@agentionai/agents 1.10.3 → 1.12.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/dist/agents/AgentConfig.d.ts +23 -0
- package/dist/agents/AgentEvent.d.ts +5 -0
- package/dist/agents/AgentEvent.js +5 -0
- package/dist/agents/BaseAgent.d.ts +113 -1
- package/dist/agents/BaseAgent.js +57 -0
- package/dist/agents/anthropic/ClaudeAgent.js +157 -117
- package/dist/agents/errors/AgentError.d.ts +12 -0
- package/dist/agents/openai/OpenAiAgent.js +116 -59
- package/dist/agents/openai-compatible/OpenAICompatibleAgent.js +140 -107
- package/dist/agents/openrouter/OpenRouterAgent.js +146 -97
- package/dist/agents/reasoning-text.d.ts +44 -0
- package/dist/agents/reasoning-text.js +43 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +1 -0
- package/dist/history/transformers.d.ts +21 -16
- package/dist/history/transformers.js +44 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +3 -3
|
@@ -190,6 +190,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
190
190
|
this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
|
|
191
191
|
// Reset token usage for this execution
|
|
192
192
|
this.resetTokenUsage();
|
|
193
|
+
this.resetPartialTurn();
|
|
193
194
|
this.currentToolCallCount = 0;
|
|
194
195
|
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
195
196
|
// Start visualization reporting
|
|
@@ -461,6 +462,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
461
462
|
async *executeStream(input, options) {
|
|
462
463
|
this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
|
|
463
464
|
this.resetTokenUsage();
|
|
465
|
+
this.resetPartialTurn();
|
|
464
466
|
this.currentToolCallCount = 0;
|
|
465
467
|
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
466
468
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
@@ -488,7 +490,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
488
490
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "AbortError", abortError.message, false);
|
|
489
491
|
this.vizEventId = undefined;
|
|
490
492
|
}
|
|
491
|
-
throw abortError;
|
|
493
|
+
throw this.withPartialTurn(abortError);
|
|
492
494
|
}
|
|
493
495
|
if (error instanceof AgentError_1.AgentError) {
|
|
494
496
|
this.emit(AgentEvent_1.AgentEvent.ERROR, error);
|
|
@@ -496,7 +498,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
496
498
|
VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
|
|
497
499
|
this.vizEventId = undefined;
|
|
498
500
|
}
|
|
499
|
-
throw error;
|
|
501
|
+
throw this.withPartialTurn(error);
|
|
500
502
|
}
|
|
501
503
|
if (error && typeof error === "object" && "error" in error) {
|
|
502
504
|
const openAIError = error;
|
|
@@ -506,7 +508,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
506
508
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "ApiError", apiError.message, openAIError.error.code === "rate_limit_exceeded");
|
|
507
509
|
this.vizEventId = undefined;
|
|
508
510
|
}
|
|
509
|
-
throw apiError;
|
|
511
|
+
throw this.withPartialTurn(apiError);
|
|
510
512
|
}
|
|
511
513
|
const executionError = new AgentError_1.ExecutionError(`OpenAI error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
512
514
|
this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
|
|
@@ -514,7 +516,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
514
516
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
|
|
515
517
|
this.vizEventId = undefined;
|
|
516
518
|
}
|
|
517
|
-
throw executionError;
|
|
519
|
+
throw this.withPartialTurn(executionError);
|
|
518
520
|
}
|
|
519
521
|
finally {
|
|
520
522
|
this.history.endExecution();
|
|
@@ -536,68 +538,123 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
536
538
|
...this.buildReasoningParams("auto"),
|
|
537
539
|
}, { signal: options?.signal });
|
|
538
540
|
let completedEvent = null;
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
541
|
+
// The Responses API builds the committed turn out of `response.completed`,
|
|
542
|
+
// which only arrives on success, so the deltas are mirrored here as well:
|
|
543
|
+
// without them a stream that dies mid-flight leaves nothing behind at all,
|
|
544
|
+
// and a reasoning summary can be minutes of generation.
|
|
545
|
+
let textDelta = "";
|
|
546
|
+
let reasoningDelta = "";
|
|
547
|
+
const partialCalls = new Map();
|
|
548
|
+
// Set once this frame's assistant message reaches history.
|
|
549
|
+
let committed = false;
|
|
550
|
+
let failure;
|
|
551
|
+
try {
|
|
552
|
+
for await (const event of stream) {
|
|
553
|
+
if (event.type === "response.output_text.delta") {
|
|
554
|
+
this.markFirstToken();
|
|
555
|
+
// Accumulated as well as yielded purely so the `finally` below can hand
|
|
556
|
+
// it back if the stream dies: the committed turn is rebuilt from
|
|
557
|
+
// `response.completed`, which never arrives on a failure.
|
|
558
|
+
textDelta += event.delta;
|
|
559
|
+
this.emit(AgentEvent_1.AgentEvent.CHUNK, event.delta);
|
|
560
|
+
yield { type: "text", content: event.delta };
|
|
561
|
+
}
|
|
562
|
+
if (event.type === "response.reasoning_summary_text.delta") {
|
|
563
|
+
this.markFirstToken();
|
|
564
|
+
reasoningDelta += event.delta;
|
|
565
|
+
this.emit(AgentEvent_1.AgentEvent.REASONING_CHUNK, event.delta);
|
|
566
|
+
yield { type: "reasoning", content: event.delta };
|
|
567
|
+
}
|
|
568
|
+
if (event.type === "response.output_item.added") {
|
|
569
|
+
const item = event.item;
|
|
570
|
+
if (item.type === "function_call") {
|
|
571
|
+
partialCalls.set(event.output_index, {
|
|
572
|
+
id: item.call_id || item.id || "",
|
|
573
|
+
name: item.name ?? "",
|
|
574
|
+
arguments: "",
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
if (event.type === "response.function_call_arguments.delta") {
|
|
579
|
+
const acc = partialCalls.get(event.output_index);
|
|
580
|
+
if (acc)
|
|
581
|
+
acc.arguments += event.delta;
|
|
582
|
+
}
|
|
583
|
+
if (event.type === "response.completed") {
|
|
584
|
+
completedEvent = event;
|
|
585
|
+
if (event.response.usage) {
|
|
586
|
+
this.accumulateUsage(this.parseUsage(event.response.usage));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (event.type === "response.incomplete") {
|
|
590
|
+
throw new AgentError_1.MaxTokensExceededError("Response incomplete: max tokens reached", this.config.maxTokens);
|
|
591
|
+
}
|
|
544
592
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
593
|
+
// The SDK's stream iterator swallows the abort and simply stops yielding.
|
|
594
|
+
// Without this the turn would fail as a malformed stream instead of a
|
|
595
|
+
// cancellation — checked here so the tokens already spent are reported.
|
|
596
|
+
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
597
|
+
if (!completedEvent) {
|
|
598
|
+
throw new AgentError_1.ExecutionError("OpenAI stream ended without a completed event");
|
|
549
599
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
600
|
+
const response = completedEvent.response;
|
|
601
|
+
const toolCalls = response.output.filter((o) => o.type === "function_call");
|
|
602
|
+
if (toolCalls.length > 0) {
|
|
603
|
+
// As in handleResponse(): bail out before the assistant turn is written,
|
|
604
|
+
// so a cancelled run leaves no unanswered function call in history.
|
|
605
|
+
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
606
|
+
this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
|
|
607
|
+
this.currentToolCallCount += toolCalls.length;
|
|
608
|
+
const functionCalls = toolCalls.map((tc) => ({
|
|
609
|
+
id: tc.id || tc.call_id,
|
|
610
|
+
call_id: tc.call_id,
|
|
611
|
+
name: tc.name,
|
|
612
|
+
arguments: tc.arguments,
|
|
613
|
+
}));
|
|
614
|
+
const assistantEntry = transformers_1.openAiTransformer.fromProviderMessage("assistant", response.output_text || "", functionCalls);
|
|
615
|
+
this.addToHistory(assistantEntry);
|
|
616
|
+
committed = true;
|
|
617
|
+
const toolResults = await this.handleToolUse(toolCalls, options);
|
|
618
|
+
for (const result of toolResults) {
|
|
619
|
+
this.addToHistory(transformers_1.openAiTransformer.toolResultEntry(result.call_id, result.output, false));
|
|
554
620
|
}
|
|
621
|
+
yield* this.streamTurn(options);
|
|
555
622
|
}
|
|
556
|
-
|
|
557
|
-
|
|
623
|
+
else {
|
|
624
|
+
const textContent = response.output_text || "";
|
|
625
|
+
const entry = transformers_1.openAiTransformer.fromProviderMessage("assistant", textContent);
|
|
626
|
+
this.addToHistory(entry);
|
|
627
|
+
committed = true;
|
|
628
|
+
this.emit(AgentEvent_1.AgentEvent.DONE, response, this.lastTokenUsage);
|
|
629
|
+
if (this.vizEventId) {
|
|
630
|
+
VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
|
|
631
|
+
input: this.lastTokenUsage?.input_tokens || 0,
|
|
632
|
+
output: this.lastTokenUsage?.output_tokens || 0,
|
|
633
|
+
total: this.lastTokenUsage?.total_tokens || 0,
|
|
634
|
+
}, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
|
|
635
|
+
this.vizEventId = undefined;
|
|
636
|
+
}
|
|
558
637
|
}
|
|
559
638
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
564
|
-
if (!completedEvent) {
|
|
565
|
-
throw new AgentError_1.ExecutionError("OpenAI stream ended without a completed event");
|
|
566
|
-
}
|
|
567
|
-
const response = completedEvent.response;
|
|
568
|
-
const toolCalls = response.output.filter((o) => o.type === "function_call");
|
|
569
|
-
if (toolCalls.length > 0) {
|
|
570
|
-
// As in handleResponse(): bail out before the assistant turn is written,
|
|
571
|
-
// so a cancelled run leaves no unanswered function call in history.
|
|
572
|
-
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
573
|
-
this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
|
|
574
|
-
this.currentToolCallCount += toolCalls.length;
|
|
575
|
-
const functionCalls = toolCalls.map((tc) => ({
|
|
576
|
-
id: tc.id || tc.call_id,
|
|
577
|
-
call_id: tc.call_id,
|
|
578
|
-
name: tc.name,
|
|
579
|
-
arguments: tc.arguments,
|
|
580
|
-
}));
|
|
581
|
-
const assistantEntry = transformers_1.openAiTransformer.fromProviderMessage("assistant", response.output_text || "", functionCalls);
|
|
582
|
-
this.addToHistory(assistantEntry);
|
|
583
|
-
const toolResults = await this.handleToolUse(toolCalls, options);
|
|
584
|
-
for (const result of toolResults) {
|
|
585
|
-
this.addToHistory(transformers_1.openAiTransformer.toolResultEntry(result.call_id, result.output, false));
|
|
586
|
-
}
|
|
587
|
-
yield* this.streamTurn(options);
|
|
639
|
+
catch (error) {
|
|
640
|
+
failure = error;
|
|
641
|
+
throw error;
|
|
588
642
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
643
|
+
finally {
|
|
644
|
+
if (!committed) {
|
|
645
|
+
this.capturePartialTurn({
|
|
646
|
+
text: textDelta,
|
|
647
|
+
reasoning: reasoningDelta,
|
|
648
|
+
toolCalls: Array.from(partialCalls.entries())
|
|
649
|
+
.sort(([a], [b]) => a - b)
|
|
650
|
+
.map(([, tc]) => ({
|
|
651
|
+
id: tc.id,
|
|
652
|
+
name: tc.name,
|
|
653
|
+
arguments: tc.arguments,
|
|
654
|
+
})),
|
|
655
|
+
reason: this.partialTurnReason(failure, options?.signal),
|
|
656
|
+
error: failure,
|
|
657
|
+
});
|
|
601
658
|
}
|
|
602
659
|
}
|
|
603
660
|
}
|
|
@@ -89,6 +89,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
89
89
|
async execute(input, options) {
|
|
90
90
|
this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
|
|
91
91
|
this.resetTokenUsage();
|
|
92
|
+
this.resetPartialTurn();
|
|
92
93
|
this.currentToolCallCount = 0;
|
|
93
94
|
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
94
95
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
@@ -312,6 +313,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
312
313
|
async *executeStream(input, options) {
|
|
313
314
|
this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
|
|
314
315
|
this.resetTokenUsage();
|
|
316
|
+
this.resetPartialTurn();
|
|
315
317
|
this.currentToolCallCount = 0;
|
|
316
318
|
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
317
319
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
@@ -339,7 +341,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
339
341
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "AbortError", abortError.message, false);
|
|
340
342
|
this.vizEventId = undefined;
|
|
341
343
|
}
|
|
342
|
-
throw abortError;
|
|
344
|
+
throw this.withPartialTurn(abortError);
|
|
343
345
|
}
|
|
344
346
|
if (error instanceof openai_1.default.APIError) {
|
|
345
347
|
const apiError = new AgentError_1.ApiError(`${this.getVendorName()} API error: ${error.message}`, error.status, error);
|
|
@@ -348,7 +350,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
348
350
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "ApiError", apiError.message, error.status === 429);
|
|
349
351
|
this.vizEventId = undefined;
|
|
350
352
|
}
|
|
351
|
-
throw apiError;
|
|
353
|
+
throw this.withPartialTurn(apiError);
|
|
352
354
|
}
|
|
353
355
|
if (error instanceof AgentError_1.AgentError) {
|
|
354
356
|
this.emit(AgentEvent_1.AgentEvent.ERROR, error);
|
|
@@ -356,7 +358,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
356
358
|
VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
|
|
357
359
|
this.vizEventId = undefined;
|
|
358
360
|
}
|
|
359
|
-
throw error;
|
|
361
|
+
throw this.withPartialTurn(error);
|
|
360
362
|
}
|
|
361
363
|
const executionError = new AgentError_1.ExecutionError(`${this.getVendorName()} error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
362
364
|
this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
|
|
@@ -364,7 +366,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
364
366
|
VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
|
|
365
367
|
this.vizEventId = undefined;
|
|
366
368
|
}
|
|
367
|
-
throw executionError;
|
|
369
|
+
throw this.withPartialTurn(executionError);
|
|
368
370
|
}
|
|
369
371
|
finally {
|
|
370
372
|
this.history.endExecution();
|
|
@@ -393,116 +395,147 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
|
|
|
393
395
|
const toolCallAcc = new Map();
|
|
394
396
|
let finishReason = null;
|
|
395
397
|
let streamUsage;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
398
|
+
// Set once this frame's assistant message reaches history. Until then the
|
|
399
|
+
// turn exists only in the accumulators above, and the `finally` salvages
|
|
400
|
+
// them — a reasoning trail can be twenty minutes of local compute, and the
|
|
401
|
+
// stream throwing (or the consumer walking away) would otherwise drop it.
|
|
402
|
+
let committed = false;
|
|
403
|
+
let failure;
|
|
404
|
+
try {
|
|
405
|
+
for await (const chunk of stream) {
|
|
406
|
+
// Usage can ride on any chunk: OpenAI sends it on a final choice-less
|
|
407
|
+
// chunk, OpenRouter attaches it to the last content chunk (the one
|
|
408
|
+
// carrying finish_reason). Keep the most recent and fold it in once the
|
|
409
|
+
// stream ends — it is a running total for the turn, not a delta, so
|
|
410
|
+
// taking the last one covers both layouts without double-counting.
|
|
411
|
+
if (chunk.usage)
|
|
412
|
+
streamUsage = chunk.usage;
|
|
413
|
+
if (chunk.id)
|
|
414
|
+
this.lastChunkId = chunk.id;
|
|
415
|
+
if (chunk.choices.length === 0)
|
|
416
|
+
continue;
|
|
417
|
+
const choice = chunk.choices[0];
|
|
418
|
+
finishReason = choice.finish_reason ?? finishReason;
|
|
419
|
+
const delta = choice.delta;
|
|
420
|
+
if (delta.content) {
|
|
421
|
+
this.markFirstToken();
|
|
422
|
+
textContent += delta.content;
|
|
423
|
+
this.emit(AgentEvent_1.AgentEvent.CHUNK, delta.content);
|
|
424
|
+
yield { type: "text", content: delta.content };
|
|
425
|
+
}
|
|
426
|
+
// Reasoning tokens (not in OpenAI SDK types — cast required). Servers
|
|
427
|
+
// disagree on the field name: OpenRouter sends `delta.reasoning`, while
|
|
428
|
+
// DeepSeek/llama.cpp send `delta.reasoning_content`. Prefer `reasoning`;
|
|
429
|
+
// never concatenate — that would duplicate the text if both were sent.
|
|
430
|
+
const deltaExtras = delta;
|
|
431
|
+
const reasoningDelta = (deltaExtras.reasoning ?? deltaExtras.reasoning_content);
|
|
432
|
+
if (reasoningDelta) {
|
|
433
|
+
this.markFirstToken();
|
|
434
|
+
// Accumulated as well as yielded: DeepSeek's thinking mode requires the
|
|
435
|
+
// assistant turn's reasoning to be replayed on the next request, so it
|
|
436
|
+
// has to reach history rather than only the caller.
|
|
437
|
+
reasoningContent += reasoningDelta;
|
|
438
|
+
this.emit(AgentEvent_1.AgentEvent.REASONING_CHUNK, reasoningDelta);
|
|
439
|
+
yield { type: "reasoning", content: reasoningDelta };
|
|
440
|
+
}
|
|
441
|
+
if (delta.tool_calls) {
|
|
442
|
+
for (const tc of delta.tool_calls) {
|
|
443
|
+
if (!toolCallAcc.has(tc.index)) {
|
|
444
|
+
toolCallAcc.set(tc.index, { id: "", name: "", arguments: "" });
|
|
445
|
+
}
|
|
446
|
+
const acc = toolCallAcc.get(tc.index);
|
|
447
|
+
if (tc.id)
|
|
448
|
+
acc.id = tc.id;
|
|
449
|
+
if (tc.function?.name)
|
|
450
|
+
acc.name += tc.function.name;
|
|
451
|
+
if (tc.function?.arguments)
|
|
452
|
+
acc.arguments += tc.function.arguments;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
416
455
|
}
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
this.
|
|
430
|
-
|
|
456
|
+
// Before any early return below, so a turn that hits the token limit or
|
|
457
|
+
// continues into a tool call still reports what it spent.
|
|
458
|
+
if (streamUsage)
|
|
459
|
+
this.accumulateStreamUsage(streamUsage);
|
|
460
|
+
// The SDK's stream iterator swallows the abort and simply stops yielding,
|
|
461
|
+
// so without this an interrupted stream would look like a short but
|
|
462
|
+
// complete turn — writing partial text to history and emitting DONE.
|
|
463
|
+
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
464
|
+
if (finishReason === "length") {
|
|
465
|
+
const error = new AgentError_1.MaxTokensExceededError("Response exceeded maximum token limit", this.config.maxTokens);
|
|
466
|
+
this.emit(AgentEvent_1.AgentEvent.MAX_TOKENS_EXCEEDED, error);
|
|
467
|
+
this.emit(AgentEvent_1.AgentEvent.ERROR, error);
|
|
468
|
+
if (this.vizEventId) {
|
|
469
|
+
VizReporter_1.vizReporter.agentError(this.vizEventId, "MaxTokensExceededError", error.message, false);
|
|
470
|
+
this.vizEventId = undefined;
|
|
471
|
+
}
|
|
472
|
+
throw error;
|
|
431
473
|
}
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
474
|
+
if (finishReason === "tool_calls" && toolCallAcc.size > 0) {
|
|
475
|
+
// As in handleResponse(): bail out before the assistant turn is written,
|
|
476
|
+
// so a cancelled run leaves no unanswered tool call in history.
|
|
477
|
+
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
478
|
+
const toolCalls = Array.from(toolCallAcc.entries())
|
|
479
|
+
.sort(([a], [b]) => a - b)
|
|
480
|
+
.map(([, tc]) => ({
|
|
481
|
+
id: tc.id,
|
|
482
|
+
type: "function",
|
|
483
|
+
function: { name: tc.name, arguments: tc.arguments },
|
|
484
|
+
}));
|
|
485
|
+
this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
|
|
486
|
+
this.currentToolCallCount += toolCalls.length;
|
|
487
|
+
const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage({
|
|
488
|
+
role: "assistant",
|
|
489
|
+
content: textContent || null,
|
|
490
|
+
tool_calls: toolCalls,
|
|
491
|
+
reasoning_content: reasoningContent || null,
|
|
492
|
+
});
|
|
493
|
+
this.addToHistory(assistantEntry);
|
|
494
|
+
committed = true;
|
|
495
|
+
const toolResults = await this.handleToolCalls(toolCalls, options);
|
|
496
|
+
for (const result of toolResults) {
|
|
497
|
+
this.addToHistory(transformers_1.chatCompletionsTransformer.toolResultEntry(result.toolCallId, result.content));
|
|
444
498
|
}
|
|
499
|
+
yield* this.streamTurn(options);
|
|
445
500
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
501
|
+
else {
|
|
502
|
+
const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage({
|
|
503
|
+
role: "assistant",
|
|
504
|
+
content: textContent || null,
|
|
505
|
+
reasoning_content: reasoningContent || null,
|
|
506
|
+
});
|
|
507
|
+
this.addToHistory(assistantEntry);
|
|
508
|
+
committed = true;
|
|
509
|
+
this.emit(AgentEvent_1.AgentEvent.DONE, { content: textContent }, this.lastTokenUsage);
|
|
510
|
+
if (this.vizEventId) {
|
|
511
|
+
VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
|
|
512
|
+
input: this.lastTokenUsage?.input_tokens || 0,
|
|
513
|
+
output: this.lastTokenUsage?.output_tokens || 0,
|
|
514
|
+
total: this.lastTokenUsage?.total_tokens || 0,
|
|
515
|
+
}, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
|
|
516
|
+
this.vizEventId = undefined;
|
|
517
|
+
}
|
|
462
518
|
}
|
|
463
|
-
throw error;
|
|
464
519
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
(0, cancellation_1.throwIfAborted)(options?.signal, `Execution of agent ${this.getName()}`);
|
|
469
|
-
const toolCalls = Array.from(toolCallAcc.entries())
|
|
470
|
-
.sort(([a], [b]) => a - b)
|
|
471
|
-
.map(([, tc]) => ({
|
|
472
|
-
id: tc.id,
|
|
473
|
-
type: "function",
|
|
474
|
-
function: { name: tc.name, arguments: tc.arguments },
|
|
475
|
-
}));
|
|
476
|
-
this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
|
|
477
|
-
this.currentToolCallCount += toolCalls.length;
|
|
478
|
-
const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage({
|
|
479
|
-
role: "assistant",
|
|
480
|
-
content: textContent || null,
|
|
481
|
-
tool_calls: toolCalls,
|
|
482
|
-
reasoning_content: reasoningContent || null,
|
|
483
|
-
});
|
|
484
|
-
this.addToHistory(assistantEntry);
|
|
485
|
-
const toolResults = await this.handleToolCalls(toolCalls, options);
|
|
486
|
-
for (const result of toolResults) {
|
|
487
|
-
this.addToHistory(transformers_1.chatCompletionsTransformer.toolResultEntry(result.toolCallId, result.content));
|
|
488
|
-
}
|
|
489
|
-
yield* this.streamTurn(options);
|
|
520
|
+
catch (error) {
|
|
521
|
+
failure = error;
|
|
522
|
+
throw error;
|
|
490
523
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
524
|
+
finally {
|
|
525
|
+
if (!committed) {
|
|
526
|
+
this.capturePartialTurn({
|
|
527
|
+
text: textContent,
|
|
528
|
+
reasoning: reasoningContent,
|
|
529
|
+
toolCalls: Array.from(toolCallAcc.entries())
|
|
530
|
+
.sort(([a], [b]) => a - b)
|
|
531
|
+
.map(([, tc]) => ({
|
|
532
|
+
id: tc.id,
|
|
533
|
+
name: tc.name,
|
|
534
|
+
arguments: tc.arguments,
|
|
535
|
+
})),
|
|
536
|
+
reason: this.partialTurnReason(failure, options?.signal),
|
|
537
|
+
error: failure,
|
|
538
|
+
});
|
|
506
539
|
}
|
|
507
540
|
}
|
|
508
541
|
}
|