@minpeter/pss-runtime 0.1.0-next.0 → 0.1.0-next.2
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 +223 -191
- package/dist/agent-child-runs.js +16 -0
- package/dist/agent-child-runs.js.map +1 -0
- package/dist/agent-host-capabilities.js +9 -0
- package/dist/agent-host-capabilities.js.map +1 -0
- package/dist/agent-host-session-store.js +12 -0
- package/dist/agent-host-session-store.js.map +1 -0
- package/dist/agent-loop.js +59 -35
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-namespace.js +24 -0
- package/dist/agent-namespace.js.map +1 -0
- package/dist/agent-options.d.ts +35 -0
- package/dist/agent-options.js +16 -0
- package/dist/agent-options.js.map +1 -0
- package/dist/agent-resume.js +143 -0
- package/dist/agent-resume.js.map +1 -0
- package/dist/agent-session-entry.d.ts +13 -0
- package/dist/agent-validation.js +35 -0
- package/dist/agent-validation.js.map +1 -0
- package/dist/agent.d.ts +8 -33
- package/dist/agent.js +131 -55
- package/dist/agent.js.map +1 -1
- package/dist/child-session-cleanups.js +61 -0
- package/dist/child-session-cleanups.js.map +1 -0
- package/dist/execution/host.js +14 -0
- package/dist/execution/host.js.map +1 -0
- package/dist/execution/index.d.ts +4 -0
- package/dist/execution/index.js +3 -0
- package/dist/execution/memory-notifications.js +54 -0
- package/dist/execution/memory-notifications.js.map +1 -0
- package/dist/execution/memory-state.js +34 -0
- package/dist/execution/memory-state.js.map +1 -0
- package/dist/execution/memory-store.js +203 -0
- package/dist/execution/memory-store.js.map +1 -0
- package/dist/execution/memory.d.ts +7 -0
- package/dist/execution/memory.js +28 -0
- package/dist/execution/memory.js.map +1 -0
- package/dist/execution/run.js +55 -0
- package/dist/execution/run.js.map +1 -0
- package/dist/execution/types.d.ts +155 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +1 -6
- package/dist/llm-tool-execution.d.ts +35 -0
- package/dist/llm-tool-execution.js +126 -0
- package/dist/llm-tool-execution.js.map +1 -0
- package/dist/llm.d.ts +11 -15
- package/dist/llm.js +5 -9
- package/dist/llm.js.map +1 -1
- package/dist/plugins.d.ts +20 -0
- package/dist/plugins.js +14 -0
- package/dist/plugins.js.map +1 -0
- package/dist/session/events.d.ts +26 -20
- package/dist/session/input-normalization.js +66 -0
- package/dist/session/input-normalization.js.map +1 -0
- package/dist/session/input.d.ts +0 -4
- package/dist/session/mapping.js +1 -2
- package/dist/session/mapping.js.map +1 -1
- package/dist/session/run.js +1 -0
- package/dist/session/run.js.map +1 -1
- package/dist/session/runtime-input.js +20 -58
- package/dist/session/runtime-input.js.map +1 -1
- package/dist/session/session-errors.js +18 -0
- package/dist/session/session-errors.js.map +1 -0
- package/dist/session/session-events.js +59 -0
- package/dist/session/session-events.js.map +1 -0
- package/dist/session/session-execution.js +88 -0
- package/dist/session/session-execution.js.map +1 -0
- package/dist/session/session-kill.js +23 -0
- package/dist/session/session-kill.js.map +1 -0
- package/dist/session/session-notification.js +58 -0
- package/dist/session/session-notification.js.map +1 -0
- package/dist/session/session-runtime-drain.js +22 -0
- package/dist/session/session-runtime-drain.js.map +1 -0
- package/dist/session/session-state.js +102 -0
- package/dist/session/session-state.js.map +1 -0
- package/dist/session/session-turn-error.js +35 -0
- package/dist/session/session-turn-error.js.map +1 -0
- package/dist/session/session-turn-processor.js +135 -0
- package/dist/session/session-turn-processor.js.map +1 -0
- package/dist/session/session.js +125 -335
- package/dist/session/session.js.map +1 -1
- package/dist/session/snapshot.js +5 -31
- package/dist/session/snapshot.js.map +1 -1
- package/dist/session/store/file.d.ts +1 -0
- package/dist/session/store/file.js +14 -0
- package/dist/session/store/file.js.map +1 -1
- package/dist/session/store/memory.d.ts +1 -0
- package/dist/session/store/memory.js +5 -0
- package/dist/session/store/memory.js.map +1 -1
- package/dist/session/store/types.d.ts +1 -0
- package/dist/subagent-background-child-run-state.js +51 -0
- package/dist/subagent-background-child-run-state.js.map +1 -0
- package/dist/subagent-background-child-run.js +103 -0
- package/dist/subagent-background-child-run.js.map +1 -0
- package/dist/subagent-background-in-process.js +98 -0
- package/dist/subagent-background-in-process.js.map +1 -0
- package/dist/subagent-background-notification-inbox.js +106 -0
- package/dist/subagent-background-notification-inbox.js.map +1 -0
- package/dist/subagent-background-notify.js +136 -0
- package/dist/subagent-background-notify.js.map +1 -0
- package/dist/subagent-background-resume-group.js +99 -0
- package/dist/subagent-background-resume-group.js.map +1 -0
- package/dist/subagent-background-runner.js +115 -0
- package/dist/subagent-background-runner.js.map +1 -0
- package/dist/subagent-background-schedule.js +43 -0
- package/dist/subagent-background-schedule.js.map +1 -0
- package/dist/subagent-child-run.js +68 -0
- package/dist/subagent-child-run.js.map +1 -0
- package/dist/subagent-job-cancel.js +84 -0
- package/dist/subagent-job-cancel.js.map +1 -0
- package/dist/subagent-job-observer.js +19 -0
- package/dist/subagent-job-observer.js.map +1 -0
- package/dist/subagent-job-output.js +87 -0
- package/dist/subagent-job-output.js.map +1 -0
- package/dist/subagent-job-state.js +66 -0
- package/dist/subagent-job-state.js.map +1 -0
- package/dist/subagent-jobs.js +96 -0
- package/dist/subagent-jobs.js.map +1 -0
- package/dist/subagent-prompt-schema.js +114 -0
- package/dist/subagent-prompt-schema.js.map +1 -0
- package/dist/subagent-run.js +111 -0
- package/dist/subagent-run.js.map +1 -0
- package/dist/subagents.js +125 -0
- package/dist/subagents.js.map +1 -0
- package/package.json +11 -6
- package/dist/plugins/compaction.d.ts +0 -15
- package/dist/plugins/compaction.js +0 -98
- package/dist/plugins/compaction.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -5
- package/dist/plugins/index.js +0 -5
- package/dist/plugins/memory.d.ts +0 -11
- package/dist/plugins/memory.js +0 -146
- package/dist/plugins/memory.js.map +0 -1
- package/dist/plugins/runner.d.ts +0 -1
- package/dist/plugins/runner.js +0 -83
- package/dist/plugins/runner.js.map +0 -1
- package/dist/plugins/scope.js +0 -13
- package/dist/plugins/scope.js.map +0 -1
- package/dist/plugins/sessions.d.ts +0 -12
- package/dist/plugins/sessions.js +0 -34
- package/dist/plugins/sessions.js.map +0 -1
- package/dist/plugins/tool-hook-handlers.js +0 -77
- package/dist/plugins/tool-hook-handlers.js.map +0 -1
- package/dist/plugins/tool-hook-results.js +0 -64
- package/dist/plugins/tool-hook-results.js.map +0 -1
- package/dist/plugins/tool-hooks.js +0 -111
- package/dist/plugins/tool-hooks.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -105
- package/dist/plugins/types.js +0 -20
- package/dist/plugins/types.js.map +0 -1
- package/dist/session/lifecycle.d.ts +0 -12
- package/dist/session/lifecycle.js +0 -126
- package/dist/session/lifecycle.js.map +0 -1
- package/dist/session/overlay-anchor.js +0 -151
- package/dist/session/overlay-anchor.js.map +0 -1
- package/dist/session/overlay.js +0 -141
- package/dist/session/overlay.js.map +0 -1
- package/dist/session/snapshot.d.ts +0 -1
- /package/dist/{agent-loop.d.ts → session/history.d.ts} +0 -0
- /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
- /package/dist/{plugins/scope.d.ts → session/session-state.d.ts} +0 -0
package/dist/agent.js
CHANGED
|
@@ -1,81 +1,157 @@
|
|
|
1
|
+
import { executionHost } from "./execution/host.js";
|
|
2
|
+
import { cancelDurableChildRuns } from "./agent-child-runs.js";
|
|
3
|
+
import { supportsBackgroundSubagents } from "./agent-host-capabilities.js";
|
|
4
|
+
import { sessionStoreForHost } from "./agent-host-session-store.js";
|
|
5
|
+
import { parentSessionNamespace, stableAgentNamespace } from "./agent-namespace.js";
|
|
6
|
+
import { assertAgentOptions, hasRuntimeModel } from "./agent-options.js";
|
|
7
|
+
import { resumeAgentRun } from "./agent-resume.js";
|
|
8
|
+
import { assertSubagents } from "./agent-validation.js";
|
|
9
|
+
import { ChildSessionCleanups } from "./child-session-cleanups.js";
|
|
10
|
+
import { createInMemoryExecutionHost } from "./execution/memory.js";
|
|
1
11
|
import { createLlm } from "./llm.js";
|
|
2
|
-
import { resolveAgentPlugins } from "./plugins/runner.js";
|
|
3
12
|
import { AgentSession } from "./session/session.js";
|
|
4
|
-
import {
|
|
13
|
+
import { createSubagentTools } from "./subagents.js";
|
|
5
14
|
//#region src/agent.ts
|
|
6
15
|
var Agent = class Agent {
|
|
7
|
-
#
|
|
16
|
+
#baseTools;
|
|
8
17
|
#llm;
|
|
9
|
-
#
|
|
10
|
-
#
|
|
18
|
+
#modelOptions;
|
|
19
|
+
#childSessionCleanups = new ChildSessionCleanups();
|
|
20
|
+
#sessionGenerations = /* @__PURE__ */ new Map();
|
|
11
21
|
#sessions = /* @__PURE__ */ new Map();
|
|
22
|
+
#sessionNamespace;
|
|
12
23
|
#store;
|
|
13
|
-
|
|
24
|
+
#host;
|
|
25
|
+
#plugins;
|
|
26
|
+
#subagents;
|
|
27
|
+
description;
|
|
28
|
+
name;
|
|
29
|
+
constructor(options) {
|
|
14
30
|
assertAgentOptions(options);
|
|
15
|
-
this
|
|
16
|
-
this
|
|
17
|
-
this.#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
this.description = options.description;
|
|
32
|
+
this.name = options.name;
|
|
33
|
+
this.#sessionNamespace = stableAgentNamespace({
|
|
34
|
+
name: options.name,
|
|
35
|
+
namespace: options.namespace
|
|
36
|
+
});
|
|
37
|
+
this.#host = options.host ?? createInMemoryExecutionHost();
|
|
38
|
+
this.#store = sessionStoreForHost(this.#host);
|
|
39
|
+
this.#plugins = options.plugins ?? [];
|
|
40
|
+
assertSubagents(options, Agent, hasRuntimeModel(options));
|
|
41
|
+
this.#subagents = hasRuntimeModel(options) ? [] : options.subagents ?? [];
|
|
42
|
+
if (hasRuntimeModel(options)) this.#llm = options.model;
|
|
43
|
+
else {
|
|
44
|
+
this.#baseTools = options.tools;
|
|
45
|
+
this.#modelOptions = {
|
|
27
46
|
instructions: options.instructions,
|
|
28
47
|
model: options.model,
|
|
29
|
-
toolChoice: options.toolChoice
|
|
30
|
-
|
|
31
|
-
});
|
|
48
|
+
toolChoice: options.toolChoice
|
|
49
|
+
};
|
|
32
50
|
}
|
|
33
51
|
}
|
|
34
|
-
static async create(options) {
|
|
35
|
-
assertAgentOptions(options);
|
|
36
|
-
return new Agent(options, await resolveAgentPlugins({
|
|
37
|
-
callerTools: hasCustomLlm(options) ? void 0 : options.tools,
|
|
38
|
-
plugins: options.plugins
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
52
|
send(input) {
|
|
42
53
|
return this.session("default").send(input);
|
|
43
54
|
}
|
|
55
|
+
async resume(runId) {
|
|
56
|
+
const host = executionHost(this.#host);
|
|
57
|
+
if (!host) throw new Error("Agent host does not support durable run resume.");
|
|
58
|
+
return await resumeAgentRun({
|
|
59
|
+
host,
|
|
60
|
+
ownerNamespace: this.#sessionNamespace,
|
|
61
|
+
resumeNotification: (notification) => this.#resumeNotification(notification),
|
|
62
|
+
runId,
|
|
63
|
+
subagents: this.#subagents
|
|
64
|
+
});
|
|
65
|
+
}
|
|
44
66
|
session(key) {
|
|
67
|
+
return this.#sessionEntry(key).publicHandle;
|
|
68
|
+
}
|
|
69
|
+
#sessionEntry(key) {
|
|
45
70
|
const existing = this.#sessions.get(key);
|
|
46
71
|
if (existing) return existing;
|
|
47
|
-
|
|
72
|
+
let session;
|
|
73
|
+
const getSession = () => {
|
|
74
|
+
if (!session) throw new Error("Agent session is not initialized.");
|
|
75
|
+
return session;
|
|
76
|
+
};
|
|
77
|
+
const parentAgentNamespace = parentSessionNamespace({
|
|
78
|
+
generation: this.#sessionGenerations.get(key) ?? 0,
|
|
79
|
+
sessionKey: key,
|
|
80
|
+
sessionNamespace: this.#sessionNamespace
|
|
81
|
+
});
|
|
82
|
+
session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event), (input, options) => getSession().notify(input, options), () => getSession().currentTurnId(), () => parentAgentNamespace)), {
|
|
48
83
|
key,
|
|
49
84
|
store: this.#store
|
|
50
|
-
}, this.#plugins,
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
85
|
+
}, this.#plugins, { executionHost: executionHost(this.#host) });
|
|
86
|
+
const entry = {
|
|
87
|
+
notify: (input, options) => session.notify(input, options),
|
|
88
|
+
publicHandle: {
|
|
89
|
+
delete: async () => {
|
|
90
|
+
session.kill();
|
|
91
|
+
await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
|
|
92
|
+
this.#evictSessionHandle(key);
|
|
93
|
+
await session.delete();
|
|
94
|
+
await this.#childSessionCleanups.delete(key);
|
|
95
|
+
},
|
|
96
|
+
interrupt: () => session.interrupt(),
|
|
97
|
+
kill: async () => {
|
|
98
|
+
session.kill();
|
|
99
|
+
await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
|
|
100
|
+
this.#evictSessionHandle(key);
|
|
101
|
+
await this.#childSessionCleanups.delete(key);
|
|
102
|
+
},
|
|
103
|
+
send: (input) => session.send(input),
|
|
104
|
+
steer: (input) => session.steer(input)
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
this.#sessions.set(key, entry);
|
|
108
|
+
return entry;
|
|
109
|
+
}
|
|
110
|
+
async #cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace) {
|
|
111
|
+
try {
|
|
112
|
+
await cancelDurableChildRuns(this.#host, parentAgentNamespace);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
this.#evictSessionHandle(key);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
#evictSessionHandle(key) {
|
|
119
|
+
this.#sessions.delete(key);
|
|
120
|
+
this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
|
|
121
|
+
}
|
|
122
|
+
#resumeNotification(notification) {
|
|
123
|
+
return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
|
|
124
|
+
}
|
|
125
|
+
#createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent, notify, currentBackgroundGroupId, currentRunId) {
|
|
126
|
+
const modelOptions = this.#modelOptions;
|
|
127
|
+
if (!modelOptions) throw new Error("Agent: missing model options.");
|
|
128
|
+
const hostExecution = executionHost(this.#host);
|
|
129
|
+
const tools = this.#subagents.length === 0 ? this.#baseTools : {
|
|
130
|
+
...this.#baseTools,
|
|
131
|
+
...createSubagentTools({
|
|
132
|
+
backgroundSubagents: supportsBackgroundSubagents(this.#host, hostExecution),
|
|
133
|
+
executionHost: hostExecution,
|
|
134
|
+
parentAgentNamespace,
|
|
135
|
+
parentSession: {
|
|
136
|
+
currentBackgroundGroupId,
|
|
137
|
+
currentRunId,
|
|
138
|
+
emitObserverEvent,
|
|
139
|
+
enqueueRuntimeInput,
|
|
140
|
+
notify
|
|
141
|
+
},
|
|
142
|
+
parentSessionKey: key,
|
|
143
|
+
registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
|
|
144
|
+
subagents: this.#subagents
|
|
145
|
+
})
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
instructions: modelOptions.instructions,
|
|
149
|
+
model: modelOptions.model,
|
|
150
|
+
toolChoice: modelOptions.toolChoice,
|
|
151
|
+
tools
|
|
60
152
|
};
|
|
61
|
-
this.#sessions.set(key, handle);
|
|
62
|
-
return handle;
|
|
63
153
|
}
|
|
64
154
|
};
|
|
65
|
-
function assertAgentOptions(options) {
|
|
66
|
-
if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide either { model } or { llm }.");
|
|
67
|
-
if ("sessions" in options) throw new TypeError("Agent.create: options.sessions was removed. Use plugins: [sessions.custom(store)].");
|
|
68
|
-
if ("hooks" in options) throw new TypeError("Agent.create: options.hooks was removed. Use run.events() with session.steer() for app control or plugin lifecycle handlers for middleware.");
|
|
69
|
-
const hasLlm = hasCustomLlm(options);
|
|
70
|
-
const hasModel = "model" in options && options.model !== void 0 && options.model !== null;
|
|
71
|
-
if (hasLlm && hasModel) throw new TypeError("Agent.create: provide either options.llm or options.model, not both.");
|
|
72
|
-
if ("llm" in options && options.llm !== void 0 && !hasLlm) throw new TypeError("Agent.create: invalid options.llm.");
|
|
73
|
-
if ("onPluginError" in options && options.onPluginError !== void 0 && typeof options.onPluginError !== "function") throw new TypeError("Agent.create: invalid options.onPluginError.");
|
|
74
|
-
if (!(hasLlm || hasModel)) throw new TypeError("Agent.create: missing options.model.");
|
|
75
|
-
}
|
|
76
|
-
function hasCustomLlm(options) {
|
|
77
|
-
return "llm" in options && typeof options.llm === "function";
|
|
78
|
-
}
|
|
79
155
|
//#endregion
|
|
80
156
|
export { Agent };
|
|
81
157
|
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","names":["#internalLlm","#llm","#onPluginError","#plugins","#sessions","#store"],"sources":["../src/agent.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport { type AgentToolChoice, createLlm, type Llm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport {\n type ResolvedAgentPlugins,\n resolveAgentPlugins,\n} from \"./plugins/runner\";\nimport type { AgentPluginErrorHandler } from \"./session/lifecycle\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport { MemorySessionStore } from \"./session/store/memory\";\nimport type { SessionStore } from \"./session/store/types\";\n\ninterface AgentLanguageModelOptions {\n instructions?: string;\n llm?: never;\n model: LanguageModel;\n onPluginError?: AgentPluginErrorHandler;\n plugins?: readonly AgentPlugin[];\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\ninterface AgentLlmOptions {\n instructions?: never;\n llm: Llm;\n model?: never;\n onPluginError?: AgentPluginErrorHandler;\n plugins?: readonly AgentPlugin[];\n toolChoice?: never;\n tools?: never;\n}\n\nexport interface SessionHandle {\n interrupt(): void;\n kill(): void;\n overlay(input: AgentInput): Promise<AgentRun>;\n send(input: AgentInput): Promise<AgentRun>;\n steer(input: AgentInput): Promise<AgentRun>;\n}\n\nexport type AgentOptions = AgentLanguageModelOptions | AgentLlmOptions;\n\nexport class Agent {\n readonly #internalLlm: Llm;\n readonly #llm: Llm;\n readonly #onPluginError?: AgentPluginErrorHandler;\n readonly #plugins: ResolvedAgentPlugins;\n readonly #sessions = new Map<string, SessionHandle>();\n readonly #store: SessionStore;\n\n private constructor(\n options: AgentOptions,\n resolvedPlugins: ResolvedAgentPlugins\n ) {\n assertAgentOptions(options);\n\n this.#plugins = resolvedPlugins;\n this.#onPluginError = options.onPluginError;\n this.#store =\n resolvedPlugins.sessionStore?.store ?? new MemorySessionStore();\n if (hasCustomLlm(options)) {\n this.#internalLlm = options.llm;\n this.#llm = options.llm;\n } else {\n this.#internalLlm = createLlm({\n instructions: options.instructions,\n model: options.model,\n });\n this.#llm = createLlm({\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n tools: resolvedPlugins.tools,\n });\n }\n }\n\n static async create(options: AgentOptions): Promise<Agent> {\n assertAgentOptions(options);\n const resolvedPlugins = await resolveAgentPlugins({\n callerTools: hasCustomLlm(options) ? undefined : options.tools,\n plugins: options.plugins,\n });\n return new Agent(options, resolvedPlugins);\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n session(key: string): SessionHandle {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n const session = new AgentSession(\n this.#llm,\n { key, store: this.#store },\n this.#plugins,\n this.#internalLlm,\n this.#onPluginError\n );\n const handle: SessionHandle = {\n interrupt: () => session.interrupt(),\n kill: () => {\n session.kill();\n this.#sessions.delete(key);\n },\n overlay: (input) => session.overlay(input),\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n this.#sessions.set(key, handle);\n return handle;\n }\n}\n\nfunction assertAgentOptions(options: unknown): asserts options is AgentOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\n \"Agent options are required. Provide either { model } or { llm }.\"\n );\n }\n\n if (\"sessions\" in options) {\n throw new TypeError(\n \"Agent.create: options.sessions was removed. Use plugins: [sessions.custom(store)].\"\n );\n }\n\n if (\"hooks\" in options) {\n throw new TypeError(\n \"Agent.create: options.hooks was removed. Use run.events() with session.steer() for app control or plugin lifecycle handlers for middleware.\"\n );\n }\n\n const hasLlm = hasCustomLlm(options);\n const hasModel =\n \"model\" in options && options.model !== undefined && options.model !== null;\n\n if (hasLlm && hasModel) {\n throw new TypeError(\n \"Agent.create: provide either options.llm or options.model, not both.\"\n );\n }\n\n if (\"llm\" in options && options.llm !== undefined && !hasLlm) {\n throw new TypeError(\"Agent.create: invalid options.llm.\");\n }\n\n if (\n \"onPluginError\" in options &&\n options.onPluginError !== undefined &&\n typeof options.onPluginError !== \"function\"\n ) {\n throw new TypeError(\"Agent.create: invalid options.onPluginError.\");\n }\n\n if (!(hasLlm || hasModel)) {\n throw new TypeError(\"Agent.create: missing options.model.\");\n }\n}\n\nfunction hasCustomLlm(options: object): options is AgentLlmOptions {\n return \"llm\" in options && typeof options.llm === \"function\";\n}\n"],"mappings":";;;;;AA2CA,IAAa,QAAb,MAAa,MAAM;CACjB;CACA;CACA;CACA;CACA,4BAAqB,IAAI,IAA2B;CACpD;CAEA,YACE,SACA,iBACA;EACA,mBAAmB,OAAO;EAE1B,KAAKG,WAAW;EAChB,KAAKD,iBAAiB,QAAQ;EAC9B,KAAKG,SACH,gBAAgB,cAAc,SAAS,IAAI,mBAAmB;EAChE,IAAI,aAAa,OAAO,GAAG;GACzB,KAAKL,eAAe,QAAQ;GAC5B,KAAKC,OAAO,QAAQ;EACtB,OAAO;GACL,KAAKD,eAAe,UAAU;IAC5B,cAAc,QAAQ;IACtB,OAAO,QAAQ;GACjB,CAAC;GACD,KAAKC,OAAO,UAAU;IACpB,cAAc,QAAQ;IACtB,OAAO,QAAQ;IACf,YAAY,QAAQ;IACpB,OAAO,gBAAgB;GACzB,CAAC;EACH;CACF;CAEA,aAAa,OAAO,SAAuC;EACzD,mBAAmB,OAAO;EAK1B,OAAO,IAAI,MAAM,SAAS,MAJI,oBAAoB;GAChD,aAAa,aAAa,OAAO,IAAI,KAAA,IAAY,QAAQ;GACzD,SAAS,QAAQ;EACnB,CAAC,CACwC;CAC3C;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,QAAQ,KAA4B;EAClC,MAAM,WAAW,KAAKG,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,MAAM,UAAU,IAAI,aAClB,KAAKH,MACL;GAAE;GAAK,OAAO,KAAKI;EAAO,GAC1B,KAAKF,UACL,KAAKH,cACL,KAAKE,cACP;EACA,MAAM,SAAwB;GAC5B,iBAAiB,QAAQ,UAAU;GACnC,YAAY;IACV,QAAQ,KAAK;IACb,KAAKE,UAAU,OAAO,GAAG;GAC3B;GACA,UAAU,UAAU,QAAQ,QAAQ,KAAK;GACzC,OAAO,UAAU,QAAQ,KAAK,KAAK;GACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;EACvC;EACA,KAAKA,UAAU,IAAI,KAAK,MAAM;EAC9B,OAAO;CACT;AACF;AAEA,SAAS,mBAAmB,SAAmD;CAC7E,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UACR,kEACF;CAGF,IAAI,cAAc,SAChB,MAAM,IAAI,UACR,oFACF;CAGF,IAAI,WAAW,SACb,MAAM,IAAI,UACR,6IACF;CAGF,MAAM,SAAS,aAAa,OAAO;CACnC,MAAM,WACJ,WAAW,WAAW,QAAQ,UAAU,KAAA,KAAa,QAAQ,UAAU;CAEzE,IAAI,UAAU,UACZ,MAAM,IAAI,UACR,sEACF;CAGF,IAAI,SAAS,WAAW,QAAQ,QAAQ,KAAA,KAAa,CAAC,QACpD,MAAM,IAAI,UAAU,oCAAoC;CAG1D,IACE,mBAAmB,WACnB,QAAQ,kBAAkB,KAAA,KAC1B,OAAO,QAAQ,kBAAkB,YAEjC,MAAM,IAAI,UAAU,8CAA8C;CAGpE,IAAI,EAAE,UAAU,WACd,MAAM,IAAI,UAAU,sCAAsC;AAE9D;AAEA,SAAS,aAAa,SAA6C;CACjE,OAAO,SAAS,WAAW,OAAO,QAAQ,QAAQ;AACpD"}
|
|
1
|
+
{"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#host","#plugins","#subagents","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#cancelDurableChildRunsBeforeLocalCleanup","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { cancelDurableChildRuns } from \"./agent-child-runs\";\nimport { supportsBackgroundSubagents } from \"./agent-host-capabilities\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport {\n parentSessionNamespace,\n stableAgentNamespace,\n} from \"./agent-namespace\";\nimport {\n type AgentModelOptions,\n type AgentOptions,\n assertAgentOptions,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport {\n type AgentInput,\n AgentSession,\n type NotifyOptions,\n} from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly #subagents: readonly Agent[];\n readonly description?: string;\n readonly name?: string;\n\n constructor(options: AgentOptions) {\n assertAgentOptions(options);\n\n this.description = options.description;\n this.name = options.name;\n this.#sessionNamespace = stableAgentNamespace({\n name: options.name,\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n assertSubagents(options, Agent, hasRuntimeModel(options));\n this.#subagents = hasRuntimeModel(options) ? [] : (options.subagents ?? []);\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n subagents: this.#subagents,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const getSession = () => {\n if (!session) {\n throw new Error(\"Agent session is not initialized.\");\n }\n return session;\n };\n const parentAgentNamespace = parentSessionNamespace({\n generation: this.#sessionGenerations.get(key) ?? 0,\n sessionKey: key,\n sessionNamespace: this.#sessionNamespace,\n });\n const llm =\n this.#llm ??\n createLlm(\n this.#createLlmOptionsForSession(\n key,\n parentAgentNamespace,\n (input: UserInput, placement?: \"turn-start\") =>\n getSession().enqueueRuntimeInput(input, placement),\n (event) => getSession().emitObserverEvent(event),\n (input: UserInput, options?: NotifyOptions) =>\n getSession().notify(input, options),\n () => getSession().currentTurnId(),\n () => parentAgentNamespace\n )\n );\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await session.delete();\n await this.#childSessionCleanups.delete(key);\n },\n interrupt: () => session.interrupt(),\n kill: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await this.#childSessionCleanups.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n async #cancelDurableChildRunsBeforeLocalCleanup(\n key: string,\n parentAgentNamespace: string\n ): Promise<void> {\n try {\n await cancelDurableChildRuns(this.#host, parentAgentNamespace);\n } catch (error) {\n this.#evictSessionHandle(key);\n throw error;\n }\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"],\n notify: (input: UserInput, options?: NotifyOptions) => Promise<AgentRun>,\n currentBackgroundGroupId: () => string | undefined,\n currentRunId: () => string | undefined\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const hostExecution = executionHost(this.#host);\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n backgroundSubagents: supportsBackgroundSubagents(\n this.#host,\n hostExecution\n ),\n executionHost: hostExecution,\n parentAgentNamespace,\n parentSession: {\n currentBackgroundGroupId,\n currentRunId,\n emitObserverEvent,\n enqueueRuntimeInput,\n notify,\n },\n parentSessionKey: key,\n registerChildSession: (sessionKey, cleanup) =>\n this.#childSessionCleanups.register(sessionKey, cleanup),\n subagents: this.#subagents,\n }),\n };\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/child-session-cleanups.ts
|
|
2
|
+
var ChildSessionCleanups = class {
|
|
3
|
+
#byParentSession = /* @__PURE__ */ new Map();
|
|
4
|
+
async delete(parentSessionKey) {
|
|
5
|
+
const cleanups = this.#byParentSession.get(parentSessionKey);
|
|
6
|
+
if (!cleanups) return;
|
|
7
|
+
this.#byParentSession.delete(parentSessionKey);
|
|
8
|
+
const results = await Promise.all([...cleanups].map(runCleanup));
|
|
9
|
+
const failedCleanups = [];
|
|
10
|
+
let firstError;
|
|
11
|
+
for (const result of results) {
|
|
12
|
+
if (result.ok) continue;
|
|
13
|
+
firstError ??= result.error;
|
|
14
|
+
failedCleanups.push(result.cleanup);
|
|
15
|
+
}
|
|
16
|
+
if (failedCleanups.length === 0) return;
|
|
17
|
+
this.#restore(parentSessionKey, failedCleanups);
|
|
18
|
+
throw firstError instanceof Error ? firstError : new Error(String(firstError));
|
|
19
|
+
}
|
|
20
|
+
register(parentSessionKey, cleanup) {
|
|
21
|
+
const existing = this.#byParentSession.get(parentSessionKey);
|
|
22
|
+
if (existing) {
|
|
23
|
+
existing.add(cleanup);
|
|
24
|
+
return () => this.#unregister(parentSessionKey, existing, cleanup);
|
|
25
|
+
}
|
|
26
|
+
const cleanups = new Set([cleanup]);
|
|
27
|
+
this.#byParentSession.set(parentSessionKey, cleanups);
|
|
28
|
+
return () => this.#unregister(parentSessionKey, cleanups, cleanup);
|
|
29
|
+
}
|
|
30
|
+
#unregister(parentSessionKey, cleanups, cleanup) {
|
|
31
|
+
cleanups.delete(cleanup);
|
|
32
|
+
if (cleanups.size === 0 && this.#byParentSession.get(parentSessionKey) === cleanups) this.#byParentSession.delete(parentSessionKey);
|
|
33
|
+
}
|
|
34
|
+
#restore(parentSessionKey, failedCleanups) {
|
|
35
|
+
const current = this.#byParentSession.get(parentSessionKey);
|
|
36
|
+
if (current) {
|
|
37
|
+
for (const cleanup of failedCleanups) current.add(cleanup);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
async function runCleanup(cleanup) {
|
|
44
|
+
try {
|
|
45
|
+
await cleanup();
|
|
46
|
+
return {
|
|
47
|
+
cleanup,
|
|
48
|
+
ok: true
|
|
49
|
+
};
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
cleanup,
|
|
53
|
+
error,
|
|
54
|
+
ok: false
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { ChildSessionCleanups };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=child-session-cleanups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-session-cleanups.js","names":["#byParentSession","#restore","#unregister"],"sources":["../src/child-session-cleanups.ts"],"sourcesContent":["type ChildSessionCleanup = () => Promise<void>;\n\ntype CleanupResult =\n | { readonly cleanup: ChildSessionCleanup; readonly ok: true }\n | {\n readonly cleanup: ChildSessionCleanup;\n readonly error: unknown;\n readonly ok: false;\n };\n\nexport class ChildSessionCleanups {\n readonly #byParentSession = new Map<string, Set<ChildSessionCleanup>>();\n\n async delete(parentSessionKey: string): Promise<void> {\n const cleanups = this.#byParentSession.get(parentSessionKey);\n if (!cleanups) {\n return;\n }\n\n this.#byParentSession.delete(parentSessionKey);\n const results = await Promise.all([...cleanups].map(runCleanup));\n const failedCleanups: ChildSessionCleanup[] = [];\n let firstError: unknown;\n for (const result of results) {\n if (result.ok) {\n continue;\n }\n\n firstError ??= result.error;\n failedCleanups.push(result.cleanup);\n }\n\n if (failedCleanups.length === 0) {\n return;\n }\n\n this.#restore(parentSessionKey, failedCleanups);\n throw firstError instanceof Error\n ? firstError\n : new Error(String(firstError));\n }\n\n register(parentSessionKey: string, cleanup: ChildSessionCleanup): () => void {\n const existing = this.#byParentSession.get(parentSessionKey);\n if (existing) {\n existing.add(cleanup);\n return () => this.#unregister(parentSessionKey, existing, cleanup);\n }\n\n const cleanups = new Set([cleanup]);\n this.#byParentSession.set(parentSessionKey, cleanups);\n return () => this.#unregister(parentSessionKey, cleanups, cleanup);\n }\n\n #unregister(\n parentSessionKey: string,\n cleanups: Set<ChildSessionCleanup>,\n cleanup: ChildSessionCleanup\n ): void {\n cleanups.delete(cleanup);\n if (\n cleanups.size === 0 &&\n this.#byParentSession.get(parentSessionKey) === cleanups\n ) {\n this.#byParentSession.delete(parentSessionKey);\n }\n }\n\n #restore(\n parentSessionKey: string,\n failedCleanups: readonly ChildSessionCleanup[]\n ): void {\n const current = this.#byParentSession.get(parentSessionKey);\n if (current) {\n for (const cleanup of failedCleanups) {\n current.add(cleanup);\n }\n return;\n }\n\n this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));\n }\n}\n\nasync function runCleanup(\n cleanup: ChildSessionCleanup\n): Promise<CleanupResult> {\n try {\n await cleanup();\n return { cleanup, ok: true };\n } catch (error) {\n return { cleanup, error, ok: false };\n }\n}\n"],"mappings":";AAUA,IAAa,uBAAb,MAAkC;CAChC,mCAA4B,IAAI,IAAsC;CAEtE,MAAM,OAAO,kBAAyC;EACpD,MAAM,WAAW,KAAKA,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,CAAC,UACH;EAGF,KAAKA,iBAAiB,OAAO,gBAAgB;EAC7C,MAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,GAAG,QAAQ,EAAE,IAAI,UAAU,CAAC;EAC/D,MAAM,iBAAwC,CAAC;EAC/C,IAAI;EACJ,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,OAAO,IACT;GAGF,eAAe,OAAO;GACtB,eAAe,KAAK,OAAO,OAAO;EACpC;EAEA,IAAI,eAAe,WAAW,GAC5B;EAGF,KAAKC,SAAS,kBAAkB,cAAc;EAC9C,MAAM,sBAAsB,QACxB,aACA,IAAI,MAAM,OAAO,UAAU,CAAC;CAClC;CAEA,SAAS,kBAA0B,SAA0C;EAC3E,MAAM,WAAW,KAAKD,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,UAAU;GACZ,SAAS,IAAI,OAAO;GACpB,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;EACnE;EAEA,MAAM,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC;EAClC,KAAKF,iBAAiB,IAAI,kBAAkB,QAAQ;EACpD,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;CACnE;CAEA,YACE,kBACA,UACA,SACM;EACN,SAAS,OAAO,OAAO;EACvB,IACE,SAAS,SAAS,KAClB,KAAKF,iBAAiB,IAAI,gBAAgB,MAAM,UAEhD,KAAKA,iBAAiB,OAAO,gBAAgB;CAEjD;CAEA,SACE,kBACA,gBACM;EACN,MAAM,UAAU,KAAKA,iBAAiB,IAAI,gBAAgB;EAC1D,IAAI,SAAS;GACX,KAAK,MAAM,WAAW,gBACpB,QAAQ,IAAI,OAAO;GAErB;EACF;EAEA,KAAKA,iBAAiB,IAAI,kBAAkB,IAAI,IAAI,cAAc,CAAC;CACrE;AACF;AAEA,eAAe,WACb,SACwB;CACxB,IAAI;EACF,MAAM,QAAQ;EACd,OAAO;GAAE;GAAS,IAAI;EAAK;CAC7B,SAAS,OAAO;EACd,OAAO;GAAE;GAAS;GAAO,IAAI;EAAM;CACrC;AACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/execution/host.ts
|
|
2
|
+
function executionHost(host) {
|
|
3
|
+
if (isExecutionHost(host)) return host;
|
|
4
|
+
}
|
|
5
|
+
function isExecutionHost(host) {
|
|
6
|
+
return "scheduler" in host && "store" in host && isExecutionStore(host.store);
|
|
7
|
+
}
|
|
8
|
+
function isExecutionStore(store) {
|
|
9
|
+
return typeof store === "object" && store !== null && "checkpoints" in store && "events" in store && "notifications" in store && "runs" in store && "sessions" in store;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { executionHost };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","names":[],"sources":["../../src/execution/host.ts"],"sourcesContent":["import type { AgentHost, ExecutionHost } from \"./types\";\n\nexport function executionHost(host: AgentHost): ExecutionHost | undefined {\n if (isExecutionHost(host)) {\n return host;\n }\n\n return;\n}\n\nfunction isExecutionHost(host: AgentHost): host is ExecutionHost {\n return \"scheduler\" in host && \"store\" in host && isExecutionStore(host.store);\n}\n\nfunction isExecutionStore(store: unknown): store is ExecutionHost[\"store\"] {\n return (\n typeof store === \"object\" &&\n store !== null &&\n \"checkpoints\" in store &&\n \"events\" in store &&\n \"notifications\" in store &&\n \"runs\" in store &&\n \"sessions\" in store\n );\n}\n"],"mappings":";AAEA,SAAgB,cAAc,MAA4C;CACxE,IAAI,gBAAgB,IAAI,GACtB,OAAO;AAIX;AAEA,SAAS,gBAAgB,MAAwC;CAC/D,OAAO,eAAe,QAAQ,WAAW,QAAQ,iBAAiB,KAAK,KAAK;AAC9E;AAEA,SAAS,iBAAiB,OAAiD;CACzE,OACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,YAAY,SACZ,mBAAmB,SACnB,UAAU,SACV,cAAc;AAElB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RuntimeToolExecutionCheckpoint, RuntimeToolExecutionContext, RuntimeToolExecutionDecision, RuntimeToolRetryPolicy, ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
|
|
2
|
+
import { AgentHostCapabilities, CheckpointPhase, CheckpointStore, CheckpointWriteResult, ClaimRunOptions, ClaimRunResult, EventCursor, EventStore, ExecutionHost, ExecutionScheduler, ExecutionStore, ExecutionStoreTransaction, NotificationClaimResult, NotificationInbox, NotificationRecord, NotificationStatus, NotificationWriteResult, ResumeSessionOptions, RunCheckpoint, RunKind, RunLease, RunRecord, RunStatus, RunStore, StoredAgentEvent } from "./types.js";
|
|
3
|
+
import { createInMemoryExecutionHost } from "./memory.js";
|
|
4
|
+
export { type AgentHostCapabilities, type CheckpointPhase, type CheckpointStore, type CheckpointWriteResult, type ClaimRunOptions, type ClaimRunResult, type EventCursor, type EventStore, type ExecutionHost, type ExecutionScheduler, type ExecutionStore, type ExecutionStoreTransaction, type NotificationClaimResult, type NotificationInbox, type NotificationRecord, type NotificationStatus, type NotificationWriteResult, type ResumeSessionOptions, type RunCheckpoint, type RunKind, type RunLease, type RunRecord, type RunStatus, type RunStore, type RuntimeToolExecutionCheckpoint, type RuntimeToolExecutionContext, type RuntimeToolExecutionDecision, type RuntimeToolRetryPolicy, type StoredAgentEvent, ToolExecutionNeedsRecoveryError, createInMemoryExecutionHost };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/execution/memory-notifications.ts
|
|
2
|
+
var InMemoryNotificationInbox = class {
|
|
3
|
+
#state;
|
|
4
|
+
constructor(state) {
|
|
5
|
+
this.#state = state;
|
|
6
|
+
}
|
|
7
|
+
claimByIdempotencyKey(idempotencyKey) {
|
|
8
|
+
const record = this.#state().notificationsByKey.get(idempotencyKey);
|
|
9
|
+
if (!record) return Promise.resolve({
|
|
10
|
+
ok: false,
|
|
11
|
+
reason: "not-found"
|
|
12
|
+
});
|
|
13
|
+
if (record.status !== "pending") return Promise.resolve({
|
|
14
|
+
ok: false,
|
|
15
|
+
reason: "already-claimed",
|
|
16
|
+
record: structuredClone(record)
|
|
17
|
+
});
|
|
18
|
+
this.#state().notificationsByKey.set(idempotencyKey, {
|
|
19
|
+
...record,
|
|
20
|
+
status: "acked"
|
|
21
|
+
});
|
|
22
|
+
return Promise.resolve({
|
|
23
|
+
ok: true,
|
|
24
|
+
record: structuredClone(record)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
enqueue(record) {
|
|
28
|
+
const existing = this.#state().notificationsByKey.get(record.idempotencyKey);
|
|
29
|
+
if (existing) return Promise.resolve({
|
|
30
|
+
existingNotificationId: existing.notificationId,
|
|
31
|
+
ok: false,
|
|
32
|
+
reason: "duplicate"
|
|
33
|
+
});
|
|
34
|
+
this.#state().notificationsByKey.set(record.idempotencyKey, structuredClone(record));
|
|
35
|
+
return Promise.resolve({ ok: true });
|
|
36
|
+
}
|
|
37
|
+
getByIdempotencyKey(idempotencyKey) {
|
|
38
|
+
const record = this.#state().notificationsByKey.get(idempotencyKey);
|
|
39
|
+
return Promise.resolve(record ? structuredClone(record) : null);
|
|
40
|
+
}
|
|
41
|
+
releaseByIdempotencyKey(idempotencyKey) {
|
|
42
|
+
const record = this.#state().notificationsByKey.get(idempotencyKey);
|
|
43
|
+
if (record?.status !== "acked") return Promise.resolve();
|
|
44
|
+
this.#state().notificationsByKey.set(idempotencyKey, {
|
|
45
|
+
...record,
|
|
46
|
+
status: "pending"
|
|
47
|
+
});
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { InMemoryNotificationInbox };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=memory-notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-notifications.js","names":["#state"],"sources":["../../src/execution/memory-notifications.ts"],"sourcesContent":["import type { ExecutionState } from \"./memory-state\";\nimport type {\n NotificationClaimResult,\n NotificationInbox,\n NotificationRecord,\n NotificationWriteResult,\n} from \"./types\";\n\nexport class InMemoryNotificationInbox implements NotificationInbox {\n readonly #state: () => ExecutionState;\n\n constructor(state: () => ExecutionState) {\n this.#state = state;\n }\n\n claimByIdempotencyKey(\n idempotencyKey: string\n ): Promise<NotificationClaimResult> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n if (!record) {\n return Promise.resolve({ ok: false, reason: \"not-found\" });\n }\n\n if (record.status !== \"pending\") {\n return Promise.resolve({\n ok: false,\n reason: \"already-claimed\",\n record: structuredClone(record),\n });\n }\n\n this.#state().notificationsByKey.set(idempotencyKey, {\n ...record,\n status: \"acked\",\n });\n return Promise.resolve({\n ok: true,\n record: structuredClone(record),\n });\n }\n\n enqueue(record: NotificationRecord): Promise<NotificationWriteResult> {\n const existing = this.#state().notificationsByKey.get(\n record.idempotencyKey\n );\n if (existing) {\n return Promise.resolve({\n existingNotificationId: existing.notificationId,\n ok: false,\n reason: \"duplicate\",\n });\n }\n\n this.#state().notificationsByKey.set(\n record.idempotencyKey,\n structuredClone(record)\n );\n return Promise.resolve({ ok: true });\n }\n\n getByIdempotencyKey(\n idempotencyKey: string\n ): Promise<NotificationRecord | null> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n return Promise.resolve(record ? structuredClone(record) : null);\n }\n\n releaseByIdempotencyKey(idempotencyKey: string): Promise<void> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n if (record?.status !== \"acked\") {\n return Promise.resolve();\n }\n\n this.#state().notificationsByKey.set(idempotencyKey, {\n ...record,\n status: \"pending\",\n });\n return Promise.resolve();\n }\n}\n"],"mappings":";AAQA,IAAa,4BAAb,MAAoE;CAClE;CAEA,YAAY,OAA6B;EACvC,KAAKA,SAAS;CAChB;CAEA,sBACE,gBACkC;EAClC,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,IAAI,CAAC,QACH,OAAO,QAAQ,QAAQ;GAAE,IAAI;GAAO,QAAQ;EAAY,CAAC;EAG3D,IAAI,OAAO,WAAW,WACpB,OAAO,QAAQ,QAAQ;GACrB,IAAI;GACJ,QAAQ;GACR,QAAQ,gBAAgB,MAAM;EAChC,CAAC;EAGH,KAAKA,OAAO,EAAE,mBAAmB,IAAI,gBAAgB;GACnD,GAAG;GACH,QAAQ;EACV,CAAC;EACD,OAAO,QAAQ,QAAQ;GACrB,IAAI;GACJ,QAAQ,gBAAgB,MAAM;EAChC,CAAC;CACH;CAEA,QAAQ,QAA8D;EACpE,MAAM,WAAW,KAAKA,OAAO,EAAE,mBAAmB,IAChD,OAAO,cACT;EACA,IAAI,UACF,OAAO,QAAQ,QAAQ;GACrB,wBAAwB,SAAS;GACjC,IAAI;GACJ,QAAQ;EACV,CAAC;EAGH,KAAKA,OAAO,EAAE,mBAAmB,IAC/B,OAAO,gBACP,gBAAgB,MAAM,CACxB;EACA,OAAO,QAAQ,QAAQ,EAAE,IAAI,KAAK,CAAC;CACrC;CAEA,oBACE,gBACoC;EACpC,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,OAAO,QAAQ,QAAQ,SAAS,gBAAgB,MAAM,IAAI,IAAI;CAChE;CAEA,wBAAwB,gBAAuC;EAC7D,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,IAAI,QAAQ,WAAW,SACrB,OAAO,QAAQ,QAAQ;EAGzB,KAAKA,OAAO,EAAE,mBAAmB,IAAI,gBAAgB;GACnD,GAAG;GACH,QAAQ;EACV,CAAC;EACD,OAAO,QAAQ,QAAQ;CACzB;AACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/execution/memory-state.ts
|
|
2
|
+
function createEmptyState() {
|
|
3
|
+
return {
|
|
4
|
+
checkpoints: /* @__PURE__ */ new Map(),
|
|
5
|
+
events: /* @__PURE__ */ new Map(),
|
|
6
|
+
notificationsByKey: /* @__PURE__ */ new Map(),
|
|
7
|
+
runs: /* @__PURE__ */ new Map(),
|
|
8
|
+
sessionVersions: /* @__PURE__ */ new Map(),
|
|
9
|
+
sessions: /* @__PURE__ */ new Map()
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function cloneState(state) {
|
|
13
|
+
return {
|
|
14
|
+
checkpoints: cloneCheckpointMap(state.checkpoints),
|
|
15
|
+
events: cloneEventMap(state.events),
|
|
16
|
+
notificationsByKey: cloneRecordMap(state.notificationsByKey),
|
|
17
|
+
runs: cloneRecordMap(state.runs),
|
|
18
|
+
sessionVersions: cloneRecordMap(state.sessionVersions),
|
|
19
|
+
sessions: cloneRecordMap(state.sessions)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function cloneCheckpointMap(map) {
|
|
23
|
+
return new Map([...map.entries()].map(([key, value]) => [key, value.map((checkpoint) => structuredClone(checkpoint))]));
|
|
24
|
+
}
|
|
25
|
+
function cloneEventMap(map) {
|
|
26
|
+
return new Map([...map.entries()].map(([key, value]) => [key, value.map((event) => structuredClone(event))]));
|
|
27
|
+
}
|
|
28
|
+
function cloneRecordMap(map) {
|
|
29
|
+
return new Map([...map.entries()].map(([key, value]) => [key, structuredClone(value)]));
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { cloneState, createEmptyState };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=memory-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-state.js","names":[],"sources":["../../src/execution/memory-state.ts"],"sourcesContent":["import type { StoredSession } from \"../session/store/types\";\nimport type {\n NotificationRecord,\n RunCheckpoint,\n RunRecord,\n StoredAgentEvent,\n} from \"./types\";\n\nexport interface ExecutionState {\n readonly checkpoints: Map<string, RunCheckpoint[]>;\n readonly events: Map<string, StoredAgentEvent[]>;\n readonly notificationsByKey: Map<string, NotificationRecord>;\n readonly runs: Map<string, RunRecord>;\n readonly sessions: Map<string, StoredSession>;\n readonly sessionVersions: Map<string, number>;\n}\n\nexport function createEmptyState(): ExecutionState {\n return {\n checkpoints: new Map(),\n events: new Map(),\n notificationsByKey: new Map(),\n runs: new Map(),\n sessionVersions: new Map(),\n sessions: new Map(),\n };\n}\n\nexport function cloneState(state: ExecutionState): ExecutionState {\n return {\n checkpoints: cloneCheckpointMap(state.checkpoints),\n events: cloneEventMap(state.events),\n notificationsByKey: cloneRecordMap(state.notificationsByKey),\n runs: cloneRecordMap(state.runs),\n sessionVersions: cloneRecordMap(state.sessionVersions),\n sessions: cloneRecordMap(state.sessions),\n };\n}\n\nfunction cloneCheckpointMap(\n map: ReadonlyMap<string, readonly RunCheckpoint[]>\n): Map<string, RunCheckpoint[]> {\n return new Map(\n [...map.entries()].map(([key, value]) => [\n key,\n value.map((checkpoint) => structuredClone(checkpoint)),\n ])\n );\n}\n\nfunction cloneEventMap(\n map: ReadonlyMap<string, readonly StoredAgentEvent[]>\n): Map<string, StoredAgentEvent[]> {\n return new Map(\n [...map.entries()].map(([key, value]) => [\n key,\n value.map((event) => structuredClone(event)),\n ])\n );\n}\n\nfunction cloneRecordMap<T>(map: ReadonlyMap<string, T>): Map<string, T> {\n return new Map(\n [...map.entries()].map(([key, value]) => [key, structuredClone(value)])\n );\n}\n"],"mappings":";AAiBA,SAAgB,mBAAmC;CACjD,OAAO;EACL,6BAAa,IAAI,IAAI;EACrB,wBAAQ,IAAI,IAAI;EAChB,oCAAoB,IAAI,IAAI;EAC5B,sBAAM,IAAI,IAAI;EACd,iCAAiB,IAAI,IAAI;EACzB,0BAAU,IAAI,IAAI;CACpB;AACF;AAEA,SAAgB,WAAW,OAAuC;CAChE,OAAO;EACL,aAAa,mBAAmB,MAAM,WAAW;EACjD,QAAQ,cAAc,MAAM,MAAM;EAClC,oBAAoB,eAAe,MAAM,kBAAkB;EAC3D,MAAM,eAAe,MAAM,IAAI;EAC/B,iBAAiB,eAAe,MAAM,eAAe;EACrD,UAAU,eAAe,MAAM,QAAQ;CACzC;AACF;AAEA,SAAS,mBACP,KAC8B;CAC9B,OAAO,IAAI,IACT,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,KAAK,CAAC,KAAK,WAAW,CACvC,KACA,MAAM,KAAK,eAAe,gBAAgB,UAAU,CAAC,CACvD,CAAC,CACH;AACF;AAEA,SAAS,cACP,KACiC;CACjC,OAAO,IAAI,IACT,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,KAAK,CAAC,KAAK,WAAW,CACvC,KACA,MAAM,KAAK,UAAU,gBAAgB,KAAK,CAAC,CAC7C,CAAC,CACH;AACF;AAEA,SAAS,eAAkB,KAA6C;CACtE,OAAO,IAAI,IACT,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,gBAAgB,KAAK,CAAC,CAAC,CACxE;AACF"}
|