@arhen/pi-core-subagent 1.3.55 → 1.3.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/manager.ts +31 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arhen/pi-core-subagent",
3
- "version": "1.3.55",
3
+ "version": "1.3.57",
4
4
  "type": "module",
5
5
  "description": "pi extension: fast in-process subagents with a dependency-graph scheduler (needs edges gate tasks and carry upstream output into dependent prompts), plus background runs, intercom and agent-to-agent mailbox. Leader defines agents inline.",
6
6
  "license": "MIT",
package/src/manager.ts CHANGED
@@ -157,16 +157,38 @@ export function resolveChildModel(ctx: ExtensionContext, explicit: string | unde
157
157
  throw new Error(`Model not found: ${ref}`);
158
158
  }
159
159
 
160
+ const PROBE_THINKING_LEVELS: ThinkingLevel[] = ["low", "minimal", "medium", "high", "xhigh", "max"];
161
+
162
+ /**
163
+ * Thinking level for the usability probe: the one the task asked for, else the cheapest
164
+ * the model accepts. Providers that require adaptive thinking reject a probe without one
165
+ * (9router claude models answer `thinking.type.disabled is not supported`), which used to
166
+ * make every preflight fail and fall back to the session model.
167
+ */
168
+ function probeThinking(model: Model<Api>, thinking?: string): ThinkingLevel | undefined {
169
+ if (thinking && thinking !== "off") return thinking as ThinkingLevel;
170
+ if (!model.reasoning) return undefined;
171
+ const map = model.thinkingLevelMap;
172
+ if (!map) return "low";
173
+ for (const level of PROBE_THINKING_LEVELS) {
174
+ const mapped = map[level as keyof typeof map];
175
+ if (mapped !== null && mapped !== undefined) return level;
176
+ }
177
+ return undefined;
178
+ }
179
+
160
180
  async function probeModel(
161
181
  ctx: ExtensionContext,
162
182
  model: Model<Api>,
163
183
  signal: AbortSignal | undefined,
184
+ thinking?: string,
164
185
  ): Promise<string | undefined> {
165
186
  try {
187
+ const reasoningEffort = probeThinking(model, thinking);
166
188
  const reply = await ctx.modelRegistry.complete(
167
189
  model,
168
190
  { messages: [{ role: "user", content: "ping", timestamp: Date.now() }] },
169
- { maxTokens: 16, signal },
191
+ { maxTokens: 16, signal, ...(reasoningEffort ? { reasoningEffort } : {}) },
170
192
  );
171
193
  return reply.stopReason === "error" ? (reply.errorMessage ?? "provider returned an error") : undefined;
172
194
  } catch (err) {
@@ -178,12 +200,18 @@ export async function ensureUsableModel(
178
200
  ctx: ExtensionContext,
179
201
  model: Model<Api> | undefined,
180
202
  signal: AbortSignal | undefined,
203
+ thinking?: string,
181
204
  ): Promise<{ model: Model<Api> | undefined; note?: string }> {
182
205
  const session = ctx.model;
183
206
  if (!model || !ctx.modelRegistry) return { model };
184
207
  if (session && model.provider === session.provider && model.id === session.id) return { model };
185
- const error = await probeModel(ctx, model, signal);
208
+ const error = await probeModel(ctx, model, signal, thinking);
186
209
  if (!error) return { model };
210
+ if (model.provider === "opencode-go" && /MissingSessionID|x-opencode-session/i.test(error)) {
211
+ // ponytail: opencode-go rejects stateless probes but accepts AgentSession requests, which add the session header.
212
+ // Upgrade path: remove this exception when modelRegistry.complete can carry AgentSession request transforms.
213
+ return { model, note: `preflight unavailable (${error}); child session will validate the model` };
214
+ }
187
215
  if (!session) throw new Error(`Model ${model.provider}/${model.id} is unusable: ${error}`);
188
216
  return {
189
217
  model: session,
@@ -742,7 +770,7 @@ export class SubagentManager {
742
770
  model = resolveChildModel(ctx, file?.model ?? input.model);
743
771
  validateThinking(model, thinking);
744
772
 
745
- const checked = await ensureUsableModel(ctx, model, signal);
773
+ const checked = await ensureUsableModel(ctx, model, signal, thinking);
746
774
  model = checked.model;
747
775
  if (checked.note) {
748
776
  task.modelNote = checked.note;