@proxysoul/soulforge 2.18.5 → 2.18.6

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 +129 -27
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -65784,18 +65784,23 @@ var init_auth = __esm(() => {
65784
65784
  });
65785
65785
 
65786
65786
  // src/core/llm/providers/codex/index.ts
65787
- var CODEX_FALLBACK_MODELS, CODEX_CONTEXT_WINDOWS, codex;
65787
+ var GPT_55_INPUT_CONTEXT = 272000, CODEX_FALLBACK_MODELS, CODEX_CONTEXT_WINDOWS, CODEX_CONTEXT_WINDOW_OVERRIDES, codex;
65788
65788
  var init_codex = __esm(() => {
65789
65789
  init_client();
65790
65790
  init_runner();
65791
65791
  CODEX_FALLBACK_MODELS = [
65792
+ { id: "gpt-5.5", name: "GPT-5.5", contextWindow: GPT_55_INPUT_CONTEXT },
65792
65793
  { id: "gpt-5.4", name: "GPT-5.4", contextWindow: 1050000 },
65793
65794
  { id: "gpt-5.2-codex", name: "GPT-5.2-Codex", contextWindow: 400000 }
65794
65795
  ];
65795
65796
  CODEX_CONTEXT_WINDOWS = [
65797
+ ["gpt-5.5", GPT_55_INPUT_CONTEXT],
65796
65798
  ["gpt-5.4", 1050000],
65797
65799
  ["gpt-5.2-codex", 400000]
65798
65800
  ];
65801
+ CODEX_CONTEXT_WINDOW_OVERRIDES = [
65802
+ ["gpt-5.5", GPT_55_INPUT_CONTEXT]
65803
+ ];
65799
65804
  codex = {
65800
65805
  id: "codex",
65801
65806
  name: "Codex",
@@ -65822,6 +65827,7 @@ var init_codex = __esm(() => {
65822
65827
  },
65823
65828
  fallbackModels: CODEX_FALLBACK_MODELS,
65824
65829
  contextWindows: CODEX_CONTEXT_WINDOWS,
65830
+ contextWindowOverrides: CODEX_CONTEXT_WINDOW_OVERRIDES,
65825
65831
  checkAvailability: async () => {
65826
65832
  const status = getCodexLoginStatus();
65827
65833
  return status.installed && status.loggedIn;
@@ -71776,7 +71782,7 @@ var package_default;
71776
71782
  var init_package = __esm(() => {
71777
71783
  package_default = {
71778
71784
  name: "@proxysoul/soulforge",
71779
- version: "2.18.5",
71785
+ version: "2.18.6",
71780
71786
  description: "Graph-powered code intelligence \u2014 multi-agent coding with codebase-aware AI",
71781
71787
  repository: {
71782
71788
  type: "git",
@@ -404475,7 +404481,37 @@ function sanitizeMessages(messages) {
404475
404481
  dirty = true;
404476
404482
  return { ...msg, content };
404477
404483
  });
404478
- return dirty ? cleaned : messages;
404484
+ const result = dirty ? cleaned : [...messages];
404485
+ const allValidCallIds = new Set;
404486
+ for (const msg of result) {
404487
+ if (msg?.role !== "assistant" || !Array.isArray(msg.content))
404488
+ continue;
404489
+ for (const p of msg.content) {
404490
+ const part = p;
404491
+ if (part?.type === "tool-call" && typeof part.toolCallId === "string" && !part.providerExecuted) {
404492
+ allValidCallIds.add(part.toolCallId);
404493
+ }
404494
+ }
404495
+ }
404496
+ for (let i2 = result.length - 1;i2 >= 0; i2--) {
404497
+ const msg = result[i2];
404498
+ if (!msg || msg.role !== "tool" || !Array.isArray(msg.content))
404499
+ continue;
404500
+ const filtered = msg.content.filter((p) => {
404501
+ const part = p;
404502
+ if (part?.type !== "tool-result")
404503
+ return true;
404504
+ return allValidCallIds.has(part.toolCallId);
404505
+ });
404506
+ if (filtered.length === 0) {
404507
+ result.splice(i2, 1);
404508
+ dirty = true;
404509
+ } else if (filtered.length !== msg.content.length) {
404510
+ result[i2] = { ...msg, content: filtered };
404511
+ dirty = true;
404512
+ }
404513
+ }
404514
+ return dirty ? result : messages;
404479
404515
  }
404480
404516
  function sanitizeToolInputsStep({
404481
404517
  messages,
@@ -407294,7 +407330,7 @@ var init_addons = __esm(() => {
407294
407330
  function isAnthropicModel(modelId) {
407295
407331
  return modelId.toLowerCase().startsWith("claude");
407296
407332
  }
407297
- var baseURL, proxy2;
407333
+ var baseURL, GPT_55_INPUT_CONTEXT2 = 272000, proxy2;
407298
407334
  var init_proxy2 = __esm(() => {
407299
407335
  init_dist6();
407300
407336
  init_dist8();
@@ -407346,8 +407382,10 @@ var init_proxy2 = __esm(() => {
407346
407382
  { id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5" },
407347
407383
  { id: "claude-sonnet-4-20250514", name: "Claude Sonnet 4" },
407348
407384
  { id: "claude-opus-4-20250514", name: "Claude Opus 4" },
407349
- { id: "claude-haiku-3-5-20241022", name: "Claude Haiku 3.5" }
407385
+ { id: "claude-haiku-3-5-20241022", name: "Claude Haiku 3.5" },
407386
+ { id: "gpt-5.5", name: "GPT-5.5", contextWindow: GPT_55_INPUT_CONTEXT2 }
407350
407387
  ],
407388
+ contextWindowOverrides: [["gpt-5.5", GPT_55_INPUT_CONTEXT2]],
407351
407389
  contextWindows: [
407352
407390
  ["claude-opus-4-8", 1e6],
407353
407391
  ["claude-opus-4.8", 1e6],
@@ -407370,6 +407408,7 @@ var init_proxy2 = __esm(() => {
407370
407408
  ["claude-3-5-sonnet", 200000],
407371
407409
  ["claude-3.5-haiku", 200000],
407372
407410
  ["claude-3-5-haiku", 200000],
407411
+ ["gpt-5.5", GPT_55_INPUT_CONTEXT2],
407373
407412
  ["gpt-5-chat", 128000],
407374
407413
  ["gpt-4.1", 1048576],
407375
407414
  ["grok-4.1", 2000000],
@@ -410619,6 +410658,7 @@ var init_providers = __esm(() => {
410619
410658
  var exports_models = {};
410620
410659
  __export(exports_models, {
410621
410660
  prewarmAllModels: () => prewarmAllModels,
410661
+ matchesContextOverride: () => matchesContextOverride,
410622
410662
  invalidateProviderModelCache: () => invalidateProviderModelCache,
410623
410663
  getShortModelLabel: () => getShortModelLabel,
410624
410664
  getOpenRouterModelPricing: () => getOpenRouterModelPricing,
@@ -410633,6 +410673,7 @@ __export(exports_models, {
410633
410673
  fetchOpenRouterMetadata: () => fetchOpenRouterMetadata,
410634
410674
  fetchGroupedModels: () => fetchGroupedModels,
410635
410675
  ensureModelMetadata: () => ensureModelMetadata,
410676
+ applyProviderContextOverride: () => applyProviderContextOverride,
410636
410677
  PROVIDER_CONFIGS: () => PROVIDER_CONFIGS
410637
410678
  });
410638
410679
  function buildProviderConfigs() {
@@ -410647,6 +410688,26 @@ function buildProviderConfigs() {
410647
410688
  fallbackModels: p.fallbackModels
410648
410689
  }));
410649
410690
  }
410691
+ function matchesContextOverride(model, pattern) {
410692
+ const lowerModel = model.toLowerCase();
410693
+ const lowerPattern = pattern.toLowerCase();
410694
+ const bareModel = lowerModel.split("/").pop() ?? lowerModel;
410695
+ const barePattern = lowerPattern.split("/").pop() ?? lowerPattern;
410696
+ return bareModel === barePattern || lowerModel === lowerPattern || lowerModel.endsWith(`/${lowerPattern}`);
410697
+ }
410698
+ function findContextOverride(provider, model) {
410699
+ if (!provider?.contextWindowOverrides)
410700
+ return;
410701
+ for (const [pattern, tokens] of provider.contextWindowOverrides) {
410702
+ if (matchesContextOverride(model, pattern))
410703
+ return tokens;
410704
+ }
410705
+ return;
410706
+ }
410707
+ function applyProviderContextOverride(providerId, model) {
410708
+ const tokens = findContextOverride(getProvider(providerId), model.id);
410709
+ return tokens ? { ...model, contextWindow: tokens } : model;
410710
+ }
410650
410711
  function getModelContextInfoSync(modelId) {
410651
410712
  const slashIdx = modelId.indexOf("/");
410652
410713
  const providerId = slashIdx >= 0 ? modelId.slice(0, slashIdx) : "";
@@ -410659,12 +410720,9 @@ function getModelContextInfoSync(modelId) {
410659
410720
  }
410660
410721
  } catch {}
410661
410722
  const ownProvider = providerId ? getProvider(providerId) : null;
410662
- if (ownProvider?.contextWindowOverrides) {
410663
- for (const [pattern, tokens] of ownProvider.contextWindowOverrides) {
410664
- if (model.includes(pattern))
410665
- return { tokens, source: "fallback" };
410666
- }
410667
- }
410723
+ const overrideTokens = providerId ? findContextOverride(ownProvider ?? undefined, model) : getAllProviders().map((provider) => findContextOverride(provider, model)).find((tokens) => tokens !== undefined);
410724
+ if (overrideTokens)
410725
+ return { tokens: overrideTokens, source: "override" };
410668
410726
  if (providerId && !ownProvider?.grouped) {
410669
410727
  const entry = modelCache.get(providerId);
410670
410728
  if (entry && Date.now() - entry.ts <= MODEL_CACHE_TTL) {
@@ -410874,10 +410932,13 @@ async function fetchProviderModels(providerId, { bypassCache = false } = {}) {
410874
410932
  try {
410875
410933
  const models = await provider.fetchModels();
410876
410934
  if (models) {
410877
- modelCache.set(providerId, { models, ts: Date.now() });
410878
- return { models };
410935
+ const normalized = models.map((m2) => applyProviderContextOverride(providerId, m2));
410936
+ modelCache.set(providerId, { models: normalized, ts: Date.now() });
410937
+ return { models: normalized };
410879
410938
  }
410880
- return { models: provider.fallbackModels };
410939
+ return {
410940
+ models: provider.fallbackModels.map((m2) => applyProviderContextOverride(providerId, m2))
410941
+ };
410881
410942
  } catch (err2) {
410882
410943
  const msg = toErrorMessage(err2);
410883
410944
  return { models: [], error: `API error: ${msg}` };
@@ -411062,11 +411123,11 @@ async function fetchProxyGrouped() {
411062
411123
  if (!grouped[group])
411063
411124
  grouped[group] = [];
411064
411125
  const ctxWindow = m2.context_length ?? anthropicCtx.get(m2.id) ?? findOpenRouterModel(m2.id)?.context_length;
411065
- grouped[group].push({
411126
+ grouped[group].push(applyProviderContextOverride("proxy", {
411066
411127
  id: m2.id,
411067
411128
  name: m2.id,
411068
411129
  contextWindow: ctxWindow
411069
- });
411130
+ }));
411070
411131
  }
411071
411132
  const subProviders = Object.keys(grouped).sort().map((id) => ({ id, name: GROUP_DISPLAY_NAMES[id] ?? titleCase(id) }));
411072
411133
  const result = {
@@ -444135,7 +444196,11 @@ Avoid these files. If you must edit one, your edit will still apply but may conf
444135
444196
  const task = tasks[0];
444136
444197
  const { doneResult, resultText } = await runAgentTask(task, models, bus, toolCallId, 1, abortSignal);
444137
444198
  if (!doneResult && !bus.getResult(task.agentId)?.success) {
444138
- throw new Error(resultText);
444199
+ return {
444200
+ reads: bus.getFileReadRecords(task.agentId),
444201
+ filesEdited: [...bus.getEditedFiles(task.agentId).keys()],
444202
+ output: `[Dispatch failed] ${resultText}`
444203
+ };
444139
444204
  }
444140
444205
  const editedMap = bus.getEditedFiles(task.agentId);
444141
444206
  const desloppifyResult2 = await runDesloppify(bus, [task], models, toolCallId, abortSignal);
@@ -444758,6 +444823,7 @@ function buildInstructions(cm, modelId) {
444758
444823
  const text2 = parts2.join(`
444759
444824
 
444760
444825
  `);
444826
+ cm.setInstructionsSize(text2.length);
444761
444827
  if (snapshot)
444762
444828
  instructionsCache.set(cm, { text: text2, key: key2 });
444763
444829
  return text2;
@@ -446459,6 +446525,7 @@ var init_manager6 = __esm(() => {
446459
446525
  mentionedFiles = new Set;
446460
446526
  conversationTokens = 0;
446461
446527
  contextWindowTokens = DEFAULT_CONTEXT_WINDOW2;
446528
+ lastInstructionsSize;
446462
446529
  repoMapCache = null;
446463
446530
  soulMapDiffChangedFiles = new Map;
446464
446531
  soulMapDiffSeq = 0;
@@ -446984,6 +447051,12 @@ var init_manager6 = __esm(() => {
446984
447051
  this.startRepoMapScan();
446985
447052
  }
446986
447053
  }
447054
+ setInstructionsSize(size) {
447055
+ this.lastInstructionsSize = size;
447056
+ }
447057
+ getInstructionsSize() {
447058
+ return this.lastInstructionsSize;
447059
+ }
446987
447060
  async setSemanticSummaries(modeOrBool) {
446988
447061
  const mode = modeOrBool === true ? "synthetic" : modeOrBool === false ? "off" : modeOrBool === "on" ? "full" : modeOrBool;
446989
447062
  this.repoMap.setSemanticMode(mode);
@@ -447345,9 +447418,10 @@ ${s.signature ? `${s.signature}
447345
447418
  }
447346
447419
  getContextBreakdown() {
447347
447420
  const sections = [];
447421
+ const cachedSize = this.getInstructionsSize();
447348
447422
  sections.push({
447349
- section: "Core + tool reference",
447350
- chars: 1800,
447423
+ section: "System prompt + tools",
447424
+ chars: cachedSize ?? 1800,
447351
447425
  active: true
447352
447426
  });
447353
447427
  const projectInfo = this.projectInfoCache?.info ?? null;
@@ -474716,12 +474790,13 @@ function useChat({
474716
474790
  const prevSyncedModel = import_react46.useRef("");
474717
474791
  if (activeModel !== prevSyncedModel.current && activeModel !== "none") {
474718
474792
  prevSyncedModel.current = activeModel;
474793
+ const { tokens: sync, source } = getModelContextInfoSync(activeModel);
474719
474794
  const cached3 = pinnedContextWindow.current.get(activeModel);
474720
- const sync = cached3 || getModelContextInfoSync(activeModel).tokens;
474721
- pinnedContextWindow.current.set(activeModel, sync);
474722
- contextManagerRef.current.setContextWindow(sync);
474795
+ const next = source === "fallback" ? cached3 ?? sync : sync;
474796
+ pinnedContextWindow.current.set(activeModel, next);
474797
+ contextManagerRef.current.setContextWindow(next);
474723
474798
  if (visible)
474724
- useStatusBarStore.getState().setContextWindow(sync);
474799
+ useStatusBarStore.getState().setContextWindow(next);
474725
474800
  }
474726
474801
  const activeModelForEffect = activeModel;
474727
474802
  import_react46.useEffect(() => {
@@ -475286,7 +475361,7 @@ INCLUDE the plan progress above VERBATIM in ## Current State so the agent knows
475286
475361
  const afterChars = systemChars + newCoreChars;
475287
475362
  const afterPct = Math.round(afterChars / charsPerToken / contextWindow * 100);
475288
475363
  const estimatedTokens = Math.ceil(afterChars / charsPerToken);
475289
- setContextTokens(0);
475364
+ setContextTokens(estimatedTokens);
475290
475365
  setStreamingChars(0);
475291
475366
  setTokenUsage((prev) => {
475292
475367
  let bd = prev.modelBreakdown;
@@ -475721,7 +475796,7 @@ ${description}`,
475721
475796
  sanitized.push(m5);
475722
475797
  if (m5.role !== "assistant" || !Array.isArray(m5.content))
475723
475798
  continue;
475724
- const callParts = m5.content.filter((p3) => typeof p3 === "object" && ("type" in p3) && p3.type === "tool-call");
475799
+ const callParts = m5.content.filter((p3) => typeof p3 === "object" && ("type" in p3) && p3.type === "tool-call" && !p3.providerExecuted);
475725
475800
  if (callParts.length === 0)
475726
475801
  continue;
475727
475802
  const next = sanitizedPre[i4 + 1];
@@ -475748,6 +475823,30 @@ ${description}`,
475748
475823
  sanitized.push({ role: "tool", content: synthetic });
475749
475824
  }
475750
475825
  }
475826
+ for (let i4 = sanitized.length - 1;i4 >= 0; i4--) {
475827
+ const msg = sanitized[i4];
475828
+ if (!msg || msg.role !== "tool" || !Array.isArray(msg.content))
475829
+ continue;
475830
+ const prev = sanitized[i4 - 1];
475831
+ const validCallIds = new Set;
475832
+ if (prev?.role === "assistant" && Array.isArray(prev.content)) {
475833
+ for (const p3 of prev.content) {
475834
+ if (typeof p3 === "object" && "type" in p3 && p3.type === "tool-call" && !p3.providerExecuted) {
475835
+ validCallIds.add(p3.toolCallId);
475836
+ }
475837
+ }
475838
+ }
475839
+ const filtered = msg.content.filter((p3) => {
475840
+ if (typeof p3 !== "object" || !("type" in p3) || p3.type !== "tool-result")
475841
+ return true;
475842
+ return validCallIds.has(p3.toolCallId);
475843
+ });
475844
+ if (filtered.length === 0) {
475845
+ sanitized.splice(i4, 1);
475846
+ } else if (filtered.length !== msg.content.length) {
475847
+ sanitized[i4] = { ...msg, content: filtered };
475848
+ }
475849
+ }
475751
475850
  const newCoreMessages = [...sanitized, userCoreMsg];
475752
475851
  setCoreMessages(newCoreMessages);
475753
475852
  if (workingStateRef.current) {
@@ -475948,6 +476047,9 @@ ${description}`,
475948
476047
  finalSegments.length = 0;
475949
476048
  subagentCumulative.clear();
475950
476049
  completedResultChars.clear();
476050
+ stallTriggered = false;
476051
+ stallAborted = false;
476052
+ stallRetryPendingRef.current = false;
475951
476053
  try {
475952
476054
  setIsLoading(true);
475953
476055
  const modelId = activeModelRef.current;
@@ -477169,8 +477271,8 @@ ${errStack}` : `Error: ${displayErr}`);
477169
477271
  setLiveToolCalls([]);
477170
477272
  stallRetryPendingRef.current = true;
477171
477273
  const backoffMs = stallRetryCountRef.current === 1 ? 2000 : 5000;
477172
- setTimeout(() => handleSubmitRef.current("Continue."), backoffMs);
477173
- return;
477274
+ await new Promise((resolve40) => setTimeout(resolve40, backoffMs));
477275
+ continue;
477174
477276
  }
477175
477277
  const rawMsg = err2 instanceof Error ? err2.message : String(err2);
477176
477278
  const rawStack = err2 instanceof Error ? err2.stack : undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proxysoul/soulforge",
3
- "version": "2.18.5",
3
+ "version": "2.18.6",
4
4
  "description": "Graph-powered code intelligence — multi-agent coding with codebase-aware AI",
5
5
  "repository": {
6
6
  "type": "git",