wave-agent-sdk 0.17.1 → 0.17.3
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/deep-research/SKILL.md +90 -0
- package/builtin/skills/settings/ENV.md +6 -3
- package/dist/agent.d.ts +28 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +128 -34
- package/dist/constants/goalPrompts.d.ts +2 -0
- package/dist/constants/goalPrompts.d.ts.map +1 -0
- package/dist/constants/goalPrompts.js +10 -0
- package/dist/constants/tools.d.ts +1 -0
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +1 -0
- package/dist/managers/aiManager.d.ts +7 -0
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +77 -41
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +10 -2
- package/dist/managers/goalManager.d.ts +43 -0
- package/dist/managers/goalManager.d.ts.map +1 -0
- package/dist/managers/goalManager.js +177 -0
- package/dist/managers/messageManager.d.ts +2 -2
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageQueue.d.ts +10 -0
- package/dist/managers/messageQueue.d.ts.map +1 -1
- package/dist/managers/messageQueue.js +53 -1
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +7 -1
- package/dist/managers/skillManager.d.ts +2 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +19 -9
- package/dist/managers/slashCommandManager.d.ts +6 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +105 -0
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +5 -0
- package/dist/managers/workflowManager.d.ts +65 -0
- package/dist/managers/workflowManager.d.ts.map +1 -0
- package/dist/managers/workflowManager.js +380 -0
- package/dist/prompts/index.d.ts +2 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +3 -3
- package/dist/services/MarketplaceService.d.ts +2 -2
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +11 -32
- package/dist/services/aiService.d.ts +23 -0
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +102 -9
- package/dist/services/configurationService.d.ts +1 -1
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +3 -16
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +4 -0
- package/dist/services/session.d.ts +9 -1
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +28 -1
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +49 -7
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +1 -1
- package/dist/tools/taskManagementTools.d.ts.map +1 -1
- package/dist/tools/taskManagementTools.js +103 -157
- package/dist/tools/types.d.ts +2 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/webFetchTool.d.ts.map +1 -1
- package/dist/tools/webFetchTool.js +0 -9
- package/dist/tools/workflowTool.d.ts +11 -0
- package/dist/tools/workflowTool.d.ts.map +1 -0
- package/dist/tools/workflowTool.js +190 -0
- package/dist/types/agent.d.ts +2 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/commands.d.ts +4 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +2 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +2 -2
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/processes.d.ts +6 -2
- package/dist/types/processes.d.ts.map +1 -1
- package/dist/types/workflow.d.ts +2 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +1 -0
- package/dist/utils/cacheControlUtils.d.ts +13 -8
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +73 -102
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +7 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +21 -6
- package/dist/utils/messageOperations.d.ts +2 -2
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/notificationXml.d.ts.map +1 -1
- package/dist/workflow/budgetTracker.d.ts +12 -0
- package/dist/workflow/budgetTracker.d.ts.map +1 -0
- package/dist/workflow/budgetTracker.js +30 -0
- package/dist/workflow/concurrencyLimiter.d.ts +14 -0
- package/dist/workflow/concurrencyLimiter.d.ts.map +1 -0
- package/dist/workflow/concurrencyLimiter.js +39 -0
- package/dist/workflow/journal.d.ts +19 -0
- package/dist/workflow/journal.d.ts.map +1 -0
- package/dist/workflow/journal.js +74 -0
- package/dist/workflow/progressReporter.d.ts +21 -0
- package/dist/workflow/progressReporter.d.ts.map +1 -0
- package/dist/workflow/progressReporter.js +118 -0
- package/dist/workflow/runState.d.ts +16 -0
- package/dist/workflow/runState.d.ts.map +1 -0
- package/dist/workflow/runState.js +57 -0
- package/dist/workflow/scriptRuntime.d.ts +35 -0
- package/dist/workflow/scriptRuntime.d.ts.map +1 -0
- package/dist/workflow/scriptRuntime.js +196 -0
- package/dist/workflow/structuredOutput.d.ts +27 -0
- package/dist/workflow/structuredOutput.d.ts.map +1 -0
- package/dist/workflow/structuredOutput.js +106 -0
- package/dist/workflow/types.d.ts +81 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +1 -0
- package/dist/workflow/workflowApis.d.ts +46 -0
- package/dist/workflow/workflowApis.d.ts.map +1 -0
- package/dist/workflow/workflowApis.js +280 -0
- package/package.json +1 -1
- package/src/agent.ts +144 -34
- package/src/constants/goalPrompts.ts +10 -0
- package/src/constants/tools.ts +1 -0
- package/src/managers/aiManager.ts +91 -47
- package/src/managers/backgroundTaskManager.ts +16 -4
- package/src/managers/goalManager.ts +232 -0
- package/src/managers/messageManager.ts +2 -2
- package/src/managers/messageQueue.ts +59 -1
- package/src/managers/pluginManager.ts +8 -1
- package/src/managers/skillManager.ts +20 -9
- package/src/managers/slashCommandManager.ts +119 -0
- package/src/managers/toolManager.ts +7 -0
- package/src/managers/workflowManager.ts +491 -0
- package/src/prompts/index.ts +4 -2
- package/src/services/MarketplaceService.ts +14 -38
- package/src/services/aiService.ts +166 -12
- package/src/services/configurationService.ts +2 -22
- package/src/services/hook.ts +5 -0
- package/src/services/session.ts +42 -2
- package/src/tools/bashTool.ts +64 -9
- package/src/tools/readTool.ts +1 -2
- package/src/tools/taskManagementTools.ts +146 -195
- package/src/tools/types.ts +2 -0
- package/src/tools/webFetchTool.ts +0 -12
- package/src/tools/workflowTool.ts +205 -0
- package/src/types/agent.ts +6 -0
- package/src/types/commands.ts +4 -0
- package/src/types/config.ts +2 -2
- package/src/types/core.ts +3 -3
- package/src/types/hooks.ts +2 -0
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +2 -2
- package/src/types/processes.ts +10 -2
- package/src/types/workflow.ts +5 -0
- package/src/utils/cacheControlUtils.ts +106 -131
- package/src/utils/containerSetup.ts +9 -0
- package/src/utils/markdownParser.ts +26 -8
- package/src/utils/messageOperations.ts +2 -2
- package/src/utils/notificationXml.ts +6 -1
- package/src/workflow/budgetTracker.ts +34 -0
- package/src/workflow/concurrencyLimiter.ts +47 -0
- package/src/workflow/journal.ts +95 -0
- package/src/workflow/progressReporter.ts +141 -0
- package/src/workflow/runState.ts +65 -0
- package/src/workflow/scriptRuntime.ts +274 -0
- package/src/workflow/structuredOutput.ts +123 -0
- package/src/workflow/types.ts +95 -0
- package/src/workflow/workflowApis.ts +412 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { OpenAIClient } from "../utils/openaiClient.js";
|
|
2
2
|
import { logger } from "../utils/globalLogger.js";
|
|
3
3
|
import { addOnceAbortListener } from "../utils/abortUtils.js";
|
|
4
|
+
import { ConfigurationError, CONFIG_ERRORS } from "../types/index.js";
|
|
4
5
|
import { transformMessagesForClaudeCache, addCacheControlToLastTool, supportsPromptCaching, extendUsageWithCacheMetrics, } from "../utils/cacheControlUtils.js";
|
|
5
6
|
import * as os from "os";
|
|
6
7
|
import * as fs from "fs";
|
|
7
8
|
import * as path from "path";
|
|
8
9
|
import { COMPACT_MESSAGES_SYSTEM_PROMPT, WEB_CONTENT_SYSTEM_PROMPT, BTW_SYSTEM_PROMPT, } from "../prompts/index.js";
|
|
10
|
+
import { GOAL_EVALUATION_SYSTEM_PROMPT } from "../constants/goalPrompts.js";
|
|
9
11
|
// Global rate limiter state for 1 QPS
|
|
10
12
|
let nextAllowedTime = 0;
|
|
11
13
|
const MIN_INTERVAL = 1000; // 1 second for 1 QPS
|
|
@@ -63,8 +65,24 @@ function getModelConfig(modelName, baseConfig = {}) {
|
|
|
63
65
|
}
|
|
64
66
|
return config;
|
|
65
67
|
}
|
|
68
|
+
function validateModelConfig(modelConfig) {
|
|
69
|
+
if (!modelConfig.model) {
|
|
70
|
+
throw new ConfigurationError(CONFIG_ERRORS.MISSING_MODEL, "model", {
|
|
71
|
+
constructor: undefined,
|
|
72
|
+
environment: process.env.WAVE_MODEL,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (!modelConfig.fastModel) {
|
|
76
|
+
throw new ConfigurationError(CONFIG_ERRORS.MISSING_FAST_MODEL, "fastModel", {
|
|
77
|
+
constructor: undefined,
|
|
78
|
+
environment: process.env.WAVE_FAST_MODEL,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
66
82
|
export async function callAgent(options) {
|
|
67
83
|
const { gatewayConfig, modelConfig, messages, abortSignal, workdir, tools, model, systemPrompt, onContentUpdate, onToolUpdate, onReasoningUpdate, } = options;
|
|
84
|
+
// Validate model config at call time
|
|
85
|
+
validateModelConfig(modelConfig);
|
|
68
86
|
// Apply global 1 QPS rate limit
|
|
69
87
|
if (process.env.NODE_ENV !== "test" ||
|
|
70
88
|
modelConfig.model === "rate-limit-test") {
|
|
@@ -127,6 +145,10 @@ export async function callAgent(options) {
|
|
|
127
145
|
if (processedTools && processedTools.length > 0) {
|
|
128
146
|
createParams.tools = processedTools;
|
|
129
147
|
}
|
|
148
|
+
// Add tool_choice if specified
|
|
149
|
+
if (options.toolChoice) {
|
|
150
|
+
createParams.tool_choice = options.toolChoice;
|
|
151
|
+
}
|
|
130
152
|
if (isStreaming) {
|
|
131
153
|
// Handle streaming response
|
|
132
154
|
const { data: stream, response } = await openai.chat.completions
|
|
@@ -139,7 +161,7 @@ export async function callAgent(options) {
|
|
|
139
161
|
response.headers.forEach((value, key) => {
|
|
140
162
|
responseHeaders[key] = value;
|
|
141
163
|
});
|
|
142
|
-
return await processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders
|
|
164
|
+
return await processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders);
|
|
143
165
|
}
|
|
144
166
|
else {
|
|
145
167
|
// Handle non-streaming response
|
|
@@ -162,8 +184,8 @@ export async function callAgent(options) {
|
|
|
162
184
|
total_tokens: response.usage.total_tokens,
|
|
163
185
|
}
|
|
164
186
|
: undefined;
|
|
165
|
-
// Extend usage with cache metrics
|
|
166
|
-
if (totalUsage &&
|
|
187
|
+
// Extend usage with cache metrics (Claude top-level + OpenAI prompt_tokens_details)
|
|
188
|
+
if (totalUsage && response.usage) {
|
|
167
189
|
totalUsage = extendUsageWithCacheMetrics(totalUsage, response.usage);
|
|
168
190
|
}
|
|
169
191
|
const result = {};
|
|
@@ -288,10 +310,9 @@ export async function callAgent(options) {
|
|
|
288
310
|
* @param onToolUpdate Callback for tool updates
|
|
289
311
|
* @param abortSignal Optional abort signal
|
|
290
312
|
* @param responseHeaders Response headers from the initial request
|
|
291
|
-
* @param modelName Model name for cache control processing
|
|
292
313
|
* @returns Final result with accumulated content and tool calls
|
|
293
314
|
*/
|
|
294
|
-
async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders
|
|
315
|
+
async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders) {
|
|
295
316
|
let accumulatedContent = "";
|
|
296
317
|
let accumulatedReasoningContent = "";
|
|
297
318
|
let hasReasoningContent = false;
|
|
@@ -312,10 +333,8 @@ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, o
|
|
|
312
333
|
completion_tokens: chunk.usage.completion_tokens,
|
|
313
334
|
total_tokens: chunk.usage.total_tokens,
|
|
314
335
|
};
|
|
315
|
-
// Extend usage with cache metrics
|
|
316
|
-
|
|
317
|
-
chunkUsage = extendUsageWithCacheMetrics(chunkUsage, chunk.usage);
|
|
318
|
-
}
|
|
336
|
+
// Extend usage with cache metrics (Claude top-level + OpenAI prompt_tokens_details)
|
|
337
|
+
chunkUsage = extendUsageWithCacheMetrics(chunkUsage, chunk.usage);
|
|
319
338
|
usage = chunkUsage;
|
|
320
339
|
}
|
|
321
340
|
// Check for finish_reason in the choice
|
|
@@ -454,6 +473,8 @@ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, o
|
|
|
454
473
|
}
|
|
455
474
|
export async function compactMessages(options) {
|
|
456
475
|
const { gatewayConfig, modelConfig, messages, abortSignal } = options;
|
|
476
|
+
// Validate model config at call time
|
|
477
|
+
validateModelConfig(modelConfig);
|
|
457
478
|
// Apply global 1 QPS rate limit
|
|
458
479
|
if (process.env.NODE_ENV !== "test" ||
|
|
459
480
|
modelConfig.model === "rate-limit-test") {
|
|
@@ -534,6 +555,8 @@ export async function compactMessages(options) {
|
|
|
534
555
|
}
|
|
535
556
|
export async function processWebContent(options) {
|
|
536
557
|
const { gatewayConfig, modelConfig, content, prompt, abortSignal } = options;
|
|
558
|
+
// Validate model config at call time
|
|
559
|
+
validateModelConfig(modelConfig);
|
|
537
560
|
// Apply global 1 QPS rate limit
|
|
538
561
|
if (process.env.NODE_ENV !== "test" ||
|
|
539
562
|
modelConfig.model === "rate-limit-test") {
|
|
@@ -601,6 +624,8 @@ export async function processWebContent(options) {
|
|
|
601
624
|
}
|
|
602
625
|
export async function btw(options) {
|
|
603
626
|
const { gatewayConfig, modelConfig, messages, question, abortSignal } = options;
|
|
627
|
+
// Validate model config at call time
|
|
628
|
+
validateModelConfig(modelConfig);
|
|
604
629
|
// Apply global 1 QPS rate limit
|
|
605
630
|
if (process.env.NODE_ENV !== "test" ||
|
|
606
631
|
modelConfig.model === "rate-limit-test") {
|
|
@@ -667,3 +692,71 @@ export async function btw(options) {
|
|
|
667
692
|
throw error;
|
|
668
693
|
}
|
|
669
694
|
}
|
|
695
|
+
export async function evaluateGoal(options) {
|
|
696
|
+
const { gatewayConfig, modelConfig, model, goalCondition, messages, abortSignal, } = options;
|
|
697
|
+
// Create OpenAI client with injected configuration (no rate limiter — bypasses 1 QPS)
|
|
698
|
+
const openai = new OpenAIClient({
|
|
699
|
+
apiKey: gatewayConfig.apiKey,
|
|
700
|
+
baseURL: gatewayConfig.baseURL,
|
|
701
|
+
defaultHeaders: gatewayConfig.defaultHeaders,
|
|
702
|
+
fetchOptions: gatewayConfig.fetchOptions,
|
|
703
|
+
fetch: gatewayConfig.fetch,
|
|
704
|
+
});
|
|
705
|
+
const { model: _model, fastModel: _fastModel, maxTokens: _maxTokens, permissionMode: _permissionMode, ...extraParams } = modelConfig;
|
|
706
|
+
void _model;
|
|
707
|
+
void _fastModel;
|
|
708
|
+
void _maxTokens;
|
|
709
|
+
void _permissionMode;
|
|
710
|
+
const openaiModelConfig = getModelConfig(model, {
|
|
711
|
+
temperature: 0,
|
|
712
|
+
max_tokens: 200,
|
|
713
|
+
...extraParams,
|
|
714
|
+
});
|
|
715
|
+
// Strip images from messages to reduce token usage (same as compact)
|
|
716
|
+
const cleanedMessages = messages.map((msg) => {
|
|
717
|
+
if (Array.isArray(msg.content)) {
|
|
718
|
+
const textParts = msg.content.filter((part) => part.type === "text");
|
|
719
|
+
const text = textParts.map((p) => p.text).join("\n");
|
|
720
|
+
return { ...msg, content: text || "(empty message)" };
|
|
721
|
+
}
|
|
722
|
+
return msg;
|
|
723
|
+
});
|
|
724
|
+
try {
|
|
725
|
+
const response = await openai.chat.completions.create({
|
|
726
|
+
...openaiModelConfig,
|
|
727
|
+
messages: [
|
|
728
|
+
{
|
|
729
|
+
role: "system",
|
|
730
|
+
content: GOAL_EVALUATION_SYSTEM_PROMPT,
|
|
731
|
+
},
|
|
732
|
+
...cleanedMessages,
|
|
733
|
+
{
|
|
734
|
+
role: "user",
|
|
735
|
+
content: `Goal condition: ${goalCondition}\n\nHas this goal been achieved based on the conversation above?`,
|
|
736
|
+
},
|
|
737
|
+
],
|
|
738
|
+
}, {
|
|
739
|
+
signal: abortSignal,
|
|
740
|
+
});
|
|
741
|
+
const result = response.choices[0]?.message?.content?.trim();
|
|
742
|
+
if (!result) {
|
|
743
|
+
throw new Error("Goal evaluation returned empty response");
|
|
744
|
+
}
|
|
745
|
+
const usage = response.usage
|
|
746
|
+
? {
|
|
747
|
+
prompt_tokens: response.usage.prompt_tokens,
|
|
748
|
+
completion_tokens: response.usage.completion_tokens,
|
|
749
|
+
total_tokens: response.usage.total_tokens,
|
|
750
|
+
}
|
|
751
|
+
: undefined;
|
|
752
|
+
return { content: result, usage };
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
if (error.name === "AbortError") {
|
|
756
|
+
logger.info("Goal evaluation was aborted");
|
|
757
|
+
throw new Error("Goal evaluation was aborted");
|
|
758
|
+
}
|
|
759
|
+
logger.error("Goal evaluation failed:", error);
|
|
760
|
+
throw error;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
@@ -52,7 +52,7 @@ export declare class ConfigurationService {
|
|
|
52
52
|
* @param fetchOptions - Fetch options override (optional)
|
|
53
53
|
* @param fetch - Custom fetch implementation override (optional)
|
|
54
54
|
* @returns Resolved gateway configuration
|
|
55
|
-
* @
|
|
55
|
+
* @returns Resolved model configuration (model/fastModel may be undefined if not yet configured)
|
|
56
56
|
*/
|
|
57
57
|
resolveGatewayConfig(apiKey?: string, baseURL?: string, defaultHeaders?: Record<string, string>, fetchOptions?: ClientOptions["fetchOptions"], fetch?: ClientOptions["fetch"]): GatewayConfig;
|
|
58
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,EACL,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAE7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,aAAa,EACb,WAAW,
|
|
1
|
+
{"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,EACL,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAE7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAQvC;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAMvC;;OAEG;IACG,uBAAuB,CAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAkEnC;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IAkLlE;;OAEG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAwC7D;;;OAGG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAcrD;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;;;;;;;;;OAUG;IACH,oBAAoB,CAClB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,YAAY,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,EAC5C,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC7B,aAAa;IA8EhB;;;;;;;;OAQG;IACH,kBAAkB,CAChB,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,cAAc,GAC9B,WAAW;IAuCd;;;;;OAKG;IACH,qBAAqB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM;IAwBxD;;;;;OAKG;IACH,eAAe,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAmBjE;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAkBnC;;;;OAIG;IACH,0BAA0B,IAAI,MAAM;IAqBpC;;;;;OAKG;IACH,sBAAsB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM;IAwBzD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;YAKf,sBAAsB;IAqBpC;;OAEG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAwB/B;;OAEG;IACH,sBAAsB,IAClB,OAAO,CAAC,OAAO,uBAAuB,EAAE,eAAe,CAAC,GACxD,SAAS;IAIb;;OAEG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB;IAa1D;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoClE;;OAEG;IACG,mBAAmB,CACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC;IAuChB;;OAEG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAKzE;;OAEG;IACH,qBAAqB,CACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GACX,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAapC;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC;IAyChB;;OAEG;IACG,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAmChB;;OAEG;IACG,mBAAmB,CACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmChB;;OAEG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAKjE;;;OAGG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;CAGnE;AAKD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,2BAA2B,CAsD7B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC9C,OAAO,GAAE,uBAA4B,GACpC,wBAAwB,CAoC1B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CA+B1B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,GACd,iBAAiB,GAAG,IAAI,CA0K1B"}
|
|
@@ -11,7 +11,6 @@ import { isValidHookEvent } from "../types/hooks.js";
|
|
|
11
11
|
import { logger } from "../utils/globalLogger.js";
|
|
12
12
|
import { getAllConfigPaths, getExistingConfigPaths, getUserConfigPaths, getProjectConfigPaths, } from "../utils/configPaths.js";
|
|
13
13
|
import { isValidEnvironmentVars, } from "../types/environment.js";
|
|
14
|
-
import { ConfigurationError, CONFIG_ERRORS, } from "../types/index.js";
|
|
15
14
|
import { DEFAULT_WAVE_MAX_INPUT_TOKENS, DEFAULT_WAVE_MAX_OUTPUT_TOKENS, } from "../utils/constants.js";
|
|
16
15
|
import { parseCustomHeaders } from "../utils/stringUtils.js";
|
|
17
16
|
import { getRemoteSettingsSync, mergeRemoteSettings, } from "./remoteSettingsService.js";
|
|
@@ -320,7 +319,7 @@ export class ConfigurationService {
|
|
|
320
319
|
* @param fetchOptions - Fetch options override (optional)
|
|
321
320
|
* @param fetch - Custom fetch implementation override (optional)
|
|
322
321
|
* @returns Resolved gateway configuration
|
|
323
|
-
* @
|
|
322
|
+
* @returns Resolved model configuration (model/fastModel may be undefined if not yet configured)
|
|
324
323
|
*/
|
|
325
324
|
resolveGatewayConfig(apiKey, baseURL, defaultHeaders, fetchOptions, fetch) {
|
|
326
325
|
// Check for SSO token first - if present and server URL is available, use SSO mode
|
|
@@ -411,19 +410,6 @@ export class ConfigurationService {
|
|
|
411
410
|
process.env.WAVE_MODEL;
|
|
412
411
|
// Resolve fast model: override > options > process.env (includes settings.json env)
|
|
413
412
|
const resolvedFastModel = fastModel || this.options.fastModel || process.env.WAVE_FAST_MODEL;
|
|
414
|
-
// Validate required fields
|
|
415
|
-
if (!resolvedAgentModel) {
|
|
416
|
-
throw new ConfigurationError(CONFIG_ERRORS.MISSING_MODEL, "model", {
|
|
417
|
-
constructor: model,
|
|
418
|
-
environment: process.env.WAVE_MODEL,
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
if (!resolvedFastModel) {
|
|
422
|
-
throw new ConfigurationError(CONFIG_ERRORS.MISSING_FAST_MODEL, "fastModel", {
|
|
423
|
-
constructor: fastModel,
|
|
424
|
-
environment: process.env.WAVE_FAST_MODEL,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
413
|
// Resolve max output tokens
|
|
428
414
|
const resolvedMaxTokens = this.resolveMaxOutputTokens(maxTokens);
|
|
429
415
|
const baseConfig = {
|
|
@@ -433,7 +419,8 @@ export class ConfigurationService {
|
|
|
433
419
|
permissionMode: permissionMode ?? this.options.permissionMode,
|
|
434
420
|
};
|
|
435
421
|
// Merge model-specific settings from configuration
|
|
436
|
-
const modelSpecificConfig =
|
|
422
|
+
const modelSpecificConfig = resolvedAgentModel &&
|
|
423
|
+
this.currentConfiguration?.models?.[resolvedAgentModel];
|
|
437
424
|
if (modelSpecificConfig) {
|
|
438
425
|
return {
|
|
439
426
|
...baseConfig,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AAgG3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
|
package/dist/services/hook.js
CHANGED
|
@@ -48,6 +48,10 @@ async function buildHookJsonInput(context) {
|
|
|
48
48
|
context.userPrompt !== undefined) {
|
|
49
49
|
jsonInput.user_prompt = context.userPrompt;
|
|
50
50
|
}
|
|
51
|
+
// Add plan_file_path if present
|
|
52
|
+
if (context.planFilePath !== undefined) {
|
|
53
|
+
jsonInput.plan_file_path = context.planFilePath;
|
|
54
|
+
}
|
|
51
55
|
// Add subagent_type if present
|
|
52
56
|
if (context.subagentType !== undefined) {
|
|
53
57
|
jsonInput.subagent_type = context.subagentType;
|
|
@@ -33,13 +33,15 @@ export interface SessionMetadata {
|
|
|
33
33
|
sessionType: "main" | "subagent";
|
|
34
34
|
subagentType?: string;
|
|
35
35
|
workdir: string;
|
|
36
|
+
createdAt: Date;
|
|
36
37
|
lastActiveAt: Date;
|
|
37
38
|
latestTotalTokens: number;
|
|
38
39
|
firstMessage?: string;
|
|
39
40
|
}
|
|
40
41
|
export interface SessionIndex {
|
|
41
|
-
sessions: Record<string, Omit<SessionMetadata, "id" | "lastActiveAt"> & {
|
|
42
|
+
sessions: Record<string, Omit<SessionMetadata, "id" | "lastActiveAt" | "createdAt"> & {
|
|
42
43
|
lastActiveAt: string;
|
|
44
|
+
createdAt: string;
|
|
43
45
|
}>;
|
|
44
46
|
lastUpdated: string;
|
|
45
47
|
}
|
|
@@ -49,6 +51,12 @@ export interface SessionIndex {
|
|
|
49
51
|
* @returns Timestamp-prefixed session ID string
|
|
50
52
|
*/
|
|
51
53
|
export declare function generateSessionId(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Parse the timestamp prefix from a session ID back into a Date
|
|
56
|
+
* Format: {YYYYMMDDHHmmss}-{8hex} (e.g. 20260527143025-a1b2c3d4)
|
|
57
|
+
* @returns Date from the session ID timestamp prefix
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseSessionIdTimestamp(sessionId: string): Date;
|
|
52
60
|
/**
|
|
53
61
|
* Generate filename for subagent sessions
|
|
54
62
|
* @param sessionId - UUID session identifier
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAOjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,UAAU,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CACd,MAAM,EACN,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,cAAc,CAAC,GAAG;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"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"}
|
package/dist/services/session.js
CHANGED
|
@@ -41,6 +41,19 @@ export function generateSessionId() {
|
|
|
41
41
|
const shortId = randomUUID().slice(0, 8);
|
|
42
42
|
return `${ts}-${shortId}`;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse the timestamp prefix from a session ID back into a Date
|
|
46
|
+
* Format: {YYYYMMDDHHmmss}-{8hex} (e.g. 20260527143025-a1b2c3d4)
|
|
47
|
+
* @returns Date from the session ID timestamp prefix
|
|
48
|
+
*/
|
|
49
|
+
export function parseSessionIdTimestamp(sessionId) {
|
|
50
|
+
const match = sessionId.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
|
|
51
|
+
if (!match) {
|
|
52
|
+
return new Date(); // Fallback to now for legacy UUID-format session IDs
|
|
53
|
+
}
|
|
54
|
+
const [, year, month, day, hour, minute, second] = match;
|
|
55
|
+
return new Date(Number(year), Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second));
|
|
56
|
+
}
|
|
44
57
|
/**
|
|
45
58
|
* Generate filename for subagent sessions
|
|
46
59
|
* @param sessionId - UUID session identifier
|
|
@@ -72,6 +85,7 @@ async function updateSessionIndex(projectDirPath, metadata) {
|
|
|
72
85
|
const { id, ...rest } = metadata;
|
|
73
86
|
index.sessions[id] = {
|
|
74
87
|
...rest,
|
|
88
|
+
createdAt: metadata.createdAt.toISOString(),
|
|
75
89
|
lastActiveAt: metadata.lastActiveAt.toISOString(),
|
|
76
90
|
firstMessage: metadata.firstMessage || index.sessions[id]?.firstMessage,
|
|
77
91
|
parentSessionId: metadata.parentSessionId,
|
|
@@ -165,8 +179,9 @@ export async function appendMessages(sessionId, newMessages, workdir, sessionTyp
|
|
|
165
179
|
const encoder = new PathEncoder();
|
|
166
180
|
const projectDir = await encoder.getProjectDirectory(workdir, SESSION_DIR);
|
|
167
181
|
const lastMessage = newMessages[newMessages.length - 1];
|
|
168
|
-
// Get first message content
|
|
182
|
+
// Get first message content and createdAt from existing index
|
|
169
183
|
let firstMessage;
|
|
184
|
+
let createdAt;
|
|
170
185
|
try {
|
|
171
186
|
const indexPath = join(projectDir.encodedPath, SESSION_INDEX_FILENAME);
|
|
172
187
|
const content = await fs.readFile(indexPath, "utf8");
|
|
@@ -175,18 +190,26 @@ export async function appendMessages(sessionId, newMessages, workdir, sessionTyp
|
|
|
175
190
|
firstMessage =
|
|
176
191
|
(await getFirstMessageContent(sessionId, workdir)) || undefined;
|
|
177
192
|
}
|
|
193
|
+
if (index.sessions[sessionId]?.createdAt) {
|
|
194
|
+
createdAt = new Date(index.sessions[sessionId].createdAt);
|
|
195
|
+
}
|
|
178
196
|
}
|
|
179
197
|
catch {
|
|
180
198
|
// If index doesn't exist, this might be the first message
|
|
181
199
|
firstMessage =
|
|
182
200
|
(await getFirstMessageContent(sessionId, workdir)) || undefined;
|
|
183
201
|
}
|
|
202
|
+
// Derive createdAt from session ID timestamp if not in index
|
|
203
|
+
if (!createdAt) {
|
|
204
|
+
createdAt = new Date(parseSessionIdTimestamp(sessionId));
|
|
205
|
+
}
|
|
184
206
|
await updateSessionIndex(projectDir.encodedPath, {
|
|
185
207
|
id: sessionId,
|
|
186
208
|
rootSessionId,
|
|
187
209
|
parentSessionId,
|
|
188
210
|
sessionType,
|
|
189
211
|
workdir,
|
|
212
|
+
createdAt,
|
|
190
213
|
lastActiveAt: new Date(lastMessage.timestamp),
|
|
191
214
|
latestTotalTokens: lastMessage.usage
|
|
192
215
|
? extractLatestTotalTokens([lastMessage])
|
|
@@ -327,6 +350,7 @@ export async function listSessionsFromJsonl(workdir) {
|
|
|
327
350
|
.map(([id, meta]) => ({
|
|
328
351
|
id,
|
|
329
352
|
...meta,
|
|
353
|
+
createdAt: new Date(meta.createdAt),
|
|
330
354
|
lastActiveAt: new Date(meta.lastActiveAt),
|
|
331
355
|
}));
|
|
332
356
|
return sessions.sort((a, b) => b.lastActiveAt.getTime() - a.lastActiveAt.getTime());
|
|
@@ -386,6 +410,7 @@ export async function listSessionsFromJsonl(workdir) {
|
|
|
386
410
|
sessionType: "main",
|
|
387
411
|
subagentType: undefined, // No longer stored in metadata
|
|
388
412
|
workdir: projectDir.originalPath,
|
|
413
|
+
createdAt: new Date(parseSessionIdTimestamp(sessionId)),
|
|
389
414
|
lastActiveAt,
|
|
390
415
|
latestTotalTokens: lastMessage?.usage
|
|
391
416
|
? extractLatestTotalTokens([lastMessage])
|
|
@@ -420,6 +445,7 @@ export async function listSessionsFromJsonl(workdir) {
|
|
|
420
445
|
const { id, ...rest } = session;
|
|
421
446
|
index.sessions[id] = {
|
|
422
447
|
...rest,
|
|
448
|
+
createdAt: session.createdAt.toISOString(),
|
|
423
449
|
lastActiveAt: session.lastActiveAt.toISOString(),
|
|
424
450
|
};
|
|
425
451
|
}
|
|
@@ -473,6 +499,7 @@ export async function listAllSessions() {
|
|
|
473
499
|
allSessions.push({
|
|
474
500
|
id,
|
|
475
501
|
...meta,
|
|
502
|
+
createdAt: new Date(meta.createdAt),
|
|
476
503
|
lastActiveAt,
|
|
477
504
|
});
|
|
478
505
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAqhBtB,CAAC"}
|
package/dist/tools/bashTool.js
CHANGED
|
@@ -8,6 +8,16 @@ import { processToolResult } from "../utils/toolResultStorage.js";
|
|
|
8
8
|
import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
|
|
9
9
|
import { BASH_TOOL_NAME, GLOB_TOOL_NAME, GREP_TOOL_NAME, READ_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, } from "../constants/tools.js";
|
|
10
10
|
const BASH_DEFAULT_TIMEOUT_MS = 120000;
|
|
11
|
+
// Commands that should not be auto-backgrounded on timeout (e.g. sleep should just be killed)
|
|
12
|
+
const DISALLOWED_AUTO_BACKGROUND_COMMANDS = ["sleep"];
|
|
13
|
+
function isAutobackgroundingAllowed(command) {
|
|
14
|
+
const trimmed = command.trim();
|
|
15
|
+
// Get the first word of the command
|
|
16
|
+
const baseCommand = trimmed.split(/\s+/)[0];
|
|
17
|
+
if (!baseCommand)
|
|
18
|
+
return true;
|
|
19
|
+
return !DISALLOWED_AUTO_BACKGROUND_COMMANDS.includes(baseCommand);
|
|
20
|
+
}
|
|
11
21
|
/**
|
|
12
22
|
* Bash command execution tool - supports both foreground and background execution
|
|
13
23
|
*/
|
|
@@ -111,8 +121,12 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
111
121
|
const runInBackground = args.run_in_background;
|
|
112
122
|
const description = args.description;
|
|
113
123
|
// Set default timeout: BASH_DEFAULT_TIMEOUT_MS for foreground, no timeout for background
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
// When run_in_background is explicitly set, cancel any timeout — the intent is to
|
|
125
|
+
// let the process run to completion (matching Claude Code behavior where background()
|
|
126
|
+
// clears the timeout via cleanupListeners).
|
|
127
|
+
const timeout = runInBackground
|
|
128
|
+
? undefined
|
|
129
|
+
: (args.timeout ?? BASH_DEFAULT_TIMEOUT_MS);
|
|
116
130
|
if (!command || typeof command !== "string") {
|
|
117
131
|
return {
|
|
118
132
|
success: false,
|
|
@@ -166,7 +180,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
166
180
|
error: "Background task manager not available",
|
|
167
181
|
};
|
|
168
182
|
}
|
|
169
|
-
const { id: taskId } = backgroundTaskManager.startShell(command
|
|
183
|
+
const { id: taskId } = backgroundTaskManager.startShell(command);
|
|
170
184
|
const task = backgroundTaskManager.getTask(taskId);
|
|
171
185
|
const outputPath = task?.outputPath;
|
|
172
186
|
const backgroundMsg = [
|
|
@@ -249,12 +263,36 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
249
263
|
},
|
|
250
264
|
});
|
|
251
265
|
}
|
|
252
|
-
// Set up timeout
|
|
266
|
+
// Set up timeout — auto-background if allowed, otherwise kill
|
|
253
267
|
let timeoutHandle;
|
|
268
|
+
const shouldAutoBackground = !!context.backgroundTaskManager && isAutobackgroundingAllowed(command);
|
|
254
269
|
if (timeout && timeout > 0) {
|
|
255
270
|
timeoutHandle = setTimeout(() => {
|
|
256
|
-
if (!isAborted) {
|
|
257
|
-
|
|
271
|
+
if (!isAborted && !isBackgrounded) {
|
|
272
|
+
if (shouldAutoBackground) {
|
|
273
|
+
// Auto-background: move the process to background task manager instead of killing it
|
|
274
|
+
isBackgrounded = true;
|
|
275
|
+
if (timeoutHandle) {
|
|
276
|
+
clearTimeout(timeoutHandle);
|
|
277
|
+
}
|
|
278
|
+
// Unregister foreground task since it's now backgrounded
|
|
279
|
+
if (context.foregroundTaskManager) {
|
|
280
|
+
context.foregroundTaskManager.unregisterForegroundTask(foregroundTaskId);
|
|
281
|
+
}
|
|
282
|
+
const backgroundTaskManager = context.backgroundTaskManager;
|
|
283
|
+
const taskId = backgroundTaskManager.adoptProcess(child, command, outputBuffer, errorBuffer);
|
|
284
|
+
const task = backgroundTaskManager.getTask(taskId);
|
|
285
|
+
const outputPath = task?.outputPath;
|
|
286
|
+
logger.info(`[Bash] Command timed out after ${timeout}ms, auto-backgrounded as ${taskId}`);
|
|
287
|
+
resolve({
|
|
288
|
+
success: true,
|
|
289
|
+
content: `Command timed out after ${timeout / 1000} seconds and was moved to background with ID: ${taskId}.${outputPath ? ` Real-time output: ${outputPath}` : ""}`,
|
|
290
|
+
shortResult: `Process ${taskId} auto-backgrounded (timeout)`,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
handleAbort("Command timed out");
|
|
295
|
+
}
|
|
258
296
|
}
|
|
259
297
|
}, timeout);
|
|
260
298
|
}
|
|
@@ -277,7 +315,11 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
277
315
|
process.kill(-child.pid, "SIGKILL");
|
|
278
316
|
}
|
|
279
317
|
catch (killError) {
|
|
280
|
-
|
|
318
|
+
// ESRCH means the process already exited — not an error
|
|
319
|
+
if (!(killError instanceof Error) ||
|
|
320
|
+
killError.code !== "ESRCH") {
|
|
321
|
+
logger.error("Failed to force kill process:", killError);
|
|
322
|
+
}
|
|
281
323
|
}
|
|
282
324
|
}
|
|
283
325
|
}, 1000);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAkItE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAkItE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA4RtB,CAAC"}
|
package/dist/tools/readTool.js
CHANGED
|
@@ -250,7 +250,7 @@ Usage:
|
|
|
250
250
|
logger.warn(`File ${filePath} exists but has empty contents`);
|
|
251
251
|
return {
|
|
252
252
|
success: true,
|
|
253
|
-
content: "
|
|
253
|
+
content: "System reminder: This file exists but has empty contents.",
|
|
254
254
|
shortResult: "Empty file",
|
|
255
255
|
metadata: {
|
|
256
256
|
type: "text",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA6CjE,eAAO,MAAM,cAAc,EAAE,UAgG5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAwEzB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UAyR5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAyE1B,CAAC"}
|