@librechat/agents 3.0.24 → 3.0.26
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/cjs/llm/google/index.cjs +78 -9
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +185 -15
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +20 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +79 -10
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +184 -17
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +20 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/types/llm/google/index.d.ts +10 -0
- package/dist/types/llm/google/types.d.ts +11 -1
- package/dist/types/llm/google/utils/common.d.ts +17 -2
- package/package.json +1 -1
- package/src/llm/google/data/gettysburg10.wav +0 -0
- package/src/llm/google/data/hotdog.jpg +0 -0
- package/src/llm/google/index.ts +129 -14
- package/src/llm/google/llm.spec.ts +932 -0
- package/src/llm/google/types.ts +14 -1
- package/src/llm/google/utils/common.ts +262 -35
- package/src/tools/ToolNode.ts +21 -6
package/src/llm/google/types.ts
CHANGED
|
@@ -5,11 +5,17 @@ import {
|
|
|
5
5
|
} from '@google/generative-ai';
|
|
6
6
|
import { BindToolsInput } from '@langchain/core/language_models/chat_models';
|
|
7
7
|
|
|
8
|
+
/** New GoogleSearch tool for Gemini 2.0+ models */
|
|
9
|
+
export interface GoogleSearchTool {
|
|
10
|
+
googleSearch: Record<string, never>;
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
export type GoogleGenerativeAIToolType =
|
|
9
14
|
| BindToolsInput
|
|
10
15
|
| GoogleGenerativeAIFunctionDeclarationsTool
|
|
11
16
|
| CodeExecutionTool
|
|
12
|
-
| GoogleSearchRetrievalTool
|
|
17
|
+
| GoogleSearchRetrievalTool
|
|
18
|
+
| GoogleSearchTool;
|
|
13
19
|
|
|
14
20
|
/** Enum for content modality types */
|
|
15
21
|
enum Modality {
|
|
@@ -27,6 +33,13 @@ interface ModalityTokenCount {
|
|
|
27
33
|
tokenCount: number;
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
/** Interface for input token details with cache and tier tracking */
|
|
37
|
+
export interface InputTokenDetails {
|
|
38
|
+
cache_read?: number;
|
|
39
|
+
over_200k?: number;
|
|
40
|
+
cache_read_over_200k?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
30
43
|
/** Main interface for Gemini API usage metadata */
|
|
31
44
|
export interface GeminiApiUsageMetadata {
|
|
32
45
|
promptTokenCount?: number;
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type FunctionDeclarationsTool as GoogleGenerativeAIFunctionDeclarationsTool,
|
|
13
13
|
} from '@google/generative-ai';
|
|
14
14
|
import {
|
|
15
|
+
AIMessage,
|
|
15
16
|
AIMessageChunk,
|
|
16
17
|
BaseMessage,
|
|
17
18
|
ChatMessage,
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
isDataContentBlock,
|
|
30
31
|
} from '@langchain/core/messages';
|
|
31
32
|
import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
32
|
-
import type { ChatGeneration } from '@langchain/core/outputs';
|
|
33
|
+
import type { ChatGeneration, ChatResult } from '@langchain/core/outputs';
|
|
33
34
|
import { isLangChainTool } from '@langchain/core/utils/function_calling';
|
|
34
35
|
import { isOpenAITool } from '@langchain/core/language_models/base';
|
|
35
36
|
import { ToolCallChunk } from '@langchain/core/messages/tool';
|
|
@@ -40,6 +41,20 @@ import {
|
|
|
40
41
|
} from './zod_to_genai_parameters';
|
|
41
42
|
import { GoogleGenerativeAIToolType } from '../types';
|
|
42
43
|
|
|
44
|
+
export const _FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY =
|
|
45
|
+
'__gemini_function_call_thought_signatures__';
|
|
46
|
+
|
|
47
|
+
const DUMMY_SIGNATURE =
|
|
48
|
+
'ErYCCrMCAdHtim9kOoOkrPiCNVsmlpMIKd7ZMxgiFbVQOkgp7nlLcDMzVsZwIzvuT7nQROivoXA72ccC2lSDvR0Gh7dkWaGuj7ctv6t7ZceHnecx0QYa+ix8tYpRfjhyWozQ49lWiws6+YGjCt10KRTyWsZ2h6O7iHTYJwKIRwGUHRKy/qK/6kFxJm5ML00gLq4D8s5Z6DBpp2ZlR+uF4G8jJgeWQgyHWVdx2wGYElaceVAc66tZdPQRdOHpWtgYSI1YdaXgVI8KHY3/EfNc2YqqMIulvkDBAnuMhkAjV9xmBa54Tq+ih3Im4+r3DzqhGqYdsSkhS0kZMwte4Hjs65dZzCw9lANxIqYi1DJ639WNPYihp/DCJCos7o+/EeSPJaio5sgWDyUnMGkY1atsJZ+m7pj7DD5tvQ==';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Executes a function immediately and returns its result.
|
|
52
|
+
* Functional utility similar to an Immediately Invoked Function Expression (IIFE).
|
|
53
|
+
* @param fn The function to execute.
|
|
54
|
+
* @returns The result of invoking fn.
|
|
55
|
+
*/
|
|
56
|
+
export const iife = <T>(fn: () => T): T => fn();
|
|
57
|
+
|
|
43
58
|
export function getMessageAuthor(message: BaseMessage): string {
|
|
44
59
|
const type = message._getType();
|
|
45
60
|
if (ChatMessage.isInstance(message)) {
|
|
@@ -352,7 +367,8 @@ function _convertLangChainContentToPart(
|
|
|
352
367
|
export function convertMessageContentToParts(
|
|
353
368
|
message: BaseMessage,
|
|
354
369
|
isMultimodalModel: boolean,
|
|
355
|
-
previousMessages: BaseMessage[]
|
|
370
|
+
previousMessages: BaseMessage[],
|
|
371
|
+
model?: string
|
|
356
372
|
): Part[] {
|
|
357
373
|
if (isToolMessage(message)) {
|
|
358
374
|
const messageName =
|
|
@@ -409,13 +425,33 @@ export function convertMessageContentToParts(
|
|
|
409
425
|
);
|
|
410
426
|
}
|
|
411
427
|
|
|
412
|
-
|
|
413
|
-
|
|
428
|
+
const functionThoughtSignatures = (
|
|
429
|
+
message.additional_kwargs as BaseMessage['additional_kwargs'] | undefined
|
|
430
|
+
)?.[_FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY] as
|
|
431
|
+
| Record<string, string>
|
|
432
|
+
| undefined;
|
|
433
|
+
|
|
434
|
+
if (isAIMessage(message) && (message.tool_calls?.length ?? 0) > 0) {
|
|
435
|
+
functionCalls = (message.tool_calls ?? []).map((tc) => {
|
|
436
|
+
const thoughtSignature = iife(() => {
|
|
437
|
+
if (tc.id != null && tc.id !== '') {
|
|
438
|
+
const signature = functionThoughtSignatures?.[tc.id];
|
|
439
|
+
if (signature != null && signature !== '') {
|
|
440
|
+
return signature;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (model?.includes('gemini-3') === true) {
|
|
444
|
+
return DUMMY_SIGNATURE;
|
|
445
|
+
}
|
|
446
|
+
return '';
|
|
447
|
+
});
|
|
448
|
+
|
|
414
449
|
return {
|
|
415
450
|
functionCall: {
|
|
416
451
|
name: tc.name,
|
|
417
452
|
args: tc.args,
|
|
418
453
|
},
|
|
454
|
+
...(thoughtSignature ? { thoughtSignature } : {}),
|
|
419
455
|
};
|
|
420
456
|
});
|
|
421
457
|
}
|
|
@@ -426,7 +462,9 @@ export function convertMessageContentToParts(
|
|
|
426
462
|
export function convertBaseMessagesToContent(
|
|
427
463
|
messages: BaseMessage[],
|
|
428
464
|
isMultimodalModel: boolean,
|
|
429
|
-
convertSystemMessageToHumanContent: boolean = false
|
|
465
|
+
convertSystemMessageToHumanContent: boolean = false,
|
|
466
|
+
|
|
467
|
+
model?: string
|
|
430
468
|
): Content[] | undefined {
|
|
431
469
|
return messages.reduce<{
|
|
432
470
|
content: Content[] | undefined;
|
|
@@ -456,7 +494,8 @@ export function convertBaseMessagesToContent(
|
|
|
456
494
|
const parts = convertMessageContentToParts(
|
|
457
495
|
message,
|
|
458
496
|
isMultimodalModel,
|
|
459
|
-
messages.slice(0, index)
|
|
497
|
+
messages.slice(0, index),
|
|
498
|
+
model
|
|
460
499
|
);
|
|
461
500
|
|
|
462
501
|
if (acc.mergeWithPreviousContent) {
|
|
@@ -505,11 +544,32 @@ export function convertResponseContentToChatGenerationChunk(
|
|
|
505
544
|
if (!response.candidates || response.candidates.length === 0) {
|
|
506
545
|
return null;
|
|
507
546
|
}
|
|
508
|
-
const functionCalls = response.functionCalls();
|
|
509
547
|
const [candidate] = response.candidates as [
|
|
510
548
|
Partial<GenerateContentCandidate> | undefined,
|
|
511
549
|
];
|
|
512
550
|
const { content: candidateContent, ...generationInfo } = candidate ?? {};
|
|
551
|
+
|
|
552
|
+
// Extract function calls directly from parts to preserve thoughtSignature
|
|
553
|
+
const functionCalls =
|
|
554
|
+
(candidateContent?.parts as Part[] | undefined)?.reduce(
|
|
555
|
+
(acc, p) => {
|
|
556
|
+
if ('functionCall' in p && p.functionCall) {
|
|
557
|
+
acc.push({
|
|
558
|
+
...p,
|
|
559
|
+
id:
|
|
560
|
+
'id' in p.functionCall && typeof p.functionCall.id === 'string'
|
|
561
|
+
? p.functionCall.id
|
|
562
|
+
: uuidv4(),
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
return acc;
|
|
566
|
+
},
|
|
567
|
+
[] as (
|
|
568
|
+
| undefined
|
|
569
|
+
| (FunctionCallPart & { id: string; thoughtSignature?: string })
|
|
570
|
+
)[]
|
|
571
|
+
) ?? [];
|
|
572
|
+
|
|
513
573
|
let content: MessageContent | undefined;
|
|
514
574
|
// Checks if some parts do not have text. If false, it means that the content is a string.
|
|
515
575
|
const reasoningParts: string[] = [];
|
|
@@ -529,27 +589,30 @@ export function convertResponseContentToChatGenerationChunk(
|
|
|
529
589
|
}
|
|
530
590
|
content = textParts.join('');
|
|
531
591
|
} else if (candidateContent && Array.isArray(candidateContent.parts)) {
|
|
532
|
-
content = candidateContent.parts
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
592
|
+
content = candidateContent.parts
|
|
593
|
+
.map((p) => {
|
|
594
|
+
if ('text' in p && 'thought' in p && p.thought === true) {
|
|
595
|
+
reasoningParts.push(p.text ?? '');
|
|
596
|
+
return undefined;
|
|
597
|
+
} else if ('text' in p) {
|
|
598
|
+
return {
|
|
599
|
+
type: 'text',
|
|
600
|
+
text: p.text,
|
|
601
|
+
};
|
|
602
|
+
} else if ('executableCode' in p) {
|
|
603
|
+
return {
|
|
604
|
+
type: 'executableCode',
|
|
605
|
+
executableCode: p.executableCode,
|
|
606
|
+
};
|
|
607
|
+
} else if ('codeExecutionResult' in p) {
|
|
608
|
+
return {
|
|
609
|
+
type: 'codeExecutionResult',
|
|
610
|
+
codeExecutionResult: p.codeExecutionResult,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
return p;
|
|
614
|
+
})
|
|
615
|
+
.filter((p) => p !== undefined);
|
|
553
616
|
} else {
|
|
554
617
|
// no content returned - likely due to abnormal stop reason, e.g. malformed function call
|
|
555
618
|
content = [];
|
|
@@ -566,20 +629,36 @@ export function convertResponseContentToChatGenerationChunk(
|
|
|
566
629
|
}
|
|
567
630
|
|
|
568
631
|
const toolCallChunks: ToolCallChunk[] = [];
|
|
569
|
-
if (functionCalls) {
|
|
632
|
+
if (functionCalls.length > 0) {
|
|
570
633
|
toolCallChunks.push(
|
|
571
634
|
...functionCalls.map((fc) => ({
|
|
572
|
-
...fc,
|
|
573
|
-
args: JSON.stringify(fc.args),
|
|
574
|
-
// Un-commenting this causes LangChain to incorrectly merge tool calls together
|
|
575
|
-
// index: extra.index,
|
|
576
635
|
type: 'tool_call_chunk' as const,
|
|
577
|
-
id:
|
|
636
|
+
id: fc?.id,
|
|
637
|
+
name: fc?.functionCall.name,
|
|
638
|
+
args: JSON.stringify(fc?.functionCall.args),
|
|
578
639
|
}))
|
|
579
640
|
);
|
|
580
641
|
}
|
|
581
642
|
|
|
582
|
-
|
|
643
|
+
// Extract thought signatures from function calls for Gemini 3+
|
|
644
|
+
const functionThoughtSignatures = functionCalls.reduce(
|
|
645
|
+
(acc, fc) => {
|
|
646
|
+
if (
|
|
647
|
+
fc &&
|
|
648
|
+
'thoughtSignature' in fc &&
|
|
649
|
+
typeof fc.thoughtSignature === 'string'
|
|
650
|
+
) {
|
|
651
|
+
acc[fc.id] = fc.thoughtSignature;
|
|
652
|
+
}
|
|
653
|
+
return acc;
|
|
654
|
+
},
|
|
655
|
+
{} as Record<string, string>
|
|
656
|
+
);
|
|
657
|
+
|
|
658
|
+
const additional_kwargs: ChatGeneration['message']['additional_kwargs'] = {
|
|
659
|
+
[_FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY]: functionThoughtSignatures,
|
|
660
|
+
};
|
|
661
|
+
|
|
583
662
|
if (reasoningParts.length > 0) {
|
|
584
663
|
additional_kwargs.reasoning = reasoningParts.join('');
|
|
585
664
|
}
|
|
@@ -608,6 +687,154 @@ export function convertResponseContentToChatGenerationChunk(
|
|
|
608
687
|
});
|
|
609
688
|
}
|
|
610
689
|
|
|
690
|
+
/**
|
|
691
|
+
* Maps a Google GenerateContentResult to a LangChain ChatResult
|
|
692
|
+
*/
|
|
693
|
+
export function mapGenerateContentResultToChatResult(
|
|
694
|
+
response: EnhancedGenerateContentResponse,
|
|
695
|
+
extra?: {
|
|
696
|
+
usageMetadata: UsageMetadata | undefined;
|
|
697
|
+
}
|
|
698
|
+
): ChatResult {
|
|
699
|
+
if (
|
|
700
|
+
!response.candidates ||
|
|
701
|
+
response.candidates.length === 0 ||
|
|
702
|
+
!response.candidates[0]
|
|
703
|
+
) {
|
|
704
|
+
return {
|
|
705
|
+
generations: [],
|
|
706
|
+
llmOutput: {
|
|
707
|
+
filters: response.promptFeedback,
|
|
708
|
+
},
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
const [candidate] = response.candidates as [
|
|
712
|
+
Partial<GenerateContentCandidate> | undefined,
|
|
713
|
+
];
|
|
714
|
+
const { content: candidateContent, ...generationInfo } = candidate ?? {};
|
|
715
|
+
|
|
716
|
+
// Extract function calls directly from parts to preserve thoughtSignature
|
|
717
|
+
const functionCalls =
|
|
718
|
+
candidateContent?.parts.reduce(
|
|
719
|
+
(acc, p) => {
|
|
720
|
+
if ('functionCall' in p && p.functionCall) {
|
|
721
|
+
acc.push({
|
|
722
|
+
...p,
|
|
723
|
+
id:
|
|
724
|
+
'id' in p.functionCall && typeof p.functionCall.id === 'string'
|
|
725
|
+
? p.functionCall.id
|
|
726
|
+
: uuidv4(),
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
return acc;
|
|
730
|
+
},
|
|
731
|
+
[] as (FunctionCallPart & { id: string; thoughtSignature?: string })[]
|
|
732
|
+
) ?? [];
|
|
733
|
+
|
|
734
|
+
let content: MessageContent | undefined;
|
|
735
|
+
const reasoningParts: string[] = [];
|
|
736
|
+
if (
|
|
737
|
+
Array.isArray(candidateContent?.parts) &&
|
|
738
|
+
candidateContent.parts.length === 1 &&
|
|
739
|
+
candidateContent.parts[0].text &&
|
|
740
|
+
!(
|
|
741
|
+
'thought' in candidateContent.parts[0] &&
|
|
742
|
+
candidateContent.parts[0].thought === true
|
|
743
|
+
)
|
|
744
|
+
) {
|
|
745
|
+
content = candidateContent.parts[0].text;
|
|
746
|
+
} else if (
|
|
747
|
+
Array.isArray(candidateContent?.parts) &&
|
|
748
|
+
candidateContent.parts.length > 0
|
|
749
|
+
) {
|
|
750
|
+
content = candidateContent.parts
|
|
751
|
+
.map((p) => {
|
|
752
|
+
if ('text' in p && 'thought' in p && p.thought === true) {
|
|
753
|
+
reasoningParts.push(p.text ?? '');
|
|
754
|
+
return undefined;
|
|
755
|
+
} else if ('text' in p) {
|
|
756
|
+
return {
|
|
757
|
+
type: 'text',
|
|
758
|
+
text: p.text,
|
|
759
|
+
};
|
|
760
|
+
} else if ('executableCode' in p) {
|
|
761
|
+
return {
|
|
762
|
+
type: 'executableCode',
|
|
763
|
+
executableCode: p.executableCode,
|
|
764
|
+
};
|
|
765
|
+
} else if ('codeExecutionResult' in p) {
|
|
766
|
+
return {
|
|
767
|
+
type: 'codeExecutionResult',
|
|
768
|
+
codeExecutionResult: p.codeExecutionResult,
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
return p;
|
|
772
|
+
})
|
|
773
|
+
.filter((p) => p !== undefined);
|
|
774
|
+
} else {
|
|
775
|
+
content = [];
|
|
776
|
+
}
|
|
777
|
+
let text = '';
|
|
778
|
+
if (typeof content === 'string') {
|
|
779
|
+
text = content;
|
|
780
|
+
} else if (Array.isArray(content) && content.length > 0) {
|
|
781
|
+
const block = content.find((b) => 'text' in b) as
|
|
782
|
+
| { text: string }
|
|
783
|
+
| undefined;
|
|
784
|
+
text = block?.text ?? text;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
const additional_kwargs: ChatGeneration['message']['additional_kwargs'] = {
|
|
788
|
+
...generationInfo,
|
|
789
|
+
};
|
|
790
|
+
if (reasoningParts.length > 0) {
|
|
791
|
+
additional_kwargs.reasoning = reasoningParts.join('');
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Extract thought signatures from function calls for Gemini 3+
|
|
795
|
+
const functionThoughtSignatures = functionCalls.reduce(
|
|
796
|
+
(acc, fc) => {
|
|
797
|
+
if ('thoughtSignature' in fc && typeof fc.thoughtSignature === 'string') {
|
|
798
|
+
acc[fc.id] = fc.thoughtSignature;
|
|
799
|
+
}
|
|
800
|
+
return acc;
|
|
801
|
+
},
|
|
802
|
+
{} as Record<string, string>
|
|
803
|
+
);
|
|
804
|
+
|
|
805
|
+
const tool_calls = functionCalls.map((fc) => ({
|
|
806
|
+
type: 'tool_call' as const,
|
|
807
|
+
id: fc.id,
|
|
808
|
+
name: fc.functionCall.name,
|
|
809
|
+
args: fc.functionCall.args,
|
|
810
|
+
}));
|
|
811
|
+
|
|
812
|
+
// Store thought signatures map for later retrieval
|
|
813
|
+
additional_kwargs[_FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY] =
|
|
814
|
+
functionThoughtSignatures;
|
|
815
|
+
|
|
816
|
+
const generation: ChatGeneration = {
|
|
817
|
+
text,
|
|
818
|
+
message: new AIMessage({
|
|
819
|
+
content: content ?? '',
|
|
820
|
+
tool_calls,
|
|
821
|
+
additional_kwargs,
|
|
822
|
+
usage_metadata: extra?.usageMetadata,
|
|
823
|
+
}),
|
|
824
|
+
generationInfo,
|
|
825
|
+
};
|
|
826
|
+
return {
|
|
827
|
+
generations: [generation],
|
|
828
|
+
llmOutput: {
|
|
829
|
+
tokenUsage: {
|
|
830
|
+
promptTokens: extra?.usageMetadata?.input_tokens,
|
|
831
|
+
completionTokens: extra?.usageMetadata?.output_tokens,
|
|
832
|
+
totalTokens: extra?.usageMetadata?.total_tokens,
|
|
833
|
+
},
|
|
834
|
+
},
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
|
|
611
838
|
export function convertToGenerativeAITools(
|
|
612
839
|
tools: GoogleGenerativeAIToolType[]
|
|
613
840
|
): GoogleGenerativeAIFunctionDeclarationsTool[] {
|
package/src/tools/ToolNode.ts
CHANGED
|
@@ -121,12 +121,27 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
121
121
|
);
|
|
122
122
|
} catch (handlerError) {
|
|
123
123
|
// eslint-disable-next-line no-console
|
|
124
|
-
console.error(
|
|
125
|
-
|
|
126
|
-
call.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
console.error('Error in errorHandler:', {
|
|
125
|
+
toolName: call.name,
|
|
126
|
+
toolCallId: call.id,
|
|
127
|
+
toolArgs: call.args,
|
|
128
|
+
stepId: this.toolCallStepIds?.get(call.id!),
|
|
129
|
+
turn: this.toolUsageCount.get(call.name),
|
|
130
|
+
originalError: {
|
|
131
|
+
message: e.message,
|
|
132
|
+
stack: e.stack ?? undefined,
|
|
133
|
+
},
|
|
134
|
+
handlerError:
|
|
135
|
+
handlerError instanceof Error
|
|
136
|
+
? {
|
|
137
|
+
message: handlerError.message,
|
|
138
|
+
stack: handlerError.stack ?? undefined,
|
|
139
|
+
}
|
|
140
|
+
: {
|
|
141
|
+
message: String(handlerError),
|
|
142
|
+
stack: undefined,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
return new ToolMessage({
|