wave-agent-sdk 0.18.3 → 0.18.5
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/builtin/skills/settings/MEMORY.md +76 -0
- package/builtin/skills/settings/SKILL.md +4 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +0 -2
- package/dist/managers/MemoryRuleManager.d.ts +9 -0
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +18 -0
- package/dist/managers/aiManager.d.ts +1 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +370 -345
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +22 -15
- package/dist/managers/messageManager.d.ts +32 -13
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +82 -76
- package/dist/prompts/index.d.ts +10 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +21 -20
- package/dist/services/aiService.d.ts +2 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +37 -10
- package/dist/services/memory.d.ts +1 -0
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +35 -17
- package/dist/tools/agentTool.d.ts.map +1 -1
- package/dist/tools/agentTool.js +24 -2
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +17 -10
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +7 -6
- package/dist/tools/readTool.js +2 -2
- package/dist/tools/writeTool.js +2 -2
- 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 -0
- package/dist/utils/gitUtils.js +6 -6
- package/dist/utils/openaiClient.d.ts.map +1 -1
- package/dist/utils/openaiClient.js +33 -32
- package/dist/utils/path.d.ts +7 -0
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +9 -0
- package/dist/utils/taskReminder.d.ts +2 -3
- package/dist/utils/taskReminder.d.ts.map +1 -1
- package/dist/utils/taskReminder.js +7 -18
- package/dist/utils/worktreeUtils.d.ts.map +1 -1
- package/dist/utils/worktreeUtils.js +19 -13
- package/package.json +1 -1
- package/scripts/install_ripgrep.js +21 -1
- package/src/agent.ts +0 -5
- package/src/managers/MemoryRuleManager.ts +23 -0
- package/src/managers/aiManager.ts +473 -434
- package/src/managers/mcpManager.ts +26 -15
- package/src/managers/messageManager.ts +99 -82
- package/src/prompts/index.ts +33 -24
- package/src/services/aiService.ts +39 -12
- package/src/services/memory.ts +34 -16
- package/src/tools/agentTool.ts +24 -2
- package/src/tools/bashTool.ts +18 -9
- package/src/tools/editTool.ts +7 -9
- package/src/tools/readTool.ts +2 -2
- package/src/tools/writeTool.ts +2 -2
- package/src/utils/constants.ts +1 -1
- package/src/utils/containerSetup.ts +1 -0
- package/src/utils/gitUtils.ts +6 -6
- package/src/utils/openaiClient.ts +40 -31
- package/src/utils/path.ts +10 -0
- package/src/utils/taskReminder.ts +7 -19
- package/src/utils/worktreeUtils.ts +46 -28
- package/builtin/skills/settings/MEMORY_RULES.md +0 -60
- package/vendor/ripgrep/linux-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-x86_64/rg +0 -0
- package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
- package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
|
@@ -101,18 +101,45 @@ export async function callAgent(options) {
|
|
|
101
101
|
fetchOptions: gatewayConfig.fetchOptions,
|
|
102
102
|
fetch: gatewayConfig.fetch,
|
|
103
103
|
});
|
|
104
|
-
//
|
|
105
|
-
const systemContent = systemPrompt || "";
|
|
106
|
-
// Add system prompt
|
|
107
|
-
const systemMessage = {
|
|
108
|
-
role: "system",
|
|
109
|
-
content: systemContent,
|
|
110
|
-
};
|
|
111
|
-
// ChatCompletionMessageParam[] is already in OpenAI format, add system prompt to the beginning
|
|
112
|
-
openaiMessages = [systemMessage, ...messages];
|
|
113
|
-
// Apply cache control for Claude models
|
|
104
|
+
// Determine model early (needed for system prompt construction)
|
|
114
105
|
const currentModel = model || modelConfig.model;
|
|
115
106
|
const resolvedMaxTokens = options.maxTokens ?? modelConfig.maxTokens;
|
|
107
|
+
// Build system message content
|
|
108
|
+
let systemMessage;
|
|
109
|
+
if (Array.isArray(systemPrompt)) {
|
|
110
|
+
if (supportsPromptCaching(currentModel)) {
|
|
111
|
+
// For Claude models, map blocks to content parts with cache_control on cacheable blocks
|
|
112
|
+
const contentParts = systemPrompt.map((block) => {
|
|
113
|
+
const part = {
|
|
114
|
+
type: "text",
|
|
115
|
+
text: block.text,
|
|
116
|
+
};
|
|
117
|
+
if (block.cacheable) {
|
|
118
|
+
part.cache_control = { type: "ephemeral" };
|
|
119
|
+
}
|
|
120
|
+
return part;
|
|
121
|
+
});
|
|
122
|
+
systemMessage = {
|
|
123
|
+
role: "system",
|
|
124
|
+
content: contentParts,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// For non-Claude models, join blocks into a single string
|
|
129
|
+
systemMessage = {
|
|
130
|
+
role: "system",
|
|
131
|
+
content: systemPrompt.map((b) => b.text).join("\n\n"),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
systemMessage = {
|
|
137
|
+
role: "system",
|
|
138
|
+
content: systemPrompt || "",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ChatCompletionMessageParam[] is already in OpenAI format, add system prompt to the beginning
|
|
142
|
+
openaiMessages = [systemMessage, ...messages];
|
|
116
143
|
processedTools = tools;
|
|
117
144
|
if (supportsPromptCaching(currentModel)) {
|
|
118
145
|
openaiMessages = transformMessagesForExplicitCache(openaiMessages, currentModel);
|
|
@@ -4,6 +4,7 @@ export declare class MemoryService {
|
|
|
4
4
|
private _cachedProjectMemory;
|
|
5
5
|
private _cachedUserMemory;
|
|
6
6
|
private _cachedCombinedMemory;
|
|
7
|
+
private _cachedAutoMemoryContent;
|
|
7
8
|
constructor(container: Container);
|
|
8
9
|
get cachedProjectMemory(): string;
|
|
9
10
|
get cachedUserMemory(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,aAAa;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,aAAa;IAMZ,OAAO,CAAC,SAAS;IAL7B,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,wBAAwB,CAAuB;gBAEnC,SAAS,EAAE,SAAS;IAExC,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IAED,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IAEM,UAAU,IAAI,IAAI;IAOzB;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAU/C;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBtD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BrC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAyCvC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6ChD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBjE"}
|
package/dist/services/memory.js
CHANGED
|
@@ -8,20 +8,22 @@ import { pathEncoder } from "../utils/pathEncoder.js";
|
|
|
8
8
|
export class MemoryService {
|
|
9
9
|
constructor(container) {
|
|
10
10
|
this.container = container;
|
|
11
|
-
this._cachedProjectMemory =
|
|
12
|
-
this._cachedUserMemory =
|
|
11
|
+
this._cachedProjectMemory = null;
|
|
12
|
+
this._cachedUserMemory = null;
|
|
13
13
|
this._cachedCombinedMemory = null;
|
|
14
|
+
this._cachedAutoMemoryContent = null;
|
|
14
15
|
}
|
|
15
16
|
get cachedProjectMemory() {
|
|
16
|
-
return this._cachedProjectMemory;
|
|
17
|
+
return this._cachedProjectMemory ?? "";
|
|
17
18
|
}
|
|
18
19
|
get cachedUserMemory() {
|
|
19
|
-
return this._cachedUserMemory;
|
|
20
|
+
return this._cachedUserMemory ?? "";
|
|
20
21
|
}
|
|
21
22
|
clearCache() {
|
|
22
|
-
this._cachedProjectMemory =
|
|
23
|
-
this._cachedUserMemory =
|
|
23
|
+
this._cachedProjectMemory = null;
|
|
24
|
+
this._cachedUserMemory = null;
|
|
24
25
|
this._cachedCombinedMemory = null;
|
|
26
|
+
this._cachedAutoMemoryContent = null;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Get the project-specific auto-memory directory.
|
|
@@ -66,15 +68,20 @@ export class MemoryService {
|
|
|
66
68
|
* Get the first 200 lines of MEMORY.md.
|
|
67
69
|
*/
|
|
68
70
|
async getAutoMemoryContent(workdir) {
|
|
71
|
+
if (this._cachedAutoMemoryContent !== null) {
|
|
72
|
+
return this._cachedAutoMemoryContent;
|
|
73
|
+
}
|
|
69
74
|
const memoryDir = this.getAutoMemoryDirectory(workdir);
|
|
70
75
|
const memoryFile = path.join(memoryDir, "MEMORY.md");
|
|
71
76
|
try {
|
|
72
77
|
const content = await fs.readFile(memoryFile, "utf-8");
|
|
73
78
|
const lines = content.split("\n").slice(0, 200);
|
|
74
|
-
|
|
79
|
+
this._cachedAutoMemoryContent = lines.join("\n");
|
|
80
|
+
return this._cachedAutoMemoryContent;
|
|
75
81
|
}
|
|
76
82
|
catch (error) {
|
|
77
83
|
if (error.code === "ENOENT") {
|
|
84
|
+
this._cachedAutoMemoryContent = "";
|
|
78
85
|
return "";
|
|
79
86
|
}
|
|
80
87
|
logger.error("Failed to read auto-memory content:", error);
|
|
@@ -110,6 +117,9 @@ export class MemoryService {
|
|
|
110
117
|
}
|
|
111
118
|
}
|
|
112
119
|
async getUserMemoryContent() {
|
|
120
|
+
if (this._cachedUserMemory !== null) {
|
|
121
|
+
return this._cachedUserMemory;
|
|
122
|
+
}
|
|
113
123
|
try {
|
|
114
124
|
await this.ensureUserMemoryFile();
|
|
115
125
|
const content = await fs.readFile(USER_MEMORY_FILE, "utf-8");
|
|
@@ -127,13 +137,15 @@ export class MemoryService {
|
|
|
127
137
|
claudeMemoryPath,
|
|
128
138
|
contentLength: claudeContent.length,
|
|
129
139
|
});
|
|
130
|
-
|
|
140
|
+
this._cachedUserMemory = claudeContent;
|
|
141
|
+
return this._cachedUserMemory;
|
|
131
142
|
}
|
|
132
143
|
catch {
|
|
133
144
|
// CLAUDE.md doesn't exist or can't be read, return the default template
|
|
134
145
|
}
|
|
135
146
|
}
|
|
136
|
-
|
|
147
|
+
this._cachedUserMemory = content;
|
|
148
|
+
return this._cachedUserMemory;
|
|
137
149
|
}
|
|
138
150
|
catch (error) {
|
|
139
151
|
logger.error("Failed to read user memory:", error);
|
|
@@ -141,6 +153,9 @@ export class MemoryService {
|
|
|
141
153
|
}
|
|
142
154
|
}
|
|
143
155
|
async readMemoryFile(workdir) {
|
|
156
|
+
if (this._cachedProjectMemory !== null) {
|
|
157
|
+
return this._cachedProjectMemory;
|
|
158
|
+
}
|
|
144
159
|
const memoryFilePath = path.join(workdir, "AGENTS.md");
|
|
145
160
|
try {
|
|
146
161
|
const content = await fs.readFile(memoryFilePath, "utf-8");
|
|
@@ -148,7 +163,8 @@ export class MemoryService {
|
|
|
148
163
|
memoryFilePath,
|
|
149
164
|
contentLength: content.length,
|
|
150
165
|
});
|
|
151
|
-
|
|
166
|
+
this._cachedProjectMemory = content;
|
|
167
|
+
return this._cachedProjectMemory;
|
|
152
168
|
}
|
|
153
169
|
catch (error) {
|
|
154
170
|
if (error.code === "ENOENT") {
|
|
@@ -160,13 +176,15 @@ export class MemoryService {
|
|
|
160
176
|
memoryFilePath: claudeMemoryPath,
|
|
161
177
|
contentLength: content.length,
|
|
162
178
|
});
|
|
163
|
-
|
|
179
|
+
this._cachedProjectMemory = content;
|
|
180
|
+
return this._cachedProjectMemory;
|
|
164
181
|
}
|
|
165
182
|
catch (claudeError) {
|
|
166
183
|
if (claudeError.code === "ENOENT") {
|
|
167
184
|
logger.debug("Neither AGENTS.md nor CLAUDE.md found", {
|
|
168
185
|
memoryFilePath,
|
|
169
186
|
});
|
|
187
|
+
this._cachedProjectMemory = "";
|
|
170
188
|
return "";
|
|
171
189
|
}
|
|
172
190
|
logger.error("Failed to read CLAUDE.md fallback", {
|
|
@@ -184,15 +202,15 @@ export class MemoryService {
|
|
|
184
202
|
if (this._cachedCombinedMemory !== null) {
|
|
185
203
|
return this._cachedCombinedMemory;
|
|
186
204
|
}
|
|
187
|
-
|
|
188
|
-
|
|
205
|
+
const projectMemory = await this.readMemoryFile(workdir);
|
|
206
|
+
const userMemory = await this.getUserMemoryContent();
|
|
189
207
|
let combined = "";
|
|
190
|
-
if (
|
|
191
|
-
combined +=
|
|
192
|
-
if (
|
|
208
|
+
if (projectMemory.trim())
|
|
209
|
+
combined += projectMemory;
|
|
210
|
+
if (userMemory.trim()) {
|
|
193
211
|
if (combined)
|
|
194
212
|
combined += "\n\n";
|
|
195
|
-
combined +=
|
|
213
|
+
combined += userMemory;
|
|
196
214
|
}
|
|
197
215
|
this._cachedCombinedMemory = combined;
|
|
198
216
|
return combined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentTool.d.ts","sourceRoot":"","sources":["../../src/tools/agentTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAStE;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"agentTool.d.ts","sourceRoot":"","sources":["../../src/tools/agentTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAStE;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,UAqTvB,CAAC"}
|
package/dist/tools/agentTool.js
CHANGED
|
@@ -214,10 +214,32 @@ When using the Agent tool, you must specify a subagent_type parameter to select
|
|
|
214
214
|
}
|
|
215
215
|
catch (error) {
|
|
216
216
|
if (!isBackgrounded) {
|
|
217
|
+
// Extract content from the subagent's last assistant message.
|
|
218
|
+
// aiManager.sendAIMessage() catch block already added an error
|
|
219
|
+
// block via addErrorBlock(), so the error info is in the message
|
|
220
|
+
// history — just return it directly.
|
|
221
|
+
let content = "";
|
|
222
|
+
try {
|
|
223
|
+
const messages = instance.messageManager.getMessages();
|
|
224
|
+
const lastAssistant = messages
|
|
225
|
+
.filter((m) => m.role === "assistant")
|
|
226
|
+
.pop();
|
|
227
|
+
if (lastAssistant) {
|
|
228
|
+
content = lastAssistant.blocks
|
|
229
|
+
.filter((b) => b.type === "text" || b.type === "error")
|
|
230
|
+
.map((b) => b.content)
|
|
231
|
+
.join("\n")
|
|
232
|
+
.trim();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Ignore errors when extracting messages
|
|
237
|
+
}
|
|
238
|
+
const errorMsg = `Agent delegation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
217
239
|
resolve({
|
|
218
240
|
success: false,
|
|
219
|
-
content:
|
|
220
|
-
error:
|
|
241
|
+
content: content || errorMsg,
|
|
242
|
+
error: errorMsg,
|
|
221
243
|
shortResult: "Delegation error",
|
|
222
244
|
});
|
|
223
245
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA2iBtB,CAAC"}
|
package/dist/tools/bashTool.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as path from "path";
|
|
|
4
4
|
import * as os from "os";
|
|
5
5
|
import { logger } from "../utils/globalLogger.js";
|
|
6
6
|
import { resolveShellPath } from "../utils/shellResolver.js";
|
|
7
|
+
import { toPosixPath } from "../utils/path.js";
|
|
7
8
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
8
9
|
import { processToolResult } from "../utils/toolResultStorage.js";
|
|
9
10
|
import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
|
|
@@ -211,7 +212,8 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
211
212
|
return new Promise((resolve) => {
|
|
212
213
|
// Create a temporary file to store the CWD
|
|
213
214
|
const tempCwdFile = path.join(os.tmpdir(), `wave_cwd_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.tmp`);
|
|
214
|
-
const
|
|
215
|
+
const tempCwdFileForBash = toPosixPath(tempCwdFile);
|
|
216
|
+
const wrappedCommand = `${command} && pwd -P >| ${tempCwdFileForBash}`;
|
|
215
217
|
const child = spawn(wrappedCommand, {
|
|
216
218
|
shell: shellPath || true,
|
|
217
219
|
stdio: "pipe",
|
|
@@ -226,6 +228,17 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
226
228
|
let isAborted = false;
|
|
227
229
|
let isBackgrounded = false;
|
|
228
230
|
let isFinished = false;
|
|
231
|
+
// Best-effort cleanup of the temp CWD file — used by abort/error/exit paths
|
|
232
|
+
const cleanupTempFile = () => {
|
|
233
|
+
try {
|
|
234
|
+
if (fs.existsSync(tempCwdFile)) {
|
|
235
|
+
fs.unlinkSync(tempCwdFile);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// ignore — best-effort cleanup
|
|
240
|
+
}
|
|
241
|
+
};
|
|
229
242
|
const updateRealtimeResults = () => {
|
|
230
243
|
if (isAborted || isBackgrounded || isFinished)
|
|
231
244
|
return;
|
|
@@ -352,6 +365,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
352
365
|
}
|
|
353
366
|
}
|
|
354
367
|
}
|
|
368
|
+
cleanupTempFile();
|
|
355
369
|
const processedOutput = processToolResult(outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""), BASH_MAX_OUTPUT_CHARS, "bash");
|
|
356
370
|
resolve({
|
|
357
371
|
success: false,
|
|
@@ -410,15 +424,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
410
424
|
newCwd = undefined;
|
|
411
425
|
}
|
|
412
426
|
finally {
|
|
413
|
-
|
|
414
|
-
try {
|
|
415
|
-
if (fs.existsSync(tempCwdFile)) {
|
|
416
|
-
fs.unlinkSync(tempCwdFile);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
catch (fileError) {
|
|
420
|
-
logger.error("Failed to clean up temp CWD file:", fileError);
|
|
421
|
-
}
|
|
427
|
+
cleanupTempFile();
|
|
422
428
|
}
|
|
423
429
|
// If CWD changed, call the onCwdChange callback and add notification
|
|
424
430
|
let cwdMessage;
|
|
@@ -462,6 +468,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
462
468
|
if (timeoutHandle) {
|
|
463
469
|
clearTimeout(timeoutHandle);
|
|
464
470
|
}
|
|
471
|
+
cleanupTempFile();
|
|
465
472
|
resolve({
|
|
466
473
|
success: false,
|
|
467
474
|
content: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAgRtB,CAAC"}
|
package/dist/tools/editTool.js
CHANGED
|
@@ -93,11 +93,13 @@ Usage:
|
|
|
93
93
|
error: "old_string and new_string must be different",
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
-
//
|
|
97
|
-
context.messageManager?.
|
|
98
|
-
// Enforce read-before-edit: the file must have been read first
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
// Trigger conditional rule loading for this file
|
|
97
|
+
context.messageManager?.triggerFileRead(filePath);
|
|
98
|
+
// Enforce read-before-edit: the file must have been read or written first.
|
|
99
|
+
// readFileState is populated by Read, Write, and Edit tools — single source
|
|
100
|
+
// of truth, aligned with Claude Code's readFileState approach.
|
|
101
|
+
const resolvedPath = resolvePath(filePath, context.workdir);
|
|
102
|
+
if (!context.readFileState?.has(resolvedPath)) {
|
|
101
103
|
return {
|
|
102
104
|
success: false,
|
|
103
105
|
content: "",
|
|
@@ -105,7 +107,6 @@ Usage:
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
try {
|
|
108
|
-
const resolvedPath = resolvePath(filePath, context.workdir);
|
|
109
110
|
// Read file content
|
|
110
111
|
let originalContent;
|
|
111
112
|
try {
|
package/dist/tools/readTool.js
CHANGED
|
@@ -169,8 +169,8 @@ Usage:
|
|
|
169
169
|
error: "file_path parameter is required and must be a string",
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
|
-
//
|
|
173
|
-
context.messageManager?.
|
|
172
|
+
// Trigger conditional rule loading for this file
|
|
173
|
+
context.messageManager?.triggerFileRead(filePath);
|
|
174
174
|
// Check for binary document formats
|
|
175
175
|
if (isBinaryDocument(filePath)) {
|
|
176
176
|
const isPdf = filePath.toLowerCase().endsWith(".pdf");
|
package/dist/tools/writeTool.js
CHANGED
|
@@ -59,8 +59,8 @@ Usage:
|
|
|
59
59
|
error: "content parameter is required and must be a string",
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
//
|
|
63
|
-
context.messageManager?.
|
|
62
|
+
// Trigger conditional rule loading for this file
|
|
63
|
+
context.messageManager?.triggerFileRead(filePath);
|
|
64
64
|
try {
|
|
65
65
|
const resolvedPath = resolvePath(filePath, context.workdir);
|
|
66
66
|
// Check if file already exists
|
|
@@ -22,5 +22,5 @@ export declare const USER_MEMORY_FILE: string;
|
|
|
22
22
|
* AI related constants
|
|
23
23
|
*/
|
|
24
24
|
export declare const DEFAULT_WAVE_MAX_INPUT_TOKENS = 200000;
|
|
25
|
-
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS =
|
|
25
|
+
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS = 32000;
|
|
26
26
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/utils/constants.js
CHANGED
|
@@ -24,4 +24,4 @@ export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "AGENTS.md");
|
|
|
24
24
|
* AI related constants
|
|
25
25
|
*/
|
|
26
26
|
export const DEFAULT_WAVE_MAX_INPUT_TOKENS = 200000; // Default token limit
|
|
27
|
-
export const DEFAULT_WAVE_MAX_OUTPUT_TOKENS =
|
|
27
|
+
export const DEFAULT_WAVE_MAX_OUTPUT_TOKENS = 32000; // Default output token limit (aligned with Claude Code)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0B3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAGhB,uBAAuB,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,sBAAsB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,0BAA0B,GACvC,SAAS,
|
|
1
|
+
{"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0B3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAGhB,uBAAuB,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,sBAAsB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,0BAA0B,GACvC,SAAS,CA8SX"}
|
package/dist/utils/gitUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import * as fsSync from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
4
|
/**
|
|
5
5
|
* Check if a directory is a git repository
|
|
6
6
|
* @param dirPath Directory path
|
|
@@ -30,7 +30,7 @@ export function isGitRepository(dirPath) {
|
|
|
30
30
|
*/
|
|
31
31
|
export function getGitRepoRoot(cwd) {
|
|
32
32
|
try {
|
|
33
|
-
return
|
|
33
|
+
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
34
34
|
cwd,
|
|
35
35
|
encoding: "utf8",
|
|
36
36
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -47,7 +47,7 @@ export function getGitRepoRoot(cwd) {
|
|
|
47
47
|
*/
|
|
48
48
|
export function getGitCommonDir(cwd) {
|
|
49
49
|
try {
|
|
50
|
-
const commonDir =
|
|
50
|
+
const commonDir = execFileSync("git", ["rev-parse", "--git-common-dir"], {
|
|
51
51
|
cwd,
|
|
52
52
|
encoding: "utf8",
|
|
53
53
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -65,7 +65,7 @@ export function getGitCommonDir(cwd) {
|
|
|
65
65
|
*/
|
|
66
66
|
export function getGitMainRepoRoot(cwd) {
|
|
67
67
|
try {
|
|
68
|
-
const output =
|
|
68
|
+
const output = execFileSync("git", ["worktree", "list", "--porcelain"], {
|
|
69
69
|
cwd,
|
|
70
70
|
encoding: "utf8",
|
|
71
71
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -223,7 +223,7 @@ export function getDefaultRemoteBranch(cwd) {
|
|
|
223
223
|
*/
|
|
224
224
|
export function hasUncommittedChanges(cwd) {
|
|
225
225
|
try {
|
|
226
|
-
const status =
|
|
226
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
227
227
|
cwd,
|
|
228
228
|
encoding: "utf8",
|
|
229
229
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -243,7 +243,7 @@ export function hasUncommittedChanges(cwd) {
|
|
|
243
243
|
export function hasNewCommits(cwd, baseBranch) {
|
|
244
244
|
try {
|
|
245
245
|
const range = baseBranch ? `${baseBranch}..HEAD` : "@{u}..HEAD";
|
|
246
|
-
const log =
|
|
246
|
+
const log = execFileSync("git", ["log", range, "--oneline"], {
|
|
247
247
|
cwd,
|
|
248
248
|
encoding: "utf8",
|
|
249
249
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openaiClient.d.ts","sourceRoot":"","sources":["../../src/utils/openaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sCAAsC,EACtC,mCAAmC,EACnC,mBAAmB,EACnB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"openaiClient.d.ts","sourceRoot":"","sources":["../../src/utils/openaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sCAAsC,EACtC,mCAAmC,EACnC,mBAAmB,EACnB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAyBnD,KAAK,YAAY,GACb,sCAAsC,GACtC,mCAAmC,CAAC;AAExC,UAAU,WAAW,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,UAAU,UAAU,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACxC,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACzC;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC,IAAI,IAAI;;qBAGO,CAAC,SAAS,YAAY,UACrB,CAAC,YACC;gBAAE,MAAM,CAAC,EAAE,WAAW,CAAA;aAAE,KACjC,UAAU,CACX,CAAC,SAAS,mCAAmC,GACzC,aAAa,CAAC,mBAAmB,CAAC,GAClC,cAAc,CACnB;;MA2BN;YAEa,OAAO;YAuHN,oBAAoB;CAyCpC"}
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { logger } from "./globalLogger.js";
|
|
2
|
+
const MAX_RETRIES = 10;
|
|
3
|
+
const BASE_DELAY_MS = 500;
|
|
4
|
+
const MAX_DELAY_MS = 32000;
|
|
5
|
+
function getRetryDelay(attempt, retryAfterHeader) {
|
|
6
|
+
if (retryAfterHeader) {
|
|
7
|
+
const seconds = parseInt(retryAfterHeader, 10);
|
|
8
|
+
if (!isNaN(seconds)) {
|
|
9
|
+
return seconds * 1000;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const baseDelay = Math.min(BASE_DELAY_MS * Math.pow(2, attempt - 1), MAX_DELAY_MS);
|
|
13
|
+
const jitter = Math.random() * 0.25 * baseDelay;
|
|
14
|
+
return baseDelay + jitter;
|
|
15
|
+
}
|
|
2
16
|
export class OpenAIClient {
|
|
3
17
|
constructor(config) {
|
|
4
18
|
this.config = config;
|
|
@@ -31,11 +45,10 @@ export class OpenAIClient {
|
|
|
31
45
|
};
|
|
32
46
|
const fetchFn = customFetch || fetch;
|
|
33
47
|
let lastError;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
48
|
+
let lastRetryAfter = null;
|
|
49
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
37
50
|
if (attempt > 0) {
|
|
38
|
-
const delay =
|
|
51
|
+
const delay = getRetryDelay(attempt, lastRetryAfter);
|
|
39
52
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
40
53
|
}
|
|
41
54
|
let response;
|
|
@@ -52,12 +65,13 @@ export class OpenAIClient {
|
|
|
52
65
|
if (e instanceof Error && e.name === "AbortError") {
|
|
53
66
|
throw e;
|
|
54
67
|
}
|
|
55
|
-
if (attempt <
|
|
68
|
+
if (attempt < MAX_RETRIES) {
|
|
56
69
|
logger.warn("OpenAI API network error, retrying...", {
|
|
57
70
|
attempt: attempt + 1,
|
|
58
71
|
error: e,
|
|
59
72
|
});
|
|
60
73
|
lastError = e;
|
|
74
|
+
lastRetryAfter = null;
|
|
61
75
|
continue;
|
|
62
76
|
}
|
|
63
77
|
throw e;
|
|
@@ -77,42 +91,24 @@ export class OpenAIClient {
|
|
|
77
91
|
};
|
|
78
92
|
}
|
|
79
93
|
}
|
|
80
|
-
let
|
|
94
|
+
let responseText = "";
|
|
81
95
|
try {
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
errorBody = JSON.parse(text);
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
logger.error("Failed to parse error response body as JSON", {
|
|
88
|
-
error: e,
|
|
89
|
-
text,
|
|
90
|
-
});
|
|
91
|
-
errorBody = text;
|
|
92
|
-
}
|
|
96
|
+
responseText = await response.text();
|
|
93
97
|
}
|
|
94
98
|
catch (e) {
|
|
95
99
|
logger.error("Failed to read error response text", { error: e });
|
|
96
|
-
errorBody = {};
|
|
97
100
|
}
|
|
98
|
-
const error = new Error(
|
|
99
|
-
errorBody !== null &&
|
|
100
|
-
"error" in errorBody &&
|
|
101
|
-
typeof errorBody.error === "object" &&
|
|
102
|
-
errorBody.error !== null &&
|
|
103
|
-
"message" in errorBody.error
|
|
104
|
-
? String(errorBody.error.message)
|
|
105
|
-
: typeof errorBody === "string"
|
|
106
|
-
? errorBody
|
|
107
|
-
: response.statusText);
|
|
101
|
+
const error = new Error(`HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}: ${responseText}`);
|
|
108
102
|
error.status = response.status;
|
|
109
|
-
error.body =
|
|
103
|
+
error.body = responseText;
|
|
110
104
|
const retryableStatus = response.status === 429 ||
|
|
111
105
|
(response.status >= 500 && response.status !== 501);
|
|
112
|
-
if (retryableStatus && attempt <
|
|
106
|
+
if (retryableStatus && attempt < MAX_RETRIES) {
|
|
107
|
+
lastRetryAfter = response.headers.get("retry-after");
|
|
113
108
|
logger.warn("OpenAI API error, retrying...", {
|
|
114
109
|
attempt: attempt + 1,
|
|
115
110
|
status: response.status,
|
|
111
|
+
retryAfter: lastRetryAfter,
|
|
116
112
|
});
|
|
117
113
|
lastError = error;
|
|
118
114
|
continue;
|
|
@@ -120,7 +116,7 @@ export class OpenAIClient {
|
|
|
120
116
|
logger.error("OpenAI API Error:", {
|
|
121
117
|
status: response.status,
|
|
122
118
|
statusText: response.statusText,
|
|
123
|
-
|
|
119
|
+
body: responseText,
|
|
124
120
|
});
|
|
125
121
|
throw error;
|
|
126
122
|
}
|
|
@@ -147,12 +143,17 @@ export class OpenAIClient {
|
|
|
147
143
|
const data = trimmedLine.slice(5).trim();
|
|
148
144
|
if (data === "[DONE]")
|
|
149
145
|
return;
|
|
146
|
+
if (!data)
|
|
147
|
+
continue; // Skip empty data lines (keepalive heartbeats)
|
|
150
148
|
try {
|
|
151
149
|
const json = JSON.parse(data);
|
|
152
150
|
yield json;
|
|
153
151
|
}
|
|
154
152
|
catch (e) {
|
|
155
|
-
logger.error("Failed to parse stream chunk", {
|
|
153
|
+
logger.error("Failed to parse stream chunk", {
|
|
154
|
+
error: e instanceof Error ? e.message : String(e),
|
|
155
|
+
data,
|
|
156
|
+
});
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
}
|
package/dist/utils/path.d.ts
CHANGED
|
@@ -12,4 +12,11 @@ export declare function resolvePath(filePath: string, workdir: string): string;
|
|
|
12
12
|
* @returns Path for display (relative or absolute)
|
|
13
13
|
*/
|
|
14
14
|
export declare function getDisplayPath(filePath: string, workdir: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Convert backslashes to forward slashes for shell compatibility on Windows.
|
|
17
|
+
* On Windows, os.tmpdir() returns paths with backslashes (e.g., C:\Users\foo\Temp),
|
|
18
|
+
* which are treated as escape characters when interpolated into shell command strings.
|
|
19
|
+
* Returns the path as-is on non-Windows platforms.
|
|
20
|
+
*/
|
|
21
|
+
export declare function toPosixPath(p: string): string;
|
|
15
22
|
//# sourceMappingURL=path.d.ts.map
|
package/dist/utils/path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBxE"}
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBxE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|
package/dist/utils/path.js
CHANGED
|
@@ -46,3 +46,12 @@ export function getDisplayPath(filePath, workdir) {
|
|
|
46
46
|
}
|
|
47
47
|
return filePath;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Convert backslashes to forward slashes for shell compatibility on Windows.
|
|
51
|
+
* On Windows, os.tmpdir() returns paths with backslashes (e.g., C:\Users\foo\Temp),
|
|
52
|
+
* which are treated as escape characters when interpolated into shell command strings.
|
|
53
|
+
* Returns the path as-is on non-Windows platforms.
|
|
54
|
+
*/
|
|
55
|
+
export function toPosixPath(p) {
|
|
56
|
+
return process.platform === "win32" ? p.replace(/\\/g, "/") : p;
|
|
57
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Message } from "../types/messaging.js";
|
|
2
2
|
import type { Task } from "../types/tasks.js";
|
|
3
|
-
import type { ChatCompletionMessageParam } from "openai/resources.js";
|
|
4
3
|
export declare const TASK_REMINDER_CONFIG: {
|
|
5
4
|
TURNS_SINCE_WRITE: number;
|
|
6
5
|
TURNS_BETWEEN_REMINDERS: number;
|
|
@@ -10,8 +9,8 @@ export declare function getTaskReminderTurnCounts(messages: Message[]): {
|
|
|
10
9
|
turnsSinceLastReminder: number;
|
|
11
10
|
};
|
|
12
11
|
export declare function buildTaskReminderText(tasks: Task[]): string;
|
|
13
|
-
export declare function maybeInjectTaskReminder(
|
|
12
|
+
export declare function maybeInjectTaskReminder(turnCounts: {
|
|
14
13
|
turnsSinceLastTaskManagement: number;
|
|
15
14
|
turnsSinceLastReminder: number;
|
|
16
|
-
}, tasks: Task[]):
|
|
15
|
+
}, tasks: Task[]): string | null;
|
|
17
16
|
//# sourceMappingURL=taskReminder.d.ts.map
|