@akagilnc/pi-workflow-roles 0.1.5842 → 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.
Files changed (67) hide show
  1. package/README.md +4 -4
  2. package/README.zh-CN.md +4 -4
  3. package/dist/acp-host/production-host.js +348 -1254
  4. package/dist/acp-host/role-turn-host.js +4 -98
  5. package/dist/headless-host/production-host.js +15731 -16582
  6. package/dist/headless-host/role-turn-host.js +6 -31
  7. package/dist/migrate-book-topology.js +31 -16
  8. package/dist/navigator-attendance.js +54 -404
  9. package/dist/navigator-invocation-identity.js +0 -2
  10. package/dist/navigator-lookup-host.js +41 -0
  11. package/dist/navigator-lookup.js +68 -0
  12. package/dist/navigator-route-table.js +42 -0
  13. package/dist/package-contracts/navigator-output.js +3 -11
  14. package/dist/packaged-role-registry.js +3 -27
  15. package/dist/public-cli/instruction-seat-run.js +4 -1
  16. package/dist/public-cli/invocation.js +13 -26
  17. package/dist/public-cli/main.js +286 -114
  18. package/dist/public-cli/option-definitions.js +24 -4
  19. package/dist/public-cli/post-admission.js +0 -9
  20. package/dist/public-cli/role-seat-runtime.js +14 -0
  21. package/dist/public-cli/settlement.js +14 -40
  22. package/dist/public-cli/terminal.js +1 -8
  23. package/dist/public-cli/turn-request.js +0 -3
  24. package/dist/public-role-summons.js +0 -1
  25. package/dist/receipt-delivery-policy.js +0 -23
  26. package/dist/role-runtime-dependencies.js +4 -11
  27. package/dist/role-runtime.js +18 -194
  28. package/dist/submission-ledger.js +19 -15
  29. package/dist/ticket-progress.js +23 -5
  30. package/extensions/role-runtime.ts +0 -16
  31. package/package.json +1 -1
  32. package/scripts/build-package.mjs +3 -7
  33. package/souls/notary.md +1 -1
  34. package/src/acp-host/role-turn-host.ts +8 -97
  35. package/src/headless-host/description.ts +0 -2
  36. package/src/headless-host/role-turn-host.ts +7 -32
  37. package/src/host-contracts.ts +5 -7
  38. package/src/navigator-attendance.ts +86 -549
  39. package/src/navigator-invocation-identity.ts +0 -2
  40. package/src/navigator-lookup-host.ts +45 -0
  41. package/src/navigator-lookup.ts +98 -0
  42. package/src/navigator-route-table.ts +92 -0
  43. package/src/package-contracts/navigator-output.ts +4 -15
  44. package/src/packaged-role-registry.ts +3 -32
  45. package/src/public-cli/instruction-seat-run.ts +3 -0
  46. package/src/public-cli/invocation.ts +18 -30
  47. package/src/public-cli/option-definitions.ts +25 -4
  48. package/src/public-cli/post-admission.ts +0 -11
  49. package/src/public-cli/role-seat-runtime.ts +14 -0
  50. package/src/public-cli/settlement.ts +23 -51
  51. package/src/public-cli/terminal.ts +3 -18
  52. package/src/public-cli/turn-request.ts +0 -5
  53. package/src/public-role-summons.ts +0 -8
  54. package/src/receipt-delivery-policy.ts +0 -21
  55. package/src/role-runtime-dependencies.ts +4 -11
  56. package/src/role-runtime.ts +19 -210
  57. package/src/submission-ledger.ts +23 -16
  58. package/src/ticket-progress.ts +32 -5
  59. package/dist/navigator-public-session.js +0 -205
  60. package/dist/navigator-role.js +0 -6
  61. package/dist/navigator-session-contracts.js +0 -227
  62. package/dist/navigator-work-context.js +0 -72
  63. package/resources/navigator-route-playbook.md +0 -33
  64. package/src/navigator-public-session.ts +0 -305
  65. package/src/navigator-role.ts +0 -15
  66. package/src/navigator-session-contracts.ts +0 -320
  67. package/src/navigator-work-context.ts +0 -97
@@ -1,393 +1,49 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
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
- navigatorModelSettingPath,
20
- navigatorProviderFailure,
21
- navigatorProviderFailureFromDiagnostics,
22
- navigatorProviderFailureFromError,
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
- const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [report.routePlaybookReadFailure];
107
- if (report.disposition === "no-advice") return playbookFailure.join("\n");
108
- if (report.disposition === "unavailable") {
109
- return [...playbookFailure, ...report.unavailableReason ? [report.unavailableReason] : []].join("\n");
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 observedRoutePlaybookFailure;
21
+ let settlementTail = Promise.resolve();
131
22
  let disposed = false;
132
- let closing;
23
+ const invocationId = options.invocationId ?? mintNavigatorInvocationId();
133
24
  const nestCancel = new AbortController();
134
- const sessionHostContext = () => {
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 = (invocationId, reason) => {
140
- const failure = reason instanceof NavigatorUnavailableError ? reason : navigatorUnavailableError("unknown", reason);
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
- if (sessionReady !== void 0) {
368
- try {
369
- await sessionReady;
370
- } catch (error) {
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(invocationId, preparationFailure);
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
- if (typeof picked === "string" && picked.trim() !== "") {
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
- function registerNavigatorModelCommand(pi, path = navigatorModelSettingPath()) {
444
- pi.registerCommand("navigator-model", {
445
- description: "Set the persistent Navigator model (provider/model[:max]).",
446
- handler: async (args) => {
447
- await writeNavigatorModelSetting(args.trim(), path);
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
- NAVIGATOR_PREPARE_TOOL_NAME,
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
- parseNavigatorModelSetting,
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
+ };