@akagilnc/pi-workflow-roles 0.1.5845 → 0.1.5853
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/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/dist/acp-host/production-host.js +348 -1254
- package/dist/acp-host/role-turn-host.js +4 -98
- package/dist/headless-host/production-host.js +15731 -16582
- package/dist/headless-host/role-turn-host.js +6 -31
- package/dist/migrate-book-topology.js +31 -16
- package/dist/navigator-attendance.js +54 -404
- package/dist/navigator-invocation-identity.js +0 -2
- package/dist/navigator-lookup-host.js +41 -0
- package/dist/navigator-lookup.js +68 -0
- package/dist/navigator-route-table.js +42 -0
- package/dist/package-contracts/navigator-output.js +3 -11
- package/dist/packaged-role-registry.js +3 -27
- package/dist/public-cli/instruction-seat-run.js +4 -1
- package/dist/public-cli/invocation.js +13 -26
- package/dist/public-cli/main.js +286 -114
- package/dist/public-cli/option-definitions.js +24 -4
- package/dist/public-cli/post-admission.js +0 -9
- package/dist/public-cli/role-seat-runtime.js +14 -0
- package/dist/public-cli/settlement.js +14 -40
- package/dist/public-cli/terminal.js +1 -8
- package/dist/public-cli/turn-request.js +0 -3
- package/dist/public-role-summons.js +0 -1
- package/dist/receipt-delivery-policy.js +0 -23
- package/dist/role-runtime-dependencies.js +4 -11
- package/dist/role-runtime.js +18 -194
- package/dist/submission-ledger.js +19 -15
- package/dist/ticket-progress.js +23 -5
- package/extensions/role-runtime.ts +0 -16
- package/package.json +1 -1
- package/scripts/build-package.mjs +3 -7
- package/src/acp-host/role-turn-host.ts +8 -97
- package/src/headless-host/description.ts +0 -2
- package/src/headless-host/role-turn-host.ts +7 -32
- package/src/host-contracts.ts +5 -7
- package/src/navigator-attendance.ts +86 -549
- package/src/navigator-invocation-identity.ts +0 -2
- package/src/navigator-lookup-host.ts +45 -0
- package/src/navigator-lookup.ts +98 -0
- package/src/navigator-route-table.ts +92 -0
- package/src/package-contracts/navigator-output.ts +4 -15
- package/src/packaged-role-registry.ts +3 -32
- package/src/public-cli/instruction-seat-run.ts +3 -0
- package/src/public-cli/invocation.ts +18 -30
- package/src/public-cli/option-definitions.ts +25 -4
- package/src/public-cli/post-admission.ts +0 -11
- package/src/public-cli/role-seat-runtime.ts +14 -0
- package/src/public-cli/settlement.ts +23 -51
- package/src/public-cli/terminal.ts +3 -18
- package/src/public-cli/turn-request.ts +0 -5
- package/src/public-role-summons.ts +0 -8
- package/src/receipt-delivery-policy.ts +0 -21
- package/src/role-runtime-dependencies.ts +4 -11
- package/src/role-runtime.ts +19 -210
- package/src/submission-ledger.ts +23 -16
- package/src/ticket-progress.ts +32 -5
- package/dist/navigator-public-session.js +0 -205
- package/dist/navigator-role.js +0 -6
- package/dist/navigator-session-contracts.js +0 -227
- package/dist/navigator-work-context.js +0 -72
- package/resources/navigator-route-playbook.md +0 -33
- package/src/navigator-public-session.ts +0 -305
- package/src/navigator-role.ts +0 -15
- package/src/navigator-session-contracts.ts +0 -320
- package/src/navigator-work-context.ts +0 -97
|
@@ -1,393 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join, resolve } from "node:path";
|
|
4
|
-
import {} from "typebox";
|
|
1
|
+
import { mintNavigatorInvocationId, NAVIGATOR_INVOCATION_ENTRY } from "./navigator-invocation-identity.js";
|
|
5
2
|
import {
|
|
6
|
-
NAVIGATOR_INVOCATION_ENTRY,
|
|
7
|
-
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
8
|
-
mintNavigatorInvocationId
|
|
9
|
-
} from "./navigator-invocation-identity.js";
|
|
10
|
-
import { PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.js";
|
|
11
|
-
import {
|
|
12
|
-
activationBookDirectory,
|
|
13
|
-
resolveActivationLedgerHome
|
|
14
|
-
} from "./activation-ledger-topology.js";
|
|
15
|
-
import { createNativeNavigatorSessionFactory } from "./navigator-public-session.js";
|
|
16
|
-
import {
|
|
17
|
-
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
18
3
|
NavigatorUnavailableError,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
navigatorProviderFailureFromPublicTerminal,
|
|
24
|
-
navigatorProviderFailureFromStatus,
|
|
25
|
-
navigatorUnavailableError,
|
|
26
|
-
parseNavigatorModelSetting,
|
|
27
|
-
readNavigatorModelSetting,
|
|
28
|
-
resolveNavigatorSeatSelection,
|
|
29
|
-
writeNavigatorModelSetting
|
|
30
|
-
} from "./navigator-session-contracts.js";
|
|
31
|
-
import { sitianReport } from "./sitian-facade.js";
|
|
32
|
-
import { issueRoot, subjectPath } from "./work-subject-identity.js";
|
|
33
|
-
import { createReceiptDeliveryPolicy } from "./receipt-delivery-policy.js";
|
|
34
|
-
import {
|
|
35
|
-
byStatusToPlainObject,
|
|
36
|
-
mergePreparedAdvice,
|
|
37
|
-
navigatorAdviceBodySchema,
|
|
38
|
-
pickPreparedProse,
|
|
39
|
-
preparedAdviceFromUnknown
|
|
40
|
-
} from "./package-contracts/navigator-output.js";
|
|
41
|
-
import { sha256Hex } from "./sha256.js";
|
|
42
|
-
import { isRecord } from "./unknown-value.js";
|
|
4
|
+
navigatorUnavailableError
|
|
5
|
+
} from "./navigator-lookup.js";
|
|
6
|
+
import { pickPreparedProse } from "./package-contracts/navigator-output.js";
|
|
7
|
+
import { subjectPath } from "./work-subject-identity.js";
|
|
43
8
|
const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
44
|
-
const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
|
|
45
|
-
const prepareSchema = navigatorAdviceBodySchema;
|
|
46
|
-
const INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
|
|
47
|
-
const SETTLEMENT_ENTRY = "ak-navigator-settlement";
|
|
48
|
-
const unavailableKeys = /* @__PURE__ */ new Set(["context", "session", "model", "thinking", "auth", "quota", "transport", "unknown"]);
|
|
49
|
-
function unavailableKey(value) {
|
|
50
|
-
return typeof value === "string" && unavailableKeys.has(value) ? value : void 0;
|
|
51
|
-
}
|
|
52
|
-
function rejectedPrepareReason(entries, start) {
|
|
53
|
-
const recent = entries.slice(start);
|
|
54
|
-
const prepareCalls = /* @__PURE__ */ new Set();
|
|
55
|
-
for (const entry of recent) {
|
|
56
|
-
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
|
|
57
|
-
for (const part of entry.message.content) {
|
|
58
|
-
if (isRecord(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
let reason;
|
|
62
|
-
for (const entry of recent) {
|
|
63
|
-
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
|
|
64
|
-
const callId = entry.message.toolCallId;
|
|
65
|
-
if (entry.message.toolName !== NAVIGATOR_PREPARE_TOOL_NAME || typeof callId !== "string" || !prepareCalls.has(callId)) {
|
|
66
|
-
return void 0;
|
|
67
|
-
}
|
|
68
|
-
const content = entry.message.content;
|
|
69
|
-
const text = Array.isArray(content) ? content.flatMap((part) => isRecord(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
|
|
70
|
-
if (text.trim() !== "") reason = text.trim();
|
|
71
|
-
}
|
|
72
|
-
return reason;
|
|
73
|
-
}
|
|
74
|
-
function normalizePreparedAdvice(value) {
|
|
75
|
-
return preparedAdviceFromUnknown(value);
|
|
76
|
-
}
|
|
77
|
-
function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
|
|
78
|
-
if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
|
|
79
|
-
if (provenance === "placeholder") return subjectRoot;
|
|
80
|
-
const normalized = subject.trim().replace(/\s+/g, " ");
|
|
81
|
-
if (normalized === "") return subjectRoot;
|
|
82
|
-
return `${subjectRoot}#${sha256Hex(normalized).slice(0, 32)}`;
|
|
83
|
-
}
|
|
84
|
-
function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
|
|
85
|
-
if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
|
|
86
|
-
const resolvedReference = resolve(cwd, reference);
|
|
87
|
-
const marker = "/runs/";
|
|
88
|
-
if (resolvedReference.includes(marker)) {
|
|
89
|
-
return subjectRoot;
|
|
90
|
-
}
|
|
91
|
-
return navigatorSubjectKey(subjectRoot, resolvedReference);
|
|
92
|
-
}
|
|
93
|
-
function createNavigatorPrepareTool(onOutput) {
|
|
94
|
-
return {
|
|
95
|
-
name: NAVIGATOR_PREPARE_TOOL_NAME,
|
|
96
|
-
label: "\u6E38\u5955\u4F7F\u51C6\u5907",
|
|
97
|
-
description: "\u63D0\u4EA4\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\u3002",
|
|
98
|
-
parameters: prepareSchema,
|
|
99
|
-
async execute(_id, value) {
|
|
100
|
-
onOutput(value);
|
|
101
|
-
return { content: [], details: value, terminate: true };
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
9
|
function formatNavigatorReport(report) {
|
|
106
|
-
|
|
107
|
-
if (report.disposition === "
|
|
108
|
-
if (report.disposition === "
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
if (report.disposition === "arrival") {
|
|
112
|
-
return [...playbookFailure, ...report.arrivalMessage ? [report.arrivalMessage] : []].join("\n");
|
|
113
|
-
}
|
|
114
|
-
return [...playbookFailure, ...report.prose ? [report.prose] : []].join("\n");
|
|
10
|
+
if (report.disposition === "no-advice") return "";
|
|
11
|
+
if (report.disposition === "unavailable") return report.unavailableReason ?? "";
|
|
12
|
+
if (report.disposition === "arrival") return report.arrivalMessage ?? "";
|
|
13
|
+
return report.prose ?? "";
|
|
115
14
|
}
|
|
116
15
|
function createNavigatorAttendance(options) {
|
|
16
|
+
const { subjectKey } = options;
|
|
117
17
|
let preparation;
|
|
118
18
|
let preparationInFlight = false;
|
|
119
|
-
let sessionReady;
|
|
120
|
-
let session;
|
|
121
|
-
let subjectKey = options.subjectKey;
|
|
122
|
-
let contextError = options.contextError;
|
|
123
19
|
let preparedAdvice;
|
|
124
|
-
const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
|
|
125
|
-
let activeInvocationId = invocationPrincipal;
|
|
126
|
-
let outputSink;
|
|
127
|
-
let settlementTail = Promise.resolve();
|
|
128
|
-
let settlementFailure;
|
|
129
20
|
let preparationFailure;
|
|
130
|
-
let
|
|
21
|
+
let settlementTail = Promise.resolve();
|
|
131
22
|
let disposed = false;
|
|
132
|
-
|
|
23
|
+
const invocationId = options.invocationId ?? mintNavigatorInvocationId();
|
|
133
24
|
const nestCancel = new AbortController();
|
|
134
|
-
const
|
|
25
|
+
const lookupContext = () => {
|
|
135
26
|
const parentSignal = options.context.signal;
|
|
136
27
|
const signal = parentSignal === void 0 ? nestCancel.signal : AbortSignal.any([nestCancel.signal, parentSignal]);
|
|
137
28
|
return { ...options.context, signal };
|
|
138
29
|
};
|
|
139
|
-
const unavailable = (
|
|
140
|
-
const failure =
|
|
30
|
+
const unavailable = (reason) => {
|
|
31
|
+
const failure = navigatorUnavailableError("unknown", reason);
|
|
141
32
|
return {
|
|
142
33
|
disposition: "unavailable",
|
|
143
34
|
unavailableReason: failure.message,
|
|
144
|
-
unavailableSource: failure.unavailableSource
|
|
145
|
-
unavailableCause: failure.unavailableCause
|
|
146
|
-
};
|
|
147
|
-
};
|
|
148
|
-
const loadMaterialsAndSession = async (invocationId) => {
|
|
149
|
-
if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
|
|
150
|
-
const modelPromise = (async () => {
|
|
151
|
-
try {
|
|
152
|
-
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
153
|
-
return resolved.configuredLabel;
|
|
154
|
-
} catch (error) {
|
|
155
|
-
if (error instanceof NavigatorUnavailableError) throw error;
|
|
156
|
-
throw navigatorUnavailableError("model", error);
|
|
157
|
-
}
|
|
158
|
-
})();
|
|
159
|
-
const modelSetting = await modelPromise;
|
|
160
|
-
let model;
|
|
161
|
-
try {
|
|
162
|
-
model = parseNavigatorModelSetting(modelSetting);
|
|
163
|
-
} catch (error) {
|
|
164
|
-
throw navigatorUnavailableError("model", error);
|
|
165
|
-
}
|
|
166
|
-
const tool = createNavigatorPrepareTool((value) => {
|
|
167
|
-
outputSink?.(value);
|
|
168
|
-
});
|
|
169
|
-
if (session === void 0) {
|
|
170
|
-
sessionReady = (async () => {
|
|
171
|
-
let created;
|
|
172
|
-
try {
|
|
173
|
-
created = await options.createSession({
|
|
174
|
-
context: sessionHostContext(),
|
|
175
|
-
subject: subjectKey,
|
|
176
|
-
...options.modelSettingPath === void 0 ? {} : { modelSettingPath: options.modelSettingPath },
|
|
177
|
-
tool
|
|
178
|
-
});
|
|
179
|
-
} catch (error) {
|
|
180
|
-
throw navigatorUnavailableError("session", error);
|
|
181
|
-
}
|
|
182
|
-
if (disposed) {
|
|
183
|
-
await created.dispose();
|
|
184
|
-
throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
185
|
-
}
|
|
186
|
-
try {
|
|
187
|
-
await created.setModel?.(modelSetting, model.thinkingLevel);
|
|
188
|
-
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
189
|
-
created.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
|
|
190
|
-
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
191
|
-
session = created;
|
|
192
|
-
return created;
|
|
193
|
-
} catch (error) {
|
|
194
|
-
if (session !== created) await created.dispose();
|
|
195
|
-
throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("session", error);
|
|
196
|
-
}
|
|
197
|
-
})();
|
|
198
|
-
await sessionReady;
|
|
199
|
-
sessionReady = void 0;
|
|
200
|
-
} else {
|
|
201
|
-
try {
|
|
202
|
-
await session.setModel?.(modelSetting, model.thinkingLevel);
|
|
203
|
-
} catch (error) {
|
|
204
|
-
throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("session", error);
|
|
205
|
-
}
|
|
206
|
-
session.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
|
|
207
|
-
}
|
|
208
|
-
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
209
|
-
if (session === void 0) throw new Error("Navigator session was not created");
|
|
210
|
-
return session;
|
|
211
|
-
};
|
|
212
|
-
const prepare = async () => {
|
|
213
|
-
const invocationId = invocationPrincipal;
|
|
214
|
-
activeInvocationId = invocationId;
|
|
215
|
-
let output;
|
|
216
|
-
let prepareBatchRejected = false;
|
|
217
|
-
outputSink = (value) => {
|
|
218
|
-
const next = normalizePreparedAdvice(value);
|
|
219
|
-
if (output === void 0) {
|
|
220
|
-
output = value;
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
const merged = mergePreparedAdvice(normalizePreparedAdvice(output), next);
|
|
224
|
-
output = {
|
|
225
|
-
...merged?.prose === void 0 ? {} : { prose: merged.prose },
|
|
226
|
-
...merged === void 0 || merged.byStatus.size === 0 ? {} : { byStatus: byStatusToPlainObject(merged.byStatus) }
|
|
227
|
-
};
|
|
35
|
+
unavailableSource: failure.unavailableSource
|
|
228
36
|
};
|
|
229
|
-
const activeSession = await loadMaterialsAndSession(invocationId);
|
|
230
|
-
const request = JSON.stringify({
|
|
231
|
-
kind: "prepare",
|
|
232
|
-
role: options.role,
|
|
233
|
-
phase: options.phase,
|
|
234
|
-
invocationId,
|
|
235
|
-
subjectKey
|
|
236
|
-
});
|
|
237
|
-
try {
|
|
238
|
-
try {
|
|
239
|
-
if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
240
|
-
const delivery = createReceiptDeliveryPolicy(options.deliveryRequestLimit);
|
|
241
|
-
const promptAllowingRejectedPrepare = async (text) => {
|
|
242
|
-
const entryStart = activeSession.entries().length;
|
|
243
|
-
prepareBatchRejected = false;
|
|
244
|
-
let promptFailure;
|
|
245
|
-
try {
|
|
246
|
-
await activeSession.prompt(text);
|
|
247
|
-
} catch (error) {
|
|
248
|
-
promptFailure = error;
|
|
249
|
-
}
|
|
250
|
-
const providerFailure = activeSession.providerFailure?.();
|
|
251
|
-
if (providerFailure !== void 0) {
|
|
252
|
-
throw navigatorUnavailableError(providerFailure.source, promptFailure ?? "Navigator provider failure", providerFailure.cause);
|
|
253
|
-
}
|
|
254
|
-
const rejectedReason = rejectedPrepareReason(activeSession.entries(), entryStart);
|
|
255
|
-
if (rejectedReason !== void 0) {
|
|
256
|
-
output = void 0;
|
|
257
|
-
prepareBatchRejected = true;
|
|
258
|
-
delivery.recordRejected(rejectedReason);
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
if (promptFailure !== void 0) throw promptFailure;
|
|
262
|
-
const sessionNoReceipt = activeSession.noReceipt?.();
|
|
263
|
-
if (sessionNoReceipt !== void 0) {
|
|
264
|
-
delivery.recordNestedNoReceipt(sessionNoReceipt);
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
await promptAllowingRejectedPrepare(request);
|
|
269
|
-
while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
|
|
270
|
-
delivery.recordDeliveryRequest();
|
|
271
|
-
await promptAllowingRejectedPrepare(request);
|
|
272
|
-
}
|
|
273
|
-
if (output === void 0 && delivery.nextAction() === "request-delivery") {
|
|
274
|
-
delivery.closeBudget();
|
|
275
|
-
}
|
|
276
|
-
if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
|
|
277
|
-
preparedAdvice = void 0;
|
|
278
|
-
return void 0;
|
|
279
|
-
}
|
|
280
|
-
} catch (error) {
|
|
281
|
-
throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("transport", error);
|
|
282
|
-
}
|
|
283
|
-
if (output === void 0) {
|
|
284
|
-
const nativeFailure = [...activeSession.entries()].reverse().find((entry) => {
|
|
285
|
-
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message)) return false;
|
|
286
|
-
return entry.message.role === "assistant" && typeof entry.message.errorMessage === "string" && entry.message.errorMessage.trim() !== "";
|
|
287
|
-
});
|
|
288
|
-
const nativeMessage = isRecord(nativeFailure) && isRecord(nativeFailure.message) ? nativeFailure.message : void 0;
|
|
289
|
-
const errorMessage = nativeMessage !== void 0 && typeof nativeMessage.errorMessage === "string" ? nativeMessage.errorMessage : "Navigator did not submit direction advice";
|
|
290
|
-
const providerFailure = activeSession.providerFailure?.();
|
|
291
|
-
const source = providerFailure?.source ?? "unknown";
|
|
292
|
-
const cause = providerFailure?.cause ?? source;
|
|
293
|
-
throw navigatorUnavailableError(source, errorMessage, cause);
|
|
294
|
-
}
|
|
295
|
-
preparedAdvice = normalizePreparedAdvice(output);
|
|
296
|
-
return preparedAdvice;
|
|
297
|
-
} finally {
|
|
298
|
-
const playbookFailure = activeSession.routePlaybookReadFailure?.();
|
|
299
|
-
observedRoutePlaybookFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
|
|
300
|
-
outputSink = void 0;
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
return {
|
|
304
|
-
setWorkContext(next) {
|
|
305
|
-
let closing2;
|
|
306
|
-
if (next.subjectKey !== subjectKey && session !== void 0) {
|
|
307
|
-
const previous = session;
|
|
308
|
-
session = void 0;
|
|
309
|
-
closing2 = previous.dispose();
|
|
310
|
-
}
|
|
311
|
-
subjectKey = next.subjectKey;
|
|
312
|
-
contextError = next.contextError;
|
|
313
|
-
return closing2;
|
|
314
|
-
},
|
|
315
|
-
prepare() {
|
|
316
|
-
if (disposed || preparation !== void 0) return;
|
|
317
|
-
preparationFailure = void 0;
|
|
318
|
-
preparedAdvice = void 0;
|
|
319
|
-
preparationInFlight = true;
|
|
320
|
-
preparation = prepare().finally(() => {
|
|
321
|
-
preparationInFlight = false;
|
|
322
|
-
});
|
|
323
|
-
void preparation.catch((error) => {
|
|
324
|
-
preparationFailure = error;
|
|
325
|
-
});
|
|
326
|
-
},
|
|
327
|
-
isPreparing() {
|
|
328
|
-
return preparationInFlight;
|
|
329
|
-
},
|
|
330
|
-
settle(settlement) {
|
|
331
|
-
const next = settlementTail.then(() => settleOnce(settlement));
|
|
332
|
-
settlementTail = next.catch((error) => {
|
|
333
|
-
settlementFailure = error;
|
|
334
|
-
});
|
|
335
|
-
return next;
|
|
336
|
-
},
|
|
337
|
-
dispose() {
|
|
338
|
-
disposed = true;
|
|
339
|
-
if (!nestCancel.signal.aborted) {
|
|
340
|
-
nestCancel.abort(navigatorUnavailableError(
|
|
341
|
-
"session",
|
|
342
|
-
new Error("Navigator attendance was disposed")
|
|
343
|
-
));
|
|
344
|
-
}
|
|
345
|
-
activeInvocationId = void 0;
|
|
346
|
-
if (closing === void 0) {
|
|
347
|
-
const current = session;
|
|
348
|
-
session = void 0;
|
|
349
|
-
closing = Promise.resolve(current?.dispose()).then(() => void 0);
|
|
350
|
-
}
|
|
351
|
-
return closing;
|
|
352
|
-
}
|
|
353
37
|
};
|
|
354
38
|
async function settleOnce(settlement) {
|
|
355
39
|
if (disposed) return;
|
|
356
|
-
const invocationId = activeInvocationId ?? invocationPrincipal;
|
|
357
40
|
let report;
|
|
358
|
-
const settlementFact = {
|
|
359
|
-
invocationId,
|
|
360
|
-
subjectKey,
|
|
361
|
-
role: settlement.role,
|
|
362
|
-
phase: settlement.phase,
|
|
363
|
-
kind: settlement.kind,
|
|
364
|
-
..."status" in settlement && settlement.status !== void 0 ? { status: settlement.status } : {}
|
|
365
|
-
};
|
|
366
41
|
if (settlement.kind === "arrival") {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
preparationFailure ??= error;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
|
|
375
|
-
if (preparationFailure !== void 0) {
|
|
376
|
-
report = unavailable(invocationId, preparationFailure);
|
|
377
|
-
} else {
|
|
378
|
-
report = {
|
|
379
|
-
disposition: "arrival",
|
|
380
|
-
...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message }
|
|
381
|
-
};
|
|
382
|
-
}
|
|
42
|
+
report = preparationFailure !== void 0 ? unavailable(preparationFailure) : {
|
|
43
|
+
disposition: "arrival",
|
|
44
|
+
...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message }
|
|
45
|
+
};
|
|
383
46
|
} else {
|
|
384
|
-
if (sessionReady !== void 0) {
|
|
385
|
-
try {
|
|
386
|
-
await sessionReady;
|
|
387
|
-
} catch (error) {
|
|
388
|
-
preparationFailure ??= error;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
47
|
if (preparation !== void 0) {
|
|
392
48
|
try {
|
|
393
49
|
await preparation;
|
|
@@ -396,22 +52,14 @@ function createNavigatorAttendance(options) {
|
|
|
396
52
|
}
|
|
397
53
|
preparation = void 0;
|
|
398
54
|
}
|
|
399
|
-
session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
|
|
400
55
|
if (preparationFailure !== void 0) {
|
|
401
|
-
report = unavailable(
|
|
56
|
+
report = unavailable(preparationFailure);
|
|
402
57
|
} else {
|
|
403
58
|
const status = "status" in settlement ? settlement.status : void 0;
|
|
404
59
|
const picked = pickPreparedProse(preparedAdvice, status);
|
|
405
|
-
|
|
406
|
-
report = { disposition: "advice", prose: picked };
|
|
407
|
-
} else {
|
|
408
|
-
report = { disposition: "no-advice" };
|
|
409
|
-
}
|
|
60
|
+
report = typeof picked === "string" && picked.trim() !== "" ? { disposition: "advice", prose: picked } : { disposition: "no-advice" };
|
|
410
61
|
}
|
|
411
62
|
}
|
|
412
|
-
if (observedRoutePlaybookFailure !== void 0) {
|
|
413
|
-
report = { ...report, routePlaybookReadFailure: observedRoutePlaybookFailure };
|
|
414
|
-
}
|
|
415
63
|
const event = {
|
|
416
64
|
version: 1,
|
|
417
65
|
disposition: report.disposition,
|
|
@@ -422,8 +70,6 @@ function createNavigatorAttendance(options) {
|
|
|
422
70
|
...report.prose === void 0 ? {} : { prose: report.prose },
|
|
423
71
|
...report.unavailableReason === void 0 ? {} : { unavailableReason: report.unavailableReason },
|
|
424
72
|
...report.unavailableSource === void 0 ? {} : { unavailableSource: report.unavailableSource },
|
|
425
|
-
...report.unavailableCause === void 0 ? {} : { unavailableCause: report.unavailableCause },
|
|
426
|
-
...report.routePlaybookReadFailure === void 0 ? {} : { routePlaybookReadFailure: report.routePlaybookReadFailure },
|
|
427
73
|
...report.arrivalMessage === void 0 ? {} : { arrivalMessage: report.arrivalMessage }
|
|
428
74
|
};
|
|
429
75
|
if (disposed) return;
|
|
@@ -434,43 +80,47 @@ function createNavigatorAttendance(options) {
|
|
|
434
80
|
throw error;
|
|
435
81
|
}
|
|
436
82
|
preparation = void 0;
|
|
437
|
-
sessionReady = void 0;
|
|
438
83
|
preparedAdvice = void 0;
|
|
439
84
|
preparationFailure = void 0;
|
|
440
|
-
observedRoutePlaybookFailure = void 0;
|
|
441
85
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
86
|
+
return {
|
|
87
|
+
prepare() {
|
|
88
|
+
if (disposed || preparation !== void 0 || options.phase === "plan") return;
|
|
89
|
+
preparationFailure = void 0;
|
|
90
|
+
preparedAdvice = void 0;
|
|
91
|
+
preparationInFlight = true;
|
|
92
|
+
preparation = options.lookup({ context: lookupContext(), role: options.role }).then((prepared) => {
|
|
93
|
+
preparedAdvice = prepared;
|
|
94
|
+
return prepared;
|
|
95
|
+
}).finally(() => {
|
|
96
|
+
preparationInFlight = false;
|
|
97
|
+
});
|
|
98
|
+
void preparation.catch((error) => {
|
|
99
|
+
preparationFailure = error;
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
isPreparing() {
|
|
103
|
+
return preparationInFlight;
|
|
104
|
+
},
|
|
105
|
+
settle(settlement) {
|
|
106
|
+
const next = settlementTail.then(() => settleOnce(settlement));
|
|
107
|
+
settlementTail = next.catch(() => void 0);
|
|
108
|
+
return next;
|
|
109
|
+
},
|
|
110
|
+
dispose() {
|
|
111
|
+
disposed = true;
|
|
112
|
+
if (!nestCancel.signal.aborted) {
|
|
113
|
+
nestCancel.abort(navigatorUnavailableError("session", new Error("Navigator attendance was disposed")));
|
|
114
|
+
}
|
|
448
115
|
}
|
|
449
|
-
}
|
|
116
|
+
};
|
|
450
117
|
}
|
|
451
118
|
export {
|
|
452
119
|
NAVIGATOR_EVENT_TYPE,
|
|
453
|
-
|
|
454
|
-
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
455
|
-
NAVIGATOR_TARGETS,
|
|
120
|
+
NAVIGATOR_INVOCATION_ENTRY,
|
|
456
121
|
NavigatorUnavailableError,
|
|
457
|
-
createNativeNavigatorSessionFactory,
|
|
458
122
|
createNavigatorAttendance,
|
|
459
|
-
createNavigatorPrepareTool,
|
|
460
123
|
formatNavigatorReport,
|
|
461
|
-
navigatorModelSettingPath,
|
|
462
|
-
navigatorProviderFailure,
|
|
463
|
-
navigatorProviderFailureFromDiagnostics,
|
|
464
|
-
navigatorProviderFailureFromError,
|
|
465
|
-
navigatorProviderFailureFromPublicTerminal,
|
|
466
|
-
navigatorProviderFailureFromStatus,
|
|
467
|
-
navigatorSubjectKey,
|
|
468
|
-
navigatorSubjectKeyForInput,
|
|
469
124
|
navigatorUnavailableError,
|
|
470
|
-
|
|
471
|
-
readNavigatorModelSetting,
|
|
472
|
-
registerNavigatorModelCommand,
|
|
473
|
-
resolveNavigatorSeatSelection,
|
|
474
|
-
subjectPath,
|
|
475
|
-
writeNavigatorModelSetting
|
|
125
|
+
subjectPath
|
|
476
126
|
};
|
|
@@ -3,7 +3,6 @@ import { isUuidV7, uuidv7 } from "./uuidv7.js";
|
|
|
3
3
|
import { isRecord } from "./unknown-value.js";
|
|
4
4
|
import { workSubjectKeysEqual } from "./work-subject-identity.js";
|
|
5
5
|
const NAVIGATOR_INVOCATION_ENTRY = "ak-navigator-invocation";
|
|
6
|
-
const NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY = "ak-navigator-route-playbook-failure";
|
|
7
6
|
const NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND = "role_infrastructure_failure";
|
|
8
7
|
const NAVIGATOR_INFRASTRUCTURE_FAILURE_KEYS = [
|
|
9
8
|
"kind",
|
|
@@ -187,7 +186,6 @@ export {
|
|
|
187
186
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
|
|
188
187
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND,
|
|
189
188
|
NAVIGATOR_INVOCATION_ENTRY,
|
|
190
|
-
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
191
189
|
buildNavigatorInfrastructureFailureFact,
|
|
192
190
|
classifyPackagedRoleTerminalResult,
|
|
193
191
|
extractInfrastructureFailureEvidence,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 游奕使的非模型回合宿主(#1192 / ADR 0082「不适配者按类型开新管线」)。
|
|
3
|
+
* 不起宿主会话、不调模型:按结构化的目标角色查 navigator-route-table,
|
|
4
|
+
* 经提交账封一行,结算照常读账本。
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
7
|
+
import { navigatorFullTable, navigatorRowsForRole } from "./navigator-route-table.js";
|
|
8
|
+
import { PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.js";
|
|
9
|
+
import { sealAcceptedSubmission } from "./submission-ledger.js";
|
|
10
|
+
/** 记入 invocation 的宿主名:如实表明这一腿是查表,不冒用真实宿主。 */
|
|
11
|
+
export const NAVIGATOR_LOOKUP_HOST = "lookup";
|
|
12
|
+
function targetRole(forRole) {
|
|
13
|
+
const known = PACKAGED_ROLE_REGISTRY.find(({ role }) => role === forRole);
|
|
14
|
+
if (known === undefined)
|
|
15
|
+
throw new Error(`navigator lookup: unknown role ${forRole}`);
|
|
16
|
+
return known.role;
|
|
17
|
+
}
|
|
18
|
+
export function createNavigatorLookupHost() {
|
|
19
|
+
return {
|
|
20
|
+
async executeTurn(request) {
|
|
21
|
+
const { activation } = request;
|
|
22
|
+
if (activation.role !== "navigator") {
|
|
23
|
+
throw new Error(`navigator lookup host cannot run ${activation.role}`);
|
|
24
|
+
}
|
|
25
|
+
const accepted = activation.forRole === undefined
|
|
26
|
+
? { byRole: navigatorFullTable() }
|
|
27
|
+
: { byStatus: navigatorRowsForRole(targetRole(activation.forRole)) };
|
|
28
|
+
sealAcceptedSubmission({
|
|
29
|
+
runDirectory: request.runDirectory,
|
|
30
|
+
cwd: request.cwd,
|
|
31
|
+
home: request.home,
|
|
32
|
+
role: "navigator",
|
|
33
|
+
accepted,
|
|
34
|
+
instruction: request.continuation.prompt,
|
|
35
|
+
toolCallId: `navigator-lookup:${randomUUID()}`,
|
|
36
|
+
...(request.courtAttemptId === undefined ? {} : { courtAttemptId: request.courtAttemptId }),
|
|
37
|
+
});
|
|
38
|
+
return { code: 0, stderr: "", timedOut: false };
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergePreparedAdvice,
|
|
3
|
+
preparedAdviceFromUnknown
|
|
4
|
+
} from "./package-contracts/navigator-output.js";
|
|
5
|
+
import { runDirectoryFromHostContext } from "./host-contracts.js";
|
|
6
|
+
class NavigatorUnavailableError extends Error {
|
|
7
|
+
unavailableSource;
|
|
8
|
+
originalCause;
|
|
9
|
+
constructor(source, message, originalCause) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "NavigatorUnavailableError";
|
|
12
|
+
this.unavailableSource = source;
|
|
13
|
+
this.originalCause = originalCause;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function navigatorUnavailableError(source, error) {
|
|
17
|
+
if (error instanceof NavigatorUnavailableError) return error;
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
+
return new NavigatorUnavailableError(source, message, error);
|
|
20
|
+
}
|
|
21
|
+
async function ledgerHomeFor(context) {
|
|
22
|
+
const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
|
|
23
|
+
for (const path of [runDirectoryFromHostContext(context), context.sessionManager?.getSessionFile?.()]) {
|
|
24
|
+
if (typeof path !== "string" || path.trim() === "") continue;
|
|
25
|
+
const home = tryHomeFromAkRolesPath(path);
|
|
26
|
+
if (home !== void 0 && home.length > 0) return home;
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
function createNavigatorLookup(deps) {
|
|
31
|
+
const summon = deps?.summonPublicRole ?? (async (options) => (await import("./public-role-summons.js")).summonPublicRole(options));
|
|
32
|
+
return async ({ context, role }) => {
|
|
33
|
+
const home = await ledgerHomeFor(context);
|
|
34
|
+
let summoned;
|
|
35
|
+
try {
|
|
36
|
+
summoned = await summon({
|
|
37
|
+
role: "navigator",
|
|
38
|
+
argv: ["--role", role],
|
|
39
|
+
cwd: context.cwd,
|
|
40
|
+
...home === void 0 ? {} : { home },
|
|
41
|
+
...context.signal === void 0 ? {} : { signal: context.signal }
|
|
42
|
+
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
throw navigatorUnavailableError("session", error);
|
|
45
|
+
}
|
|
46
|
+
const outcome = summoned.terminal?.roleOutcome;
|
|
47
|
+
if (outcome === void 0) {
|
|
48
|
+
const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
|
|
49
|
+
throw new NavigatorUnavailableError("session", `Navigator lookup produced no terminal (${detail})`);
|
|
50
|
+
}
|
|
51
|
+
if (outcome.kind === "failure") {
|
|
52
|
+
throw new NavigatorUnavailableError("session", outcome.diagnostic);
|
|
53
|
+
}
|
|
54
|
+
if (outcome.kind !== "accepted") {
|
|
55
|
+
throw new NavigatorUnavailableError("session", `Navigator lookup settled ${outcome.kind}`);
|
|
56
|
+
}
|
|
57
|
+
let prepared;
|
|
58
|
+
for (const payload of outcome.payloads ?? []) {
|
|
59
|
+
prepared = mergePreparedAdvice(prepared, preparedAdviceFromUnknown(payload));
|
|
60
|
+
}
|
|
61
|
+
return prepared;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
NavigatorUnavailableError,
|
|
66
|
+
createNavigatorLookup,
|
|
67
|
+
navigatorUnavailableError
|
|
68
|
+
};
|