@arhen/pi-core-subagent 1.1.9 → 1.1.11

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/index.ts +43 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arhen/pi-core-subagent",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
4
4
  "type": "module",
5
5
  "description": "pi extension: fast in-process subagents with single/parallel/chain, background runs, intercom and agent-to-agent mailbox. Leader defines agents inline.",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -12,12 +12,13 @@
12
12
  */
13
13
 
14
14
  import type { AgentSessionEvent, ExtensionAPI, ExtensionContext, Theme, ToolDefinition } from "@earendil-works/pi-coding-agent";
15
- import { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } from "@earendil-works/pi-coding-agent";
15
+ import { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
16
16
  import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
17
17
  import { StringEnum, type Api, type AssistantMessage, type Model } from "@earendil-works/pi-ai";
18
18
  import { Text, truncateToWidth } from "@earendil-works/pi-tui";
19
19
  import type { Component, TUI } from "@earendil-works/pi-tui";
20
20
  import { Type } from "typebox";
21
+ import { join } from "node:path";
21
22
  import { CHILD_TALK_TOOLS, createChildTools, createWatchdog, type ChildHandlers } from "./child.ts";
22
23
  import { createMailbox, type Mailbox } from "./mailbox.ts";
23
24
 
@@ -341,20 +342,40 @@ function cloneRun(run: RunSnapshot): RunSnapshot {
341
342
  * Order: explicit "provider/model-id" or bare id (searched across available
342
343
  * models) → agent file model → parent's current model (ctx.model) → undefined
343
344
  * (createAgentSession falls back to settings). */
344
- function resolveChildModel(ctx: ExtensionContext, explicit: string | undefined) {
345
- if (explicit?.trim()) {
346
- const ref = explicit.trim();
347
- const slash = ref.indexOf("/");
348
- if (slash > 0 && slash < ref.length - 1) {
349
- const model = ctx.modelRegistry.find(ref.slice(0, slash), ref.slice(slash + 1));
350
- if (!model) throw new Error(`Model not found: ${ref}`);
351
- return model;
345
+ export function resolveChildModel(ctx: ExtensionContext, explicit: string | undefined) {
346
+ if (!explicit?.trim()) return ctx.model; // inherit the parent's active model
347
+ const ref = explicit.trim();
348
+ const available = ctx.modelRegistry.getAvailable();
349
+ // Model ids can contain slashes (e.g. 9router/cc/claude-opus-5), so a bare id
350
+ // match and every provider/id split point must be tried, not just the first.
351
+ const byId = available.find((m) => m.id === ref);
352
+ if (byId) return byId;
353
+ for (let slash = ref.indexOf("/"); slash > 0; slash = ref.indexOf("/", slash + 1)) {
354
+ const model = ctx.modelRegistry.find(ref.slice(0, slash), ref.slice(slash + 1));
355
+ if (model) return model;
356
+ }
357
+ throw new Error(`Model not found: ${ref}`);
358
+ }
359
+
360
+ /** Extension-registered providers (e.g. 9router) live only in the parent's
361
+ * in-memory runtime. A child builds its runtime from disk and would lose them,
362
+ * so replay the parent's registrations before the child resolves auth. */
363
+ async function createChildModelRuntime(ctx: ExtensionContext) {
364
+ const ids = ctx.modelRegistry.getRegisteredProviderIds?.() ?? [];
365
+ if (ids.length === 0) return undefined; // no extension providers: disk runtime is enough
366
+ const agentDir = getAgentDir();
367
+ const runtime = await ModelRuntime.create({ authPath: join(agentDir, "auth.json"), modelsPath: join(agentDir, "models.json") });
368
+ for (const id of ids) {
369
+ const native = ctx.modelRegistry.getRegisteredNativeProvider?.(id);
370
+ if (native) {
371
+ runtime.registerNativeProvider(native);
372
+ continue;
352
373
  }
353
- const byId = ctx.modelRegistry.getAvailable().find((m) => m.id === ref);
354
- if (!byId) throw new Error(`Model not found: ${ref}`);
355
- return byId;
374
+ const config = ctx.modelRegistry.getRegisteredProviderConfig?.(id);
375
+ if (config) runtime.registerProvider(id, config);
356
376
  }
357
- return ctx.model; // inherit the parent's active model
377
+ await runtime.refresh({ allowNetwork: false });
378
+ return runtime;
358
379
  }
359
380
 
360
381
  /** Validate a thinking level against the RESOLVED model's registry entry.
@@ -731,6 +752,7 @@ class SubagentManager {
731
752
  const created = await createAgentSession({
732
753
  cwd: task.cwd,
733
754
  agentDir: getAgentDir(),
755
+ modelRuntime: await createChildModelRuntime(ctx),
734
756
  resourceLoader: loader,
735
757
  sessionManager: SessionManager.create(task.cwd, undefined, { parentSession: getParentSessionFile(ctx) }),
736
758
  model,
@@ -1196,7 +1218,14 @@ export default function (pi: ExtensionAPI) {
1196
1218
  return { content: [{ type: "text", text: makeSummary(details.run) }], details };
1197
1219
  },
1198
1220
  renderCall(args, theme) {
1199
- const mode = args.chain?.length ? `chain ${args.chain.length}` : args.tasks?.length ? `parallel ${args.tasks.length}` : `single ${args.agent ?? "?"}`;
1221
+ // ponytail: args stream in partially, so mode is unknowable until JSON closes. Show "preparing…" instead of a wrong "single ?".
1222
+ const mode = args.chain?.length
1223
+ ? `chain ${args.chain.length}`
1224
+ : args.tasks?.length
1225
+ ? `parallel ${args.tasks.length}`
1226
+ : args.agent
1227
+ ? `single ${args.agent}`
1228
+ : "preparing…";
1200
1229
  const flags = [args.background ? "bg" : "", args.allowIntercom ? "talk" : ""].filter(Boolean).join(" ");
1201
1230
  // Params used, dimmed: model, thinking, toolset, per-task write count.
1202
1231
  const tasks = args.tasks ?? args.chain ?? [];