@combycode/llm-sdk 1.0.0-rc.0

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 (228) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +103 -0
  4. package/dist/agent/approval-types.d.ts +49 -0
  5. package/dist/agent/context-registry/layers.d.ts +39 -0
  6. package/dist/agent/context-registry/registry-internal.d.ts +14 -0
  7. package/dist/agent/context-registry/registry.d.ts +104 -0
  8. package/dist/agent/context-registry/types.d.ts +110 -0
  9. package/dist/agent/guardrail-types.d.ts +58 -0
  10. package/dist/agent/history-types.d.ts +40 -0
  11. package/dist/agent/history.d.ts +111 -0
  12. package/dist/agent/loop-config.d.ts +67 -0
  13. package/dist/agent/loop-internals.d.ts +46 -0
  14. package/dist/agent/loop-step-state.d.ts +20 -0
  15. package/dist/agent/loop.d.ts +133 -0
  16. package/dist/agent/tool-key.d.ts +3 -0
  17. package/dist/agent/types.d.ts +138 -0
  18. package/dist/bus/agent-bus.d.ts +99 -0
  19. package/dist/bus/async-context.browser.d.ts +13 -0
  20. package/dist/bus/async-context.d.ts +11 -0
  21. package/dist/bus/async-context.types.d.ts +14 -0
  22. package/dist/bus/hook-bus.d.ts +43 -0
  23. package/dist/bus/hook-map.d.ts +592 -0
  24. package/dist/helpers/agent.d.ts +32 -0
  25. package/dist/helpers/batch.d.ts +74 -0
  26. package/dist/helpers/calibration-store.d.ts +27 -0
  27. package/dist/helpers/calibration-types.d.ts +64 -0
  28. package/dist/helpers/chain.d.ts +30 -0
  29. package/dist/helpers/client-pool.d.ts +15 -0
  30. package/dist/helpers/client-resolver.d.ts +62 -0
  31. package/dist/helpers/collection.d.ts +19 -0
  32. package/dist/helpers/consolidate.d.ts +66 -0
  33. package/dist/helpers/content.d.ts +25 -0
  34. package/dist/helpers/conversation-export.d.ts +14 -0
  35. package/dist/helpers/conversation-zip.d.ts +28 -0
  36. package/dist/helpers/count-tokens.d.ts +26 -0
  37. package/dist/helpers/define-tool.d.ts +66 -0
  38. package/dist/helpers/delegate.d.ts +6 -0
  39. package/dist/helpers/embed.d.ts +24 -0
  40. package/dist/helpers/engine.d.ts +121 -0
  41. package/dist/helpers/estimate-types.d.ts +67 -0
  42. package/dist/helpers/estimate.d.ts +45 -0
  43. package/dist/helpers/estimator.d.ts +48 -0
  44. package/dist/helpers/handoff-types.d.ts +18 -0
  45. package/dist/helpers/handoff.d.ts +14 -0
  46. package/dist/helpers/llm.d.ts +24 -0
  47. package/dist/helpers/mcp.d.ts +82 -0
  48. package/dist/helpers/media.d.ts +58 -0
  49. package/dist/helpers/models.d.ts +36 -0
  50. package/dist/helpers/moderate-types.d.ts +73 -0
  51. package/dist/helpers/moderate.d.ts +13 -0
  52. package/dist/helpers/moderation-guardrail.d.ts +29 -0
  53. package/dist/helpers/observer.d.ts +36 -0
  54. package/dist/helpers/one-shot.d.ts +86 -0
  55. package/dist/helpers/parallel.d.ts +16 -0
  56. package/dist/helpers/realtime.d.ts +25 -0
  57. package/dist/helpers/route.d.ts +29 -0
  58. package/dist/helpers/select-model.d.ts +41 -0
  59. package/dist/helpers/server.d.ts +32 -0
  60. package/dist/helpers/transcribe.d.ts +36 -0
  61. package/dist/index.browser.js +38047 -0
  62. package/dist/index.d.ts +275 -0
  63. package/dist/index.js +37974 -0
  64. package/dist/llm/audio/voices.d.ts +7 -0
  65. package/dist/llm/client-config.d.ts +37 -0
  66. package/dist/llm/client-internal.d.ts +28 -0
  67. package/dist/llm/client.d.ts +68 -0
  68. package/dist/llm/providers/_shared/constants.d.ts +5 -0
  69. package/dist/llm/providers/_shared/response-utils.d.ts +8 -0
  70. package/dist/llm/providers/anthropic/batch.d.ts +19 -0
  71. package/dist/llm/providers/anthropic/constants.d.ts +13 -0
  72. package/dist/llm/providers/anthropic/files.d.ts +23 -0
  73. package/dist/llm/providers/anthropic/messages.d.ts +30 -0
  74. package/dist/llm/providers/google/batch.d.ts +20 -0
  75. package/dist/llm/providers/google/constants.d.ts +6 -0
  76. package/dist/llm/providers/google/embeddings.d.ts +15 -0
  77. package/dist/llm/providers/google/files.d.ts +22 -0
  78. package/dist/llm/providers/google/generate.d.ts +27 -0
  79. package/dist/llm/providers/google/interactions.d.ts +30 -0
  80. package/dist/llm/providers/google/media.d.ts +27 -0
  81. package/dist/llm/providers/google/realtime.d.ts +27 -0
  82. package/dist/llm/providers/openai/batch.d.ts +19 -0
  83. package/dist/llm/providers/openai/completions.d.ts +25 -0
  84. package/dist/llm/providers/openai/embeddings.d.ts +16 -0
  85. package/dist/llm/providers/openai/files.d.ts +23 -0
  86. package/dist/llm/providers/openai/media.d.ts +28 -0
  87. package/dist/llm/providers/openai/moderations.d.ts +19 -0
  88. package/dist/llm/providers/openai/realtime.d.ts +24 -0
  89. package/dist/llm/providers/openai/responses.d.ts +29 -0
  90. package/dist/llm/providers/openai/tiers.d.ts +13 -0
  91. package/dist/llm/providers/openai/transcription.d.ts +20 -0
  92. package/dist/llm/providers/openrouter/completions.d.ts +15 -0
  93. package/dist/llm/providers/openrouter/embeddings.d.ts +7 -0
  94. package/dist/llm/providers/openrouter/media.d.ts +25 -0
  95. package/dist/llm/providers/openrouter/responses.d.ts +17 -0
  96. package/dist/llm/providers/xai/batch.d.ts +19 -0
  97. package/dist/llm/providers/xai/completions.d.ts +24 -0
  98. package/dist/llm/providers/xai/files.d.ts +23 -0
  99. package/dist/llm/providers/xai/media.d.ts +27 -0
  100. package/dist/llm/providers/xai/responses.d.ts +20 -0
  101. package/dist/llm/realtime/session.d.ts +34 -0
  102. package/dist/llm/realtime/types.d.ts +66 -0
  103. package/dist/llm/server-state.d.ts +32 -0
  104. package/dist/llm/types/audio.d.ts +18 -0
  105. package/dist/llm/types/messages.d.ts +125 -0
  106. package/dist/llm/types/options.d.ts +51 -0
  107. package/dist/llm/types/provider.d.ts +39 -0
  108. package/dist/llm/types/request.d.ts +51 -0
  109. package/dist/llm/types/response.d.ts +36 -0
  110. package/dist/llm/types/schema-utils.d.ts +8 -0
  111. package/dist/llm/types/stream.d.ts +42 -0
  112. package/dist/llm/types/tiers.d.ts +11 -0
  113. package/dist/llm/types/tools.d.ts +20 -0
  114. package/dist/network/engine.d.ts +87 -0
  115. package/dist/network/errors.d.ts +14 -0
  116. package/dist/network/queue-state-config.d.ts +41 -0
  117. package/dist/network/queue-state.d.ts +45 -0
  118. package/dist/network/rate-limiter.d.ts +49 -0
  119. package/dist/network/realtime-connection.d.ts +40 -0
  120. package/dist/network/request-queue.d.ts +40 -0
  121. package/dist/network/semaphore.d.ts +12 -0
  122. package/dist/network/sse.d.ts +3 -0
  123. package/dist/network/types.d.ts +127 -0
  124. package/dist/plugins/batch/batcher.d.ts +45 -0
  125. package/dist/plugins/batch/strategy.d.ts +20 -0
  126. package/dist/plugins/batch/types.d.ts +54 -0
  127. package/dist/plugins/cache/cache.d.ts +50 -0
  128. package/dist/plugins/cache/file-store.d.ts +15 -0
  129. package/dist/plugins/cache/memory-store.d.ts +10 -0
  130. package/dist/plugins/cache/types.d.ts +28 -0
  131. package/dist/plugins/configuration/configuration.d.ts +71 -0
  132. package/dist/plugins/context-guard/facts.d.ts +14 -0
  133. package/dist/plugins/context-guard/guard.d.ts +27 -0
  134. package/dist/plugins/context-guard/strategies/layered.d.ts +24 -0
  135. package/dist/plugins/context-guard/strategies/truncate.d.ts +19 -0
  136. package/dist/plugins/context-guard/tools.d.ts +50 -0
  137. package/dist/plugins/context-guard/types.d.ts +110 -0
  138. package/dist/plugins/context-measurer/calibration/store.d.ts +19 -0
  139. package/dist/plugins/context-measurer/counter/count-api.d.ts +41 -0
  140. package/dist/plugins/context-measurer/counter/heuristic.d.ts +25 -0
  141. package/dist/plugins/context-measurer/counter/hybrid.d.ts +33 -0
  142. package/dist/plugins/context-measurer/counter/tiktoken.d.ts +13 -0
  143. package/dist/plugins/context-measurer/measurer.d.ts +49 -0
  144. package/dist/plugins/context-measurer/types.d.ts +40 -0
  145. package/dist/plugins/cost-collector/collector.d.ts +42 -0
  146. package/dist/plugins/cost-collector/cost-collector-internal.d.ts +58 -0
  147. package/dist/plugins/cost-collector/cost-collector-types.d.ts +42 -0
  148. package/dist/plugins/embeddings/types.d.ts +23 -0
  149. package/dist/plugins/files/attachment.d.ts +79 -0
  150. package/dist/plugins/files/provider-adapter.d.ts +37 -0
  151. package/dist/plugins/files/registry.d.ts +48 -0
  152. package/dist/plugins/files/strategy.d.ts +38 -0
  153. package/dist/plugins/internal-tools/backends/local.d.ts +12 -0
  154. package/dist/plugins/internal-tools/builtin/builtin.d.ts +21 -0
  155. package/dist/plugins/internal-tools/builtin/clarify.d.ts +12 -0
  156. package/dist/plugins/internal-tools/builtin/classify.d.ts +12 -0
  157. package/dist/plugins/internal-tools/builtin/score.d.ts +13 -0
  158. package/dist/plugins/internal-tools/builtin/structure.d.ts +11 -0
  159. package/dist/plugins/internal-tools/builtin/summarize.d.ts +19 -0
  160. package/dist/plugins/internal-tools/id.d.ts +12 -0
  161. package/dist/plugins/internal-tools/registry.d.ts +24 -0
  162. package/dist/plugins/internal-tools/runner/define.d.ts +7 -0
  163. package/dist/plugins/internal-tools/runner/json-enforcement.d.ts +3 -0
  164. package/dist/plugins/internal-tools/runner/runner.d.ts +47 -0
  165. package/dist/plugins/internal-tools/runner/template.d.ts +10 -0
  166. package/dist/plugins/internal-tools/runner/types.d.ts +57 -0
  167. package/dist/plugins/internal-tools/runner/variants.d.ts +34 -0
  168. package/dist/plugins/internal-tools/types.d.ts +80 -0
  169. package/dist/plugins/logger/console-sink.d.ts +26 -0
  170. package/dist/plugins/logger/logger.d.ts +38 -0
  171. package/dist/plugins/logger/types.d.ts +25 -0
  172. package/dist/plugins/mcp/base-transport.d.ts +58 -0
  173. package/dist/plugins/mcp/client.d.ts +92 -0
  174. package/dist/plugins/mcp/jsonrpc.d.ts +20 -0
  175. package/dist/plugins/mcp/oauth.d.ts +122 -0
  176. package/dist/plugins/mcp/sampling.d.ts +17 -0
  177. package/dist/plugins/mcp/tools.d.ts +20 -0
  178. package/dist/plugins/mcp/transport-http.d.ts +50 -0
  179. package/dist/plugins/mcp/transport-stdio.d.ts +23 -0
  180. package/dist/plugins/mcp/transport-ws.d.ts +32 -0
  181. package/dist/plugins/mcp/transport.d.ts +29 -0
  182. package/dist/plugins/mcp/types.d.ts +202 -0
  183. package/dist/plugins/mcp/url-guard.d.ts +70 -0
  184. package/dist/plugins/mcp/win-spawn.d.ts +20 -0
  185. package/dist/plugins/media/file-store.d.ts +24 -0
  186. package/dist/plugins/media/memory-store.d.ts +17 -0
  187. package/dist/plugins/media/output.d.ts +44 -0
  188. package/dist/plugins/media/source-image.d.ts +36 -0
  189. package/dist/plugins/media/types.d.ts +146 -0
  190. package/dist/plugins/model-catalog/catalog.d.ts +152 -0
  191. package/dist/plugins/permissions/glob.d.ts +6 -0
  192. package/dist/plugins/permissions/matchers.d.ts +7 -0
  193. package/dist/plugins/permissions/policy.d.ts +10 -0
  194. package/dist/plugins/permissions/types.d.ts +22 -0
  195. package/dist/plugins/persistence/file.d.ts +25 -0
  196. package/dist/plugins/persistence/memory.d.ts +23 -0
  197. package/dist/plugins/persistence/types.d.ts +21 -0
  198. package/dist/plugins/retrieval/chunker.d.ts +28 -0
  199. package/dist/plugins/retrieval/hosted-google.d.ts +60 -0
  200. package/dist/plugins/retrieval/hosted-openai.d.ts +45 -0
  201. package/dist/plugins/retrieval/hosted-xai.d.ts +57 -0
  202. package/dist/plugins/retrieval/index.d.ts +70 -0
  203. package/dist/plugins/retrieval/local.d.ts +50 -0
  204. package/dist/plugins/retrieval/types.d.ts +161 -0
  205. package/dist/plugins/retrieval/vector-store.d.ts +70 -0
  206. package/dist/plugins/scheduler/scheduler.d.ts +31 -0
  207. package/dist/plugins/telemetry/telemetry.d.ts +118 -0
  208. package/dist/plugins/tool-catalog/catalog.d.ts +31 -0
  209. package/dist/plugins/tool-catalog/errors.d.ts +22 -0
  210. package/dist/plugins/tool-catalog/types.d.ts +44 -0
  211. package/dist/runtime/runtime.d.ts +20 -0
  212. package/dist/server/auth.d.ts +25 -0
  213. package/dist/server/dispatch.d.ts +35 -0
  214. package/dist/server/loaders.d.ts +26 -0
  215. package/dist/server/oai-adapter.d.ts +30 -0
  216. package/dist/server/oai-types.d.ts +114 -0
  217. package/dist/server/response-store.d.ts +59 -0
  218. package/dist/server/router.d.ts +59 -0
  219. package/dist/server/server.d.ts +61 -0
  220. package/dist/types/request-context.d.ts +46 -0
  221. package/dist/util/async.d.ts +3 -0
  222. package/dist/util/base64.d.ts +8 -0
  223. package/dist/util/duration.d.ts +12 -0
  224. package/dist/util/http.d.ts +9 -0
  225. package/dist/util/image-mime.d.ts +8 -0
  226. package/dist/util/json-schema.d.ts +7 -0
  227. package/dist/util/wav.d.ts +20 -0
  228. package/package.json +95 -0
@@ -0,0 +1,43 @@
1
+ /** HookBus — typed pub/sub for SDK instrumentation.
2
+ *
3
+ * Subsystems (network engine, llm client, agent loop, server, plugins) emit
4
+ * hook events; consumers (logger, cache, cost, context guard, ...) subscribe.
5
+ *
6
+ * Distinct from AgentBus:
7
+ * - HookBus carries SDK-internal instrumentation. Type-safe per event name.
8
+ * - AgentBus carries cross-module business events with pattern matching
9
+ * and correlation. See `agent-bus.ts`.
10
+ *
11
+ * Failure mode: handlers throwing inside `emit()` propagate. We do NOT
12
+ * swallow — emitters need to know if a critical handler (like ContextGuard
13
+ * abort) failed. Plugins that should never break the request must catch
14
+ * their own errors. */
15
+ import type { HookHandler, HookMap, HookName } from './hook-map';
16
+ /** Catch-all handler: receives the event name + context for EVERY emit. */
17
+ export type AnyHookHandler = (name: HookName, ctx: unknown) => void | Promise<void>;
18
+ export declare class HookBus {
19
+ private handlers;
20
+ private anyHandlers;
21
+ /** Register a catch-all handler invoked for every event (telemetry tap).
22
+ * Returns an unsubscribe function. */
23
+ onAny(handler: AnyHookHandler): () => void;
24
+ /** Register a handler. Returns unsubscribe function. */
25
+ on<K extends HookName>(name: K, handler: HookHandler<K>): () => void;
26
+ /** Register a one-time handler. */
27
+ once<K extends HookName>(name: K, handler: HookHandler<K>): () => void;
28
+ /** Remove all handlers for a hook, or all hooks (incl. catch-all) if no name. */
29
+ off(name?: HookName): void;
30
+ /** Emit asynchronously. Handlers run in registration order; awaited sequentially.
31
+ * Propagates any handler error to the caller. */
32
+ emit<K extends HookName>(name: K, ctx: HookMap[K]): Promise<void>;
33
+ /** Emit synchronously. For hot paths (per-chunk stream events). Async handlers
34
+ * start but are NOT awaited; their resolution timing is undefined. Use only
35
+ * when the emitter cannot block. */
36
+ emitSync<K extends HookName>(name: K, ctx: HookMap[K]): void;
37
+ /** Whether any handlers are registered for a hook name. */
38
+ has(name: HookName): boolean;
39
+ /** Diagnostic: total handlers across all names. Useful for leak detection
40
+ * in tests (engine.destroy() should bring this back to 0 if no external
41
+ * subscribers remain). */
42
+ get handlerCount(): number;
43
+ }
@@ -0,0 +1,592 @@
1
+ /** HookMap — typed event catalog for HookBus.
2
+ *
3
+ * Each subsystem adds its events here as it lands in the SDK. Keep this
4
+ * file as the single source of truth (no module-level declaration merging)
5
+ * so the universe of events is greppable in one place.
6
+ *
7
+ * Each layer (network, llm, agent, server) and plugin (cache, ...) extends
8
+ * this interface with the events it emits.
9
+ *
10
+ * Convention:
11
+ * - Names always start with `on`.
12
+ * - Context shape carries the `RequestContext` accumulating IDs when
13
+ * the event happens during a request lifecycle (vs. lifecycle-only
14
+ * events like onClientCreate).
15
+ */
16
+ import type { ConversationHistory } from '../agent/history';
17
+ import type { GuardrailTriggeredContext } from '../agent/guardrail-types';
18
+ import type { ApprovalRequest, ApprovalDecision } from '../agent/approval-types';
19
+ import type { ContentPart, Message, ToolCallPart } from '../llm/types/messages';
20
+ import type { CompletionResponse } from '../llm/types/response';
21
+ import type { ErrorKind, LLMError } from '../network/errors';
22
+ import type { TraceContext } from '../network/types';
23
+ import type { RequestContext } from '../types/request-context';
24
+ export type { GuardrailTriggeredContext };
25
+ /** Sources known to emit warnings. */
26
+ export type WarningSource = 'agent' | 'llm' | 'network' | 'engine' | 'queue' | 'cache' | 'cost' | 'context' | 'media' | 'files' | 'persistence' | 'server' | 'plugin';
27
+ export interface WarningContext {
28
+ source: WarningSource;
29
+ code: string;
30
+ message: string;
31
+ details?: Record<string, unknown>;
32
+ }
33
+ /** An internal SDK invariant was violated — a "should never happen" event, e.g.
34
+ * a queue worker threw from its pre-`try` setup (which would otherwise hang the
35
+ * caller forever). Deliberately DISTINCT from `onModelError`: that signals a
36
+ * provider/model request failure (the provider's fault, expected to recur under
37
+ * load); this signals a bug in the SDK itself. Keeping them separate stops
38
+ * engine bugs from polluting per-provider error metrics and makes any occurrence
39
+ * here independently alert-worthy. */
40
+ export interface InternalErrorContext {
41
+ /** Subsystem that raised it. */
42
+ source: WarningSource;
43
+ /** The error the affected caller will be rejected with. */
44
+ error: LLMError;
45
+ /** Queue name when raised inside a queued request, else null. */
46
+ queueName: string | null;
47
+ /** Provider when known, else null. */
48
+ provider: string | null;
49
+ }
50
+ /** Queue layer */
51
+ export interface EnqueueContext {
52
+ provider: string;
53
+ model: string;
54
+ queueName: string;
55
+ priority: number;
56
+ queueLength: number;
57
+ estimatedTokens: number;
58
+ trace?: TraceContext;
59
+ }
60
+ export interface DequeueContext {
61
+ provider: string;
62
+ model: string;
63
+ queueName: string;
64
+ waitedMs: number;
65
+ queueLength: number;
66
+ trace?: TraceContext;
67
+ }
68
+ export interface QueueTimeoutContext {
69
+ provider: string;
70
+ model: string;
71
+ queueName: string;
72
+ waitedMs: number;
73
+ deadline: number;
74
+ trace?: TraceContext;
75
+ }
76
+ export interface RateLimitUpdateContext {
77
+ provider: string;
78
+ queueName: string;
79
+ source: 'response_headers' | 'rate_limit_error';
80
+ rpmRemaining: number | null;
81
+ tpmRemaining: number | null;
82
+ rpmLimit: number | null;
83
+ tpmLimit: number | null;
84
+ resetAt: number | null;
85
+ trace?: TraceContext;
86
+ }
87
+ /** HTTP layer */
88
+ export interface RequestStartContext {
89
+ provider: string;
90
+ model: string;
91
+ queueName: string;
92
+ url: string;
93
+ method: string;
94
+ bodySize: number;
95
+ attempt: number;
96
+ idempotencyKey: string;
97
+ streaming: boolean;
98
+ /** Set true to abort the request. */
99
+ abort?: boolean;
100
+ trace?: TraceContext;
101
+ }
102
+ export interface RequestCompleteContext {
103
+ provider: string;
104
+ model: string;
105
+ queueName: string;
106
+ status: number;
107
+ headers: Record<string, string>;
108
+ latencyMs: number;
109
+ attempt: number;
110
+ bodySize: number;
111
+ streaming: boolean;
112
+ trace?: TraceContext;
113
+ }
114
+ export interface ModelErrorContext {
115
+ provider: string;
116
+ model: string;
117
+ queueName: string;
118
+ error: LLMError;
119
+ headers: Record<string, string>;
120
+ attempt: number;
121
+ willRetry: boolean;
122
+ trace?: TraceContext;
123
+ }
124
+ export interface RateLimitHitContext {
125
+ provider: string;
126
+ model: string;
127
+ queueName: string;
128
+ status: number;
129
+ retryAfterMs: number | null;
130
+ headers: Record<string, string>;
131
+ remainingRequests: number | null;
132
+ remainingTokens: number | null;
133
+ limitRequests: number | null;
134
+ limitTokens: number | null;
135
+ trace?: TraceContext;
136
+ }
137
+ export interface RetryContext {
138
+ provider: string;
139
+ model: string;
140
+ queueName: string;
141
+ attempt: number;
142
+ backoffMs: number;
143
+ reason: ErrorKind;
144
+ idempotencyKey: string;
145
+ trace?: TraceContext;
146
+ }
147
+ export interface StreamChunkContext {
148
+ provider: string;
149
+ model: string;
150
+ queueName: string;
151
+ chunkIndex: number;
152
+ raw: unknown;
153
+ trace?: TraceContext;
154
+ }
155
+ export interface ClientCreateContext {
156
+ clientId: string;
157
+ provider: string;
158
+ model: string;
159
+ mode: 'foreground' | 'background';
160
+ batchable: boolean;
161
+ }
162
+ export interface ClientDestroyContext {
163
+ clientId: string;
164
+ provider: string;
165
+ model: string;
166
+ }
167
+ export interface MessageResolveContext {
168
+ provider: string;
169
+ model: string;
170
+ /** Messages being sent. Handlers MAY mutate this array in place
171
+ * (FilesRegistry resolves file refs; ContextGuard compacts). */
172
+ messages: Message[];
173
+ /** Full system-prompt string. */
174
+ system?: string;
175
+ /** Conversation reference, when caller (AgentLoop) provides it. Enables
176
+ * ContextGuard to read strategy from history.metadata and mutate history. */
177
+ history?: ConversationHistory;
178
+ /** Set true to abort the request pre-send. */
179
+ abort?: boolean;
180
+ abortReason?: string;
181
+ }
182
+ export interface BeforeSubmitContext {
183
+ provider: string;
184
+ model: string;
185
+ clientId: string;
186
+ agentId?: string;
187
+ mode: 'foreground' | 'background';
188
+ batchable: boolean;
189
+ /** Provider-formatted request body. */
190
+ request: Record<string, unknown>;
191
+ /** RequestContext IDs accumulated so far. */
192
+ ctx: RequestContext;
193
+ intercepted?: boolean;
194
+ resultPromise?: Promise<unknown>;
195
+ }
196
+ export interface CompletionContext {
197
+ provider: string;
198
+ model: string;
199
+ response: CompletionResponse;
200
+ request: {
201
+ estimatedInputTokens: number;
202
+ inputChars: number;
203
+ messageCount: number;
204
+ hasTools: boolean;
205
+ };
206
+ /** Provider-formatted request body — same object passed to onBeforeSubmit. */
207
+ requestBody?: Record<string, unknown>;
208
+ /** Raw HTTP response body (pre-parsing). Cache stores this so a hit can
209
+ * replay exact bytes through parseResponse. */
210
+ responseBody?: unknown;
211
+ /** RequestContext IDs accumulated through the call. */
212
+ ctx: RequestContext;
213
+ }
214
+ export interface AgentCreateContext {
215
+ agentId: string;
216
+ clientId: string;
217
+ provider: string;
218
+ model: string;
219
+ mode: 'foreground' | 'background';
220
+ batchable: boolean;
221
+ }
222
+ export interface AgentDestroyContext {
223
+ agentId: string;
224
+ clientId: string;
225
+ }
226
+ export interface RunStartContext {
227
+ runId: string;
228
+ agentId: string;
229
+ userMessage: string | ContentPart[] | Message[];
230
+ model: string;
231
+ system?: string;
232
+ toolNames: string[];
233
+ historyLength: number;
234
+ trace?: TraceContext;
235
+ }
236
+ export interface StepStartContext {
237
+ runId: string;
238
+ agentId: string;
239
+ step: number;
240
+ type: 'initial' | 'tool_followup';
241
+ messageCount: number;
242
+ estimatedInputTokens: number;
243
+ trace?: TraceContext;
244
+ }
245
+ export interface StepCompleteContext {
246
+ runId: string;
247
+ agentId: string;
248
+ step: number;
249
+ response: CompletionResponse;
250
+ hasToolCalls: boolean;
251
+ toolCalls: ToolCallPart[];
252
+ willContinue: boolean;
253
+ trace?: TraceContext;
254
+ }
255
+ export interface ToolCallStartContext {
256
+ runId: string;
257
+ agentId: string;
258
+ step: number;
259
+ callId: string;
260
+ toolName: string;
261
+ arguments: Record<string, unknown>;
262
+ /** Set true to skip execution. */
263
+ skip?: boolean;
264
+ /** Set to use this string as the result without executing. */
265
+ overrideResult?: string;
266
+ trace?: TraceContext;
267
+ }
268
+ export interface ToolCallCompleteContext {
269
+ runId: string;
270
+ agentId: string;
271
+ step: number;
272
+ callId: string;
273
+ toolName: string;
274
+ arguments: Record<string, unknown>;
275
+ result: string | ContentPart[];
276
+ resultSizeBytes: number;
277
+ latencyMs: number;
278
+ metrics: Map<string, {
279
+ value: number | string | boolean;
280
+ type: string;
281
+ }>;
282
+ trace?: TraceContext;
283
+ }
284
+ export interface ToolCallErrorContext {
285
+ runId: string;
286
+ agentId: string;
287
+ step: number;
288
+ callId: string;
289
+ toolName: string;
290
+ arguments: Record<string, unknown>;
291
+ error: Error;
292
+ latencyMs: number;
293
+ metrics: Map<string, {
294
+ value: number | string | boolean;
295
+ type: string;
296
+ }>;
297
+ /** Default true — set false to abort the run. */
298
+ continueOnError?: boolean;
299
+ /** Use this instead of the error message. */
300
+ fallbackResult?: string;
301
+ trace?: TraceContext;
302
+ }
303
+ export interface RunCompleteContext {
304
+ runId: string;
305
+ agentId: string;
306
+ /** Original input passed to `agent.complete(...)` for this run. */
307
+ userMessage: string | ContentPart[] | Message[];
308
+ reason: 'done' | 'stopped' | 'error' | 'guardrail' | 'max_steps';
309
+ text: string;
310
+ response: CompletionResponse;
311
+ trace?: TraceContext;
312
+ }
313
+ export interface RunErrorContext {
314
+ runId: string;
315
+ agentId: string;
316
+ step: number;
317
+ error: Error;
318
+ phase: 'build_request' | 'llm_call' | 'tool_execution' | 'parse_response';
319
+ trace?: TraceContext;
320
+ }
321
+ /** Emitted when the loop suspends at an approval gate waiting for a human decision.
322
+ * Extends ApprovalRequest (which carries trace) and adds flat runId/agentId so
323
+ * hook consumers have direct access to those ids without unpacking trace. */
324
+ export interface ApprovalRequestedContext extends ApprovalRequest {
325
+ /** The agent-loop run ID this call belongs to (same as trace.requestId). */
326
+ runId: string;
327
+ /** The agent ID / conversation ID (same as trace.sessionId). */
328
+ agentId: string;
329
+ }
330
+ /** Emitted when the approver returns a decision and the loop resumes. */
331
+ export interface ApprovalResolvedContext {
332
+ callId: string;
333
+ toolName: string;
334
+ runId: string;
335
+ agentId: string;
336
+ step: number;
337
+ decision: ApprovalDecision['decision'];
338
+ note?: string;
339
+ trace?: TraceContext;
340
+ }
341
+ export interface CostEntry {
342
+ id: string;
343
+ timestamp: number;
344
+ provider: string;
345
+ model: string;
346
+ tokens: {
347
+ input: number;
348
+ output: number;
349
+ cached: number;
350
+ cacheWrite: number;
351
+ reasoning: number;
352
+ /** Audio input/output tokens (realtime / audio models), priced separately. */
353
+ audioInput?: number;
354
+ audioOutput?: number;
355
+ };
356
+ cost: {
357
+ input: number;
358
+ output: number;
359
+ cacheRead: number;
360
+ cacheWrite: number;
361
+ reasoning: number;
362
+ total: number;
363
+ source: 'provider' | 'calculated' | 'unknown';
364
+ };
365
+ /** Service tier billed (provider's raw name, e.g. 'batch' | 'priority'), when
366
+ * the provider reported one. The tier whose rates were used for `cost`. */
367
+ serviceTier?: string;
368
+ providerEvidence: Record<string, unknown>;
369
+ tags: Record<string, string | undefined>;
370
+ }
371
+ export interface CostEntryContext {
372
+ entry: CostEntry;
373
+ runningTotal: number;
374
+ trace?: TraceContext;
375
+ }
376
+ export interface BudgetWarningContext {
377
+ budgetId: string;
378
+ scope: Record<string, string | undefined>;
379
+ limit: number;
380
+ current: number;
381
+ threshold: number;
382
+ percentage: number;
383
+ }
384
+ export interface BudgetExceededContext {
385
+ budgetId: string;
386
+ scope: Record<string, string | undefined>;
387
+ limit: number;
388
+ current: number;
389
+ overage: number;
390
+ }
391
+ export interface ContextMeasureContext {
392
+ provider: string;
393
+ model: string;
394
+ /** Estimated current input tokens. */
395
+ current: number;
396
+ /** Model context window (null if unknown). */
397
+ window: number | null;
398
+ /** current / window, 0-1 (null when window unknown). */
399
+ percentage: number | null;
400
+ accuracy: 'fast' | 'exact';
401
+ messages: Message[];
402
+ system?: string;
403
+ history?: ConversationHistory;
404
+ abort?: boolean;
405
+ abortReason?: string;
406
+ trace?: TraceContext;
407
+ }
408
+ export interface InternalToolCallStartContext {
409
+ toolId: string;
410
+ input: unknown;
411
+ /** Empty string for non-LLM tools. */
412
+ chosenModel: string;
413
+ attempt: number;
414
+ }
415
+ export interface InternalToolCallCompleteContext {
416
+ toolId: string;
417
+ input: unknown;
418
+ output: unknown;
419
+ /** Empty string for non-LLM tools. */
420
+ chosenModel: string;
421
+ latencyMs: number;
422
+ attempts: number;
423
+ /** Usage from the underlying LLM call, when applicable. */
424
+ usage?: import('../llm/types/response').Usage;
425
+ }
426
+ export interface InternalToolCallErrorContext {
427
+ toolId: string;
428
+ input: unknown;
429
+ /** Empty string for non-LLM tools. */
430
+ chosenModel: string;
431
+ error: Error;
432
+ attempt: number;
433
+ willRetry: boolean;
434
+ }
435
+ export interface MediaGeneratedContext {
436
+ /** MediaOutputPart entries — one per saved media item. */
437
+ parts: Array<import('../llm/types/messages').MediaOutputPart>;
438
+ /** True when MediaStore retained the bytes. */
439
+ stored: boolean;
440
+ provider: string;
441
+ /** `inline` = from inside an LLM response; `media_output` = MediaOutput. */
442
+ source: 'inline' | 'media_output';
443
+ /** Cost-bearing metadata. CostCollector subscribes to this event and
444
+ * computes via catalog.pricing (perImage, perMChars, perSecond). */
445
+ model?: string;
446
+ mediaType?: 'image' | 'audio' | 'video';
447
+ count?: number;
448
+ /** For audio TTS — chars-billed input. */
449
+ textInput?: string;
450
+ /** For video — generated duration seconds. */
451
+ durationSeconds?: number;
452
+ /** Token usage the provider reported (token-priced media). Lets the cost
453
+ * engine price gpt-image / gemini-tts by their per-token rates. */
454
+ usage?: import('../llm/types/response').Usage;
455
+ /** The resolution requested — selects a `perUnit[resolution]` rate. */
456
+ resolution?: string;
457
+ /** Provider-reported cost evidence (extracted), when the response carries it. */
458
+ providerEvidence?: Record<string, unknown>;
459
+ /** Trace correlation for this media op (sessionId + minted requestId). */
460
+ trace?: TraceContext;
461
+ }
462
+ export interface MediaErrorContext {
463
+ id: string;
464
+ type: 'image' | 'audio' | 'video';
465
+ provider: string;
466
+ error: string;
467
+ /** For async ops (video). */
468
+ operationId?: string;
469
+ }
470
+ export interface ServerRequestContext {
471
+ serverId: string;
472
+ requestId: string;
473
+ method: string;
474
+ path: string;
475
+ userId: string | null;
476
+ model: string | null;
477
+ }
478
+ export interface ServerResponseContext {
479
+ serverId: string;
480
+ requestId: string;
481
+ status: number;
482
+ latencyMs: number;
483
+ userId: string | null;
484
+ model: string | null;
485
+ }
486
+ export interface AuthFailContext {
487
+ serverId: string;
488
+ requestId: string;
489
+ reason: string;
490
+ }
491
+ export interface RealtimeOpenContext {
492
+ provider: string;
493
+ model: string;
494
+ url: string;
495
+ }
496
+ /** One frame crossed the socket. Carries METADATA only (never the payload) —
497
+ * size + direction + kind, enough for cost/observability without leaking
498
+ * conversation content through the hook bus. */
499
+ export interface RealtimeFrameContext {
500
+ provider: string;
501
+ model: string;
502
+ direction: 'in' | 'out';
503
+ kind: 'text' | 'binary';
504
+ bytes: number;
505
+ }
506
+ export interface RealtimeCloseContext {
507
+ provider: string;
508
+ model: string;
509
+ code: number | null;
510
+ reason: string | null;
511
+ }
512
+ export interface RealtimeErrorContext {
513
+ provider: string;
514
+ model: string;
515
+ error: Error;
516
+ }
517
+ /** The catalog. Extend per-phase. */
518
+ export interface McpConnectContext {
519
+ /** The connection's namespace/label. */
520
+ server: string;
521
+ transport: 'stdio' | 'http' | 'ws';
522
+ serverName?: string;
523
+ serverVersion?: string;
524
+ toolCount: number;
525
+ trace?: TraceContext;
526
+ }
527
+ export interface McpToolCallContext {
528
+ server: string;
529
+ tool: string;
530
+ latencyMs: number;
531
+ isError: boolean;
532
+ trace?: TraceContext;
533
+ }
534
+ export interface McpErrorContext {
535
+ server: string;
536
+ phase: 'connect' | 'request';
537
+ error: Error;
538
+ trace?: TraceContext;
539
+ }
540
+ export interface HookMap {
541
+ onWarning: WarningContext;
542
+ onInternalError: InternalErrorContext;
543
+ onEnqueue: EnqueueContext;
544
+ onDequeue: DequeueContext;
545
+ onQueueTimeout: QueueTimeoutContext;
546
+ onRateLimitUpdate: RateLimitUpdateContext;
547
+ onRequestStart: RequestStartContext;
548
+ onRequestComplete: RequestCompleteContext;
549
+ onModelError: ModelErrorContext;
550
+ onRateLimitHit: RateLimitHitContext;
551
+ onRetry: RetryContext;
552
+ onStreamChunk: StreamChunkContext;
553
+ onRealtimeOpen: RealtimeOpenContext;
554
+ onRealtimeFrame: RealtimeFrameContext;
555
+ onRealtimeClose: RealtimeCloseContext;
556
+ onRealtimeError: RealtimeErrorContext;
557
+ onClientCreate: ClientCreateContext;
558
+ onClientDestroy: ClientDestroyContext;
559
+ onMessageResolve: MessageResolveContext;
560
+ onBeforeSubmit: BeforeSubmitContext;
561
+ onCompletion: CompletionContext;
562
+ onAgentCreate: AgentCreateContext;
563
+ onAgentDestroy: AgentDestroyContext;
564
+ onRunStart: RunStartContext;
565
+ onStepStart: StepStartContext;
566
+ onStepComplete: StepCompleteContext;
567
+ onToolCallStart: ToolCallStartContext;
568
+ onToolCallComplete: ToolCallCompleteContext;
569
+ onToolCallError: ToolCallErrorContext;
570
+ onRunComplete: RunCompleteContext;
571
+ onRunError: RunErrorContext;
572
+ onGuardrailTriggered: GuardrailTriggeredContext;
573
+ onApprovalRequested: ApprovalRequestedContext;
574
+ onApprovalResolved: ApprovalResolvedContext;
575
+ onServerRequest: ServerRequestContext;
576
+ onServerResponse: ServerResponseContext;
577
+ onAuthFail: AuthFailContext;
578
+ onCostEntry: CostEntryContext;
579
+ onBudgetWarning: BudgetWarningContext;
580
+ onBudgetExceeded: BudgetExceededContext;
581
+ onContextMeasure: ContextMeasureContext;
582
+ onMediaGenerated: MediaGeneratedContext;
583
+ onMediaError: MediaErrorContext;
584
+ onInternalToolCallStart: InternalToolCallStartContext;
585
+ onInternalToolCallComplete: InternalToolCallCompleteContext;
586
+ onInternalToolCallError: InternalToolCallErrorContext;
587
+ onMcpConnect: McpConnectContext;
588
+ onMcpToolCall: McpToolCallContext;
589
+ onMcpError: McpErrorContext;
590
+ }
591
+ export type HookName = keyof HookMap;
592
+ export type HookHandler<K extends HookName> = (ctx: HookMap[K]) => void | Promise<void>;
@@ -0,0 +1,32 @@
1
+ /** createAgent — convenience helper that builds an AgentLoop. Accepts either
2
+ * a pre-built `client` or a model string (`'provider/model'`) plus optional
3
+ * apiKey override; the helper builds the client via createLLM with the
4
+ * engine's fetch + hooks + adapter wiring, pulling apiKey from
5
+ * `engine.apiKeys` when not passed. */
6
+ import { AgentLoop } from '../agent/loop';
7
+ import type { AgentLoopConfig } from '../agent/loop-config';
8
+ import type { LLMClient } from '../llm/client';
9
+ import type { LLMClientConfig } from '../llm/client-config';
10
+ import type { ProviderName } from '../llm/types/provider';
11
+ import type { EngineHandle } from './engine';
12
+ export interface CreateAgentOptions extends Omit<AgentLoopConfig, 'client' | 'hooks' | 'system'> {
13
+ /** Persona / role text. May be a function for live-reload prompts —
14
+ * re-evaluated at the start of every `complete()` / `stream()` call. */
15
+ system?: AgentLoopConfig['system'];
16
+ /** Pre-built client. When omitted, pass a `model` (and optionally `apiKey`)
17
+ * and the helper will build one via createLLM. */
18
+ client?: LLMClient;
19
+ /** Model string. Bare (e.g. `claude-haiku-4-5` — pair with `provider`) or
20
+ * namespaced (e.g. `anthropic/claude-haiku-4-5`). */
21
+ model?: string;
22
+ /** Required when `model` is bare. */
23
+ provider?: ProviderName;
24
+ /** Optional — falls back to `engine.apiKeys[provider]`. */
25
+ apiKey?: string;
26
+ baseURL?: string;
27
+ /** Extra LLMClient options applied to the lazily-built client. */
28
+ clientOptions?: Partial<Omit<LLMClientConfig, 'provider' | 'model' | 'apiKey' | 'baseURL' | 'hooks' | 'fetch'>>;
29
+ engine?: EngineHandle;
30
+ hooks?: AgentLoopConfig['hooks'];
31
+ }
32
+ export declare function createAgent(opts: CreateAgentOptions): AgentLoop;