@riddledc/riddle-proof 0.5.48 → 0.5.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-2RS4PBYK.js → chunk-722PW3X3.js} +105 -9
- package/dist/{chunk-PLSGW2GI.js → chunk-CI2F66EE.js} +63 -0
- package/dist/{chunk-JOXTKWX6.js → chunk-U7Q3RB5D.js} +1 -1
- package/dist/{chunk-N3ZNBRIG.js → chunk-YJPQOAZG.js} +1 -1
- package/dist/{chunk-NOBFZDZG.js → chunk-YW77WDTR.js} +104 -10
- package/dist/cli.cjs +266 -17
- package/dist/cli.js +4 -4
- package/dist/codex-exec-agent.cjs +107 -10
- package/dist/codex-exec-agent.d.cts +1 -0
- package/dist/codex-exec-agent.d.ts +1 -0
- package/dist/codex-exec-agent.js +2 -1
- package/dist/engine-harness.cjs +166 -7
- package/dist/engine-harness.js +3 -3
- package/dist/index.cjs +268 -19
- package/dist/index.js +5 -5
- package/dist/local-agent.cjs +107 -10
- package/dist/local-agent.js +2 -1
- package/dist/openclaw.js +2 -2
- package/dist/proof-run-core.d.cts +1 -1
- package/dist/proof-run-core.d.ts +1 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/dist/run-card.cjs +63 -0
- package/dist/run-card.js +1 -1
- package/dist/runner.js +3 -3
- package/dist/state.cjs +63 -0
- package/dist/state.js +2 -2
- package/dist/types.d.cts +12 -0
- package/dist/types.d.ts +12 -0
- package/package.json +1 -1
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
createRunStatusSnapshot,
|
|
11
11
|
normalizeRunParams,
|
|
12
12
|
setRunStatus
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-U7Q3RB5D.js";
|
|
14
14
|
import {
|
|
15
15
|
createRiddleProofRunCard
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CI2F66EE.js";
|
|
17
17
|
import {
|
|
18
18
|
authorPacketPayloadFromCheckpointResponse,
|
|
19
19
|
buildCheckpointPacketForEngineResult,
|
|
@@ -898,7 +898,10 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
898
898
|
worktree_path: workdir || null
|
|
899
899
|
}
|
|
900
900
|
});
|
|
901
|
+
const implementationStartedAt = timestamp();
|
|
902
|
+
const implementationStartedMs = Date.now();
|
|
901
903
|
const implementation = await agent.implementChange({ ...context, workdir });
|
|
904
|
+
const implementationDurationMs = Date.now() - implementationStartedMs;
|
|
902
905
|
if (implementation.blocker || implementation.ok === false) {
|
|
903
906
|
recordEvent(state, {
|
|
904
907
|
kind: "agent.implementation.blocked",
|
|
@@ -907,6 +910,8 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
907
910
|
summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
|
|
908
911
|
details: compactRecord({
|
|
909
912
|
worktree_path: workdir || null,
|
|
913
|
+
started_at: implementationStartedAt,
|
|
914
|
+
duration_ms: implementationDurationMs,
|
|
910
915
|
changed_files: implementation.changedFiles || [],
|
|
911
916
|
tests_run: implementation.testsRun || [],
|
|
912
917
|
implementation_notes: implementation.implementationNotes || null,
|
|
@@ -932,6 +937,8 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
932
937
|
summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
|
|
933
938
|
details: compactRecord({
|
|
934
939
|
worktree_path: workdir || null,
|
|
940
|
+
started_at: implementationStartedAt,
|
|
941
|
+
duration_ms: implementationDurationMs,
|
|
935
942
|
changed_files: implementation.changedFiles || [],
|
|
936
943
|
tests_run: implementation.testsRun || [],
|
|
937
944
|
implementation_notes: implementation.implementationNotes || null,
|
|
@@ -946,7 +953,8 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
946
953
|
details: compactRecord({
|
|
947
954
|
worktree_path: workdir || null,
|
|
948
955
|
checkpoint: result.checkpoint || null,
|
|
949
|
-
next_stage: "implement"
|
|
956
|
+
next_stage: "implement",
|
|
957
|
+
previous_duration_ms: implementationDurationMs
|
|
950
958
|
})
|
|
951
959
|
});
|
|
952
960
|
return {
|
|
@@ -965,6 +973,8 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
965
973
|
summary: implementation.summary || "Implementation adapter reported code changes.",
|
|
966
974
|
details: {
|
|
967
975
|
worktree_path: workdir || null,
|
|
976
|
+
started_at: implementationStartedAt,
|
|
977
|
+
duration_ms: implementationDurationMs,
|
|
968
978
|
diffDetected,
|
|
969
979
|
changed_files: implementation.changedFiles || [],
|
|
970
980
|
tests_run: implementation.testsRun || [],
|
|
@@ -1081,15 +1091,44 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
1081
1091
|
if (input.checkpoint_mode === "yield") {
|
|
1082
1092
|
return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
|
|
1083
1093
|
}
|
|
1094
|
+
const startedAt = timestamp();
|
|
1095
|
+
const startedMs = Date.now();
|
|
1096
|
+
recordEvent(state, {
|
|
1097
|
+
kind: "agent.recon_assessment.started",
|
|
1098
|
+
checkpoint,
|
|
1099
|
+
stage: "recon",
|
|
1100
|
+
summary: "Recon assessment agent started.",
|
|
1101
|
+
details: { started_at: startedAt }
|
|
1102
|
+
});
|
|
1084
1103
|
const assessment = await agent.assessRecon(context);
|
|
1104
|
+
const durationMs = Date.now() - startedMs;
|
|
1085
1105
|
const blocker = requirePayload("recon_assessment", assessment, state, result);
|
|
1086
|
-
if (blocker)
|
|
1106
|
+
if (blocker) {
|
|
1107
|
+
recordEvent(state, {
|
|
1108
|
+
kind: "agent.recon_assessment.blocked",
|
|
1109
|
+
checkpoint,
|
|
1110
|
+
stage: "recon",
|
|
1111
|
+
summary: blocker.message,
|
|
1112
|
+
details: compactRecord({
|
|
1113
|
+
started_at: startedAt,
|
|
1114
|
+
duration_ms: durationMs,
|
|
1115
|
+
blocker,
|
|
1116
|
+
adapter_details: assessment.details || null
|
|
1117
|
+
})
|
|
1118
|
+
});
|
|
1119
|
+
return { blocker };
|
|
1120
|
+
}
|
|
1087
1121
|
recordEvent(state, {
|
|
1088
1122
|
kind: "agent.recon_assessment.completed",
|
|
1089
1123
|
checkpoint,
|
|
1090
1124
|
stage: "recon",
|
|
1091
1125
|
summary: assessment.summary,
|
|
1092
|
-
details: {
|
|
1126
|
+
details: compactRecord({
|
|
1127
|
+
payload: assessment.payload,
|
|
1128
|
+
started_at: startedAt,
|
|
1129
|
+
duration_ms: durationMs,
|
|
1130
|
+
adapter_details: assessment.details || null
|
|
1131
|
+
})
|
|
1093
1132
|
});
|
|
1094
1133
|
return {
|
|
1095
1134
|
next: { ...baseContinuation(result), recon_assessment_json: jsonParam(assessment.payload) }
|
|
@@ -1101,15 +1140,44 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
1101
1140
|
if (input.checkpoint_mode === "yield") {
|
|
1102
1141
|
return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
|
|
1103
1142
|
}
|
|
1143
|
+
const startedAt = timestamp();
|
|
1144
|
+
const startedMs = Date.now();
|
|
1145
|
+
recordEvent(state, {
|
|
1146
|
+
kind: "agent.author_packet.started",
|
|
1147
|
+
checkpoint,
|
|
1148
|
+
stage: "author",
|
|
1149
|
+
summary: "Proof authoring agent started.",
|
|
1150
|
+
details: { started_at: startedAt }
|
|
1151
|
+
});
|
|
1104
1152
|
const packet = await agent.authorProofPacket(context);
|
|
1153
|
+
const durationMs = Date.now() - startedMs;
|
|
1105
1154
|
const blocker = requirePayload("author_packet", packet, state, result);
|
|
1106
|
-
if (blocker)
|
|
1155
|
+
if (blocker) {
|
|
1156
|
+
recordEvent(state, {
|
|
1157
|
+
kind: "agent.author_packet.blocked",
|
|
1158
|
+
checkpoint,
|
|
1159
|
+
stage: "author",
|
|
1160
|
+
summary: blocker.message,
|
|
1161
|
+
details: compactRecord({
|
|
1162
|
+
started_at: startedAt,
|
|
1163
|
+
duration_ms: durationMs,
|
|
1164
|
+
blocker,
|
|
1165
|
+
adapter_details: packet.details || null
|
|
1166
|
+
})
|
|
1167
|
+
});
|
|
1168
|
+
return { blocker };
|
|
1169
|
+
}
|
|
1107
1170
|
recordEvent(state, {
|
|
1108
1171
|
kind: "agent.author_packet.completed",
|
|
1109
1172
|
checkpoint,
|
|
1110
1173
|
stage: "author",
|
|
1111
1174
|
summary: packet.summary,
|
|
1112
|
-
details: {
|
|
1175
|
+
details: compactRecord({
|
|
1176
|
+
payload: packet.payload,
|
|
1177
|
+
started_at: startedAt,
|
|
1178
|
+
duration_ms: durationMs,
|
|
1179
|
+
adapter_details: packet.details || null
|
|
1180
|
+
})
|
|
1113
1181
|
});
|
|
1114
1182
|
return {
|
|
1115
1183
|
next: { ...baseContinuation(result), author_packet_json: jsonParam(packet.payload) }
|
|
@@ -1132,9 +1200,31 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
1132
1200
|
if (input.checkpoint_mode === "yield") {
|
|
1133
1201
|
return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
|
|
1134
1202
|
}
|
|
1203
|
+
const startedAt = timestamp();
|
|
1204
|
+
const startedMs = Date.now();
|
|
1205
|
+
recordEvent(state, {
|
|
1206
|
+
kind: "agent.proof_assessment.started",
|
|
1207
|
+
checkpoint,
|
|
1208
|
+
stage: "verify",
|
|
1209
|
+
summary: "Proof assessment agent started.",
|
|
1210
|
+
details: { started_at: startedAt }
|
|
1211
|
+
});
|
|
1135
1212
|
const assessment = await agent.assessProof(context);
|
|
1213
|
+
const durationMs = Date.now() - startedMs;
|
|
1136
1214
|
const blocker = requirePayload("proof_assessment", assessment, state, result);
|
|
1137
1215
|
if (blocker) {
|
|
1216
|
+
recordEvent(state, {
|
|
1217
|
+
kind: "agent.proof_assessment.blocked",
|
|
1218
|
+
checkpoint,
|
|
1219
|
+
stage: "verify",
|
|
1220
|
+
summary: blocker.message,
|
|
1221
|
+
details: compactRecord({
|
|
1222
|
+
started_at: startedAt,
|
|
1223
|
+
duration_ms: durationMs,
|
|
1224
|
+
blocker,
|
|
1225
|
+
adapter_details: assessment.details || null
|
|
1226
|
+
})
|
|
1227
|
+
});
|
|
1138
1228
|
if (blocker.code === "main_agent_proof_review_required") {
|
|
1139
1229
|
recordEvent(state, {
|
|
1140
1230
|
kind: "checkpoint.packet.requested",
|
|
@@ -1153,7 +1243,12 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
1153
1243
|
checkpoint,
|
|
1154
1244
|
stage: "verify",
|
|
1155
1245
|
summary: assessment.summary,
|
|
1156
|
-
details: {
|
|
1246
|
+
details: compactRecord({
|
|
1247
|
+
payload,
|
|
1248
|
+
started_at: startedAt,
|
|
1249
|
+
duration_ms: durationMs,
|
|
1250
|
+
adapter_details: assessment.details || null
|
|
1251
|
+
})
|
|
1157
1252
|
});
|
|
1158
1253
|
const visualBlocker = proofAssessmentVisualBlocker({
|
|
1159
1254
|
...context.fullRiddleState || {},
|
|
@@ -1174,7 +1269,8 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
1174
1269
|
recovery_stage: "verify",
|
|
1175
1270
|
evidence_issue_code: recoveryAssessment.evidence_issue_code || null,
|
|
1176
1271
|
visual_delta: recoveryAssessment.visual_delta || null,
|
|
1177
|
-
proof_assessment: recoveryAssessment
|
|
1272
|
+
proof_assessment: recoveryAssessment,
|
|
1273
|
+
agent_duration_ms: durationMs
|
|
1178
1274
|
})
|
|
1179
1275
|
});
|
|
1180
1276
|
return { next: proofAssessmentContinuation(result, recoveryAssessment) };
|
|
@@ -30,6 +30,68 @@ function compactText(value, limit = 600) {
|
|
|
30
30
|
if (!text) return void 0;
|
|
31
31
|
return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
|
|
32
32
|
}
|
|
33
|
+
function numericValue(value) {
|
|
34
|
+
const number = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
|
|
35
|
+
return Number.isFinite(number) ? number : void 0;
|
|
36
|
+
}
|
|
37
|
+
function eventDetails(event) {
|
|
38
|
+
return recordValue(recordValue(event)?.details) || {};
|
|
39
|
+
}
|
|
40
|
+
function collectRunnerMetrics(details) {
|
|
41
|
+
const metrics = [];
|
|
42
|
+
const adapterDetails = recordValue(details.adapter_details);
|
|
43
|
+
const direct = recordValue(adapterDetails?.runner_metrics);
|
|
44
|
+
if (direct) metrics.push(direct);
|
|
45
|
+
const attempts = Array.isArray(adapterDetails?.attempt_summaries) ? adapterDetails.attempt_summaries : [];
|
|
46
|
+
for (const attempt of attempts) {
|
|
47
|
+
const attemptMetrics = recordValue(recordValue(attempt)?.runner_metrics);
|
|
48
|
+
if (attemptMetrics) metrics.push(attemptMetrics);
|
|
49
|
+
}
|
|
50
|
+
return metrics;
|
|
51
|
+
}
|
|
52
|
+
function observabilityFrom(state) {
|
|
53
|
+
const engineEvents = state.events.filter((event) => event.kind === "engine.result").map((event) => ({ event, details: eventDetails(event) }));
|
|
54
|
+
const agentEvents = state.events.filter((event) => event.kind.startsWith("agent.")).map((event) => ({ event, details: eventDetails(event) })).filter(({ details }) => numericValue(details.duration_ms) !== void 0);
|
|
55
|
+
const retryEvents = state.events.filter((event) => /retry|recovery/i.test(event.kind) || /retry|recovery/i.test(event.summary || "")).slice(-8);
|
|
56
|
+
const runnerMetrics = agentEvents.flatMap(({ details }) => collectRunnerMetrics(details));
|
|
57
|
+
const promptChars = runnerMetrics.map((metrics) => numericValue(metrics.prompt_chars)).filter((value) => value !== void 0);
|
|
58
|
+
const sum = (values) => values.reduce((total, value) => total + (value ?? 0), 0);
|
|
59
|
+
const recentEngineTimings = engineEvents.slice(-8).map(({ event, details }) => compactRecord({
|
|
60
|
+
checkpoint: event.checkpoint || null,
|
|
61
|
+
stage: event.stage || null,
|
|
62
|
+
duration_ms: numericValue(details.duration_ms),
|
|
63
|
+
ok: details.ok ?? null
|
|
64
|
+
}));
|
|
65
|
+
const recentAgentTimings = agentEvents.slice(-8).map(({ event, details }) => {
|
|
66
|
+
const metrics = collectRunnerMetrics(details);
|
|
67
|
+
const localPromptChars = metrics.map((item) => numericValue(item.prompt_chars)).filter((value) => value !== void 0);
|
|
68
|
+
return compactRecord({
|
|
69
|
+
kind: event.kind,
|
|
70
|
+
checkpoint: event.checkpoint || null,
|
|
71
|
+
stage: event.stage || null,
|
|
72
|
+
duration_ms: numericValue(details.duration_ms),
|
|
73
|
+
prompt_chars: localPromptChars.length ? Math.max(...localPromptChars) : void 0,
|
|
74
|
+
attempt_count: numericValue(recordValue(details.adapter_details)?.attempt_count)
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
return compactRecord({
|
|
78
|
+
engine_call_count: engineEvents.length,
|
|
79
|
+
agent_call_count: agentEvents.length,
|
|
80
|
+
engine_total_ms: sum(engineEvents.map(({ details }) => numericValue(details.duration_ms))),
|
|
81
|
+
agent_total_ms: sum(agentEvents.map(({ details }) => numericValue(details.duration_ms))),
|
|
82
|
+
max_agent_prompt_chars: promptChars.length ? Math.max(...promptChars) : void 0,
|
|
83
|
+
total_agent_prompt_chars: promptChars.length ? sum(promptChars) : void 0,
|
|
84
|
+
recent_engine_timings: recentEngineTimings.length ? recentEngineTimings : void 0,
|
|
85
|
+
recent_agent_timings: recentAgentTimings.length ? recentAgentTimings : void 0,
|
|
86
|
+
retry_event_count: retryEvents.length,
|
|
87
|
+
recent_retry_reasons: retryEvents.length ? retryEvents.map((event) => compactRecord({
|
|
88
|
+
kind: event.kind,
|
|
89
|
+
checkpoint: event.checkpoint || null,
|
|
90
|
+
stage: event.stage || null,
|
|
91
|
+
summary: compactText(event.summary, 240)
|
|
92
|
+
})) : void 0
|
|
93
|
+
});
|
|
94
|
+
}
|
|
33
95
|
function visualDeltaFrom(input) {
|
|
34
96
|
const fullState = input.fullRiddleState || {};
|
|
35
97
|
const bundle = recordValue(fullState.evidence_bundle);
|
|
@@ -142,6 +204,7 @@ function createRiddleProofRunCard(state, input = {}) {
|
|
|
142
204
|
proof_evidence_present: fullState.proof_evidence_present === true || Boolean(bundle?.proof_evidence || bundle?.proof_evidence_sample),
|
|
143
205
|
artifacts
|
|
144
206
|
}),
|
|
207
|
+
observability: observabilityFrom(state),
|
|
145
208
|
stop_condition: compactRecord({
|
|
146
209
|
status: state.status,
|
|
147
210
|
terminal: isTerminalStatus(state.status),
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compactRecord
|
|
3
|
+
} from "./chunk-DUFDZJOF.js";
|
|
4
|
+
|
|
1
5
|
// src/codex-exec-agent.ts
|
|
2
6
|
import { execFileSync, spawnSync } from "child_process";
|
|
3
7
|
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
@@ -128,10 +132,10 @@ var PROOF_SCHEMA = {
|
|
|
128
132
|
source: { type: "string", enum: ["supervising_agent"] }
|
|
129
133
|
}
|
|
130
134
|
};
|
|
131
|
-
var PROMPT_STRING_LIMIT =
|
|
132
|
-
var PROMPT_ARRAY_LIMIT =
|
|
133
|
-
var PROMPT_OBJECT_KEY_LIMIT =
|
|
134
|
-
var PROMPT_BLOCK_LIMIT =
|
|
135
|
+
var PROMPT_STRING_LIMIT = 1400;
|
|
136
|
+
var PROMPT_ARRAY_LIMIT = 8;
|
|
137
|
+
var PROMPT_OBJECT_KEY_LIMIT = 50;
|
|
138
|
+
var PROMPT_BLOCK_LIMIT = 7e4;
|
|
135
139
|
var PROMPT_KEY_PRIORITY = [
|
|
136
140
|
"ok",
|
|
137
141
|
"status",
|
|
@@ -153,6 +157,16 @@ var PROMPT_KEY_PRIORITY = [
|
|
|
153
157
|
"after_cdn",
|
|
154
158
|
"before_baseline",
|
|
155
159
|
"prod_baseline",
|
|
160
|
+
"route_hints",
|
|
161
|
+
"route_candidates",
|
|
162
|
+
"keyword_hits",
|
|
163
|
+
"observations",
|
|
164
|
+
"latest_attempt",
|
|
165
|
+
"attempt_history",
|
|
166
|
+
"current_plan",
|
|
167
|
+
"plan_history",
|
|
168
|
+
"decision_history",
|
|
169
|
+
"refined_inputs",
|
|
156
170
|
"recon_assessment",
|
|
157
171
|
"baseline_understanding",
|
|
158
172
|
"supervisor_author_packet",
|
|
@@ -176,6 +190,7 @@ var PROMPT_KEY_PRIORITY = [
|
|
|
176
190
|
"shipGate",
|
|
177
191
|
"last_error",
|
|
178
192
|
"errors",
|
|
193
|
+
"runtime_events",
|
|
179
194
|
"events"
|
|
180
195
|
];
|
|
181
196
|
var PROMPT_PRIORITY_INDEX = new Map(PROMPT_KEY_PRIORITY.map((key, index) => [key, index]));
|
|
@@ -192,7 +207,7 @@ function compactPromptValue(value, depth = 0, key = "") {
|
|
|
192
207
|
if (!looksLikeUrl && (lowerKey.includes("base64") || lowerKey.includes("data_url") || lowerKey.includes("screenshot_blob"))) {
|
|
193
208
|
return `[omitted ${value.length} chars from ${key || "large artifact"}]`;
|
|
194
209
|
}
|
|
195
|
-
const limit = looksLikeUrl ? 1e3 : depth <= 1 ? PROMPT_STRING_LIMIT :
|
|
210
|
+
const limit = looksLikeUrl ? 1e3 : depth <= 1 ? PROMPT_STRING_LIMIT : 900;
|
|
196
211
|
return truncatePromptString(value, limit);
|
|
197
212
|
}
|
|
198
213
|
if (Array.isArray(value)) {
|
|
@@ -323,11 +338,39 @@ function isHarnessVerificationOnlyBlocker(blocker) {
|
|
|
323
338
|
const text = blocker.toLowerCase();
|
|
324
339
|
return (text.includes("erofs") || text.includes("read-only file system")) && text.includes("node_modules") && (text.includes(".vite-temp") || text.includes("vite.config"));
|
|
325
340
|
}
|
|
341
|
+
function runnerMetrics(input) {
|
|
342
|
+
const schemaText = JSON.stringify(input.request.schema);
|
|
343
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
344
|
+
return compactRecord({
|
|
345
|
+
purpose: input.request.purpose,
|
|
346
|
+
workdir: input.request.workdir,
|
|
347
|
+
started_at: input.startedAt,
|
|
348
|
+
finished_at: finishedAt,
|
|
349
|
+
duration_ms: Date.now() - input.startedMs,
|
|
350
|
+
prompt_chars: input.request.prompt.length,
|
|
351
|
+
prompt_lines: input.request.prompt.split(/\r?\n/).length,
|
|
352
|
+
schema_chars: schemaText.length,
|
|
353
|
+
stdout_chars: (input.stdout || "").length,
|
|
354
|
+
stderr_chars: (input.stderr || "").length,
|
|
355
|
+
final_message_chars: (input.finalText || "").length,
|
|
356
|
+
exit_status: input.status ?? null,
|
|
357
|
+
timed_out: input.timedOut || false,
|
|
358
|
+
error_code: input.errorCode,
|
|
359
|
+
codex_command: input.config.codexCommand || "codex",
|
|
360
|
+
codex_model: input.config.codexModel,
|
|
361
|
+
codex_sandbox: input.config.codexSandbox || "workspace-write",
|
|
362
|
+
codex_full_auto: input.config.codexFullAuto !== false,
|
|
363
|
+
timeout_ms: Number(input.config.codexTimeoutMs || 6e5)
|
|
364
|
+
});
|
|
365
|
+
}
|
|
326
366
|
function createCodexExecJsonRunner(config = {}) {
|
|
327
367
|
return (request) => {
|
|
368
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
369
|
+
const startedMs = Date.now();
|
|
328
370
|
if (!request.workdir || !existsSync(request.workdir)) {
|
|
329
371
|
return {
|
|
330
372
|
ok: false,
|
|
373
|
+
metrics: runnerMetrics({ request, config, startedAt, startedMs, errorCode: "workdir_missing" }),
|
|
331
374
|
blocker: {
|
|
332
375
|
code: "codex_workdir_missing",
|
|
333
376
|
message: `Codex workdir does not exist for ${request.purpose}.`,
|
|
@@ -372,6 +415,17 @@ function createCodexExecJsonRunner(config = {}) {
|
|
|
372
415
|
ok: false,
|
|
373
416
|
stdout: proc.stdout || "",
|
|
374
417
|
stderr: proc.stderr || "",
|
|
418
|
+
metrics: runnerMetrics({
|
|
419
|
+
request,
|
|
420
|
+
config,
|
|
421
|
+
startedAt,
|
|
422
|
+
startedMs,
|
|
423
|
+
stdout: proc.stdout || "",
|
|
424
|
+
stderr: proc.stderr || "",
|
|
425
|
+
status: proc.status,
|
|
426
|
+
timedOut,
|
|
427
|
+
errorCode: proc.error.code || "spawn_error"
|
|
428
|
+
}),
|
|
375
429
|
blocker: {
|
|
376
430
|
code: timedOut ? "codex_timeout" : "codex_exec_error",
|
|
377
431
|
message: timedOut ? `Codex timed out during ${request.purpose}.` : `Codex failed to start or complete ${request.purpose}.`,
|
|
@@ -384,6 +438,16 @@ function createCodexExecJsonRunner(config = {}) {
|
|
|
384
438
|
ok: false,
|
|
385
439
|
stdout: proc.stdout || "",
|
|
386
440
|
stderr: proc.stderr || "",
|
|
441
|
+
metrics: runnerMetrics({
|
|
442
|
+
request,
|
|
443
|
+
config,
|
|
444
|
+
startedAt,
|
|
445
|
+
startedMs,
|
|
446
|
+
stdout: proc.stdout || "",
|
|
447
|
+
stderr: proc.stderr || "",
|
|
448
|
+
status: proc.status,
|
|
449
|
+
errorCode: "nonzero_exit"
|
|
450
|
+
}),
|
|
387
451
|
blocker: {
|
|
388
452
|
code: "codex_nonzero_exit",
|
|
389
453
|
message: `Codex exited with status ${proc.status} during ${request.purpose}.`,
|
|
@@ -398,6 +462,17 @@ function createCodexExecJsonRunner(config = {}) {
|
|
|
398
462
|
ok: false,
|
|
399
463
|
stdout: proc.stdout || "",
|
|
400
464
|
stderr: proc.stderr || "",
|
|
465
|
+
metrics: runnerMetrics({
|
|
466
|
+
request,
|
|
467
|
+
config,
|
|
468
|
+
startedAt,
|
|
469
|
+
startedMs,
|
|
470
|
+
stdout: proc.stdout || "",
|
|
471
|
+
stderr: proc.stderr || "",
|
|
472
|
+
finalText,
|
|
473
|
+
status: proc.status,
|
|
474
|
+
errorCode: "invalid_json"
|
|
475
|
+
}),
|
|
401
476
|
blocker: {
|
|
402
477
|
code: "codex_invalid_json",
|
|
403
478
|
message: `Codex completed ${request.purpose}, but did not return valid JSON.`,
|
|
@@ -409,7 +484,17 @@ function createCodexExecJsonRunner(config = {}) {
|
|
|
409
484
|
ok: true,
|
|
410
485
|
json: parsed,
|
|
411
486
|
stdout: proc.stdout || "",
|
|
412
|
-
stderr: proc.stderr || ""
|
|
487
|
+
stderr: proc.stderr || "",
|
|
488
|
+
metrics: runnerMetrics({
|
|
489
|
+
request,
|
|
490
|
+
config,
|
|
491
|
+
startedAt,
|
|
492
|
+
startedMs,
|
|
493
|
+
stdout: proc.stdout || "",
|
|
494
|
+
stderr: proc.stderr || "",
|
|
495
|
+
finalText,
|
|
496
|
+
status: proc.status
|
|
497
|
+
})
|
|
413
498
|
};
|
|
414
499
|
} finally {
|
|
415
500
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
@@ -430,14 +515,21 @@ function payloadOrBlocker(raw, checkpoint) {
|
|
|
430
515
|
ok: false,
|
|
431
516
|
blocker: {
|
|
432
517
|
...blocker,
|
|
433
|
-
checkpoint
|
|
518
|
+
checkpoint,
|
|
519
|
+
details: {
|
|
520
|
+
...blocker.details || {},
|
|
521
|
+
runner_metrics: raw.metrics || null
|
|
522
|
+
}
|
|
434
523
|
}
|
|
435
524
|
};
|
|
436
525
|
}
|
|
437
526
|
return {
|
|
438
527
|
ok: true,
|
|
439
528
|
payload: raw.json,
|
|
440
|
-
summary: typeof raw.json.summary === "string" ? raw.json.summary : void 0
|
|
529
|
+
summary: typeof raw.json.summary === "string" ? raw.json.summary : void 0,
|
|
530
|
+
details: compactRecord({
|
|
531
|
+
runner_metrics: raw.metrics || null
|
|
532
|
+
})
|
|
441
533
|
};
|
|
442
534
|
}
|
|
443
535
|
function stringArray(value) {
|
|
@@ -573,14 +665,16 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
|
|
|
573
665
|
agent_summary: summary,
|
|
574
666
|
agent_changed_files: changedFiles,
|
|
575
667
|
agent_tests_run: testsRun,
|
|
576
|
-
agent_blockers: blockers
|
|
668
|
+
agent_blockers: blockers,
|
|
669
|
+
runner_metrics: raw.metrics || null
|
|
577
670
|
};
|
|
578
671
|
attemptSummaries.push({
|
|
579
672
|
purpose,
|
|
580
673
|
summary,
|
|
581
674
|
changed_files: changedFiles,
|
|
582
675
|
tests_run: testsRun,
|
|
583
|
-
blockers
|
|
676
|
+
blockers,
|
|
677
|
+
runner_metrics: raw.metrics || null
|
|
584
678
|
});
|
|
585
679
|
if (hardBlockers.length) {
|
|
586
680
|
return {
|