@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,205 +0,0 @@
|
|
|
1
|
-
import { basename } from "node:path";
|
|
2
|
-
import { sitianReportSafe } from "./host-session-record.js";
|
|
3
|
-
import {
|
|
4
|
-
NavigatorUnavailableError,
|
|
5
|
-
navigatorProviderFailureFromPublicTerminal,
|
|
6
|
-
navigatorProviderFailureFromError,
|
|
7
|
-
navigatorUnavailableError,
|
|
8
|
-
parseNavigatorModelSetting
|
|
9
|
-
} from "./navigator-session-contracts.js";
|
|
10
|
-
import { runDirectoryFromHostContext } from "./host-contracts.js";
|
|
11
|
-
import { parseRunLeaf } from "./role-run-placement.js";
|
|
12
|
-
import { CliUsageError } from "./public-cli/cli-errors.js";
|
|
13
|
-
import { isNavigatorSeat } from "./packaged-role-registry.js";
|
|
14
|
-
async function resolveNavigatorLedgerHome(context) {
|
|
15
|
-
const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
|
|
16
|
-
const runDirectory = runDirectoryFromHostContext(context);
|
|
17
|
-
if (runDirectory !== void 0) {
|
|
18
|
-
const fromRun = tryHomeFromAkRolesPath(runDirectory);
|
|
19
|
-
if (fromRun !== void 0 && fromRun.length > 0) return fromRun;
|
|
20
|
-
}
|
|
21
|
-
const parentFile = context.sessionManager?.getSessionFile?.();
|
|
22
|
-
if (typeof parentFile === "string" && parentFile.trim() !== "") {
|
|
23
|
-
const fromParent = tryHomeFromAkRolesPath(parentFile);
|
|
24
|
-
if (fromParent !== void 0 && fromParent.length > 0) return fromParent;
|
|
25
|
-
}
|
|
26
|
-
return void 0;
|
|
27
|
-
}
|
|
28
|
-
function runIdFromNavigatorDirectory(runDirectory) {
|
|
29
|
-
const parsed = parseRunLeaf(basename(runDirectory));
|
|
30
|
-
if (parsed === void 0 || parsed.role !== "navigator") return void 0;
|
|
31
|
-
return parsed.runId;
|
|
32
|
-
}
|
|
33
|
-
async function navigatorHostRunResumable(home, runId, runDirectory) {
|
|
34
|
-
const { piDurablePrincipalAuthority } = await import("./pi/durable-principal.js");
|
|
35
|
-
const { loadResumablePublicRole } = await import("./public-cli/run-lifecycle.js");
|
|
36
|
-
try {
|
|
37
|
-
const loaded = await loadResumablePublicRole(
|
|
38
|
-
home,
|
|
39
|
-
runId,
|
|
40
|
-
piDurablePrincipalAuthority,
|
|
41
|
-
runDirectory === void 0 ? void 0 : { runDirectory }
|
|
42
|
-
);
|
|
43
|
-
return isNavigatorSeat(loaded.admitted.role);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
if (error instanceof CliUsageError) return false;
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function createNativeNavigatorSessionFactory(deps) {
|
|
50
|
-
return async ({ context, tool }) => {
|
|
51
|
-
const entries = [];
|
|
52
|
-
let providerFailure;
|
|
53
|
-
let noReceipt;
|
|
54
|
-
let routePlaybookReadFailure;
|
|
55
|
-
let disposed = false;
|
|
56
|
-
let hostRun;
|
|
57
|
-
const summon = deps?.summonPublicRole ?? (async (options) => {
|
|
58
|
-
const { summonPublicRole } = await import("./public-role-summons.js");
|
|
59
|
-
return summonPublicRole(options);
|
|
60
|
-
});
|
|
61
|
-
const parentSessionFile = () => context.sessionManager?.getSessionFile?.();
|
|
62
|
-
return {
|
|
63
|
-
prompt: async (text) => {
|
|
64
|
-
if (disposed) {
|
|
65
|
-
throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
66
|
-
}
|
|
67
|
-
providerFailure = void 0;
|
|
68
|
-
noReceipt = void 0;
|
|
69
|
-
routePlaybookReadFailure = void 0;
|
|
70
|
-
try {
|
|
71
|
-
const summonHome = await resolveNavigatorLedgerHome(context);
|
|
72
|
-
if (disposed) return;
|
|
73
|
-
const resumeRunId = hostRun?.runId;
|
|
74
|
-
const baseSummon = {
|
|
75
|
-
role: "navigator",
|
|
76
|
-
argv: [text],
|
|
77
|
-
cwd: context.cwd,
|
|
78
|
-
// Attendance prepare always asks for structured byStatus (#1160).
|
|
79
|
-
// Direct `ak-role navigator` never sets this flag.
|
|
80
|
-
navigatorByStatusPrepare: true,
|
|
81
|
-
...summonHome === void 0 ? {} : { home: summonHome },
|
|
82
|
-
...context.signal === void 0 ? {} : { signal: context.signal }
|
|
83
|
-
};
|
|
84
|
-
const resumable = deps?.hostRunResumable ?? navigatorHostRunResumable;
|
|
85
|
-
let summoned;
|
|
86
|
-
if (resumeRunId === void 0 || summonHome === void 0) {
|
|
87
|
-
if (disposed) return;
|
|
88
|
-
summoned = await summon(baseSummon);
|
|
89
|
-
} else {
|
|
90
|
-
const canResume = await resumable(summonHome, resumeRunId, hostRun?.runDirectory);
|
|
91
|
-
if (disposed) return;
|
|
92
|
-
if (canResume) {
|
|
93
|
-
summoned = await summon({
|
|
94
|
-
...baseSummon,
|
|
95
|
-
resumeRunId,
|
|
96
|
-
...hostRun === void 0 ? {} : { resumeRunDirectory: hostRun.runDirectory }
|
|
97
|
-
});
|
|
98
|
-
} else {
|
|
99
|
-
hostRun = void 0;
|
|
100
|
-
summoned = await summon(baseSummon);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (disposed) return;
|
|
104
|
-
const playbookFailure = summoned.terminal?.navigator?.advisoryDiagnostic;
|
|
105
|
-
routePlaybookReadFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
|
|
106
|
-
const outcome = summoned.terminal?.roleOutcome;
|
|
107
|
-
if (outcome === void 0) {
|
|
108
|
-
const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
|
|
109
|
-
providerFailure = { source: "transport", cause: "unknown" };
|
|
110
|
-
throw navigatorUnavailableError(
|
|
111
|
-
providerFailure.source,
|
|
112
|
-
new Error(`Navigator public summon produced no terminal (${detail})`),
|
|
113
|
-
providerFailure.cause
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
if (outcome.kind === "failure") {
|
|
117
|
-
providerFailure = navigatorProviderFailureFromPublicTerminal(outcome);
|
|
118
|
-
const failedAttempts = outcome.decisiveFacts.failedAttempts;
|
|
119
|
-
const attemptReasons = Array.isArray(failedAttempts) ? failedAttempts.map((entry, index) => {
|
|
120
|
-
const fact = entry !== null && typeof entry === "object" ? entry : void 0;
|
|
121
|
-
return `${typeof fact?.attempt === "number" ? fact.attempt + 1 : index + 1}: ${typeof fact?.diagnostic === "string" ? fact.diagnostic : outcome.diagnostic}`;
|
|
122
|
-
}) : [];
|
|
123
|
-
throw navigatorUnavailableError(
|
|
124
|
-
providerFailure.source,
|
|
125
|
-
new Error(attemptReasons.length > 0 ? attemptReasons.join("\n") : outcome.diagnostic),
|
|
126
|
-
providerFailure.cause
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
if (outcome.kind === "no_receipt") {
|
|
130
|
-
noReceipt = outcome;
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const runDirectory = summoned.runDirectory ?? (typeof summoned.admitted?.runDirectory === "string" ? summoned.admitted.runDirectory : void 0);
|
|
134
|
-
if (typeof runDirectory === "string" && runDirectory.trim() !== "") {
|
|
135
|
-
const nextRunId = runIdFromNavigatorDirectory(runDirectory);
|
|
136
|
-
if (nextRunId !== void 0) {
|
|
137
|
-
hostRun = { runId: nextRunId, runDirectory };
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (outcome.kind !== "accepted") {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const {
|
|
144
|
-
byStatusToPlainObject,
|
|
145
|
-
mergePreparedAdvice,
|
|
146
|
-
preparedAdviceFromUnknown
|
|
147
|
-
} = await import("./package-contracts/navigator-output.js");
|
|
148
|
-
let prepared = void 0;
|
|
149
|
-
for (const payload of outcome.payloads ?? []) {
|
|
150
|
-
prepared = mergePreparedAdvice(prepared, preparedAdviceFromUnknown(payload));
|
|
151
|
-
}
|
|
152
|
-
if (prepared === void 0) return;
|
|
153
|
-
if (disposed) return;
|
|
154
|
-
await tool.execute(
|
|
155
|
-
"navigator-public-prepare",
|
|
156
|
-
{
|
|
157
|
-
...prepared.prose === void 0 ? {} : { prose: prepared.prose },
|
|
158
|
-
...prepared.byStatus.size === 0 ? {} : { byStatus: byStatusToPlainObject(prepared.byStatus) }
|
|
159
|
-
},
|
|
160
|
-
void 0,
|
|
161
|
-
void 0,
|
|
162
|
-
context
|
|
163
|
-
);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
if (disposed) return;
|
|
166
|
-
if (error instanceof NavigatorUnavailableError) throw error;
|
|
167
|
-
const fact = navigatorProviderFailureFromError(error);
|
|
168
|
-
providerFailure = fact ?? { source: "transport", cause: "unknown" };
|
|
169
|
-
throw navigatorUnavailableError(providerFailure.source, error, providerFailure.cause);
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
providerFailure: () => providerFailure,
|
|
173
|
-
noReceipt: () => noReceipt,
|
|
174
|
-
routePlaybookReadFailure: () => routePlaybookReadFailure,
|
|
175
|
-
appendEntry: (customType, data) => {
|
|
176
|
-
entries.push({ type: "custom", customType, data });
|
|
177
|
-
const parent = parentSessionFile();
|
|
178
|
-
sitianReportSafe({
|
|
179
|
-
level: "event",
|
|
180
|
-
kind: "attendance",
|
|
181
|
-
cwd: context.cwd,
|
|
182
|
-
...parent === void 0 ? {} : { sessionParent: parent },
|
|
183
|
-
payload: { customType, data },
|
|
184
|
-
source: "navigator-public-session"
|
|
185
|
-
});
|
|
186
|
-
},
|
|
187
|
-
entries: () => entries,
|
|
188
|
-
setModel: async (next) => {
|
|
189
|
-
try {
|
|
190
|
-
parseNavigatorModelSetting(next);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
throw navigatorUnavailableError("model", error);
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
dispose: async () => {
|
|
196
|
-
disposed = true;
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
export {
|
|
202
|
-
createNativeNavigatorSessionFactory,
|
|
203
|
-
navigatorHostRunResumable,
|
|
204
|
-
runIdFromNavigatorDirectory
|
|
205
|
-
};
|
package/dist/navigator-role.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { roleSubmissionDeclaration } from "./role-submission-declarations.js";
|
|
2
|
-
/**
|
|
3
|
-
* 决定工具规格。生命周期装配归注册信封 owner——src/role-runtime.ts(ADR 0018)。
|
|
4
|
-
* #959: navigator speaks free-form prose; tool is a lifecycle vehicle only.
|
|
5
|
-
*/
|
|
6
|
-
export const NAVIGATOR_TOOL_SPEC = roleSubmissionDeclaration("navigator");
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { Type } from "typebox";
|
|
5
|
-
import { Value } from "typebox/value";
|
|
6
|
-
import { isRecord, errorText, isEnoent } from "./unknown-value.js";
|
|
7
|
-
const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare";
|
|
8
|
-
const NAVIGATOR_UNAVAILABLE_KEYS = /* @__PURE__ */ new Set([
|
|
9
|
-
"context",
|
|
10
|
-
"session",
|
|
11
|
-
"model",
|
|
12
|
-
"thinking",
|
|
13
|
-
"auth",
|
|
14
|
-
"quota",
|
|
15
|
-
"transport",
|
|
16
|
-
"unknown"
|
|
17
|
-
]);
|
|
18
|
-
function navigatorUnavailableKey(value) {
|
|
19
|
-
return typeof value === "string" && NAVIGATOR_UNAVAILABLE_KEYS.has(value) ? value : void 0;
|
|
20
|
-
}
|
|
21
|
-
class NavigatorUnavailableError extends Error {
|
|
22
|
-
unavailableSource;
|
|
23
|
-
unavailableCause;
|
|
24
|
-
originalCause;
|
|
25
|
-
constructor(source, message, cause = source, originalCause) {
|
|
26
|
-
super(message);
|
|
27
|
-
this.name = "NavigatorUnavailableError";
|
|
28
|
-
this.unavailableSource = source;
|
|
29
|
-
this.unavailableCause = cause;
|
|
30
|
-
this.originalCause = originalCause;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function navigatorUnavailableError(source, error, cause = source) {
|
|
34
|
-
const message = errorText(error);
|
|
35
|
-
return error instanceof NavigatorUnavailableError ? error : new NavigatorUnavailableError(source, message, cause, error);
|
|
36
|
-
}
|
|
37
|
-
function navigatorProviderFailureFromStatus(status) {
|
|
38
|
-
if (status === 401 || status === 403) return { source: "auth", cause: "auth" };
|
|
39
|
-
if (status === 429) return { source: "quota", cause: "quota" };
|
|
40
|
-
return void 0;
|
|
41
|
-
}
|
|
42
|
-
function navigatorProviderFailureFromCode(code) {
|
|
43
|
-
if (typeof code === "number") return navigatorProviderFailureFromStatus(code);
|
|
44
|
-
if (typeof code !== "string") return void 0;
|
|
45
|
-
if (code === "unauthorized" || code === "authentication_failed") return { source: "auth", cause: "auth" };
|
|
46
|
-
if (code === "insufficient_quota" || code === "quota_exhausted") return { source: "quota", cause: "quota" };
|
|
47
|
-
if (code === "transport_error") return { source: "transport", cause: "transport" };
|
|
48
|
-
return void 0;
|
|
49
|
-
}
|
|
50
|
-
function navigatorProviderFailureFromError(error) {
|
|
51
|
-
let cursor = error;
|
|
52
|
-
const seen = /* @__PURE__ */ new Set();
|
|
53
|
-
while (typeof cursor === "object" && cursor !== null && !seen.has(cursor)) {
|
|
54
|
-
seen.add(cursor);
|
|
55
|
-
if (cursor instanceof NavigatorUnavailableError) {
|
|
56
|
-
return { source: cursor.unavailableSource, cause: cursor.unavailableCause };
|
|
57
|
-
}
|
|
58
|
-
if (!isRecord(cursor)) {
|
|
59
|
-
cursor = cursor instanceof Error ? cursor.cause : void 0;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const fromReason = navigatorUnavailableKey(cursor.reason);
|
|
63
|
-
if (fromReason !== void 0) return { source: fromReason, cause: fromReason };
|
|
64
|
-
const statusCode = typeof cursor.statusCode === "number" ? cursor.statusCode : typeof cursor.status === "number" ? cursor.status : typeof cursor.httpStatus === "number" ? cursor.httpStatus : void 0;
|
|
65
|
-
const fromStatus = navigatorProviderFailureFromStatus(statusCode);
|
|
66
|
-
if (fromStatus !== void 0) return fromStatus;
|
|
67
|
-
const fromCode = navigatorProviderFailureFromCode(cursor.code);
|
|
68
|
-
if (fromCode !== void 0) return fromCode;
|
|
69
|
-
cursor = cursor.cause;
|
|
70
|
-
}
|
|
71
|
-
return void 0;
|
|
72
|
-
}
|
|
73
|
-
function navigatorProviderFailureFromDiagnostics(diagnostics) {
|
|
74
|
-
if (!Array.isArray(diagnostics)) return void 0;
|
|
75
|
-
for (const diagnostic of diagnostics) {
|
|
76
|
-
if (!isRecord(diagnostic)) continue;
|
|
77
|
-
if (diagnostic.type === "provider_transport_failure") return { source: "transport", cause: "transport" };
|
|
78
|
-
if (isRecord(diagnostic.error)) {
|
|
79
|
-
const fromCode = navigatorProviderFailureFromCode(diagnostic.error.code);
|
|
80
|
-
if (fromCode !== void 0) return fromCode;
|
|
81
|
-
}
|
|
82
|
-
if (isRecord(diagnostic.details)) {
|
|
83
|
-
const status = typeof diagnostic.details.status === "number" ? diagnostic.details.status : typeof diagnostic.details.statusCode === "number" ? diagnostic.details.statusCode : void 0;
|
|
84
|
-
const fromStatus = navigatorProviderFailureFromStatus(status);
|
|
85
|
-
if (fromStatus !== void 0) return fromStatus;
|
|
86
|
-
const fromCode = navigatorProviderFailureFromCode(diagnostic.details.code);
|
|
87
|
-
if (fromCode !== void 0) return fromCode;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return void 0;
|
|
91
|
-
}
|
|
92
|
-
function navigatorProviderFailureFromPublicTerminal(outcome) {
|
|
93
|
-
const facts = outcome.decisiveFacts;
|
|
94
|
-
const secondary = typeof facts.secondaryEvidence === "object" && facts.secondaryEvidence !== null ? facts.secondaryEvidence : void 0;
|
|
95
|
-
const httpStatus = typeof secondary?.httpStatus === "number" ? secondary.httpStatus : typeof facts.httpStatus === "number" ? facts.httpStatus : typeof facts.errorCode === "number" ? facts.errorCode : void 0;
|
|
96
|
-
const fromStatus = navigatorProviderFailureFromStatus(httpStatus);
|
|
97
|
-
if (fromStatus !== void 0) return fromStatus;
|
|
98
|
-
const diagnostics = secondary?.diagnostics ?? facts.diagnostics;
|
|
99
|
-
const fromDiagnostics = navigatorProviderFailureFromDiagnostics(diagnostics);
|
|
100
|
-
if (fromDiagnostics !== void 0) return fromDiagnostics;
|
|
101
|
-
const fromCode = navigatorProviderFailureFromError({
|
|
102
|
-
code: secondary?.code ?? facts.errorCode
|
|
103
|
-
});
|
|
104
|
-
if (fromCode !== void 0) return fromCode;
|
|
105
|
-
if (outcome.cause === "provider") return { source: "transport", cause: "unknown" };
|
|
106
|
-
const typed = navigatorUnavailableKey(outcome.cause);
|
|
107
|
-
if (typed !== void 0) return { source: typed, cause: typed };
|
|
108
|
-
return { source: "unknown", cause: "unknown" };
|
|
109
|
-
}
|
|
110
|
-
const navigatorProviderFailureSchema = Type.Object({
|
|
111
|
-
source: Type.Union([
|
|
112
|
-
Type.Literal("context"),
|
|
113
|
-
Type.Literal("session"),
|
|
114
|
-
Type.Literal("model"),
|
|
115
|
-
Type.Literal("thinking"),
|
|
116
|
-
Type.Literal("auth"),
|
|
117
|
-
Type.Literal("quota"),
|
|
118
|
-
Type.Literal("transport"),
|
|
119
|
-
Type.Literal("unknown")
|
|
120
|
-
]),
|
|
121
|
-
cause: Type.Union([
|
|
122
|
-
Type.Literal("context"),
|
|
123
|
-
Type.Literal("session"),
|
|
124
|
-
Type.Literal("model"),
|
|
125
|
-
Type.Literal("thinking"),
|
|
126
|
-
Type.Literal("auth"),
|
|
127
|
-
Type.Literal("quota"),
|
|
128
|
-
Type.Literal("transport"),
|
|
129
|
-
Type.Literal("unknown")
|
|
130
|
-
])
|
|
131
|
-
}, { additionalProperties: false });
|
|
132
|
-
function navigatorProviderFailure(message, source, cause = source) {
|
|
133
|
-
const fact = { source, cause };
|
|
134
|
-
if (!Value.Check(navigatorProviderFailureSchema, fact)) throw new TypeError("Navigator provider failure fact is not typed");
|
|
135
|
-
return Object.assign(message, { navigatorFailure: fact });
|
|
136
|
-
}
|
|
137
|
-
function navigatorModelSettingPath() {
|
|
138
|
-
return join(process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent"), "navigator-model.json");
|
|
139
|
-
}
|
|
140
|
-
async function readNavigatorModelSetting(path = navigatorModelSettingPath()) {
|
|
141
|
-
try {
|
|
142
|
-
const raw = JSON.parse(await readFile(path, "utf8"));
|
|
143
|
-
if (!isRecord(raw) || typeof raw.model !== "string" || raw.model.trim() === "") {
|
|
144
|
-
throw new Error("Navigator model setting is malformed");
|
|
145
|
-
}
|
|
146
|
-
return raw.model;
|
|
147
|
-
} catch (error) {
|
|
148
|
-
if (isEnoent(error)) {
|
|
149
|
-
throw new Error("Navigator model setting is missing");
|
|
150
|
-
}
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async function writeNavigatorModelSetting(model, path = navigatorModelSettingPath()) {
|
|
155
|
-
const normalized = model.trim();
|
|
156
|
-
parseNavigatorModelSetting(normalized);
|
|
157
|
-
await mkdir(dirname(path), { recursive: true });
|
|
158
|
-
await writeFile(path, `${JSON.stringify({ model: normalized })}
|
|
159
|
-
`, "utf8");
|
|
160
|
-
}
|
|
161
|
-
function parseNavigatorModelSetting(value) {
|
|
162
|
-
const slash = value.indexOf("/");
|
|
163
|
-
if (slash <= 0 || slash === value.length - 1) {
|
|
164
|
-
throw new Error("Navigator model setting must be provider/model[:thinking]");
|
|
165
|
-
}
|
|
166
|
-
const provider = value.slice(0, slash);
|
|
167
|
-
const modelWithThinking = value.slice(slash + 1);
|
|
168
|
-
const colon = modelWithThinking.lastIndexOf(":");
|
|
169
|
-
const suffix = colon < 0 ? void 0 : modelWithThinking.slice(colon + 1);
|
|
170
|
-
const model = colon < 0 ? modelWithThinking : modelWithThinking.slice(0, colon);
|
|
171
|
-
if (model === "") throw new Error("Navigator model setting must include a model");
|
|
172
|
-
if (suffix !== void 0 && suffix.trim() === "") {
|
|
173
|
-
throw new Error("Navigator model setting thinking suffix must be non-blank");
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
provider,
|
|
177
|
-
model,
|
|
178
|
-
...suffix === void 0 ? {} : { thinkingLevel: suffix }
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
async function resolveNavigatorSeatSelection(context) {
|
|
182
|
-
try {
|
|
183
|
-
const { loadPublicCliConfig } = await import("./public-cli/config.js");
|
|
184
|
-
const { seatModelOnly } = await import("./public-cli/registry.js");
|
|
185
|
-
const { packageMachineHome } = await import("./activation-ledger-topology.js");
|
|
186
|
-
const homeCandidate = context.home;
|
|
187
|
-
const envHome = process.env.HOME;
|
|
188
|
-
const home = typeof homeCandidate === "string" ? homeCandidate : typeof envHome === "string" && envHome.trim() !== "" ? envHome : packageMachineHome();
|
|
189
|
-
const config = await loadPublicCliConfig(home);
|
|
190
|
-
const modelOnly = seatModelOnly(config.seats.navigator);
|
|
191
|
-
if (modelOnly === void 0) {
|
|
192
|
-
const { missingResolvedSeatModelMessage } = await import("./public-cli/config.js");
|
|
193
|
-
throw navigatorUnavailableError(
|
|
194
|
-
"model",
|
|
195
|
-
new Error(missingResolvedSeatModelMessage("navigator"))
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
const thinkingRaw = modelOnly.thinking;
|
|
199
|
-
const configuredLabel = thinkingRaw === void 0 ? `${modelOnly.provider}/${modelOnly.model}` : `${modelOnly.provider}/${modelOnly.model}:${thinkingRaw}`;
|
|
200
|
-
return {
|
|
201
|
-
selection: {
|
|
202
|
-
provider: modelOnly.provider,
|
|
203
|
-
model: modelOnly.model,
|
|
204
|
-
...thinkingRaw === void 0 ? {} : { thinking: thinkingRaw }
|
|
205
|
-
},
|
|
206
|
-
configuredLabel,
|
|
207
|
-
...thinkingRaw === void 0 ? {} : { thinkingLevel: thinkingRaw }
|
|
208
|
-
};
|
|
209
|
-
} catch (error) {
|
|
210
|
-
throw navigatorUnavailableError("model", error);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
export {
|
|
214
|
-
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
215
|
-
NavigatorUnavailableError,
|
|
216
|
-
navigatorModelSettingPath,
|
|
217
|
-
navigatorProviderFailure,
|
|
218
|
-
navigatorProviderFailureFromDiagnostics,
|
|
219
|
-
navigatorProviderFailureFromError,
|
|
220
|
-
navigatorProviderFailureFromPublicTerminal,
|
|
221
|
-
navigatorProviderFailureFromStatus,
|
|
222
|
-
navigatorUnavailableError,
|
|
223
|
-
parseNavigatorModelSetting,
|
|
224
|
-
readNavigatorModelSetting,
|
|
225
|
-
resolveNavigatorSeatSelection,
|
|
226
|
-
writeNavigatorModelSetting
|
|
227
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host-neutral Navigator work-context loader (#590 / #1187).
|
|
3
|
-
* Auto prepare is identity-only: subjectKey + provenance. No parent dispatch,
|
|
4
|
-
* role-input bytes, or work-root authority files are loaded as materials.
|
|
5
|
-
* Flag/input resolution is supplied by the host; no ExtensionAPI dependency.
|
|
6
|
-
*/
|
|
7
|
-
import { resolve } from "node:path";
|
|
8
|
-
import { sessionDirectoryOf } from "./role-run-placement.js";
|
|
9
|
-
import { runDirectoryFromHostContext } from "./host-contracts.js";
|
|
10
|
-
import { navigatorSubjectKeyForInput, navigatorUnavailableError, subjectPath, } from "./navigator-attendance.js";
|
|
11
|
-
import { packagedNavigatorSubject, packagedRoleInputFlag } from "./packaged-role-registry.js";
|
|
12
|
-
import { loadAdmittedJudgeRequest } from "./public-cli/invocation.js";
|
|
13
|
-
function navigatorInputReference(getFlag, role) {
|
|
14
|
-
if (getFlag === undefined)
|
|
15
|
-
return undefined;
|
|
16
|
-
const name = packagedRoleInputFlag(role);
|
|
17
|
-
const value = name === undefined ? undefined : getFlag(name);
|
|
18
|
-
return typeof value === "string" && value !== "" ? resolve(value) : undefined;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Resolve typed Navigator work context from host flags and/or the public admitted request.
|
|
22
|
-
* Returns identity (subjectKey + provenance) only — auto prepare does not consume materials.
|
|
23
|
-
*/
|
|
24
|
-
export async function loadNavigatorWorkContext(options) {
|
|
25
|
-
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
26
|
-
const subjectMode = packagedNavigatorSubject(options.role);
|
|
27
|
-
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
28
|
-
const subjectKey = reference === undefined
|
|
29
|
-
? subjectRoot
|
|
30
|
-
: navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
31
|
-
// Public ak-role run: admitted request decides empty vs concrete identity.
|
|
32
|
-
const publicRunDir = runDirectoryFromHostContext(options.context);
|
|
33
|
-
const currentSessionDir = options.context.sessionManager.getSessionDir();
|
|
34
|
-
const isBoundPublicRun = publicRunDir !== undefined
|
|
35
|
-
&& resolve(currentSessionDir) === resolve(sessionDirectoryOf(publicRunDir));
|
|
36
|
-
if (subjectMode === "public-instruction" && isBoundPublicRun) {
|
|
37
|
-
// Control-plane read faults keep their real cause inside context-error (#1187 F2).
|
|
38
|
-
// Only true absence / wrong-shape is undefined → generic missing message.
|
|
39
|
-
let admitted;
|
|
40
|
-
try {
|
|
41
|
-
admitted = await loadAdmittedJudgeRequest(publicRunDir);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
throw navigatorUnavailableError("context", error);
|
|
45
|
-
}
|
|
46
|
-
if (admitted === undefined) {
|
|
47
|
-
throw navigatorUnavailableError("context", new Error("public Judge admitted request was missing or malformed"));
|
|
48
|
-
}
|
|
49
|
-
if (!admitted.instructionEmpty && admitted.instruction.trim() !== "") {
|
|
50
|
-
// #1187: non-empty public admission starts parallel prepare by identity.
|
|
51
|
-
// Parent instruction remains the parent role's own dispatch; auto navigator
|
|
52
|
-
// does not receive that prose (or a duplicate authority copy) as material.
|
|
53
|
-
return {
|
|
54
|
-
subjectKey: subjectRoot,
|
|
55
|
-
subjectProvenance: "role_input",
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
subjectKey: subjectRoot,
|
|
60
|
-
subjectProvenance: "placeholder",
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
// Concrete role-input path (file/case/source-run flag) is identity enough to start prepare.
|
|
64
|
-
// Navigator reads ticket and station records itself when needed — no material copy here.
|
|
65
|
-
if (reference !== undefined) {
|
|
66
|
-
return { subjectKey, subjectProvenance: "role_input" };
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
subjectKey: subjectRoot,
|
|
70
|
-
subjectProvenance: "placeholder",
|
|
71
|
-
};
|
|
72
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
## 备答
|
|
2
|
-
|
|
3
|
-
父衙门一开始即并行准备。有票时读票卷宗里实际发生的角色运行,必要时看票面;不读过去的建议。按主衙门可能的结局 status 预写建议,经 `byStatus` 提交(键为 status 字面量,值为建议正文)。无状态分叉时可用单条 `prose`。
|
|
4
|
-
|
|
5
|
-
## 常用交付线
|
|
6
|
-
|
|
7
|
-
立票
|
|
8
|
-
↓
|
|
9
|
-
给事中(票庭审读)
|
|
10
|
-
↓
|
|
11
|
-
将作监(开工)
|
|
12
|
-
↓
|
|
13
|
-
御史台
|
|
14
|
-
↓
|
|
15
|
-
大理寺
|
|
16
|
-
├─ 有问题(通常) → 修内司 → 大理寺(修内司收卷不经御史台,直回大理寺)
|
|
17
|
-
├─ 需要再审(大理寺点名) → 御史台 → 大理寺
|
|
18
|
-
└─ 收敛 → 调用者合并、关票
|
|
19
|
-
|
|
20
|
-
## 线上审查材料
|
|
21
|
-
|
|
22
|
-
collector(收齐 current-head 材料)
|
|
23
|
-
↓
|
|
24
|
-
大理寺(裁决 findings)
|
|
25
|
-
├─ 有问题 → 修内司 → 大理寺
|
|
26
|
-
└─ 收敛 → 调用者合并、关票
|
|
27
|
-
|
|
28
|
-
## 未完交棒(unfinished)
|
|
29
|
-
|
|
30
|
-
修内司 / 将作监 apply 以 unfinished 交棒时,工作仍未结清:
|
|
31
|
-
→ 续修(通常仍是同一 worker 的 apply),不要送大理寺
|
|
32
|
-
|
|
33
|
-
refused / partially_completed 是已结清结算,送大理寺审计仍合法。
|