





















@@ -735,6 +735,33 @@ describe("runEmbeddedPiAgent incomplete-turn safety", () => {
735735expect(retryInstruction).toBe(REASONING_ONLY_RETRY_INSTRUCTION);
736736});
737737738+it("detects reasoning-only Gemini turns from signed thinking blocks", () => {
739+const retryInstruction = resolveReasoningOnlyRetryInstruction({
740+provider: "google",
741+modelId: "gemini-2.5-pro",
742+aborted: false,
743+timedOut: false,
744+attempt: makeAttemptResult({
745+assistantTexts: [],
746+lastAssistant: {
747+role: "assistant",
748+stopReason: "end_turn",
749+provider: "google",
750+model: "gemini-2.5-pro",
751+content: [
752+{
753+type: "thinking",
754+thinking: "internal reasoning",
755+thinkingSignature: JSON.stringify({ id: "gemini_rs_helper", type: "reasoning" }),
756+},
757+],
758+} as unknown as EmbeddedRunAttemptResult["lastAssistant"],
759+}),
760+});
761+762+expect(retryInstruction).toBe(REASONING_ONLY_RETRY_INSTRUCTION);
763+});
764+738765it("treats exact NO_REPLY as a deliberate silent assistant reply", () => {
739766const incompleteTurnText = resolveIncompleteTurnPayloadText({
740767payloadCount: 0,
@@ -916,6 +943,28 @@ describe("runEmbeddedPiAgent incomplete-turn safety", () => {
916943expect(DEFAULT_EMPTY_RESPONSE_RETRY_LIMIT).toBe(1);
917944});
918945946+it("detects generic empty Gemini turns without visible text", () => {
947+const retryInstruction = resolveEmptyResponseRetryInstruction({
948+provider: "google-vertex",
949+modelId: "google/gemini-3.1-flash",
950+payloadCount: 0,
951+aborted: false,
952+timedOut: false,
953+attempt: makeAttemptResult({
954+assistantTexts: [],
955+lastAssistant: {
956+role: "assistant",
957+stopReason: "end_turn",
958+provider: "google-vertex",
959+model: "gemini-3.1-flash",
960+content: [{ type: "text", text: "" }],
961+} as unknown as EmbeddedRunAttemptResult["lastAssistant"],
962+}),
963+});
964+965+expect(retryInstruction).toBe(EMPTY_RESPONSE_RETRY_INSTRUCTION);
966+});
967+919968it("does not retry generic empty GPT turns after side effects", () => {
920969const retryInstruction = resolveEmptyResponseRetryInstruction({
921970provider: "openai",
@@ -985,6 +1034,21 @@ describe("runEmbeddedPiAgent incomplete-turn safety", () => {
9851034expect(result.meta.livenessState).toBe("working");
9861035});
98710361037+it("detects replay-safe planning-only Gemini turns", () => {
1038+const retryInstruction = resolvePlanningOnlyRetryInstruction({
1039+provider: "google-gemini-cli",
1040+modelId: "gemini-3.1-pro",
1041+prompt: "Please inspect the code, make the change, and run the checks.",
1042+aborted: false,
1043+timedOut: false,
1044+attempt: makeAttemptResult({
1045+assistantTexts: ["I'll inspect the code, make the change, and run the checks."],
1046+}),
1047+});
1048+1049+expect(retryInstruction).toContain("Do not restate the plan");
1050+});
1051+9881052it("does not misclassify a direct answer that says 'i'm not going to' as planning-only", () => {
9891053const retryInstruction = resolvePlanningOnlyRetryInstruction({
9901054provider: "openai-codex",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。