@aiderdesk/aiderdesk 0.66.0 → 0.68.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/out/renderer/assets/{arc-BXuUWHai.js → arc-Cju-fnUJ.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-3BPJPVTR-Bm9oFTP_.js → architectureDiagram-3BPJPVTR-hVK8LPcC.js} +3 -3
- package/out/renderer/assets/{blockDiagram-GPEHLZMM-DQ2DevZl.js → blockDiagram-GPEHLZMM-B04Ulwbh.js} +4 -4
- package/out/renderer/assets/{c4Diagram-AAUBKEIU-BdR46VbA.js → c4Diagram-AAUBKEIU-DSP8EUB6.js} +2 -2
- package/out/renderer/assets/{channel-DUdp1NJ7.js → channel-CM1Bn7Zy.js} +1 -1
- package/out/renderer/assets/{chunk-2J33WTMH-Dzi-idRV.js → chunk-2J33WTMH-Bd_3pGvb.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-DEyFpixF.js → chunk-4BX2VUAB-Csrpxz3N.js} +1 -1
- package/out/renderer/assets/{chunk-55IACEB6-DyyQMIZa.js → chunk-55IACEB6-BB7RTMZZ.js} +1 -1
- package/out/renderer/assets/{chunk-727SXJPM-vXEiesCP.js → chunk-727SXJPM-D6Y9H3aA.js} +5 -5
- package/out/renderer/assets/{chunk-AQP2D5EJ-B0SWmbrS.js → chunk-AQP2D5EJ-D5f9Zgag.js} +3 -3
- package/out/renderer/assets/{chunk-FMBD7UC4-CoPwvBCa.js → chunk-FMBD7UC4-Bstyl64g.js} +1 -1
- package/out/renderer/assets/{chunk-ND2GUHAM-ku5t5SwP.js → chunk-ND2GUHAM-CVaUW2HV.js} +1 -1
- package/out/renderer/assets/{chunk-QZHKN3VN-DBGBAqit.js → chunk-QZHKN3VN-AMfy7Nbn.js} +1 -1
- package/out/renderer/assets/{classDiagram-4FO5ZUOK-DTyjsHX9.js → classDiagram-4FO5ZUOK-CPmL8t3E.js} +6 -6
- package/out/renderer/assets/{classDiagram-v2-Q7XG4LA2-DTyjsHX9.js → classDiagram-v2-Q7XG4LA2-CPmL8t3E.js} +6 -6
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-wGfE9wIx.js → cose-bilkent-S5V4N54A-px_eCLil.js} +1 -1
- package/out/renderer/assets/{dagre-BM42HDAG-cwyj1-l0.js → dagre-BM42HDAG-c63xhfuM.js} +3 -3
- package/out/renderer/assets/{diagram-2AECGRRQ-BYvCxkOs.js → diagram-2AECGRRQ-DISIyKng.js} +3 -3
- package/out/renderer/assets/{diagram-5GNKFQAL--ZlqvgmY.js → diagram-5GNKFQAL-BSkGLBgD.js} +4 -4
- package/out/renderer/assets/{diagram-KO2AKTUF-CoPNrPhx.js → diagram-KO2AKTUF-xiSl-Lui.js} +3 -3
- package/out/renderer/assets/{diagram-LMA3HP47-wjhxYTWf.js → diagram-LMA3HP47-lJ69G8gJ.js} +3 -3
- package/out/renderer/assets/{diagram-OG6HWLK6-DhYpewbd.js → diagram-OG6HWLK6-AoDpX3QT.js} +4 -4
- package/out/renderer/assets/{erDiagram-TEJ5UH35-DolRLBng.js → erDiagram-TEJ5UH35-O7UNRkDw.js} +4 -4
- package/out/renderer/assets/{flowDiagram-I6XJVG4X-DjAbl_XC.js → flowDiagram-I6XJVG4X-Dd9XTtIY.js} +6 -6
- package/out/renderer/assets/{ganttDiagram-6RSMTGT7-AF7-XgtX.js → ganttDiagram-6RSMTGT7-Bc7FUk0Y.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-PVQCEYII-BMZLakzH.js → gitGraphDiagram-PVQCEYII-DwEksAhs.js} +4 -4
- package/out/renderer/assets/{graph-B_ifajWk.js → graph-BPvbzKl1.js} +1 -1
- package/out/renderer/assets/{index-3bI-dJm8.js → index-BmQl7j8n.js} +3399 -2428
- package/out/renderer/assets/{index-B62bIfbt.css → index-z-BItG-u.css} +36 -16
- package/out/renderer/assets/{infoDiagram-5YYISTIA-0f7Qxxvp.js → infoDiagram-5YYISTIA-DvophXOV.js} +2 -2
- package/out/renderer/assets/{ishikawaDiagram-YF4QCWOH-BX_EIAMn.js → ishikawaDiagram-YF4QCWOH-CDT4EDOF.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-JHISSGLW-Dmitv8wD.js → journeyDiagram-JHISSGLW-B5FCPOti.js} +4 -4
- package/out/renderer/assets/jsx-dev-runtime-DuBp-Rhq.js +49 -0
- package/out/renderer/assets/{kanban-definition-UN3LZRKU-By2GFUNB.js → kanban-definition-UN3LZRKU-CM_TQl4S.js} +2 -2
- package/out/renderer/assets/{layout-DAkKffy1.js → layout-DdBKGefG.js} +2 -2
- package/out/renderer/assets/{mindmap-definition-RKZ34NQL-yIrV1m0y.js → mindmap-definition-RKZ34NQL-BeGrpK-H.js} +3 -3
- package/out/renderer/assets/{pieDiagram-4H26LBE5-PV9y5rw_.js → pieDiagram-4H26LBE5-CnMhRK3I.js} +4 -4
- package/out/renderer/assets/{quadrantDiagram-W4KKPZXB-DeX0zTCp.js → quadrantDiagram-W4KKPZXB-O_Q_JI2s.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-4Y6WPE33-Bzfk_KE-.js → requirementDiagram-4Y6WPE33-vf9wLf04.js} +3 -3
- package/out/renderer/assets/{sankeyDiagram-5OEKKPKP-BuCv8QIY.js → sankeyDiagram-5OEKKPKP-CE4n-uB4.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-3UESZ5HK-Zg7Ukud8.js → sequenceDiagram-3UESZ5HK-DebEZhql.js} +3 -3
- package/out/renderer/assets/{stateDiagram-AJRCARHV-CLaqfYR8.js → stateDiagram-AJRCARHV-DCsVosBt.js} +6 -6
- package/out/renderer/assets/{stateDiagram-v2-BHNVJYJU-Cmm1ljQ4.js → stateDiagram-v2-BHNVJYJU-8oguEvt8.js} +4 -4
- package/out/renderer/assets/{timeline-definition-PNZ67QCA-DQBaAVcC.js → timeline-definition-PNZ67QCA-CSfXVnNf.js} +2 -2
- package/out/renderer/assets/{vennDiagram-CIIHVFJN-CuplbU_R.js → vennDiagram-CIIHVFJN-DxOEVeC4.js} +1 -1
- package/out/renderer/assets/{wardley-L42UT6IY-BiqfHMim.js → wardley-L42UT6IY-Cz6T4MDn.js} +1 -1
- package/out/renderer/assets/{wardleyDiagram-YWT4CUSO-BaV0FnUu.js → wardleyDiagram-YWT4CUSO-B4sA3LOJ.js} +3 -3
- package/out/renderer/assets/{xychartDiagram-2RQKCTM6-DA_Miw-n.js → xychartDiagram-2RQKCTM6-DbJjruqS.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/out/resources/prompts/workflow.hbs +2 -2
- package/out/resources/skills/extension-creator/SKILL.md +24 -0
- package/out/resources/skills/extension-creator/references/examples-gallery.md +11 -0
- package/out/resources/skills/extension-creator/references/extension-interface.md +4 -0
- package/out/resources/skills/extension-creator/references/external-libraries.md +159 -0
- package/out/resources/skills/extension-creator/references/ui-components.md +24 -0
- package/out/runner.js +860 -205
- package/package.json +16 -3
package/out/runner.js
CHANGED
|
@@ -231,6 +231,7 @@ const TASKS_TOOL_GET_TASK_MESSAGE = "get_task_message";
|
|
|
231
231
|
const TASKS_TOOL_CREATE_TASK = "create_task";
|
|
232
232
|
const TASKS_TOOL_DELETE_TASK = "delete_task";
|
|
233
233
|
const TASKS_TOOL_SEARCH_TASK = "search_task";
|
|
234
|
+
const TASKS_TOOL_RUN_PROMPT = "run_prompt";
|
|
234
235
|
const TASKS_TOOL_SEARCH_PARENT_TASK = "search_parent_task";
|
|
235
236
|
const TASKS_TOOL_DESCRIPTIONS = {
|
|
236
237
|
[TASKS_TOOL_LIST_TASKS]: "List all tasks in the current project. Returns basic information for each task including id, name, and creation/update timestamps. Use this to get an overview of all available tasks before performing specific task operations.",
|
|
@@ -239,6 +240,7 @@ const TASKS_TOOL_DESCRIPTIONS = {
|
|
|
239
240
|
[TASKS_TOOL_CREATE_TASK]: "Create a new task in the current project with an initial prompt. Optionally use user-provided agentProfileId to use a different agent, a modelId to override the model, or a parentTaskId (if available) to create a subtask of another task. The new task will start with the provided prompt as its first user message. Use this to begin new work streams, separate different aspects of a project, or break down complex tasks into manageable subtasks. Use execute to create a task and wait for the task to be finished. Use executeInBackground to create a task in the background without waiting for the task to be finished.",
|
|
240
241
|
[TASKS_TOOL_DELETE_TASK]: "Permanently delete a task and all its associated data including messages, context files, and metadata. This action cannot be undone. Note that you cannot delete the currently active task. Use this to clean up completed or abandoned tasks, but be cautious as this removes all task history permanently.",
|
|
241
242
|
[TASKS_TOOL_SEARCH_TASK]: "Search content within a specific task using semantic search. Use natural language queries with 2-5 descriptive words including key concepts and context. Searches through task conversation history and context files. Use this to find relevant information, discussions, or code snippets within a task.",
|
|
243
|
+
[TASKS_TOOL_RUN_PROMPT]: "Run a prompt on an existing task. The task must already exist (use create_task first if needed). Use this to send additional instructions to a task, continue work on an existing task, or delegate follow-up work. By default, waits for the prompt to complete before returning. Use executeInBackground to run without waiting.",
|
|
242
244
|
[TASKS_TOOL_SEARCH_PARENT_TASK]: "Search content within parent task using semantic search. Use natural language queries with 2-5 descriptive words including key concepts and context. Automatically searches parent task conversation history and context files."
|
|
243
245
|
};
|
|
244
246
|
const WorktreeSchema = zod.z.object({
|
|
@@ -257,6 +259,13 @@ const MergeStateSchema = zod.z.object({
|
|
|
257
259
|
});
|
|
258
260
|
const AIDER_MODES = ["code", "ask", "architect", "context"];
|
|
259
261
|
const AIDER_COMMANDS = ["commit", "map", "map-refresh", "tokens", "test"];
|
|
262
|
+
var AutonomyMode = /* @__PURE__ */ ((AutonomyMode2) => {
|
|
263
|
+
AutonomyMode2["Manual"] = "manual";
|
|
264
|
+
AutonomyMode2["Guided"] = "guided";
|
|
265
|
+
AutonomyMode2["Autonomous"] = "autonomous";
|
|
266
|
+
return AutonomyMode2;
|
|
267
|
+
})(AutonomyMode || {});
|
|
268
|
+
const DEFAULT_AUTONOMY_MODE = "guided";
|
|
260
269
|
var DiffViewMode = /* @__PURE__ */ ((DiffViewMode2) => {
|
|
261
270
|
DiffViewMode2["SideBySide"] = "side-by-side";
|
|
262
271
|
DiffViewMode2["Unified"] = "unified";
|
|
@@ -300,7 +309,7 @@ const ProjectSettingsSchema = zod.z.object({
|
|
|
300
309
|
thinkingTokens: zod.z.string().optional(),
|
|
301
310
|
currentMode: zod.z.string(),
|
|
302
311
|
weakModelLocked: zod.z.boolean().optional(),
|
|
303
|
-
|
|
312
|
+
autonomyModeLocked: zod.z.boolean().optional(),
|
|
304
313
|
updatedFilesGroupMode: zod.z.enum(["grouped", "flat"]).default("flat"),
|
|
305
314
|
disabledRuleFiles: zod.z.array(zod.z.string()).default([]),
|
|
306
315
|
contextSidebarSectionsOrder: zod.z.array(zod.z.string()).default([]),
|
|
@@ -339,6 +348,12 @@ var ContextCompactionType = /* @__PURE__ */ ((ContextCompactionType2) => {
|
|
|
339
348
|
ContextCompactionType2["Smart"] = "smart";
|
|
340
349
|
return ContextCompactionType2;
|
|
341
350
|
})(ContextCompactionType || {});
|
|
351
|
+
var FileWatchMode = /* @__PURE__ */ ((FileWatchMode2) => {
|
|
352
|
+
FileWatchMode2["Auto"] = "auto";
|
|
353
|
+
FileWatchMode2["Native"] = "native";
|
|
354
|
+
FileWatchMode2["Polling"] = "polling";
|
|
355
|
+
return FileWatchMode2;
|
|
356
|
+
})(FileWatchMode || {});
|
|
342
357
|
var MemoryEmbeddingProgressPhase = /* @__PURE__ */ ((MemoryEmbeddingProgressPhase2) => {
|
|
343
358
|
MemoryEmbeddingProgressPhase2["Idle"] = "idle";
|
|
344
359
|
MemoryEmbeddingProgressPhase2["LoadingModel"] = "loading-model";
|
|
@@ -372,7 +387,7 @@ const TaskDataSchema = zod.z.object({
|
|
|
372
387
|
lastMergeState: MergeStateSchema.optional(),
|
|
373
388
|
aiderTotalCost: zod.z.number(),
|
|
374
389
|
agentTotalCost: zod.z.number(),
|
|
375
|
-
|
|
390
|
+
autonomyMode: zod.z.nativeEnum(AutonomyMode).optional(),
|
|
376
391
|
agentProfileId: zod.z.string().optional(),
|
|
377
392
|
provider: zod.z.string().optional(),
|
|
378
393
|
model: zod.z.string().optional(),
|
|
@@ -886,6 +901,9 @@ if (process.env.NODE_ENV !== "production" || process.env.AIDER_DESK_HEADLESS ===
|
|
|
886
901
|
const initEventLogging = (eventManager) => {
|
|
887
902
|
eventTransport.setEventManager(eventManager);
|
|
888
903
|
};
|
|
904
|
+
const isAutoApprove = (task) => {
|
|
905
|
+
return task.task.autonomyMode !== AutonomyMode.Manual;
|
|
906
|
+
};
|
|
889
907
|
class ApprovalManager {
|
|
890
908
|
constructor(task, profile) {
|
|
891
909
|
this.task = task;
|
|
@@ -913,7 +931,7 @@ class ApprovalManager {
|
|
|
913
931
|
key = extensionResult.key;
|
|
914
932
|
text = extensionResult.text;
|
|
915
933
|
subject = extensionResult.subject;
|
|
916
|
-
if (this.task
|
|
934
|
+
if (isAutoApprove(this.task)) {
|
|
917
935
|
return [true, void 0];
|
|
918
936
|
}
|
|
919
937
|
const isApprovedFromSet = this.alwaysApproveForRunKeys.has(key) || (this.profile.toolApprovals[key] || ToolApprovalState.Always) === ToolApprovalState.Always;
|
|
@@ -1494,6 +1512,7 @@ const AVAILABLE_PROVIDERS = [
|
|
|
1494
1512
|
"lmstudio",
|
|
1495
1513
|
"minimax",
|
|
1496
1514
|
"mistral",
|
|
1515
|
+
"neuralwatt",
|
|
1497
1516
|
"ollama",
|
|
1498
1517
|
"openai",
|
|
1499
1518
|
"openai-compatible",
|
|
@@ -1539,6 +1558,7 @@ const isOpenCodeProvider = (provider) => provider.name === "opencode";
|
|
|
1539
1558
|
const isZaiPlanProvider = (provider) => provider.name === "zai-plan";
|
|
1540
1559
|
const isMinimaxProvider = (provider) => provider.name === "minimax";
|
|
1541
1560
|
const isMistralProvider = (provider) => provider.name === "mistral";
|
|
1561
|
+
const isNeuralwattProvider = (provider) => provider.name === "neuralwatt";
|
|
1542
1562
|
const isSyntheticProvider = (provider) => provider.name === "synthetic";
|
|
1543
1563
|
const DEFAULT_PROVIDER_MODELS = {
|
|
1544
1564
|
"alibaba-plan": "qwen3-coder-plus",
|
|
@@ -1559,7 +1579,8 @@ const DEFAULT_PROVIDER_MODELS = {
|
|
|
1559
1579
|
synthetic: "hf:zai-org/GLM-4.7",
|
|
1560
1580
|
"zai-plan": "glm-5.1",
|
|
1561
1581
|
minimax: "MiniMax-M2.7",
|
|
1562
|
-
mistral: "mistral-large-latest"
|
|
1582
|
+
mistral: "mistral-large-latest",
|
|
1583
|
+
neuralwatt: "claude-sonnet-4-6"
|
|
1563
1584
|
};
|
|
1564
1585
|
const DEFAULT_AIDER_MAIN_MODEL = `anthropic/${DEFAULT_PROVIDER_MODELS.anthropic}`;
|
|
1565
1586
|
const DEFAULT_AGENT_PROFILE_ID = "default";
|
|
@@ -1964,6 +1985,12 @@ const getDefaultProviderParams = (providerName) => {
|
|
|
1964
1985
|
apiKey: ""
|
|
1965
1986
|
};
|
|
1966
1987
|
break;
|
|
1988
|
+
case "neuralwatt":
|
|
1989
|
+
provider = {
|
|
1990
|
+
name: "neuralwatt",
|
|
1991
|
+
apiKey: ""
|
|
1992
|
+
};
|
|
1993
|
+
break;
|
|
1967
1994
|
case "gemini-cli":
|
|
1968
1995
|
provider = {
|
|
1969
1996
|
name: "gemini-cli",
|
|
@@ -2086,7 +2113,7 @@ class TelemetryManager {
|
|
|
2086
2113
|
useTodoTools: profile.useTodoTools,
|
|
2087
2114
|
includeContextFiles: profile.includeContextFiles,
|
|
2088
2115
|
includeRepoMap: profile.includeRepoMap,
|
|
2089
|
-
|
|
2116
|
+
autonomyMode: task?.autonomyMode ?? "guided",
|
|
2090
2117
|
enabledMcpServersCount: profile.enabledServers.length,
|
|
2091
2118
|
totalMcpServersCount: Object.keys(this.store.getSettings().mcpServers).length
|
|
2092
2119
|
}
|
|
@@ -2245,7 +2272,8 @@ const readApiKeyFromConfFile = (filePath, envVarName) => {
|
|
|
2245
2272
|
OPENCODE_API_KEY: ["opencode"],
|
|
2246
2273
|
REQUESTY_API_KEY: ["requesty"],
|
|
2247
2274
|
SYNTHETIC_API_KEY: ["synthetic"],
|
|
2248
|
-
MISTRAL_API_KEY: ["mistral"]
|
|
2275
|
+
MISTRAL_API_KEY: ["mistral"],
|
|
2276
|
+
NEURALWATT_API_KEY: ["neuralwatt"]
|
|
2249
2277
|
};
|
|
2250
2278
|
const providerNames = envVarToProviderName[envVarName] || [envVarName.replace(/_API_KEY$/, "").toLowerCase()];
|
|
2251
2279
|
const apiKeys = Array.isArray(apiKeyValue) ? apiKeyValue : [apiKeyValue];
|
|
@@ -2411,13 +2439,26 @@ const getDefaultProjectSettings = (store, providerModels, baseDir, defaultAgentP
|
|
|
2411
2439
|
modelEditFormats: {},
|
|
2412
2440
|
currentMode: "agent",
|
|
2413
2441
|
agentProfileId: defaultAgentProfileId,
|
|
2414
|
-
|
|
2442
|
+
autonomyModeLocked: false,
|
|
2415
2443
|
updatedFilesGroupMode: "flat",
|
|
2416
2444
|
disabledRuleFiles: [],
|
|
2417
2445
|
contextSidebarSectionsOrder: [],
|
|
2418
2446
|
contextSidebarSectionsHidden: []
|
|
2419
2447
|
};
|
|
2420
2448
|
};
|
|
2449
|
+
const DEFAULT_FETCH_TIMEOUT_MS = 12e4;
|
|
2450
|
+
const fetchWithTimeout = async (url, timeoutMs = DEFAULT_FETCH_TIMEOUT_MS) => {
|
|
2451
|
+
const controller = new AbortController();
|
|
2452
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2453
|
+
try {
|
|
2454
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
2455
|
+
clearTimeout(timeoutId);
|
|
2456
|
+
return response;
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
clearTimeout(timeoutId);
|
|
2459
|
+
throw error;
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2421
2462
|
const filenamify = filenamifyImport.default;
|
|
2422
2463
|
const getFilePathSuggestions = async (currentPath, directoriesOnly = false) => {
|
|
2423
2464
|
try {
|
|
@@ -3259,7 +3300,7 @@ File size limit (${sizeLimit.toFixed(1)} KB) exceeded. Use shell commands (e.g.,
|
|
|
3259
3300
|
}
|
|
3260
3301
|
return resultLines.join("\n");
|
|
3261
3302
|
};
|
|
3262
|
-
const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTokens = 5e4) => {
|
|
3303
|
+
const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTokens = 5e4, saveToFile = true, truncationSuffix) => {
|
|
3263
3304
|
const lines = content.split("\n");
|
|
3264
3305
|
const sizeBytes = Buffer.byteLength(content, "utf8");
|
|
3265
3306
|
const sizeKB = sizeBytes / 1024;
|
|
@@ -3267,10 +3308,13 @@ const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTo
|
|
|
3267
3308
|
if (lines.length <= maxLines && sizeKB <= maxSizeKB && tokenCount <= maxTokens) {
|
|
3268
3309
|
return content;
|
|
3269
3310
|
}
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3311
|
+
let tmpFilePath;
|
|
3312
|
+
if (saveToFile) {
|
|
3313
|
+
const id = Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
|
|
3314
|
+
const tmpFileName = `aider-desk-tool-result-${id}.txt`;
|
|
3315
|
+
tmpFilePath = path.join(os.tmpdir(), tmpFileName);
|
|
3316
|
+
await fs.writeFile(tmpFilePath, content, "utf8");
|
|
3317
|
+
}
|
|
3274
3318
|
const reasons = [];
|
|
3275
3319
|
if (lines.length > maxLines) {
|
|
3276
3320
|
reasons.push(`${lines.length} lines exceeded limit of ${maxLines}`);
|
|
@@ -3281,6 +3325,13 @@ const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTo
|
|
|
3281
3325
|
if (tokenCount > maxTokens) {
|
|
3282
3326
|
reasons.push(`${tokenCount} tokens exceeded limit of ${maxTokens}`);
|
|
3283
3327
|
}
|
|
3328
|
+
const getSuffix = () => {
|
|
3329
|
+
if (truncationSuffix) {
|
|
3330
|
+
return truncationSuffix;
|
|
3331
|
+
}
|
|
3332
|
+
const fileNote = tmpFilePath ? ` Full content saved to ${tmpFilePath}.` : "";
|
|
3333
|
+
return `Content truncated (${reasons.join(", ")}).${fileNote}`;
|
|
3334
|
+
};
|
|
3284
3335
|
if (tokenCount > maxTokens) {
|
|
3285
3336
|
const headBudget = Math.floor(maxTokens / 2);
|
|
3286
3337
|
const tailBudget = maxTokens - headBudget;
|
|
@@ -3313,6 +3364,14 @@ const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTo
|
|
|
3313
3364
|
... ${omittedLines} lines omitted (${reasons.join(", ")}). Full content saved to ${tmpFilePath}.
|
|
3314
3365
|
|
|
3315
3366
|
`;
|
|
3367
|
+
if (truncationSuffix) {
|
|
3368
|
+
const suffixNotice = `
|
|
3369
|
+
|
|
3370
|
+
... ${omittedLines} lines omitted. ${truncationSuffix}
|
|
3371
|
+
|
|
3372
|
+
`;
|
|
3373
|
+
return headLines.join("\n") + suffixNotice + tailLines.join("\n");
|
|
3374
|
+
}
|
|
3316
3375
|
return headLines.join("\n") + truncationNotice + tailLines.join("\n");
|
|
3317
3376
|
}
|
|
3318
3377
|
let preview;
|
|
@@ -3324,7 +3383,7 @@ const truncateToolResult = async (content, maxLines = 1e3, maxSizeKB = 50, maxTo
|
|
|
3324
3383
|
preview = lines.slice(0, maxLines).join("\n");
|
|
3325
3384
|
}
|
|
3326
3385
|
return preview + `
|
|
3327
|
-
...
|
|
3386
|
+
... ${getSuffix()}`;
|
|
3328
3387
|
};
|
|
3329
3388
|
const NETWORK_ERROR_CODES = ["ECONNRESET", "EPIPE", "ETIMEDOUT", "ECONNREFUSED", "ENOTFOUND", "ENETUNREACH", "EAI_AGAIN"];
|
|
3330
3389
|
const UNDICI_ERROR_PREFIX = "UND_ERR_";
|
|
@@ -3744,10 +3803,17 @@ Do not use escape characters \\ in the string like \\n or \\" and others. Do not
|
|
|
3744
3803
|
}
|
|
3745
3804
|
const results = [];
|
|
3746
3805
|
const outputLineRegex = /^(.+?)([:-])(\d+)\2(.*)$/;
|
|
3806
|
+
let pendingBeforeContext = [];
|
|
3807
|
+
let afterContextBreak = false;
|
|
3747
3808
|
for (let rawLine of outputLines) {
|
|
3748
3809
|
if (rawLine.endsWith("\r")) {
|
|
3749
3810
|
rawLine = rawLine.slice(0, -1);
|
|
3750
3811
|
}
|
|
3812
|
+
if (rawLine === "--") {
|
|
3813
|
+
pendingBeforeContext = [];
|
|
3814
|
+
afterContextBreak = true;
|
|
3815
|
+
continue;
|
|
3816
|
+
}
|
|
3751
3817
|
const line = rawLine;
|
|
3752
3818
|
const match = outputLineRegex.exec(line);
|
|
3753
3819
|
if (!match) {
|
|
@@ -3761,18 +3827,28 @@ Do not use escape characters \\ in the string like \\n or \\" and others. Do not
|
|
|
3761
3827
|
const filePath = rawFilePath.startsWith("./") ? rawFilePath.slice(2) : rawFilePath;
|
|
3762
3828
|
const isMatch = separator === ":";
|
|
3763
3829
|
if (isMatch) {
|
|
3830
|
+
const context = pendingBeforeContext.length > 0 ? [...pendingBeforeContext, content] : void 0;
|
|
3764
3831
|
results.push({
|
|
3765
3832
|
filePath,
|
|
3766
3833
|
lineNumber: lineNum,
|
|
3767
|
-
lineContent: content
|
|
3834
|
+
lineContent: content,
|
|
3835
|
+
context
|
|
3768
3836
|
});
|
|
3837
|
+
pendingBeforeContext = [];
|
|
3838
|
+
afterContextBreak = false;
|
|
3769
3839
|
} else {
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3840
|
+
if (afterContextBreak) {
|
|
3841
|
+
pendingBeforeContext.push(content);
|
|
3842
|
+
} else {
|
|
3843
|
+
const lastResult = results[results.length - 1];
|
|
3844
|
+
if (lastResult) {
|
|
3845
|
+
if (!lastResult.context) {
|
|
3846
|
+
lastResult.context = [];
|
|
3847
|
+
}
|
|
3848
|
+
lastResult.context.push(content);
|
|
3849
|
+
} else {
|
|
3850
|
+
pendingBeforeContext.push(content);
|
|
3774
3851
|
}
|
|
3775
|
-
lastResult.context.push(content);
|
|
3776
3852
|
}
|
|
3777
3853
|
}
|
|
3778
3854
|
if (results.length >= maxResults) {
|
|
@@ -4462,15 +4538,15 @@ const createTasksToolset = (settings, task, profile, promptContext) => {
|
|
|
4462
4538
|
parentTaskId: zod.z.string().nullable().optional().describe(
|
|
4463
4539
|
"Optional ID of the parent task. If provided, the new task will be created as a subtask of the specified parent. When asSubtask is specified as true, this is not needed as parent ID is resolved automatically."
|
|
4464
4540
|
),
|
|
4465
|
-
|
|
4466
|
-
|
|
4541
|
+
autonomyMode: zod.z.enum(AutonomyMode).optional().describe(
|
|
4542
|
+
'The autonomy mode for the new task. "manual" requires approval for every tool and plan, "guided" (default) auto-approves tools but waits for plan approval from user, "autonomous" runs without interruption.'
|
|
4467
4543
|
),
|
|
4468
4544
|
worktree: zod.z.boolean().optional().default(false).describe("If true, the task will be created in worktree mode. Use only when explicitly requested by the user."),
|
|
4469
4545
|
executeAndWait: zod.z.boolean().optional().default(false).describe("If true, the task will be created and executed immediately and the tool will wait for it to complete before returning."),
|
|
4470
4546
|
executeInBackground: zod.z.boolean().optional().default(false).describe("If true, the task will be created and executed in the background.")
|
|
4471
4547
|
}),
|
|
4472
4548
|
execute: async (input, { toolCallId }) => {
|
|
4473
|
-
const { prompt, name, agentProfileId, modelId, mode = "agent", asSubtask = false,
|
|
4549
|
+
const { prompt, name, agentProfileId, modelId, mode = "agent", asSubtask = false, autonomyMode, worktree, executeAndWait, executeInBackground } = input;
|
|
4474
4550
|
const parentTaskId = asSubtask ? task.task.parentId || task.taskId : "parentTaskId" in input ? input.parentTaskId : void 0;
|
|
4475
4551
|
task.addToolMessage(toolCallId, TASKS_TOOL_GROUP_NAME, TASKS_TOOL_CREATE_TASK, input, void 0, void 0, promptContext);
|
|
4476
4552
|
const toolName = `${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_CREATE_TASK}`;
|
|
@@ -4488,7 +4564,7 @@ Parent Task ID: ${parentTaskId || "none (top-level task)"}` : ""}`;
|
|
|
4488
4564
|
const newTask = await task.getProject().createNewTask({
|
|
4489
4565
|
parentId: parentTaskId || null,
|
|
4490
4566
|
name: name || "",
|
|
4491
|
-
|
|
4567
|
+
autonomyMode,
|
|
4492
4568
|
workingMode: worktree ? "worktree" : "local"
|
|
4493
4569
|
});
|
|
4494
4570
|
const updates = {};
|
|
@@ -4566,6 +4642,66 @@ Parent Task ID: ${parentTaskId || "none (top-level task)"}` : ""}`;
|
|
|
4566
4642
|
}
|
|
4567
4643
|
}
|
|
4568
4644
|
});
|
|
4645
|
+
const runPromptTool = ai.tool({
|
|
4646
|
+
description: TASKS_TOOL_DESCRIPTIONS[TASKS_TOOL_RUN_PROMPT],
|
|
4647
|
+
inputSchema: zod.z.object({
|
|
4648
|
+
taskId: zod.z.string().describe("The ID of the existing task to run the prompt on"),
|
|
4649
|
+
prompt: zod.z.string().describe("The prompt to run on the task"),
|
|
4650
|
+
mode: zod.z.string().optional().describe("Optional mode to use for the prompt. Use only when explicitly requested by the user."),
|
|
4651
|
+
executeAndWait: zod.z.boolean().optional().default(true).describe("If true (default), the tool will wait for the prompt to complete before returning. If false, the prompt will run in the background.")
|
|
4652
|
+
}),
|
|
4653
|
+
execute: async (input, { toolCallId }) => {
|
|
4654
|
+
const { taskId, prompt, mode, executeAndWait = true } = input;
|
|
4655
|
+
task.addToolMessage(
|
|
4656
|
+
toolCallId,
|
|
4657
|
+
TASKS_TOOL_GROUP_NAME,
|
|
4658
|
+
TASKS_TOOL_RUN_PROMPT,
|
|
4659
|
+
{ taskId, prompt, mode, executeAndWait },
|
|
4660
|
+
void 0,
|
|
4661
|
+
void 0,
|
|
4662
|
+
promptContext
|
|
4663
|
+
);
|
|
4664
|
+
const toolName = `${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_RUN_PROMPT}`;
|
|
4665
|
+
const questionKey = toolName;
|
|
4666
|
+
const questionText = `Approve running prompt on task ${taskId}?`;
|
|
4667
|
+
const questionSubject = `Task ID: ${taskId}
|
|
4668
|
+
Prompt: ${prompt}${executeAndWait ? "\nWait for completion: true" : "\nRun in background: true"}`;
|
|
4669
|
+
const [isApproved, userInput] = await approvalManager.handleToolApproval(toolName, input, questionKey, questionText, questionSubject);
|
|
4670
|
+
if (!isApproved) {
|
|
4671
|
+
return `Running prompt on task denied by user. Reason: ${userInput}`;
|
|
4672
|
+
}
|
|
4673
|
+
try {
|
|
4674
|
+
const targetTask = task.getProject().getTask(taskId);
|
|
4675
|
+
if (!targetTask) {
|
|
4676
|
+
return `Task with ID ${taskId} not found`;
|
|
4677
|
+
}
|
|
4678
|
+
const effectiveMode = mode || targetTask.task.currentMode || "agent";
|
|
4679
|
+
const run = targetTask.runPrompt(prompt, effectiveMode, false);
|
|
4680
|
+
if (executeAndWait) {
|
|
4681
|
+
await run;
|
|
4682
|
+
}
|
|
4683
|
+
const taskState = targetTask.task.state;
|
|
4684
|
+
const contextMessages = await targetTask.getContextMessages();
|
|
4685
|
+
let resultMessage = executeAndWait ? "Prompt has been executed successfully" : "Prompt has been started in the background";
|
|
4686
|
+
if (executeAndWait && taskState === DefaultTaskState.Interrupted) {
|
|
4687
|
+
resultMessage = "Task has been interrupted";
|
|
4688
|
+
} else if (executeAndWait && taskState === DefaultTaskState.Delegated) {
|
|
4689
|
+
resultMessage = "Task has been delegated to a subagent";
|
|
4690
|
+
}
|
|
4691
|
+
return {
|
|
4692
|
+
taskId,
|
|
4693
|
+
result: resultMessage,
|
|
4694
|
+
state: taskState,
|
|
4695
|
+
...executeAndWait && contextMessages.length > 0 && {
|
|
4696
|
+
lastMessage: contextMessages[contextMessages.length - 1]
|
|
4697
|
+
}
|
|
4698
|
+
};
|
|
4699
|
+
} catch (error) {
|
|
4700
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4701
|
+
return `Error running prompt on task: ${errorMessage}`;
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
});
|
|
4569
4705
|
const searchTaskTool = ai.tool({
|
|
4570
4706
|
description: TASKS_TOOL_DESCRIPTIONS[TASKS_TOOL_SEARCH_TASK],
|
|
4571
4707
|
inputSchema: zod.z.object({
|
|
@@ -4632,6 +4768,7 @@ Please, consider reporting an issue at https://github.com/hotovo/aider-desk/issu
|
|
|
4632
4768
|
[`${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_GET_TASK_MESSAGE}`]: getTaskMessageTool,
|
|
4633
4769
|
[`${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_CREATE_TASK}`]: createTaskTool,
|
|
4634
4770
|
[`${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_DELETE_TASK}`]: deleteTaskTool,
|
|
4771
|
+
[`${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_RUN_PROMPT}`]: runPromptTool,
|
|
4635
4772
|
[`${TASKS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${TASKS_TOOL_SEARCH_TASK}`]: searchTaskTool
|
|
4636
4773
|
};
|
|
4637
4774
|
const filteredTools = {};
|
|
@@ -4865,7 +5002,7 @@ const createAiderToolset = (task, profile, promptContext) => {
|
|
|
4865
5002
|
}
|
|
4866
5003
|
task.addToolMessage(toolCallId, AIDER_TOOL_GROUP_NAME, AIDER_TOOL_RUN_PROMPT, { prompt }, void 0, void 0, aiderPromptContext);
|
|
4867
5004
|
const responses = await task.sendPromptToAider(prompt, aiderPromptContext, "code", [], void 0, {
|
|
4868
|
-
autoApprove: task.task.
|
|
5005
|
+
autoApprove: task.task.autonomyMode !== AutonomyMode.Manual,
|
|
4869
5006
|
denyCommands: true
|
|
4870
5007
|
});
|
|
4871
5008
|
task.addLogMessage("loading");
|
|
@@ -6071,7 +6208,8 @@ const addImportantReminders = async (task, profile, projectProfiles, userRequest
|
|
|
6071
6208
|
${subagents}`);
|
|
6072
6209
|
}
|
|
6073
6210
|
}
|
|
6074
|
-
|
|
6211
|
+
const shouldPresentPlan = task.task.autonomyMode !== AutonomyMode.Autonomous;
|
|
6212
|
+
if (shouldPresentPlan && !profile.isSubagent) {
|
|
6075
6213
|
reminders.push("Before making any complex changes, present the plan and wait for my approval.");
|
|
6076
6214
|
}
|
|
6077
6215
|
if (task.getTaskDir() !== task.getProjectDir()) {
|
|
@@ -6577,7 +6715,7 @@ ${fileList}`
|
|
|
6577
6715
|
task.addToolMessage(options.toolCallId, serverName, messageToolName, effectiveInput, void 0, void 0, promptContext);
|
|
6578
6716
|
const toolCalledExtensionResult = await this.extensionManager.dispatchEvent(
|
|
6579
6717
|
"onToolCalled",
|
|
6580
|
-
{ toolName, agentProfile: profile, input: effectiveInput, abortSignal: options.abortSignal || abortSignal },
|
|
6718
|
+
{ toolCallId: options.toolCallId, toolName, agentProfile: profile, input: effectiveInput, abortSignal: options.abortSignal || abortSignal },
|
|
6581
6719
|
task.project,
|
|
6582
6720
|
task
|
|
6583
6721
|
);
|
|
@@ -6594,7 +6732,7 @@ ${fileList}`
|
|
|
6594
6732
|
}
|
|
6595
6733
|
const toolFinishedExtensionResult = await this.extensionManager.dispatchEvent(
|
|
6596
6734
|
"onToolFinished",
|
|
6597
|
-
{ toolName, agentProfile: profile, input: effectiveInput, output: result },
|
|
6735
|
+
{ toolCallId: options.toolCallId, toolName, agentProfile: profile, input: effectiveInput, output: result },
|
|
6598
6736
|
task.project,
|
|
6599
6737
|
task
|
|
6600
6738
|
);
|
|
@@ -6770,7 +6908,8 @@ ${fileList}`
|
|
|
6770
6908
|
};
|
|
6771
6909
|
})
|
|
6772
6910
|
] : prompt,
|
|
6773
|
-
promptContext
|
|
6911
|
+
promptContext,
|
|
6912
|
+
timestamp: Date.now()
|
|
6774
6913
|
} : null;
|
|
6775
6914
|
if (userRequestMessage) {
|
|
6776
6915
|
logger.info("User request message created:", {
|
|
@@ -7037,31 +7176,6 @@ ${fileList}`
|
|
|
7037
7176
|
return extensionResult2.optimizedMessages ?? optimized;
|
|
7038
7177
|
};
|
|
7039
7178
|
const optimizedMessages = await getOptimizedMessages();
|
|
7040
|
-
logger.info("Optimized messages for LLM:", {
|
|
7041
|
-
count: optimizedMessages.length,
|
|
7042
|
-
lastUserMessage: (() => {
|
|
7043
|
-
for (let i = optimizedMessages.length - 1; i >= 0; i--) {
|
|
7044
|
-
if (optimizedMessages[i].role === "user") {
|
|
7045
|
-
const msg = optimizedMessages[i];
|
|
7046
|
-
return {
|
|
7047
|
-
index: i,
|
|
7048
|
-
contentType: typeof msg.content,
|
|
7049
|
-
contentIsArray: Array.isArray(msg.content),
|
|
7050
|
-
contentPreview: typeof msg.content === "string" ? msg.content.substring(0, 200) : Array.isArray(msg.content) ? msg.content.map((p) => ({
|
|
7051
|
-
type: p.type,
|
|
7052
|
-
...p.type === "text" ? { textPreview: p.text?.substring(0, 100) } : {},
|
|
7053
|
-
...p.type === "image" ? {
|
|
7054
|
-
mediaType: p.mediaType,
|
|
7055
|
-
imageType: typeof p.image,
|
|
7056
|
-
imagePreview: typeof p.image === "string" ? p.image.substring(0, 80) : void 0
|
|
7057
|
-
} : {}
|
|
7058
|
-
})) : String(msg.content).substring(0, 200)
|
|
7059
|
-
};
|
|
7060
|
-
}
|
|
7061
|
-
}
|
|
7062
|
-
return null;
|
|
7063
|
-
})()
|
|
7064
|
-
});
|
|
7065
7179
|
return {
|
|
7066
7180
|
providerOptions,
|
|
7067
7181
|
model: ai.wrapLanguageModel({
|
|
@@ -7086,7 +7200,7 @@ ${fileList}`
|
|
|
7086
7200
|
let iterationCount = 0;
|
|
7087
7201
|
let retryCount = 0;
|
|
7088
7202
|
while (true) {
|
|
7089
|
-
logger.info(`Starting iteration ${iterationCount}
|
|
7203
|
+
logger.info(`Starting iteration ${iterationCount}`, { task: task.taskId });
|
|
7090
7204
|
iterationCount++;
|
|
7091
7205
|
if (profile.maxIterations > 0 && iterationCount > profile.maxIterations) {
|
|
7092
7206
|
logger.warn(`Max iterations (${profile.maxIterations}) reached. Stopping agent.`);
|
|
@@ -7783,14 +7897,16 @@ ${fileList}`
|
|
|
7783
7897
|
...message,
|
|
7784
7898
|
id: currentResponseId,
|
|
7785
7899
|
usageReport,
|
|
7786
|
-
promptContext
|
|
7900
|
+
promptContext,
|
|
7901
|
+
timestamp: Date.now()
|
|
7787
7902
|
});
|
|
7788
7903
|
} else if (message.role === "tool") {
|
|
7789
7904
|
messages.push({
|
|
7790
7905
|
...message,
|
|
7791
7906
|
// @ts-expect-error the id is there
|
|
7792
7907
|
id: message.id || uuid.v4(),
|
|
7793
|
-
promptContext
|
|
7908
|
+
promptContext,
|
|
7909
|
+
timestamp: Date.now()
|
|
7794
7910
|
});
|
|
7795
7911
|
}
|
|
7796
7912
|
});
|
|
@@ -7903,6 +8019,52 @@ ${extractTextContent(userRequestMessage.content)}`;
|
|
|
7903
8019
|
return true;
|
|
7904
8020
|
}
|
|
7905
8021
|
}
|
|
8022
|
+
let isDockerCache;
|
|
8023
|
+
const isDocker = () => {
|
|
8024
|
+
if (isDockerCache !== void 0) {
|
|
8025
|
+
return isDockerCache;
|
|
8026
|
+
}
|
|
8027
|
+
try {
|
|
8028
|
+
isDockerCache = fs__namespace.existsSync("/.dockerenv") || fs__namespace.existsSync("/run/.containerenv");
|
|
8029
|
+
} catch {
|
|
8030
|
+
isDockerCache = false;
|
|
8031
|
+
}
|
|
8032
|
+
return isDockerCache;
|
|
8033
|
+
};
|
|
8034
|
+
const isNetworkDrive = (drivePath) => {
|
|
8035
|
+
try {
|
|
8036
|
+
const driveLetter = drivePath.charAt(0).toUpperCase();
|
|
8037
|
+
const output = child_process.execSync(`net use ${driveLetter}:`, {
|
|
8038
|
+
encoding: "utf8",
|
|
8039
|
+
timeout: 5e3,
|
|
8040
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
8041
|
+
});
|
|
8042
|
+
return output.includes("\\\\") || output.includes("//");
|
|
8043
|
+
} catch {
|
|
8044
|
+
return false;
|
|
8045
|
+
}
|
|
8046
|
+
};
|
|
8047
|
+
const shouldUsePolling = (watchPath, mode = FileWatchMode.Auto) => {
|
|
8048
|
+
if (mode === FileWatchMode.Polling) {
|
|
8049
|
+
return true;
|
|
8050
|
+
}
|
|
8051
|
+
if (mode === FileWatchMode.Native) {
|
|
8052
|
+
return false;
|
|
8053
|
+
}
|
|
8054
|
+
if (isDocker()) {
|
|
8055
|
+
logger.debug(`[FileWatch] Docker environment detected, using polling for ${watchPath}`);
|
|
8056
|
+
return true;
|
|
8057
|
+
}
|
|
8058
|
+
if (process.platform === "win32") {
|
|
8059
|
+
const isUncPath = watchPath.startsWith("\\\\") || watchPath.startsWith("//");
|
|
8060
|
+
const isNetworkLetterDrive = /^[A-Za-z]:/.test(watchPath) && isNetworkDrive(watchPath);
|
|
8061
|
+
if (isUncPath || isNetworkLetterDrive) {
|
|
8062
|
+
logger.debug(`[FileWatch] Network path detected (${watchPath}), using polling`);
|
|
8063
|
+
return true;
|
|
8064
|
+
}
|
|
8065
|
+
}
|
|
8066
|
+
return false;
|
|
8067
|
+
};
|
|
7906
8068
|
const getGlobalAgentsDir = () => path__namespace.join(os.homedir(), AIDER_DESK_AGENTS_DIR);
|
|
7907
8069
|
const getProjectAgentsDir = (projectDir) => path__namespace.join(projectDir, AIDER_DESK_AGENTS_DIR);
|
|
7908
8070
|
const getAgentsDirForProfile = (profile) => profile.projectDir ? getProjectAgentsDir(profile.projectDir) : getGlobalAgentsDir();
|
|
@@ -7935,9 +8097,10 @@ const getAllRuleFilesForProfile = async (profile, dirName) => {
|
|
|
7935
8097
|
return ruleFiles;
|
|
7936
8098
|
};
|
|
7937
8099
|
class AgentProfileManager {
|
|
7938
|
-
constructor(eventManager, extensionManager) {
|
|
8100
|
+
constructor(eventManager, extensionManager, store) {
|
|
7939
8101
|
this.eventManager = eventManager;
|
|
7940
8102
|
this.extensionManager = extensionManager;
|
|
8103
|
+
this.store = store;
|
|
7941
8104
|
this.extensionsChangeListener = () => {
|
|
7942
8105
|
this.sendAgentProfilesUpdated();
|
|
7943
8106
|
};
|
|
@@ -8052,12 +8215,12 @@ class AgentProfileManager {
|
|
|
8052
8215
|
}
|
|
8053
8216
|
const watcher = chokidar.watch(agentsDir, {
|
|
8054
8217
|
persistent: true,
|
|
8055
|
-
usePolling:
|
|
8218
|
+
usePolling: shouldUsePolling(agentsDir, this.store.getSettings().fileWatchMode),
|
|
8056
8219
|
ignoreInitial: true
|
|
8057
8220
|
});
|
|
8058
8221
|
const rulesWatcher = chokidar.watch(path__namespace.join(agentsDir, "*", AIDER_DESK_RULES_DIR), {
|
|
8059
8222
|
persistent: true,
|
|
8060
|
-
usePolling:
|
|
8223
|
+
usePolling: shouldUsePolling(agentsDir, this.store.getSettings().fileWatchMode),
|
|
8061
8224
|
ignoreInitial: true
|
|
8062
8225
|
});
|
|
8063
8226
|
const reloadFunction = () => this.debounceReloadProfiles(agentsDir);
|
|
@@ -8455,6 +8618,22 @@ class AgentProfileManager {
|
|
|
8455
8618
|
this.directoryWatchers.clear();
|
|
8456
8619
|
this.profiles.clear();
|
|
8457
8620
|
}
|
|
8621
|
+
async settingsChanged(oldSettings, newSettings) {
|
|
8622
|
+
if (oldSettings.fileWatchMode === newSettings.fileWatchMode) {
|
|
8623
|
+
return;
|
|
8624
|
+
}
|
|
8625
|
+
const watchedDirs = Array.from(this.directoryWatchers.keys());
|
|
8626
|
+
for (const watcher of this.directoryWatchers.values()) {
|
|
8627
|
+
await watcher.close();
|
|
8628
|
+
}
|
|
8629
|
+
this.directoryWatchers.clear();
|
|
8630
|
+
for (const dir of watchedDirs) {
|
|
8631
|
+
if (dir.endsWith("-rules")) {
|
|
8632
|
+
continue;
|
|
8633
|
+
}
|
|
8634
|
+
await this.setupWatcherForDirectory(dir);
|
|
8635
|
+
}
|
|
8636
|
+
}
|
|
8458
8637
|
getDefaultAgentProfileId() {
|
|
8459
8638
|
for (const defaultProfile of DEFAULT_AGENT_PROFILES) {
|
|
8460
8639
|
if (this.profiles.has(defaultProfile.id)) {
|
|
@@ -9037,7 +9216,8 @@ const InitProjectRulesFileSchema = zod.z.object({
|
|
|
9037
9216
|
const CreateNewTaskSchema = zod.z.object({
|
|
9038
9217
|
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
9039
9218
|
parentId: zod.z.string().nullable().optional(),
|
|
9040
|
-
name: zod.z.string().optional()
|
|
9219
|
+
name: zod.z.string().optional(),
|
|
9220
|
+
activate: zod.z.boolean().optional()
|
|
9041
9221
|
});
|
|
9042
9222
|
const UpdateTaskSchema = zod.z.object({
|
|
9043
9223
|
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
@@ -9335,8 +9515,8 @@ class ProjectApi extends BaseApi {
|
|
|
9335
9515
|
if (!parsed) {
|
|
9336
9516
|
return;
|
|
9337
9517
|
}
|
|
9338
|
-
const { projectDir, parentId, name } = parsed;
|
|
9339
|
-
const params = { parentId, name };
|
|
9518
|
+
const { projectDir, parentId, name, activate } = parsed;
|
|
9519
|
+
const params = { parentId, name, activate };
|
|
9340
9520
|
const task = await this.eventsHandler.createNewTask(projectDir, params);
|
|
9341
9521
|
res.status(200).json(task);
|
|
9342
9522
|
})
|
|
@@ -10663,6 +10843,18 @@ class ExtensionsApi extends BaseApi {
|
|
|
10663
10843
|
res.status(200).json(result);
|
|
10664
10844
|
})
|
|
10665
10845
|
);
|
|
10846
|
+
router.post(
|
|
10847
|
+
"/extensions/load-library",
|
|
10848
|
+
this.handleRequest(async (req, res) => {
|
|
10849
|
+
const { librarySpec } = req.body;
|
|
10850
|
+
if (!librarySpec) {
|
|
10851
|
+
res.status(400).json({ message: "librarySpec is required" });
|
|
10852
|
+
return;
|
|
10853
|
+
}
|
|
10854
|
+
const source = await this.eventsHandler.loadExtensionLibrary(librarySpec);
|
|
10855
|
+
res.status(200).type("application/javascript").send(source);
|
|
10856
|
+
})
|
|
10857
|
+
);
|
|
10666
10858
|
router.get(
|
|
10667
10859
|
"/extensions/config-component",
|
|
10668
10860
|
this.handleRequest(async (req, res) => {
|
|
@@ -11402,10 +11594,11 @@ class ShellCommandError extends Error {
|
|
|
11402
11594
|
}
|
|
11403
11595
|
const execAsync$1 = util.promisify(child_process.exec);
|
|
11404
11596
|
class CustomCommandManager {
|
|
11405
|
-
constructor(project, eventManager, extensionManager) {
|
|
11597
|
+
constructor(project, eventManager, extensionManager, store) {
|
|
11406
11598
|
this.project = project;
|
|
11407
11599
|
this.eventManager = eventManager;
|
|
11408
11600
|
this.extensionManager = extensionManager;
|
|
11601
|
+
this.store = store;
|
|
11409
11602
|
}
|
|
11410
11603
|
commands = /* @__PURE__ */ new Map();
|
|
11411
11604
|
watchers = [];
|
|
@@ -11445,7 +11638,7 @@ class CustomCommandManager {
|
|
|
11445
11638
|
}
|
|
11446
11639
|
const watcher = chokidar.watch(commandsDir, {
|
|
11447
11640
|
persistent: true,
|
|
11448
|
-
usePolling:
|
|
11641
|
+
usePolling: shouldUsePolling(commandsDir, this.store.getSettings().fileWatchMode),
|
|
11449
11642
|
ignoreInitial: true
|
|
11450
11643
|
});
|
|
11451
11644
|
watcher.on("add", async () => {
|
|
@@ -11503,7 +11696,7 @@ class CustomCommandManager {
|
|
|
11503
11696
|
const args = Array.isArray(parsed.arguments) ? parsed.arguments : [];
|
|
11504
11697
|
const template = parsed.__content?.trim() || "";
|
|
11505
11698
|
const includeContext = typeof parsed.includeContext === "boolean" ? parsed.includeContext : true;
|
|
11506
|
-
const
|
|
11699
|
+
const autonomyMode = typeof parsed.autonomyMode === "string" && ["manual", "guided", "autonomous"].includes(parsed.autonomyMode) ? parsed.autonomyMode : void 0;
|
|
11507
11700
|
const skills = typeof parsed.skills === "string" && parsed.skills.trim() ? parsed.skills.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
11508
11701
|
commands.set(name, {
|
|
11509
11702
|
name,
|
|
@@ -11511,7 +11704,7 @@ class CustomCommandManager {
|
|
|
11511
11704
|
arguments: args,
|
|
11512
11705
|
template,
|
|
11513
11706
|
includeContext,
|
|
11514
|
-
|
|
11707
|
+
autonomyMode,
|
|
11515
11708
|
skills
|
|
11516
11709
|
});
|
|
11517
11710
|
} catch (err) {
|
|
@@ -11644,6 +11837,14 @@ class CustomCommandManager {
|
|
|
11644
11837
|
this.watchers.forEach((watcher) => watcher.close());
|
|
11645
11838
|
this.watchers = [];
|
|
11646
11839
|
}
|
|
11840
|
+
async settingsChanged(oldSettings, newSettings) {
|
|
11841
|
+
if (oldSettings.fileWatchMode === newSettings.fileWatchMode) {
|
|
11842
|
+
return;
|
|
11843
|
+
}
|
|
11844
|
+
this.watchers.forEach((watcher) => watcher.close());
|
|
11845
|
+
this.watchers = [];
|
|
11846
|
+
await this.setupFileWatchers();
|
|
11847
|
+
}
|
|
11647
11848
|
}
|
|
11648
11849
|
const migrateContextMessage = (message) => {
|
|
11649
11850
|
if (Array.isArray(message.content)) {
|
|
@@ -11778,7 +11979,8 @@ class ContextManager {
|
|
|
11778
11979
|
id: uuid.v4(),
|
|
11779
11980
|
role: roleOrMessage,
|
|
11780
11981
|
content: content || "",
|
|
11781
|
-
usageReport
|
|
11982
|
+
usageReport,
|
|
11983
|
+
timestamp: Date.now()
|
|
11782
11984
|
};
|
|
11783
11985
|
} else {
|
|
11784
11986
|
message = roleOrMessage;
|
|
@@ -12427,6 +12629,7 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12427
12629
|
toolMessage.response = JSON.stringify(part.output.value);
|
|
12428
12630
|
toolMessage.usageReport = message.usageReport || toolMessage.usageReport;
|
|
12429
12631
|
toolMessage.promptContext = promptContext;
|
|
12632
|
+
toolMessage.finished = true;
|
|
12430
12633
|
}
|
|
12431
12634
|
if (serverName === AIDER_TOOL_GROUP_NAME && toolName === AIDER_TOOL_RUN_PROMPT && part.output?.value && typeof part.output.value === "object" && "responses" in part.output.value) {
|
|
12432
12635
|
const responses = part.output.value.responses;
|
|
@@ -12444,7 +12647,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12444
12647
|
commitMessage: response.commitMessage,
|
|
12445
12648
|
diff: response.diff,
|
|
12446
12649
|
usageReport: response.usageReport,
|
|
12447
|
-
promptContext: message.promptContext
|
|
12650
|
+
promptContext: message.promptContext,
|
|
12651
|
+
timestamp: message.timestamp
|
|
12448
12652
|
};
|
|
12449
12653
|
messagesData.push(responseCompletedData);
|
|
12450
12654
|
});
|
|
@@ -12483,7 +12687,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12483
12687
|
baseDir: this.task.getProjectDir(),
|
|
12484
12688
|
taskId: this.taskId,
|
|
12485
12689
|
usageReport: subMessage.usageReport,
|
|
12486
|
-
promptContext: subMessage.promptContext
|
|
12690
|
+
promptContext: subMessage.promptContext,
|
|
12691
|
+
timestamp: subMessage.timestamp
|
|
12487
12692
|
};
|
|
12488
12693
|
messagesData.push(responseCompletedData);
|
|
12489
12694
|
}
|
|
@@ -12499,7 +12704,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12499
12704
|
toolName: subToolName,
|
|
12500
12705
|
args: subPart.input,
|
|
12501
12706
|
usageReport: void 0,
|
|
12502
|
-
promptContext: subMessage.promptContext
|
|
12707
|
+
promptContext: subMessage.promptContext,
|
|
12708
|
+
timestamp: subMessage.timestamp
|
|
12503
12709
|
};
|
|
12504
12710
|
messagesData.push(toolData);
|
|
12505
12711
|
}
|
|
@@ -12513,7 +12719,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12513
12719
|
baseDir: this.task.getProjectDir(),
|
|
12514
12720
|
taskId: this.taskId,
|
|
12515
12721
|
usageReport: subMessage.usageReport,
|
|
12516
|
-
promptContext: subMessage.promptContext
|
|
12722
|
+
promptContext: subMessage.promptContext,
|
|
12723
|
+
timestamp: subMessage.timestamp
|
|
12517
12724
|
};
|
|
12518
12725
|
messagesData.push(responseCompletedData);
|
|
12519
12726
|
}
|
|
@@ -12523,6 +12730,7 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12523
12730
|
const toolMessage2 = messagesData.find((message2) => message2.type === "tool" && message2.id === subPart.toolCallId);
|
|
12524
12731
|
if (toolMessage2) {
|
|
12525
12732
|
toolMessage2.response = JSON.stringify(subPart.output.value);
|
|
12733
|
+
toolMessage2.finished = true;
|
|
12526
12734
|
}
|
|
12527
12735
|
}
|
|
12528
12736
|
}
|
|
@@ -12556,7 +12764,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12556
12764
|
commitMessage: message.commitMessage,
|
|
12557
12765
|
diff: message.diff,
|
|
12558
12766
|
usageReport: message.usageReport,
|
|
12559
|
-
promptContext: message.promptContext
|
|
12767
|
+
promptContext: message.promptContext,
|
|
12768
|
+
timestamp: message.timestamp
|
|
12560
12769
|
};
|
|
12561
12770
|
messagesData.push(responseCompletedData);
|
|
12562
12771
|
reasoning = "";
|
|
@@ -12585,7 +12794,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12585
12794
|
toolName,
|
|
12586
12795
|
args: toolCall.input,
|
|
12587
12796
|
usageReport: message.usageReport,
|
|
12588
|
-
promptContext: message.promptContext
|
|
12797
|
+
promptContext: message.promptContext,
|
|
12798
|
+
timestamp: message.timestamp
|
|
12589
12799
|
};
|
|
12590
12800
|
messagesData.push(toolData);
|
|
12591
12801
|
} else if (part.type === "tool-result") {
|
|
@@ -12600,6 +12810,7 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12600
12810
|
if (toolMessage) {
|
|
12601
12811
|
toolMessage.response = JSON.stringify(toolResultData.output);
|
|
12602
12812
|
toolMessage.usageReport = message.usageReport || toolMessage.usageReport;
|
|
12813
|
+
toolMessage.finished = true;
|
|
12603
12814
|
const promptContext = extractPromptContextFromToolResult(toolResultData.output);
|
|
12604
12815
|
if (promptContext) {
|
|
12605
12816
|
toolMessage.promptContext = promptContext;
|
|
@@ -12619,7 +12830,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12619
12830
|
taskId: this.taskId,
|
|
12620
12831
|
reflectedMessage: message.reflectedMessage,
|
|
12621
12832
|
usageReport: message.usageReport,
|
|
12622
|
-
promptContext: message.promptContext
|
|
12833
|
+
promptContext: message.promptContext,
|
|
12834
|
+
timestamp: message.timestamp
|
|
12623
12835
|
};
|
|
12624
12836
|
messagesData.push(responseCompletedData);
|
|
12625
12837
|
}
|
|
@@ -12637,7 +12849,8 @@ ${JSON.stringify(part.output.value)}`
|
|
|
12637
12849
|
taskId: this.taskId,
|
|
12638
12850
|
content,
|
|
12639
12851
|
images: images && images.length > 0 ? images : void 0,
|
|
12640
|
-
promptContext: message.promptContext
|
|
12852
|
+
promptContext: message.promptContext,
|
|
12853
|
+
timestamp: message.timestamp
|
|
12641
12854
|
};
|
|
12642
12855
|
messagesData.push(userMessageData);
|
|
12643
12856
|
} else if (message.role === "tool" && Array.isArray(message.content)) {
|
|
@@ -13395,7 +13608,16 @@ class SkillManager {
|
|
|
13395
13608
|
loadSkillsFromDir(projectSkillsDir, "project"),
|
|
13396
13609
|
loadSkillsFromDir(AIDER_DESK_BUILTIN_SKILLS_DIR, "builtin")
|
|
13397
13610
|
]);
|
|
13398
|
-
|
|
13611
|
+
const allSkills = [...extensionSkills, ...projectSkills, ...globalSkills, ...builtinSkills];
|
|
13612
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13613
|
+
const deduped = [];
|
|
13614
|
+
for (const skill of allSkills) {
|
|
13615
|
+
if (!seen.has(skill.name)) {
|
|
13616
|
+
seen.add(skill.name);
|
|
13617
|
+
deduped.push(skill);
|
|
13618
|
+
}
|
|
13619
|
+
}
|
|
13620
|
+
return deduped;
|
|
13399
13621
|
}
|
|
13400
13622
|
async getSkills(contextMessages) {
|
|
13401
13623
|
const skills = await this.loadAllSkills();
|
|
@@ -15211,6 +15433,12 @@ Git output: ${err.stderr || err.stdout || err.message}`
|
|
|
15211
15433
|
await this.pruneDeleted(projectDir);
|
|
15212
15434
|
}
|
|
15213
15435
|
}
|
|
15436
|
+
var CompactionLevel = /* @__PURE__ */ ((CompactionLevel2) => {
|
|
15437
|
+
CompactionLevel2[CompactionLevel2["One"] = 1] = "One";
|
|
15438
|
+
CompactionLevel2[CompactionLevel2["Two"] = 2] = "Two";
|
|
15439
|
+
CompactionLevel2[CompactionLevel2["Three"] = 3] = "Three";
|
|
15440
|
+
return CompactionLevel2;
|
|
15441
|
+
})(CompactionLevel || {});
|
|
15214
15442
|
const extractFilePath = (args) => {
|
|
15215
15443
|
if (typeof args === "object" && args !== null && "filePath" in args) {
|
|
15216
15444
|
return args.filePath;
|
|
@@ -15327,10 +15555,9 @@ const getProtectedStartIndex = (messages, protectedMessageCount) => {
|
|
|
15327
15555
|
return Math.max(0, messages.length - protectedMessageCount);
|
|
15328
15556
|
};
|
|
15329
15557
|
const mergeConsecutiveAssistantMessages = (messages) => {
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
const
|
|
15333
|
-
const next = result[i + 1];
|
|
15558
|
+
for (let i = messages.length - 2; i >= 0; i--) {
|
|
15559
|
+
const current = messages[i];
|
|
15560
|
+
const next = messages[i + 1];
|
|
15334
15561
|
if (current.role !== "assistant" || next.role !== "assistant") {
|
|
15335
15562
|
continue;
|
|
15336
15563
|
}
|
|
@@ -15343,35 +15570,95 @@ const mergeConsecutiveAssistantMessages = (messages) => {
|
|
|
15343
15570
|
const nextTextParts = Array.isArray(next.content) ? next.content.filter((p) => p.type === "text") : [];
|
|
15344
15571
|
const mergedText = [...currentTextParts, ...nextTextParts].map((p) => p.text).filter(Boolean).join("\n\n");
|
|
15345
15572
|
current.content = mergedText ? [{ type: "text", text: mergedText }] : [];
|
|
15346
|
-
|
|
15573
|
+
messages.splice(i + 1, 1);
|
|
15347
15574
|
}
|
|
15348
|
-
return
|
|
15575
|
+
return messages.filter((msg) => {
|
|
15349
15576
|
if (msg.role === "assistant" && Array.isArray(msg.content) && msg.content.length === 0) {
|
|
15350
15577
|
return false;
|
|
15351
15578
|
}
|
|
15352
15579
|
return true;
|
|
15353
15580
|
});
|
|
15354
15581
|
};
|
|
15355
|
-
const
|
|
15582
|
+
const truncateNonPowerToolResults = async (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
15583
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15584
|
+
const redactionMessage = "Result redacted due to compaction, run again if needed.";
|
|
15585
|
+
for (let i = 0; i < protectedStart; i++) {
|
|
15586
|
+
const msg = messages[i];
|
|
15587
|
+
if (msg.role !== "tool") {
|
|
15588
|
+
continue;
|
|
15589
|
+
}
|
|
15590
|
+
for (let j = 0; j < msg.content.length; j++) {
|
|
15591
|
+
const part = msg.content[j];
|
|
15592
|
+
if (part.type !== "tool-result") {
|
|
15593
|
+
continue;
|
|
15594
|
+
}
|
|
15595
|
+
const [serverName] = extractServerNameToolName(part.toolName);
|
|
15596
|
+
if (isPowerTool(serverName)) {
|
|
15597
|
+
continue;
|
|
15598
|
+
}
|
|
15599
|
+
if (compactionLevel >= 3) {
|
|
15600
|
+
if (part.output.type === "text" || part.output.type === "error-text") {
|
|
15601
|
+
part.output = {
|
|
15602
|
+
type: part.output.type,
|
|
15603
|
+
value: redactionMessage
|
|
15604
|
+
};
|
|
15605
|
+
} else {
|
|
15606
|
+
part.output = {
|
|
15607
|
+
type: "text",
|
|
15608
|
+
value: redactionMessage
|
|
15609
|
+
};
|
|
15610
|
+
}
|
|
15611
|
+
continue;
|
|
15612
|
+
}
|
|
15613
|
+
if (part.output.type !== "text" && part.output.type !== "error-text") {
|
|
15614
|
+
continue;
|
|
15615
|
+
}
|
|
15616
|
+
const outputText = part.output.value;
|
|
15617
|
+
if (!outputText) {
|
|
15618
|
+
continue;
|
|
15619
|
+
}
|
|
15620
|
+
const maxLines = compactionLevel >= 2 ? 10 : 20;
|
|
15621
|
+
const maxSizeKB = compactionLevel >= 2 ? 1 : 2;
|
|
15622
|
+
const maxTokens = compactionLevel >= 2 ? 1e3 : 2e3;
|
|
15623
|
+
const truncated = await truncateToolResult(
|
|
15624
|
+
outputText,
|
|
15625
|
+
maxLines,
|
|
15626
|
+
maxSizeKB,
|
|
15627
|
+
maxTokens,
|
|
15628
|
+
false,
|
|
15629
|
+
"Output truncated due to compaction, re-execute the tool if full output is needed."
|
|
15630
|
+
);
|
|
15631
|
+
if (truncated !== outputText) {
|
|
15632
|
+
part.output = {
|
|
15633
|
+
type: part.output.type,
|
|
15634
|
+
value: truncated
|
|
15635
|
+
};
|
|
15636
|
+
}
|
|
15637
|
+
}
|
|
15638
|
+
}
|
|
15639
|
+
return messages;
|
|
15640
|
+
};
|
|
15641
|
+
const smartCompactMessages = async (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
15356
15642
|
let result = cloneMessages(messages);
|
|
15357
15643
|
result = removeErroredTools(result, protectedMessageCount);
|
|
15358
15644
|
result = collapseFileEdits(result, protectedMessageCount);
|
|
15359
15645
|
result = removeStaleFileReads(result, protectedMessageCount);
|
|
15360
|
-
result =
|
|
15361
|
-
result =
|
|
15362
|
-
result =
|
|
15646
|
+
result = compactFileReads(result, protectedMessageCount, compactionLevel);
|
|
15647
|
+
result = removeObsoleteSearches(result, protectedMessageCount, compactionLevel);
|
|
15648
|
+
result = compactSemanticSearches(result, protectedMessageCount, compactionLevel);
|
|
15649
|
+
result = deduplicateBash(result, protectedMessageCount, compactionLevel);
|
|
15363
15650
|
result = redactFetchOutputs(result, protectedMessageCount);
|
|
15651
|
+
result = await truncateNonPowerToolResults(result, protectedMessageCount, compactionLevel);
|
|
15364
15652
|
result = mergeConsecutiveAssistantMessages(result);
|
|
15365
15653
|
return result;
|
|
15366
15654
|
};
|
|
15367
15655
|
const removeErroredTools = (messages, protectedMessageCount = 10) => {
|
|
15368
|
-
const
|
|
15369
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
15656
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15370
15657
|
for (let i = protectedStart - 1; i >= 0; i--) {
|
|
15371
|
-
if (i >=
|
|
15658
|
+
if (i >= messages.length) {
|
|
15372
15659
|
continue;
|
|
15373
15660
|
}
|
|
15374
|
-
const msg =
|
|
15661
|
+
const msg = messages[i];
|
|
15375
15662
|
if (msg.role !== "tool") {
|
|
15376
15663
|
continue;
|
|
15377
15664
|
}
|
|
@@ -15381,22 +15668,21 @@ const removeErroredTools = (messages, protectedMessageCount = 10) => {
|
|
|
15381
15668
|
continue;
|
|
15382
15669
|
}
|
|
15383
15670
|
if (isErrorResult(info.output) || isNoOpResult(info.output)) {
|
|
15384
|
-
removeToolCallFromAssistant(
|
|
15385
|
-
removeToolResult(
|
|
15671
|
+
removeToolCallFromAssistant(messages, info.toolCallId);
|
|
15672
|
+
removeToolResult(messages, info.toolCallId);
|
|
15386
15673
|
}
|
|
15387
15674
|
}
|
|
15388
15675
|
}
|
|
15389
|
-
return
|
|
15676
|
+
return messages;
|
|
15390
15677
|
};
|
|
15391
15678
|
const collapseFileEdits = (messages, protectedMessageCount = 10) => {
|
|
15392
|
-
const
|
|
15393
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
15679
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15394
15680
|
const fileEditGroups = /* @__PURE__ */ new Map();
|
|
15395
15681
|
for (let i = 0; i < protectedStart; i++) {
|
|
15396
|
-
if (i >=
|
|
15682
|
+
if (i >= messages.length) {
|
|
15397
15683
|
break;
|
|
15398
15684
|
}
|
|
15399
|
-
const msg =
|
|
15685
|
+
const msg = messages[i];
|
|
15400
15686
|
if (msg.role !== "tool") {
|
|
15401
15687
|
continue;
|
|
15402
15688
|
}
|
|
@@ -15411,7 +15697,7 @@ const collapseFileEdits = (messages, protectedMessageCount = 10) => {
|
|
|
15411
15697
|
if (toolName !== POWER_TOOL_FILE_EDIT && toolName !== POWER_TOOL_FILE_WRITE) {
|
|
15412
15698
|
continue;
|
|
15413
15699
|
}
|
|
15414
|
-
const callInfo = findAssistantToolCall(
|
|
15700
|
+
const callInfo = findAssistantToolCall(messages, part.toolCallId);
|
|
15415
15701
|
if (!callInfo) {
|
|
15416
15702
|
continue;
|
|
15417
15703
|
}
|
|
@@ -15443,22 +15729,21 @@ const collapseFileEdits = (messages, protectedMessageCount = 10) => {
|
|
|
15443
15729
|
}
|
|
15444
15730
|
]
|
|
15445
15731
|
};
|
|
15446
|
-
const assistantIndex =
|
|
15732
|
+
const assistantIndex = messages.findIndex((m) => m.id === lastEdit.assistantMessageId);
|
|
15447
15733
|
const insertIndex = assistantIndex !== -1 ? assistantIndex + 1 : 0;
|
|
15448
|
-
|
|
15734
|
+
messages.splice(insertIndex, 0, syntheticMessage);
|
|
15449
15735
|
for (const edit of edits) {
|
|
15450
|
-
removeToolCallFromAssistant(
|
|
15451
|
-
removeToolResult(
|
|
15736
|
+
removeToolCallFromAssistant(messages, edit.toolCallId);
|
|
15737
|
+
removeToolResult(messages, edit.toolCallId);
|
|
15452
15738
|
}
|
|
15453
15739
|
}
|
|
15454
|
-
return
|
|
15740
|
+
return messages;
|
|
15455
15741
|
};
|
|
15456
15742
|
const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
15457
|
-
const
|
|
15458
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
15743
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15459
15744
|
const editedFilePaths = /* @__PURE__ */ new Set();
|
|
15460
|
-
for (let i = 0; i <
|
|
15461
|
-
const msg =
|
|
15745
|
+
for (let i = 0; i < messages.length; i++) {
|
|
15746
|
+
const msg = messages[i];
|
|
15462
15747
|
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
15463
15748
|
for (const part of msg.content) {
|
|
15464
15749
|
if (part.type === "text") {
|
|
@@ -15484,7 +15769,7 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15484
15769
|
if (toolName !== POWER_TOOL_FILE_EDIT && toolName !== POWER_TOOL_FILE_WRITE) {
|
|
15485
15770
|
continue;
|
|
15486
15771
|
}
|
|
15487
|
-
const callInfo = findAssistantToolCall(
|
|
15772
|
+
const callInfo = findAssistantToolCall(messages, part.toolCallId);
|
|
15488
15773
|
if (callInfo) {
|
|
15489
15774
|
const filePath = extractFilePath(callInfo.input);
|
|
15490
15775
|
if (filePath) {
|
|
@@ -15494,8 +15779,8 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15494
15779
|
}
|
|
15495
15780
|
}
|
|
15496
15781
|
const protectedReadFilePaths = /* @__PURE__ */ new Set();
|
|
15497
|
-
for (let i = protectedStart; i <
|
|
15498
|
-
const msg =
|
|
15782
|
+
for (let i = protectedStart; i < messages.length; i++) {
|
|
15783
|
+
const msg = messages[i];
|
|
15499
15784
|
if (msg.role !== "tool") {
|
|
15500
15785
|
continue;
|
|
15501
15786
|
}
|
|
@@ -15507,7 +15792,7 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15507
15792
|
if (!isPowerTool(serverName) || toolName !== POWER_TOOL_FILE_READ) {
|
|
15508
15793
|
continue;
|
|
15509
15794
|
}
|
|
15510
|
-
const callInfo = findAssistantToolCall(
|
|
15795
|
+
const callInfo = findAssistantToolCall(messages, part.toolCallId);
|
|
15511
15796
|
if (callInfo) {
|
|
15512
15797
|
const filePath = extractFilePath(callInfo.input);
|
|
15513
15798
|
if (filePath) {
|
|
@@ -15518,10 +15803,10 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15518
15803
|
}
|
|
15519
15804
|
const readFileGroups = /* @__PURE__ */ new Map();
|
|
15520
15805
|
for (let i = protectedStart - 1; i >= 0; i--) {
|
|
15521
|
-
if (i >=
|
|
15806
|
+
if (i >= messages.length) {
|
|
15522
15807
|
continue;
|
|
15523
15808
|
}
|
|
15524
|
-
const msg =
|
|
15809
|
+
const msg = messages[i];
|
|
15525
15810
|
if (msg.role !== "tool") {
|
|
15526
15811
|
continue;
|
|
15527
15812
|
}
|
|
@@ -15533,7 +15818,7 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15533
15818
|
if (!isPowerTool(serverName) || toolName !== POWER_TOOL_FILE_READ) {
|
|
15534
15819
|
continue;
|
|
15535
15820
|
}
|
|
15536
|
-
const callInfo = findAssistantToolCall(
|
|
15821
|
+
const callInfo = findAssistantToolCall(messages, part.toolCallId);
|
|
15537
15822
|
if (!callInfo) {
|
|
15538
15823
|
continue;
|
|
15539
15824
|
}
|
|
@@ -15542,8 +15827,8 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15542
15827
|
continue;
|
|
15543
15828
|
}
|
|
15544
15829
|
if (editedFilePaths.has(filePath) || protectedReadFilePaths.has(filePath)) {
|
|
15545
|
-
removeToolCallFromAssistant(
|
|
15546
|
-
removeToolResult(
|
|
15830
|
+
removeToolCallFromAssistant(messages, part.toolCallId);
|
|
15831
|
+
removeToolResult(messages, part.toolCallId);
|
|
15547
15832
|
continue;
|
|
15548
15833
|
}
|
|
15549
15834
|
if (!readFileGroups.has(filePath)) {
|
|
@@ -15561,18 +15846,58 @@ const removeStaleFileReads = (messages, protectedMessageCount = 10) => {
|
|
|
15561
15846
|
}
|
|
15562
15847
|
const toRemove = reads.slice(0, -1);
|
|
15563
15848
|
for (const read of toRemove) {
|
|
15564
|
-
removeToolCallFromAssistant(
|
|
15565
|
-
removeToolResult(
|
|
15849
|
+
removeToolCallFromAssistant(messages, read.toolCallId);
|
|
15850
|
+
removeToolResult(messages, read.toolCallId);
|
|
15566
15851
|
}
|
|
15567
15852
|
}
|
|
15568
|
-
return
|
|
15853
|
+
return messages;
|
|
15854
|
+
};
|
|
15855
|
+
const compactFileReads = (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
15856
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15857
|
+
const maxLines = compactionLevel === 3 ? 0 : compactionLevel === 2 ? 20 : 50;
|
|
15858
|
+
for (let i = 0; i < protectedStart; i++) {
|
|
15859
|
+
if (i >= messages.length) {
|
|
15860
|
+
break;
|
|
15861
|
+
}
|
|
15862
|
+
const msg = messages[i];
|
|
15863
|
+
if (msg.role !== "tool") {
|
|
15864
|
+
continue;
|
|
15865
|
+
}
|
|
15866
|
+
for (let j = 0; j < msg.content.length; j++) {
|
|
15867
|
+
const part = msg.content[j];
|
|
15868
|
+
if (part.type !== "tool-result") {
|
|
15869
|
+
continue;
|
|
15870
|
+
}
|
|
15871
|
+
const [serverName, toolName] = extractServerNameToolName(part.toolName);
|
|
15872
|
+
if (!isPowerTool(serverName) || toolName !== POWER_TOOL_FILE_READ) {
|
|
15873
|
+
continue;
|
|
15874
|
+
}
|
|
15875
|
+
if (part.output.type !== "text") {
|
|
15876
|
+
continue;
|
|
15877
|
+
}
|
|
15878
|
+
if (compactionLevel === 3) {
|
|
15879
|
+
part.output = {
|
|
15880
|
+
type: "text",
|
|
15881
|
+
value: "<result redacted due to compaction, read the file again if content is needed>"
|
|
15882
|
+
};
|
|
15883
|
+
continue;
|
|
15884
|
+
}
|
|
15885
|
+
const lines = part.output.value.split("\n");
|
|
15886
|
+
if (lines.length > maxLines) {
|
|
15887
|
+
part.output = {
|
|
15888
|
+
type: "text",
|
|
15889
|
+
value: lines.slice(0, maxLines).join("\n") + "\n<truncated due to compaction, read the file again if full content is needed>"
|
|
15890
|
+
};
|
|
15891
|
+
}
|
|
15892
|
+
}
|
|
15893
|
+
}
|
|
15894
|
+
return messages;
|
|
15569
15895
|
};
|
|
15570
|
-
const removeObsoleteSearches = (messages, protectedMessageCount = 10) => {
|
|
15571
|
-
const
|
|
15572
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
15896
|
+
const removeObsoleteSearches = (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
15897
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15573
15898
|
const fileModificationPositions = [];
|
|
15574
|
-
for (let i = 0; i <
|
|
15575
|
-
const msg =
|
|
15899
|
+
for (let i = 0; i < messages.length; i++) {
|
|
15900
|
+
const msg = messages[i];
|
|
15576
15901
|
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
15577
15902
|
for (const part of msg.content) {
|
|
15578
15903
|
if (part.type === "text" && part.text.includes("<file-edited")) {
|
|
@@ -15599,14 +15924,14 @@ const removeObsoleteSearches = (messages, protectedMessageCount = 10) => {
|
|
|
15599
15924
|
}
|
|
15600
15925
|
}
|
|
15601
15926
|
const hasFileModifications = fileModificationPositions.length > 0;
|
|
15602
|
-
if (!hasFileModifications) {
|
|
15603
|
-
return
|
|
15927
|
+
if (!hasFileModifications && compactionLevel < 3) {
|
|
15928
|
+
return messages;
|
|
15604
15929
|
}
|
|
15605
15930
|
for (let i = protectedStart - 1; i >= 0; i--) {
|
|
15606
|
-
if (i >=
|
|
15931
|
+
if (i >= messages.length) {
|
|
15607
15932
|
continue;
|
|
15608
15933
|
}
|
|
15609
|
-
const msg =
|
|
15934
|
+
const msg = messages[i];
|
|
15610
15935
|
if (msg.role !== "tool") {
|
|
15611
15936
|
continue;
|
|
15612
15937
|
}
|
|
@@ -15621,24 +15946,23 @@ const removeObsoleteSearches = (messages, protectedMessageCount = 10) => {
|
|
|
15621
15946
|
if (toolName !== POWER_TOOL_GLOB && toolName !== POWER_TOOL_GREP) {
|
|
15622
15947
|
continue;
|
|
15623
15948
|
}
|
|
15624
|
-
const
|
|
15625
|
-
if (
|
|
15626
|
-
removeToolCallFromAssistant(
|
|
15627
|
-
removeToolResult(
|
|
15949
|
+
const shouldRemove = compactionLevel >= 3 || fileModificationPositions.some((pos) => pos > i);
|
|
15950
|
+
if (shouldRemove) {
|
|
15951
|
+
removeToolCallFromAssistant(messages, part.toolCallId);
|
|
15952
|
+
removeToolResult(messages, part.toolCallId);
|
|
15628
15953
|
}
|
|
15629
15954
|
}
|
|
15630
15955
|
}
|
|
15631
|
-
return
|
|
15956
|
+
return messages;
|
|
15632
15957
|
};
|
|
15633
|
-
const compactSemanticSearches = (messages, protectedMessageCount = 10) => {
|
|
15634
|
-
const
|
|
15635
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
15958
|
+
const compactSemanticSearches = (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
15959
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15636
15960
|
const searchIndices = [];
|
|
15637
15961
|
for (let i = 0; i < protectedStart; i++) {
|
|
15638
|
-
if (i >=
|
|
15962
|
+
if (i >= messages.length) {
|
|
15639
15963
|
break;
|
|
15640
15964
|
}
|
|
15641
|
-
const msg =
|
|
15965
|
+
const msg = messages[i];
|
|
15642
15966
|
if (msg.role !== "tool") {
|
|
15643
15967
|
continue;
|
|
15644
15968
|
}
|
|
@@ -15654,38 +15978,45 @@ const compactSemanticSearches = (messages, protectedMessageCount = 10) => {
|
|
|
15654
15978
|
searchIndices.push({ messageIndex: i, partIndex: j, toolCallId: part.toolCallId });
|
|
15655
15979
|
}
|
|
15656
15980
|
}
|
|
15657
|
-
if (searchIndices.length <= 1) {
|
|
15658
|
-
return
|
|
15981
|
+
if (searchIndices.length <= 1 && compactionLevel < 3) {
|
|
15982
|
+
return messages;
|
|
15983
|
+
}
|
|
15984
|
+
if (compactionLevel >= 3) {
|
|
15985
|
+
for (const search2 of searchIndices) {
|
|
15986
|
+
removeToolCallFromAssistant(messages, search2.toolCallId);
|
|
15987
|
+
removeToolResult(messages, search2.toolCallId);
|
|
15988
|
+
}
|
|
15989
|
+
return messages;
|
|
15659
15990
|
}
|
|
15660
15991
|
const toRemove = searchIndices.slice(0, -1);
|
|
15661
15992
|
const toKeep = searchIndices[searchIndices.length - 1];
|
|
15662
15993
|
for (const search2 of toRemove) {
|
|
15663
|
-
removeToolCallFromAssistant(
|
|
15664
|
-
removeToolResult(
|
|
15994
|
+
removeToolCallFromAssistant(messages, search2.toolCallId);
|
|
15995
|
+
removeToolResult(messages, search2.toolCallId);
|
|
15665
15996
|
}
|
|
15666
|
-
const
|
|
15997
|
+
const maxLines = compactionLevel === 2 ? 20 : 50;
|
|
15998
|
+
const keptToolIdx = messages.findIndex((m) => m.role === "tool" && m.content.some((p) => p.type === "tool-result" && p.toolCallId === toKeep.toolCallId));
|
|
15667
15999
|
if (keptToolIdx !== -1) {
|
|
15668
|
-
const keptMsg =
|
|
16000
|
+
const keptMsg = messages[keptToolIdx];
|
|
15669
16001
|
const keptPartIdx = keptMsg.content.findIndex((p) => p.type === "tool-result" && p.toolCallId === toKeep.toolCallId);
|
|
15670
16002
|
const keptPart = keptMsg.content[keptPartIdx];
|
|
15671
16003
|
if (keptPart && keptPart.output.type === "text") {
|
|
15672
16004
|
const lines = keptPart.output.value.split("\n");
|
|
15673
|
-
if (lines.length >
|
|
16005
|
+
if (lines.length > maxLines) {
|
|
15674
16006
|
keptPart.output = {
|
|
15675
16007
|
type: "text",
|
|
15676
|
-
value: lines.slice(0,
|
|
16008
|
+
value: lines.slice(0, maxLines).join("\n") + "\n<truncated due to compaction, run again if full output is needed>"
|
|
15677
16009
|
};
|
|
15678
16010
|
}
|
|
15679
16011
|
}
|
|
15680
16012
|
}
|
|
15681
|
-
return
|
|
16013
|
+
return messages;
|
|
15682
16014
|
};
|
|
15683
|
-
const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
15684
|
-
const
|
|
15685
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
16015
|
+
const deduplicateBash = (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
16016
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15686
16017
|
const bashCommands = /* @__PURE__ */ new Map();
|
|
15687
16018
|
for (let i = 0; i < protectedStart; i++) {
|
|
15688
|
-
const msg =
|
|
16019
|
+
const msg = messages[i];
|
|
15689
16020
|
if (msg.role !== "tool") {
|
|
15690
16021
|
continue;
|
|
15691
16022
|
}
|
|
@@ -15697,7 +16028,7 @@ const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
|
15697
16028
|
if (!isPowerTool(serverName) || toolName !== POWER_TOOL_BASH) {
|
|
15698
16029
|
continue;
|
|
15699
16030
|
}
|
|
15700
|
-
const callInfo = findAssistantToolCall(
|
|
16031
|
+
const callInfo = findAssistantToolCall(messages, part.toolCallId);
|
|
15701
16032
|
if (!callInfo) {
|
|
15702
16033
|
continue;
|
|
15703
16034
|
}
|
|
@@ -15720,15 +16051,15 @@ const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
|
15720
16051
|
}
|
|
15721
16052
|
const toRemove = occurrences.slice(0, -1);
|
|
15722
16053
|
for (const occ of toRemove) {
|
|
15723
|
-
removeToolCallFromAssistant(
|
|
15724
|
-
removeToolResult(
|
|
16054
|
+
removeToolCallFromAssistant(messages, occ.toolCallId);
|
|
16055
|
+
removeToolResult(messages, occ.toolCallId);
|
|
15725
16056
|
}
|
|
15726
16057
|
}
|
|
15727
16058
|
for (let i = 0; i < protectedStart; i++) {
|
|
15728
|
-
if (i >=
|
|
16059
|
+
if (i >= messages.length) {
|
|
15729
16060
|
break;
|
|
15730
16061
|
}
|
|
15731
|
-
const msg =
|
|
16062
|
+
const msg = messages[i];
|
|
15732
16063
|
if (msg.role !== "tool") {
|
|
15733
16064
|
continue;
|
|
15734
16065
|
}
|
|
@@ -15741,6 +16072,13 @@ const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
|
15741
16072
|
if (!isPowerTool(serverName) || toolName !== POWER_TOOL_BASH) {
|
|
15742
16073
|
continue;
|
|
15743
16074
|
}
|
|
16075
|
+
if (compactionLevel >= 3) {
|
|
16076
|
+
part.output = {
|
|
16077
|
+
type: "text",
|
|
16078
|
+
value: "<result redacted due to compaction, run again if needed>"
|
|
16079
|
+
};
|
|
16080
|
+
continue;
|
|
16081
|
+
}
|
|
15744
16082
|
if (part.output.type !== "text") {
|
|
15745
16083
|
continue;
|
|
15746
16084
|
}
|
|
@@ -15751,11 +16089,12 @@ const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
|
15751
16089
|
const stderr = typeof parsed.stderr === "string" ? parsed.stderr : "";
|
|
15752
16090
|
const redactionMessage = "<output redacted due to compaction, run again if output is needed>";
|
|
15753
16091
|
let modified = false;
|
|
15754
|
-
|
|
16092
|
+
const redactionThreshold = compactionLevel >= 2 ? 0 : 30;
|
|
16093
|
+
if (stdout.length > redactionThreshold) {
|
|
15755
16094
|
parsed.stdout = redactionMessage;
|
|
15756
16095
|
modified = true;
|
|
15757
16096
|
}
|
|
15758
|
-
if (stderr.length >
|
|
16097
|
+
if (stderr.length > redactionThreshold) {
|
|
15759
16098
|
parsed.stderr = redactionMessage;
|
|
15760
16099
|
modified = true;
|
|
15761
16100
|
}
|
|
@@ -15770,13 +16109,12 @@ const deduplicateBash = (messages, protectedMessageCount = 10) => {
|
|
|
15770
16109
|
}
|
|
15771
16110
|
}
|
|
15772
16111
|
}
|
|
15773
|
-
return
|
|
16112
|
+
return messages;
|
|
15774
16113
|
};
|
|
15775
16114
|
const redactFetchOutputs = (messages, protectedMessageCount = 10) => {
|
|
15776
|
-
const
|
|
15777
|
-
const protectedStart = getProtectedStartIndex(result, protectedMessageCount);
|
|
16115
|
+
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
15778
16116
|
for (let i = 0; i < protectedStart; i++) {
|
|
15779
|
-
const msg =
|
|
16117
|
+
const msg = messages[i];
|
|
15780
16118
|
if (msg.role !== "tool") {
|
|
15781
16119
|
continue;
|
|
15782
16120
|
}
|
|
@@ -15798,7 +16136,7 @@ const redactFetchOutputs = (messages, protectedMessageCount = 10) => {
|
|
|
15798
16136
|
}
|
|
15799
16137
|
}
|
|
15800
16138
|
}
|
|
15801
|
-
return
|
|
16139
|
+
return messages;
|
|
15802
16140
|
};
|
|
15803
16141
|
const INTERNAL_TASK_ID = "internal";
|
|
15804
16142
|
const RESPONSE_CHUNK_FLUSH_INTERVAL_MS = 10;
|
|
@@ -15886,6 +16224,8 @@ class Task {
|
|
|
15886
16224
|
tokensInfo;
|
|
15887
16225
|
queuedPrompts = [];
|
|
15888
16226
|
isCompacting = false;
|
|
16227
|
+
lastSmartCompactionMessageCount = 0;
|
|
16228
|
+
smartCompactionLevel = CompactionLevel.One;
|
|
15889
16229
|
taskDataPath;
|
|
15890
16230
|
contextManager;
|
|
15891
16231
|
agent;
|
|
@@ -16375,7 +16715,8 @@ class Task {
|
|
|
16375
16715
|
id: promptContext.id,
|
|
16376
16716
|
role: MessageRole.User,
|
|
16377
16717
|
content: prompt,
|
|
16378
|
-
promptContext
|
|
16718
|
+
promptContext,
|
|
16719
|
+
timestamp: Date.now()
|
|
16379
16720
|
});
|
|
16380
16721
|
this.addUserMessage(promptContext.id, prompt);
|
|
16381
16722
|
await this.saveTask({
|
|
@@ -16408,7 +16749,8 @@ class Task {
|
|
|
16408
16749
|
id: promptContext.id,
|
|
16409
16750
|
role: MessageRole.User,
|
|
16410
16751
|
content: prompt,
|
|
16411
|
-
promptContext
|
|
16752
|
+
promptContext,
|
|
16753
|
+
timestamp: Date.now()
|
|
16412
16754
|
});
|
|
16413
16755
|
let messages = this.contextManager.toConnectorMessages();
|
|
16414
16756
|
let files = this.contextManager.getContextFiles();
|
|
@@ -16427,8 +16769,9 @@ class Task {
|
|
|
16427
16769
|
promptContext = extensionResult.promptContext;
|
|
16428
16770
|
messages = extensionResult.messages;
|
|
16429
16771
|
files = extensionResult.files;
|
|
16772
|
+
const effectiveAutonomyMode = extensionResult.autonomyMode ?? this.task.autonomyMode ?? DEFAULT_AUTONOMY_MODE;
|
|
16430
16773
|
let responses = await this.sendPromptToAider(prompt, promptContext, mode, messages, files, {
|
|
16431
|
-
autoApprove:
|
|
16774
|
+
autoApprove: effectiveAutonomyMode === AutonomyMode.Autonomous,
|
|
16432
16775
|
denyCommands: extensionResult.denyCommands
|
|
16433
16776
|
});
|
|
16434
16777
|
logger.debug("Responses:", { responses });
|
|
@@ -16813,7 +17156,8 @@ ${contentText}</agent-response>`;
|
|
|
16813
17156
|
diff: message.diff,
|
|
16814
17157
|
usageReport,
|
|
16815
17158
|
sequenceNumber: message.sequenceNumber,
|
|
16816
|
-
promptContext: message.promptContext
|
|
17159
|
+
promptContext: message.promptContext,
|
|
17160
|
+
timestamp: Date.now()
|
|
16817
17161
|
};
|
|
16818
17162
|
const extensionResult = await this.extensionManager.dispatchEvent("onResponseCompleted", { response: data }, this.project, this);
|
|
16819
17163
|
data = extensionResult.response;
|
|
@@ -16880,14 +17224,20 @@ ${contentText}</agent-response>`;
|
|
|
16880
17224
|
if (!determinedAnswer) {
|
|
16881
17225
|
determinedAnswer = normalizedAnswer === "a" || normalizedAnswer === "y" ? "y" : "n";
|
|
16882
17226
|
}
|
|
16883
|
-
if (
|
|
16884
|
-
logger.debug('Storing answer for question due to "
|
|
17227
|
+
if (normalizedAnswer === "a") {
|
|
17228
|
+
logger.debug('Storing answer for question due to "a" (Always) input:', {
|
|
17229
|
+
baseDir: this.project.baseDir,
|
|
17230
|
+
questionKey: this.getQuestionKey(this.currentQuestion),
|
|
17231
|
+
rawInput: answer
|
|
17232
|
+
});
|
|
17233
|
+
this.storedQuestionAnswers.set(this.getQuestionKey(this.currentQuestion), "y");
|
|
17234
|
+
} else if (normalizedAnswer === "d") {
|
|
17235
|
+
logger.debug(`Storing answer for question due to "d" (Don't ask again) input:`, {
|
|
16885
17236
|
baseDir: this.project.baseDir,
|
|
16886
17237
|
questionKey: this.getQuestionKey(this.currentQuestion),
|
|
16887
|
-
rawInput: answer
|
|
16888
|
-
determinedAndStoredAnswer: determinedAnswer
|
|
17238
|
+
rawInput: answer
|
|
16889
17239
|
});
|
|
16890
|
-
this.storedQuestionAnswers.set(this.getQuestionKey(this.currentQuestion),
|
|
17240
|
+
this.storedQuestionAnswers.set(this.getQuestionKey(this.currentQuestion), "n");
|
|
16891
17241
|
}
|
|
16892
17242
|
const questionToAnswer = this.currentQuestion;
|
|
16893
17243
|
if (!this.currentQuestion.internal) {
|
|
@@ -17050,11 +17400,21 @@ ${contentText}</agent-response>`;
|
|
|
17050
17400
|
void this.updateContextInfo(true, true);
|
|
17051
17401
|
}
|
|
17052
17402
|
async askQuestion(questionData, awaitAnswer = true) {
|
|
17053
|
-
|
|
17403
|
+
let storedAnswer = this.storedQuestionAnswers.get(this.getQuestionKey(questionData));
|
|
17404
|
+
const extensionResult = await this.extensionManager.dispatchEvent(
|
|
17405
|
+
"onQuestionAsked",
|
|
17406
|
+
{
|
|
17407
|
+
question: questionData,
|
|
17408
|
+
storedAnswer
|
|
17409
|
+
},
|
|
17410
|
+
this.project,
|
|
17411
|
+
this
|
|
17412
|
+
);
|
|
17054
17413
|
if (extensionResult.answer) {
|
|
17055
17414
|
logger.info("Question answered by extension", {
|
|
17056
17415
|
question: questionData.text,
|
|
17057
|
-
answer: extensionResult.answer
|
|
17416
|
+
answer: extensionResult.answer,
|
|
17417
|
+
storedAnswer
|
|
17058
17418
|
});
|
|
17059
17419
|
return [extensionResult.answer, void 0];
|
|
17060
17420
|
}
|
|
@@ -17064,7 +17424,7 @@ ${contentText}</agent-response>`;
|
|
|
17064
17424
|
this.currentQuestionResolves.push(resolve);
|
|
17065
17425
|
});
|
|
17066
17426
|
}
|
|
17067
|
-
|
|
17427
|
+
storedAnswer = this.storedQuestionAnswers.get(this.getQuestionKey(questionData));
|
|
17068
17428
|
if (questionData.isGroupQuestion && !questionData.answers) {
|
|
17069
17429
|
questionData.answers = [
|
|
17070
17430
|
{ text: "(Y)es", shortkey: "y" },
|
|
@@ -17405,7 +17765,8 @@ ${contentText}</agent-response>`;
|
|
|
17405
17765
|
message,
|
|
17406
17766
|
finished,
|
|
17407
17767
|
promptContext,
|
|
17408
|
-
actionIds
|
|
17768
|
+
actionIds,
|
|
17769
|
+
timestamp: Date.now()
|
|
17409
17770
|
};
|
|
17410
17771
|
this.eventManager.sendLog(data);
|
|
17411
17772
|
}
|
|
@@ -17556,6 +17917,7 @@ ${contentText}</agent-response>`;
|
|
|
17556
17917
|
lastAgentProviderMetadata: null
|
|
17557
17918
|
});
|
|
17558
17919
|
}
|
|
17920
|
+
this.smartCompactionLevel = CompactionLevel.One;
|
|
17559
17921
|
this.contextManager.clearMessages(true, createSnapshot);
|
|
17560
17922
|
await this.runCommand("clear", addToHistory);
|
|
17561
17923
|
this.eventManager.sendClearTask(this.project.baseDir, this.taskId, true, false);
|
|
@@ -17757,7 +18119,8 @@ ${contentText}</agent-response>`;
|
|
|
17757
18119
|
response,
|
|
17758
18120
|
usageReport,
|
|
17759
18121
|
promptContext,
|
|
17760
|
-
finished
|
|
18122
|
+
finished,
|
|
18123
|
+
timestamp: Date.now()
|
|
17761
18124
|
};
|
|
17762
18125
|
if (response && usageReport && saveToDb) {
|
|
17763
18126
|
this.dataManager.saveMessage(id, "tool", this.project.baseDir, usageReport.model, usageReport, {
|
|
@@ -17798,7 +18161,8 @@ ${contentText}</agent-response>`;
|
|
|
17798
18161
|
taskId: this.taskId,
|
|
17799
18162
|
content,
|
|
17800
18163
|
images,
|
|
17801
|
-
promptContext
|
|
18164
|
+
promptContext,
|
|
18165
|
+
timestamp: Date.now()
|
|
17802
18166
|
};
|
|
17803
18167
|
this.eventManager.sendUserMessage(data);
|
|
17804
18168
|
}
|
|
@@ -17841,7 +18205,9 @@ ${contentText}</agent-response>`;
|
|
|
17841
18205
|
const removedMessages = this.contextManager.removeMessagesUpToUserMessage(messageId);
|
|
17842
18206
|
const originalUserMessage = removedMessages[0];
|
|
17843
18207
|
if (!originalUserMessage || originalUserMessage.role !== MessageRole.User) {
|
|
17844
|
-
logger.warn("Could not find the specified user message to redo.", {
|
|
18208
|
+
logger.warn("Could not find the specified user message to redo.", {
|
|
18209
|
+
messageId
|
|
18210
|
+
});
|
|
17845
18211
|
return;
|
|
17846
18212
|
}
|
|
17847
18213
|
const originalText = extractTextContent(originalUserMessage.content);
|
|
@@ -17958,7 +18324,14 @@ ${contentText}</agent-response>`;
|
|
|
17958
18324
|
return [];
|
|
17959
18325
|
}
|
|
17960
18326
|
await this.contextManager.backupContext();
|
|
17961
|
-
const
|
|
18327
|
+
const messagesSinceLastCompaction = contextMessages.length - this.lastSmartCompactionMessageCount;
|
|
18328
|
+
if (messagesSinceLastCompaction <= 3) {
|
|
18329
|
+
this.smartCompactionLevel = Math.min(this.smartCompactionLevel + 1, CompactionLevel.Three);
|
|
18330
|
+
} else if (messagesSinceLastCompaction > 5) {
|
|
18331
|
+
this.smartCompactionLevel = CompactionLevel.One;
|
|
18332
|
+
}
|
|
18333
|
+
const compactedMessages = await smartCompactMessages(contextMessages, 10, this.smartCompactionLevel);
|
|
18334
|
+
this.lastSmartCompactionMessageCount = compactedMessages.length;
|
|
17962
18335
|
this.contextManager.setContextMessages(compactedMessages);
|
|
17963
18336
|
await this.contextManager.loadMessages(compactedMessages, false);
|
|
17964
18337
|
await this.updateContextInfo();
|
|
@@ -18121,7 +18494,7 @@ ${contentText}</agent-response>`;
|
|
|
18121
18494
|
const newTaskData = await this.project.createNewTask({
|
|
18122
18495
|
parentId: this.task.parentId || this.taskId,
|
|
18123
18496
|
sendEvent: false,
|
|
18124
|
-
|
|
18497
|
+
autonomyMode: execute ? this.task.autonomyMode : void 0,
|
|
18125
18498
|
activate: true
|
|
18126
18499
|
});
|
|
18127
18500
|
const newTask = this.project.getTask(newTaskData.id);
|
|
@@ -18441,7 +18814,12 @@ ${error.stderr}`,
|
|
|
18441
18814
|
}
|
|
18442
18815
|
}
|
|
18443
18816
|
}
|
|
18444
|
-
const systemPrompt = await this.promptsManager.getSystemPrompt(
|
|
18817
|
+
const systemPrompt = await this.promptsManager.getSystemPrompt(
|
|
18818
|
+
this.store.getSettings(),
|
|
18819
|
+
this,
|
|
18820
|
+
profile,
|
|
18821
|
+
command.autonomyMode ?? this.task.autonomyMode ?? DEFAULT_AUTONOMY_MODE
|
|
18822
|
+
);
|
|
18445
18823
|
const messages = command.includeContext === false ? [] : void 0;
|
|
18446
18824
|
const contextFiles = command.includeContext === false ? [] : void 0;
|
|
18447
18825
|
this.addLogMessage("loading", "Executing custom command...");
|
|
@@ -18876,7 +19254,13 @@ ${diff}
|
|
|
18876
19254
|
if (success) {
|
|
18877
19255
|
const newHead = await this.worktreeManager.getHeadCommit(this.task.worktree.path);
|
|
18878
19256
|
if (newHead) {
|
|
18879
|
-
await this.saveTask({
|
|
19257
|
+
await this.saveTask({
|
|
19258
|
+
worktree: {
|
|
19259
|
+
...this.task.worktree,
|
|
19260
|
+
baseCommit: newHead,
|
|
19261
|
+
baseBranch: effectiveFromBranch
|
|
19262
|
+
}
|
|
19263
|
+
});
|
|
18880
19264
|
}
|
|
18881
19265
|
this.addLogMessage("info", "Worktree rebased successfully", true);
|
|
18882
19266
|
return;
|
|
@@ -19192,7 +19576,7 @@ ${diff}
|
|
|
19192
19576
|
const newTaskData = await this.project.createNewTask({
|
|
19193
19577
|
name: taskName,
|
|
19194
19578
|
sendEvent: false,
|
|
19195
|
-
|
|
19579
|
+
autonomyMode: AutonomyMode.Autonomous,
|
|
19196
19580
|
activate: true,
|
|
19197
19581
|
mode,
|
|
19198
19582
|
parentId: this.task.parentId || this.taskId,
|
|
@@ -19332,7 +19716,7 @@ class Project {
|
|
|
19332
19716
|
this.promptsManager = promptsManager;
|
|
19333
19717
|
this.extensionManager = extensionManager;
|
|
19334
19718
|
this.pythonInstaller = pythonInstaller;
|
|
19335
|
-
this.customCommandManager = new CustomCommandManager(this, this.eventManager, this.extensionManager);
|
|
19719
|
+
this.customCommandManager = new CustomCommandManager(this, this.eventManager, this.extensionManager, this.store);
|
|
19336
19720
|
this.tasksLoadingPromise = this.loadTasks();
|
|
19337
19721
|
}
|
|
19338
19722
|
customCommandManager;
|
|
@@ -19408,9 +19792,7 @@ class Project {
|
|
|
19408
19792
|
...normalizedParams
|
|
19409
19793
|
};
|
|
19410
19794
|
}
|
|
19411
|
-
const projectSettings = this.getProjectSettings();
|
|
19412
19795
|
const taskData = {
|
|
19413
|
-
autoApprove: projectSettings.autoApproveLocked ? true : initialTaskData.autoApprove,
|
|
19414
19796
|
...initialTaskData
|
|
19415
19797
|
};
|
|
19416
19798
|
const extResult = await this.extensionManager.dispatchEvent("onTaskCreated", { task: taskData }, this);
|
|
@@ -19712,6 +20094,7 @@ class Project {
|
|
|
19712
20094
|
this.forEachTask((task) => {
|
|
19713
20095
|
void task.settingsChanged(oldSettings, newSettings);
|
|
19714
20096
|
});
|
|
20097
|
+
void this.customCommandManager.settingsChanged(oldSettings, newSettings);
|
|
19715
20098
|
}
|
|
19716
20099
|
async projectSettingsChanged(oldSettings, newSettings) {
|
|
19717
20100
|
this.forEachTask((task) => {
|
|
@@ -19961,7 +20344,8 @@ class EventManager {
|
|
|
19961
20344
|
baseDir,
|
|
19962
20345
|
taskId,
|
|
19963
20346
|
command,
|
|
19964
|
-
output
|
|
20347
|
+
output,
|
|
20348
|
+
timestamp: Date.now()
|
|
19965
20349
|
};
|
|
19966
20350
|
this.sendToWindows("command-output", data);
|
|
19967
20351
|
this.broadcastToEventConnectors("command-output", data);
|
|
@@ -22570,6 +22954,117 @@ const mistralProviderStrategy = {
|
|
|
22570
22954
|
getAiderMapping: getMistralAiderMapping,
|
|
22571
22955
|
getModelInfo: getDefaultModelInfo
|
|
22572
22956
|
};
|
|
22957
|
+
const NEURALWATT_BASE_URL = "https://api.neuralwatt.com/v1";
|
|
22958
|
+
const loadNeuralwattModels = async (profile, settings) => {
|
|
22959
|
+
if (!isNeuralwattProvider(profile.provider)) {
|
|
22960
|
+
return { models: [], success: false };
|
|
22961
|
+
}
|
|
22962
|
+
const provider = profile.provider;
|
|
22963
|
+
const apiKey = provider.apiKey || "";
|
|
22964
|
+
const apiKeyEnv = getEffectiveEnvironmentVariable("NEURALWATT_API_KEY", settings);
|
|
22965
|
+
const effectiveApiKey = apiKey || apiKeyEnv?.value || "";
|
|
22966
|
+
if (!effectiveApiKey) {
|
|
22967
|
+
logger.debug("Neuralwatt API key is required. Please set it in Providers settings or via NEURALWATT_API_KEY environment variable.");
|
|
22968
|
+
return { models: [], success: false };
|
|
22969
|
+
}
|
|
22970
|
+
try {
|
|
22971
|
+
const response = await fetch(`${NEURALWATT_BASE_URL}/models`, {
|
|
22972
|
+
headers: { Authorization: `Bearer ${effectiveApiKey}` }
|
|
22973
|
+
});
|
|
22974
|
+
if (!response.ok) {
|
|
22975
|
+
const errorMsg = `Neuralwatt models API response failed: ${response.status} ${response.statusText} ${await response.text()}`;
|
|
22976
|
+
logger.error(errorMsg, { status: response.status, statusText: response.statusText });
|
|
22977
|
+
return { models: [], success: false, error: errorMsg };
|
|
22978
|
+
}
|
|
22979
|
+
const data = await response.json();
|
|
22980
|
+
logger.debug(`Received response from Neuralwatt models API for profile ${profile.id}`, { data });
|
|
22981
|
+
const models = data.data?.map((model) => {
|
|
22982
|
+
const metadata = model.metadata;
|
|
22983
|
+
const pricing = metadata?.pricing;
|
|
22984
|
+
const limits = metadata?.limits;
|
|
22985
|
+
const capabilities = metadata?.capabilities;
|
|
22986
|
+
return {
|
|
22987
|
+
id: model.id,
|
|
22988
|
+
providerId: profile.id,
|
|
22989
|
+
maxInputTokens: limits?.max_context_length ?? model.max_model_len,
|
|
22990
|
+
maxOutputTokensLimit: limits?.max_output_tokens ?? void 0,
|
|
22991
|
+
inputCostPerToken: pricing ? pricing.input_per_million / 1e6 : void 0,
|
|
22992
|
+
outputCostPerToken: pricing ? pricing.output_per_million / 1e6 : void 0,
|
|
22993
|
+
cacheReadInputTokenCost: pricing?.cached_input_per_million != null ? pricing.cached_input_per_million / 1e6 : void 0,
|
|
22994
|
+
supportsTools: capabilities?.tools
|
|
22995
|
+
};
|
|
22996
|
+
}) || [];
|
|
22997
|
+
logger.info(`Loaded ${models.length} Neuralwatt models for profile ${profile.id}`);
|
|
22998
|
+
return { models, success: true };
|
|
22999
|
+
} catch (error) {
|
|
23000
|
+
const errorMsg = typeof error === "string" ? error : error instanceof Error ? error.message : "Unknown error loading Neuralwatt models";
|
|
23001
|
+
logger.error("Error loading Neuralwatt models:", error);
|
|
23002
|
+
return { models: [], success: false, error: errorMsg };
|
|
23003
|
+
}
|
|
23004
|
+
};
|
|
23005
|
+
const hasNeuralwattEnvVars = (settings) => {
|
|
23006
|
+
return !!getEffectiveEnvironmentVariable("NEURALWATT_API_KEY", settings, void 0)?.value;
|
|
23007
|
+
};
|
|
23008
|
+
const getNeuralwattAiderMapping = (provider, modelId) => {
|
|
23009
|
+
const neuralwattProvider = provider.provider;
|
|
23010
|
+
const envVars = {};
|
|
23011
|
+
if (neuralwattProvider.apiKey) {
|
|
23012
|
+
envVars.OPENAI_API_KEY = neuralwattProvider.apiKey;
|
|
23013
|
+
}
|
|
23014
|
+
envVars.OPENAI_API_BASE = NEURALWATT_BASE_URL;
|
|
23015
|
+
return {
|
|
23016
|
+
modelName: `openai/${modelId}`,
|
|
23017
|
+
environmentVariables: envVars
|
|
23018
|
+
};
|
|
23019
|
+
};
|
|
23020
|
+
const createNeuralwattLlm = (profile, model, settings, projectDir) => {
|
|
23021
|
+
const provider = profile.provider;
|
|
23022
|
+
let apiKey = provider.apiKey;
|
|
23023
|
+
if (!apiKey) {
|
|
23024
|
+
const effectiveVar = getEffectiveEnvironmentVariable("NEURALWATT_API_KEY", settings, projectDir);
|
|
23025
|
+
if (effectiveVar) {
|
|
23026
|
+
apiKey = effectiveVar.value;
|
|
23027
|
+
logger.debug(`Loaded NEURALWATT_API_KEY from ${effectiveVar.source}`);
|
|
23028
|
+
}
|
|
23029
|
+
}
|
|
23030
|
+
if (!apiKey) {
|
|
23031
|
+
throw new Error("Neuralwatt API key is required in Providers settings or Aider environment variables (NEURALWATT_API_KEY)");
|
|
23032
|
+
}
|
|
23033
|
+
const compatibleProvider = openaiCompatible.createOpenAICompatible({
|
|
23034
|
+
name: "neuralwatt",
|
|
23035
|
+
apiKey,
|
|
23036
|
+
baseURL: NEURALWATT_BASE_URL,
|
|
23037
|
+
headers: profile.headers
|
|
23038
|
+
});
|
|
23039
|
+
return compatibleProvider(model.id);
|
|
23040
|
+
};
|
|
23041
|
+
const getNeuralwattUsageReport = (task, provider, model, usage, providerMetadata) => {
|
|
23042
|
+
const totalSentTokens = usage.inputTokens || 0;
|
|
23043
|
+
const receivedTokens = usage.outputTokens || 0;
|
|
23044
|
+
const cacheReadTokens = usage.cachedInputTokens || 0;
|
|
23045
|
+
const sentTokens = totalSentTokens - cacheReadTokens;
|
|
23046
|
+
logger.info("Neuralwatt usage report", {
|
|
23047
|
+
providerMetadata,
|
|
23048
|
+
usage
|
|
23049
|
+
});
|
|
23050
|
+
const messageCost = calculateCost(model, sentTokens, receivedTokens, cacheReadTokens);
|
|
23051
|
+
return {
|
|
23052
|
+
model: `${provider.id}/${model.id}`,
|
|
23053
|
+
sentTokens,
|
|
23054
|
+
receivedTokens,
|
|
23055
|
+
cacheReadTokens,
|
|
23056
|
+
messageCost,
|
|
23057
|
+
agentTotalCost: task.task.agentTotalCost + messageCost
|
|
23058
|
+
};
|
|
23059
|
+
};
|
|
23060
|
+
const neuralwattProviderStrategy = {
|
|
23061
|
+
createLlm: createNeuralwattLlm,
|
|
23062
|
+
getUsageReport: getNeuralwattUsageReport,
|
|
23063
|
+
loadModels: loadNeuralwattModels,
|
|
23064
|
+
hasEnvVars: hasNeuralwattEnvVars,
|
|
23065
|
+
getAiderMapping: getNeuralwattAiderMapping,
|
|
23066
|
+
getModelInfo: getDefaultModelInfo
|
|
23067
|
+
};
|
|
22573
23068
|
const loadOllamaModels = async (profile, settings) => {
|
|
22574
23069
|
if (!isOllamaProvider(profile.provider)) {
|
|
22575
23070
|
return { models: [], success: false };
|
|
@@ -23933,6 +24428,7 @@ class ModelManager {
|
|
|
23933
24428
|
lmstudio: lmStudioProviderStrategy,
|
|
23934
24429
|
minimax: minimaxProviderStrategy,
|
|
23935
24430
|
mistral: mistralProviderStrategy,
|
|
24431
|
+
neuralwatt: neuralwattProviderStrategy,
|
|
23936
24432
|
ollama: ollamaProviderStrategy,
|
|
23937
24433
|
openai: openaiProviderStrategy,
|
|
23938
24434
|
"openai-compatible": openaiCompatibleProviderStrategy,
|
|
@@ -25284,7 +25780,7 @@ class MemoryManager {
|
|
|
25284
25780
|
done: this.embeddingProgress.done,
|
|
25285
25781
|
total: this.embeddingProgress.total,
|
|
25286
25782
|
finished: true,
|
|
25287
|
-
error: "Failed to load @huggingface/transformers. This is usually a packaging issue with native dependencies
|
|
25783
|
+
error: "Failed to load @huggingface/transformers. This is usually a packaging issue with native dependencies."
|
|
25288
25784
|
};
|
|
25289
25785
|
logger.error("Failed to load transformers module. Memory embedding will be unavailable.", error);
|
|
25290
25786
|
return;
|
|
@@ -25456,7 +25952,7 @@ class MemoryManager {
|
|
|
25456
25952
|
done: this.embeddingProgress.done,
|
|
25457
25953
|
total: this.embeddingProgress.total,
|
|
25458
25954
|
finished: true,
|
|
25459
|
-
error: "Failed to load @huggingface/transformers. This is usually a packaging issue with native dependencies
|
|
25955
|
+
error: "Failed to load @huggingface/transformers. This is usually a packaging issue with native dependencies."
|
|
25460
25956
|
};
|
|
25461
25957
|
logger.error("Failed to load transformers module. Memory embedding will be unavailable.", error);
|
|
25462
25958
|
return;
|
|
@@ -26112,6 +26608,18 @@ class ExtensionContextImpl {
|
|
|
26112
26608
|
return [];
|
|
26113
26609
|
}
|
|
26114
26610
|
}
|
|
26611
|
+
getProviders() {
|
|
26612
|
+
if (!this.modelManager) {
|
|
26613
|
+
this.log("ModelManager not available, returning empty providers", "warn");
|
|
26614
|
+
return [];
|
|
26615
|
+
}
|
|
26616
|
+
try {
|
|
26617
|
+
return this.modelManager.getProviders();
|
|
26618
|
+
} catch (error) {
|
|
26619
|
+
this.log(`Failed to get providers: ${error}`, "error");
|
|
26620
|
+
return [];
|
|
26621
|
+
}
|
|
26622
|
+
}
|
|
26115
26623
|
async getSetting(key) {
|
|
26116
26624
|
if (!this.store) {
|
|
26117
26625
|
throw new Error("Store not available");
|
|
@@ -26202,8 +26710,11 @@ class ExtensionContextImpl {
|
|
|
26202
26710
|
}
|
|
26203
26711
|
return this.memoryManager;
|
|
26204
26712
|
}
|
|
26713
|
+
async truncateToolResult(content, maxLines, maxSizeKB, maxTokens, saveToFile, truncationSuffix) {
|
|
26714
|
+
return truncateToolResult(content, maxLines, maxSizeKB, maxTokens, saveToFile, truncationSuffix);
|
|
26715
|
+
}
|
|
26205
26716
|
}
|
|
26206
|
-
const CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26717
|
+
const CACHE_TTL_MS$1 = 24 * 60 * 60 * 1e3;
|
|
26207
26718
|
class ExtensionFetcher {
|
|
26208
26719
|
cache = /* @__PURE__ */ new Map();
|
|
26209
26720
|
getAvailableExtensionsPromise = null;
|
|
@@ -26234,7 +26745,7 @@ class ExtensionFetcher {
|
|
|
26234
26745
|
async fetchExtensionsFromRepo(repoUrl, forceRefresh) {
|
|
26235
26746
|
const cached = this.cache.get(repoUrl);
|
|
26236
26747
|
const now = Date.now();
|
|
26237
|
-
if (!forceRefresh && cached && now - cached.timestamp < CACHE_TTL_MS) {
|
|
26748
|
+
if (!forceRefresh && cached && now - cached.timestamp < CACHE_TTL_MS$1) {
|
|
26238
26749
|
logger.debug(`[ExtensionFetcher] Using cached extensions for ${repoUrl}`);
|
|
26239
26750
|
return cached.extensions;
|
|
26240
26751
|
}
|
|
@@ -26546,6 +27057,67 @@ class ExtensionFetcher {
|
|
|
26546
27057
|
return this.convertToGitHubRawUrl(webUrl);
|
|
26547
27058
|
}
|
|
26548
27059
|
}
|
|
27060
|
+
const ESM_SH_BASE_URL = "https://esm.sh";
|
|
27061
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27062
|
+
const sanitizeLibraryName = (name) => {
|
|
27063
|
+
return name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
27064
|
+
};
|
|
27065
|
+
class ExtensionLibraryLoader {
|
|
27066
|
+
cacheDir;
|
|
27067
|
+
constructor() {
|
|
27068
|
+
this.cacheDir = path.join(AIDER_DESK_CACHE_DIR, "extension-libraries");
|
|
27069
|
+
}
|
|
27070
|
+
getCachePath(librarySpec) {
|
|
27071
|
+
const sanitized = sanitizeLibraryName(librarySpec);
|
|
27072
|
+
return path.join(this.cacheDir, `${sanitized}.js`);
|
|
27073
|
+
}
|
|
27074
|
+
getMetaPath(librarySpec) {
|
|
27075
|
+
const sanitized = sanitizeLibraryName(librarySpec);
|
|
27076
|
+
return path.join(this.cacheDir, `${sanitized}.meta.json`);
|
|
27077
|
+
}
|
|
27078
|
+
async loadLibrary(librarySpec) {
|
|
27079
|
+
const cachePath = this.getCachePath(librarySpec);
|
|
27080
|
+
const metaPath = this.getMetaPath(librarySpec);
|
|
27081
|
+
try {
|
|
27082
|
+
await fs.access(cachePath);
|
|
27083
|
+
await fs.access(metaPath);
|
|
27084
|
+
try {
|
|
27085
|
+
const meta = JSON.parse(await fs.readFile(metaPath, "utf-8"));
|
|
27086
|
+
const age = Date.now() - new Date(meta.fetchedAt).getTime();
|
|
27087
|
+
if (age < CACHE_TTL_MS) {
|
|
27088
|
+
logger.debug(`[ExtensionLibraryLoader] Cache hit for ${librarySpec}`);
|
|
27089
|
+
return await fs.readFile(cachePath, "utf-8");
|
|
27090
|
+
}
|
|
27091
|
+
logger.info(`[ExtensionLibraryLoader] Cache stale for ${librarySpec} (age: ${Math.round(age / 1e3 / 60)}min), re-fetching`);
|
|
27092
|
+
} catch {
|
|
27093
|
+
logger.warn(`[ExtensionLibraryLoader] Failed to read meta for ${librarySpec}, re-fetching`);
|
|
27094
|
+
}
|
|
27095
|
+
} catch {
|
|
27096
|
+
}
|
|
27097
|
+
logger.info(`[ExtensionLibraryLoader] Fetching ${librarySpec} from esm.sh`);
|
|
27098
|
+
const url = `${ESM_SH_BASE_URL}/${librarySpec}?external=react,react-dom,react/jsx-runtime,react/jsx-dev-runtime&bundle-deps&bundle`;
|
|
27099
|
+
let response = await fetchWithTimeout(url);
|
|
27100
|
+
if (!response.ok) {
|
|
27101
|
+
throw new Error(`Failed to fetch library ${librarySpec} from esm.sh: ${response.status} ${response.statusText}`);
|
|
27102
|
+
}
|
|
27103
|
+
let source = await response.text();
|
|
27104
|
+
const redirectMatch = source.match(/export\s+\*\s+from\s+["']([^"']+)["']/);
|
|
27105
|
+
if (redirectMatch) {
|
|
27106
|
+
const bundleUrl = `${ESM_SH_BASE_URL}${redirectMatch[1]}`;
|
|
27107
|
+
logger.debug(`[ExtensionLibraryLoader] Following redirect to ${bundleUrl}`);
|
|
27108
|
+
response = await fetchWithTimeout(bundleUrl);
|
|
27109
|
+
if (!response.ok) {
|
|
27110
|
+
throw new Error(`Failed to fetch bundle for ${librarySpec} from esm.sh: ${response.status} ${response.statusText}`);
|
|
27111
|
+
}
|
|
27112
|
+
source = await response.text();
|
|
27113
|
+
}
|
|
27114
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
27115
|
+
await fs.writeFile(cachePath, source, "utf-8");
|
|
27116
|
+
await fs.writeFile(metaPath, JSON.stringify({ librarySpec, fetchedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
|
|
27117
|
+
logger.info(`[ExtensionLibraryLoader] Cached ${librarySpec}`);
|
|
27118
|
+
return source;
|
|
27119
|
+
}
|
|
27120
|
+
}
|
|
26549
27121
|
class ExtensionManager {
|
|
26550
27122
|
constructor(store, modelManager, eventManager, telemetryManager, memoryManager, registry = new ExtensionRegistry()) {
|
|
26551
27123
|
this.store = store;
|
|
@@ -26556,6 +27128,7 @@ class ExtensionManager {
|
|
|
26556
27128
|
this.registry = registry;
|
|
26557
27129
|
this.loader = new ExtensionLoader();
|
|
26558
27130
|
this.fetcher = new ExtensionFetcher();
|
|
27131
|
+
this.libraryLoader = new ExtensionLibraryLoader();
|
|
26559
27132
|
}
|
|
26560
27133
|
loader;
|
|
26561
27134
|
fetcher;
|
|
@@ -26563,6 +27136,7 @@ class ExtensionManager {
|
|
|
26563
27136
|
projectWatchers = /* @__PURE__ */ new Map();
|
|
26564
27137
|
initialized = false;
|
|
26565
27138
|
listeners = [];
|
|
27139
|
+
libraryLoader;
|
|
26566
27140
|
debouncedNotifyListeners = debounce(() => {
|
|
26567
27141
|
const extensions = this.registry.getExtensions();
|
|
26568
27142
|
for (const listener of this.listeners) {
|
|
@@ -26607,6 +27181,9 @@ class ExtensionManager {
|
|
|
26607
27181
|
logger.debug("[Extensions] Repository list changed, refreshing extension cache");
|
|
26608
27182
|
void this.fetcher.getAvailableExtensions(newRepositories, true);
|
|
26609
27183
|
}
|
|
27184
|
+
if (oldSettings.fileWatchMode !== newSettings.fileWatchMode) {
|
|
27185
|
+
void this.restartWatchers();
|
|
27186
|
+
}
|
|
26610
27187
|
}
|
|
26611
27188
|
addListener(listener) {
|
|
26612
27189
|
this.listeners.push(listener);
|
|
@@ -26911,7 +27488,7 @@ class ExtensionManager {
|
|
|
26911
27488
|
};
|
|
26912
27489
|
const watcher = chokidar.watch(dir, {
|
|
26913
27490
|
persistent: true,
|
|
26914
|
-
usePolling:
|
|
27491
|
+
usePolling: shouldUsePolling(dir, this.store.getSettings().fileWatchMode),
|
|
26915
27492
|
ignoreInitial: true,
|
|
26916
27493
|
ignored: (filePath) => {
|
|
26917
27494
|
const basename = path.basename(filePath);
|
|
@@ -26995,6 +27572,25 @@ class ExtensionManager {
|
|
|
26995
27572
|
logger.debug(`[Extensions] Stopped watching project extensions: ${projectDir}`);
|
|
26996
27573
|
}
|
|
26997
27574
|
}
|
|
27575
|
+
async restartWatchers() {
|
|
27576
|
+
const projectDirs = Array.from(this.projectWatchers.keys());
|
|
27577
|
+
await this.stopGlobalWatcher();
|
|
27578
|
+
for (const dir of projectDirs) {
|
|
27579
|
+
await this.stopProjectWatcher(dir);
|
|
27580
|
+
}
|
|
27581
|
+
await this.startHotReloadWatcher();
|
|
27582
|
+
for (const dir of projectDirs) {
|
|
27583
|
+
const projectExtensionsDir = path.join(dir, AIDER_DESK_EXTENSIONS_DIR);
|
|
27584
|
+
const watcher = await this.setupWatcherForDir(projectExtensionsDir, async () => {
|
|
27585
|
+
logger.debug(`[Extensions] Project extensions changed for ${dir}, reloading...`);
|
|
27586
|
+
await this.unloadExtensionsForDir(projectExtensionsDir);
|
|
27587
|
+
await this.loadExtensionsForDir(projectExtensionsDir);
|
|
27588
|
+
});
|
|
27589
|
+
if (watcher) {
|
|
27590
|
+
this.projectWatchers.set(dir, watcher);
|
|
27591
|
+
}
|
|
27592
|
+
}
|
|
27593
|
+
}
|
|
26998
27594
|
static TOOL_NAME_REGEX = /^[a-z][a-z0-9_-]*$/;
|
|
26999
27595
|
validateToolDefinition(tool) {
|
|
27000
27596
|
const errors = [];
|
|
@@ -27395,6 +27991,39 @@ class ExtensionManager {
|
|
|
27395
27991
|
}
|
|
27396
27992
|
return collectedComponents;
|
|
27397
27993
|
}
|
|
27994
|
+
getUIComponentsLibraries(project) {
|
|
27995
|
+
const librariesByExtension = /* @__PURE__ */ new Map();
|
|
27996
|
+
const allExtensions = this.registry.getExtensions(project?.baseDir);
|
|
27997
|
+
const extensions = this.filterEnabledExtensions(allExtensions);
|
|
27998
|
+
for (const loaded of extensions) {
|
|
27999
|
+
const { instance, initialized, metadata } = loaded;
|
|
28000
|
+
if (!initialized || !instance.getUIComponentsLibraries) {
|
|
28001
|
+
continue;
|
|
28002
|
+
}
|
|
28003
|
+
try {
|
|
28004
|
+
const libraries = instance.getUIComponentsLibraries();
|
|
28005
|
+
if (typeof libraries !== "object" || libraries === null || Array.isArray(libraries)) {
|
|
28006
|
+
logger.error(`[Extensions] Extension '${metadata.name}' getUIComponentsLibraries() did not return a Record<string, string>`);
|
|
28007
|
+
continue;
|
|
28008
|
+
}
|
|
28009
|
+
const validLibs = {};
|
|
28010
|
+
for (const [key, spec] of Object.entries(libraries)) {
|
|
28011
|
+
if (typeof key === "string" && typeof spec === "string") {
|
|
28012
|
+
validLibs[key] = spec;
|
|
28013
|
+
}
|
|
28014
|
+
}
|
|
28015
|
+
if (Object.keys(validLibs).length > 0) {
|
|
28016
|
+
librariesByExtension.set(loaded.id, validLibs);
|
|
28017
|
+
}
|
|
28018
|
+
} catch (error) {
|
|
28019
|
+
logger.error(`[Extensions] Failed to get UI component libraries from extension '${metadata.name}':`, error);
|
|
28020
|
+
}
|
|
28021
|
+
}
|
|
28022
|
+
return librariesByExtension;
|
|
28023
|
+
}
|
|
28024
|
+
async loadExtensionLibrary(librarySpec) {
|
|
28025
|
+
return await this.libraryLoader.loadLibrary(librarySpec);
|
|
28026
|
+
}
|
|
27398
28027
|
/**
|
|
27399
28028
|
* Check if an extension provides a settings config component.
|
|
27400
28029
|
* Uses the dedicated getConfigComponent() method on the Extension interface.
|
|
@@ -27913,7 +28542,7 @@ class ExtensionManager {
|
|
|
27913
28542
|
}
|
|
27914
28543
|
}
|
|
27915
28544
|
class EventsHandler {
|
|
27916
|
-
constructor(projectManager, store, mcpManager, versionsManager, modelManager, telemetryManager, dataManager, terminalManager, cloudflareTunnelManager, eventManager, agentProfileManager, memoryManager, extensionManager, proxyManager, windowManager) {
|
|
28545
|
+
constructor(projectManager, store, mcpManager, versionsManager, modelManager, telemetryManager, dataManager, terminalManager, cloudflareTunnelManager, eventManager, agentProfileManager, memoryManager, extensionManager, proxyManager, promptsManager, windowManager) {
|
|
27917
28546
|
this.projectManager = projectManager;
|
|
27918
28547
|
this.store = store;
|
|
27919
28548
|
this.mcpManager = mcpManager;
|
|
@@ -27928,6 +28557,7 @@ class EventsHandler {
|
|
|
27928
28557
|
this.memoryManager = memoryManager;
|
|
27929
28558
|
this.extensionManager = extensionManager;
|
|
27930
28559
|
this.proxyManager = proxyManager;
|
|
28560
|
+
this.promptsManager = promptsManager;
|
|
27931
28561
|
this.windowManager = windowManager;
|
|
27932
28562
|
}
|
|
27933
28563
|
loadSettings() {
|
|
@@ -27941,6 +28571,8 @@ class EventsHandler {
|
|
|
27941
28571
|
this.telemetryManager.settingsChanged(oldSettings, newSettings);
|
|
27942
28572
|
void this.memoryManager.settingsChanged(oldSettings, newSettings);
|
|
27943
28573
|
this.extensionManager.settingsChanged(oldSettings, newSettings);
|
|
28574
|
+
void this.agentProfileManager.settingsChanged(oldSettings, newSettings);
|
|
28575
|
+
void this.promptsManager.settingsChanged(oldSettings, newSettings);
|
|
27944
28576
|
this.eventManager.sendSettingsUpdated(newSettings);
|
|
27945
28577
|
return this.store.getSettings();
|
|
27946
28578
|
}
|
|
@@ -28816,15 +29448,20 @@ ${error instanceof Error ? error.message : String(error)}`);
|
|
|
28816
29448
|
const task = taskId && project ? project.getTask(taskId) ?? void 0 : void 0;
|
|
28817
29449
|
const components = this.extensionManager.getUIComponents(project, task);
|
|
28818
29450
|
const filtered = placement ? components.filter((c) => c.component.placement === placement) : components;
|
|
29451
|
+
const librariesByExtension = this.extensionManager.getUIComponentsLibraries(project);
|
|
28819
29452
|
return filtered.map((c) => ({
|
|
28820
29453
|
extensionId: c.extensionId,
|
|
28821
29454
|
componentId: c.component.id,
|
|
28822
29455
|
placement: c.component.placement,
|
|
28823
29456
|
jsx: c.component.jsx,
|
|
28824
29457
|
loadData: c.component.loadData,
|
|
28825
|
-
noDataCache: c.component.noDataCache
|
|
29458
|
+
noDataCache: c.component.noDataCache,
|
|
29459
|
+
libraries: librariesByExtension.get(c.extensionId)
|
|
28826
29460
|
}));
|
|
28827
29461
|
}
|
|
29462
|
+
async loadExtensionLibrary(librarySpec) {
|
|
29463
|
+
return await this.extensionManager.loadExtensionLibrary(librarySpec);
|
|
29464
|
+
}
|
|
28828
29465
|
async getUIExtensionData(extensionId, componentId, projectDir, taskId) {
|
|
28829
29466
|
logger.debug("Getting UI extension data:", {
|
|
28830
29467
|
extensionId,
|
|
@@ -28921,8 +29558,9 @@ const registerAllHelpers = () => {
|
|
|
28921
29558
|
registerFormattingHelpers();
|
|
28922
29559
|
};
|
|
28923
29560
|
class PromptsManager {
|
|
28924
|
-
constructor(extensionManager, defaultTemplatesDir = AIDER_DESK_DEFAULT_PROMPTS_DIR, globalPromptsDir = AIDER_DESK_GLOBAL_PROMPTS_DIR) {
|
|
29561
|
+
constructor(extensionManager, store, defaultTemplatesDir = AIDER_DESK_DEFAULT_PROMPTS_DIR, globalPromptsDir = AIDER_DESK_GLOBAL_PROMPTS_DIR) {
|
|
28925
29562
|
this.extensionManager = extensionManager;
|
|
29563
|
+
this.store = store;
|
|
28926
29564
|
this.defaultTemplatesDir = defaultTemplatesDir;
|
|
28927
29565
|
this.globalPromptsDir = globalPromptsDir;
|
|
28928
29566
|
registerAllHelpers();
|
|
@@ -29016,7 +29654,7 @@ class PromptsManager {
|
|
|
29016
29654
|
}
|
|
29017
29655
|
const watcher = chokidar.watch(this.globalPromptsDir, {
|
|
29018
29656
|
persistent: true,
|
|
29019
|
-
usePolling:
|
|
29657
|
+
usePolling: shouldUsePolling(this.globalPromptsDir, this.store.getSettings().fileWatchMode),
|
|
29020
29658
|
ignoreInitial: true
|
|
29021
29659
|
});
|
|
29022
29660
|
const debouncedReload = debounce(async () => {
|
|
@@ -29041,7 +29679,7 @@ class PromptsManager {
|
|
|
29041
29679
|
await this.compileProjectTemplates(projectDir);
|
|
29042
29680
|
const watcher = chokidar.watch(projectPromptsDir, {
|
|
29043
29681
|
persistent: true,
|
|
29044
|
-
usePolling:
|
|
29682
|
+
usePolling: shouldUsePolling(projectPromptsDir, this.store.getSettings().fileWatchMode),
|
|
29045
29683
|
ignoreInitial: true
|
|
29046
29684
|
});
|
|
29047
29685
|
const debouncedReload = debounce(async () => {
|
|
@@ -29070,6 +29708,20 @@ class PromptsManager {
|
|
|
29070
29708
|
this.projectTemplatesCache.clear();
|
|
29071
29709
|
logger.info("PromptsManager disposed");
|
|
29072
29710
|
}
|
|
29711
|
+
async settingsChanged(oldSettings, newSettings) {
|
|
29712
|
+
if (oldSettings.fileWatchMode === newSettings.fileWatchMode) {
|
|
29713
|
+
return;
|
|
29714
|
+
}
|
|
29715
|
+
const watchedProjects = Array.from(this.watchers.keys()).filter((k) => k !== "global");
|
|
29716
|
+
for (const watcher of this.watchers.values()) {
|
|
29717
|
+
await watcher.close();
|
|
29718
|
+
}
|
|
29719
|
+
this.watchers.clear();
|
|
29720
|
+
await this.setupGlobalWatcher();
|
|
29721
|
+
for (const projectDir of watchedProjects) {
|
|
29722
|
+
await this.watchProject(projectDir);
|
|
29723
|
+
}
|
|
29724
|
+
}
|
|
29073
29725
|
async render(name, data, projectDir, task) {
|
|
29074
29726
|
const projectTemplates = this.projectTemplatesCache.get(projectDir);
|
|
29075
29727
|
const projectTemplate = projectTemplates?.get(name);
|
|
@@ -29095,7 +29747,7 @@ class PromptsManager {
|
|
|
29095
29747
|
}
|
|
29096
29748
|
return prompt;
|
|
29097
29749
|
}
|
|
29098
|
-
calculateToolPermissions = (settings, agentProfile,
|
|
29750
|
+
calculateToolPermissions = (settings, agentProfile, autonomyMode) => {
|
|
29099
29751
|
const { usePowerTools = false, useMemoryTools = false, useSkillsTools = false } = agentProfile;
|
|
29100
29752
|
const memoryEnabled = settings.memory.enabled && useMemoryTools;
|
|
29101
29753
|
const isAllowed = (tool) => agentProfile.toolApprovals[tool] !== ToolApprovalState.Never;
|
|
@@ -29124,11 +29776,12 @@ class PromptsManager {
|
|
|
29124
29776
|
skills: {
|
|
29125
29777
|
allowed: useSkillsTools && isAllowed(`${SKILLS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${SKILLS_TOOL_ACTIVATE_SKILL}`)
|
|
29126
29778
|
},
|
|
29127
|
-
|
|
29779
|
+
autonomyMode
|
|
29128
29780
|
};
|
|
29129
29781
|
};
|
|
29130
|
-
getSystemPrompt = async (settings, task, agentProfile,
|
|
29131
|
-
const
|
|
29782
|
+
getSystemPrompt = async (settings, task, agentProfile, autonomyMode, additionalInstructions) => {
|
|
29783
|
+
const effectiveAutonomyMode = autonomyMode ?? task.task.autonomyMode ?? DEFAULT_AUTONOMY_MODE;
|
|
29784
|
+
const toolPermissions = this.calculateToolPermissions(settings, agentProfile, effectiveAutonomyMode);
|
|
29132
29785
|
toolPermissions.powerTools.anyEnabled = Object.values(toolPermissions.powerTools).some((v) => v);
|
|
29133
29786
|
const rulesFiles = await this.getRulesContent(task, agentProfile);
|
|
29134
29787
|
const customInstructions = [agentProfile.customInstructions, additionalInstructions].filter(Boolean).join("\n\n").trim();
|
|
@@ -29537,12 +30190,12 @@ const initManagers = async (store, windowManager) => {
|
|
|
29537
30190
|
extensionManager.init().catch((error) => {
|
|
29538
30191
|
logger.error("[Extensions] Extension system initialization failed, continuing without extensions:", error);
|
|
29539
30192
|
});
|
|
29540
|
-
const promptsManager = new PromptsManager(extensionManager);
|
|
30193
|
+
const promptsManager = new PromptsManager(extensionManager, store);
|
|
29541
30194
|
promptsManager.init().catch((error) => {
|
|
29542
30195
|
logger.error("[Prompts] Prompts system initialization failed:", error);
|
|
29543
30196
|
});
|
|
29544
30197
|
const worktreeManager = new WorktreeManager();
|
|
29545
|
-
const agentProfileManager = new AgentProfileManager(eventManager, extensionManager);
|
|
30198
|
+
const agentProfileManager = new AgentProfileManager(eventManager, extensionManager, store);
|
|
29546
30199
|
agentProfileManager.init().catch((error) => {
|
|
29547
30200
|
logger.error("[AgentProfile] Agent profile system initialization failed:", error);
|
|
29548
30201
|
});
|
|
@@ -29579,6 +30232,7 @@ const initManagers = async (store, windowManager) => {
|
|
|
29579
30232
|
memoryManager,
|
|
29580
30233
|
extensionManager,
|
|
29581
30234
|
proxyManager,
|
|
30235
|
+
promptsManager,
|
|
29582
30236
|
windowManager
|
|
29583
30237
|
);
|
|
29584
30238
|
const serverController = new ServerController(httpServer, projectManager, eventsHandler, store, pythonInstaller);
|
|
@@ -30210,7 +30864,8 @@ const DEFAULT_SETTINGS = {
|
|
|
30210
30864
|
proxy: {
|
|
30211
30865
|
enabled: false,
|
|
30212
30866
|
url: ""
|
|
30213
|
-
}
|
|
30867
|
+
},
|
|
30868
|
+
fileWatchMode: FileWatchMode.Auto
|
|
30214
30869
|
};
|
|
30215
30870
|
const compareBaseDirs = (baseDir1, baseDir2) => {
|
|
30216
30871
|
return normalizeBaseDir(baseDir1) === normalizeBaseDir(baseDir2);
|