@akagilnc/pi-workflow-roles 0.1.4259 → 0.1.4274
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 +26 -22
- package/README.zh-CN.md +23 -20
- package/dist/acp-host/production-host.js +5984 -5227
- package/dist/headless-host/production-host.js +5912 -5155
- package/dist/navigator-attendance.js +0 -2
- package/dist/navigator-public-session.js +2 -4
- package/dist/navigator-session-contracts.js +6 -13
- package/dist/public-cli/config.js +16 -20
- package/dist/public-cli/main.js +502 -411
- package/dist/public-cli/registry.js +0 -57
- package/dist/public-role-summons.js +121 -96
- package/package.json +1 -1
- package/src/navigator-attendance.ts +0 -2
- package/src/navigator-public-session.ts +3 -3
- package/src/navigator-session-contracts.ts +8 -14
- package/src/public-cli/cli.ts +115 -307
- package/src/public-cli/config.ts +35 -23
- package/src/public-cli/registry.ts +2 -66
- package/src/public-role-summons.ts +197 -125
|
@@ -19,62 +19,6 @@ function seatModelOnly(seat) {
|
|
|
19
19
|
if (seat?.provider === void 0 || seat.model === void 0) return void 0;
|
|
20
20
|
return seat.thinking === void 0 ? { provider: seat.provider, model: seat.model } : { provider: seat.provider, model: seat.model, thinking: seat.thinking };
|
|
21
21
|
}
|
|
22
|
-
const STARTUP_CANDIDATES = {
|
|
23
|
-
judge: [
|
|
24
|
-
{ provider: "openai-codex", model: "gpt-5.6-sol", thinking: "high" },
|
|
25
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
26
|
-
],
|
|
27
|
-
countersign: [
|
|
28
|
-
{ provider: "openai-codex", model: "gpt-5.6-sol", thinking: "high" },
|
|
29
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
30
|
-
],
|
|
31
|
-
"gleaner-left": [
|
|
32
|
-
{ provider: "openai-codex", model: "gpt-5.6-sol", thinking: "medium" },
|
|
33
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
34
|
-
],
|
|
35
|
-
reviewer: [
|
|
36
|
-
{ provider: "openai-codex", model: "gpt-5.6-sol", thinking: "medium" },
|
|
37
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
38
|
-
],
|
|
39
|
-
coder: [
|
|
40
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
|
|
41
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
42
|
-
],
|
|
43
|
-
fixer: [
|
|
44
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
|
|
45
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
46
|
-
],
|
|
47
|
-
collector: [
|
|
48
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
|
|
49
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
50
|
-
],
|
|
51
|
-
doctor: [
|
|
52
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
|
|
53
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
54
|
-
],
|
|
55
|
-
merger: [
|
|
56
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
|
|
57
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
58
|
-
],
|
|
59
|
-
// #620: subordinate officers inherit gatekeeper; no package startup model.
|
|
60
|
-
notary: [],
|
|
61
|
-
// #453/#620/#639: gatekeeper callable but no package startup model — caller
|
|
62
|
-
// configures it or inherits on the province path.
|
|
63
|
-
gatekeeper: [],
|
|
64
|
-
inspector: [],
|
|
65
|
-
navigator: [
|
|
66
|
-
{ provider: "openai-codex", model: "gpt-5.6-luna", thinking: "medium" },
|
|
67
|
-
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
68
|
-
],
|
|
69
|
-
// #675: auditor public seat — no package startup; caller configures.
|
|
70
|
-
auditor: [],
|
|
71
|
-
// #708 `diarist-seat-default`: owner-set initial value; changed in the seat
|
|
72
|
-
// table like any other seat. No engine axis, package-default host.
|
|
73
|
-
diarist: [{ provider: "xai", model: "grok-4.5", thinking: "medium" }]
|
|
74
|
-
};
|
|
75
|
-
function publicStartupCandidates(seat) {
|
|
76
|
-
return STARTUP_CANDIDATES[seat];
|
|
77
|
-
}
|
|
78
22
|
const PUBLIC_DETERMINISTIC_COMMANDS = ["analyst"];
|
|
79
23
|
function listHelpCapabilities() {
|
|
80
24
|
const support = PUBLIC_CLI_SUPPORT_COMMANDS.map((name) => ({
|
|
@@ -118,6 +62,5 @@ export {
|
|
|
118
62
|
isPublicCliSupportCommand,
|
|
119
63
|
isPublicConfigurableSeat,
|
|
120
64
|
listHelpCapabilities,
|
|
121
|
-
publicStartupCandidates,
|
|
122
65
|
seatModelOnly
|
|
123
66
|
};
|
|
@@ -77,11 +77,17 @@ function hostSelectionFailureFromUnknown(error) {
|
|
|
77
77
|
const failure = error.failure;
|
|
78
78
|
return failure;
|
|
79
79
|
}
|
|
80
|
-
async function createSummonEnv(options) {
|
|
81
|
-
const [
|
|
80
|
+
async function createSummonEnv(options, afterHost) {
|
|
81
|
+
const [
|
|
82
|
+
{ piDurablePrincipalAuthority },
|
|
83
|
+
{ appendPiSessionCustomEntry },
|
|
84
|
+
{ resolveRoleTurnHost },
|
|
85
|
+
{ missingResolvedSeatModelMessage, resolvedSeatWithModel }
|
|
86
|
+
] = await Promise.all([
|
|
82
87
|
import("./pi/durable-principal.js"),
|
|
83
88
|
import("./pi/role-turn-host.js"),
|
|
84
|
-
import("./public-cli/role-turn-host-resolution.js")
|
|
89
|
+
import("./public-cli/role-turn-host-resolution.js"),
|
|
90
|
+
import("./public-cli/config.js")
|
|
85
91
|
]);
|
|
86
92
|
const principalAuthority = piDurablePrincipalAuthority;
|
|
87
93
|
const roleTurnHost = resolveRoleTurnHost(
|
|
@@ -93,26 +99,37 @@ async function createSummonEnv(options) {
|
|
|
93
99
|
},
|
|
94
100
|
{ role: options.role, seat: options.seat, principalAuthority }
|
|
95
101
|
);
|
|
96
|
-
|
|
102
|
+
afterHost?.();
|
|
103
|
+
const seatWithModel = resolvedSeatWithModel(options.seat);
|
|
104
|
+
if (seatWithModel === void 0) {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
missingModelMessage: missingResolvedSeatModelMessage(options.role)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const hostName = seatWithModel.host ?? "pi";
|
|
97
111
|
const { loadHostProvidersTable, projectHostFacingProvider } = await import("./public-cli/host-providers.js");
|
|
98
|
-
const hostFacingSelection =
|
|
99
|
-
|
|
112
|
+
const hostFacingSelection = projectHostFacingProvider(
|
|
113
|
+
seatWithModel.selection,
|
|
100
114
|
hostName,
|
|
101
115
|
loadHostProvidersTable(options.home),
|
|
102
116
|
options.home
|
|
103
117
|
);
|
|
104
118
|
return {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
ok: true,
|
|
120
|
+
env: {
|
|
121
|
+
home: options.home,
|
|
122
|
+
principalAuthority,
|
|
123
|
+
agentDir: options.agentDir,
|
|
124
|
+
sessionAppender: appendPiSessionCustomEntry,
|
|
125
|
+
packageRoot: options.packageRoot,
|
|
126
|
+
roleTurnHost,
|
|
127
|
+
cwd: options.cwd,
|
|
128
|
+
credentials: options.credentials,
|
|
129
|
+
...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
|
|
130
|
+
...projectSeatEngine(seatWithModel),
|
|
131
|
+
...projectSeatHost(seatWithModel)
|
|
132
|
+
}
|
|
116
133
|
};
|
|
117
134
|
}
|
|
118
135
|
async function summonPublicRole(options) {
|
|
@@ -127,46 +144,72 @@ async function summonPublicRole(options) {
|
|
|
127
144
|
const credentials = options.credentials ?? await loadCredentialProviders(agentDir);
|
|
128
145
|
const config = await loadPublicCliConfig(home);
|
|
129
146
|
const seat = resolveEffectiveSeat(config, options.role, credentials);
|
|
130
|
-
let summonEnv;
|
|
131
|
-
try {
|
|
132
|
-
summonEnv = await createSummonEnv({
|
|
133
|
-
role: options.role,
|
|
134
|
-
home,
|
|
135
|
-
agentDir,
|
|
136
|
-
cwd: options.cwd,
|
|
137
|
-
packageRoot,
|
|
138
|
-
credentials,
|
|
139
|
-
seat,
|
|
140
|
-
...options.extraPiArgs === void 0 ? {} : { extraPiArgs: options.extraPiArgs },
|
|
141
|
-
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
142
|
-
...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters }
|
|
143
|
-
});
|
|
144
|
-
} catch (error) {
|
|
145
|
-
const failure = hostSelectionFailureFromUnknown(error);
|
|
146
|
-
if (failure !== void 0) {
|
|
147
|
-
const { formatHostSelectionFailure } = await import("./public-cli/role-turn-host-resolution.js");
|
|
148
|
-
return { exitCode: 1, stderr: formatHostSelectionFailure(failure) };
|
|
149
|
-
}
|
|
150
|
-
throw error;
|
|
151
|
-
}
|
|
152
|
-
const env = {
|
|
153
|
-
...summonEnv,
|
|
154
|
-
// Station child role run (#840): omit automatic navigator attendance.
|
|
155
|
-
stationChild: true,
|
|
156
|
-
// Host config passthrough only — same face as public CLI (#422 / #675).
|
|
157
|
-
...config.autoResumeLimit === void 0 ? {} : { autoResumeLimit: config.autoResumeLimit },
|
|
158
|
-
// Parent cancellation reaches the nested activation's own turn dispatch.
|
|
159
|
-
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
160
|
-
// #753: reask rides the existing notary same-ticket resume summons.instruction.
|
|
161
|
-
...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
|
|
162
|
-
// #879: verbatim submission body on officer dialogue content channel.
|
|
163
|
-
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
|
|
164
|
-
...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
|
|
165
|
-
// createRunId is the only remaining env overlay — host is seat-selected above.
|
|
166
|
-
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
167
|
-
};
|
|
168
147
|
const captured = options.io === void 0 ? createCapturingIo() : void 0;
|
|
169
148
|
const io = options.io ?? captured.io;
|
|
149
|
+
const summonEnvInput = {
|
|
150
|
+
role: options.role,
|
|
151
|
+
home,
|
|
152
|
+
agentDir,
|
|
153
|
+
cwd: options.cwd,
|
|
154
|
+
packageRoot,
|
|
155
|
+
credentials,
|
|
156
|
+
seat,
|
|
157
|
+
...options.extraPiArgs === void 0 ? {} : { extraPiArgs: options.extraPiArgs },
|
|
158
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
159
|
+
...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters }
|
|
160
|
+
};
|
|
161
|
+
async function prepareSummonEnv(afterHost) {
|
|
162
|
+
try {
|
|
163
|
+
const built = await createSummonEnv(summonEnvInput, afterHost);
|
|
164
|
+
if (!built.ok) {
|
|
165
|
+
return { ok: false, exitCode: 1, stderr: built.missingModelMessage };
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
ok: true,
|
|
169
|
+
env: {
|
|
170
|
+
...built.env,
|
|
171
|
+
stationChild: true,
|
|
172
|
+
...config.autoResumeLimit === void 0 ? {} : { autoResumeLimit: config.autoResumeLimit },
|
|
173
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
174
|
+
...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
|
|
175
|
+
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
|
|
176
|
+
...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
|
|
177
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
} catch (error) {
|
|
181
|
+
const failure = hostSelectionFailureFromUnknown(error);
|
|
182
|
+
if (failure !== void 0) {
|
|
183
|
+
const { formatHostSelectionFailure } = await import("./public-cli/role-turn-host-resolution.js");
|
|
184
|
+
return { ok: false, exitCode: 1, stderr: formatHostSelectionFailure(failure) };
|
|
185
|
+
}
|
|
186
|
+
const { CliUsageError } = await import("./public-cli/cli-errors.js");
|
|
187
|
+
if (error instanceof CliUsageError) {
|
|
188
|
+
const { presentStructuralRejection } = await import("./public-cli/settlement.js");
|
|
189
|
+
presentStructuralRejection(error, io);
|
|
190
|
+
return { ok: false, exitCode: 2 };
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function projectPrepareFailure(prepared) {
|
|
196
|
+
const parts = [prepared.stderr, captured?.stderrText()].filter(
|
|
197
|
+
(s) => typeof s === "string" && s !== ""
|
|
198
|
+
);
|
|
199
|
+
const stderr2 = parts.length === 0 ? void 0 : parts.join("");
|
|
200
|
+
return {
|
|
201
|
+
exitCode: prepared.exitCode,
|
|
202
|
+
...stderr2 === void 0 ? {} : { stderr: stderr2 }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
async function runPrepared(parse, run) {
|
|
206
|
+
let parsedArgv;
|
|
207
|
+
const prepared = await prepareSummonEnv(() => {
|
|
208
|
+
parsedArgv = parse(options.argv);
|
|
209
|
+
});
|
|
210
|
+
if (!prepared.ok) return { fail: projectPrepareFailure(prepared) };
|
|
211
|
+
return { ok: await run(prepared.env, () => parsedArgv) };
|
|
212
|
+
}
|
|
170
213
|
let result;
|
|
171
214
|
switch (options.role) {
|
|
172
215
|
case "notary": {
|
|
@@ -174,7 +217,9 @@ async function summonPublicRole(options) {
|
|
|
174
217
|
import("./public-cli/notary-run.js"),
|
|
175
218
|
import("./public-cli/invocation.js")
|
|
176
219
|
]);
|
|
177
|
-
|
|
220
|
+
const stepped = await runPrepared(parseNotaryArgv, (env, once) => runPublicNotary(options.argv, env, io, once));
|
|
221
|
+
if ("fail" in stepped) return stepped.fail;
|
|
222
|
+
result = stepped.ok;
|
|
178
223
|
break;
|
|
179
224
|
}
|
|
180
225
|
case "inspector": {
|
|
@@ -182,49 +227,23 @@ async function summonPublicRole(options) {
|
|
|
182
227
|
import("./public-cli/inspector-run.js"),
|
|
183
228
|
import("./public-cli/invocation.js")
|
|
184
229
|
]);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
case "auditor": {
|
|
189
|
-
const [{ runPublicInstructionSeat }, { parseAuditorArgv }] = await Promise.all([
|
|
190
|
-
import("./public-cli/instruction-seat-run.js"),
|
|
191
|
-
import("./public-cli/invocation.js")
|
|
192
|
-
]);
|
|
193
|
-
result = await runPublicInstructionSeat(
|
|
194
|
-
options.argv,
|
|
195
|
-
env,
|
|
196
|
-
io,
|
|
197
|
-
"auditor",
|
|
198
|
-
parseAuditorArgv
|
|
199
|
-
);
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
case "navigator": {
|
|
203
|
-
const [{ runPublicInstructionSeat }, { parseNavigatorArgv }] = await Promise.all([
|
|
204
|
-
import("./public-cli/instruction-seat-run.js"),
|
|
205
|
-
import("./public-cli/invocation.js")
|
|
206
|
-
]);
|
|
207
|
-
result = await runPublicInstructionSeat(
|
|
208
|
-
options.argv,
|
|
209
|
-
env,
|
|
210
|
-
io,
|
|
211
|
-
"navigator",
|
|
212
|
-
parseNavigatorArgv
|
|
213
|
-
);
|
|
230
|
+
const stepped = await runPrepared(parseInspectorArgv, (env, once) => runPublicInspector(options.argv, env, io, once));
|
|
231
|
+
if ("fail" in stepped) return stepped.fail;
|
|
232
|
+
result = stepped.ok;
|
|
214
233
|
break;
|
|
215
234
|
}
|
|
235
|
+
case "auditor":
|
|
236
|
+
case "navigator":
|
|
216
237
|
case "gatekeeper": {
|
|
217
|
-
const
|
|
238
|
+
const seat2 = options.role;
|
|
239
|
+
const [{ runPublicInstructionSeat }, invocation] = await Promise.all([
|
|
218
240
|
import("./public-cli/instruction-seat-run.js"),
|
|
219
241
|
import("./public-cli/invocation.js")
|
|
220
242
|
]);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
"gatekeeper",
|
|
226
|
-
parseGatekeeperArgv
|
|
227
|
-
);
|
|
243
|
+
const parse = seat2 === "auditor" ? invocation.parseAuditorArgv : seat2 === "navigator" ? invocation.parseNavigatorArgv : invocation.parseGatekeeperArgv;
|
|
244
|
+
const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat(options.argv, env, io, seat2, once));
|
|
245
|
+
if ("fail" in stepped) return stepped.fail;
|
|
246
|
+
result = stepped.ok;
|
|
228
247
|
break;
|
|
229
248
|
}
|
|
230
249
|
case "judge": {
|
|
@@ -232,7 +251,9 @@ async function summonPublicRole(options) {
|
|
|
232
251
|
import("./public-cli/judge-run.js"),
|
|
233
252
|
import("./public-cli/invocation.js")
|
|
234
253
|
]);
|
|
235
|
-
|
|
254
|
+
const stepped = await runPrepared(parseJudgeArgv, (env, once) => runPublicJudge(options.argv, env, io, once));
|
|
255
|
+
if ("fail" in stepped) return stepped.fail;
|
|
256
|
+
result = stepped.ok;
|
|
236
257
|
break;
|
|
237
258
|
}
|
|
238
259
|
case "doctor": {
|
|
@@ -240,7 +261,9 @@ async function summonPublicRole(options) {
|
|
|
240
261
|
import("./public-cli/doctor-run.js"),
|
|
241
262
|
import("./public-cli/invocation.js")
|
|
242
263
|
]);
|
|
243
|
-
|
|
264
|
+
const stepped = await runPrepared(parseDoctorArgv, (env, once) => runPublicDoctor(options.argv, env, io, once));
|
|
265
|
+
if ("fail" in stepped) return stepped.fail;
|
|
266
|
+
result = stepped.ok;
|
|
244
267
|
break;
|
|
245
268
|
}
|
|
246
269
|
case "diarist": {
|
|
@@ -248,7 +271,9 @@ async function summonPublicRole(options) {
|
|
|
248
271
|
import("./public-cli/diarist-run.js"),
|
|
249
272
|
import("./public-cli/invocation.js")
|
|
250
273
|
]);
|
|
251
|
-
|
|
274
|
+
const stepped = await runPrepared(parseDiaristArgv, (env, once) => runPublicDiarist(options.argv, env, io, once));
|
|
275
|
+
if ("fail" in stepped) return stepped.fail;
|
|
276
|
+
result = stepped.ok;
|
|
252
277
|
break;
|
|
253
278
|
}
|
|
254
279
|
}
|
package/package.json
CHANGED
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
import type { HostContext } from "./host-contracts.ts";
|
|
19
19
|
import { createNativeNavigatorSessionFactory } from "./navigator-public-session.ts";
|
|
20
20
|
import {
|
|
21
|
-
NAVIGATOR_DEFAULT_MODEL,
|
|
22
21
|
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
23
22
|
NavigatorUnavailableError,
|
|
24
23
|
navigatorModelSettingPath,
|
|
@@ -40,7 +39,6 @@ import {
|
|
|
40
39
|
import { sitianReport } from "./sitian-facade.ts";
|
|
41
40
|
|
|
42
41
|
export {
|
|
43
|
-
NAVIGATOR_DEFAULT_MODEL,
|
|
44
42
|
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
45
43
|
NavigatorUnavailableError,
|
|
46
44
|
navigatorModelSettingPath,
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
navigatorProviderFailureFromError,
|
|
13
13
|
navigatorUnavailableError,
|
|
14
14
|
parseNavigatorModelSetting,
|
|
15
|
-
resolveNavigatorSeatSelection,
|
|
16
15
|
type NavigatorProviderFailureFact,
|
|
17
16
|
type NavigatorSessionFactory,
|
|
18
17
|
} from "./navigator-session-contracts.ts";
|
|
@@ -43,8 +42,9 @@ async function resolveNavigatorLedgerHome(context: HostContext): Promise<string
|
|
|
43
42
|
|
|
44
43
|
export function createNativeNavigatorSessionFactory(): NavigatorSessionFactory {
|
|
45
44
|
return async ({ context, subject, tool }) => {
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// Model is enforced at prepare (attendance seat resolve) and at prompt (summon).
|
|
46
|
+
// Factory open only books the archivist nest — no package default, no eager seat read.
|
|
47
|
+
let thinkingLevel: string | undefined;
|
|
48
48
|
|
|
49
49
|
// Archivist nest for attendance route memory only (ADR 0018 / 0065) — not a session open.
|
|
50
50
|
// #852: navigator/<work-subject> is the sole book-top exception; always pass subject so
|
|
@@ -15,7 +15,6 @@ import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
export const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare" as const;
|
|
18
|
-
export const NAVIGATOR_DEFAULT_MODEL = "openai-codex/gpt-5.6-luna:max" as const;
|
|
19
18
|
|
|
20
19
|
export type NavigatorUnavailableKey =
|
|
21
20
|
| "context" | "session" | "model" | "thinking" | "auth" | "quota" | "transport" | "unknown";
|
|
@@ -229,8 +228,9 @@ export async function readNavigatorModelSetting(path = navigatorModelSettingPath
|
|
|
229
228
|
}
|
|
230
229
|
return raw.model;
|
|
231
230
|
} catch (error) {
|
|
231
|
+
// #178: missing file is absence (no package default).
|
|
232
232
|
if (error instanceof Error && "code" in error && (error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
233
|
-
|
|
233
|
+
throw new Error("Navigator model setting is missing");
|
|
234
234
|
}
|
|
235
235
|
throw error;
|
|
236
236
|
}
|
|
@@ -294,19 +294,13 @@ export async function resolveNavigatorSeatSelection(
|
|
|
294
294
|
: packageMachineHome();
|
|
295
295
|
const config = await loadPublicCliConfig(home);
|
|
296
296
|
const modelOnly = seatModelOnly(config.seats.navigator);
|
|
297
|
-
// Seat table
|
|
298
|
-
// Bare missing seat uses the package default constant (not a file path).
|
|
297
|
+
// Seat table only — missing navigator seat → typed model-unavailable (#178).
|
|
299
298
|
if (modelOnly === undefined) {
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
...(parsed.thinkingLevel === undefined ? {} : { thinking: parsed.thinkingLevel }),
|
|
306
|
-
},
|
|
307
|
-
configuredLabel: NAVIGATOR_DEFAULT_MODEL,
|
|
308
|
-
...(parsed.thinkingLevel === undefined ? {} : { thinkingLevel: parsed.thinkingLevel }),
|
|
309
|
-
};
|
|
299
|
+
const { missingResolvedSeatModelMessage } = await import("./public-cli/config.ts");
|
|
300
|
+
throw navigatorUnavailableError(
|
|
301
|
+
"model",
|
|
302
|
+
new Error(missingResolvedSeatModelMessage("navigator")),
|
|
303
|
+
);
|
|
310
304
|
}
|
|
311
305
|
// Host params passthrough only — no map/validate/default (#675 ⑥).
|
|
312
306
|
const thinkingRaw = modelOnly.thinking;
|