@tencent-ai/agent-sdk 0.3.10 → 0.3.12
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/cli/CHANGELOG.md +23 -0
- package/cli/dist/codebuddy.js +4 -4
- package/cli/package.json +1 -1
- package/cli/product.cloudhosted.json +2 -2
- package/cli/product.internal.json +2 -2
- package/cli/product.ioa.json +2 -2
- package/cli/product.json +2 -2
- package/cli/product.selfhosted.json +2 -2
- package/lib/acp/agent.d.ts +226 -11
- package/lib/acp/agent.d.ts.map +1 -1
- package/lib/acp/agent.js +302 -21
- package/lib/acp/agent.js.map +1 -1
- package/lib/acp/converter.d.ts +77 -0
- package/lib/acp/converter.d.ts.map +1 -0
- package/lib/acp/converter.js +613 -0
- package/lib/acp/converter.js.map +1 -0
- package/lib/acp/index.d.ts +4 -14
- package/lib/acp/index.d.ts.map +1 -1
- package/lib/acp/index.js +4 -15
- package/lib/acp/index.js.map +1 -1
- package/lib/index.d.ts +4 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -4
- package/lib/index.js.map +1 -1
- package/lib/session.d.ts +13 -9
- package/lib/session.d.ts.map +1 -1
- package/lib/session.js +18 -107
- package/lib/session.js.map +1 -1
- package/lib/types.d.ts +15 -7
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/package.json +1 -1
- package/lib/acp/tool-converter.d.ts +0 -152
- package/lib/acp/tool-converter.d.ts.map +0 -1
- package/lib/acp/tool-converter.js +0 -806
- package/lib/acp/tool-converter.js.map +0 -1
|
@@ -1,806 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* ACP Message Transformer
|
|
4
|
-
*
|
|
5
|
-
* Converts SDK internal tool formats to ACP (Agent Client Protocol) format and vice versa.
|
|
6
|
-
*
|
|
7
|
-
* Uses official @agentclientprotocol/sdk types for compatibility with the ACP specification.
|
|
8
|
-
*
|
|
9
|
-
* Critical Design Principle: NO DATA LOSS
|
|
10
|
-
* - SDK tool inputs are preserved completely in rawInput
|
|
11
|
-
* - Tool IDs are maintained throughout the conversion
|
|
12
|
-
* - Tool results are preserved with error state tracking
|
|
13
|
-
*/
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.AcpTransformer = void 0;
|
|
16
|
-
// ============= ACP Message Transformer (Stateless Utility) =============
|
|
17
|
-
/**
|
|
18
|
-
* Bidirectional converter between SDK internal format (JSON Lines) and ACP (Agent Client Protocol) format.
|
|
19
|
-
*
|
|
20
|
-
* This is an abstract utility class with only static methods - do not instantiate.
|
|
21
|
-
*
|
|
22
|
-
* Key features:
|
|
23
|
-
* - Converts SDK tool use/result to ACP format
|
|
24
|
-
* - Converts ACP messages to SDK format
|
|
25
|
-
* - Extracts and manipulates tool/text blocks
|
|
26
|
-
* - Complete data preservation in roundtrip conversions
|
|
27
|
-
* - Type-safe message routing
|
|
28
|
-
*/
|
|
29
|
-
class AcpTransformer {
|
|
30
|
-
// ============= Public API: SDK Tool Use ↔ ACP Tool Call =============
|
|
31
|
-
/**
|
|
32
|
-
* Convert SDK ToolUseContentBlock to complete session/update params
|
|
33
|
-
* Returns an object that can be spread directly into AcpMessage params
|
|
34
|
-
*
|
|
35
|
-
* This is the preferred method for creating tool call messages that comply with ACP spec.
|
|
36
|
-
*
|
|
37
|
-
* @param toolUse - SDK tool use block
|
|
38
|
-
* @param sessionId - Session ID for the message
|
|
39
|
-
* @param messageId - Optional message ID (defaults to toolUse.id)
|
|
40
|
-
* @returns Complete params object ready to be used in session/update message
|
|
41
|
-
*/
|
|
42
|
-
static convertSdkToolUseToSessionUpdate(toolUse, sessionId, messageId) {
|
|
43
|
-
const toolName = toolUse.name;
|
|
44
|
-
const toolInput = toolUse.input;
|
|
45
|
-
return {
|
|
46
|
-
sessionId,
|
|
47
|
-
update: {
|
|
48
|
-
sessionUpdate: 'tool_call',
|
|
49
|
-
toolCallId: toolUse.id,
|
|
50
|
-
status: 'pending',
|
|
51
|
-
title: AcpTransformer.generateToolTitle(toolName, toolInput),
|
|
52
|
-
kind: AcpTransformer.getToolKind(toolName),
|
|
53
|
-
rawInput: toolInput,
|
|
54
|
-
content: AcpTransformer.generateToolContent(toolName, toolInput),
|
|
55
|
-
locations: AcpTransformer.extractToolLocations(toolName, toolInput),
|
|
56
|
-
},
|
|
57
|
-
_meta: {
|
|
58
|
-
'codebuddy.ai': {
|
|
59
|
-
toolName,
|
|
60
|
-
messageId: messageId || toolUse.id,
|
|
61
|
-
},
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
// ============= Public API: Bidirectional Tool Conversion =============
|
|
66
|
-
/**
|
|
67
|
-
* Convert ACP Tool Result to SDK ToolResultContentBlock
|
|
68
|
-
* Preserves tool_use_id and ensures error state is tracked
|
|
69
|
-
*/
|
|
70
|
-
static convertAcpToolResultToSdk(toolCallId, acpResult) {
|
|
71
|
-
const isError = acpResult.status === 'failed';
|
|
72
|
-
const content = acpResult.content ? AcpTransformer.formatAcpContentForSdk(acpResult.content) : '';
|
|
73
|
-
return {
|
|
74
|
-
type: 'tool_result',
|
|
75
|
-
tool_use_id: toolCallId,
|
|
76
|
-
content: content,
|
|
77
|
-
is_error: isError,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Convert SDK ToolResultContentBlock to ACP ToolResult
|
|
82
|
-
* Enables bidirectional conversion for tool results
|
|
83
|
-
*/
|
|
84
|
-
static convertSdkToolResultToAcpToolResult(toolResult) {
|
|
85
|
-
const content = [];
|
|
86
|
-
if (toolResult.content) {
|
|
87
|
-
if (typeof toolResult.content === 'string') {
|
|
88
|
-
content.push({
|
|
89
|
-
type: 'content',
|
|
90
|
-
content: { type: 'text', text: toolResult.content },
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
else if (Array.isArray(toolResult.content)) {
|
|
94
|
-
for (const block of toolResult.content) {
|
|
95
|
-
if ('type' in block && block.type === 'text') {
|
|
96
|
-
const textBlock = block;
|
|
97
|
-
content.push({
|
|
98
|
-
type: 'content',
|
|
99
|
-
content: { type: 'text', text: textBlock.text },
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return {
|
|
106
|
-
toolCallId: toolResult.tool_use_id,
|
|
107
|
-
status: toolResult.is_error ? 'failed' : 'completed',
|
|
108
|
-
content: content.length > 0 ? content : undefined,
|
|
109
|
-
rawOutput: toolResult.content,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
// ============= Public API: Message Transformation =============
|
|
113
|
-
/**
|
|
114
|
-
* Convert ACP message to SDK internal format (JSON Lines)
|
|
115
|
-
*
|
|
116
|
-
* Converts all ACP message types to corresponding SDK messages:
|
|
117
|
-
* - session/prompt: User input → UserMessage
|
|
118
|
-
* - session/cancel: Cancellation request → ControlRequest
|
|
119
|
-
* - session/update (tool_call_update): Tool result → UserMessage with tool_result block
|
|
120
|
-
*/
|
|
121
|
-
static acpToSdk(acpMessage) {
|
|
122
|
-
if (acpMessage.method === 'session/prompt') {
|
|
123
|
-
const params = acpMessage.params;
|
|
124
|
-
const sessionId = params === null || params === void 0 ? void 0 : params.sessionId;
|
|
125
|
-
const prompt = params === null || params === void 0 ? void 0 : params.prompt;
|
|
126
|
-
const content = AcpTransformer.privateExtractPromptText(prompt);
|
|
127
|
-
return {
|
|
128
|
-
type: 'user',
|
|
129
|
-
session_id: sessionId || 'unknown',
|
|
130
|
-
message: {
|
|
131
|
-
role: 'user',
|
|
132
|
-
content: content,
|
|
133
|
-
},
|
|
134
|
-
parent_tool_use_id: null,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (acpMessage.method === 'session/cancel') {
|
|
138
|
-
return {
|
|
139
|
-
type: 'control_request',
|
|
140
|
-
request: { subtype: 'interrupt' },
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
// Handle session/update with tool_call_update
|
|
144
|
-
if (acpMessage.method === 'session/update') {
|
|
145
|
-
const params = acpMessage.params;
|
|
146
|
-
const sessionId = params === null || params === void 0 ? void 0 : params.sessionId;
|
|
147
|
-
const update = params === null || params === void 0 ? void 0 : params.update;
|
|
148
|
-
if ((update === null || update === void 0 ? void 0 : update.sessionUpdate) === 'tool_call_update') {
|
|
149
|
-
// Convert tool_call_update back to SDK tool result format
|
|
150
|
-
const toolCallId = update.toolCallId;
|
|
151
|
-
const status = update.status;
|
|
152
|
-
const content = update.content;
|
|
153
|
-
if (toolCallId) {
|
|
154
|
-
// Create an AcpToolResult from the update
|
|
155
|
-
const acpResult = {
|
|
156
|
-
toolCallId,
|
|
157
|
-
status: status || 'completed',
|
|
158
|
-
content: content,
|
|
159
|
-
};
|
|
160
|
-
return AcpTransformer.privateCreateToolResultMessage({ params: { sessionId } }, acpResult);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Convert SDK internal message to ACP format
|
|
168
|
-
*
|
|
169
|
-
* @param message - SDK message to convert
|
|
170
|
-
* @param mode - Conversion mode:
|
|
171
|
-
* - 'stream': Real-time streaming mode (session/prompt) - converts to incremental chunks
|
|
172
|
-
* - 'history': History replay mode (session/load) - converts to complete messages
|
|
173
|
-
*
|
|
174
|
-
* Converts all SDK message types to corresponding ACP messages:
|
|
175
|
-
* - Stream mode: PartialAssistantMessage (stream_event) → streaming text/tool deltas
|
|
176
|
-
* - History mode: AssistantMessage/UserMessage → complete message objects
|
|
177
|
-
*/
|
|
178
|
-
static sdkToAcp(message, mode = 'stream') {
|
|
179
|
-
const messages = [];
|
|
180
|
-
// ============= Stream Mode: Handle Real-time Streaming Events =============
|
|
181
|
-
if (mode === 'stream') {
|
|
182
|
-
// Process stream_event for incremental updates
|
|
183
|
-
if ('type' in message && message.type === 'stream_event') {
|
|
184
|
-
const partialMsg = message;
|
|
185
|
-
const streamEvent = partialMsg.event;
|
|
186
|
-
// Handle content_block_start: process the initial content_block (aligned with Zed)
|
|
187
|
-
if (streamEvent.type === 'content_block_start' && 'content_block' in streamEvent) {
|
|
188
|
-
const block = streamEvent.content_block;
|
|
189
|
-
// Handle tool_use blocks at start
|
|
190
|
-
if (block.type === 'tool_use') {
|
|
191
|
-
const toolMsg = {
|
|
192
|
-
jsonrpc: '2.0',
|
|
193
|
-
method: 'session/update',
|
|
194
|
-
params: AcpTransformer.convertSdkToolUseToSessionUpdate(block, partialMsg.session_id || 'unknown', partialMsg.uuid),
|
|
195
|
-
};
|
|
196
|
-
messages.push(toolMsg);
|
|
197
|
-
}
|
|
198
|
-
// Handle text blocks at start (initial empty text block)
|
|
199
|
-
else if (block.type === 'text') {
|
|
200
|
-
messages.push({
|
|
201
|
-
jsonrpc: '2.0',
|
|
202
|
-
method: 'session/update',
|
|
203
|
-
params: {
|
|
204
|
-
sessionId: partialMsg.session_id || 'unknown',
|
|
205
|
-
update: {
|
|
206
|
-
sessionUpdate: 'agent_message_chunk',
|
|
207
|
-
content: {
|
|
208
|
-
type: 'text',
|
|
209
|
-
text: block.text || '',
|
|
210
|
-
},
|
|
211
|
-
},
|
|
212
|
-
_meta: {
|
|
213
|
-
'codebuddy.ai': {
|
|
214
|
-
messageId: partialMsg.uuid,
|
|
215
|
-
},
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Handle content_block_delta: process incremental updates (aligned with Zed)
|
|
222
|
-
else if (streamEvent.type === 'content_block_delta') {
|
|
223
|
-
if ('delta' in streamEvent && streamEvent.delta.type === 'text_delta') {
|
|
224
|
-
// Convert text deltas to agent_message_chunk format (Zed naming convention)
|
|
225
|
-
messages.push({
|
|
226
|
-
jsonrpc: '2.0',
|
|
227
|
-
method: 'session/update',
|
|
228
|
-
params: {
|
|
229
|
-
sessionId: partialMsg.session_id || 'unknown',
|
|
230
|
-
update: {
|
|
231
|
-
sessionUpdate: 'agent_message_chunk',
|
|
232
|
-
content: {
|
|
233
|
-
type: 'text',
|
|
234
|
-
text: streamEvent.delta.text,
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
_meta: {
|
|
238
|
-
'codebuddy.ai': {
|
|
239
|
-
messageId: partialMsg.uuid,
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
// Handle user messages with tool results in stream mode
|
|
248
|
-
// Tool results don't stream - they arrive as complete messages
|
|
249
|
-
if ('type' in message && message.type === 'user') {
|
|
250
|
-
const userMsg = message;
|
|
251
|
-
const messageId = userMsg.uuid;
|
|
252
|
-
if (userMsg.message.content && Array.isArray(userMsg.message.content)) {
|
|
253
|
-
// Look for tool result blocks
|
|
254
|
-
const toolResultBlocks = userMsg.message.content.filter((block) => typeof block === 'object' &&
|
|
255
|
-
block !== null &&
|
|
256
|
-
'type' in block &&
|
|
257
|
-
block.type === 'tool_result');
|
|
258
|
-
// Convert tool results to ACP tool_call_update format
|
|
259
|
-
for (const toolResultBlock of toolResultBlocks) {
|
|
260
|
-
const acpResult = AcpTransformer.convertSdkToolResultToAcpToolResult(toolResultBlock);
|
|
261
|
-
const updateMsg = {
|
|
262
|
-
jsonrpc: '2.0',
|
|
263
|
-
method: 'session/update',
|
|
264
|
-
params: {
|
|
265
|
-
sessionId: userMsg.session_id || 'unknown',
|
|
266
|
-
update: {
|
|
267
|
-
sessionUpdate: 'tool_call_update',
|
|
268
|
-
toolCallId: acpResult.toolCallId,
|
|
269
|
-
status: acpResult.status,
|
|
270
|
-
content: acpResult.content,
|
|
271
|
-
},
|
|
272
|
-
_meta: {
|
|
273
|
-
'codebuddy.ai': {
|
|
274
|
-
messageId: messageId,
|
|
275
|
-
},
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
messages.push(updateMsg);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// Skip system, tool_progress, assistant (handled by stream_event), and other internal messages in stream mode
|
|
284
|
-
return messages;
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
// ============= History Mode: Handle Complete Messages =============
|
|
288
|
-
// Convert complete messages for history replay (for session/load)
|
|
289
|
-
// Handle assistant messages (contain tool calls and text from the model)
|
|
290
|
-
if ('type' in message && message.type === 'assistant') {
|
|
291
|
-
const assistantMsg = message;
|
|
292
|
-
const messageId = assistantMsg.message.id;
|
|
293
|
-
if (assistantMsg.message.content && Array.isArray(assistantMsg.message.content)) {
|
|
294
|
-
// Extract and convert tool use blocks
|
|
295
|
-
const toolUseBlocks = AcpTransformer.privateExtractToolUseBlocks(assistantMsg.message.content);
|
|
296
|
-
for (const toolUse of toolUseBlocks) {
|
|
297
|
-
const toolCallMsg = {
|
|
298
|
-
jsonrpc: '2.0',
|
|
299
|
-
method: 'session/update',
|
|
300
|
-
params: AcpTransformer.convertSdkToolUseToSessionUpdate(toolUse, assistantMsg.session_id || 'unknown', messageId),
|
|
301
|
-
};
|
|
302
|
-
messages.push(toolCallMsg);
|
|
303
|
-
}
|
|
304
|
-
// Extract and send text content if present
|
|
305
|
-
const textContent = AcpTransformer.privateExtractTextContent(assistantMsg.message.content);
|
|
306
|
-
if (textContent) {
|
|
307
|
-
messages.push({
|
|
308
|
-
jsonrpc: '2.0',
|
|
309
|
-
method: 'session/update',
|
|
310
|
-
params: {
|
|
311
|
-
sessionId: assistantMsg.session_id || 'unknown',
|
|
312
|
-
update: {
|
|
313
|
-
sessionUpdate: 'agent_message_chunk',
|
|
314
|
-
content: {
|
|
315
|
-
type: 'text',
|
|
316
|
-
text: textContent,
|
|
317
|
-
},
|
|
318
|
-
},
|
|
319
|
-
_meta: {
|
|
320
|
-
'codebuddy.ai': {
|
|
321
|
-
messageId: messageId,
|
|
322
|
-
},
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
// Handle user messages with tool results or text content
|
|
330
|
-
if ('type' in message && message.type === 'user') {
|
|
331
|
-
const userMsg = message;
|
|
332
|
-
const messageId = userMsg.uuid;
|
|
333
|
-
if (userMsg.message.content) {
|
|
334
|
-
// Handle array content (tool results and text blocks)
|
|
335
|
-
if (Array.isArray(userMsg.message.content)) {
|
|
336
|
-
// Look for tool result blocks
|
|
337
|
-
const toolResultBlocks = userMsg.message.content.filter((block) => typeof block === 'object' &&
|
|
338
|
-
block !== null &&
|
|
339
|
-
'type' in block &&
|
|
340
|
-
block.type === 'tool_result');
|
|
341
|
-
// Convert tool results to ACP tool_call_update format (via session/update)
|
|
342
|
-
for (const toolResultBlock of toolResultBlocks) {
|
|
343
|
-
const acpResult = AcpTransformer.convertSdkToolResultToAcpToolResult(toolResultBlock);
|
|
344
|
-
// Wrap tool result as session/update with tool_call_update
|
|
345
|
-
const updateMsg = {
|
|
346
|
-
jsonrpc: '2.0',
|
|
347
|
-
method: 'session/update',
|
|
348
|
-
params: {
|
|
349
|
-
sessionId: userMsg.session_id || 'unknown',
|
|
350
|
-
update: {
|
|
351
|
-
sessionUpdate: 'tool_call_update',
|
|
352
|
-
toolCallId: acpResult.toolCallId,
|
|
353
|
-
status: acpResult.status,
|
|
354
|
-
content: acpResult.content,
|
|
355
|
-
},
|
|
356
|
-
_meta: {
|
|
357
|
-
'codebuddy.ai': {
|
|
358
|
-
messageId: messageId,
|
|
359
|
-
},
|
|
360
|
-
}
|
|
361
|
-
},
|
|
362
|
-
};
|
|
363
|
-
messages.push(updateMsg);
|
|
364
|
-
}
|
|
365
|
-
// Extract and send text content if present (for resume history)
|
|
366
|
-
const textContent = AcpTransformer.privateExtractTextContent(userMsg.message.content);
|
|
367
|
-
if (textContent) {
|
|
368
|
-
messages.push({
|
|
369
|
-
jsonrpc: '2.0',
|
|
370
|
-
method: 'session/prompt',
|
|
371
|
-
params: {
|
|
372
|
-
sessionId: userMsg.session_id || 'unknown',
|
|
373
|
-
prompt: [{ type: 'text', text: textContent }],
|
|
374
|
-
_meta: {
|
|
375
|
-
'codebuddy.ai': {
|
|
376
|
-
messageId: messageId,
|
|
377
|
-
},
|
|
378
|
-
}
|
|
379
|
-
},
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
else if (typeof userMsg.message.content === 'string' && userMsg.message.content) {
|
|
384
|
-
// Handle string content (for resume history)
|
|
385
|
-
messages.push({
|
|
386
|
-
jsonrpc: '2.0',
|
|
387
|
-
method: 'session/prompt',
|
|
388
|
-
params: {
|
|
389
|
-
sessionId: userMsg.session_id || 'unknown',
|
|
390
|
-
prompt: [{ type: 'text', text: userMsg.message.content }],
|
|
391
|
-
_meta: {
|
|
392
|
-
'codebuddy.ai': {
|
|
393
|
-
messageId: messageId,
|
|
394
|
-
},
|
|
395
|
-
}
|
|
396
|
-
},
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
// Handle result messages (marks the end of a turn)
|
|
402
|
-
if ('type' in message && message.type === 'result') {
|
|
403
|
-
messages.push({
|
|
404
|
-
jsonrpc: '2.0',
|
|
405
|
-
method: 'session/result',
|
|
406
|
-
params: {
|
|
407
|
-
sessionId: message.session_id || 'unknown',
|
|
408
|
-
result: message,
|
|
409
|
-
},
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
// Handle error messages
|
|
413
|
-
if ('type' in message && message.type === 'error') {
|
|
414
|
-
messages.push({
|
|
415
|
-
jsonrpc: '2.0',
|
|
416
|
-
method: 'session/error',
|
|
417
|
-
params: {
|
|
418
|
-
sessionId: message.session_id || 'unknown',
|
|
419
|
-
error: message.error,
|
|
420
|
-
},
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
// Skip system, tool_progress, stream_event (partial), compact_boundary and other internal messages
|
|
425
|
-
return messages;
|
|
426
|
-
}
|
|
427
|
-
// ============= Private: Title Generation by Tool Type =============
|
|
428
|
-
static generateToolTitle(toolName, input) {
|
|
429
|
-
switch (toolName) {
|
|
430
|
-
case 'Read':
|
|
431
|
-
case 'read': {
|
|
432
|
-
const filePath = input.file_path;
|
|
433
|
-
const offset = input.offset;
|
|
434
|
-
const limit = input.limit;
|
|
435
|
-
if (!filePath)
|
|
436
|
-
return 'Read';
|
|
437
|
-
if (limit) {
|
|
438
|
-
const startLine = (offset !== null && offset !== void 0 ? offset : 0) + 1;
|
|
439
|
-
const endLine = startLine + limit - 1;
|
|
440
|
-
return `Read ${filePath} (${startLine}-${endLine})`;
|
|
441
|
-
}
|
|
442
|
-
else if (offset) {
|
|
443
|
-
return `Read ${filePath} (from line ${(offset !== null && offset !== void 0 ? offset : 0) + 1})`;
|
|
444
|
-
}
|
|
445
|
-
return `Read ${filePath}`;
|
|
446
|
-
}
|
|
447
|
-
case 'Write':
|
|
448
|
-
case 'write': {
|
|
449
|
-
const filePath = input.file_path;
|
|
450
|
-
return filePath ? `Write ${filePath}` : 'Write';
|
|
451
|
-
}
|
|
452
|
-
case 'Edit':
|
|
453
|
-
case 'edit':
|
|
454
|
-
case 'MultiEdit': {
|
|
455
|
-
const filePath = input.file_path;
|
|
456
|
-
return filePath ? `Edit \`${filePath}\`` : 'Edit';
|
|
457
|
-
}
|
|
458
|
-
case 'Bash':
|
|
459
|
-
case 'bash': {
|
|
460
|
-
const command = input.command;
|
|
461
|
-
if (!command)
|
|
462
|
-
return 'Terminal';
|
|
463
|
-
const escaped = command.split('`').join('\\`');
|
|
464
|
-
return `\`${escaped}\``;
|
|
465
|
-
}
|
|
466
|
-
case 'BashOutput':
|
|
467
|
-
case 'bash_output':
|
|
468
|
-
return 'Tail Logs';
|
|
469
|
-
case 'KillShell':
|
|
470
|
-
case 'kill_shell':
|
|
471
|
-
return 'Kill Process';
|
|
472
|
-
case 'Glob':
|
|
473
|
-
case 'glob': {
|
|
474
|
-
let label = 'Find';
|
|
475
|
-
const path = input.path;
|
|
476
|
-
const pattern = input.pattern;
|
|
477
|
-
if (path)
|
|
478
|
-
label += ` \`${path}\``;
|
|
479
|
-
if (pattern)
|
|
480
|
-
label += ` \`${pattern}\``;
|
|
481
|
-
return label;
|
|
482
|
-
}
|
|
483
|
-
case 'Grep':
|
|
484
|
-
case 'grep': {
|
|
485
|
-
let label = 'grep';
|
|
486
|
-
if (input['-i'])
|
|
487
|
-
label += ' -i';
|
|
488
|
-
if (input['-n'])
|
|
489
|
-
label += ' -n';
|
|
490
|
-
if (input['-C'] !== undefined)
|
|
491
|
-
label += ` -C ${input['-C']}`;
|
|
492
|
-
if (input['-A'] !== undefined)
|
|
493
|
-
label += ` -A ${input['-A']}`;
|
|
494
|
-
if (input['-B'] !== undefined)
|
|
495
|
-
label += ` -B ${input['-B']}`;
|
|
496
|
-
if (input.multiline)
|
|
497
|
-
label += ' -P';
|
|
498
|
-
if (input.glob)
|
|
499
|
-
label += ` --include="${input.glob}"`;
|
|
500
|
-
if (input.type)
|
|
501
|
-
label += ` --type=${input.type}`;
|
|
502
|
-
const pattern = input.pattern;
|
|
503
|
-
const path = input.path;
|
|
504
|
-
if (pattern)
|
|
505
|
-
label += ` "${pattern}"`;
|
|
506
|
-
if (path)
|
|
507
|
-
label += ` ${path}`;
|
|
508
|
-
return label;
|
|
509
|
-
}
|
|
510
|
-
case 'WebFetch':
|
|
511
|
-
case 'web_fetch': {
|
|
512
|
-
const url = input.url;
|
|
513
|
-
return url ? `Fetch ${url}` : 'Fetch';
|
|
514
|
-
}
|
|
515
|
-
case 'WebSearch':
|
|
516
|
-
case 'web_search': {
|
|
517
|
-
const query = input.query;
|
|
518
|
-
if (!query)
|
|
519
|
-
return 'Search';
|
|
520
|
-
let label = `"${query}"`;
|
|
521
|
-
const allowedDomains = input.allowed_domains;
|
|
522
|
-
const blockedDomains = input.blocked_domains;
|
|
523
|
-
if (allowedDomains === null || allowedDomains === void 0 ? void 0 : allowedDomains.length)
|
|
524
|
-
label += ` (allowed: ${allowedDomains.join(', ')})`;
|
|
525
|
-
if (blockedDomains === null || blockedDomains === void 0 ? void 0 : blockedDomains.length)
|
|
526
|
-
label += ` (blocked: ${blockedDomains.join(', ')})`;
|
|
527
|
-
return label;
|
|
528
|
-
}
|
|
529
|
-
case 'NotebookRead':
|
|
530
|
-
case 'notebook_read': {
|
|
531
|
-
const path = input.notebook_path;
|
|
532
|
-
return path ? `Read Notebook ${path}` : 'Read Notebook';
|
|
533
|
-
}
|
|
534
|
-
case 'NotebookEdit':
|
|
535
|
-
case 'notebook_edit': {
|
|
536
|
-
const path = input.notebook_path;
|
|
537
|
-
return path ? `Edit Notebook ${path}` : 'Edit Notebook';
|
|
538
|
-
}
|
|
539
|
-
case 'Task':
|
|
540
|
-
case 'task': {
|
|
541
|
-
const description = input.description;
|
|
542
|
-
return description || 'Task';
|
|
543
|
-
}
|
|
544
|
-
case 'TodoWrite':
|
|
545
|
-
case 'todo_write': {
|
|
546
|
-
return 'Update TODOs';
|
|
547
|
-
}
|
|
548
|
-
case 'AskUserQuestion':
|
|
549
|
-
case 'ask_user_question':
|
|
550
|
-
return 'Ask User';
|
|
551
|
-
case 'SlashCommand':
|
|
552
|
-
case 'slash_command': {
|
|
553
|
-
const command = input.command;
|
|
554
|
-
return command ? `Run: ${command}` : 'Slash Command';
|
|
555
|
-
}
|
|
556
|
-
case 'Skill':
|
|
557
|
-
case 'skill': {
|
|
558
|
-
const command = input.command;
|
|
559
|
-
return command ? `Skill: ${command}` : 'Skill';
|
|
560
|
-
}
|
|
561
|
-
case 'LSP':
|
|
562
|
-
case 'lsp': {
|
|
563
|
-
const operation = input.operation;
|
|
564
|
-
return operation ? `LSP: ${operation}` : 'LSP';
|
|
565
|
-
}
|
|
566
|
-
case 'EnterPlanMode':
|
|
567
|
-
case 'enter_plan_mode':
|
|
568
|
-
return 'Enter Plan Mode';
|
|
569
|
-
case 'ExitPlanMode':
|
|
570
|
-
case 'exit_plan_mode':
|
|
571
|
-
return 'Exit Plan Mode';
|
|
572
|
-
case 'TaskOutput':
|
|
573
|
-
case 'task_output':
|
|
574
|
-
return 'Get Task Output';
|
|
575
|
-
default:
|
|
576
|
-
return toolName || 'Unknown Tool';
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
// ============= Private: Tool Kind Classification =============
|
|
580
|
-
static getToolKind(toolName) {
|
|
581
|
-
switch (toolName) {
|
|
582
|
-
case 'Read':
|
|
583
|
-
case 'read':
|
|
584
|
-
case 'NotebookRead':
|
|
585
|
-
case 'notebook_read':
|
|
586
|
-
case 'Glob':
|
|
587
|
-
case 'glob':
|
|
588
|
-
return 'read';
|
|
589
|
-
case 'Write':
|
|
590
|
-
case 'write':
|
|
591
|
-
case 'Edit':
|
|
592
|
-
case 'edit':
|
|
593
|
-
case 'MultiEdit':
|
|
594
|
-
case 'NotebookEdit':
|
|
595
|
-
case 'notebook_edit':
|
|
596
|
-
return 'edit';
|
|
597
|
-
case 'Bash':
|
|
598
|
-
case 'bash':
|
|
599
|
-
case 'BashOutput':
|
|
600
|
-
case 'bash_output':
|
|
601
|
-
case 'KillShell':
|
|
602
|
-
case 'kill_shell':
|
|
603
|
-
case 'TaskOutput':
|
|
604
|
-
case 'task_output':
|
|
605
|
-
return 'execute';
|
|
606
|
-
case 'Grep':
|
|
607
|
-
case 'grep':
|
|
608
|
-
case 'WebSearch':
|
|
609
|
-
case 'web_search':
|
|
610
|
-
return 'search';
|
|
611
|
-
case 'WebFetch':
|
|
612
|
-
case 'web_fetch':
|
|
613
|
-
return 'fetch';
|
|
614
|
-
case 'Task':
|
|
615
|
-
case 'task':
|
|
616
|
-
case 'TodoWrite':
|
|
617
|
-
case 'todo_write':
|
|
618
|
-
case 'EnterPlanMode':
|
|
619
|
-
case 'enter_plan_mode':
|
|
620
|
-
case 'ExitPlanMode':
|
|
621
|
-
case 'exit_plan_mode':
|
|
622
|
-
return 'think';
|
|
623
|
-
default:
|
|
624
|
-
return 'other';
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
// ============= Private: Content Generation by Tool Type =============
|
|
628
|
-
static generateToolContent(toolName, input) {
|
|
629
|
-
const content = [];
|
|
630
|
-
switch (toolName) {
|
|
631
|
-
case 'Edit':
|
|
632
|
-
case 'edit':
|
|
633
|
-
case 'MultiEdit': {
|
|
634
|
-
const filePath = input.file_path;
|
|
635
|
-
const oldString = input.old_string;
|
|
636
|
-
const newString = input.new_string;
|
|
637
|
-
if (filePath && oldString !== undefined && newString !== undefined) {
|
|
638
|
-
content.push({
|
|
639
|
-
type: 'diff',
|
|
640
|
-
path: filePath,
|
|
641
|
-
oldText: oldString || null,
|
|
642
|
-
newText: newString,
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
break;
|
|
646
|
-
}
|
|
647
|
-
case 'Bash':
|
|
648
|
-
case 'bash': {
|
|
649
|
-
const description = input.description;
|
|
650
|
-
if (description) {
|
|
651
|
-
content.push({
|
|
652
|
-
type: 'content',
|
|
653
|
-
content: { type: 'text', text: description },
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
break;
|
|
657
|
-
}
|
|
658
|
-
case 'Task':
|
|
659
|
-
case 'task': {
|
|
660
|
-
const prompt = input.prompt;
|
|
661
|
-
if (prompt) {
|
|
662
|
-
content.push({
|
|
663
|
-
type: 'content',
|
|
664
|
-
content: { type: 'text', text: prompt },
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
break;
|
|
668
|
-
}
|
|
669
|
-
case 'WebFetch':
|
|
670
|
-
case 'web_fetch': {
|
|
671
|
-
const prompt = input.prompt;
|
|
672
|
-
if (prompt) {
|
|
673
|
-
content.push({
|
|
674
|
-
type: 'content',
|
|
675
|
-
content: { type: 'text', text: prompt },
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
break;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
return content.length > 0 ? content : undefined;
|
|
682
|
-
}
|
|
683
|
-
// ============= Private: Location Extraction by Tool Type =============
|
|
684
|
-
static extractToolLocations(toolName, input) {
|
|
685
|
-
const locations = [];
|
|
686
|
-
const filePath = input.file_path;
|
|
687
|
-
const notebookPath = input.notebook_path;
|
|
688
|
-
const path = input.path;
|
|
689
|
-
if (filePath) {
|
|
690
|
-
// For file operations, only include path, not line number
|
|
691
|
-
// Line numbers should be added by specific operations that target specific lines
|
|
692
|
-
locations.push({
|
|
693
|
-
path: filePath,
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
else if (notebookPath) {
|
|
697
|
-
locations.push({ path: notebookPath });
|
|
698
|
-
}
|
|
699
|
-
else if (path && (toolName === 'Glob' || toolName === 'glob')) {
|
|
700
|
-
locations.push({ path });
|
|
701
|
-
}
|
|
702
|
-
return locations.length > 0 ? locations : undefined;
|
|
703
|
-
}
|
|
704
|
-
// ============= Private: Content Format Conversion =============
|
|
705
|
-
static formatAcpContentForSdk(toolCallContent) {
|
|
706
|
-
var _a;
|
|
707
|
-
if (toolCallContent.length === 0) {
|
|
708
|
-
return '';
|
|
709
|
-
}
|
|
710
|
-
const blocks = [];
|
|
711
|
-
for (const item of toolCallContent) {
|
|
712
|
-
if (item.type === 'diff') {
|
|
713
|
-
const diff = item;
|
|
714
|
-
const diffText = `--- ${diff.path}
|
|
715
|
-
+++ ${diff.path}
|
|
716
|
-
${AcpTransformer.formatDiffHunk((_a = diff.oldText) !== null && _a !== void 0 ? _a : null, diff.newText)}`;
|
|
717
|
-
blocks.push({
|
|
718
|
-
type: 'text',
|
|
719
|
-
text: diffText,
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
else if (item.type === 'content') {
|
|
723
|
-
const contentItem = item;
|
|
724
|
-
if (contentItem.content && contentItem.content.type === 'text' && contentItem.content.text) {
|
|
725
|
-
blocks.push({
|
|
726
|
-
type: 'text',
|
|
727
|
-
text: contentItem.content.text,
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
else if (item.type === 'terminal') {
|
|
732
|
-
const terminalItem = item;
|
|
733
|
-
if (terminalItem.terminalId) {
|
|
734
|
-
blocks.push({
|
|
735
|
-
type: 'text',
|
|
736
|
-
text: `[Terminal: ${terminalItem.terminalId}]`,
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
if (blocks.length === 1 && blocks[0].type === 'text') {
|
|
742
|
-
return blocks[0].text;
|
|
743
|
-
}
|
|
744
|
-
return blocks.length > 0 ? blocks : '';
|
|
745
|
-
}
|
|
746
|
-
static formatDiffHunk(oldText, newText) {
|
|
747
|
-
const oldLines = oldText ? oldText.split('\n') : [];
|
|
748
|
-
const newLines = newText.split('\n');
|
|
749
|
-
const hunks = [];
|
|
750
|
-
hunks.push(`@@ -1,${oldLines.length} +1,${newLines.length} @@`);
|
|
751
|
-
for (const line of oldLines) {
|
|
752
|
-
hunks.push(`-${line}`);
|
|
753
|
-
}
|
|
754
|
-
for (const line of newLines) {
|
|
755
|
-
hunks.push(`+${line}`);
|
|
756
|
-
}
|
|
757
|
-
return hunks.join('\n');
|
|
758
|
-
}
|
|
759
|
-
// ============= Private: Prompt and Result Helpers =============
|
|
760
|
-
static privateExtractPromptText(prompt) {
|
|
761
|
-
let content = '';
|
|
762
|
-
if (prompt && Array.isArray(prompt)) {
|
|
763
|
-
for (const block of prompt) {
|
|
764
|
-
if (block.type === 'text' && block.text) {
|
|
765
|
-
content += block.text;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
return content;
|
|
770
|
-
}
|
|
771
|
-
// ============= Private: Content Block Extraction =============
|
|
772
|
-
static privateExtractToolUseBlocks(contentBlocks) {
|
|
773
|
-
if (!Array.isArray(contentBlocks))
|
|
774
|
-
return [];
|
|
775
|
-
return contentBlocks.filter((block) => typeof block === 'object' &&
|
|
776
|
-
block !== null &&
|
|
777
|
-
'type' in block &&
|
|
778
|
-
block.type === 'tool_use');
|
|
779
|
-
}
|
|
780
|
-
static privateExtractTextContent(contentBlocks) {
|
|
781
|
-
if (!Array.isArray(contentBlocks))
|
|
782
|
-
return '';
|
|
783
|
-
return contentBlocks
|
|
784
|
-
.filter((block) => typeof block === 'object' &&
|
|
785
|
-
block !== null &&
|
|
786
|
-
'type' in block &&
|
|
787
|
-
block.type === 'text')
|
|
788
|
-
.map((block) => block.text)
|
|
789
|
-
.join('\n');
|
|
790
|
-
}
|
|
791
|
-
static privateCreateToolResultMessage(acpMessage, acpResult) {
|
|
792
|
-
var _a;
|
|
793
|
-
const toolResultBlock = AcpTransformer.convertAcpToolResultToSdk(acpResult.toolCallId, acpResult);
|
|
794
|
-
return {
|
|
795
|
-
type: 'user',
|
|
796
|
-
session_id: ((_a = acpMessage.params) === null || _a === void 0 ? void 0 : _a.sessionId) || 'unknown',
|
|
797
|
-
message: {
|
|
798
|
-
role: 'user',
|
|
799
|
-
content: [toolResultBlock],
|
|
800
|
-
},
|
|
801
|
-
parent_tool_use_id: acpResult.toolCallId,
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
exports.AcpTransformer = AcpTransformer;
|
|
806
|
-
//# sourceMappingURL=tool-converter.js.map
|