@proxysoul/soulforge 1.7.3 → 1.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +367 -212
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -57838,7 +57838,7 @@ var package_default;
57838
57838
  var init_package = __esm(() => {
57839
57839
  package_default = {
57840
57840
  name: "@proxysoul/soulforge",
57841
- version: "1.7.3",
57841
+ version: "1.7.5",
57842
57842
  description: "Graph-powered code intelligence \u2014 multi-agent coding with codebase-aware AI",
57843
57843
  repository: {
57844
57844
  type: "git",
@@ -59984,7 +59984,7 @@ function supportsAnthropicOptions(modelId) {
59984
59984
  }
59985
59985
  function buildContextEdits(config2, contextWindow, thinkingEnabled) {
59986
59986
  const edits = [];
59987
- if (config2.clearThinking && thinkingEnabled) {
59987
+ if (config2?.clearThinking !== false && thinkingEnabled) {
59988
59988
  edits.push({
59989
59989
  type: "clear_thinking_20251015",
59990
59990
  keep: {
@@ -59993,7 +59993,7 @@ function buildContextEdits(config2, contextWindow, thinkingEnabled) {
59993
59993
  }
59994
59994
  });
59995
59995
  }
59996
- if (config2.clearToolUses) {
59996
+ if (config2?.clearToolUses !== false) {
59997
59997
  edits.push({
59998
59998
  type: "clear_tool_uses_20250919",
59999
59999
  trigger: {
@@ -60005,19 +60005,22 @@ function buildContextEdits(config2, contextWindow, thinkingEnabled) {
60005
60005
  value: 6
60006
60006
  },
60007
60007
  clearToolInputs: true,
60008
- clear_at_least: {
60008
+ clearAtLeast: {
60009
60009
  type: "input_tokens",
60010
60010
  value: 5000
60011
60011
  }
60012
60012
  });
60013
60013
  }
60014
- if (config2.compact && contextWindow >= 200000) {
60014
+ if (config2?.compact && contextWindow >= 200000) {
60015
+ const trigger = Math.max(150000, Math.floor(contextWindow * 0.5));
60015
60016
  edits.push({
60016
60017
  type: "compact_20260112",
60017
60018
  trigger: {
60018
60019
  type: "input_tokens",
60019
- value: Math.floor(contextWindow * 0.75)
60020
- }
60020
+ value: trigger
60021
+ },
60022
+ instructions: ["Write a concise summary of the conversation so far.", "Focus on: files modified, key decisions made, current task progress, and next steps.", "Preserve exact file paths, function names, and error messages.", "Do NOT list what you plan to do \u2014 only what has already been done and what remains.", "Do NOT dump internal state or repeat tool outputs.", "Keep the summary under 2000 tokens.", "Wrap in <summary></summary> tags."].join(`
60023
+ `)
60021
60024
  });
60022
60025
  }
60023
60026
  return edits.length > 0 ? edits : null;
@@ -60048,13 +60051,19 @@ function buildAnthropicOptions(modelId, caps, config2) {
60048
60051
  if (caps.effort && config2.performance?.effort && config2.performance.effort !== "off") {
60049
60052
  opts.effort = config2.performance.effort;
60050
60053
  }
60054
+ if (caps.speed && config2.performance?.speed && config2.performance.speed !== "off") {
60055
+ opts.speed = config2.performance.speed;
60056
+ }
60057
+ if (config2.performance?.toolStreaming === false) {
60058
+ opts.toolStreaming = false;
60059
+ }
60051
60060
  if (config2.performance?.disableParallelToolUse) {
60052
60061
  opts.disableParallelToolUse = true;
60053
60062
  }
60054
60063
  if (config2.performance?.sendReasoning === false) {
60055
60064
  opts.sendReasoning = false;
60056
60065
  }
60057
- if (caps.contextManagement && config2.contextManagement) {
60066
+ if (caps.contextManagement) {
60058
60067
  const contextWindow = getModelContextWindow(modelId);
60059
60068
  const edits = buildContextEdits(config2.contextManagement, contextWindow, thinkingEnabled);
60060
60069
  if (edits) {
@@ -331649,12 +331658,21 @@ function truncate(text2, siteLinks) {
331649
331658
  ${siteLinks.map((l) => `- ${l}`).join(`
331650
331659
  `)}` : "";
331651
331660
  const budget = MAX_CONTENT_LENGTH - linksSection.length;
331652
- const body2 = text2.length > budget ? `${text2.slice(0, budget)}
331653
-
331654
- [...]` : text2;
331661
+ if (text2.length <= budget)
331662
+ return text2 + linksSection;
331663
+ const tailBudget = Math.min(Math.floor(budget * 0.25), 20000);
331664
+ const headBudget = budget - tailBudget;
331665
+ const head = text2.slice(0, headBudget);
331666
+ const tail = text2.slice(-tailBudget);
331667
+ const omitted = text2.length - headBudget - tailBudget;
331668
+ const body2 = `${head}
331669
+
331670
+ [... ${String(Math.round(omitted / 1024))}KB omitted \u2014 ${String(Math.round(text2.length / 1024))}KB total. Showing first ${String(Math.round(headBudget / 1024))}KB + last ${String(Math.round(tailBudget / 1024))}KB. For specific sections, try a sub-page URL from the links below.]
331671
+
331672
+ ${tail}`;
331655
331673
  return body2 + linksSection;
331656
331674
  }
331657
- var import_readability, MAX_CONTENT_LENGTH = 16000, pageCache, CACHE_TTL2, MAX_CACHE_SIZE = 100, lastSweep = 0, lastJinaWarning = null, fetchPageTool;
331675
+ var import_readability, MAX_CONTENT_LENGTH = 120000, pageCache, CACHE_TTL2, MAX_CACHE_SIZE = 100, lastSweep = 0, lastJinaWarning = null, fetchPageTool;
331658
331676
  var init_fetch_page = __esm(() => {
331659
331677
  init_esm10();
331660
331678
  init_secrets();
@@ -342323,6 +342341,82 @@ ${crossTabWarning}` : `Shell: ${desc}
342323
342341
  }),
342324
342342
  ...opts?.codeExecution ? {
342325
342343
  code_execution: createAnthropic().tools.codeExecution_20260120()
342344
+ } : {},
342345
+ ...opts?.computerUse ? {
342346
+ computer: createAnthropic().tools.computer_20251124({
342347
+ displayWidthPx: 1920,
342348
+ displayHeightPx: 1080,
342349
+ execute: async ({
342350
+ action,
342351
+ coordinate,
342352
+ text: text2
342353
+ }) => {
342354
+ return `Computer use action: ${action}${coordinate ? ` at (${coordinate.join(",")})` : ""}${text2 ? ` text: ${text2}` : ""}`;
342355
+ }
342356
+ })
342357
+ } : {},
342358
+ ...opts?.anthropicTextEditor ? {
342359
+ str_replace_based_edit_tool: createAnthropic().tools.textEditor_20250728({
342360
+ async execute({
342361
+ command,
342362
+ path,
342363
+ old_str,
342364
+ new_str,
342365
+ insert_text,
342366
+ file_text,
342367
+ view_range
342368
+ }) {
342369
+ const fs2 = await import("fs");
342370
+ const absPath = path.startsWith("/") ? path : resolve30(effectiveCwd, path);
342371
+ switch (command) {
342372
+ case "view": {
342373
+ if (!fs2.existsSync(absPath))
342374
+ return `File not found: ${path}`;
342375
+ const content = fs2.readFileSync(absPath, "utf-8");
342376
+ const lines = content.split(`
342377
+ `);
342378
+ if (view_range && view_range.length >= 2) {
342379
+ const start2 = view_range[0] ?? 1;
342380
+ const end = view_range[1] ?? lines.length;
342381
+ return lines.slice(start2 - 1, end).map((l, i2) => `${start2 + i2} ${l}`).join(`
342382
+ `);
342383
+ }
342384
+ return lines.map((l, i2) => `${i2 + 1} ${l}`).join(`
342385
+ `);
342386
+ }
342387
+ case "create": {
342388
+ fs2.mkdirSync(resolve30(absPath, ".."), {
342389
+ recursive: true
342390
+ });
342391
+ fs2.writeFileSync(absPath, file_text ?? "", "utf-8");
342392
+ return `Created ${path}`;
342393
+ }
342394
+ case "str_replace": {
342395
+ if (!fs2.existsSync(absPath))
342396
+ return `File not found: ${path}`;
342397
+ const src = fs2.readFileSync(absPath, "utf-8");
342398
+ if (!old_str || !src.includes(old_str))
342399
+ return `old_str not found in ${path}`;
342400
+ fs2.writeFileSync(absPath, src.replace(old_str, new_str ?? ""), "utf-8");
342401
+ return `Applied replacement in ${path}`;
342402
+ }
342403
+ case "insert": {
342404
+ if (!fs2.existsSync(absPath))
342405
+ return `File not found: ${path}`;
342406
+ const orig = fs2.readFileSync(absPath, "utf-8");
342407
+ const origLines = orig.split(`
342408
+ `);
342409
+ const insertLine = view_range?.[0] ?? origLines.length;
342410
+ origLines.splice(insertLine, 0, insert_text ?? "");
342411
+ fs2.writeFileSync(absPath, origLines.join(`
342412
+ `), "utf-8");
342413
+ return `Inserted text at line ${insertLine} in ${path}`;
342414
+ }
342415
+ default:
342416
+ return `Unknown command: ${command}`;
342417
+ }
342418
+ }
342419
+ })
342326
342420
  } : {}
342327
342421
  };
342328
342422
  }
@@ -342874,9 +342968,6 @@ function setApiExportEnabled(v) {
342874
342968
  function isApiExportEnabled() {
342875
342969
  return apiExportEnabled;
342876
342970
  }
342877
- function estimateTokens2(text2) {
342878
- return Math.ceil(text2.length / 4);
342879
- }
342880
342971
  function detectRepeatedCalls(steps, window3 = REPEAT_CALL_WINDOW, threshold = REPEAT_CALL_THRESHOLD) {
342881
342972
  const counts = new Map;
342882
342973
  const start2 = Math.max(0, steps.length - window3);
@@ -342984,6 +343075,11 @@ function buildSummary(toolName, text2, ctx) {
342984
343075
  const entryMatch = text2.match(/(\d+) entries/);
342985
343076
  return `${tag} ${entryMatch ? entryMatch[1] : String(lineCount2)} entries`;
342986
343077
  }
343078
+ if (toolName === "fetch_page" || toolName === "web_search") {
343079
+ const truncated = text2.includes("page truncated");
343080
+ const url2 = typeof args2?.url === "string" ? ` ${args2.url.slice(0, 80)}` : "";
343081
+ return `${tag} ${String(lineCount2)} lines${url2}${truncated ? " (truncated \u2014 cached, try a sub-page URL)" : ""}`;
343082
+ }
342987
343083
  if (toolName === "soul_analyze" || toolName === "soul_impact") {
342988
343084
  const action = typeof args2?.action === "string" ? `${args2.action}: ` : "";
342989
343085
  const firstLine = text2.split(`
@@ -343124,68 +343220,6 @@ function compactOldToolResults(messages, symbolLookup, pathMap) {
343124
343220
  }
343125
343221
  return result;
343126
343222
  }
343127
- function pruneByTokenBudget(messages) {
343128
- const targets = [];
343129
- let totalTokens = 0;
343130
- for (let mi = messages.length - 1;mi >= 0; mi--) {
343131
- const msg = messages[mi];
343132
- if (!msg || msg.role !== "tool" || !Array.isArray(msg.content))
343133
- continue;
343134
- for (let pi = msg.content.length - 1;pi >= 0; pi--) {
343135
- const part = msg.content[pi];
343136
- if (!part || part.type !== "tool-result")
343137
- continue;
343138
- if (EDIT_TOOLS.has(part.toolName))
343139
- continue;
343140
- const text2 = extractText(part.output);
343141
- const tokens = estimateTokens2(text2);
343142
- if (tokens <= 50)
343143
- continue;
343144
- totalTokens += tokens;
343145
- targets.push({
343146
- msgIdx: mi,
343147
- partIdx: pi,
343148
- tokens
343149
- });
343150
- }
343151
- }
343152
- const excess = totalTokens - PRUNE_PROTECT_TOKENS;
343153
- if (excess < PRUNE_MINIMUM_TOKENS)
343154
- return messages;
343155
- let freed = 0;
343156
- const pruneSet = new Set;
343157
- for (let i2 = targets.length - 1;i2 >= 0 && freed < excess; i2--) {
343158
- const t = targets[i2];
343159
- if (!t)
343160
- continue;
343161
- pruneSet.add(`${String(t.msgIdx)}:${String(t.partIdx)}`);
343162
- freed += t.tokens;
343163
- }
343164
- if (pruneSet.size === 0)
343165
- return messages;
343166
- return messages.map((msg, mi) => {
343167
- if (msg.role !== "tool" || !Array.isArray(msg.content))
343168
- return msg;
343169
- let changed = false;
343170
- const newContent = msg.content.map((part, pi) => {
343171
- if (pruneSet.has(`${String(mi)}:${String(pi)}`)) {
343172
- changed = true;
343173
- return {
343174
- ...part,
343175
- output: {
343176
- type: "text",
343177
- value: PRUNED_PLACEHOLDER
343178
- }
343179
- };
343180
- }
343181
- return part;
343182
- });
343183
- return changed ? {
343184
- ...msg,
343185
- content: newContent
343186
- } : msg;
343187
- });
343188
- }
343189
343223
  function buildPrepareStep({
343190
343224
  bus,
343191
343225
  agentId,
@@ -343204,6 +343238,7 @@ function buildPrepareStep({
343204
343238
  const isExplore = role === "explore" || role === "investigate";
343205
343239
  const stepNudgeAt = isExplore ? STEP_NUDGE_EXPLORE : STEP_NUDGE_CODE;
343206
343240
  const maxSteps = isExplore ? EXPLORE_MAX_STEPS : CODE_MAX_STEPS;
343241
+ const previousInjects = [];
343207
343242
  const prepareStep = ({
343208
343243
  stepNumber,
343209
343244
  steps,
@@ -343250,10 +343285,9 @@ function buildPrepareStep({
343250
343285
  }
343251
343286
  if (!disablePruning && stepNumber >= 2) {
343252
343287
  const src = result.messages ?? messages;
343253
- const pruned = pruneByTokenBudget(src);
343254
- if (pruned !== src) {
343255
- const compacted = compactOldToolResults(pruned, symbolLookup);
343256
- result.messages = compacted !== pruned ? compacted : pruned;
343288
+ const compacted = compactOldToolResults(src, symbolLookup);
343289
+ if (compacted !== src) {
343290
+ result.messages = compacted;
343257
343291
  }
343258
343292
  }
343259
343293
  const lastStep = steps.length > 0 ? steps[steps.length - 1] : undefined;
@@ -343339,22 +343373,17 @@ function buildPrepareStep({
343339
343373
  });
343340
343374
  }
343341
343375
  const contextSize = lastStep?.usage.inputTokens ?? 0;
343376
+ const hints = [];
343342
343377
  if (bus && agentId) {
343343
343378
  const unseen = bus.drainUnseenFindings(agentId);
343344
343379
  if (unseen) {
343345
- const existing = result.system ?? "";
343346
- result.system = `${existing}
343347
-
343348
- --- Peer findings (new) ---
343349
- ${unseen}`.trim();
343380
+ hints.push(`--- Peer findings (new) ---
343381
+ ${unseen}`);
343350
343382
  }
343351
343383
  }
343352
343384
  const taskBlock = renderTaskList(tabId);
343353
- if (taskBlock) {
343354
- result.system = `${result.system ?? ""}
343355
-
343356
- ${taskBlock}`.trim();
343357
- }
343385
+ if (taskBlock)
343386
+ hints.push(taskBlock);
343358
343387
  if (stepNumber >= CONSECUTIVE_READ_LIMIT && !nudgeFired) {
343359
343388
  let consecutiveReads = 0;
343360
343389
  for (let i2 = steps.length - 1;i2 >= 0; i2--) {
@@ -343369,53 +343398,32 @@ ${taskBlock}`.trim();
343369
343398
  break;
343370
343399
  }
343371
343400
  if (consecutiveReads >= CONSECUTIVE_READ_LIMIT) {
343372
- const existing = result.system ?? "";
343373
343401
  const hint = isExplore ? `[status: ${String(consecutiveReads)} read-only steps \u2014 summarize findings or use a search tool for remaining questions]` : `[status: ${String(consecutiveReads)} read-only steps \u2014 apply edits with multi_edit]`;
343374
- result.system = `${existing}
343375
-
343376
- ${hint}`.trim();
343402
+ hints.push(hint);
343377
343403
  }
343378
343404
  }
343379
343405
  if (stepNumber >= REPEAT_CALL_THRESHOLD) {
343380
343406
  const repeated = detectRepeatedCalls(steps);
343381
343407
  if (repeated) {
343382
- const existing = result.system ?? "";
343383
- result.system = `${existing}
343384
-
343385
- \uD83D\uDD01 ${repeated.toolName} called ${String(repeated.count)}\xD7 with identical arguments \u2014 same result each time. Use the result you already have, or try a different tool/approach.`.trim();
343408
+ hints.push(`\uD83D\uDD01 ${repeated.toolName} called ${String(repeated.count)}\xD7 with identical arguments \u2014 same result each time. Use the result you already have, or try a different tool/approach.`);
343386
343409
  }
343387
343410
  }
343388
343411
  if (stepNumber >= stepNudgeAt) {
343389
343412
  const remaining = maxSteps - stepNumber;
343390
- const existing = result.system ?? "";
343391
343413
  if (remaining <= 1) {
343392
- const hint = isExplore ? "Write your final text summary NOW. Name files, line numbers, exact values found." : "Apply edits with multi_edit NOW, then summarize what you changed.";
343393
- result.system = `${existing}
343394
-
343395
- \uD83D\uDED1 FINAL STEP. ${hint}`.trim();
343414
+ const hint = isExplore ? "\uD83D\uDED1 FINAL STEP. Write your final text summary NOW. Name files, line numbers, exact values found." : "\uD83D\uDED1 FINAL STEP. Apply edits with multi_edit NOW, then summarize what you changed.";
343415
+ hints.push(hint);
343396
343416
  result.toolChoice = "none";
343397
343417
  result.activeTools = [];
343398
- const msgs = result.messages ?? messages;
343399
- result.messages = [...msgs, {
343400
- role: "user",
343401
- content: [{
343402
- type: "text",
343403
- text: `FINAL step \u2014 write your text summary now: what you found or changed, which files, key details.`
343404
- }]
343405
- }];
343406
343418
  } else if (remaining <= 2) {
343407
- const hint = isExplore ? "Write your text summary NOW. Name files, line numbers, exact values." : "Apply edits with multi_edit NOW, then summarize what you changed.";
343408
- result.system = `${existing}
343409
-
343410
- \uD83D\uDED1 ${String(remaining)} steps left. ${hint}`.trim();
343419
+ const hint = isExplore ? `\uD83D\uDED1 ${String(remaining)} steps left. Write your text summary NOW. Name files, line numbers, exact values.` : `\uD83D\uDED1 ${String(remaining)} steps left. Apply edits with multi_edit NOW, then summarize what you changed.`;
343420
+ hints.push(hint);
343411
343421
  if (!isExplore) {
343412
343422
  result.activeTools = ["edit_file", "multi_edit", "done", "report_finding"];
343413
343423
  }
343414
343424
  } else {
343415
- const hint = isExplore ? "Write your text summary soon. Name files, line numbers, exact values found." : "Apply your edits NOW with multi_edit.";
343416
- result.system = `${existing}
343417
-
343418
- \u26A0 Step ${String(stepNumber)}/${String(maxSteps)} \u2014 ${String(remaining)} steps left. ${hint}`.trim();
343425
+ const hint = isExplore ? `\u26A0 Step ${String(stepNumber)}/${String(maxSteps)} \u2014 ${String(remaining)} steps left. Write your text summary soon. Name files, line numbers, exact values found.` : `\u26A0 Step ${String(stepNumber)}/${String(maxSteps)} \u2014 ${String(remaining)} steps left. Apply your edits NOW with multi_edit.`;
343426
+ hints.push(hint);
343419
343427
  }
343420
343428
  }
343421
343429
  if (contextSize > nudgeThreshold) {
@@ -343429,17 +343437,41 @@ ${hint}`.trim();
343429
343437
  agentId
343430
343438
  });
343431
343439
  }
343432
- const msgs = result.messages ?? messages;
343433
- result.messages = [...msgs, {
343434
- role: "user",
343435
- content: [{
343436
- type: "text",
343437
- text: "Stop calling tools. Write a concise text summary now: what you found or changed, which files, key details."
343438
- }]
343439
- }];
343440
+ hints.push("Stop calling tools. Write a concise text summary now: what you found or changed, which files, key details.");
343440
343441
  result.toolChoice = "none";
343441
343442
  result.activeTools = [];
343442
343443
  }
343444
+ if (hints.length > 0 || previousInjects.length > 0) {
343445
+ const msgs = result.messages ?? [...sanitizedMessages ?? messages];
343446
+ const cleanMsgCount = msgs.length;
343447
+ let offset = 0;
343448
+ for (const prev of previousInjects) {
343449
+ const insertAt = prev.cleanInsertAt + offset;
343450
+ if (insertAt <= msgs.length) {
343451
+ msgs.splice(insertAt, 0, prev.message);
343452
+ offset++;
343453
+ }
343454
+ }
343455
+ if (hints.length > 0) {
343456
+ const injectMessage = {
343457
+ role: "user",
343458
+ content: [{
343459
+ type: "text",
343460
+ text: hints.map((h) => `<system-reminder>
343461
+ ${h}
343462
+ </system-reminder>`).join(`
343463
+
343464
+ `)
343465
+ }]
343466
+ };
343467
+ previousInjects.push({
343468
+ cleanInsertAt: cleanMsgCount,
343469
+ message: injectMessage
343470
+ });
343471
+ msgs.push(injectMessage);
343472
+ }
343473
+ result.messages = msgs;
343474
+ }
343443
343475
  return Object.keys(result).length > 0 ? result : undefined;
343444
343476
  };
343445
343477
  const tokenStop = ({
@@ -343474,7 +343506,7 @@ function buildSymbolLookup(repoMap) {
343474
343506
  return repoMap.getFileSymbolsCached(rel);
343475
343507
  };
343476
343508
  }
343477
- var apiExportEnabled = false, OUTPUT_NUDGE_PCT = 0.8, HARD_STOP_PCT = 0.9, DEFAULT_CONTEXT_WINDOW = 200000, MAX_SUBAGENT_CONTEXT = 200000, KEEP_RECENT_MESSAGES = 4, PRUNE_PROTECT_TOKENS = 40000, PRUNE_MINIMUM_TOKENS = 20000, PRUNED_PLACEHOLDER = "[Old tool result content cleared]", EXPLORE_MAX_STEPS = 28, CODE_MAX_STEPS = 18, STEP_NUDGE_EXPLORE = 18, STEP_NUDGE_CODE = 10, CONSECUTIVE_READ_LIMIT = 5, REPEAT_CALL_THRESHOLD = 3, REPEAT_CALL_WINDOW = 8, READ_TOOL_NAMES, SUMMARIZABLE_TOOLS, EDIT_TOOLS;
343509
+ var apiExportEnabled = false, OUTPUT_NUDGE_PCT = 0.8, HARD_STOP_PCT = 0.9, DEFAULT_CONTEXT_WINDOW = 200000, MAX_SUBAGENT_CONTEXT = 200000, KEEP_RECENT_MESSAGES = 4, EXPLORE_MAX_STEPS = 28, CODE_MAX_STEPS = 18, STEP_NUDGE_EXPLORE = 18, STEP_NUDGE_CODE = 10, CONSECUTIVE_READ_LIMIT = 5, REPEAT_CALL_THRESHOLD = 3, REPEAT_CALL_WINDOW = 8, READ_TOOL_NAMES, SUMMARIZABLE_TOOLS, EDIT_TOOLS;
343478
343510
  var init_step_utils = __esm(() => {
343479
343511
  init_dist10();
343480
343512
  init_task_list();
@@ -343513,19 +343545,27 @@ function createCodeAgent(model, options) {
343513
343545
  const agentId = options?.agentId;
343514
343546
  const hasBus = !!(bus && agentId);
343515
343547
  const busTools = hasBus ? buildBusTools(bus, agentId, "code") : {};
343516
- let tools = buildSubagentCodeTools({
343517
- webSearchModel: options?.webSearchModel,
343518
- onApproveWebSearch: options?.onApproveWebSearch,
343519
- onApproveFetchPage: options?.onApproveFetchPage,
343520
- repoMap: options?.repoMap
343521
- });
343522
- if (hasBus) {
343523
- tools = wrapWithBusCache(tools, bus, agentId, options?.repoMap);
343548
+ let allTools;
343549
+ if (options?.forgeTools) {
343550
+ allTools = {
343551
+ ...options.forgeTools,
343552
+ ...busTools
343553
+ };
343554
+ } else {
343555
+ let tools = buildSubagentCodeTools({
343556
+ webSearchModel: options?.webSearchModel,
343557
+ onApproveWebSearch: options?.onApproveWebSearch,
343558
+ onApproveFetchPage: options?.onApproveFetchPage,
343559
+ repoMap: options?.repoMap
343560
+ });
343561
+ if (hasBus) {
343562
+ tools = wrapWithBusCache(tools, bus, agentId, options?.repoMap);
343563
+ }
343564
+ allTools = {
343565
+ ...tools,
343566
+ ...busTools
343567
+ };
343524
343568
  }
343525
- const allTools = {
343526
- ...tools,
343527
- ...busTools
343528
- };
343529
343569
  const {
343530
343570
  prepareStep,
343531
343571
  stopConditions
@@ -343613,19 +343653,27 @@ function createExploreAgent(model, options) {
343613
343653
  const agentId = options?.agentId;
343614
343654
  const hasBus = !!(bus && agentId);
343615
343655
  const busTools = hasBus ? buildBusTools(bus, agentId, "explore") : {};
343616
- let tools = buildSubagentExploreTools({
343617
- webSearchModel: options?.webSearchModel,
343618
- onApproveWebSearch: options?.onApproveWebSearch,
343619
- onApproveFetchPage: options?.onApproveFetchPage,
343620
- repoMap: options?.repoMap
343621
- });
343622
- if (hasBus) {
343623
- tools = wrapWithBusCache(tools, bus, agentId, options?.repoMap);
343656
+ let allTools;
343657
+ if (options?.forgeTools) {
343658
+ allTools = {
343659
+ ...options.forgeTools,
343660
+ ...busTools
343661
+ };
343662
+ } else {
343663
+ let tools = buildSubagentExploreTools({
343664
+ webSearchModel: options?.webSearchModel,
343665
+ onApproveWebSearch: options?.onApproveWebSearch,
343666
+ onApproveFetchPage: options?.onApproveFetchPage,
343667
+ repoMap: options?.repoMap
343668
+ });
343669
+ if (hasBus) {
343670
+ tools = wrapWithBusCache(tools, bus, agentId, options?.repoMap);
343671
+ }
343672
+ allTools = {
343673
+ ...tools,
343674
+ ...busTools
343675
+ };
343624
343676
  }
343625
- const allTools = {
343626
- ...tools,
343627
- ...busTools
343628
- };
343629
343677
  const {
343630
343678
  prepareStep,
343631
343679
  stopConditions
@@ -344809,6 +344857,25 @@ var init_agent_verification = __esm(() => {
344809
344857
  // src/core/agents/subagent-tools.ts
344810
344858
  import { readFile as fsReadFile } from "fs/promises";
344811
344859
  import { isAbsolute as pathIsAbsolute, resolve as pathResolve } from "path";
344860
+ function guardForgeTools(forgeTools, role) {
344861
+ const blocked = role === "code" ? CODE_BLOCKED : EXPLORE_BLOCKED;
344862
+ const guarded = {};
344863
+ const rejectMsg = (name21) => `${name21} is not available in ${role} mode. Use report_finding to suggest changes instead.`;
344864
+ for (const [name21, t] of Object.entries(forgeTools)) {
344865
+ if (blocked.has(name21)) {
344866
+ guarded[name21] = {
344867
+ ...t,
344868
+ execute: async () => ({
344869
+ success: false,
344870
+ error: rejectMsg(name21)
344871
+ })
344872
+ };
344873
+ } else {
344874
+ guarded[name21] = t;
344875
+ }
344876
+ }
344877
+ return guarded;
344878
+ }
344812
344879
  function formatToolArgs(toolCall) {
344813
344880
  const a = toolCall.input ?? {};
344814
344881
  if (toolCall.toolName === "read_file" && a.path)
@@ -344952,6 +345019,8 @@ function createAgent(task, models, bus, parentToolCallId) {
344952
345019
  }
344953
345020
  const contextWindow = getModelContextWindow(modelId);
344954
345021
  const forgeInstructions = useMiniForge ? models.forgeInstructions : undefined;
345022
+ const agentRole = useExplore ? task.role === "investigate" ? "investigate" : "explore" : "code";
345023
+ const forgeToolsGuarded = useMiniForge && models.forgeTools ? guardForgeTools(models.forgeTools, agentRole) : undefined;
344955
345024
  const opts = {
344956
345025
  bus,
344957
345026
  agentId: task.agentId,
@@ -344964,9 +345033,10 @@ function createAgent(task, models, bus, parentToolCallId) {
344964
345033
  repoMap: models.repoMap,
344965
345034
  contextWindow,
344966
345035
  disablePruning: models.disablePruning,
344967
- role: task.role === "investigate" ? "investigate" : "explore",
345036
+ role: agentRole === "code" ? "explore" : agentRole,
344968
345037
  tabId: models.tabId,
344969
- forgeInstructions
345038
+ forgeInstructions,
345039
+ forgeTools: forgeToolsGuarded
344970
345040
  };
344971
345041
  const hasPreloadedFiles = !useExplore && task.task.includes("--- Preloaded file contents");
344972
345042
  const agent = useExplore ? createExploreAgent(model, opts) : createCodeAgent(model, {
@@ -345934,7 +346004,7 @@ ${value}
345934
346004
  })
345935
346005
  };
345936
346006
  }
345937
- var SKILL_TOKEN_RE, SKILL_MATCH_THRESHOLD = 2, SKILL_NAME_WEIGHT = 3, SKILL_PREVIEW_CHARS = 200, SKILL_MAX_INJECT_CHARS = 2000, PRELOAD_FULL_FILE_MAX_LINES = 500, PRELOAD_TOTAL_MAX_CHARS = 80000;
346007
+ var EXPLORE_BLOCKED, CODE_BLOCKED, SKILL_TOKEN_RE, SKILL_MATCH_THRESHOLD = 2, SKILL_NAME_WEIGHT = 3, SKILL_PREVIEW_CHARS = 200, SKILL_MAX_INJECT_CHARS = 2000, PRELOAD_FULL_FILE_MAX_LINES = 500, PRELOAD_TOTAL_MAX_CHARS = 80000;
345938
346008
  var init_subagent_tools = __esm(() => {
345939
346009
  init_dist10();
345940
346010
  init_zod();
@@ -345950,6 +346020,8 @@ var init_subagent_tools = __esm(() => {
345950
346020
  init_code();
345951
346021
  init_explore();
345952
346022
  init_subagent_events();
346023
+ EXPLORE_BLOCKED = new Set(["edit_file", "multi_edit", "write_file", "create_file", "rename_symbol", "move_symbol", "refactor", "dispatch", "shell"]);
346024
+ CODE_BLOCKED = new Set(["dispatch"]);
345953
346025
  SKILL_TOKEN_RE = /[a-z0-9]+/gi;
345954
346026
  });
345955
346027
 
@@ -346225,6 +346297,8 @@ function createForgeAgent({
346225
346297
  providerOptions,
346226
346298
  headers,
346227
346299
  codeExecution: codeExecution3,
346300
+ computerUse,
346301
+ anthropicTextEditor,
346228
346302
  cwd: cwd2,
346229
346303
  sessionId,
346230
346304
  sharedCacheRef,
@@ -346242,11 +346316,14 @@ function createForgeAgent({
346242
346316
  const modelId = typeof model === "object" && model !== null && "modelId" in model ? String(model.modelId) : "";
346243
346317
  if (modelId)
346244
346318
  contextManager.setActiveModel(modelId);
346245
- const canUseCodeExecution = codeExecution3 && isAnthropicNative(modelId);
346319
+ const isAnthropic = isAnthropicNative(modelId);
346320
+ const canUseCodeExecution = codeExecution3 && isAnthropic;
346246
346321
  const onDemandEnabled = !disabledTools?.has("request_tools") && !isRestricted && !planExecution;
346247
346322
  const activeDeferredTools = onDemandEnabled ? new Set : undefined;
346248
346323
  const directTools = buildTools(undefined, editorIntegration, onApproveWebSearch, {
346249
346324
  codeExecution: canUseCodeExecution,
346325
+ computerUse: computerUse && isAnthropic,
346326
+ anthropicTextEditor: anthropicTextEditor && isAnthropic,
346250
346327
  contextManager,
346251
346328
  agentSkills: !disabledTools?.has("skills"),
346252
346329
  webSearchModel,
@@ -346259,6 +346336,7 @@ function createForgeAgent({
346259
346336
  activeDeferredTools
346260
346337
  });
346261
346338
  const forgeInstructions = buildInstructions(contextManager, modelId);
346339
+ const forgeTools = directTools;
346262
346340
  const subagentHeaders = detectModelFamily(modelId) === "openai" && sessionId ? {
346263
346341
  ...headers,
346264
346342
  "x-prompt-cache-key": sessionId
@@ -346279,7 +346357,8 @@ function createForgeAgent({
346279
346357
  skills,
346280
346358
  disablePruning,
346281
346359
  tabId: tabId ?? contextManager.getTabId() ?? undefined,
346282
- forgeInstructions
346360
+ forgeInstructions,
346361
+ forgeTools
346283
346362
  }).dispatch
346284
346363
  } : buildSubagentTools({
346285
346364
  defaultModel: model,
@@ -346299,7 +346378,8 @@ function createForgeAgent({
346299
346378
  skills,
346300
346379
  disablePruning,
346301
346380
  tabId: tabId ?? contextManager.getTabId() ?? undefined,
346302
- forgeInstructions
346381
+ forgeInstructions,
346382
+ forgeTools
346303
346383
  });
346304
346384
  const cachedReadFile = sharedCacheRef && agentFeatures?.dispatchCache !== false ? wrapReadFileWithDispatchCache(directTools.read_file, sharedCacheRef, cwd2) : directTools.read_file;
346305
346385
  const allTools = {
@@ -360490,11 +360570,14 @@ Be concise, direct, and to the point. Match response length to question complexi
360490
360570
  Output text to communicate with the user \u2014 all text outside tool use is displayed.
360491
360571
  Use Github-flavored markdown. Code blocks with language hints.
360492
360572
  Minimize output tokens while maintaining helpfulness, quality, and accuracy.
360493
- Skip narration ("Let me now...", "I have enough context") \u2014 just call the tool or write the code.
360494
- Skip summaries of what you just did \u2014 the user sees tool calls in real-time.
360495
- Go straight to the answer. No transition sentences, no restating the question.
360496
360573
  Answer concisely \u2014 fewer than 4 lines unless the user asks for detail.
360497
360574
 
360575
+ # Silent tool use
360576
+ Stay silent while gathering information. When you need to read files, search, or explore \u2014 just call the tools with zero surrounding text. Emit text only when you have something meaningful to tell the user: an answer, a question, a decision, or a result.
360577
+ Good: [tool call] \u2192 [tool call] \u2192 [tool call] \u2192 "Here's what I found: ..."
360578
+ Bad: "Let me check..." \u2192 [tool call] \u2192 "Now let me look at..." \u2192 [tool call] \u2192 "I see the pattern..."
360579
+ The user sees tool calls in real-time \u2014 your narration between them adds noise, not value. Go straight to the answer once you have it.
360580
+
360498
360581
  # Doing tasks
360499
360582
  When given a software engineering task:
360500
360583
  1. Read the Soul Map first \u2014 it has files, symbols, line numbers, and dependencies
@@ -360519,8 +360602,10 @@ var init_default = __esm(() => {
360519
360602
 
360520
360603
  # Tone and style
360521
360604
  Be concise and direct. Use Github-flavored markdown. Code blocks with language hints.
360522
- Minimize output tokens while maintaining quality. No preamble, no postamble.
360523
- Do not summarize actions you just took. Answer concisely.
360605
+ Minimize output tokens while maintaining quality. Answer concisely.
360606
+
360607
+ # Silent tool use
360608
+ Stay silent while gathering information. When you need to read files, search, or explore \u2014 just call the tools with zero surrounding text. Emit text only when you have something meaningful to tell the user: an answer, a question, a decision, or a result.
360524
360609
 
360525
360610
  # Doing tasks
360526
360611
  1. Use search tools to understand the codebase. Use the Task tool for broad exploration.
@@ -360545,9 +360630,12 @@ var init_google2 = __esm(() => {
360545
360630
 
360546
360631
  # Tone and style
360547
360632
  Use Github-flavored markdown. Code blocks with language hints.
360548
- Minimize output tokens. Do not summarize what you just did.
360633
+ Minimize output tokens.
360549
360634
  Answer concisely \u2014 fewer than 4 lines unless the user asks for detail.
360550
360635
 
360636
+ # Silent tool use
360637
+ Stay silent while gathering information. When you need to read files, search, or explore \u2014 just call the tools with zero surrounding text. Emit text only when you have something meaningful to tell the user: an answer, a question, a decision, or a result. The user sees tool calls in real-time \u2014 narration between them adds noise, not value.
360638
+
360551
360639
  # Primary Workflow
360552
360640
  1. **Understand**: Use search tools and the Task tool for exploration. Use direct tools for targeted lookups.
360553
360641
  2. **Implement**: Make changes using edit tools. Read files once, plan all changes, apply in one call.
@@ -360568,10 +360656,12 @@ If you are not sure about file content or codebase structure, use your tools to
360568
360656
 
360569
360657
  # Tone and style
360570
360658
  Be concise and direct. Use Github-flavored markdown. Code blocks with language hints.
360571
- Minimize output tokens while maintaining quality. Do not add preamble or postamble.
360572
- Do not summarize actions you just took \u2014 the user sees tool calls in real-time.
360659
+ Minimize output tokens while maintaining quality.
360573
360660
  Answer concisely \u2014 fewer than 4 lines unless the user asks for detail.
360574
360661
 
360662
+ # Silent tool use
360663
+ Stay silent while gathering information. When you need to read files, search, or explore \u2014 just call the tools with zero surrounding text. Emit text only when you have something meaningful to tell the user: an answer, a question, a decision, or a result. The user sees tool calls in real-time \u2014 narration between them adds noise, not value.
360664
+
360575
360665
  # Coding guidelines
360576
360666
  - Fix problems at the root cause, not surface-level patches
360577
360667
  - Avoid unneeded complexity. Ignore unrelated bugs \u2014 not your responsibility
@@ -430426,7 +430516,7 @@ var init_navigation = __esm(() => {
430426
430516
  // src/core/commands/proxy.ts
430427
430517
  async function cleanupProxySelections(ctx) {
430428
430518
  if (ctx.chat.activeModel.startsWith("proxy/")) {
430429
- ctx.chat.setActiveModel("none");
430519
+ ctx.syncActiveModel("none");
430430
430520
  ctx.saveToScope({
430431
430521
  defaultModel: "none"
430432
430522
  }, ctx.detectScope("defaultModel"));
@@ -430683,6 +430773,13 @@ async function handleProxyLogin(_input, ctx) {
430683
430773
  label: ok ? "Authentication complete." : "Authentication failed.",
430684
430774
  color: ok ? getThemeTokens().success : getThemeTokens().brandSecondary
430685
430775
  });
430776
+ if (ok && ctx.chat.activeModel === "none") {
430777
+ loginLines.push({
430778
+ type: "text",
430779
+ label: "Press Ctrl+L or type /model to select a proxy model.",
430780
+ color: getThemeTokens().textSecondary
430781
+ });
430782
+ }
430686
430783
  updatePopup([...loginLines]);
430687
430784
  }).catch((err2) => {
430688
430785
  const msg = err2 instanceof Error ? err2.message : String(err2);
@@ -436467,12 +436564,6 @@ var init_Footer = __esm(async () => {
436467
436564
  l: "Tab",
436468
436565
  ls: "Tab",
436469
436566
  tier: 3
436470
- }, {
436471
- k: "^X",
436472
- ic: icon("stop"),
436473
- l: "Stop",
436474
- ls: "Stop",
436475
- tier: 3
436476
436567
  }, {
436477
436568
  k: "^C",
436478
436569
  ic: icon("quit"),
@@ -437669,7 +437760,7 @@ function pruneOldToolResults(msgs) {
437669
437760
  continue;
437670
437761
  const text3 = typeof p2.output === "string" ? p2.output : typeof p2.output?.value === "string" ? p2.output.value : JSON.stringify(p2.output ?? "");
437671
437762
  const tokens = Math.round(text3.length / CHARS_PER_TOKEN2);
437672
- if (protectedTokens < PRUNE_PROTECT_TOKENS2) {
437763
+ if (protectedTokens < PRUNE_PROTECT_TOKENS) {
437673
437764
  protectedTokens += tokens;
437674
437765
  } else {
437675
437766
  prunableTokens += tokens;
@@ -437677,7 +437768,7 @@ function pruneOldToolResults(msgs) {
437677
437768
  }
437678
437769
  }
437679
437770
  }
437680
- if (prunableTokens < PRUNE_MINIMUM_TOKENS2 || toPrune.size === 0)
437771
+ if (prunableTokens < PRUNE_MINIMUM_TOKENS || toPrune.size === 0)
437681
437772
  return msgs;
437682
437773
  return msgs.map((msg, idx) => {
437683
437774
  if (!toPrune.has(idx))
@@ -438850,6 +438941,8 @@ ${description}`,
438850
438941
  providerOptions,
438851
438942
  headers,
438852
438943
  codeExecution: effectiveConfig2.codeExecution,
438944
+ computerUse: effectiveConfig2.computerUse,
438945
+ anthropicTextEditor: effectiveConfig2.anthropicTextEditor,
438853
438946
  cwd: cwd2,
438854
438947
  sessionId: sessionIdRef.current,
438855
438948
  sharedCacheRef: sharedCacheRef.current,
@@ -438891,6 +438984,8 @@ ${description}`,
438891
438984
  providerOptions: degraded.providerOptions,
438892
438985
  headers: degraded.headers,
438893
438986
  codeExecution: effectiveConfig2.codeExecution,
438987
+ computerUse: effectiveConfig2.computerUse,
438988
+ anthropicTextEditor: effectiveConfig2.anthropicTextEditor,
438894
438989
  cwd: cwd2,
438895
438990
  sessionId: sessionIdRef.current,
438896
438991
  sharedCacheRef: sharedCacheRef.current,
@@ -439798,7 +439893,7 @@ ${pContent}`;
439798
439893
  cycleMode: cycleModeFn
439799
439894
  };
439800
439895
  }
439801
- var import_react32, ZERO_USAGE2, CHARS_PER_TOKEN2 = 4, PRUNE_PROTECT_TOKENS2 = 40000, PRUNE_MINIMUM_TOKENS2 = 20000;
439896
+ var import_react32, ZERO_USAGE2, CHARS_PER_TOKEN2 = 4, PRUNE_PROTECT_TOKENS = 40000, PRUNE_MINIMUM_TOKENS = 20000;
439802
439897
  var init_useChat = __esm(() => {
439803
439898
  init_dist10();
439804
439899
  init_agent_bus();
@@ -440206,7 +440301,8 @@ var init_InputBox = __esm(async () => {
440206
440301
  return results;
440207
440302
  }, [showAutocomplete, commandToken]);
440208
440303
  const hasMatches = matches3.length > 0;
440209
- const isCommandPrefix = hasMatches && matches3.some((m_0) => m_0.cmd.startsWith(commandToken.trimEnd()));
440304
+ const trimmedToken = commandToken.trimEnd();
440305
+ const isCommandPrefix = hasMatches && (matches3.some((m_0) => m_0.cmd.startsWith(trimmedToken)) || !trimmedToken.includes(" ", 1));
440210
440306
  const hasMatchesForNav = hasMatches && isCommandPrefix;
440211
440307
  const ghost = hasMatchesForNav && matches3[selectedIdx]?.cmd.startsWith(commandToken) ? matches3[selectedIdx].cmd.slice(value.length) : "";
440212
440308
  const maxVisible = Math.min(8, Math.max(4, Math.floor(termRows * 0.25)));
@@ -440256,7 +440352,8 @@ var init_InputBox = __esm(async () => {
440256
440352
  setVisualLines(1);
440257
440353
  }, []);
440258
440354
  const handleSubmit = import_react34.useCallback((input_0) => {
440259
- if (hasMatchesForNav && matches3[selectedIdx]) {
440355
+ const useAutocomplete = hasMatchesForNav || showAutocomplete && hasMatches && matches3[selectedIdx];
440356
+ if (useAutocomplete && matches3[selectedIdx]) {
440260
440357
  const completed_0 = matches3[selectedIdx].cmd;
440261
440358
  if (completed_0 === "/open" || completed_0 === "/git branch") {
440262
440359
  const withSpace = `${completed_0} `;
@@ -440288,7 +440385,7 @@ var init_InputBox = __esm(async () => {
440288
440385
  pushHistory(finalInput.trim());
440289
440386
  onSubmit(finalInput.trim());
440290
440387
  resetInput();
440291
- }, [matches3, selectedIdx, pushHistory, onSubmit, resetInput, isLoading, isCompacting, onQueue, hasMatchesForNav]);
440388
+ }, [matches3, selectedIdx, pushHistory, onSubmit, resetInput, isLoading, isCompacting, onQueue, hasMatchesForNav, showAutocomplete, hasMatches]);
440292
440389
  const handleContentChange = import_react34.useCallback(() => {
440293
440390
  const text_0 = textareaRef.current?.plainText ?? "";
440294
440391
  if (isNavigatingHistory.current) {
@@ -451191,14 +451288,30 @@ function LoadingStatus({
451191
451288
  flexDirection: "column",
451192
451289
  flexShrink: 0,
451193
451290
  children: [
451194
- showBusy && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
451195
- height: 1,
451196
- paddingX: 1,
451197
- children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
451198
- ref: scanRef,
451199
- content: buildScanContent(scanPosRef.current, scanWidth)
451200
- }, undefined, false, undefined, this)
451201
- }, undefined, false, undefined, this),
451291
+ showBusy && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
451292
+ children: [
451293
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
451294
+ height: 1,
451295
+ paddingX: 1,
451296
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
451297
+ fg: getThemeTokens().error,
451298
+ attributes: TextAttributes.BOLD,
451299
+ children: [
451300
+ icon("stop"),
451301
+ " ^X to stop"
451302
+ ]
451303
+ }, undefined, true, undefined, this)
451304
+ }, undefined, false, undefined, this),
451305
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
451306
+ height: 1,
451307
+ paddingX: 1,
451308
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
451309
+ ref: scanRef,
451310
+ content: buildScanContent(scanPosRef.current, scanWidth)
451311
+ }, undefined, false, undefined, this)
451312
+ }, undefined, false, undefined, this)
451313
+ ]
451314
+ }, undefined, true, undefined, this),
451202
451315
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
451203
451316
  height: 1,
451204
451317
  flexDirection: "row",
@@ -473414,6 +473527,8 @@ function readValuesFromLayer(layer) {
473414
473527
  v4.speed = layer.performance.speed;
473415
473528
  if (layer.performance?.sendReasoning !== undefined)
473416
473529
  v4.sendReasoning = layer.performance.sendReasoning;
473530
+ if (layer.performance?.toolStreaming !== undefined)
473531
+ v4.toolStreaming = layer.performance.toolStreaming;
473417
473532
  if (layer.performance?.disableParallelToolUse !== undefined)
473418
473533
  v4.disableParallelToolUse = layer.performance.disableParallelToolUse;
473419
473534
  if (layer.performance?.openaiReasoningEffort !== undefined)
@@ -473422,6 +473537,10 @@ function readValuesFromLayer(layer) {
473422
473537
  v4.serviceTier = layer.performance.serviceTier;
473423
473538
  if (layer.codeExecution !== undefined)
473424
473539
  v4.codeExecution = layer.codeExecution;
473540
+ if (layer.computerUse !== undefined)
473541
+ v4.computerUse = layer.computerUse;
473542
+ if (layer.anthropicTextEditor !== undefined)
473543
+ v4.anthropicTextEditor = layer.anthropicTextEditor;
473425
473544
  if (layer.webSearch !== undefined)
473426
473545
  v4.webSearch = layer.webSearch;
473427
473546
  if (layer.contextManagement?.compact !== undefined)
@@ -473480,6 +473599,12 @@ function buildPatch(key3, value) {
473480
473599
  sendReasoning: value
473481
473600
  }
473482
473601
  };
473602
+ case "toolStreaming":
473603
+ return {
473604
+ performance: {
473605
+ toolStreaming: value
473606
+ }
473607
+ };
473483
473608
  case "disableParallelToolUse":
473484
473609
  return {
473485
473610
  performance: {
@@ -473502,6 +473627,14 @@ function buildPatch(key3, value) {
473502
473627
  return {
473503
473628
  codeExecution: value
473504
473629
  };
473630
+ case "computerUse":
473631
+ return {
473632
+ computerUse: value
473633
+ };
473634
+ case "anthropicTextEditor":
473635
+ return {
473636
+ anthropicTextEditor: value
473637
+ };
473505
473638
  case "webSearch":
473506
473639
  return {
473507
473640
  webSearch: value
@@ -473562,7 +473695,7 @@ function ProviderSettings(t0) {
473562
473695
  const containerRows = termRows - 2;
473563
473696
  const popupWidth = Math.min(MAX_POPUP_WIDTH11, Math.floor(termCols * 0.85));
473564
473697
  const innerW = popupWidth - 2;
473565
- const maxVisible = Math.max(4, Math.floor(containerRows * 0.8) - CHROME_ROWS16);
473698
+ const maxVisible = Math.max(4, Math.floor(containerRows * 0.85) - CHROME_ROWS16);
473566
473699
  const t2 = useTheme();
473567
473700
  const [tab, setTab] = import_react110.useState("claude");
473568
473701
  const {
@@ -474165,7 +474298,7 @@ function ProviderSettings(t0) {
474165
474298
  }
474166
474299
  return t33;
474167
474300
  }
474168
- var import_compiler_runtime62, import_react110, MAX_POPUP_WIDTH11 = 78, CHROME_ROWS16 = 7, TABS3, TAB_LABELS2, TAB_ICONS, CLAUDE_ITEMS, OPENAI_ITEMS, GENERAL_ITEMS, TAB_ITEMS, DEFAULTS;
474301
+ var import_compiler_runtime62, import_react110, MAX_POPUP_WIDTH11 = 88, CHROME_ROWS16 = 7, TABS3, TAB_LABELS2, TAB_ICONS, CLAUDE_ITEMS, OPENAI_ITEMS, GENERAL_ITEMS, TAB_ITEMS, DEFAULTS;
474169
474302
  var init_ProviderSettings = __esm(async () => {
474170
474303
  init_icons();
474171
474304
  init_theme();
@@ -474210,9 +474343,29 @@ var init_ProviderSettings = __esm(async () => {
474210
474343
  }, {
474211
474344
  key: "speed",
474212
474345
  label: "Speed",
474213
- desc: "Opus only \u2014 2.5x faster output (requires SDK update)",
474346
+ desc: "Opus 4.6 \u2014 2.5x faster output (standard | fast)",
474214
474347
  type: "cycle",
474215
474348
  options: ["off", "standard", "fast"]
474349
+ }, {
474350
+ key: "codeExecution",
474351
+ label: "Code Execution",
474352
+ desc: "Sandboxed code evaluation (Python/Bash)",
474353
+ type: "toggle"
474354
+ }, {
474355
+ key: "computerUse",
474356
+ label: "Computer Use",
474357
+ desc: "Keyboard/mouse/screenshot control",
474358
+ type: "toggle"
474359
+ }, {
474360
+ key: "anthropicTextEditor",
474361
+ label: "Anthropic Text Editor",
474362
+ desc: "Anthropic's str_replace editor tool",
474363
+ type: "toggle"
474364
+ }, {
474365
+ key: "toolStreaming",
474366
+ label: "Tool Streaming",
474367
+ desc: "Stream tool call args incrementally (disable to debug)",
474368
+ type: "toggle"
474216
474369
  }, {
474217
474370
  key: "sendReasoning",
474218
474371
  label: "Send Reasoning",
@@ -474221,24 +474374,18 @@ var init_ProviderSettings = __esm(async () => {
474221
474374
  }, {
474222
474375
  key: "compact",
474223
474376
  label: "Server Compaction",
474224
- desc: "API-level context compaction (200K+ models)",
474377
+ desc: "Anthropic server-side context compaction (200K+ models)",
474225
474378
  type: "toggle"
474226
474379
  }, {
474227
474380
  key: "clearToolUses",
474228
474381
  label: "Clear Tool Uses",
474229
- desc: "Auto-clear old tool results, keep last 10",
474382
+ desc: "Server-side \u2014 auto-clear old tool results, keep last 6",
474230
474383
  type: "toggle"
474231
474384
  }, {
474232
474385
  key: "clearThinking",
474233
474386
  label: "Clear Thinking",
474234
- desc: "Auto-clear old thinking blocks, keep last 5",
474387
+ desc: "Server-side \u2014 auto-clear old thinking blocks, keep last 2",
474235
474388
  type: "toggle"
474236
- }, {
474237
- key: "pruning",
474238
- label: "Tool Result Pruning",
474239
- desc: "Compact old tool results \u2014 main | subagents | both | none",
474240
- type: "cycle",
474241
- options: ["none", "main", "subagents", "both"]
474242
474389
  }];
474243
474390
  OPENAI_ITEMS = [{
474244
474391
  key: "openaiReasoningEffort",
@@ -474258,16 +474405,17 @@ var init_ProviderSettings = __esm(async () => {
474258
474405
  label: "Sequential Tools",
474259
474406
  desc: "One tool at a time instead of parallel (all providers)",
474260
474407
  type: "toggle"
474261
- }, {
474262
- key: "codeExecution",
474263
- label: "Code Execution",
474264
- desc: "Sandboxed code evaluation",
474265
- type: "toggle"
474266
474408
  }, {
474267
474409
  key: "webSearch",
474268
474410
  label: "Web Search",
474269
474411
  desc: "Allow web search tool",
474270
474412
  type: "toggle"
474413
+ }, {
474414
+ key: "pruning",
474415
+ label: "Tool Result Pruning",
474416
+ desc: "Client-side \u2014 compact old tool results: main | subagents | both | none",
474417
+ type: "cycle",
474418
+ options: ["none", "main", "subagents", "both"]
474271
474419
  }];
474272
474420
  TAB_ITEMS = {
474273
474421
  claude: CLAUDE_ITEMS,
@@ -474280,10 +474428,13 @@ var init_ProviderSettings = __esm(async () => {
474280
474428
  effort: "off",
474281
474429
  speed: "off",
474282
474430
  sendReasoning: false,
474431
+ toolStreaming: true,
474283
474432
  disableParallelToolUse: false,
474284
474433
  openaiReasoningEffort: "off",
474285
474434
  serviceTier: "off",
474286
474435
  codeExecution: false,
474436
+ computerUse: false,
474437
+ anthropicTextEditor: false,
474287
474438
  webSearch: true,
474288
474439
  compact: false,
474289
474440
  clearToolUses: false,
@@ -477646,7 +477797,11 @@ function App({
477646
477797
  saveToScope,
477647
477798
  detectScope,
477648
477799
  agentFeatures: effectiveConfig.agentFeatures,
477649
- instructionFiles: effectiveConfig.instructionFiles
477800
+ instructionFiles: effectiveConfig.instructionFiles,
477801
+ syncActiveModel: (modelId) => {
477802
+ chat_0.setActiveModel(modelId);
477803
+ setActiveModelForHeader(modelId);
477804
+ }
477650
477805
  });
477651
477806
  }, [tabMgr, toggleEditor, nvimOpen, handleExit, cwd2, git, contextManager, handleSuspend, openEditorWithFile, effectiveConfig.nvimConfig, effectiveConfig.vimHints, effectiveConfig.verbose, effectiveConfig.diffStyle, effectiveConfig.autoCompactDiffs, effectiveConfig.compaction?.strategy, saveToScope, detectScope, effectiveConfig.agentFeatures, effectiveConfig.instructionFiles]);
477652
477807
  const closeLlmSelector = import_react120.useCallback(() => {
@@ -477964,13 +478119,13 @@ function App({
477964
478119
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(LlmSelector, {
477965
478120
  visible: modalLlmSelector,
477966
478121
  activeModel: activeModelForHeader,
477967
- onSelect: (modelId) => {
478122
+ onSelect: (modelId_0) => {
477968
478123
  const slot = useUIStore.getState().routerSlotPicking;
477969
478124
  if (slot) {
477970
478125
  const current = effectiveConfig.taskRouter ?? DEFAULT_TASK_ROUTER;
477971
478126
  const updated = {
477972
478127
  ...current,
477973
- [slot]: modelId
478128
+ [slot]: modelId_0
477974
478129
  };
477975
478130
  saveToScope({
477976
478131
  taskRouter: updated
@@ -477979,11 +478134,11 @@ function App({
477979
478134
  useUIStore.getState().closeModal("llmSelector");
477980
478135
  useUIStore.getState().openModal("routerSettings");
477981
478136
  } else {
477982
- activeChatRef.current?.setActiveModel(modelId);
477983
- notifyProviderSwitch(modelId);
477984
- setActiveModelForHeader(modelId);
478137
+ activeChatRef.current?.setActiveModel(modelId_0);
478138
+ notifyProviderSwitch(modelId_0);
478139
+ setActiveModelForHeader(modelId_0);
477985
478140
  saveToScope({
477986
- defaultModel: modelId
478141
+ defaultModel: modelId_0
477987
478142
  }, modelScope);
477988
478143
  const wasFromWizard_0 = wizardOpenedLlm.current;
477989
478144
  wizardOpenedLlm.current = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proxysoul/soulforge",
3
- "version": "1.7.3",
3
+ "version": "1.7.5",
4
4
  "description": "Graph-powered code intelligence — multi-agent coding with codebase-aware AI",
5
5
  "repository": {
6
6
  "type": "git",