@ponythewhite/base-context-agent 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/NOTICE +22 -0
- package/README.md +551 -0
- package/dist/LICENSE +23 -0
- package/dist/NOTICE +22 -0
- package/dist/agent-loop.d.ts +24 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +897 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent.d.ts +144 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +569 -0
- package/dist/agent.js.map +1 -0
- package/dist/build-info.json +14 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/invocation-output.d.ts +30 -0
- package/dist/invocation-output.d.ts.map +1 -0
- package/dist/invocation-output.js +125 -0
- package/dist/invocation-output.js.map +1 -0
- package/dist/proxy.d.ts +59 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +268 -0
- package/dist/proxy.js.map +1 -0
- package/dist/types.d.ts +512 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/dist/agent.js
ADDED
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
import { createAssistantMessageDiagnostic, isLocalRequestPreparationError, RequestTokenBudgetError, streamSimple, } from "@ponythewhite/base-context-ai";
|
|
2
|
+
import { runAgentLoop, runAgentLoopContinue } from "./agent-loop.js";
|
|
3
|
+
import { AgentOutputLimitError } from "./invocation-output.js";
|
|
4
|
+
/** Preserve actual local request preparation failures and primary cleanup chains without inventing an assistant. */
|
|
5
|
+
function isRequestTokenBudgetFailure(error) {
|
|
6
|
+
return (error instanceof RequestTokenBudgetError ||
|
|
7
|
+
isLocalRequestPreparationError(error) ||
|
|
8
|
+
(error instanceof AggregateError && isRequestTokenBudgetFailure(error.errors[0])));
|
|
9
|
+
}
|
|
10
|
+
function defaultConvertToLlm(messages) {
|
|
11
|
+
return messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
|
|
12
|
+
}
|
|
13
|
+
const EMPTY_USAGE = {
|
|
14
|
+
input: 0,
|
|
15
|
+
output: 0,
|
|
16
|
+
cacheRead: 0,
|
|
17
|
+
cacheWrite: 0,
|
|
18
|
+
totalTokens: 0,
|
|
19
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
20
|
+
};
|
|
21
|
+
const DEFAULT_MODEL = {
|
|
22
|
+
id: "unknown",
|
|
23
|
+
name: "unknown",
|
|
24
|
+
api: "unknown",
|
|
25
|
+
provider: "unknown",
|
|
26
|
+
baseUrl: "",
|
|
27
|
+
reasoning: false,
|
|
28
|
+
input: [],
|
|
29
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
30
|
+
contextWindow: 0,
|
|
31
|
+
maxTokens: 0,
|
|
32
|
+
};
|
|
33
|
+
function createMutableAgentState(initialState) {
|
|
34
|
+
let tools = initialState?.tools?.slice() ?? [];
|
|
35
|
+
let messages = initialState?.messages?.slice() ?? [];
|
|
36
|
+
return {
|
|
37
|
+
systemPrompt: initialState?.systemPrompt ?? "",
|
|
38
|
+
model: initialState?.model ?? DEFAULT_MODEL,
|
|
39
|
+
thinkingLevel: initialState?.thinkingLevel ?? "off",
|
|
40
|
+
serviceTier: initialState?.serviceTier ?? "default",
|
|
41
|
+
get tools() {
|
|
42
|
+
return tools;
|
|
43
|
+
},
|
|
44
|
+
set tools(nextTools) {
|
|
45
|
+
tools = nextTools.slice();
|
|
46
|
+
},
|
|
47
|
+
get messages() {
|
|
48
|
+
return messages;
|
|
49
|
+
},
|
|
50
|
+
set messages(nextMessages) {
|
|
51
|
+
messages = nextMessages.slice();
|
|
52
|
+
},
|
|
53
|
+
isStreaming: false,
|
|
54
|
+
streamingMessage: undefined,
|
|
55
|
+
pendingToolCalls: new Set(),
|
|
56
|
+
errorMessage: undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
class PendingMessageQueue {
|
|
60
|
+
mode;
|
|
61
|
+
batches = [];
|
|
62
|
+
constructor(mode) {
|
|
63
|
+
this.mode = mode;
|
|
64
|
+
}
|
|
65
|
+
enqueue(message) {
|
|
66
|
+
const batch = Array.isArray(message) ? message.slice() : [message];
|
|
67
|
+
if (batch.length > 0) {
|
|
68
|
+
this.batches.push(batch);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
hasItems() {
|
|
72
|
+
return this.batches.length > 0;
|
|
73
|
+
}
|
|
74
|
+
drain() {
|
|
75
|
+
if (this.mode === "all") {
|
|
76
|
+
const drained = this.batches.flat();
|
|
77
|
+
this.batches = [];
|
|
78
|
+
return drained;
|
|
79
|
+
}
|
|
80
|
+
const first = this.batches[0];
|
|
81
|
+
if (!first) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
this.batches = this.batches.slice(1);
|
|
85
|
+
return first;
|
|
86
|
+
}
|
|
87
|
+
clear() {
|
|
88
|
+
this.batches = [];
|
|
89
|
+
}
|
|
90
|
+
removeWhere(predicate) {
|
|
91
|
+
const removed = [];
|
|
92
|
+
const retained = [];
|
|
93
|
+
for (const batch of this.batches) {
|
|
94
|
+
if (batch.some(predicate)) {
|
|
95
|
+
removed.push(...batch);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
retained.push(batch);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
this.batches = retained;
|
|
102
|
+
return removed;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Typed precondition failure from {@link Agent.continue}, so callers classify by code instead of message text. */
|
|
106
|
+
export class AgentContinueError extends Error {
|
|
107
|
+
code;
|
|
108
|
+
constructor(code, message) {
|
|
109
|
+
super(message);
|
|
110
|
+
this.code = code;
|
|
111
|
+
this.name = "AgentContinueError";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export class Agent {
|
|
115
|
+
_state;
|
|
116
|
+
listeners = new Set();
|
|
117
|
+
steeringQueue;
|
|
118
|
+
followUpQueue;
|
|
119
|
+
convertToLlm;
|
|
120
|
+
transformContext;
|
|
121
|
+
initializationOwner;
|
|
122
|
+
contextOwner;
|
|
123
|
+
requestPreparationRecoveryOwner;
|
|
124
|
+
providerFailureRecoveryOwner;
|
|
125
|
+
outputOwner;
|
|
126
|
+
activeOutputPolicy;
|
|
127
|
+
/** Native sinks join finalized message values; configuration is captured once per invocation. */
|
|
128
|
+
bindOutputOwner(owner) {
|
|
129
|
+
if (this.outputOwner)
|
|
130
|
+
throw new Error("Agent output owner is already bound");
|
|
131
|
+
this.outputOwner = owner;
|
|
132
|
+
}
|
|
133
|
+
/** Finish native initialization before capturing context or emitting loop events. */
|
|
134
|
+
bindInitializationOwner(owner) {
|
|
135
|
+
if (this.initializationOwner)
|
|
136
|
+
throw new Error("Agent initialization owner is already bound");
|
|
137
|
+
this.initializationOwner = owner;
|
|
138
|
+
}
|
|
139
|
+
/** Native persistence remains ahead of replaceable context callbacks. */
|
|
140
|
+
bindContextOwner(owner) {
|
|
141
|
+
if (this.contextOwner)
|
|
142
|
+
throw new Error("Agent context owner is already bound");
|
|
143
|
+
this.contextOwner = owner;
|
|
144
|
+
}
|
|
145
|
+
bindRequestPreparationRecoveryOwner(owner) {
|
|
146
|
+
if (this.requestPreparationRecoveryOwner)
|
|
147
|
+
throw new Error("Agent request preparation recovery owner is already bound");
|
|
148
|
+
this.requestPreparationRecoveryOwner = owner;
|
|
149
|
+
}
|
|
150
|
+
bindProviderFailureRecoveryOwner(owner) {
|
|
151
|
+
if (this.providerFailureRecoveryOwner)
|
|
152
|
+
throw new Error("Agent provider failure recovery owner is already bound");
|
|
153
|
+
this.providerFailureRecoveryOwner = owner;
|
|
154
|
+
}
|
|
155
|
+
configuredStreamFn;
|
|
156
|
+
effectiveStreamFn;
|
|
157
|
+
ownedStreamFn;
|
|
158
|
+
streamOwner;
|
|
159
|
+
get streamFn() {
|
|
160
|
+
return this.effectiveStreamFn;
|
|
161
|
+
}
|
|
162
|
+
set streamFn(streamFn) {
|
|
163
|
+
this.configuredStreamFn = streamFn;
|
|
164
|
+
const ownedStreamFn = this.streamOwner?.(streamFn);
|
|
165
|
+
this.ownedStreamFn = ownedStreamFn;
|
|
166
|
+
this.effectiveStreamFn = ownedStreamFn ?? streamFn;
|
|
167
|
+
}
|
|
168
|
+
/** A native owner remains in the path when an embedding changes its configured stream. */
|
|
169
|
+
bindStreamOwner(owner) {
|
|
170
|
+
if (this.streamOwner)
|
|
171
|
+
throw new Error("Agent stream owner is already bound");
|
|
172
|
+
this.streamOwner = owner;
|
|
173
|
+
this.streamFn = this.configuredStreamFn;
|
|
174
|
+
}
|
|
175
|
+
getApiKey;
|
|
176
|
+
onPayload;
|
|
177
|
+
onResponse;
|
|
178
|
+
beforeToolCall;
|
|
179
|
+
afterToolCall;
|
|
180
|
+
onToolInvocationStarting;
|
|
181
|
+
onToolExchangeFinalized;
|
|
182
|
+
toolExecutionOwner;
|
|
183
|
+
/** Native persistence runs before replaceable caller hooks. */
|
|
184
|
+
bindToolExecutionOwner(owner) {
|
|
185
|
+
if (this.toolExecutionOwner)
|
|
186
|
+
throw new Error("Agent tool execution owner is already bound");
|
|
187
|
+
this.toolExecutionOwner = {
|
|
188
|
+
onToolInvocationStarting: owner.onToolInvocationStarting,
|
|
189
|
+
onToolExchangeFinalized: owner.onToolExchangeFinalized,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
shouldStopAfterTurn;
|
|
193
|
+
getTurnOutcome;
|
|
194
|
+
shouldStopBeforeTurn;
|
|
195
|
+
getContinuationMessages;
|
|
196
|
+
getContinuationOutcome;
|
|
197
|
+
activeRun;
|
|
198
|
+
sessionId;
|
|
199
|
+
thinkingBudgets;
|
|
200
|
+
transport;
|
|
201
|
+
maxRetryDelayMs;
|
|
202
|
+
toolExecution;
|
|
203
|
+
constructor(options = {}) {
|
|
204
|
+
this._state = createMutableAgentState(options.initialState);
|
|
205
|
+
this.convertToLlm = options.convertToLlm ?? defaultConvertToLlm;
|
|
206
|
+
this.transformContext = options.transformContext;
|
|
207
|
+
this.streamFn = options.streamFn ?? streamSimple;
|
|
208
|
+
this.getApiKey = options.getApiKey;
|
|
209
|
+
this.onPayload = options.onPayload;
|
|
210
|
+
this.onResponse = options.onResponse;
|
|
211
|
+
this.beforeToolCall = options.beforeToolCall;
|
|
212
|
+
this.afterToolCall = options.afterToolCall;
|
|
213
|
+
this.onToolInvocationStarting = options.onToolInvocationStarting;
|
|
214
|
+
this.onToolExchangeFinalized = options.onToolExchangeFinalized;
|
|
215
|
+
this.shouldStopAfterTurn = options.shouldStopAfterTurn;
|
|
216
|
+
this.getTurnOutcome = options.getTurnOutcome;
|
|
217
|
+
this.shouldStopBeforeTurn = options.shouldStopBeforeTurn;
|
|
218
|
+
this.getContinuationMessages = options.getContinuationMessages;
|
|
219
|
+
this.getContinuationOutcome = options.getContinuationOutcome;
|
|
220
|
+
this.steeringQueue = new PendingMessageQueue(options.steeringMode ?? "one-at-a-time");
|
|
221
|
+
this.followUpQueue = new PendingMessageQueue(options.followUpMode ?? "one-at-a-time");
|
|
222
|
+
this.sessionId = options.sessionId;
|
|
223
|
+
this.thinkingBudgets = options.thinkingBudgets;
|
|
224
|
+
this.transport = options.transport ?? "auto";
|
|
225
|
+
this.maxRetryDelayMs = options.maxRetryDelayMs;
|
|
226
|
+
this.toolExecution = options.toolExecution ?? "parallel";
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Subscribe to agent lifecycle events.
|
|
230
|
+
*
|
|
231
|
+
* Listener promises are awaited in subscription order and are included in
|
|
232
|
+
* the current run's settlement. Listeners also receive the active abort
|
|
233
|
+
* signal for the current run.
|
|
234
|
+
*
|
|
235
|
+
* `agent_end` is the final emitted event for a run, but the agent does not
|
|
236
|
+
* become idle until all awaited listeners for that event have settled.
|
|
237
|
+
*/
|
|
238
|
+
subscribe(listener) {
|
|
239
|
+
this.listeners.add(listener);
|
|
240
|
+
return () => this.listeners.delete(listener);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Current agent state.
|
|
244
|
+
*
|
|
245
|
+
* Assigning `state.tools` or `state.messages` copies the provided top-level array.
|
|
246
|
+
*/
|
|
247
|
+
get state() {
|
|
248
|
+
return this._state;
|
|
249
|
+
}
|
|
250
|
+
set steeringMode(mode) {
|
|
251
|
+
this.steeringQueue.mode = mode;
|
|
252
|
+
}
|
|
253
|
+
get steeringMode() {
|
|
254
|
+
return this.steeringQueue.mode;
|
|
255
|
+
}
|
|
256
|
+
set followUpMode(mode) {
|
|
257
|
+
this.followUpQueue.mode = mode;
|
|
258
|
+
}
|
|
259
|
+
get followUpMode() {
|
|
260
|
+
return this.followUpQueue.mode;
|
|
261
|
+
}
|
|
262
|
+
/** Queue a message batch to be injected after the current assistant turn finishes. */
|
|
263
|
+
steer(message) {
|
|
264
|
+
this.steeringQueue.enqueue(message);
|
|
265
|
+
}
|
|
266
|
+
/** Queue a message batch to run only after the agent would otherwise stop. */
|
|
267
|
+
followUp(message) {
|
|
268
|
+
this.followUpQueue.enqueue(message);
|
|
269
|
+
}
|
|
270
|
+
clearSteeringQueue() {
|
|
271
|
+
this.steeringQueue.clear();
|
|
272
|
+
}
|
|
273
|
+
clearFollowUpQueue() {
|
|
274
|
+
this.followUpQueue.clear();
|
|
275
|
+
}
|
|
276
|
+
clearAllQueues() {
|
|
277
|
+
this.clearSteeringQueue();
|
|
278
|
+
this.clearFollowUpQueue();
|
|
279
|
+
}
|
|
280
|
+
removeQueuedMessages(predicate) {
|
|
281
|
+
return [...this.steeringQueue.removeWhere(predicate), ...this.followUpQueue.removeWhere(predicate)];
|
|
282
|
+
}
|
|
283
|
+
hasQueuedMessages() {
|
|
284
|
+
return this.steeringQueue.hasItems() || this.followUpQueue.hasItems();
|
|
285
|
+
}
|
|
286
|
+
get signal() {
|
|
287
|
+
return this.activeRun?.abortController.signal;
|
|
288
|
+
}
|
|
289
|
+
abort() {
|
|
290
|
+
this.activeRun?.abortController.abort();
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Resolve when the current run and all awaited event listeners have finished.
|
|
294
|
+
*
|
|
295
|
+
* This resolves after `agent_end` listeners settle.
|
|
296
|
+
*/
|
|
297
|
+
waitForIdle() {
|
|
298
|
+
return this.activeRun?.promise ?? Promise.resolve();
|
|
299
|
+
}
|
|
300
|
+
reset() {
|
|
301
|
+
this._state.messages = [];
|
|
302
|
+
this._state.isStreaming = false;
|
|
303
|
+
this._state.streamingMessage = undefined;
|
|
304
|
+
this._state.pendingToolCalls = new Set();
|
|
305
|
+
this._state.errorMessage = undefined;
|
|
306
|
+
this.clearFollowUpQueue();
|
|
307
|
+
this.clearSteeringQueue();
|
|
308
|
+
}
|
|
309
|
+
async prompt(input, images) {
|
|
310
|
+
if (this.activeRun) {
|
|
311
|
+
throw new Error("Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.");
|
|
312
|
+
}
|
|
313
|
+
const messages = this.normalizePromptInput(input, images);
|
|
314
|
+
await this.runPromptMessages(messages);
|
|
315
|
+
}
|
|
316
|
+
/** The last message must convert to a user or tool-result message. */
|
|
317
|
+
async continue() {
|
|
318
|
+
if (this.activeRun) {
|
|
319
|
+
throw new AgentContinueError("busy", "Agent is already processing. Wait for completion before continuing.");
|
|
320
|
+
}
|
|
321
|
+
const runQueuedMessages = () => {
|
|
322
|
+
const queuedSteering = this.steeringQueue.drain();
|
|
323
|
+
if (queuedSteering.length > 0) {
|
|
324
|
+
return this.runPromptMessages(queuedSteering, { skipInitialSteeringPoll: true });
|
|
325
|
+
}
|
|
326
|
+
const queuedFollowUps = this.followUpQueue.drain();
|
|
327
|
+
if (queuedFollowUps.length > 0) {
|
|
328
|
+
return this.runPromptMessages(queuedFollowUps);
|
|
329
|
+
}
|
|
330
|
+
return undefined;
|
|
331
|
+
};
|
|
332
|
+
const lastMessage = this._state.messages[this._state.messages.length - 1];
|
|
333
|
+
if (!lastMessage) {
|
|
334
|
+
const queuedRun = runQueuedMessages();
|
|
335
|
+
if (queuedRun) {
|
|
336
|
+
await queuedRun;
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
throw new AgentContinueError("nothing-to-continue", "No messages to continue from");
|
|
340
|
+
}
|
|
341
|
+
if (lastMessage.role === "assistant") {
|
|
342
|
+
const queuedRun = runQueuedMessages();
|
|
343
|
+
if (queuedRun) {
|
|
344
|
+
await queuedRun;
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
throw new AgentContinueError("nothing-to-continue", "Cannot continue from message role: assistant");
|
|
348
|
+
}
|
|
349
|
+
const lastMessageRole = lastMessage.role;
|
|
350
|
+
if (lastMessageRole === "custom") {
|
|
351
|
+
const queuedRun = runQueuedMessages();
|
|
352
|
+
if (queuedRun) {
|
|
353
|
+
await queuedRun;
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
await this.runContinuation();
|
|
358
|
+
}
|
|
359
|
+
normalizePromptInput(input, images) {
|
|
360
|
+
if (Array.isArray(input)) {
|
|
361
|
+
return input;
|
|
362
|
+
}
|
|
363
|
+
if (typeof input !== "string") {
|
|
364
|
+
return [input];
|
|
365
|
+
}
|
|
366
|
+
const content = [{ type: "text", text: input }];
|
|
367
|
+
if (images && images.length > 0) {
|
|
368
|
+
content.push(...images);
|
|
369
|
+
}
|
|
370
|
+
return [{ role: "user", content, timestamp: Date.now() }];
|
|
371
|
+
}
|
|
372
|
+
async runPromptMessages(messages, options = {}) {
|
|
373
|
+
await this.runWithLifecycle(async (signal) => {
|
|
374
|
+
await runAgentLoop(messages, this.createContextSnapshot(), this.createLoopConfig(options), (event) => this.processEvents(event), signal, this.streamFn);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
async runContinuation() {
|
|
378
|
+
await this.runWithLifecycle(async (signal) => {
|
|
379
|
+
await runAgentLoopContinue(this.createContextSnapshot(), this.createLoopConfig(), (event) => this.processEvents(event), signal, this.streamFn);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
createContextSnapshot() {
|
|
383
|
+
return {
|
|
384
|
+
systemPrompt: this._state.systemPrompt,
|
|
385
|
+
messages: this._state.messages.slice(),
|
|
386
|
+
tools: this._state.tools.slice(),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
createLoopConfig(options = {}) {
|
|
390
|
+
let skipInitialSteeringPoll = options.skipInitialSteeringPoll === true;
|
|
391
|
+
const onToolInvocationStarting = this.onToolInvocationStarting;
|
|
392
|
+
const onToolExchangeFinalized = this.onToolExchangeFinalized;
|
|
393
|
+
return {
|
|
394
|
+
outputPolicy: this.activeOutputPolicy,
|
|
395
|
+
model: this._state.model,
|
|
396
|
+
reasoning: this._state.thinkingLevel,
|
|
397
|
+
serviceTier: this._state.serviceTier,
|
|
398
|
+
sessionId: this.sessionId,
|
|
399
|
+
onPayload: this.onPayload,
|
|
400
|
+
onResponse: this.onResponse,
|
|
401
|
+
transport: this.transport,
|
|
402
|
+
thinkingBudgets: this.thinkingBudgets,
|
|
403
|
+
maxRetryDelayMs: this.maxRetryDelayMs,
|
|
404
|
+
toolExecution: this.toolExecution,
|
|
405
|
+
beforeToolCall: this.beforeToolCall,
|
|
406
|
+
afterToolCall: this.afterToolCall,
|
|
407
|
+
onToolInvocationStarting: async (invocation, signal, tool, execute, assistantMessage) => {
|
|
408
|
+
const owner = await this.toolExecutionOwner?.onToolInvocationStarting(invocation, signal, tool, execute, assistantMessage);
|
|
409
|
+
await onToolInvocationStarting?.(invocation, signal);
|
|
410
|
+
return owner || undefined;
|
|
411
|
+
},
|
|
412
|
+
onToolExchangeFinalized: async (exchange, signal, owner) => {
|
|
413
|
+
if (owner)
|
|
414
|
+
await owner.finalize(exchange, signal);
|
|
415
|
+
else
|
|
416
|
+
await this.toolExecutionOwner?.onToolExchangeFinalized(exchange, signal);
|
|
417
|
+
await onToolExchangeFinalized?.(exchange, signal);
|
|
418
|
+
},
|
|
419
|
+
shouldStopAfterTurn: async (context) => this.shouldStopAfterTurn?.(context) ?? false,
|
|
420
|
+
getTurnOutcome: this.getTurnOutcome?.bind(this),
|
|
421
|
+
shouldStopBeforeTurn: () => this.shouldStopBeforeTurn?.() ?? false,
|
|
422
|
+
beforeContextBuild: async () => this.contextOwner?.(),
|
|
423
|
+
recoverRequestPreparation: this.requestPreparationRecoveryOwner,
|
|
424
|
+
recoverProviderFailure: this.providerFailureRecoveryOwner?.recover,
|
|
425
|
+
onContextAdopted: (messages) => {
|
|
426
|
+
this._state.messages = messages;
|
|
427
|
+
},
|
|
428
|
+
ownedStreamFn: this.ownedStreamFn,
|
|
429
|
+
convertToLlm: this.convertToLlm,
|
|
430
|
+
transformContext: this.transformContext,
|
|
431
|
+
getSystemPrompt: () => this._state.systemPrompt,
|
|
432
|
+
getApiKey: this.getApiKey,
|
|
433
|
+
getSteeringMessages: async () => {
|
|
434
|
+
if (skipInitialSteeringPoll) {
|
|
435
|
+
skipInitialSteeringPoll = false;
|
|
436
|
+
return [];
|
|
437
|
+
}
|
|
438
|
+
return this.steeringQueue.drain();
|
|
439
|
+
},
|
|
440
|
+
getFollowUpMessages: async () => this.followUpQueue.drain(),
|
|
441
|
+
getContinuationMessages: async (context, signal) => this.getContinuationMessages?.(context, signal) ?? [],
|
|
442
|
+
getContinuationOutcome: this.getContinuationOutcome?.bind(this),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async runWithLifecycle(executor) {
|
|
446
|
+
if (this.activeRun) {
|
|
447
|
+
throw new Error("Agent is already processing.");
|
|
448
|
+
}
|
|
449
|
+
const abortController = new AbortController();
|
|
450
|
+
let resolvePromise = () => { };
|
|
451
|
+
const promise = new Promise((resolve) => {
|
|
452
|
+
resolvePromise = resolve;
|
|
453
|
+
});
|
|
454
|
+
this.activeRun = { promise, resolve: resolvePromise, abortController };
|
|
455
|
+
this._state.isStreaming = true;
|
|
456
|
+
this._state.streamingMessage = undefined;
|
|
457
|
+
this._state.errorMessage = undefined;
|
|
458
|
+
try {
|
|
459
|
+
const outputPolicy = this.outputOwner?.();
|
|
460
|
+
this.activeOutputPolicy = outputPolicy
|
|
461
|
+
? {
|
|
462
|
+
limits: { ...outputPolicy.limits },
|
|
463
|
+
snapshot: outputPolicy.snapshot.bind(outputPolicy),
|
|
464
|
+
bindUpdates: outputPolicy.bindUpdates?.bind(outputPolicy),
|
|
465
|
+
settleUpdates: outputPolicy.settleUpdates?.bind(outputPolicy),
|
|
466
|
+
}
|
|
467
|
+
: undefined;
|
|
468
|
+
if (this.initializationOwner) {
|
|
469
|
+
await this.initializationOwner();
|
|
470
|
+
abortController.signal.throwIfAborted();
|
|
471
|
+
}
|
|
472
|
+
await executor(abortController.signal);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
if (error instanceof AgentOutputLimitError || isRequestTokenBudgetFailure(error)) {
|
|
476
|
+
this._state.errorMessage = error.message;
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
await this.handleRunFailure(error, abortController.signal.aborted);
|
|
480
|
+
}
|
|
481
|
+
finally {
|
|
482
|
+
try {
|
|
483
|
+
this.providerFailureRecoveryOwner?.settle?.();
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
this.finishRun();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
async handleRunFailure(error, aborted) {
|
|
491
|
+
const failureMessage = {
|
|
492
|
+
role: "assistant",
|
|
493
|
+
content: [{ type: "text", text: "" }],
|
|
494
|
+
api: this._state.model.api,
|
|
495
|
+
provider: this._state.model.provider,
|
|
496
|
+
model: this._state.model.id,
|
|
497
|
+
usage: EMPTY_USAGE,
|
|
498
|
+
stopReason: aborted ? "aborted" : "error",
|
|
499
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
500
|
+
diagnostics: aborted
|
|
501
|
+
? undefined
|
|
502
|
+
: [createAssistantMessageDiagnostic("agent_lifecycle_failure", error, { source: "run_with_lifecycle" })],
|
|
503
|
+
timestamp: Date.now(),
|
|
504
|
+
};
|
|
505
|
+
this._state.errorMessage = failureMessage.errorMessage;
|
|
506
|
+
await this.processEvents({ type: "message_start", message: failureMessage }).catch(() => undefined);
|
|
507
|
+
await this.processEvents({ type: "message_end", message: failureMessage }).catch(() => undefined);
|
|
508
|
+
await this.processEvents({ type: "agent_end", messages: [failureMessage] }).catch(() => undefined);
|
|
509
|
+
}
|
|
510
|
+
finishRun() {
|
|
511
|
+
this.activeOutputPolicy = undefined;
|
|
512
|
+
this._state.isStreaming = false;
|
|
513
|
+
this._state.streamingMessage = undefined;
|
|
514
|
+
this._state.pendingToolCalls = new Set();
|
|
515
|
+
this.activeRun?.resolve();
|
|
516
|
+
this.activeRun = undefined;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Reduce internal state for a loop event, then await listeners.
|
|
520
|
+
*
|
|
521
|
+
* `agent_end` only means no further loop events will be emitted. The run is
|
|
522
|
+
* considered idle later, after all awaited listeners for `agent_end` finish
|
|
523
|
+
* and `finishRun()` clears runtime-owned state.
|
|
524
|
+
*/
|
|
525
|
+
async processEvents(event) {
|
|
526
|
+
switch (event.type) {
|
|
527
|
+
case "message_start":
|
|
528
|
+
this._state.streamingMessage = event.message;
|
|
529
|
+
break;
|
|
530
|
+
case "message_update":
|
|
531
|
+
this._state.streamingMessage = event.message;
|
|
532
|
+
break;
|
|
533
|
+
case "message_end":
|
|
534
|
+
this._state.streamingMessage = undefined;
|
|
535
|
+
this._state.messages.push(event.message);
|
|
536
|
+
break;
|
|
537
|
+
case "tool_execution_start": {
|
|
538
|
+
const pendingToolCalls = new Set(this._state.pendingToolCalls);
|
|
539
|
+
pendingToolCalls.add(event.toolCallId);
|
|
540
|
+
this._state.pendingToolCalls = pendingToolCalls;
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
case "tool_execution_end": {
|
|
544
|
+
const pendingToolCalls = new Set(this._state.pendingToolCalls);
|
|
545
|
+
pendingToolCalls.delete(event.toolCallId);
|
|
546
|
+
this._state.pendingToolCalls = pendingToolCalls;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
case "turn_end":
|
|
550
|
+
if (event.message.role === "assistant" && event.message.errorMessage) {
|
|
551
|
+
this._state.errorMessage = event.message.errorMessage;
|
|
552
|
+
}
|
|
553
|
+
break;
|
|
554
|
+
case "agent_end":
|
|
555
|
+
this._state.streamingMessage = undefined;
|
|
556
|
+
if (event.refusal)
|
|
557
|
+
this._state.errorMessage = new AgentOutputLimitError(event.refusal).message;
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
const signal = this.activeRun?.abortController.signal;
|
|
561
|
+
if (!signal) {
|
|
562
|
+
throw new Error("Agent listener invoked outside active run");
|
|
563
|
+
}
|
|
564
|
+
for (const listener of this.listeners) {
|
|
565
|
+
await listener(event, signal);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcreateAssistantMessageDiagnostic,\n\ttype ImageContent,\n\tisLocalRequestPreparationError,\n\ttype Message,\n\ttype Model,\n\tRequestTokenBudgetError,\n\ttype SimpleStreamOptions,\n\tstreamSimple,\n\ttype TextContent,\n\ttype ThinkingBudgets,\n\ttype Transport,\n} from \"@ponythewhite/base-context-ai\";\nimport { runAgentLoop, runAgentLoopContinue } from \"./agent-loop.js\";\nimport { AgentOutputLimitError } from \"./invocation-output.js\";\nimport type {\n\tAfterToolCallContext,\n\tAfterToolCallResult,\n\tAgentContext,\n\tAgentContextBuildResult,\n\tAgentContinuationOutcome,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentOutputPolicy,\n\tAgentOwnedStreamFn,\n\tAgentState,\n\tAgentTool,\n\tAgentTurnOutcome,\n\tBeforeToolCallContext,\n\tBeforeToolCallResult,\n\tFinalizedToolExchange,\n\tGetContinuationMessagesContext,\n\tGetTurnOutcomeContext,\n\tShouldStopAfterTurnContext,\n\tStreamFn,\n\tToolExecutionMode,\n\tToolInvocation,\n} from \"./types.js\";\n\n/** Preserve actual local request preparation failures and primary cleanup chains without inventing an assistant. */\nfunction isRequestTokenBudgetFailure(error: unknown): error is Error {\n\treturn (\n\t\terror instanceof RequestTokenBudgetError ||\n\t\tisLocalRequestPreparationError(error) ||\n\t\t(error instanceof AggregateError && isRequestTokenBudgetFailure(error.errors[0]))\n\t);\n}\n\nfunction defaultConvertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(\n\t\t(message) => message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\",\n\t);\n}\n\nconst EMPTY_USAGE = {\n\tinput: 0,\n\toutput: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n};\n\nconst DEFAULT_MODEL = {\n\tid: \"unknown\",\n\tname: \"unknown\",\n\tapi: \"unknown\",\n\tprovider: \"unknown\",\n\tbaseUrl: \"\",\n\treasoning: false,\n\tinput: [],\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\tcontextWindow: 0,\n\tmaxTokens: 0,\n} satisfies Model<any>;\n\ntype QueueMode = \"all\" | \"one-at-a-time\";\n\ntype MutableAgentState = Omit<AgentState, \"isStreaming\" | \"streamingMessage\" | \"pendingToolCalls\" | \"errorMessage\"> & {\n\tisStreaming: boolean;\n\tstreamingMessage?: AgentMessage;\n\tpendingToolCalls: Set<string>;\n\terrorMessage?: string;\n};\n\nfunction createMutableAgentState(\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>,\n): MutableAgentState {\n\tlet tools = initialState?.tools?.slice() ?? [];\n\tlet messages = initialState?.messages?.slice() ?? [];\n\n\treturn {\n\t\tsystemPrompt: initialState?.systemPrompt ?? \"\",\n\t\tmodel: initialState?.model ?? DEFAULT_MODEL,\n\t\tthinkingLevel: initialState?.thinkingLevel ?? \"off\",\n\t\tserviceTier: initialState?.serviceTier ?? \"default\",\n\t\tget tools() {\n\t\t\treturn tools;\n\t\t},\n\t\tset tools(nextTools: AgentTool<any>[]) {\n\t\t\ttools = nextTools.slice();\n\t\t},\n\t\tget messages() {\n\t\t\treturn messages;\n\t\t},\n\t\tset messages(nextMessages: AgentMessage[]) {\n\t\t\tmessages = nextMessages.slice();\n\t\t},\n\t\tisStreaming: false,\n\t\tstreamingMessage: undefined,\n\t\tpendingToolCalls: new Set<string>(),\n\t\terrorMessage: undefined,\n\t};\n}\n\nexport interface AgentOptions {\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>;\n\tconvertToLlm?: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\ttransformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tstreamFn?: StreamFn;\n\tgetApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tonPayload?: SimpleStreamOptions[\"onPayload\"];\n\tonResponse?: SimpleStreamOptions[\"onResponse\"];\n\tbeforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise<BeforeToolCallResult | undefined>;\n\tafterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise<AfterToolCallResult | undefined>;\n\tonToolInvocationStarting?: (invocation: ToolInvocation, signal?: AbortSignal) => void | Promise<void>;\n\tonToolExchangeFinalized?: (exchange: FinalizedToolExchange, signal?: AbortSignal) => void | Promise<void>;\n\tshouldStopAfterTurn?: (context: ShouldStopAfterTurnContext) => boolean | Promise<boolean>;\n\tgetTurnOutcome?: (\n\t\tcontext: GetTurnOutcomeContext,\n\t\tsignal?: AbortSignal,\n\t) => AgentTurnOutcome | Promise<AgentTurnOutcome>;\n\tshouldStopBeforeTurn?: () => boolean;\n\tgetContinuationMessages?: (context: GetContinuationMessagesContext, signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tgetContinuationOutcome?: (\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentContinuationOutcome>;\n\tsteeringMode?: QueueMode;\n\tfollowUpMode?: QueueMode;\n\tsessionId?: string;\n\tthinkingBudgets?: ThinkingBudgets;\n\ttransport?: Transport;\n\tmaxRetryDelayMs?: number;\n\ttoolExecution?: ToolExecutionMode;\n}\n\nclass PendingMessageQueue {\n\tprivate batches: AgentMessage[][] = [];\n\n\tconstructor(public mode: QueueMode) {}\n\n\tenqueue(message: AgentMessage | AgentMessage[]): void {\n\t\tconst batch = Array.isArray(message) ? message.slice() : [message];\n\t\tif (batch.length > 0) {\n\t\t\tthis.batches.push(batch);\n\t\t}\n\t}\n\n\thasItems(): boolean {\n\t\treturn this.batches.length > 0;\n\t}\n\n\tdrain(): AgentMessage[] {\n\t\tif (this.mode === \"all\") {\n\t\t\tconst drained = this.batches.flat();\n\t\t\tthis.batches = [];\n\t\t\treturn drained;\n\t\t}\n\n\t\tconst first = this.batches[0];\n\t\tif (!first) {\n\t\t\treturn [];\n\t\t}\n\t\tthis.batches = this.batches.slice(1);\n\t\treturn first;\n\t}\n\n\tclear(): void {\n\t\tthis.batches = [];\n\t}\n\n\tremoveWhere(predicate: (message: AgentMessage) => boolean): AgentMessage[] {\n\t\tconst removed: AgentMessage[] = [];\n\t\tconst retained: AgentMessage[][] = [];\n\t\tfor (const batch of this.batches) {\n\t\t\tif (batch.some(predicate)) {\n\t\t\t\tremoved.push(...batch);\n\t\t\t} else {\n\t\t\t\tretained.push(batch);\n\t\t\t}\n\t\t}\n\t\tthis.batches = retained;\n\t\treturn removed;\n\t}\n}\n\ntype ActiveRun = {\n\tpromise: Promise<void>;\n\tresolve: () => void;\n\tabortController: AbortController;\n};\n\n/** Why {@link Agent.continue} refused to start a continuation. */\nexport type AgentContinueErrorCode = \"busy\" | \"nothing-to-continue\";\n\n/** Typed precondition failure from {@link Agent.continue}, so callers classify by code instead of message text. */\nexport class AgentContinueError extends Error {\n\tconstructor(\n\t\treadonly code: AgentContinueErrorCode,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"AgentContinueError\";\n\t}\n}\n\nexport class Agent {\n\tprivate _state: MutableAgentState;\n\tprivate readonly listeners = new Set<(event: AgentEvent, signal: AbortSignal) => Promise<void> | void>();\n\tprivate readonly steeringQueue: PendingMessageQueue;\n\tprivate readonly followUpQueue: PendingMessageQueue;\n\n\tpublic convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\tpublic transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tprivate initializationOwner?: () => Promise<void>;\n\tprivate contextOwner?: () => Promise<AgentContextBuildResult>;\n\tprivate requestPreparationRecoveryOwner?: AgentLoopConfig[\"recoverRequestPreparation\"];\n\tprivate providerFailureRecoveryOwner?: {\n\t\trecover: NonNullable<AgentLoopConfig[\"recoverProviderFailure\"]>;\n\t\tsettle?: () => void;\n\t};\n\tprivate outputOwner?: () => AgentOutputPolicy | undefined;\n\tprivate activeOutputPolicy?: AgentOutputPolicy;\n\n\t/** Native sinks join finalized message values; configuration is captured once per invocation. */\n\tbindOutputOwner(owner: () => AgentOutputPolicy | undefined): void {\n\t\tif (this.outputOwner) throw new Error(\"Agent output owner is already bound\");\n\t\tthis.outputOwner = owner;\n\t}\n\n\t/** Finish native initialization before capturing context or emitting loop events. */\n\tbindInitializationOwner(owner: () => Promise<void>): void {\n\t\tif (this.initializationOwner) throw new Error(\"Agent initialization owner is already bound\");\n\t\tthis.initializationOwner = owner;\n\t}\n\n\t/** Native persistence remains ahead of replaceable context callbacks. */\n\tbindContextOwner(owner: () => Promise<AgentContextBuildResult>): void {\n\t\tif (this.contextOwner) throw new Error(\"Agent context owner is already bound\");\n\t\tthis.contextOwner = owner;\n\t}\n\n\tbindRequestPreparationRecoveryOwner(owner: NonNullable<AgentLoopConfig[\"recoverRequestPreparation\"]>): void {\n\t\tif (this.requestPreparationRecoveryOwner)\n\t\t\tthrow new Error(\"Agent request preparation recovery owner is already bound\");\n\t\tthis.requestPreparationRecoveryOwner = owner;\n\t}\n\n\tbindProviderFailureRecoveryOwner(owner: {\n\t\trecover: NonNullable<AgentLoopConfig[\"recoverProviderFailure\"]>;\n\t\tsettle?: () => void;\n\t}): void {\n\t\tif (this.providerFailureRecoveryOwner) throw new Error(\"Agent provider failure recovery owner is already bound\");\n\t\tthis.providerFailureRecoveryOwner = owner;\n\t}\n\n\tprivate configuredStreamFn!: StreamFn;\n\tprivate effectiveStreamFn!: StreamFn;\n\tprivate ownedStreamFn?: AgentOwnedStreamFn;\n\tprivate streamOwner?: (streamFn: StreamFn) => AgentOwnedStreamFn;\n\n\tget streamFn(): StreamFn {\n\t\treturn this.effectiveStreamFn;\n\t}\n\tset streamFn(streamFn: StreamFn) {\n\t\tthis.configuredStreamFn = streamFn;\n\t\tconst ownedStreamFn = this.streamOwner?.(streamFn);\n\t\tthis.ownedStreamFn = ownedStreamFn;\n\t\tthis.effectiveStreamFn = ownedStreamFn ?? streamFn;\n\t}\n\n\t/** A native owner remains in the path when an embedding changes its configured stream. */\n\tbindStreamOwner(owner: (streamFn: StreamFn) => AgentOwnedStreamFn): void {\n\t\tif (this.streamOwner) throw new Error(\"Agent stream owner is already bound\");\n\t\tthis.streamOwner = owner;\n\t\tthis.streamFn = this.configuredStreamFn;\n\t}\n\tpublic getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tpublic onPayload?: SimpleStreamOptions[\"onPayload\"];\n\tpublic onResponse?: SimpleStreamOptions[\"onResponse\"];\n\tpublic beforeToolCall?: (\n\t\tcontext: BeforeToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<BeforeToolCallResult | undefined>;\n\tpublic afterToolCall?: (\n\t\tcontext: AfterToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AfterToolCallResult | undefined>;\n\tpublic onToolInvocationStarting?: (invocation: ToolInvocation, signal?: AbortSignal) => void | Promise<void>;\n\tpublic onToolExchangeFinalized?: (exchange: FinalizedToolExchange, signal?: AbortSignal) => void | Promise<void>;\n\tprivate toolExecutionOwner?: Required<Pick<AgentLoopConfig, \"onToolInvocationStarting\" | \"onToolExchangeFinalized\">>;\n\n\t/** Native persistence runs before replaceable caller hooks. */\n\tbindToolExecutionOwner(\n\t\towner: Required<Pick<AgentLoopConfig, \"onToolInvocationStarting\" | \"onToolExchangeFinalized\">>,\n\t): void {\n\t\tif (this.toolExecutionOwner) throw new Error(\"Agent tool execution owner is already bound\");\n\t\tthis.toolExecutionOwner = {\n\t\t\tonToolInvocationStarting: owner.onToolInvocationStarting,\n\t\t\tonToolExchangeFinalized: owner.onToolExchangeFinalized,\n\t\t};\n\t}\n\n\tpublic shouldStopAfterTurn?: (context: ShouldStopAfterTurnContext) => boolean | Promise<boolean>;\n\tpublic getTurnOutcome?: (\n\t\tcontext: GetTurnOutcomeContext,\n\t\tsignal?: AbortSignal,\n\t) => AgentTurnOutcome | Promise<AgentTurnOutcome>;\n\tpublic shouldStopBeforeTurn?: () => boolean;\n\tpublic getContinuationMessages?: (\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentMessage[]>;\n\tpublic getContinuationOutcome?: (\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentContinuationOutcome>;\n\tprivate activeRun?: ActiveRun;\n\tpublic sessionId?: string;\n\tpublic thinkingBudgets?: ThinkingBudgets;\n\tpublic transport: Transport;\n\tpublic maxRetryDelayMs?: number;\n\tpublic toolExecution: ToolExecutionMode;\n\n\tconstructor(options: AgentOptions = {}) {\n\t\tthis._state = createMutableAgentState(options.initialState);\n\t\tthis.convertToLlm = options.convertToLlm ?? defaultConvertToLlm;\n\t\tthis.transformContext = options.transformContext;\n\t\tthis.streamFn = options.streamFn ?? streamSimple;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.onPayload = options.onPayload;\n\t\tthis.onResponse = options.onResponse;\n\t\tthis.beforeToolCall = options.beforeToolCall;\n\t\tthis.afterToolCall = options.afterToolCall;\n\t\tthis.onToolInvocationStarting = options.onToolInvocationStarting;\n\t\tthis.onToolExchangeFinalized = options.onToolExchangeFinalized;\n\t\tthis.shouldStopAfterTurn = options.shouldStopAfterTurn;\n\t\tthis.getTurnOutcome = options.getTurnOutcome;\n\t\tthis.shouldStopBeforeTurn = options.shouldStopBeforeTurn;\n\t\tthis.getContinuationMessages = options.getContinuationMessages;\n\t\tthis.getContinuationOutcome = options.getContinuationOutcome;\n\t\tthis.steeringQueue = new PendingMessageQueue(options.steeringMode ?? \"one-at-a-time\");\n\t\tthis.followUpQueue = new PendingMessageQueue(options.followUpMode ?? \"one-at-a-time\");\n\t\tthis.sessionId = options.sessionId;\n\t\tthis.thinkingBudgets = options.thinkingBudgets;\n\t\tthis.transport = options.transport ?? \"auto\";\n\t\tthis.maxRetryDelayMs = options.maxRetryDelayMs;\n\t\tthis.toolExecution = options.toolExecution ?? \"parallel\";\n\t}\n\n\t/**\n\t * Subscribe to agent lifecycle events.\n\t *\n\t * Listener promises are awaited in subscription order and are included in\n\t * the current run's settlement. Listeners also receive the active abort\n\t * signal for the current run.\n\t *\n\t * `agent_end` is the final emitted event for a run, but the agent does not\n\t * become idle until all awaited listeners for that event have settled.\n\t */\n\tsubscribe(listener: (event: AgentEvent, signal: AbortSignal) => Promise<void> | void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/**\n\t * Current agent state.\n\t *\n\t * Assigning `state.tools` or `state.messages` copies the provided top-level array.\n\t */\n\tget state(): AgentState {\n\t\treturn this._state;\n\t}\n\n\tset steeringMode(mode: QueueMode) {\n\t\tthis.steeringQueue.mode = mode;\n\t}\n\n\tget steeringMode(): QueueMode {\n\t\treturn this.steeringQueue.mode;\n\t}\n\n\tset followUpMode(mode: QueueMode) {\n\t\tthis.followUpQueue.mode = mode;\n\t}\n\n\tget followUpMode(): QueueMode {\n\t\treturn this.followUpQueue.mode;\n\t}\n\n\t/** Queue a message batch to be injected after the current assistant turn finishes. */\n\tsteer(message: AgentMessage | AgentMessage[]): void {\n\t\tthis.steeringQueue.enqueue(message);\n\t}\n\n\t/** Queue a message batch to run only after the agent would otherwise stop. */\n\tfollowUp(message: AgentMessage | AgentMessage[]): void {\n\t\tthis.followUpQueue.enqueue(message);\n\t}\n\n\tclearSteeringQueue(): void {\n\t\tthis.steeringQueue.clear();\n\t}\n\n\tclearFollowUpQueue(): void {\n\t\tthis.followUpQueue.clear();\n\t}\n\n\tclearAllQueues(): void {\n\t\tthis.clearSteeringQueue();\n\t\tthis.clearFollowUpQueue();\n\t}\n\n\tremoveQueuedMessages(predicate: (message: AgentMessage) => boolean): AgentMessage[] {\n\t\treturn [...this.steeringQueue.removeWhere(predicate), ...this.followUpQueue.removeWhere(predicate)];\n\t}\n\n\thasQueuedMessages(): boolean {\n\t\treturn this.steeringQueue.hasItems() || this.followUpQueue.hasItems();\n\t}\n\n\tget signal(): AbortSignal | undefined {\n\t\treturn this.activeRun?.abortController.signal;\n\t}\n\n\tabort(): void {\n\t\tthis.activeRun?.abortController.abort();\n\t}\n\n\t/**\n\t * Resolve when the current run and all awaited event listeners have finished.\n\t *\n\t * This resolves after `agent_end` listeners settle.\n\t */\n\twaitForIdle(): Promise<void> {\n\t\treturn this.activeRun?.promise ?? Promise.resolve();\n\t}\n\n\treset(): void {\n\t\tthis._state.messages = [];\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis._state.errorMessage = undefined;\n\t\tthis.clearFollowUpQueue();\n\t\tthis.clearSteeringQueue();\n\t}\n\n\tasync prompt(message: AgentMessage | AgentMessage[]): Promise<void>;\n\tasync prompt(input: string, images?: ImageContent[]): Promise<void>;\n\tasync prompt(input: string | AgentMessage | AgentMessage[], images?: ImageContent[]): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.\",\n\t\t\t);\n\t\t}\n\t\tconst messages = this.normalizePromptInput(input, images);\n\t\tawait this.runPromptMessages(messages);\n\t}\n\n\t/** The last message must convert to a user or tool-result message. */\n\tasync continue(): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new AgentContinueError(\"busy\", \"Agent is already processing. Wait for completion before continuing.\");\n\t\t}\n\n\t\tconst runQueuedMessages = (): Promise<void> | undefined => {\n\t\t\tconst queuedSteering = this.steeringQueue.drain();\n\t\t\tif (queuedSteering.length > 0) {\n\t\t\t\treturn this.runPromptMessages(queuedSteering, { skipInitialSteeringPoll: true });\n\t\t\t}\n\n\t\t\tconst queuedFollowUps = this.followUpQueue.drain();\n\t\t\tif (queuedFollowUps.length > 0) {\n\t\t\t\treturn this.runPromptMessages(queuedFollowUps);\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t};\n\n\t\tconst lastMessage = this._state.messages[this._state.messages.length - 1];\n\t\tif (!lastMessage) {\n\t\t\tconst queuedRun = runQueuedMessages();\n\t\t\tif (queuedRun) {\n\t\t\t\tawait queuedRun;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthrow new AgentContinueError(\"nothing-to-continue\", \"No messages to continue from\");\n\t\t}\n\n\t\tif (lastMessage.role === \"assistant\") {\n\t\t\tconst queuedRun = runQueuedMessages();\n\t\t\tif (queuedRun) {\n\t\t\t\tawait queuedRun;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthrow new AgentContinueError(\"nothing-to-continue\", \"Cannot continue from message role: assistant\");\n\t\t}\n\n\t\tconst lastMessageRole: string = lastMessage.role;\n\t\tif (lastMessageRole === \"custom\") {\n\t\t\tconst queuedRun = runQueuedMessages();\n\t\t\tif (queuedRun) {\n\t\t\t\tawait queuedRun;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tawait this.runContinuation();\n\t}\n\n\tprivate normalizePromptInput(\n\t\tinput: string | AgentMessage | AgentMessage[],\n\t\timages?: ImageContent[],\n\t): AgentMessage[] {\n\t\tif (Array.isArray(input)) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input !== \"string\") {\n\t\t\treturn [input];\n\t\t}\n\n\t\tconst content: Array<TextContent | ImageContent> = [{ type: \"text\", text: input }];\n\t\tif (images && images.length > 0) {\n\t\t\tcontent.push(...images);\n\t\t}\n\t\treturn [{ role: \"user\", content, timestamp: Date.now() }];\n\t}\n\n\tprivate async runPromptMessages(\n\t\tmessages: AgentMessage[],\n\t\toptions: { skipInitialSteeringPoll?: boolean } = {},\n\t): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoop(\n\t\t\t\tmessages,\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(options),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async runContinuation(): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoopContinue(\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate createContextSnapshot(): AgentContext {\n\t\treturn {\n\t\t\tsystemPrompt: this._state.systemPrompt,\n\t\t\tmessages: this._state.messages.slice(),\n\t\t\ttools: this._state.tools.slice(),\n\t\t};\n\t}\n\n\tprivate createLoopConfig(options: { skipInitialSteeringPoll?: boolean } = {}): AgentLoopConfig {\n\t\tlet skipInitialSteeringPoll = options.skipInitialSteeringPoll === true;\n\t\tconst onToolInvocationStarting = this.onToolInvocationStarting;\n\t\tconst onToolExchangeFinalized = this.onToolExchangeFinalized;\n\t\treturn {\n\t\t\toutputPolicy: this.activeOutputPolicy,\n\t\t\tmodel: this._state.model,\n\t\t\treasoning: this._state.thinkingLevel,\n\t\t\tserviceTier: this._state.serviceTier,\n\t\t\tsessionId: this.sessionId,\n\t\t\tonPayload: this.onPayload,\n\t\t\tonResponse: this.onResponse,\n\t\t\ttransport: this.transport,\n\t\t\tthinkingBudgets: this.thinkingBudgets,\n\t\t\tmaxRetryDelayMs: this.maxRetryDelayMs,\n\t\t\ttoolExecution: this.toolExecution,\n\t\t\tbeforeToolCall: this.beforeToolCall,\n\t\t\tafterToolCall: this.afterToolCall,\n\t\t\tonToolInvocationStarting: async (invocation, signal, tool, execute, assistantMessage) => {\n\t\t\t\tconst owner = await this.toolExecutionOwner?.onToolInvocationStarting(\n\t\t\t\t\tinvocation,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttool,\n\t\t\t\t\texecute,\n\t\t\t\t\tassistantMessage,\n\t\t\t\t);\n\t\t\t\tawait onToolInvocationStarting?.(invocation, signal);\n\t\t\t\treturn owner || undefined;\n\t\t\t},\n\t\t\tonToolExchangeFinalized: async (exchange, signal, owner) => {\n\t\t\t\tif (owner) await owner.finalize(exchange, signal);\n\t\t\t\telse await this.toolExecutionOwner?.onToolExchangeFinalized(exchange, signal);\n\t\t\t\tawait onToolExchangeFinalized?.(exchange, signal);\n\t\t\t},\n\t\t\tshouldStopAfterTurn: async (context) => this.shouldStopAfterTurn?.(context) ?? false,\n\t\t\tgetTurnOutcome: this.getTurnOutcome?.bind(this),\n\t\t\tshouldStopBeforeTurn: () => this.shouldStopBeforeTurn?.() ?? false,\n\t\t\tbeforeContextBuild: async () => this.contextOwner?.(),\n\t\t\trecoverRequestPreparation: this.requestPreparationRecoveryOwner,\n\t\t\trecoverProviderFailure: this.providerFailureRecoveryOwner?.recover,\n\t\t\tonContextAdopted: (messages) => {\n\t\t\t\tthis._state.messages = messages;\n\t\t\t},\n\t\t\townedStreamFn: this.ownedStreamFn,\n\t\t\tconvertToLlm: this.convertToLlm,\n\t\t\ttransformContext: this.transformContext,\n\t\t\tgetSystemPrompt: () => this._state.systemPrompt,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tgetSteeringMessages: async () => {\n\t\t\t\tif (skipInitialSteeringPoll) {\n\t\t\t\t\tskipInitialSteeringPoll = false;\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn this.steeringQueue.drain();\n\t\t\t},\n\t\t\tgetFollowUpMessages: async () => this.followUpQueue.drain(),\n\t\t\tgetContinuationMessages: async (context, signal) => this.getContinuationMessages?.(context, signal) ?? [],\n\t\t\tgetContinuationOutcome: this.getContinuationOutcome?.bind(this),\n\t\t};\n\t}\n\n\tprivate async runWithLifecycle(executor: (signal: AbortSignal) => Promise<void>): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\"Agent is already processing.\");\n\t\t}\n\n\t\tconst abortController = new AbortController();\n\t\tlet resolvePromise = () => {};\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolvePromise = resolve;\n\t\t});\n\t\tthis.activeRun = { promise, resolve: resolvePromise, abortController };\n\n\t\tthis._state.isStreaming = true;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.errorMessage = undefined;\n\n\t\ttry {\n\t\t\tconst outputPolicy = this.outputOwner?.();\n\t\t\tthis.activeOutputPolicy = outputPolicy\n\t\t\t\t? {\n\t\t\t\t\t\tlimits: { ...outputPolicy.limits },\n\t\t\t\t\t\tsnapshot: outputPolicy.snapshot.bind(outputPolicy),\n\t\t\t\t\t\tbindUpdates: outputPolicy.bindUpdates?.bind(outputPolicy),\n\t\t\t\t\t\tsettleUpdates: outputPolicy.settleUpdates?.bind(outputPolicy),\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\t\tif (this.initializationOwner) {\n\t\t\t\tawait this.initializationOwner();\n\t\t\t\tabortController.signal.throwIfAborted();\n\t\t\t}\n\t\t\tawait executor(abortController.signal);\n\t\t} catch (error) {\n\t\t\tif (error instanceof AgentOutputLimitError || isRequestTokenBudgetFailure(error)) {\n\t\t\t\tthis._state.errorMessage = error.message;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait this.handleRunFailure(error, abortController.signal.aborted);\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tthis.providerFailureRecoveryOwner?.settle?.();\n\t\t\t} finally {\n\t\t\t\tthis.finishRun();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async handleRunFailure(error: unknown, aborted: boolean): Promise<void> {\n\t\tconst failureMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\t\tapi: this._state.model.api,\n\t\t\tprovider: this._state.model.provider,\n\t\t\tmodel: this._state.model.id,\n\t\t\tusage: EMPTY_USAGE,\n\t\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\t\tdiagnostics: aborted\n\t\t\t\t? undefined\n\t\t\t\t: [createAssistantMessageDiagnostic(\"agent_lifecycle_failure\", error, { source: \"run_with_lifecycle\" })],\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies AgentMessage;\n\t\tthis._state.errorMessage = failureMessage.errorMessage;\n\t\tawait this.processEvents({ type: \"message_start\", message: failureMessage }).catch(() => undefined);\n\t\tawait this.processEvents({ type: \"message_end\", message: failureMessage }).catch(() => undefined);\n\t\tawait this.processEvents({ type: \"agent_end\", messages: [failureMessage] }).catch(() => undefined);\n\t}\n\n\tprivate finishRun(): void {\n\t\tthis.activeOutputPolicy = undefined;\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis.activeRun?.resolve();\n\t\tthis.activeRun = undefined;\n\t}\n\n\t/**\n\t * Reduce internal state for a loop event, then await listeners.\n\t *\n\t * `agent_end` only means no further loop events will be emitted. The run is\n\t * considered idle later, after all awaited listeners for `agent_end` finish\n\t * and `finishRun()` clears runtime-owned state.\n\t */\n\tprivate async processEvents(event: AgentEvent): Promise<void> {\n\t\tswitch (event.type) {\n\t\t\tcase \"message_start\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_update\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tthis._state.messages.push(event.message);\n\t\t\t\tbreak;\n\n\t\t\tcase \"tool_execution_start\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.add(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"tool_execution_end\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.delete(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"turn_end\":\n\t\t\t\tif (event.message.role === \"assistant\" && event.message.errorMessage) {\n\t\t\t\t\tthis._state.errorMessage = event.message.errorMessage;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"agent_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tif (event.refusal) this._state.errorMessage = new AgentOutputLimitError(event.refusal).message;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst signal = this.activeRun?.abortController.signal;\n\t\tif (!signal) {\n\t\t\tthrow new Error(\"Agent listener invoked outside active run\");\n\t\t}\n\t\tfor (const listener of this.listeners) {\n\t\t\tawait listener(event, signal);\n\t\t}\n\t}\n}\n"]}
|