wave-agent-sdk 0.18.6 → 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 +31 -8
- package/dist/managers/cronManager.d.ts.map +1 -1
- package/dist/managers/cronManager.js +2 -0
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/liveConfigManager.js +0 -9
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +13 -3
- package/dist/managers/messageManager.d.ts +4 -6
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +27 -81
- 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/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +2 -0
- 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 +24 -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 +31 -20
- package/dist/telemetry/sessionTracing.d.ts.map +1 -1
- package/dist/telemetry/sessionTracing.js +192 -62
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +16 -1
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +6 -7
- 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 +16 -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/fileUtils.d.ts +0 -6
- package/dist/utils/fileUtils.d.ts.map +1 -1
- package/dist/utils/fileUtils.js +0 -43
- package/dist/utils/gitUtils.d.ts +11 -0
- package/dist/utils/gitUtils.d.ts.map +1 -1
- package/dist/utils/gitUtils.js +51 -0
- package/dist/utils/groupMessagesByApiRound.d.ts.map +1 -1
- package/dist/utils/groupMessagesByApiRound.js +7 -6
- 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/dist/utils/tokenEstimate.d.ts +24 -0
- package/dist/utils/tokenEstimate.d.ts.map +1 -0
- package/dist/utils/tokenEstimate.js +30 -0
- package/dist/utils/worktreeUtils.d.ts.map +1 -1
- package/dist/utils/worktreeUtils.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 +36 -7
- package/src/managers/cronManager.ts +2 -0
- package/src/managers/liveConfigManager.ts +0 -12
- package/src/managers/mcpManager.ts +16 -3
- package/src/managers/messageManager.ts +32 -109
- package/src/managers/skillManager.ts +16 -2
- package/src/managers/toolManager.ts +2 -0
- package/src/prompts/index.ts +6 -1
- package/src/services/aiService.ts +12 -5
- package/src/services/configurationService.ts +26 -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 +225 -73
- package/src/tools/bashTool.ts +23 -1
- package/src/tools/readTool.ts +6 -12
- 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 +19 -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/fileUtils.ts +0 -46
- package/src/utils/gitUtils.ts +54 -0
- package/src/utils/groupMessagesByApiRound.ts +7 -6
- package/src/utils/mcpUtils.ts +2 -1
- package/src/utils/modelCapabilities.ts +30 -0
- package/src/utils/skillParser.ts +3 -1
- package/src/utils/tokenEstimate.ts +34 -0
- package/src/utils/worktreeUtils.ts +8 -1
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
import type { ModelCapabilities } from "../types/config.js";
|
|
9
|
+
/**
|
|
10
|
+
* Determines if a model supports prompt caching.
|
|
11
|
+
* @param capabilities - Declarative model capabilities
|
|
12
|
+
* @returns True if promptCaching is explicitly enabled (default: false)
|
|
13
|
+
*/
|
|
14
|
+
export declare function supportsPromptCaching(capabilities?: ModelCapabilities): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Determines if a model supports image/vision recognition.
|
|
17
|
+
* Opt-out semantics: by default all models are assumed to support vision.
|
|
18
|
+
* @param capabilities - Declarative model capabilities
|
|
19
|
+
* @returns True unless vision is explicitly disabled (default: true)
|
|
20
|
+
*/
|
|
21
|
+
export declare function supportsVision(capabilities?: ModelCapabilities): boolean;
|
|
22
|
+
//# sourceMappingURL=modelCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelCapabilities.d.ts","sourceRoot":"","sources":["../../src/utils/modelCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,CAAC,EAAE,iBAAiB,GAC/B,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAExE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
* Determines if a model supports prompt caching.
|
|
10
|
+
* @param capabilities - Declarative model capabilities
|
|
11
|
+
* @returns True if promptCaching is explicitly enabled (default: false)
|
|
12
|
+
*/
|
|
13
|
+
export function supportsPromptCaching(capabilities) {
|
|
14
|
+
return capabilities?.promptCaching ?? false;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Determines if a model supports image/vision recognition.
|
|
18
|
+
* Opt-out semantics: by default all models are assumed to support vision.
|
|
19
|
+
* @param capabilities - Declarative model capabilities
|
|
20
|
+
* @returns True unless vision is explicitly disabled (default: true)
|
|
21
|
+
*/
|
|
22
|
+
export function supportsVision(capabilities) {
|
|
23
|
+
return capabilities?.vision ?? true;
|
|
24
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skillParser.d.ts","sourceRoot":"","sources":["../../src/utils/skillParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,
|
|
1
|
+
{"version":3,"file":"skillParser.d.ts","sourceRoot":"","sources":["../../src/utils/skillParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CAoGjB;AAyDD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAwCvE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAa5E"}
|
|
@@ -38,7 +38,9 @@ export function parseSkillFile(filePath, options = {}) {
|
|
|
38
38
|
const skillType = skillPath.includes("/.wave/skills") ||
|
|
39
39
|
skillPath.includes("\\.wave\\skills") ||
|
|
40
40
|
skillPath.includes("/.claude/skills") ||
|
|
41
|
-
skillPath.includes("\\.claude\\skills")
|
|
41
|
+
skillPath.includes("\\.claude\\skills") ||
|
|
42
|
+
skillPath.includes("/.agents/skills") ||
|
|
43
|
+
skillPath.includes("\\.agents\\skills")
|
|
42
44
|
? "project"
|
|
43
45
|
: "personal";
|
|
44
46
|
// Extract allowed tools
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CJK-aware token estimation without external dependencies.
|
|
3
|
+
*
|
|
4
|
+
* The naive `length / 4` heuristic under-estimates CJK text by ~4x because
|
|
5
|
+
* each Chinese/Japanese/Korean character is typically 1-2 tokens, not 0.25.
|
|
6
|
+
* This function separates CJK characters from other text and applies
|
|
7
|
+
* different ratios:
|
|
8
|
+
*
|
|
9
|
+
* - CJK characters: 1 char ≈ 1 token
|
|
10
|
+
* - Other characters: 4 chars ≈ 1 token (2 for JSON/JSONL/JSONC)
|
|
11
|
+
*
|
|
12
|
+
* The estimate intentionally leans high for CJK (safe direction for limit
|
|
13
|
+
* checks — better to reject than to let oversized content through).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Estimate token count for a string, with CJK-awareness.
|
|
17
|
+
*
|
|
18
|
+
* @param content - The text content to estimate
|
|
19
|
+
* @param ext - File extension (without dot), e.g. "ts", "json". JSON/JSONL/JSONC
|
|
20
|
+
* files use a tighter ratio (2 chars/token) for non-CJK text.
|
|
21
|
+
* @returns Estimated token count
|
|
22
|
+
*/
|
|
23
|
+
export declare function estimateTokens(content: string, ext?: string): number;
|
|
24
|
+
//# sourceMappingURL=tokenEstimate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenEstimate.d.ts","sourceRoot":"","sources":["../../src/utils/tokenEstimate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAMpE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CJK-aware token estimation without external dependencies.
|
|
3
|
+
*
|
|
4
|
+
* The naive `length / 4` heuristic under-estimates CJK text by ~4x because
|
|
5
|
+
* each Chinese/Japanese/Korean character is typically 1-2 tokens, not 0.25.
|
|
6
|
+
* This function separates CJK characters from other text and applies
|
|
7
|
+
* different ratios:
|
|
8
|
+
*
|
|
9
|
+
* - CJK characters: 1 char ≈ 1 token
|
|
10
|
+
* - Other characters: 4 chars ≈ 1 token (2 for JSON/JSONL/JSONC)
|
|
11
|
+
*
|
|
12
|
+
* The estimate intentionally leans high for CJK (safe direction for limit
|
|
13
|
+
* checks — better to reject than to let oversized content through).
|
|
14
|
+
*/
|
|
15
|
+
// CJK Unified Ideographs + Extension A + Hiragana + Katakana + Hangul Syllables
|
|
16
|
+
const CJK_REGEX = /[\u4e00-\u9fff\u3400-\u4dbf\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g;
|
|
17
|
+
/**
|
|
18
|
+
* Estimate token count for a string, with CJK-awareness.
|
|
19
|
+
*
|
|
20
|
+
* @param content - The text content to estimate
|
|
21
|
+
* @param ext - File extension (without dot), e.g. "ts", "json". JSON/JSONL/JSONC
|
|
22
|
+
* files use a tighter ratio (2 chars/token) for non-CJK text.
|
|
23
|
+
* @returns Estimated token count
|
|
24
|
+
*/
|
|
25
|
+
export function estimateTokens(content, ext) {
|
|
26
|
+
const cjkCount = (content.match(CJK_REGEX) || []).length;
|
|
27
|
+
const otherCount = content.length - cjkCount;
|
|
28
|
+
const bytesPerToken = ext === "json" || ext === "jsonl" || ext === "jsonc" ? 2 : 4;
|
|
29
|
+
return Math.ceil(cjkCount + otherCount / bytesPerToken);
|
|
30
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktreeUtils.d.ts","sourceRoot":"","sources":["../../src/utils/worktreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"worktreeUtils.d.ts","sourceRoot":"","sources":["../../src/utils/worktreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAgKtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAmEvD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsClD"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
|
-
import { getGitMainRepoRoot, getDefaultRemoteBranch } from "./gitUtils.js";
|
|
8
|
+
import { getGitMainRepoRoot, getDefaultRemoteBranch, ensureWaveRuntimeFilesExcluded, } from "./gitUtils.js";
|
|
9
9
|
import { logger } from "./globalLogger.js";
|
|
10
10
|
/**
|
|
11
11
|
* Validate a worktree name to prevent path traversal and invalid characters.
|
|
@@ -79,6 +79,8 @@ export function createWorktree(name, cwd) {
|
|
|
79
79
|
const worktreePath = path.join(repoRoot, ".wave", "worktrees", name);
|
|
80
80
|
const branchName = `worktree-${name}`;
|
|
81
81
|
const baseBranch = getDefaultRemoteBranch(cwd);
|
|
82
|
+
// Ensure Wave runtime files are git-excluded in this repo
|
|
83
|
+
ensureWaveRuntimeFilesExcluded(cwd);
|
|
82
84
|
// Ensure parent directory exists
|
|
83
85
|
const parentDir = path.dirname(worktreePath);
|
|
84
86
|
if (!fs.existsSync(parentDir)) {
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -41,6 +41,7 @@ import { SkillManager } from "./managers/skillManager.js";
|
|
|
41
41
|
import { TaskManager } from "./services/taskManager.js";
|
|
42
42
|
import { btw } from "./services/aiService.js";
|
|
43
43
|
import { convertMessagesForAPI } from "./utils/convertMessagesForAPI.js";
|
|
44
|
+
import { supportsVision } from "./utils/modelCapabilities.js";
|
|
44
45
|
import { parseTaskNotificationXml } from "./utils/notificationXml.js";
|
|
45
46
|
import { InitializationService } from "./services/initializationService.js";
|
|
46
47
|
import { InteractionService } from "./services/interactionService.js";
|
|
@@ -598,17 +599,20 @@ export class Agent {
|
|
|
598
599
|
options,
|
|
599
600
|
);
|
|
600
601
|
|
|
601
|
-
// Initialize OpenTelemetry (
|
|
602
|
+
// Initialize OpenTelemetry (awaited to ensure ALS context is ready before
|
|
603
|
+
// startInteractionSpan is called, preventing trace context fragmentation)
|
|
602
604
|
const telemetryConfig = this.configurationService.resolveTelemetryConfig();
|
|
603
|
-
|
|
605
|
+
try {
|
|
606
|
+
await initializeTelemetry(telemetryConfig);
|
|
607
|
+
} catch (error) {
|
|
604
608
|
this.logger?.warn("Telemetry initialization failed:", error);
|
|
605
|
-
}
|
|
609
|
+
}
|
|
606
610
|
|
|
607
611
|
// Log session_start event
|
|
608
612
|
try {
|
|
609
613
|
const modelConfig = this.getModelConfig();
|
|
610
614
|
if (modelConfig.model) {
|
|
611
|
-
logOTelEvent("session_start", {
|
|
615
|
+
await logOTelEvent("session_start", {
|
|
612
616
|
sessionId: this.messageManager.getSessionId(),
|
|
613
617
|
model: modelConfig.model,
|
|
614
618
|
workdir: this.workdir,
|
|
@@ -992,7 +996,9 @@ export class Agent {
|
|
|
992
996
|
* @returns Promise that resolves to the AI's answer
|
|
993
997
|
*/
|
|
994
998
|
public async askBtw(question: string): Promise<string> {
|
|
995
|
-
const messages = convertMessagesForAPI(this.messageManager.getMessages()
|
|
999
|
+
const messages = convertMessagesForAPI(this.messageManager.getMessages(), {
|
|
1000
|
+
supportsVision: supportsVision(this.getModelConfig().capabilities),
|
|
1001
|
+
});
|
|
996
1002
|
const result = await btw({
|
|
997
1003
|
gatewayConfig: this.getGatewayConfig(),
|
|
998
1004
|
modelConfig: this.getModelConfig(),
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from "./managers/messageQueue.js";
|
|
|
14
14
|
// Export all utilities
|
|
15
15
|
export * from "./utils/bashParser.js";
|
|
16
16
|
export * from "./utils/convertMessagesForAPI.js";
|
|
17
|
+
export * from "./utils/modelCapabilities.js";
|
|
17
18
|
export * from "./utils/fileSearch.js";
|
|
18
19
|
export * from "./utils/globalLogger.js";
|
|
19
20
|
export * from "./utils/mcpUtils.js";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type CallAgentOptions } from "../services/aiService.js";
|
|
2
2
|
import * as aiService from "../services/aiService.js";
|
|
3
3
|
import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
|
|
4
|
+
import { supportsVision } from "../utils/modelCapabilities.js";
|
|
4
5
|
import { parseTaskNotificationXml } from "../utils/notificationXml.js";
|
|
5
6
|
import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
|
|
7
|
+
import { estimateTokens } from "../utils/tokenEstimate.js";
|
|
6
8
|
import {
|
|
7
9
|
getTaskReminderTurnCounts,
|
|
8
10
|
maybeInjectTaskReminder,
|
|
@@ -44,6 +46,7 @@ import {
|
|
|
44
46
|
endInteractionSpan,
|
|
45
47
|
startLLMRequestSpan,
|
|
46
48
|
endLLMRequestSpan,
|
|
49
|
+
resetTracingState,
|
|
47
50
|
} from "../telemetry/sessionTracing.js";
|
|
48
51
|
import { logOTelEvent } from "../telemetry/events.js";
|
|
49
52
|
|
|
@@ -491,7 +494,7 @@ export class AIManager {
|
|
|
491
494
|
);
|
|
492
495
|
|
|
493
496
|
// 7. Execute message reconstruction
|
|
494
|
-
this.messageManager.compactMessagesAndUpdateSession(
|
|
497
|
+
await this.messageManager.compactMessagesAndUpdateSession(
|
|
495
498
|
enhancedSummary,
|
|
496
499
|
compactUsage,
|
|
497
500
|
);
|
|
@@ -522,6 +525,9 @@ export class AIManager {
|
|
|
522
525
|
|
|
523
526
|
this.consecutiveCompactionFailures = 0;
|
|
524
527
|
|
|
528
|
+
// Reset incremental tracing state after compaction
|
|
529
|
+
resetTracingState();
|
|
530
|
+
|
|
525
531
|
// 9. Log OTEL event
|
|
526
532
|
logOTelEvent("compaction", {
|
|
527
533
|
beforeTokens: String(messagesToCompact.length),
|
|
@@ -606,7 +612,7 @@ export class AIManager {
|
|
|
606
612
|
);
|
|
607
613
|
let usedTokens = 0;
|
|
608
614
|
for (const file of recentFiles) {
|
|
609
|
-
const fileTokens =
|
|
615
|
+
const fileTokens = estimateTokens(file.content);
|
|
610
616
|
if (usedTokens + fileTokens > POST_COMPACT_MAX_TOKENS_PER_FILE) continue;
|
|
611
617
|
if (fileTokens > 0) usedTokens += fileTokens;
|
|
612
618
|
contextParts.push(`\n\n## ${file.path}\n\`\`\`\n${file.content}\n\`\`\``);
|
|
@@ -639,7 +645,7 @@ export class AIManager {
|
|
|
639
645
|
skillContent.slice(0, maxSkillChars) + "\n\n...[truncated]...";
|
|
640
646
|
}
|
|
641
647
|
|
|
642
|
-
const skillTokens =
|
|
648
|
+
const skillTokens = estimateTokens(skillContent);
|
|
643
649
|
if (skillsUsedTokens + skillTokens > POST_COMPACT_SKILLS_TOKEN_BUDGET)
|
|
644
650
|
break;
|
|
645
651
|
skillsUsedTokens += skillTokens;
|
|
@@ -813,6 +819,7 @@ export class AIManager {
|
|
|
813
819
|
let turnDepth = turnOffset;
|
|
814
820
|
|
|
815
821
|
inner: while (true) {
|
|
822
|
+
let llmSpan: import("@opentelemetry/api").Span | undefined;
|
|
816
823
|
try {
|
|
817
824
|
// Save session in each iteration to ensure message persistence
|
|
818
825
|
await this.messageManager.saveSession();
|
|
@@ -836,7 +843,10 @@ export class AIManager {
|
|
|
836
843
|
|
|
837
844
|
// Get recent message history
|
|
838
845
|
const rawMessages = this.messageManager.getMessages();
|
|
839
|
-
const
|
|
846
|
+
const currentModelConfig = this.getModelConfig();
|
|
847
|
+
const recentMessages = convertMessagesForAPI(rawMessages, {
|
|
848
|
+
supportsVision: supportsVision(currentModelConfig.capabilities),
|
|
849
|
+
});
|
|
840
850
|
|
|
841
851
|
// Track if assistant message has been created
|
|
842
852
|
let assistantMessageCreated = false;
|
|
@@ -949,15 +959,33 @@ export class AIManager {
|
|
|
949
959
|
};
|
|
950
960
|
}
|
|
951
961
|
|
|
952
|
-
|
|
962
|
+
llmSpan = startLLMRequestSpan(
|
|
963
|
+
model || this.getModelConfig().model || "",
|
|
964
|
+
{
|
|
965
|
+
context: "interaction",
|
|
966
|
+
systemPrompt:
|
|
967
|
+
typeof callAgentOptions.systemPrompt === "string"
|
|
968
|
+
? callAgentOptions.systemPrompt
|
|
969
|
+
: undefined,
|
|
970
|
+
inputMessages: callAgentOptions.messages,
|
|
971
|
+
toolsSchema: callAgentOptions.tools
|
|
972
|
+
? JSON.stringify(callAgentOptions.tools)
|
|
973
|
+
: undefined,
|
|
974
|
+
},
|
|
975
|
+
);
|
|
953
976
|
|
|
954
977
|
const result = await aiService.callAgent(callAgentOptions);
|
|
955
978
|
|
|
956
979
|
// End LLM span with usage data
|
|
957
|
-
endLLMRequestSpan({
|
|
980
|
+
endLLMRequestSpan(llmSpan, {
|
|
958
981
|
model: model || this.getModelConfig().model || "",
|
|
959
982
|
success: true,
|
|
960
983
|
hasToolCall: !!(result.tool_calls && result.tool_calls.length > 0),
|
|
984
|
+
inputTokens: result.usage?.prompt_tokens,
|
|
985
|
+
outputTokens: result.usage?.completion_tokens,
|
|
986
|
+
cacheReadTokens: result.usage?.cache_read_input_tokens,
|
|
987
|
+
cacheCreationTokens: result.usage?.cache_creation_input_tokens,
|
|
988
|
+
modelOutput: result.content,
|
|
961
989
|
});
|
|
962
990
|
|
|
963
991
|
const createdByStreaming = assistantMessageCreated;
|
|
@@ -1238,7 +1266,7 @@ export class AIManager {
|
|
|
1238
1266
|
break inner;
|
|
1239
1267
|
} catch (error) {
|
|
1240
1268
|
// End LLM span with error
|
|
1241
|
-
endLLMRequestSpan({
|
|
1269
|
+
endLLMRequestSpan(llmSpan, {
|
|
1242
1270
|
model: model || this.getModelConfig().model || "",
|
|
1243
1271
|
success: false,
|
|
1244
1272
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -1653,6 +1681,7 @@ export class AIManager {
|
|
|
1653
1681
|
shortResult: toolResult.shortResult,
|
|
1654
1682
|
isManuallyBackgrounded: toolResult.isManuallyBackgrounded,
|
|
1655
1683
|
startLineNumber: toolResult.startLineNumber,
|
|
1684
|
+
images: toolResult.images,
|
|
1656
1685
|
timestamp: Date.now(),
|
|
1657
1686
|
});
|
|
1658
1687
|
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
releaseSchedulerLock,
|
|
16
16
|
registerSchedulerLockCleanup,
|
|
17
17
|
} from "../utils/cronTasksLock.js";
|
|
18
|
+
import { ensureWaveRuntimeFilesExcluded } from "../utils/gitUtils.js";
|
|
18
19
|
|
|
19
20
|
export class CronManager {
|
|
20
21
|
private jobs = new Map<string, CronJob>();
|
|
@@ -100,6 +101,7 @@ export class CronManager {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
private tryLock(workdir: string): void {
|
|
104
|
+
ensureWaveRuntimeFilesExcluded(workdir);
|
|
103
105
|
tryAcquireSchedulerLock({ dir: workdir, sessionId: this.sessionId })
|
|
104
106
|
.then((acquired) => {
|
|
105
107
|
if (acquired) {
|
|
@@ -17,7 +17,6 @@ import type { HookManager } from "./hookManager.js";
|
|
|
17
17
|
import type { PermissionManager } from "./permissionManager.js";
|
|
18
18
|
import { isValidHookEvent } from "../types/hooks.js";
|
|
19
19
|
import { ConfigurationService } from "../services/configurationService.js";
|
|
20
|
-
import { ensureGlobalGitIgnore } from "../utils/fileUtils.js";
|
|
21
20
|
import { Container } from "../utils/container.js";
|
|
22
21
|
|
|
23
22
|
import type {
|
|
@@ -97,9 +96,6 @@ export class LiveConfigManager {
|
|
|
97
96
|
if (projectPaths) {
|
|
98
97
|
for (const projectPath of projectPaths) {
|
|
99
98
|
if (existsSync(projectPath)) {
|
|
100
|
-
if (projectPath.endsWith("settings.local.json")) {
|
|
101
|
-
await ensureGlobalGitIgnore("**/.wave/settings.local.json");
|
|
102
|
-
}
|
|
103
99
|
await this.fileWatcher.watchFile(projectPath, (event) =>
|
|
104
100
|
this.handleFileChange(event, "project"),
|
|
105
101
|
);
|
|
@@ -364,14 +360,6 @@ export class LiveConfigManager {
|
|
|
364
360
|
|
|
365
361
|
// Handle file creation or modification
|
|
366
362
|
if (event.type === "change" || event.type === "create") {
|
|
367
|
-
if (
|
|
368
|
-
source === "project" &&
|
|
369
|
-
event.path.endsWith("settings.local.json") &&
|
|
370
|
-
event.type === "create"
|
|
371
|
-
) {
|
|
372
|
-
await ensureGlobalGitIgnore("**/.wave/settings.local.json");
|
|
373
|
-
}
|
|
374
|
-
|
|
375
363
|
// Add small delay to ensure file write is complete
|
|
376
364
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
377
365
|
|
|
@@ -725,11 +725,17 @@ export class McpManager {
|
|
|
725
725
|
}
|
|
726
726
|
}
|
|
727
727
|
|
|
728
|
-
// Get all tools from connected servers
|
|
728
|
+
// Get all tools from connected servers.
|
|
729
|
+
// "reconnecting" servers retain their last-known tool snapshot so that
|
|
730
|
+
// transient SSE disconnects don't churn the tool list (which would bust
|
|
731
|
+
// the prompt cache). Tools are only dropped once the server truly fails
|
|
732
|
+
// (status "error"/"disconnected").
|
|
729
733
|
getAllConnectedTools(): McpTool[] {
|
|
730
734
|
const allTools: McpTool[] = [];
|
|
731
735
|
for (const server of this.servers.values()) {
|
|
732
|
-
|
|
736
|
+
const usable =
|
|
737
|
+
server.status === "connected" || server.status === "reconnecting";
|
|
738
|
+
if (usable && server.tools) {
|
|
733
739
|
allTools.push(...server.tools);
|
|
734
740
|
}
|
|
735
741
|
}
|
|
@@ -848,9 +854,16 @@ export class McpManager {
|
|
|
848
854
|
textContent.push(String(result.content));
|
|
849
855
|
}
|
|
850
856
|
|
|
857
|
+
const textContentStr =
|
|
858
|
+
textContent.length > 0
|
|
859
|
+
? textContent.join("\n")
|
|
860
|
+
: images.length > 0
|
|
861
|
+
? `Tool returned ${images.length} image(s).`
|
|
862
|
+
: "No content";
|
|
863
|
+
|
|
851
864
|
return {
|
|
852
865
|
success: true,
|
|
853
|
-
content:
|
|
866
|
+
content: textContentStr,
|
|
854
867
|
images: images.length > 0 ? images : undefined,
|
|
855
868
|
serverName,
|
|
856
869
|
};
|