Skip to content

Commit d0975e7

Browse files
committed
fix(diagnostics): keep model content off shared event bus
1 parent 6e60307 commit d0975e7

14 files changed

Lines changed: 526 additions & 245 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
35bdbdccac62eb5f37f36e34e38b3b27ca6074a75d0dcd55b3559b35c63ed552 config-baseline.json
2-
ae47c6ab059b16c85f759eaec9be4899882877e7bb31b544afc449c811d73686 config-baseline.core.json
1+
4e41932c1c152cf4ac0acadec9f9813c4f68615483b5d8c90252837efe3609f3 config-baseline.json
2+
1bf08d3e55b5d766867b9675a1b8dbfbcbf91f82d9f038f9eb676557ce51f63e config-baseline.core.json
33
c766614db5c416910fb6cdd454efb0738779af80ddd58a4fb06d8b1ca6484ce2 config-baseline.channel.json
44
74441e331aabb3026784c148d4ee5ce3f489a15ed87ffd9b7ba0c5e2a7bc93be config-baseline.plugin.json
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
7a629e599f392dc3c1cae297833bdaa0509673a3dea7b2fe80fc9e76d5ffc2da plugin-sdk-api-baseline.json
2-
0f3f3164acf62806a18cb86137553b54ed6d0d40306bbc720bd11f9db490847c plugin-sdk-api-baseline.jsonl
1+
80a4c9d4a12e4c4c24bf31fa31d498a6ac3cec83834a564817c68a0a36d96483 plugin-sdk-api-baseline.json
2+
819a64c37603957e0053c4949966c99c8122299ad0f59b5780d5e5fe4ea97be3 plugin-sdk-api-baseline.jsonl

extensions/codex/src/app-server/run-attempt.test.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import {
2020
waitForDiagnosticEventsDrained,
2121
type DiagnosticEventPayload,
2222
} from "openclaw/plugin-sdk/diagnostic-runtime";
23+
import {
24+
onTrustedInternalDiagnosticEvent,
25+
type DiagnosticEventPrivateData,
26+
} from "../../../../src/infra/diagnostic-events.js";
2327
import {
2428
clearInternalHooks,
2529
initializeGlobalHookRunner,
@@ -6746,16 +6750,18 @@ describe("runCodexAppServerAttempt", () => {
67466750

67476751
it("emits gated model-call content diagnostics for codex turns", async () => {
67486752
const diagnosticEvents: DiagnosticEventPayload[] = [];
6753+
const diagnosticContentByType = new Map<string, DiagnosticEventPrivateData>();
67496754
let diagnosticTypesAtLlmOutput: string[] = [];
67506755
const llmOutput = vi.fn(() => {
67516756
diagnosticTypesAtLlmOutput = diagnosticEvents.map((event) => event.type);
67526757
});
67536758
initializeGlobalHookRunner(
67546759
createMockPluginRegistry([{ hookName: "llm_output", handler: llmOutput }]),
67556760
);
6756-
const stopDiagnostics = onInternalDiagnosticEvent((event) => {
6761+
const stopDiagnostics = onTrustedInternalDiagnosticEvent((event, _metadata, privateData) => {
67576762
if (event.type.startsWith("model.call.")) {
67586763
diagnosticEvents.push(event);
6764+
diagnosticContentByType.set(event.type, privateData);
67596765
}
67606766
});
67616767
try {
@@ -6803,11 +6809,13 @@ describe("runCodexAppServerAttempt", () => {
68036809
);
68046810
expect(startedEvent?.callId).toBe("run-1:codex-model:1");
68056811
expect(startedEvent?.trace?.traceId).toBeTypeOf("string");
6806-
expect(JSON.stringify(startedEvent?.inputMessages)).toContain("hello");
6807-
expect(startedEvent?.systemPrompt).toContain(
6812+
expect(JSON.stringify(startedEvent)).not.toContain("hello");
6813+
const startedContent = diagnosticContentByType.get("model.call.started")?.modelContent;
6814+
expect(JSON.stringify(startedContent?.inputMessages)).toContain("hello");
6815+
expect(startedContent?.systemPrompt).toContain(
68086816
"You are a personal agent running inside OpenClaw.",
68096817
);
6810-
expect(startedEvent?.toolDefinitions).toContainEqual(
6818+
expect(startedContent?.toolDefinitions).toContainEqual(
68116819
expect.objectContaining({
68126820
name: "message",
68136821
parameters: expect.objectContaining({
@@ -6817,7 +6825,10 @@ describe("runCodexAppServerAttempt", () => {
68176825
}),
68186826
);
68196827
expect(completedEvent?.callId).toBe("run-1:codex-model:1");
6820-
expect(JSON.stringify(completedEvent?.outputMessages)).toContain("hello back");
6828+
expect(JSON.stringify(completedEvent)).not.toContain("hello back");
6829+
expect(
6830+
JSON.stringify(diagnosticContentByType.get("model.call.completed")?.modelContent),
6831+
).toContain("hello back");
68216832
expect(completedEvent?.requestPayloadBytes).toBeGreaterThan(0);
68226833
expect(llmOutput).toHaveBeenCalledTimes(1);
68236834
expect(diagnosticTypesAtLlmOutput).toContain("model.call.completed");

extensions/codex/src/app-server/run-attempt.ts

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ import { markAuthProfileBlockedUntil, resolveAgentDir } from "openclaw/plugin-sd
5050
import {
5151
createDiagnosticTraceContextFromActiveScope,
5252
emitTrustedDiagnosticEvent,
53+
emitTrustedDiagnosticEventWithPrivateData,
5354
freezeDiagnosticTraceContext,
5455
hasPendingInternalDiagnosticEvent,
5556
onInternalDiagnosticEvent,
5657
resolveDiagnosticModelContentCapturePolicy,
58+
type DiagnosticModelCallContent,
5759
type DiagnosticEventPayload,
5860
} from "openclaw/plugin-sdk/diagnostic-runtime";
5961
import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
@@ -2720,40 +2722,59 @@ export async function runCodexAppServerAttempt(
27202722
const codexDiagnosticToolDefinitions = codexModelContentCapture.toolDefinitions
27212723
? buildCodexDiagnosticToolDefinitions(tools)
27222724
: undefined;
2723-
const buildCodexModelCallDiagnosticFields = () => ({
2724-
...codexModelCallBaseFields,
2725-
...(codexModelContentCapture.inputMessages
2726-
? { inputMessages: buildTurnStartFailureMessages() }
2727-
: {}),
2728-
...(codexModelContentCapture.systemPrompt
2729-
? { systemPrompt: buildRenderedCodexDeveloperInstructions() }
2730-
: {}),
2731-
...(codexDiagnosticToolDefinitions ? { toolDefinitions: codexDiagnosticToolDefinitions } : {}),
2732-
});
2725+
const codexModelContentPrivateData = (
2726+
modelContent: DiagnosticModelCallContent | undefined,
2727+
) => (modelContent && Object.keys(modelContent).length > 0 ? { modelContent } : undefined);
2728+
const buildCodexModelCallDiagnosticContent = (): DiagnosticModelCallContent | undefined => {
2729+
const modelContent = {
2730+
...(codexModelContentCapture.inputMessages
2731+
? { inputMessages: buildTurnStartFailureMessages() }
2732+
: {}),
2733+
...(codexModelContentCapture.systemPrompt
2734+
? { systemPrompt: buildRenderedCodexDeveloperInstructions() }
2735+
: {}),
2736+
...(codexDiagnosticToolDefinitions
2737+
? { toolDefinitions: codexDiagnosticToolDefinitions }
2738+
: {}),
2739+
};
2740+
return Object.keys(modelContent).length > 0 ? modelContent : undefined;
2741+
};
27332742
const emitCodexModelCallStarted = () => {
27342743
codexModelCallStartedAt = Date.now();
27352744
codexModelCallStarted = true;
2736-
emitTrustedDiagnosticEvent({
2737-
type: "model.call.started",
2738-
...buildCodexModelCallDiagnosticFields(),
2739-
});
2745+
emitTrustedDiagnosticEventWithPrivateData(
2746+
{
2747+
type: "model.call.started",
2748+
...codexModelCallBaseFields,
2749+
},
2750+
codexModelContentPrivateData(buildCodexModelCallDiagnosticContent()),
2751+
);
27402752
};
27412753
const emitCodexModelCallCompleted = (result: EmbeddedRunAttemptResult) => {
27422754
if (!codexModelCallStarted || codexModelCallTerminalEmitted) {
27432755
return;
27442756
}
27452757
codexModelCallTerminalEmitted = true;
2746-
emitTrustedDiagnosticEvent({
2747-
type: "model.call.completed",
2748-
...buildCodexModelCallDiagnosticFields(),
2749-
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
2750-
...(codexModelCallRequestPayloadBytes !== undefined
2751-
? { requestPayloadBytes: codexModelCallRequestPayloadBytes }
2752-
: {}),
2753-
...(codexModelContentCapture.outputMessages
2754-
? { outputMessages: result.lastAssistant ? [result.lastAssistant] : result.assistantTexts }
2755-
: {}),
2756-
});
2758+
emitTrustedDiagnosticEventWithPrivateData(
2759+
{
2760+
type: "model.call.completed",
2761+
...codexModelCallBaseFields,
2762+
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
2763+
...(codexModelCallRequestPayloadBytes !== undefined
2764+
? { requestPayloadBytes: codexModelCallRequestPayloadBytes }
2765+
: {}),
2766+
},
2767+
codexModelContentPrivateData({
2768+
...buildCodexModelCallDiagnosticContent(),
2769+
...(codexModelContentCapture.outputMessages
2770+
? {
2771+
outputMessages: result.lastAssistant
2772+
? [result.lastAssistant]
2773+
: result.assistantTexts,
2774+
}
2775+
: {}),
2776+
}),
2777+
);
27572778
};
27582779
const emitCodexModelCallError = (
27592780
error: unknown,
@@ -2763,17 +2784,22 @@ export async function runCodexAppServerAttempt(
27632784
return;
27642785
}
27652786
codexModelCallTerminalEmitted = true;
2766-
emitTrustedDiagnosticEvent({
2767-
type: "model.call.error",
2768-
...buildCodexModelCallDiagnosticFields(),
2769-
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
2770-
errorCategory: fields.failureKind ?? "error",
2771-
...(fields.failureKind ? { failureKind: fields.failureKind } : {}),
2772-
...(codexModelCallRequestPayloadBytes !== undefined
2773-
? { requestPayloadBytes: codexModelCallRequestPayloadBytes }
2774-
: {}),
2775-
...(codexModelContentCapture.outputMessages ? { outputMessages: [] } : {}),
2776-
});
2787+
emitTrustedDiagnosticEventWithPrivateData(
2788+
{
2789+
type: "model.call.error",
2790+
...codexModelCallBaseFields,
2791+
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
2792+
errorCategory: fields.failureKind ?? "error",
2793+
...(fields.failureKind ? { failureKind: fields.failureKind } : {}),
2794+
...(codexModelCallRequestPayloadBytes !== undefined
2795+
? { requestPayloadBytes: codexModelCallRequestPayloadBytes }
2796+
: {}),
2797+
},
2798+
codexModelContentPrivateData({
2799+
...buildCodexModelCallDiagnosticContent(),
2800+
...(codexModelContentCapture.outputMessages ? { outputMessages: [] } : {}),
2801+
}),
2802+
);
27772803
embeddedAgentLog.debug("codex app-server model call diagnostic ended with error", {
27782804
error: formatErrorMessage(error),
27792805
});

0 commit comments

Comments
 (0)