@better-agent/core 0.1.0-beta.1

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 (179) hide show
  1. package/README.md +3 -0
  2. package/dist/agent/constants.mjs +6 -0
  3. package/dist/agent/constants.mjs.map +1 -0
  4. package/dist/agent/define-agent.d.mts +29 -0
  5. package/dist/agent/define-agent.d.mts.map +1 -0
  6. package/dist/agent/define-agent.mjs +27 -0
  7. package/dist/agent/define-agent.mjs.map +1 -0
  8. package/dist/agent/index.d.mts +2 -0
  9. package/dist/agent/types.d.mts +216 -0
  10. package/dist/agent/types.d.mts.map +1 -0
  11. package/dist/agent/validation.mjs +64 -0
  12. package/dist/agent/validation.mjs.map +1 -0
  13. package/dist/api.d.mts +8 -0
  14. package/dist/api.d.mts.map +1 -0
  15. package/dist/api.mjs +63 -0
  16. package/dist/api.mjs.map +1 -0
  17. package/dist/app/config.mjs +43 -0
  18. package/dist/app/config.mjs.map +1 -0
  19. package/dist/app/create-app.d.mts +36 -0
  20. package/dist/app/create-app.d.mts.map +1 -0
  21. package/dist/app/create-app.mjs +132 -0
  22. package/dist/app/create-app.mjs.map +1 -0
  23. package/dist/app/registry.mjs +43 -0
  24. package/dist/app/registry.mjs.map +1 -0
  25. package/dist/app/types.d.mts +142 -0
  26. package/dist/app/types.d.mts.map +1 -0
  27. package/dist/events/constants.d.mts +49 -0
  28. package/dist/events/constants.d.mts.map +1 -0
  29. package/dist/events/constants.mjs +46 -0
  30. package/dist/events/constants.mjs.map +1 -0
  31. package/dist/events/index.d.mts +4 -0
  32. package/dist/events/index.mjs +3 -0
  33. package/dist/events/types.d.mts +289 -0
  34. package/dist/events/types.d.mts.map +1 -0
  35. package/dist/index.d.mts +23 -0
  36. package/dist/index.mjs +14 -0
  37. package/dist/internal/id.mjs +21 -0
  38. package/dist/internal/id.mjs.map +1 -0
  39. package/dist/internal/types.d.mts +11 -0
  40. package/dist/internal/types.d.mts.map +1 -0
  41. package/dist/mcp/error/mcp-client-error.d.mts +36 -0
  42. package/dist/mcp/error/mcp-client-error.d.mts.map +1 -0
  43. package/dist/mcp/error/mcp-client-error.mjs +33 -0
  44. package/dist/mcp/error/mcp-client-error.mjs.map +1 -0
  45. package/dist/mcp/index.d.mts +8 -0
  46. package/dist/mcp/index.mjs +9 -0
  47. package/dist/mcp/tool/json-rpc-message.d.mts +50 -0
  48. package/dist/mcp/tool/json-rpc-message.d.mts.map +1 -0
  49. package/dist/mcp/tool/json-rpc-message.mjs +84 -0
  50. package/dist/mcp/tool/json-rpc-message.mjs.map +1 -0
  51. package/dist/mcp/tool/mcp-client.d.mts +71 -0
  52. package/dist/mcp/tool/mcp-client.d.mts.map +1 -0
  53. package/dist/mcp/tool/mcp-client.mjs +304 -0
  54. package/dist/mcp/tool/mcp-client.mjs.map +1 -0
  55. package/dist/mcp/tool/mcp-http-transport.d.mts +62 -0
  56. package/dist/mcp/tool/mcp-http-transport.d.mts.map +1 -0
  57. package/dist/mcp/tool/mcp-http-transport.mjs +307 -0
  58. package/dist/mcp/tool/mcp-http-transport.mjs.map +1 -0
  59. package/dist/mcp/tool/mcp-tools.d.mts +20 -0
  60. package/dist/mcp/tool/mcp-tools.d.mts.map +1 -0
  61. package/dist/mcp/tool/mcp-tools.mjs +73 -0
  62. package/dist/mcp/tool/mcp-tools.mjs.map +1 -0
  63. package/dist/mcp/tool/mcp-transport.d.mts +81 -0
  64. package/dist/mcp/tool/mcp-transport.d.mts.map +1 -0
  65. package/dist/mcp/tool/mcp-transport.mjs +11 -0
  66. package/dist/mcp/tool/mcp-transport.mjs.map +1 -0
  67. package/dist/mcp/tool/types.d.mts +230 -0
  68. package/dist/mcp/tool/types.d.mts.map +1 -0
  69. package/dist/mcp/tool/types.mjs +19 -0
  70. package/dist/mcp/tool/types.mjs.map +1 -0
  71. package/dist/persistence/index.d.mts +3 -0
  72. package/dist/persistence/index.mjs +3 -0
  73. package/dist/persistence/memory.d.mts +21 -0
  74. package/dist/persistence/memory.d.mts.map +1 -0
  75. package/dist/persistence/memory.mjs +107 -0
  76. package/dist/persistence/memory.mjs.map +1 -0
  77. package/dist/persistence/types.d.mts +124 -0
  78. package/dist/persistence/types.d.mts.map +1 -0
  79. package/dist/plugins/index.d.mts +2 -0
  80. package/dist/plugins/runtime.d.mts +17 -0
  81. package/dist/plugins/runtime.d.mts.map +1 -0
  82. package/dist/plugins/runtime.mjs +456 -0
  83. package/dist/plugins/runtime.mjs.map +1 -0
  84. package/dist/plugins/types.d.mts +344 -0
  85. package/dist/plugins/types.d.mts.map +1 -0
  86. package/dist/providers/index.d.mts +9 -0
  87. package/dist/providers/index.mjs +0 -0
  88. package/dist/providers/types/capabilities.d.mts +153 -0
  89. package/dist/providers/types/capabilities.d.mts.map +1 -0
  90. package/dist/providers/types/content.d.mts +125 -0
  91. package/dist/providers/types/content.d.mts.map +1 -0
  92. package/dist/providers/types/conversation.d.mts +32 -0
  93. package/dist/providers/types/conversation.d.mts.map +1 -0
  94. package/dist/providers/types/index.d.mts +8 -0
  95. package/dist/providers/types/input.d.mts +74 -0
  96. package/dist/providers/types/input.d.mts.map +1 -0
  97. package/dist/providers/types/model.d.mts +68 -0
  98. package/dist/providers/types/model.d.mts.map +1 -0
  99. package/dist/providers/types/output.d.mts +29 -0
  100. package/dist/providers/types/output.d.mts.map +1 -0
  101. package/dist/providers/types/response.d.mts +35 -0
  102. package/dist/providers/types/response.d.mts.map +1 -0
  103. package/dist/providers/types/tool-calls.d.mts +51 -0
  104. package/dist/providers/types/tool-calls.d.mts.map +1 -0
  105. package/dist/run/agent-loop.mjs +231 -0
  106. package/dist/run/agent-loop.mjs.map +1 -0
  107. package/dist/run/event-queue.mjs +67 -0
  108. package/dist/run/event-queue.mjs.map +1 -0
  109. package/dist/run/execute-tool-calls.mjs +550 -0
  110. package/dist/run/execute-tool-calls.mjs.map +1 -0
  111. package/dist/run/execution.mjs +93 -0
  112. package/dist/run/execution.mjs.map +1 -0
  113. package/dist/run/helpers.mjs +466 -0
  114. package/dist/run/helpers.mjs.map +1 -0
  115. package/dist/run/hooks.mjs +124 -0
  116. package/dist/run/hooks.mjs.map +1 -0
  117. package/dist/run/index.d.mts +4 -0
  118. package/dist/run/messages.d.mts +8 -0
  119. package/dist/run/messages.d.mts.map +1 -0
  120. package/dist/run/messages.mjs +83 -0
  121. package/dist/run/messages.mjs.map +1 -0
  122. package/dist/run/model-strategy.mjs +105 -0
  123. package/dist/run/model-strategy.mjs.map +1 -0
  124. package/dist/run/output-errors.d.mts +75 -0
  125. package/dist/run/output-errors.d.mts.map +1 -0
  126. package/dist/run/pending-tools.d.mts +1 -0
  127. package/dist/run/pending-tools.mjs +185 -0
  128. package/dist/run/pending-tools.mjs.map +1 -0
  129. package/dist/run/registry.mjs +22 -0
  130. package/dist/run/registry.mjs.map +1 -0
  131. package/dist/run/runtime.d.mts +19 -0
  132. package/dist/run/runtime.d.mts.map +1 -0
  133. package/dist/run/runtime.mjs +491 -0
  134. package/dist/run/runtime.mjs.map +1 -0
  135. package/dist/run/stop-conditions.mjs +41 -0
  136. package/dist/run/stop-conditions.mjs.map +1 -0
  137. package/dist/run/types.d.mts +348 -0
  138. package/dist/run/types.d.mts.map +1 -0
  139. package/dist/schema/index.d.mts +2 -0
  140. package/dist/schema/resolve-json-schema.d.mts +12 -0
  141. package/dist/schema/resolve-json-schema.d.mts.map +1 -0
  142. package/dist/schema/resolve-json-schema.mjs +167 -0
  143. package/dist/schema/resolve-json-schema.mjs.map +1 -0
  144. package/dist/schema/types.d.mts +27 -0
  145. package/dist/schema/types.d.mts.map +1 -0
  146. package/dist/server/create-server.d.mts +21 -0
  147. package/dist/server/create-server.d.mts.map +1 -0
  148. package/dist/server/create-server.mjs +107 -0
  149. package/dist/server/create-server.mjs.map +1 -0
  150. package/dist/server/http.mjs +182 -0
  151. package/dist/server/http.mjs.map +1 -0
  152. package/dist/server/index.d.mts +3 -0
  153. package/dist/server/index.mjs +3 -0
  154. package/dist/server/routes.mjs +399 -0
  155. package/dist/server/routes.mjs.map +1 -0
  156. package/dist/server/types.d.mts +31 -0
  157. package/dist/server/types.d.mts.map +1 -0
  158. package/dist/tools/constants.d.mts +12 -0
  159. package/dist/tools/constants.d.mts.map +1 -0
  160. package/dist/tools/constants.mjs +13 -0
  161. package/dist/tools/constants.mjs.map +1 -0
  162. package/dist/tools/define-tool.d.mts +25 -0
  163. package/dist/tools/define-tool.d.mts.map +1 -0
  164. package/dist/tools/define-tool.mjs +76 -0
  165. package/dist/tools/define-tool.mjs.map +1 -0
  166. package/dist/tools/index.d.mts +5 -0
  167. package/dist/tools/lazy-tools.d.mts +49 -0
  168. package/dist/tools/lazy-tools.d.mts.map +1 -0
  169. package/dist/tools/lazy-tools.mjs +87 -0
  170. package/dist/tools/lazy-tools.mjs.map +1 -0
  171. package/dist/tools/resolve-tools.d.mts +12 -0
  172. package/dist/tools/resolve-tools.d.mts.map +1 -0
  173. package/dist/tools/resolve-tools.mjs +86 -0
  174. package/dist/tools/resolve-tools.mjs.map +1 -0
  175. package/dist/tools/types.d.mts +318 -0
  176. package/dist/tools/types.d.mts.map +1 -0
  177. package/dist/tools/validation.mjs +23 -0
  178. package/dist/tools/validation.mjs.map +1 -0
  179. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-tools.mjs","names":[],"sources":["../../src/run/pending-tools.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { SubmitToolApprovalParams, SubmitToolResultParams } from \"./types\";\n\nexport interface PendingToolRuntime {\n awaitClientToolResult(params: {\n runId: string;\n toolCallId: string;\n toolName: string;\n timeoutMs?: number;\n signal?: AbortSignal;\n }): Promise<unknown>;\n awaitToolApproval(params: {\n runId: string;\n toolCallId: string;\n toolName: string;\n timeoutMs?: number;\n signal?: AbortSignal;\n }): Promise<{\n decision: \"approved\" | \"denied\";\n note?: string;\n actorId?: string;\n }>;\n submitToolResult(params: SubmitToolResultParams): Promise<boolean>;\n submitToolApproval(params: SubmitToolApprovalParams): Promise<boolean>;\n clearRun(runId: string, reason: string): void;\n}\n\nexport const createPendingToolRuntime = (): PendingToolRuntime => {\n type PendingEntry<TValue> = {\n resolve: (value: TValue) => void;\n reject: (error: BetterAgentError) => void;\n };\n const pendingClientToolCalls = new Map<string, Map<string, PendingEntry<unknown>>>();\n const pendingApprovals = new Map<\n string,\n Map<\n string,\n PendingEntry<{\n decision: \"approved\" | \"denied\";\n note?: string;\n actorId?: string;\n }>\n >\n >();\n\n const removePendingEntry = <TValue>(\n entries: Map<string, Map<string, PendingEntry<TValue>>>,\n runId: string,\n toolCallId: string,\n ) => {\n const runPending = entries.get(runId);\n if (!runPending) {\n return;\n }\n\n runPending.delete(toolCallId);\n if (runPending.size === 0) {\n entries.delete(runId);\n }\n };\n\n return {\n awaitClientToolResult(params) {\n return new Promise((resolve, reject) => {\n const timeoutMs = params.timeoutMs ?? 30_000;\n const runPending = pendingClientToolCalls.get(params.runId) ?? new Map();\n pendingClientToolCalls.set(params.runId, runPending);\n\n if (runPending.has(params.toolCallId)) {\n reject(\n BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Client tool '${params.toolName}' call '${params.toolCallId}' is already pending.`,\n {\n context: {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n trace: [{ at: \"core.run.pendingTools.awaitClientToolResult\" }],\n },\n ),\n );\n return;\n }\n\n const onAbort = () => {\n cleanup();\n reject(\n createAbortError(\n `Run '${params.runId}' was aborted while waiting for client tool result for '${params.toolName}'.`,\n {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n ),\n );\n };\n const cleanup = () => {\n clearTimeout(timeout);\n params.signal?.removeEventListener(\"abort\", onAbort);\n removePendingEntry(pendingClientToolCalls, params.runId, params.toolCallId);\n };\n const timeout = setTimeout(() => {\n cleanup();\n reject(\n BetterAgentError.fromCode(\n \"TIMEOUT\",\n `Timed out waiting for client tool result for '${params.toolName}'.`,\n {\n context: {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n trace: [{ at: \"core.run.pendingTools.awaitClientToolResult\" }],\n },\n ),\n );\n }, timeoutMs);\n\n if (params.signal?.aborted) {\n onAbort();\n return;\n }\n\n params.signal?.addEventListener(\"abort\", onAbort, { once: true });\n runPending.set(params.toolCallId, {\n resolve: (value: unknown) => {\n cleanup();\n resolve(value);\n },\n reject: (error: BetterAgentError) => {\n cleanup();\n reject(error);\n },\n });\n });\n },\n\n awaitToolApproval(params) {\n return new Promise((resolve, reject) => {\n const timeoutMs = params.timeoutMs ?? 30_000;\n const runPending = pendingApprovals.get(params.runId) ?? new Map();\n pendingApprovals.set(params.runId, runPending);\n\n if (runPending.has(params.toolCallId)) {\n reject(\n BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Tool '${params.toolName}' call '${params.toolCallId}' is already pending approval.`,\n {\n context: {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n trace: [{ at: \"core.run.pendingTools.awaitToolApproval\" }],\n },\n ),\n );\n return;\n }\n const cleanup = () => {\n clearTimeout(timeout);\n params.signal?.removeEventListener(\"abort\", onAbort);\n removePendingEntry(pendingApprovals, params.runId, params.toolCallId);\n };\n\n const onAbort = () => {\n cleanup();\n reject(\n createAbortError(\n `Run '${params.runId}' was aborted while waiting for approval of '${params.toolName}'.`,\n {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n ),\n );\n };\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(\n BetterAgentError.fromCode(\n \"TIMEOUT\",\n `Timed out waiting for approval of '${params.toolName}'.`,\n {\n context: {\n runId: params.runId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n },\n trace: [{ at: \"core.run.pendingTools.awaitToolApproval\" }],\n },\n ),\n );\n }, timeoutMs);\n\n if (params.signal?.aborted) {\n onAbort();\n return;\n }\n\n params.signal?.addEventListener(\"abort\", onAbort, { once: true });\n runPending.set(params.toolCallId, {\n resolve: (value: {\n decision: \"approved\" | \"denied\";\n note?: string;\n actorId?: string;\n }) => {\n cleanup();\n resolve(value);\n },\n reject: (error: BetterAgentError) => {\n cleanup();\n reject(error);\n },\n });\n });\n },\n\n submitToolResult(params) {\n const runPending = pendingClientToolCalls.get(params.runId);\n if (!runPending) return Promise.resolve(false);\n\n const pending = runPending.get(params.toolCallId);\n if (!pending) return Promise.resolve(false);\n\n runPending.delete(params.toolCallId);\n if (runPending.size === 0) {\n pendingClientToolCalls.delete(params.runId);\n }\n\n if (params.status === \"error\") {\n pending.reject(\n BetterAgentError.fromCode(\"TOOL_EXECUTION_FAILED\", params.error, {\n context: {\n runId: params.runId,\n toolCallId: params.toolCallId,\n },\n trace: [{ at: \"core.run.pendingTools.submitToolResult\" }],\n }),\n );\n } else {\n pending.resolve(params.result);\n }\n\n return Promise.resolve(true);\n },\n\n submitToolApproval(params) {\n const runPending = pendingApprovals.get(params.runId);\n if (!runPending) return Promise.resolve(false);\n\n const pending = runPending.get(params.toolCallId);\n if (!pending) return Promise.resolve(false);\n\n runPending.delete(params.toolCallId);\n if (runPending.size === 0) {\n pendingApprovals.delete(params.runId);\n }\n\n const result: {\n decision: \"approved\" | \"denied\";\n note?: string;\n actorId?: string;\n } = {\n decision: params.decision,\n };\n\n if (params.note !== undefined) {\n result.note = params.note;\n }\n\n if (params.actorId !== undefined) {\n result.actorId = params.actorId;\n }\n\n pending.resolve(result);\n\n return Promise.resolve(true);\n },\n\n clearRun(runId: string, reason: string) {\n const clientToolCalls = pendingClientToolCalls.get(runId);\n if (clientToolCalls) {\n for (const [toolCallId, pending] of clientToolCalls) {\n pending.reject(\n createAbortError(`Run '${runId}' was cleared: ${reason}`, {\n runId,\n toolCallId,\n }),\n );\n }\n pendingClientToolCalls.delete(runId);\n }\n\n const approvals = pendingApprovals.get(runId);\n if (approvals) {\n for (const [toolCallId, pending] of approvals) {\n pending.reject(\n createAbortError(`Run '${runId}' was cleared: ${reason}`, {\n runId,\n toolCallId,\n }),\n );\n }\n pendingApprovals.delete(runId);\n }\n },\n };\n};\n\nconst createAbortError = (message: string, context: Record<string, unknown>) =>\n BetterAgentError.fromCode(\"ABORTED\", message, {\n context,\n trace: [{ at: \"core.run.pendingTools.clearRun\" }],\n });\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { BetterAgentError } from "@better-agent/shared/errors";
2
+
3
+ //#region src/run/registry.ts
4
+ /** Builds a read-only agent registry. */
5
+ function createAgentRegistry(agents) {
6
+ const registry = /* @__PURE__ */ new Map();
7
+ for (const agent of agents) registry.set(agent.name, agent);
8
+ return registry;
9
+ }
10
+ function resolveAgentFromRegistry(agents, agent, traceAt) {
11
+ const resolved = typeof agent === "string" ? agents.get(agent) : agents.get(agent.name) ?? agent;
12
+ if (resolved) return resolved;
13
+ const agentName = typeof agent === "string" ? agent : agent.name;
14
+ throw BetterAgentError.fromCode("NOT_FOUND", `Agent '${agentName}' does not exist.`, {
15
+ context: { agentName },
16
+ trace: [{ at: traceAt }]
17
+ });
18
+ }
19
+
20
+ //#endregion
21
+ export { createAgentRegistry, resolveAgentFromRegistry };
22
+ //# sourceMappingURL=registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../../src/run/registry.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { AnyAgentDefinition } from \"../agent\";\n\n/** Builds a read-only agent registry. */\nexport function createAgentRegistry(\n agents: readonly AnyAgentDefinition[],\n): ReadonlyMap<string, AnyAgentDefinition> {\n const registry = new Map<string, AnyAgentDefinition>();\n\n for (const agent of agents) {\n registry.set(agent.name, agent);\n }\n\n return registry;\n}\n\nexport function resolveAgentFromRegistry(\n agents: ReadonlyMap<string, AnyAgentDefinition>,\n agent: string | AnyAgentDefinition,\n traceAt: string,\n): AnyAgentDefinition {\n const resolved =\n typeof agent === \"string\" ? agents.get(agent) : (agents.get(agent.name) ?? agent);\n if (resolved) {\n return resolved;\n }\n\n const agentName = typeof agent === \"string\" ? agent : agent.name;\n throw BetterAgentError.fromCode(\"NOT_FOUND\", `Agent '${agentName}' does not exist.`, {\n context: { agentName },\n trace: [{ at: traceAt }],\n });\n}\n"],"mappings":";;;;AAIA,SAAgB,oBACZ,QACuC;CACvC,MAAM,2BAAW,IAAI,KAAiC;AAEtD,MAAK,MAAM,SAAS,OAChB,UAAS,IAAI,MAAM,MAAM,MAAM;AAGnC,QAAO;;AAGX,SAAgB,yBACZ,QACA,OACA,SACkB;CAClB,MAAM,WACF,OAAO,UAAU,WAAW,OAAO,IAAI,MAAM,GAAI,OAAO,IAAI,MAAM,KAAK,IAAI;AAC/E,KAAI,SACA,QAAO;CAGX,MAAM,YAAY,OAAO,UAAU,WAAW,QAAQ,MAAM;AAC5D,OAAM,iBAAiB,SAAS,aAAa,UAAU,UAAU,oBAAoB;EACjF,SAAS,EAAE,WAAW;EACtB,OAAO,CAAC,EAAE,IAAI,SAAS,CAAC;EAC3B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { AnyAgentDefinition } from "../agent/types.mjs";
2
+ import { ConversationRuntimeStateStore, ConversationStore, StreamStore } from "../persistence/types.mjs";
3
+ import { PluginRuntime } from "../plugins/types.mjs";
4
+ import { BetterAgentRuntime, RunAdvancedOptions } from "./types.mjs";
5
+
6
+ //#region src/run/runtime.d.ts
7
+ /** Creates a runtime for registered agents. */
8
+ declare function createRuntime<const TAgents extends readonly AnyAgentDefinition[]>(options: {
9
+ agents: TAgents;
10
+ pluginRuntime?: PluginRuntime | null;
11
+ stream?: StreamStore;
12
+ conversations?: ConversationStore;
13
+ runtimeState?: ConversationRuntimeStateStore;
14
+ streamLifecycle?: "request_bound" | "detached";
15
+ advanced?: RunAdvancedOptions;
16
+ }): BetterAgentRuntime<TAgents>;
17
+ //#endregion
18
+ export { createRuntime };
19
+ //# sourceMappingURL=runtime.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.mts","names":[],"sources":["../../src/run/runtime.ts"],"mappings":";;;;;;;iBAiCgB,aAAA,gCAA6C,kBAAA,GAAA,CAAsB,OAAA;EAC/E,MAAA,EAAQ,OAAA;EACR,aAAA,GAAgB,aAAA;EAChB,MAAA,GAAS,WAAA;EACT,aAAA,GAAgB,iBAAA;EAChB,YAAA,GAAe,6BAAA;EACf,eAAA;EACA,QAAA,GAAW,kBAAA;AAAA,IACX,kBAAA,CAAmB,OAAA"}
@@ -0,0 +1,491 @@
1
+ import { Events } from "../events/constants.mjs";
2
+ import { createAsyncEventQueue } from "./event-queue.mjs";
3
+ import { createStreamPersistenceEmitter, generateId, loadConversationMessages, saveConversationMessages, toEventEmitter, validateAgentContext, validateStoredConversationItems } from "./helpers.mjs";
4
+ import { executeRun } from "./execution.mjs";
5
+ import { createPendingToolRuntime } from "./pending-tools.mjs";
6
+ import { createAgentRegistry, resolveAgentFromRegistry } from "./registry.mjs";
7
+ import { BetterAgentError } from "@better-agent/shared/errors";
8
+ import { logger } from "@better-agent/shared/logger";
9
+
10
+ //#region src/run/runtime.ts
11
+ /** Creates a runtime for registered agents. */
12
+ function createRuntime(options) {
13
+ const agents = createAgentRegistry(options.agents);
14
+ const pluginRuntime = options.pluginRuntime ?? null;
15
+ const pendingToolRuntime = createPendingToolRuntime();
16
+ const streamLifecycle = options.streamLifecycle ?? "request_bound";
17
+ const activeRuns = /* @__PURE__ */ new Map();
18
+ const resolveConversationReplay = (agent, runReplay) => {
19
+ const agentReplay = agent.conversationReplay;
20
+ if (!agentReplay && !runReplay) return;
21
+ const merged = {
22
+ ...agentReplay ?? {},
23
+ ...runReplay ?? {}
24
+ };
25
+ if (runReplay && Object.prototype.hasOwnProperty.call(runReplay, "prepareInput") && runReplay.prepareInput === null) merged.prepareInput = void 0;
26
+ return merged;
27
+ };
28
+ const warnIgnoredConversationReplay = (params) => {
29
+ if (!params.conversationReplay) return;
30
+ const replayMode = params.agent.model.caps.replayMode ?? (params.agent.model.caps.inputShape === "prompt" ? "single_turn_persistent" : "multi_turn");
31
+ if (replayMode === "multi_turn") return;
32
+ logger.warn(`conversationReplay was provided for agent '${params.agent.name}', but model replayMode is '${replayMode}', so stored history replay customization was skipped.`);
33
+ };
34
+ const buildPersistence = (persistence, defaults) => {
35
+ const resolved = {
36
+ stream: persistence?.stream ?? defaults?.stream,
37
+ conversations: persistence?.conversations ?? defaults?.conversations,
38
+ runtimeState: persistence?.runtimeState ?? defaults?.runtimeState
39
+ };
40
+ return resolved.stream || resolved.conversations || resolved.runtimeState ? resolved : void 0;
41
+ };
42
+ const createPluginEventContext = (params) => ({
43
+ runId: params.runId,
44
+ agentName: params.agentName,
45
+ conversationId: params.conversationId,
46
+ control: { abortRun: async () => {
47
+ params.abortController.abort();
48
+ } }
49
+ });
50
+ const createLiveEmitter = (params) => {
51
+ const userEmit = toEventEmitter(params.onEvent);
52
+ return async (event) => {
53
+ const pluginEventContext = createPluginEventContext({
54
+ runId: params.runId,
55
+ agentName: params.agentName,
56
+ abortController: params.abortController,
57
+ conversationId: params.conversationId
58
+ });
59
+ const transformed = pluginRuntime?.hasEventMiddleware === true ? await pluginRuntime.dispatchEvent(event, pluginEventContext) : event;
60
+ if (!transformed) return;
61
+ if (params.persistenceEmit) await params.persistenceEmit(transformed);
62
+ if (pluginRuntime?.hasOnEvent) await pluginRuntime.dispatchOnEvent(transformed, pluginEventContext);
63
+ if (params.queuePush) await params.queuePush(transformed);
64
+ await userEmit(transformed);
65
+ };
66
+ };
67
+ const wrapRuntimeError = (params) => BetterAgentError.wrap({
68
+ err: params.error,
69
+ message: params.message,
70
+ opts: {
71
+ code: params.isAbort ? "ABORTED" : params.error instanceof BetterAgentError ? params.error.code : "INTERNAL",
72
+ trace: [{ at: params.traceAt }]
73
+ }
74
+ });
75
+ const emitSafely = async (emit, event) => {
76
+ try {
77
+ await emit(event);
78
+ } catch (error) {
79
+ logger.error("Failed to emit runtime event.", error);
80
+ }
81
+ };
82
+ const closeStreamSafely = async (streamStore, runId) => {
83
+ if (!streamStore) return;
84
+ try {
85
+ await streamStore.close(runId);
86
+ } catch (error) {
87
+ logger.error(`Failed to close stream '${runId}'.`, error);
88
+ }
89
+ };
90
+ const createRuntimeExecutionContext = (params) => {
91
+ const runId = generateId("run");
92
+ const abortController = new AbortController();
93
+ activeRuns.set(runId, abortController);
94
+ const signalController = new AbortController();
95
+ const abortFromSignal = (signal) => {
96
+ if (!signalController.signal.aborted) signalController.abort(signal.reason);
97
+ };
98
+ const onInternalAbort = () => abortFromSignal(abortController.signal);
99
+ const onExternalAbort = () => {
100
+ if (params.externalSignal) abortFromSignal(params.externalSignal);
101
+ };
102
+ const signal = signalController.signal;
103
+ const persistenceEmit = params.streamStore ? createStreamPersistenceEmitter({
104
+ stream: params.streamStore,
105
+ streamId: runId
106
+ }) : void 0;
107
+ const emit = createLiveEmitter({
108
+ runId,
109
+ agentName: params.resolvedAgent.name,
110
+ abortController,
111
+ conversationId: params.conversationId,
112
+ persistenceEmit,
113
+ queuePush: params.queue ? async (event) => {
114
+ if (!params.queueSignal?.aborted) params.queue?.push(event);
115
+ } : void 0,
116
+ onEvent: params.onEvent
117
+ });
118
+ abortController.signal.addEventListener("abort", onInternalAbort, { once: true });
119
+ if (params.externalSignal && !params.detachFromExternalAbort) if (params.externalSignal.aborted) abortFromSignal(params.externalSignal);
120
+ else params.externalSignal.addEventListener("abort", onExternalAbort, { once: true });
121
+ if (params.queue && params.queueSignal) {
122
+ const closeQueueOnAbort = () => params.queue?.close();
123
+ if (params.queueSignal.aborted) closeQueueOnAbort();
124
+ else params.queueSignal.addEventListener("abort", closeQueueOnAbort, { once: true });
125
+ }
126
+ return {
127
+ runId,
128
+ signal,
129
+ emit,
130
+ cleanupSignal() {
131
+ abortController.signal.removeEventListener("abort", onInternalAbort);
132
+ params.externalSignal?.removeEventListener("abort", onExternalAbort);
133
+ }
134
+ };
135
+ };
136
+ const completeRunSuccess = async (params) => {
137
+ const itemsToSave = pluginRuntime?.hasOnBeforeSave === true ? await pluginRuntime.applyBeforeSave({
138
+ runId: params.runId,
139
+ agentName: params.resolvedAgent.name,
140
+ items: params.result.items,
141
+ conversationId: params.conversationId
142
+ }) : params.result.items;
143
+ if (params.saveConversationParams) await saveConversationMessages({
144
+ ...params.saveConversationParams,
145
+ result: {
146
+ ...params.result,
147
+ items: itemsToSave
148
+ }
149
+ });
150
+ const publicResult = {
151
+ response: params.result.response,
152
+ structured: params.result.structured
153
+ };
154
+ await params.emit({
155
+ type: Events.RUN_FINISHED,
156
+ runId: params.runId,
157
+ agentName: params.resolvedAgent.name,
158
+ result: publicResult,
159
+ timestamp: Date.now(),
160
+ conversationId: params.conversationId
161
+ });
162
+ activeRuns.delete(params.runId);
163
+ if (params.runtimeState && params.conversationId !== void 0) await params.runtimeState.clear({
164
+ conversationId: params.conversationId,
165
+ agentName: params.resolvedAgent.name
166
+ });
167
+ await closeStreamSafely(params.streamStore, params.runId);
168
+ params.queue?.close();
169
+ pendingToolRuntime.clearRun(params.runId, "Run finished");
170
+ return params.success(publicResult);
171
+ };
172
+ const handleRunFailure = async (params) => {
173
+ const isAbort = params.signal.aborted || params.error instanceof BetterAgentError && params.error.code === "ABORTED";
174
+ const wrapped = wrapRuntimeError({
175
+ error: params.error,
176
+ message: "Run failed",
177
+ traceAt: params.traceAt,
178
+ isAbort
179
+ });
180
+ if (isAbort) await emitSafely(params.emit, {
181
+ type: Events.RUN_ABORTED,
182
+ runId: params.runId,
183
+ agentName: params.resolvedAgent.name,
184
+ timestamp: Date.now(),
185
+ conversationId: params.conversationId
186
+ });
187
+ else await emitSafely(params.emit, {
188
+ type: Events.RUN_ERROR,
189
+ runId: params.runId,
190
+ agentName: params.resolvedAgent.name,
191
+ error: wrapped,
192
+ timestamp: Date.now(),
193
+ conversationId: params.conversationId
194
+ });
195
+ activeRuns.delete(params.runId);
196
+ if (params.runtimeState && params.conversationId !== void 0) await params.runtimeState.clear({
197
+ conversationId: params.conversationId,
198
+ agentName: params.resolvedAgent.name
199
+ });
200
+ await closeStreamSafely(params.streamStore, params.runId);
201
+ params.queue?.fail(wrapped);
202
+ pendingToolRuntime.clearRun(params.runId, wrapped.message);
203
+ throw wrapped;
204
+ };
205
+ return {
206
+ streamLifecycle,
207
+ run: (async (agent, runOptions) => {
208
+ const resolvedAgent = resolveAgentFromRegistry(agents, agent, "core.run.createRuntime.run");
209
+ if (runOptions.conversationId !== void 0 && runOptions.conversationId.trim().length === 0) throw BetterAgentError.fromCode("VALIDATION_FAILED", "conversationId must be a non-empty string.", {
210
+ context: { conversationId: runOptions.conversationId },
211
+ trace: [{ at: "core.run.createRuntime.run.validateConversationId" }]
212
+ });
213
+ const execution = createRuntimeExecutionContext({
214
+ resolvedAgent,
215
+ conversationId: runOptions.conversationId,
216
+ onEvent: runOptions.onEvent,
217
+ externalSignal: runOptions.signal
218
+ });
219
+ const resolvedPersistence = buildPersistence(runOptions.persistence, {
220
+ stream: options.stream,
221
+ conversations: options.conversations,
222
+ runtimeState: options.runtimeState
223
+ });
224
+ try {
225
+ const effectiveConversationReplay = resolveConversationReplay(resolvedAgent, runOptions.conversationReplay);
226
+ warnIgnoredConversationReplay({
227
+ agent: resolvedAgent,
228
+ conversationReplay: effectiveConversationReplay
229
+ });
230
+ const validatedContext = await validateAgentContext(resolvedAgent, runOptions.context);
231
+ const resolvedConversations = runOptions.persistence?.conversations ?? options.conversations;
232
+ const conversationInput = await loadConversationMessages({
233
+ input: runOptions.input,
234
+ caps: resolvedAgent.model.caps,
235
+ agentName: resolvedAgent.name,
236
+ replaceHistory: runOptions.replaceHistory,
237
+ conversationReplay: effectiveConversationReplay,
238
+ conversations: resolvedConversations,
239
+ conversationId: runOptions.conversationId
240
+ });
241
+ await execution.emit({
242
+ type: Events.RUN_STARTED,
243
+ runId: execution.runId,
244
+ agentName: resolvedAgent.name,
245
+ runInput: {
246
+ input: runOptions.input,
247
+ context: validatedContext
248
+ },
249
+ timestamp: Date.now(),
250
+ conversationId: runOptions.conversationId
251
+ });
252
+ if (execution.signal.aborted) throw BetterAgentError.fromCode("ABORTED", "Run aborted before it started", {
253
+ context: {
254
+ runId: execution.runId,
255
+ agentName: resolvedAgent.name
256
+ },
257
+ trace: [{ at: "core.run.createRuntime.run.abortedBeforeStart" }]
258
+ });
259
+ const result = await executeRun({
260
+ agent: resolvedAgent,
261
+ options: {
262
+ ...runOptions,
263
+ input: conversationInput.input,
264
+ initialItems: conversationInput.items,
265
+ replayStartIndex: conversationInput.replayStartIndex,
266
+ conversationReplayActive: conversationInput.conversationReplayActive,
267
+ conversationReplay: effectiveConversationReplay,
268
+ context: validatedContext,
269
+ runId: execution.runId,
270
+ signal: execution.signal,
271
+ emit: execution.emit,
272
+ generateMessageId: () => generateId("message"),
273
+ mode: "run",
274
+ advancedDefaults: options.advanced,
275
+ persistence: resolvedPersistence,
276
+ pendingToolRuntime,
277
+ pluginRuntime
278
+ }
279
+ });
280
+ return await completeRunSuccess({
281
+ runId: execution.runId,
282
+ resolvedAgent,
283
+ emit: execution.emit,
284
+ result,
285
+ saveConversationParams: {
286
+ agentName: resolvedAgent.name,
287
+ loaded: conversationInput.loaded,
288
+ conversations: resolvedConversations,
289
+ conversationId: runOptions.conversationId
290
+ },
291
+ runtimeState: resolvedPersistence?.runtimeState,
292
+ conversationId: runOptions.conversationId,
293
+ success: (publicResult) => publicResult
294
+ });
295
+ } catch (error) {
296
+ return await handleRunFailure({
297
+ error,
298
+ signal: execution.signal,
299
+ traceAt: "core.run.createRuntime.run",
300
+ emit: execution.emit,
301
+ runId: execution.runId,
302
+ resolvedAgent,
303
+ conversationId: runOptions.conversationId,
304
+ runtimeState: resolvedPersistence?.runtimeState
305
+ });
306
+ } finally {
307
+ execution.cleanupSignal();
308
+ }
309
+ }),
310
+ stream: ((agent, runOptions) => {
311
+ const resolvedAgent = resolveAgentFromRegistry(agents, agent, "core.run.createRuntime.stream");
312
+ if (runOptions.conversationId !== void 0 && runOptions.conversationId.trim().length === 0) throw BetterAgentError.fromCode("VALIDATION_FAILED", "conversationId must be a non-empty string.", {
313
+ context: { conversationId: runOptions.conversationId },
314
+ trace: [{ at: "core.run.createRuntime.stream.validateConversationId" }]
315
+ });
316
+ const queue = createAsyncEventQueue();
317
+ const runPersistence = runOptions.persistence;
318
+ const streamStore = runPersistence?.stream ?? options.stream;
319
+ const execution = createRuntimeExecutionContext({
320
+ resolvedAgent,
321
+ conversationId: runOptions.conversationId,
322
+ onEvent: runOptions.onEvent,
323
+ externalSignal: runOptions.signal,
324
+ detachFromExternalAbort: streamLifecycle === "detached",
325
+ queueSignal: streamLifecycle === "detached" ? runOptions.signal : void 0,
326
+ streamStore,
327
+ queue
328
+ });
329
+ const resolvedPersistence = buildPersistence(runPersistence, {
330
+ stream: streamStore,
331
+ conversations: options.conversations,
332
+ runtimeState: options.runtimeState
333
+ });
334
+ const result = (async () => {
335
+ try {
336
+ const effectiveConversationReplay = resolveConversationReplay(resolvedAgent, runOptions.conversationReplay);
337
+ warnIgnoredConversationReplay({
338
+ agent: resolvedAgent,
339
+ conversationReplay: effectiveConversationReplay
340
+ });
341
+ const validatedContext = await validateAgentContext(resolvedAgent, runOptions.context);
342
+ const resolvedConversations = runPersistence?.conversations ?? options.conversations;
343
+ const conversationInput = await loadConversationMessages({
344
+ input: runOptions.input,
345
+ caps: resolvedAgent.model.caps,
346
+ agentName: resolvedAgent.name,
347
+ replaceHistory: runOptions.replaceHistory,
348
+ conversationReplay: effectiveConversationReplay,
349
+ conversations: resolvedConversations,
350
+ conversationId: runOptions.conversationId
351
+ });
352
+ if (streamStore) await streamStore.open(execution.runId, { runId: execution.runId });
353
+ if (resolvedPersistence?.runtimeState && runOptions.conversationId !== void 0) await resolvedPersistence.runtimeState.set({
354
+ conversationId: runOptions.conversationId,
355
+ agentName: resolvedAgent.name,
356
+ status: "running",
357
+ updatedAt: Date.now(),
358
+ activeRunId: execution.runId,
359
+ activeStreamId: streamStore ? execution.runId : void 0
360
+ });
361
+ await execution.emit({
362
+ type: Events.RUN_STARTED,
363
+ runId: execution.runId,
364
+ agentName: resolvedAgent.name,
365
+ runInput: {
366
+ input: runOptions.input,
367
+ context: validatedContext
368
+ },
369
+ timestamp: Date.now(),
370
+ conversationId: runOptions.conversationId
371
+ });
372
+ if (execution.signal.aborted) throw BetterAgentError.fromCode("ABORTED", "Run aborted before it started", {
373
+ context: {
374
+ runId: execution.runId,
375
+ agentName: resolvedAgent.name
376
+ },
377
+ trace: [{ at: "core.run.createRuntime.stream.abortedBeforeStart" }]
378
+ });
379
+ const runResult = await executeRun({
380
+ agent: resolvedAgent,
381
+ options: {
382
+ ...runOptions,
383
+ input: conversationInput.input,
384
+ initialItems: conversationInput.items,
385
+ replayStartIndex: conversationInput.replayStartIndex,
386
+ conversationReplayActive: conversationInput.conversationReplayActive,
387
+ conversationReplay: effectiveConversationReplay,
388
+ context: validatedContext,
389
+ runId: execution.runId,
390
+ signal: execution.signal,
391
+ emit: execution.emit,
392
+ generateMessageId: () => generateId("message"),
393
+ mode: "stream",
394
+ advancedDefaults: options.advanced,
395
+ persistence: resolvedPersistence,
396
+ pendingToolRuntime,
397
+ pluginRuntime
398
+ }
399
+ });
400
+ return await completeRunSuccess({
401
+ runId: execution.runId,
402
+ resolvedAgent,
403
+ emit: execution.emit,
404
+ result: runResult,
405
+ streamStore,
406
+ queue,
407
+ saveConversationParams: {
408
+ agentName: resolvedAgent.name,
409
+ loaded: conversationInput.loaded,
410
+ conversations: resolvedConversations,
411
+ conversationId: runOptions.conversationId
412
+ },
413
+ runtimeState: resolvedPersistence?.runtimeState,
414
+ conversationId: runOptions.conversationId,
415
+ success: (publicResult) => publicResult
416
+ });
417
+ } catch (error) {
418
+ return await handleRunFailure({
419
+ error,
420
+ signal: execution.signal,
421
+ traceAt: "core.run.createRuntime.stream",
422
+ emit: execution.emit,
423
+ runId: execution.runId,
424
+ resolvedAgent,
425
+ conversationId: runOptions.conversationId,
426
+ streamStore,
427
+ runtimeState: resolvedPersistence?.runtimeState,
428
+ queue
429
+ });
430
+ } finally {
431
+ execution.cleanupSignal();
432
+ }
433
+ })();
434
+ result.catch(() => {});
435
+ return {
436
+ runId: execution.runId,
437
+ events: queue.iterate(),
438
+ result
439
+ };
440
+ }),
441
+ loadConversation: async (agent, conversationId) => {
442
+ if (conversationId.trim().length === 0) throw BetterAgentError.fromCode("VALIDATION_FAILED", "conversationId must be a non-empty string.", {
443
+ context: { conversationId },
444
+ trace: [{ at: "core.run.createRuntime.loadConversation.validateConversationId" }]
445
+ });
446
+ const resolvedAgent = resolveAgentFromRegistry(agents, agent, "core.run.createRuntime.loadConversation");
447
+ const conversations = options.conversations;
448
+ if (!conversations) return null;
449
+ const loaded = await conversations.load({
450
+ conversationId,
451
+ agentName: resolvedAgent.name
452
+ });
453
+ if (!loaded) return null;
454
+ validateStoredConversationItems(loaded.items, conversationId);
455
+ return { items: loaded.items };
456
+ },
457
+ resumeStream: async (params) => {
458
+ if (params.streamId.trim().length === 0) throw BetterAgentError.fromCode("VALIDATION_FAILED", "streamId must be a non-empty string.", {
459
+ context: { streamId: params.streamId },
460
+ trace: [{ at: "core.run.createRuntime.resumeStream.validateStreamId" }]
461
+ });
462
+ if (!options.stream) return null;
463
+ return options.stream.resume(params.streamId, params.afterSeq);
464
+ },
465
+ resumeConversation: async (agent, params) => {
466
+ if (params.conversationId.trim().length === 0) throw BetterAgentError.fromCode("VALIDATION_FAILED", "conversationId must be a non-empty string.", {
467
+ context: { conversationId: params.conversationId },
468
+ trace: [{ at: "core.run.createRuntime.resumeConversation.validateConversationId" }]
469
+ });
470
+ const resolvedAgent = resolveAgentFromRegistry(agents, agent, "core.run.createRuntime.resumeConversation");
471
+ const state = !options.runtimeState ? null : await options.runtimeState.get({
472
+ conversationId: params.conversationId,
473
+ agentName: resolvedAgent.name
474
+ });
475
+ if (!state || state.status !== "running" || !state.activeStreamId || !options.stream) return null;
476
+ return options.stream.resume(state.activeStreamId, params.afterSeq);
477
+ },
478
+ abortRun: async (runId) => {
479
+ const controller = activeRuns.get(runId);
480
+ if (!controller) return false;
481
+ controller.abort();
482
+ return true;
483
+ },
484
+ submitToolResult: async (params) => pendingToolRuntime.submitToolResult(params),
485
+ submitToolApproval: async (params) => pendingToolRuntime.submitToolApproval(params)
486
+ };
487
+ }
488
+
489
+ //#endregion
490
+ export { createRuntime };
491
+ //# sourceMappingURL=runtime.mjs.map