openfox 2.0.123 → 2.0.124

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 (39) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/CHANGELOG.md +16 -0
  3. package/dist/{auto-config-4BFGLPCP.js → auto-config-454YE6KC.js} +6 -66
  4. package/dist/{chat-handler-UWZYFGRY.js → chat-handler-N43TBYLV.js} +8 -8
  5. package/dist/{chunk-YGOF4QDW.js → chunk-57UCBFBD.js} +6 -6
  6. package/dist/{chunk-4L7UMEHD.js → chunk-5CCM655F.js} +85 -12
  7. package/dist/{chunk-H4JRR5KV.js → chunk-A6EZBX62.js} +2 -2
  8. package/dist/{chunk-PZUKG3OZ.js → chunk-FAL4WO4V.js} +3 -3
  9. package/dist/{chunk-TPDBUOPN.js → chunk-ISE55FOR.js} +11 -4
  10. package/dist/{chunk-INOO465O.js → chunk-KD4W3I6C.js} +108 -29
  11. package/dist/{chunk-ZKMZI4ZG.js → chunk-KGFERMCV.js} +4 -4
  12. package/dist/{chunk-V2UJP5CX.js → chunk-QJNBQCAF.js} +4 -4
  13. package/dist/{chunk-YU5QPXSU.js → chunk-RXLAFEZB.js} +4 -4
  14. package/dist/chunk-SBADOWVC.js +7 -0
  15. package/dist/{chunk-SS6KV6DI.js → chunk-UGEFD67O.js} +2 -2
  16. package/dist/{chunk-FFEZJBQO.js → chunk-VUBFPRKT.js} +29 -29
  17. package/dist/cli/dev.js +1 -1
  18. package/dist/cli/index.js +1 -1
  19. package/dist/{dynamic-context-5TPG2AJL.js → dynamic-context-KTQCAPTK.js} +2 -2
  20. package/dist/{launch-5PJLLVXV.js → launch-Z5D5YFRJ.js} +9 -9
  21. package/dist/{model-catalog-T2GQFJI4.js → model-catalog-ZLOWTQA7.js} +2 -2
  22. package/dist/{orchestrator-2Q3R5KKR.js → orchestrator-BQBBO4US.js} +8 -8
  23. package/dist/package.json +1 -1
  24. package/dist/{path-security-NRO37OAP.js → path-security-YTPZ35SL.js} +6 -4
  25. package/dist/{processor-N2XW2KJV.js → processor-WTRVYXAO.js} +7 -7
  26. package/dist/{provider-EBL6Z7TV.js → provider-LICG53GG.js} +3 -3
  27. package/dist/{provider-manager-MKF27CTA.js → provider-manager-3QC2MSSR.js} +3 -3
  28. package/dist/{serve-TARX23JF.js → serve-75G5Z7UQ.js} +12 -12
  29. package/dist/server/index.js +11 -11
  30. package/dist/{server-FKVRW7RV.js → server-N3VATHIA.js} +10 -10
  31. package/dist/{service-SY6Y4BIM.js → service-OURGS2SI.js} +4 -4
  32. package/dist/{tasks-IDIKTBOR.js → tasks-4SOLTX6A.js} +4 -4
  33. package/dist/{tools-YPVZ5QM2.js → tools-G44LBKD4.js} +6 -6
  34. package/dist/{update-VSSOHC47.js → update-R2TEHD7V.js} +2 -2
  35. package/dist/web/assets/{index-C10YdCOU.js → index-GZTGHRRr.js} +65 -65
  36. package/dist/web/index.html +1 -1
  37. package/dist/web/sw.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-LXCDR3H5.js +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.124 - 2026-08-19
4
+
5
+ ### Enhancements
6
+
7
+ - **project_tasks list paginates** — capped at 10 results (25 max) to keep agent context lean
8
+ - **Pinned effort chips light up for any model** — the selector highlights a model's pinned effort even when it isn't the active pick
9
+
10
+ ### Bug Fixes
11
+
12
+ - **Reasoning effort options come from a curated catalog** — endpoint probing that collapsed or misdetected levels is gone
13
+ - **Qwen effort presets corrected** — qwen3.8 offers none/low/medium/xhigh (default xhigh), qwen3.5/3.6 offer none/high
14
+ - **maxTokens budget accounts for tool results** — tool-result tokens are subtracted so large outputs no longer overstate the budget
15
+ - **Context-overflow retries halve maxTokens** — retry immediately with a halved budget instead of a doomed backoff retry
16
+ - **`..` paths respect shell cd state** — relative traversals no longer trigger false outside-sandbox confirmations
17
+ - **Division expressions no longer flagged as paths** — 'length / 4' no longer trips the root-path safety check
18
+
3
19
  ## 2.0.123 - 2026-08-18
4
20
 
5
21
  ### Features
package/dist/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.124 - 2026-08-19
4
+
5
+ ### Enhancements
6
+
7
+ - **project_tasks list paginates** — capped at 10 results (25 max) to keep agent context lean
8
+ - **Pinned effort chips light up for any model** — the selector highlights a model's pinned effort even when it isn't the active pick
9
+
10
+ ### Bug Fixes
11
+
12
+ - **Reasoning effort options come from a curated catalog** — endpoint probing that collapsed or misdetected levels is gone
13
+ - **Qwen effort presets corrected** — qwen3.8 offers none/low/medium/xhigh (default xhigh), qwen3.5/3.6 offer none/high
14
+ - **maxTokens budget accounts for tool results** — tool-result tokens are subtracted so large outputs no longer overstate the budget
15
+ - **Context-overflow retries halve maxTokens** — retry immediately with a halved budget instead of a doomed backoff retry
16
+ - **`..` paths respect shell cd state** — relative traversals no longer trigger false outside-sandbox confirmations
17
+ - **Division expressions no longer flagged as paths** — 'length / 4' no longer trips the root-path safety check
18
+
3
19
  ## 2.0.123 - 2026-08-18
4
20
 
5
21
  ### Features
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-HNCM3D7Y.js";
7
7
  import {
8
8
  getCatalogEntry
9
- } from "./chunk-TPDBUOPN.js";
9
+ } from "./chunk-ISE55FOR.js";
10
10
  import {
11
11
  logger
12
12
  } from "./chunk-K44MW7JJ.js";
@@ -184,64 +184,6 @@ async function probeReasoningInMessages(baseUrl, apiKey, model) {
184
184
  return void 0;
185
185
  }
186
186
  }
187
- var REASONING_EFFORT_CANDIDATES = ["low", "medium", "high", "xhigh", "max"];
188
- async function probeReasoningEffort(baseUrl, apiKey, model, effort, signal) {
189
- const body = {
190
- model,
191
- messages: [{ role: "user", content: "say hi in one word" }],
192
- max_tokens: 0,
193
- ...effort ? { reasoning_effort: effort } : {}
194
- };
195
- try {
196
- const response = await fetch(`${ensureVersionPrefix(baseUrl)}/chat/completions`, {
197
- method: "POST",
198
- headers: buildAuthHeaders(apiKey),
199
- body: JSON.stringify(body),
200
- signal
201
- });
202
- if (!response.ok) {
203
- return { effort: effort ?? "baseline", ok: false, promptTokens: 0 };
204
- }
205
- const data = await response.json();
206
- return {
207
- effort: effort ?? "baseline",
208
- ok: true,
209
- promptTokens: data.usage?.prompt_tokens ?? 0
210
- };
211
- } catch {
212
- return { effort: effort ?? "baseline", ok: false, promptTokens: 0 };
213
- }
214
- }
215
- async function probeReasoningEfforts(baseUrl, apiKey, model) {
216
- const timeout = AbortSignal.timeout(15e3);
217
- const baseline = await probeReasoningEffort(baseUrl, apiKey, model, void 0, timeout);
218
- if (!baseline.ok) {
219
- return void 0;
220
- }
221
- const results = await Promise.all(
222
- REASONING_EFFORT_CANDIDATES.map(
223
- (effort) => probeReasoningEffort(baseUrl, apiKey, model, effort, timeout).then((r) => ({ ...r, effort }))
224
- )
225
- );
226
- const accepted = results.filter((r) => r.ok);
227
- if (accepted.length === 0) {
228
- return void 0;
229
- }
230
- const impactful = accepted.filter((r) => r.promptTokens !== baseline.promptTokens);
231
- const pool = impactful.length > 0 ? impactful : accepted;
232
- const distinctTokens = new Set(pool.map((r) => r.promptTokens));
233
- if (distinctTokens.size <= 1) {
234
- return pool.map((r) => r.effort);
235
- }
236
- const seen = /* @__PURE__ */ new Set();
237
- const distinct = [];
238
- for (const r of pool) {
239
- if (seen.has(r.promptTokens)) continue;
240
- seen.add(r.promptTokens);
241
- distinct.push(r.effort);
242
- }
243
- return distinct;
244
- }
245
187
  var STANDARD_PARAMS = ["temperature", "top_p", "max_tokens", "top_k", "reasoning_effort"];
246
188
  var PARAM_VALUES = {
247
189
  temperature: 0.7,
@@ -340,15 +282,13 @@ async function autoConfig(input) {
340
282
  supportsVision
341
283
  } = await detectModelInfo(baseUrl, apiKey, backend, model.id);
342
284
  const catalog = getCatalogEntry(model.id);
343
- const shouldProbeEfforts = backend !== "unknown" || !catalog;
344
- const [thinkingConfig, nonThinkingConfig, rejectedParams, reasoningEfforts] = await Promise.all([
285
+ const reasoningEfforts = catalog?.reasoningEfforts;
286
+ const [thinkingConfig, nonThinkingConfig, rejectedParams] = await Promise.all([
345
287
  probeCombos(baseUrl, apiKey, model.id, THINKING_COMBOS),
346
288
  probeCombos(baseUrl, apiKey, model.id, NON_THINKING_COMBOS),
347
- probeRejectedParams(baseUrl, apiKey, model.id, backend),
348
- shouldProbeEfforts ? probeReasoningEfforts(baseUrl, apiKey, model.id) : Promise.resolve(void 0)
289
+ probeRejectedParams(baseUrl, apiKey, model.id, backend)
349
290
  ]);
350
291
  const sendReasoningInMessages = thinkingConfig ? await probeReasoningInMessages(baseUrl, apiKey, model.id) : void 0;
351
- const effectiveReasoningEfforts = reasoningEfforts ?? catalog?.reasoningEfforts;
352
292
  results.push({
353
293
  id: model.id,
354
294
  contextWindow,
@@ -358,7 +298,7 @@ async function autoConfig(input) {
358
298
  nonThinkingConfig,
359
299
  ...sendReasoningInMessages !== void 0 ? { sendReasoningInMessages } : {},
360
300
  ...rejectedParams.length > 0 ? { rejectedParams } : {},
361
- ...effectiveReasoningEfforts ? { reasoningEfforts: effectiveReasoningEfforts } : {},
301
+ ...reasoningEfforts ? { reasoningEfforts } : {},
362
302
  ...catalog?.defaultReasoningEffort ? { defaultReasoningEffort: catalog.defaultReasoningEffort } : {}
363
303
  });
364
304
  }
@@ -367,4 +307,4 @@ async function autoConfig(input) {
367
307
  export {
368
308
  autoConfig
369
309
  };
370
- //# sourceMappingURL=auto-config-4BFGLPCP.js.map
310
+ //# sourceMappingURL=auto-config-454YE6KC.js.map
@@ -5,9 +5,9 @@ import {
5
5
  } from "./chunk-W4SM4FFZ.js";
6
6
  import {
7
7
  runChatTurn
8
- } from "./chunk-V2UJP5CX.js";
9
- import "./chunk-4L7UMEHD.js";
10
- import "./chunk-PZUKG3OZ.js";
8
+ } from "./chunk-QJNBQCAF.js";
9
+ import "./chunk-5CCM655F.js";
10
+ import "./chunk-FAL4WO4V.js";
11
11
  import "./chunk-ZIL6VKLU.js";
12
12
  import "./chunk-62GUO2EG.js";
13
13
  import "./chunk-GIJUWPRQ.js";
@@ -18,9 +18,9 @@ import "./chunk-JE7LW7Y6.js";
18
18
  import "./chunk-OAN4BXEW.js";
19
19
  import "./chunk-3NMLSANH.js";
20
20
  import "./chunk-J7GAZGZT.js";
21
- import "./chunk-SS6KV6DI.js";
21
+ import "./chunk-UGEFD67O.js";
22
22
  import "./chunk-7YP4O4XE.js";
23
- import "./chunk-INOO465O.js";
23
+ import "./chunk-KD4W3I6C.js";
24
24
  import {
25
25
  getEventStore
26
26
  } from "./chunk-YJD5A375.js";
@@ -34,7 +34,7 @@ import {
34
34
  import "./chunk-66MG44TF.js";
35
35
  import "./chunk-JURM3RPZ.js";
36
36
  import "./chunk-LCLH6ZUL.js";
37
- import "./chunk-H4JRR5KV.js";
37
+ import "./chunk-A6EZBX62.js";
38
38
  import "./chunk-K2QKX4ZJ.js";
39
39
  import "./chunk-J2GP3J3X.js";
40
40
  import "./chunk-KBESUA3W.js";
@@ -48,7 +48,7 @@ import "./chunk-MIPQOHWS.js";
48
48
  import "./chunk-VPRB5FNR.js";
49
49
  import "./chunk-N2Q3KYWM.js";
50
50
  import "./chunk-OYBUJIC3.js";
51
- import "./chunk-TPDBUOPN.js";
51
+ import "./chunk-ISE55FOR.js";
52
52
  import "./chunk-K44MW7JJ.js";
53
53
  import "./chunk-KSDWQ6IZ.js";
54
54
  import "./chunk-KSXCOHHW.js";
@@ -174,4 +174,4 @@ export {
174
174
  startChatSession,
175
175
  stopSessionExecution
176
176
  };
177
- //# sourceMappingURL=chat-handler-UWZYFGRY.js.map
177
+ //# sourceMappingURL=chat-handler-N43TBYLV.js.map
@@ -5,18 +5,18 @@ import {
5
5
  } from "./chunk-W4SM4FFZ.js";
6
6
  import {
7
7
  launchWorkflowRun
8
- } from "./chunk-ZKMZI4ZG.js";
8
+ } from "./chunk-KGFERMCV.js";
9
9
  import {
10
10
  runChatTurn
11
- } from "./chunk-V2UJP5CX.js";
11
+ } from "./chunk-QJNBQCAF.js";
12
12
  import {
13
13
  devServerManager
14
- } from "./chunk-4L7UMEHD.js";
14
+ } from "./chunk-5CCM655F.js";
15
15
  import {
16
16
  applyDynamicContext,
17
17
  computeSessionHash,
18
18
  computeUnifiedDiff
19
- } from "./chunk-PZUKG3OZ.js";
19
+ } from "./chunk-FAL4WO4V.js";
20
20
  import {
21
21
  appendCompactionPrompt
22
22
  } from "./chunk-JEZN37KV.js";
@@ -1299,7 +1299,7 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
1299
1299
  }
1300
1300
  const session = sessionManager.requireSession(sessionId);
1301
1301
  try {
1302
- const { buildCachedPrompt } = await import("./dynamic-context-5TPG2AJL.js");
1302
+ const { buildCachedPrompt } = await import("./dynamic-context-KTQCAPTK.js");
1303
1303
  const allAgents = await import("./registry-Z4GVYFTV.js");
1304
1304
  const agentDef = allAgents.findAgentById(session.mode, await allAgents.loadAllAgentsDefault()) ?? allAgents.findAgentById("planner", await allAgents.loadAllAgentsDefault());
1305
1305
  const modelName = session.providerModel ?? _providerManager?.getCurrentModel();
@@ -1624,4 +1624,4 @@ export {
1624
1624
  signalMcpReady,
1625
1625
  createWebSocketServer
1626
1626
  };
1627
- //# sourceMappingURL=chunk-YGOF4QDW.js.map
1627
+ //# sourceMappingURL=chunk-57UCBFBD.js.map
@@ -61,7 +61,7 @@ import {
61
61
  getGateConfig,
62
62
  isTaskConflictError,
63
63
  isTaskGateError
64
- } from "./chunk-SS6KV6DI.js";
64
+ } from "./chunk-UGEFD67O.js";
65
65
  import {
66
66
  getSessionDisabledServers
67
67
  } from "./chunk-7YP4O4XE.js";
@@ -70,8 +70,9 @@ import {
70
70
  extractAbsolutePathsFromCommand,
71
71
  extractSensitivePathsFromCommand,
72
72
  registerPathConfirmation,
73
- requestPathAccess
74
- } from "./chunk-INOO465O.js";
73
+ requestPathAccess,
74
+ resolveRelativeTraversals
75
+ } from "./chunk-KD4W3I6C.js";
75
76
  import {
76
77
  getCurrentContextWindowId,
77
78
  getCurrentWindowMessageOptions,
@@ -1218,9 +1219,11 @@ var runCommandTool = createTool(
1218
1219
  const pathsToCheck = [workingDir];
1219
1220
  const commandPaths = extractAbsolutePathsFromCommand(args.command);
1220
1221
  for (const cmdPath of commandPaths) {
1221
- const resolved = isAbsolute(cmdPath) ? cmdPath : resolve3(workingDir, cmdPath);
1222
- pathsToCheck.push(resolved);
1222
+ if (isAbsolute(cmdPath)) {
1223
+ pathsToCheck.push(cmdPath);
1224
+ }
1223
1225
  }
1226
+ pathsToCheck.push(...resolveRelativeTraversals(args.command, workingDir));
1224
1227
  const sensitivePaths = extractSensitivePathsFromCommand(args.command);
1225
1228
  for (const sensitivePath of sensitivePaths) {
1226
1229
  const resolved = isAbsolute(sensitivePath) ? sensitivePath : resolve3(workingDir, sensitivePath);
@@ -1783,6 +1786,21 @@ Error: ${toolResult.error}` : `Error: ${toolResult.error}`
1783
1786
  return { toolMessages, criteriaChanged: false, returnValueContent, returnValueResult, stepDoneCalled };
1784
1787
  }
1785
1788
 
1789
+ // src/server/chat/token-budget.ts
1790
+ var CHARS_PER_TOKEN = 4;
1791
+ var TOOL_MESSAGE_OVERHEAD_TOKENS = 16;
1792
+ function estimateToolResultTokens(toolMessages) {
1793
+ return toolMessages.reduce(
1794
+ (sum, message) => sum + TOOL_MESSAGE_OVERHEAD_TOKENS + Math.ceil(message.content.length / CHARS_PER_TOKEN),
1795
+ 0
1796
+ );
1797
+ }
1798
+ var CONTEXT_LENGTH_ERROR_PATTERN = /context\s*length|context_length|context window|prompt (?:is )?too long/i;
1799
+ function isContextLengthError(message) {
1800
+ if (!message) return false;
1801
+ return CONTEXT_LENGTH_ERROR_PATTERN.test(message);
1802
+ }
1803
+
1786
1804
  // src/server/chat/retry-limiter.ts
1787
1805
  function createRetryLimiter(max) {
1788
1806
  let current = 0;
@@ -1866,6 +1884,7 @@ function emitDoneAndBreak(assistantMsgId, segments, statsIdentity, mode, turnMet
1866
1884
  }
1867
1885
  }
1868
1886
  var MAX_TRUNCATION_RETRIES = 3;
1887
+ var MAX_CONTEXT_LENGTH_RETRIES = 3;
1869
1888
  var OUTPUT_RESERVE_TOKENS = 2048;
1870
1889
  var CONTINUE_PROMPT = "Continue your previous response. Do NOT repeat what you already wrote.";
1871
1890
  var CONTINUE_AFTER_STREAM_ERROR_PROMPT = "The LLM stream was interrupted mid-response. Continue exactly where you left off \u2014 do not repeat what was already written.";
@@ -1876,6 +1895,8 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1876
1895
  const resolveClient = () => config.getLLMClient?.() ?? llmClient;
1877
1896
  const retryLimiter = createRetryLimiter(config.maxRetriesPerTurn ?? 10);
1878
1897
  let truncationRetryCount = 0;
1898
+ let contextRetryCount = 0;
1899
+ let pendingToolResultTokens = 0;
1879
1900
  let returnValueContent;
1880
1901
  let returnValueResult;
1881
1902
  let currentMaxTokensOverride;
@@ -1978,8 +1999,14 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1978
1999
  const contextState = sessionManager.getContextState(sessionId);
1979
2000
  previousContextTokens = contextState.currentTokens;
1980
2001
  const contextWindow = sessionManager.getCurrentModelContext(sessionId, config.mode);
1981
- const availableForOutput = Math.max(256, contextWindow - contextState.currentTokens - OUTPUT_RESERVE_TOKENS);
1982
- let modelSettings = config.modelSettings ?? (currentMaxTokensOverride !== void 0 ? { ...sessionManager.getCurrentModelSettings(sessionId, config.mode), maxTokens: currentMaxTokensOverride } : sessionManager.getCurrentModelSettings(sessionId, config.mode));
2002
+ const availableForOutput = Math.max(
2003
+ 256,
2004
+ contextWindow - contextState.currentTokens - pendingToolResultTokens - OUTPUT_RESERVE_TOKENS
2005
+ );
2006
+ let modelSettings = config.modelSettings ?? sessionManager.getCurrentModelSettings(sessionId, config.mode);
2007
+ if (modelSettings && currentMaxTokensOverride !== void 0) {
2008
+ modelSettings = { ...modelSettings, maxTokens: currentMaxTokensOverride };
2009
+ }
1983
2010
  if (modelSettings) {
1984
2011
  const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1985
2012
  modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
@@ -2021,6 +2048,12 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
2021
2048
  continuationAppended = true;
2022
2049
  }
2023
2050
  if (signal?.aborted) throw new Error("Aborted");
2051
+ if (isContextLengthError(attemptResult.error) && contextRetryCount < MAX_CONTEXT_LENGTH_RETRIES) {
2052
+ contextRetryCount += 1;
2053
+ const currentMax = modelSettings?.maxTokens ?? currentMaxTokensOverride ?? 16384;
2054
+ currentMaxTokensOverride = Math.max(256, Math.floor(currentMax / 2));
2055
+ continue;
2056
+ }
2024
2057
  requestFailures += 1;
2025
2058
  if (requestFirstFailureAt === 0) {
2026
2059
  requestFirstFailureAt = Date.now();
@@ -2099,6 +2132,8 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
2099
2132
  result.usage.completionTokens,
2100
2133
  config.subAgentMetadata?.subAgentId
2101
2134
  );
2135
+ pendingToolResultTokens = 0;
2136
+ currentMaxTokensOverride = void 0;
2102
2137
  if (!compacting) {
2103
2138
  const contextState = sessionManager.getContextState(sessionId);
2104
2139
  const { shouldCompact, appendCompactionPrompt } = await import("./compactor-VTATJTPN.js");
@@ -2208,6 +2243,7 @@ ${COMPACTION_PROMPT}`,
2208
2243
  }
2209
2244
  batchContext.agentTimeout = getRuntimeConfig().agent.toolTimeout;
2210
2245
  const batchResult = await executeTools(assistantMsgId, result.toolCalls, batchContext, append);
2246
+ pendingToolResultTokens = estimateToolResultTokens(batchResult.toolMessages);
2211
2247
  if (batchResult.stepDoneCalled) {
2212
2248
  emitDoneAndBreak(
2213
2249
  assistantMsgId,
@@ -3116,7 +3152,7 @@ var callSubAgentTool = {
3116
3152
  };
3117
3153
  }
3118
3154
  try {
3119
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-YPVZ5QM2.js");
3155
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-G44LBKD4.js");
3120
3156
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3121
3157
  const turnMetrics = new TurnMetrics();
3122
3158
  const result = await executeSubAgent({
@@ -4138,7 +4174,7 @@ var mcpConfigTool = createTool(
4138
4174
  mcpNotifyChanged?.(sessionId);
4139
4175
  }
4140
4176
  async function rebuildTools() {
4141
- const { setMcpTools: setMcpTools2 } = await import("./tools-YPVZ5QM2.js");
4177
+ const { setMcpTools: setMcpTools2 } = await import("./tools-G44LBKD4.js");
4142
4178
  const mcpTools = createMcpTools(mcpManagerForTools);
4143
4179
  setMcpTools2(mcpTools);
4144
4180
  }
@@ -4565,13 +4601,15 @@ function getTasksService() {
4565
4601
  }
4566
4602
  var VALID_ACTIONS = ["list", "create", "edit", "move", "set_gate_value", "delete"];
4567
4603
  var LIST_STATUSES = ["todo", "in_progress", "done", "all"];
4604
+ var LIST_DEFAULT_LIMIT = 10;
4605
+ var LIST_MAX_LIMIT = 25;
4568
4606
  var projectTasksTool = createTool(
4569
4607
  "project_tasks",
4570
4608
  {
4571
4609
  type: "function",
4572
4610
  function: {
4573
4611
  name: "project_tasks",
4574
- description: "Kanban task board for this project. Core loop: list \u2192 move \u2192 set_gate_value.\n\nRules:\n- Moving to in_progress binds the task to YOUR current session.\n- Do not move tasks or fill gate values without explicit user approval or a system instruction \u2014 complete the work, then let the user review before the task advances.\n- Moving to done is blocked by unmet gates: the error names the missing fields \u2014 fill them only with user approval, then retry the move.\n- Stale writes fail with CONFLICT \u2014 re-list and retry.\n\nActions:\n- list: tasks (status, gate values, queue position, bound session, audit trail); defaults to open tasks, filter via status (todo | in_progress | done | all)\n- create: add a task to To Do (prompt required)\n- edit: update prompt/attachments/agent/model (taskId + fields)\n- move: change column (to: todo | in_progress | done; optional reason)\n- set_gate_value: fill a gate field (taskId, gateId, value)\n- delete: remove a task (taskId)",
4612
+ description: "Kanban task board for this project. Core loop: list \u2192 move \u2192 set_gate_value.\n\nRules:\n- Moving to in_progress binds the task to YOUR current session.\n- Do not move tasks or fill gate values without explicit user approval or a system instruction \u2014 complete the work, then let the user review before the task advances.\n- Moving to done is blocked by unmet gates: the error names the missing fields \u2014 fill them only with user approval, then retry the move.\n- Stale writes fail with CONFLICT \u2014 re-list and retry.\n\nActions:\n- list: tasks (status, gate values, queue position, bound session, audit trail); defaults to open tasks, filter via status (todo | in_progress | done | all); paginated \u2014 limit 10 max 25, page with offset\n- create: add a task to To Do (prompt required)\n- edit: update prompt/attachments/agent/model (taskId + fields)\n- move: change column (to: todo | in_progress | done; optional reason)\n- set_gate_value: fill a gate field (taskId, gateId, value)\n- delete: remove a task (taskId)",
4575
4613
  parameters: {
4576
4614
  type: "object",
4577
4615
  properties: {
@@ -4591,6 +4629,14 @@ var projectTasksTool = createTool(
4591
4629
  enum: ["todo", "in_progress", "done", "all"],
4592
4630
  description: "Column filter for action=list (default: open tasks)"
4593
4631
  },
4632
+ limit: {
4633
+ type: "number",
4634
+ description: "Max tasks to return for action=list (default: 10, max: 25)"
4635
+ },
4636
+ offset: {
4637
+ type: "number",
4638
+ description: "Number of tasks to skip for action=list pagination (default: 0). Pages are snapshots \u2014 re-list after mutations."
4639
+ },
4594
4640
  expectedVersion: {
4595
4641
  type: "number",
4596
4642
  description: "Task version from your last read; stale writes fail with CONFLICT"
@@ -4618,10 +4664,26 @@ var projectTasksTool = createTool(
4618
4664
  `Invalid "status" filter for action=list: "${String(status)}". Expected one of: todo, in_progress, done, all.`
4619
4665
  );
4620
4666
  }
4667
+ const page = parseListPage(args.limit, args.offset);
4668
+ if (!page.ok) return helpers.error(page.error);
4621
4669
  const tasks = svc.list(projectId);
4622
4670
  const filtered = status === "all" ? tasks : tasks.filter((t) => status === void 0 ? t.status !== "done" : t.status === status);
4671
+ const pageTasks = filtered.slice(page.offset, page.offset + page.limit);
4623
4672
  const gates = getGateConfig(projectId);
4624
- return helpers.success(JSON.stringify({ gates, tasks: filtered.map((t) => taskForAgent(t)) }, null, 2));
4673
+ return helpers.success(
4674
+ JSON.stringify(
4675
+ {
4676
+ gates,
4677
+ tasks: pageTasks.map((t) => taskForAgent(t)),
4678
+ total: filtered.length,
4679
+ limit: page.limit,
4680
+ offset: page.offset,
4681
+ hasMore: page.offset + page.limit < filtered.length
4682
+ },
4683
+ null,
4684
+ 2
4685
+ )
4686
+ );
4625
4687
  }
4626
4688
  case "create": {
4627
4689
  const task = svc.create(
@@ -4714,6 +4776,17 @@ var projectTasksTool = createTool(
4714
4776
  }
4715
4777
  }
4716
4778
  );
4779
+ function parseListPage(limit, offset) {
4780
+ const pageSize = limit ?? LIST_DEFAULT_LIMIT;
4781
+ const skip = offset ?? 0;
4782
+ if (!Number.isInteger(pageSize) || pageSize < 1 || pageSize > LIST_MAX_LIMIT) {
4783
+ return { ok: false, error: `Invalid "limit" for action=list: must be an integer between 1 and ${LIST_MAX_LIMIT}.` };
4784
+ }
4785
+ if (!Number.isInteger(skip) || skip < 0) {
4786
+ return { ok: false, error: 'Invalid "offset" for action=list: must be a non-negative integer.' };
4787
+ }
4788
+ return { ok: true, limit: pageSize, offset: skip };
4789
+ }
4717
4790
  function taskForAgent(task) {
4718
4791
  return {
4719
4792
  id: task.id,
@@ -5026,4 +5099,4 @@ export {
5026
5099
  getToolRegistryForAgent,
5027
5100
  createToolRegistry
5028
5101
  };
5029
- //# sourceMappingURL=chunk-4L7UMEHD.js.map
5102
+ //# sourceMappingURL=chunk-5CCM655F.js.map
@@ -21,7 +21,7 @@ import {
21
21
  import {
22
22
  getCatalogEntry,
23
23
  resolveEffortForModel
24
- } from "./chunk-TPDBUOPN.js";
24
+ } from "./chunk-ISE55FOR.js";
25
25
  import {
26
26
  logger
27
27
  } from "./chunk-K44MW7JJ.js";
@@ -841,4 +841,4 @@ export {
841
841
  parseDefaultModelSelection,
842
842
  createProviderManager
843
843
  };
844
- //# sourceMappingURL=chunk-H4JRR5KV.js.map
844
+ //# sourceMappingURL=chunk-A6EZBX62.js.map
@@ -105,7 +105,7 @@ function resolveAgentDef(sessionManager, sessionId) {
105
105
  }
106
106
  async function buildCachedPrompt(sessionManager, sessionId, agentDef, modelName) {
107
107
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
108
- const { getToolRegistryForAgent } = await import("./tools-YPVZ5QM2.js");
108
+ const { getToolRegistryForAgent } = await import("./tools-G44LBKD4.js");
109
109
  const tools = getToolRegistryForAgent(agentDef, sessionId).definitions;
110
110
  const toolFingerprint = getToolFingerprint(tools);
111
111
  const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
@@ -124,7 +124,7 @@ async function buildCachedPrompt(sessionManager, sessionId, agentDef, modelName)
124
124
  async function computeSessionHash(sessionManager, sessionId, modelName) {
125
125
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
126
126
  const agentDef = await resolveAgentDef(sessionManager, sessionId);
127
- const { getToolRegistryForAgent } = await import("./tools-YPVZ5QM2.js");
127
+ const { getToolRegistryForAgent } = await import("./tools-G44LBKD4.js");
128
128
  const tools = getToolRegistryForAgent(agentDef, sessionId).definitions;
129
129
  const toolFingerprint = getToolFingerprint(tools);
130
130
  return computeDynamicContextHash(instructionContent, skills, toolFingerprint, modelName);
@@ -148,4 +148,4 @@ export {
148
148
  computeSessionHash,
149
149
  applyDynamicContext
150
150
  };
151
- //# sourceMappingURL=chunk-PZUKG3OZ.js.map
151
+ //# sourceMappingURL=chunk-FAL4WO4V.js.map
@@ -33,9 +33,16 @@ var CATALOG = [
33
33
  entry: { reasoningEfforts: ["none", "low", "high", "max"], defaultReasoningEffort: "high" }
34
34
  },
35
35
  {
36
- // Qwen3.6 / 3.7 / 3.8 families: low/medium/high is the common denominator.
37
- pattern: /^qwen3\.(6|7|8)(\b|-)/i,
38
- entry: { reasoningEfforts: ["low", "medium", "high"], defaultReasoningEffort: "medium" }
36
+ // Qwen3.8: official reasoning_effort values are low/medium/xhigh
37
+ // (xhigh is the model default); 'none' disables thinking on setups
38
+ // that honor it.
39
+ pattern: /^qwen3\.8(\b|-)/i,
40
+ entry: { reasoningEfforts: ["none", "low", "medium", "xhigh"], defaultReasoningEffort: "xhigh" }
41
+ },
42
+ {
43
+ // Qwen3.5 / 3.6: on/off thinking only — none (off) or high (thinking on).
44
+ pattern: /^qwen3\.(5|6)(\b|-)/i,
45
+ entry: { reasoningEfforts: ["none", "high"], defaultReasoningEffort: "high" }
39
46
  },
40
47
  {
41
48
  // Z.ai GLM-5.3: only max/high/low are accepted.
@@ -79,4 +86,4 @@ export {
79
86
  getCatalogEntry,
80
87
  getCatalogDefaultEffort
81
88
  };
82
- //# sourceMappingURL=chunk-TPDBUOPN.js.map
89
+ //# sourceMappingURL=chunk-ISE55FOR.js.map