@eggjs/agent-runtime 0.0.0 → 3.73.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/LICENSE +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +31 -0
- package/dist/src/AgentRuntime.d.ts +42 -0
- package/dist/src/AgentRuntime.js +376 -0
- package/dist/src/AgentStore.d.ts +42 -0
- package/dist/src/AgentStore.js +3 -0
- package/dist/src/AgentStoreUtils.d.ts +4 -0
- package/dist/src/AgentStoreUtils.js +23 -0
- package/dist/src/FileAgentStore.d.ts +21 -0
- package/dist/src/FileAgentStore.js +104 -0
- package/dist/src/HttpSSEWriter.d.ts +16 -0
- package/dist/src/HttpSSEWriter.js +51 -0
- package/dist/src/MessageConverter.d.ts +32 -0
- package/dist/src/MessageConverter.js +108 -0
- package/dist/src/OSSAgentStore.d.ts +62 -0
- package/dist/src/OSSAgentStore.js +165 -0
- package/dist/src/OSSObjectStorageClient.d.ts +46 -0
- package/dist/src/OSSObjectStorageClient.js +90 -0
- package/dist/src/RunBuilder.d.ts +43 -0
- package/dist/src/RunBuilder.js +127 -0
- package/dist/src/SSEWriter.d.ts +14 -0
- package/dist/src/SSEWriter.js +3 -0
- package/dist/src/agentDefaults.d.ts +1 -0
- package/dist/src/agentDefaults.js +447 -0
- package/dist/src/enhanceAgentController.d.ts +2 -0
- package/dist/src/enhanceAgentController.js +90 -0
- package/package.json +32 -13
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from '@eggjs/tegg-types/agent-runtime';
|
|
2
|
+
export * from './src/OSSObjectStorageClient';
|
|
3
|
+
export * from './src/OSSAgentStore';
|
|
4
|
+
export * from './src/AgentStoreUtils';
|
|
5
|
+
export * from './src/MessageConverter';
|
|
6
|
+
export * from './src/RunBuilder';
|
|
7
|
+
export * from './src/SSEWriter';
|
|
8
|
+
export * from './src/HttpSSEWriter';
|
|
9
|
+
export { AgentRuntime, AGENT_RUNTIME } from './src/AgentRuntime';
|
|
10
|
+
export type { AgentExecutor, AgentRuntimeOptions } from './src/AgentRuntime';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.AGENT_RUNTIME = exports.AgentRuntime = void 0;
|
|
18
|
+
// Re-export types from @eggjs/tegg-types (backward compatible)
|
|
19
|
+
__exportStar(require("@eggjs/tegg-types/agent-runtime"), exports);
|
|
20
|
+
// Implementation code
|
|
21
|
+
__exportStar(require("./src/OSSObjectStorageClient"), exports);
|
|
22
|
+
__exportStar(require("./src/OSSAgentStore"), exports);
|
|
23
|
+
__exportStar(require("./src/AgentStoreUtils"), exports);
|
|
24
|
+
__exportStar(require("./src/MessageConverter"), exports);
|
|
25
|
+
__exportStar(require("./src/RunBuilder"), exports);
|
|
26
|
+
__exportStar(require("./src/SSEWriter"), exports);
|
|
27
|
+
__exportStar(require("./src/HttpSSEWriter"), exports);
|
|
28
|
+
var AgentRuntime_1 = require("./src/AgentRuntime");
|
|
29
|
+
Object.defineProperty(exports, "AgentRuntime", { enumerable: true, get: function () { return AgentRuntime_1.AgentRuntime; } });
|
|
30
|
+
Object.defineProperty(exports, "AGENT_RUNTIME", { enumerable: true, get: function () { return AgentRuntime_1.AGENT_RUNTIME; } });
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtEQUErRDtBQUMvRCxrRUFBZ0Q7QUFDaEQsc0JBQXNCO0FBQ3RCLCtEQUE2QztBQUM3QyxzREFBb0M7QUFDcEMsd0RBQXNDO0FBQ3RDLHlEQUF1QztBQUN2QyxtREFBaUM7QUFDakMsa0RBQWdDO0FBQ2hDLHNEQUFvQztBQUNwQyxtREFBaUU7QUFBeEQsNEdBQUEsWUFBWSxPQUFBO0FBQUUsNkdBQUEsYUFBYSxPQUFBIn0=
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CreateRunInput, ThreadObject, ThreadObjectWithMessages, RunObject, AgentStreamMessage, AgentStore } from '@eggjs/tegg-types/agent-runtime';
|
|
2
|
+
import type { EggLogger } from 'egg-logger';
|
|
3
|
+
import type { SSEWriter } from './SSEWriter';
|
|
4
|
+
export declare const AGENT_RUNTIME: unique symbol;
|
|
5
|
+
/**
|
|
6
|
+
* The executor interface — only requires execRun so the runtime can delegate
|
|
7
|
+
* execution back through the controller's prototype chain (AOP/mock friendly).
|
|
8
|
+
*/
|
|
9
|
+
export interface AgentExecutor {
|
|
10
|
+
execRun(input: CreateRunInput, signal?: AbortSignal): AsyncGenerator<AgentStreamMessage>;
|
|
11
|
+
}
|
|
12
|
+
export interface AgentRuntimeOptions {
|
|
13
|
+
executor: AgentExecutor;
|
|
14
|
+
store: AgentStore;
|
|
15
|
+
logger: EggLogger;
|
|
16
|
+
}
|
|
17
|
+
export declare class AgentRuntime {
|
|
18
|
+
private static readonly TERMINAL_RUN_STATUSES;
|
|
19
|
+
private store;
|
|
20
|
+
private runningTasks;
|
|
21
|
+
private executor;
|
|
22
|
+
private logger;
|
|
23
|
+
constructor(options: AgentRuntimeOptions);
|
|
24
|
+
createThread(): Promise<ThreadObject>;
|
|
25
|
+
getThread(threadId: string): Promise<ThreadObjectWithMessages>;
|
|
26
|
+
private ensureThread;
|
|
27
|
+
syncRun(input: CreateRunInput, signal?: AbortSignal): Promise<RunObject>;
|
|
28
|
+
asyncRun(input: CreateRunInput): Promise<RunObject>;
|
|
29
|
+
streamRun(input: CreateRunInput, writer: SSEWriter): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Consume the execRun async generator, emitting SSE message.delta events
|
|
32
|
+
* for each chunk and accumulating content blocks and token usage.
|
|
33
|
+
*/
|
|
34
|
+
private consumeStreamMessages;
|
|
35
|
+
getRun(runId: string): Promise<RunObject>;
|
|
36
|
+
cancelRun(runId: string): Promise<RunObject>;
|
|
37
|
+
/** Wait for all in-flight background tasks to complete naturally (without aborting). */
|
|
38
|
+
waitForPendingTasks(): Promise<void>;
|
|
39
|
+
destroy(): Promise<void>;
|
|
40
|
+
/** Factory method — avoids the spread-arg type issue with dynamic delegation. */
|
|
41
|
+
static create(options: AgentRuntimeOptions): AgentRuntime;
|
|
42
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentRuntime = exports.AGENT_RUNTIME = void 0;
|
|
4
|
+
const agent_runtime_1 = require("@eggjs/tegg-types/agent-runtime");
|
|
5
|
+
const AgentStoreUtils_1 = require("./AgentStoreUtils");
|
|
6
|
+
const MessageConverter_1 = require("./MessageConverter");
|
|
7
|
+
const RunBuilder_1 = require("./RunBuilder");
|
|
8
|
+
exports.AGENT_RUNTIME = Symbol('agentRuntime');
|
|
9
|
+
class AgentRuntime {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.executor = options.executor;
|
|
12
|
+
this.store = options.store;
|
|
13
|
+
if (!options.logger) {
|
|
14
|
+
throw new Error('AgentRuntimeOptions.logger is required');
|
|
15
|
+
}
|
|
16
|
+
this.logger = options.logger;
|
|
17
|
+
this.runningTasks = new Map();
|
|
18
|
+
}
|
|
19
|
+
async createThread() {
|
|
20
|
+
var _a;
|
|
21
|
+
const thread = await this.store.createThread();
|
|
22
|
+
return {
|
|
23
|
+
id: thread.id,
|
|
24
|
+
object: agent_runtime_1.AgentObjectType.Thread,
|
|
25
|
+
createdAt: thread.createdAt,
|
|
26
|
+
metadata: (_a = thread.metadata) !== null && _a !== void 0 ? _a : {},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async getThread(threadId) {
|
|
30
|
+
var _a;
|
|
31
|
+
const thread = await this.store.getThread(threadId);
|
|
32
|
+
return {
|
|
33
|
+
id: thread.id,
|
|
34
|
+
object: agent_runtime_1.AgentObjectType.Thread,
|
|
35
|
+
createdAt: thread.createdAt,
|
|
36
|
+
metadata: (_a = thread.metadata) !== null && _a !== void 0 ? _a : {},
|
|
37
|
+
messages: thread.messages,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async ensureThread(input) {
|
|
41
|
+
if (input.threadId) {
|
|
42
|
+
return { threadId: input.threadId, input };
|
|
43
|
+
}
|
|
44
|
+
const thread = await this.store.createThread();
|
|
45
|
+
return { threadId: thread.id, input: { ...input, threadId: thread.id } };
|
|
46
|
+
}
|
|
47
|
+
async syncRun(input, signal) {
|
|
48
|
+
const { threadId, input: resolvedInput } = await this.ensureThread(input);
|
|
49
|
+
input = resolvedInput;
|
|
50
|
+
const run = await this.store.createRun(input.input.messages, threadId, input.config, input.metadata);
|
|
51
|
+
const rb = RunBuilder_1.RunBuilder.create(run, threadId);
|
|
52
|
+
// Bridge external signal to an internal AbortController so cancelRun can abort syncRun
|
|
53
|
+
const abortController = new AbortController();
|
|
54
|
+
if (signal) {
|
|
55
|
+
if (signal.aborted) {
|
|
56
|
+
abortController.abort();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
signal.addEventListener('abort', () => abortController.abort(), { once: true });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Register in runningTasks so cancelRun can find and await this run.
|
|
63
|
+
// Use a real pending promise (not Promise.resolve()) so cancelRun's
|
|
64
|
+
// `await task.promise` blocks until syncRun's try/finally completes.
|
|
65
|
+
let resolveTask;
|
|
66
|
+
const taskPromise = new Promise(r => {
|
|
67
|
+
resolveTask = r;
|
|
68
|
+
});
|
|
69
|
+
this.runningTasks.set(run.id, { promise: taskPromise, abortController });
|
|
70
|
+
try {
|
|
71
|
+
await this.store.updateRun(run.id, rb.start());
|
|
72
|
+
const streamMessages = [];
|
|
73
|
+
for await (const msg of this.executor.execRun(input, abortController.signal)) {
|
|
74
|
+
if (abortController.signal.aborted) {
|
|
75
|
+
// Run was cancelled externally — re-read store for the latest state
|
|
76
|
+
const latest = await this.store.getRun(run.id);
|
|
77
|
+
return RunBuilder_1.RunBuilder.fromRecord(latest).snapshot();
|
|
78
|
+
}
|
|
79
|
+
streamMessages.push(msg);
|
|
80
|
+
}
|
|
81
|
+
const { output, usage } = MessageConverter_1.MessageConverter.extractFromStreamMessages(streamMessages, run.id);
|
|
82
|
+
// Append messages first so that if updateRun fails the run stays in_progress
|
|
83
|
+
// and can be retried, rather than showing completed with missing thread history.
|
|
84
|
+
// TODO(atomicity): for full consistency, add an aggregate store method
|
|
85
|
+
// (e.g. completeRunWithMessages) that wraps both writes in a single transaction.
|
|
86
|
+
await this.store.appendMessages(threadId, [
|
|
87
|
+
...MessageConverter_1.MessageConverter.toInputMessageObjects(input.input.messages, threadId),
|
|
88
|
+
...output,
|
|
89
|
+
]);
|
|
90
|
+
await this.store.updateRun(run.id, rb.complete(output, usage));
|
|
91
|
+
return rb.snapshot();
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (abortController.signal.aborted) {
|
|
95
|
+
// Cancelled — re-read store for the latest state
|
|
96
|
+
const latest = await this.store.getRun(run.id);
|
|
97
|
+
return RunBuilder_1.RunBuilder.fromRecord(latest).snapshot();
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
await this.store.updateRun(run.id, rb.fail(err));
|
|
101
|
+
}
|
|
102
|
+
catch (storeErr) {
|
|
103
|
+
this.logger.error('[AgentRuntime] failed to update run status after syncRun error:', storeErr);
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
resolveTask();
|
|
109
|
+
this.runningTasks.delete(run.id);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async asyncRun(input) {
|
|
113
|
+
const { threadId, input: resolvedInput } = await this.ensureThread(input);
|
|
114
|
+
input = resolvedInput;
|
|
115
|
+
const run = await this.store.createRun(input.input.messages, threadId, input.config, input.metadata);
|
|
116
|
+
const rb = RunBuilder_1.RunBuilder.create(run, threadId);
|
|
117
|
+
const abortController = new AbortController();
|
|
118
|
+
// Capture queued snapshot before background task mutates state
|
|
119
|
+
const queuedSnapshot = rb.snapshot();
|
|
120
|
+
// Register in runningTasks before the IIFE starts executing to avoid a race
|
|
121
|
+
// where the IIFE's finally block deletes the entry before it is set.
|
|
122
|
+
let resolveTask;
|
|
123
|
+
const taskPromise = new Promise(r => {
|
|
124
|
+
resolveTask = r;
|
|
125
|
+
});
|
|
126
|
+
this.runningTasks.set(run.id, { promise: taskPromise, abortController });
|
|
127
|
+
(async () => {
|
|
128
|
+
try {
|
|
129
|
+
await this.store.updateRun(run.id, rb.start());
|
|
130
|
+
const streamMessages = [];
|
|
131
|
+
for await (const msg of this.executor.execRun(input, abortController.signal)) {
|
|
132
|
+
if (abortController.signal.aborted)
|
|
133
|
+
return;
|
|
134
|
+
streamMessages.push(msg);
|
|
135
|
+
}
|
|
136
|
+
// Check if another worker has cancelled this run before writing final state
|
|
137
|
+
const currentRun = await this.store.getRun(run.id);
|
|
138
|
+
if (currentRun.status === agent_runtime_1.RunStatus.Cancelling || currentRun.status === agent_runtime_1.RunStatus.Cancelled) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const { output, usage } = MessageConverter_1.MessageConverter.extractFromStreamMessages(streamMessages, run.id);
|
|
142
|
+
// Append messages before marking run as completed — see syncRun comment.
|
|
143
|
+
// TODO(atomicity): add aggregate store method for full transactional guarantee.
|
|
144
|
+
await this.store.appendMessages(threadId, [
|
|
145
|
+
...MessageConverter_1.MessageConverter.toInputMessageObjects(input.input.messages, threadId),
|
|
146
|
+
...output,
|
|
147
|
+
]);
|
|
148
|
+
await this.store.updateRun(run.id, rb.complete(output, usage));
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (!abortController.signal.aborted) {
|
|
152
|
+
// Check store before writing failed state — another worker may have cancelled
|
|
153
|
+
try {
|
|
154
|
+
const currentRun = await this.store.getRun(run.id);
|
|
155
|
+
if (currentRun.status !== agent_runtime_1.RunStatus.Cancelling && currentRun.status !== agent_runtime_1.RunStatus.Cancelled) {
|
|
156
|
+
await this.store.updateRun(run.id, rb.fail(err));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (storeErr) {
|
|
160
|
+
// TODO: need a background expiry mechanism to clean up runs stuck in non-terminal states
|
|
161
|
+
// (e.g. in_progress or cancelling) when store writes fail persistently.
|
|
162
|
+
this.logger.error('[AgentRuntime] failed to update run status after error:', storeErr);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
this.logger.error('[AgentRuntime] execRun error during abort:', err);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
resolveTask();
|
|
171
|
+
this.runningTasks.delete(run.id);
|
|
172
|
+
}
|
|
173
|
+
})();
|
|
174
|
+
return queuedSnapshot;
|
|
175
|
+
}
|
|
176
|
+
async streamRun(input, writer) {
|
|
177
|
+
// Abort execRun generator when client disconnects
|
|
178
|
+
const abortController = new AbortController();
|
|
179
|
+
writer.onClose(() => abortController.abort());
|
|
180
|
+
const { threadId, input: resolvedInput } = await this.ensureThread(input);
|
|
181
|
+
input = resolvedInput;
|
|
182
|
+
const run = await this.store.createRun(input.input.messages, threadId, input.config, input.metadata);
|
|
183
|
+
const rb = RunBuilder_1.RunBuilder.create(run, threadId);
|
|
184
|
+
// Register in runningTasks so cancelRun/destroy can manage streaming runs.
|
|
185
|
+
let resolveTask;
|
|
186
|
+
const taskPromise = new Promise(r => {
|
|
187
|
+
resolveTask = r;
|
|
188
|
+
});
|
|
189
|
+
this.runningTasks.set(run.id, { promise: taskPromise, abortController });
|
|
190
|
+
// event: thread.run.created
|
|
191
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunCreated, rb.snapshot());
|
|
192
|
+
// event: thread.run.in_progress
|
|
193
|
+
await this.store.updateRun(run.id, rb.start());
|
|
194
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunInProgress, rb.snapshot());
|
|
195
|
+
const msgId = (0, AgentStoreUtils_1.newMsgId)();
|
|
196
|
+
// event: thread.message.created
|
|
197
|
+
const msgObj = MessageConverter_1.MessageConverter.createStreamMessage(msgId, run.id);
|
|
198
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadMessageCreated, msgObj);
|
|
199
|
+
try {
|
|
200
|
+
const { content, usage, aborted } = await this.consumeStreamMessages(input, abortController.signal, writer, msgId);
|
|
201
|
+
if (aborted) {
|
|
202
|
+
// Skip intermediate cancelling store write — no external observer between the
|
|
203
|
+
// two states since the SSE client has already disconnected.
|
|
204
|
+
rb.cancelling();
|
|
205
|
+
try {
|
|
206
|
+
await this.store.updateRun(run.id, rb.cancel());
|
|
207
|
+
}
|
|
208
|
+
catch (storeErr) {
|
|
209
|
+
this.logger.error('[AgentRuntime] failed to write cancelled status during stream abort:', storeErr);
|
|
210
|
+
}
|
|
211
|
+
if (!writer.closed) {
|
|
212
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunCancelled, rb.snapshot());
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// event: thread.message.completed
|
|
217
|
+
const completedMsg = MessageConverter_1.MessageConverter.completeMessage(msgObj, content);
|
|
218
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadMessageCompleted, completedMsg);
|
|
219
|
+
// Persist and emit completion — append messages before marking run as completed
|
|
220
|
+
// so a failure leaves the run in_progress (retryable) instead of completed-but-incomplete.
|
|
221
|
+
// TODO(atomicity): add aggregate store method for full transactional guarantee.
|
|
222
|
+
const output = content.length > 0 ? [completedMsg] : [];
|
|
223
|
+
await this.store.appendMessages(threadId, [
|
|
224
|
+
...MessageConverter_1.MessageConverter.toInputMessageObjects(input.input.messages, threadId),
|
|
225
|
+
...output,
|
|
226
|
+
]);
|
|
227
|
+
await this.store.updateRun(run.id, rb.complete(output, usage));
|
|
228
|
+
// event: thread.run.completed
|
|
229
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunCompleted, rb.snapshot());
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
if (abortController.signal.aborted) {
|
|
233
|
+
// Client disconnected or cancelRun fired — mark as cancelled, not failed
|
|
234
|
+
rb.cancelling();
|
|
235
|
+
try {
|
|
236
|
+
await this.store.updateRun(run.id, rb.cancel());
|
|
237
|
+
}
|
|
238
|
+
catch (storeErr) {
|
|
239
|
+
this.logger.error('[AgentRuntime] failed to write cancelled status during stream error:', storeErr);
|
|
240
|
+
}
|
|
241
|
+
if (!writer.closed) {
|
|
242
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunCancelled, rb.snapshot());
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
try {
|
|
247
|
+
await this.store.updateRun(run.id, rb.fail(err));
|
|
248
|
+
}
|
|
249
|
+
catch (storeErr) {
|
|
250
|
+
this.logger.error('[AgentRuntime] failed to update run status after error:', storeErr);
|
|
251
|
+
}
|
|
252
|
+
// event: thread.run.failed
|
|
253
|
+
if (!writer.closed) {
|
|
254
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadRunFailed, rb.snapshot());
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
resolveTask();
|
|
260
|
+
this.runningTasks.delete(run.id);
|
|
261
|
+
// event: done
|
|
262
|
+
if (!writer.closed) {
|
|
263
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.Done, '[DONE]');
|
|
264
|
+
writer.end();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Consume the execRun async generator, emitting SSE message.delta events
|
|
270
|
+
* for each chunk and accumulating content blocks and token usage.
|
|
271
|
+
*/
|
|
272
|
+
async consumeStreamMessages(input, signal, writer, msgId) {
|
|
273
|
+
var _a, _b;
|
|
274
|
+
const content = [];
|
|
275
|
+
let promptTokens = 0;
|
|
276
|
+
let completionTokens = 0;
|
|
277
|
+
let hasUsage = false;
|
|
278
|
+
for await (const msg of this.executor.execRun(input, signal)) {
|
|
279
|
+
if (signal.aborted) {
|
|
280
|
+
return { content, usage: undefined, aborted: true };
|
|
281
|
+
}
|
|
282
|
+
if (msg.message) {
|
|
283
|
+
const contentBlocks = MessageConverter_1.MessageConverter.toContentBlocks(msg.message);
|
|
284
|
+
content.push(...contentBlocks);
|
|
285
|
+
// event: thread.message.delta
|
|
286
|
+
const delta = {
|
|
287
|
+
id: msgId,
|
|
288
|
+
object: agent_runtime_1.AgentObjectType.ThreadMessageDelta,
|
|
289
|
+
delta: { content: contentBlocks },
|
|
290
|
+
};
|
|
291
|
+
writer.writeEvent(agent_runtime_1.AgentSSEEvent.ThreadMessageDelta, delta);
|
|
292
|
+
}
|
|
293
|
+
if (msg.usage) {
|
|
294
|
+
hasUsage = true;
|
|
295
|
+
promptTokens += (_a = msg.usage.promptTokens) !== null && _a !== void 0 ? _a : 0;
|
|
296
|
+
completionTokens += (_b = msg.usage.completionTokens) !== null && _b !== void 0 ? _b : 0;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
content,
|
|
301
|
+
usage: hasUsage ? { promptTokens, completionTokens, totalTokens: promptTokens + completionTokens } : undefined,
|
|
302
|
+
aborted: false,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
async getRun(runId) {
|
|
306
|
+
const run = await this.store.getRun(runId);
|
|
307
|
+
return RunBuilder_1.RunBuilder.fromRecord(run).snapshot();
|
|
308
|
+
}
|
|
309
|
+
async cancelRun(runId) {
|
|
310
|
+
// 1. Check current status — reject if already terminal
|
|
311
|
+
const run = await this.store.getRun(runId);
|
|
312
|
+
if (AgentRuntime.TERMINAL_RUN_STATUSES.has(run.status)) {
|
|
313
|
+
throw new agent_runtime_1.AgentConflictError(`Cannot cancel run with status '${run.status}'`);
|
|
314
|
+
}
|
|
315
|
+
const rb = RunBuilder_1.RunBuilder.fromRecord(run);
|
|
316
|
+
// 2. Write "cancelling" to store first — visible to all workers
|
|
317
|
+
await this.store.updateRun(runId, rb.cancelling());
|
|
318
|
+
// 3. If the task is running locally, abort it for immediate effect
|
|
319
|
+
const task = this.runningTasks.get(runId);
|
|
320
|
+
if (task) {
|
|
321
|
+
task.abortController.abort();
|
|
322
|
+
await task.promise.catch(() => {
|
|
323
|
+
/* ignore */
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
// 4. Re-read store to mitigate TOCTOU: if the run completed/failed between
|
|
327
|
+
// steps 2 and 4, do not overwrite the terminal state.
|
|
328
|
+
// TODO: For full atomicity, use CAS / ETag-based conditional writes.
|
|
329
|
+
const freshRun = await this.store.getRun(runId);
|
|
330
|
+
if (AgentRuntime.TERMINAL_RUN_STATUSES.has(freshRun.status)) {
|
|
331
|
+
// Run reached a terminal state while we were cancelling — return as-is
|
|
332
|
+
return RunBuilder_1.RunBuilder.fromRecord(freshRun).snapshot();
|
|
333
|
+
}
|
|
334
|
+
// 5. Transition to final "cancelled" state
|
|
335
|
+
try {
|
|
336
|
+
await this.store.updateRun(runId, rb.cancel());
|
|
337
|
+
}
|
|
338
|
+
catch (err) {
|
|
339
|
+
this.logger.error('[AgentRuntime] failed to write cancelled state after cancelling:', err);
|
|
340
|
+
// Return best-effort snapshot from store
|
|
341
|
+
const fallback = await this.store.getRun(runId);
|
|
342
|
+
return RunBuilder_1.RunBuilder.fromRecord(fallback).snapshot();
|
|
343
|
+
}
|
|
344
|
+
return rb.snapshot();
|
|
345
|
+
}
|
|
346
|
+
/** Wait for all in-flight background tasks to complete naturally (without aborting). */
|
|
347
|
+
async waitForPendingTasks() {
|
|
348
|
+
if (this.runningTasks.size) {
|
|
349
|
+
const pending = Array.from(this.runningTasks.values()).map(t => t.promise);
|
|
350
|
+
await Promise.allSettled(pending);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async destroy() {
|
|
354
|
+
// Abort all in-flight background tasks, then wait for them to settle
|
|
355
|
+
for (const task of this.runningTasks.values()) {
|
|
356
|
+
task.abortController.abort();
|
|
357
|
+
}
|
|
358
|
+
await this.waitForPendingTasks();
|
|
359
|
+
// Destroy store
|
|
360
|
+
if (this.store.destroy) {
|
|
361
|
+
await this.store.destroy();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/** Factory method — avoids the spread-arg type issue with dynamic delegation. */
|
|
365
|
+
static create(options) {
|
|
366
|
+
return new AgentRuntime(options);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
exports.AgentRuntime = AgentRuntime;
|
|
370
|
+
AgentRuntime.TERMINAL_RUN_STATUSES = new Set([
|
|
371
|
+
agent_runtime_1.RunStatus.Completed,
|
|
372
|
+
agent_runtime_1.RunStatus.Failed,
|
|
373
|
+
agent_runtime_1.RunStatus.Cancelled,
|
|
374
|
+
agent_runtime_1.RunStatus.Expired,
|
|
375
|
+
]);
|
|
376
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdlbnRSdW50aW1lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL0FnZW50UnVudGltZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFXQSxtRUFBZ0g7QUFHaEgsdURBQTZDO0FBQzdDLHlEQUFzRDtBQUN0RCw2Q0FBMEM7QUFJN0IsUUFBQSxhQUFhLEdBQWtCLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztBQWdCbkUsTUFBYSxZQUFZO0lBYXZCLFlBQVksT0FBNEI7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUM1RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQzdCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVk7O1FBQ2hCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMvQyxPQUFPO1lBQ0wsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ2IsTUFBTSxFQUFFLCtCQUFlLENBQUMsTUFBTTtZQUM5QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7WUFDM0IsUUFBUSxFQUFFLE1BQUEsTUFBTSxDQUFDLFFBQVEsbUNBQUksRUFBRTtTQUNoQyxDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTLENBQUMsUUFBZ0I7O1FBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7UUFD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
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { InputMessage, MessageObject, AgentRunConfig, RunStatus } from '@eggjs/controller-decorator';
|
|
2
|
+
export interface ThreadRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
object: 'thread';
|
|
5
|
+
messages: MessageObject[];
|
|
6
|
+
metadata: Record<string, unknown>;
|
|
7
|
+
created_at: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RunRecord {
|
|
10
|
+
id: string;
|
|
11
|
+
object: 'thread.run';
|
|
12
|
+
thread_id?: string;
|
|
13
|
+
status: RunStatus;
|
|
14
|
+
input: InputMessage[];
|
|
15
|
+
output?: MessageObject[];
|
|
16
|
+
last_error?: {
|
|
17
|
+
code: string;
|
|
18
|
+
message: string;
|
|
19
|
+
} | null;
|
|
20
|
+
usage?: {
|
|
21
|
+
prompt_tokens: number;
|
|
22
|
+
completion_tokens: number;
|
|
23
|
+
total_tokens: number;
|
|
24
|
+
} | null;
|
|
25
|
+
config?: AgentRunConfig;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
created_at: number;
|
|
28
|
+
started_at?: number | null;
|
|
29
|
+
completed_at?: number | null;
|
|
30
|
+
cancelled_at?: number | null;
|
|
31
|
+
failed_at?: number | null;
|
|
32
|
+
}
|
|
33
|
+
export interface AgentStore {
|
|
34
|
+
init?(): Promise<void>;
|
|
35
|
+
destroy?(): Promise<void>;
|
|
36
|
+
createThread(metadata?: Record<string, unknown>): Promise<ThreadRecord>;
|
|
37
|
+
getThread(threadId: string): Promise<ThreadRecord>;
|
|
38
|
+
appendMessages(threadId: string, messages: MessageObject[]): Promise<void>;
|
|
39
|
+
createRun(input: InputMessage[], threadId?: string, config?: AgentRunConfig, metadata?: Record<string, unknown>): Promise<RunRecord>;
|
|
40
|
+
getRun(runId: string): Promise<RunRecord>;
|
|
41
|
+
updateRun(runId: string, updates: Partial<RunRecord>): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdlbnRTdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9BZ2VudFN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.nowUnix = nowUnix;
|
|
7
|
+
exports.newMsgId = newMsgId;
|
|
8
|
+
exports.newThreadId = newThreadId;
|
|
9
|
+
exports.newRunId = newRunId;
|
|
10
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
11
|
+
function nowUnix() {
|
|
12
|
+
return Math.floor(Date.now() / 1000);
|
|
13
|
+
}
|
|
14
|
+
function newMsgId() {
|
|
15
|
+
return `msg_${node_crypto_1.default.randomUUID()}`;
|
|
16
|
+
}
|
|
17
|
+
function newThreadId() {
|
|
18
|
+
return `thread_${node_crypto_1.default.randomUUID()}`;
|
|
19
|
+
}
|
|
20
|
+
function newRunId() {
|
|
21
|
+
return `run_${node_crypto_1.default.randomUUID()}`;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdlbnRTdG9yZVV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL0FnZW50U3RvcmVVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLDBCQUVDO0FBRUQsNEJBRUM7QUFFRCxrQ0FFQztBQUVELDRCQUVDO0FBaEJELDhEQUFpQztBQUVqQyxTQUFnQixPQUFPO0lBQ3JCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUVELFNBQWdCLFFBQVE7SUFDdEIsT0FBTyxPQUFPLHFCQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztBQUN0QyxDQUFDO0FBRUQsU0FBZ0IsV0FBVztJQUN6QixPQUFPLFVBQVUscUJBQU0sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO0FBQ3pDLENBQUM7QUFFRCxTQUFnQixRQUFRO0lBQ3RCLE9BQU8sT0FBTyxxQkFBTSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUM7QUFDdEMsQ0FBQyJ9
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { InputMessage, MessageObject, AgentRunConfig } from '@eggjs/controller-decorator';
|
|
2
|
+
import type { AgentStore, ThreadRecord, RunRecord } from './AgentStore';
|
|
3
|
+
export interface FileAgentStoreOptions {
|
|
4
|
+
dataDir: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class FileAgentStore implements AgentStore {
|
|
7
|
+
private readonly dataDir;
|
|
8
|
+
private readonly threadsDir;
|
|
9
|
+
private readonly runsDir;
|
|
10
|
+
constructor(options: FileAgentStoreOptions);
|
|
11
|
+
private safePath;
|
|
12
|
+
init(): Promise<void>;
|
|
13
|
+
createThread(metadata?: Record<string, unknown>): Promise<ThreadRecord>;
|
|
14
|
+
getThread(threadId: string): Promise<ThreadRecord>;
|
|
15
|
+
appendMessages(threadId: string, messages: MessageObject[]): Promise<void>;
|
|
16
|
+
createRun(input: InputMessage[], threadId?: string, config?: AgentRunConfig, metadata?: Record<string, unknown>): Promise<RunRecord>;
|
|
17
|
+
getRun(runId: string): Promise<RunRecord>;
|
|
18
|
+
updateRun(runId: string, updates: Partial<RunRecord>): Promise<void>;
|
|
19
|
+
private writeFile;
|
|
20
|
+
private readFile;
|
|
21
|
+
}
|