@geminixiang/mikan 1.0.0-beta.26 → 1.0.0-beta.28

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 (124) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/adapters/discord/bot.d.ts.map +1 -1
  4. package/dist/adapters/discord/bot.js +17 -3
  5. package/dist/adapters/discord/bot.js.map +1 -1
  6. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  7. package/dist/adapters/slack/blocks.js +49 -5
  8. package/dist/adapters/slack/blocks.js.map +1 -1
  9. package/dist/adapters/slack/bot.d.ts.map +1 -1
  10. package/dist/adapters/slack/bot.js +13 -1
  11. package/dist/adapters/slack/bot.js.map +1 -1
  12. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  13. package/dist/adapters/slack/response-lifecycle.js +14 -4
  14. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  15. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  16. package/dist/adapters/telegram/bot.js +24 -1
  17. package/dist/adapters/telegram/bot.js.map +1 -1
  18. package/dist/agent.d.ts.map +1 -1
  19. package/dist/agent.js +73 -0
  20. package/dist/agent.js.map +1 -1
  21. package/dist/cli/boot.d.ts +1 -1
  22. package/dist/cli/boot.d.ts.map +1 -1
  23. package/dist/cli/boot.js +7 -14
  24. package/dist/cli/boot.js.map +1 -1
  25. package/dist/commands/new.d.ts.map +1 -1
  26. package/dist/commands/new.js +8 -1
  27. package/dist/commands/new.js.map +1 -1
  28. package/dist/commands/types.d.ts +2 -1
  29. package/dist/commands/types.d.ts.map +1 -1
  30. package/dist/commands/types.js.map +1 -1
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +13 -40
  33. package/dist/config.js.map +1 -1
  34. package/dist/harness/extensions/registry.d.ts +19 -7
  35. package/dist/harness/extensions/registry.d.ts.map +1 -1
  36. package/dist/harness/extensions/registry.js +65 -6
  37. package/dist/harness/extensions/registry.js.map +1 -1
  38. package/dist/harness/extensions/types.d.ts +27 -6
  39. package/dist/harness/extensions/types.d.ts.map +1 -1
  40. package/dist/harness/extensions/types.js.map +1 -1
  41. package/dist/harness/index.d.ts +1 -1
  42. package/dist/harness/index.d.ts.map +1 -1
  43. package/dist/harness/index.js.map +1 -1
  44. package/dist/harness/runner.d.ts +8 -1
  45. package/dist/harness/runner.d.ts.map +1 -1
  46. package/dist/harness/runner.js +62 -11
  47. package/dist/harness/runner.js.map +1 -1
  48. package/dist/harness/session-store.d.ts +5 -4
  49. package/dist/harness/session-store.d.ts.map +1 -1
  50. package/dist/harness/session-store.js +120 -28
  51. package/dist/harness/session-store.js.map +1 -1
  52. package/dist/main.js +1 -51
  53. package/dist/main.js.map +1 -1
  54. package/dist/runtime/conversation-runtime.js +86 -4
  55. package/dist/runtime/conversation-runtime.js.map +1 -1
  56. package/dist/runtime/types.d.ts +2 -0
  57. package/dist/runtime/types.d.ts.map +1 -1
  58. package/dist/runtime/types.js.map +1 -1
  59. package/dist/sandbox/gondolin-bootstrap.d.ts +3 -17
  60. package/dist/sandbox/gondolin-bootstrap.d.ts.map +1 -1
  61. package/dist/sandbox/gondolin-bootstrap.js +2 -20
  62. package/dist/sandbox/gondolin-bootstrap.js.map +1 -1
  63. package/dist/sandbox/gondolin-contract.d.ts +3 -70
  64. package/dist/sandbox/gondolin-contract.d.ts.map +1 -1
  65. package/dist/sandbox/gondolin-contract.js +5 -89
  66. package/dist/sandbox/gondolin-contract.js.map +1 -1
  67. package/dist/sandbox/gondolin-recovery.d.ts +5 -18
  68. package/dist/sandbox/gondolin-recovery.d.ts.map +1 -1
  69. package/dist/sandbox/gondolin-recovery.js +5 -20
  70. package/dist/sandbox/gondolin-recovery.js.map +1 -1
  71. package/dist/sandbox/gondolin-worker-client.d.ts +8 -33
  72. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -1
  73. package/dist/sandbox/gondolin-worker-client.js +6 -7
  74. package/dist/sandbox/gondolin-worker-client.js.map +1 -1
  75. package/dist/sandbox/gondolin.d.ts +0 -5
  76. package/dist/sandbox/gondolin.d.ts.map +1 -1
  77. package/dist/sandbox/gondolin.js +14 -56
  78. package/dist/sandbox/gondolin.js.map +1 -1
  79. package/dist/sandbox/types.d.ts +1 -1
  80. package/dist/sandbox/types.d.ts.map +1 -1
  81. package/dist/sandbox/types.js.map +1 -1
  82. package/dist/sessions/chat-history-sync.d.ts.map +1 -1
  83. package/dist/sessions/chat-history-sync.js +14 -3
  84. package/dist/sessions/chat-history-sync.js.map +1 -1
  85. package/dist/tools/bash.d.ts.map +1 -1
  86. package/dist/tools/bash.js +1 -0
  87. package/dist/tools/bash.js.map +1 -1
  88. package/dist/tools/edit.d.ts.map +1 -1
  89. package/dist/tools/edit.js +1 -0
  90. package/dist/tools/edit.js.map +1 -1
  91. package/dist/tools/sandbox.d.ts.map +1 -1
  92. package/dist/tools/sandbox.js +1 -0
  93. package/dist/tools/sandbox.js.map +1 -1
  94. package/dist/tools/write.d.ts.map +1 -1
  95. package/dist/tools/write.js +1 -0
  96. package/dist/tools/write.js.map +1 -1
  97. package/dist/types.d.ts +6 -65
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js.map +1 -1
  100. package/package.json +1 -1
  101. package/dist/sandbox/gondolin-fleet.d.ts +0 -104
  102. package/dist/sandbox/gondolin-fleet.d.ts.map +0 -1
  103. package/dist/sandbox/gondolin-fleet.js +0 -330
  104. package/dist/sandbox/gondolin-fleet.js.map +0 -1
  105. package/dist/sandbox/gondolin-gateway.d.ts +0 -86
  106. package/dist/sandbox/gondolin-gateway.d.ts.map +0 -1
  107. package/dist/sandbox/gondolin-gateway.js +0 -407
  108. package/dist/sandbox/gondolin-gateway.js.map +0 -1
  109. package/dist/sandbox/gondolin-join.d.ts +0 -62
  110. package/dist/sandbox/gondolin-join.d.ts.map +0 -1
  111. package/dist/sandbox/gondolin-join.js +0 -261
  112. package/dist/sandbox/gondolin-join.js.map +0 -1
  113. package/dist/sandbox/gondolin-nfs-advisory.d.ts +0 -15
  114. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +0 -1
  115. package/dist/sandbox/gondolin-nfs-advisory.js +0 -60
  116. package/dist/sandbox/gondolin-nfs-advisory.js.map +0 -1
  117. package/dist/sandbox/gondolin-placement.d.ts +0 -30
  118. package/dist/sandbox/gondolin-placement.d.ts.map +0 -1
  119. package/dist/sandbox/gondolin-placement.js +0 -77
  120. package/dist/sandbox/gondolin-placement.js.map +0 -1
  121. package/dist/sandbox/gondolin-remote.d.ts +0 -70
  122. package/dist/sandbox/gondolin-remote.d.ts.map +0 -1
  123. package/dist/sandbox/gondolin-remote.js +0 -325
  124. package/dist/sandbox/gondolin-remote.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/harness/extensions/registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook registry and dispatch for mikan extensions.\n *\n * The registry collects hook handlers and contributed tools from activated\n * extensions and dispatches events from the harness runner. Handler failures\n * are logged and swallowed so a broken extension cannot take down a run.\n */\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport * as log from \"../../log.js\";\nimport type {\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n MikanHookMap,\n MikanHookName,\n ToolResultHookEvent,\n ToolResultHookResult,\n} from \"./types.js\";\n\nconst COMMAND_NAME_PATTERN = /^[a-z0-9_-]+$/i;\n\n/**\n * Parse `/name args…` slash-command text. Returns undefined when the text is\n * not a slash command with a valid name (`COMMAND_NAME_PATTERN`).\n */\nexport function parseCommandInput(text: string): { name: string; args: string } | undefined {\n const match = /^\\/(\\S+)(?:\\s+([\\s\\S]*))?$/.exec(text.trim());\n if (!match || !COMMAND_NAME_PATTERN.test(match[1])) return undefined;\n return { name: match[1], args: match[2]?.trim() ?? \"\" };\n}\n\ntype HookHandlers = {\n [T in MikanHookName]: Array<{ owner: string; handler: MikanHookMap[T] }>;\n};\n\nexport class ExtensionRegistry {\n private handlers: HookHandlers = {\n before_agent_start: [],\n tool_call: [],\n tool_result: [],\n message_end: [],\n turn_end: [],\n session_compact: [],\n agent_error: [],\n budget_exceeded: [],\n };\n private tools: AgentTool[] = [];\n private commands = new Map<string, { owner: string; command: ExtensionCommand }>();\n private disposers: Array<{ owner: string; disposer: ExtensionDisposer }> = [];\n\n register<T extends MikanHookName>(owner: string, hook: T, handler: MikanHookMap[T]): void {\n this.handlers[hook].push({ owner, handler });\n }\n\n registerTool(tool: AgentTool): void {\n this.tools.push(tool);\n }\n\n /**\n * Register an extension command. Invalid names throw (surfaces as an\n * activation error for that extension); a duplicate name is logged and\n * ignored so the first registration wins, mirroring hook isolation.\n */\n registerCommand(owner: string, command: ExtensionCommand): void {\n if (!COMMAND_NAME_PATTERN.test(command.name)) {\n throw new Error(`Invalid extension command name: ${JSON.stringify(command.name)}`);\n }\n const key = command.name.toLowerCase();\n const existing = this.commands.get(key);\n if (existing) {\n log.logWarning(\n `Extension command \"/${command.name}\" already registered by ${existing.owner}`,\n `ignoring registration from ${owner}`,\n );\n return;\n }\n this.commands.set(key, { owner, command });\n }\n\n registerDisposer(owner: string, disposer: ExtensionDisposer): void {\n this.disposers.push({ owner, disposer });\n }\n\n getContributedTools(): AgentTool[] {\n return [...this.tools];\n }\n\n /** Registered commands, for inventory surfaces. */\n getCommands(): ExtensionCommand[] {\n return [...this.commands.values()].map((entry) => entry.command);\n }\n\n /**\n * Run the handler for `/name`, if an extension registered it. Returns true\n * when a matching command exists — including when its handler threw (the\n * command was consumed; the error is logged and reported to the user).\n */\n async dispatchCommand(name: string, context: ExtensionCommandContext): Promise<boolean> {\n const entry = this.commands.get(name.toLowerCase());\n if (!entry) return false;\n try {\n await entry.command.handler(context);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`Extension command \"/${entry.command.name}\" failed (${entry.owner})`, message);\n try {\n await context.respond(`Command /${entry.command.name} failed: ${message}`);\n } catch {\n // The reply channel itself failed; the log line above is the record.\n }\n }\n return true;\n }\n\n /**\n * Run all registered disposers in reverse registration order (LIFO).\n * Disposer errors are logged and never propagate. Idempotent: disposers\n * run once and the list is cleared.\n */\n async dispose(): Promise<void> {\n const disposers = this.disposers;\n this.disposers = [];\n for (const { owner, disposer } of disposers.toReversed()) {\n try {\n await disposer();\n } catch (err) {\n log.logWarning(\n `Extension disposer failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n }\n\n hasHandlers(hook: MikanHookName): boolean {\n return this.handlers[hook].length > 0;\n }\n\n /**\n * Run handlers in registration order. Returns the first non-undefined\n * result. Handler errors are logged and skipped.\n */\n async emit<T extends MikanHookName>(\n hook: T,\n event: Parameters<MikanHookMap[T]>[0],\n ): Promise<Awaited<ReturnType<MikanHookMap[T]>> | undefined> {\n for (const { owner, handler } of this.handlers[hook]) {\n try {\n const result = await (handler as (input: unknown) => unknown)(event);\n if (result !== undefined) {\n return result as Awaited<ReturnType<MikanHookMap[T]>>;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"${hook}\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return undefined;\n }\n\n /**\n * Dispatch `before_agent_start` with merge semantics: `systemPrompt` and\n * `prompt` rewrites chain (each handler sees the event as rewritten by\n * earlier handlers), while `block` from ANY handler wins so a policy\n * extension cannot be shadowed by registration order. The first block's\n * reason is kept. Returns undefined when no handler changed anything.\n */\n async emitBeforeAgentStart(\n event: BeforeAgentStartHookEvent,\n ): Promise<BeforeAgentStartHookResult | undefined> {\n const chained: BeforeAgentStartHookEvent = { ...event };\n const merged: BeforeAgentStartHookResult = {};\n for (const { owner, handler } of this.handlers.before_agent_start) {\n try {\n const result = await handler(chained);\n if (!result) continue;\n if (result.systemPrompt !== undefined) {\n merged.systemPrompt = result.systemPrompt;\n chained.systemPrompt = result.systemPrompt;\n }\n if (result.prompt !== undefined) {\n merged.prompt = result.prompt;\n chained.prompt = result.prompt;\n }\n if (result.block && !merged.block) {\n merged.block = true;\n merged.reason = result.reason;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"before_agent_start\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return merged.systemPrompt !== undefined || merged.prompt !== undefined || merged.block\n ? merged\n : undefined;\n }\n\n /**\n * Dispatch `tool_result` with chaining semantics: each handler sees the\n * content/isError as rewritten by earlier handlers, so e.g. a redaction\n * extension processes the output of upstream rewriters instead of the\n * original. Returns the accumulated override, or undefined when no handler\n * changed anything.\n */\n async emitToolResult(event: ToolResultHookEvent): Promise<ToolResultHookResult | undefined> {\n const chained: ToolResultHookEvent = { ...event };\n const merged: ToolResultHookResult = {};\n for (const { owner, handler } of this.handlers.tool_result) {\n try {\n const result = await handler(chained);\n if (!result) continue;\n if (result.content !== undefined) {\n merged.content = result.content;\n chained.content = result.content;\n }\n if (result.isError !== undefined) {\n merged.isError = result.isError;\n chained.isError = result.isError;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"tool_result\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return merged.content !== undefined || merged.isError !== undefined ? merged : undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/harness/extensions/registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook registry and dispatch for mikan extensions.\n *\n * The registry collects hook handlers and contributed tools from activated\n * extensions and dispatches events from the harness runner. Handler failures\n * are logged and swallowed so a broken extension cannot take down a run.\n */\nimport type { AgentMessage, AgentTool } from \"@earendil-works/pi-agent-core\";\nimport * as log from \"../../log.js\";\nimport type {\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n ContextHookEvent,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n MessageEndHookEvent,\n MessageEndHookResult,\n MikanHookMap,\n MikanHookName,\n ToolResultHookEvent,\n ToolResultHookResult,\n} from \"./types.js\";\n\nconst COMMAND_NAME_PATTERN = /^[a-z0-9_-]+$/i;\n\n/**\n * Parse `/name args…` slash-command text. Returns undefined when the text is\n * not a slash command with a valid name (`COMMAND_NAME_PATTERN`).\n */\nexport function parseCommandInput(text: string): { name: string; args: string } | undefined {\n const match = /^\\/(\\S+)(?:\\s+([\\s\\S]*))?$/.exec(text.trim());\n if (!match || !COMMAND_NAME_PATTERN.test(match[1])) return undefined;\n return { name: match[1], args: match[2]?.trim() ?? \"\" };\n}\n\ntype HookHandlers = {\n [T in MikanHookName]: Array<{ owner: string; handler: MikanHookMap[T] }>;\n};\n\nexport class ExtensionRegistry {\n private handlers: HookHandlers = {\n before_agent_start: [],\n context: [],\n tool_call: [],\n tool_result: [],\n message_end: [],\n turn_end: [],\n session_compact: [],\n agent_error: [],\n budget_exceeded: [],\n };\n private tools: AgentTool[] = [];\n private commands = new Map<string, { owner: string; command: ExtensionCommand }>();\n private disposers: Array<{ owner: string; disposer: ExtensionDisposer }> = [];\n\n register<T extends MikanHookName>(owner: string, hook: T, handler: MikanHookMap[T]): void {\n this.handlers[hook].push({ owner, handler });\n }\n\n registerTool(tool: AgentTool): void {\n this.tools.push(tool);\n }\n\n /**\n * Register an extension command. Invalid names throw (surfaces as an\n * activation error for that extension); a duplicate name is logged and\n * ignored so the first registration wins, mirroring hook isolation.\n */\n registerCommand(owner: string, command: ExtensionCommand): void {\n if (!COMMAND_NAME_PATTERN.test(command.name)) {\n throw new Error(`Invalid extension command name: ${JSON.stringify(command.name)}`);\n }\n const key = command.name.toLowerCase();\n const existing = this.commands.get(key);\n if (existing) {\n log.logWarning(\n `Extension command \"/${command.name}\" already registered by ${existing.owner}`,\n `ignoring registration from ${owner}`,\n );\n return;\n }\n this.commands.set(key, { owner, command });\n }\n\n registerDisposer(owner: string, disposer: ExtensionDisposer): void {\n this.disposers.push({ owner, disposer });\n }\n\n getContributedTools(): AgentTool[] {\n return [...this.tools];\n }\n\n /** Registered commands, for inventory surfaces. */\n getCommands(): ExtensionCommand[] {\n return [...this.commands.values()].map((entry) => entry.command);\n }\n\n /**\n * Run the handler for `/name`, if an extension registered it. Returns true\n * when a matching command exists — including when its handler threw (the\n * command was consumed; the error is logged and reported to the user).\n */\n async dispatchCommand(name: string, context: ExtensionCommandContext): Promise<boolean> {\n const entry = this.commands.get(name.toLowerCase());\n if (!entry) return false;\n try {\n await entry.command.handler(context);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`Extension command \"/${entry.command.name}\" failed (${entry.owner})`, message);\n try {\n await context.respond(`Command /${entry.command.name} failed: ${message}`);\n } catch {\n // The reply channel itself failed; the log line above is the record.\n }\n }\n return true;\n }\n\n /**\n * Run all registered disposers in reverse registration order (LIFO).\n * Disposer errors are logged and never propagate. Idempotent: disposers\n * run once and the list is cleared.\n */\n async dispose(): Promise<void> {\n const disposers = this.disposers;\n this.disposers = [];\n for (const { owner, disposer } of disposers.toReversed()) {\n try {\n await disposer();\n } catch (err) {\n log.logWarning(\n `Extension disposer failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n }\n\n hasHandlers(hook: MikanHookName): boolean {\n return this.handlers[hook].length > 0;\n }\n\n /**\n * Run handlers in registration order. Returns the first non-undefined\n * result. Handler errors are logged and skipped.\n */\n async emit<T extends MikanHookName>(\n hook: T,\n event: Parameters<MikanHookMap[T]>[0],\n ): Promise<Awaited<ReturnType<MikanHookMap[T]>> | undefined> {\n for (const { owner, handler } of this.handlers[hook]) {\n try {\n const result = await (handler as (input: unknown) => unknown)(event);\n if (result !== undefined) {\n return result as Awaited<ReturnType<MikanHookMap[T]>>;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"${hook}\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return undefined;\n }\n\n /**\n * Dispatch `before_agent_start` with merge semantics: `systemPrompt` and\n * `prompt` rewrites chain (each handler sees the event as rewritten by\n * earlier handlers), while `block` from ANY handler wins so a policy\n * extension cannot be shadowed by registration order. The first block's\n * reason is kept. Returns undefined when no handler changed anything.\n */\n async emitBeforeAgentStart(\n event: BeforeAgentStartHookEvent,\n ): Promise<BeforeAgentStartHookResult | undefined> {\n const chained: BeforeAgentStartHookEvent = { ...event };\n const merged: BeforeAgentStartHookResult = {};\n for (const { owner, handler } of this.handlers.before_agent_start) {\n try {\n const result = await handler(chained);\n if (!result) continue;\n if (result.systemPrompt !== undefined) {\n merged.systemPrompt = result.systemPrompt;\n chained.systemPrompt = result.systemPrompt;\n }\n if (result.prompt !== undefined) {\n merged.prompt = result.prompt;\n chained.prompt = result.prompt;\n }\n if (result.block && !merged.block) {\n merged.block = true;\n merged.reason = result.reason;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"before_agent_start\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return merged.systemPrompt !== undefined || merged.prompt !== undefined || merged.block\n ? merged\n : undefined;\n }\n\n /**\n * Dispatch `context` with Pi-compatible chaining semantics. Handlers receive\n * a call-local clone, so in-place mutations and returned replacements affect\n * only this LLM call and never the canonical transcript.\n */\n async emitContext(event: ContextHookEvent): Promise<AgentMessage[]> {\n let messages = structuredClone(event.messages);\n for (const { owner, handler } of this.handlers.context) {\n try {\n const result = await handler({ ...event, messages });\n if (result?.messages) messages = result.messages;\n } catch (err) {\n log.logWarning(\n `Extension hook \"context\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return messages;\n }\n\n /**\n * Dispatch `message_end` with Pi-compatible chaining semantics. Each handler\n * sees the replacement from the previous handler. Role-changing replacements\n * are rejected because the agent lifecycle event role cannot be changed.\n */\n async emitMessageEnd(event: MessageEndHookEvent): Promise<MessageEndHookResult | undefined> {\n let message = event.message;\n let modified = false;\n for (const { owner, handler } of this.handlers.message_end) {\n try {\n const result = await handler({ ...event, message });\n if (!result?.message) continue;\n if (result.message.role !== message.role) {\n log.logWarning(\n `Extension hook \"message_end\" failed (${owner})`,\n \"message_end handlers must return a message with the same role\",\n );\n continue;\n }\n message = result.message;\n modified = true;\n } catch (err) {\n log.logWarning(\n `Extension hook \"message_end\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return modified ? { message } : undefined;\n }\n\n /**\n * Dispatch `tool_result` with chaining semantics: each handler sees content,\n * details, isError, and usage as rewritten by earlier handlers, so e.g. a\n * redaction extension processes the output of upstream rewriters instead of\n * the original. Returns the accumulated override, or undefined when no\n * handler changed anything.\n */\n async emitToolResult(event: ToolResultHookEvent): Promise<ToolResultHookResult | undefined> {\n const chained: ToolResultHookEvent = { ...event };\n const merged: ToolResultHookResult = {};\n for (const { owner, handler } of this.handlers.tool_result) {\n try {\n const result = await handler(chained);\n if (!result) continue;\n if (result.content !== undefined) {\n merged.content = result.content;\n chained.content = result.content;\n }\n if (result.details !== undefined) {\n merged.details = result.details;\n chained.details = result.details;\n }\n if (result.isError !== undefined) {\n merged.isError = result.isError;\n chained.isError = result.isError;\n }\n if (result.usage !== undefined) {\n merged.usage = result.usage;\n chained.usage = result.usage;\n }\n } catch (err) {\n log.logWarning(\n `Extension hook \"tool_result\" failed (${owner})`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return merged.content !== undefined ||\n merged.details !== undefined ||\n merged.isError !== undefined ||\n merged.usage !== undefined\n ? merged\n : undefined;\n }\n}\n"]}
@@ -18,13 +18,13 @@
18
18
  * ```
19
19
  *
20
20
  * Hooks run in registration order. Result semantics are per hook:
21
- * `tool_call` keeps v1's first-non-undefined-wins; `before_agent_start` and
22
- * `tool_result` chain — each handler sees the event as rewritten by earlier
23
- * handlers, and for `before_agent_start` a `block` from any handler wins.
24
- * Hook errors are logged and never crash a run.
21
+ * `tool_call` keeps v1's first-non-undefined-wins; `before_agent_start`,
22
+ * `context`, `message_end`, and `tool_result` chain — each handler sees the
23
+ * event as rewritten by earlier handlers, and for `before_agent_start` a
24
+ * `block` from any handler wins. Hook errors are logged and never crash a run.
25
25
  */
26
26
  import type { AgentMessage, AgentTool, ThinkingLevel } from "@earendil-works/pi-agent-core";
27
- import type { Api, ImageContent, Model, TextContent } from "@earendil-works/pi-ai";
27
+ import type { Api, ImageContent, Model, TextContent, Usage } from "@earendil-works/pi-ai";
28
28
  import type { TSchema } from "@sinclair/typebox";
29
29
  import type { EventFilePayload } from "../event-format.js";
30
30
  import type { MikanSkill } from "../skills.js";
@@ -77,24 +77,44 @@ export interface ToolCallHookResult {
77
77
  block?: boolean;
78
78
  reason?: string;
79
79
  }
80
+ export interface ContextHookEvent {
81
+ /** A call-local clone of the transcript about to be sent to the LLM. */
82
+ messages: AgentMessage[];
83
+ origin?: RunOrigin;
84
+ }
85
+ export interface ContextHookResult {
86
+ /** Replace the messages sent for this LLM call only. */
87
+ messages?: AgentMessage[];
88
+ }
80
89
  export interface ToolResultHookEvent {
81
90
  toolCallId: string;
82
91
  toolName: string;
83
92
  args: unknown;
84
93
  content: (TextContent | ImageContent)[];
94
+ details: unknown;
85
95
  isError: boolean;
96
+ /** Usage from the tool execution itself, if available. */
97
+ usage?: Usage;
86
98
  origin?: RunOrigin;
87
99
  }
88
100
  export interface ToolResultHookResult {
89
101
  /** Replace the tool result content sent back to the model (e.g. redaction). */
90
102
  content?: (TextContent | ImageContent)[];
103
+ /** Replace the structured tool result details. */
104
+ details?: unknown;
91
105
  /** Override the tool result error flag. */
92
106
  isError?: boolean;
107
+ /** Replace usage reported by the tool execution. */
108
+ usage?: Usage;
93
109
  }
94
110
  export interface MessageEndHookEvent {
95
111
  message: AgentMessage;
96
112
  origin?: RunOrigin;
97
113
  }
114
+ export interface MessageEndHookResult {
115
+ /** Replace the finalized message. The replacement must keep the original role. */
116
+ message?: AgentMessage;
117
+ }
98
118
  export interface TurnEndHookEvent {
99
119
  messages: AgentMessage[];
100
120
  origin?: RunOrigin;
@@ -122,8 +142,9 @@ export interface BudgetExceededHookEvent {
122
142
  export interface MikanHookMap {
123
143
  before_agent_start: (event: BeforeAgentStartHookEvent) => BeforeAgentStartHookResult | undefined | void | Promise<BeforeAgentStartHookResult | undefined | void>;
124
144
  tool_call: (event: ToolCallHookEvent) => ToolCallHookResult | undefined | void | Promise<ToolCallHookResult | undefined | void>;
145
+ context: (event: ContextHookEvent) => ContextHookResult | undefined | void | Promise<ContextHookResult | undefined | void>;
125
146
  tool_result: (event: ToolResultHookEvent) => ToolResultHookResult | undefined | void | Promise<ToolResultHookResult | undefined | void>;
126
- message_end: (event: MessageEndHookEvent) => void | Promise<void>;
147
+ message_end: (event: MessageEndHookEvent) => MessageEndHookResult | undefined | void | Promise<MessageEndHookResult | undefined | void>;
127
148
  turn_end: (event: TurnEndHookEvent) => void | Promise<void>;
128
149
  session_compact: (event: SessionCompactHookEvent) => void | Promise<void>;
129
150
  agent_error: (event: AgentErrorHookEvent) => void | Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/harness/extensions/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * mikan extension system, v1.\n *\n * Extensions are ES modules that export an `activate` function (either as\n * the default export or a named `activate` export, optionally wrapped in an\n * object that also carries a `name`). `activate` receives a\n * {@link MikanExtensionApi} and registers hooks and tools.\n *\n * ```js\n * // extensions/audit.mjs\n * export default function activate(api) {\n * api.on(\"tool_call\", ({ toolName, args }) => {\n * if (toolName === \"bash\" && String(args.command).includes(\"rm -rf /\")) {\n * return { block: true, reason: \"destructive command\" };\n * }\n * });\n * }\n * ```\n *\n * Hooks run in registration order. Result semantics are per hook:\n * `tool_call` keeps v1's first-non-undefined-wins; `before_agent_start` and\n * `tool_result` chain — each handler sees the event as rewritten by earlier\n * handlers, and for `before_agent_start` a `block` from any handler wins.\n * Hook errors are logged and never crash a run.\n */\nimport type { AgentMessage, AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, ImageContent, Model, TextContent } from \"@earendil-works/pi-ai\";\nimport type { TSchema } from \"@sinclair/typebox\";\nimport type { EventFilePayload } from \"../event-format.js\";\nimport type { MikanSkill } from \"../skills.js\";\nimport type {\n SubagentRunOutput,\n SubagentRunRequest,\n SubagentRunResult,\n CompactionEntry,\n} from \"../types.js\";\n\n/**\n * Platform provenance of the run a hook event belongs to. Interactive runs\n * carry the triggering message's identity (usable with `api.react` and for\n * per-user policy); autonomous runs (schedules/events) have no triggering\n * platform message, so only `kind` and `platform` are set.\n */\nexport interface RunOrigin {\n kind: \"interactive\" | \"event\";\n /** Platform adapter name serving this run (e.g. \"slack\"). */\n platform?: string;\n /** Platform message id of the triggering message; pass to `api.react`. */\n messageTs?: string;\n userId?: string;\n userName?: string;\n threadTs?: string;\n /** Attachments already downloaded to host paths (extensions run on host). */\n attachments?: { name: string; localPath: string }[];\n}\n\nexport interface BeforeAgentStartHookEvent {\n prompt: string;\n images?: ImageContent[];\n systemPrompt: string;\n origin?: RunOrigin;\n}\n\nexport interface BeforeAgentStartHookResult {\n /** Replace the system prompt for this turn. */\n systemPrompt?: string;\n /** Rewrite the user prompt for this turn. */\n prompt?: string;\n /** Block the turn entirely; the model is never called and nothing persists. */\n block?: boolean;\n /** Shown to the user when the turn is blocked. */\n reason?: string;\n}\n\nexport interface ToolCallHookEvent {\n toolCallId: string;\n toolName: string;\n args: unknown;\n origin?: RunOrigin;\n}\n\nexport interface ToolCallHookResult {\n /** Block the tool call; the model receives an error tool result instead. */\n block?: boolean;\n reason?: string;\n}\n\nexport interface ToolResultHookEvent {\n toolCallId: string;\n toolName: string;\n args: unknown;\n content: (TextContent | ImageContent)[];\n isError: boolean;\n origin?: RunOrigin;\n}\n\nexport interface ToolResultHookResult {\n /** Replace the tool result content sent back to the model (e.g. redaction). */\n content?: (TextContent | ImageContent)[];\n /** Override the tool result error flag. */\n isError?: boolean;\n}\n\nexport interface MessageEndHookEvent {\n message: AgentMessage;\n origin?: RunOrigin;\n}\n\nexport interface TurnEndHookEvent {\n messages: AgentMessage[];\n origin?: RunOrigin;\n}\n\nexport interface SessionCompactHookEvent {\n entry: CompactionEntry;\n reason: \"threshold\" | \"overflow\" | \"manual\";\n}\n\n/** A turn settled with an error after retries were exhausted (or none applied). */\nexport interface AgentErrorHookEvent {\n errorMessage: string;\n origin?: RunOrigin;\n}\n\n/** The run budget circuit breaker tripped and the run was aborted. */\nexport interface BudgetExceededHookEvent {\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 origin?: RunOrigin;\n}\n\n/** Map of hook names to handler signatures. */\nexport interface MikanHookMap {\n before_agent_start: (\n event: BeforeAgentStartHookEvent,\n ) =>\n | BeforeAgentStartHookResult\n | undefined\n | void\n | Promise<BeforeAgentStartHookResult | undefined | void>;\n tool_call: (\n event: ToolCallHookEvent,\n ) => ToolCallHookResult | undefined | void | Promise<ToolCallHookResult | undefined | void>;\n tool_result: (\n event: ToolResultHookEvent,\n ) => ToolResultHookResult | undefined | void | Promise<ToolResultHookResult | undefined | void>;\n message_end: (event: MessageEndHookEvent) => void | Promise<void>;\n turn_end: (event: TurnEndHookEvent) => void | Promise<void>;\n session_compact: (event: SessionCompactHookEvent) => void | Promise<void>;\n agent_error: (event: AgentErrorHookEvent) => void | Promise<void>;\n budget_exceeded: (event: BudgetExceededHookEvent) => void | Promise<void>;\n}\n\nexport type MikanHookName = keyof MikanHookMap;\n\n// ── v2: schedules ────────────────────────────────────────────────────────────\n\n/**\n * A schedule contributed by an extension. Fires an autonomous agent run in\n * this conversation with `text` as the task prompt (the run does not inherit\n * conversation history — write `text` self-contained).\n */\nexport type ExtensionScheduleSpec =\n | {\n type: \"periodic\";\n /** Cron expression (croner syntax). */\n schedule: string;\n /** IANA timezone, e.g. \"Asia/Taipei\". */\n timezone: string;\n text: string;\n /** Target platform; optional when only one platform is running. */\n platform?: string;\n }\n | {\n type: \"one-shot\";\n /** ISO 8601 timestamp with offset. */\n at: string;\n text: string;\n platform?: string;\n };\n\nexport interface ExtensionScheduleInfo {\n /** Extension-chosen schedule name. */\n name: string;\n spec: ExtensionScheduleSpec;\n}\n\n/**\n * Event-file payload the harness hands to the embedder's schedule store —\n * the canonical event-file shape owned by the event-format module.\n * `platform` may be omitted when the embedder runs a single platform.\n * `immediate` backs `api.triggerRun` — the event fires as soon as the\n * embedder's watcher picks it up.\n */\nexport type ExtensionSchedulePayload = EventFilePayload;\n\n// ── v3: commands and lifecycle ───────────────────────────────────────────────\n\n/** Cleanup callback run when the harness instance owning the extension is discarded. */\nexport type ExtensionDisposer = () => void | Promise<void>;\n\n/** Context handed to an extension command handler for one invocation. */\nexport interface ExtensionCommandContext {\n /** Text after the command name, trimmed (\"\" when none). */\n args: string;\n conversationId: string;\n userId?: string;\n userName?: string;\n /** Reply in the conversation the command was sent from. */\n respond(text: string): Promise<void>;\n}\n\n/**\n * A chat command contributed by an extension (`/name args…`). Dispatched\n * deterministically by the embedder — no model call, no agent-session entry\n * (the triggering message still syncs to chat history).\n * Built-in commands always win over extension commands of the same name.\n */\nexport interface ExtensionCommand {\n /** Command name without the leading slash; `[a-z0-9_-]+`, case-insensitive match. */\n name: string;\n /** One-line description for inventory surfaces. */\n description?: string;\n handler: (context: ExtensionCommandContext) => void | Promise<void>;\n}\n\nexport interface SubagentApi {\n /**\n * Run one fresh subagent and return its result to the extension. The\n * subagent has no conversation history, receives no tools by default, and\n * cannot recursively start another subagent run. Never rejects: every\n * failure, including request validation, resolves to a result with a\n * terminal status.\n */\n run<TOutputSchema extends TSchema | undefined = undefined>(\n request: SubagentRunRequest<TOutputSchema>,\n ): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>>;\n}\n\n// ── v2: embedder-injected services ───────────────────────────────────────────\n\n/**\n * Persistence backend for extension schedules, injected by the embedder\n * (mikan backs this with event files watched by its EventsWatcher).\n * Filenames are fully qualified by the harness (`ext-<slug>-<name>.json`).\n */\nexport interface ExtensionScheduleStore {\n write(filename: string, payload: ExtensionSchedulePayload): Promise<void>;\n delete(filename: string): Promise<boolean>;\n /** List all schedule files, harness filters by ownership prefix. */\n list(): Promise<Array<{ filename: string; payload: ExtensionSchedulePayload }>>;\n}\n\n/**\n * Host services injected into extensions by the embedder. All fields are\n * optional: the corresponding api surface throws an informative error when\n * the running context does not provide the service.\n */\nexport interface ExtensionHostServices {\n /** State dir for per-extension data dirs; defaults to `~/.mikan`. */\n stateDir?: string;\n /** Schedule persistence; enables `api.schedules`. */\n scheduleStore?: ExtensionScheduleStore;\n /** Post a message to a conversation without an agent run; enables `api.notify`. */\n postMessage?: (conversationId: string, text: string, platform?: string) => Promise<void>;\n /** Add an emoji reaction to a message; enables `api.react`. */\n addReaction?: (\n conversationId: string,\n messageTs: string,\n emoji: string,\n platform?: string,\n ) => Promise<void>;\n /** Upload a host file into a conversation; enables `api.uploadFile`. */\n uploadFile?: (\n conversationId: string,\n filePath: string,\n title?: string,\n platform?: string,\n ) => Promise<void>;\n /** Resolve read-only secrets for an extension slug; enables `api.secrets`. */\n resolveSecrets?: (slug: string) => Record<string, string>;\n /** Run a fresh isolated subagent; enables `api.subagent`. */\n runSubagent?: <TOutputSchema extends TSchema | undefined = undefined>(\n request: SubagentRunRequest<TOutputSchema>,\n contributedTools: AgentTool[],\n ) => Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>>;\n}\n\n// ── v2: manifest ─────────────────────────────────────────────────────────────\n\n/**\n * Optional `manifest.json` next to a directory-form extension's entrypoint.\n * `name` is the display name only; the slug (data dir, secrets, schedule\n * ownership) always derives from the install path so identity is\n * admin-controlled and stable across manifest edits.\n */\nexport interface ExtensionManifest {\n name?: string;\n version?: string;\n description?: string;\n}\n\n/** API handed to an extension's `activate` function. */\nexport interface MikanExtensionApi {\n /** Register a hook handler. */\n on<T extends MikanHookName>(hook: T, handler: MikanHookMap[T]): void;\n /** Contribute an additional agent tool. */\n registerTool(tool: AgentTool): void;\n /**\n * Contribute a chat command (`/name`). Dispatched without a model call;\n * built-in commands and earlier registrations of the same name win.\n */\n registerCommand(command: ExtensionCommand): void;\n /**\n * Register cleanup to run when this harness instance is discarded\n * (`/pi-new`, session eviction, shutdown). Alternative to returning a\n * disposer from `activate`. Disposers run in reverse registration order.\n */\n onDispose(disposer: ExtensionDisposer): void;\n /** Extension-scoped logging that lands in mikan's structured log. */\n log(message: string): void;\n /** Context about the conversation this harness instance serves. */\n readonly context: {\n readonly conversationId: string;\n readonly workspaceDir: string;\n readonly model: Model<Api>;\n readonly thinkingLevel: ThinkingLevel;\n };\n /**\n * Host-only filesystem locations owned by this extension (never mounted\n * into sandbox containers). Which one you use is a declaration: `dataDir`\n * for conversation-scoped state (the safe default — isolation for free),\n * `sharedDataDir` for deliberately cross-conversation state (you own tenant\n * partitioning and concurrency). See `LAYOUT.md`.\n */\n readonly paths: {\n /**\n * This conversation's private data directory\n * (`conversations/<conversationId>/extension-data/<slug>`), created on\n * first access. Default choice: co-located with the conversation, so it\n * disappears when the conversation is deleted.\n */\n readonly dataDir: string;\n /**\n * Data shared across all conversations this extension serves\n * (`global/extension-data/<slug>`), created on first access. Explicit\n * opt-in for multi-conversation applications (e.g. a PM tool with\n * cross-channel views); key rows by conversation id yourself.\n */\n readonly sharedDataDir: string;\n };\n /**\n * Read-only secrets from the embedder's vault\n * (mikan: `<stateDir>/vaults/extensions/<slug>/env`).\n */\n readonly secrets: {\n get(key: string): string | undefined;\n /** Secret names only, never values. */\n list(): string[];\n };\n /**\n * Named schedules owned by this extension + conversation. Backed by the\n * embedder's schedule store; in mikan these become event files that fire\n * autonomous agent runs (hot-reloaded, persisted across restarts).\n */\n readonly schedules: {\n /** Create or replace a named schedule. */\n upsert(name: string, spec: ExtensionScheduleSpec): Promise<void>;\n /** Delete a named schedule. Returns false when it did not exist. */\n delete(name: string): Promise<boolean>;\n /** Schedules owned by this extension in this conversation. */\n list(): Promise<ExtensionScheduleInfo[]>;\n };\n /** Fresh isolated subagent runs. */\n readonly subagent: SubagentApi;\n /**\n * Post text into a conversation without triggering an agent run. Defaults\n * to this conversation; pass `conversationId` to post elsewhere (pairs\n * with `sharedDataDir` for cross-conversation applications). Available\n * when the embedder provides platform messaging.\n */\n notify(text: string, options?: { conversationId?: string }): Promise<void>;\n /**\n * Add an emoji reaction to a message in this conversation. `messageTs` is\n * the platform message id the extension read from an event (see\n * `RunOrigin.messageTs`); `emoji` is a short name without colons.\n * Available when the embedder provides reaction support.\n */\n react(messageTs: string, emoji: string): Promise<void>;\n /**\n * Upload a host-side file into this conversation without an agent run.\n * Available when the embedder provides file uploads for the platform.\n */\n uploadFile(filePath: string, title?: string): Promise<void>;\n /**\n * Fire an autonomous agent run in this conversation as soon as possible.\n * Like a schedule, the run does not inherit conversation history — write\n * `text` self-contained. Backed by the embedder's schedule store.\n */\n triggerRun(text: string): Promise<void>;\n}\n\nexport type MikanExtensionActivate = (\n api: MikanExtensionApi,\n) => void | ExtensionDisposer | Promise<void | ExtensionDisposer>;\n\nexport interface MikanExtensionModule {\n name?: string;\n activate: MikanExtensionActivate;\n}\n\nexport interface LoadedExtension {\n name: string;\n path: string;\n /** Filesystem-safe identifier used for data dirs, secrets, and schedules. */\n slug: string;\n version?: string;\n description?: string;\n /** Skills discovered under the extension's `skills/` directory. */\n skills: MikanSkill[];\n}\n\nexport interface ExtensionLoadError {\n path: string;\n error: string;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/harness/extensions/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * mikan extension system, v1.\n *\n * Extensions are ES modules that export an `activate` function (either as\n * the default export or a named `activate` export, optionally wrapped in an\n * object that also carries a `name`). `activate` receives a\n * {@link MikanExtensionApi} and registers hooks and tools.\n *\n * ```js\n * // extensions/audit.mjs\n * export default function activate(api) {\n * api.on(\"tool_call\", ({ toolName, args }) => {\n * if (toolName === \"bash\" && String(args.command).includes(\"rm -rf /\")) {\n * return { block: true, reason: \"destructive command\" };\n * }\n * });\n * }\n * ```\n *\n * Hooks run in registration order. Result semantics are per hook:\n * `tool_call` keeps v1's first-non-undefined-wins; `before_agent_start`,\n * `context`, `message_end`, and `tool_result` chain — each handler sees the\n * event as rewritten by earlier handlers, and for `before_agent_start` a\n * `block` from any handler wins. Hook errors are logged and never crash a run.\n */\nimport type { AgentMessage, AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, ImageContent, Model, TextContent, Usage } from \"@earendil-works/pi-ai\";\nimport type { TSchema } from \"@sinclair/typebox\";\nimport type { EventFilePayload } from \"../event-format.js\";\nimport type { MikanSkill } from \"../skills.js\";\nimport type {\n SubagentRunOutput,\n SubagentRunRequest,\n SubagentRunResult,\n CompactionEntry,\n} from \"../types.js\";\n\n/**\n * Platform provenance of the run a hook event belongs to. Interactive runs\n * carry the triggering message's identity (usable with `api.react` and for\n * per-user policy); autonomous runs (schedules/events) have no triggering\n * platform message, so only `kind` and `platform` are set.\n */\nexport interface RunOrigin {\n kind: \"interactive\" | \"event\";\n /** Platform adapter name serving this run (e.g. \"slack\"). */\n platform?: string;\n /** Platform message id of the triggering message; pass to `api.react`. */\n messageTs?: string;\n userId?: string;\n userName?: string;\n threadTs?: string;\n /** Attachments already downloaded to host paths (extensions run on host). */\n attachments?: { name: string; localPath: string }[];\n}\n\nexport interface BeforeAgentStartHookEvent {\n prompt: string;\n images?: ImageContent[];\n systemPrompt: string;\n origin?: RunOrigin;\n}\n\nexport interface BeforeAgentStartHookResult {\n /** Replace the system prompt for this turn. */\n systemPrompt?: string;\n /** Rewrite the user prompt for this turn. */\n prompt?: string;\n /** Block the turn entirely; the model is never called and nothing persists. */\n block?: boolean;\n /** Shown to the user when the turn is blocked. */\n reason?: string;\n}\n\nexport interface ToolCallHookEvent {\n toolCallId: string;\n toolName: string;\n args: unknown;\n origin?: RunOrigin;\n}\n\nexport interface ToolCallHookResult {\n /** Block the tool call; the model receives an error tool result instead. */\n block?: boolean;\n reason?: string;\n}\n\nexport interface ContextHookEvent {\n /** A call-local clone of the transcript about to be sent to the LLM. */\n messages: AgentMessage[];\n origin?: RunOrigin;\n}\n\nexport interface ContextHookResult {\n /** Replace the messages sent for this LLM call only. */\n messages?: AgentMessage[];\n}\n\nexport interface ToolResultHookEvent {\n toolCallId: string;\n toolName: string;\n args: unknown;\n content: (TextContent | ImageContent)[];\n details: unknown;\n isError: boolean;\n /** Usage from the tool execution itself, if available. */\n usage?: Usage;\n origin?: RunOrigin;\n}\n\nexport interface ToolResultHookResult {\n /** Replace the tool result content sent back to the model (e.g. redaction). */\n content?: (TextContent | ImageContent)[];\n /** Replace the structured tool result details. */\n details?: unknown;\n /** Override the tool result error flag. */\n isError?: boolean;\n /** Replace usage reported by the tool execution. */\n usage?: Usage;\n}\n\nexport interface MessageEndHookEvent {\n message: AgentMessage;\n origin?: RunOrigin;\n}\n\nexport interface MessageEndHookResult {\n /** Replace the finalized message. The replacement must keep the original role. */\n message?: AgentMessage;\n}\n\nexport interface TurnEndHookEvent {\n messages: AgentMessage[];\n origin?: RunOrigin;\n}\n\nexport interface SessionCompactHookEvent {\n entry: CompactionEntry;\n reason: \"threshold\" | \"overflow\" | \"manual\";\n}\n\n/** A turn settled with an error after retries were exhausted (or none applied). */\nexport interface AgentErrorHookEvent {\n errorMessage: string;\n origin?: RunOrigin;\n}\n\n/** The run budget circuit breaker tripped and the run was aborted. */\nexport interface BudgetExceededHookEvent {\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 origin?: RunOrigin;\n}\n\n/** Map of hook names to handler signatures. */\nexport interface MikanHookMap {\n before_agent_start: (\n event: BeforeAgentStartHookEvent,\n ) =>\n | BeforeAgentStartHookResult\n | undefined\n | void\n | Promise<BeforeAgentStartHookResult | undefined | void>;\n tool_call: (\n event: ToolCallHookEvent,\n ) => ToolCallHookResult | undefined | void | Promise<ToolCallHookResult | undefined | void>;\n context: (\n event: ContextHookEvent,\n ) => ContextHookResult | undefined | void | Promise<ContextHookResult | undefined | void>;\n tool_result: (\n event: ToolResultHookEvent,\n ) => ToolResultHookResult | undefined | void | Promise<ToolResultHookResult | undefined | void>;\n message_end: (\n event: MessageEndHookEvent,\n ) => MessageEndHookResult | undefined | void | Promise<MessageEndHookResult | undefined | void>;\n turn_end: (event: TurnEndHookEvent) => void | Promise<void>;\n session_compact: (event: SessionCompactHookEvent) => void | Promise<void>;\n agent_error: (event: AgentErrorHookEvent) => void | Promise<void>;\n budget_exceeded: (event: BudgetExceededHookEvent) => void | Promise<void>;\n}\n\nexport type MikanHookName = keyof MikanHookMap;\n\n// ── v2: schedules ────────────────────────────────────────────────────────────\n\n/**\n * A schedule contributed by an extension. Fires an autonomous agent run in\n * this conversation with `text` as the task prompt (the run does not inherit\n * conversation history — write `text` self-contained).\n */\nexport type ExtensionScheduleSpec =\n | {\n type: \"periodic\";\n /** Cron expression (croner syntax). */\n schedule: string;\n /** IANA timezone, e.g. \"Asia/Taipei\". */\n timezone: string;\n text: string;\n /** Target platform; optional when only one platform is running. */\n platform?: string;\n }\n | {\n type: \"one-shot\";\n /** ISO 8601 timestamp with offset. */\n at: string;\n text: string;\n platform?: string;\n };\n\nexport interface ExtensionScheduleInfo {\n /** Extension-chosen schedule name. */\n name: string;\n spec: ExtensionScheduleSpec;\n}\n\n/**\n * Event-file payload the harness hands to the embedder's schedule store —\n * the canonical event-file shape owned by the event-format module.\n * `platform` may be omitted when the embedder runs a single platform.\n * `immediate` backs `api.triggerRun` — the event fires as soon as the\n * embedder's watcher picks it up.\n */\nexport type ExtensionSchedulePayload = EventFilePayload;\n\n// ── v3: commands and lifecycle ───────────────────────────────────────────────\n\n/** Cleanup callback run when the harness instance owning the extension is discarded. */\nexport type ExtensionDisposer = () => void | Promise<void>;\n\n/** Context handed to an extension command handler for one invocation. */\nexport interface ExtensionCommandContext {\n /** Text after the command name, trimmed (\"\" when none). */\n args: string;\n conversationId: string;\n userId?: string;\n userName?: string;\n /** Reply in the conversation the command was sent from. */\n respond(text: string): Promise<void>;\n}\n\n/**\n * A chat command contributed by an extension (`/name args…`). Dispatched\n * deterministically by the embedder — no model call, no agent-session entry\n * (the triggering message still syncs to chat history).\n * Built-in commands always win over extension commands of the same name.\n */\nexport interface ExtensionCommand {\n /** Command name without the leading slash; `[a-z0-9_-]+`, case-insensitive match. */\n name: string;\n /** One-line description for inventory surfaces. */\n description?: string;\n handler: (context: ExtensionCommandContext) => void | Promise<void>;\n}\n\nexport interface SubagentApi {\n /**\n * Run one fresh subagent and return its result to the extension. The\n * subagent has no conversation history, receives no tools by default, and\n * cannot recursively start another subagent run. Never rejects: every\n * failure, including request validation, resolves to a result with a\n * terminal status.\n */\n run<TOutputSchema extends TSchema | undefined = undefined>(\n request: SubagentRunRequest<TOutputSchema>,\n ): Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>>;\n}\n\n// ── v2: embedder-injected services ───────────────────────────────────────────\n\n/**\n * Persistence backend for extension schedules, injected by the embedder\n * (mikan backs this with event files watched by its EventsWatcher).\n * Filenames are fully qualified by the harness (`ext-<slug>-<name>.json`).\n */\nexport interface ExtensionScheduleStore {\n write(filename: string, payload: ExtensionSchedulePayload): Promise<void>;\n delete(filename: string): Promise<boolean>;\n /** List all schedule files, harness filters by ownership prefix. */\n list(): Promise<Array<{ filename: string; payload: ExtensionSchedulePayload }>>;\n}\n\n/**\n * Host services injected into extensions by the embedder. All fields are\n * optional: the corresponding api surface throws an informative error when\n * the running context does not provide the service.\n */\nexport interface ExtensionHostServices {\n /** State dir for per-extension data dirs; defaults to `~/.mikan`. */\n stateDir?: string;\n /** Schedule persistence; enables `api.schedules`. */\n scheduleStore?: ExtensionScheduleStore;\n /** Post a message to a conversation without an agent run; enables `api.notify`. */\n postMessage?: (conversationId: string, text: string, platform?: string) => Promise<void>;\n /** Add an emoji reaction to a message; enables `api.react`. */\n addReaction?: (\n conversationId: string,\n messageTs: string,\n emoji: string,\n platform?: string,\n ) => Promise<void>;\n /** Upload a host file into a conversation; enables `api.uploadFile`. */\n uploadFile?: (\n conversationId: string,\n filePath: string,\n title?: string,\n platform?: string,\n ) => Promise<void>;\n /** Resolve read-only secrets for an extension slug; enables `api.secrets`. */\n resolveSecrets?: (slug: string) => Record<string, string>;\n /** Run a fresh isolated subagent; enables `api.subagent`. */\n runSubagent?: <TOutputSchema extends TSchema | undefined = undefined>(\n request: SubagentRunRequest<TOutputSchema>,\n contributedTools: AgentTool[],\n ) => Promise<SubagentRunResult<SubagentRunOutput<TOutputSchema>>>;\n}\n\n// ── v2: manifest ─────────────────────────────────────────────────────────────\n\n/**\n * Optional `manifest.json` next to a directory-form extension's entrypoint.\n * `name` is the display name only; the slug (data dir, secrets, schedule\n * ownership) always derives from the install path so identity is\n * admin-controlled and stable across manifest edits.\n */\nexport interface ExtensionManifest {\n name?: string;\n version?: string;\n description?: string;\n}\n\n/** API handed to an extension's `activate` function. */\nexport interface MikanExtensionApi {\n /** Register a hook handler. */\n on<T extends MikanHookName>(hook: T, handler: MikanHookMap[T]): void;\n /** Contribute an additional agent tool. */\n registerTool(tool: AgentTool): void;\n /**\n * Contribute a chat command (`/name`). Dispatched without a model call;\n * built-in commands and earlier registrations of the same name win.\n */\n registerCommand(command: ExtensionCommand): void;\n /**\n * Register cleanup to run when this harness instance is discarded\n * (`/pi-new`, session eviction, shutdown). Alternative to returning a\n * disposer from `activate`. Disposers run in reverse registration order.\n */\n onDispose(disposer: ExtensionDisposer): void;\n /** Extension-scoped logging that lands in mikan's structured log. */\n log(message: string): void;\n /** Context about the conversation this harness instance serves. */\n readonly context: {\n readonly conversationId: string;\n readonly workspaceDir: string;\n readonly model: Model<Api>;\n readonly thinkingLevel: ThinkingLevel;\n };\n /**\n * Host-only filesystem locations owned by this extension (never mounted\n * into sandbox containers). Which one you use is a declaration: `dataDir`\n * for conversation-scoped state (the safe default — isolation for free),\n * `sharedDataDir` for deliberately cross-conversation state (you own tenant\n * partitioning and concurrency). See `LAYOUT.md`.\n */\n readonly paths: {\n /**\n * This conversation's private data directory\n * (`conversations/<conversationId>/extension-data/<slug>`), created on\n * first access. Default choice: co-located with the conversation, so it\n * disappears when the conversation is deleted.\n */\n readonly dataDir: string;\n /**\n * Data shared across all conversations this extension serves\n * (`global/extension-data/<slug>`), created on first access. Explicit\n * opt-in for multi-conversation applications (e.g. a PM tool with\n * cross-channel views); key rows by conversation id yourself.\n */\n readonly sharedDataDir: string;\n };\n /**\n * Read-only secrets from the embedder's vault\n * (mikan: `<stateDir>/vaults/extensions/<slug>/env`).\n */\n readonly secrets: {\n get(key: string): string | undefined;\n /** Secret names only, never values. */\n list(): string[];\n };\n /**\n * Named schedules owned by this extension + conversation. Backed by the\n * embedder's schedule store; in mikan these become event files that fire\n * autonomous agent runs (hot-reloaded, persisted across restarts).\n */\n readonly schedules: {\n /** Create or replace a named schedule. */\n upsert(name: string, spec: ExtensionScheduleSpec): Promise<void>;\n /** Delete a named schedule. Returns false when it did not exist. */\n delete(name: string): Promise<boolean>;\n /** Schedules owned by this extension in this conversation. */\n list(): Promise<ExtensionScheduleInfo[]>;\n };\n /** Fresh isolated subagent runs. */\n readonly subagent: SubagentApi;\n /**\n * Post text into a conversation without triggering an agent run. Defaults\n * to this conversation; pass `conversationId` to post elsewhere (pairs\n * with `sharedDataDir` for cross-conversation applications). Available\n * when the embedder provides platform messaging.\n */\n notify(text: string, options?: { conversationId?: string }): Promise<void>;\n /**\n * Add an emoji reaction to a message in this conversation. `messageTs` is\n * the platform message id the extension read from an event (see\n * `RunOrigin.messageTs`); `emoji` is a short name without colons.\n * Available when the embedder provides reaction support.\n */\n react(messageTs: string, emoji: string): Promise<void>;\n /**\n * Upload a host-side file into this conversation without an agent run.\n * Available when the embedder provides file uploads for the platform.\n */\n uploadFile(filePath: string, title?: string): Promise<void>;\n /**\n * Fire an autonomous agent run in this conversation as soon as possible.\n * Like a schedule, the run does not inherit conversation history — write\n * `text` self-contained. Backed by the embedder's schedule store.\n */\n triggerRun(text: string): Promise<void>;\n}\n\nexport type MikanExtensionActivate = (\n api: MikanExtensionApi,\n) => void | ExtensionDisposer | Promise<void | ExtensionDisposer>;\n\nexport interface MikanExtensionModule {\n name?: string;\n activate: MikanExtensionActivate;\n}\n\nexport interface LoadedExtension {\n name: string;\n path: string;\n /** Filesystem-safe identifier used for data dirs, secrets, and schedules. */\n slug: string;\n version?: string;\n description?: string;\n /** Skills discovered under the extension's `skills/` directory. */\n skills: MikanSkill[];\n}\n\nexport interface ExtensionLoadError {\n path: string;\n error: string;\n}\n"]}
@@ -15,6 +15,6 @@ export { DEFAULT_BUDGET_SETTINGS, DEFAULT_EVENT_BUDGET, DEFAULT_RETRY_SETTINGS,
15
15
  export { buildEventPayload, EventTypeSchema, parseEventPayload, type EventConversationKind, type EventFilePayload, type EventPayloadInput, type EventType, type ImmediateEventPayload, type OneShotEventPayload, type PeriodicEventPayload, } from "./event-format.js";
16
16
  export { ExtensionRegistry, parseCommandInput } from "./extensions/registry.js";
17
17
  export { defaultExtensionDirs, extensionSlug, listInstalledExtensions, loadExtensions, validateExtension, type ExtensionValidation, type InstalledExtensionInfo, type LoadExtensionsOptions, type LoadExtensionsResult, } from "./extensions/loader.js";
18
- export type { AgentErrorHookEvent, BeforeAgentStartHookEvent, BeforeAgentStartHookResult, BudgetExceededHookEvent, SubagentApi, ExtensionCommand, ExtensionCommandContext, ExtensionDisposer, ExtensionHostServices, ExtensionLoadError, ExtensionManifest, ExtensionScheduleInfo, ExtensionSchedulePayload, ExtensionScheduleSpec, ExtensionScheduleStore, LoadedExtension, MessageEndHookEvent, MikanExtensionActivate, MikanExtensionApi, MikanExtensionModule, MikanHookMap, MikanHookName, RunOrigin, SessionCompactHookEvent, ToolCallHookEvent, ToolCallHookResult, ToolResultHookEvent, ToolResultHookResult, TurnEndHookEvent, } from "./extensions/types.js";
18
+ export type { AgentErrorHookEvent, BeforeAgentStartHookEvent, BeforeAgentStartHookResult, BudgetExceededHookEvent, ContextHookEvent, ContextHookResult, SubagentApi, ExtensionCommand, ExtensionCommandContext, ExtensionDisposer, ExtensionHostServices, ExtensionLoadError, ExtensionManifest, ExtensionScheduleInfo, ExtensionSchedulePayload, ExtensionScheduleSpec, ExtensionScheduleStore, LoadedExtension, MessageEndHookEvent, MessageEndHookResult, MikanExtensionActivate, MikanExtensionApi, MikanExtensionModule, MikanHookMap, MikanHookName, RunOrigin, SessionCompactHookEvent, ToolCallHookEvent, ToolCallHookResult, ToolResultHookEvent, ToolResultHookResult, TurnEndHookEvent, } from "./extensions/types.js";
19
19
  export { type SubagentModelSpec, type SubagentParentContext, type SubagentRunBudget, type SubagentRunOutput, type SubagentRunRequest, type SubagentRunResult, type SubagentRunStatus, type SubagentUsage, CURRENT_SESSION_VERSION, type BranchSummaryEntry, type CompactionEntry, type CustomEntry, type CustomMessageEntry, type SessionContext, type SessionEntry, type SessionFileEntry, type SessionHeader, type SessionInfoEntry, type SessionMessageEntry, } from "./types.js";
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAiC,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,GAMlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GAIjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GAKvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAQlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC;AAgChC,OAAO,EASL,uBAAuB,GAWxB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * mikan agent harness.\n *\n * mikan's own harness engineering layer, built directly on pi-agent-core\n * (agent loop, compaction, context building) and pi-ai (providers, models,\n * auth). See `src/harness/README.md` for the architecture.\n */\nexport { FileCredentialStore, defaultAuthPath } from \"./auth.js\";\nexport {\n DEFAULT_HTTP_IDLE_TIMEOUT_MS,\n configureHttpDispatcher,\n parseHttpIdleTimeoutMs,\n} from \"./http.js\";\nexport { MikanModels, defaultModelsJsonPath, type CreateMikanModelsOptions } from \"./models.js\";\nexport { SessionStore, loadSessionFileEntries, parseSessionFileEntries } from \"./session-store.js\";\nexport {\n MikanAgentSession,\n type CompactionReason,\n type HarnessEvent,\n type HarnessEventListener,\n type MikanAgentSessionOptions,\n type PromptBlockedOutcome,\n} from \"./runner.js\";\nexport {\n formatSkillsForPrompt,\n loadSkillsFromDir,\n parseFrontmatter,\n type LoadSkillsResult,\n type MikanSkill,\n type SkillDiagnostic,\n} from \"./skills.js\";\nexport {\n DEFAULT_BUDGET_SETTINGS,\n DEFAULT_EVENT_BUDGET,\n DEFAULT_RETRY_SETTINGS,\n resolveHarnessSettings,\n type BudgetSettings,\n type CompactionSettings,\n type HarnessSettings,\n type RetrySettings,\n} from \"./settings.js\";\nexport {\n buildEventPayload,\n EventTypeSchema,\n parseEventPayload,\n type EventConversationKind,\n type EventFilePayload,\n type EventPayloadInput,\n type EventType,\n type ImmediateEventPayload,\n type OneShotEventPayload,\n type PeriodicEventPayload,\n} from \"./event-format.js\";\nexport { ExtensionRegistry, parseCommandInput } from \"./extensions/registry.js\";\nexport {\n defaultExtensionDirs,\n extensionSlug,\n listInstalledExtensions,\n loadExtensions,\n validateExtension,\n type ExtensionValidation,\n type InstalledExtensionInfo,\n type LoadExtensionsOptions,\n type LoadExtensionsResult,\n} from \"./extensions/loader.js\";\nexport type {\n AgentErrorHookEvent,\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n BudgetExceededHookEvent,\n SubagentApi,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionScheduleInfo,\n ExtensionSchedulePayload,\n ExtensionScheduleSpec,\n ExtensionScheduleStore,\n LoadedExtension,\n MessageEndHookEvent,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n MikanHookMap,\n MikanHookName,\n RunOrigin,\n SessionCompactHookEvent,\n ToolCallHookEvent,\n ToolCallHookResult,\n ToolResultHookEvent,\n ToolResultHookResult,\n TurnEndHookEvent,\n} from \"./extensions/types.js\";\nexport {\n type SubagentModelSpec,\n type SubagentParentContext,\n type SubagentRunBudget,\n type SubagentRunOutput,\n type SubagentRunRequest,\n type SubagentRunResult,\n type SubagentRunStatus,\n type SubagentUsage,\n CURRENT_SESSION_VERSION,\n type BranchSummaryEntry,\n type CompactionEntry,\n type CustomEntry,\n type CustomMessageEntry,\n type SessionContext,\n type SessionEntry,\n type SessionFileEntry,\n type SessionHeader,\n type SessionInfoEntry,\n type SessionMessageEntry,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAiC,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,GAMlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GAIjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GAKvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAQlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC;AAmChC,OAAO,EASL,uBAAuB,GAWxB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * mikan agent harness.\n *\n * mikan's own harness engineering layer, built directly on pi-agent-core\n * (agent loop, compaction, context building) and pi-ai (providers, models,\n * auth). See `src/harness/README.md` for the architecture.\n */\nexport { FileCredentialStore, defaultAuthPath } from \"./auth.js\";\nexport {\n DEFAULT_HTTP_IDLE_TIMEOUT_MS,\n configureHttpDispatcher,\n parseHttpIdleTimeoutMs,\n} from \"./http.js\";\nexport { MikanModels, defaultModelsJsonPath, type CreateMikanModelsOptions } from \"./models.js\";\nexport { SessionStore, loadSessionFileEntries, parseSessionFileEntries } from \"./session-store.js\";\nexport {\n MikanAgentSession,\n type CompactionReason,\n type HarnessEvent,\n type HarnessEventListener,\n type MikanAgentSessionOptions,\n type PromptBlockedOutcome,\n} from \"./runner.js\";\nexport {\n formatSkillsForPrompt,\n loadSkillsFromDir,\n parseFrontmatter,\n type LoadSkillsResult,\n type MikanSkill,\n type SkillDiagnostic,\n} from \"./skills.js\";\nexport {\n DEFAULT_BUDGET_SETTINGS,\n DEFAULT_EVENT_BUDGET,\n DEFAULT_RETRY_SETTINGS,\n resolveHarnessSettings,\n type BudgetSettings,\n type CompactionSettings,\n type HarnessSettings,\n type RetrySettings,\n} from \"./settings.js\";\nexport {\n buildEventPayload,\n EventTypeSchema,\n parseEventPayload,\n type EventConversationKind,\n type EventFilePayload,\n type EventPayloadInput,\n type EventType,\n type ImmediateEventPayload,\n type OneShotEventPayload,\n type PeriodicEventPayload,\n} from \"./event-format.js\";\nexport { ExtensionRegistry, parseCommandInput } from \"./extensions/registry.js\";\nexport {\n defaultExtensionDirs,\n extensionSlug,\n listInstalledExtensions,\n loadExtensions,\n validateExtension,\n type ExtensionValidation,\n type InstalledExtensionInfo,\n type LoadExtensionsOptions,\n type LoadExtensionsResult,\n} from \"./extensions/loader.js\";\nexport type {\n AgentErrorHookEvent,\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n BudgetExceededHookEvent,\n ContextHookEvent,\n ContextHookResult,\n SubagentApi,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionScheduleInfo,\n ExtensionSchedulePayload,\n ExtensionScheduleSpec,\n ExtensionScheduleStore,\n LoadedExtension,\n MessageEndHookEvent,\n MessageEndHookResult,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n MikanHookMap,\n MikanHookName,\n RunOrigin,\n SessionCompactHookEvent,\n ToolCallHookEvent,\n ToolCallHookResult,\n ToolResultHookEvent,\n ToolResultHookResult,\n TurnEndHookEvent,\n} from \"./extensions/types.js\";\nexport {\n type SubagentModelSpec,\n type SubagentParentContext,\n type SubagentRunBudget,\n type SubagentRunOutput,\n type SubagentRunRequest,\n type SubagentRunResult,\n type SubagentRunStatus,\n type SubagentUsage,\n CURRENT_SESSION_VERSION,\n type BranchSummaryEntry,\n type CompactionEntry,\n type CustomEntry,\n type CustomMessageEntry,\n type SessionContext,\n type SessionEntry,\n type SessionFileEntry,\n type SessionHeader,\n type SessionInfoEntry,\n type SessionMessageEntry,\n} from \"./types.js\";\n"]}
@@ -139,7 +139,7 @@ export declare class MikanAgentSession {
139
139
  private ensureAuthConfigured;
140
140
  private emit;
141
141
  private handleAgentEvent;
142
- /** Fold one assistant turn's usage into the running per-run tally. */
142
+ /** Fold one assistant completion's usage into the running per-run tally. */
143
143
  private recordUsage;
144
144
  /** Compare the tally against the run budget; abort the run when a cap is exceeded. */
145
145
  private enforceBudget;
@@ -154,6 +154,13 @@ export declare class MikanAgentSession {
154
154
  private handleOverflow;
155
155
  private checkThresholdCompaction;
156
156
  private runCompaction;
157
+ /**
158
+ * Compaction can make one completion, or two when its cut splits a turn.
159
+ * Intercept only those opaque upstream calls so each returned assistant
160
+ * message is tallied exactly once. A call at maxLlmCalls is not started;
161
+ * the cap is otherwise enforced before any post-compaction continuation.
162
+ */
163
+ private createCompactionModels;
157
164
  private isRetryableError;
158
165
  private prepareRetry;
159
166
  private dropTrailingErrorMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,EAQL,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EAEd,KAAK,aAAa,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,GAAG,EAER,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,KAAK,cAAc,EAAwB,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,YAAY,CAAC;AAGjE,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AASnE,UAAU,uBAAuB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACtD;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAyBD,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAC3D,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,yBAAyB,CAA8B;IAC/D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAIX;IACF,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,oBAAoB,CAAqB;IACjD,OAAO,CAAC,SAAS,CAAwB;IAEzC,YAAY,OAAO,EAAE,wBAAwB,EA8C5C;IAED,2DAA2D;IAC3D,IAAI,QAAQ,IAAI,YAAY,EAAE,CAE7B;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,CAEtB;IAED,+EAA+E;IAC/E,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,6EAA6E;IAC7E,eAAe,IAAI,QAAQ,CAAC;QAC1B,KAAK,EAAE,aAAa,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC,CASD;IAED;;;;;;;OAOG;IACG,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3D;IAED,SAAS,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAGpD;IAED,oEAAoE;IACpE,iBAAiB,IAAI,MAAM,CAM1B;IAED;;;;;;;;;;;OAWG;IACG,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,GACjF,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAU3C;YAEa,SAAS;IAwFvB,6EAA6E;IAC7E,KAAK,IAAI,IAAI,CAIZ;YAEa,oBAAoB;YASpB,IAAI;YAaJ,gBAAgB;IAmC9B,sEAAsE;IACtE,OAAO,CAAC,WAAW;IAOnB,sFAAsF;YACxE,aAAa;IAO3B,kFAAkF;YACpE,YAAY;IAwB1B,OAAO,CAAC,gBAAgB;IAUxB,+EAA+E;IAC/E,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,wBAAwB;IAShC,0FAA0F;YAC5E,aAAa;YAsBb,cAAc;YAgBd,wBAAwB;YAiBxB,aAAa;IAmF3B,OAAO,CAAC,gBAAgB;YAKV,YAAY;IA+C1B,OAAO,CAAC,wBAAwB;CAMjC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"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"}
@@ -64,6 +64,11 @@ export class MikanAgentSession {
64
64
  tools,
65
65
  },
66
66
  convertToLlm,
67
+ transformContext: async (messages) => {
68
+ if (!this.extensions?.hasHandlers("context"))
69
+ return messages;
70
+ return this.extensions.emitContext({ messages, origin: this.runOrigin });
71
+ },
67
72
  streamFn: (model, context, streamOptions) => this.models.models.streamSimple(model, context, streamOptions),
68
73
  beforeToolCall: async ({ toolCall, args }) => {
69
74
  if (!this.extensions?.hasHandlers("tool_call"))
@@ -87,7 +92,9 @@ export class MikanAgentSession {
87
92
  toolName: toolCall.name,
88
93
  args,
89
94
  content: result.content,
95
+ details: result.details,
90
96
  isError,
97
+ usage: result.usage,
91
98
  origin: this.runOrigin,
92
99
  });
93
100
  },
@@ -163,14 +170,16 @@ export class MikanAgentSession {
163
170
  throw new Error("Agent is already processing a prompt");
164
171
  }
165
172
  this.runActive = true;
173
+ const runSystemPrompt = this.agent.state.systemPrompt;
166
174
  try {
167
- return await this.runPrompt(text, options);
175
+ return await this.runPrompt(text, runSystemPrompt, options);
168
176
  }
169
177
  finally {
178
+ this.agent.state.systemPrompt = runSystemPrompt;
170
179
  this.runActive = false;
171
180
  }
172
181
  }
173
- async runPrompt(text, options) {
182
+ async runPrompt(text, runSystemPrompt, options) {
174
183
  const model = this.agent.state.model;
175
184
  await this.ensureAuthConfigured(model);
176
185
  this.retryAttempt = 0;
@@ -190,7 +199,7 @@ export class MikanAgentSession {
190
199
  await this.checkThresholdCompaction(lastAssistant);
191
200
  }
192
201
  let promptText = text;
193
- let systemPrompt = this.agent.state.systemPrompt;
202
+ let systemPrompt = runSystemPrompt;
194
203
  if (this.extensions?.hasHandlers("before_agent_start")) {
195
204
  const result = await this.extensions.emitBeforeAgentStart({
196
205
  prompt: promptText,
@@ -266,10 +275,20 @@ export class MikanAgentSession {
266
275
  }
267
276
  }
268
277
  async handleAgentEvent(event) {
269
- await this.emit(event);
270
- if (event.type !== "message_end")
278
+ if (event.type !== "message_end") {
279
+ await this.emit(event);
271
280
  return;
272
- const message = event.message;
281
+ }
282
+ let message = event.message;
283
+ if (this.extensions?.hasHandlers("message_end")) {
284
+ const result = await this.extensions.emitMessageEnd({ message, origin: this.runOrigin });
285
+ if (result?.message) {
286
+ for (const key of Object.keys(message)) {
287
+ delete message[key];
288
+ }
289
+ Object.assign(message, result.message);
290
+ }
291
+ }
273
292
  if (message.role === "user" || message.role === "assistant" || message.role === "toolResult") {
274
293
  this.sessionStore.appendMessage(message);
275
294
  }
@@ -277,9 +296,7 @@ export class MikanAgentSession {
277
296
  const custom = message;
278
297
  this.sessionStore.appendCustomMessageEntry(custom.customType, custom.content, custom.display, custom.details);
279
298
  }
280
- if (this.extensions?.hasHandlers("message_end")) {
281
- await this.extensions.emit("message_end", { message, origin: this.runOrigin });
282
- }
299
+ await this.emit({ ...event, message });
283
300
  if (message.role === "assistant") {
284
301
  this.recordUsage(message);
285
302
  await this.enforceBudget(message);
@@ -292,7 +309,7 @@ export class MikanAgentSession {
292
309
  }
293
310
  }
294
311
  }
295
- /** Fold one assistant turn's usage into the running per-run tally. */
312
+ /** Fold one assistant completion's usage into the running per-run tally. */
296
313
  recordUsage(message) {
297
314
  this.tally.llmCalls += 1;
298
315
  const usage = message.usage;
@@ -311,6 +328,8 @@ export class MikanAgentSession {
311
328
  }
312
329
  /** Mark the run over budget, notify listeners and extensions, abort the agent. */
313
330
  async exceedBudget(reason) {
331
+ if (this.budgetExceededReason)
332
+ return;
314
333
  this.budgetExceededReason = reason;
315
334
  await this.emit({
316
335
  type: "budget_exceeded",
@@ -428,7 +447,7 @@ export class MikanAgentSession {
428
447
  started = true;
429
448
  this.compactionAbortController = new AbortController();
430
449
  const signal = this.compactionAbortController.signal;
431
- const result = getOrThrow(await compact(preparation, this.models.models, this.agent.state.model, undefined, signal, this.agent.state.thinkingLevel));
450
+ const result = getOrThrow(await compact(preparation, this.createCompactionModels(), this.agent.state.model, undefined, signal, this.agent.state.thinkingLevel));
432
451
  if (signal.aborted) {
433
452
  await this.emit({ type: "compaction_end", reason, aborted: true });
434
453
  return false;
@@ -455,6 +474,8 @@ export class MikanAgentSession {
455
474
  },
456
475
  aborted: false,
457
476
  });
477
+ if (this.budgetExceededReason)
478
+ return false;
458
479
  if (willRetry) {
459
480
  this.dropTrailingErrorMessage();
460
481
  return true;
@@ -482,6 +503,36 @@ export class MikanAgentSession {
482
503
  this.compactionAbortController = undefined;
483
504
  }
484
505
  }
506
+ /**
507
+ * Compaction can make one completion, or two when its cut splits a turn.
508
+ * Intercept only those opaque upstream calls so each returned assistant
509
+ * message is tallied exactly once. A call at maxLlmCalls is not started;
510
+ * the cap is otherwise enforced before any post-compaction continuation.
511
+ */
512
+ createCompactionModels() {
513
+ const models = this.models.models;
514
+ return new Proxy(models, {
515
+ get: (target, property) => {
516
+ if (property === "completeSimple") {
517
+ return async (...args) => {
518
+ const maxLlmCalls = this.runBudget.maxLlmCalls;
519
+ if (maxLlmCalls !== undefined && this.tally.llmCalls >= maxLlmCalls) {
520
+ await this.exceedBudget(`${this.tally.llmCalls} LLM calls >= ${maxLlmCalls} limit`);
521
+ throw new Error("Compaction LLM-call budget exhausted");
522
+ }
523
+ const message = await target.completeSimple(...args);
524
+ this.recordUsage(message);
525
+ const reason = this.resourceOverBudgetReason();
526
+ if (reason)
527
+ await this.exceedBudget(reason);
528
+ return message;
529
+ };
530
+ }
531
+ const value = Reflect.get(target, property, target);
532
+ return typeof value === "function" ? value.bind(target) : value;
533
+ },
534
+ });
535
+ }
485
536
  isRetryableError(message) {
486
537
  if (message.stopReason !== "error" || !message.errorMessage)
487
538
  return false;