diff --git a/CHANGELOG.md b/CHANGELOG.md index 5914e1b0bfc..4b0757c19f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Docs: https://docs.openclaw.ai - Telegram: deliver generated media completions back into forum topics by preserving topic IDs across requester-agent handoff. (#83556) Thanks @fuller-stack-dev. - Gateway: defer update-check startup until after readiness so package update checks no longer block sidecar-ready startup, while preserving update broadcasts and shutdown cleanup. (#83520) Thanks @samzong. - Telegram: keep `/btw` and read-only status commands from aborting active runs, and avoid retaining raw update payloads in timed-out spool tombstones. Refs #83272. +- Agents: log strict-agentic execution contract diagnostics only when the planning-only retry path actually triggers. - Agents/video: hide `video_generate` reference-audio parameters unless a registered video provider supports audio inputs. - Plugins: fall back to npm for official ClawHub updates when artifact downloads are unavailable, including beta-to-default fallback and dry-run version reporting. - Plugins/xAI: echo PKCE challenge fields during OAuth authorization-code token exchange for xAI token-endpoint compatibility. (#83499) Thanks @fuller-stack-dev. diff --git a/src/agents/pi-embedded-runner/run.incomplete-turn.test.ts b/src/agents/pi-embedded-runner/run.incomplete-turn.test.ts index e336796dc30..0eebe0193a6 100644 --- a/src/agents/pi-embedded-runner/run.incomplete-turn.test.ts +++ b/src/agents/pi-embedded-runner/run.incomplete-turn.test.ts @@ -53,10 +53,6 @@ describe("runEmbeddedPiAgent incomplete-turn safety", () => { return mockedLog.warn.mock.calls.map(([message]) => String(message)); } - function infoMessages(): string[] { - return mockedLog.info.mock.calls.map(([message]) => String(message)); - } - function expectWarnMessageWith(text: string): void { expect(warnMessages().join("\n")).toContain(text); } @@ -353,11 +349,14 @@ describe("runEmbeddedPiAgent incomplete-turn safety", () => { }, ]); expect(result.meta.livenessState).toBe("blocked"); - expect(infoMessages().join("\n")).toContain( - "strict-agentic execution contract active: runId=run-strict-agentic-auto-activated", + expect(warnMessages().join("\n")).toContain( + "strict-agentic execution contract triggered: runId=run-strict-agentic-auto-activated", ); - expect(infoMessages().join("\n")).toContain( - "provider=openai-codex/gpt-5.4 harness=codex configured=unspecified", + expect(warnMessages().join("\n")).toContain( + "provider=openai-codex/gpt-5.4 harness=codex contract=strict-agentic configured=unspecified", + ); + expect(mockedLog.info.mock.calls.map(([message]) => String(message)).join("\n")).not.toContain( + "strict-agentic execution contract active", ); }); diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index 18e1b31ccf2..4bf7f50cde1 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -998,14 +998,7 @@ export async function runEmbeddedPiAgent( modelId, }); const executionContract = strictAgenticActive ? "strict-agentic" : "default"; - const configuredExecutionContractForLog = configuredExecutionContract ?? "default"; - if (strictAgenticActive) { - log.info( - `strict-agentic execution contract active: runId=${params.runId} sessionId=${params.sessionId} ` + - `provider=${sanitizeForLog(provider)}/${sanitizeForLog(modelId)} harness=${sanitizeForLog(agentHarness.id)} ` + - `configured=${configuredExecutionContract ?? "unspecified"}`, - ); - } + const configuredExecutionContractForLog = configuredExecutionContract ?? "unspecified"; const maxPlanningOnlyRetryAttempts = resolvePlanningOnlyRetryLimit(executionContract); const maxReasoningOnlyRetryAttempts = DEFAULT_REASONING_ONLY_RETRY_LIMIT; const maxEmptyResponseRetryAttempts = DEFAULT_EMPTY_RESPONSE_RETRY_LIMIT; @@ -2804,9 +2797,14 @@ export async function runEmbeddedPiAgent( } planningOnlyRetryAttempts += 1; planningOnlyRetryInstruction = nextPlanningOnlyRetryInstruction; + const planningOnlyRetryLogPrefix = + executionContract === "strict-agentic" + ? "strict-agentic execution contract triggered" + : "planning-only turn detected"; log.warn( - `planning-only turn detected: runId=${params.runId} sessionId=${params.sessionId} ` + - `provider=${provider}/${modelId} contract=${executionContract} configured=${configuredExecutionContractForLog} — retrying ` + + `${planningOnlyRetryLogPrefix}: runId=${params.runId} sessionId=${params.sessionId} ` + + `provider=${provider}/${modelId} harness=${sanitizeForLog(agentHarness.id)} ` + + `contract=${executionContract} configured=${configuredExecutionContractForLog} — retrying ` + `${planningOnlyRetryAttempts}/${maxPlanningOnlyRetryAttempts} with act-now steer`, ); continue;