@akagilnc/pi-workflow-roles 0.1.1883 → 0.1.1918
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/evidence-child-executor.js +153 -16
- package/dist/navigator-attendance.js +64 -29
- package/dist/public-cli/main.js +786 -373
- package/dist/reviewer-child-executor.js +1 -1
- package/dist/typed-provider-http.js +60 -0
- package/dist/upstream-error-testimony.js +19 -0
- package/package.json +1 -1
- package/scripts/build-package.mjs +2 -0
- package/src/evidence-child-executor.ts +177 -24
- package/src/factory-board.ts +60 -3
- package/src/navigator-attendance.ts +86 -33
- package/src/public-cli/cli.ts +96 -39
- package/src/public-cli/coder-run.ts +36 -11
- package/src/public-cli/collector-run.ts +8 -3
- package/src/public-cli/doctor-run.ts +1 -0
- package/src/public-cli/explicit-internal.ts +61 -19
- package/src/public-cli/fixer-run.ts +36 -11
- package/src/public-cli/invocation.ts +137 -101
- package/src/public-cli/judge-run.ts +39 -11
- package/src/public-cli/merger-run.ts +36 -11
- package/src/public-cli/reviewer-run.ts +35 -11
- package/src/public-cli/run-lifecycle.ts +89 -76
- package/src/public-cli/settlement.ts +256 -66
- package/src/reviewer-child-executor.ts +1 -1
- package/src/role-runtime.ts +18 -8
- package/src/ticket-frontmatter.ts +94 -0
- package/src/ticket-trajectory.ts +145 -5
- package/src/typed-provider-http.ts +99 -0
- package/src/upstream-error-testimony.ts +45 -0
|
@@ -18,6 +18,12 @@ import { renderPublicAkRoleCommand } from "./public-command-renderer.ts";
|
|
|
18
18
|
import { issueRoot, subjectPath } from "./work-subject-identity.ts";
|
|
19
19
|
import { wrapPackageOwnedToolDefinition } from "./package-owned-tool-idle.ts";
|
|
20
20
|
import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_PROMPT } from "./receipt-delivery-policy.ts";
|
|
21
|
+
import { recordTypedProviderHttpStatus } from "./typed-provider-http.ts";
|
|
22
|
+
import {
|
|
23
|
+
hasUpstreamErrorTestimony,
|
|
24
|
+
isNonSuccessHttpStatus,
|
|
25
|
+
projectConfirmedRemotePayload,
|
|
26
|
+
} from "./upstream-error-testimony.ts";
|
|
21
27
|
|
|
22
28
|
export const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance" as const;
|
|
23
29
|
export const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare" as const;
|
|
@@ -1092,19 +1098,37 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1092
1098
|
}
|
|
1093
1099
|
assignProviderFailure(navigatorProviderFailureFromStatus(status));
|
|
1094
1100
|
};
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
+
/** Project only fields actually held on the call surface — never forge upstream payload. */
|
|
1102
|
+
const projectHeldUpstream = (error: unknown): Record<string, unknown> => {
|
|
1103
|
+
if (!exactRecord(error)) return {};
|
|
1104
|
+
// Shape reading stays local; testimony + confirmed-remote payload use shared authority.
|
|
1105
|
+
const status = typeof error.statusCode === "number"
|
|
1106
|
+
? error.statusCode
|
|
1107
|
+
: typeof error.status === "number"
|
|
1108
|
+
? error.status
|
|
1109
|
+
: typeof error.httpStatus === "number"
|
|
1110
|
+
? error.httpStatus
|
|
1111
|
+
: undefined;
|
|
1112
|
+
const httpStatus = isNonSuccessHttpStatus(status) ? status : undefined;
|
|
1113
|
+
const diagnostics = Array.isArray(error.diagnostics) && error.diagnostics.length > 0
|
|
1114
|
+
? error.diagnostics
|
|
1115
|
+
: undefined;
|
|
1116
|
+
const testimony = hasUpstreamErrorTestimony({
|
|
1117
|
+
...(httpStatus === undefined ? {} : { httpStatus }),
|
|
1118
|
+
...(diagnostics === undefined ? {} : { diagnostics }),
|
|
1119
|
+
});
|
|
1120
|
+
return {
|
|
1121
|
+
...(httpStatus === undefined ? {} : { statusCode: httpStatus, status: httpStatus }),
|
|
1122
|
+
...(diagnostics === undefined ? {} : { diagnostics }),
|
|
1123
|
+
...(testimony ? projectConfirmedRemotePayload(error) : {}),
|
|
1124
|
+
};
|
|
1101
1125
|
};
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
return
|
|
1126
|
+
/** Keep held upstream fields; strip only the local navigatorFailure classification marker. */
|
|
1127
|
+
const retainUpstreamMessage = <T extends Record<string, unknown>>(error: T): T => {
|
|
1128
|
+
if (!("navigatorFailure" in error)) return error;
|
|
1129
|
+
const copy = { ...error };
|
|
1130
|
+
delete copy.navigatorFailure;
|
|
1131
|
+
return copy;
|
|
1108
1132
|
};
|
|
1109
1133
|
const setupFailureMessage = (error: unknown) => ({
|
|
1110
1134
|
role: "assistant" as const,
|
|
@@ -1115,15 +1139,27 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1115
1139
|
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
|
|
1116
1140
|
stopReason: "error" as const,
|
|
1117
1141
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
1118
|
-
navigatorFailureEvidenceId: retainProviderFailure(error),
|
|
1119
1142
|
timestamp: Date.now(),
|
|
1143
|
+
...projectHeldUpstream(error),
|
|
1120
1144
|
});
|
|
1145
|
+
const persistNavigatorHttpObservation = async (
|
|
1146
|
+
status: number,
|
|
1147
|
+
model: unknown,
|
|
1148
|
+
): Promise<void> => {
|
|
1149
|
+
const runDir = process.env.AK_ROLE_RUN_DIR;
|
|
1150
|
+
if (typeof runDir !== "string" || runDir.trim() === "") return;
|
|
1151
|
+
const provider = exactRecord(model) && typeof model.provider === "string" && model.provider.trim() !== ""
|
|
1152
|
+
? model.provider
|
|
1153
|
+
: undefined;
|
|
1154
|
+
if (provider === undefined) return;
|
|
1155
|
+
await recordTypedProviderHttpStatus(runDir, { httpStatus: status, provider });
|
|
1156
|
+
};
|
|
1121
1157
|
const instrumentProvider = <TProvider extends NonNullable<typeof provider>>(sourceProvider: TProvider): TProvider => {
|
|
1122
1158
|
type StreamFn = TProvider["stream"];
|
|
1123
1159
|
type StreamSimpleFn = TProvider["streamSimple"];
|
|
1124
1160
|
type StreamOptionsArg = Parameters<StreamFn>[2];
|
|
1125
1161
|
type StreamSimpleOptionsArg = Parameters<StreamSimpleFn>[2];
|
|
1126
|
-
const instrumentStreamOptions = <TOptions>(options: TOptions): TOptions => {
|
|
1162
|
+
const instrumentStreamOptions = <TOptions>(options: TOptions, observedStatus: { value?: number }): TOptions => {
|
|
1127
1163
|
const record = (exactRecord(options) ? options : {}) as Record<string, unknown>;
|
|
1128
1164
|
const previous = typeof record.onResponse === "function"
|
|
1129
1165
|
? record.onResponse as (response: { status: number; headers: Record<string, string> }, model: unknown) => void | Promise<void>
|
|
@@ -1131,12 +1167,23 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1131
1167
|
return {
|
|
1132
1168
|
...record,
|
|
1133
1169
|
onResponse: async (response: { status: number; headers: Record<string, string> }, model: unknown) => {
|
|
1170
|
+
observedStatus.value = response.status;
|
|
1134
1171
|
classifyProviderResponseStatus(response.status);
|
|
1172
|
+
// Durable run-dossier sink for typed non-success HTTP (2xx clears).
|
|
1173
|
+
await persistNavigatorHttpObservation(response.status, model);
|
|
1135
1174
|
await previous?.(response, model);
|
|
1136
1175
|
},
|
|
1137
1176
|
} as TOptions;
|
|
1138
1177
|
};
|
|
1139
|
-
|
|
1178
|
+
/** Attach a directly observed non-success HTTP status when the terminal message lacks one. */
|
|
1179
|
+
const withObservedStatus = <T extends Record<string, unknown>>(message: T, observedStatus: number | undefined): T => {
|
|
1180
|
+
if (observedStatus === undefined || observedStatus >= 200 && observedStatus < 300) return message;
|
|
1181
|
+
if (typeof message.statusCode === "number" || typeof message.status === "number" || typeof message.httpStatus === "number") {
|
|
1182
|
+
return message;
|
|
1183
|
+
}
|
|
1184
|
+
return { ...message, statusCode: observedStatus, status: observedStatus };
|
|
1185
|
+
};
|
|
1186
|
+
const wrapProviderStream = (source: ReturnType<StreamFn>, observedStatus: { value?: number }): ReturnType<StreamFn> => {
|
|
1140
1187
|
const wrapped = createAssistantMessageEventStream();
|
|
1141
1188
|
void (async () => {
|
|
1142
1189
|
let result: Awaited<ReturnType<typeof source.result>> | undefined;
|
|
@@ -1147,13 +1194,14 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1147
1194
|
sawTerminal = true;
|
|
1148
1195
|
if (event.type === "done" && exactRecord(event.message)) {
|
|
1149
1196
|
assignProviderFailure(navigatorProviderFailureFromDiagnostics(event.message.diagnostics));
|
|
1150
|
-
|
|
1197
|
+
// Keep held message/status/body/code/errno/diagnostics on the session surface.
|
|
1198
|
+
result = withObservedStatus(retainUpstreamMessage(event.message), observedStatus.value) as typeof event.message;
|
|
1151
1199
|
wrapped.push({ ...event, message: result });
|
|
1152
1200
|
continue;
|
|
1153
1201
|
}
|
|
1154
1202
|
if (event.type === "error" && exactRecord(event.error)) {
|
|
1155
1203
|
classifyProviderStreamError(event.error);
|
|
1156
|
-
result =
|
|
1204
|
+
result = withObservedStatus(retainUpstreamMessage(event.error), observedStatus.value) as typeof event.error;
|
|
1157
1205
|
wrapped.push({ ...event, error: result });
|
|
1158
1206
|
continue;
|
|
1159
1207
|
}
|
|
@@ -1163,24 +1211,24 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1163
1211
|
// Only await result after a terminal done/error event. end(undefined) leaves result() unresolved forever.
|
|
1164
1212
|
if (sawTerminal) {
|
|
1165
1213
|
const terminal = await source.result();
|
|
1166
|
-
if (result === undefined && exactRecord(terminal))
|
|
1167
|
-
|
|
1214
|
+
if (result === undefined && exactRecord(terminal)) {
|
|
1215
|
+
result = withObservedStatus(retainUpstreamMessage(terminal), observedStatus.value) as typeof terminal;
|
|
1216
|
+
} else if (result === undefined) result = terminal;
|
|
1168
1217
|
}
|
|
1169
1218
|
} catch (error) {
|
|
1170
|
-
//
|
|
1219
|
+
// Stream throw: project held upstream fields onto the synthetic terminal message (session is durable).
|
|
1171
1220
|
classifyProviderStreamError(error);
|
|
1172
|
-
if (providerFailure === undefined) providerFailure = { source: "
|
|
1221
|
+
if (providerFailure === undefined) providerFailure = { source: "unknown", cause: "unknown" };
|
|
1173
1222
|
if (!sawTerminal) {
|
|
1174
|
-
const message = setupFailureMessage(error);
|
|
1223
|
+
const message = withObservedStatus(setupFailureMessage(error), observedStatus.value);
|
|
1175
1224
|
wrapped.push({ type: "error", reason: "error", error: message });
|
|
1176
1225
|
result = message;
|
|
1177
1226
|
sawTerminal = true;
|
|
1178
1227
|
}
|
|
1179
1228
|
} finally {
|
|
1180
|
-
// No terminal stream event
|
|
1181
|
-
// Emit a synthetic error so callers do not hang waiting for done/error, and never await an unresolved source.result().
|
|
1229
|
+
// No terminal stream event: unknown only — do not forge upstream payload.
|
|
1182
1230
|
if (!sawTerminal) {
|
|
1183
|
-
if (providerFailure === undefined) providerFailure = { source: "
|
|
1231
|
+
if (providerFailure === undefined) providerFailure = { source: "unknown", cause: "unknown" };
|
|
1184
1232
|
const message = setupFailureMessage(new Error("Navigator provider produced no response"));
|
|
1185
1233
|
wrapped.push({ type: "error", reason: "error", error: message });
|
|
1186
1234
|
result = message;
|
|
@@ -1191,15 +1239,16 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1191
1239
|
})();
|
|
1192
1240
|
return wrapped as ReturnType<StreamFn>;
|
|
1193
1241
|
};
|
|
1194
|
-
const invokeInstrumentedStream = (invoke: () => ReturnType<StreamFn>): ReturnType<StreamFn> => {
|
|
1242
|
+
const invokeInstrumentedStream = (invoke: (observedStatus: { value?: number }) => ReturnType<StreamFn>): ReturnType<StreamFn> => {
|
|
1195
1243
|
// Reset before invoking the selected provider so setup throws cannot leave a prior call's fact.
|
|
1196
1244
|
providerFailure = undefined;
|
|
1245
|
+
const observedStatus: { value?: number } = {};
|
|
1197
1246
|
try {
|
|
1198
|
-
return wrapProviderStream(invoke());
|
|
1247
|
+
return wrapProviderStream(invoke(observedStatus), observedStatus);
|
|
1199
1248
|
} catch (error) {
|
|
1200
|
-
//
|
|
1249
|
+
// Setup failures become terminal synthetic errors with held upstream fields projected when present.
|
|
1201
1250
|
classifyProviderStreamError(error);
|
|
1202
|
-
if (providerFailure === undefined) providerFailure = { source: "
|
|
1251
|
+
if (providerFailure === undefined) providerFailure = { source: "unknown", cause: "unknown" };
|
|
1203
1252
|
const wrapped = createAssistantMessageEventStream();
|
|
1204
1253
|
const message = setupFailureMessage(error);
|
|
1205
1254
|
queueMicrotask(() => {
|
|
@@ -1212,12 +1261,16 @@ export function createNativeNavigatorSessionFactory(defaultModelSettingPath = na
|
|
|
1212
1261
|
return {
|
|
1213
1262
|
...sourceProvider,
|
|
1214
1263
|
stream(model: Parameters<StreamFn>[0], streamContext: Parameters<StreamFn>[1], options: StreamOptionsArg) {
|
|
1215
|
-
|
|
1216
|
-
|
|
1264
|
+
return invokeInstrumentedStream((observedStatus) => {
|
|
1265
|
+
const instrumented = instrumentStreamOptions(options, observedStatus);
|
|
1266
|
+
return sourceProvider.stream(model, streamContext, instrumented) as ReturnType<StreamFn>;
|
|
1267
|
+
}) as ReturnType<StreamFn>;
|
|
1217
1268
|
},
|
|
1218
1269
|
streamSimple(model: Parameters<StreamSimpleFn>[0], streamContext: Parameters<StreamSimpleFn>[1], options: StreamSimpleOptionsArg) {
|
|
1219
|
-
|
|
1220
|
-
|
|
1270
|
+
return invokeInstrumentedStream((observedStatus) => {
|
|
1271
|
+
const instrumented = instrumentStreamOptions(options, observedStatus);
|
|
1272
|
+
return sourceProvider.streamSimple(model, streamContext, instrumented) as ReturnType<StreamFn>;
|
|
1273
|
+
}) as ReturnType<StreamSimpleFn>;
|
|
1221
1274
|
},
|
|
1222
1275
|
} as TProvider;
|
|
1223
1276
|
};
|
package/src/public-cli/cli.ts
CHANGED
|
@@ -61,6 +61,69 @@ export {
|
|
|
61
61
|
export { CliUsageError } from "./cli-errors.ts";
|
|
62
62
|
export type { CliIo } from "./cli-io.ts";
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Sole production map: public role command → argv parser.
|
|
66
|
+
* cli handlers consume this table; no parallel set.
|
|
67
|
+
*/
|
|
68
|
+
export const PUBLIC_ROLE_ARGV = {
|
|
69
|
+
judge: { parse: parseJudgeArgv },
|
|
70
|
+
coder: { parse: parseCoderArgv },
|
|
71
|
+
fixer: { parse: parseFixerArgv },
|
|
72
|
+
collector: { parse: parseCollectorArgv },
|
|
73
|
+
doctor: { parse: parseDoctorArgv },
|
|
74
|
+
merger: { parse: parseMergerArgv },
|
|
75
|
+
reviewer: { parse: parseReviewerArgv },
|
|
76
|
+
} as const;
|
|
77
|
+
|
|
78
|
+
type TakenPublicGlobalFlag =
|
|
79
|
+
| { flag: "help"; consume: 1 }
|
|
80
|
+
| { flag: "model"; consume: 1 | 2; value: string | undefined }
|
|
81
|
+
| { flag: "thinking"; consume: 1 | 2; raw: string | undefined };
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* If `argv[index]` is a public global flag, describe its span and payload.
|
|
85
|
+
* Sole global-flag grammar for parseArgv.
|
|
86
|
+
*/
|
|
87
|
+
function takePublicGlobalFlag(
|
|
88
|
+
argv: readonly string[],
|
|
89
|
+
index: number,
|
|
90
|
+
): TakenPublicGlobalFlag | undefined {
|
|
91
|
+
const token = argv[index];
|
|
92
|
+
if (token === undefined) return undefined;
|
|
93
|
+
if (token === "--help" || token === "-h") {
|
|
94
|
+
return { flag: "help", consume: 1 };
|
|
95
|
+
}
|
|
96
|
+
if (token === "--model") {
|
|
97
|
+
const value = argv[index + 1];
|
|
98
|
+
if (value === undefined) {
|
|
99
|
+
return { flag: "model", consume: 1, value: undefined };
|
|
100
|
+
}
|
|
101
|
+
return { flag: "model", consume: 2, value };
|
|
102
|
+
}
|
|
103
|
+
if (token.startsWith("--model=")) {
|
|
104
|
+
return {
|
|
105
|
+
flag: "model",
|
|
106
|
+
consume: 1,
|
|
107
|
+
value: token.slice("--model=".length),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (token === "--thinking") {
|
|
111
|
+
const raw = argv[index + 1];
|
|
112
|
+
if (raw === undefined) {
|
|
113
|
+
return { flag: "thinking", consume: 1, raw: undefined };
|
|
114
|
+
}
|
|
115
|
+
return { flag: "thinking", consume: 2, raw };
|
|
116
|
+
}
|
|
117
|
+
if (token.startsWith("--thinking=")) {
|
|
118
|
+
return {
|
|
119
|
+
flag: "thinking",
|
|
120
|
+
consume: 1,
|
|
121
|
+
raw: token.slice("--thinking=".length),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
64
127
|
export type CliEnv = {
|
|
65
128
|
home?: string;
|
|
66
129
|
agentDir?: string;
|
|
@@ -167,44 +230,38 @@ function parseArgv(argv: readonly string[]): ParsedGlobal {
|
|
|
167
230
|
|
|
168
231
|
// Global flags may appear before or after the subcommand
|
|
169
232
|
// (`ak-role --model x roles` and `ak-role roles --model x`).
|
|
233
|
+
// Grammar authority: takePublicGlobalFlag above.
|
|
170
234
|
while (args.length > 0) {
|
|
171
|
-
|
|
172
|
-
|
|
235
|
+
if (args[0] === "--") {
|
|
236
|
+
args.shift();
|
|
173
237
|
positional.push(...args);
|
|
174
238
|
break;
|
|
175
239
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
model
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (token.startsWith("--thinking=")) {
|
|
197
|
-
thinking = parseThinking(token.slice("--thinking=".length));
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
if (token.startsWith("-") && token !== "-") {
|
|
201
|
-
// Subcommands may own additional flags later; only reject unknowns at the
|
|
202
|
-
// top level when they appear before any positional command is collected
|
|
203
|
-
// and the command is one that does not accept free flags (enforced below).
|
|
204
|
-
positional.push(token);
|
|
240
|
+
const taken = takePublicGlobalFlag(args, 0);
|
|
241
|
+
if (taken !== undefined) {
|
|
242
|
+
if (taken.flag === "help") {
|
|
243
|
+
help = true;
|
|
244
|
+
args.splice(0, taken.consume);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (taken.flag === "model") {
|
|
248
|
+
if (taken.value === undefined) {
|
|
249
|
+
throw new CliUsageError("--model requires a value");
|
|
250
|
+
}
|
|
251
|
+
model = taken.value;
|
|
252
|
+
args.splice(0, taken.consume);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (taken.raw === undefined) {
|
|
256
|
+
throw new CliUsageError("--thinking requires a value");
|
|
257
|
+
}
|
|
258
|
+
thinking = parseThinking(taken.raw);
|
|
259
|
+
args.splice(0, taken.consume);
|
|
205
260
|
continue;
|
|
206
261
|
}
|
|
207
|
-
|
|
262
|
+
// Subcommands may own additional flags later; unknown dashed tokens stay
|
|
263
|
+
// positional here (same as pre-unification parseArgv).
|
|
264
|
+
positional.push(args.shift()!);
|
|
208
265
|
}
|
|
209
266
|
|
|
210
267
|
const [command, ...rest] = positional;
|
|
@@ -626,7 +683,7 @@ export async function runAkRole(
|
|
|
626
683
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
627
684
|
},
|
|
628
685
|
io,
|
|
629
|
-
|
|
686
|
+
PUBLIC_ROLE_ARGV.judge.parse,
|
|
630
687
|
);
|
|
631
688
|
return {
|
|
632
689
|
exitCode: result.exitCode,
|
|
@@ -669,7 +726,7 @@ export async function runAkRole(
|
|
|
669
726
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
670
727
|
},
|
|
671
728
|
io,
|
|
672
|
-
|
|
729
|
+
PUBLIC_ROLE_ARGV.coder.parse,
|
|
673
730
|
);
|
|
674
731
|
return {
|
|
675
732
|
exitCode: result.exitCode,
|
|
@@ -712,7 +769,7 @@ export async function runAkRole(
|
|
|
712
769
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
713
770
|
},
|
|
714
771
|
io,
|
|
715
|
-
|
|
772
|
+
PUBLIC_ROLE_ARGV.fixer.parse,
|
|
716
773
|
);
|
|
717
774
|
return {
|
|
718
775
|
exitCode: result.exitCode,
|
|
@@ -755,7 +812,7 @@ export async function runAkRole(
|
|
|
755
812
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
756
813
|
},
|
|
757
814
|
io,
|
|
758
|
-
|
|
815
|
+
PUBLIC_ROLE_ARGV.collector.parse,
|
|
759
816
|
);
|
|
760
817
|
return {
|
|
761
818
|
exitCode: result.exitCode,
|
|
@@ -798,7 +855,7 @@ export async function runAkRole(
|
|
|
798
855
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
799
856
|
},
|
|
800
857
|
io,
|
|
801
|
-
|
|
858
|
+
PUBLIC_ROLE_ARGV.reviewer.parse,
|
|
802
859
|
);
|
|
803
860
|
return {
|
|
804
861
|
exitCode: result.exitCode,
|
|
@@ -841,7 +898,7 @@ export async function runAkRole(
|
|
|
841
898
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
842
899
|
},
|
|
843
900
|
io,
|
|
844
|
-
|
|
901
|
+
PUBLIC_ROLE_ARGV.doctor.parse,
|
|
845
902
|
);
|
|
846
903
|
return {
|
|
847
904
|
exitCode: result.exitCode,
|
|
@@ -884,7 +941,7 @@ export async function runAkRole(
|
|
|
884
941
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
885
942
|
},
|
|
886
943
|
io,
|
|
887
|
-
|
|
944
|
+
PUBLIC_ROLE_ARGV.merger.parse,
|
|
888
945
|
);
|
|
889
946
|
return {
|
|
890
947
|
exitCode: result.exitCode,
|
|
@@ -41,11 +41,11 @@ import {
|
|
|
41
41
|
markRunResumable,
|
|
42
42
|
markRunRunning,
|
|
43
43
|
markRunTerminal,
|
|
44
|
-
readTypedHttp429Observation,
|
|
45
44
|
renderResumeCommand,
|
|
46
45
|
RESUME_TRANSPORT_ENVELOPE,
|
|
47
46
|
RunWriterLeaseHeldError,
|
|
48
47
|
type RunWriterLease,
|
|
48
|
+
type TypedProviderHttpObservation,
|
|
49
49
|
} from "./run-lifecycle.ts";
|
|
50
50
|
import {
|
|
51
51
|
classifyPostAdmissionFailure,
|
|
@@ -58,7 +58,9 @@ import {
|
|
|
58
58
|
presentFailureTerminal,
|
|
59
59
|
presentStructuralRejection,
|
|
60
60
|
explicitInternalKnownFailureClassificationInput,
|
|
61
|
-
|
|
61
|
+
resolveAuditedRunnerFailureResolution,
|
|
62
|
+
resolveControlledFailureResumeObservation,
|
|
63
|
+
controlledFailureInputFromResolution,
|
|
62
64
|
settleFailureTerminalResult,
|
|
63
65
|
trySettleCoderTerminalResult,
|
|
64
66
|
} from "./settlement.ts";
|
|
@@ -196,6 +198,8 @@ async function presentControlledFailure(
|
|
|
196
198
|
readonly code?: string | number;
|
|
197
199
|
};
|
|
198
200
|
knownDiagnostic?: string;
|
|
201
|
+
typedHttpObservationSettled?: true;
|
|
202
|
+
typedHttpObservation?: TypedProviderHttpObservation;
|
|
199
203
|
},
|
|
200
204
|
io: CliIo,
|
|
201
205
|
): Promise<{
|
|
@@ -204,10 +208,23 @@ async function presentControlledFailure(
|
|
|
204
208
|
terminal: TerminalResult;
|
|
205
209
|
}> {
|
|
206
210
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
211
|
+
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
212
|
+
runDirectory: admitted.runDirectory,
|
|
213
|
+
...(failureInput.typedHttpObservationSettled === true
|
|
214
|
+
? {
|
|
215
|
+
typedHttpObservationSettled: true as const,
|
|
216
|
+
...(failureInput.typedHttpObservation === undefined
|
|
217
|
+
? {}
|
|
218
|
+
: { typedHttpObservation: failureInput.typedHttpObservation }),
|
|
219
|
+
}
|
|
220
|
+
: {}),
|
|
221
|
+
});
|
|
222
|
+
const knownFailure =
|
|
223
|
+
failureInput.knownFailure ?? resumeObservation.observationReadFailure;
|
|
207
224
|
const session =
|
|
208
225
|
!hasThrown &&
|
|
209
226
|
!failureInput.timedOut &&
|
|
210
|
-
|
|
227
|
+
knownFailure === undefined &&
|
|
211
228
|
failureInput.knownCause === undefined
|
|
212
229
|
? await inspectJudgeSession(admitted.sessionFile)
|
|
213
230
|
: undefined;
|
|
@@ -216,7 +233,7 @@ async function presentControlledFailure(
|
|
|
216
233
|
code: failureInput.code,
|
|
217
234
|
stderr: failureInput.stderr,
|
|
218
235
|
...(hasThrown ? { thrown: failureInput.thrown } : {}),
|
|
219
|
-
...explicitInternalKnownFailureClassificationInput(
|
|
236
|
+
...explicitInternalKnownFailureClassificationInput(knownFailure),
|
|
220
237
|
...(failureInput.knownCause === undefined
|
|
221
238
|
? {}
|
|
222
239
|
: { knownCause: failureInput.knownCause }),
|
|
@@ -230,7 +247,7 @@ async function presentControlledFailure(
|
|
|
230
247
|
});
|
|
231
248
|
|
|
232
249
|
const hasLawfulTerminalResult = await hasLawfulCoderTerminalResult(admitted);
|
|
233
|
-
const typedHttp429 =
|
|
250
|
+
const typedHttp429 = resumeObservation.typedHttp429;
|
|
234
251
|
const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
|
|
235
252
|
admitted.sessionFile,
|
|
236
253
|
);
|
|
@@ -296,8 +313,9 @@ async function dispatchAdmittedCoder(input: {
|
|
|
296
313
|
PI_CODING_AGENT_DIR: env.agentDir,
|
|
297
314
|
AK_ROLE_RUN_DIR: admitted.runDirectory,
|
|
298
315
|
};
|
|
299
|
-
|
|
300
|
-
|
|
316
|
+
const correlationId = admitted.correlationId ?? env.correlationId;
|
|
317
|
+
if (correlationId !== undefined && correlationId.trim() !== "") {
|
|
318
|
+
childEnv.AK_CORRELATION_ID = correlationId;
|
|
301
319
|
}
|
|
302
320
|
|
|
303
321
|
let result: ExplicitInternalPiResult;
|
|
@@ -369,10 +387,11 @@ async function dispatchAdmittedCoder(input: {
|
|
|
369
387
|
env.model,
|
|
370
388
|
env.credentials,
|
|
371
389
|
);
|
|
372
|
-
const
|
|
390
|
+
const resolution = await resolveAuditedRunnerFailureResolution({
|
|
373
391
|
runner: result.knownFailure,
|
|
374
392
|
sessionFile: admitted.sessionFile,
|
|
375
393
|
credential: credentialFailure,
|
|
394
|
+
runDirectory: admitted.runDirectory,
|
|
376
395
|
});
|
|
377
396
|
return await presentControlledFailure(
|
|
378
397
|
admitted,
|
|
@@ -380,7 +399,7 @@ async function dispatchAdmittedCoder(input: {
|
|
|
380
399
|
timedOut: result.timedOut,
|
|
381
400
|
code: result.code,
|
|
382
401
|
stderr: result.stderr,
|
|
383
|
-
...(
|
|
402
|
+
...controlledFailureInputFromResolution(resolution),
|
|
384
403
|
},
|
|
385
404
|
io,
|
|
386
405
|
);
|
|
@@ -469,7 +488,10 @@ export async function runPublicCoder(
|
|
|
469
488
|
|
|
470
489
|
return await dispatchAdmittedCoder({
|
|
471
490
|
admitted,
|
|
472
|
-
env
|
|
491
|
+
env: {
|
|
492
|
+
...env,
|
|
493
|
+
...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
|
|
494
|
+
},
|
|
473
495
|
io,
|
|
474
496
|
extraArgs,
|
|
475
497
|
lease,
|
|
@@ -563,7 +585,10 @@ export async function runPublicCoderResume(
|
|
|
563
585
|
|
|
564
586
|
return await dispatchAdmittedCoder({
|
|
565
587
|
admitted,
|
|
566
|
-
env
|
|
588
|
+
env: {
|
|
589
|
+
...env,
|
|
590
|
+
...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
|
|
591
|
+
},
|
|
567
592
|
io,
|
|
568
593
|
extraArgs,
|
|
569
594
|
lease,
|
|
@@ -211,8 +211,9 @@ async function dispatchAdmittedCollector(input: {
|
|
|
211
211
|
PI_CODING_AGENT_DIR: env.agentDir,
|
|
212
212
|
AK_ROLE_RUN_DIR: admitted.runDirectory,
|
|
213
213
|
};
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
const correlationId = admitted.correlationId ?? env.correlationId;
|
|
215
|
+
if (correlationId !== undefined && correlationId.trim() !== "") {
|
|
216
|
+
childEnv.AK_CORRELATION_ID = correlationId;
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
let result: ExplicitInternalPiResult;
|
|
@@ -299,6 +300,7 @@ async function dispatchAdmittedCollector(input: {
|
|
|
299
300
|
}),
|
|
300
301
|
sessionFile: admitted.sessionFile,
|
|
301
302
|
credential: credentialFailure,
|
|
303
|
+
runDirectory: admitted.runDirectory,
|
|
302
304
|
});
|
|
303
305
|
return await presentControlledFailure(
|
|
304
306
|
admitted,
|
|
@@ -367,7 +369,10 @@ export async function runPublicCollector(
|
|
|
367
369
|
|
|
368
370
|
return await dispatchAdmittedCollector({
|
|
369
371
|
admitted,
|
|
370
|
-
env
|
|
372
|
+
env: {
|
|
373
|
+
...env,
|
|
374
|
+
...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
|
|
375
|
+
},
|
|
371
376
|
io,
|
|
372
377
|
extraArgs,
|
|
373
378
|
lease,
|
|
@@ -280,6 +280,7 @@ async function dispatchAdmittedDoctor(input: {
|
|
|
280
280
|
runner: result.knownFailure,
|
|
281
281
|
sessionFile: admitted.sessionFile,
|
|
282
282
|
credential: credentialFailure,
|
|
283
|
+
runDirectory: admitted.runDirectory,
|
|
283
284
|
});
|
|
284
285
|
return await presentControlledFailure(
|
|
285
286
|
admitted,
|