wave-agent-sdk 0.17.9 → 0.17.10
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 +1 -1
- package/dist/managers/aiManager.d.ts +10 -4
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +214 -200
- package/dist/managers/backgroundTaskManager.js +1 -1
- package/dist/managers/bangManager.js +1 -1
- package/dist/managers/hookManager.js +2 -4
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +1 -3
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +1 -8
- package/dist/managers/toolManager.d.ts +6 -0
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +17 -12
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +20 -12
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +13 -0
- package/dist/services/jsonlHandler.d.ts +1 -1
- package/dist/services/jsonlHandler.d.ts.map +1 -1
- package/dist/services/jsonlHandler.js +7 -22
- package/dist/services/session.d.ts +2 -9
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +16 -46
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +3 -1
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +28 -1
- package/dist/tools/enterPlanMode.d.ts.map +1 -1
- package/dist/tools/enterPlanMode.js +8 -0
- package/dist/tools/exitPlanMode.d.ts.map +1 -1
- package/dist/tools/exitPlanMode.js +8 -0
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +18 -10
- package/dist/tools/types.d.ts +8 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +14 -1
- package/dist/types/agent.d.ts +0 -2
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.d.ts +20 -15
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +69 -66
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +1 -6
- package/package.json +1 -1
- package/src/managers/aiManager.ts +292 -263
- package/src/managers/backgroundTaskManager.ts +1 -1
- package/src/managers/bangManager.ts +1 -1
- package/src/managers/hookManager.ts +6 -6
- package/src/managers/mcpManager.ts +2 -4
- package/src/managers/messageManager.ts +1 -9
- package/src/managers/toolManager.ts +18 -12
- package/src/services/aiService.ts +23 -12
- package/src/services/configurationService.ts +21 -0
- package/src/services/jsonlHandler.ts +7 -27
- package/src/services/session.ts +16 -57
- package/src/tools/bashTool.ts +3 -1
- package/src/tools/editTool.ts +31 -1
- package/src/tools/enterPlanMode.ts +9 -0
- package/src/tools/exitPlanMode.ts +10 -0
- package/src/tools/readTool.ts +20 -10
- package/src/tools/types.ts +15 -3
- package/src/tools/writeTool.ts +15 -1
- package/src/types/agent.ts +0 -2
- package/src/types/config.ts +1 -0
- package/src/utils/cacheControlUtils.ts +77 -95
- package/src/utils/constants.ts +1 -1
- package/src/utils/containerSetup.ts +3 -7
|
@@ -27,7 +27,7 @@ Wave uses several environment variables to control its core functionality.
|
|
|
27
27
|
| `WAVE_CUSTOM_HEADERS` | Custom HTTP headers for the AI gateway. Newline-separated `Key: Value` pairs (e.g., `"X-Foo: bar\nAuthorization: Bearer xxx"`). | - |
|
|
28
28
|
| `WAVE_MODEL` | The primary AI model to use for the agent. | `gemini-3-flash` |
|
|
29
29
|
| `WAVE_FAST_MODEL` | The fast AI model to use for quick tasks. | `gemini-2.5-flash` |
|
|
30
|
-
| `WAVE_MAX_INPUT_TOKENS` | Maximum number of input tokens allowed. | `
|
|
30
|
+
| `WAVE_MAX_INPUT_TOKENS` | Maximum number of input tokens allowed. | `200000` |
|
|
31
31
|
| `WAVE_MAX_OUTPUT_TOKENS` | Maximum number of output tokens allowed. | `16384` |
|
|
32
32
|
| `WAVE_DISABLE_AUTO_MEMORY` | Set to `1` or `true` to disable the auto-memory feature. | `false` |
|
|
33
33
|
| `WAVE_AUTO_MEMORY_FREQUENCY` | Auto memory update frequency. `1` = every turn, `2` = every 2 turns, etc. | `1` |
|
|
@@ -31,6 +31,8 @@ export declare class AIManager {
|
|
|
31
31
|
private originalWorkdir;
|
|
32
32
|
private consecutiveCompactionFailures;
|
|
33
33
|
private readonly maxTurns?;
|
|
34
|
+
/** Tracks file mtime/hash at read time for staleness detection on Edit/Write */
|
|
35
|
+
private readFileState;
|
|
34
36
|
/** Override tool_choice for this AI manager (e.g. for structured output) */
|
|
35
37
|
toolChoiceOverride?: "auto" | "none" | "required" | {
|
|
36
38
|
type: "function";
|
|
@@ -69,11 +71,10 @@ export declare class AIManager {
|
|
|
69
71
|
*/
|
|
70
72
|
private getFilteredToolsConfig;
|
|
71
73
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* This preserves prompt caching by keeping the system prompt constant.
|
|
74
|
+
* Add plan mode reminder as a persistent meta message to the message manager.
|
|
75
|
+
* Called before getMessages() so the stored message is included in the API call.
|
|
75
76
|
*/
|
|
76
|
-
private
|
|
77
|
+
private maybeAddPlanModeMessage;
|
|
77
78
|
setIsLoading(isLoading: boolean): void;
|
|
78
79
|
abortAIMessage(): void;
|
|
79
80
|
private generateCompactParams;
|
|
@@ -108,6 +109,11 @@ export declare class AIManager {
|
|
|
108
109
|
* @returns Promise<boolean> - true if should continue conversation, false if should stop
|
|
109
110
|
*/
|
|
110
111
|
private executeStopHooks;
|
|
112
|
+
/**
|
|
113
|
+
* Execute a single tool call: arg parsing, block emission, PreToolUse hooks,
|
|
114
|
+
* tool execution, PostToolUse hooks, and error handling.
|
|
115
|
+
*/
|
|
116
|
+
private executeToolCall;
|
|
111
117
|
/**
|
|
112
118
|
* Execute PreToolUse hooks before tool execution
|
|
113
119
|
* Returns true if hooks allow tool execution, false if blocked
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
|
|
|
3
3
|
import { microcompactMessages } from "../utils/microcompact.js";
|
|
4
4
|
import { parseTaskNotificationXml } from "../utils/notificationXml.js";
|
|
5
5
|
import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
|
|
6
|
-
import * as fs from "node:fs/promises";
|
|
7
6
|
import { existsSync } from "node:fs";
|
|
8
7
|
import { buildSystemPrompt } from "../prompts/index.js";
|
|
9
8
|
import { buildPlanModeReminder, buildPlanModeReEntryReminder, buildExitedPlanModeReminder, } from "../prompts/planModeReminders.js";
|
|
@@ -19,6 +18,8 @@ export class AIManager {
|
|
|
19
18
|
this.abortController = null;
|
|
20
19
|
this.toolAbortController = null;
|
|
21
20
|
this.consecutiveCompactionFailures = 0;
|
|
21
|
+
/** Tracks file mtime/hash at read time for staleness detection on Edit/Write */
|
|
22
|
+
this.readFileState = new Map();
|
|
22
23
|
this.isCompacting = false;
|
|
23
24
|
this.systemPrompt = options.systemPrompt;
|
|
24
25
|
this.subagentType = options.subagentType; // Store subagent type
|
|
@@ -122,50 +123,47 @@ export class AIManager {
|
|
|
122
123
|
});
|
|
123
124
|
}
|
|
124
125
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* This preserves prompt caching by keeping the system prompt constant.
|
|
126
|
+
* Add plan mode reminder as a persistent meta message to the message manager.
|
|
127
|
+
* Called before getMessages() so the stored message is included in the API call.
|
|
128
128
|
*/
|
|
129
|
-
|
|
130
|
-
const messages = [];
|
|
129
|
+
maybeAddPlanModeMessage(currentMode) {
|
|
131
130
|
if (!this.permissionManager)
|
|
132
|
-
return
|
|
131
|
+
return;
|
|
133
132
|
// Handle exit notification (one-time after leaving plan mode)
|
|
134
133
|
if (this.permissionManager.getNeedsPlanModeExitAttachment()) {
|
|
135
134
|
const planFilePath = this.permissionManager.getPlanFilePath();
|
|
136
135
|
const planExists = planFilePath ? existsSync(planFilePath) : false;
|
|
137
|
-
|
|
138
|
-
role: "user",
|
|
136
|
+
this.messageManager.addUserMessage({
|
|
139
137
|
content: buildExitedPlanModeReminder(planFilePath, planExists),
|
|
138
|
+
isMeta: true,
|
|
140
139
|
});
|
|
141
140
|
this.permissionManager.setNeedsPlanModeExitAttachment(false);
|
|
142
141
|
}
|
|
143
142
|
if (currentMode !== "plan")
|
|
144
|
-
return
|
|
143
|
+
return;
|
|
145
144
|
const planFilePath = this.permissionManager.getPlanFilePath();
|
|
146
145
|
if (!planFilePath)
|
|
147
|
-
return
|
|
146
|
+
return;
|
|
148
147
|
const planExists = existsSync(planFilePath);
|
|
149
148
|
// One-time plan entry reminder
|
|
150
149
|
const planMgr = this.planManager;
|
|
151
150
|
if (planMgr?.isPlanEntryReminderPending()) {
|
|
152
151
|
if (this.permissionManager.hasExitedPlanModeInSession() && planExists) {
|
|
153
152
|
// Re-entry: use small reminder
|
|
154
|
-
|
|
155
|
-
role: "user",
|
|
153
|
+
this.messageManager.addUserMessage({
|
|
156
154
|
content: buildPlanModeReEntryReminder(planFilePath),
|
|
155
|
+
isMeta: true,
|
|
157
156
|
});
|
|
158
157
|
}
|
|
159
158
|
else {
|
|
160
159
|
// First entry: use full reminder
|
|
161
|
-
|
|
162
|
-
role: "user",
|
|
160
|
+
this.messageManager.addUserMessage({
|
|
163
161
|
content: buildPlanModeReminder(planFilePath, planExists, !!this.subagentType),
|
|
162
|
+
isMeta: true,
|
|
164
163
|
});
|
|
165
164
|
}
|
|
166
165
|
planMgr.consumePlanEntryReminder();
|
|
167
166
|
}
|
|
168
|
-
return messages;
|
|
169
167
|
}
|
|
170
168
|
setIsLoading(isLoading) {
|
|
171
169
|
this.isLoading = isLoading;
|
|
@@ -299,6 +297,18 @@ export class AIManager {
|
|
|
299
297
|
const enhancedSummary = await this.buildPostCompactContext(compactResult.content);
|
|
300
298
|
// 7. Execute message reconstruction
|
|
301
299
|
this.messageManager.compactMessagesAndUpdateSession(enhancedSummary, compactUsage);
|
|
300
|
+
// Re-add plan mode reminder as persistent meta message after compaction
|
|
301
|
+
const postCompactMode = this.permissionManager?.getCurrentEffectiveMode(this.getModelConfig().permissionMode);
|
|
302
|
+
if (postCompactMode === "plan") {
|
|
303
|
+
const planFilePath = this.permissionManager?.getPlanFilePath();
|
|
304
|
+
if (planFilePath) {
|
|
305
|
+
const planExists = existsSync(planFilePath);
|
|
306
|
+
this.messageManager.addUserMessage({
|
|
307
|
+
content: buildPlanModeReminder(planFilePath, planExists, !!this.subagentType),
|
|
308
|
+
isMeta: true,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
302
312
|
// 8. Track usage
|
|
303
313
|
if (compactUsage && this.callbacks?.onUsageAdded) {
|
|
304
314
|
this.callbacks.onUsageAdded(compactUsage);
|
|
@@ -376,22 +386,6 @@ export class AIManager {
|
|
|
376
386
|
if (usedTokens >= POST_COMPACT_TOKEN_BUDGET)
|
|
377
387
|
break;
|
|
378
388
|
}
|
|
379
|
-
// 2. Plan mode context
|
|
380
|
-
const currentMode = this.permissionManager?.getCurrentEffectiveMode(this.getModelConfig().permissionMode);
|
|
381
|
-
if (currentMode === "plan") {
|
|
382
|
-
const planFilePath = this.permissionManager?.getPlanFilePath();
|
|
383
|
-
if (planFilePath) {
|
|
384
|
-
let planExists = false;
|
|
385
|
-
try {
|
|
386
|
-
await fs.access(planFilePath);
|
|
387
|
-
planExists = true;
|
|
388
|
-
}
|
|
389
|
-
catch {
|
|
390
|
-
// Plan file doesn't exist yet
|
|
391
|
-
}
|
|
392
|
-
contextParts.push(`\n\n${buildPlanModeReminder(planFilePath, planExists, !!this.subagentType)}`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
389
|
// 4. Invoked skills context (with token budget, matching Claude Code)
|
|
396
390
|
const POST_COMPACT_SKILLS_TOKEN_BUDGET = 25000;
|
|
397
391
|
const POST_COMPACT_MAX_TOKENS_PER_SKILL = 5000;
|
|
@@ -549,6 +543,10 @@ export class AIManager {
|
|
|
549
543
|
abortController = this.abortController;
|
|
550
544
|
toolAbortController = this.toolAbortController;
|
|
551
545
|
}
|
|
546
|
+
// Get current permission mode
|
|
547
|
+
const currentMode = this.permissionManager?.getCurrentEffectiveMode(this.getModelConfig().permissionMode);
|
|
548
|
+
// Add plan mode reminder as persistent meta message before getting messages
|
|
549
|
+
this.maybeAddPlanModeMessage(currentMode);
|
|
552
550
|
// Get recent message history with microcompact applied
|
|
553
551
|
const rawMessages = this.messageManager.getMessages();
|
|
554
552
|
const microcompactedMessages = microcompactMessages(rawMessages, {
|
|
@@ -562,19 +560,11 @@ export class AIManager {
|
|
|
562
560
|
// Track if assistant message has been created
|
|
563
561
|
let assistantMessageCreated = false;
|
|
564
562
|
logger?.debug("modelConfig in sendAIMessage", this.getModelConfig());
|
|
565
|
-
// Get current permission mode and plan file path
|
|
566
|
-
const currentMode = this.permissionManager?.getCurrentEffectiveMode(this.getModelConfig().permissionMode);
|
|
567
563
|
const toolsConfig = this.getFilteredToolsConfig();
|
|
568
564
|
const toolNames = new Set(toolsConfig.map((t) => t.function.name));
|
|
569
565
|
const filteredToolPlugins = this.toolManager
|
|
570
566
|
.getTools()
|
|
571
567
|
.filter((t) => toolNames.has(t.name));
|
|
572
|
-
// Inject plan mode system-reminder messages (not system prompt)
|
|
573
|
-
// This preserves prompt caching by keeping the system prompt constant
|
|
574
|
-
const planModeMessages = this.buildPlanModeMessages(currentMode);
|
|
575
|
-
if (planModeMessages.length > 0) {
|
|
576
|
-
recentMessages.push(...planModeMessages);
|
|
577
|
-
}
|
|
578
568
|
let autoMemoryOptions;
|
|
579
569
|
if (this.getAutoMemoryEnabled()) {
|
|
580
570
|
const directory = this.memoryService.getAutoMemoryDirectory(this.getWorkdir());
|
|
@@ -719,170 +709,34 @@ export class AIManager {
|
|
|
719
709
|
}
|
|
720
710
|
}
|
|
721
711
|
if (toolCalls.length > 0) {
|
|
722
|
-
//
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
let toolArgs = {};
|
|
733
|
-
let jsonRecovered = false;
|
|
734
|
-
const argsString = functionToolCall.function?.arguments?.trim();
|
|
735
|
-
if (!argsString || argsString === "") {
|
|
736
|
-
// Tool without parameters, use empty object
|
|
737
|
-
toolArgs = {};
|
|
712
|
+
// Partition tool calls into batches: consecutive concurrency-safe
|
|
713
|
+
// tools run in parallel, non-safe tools (Edit, Write, MCP) run one
|
|
714
|
+
// at a time to prevent read-modify-write races on the same file.
|
|
715
|
+
const batches = [];
|
|
716
|
+
for (const call of toolCalls) {
|
|
717
|
+
const toolName = call.function?.name || "";
|
|
718
|
+
const safe = this.toolManager.isConcurrencySafe(toolName);
|
|
719
|
+
const lastBatch = batches[batches.length - 1];
|
|
720
|
+
if (lastBatch && lastBatch.safe && safe) {
|
|
721
|
+
lastBatch.calls.push(call);
|
|
738
722
|
}
|
|
739
723
|
else {
|
|
740
|
-
|
|
741
|
-
try {
|
|
742
|
-
toolArgs = JSON.parse(argsString);
|
|
743
|
-
}
|
|
744
|
-
catch {
|
|
745
|
-
// Attempt to recover truncated JSON (e.g., missing closing braces)
|
|
746
|
-
recoveredArgs = recoverTruncatedJson(argsString);
|
|
747
|
-
try {
|
|
748
|
-
toolArgs = JSON.parse(recoveredArgs);
|
|
749
|
-
jsonRecovered = true;
|
|
750
|
-
logger.warn(`Recovered truncated JSON for tool "${toolName}"`);
|
|
751
|
-
}
|
|
752
|
-
catch (parseError) {
|
|
753
|
-
let errorMessage = `Failed to parse tool arguments`;
|
|
754
|
-
if (result.finish_reason === "length") {
|
|
755
|
-
errorMessage +=
|
|
756
|
-
" (output truncated, please reduce your output)";
|
|
757
|
-
}
|
|
758
|
-
logger?.error(errorMessage, parseError);
|
|
759
|
-
this.messageManager.updateToolBlock({
|
|
760
|
-
id: toolId,
|
|
761
|
-
parameters: argsString,
|
|
762
|
-
result: errorMessage,
|
|
763
|
-
success: false,
|
|
764
|
-
error: errorMessage,
|
|
765
|
-
stage: "end",
|
|
766
|
-
name: toolName,
|
|
767
|
-
compactParams: "",
|
|
768
|
-
timestamp: Date.now(),
|
|
769
|
-
});
|
|
770
|
-
return;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
724
|
+
batches.push({ calls: [call], safe });
|
|
773
725
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
name: toolName,
|
|
781
|
-
compactParams,
|
|
782
|
-
parameters: argsString,
|
|
783
|
-
});
|
|
726
|
+
}
|
|
727
|
+
// Execute batches sequentially; within a safe batch, tools run in parallel
|
|
728
|
+
for (const batch of batches) {
|
|
729
|
+
if (abortController.signal.aborted ||
|
|
730
|
+
toolAbortController.signal.aborted) {
|
|
731
|
+
break;
|
|
784
732
|
}
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
id: toolId,
|
|
788
|
-
stage: "running",
|
|
789
|
-
name: toolName,
|
|
790
|
-
compactParams,
|
|
791
|
-
parameters: argsString,
|
|
792
|
-
parametersChunk: "",
|
|
793
|
-
});
|
|
794
|
-
try {
|
|
795
|
-
// Execute PreToolUse hooks before tool execution
|
|
796
|
-
const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
|
|
797
|
-
// If PreToolUse hooks blocked execution, skip tool execution
|
|
798
|
-
if (!shouldExecuteTool) {
|
|
799
|
-
logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
|
|
800
|
-
return; // Skip this tool and return from this map function
|
|
801
|
-
}
|
|
802
|
-
// Create tool execution context
|
|
803
|
-
const context = {
|
|
804
|
-
abortSignal: toolAbortController.signal,
|
|
805
|
-
backgroundTaskManager: this.backgroundTaskManager,
|
|
806
|
-
workdir: this.getWorkdir(),
|
|
807
|
-
originalWorkdir: this.originalWorkdir,
|
|
808
|
-
env: this.container.get("MergedEnv"),
|
|
809
|
-
messageId: this.messageManager.getMessages().slice(-1)[0]?.id,
|
|
810
|
-
sessionId: this.messageManager.getSessionId(),
|
|
811
|
-
toolCallId: toolId,
|
|
812
|
-
taskManager: this.taskManager,
|
|
813
|
-
onShortResultUpdate: (shortResult) => {
|
|
814
|
-
this.messageManager.updateToolBlock({
|
|
815
|
-
id: toolId,
|
|
816
|
-
shortResult,
|
|
817
|
-
stage: "running", // Keep it in running stage while updating shortResult
|
|
818
|
-
});
|
|
819
|
-
},
|
|
820
|
-
onResultUpdate: (result) => {
|
|
821
|
-
this.messageManager.updateToolBlock({
|
|
822
|
-
id: toolId,
|
|
823
|
-
result,
|
|
824
|
-
stage: "running", // Keep it in running stage while updating result
|
|
825
|
-
});
|
|
826
|
-
},
|
|
827
|
-
onCwdChange: async (newCwd) => {
|
|
828
|
-
const oldCwd = this.getWorkdir();
|
|
829
|
-
this.container.register("Workdir", newCwd);
|
|
830
|
-
this._onCwdChange?.(newCwd);
|
|
831
|
-
if (this.hookManager) {
|
|
832
|
-
const sessionId = this.messageManager.getSessionId();
|
|
833
|
-
const transcriptPath = this.messageManager.getTranscriptPath();
|
|
834
|
-
const env = Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined));
|
|
835
|
-
await this.hookManager.executeCwdChangedHooks(oldCwd, newCwd, sessionId, transcriptPath, env);
|
|
836
|
-
}
|
|
837
|
-
},
|
|
838
|
-
};
|
|
839
|
-
// Execute tool
|
|
840
|
-
const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
|
|
841
|
-
// Build result content, adding truncation warning if JSON was recovered
|
|
842
|
-
let toolResultContent = toolResult.content ||
|
|
843
|
-
(toolResult.error ? `Error: ${toolResult.error}` : "");
|
|
844
|
-
if (jsonRecovered) {
|
|
845
|
-
toolResultContent +=
|
|
846
|
-
"\n\nTool arguments were truncated (likely exceeded max output tokens). Please reduce your output or split into multiple tool calls.";
|
|
847
|
-
}
|
|
848
|
-
// Update message state - tool execution completed
|
|
849
|
-
this.messageManager.updateToolBlock({
|
|
850
|
-
id: toolId,
|
|
851
|
-
parameters: argsString,
|
|
852
|
-
result: toolResultContent,
|
|
853
|
-
success: toolResult.success,
|
|
854
|
-
error: toolResult.error,
|
|
855
|
-
stage: "end",
|
|
856
|
-
name: toolName,
|
|
857
|
-
compactParams,
|
|
858
|
-
shortResult: toolResult.shortResult,
|
|
859
|
-
isManuallyBackgrounded: toolResult.isManuallyBackgrounded,
|
|
860
|
-
startLineNumber: toolResult.startLineNumber,
|
|
861
|
-
timestamp: Date.now(),
|
|
862
|
-
});
|
|
863
|
-
// Execute PostToolUse hooks after successful tool completion
|
|
864
|
-
await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
|
|
733
|
+
if (batch.calls.length === 1) {
|
|
734
|
+
await this.executeToolCall(batch.calls[0], abortController, toolAbortController, result.finish_reason);
|
|
865
735
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
? toolError.message
|
|
869
|
-
: String(toolError);
|
|
870
|
-
this.messageManager.updateToolBlock({
|
|
871
|
-
id: toolId,
|
|
872
|
-
parameters: JSON.stringify(toolArgs, null, 2),
|
|
873
|
-
result: `Tool execution failed: ${errorMessage}`,
|
|
874
|
-
success: false,
|
|
875
|
-
error: errorMessage,
|
|
876
|
-
stage: "end",
|
|
877
|
-
name: toolName,
|
|
878
|
-
compactParams,
|
|
879
|
-
isManuallyBackgrounded: false,
|
|
880
|
-
timestamp: Date.now(),
|
|
881
|
-
});
|
|
736
|
+
else {
|
|
737
|
+
await Promise.all(batch.calls.map((call) => this.executeToolCall(call, abortController, toolAbortController, result.finish_reason)));
|
|
882
738
|
}
|
|
883
|
-
}
|
|
884
|
-
// Wait for all tools to complete execution in parallel
|
|
885
|
-
await Promise.all(toolExecutionPromises);
|
|
739
|
+
}
|
|
886
740
|
}
|
|
887
741
|
// Handle token statistics and message compaction
|
|
888
742
|
await this.handleTokenUsageAndCompaction(result.usage, abortController);
|
|
@@ -1172,6 +1026,167 @@ export class AIManager {
|
|
|
1172
1026
|
return false;
|
|
1173
1027
|
}
|
|
1174
1028
|
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Execute a single tool call: arg parsing, block emission, PreToolUse hooks,
|
|
1031
|
+
* tool execution, PostToolUse hooks, and error handling.
|
|
1032
|
+
*/
|
|
1033
|
+
async executeToolCall(functionToolCall, abortController, toolAbortController, finishReason) {
|
|
1034
|
+
const toolId = functionToolCall.id || "";
|
|
1035
|
+
// Check if already interrupted, skip tool execution if so
|
|
1036
|
+
if (abortController.signal.aborted || toolAbortController.signal.aborted) {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
const toolName = functionToolCall.function?.name || "";
|
|
1040
|
+
// Safely parse tool parameters, handle tools without parameters
|
|
1041
|
+
let toolArgs = {};
|
|
1042
|
+
let jsonRecovered = false;
|
|
1043
|
+
const argsString = functionToolCall.function?.arguments?.trim();
|
|
1044
|
+
if (!argsString || argsString === "") {
|
|
1045
|
+
// Tool without parameters, use empty object
|
|
1046
|
+
toolArgs = {};
|
|
1047
|
+
}
|
|
1048
|
+
else {
|
|
1049
|
+
let recoveredArgs = argsString;
|
|
1050
|
+
try {
|
|
1051
|
+
toolArgs = JSON.parse(argsString);
|
|
1052
|
+
}
|
|
1053
|
+
catch {
|
|
1054
|
+
// Attempt to recover truncated JSON (e.g., missing closing braces)
|
|
1055
|
+
recoveredArgs = recoverTruncatedJson(argsString);
|
|
1056
|
+
try {
|
|
1057
|
+
toolArgs = JSON.parse(recoveredArgs);
|
|
1058
|
+
jsonRecovered = true;
|
|
1059
|
+
logger.warn(`Recovered truncated JSON for tool "${toolName}"`);
|
|
1060
|
+
}
|
|
1061
|
+
catch (parseError) {
|
|
1062
|
+
let errorMessage = `Failed to parse tool arguments`;
|
|
1063
|
+
if (finishReason === "length") {
|
|
1064
|
+
errorMessage += " (output truncated, please reduce your output)";
|
|
1065
|
+
}
|
|
1066
|
+
logger?.error(errorMessage, parseError);
|
|
1067
|
+
this.messageManager.updateToolBlock({
|
|
1068
|
+
id: toolId,
|
|
1069
|
+
parameters: argsString,
|
|
1070
|
+
result: errorMessage,
|
|
1071
|
+
success: false,
|
|
1072
|
+
error: errorMessage,
|
|
1073
|
+
stage: "end",
|
|
1074
|
+
name: toolName,
|
|
1075
|
+
compactParams: "",
|
|
1076
|
+
timestamp: Date.now(),
|
|
1077
|
+
});
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
const compactParams = this.generateCompactParams(toolName, toolArgs);
|
|
1083
|
+
// Emit start stage for non-streaming tool calls
|
|
1084
|
+
if (!this.stream) {
|
|
1085
|
+
this.messageManager.updateToolBlock({
|
|
1086
|
+
id: toolId,
|
|
1087
|
+
stage: "start",
|
|
1088
|
+
name: toolName,
|
|
1089
|
+
compactParams,
|
|
1090
|
+
parameters: argsString,
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
// Emit running stage (tool execution about to start)
|
|
1094
|
+
this.messageManager.updateToolBlock({
|
|
1095
|
+
id: toolId,
|
|
1096
|
+
stage: "running",
|
|
1097
|
+
name: toolName,
|
|
1098
|
+
compactParams,
|
|
1099
|
+
parameters: argsString,
|
|
1100
|
+
parametersChunk: "",
|
|
1101
|
+
});
|
|
1102
|
+
try {
|
|
1103
|
+
// Execute PreToolUse hooks before tool execution
|
|
1104
|
+
const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
|
|
1105
|
+
// If PreToolUse hooks blocked execution, skip tool execution
|
|
1106
|
+
if (!shouldExecuteTool) {
|
|
1107
|
+
logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
// Create tool execution context
|
|
1111
|
+
const context = {
|
|
1112
|
+
abortSignal: toolAbortController.signal,
|
|
1113
|
+
backgroundTaskManager: this.backgroundTaskManager,
|
|
1114
|
+
workdir: this.getWorkdir(),
|
|
1115
|
+
originalWorkdir: this.originalWorkdir,
|
|
1116
|
+
messageId: this.messageManager.getMessages().slice(-1)[0]?.id,
|
|
1117
|
+
sessionId: this.messageManager.getSessionId(),
|
|
1118
|
+
toolCallId: toolId,
|
|
1119
|
+
taskManager: this.taskManager,
|
|
1120
|
+
readFileState: this.readFileState,
|
|
1121
|
+
onShortResultUpdate: (shortResult) => {
|
|
1122
|
+
this.messageManager.updateToolBlock({
|
|
1123
|
+
id: toolId,
|
|
1124
|
+
shortResult,
|
|
1125
|
+
stage: "running",
|
|
1126
|
+
});
|
|
1127
|
+
},
|
|
1128
|
+
onResultUpdate: (result) => {
|
|
1129
|
+
this.messageManager.updateToolBlock({
|
|
1130
|
+
id: toolId,
|
|
1131
|
+
result,
|
|
1132
|
+
stage: "running",
|
|
1133
|
+
});
|
|
1134
|
+
},
|
|
1135
|
+
onCwdChange: async (newCwd) => {
|
|
1136
|
+
const oldCwd = this.getWorkdir();
|
|
1137
|
+
this.container.register("Workdir", newCwd);
|
|
1138
|
+
this._onCwdChange?.(newCwd);
|
|
1139
|
+
if (this.hookManager) {
|
|
1140
|
+
const sessionId = this.messageManager.getSessionId();
|
|
1141
|
+
const transcriptPath = this.messageManager.getTranscriptPath();
|
|
1142
|
+
const env = Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined));
|
|
1143
|
+
await this.hookManager.executeCwdChangedHooks(oldCwd, newCwd, sessionId, transcriptPath, env);
|
|
1144
|
+
}
|
|
1145
|
+
},
|
|
1146
|
+
};
|
|
1147
|
+
// Execute tool
|
|
1148
|
+
const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
|
|
1149
|
+
// Build result content, adding truncation warning if JSON was recovered
|
|
1150
|
+
let toolResultContent = toolResult.content ||
|
|
1151
|
+
(toolResult.error ? `Error: ${toolResult.error}` : "");
|
|
1152
|
+
if (jsonRecovered) {
|
|
1153
|
+
toolResultContent +=
|
|
1154
|
+
"\n\nTool arguments were truncated (likely exceeded max output tokens). Please reduce your output or split into multiple tool calls.";
|
|
1155
|
+
}
|
|
1156
|
+
// Update message state - tool execution completed
|
|
1157
|
+
this.messageManager.updateToolBlock({
|
|
1158
|
+
id: toolId,
|
|
1159
|
+
parameters: argsString,
|
|
1160
|
+
result: toolResultContent,
|
|
1161
|
+
success: toolResult.success,
|
|
1162
|
+
error: toolResult.error,
|
|
1163
|
+
stage: "end",
|
|
1164
|
+
name: toolName,
|
|
1165
|
+
compactParams,
|
|
1166
|
+
shortResult: toolResult.shortResult,
|
|
1167
|
+
isManuallyBackgrounded: toolResult.isManuallyBackgrounded,
|
|
1168
|
+
startLineNumber: toolResult.startLineNumber,
|
|
1169
|
+
timestamp: Date.now(),
|
|
1170
|
+
});
|
|
1171
|
+
// Execute PostToolUse hooks after successful tool completion
|
|
1172
|
+
await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
|
|
1173
|
+
}
|
|
1174
|
+
catch (toolError) {
|
|
1175
|
+
const errorMessage = toolError instanceof Error ? toolError.message : String(toolError);
|
|
1176
|
+
this.messageManager.updateToolBlock({
|
|
1177
|
+
id: toolId,
|
|
1178
|
+
parameters: JSON.stringify(toolArgs, null, 2),
|
|
1179
|
+
result: `Tool execution failed: ${errorMessage}`,
|
|
1180
|
+
success: false,
|
|
1181
|
+
error: errorMessage,
|
|
1182
|
+
stage: "end",
|
|
1183
|
+
name: toolName,
|
|
1184
|
+
compactParams,
|
|
1185
|
+
isManuallyBackgrounded: false,
|
|
1186
|
+
timestamp: Date.now(),
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1175
1190
|
/**
|
|
1176
1191
|
* Execute PreToolUse hooks before tool execution
|
|
1177
1192
|
* Returns true if hooks allow tool execution, false if blocked
|
|
@@ -1243,8 +1258,7 @@ export class AIManager {
|
|
|
1243
1258
|
toolResponse,
|
|
1244
1259
|
subagentType: this.subagentType, // Include subagent type in hook context
|
|
1245
1260
|
planFilePath: this.permissionManager?.getPlanFilePath(),
|
|
1246
|
-
env:
|
|
1247
|
-
process.env,
|
|
1261
|
+
env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)), // Include environment variables
|
|
1248
1262
|
};
|
|
1249
1263
|
const results = await this.hookManager.executeHooks("PostToolUse", context);
|
|
1250
1264
|
// Process hook results to handle exit codes and update tool results
|
|
@@ -718,8 +718,7 @@ export class HookManager {
|
|
|
718
718
|
transcriptPath,
|
|
719
719
|
cwd: this.workdir,
|
|
720
720
|
endSource: source,
|
|
721
|
-
env:
|
|
722
|
-
process.env,
|
|
721
|
+
env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)),
|
|
723
722
|
};
|
|
724
723
|
const results = await this.executeHooks("SessionEnd", context);
|
|
725
724
|
// Process results but never block shutdown
|
|
@@ -768,8 +767,7 @@ export class HookManager {
|
|
|
768
767
|
transcriptPath,
|
|
769
768
|
cwd: this.workdir,
|
|
770
769
|
compactSummary,
|
|
771
|
-
env:
|
|
772
|
-
process.env,
|
|
770
|
+
env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)),
|
|
773
771
|
};
|
|
774
772
|
const results = await this.executeHooks("PostCompact", context);
|
|
775
773
|
if (results.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,SAAS,EACT,OAAO,EACP,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAQ3B,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC3D;AAID,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9C;AAQD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAsC7D;AAED,qBAAa,UAAU;IAanB,OAAO,CAAC,SAAS;IAZnB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAA8C;IAEhE,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,iBAAiB,CAAkC;gBAGjD,SAAS,EAAE,SAAS,EAC5B,OAAO,GAAE,iBAAsB;IAMjC;;OAEG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC,IAAI,CAAC;IAgDV,kBAAkB,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAO/C,UAAU,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAgEvC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrD,SAAS,IAAI,SAAS,GAAG,IAAI;IAI7B,aAAa,IAAI,eAAe,EAAE;IAIlC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIpD,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IASzE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO;IAuDzD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAgB7B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -332,10 +332,8 @@ export class McpManager {
|
|
|
332
332
|
if (!server.config.command) {
|
|
333
333
|
throw new Error(`MCP server ${name} with type "stdio" requires a 'command'`);
|
|
334
334
|
}
|
|
335
|
-
const agentEnv = this.container.get("MergedEnv") ||
|
|
336
|
-
process.env;
|
|
337
335
|
const env = {
|
|
338
|
-
...
|
|
336
|
+
...process.env,
|
|
339
337
|
...(server.config.env || {}),
|
|
340
338
|
};
|
|
341
339
|
// For plugin servers, substitute ${WAVE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_ROOT}
|