@akagilnc/pi-workflow-roles 0.1.4586 → 0.1.4631

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 (63) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +3 -3
  3. package/dist/acp-host/production-host.js +1184 -717
  4. package/dist/activation-ledger-topology.js +0 -4
  5. package/dist/archivist-record-topology.js +27 -35
  6. package/dist/headless-host/description.js +7 -4
  7. package/dist/headless-host/production-host.js +998 -595
  8. package/dist/migrate-book-topology.js +3 -6
  9. package/dist/navigator-attendance.js +146 -241
  10. package/dist/navigator-public-session.js +81 -15
  11. package/dist/package-contracts/navigator-output.js +30 -12
  12. package/dist/pi/role-turn-host.js +0 -3
  13. package/dist/public-cli/auto-resume.js +26 -0
  14. package/dist/public-cli/judge-run.js +2 -2
  15. package/dist/public-cli/main.js +1119 -870
  16. package/dist/public-cli/option-definitions.js +1 -1
  17. package/dist/public-cli/post-admission.js +103 -9
  18. package/dist/public-cli/process-cancel.js +57 -0
  19. package/dist/public-cli/run-lifecycle.js +29 -7
  20. package/dist/public-cli/settlement.js +46 -32
  21. package/dist/public-cli/terminal.js +8 -27
  22. package/dist/public-role-summons.js +22 -4
  23. package/dist/submission-ledger.js +56 -23
  24. package/package.json +1 -1
  25. package/resources/836-deleted-machine-instruction-inventory.md +2 -0
  26. package/resources/navigator-route-playbook.md +9 -0
  27. package/scripts/build-package.mjs +6 -2
  28. package/src/acp-host/role-turn-host.ts +129 -13
  29. package/src/activation-ledger-topology.ts +1 -6
  30. package/src/activation-ledger.ts +5 -236
  31. package/src/analyst-entry.ts +19 -2
  32. package/src/analyst-ledger.ts +111 -6
  33. package/src/archivist-record-entry.ts +1 -1
  34. package/src/headless-host/description.ts +17 -7
  35. package/src/headless-host/role-turn-host.ts +42 -11
  36. package/src/navigator-attendance.ts +290 -425
  37. package/src/navigator-public-session.ts +126 -25
  38. package/src/navigator-role.ts +2 -2
  39. package/src/package-contracts/navigator-output.ts +41 -25
  40. package/src/pi/role-turn-host.ts +0 -3
  41. package/src/public-cli/auto-resume.ts +34 -0
  42. package/src/public-cli/cli.ts +30 -0
  43. package/src/public-cli/coder-run.ts +2 -2
  44. package/src/public-cli/fixer-run.ts +2 -2
  45. package/src/public-cli/judge-run.ts +2 -2
  46. package/src/public-cli/main.ts +25 -3
  47. package/src/public-cli/merger-run.ts +2 -2
  48. package/src/public-cli/option-definitions.ts +1 -1
  49. package/src/public-cli/post-admission.ts +175 -7
  50. package/src/public-cli/process-cancel.ts +75 -0
  51. package/src/public-cli/run-lifecycle.ts +37 -7
  52. package/src/public-cli/settlement.ts +42 -33
  53. package/src/public-cli/terminal.ts +12 -37
  54. package/src/public-role-summons.ts +34 -5
  55. package/src/role-envelope.ts +89 -4
  56. package/src/role-runtime.ts +78 -65
  57. package/src/submission-ledger.ts +63 -21
  58. package/dist/activation-reconciliation.js +0 -61
  59. package/dist/public-cli/command-renderer.js +0 -5
  60. package/dist/public-command-renderer.js +0 -29
  61. package/src/activation-reconciliation.ts +0 -163
  62. package/src/public-cli/command-renderer.ts +0 -9
  63. package/src/public-command-renderer.ts +0 -55
@@ -1,3 +1,4 @@
1
+ import { basename } from "node:path";
1
2
  import { sitianReport } from "./sitian-facade.js";
2
3
  import {
3
4
  NavigatorUnavailableError,
@@ -7,6 +8,7 @@ import {
7
8
  parseNavigatorModelSetting
8
9
  } from "./navigator-session-contracts.js";
9
10
  import { runDirectoryFromHostContext } from "./host-contracts.js";
11
+ import { CliUsageError } from "./public-cli/cli-errors.js";
10
12
  async function resolveNavigatorLedgerHome(context) {
11
13
  const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
12
14
  const runDirectory = runDirectoryFromHostContext(context);
@@ -21,7 +23,42 @@ async function resolveNavigatorLedgerHome(context) {
21
23
  }
22
24
  return void 0;
23
25
  }
24
- function createNativeNavigatorSessionFactory() {
26
+ const NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
27
+ function exactRecord(value) {
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ }
30
+ function runIdFromNavigatorDirectory(runDirectory) {
31
+ const entry = basename(runDirectory);
32
+ const suffix = "@navigator";
33
+ if (!entry.endsWith(suffix)) return void 0;
34
+ const runId = entry.slice(0, entry.length - suffix.length);
35
+ return runId.length > 0 ? runId : void 0;
36
+ }
37
+ function readNavigatorHostRunPointer(entries) {
38
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
39
+ const entry = entries[index];
40
+ if (!exactRecord(entry)) continue;
41
+ if (entry.type === "custom" && entry.customType === NAVIGATOR_HOST_RUN_POINTER_ENTRY) {
42
+ const data = entry.data;
43
+ if (exactRecord(data) && typeof data.runId === "string" && data.runId.trim() !== "") {
44
+ return data.runId.trim();
45
+ }
46
+ }
47
+ }
48
+ return void 0;
49
+ }
50
+ async function navigatorHostRunResumable(home, runId) {
51
+ const { piDurablePrincipalAuthority } = await import("./pi/durable-principal.js");
52
+ const { loadResumableInstructionSeatRun } = await import("./public-cli/run-lifecycle.js");
53
+ try {
54
+ const loaded = await loadResumableInstructionSeatRun(home, runId, piDurablePrincipalAuthority);
55
+ return loaded.admitted.role === "navigator";
56
+ } catch (error) {
57
+ if (error instanceof CliUsageError) return false;
58
+ throw error;
59
+ }
60
+ }
61
+ function createNativeNavigatorSessionFactory(deps) {
25
62
  return async ({ context, subject, tool }) => {
26
63
  let thinkingLevel;
27
64
  const { createRecordSession, NAVIGATOR_RECORD_KIND } = await import("./archivist-record-entry.js");
@@ -37,6 +74,11 @@ function createNativeNavigatorSessionFactory() {
37
74
  let noReceipt;
38
75
  let disposed = false;
39
76
  let inFlightPrompt;
77
+ let hostRunId = readNavigatorHostRunPointer(sessionManager.getEntries());
78
+ const summon = deps?.summonPublicRole ?? (async (options) => {
79
+ const { summonPublicRole } = await import("./public-role-summons.js");
80
+ return summonPublicRole(options);
81
+ });
40
82
  return {
41
83
  prompt: async (text) => {
42
84
  if (disposed) {
@@ -46,14 +88,24 @@ function createNativeNavigatorSessionFactory() {
46
88
  noReceipt = void 0;
47
89
  const run = (async () => {
48
90
  try {
49
- const { summonPublicRole } = await import("./public-role-summons.js");
50
91
  const summonHome = await resolveNavigatorLedgerHome(context);
51
- const summoned = await summonPublicRole({
92
+ const resumeRunId = hostRunId;
93
+ const baseSummon = {
52
94
  role: "navigator",
53
95
  argv: [text],
54
96
  cwd: context.cwd,
55
97
  ...summonHome === void 0 ? {} : { home: summonHome }
56
- });
98
+ };
99
+ const resumable = deps?.hostRunResumable ?? navigatorHostRunResumable;
100
+ let summoned;
101
+ if (resumeRunId === void 0 || summonHome === void 0) {
102
+ summoned = await summon(baseSummon);
103
+ } else if (await resumable(summonHome, resumeRunId)) {
104
+ summoned = await summon({ ...baseSummon, resumeRunId });
105
+ } else {
106
+ hostRunId = void 0;
107
+ summoned = await summon(baseSummon);
108
+ }
57
109
  const outcome = summoned.terminal?.roleOutcome;
58
110
  if (outcome === void 0) {
59
111
  const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
@@ -76,21 +128,31 @@ function createNativeNavigatorSessionFactory() {
76
128
  noReceipt = outcome;
77
129
  return;
78
130
  }
131
+ const runDirectory = summoned.runDirectory ?? (typeof summoned.admitted?.runDirectory === "string" ? summoned.admitted.runDirectory : void 0);
132
+ if (typeof runDirectory === "string" && runDirectory.trim() !== "") {
133
+ const nextRunId = runIdFromNavigatorDirectory(runDirectory);
134
+ if (nextRunId !== void 0) {
135
+ hostRunId = nextRunId;
136
+ sessionManager.appendCustomEntry(NAVIGATOR_HOST_RUN_POINTER_ENTRY, { runId: nextRunId });
137
+ }
138
+ }
79
139
  if (outcome.kind !== "accepted") {
80
140
  return;
81
141
  }
142
+ const { navigatorProseFromUnknown } = await import("./package-contracts/navigator-output.js");
143
+ const proseParts = [];
82
144
  for (const payload of outcome.payloads ?? []) {
83
- if (typeof payload !== "object" || payload === null || Array.isArray(payload)) continue;
84
- const candidates = payload.candidates;
85
- if (!Array.isArray(candidates)) continue;
86
- await tool.execute(
87
- "navigator-public-prepare",
88
- { candidates },
89
- void 0,
90
- void 0,
91
- context
92
- );
145
+ const prose = navigatorProseFromUnknown(payload);
146
+ if (prose !== void 0) proseParts.push(prose);
93
147
  }
148
+ if (proseParts.length === 0) return;
149
+ await tool.execute(
150
+ "navigator-public-prepare",
151
+ { prose: proseParts.join("\n\n") },
152
+ void 0,
153
+ void 0,
154
+ context
155
+ );
94
156
  } catch (error) {
95
157
  if (error instanceof NavigatorUnavailableError) throw error;
96
158
  const fact = navigatorProviderFailureFromError(error);
@@ -142,5 +204,9 @@ function createNativeNavigatorSessionFactory() {
142
204
  };
143
205
  }
144
206
  export {
145
- createNativeNavigatorSessionFactory
207
+ NAVIGATOR_HOST_RUN_POINTER_ENTRY,
208
+ createNativeNavigatorSessionFactory,
209
+ navigatorHostRunResumable,
210
+ readNavigatorHostRunPointer,
211
+ runIdFromNavigatorDirectory
146
212
  };
@@ -6,31 +6,49 @@ const NAVIGATOR_ACCEPTED_TEXT = "\u6E38\u5955\u4F7F\u5EFA\u8BAE\u5DF2\u53D7\u740
6
6
  const navigatorOutputSchema = withTerminatingOutputDeclarations(
7
7
  openToolObject(
8
8
  Type.Object({
9
- status: Type.Unknown({
10
- description: "advice \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
11
- }),
12
- candidates: Type.Unknown({
13
- description: "\u6392\u597D\u5E8F\u7684\u8DEF\u7EBF\u5EFA\u8BAE\u6570\u7EC4\uFF0C\u5143\u7D20\u542B next/phase/reason \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
9
+ prose: Type.Unknown({
10
+ description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
14
11
  })
15
12
  })
16
13
  )
17
14
  );
18
- function isRecord(value) {
19
- return typeof value === "object" && value !== null && !Array.isArray(value);
20
- }
21
15
  function projectLawfulNavigatorOutput(value) {
22
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
16
+ if (value === void 0 || value === null) return void 0;
17
+ if (typeof value === "string") return { prose: value };
18
+ if (typeof value === "object" && !Array.isArray(value)) {
19
+ const record = value;
20
+ if (typeof record.prose === "string") return { prose: record.prose };
21
+ if (record.prose !== void 0 && record.prose !== null) {
22
+ return { prose: typeof record.prose === "string" ? record.prose : String(record.prose) };
23
+ }
24
+ const keys = Object.keys(record);
25
+ if (keys.length === 0) return { prose: "" };
26
+ try {
27
+ return { prose: JSON.stringify(record) };
28
+ } catch {
29
+ return { prose: String(record) };
30
+ }
31
+ }
32
+ return { prose: String(value) };
23
33
  }
24
34
  function validateRecordedNavigatorOutput(value) {
25
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
26
- throw new Error("Navigator output is not an object");
35
+ const projected = projectLawfulNavigatorOutput(value);
36
+ if (projected === void 0) {
37
+ throw new Error("Navigator output is empty");
27
38
  }
28
- return value;
39
+ return projected;
40
+ }
41
+ function navigatorProseFromUnknown(value) {
42
+ const projected = projectLawfulNavigatorOutput(value);
43
+ if (projected === void 0) return void 0;
44
+ const trimmed = projected.prose.trim();
45
+ return trimmed === "" ? void 0 : projected.prose;
29
46
  }
30
47
  export {
31
48
  NAVIGATOR_ACCEPTED_TEXT,
32
49
  NAVIGATOR_OUTPUT_TOOL_NAME,
33
50
  navigatorOutputSchema,
51
+ navigatorProseFromUnknown,
34
52
  projectLawfulNavigatorOutput,
35
53
  validateRecordedNavigatorOutput
36
54
  };
@@ -361,9 +361,6 @@ export function createPiRoleTurnHost(config) {
361
361
  && process.env.AK_ROLE_AUDITOR_SUBJECT.trim() !== "") {
362
362
  env.AK_ROLE_AUDITOR_SUBJECT = process.env.AK_ROLE_AUDITOR_SUBJECT;
363
363
  }
364
- if (request.correlationId !== undefined && request.correlationId.trim() !== "") {
365
- env.AK_CORRELATION_ID = request.correlationId;
366
- }
367
364
  if (config.recordLaunchedRolePackageIdentity !== undefined &&
368
365
  config.observeLaunchedRolePackageIdentity !== undefined) {
369
366
  await config.recordLaunchedRolePackageIdentity(request.runDirectory, await config.observeLaunchedRolePackageIdentity(config.packageRoot, roleEntry));
@@ -18,6 +18,7 @@ import { join } from "node:path";
18
18
  import { roleRunArtifactsDirectory } from "../role-run-placement.js";
19
19
  import { AUTO_RESUME_LIMIT, describeErrorIdentity, acquireRunWriterLease, markRunResumable, markRunTerminal, RunWriterLeaseHeldError, } from "./run-lifecycle.js";
20
20
  import { parseAutoResumeLimit } from "./config.js";
21
+ import { processCancelSignalName } from "./process-cancel.js";
21
22
  import { isLawfulTypedTerminalOutcome, formatTerminalResult } from "./terminal.js";
22
23
  import { attachRecordedSubmissions, presentFailureTerminal, presentStructuralRejection, resolveControlledFailureResumeObservation, } from "./settlement.js";
23
24
  const dummyIo = { stdout: () => { }, stderr: () => { } };
@@ -423,6 +424,12 @@ export async function runWithAutoResumeLoop(options) {
423
424
  presentTerminal(terminal, options.io);
424
425
  return result;
425
426
  }
427
+ // #855: process cancel — stop even if dispatch forgot skipAutoResume.
428
+ if (processCancelSignalName(options.signal) !== undefined) {
429
+ if (terminal !== undefined)
430
+ presentTerminal(terminal, options.io);
431
+ return result;
432
+ }
426
433
  }
427
434
  if (result !== undefined) {
428
435
  const terminal = result.terminal;
@@ -457,6 +464,25 @@ export async function runWithAutoResumeLoop(options) {
457
464
  terminal,
458
465
  };
459
466
  }
467
+ // #855: process cancel on the throw path — do not re-dispatch; name the signal.
468
+ const cancelName = processCancelSignalName(options.signal);
469
+ if (cancelName !== undefined) {
470
+ const terminal = await attachDispatchExceptionTerminal(options.admitted, dispatchExceptionFailureTerminal({
471
+ role: options.admitted.role,
472
+ runId: options.admitted.runId,
473
+ causeError: lastThrownError,
474
+ errorFiles: retainedErrorFiles,
475
+ autoResumeAttempts,
476
+ endReason: `ak-role terminated by ${cancelName}`,
477
+ everyAttemptThrew,
478
+ }), options.io);
479
+ await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
480
+ presentTerminal(terminal, options.io);
481
+ return {
482
+ exitCode: 1,
483
+ terminal,
484
+ };
485
+ }
460
486
  if (!(await isPrincipalAvailable(options.admitted.principal))) {
461
487
  const terminal = await attachDispatchExceptionTerminal(options.admitted, dispatchExceptionFailureTerminal({
462
488
  role: options.admitted.role,
@@ -1,7 +1,7 @@
1
1
  import { engineSessionMaterialFromOptions, pickEngineAxis } from "../package-resources/engine-material.js";
2
2
  import { CliUsageError } from "./cli-errors.js";
3
3
  import { admitJudgeInvocation, buildJudgeTransportPrompt, } from "./invocation.js";
4
- import { loadResumableJudgeRun, markRunAdmitted, buildResumeContinuationPrompt, } from "./run-lifecycle.js";
4
+ import { loadResumableJudgeRun, markRunAdmitted, buildAutoResumeContinuationPrompt, } from "./run-lifecycle.js";
5
5
  import { presentStructuralRejection, readEngineDetourInfrastructureFailure, trySettleJudgeTerminalResult, } from "./settlement.js";
6
6
  import { projectRoleTurnRequest, } from "./turn-request.js";
7
7
  import { runPostAdmissionResumable, runPostAdmissionSeatResume, resumeTurnRequestProjectionOptions, } from "./post-admission.js";
@@ -86,7 +86,7 @@ export async function runPublicJudge(argv, env, io, parseJudgeArgv) {
86
86
  : { correlationId: admitted.correlationId ?? env.correlationId }),
87
87
  continuation: {
88
88
  kind: "resume",
89
- prompt: buildResumeContinuationPrompt({
89
+ prompt: buildAutoResumeContinuationPrompt({
90
90
  packageRoot: env.packageRoot,
91
91
  ...pickEngineAxis(env),
92
92
  }),