wave-agent-sdk 1.0.4 → 1.0.6
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/agent.d.ts +23 -1
- package/dist/agent.js +34 -4
- package/dist/managers/aiManager.d.ts +36 -0
- package/dist/managers/aiManager.js +240 -8
- package/dist/managers/messageManager.d.ts +1 -3
- package/dist/managers/messageManager.js +19 -9
- package/dist/managers/slashCommandManager.js +28 -0
- package/dist/managers/subagentManager.d.ts +0 -2
- package/dist/services/session.js +2 -9
- package/dist/telemetry/instrumentation.d.ts +1 -1
- package/dist/telemetry/instrumentation.js +57 -28
- package/dist/tools/bashTool.js +16 -6
- package/dist/tools/grepTool.js +11 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/messaging.d.ts +2 -0
- package/dist/utils/containerSetup.js +0 -3
- package/dist/utils/messageOperations.d.ts +10 -1
- package/dist/utils/messageOperations.js +19 -1
- package/dist/utils/notificationXml.js +5 -0
- package/dist/utils/ripgrep.d.ts +4 -4
- package/dist/utils/ripgrep.js +4 -27
- package/package.json +20 -8
- package/bin/rg +0 -79
- package/dist/managers/forkedAgentManager.d.ts +0 -50
- package/dist/managers/forkedAgentManager.js +0 -130
- package/scripts/install_ripgrep.js +0 -111
- package/scripts/postinstall.js +0 -38
- package/src/agent.ts +0 -1271
- package/src/constants/subagents.ts +0 -4
- package/src/constants/toolLimits.ts +0 -15
- package/src/constants/tools.ts +0 -24
- package/src/core/plugin.ts +0 -237
- package/src/core/session.ts +0 -9
- package/src/index.ts +0 -38
- package/src/managers/MemoryRuleManager.ts +0 -198
- package/src/managers/aiManager.ts +0 -2429
- package/src/managers/backgroundTaskManager.ts +0 -480
- package/src/managers/bangManager.ts +0 -119
- package/src/managers/cronManager.ts +0 -401
- package/src/managers/foregroundTaskManager.ts +0 -30
- package/src/managers/forkedAgentManager.ts +0 -216
- package/src/managers/hookManager.ts +0 -1089
- package/src/managers/liveConfigManager.ts +0 -445
- package/src/managers/lspManager.ts +0 -470
- package/src/managers/mcpManager.ts +0 -1010
- package/src/managers/messageManager.ts +0 -1180
- package/src/managers/messageQueue.ts +0 -157
- package/src/managers/permissionManager.ts +0 -1140
- package/src/managers/planManager.ts +0 -112
- package/src/managers/pluginManager.ts +0 -330
- package/src/managers/pluginScopeManager.ts +0 -124
- package/src/managers/reversionManager.ts +0 -178
- package/src/managers/skillManager.ts +0 -578
- package/src/managers/slashCommandManager.ts +0 -564
- package/src/managers/subagentManager.ts +0 -915
- package/src/managers/toolManager.ts +0 -489
- package/src/managers/workflowManager.ts +0 -493
- package/src/prompts/autoMemory.ts +0 -33
- package/src/prompts/autoMemoryExtraction.ts +0 -146
- package/src/prompts/index.ts +0 -506
- package/src/prompts/planModeReminders.ts +0 -126
- package/src/services/GitService.ts +0 -131
- package/src/services/MarketplaceService.ts +0 -1052
- package/src/services/MemoryRuleService.ts +0 -71
- package/src/services/aiService.ts +0 -919
- package/src/services/authService.ts +0 -565
- package/src/services/autoMemoryService.ts +0 -280
- package/src/services/configurationService.ts +0 -1520
- package/src/services/fileWatcher.ts +0 -319
- package/src/services/hook.ts +0 -348
- package/src/services/initializationService.ts +0 -357
- package/src/services/interactionService.ts +0 -229
- package/src/services/jsonlHandler.ts +0 -295
- package/src/services/memory.ts +0 -234
- package/src/services/pluginLoader.ts +0 -252
- package/src/services/remoteSettingsService.ts +0 -366
- package/src/services/reversionService.ts +0 -122
- package/src/services/session.ts +0 -922
- package/src/services/taskManager.ts +0 -321
- package/src/telemetry/events.ts +0 -65
- package/src/telemetry/instrumentation.ts +0 -499
- package/src/telemetry/sessionTracing.ts +0 -348
- package/src/tools/agentTool.ts +0 -322
- package/src/tools/askUserQuestion.ts +0 -160
- package/src/tools/bashTool.ts +0 -621
- package/src/tools/buildTool.ts +0 -61
- package/src/tools/cronCreateTool.ts +0 -161
- package/src/tools/cronDeleteTool.ts +0 -51
- package/src/tools/cronListTool.ts +0 -47
- package/src/tools/editTool.ts +0 -313
- package/src/tools/enterPlanMode.ts +0 -124
- package/src/tools/enterWorktreeTool.ts +0 -190
- package/src/tools/exitPlanMode.ts +0 -139
- package/src/tools/exitWorktreeTool.ts +0 -236
- package/src/tools/globTool.ts +0 -167
- package/src/tools/grepTool.ts +0 -399
- package/src/tools/lspTool.ts +0 -883
- package/src/tools/readTool.ts +0 -426
- package/src/tools/skillTool.ts +0 -248
- package/src/tools/taskManagementTools.ts +0 -574
- package/src/tools/taskStopTool.ts +0 -78
- package/src/tools/types.ts +0 -137
- package/src/tools/webFetchTool.ts +0 -373
- package/src/tools/workflowTool.ts +0 -205
- package/src/tools/writeTool.ts +0 -267
- package/src/types/agent.ts +0 -128
- package/src/types/auth.ts +0 -19
- package/src/types/commands.ts +0 -30
- package/src/types/config.ts +0 -43
- package/src/types/configuration.ts +0 -168
- package/src/types/core.ts +0 -105
- package/src/types/cron.ts +0 -13
- package/src/types/environment.ts +0 -106
- package/src/types/fileSearch.ts +0 -4
- package/src/types/history.ts +0 -7
- package/src/types/hooks.ts +0 -256
- package/src/types/index.ts +0 -41
- package/src/types/lsp.ts +0 -98
- package/src/types/marketplace.ts +0 -71
- package/src/types/mcp.ts +0 -43
- package/src/types/memoryRule.ts +0 -31
- package/src/types/messaging.ts +0 -114
- package/src/types/permissions.ts +0 -80
- package/src/types/plugins.ts +0 -39
- package/src/types/processes.ts +0 -99
- package/src/types/reversion.ts +0 -29
- package/src/types/session.ts +0 -12
- package/src/types/skills.ts +0 -108
- package/src/types/tasks.ts +0 -13
- package/src/types/telemetry.ts +0 -98
- package/src/types/tools.ts +0 -44
- package/src/types/workflow.ts +0 -6
- package/src/utils/abortUtils.ts +0 -118
- package/src/utils/atomicWrite.ts +0 -61
- package/src/utils/bashParser.ts +0 -899
- package/src/utils/cacheControlUtils.ts +0 -426
- package/src/utils/commandArgumentParser.ts +0 -161
- package/src/utils/commandPathResolver.ts +0 -88
- package/src/utils/configPaths.ts +0 -220
- package/src/utils/configValidator.ts +0 -100
- package/src/utils/constants.ts +0 -39
- package/src/utils/container.ts +0 -92
- package/src/utils/containerSetup.ts +0 -371
- package/src/utils/convertMessagesForAPI.ts +0 -326
- package/src/utils/cronTasks.ts +0 -128
- package/src/utils/cronTasksLock.ts +0 -182
- package/src/utils/cronToHuman.ts +0 -99
- package/src/utils/customCommands.ts +0 -95
- package/src/utils/editUtils.ts +0 -20
- package/src/utils/fileFormat.ts +0 -40
- package/src/utils/fileSearch.ts +0 -151
- package/src/utils/fileUtils.ts +0 -223
- package/src/utils/gitUtils.ts +0 -315
- package/src/utils/globalLogger.ts +0 -128
- package/src/utils/groupMessagesByApiRound.ts +0 -121
- package/src/utils/hookMatcher.ts +0 -176
- package/src/utils/markdownParser.ts +0 -317
- package/src/utils/mcpUtils.ts +0 -138
- package/src/utils/messageOperations.ts +0 -641
- package/src/utils/modelCapabilities.ts +0 -30
- package/src/utils/nameGenerator.ts +0 -99
- package/src/utils/notificationXml.ts +0 -57
- package/src/utils/openaiClient.ts +0 -251
- package/src/utils/parseCronExpression.ts +0 -78
- package/src/utils/path.ts +0 -72
- package/src/utils/pathEncoder.ts +0 -400
- package/src/utils/pathSafety.ts +0 -40
- package/src/utils/promptHistory.ts +0 -168
- package/src/utils/ripgrep.ts +0 -35
- package/src/utils/shellResolver.ts +0 -190
- package/src/utils/skillParser.ts +0 -246
- package/src/utils/stringUtils.ts +0 -156
- package/src/utils/subagentParser.ts +0 -279
- package/src/utils/taskReminder.ts +0 -96
- package/src/utils/tokenCalculation.ts +0 -43
- package/src/utils/tokenEstimate.ts +0 -34
- package/src/utils/toolResultStorage.ts +0 -117
- package/src/utils/worktreeSession.ts +0 -26
- package/src/utils/worktreeUtils.ts +0 -786
- package/src/workflow/budgetTracker.ts +0 -34
- package/src/workflow/concurrencyLimiter.ts +0 -47
- package/src/workflow/journal.ts +0 -95
- package/src/workflow/progressReporter.ts +0 -141
- package/src/workflow/runState.ts +0 -65
- package/src/workflow/scriptRuntime.ts +0 -274
- package/src/workflow/structuredOutput.ts +0 -123
- package/src/workflow/types.ts +0 -101
- package/src/workflow/workflowApis.ts +0 -410
- package/vendor/ripgrep/linux-aarch64/rg +0 -0
- package/vendor/ripgrep/linux-x86_64/rg +0 -0
- package/vendor/ripgrep/macos-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-x86_64/rg +0 -0
- package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
- package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
|
@@ -1,641 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "crypto";
|
|
2
|
-
import type {
|
|
3
|
-
Message,
|
|
4
|
-
Usage,
|
|
5
|
-
ToolBlock,
|
|
6
|
-
TaskNotificationBlock,
|
|
7
|
-
} from "../types/index.js";
|
|
8
|
-
import { MessageSource } from "../types/index.js";
|
|
9
|
-
import { readFileSync } from "fs";
|
|
10
|
-
import { extname } from "path";
|
|
11
|
-
import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
|
|
12
|
-
import { logger } from "./globalLogger.js";
|
|
13
|
-
|
|
14
|
-
// Base user message parameters interface
|
|
15
|
-
export interface UserMessageParams {
|
|
16
|
-
content: string;
|
|
17
|
-
customCommandContent?: string;
|
|
18
|
-
images?: Array<{ path: string; mimeType: string }>;
|
|
19
|
-
source?: MessageSource;
|
|
20
|
-
isMeta?: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Parameter interfaces for message operations
|
|
24
|
-
export interface AddUserMessageParams extends UserMessageParams {
|
|
25
|
-
messages: Message[];
|
|
26
|
-
id?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface UpdateToolBlockParams {
|
|
30
|
-
messages: Message[];
|
|
31
|
-
id: string;
|
|
32
|
-
messageId?: string; // Optional message ID to target a specific message
|
|
33
|
-
parameters?: string;
|
|
34
|
-
result?: string;
|
|
35
|
-
success?: boolean;
|
|
36
|
-
error?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Tool execution stage:
|
|
39
|
-
* - 'start': Tool call initiated during AI streaming
|
|
40
|
-
* - 'streaming': Tool parameters being received incrementally
|
|
41
|
-
* - 'running': Tool execution in progress
|
|
42
|
-
* - 'end': Tool execution completed with final result
|
|
43
|
-
*/
|
|
44
|
-
stage?: "start" | "streaming" | "running" | "end";
|
|
45
|
-
name?: string;
|
|
46
|
-
shortResult?: string;
|
|
47
|
-
startLineNumber?: number;
|
|
48
|
-
images?: Array<{ data: string; mediaType?: string }>;
|
|
49
|
-
compactParams?: string;
|
|
50
|
-
parametersChunk?: string; // Incremental parameter updates for streaming
|
|
51
|
-
isManuallyBackgrounded?: boolean;
|
|
52
|
-
timestamp?: number;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Agent specific interfaces (without messages parameter)
|
|
56
|
-
export type AgentToolBlockUpdateParams = Omit<
|
|
57
|
-
UpdateToolBlockParams,
|
|
58
|
-
"messages"
|
|
59
|
-
>;
|
|
60
|
-
|
|
61
|
-
// Callback payload type — SDK always fills messageId (required)
|
|
62
|
-
export type ToolBlockUpdateCallbackParams = Omit<
|
|
63
|
-
AgentToolBlockUpdateParams,
|
|
64
|
-
"messageId"
|
|
65
|
-
> & {
|
|
66
|
-
messageId: string;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export interface AddErrorBlockParams {
|
|
70
|
-
messages: Message[];
|
|
71
|
-
error: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface AddBangParams {
|
|
75
|
-
messages: Message[];
|
|
76
|
-
command: string;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface UpdateBangParams {
|
|
80
|
-
messages: Message[];
|
|
81
|
-
command: string;
|
|
82
|
-
output: string;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface CompleteBangParams {
|
|
86
|
-
messages: Message[];
|
|
87
|
-
command: string;
|
|
88
|
-
exitCode: number;
|
|
89
|
-
output?: string;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Convert image file path to base64 format
|
|
94
|
-
* @param imagePath Image file path
|
|
95
|
-
* @returns base64 format image data URL
|
|
96
|
-
*/
|
|
97
|
-
export const convertImageToBase64 = (imagePath: string): string => {
|
|
98
|
-
try {
|
|
99
|
-
const imageBuffer = readFileSync(imagePath);
|
|
100
|
-
const ext = extname(imagePath).toLowerCase().substring(1);
|
|
101
|
-
|
|
102
|
-
// Determine MIME type based on file extension
|
|
103
|
-
let mimeType = "image/png"; // Default
|
|
104
|
-
switch (ext) {
|
|
105
|
-
case "jpg":
|
|
106
|
-
case "jpeg":
|
|
107
|
-
mimeType = "image/jpeg";
|
|
108
|
-
break;
|
|
109
|
-
case "png":
|
|
110
|
-
mimeType = "image/png";
|
|
111
|
-
break;
|
|
112
|
-
case "gif":
|
|
113
|
-
mimeType = "image/gif";
|
|
114
|
-
break;
|
|
115
|
-
case "webp":
|
|
116
|
-
mimeType = "image/webp";
|
|
117
|
-
break;
|
|
118
|
-
case "bmp":
|
|
119
|
-
mimeType = "image/bmp";
|
|
120
|
-
break;
|
|
121
|
-
default:
|
|
122
|
-
mimeType = "image/png";
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const base64String = imageBuffer.toString("base64");
|
|
126
|
-
return `data:${mimeType};base64,${base64String}`;
|
|
127
|
-
} catch (error) {
|
|
128
|
-
logger.error(`Failed to convert image to base64: ${imagePath}`, error);
|
|
129
|
-
// Return an error placeholder or throw error
|
|
130
|
-
return `data:image/png;base64,`; // Empty base64, avoid program crash
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export const generateMessageId = (): string => `msg-${randomUUID()}`;
|
|
135
|
-
|
|
136
|
-
// Add user message
|
|
137
|
-
export const addUserMessageToMessages = ({
|
|
138
|
-
messages,
|
|
139
|
-
content,
|
|
140
|
-
customCommandContent,
|
|
141
|
-
images,
|
|
142
|
-
source,
|
|
143
|
-
id,
|
|
144
|
-
isMeta,
|
|
145
|
-
}: AddUserMessageParams): Message[] => {
|
|
146
|
-
const blocks: Message["blocks"] = [];
|
|
147
|
-
|
|
148
|
-
// Create text block with optional source and customCommandContent
|
|
149
|
-
const textBlock = {
|
|
150
|
-
type: "text" as const,
|
|
151
|
-
content,
|
|
152
|
-
stage: "end" as const,
|
|
153
|
-
...(customCommandContent && { customCommandContent }),
|
|
154
|
-
...(source && { source }),
|
|
155
|
-
};
|
|
156
|
-
blocks.push(textBlock);
|
|
157
|
-
|
|
158
|
-
// If there are images, add image block
|
|
159
|
-
if (images && images.length > 0) {
|
|
160
|
-
const imageUrls = images.map((img) => img.path);
|
|
161
|
-
blocks.push({
|
|
162
|
-
type: "image",
|
|
163
|
-
imageUrls,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const userMessage: Message = {
|
|
168
|
-
id: id || generateMessageId(),
|
|
169
|
-
role: "user",
|
|
170
|
-
blocks,
|
|
171
|
-
timestamp: new Date().toISOString(),
|
|
172
|
-
...(isMeta !== undefined && { isMeta }),
|
|
173
|
-
};
|
|
174
|
-
return [...messages, userMessage];
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Update a user message's content by its ID.
|
|
179
|
-
*/
|
|
180
|
-
export const updateUserMessageInMessages = (
|
|
181
|
-
messages: Message[],
|
|
182
|
-
id: string,
|
|
183
|
-
params: Partial<UserMessageParams>,
|
|
184
|
-
): Message[] => {
|
|
185
|
-
return messages.map((msg) => {
|
|
186
|
-
if (msg.id === id && msg.role === "user") {
|
|
187
|
-
const newBlocks = msg.blocks.map((block) => {
|
|
188
|
-
if (block.type === "text") {
|
|
189
|
-
return {
|
|
190
|
-
...block,
|
|
191
|
-
...(params.content !== undefined && { content: params.content }),
|
|
192
|
-
...(params.customCommandContent !== undefined && {
|
|
193
|
-
customCommandContent: params.customCommandContent,
|
|
194
|
-
}),
|
|
195
|
-
...(params.source !== undefined && { source: params.source }),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
return block;
|
|
199
|
-
});
|
|
200
|
-
return {
|
|
201
|
-
...msg,
|
|
202
|
-
blocks: newBlocks,
|
|
203
|
-
...(params.isMeta !== undefined && { isMeta: params.isMeta }),
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
return msg;
|
|
207
|
-
});
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// Add assistant message (support one-time addition of answer and tool calls)
|
|
211
|
-
export const addAssistantMessageToMessages = (
|
|
212
|
-
messages: Message[],
|
|
213
|
-
content?: string,
|
|
214
|
-
toolCalls?: ChatCompletionMessageFunctionToolCall[],
|
|
215
|
-
usage?: Usage,
|
|
216
|
-
additionalFields?: Record<string, unknown>,
|
|
217
|
-
): Message[] => {
|
|
218
|
-
const blocks: Message["blocks"] = [];
|
|
219
|
-
|
|
220
|
-
// If there's answer content, add text block
|
|
221
|
-
if (content) {
|
|
222
|
-
blocks.push({ type: "text", content: content });
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// If there are tool calls, add tool blocks
|
|
226
|
-
if (toolCalls && toolCalls.length > 0) {
|
|
227
|
-
toolCalls.forEach((toolCall) => {
|
|
228
|
-
blocks.push({
|
|
229
|
-
type: "tool",
|
|
230
|
-
parameters: toolCall.function.arguments || "",
|
|
231
|
-
result: "",
|
|
232
|
-
id: toolCall.id || "",
|
|
233
|
-
name: toolCall.function?.name || "",
|
|
234
|
-
stage: "start",
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const initialAssistantMessage: Message = {
|
|
240
|
-
id: generateMessageId(),
|
|
241
|
-
role: "assistant",
|
|
242
|
-
blocks,
|
|
243
|
-
timestamp: new Date().toISOString(),
|
|
244
|
-
usage, // Include usage data if provided
|
|
245
|
-
...(additionalFields ? { additionalFields: { ...additionalFields } } : {}),
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
return [...messages, initialAssistantMessage];
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Add a tool block to a specific message by ID.
|
|
253
|
-
*/
|
|
254
|
-
export const addToolBlockToMessageInMessages = (
|
|
255
|
-
messages: Message[],
|
|
256
|
-
messageId: string,
|
|
257
|
-
params: Omit<AgentToolBlockUpdateParams, "id">,
|
|
258
|
-
): { messages: Message[]; toolBlockId: string } => {
|
|
259
|
-
const toolBlockId = randomUUID();
|
|
260
|
-
const newMessages = messages.map((msg) => {
|
|
261
|
-
if (msg.id === messageId) {
|
|
262
|
-
return {
|
|
263
|
-
...msg,
|
|
264
|
-
blocks: [
|
|
265
|
-
...msg.blocks,
|
|
266
|
-
{
|
|
267
|
-
type: "tool" as const,
|
|
268
|
-
id: toolBlockId,
|
|
269
|
-
name: params.name || "unknown",
|
|
270
|
-
parameters: params.parameters || "",
|
|
271
|
-
result: params.result || "",
|
|
272
|
-
stage: "start",
|
|
273
|
-
...params,
|
|
274
|
-
} as ToolBlock,
|
|
275
|
-
],
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
return msg;
|
|
279
|
-
});
|
|
280
|
-
return { messages: newMessages, toolBlockId };
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
// Update Tool Block of the last assistant or user message
|
|
284
|
-
export const updateToolBlockInMessage = ({
|
|
285
|
-
messages,
|
|
286
|
-
id,
|
|
287
|
-
messageId,
|
|
288
|
-
parameters,
|
|
289
|
-
result,
|
|
290
|
-
success,
|
|
291
|
-
error,
|
|
292
|
-
stage,
|
|
293
|
-
name,
|
|
294
|
-
shortResult,
|
|
295
|
-
startLineNumber,
|
|
296
|
-
images,
|
|
297
|
-
compactParams,
|
|
298
|
-
parametersChunk,
|
|
299
|
-
isManuallyBackgrounded,
|
|
300
|
-
}: UpdateToolBlockParams): { messages: Message[]; messageId?: string } => {
|
|
301
|
-
const newMessages = [...messages];
|
|
302
|
-
|
|
303
|
-
// If messageId is provided, target that specific message
|
|
304
|
-
if (messageId) {
|
|
305
|
-
const messageIndex = newMessages.findIndex((msg) => msg.id === messageId);
|
|
306
|
-
if (messageIndex !== -1) {
|
|
307
|
-
const toolBlockIndex = newMessages[messageIndex].blocks.findIndex(
|
|
308
|
-
(block) => block.type === "tool" && block.id === id,
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
if (toolBlockIndex !== -1) {
|
|
312
|
-
const toolBlock = newMessages[messageIndex].blocks[toolBlockIndex];
|
|
313
|
-
if (toolBlock.type === "tool") {
|
|
314
|
-
if (parameters !== undefined) toolBlock.parameters = parameters;
|
|
315
|
-
if (result !== undefined) toolBlock.result = result;
|
|
316
|
-
if (shortResult !== undefined) toolBlock.shortResult = shortResult;
|
|
317
|
-
if (startLineNumber !== undefined)
|
|
318
|
-
toolBlock.startLineNumber = startLineNumber;
|
|
319
|
-
if (images !== undefined) toolBlock.images = images;
|
|
320
|
-
if (success !== undefined) toolBlock.success = success;
|
|
321
|
-
if (error !== undefined) toolBlock.error = error;
|
|
322
|
-
if (stage !== undefined) toolBlock.stage = stage;
|
|
323
|
-
if (compactParams !== undefined)
|
|
324
|
-
toolBlock.compactParams = compactParams;
|
|
325
|
-
if (parametersChunk !== undefined)
|
|
326
|
-
toolBlock.parametersChunk = parametersChunk;
|
|
327
|
-
if (isManuallyBackgrounded !== undefined)
|
|
328
|
-
toolBlock.isManuallyBackgrounded = isManuallyBackgrounded;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return { messages: newMessages, messageId };
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Find the last assistant or user message
|
|
336
|
-
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
337
|
-
if (newMessages[i].role === "assistant" || newMessages[i].role === "user") {
|
|
338
|
-
const toolBlockIndex = newMessages[i].blocks.findIndex(
|
|
339
|
-
(block) => block.type === "tool" && block.id === id,
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
if (toolBlockIndex !== -1) {
|
|
343
|
-
const toolBlock = newMessages[i].blocks[toolBlockIndex];
|
|
344
|
-
if (toolBlock.type === "tool") {
|
|
345
|
-
if (parameters !== undefined) toolBlock.parameters = parameters;
|
|
346
|
-
if (result !== undefined) toolBlock.result = result;
|
|
347
|
-
if (shortResult !== undefined) toolBlock.shortResult = shortResult;
|
|
348
|
-
if (startLineNumber !== undefined)
|
|
349
|
-
toolBlock.startLineNumber = startLineNumber;
|
|
350
|
-
if (images !== undefined) toolBlock.images = images; // Add image data update
|
|
351
|
-
if (success !== undefined) toolBlock.success = success;
|
|
352
|
-
if (error !== undefined) toolBlock.error = error;
|
|
353
|
-
if (stage !== undefined) toolBlock.stage = stage;
|
|
354
|
-
if (compactParams !== undefined)
|
|
355
|
-
toolBlock.compactParams = compactParams;
|
|
356
|
-
if (parametersChunk !== undefined)
|
|
357
|
-
toolBlock.parametersChunk = parametersChunk;
|
|
358
|
-
if (isManuallyBackgrounded !== undefined)
|
|
359
|
-
toolBlock.isManuallyBackgrounded = isManuallyBackgrounded;
|
|
360
|
-
}
|
|
361
|
-
const foundMessageId = newMessages[i].id;
|
|
362
|
-
return { messages: newMessages, messageId: foundMessageId };
|
|
363
|
-
} else if (newMessages[i].role === "assistant") {
|
|
364
|
-
// If existing block not found in assistant message, create new one
|
|
365
|
-
// This handles cases where we're streaming tool parameters before execution
|
|
366
|
-
newMessages[i].blocks.push({
|
|
367
|
-
type: "tool",
|
|
368
|
-
parameters: parameters,
|
|
369
|
-
result: result || "",
|
|
370
|
-
shortResult: shortResult,
|
|
371
|
-
startLineNumber: startLineNumber,
|
|
372
|
-
images: images, // Add image data
|
|
373
|
-
id: id,
|
|
374
|
-
name: name || "unknown",
|
|
375
|
-
success: success,
|
|
376
|
-
error: error,
|
|
377
|
-
stage: stage ?? "start",
|
|
378
|
-
compactParams: compactParams,
|
|
379
|
-
parametersChunk: parametersChunk,
|
|
380
|
-
isManuallyBackgrounded: isManuallyBackgrounded,
|
|
381
|
-
});
|
|
382
|
-
const foundMessageId = newMessages[i].id;
|
|
383
|
-
return { messages: newMessages, messageId: foundMessageId };
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return { messages: newMessages };
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
// Add Error Block to the last assistant message
|
|
391
|
-
export const addErrorBlockToMessage = ({
|
|
392
|
-
messages,
|
|
393
|
-
error,
|
|
394
|
-
}: AddErrorBlockParams): Message[] => {
|
|
395
|
-
const newMessages = [...messages];
|
|
396
|
-
|
|
397
|
-
// Check if the last message is an assistant message
|
|
398
|
-
const lastMessage = newMessages[newMessages.length - 1];
|
|
399
|
-
if (lastMessage && lastMessage.role === "assistant") {
|
|
400
|
-
// Create a new message object with the error block added
|
|
401
|
-
newMessages[newMessages.length - 1] = {
|
|
402
|
-
...lastMessage,
|
|
403
|
-
blocks: [
|
|
404
|
-
...lastMessage.blocks,
|
|
405
|
-
{
|
|
406
|
-
type: "error",
|
|
407
|
-
content: error,
|
|
408
|
-
},
|
|
409
|
-
],
|
|
410
|
-
};
|
|
411
|
-
} else {
|
|
412
|
-
// If the last message is not an assistant message, create a new assistant message
|
|
413
|
-
newMessages.push({
|
|
414
|
-
id: generateMessageId(),
|
|
415
|
-
role: "assistant",
|
|
416
|
-
blocks: [
|
|
417
|
-
{
|
|
418
|
-
type: "error",
|
|
419
|
-
content: error,
|
|
420
|
-
},
|
|
421
|
-
],
|
|
422
|
-
timestamp: new Date().toISOString(),
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
return newMessages;
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
// Add bang block to message list
|
|
430
|
-
export const addBangMessage = ({
|
|
431
|
-
messages,
|
|
432
|
-
command,
|
|
433
|
-
}: AddBangParams): Message[] => {
|
|
434
|
-
const outputMessage: Message = {
|
|
435
|
-
id: generateMessageId(),
|
|
436
|
-
role: "user",
|
|
437
|
-
blocks: [
|
|
438
|
-
{
|
|
439
|
-
type: "bang",
|
|
440
|
-
command,
|
|
441
|
-
output: "",
|
|
442
|
-
stage: "running" as const,
|
|
443
|
-
exitCode: null,
|
|
444
|
-
},
|
|
445
|
-
],
|
|
446
|
-
timestamp: new Date().toISOString(),
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
return [...messages, outputMessage];
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
// Update output content of bang block
|
|
453
|
-
export const updateBangInMessage = ({
|
|
454
|
-
messages,
|
|
455
|
-
command,
|
|
456
|
-
output,
|
|
457
|
-
}: UpdateBangParams): Message[] => {
|
|
458
|
-
const newMessages = [...messages];
|
|
459
|
-
// Find the last user message with a bang block for this command
|
|
460
|
-
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
461
|
-
const msg = newMessages[i];
|
|
462
|
-
if (msg.role === "user") {
|
|
463
|
-
const commandBlock = msg.blocks.find(
|
|
464
|
-
(block) =>
|
|
465
|
-
block.type === "bang" &&
|
|
466
|
-
block.command === command &&
|
|
467
|
-
block.stage === "running",
|
|
468
|
-
);
|
|
469
|
-
if (commandBlock && commandBlock.type === "bang") {
|
|
470
|
-
commandBlock.output = output.trim();
|
|
471
|
-
break;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return newMessages;
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
// Complete bang execution, update exit status
|
|
479
|
-
export const completeBangInMessage = ({
|
|
480
|
-
messages,
|
|
481
|
-
command,
|
|
482
|
-
exitCode,
|
|
483
|
-
output,
|
|
484
|
-
}: CompleteBangParams): Message[] => {
|
|
485
|
-
const newMessages = [...messages];
|
|
486
|
-
// Find the last user message with a bang block for this command
|
|
487
|
-
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
488
|
-
const msg = newMessages[i];
|
|
489
|
-
if (msg.role === "user") {
|
|
490
|
-
const commandBlock = msg.blocks.find(
|
|
491
|
-
(block) =>
|
|
492
|
-
block.type === "bang" &&
|
|
493
|
-
block.command === command &&
|
|
494
|
-
block.stage === "running",
|
|
495
|
-
);
|
|
496
|
-
if (commandBlock && commandBlock.type === "bang") {
|
|
497
|
-
commandBlock.stage = "end";
|
|
498
|
-
commandBlock.exitCode = exitCode;
|
|
499
|
-
if (output !== undefined) {
|
|
500
|
-
commandBlock.output = output.trim();
|
|
501
|
-
}
|
|
502
|
-
break;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return newMessages;
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
/**
|
|
510
|
-
* Helper to count tool blocks in messages
|
|
511
|
-
*/
|
|
512
|
-
export function countToolBlocks(messages: Message[]): number {
|
|
513
|
-
let toolCount = 0;
|
|
514
|
-
messages.forEach((msg) => {
|
|
515
|
-
msg.blocks.forEach((block) => {
|
|
516
|
-
if (block.type === "tool") {
|
|
517
|
-
toolCount++;
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
});
|
|
521
|
-
return toolCount;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Remove the last user message from the conversation
|
|
526
|
-
* Used for hook error handling when the user prompt needs to be erased
|
|
527
|
-
*/
|
|
528
|
-
export const removeLastUserMessage = (messages: Message[]): Message[] => {
|
|
529
|
-
const newMessages = [...messages];
|
|
530
|
-
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
531
|
-
if (newMessages[i].role === "user") {
|
|
532
|
-
newMessages.splice(i, 1);
|
|
533
|
-
break;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return newMessages;
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Efficiently clone a message for UI freezing.
|
|
541
|
-
* Clones the message object and its blocks array, but reuses string references.
|
|
542
|
-
*/
|
|
543
|
-
export function cloneMessage(message: Message): Message {
|
|
544
|
-
return {
|
|
545
|
-
...message,
|
|
546
|
-
blocks: message.blocks.map((block) => {
|
|
547
|
-
const clonedBlock = { ...block };
|
|
548
|
-
// Deep clone arrays/objects within blocks if they exist
|
|
549
|
-
if (clonedBlock.type === "tool" && clonedBlock.images) {
|
|
550
|
-
clonedBlock.images = clonedBlock.images.map((img) => ({ ...img }));
|
|
551
|
-
} else if (clonedBlock.type === "image" && clonedBlock.imageUrls) {
|
|
552
|
-
clonedBlock.imageUrls = [...clonedBlock.imageUrls];
|
|
553
|
-
} else if (clonedBlock.type === "file_history" && clonedBlock.snapshots) {
|
|
554
|
-
clonedBlock.snapshots = clonedBlock.snapshots.map((s) => ({ ...s }));
|
|
555
|
-
}
|
|
556
|
-
return clonedBlock;
|
|
557
|
-
}) as Message["blocks"],
|
|
558
|
-
// Clone additionalFields if it exists
|
|
559
|
-
...(message.additionalFields
|
|
560
|
-
? { additionalFields: { ...message.additionalFields } }
|
|
561
|
-
: {}),
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
/**
|
|
566
|
-
* Helper to format tool and token summary
|
|
567
|
-
*/
|
|
568
|
-
export function formatToolTokenSummary(
|
|
569
|
-
toolCount: number,
|
|
570
|
-
tokens: number,
|
|
571
|
-
): string {
|
|
572
|
-
if (toolCount === 0) {
|
|
573
|
-
return "";
|
|
574
|
-
}
|
|
575
|
-
let summary = `(${toolCount} tools`;
|
|
576
|
-
if (tokens > 0) {
|
|
577
|
-
summary += ` | ${tokens.toLocaleString()} tokens`;
|
|
578
|
-
}
|
|
579
|
-
summary += ")";
|
|
580
|
-
return summary;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* Extracts displayable text from a Message object, handling various block types.
|
|
585
|
-
* Returns the first available content block.
|
|
586
|
-
*/
|
|
587
|
-
export function getMessageContent(message: Message): string {
|
|
588
|
-
// Find first available content block
|
|
589
|
-
const textBlock = message.blocks.find((block) => block.type === "text");
|
|
590
|
-
if (textBlock && "content" in textBlock) {
|
|
591
|
-
return textBlock.content;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
const bangBlock = message.blocks.find((block) => block.type === "bang");
|
|
595
|
-
if (bangBlock && "command" in bangBlock) {
|
|
596
|
-
return `!${bangBlock.command}`;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
const compactBlock = message.blocks.find((block) => block.type === "compact");
|
|
600
|
-
if (compactBlock && "content" in compactBlock) {
|
|
601
|
-
return compactBlock.content;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return "";
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
export interface AddNotificationMessageParams {
|
|
608
|
-
messages: Message[];
|
|
609
|
-
taskId: string;
|
|
610
|
-
taskType: "shell" | "agent" | "workflow";
|
|
611
|
-
status: "completed" | "failed" | "killed" | "aborted";
|
|
612
|
-
summary: string;
|
|
613
|
-
outputFile?: string;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
export const addNotificationMessageToMessages = ({
|
|
617
|
-
messages,
|
|
618
|
-
taskId,
|
|
619
|
-
taskType,
|
|
620
|
-
status,
|
|
621
|
-
summary,
|
|
622
|
-
outputFile,
|
|
623
|
-
}: AddNotificationMessageParams): Message[] => {
|
|
624
|
-
const block: TaskNotificationBlock = {
|
|
625
|
-
type: "task_notification",
|
|
626
|
-
taskId,
|
|
627
|
-
taskType,
|
|
628
|
-
status,
|
|
629
|
-
summary,
|
|
630
|
-
...(outputFile !== undefined && { outputFile }),
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
const notificationMessage: Message = {
|
|
634
|
-
id: generateMessageId(),
|
|
635
|
-
role: "user",
|
|
636
|
-
blocks: [block],
|
|
637
|
-
timestamp: new Date().toISOString(),
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
return [...messages, notificationMessage];
|
|
641
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model Capability Detection
|
|
3
|
-
*
|
|
4
|
-
* Pure declarative capability accessors. Capabilities are configured per-model
|
|
5
|
-
* via the `capabilities` field in `ModelConfig` (settings.json), not via regex
|
|
6
|
-
* or environment variables.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { ModelCapabilities } from "../types/config.js";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Determines if a model supports prompt caching.
|
|
13
|
-
* @param capabilities - Declarative model capabilities
|
|
14
|
-
* @returns True if promptCaching is explicitly enabled (default: false)
|
|
15
|
-
*/
|
|
16
|
-
export function supportsPromptCaching(
|
|
17
|
-
capabilities?: ModelCapabilities,
|
|
18
|
-
): boolean {
|
|
19
|
-
return capabilities?.promptCaching ?? false;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Determines if a model supports image/vision recognition.
|
|
24
|
-
* Opt-out semantics: by default all models are assumed to support vision.
|
|
25
|
-
* @param capabilities - Declarative model capabilities
|
|
26
|
-
* @returns True unless vision is explicitly disabled (default: true)
|
|
27
|
-
*/
|
|
28
|
-
export function supportsVision(capabilities?: ModelCapabilities): boolean {
|
|
29
|
-
return capabilities?.vision ?? true;
|
|
30
|
-
}
|