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

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 (67) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/adapters/discord/bot.d.ts.map +1 -1
  3. package/dist/adapters/discord/bot.js +17 -3
  4. package/dist/adapters/discord/bot.js.map +1 -1
  5. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  6. package/dist/adapters/slack/blocks.js +13 -2
  7. package/dist/adapters/slack/blocks.js.map +1 -1
  8. package/dist/adapters/slack/bot.d.ts.map +1 -1
  9. package/dist/adapters/slack/bot.js +13 -1
  10. package/dist/adapters/slack/bot.js.map +1 -1
  11. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  12. package/dist/adapters/slack/response-lifecycle.js +3 -3
  13. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  14. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  15. package/dist/adapters/telegram/bot.js +24 -1
  16. package/dist/adapters/telegram/bot.js.map +1 -1
  17. package/dist/agent.d.ts.map +1 -1
  18. package/dist/agent.js +73 -0
  19. package/dist/agent.js.map +1 -1
  20. package/dist/commands/new.d.ts.map +1 -1
  21. package/dist/commands/new.js +8 -1
  22. package/dist/commands/new.js.map +1 -1
  23. package/dist/commands/types.d.ts +2 -1
  24. package/dist/commands/types.d.ts.map +1 -1
  25. package/dist/commands/types.js.map +1 -1
  26. package/dist/harness/extensions/registry.d.ts +19 -7
  27. package/dist/harness/extensions/registry.d.ts.map +1 -1
  28. package/dist/harness/extensions/registry.js +65 -6
  29. package/dist/harness/extensions/registry.js.map +1 -1
  30. package/dist/harness/extensions/types.d.ts +27 -6
  31. package/dist/harness/extensions/types.d.ts.map +1 -1
  32. package/dist/harness/extensions/types.js.map +1 -1
  33. package/dist/harness/index.d.ts +1 -1
  34. package/dist/harness/index.d.ts.map +1 -1
  35. package/dist/harness/index.js.map +1 -1
  36. package/dist/harness/runner.d.ts +8 -1
  37. package/dist/harness/runner.d.ts.map +1 -1
  38. package/dist/harness/runner.js +62 -11
  39. package/dist/harness/runner.js.map +1 -1
  40. package/dist/harness/session-store.d.ts +5 -4
  41. package/dist/harness/session-store.d.ts.map +1 -1
  42. package/dist/harness/session-store.js +120 -28
  43. package/dist/harness/session-store.js.map +1 -1
  44. package/dist/runtime/conversation-runtime.js +86 -4
  45. package/dist/runtime/conversation-runtime.js.map +1 -1
  46. package/dist/runtime/types.d.ts +2 -0
  47. package/dist/runtime/types.d.ts.map +1 -1
  48. package/dist/runtime/types.js.map +1 -1
  49. package/dist/sessions/chat-history-sync.d.ts.map +1 -1
  50. package/dist/sessions/chat-history-sync.js +14 -3
  51. package/dist/sessions/chat-history-sync.js.map +1 -1
  52. package/dist/tools/bash.d.ts.map +1 -1
  53. package/dist/tools/bash.js +1 -0
  54. package/dist/tools/bash.js.map +1 -1
  55. package/dist/tools/edit.d.ts.map +1 -1
  56. package/dist/tools/edit.js +1 -0
  57. package/dist/tools/edit.js.map +1 -1
  58. package/dist/tools/sandbox.d.ts.map +1 -1
  59. package/dist/tools/sandbox.js +1 -0
  60. package/dist/tools/sandbox.js.map +1 -1
  61. package/dist/tools/write.d.ts.map +1 -1
  62. package/dist/tools/write.js +1 -0
  63. package/dist/tools/write.js.map +1 -1
  64. package/dist/types.d.ts +6 -1
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/types.js.map +1 -1
  67. package/package.json +1 -1
@@ -19,7 +19,14 @@ export class NewCommandHandler {
19
19
  ]), { style: "muted" });
20
20
  return true;
21
21
  }
22
- await context.services.runtime.handleNewCommand(context.sessionKey, context.conversationId, context.bot);
22
+ await context.services.runtime.handleNewCommand(context.sessionKey, context.conversationId, context.bot, {
23
+ id: `memory:${context.sessionKey}`,
24
+ sessionKey: context.sessionKey,
25
+ conversationKind: "direct",
26
+ userId: context.platformUserId,
27
+ userName: context.platformUserName,
28
+ text: context.commandText,
29
+ }, context.responder, context.bot.getMessagingInfo());
23
30
  return true;
24
31
  }
25
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAEvC,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,SAAS,CAAC,OAAuB;QACrC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnE,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACjC,MAAM,0BAA0B,CAC9B,OAAO,CAAC,SAAS,EACjB,oBAAoB,CAAC,aAAa,EAAE;gBAClC,4CAA4C;aAC7C,CAAC,EACF,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,0BAA0B,CAC9B,OAAO,CAAC,SAAS,EACjB,oBAAoB,CAAC,aAAa,EAAE;gBAClC,wDAAwD;gBACxD,yBAAyB;aAC1B,CAAC,EACF,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAC7C,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,GAAG,CACZ,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nconst NEW_COMMANDS = slashForms(\"new\");\n\nexport class NewCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n if (!matchCommand(context.commandText, NEW_COMMANDS)) return false;\n\n if (!context.privateConversation) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"New Session\", [\n \"為了避免誤清除共享上下文,`/new` 目前只能在與機器人的私訊 / DM 中使用。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (!context.services.runtime) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"New Session\", [\n \"New command is not configured correctly on the server.\",\n \"Please try again later.\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n await context.services.runtime.handleNewCommand(\n context.sessionKey,\n context.conversationId,\n context.bot,\n );\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAEvC,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,SAAS,CAAC,OAAuB;QACrC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnE,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACjC,MAAM,0BAA0B,CAC9B,OAAO,CAAC,SAAS,EACjB,oBAAoB,CAAC,aAAa,EAAE;gBAClC,4CAA4C;aAC7C,CAAC,EACF,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,0BAA0B,CAC9B,OAAO,CAAC,SAAS,EACjB,oBAAoB,CAAC,aAAa,EAAE;gBAClC,wDAAwD;gBACxD,yBAAyB;aAC1B,CAAC,EACF,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAC7C,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,GAAG,EACX;YACE,EAAE,EAAE,UAAU,OAAO,CAAC,UAAU,EAAE;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,gBAAgB,EAAE,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,cAAc;YAC9B,QAAQ,EAAE,OAAO,CAAC,gBAAgB;YAClC,IAAI,EAAE,OAAO,CAAC,WAAW;SAC1B,EACD,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAC/B,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nconst NEW_COMMANDS = slashForms(\"new\");\n\nexport class NewCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n if (!matchCommand(context.commandText, NEW_COMMANDS)) return false;\n\n if (!context.privateConversation) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"New Session\", [\n \"為了避免誤清除共享上下文,`/new` 目前只能在與機器人的私訊 / DM 中使用。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (!context.services.runtime) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"New Session\", [\n \"New command is not configured correctly on the server.\",\n \"Please try again later.\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n await context.services.runtime.handleNewCommand(\n context.sessionKey,\n context.conversationId,\n context.bot,\n {\n id: `memory:${context.sessionKey}`,\n sessionKey: context.sessionKey,\n conversationKind: \"direct\",\n userId: context.platformUserId,\n userName: context.platformUserName,\n text: context.commandText,\n },\n context.responder,\n context.bot.getMessagingInfo(),\n );\n return true;\n }\n}\n"]}
@@ -25,7 +25,7 @@ export interface AdminTokenStoreLike {
25
25
  };
26
26
  }
27
27
  interface CommandRuntimeBridge {
28
- handleNewCommand(sessionKey: string, conversationId: string, bot: MessagingBot): Promise<void>;
28
+ handleNewCommand(sessionKey: string, conversationId: string, bot: MessagingBot, message: ConversationContext["message"], responder: ConversationContext["responder"], platform: ConversationContext["platform"]): Promise<void>;
29
29
  switchConversationModel(conversationId: string, provider: string, model: string): boolean;
30
30
  refreshConversationEnvironment(conversationId: string): boolean;
31
31
  }
@@ -46,6 +46,7 @@ export interface CommandContext {
46
46
  responder: ConversationContext["responder"];
47
47
  platform: PlatformName;
48
48
  platformUserId: string;
49
+ platformUserName?: string;
49
50
  conversationId: string;
50
51
  vaultConversationId?: string;
51
52
  sessionKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { MessagingBot, ConversationContext, PlatformName } from \"../adapter.js\";\nimport type { DockerContainerManager } from \"../provisioner.js\";\nimport type { SandboxConfig } from \"../sandbox/index.js\";\nimport type { SandboxResourceController } from \"../types.js\";\nimport type { VaultManager } from \"../vault/index.js\";\n\nexport interface LinkTokenStoreLike {\n create(\n platform: PlatformName,\n platformUserId: string,\n conversationId: string,\n vaultId: string,\n providerId: string,\n ): { token: string };\n}\n\nexport interface SessionViewTokenStoreLike {\n create(\n platform: PlatformName,\n platformUserId: string,\n conversationId: string,\n sessionKey: string,\n sessionFile: string,\n platformUserName?: string,\n ): { token: string };\n}\n\nexport interface AdminTokenStoreLike {\n create(args: {\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n platformUserName?: string;\n }): { token: string };\n}\n\ninterface CommandRuntimeBridge {\n handleNewCommand(sessionKey: string, conversationId: string, bot: MessagingBot): Promise<void>;\n switchConversationModel(conversationId: string, provider: string, model: string): boolean;\n refreshConversationEnvironment(conversationId: string): boolean;\n}\n\nexport interface CommandServices {\n workingDir: string;\n runtime?: CommandRuntimeBridge;\n sandbox: SandboxConfig;\n vaultManager: VaultManager;\n provisioner?: DockerContainerManager;\n resourceController?: SandboxResourceController;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore: SessionViewTokenStoreLike;\n adminTokenStore: AdminTokenStoreLike;\n portalBaseUrl?: string;\n}\n\nexport interface CommandContext {\n bot: MessagingBot;\n responder: ConversationContext[\"responder\"];\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n vaultConversationId?: string;\n sessionKey: string;\n commandText: string;\n privateConversation: boolean;\n services: CommandServices;\n}\n\nexport interface CommandHandler {\n tryHandle(context: CommandContext): Promise<boolean>;\n}\n\n// ── command-specific parsed types ────────────────────────────────────────────\n\nexport interface ParsedModelCommand {\n provider?: string;\n model?: string;\n thinkingLevel?: ThinkingLevel;\n}\n\nexport interface ParsedSandboxCommand {\n action?: \"boost\" | \"private\" | \"full\";\n}\n\nexport type ParsedLoginCommand =\n | { action: \"setup\" }\n | { action: \"shared_create\" | \"shared_update\" | \"shared_delete\"; name: string }\n | { action: \"shared_list\" }\n | { action: \"copy_shared\"; name: string };\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { MessagingBot, ConversationContext, PlatformName } from \"../adapter.js\";\nimport type { DockerContainerManager } from \"../provisioner.js\";\nimport type { SandboxConfig } from \"../sandbox/index.js\";\nimport type { SandboxResourceController } from \"../types.js\";\nimport type { VaultManager } from \"../vault/index.js\";\n\nexport interface LinkTokenStoreLike {\n create(\n platform: PlatformName,\n platformUserId: string,\n conversationId: string,\n vaultId: string,\n providerId: string,\n ): { token: string };\n}\n\nexport interface SessionViewTokenStoreLike {\n create(\n platform: PlatformName,\n platformUserId: string,\n conversationId: string,\n sessionKey: string,\n sessionFile: string,\n platformUserName?: string,\n ): { token: string };\n}\n\nexport interface AdminTokenStoreLike {\n create(args: {\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n platformUserName?: string;\n }): { token: string };\n}\n\ninterface CommandRuntimeBridge {\n handleNewCommand(\n sessionKey: string,\n conversationId: string,\n bot: MessagingBot,\n message: ConversationContext[\"message\"],\n responder: ConversationContext[\"responder\"],\n platform: ConversationContext[\"platform\"],\n ): Promise<void>;\n switchConversationModel(conversationId: string, provider: string, model: string): boolean;\n refreshConversationEnvironment(conversationId: string): boolean;\n}\n\nexport interface CommandServices {\n workingDir: string;\n runtime?: CommandRuntimeBridge;\n sandbox: SandboxConfig;\n vaultManager: VaultManager;\n provisioner?: DockerContainerManager;\n resourceController?: SandboxResourceController;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore: SessionViewTokenStoreLike;\n adminTokenStore: AdminTokenStoreLike;\n portalBaseUrl?: string;\n}\n\nexport interface CommandContext {\n bot: MessagingBot;\n responder: ConversationContext[\"responder\"];\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n conversationId: string;\n vaultConversationId?: string;\n sessionKey: string;\n commandText: string;\n privateConversation: boolean;\n services: CommandServices;\n}\n\nexport interface CommandHandler {\n tryHandle(context: CommandContext): Promise<boolean>;\n}\n\n// ── command-specific parsed types ────────────────────────────────────────────\n\nexport interface ParsedModelCommand {\n provider?: string;\n model?: string;\n thinkingLevel?: ThinkingLevel;\n}\n\nexport interface ParsedSandboxCommand {\n action?: \"boost\" | \"private\" | \"full\";\n}\n\nexport type ParsedLoginCommand =\n | { action: \"setup\" }\n | { action: \"shared_create\" | \"shared_update\" | \"shared_delete\"; name: string }\n | { action: \"shared_list\" }\n | { action: \"copy_shared\"; name: string };\n"]}
@@ -5,8 +5,8 @@
5
5
  * extensions and dispatches events from the harness runner. Handler failures
6
6
  * are logged and swallowed so a broken extension cannot take down a run.
7
7
  */
8
- import type { AgentTool } from "@earendil-works/pi-agent-core";
9
- import type { BeforeAgentStartHookEvent, BeforeAgentStartHookResult, ExtensionCommand, ExtensionCommandContext, ExtensionDisposer, MikanHookMap, MikanHookName, ToolResultHookEvent, ToolResultHookResult } from "./types.js";
8
+ import type { AgentMessage, AgentTool } from "@earendil-works/pi-agent-core";
9
+ import type { BeforeAgentStartHookEvent, BeforeAgentStartHookResult, ContextHookEvent, ExtensionCommand, ExtensionCommandContext, ExtensionDisposer, MessageEndHookEvent, MessageEndHookResult, MikanHookMap, MikanHookName, ToolResultHookEvent, ToolResultHookResult } from "./types.js";
10
10
  /**
11
11
  * Parse `/name args…` slash-command text. Returns undefined when the text is
12
12
  * not a slash command with a valid name (`COMMAND_NAME_PATTERN`).
@@ -59,11 +59,23 @@ export declare class ExtensionRegistry {
59
59
  */
60
60
  emitBeforeAgentStart(event: BeforeAgentStartHookEvent): Promise<BeforeAgentStartHookResult | undefined>;
61
61
  /**
62
- * Dispatch `tool_result` with chaining semantics: each handler sees the
63
- * content/isError as rewritten by earlier handlers, so e.g. a redaction
64
- * extension processes the output of upstream rewriters instead of the
65
- * original. Returns the accumulated override, or undefined when no handler
66
- * changed anything.
62
+ * Dispatch `context` with Pi-compatible chaining semantics. Handlers receive
63
+ * a call-local clone, so in-place mutations and returned replacements affect
64
+ * only this LLM call and never the canonical transcript.
65
+ */
66
+ emitContext(event: ContextHookEvent): Promise<AgentMessage[]>;
67
+ /**
68
+ * Dispatch `message_end` with Pi-compatible chaining semantics. Each handler
69
+ * sees the replacement from the previous handler. Role-changing replacements
70
+ * are rejected because the agent lifecycle event role cannot be changed.
71
+ */
72
+ emitMessageEnd(event: MessageEndHookEvent): Promise<MessageEndHookResult | undefined>;
73
+ /**
74
+ * Dispatch `tool_result` with chaining semantics: each handler sees content,
75
+ * details, isError, and usage as rewritten by earlier handlers, so e.g. a
76
+ * redaction extension processes the output of upstream rewriters instead of
77
+ * the original. Returns the accumulated override, or undefined when no
78
+ * handler changed anything.
67
79
  */
68
80
  emitToolResult(event: ToolResultHookEvent): Promise<ToolResultHookResult | undefined>;
69
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAI1F;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CASd;IACF,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAmE;IACnF,OAAO,CAAC,SAAS,CAA6D;IAE9E,QAAQ,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAExF;IAED,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAElC;IAED;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAc9D;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAEjE;IAED,mBAAmB,IAAI,SAAS,EAAE,CAEjC;IAED,mDAAmD;IACnD,WAAW,IAAI,gBAAgB,EAAE,CAEhC;IAED;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,CAetF;IAED;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAa7B;IAED,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAExC;IAED;;;OAGG;IACG,IAAI,CAAC,CAAC,SAAS,aAAa,EAChC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAe3D;IAED;;;;;;OAMG;IACG,oBAAoB,CACxB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CA6BjD;IAED;;;;;;OAMG;IACG,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAuB1F;CACF"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE7E,OAAO,KAAK,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAI1F;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAUd;IACF,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAmE;IACnF,OAAO,CAAC,SAAS,CAA6D;IAE9E,QAAQ,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAExF;IAED,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAElC;IAED;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAc9D;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAEjE;IAED,mBAAmB,IAAI,SAAS,EAAE,CAEjC;IAED,mDAAmD;IACnD,WAAW,IAAI,gBAAgB,EAAE,CAEhC;IAED;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,CAetF;IAED;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAa7B;IAED,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAExC;IAED;;;OAGG;IACG,IAAI,CAAC,CAAC,SAAS,aAAa,EAChC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAe3D;IAED;;;;;;OAMG;IACG,oBAAoB,CACxB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CA6BjD;IAED;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAclE;IAED;;;;OAIG;IACG,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAwB1F;IAED;;;;;;OAMG;IACG,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAoC1F;CACF"}
@@ -14,6 +14,7 @@ export class ExtensionRegistry {
14
14
  constructor() {
15
15
  this.handlers = {
16
16
  before_agent_start: [],
17
+ context: [],
17
18
  tool_call: [],
18
19
  tool_result: [],
19
20
  message_end: [],
@@ -158,11 +159,56 @@ export class ExtensionRegistry {
158
159
  : undefined;
159
160
  }
160
161
  /**
161
- * Dispatch `tool_result` with chaining semantics: each handler sees the
162
- * content/isError as rewritten by earlier handlers, so e.g. a redaction
163
- * extension processes the output of upstream rewriters instead of the
164
- * original. Returns the accumulated override, or undefined when no handler
165
- * changed anything.
162
+ * Dispatch `context` with Pi-compatible chaining semantics. Handlers receive
163
+ * a call-local clone, so in-place mutations and returned replacements affect
164
+ * only this LLM call and never the canonical transcript.
165
+ */
166
+ async emitContext(event) {
167
+ let messages = structuredClone(event.messages);
168
+ for (const { owner, handler } of this.handlers.context) {
169
+ try {
170
+ const result = await handler({ ...event, messages });
171
+ if (result?.messages)
172
+ messages = result.messages;
173
+ }
174
+ catch (err) {
175
+ log.logWarning(`Extension hook "context" failed (${owner})`, err instanceof Error ? err.message : String(err));
176
+ }
177
+ }
178
+ return messages;
179
+ }
180
+ /**
181
+ * Dispatch `message_end` with Pi-compatible chaining semantics. Each handler
182
+ * sees the replacement from the previous handler. Role-changing replacements
183
+ * are rejected because the agent lifecycle event role cannot be changed.
184
+ */
185
+ async emitMessageEnd(event) {
186
+ let message = event.message;
187
+ let modified = false;
188
+ for (const { owner, handler } of this.handlers.message_end) {
189
+ try {
190
+ const result = await handler({ ...event, message });
191
+ if (!result?.message)
192
+ continue;
193
+ if (result.message.role !== message.role) {
194
+ log.logWarning(`Extension hook "message_end" failed (${owner})`, "message_end handlers must return a message with the same role");
195
+ continue;
196
+ }
197
+ message = result.message;
198
+ modified = true;
199
+ }
200
+ catch (err) {
201
+ log.logWarning(`Extension hook "message_end" failed (${owner})`, err instanceof Error ? err.message : String(err));
202
+ }
203
+ }
204
+ return modified ? { message } : undefined;
205
+ }
206
+ /**
207
+ * Dispatch `tool_result` with chaining semantics: each handler sees content,
208
+ * details, isError, and usage as rewritten by earlier handlers, so e.g. a
209
+ * redaction extension processes the output of upstream rewriters instead of
210
+ * the original. Returns the accumulated override, or undefined when no
211
+ * handler changed anything.
166
212
  */
167
213
  async emitToolResult(event) {
168
214
  const chained = { ...event };
@@ -176,16 +222,29 @@ export class ExtensionRegistry {
176
222
  merged.content = result.content;
177
223
  chained.content = result.content;
178
224
  }
225
+ if (result.details !== undefined) {
226
+ merged.details = result.details;
227
+ chained.details = result.details;
228
+ }
179
229
  if (result.isError !== undefined) {
180
230
  merged.isError = result.isError;
181
231
  chained.isError = result.isError;
182
232
  }
233
+ if (result.usage !== undefined) {
234
+ merged.usage = result.usage;
235
+ chained.usage = result.usage;
236
+ }
183
237
  }
184
238
  catch (err) {
185
239
  log.logWarning(`Extension hook "tool_result" failed (${owner})`, err instanceof Error ? err.message : String(err));
186
240
  }
187
241
  }
188
- return merged.content !== undefined || merged.isError !== undefined ? merged : undefined;
242
+ return merged.content !== undefined ||
243
+ merged.details !== undefined ||
244
+ merged.isError !== undefined ||
245
+ merged.usage !== undefined
246
+ ? merged
247
+ : undefined;
189
248
  }
190
249
  }
191
250
  //# sourceMappingURL=registry.js.map
@@ -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;