wave-agent-sdk 0.18.7 → 0.19.0
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/builtin/skills/settings/ENV.md +0 -1
- package/builtin/skills/settings/HOOKS.md +10 -0
- package/builtin/skills/settings/MODELS.md +37 -0
- package/builtin/skills/settings/SKILLS.md +6 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +12 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +20 -4
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +7 -2
- package/dist/managers/messageManager.d.ts +3 -5
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +17 -77
- package/dist/managers/skillManager.d.ts +1 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +11 -2
- package/dist/prompts/index.d.ts +3 -2
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +5 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +13 -9
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +22 -9
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +6 -0
- package/dist/services/initializationService.d.ts.map +1 -1
- package/dist/services/initializationService.js +1 -1
- package/dist/services/interactionService.js +1 -1
- package/dist/services/reversionService.d.ts +5 -1
- package/dist/services/reversionService.d.ts.map +1 -1
- package/dist/services/reversionService.js +50 -22
- package/dist/services/session.d.ts +4 -13
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +59 -215
- package/dist/telemetry/sessionTracing.d.ts +14 -4
- package/dist/telemetry/sessionTracing.d.ts.map +1 -1
- package/dist/telemetry/sessionTracing.js +134 -8
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +16 -1
- package/dist/types/config.d.ts +7 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +1 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +0 -1
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/skills.d.ts +1 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +14 -1
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/utils/atomicWrite.d.ts +15 -0
- package/dist/utils/atomicWrite.d.ts.map +1 -0
- package/dist/utils/atomicWrite.js +59 -0
- package/dist/utils/cacheControlUtils.d.ts +3 -15
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +4 -35
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +5 -1
- package/dist/utils/convertMessagesForAPI.d.ts +9 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +74 -55
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/mcpUtils.js +2 -1
- package/dist/utils/modelCapabilities.d.ts +22 -0
- package/dist/utils/modelCapabilities.d.ts.map +1 -0
- package/dist/utils/modelCapabilities.js +24 -0
- package/dist/utils/skillParser.d.ts.map +1 -1
- package/dist/utils/skillParser.js +3 -1
- package/package.json +1 -1
- package/src/agent.ts +11 -5
- package/src/index.ts +1 -0
- package/src/managers/aiManager.ts +22 -2
- package/src/managers/mcpManager.ts +8 -2
- package/src/managers/messageManager.ts +22 -104
- package/src/managers/skillManager.ts +16 -2
- package/src/prompts/index.ts +6 -1
- package/src/services/aiService.ts +12 -5
- package/src/services/configurationService.ts +24 -24
- package/src/services/hook.ts +7 -0
- package/src/services/initializationService.ts +1 -3
- package/src/services/interactionService.ts +1 -1
- package/src/services/reversionService.ts +50 -27
- package/src/services/session.ts +63 -262
- package/src/telemetry/sessionTracing.ts +167 -12
- package/src/tools/bashTool.ts +23 -1
- package/src/types/config.ts +8 -0
- package/src/types/hooks.ts +1 -0
- package/src/types/messaging.ts +0 -1
- package/src/types/skills.ts +1 -0
- package/src/types/telemetry.ts +17 -1
- package/src/utils/atomicWrite.ts +61 -0
- package/src/utils/cacheControlUtils.ts +5 -38
- package/src/utils/containerSetup.ts +5 -1
- package/src/utils/convertMessagesForAPI.ts +87 -57
- package/src/utils/mcpUtils.ts +2 -1
- package/src/utils/modelCapabilities.ts +30 -0
- package/src/utils/skillParser.ts +3 -1
|
@@ -39,15 +39,26 @@ function safeToolArguments(args: string): string {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Options for converting messages to API format.
|
|
44
|
+
*/
|
|
45
|
+
export interface ConvertMessagesOptions {
|
|
46
|
+
/** When false, images are stripped and replaced with text placeholders. */
|
|
47
|
+
supportsVision?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
/**
|
|
43
51
|
* Convert message format to API call format, stopping when a compacted message is encountered.
|
|
44
52
|
* Messages with no meaningful content or tool calls are filtered out.
|
|
45
53
|
* @param messages Message list
|
|
54
|
+
* @param options Optional conversion options (e.g. supportsVision)
|
|
46
55
|
* @returns Converted API message format list
|
|
47
56
|
*/
|
|
48
57
|
export function convertMessagesForAPI(
|
|
49
58
|
messages: Message[],
|
|
59
|
+
options?: ConvertMessagesOptions,
|
|
50
60
|
): ChatCompletionMessageParam[] {
|
|
61
|
+
const supportsVision = options?.supportsVision !== false;
|
|
51
62
|
const recentMessages: ChatCompletionMessageParam[] = [];
|
|
52
63
|
|
|
53
64
|
const startIndex = messages.length - 1;
|
|
@@ -86,53 +97,64 @@ export function convertMessagesForAPI(
|
|
|
86
97
|
const completedToolIds = new Set<string>(); // Record completed tool IDs
|
|
87
98
|
|
|
88
99
|
if (toolBlocks.length > 0) {
|
|
100
|
+
// Collect image user messages to place after all tool messages
|
|
101
|
+
const imageUserMessages: ChatCompletionMessageParam[] = [];
|
|
102
|
+
|
|
89
103
|
toolBlocks.forEach((toolBlock) => {
|
|
90
104
|
// Only add completed tool blocks (i.e., stage is 'end')
|
|
91
105
|
if (toolBlock.id && toolBlock.stage === "end") {
|
|
92
106
|
completedToolIds.add(toolBlock.id);
|
|
93
107
|
|
|
94
|
-
//
|
|
108
|
+
// Always add a proper tool message to satisfy tool_call_id pairing
|
|
109
|
+
recentMessages.unshift({
|
|
110
|
+
tool_call_id: toolBlock.id,
|
|
111
|
+
role: "tool",
|
|
112
|
+
content: stripAnsiColors(toolBlock.result || ""),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// If there are images, also prepare a user message with image content
|
|
95
116
|
if (toolBlock.images && toolBlock.images.length > 0) {
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
if (supportsVision) {
|
|
118
|
+
const contentParts: ChatCompletionContentPart[] = [];
|
|
98
119
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
text: toolResultText,
|
|
104
|
-
});
|
|
120
|
+
toolBlock.images.forEach((image) => {
|
|
121
|
+
const imageUrl = image.data.startsWith("data:")
|
|
122
|
+
? image.data
|
|
123
|
+
: `data:${image.mediaType || "image/png"};base64,${image.data}`;
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
type: "image_url",
|
|
114
|
-
image_url: {
|
|
115
|
-
url: imageUrl,
|
|
116
|
-
detail: "auto",
|
|
117
|
-
},
|
|
125
|
+
contentParts.push({
|
|
126
|
+
type: "image_url",
|
|
127
|
+
image_url: {
|
|
128
|
+
url: imageUrl,
|
|
129
|
+
detail: "auto",
|
|
130
|
+
},
|
|
131
|
+
});
|
|
118
132
|
});
|
|
119
|
-
});
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
134
|
+
imageUserMessages.push({
|
|
135
|
+
role: "user",
|
|
136
|
+
content: contentParts,
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
// Non-vision model: replace images with a text placeholder
|
|
140
|
+
imageUserMessages.push({
|
|
141
|
+
role: "user",
|
|
142
|
+
content:
|
|
143
|
+
"[Tool returned an image, but the current model does not support image recognition]",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
133
146
|
}
|
|
134
147
|
}
|
|
135
148
|
});
|
|
149
|
+
|
|
150
|
+
// Insert image user messages after all tool messages but before the
|
|
151
|
+
// assistant message (which will be unshifted next). Since tool messages
|
|
152
|
+
// were unshifted to the front, we splice images right after them.
|
|
153
|
+
if (imageUserMessages.length > 0) {
|
|
154
|
+
// Tool messages are at indices 0..N-1, existing messages start at N
|
|
155
|
+
const toolMsgCount = completedToolIds.size;
|
|
156
|
+
recentMessages.splice(toolMsgCount, 0, ...imageUserMessages);
|
|
157
|
+
}
|
|
136
158
|
}
|
|
137
159
|
|
|
138
160
|
// Construct the content of the assistant message
|
|
@@ -227,32 +249,40 @@ export function convertMessagesForAPI(
|
|
|
227
249
|
block.imageUrls &&
|
|
228
250
|
block.imageUrls.length > 0
|
|
229
251
|
) {
|
|
230
|
-
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
252
|
+
if (!supportsVision) {
|
|
253
|
+
// Non-vision model: replace images with a text placeholder
|
|
254
|
+
contentParts.push({
|
|
255
|
+
type: "text",
|
|
256
|
+
text: "[User shared an image, but the current model does not support image recognition]",
|
|
257
|
+
});
|
|
258
|
+
} else {
|
|
259
|
+
block.imageUrls.forEach((imageUrl: string) => {
|
|
260
|
+
// Check if it's already base64, convert if not
|
|
261
|
+
let finalImageUrl = imageUrl;
|
|
262
|
+
if (!imageUrl.startsWith("data:image/")) {
|
|
263
|
+
// If it's a file path, it needs to be converted to base64
|
|
264
|
+
try {
|
|
265
|
+
finalImageUrl = convertImageToBase64(imageUrl);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
logger.error(
|
|
268
|
+
"Failed to convert image path to base64:",
|
|
269
|
+
imageUrl,
|
|
270
|
+
error,
|
|
271
|
+
);
|
|
272
|
+
// Skip this image, do not add to content
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
245
275
|
}
|
|
246
|
-
}
|
|
247
276
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
277
|
+
contentParts.push({
|
|
278
|
+
type: "image_url",
|
|
279
|
+
image_url: {
|
|
280
|
+
url: finalImageUrl,
|
|
281
|
+
detail: "auto",
|
|
282
|
+
},
|
|
283
|
+
});
|
|
254
284
|
});
|
|
255
|
-
}
|
|
285
|
+
}
|
|
256
286
|
}
|
|
257
287
|
|
|
258
288
|
// If there is a tool block in user message, add its result
|
package/src/utils/mcpUtils.ts
CHANGED
|
@@ -132,6 +132,7 @@ export function findToolServer(
|
|
|
132
132
|
): McpServerStatus | undefined {
|
|
133
133
|
return servers.find(
|
|
134
134
|
(s) =>
|
|
135
|
-
s.status === "connected"
|
|
135
|
+
(s.status === "connected" || s.status === "reconnecting") &&
|
|
136
|
+
s.tools?.some((t) => t.name === toolName),
|
|
136
137
|
);
|
|
137
138
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
}
|
package/src/utils/skillParser.ts
CHANGED
|
@@ -57,7 +57,9 @@ export function parseSkillFile(
|
|
|
57
57
|
skillPath.includes("/.wave/skills") ||
|
|
58
58
|
skillPath.includes("\\.wave\\skills") ||
|
|
59
59
|
skillPath.includes("/.claude/skills") ||
|
|
60
|
-
skillPath.includes("\\.claude\\skills")
|
|
60
|
+
skillPath.includes("\\.claude\\skills") ||
|
|
61
|
+
skillPath.includes("/.agents/skills") ||
|
|
62
|
+
skillPath.includes("\\.agents\\skills")
|
|
61
63
|
? "project"
|
|
62
64
|
: "personal";
|
|
63
65
|
|