@aiderdesk/aiderdesk 0.68.0 → 0.69.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-Cju-fnUJ.js → arc--tfU0Ahe.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-3BPJPVTR-hVK8LPcC.js → architectureDiagram-3BPJPVTR-D2uDC6Pw.js} +3 -3
- package/out/renderer/assets/{blockDiagram-GPEHLZMM-B04Ulwbh.js → blockDiagram-GPEHLZMM-BKopmU2x.js} +4 -4
- package/out/renderer/assets/{c4Diagram-AAUBKEIU-DSP8EUB6.js → c4Diagram-AAUBKEIU-CU9NH6bi.js} +2 -2
- package/out/renderer/assets/{channel-CM1Bn7Zy.js → channel-CBm2XBi8.js} +1 -1
- package/out/renderer/assets/{chunk-2J33WTMH-Bd_3pGvb.js → chunk-2J33WTMH-Yb07TKpF.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-Csrpxz3N.js → chunk-4BX2VUAB-B1KgZMg1.js} +1 -1
- package/out/renderer/assets/{chunk-55IACEB6-BB7RTMZZ.js → chunk-55IACEB6-BQ1g6F53.js} +1 -1
- package/out/renderer/assets/{chunk-727SXJPM-D6Y9H3aA.js → chunk-727SXJPM-nQzqwjgJ.js} +5 -5
- package/out/renderer/assets/{chunk-AQP2D5EJ-D5f9Zgag.js → chunk-AQP2D5EJ-8vVOUXUS.js} +3 -3
- package/out/renderer/assets/{chunk-FMBD7UC4-Bstyl64g.js → chunk-FMBD7UC4-dVquqYuV.js} +1 -1
- package/out/renderer/assets/{chunk-ND2GUHAM-CVaUW2HV.js → chunk-ND2GUHAM-Bu2VSodd.js} +1 -1
- package/out/renderer/assets/{chunk-QZHKN3VN-AMfy7Nbn.js → chunk-QZHKN3VN-Bl58FmbX.js} +1 -1
- package/out/renderer/assets/{classDiagram-4FO5ZUOK-CPmL8t3E.js → classDiagram-4FO5ZUOK-Dmfohc7-.js} +6 -6
- package/out/renderer/assets/{classDiagram-v2-Q7XG4LA2-CPmL8t3E.js → classDiagram-v2-Q7XG4LA2-Dmfohc7-.js} +6 -6
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-px_eCLil.js → cose-bilkent-S5V4N54A-8bgOaac3.js} +1 -1
- package/out/renderer/assets/{dagre-BM42HDAG-c63xhfuM.js → dagre-BM42HDAG-BZZ0JLHX.js} +3 -3
- package/out/renderer/assets/{diagram-2AECGRRQ-DISIyKng.js → diagram-2AECGRRQ-9oArT1ZV.js} +3 -3
- package/out/renderer/assets/{diagram-5GNKFQAL-BSkGLBgD.js → diagram-5GNKFQAL-OMRICVmJ.js} +4 -4
- package/out/renderer/assets/{diagram-KO2AKTUF-xiSl-Lui.js → diagram-KO2AKTUF-pjPRIjL7.js} +3 -3
- package/out/renderer/assets/{diagram-LMA3HP47-lJ69G8gJ.js → diagram-LMA3HP47-cRVrdFbD.js} +3 -3
- package/out/renderer/assets/{diagram-OG6HWLK6-AoDpX3QT.js → diagram-OG6HWLK6-gJvA5dOA.js} +4 -4
- package/out/renderer/assets/{erDiagram-TEJ5UH35-O7UNRkDw.js → erDiagram-TEJ5UH35-BvHOuuhD.js} +4 -4
- package/out/renderer/assets/{flowDiagram-I6XJVG4X-Dd9XTtIY.js → flowDiagram-I6XJVG4X-D17Inzho.js} +6 -6
- package/out/renderer/assets/{ganttDiagram-6RSMTGT7-Bc7FUk0Y.js → ganttDiagram-6RSMTGT7-CIorTPIp.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-PVQCEYII-DwEksAhs.js → gitGraphDiagram-PVQCEYII-R3v9UanE.js} +4 -4
- package/out/renderer/assets/{graph-BPvbzKl1.js → graph-DNFReSa8.js} +1 -1
- package/out/renderer/assets/{index-BmQl7j8n.js → index-COTYjomB.js} +27701 -132358
- package/out/renderer/assets/{index-z-BItG-u.css → index-D56aByCg.css} +32 -0
- package/out/renderer/assets/{infoDiagram-5YYISTIA-DvophXOV.js → infoDiagram-5YYISTIA-B4hJmlOG.js} +2 -2
- package/out/renderer/assets/{ishikawaDiagram-YF4QCWOH-CDT4EDOF.js → ishikawaDiagram-YF4QCWOH-DxohqJKP.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-JHISSGLW-B5FCPOti.js → journeyDiagram-JHISSGLW-BxFBZYTB.js} +4 -4
- package/out/renderer/assets/{jsx-dev-runtime-DuBp-Rhq.js → jsx-dev-runtime-BsbxiHH-.js} +1 -1
- package/out/renderer/assets/{kanban-definition-UN3LZRKU-CM_TQl4S.js → kanban-definition-UN3LZRKU-B39Yt2kD.js} +2 -2
- package/out/renderer/assets/{layout-DdBKGefG.js → layout-yXTq0RED.js} +2 -2
- package/out/renderer/assets/{mindmap-definition-RKZ34NQL-BeGrpK-H.js → mindmap-definition-RKZ34NQL-BD2OIaSH.js} +3 -3
- package/out/renderer/assets/{pieDiagram-4H26LBE5-CnMhRK3I.js → pieDiagram-4H26LBE5-COAWItT4.js} +4 -4
- package/out/renderer/assets/pierre-dark-C-Drv5KU.js +4 -0
- package/out/renderer/assets/pierre-dark-soft-Cd74uQaL.js +4 -0
- package/out/renderer/assets/pierre-light-CfQnmt6J.js +4 -0
- package/out/renderer/assets/pierre-light-soft-DMVdU74b.js +4 -0
- package/out/renderer/assets/{quadrantDiagram-W4KKPZXB-O_Q_JI2s.js → quadrantDiagram-W4KKPZXB-BLY0H2F6.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-4Y6WPE33-vf9wLf04.js → requirementDiagram-4Y6WPE33-DEJf5mz_.js} +3 -3
- package/out/renderer/assets/{sankeyDiagram-5OEKKPKP-CE4n-uB4.js → sankeyDiagram-5OEKKPKP-D3BkTe8z.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-3UESZ5HK-DebEZhql.js → sequenceDiagram-3UESZ5HK-DUU_lUpD.js} +3 -3
- package/out/renderer/assets/{stateDiagram-AJRCARHV-DCsVosBt.js → stateDiagram-AJRCARHV-DnH4p93i.js} +6 -6
- package/out/renderer/assets/{stateDiagram-v2-BHNVJYJU-8oguEvt8.js → stateDiagram-v2-BHNVJYJU-CRXRiP95.js} +4 -4
- package/out/renderer/assets/{timeline-definition-PNZ67QCA-CSfXVnNf.js → timeline-definition-PNZ67QCA-Uv34KQP0.js} +2 -2
- package/out/renderer/assets/{vennDiagram-CIIHVFJN-DxOEVeC4.js → vennDiagram-CIIHVFJN-JyUQxmn1.js} +1 -1
- package/out/renderer/assets/{wardley-L42UT6IY-Cz6T4MDn.js → wardley-L42UT6IY-4X2JoJpL.js} +1 -1
- package/out/renderer/assets/{wardleyDiagram-YWT4CUSO-B4sA3LOJ.js → wardleyDiagram-YWT4CUSO-B9pIhVmY.js} +3 -3
- package/out/renderer/assets/{worker-CfJUABHG.js → worker-BdXuKH1Q.js} +274 -171
- package/out/renderer/assets/{xychartDiagram-2RQKCTM6-DbJjruqS.js → xychartDiagram-2RQKCTM6-PJZgkel8.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/out/resources/skills/extension-creator/references/ui-components.md +11 -0
- package/out/runner.js +323 -422
- package/package.json +19 -32
- package/patches/{ai+5.0.179.patch → ai+5.0.195.patch} +9 -9
- package/out/renderer/assets/pierre-dark-DADY5eR0.js +0 -4
- package/out/renderer/assets/pierre-light-DUjirxKp.js +0 -4
- package/patches/@ai-sdk+deepseek+1.0.37.patch +0 -150
- package/patches/ai-sdk-provider-claude-code+2.3.0.patch +0 -1024
package/out/runner.js
CHANGED
|
@@ -73,8 +73,6 @@ const clientBedrock = require("@aws-sdk/client-bedrock");
|
|
|
73
73
|
const credentialProviders = require("@aws-sdk/credential-providers");
|
|
74
74
|
const amazonBedrock = require("@ai-sdk/amazon-bedrock");
|
|
75
75
|
const cerebras = require("@ai-sdk/cerebras");
|
|
76
|
-
const aiSdkProviderClaudeCode = require("ai-sdk-provider-claude-code");
|
|
77
|
-
const jsonSchemaToZod = require("@dmitryrechkin/json-schema-to-zod");
|
|
78
76
|
const deepseek = require("@ai-sdk/deepseek");
|
|
79
77
|
const google = require("@ai-sdk/google");
|
|
80
78
|
const genai = require("@google/genai");
|
|
@@ -868,7 +866,6 @@ const CLOUDFLARED_BINARY_PATH = path.join(
|
|
|
868
866
|
"bin",
|
|
869
867
|
process.platform === "win32" ? "cloudflared.exe" : "cloudflared"
|
|
870
868
|
);
|
|
871
|
-
const CLAUDE_CODE_EXECUTABLE_PATH = path.join(RESOURCES_DIR, "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-agent-sdk", "cli.js");
|
|
872
869
|
const eventTransport = new EventTransport();
|
|
873
870
|
const logger = winston.createLogger({
|
|
874
871
|
level: process.env.LOG_LEVEL || "info",
|
|
@@ -1497,11 +1494,9 @@ const AVAILABLE_PROVIDERS = [
|
|
|
1497
1494
|
"alibaba-plan",
|
|
1498
1495
|
"anthropic",
|
|
1499
1496
|
"anthropic-compatible",
|
|
1500
|
-
"auggie",
|
|
1501
1497
|
"azure",
|
|
1502
1498
|
"bedrock",
|
|
1503
1499
|
"cerebras",
|
|
1504
|
-
"claude-agent-sdk",
|
|
1505
1500
|
"deepseek",
|
|
1506
1501
|
"gemini",
|
|
1507
1502
|
"gemini-cli",
|
|
@@ -1532,7 +1527,6 @@ const isOpenAiProvider = (provider) => provider.name === "openai";
|
|
|
1532
1527
|
const isAzureProvider = (provider) => provider.name === "azure";
|
|
1533
1528
|
const isAnthropicProvider = (provider) => provider.name === "anthropic";
|
|
1534
1529
|
const isAnthropicCompatibleProvider = (provider) => provider.name === "anthropic-compatible";
|
|
1535
|
-
const isAuggieProvider = (provider) => provider.name === "auggie";
|
|
1536
1530
|
const isKimiPlanProvider = (provider) => provider.name === "kimi-plan";
|
|
1537
1531
|
const isAlibabaPlanProvider = (provider) => provider.name === "alibaba-plan";
|
|
1538
1532
|
var GeminiVoiceModel = /* @__PURE__ */ ((GeminiVoiceModel2) => {
|
|
@@ -1545,7 +1539,6 @@ const isLmStudioProvider = (provider) => provider.name === "lmstudio";
|
|
|
1545
1539
|
const isDeepseekProvider = (provider) => provider.name === "deepseek";
|
|
1546
1540
|
const isGroqProvider = (provider) => provider.name === "groq";
|
|
1547
1541
|
const isCerebrasProvider = (provider) => provider.name === "cerebras";
|
|
1548
|
-
const isClaudeAgentSdkProvider = (provider) => provider.name === "claude-agent-sdk";
|
|
1549
1542
|
const isGeminiCliProvider = (provider) => provider.name === "gemini-cli";
|
|
1550
1543
|
const isBedrockProvider = (provider) => provider.name === "bedrock";
|
|
1551
1544
|
const isOpenAiCompatibleProvider = (provider) => provider.name === "openai-compatible";
|
|
@@ -1563,10 +1556,8 @@ const isSyntheticProvider = (provider) => provider.name === "synthetic";
|
|
|
1563
1556
|
const DEFAULT_PROVIDER_MODELS = {
|
|
1564
1557
|
"alibaba-plan": "qwen3-coder-plus",
|
|
1565
1558
|
anthropic: "claude-sonnet-4-6",
|
|
1566
|
-
auggie: "gpt-5-4",
|
|
1567
1559
|
bedrock: "global.anthropic.claude-sonnet-4-6",
|
|
1568
1560
|
cerebras: "qwen-3-235b-a22b-instruct-2507",
|
|
1569
|
-
"claude-agent-sdk": "sonnet",
|
|
1570
1561
|
deepseek: "deepseek-v4-pro",
|
|
1571
1562
|
gemini: "gemini-pro-latest",
|
|
1572
1563
|
"gemini-cli": "gemini-2.5-pro",
|
|
@@ -1639,6 +1630,7 @@ const DEFAULT_AGENT_PROFILE = {
|
|
|
1639
1630
|
useMemoryTools: true,
|
|
1640
1631
|
useSkillsTools: true,
|
|
1641
1632
|
useExtensionTools: true,
|
|
1633
|
+
disabledExtensionTools: [],
|
|
1642
1634
|
customInstructions: "",
|
|
1643
1635
|
enabledServers: [],
|
|
1644
1636
|
subagent: {
|
|
@@ -1774,6 +1766,7 @@ const COMPACT_CONVERSATION_AGENT_PROFILE = {
|
|
|
1774
1766
|
}
|
|
1775
1767
|
};
|
|
1776
1768
|
({
|
|
1769
|
+
...DEFAULT_AGENT_PROFILE,
|
|
1777
1770
|
toolApprovals: {
|
|
1778
1771
|
...DEFAULT_AGENT_PROFILE.toolApprovals,
|
|
1779
1772
|
[`${POWER_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${POWER_TOOL_FILE_EDIT}`]: ToolApprovalState.Never,
|
|
@@ -1823,13 +1816,6 @@ const getDefaultProviderParams = (providerName) => {
|
|
|
1823
1816
|
baseUrl: ""
|
|
1824
1817
|
};
|
|
1825
1818
|
break;
|
|
1826
|
-
case "auggie":
|
|
1827
|
-
provider = {
|
|
1828
|
-
name: "auggie",
|
|
1829
|
-
apiKey: "",
|
|
1830
|
-
apiUrl: ""
|
|
1831
|
-
};
|
|
1832
|
-
break;
|
|
1833
1819
|
case "gemini":
|
|
1834
1820
|
provider = {
|
|
1835
1821
|
name: "gemini",
|
|
@@ -2262,7 +2248,6 @@ const readApiKeyFromConfFile = (filePath, envVarName) => {
|
|
|
2262
2248
|
GOOGLE_API_KEY: ["gemini", "google"],
|
|
2263
2249
|
OPENAI_API_KEY: ["openai"],
|
|
2264
2250
|
ANTHROPIC_API_KEY: ["anthropic", "anthropic-compatible"],
|
|
2265
|
-
AUGMENT_API_TOKEN: ["auggie"],
|
|
2266
2251
|
GROQ_API_KEY: ["groq"],
|
|
2267
2252
|
ALIBABA_PLAN_API_KEY: ["alibaba-plan"],
|
|
2268
2253
|
KIMI_PLAN_API_KEY: ["kimi-plan"],
|
|
@@ -3248,6 +3233,20 @@ const scrapeWeb = async (url, timeout = 6e4, abortSignal, format = "markdown") =
|
|
|
3248
3233
|
const scraper = new WebScraper();
|
|
3249
3234
|
return await scraper.scrape(url, timeout, abortSignal, format);
|
|
3250
3235
|
};
|
|
3236
|
+
const coerceBoolean = zod.z.preprocess((val) => {
|
|
3237
|
+
if (typeof val === "boolean") {
|
|
3238
|
+
return val;
|
|
3239
|
+
}
|
|
3240
|
+
if (typeof val === "string") {
|
|
3241
|
+
if (val.toLowerCase() === "true") {
|
|
3242
|
+
return true;
|
|
3243
|
+
}
|
|
3244
|
+
if (val.toLowerCase() === "false") {
|
|
3245
|
+
return false;
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
return val;
|
|
3249
|
+
}, zod.z.boolean());
|
|
3251
3250
|
const THINKING_RESPONSE_STAR_TAG = "---\n► **THINKING**\n";
|
|
3252
3251
|
const ANSWER_RESPONSE_START_TAG = "---\n► **ANSWER**\n";
|
|
3253
3252
|
const extractPromptContextFromToolResult = (toolResult) => {
|
|
@@ -3484,8 +3483,8 @@ Include enough lines in each to uniquely match each set of lines that need to ch
|
|
|
3484
3483
|
Do not use escape characters \\ in the string like \\n or \\" and others. Do not start the search term with a \\ character.`
|
|
3485
3484
|
),
|
|
3486
3485
|
replacementText: zod.z.string().describe('The string to replace the searchTerm with. Do not use escape characters \\ in the string like \\n or \\" and others'),
|
|
3487
|
-
isRegex:
|
|
3488
|
-
replaceAll:
|
|
3486
|
+
isRegex: coerceBoolean.optional().default(false).describe("Whether the searchTerm should be treated as a regular expression. Use regex only when it is really needed. Default: false."),
|
|
3487
|
+
replaceAll: coerceBoolean.optional().default(false).describe("Whether to replace all occurrences or just the first one. Default: false.")
|
|
3489
3488
|
}),
|
|
3490
3489
|
execute: async (input, { toolCallId }) => {
|
|
3491
3490
|
const { filePath, searchTerm, replacementText, isRegex, replaceAll } = input;
|
|
@@ -3575,9 +3574,9 @@ Do not use escape characters \\ in the string like \\n or \\" and others. Do not
|
|
|
3575
3574
|
description: POWER_TOOL_DESCRIPTIONS[POWER_TOOL_FILE_READ],
|
|
3576
3575
|
inputSchema: zod.z.object({
|
|
3577
3576
|
filePath: zod.z.string().describe("The path to the file to be read (relative to the <WorkingDirectory> or absolute if outside of the directory)."),
|
|
3578
|
-
withLines:
|
|
3579
|
-
lineOffset: zod.z.number().int().min(0).optional().default(0).describe("The starting line number (0-based) to begin reading from. Default: 0."),
|
|
3580
|
-
lineLimit: zod.z.number().int().min(1).optional().default(1e3).describe("The maximum number of lines to read. Default: 1000.")
|
|
3577
|
+
withLines: coerceBoolean.optional().default(false).describe('Whether to return the file content with line numbers in format "lineNumber|content". Default: false.'),
|
|
3578
|
+
lineOffset: zod.z.coerce.number().int().min(0).optional().default(0).describe("The starting line number (0-based) to begin reading from. Default: 0."),
|
|
3579
|
+
lineLimit: zod.z.coerce.number().int().min(1).optional().default(1e3).describe("The maximum number of lines to read. Default: 1000.")
|
|
3581
3580
|
}),
|
|
3582
3581
|
execute: async (input, { toolCallId }) => {
|
|
3583
3582
|
const { filePath, withLines, lineOffset, lineLimit } = input;
|
|
@@ -3741,8 +3740,8 @@ Do not use escape characters \\ in the string like \\n or \\" and others. Do not
|
|
|
3741
3740
|
filePattern: zod.z.string().describe("A glob pattern specifying the files to search within (e.g., src/**/*.tsx, *.py)."),
|
|
3742
3741
|
searchTerm: zod.z.string().describe("The regular expression to search for within the files."),
|
|
3743
3742
|
contextLines: zod.z.number().int().min(0).optional().default(0).describe("The number of lines of context to show before and after each matching line. Default: 0."),
|
|
3744
|
-
caseSensitive:
|
|
3745
|
-
maxResults: zod.z.number().int().min(1).optional().default(50).describe("Maximum number of results to return. Default: 50.")
|
|
3743
|
+
caseSensitive: coerceBoolean.optional().default(false).describe("Whether the search should be case sensitive. Default: false."),
|
|
3744
|
+
maxResults: zod.z.coerce.number().int().min(1).optional().default(50).describe("Maximum number of results to return. Default: 50.")
|
|
3746
3745
|
}),
|
|
3747
3746
|
execute: async (input, { toolCallId }) => {
|
|
3748
3747
|
const { filePattern, searchTerm, contextLines, caseSensitive, maxResults } = input;
|
|
@@ -3909,7 +3908,7 @@ Do not use escape characters \\ in the string like \\n or \\" and others. Do not
|
|
|
3909
3908
|
inputSchema: zod.z.object({
|
|
3910
3909
|
command: zod.z.string().min(1).describe("The shell command to execute (e.g., ls -la, npm install)."),
|
|
3911
3910
|
cwd: zod.z.string().optional().describe("The working directory for the command (relative to <WorkingDirectory>). Default: <WorkingDirectory>."),
|
|
3912
|
-
timeout: zod.z.number().int().min(0).optional().default(12e4).describe("Timeout for the command execution in milliseconds. Default: 120000 ms.")
|
|
3911
|
+
timeout: zod.z.coerce.number().int().min(0).optional().default(12e4).describe("Timeout for the command execution in milliseconds. Default: 120000 ms.")
|
|
3913
3912
|
}),
|
|
3914
3913
|
execute: async (input, { toolCallId }) => {
|
|
3915
3914
|
const { command, cwd, timeout } = input;
|
|
@@ -4094,7 +4093,7 @@ Timeout: ${timeout}ms`;
|
|
|
4094
4093
|
description: POWER_TOOL_DESCRIPTIONS[POWER_TOOL_FETCH],
|
|
4095
4094
|
inputSchema: zod.z.object({
|
|
4096
4095
|
url: zod.z.string().describe("The URL to fetch."),
|
|
4097
|
-
timeout: zod.z.number().int().min(0).optional().default(6e4).describe("Timeout for the fetch operation in milliseconds. Default: 60000 ms."),
|
|
4096
|
+
timeout: zod.z.coerce.number().int().min(0).optional().default(6e4).describe("Timeout for the fetch operation in milliseconds. Default: 60000 ms."),
|
|
4098
4097
|
format: zod.z.enum(["markdown", "html", "raw"]).optional().default("markdown").describe(
|
|
4099
4098
|
'Format of the response: "markdown" (default, converts HTML to markdown), "html" (returns raw HTML), "raw" (fetches raw content via HTTP, ideal for API responses or raw files).'
|
|
4100
4099
|
)
|
|
@@ -4144,10 +4143,10 @@ Format: ${format}`;
|
|
|
4144
4143
|
inputSchema: zod.z.object({
|
|
4145
4144
|
query: zod.z.string().describe("Search query with Elasticsearch syntax. Use + for important terms."),
|
|
4146
4145
|
path: zod.z.string().optional().default(task.getTaskDir()).describe('Absolute path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
|
|
4147
|
-
allowTests:
|
|
4148
|
-
exact:
|
|
4149
|
-
maxResults: zod.z.number().optional().describe("Maximum number of results to return"),
|
|
4150
|
-
maxTokens: zod.z.number().optional().default(5e3).describe("Maximum number of tokens to return"),
|
|
4146
|
+
allowTests: coerceBoolean.optional().default(false).describe("Allow test files in search results"),
|
|
4147
|
+
exact: coerceBoolean.optional().default(false).describe("Perform exact search without tokenization (case-insensitive)"),
|
|
4148
|
+
maxResults: zod.z.coerce.number().optional().describe("Maximum number of results to return"),
|
|
4149
|
+
maxTokens: zod.z.coerce.number().optional().default(5e3).describe("Maximum number of tokens to return"),
|
|
4151
4150
|
language: zod.z.string().optional().describe("Limit search to files of a specific programming language")
|
|
4152
4151
|
}),
|
|
4153
4152
|
execute: async (input, { toolCallId }) => {
|
|
@@ -4259,7 +4258,7 @@ const createTodoToolset = (task, profile, promptContext) => {
|
|
|
4259
4258
|
items: zod.z.array(
|
|
4260
4259
|
zod.z.object({
|
|
4261
4260
|
name: zod.z.string().describe("The name of the todo item."),
|
|
4262
|
-
completed:
|
|
4261
|
+
completed: coerceBoolean.optional().default(false).describe("Whether the todo item is completed.")
|
|
4263
4262
|
})
|
|
4264
4263
|
).describe("An array of todo items."),
|
|
4265
4264
|
initialUserPrompt: zod.z.string().describe("The original user prompt that initiated the task.")
|
|
@@ -4313,7 +4312,7 @@ Items: ${JSON.stringify(items)}`;
|
|
|
4313
4312
|
description: TODO_TOOL_DESCRIPTIONS[TODO_TOOL_UPDATE_ITEM_COMPLETION],
|
|
4314
4313
|
inputSchema: zod.z.object({
|
|
4315
4314
|
name: zod.z.string().describe("The name of the todo item to update."),
|
|
4316
|
-
completed:
|
|
4315
|
+
completed: coerceBoolean.describe("The new completion status for the todo item.")
|
|
4317
4316
|
}),
|
|
4318
4317
|
execute: async (input, { toolCallId }) => {
|
|
4319
4318
|
const { name, completed } = input;
|
|
@@ -4378,8 +4377,8 @@ const createTasksToolset = (settings, task, profile, promptContext) => {
|
|
|
4378
4377
|
const listTasksTool = ai.tool({
|
|
4379
4378
|
description: TASKS_TOOL_DESCRIPTIONS[TASKS_TOOL_LIST_TASKS],
|
|
4380
4379
|
inputSchema: zod.z.object({
|
|
4381
|
-
offset: zod.z.number().optional().describe("The number of tasks to skip (for pagination)"),
|
|
4382
|
-
limit: zod.z.number().optional().describe("The maximum number of tasks to return"),
|
|
4380
|
+
offset: zod.z.coerce.number().optional().describe("The number of tasks to skip (for pagination)"),
|
|
4381
|
+
limit: zod.z.coerce.number().optional().describe("The maximum number of tasks to return"),
|
|
4383
4382
|
state: zod.z.string().optional().describe("Filter tasks by state (e.g., TODO, IN_PROGRESS, DONE)")
|
|
4384
4383
|
}),
|
|
4385
4384
|
execute: async (input, { toolCallId }) => {
|
|
@@ -4543,7 +4542,7 @@ const createTasksToolset = (settings, task, profile, promptContext) => {
|
|
|
4543
4542
|
),
|
|
4544
4543
|
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."),
|
|
4545
4544
|
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."),
|
|
4546
|
-
executeInBackground:
|
|
4545
|
+
executeInBackground: coerceBoolean.optional().default(false).describe("If true, the task will be created and executed in the background.")
|
|
4547
4546
|
}),
|
|
4548
4547
|
execute: async (input, { toolCallId }) => {
|
|
4549
4548
|
const { prompt, name, agentProfileId, modelId, mode = "agent", asSubtask = false, autonomyMode, worktree, executeAndWait, executeInBackground } = input;
|
|
@@ -4707,7 +4706,7 @@ Prompt: ${prompt}${executeAndWait ? "\nWait for completion: true" : "\nRun in ba
|
|
|
4707
4706
|
inputSchema: zod.z.object({
|
|
4708
4707
|
taskId: zod.z.string().describe("The ID of the task to search within"),
|
|
4709
4708
|
query: zod.z.string().describe("Search query with Elasticsearch syntax. Use + for important terms."),
|
|
4710
|
-
maxTokens: zod.z.number().optional().default(1e4).describe("Maximum number of tokens to return in the search results. Default: 10000")
|
|
4709
|
+
maxTokens: zod.z.coerce.number().optional().default(1e4).describe("Maximum number of tokens to return in the search results. Default: 10000")
|
|
4711
4710
|
}),
|
|
4712
4711
|
execute: async (input, { toolCallId }) => {
|
|
4713
4712
|
const { taskId, query, maxTokens } = input;
|
|
@@ -4784,7 +4783,7 @@ const createSearchParentTaskTool = (task, promptContext) => {
|
|
|
4784
4783
|
description: TASKS_TOOL_DESCRIPTIONS[TASKS_TOOL_SEARCH_PARENT_TASK],
|
|
4785
4784
|
inputSchema: zod.z.object({
|
|
4786
4785
|
query: zod.z.string().describe("Search query with Elasticsearch syntax. Use + for important terms."),
|
|
4787
|
-
maxTokens: zod.z.number().optional().default(1e4).describe("Maximum number of tokens to return in the search results. Default: 10000")
|
|
4786
|
+
maxTokens: zod.z.coerce.number().optional().default(1e4).describe("Maximum number of tokens to return in the search results. Default: 10000")
|
|
4788
4787
|
}),
|
|
4789
4788
|
execute: async ({ query, maxTokens }, { toolCallId }) => {
|
|
4790
4789
|
const parentTaskId = task.task.parentId;
|
|
@@ -4874,7 +4873,7 @@ const createAiderToolset = (task, profile, promptContext) => {
|
|
|
4874
4873
|
description: AIDER_TOOL_DESCRIPTIONS[AIDER_TOOL_ADD_CONTEXT_FILES],
|
|
4875
4874
|
inputSchema: zod.z.object({
|
|
4876
4875
|
paths: zod.z.array(zod.z.string()).describe('One or more file paths to add to context. Relative to task directory (e.g. "src/file.ts") or absolute (e.g. "/tmp/log.txt" for read-only).'),
|
|
4877
|
-
readOnly:
|
|
4876
|
+
readOnly: coerceBoolean.optional().describe("Whether the file(s) are read-only. Applies to all paths if true.")
|
|
4878
4877
|
}),
|
|
4879
4878
|
execute: async (input, { toolCallId }) => {
|
|
4880
4879
|
const { paths, readOnly = false } = input;
|
|
@@ -5103,7 +5102,7 @@ const createMemoryToolset = (task, profile, memoryManager, promptContext) => {
|
|
|
5103
5102
|
description: MEMORY_TOOL_DESCRIPTIONS[MEMORY_TOOL_RETRIEVE],
|
|
5104
5103
|
inputSchema: zod.z.object({
|
|
5105
5104
|
query: zod.z.string().describe("The search query to find relevant memories"),
|
|
5106
|
-
limit: zod.z.number().optional().default(3).describe("Maximum number of memories to retrieve (default: 3)")
|
|
5105
|
+
limit: zod.z.coerce.number().optional().default(3).describe("Maximum number of memories to retrieve (default: 3)")
|
|
5107
5106
|
}),
|
|
5108
5107
|
execute: async (input, { toolCallId }) => {
|
|
5109
5108
|
const { query, limit } = input;
|
|
@@ -5170,7 +5169,7 @@ Timestamp: ${new Date(memory.timestamp).toLocaleString()}`;
|
|
|
5170
5169
|
description: MEMORY_TOOL_DESCRIPTIONS[MEMORY_TOOL_LIST],
|
|
5171
5170
|
inputSchema: zod.z.object({
|
|
5172
5171
|
type: zod.z.enum(["task", "user-preference", "code-pattern"]).optional().describe("Filter by memory type"),
|
|
5173
|
-
limit: zod.z.number().optional().default(20).describe("Maximum number of memories to list (default: 20)")
|
|
5172
|
+
limit: zod.z.coerce.number().optional().default(20).describe("Maximum number of memories to list (default: 20)")
|
|
5174
5173
|
}),
|
|
5175
5174
|
execute: async (input, { toolCallId }) => {
|
|
5176
5175
|
const { type, limit } = input;
|
|
@@ -6594,14 +6593,16 @@ ${file.content}</content-with-line-numbers>
|
|
|
6594
6593
|
logger.debug("Adding file list for non-image files", {
|
|
6595
6594
|
files: nonImageFiles.map((f) => f.path)
|
|
6596
6595
|
});
|
|
6596
|
+
const hasReadOnlyFiles = nonImageFiles.some((file) => file.readOnly);
|
|
6597
6597
|
const fileList = nonImageFiles.map((file) => {
|
|
6598
|
-
return `- ${file.path}`;
|
|
6598
|
+
return `- ${file.path}${file.readOnly ? " (read-only)" : ""}`;
|
|
6599
6599
|
}).join("\n");
|
|
6600
|
+
const readOnlyNote = hasReadOnlyFiles ? "\n\nNote: Files marked as read-only must NOT be modified. Use them only for understanding context." : "";
|
|
6600
6601
|
messages.push({
|
|
6601
6602
|
role: "user",
|
|
6602
6603
|
content: `The following files are currently in the working context:
|
|
6603
6604
|
|
|
6604
|
-
${fileList}`
|
|
6605
|
+
${fileList}${readOnlyNote}`
|
|
6605
6606
|
});
|
|
6606
6607
|
messages.push({
|
|
6607
6608
|
role: "assistant",
|
|
@@ -6699,7 +6700,7 @@ ${fileList}`
|
|
|
6699
6700
|
const providerTools = await this.modelManager.getProviderTools(provider, model);
|
|
6700
6701
|
Object.assign(toolSet, providerTools);
|
|
6701
6702
|
if (this.extensionManager.isInitialized() && profile.useExtensionTools !== false) {
|
|
6702
|
-
const extensionTools = this.extensionManager.createExtensionToolset(task, mode, profile, toolSet, abortSignal);
|
|
6703
|
+
const extensionTools = this.extensionManager.createExtensionToolset(task, mode, profile, toolSet, approvalManager, abortSignal);
|
|
6703
6704
|
Object.assign(toolSet, extensionTools);
|
|
6704
6705
|
}
|
|
6705
6706
|
return this.wrapToolsWithHooks(task, profile, toolSet, abortSignal, promptContext);
|
|
@@ -7851,7 +7852,7 @@ ${fileList}`
|
|
|
7851
7852
|
const processToolResult = (toolResult) => {
|
|
7852
7853
|
const [serverName, toolName] = extractServerNameToolName(toolResult.toolName);
|
|
7853
7854
|
const toolPromptContext = extractPromptContextFromToolResult(toolResult.output) ?? promptContext;
|
|
7854
|
-
task.addToolMessage(toolResult.toolCallId, serverName, toolName, toolResult.input, JSON.stringify(toolResult.output),
|
|
7855
|
+
task.addToolMessage(toolResult.toolCallId, serverName, toolName, toolResult.input, JSON.stringify(toolResult.output), usageReport, toolPromptContext);
|
|
7855
7856
|
};
|
|
7856
7857
|
for (let i = 0; i < content.length; i++) {
|
|
7857
7858
|
let part = content[i];
|
|
@@ -8337,6 +8338,7 @@ class AgentProfileManager {
|
|
|
8337
8338
|
maxIterations: loadedProfile.maxIterations ?? DEFAULT_AGENT_PROFILE.maxIterations,
|
|
8338
8339
|
minTimeBetweenToolCalls: loadedProfile.minTimeBetweenToolCalls ?? DEFAULT_AGENT_PROFILE.minTimeBetweenToolCalls,
|
|
8339
8340
|
enabledServers: loadedProfile.enabledServers ?? [],
|
|
8341
|
+
disabledExtensionTools: loadedProfile.disabledExtensionTools ?? [],
|
|
8340
8342
|
customInstructions: loadedProfile.customInstructions ?? "",
|
|
8341
8343
|
toolApprovals: {
|
|
8342
8344
|
...loadedProfile.toolApprovals
|
|
@@ -9306,11 +9308,22 @@ const MergeWorktreeToMainSchema = zod.z.object({
|
|
|
9306
9308
|
targetBranch: zod.z.string().optional(),
|
|
9307
9309
|
commitMessage: zod.z.string().optional()
|
|
9308
9310
|
});
|
|
9309
|
-
const
|
|
9311
|
+
const SwitchToLocalWorkingModeSchema = zod.z.object({
|
|
9310
9312
|
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
9311
9313
|
taskId: zod.z.string().min(1, "Task id is required"),
|
|
9314
|
+
mergeBeforeSwitch: zod.z.boolean().optional(),
|
|
9312
9315
|
targetBranch: zod.z.string().optional()
|
|
9313
9316
|
});
|
|
9317
|
+
const SwitchToWorktreeWorkingModeSchema = zod.z.object({
|
|
9318
|
+
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
9319
|
+
taskId: zod.z.string().min(1, "Task id is required"),
|
|
9320
|
+
carryOverUncommittedChanges: zod.z.boolean().optional(),
|
|
9321
|
+
dropSourceChanges: zod.z.boolean().optional()
|
|
9322
|
+
});
|
|
9323
|
+
const LocalUncommittedFilesSchema = zod.z.object({
|
|
9324
|
+
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
9325
|
+
taskId: zod.z.string().min(1, "Task id is required")
|
|
9326
|
+
});
|
|
9314
9327
|
const ApplyUncommittedChangesSchema = zod.z.object({
|
|
9315
9328
|
projectDir: zod.z.string().min(1, "Project directory is required"),
|
|
9316
9329
|
taskId: zod.z.string().min(1, "Task id is required"),
|
|
@@ -9761,15 +9774,39 @@ class ProjectApi extends BaseApi {
|
|
|
9761
9774
|
})
|
|
9762
9775
|
);
|
|
9763
9776
|
router.post(
|
|
9764
|
-
"/project/
|
|
9777
|
+
"/project/switch-to-local-working-mode",
|
|
9765
9778
|
this.handleRequest(async (req, res) => {
|
|
9766
|
-
const parsed = this.validateRequest(
|
|
9779
|
+
const parsed = this.validateRequest(SwitchToLocalWorkingModeSchema, req.body, res);
|
|
9767
9780
|
if (!parsed) {
|
|
9768
9781
|
return;
|
|
9769
9782
|
}
|
|
9770
|
-
const { projectDir, taskId, targetBranch } = parsed;
|
|
9771
|
-
await this.eventsHandler.
|
|
9772
|
-
res.status(200).json({ message: "
|
|
9783
|
+
const { projectDir, taskId, mergeBeforeSwitch, targetBranch } = parsed;
|
|
9784
|
+
await this.eventsHandler.switchToLocalWorkingMode(projectDir, taskId, { mergeBeforeSwitch, targetBranch });
|
|
9785
|
+
res.status(200).json({ message: "Switched to local working mode" });
|
|
9786
|
+
})
|
|
9787
|
+
);
|
|
9788
|
+
router.post(
|
|
9789
|
+
"/project/switch-to-worktree-working-mode",
|
|
9790
|
+
this.handleRequest(async (req, res) => {
|
|
9791
|
+
const parsed = this.validateRequest(SwitchToWorktreeWorkingModeSchema, req.body, res);
|
|
9792
|
+
if (!parsed) {
|
|
9793
|
+
return;
|
|
9794
|
+
}
|
|
9795
|
+
const { projectDir, taskId, carryOverUncommittedChanges, dropSourceChanges } = parsed;
|
|
9796
|
+
await this.eventsHandler.switchToWorktreeWorkingMode(projectDir, taskId, { carryOverUncommittedChanges, dropSourceChanges });
|
|
9797
|
+
res.status(200).json({ message: "Switched to worktree working mode" });
|
|
9798
|
+
})
|
|
9799
|
+
);
|
|
9800
|
+
router.get(
|
|
9801
|
+
"/project/local-uncommitted-files",
|
|
9802
|
+
this.handleRequest(async (req, res) => {
|
|
9803
|
+
const parsed = this.validateRequest(LocalUncommittedFilesSchema, req.query, res);
|
|
9804
|
+
if (!parsed) {
|
|
9805
|
+
return;
|
|
9806
|
+
}
|
|
9807
|
+
const { projectDir, taskId } = parsed;
|
|
9808
|
+
const result = await this.eventsHandler.getLocalUncommittedFiles(projectDir, taskId);
|
|
9809
|
+
res.status(200).json(result);
|
|
9773
9810
|
})
|
|
9774
9811
|
);
|
|
9775
9812
|
router.post(
|
|
@@ -10713,6 +10750,9 @@ class TerminalApi extends BaseApi {
|
|
|
10713
10750
|
const GetInstalledExtensionsSchema = zod.z.object({
|
|
10714
10751
|
projectDir: zod.z.string().optional()
|
|
10715
10752
|
});
|
|
10753
|
+
const GetExtensionToolsInfoSchema = zod.z.object({
|
|
10754
|
+
projectDir: zod.z.string().optional()
|
|
10755
|
+
});
|
|
10716
10756
|
const GetAvailableExtensionsSchema = zod.z.object({
|
|
10717
10757
|
repositories: zod.z.string().optional(),
|
|
10718
10758
|
// Comma-separated URLs
|
|
@@ -10751,6 +10791,18 @@ class ExtensionsApi extends BaseApi {
|
|
|
10751
10791
|
res.status(200).json(extensions);
|
|
10752
10792
|
})
|
|
10753
10793
|
);
|
|
10794
|
+
router.get(
|
|
10795
|
+
"/extensions/tools-info",
|
|
10796
|
+
this.handleRequest(async (req, res) => {
|
|
10797
|
+
const parsed = this.validateRequest(GetExtensionToolsInfoSchema, req.query, res);
|
|
10798
|
+
if (!parsed) {
|
|
10799
|
+
return;
|
|
10800
|
+
}
|
|
10801
|
+
const { projectDir } = parsed;
|
|
10802
|
+
const toolsInfo = this.eventsHandler.getExtensionToolsInfo(projectDir);
|
|
10803
|
+
res.status(200).json(toolsInfo);
|
|
10804
|
+
})
|
|
10805
|
+
);
|
|
10754
10806
|
router.get(
|
|
10755
10807
|
"/extensions/available",
|
|
10756
10808
|
this.handleRequest(async (req, res) => {
|
|
@@ -15646,7 +15698,7 @@ const smartCompactMessages = async (messages, protectedMessageCount = 10, compac
|
|
|
15646
15698
|
result = compactFileReads(result, protectedMessageCount, compactionLevel);
|
|
15647
15699
|
result = removeObsoleteSearches(result, protectedMessageCount, compactionLevel);
|
|
15648
15700
|
result = compactSemanticSearches(result, protectedMessageCount, compactionLevel);
|
|
15649
|
-
result =
|
|
15701
|
+
result = compactBashOutputs(result, protectedMessageCount, compactionLevel);
|
|
15650
15702
|
result = redactFetchOutputs(result, protectedMessageCount);
|
|
15651
15703
|
result = await truncateNonPowerToolResults(result, protectedMessageCount, compactionLevel);
|
|
15652
15704
|
result = mergeConsecutiveAssistantMessages(result);
|
|
@@ -16012,8 +16064,9 @@ const compactSemanticSearches = (messages, protectedMessageCount = 10, compactio
|
|
|
16012
16064
|
}
|
|
16013
16065
|
return messages;
|
|
16014
16066
|
};
|
|
16015
|
-
const
|
|
16067
|
+
const compactBashOutputs = (messages, protectedMessageCount = 10, compactionLevel = 1) => {
|
|
16016
16068
|
const protectedStart = getProtectedStartIndex(messages, protectedMessageCount);
|
|
16069
|
+
logger.info(`Compacting bash outputs at level ${compactionLevel}`);
|
|
16017
16070
|
const bashCommands = /* @__PURE__ */ new Map();
|
|
16018
16071
|
for (let i = 0; i < protectedStart; i++) {
|
|
16019
16072
|
const msg = messages[i];
|
|
@@ -16079,6 +16132,23 @@ const deduplicateBash = (messages, protectedMessageCount = 10, compactionLevel =
|
|
|
16079
16132
|
};
|
|
16080
16133
|
continue;
|
|
16081
16134
|
}
|
|
16135
|
+
if (part.output.type === "json" || part.output.type === "error-json") {
|
|
16136
|
+
const value = part.output.value;
|
|
16137
|
+
if (typeof value === "object" && value !== null) {
|
|
16138
|
+
const obj = value;
|
|
16139
|
+
const stdout = typeof obj.stdout === "string" ? obj.stdout : "";
|
|
16140
|
+
const stderr = typeof obj.stderr === "string" ? obj.stderr : "";
|
|
16141
|
+
const redactionMessage = "<output redacted due to compaction, run again if output is needed>";
|
|
16142
|
+
const redactionThreshold = compactionLevel >= 2 ? 0 : 30;
|
|
16143
|
+
if (stdout.length > redactionThreshold) {
|
|
16144
|
+
obj.stdout = redactionMessage;
|
|
16145
|
+
}
|
|
16146
|
+
if (stderr.length > redactionThreshold) {
|
|
16147
|
+
obj.stderr = redactionMessage;
|
|
16148
|
+
}
|
|
16149
|
+
}
|
|
16150
|
+
continue;
|
|
16151
|
+
}
|
|
16082
16152
|
if (part.output.type !== "text") {
|
|
16083
16153
|
continue;
|
|
16084
16154
|
}
|
|
@@ -16819,6 +16889,7 @@ class Task {
|
|
|
16819
16889
|
provider: this.task.provider || profile.provider,
|
|
16820
16890
|
model: this.task.model || profile.model
|
|
16821
16891
|
});
|
|
16892
|
+
this.smartCompactionLevel = 1;
|
|
16822
16893
|
const agentMessages = await this.agent.runAgent(
|
|
16823
16894
|
this,
|
|
16824
16895
|
profile,
|
|
@@ -17917,7 +17988,6 @@ ${contentText}</agent-response>`;
|
|
|
17917
17988
|
lastAgentProviderMetadata: null
|
|
17918
17989
|
});
|
|
17919
17990
|
}
|
|
17920
|
-
this.smartCompactionLevel = CompactionLevel.One;
|
|
17921
17991
|
this.contextManager.clearMessages(true, createSnapshot);
|
|
17922
17992
|
await this.runCommand("clear", addToHistory);
|
|
17923
17993
|
this.eventManager.sendClearTask(this.project.baseDir, this.taskId, true, false);
|
|
@@ -18326,10 +18396,20 @@ ${contentText}</agent-response>`;
|
|
|
18326
18396
|
await this.contextManager.backupContext();
|
|
18327
18397
|
const messagesSinceLastCompaction = contextMessages.length - this.lastSmartCompactionMessageCount;
|
|
18328
18398
|
if (messagesSinceLastCompaction <= 3) {
|
|
18399
|
+
logger.info("Increasing compaction level to aggressive due to low message count since last compaction.", {
|
|
18400
|
+
messagesSinceLastCompaction,
|
|
18401
|
+
smartCompactionLevel: this.smartCompactionLevel
|
|
18402
|
+
});
|
|
18329
18403
|
this.smartCompactionLevel = Math.min(this.smartCompactionLevel + 1, CompactionLevel.Three);
|
|
18330
|
-
} else if (messagesSinceLastCompaction > 5) {
|
|
18331
|
-
|
|
18404
|
+
} else if (messagesSinceLastCompaction > 5 && this.smartCompactionLevel > CompactionLevel.One) {
|
|
18405
|
+
logger.info("Decreasing compaction level to mild due to high message count since last compaction.", {
|
|
18406
|
+
messagesSinceLastCompaction
|
|
18407
|
+
});
|
|
18408
|
+
this.smartCompactionLevel = Math.max(this.smartCompactionLevel - 1, CompactionLevel.One);
|
|
18332
18409
|
}
|
|
18410
|
+
logger.debug("Current compaction level:", {
|
|
18411
|
+
smartCompactionLevel: this.smartCompactionLevel
|
|
18412
|
+
});
|
|
18333
18413
|
const compactedMessages = await smartCompactMessages(contextMessages, 10, this.smartCompactionLevel);
|
|
18334
18414
|
this.lastSmartCompactionMessageCount = compactedMessages.length;
|
|
18335
18415
|
this.contextManager.setContextMessages(compactedMessages);
|
|
@@ -18345,7 +18425,7 @@ ${contentText}</agent-response>`;
|
|
|
18345
18425
|
if (!contextMessages) {
|
|
18346
18426
|
contextMessages = await this.contextManager.getContextMessages();
|
|
18347
18427
|
}
|
|
18348
|
-
const userMessage = contextMessages
|
|
18428
|
+
const userMessage = contextMessages.find((msg) => msg.role === MessageRole.User);
|
|
18349
18429
|
if (!userMessage) {
|
|
18350
18430
|
this.addLogMessage("warning", "No conversation to compact.");
|
|
18351
18431
|
return;
|
|
@@ -19025,46 +19105,96 @@ Only answer with the commit message, nothing else.`,
|
|
|
19025
19105
|
await this.sendUpdatedFilesUpdated();
|
|
19026
19106
|
await this.sendWorktreeIntegrationStatusUpdated();
|
|
19027
19107
|
}
|
|
19028
|
-
async
|
|
19029
|
-
if (!this.task.worktree) {
|
|
19108
|
+
async switchToLocalWorkingMode(options) {
|
|
19109
|
+
if (options?.mergeBeforeSwitch && !this.task.worktree) {
|
|
19030
19110
|
throw new Error("No worktree exists for this task");
|
|
19031
19111
|
}
|
|
19032
|
-
logger.info("
|
|
19112
|
+
logger.info("Switching to local working mode", {
|
|
19033
19113
|
baseDir: this.project.baseDir,
|
|
19034
|
-
taskId: this.taskId
|
|
19114
|
+
taskId: this.taskId,
|
|
19115
|
+
mergeBeforeSwitch: options?.mergeBeforeSwitch ?? false
|
|
19035
19116
|
});
|
|
19036
19117
|
await this.waitForCurrentPromptToFinish();
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
this.
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19118
|
+
if (options?.mergeBeforeSwitch && this.task.worktree) {
|
|
19119
|
+
try {
|
|
19120
|
+
const effectiveTargetBranch = options.targetBranch || await this.worktreeManager.getProjectMainBranch(this.project.baseDir);
|
|
19121
|
+
this.addLogMessage("loading", `Merging worktree to ${effectiveTargetBranch} branch and switching to local mode...`);
|
|
19122
|
+
const settings = this.store.getSettings();
|
|
19123
|
+
const symlinkFolders = settings.taskSettings.worktreeSymlinkFolders || [];
|
|
19124
|
+
const mergeState = await this.worktreeManager.mergeWorktreeToMainWithUncommitted(
|
|
19125
|
+
this.project.baseDir,
|
|
19126
|
+
this.task.id,
|
|
19127
|
+
this.task.worktree.path,
|
|
19128
|
+
false,
|
|
19129
|
+
this.task.name || `Task ${this.taskId} changes`,
|
|
19130
|
+
options.targetBranch,
|
|
19131
|
+
symlinkFolders
|
|
19132
|
+
);
|
|
19133
|
+
await this.saveTask({ lastMergeState: mergeState });
|
|
19134
|
+
this.addLogMessage("info", `Successfully merged worktree to ${effectiveTargetBranch} branch`, true);
|
|
19135
|
+
} catch (error) {
|
|
19136
|
+
logger.error("Failed to merge worktree and switch to local:", { error });
|
|
19137
|
+
const isConflict = error instanceof GitError && (error.gitOutput?.toLowerCase().includes("resolve all conflicts") || error.message?.toLowerCase().includes("conflicts must be resolved first") || error.gitOutput?.toLowerCase().includes("conflicts must be resolved first"));
|
|
19138
|
+
this.addLogMessage(
|
|
19139
|
+
"error",
|
|
19140
|
+
isConflict ? "worktree.mergeConflicts" : error instanceof GitError ? error.getErrorDetails() : `Failed to merge worktree: ${error instanceof Error ? error.message : String(error)}`,
|
|
19141
|
+
true,
|
|
19142
|
+
void 0,
|
|
19143
|
+
isConflict ? ["rebase-worktree"] : void 0
|
|
19144
|
+
);
|
|
19145
|
+
await this.sendUpdatedFilesUpdated();
|
|
19146
|
+
await this.sendWorktreeIntegrationStatusUpdated();
|
|
19147
|
+
throw error;
|
|
19148
|
+
}
|
|
19067
19149
|
}
|
|
19150
|
+
await this.updateTask({ workingMode: "local" });
|
|
19151
|
+
}
|
|
19152
|
+
async switchToWorktreeWorkingMode(options) {
|
|
19153
|
+
logger.info("Switching to worktree working mode", {
|
|
19154
|
+
baseDir: this.project.baseDir,
|
|
19155
|
+
taskId: this.taskId,
|
|
19156
|
+
carryOverUncommittedChanges: options?.carryOverUncommittedChanges ?? false,
|
|
19157
|
+
dropSourceChanges: options?.dropSourceChanges ?? true
|
|
19158
|
+
});
|
|
19159
|
+
await this.waitForCurrentPromptToFinish();
|
|
19160
|
+
let stashId = null;
|
|
19161
|
+
const settings = this.store.getSettings();
|
|
19162
|
+
const symlinkFolders = settings.taskSettings.worktreeSymlinkFolders || [];
|
|
19163
|
+
if (options?.carryOverUncommittedChanges) {
|
|
19164
|
+
const timestamp = Date.now();
|
|
19165
|
+
const shortId = this.taskId.length > 24 ? this.taskId.substring(24) : this.taskId;
|
|
19166
|
+
stashId = `local-${shortId}-to-worktree-${timestamp}`;
|
|
19167
|
+
try {
|
|
19168
|
+
const stashResult = await this.worktreeManager.stashUncommittedChanges(
|
|
19169
|
+
stashId,
|
|
19170
|
+
this.project.baseDir,
|
|
19171
|
+
"Uncommitted changes to carry over to worktree",
|
|
19172
|
+
symlinkFolders
|
|
19173
|
+
);
|
|
19174
|
+
if (!stashResult) {
|
|
19175
|
+
stashId = null;
|
|
19176
|
+
}
|
|
19177
|
+
} catch (error) {
|
|
19178
|
+
logger.error("Failed to stash uncommitted changes before worktree switch:", { error });
|
|
19179
|
+
stashId = null;
|
|
19180
|
+
}
|
|
19181
|
+
}
|
|
19182
|
+
await this.updateTask({ workingMode: "worktree" });
|
|
19183
|
+
if (stashId && this.task.worktree) {
|
|
19184
|
+
try {
|
|
19185
|
+
await this.worktreeManager.applyStash(this.task.worktree.path, stashId);
|
|
19186
|
+
if (!options?.dropSourceChanges) {
|
|
19187
|
+
await this.worktreeManager.applyStash(this.project.baseDir, stashId);
|
|
19188
|
+
}
|
|
19189
|
+
await this.worktreeManager.dropStash(this.project.baseDir, stashId);
|
|
19190
|
+
} catch (error) {
|
|
19191
|
+
logger.error("Failed to apply stashed changes to worktree:", { error });
|
|
19192
|
+
}
|
|
19193
|
+
}
|
|
19194
|
+
void this.sendUpdatedFilesUpdated();
|
|
19195
|
+
}
|
|
19196
|
+
async getLocalUncommittedFiles() {
|
|
19197
|
+
return await this.worktreeManager.getUncommittedFiles(this.project.baseDir);
|
|
19068
19198
|
}
|
|
19069
19199
|
async applyUncommittedChanges(targetBranch) {
|
|
19070
19200
|
if (!this.task.worktree) {
|
|
@@ -20876,132 +21006,6 @@ const anthropicCompatibleProviderStrategy = {
|
|
|
20876
21006
|
// Cache control
|
|
20877
21007
|
getCacheControl: getAnthropicCacheControl
|
|
20878
21008
|
};
|
|
20879
|
-
const loadAuggieSdk = async () => import("@augmentcode/auggie-sdk");
|
|
20880
|
-
const AUGGIE_MODELS = [
|
|
20881
|
-
{
|
|
20882
|
-
id: "claude-haiku-4-5",
|
|
20883
|
-
maxInputTokens: 2e5,
|
|
20884
|
-
maxOutputTokensLimit: 8192
|
|
20885
|
-
},
|
|
20886
|
-
{
|
|
20887
|
-
id: "claude-sonnet-4",
|
|
20888
|
-
maxInputTokens: 2e5,
|
|
20889
|
-
maxOutputTokensLimit: 16384
|
|
20890
|
-
},
|
|
20891
|
-
{
|
|
20892
|
-
id: "claude-sonnet-4-5",
|
|
20893
|
-
maxInputTokens: 2e5,
|
|
20894
|
-
maxOutputTokensLimit: 16384
|
|
20895
|
-
},
|
|
20896
|
-
{
|
|
20897
|
-
id: "claude-opus-4-5",
|
|
20898
|
-
maxInputTokens: 2e5,
|
|
20899
|
-
maxOutputTokensLimit: 32768
|
|
20900
|
-
},
|
|
20901
|
-
{
|
|
20902
|
-
id: "claude-opus-4-6",
|
|
20903
|
-
maxInputTokens: 2e5,
|
|
20904
|
-
maxOutputTokensLimit: 32768
|
|
20905
|
-
},
|
|
20906
|
-
{
|
|
20907
|
-
id: "claude-opus-4-7",
|
|
20908
|
-
maxInputTokens: 2e5,
|
|
20909
|
-
maxOutputTokensLimit: 32768
|
|
20910
|
-
},
|
|
20911
|
-
{ id: "gpt-5-1", maxInputTokens: 2e5, maxOutputTokensLimit: 16384 },
|
|
20912
|
-
{ id: "gpt-5-2", maxInputTokens: 2e5, maxOutputTokensLimit: 16384 },
|
|
20913
|
-
{ id: "gpt-5-4", maxInputTokens: 2e5, maxOutputTokensLimit: 16384 }
|
|
20914
|
-
];
|
|
20915
|
-
const loadAuggieModels = async (profile, _settings) => {
|
|
20916
|
-
if (!isAuggieProvider(profile.provider)) {
|
|
20917
|
-
return {
|
|
20918
|
-
models: [],
|
|
20919
|
-
success: false
|
|
20920
|
-
};
|
|
20921
|
-
}
|
|
20922
|
-
const models = AUGGIE_MODELS.map((model) => ({
|
|
20923
|
-
id: model.id,
|
|
20924
|
-
providerId: profile.id,
|
|
20925
|
-
maxInputTokens: model.maxInputTokens,
|
|
20926
|
-
maxOutputTokensLimit: model.maxOutputTokensLimit
|
|
20927
|
-
}));
|
|
20928
|
-
logger.info(`Loaded ${models.length} Auggie models for profile ${profile.id}`);
|
|
20929
|
-
return { models, success: true };
|
|
20930
|
-
};
|
|
20931
|
-
const hasAuggieEnvVars = (settings) => {
|
|
20932
|
-
if (getEffectiveEnvironmentVariable("AUGMENT_API_TOKEN", settings, void 0)?.value && getEffectiveEnvironmentVariable("AUGMENT_API_URL", settings, void 0)?.value) {
|
|
20933
|
-
return true;
|
|
20934
|
-
}
|
|
20935
|
-
const auggieSessionFile = path.join(os.homedir(), ".augment", "session.json");
|
|
20936
|
-
if (findExecutableInPath("auggie") && fs$1.existsSync(auggieSessionFile)) {
|
|
20937
|
-
return true;
|
|
20938
|
-
}
|
|
20939
|
-
return false;
|
|
20940
|
-
};
|
|
20941
|
-
const getAuggieAiderMapping = (provider, modelId) => {
|
|
20942
|
-
const auggieProvider = provider.provider;
|
|
20943
|
-
const envVars = {};
|
|
20944
|
-
if (auggieProvider.apiKey) {
|
|
20945
|
-
envVars.AUGMENT_API_TOKEN = auggieProvider.apiKey;
|
|
20946
|
-
}
|
|
20947
|
-
if (auggieProvider.apiUrl) {
|
|
20948
|
-
envVars.AUGMENT_API_URL = auggieProvider.apiUrl;
|
|
20949
|
-
}
|
|
20950
|
-
return {
|
|
20951
|
-
modelName: `auggie/${modelId}`,
|
|
20952
|
-
environmentVariables: envVars
|
|
20953
|
-
};
|
|
20954
|
-
};
|
|
20955
|
-
const createAuggieLlm = async (profile, model, settings, projectDir) => {
|
|
20956
|
-
const provider = profile.provider;
|
|
20957
|
-
let apiKey = provider.apiKey;
|
|
20958
|
-
let apiUrl = provider.apiUrl;
|
|
20959
|
-
if (!apiKey) {
|
|
20960
|
-
const effectiveVar = getEffectiveEnvironmentVariable("AUGMENT_API_TOKEN", settings, projectDir);
|
|
20961
|
-
if (effectiveVar) {
|
|
20962
|
-
apiKey = effectiveVar.value;
|
|
20963
|
-
logger.debug(`Loaded AUGMENT_API_TOKEN from ${effectiveVar.source}`);
|
|
20964
|
-
}
|
|
20965
|
-
}
|
|
20966
|
-
if (!apiUrl) {
|
|
20967
|
-
const effectiveUrlVar = getEffectiveEnvironmentVariable("AUGMENT_API_URL", settings, projectDir);
|
|
20968
|
-
if (effectiveUrlVar) {
|
|
20969
|
-
apiUrl = effectiveUrlVar.value;
|
|
20970
|
-
logger.debug(`Loaded AUGMENT_API_URL from ${effectiveUrlVar.source}`);
|
|
20971
|
-
}
|
|
20972
|
-
}
|
|
20973
|
-
if (apiKey && !apiUrl) {
|
|
20974
|
-
throw new Error("API URL is required when API key is provided.");
|
|
20975
|
-
}
|
|
20976
|
-
const { AugmentLanguageModel, resolveAugmentCredentials } = await loadAuggieSdk();
|
|
20977
|
-
const AugmentLanguageModelCtor = AugmentLanguageModel;
|
|
20978
|
-
if (apiKey && apiUrl) {
|
|
20979
|
-
return new AugmentLanguageModelCtor(model.id, {
|
|
20980
|
-
apiKey,
|
|
20981
|
-
apiUrl
|
|
20982
|
-
});
|
|
20983
|
-
} else {
|
|
20984
|
-
const credentials = await resolveAugmentCredentials();
|
|
20985
|
-
return new AugmentLanguageModelCtor(model.id, credentials);
|
|
20986
|
-
}
|
|
20987
|
-
};
|
|
20988
|
-
const getAuggieUsageReport = (_task, _provider, model) => {
|
|
20989
|
-
return {
|
|
20990
|
-
model: model.id,
|
|
20991
|
-
sentTokens: 0,
|
|
20992
|
-
receivedTokens: 0,
|
|
20993
|
-
messageCost: 0,
|
|
20994
|
-
agentTotalCost: 0
|
|
20995
|
-
};
|
|
20996
|
-
};
|
|
20997
|
-
const auggieProviderStrategy = {
|
|
20998
|
-
createLlm: createAuggieLlm,
|
|
20999
|
-
getUsageReport: getAuggieUsageReport,
|
|
21000
|
-
loadModels: loadAuggieModels,
|
|
21001
|
-
hasEnvVars: hasAuggieEnvVars,
|
|
21002
|
-
getAiderMapping: getAuggieAiderMapping,
|
|
21003
|
-
getModelInfo: getDefaultModelInfo
|
|
21004
|
-
};
|
|
21005
21009
|
const extractResourceNameFromEndpoint = (endpoint) => {
|
|
21006
21010
|
try {
|
|
21007
21011
|
const url = new URL(endpoint);
|
|
@@ -21427,199 +21431,6 @@ const cerebrasProviderStrategy = {
|
|
|
21427
21431
|
getAiderMapping: getCerebrasAiderMapping,
|
|
21428
21432
|
getModelInfo: getDefaultModelInfo
|
|
21429
21433
|
};
|
|
21430
|
-
const loadClaudeAgentSdkModels = async (profile, _settings) => {
|
|
21431
|
-
if (!isClaudeAgentSdkProvider(profile.provider)) {
|
|
21432
|
-
return {
|
|
21433
|
-
models: [],
|
|
21434
|
-
success: false
|
|
21435
|
-
};
|
|
21436
|
-
}
|
|
21437
|
-
try {
|
|
21438
|
-
const models = [
|
|
21439
|
-
{
|
|
21440
|
-
id: "haiku",
|
|
21441
|
-
providerId: profile.id,
|
|
21442
|
-
maxInputTokens: 2e5,
|
|
21443
|
-
maxOutputTokensLimit: 64e3
|
|
21444
|
-
},
|
|
21445
|
-
{
|
|
21446
|
-
id: "sonnet",
|
|
21447
|
-
providerId: profile.id,
|
|
21448
|
-
maxInputTokens: 2e5,
|
|
21449
|
-
maxOutputTokens: 64e3
|
|
21450
|
-
},
|
|
21451
|
-
{
|
|
21452
|
-
id: "opus",
|
|
21453
|
-
providerId: profile.id,
|
|
21454
|
-
maxInputTokens: 2e5,
|
|
21455
|
-
maxOutputTokensLimit: 64e3
|
|
21456
|
-
}
|
|
21457
|
-
];
|
|
21458
|
-
logger.info(`Loaded ${models.length} Claude Agent SDK models for profile ${profile.id}`);
|
|
21459
|
-
return { models, success: true };
|
|
21460
|
-
} catch (error) {
|
|
21461
|
-
const errorMsg = typeof error === "string" ? error : error instanceof Error ? error.message : "Unknown error loading Claude Agent SDK models";
|
|
21462
|
-
logger.error("Error loading Claude Agent SDK models:", error);
|
|
21463
|
-
return { models: [], success: false, error: errorMsg };
|
|
21464
|
-
}
|
|
21465
|
-
};
|
|
21466
|
-
const hasClaudeAgentSdkEnvVars = () => {
|
|
21467
|
-
return findExecutableInPath("claude") !== null;
|
|
21468
|
-
};
|
|
21469
|
-
const getClaudeAgentSdkAiderMapping = (_provider, modelId) => {
|
|
21470
|
-
return {
|
|
21471
|
-
environmentVariables: {},
|
|
21472
|
-
modelName: `claude-agent-sdk/${modelId}`
|
|
21473
|
-
};
|
|
21474
|
-
};
|
|
21475
|
-
const normalizeAiSdkToolSet = (toolSet) => {
|
|
21476
|
-
const normalizedToolSet = {};
|
|
21477
|
-
for (const [toolName, toolDefinition] of Object.entries(toolSet)) {
|
|
21478
|
-
let normalizedTool = { ...toolDefinition };
|
|
21479
|
-
const inputSchema = toolDefinition.inputSchema;
|
|
21480
|
-
if (inputSchema && typeof inputSchema === "object" && "jsonSchema" in inputSchema) {
|
|
21481
|
-
const jsonSchemaObj = inputSchema.jsonSchema;
|
|
21482
|
-
const schema = typeof jsonSchemaObj === "function" ? jsonSchemaObj() : jsonSchemaObj;
|
|
21483
|
-
const zodShape = jsonSchemaToZod.JSONSchemaToZod.convert(schema);
|
|
21484
|
-
normalizedTool = {
|
|
21485
|
-
...toolDefinition,
|
|
21486
|
-
inputSchema: zodShape
|
|
21487
|
-
};
|
|
21488
|
-
logger.debug(`Converted JSONSchema to Zod for tool: ${toolName}`);
|
|
21489
|
-
}
|
|
21490
|
-
if (toolName === `${AIDER_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${AIDER_TOOL_RUN_PROMPT}`) {
|
|
21491
|
-
const originalExecute = normalizedTool.execute;
|
|
21492
|
-
if (!originalExecute) {
|
|
21493
|
-
normalizedToolSet[toolName] = normalizedTool;
|
|
21494
|
-
continue;
|
|
21495
|
-
}
|
|
21496
|
-
normalizedToolSet[toolName] = {
|
|
21497
|
-
...normalizedTool,
|
|
21498
|
-
execute: async (args, options) => {
|
|
21499
|
-
const result = await originalExecute(args, options);
|
|
21500
|
-
if (result && typeof result === "object") {
|
|
21501
|
-
delete result.responses;
|
|
21502
|
-
}
|
|
21503
|
-
return result;
|
|
21504
|
-
}
|
|
21505
|
-
};
|
|
21506
|
-
} else if (toolName === `${SUBAGENTS_TOOL_GROUP_NAME}${TOOL_GROUP_NAME_SEPARATOR}${SUBAGENTS_TOOL_RUN_TASK}`) {
|
|
21507
|
-
const originalExecute = normalizedTool.execute;
|
|
21508
|
-
if (!originalExecute) {
|
|
21509
|
-
normalizedToolSet[toolName] = normalizedTool;
|
|
21510
|
-
continue;
|
|
21511
|
-
}
|
|
21512
|
-
normalizedToolSet[toolName] = {
|
|
21513
|
-
...normalizedTool,
|
|
21514
|
-
execute: async (args, options) => {
|
|
21515
|
-
const result = await originalExecute(args, options);
|
|
21516
|
-
if (result && typeof result === "object") {
|
|
21517
|
-
try {
|
|
21518
|
-
const messages = result.messages;
|
|
21519
|
-
if (Array.isArray(messages) && messages.length > 0) {
|
|
21520
|
-
const lastMessage = messages[messages.length - 1];
|
|
21521
|
-
return {
|
|
21522
|
-
messages: [lastMessage],
|
|
21523
|
-
promptContext: result.promptContext
|
|
21524
|
-
};
|
|
21525
|
-
}
|
|
21526
|
-
} catch (error) {
|
|
21527
|
-
logger.warn("Failed to optimize subagent result:", error);
|
|
21528
|
-
}
|
|
21529
|
-
}
|
|
21530
|
-
return result;
|
|
21531
|
-
}
|
|
21532
|
-
};
|
|
21533
|
-
} else {
|
|
21534
|
-
normalizedToolSet[toolName] = normalizedTool;
|
|
21535
|
-
}
|
|
21536
|
-
}
|
|
21537
|
-
return normalizedToolSet;
|
|
21538
|
-
};
|
|
21539
|
-
const createClaudeAgentSdkLlm = (_profile, model, _settings, _projectDir, toolSet, systemPrompt, providerMetadata) => {
|
|
21540
|
-
const settings = {
|
|
21541
|
-
env: {
|
|
21542
|
-
// setting MAX_MCP_OUTPUT_TOKENS to a high number to avoid errors
|
|
21543
|
-
MAX_MCP_OUTPUT_TOKENS: "9999999"
|
|
21544
|
-
},
|
|
21545
|
-
// for now only tools from AiderDesk are allowed
|
|
21546
|
-
disallowedTools: [
|
|
21547
|
-
"AskUserQuestion",
|
|
21548
|
-
"Bash",
|
|
21549
|
-
"TaskOutput",
|
|
21550
|
-
"Edit",
|
|
21551
|
-
"EnterPlanMode",
|
|
21552
|
-
"ExitPlanMode",
|
|
21553
|
-
"Glob",
|
|
21554
|
-
"Grep",
|
|
21555
|
-
"KillShell",
|
|
21556
|
-
"MCPSearch",
|
|
21557
|
-
"NotebookEdit",
|
|
21558
|
-
"Read",
|
|
21559
|
-
"Skill",
|
|
21560
|
-
"Task",
|
|
21561
|
-
"TaskCreate",
|
|
21562
|
-
"TaskGet",
|
|
21563
|
-
"TaskList",
|
|
21564
|
-
"TaskUpdate",
|
|
21565
|
-
"TodoWrite",
|
|
21566
|
-
"WebFetch",
|
|
21567
|
-
"WebSearch",
|
|
21568
|
-
"Write",
|
|
21569
|
-
"LSP"
|
|
21570
|
-
]
|
|
21571
|
-
};
|
|
21572
|
-
if (providerMetadata && typeof providerMetadata === "object" && "claude-code" in providerMetadata) {
|
|
21573
|
-
const metadata = providerMetadata["claude-code"] || {};
|
|
21574
|
-
settings.resume = metadata.sessionId;
|
|
21575
|
-
}
|
|
21576
|
-
if (!isDev() && isElectron()) {
|
|
21577
|
-
settings.pathToClaudeCodeExecutable = CLAUDE_CODE_EXECUTABLE_PATH;
|
|
21578
|
-
}
|
|
21579
|
-
if (toolSet) {
|
|
21580
|
-
logger.debug(`Adding ${Object.keys(toolSet).length} tools to Claude Agent SDK`, {
|
|
21581
|
-
tools: Object.keys(toolSet)
|
|
21582
|
-
});
|
|
21583
|
-
settings.aiSdkTools = normalizeAiSdkToolSet(toolSet);
|
|
21584
|
-
settings.allowedTools = ["mcp__ai-sdk"];
|
|
21585
|
-
} else {
|
|
21586
|
-
settings.allowedTools = [];
|
|
21587
|
-
}
|
|
21588
|
-
if (systemPrompt) {
|
|
21589
|
-
settings.systemPrompt = systemPrompt;
|
|
21590
|
-
}
|
|
21591
|
-
return aiSdkProviderClaudeCode.claudeCode(model.id, settings);
|
|
21592
|
-
};
|
|
21593
|
-
const getClaudeAgentSdkUsageReport = (task, provider, model, _usage, providerMetadata) => {
|
|
21594
|
-
const data = providerMetadata["claude-code"] || {};
|
|
21595
|
-
const usage = data.lastMessageRawUsage || data.rawUsage || {};
|
|
21596
|
-
logger.debug("Claude Agent SDK usage:", { usage: _usage, providerMetadata });
|
|
21597
|
-
const sentTokens = usage.input_tokens || 0;
|
|
21598
|
-
const receivedTokens = usage.output_tokens || 0;
|
|
21599
|
-
const cacheWriteTokens = usage.cache_creation_input_tokens || 0;
|
|
21600
|
-
const cacheReadTokens = usage.cache_read_input_tokens || 0;
|
|
21601
|
-
const messageCost = calculateCost(model, sentTokens, receivedTokens, cacheReadTokens);
|
|
21602
|
-
return {
|
|
21603
|
-
model: `${provider.id}/${model.id}`,
|
|
21604
|
-
sentTokens: sentTokens + cacheReadTokens,
|
|
21605
|
-
receivedTokens: receivedTokens + cacheWriteTokens,
|
|
21606
|
-
messageCost,
|
|
21607
|
-
agentTotalCost: task.task.agentTotalCost + messageCost
|
|
21608
|
-
};
|
|
21609
|
-
};
|
|
21610
|
-
const getClaudeAgentSdkProviderParameters = () => {
|
|
21611
|
-
return {
|
|
21612
|
-
system: void 0
|
|
21613
|
-
};
|
|
21614
|
-
};
|
|
21615
|
-
const claudeAgentSdkProviderStrategy = {
|
|
21616
|
-
createLlm: createClaudeAgentSdkLlm,
|
|
21617
|
-
getUsageReport: getClaudeAgentSdkUsageReport,
|
|
21618
|
-
loadModels: loadClaudeAgentSdkModels,
|
|
21619
|
-
hasEnvVars: hasClaudeAgentSdkEnvVars,
|
|
21620
|
-
getAiderMapping: getClaudeAgentSdkAiderMapping,
|
|
21621
|
-
getProviderParameters: getClaudeAgentSdkProviderParameters
|
|
21622
|
-
};
|
|
21623
21434
|
const loadDeepseekModels = async (profile, settings) => {
|
|
21624
21435
|
if (!isDeepseekProvider(profile.provider)) {
|
|
21625
21436
|
return { models: [], success: false };
|
|
@@ -22678,6 +22489,20 @@ const loadMinimaxModels = async (profile) => {
|
|
|
22678
22489
|
};
|
|
22679
22490
|
}
|
|
22680
22491
|
const hardcodedModels = [
|
|
22492
|
+
{
|
|
22493
|
+
id: "MiniMax-M3",
|
|
22494
|
+
providerId: profile.id,
|
|
22495
|
+
maxInputTokens: 1e6,
|
|
22496
|
+
maxOutputTokensLimit: 131072,
|
|
22497
|
+
inputCostPerToken: 3e-7,
|
|
22498
|
+
// 0.3 per 1M tokens
|
|
22499
|
+
outputCostPerToken: 12e-7,
|
|
22500
|
+
// 1.2 per 1M tokens
|
|
22501
|
+
cacheReadInputTokenCost: 6e-8,
|
|
22502
|
+
// 0.06 per 1M tokens
|
|
22503
|
+
cacheWriteInputTokenCost: 375e-9
|
|
22504
|
+
// 0.375 per 1M tokens
|
|
22505
|
+
},
|
|
22681
22506
|
{
|
|
22682
22507
|
id: "MiniMax-M2.7",
|
|
22683
22508
|
providerId: profile.id,
|
|
@@ -24396,7 +24221,7 @@ const zaiPlanProviderStrategy = {
|
|
|
24396
24221
|
const MODELS_META_URL = "https://models.dev/api.json";
|
|
24397
24222
|
const MODELS_FILE = path.join(AIDER_DESK_DATA_DIR, "models.json");
|
|
24398
24223
|
const PROVIDER_MODELS_CACHE_FILE = path.join(AIDER_DESK_CACHE_DIR, "provider-models.json");
|
|
24399
|
-
const PROVIDER_MODELS_CACHE_VERSION =
|
|
24224
|
+
const PROVIDER_MODELS_CACHE_VERSION = 2;
|
|
24400
24225
|
class ModelManager {
|
|
24401
24226
|
constructor(store, eventManager) {
|
|
24402
24227
|
this.store = store;
|
|
@@ -24412,11 +24237,9 @@ class ModelManager {
|
|
|
24412
24237
|
providerRegistry = {
|
|
24413
24238
|
anthropic: anthropicProviderStrategy,
|
|
24414
24239
|
"anthropic-compatible": anthropicCompatibleProviderStrategy,
|
|
24415
|
-
auggie: auggieProviderStrategy,
|
|
24416
24240
|
azure: azureProviderStrategy,
|
|
24417
24241
|
bedrock: bedrockProviderStrategy,
|
|
24418
24242
|
cerebras: cerebrasProviderStrategy,
|
|
24419
|
-
"claude-agent-sdk": claudeAgentSdkProviderStrategy,
|
|
24420
24243
|
deepseek: deepseekProviderStrategy,
|
|
24421
24244
|
gemini: geminiProviderStrategy,
|
|
24422
24245
|
"gemini-cli": geminiCliProviderStrategy,
|
|
@@ -25089,7 +24912,7 @@ class ModelManager {
|
|
|
25089
24912
|
const { provider } = registered;
|
|
25090
24913
|
this.providerRegistry[provider.provider.name] = {
|
|
25091
24914
|
...provider.strategy,
|
|
25092
|
-
createLlm: (profile2, model, settings, projectDir) => provider.strategy.createLlm(profile2, model, settings, projectDir),
|
|
24915
|
+
createLlm: (profile2, model, settings, projectDir, toolSet, systemPrompt, providerMetadata) => provider.strategy.createLlm(profile2, model, settings, projectDir, toolSet, systemPrompt, providerMetadata),
|
|
25093
24916
|
getUsageReport: provider.strategy.getUsageReport || getDefaultUsageReport,
|
|
25094
24917
|
getProviderOptions: provider.strategy.getProviderOptions ? (_provider, model) => provider.strategy.getProviderOptions(model) : void 0,
|
|
25095
24918
|
getProviderTools: provider.strategy.getProviderTools ? (_provider, model) => provider.strategy.getProviderTools(model) : void 0,
|
|
@@ -25147,7 +24970,11 @@ class ModelManager {
|
|
|
25147
24970
|
this.eventManager.sendProvidersUpdated(this.getProviders());
|
|
25148
24971
|
}
|
|
25149
24972
|
getProviders() {
|
|
25150
|
-
|
|
24973
|
+
const providersById = new Map(this.store.getProviders().map((p) => [p.id, p]));
|
|
24974
|
+
for (const extensionProfile of this.getExtensionProviderProfiles()) {
|
|
24975
|
+
providersById.set(extensionProfile.id, extensionProfile);
|
|
24976
|
+
}
|
|
24977
|
+
return [...providersById.values()];
|
|
25151
24978
|
}
|
|
25152
24979
|
getExtensionProviderProfiles() {
|
|
25153
24980
|
return [...this.extensionProviders.values()].map((e) => e.profile);
|
|
@@ -27619,15 +27446,48 @@ class ExtensionManager {
|
|
|
27619
27446
|
errors
|
|
27620
27447
|
};
|
|
27621
27448
|
}
|
|
27449
|
+
getToolsInfo(projectDir) {
|
|
27450
|
+
const allExtensions = this.registry.getExtensions(projectDir);
|
|
27451
|
+
const extensions = this.filterEnabledExtensions(allExtensions);
|
|
27452
|
+
const result = [];
|
|
27453
|
+
for (const loaded of extensions) {
|
|
27454
|
+
const { instance, metadata } = loaded;
|
|
27455
|
+
if (!instance.getTools) {
|
|
27456
|
+
continue;
|
|
27457
|
+
}
|
|
27458
|
+
try {
|
|
27459
|
+
const context = new ExtensionContextImpl(loaded.id, metadata.name, this.store, this.modelManager, this.eventManager, this.memoryManager);
|
|
27460
|
+
const tools = instance.getTools(context, "agent", DEFAULT_AGENT_PROFILE);
|
|
27461
|
+
if (!Array.isArray(tools)) {
|
|
27462
|
+
continue;
|
|
27463
|
+
}
|
|
27464
|
+
const toolInfos = tools.filter((tool) => tool.name && tool.description).map((tool) => ({ name: tool.name, description: tool.description }));
|
|
27465
|
+
if (toolInfos.length > 0) {
|
|
27466
|
+
result.push({
|
|
27467
|
+
extensionId: loaded.id,
|
|
27468
|
+
extensionName: metadata.name,
|
|
27469
|
+
tools: toolInfos
|
|
27470
|
+
});
|
|
27471
|
+
}
|
|
27472
|
+
} catch (error) {
|
|
27473
|
+
logger.error(`[Extensions] Failed to get tools info from extension '${metadata.name}':`, error);
|
|
27474
|
+
}
|
|
27475
|
+
}
|
|
27476
|
+
return result;
|
|
27477
|
+
}
|
|
27622
27478
|
getTools(task, mode, profile) {
|
|
27623
27479
|
const collectedTools = [];
|
|
27624
27480
|
const allExtensions = this.registry.getExtensions(task.getProjectDir());
|
|
27625
27481
|
const extensions = this.filterEnabledExtensions(allExtensions);
|
|
27482
|
+
const disabledExtensionTools = profile.disabledExtensionTools ?? [];
|
|
27626
27483
|
for (const loaded of extensions) {
|
|
27627
27484
|
const { instance, metadata } = loaded;
|
|
27628
27485
|
if (!instance.getTools) {
|
|
27629
27486
|
continue;
|
|
27630
27487
|
}
|
|
27488
|
+
if (disabledExtensionTools.includes(loaded.id)) {
|
|
27489
|
+
continue;
|
|
27490
|
+
}
|
|
27631
27491
|
try {
|
|
27632
27492
|
const context = new ExtensionContextImpl(
|
|
27633
27493
|
loaded.id,
|
|
@@ -27650,6 +27510,10 @@ class ExtensionManager {
|
|
|
27650
27510
|
logger.error(`[Extensions] Invalid tool '${tool.name}' from extension '${metadata.name}': ${validation.errors.join(", ")}`);
|
|
27651
27511
|
continue;
|
|
27652
27512
|
}
|
|
27513
|
+
const fullToolId = `${loaded.id}${TOOL_GROUP_NAME_SEPARATOR}${tool.name}`;
|
|
27514
|
+
if (profile.toolApprovals?.[fullToolId] === ToolApprovalState.Never || profile.toolApprovals?.[tool.name] === ToolApprovalState.Never) {
|
|
27515
|
+
continue;
|
|
27516
|
+
}
|
|
27653
27517
|
collectedTools.push({
|
|
27654
27518
|
extensionId: loaded.id,
|
|
27655
27519
|
extensionName: metadata.name,
|
|
@@ -27673,11 +27537,12 @@ class ExtensionManager {
|
|
|
27673
27537
|
* @param abortSignal - Optional AbortSignal for cancellation support
|
|
27674
27538
|
* @returns A ToolSet containing all approved extension tools
|
|
27675
27539
|
*/
|
|
27676
|
-
createExtensionToolset(task, mode, profile, allTools, abortSignal) {
|
|
27540
|
+
createExtensionToolset(task, mode, profile, allTools, approvalManager, abortSignal) {
|
|
27677
27541
|
const toolSet = {};
|
|
27678
27542
|
const registeredTools = this.getTools(task, mode, profile);
|
|
27679
27543
|
for (const { extensionId, extensionName, tool } of registeredTools) {
|
|
27680
27544
|
const toolId = tool.name;
|
|
27545
|
+
const fullToolId = `${extensionId}${TOOL_GROUP_NAME_SEPARATOR}${tool.name}`;
|
|
27681
27546
|
const context = new ExtensionContextImpl(
|
|
27682
27547
|
extensionId,
|
|
27683
27548
|
extensionName,
|
|
@@ -27688,14 +27553,25 @@ class ExtensionManager {
|
|
|
27688
27553
|
task.project,
|
|
27689
27554
|
task
|
|
27690
27555
|
);
|
|
27691
|
-
if (profile.toolApprovals?.[toolId] === ToolApprovalState.Never) {
|
|
27692
|
-
logger.debug(`[Extensions] Skipping tool '${tool.name}' (marked as Never approved)`);
|
|
27693
|
-
continue;
|
|
27694
|
-
}
|
|
27695
27556
|
toolSet[toolId] = {
|
|
27696
27557
|
description: tool.description,
|
|
27697
27558
|
inputSchema: tool.inputSchema,
|
|
27698
27559
|
execute: async (input, options) => {
|
|
27560
|
+
const toolApproval = profile.toolApprovals?.[fullToolId];
|
|
27561
|
+
logger.debug(
|
|
27562
|
+
`[Extensions] Tool '${tool.name}' approval check: fullToolId='${fullToolId}', approval=${toolApproval}, allApprovals=${JSON.stringify(profile.toolApprovals)}`
|
|
27563
|
+
);
|
|
27564
|
+
if (toolApproval === ToolApprovalState.Ask) {
|
|
27565
|
+
const questionKey = fullToolId;
|
|
27566
|
+
const questionText = `Approve tool ${tool.name} from ${extensionName} extension?`;
|
|
27567
|
+
const questionSubject = input ? JSON.stringify(input) : void 0;
|
|
27568
|
+
const [isApproved, userInput] = await approvalManager.handleToolApproval(fullToolId, input, questionKey, questionText, questionSubject);
|
|
27569
|
+
if (!isApproved) {
|
|
27570
|
+
logger.warn(`Tool execution denied by user: ${fullToolId}`);
|
|
27571
|
+
return `Tool execution denied by user.${userInput ? ` User input: ${userInput}` : ""}`;
|
|
27572
|
+
}
|
|
27573
|
+
logger.debug(`Tool execution approved: ${fullToolId}`);
|
|
27574
|
+
}
|
|
27699
27575
|
const allToolsInternal = Object.entries(allTools).reduce(
|
|
27700
27576
|
(acc, [toolId2, tool2]) => {
|
|
27701
27577
|
acc[toolId2] = {
|
|
@@ -28933,12 +28809,26 @@ class EventsHandler {
|
|
|
28933
28809
|
}
|
|
28934
28810
|
await task.mergeWorktreeToMain(squash, targetBranch, commitMessage);
|
|
28935
28811
|
}
|
|
28936
|
-
async
|
|
28812
|
+
async switchToLocalWorkingMode(baseDir, taskId, options) {
|
|
28813
|
+
const task = this.projectManager.getProject(baseDir).getTask(taskId);
|
|
28814
|
+
if (!task) {
|
|
28815
|
+
throw new Error(`Task ${taskId} not found`);
|
|
28816
|
+
}
|
|
28817
|
+
await task.switchToLocalWorkingMode(options);
|
|
28818
|
+
}
|
|
28819
|
+
async switchToWorktreeWorkingMode(baseDir, taskId, options) {
|
|
28937
28820
|
const task = this.projectManager.getProject(baseDir).getTask(taskId);
|
|
28938
28821
|
if (!task) {
|
|
28939
28822
|
throw new Error(`Task ${taskId} not found`);
|
|
28940
28823
|
}
|
|
28941
|
-
await task.
|
|
28824
|
+
await task.switchToWorktreeWorkingMode(options);
|
|
28825
|
+
}
|
|
28826
|
+
async getLocalUncommittedFiles(baseDir, taskId) {
|
|
28827
|
+
const task = this.projectManager.getProject(baseDir).getTask(taskId);
|
|
28828
|
+
if (!task) {
|
|
28829
|
+
throw new Error(`Task ${taskId} not found`);
|
|
28830
|
+
}
|
|
28831
|
+
return await task.getLocalUncommittedFiles();
|
|
28942
28832
|
}
|
|
28943
28833
|
async applyUncommittedChanges(baseDir, taskId, targetBranch) {
|
|
28944
28834
|
const task = this.projectManager.getProject(baseDir).getTask(taskId);
|
|
@@ -29417,6 +29307,9 @@ ${error instanceof Error ? error.message : String(error)}`);
|
|
|
29417
29307
|
readmeContent: ext.readmeContent
|
|
29418
29308
|
}));
|
|
29419
29309
|
}
|
|
29310
|
+
getExtensionToolsInfo(projectDir) {
|
|
29311
|
+
return this.extensionManager.getToolsInfo(projectDir);
|
|
29312
|
+
}
|
|
29420
29313
|
async getAvailableExtensions(repositories, forceRefresh, fetchOnly) {
|
|
29421
29314
|
return await this.extensionManager.getAvailableExtensions(repositories, forceRefresh, fetchOnly);
|
|
29422
29315
|
}
|
|
@@ -29452,6 +29345,7 @@ ${error instanceof Error ? error.message : String(error)}`);
|
|
|
29452
29345
|
return filtered.map((c) => ({
|
|
29453
29346
|
extensionId: c.extensionId,
|
|
29454
29347
|
componentId: c.component.id,
|
|
29348
|
+
name: c.component.name,
|
|
29455
29349
|
placement: c.component.placement,
|
|
29456
29350
|
jsx: c.component.jsx,
|
|
29457
29351
|
loadData: c.component.loadData,
|
|
@@ -30791,6 +30685,9 @@ const migrateSettingsV19toV20 = (settings) => {
|
|
|
30791
30685
|
}
|
|
30792
30686
|
};
|
|
30793
30687
|
};
|
|
30688
|
+
const migrateProvidersV20toV21 = (providers) => {
|
|
30689
|
+
return providers.filter((p) => p.provider.name !== "claude-agent-sdk" && p.provider.name !== "auggie");
|
|
30690
|
+
};
|
|
30794
30691
|
const DEFAULT_SETTINGS = {
|
|
30795
30692
|
language: "en",
|
|
30796
30693
|
startupMode: ProjectStartMode.Empty,
|
|
@@ -30870,7 +30767,7 @@ const DEFAULT_SETTINGS = {
|
|
|
30870
30767
|
const compareBaseDirs = (baseDir1, baseDir2) => {
|
|
30871
30768
|
return normalizeBaseDir(baseDir1) === normalizeBaseDir(baseDir2);
|
|
30872
30769
|
};
|
|
30873
|
-
const CURRENT_SETTINGS_VERSION =
|
|
30770
|
+
const CURRENT_SETTINGS_VERSION = 21;
|
|
30874
30771
|
class Store {
|
|
30875
30772
|
// @ts-expect-error expected to be initialized
|
|
30876
30773
|
store;
|
|
@@ -31025,6 +30922,10 @@ class Store {
|
|
|
31025
30922
|
settings = migrateSettingsV19toV20(settings);
|
|
31026
30923
|
settingsVersion = 20;
|
|
31027
30924
|
}
|
|
30925
|
+
if (settingsVersion === 20) {
|
|
30926
|
+
providers = migrateProvidersV20toV21(providers || []);
|
|
30927
|
+
settingsVersion = 21;
|
|
30928
|
+
}
|
|
31028
30929
|
this.store.set("settings", settings);
|
|
31029
30930
|
this.store.set("openProjects", openProjects || []);
|
|
31030
30931
|
this.store.set("providers", providers || []);
|