@akagilnc/pi-workflow-roles 0.1.3439 → 0.1.3448

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.
@@ -802,7 +802,7 @@ function createNativeNavigatorSessionFactory(defaultModelSettingPath = navigator
802
802
  }
803
803
  },
804
804
  entries: () => sessionManager.getEntries(),
805
- setModel: async (next, nextThinking) => {
805
+ setModel: async (next) => {
806
806
  let nextParsed;
807
807
  try {
808
808
  nextParsed = parseNavigatorModelSetting(next);
@@ -815,16 +815,10 @@ function createNativeNavigatorSessionFactory(defaultModelSettingPath = navigator
815
815
  `Navigator model switch requires a new session: ${configuredLabel} \u2192 ${next}`
816
816
  );
817
817
  }
818
- if (nextParsed.thinkingLevel !== nextThinking || thinkingLevel !== nextThinking) {
819
- throw new NavigatorUnavailableError(
820
- "thinking",
821
- `Navigator thinking level ${nextThinking} is unavailable for ${next}`
822
- );
823
- }
824
818
  selection = {
825
819
  provider: nextParsed.provider,
826
820
  model: nextParsed.model,
827
- thinking: nextParsed.thinkingLevel
821
+ ...nextParsed.thinkingLevel === void 0 ? {} : { thinking: nextParsed.thinkingLevel }
828
822
  };
829
823
  thinkingLevel = nextParsed.thinkingLevel;
830
824
  configuredLabel = next;
@@ -750,7 +750,7 @@ async function openPiInstitutionalSession(options) {
750
750
  api: fallbackApi,
751
751
  provider: selection.provider,
752
752
  baseUrl: providerDefaultModel?.baseUrl ?? "",
753
- reasoning: selection.thinking !== void 0 && selection.thinking !== "off",
753
+ reasoning: providerDefaultModel?.reasoning ?? false,
754
754
  input: ["text"],
755
755
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
756
756
  contextWindow: 128e3,
@@ -1049,11 +1049,10 @@ async function openPiInstitutionalSession(options) {
1049
1049
  });
1050
1050
  }
1051
1051
  }
1052
- const requestedThinking = options.selection.thinking === "max" ? "max" : "off";
1053
1052
  const { session } = await createAgentSession({
1054
1053
  cwd: options.cwd,
1055
1054
  model: effectiveModel,
1056
- thinkingLevel: requestedThinking,
1055
+ ...options.selection.thinking === void 0 ? {} : { thinkingLevel: options.selection.thinking },
1057
1056
  modelRuntime: runtime,
1058
1057
  sessionManager,
1059
1058
  settingsManager: settings,
@@ -1063,15 +1062,6 @@ async function openPiInstitutionalSession(options) {
1063
1062
  ...options.toolsAllowlist === void 0 ? {} : { tools: options.toolsAllowlist },
1064
1063
  ...customTools.length === 0 ? {} : { customTools }
1065
1064
  });
1066
- if (requestedThinking === "max" && session.thinkingLevel !== "max") {
1067
- session.dispose();
1068
- throw withTypedReason(
1069
- new Error(
1070
- `${label} thinking level max is unavailable for ${selection.provider}/${selection.model}`
1071
- ),
1072
- "thinking"
1073
- );
1074
- }
1075
1065
  const listeners = /* @__PURE__ */ new Set();
1076
1066
  const accumulatedUsage = emptyUsage();
1077
1067
  let lastEmittedAssistant;
@@ -3980,33 +3970,29 @@ async function readNavigatorModelSetting(path = navigatorModelSettingPath()) {
3980
3970
  function parseNavigatorModelSetting(value) {
3981
3971
  const slash = value.indexOf("/");
3982
3972
  if (slash <= 0 || slash === value.length - 1) {
3983
- throw new Error("Navigator model setting must be provider/model[:max]");
3973
+ throw new Error("Navigator model setting must be provider/model[:thinking]");
3984
3974
  }
3985
3975
  const provider = value.slice(0, slash);
3986
3976
  const modelWithThinking = value.slice(slash + 1);
3987
3977
  const colon = modelWithThinking.lastIndexOf(":");
3988
3978
  const suffix = colon < 0 ? void 0 : modelWithThinking.slice(colon + 1);
3989
- if (suffix !== void 0 && suffix !== "max") {
3990
- throw new Error("Navigator model setting must use :max or omit the thinking suffix");
3991
- }
3992
3979
  const model = colon < 0 ? modelWithThinking : modelWithThinking.slice(0, colon);
3993
3980
  if (model === "") throw new Error("Navigator model setting must include a model");
3994
- return { provider, model, thinkingLevel: suffix === "max" ? "max" : "off" };
3981
+ return suffix === void 0 ? { provider, model } : { provider, model, thinkingLevel: suffix };
3995
3982
  }
3996
3983
  async function resolveNavigatorSeatSelection(context, modelSettingPath, defaultModelSettingPath) {
3997
3984
  const runDirectory = auditorRunDirectory(context);
3998
3985
  if (runDirectory !== void 0) {
3999
3986
  try {
4000
3987
  const selection = await readInstitutionalSeatSelection(runDirectory, "navigator");
4001
- const thinkingLevel = selection.thinking === "max" ? "max" : "off";
4002
3988
  return {
4003
3989
  selection: {
4004
3990
  provider: selection.provider,
4005
3991
  model: selection.model,
4006
3992
  ...selection.thinking === void 0 ? {} : { thinking: selection.thinking }
4007
3993
  },
4008
- configuredLabel: `${selection.provider}/${selection.model}${thinkingLevel === "max" ? ":max" : ""}`,
4009
- thinkingLevel
3994
+ configuredLabel: selection.thinking === void 0 ? `${selection.provider}/${selection.model}` : `${selection.provider}/${selection.model}:${selection.thinking}`,
3995
+ ...selection.thinking === void 0 ? {} : { thinkingLevel: selection.thinking }
4010
3996
  };
4011
3997
  } catch (error) {
4012
3998
  if (error instanceof InstitutionalResolutionError && (error.reason === "missing-page" || error.reason === "missing-seat")) {
@@ -4031,10 +4017,10 @@ async function resolveNavigatorSeatSelection(context, modelSettingPath, defaultM
4031
4017
  selection: {
4032
4018
  provider: parsed.provider,
4033
4019
  model: parsed.model,
4034
- thinking: parsed.thinkingLevel
4020
+ ...parsed.thinkingLevel === void 0 ? {} : { thinking: parsed.thinkingLevel }
4035
4021
  },
4036
4022
  configuredLabel: configured,
4037
- thinkingLevel: parsed.thinkingLevel
4023
+ ...parsed.thinkingLevel === void 0 ? {} : { thinkingLevel: parsed.thinkingLevel }
4038
4024
  };
4039
4025
  }
4040
4026
 
@@ -4852,7 +4838,7 @@ function createNativeNavigatorSessionFactory(defaultModelSettingPath = navigator
4852
4838
  }
4853
4839
  },
4854
4840
  entries: () => sessionManager.getEntries(),
4855
- setModel: async (next, nextThinking) => {
4841
+ setModel: async (next) => {
4856
4842
  let nextParsed;
4857
4843
  try {
4858
4844
  nextParsed = parseNavigatorModelSetting(next);
@@ -4865,16 +4851,10 @@ function createNativeNavigatorSessionFactory(defaultModelSettingPath = navigator
4865
4851
  `Navigator model switch requires a new session: ${configuredLabel} \u2192 ${next}`
4866
4852
  );
4867
4853
  }
4868
- if (nextParsed.thinkingLevel !== nextThinking || thinkingLevel !== nextThinking) {
4869
- throw new NavigatorUnavailableError(
4870
- "thinking",
4871
- `Navigator thinking level ${nextThinking} is unavailable for ${next}`
4872
- );
4873
- }
4874
4854
  selection = {
4875
4855
  provider: nextParsed.provider,
4876
4856
  model: nextParsed.model,
4877
- thinking: nextParsed.thinkingLevel
4857
+ ...nextParsed.thinkingLevel === void 0 ? {} : { thinking: nextParsed.thinkingLevel }
4878
4858
  };
4879
4859
  thinkingLevel = nextParsed.thinkingLevel;
4880
4860
  configuredLabel = next;
@@ -6195,9 +6175,6 @@ ${text}
6195
6175
  try {
6196
6176
  await created.setModel?.(modelSetting, model.thinkingLevel);
6197
6177
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
6198
- if (created.getThinkingLevel?.() !== void 0 && created.getThinkingLevel() !== model.thinkingLevel) {
6199
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
6200
- }
6201
6178
  created.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
6202
6179
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
6203
6180
  session = created;
@@ -6212,9 +6189,6 @@ ${text}
6212
6189
  } else {
6213
6190
  try {
6214
6191
  await session.setModel?.(modelSetting, model.thinkingLevel);
6215
- if (session.getThinkingLevel?.() !== void 0 && session.getThinkingLevel() !== model.thinkingLevel) {
6216
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
6217
- }
6218
6192
  } catch (error) {
6219
6193
  throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("session", error);
6220
6194
  }
@@ -16,12 +16,7 @@ function validateRecordedInspectorOutput(value) {
16
16
  throw new Error("Inspector output has no execution discriminator");
17
17
  }
18
18
  function inspectorDecisiveFacts(output) {
19
- const facts = { status: output.status };
20
- const findings = output.findings;
21
- if (findings !== void 0) facts.findings = findings;
22
- const reason = output.reason;
23
- if (reason !== void 0) facts.reason = reason;
24
- return facts;
19
+ return { ...output };
25
20
  }
26
21
  export {
27
22
  INSPECTOR_ACCEPTED_TEXT,
@@ -396,9 +396,6 @@ ${text}
396
396
  try {
397
397
  await created.setModel?.(modelSetting, model.thinkingLevel);
398
398
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
399
- if (created.getThinkingLevel?.() !== void 0 && created.getThinkingLevel() !== model.thinkingLevel) {
400
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
401
- }
402
399
  created.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
403
400
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
404
401
  session = created;
@@ -413,9 +410,6 @@ ${text}
413
410
  } else {
414
411
  try {
415
412
  await session.setModel?.(modelSetting, model.thinkingLevel);
416
- if (session.getThinkingLevel?.() !== void 0 && session.getThinkingLevel() !== model.thinkingLevel) {
417
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
418
- }
419
413
  } catch (error) {
420
414
  throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("session", error);
421
415
  }
@@ -151,33 +151,29 @@ async function writeNavigatorModelSetting(model, path = navigatorModelSettingPat
151
151
  function parseNavigatorModelSetting(value) {
152
152
  const slash = value.indexOf("/");
153
153
  if (slash <= 0 || slash === value.length - 1) {
154
- throw new Error("Navigator model setting must be provider/model[:max]");
154
+ throw new Error("Navigator model setting must be provider/model[:thinking]");
155
155
  }
156
156
  const provider = value.slice(0, slash);
157
157
  const modelWithThinking = value.slice(slash + 1);
158
158
  const colon = modelWithThinking.lastIndexOf(":");
159
159
  const suffix = colon < 0 ? void 0 : modelWithThinking.slice(colon + 1);
160
- if (suffix !== void 0 && suffix !== "max") {
161
- throw new Error("Navigator model setting must use :max or omit the thinking suffix");
162
- }
163
160
  const model = colon < 0 ? modelWithThinking : modelWithThinking.slice(0, colon);
164
161
  if (model === "") throw new Error("Navigator model setting must include a model");
165
- return { provider, model, thinkingLevel: suffix === "max" ? "max" : "off" };
162
+ return suffix === void 0 ? { provider, model } : { provider, model, thinkingLevel: suffix };
166
163
  }
167
164
  async function resolveNavigatorSeatSelection(context, modelSettingPath, defaultModelSettingPath) {
168
165
  const runDirectory = auditorRunDirectory(context);
169
166
  if (runDirectory !== void 0) {
170
167
  try {
171
168
  const selection = await readInstitutionalSeatSelection(runDirectory, "navigator");
172
- const thinkingLevel = selection.thinking === "max" ? "max" : "off";
173
169
  return {
174
170
  selection: {
175
171
  provider: selection.provider,
176
172
  model: selection.model,
177
173
  ...selection.thinking === void 0 ? {} : { thinking: selection.thinking }
178
174
  },
179
- configuredLabel: `${selection.provider}/${selection.model}${thinkingLevel === "max" ? ":max" : ""}`,
180
- thinkingLevel
175
+ configuredLabel: selection.thinking === void 0 ? `${selection.provider}/${selection.model}` : `${selection.provider}/${selection.model}:${selection.thinking}`,
176
+ ...selection.thinking === void 0 ? {} : { thinkingLevel: selection.thinking }
181
177
  };
182
178
  } catch (error) {
183
179
  if (error instanceof InstitutionalResolutionError && (error.reason === "missing-page" || error.reason === "missing-seat")) {
@@ -202,10 +198,10 @@ async function resolveNavigatorSeatSelection(context, modelSettingPath, defaultM
202
198
  selection: {
203
199
  provider: parsed.provider,
204
200
  model: parsed.model,
205
- thinking: parsed.thinkingLevel
201
+ ...parsed.thinkingLevel === void 0 ? {} : { thinking: parsed.thinkingLevel }
206
202
  },
207
203
  configuredLabel: configured,
208
- thinkingLevel: parsed.thinkingLevel
204
+ ...parsed.thinkingLevel === void 0 ? {} : { thinkingLevel: parsed.thinkingLevel }
209
205
  };
210
206
  }
211
207
  export {
@@ -158,7 +158,7 @@ async function openPiInstitutionalSession(options) {
158
158
  api: fallbackApi,
159
159
  provider: selection.provider,
160
160
  baseUrl: providerDefaultModel?.baseUrl ?? "",
161
- reasoning: selection.thinking !== void 0 && selection.thinking !== "off",
161
+ reasoning: providerDefaultModel?.reasoning ?? false,
162
162
  input: ["text"],
163
163
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
164
164
  contextWindow: 128e3,
@@ -457,11 +457,10 @@ async function openPiInstitutionalSession(options) {
457
457
  });
458
458
  }
459
459
  }
460
- const requestedThinking = options.selection.thinking === "max" ? "max" : "off";
461
460
  const { session } = await createAgentSession({
462
461
  cwd: options.cwd,
463
462
  model: effectiveModel,
464
- thinkingLevel: requestedThinking,
463
+ ...options.selection.thinking === void 0 ? {} : { thinkingLevel: options.selection.thinking },
465
464
  modelRuntime: runtime,
466
465
  sessionManager,
467
466
  settingsManager: settings,
@@ -471,15 +470,6 @@ async function openPiInstitutionalSession(options) {
471
470
  ...options.toolsAllowlist === void 0 ? {} : { tools: options.toolsAllowlist },
472
471
  ...customTools.length === 0 ? {} : { customTools }
473
472
  });
474
- if (requestedThinking === "max" && session.thinkingLevel !== "max") {
475
- session.dispose();
476
- throw withTypedReason(
477
- new Error(
478
- `${label} thinking level max is unavailable for ${selection.provider}/${selection.model}`
479
- ),
480
- "thinking"
481
- );
482
- }
483
473
  const listeners = /* @__PURE__ */ new Set();
484
474
  const accumulatedUsage = emptyUsage();
485
475
  let lastEmittedAssistant;
@@ -18,15 +18,6 @@ const GATE_OFFICER_SEATS = [
18
18
  function isGateOfficerSeat(value) {
19
19
  return GATE_OFFICER_SEATS.includes(value);
20
20
  }
21
- const THINKING_LEVELS = /* @__PURE__ */ new Set([
22
- "off",
23
- "minimal",
24
- "low",
25
- "medium",
26
- "high",
27
- "xhigh",
28
- "max"
29
- ]);
30
21
  function publicCliConfigPath(home) {
31
22
  if (typeof home !== "string" || home.trim() === "") {
32
23
  throw new Error("home must be explicitly provided");
@@ -169,13 +160,7 @@ function parseModelSpec(spec, fallbackThinking) {
169
160
  let modelPart = trimmed;
170
161
  let thinking = fallbackThinking;
171
162
  if (thinkingSplit !== -1) {
172
- const maybeThinking = trimmed.slice(thinkingSplit + 1);
173
- if (!THINKING_LEVELS.has(maybeThinking)) {
174
- throw new Error(
175
- `model specification must be provider/model[:thinking], got ${spec}`
176
- );
177
- }
178
- thinking = maybeThinking;
163
+ thinking = trimmed.slice(thinkingSplit + 1);
179
164
  modelPart = trimmed.slice(0, thinkingSplit);
180
165
  }
181
166
  const slash = modelPart.indexOf("/");
@@ -286,10 +271,8 @@ function parseSeatModelConfig(value, seat) {
286
271
  if (typeof raw.model !== "string" || raw.model.trim() === "") {
287
272
  throw new Error(`config seat ${seat} requires model`);
288
273
  }
289
- if (raw.thinking !== void 0) {
290
- if (typeof raw.thinking !== "string" || !THINKING_LEVELS.has(raw.thinking)) {
291
- throw new Error(`config seat ${seat} requires a valid thinking level`);
292
- }
274
+ if (raw.thinking !== void 0 && typeof raw.thinking !== "string") {
275
+ throw new Error(`config seat ${seat} thinking must be a string`);
293
276
  }
294
277
  const parsed = {
295
278
  provider: raw.provider,
@@ -443,7 +426,6 @@ async function loadCredentialProviders(agentDir) {
443
426
  }
444
427
  export {
445
428
  GATE_OFFICER_SEATS,
446
- THINKING_LEVELS,
447
429
  buildSeatModelCliArgs,
448
430
  clearPersistentSeatConfig,
449
431
  credentialProvidersFromAuthData,
@@ -15013,12 +15013,7 @@ function validateRecordedInspectorOutput(value) {
15013
15013
  throw new Error("Inspector output has no execution discriminator");
15014
15014
  }
15015
15015
  function inspectorDecisiveFacts(output) {
15016
- const facts = { status: output.status };
15017
- const findings = output.findings;
15018
- if (findings !== void 0) facts.findings = findings;
15019
- const reason = output.reason;
15020
- if (reason !== void 0) facts.reason = reason;
15021
- return facts;
15016
+ return { ...output };
15022
15017
  }
15023
15018
  var INSPECTOR_OUTPUT_TOOL_NAME;
15024
15019
  var init_inspector_contracts = __esm({
@@ -15537,13 +15532,7 @@ function parseModelSpec(spec, fallbackThinking) {
15537
15532
  let modelPart = trimmed;
15538
15533
  let thinking = fallbackThinking;
15539
15534
  if (thinkingSplit !== -1) {
15540
- const maybeThinking = trimmed.slice(thinkingSplit + 1);
15541
- if (!THINKING_LEVELS.has(maybeThinking)) {
15542
- throw new Error(
15543
- `model specification must be provider/model[:thinking], got ${spec}`
15544
- );
15545
- }
15546
- thinking = maybeThinking;
15535
+ thinking = trimmed.slice(thinkingSplit + 1);
15547
15536
  modelPart = trimmed.slice(0, thinkingSplit);
15548
15537
  }
15549
15538
  const slash = modelPart.indexOf("/");
@@ -15644,10 +15633,8 @@ function parseSeatModelConfig(value, seat) {
15644
15633
  if (typeof raw.model !== "string" || raw.model.trim() === "") {
15645
15634
  throw new Error(`config seat ${seat} requires model`);
15646
15635
  }
15647
- if (raw.thinking !== void 0) {
15648
- if (typeof raw.thinking !== "string" || !THINKING_LEVELS.has(raw.thinking)) {
15649
- throw new Error(`config seat ${seat} requires a valid thinking level`);
15650
- }
15636
+ if (raw.thinking !== void 0 && typeof raw.thinking !== "string") {
15637
+ throw new Error(`config seat ${seat} thinking must be a string`);
15651
15638
  }
15652
15639
  const parsed = {
15653
15640
  provider: raw.provider,
@@ -15796,7 +15783,7 @@ async function loadCredentialProviders(agentDir) {
15796
15783
  throw error;
15797
15784
  }
15798
15785
  }
15799
- var GATE_OFFICER_SEATS, THINKING_LEVELS;
15786
+ var GATE_OFFICER_SEATS;
15800
15787
  var init_config2 = __esm({
15801
15788
  "src/public-cli/config.ts"() {
15802
15789
  "use strict";
@@ -15808,15 +15795,6 @@ var init_config2 = __esm({
15808
15795
  "inspector",
15809
15796
  "notary"
15810
15797
  ];
15811
- THINKING_LEVELS = /* @__PURE__ */ new Set([
15812
- "off",
15813
- "minimal",
15814
- "low",
15815
- "medium",
15816
- "high",
15817
- "xhigh",
15818
- "max"
15819
- ]);
15820
15798
  }
15821
15799
  });
15822
15800
 
@@ -18084,7 +18062,7 @@ async function loadResumableRunRecord(home, runId, authority) {
18084
18062
  model = {
18085
18063
  provider: rec.provider,
18086
18064
  model: rec.model,
18087
- ...typeof rec.thinking === "string" && THINKING_LEVELS.has(rec.thinking) ? { thinking: rec.thinking } : {}
18065
+ ...typeof rec.thinking === "string" ? { thinking: rec.thinking } : {}
18088
18066
  };
18089
18067
  }
18090
18068
  if (correlationId === void 0 || ticketNumber === void 0 || ticketResolution === void 0) {
@@ -18449,7 +18427,6 @@ var init_run_lifecycle = __esm({
18449
18427
  init_typed_provider_http();
18450
18428
  init_collector_config();
18451
18429
  init_engine_material();
18452
- init_config2();
18453
18430
  init_invocation();
18454
18431
  V1_RESUMABLE_PROVIDERS = ["openai-codex", "xai"];
18455
18432
  AUTO_RESUME_LIMIT = 2;
@@ -18891,8 +18868,8 @@ var init_option_definitions = __esm({
18891
18868
  repeatable: false,
18892
18869
  form: "option",
18893
18870
  description: {
18894
- en: "Override thinking level: off|minimal|low|medium|high|xhigh|max.",
18895
- zh: "\u8986\u76D6 thinking \u6863\u4F4D\uFF1Aoff|minimal|low|medium|high|xhigh|max\u3002"
18871
+ en: "Override thinking level (opaque pass-through to Pi; e.g. off|minimal|low|medium|high|xhigh|max).",
18872
+ zh: "\u8986\u76D6 thinking \u6863\u4F4D\uFF08\u539F\u6837\u900F\u4F20\u7ED9 Pi\uFF1B\u4F8B\u5982 off|minimal|low|medium|high|xhigh|max\uFF09\u3002"
18896
18873
  }
18897
18874
  },
18898
18875
  {
@@ -19643,7 +19620,7 @@ async function recordEffectiveInvocationModel(runDirectory, model, engine, host)
19643
19620
  const effectiveModel = typeof next.provider === "string" && typeof next.model === "string" ? {
19644
19621
  provider: next.provider,
19645
19622
  model: next.model,
19646
- ...typeof next.thinking === "string" && THINKING_LEVELS.has(next.thinking) ? { thinking: next.thinking } : {}
19623
+ ...typeof next.thinking === "string" ? { thinking: next.thinking } : {}
19647
19624
  } : void 0;
19648
19625
  const home = homeFromRunDirectory(runDirectory);
19649
19626
  const config = await loadPublicCliConfig(home);
@@ -33049,9 +33026,6 @@ function resolveAgentDir(env, home) {
33049
33026
  return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join35(home, ".pi", "agent");
33050
33027
  }
33051
33028
  function parseThinking(value) {
33052
- if (!THINKING_LEVELS2.has(value)) {
33053
- throw new CliUsageError(`unknown thinking level: ${value}`);
33054
- }
33055
33029
  return value;
33056
33030
  }
33057
33031
  function parseArgv(argv) {
@@ -33884,7 +33858,7 @@ async function runAkRole(argv, env) {
33884
33858
  return { exitCode: 1 };
33885
33859
  }
33886
33860
  }
33887
- var RESUME_SEAT_DISPATCH, PUBLIC_ROLE_ARGV, PUBLIC_GLOBAL_OPTIONS, HostSelectionError, THINKING_LEVELS2;
33861
+ var RESUME_SEAT_DISPATCH, PUBLIC_ROLE_ARGV, PUBLIC_GLOBAL_OPTIONS, HostSelectionError;
33888
33862
  var init_cli = __esm({
33889
33863
  "src/public-cli/cli.ts"() {
33890
33864
  "use strict";
@@ -33957,15 +33931,6 @@ var init_cli = __esm({
33957
33931
  }
33958
33932
  failure;
33959
33933
  };
33960
- THINKING_LEVELS2 = /* @__PURE__ */ new Set([
33961
- "off",
33962
- "minimal",
33963
- "low",
33964
- "medium",
33965
- "high",
33966
- "xhigh",
33967
- "max"
33968
- ]);
33969
33934
  }
33970
33935
  });
33971
33936
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.3439",
3
+ "version": "0.1.3448",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -975,7 +975,7 @@ export function createNativeNavigatorSessionFactory(
975
975
  return async ({ context, subject, modelSettingPath, tool }) => {
976
976
  const resolved = await resolveNavigatorSeatSelection(context, modelSettingPath, defaultModelSettingPath);
977
977
  let selection = resolved.selection;
978
- let thinkingLevel = resolved.thinkingLevel;
978
+ let thinkingLevel: string | undefined = resolved.thinkingLevel;
979
979
  let configuredLabel = resolved.configuredLabel;
980
980
 
981
981
  const { createRecordSession } = await import("./archivist-record-entry.ts");
@@ -1117,7 +1117,7 @@ export function createNativeNavigatorSessionFactory(
1117
1117
  }
1118
1118
  },
1119
1119
  entries: () => sessionManager.getEntries(),
1120
- setModel: async (next, nextThinking) => {
1120
+ setModel: async (next) => {
1121
1121
  let nextParsed: ReturnType<typeof parseNavigatorModelSetting>;
1122
1122
  try {
1123
1123
  nextParsed = parseNavigatorModelSetting(next);
@@ -1133,16 +1133,11 @@ export function createNativeNavigatorSessionFactory(
1133
1133
  `Navigator model switch requires a new session: ${configuredLabel} → ${next}`,
1134
1134
  );
1135
1135
  }
1136
- if (nextParsed.thinkingLevel !== nextThinking || thinkingLevel !== nextThinking) {
1137
- throw new NavigatorUnavailableError(
1138
- "thinking",
1139
- `Navigator thinking level ${nextThinking} is unavailable for ${next}`,
1140
- );
1141
- }
1136
+ // Thinking is opaque pass-through; no stick/availability re-check.
1142
1137
  selection = {
1143
1138
  provider: nextParsed.provider,
1144
1139
  model: nextParsed.model,
1145
- thinking: nextParsed.thinkingLevel,
1140
+ ...(nextParsed.thinkingLevel === undefined ? {} : { thinking: nextParsed.thinkingLevel }),
1146
1141
  };
1147
1142
  thinkingLevel = nextParsed.thinkingLevel;
1148
1143
  configuredLabel = next;
@@ -28,12 +28,11 @@ export function validateRecordedInspectorOutput(value: unknown): InspectorOutput
28
28
  throw new Error("Inspector output has no execution discriminator");
29
29
  }
30
30
 
31
- /** Machine-facing facts from an accepted 察院 release. Findings retained as submitted. */
31
+ /**
32
+ * Machine-facing facts from an accepted 察院 release.
33
+ * Lawful free content is retained as submitted (ADR 0025 / 0055) — no field whitelist.
34
+ * status remains the sole execution discriminator; free fields never derive status.
35
+ */
32
36
  export function inspectorDecisiveFacts(output: InspectorOutput): Record<string, unknown> {
33
- const facts: Record<string, unknown> = { status: output.status };
34
- const findings = (output as { findings?: unknown }).findings;
35
- if (findings !== undefined) facts.findings = findings;
36
- const reason = (output as { reason?: unknown }).reason;
37
- if (reason !== undefined) facts.reason = reason;
38
- return facts;
37
+ return { ...(output as Readonly<Record<string, unknown>>) };
39
38
  }
@@ -648,9 +648,6 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
648
648
  try {
649
649
  await created.setModel?.(modelSetting, model.thinkingLevel);
650
650
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
651
- if (created.getThinkingLevel?.() !== undefined && created.getThinkingLevel() !== model.thinkingLevel) {
652
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
653
- }
654
651
  created.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
655
652
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
656
653
  session = created;
@@ -665,9 +662,6 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
665
662
  } else {
666
663
  try {
667
664
  await session.setModel?.(modelSetting, model.thinkingLevel);
668
- if (session.getThinkingLevel?.() !== undefined && session.getThinkingLevel() !== model.thinkingLevel) {
669
- throw new NavigatorUnavailableError("thinking", `Navigator thinking level ${model.thinkingLevel} is unavailable for ${modelSetting}`);
670
- }
671
665
  } catch (error) {
672
666
  // Contract: README.md#Navigator-attendance — resumed-session configuration failures remain typed unavailable and retain the original cause.
673
667
  throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("session", error);
@@ -162,8 +162,8 @@ export type NavigatorPreparationSession = {
162
162
  appendEntry(customType: string, data: unknown): void;
163
163
  entries(): readonly unknown[];
164
164
  providerFailure?(): NavigatorProviderFailureFact | undefined;
165
- setModel?(model: string, thinkingLevel: "off" | "max"): Promise<void>;
166
- getThinkingLevel?(): string;
165
+ setModel?(model: string, thinkingLevel?: string): Promise<void>;
166
+ getThinkingLevel?(): string | undefined;
167
167
  recordPointer(): string;
168
168
  dispose(): void | Promise<void>;
169
169
  };
@@ -204,22 +204,22 @@ export async function writeNavigatorModelSetting(model: string, path = navigator
204
204
  export function parseNavigatorModelSetting(value: string): {
205
205
  provider: string;
206
206
  model: string;
207
- thinkingLevel: "off" | "max";
207
+ thinkingLevel?: string;
208
208
  } {
209
209
  const slash = value.indexOf("/");
210
210
  if (slash <= 0 || slash === value.length - 1) {
211
- throw new Error("Navigator model setting must be provider/model[:max]");
211
+ throw new Error("Navigator model setting must be provider/model[:thinking]");
212
212
  }
213
213
  const provider = value.slice(0, slash);
214
214
  const modelWithThinking = value.slice(slash + 1);
215
215
  const colon = modelWithThinking.lastIndexOf(":");
216
216
  const suffix = colon < 0 ? undefined : modelWithThinking.slice(colon + 1);
217
- if (suffix !== undefined && suffix !== "max") {
218
- throw new Error("Navigator model setting must use :max or omit the thinking suffix");
219
- }
220
217
  const model = colon < 0 ? modelWithThinking : modelWithThinking.slice(0, colon);
221
218
  if (model === "") throw new Error("Navigator model setting must include a model");
222
- return { provider, model, thinkingLevel: suffix === "max" ? "max" : "off" };
219
+ // Suffix is opaque pass-through; bare provider/model omits thinkingLevel (Pi default).
220
+ return suffix === undefined
221
+ ? { provider, model }
222
+ : { provider, model, thinkingLevel: suffix };
223
223
  }
224
224
 
225
225
  /**
@@ -230,20 +230,21 @@ export async function resolveNavigatorSeatSelection(
230
230
  context: HostContext,
231
231
  modelSettingPath: string | undefined,
232
232
  defaultModelSettingPath: string,
233
- ): Promise<{ selection: HostInstitutionalModelSelection; configuredLabel: string; thinkingLevel: "off" | "max" }> {
233
+ ): Promise<{ selection: HostInstitutionalModelSelection; configuredLabel: string; thinkingLevel?: string }> {
234
234
  const runDirectory = auditorRunDirectory(context);
235
235
  if (runDirectory !== undefined) {
236
236
  try {
237
237
  const selection = await readInstitutionalSeatSelection(runDirectory, "navigator");
238
- const thinkingLevel = selection.thinking === "max" ? "max" : "off";
239
238
  return {
240
239
  selection: {
241
240
  provider: selection.provider,
242
241
  model: selection.model,
243
242
  ...(selection.thinking === undefined ? {} : { thinking: selection.thinking }),
244
243
  },
245
- configuredLabel: `${selection.provider}/${selection.model}${thinkingLevel === "max" ? ":max" : ""}`,
246
- thinkingLevel,
244
+ configuredLabel: selection.thinking === undefined
245
+ ? `${selection.provider}/${selection.model}`
246
+ : `${selection.provider}/${selection.model}:${selection.thinking}`,
247
+ ...(selection.thinking === undefined ? {} : { thinkingLevel: selection.thinking }),
247
248
  };
248
249
  } catch (error) {
249
250
  if (
@@ -274,9 +275,9 @@ export async function resolveNavigatorSeatSelection(
274
275
  selection: {
275
276
  provider: parsed.provider,
276
277
  model: parsed.model,
277
- thinking: parsed.thinkingLevel,
278
+ ...(parsed.thinkingLevel === undefined ? {} : { thinking: parsed.thinkingLevel }),
278
279
  },
279
280
  configuredLabel: configured,
280
- thinkingLevel: parsed.thinkingLevel,
281
+ ...(parsed.thinkingLevel === undefined ? {} : { thinkingLevel: parsed.thinkingLevel }),
281
282
  };
282
283
  }
@@ -237,7 +237,7 @@ export async function openPiInstitutionalSession(
237
237
  ? childRegistry.find(selection.provider, selection.model)
238
238
  : undefined;
239
239
 
240
- const withTypedReason = (error: Error, reason: "auth" | "model" | "thinking"): Error =>
240
+ const withTypedReason = (error: Error, reason: "auth" | "model"): Error =>
241
241
  Object.assign(error, { reason });
242
242
 
243
243
  // Existing Navigator/model contract (pre-#590): unknown provider or model is
@@ -254,13 +254,15 @@ export async function openPiInstitutionalSession(
254
254
  const fallbackApi = providerDefaultModel?.api
255
255
  ?? (childProvider as any)?.api
256
256
  ?? (selection.provider === "openai-codex" ? "openai-codex-responses" : "openai-completions");
257
+ // Fallback model facts come from the provider surface only — never derive
258
+ // reasoning (or any capability) from the thinking string (#683 pass-through).
257
259
  const modelToUse = foundModel ?? {
258
260
  id: selection.model,
259
261
  name: selection.model,
260
262
  api: fallbackApi as any,
261
263
  provider: selection.provider,
262
264
  baseUrl: providerDefaultModel?.baseUrl ?? "",
263
- reasoning: selection.thinking !== undefined && selection.thinking !== "off",
265
+ reasoning: providerDefaultModel?.reasoning ?? false,
264
266
  input: ["text"],
265
267
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
266
268
  contextWindow: 128000,
@@ -631,15 +633,15 @@ export async function openPiInstitutionalSession(
631
633
  }
632
634
  }
633
635
 
634
- // 7. Create AgentSession
635
- // Existing Navigator contract: requested thinking must stick after open. Pi
636
- // clamps unsupported levels; if max was requested and not applied, fail as
637
- // typed unavailable/thinking (pre-#590 attendance setModel check).
638
- const requestedThinking = options.selection.thinking === "max" ? "max" : "off";
636
+ // 7. Create AgentSession — thinking is opaque pass-through. Absent selection
637
+ // omits thinkingLevel (Pi default). Pi clamps unsupported levels itself;
638
+ // we do not re-check or invent defaults.
639
639
  const { session } = await createAgentSession({
640
640
  cwd: options.cwd,
641
641
  model: effectiveModel,
642
- thinkingLevel: requestedThinking as any,
642
+ ...(options.selection.thinking === undefined
643
+ ? {}
644
+ : { thinkingLevel: options.selection.thinking as any }),
643
645
  modelRuntime: runtime,
644
646
  sessionManager,
645
647
  settingsManager: settings,
@@ -649,15 +651,6 @@ export async function openPiInstitutionalSession(
649
651
  ...(options.toolsAllowlist === undefined ? {} : { tools: options.toolsAllowlist as string[] }),
650
652
  ...(customTools.length === 0 ? {} : { customTools }),
651
653
  });
652
- if (requestedThinking === "max" && session.thinkingLevel !== "max") {
653
- session.dispose();
654
- throw withTypedReason(
655
- new Error(
656
- `${label} thinking level max is unavailable for ${selection.provider}/${selection.model}`,
657
- ),
658
- "thinking",
659
- );
660
- }
661
654
 
662
655
  // 8. Event subscriptions
663
656
  const listeners = new Set<(event: HostInstitutionalSessionEvent) => void>();
@@ -461,16 +461,6 @@ function cliResultFromRoleRun(result: {
461
461
  };
462
462
  }
463
463
 
464
- const THINKING_LEVELS = new Set([
465
- "off",
466
- "minimal",
467
- "low",
468
- "medium",
469
- "high",
470
- "xhigh",
471
- "max",
472
- ]);
473
-
474
464
  function defaultIo(): CliIo {
475
465
  return {
476
466
  stdout: (text) => {
@@ -505,10 +495,8 @@ type ParsedGlobal = {
505
495
  };
506
496
 
507
497
  function parseThinking(value: string): PublicThinkingLevel {
508
- if (!THINKING_LEVELS.has(value)) {
509
- throw new CliUsageError(`unknown thinking level: ${value}`);
510
- }
511
- return value as PublicThinkingLevel;
498
+ // #683: opaque pass-through — no local whitelist.
499
+ return value;
512
500
  }
513
501
 
514
502
  function parseArgv(argv: readonly string[]): ParsedGlobal {
@@ -102,16 +102,6 @@ export type InvocationModelOverride = {
102
102
  host?: string;
103
103
  };
104
104
 
105
- export const THINKING_LEVELS = new Set<PublicThinkingLevel>([
106
- "off",
107
- "minimal",
108
- "low",
109
- "medium",
110
- "high",
111
- "xhigh",
112
- "max",
113
- ]);
114
-
115
105
  export function publicCliConfigPath(home: string): string {
116
106
  if (typeof home !== "string" || home.trim() === "") {
117
107
  throw new Error("home must be explicitly provided");
@@ -336,17 +326,10 @@ export function parseModelSpec(
336
326
  const thinkingSplit = trimmed.lastIndexOf(":");
337
327
  let modelPart = trimmed;
338
328
  let thinking: PublicThinkingLevel | undefined = fallbackThinking;
339
- // #346: no colon → bare provider/model is legal. Colon present (any index,
340
- // including 0) → suffix must be a typed PublicThinkingLevel (empty/unknown
341
- // stay format rejects; never swallow ":…" into the model name).
329
+ // #346/#683: no colon → bare provider/model is legal. Colon present → suffix
330
+ // is opaque thinking pass-through (no local whitelist); never swallow into model.
342
331
  if (thinkingSplit !== -1) {
343
- const maybeThinking = trimmed.slice(thinkingSplit + 1);
344
- if (!THINKING_LEVELS.has(maybeThinking as PublicThinkingLevel)) {
345
- throw new Error(
346
- `model specification must be provider/model[:thinking], got ${spec}`,
347
- );
348
- }
349
- thinking = maybeThinking as PublicThinkingLevel;
332
+ thinking = trimmed.slice(thinkingSplit + 1);
350
333
  modelPart = trimmed.slice(0, thinkingSplit);
351
334
  }
352
335
  const slash = modelPart.indexOf("/");
@@ -507,14 +490,9 @@ function parseSeatModelConfig(value: unknown, seat: string): PersistentSeatConfi
507
490
  if (typeof raw.model !== "string" || raw.model.trim() === "") {
508
491
  throw new Error(`config seat ${seat} requires model`);
509
492
  }
510
- // #384: thinking is optional on persistent seats; when present it must be typed.
511
- if (raw.thinking !== undefined) {
512
- if (
513
- typeof raw.thinking !== "string" ||
514
- !THINKING_LEVELS.has(raw.thinking as PublicThinkingLevel)
515
- ) {
516
- throw new Error(`config seat ${seat} requires a valid thinking level`);
517
- }
493
+ // #384/#683: thinking is optional opaque pass-through; when present must be a string.
494
+ if (raw.thinking !== undefined && typeof raw.thinking !== "string") {
495
+ throw new Error(`config seat ${seat} thinking must be a string`);
518
496
  }
519
497
  const parsed: PersistentSeatConfig = {
520
498
  provider: raw.provider as string,
@@ -73,7 +73,7 @@ import {
73
73
  type OptionOwner,
74
74
  type PublicOptionDefinition,
75
75
  } from "./option-definitions.ts";
76
- import { loadPublicCliConfig, THINKING_LEVELS } from "./config.ts";
76
+ import { loadPublicCliConfig } from "./config.ts";
77
77
  import type { PublicThinkingLevel } from "./registry.ts";
78
78
  import {
79
79
  resolveInstitutionalSeatSelections,
@@ -311,7 +311,7 @@ async function writeAdmittedRequestPersistence(
311
311
  /**
312
312
  * Effective provider/model selection recorded on the invocation identity page.
313
313
  * thinking is present only when the caller/seat supplied it — bare model omits it.
314
- * Restored values are bounded to typed PublicThinkingLevel (never arbitrary string).
314
+ * Thinking is opaque pass-through (#683); no local whitelist filter on restore.
315
315
  */
316
316
  export type InvocationEffectiveModel = {
317
317
  readonly provider: string;
@@ -417,9 +417,8 @@ export async function recordEffectiveInvocationModel(
417
417
  ? {
418
418
  provider: next.provider,
419
419
  model: next.model,
420
- ...(typeof next.thinking === "string" &&
421
- THINKING_LEVELS.has(next.thinking as PublicThinkingLevel)
422
- ? { thinking: next.thinking as PublicThinkingLevel }
420
+ ...(typeof next.thinking === "string"
421
+ ? { thinking: next.thinking }
423
422
  : {}),
424
423
  }
425
424
  : undefined;
@@ -288,8 +288,8 @@ const GLOBAL_OPTIONS = [
288
288
  repeatable: false,
289
289
  form: "option",
290
290
  description: {
291
- en: "Override thinking level: off|minimal|low|medium|high|xhigh|max.",
292
- zh: "覆盖 thinking 档位:off|minimal|low|medium|high|xhigh|max。",
291
+ en: "Override thinking level (opaque pass-through to Pi; e.g. off|minimal|low|medium|high|xhigh|max).",
292
+ zh: "覆盖 thinking 档位(原样透传给 Pi;例如 off|minimal|low|medium|high|xhigh|max)。",
293
293
  },
294
294
  },
295
295
  {
@@ -31,14 +31,8 @@ export const PUBLIC_CLI_SUPPORT_COMMANDS = [
31
31
 
32
32
  export type PublicCliSupportCommand = (typeof PUBLIC_CLI_SUPPORT_COMMANDS)[number];
33
33
 
34
- export type PublicThinkingLevel =
35
- | "off"
36
- | "minimal"
37
- | "low"
38
- | "medium"
39
- | "high"
40
- | "xhigh"
41
- | "max";
34
+ /** Opaque thinking level string — pass-through to Pi; no local whitelist (#683). */
35
+ export type PublicThinkingLevel = string;
42
36
 
43
37
  export type ModelRef = {
44
38
  provider: string;
@@ -36,7 +36,6 @@ import {
36
36
  engineSessionMaterialFromOptions,
37
37
  type EngineSessionMaterial,
38
38
  } from "../package-resources/engine-material.ts";
39
- import { THINKING_LEVELS } from "./config.ts";
40
39
  import type { PublicThinkingLevel } from "./registry.ts";
41
40
  import {
42
41
  recordEffectiveInvocationModel,
@@ -1136,8 +1135,7 @@ async function loadResumableRunRecord(
1136
1135
  model = {
1137
1136
  provider: rec.provider,
1138
1137
  model: rec.model,
1139
- ...(typeof rec.thinking === "string" &&
1140
- THINKING_LEVELS.has(rec.thinking as PublicThinkingLevel)
1138
+ ...(typeof rec.thinking === "string"
1141
1139
  ? { thinking: rec.thinking as PublicThinkingLevel }
1142
1140
  : {}),
1143
1141
  };