@vybestack/llxprt-code-core 0.5.0-nightly.251109.557a0fe7 → 0.5.0-nightly.251110.281144e6
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/src/auth/precedence.d.ts +4 -0
- package/dist/src/auth/precedence.js +75 -21
- package/dist/src/auth/precedence.js.map +1 -1
- package/dist/src/config/config.d.ts +1 -0
- package/dist/src/config/config.js +43 -3
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/core/client.d.ts +1 -0
- package/dist/src/core/client.js +6 -0
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/coreToolScheduler.js +5 -5
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/prompts.js +53 -0
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/turn.js +19 -2
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/parsers/TextToolCallParser.d.ts +3 -1
- package/dist/src/parsers/TextToolCallParser.js +68 -20
- package/dist/src/parsers/TextToolCallParser.js.map +1 -1
- package/dist/src/providers/BaseProvider.js +28 -9
- package/dist/src/providers/BaseProvider.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.js +12 -18
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.js +9 -1
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.d.ts +27 -5
- package/dist/src/providers/openai/OpenAIProvider.js +1078 -117
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/openai/ToolCallCollector.d.ts +77 -0
- package/dist/src/providers/openai/ToolCallCollector.js +150 -0
- package/dist/src/providers/openai/ToolCallCollector.js.map +1 -0
- package/dist/src/providers/openai/ToolCallExecutor.d.ts +65 -0
- package/dist/src/providers/openai/ToolCallExecutor.js +120 -0
- package/dist/src/providers/openai/ToolCallExecutor.js.map +1 -0
- package/dist/src/providers/openai/ToolCallNormalizer.d.ts +47 -0
- package/dist/src/providers/openai/ToolCallNormalizer.js +101 -0
- package/dist/src/providers/openai/ToolCallNormalizer.js.map +1 -0
- package/dist/src/providers/openai/ToolCallPipeline.d.ts +80 -0
- package/dist/src/providers/openai/ToolCallPipeline.js +137 -0
- package/dist/src/providers/openai/ToolCallPipeline.js.map +1 -0
- package/dist/src/providers/openai/ToolCallValidator.d.ts +55 -0
- package/dist/src/providers/openai/ToolCallValidator.js +108 -0
- package/dist/src/providers/openai/ToolCallValidator.js.map +1 -0
- package/dist/src/providers/openai/ToolNameValidator.d.ts +38 -0
- package/dist/src/providers/openai/ToolNameValidator.js +90 -0
- package/dist/src/providers/openai/ToolNameValidator.js.map +1 -0
- package/dist/src/providers/openai/test-types.d.ts +37 -0
- package/dist/src/providers/openai/test-types.js +3 -0
- package/dist/src/providers/openai/test-types.js.map +1 -0
- package/dist/src/providers/openai/toolNameUtils.d.ts +57 -0
- package/dist/src/providers/openai/toolNameUtils.js +180 -0
- package/dist/src/providers/openai/toolNameUtils.js.map +1 -0
- package/dist/src/providers/types/IProviderConfig.d.ts +6 -0
- package/dist/src/providers/utils/toolResponsePayload.d.ts +18 -0
- package/dist/src/providers/utils/toolResponsePayload.js +130 -0
- package/dist/src/providers/utils/toolResponsePayload.js.map +1 -0
- package/dist/src/runtime/AgentRuntimeLoader.js +5 -5
- package/dist/src/runtime/AgentRuntimeLoader.js.map +1 -1
- package/dist/src/services/history/HistoryService.d.ts +6 -0
- package/dist/src/services/history/HistoryService.js +61 -20
- package/dist/src/services/history/HistoryService.js.map +1 -1
- package/dist/src/tools/ToolFormatter.js +9 -40
- package/dist/src/tools/ToolFormatter.js.map +1 -1
- package/dist/src/tools/doubleEscapeUtils.js +6 -14
- package/dist/src/tools/doubleEscapeUtils.js.map +1 -1
- package/dist/src/tools/task.d.ts +0 -9
- package/dist/src/tools/task.js +4 -42
- package/dist/src/tools/task.js.map +1 -1
- package/dist/src/tools/tool-registry.js +20 -9
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/toolNameUtils.d.ts +43 -0
- package/dist/src/tools/toolNameUtils.js +126 -0
- package/dist/src/tools/toolNameUtils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Vybestack LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type { ToolFormat } from '../../tools/IToolFormatter.js';
|
|
17
|
+
export interface ToolNameValidationResult {
|
|
18
|
+
name: string;
|
|
19
|
+
warnings: string[];
|
|
20
|
+
isValid: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare class ToolNameValidator {
|
|
23
|
+
private logger;
|
|
24
|
+
constructor();
|
|
25
|
+
/**
|
|
26
|
+
* Validates and normalizes a tool name from qwen model responses
|
|
27
|
+
* Based on subagent.ts normalizeToolName but enhanced for OpenAI provider
|
|
28
|
+
*/
|
|
29
|
+
validateToolName(rawName: string | undefined, detectedFormat: ToolFormat, availableToolNames?: string[]): ToolNameValidationResult;
|
|
30
|
+
/**
|
|
31
|
+
* Normalize tool name using shared utility function
|
|
32
|
+
*/
|
|
33
|
+
private normalizeToolName;
|
|
34
|
+
/**
|
|
35
|
+
* Find matching tool from available tools with fuzzy matching
|
|
36
|
+
*/
|
|
37
|
+
private findMatchingTool;
|
|
38
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Vybestack LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Tool Name Validator for OpenAI Provider
|
|
18
|
+
*
|
|
19
|
+
* Based on the mature logic from subagent.ts normalizeToolName function,
|
|
20
|
+
* but adapted for OpenAI provider context with enhanced error handling.
|
|
21
|
+
*/
|
|
22
|
+
import { DebugLogger } from '../../debug/index.js';
|
|
23
|
+
import { normalizeToolName, findMatchingTool, } from '../../tools/toolNameUtils.js';
|
|
24
|
+
export class ToolNameValidator {
|
|
25
|
+
logger;
|
|
26
|
+
constructor() {
|
|
27
|
+
this.logger = new DebugLogger('llxprt:provider:openai:ToolNameValidator');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validates and normalizes a tool name from qwen model responses
|
|
31
|
+
* Based on subagent.ts normalizeToolName but enhanced for OpenAI provider
|
|
32
|
+
*/
|
|
33
|
+
validateToolName(rawName, detectedFormat, availableToolNames = []) {
|
|
34
|
+
const result = {
|
|
35
|
+
name: '',
|
|
36
|
+
warnings: [],
|
|
37
|
+
isValid: true,
|
|
38
|
+
};
|
|
39
|
+
// Step 1: Handle undefined/null/empty names
|
|
40
|
+
if (!rawName || rawName.trim() === '') {
|
|
41
|
+
result.name = 'undefined_tool_name';
|
|
42
|
+
result.warnings.push('Empty or undefined tool name, using fallback');
|
|
43
|
+
result.isValid = false;
|
|
44
|
+
this.logger.debug(() => `Empty tool name detected, using fallback: ${result.name}`);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
// Step 2: Attempt to normalize and validate against available tools
|
|
48
|
+
const normalized = this.normalizeToolName(rawName);
|
|
49
|
+
if (!normalized) {
|
|
50
|
+
result.name = 'undefined_tool_name';
|
|
51
|
+
result.warnings.push(`Unable to normalize tool name: "${rawName}", using fallback`);
|
|
52
|
+
result.isValid = false;
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
// Step 3: Validate against available tool names if provided
|
|
56
|
+
if (availableToolNames.length > 0) {
|
|
57
|
+
const matchedTool = this.findMatchingTool(normalized, availableToolNames);
|
|
58
|
+
if (matchedTool) {
|
|
59
|
+
result.name = matchedTool;
|
|
60
|
+
if (matchedTool !== rawName) {
|
|
61
|
+
result.warnings.push(`Tool name normalized: "${rawName}" -> "${matchedTool}"`);
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
result.name = 'undefined_tool_name';
|
|
67
|
+
result.warnings.push(`Tool "${normalized}" not found in available tools, using fallback`);
|
|
68
|
+
result.isValid = false;
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Step 4: Return normalized name if no validation against available tools
|
|
73
|
+
result.name = normalized;
|
|
74
|
+
if (normalized !== rawName) {
|
|
75
|
+
result.warnings.push(`Tool name normalized: "${rawName}" -> "${normalized}"`);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Normalize tool name using shared utility function
|
|
81
|
+
*/
|
|
82
|
+
normalizeToolName(name) {
|
|
83
|
+
return normalizeToolName(name);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Find matching tool from available tools with fuzzy matching
|
|
87
|
+
*/
|
|
88
|
+
findMatchingTool = findMatchingTool;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=ToolNameValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolNameValidator.js","sourceRoot":"","sources":["../../../../src/providers/openai/ToolNameValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AAQtC,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAc;IAE5B;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,0CAA0C,CAAC,CAAC;IAC5E,CAAC;IAED;;;OAGG;IACH,gBAAgB,CACd,OAA2B,EAC3B,cAA0B,EAC1B,qBAA+B,EAAE;QAEjC,MAAM,MAAM,GAA6B;YACvC,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,IAAI;SACd,CAAC;QAEF,4CAA4C;QAC5C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,GAAG,qBAAqB,CAAC;YACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YACrE,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,GAAG,EAAE,CAAC,6CAA6C,MAAM,CAAC,IAAI,EAAE,CACjE,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,oEAAoE;QACpE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,GAAG,qBAAqB,CAAC;YACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAClB,mCAAmC,OAAO,mBAAmB,CAC9D,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,4DAA4D;QAC5D,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;YAC1E,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,GAAG,WAAW,CAAC;gBAC1B,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;oBAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAClB,0BAA0B,OAAO,SAAS,WAAW,GAAG,CACzD,CAAC;gBACJ,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,GAAG,qBAAqB,CAAC;gBACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAClB,SAAS,UAAU,gDAAgD,CACpE,CAAC;gBACF,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;gBACvB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,0EAA0E;QAC1E,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC;QACzB,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAClB,0BAA0B,OAAO,SAAS,UAAU,GAAG,CACxD,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,IAAY;QACpC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACK,gBAAgB,GAAG,gBAAgB,CAAC;CAC7C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type AnyObject = Record<string, unknown>;
|
|
2
|
+
export type UnknownArray = unknown[];
|
|
3
|
+
export type MockChunkType = Record<string, unknown>;
|
|
4
|
+
export interface MockResponse {
|
|
5
|
+
choices?: Array<{
|
|
6
|
+
delta?: Record<string, unknown>;
|
|
7
|
+
message?: {
|
|
8
|
+
tool_calls?: Array<Record<string, unknown>>;
|
|
9
|
+
};
|
|
10
|
+
}>;
|
|
11
|
+
usage?: Record<string, unknown>;
|
|
12
|
+
model?: string;
|
|
13
|
+
id?: string;
|
|
14
|
+
object?: string;
|
|
15
|
+
created?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolCallData {
|
|
18
|
+
index?: number;
|
|
19
|
+
id?: string;
|
|
20
|
+
type?: string;
|
|
21
|
+
function?: {
|
|
22
|
+
name?: string;
|
|
23
|
+
arguments?: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface MockToolCall {
|
|
27
|
+
index?: number;
|
|
28
|
+
id?: string;
|
|
29
|
+
type?: string;
|
|
30
|
+
function?: {
|
|
31
|
+
name?: string;
|
|
32
|
+
arguments?: string;
|
|
33
|
+
};
|
|
34
|
+
delta?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
export type StreamChunk = Record<string, unknown>;
|
|
37
|
+
export type MockChunk = Record<string, unknown>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-types.js","sourceRoot":"","sources":["../../../../src/providers/openai/test-types.ts"],"names":[],"mappings":"AAAA,6CAA6C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Vybestack LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Enhances tool name extraction for qwen and other providers that may send tool names in chunks
|
|
18
|
+
* @param currentName Current accumulated tool name
|
|
19
|
+
* @param newName New name chunk from streaming
|
|
20
|
+
* @param isComplete Whether the stream for this tool call is complete
|
|
21
|
+
* @returns Enhanced tool name with fallback strategies
|
|
22
|
+
*/
|
|
23
|
+
export declare function enhanceToolNameExtraction(currentName: string, newName: string | undefined, isComplete: boolean): {
|
|
24
|
+
name: string;
|
|
25
|
+
isFallback: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validates a tool name for consistency with expected tool names
|
|
29
|
+
* @param toolName The tool name to validate
|
|
30
|
+
* @param availableToolNames Array of available tool names
|
|
31
|
+
* @returns Validated tool name or null if invalid
|
|
32
|
+
*/
|
|
33
|
+
export declare function validateToolName(toolName: string, availableToolNames?: string[]): {
|
|
34
|
+
isValid: boolean;
|
|
35
|
+
correctedName?: string;
|
|
36
|
+
reason?: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Processes final tool name validation with comprehensive fallback strategy
|
|
40
|
+
* @param toolName The tool name to process
|
|
41
|
+
* @param availableToolNames Array of available tool names
|
|
42
|
+
* @returns Final validated tool name
|
|
43
|
+
*/
|
|
44
|
+
export declare function processFinalToolName(toolName: string, availableToolNames?: string[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* Safely extracts tool name from streaming delta with comprehensive error handling
|
|
47
|
+
* @param delta The streaming delta object
|
|
48
|
+
* @param currentIndex Current tool call index
|
|
49
|
+
* @param availableToolNames Array of available tool names
|
|
50
|
+
* @returns Safe tool name extraction result
|
|
51
|
+
*/
|
|
52
|
+
export declare function safeExtractToolName(delta: Record<string, unknown>, currentIndex: number, availableToolNames?: string[]): {
|
|
53
|
+
name: string;
|
|
54
|
+
hasName: boolean;
|
|
55
|
+
isComplete: boolean;
|
|
56
|
+
warnings: string[];
|
|
57
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Vybestack LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Utility functions for handling tool names in streaming responses
|
|
18
|
+
* Particularly important for qwen models that may send tool names in separate chunks
|
|
19
|
+
*/
|
|
20
|
+
import { DebugLogger } from '../../debug/index.js';
|
|
21
|
+
const logger = new DebugLogger('llxprt:providers:openai:toolNameUtils');
|
|
22
|
+
/**
|
|
23
|
+
* Enhances tool name extraction for qwen and other providers that may send tool names in chunks
|
|
24
|
+
* @param currentName Current accumulated tool name
|
|
25
|
+
* @param newName New name chunk from streaming
|
|
26
|
+
* @param isComplete Whether the stream for this tool call is complete
|
|
27
|
+
* @returns Enhanced tool name with fallback strategies
|
|
28
|
+
*/
|
|
29
|
+
export function enhanceToolNameExtraction(currentName, newName, isComplete) {
|
|
30
|
+
// If we already have a valid name, keep it
|
|
31
|
+
if (currentName && currentName.trim()) {
|
|
32
|
+
return { name: currentName.trim(), isFallback: false };
|
|
33
|
+
}
|
|
34
|
+
// Try to use the new name chunk
|
|
35
|
+
if (newName && newName.trim()) {
|
|
36
|
+
return { name: newName.trim(), isFallback: false };
|
|
37
|
+
}
|
|
38
|
+
// If stream is complete and we still don't have a name, this is an issue
|
|
39
|
+
if (isComplete && !currentName && !newName) {
|
|
40
|
+
logger.error(() => 'Tool name extraction failed - no name found in streaming chunks', {
|
|
41
|
+
currentName,
|
|
42
|
+
newName,
|
|
43
|
+
isComplete,
|
|
44
|
+
});
|
|
45
|
+
// Use a more specific fallback that indicates the real issue
|
|
46
|
+
return {
|
|
47
|
+
name: 'missing_tool_name_check_stream_chunks',
|
|
48
|
+
isFallback: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Still streaming, return empty for now
|
|
52
|
+
return { name: currentName || '', isFallback: false };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validates a tool name for consistency with expected tool names
|
|
56
|
+
* @param toolName The tool name to validate
|
|
57
|
+
* @param availableToolNames Array of available tool names
|
|
58
|
+
* @returns Validated tool name or null if invalid
|
|
59
|
+
*/
|
|
60
|
+
export function validateToolName(toolName, availableToolNames = []) {
|
|
61
|
+
if (!toolName || !toolName.trim()) {
|
|
62
|
+
return {
|
|
63
|
+
isValid: false,
|
|
64
|
+
reason: 'Tool name is empty or missing',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const trimmedName = toolName.trim();
|
|
68
|
+
// Direct match
|
|
69
|
+
if (availableToolNames.includes(trimmedName)) {
|
|
70
|
+
return { isValid: true, correctedName: trimmedName };
|
|
71
|
+
}
|
|
72
|
+
// Case-insensitive match
|
|
73
|
+
const caseInsensitiveMatch = availableToolNames.find((availableName) => availableName.toLowerCase() === trimmedName.toLowerCase());
|
|
74
|
+
if (caseInsensitiveMatch) {
|
|
75
|
+
logger.debug(() => `Tool name case correction: '${trimmedName}' -> '${caseInsensitiveMatch}'`, {
|
|
76
|
+
originalName: trimmedName,
|
|
77
|
+
correctedName: caseInsensitiveMatch,
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
isValid: true,
|
|
81
|
+
correctedName: caseInsensitiveMatch,
|
|
82
|
+
reason: 'Case-insensitive match applied',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Partial match (for names that might be truncated)
|
|
86
|
+
const partialMatch = availableToolNames.find((availableName) => availableName.startsWith(trimmedName) ||
|
|
87
|
+
trimmedName.startsWith(availableName));
|
|
88
|
+
if (partialMatch &&
|
|
89
|
+
(availableToolNames.length === 1 || trimmedName.length > 3)) {
|
|
90
|
+
logger.debug(() => `Tool name partial match correction: '${trimmedName}' -> '${partialMatch}'`, {
|
|
91
|
+
originalName: trimmedName,
|
|
92
|
+
correctedName: partialMatch,
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
isValid: true,
|
|
96
|
+
correctedName: partialMatch,
|
|
97
|
+
reason: 'Partial match applied',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// Name is not found in available tools
|
|
101
|
+
return {
|
|
102
|
+
isValid: false,
|
|
103
|
+
reason: `Tool name '${trimmedName}' not found in available tools: [${availableToolNames.join(', ')}]`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Processes final tool name validation with comprehensive fallback strategy
|
|
108
|
+
* @param toolName The tool name to process
|
|
109
|
+
* @param availableToolNames Array of available tool names
|
|
110
|
+
* @returns Final validated tool name
|
|
111
|
+
*/
|
|
112
|
+
export function processFinalToolName(toolName, availableToolNames = []) {
|
|
113
|
+
// First, validate against available tools
|
|
114
|
+
const validation = validateToolName(toolName, availableToolNames);
|
|
115
|
+
if (validation.isValid && validation.correctedName) {
|
|
116
|
+
return validation.correctedName;
|
|
117
|
+
}
|
|
118
|
+
// If validation failed, log the issue and return a more informative fallback
|
|
119
|
+
logger.error(() => 'Tool name validation failed, using enhanced fallback', {
|
|
120
|
+
originalName: toolName,
|
|
121
|
+
availableToolNames,
|
|
122
|
+
reason: validation.reason,
|
|
123
|
+
});
|
|
124
|
+
// Use a more descriptive fallback that includes debugging information
|
|
125
|
+
const fallbackName = toolName && toolName.trim()
|
|
126
|
+
? `tool_name_not_found_${toolName.replace(/[^a-zA-Z0-9]/g, '_')}`
|
|
127
|
+
: 'missing_tool_name';
|
|
128
|
+
return fallbackName;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Safely extracts tool name from streaming delta with comprehensive error handling
|
|
132
|
+
* @param delta The streaming delta object
|
|
133
|
+
* @param currentIndex Current tool call index
|
|
134
|
+
* @param availableToolNames Array of available tool names
|
|
135
|
+
* @returns Safe tool name extraction result
|
|
136
|
+
*/
|
|
137
|
+
export function safeExtractToolName(delta, currentIndex, availableToolNames = []) {
|
|
138
|
+
const warnings = [];
|
|
139
|
+
let hasName = false;
|
|
140
|
+
let isComplete = false;
|
|
141
|
+
// Extract name from various delta structures
|
|
142
|
+
let extractedName = '';
|
|
143
|
+
// Standard OpenAI format
|
|
144
|
+
if (delta?.function &&
|
|
145
|
+
typeof delta.function === 'object' &&
|
|
146
|
+
'name' in delta.function) {
|
|
147
|
+
extractedName = String(delta.function.name);
|
|
148
|
+
hasName = true;
|
|
149
|
+
}
|
|
150
|
+
// Alternative format (some providers use different structures)
|
|
151
|
+
if (!extractedName && 'name' in delta) {
|
|
152
|
+
extractedName = String(delta.name);
|
|
153
|
+
hasName = true;
|
|
154
|
+
}
|
|
155
|
+
// Check if this is a completion signal
|
|
156
|
+
if (delta?.finish_reason === 'tool_calls' ||
|
|
157
|
+
(currentIndex >= 0 && delta?.index !== undefined)) {
|
|
158
|
+
isComplete = true;
|
|
159
|
+
}
|
|
160
|
+
// Validate the extracted name
|
|
161
|
+
if (hasName) {
|
|
162
|
+
const validation = validateToolName(extractedName, availableToolNames);
|
|
163
|
+
if (!validation.isValid) {
|
|
164
|
+
warnings.push(validation.reason || 'Unknown validation error');
|
|
165
|
+
extractedName = processFinalToolName(extractedName, availableToolNames);
|
|
166
|
+
}
|
|
167
|
+
else if (validation.correctedName &&
|
|
168
|
+
validation.correctedName !== extractedName) {
|
|
169
|
+
warnings.push(validation.reason || 'Name was corrected');
|
|
170
|
+
extractedName = validation.correctedName;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
name: extractedName,
|
|
175
|
+
hasName,
|
|
176
|
+
isComplete,
|
|
177
|
+
warnings,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=toolNameUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolNameUtils.js","sourceRoot":"","sources":["../../../../src/providers/openai/toolNameUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,uCAAuC,CAAC,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CACvC,WAAmB,EACnB,OAA2B,EAC3B,UAAmB;IAEnB,2CAA2C;IAC3C,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACrD,CAAC;IAED,yEAAyE;IACzE,IAAI,UAAU,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,CACV,GAAG,EAAE,CAAC,iEAAiE,EACvE;YACE,WAAW;YACX,OAAO;YACP,UAAU;SACX,CACF,CAAC;QAEF,6DAA6D;QAC7D,OAAO;YACL,IAAI,EAAE,uCAAuC;YAC7C,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,OAAO,EAAE,IAAI,EAAE,WAAW,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,qBAA+B,EAAE;IAEjC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,+BAA+B;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEpC,eAAe;IACf,IAAI,kBAAkB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IACvD,CAAC;IAED,yBAAyB;IACzB,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,IAAI,CAClD,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAC5D,CAAC;IACF,IAAI,oBAAoB,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,CACV,GAAG,EAAE,CACH,+BAA+B,WAAW,SAAS,oBAAoB,GAAG,EAC5E;YACE,YAAY,EAAE,WAAW;YACzB,aAAa,EAAE,oBAAoB;SACpC,CACF,CAAC;QACF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,oBAAoB;YACnC,MAAM,EAAE,gCAAgC;SACzC,CAAC;IACJ,CAAC;IAED,oDAAoD;IACpD,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAC1C,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,UAAU,CAAC,WAAW,CAAC;QACrC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CACxC,CAAC;IACF,IACE,YAAY;QACZ,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,EAC3D,CAAC;QACD,MAAM,CAAC,KAAK,CACV,GAAG,EAAE,CACH,wCAAwC,WAAW,SAAS,YAAY,GAAG,EAC7E;YACE,YAAY,EAAE,WAAW;YACzB,aAAa,EAAE,YAAY;SAC5B,CACF,CAAC;QACF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,YAAY;YAC3B,MAAM,EAAE,uBAAuB;SAChC,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,cAAc,WAAW,oCAAoC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KACtG,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,qBAA+B,EAAE;IAEjC,0CAA0C;IAC1C,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IAElE,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC;QACnD,OAAO,UAAU,CAAC,aAAa,CAAC;IAClC,CAAC;IAED,6EAA6E;IAC7E,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,sDAAsD,EAAE;QACzE,YAAY,EAAE,QAAQ;QACtB,kBAAkB;QAClB,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC,CAAC;IAEH,sEAAsE;IACtE,MAAM,YAAY,GAChB,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE;QACzB,CAAC,CAAC,uBAAuB,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE;QACjE,CAAC,CAAC,mBAAmB,CAAC;IAE1B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAA8B,EAC9B,YAAoB,EACpB,qBAA+B,EAAE;IAOjC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,6CAA6C;IAC7C,IAAI,aAAa,GAAG,EAAE,CAAC;IAEvB,yBAAyB;IACzB,IACE,KAAK,EAAE,QAAQ;QACf,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,MAAM,IAAI,KAAK,CAAC,QAAQ,EACxB,CAAC;QACD,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QACtC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,uCAAuC;IACvC,IACE,KAAK,EAAE,aAAa,KAAK,YAAY;QACrC,CAAC,YAAY,IAAI,CAAC,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,EACjD,CAAC;QACD,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,gBAAgB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;QAEvE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,0BAA0B,CAAC,CAAC;YAC/D,aAAa,GAAG,oBAAoB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;QAC1E,CAAC;aAAM,IACL,UAAU,CAAC,aAAa;YACxB,UAAU,CAAC,aAAa,KAAK,aAAa,EAC1C,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC;YACzD,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,OAAO;QACP,UAAU;QACV,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -69,6 +69,12 @@ export interface IProviderConfig {
|
|
|
69
69
|
* Whether to enable OpenAI Responses API for compatible models.
|
|
70
70
|
*/
|
|
71
71
|
openaiResponsesEnabled?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Tool call processing mode for OpenAI provider.
|
|
74
|
+
* - 'pipeline': Use optimized tool call pipeline (default)
|
|
75
|
+
* - 'legacy': Use original accumulated tool calls approach
|
|
76
|
+
*/
|
|
77
|
+
toolCallProcessingMode?: 'pipeline' | 'legacy';
|
|
72
78
|
/**
|
|
73
79
|
* Organization ID for providers that support organization-level access.
|
|
74
80
|
*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Config } from '../../config/config.js';
|
|
7
|
+
import type { ToolResponseBlock } from '../../services/history/IContent.js';
|
|
8
|
+
export interface ToolResponsePayload {
|
|
9
|
+
status: 'success' | 'error';
|
|
10
|
+
toolName?: string;
|
|
11
|
+
result: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
truncated?: boolean;
|
|
14
|
+
originalLength?: number;
|
|
15
|
+
limitMessage?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const EMPTY_TOOL_RESULT_PLACEHOLDER = "[no tool result]";
|
|
18
|
+
export declare function buildToolResponsePayload(block: ToolResponseBlock, config?: Config): ToolResponsePayload;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { limitOutputTokens } from '../../utils/toolOutputLimiter.js';
|
|
7
|
+
import { ensureJsonSafe, hasUnicodeReplacements, } from '../../utils/unicodeUtils.js';
|
|
8
|
+
export const EMPTY_TOOL_RESULT_PLACEHOLDER = '[no tool result]';
|
|
9
|
+
const MAX_TOOL_RESPONSE_CHARS = 1024;
|
|
10
|
+
const MAX_TOOL_RESPONSE_TEXT_CHARS = 512;
|
|
11
|
+
function coerceToString(value) {
|
|
12
|
+
if (typeof value === 'string') {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
try {
|
|
20
|
+
return String(value);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return '[unserializable value]';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function sanitizeResultString(result) {
|
|
28
|
+
const sanitized = hasUnicodeReplacements(result)
|
|
29
|
+
? ensureJsonSafe(result)
|
|
30
|
+
: result;
|
|
31
|
+
if (sanitized.length <= MAX_TOOL_RESPONSE_CHARS) {
|
|
32
|
+
return {
|
|
33
|
+
text: sanitized,
|
|
34
|
+
truncated: false,
|
|
35
|
+
originalLength: sanitized.length,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const truncatedText = `${sanitized.slice(0, MAX_TOOL_RESPONSE_CHARS)}… [truncated ${sanitized.length - MAX_TOOL_RESPONSE_CHARS} chars]`;
|
|
39
|
+
return {
|
|
40
|
+
text: truncatedText,
|
|
41
|
+
truncated: true,
|
|
42
|
+
originalLength: sanitized.length,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function limitToolResponseText(text) {
|
|
46
|
+
let limited = text;
|
|
47
|
+
let truncated = false;
|
|
48
|
+
const originalLength = text.length;
|
|
49
|
+
const lines = limited.split('\n');
|
|
50
|
+
if (lines.length > 1) {
|
|
51
|
+
limited = `${lines[0]}\n[+${lines.length - 1} more lines omitted]`;
|
|
52
|
+
truncated = true;
|
|
53
|
+
}
|
|
54
|
+
if (limited.length > MAX_TOOL_RESPONSE_TEXT_CHARS) {
|
|
55
|
+
limited = `${limited.slice(0, MAX_TOOL_RESPONSE_TEXT_CHARS)}… [truncated ${limited.length - MAX_TOOL_RESPONSE_TEXT_CHARS} chars]`;
|
|
56
|
+
truncated = true;
|
|
57
|
+
}
|
|
58
|
+
return { value: limited, truncated, originalLength };
|
|
59
|
+
}
|
|
60
|
+
function formatToolResult(result) {
|
|
61
|
+
if (result === undefined || result === null) {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
if (typeof result === 'string') {
|
|
65
|
+
const limited = limitToolResponseText(result);
|
|
66
|
+
return { ...limited, raw: result };
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const serialized = JSON.stringify(result);
|
|
70
|
+
return { value: serialized, raw: serialized };
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
const coerced = coerceToString(result);
|
|
74
|
+
return { value: coerced, raw: coerced };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function limitToolPayload(serializedResult, block, config) {
|
|
78
|
+
if (!serializedResult) {
|
|
79
|
+
return {
|
|
80
|
+
text: EMPTY_TOOL_RESULT_PLACEHOLDER,
|
|
81
|
+
truncated: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (!config) {
|
|
85
|
+
const normalized = sanitizeResultString(serializedResult);
|
|
86
|
+
return {
|
|
87
|
+
text: normalized.text,
|
|
88
|
+
truncated: normalized.truncated,
|
|
89
|
+
originalLength: normalized.originalLength,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const limited = limitOutputTokens(serializedResult, config, block.toolName ?? 'tool_response');
|
|
93
|
+
const candidate = limited.content || limited.message || EMPTY_TOOL_RESULT_PLACEHOLDER;
|
|
94
|
+
const normalized = sanitizeResultString(candidate);
|
|
95
|
+
return {
|
|
96
|
+
text: normalized.text,
|
|
97
|
+
truncated: limited.wasTruncated || normalized.truncated,
|
|
98
|
+
originalLength: normalized.originalLength,
|
|
99
|
+
limitMessage: limited.wasTruncated ? limited.message : undefined,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function buildToolResponsePayload(block, config) {
|
|
103
|
+
const payload = {
|
|
104
|
+
status: block.error ? 'error' : 'success',
|
|
105
|
+
toolName: block.toolName,
|
|
106
|
+
result: EMPTY_TOOL_RESULT_PLACEHOLDER,
|
|
107
|
+
};
|
|
108
|
+
const formatted = formatToolResult(block.result);
|
|
109
|
+
const serializedResult = config && formatted.raw ? formatted.raw : formatted.value;
|
|
110
|
+
if (serializedResult) {
|
|
111
|
+
const limited = limitToolPayload(serializedResult, block, config);
|
|
112
|
+
payload.result = limited.text;
|
|
113
|
+
if (limited.truncated) {
|
|
114
|
+
payload.truncated = true;
|
|
115
|
+
payload.originalLength = limited.originalLength;
|
|
116
|
+
}
|
|
117
|
+
if (limited.limitMessage) {
|
|
118
|
+
payload.limitMessage = limited.limitMessage;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (formatted.truncated) {
|
|
122
|
+
payload.truncated = true;
|
|
123
|
+
payload.originalLength = formatted.originalLength ?? payload.originalLength;
|
|
124
|
+
}
|
|
125
|
+
if (block.error) {
|
|
126
|
+
payload.error = coerceToString(block.error);
|
|
127
|
+
}
|
|
128
|
+
return payload;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=toolResponsePayload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolResponsePayload.js","sourceRoot":"","sources":["../../../../src/providers/utils/toolResponsePayload.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { createProviderAdapterFromManager, createTelemetryAdapterFromConfig, } f
|
|
|
8
8
|
import { createAgentRuntimeContext } from './createAgentRuntimeContext.js';
|
|
9
9
|
import { createContentGenerator, } from '../core/contentGenerator.js';
|
|
10
10
|
const defaultContentGeneratorFactory = (contentConfig, config, sessionId) => createContentGenerator(contentConfig, config, sessionId);
|
|
11
|
-
|
|
11
|
+
import { normalizeToolName } from '../tools/toolNameUtils.js';
|
|
12
12
|
function buildToolGovernance(profile) {
|
|
13
13
|
const allowedRaw = Array.isArray(profile.settings.tools?.allowed)
|
|
14
14
|
? profile.settings.tools?.allowed
|
|
@@ -18,13 +18,13 @@ function buildToolGovernance(profile) {
|
|
|
18
18
|
: undefined;
|
|
19
19
|
const excludedRaw = profile.config.getExcludeTools?.() ?? [];
|
|
20
20
|
return {
|
|
21
|
-
allowed: new Set((allowedRaw ?? []).map((tool) => normalizeToolName(tool))),
|
|
22
|
-
disabled: new Set((disabledRaw ?? []).map((tool) => normalizeToolName(tool))),
|
|
23
|
-
excluded: new Set(excludedRaw.map((tool) => normalizeToolName(tool))),
|
|
21
|
+
allowed: new Set((allowedRaw ?? []).map((tool) => normalizeToolName(tool) || tool)),
|
|
22
|
+
disabled: new Set((disabledRaw ?? []).map((tool) => normalizeToolName(tool) || tool)),
|
|
23
|
+
excluded: new Set(excludedRaw.map((tool) => normalizeToolName(tool) || tool)),
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
function isToolPermitted(toolName, governance) {
|
|
27
|
-
const canonical = normalizeToolName(toolName);
|
|
27
|
+
const canonical = normalizeToolName(toolName) || toolName;
|
|
28
28
|
if (governance.excluded.has(canonical)) {
|
|
29
29
|
return false;
|
|
30
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentRuntimeLoader.js","sourceRoot":"","sources":["../../../src/runtime/AgentRuntimeLoader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAKvE,OAAO,EACL,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAS9B,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,OAAO,EACL,sBAAsB,GAGvB,MAAM,6BAA6B,CAAC;AA2CrC,MAAM,8BAA8B,GAA4B,CAC9D,aAAa,EACb,MAAM,EACN,SAAS,EACT,EAAE,CAAC,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAE9D,
|
|
1
|
+
{"version":3,"file":"AgentRuntimeLoader.js","sourceRoot":"","sources":["../../../src/runtime/AgentRuntimeLoader.ts"],"names":[],"mappings":"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"}
|