@geminixiang/mikan 1.0.0-beta.21 → 1.0.0-beta.22

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 (112) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/adapters/intake.d.ts.map +1 -1
  3. package/dist/adapters/intake.js +5 -0
  4. package/dist/adapters/intake.js.map +1 -1
  5. package/dist/adapters/slack/bot.d.ts.map +1 -1
  6. package/dist/adapters/slack/bot.js +13 -2
  7. package/dist/adapters/slack/bot.js.map +1 -1
  8. package/dist/adapters/slack/types.d.ts +2 -0
  9. package/dist/adapters/slack/types.d.ts.map +1 -1
  10. package/dist/adapters/slack/types.js.map +1 -1
  11. package/dist/agent.d.ts.map +1 -1
  12. package/dist/agent.js +26 -15
  13. package/dist/agent.js.map +1 -1
  14. package/dist/commands/login.js +2 -2
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/sandbox.js +2 -2
  17. package/dist/commands/sandbox.js.map +1 -1
  18. package/dist/execution-resolver.d.ts +5 -6
  19. package/dist/execution-resolver.d.ts.map +1 -1
  20. package/dist/execution-resolver.js +72 -103
  21. package/dist/execution-resolver.js.map +1 -1
  22. package/dist/harness/index.d.ts +1 -1
  23. package/dist/harness/index.d.ts.map +1 -1
  24. package/dist/harness/index.js.map +1 -1
  25. package/dist/harness/runner.d.ts +4 -0
  26. package/dist/harness/runner.d.ts.map +1 -1
  27. package/dist/harness/runner.js +16 -2
  28. package/dist/harness/runner.js.map +1 -1
  29. package/dist/harness/subagent-runner.d.ts +14 -13
  30. package/dist/harness/subagent-runner.d.ts.map +1 -1
  31. package/dist/harness/subagent-runner.js +105 -19
  32. package/dist/harness/subagent-runner.js.map +1 -1
  33. package/dist/harness/types.d.ts +11 -0
  34. package/dist/harness/types.d.ts.map +1 -1
  35. package/dist/harness/types.js.map +1 -1
  36. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  37. package/dist/runtime/conversation-runtime.js +23 -79
  38. package/dist/runtime/conversation-runtime.js.map +1 -1
  39. package/dist/runtime/session-lifecycle.d.ts +19 -0
  40. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  41. package/dist/runtime/session-lifecycle.js +76 -0
  42. package/dist/runtime/session-lifecycle.js.map +1 -0
  43. package/dist/runtime/types.d.ts +5 -0
  44. package/dist/runtime/types.d.ts.map +1 -1
  45. package/dist/runtime/types.js.map +1 -1
  46. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  47. package/dist/sandbox/cloudflare.js +1 -0
  48. package/dist/sandbox/cloudflare.js.map +1 -1
  49. package/dist/sandbox/container.d.ts.map +1 -1
  50. package/dist/sandbox/container.js +1 -0
  51. package/dist/sandbox/container.js.map +1 -1
  52. package/dist/sandbox/firecracker.d.ts.map +1 -1
  53. package/dist/sandbox/firecracker.js +1 -0
  54. package/dist/sandbox/firecracker.js.map +1 -1
  55. package/dist/sandbox/gondolin.d.ts.map +1 -1
  56. package/dist/sandbox/gondolin.js +1 -0
  57. package/dist/sandbox/gondolin.js.map +1 -1
  58. package/dist/sandbox/host.d.ts.map +1 -1
  59. package/dist/sandbox/host.js +1 -0
  60. package/dist/sandbox/host.js.map +1 -1
  61. package/dist/sandbox/identity.d.ts +11 -16
  62. package/dist/sandbox/identity.d.ts.map +1 -1
  63. package/dist/sandbox/identity.js +32 -26
  64. package/dist/sandbox/identity.js.map +1 -1
  65. package/dist/sandbox/image.d.ts.map +1 -1
  66. package/dist/sandbox/image.js +1 -0
  67. package/dist/sandbox/image.js.map +1 -1
  68. package/dist/sandbox/index.d.ts +1 -0
  69. package/dist/sandbox/index.d.ts.map +1 -1
  70. package/dist/sandbox/index.js +6 -0
  71. package/dist/sandbox/index.js.map +1 -1
  72. package/dist/sandbox/types.d.ts +5 -0
  73. package/dist/sandbox/types.d.ts.map +1 -1
  74. package/dist/sandbox/types.js.map +1 -1
  75. package/dist/sessions/session-key.d.ts +9 -0
  76. package/dist/sessions/session-key.d.ts.map +1 -1
  77. package/dist/sessions/session-key.js +50 -2
  78. package/dist/sessions/session-key.js.map +1 -1
  79. package/dist/sessions/store.d.ts.map +1 -1
  80. package/dist/sessions/store.js +36 -8
  81. package/dist/sessions/store.js.map +1 -1
  82. package/dist/tools/sandbox.js +2 -2
  83. package/dist/tools/sandbox.js.map +1 -1
  84. package/dist/tools/subagent-slots.d.ts +3 -3
  85. package/dist/tools/subagent-slots.d.ts.map +1 -1
  86. package/dist/tools/subagent-slots.js +25 -10
  87. package/dist/tools/subagent-slots.js.map +1 -1
  88. package/dist/tools/subagent.d.ts +13 -2
  89. package/dist/tools/subagent.d.ts.map +1 -1
  90. package/dist/tools/subagent.js +16 -16
  91. package/dist/tools/subagent.js.map +1 -1
  92. package/dist/types.d.ts +7 -0
  93. package/dist/types.d.ts.map +1 -1
  94. package/dist/types.js.map +1 -1
  95. package/dist/vault/injection.d.ts +4 -14
  96. package/dist/vault/injection.d.ts.map +1 -1
  97. package/dist/vault/injection.js +5 -2
  98. package/dist/vault/injection.js.map +1 -1
  99. package/dist/vault/types.d.ts +4 -0
  100. package/dist/vault/types.d.ts.map +1 -1
  101. package/dist/vault/types.js.map +1 -1
  102. package/dist/web/admin/portal.js +2 -2
  103. package/dist/web/admin/portal.js.map +1 -1
  104. package/dist/workspace-projection/index.d.ts +5 -0
  105. package/dist/workspace-projection/index.d.ts.map +1 -0
  106. package/dist/workspace-projection/index.js +71 -0
  107. package/dist/workspace-projection/index.js.map +1 -0
  108. package/dist/workspace-projection/types.d.ts +7 -0
  109. package/dist/workspace-projection/types.d.ts.map +1 -0
  110. package/dist/workspace-projection/types.js +2 -0
  111. package/dist/workspace-projection/types.js.map +1 -0
  112. package/package.json +1 -1
@@ -43,6 +43,7 @@ export class MikanAgentSession {
43
43
  this.listeners = new Set();
44
44
  this.retryAttempt = 0;
45
45
  this.overflowRecoveryAttempted = false;
46
+ this.runActive = false;
46
47
  this.tally = { tokens: 0, costUsd: 0, llmCalls: 0, startedAt: 0 };
47
48
  this.runBudget = {};
48
49
  this.models = options.models;
@@ -97,6 +98,10 @@ export class MikanAgentSession {
97
98
  get model() {
98
99
  return this.agent.state.model;
99
100
  }
101
+ /** Whether this session currently owns a prompt, including pre-model hooks. */
102
+ get isActiveRun() {
103
+ return this.runActive;
104
+ }
100
105
  /** Resource totals and terminal budget state from the most recent prompt. */
101
106
  getLastRunStats() {
102
107
  return {
@@ -118,7 +123,7 @@ export class MikanAgentSession {
118
123
  async foldExternalUsage(usage) {
119
124
  this.tally.tokens += usage.tokens ?? 0;
120
125
  this.tally.costUsd += usage.costUsd ?? 0;
121
- if (this.budgetExceededReason || !this.agent.state.isStreaming)
126
+ if (this.budgetExceededReason || !this.runActive)
122
127
  return;
123
128
  const reason = this.resourceOverBudgetReason();
124
129
  if (reason)
@@ -149,9 +154,18 @@ export class MikanAgentSession {
149
154
  * @param options.origin Platform provenance forwarded to extension hooks.
150
155
  */
151
156
  async prompt(text, options) {
152
- if (this.agent.state.isStreaming) {
157
+ if (this.runActive) {
153
158
  throw new Error("Agent is already processing a prompt");
154
159
  }
160
+ this.runActive = true;
161
+ try {
162
+ return await this.runPrompt(text, options);
163
+ }
164
+ finally {
165
+ this.runActive = false;
166
+ }
167
+ }
168
+ async runPrompt(text, options) {
155
169
  const model = this.agent.state.model;
156
170
  await this.ensureAuthConfigured(model);
157
171
  this.retryAttempt = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MikanAgentSession — mikan's agent run loop.\n *\n * Owns a pi-agent-core `Agent` and layers on the behaviors mikan needs for\n * long-lived chat conversations:\n *\n * - message persistence into the conversation's {@link SessionStore}\n * - automatic context compaction (threshold and overflow recovery), using\n * pi-agent-core's compaction pipeline over the session tree\n * - automatic retry with exponential backoff on transient provider errors\n * - extension hook dispatch ({@link ExtensionRegistry})\n *\n * Events mirror the agent's lifecycle events plus `compaction_start/_end`\n * and `auto_retry_start/_end`, preserving the event surface mikan's\n * platform adapters already render.\n */\nimport {\n Agent,\n calculateContextTokens,\n compact,\n convertToLlm,\n estimateContextTokens,\n getOrThrow,\n prepareCompaction,\n shouldCompact,\n type AgentEvent,\n type AgentMessage,\n type AgentTool,\n type CustomMessage,\n type ThinkingLevel,\n} from \"@earendil-works/pi-agent-core\";\nimport {\n isContextOverflow,\n type Api,\n type AssistantMessage,\n type ImageContent,\n type Model,\n} from \"@earendil-works/pi-ai\";\nimport * as log from \"../log.js\";\nimport type { ExtensionRegistry } from \"./extensions/registry.js\";\nimport type { RunOrigin } from \"./extensions/types.js\";\nimport type { MikanModels } from \"./models.js\";\nimport { resolveHarnessSettings, type BudgetSettings, type HarnessSettings } from \"./settings.js\";\nimport type { SessionStore } from \"./session-store.js\";\nimport type { CompactionEntry } from \"./types.js\";\n\nexport type CompactionReason = \"threshold\" | \"overflow\" | \"manual\";\n\n/** Running resource tally for the current `prompt()` call, matched against the budget. */\ninterface RunTally {\n tokens: number;\n costUsd: number;\n llmCalls: number;\n startedAt: number;\n}\n\ninterface CompactionResultSummary {\n summary: string;\n firstKeptEntryId: string;\n tokensBefore: number;\n}\n\nexport type HarnessEvent =\n | AgentEvent\n | { type: \"compaction_start\"; reason: CompactionReason }\n | {\n type: \"compaction_end\";\n reason: CompactionReason;\n result?: CompactionResultSummary;\n aborted: boolean;\n errorMessage?: string;\n }\n | {\n type: \"auto_retry_start\";\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n errorMessage: string;\n }\n | { type: \"auto_retry_end\"; success: boolean; attempt: number; finalError?: string }\n | {\n type: \"budget_exceeded\";\n /** Which cap was hit, e.g. \"cost 2.01 USD > 2 USD limit\". */\n reason: string;\n tokens: number;\n costUsd: number;\n llmCalls: number;\n durationMs: number;\n };\n\nexport type HarnessEventListener = (event: HarnessEvent) => void | Promise<void>;\n\n/** Outcome of a `prompt()` call that an extension blocked before the model ran. */\nexport interface PromptBlockedOutcome {\n blocked: true;\n reason?: string;\n}\n\n// Transient provider failures worth retrying: overload/rate-limit responses,\n// 5xx statuses, and network/stream interruptions.\nconst RETRYABLE_ERROR_PATTERN =\n /overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|ended without|stream ended before message_stop|http2 request did not get a response|timed? out|timeout|terminated|retry delay/i;\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n reject(new Error(\"aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nexport interface MikanAgentSessionOptions {\n systemPrompt: string;\n model: Model<Api>;\n thinkingLevel: ThinkingLevel;\n tools: AgentTool[];\n models: MikanModels;\n sessionStore: SessionStore;\n settings?: Parameters<typeof resolveHarnessSettings>[0];\n extensions?: ExtensionRegistry;\n}\n\nexport class MikanAgentSession {\n readonly agent: Agent;\n readonly sessionStore: SessionStore;\n private readonly models: MikanModels;\n private readonly settings: HarnessSettings;\n private readonly extensions: ExtensionRegistry | undefined;\n private listeners = new Set<HarnessEventListener>();\n private retryAttempt = 0;\n private overflowRecoveryAttempted = false;\n private retryAbortController: AbortController | undefined;\n private compactionAbortController: AbortController | undefined;\n private tally: RunTally = { tokens: 0, costUsd: 0, llmCalls: 0, startedAt: 0 };\n private runBudget: BudgetSettings = {};\n private budgetExceededReason: string | undefined;\n private runOrigin: RunOrigin | undefined;\n\n constructor(options: MikanAgentSessionOptions) {\n this.models = options.models;\n this.sessionStore = options.sessionStore;\n this.settings = resolveHarnessSettings(options.settings);\n this.extensions = options.extensions;\n\n const tools = [...options.tools, ...(options.extensions?.getContributedTools() ?? [])];\n this.agent = new Agent({\n initialState: {\n systemPrompt: options.systemPrompt,\n model: options.model,\n thinkingLevel: options.thinkingLevel,\n tools,\n },\n convertToLlm,\n streamFn: (model, context, streamOptions) =>\n this.models.models.streamSimple(model, context, streamOptions),\n beforeToolCall: async ({ toolCall, args }) => {\n if (!this.extensions?.hasHandlers(\"tool_call\")) return undefined;\n const result = await this.extensions.emit(\"tool_call\", {\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n args,\n origin: this.runOrigin,\n });\n return result ?? undefined;\n },\n afterToolCall: async ({ toolCall, args, result, isError }) => {\n if (!this.extensions?.hasHandlers(\"tool_result\")) return undefined;\n // Chained extension rewrites (redaction, truncation) become a\n // pi-agent-core AfterToolCallResult override; undefined keeps the\n // executed result untouched.\n return this.extensions.emitToolResult({\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n args,\n content: result.content,\n isError,\n origin: this.runOrigin,\n });\n },\n });\n\n this.agent.subscribe(async (event) => {\n await this.handleAgentEvent(event);\n });\n }\n\n /** Conversation transcript currently held by the agent. */\n get messages(): AgentMessage[] {\n return this.agent.state.messages;\n }\n\n get model(): Model<Api> {\n return this.agent.state.model;\n }\n\n /** Resource totals and terminal budget state from the most recent prompt. */\n getLastRunStats(): Readonly<{\n tokens: number;\n costUsd: number;\n llmCalls: number;\n durationMs: number;\n budgetExceededReason?: string;\n }> {\n return {\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: this.tally.startedAt > 0 ? Date.now() - this.tally.startedAt : 0,\n ...(this.budgetExceededReason ? { budgetExceededReason: this.budgetExceededReason } : {}),\n };\n }\n\n /**\n * Fold spend incurred outside this session's own LLM calls — e.g. subagent\n * runs launched by a tool during the current prompt — into the run tally\n * and enforce the run budget at the fold itself: a fold that lands over a\n * resource ceiling aborts the run now instead of waiting for a next\n * assistant message that may never come (and would be paid for). Counts\n * tokens and cost only; external runs are not this session's turns.\n */\n async foldExternalUsage(usage: { tokens?: number; costUsd?: number }): Promise<void> {\n this.tally.tokens += usage.tokens ?? 0;\n this.tally.costUsd += usage.costUsd ?? 0;\n if (this.budgetExceededReason || !this.agent.state.isStreaming) return;\n const reason = this.resourceOverBudgetReason();\n if (reason) await this.exceedBudget(reason);\n }\n\n subscribe(listener: HarnessEventListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** Replace the agent transcript from the persisted session tree. */\n reloadFromSession(): number {\n const context = this.sessionStore.buildSessionContext();\n if (context.messages.length > 0) {\n this.agent.state.messages = context.messages;\n }\n return context.messages.length;\n }\n\n /**\n * Send a user prompt and run the agent loop to completion, including\n * automatic retries and compaction. Resolves when the turn (and any\n * recovery continuations) settles. Returns a blocked outcome when a\n * `before_agent_start` extension blocked the turn — the model was never\n * called and nothing was persisted.\n *\n * @param options.budget Per-run resource ceilings that override the session\n * defaults. Autonomous (event / trigger) runs should pass a budget so a\n * runaway loop is stopped even with no human watching.\n * @param options.origin Platform provenance forwarded to extension hooks.\n */\n async prompt(\n text: string,\n options?: { images?: ImageContent[]; budget?: BudgetSettings; origin?: RunOrigin },\n ): Promise<PromptBlockedOutcome | undefined> {\n if (this.agent.state.isStreaming) {\n throw new Error(\"Agent is already processing a prompt\");\n }\n\n const model = this.agent.state.model;\n await this.ensureAuthConfigured(model);\n\n this.retryAttempt = 0;\n this.overflowRecoveryAttempted = false;\n this.runBudget = { ...this.settings.budget, ...options?.budget };\n this.budgetExceededReason = undefined;\n this.tally = { tokens: 0, costUsd: 0, llmCalls: 0, startedAt: Date.now() };\n this.runOrigin = options?.origin;\n\n // A previous turn may have ended over the threshold (for example after an\n // abort); compact before adding new context on top.\n const lastAssistant = this.findLastAssistantMessage();\n if (lastAssistant && lastAssistant.stopReason !== \"error\") {\n await this.checkThresholdCompaction(lastAssistant);\n }\n\n let promptText = text;\n let systemPrompt = this.agent.state.systemPrompt;\n if (this.extensions?.hasHandlers(\"before_agent_start\")) {\n const result = await this.extensions.emitBeforeAgentStart({\n prompt: promptText,\n images: options?.images,\n systemPrompt,\n origin: this.runOrigin,\n });\n if (result?.block) {\n // Blocked before agent.prompt(): the user message never enters the\n // transcript or session store, so the blocked turn leaves no trace.\n log.logInfo(`Extension blocked turn${result.reason ? `: ${result.reason}` : \"\"}`);\n return { blocked: true, reason: result.reason };\n }\n if (result?.prompt !== undefined && result.prompt !== promptText) {\n log.logInfo(\n `Extension rewrote user prompt: ${promptText.length} → ${result.prompt.length} chars`,\n );\n promptText = result.prompt;\n }\n if (result?.systemPrompt && result.systemPrompt !== systemPrompt) {\n // An extension rewrote the system prompt for this turn. Log the new\n // size so the diagnostic in agent.ts (which logs the pre-hook prompt)\n // isn't mistaken for the final prompt sent to the model.\n log.logInfo(\n `Extension rewrote system prompt: ${systemPrompt.length} → ${result.systemPrompt.length} chars`,\n );\n systemPrompt = result.systemPrompt;\n this.agent.state.systemPrompt = systemPrompt;\n }\n }\n\n const userMessage: AgentMessage = {\n role: \"user\",\n content: [{ type: \"text\", text: promptText }, ...(options?.images ?? [])],\n timestamp: Date.now(),\n };\n\n await this.agent.prompt([userMessage]);\n while (await this.handlePostRun()) {\n await this.agent.continue();\n }\n\n // The turn settled on an error (retries exhausted or not retryable):\n // give monitoring extensions the final failure, once per turn.\n const settled = this.findLastAssistantMessage();\n if (settled?.stopReason === \"error\" && this.extensions?.hasHandlers(\"agent_error\")) {\n await this.extensions.emit(\"agent_error\", {\n errorMessage: settled.errorMessage || \"Unknown error\",\n origin: this.runOrigin,\n });\n }\n\n if (this.extensions?.hasHandlers(\"turn_end\")) {\n await this.extensions.emit(\"turn_end\", {\n messages: this.agent.state.messages,\n origin: this.runOrigin,\n });\n }\n return undefined;\n }\n\n /** Abort the active run, pending retry backoff, and in-flight compaction. */\n abort(): void {\n this.retryAbortController?.abort();\n this.compactionAbortController?.abort();\n this.agent.abort();\n }\n\n private async ensureAuthConfigured(model: Model<Api>): Promise<void> {\n const auth = await this.models.getAuth(model);\n if (!auth) {\n throw new Error(\n `No credentials for provider \"${model.provider}\". Set the provider API key environment variable or add it to auth.json.`,\n );\n }\n }\n\n private async emit(event: HarnessEvent): Promise<void> {\n for (const listener of this.listeners) {\n try {\n await listener(event);\n } catch (err) {\n log.logWarning(\n \"Harness event listener failed\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n }\n\n private async handleAgentEvent(event: AgentEvent): Promise<void> {\n await this.emit(event);\n\n if (event.type !== \"message_end\") return;\n const message = event.message;\n\n if (message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") {\n this.sessionStore.appendMessage(message);\n } else if (message.role === \"custom\") {\n const custom = message as CustomMessage;\n this.sessionStore.appendCustomMessageEntry(\n custom.customType,\n custom.content,\n custom.display,\n custom.details,\n );\n }\n\n if (this.extensions?.hasHandlers(\"message_end\")) {\n await this.extensions.emit(\"message_end\", { message, origin: this.runOrigin });\n }\n\n if (message.role === \"assistant\") {\n this.recordUsage(message);\n await this.enforceBudget(message);\n if (message.stopReason !== \"error\") {\n this.overflowRecoveryAttempted = false;\n if (this.retryAttempt > 0) {\n await this.emit({ type: \"auto_retry_end\", success: true, attempt: this.retryAttempt });\n this.retryAttempt = 0;\n }\n }\n }\n }\n\n /** Fold one assistant turn's usage into the running per-run tally. */\n private recordUsage(message: AssistantMessage): void {\n this.tally.llmCalls += 1;\n const usage = message.usage;\n if (!usage) return;\n this.tally.tokens += usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n this.tally.costUsd += usage.cost?.total ?? 0;\n }\n\n /** Compare the tally against the run budget; abort the run when a cap is exceeded. */\n private async enforceBudget(message: AssistantMessage): Promise<void> {\n if (this.budgetExceededReason) return;\n const reason = this.overBudgetReason(message);\n if (!reason) return;\n await this.exceedBudget(reason);\n }\n\n /** Mark the run over budget, notify listeners and extensions, abort the agent. */\n private async exceedBudget(reason: string): Promise<void> {\n this.budgetExceededReason = reason;\n await this.emit({\n type: \"budget_exceeded\",\n reason,\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: Date.now() - this.tally.startedAt,\n });\n if (this.extensions?.hasHandlers(\"budget_exceeded\")) {\n await this.extensions.emit(\"budget_exceeded\", {\n reason,\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: Date.now() - this.tally.startedAt,\n origin: this.runOrigin,\n });\n }\n log.logWarning(\"Run budget exceeded — aborting\", reason);\n this.agent.abort();\n }\n\n private overBudgetReason(message: AssistantMessage): string | undefined {\n const { maxLlmCalls } = this.runBudget;\n const needsAnotherCall =\n message.stopReason === \"error\" || message.content.some((part) => part.type === \"toolCall\");\n if (needsAnotherCall && maxLlmCalls !== undefined && this.tally.llmCalls >= maxLlmCalls) {\n return `${this.tally.llmCalls} LLM calls >= ${maxLlmCalls} limit`;\n }\n return this.resourceOverBudgetReason();\n }\n\n /** The message-independent budget checks, shared with external-spend folds. */\n private resourceOverBudgetReason(): string | undefined {\n const { maxTokens, maxCostUsd, maxDurationMs } = this.runBudget;\n if (maxTokens !== undefined && this.tally.tokens >= maxTokens) {\n return `${this.tally.tokens} tokens >= ${maxTokens} limit`;\n }\n if (maxCostUsd !== undefined && this.tally.costUsd >= maxCostUsd) {\n return `cost ${this.tally.costUsd.toFixed(2)} USD >= ${maxCostUsd} USD limit`;\n }\n if (maxDurationMs !== undefined && Date.now() - this.tally.startedAt >= maxDurationMs) {\n return `${Date.now() - this.tally.startedAt}ms >= ${maxDurationMs}ms limit`;\n }\n return undefined;\n }\n\n private findLastAssistantMessage(): AssistantMessage | undefined {\n const messages = this.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message.role === \"assistant\") return message;\n }\n return undefined;\n }\n\n /** Decide what to do after a run settles. Returns true when the agent should continue. */\n private async handlePostRun(): Promise<boolean> {\n // A run stopped for going over budget must not be retried or compacted back\n // into another continuation — that would defeat the circuit breaker.\n if (this.budgetExceededReason) return false;\n\n const lastAssistant = this.findLastAssistantMessage();\n if (!lastAssistant) return false;\n\n if (lastAssistant.stopReason === \"error\") {\n const contextWindow = this.agent.state.model.contextWindow || 0;\n if (isContextOverflow(lastAssistant, contextWindow)) {\n return this.handleOverflow();\n }\n if (this.isRetryableError(lastAssistant)) {\n return this.prepareRetry(lastAssistant);\n }\n return false;\n }\n\n return this.checkThresholdCompaction(lastAssistant);\n }\n\n private async handleOverflow(): Promise<boolean> {\n if (this.overflowRecoveryAttempted) {\n await this.emit({\n type: \"compaction_end\",\n reason: \"overflow\",\n aborted: false,\n errorMessage:\n \"Context overflow recovery failed after one compact-and-retry attempt. Try /new or a larger-context model.\",\n });\n return false;\n }\n this.overflowRecoveryAttempted = true;\n this.dropTrailingErrorMessage();\n return this.runCompaction(\"overflow\", true);\n }\n\n private async checkThresholdCompaction(lastAssistant: AssistantMessage): Promise<boolean> {\n const settings = this.settings.compaction;\n if (!settings.enabled) return false;\n const contextWindow = this.agent.state.model.contextWindow || 0;\n if (contextWindow <= 0) return false;\n\n let contextTokens = lastAssistant.usage ? calculateContextTokens(lastAssistant.usage) : 0;\n if (contextTokens === 0) {\n const estimate = estimateContextTokens(this.agent.state.messages);\n if (estimate.lastUsageIndex === null) return false;\n contextTokens = estimate.tokens;\n }\n\n if (!shouldCompact(contextTokens, contextWindow, settings)) return false;\n return this.runCompaction(\"threshold\", false);\n }\n\n private async runCompaction(reason: CompactionReason, willRetry: boolean): Promise<boolean> {\n let started = false;\n try {\n const pathEntries = this.sessionStore.getBranch();\n const preparation = getOrThrow(prepareCompaction(pathEntries, this.settings.compaction));\n if (!preparation) return false;\n\n await this.emit({ type: \"compaction_start\", reason });\n started = true;\n this.compactionAbortController = new AbortController();\n const signal = this.compactionAbortController.signal;\n\n const result = getOrThrow(\n await compact(\n preparation,\n this.models.models,\n this.agent.state.model,\n undefined,\n signal,\n this.agent.state.thinkingLevel,\n ),\n );\n if (signal.aborted) {\n await this.emit({ type: \"compaction_end\", reason, aborted: true });\n return false;\n }\n\n const entryId = this.sessionStore.appendCompaction(\n result.summary,\n result.firstKeptEntryId,\n result.tokensBefore,\n result.details,\n );\n const context = this.sessionStore.buildSessionContext();\n this.agent.state.messages = context.messages;\n\n if (this.extensions?.hasHandlers(\"session_compact\")) {\n const entry = this.sessionStore.getEntry(entryId);\n if (entry?.type === \"compaction\") {\n await this.extensions.emit(\"session_compact\", {\n entry: entry as CompactionEntry,\n reason,\n });\n }\n }\n\n await this.emit({\n type: \"compaction_end\",\n reason,\n result: {\n summary: result.summary,\n firstKeptEntryId: result.firstKeptEntryId,\n tokensBefore: result.tokensBefore,\n },\n aborted: false,\n });\n\n if (willRetry) {\n this.dropTrailingErrorMessage();\n return true;\n }\n return this.agent.hasQueuedMessages();\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"compaction failed\";\n if (started) {\n await this.emit({\n type: \"compaction_end\",\n reason,\n aborted: false,\n errorMessage:\n reason === \"overflow\"\n ? `Context overflow recovery failed: ${errorMessage}`\n : `Auto-compaction failed: ${errorMessage}`,\n });\n } else {\n log.logWarning(\"Compaction preparation failed\", errorMessage);\n }\n return false;\n } finally {\n this.compactionAbortController = undefined;\n }\n }\n\n private isRetryableError(message: AssistantMessage): boolean {\n if (message.stopReason !== \"error\" || !message.errorMessage) return false;\n return RETRYABLE_ERROR_PATTERN.test(message.errorMessage);\n }\n\n private async prepareRetry(message: AssistantMessage): Promise<boolean> {\n const settings = this.settings.retry;\n if (!settings.enabled) return false;\n\n this.retryAttempt++;\n if (this.retryAttempt > settings.maxRetries) {\n this.retryAttempt--;\n await this.emit({\n type: \"auto_retry_end\",\n success: false,\n attempt: this.retryAttempt,\n finalError: message.errorMessage,\n });\n this.retryAttempt = 0;\n return false;\n }\n\n const delayMs = settings.baseDelayMs * 2 ** (this.retryAttempt - 1);\n await this.emit({\n type: \"auto_retry_start\",\n attempt: this.retryAttempt,\n maxAttempts: settings.maxRetries,\n delayMs,\n errorMessage: message.errorMessage || \"Unknown error\",\n });\n\n this.dropTrailingErrorMessage();\n\n this.retryAbortController = new AbortController();\n try {\n await sleep(delayMs, this.retryAbortController.signal);\n } catch {\n const attempt = this.retryAttempt;\n this.retryAttempt = 0;\n await this.emit({\n type: \"auto_retry_end\",\n success: false,\n attempt,\n finalError: \"Retry cancelled\",\n });\n return false;\n } finally {\n this.retryAbortController = undefined;\n }\n return true;\n }\n\n private dropTrailingErrorMessage(): void {\n const messages = this.agent.state.messages;\n if (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n this.agent.state.messages = messages.slice(0, -1);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MikanAgentSession — mikan's agent run loop.\n *\n * Owns a pi-agent-core `Agent` and layers on the behaviors mikan needs for\n * long-lived chat conversations:\n *\n * - message persistence into the conversation's {@link SessionStore}\n * - automatic context compaction (threshold and overflow recovery), using\n * pi-agent-core's compaction pipeline over the session tree\n * - automatic retry with exponential backoff on transient provider errors\n * - extension hook dispatch ({@link ExtensionRegistry})\n *\n * Events mirror the agent's lifecycle events plus `compaction_start/_end`\n * and `auto_retry_start/_end`, preserving the event surface mikan's\n * platform adapters already render.\n */\nimport {\n Agent,\n calculateContextTokens,\n compact,\n convertToLlm,\n estimateContextTokens,\n getOrThrow,\n prepareCompaction,\n shouldCompact,\n type AgentEvent,\n type AgentMessage,\n type AgentTool,\n type CustomMessage,\n type ThinkingLevel,\n} from \"@earendil-works/pi-agent-core\";\nimport {\n isContextOverflow,\n type Api,\n type AssistantMessage,\n type ImageContent,\n type Model,\n} from \"@earendil-works/pi-ai\";\nimport * as log from \"../log.js\";\nimport type { ExtensionRegistry } from \"./extensions/registry.js\";\nimport type { RunOrigin } from \"./extensions/types.js\";\nimport type { MikanModels } from \"./models.js\";\nimport { resolveHarnessSettings, type BudgetSettings, type HarnessSettings } from \"./settings.js\";\nimport type { SessionStore } from \"./session-store.js\";\nimport type { CompactionEntry } from \"./types.js\";\n\nexport type CompactionReason = \"threshold\" | \"overflow\" | \"manual\";\n\n/** Running resource tally for the current `prompt()` call, matched against the budget. */\ninterface RunTally {\n tokens: number;\n costUsd: number;\n llmCalls: number;\n startedAt: number;\n}\n\ninterface CompactionResultSummary {\n summary: string;\n firstKeptEntryId: string;\n tokensBefore: number;\n}\n\nexport type HarnessEvent =\n | AgentEvent\n | { type: \"compaction_start\"; reason: CompactionReason }\n | {\n type: \"compaction_end\";\n reason: CompactionReason;\n result?: CompactionResultSummary;\n aborted: boolean;\n errorMessage?: string;\n }\n | {\n type: \"auto_retry_start\";\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n errorMessage: string;\n }\n | { type: \"auto_retry_end\"; success: boolean; attempt: number; finalError?: string }\n | {\n type: \"budget_exceeded\";\n /** Which cap was hit, e.g. \"cost 2.01 USD > 2 USD limit\". */\n reason: string;\n tokens: number;\n costUsd: number;\n llmCalls: number;\n durationMs: number;\n };\n\nexport type HarnessEventListener = (event: HarnessEvent) => void | Promise<void>;\n\n/** Outcome of a `prompt()` call that an extension blocked before the model ran. */\nexport interface PromptBlockedOutcome {\n blocked: true;\n reason?: string;\n}\n\n// Transient provider failures worth retrying: overload/rate-limit responses,\n// 5xx statuses, and network/stream interruptions.\nconst RETRYABLE_ERROR_PATTERN =\n /overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|ended without|stream ended before message_stop|http2 request did not get a response|timed? out|timeout|terminated|retry delay/i;\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n reject(new Error(\"aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nexport interface MikanAgentSessionOptions {\n systemPrompt: string;\n model: Model<Api>;\n thinkingLevel: ThinkingLevel;\n tools: AgentTool[];\n models: MikanModels;\n sessionStore: SessionStore;\n settings?: Parameters<typeof resolveHarnessSettings>[0];\n extensions?: ExtensionRegistry;\n}\n\nexport class MikanAgentSession {\n readonly agent: Agent;\n readonly sessionStore: SessionStore;\n private readonly models: MikanModels;\n private readonly settings: HarnessSettings;\n private readonly extensions: ExtensionRegistry | undefined;\n private listeners = new Set<HarnessEventListener>();\n private retryAttempt = 0;\n private overflowRecoveryAttempted = false;\n private retryAbortController: AbortController | undefined;\n private compactionAbortController: AbortController | undefined;\n private runActive = false;\n private tally: RunTally = { tokens: 0, costUsd: 0, llmCalls: 0, startedAt: 0 };\n private runBudget: BudgetSettings = {};\n private budgetExceededReason: string | undefined;\n private runOrigin: RunOrigin | undefined;\n\n constructor(options: MikanAgentSessionOptions) {\n this.models = options.models;\n this.sessionStore = options.sessionStore;\n this.settings = resolveHarnessSettings(options.settings);\n this.extensions = options.extensions;\n\n const tools = [...options.tools, ...(options.extensions?.getContributedTools() ?? [])];\n this.agent = new Agent({\n initialState: {\n systemPrompt: options.systemPrompt,\n model: options.model,\n thinkingLevel: options.thinkingLevel,\n tools,\n },\n convertToLlm,\n streamFn: (model, context, streamOptions) =>\n this.models.models.streamSimple(model, context, streamOptions),\n beforeToolCall: async ({ toolCall, args }) => {\n if (!this.extensions?.hasHandlers(\"tool_call\")) return undefined;\n const result = await this.extensions.emit(\"tool_call\", {\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n args,\n origin: this.runOrigin,\n });\n return result ?? undefined;\n },\n afterToolCall: async ({ toolCall, args, result, isError }) => {\n if (!this.extensions?.hasHandlers(\"tool_result\")) return undefined;\n // Chained extension rewrites (redaction, truncation) become a\n // pi-agent-core AfterToolCallResult override; undefined keeps the\n // executed result untouched.\n return this.extensions.emitToolResult({\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n args,\n content: result.content,\n isError,\n origin: this.runOrigin,\n });\n },\n });\n\n this.agent.subscribe(async (event) => {\n await this.handleAgentEvent(event);\n });\n }\n\n /** Conversation transcript currently held by the agent. */\n get messages(): AgentMessage[] {\n return this.agent.state.messages;\n }\n\n get model(): Model<Api> {\n return this.agent.state.model;\n }\n\n /** Whether this session currently owns a prompt, including pre-model hooks. */\n get isActiveRun(): boolean {\n return this.runActive;\n }\n\n /** Resource totals and terminal budget state from the most recent prompt. */\n getLastRunStats(): Readonly<{\n tokens: number;\n costUsd: number;\n llmCalls: number;\n durationMs: number;\n budgetExceededReason?: string;\n }> {\n return {\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: this.tally.startedAt > 0 ? Date.now() - this.tally.startedAt : 0,\n ...(this.budgetExceededReason ? { budgetExceededReason: this.budgetExceededReason } : {}),\n };\n }\n\n /**\n * Fold spend incurred outside this session's own LLM calls — e.g. subagent\n * runs launched by a tool during the current prompt — into the run tally\n * and enforce the run budget at the fold itself: a fold that lands over a\n * resource ceiling aborts the run now instead of waiting for a next\n * assistant message that may never come (and would be paid for). Counts\n * tokens and cost only; external runs are not this session's turns.\n */\n async foldExternalUsage(usage: { tokens?: number; costUsd?: number }): Promise<void> {\n this.tally.tokens += usage.tokens ?? 0;\n this.tally.costUsd += usage.costUsd ?? 0;\n if (this.budgetExceededReason || !this.runActive) return;\n const reason = this.resourceOverBudgetReason();\n if (reason) await this.exceedBudget(reason);\n }\n\n subscribe(listener: HarnessEventListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** Replace the agent transcript from the persisted session tree. */\n reloadFromSession(): number {\n const context = this.sessionStore.buildSessionContext();\n if (context.messages.length > 0) {\n this.agent.state.messages = context.messages;\n }\n return context.messages.length;\n }\n\n /**\n * Send a user prompt and run the agent loop to completion, including\n * automatic retries and compaction. Resolves when the turn (and any\n * recovery continuations) settles. Returns a blocked outcome when a\n * `before_agent_start` extension blocked the turn — the model was never\n * called and nothing was persisted.\n *\n * @param options.budget Per-run resource ceilings that override the session\n * defaults. Autonomous (event / trigger) runs should pass a budget so a\n * runaway loop is stopped even with no human watching.\n * @param options.origin Platform provenance forwarded to extension hooks.\n */\n async prompt(\n text: string,\n options?: { images?: ImageContent[]; budget?: BudgetSettings; origin?: RunOrigin },\n ): Promise<PromptBlockedOutcome | undefined> {\n if (this.runActive) {\n throw new Error(\"Agent is already processing a prompt\");\n }\n this.runActive = true;\n try {\n return await this.runPrompt(text, options);\n } finally {\n this.runActive = false;\n }\n }\n\n private async runPrompt(\n text: string,\n options?: { images?: ImageContent[]; budget?: BudgetSettings; origin?: RunOrigin },\n ): Promise<PromptBlockedOutcome | undefined> {\n const model = this.agent.state.model;\n await this.ensureAuthConfigured(model);\n\n this.retryAttempt = 0;\n this.overflowRecoveryAttempted = false;\n this.runBudget = { ...this.settings.budget, ...options?.budget };\n this.budgetExceededReason = undefined;\n this.tally = { tokens: 0, costUsd: 0, llmCalls: 0, startedAt: Date.now() };\n this.runOrigin = options?.origin;\n\n // A previous turn may have ended over the threshold (for example after an\n // abort); compact before adding new context on top.\n const lastAssistant = this.findLastAssistantMessage();\n if (lastAssistant && lastAssistant.stopReason !== \"error\") {\n await this.checkThresholdCompaction(lastAssistant);\n }\n\n let promptText = text;\n let systemPrompt = this.agent.state.systemPrompt;\n if (this.extensions?.hasHandlers(\"before_agent_start\")) {\n const result = await this.extensions.emitBeforeAgentStart({\n prompt: promptText,\n images: options?.images,\n systemPrompt,\n origin: this.runOrigin,\n });\n if (result?.block) {\n // Blocked before agent.prompt(): the user message never enters the\n // transcript or session store, so the blocked turn leaves no trace.\n log.logInfo(`Extension blocked turn${result.reason ? `: ${result.reason}` : \"\"}`);\n return { blocked: true, reason: result.reason };\n }\n if (result?.prompt !== undefined && result.prompt !== promptText) {\n log.logInfo(\n `Extension rewrote user prompt: ${promptText.length} → ${result.prompt.length} chars`,\n );\n promptText = result.prompt;\n }\n if (result?.systemPrompt && result.systemPrompt !== systemPrompt) {\n // An extension rewrote the system prompt for this turn. Log the new\n // size so the diagnostic in agent.ts (which logs the pre-hook prompt)\n // isn't mistaken for the final prompt sent to the model.\n log.logInfo(\n `Extension rewrote system prompt: ${systemPrompt.length} → ${result.systemPrompt.length} chars`,\n );\n systemPrompt = result.systemPrompt;\n this.agent.state.systemPrompt = systemPrompt;\n }\n }\n\n const userMessage: AgentMessage = {\n role: \"user\",\n content: [{ type: \"text\", text: promptText }, ...(options?.images ?? [])],\n timestamp: Date.now(),\n };\n\n await this.agent.prompt([userMessage]);\n while (await this.handlePostRun()) {\n await this.agent.continue();\n }\n\n // The turn settled on an error (retries exhausted or not retryable):\n // give monitoring extensions the final failure, once per turn.\n const settled = this.findLastAssistantMessage();\n if (settled?.stopReason === \"error\" && this.extensions?.hasHandlers(\"agent_error\")) {\n await this.extensions.emit(\"agent_error\", {\n errorMessage: settled.errorMessage || \"Unknown error\",\n origin: this.runOrigin,\n });\n }\n\n if (this.extensions?.hasHandlers(\"turn_end\")) {\n await this.extensions.emit(\"turn_end\", {\n messages: this.agent.state.messages,\n origin: this.runOrigin,\n });\n }\n return undefined;\n }\n\n /** Abort the active run, pending retry backoff, and in-flight compaction. */\n abort(): void {\n this.retryAbortController?.abort();\n this.compactionAbortController?.abort();\n this.agent.abort();\n }\n\n private async ensureAuthConfigured(model: Model<Api>): Promise<void> {\n const auth = await this.models.getAuth(model);\n if (!auth) {\n throw new Error(\n `No credentials for provider \"${model.provider}\". Set the provider API key environment variable or add it to auth.json.`,\n );\n }\n }\n\n private async emit(event: HarnessEvent): Promise<void> {\n for (const listener of this.listeners) {\n try {\n await listener(event);\n } catch (err) {\n log.logWarning(\n \"Harness event listener failed\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n }\n\n private async handleAgentEvent(event: AgentEvent): Promise<void> {\n await this.emit(event);\n\n if (event.type !== \"message_end\") return;\n const message = event.message;\n\n if (message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") {\n this.sessionStore.appendMessage(message);\n } else if (message.role === \"custom\") {\n const custom = message as CustomMessage;\n this.sessionStore.appendCustomMessageEntry(\n custom.customType,\n custom.content,\n custom.display,\n custom.details,\n );\n }\n\n if (this.extensions?.hasHandlers(\"message_end\")) {\n await this.extensions.emit(\"message_end\", { message, origin: this.runOrigin });\n }\n\n if (message.role === \"assistant\") {\n this.recordUsage(message);\n await this.enforceBudget(message);\n if (message.stopReason !== \"error\") {\n this.overflowRecoveryAttempted = false;\n if (this.retryAttempt > 0) {\n await this.emit({ type: \"auto_retry_end\", success: true, attempt: this.retryAttempt });\n this.retryAttempt = 0;\n }\n }\n }\n }\n\n /** Fold one assistant turn's usage into the running per-run tally. */\n private recordUsage(message: AssistantMessage): void {\n this.tally.llmCalls += 1;\n const usage = message.usage;\n if (!usage) return;\n this.tally.tokens += usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n this.tally.costUsd += usage.cost?.total ?? 0;\n }\n\n /** Compare the tally against the run budget; abort the run when a cap is exceeded. */\n private async enforceBudget(message: AssistantMessage): Promise<void> {\n if (this.budgetExceededReason) return;\n const reason = this.overBudgetReason(message);\n if (!reason) return;\n await this.exceedBudget(reason);\n }\n\n /** Mark the run over budget, notify listeners and extensions, abort the agent. */\n private async exceedBudget(reason: string): Promise<void> {\n this.budgetExceededReason = reason;\n await this.emit({\n type: \"budget_exceeded\",\n reason,\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: Date.now() - this.tally.startedAt,\n });\n if (this.extensions?.hasHandlers(\"budget_exceeded\")) {\n await this.extensions.emit(\"budget_exceeded\", {\n reason,\n tokens: this.tally.tokens,\n costUsd: this.tally.costUsd,\n llmCalls: this.tally.llmCalls,\n durationMs: Date.now() - this.tally.startedAt,\n origin: this.runOrigin,\n });\n }\n log.logWarning(\"Run budget exceeded — aborting\", reason);\n this.agent.abort();\n }\n\n private overBudgetReason(message: AssistantMessage): string | undefined {\n const { maxLlmCalls } = this.runBudget;\n const needsAnotherCall =\n message.stopReason === \"error\" || message.content.some((part) => part.type === \"toolCall\");\n if (needsAnotherCall && maxLlmCalls !== undefined && this.tally.llmCalls >= maxLlmCalls) {\n return `${this.tally.llmCalls} LLM calls >= ${maxLlmCalls} limit`;\n }\n return this.resourceOverBudgetReason();\n }\n\n /** The message-independent budget checks, shared with external-spend folds. */\n private resourceOverBudgetReason(): string | undefined {\n const { maxTokens, maxCostUsd, maxDurationMs } = this.runBudget;\n if (maxTokens !== undefined && this.tally.tokens >= maxTokens) {\n return `${this.tally.tokens} tokens >= ${maxTokens} limit`;\n }\n if (maxCostUsd !== undefined && this.tally.costUsd >= maxCostUsd) {\n return `cost ${this.tally.costUsd.toFixed(2)} USD >= ${maxCostUsd} USD limit`;\n }\n if (maxDurationMs !== undefined && Date.now() - this.tally.startedAt >= maxDurationMs) {\n return `${Date.now() - this.tally.startedAt}ms >= ${maxDurationMs}ms limit`;\n }\n return undefined;\n }\n\n private findLastAssistantMessage(): AssistantMessage | undefined {\n const messages = this.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message.role === \"assistant\") return message;\n }\n return undefined;\n }\n\n /** Decide what to do after a run settles. Returns true when the agent should continue. */\n private async handlePostRun(): Promise<boolean> {\n // A run stopped for going over budget must not be retried or compacted back\n // into another continuation — that would defeat the circuit breaker.\n if (this.budgetExceededReason) return false;\n\n const lastAssistant = this.findLastAssistantMessage();\n if (!lastAssistant) return false;\n\n if (lastAssistant.stopReason === \"error\") {\n const contextWindow = this.agent.state.model.contextWindow || 0;\n if (isContextOverflow(lastAssistant, contextWindow)) {\n return this.handleOverflow();\n }\n if (this.isRetryableError(lastAssistant)) {\n return this.prepareRetry(lastAssistant);\n }\n return false;\n }\n\n return this.checkThresholdCompaction(lastAssistant);\n }\n\n private async handleOverflow(): Promise<boolean> {\n if (this.overflowRecoveryAttempted) {\n await this.emit({\n type: \"compaction_end\",\n reason: \"overflow\",\n aborted: false,\n errorMessage:\n \"Context overflow recovery failed after one compact-and-retry attempt. Try /new or a larger-context model.\",\n });\n return false;\n }\n this.overflowRecoveryAttempted = true;\n this.dropTrailingErrorMessage();\n return this.runCompaction(\"overflow\", true);\n }\n\n private async checkThresholdCompaction(lastAssistant: AssistantMessage): Promise<boolean> {\n const settings = this.settings.compaction;\n if (!settings.enabled) return false;\n const contextWindow = this.agent.state.model.contextWindow || 0;\n if (contextWindow <= 0) return false;\n\n let contextTokens = lastAssistant.usage ? calculateContextTokens(lastAssistant.usage) : 0;\n if (contextTokens === 0) {\n const estimate = estimateContextTokens(this.agent.state.messages);\n if (estimate.lastUsageIndex === null) return false;\n contextTokens = estimate.tokens;\n }\n\n if (!shouldCompact(contextTokens, contextWindow, settings)) return false;\n return this.runCompaction(\"threshold\", false);\n }\n\n private async runCompaction(reason: CompactionReason, willRetry: boolean): Promise<boolean> {\n let started = false;\n try {\n const pathEntries = this.sessionStore.getBranch();\n const preparation = getOrThrow(prepareCompaction(pathEntries, this.settings.compaction));\n if (!preparation) return false;\n\n await this.emit({ type: \"compaction_start\", reason });\n started = true;\n this.compactionAbortController = new AbortController();\n const signal = this.compactionAbortController.signal;\n\n const result = getOrThrow(\n await compact(\n preparation,\n this.models.models,\n this.agent.state.model,\n undefined,\n signal,\n this.agent.state.thinkingLevel,\n ),\n );\n if (signal.aborted) {\n await this.emit({ type: \"compaction_end\", reason, aborted: true });\n return false;\n }\n\n const entryId = this.sessionStore.appendCompaction(\n result.summary,\n result.firstKeptEntryId,\n result.tokensBefore,\n result.details,\n );\n const context = this.sessionStore.buildSessionContext();\n this.agent.state.messages = context.messages;\n\n if (this.extensions?.hasHandlers(\"session_compact\")) {\n const entry = this.sessionStore.getEntry(entryId);\n if (entry?.type === \"compaction\") {\n await this.extensions.emit(\"session_compact\", {\n entry: entry as CompactionEntry,\n reason,\n });\n }\n }\n\n await this.emit({\n type: \"compaction_end\",\n reason,\n result: {\n summary: result.summary,\n firstKeptEntryId: result.firstKeptEntryId,\n tokensBefore: result.tokensBefore,\n },\n aborted: false,\n });\n\n if (willRetry) {\n this.dropTrailingErrorMessage();\n return true;\n }\n return this.agent.hasQueuedMessages();\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"compaction failed\";\n if (started) {\n await this.emit({\n type: \"compaction_end\",\n reason,\n aborted: false,\n errorMessage:\n reason === \"overflow\"\n ? `Context overflow recovery failed: ${errorMessage}`\n : `Auto-compaction failed: ${errorMessage}`,\n });\n } else {\n log.logWarning(\"Compaction preparation failed\", errorMessage);\n }\n return false;\n } finally {\n this.compactionAbortController = undefined;\n }\n }\n\n private isRetryableError(message: AssistantMessage): boolean {\n if (message.stopReason !== \"error\" || !message.errorMessage) return false;\n return RETRYABLE_ERROR_PATTERN.test(message.errorMessage);\n }\n\n private async prepareRetry(message: AssistantMessage): Promise<boolean> {\n const settings = this.settings.retry;\n if (!settings.enabled) return false;\n\n this.retryAttempt++;\n if (this.retryAttempt > settings.maxRetries) {\n this.retryAttempt--;\n await this.emit({\n type: \"auto_retry_end\",\n success: false,\n attempt: this.retryAttempt,\n finalError: message.errorMessage,\n });\n this.retryAttempt = 0;\n return false;\n }\n\n const delayMs = settings.baseDelayMs * 2 ** (this.retryAttempt - 1);\n await this.emit({\n type: \"auto_retry_start\",\n attempt: this.retryAttempt,\n maxAttempts: settings.maxRetries,\n delayMs,\n errorMessage: message.errorMessage || \"Unknown error\",\n });\n\n this.dropTrailingErrorMessage();\n\n this.retryAbortController = new AbortController();\n try {\n await sleep(delayMs, this.retryAbortController.signal);\n } catch {\n const attempt = this.retryAttempt;\n this.retryAttempt = 0;\n await this.emit({\n type: \"auto_retry_end\",\n success: false,\n attempt,\n finalError: \"Retry cancelled\",\n });\n return false;\n } finally {\n this.retryAbortController = undefined;\n }\n return true;\n }\n\n private dropTrailingErrorMessage(): void {\n const messages = this.agent.state.messages;\n if (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n this.agent.state.messages = messages.slice(0, -1);\n }\n }\n}\n"]}
@@ -1,8 +1,14 @@
1
- import type { AgentTool, ThinkingLevel } from "@earendil-works/pi-agent-core";
1
+ import type { AgentMessage, AgentTool, ThinkingLevel } from "@earendil-works/pi-agent-core";
2
2
  import type { Api, Model } from "@earendil-works/pi-ai";
3
3
  import { type TSchema } from "@sinclair/typebox";
4
4
  import type { MikanModels } from "./models.js";
5
- import type { SubagentRunOutput, SubagentRunRequest, SubagentRunResult } from "./types.js";
5
+ import type { SubagentRunOutput, SubagentRunRequest, SubagentRunResult, SubagentUsage } from "./types.js";
6
+ import { type SubagentSlotPool } from "../tools/subagent-slots.js";
7
+ export declare const DEFAULT_SUBAGENT_BUDGET: {
8
+ readonly maxTurns: 100;
9
+ readonly maxCostUsd: 10;
10
+ readonly maxDurationMs: number;
11
+ };
6
12
  interface RunSubagentOptions<TOutputSchema extends TSchema | undefined = undefined> {
7
13
  request: SubagentRunRequest<TOutputSchema>;
8
14
  defaultModel: Model<Api>;
@@ -10,17 +16,12 @@ interface RunSubagentOptions<TOutputSchema extends TSchema | undefined = undefin
10
16
  models: MikanModels;
11
17
  workspaceDir: string;
12
18
  availableTools: AgentTool[];
13
- /**
14
- * The one seam through which a run's spend reaches its initiator (e.g. the
15
- * parent session's budget). Called exactly once per run with the final
16
- * totals — on every terminal path, including never-reject failures —
17
- * before the result is returned. Errors thrown here are logged and
18
- * swallowed to preserve the never-reject contract.
19
- */
20
- onUsage?: (usage: {
21
- tokens: number;
22
- costUsd: number;
23
- }) => void | Promise<void>;
19
+ /** Process-wide launch pool shared by tool and extension invocations. */
20
+ slots?: SubagentSlotPool;
21
+ /** Host-snapshotted parent transcript; never sourced from the public request. */
22
+ parentMessages?: AgentMessage[];
23
+ /** Usage attribution snapshotted when this invocation begins. */
24
+ onUsage?: (usage: SubagentUsage) => void | Promise<void>;
24
25
  }
25
26
  /**
26
27
  * Execute one non-recursive, fresh subagent run. Never rejects: every
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-runner.d.ts","sourceRoot":"","sources":["../../src/harness/subagent-runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,SAAS,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,KAAK,EAAE,GAAG,EAAoB,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAgHpB,UAAU,kBAAkB,CAAC,aAAa,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS;IAChF,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChF;AAiFD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,aAAa,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS,EACrF,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAQ9D"}
1
+ {"version":3,"file":"subagent-runner.d.ts","sourceRoot":"","sources":["../../src/harness/subagent-runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,KAAK,EAAE,GAAG,EAAoB,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKtF,eAAO,MAAM,uBAAuB;aAClC,QAAQ,EAAE,GAAG;aACb,UAAU,EAAE,EAAE;aACd,aAAa;CACL,CAAC;AAuGX,UAAU,kBAAkB,CAAC,aAAa,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS;IAChF,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,yEAAyE;IACzE,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,iFAAiF;IACjF,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,iEAAiE;IACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAyID;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,aAAa,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS,EACrF,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAQ9D"}
@@ -5,12 +5,13 @@ import { Value } from "@sinclair/typebox/value";
5
5
  import * as log from "../log.js";
6
6
  import { MikanAgentSession } from "./runner.js";
7
7
  import { SessionStore } from "./session-store.js";
8
+ import { unboundedSlotPool } from "../tools/subagent-slots.js";
8
9
  const subagentRunDepth = new AsyncLocalStorage();
9
10
  const DEFAULT_SYSTEM_PROMPT = "You are a focused subagent. Complete only the assigned task and return the result directly.";
10
- const DEFAULT_SUBAGENT_BUDGET = {
11
- maxTurns: 8,
12
- maxCostUsd: 0.5,
13
- maxDurationMs: 2 * 60 * 1000,
11
+ export const DEFAULT_SUBAGENT_BUDGET = {
12
+ maxTurns: 100,
13
+ maxCostUsd: 10,
14
+ maxDurationMs: 10 * 60 * 1000,
14
15
  };
15
16
  const SCHEMA_STRUCTURAL_KEYS = new Set([
16
17
  "type",
@@ -140,23 +141,71 @@ function selectTools(requested, available) {
140
141
  }
141
142
  return selected;
142
143
  }
143
- function formatTask(task, input) {
144
+ function formatTask(task, input, parentContext) {
144
145
  const trimmed = task.trim();
145
146
  if (!trimmed)
146
147
  throw new Error("api.subagent.run requires a non-empty task");
147
- if (input === undefined)
148
- return trimmed;
149
- let serialized;
150
- try {
151
- serialized = JSON.stringify(input, null, 2);
148
+ let formatted = trimmed;
149
+ if (input !== undefined) {
150
+ let serialized;
151
+ try {
152
+ serialized = JSON.stringify(input, null, 2);
153
+ }
154
+ catch (err) {
155
+ throw new Error(`api.subagent.run input must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
156
+ }
157
+ if (serialized === undefined)
158
+ throw new Error("api.subagent.run input must be JSON-serializable");
159
+ formatted = `${trimmed}\n\nInput:\n${serialized}`;
152
160
  }
153
- catch (err) {
154
- throw new Error(`api.subagent.run input must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
161
+ return parentContext ? `${parentContext}\n\n${formatted}` : formatted;
162
+ }
163
+ function messageText(message) {
164
+ if (message.role === "compactionSummary" || message.role === "branchSummary") {
165
+ return message.summary;
166
+ }
167
+ if (!("content" in message))
168
+ return "";
169
+ if (typeof message.content === "string")
170
+ return message.content;
171
+ if (!Array.isArray(message.content))
172
+ return "";
173
+ return message.content
174
+ .filter((part) => typeof part === "object" && part !== null && part.type === "text")
175
+ .map((part) => part.text)
176
+ .join("");
177
+ }
178
+ function normalizedParentContext(request, messages) {
179
+ if (!request.parentContext || !messages)
180
+ return undefined;
181
+ const recentTurns = request.parentContext.recentTurns ?? 3;
182
+ if (!Number.isInteger(recentTurns) || recentTurns < 1 || recentTurns > 8) {
183
+ throw new Error("api.subagent.run parentContext.recentTurns must be an integer from 1 to 8");
155
184
  }
156
- if (serialized === undefined) {
157
- throw new Error("api.subagent.run input must be JSON-serializable");
185
+ const conversation = messages.filter((message) => (message.role === "user" || message.role === "assistant") && messageText(message));
186
+ let first = conversation.length;
187
+ let users = 0;
188
+ while (first > 0 && users < recentTurns) {
189
+ first -= 1;
190
+ if (conversation[first].role === "user")
191
+ users += 1;
158
192
  }
159
- return `${trimmed}\n\nInput:\n${serialized}`;
193
+ const recent = conversation.slice(first);
194
+ const recentStart = recent[0] ? messages.indexOf(recent[0]) : messages.length;
195
+ let summary;
196
+ for (let index = recentStart - 1; index >= 0; index--) {
197
+ const message = messages[index];
198
+ if (message.role === "compactionSummary" || message.role === "branchSummary") {
199
+ summary = message;
200
+ break;
201
+ }
202
+ }
203
+ return [
204
+ "<parent_reference_context>",
205
+ summary ? `Earlier summary: ${messageText(summary)}` : "[Earlier parent context omitted]",
206
+ ...recent.map((message) => `${message.role === "user" ? "User" : "Assistant"}: ${messageText(message)}`),
207
+ "</parent_reference_context>",
208
+ ].join("\n");
160
209
  }
161
210
  function buildSystemPrompt(base, outputSchema) {
162
211
  const prompt = base?.trim() || DEFAULT_SYSTEM_PROMPT;
@@ -193,7 +242,7 @@ function assistantText(message) {
193
242
  * `onUsage` before the result is returned.
194
243
  */
195
244
  export async function runSubagent(options) {
196
- const result = await executeSubagentRun(options);
245
+ const result = await executeBoundedSubagentRun(options);
197
246
  try {
198
247
  await options.onUsage?.({ tokens: result.tokens, costUsd: result.costUsd });
199
248
  }
@@ -202,6 +251,36 @@ export async function runSubagent(options) {
202
251
  }
203
252
  return result;
204
253
  }
254
+ async function executeBoundedSubagentRun(options) {
255
+ const startedAt = Date.now();
256
+ let release;
257
+ try {
258
+ release = await (options.slots ?? unboundedSlotPool()).acquire(options.request.signal);
259
+ }
260
+ catch (err) {
261
+ if (err instanceof Error && err.name === "AbortError") {
262
+ return {
263
+ runId: randomUUID(),
264
+ status: "cancelled",
265
+ model: options.request.model ?? {
266
+ provider: options.defaultModel.provider,
267
+ id: options.defaultModel.id,
268
+ },
269
+ turns: 0,
270
+ tokens: 0,
271
+ costUsd: 0,
272
+ durationMs: Date.now() - startedAt,
273
+ };
274
+ }
275
+ throw err;
276
+ }
277
+ try {
278
+ return await executeSubagentRun(options);
279
+ }
280
+ finally {
281
+ release();
282
+ }
283
+ }
205
284
  async function executeSubagentRun(options) {
206
285
  const { request } = options;
207
286
  const runId = randomUUID();
@@ -229,7 +308,7 @@ async function executeSubagentRun(options) {
229
308
  : options.defaultModel;
230
309
  modelSpec = { provider: model.provider, id: model.id };
231
310
  const tools = selectTools(request.tools, options.availableTools);
232
- const task = formatTask(request.task, request.input);
311
+ const task = formatTask(request.task, request.input, normalizedParentContext(request, options.parentMessages));
233
312
  const budget = resolveBudget(request.budget);
234
313
  const session = new MikanAgentSession({
235
314
  systemPrompt: buildSystemPrompt(request.systemPrompt, request.outputSchema),
@@ -268,8 +347,15 @@ async function executeSubagentRun(options) {
268
347
  durationMs: Date.now() - startedAt,
269
348
  ...(text ? { text } : {}),
270
349
  };
271
- if (terminalSignal)
272
- return { ...base, status: terminalSignal };
350
+ if (terminalSignal) {
351
+ return {
352
+ ...base,
353
+ status: terminalSignal,
354
+ ...(terminalSignal === "timeout"
355
+ ? { error: `Subagent exceeded its ${budget.maxDurationMs}ms duration limit` }
356
+ : {}),
357
+ };
358
+ }
273
359
  if (stats.budgetExceededReason) {
274
360
  return {
275
361
  ...base,
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-runner.js","sourceRoot":"","sources":["../../src/harness/subagent-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { AgentMessage, AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, AssistantMessage, Model } from \"@earendil-works/pi-ai\";\nimport { Kind, Type, type TSchema } from \"@sinclair/typebox\";\nimport { Value } from \"@sinclair/typebox/value\";\nimport * as log from \"../log.js\";\nimport type { MikanModels } from \"./models.js\";\nimport { MikanAgentSession } from \"./runner.js\";\nimport { SessionStore } from \"./session-store.js\";\nimport type {\n SubagentModelSpec,\n SubagentRunOutput,\n SubagentRunRequest,\n SubagentRunResult,\n} from \"./types.js\";\n\nconst subagentRunDepth = new AsyncLocalStorage<number>();\nconst DEFAULT_SYSTEM_PROMPT =\n \"You are a focused subagent. Complete only the assigned task and return the result directly.\";\nconst DEFAULT_SUBAGENT_BUDGET = {\n maxTurns: 8,\n maxCostUsd: 0.5,\n maxDurationMs: 2 * 60 * 1000,\n} as const;\n\nconst SCHEMA_STRUCTURAL_KEYS = new Set([\n \"type\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"const\",\n \"anyOf\",\n \"oneOf\",\n \"allOf\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction schemaOptions(node: Record<string, unknown>): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (!SCHEMA_STRUCTURAL_KEYS.has(key)) options[key] = value;\n }\n if (isRecord(options.additionalProperties)) {\n options.additionalProperties = hydrateSchema(options.additionalProperties);\n }\n return options;\n}\n\n/**\n * outputSchema arrives over the subagent tool as plain JSON (tool-call\n * arguments never carry TypeBox's Kind symbol), but Value.Check dispatches\n * purely on schema[Kind] and throws ValueCheckUnknownTypeError for anything\n * without it. Hydrate plain JSON Schema into real TypeBox schema nodes so\n * validation runs instead of throwing; schemas built with TypeBox already\n * carry Kind and pass through untouched.\n *\n * Unsupported keywords ($ref, not, patternProperties, if/then/else) degrade to\n * a permissive Unknown — fail-open by design: outputSchema is advisory output\n * validation, not a security boundary.\n */\nfunction hydrateSchema(schema: unknown): TSchema {\n if (isRecord(schema) && Kind in schema) return schema as TSchema;\n if (!isRecord(schema)) return Type.Unknown();\n\n if (Array.isArray(schema.enum)) {\n const literals = schema.enum.filter(\n (value): value is string | number | boolean =>\n typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\",\n );\n return literals.length > 0\n ? Type.Union(literals.map((value) => Type.Literal(value)))\n : Type.Unknown();\n }\n if (\"const\" in schema) {\n const value = schema.const;\n return typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\"\n ? Type.Literal(value)\n : Type.Unknown();\n }\n if (Array.isArray(schema.anyOf)) return Type.Union(schema.anyOf.map(hydrateSchema));\n if (Array.isArray(schema.oneOf)) return Type.Union(schema.oneOf.map(hydrateSchema));\n if (Array.isArray(schema.allOf)) return Type.Intersect(schema.allOf.map(hydrateSchema));\n\n const type = Array.isArray(schema.type)\n ? schema.type\n : (schema.type ?? (schema.properties ? \"object\" : schema.items ? \"array\" : undefined));\n if (Array.isArray(type)) {\n return Type.Union(type.map((variant) => hydrateSchema({ ...schema, type: variant })));\n }\n\n const options = schemaOptions(schema);\n switch (type) {\n case \"object\": {\n const properties = isRecord(schema.properties) ? schema.properties : {};\n const required = new Set(Array.isArray(schema.required) ? schema.required : []);\n const props: Record<string, TSchema> = {};\n for (const [key, value] of Object.entries(properties)) {\n const hydrated = hydrateSchema(value);\n props[key] = required.has(key) ? hydrated : Type.Optional(hydrated);\n }\n return Type.Object(props, options);\n }\n case \"array\":\n return Type.Array(\n schema.items !== undefined ? hydrateSchema(schema.items) : Type.Unknown(),\n options,\n );\n case \"string\":\n return Type.String(options);\n case \"number\":\n return Type.Number(options);\n case \"integer\":\n return Type.Integer(options);\n case \"boolean\":\n return Type.Boolean(options);\n case \"null\":\n return Type.Null(options);\n default:\n return Type.Unknown(options);\n }\n}\n\ninterface RunSubagentOptions<TOutputSchema extends TSchema | undefined = undefined> {\n request: SubagentRunRequest<TOutputSchema>;\n defaultModel: Model<Api>;\n thinkingLevel: ThinkingLevel;\n models: MikanModels;\n workspaceDir: string;\n availableTools: AgentTool[];\n /**\n * The one seam through which a run's spend reaches its initiator (e.g. the\n * parent session's budget). Called exactly once per run with the final\n * totals — on every terminal path, including never-reject failures —\n * before the result is returned. Errors thrown here are logged and\n * swallowed to preserve the never-reject contract.\n */\n onUsage?: (usage: { tokens: number; costUsd: number }) => void | Promise<void>;\n}\n\nfunction resolveBudget(budget: RunSubagentOptions[\"request\"][\"budget\"]) {\n const resolved = { ...DEFAULT_SUBAGENT_BUDGET, ...budget };\n const positiveIntegerFields = [\n [\"maxTurns\", resolved.maxTurns],\n [\"maxTokens\", resolved.maxTokens],\n [\"maxDurationMs\", resolved.maxDurationMs],\n ] as const;\n for (const [name, value] of positiveIntegerFields) {\n if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {\n throw new Error(`api.subagent.run budget.${name} must be a positive integer`);\n }\n }\n if (!Number.isFinite(resolved.maxCostUsd) || resolved.maxCostUsd < 0) {\n throw new Error(\"api.subagent.run budget.maxCostUsd must be a non-negative number\");\n }\n return resolved;\n}\n\nfunction selectTools(requested: string[] | undefined, available: AgentTool[]): AgentTool[] {\n if (!requested || requested.length === 0) return [];\n const byName = new Map<string, AgentTool>();\n for (const tool of available) {\n if (!byName.has(tool.name)) byName.set(tool.name, tool);\n }\n const selected: AgentTool[] = [];\n for (const name of new Set(requested)) {\n const tool = byName.get(name);\n if (!tool) throw new Error(`Unknown or unavailable subagent tool: ${name}`);\n selected.push(tool);\n }\n return selected;\n}\n\nfunction formatTask(task: string, input: unknown): string {\n const trimmed = task.trim();\n if (!trimmed) throw new Error(\"api.subagent.run requires a non-empty task\");\n if (input === undefined) return trimmed;\n let serialized: string | undefined;\n try {\n serialized = JSON.stringify(input, null, 2);\n } catch (err) {\n throw new Error(\n `api.subagent.run input must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n if (serialized === undefined) {\n throw new Error(\"api.subagent.run input must be JSON-serializable\");\n }\n return `${trimmed}\\n\\nInput:\\n${serialized}`;\n}\n\nfunction buildSystemPrompt(base: string | undefined, outputSchema: TSchema | undefined): string {\n const prompt = base?.trim() || DEFAULT_SYSTEM_PROMPT;\n if (!outputSchema) return prompt;\n return [\n prompt,\n \"\",\n \"Return only one JSON value matching this JSON Schema. Do not use Markdown or code fences.\",\n JSON.stringify(outputSchema),\n ].join(\"\\n\");\n}\n\nfunction finalAssistant(messages: AgentMessage[]): AssistantMessage | undefined {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role === \"assistant\") return message;\n }\n return undefined;\n}\n\nfunction assistantText(message: AssistantMessage | undefined): string {\n if (!message) return \"\";\n return message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\");\n}\n\n/**\n * Execute one non-recursive, fresh subagent run. Never rejects: every\n * failure — including request validation — is a result with a terminal\n * status, so batch callers (`tasks` / `dag`) can never orphan in-flight\n * sibling runs on one bad request. The run's spend is reported through\n * `onUsage` before the result is returned.\n */\nexport async function runSubagent<TOutputSchema extends TSchema | undefined = undefined>(\n options: RunSubagentOptions<TOutputSchema>,\n): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>> {\n const result = await executeSubagentRun(options);\n try {\n await options.onUsage?.({ tokens: result.tokens, costUsd: result.costUsd });\n } catch (err) {\n log.logWarning(\"Subagent onUsage listener failed\", String(err));\n }\n return result;\n}\n\nasync function executeSubagentRun<TOutputSchema extends TSchema | undefined = undefined>(\n options: RunSubagentOptions<TOutputSchema>,\n): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>> {\n const { request } = options;\n const runId = randomUUID();\n const startedAt = Date.now();\n let modelSpec: SubagentModelSpec = request.model ?? {\n provider: options.defaultModel.provider,\n id: options.defaultModel.id,\n };\n let sessionRef: MikanAgentSession | undefined;\n let terminalSignal: \"cancelled\" | \"timeout\" | undefined;\n let timeout: NodeJS.Timeout | undefined;\n const abort = (reason: \"cancelled\" | \"timeout\") => {\n if (terminalSignal) return;\n terminalSignal = reason;\n sessionRef?.abort();\n };\n const onAbort = () => abort(\"cancelled\");\n\n try {\n if ((subagentRunDepth.getStore() ?? 0) >= 1) {\n throw new Error(\"Nested api.subagent.run calls are not allowed\");\n }\n const model = request.model\n ? options.models.resolve(request.model.provider, request.model.id)\n : options.defaultModel;\n modelSpec = { provider: model.provider, id: model.id };\n const tools = selectTools(request.tools, options.availableTools);\n const task = formatTask(request.task, request.input);\n const budget = resolveBudget(request.budget);\n const session = new MikanAgentSession({\n systemPrompt: buildSystemPrompt(request.systemPrompt, request.outputSchema),\n model,\n thinkingLevel: options.thinkingLevel,\n tools,\n models: options.models,\n sessionStore: SessionStore.inMemory(options.workspaceDir),\n settings: { compaction: { enabled: false } },\n });\n sessionRef = session;\n\n request.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (request.signal?.aborted) abort(\"cancelled\");\n timeout = setTimeout(() => abort(\"timeout\"), budget.maxDurationMs);\n timeout.unref();\n\n if (!terminalSignal) {\n await subagentRunDepth.run(1, () =>\n session.prompt(task, {\n budget: {\n maxLlmCalls: budget.maxTurns,\n maxTokens: budget.maxTokens,\n maxCostUsd: budget.maxCostUsd,\n maxDurationMs: budget.maxDurationMs,\n },\n }),\n );\n }\n\n const stats = session.getLastRunStats();\n const assistant = finalAssistant(session.messages);\n const text = assistantText(assistant);\n const base = {\n runId,\n model: modelSpec,\n turns: stats.llmCalls,\n tokens: stats.tokens,\n costUsd: stats.costUsd,\n durationMs: Date.now() - startedAt,\n ...(text ? { text } : {}),\n };\n\n if (terminalSignal) return { ...base, status: terminalSignal };\n if (stats.budgetExceededReason) {\n return {\n ...base,\n status: \"budget_exceeded\",\n error: stats.budgetExceededReason,\n };\n }\n if (assistant?.stopReason === \"error\") {\n return {\n ...base,\n status: \"failed\",\n error: assistant.errorMessage || \"Subagent failed\",\n };\n }\n if (!assistant) {\n return { ...base, status: \"failed\", error: \"Subagent produced no assistant response\" };\n }\n\n if (request.outputSchema) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return { ...base, status: \"invalid_output\", error: \"Subagent output is not valid JSON\" };\n }\n if (!Value.Check(hydrateSchema(request.outputSchema), parsed)) {\n return {\n ...base,\n status: \"invalid_output\",\n error: \"Subagent output does not match the requested schema\",\n };\n }\n return {\n ...base,\n status: \"completed\",\n output: parsed as SubagentRunOutput<TOutputSchema>,\n };\n }\n\n if (!text) {\n return { ...base, status: \"failed\", error: \"Subagent produced no text output\" };\n }\n return {\n ...base,\n status: \"completed\",\n output: text as SubagentRunOutput<TOutputSchema>,\n };\n } catch (err) {\n const stats = sessionRef?.getLastRunStats();\n return {\n runId,\n status: terminalSignal ?? \"failed\",\n model: modelSpec,\n turns: stats?.llmCalls ?? 0,\n tokens: stats?.tokens ?? 0,\n costUsd: stats?.costUsd ?? 0,\n durationMs: Date.now() - startedAt,\n error: err instanceof Error ? err.message : String(err),\n };\n } finally {\n if (timeout) clearTimeout(timeout);\n request.signal?.removeEventListener(\"abort\", onAbort);\n }\n}\n"]}
1
+ {"version":3,"file":"subagent-runner.js","sourceRoot":"","sources":["../../src/harness/subagent-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { AgentMessage, AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, AssistantMessage, Model } from \"@earendil-works/pi-ai\";\nimport { Kind, Type, type TSchema } from \"@sinclair/typebox\";\nimport { Value } from \"@sinclair/typebox/value\";\nimport * as log from \"../log.js\";\nimport type { MikanModels } from \"./models.js\";\nimport { MikanAgentSession } from \"./runner.js\";\nimport { SessionStore } from \"./session-store.js\";\nimport type {\n SubagentModelSpec,\n SubagentRunOutput,\n SubagentRunRequest,\n SubagentRunResult,\n SubagentUsage,\n} from \"./types.js\";\nimport { unboundedSlotPool, type SubagentSlotPool } from \"../tools/subagent-slots.js\";\n\nconst subagentRunDepth = new AsyncLocalStorage<number>();\nconst DEFAULT_SYSTEM_PROMPT =\n \"You are a focused subagent. Complete only the assigned task and return the result directly.\";\nexport const DEFAULT_SUBAGENT_BUDGET = {\n maxTurns: 100,\n maxCostUsd: 10,\n maxDurationMs: 10 * 60 * 1000,\n} as const;\n\nconst SCHEMA_STRUCTURAL_KEYS = new Set([\n \"type\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"const\",\n \"anyOf\",\n \"oneOf\",\n \"allOf\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction schemaOptions(node: Record<string, unknown>): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (!SCHEMA_STRUCTURAL_KEYS.has(key)) options[key] = value;\n }\n if (isRecord(options.additionalProperties)) {\n options.additionalProperties = hydrateSchema(options.additionalProperties);\n }\n return options;\n}\n\n/**\n * outputSchema arrives over the subagent tool as plain JSON (tool-call\n * arguments never carry TypeBox's Kind symbol), but Value.Check dispatches\n * purely on schema[Kind] and throws ValueCheckUnknownTypeError for anything\n * without it. Hydrate plain JSON Schema into real TypeBox schema nodes so\n * validation runs instead of throwing; schemas built with TypeBox already\n * carry Kind and pass through untouched.\n *\n * Unsupported keywords ($ref, not, patternProperties, if/then/else) degrade to\n * a permissive Unknown — fail-open by design: outputSchema is advisory output\n * validation, not a security boundary.\n */\nfunction hydrateSchema(schema: unknown): TSchema {\n if (isRecord(schema) && Kind in schema) return schema as TSchema;\n if (!isRecord(schema)) return Type.Unknown();\n\n if (Array.isArray(schema.enum)) {\n const literals = schema.enum.filter(\n (value): value is string | number | boolean =>\n typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\",\n );\n return literals.length > 0\n ? Type.Union(literals.map((value) => Type.Literal(value)))\n : Type.Unknown();\n }\n if (\"const\" in schema) {\n const value = schema.const;\n return typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\"\n ? Type.Literal(value)\n : Type.Unknown();\n }\n if (Array.isArray(schema.anyOf)) return Type.Union(schema.anyOf.map(hydrateSchema));\n if (Array.isArray(schema.oneOf)) return Type.Union(schema.oneOf.map(hydrateSchema));\n if (Array.isArray(schema.allOf)) return Type.Intersect(schema.allOf.map(hydrateSchema));\n\n const type = Array.isArray(schema.type)\n ? schema.type\n : (schema.type ?? (schema.properties ? \"object\" : schema.items ? \"array\" : undefined));\n if (Array.isArray(type)) {\n return Type.Union(type.map((variant) => hydrateSchema({ ...schema, type: variant })));\n }\n\n const options = schemaOptions(schema);\n switch (type) {\n case \"object\": {\n const properties = isRecord(schema.properties) ? schema.properties : {};\n const required = new Set(Array.isArray(schema.required) ? schema.required : []);\n const props: Record<string, TSchema> = {};\n for (const [key, value] of Object.entries(properties)) {\n const hydrated = hydrateSchema(value);\n props[key] = required.has(key) ? hydrated : Type.Optional(hydrated);\n }\n return Type.Object(props, options);\n }\n case \"array\":\n return Type.Array(\n schema.items !== undefined ? hydrateSchema(schema.items) : Type.Unknown(),\n options,\n );\n case \"string\":\n return Type.String(options);\n case \"number\":\n return Type.Number(options);\n case \"integer\":\n return Type.Integer(options);\n case \"boolean\":\n return Type.Boolean(options);\n case \"null\":\n return Type.Null(options);\n default:\n return Type.Unknown(options);\n }\n}\n\ninterface RunSubagentOptions<TOutputSchema extends TSchema | undefined = undefined> {\n request: SubagentRunRequest<TOutputSchema>;\n defaultModel: Model<Api>;\n thinkingLevel: ThinkingLevel;\n models: MikanModels;\n workspaceDir: string;\n availableTools: AgentTool[];\n /** Process-wide launch pool shared by tool and extension invocations. */\n slots?: SubagentSlotPool;\n /** Host-snapshotted parent transcript; never sourced from the public request. */\n parentMessages?: AgentMessage[];\n /** Usage attribution snapshotted when this invocation begins. */\n onUsage?: (usage: SubagentUsage) => void | Promise<void>;\n}\n\nfunction resolveBudget(budget: RunSubagentOptions[\"request\"][\"budget\"]) {\n const resolved = { ...DEFAULT_SUBAGENT_BUDGET, ...budget };\n const positiveIntegerFields = [\n [\"maxTurns\", resolved.maxTurns],\n [\"maxTokens\", resolved.maxTokens],\n [\"maxDurationMs\", resolved.maxDurationMs],\n ] as const;\n for (const [name, value] of positiveIntegerFields) {\n if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {\n throw new Error(`api.subagent.run budget.${name} must be a positive integer`);\n }\n }\n if (!Number.isFinite(resolved.maxCostUsd) || resolved.maxCostUsd < 0) {\n throw new Error(\"api.subagent.run budget.maxCostUsd must be a non-negative number\");\n }\n return resolved;\n}\n\nfunction selectTools(requested: string[] | undefined, available: AgentTool[]): AgentTool[] {\n if (!requested || requested.length === 0) return [];\n const byName = new Map<string, AgentTool>();\n for (const tool of available) {\n if (!byName.has(tool.name)) byName.set(tool.name, tool);\n }\n const selected: AgentTool[] = [];\n for (const name of new Set(requested)) {\n const tool = byName.get(name);\n if (!tool) throw new Error(`Unknown or unavailable subagent tool: ${name}`);\n selected.push(tool);\n }\n return selected;\n}\n\nfunction formatTask(task: string, input: unknown, parentContext?: string): string {\n const trimmed = task.trim();\n if (!trimmed) throw new Error(\"api.subagent.run requires a non-empty task\");\n let formatted = trimmed;\n if (input !== undefined) {\n let serialized: string | undefined;\n try {\n serialized = JSON.stringify(input, null, 2);\n } catch (err) {\n throw new Error(\n `api.subagent.run input must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n if (serialized === undefined)\n throw new Error(\"api.subagent.run input must be JSON-serializable\");\n formatted = `${trimmed}\\n\\nInput:\\n${serialized}`;\n }\n return parentContext ? `${parentContext}\\n\\n${formatted}` : formatted;\n}\n\nfunction messageText(message: AgentMessage): string {\n if (message.role === \"compactionSummary\" || message.role === \"branchSummary\") {\n return message.summary;\n }\n if (!(\"content\" in message)) return \"\";\n if (typeof message.content === \"string\") return message.content;\n if (!Array.isArray(message.content)) return \"\";\n return message.content\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n typeof part === \"object\" && part !== null && part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\");\n}\n\nfunction normalizedParentContext(\n request: SubagentRunRequest<TSchema | undefined>,\n messages: AgentMessage[] | undefined,\n): string | undefined {\n if (!request.parentContext || !messages) return undefined;\n const recentTurns = request.parentContext.recentTurns ?? 3;\n if (!Number.isInteger(recentTurns) || recentTurns < 1 || recentTurns > 8) {\n throw new Error(\"api.subagent.run parentContext.recentTurns must be an integer from 1 to 8\");\n }\n const conversation = messages.filter(\n (message) => (message.role === \"user\" || message.role === \"assistant\") && messageText(message),\n );\n let first = conversation.length;\n let users = 0;\n while (first > 0 && users < recentTurns) {\n first -= 1;\n if (conversation[first].role === \"user\") users += 1;\n }\n const recent = conversation.slice(first);\n const recentStart = recent[0] ? messages.indexOf(recent[0]) : messages.length;\n let summary: AgentMessage | undefined;\n for (let index = recentStart - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role === \"compactionSummary\" || message.role === \"branchSummary\") {\n summary = message;\n break;\n }\n }\n return [\n \"<parent_reference_context>\",\n summary ? `Earlier summary: ${messageText(summary)}` : \"[Earlier parent context omitted]\",\n ...recent.map(\n (message) => `${message.role === \"user\" ? \"User\" : \"Assistant\"}: ${messageText(message)}`,\n ),\n \"</parent_reference_context>\",\n ].join(\"\\n\");\n}\n\nfunction buildSystemPrompt(base: string | undefined, outputSchema: TSchema | undefined): string {\n const prompt = base?.trim() || DEFAULT_SYSTEM_PROMPT;\n if (!outputSchema) return prompt;\n return [\n prompt,\n \"\",\n \"Return only one JSON value matching this JSON Schema. Do not use Markdown or code fences.\",\n JSON.stringify(outputSchema),\n ].join(\"\\n\");\n}\n\nfunction finalAssistant(messages: AgentMessage[]): AssistantMessage | undefined {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role === \"assistant\") return message;\n }\n return undefined;\n}\n\nfunction assistantText(message: AssistantMessage | undefined): string {\n if (!message) return \"\";\n return message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\");\n}\n\n/**\n * Execute one non-recursive, fresh subagent run. Never rejects: every\n * failure — including request validation — is a result with a terminal\n * status, so batch callers (`tasks` / `dag`) can never orphan in-flight\n * sibling runs on one bad request. The run's spend is reported through\n * `onUsage` before the result is returned.\n */\nexport async function runSubagent<TOutputSchema extends TSchema | undefined = undefined>(\n options: RunSubagentOptions<TOutputSchema>,\n): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>> {\n const result = await executeBoundedSubagentRun(options);\n try {\n await options.onUsage?.({ tokens: result.tokens, costUsd: result.costUsd });\n } catch (err) {\n log.logWarning(\"Subagent onUsage listener failed\", String(err));\n }\n return result;\n}\n\nasync function executeBoundedSubagentRun<TOutputSchema extends TSchema | undefined = undefined>(\n options: RunSubagentOptions<TOutputSchema>,\n): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>> {\n const startedAt = Date.now();\n let release: (() => void) | undefined;\n try {\n release = await (options.slots ?? unboundedSlotPool()).acquire(options.request.signal);\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return {\n runId: randomUUID(),\n status: \"cancelled\",\n model: options.request.model ?? {\n provider: options.defaultModel.provider,\n id: options.defaultModel.id,\n },\n turns: 0,\n tokens: 0,\n costUsd: 0,\n durationMs: Date.now() - startedAt,\n };\n }\n throw err;\n }\n try {\n return await executeSubagentRun(options);\n } finally {\n release();\n }\n}\n\nasync function executeSubagentRun<TOutputSchema extends TSchema | undefined = undefined>(\n options: RunSubagentOptions<TOutputSchema>,\n): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>> {\n const { request } = options;\n const runId = randomUUID();\n const startedAt = Date.now();\n let modelSpec: SubagentModelSpec = request.model ?? {\n provider: options.defaultModel.provider,\n id: options.defaultModel.id,\n };\n let sessionRef: MikanAgentSession | undefined;\n let terminalSignal: \"cancelled\" | \"timeout\" | undefined;\n let timeout: NodeJS.Timeout | undefined;\n const abort = (reason: \"cancelled\" | \"timeout\") => {\n if (terminalSignal) return;\n terminalSignal = reason;\n sessionRef?.abort();\n };\n const onAbort = () => abort(\"cancelled\");\n\n try {\n if ((subagentRunDepth.getStore() ?? 0) >= 1) {\n throw new Error(\"Nested api.subagent.run calls are not allowed\");\n }\n const model = request.model\n ? options.models.resolve(request.model.provider, request.model.id)\n : options.defaultModel;\n modelSpec = { provider: model.provider, id: model.id };\n const tools = selectTools(request.tools, options.availableTools);\n const task = formatTask(\n request.task,\n request.input,\n normalizedParentContext(request, options.parentMessages),\n );\n const budget = resolveBudget(request.budget);\n const session = new MikanAgentSession({\n systemPrompt: buildSystemPrompt(request.systemPrompt, request.outputSchema),\n model,\n thinkingLevel: options.thinkingLevel,\n tools,\n models: options.models,\n sessionStore: SessionStore.inMemory(options.workspaceDir),\n settings: { compaction: { enabled: false } },\n });\n sessionRef = session;\n\n request.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (request.signal?.aborted) abort(\"cancelled\");\n timeout = setTimeout(() => abort(\"timeout\"), budget.maxDurationMs);\n timeout.unref();\n\n if (!terminalSignal) {\n await subagentRunDepth.run(1, () =>\n session.prompt(task, {\n budget: {\n maxLlmCalls: budget.maxTurns,\n maxTokens: budget.maxTokens,\n maxCostUsd: budget.maxCostUsd,\n maxDurationMs: budget.maxDurationMs,\n },\n }),\n );\n }\n\n const stats = session.getLastRunStats();\n const assistant = finalAssistant(session.messages);\n const text = assistantText(assistant);\n const base = {\n runId,\n model: modelSpec,\n turns: stats.llmCalls,\n tokens: stats.tokens,\n costUsd: stats.costUsd,\n durationMs: Date.now() - startedAt,\n ...(text ? { text } : {}),\n };\n\n if (terminalSignal) {\n return {\n ...base,\n status: terminalSignal,\n ...(terminalSignal === \"timeout\"\n ? { error: `Subagent exceeded its ${budget.maxDurationMs}ms duration limit` }\n : {}),\n };\n }\n if (stats.budgetExceededReason) {\n return {\n ...base,\n status: \"budget_exceeded\",\n error: stats.budgetExceededReason,\n };\n }\n if (assistant?.stopReason === \"error\") {\n return {\n ...base,\n status: \"failed\",\n error: assistant.errorMessage || \"Subagent failed\",\n };\n }\n if (!assistant) {\n return { ...base, status: \"failed\", error: \"Subagent produced no assistant response\" };\n }\n\n if (request.outputSchema) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return { ...base, status: \"invalid_output\", error: \"Subagent output is not valid JSON\" };\n }\n if (!Value.Check(hydrateSchema(request.outputSchema), parsed)) {\n return {\n ...base,\n status: \"invalid_output\",\n error: \"Subagent output does not match the requested schema\",\n };\n }\n return {\n ...base,\n status: \"completed\",\n output: parsed as SubagentRunOutput<TOutputSchema>,\n };\n }\n\n if (!text) {\n return { ...base, status: \"failed\", error: \"Subagent produced no text output\" };\n }\n return {\n ...base,\n status: \"completed\",\n output: text as SubagentRunOutput<TOutputSchema>,\n };\n } catch (err) {\n const stats = sessionRef?.getLastRunStats();\n return {\n runId,\n status: terminalSignal ?? \"failed\",\n model: modelSpec,\n turns: stats?.llmCalls ?? 0,\n tokens: stats?.tokens ?? 0,\n costUsd: stats?.costUsd ?? 0,\n durationMs: Date.now() - startedAt,\n error: err instanceof Error ? err.message : String(err),\n };\n } finally {\n if (timeout) clearTimeout(timeout);\n request.signal?.removeEventListener(\"abort\", onAbort);\n }\n}\n"]}