// Worker-side contracts of the subagents plugin: the session's subagent registry (a Durable document other worker // plugins read: one-shot agents, search, PowerShell), the tool choices subagents and one-shot agents resolve alike // from their caller's tools, and giving a subagent its own location (a granted `location_move`). import type { ModelThinkingLevel } from "@earendil-works/pi-ai"; import { clampThinkingLevel, type Models } from "@earendil-works/pi-ai/models"; import { type Agent, type ConversationId, configure, defineDoc, type EntryId, type ModelRef, ROOT_CONVERSATION_ID, type TaskId, type ToolExecutionApi, type ToolRegistration, type Tx, } from "@earendil-works/pi-durable"; import type { Context, Location } from "@p2/app/v1"; import type { P2Tool } from "@p2/app/v1/worker"; export const THINKING = ["off", "minimal", "low", "medium", "high", "xhigh", "max"]; export const TEAM_TOOL = "team"; export type Subagent = { conversationId: ConversationId; model: string; thinkingLevel: string; tools: string[]; /** * Its own location, chosen at spawn (e.g. a git worktree, on the caller's environment) and kept when the session * moves; absent: it follows the session. */ location?: Location; /** * An own cwd from version 1, which did not record the environment: the worker places it (`placeSubagents`) on the * environment it was spawned on before the Harness is live, so no one else reads it. */ unplacedCwd?: string; /** * The top-level conversation that last spawned it or sent it a message (the main conversation or a `/tree` branch): * where `team send to: "parent"` goes. Absent (spawned before it was recorded): the current main conversation. */ parent?: ConversationId; /** Answers already reported: several messages can end in one answer, reported once. */ reported: EntryId[]; /** Hidden from the sidebar's list and `status`; still usable, and `send` restores it. */ archived?: true; }; /** A code mode script's one-shot agent (plugins/agent), listed for inspection from the script's tool card. */ export type OneShot = { conversationId: ConversationId; label: string; model: string; thinkingLevel: string; tools: string[]; }; export type SubagentState = { agents: Record; reporters: Record; /** One-shot agents by the nested call ID that ran them (`