@zhin.js/agent 1.1.39 → 1.1.41

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 (120) hide show
  1. package/lib/assistant/job-storage.d.ts +238 -0
  2. package/lib/assistant/job-storage.js +143 -0
  3. package/lib/assistant/job-storage.js.map +1 -0
  4. package/lib/assistant/job-store.d.ts +7 -0
  5. package/lib/assistant/job-store.js +41 -3
  6. package/lib/assistant/job-store.js.map +1 -1
  7. package/lib/config/perception-config.d.ts +9 -0
  8. package/lib/config/perception-config.js +27 -0
  9. package/lib/config/perception-config.js.map +1 -1
  10. package/lib/context/context-system.d.ts +1 -0
  11. package/lib/context/context-system.js +8 -8
  12. package/lib/context/context-system.js.map +1 -1
  13. package/lib/context/im-turn-context-adapter.js +2 -0
  14. package/lib/context/im-turn-context-adapter.js.map +1 -1
  15. package/lib/context/skill-context.d.ts +3 -0
  16. package/lib/context/skill-context.js +6 -0
  17. package/lib/context/skill-context.js.map +1 -0
  18. package/lib/context/turn-envelope.d.ts +4 -0
  19. package/lib/context/turn-envelope.js +24 -7
  20. package/lib/context/turn-envelope.js.map +1 -1
  21. package/lib/context/turn-user-message.d.ts +3 -1
  22. package/lib/context/turn-user-message.js +14 -1
  23. package/lib/context/turn-user-message.js.map +1 -1
  24. package/lib/core/agent-core-run.d.ts +1 -0
  25. package/lib/core/agent-core-run.js +47 -20
  26. package/lib/core/agent-core-run.js.map +1 -1
  27. package/lib/core/structured-reply-recovery.d.ts +6 -2
  28. package/lib/core/structured-reply-recovery.js +22 -8
  29. package/lib/core/structured-reply-recovery.js.map +1 -1
  30. package/lib/core/turn-completion-usage.d.ts +2 -1
  31. package/lib/core/turn-completion-usage.js +14 -5
  32. package/lib/core/turn-completion-usage.js.map +1 -1
  33. package/lib/core/turn-event-mapper.d.ts +1 -1
  34. package/lib/core/turn-event-mapper.js +8 -5
  35. package/lib/core/turn-event-mapper.js.map +1 -1
  36. package/lib/decision/config.d.ts +1 -1
  37. package/lib/decision/config.js +1 -1
  38. package/lib/decision/config.js.map +1 -1
  39. package/lib/decision/types.d.ts +1 -1
  40. package/lib/decision/types.js.map +1 -1
  41. package/lib/event/turn-event.d.ts +7 -1
  42. package/lib/event/turn-event.js.map +1 -1
  43. package/lib/index.d.ts +4 -1
  44. package/lib/index.js +2 -0
  45. package/lib/index.js.map +1 -1
  46. package/lib/media/perception.d.ts +3 -4
  47. package/lib/media/perception.js +59 -37
  48. package/lib/media/perception.js.map +1 -1
  49. package/lib/memory/compaction-runtime.d.ts +3 -2
  50. package/lib/memory/compaction-runtime.js +22 -14
  51. package/lib/memory/compaction-runtime.js.map +1 -1
  52. package/lib/outbound/agent-output.js +2 -0
  53. package/lib/outbound/agent-output.js.map +1 -1
  54. package/lib/outbound/chat-failure.d.ts +27 -0
  55. package/lib/outbound/chat-failure.js +53 -0
  56. package/lib/outbound/chat-failure.js.map +1 -0
  57. package/lib/outbound/structured-reply.d.ts +7 -0
  58. package/lib/outbound/structured-reply.js +52 -16
  59. package/lib/outbound/structured-reply.js.map +1 -1
  60. package/lib/plugin-runtime/agent-runtime.js +49 -8
  61. package/lib/plugin-runtime/agent-runtime.js.map +1 -1
  62. package/lib/plugin-runtime/ai-completion.d.ts +4 -3
  63. package/lib/plugin-runtime/ai-completion.js +64 -10
  64. package/lib/plugin-runtime/ai-completion.js.map +1 -1
  65. package/lib/plugin-runtime/capability-ingress.js +3 -1
  66. package/lib/plugin-runtime/capability-ingress.js.map +1 -1
  67. package/lib/plugin-runtime/decision-runtime.d.ts +1 -0
  68. package/lib/plugin-runtime/deferred-capability-plan.d.ts +4 -1
  69. package/lib/plugin-runtime/deferred-capability-plan.js +25 -9
  70. package/lib/plugin-runtime/deferred-capability-plan.js.map +1 -1
  71. package/lib/plugin-runtime/full-agent-turn-engine.js +1 -0
  72. package/lib/plugin-runtime/full-agent-turn-engine.js.map +1 -1
  73. package/lib/plugin-runtime/index.d.ts +2 -0
  74. package/lib/plugin-runtime/index.js +2 -0
  75. package/lib/plugin-runtime/index.js.map +1 -1
  76. package/lib/prompt/assembly.js +0 -9
  77. package/lib/prompt/assembly.js.map +1 -1
  78. package/lib/prompt/git-context.js +1 -1
  79. package/lib/prompt/git-context.js.map +1 -1
  80. package/lib/prompt/rules/chat-rules.js +8 -9
  81. package/lib/prompt/rules/chat-rules.js.map +1 -1
  82. package/lib/prompt/rules/critical-rules.js +10 -10
  83. package/lib/prompt/rules/critical-rules.js.map +1 -1
  84. package/lib/prompt/system-prompt.js +4 -5
  85. package/lib/prompt/system-prompt.js.map +1 -1
  86. package/lib/security/file-role-policy.js +6 -6
  87. package/lib/security/file-role-policy.js.map +1 -1
  88. package/lib/security/policy-facade.js +1 -1
  89. package/lib/security/policy-facade.js.map +1 -1
  90. package/lib/security/usage-quota.d.ts +4 -0
  91. package/lib/security/usage-quota.js +23 -2
  92. package/lib/security/usage-quota.js.map +1 -1
  93. package/lib/session/approval-port.d.ts +2 -0
  94. package/lib/session/approval-port.js.map +1 -1
  95. package/lib/session/approval-review-agent.d.ts +1 -1
  96. package/lib/session/approval-review-agent.js +19 -4
  97. package/lib/session/approval-review-agent.js.map +1 -1
  98. package/lib/session/turn-ingress-session.js +7 -1
  99. package/lib/session/turn-ingress-session.js.map +1 -1
  100. package/lib/tool/tool-approval-gate.js +4 -2
  101. package/lib/tool/tool-approval-gate.js.map +1 -1
  102. package/lib/tool/turn-tool-runtime.js +24 -5
  103. package/lib/tool/turn-tool-runtime.js.map +1 -1
  104. package/lib/tool-catalog/deferred-turn-controller.js +1 -4
  105. package/lib/tool-catalog/deferred-turn-controller.js.map +1 -1
  106. package/lib/trace/context-budget.d.ts +4 -3
  107. package/lib/trace/context-budget.js +28 -8
  108. package/lib/trace/context-budget.js.map +1 -1
  109. package/lib/trace/turn-trace-format.js +4 -1
  110. package/lib/trace/turn-trace-format.js.map +1 -1
  111. package/lib/trace/turn-trace.d.ts +6 -0
  112. package/lib/trace/turn-trace.js +8 -2
  113. package/lib/trace/turn-trace.js.map +1 -1
  114. package/lib/trace/turn-usage-log.d.ts +14 -0
  115. package/lib/trace/turn-usage-log.js +83 -0
  116. package/lib/trace/turn-usage-log.js.map +1 -0
  117. package/lib/usage/usage-store.d.ts +199 -0
  118. package/lib/usage/usage-store.js +121 -0
  119. package/lib/usage/usage-store.js.map +1 -0
  120. package/package.json +12 -12
@@ -1,12 +1,15 @@
1
1
  import { EMPTY_TOKEN_USAGE } from '@zhin.js/ai';
2
+ import { turnUsageEvent } from './turn-event-mapper.js';
2
3
  /** Counts completed provider responses before reply validation, including rejected replies and retries. */
3
4
  export function trackTurnCompletionUsage(delegate) {
4
5
  const total = { ...EMPTY_TOKEN_USAGE, cost: { ...EMPTY_TOKEN_USAGE.cost } };
5
6
  const pending = [];
6
7
  const reported = new WeakSet();
7
- const record = (assistant) => {
8
+ const record = (assistant, durationMs) => {
8
9
  const usage = assistant.usage;
9
- pending.push({ ...usage, cost: { ...usage.cost } });
10
+ pending.push(turnUsageEvent(usage, {
11
+ provider: assistant.provider, model: assistant.model, stopReason: assistant.stopReason, durationMs,
12
+ }));
10
13
  reported.add(assistant);
11
14
  total.input += usage.input;
12
15
  total.output += usage.output;
@@ -24,11 +27,17 @@ export function trackTurnCompletionUsage(delegate) {
24
27
  };
25
28
  return {
26
29
  transport: {
27
- complete: async (model, context, options) => record(await delegate.complete(model, context, options)),
28
- completeSimple: async (model, context, options) => record(await delegate.completeSimple(model, context, options)),
30
+ complete: async (model, context, options) => {
31
+ const started = performance.now();
32
+ return record(await delegate.complete(model, context, options), performance.now() - started);
33
+ },
34
+ completeSimple: async (model, context, options) => {
35
+ const started = performance.now();
36
+ return record(await delegate.completeSimple(model, context, options), performance.now() - started);
37
+ },
29
38
  },
30
39
  get usage() { return { ...total, cost: { ...total.cost } }; },
31
- drainUsage: () => pending.splice(0),
40
+ drainEvents: () => pending.splice(0),
32
41
  hasReported: assistant => reported.has(assistant),
33
42
  };
34
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"turn-completion-usage.js","sourceRoot":"","sources":["../../src/core/turn-completion-usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAkE,MAAM,aAAa,CAAC;AAEhH,2GAA2G;AAC3G,MAAM,UAAU,wBAAwB,CAAC,QAA2B;IAMlE,MAAM,KAAK,GAAe,EAAE,GAAG,iBAAiB,EAAE,IAAI,EAAE,EAAE,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC;IACxF,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAU,CAAC;IACvC,MAAM,MAAM,GAAG,CAAC,SAA2B,EAAoB,EAAE;QAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpD,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxB,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;QAC3B,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QAC7B,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;QACnC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;QACrC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC;QACvC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,KAAK,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QAC9F,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,OAAO;QACL,SAAS,EAAE;YACT,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACrG,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;SAClH;QACD,IAAI,KAAK,KAAK,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACnC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;KAClD,CAAC;AACJ,CAAC","sourcesContent":["import { EMPTY_TOKEN_USAGE, type AssistantMessage, type LlmCompletionPort, type TokenUsage } from '@zhin.js/ai';\n\n/** Counts completed provider responses before reply validation, including rejected replies and retries. */\nexport function trackTurnCompletionUsage(delegate: LlmCompletionPort): {\n transport: LlmCompletionPort;\n readonly usage: TokenUsage;\n drainUsage(): TokenUsage[];\n hasReported(message: object): boolean;\n} {\n const total: TokenUsage = { ...EMPTY_TOKEN_USAGE, cost: { ...EMPTY_TOKEN_USAGE.cost } };\n const pending: TokenUsage[] = [];\n const reported = new WeakSet<object>();\n const record = (assistant: AssistantMessage): AssistantMessage => {\n const usage = assistant.usage;\n pending.push({ ...usage, cost: { ...usage.cost } });\n reported.add(assistant);\n total.input += usage.input;\n total.output += usage.output;\n total.cacheRead += usage.cacheRead;\n total.cacheWrite += usage.cacheWrite;\n total.totalTokens += usage.totalTokens;\n if (usage.reasoning !== undefined) total.reasoning = (total.reasoning ?? 0) + usage.reasoning;\n total.cost.input += usage.cost.input;\n total.cost.output += usage.cost.output;\n total.cost.cacheRead += usage.cost.cacheRead;\n total.cost.cacheWrite += usage.cost.cacheWrite;\n total.cost.total += usage.cost.total;\n return assistant;\n };\n return {\n transport: {\n complete: async (model, context, options) => record(await delegate.complete(model, context, options)),\n completeSimple: async (model, context, options) => record(await delegate.completeSimple(model, context, options)),\n },\n get usage() { return { ...total, cost: { ...total.cost } }; },\n drainUsage: () => pending.splice(0),\n hasReported: assistant => reported.has(assistant),\n };\n}\n"]}
1
+ {"version":3,"file":"turn-completion-usage.js","sourceRoot":"","sources":["../../src/core/turn-completion-usage.ts"],"names":[],"mappings":"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","sourcesContent":["import { EMPTY_TOKEN_USAGE, type AssistantMessage, type LlmCompletionPort, type TokenUsage } from '@zhin.js/ai';\n\nimport type { UsageEvent } from '../event/turn-event.js';\nimport { turnUsageEvent } from './turn-event-mapper.js';\n\n/** Counts completed provider responses before reply validation, including rejected replies and retries. */\nexport function trackTurnCompletionUsage(delegate: LlmCompletionPort): {\n transport: LlmCompletionPort;\n readonly usage: TokenUsage;\n drainEvents(): UsageEvent[];\n hasReported(message: object): boolean;\n} {\n const total: TokenUsage = { ...EMPTY_TOKEN_USAGE, cost: { ...EMPTY_TOKEN_USAGE.cost } };\n const pending: UsageEvent[] = [];\n const reported = new WeakSet<object>();\n const record = (assistant: AssistantMessage, durationMs: number): AssistantMessage => {\n const usage = assistant.usage;\n pending.push(turnUsageEvent(usage, {\n provider: assistant.provider, model: assistant.model, stopReason: assistant.stopReason, durationMs,\n }));\n reported.add(assistant);\n total.input += usage.input;\n total.output += usage.output;\n total.cacheRead += usage.cacheRead;\n total.cacheWrite += usage.cacheWrite;\n total.totalTokens += usage.totalTokens;\n if (usage.reasoning !== undefined) total.reasoning = (total.reasoning ?? 0) + usage.reasoning;\n total.cost.input += usage.cost.input;\n total.cost.output += usage.cost.output;\n total.cost.cacheRead += usage.cost.cacheRead;\n total.cost.cacheWrite += usage.cost.cacheWrite;\n total.cost.total += usage.cost.total;\n return assistant;\n };\n return {\n transport: {\n complete: async (model, context, options) => {\n const started = performance.now();\n return record(await delegate.complete(model, context, options), performance.now() - started);\n },\n completeSimple: async (model, context, options) => {\n const started = performance.now();\n return record(await delegate.completeSimple(model, context, options), performance.now() - started);\n },\n },\n get usage() { return { ...total, cost: { ...total.cost } }; },\n drainEvents: () => pending.splice(0),\n hasReported: assistant => reported.has(assistant),\n };\n}\n"]}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { AgentEvent, TokenUsage } from '@zhin.js/ai';
5
5
  import type { TurnEvent, UsageEvent } from '../event/turn-event.js';
6
- export declare function turnUsageEvent(usage: TokenUsage): UsageEvent;
6
+ export declare function turnUsageEvent(usage: TokenUsage, details?: Pick<UsageEvent, 'provider' | 'model' | 'durationMs' | 'stopReason'>): UsageEvent;
7
7
  export interface TurnEventMapperState {
8
8
  accumulatedText: string;
9
9
  accumulatedThinking: string;
@@ -1,12 +1,15 @@
1
- export function turnUsageEvent(usage) {
1
+ export function turnUsageEvent(usage, details = {}) {
2
2
  return {
3
3
  type: 'usage',
4
+ ...details,
4
5
  usage: {
5
6
  promptTokens: usage.input,
6
7
  completionTokens: usage.output,
7
8
  totalTokens: usage.totalTokens,
8
- ...(usage.cacheRead > 0 ? { cacheReadTokens: usage.cacheRead } : {}),
9
- ...(usage.reasoning ? { reasoningTokens: usage.reasoning } : {}),
9
+ ...(usage.reported ? { reported: { ...usage.reported } } : {}),
10
+ ...(usage.cacheRead > 0 || usage.reported?.cacheRead ? { cacheReadTokens: usage.cacheRead } : {}),
11
+ ...(usage.cacheWrite > 0 || usage.reported?.cacheWrite ? { cacheWriteTokens: usage.cacheWrite } : {}),
12
+ ...(usage.reasoning !== undefined ? { reasoningTokens: usage.reasoning } : {}),
10
13
  },
11
14
  };
12
15
  }
@@ -27,8 +30,8 @@ export function* mapAgentEventToTurnEvents(event, state) {
27
30
  break;
28
31
  case 'message_end':
29
32
  if (event.message.role === 'assistant') {
30
- const usage = event.message.usage;
31
- yield turnUsageEvent(usage);
33
+ const message = event.message;
34
+ yield turnUsageEvent(message.usage, { provider: message.provider, model: message.model, stopReason: message.stopReason });
32
35
  }
33
36
  break;
34
37
  case 'message_update':
@@ -1 +1 @@
1
- {"version":3,"file":"turn-event-mapper.js","sourceRoot":"","sources":["../../src/core/turn-event-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Maps @zhin.js/ai agentLoop AgentEvent stream to TurnEvent union.\n */\nimport type { AgentEvent, AssistantMessage, TokenUsage } from '@zhin.js/ai';\nimport type { TurnEvent, UsageEvent } from '../event/turn-event.js';\n\nexport function turnUsageEvent(usage: TokenUsage): UsageEvent {\n return {\n type: 'usage',\n usage: {\n promptTokens: usage.input,\n completionTokens: usage.output,\n totalTokens: usage.totalTokens,\n ...(usage.cacheRead > 0 ? { cacheReadTokens: usage.cacheRead } : {}),\n ...(usage.reasoning ? { reasoningTokens: usage.reasoning } : {}),\n },\n };\n}\n\nexport interface TurnEventMapperState {\n accumulatedText: string;\n accumulatedThinking: string;\n toolStartTimes: Map<string, number>;\n iteration: number;\n maxIterations: number;\n}\n\nexport function createTurnEventMapperState(maxIterations = 15): TurnEventMapperState {\n return { accumulatedText: '', accumulatedThinking: '', toolStartTimes: new Map(), iteration: 0, maxIterations };\n}\n\nexport function* mapAgentEventToTurnEvents(\n event: AgentEvent,\n state: TurnEventMapperState,\n): Generator<TurnEvent> {\n switch (event.type) {\n case 'turn_start':\n state.iteration += 1;\n state.accumulatedText = '';\n state.accumulatedThinking = '';\n yield {\n type: 'iteration_start',\n iteration: state.iteration,\n maxIterations: state.maxIterations,\n };\n break;\n case 'message_end':\n if (event.message.role === 'assistant') {\n const usage = (event.message as AssistantMessage).usage;\n yield turnUsageEvent(usage);\n }\n break;\n case 'message_update':\n if (event.delta?.type === 'text_delta') {\n state.accumulatedText += event.delta.text;\n yield {\n type: 'chunk',\n text: event.delta.text,\n accumulated: state.accumulatedText,\n };\n } else if (event.delta?.type === 'thinking_delta') {\n state.accumulatedThinking += event.delta.thinking;\n yield { type: 'thinking', text: event.delta.thinking };\n }\n break;\n case 'tool_execution_start':\n state.toolStartTimes.set(event.toolCallId, performance.now());\n yield {\n type: 'tool_call',\n toolName: event.toolCall.name,\n args: (event.toolCall.arguments ?? {}) as Record<string, unknown>,\n toolUseId: event.toolCallId,\n };\n break;\n case 'tool_execution_end': {\n const started = state.toolStartTimes.get(event.toolCallId);\n const durationMs = started != null ? performance.now() - started : 0;\n state.toolStartTimes.delete(event.toolCallId);\n const toolName =\n event.result.role === 'toolResult'\n ? String(event.result.toolName ?? 'unknown')\n : 'unknown';\n const output =\n event.result.role === 'toolResult' && Array.isArray(event.result.content)\n ? event.result.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n : '';\n yield {\n type: 'tool_result',\n toolName,\n output,\n durationMs,\n toolUseId: event.toolCallId,\n };\n break;\n }\n default:\n break;\n }\n}\n"]}
1
+ {"version":3,"file":"turn-event-mapper.js","sourceRoot":"","sources":["../../src/core/turn-event-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Maps @zhin.js/ai agentLoop AgentEvent stream to TurnEvent union.\n */\nimport type { AgentEvent, AssistantMessage, TokenUsage } from '@zhin.js/ai';\nimport type { TurnEvent, UsageEvent } from '../event/turn-event.js';\n\nexport function turnUsageEvent(\n usage: TokenUsage,\n details: Pick<UsageEvent, 'provider' | 'model' | 'durationMs' | 'stopReason'> = {},\n): UsageEvent {\n return {\n type: 'usage',\n ...details,\n usage: {\n promptTokens: usage.input,\n completionTokens: usage.output,\n totalTokens: usage.totalTokens,\n ...(usage.reported ? { reported: { ...usage.reported } } : {}),\n ...(usage.cacheRead > 0 || usage.reported?.cacheRead ? { cacheReadTokens: usage.cacheRead } : {}),\n ...(usage.cacheWrite > 0 || usage.reported?.cacheWrite ? { cacheWriteTokens: usage.cacheWrite } : {}),\n ...(usage.reasoning !== undefined ? { reasoningTokens: usage.reasoning } : {}),\n },\n };\n}\n\nexport interface TurnEventMapperState {\n accumulatedText: string;\n accumulatedThinking: string;\n toolStartTimes: Map<string, number>;\n iteration: number;\n maxIterations: number;\n}\n\nexport function createTurnEventMapperState(maxIterations = 15): TurnEventMapperState {\n return { accumulatedText: '', accumulatedThinking: '', toolStartTimes: new Map(), iteration: 0, maxIterations };\n}\n\nexport function* mapAgentEventToTurnEvents(\n event: AgentEvent,\n state: TurnEventMapperState,\n): Generator<TurnEvent> {\n switch (event.type) {\n case 'turn_start':\n state.iteration += 1;\n state.accumulatedText = '';\n state.accumulatedThinking = '';\n yield {\n type: 'iteration_start',\n iteration: state.iteration,\n maxIterations: state.maxIterations,\n };\n break;\n case 'message_end':\n if (event.message.role === 'assistant') {\n const message = event.message as AssistantMessage;\n yield turnUsageEvent(message.usage, { provider: message.provider, model: message.model, stopReason: message.stopReason });\n }\n break;\n case 'message_update':\n if (event.delta?.type === 'text_delta') {\n state.accumulatedText += event.delta.text;\n yield {\n type: 'chunk',\n text: event.delta.text,\n accumulated: state.accumulatedText,\n };\n } else if (event.delta?.type === 'thinking_delta') {\n state.accumulatedThinking += event.delta.thinking;\n yield { type: 'thinking', text: event.delta.thinking };\n }\n break;\n case 'tool_execution_start':\n state.toolStartTimes.set(event.toolCallId, performance.now());\n yield {\n type: 'tool_call',\n toolName: event.toolCall.name,\n args: (event.toolCall.arguments ?? {}) as Record<string, unknown>,\n toolUseId: event.toolCallId,\n };\n break;\n case 'tool_execution_end': {\n const started = state.toolStartTimes.get(event.toolCallId);\n const durationMs = started != null ? performance.now() - started : 0;\n state.toolStartTimes.delete(event.toolCallId);\n const toolName =\n event.result.role === 'toolResult'\n ? String(event.result.toolName ?? 'unknown')\n : 'unknown';\n const output =\n event.result.role === 'toolResult' && Array.isArray(event.result.content)\n ? event.result.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n : '';\n yield {\n type: 'tool_result',\n toolName,\n output,\n durationMs,\n toolUseId: event.toolCallId,\n };\n break;\n }\n default:\n break;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  import type { AgentDecisionConfig } from './types.js';
2
- export declare const DECISION_TASKS: readonly ["skills", "tools", "memory", "agents", "approval"];
2
+ export declare const DECISION_TASKS: readonly ["skills", "tools", "memory", "agents", "approval", "ambient"];
3
3
  /** Validate before installing any optional remote decision service. */
4
4
  export declare function normalizeAgentDecisionConfig(input: unknown): AgentDecisionConfig | undefined;
@@ -1,4 +1,4 @@
1
- export const DECISION_TASKS = ['skills', 'tools', 'memory', 'agents', 'approval'];
1
+ export const DECISION_TASKS = ['skills', 'tools', 'memory', 'agents', 'approval', 'ambient'];
2
2
  /** Validate before installing any optional remote decision service. */
3
3
  export function normalizeAgentDecisionConfig(input) {
4
4
  if (input === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/decision/config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentDecisionConfig, DecisionTask, DecisionTaskPolicy } from './types.js';\n\nexport const DECISION_TASKS = ['skills', 'tools', 'memory', 'agents', 'approval'] as const satisfies readonly DecisionTask[];\n\n/** Validate before installing any optional remote decision service. */\nexport function normalizeAgentDecisionConfig(input: unknown): AgentDecisionConfig | undefined {\n if (input === undefined) return undefined;\n const config = object(input, 'ai.decisions');\n keys(config, ['provider', ...DECISION_TASKS], 'ai.decisions');\n if (typeof config.provider !== 'string' || !/^root(?:\\/[a-z0-9][a-z0-9-]*)+$/.test(config.provider)) {\n throw new TypeError('ai.decisions.provider must be an exact Plugin owner, such as root/typesafe');\n }\n const policies: Partial<Record<DecisionTask, DecisionTaskPolicy>> = {};\n for (const task of DECISION_TASKS) {\n if (config[task] === undefined) continue;\n const label = `ai.decisions.${task}`;\n const policy = object(config[task], label);\n keys(policy, ['mode', 'timeoutMs', 'minConfidence', 'topK', 'maxCandidates', 'maxSelections'], label);\n if (typeof policy.mode !== 'string' || !['off', 'shadow', 'active'].includes(policy.mode)) {\n throw new TypeError(`${label}.mode must be off, shadow, or active`);\n }\n for (const field of ['timeoutMs', 'topK', 'maxCandidates', 'maxSelections']) {\n if (policy[field] !== undefined && (!Number.isSafeInteger(policy[field]) || Number(policy[field]) <= 0)) {\n throw new TypeError(`${label}.${field} must be a positive safe integer`);\n }\n }\n if (policy.timeoutMs !== undefined && Number(policy.timeoutMs) > 2_147_483_647) {\n throw new TypeError(`${label}.timeoutMs exceeds the Node timer limit`);\n }\n if (policy.minConfidence !== undefined && (typeof policy.minConfidence !== 'number'\n || !Number.isFinite(policy.minConfidence) || policy.minConfidence < 0 || policy.minConfidence > 1)) {\n throw new TypeError(`${label}.minConfidence must be between 0 and 1`);\n }\n policies[task] = Object.freeze({ ...policy }) as unknown as DecisionTaskPolicy;\n }\n return Object.freeze({ provider: config.provider, ...policies });\n}\n\nfunction object(input: unknown, label: string): Record<string, unknown> {\n if (!input || typeof input !== 'object' || Array.isArray(input)) throw new TypeError(`${label} must be an object`);\n return input as Record<string, unknown>;\n}\n\nfunction keys(input: Record<string, unknown>, allowed: readonly string[], label: string): void {\n if (Object.keys(input).some(key => !allowed.includes(key))) throw new TypeError(`${label} contains an unknown field`);\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/decision/config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentDecisionConfig, DecisionTask, DecisionTaskPolicy } from './types.js';\n\nexport const DECISION_TASKS = ['skills', 'tools', 'memory', 'agents', 'approval', 'ambient'] as const satisfies readonly DecisionTask[];\n\n/** Validate before installing any optional remote decision service. */\nexport function normalizeAgentDecisionConfig(input: unknown): AgentDecisionConfig | undefined {\n if (input === undefined) return undefined;\n const config = object(input, 'ai.decisions');\n keys(config, ['provider', ...DECISION_TASKS], 'ai.decisions');\n if (typeof config.provider !== 'string' || !/^root(?:\\/[a-z0-9][a-z0-9-]*)+$/.test(config.provider)) {\n throw new TypeError('ai.decisions.provider must be an exact Plugin owner, such as root/typesafe');\n }\n const policies: Partial<Record<DecisionTask, DecisionTaskPolicy>> = {};\n for (const task of DECISION_TASKS) {\n if (config[task] === undefined) continue;\n const label = `ai.decisions.${task}`;\n const policy = object(config[task], label);\n keys(policy, ['mode', 'timeoutMs', 'minConfidence', 'topK', 'maxCandidates', 'maxSelections'], label);\n if (typeof policy.mode !== 'string' || !['off', 'shadow', 'active'].includes(policy.mode)) {\n throw new TypeError(`${label}.mode must be off, shadow, or active`);\n }\n for (const field of ['timeoutMs', 'topK', 'maxCandidates', 'maxSelections']) {\n if (policy[field] !== undefined && (!Number.isSafeInteger(policy[field]) || Number(policy[field]) <= 0)) {\n throw new TypeError(`${label}.${field} must be a positive safe integer`);\n }\n }\n if (policy.timeoutMs !== undefined && Number(policy.timeoutMs) > 2_147_483_647) {\n throw new TypeError(`${label}.timeoutMs exceeds the Node timer limit`);\n }\n if (policy.minConfidence !== undefined && (typeof policy.minConfidence !== 'number'\n || !Number.isFinite(policy.minConfidence) || policy.minConfidence < 0 || policy.minConfidence > 1)) {\n throw new TypeError(`${label}.minConfidence must be between 0 and 1`);\n }\n policies[task] = Object.freeze({ ...policy }) as unknown as DecisionTaskPolicy;\n }\n return Object.freeze({ provider: config.provider, ...policies });\n}\n\nfunction object(input: unknown, label: string): Record<string, unknown> {\n if (!input || typeof input !== 'object' || Array.isArray(input)) throw new TypeError(`${label} must be an object`);\n return input as Record<string, unknown>;\n}\n\nfunction keys(input: Record<string, unknown>, allowed: readonly string[], label: string): void {\n if (Object.keys(input).some(key => !allowed.includes(key))) throw new TypeError(`${label} contains an unknown field`);\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { AIConfig, DecisionProvider, DecisionTaskConfig } from '@zhin.js/ai';
2
- export type DecisionTask = 'skills' | 'tools' | 'memory' | 'agents' | 'approval';
2
+ export type DecisionTask = 'skills' | 'tools' | 'memory' | 'agents' | 'approval' | 'ambient';
3
3
  export type DecisionMode = 'off' | 'shadow' | 'active';
4
4
  export type DecisionTaskPolicy = DecisionTaskConfig;
5
5
  export type AgentDecisionConfig = NonNullable<AIConfig['decisions']>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/decision/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AIConfig, DecisionProvider, DecisionTaskConfig } from '@zhin.js/ai';\n\nexport type DecisionTask = 'skills' | 'tools' | 'memory' | 'agents' | 'approval';\nexport type DecisionMode = 'off' | 'shadow' | 'active';\n\nexport type DecisionTaskPolicy = DecisionTaskConfig;\nexport type AgentDecisionConfig = NonNullable<AIConfig['decisions']>;\n\n/** Observations contain no message, candidate name, parameter, or private text. */\nexport interface DecisionObservation {\n readonly task: DecisionTask;\n readonly mode: DecisionMode;\n readonly outcome: 'selected' | 'abstained' | 'failed' | 'shadow';\n readonly candidates: number;\n readonly selected: number;\n readonly durationMs: number;\n readonly model?: string;\n readonly reason?: 'provider_error' | 'timeout' | 'low_confidence' | 'no_relevant_candidate' | 'invalid_response';\n readonly usage?: Readonly<{ inputTokens: number; outputTokens: number; totalTokens: number }>;\n}\n\nexport interface AgentDecisionRuntime {\n readonly provider: DecisionProvider;\n readonly config: AgentDecisionConfig;\n readonly observe?: (observation: DecisionObservation) => void;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/decision/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AIConfig, DecisionProvider, DecisionTaskConfig } from '@zhin.js/ai';\n\nexport type DecisionTask = 'skills' | 'tools' | 'memory' | 'agents' | 'approval' | 'ambient';\nexport type DecisionMode = 'off' | 'shadow' | 'active';\n\nexport type DecisionTaskPolicy = DecisionTaskConfig;\nexport type AgentDecisionConfig = NonNullable<AIConfig['decisions']>;\n\n/** Observations contain no message, candidate name, parameter, or private text. */\nexport interface DecisionObservation {\n readonly task: DecisionTask;\n readonly mode: DecisionMode;\n readonly outcome: 'selected' | 'abstained' | 'failed' | 'shadow';\n readonly candidates: number;\n readonly selected: number;\n readonly durationMs: number;\n readonly model?: string;\n readonly reason?: 'provider_error' | 'timeout' | 'low_confidence' | 'no_relevant_candidate' | 'invalid_response';\n readonly usage?: Readonly<{ inputTokens: number; outputTokens: number; totalTokens: number }>;\n}\n\nexport interface AgentDecisionRuntime {\n readonly provider: DecisionProvider;\n readonly config: AgentDecisionConfig;\n readonly observe?: (observation: DecisionObservation) => void;\n}\n"]}
@@ -4,9 +4,11 @@ import type { AgentOutputElement } from '../outbound/agent-output.js';
4
4
  *
5
5
  * Consumed by processMessageStream() callers; produced by the turn pipeline.
6
6
  */
7
- import type { ToolExecutionCause } from '@zhin.js/ai';
7
+ import type { ToolExecutionCause, TokenUsage } from '@zhin.js/ai';
8
8
  import type { DecisionObservation } from '../decision/types.js';
9
9
  export interface TurnUsage {
10
+ reported?: TokenUsage['reported'];
11
+ cacheWriteTokens?: number;
10
12
  promptTokens: number;
11
13
  completionTokens: number;
12
14
  totalTokens: number;
@@ -108,6 +110,10 @@ export interface ThinkingEvent {
108
110
  /** Per-model-iteration usage, emitted before the next tool/model iteration. */
109
111
  export interface UsageEvent {
110
112
  type: 'usage';
113
+ provider?: string;
114
+ model?: string;
115
+ durationMs?: number;
116
+ stopReason?: string;
111
117
  usage: TurnUsage;
112
118
  }
113
119
  export interface TurnEndEvent {
@@ -1 +1 @@
1
- {"version":3,"file":"turn-event.js","sourceRoot":"","sources":["../../src/event/turn-event.ts"],"names":[],"mappings":"AAwLA,MAAM,UAAU,mBAAmB,CAAC,KAAgB;IAClD,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU;WAC3B,KAAK,CAAC,IAAI,KAAK,OAAO;WACtB,KAAK,CAAC,IAAI,KAAK,gBAAgB;WAC/B,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC;AACxC,CAAC","sourcesContent":["import type { AgentOutputElement } from '../outbound/agent-output.js';\n/**\n * TurnEvent — structured event union for the AsyncGenerator streaming API.\n *\n * Consumed by processMessageStream() callers; produced by the turn pipeline.\n */\nimport type { ToolExecutionCause, Usage } from '@zhin.js/ai';\nimport type { DecisionObservation } from '../decision/types.js';\n\nexport interface TurnUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n /** Prompt tokens served from the provider's prompt cache, when reported. */\n cacheReadTokens?: number;\n /** Completion tokens spent on reasoning (e.g. Gemini thoughts), when reported. */\n reasoningTokens?: number;\n}\n\nexport type TurnEvent =\n | TurnStartEvent\n | ChunkEvent\n | CapabilityResolutionEvent\n | DecisionEvaluationEvent\n | MediaResolutionEvent\n | IterationStartEvent\n | ToolCallEvent\n | ToolResultEvent\n | ToolDeniedEvent\n | ToolFailedEvent\n | ToolCancelledEvent\n | ThinkingEvent\n | UsageEvent\n | TurnEndEvent\n | TurnErrorEvent\n | TurnCancelledEvent\n | TurnBudgetExceededEvent\n | SubagentStartEvent\n | SubagentProgressEvent\n | SubagentEndEvent\n | McpConnectEvent\n | McpToolCallEvent;\n\nexport interface TurnStartEvent {\n type: 'turn_start';\n sessionId: string;\n turnId: string;\n /** Native inbound message anchor when the turn originates from IM. */\n sourceMessageId?: string;\n}\n\n/** Operational metadata only: never contains request text, candidate content, or credentials. */\nexport interface DecisionEvaluationEvent extends DecisionObservation {\n type: 'decision_evaluation';\n}\n\nexport interface ChunkEvent {\n type: 'chunk';\n text: string;\n accumulated: string;\n}\n\nexport interface IterationStartEvent {\n type: 'iteration_start';\n iteration: number;\n maxIterations: number;\n}\n\n/** Immutable capability plan selected before model execution. */\nexport interface CapabilityResolutionEvent {\n type: 'capability_resolution';\n mode: 'deferred' | 'direct';\n resolvedBy: 'execution-plan' | 'affinity' | 'session';\n tools: string[];\n skills: string[];\n missingTools: string[];\n missingSkills: string[];\n}\n\n/** Durable terminal fact for one inbound media item. */\nexport interface MediaResolutionEvent {\n type: 'media_resolution';\n index: number;\n mediaKind: 'image' | 'audio' | 'video' | 'file';\n status: 'accepted' | 'derived' | 'unsupported' | 'rejected' | 'failed';\n code: string;\n /** Set when the text came from the perception pre-pass (`code: 'media_perception'`). */\n provenance?: {\n source: 'media_perception';\n provider: string;\n model: string;\n cached: boolean;\n };\n}\n\nexport interface ToolCallEvent {\n type: 'tool_call';\n toolName: string;\n args: Record<string, unknown>;\n toolUseId: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolResultEvent {\n type: 'tool_result';\n toolName: string;\n output: unknown;\n durationMs: number;\n toolUseId: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolDeniedEvent {\n type: 'tool_denied';\n toolName: string;\n toolUseId: string;\n policy: string;\n reason: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolFailedEvent {\n type: 'tool_failed';\n toolName: string;\n toolUseId: string;\n error: string;\n durationMs: number;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolCancelledEvent {\n type: 'tool_cancelled';\n toolName: string;\n toolUseId: string;\n reason: string;\n durationMs: number;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ThinkingEvent {\n type: 'thinking';\n text: string;\n}\n\n/** Per-model-iteration usage, emitted before the next tool/model iteration. */\nexport interface UsageEvent {\n type: 'usage';\n usage: TurnUsage;\n}\n\nexport interface TurnEndEvent {\n type: 'turn_end';\n output: AgentOutputElement[];\n usage: TurnUsage;\n /** Control-only ingress links its own principal/journal to the affected turn. */\n control?: Readonly<{\n intent: 'steer' | 'follow_up' | 'observe';\n targetTurnId?: string;\n }>;\n}\n\nexport interface TurnErrorEvent {\n type: 'error';\n error: Error;\n recoverable: boolean;\n /** Stable failure taxonomy persisted with the terminal fact. */\n code?: string;\n}\n\n/** A turn stopped by timeout, replacement, explicit cancellation, or disposal. */\nexport interface TurnCancelledEvent {\n type: 'turn_cancelled';\n reason: string;\n code: 'cancelled' | 'superseded' | 'timeout' | 'disposed';\n}\n\nexport interface TurnBudgetExceededEvent {\n type: 'budget_exceeded';\n budget: string;\n usage: TurnUsage;\n}\n\nexport type TurnTerminalEvent = TurnEndEvent | TurnErrorEvent | TurnCancelledEvent | TurnBudgetExceededEvent;\n\nexport function isTurnTerminalEvent(event: TurnEvent): event is TurnTerminalEvent {\n return event.type === 'turn_end'\n || event.type === 'error'\n || event.type === 'turn_cancelled'\n || event.type === 'budget_exceeded';\n}\n\nexport interface SubagentStartEvent {\n type: 'subagent_start';\n taskId: string;\n agentName?: string;\n description: string;\n}\n\nexport interface SubagentProgressEvent {\n type: 'subagent_progress';\n taskId: string;\n summary: string;\n}\n\nexport interface SubagentEndEvent {\n type: 'subagent_end';\n taskId: string;\n status: 'ok' | 'error';\n result?: string;\n}\n\nexport interface McpConnectEvent {\n type: 'mcp_connect';\n serverName: string;\n status: 'connecting' | 'connected' | 'error';\n}\n\nexport interface McpToolCallEvent {\n type: 'mcp_tool_call';\n serverName: string;\n toolName: string;\n}\n"]}
1
+ {"version":3,"file":"turn-event.js","sourceRoot":"","sources":["../../src/event/turn-event.ts"],"names":[],"mappings":"AA8LA,MAAM,UAAU,mBAAmB,CAAC,KAAgB;IAClD,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU;WAC3B,KAAK,CAAC,IAAI,KAAK,OAAO;WACtB,KAAK,CAAC,IAAI,KAAK,gBAAgB;WAC/B,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC;AACxC,CAAC","sourcesContent":["import type { AgentOutputElement } from '../outbound/agent-output.js';\n/**\n * TurnEvent — structured event union for the AsyncGenerator streaming API.\n *\n * Consumed by processMessageStream() callers; produced by the turn pipeline.\n */\nimport type { ToolExecutionCause, Usage, TokenUsage } from '@zhin.js/ai';\nimport type { DecisionObservation } from '../decision/types.js';\n\nexport interface TurnUsage {\n reported?: TokenUsage['reported'];\n cacheWriteTokens?: number;\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n /** Prompt tokens served from the provider's prompt cache, when reported. */\n cacheReadTokens?: number;\n /** Completion tokens spent on reasoning (e.g. Gemini thoughts), when reported. */\n reasoningTokens?: number;\n}\n\nexport type TurnEvent =\n | TurnStartEvent\n | ChunkEvent\n | CapabilityResolutionEvent\n | DecisionEvaluationEvent\n | MediaResolutionEvent\n | IterationStartEvent\n | ToolCallEvent\n | ToolResultEvent\n | ToolDeniedEvent\n | ToolFailedEvent\n | ToolCancelledEvent\n | ThinkingEvent\n | UsageEvent\n | TurnEndEvent\n | TurnErrorEvent\n | TurnCancelledEvent\n | TurnBudgetExceededEvent\n | SubagentStartEvent\n | SubagentProgressEvent\n | SubagentEndEvent\n | McpConnectEvent\n | McpToolCallEvent;\n\nexport interface TurnStartEvent {\n type: 'turn_start';\n sessionId: string;\n turnId: string;\n /** Native inbound message anchor when the turn originates from IM. */\n sourceMessageId?: string;\n}\n\n/** Operational metadata only: never contains request text, candidate content, or credentials. */\nexport interface DecisionEvaluationEvent extends DecisionObservation {\n type: 'decision_evaluation';\n}\n\nexport interface ChunkEvent {\n type: 'chunk';\n text: string;\n accumulated: string;\n}\n\nexport interface IterationStartEvent {\n type: 'iteration_start';\n iteration: number;\n maxIterations: number;\n}\n\n/** Immutable capability plan selected before model execution. */\nexport interface CapabilityResolutionEvent {\n type: 'capability_resolution';\n mode: 'deferred' | 'direct';\n resolvedBy: 'execution-plan' | 'affinity' | 'session';\n tools: string[];\n skills: string[];\n missingTools: string[];\n missingSkills: string[];\n}\n\n/** Durable terminal fact for one inbound media item. */\nexport interface MediaResolutionEvent {\n type: 'media_resolution';\n index: number;\n mediaKind: 'image' | 'audio' | 'video' | 'file';\n status: 'accepted' | 'derived' | 'unsupported' | 'rejected' | 'failed';\n code: string;\n /** Set when the text came from the perception pre-pass (`code: 'media_perception'`). */\n provenance?: {\n source: 'media_perception';\n provider: string;\n model: string;\n cached: boolean;\n };\n}\n\nexport interface ToolCallEvent {\n type: 'tool_call';\n toolName: string;\n args: Record<string, unknown>;\n toolUseId: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolResultEvent {\n type: 'tool_result';\n toolName: string;\n output: unknown;\n durationMs: number;\n toolUseId: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolDeniedEvent {\n type: 'tool_denied';\n toolName: string;\n toolUseId: string;\n policy: string;\n reason: string;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolFailedEvent {\n type: 'tool_failed';\n toolName: string;\n toolUseId: string;\n error: string;\n durationMs: number;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ToolCancelledEvent {\n type: 'tool_cancelled';\n toolName: string;\n toolUseId: string;\n reason: string;\n durationMs: number;\n causedBy?: ToolExecutionCause;\n}\n\nexport interface ThinkingEvent {\n type: 'thinking';\n text: string;\n}\n\n/** Per-model-iteration usage, emitted before the next tool/model iteration. */\nexport interface UsageEvent {\n type: 'usage';\n provider?: string;\n model?: string;\n durationMs?: number;\n stopReason?: string;\n usage: TurnUsage;\n}\n\nexport interface TurnEndEvent {\n type: 'turn_end';\n output: AgentOutputElement[];\n usage: TurnUsage;\n /** Control-only ingress links its own principal/journal to the affected turn. */\n control?: Readonly<{\n intent: 'steer' | 'follow_up' | 'observe';\n targetTurnId?: string;\n }>;\n}\n\nexport interface TurnErrorEvent {\n type: 'error';\n error: Error;\n recoverable: boolean;\n /** Stable failure taxonomy persisted with the terminal fact. */\n code?: string;\n}\n\n/** A turn stopped by timeout, replacement, explicit cancellation, or disposal. */\nexport interface TurnCancelledEvent {\n type: 'turn_cancelled';\n reason: string;\n code: 'cancelled' | 'superseded' | 'timeout' | 'disposed';\n}\n\nexport interface TurnBudgetExceededEvent {\n type: 'budget_exceeded';\n budget: string;\n usage: TurnUsage;\n}\n\nexport type TurnTerminalEvent = TurnEndEvent | TurnErrorEvent | TurnCancelledEvent | TurnBudgetExceededEvent;\n\nexport function isTurnTerminalEvent(event: TurnEvent): event is TurnTerminalEvent {\n return event.type === 'turn_end'\n || event.type === 'error'\n || event.type === 'turn_cancelled'\n || event.type === 'budget_exceeded';\n}\n\nexport interface SubagentStartEvent {\n type: 'subagent_start';\n taskId: string;\n agentName?: string;\n description: string;\n}\n\nexport interface SubagentProgressEvent {\n type: 'subagent_progress';\n taskId: string;\n summary: string;\n}\n\nexport interface SubagentEndEvent {\n type: 'subagent_end';\n taskId: string;\n status: 'ok' | 'error';\n result?: string;\n}\n\nexport interface McpConnectEvent {\n type: 'mcp_connect';\n serverName: string;\n status: 'connecting' | 'connected' | 'error';\n}\n\nexport interface McpToolCallEvent {\n type: 'mcp_tool_call';\n serverName: string;\n toolName: string;\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -121,6 +121,9 @@ export { buildAgentSurfaceInfoReport, formatAgentSurfaceInfoReport, } from './di
121
121
  export type { AgentSurfaceInfoReport, AgentSurfacePluginInfo, AgentSurfaceWorkspaceAgentInfo, } from './discovery/agent-surface-info.js';
122
122
  export * from './detached-task/index.js';
123
123
  export { aiCompletionToken, AiCompletionQuotaError } from './plugin-runtime/ai-completion.js';
124
- export type { AiCompletion, AiCompletionInput, AiCompletionResult, AiCompletionUntrustedInput, UsageSubject, } from './plugin-runtime/ai-completion.js';
124
+ export type { AiCompletion, AiCompletionInput, AiCompletionResult, AiCompletionUntrustedInput, AiCompletionUsageShare, UsageSubject, } from './plugin-runtime/ai-completion.js';
125
125
  export type { AgentOutputElement } from './outbound/agent-output.js';
126
126
  export { renderAgentOutput, splitOutputMessages } from './outbound/agent-output.js';
127
+ export { REACTION_SEGMENT_TYPE } from './outbound/structured-reply.js';
128
+ export { chatFailureLine, chatFailureKindOf } from './outbound/chat-failure.js';
129
+ export type { ChatFailureKind, ChatFailureOptions } from './outbound/chat-failure.js';
package/lib/index.js CHANGED
@@ -85,4 +85,6 @@ export * from './detached-task/index.js';
85
85
  // Plain text completion for plugins (#804): tool-free, with retry and fallback.
86
86
  export { aiCompletionToken, AiCompletionQuotaError } from './plugin-runtime/ai-completion.js';
87
87
  export { renderAgentOutput, splitOutputMessages } from './outbound/agent-output.js';
88
+ export { REACTION_SEGMENT_TYPE } from './outbound/structured-reply.js';
89
+ export { chatFailureLine, chatFailureKindOf } from './outbound/chat-failure.js';
88
90
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AI Agent runtime and generation-owned support resources.\n *\n * Agent Tools are owned by `@zhin.js/tool` and published through the\n * generation ToolIndex. AgentResourceHub owns skills, subagents, and hooks;\n * MCP connections are generation-owned by `@zhin.js/mcp-feature`.\n * @module @zhin.js/agent\n */\n\n// ── Agent-specific modules ──\n\nexport { AIService } from './service.js';\nexport type { ServiceAgent, ServiceAgentResult, CreateServiceAgentOptions } from './service.js';\nexport { createAgentSession } from './create-agent-session.js';\nexport type { AgentSessionHandle, CreateAgentSessionOptions } from './create-agent-session.js';\nexport { PluginAILoopHookRegistry } from './plugin-loop-hooks.js';\nexport type {\n PluginBeforeToolCallHandler,\n PluginAfterToolCallHandler,\n PluginTransformContextHandler,\n} from './plugin-loop-hooks.js';\n\nexport { ZhinAgent } from './zhin-agent/index.js';\nexport type { AgentTurnConfiguration, AgentTurnRequest } from './zhin-agent/index.js';\nexport {\n pluginToolToAgentTool,\n agentToolToLlmTool,\n agentToolsToLlmTools,\n} from './tool-bridge.js';\nexport type { NormalizableTool } from './tool-bridge.js';\nexport type {\n ZhinAgentConfig,\n OnChunkCallback,\n} from './config/index.js';\nexport type {\n IAgentTurnProcessor,\n IAgentSessionManager,\n IAgentDiagnostics,\n IAgentConfigurator,\n} from './config/agent-interfaces.js';\nexport type {\n TurnEvent, TurnUsage,\n TurnStartEvent, ChunkEvent, CapabilityResolutionEvent, IterationStartEvent,\n ToolCallEvent as TurnToolCallEvent,\n ToolResultEvent,\n ThinkingEvent, TurnEndEvent, TurnErrorEvent,\n TurnBudgetExceededEvent,\n SubagentStartEvent, SubagentProgressEvent, SubagentEndEvent,\n McpConnectEvent, McpToolCallEvent,\n} from './event/turn-event.js';\nexport {\n createTurnIngress,\n resolveTurnContextValue,\n turnPermissionSubject,\n} from './turn/turn-ingress.js';\nexport { executeAgentTurn } from './turn/execute-agent-turn.js';\nexport type { TurnEventObserver, TurnEventSource } from './turn/execute-agent-turn.js';\nexport type {\n ActivityPort,\n DeliveryIntent,\n DeliveryOutcome,\n DeliveryPort,\n FrozenCapabilityCatalog,\n ReplyPort,\n TurnIdentity,\n TurnAccessContext,\n TurnIngress,\n TurnIngressInput,\n TurnIntent,\n TurnIntentKind,\n TurnJournalPort,\n TurnInput,\n TurnMedia,\n TurnOrigin,\n TurnOutcome,\n TurnPolicyContext,\n TurnExecutionProfile,\n TurnPorts,\n TurnPrincipal,\n TurnRequest,\n TurnRequestPorts,\n TurnScope,\n TurnSessionAddress,\n} from './turn/turn-ingress.js';\n\nexport {\n DEFAULT_CONFIG as ZHIN_AGENT_DEFAULT_CONFIG,\n DEFAULT_ALWAYS_LOADED_TOOLS,\n SECTION_SEP,\n} from './config/index.js';\nexport { MODEL_HARNESS_DEFAULTS, resolveModelHarness, mergeModelHarnessValues } from './config/model-harness-runtime.js';\nexport type { ModelHarnessRow, ResolvedModelHarness, ModelHarnessConfig } from './config/model-harness.js';\nexport {\n checkExecPolicy, applyExecPolicyToTools, resolveExecAllowlist, EXEC_PRESETS,\n isDangerousCommand, stripEnvVarPrefix, stripSafeWrappers, splitCompoundCommand, extractCommandName,\n type ExecPolicyResult,\n} from './security/exec-policy.js';\nexport {\n OWNER_APPROVE_ALWAYS_TOOL,\n OwnerApprovalRuntime,\n} from './security/owner-approval-runtime.js';\nexport type {\n OwnerApprovalAddress,\n OwnerApprovalCommandContext,\n ToolRequesterRole,\n} from './security/owner-approval-runtime.js';\nexport {\n handleRuntimeManagementCommand,\n} from './init/runtime-management-commands.js';\nexport type {\n RuntimeManagementDeps,\n RuntimeManagementSenderRoles,\n} from './init/runtime-management-commands.js';\nexport {\n buildRichSystemPrompt,\n buildLiteSystemPrompt,\n buildUserMessageWithHistory,\n describePromptSectionsForDebug,\n createDefaultPromptAssemblyRegistry,\n enforcePromptBudget,\n} from './prompt/system-prompt.js';\nexport type { RichSystemPromptContext, PromptSectionDebugInfo } from './prompt/system-prompt.js';\nexport { PromptAssemblyRegistry } from './prompt/prompt-assembly-registry.js';\nexport type {\n PromptAssemblyEntry,\n PromptAssemblySection,\n PromptSectionRegistry,\n} from './prompt/prompt-assembly-registry.js';\nexport { promptAssemblyToken } from './prompt/tokens.js';\nexport type { PromptAssemblyToken, PromptAssemblyResource } from './prompt/tokens.js';\nexport {\n defineAgentPromptSection,\n isPromptSectionIndex,\n PromptSectionIndex,\n promptSectionFeatureId,\n} from '@zhin.js/prompt-section';\nexport type {\n AgentPromptSectionDefinition,\n AgentPromptSectionInput,\n PromptProfile,\n PromptSectionDescriptor,\n PromptSectionLayer,\n PromptSectionRetention,\n} from '@zhin.js/prompt-section';\nexport {\n buildAgentsEnvelopeContext,\n collectAgentsInstructionChain,\n} from './context/agents-instruction.js';\nexport type { AgentsInstructionEntry } from './context/agents-instruction.js';\nexport {\n resolveWorkspacePrompt,\n} from './prompt/workspace-prompt.js';\nexport type { WorkspacePromptRole } from './prompt/workspace-prompt.js';\nexport { createUserProfileTool } from './tool/context-tools.js';\nexport { createSpawnTaskTool } from './spawn/spawn-task-tool.js';\nexport * from './interaction/index.js';\n\nexport { UserProfileStore, AI_USER_PROFILE_MODEL } from './user-profile.js';\n\n// ── Capability Seam ────────────────────────────────────────────────────────\nexport type {\n SeamProvider,\n SeamScope,\n ToolService,\n ToolServiceProvider,\n ToolSchema,\n ToolExecutionResult,\n SkillService,\n SkillServiceProvider,\n CapabilitySeamToken,\n ProjectedSeamTool,\n ProjectedSeamSkill,\n} from './seam/index.js';\nexport { SeamProviderRegistry, SeamIntegration } from './seam/index.js';\nexport { capabilitySeamToken } from './seam/index.js';\nexport { BuiltinToolService } from './builtins/builtin-tool-service.js';\nexport { SkillRegistryAsService } from './skill/skill-registry-as-service.js';\n\nexport { SubagentSystem } from './subagent/index.js';\nexport { SubagentRuntime } from './subagent/subagent-runtime.js';\nexport type {\n SubagentOrigin, SubagentResultDelivery, SubagentResultSender, SpawnOptions, SubagentRuntimeOptions,\n SubagentCompletePayload,\n} from './subagent/index.js';\nexport { RESERVED_TOOL_NAMES, RESERVED_TOOL_NAME_PREFIXES } from './reserved-tools.js';\n\nexport {\n stampToolGeneration,\n} from './tool/tool-system.js';\nexport { FileJournalStore } from './journal/index.js';\nexport { PersistentTurnJournal } from './journal/index.js';\n\nexport {\n createScheduleTools,\n generateScheduleJobId,\n SCHEDULE_JOBS_FILENAME,\n} from './schedule-manager.js';\nexport type { ScheduleManager, ScheduleToolRegistration } from './schedule-manager.js';\n\nexport {\n ScheduleJobEngine,\n ScheduleJobStore,\n AssistantEventIngress,\n JobWorker,\n createScheduleJobStoreFromConfig,\n getScheduleJobsPath,\n resolveAssistantConfig,\n resolveAssistantDefaultsConfig,\n resolveAssistantEventsConfig,\n isAssistantEventsActive,\n createNotificationRouter,\n imNotifyToSendOptions,\n parseJobNotify,\n SCHEDULE_JOBS_VERSION,\n syncProfileRoutinesToStore,\n scheduleJobCreatorFromPrincipal,\n parseScheduleJobCreator,\n parseExecutionPlanFromArgs,\n parseScheduleJobExecutionPlan,\n addScheduleJob,\n parseScheduleAddFromToolArgs,\n parseScheduleAddFromRpcMessage,\n bootstrapAssistantHome,\n isAssistantHomeActive,\n resolveAssistantHomeConfig,\n} from './assistant/index.js';\nexport * from './schedule-domain/index.js';\nexport type {\n AssistantConfig,\n AssistantDefaultsConfig,\n AssistantEventsConfig,\n AssistantProfileConfig,\n AssistantProfile,\n NotificationRouter,\n BootstrapAssistantHomeResult,\n HomeToolRegistration,\n ScheduleJob,\n ScheduleJobFile,\n ScheduleJobCreator,\n ScheduleJobExecutionPlan,\n ScheduleInvocationContext,\n AssistantEventRequest,\n AssistantEventResult,\n} from './assistant/index.js';\nexport {\n loadAssistantProfileFile,\n loadBootstrapWithProfile,\n syncProfileHeartbeatToStore,\n pruneStaleProfileCronJobs,\n mergeProfileDeviceAliases,\n validateAssistantProfile,\n resolveAssistantProfileConfig,\n ASSISTANT_PROFILE_VERSION,\n DEFAULT_PROFILE_FILENAME,\n PROFILE_HEARTBEAT_JOB_ID,\n PROFILE_MORNING_BRIEF_JOB_ID,\n PROFILE_BEDTIME_CHECK_JOB_ID,\n} from './assistant/index.js';\n\nexport type {\n ApprovalDecision,\n ApprovalDecisionMemory,\n ApprovalDecisionPort,\n ApprovalOutcome,\n ApprovalOutcomePort,\n ApprovalPort,\n ApprovalRequestInput,\n} from './session/approval-port.js';\nexport {\n approvalOutcomeToDecision,\n formatApprovalDenial,\n requestApprovalOutcome,\n} from './session/approval-port.js';\nexport {\n ApprovalReviewAgent,\n createAutoApprovalPort,\n createBypassApprovalPort,\n} from './session/approval-review-agent.js';\nexport type {\n ApprovalReviewAgentOptions,\n ApprovalReviewDecision,\n} from './session/approval-review-agent.js';\nexport { beginIngressTurnSession } from './session/turn-ingress-session.js';\n\nexport type {\n AgentRole,\n AgentRoleConfig,\n} from './resource-hub/role-configs.js';\nexport { AGENT_ROLE_CONFIGS } from './resource-hub/role-configs.js';\n\nexport {\n loadBootstrapFiles, buildContextFiles, buildBootstrapContextSection,\n buildStableContextFiles, buildStableBootstrapSection,\n loadSoulPersona, loadToolsGuide, loadAgentsMemory,\n STABLE_BOOTSTRAP_FILENAMES,\n} from './bootstrap.js';\nexport { getFileMemoryContext, getMemoryDir } from './memory-layers.js';\nexport type { BootstrapFile, ContextFile } from './bootstrap.js';\n\nexport {\n NO_MEDIA_AUTHORITY,\n preprocessInboundMedia,\n publishOutboundElements,\n resolveMultimodalConfig,\n resolveOutboundCapabilities,\n} from './media/index.js';\nexport type { AudioTranscriptionPort, MediaBinaryPayload, MultimodalConfig, OutboundMediaAuthority, OutboundMediaCapabilities } from './media/index.js';\nexport { createLlmMediaPerceptionPort, resolvePerceptionConfig } from './media/index.js';\nexport type { MediaPerception, MediaPerceptionPort, PerceptionMediaKind, ResolvedPerceptionConfig } from './media/index.js';\n\nexport { filterImDeliveryContent } from './segment/filter-im-delivery.js';\n\nexport {\n loadMemoryLayers,\n buildMemoryPrompt,\n safeSessionKey,\n getMemoryRoot,\n checkMemoryWritePath,\n classifyMemoryWritePath,\n formatMemoryPathsHint,\n resolveMemoryPromptOptions,\n DEFAULT_MEMORY_BUDGETS,\n} from './memory-layers.js';\nexport type {\n MemoryLayerBudgets,\n MemoryPromptOptions,\n MemoryLayersInput,\n LoadedMemoryLayers,\n MemoryWriteScope,\n MemoryWriteDecision,\n} from './memory-layers.js';\n\nexport { aiHookRuntimeBus, AIHookRuntimeBus } from './ai-hook-runtime-bus.js';\n\nexport {\n createAIHookBusPayload,\n isAISessionNewPayload,\n isAISessionCompactPayload,\n} from './ai-event-bus.js';\nexport type {\n AISessionNewPayload,\n AISessionCompactPayload,\n} from './ai-event-bus.js';\nexport {\n AI_EVENT_NAMES,\n subscribeAIEventsOnTarget,\n} from './ai-event-subscriber.js';\nexport { originFromMessage } from './spawn/spawn-task-tool.js';\nexport type {\n AIEventFilter,\n AIEventHandlers,\n AIEventTarget,\n} from './ai-event-subscriber.js';\nexport type {\n AIEventName,\n AIEventSource,\n AIEventMode,\n AIEventPath,\n AIEventPayload,\n} from './ai-event-contract.js';\nexport { AgentEventBus } from './event/ai-event-bus.js';\n\n// ── Activity Feedback(替代 endpoint typingIndicator)──\nexport {\n ActivityFeedbackManager,\n resolveActivityFeedbackPhaseConfig,\n isActivityFeedbackEnabled,\n toActivityFeedbackEventContext,\n resolveActivitySceneType,\n resolveActivityEventTargets,\n enableActivityFeedbackForBot,\n isGenericActivityFeedbackManager,\n resolveSubagentActivityTag,\n formatSubagentActivityPrefix,\n withSubagentActivityPrefix,\n applySubagentActivityPrefixToConfig,\n resolveActivityFeedbackSessionId,\n} from './activity-feedback/index.js';\nexport type {\n ActivityFeedbackType,\n ActivityFeedbackPhase,\n ActivitySceneType,\n ActivityFeedbackPhaseConfig,\n ActivityFeedbackScenePhases,\n ActivityFeedbackConfig,\n ResolvedActivityFeedbackPhaseConfig,\n EndpointWithActivityFeedback,\n ActivityFeedbackSendPort,\n PlatformActivityFeedbackManager,\n PlatformActivityFeedbackStartOptions,\n BotActivityFeedbackManager,\n ActivityFeedbackEventContext,\n ActivityFeedbackGatePhase,\n} from './activity-feedback/index.js';\n\nexport type {\n ProactiveSendContext,\n ProactiveSendSource,\n ProactiveOutboundService,\n} from './outbound/send-proactive.js';\nexport { deliverScheduleToAdapter } from './assistant/deliver-schedule-to-adapter.js';\nexport type { DeliverScheduleToAdapterInput } from './assistant/deliver-schedule-to-adapter.js';\nexport { createTaskExecutor } from './task-executor.js';\nexport type {\n TaskExecutor,\n TaskExecutionOptions,\n TaskExecutionResult,\n TaskExecutorDeps,\n ScheduleActivityEvent,\n ScheduleActivityPort,\n} from './task-executor.js';\nexport type {\n ScheduleTurnExecutionRequest,\n ScheduleTurnPort,\n} from './schedule-domain/execution-domain.js';\nexport { demoteScheduleCreator } from './schedule-domain/security-harness.js';\nexport {\n SKILL_DISCLOSURE_TOOLS,\n SKILL_DISCLOSURE_STEPS,\n SKILL_DISCLOSURE_PROMPT_HINT,\n} from './skill/progressive-disclosure.js';\n// ── Typing Indicator ──\nexport {\n TypingIndicatorManager,\n ReactionTypingIndicator,\n MessageTypingIndicator,\n NoneTypingIndicator,\n ReactionTypingIndicatorAdapter,\n NativeTypingIndicatorAdapter,\n NativeTypingIndicator,\n GenericTypingIndicatorAdapter,\n} from './typing-indicator/index.js';\nexport type {\n TypingIndicatorType,\n TypingIndicatorConfig,\n TypingIndicatorOptions,\n TypingIndicator,\n TypingIndicatorAdapter,\n} from './typing-indicator/index.js';\n\n// ── Activity Feedback 平台能力 ──\nexport {\n PLATFORM_FEATURES,\n buildTypingSendContent,\n} from './typing-indicator/adapter-integration.js';\nexport type {\n PlatformFeatures,\n} from './typing-indicator/adapter-integration.js';\n\n// ── MCP Client ──\nexport { McpClientManager, McpClientConnection, mcpToolToAgentTool } from './mcp-client/index.js';\nexport type { McpClientConnectionState, McpToolDefinition } from './mcp-client/index.js';\n\n// ── Common adapter tools (migrated from core) ──\nexport {\n createSceneManagementTools, buildSceneMethodArgs,\n SCENE_MANAGEMENT_METHOD_SPECS, SCENE_MANAGEMENT_SKILL_TAGS, SCENE_MANAGEMENT_SKILL_KEYWORDS,\n} from './common-adapter-tools.js';\nexport type { ISceneManagement, SceneManagementMethodSpec } from './common-adapter-tools.js';\n\n// ── Agent capability resource hub ──\nexport { AgentResourceHub } from './resource-hub/index.js';\nexport {\n ResourceRegistry,\n canAccessTool,\n normalizeTool,\n SkillRegistry,\n SubAgentRegistry,\n McpRegistry,\n HookRegistry,\n createAIHookEvent,\n} from './resource-hub/index.js';\nexport type {\n McpConnection,\n ResourceScope, ResourceEntry,\n Tool, Message, SenderRole, ToolScope, FileRole,\n ToolParametersSchema, PropertySchema, ToolJsonSchema,\n Skill, SkillMetadata,\n SubAgentDef, AgentPreset,\n McpServerEntry, McpResource, McpPrompt,\n AIHook, AIHookEvent as OrchestratorHookEvent, AIHookEventType as OrchestratorHookEventType, AIHookHandler as OrchestratorHookHandler,\n ToolHookDecision, PostToolHookDecision,\n PreToolUseEvent, PostToolUseEvent,\n PreToolUseHandler, PostToolUseHandler,\n PreToolUseHook, PostToolUseHook, ToolHook,\n} from './resource-hub/index.js';\n\nexport {\n FIVE_AGENT_ROLES,\n isFiveAgentRole,\n asFiveAgentRole,\n filterToolNamesForRole,\n filterToolsForRole,\n isToolAllowedForRole,\n} from './orchestration/five-agent/index.js';\nexport type { FiveAgentRole } from './orchestration/five-agent/index.js';\n\nexport {\n defineSkill,\n defineHook,\n defineEval,\n disableTool,\n normalizeToolDenylist,\n namespaceAuthoringName,\n slotNameFromFile,\n slotNameFromDir,\n} from './authoring/index.js';\nexport type {\n AuthoringSkillDefinition,\n AuthoringHookDefinition,\n AuthoringEvalDefinition,\n AuthoringEvalContext,\n DiscoveredPluginAgentSurface,\n} from './authoring/index.js';\nexport {\n discoverPluginAgentSurface,\n} from './discovery/agent-surface.js';\nexport {\n discoverWorkspaceAgents,\n type AgentMeta,\n} from './discovery/agents.js';\nexport {\n buildAgentSurfaceInfoReport,\n formatAgentSurfaceInfoReport,\n} from './discovery/agent-surface-info.js';\nexport type {\n AgentSurfaceInfoReport,\n AgentSurfacePluginInfo,\n AgentSurfaceWorkspaceAgentInfo,\n} from './discovery/agent-surface-info.js';\n\n// Detached background tasks (#731) and interjection / commands (#732)\nexport * from './detached-task/index.js';\n\n// Plain text completion for plugins (#804): tool-free, with retry and fallback.\nexport { aiCompletionToken, AiCompletionQuotaError } from './plugin-runtime/ai-completion.js';\nexport type {\n AiCompletion,\n AiCompletionInput,\n AiCompletionResult,\n AiCompletionUntrustedInput,\n UsageSubject,\n} from './plugin-runtime/ai-completion.js';\n\nexport type { AgentOutputElement } from './outbound/agent-output.js';\nexport { renderAgentOutput, splitOutputMessages } from './outbound/agent-output.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AI Agent runtime and generation-owned support resources.\n *\n * Agent Tools are owned by `@zhin.js/tool` and published through the\n * generation ToolIndex. AgentResourceHub owns skills, subagents, and hooks;\n * MCP connections are generation-owned by `@zhin.js/mcp-feature`.\n * @module @zhin.js/agent\n */\n\n// ── Agent-specific modules ──\n\nexport { AIService } from './service.js';\nexport type { ServiceAgent, ServiceAgentResult, CreateServiceAgentOptions } from './service.js';\nexport { createAgentSession } from './create-agent-session.js';\nexport type { AgentSessionHandle, CreateAgentSessionOptions } from './create-agent-session.js';\nexport { PluginAILoopHookRegistry } from './plugin-loop-hooks.js';\nexport type {\n PluginBeforeToolCallHandler,\n PluginAfterToolCallHandler,\n PluginTransformContextHandler,\n} from './plugin-loop-hooks.js';\n\nexport { ZhinAgent } from './zhin-agent/index.js';\nexport type { AgentTurnConfiguration, AgentTurnRequest } from './zhin-agent/index.js';\nexport {\n pluginToolToAgentTool,\n agentToolToLlmTool,\n agentToolsToLlmTools,\n} from './tool-bridge.js';\nexport type { NormalizableTool } from './tool-bridge.js';\nexport type {\n ZhinAgentConfig,\n OnChunkCallback,\n} from './config/index.js';\nexport type {\n IAgentTurnProcessor,\n IAgentSessionManager,\n IAgentDiagnostics,\n IAgentConfigurator,\n} from './config/agent-interfaces.js';\nexport type {\n TurnEvent, TurnUsage,\n TurnStartEvent, ChunkEvent, CapabilityResolutionEvent, IterationStartEvent,\n ToolCallEvent as TurnToolCallEvent,\n ToolResultEvent,\n ThinkingEvent, TurnEndEvent, TurnErrorEvent,\n TurnBudgetExceededEvent,\n SubagentStartEvent, SubagentProgressEvent, SubagentEndEvent,\n McpConnectEvent, McpToolCallEvent,\n} from './event/turn-event.js';\nexport {\n createTurnIngress,\n resolveTurnContextValue,\n turnPermissionSubject,\n} from './turn/turn-ingress.js';\nexport { executeAgentTurn } from './turn/execute-agent-turn.js';\nexport type { TurnEventObserver, TurnEventSource } from './turn/execute-agent-turn.js';\nexport type {\n ActivityPort,\n DeliveryIntent,\n DeliveryOutcome,\n DeliveryPort,\n FrozenCapabilityCatalog,\n ReplyPort,\n TurnIdentity,\n TurnAccessContext,\n TurnIngress,\n TurnIngressInput,\n TurnIntent,\n TurnIntentKind,\n TurnJournalPort,\n TurnInput,\n TurnMedia,\n TurnOrigin,\n TurnOutcome,\n TurnPolicyContext,\n TurnExecutionProfile,\n TurnPorts,\n TurnPrincipal,\n TurnRequest,\n TurnRequestPorts,\n TurnScope,\n TurnSessionAddress,\n} from './turn/turn-ingress.js';\n\nexport {\n DEFAULT_CONFIG as ZHIN_AGENT_DEFAULT_CONFIG,\n DEFAULT_ALWAYS_LOADED_TOOLS,\n SECTION_SEP,\n} from './config/index.js';\nexport { MODEL_HARNESS_DEFAULTS, resolveModelHarness, mergeModelHarnessValues } from './config/model-harness-runtime.js';\nexport type { ModelHarnessRow, ResolvedModelHarness, ModelHarnessConfig } from './config/model-harness.js';\nexport {\n checkExecPolicy, applyExecPolicyToTools, resolveExecAllowlist, EXEC_PRESETS,\n isDangerousCommand, stripEnvVarPrefix, stripSafeWrappers, splitCompoundCommand, extractCommandName,\n type ExecPolicyResult,\n} from './security/exec-policy.js';\nexport {\n OWNER_APPROVE_ALWAYS_TOOL,\n OwnerApprovalRuntime,\n} from './security/owner-approval-runtime.js';\nexport type {\n OwnerApprovalAddress,\n OwnerApprovalCommandContext,\n ToolRequesterRole,\n} from './security/owner-approval-runtime.js';\nexport {\n handleRuntimeManagementCommand,\n} from './init/runtime-management-commands.js';\nexport type {\n RuntimeManagementDeps,\n RuntimeManagementSenderRoles,\n} from './init/runtime-management-commands.js';\nexport {\n buildRichSystemPrompt,\n buildLiteSystemPrompt,\n buildUserMessageWithHistory,\n describePromptSectionsForDebug,\n createDefaultPromptAssemblyRegistry,\n enforcePromptBudget,\n} from './prompt/system-prompt.js';\nexport type { RichSystemPromptContext, PromptSectionDebugInfo } from './prompt/system-prompt.js';\nexport { PromptAssemblyRegistry } from './prompt/prompt-assembly-registry.js';\nexport type {\n PromptAssemblyEntry,\n PromptAssemblySection,\n PromptSectionRegistry,\n} from './prompt/prompt-assembly-registry.js';\nexport { promptAssemblyToken } from './prompt/tokens.js';\nexport type { PromptAssemblyToken, PromptAssemblyResource } from './prompt/tokens.js';\nexport {\n defineAgentPromptSection,\n isPromptSectionIndex,\n PromptSectionIndex,\n promptSectionFeatureId,\n} from '@zhin.js/prompt-section';\nexport type {\n AgentPromptSectionDefinition,\n AgentPromptSectionInput,\n PromptProfile,\n PromptSectionDescriptor,\n PromptSectionLayer,\n PromptSectionRetention,\n} from '@zhin.js/prompt-section';\nexport {\n buildAgentsEnvelopeContext,\n collectAgentsInstructionChain,\n} from './context/agents-instruction.js';\nexport type { AgentsInstructionEntry } from './context/agents-instruction.js';\nexport {\n resolveWorkspacePrompt,\n} from './prompt/workspace-prompt.js';\nexport type { WorkspacePromptRole } from './prompt/workspace-prompt.js';\nexport { createUserProfileTool } from './tool/context-tools.js';\nexport { createSpawnTaskTool } from './spawn/spawn-task-tool.js';\nexport * from './interaction/index.js';\n\nexport { UserProfileStore, AI_USER_PROFILE_MODEL } from './user-profile.js';\n\n// ── Capability Seam ────────────────────────────────────────────────────────\nexport type {\n SeamProvider,\n SeamScope,\n ToolService,\n ToolServiceProvider,\n ToolSchema,\n ToolExecutionResult,\n SkillService,\n SkillServiceProvider,\n CapabilitySeamToken,\n ProjectedSeamTool,\n ProjectedSeamSkill,\n} from './seam/index.js';\nexport { SeamProviderRegistry, SeamIntegration } from './seam/index.js';\nexport { capabilitySeamToken } from './seam/index.js';\nexport { BuiltinToolService } from './builtins/builtin-tool-service.js';\nexport { SkillRegistryAsService } from './skill/skill-registry-as-service.js';\n\nexport { SubagentSystem } from './subagent/index.js';\nexport { SubagentRuntime } from './subagent/subagent-runtime.js';\nexport type {\n SubagentOrigin, SubagentResultDelivery, SubagentResultSender, SpawnOptions, SubagentRuntimeOptions,\n SubagentCompletePayload,\n} from './subagent/index.js';\nexport { RESERVED_TOOL_NAMES, RESERVED_TOOL_NAME_PREFIXES } from './reserved-tools.js';\n\nexport {\n stampToolGeneration,\n} from './tool/tool-system.js';\nexport { FileJournalStore } from './journal/index.js';\nexport { PersistentTurnJournal } from './journal/index.js';\n\nexport {\n createScheduleTools,\n generateScheduleJobId,\n SCHEDULE_JOBS_FILENAME,\n} from './schedule-manager.js';\nexport type { ScheduleManager, ScheduleToolRegistration } from './schedule-manager.js';\n\nexport {\n ScheduleJobEngine,\n ScheduleJobStore,\n AssistantEventIngress,\n JobWorker,\n createScheduleJobStoreFromConfig,\n getScheduleJobsPath,\n resolveAssistantConfig,\n resolveAssistantDefaultsConfig,\n resolveAssistantEventsConfig,\n isAssistantEventsActive,\n createNotificationRouter,\n imNotifyToSendOptions,\n parseJobNotify,\n SCHEDULE_JOBS_VERSION,\n syncProfileRoutinesToStore,\n scheduleJobCreatorFromPrincipal,\n parseScheduleJobCreator,\n parseExecutionPlanFromArgs,\n parseScheduleJobExecutionPlan,\n addScheduleJob,\n parseScheduleAddFromToolArgs,\n parseScheduleAddFromRpcMessage,\n bootstrapAssistantHome,\n isAssistantHomeActive,\n resolveAssistantHomeConfig,\n} from './assistant/index.js';\nexport * from './schedule-domain/index.js';\nexport type {\n AssistantConfig,\n AssistantDefaultsConfig,\n AssistantEventsConfig,\n AssistantProfileConfig,\n AssistantProfile,\n NotificationRouter,\n BootstrapAssistantHomeResult,\n HomeToolRegistration,\n ScheduleJob,\n ScheduleJobFile,\n ScheduleJobCreator,\n ScheduleJobExecutionPlan,\n ScheduleInvocationContext,\n AssistantEventRequest,\n AssistantEventResult,\n} from './assistant/index.js';\nexport {\n loadAssistantProfileFile,\n loadBootstrapWithProfile,\n syncProfileHeartbeatToStore,\n pruneStaleProfileCronJobs,\n mergeProfileDeviceAliases,\n validateAssistantProfile,\n resolveAssistantProfileConfig,\n ASSISTANT_PROFILE_VERSION,\n DEFAULT_PROFILE_FILENAME,\n PROFILE_HEARTBEAT_JOB_ID,\n PROFILE_MORNING_BRIEF_JOB_ID,\n PROFILE_BEDTIME_CHECK_JOB_ID,\n} from './assistant/index.js';\n\nexport type {\n ApprovalDecision,\n ApprovalDecisionMemory,\n ApprovalDecisionPort,\n ApprovalOutcome,\n ApprovalOutcomePort,\n ApprovalPort,\n ApprovalRequestInput,\n} from './session/approval-port.js';\nexport {\n approvalOutcomeToDecision,\n formatApprovalDenial,\n requestApprovalOutcome,\n} from './session/approval-port.js';\nexport {\n ApprovalReviewAgent,\n createAutoApprovalPort,\n createBypassApprovalPort,\n} from './session/approval-review-agent.js';\nexport type {\n ApprovalReviewAgentOptions,\n ApprovalReviewDecision,\n} from './session/approval-review-agent.js';\nexport { beginIngressTurnSession } from './session/turn-ingress-session.js';\n\nexport type {\n AgentRole,\n AgentRoleConfig,\n} from './resource-hub/role-configs.js';\nexport { AGENT_ROLE_CONFIGS } from './resource-hub/role-configs.js';\n\nexport {\n loadBootstrapFiles, buildContextFiles, buildBootstrapContextSection,\n buildStableContextFiles, buildStableBootstrapSection,\n loadSoulPersona, loadToolsGuide, loadAgentsMemory,\n STABLE_BOOTSTRAP_FILENAMES,\n} from './bootstrap.js';\nexport { getFileMemoryContext, getMemoryDir } from './memory-layers.js';\nexport type { BootstrapFile, ContextFile } from './bootstrap.js';\n\nexport {\n NO_MEDIA_AUTHORITY,\n preprocessInboundMedia,\n publishOutboundElements,\n resolveMultimodalConfig,\n resolveOutboundCapabilities,\n} from './media/index.js';\nexport type { AudioTranscriptionPort, MediaBinaryPayload, MultimodalConfig, OutboundMediaAuthority, OutboundMediaCapabilities } from './media/index.js';\nexport { createLlmMediaPerceptionPort, resolvePerceptionConfig } from './media/index.js';\nexport type { MediaPerception, MediaPerceptionPort, PerceptionMediaKind, ResolvedPerceptionConfig } from './media/index.js';\n\nexport { filterImDeliveryContent } from './segment/filter-im-delivery.js';\n\nexport {\n loadMemoryLayers,\n buildMemoryPrompt,\n safeSessionKey,\n getMemoryRoot,\n checkMemoryWritePath,\n classifyMemoryWritePath,\n formatMemoryPathsHint,\n resolveMemoryPromptOptions,\n DEFAULT_MEMORY_BUDGETS,\n} from './memory-layers.js';\nexport type {\n MemoryLayerBudgets,\n MemoryPromptOptions,\n MemoryLayersInput,\n LoadedMemoryLayers,\n MemoryWriteScope,\n MemoryWriteDecision,\n} from './memory-layers.js';\n\nexport { aiHookRuntimeBus, AIHookRuntimeBus } from './ai-hook-runtime-bus.js';\n\nexport {\n createAIHookBusPayload,\n isAISessionNewPayload,\n isAISessionCompactPayload,\n} from './ai-event-bus.js';\nexport type {\n AISessionNewPayload,\n AISessionCompactPayload,\n} from './ai-event-bus.js';\nexport {\n AI_EVENT_NAMES,\n subscribeAIEventsOnTarget,\n} from './ai-event-subscriber.js';\nexport { originFromMessage } from './spawn/spawn-task-tool.js';\nexport type {\n AIEventFilter,\n AIEventHandlers,\n AIEventTarget,\n} from './ai-event-subscriber.js';\nexport type {\n AIEventName,\n AIEventSource,\n AIEventMode,\n AIEventPath,\n AIEventPayload,\n} from './ai-event-contract.js';\nexport { AgentEventBus } from './event/ai-event-bus.js';\n\n// ── Activity Feedback(替代 endpoint typingIndicator)──\nexport {\n ActivityFeedbackManager,\n resolveActivityFeedbackPhaseConfig,\n isActivityFeedbackEnabled,\n toActivityFeedbackEventContext,\n resolveActivitySceneType,\n resolveActivityEventTargets,\n enableActivityFeedbackForBot,\n isGenericActivityFeedbackManager,\n resolveSubagentActivityTag,\n formatSubagentActivityPrefix,\n withSubagentActivityPrefix,\n applySubagentActivityPrefixToConfig,\n resolveActivityFeedbackSessionId,\n} from './activity-feedback/index.js';\nexport type {\n ActivityFeedbackType,\n ActivityFeedbackPhase,\n ActivitySceneType,\n ActivityFeedbackPhaseConfig,\n ActivityFeedbackScenePhases,\n ActivityFeedbackConfig,\n ResolvedActivityFeedbackPhaseConfig,\n EndpointWithActivityFeedback,\n ActivityFeedbackSendPort,\n PlatformActivityFeedbackManager,\n PlatformActivityFeedbackStartOptions,\n BotActivityFeedbackManager,\n ActivityFeedbackEventContext,\n ActivityFeedbackGatePhase,\n} from './activity-feedback/index.js';\n\nexport type {\n ProactiveSendContext,\n ProactiveSendSource,\n ProactiveOutboundService,\n} from './outbound/send-proactive.js';\nexport { deliverScheduleToAdapter } from './assistant/deliver-schedule-to-adapter.js';\nexport type { DeliverScheduleToAdapterInput } from './assistant/deliver-schedule-to-adapter.js';\nexport { createTaskExecutor } from './task-executor.js';\nexport type {\n TaskExecutor,\n TaskExecutionOptions,\n TaskExecutionResult,\n TaskExecutorDeps,\n ScheduleActivityEvent,\n ScheduleActivityPort,\n} from './task-executor.js';\nexport type {\n ScheduleTurnExecutionRequest,\n ScheduleTurnPort,\n} from './schedule-domain/execution-domain.js';\nexport { demoteScheduleCreator } from './schedule-domain/security-harness.js';\nexport {\n SKILL_DISCLOSURE_TOOLS,\n SKILL_DISCLOSURE_STEPS,\n SKILL_DISCLOSURE_PROMPT_HINT,\n} from './skill/progressive-disclosure.js';\n// ── Typing Indicator ──\nexport {\n TypingIndicatorManager,\n ReactionTypingIndicator,\n MessageTypingIndicator,\n NoneTypingIndicator,\n ReactionTypingIndicatorAdapter,\n NativeTypingIndicatorAdapter,\n NativeTypingIndicator,\n GenericTypingIndicatorAdapter,\n} from './typing-indicator/index.js';\nexport type {\n TypingIndicatorType,\n TypingIndicatorConfig,\n TypingIndicatorOptions,\n TypingIndicator,\n TypingIndicatorAdapter,\n} from './typing-indicator/index.js';\n\n// ── Activity Feedback 平台能力 ──\nexport {\n PLATFORM_FEATURES,\n buildTypingSendContent,\n} from './typing-indicator/adapter-integration.js';\nexport type {\n PlatformFeatures,\n} from './typing-indicator/adapter-integration.js';\n\n// ── MCP Client ──\nexport { McpClientManager, McpClientConnection, mcpToolToAgentTool } from './mcp-client/index.js';\nexport type { McpClientConnectionState, McpToolDefinition } from './mcp-client/index.js';\n\n// ── Common adapter tools (migrated from core) ──\nexport {\n createSceneManagementTools, buildSceneMethodArgs,\n SCENE_MANAGEMENT_METHOD_SPECS, SCENE_MANAGEMENT_SKILL_TAGS, SCENE_MANAGEMENT_SKILL_KEYWORDS,\n} from './common-adapter-tools.js';\nexport type { ISceneManagement, SceneManagementMethodSpec } from './common-adapter-tools.js';\n\n// ── Agent capability resource hub ──\nexport { AgentResourceHub } from './resource-hub/index.js';\nexport {\n ResourceRegistry,\n canAccessTool,\n normalizeTool,\n SkillRegistry,\n SubAgentRegistry,\n McpRegistry,\n HookRegistry,\n createAIHookEvent,\n} from './resource-hub/index.js';\nexport type {\n McpConnection,\n ResourceScope, ResourceEntry,\n Tool, Message, SenderRole, ToolScope, FileRole,\n ToolParametersSchema, PropertySchema, ToolJsonSchema,\n Skill, SkillMetadata,\n SubAgentDef, AgentPreset,\n McpServerEntry, McpResource, McpPrompt,\n AIHook, AIHookEvent as OrchestratorHookEvent, AIHookEventType as OrchestratorHookEventType, AIHookHandler as OrchestratorHookHandler,\n ToolHookDecision, PostToolHookDecision,\n PreToolUseEvent, PostToolUseEvent,\n PreToolUseHandler, PostToolUseHandler,\n PreToolUseHook, PostToolUseHook, ToolHook,\n} from './resource-hub/index.js';\n\nexport {\n FIVE_AGENT_ROLES,\n isFiveAgentRole,\n asFiveAgentRole,\n filterToolNamesForRole,\n filterToolsForRole,\n isToolAllowedForRole,\n} from './orchestration/five-agent/index.js';\nexport type { FiveAgentRole } from './orchestration/five-agent/index.js';\n\nexport {\n defineSkill,\n defineHook,\n defineEval,\n disableTool,\n normalizeToolDenylist,\n namespaceAuthoringName,\n slotNameFromFile,\n slotNameFromDir,\n} from './authoring/index.js';\nexport type {\n AuthoringSkillDefinition,\n AuthoringHookDefinition,\n AuthoringEvalDefinition,\n AuthoringEvalContext,\n DiscoveredPluginAgentSurface,\n} from './authoring/index.js';\nexport {\n discoverPluginAgentSurface,\n} from './discovery/agent-surface.js';\nexport {\n discoverWorkspaceAgents,\n type AgentMeta,\n} from './discovery/agents.js';\nexport {\n buildAgentSurfaceInfoReport,\n formatAgentSurfaceInfoReport,\n} from './discovery/agent-surface-info.js';\nexport type {\n AgentSurfaceInfoReport,\n AgentSurfacePluginInfo,\n AgentSurfaceWorkspaceAgentInfo,\n} from './discovery/agent-surface-info.js';\n\n// Detached background tasks (#731) and interjection / commands (#732)\nexport * from './detached-task/index.js';\n\n// Plain text completion for plugins (#804): tool-free, with retry and fallback.\nexport { aiCompletionToken, AiCompletionQuotaError } from './plugin-runtime/ai-completion.js';\nexport type {\n AiCompletion,\n AiCompletionInput,\n AiCompletionResult,\n AiCompletionUntrustedInput,\n AiCompletionUsageShare,\n UsageSubject,\n} from './plugin-runtime/ai-completion.js';\n\nexport type { AgentOutputElement } from './outbound/agent-output.js';\nexport { renderAgentOutput, splitOutputMessages } from './outbound/agent-output.js';\nexport { REACTION_SEGMENT_TYPE } from './outbound/structured-reply.js';\nexport { chatFailureLine, chatFailureKindOf } from './outbound/chat-failure.js';\nexport type { ChatFailureKind, ChatFailureOptions } from './outbound/chat-failure.js';\n"]}
@@ -39,10 +39,9 @@ export declare class MediaPerceptionFailedError extends Error {
39
39
  constructor(cause: unknown, usage: Usage);
40
40
  }
41
41
  /**
42
- * Perception port backed by a configured provider/model: one media-capable
43
- * completion per payload through the provider resilience layer (retry,
44
- * per-attempt timeout, error classification). Descriptions are cached by
45
- * content hash.
42
+ * Perception port backed by an ordered provider/model chain. Each candidate
43
+ * uses the provider resilience layer (retry, per-attempt timeout, error
44
+ * classification). Successful descriptions are cached by content hash.
46
45
  */
47
46
  export declare function createLlmMediaPerceptionPort(options: LlmMediaPerceptionOptions): MediaPerceptionPort;
48
47
  /**
@@ -69,17 +69,16 @@ function isPdf(payload) {
69
69
  || payload.fileName?.toLowerCase().endsWith('.pdf') === true;
70
70
  }
71
71
  /**
72
- * Perception port backed by a configured provider/model: one media-capable
73
- * completion per payload through the provider resilience layer (retry,
74
- * per-attempt timeout, error classification). Descriptions are cached by
75
- * content hash.
72
+ * Perception port backed by an ordered provider/model chain. Each candidate
73
+ * uses the provider resilience layer (retry, per-attempt timeout, error
74
+ * classification). Successful descriptions are cached by content hash.
76
75
  */
77
76
  export function createLlmMediaPerceptionPort(options) {
78
77
  const { runtime, config } = options;
79
78
  const cache = new Map();
80
- const remember = (key, text) => {
79
+ const remember = (key, value) => {
81
80
  cache.delete(key);
82
- cache.set(key, text);
81
+ cache.set(key, value);
83
82
  while (cache.size > CACHE_LIMIT)
84
83
  cache.delete(cache.keys().next().value);
85
84
  };
@@ -94,27 +93,15 @@ export function createLlmMediaPerceptionPort(options) {
94
93
  return payload.kind !== 'file' || isPdf(payload);
95
94
  },
96
95
  async describe(payload, signal) {
97
- if (payload.kind === 'audio')
96
+ signal?.throwIfAborted();
97
+ if (payload.kind === 'audio' || !config.kinds.includes(payload.kind) || (payload.kind === 'file' && !isPdf(payload)))
98
98
  return undefined;
99
99
  const key = perceptionCacheKey(payload);
100
100
  const hit = cache.get(key);
101
101
  if (hit !== undefined) {
102
102
  remember(key, hit);
103
- return { text: hit, provider: config.provider, model: config.model, cached: true };
104
- }
105
- const model = runtime.model(config.provider, config.model);
106
- const input = Array.isArray(model.input) ? model.input : ['text'];
107
- if (!input.includes(payload.kind)) {
108
- throw new Error(`perception model ${config.provider}/${config.model} does not declare ${payload.kind} input`);
103
+ return { ...hit, cached: true };
109
104
  }
110
- const resilience = resolveProviderResilienceConfig(options.resilience, resolveProviderConfigResilience(runtime.providerConfig?.(config.provider)),
111
- // One retry at most: perception runs before the turn and must stay quick.
112
- { requestTimeoutMs: config.timeoutMs, maxRetries: Math.min(options.resilience?.maxRetries ?? 1, 1) });
113
- const port = createResilientCompletionPort(runtime, {
114
- config: resilience,
115
- timers: options.timers,
116
- onEvent: options.onEvent,
117
- });
118
105
  const block = {
119
106
  type: payload.kind,
120
107
  data: {
@@ -132,23 +119,58 @@ export function createLlmMediaPerceptionPort(options) {
132
119
  media: [block],
133
120
  timestamp: Date.now(),
134
121
  };
135
- let reply;
136
- let text;
137
- try {
138
- reply = await port.complete(model, { systemPrompt: PERCEPTION_SYSTEM_PROMPT, messages: [user] }, { signal });
139
- text = truncatePerceptionText(assistantAnswerText(reply), config.maxChars);
140
- }
141
- catch (error) {
142
- const prompt = estimatePromptTokens(`${PERCEPTION_SYSTEM_PROMPT}\n${PERCEPTION_INSTRUCTIONS[payload.kind]}`)
143
- + (FAILED_PERCEPTION_MEDIA_TOKENS[payload.kind] ?? 1_000);
144
- throw new MediaPerceptionFailedError(error, { prompt_tokens: prompt, completion_tokens: 0, total_tokens: prompt });
122
+ const total = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
123
+ const addUsage = (usage) => {
124
+ if (!usage)
125
+ return;
126
+ total.prompt_tokens += usage.prompt_tokens;
127
+ total.completion_tokens += usage.completion_tokens;
128
+ total.total_tokens += usage.total_tokens;
129
+ };
130
+ let lastError;
131
+ let empty;
132
+ for (const candidate of [config, ...(config.fallbacks ?? [])]) {
133
+ signal?.throwIfAborted();
134
+ let sent = false;
135
+ try {
136
+ const model = runtime.model(candidate.provider, candidate.model);
137
+ if (!(model.input ?? ['text']).includes(payload.kind)) {
138
+ throw new Error(`perception model ${candidate.provider}/${candidate.model} does not declare ${payload.kind} input`);
139
+ }
140
+ const resilience = resolveProviderResilienceConfig(options.resilience, resolveProviderConfigResilience(runtime.providerConfig?.(candidate.provider)), { requestTimeoutMs: config.timeoutMs, maxRetries: Math.min(options.resilience?.maxRetries ?? 1, 1) });
141
+ const port = createResilientCompletionPort(runtime, {
142
+ config: resilience, timers: options.timers, onEvent: options.onEvent,
143
+ });
144
+ sent = true;
145
+ const reply = await port.complete(model, { systemPrompt: PERCEPTION_SYSTEM_PROMPT, messages: [user] }, { signal });
146
+ addUsage(perceptionUsageOf(reply.usage));
147
+ const text = truncatePerceptionText(assistantAnswerText(reply), config.maxChars);
148
+ const result = { text, provider: candidate.provider, model: candidate.model };
149
+ // 空回答同样计费,但不写缓存;继续尝试下一个候选。
150
+ if (!text) {
151
+ empty = { ...result, cached: false };
152
+ continue;
153
+ }
154
+ remember(key, result);
155
+ return { ...result, cached: false, ...(total.total_tokens ? { usage: total } : {}) };
156
+ }
157
+ catch (error) {
158
+ // 取消属于当前回合,不能借备用模型启动新的请求。
159
+ if (signal?.aborted)
160
+ throw error;
161
+ if (sent) {
162
+ const prompt = estimatePromptTokens(`${PERCEPTION_SYSTEM_PROMPT}\n${PERCEPTION_INSTRUCTIONS[payload.kind]}`)
163
+ + (FAILED_PERCEPTION_MEDIA_TOKENS[payload.kind] ?? 1_000);
164
+ addUsage({ prompt_tokens: prompt, completion_tokens: 0, total_tokens: prompt });
165
+ }
166
+ lastError = error;
167
+ }
145
168
  }
146
- const usage = perceptionUsageOf(reply.usage);
147
- // An empty description still spent tokens: report the usage with no text.
148
- if (!text)
149
- return { text: '', provider: config.provider, model: config.model, cached: false, ...(usage ? { usage } : {}) };
150
- remember(key, text);
151
- return { text, provider: config.provider, model: config.model, cached: false, ...(usage ? { usage } : {}) };
169
+ if (empty)
170
+ return { ...empty, ...(total.total_tokens ? { usage: total } : {}) };
171
+ if (total.total_tokens)
172
+ throw new MediaPerceptionFailedError(lastError, total);
173
+ throw lastError;
152
174
  },
153
175
  });
154
176
  }