@vybestack/llxprt-code-core 0.8.0-nightly.260113.48db4b09b → 0.8.0-nightly.260113.cd34be5f1
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.
|
@@ -7,8 +7,24 @@ import { type ToolCallRequestInfo } from '../index.js';
|
|
|
7
7
|
import { type Config } from '../config/config.js';
|
|
8
8
|
import { type CompletedToolCall } from './coreToolScheduler.js';
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
* It does not handle confirmations, multiple calls, or live updates.
|
|
10
|
+
* Configuration subset required for non-interactive tool execution.
|
|
12
11
|
*/
|
|
13
12
|
export type ToolExecutionConfig = Pick<Config, 'getToolRegistry' | 'getEphemeralSettings' | 'getEphemeralSetting' | 'getExcludeTools' | 'getSessionId' | 'getTelemetryLogPromptsEnabled'> & Partial<Pick<Config, 'getAllowedTools' | 'getApprovalMode' | 'getMessageBus' | 'getPolicyEngine'>>;
|
|
13
|
+
/**
|
|
14
|
+
* Executes a single tool call non-interactively by leveraging the CoreToolScheduler.
|
|
15
|
+
*
|
|
16
|
+
* This is a thin wrapper that:
|
|
17
|
+
* 1. Creates a temporary CoreToolScheduler with a non-interactive PolicyEngine
|
|
18
|
+
* 2. Schedules the tool call
|
|
19
|
+
* 3. Returns the completed result
|
|
20
|
+
*
|
|
21
|
+
* Non-interactive mode means:
|
|
22
|
+
* - Tools that require user approval (ASK_USER) are automatically rejected as policy violations
|
|
23
|
+
* (handled by PolicyEngine with nonInteractive: true)
|
|
24
|
+
* - No live output updates are provided
|
|
25
|
+
* - The scheduler is disposed after execution
|
|
26
|
+
*
|
|
27
|
+
* Note: Emoji filtering is handled by the individual tools (edit.ts, write-file.ts)
|
|
28
|
+
* so it is not duplicated here.
|
|
29
|
+
*/
|
|
14
30
|
export declare function executeToolCall(config: ToolExecutionConfig, toolCallRequest: ToolCallRequestInfo, abortSignal?: AbortSignal): Promise<CompletedToolCall>;
|
|
@@ -9,88 +9,23 @@ import { MessageBus } from '../confirmation-bus/message-bus.js';
|
|
|
9
9
|
import { PolicyEngine } from '../policy/policy-engine.js';
|
|
10
10
|
import { PolicyDecision } from '../policy/types.js';
|
|
11
11
|
import { CoreToolScheduler, } from './coreToolScheduler.js';
|
|
12
|
-
import { EmojiFilter } from '../filters/EmojiFilter.js';
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
13
|
+
* Executes a single tool call non-interactively by leveraging the CoreToolScheduler.
|
|
14
|
+
*
|
|
15
|
+
* This is a thin wrapper that:
|
|
16
|
+
* 1. Creates a temporary CoreToolScheduler with a non-interactive PolicyEngine
|
|
17
|
+
* 2. Schedules the tool call
|
|
18
|
+
* 3. Returns the completed result
|
|
19
|
+
*
|
|
20
|
+
* Non-interactive mode means:
|
|
21
|
+
* - Tools that require user approval (ASK_USER) are automatically rejected as policy violations
|
|
22
|
+
* (handled by PolicyEngine with nonInteractive: true)
|
|
23
|
+
* - No live output updates are provided
|
|
24
|
+
* - The scheduler is disposed after execution
|
|
25
|
+
*
|
|
26
|
+
* Note: Emoji filtering is handled by the individual tools (edit.ts, write-file.ts)
|
|
27
|
+
* so it is not duplicated here.
|
|
15
28
|
*/
|
|
16
|
-
let emojiFilter = null;
|
|
17
|
-
/**
|
|
18
|
-
* Gets or creates the emoji filter instance based on current configuration
|
|
19
|
-
* Always checks current configuration to ensure filter is up-to-date
|
|
20
|
-
*/
|
|
21
|
-
function getOrCreateFilter(config) {
|
|
22
|
-
// Get emojifilter from ephemeral settings or default to 'auto'
|
|
23
|
-
const mode = config.getEphemeralSetting('emojifilter') || 'auto';
|
|
24
|
-
/**
|
|
25
|
-
* @requirement REQ-004.1 - Silent filtering in auto mode
|
|
26
|
-
* Use mode directly from settings
|
|
27
|
-
*/
|
|
28
|
-
const filterMode = mode;
|
|
29
|
-
// Always create a new filter to ensure current configuration is applied
|
|
30
|
-
// Tool execution is infrequent enough that this performance cost is acceptable
|
|
31
|
-
const filterConfig = { mode: filterMode };
|
|
32
|
-
emojiFilter = new EmojiFilter(filterConfig);
|
|
33
|
-
return emojiFilter;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Filters file modification tool arguments
|
|
37
|
-
*/
|
|
38
|
-
function filterFileModificationArgs(filter, toolName, args) {
|
|
39
|
-
// Never filter file paths - they might legitimately contain emojis
|
|
40
|
-
// Only filter the content being written to files
|
|
41
|
-
if (toolName === 'edit_file' ||
|
|
42
|
-
toolName === 'edit' ||
|
|
43
|
-
toolName === 'replace' ||
|
|
44
|
-
toolName === 'replace_all') {
|
|
45
|
-
const oldString = args?.old_string;
|
|
46
|
-
const newString = args?.new_string;
|
|
47
|
-
// CRITICAL: Never filter old_string - it must match exactly what's in the file
|
|
48
|
-
// Only filter new_string to prevent emojis from being written
|
|
49
|
-
const newResult = filter.filterFileContent(newString, toolName);
|
|
50
|
-
if (newResult.blocked) {
|
|
51
|
-
return {
|
|
52
|
-
filtered: null,
|
|
53
|
-
emojiDetected: true,
|
|
54
|
-
blocked: true,
|
|
55
|
-
error: 'Cannot write emojis to code files',
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
filtered: {
|
|
60
|
-
...args,
|
|
61
|
-
// Preserve file_path unchanged - never filter paths
|
|
62
|
-
file_path: args.file_path,
|
|
63
|
-
// MUST preserve old_string exactly for matching
|
|
64
|
-
old_string: oldString,
|
|
65
|
-
// Filter new_string to remove emojis
|
|
66
|
-
new_string: newResult.filtered,
|
|
67
|
-
},
|
|
68
|
-
emojiDetected: newResult.emojiDetected,
|
|
69
|
-
blocked: false,
|
|
70
|
-
systemFeedback: newResult.systemFeedback,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
if (toolName === 'write_file' || toolName === 'create_file') {
|
|
74
|
-
const content = args.content;
|
|
75
|
-
const result = filter.filterFileContent(content, toolName);
|
|
76
|
-
if (result.blocked) {
|
|
77
|
-
return result;
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
filtered: {
|
|
81
|
-
...args,
|
|
82
|
-
// Preserve file_path unchanged - never filter paths
|
|
83
|
-
file_path: args.file_path,
|
|
84
|
-
content: result.filtered,
|
|
85
|
-
},
|
|
86
|
-
emojiDetected: result.emojiDetected,
|
|
87
|
-
blocked: false,
|
|
88
|
-
systemFeedback: result.systemFeedback,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
// Fallback for other tools
|
|
92
|
-
return filter.filterToolArgs(args);
|
|
93
|
-
}
|
|
94
29
|
export async function executeToolCall(config, toolCallRequest, abortSignal) {
|
|
95
30
|
const startTime = Date.now();
|
|
96
31
|
const agentId = toolCallRequest.agentId ?? DEFAULT_AGENT_ID;
|
|
@@ -104,26 +39,11 @@ export async function executeToolCall(config, toolCallRequest, abortSignal) {
|
|
|
104
39
|
abortSignal.addEventListener('abort', () => internalAbortController.abort(), { once: true });
|
|
105
40
|
}
|
|
106
41
|
}
|
|
107
|
-
const filter = getOrCreateFilter(config);
|
|
108
|
-
let filteredRequest = toolCallRequest;
|
|
109
|
-
let systemFeedback;
|
|
110
|
-
try {
|
|
111
|
-
const filtered = applyEmojiFiltering(filter, toolCallRequest);
|
|
112
|
-
filteredRequest = filtered.filteredRequest;
|
|
113
|
-
systemFeedback = filtered.systemFeedback;
|
|
114
|
-
}
|
|
115
|
-
catch (e) {
|
|
116
|
-
return createErrorCompletedToolCall(toolCallRequest, e instanceof Error ? e : new Error(String(e)), ToolErrorType.INVALID_TOOL_PARAMS, Date.now() - startTime);
|
|
117
|
-
}
|
|
118
42
|
const schedulerConfig = createSchedulerConfigForNonInteractive(config);
|
|
119
43
|
let completionResolver = null;
|
|
120
44
|
const completionPromise = new Promise((resolve) => {
|
|
121
45
|
completionResolver = resolve;
|
|
122
46
|
});
|
|
123
|
-
let awaitingApprovalResolver = null;
|
|
124
|
-
const awaitingApprovalPromise = new Promise((resolve) => {
|
|
125
|
-
awaitingApprovalResolver = resolve;
|
|
126
|
-
});
|
|
127
47
|
const scheduler = new CoreToolScheduler({
|
|
128
48
|
config: schedulerConfig,
|
|
129
49
|
toolContextInteractiveMode: false,
|
|
@@ -132,42 +52,15 @@ export async function executeToolCall(config, toolCallRequest, abortSignal) {
|
|
|
132
52
|
onAllToolCallsComplete: async (completedToolCalls) => {
|
|
133
53
|
completionResolver?.(completedToolCalls);
|
|
134
54
|
},
|
|
135
|
-
onToolCallsUpdate: (toolCalls) => {
|
|
136
|
-
try {
|
|
137
|
-
const awaiting = toolCalls.find((call) => call.status === 'awaiting_approval');
|
|
138
|
-
if (awaiting && awaitingApprovalResolver) {
|
|
139
|
-
awaitingApprovalResolver(awaiting);
|
|
140
|
-
awaitingApprovalResolver = null;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
// Callback must be non-throwing.
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
55
|
});
|
|
148
56
|
try {
|
|
149
57
|
const effectiveSignal = internalAbortController.signal;
|
|
150
|
-
await scheduler.schedule([
|
|
151
|
-
const
|
|
152
|
-
completionPromise.then((calls) => ({ kind: 'complete', calls })),
|
|
153
|
-
awaitingApprovalPromise.then((call) => ({
|
|
154
|
-
kind: 'awaiting',
|
|
155
|
-
call,
|
|
156
|
-
})),
|
|
157
|
-
]);
|
|
158
|
-
if (raceResult.kind === 'awaiting') {
|
|
159
|
-
internalAbortController.abort();
|
|
160
|
-
scheduler.cancelAll();
|
|
161
|
-
return createErrorCompletedToolCall(toolCallRequest, new Error('Non-interactive tool execution reached awaiting_approval; treat as policy denial (no user interaction is possible).'), ToolErrorType.POLICY_VIOLATION, Date.now() - startTime);
|
|
162
|
-
}
|
|
163
|
-
const completedCalls = raceResult.calls;
|
|
58
|
+
await scheduler.schedule([toolCallRequest], effectiveSignal);
|
|
59
|
+
const completedCalls = await completionPromise;
|
|
164
60
|
if (completedCalls.length !== 1) {
|
|
165
61
|
throw new Error('Non-interactive executor expects exactly one tool call');
|
|
166
62
|
}
|
|
167
63
|
const completed = completedCalls[0];
|
|
168
|
-
if (systemFeedback) {
|
|
169
|
-
appendSystemFeedbackToResponse(completed.response, systemFeedback);
|
|
170
|
-
}
|
|
171
64
|
if (!completed.response.agentId) {
|
|
172
65
|
completed.response.agentId = agentId;
|
|
173
66
|
}
|
|
@@ -183,52 +76,10 @@ export async function executeToolCall(config, toolCallRequest, abortSignal) {
|
|
|
183
76
|
scheduler.dispose();
|
|
184
77
|
}
|
|
185
78
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
'exec',
|
|
191
|
-
'run_shell_command',
|
|
192
|
-
'grep',
|
|
193
|
-
'search_file_content',
|
|
194
|
-
'glob',
|
|
195
|
-
'find',
|
|
196
|
-
'ls',
|
|
197
|
-
'list_directory',
|
|
198
|
-
'read_file',
|
|
199
|
-
'read_many_files',
|
|
200
|
-
].includes(request.name);
|
|
201
|
-
if (isSearchTool) {
|
|
202
|
-
return { filteredRequest: request };
|
|
203
|
-
}
|
|
204
|
-
const isFileModTool = [
|
|
205
|
-
'edit_file',
|
|
206
|
-
'edit',
|
|
207
|
-
'write_file',
|
|
208
|
-
'create_file',
|
|
209
|
-
'replace',
|
|
210
|
-
'replace_all',
|
|
211
|
-
].includes(request.name);
|
|
212
|
-
const filterResult = isFileModTool
|
|
213
|
-
? filterFileModificationArgs(filter, request.name, request.args)
|
|
214
|
-
: filter.filterToolArgs(request.args);
|
|
215
|
-
if (filterResult.blocked) {
|
|
216
|
-
throw new Error(filterResult.error || 'Tool execution blocked');
|
|
217
|
-
}
|
|
218
|
-
const filteredArgs = filterResult.filtered !== null && typeof filterResult.filtered === 'object'
|
|
219
|
-
? filterResult.filtered
|
|
220
|
-
: request.args;
|
|
221
|
-
if (filteredArgs === request.args && !filterResult.systemFeedback) {
|
|
222
|
-
return { filteredRequest: request };
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
filteredRequest: {
|
|
226
|
-
...request,
|
|
227
|
-
args: filteredArgs,
|
|
228
|
-
},
|
|
229
|
-
systemFeedback: filterResult.systemFeedback,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
79
|
+
/**
|
|
80
|
+
* Creates a PolicyEngine configured for non-interactive mode.
|
|
81
|
+
* In non-interactive mode, ASK_USER decisions are converted to DENY.
|
|
82
|
+
*/
|
|
232
83
|
function createNonInteractivePolicyEngine(policyEngine) {
|
|
233
84
|
if (!policyEngine) {
|
|
234
85
|
return new PolicyEngine({
|
|
@@ -292,24 +143,4 @@ function createErrorCompletedToolCall(request, error, errorType, durationMs) {
|
|
|
292
143
|
durationMs,
|
|
293
144
|
};
|
|
294
145
|
}
|
|
295
|
-
function appendSystemFeedbackToResponse(response, systemFeedback) {
|
|
296
|
-
const reminder = `\n\n<system-reminder>\n${systemFeedback}\n</system-reminder>`;
|
|
297
|
-
if (response.error) {
|
|
298
|
-
response.error = new Error(`${response.error.message}${reminder}`);
|
|
299
|
-
if (response.resultDisplay) {
|
|
300
|
-
response.resultDisplay = `${response.resultDisplay}${reminder}`;
|
|
301
|
-
}
|
|
302
|
-
const functionResponsePart = response.responseParts.find((part) => part.functionResponse?.response);
|
|
303
|
-
const responseObj = functionResponsePart?.functionResponse?.response;
|
|
304
|
-
if (responseObj && typeof responseObj.error === 'string') {
|
|
305
|
-
responseObj.error = `${responseObj.error}${reminder}`;
|
|
306
|
-
}
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
const functionResponsePart = response.responseParts.find((part) => part.functionResponse?.response);
|
|
310
|
-
const responseObj = functionResponsePart?.functionResponse?.response;
|
|
311
|
-
if (responseObj && typeof responseObj.output === 'string') {
|
|
312
|
-
responseObj.output = `${responseObj.output}${reminder}`;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
146
|
//# sourceMappingURL=nonInteractiveToolExecutor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nonInteractiveToolExecutor.js","sourceRoot":"","sources":["../../../src/core/nonInteractiveToolExecutor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"nonInteractiveToolExecutor.js","sourceRoot":"","sources":["../../../src/core/nonInteractiveToolExecutor.ts"],"names":[],"mappings":"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"}
|