@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.
- package/README.md +3 -0
- package/dist/agent/constants.mjs +6 -0
- package/dist/agent/constants.mjs.map +1 -0
- package/dist/agent/define-agent.d.mts +29 -0
- package/dist/agent/define-agent.d.mts.map +1 -0
- package/dist/agent/define-agent.mjs +27 -0
- package/dist/agent/define-agent.mjs.map +1 -0
- package/dist/agent/index.d.mts +2 -0
- package/dist/agent/types.d.mts +216 -0
- package/dist/agent/types.d.mts.map +1 -0
- package/dist/agent/validation.mjs +64 -0
- package/dist/agent/validation.mjs.map +1 -0
- package/dist/api.d.mts +8 -0
- package/dist/api.d.mts.map +1 -0
- package/dist/api.mjs +63 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app/config.mjs +43 -0
- package/dist/app/config.mjs.map +1 -0
- package/dist/app/create-app.d.mts +36 -0
- package/dist/app/create-app.d.mts.map +1 -0
- package/dist/app/create-app.mjs +132 -0
- package/dist/app/create-app.mjs.map +1 -0
- package/dist/app/registry.mjs +43 -0
- package/dist/app/registry.mjs.map +1 -0
- package/dist/app/types.d.mts +142 -0
- package/dist/app/types.d.mts.map +1 -0
- package/dist/events/constants.d.mts +49 -0
- package/dist/events/constants.d.mts.map +1 -0
- package/dist/events/constants.mjs +46 -0
- package/dist/events/constants.mjs.map +1 -0
- package/dist/events/index.d.mts +4 -0
- package/dist/events/index.mjs +3 -0
- package/dist/events/types.d.mts +289 -0
- package/dist/events/types.d.mts.map +1 -0
- package/dist/index.d.mts +23 -0
- package/dist/index.mjs +14 -0
- package/dist/internal/id.mjs +21 -0
- package/dist/internal/id.mjs.map +1 -0
- package/dist/internal/types.d.mts +11 -0
- package/dist/internal/types.d.mts.map +1 -0
- package/dist/mcp/error/mcp-client-error.d.mts +36 -0
- package/dist/mcp/error/mcp-client-error.d.mts.map +1 -0
- package/dist/mcp/error/mcp-client-error.mjs +33 -0
- package/dist/mcp/error/mcp-client-error.mjs.map +1 -0
- package/dist/mcp/index.d.mts +8 -0
- package/dist/mcp/index.mjs +9 -0
- package/dist/mcp/tool/json-rpc-message.d.mts +50 -0
- package/dist/mcp/tool/json-rpc-message.d.mts.map +1 -0
- package/dist/mcp/tool/json-rpc-message.mjs +84 -0
- package/dist/mcp/tool/json-rpc-message.mjs.map +1 -0
- package/dist/mcp/tool/mcp-client.d.mts +71 -0
- package/dist/mcp/tool/mcp-client.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-client.mjs +304 -0
- package/dist/mcp/tool/mcp-client.mjs.map +1 -0
- package/dist/mcp/tool/mcp-http-transport.d.mts +62 -0
- package/dist/mcp/tool/mcp-http-transport.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-http-transport.mjs +307 -0
- package/dist/mcp/tool/mcp-http-transport.mjs.map +1 -0
- package/dist/mcp/tool/mcp-tools.d.mts +20 -0
- package/dist/mcp/tool/mcp-tools.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-tools.mjs +73 -0
- package/dist/mcp/tool/mcp-tools.mjs.map +1 -0
- package/dist/mcp/tool/mcp-transport.d.mts +81 -0
- package/dist/mcp/tool/mcp-transport.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-transport.mjs +11 -0
- package/dist/mcp/tool/mcp-transport.mjs.map +1 -0
- package/dist/mcp/tool/types.d.mts +230 -0
- package/dist/mcp/tool/types.d.mts.map +1 -0
- package/dist/mcp/tool/types.mjs +19 -0
- package/dist/mcp/tool/types.mjs.map +1 -0
- package/dist/persistence/index.d.mts +3 -0
- package/dist/persistence/index.mjs +3 -0
- package/dist/persistence/memory.d.mts +21 -0
- package/dist/persistence/memory.d.mts.map +1 -0
- package/dist/persistence/memory.mjs +107 -0
- package/dist/persistence/memory.mjs.map +1 -0
- package/dist/persistence/types.d.mts +124 -0
- package/dist/persistence/types.d.mts.map +1 -0
- package/dist/plugins/index.d.mts +2 -0
- package/dist/plugins/runtime.d.mts +17 -0
- package/dist/plugins/runtime.d.mts.map +1 -0
- package/dist/plugins/runtime.mjs +456 -0
- package/dist/plugins/runtime.mjs.map +1 -0
- package/dist/plugins/types.d.mts +344 -0
- package/dist/plugins/types.d.mts.map +1 -0
- package/dist/providers/index.d.mts +9 -0
- package/dist/providers/index.mjs +0 -0
- package/dist/providers/types/capabilities.d.mts +153 -0
- package/dist/providers/types/capabilities.d.mts.map +1 -0
- package/dist/providers/types/content.d.mts +125 -0
- package/dist/providers/types/content.d.mts.map +1 -0
- package/dist/providers/types/conversation.d.mts +32 -0
- package/dist/providers/types/conversation.d.mts.map +1 -0
- package/dist/providers/types/index.d.mts +8 -0
- package/dist/providers/types/input.d.mts +74 -0
- package/dist/providers/types/input.d.mts.map +1 -0
- package/dist/providers/types/model.d.mts +68 -0
- package/dist/providers/types/model.d.mts.map +1 -0
- package/dist/providers/types/output.d.mts +29 -0
- package/dist/providers/types/output.d.mts.map +1 -0
- package/dist/providers/types/response.d.mts +35 -0
- package/dist/providers/types/response.d.mts.map +1 -0
- package/dist/providers/types/tool-calls.d.mts +51 -0
- package/dist/providers/types/tool-calls.d.mts.map +1 -0
- package/dist/run/agent-loop.mjs +231 -0
- package/dist/run/agent-loop.mjs.map +1 -0
- package/dist/run/event-queue.mjs +67 -0
- package/dist/run/event-queue.mjs.map +1 -0
- package/dist/run/execute-tool-calls.mjs +550 -0
- package/dist/run/execute-tool-calls.mjs.map +1 -0
- package/dist/run/execution.mjs +93 -0
- package/dist/run/execution.mjs.map +1 -0
- package/dist/run/helpers.mjs +466 -0
- package/dist/run/helpers.mjs.map +1 -0
- package/dist/run/hooks.mjs +124 -0
- package/dist/run/hooks.mjs.map +1 -0
- package/dist/run/index.d.mts +4 -0
- package/dist/run/messages.d.mts +8 -0
- package/dist/run/messages.d.mts.map +1 -0
- package/dist/run/messages.mjs +83 -0
- package/dist/run/messages.mjs.map +1 -0
- package/dist/run/model-strategy.mjs +105 -0
- package/dist/run/model-strategy.mjs.map +1 -0
- package/dist/run/output-errors.d.mts +75 -0
- package/dist/run/output-errors.d.mts.map +1 -0
- package/dist/run/pending-tools.d.mts +1 -0
- package/dist/run/pending-tools.mjs +185 -0
- package/dist/run/pending-tools.mjs.map +1 -0
- package/dist/run/registry.mjs +22 -0
- package/dist/run/registry.mjs.map +1 -0
- package/dist/run/runtime.d.mts +19 -0
- package/dist/run/runtime.d.mts.map +1 -0
- package/dist/run/runtime.mjs +491 -0
- package/dist/run/runtime.mjs.map +1 -0
- package/dist/run/stop-conditions.mjs +41 -0
- package/dist/run/stop-conditions.mjs.map +1 -0
- package/dist/run/types.d.mts +348 -0
- package/dist/run/types.d.mts.map +1 -0
- package/dist/schema/index.d.mts +2 -0
- package/dist/schema/resolve-json-schema.d.mts +12 -0
- package/dist/schema/resolve-json-schema.d.mts.map +1 -0
- package/dist/schema/resolve-json-schema.mjs +167 -0
- package/dist/schema/resolve-json-schema.mjs.map +1 -0
- package/dist/schema/types.d.mts +27 -0
- package/dist/schema/types.d.mts.map +1 -0
- package/dist/server/create-server.d.mts +21 -0
- package/dist/server/create-server.d.mts.map +1 -0
- package/dist/server/create-server.mjs +107 -0
- package/dist/server/create-server.mjs.map +1 -0
- package/dist/server/http.mjs +182 -0
- package/dist/server/http.mjs.map +1 -0
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.mjs +3 -0
- package/dist/server/routes.mjs +399 -0
- package/dist/server/routes.mjs.map +1 -0
- package/dist/server/types.d.mts +31 -0
- package/dist/server/types.d.mts.map +1 -0
- package/dist/tools/constants.d.mts +12 -0
- package/dist/tools/constants.d.mts.map +1 -0
- package/dist/tools/constants.mjs +13 -0
- package/dist/tools/constants.mjs.map +1 -0
- package/dist/tools/define-tool.d.mts +25 -0
- package/dist/tools/define-tool.d.mts.map +1 -0
- package/dist/tools/define-tool.mjs +76 -0
- package/dist/tools/define-tool.mjs.map +1 -0
- package/dist/tools/index.d.mts +5 -0
- package/dist/tools/lazy-tools.d.mts +49 -0
- package/dist/tools/lazy-tools.d.mts.map +1 -0
- package/dist/tools/lazy-tools.mjs +87 -0
- package/dist/tools/lazy-tools.mjs.map +1 -0
- package/dist/tools/resolve-tools.d.mts +12 -0
- package/dist/tools/resolve-tools.d.mts.map +1 -0
- package/dist/tools/resolve-tools.mjs +86 -0
- package/dist/tools/resolve-tools.mjs.map +1 -0
- package/dist/tools/types.d.mts +318 -0
- package/dist/tools/types.d.mts.map +1 -0
- package/dist/tools/validation.mjs +23 -0
- package/dist/tools/validation.mjs.map +1 -0
- 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
|