openfox 2.0.118 → 2.0.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/CHANGELOG.md +26 -0
- package/dist/agent-defaults/code-reviewer.agent.md +8 -3
- package/dist/{auto-config-AAUO4PKW.js → auto-config-YXNCBYEY.js} +125 -11
- package/dist/{chat-handler-KNBP6WVI.js → chat-handler-M54IWF5Y.js} +11 -10
- package/dist/{chunk-HZSKKJHQ.js → chunk-5FAPM2GM.js} +28 -9
- package/dist/{chunk-CX7UJZA5.js → chunk-6DDB67FN.js} +4 -4
- package/dist/{chunk-5ZR5O5GC.js → chunk-AIFZNTUJ.js} +4 -4
- package/dist/{chunk-45OS4H3L.js → chunk-AVQCOSOF.js} +7 -7
- package/dist/chunk-EW25UQG3.js +7 -0
- package/dist/{chunk-MKWS7TQH.js → chunk-J6KFWVZ3.js} +21 -15
- package/dist/chunk-K2QKX4ZJ.js +31 -0
- package/dist/{chunk-TOKQ2UVG.js → chunk-MIPQOHWS.js} +20 -6
- package/dist/{chunk-NP2SV2CX.js → chunk-SE62ZBNX.js} +9 -3
- package/dist/{chunk-GZTMCTUS.js → chunk-U6JMRMBW.js} +17 -21
- package/dist/{chunk-5E5G3DLI.js → chunk-UNNCD7A3.js} +3 -3
- package/dist/{chunk-IDUXGSQV.js → chunk-V5XWUVF5.js} +13 -9
- package/dist/{chunk-MTFLMNLN.js → chunk-VFS7TFA7.js} +2 -2
- package/dist/{chunk-Y6WWEQPC.js → chunk-XB7IXMUI.js} +11 -11
- package/dist/{chunk-RXIDGWNV.js → chunk-XZ2WAI66.js} +56 -26
- package/dist/{chunk-CIYA6BNB.js → chunk-YHAE2SJI.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{client-KCNTDTIR.js → client-R4PI64IL.js} +3 -3
- package/dist/{client-pure-B5DHEKQJ.js → client-pure-QSY7TJGK.js} +2 -2
- package/dist/{compactor-5ATICQ2A.js → compactor-F6XMYVHL.js} +4 -4
- package/dist/{dynamic-context-4SKLIPJ4.js → dynamic-context-NXQ2TFAZ.js} +2 -2
- package/dist/{launch-Q6GUJ22H.js → launch-I5XBYRSJ.js} +11 -10
- package/dist/{orchestrator-DVCGWWNA.js → orchestrator-MNON5G7R.js} +10 -9
- package/dist/package.json +1 -1
- package/dist/{processor-G6UJGA2K.js → processor-OZSK7RUD.js} +10 -9
- package/dist/{protocol-DzJrspsl.d.ts → protocol-D5kJLGWy.d.ts} +1 -1
- package/dist/provider/index.d.ts +4 -4
- package/dist/{provider-Q7J4UFTS.js → provider-7YF42S7C.js} +5 -4
- package/dist/{provider-manager-TMBO4DFG.js → provider-manager-FJIPQJMX.js} +5 -4
- package/dist/{serve-23YIIMXH.js → serve-V34QG72C.js} +16 -15
- package/dist/server/index.d.ts +5 -3
- package/dist/server/index.js +15 -14
- package/dist/{server-IDXIAC5L.js → server-XZQLWIVD.js} +14 -13
- package/dist/{service-M7XJHAK4.js → service-ZKH465DA.js} +6 -5
- package/dist/session-status-6Q5B5PEN.js +35 -0
- package/dist/shared/index.d.ts +3 -3
- package/dist/{tasks-X5H5HM4J.js → tasks-I766NBPW.js} +8 -6
- package/dist/{tools-GOGLGTNV.js → tools-ZJXDZLRH.js} +8 -7
- package/dist/{types-CIVhQMvD.d.ts → types-B5CI_Ql3.d.ts} +3 -1
- package/dist/{types-Df7NM9b5.d.ts → types-CZlj7ufS.d.ts} +2 -0
- package/dist/{update-T3YMIWQO.js → update-C3YVPKCR.js} +2 -2
- package/dist/web/assets/index-BlYcAqzD.js +324 -0
- package/dist/web/assets/{index-XTp1QlHA.css → index-D9sfxcRH.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/dist/workflow-defaults/default.workflow.json +1 -1
- package/package.json +1 -1
- package/dist/chunk-BSULZIPW.js +0 -7
- package/dist/web/assets/index-BgENxR9h.js +0 -324
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.119 - 2026-08-14
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Per-model sampling controls** — pick which sampling parameters each backend receives, per model
|
|
8
|
+
- **Read-only session status** — lightweight API and widget expose live state for external integrations
|
|
9
|
+
|
|
10
|
+
### Enhancements
|
|
11
|
+
|
|
12
|
+
- **Reviewer gets the full picture** — code reviews now factor in intended scope, verifier notes, and changed files
|
|
13
|
+
- **No surprise navigation on In Progress** — moving a task keeps your place; open it via the card link
|
|
14
|
+
- **Task editor shortcuts inverted** — Enter inserts a newline, Shift+Enter saves
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **New-task autocomplete fixed** — slash/@ suggestions are no longer clipped and load on cold start
|
|
19
|
+
- **Long chats safer against rejection** — max_tokens now keeps 2048 tokens of headroom
|
|
20
|
+
- **Split panes keep dev state separate** — server status, logs, and config no longer bleed between workdirs
|
|
21
|
+
- **ask_user prompts render as markdown** — no more raw text walls
|
|
22
|
+
- **Submodule changes appear in the diff preview**
|
|
23
|
+
- **Auto-config spots rejected reasoning** — providers that refuse it no longer receive reasoning history
|
|
24
|
+
- **LM Studio context windows set by auto-config** — no longer left at zero
|
|
25
|
+
- **No phantom password prompt** — the login modal no longer flashes while connecting
|
|
26
|
+
- **Silent streams end their turn** — idle LLM connections time out cleanly instead of hanging
|
|
27
|
+
- **Null token usage no longer crashes sessions**
|
|
28
|
+
|
|
3
29
|
## 2.0.118 - 2026-08-12
|
|
4
30
|
|
|
5
31
|
### Features
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.119 - 2026-08-14
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Per-model sampling controls** — pick which sampling parameters each backend receives, per model
|
|
8
|
+
- **Read-only session status** — lightweight API and widget expose live state for external integrations
|
|
9
|
+
|
|
10
|
+
### Enhancements
|
|
11
|
+
|
|
12
|
+
- **Reviewer gets the full picture** — code reviews now factor in intended scope, verifier notes, and changed files
|
|
13
|
+
- **No surprise navigation on In Progress** — moving a task keeps your place; open it via the card link
|
|
14
|
+
- **Task editor shortcuts inverted** — Enter inserts a newline, Shift+Enter saves
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **New-task autocomplete fixed** — slash/@ suggestions are no longer clipped and load on cold start
|
|
19
|
+
- **Long chats safer against rejection** — max_tokens now keeps 2048 tokens of headroom
|
|
20
|
+
- **Split panes keep dev state separate** — server status, logs, and config no longer bleed between workdirs
|
|
21
|
+
- **ask_user prompts render as markdown** — no more raw text walls
|
|
22
|
+
- **Submodule changes appear in the diff preview**
|
|
23
|
+
- **Auto-config spots rejected reasoning** — providers that refuse it no longer receive reasoning history
|
|
24
|
+
- **LM Studio context windows set by auto-config** — no longer left at zero
|
|
25
|
+
- **No phantom password prompt** — the login modal no longer flashes while connecting
|
|
26
|
+
- **Silent streams end their turn** — idle LLM connections time out cleanly instead of hanging
|
|
27
|
+
- **Null token usage no longer crashes sessions**
|
|
28
|
+
|
|
3
29
|
## 2.0.118 - 2026-08-12
|
|
4
30
|
|
|
5
31
|
### Features
|
|
@@ -11,14 +11,19 @@ allowedTools:
|
|
|
11
11
|
- session_metadata
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
You are a code reviewer. Review the **git diff** of the modified files rather than reading the full files.
|
|
14
|
+
You are a code reviewer. Your caller may provide situational context before the diff — **intended scope (criteria)**, **what the verifier already confirmed**, and the **modified files**. Review the **git diff** of the modified files rather than reading the full files.
|
|
15
|
+
|
|
16
|
+
When context is provided, use it to judge the change against what was actually requested:
|
|
17
|
+
|
|
18
|
+
- Read the intended scope (criteria) and check the diff delivers it faithfully — flag mismatches, partial implementations, or scope creep.
|
|
19
|
+
- Treat the verifier's notes as already-confirmed ground truth. Don't re-verify what it covered; instead catch what it missed.
|
|
20
|
+
- You're not looking for 100% perfection. Just something that feels good to use and doesn't bloat the software.
|
|
21
|
+
|
|
15
22
|
You're mostly interested in:
|
|
16
23
|
|
|
17
24
|
1. **For the user (UX interaction)** — does this feel good to use? Any rough edges, confusing behavior, or unnecessary friction?
|
|
18
25
|
2. **For the project (code quality + guidelines)** — does this follow project conventions? Is it maintainable? Does it bloat the software?
|
|
19
26
|
|
|
20
|
-
You're not looking for 100% perfection. Just something that feels good to use and doesn't bloat the software.
|
|
21
|
-
|
|
22
27
|
## Managing Findings
|
|
23
28
|
|
|
24
29
|
Use `session_metadata` to track your findings:
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findLmStudioModel
|
|
3
|
+
} from "./chunk-K2QKX4ZJ.js";
|
|
1
4
|
import {
|
|
2
5
|
ensureVersionPrefix
|
|
3
6
|
} from "./chunk-HNCM3D7Y.js";
|
|
@@ -98,14 +101,10 @@ async function detectLmstudioInfo(baseUrl, modelId) {
|
|
|
98
101
|
const nativeUrl = `${base.replace(/\/v\d+\/?$/, "")}/api/v1/models`;
|
|
99
102
|
const response = await fetch(nativeUrl, { signal: AbortSignal.timeout(5e3) });
|
|
100
103
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
101
|
-
const
|
|
102
|
-
const model = data.find((m) => (m.key ?? m.id) === modelId);
|
|
104
|
+
const model = findLmStudioModel(await response.json(), modelId);
|
|
103
105
|
if (!model) throw new Error(`Model ${modelId} not found in LM Studio`);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const supportsVision = model.capabilities?.vision ?? false;
|
|
107
|
-
if (ctxLen) {
|
|
108
|
-
return { contextWindow: ctxLen, source: "backend", supportsVision };
|
|
106
|
+
if (model.contextWindow) {
|
|
107
|
+
return { contextWindow: model.contextWindow, source: "backend", supportsVision: model.supportsVision };
|
|
109
108
|
}
|
|
110
109
|
throw new Error("No context_length in LM Studio response");
|
|
111
110
|
}
|
|
@@ -157,6 +156,117 @@ async function probeCombos(baseUrl, apiKey, model, combos) {
|
|
|
157
156
|
logger.debug("Auto-config: no working combo found", { model });
|
|
158
157
|
return null;
|
|
159
158
|
}
|
|
159
|
+
async function probeReasoningInMessages(baseUrl, apiKey, model) {
|
|
160
|
+
const headers = { "Content-Type": "application/json" };
|
|
161
|
+
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
162
|
+
try {
|
|
163
|
+
const response = await fetch(`${ensureVersionPrefix(baseUrl)}/chat/completions`, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers,
|
|
166
|
+
body: JSON.stringify({
|
|
167
|
+
model,
|
|
168
|
+
messages: [
|
|
169
|
+
{ role: "user", content: "say hi in one word" },
|
|
170
|
+
{ role: "assistant", content: "hi", reasoning: "probe" },
|
|
171
|
+
{ role: "user", content: "say hi in one word" }
|
|
172
|
+
],
|
|
173
|
+
max_tokens: 1
|
|
174
|
+
}),
|
|
175
|
+
signal: AbortSignal.timeout(15e3)
|
|
176
|
+
});
|
|
177
|
+
return response.ok;
|
|
178
|
+
} catch {
|
|
179
|
+
return void 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
var STANDARD_PARAMS = ["temperature", "top_p", "max_tokens", "top_k", "reasoning_effort"];
|
|
183
|
+
var PARAM_VALUES = {
|
|
184
|
+
temperature: 0.7,
|
|
185
|
+
top_p: 0.9,
|
|
186
|
+
max_tokens: 50,
|
|
187
|
+
top_k: 40,
|
|
188
|
+
reasoning_effort: "high"
|
|
189
|
+
};
|
|
190
|
+
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
191
|
+
var REJECTED_PARAM_PATTERNS = STANDARD_PARAMS.map((param) => ({
|
|
192
|
+
param,
|
|
193
|
+
pattern: new RegExp(`\\b${escapeRegExp(param)}\\b`, "i")
|
|
194
|
+
}));
|
|
195
|
+
function extractRejectedParam(errorText) {
|
|
196
|
+
for (const { param, pattern } of REJECTED_PARAM_PATTERNS) {
|
|
197
|
+
if (pattern.test(errorText)) return param;
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
}
|
|
201
|
+
var DUMMY_TOOL = {
|
|
202
|
+
type: "function",
|
|
203
|
+
function: {
|
|
204
|
+
name: "noop",
|
|
205
|
+
description: "No-op tool for probing",
|
|
206
|
+
parameters: { type: "object", properties: {}, required: [] }
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
async function probeChatCompletions(baseUrl, headers, model, samplingParams) {
|
|
210
|
+
const body = {
|
|
211
|
+
model,
|
|
212
|
+
messages: [{ role: "user", content: "say hi in one word" }],
|
|
213
|
+
tools: [DUMMY_TOOL],
|
|
214
|
+
tool_choice: "auto"
|
|
215
|
+
};
|
|
216
|
+
for (const param of samplingParams) {
|
|
217
|
+
body[param] = PARAM_VALUES[param];
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const response = await fetch(`${ensureVersionPrefix(baseUrl)}/chat/completions`, {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers,
|
|
223
|
+
body: JSON.stringify(body),
|
|
224
|
+
signal: AbortSignal.timeout(15e3)
|
|
225
|
+
});
|
|
226
|
+
if (response.ok) return { ok: true, status: response.status, errorText: "" };
|
|
227
|
+
return { ok: false, status: response.status, errorText: await response.text() };
|
|
228
|
+
} catch {
|
|
229
|
+
return { ok: false, status: 0, errorText: "" };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async function probeRejectedParams(baseUrl, apiKey, model, backend) {
|
|
233
|
+
const headers = { "Content-Type": "application/json" };
|
|
234
|
+
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
235
|
+
const candidates = [...STANDARD_PARAMS];
|
|
236
|
+
if (["openai", "anthropic", "ollama"].includes(backend)) {
|
|
237
|
+
const idx = candidates.indexOf("top_k");
|
|
238
|
+
if (idx !== -1) candidates.splice(idx, 1);
|
|
239
|
+
}
|
|
240
|
+
const control = await probeChatCompletions(baseUrl, headers, model, []);
|
|
241
|
+
if (!control.ok) {
|
|
242
|
+
logger.debug("Auto-config: rejection-probe control failed, skipping param detection", {
|
|
243
|
+
model,
|
|
244
|
+
status: control.status
|
|
245
|
+
});
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
const rejected = [];
|
|
249
|
+
const remaining = [...candidates];
|
|
250
|
+
while (remaining.length > 0) {
|
|
251
|
+
const probe = await probeChatCompletions(baseUrl, headers, model, remaining);
|
|
252
|
+
if (probe.ok) break;
|
|
253
|
+
if (probe.status === 400) {
|
|
254
|
+
const rejectedParam = extractRejectedParam(probe.errorText);
|
|
255
|
+
if (rejectedParam && remaining.includes(rejectedParam)) {
|
|
256
|
+
rejected.push(rejectedParam);
|
|
257
|
+
remaining.splice(remaining.indexOf(rejectedParam), 1);
|
|
258
|
+
logger.debug("Auto-config: param rejected, retrying without", { model, rejectedParam });
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
if (rejected.length > 0) {
|
|
266
|
+
logger.info("Auto-config: detected rejected params", { model, rejected });
|
|
267
|
+
}
|
|
268
|
+
return rejected;
|
|
269
|
+
}
|
|
160
270
|
async function autoConfig(input) {
|
|
161
271
|
const { url, apiKey, backend, models } = input;
|
|
162
272
|
const baseUrl = url.replace(/\/+$/, "");
|
|
@@ -168,17 +278,21 @@ async function autoConfig(input) {
|
|
|
168
278
|
source: contextSource,
|
|
169
279
|
supportsVision
|
|
170
280
|
} = await detectModelInfo(baseUrl, apiKey, backend, model.id);
|
|
171
|
-
const [thinkingConfig, nonThinkingConfig] = await Promise.all([
|
|
281
|
+
const [thinkingConfig, nonThinkingConfig, rejectedParams] = await Promise.all([
|
|
172
282
|
probeCombos(baseUrl, apiKey, model.id, THINKING_COMBOS),
|
|
173
|
-
probeCombos(baseUrl, apiKey, model.id, NON_THINKING_COMBOS)
|
|
283
|
+
probeCombos(baseUrl, apiKey, model.id, NON_THINKING_COMBOS),
|
|
284
|
+
probeRejectedParams(baseUrl, apiKey, model.id, backend)
|
|
174
285
|
]);
|
|
286
|
+
const sendReasoningInMessages = thinkingConfig ? await probeReasoningInMessages(baseUrl, apiKey, model.id) : void 0;
|
|
175
287
|
results.push({
|
|
176
288
|
id: model.id,
|
|
177
289
|
contextWindow,
|
|
178
290
|
contextSource,
|
|
179
291
|
supportsVision,
|
|
180
292
|
thinkingConfig,
|
|
181
|
-
nonThinkingConfig
|
|
293
|
+
nonThinkingConfig,
|
|
294
|
+
...sendReasoningInMessages !== void 0 ? { sendReasoningInMessages } : {},
|
|
295
|
+
...rejectedParams.length > 0 ? { rejectedParams } : {}
|
|
182
296
|
});
|
|
183
297
|
}
|
|
184
298
|
return { models: results };
|
|
@@ -186,4 +300,4 @@ async function autoConfig(input) {
|
|
|
186
300
|
export {
|
|
187
301
|
autoConfig
|
|
188
302
|
};
|
|
189
|
-
//# sourceMappingURL=auto-config-
|
|
303
|
+
//# sourceMappingURL=auto-config-YXNCBYEY.js.map
|
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
buildRunChatTurnParams,
|
|
3
3
|
finalizeTurnCompletion,
|
|
4
4
|
generateSessionNameForSession
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VFS7TFA7.js";
|
|
6
6
|
import {
|
|
7
7
|
runChatTurn
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-6DDB67FN.js";
|
|
9
|
+
import "./chunk-V5XWUVF5.js";
|
|
10
|
+
import "./chunk-UNNCD7A3.js";
|
|
11
11
|
import "./chunk-2FCLCUVR.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-SE62ZBNX.js";
|
|
13
13
|
import "./chunk-27NABDXB.js";
|
|
14
14
|
import "./chunk-M6X6AIEG.js";
|
|
15
15
|
import "./chunk-ZTOG6LJD.js";
|
|
@@ -18,7 +18,7 @@ import "./chunk-JE7LW7Y6.js";
|
|
|
18
18
|
import "./chunk-OAN4BXEW.js";
|
|
19
19
|
import "./chunk-O6DU226D.js";
|
|
20
20
|
import "./chunk-J7GAZGZT.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-5FAPM2GM.js";
|
|
22
22
|
import "./chunk-EQ5CGNOT.js";
|
|
23
23
|
import "./chunk-XZGQZ42D.js";
|
|
24
24
|
import {
|
|
@@ -38,13 +38,14 @@ import "./chunk-LCLH6ZUL.js";
|
|
|
38
38
|
import "./chunk-LNNBLB6G.js";
|
|
39
39
|
import "./chunk-OSXPQSLW.js";
|
|
40
40
|
import "./chunk-3PG65AXG.js";
|
|
41
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-U6JMRMBW.js";
|
|
42
|
+
import "./chunk-K2QKX4ZJ.js";
|
|
42
43
|
import "./chunk-J2GP3J3X.js";
|
|
43
|
-
import "./chunk-
|
|
44
|
+
import "./chunk-J6KFWVZ3.js";
|
|
44
45
|
import "./chunk-W7VIYHPQ.js";
|
|
45
46
|
import "./chunk-AZHWLLPP.js";
|
|
46
47
|
import "./chunk-HNCM3D7Y.js";
|
|
47
|
-
import "./chunk-
|
|
48
|
+
import "./chunk-MIPQOHWS.js";
|
|
48
49
|
import "./chunk-LTYL6ZGH.js";
|
|
49
50
|
import "./chunk-HD6Y77RO.js";
|
|
50
51
|
import "./chunk-5PT4UMRR.js";
|
|
@@ -173,4 +174,4 @@ export {
|
|
|
173
174
|
startChatSession,
|
|
174
175
|
stopSessionExecution
|
|
175
176
|
};
|
|
176
|
-
//# sourceMappingURL=chat-handler-
|
|
177
|
+
//# sourceMappingURL=chat-handler-M54IWF5Y.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-3PG65AXG.js";
|
|
12
12
|
import {
|
|
13
13
|
parseDefaultModelSelection
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-U6JMRMBW.js";
|
|
15
15
|
import {
|
|
16
16
|
getDatabase
|
|
17
17
|
} from "./chunk-5PT4UMRR.js";
|
|
@@ -677,6 +677,12 @@ function createTasksService(deps) {
|
|
|
677
677
|
...autoLaunched ? { autoLaunched } : {}
|
|
678
678
|
});
|
|
679
679
|
}
|
|
680
|
+
function reusableTarget(projectId, sessionId) {
|
|
681
|
+
if (!sessionId) return void 0;
|
|
682
|
+
const session = sessionManager.getSession(sessionId);
|
|
683
|
+
if (!session || session.projectId !== projectId || session.messages.length > 0) return void 0;
|
|
684
|
+
return sessionId;
|
|
685
|
+
}
|
|
680
686
|
function list(projectId) {
|
|
681
687
|
return listTasks(projectId);
|
|
682
688
|
}
|
|
@@ -787,12 +793,14 @@ function createTasksService(deps) {
|
|
|
787
793
|
const launched = runningCount < settings.slotLimit && !settings.queuePaused;
|
|
788
794
|
setTaskRunState(taskId, launched ? "running" : "queued");
|
|
789
795
|
if (launched) {
|
|
790
|
-
const seeded = await seedSession(projectId, task, from);
|
|
796
|
+
const seeded = await seedSession(projectId, task, from, reusableTarget(projectId, opts.sessionId));
|
|
791
797
|
addTaskLink(taskId, seeded.session.id, true);
|
|
792
798
|
addAuditEntry(taskId, "human", "move", `Moved to In Progress (running)`, opts.actorName);
|
|
793
799
|
sessionId = seeded.session.id;
|
|
794
800
|
} else {
|
|
795
801
|
appendToBottom(taskId, "in_progress");
|
|
802
|
+
const earmarked = reusableTarget(projectId, opts.sessionId);
|
|
803
|
+
if (earmarked) addTaskLink(taskId, earmarked, false);
|
|
796
804
|
addAuditEntry(taskId, "human", "move", `Moved to In Progress (queued)`, opts.actorName);
|
|
797
805
|
}
|
|
798
806
|
}
|
|
@@ -905,11 +913,20 @@ function createTasksService(deps) {
|
|
|
905
913
|
function activeCount(projectId) {
|
|
906
914
|
return listTasks(projectId).filter((t) => t.status === "in_progress" && t.runState === "running").length;
|
|
907
915
|
}
|
|
908
|
-
async function seedSession(projectId, task, from) {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
916
|
+
async function seedSession(projectId, task, from, targetSessionId) {
|
|
917
|
+
let session;
|
|
918
|
+
if (targetSessionId) {
|
|
919
|
+
const existing = sessionManager.getSession(targetSessionId);
|
|
920
|
+
if (!existing) {
|
|
921
|
+
return seedSession(projectId, task, from);
|
|
922
|
+
}
|
|
923
|
+
session = existing;
|
|
924
|
+
} else {
|
|
925
|
+
const defaults = parseDefaultModelSelection(config.defaultModelSelection);
|
|
926
|
+
const providerId = task.providerId ?? defaults.providerId ?? null;
|
|
927
|
+
const model = task.model ?? defaults.model ?? null;
|
|
928
|
+
session = sessionManager.createSession(projectId, void 0, providerId, model);
|
|
929
|
+
}
|
|
913
930
|
if (task.agentId) {
|
|
914
931
|
try {
|
|
915
932
|
sessionManager.setMode(session.id, task.agentId);
|
|
@@ -957,7 +974,9 @@ function createTasksService(deps) {
|
|
|
957
974
|
const next = queued[0];
|
|
958
975
|
if (!next) return void 0;
|
|
959
976
|
setTaskRunState(next.id, "running");
|
|
960
|
-
const
|
|
977
|
+
const earmarks = listTaskLinks(next.id);
|
|
978
|
+
const target = reusableTarget(projectId, earmarks[0]?.session_id);
|
|
979
|
+
const seeded = await seedSession(projectId, next, "queued", target);
|
|
961
980
|
addTaskLink(next.id, seeded.session.id, true);
|
|
962
981
|
addAuditEntry(next.id, "system", "auto_launch", `Auto-launched into session ${seeded.session.id}`, "system");
|
|
963
982
|
return {
|
|
@@ -1079,4 +1098,4 @@ export {
|
|
|
1079
1098
|
isTaskGateError,
|
|
1080
1099
|
createTasksService
|
|
1081
1100
|
};
|
|
1082
|
-
//# sourceMappingURL=chunk-
|
|
1101
|
+
//# sourceMappingURL=chunk-5FAPM2GM.js.map
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
getToolRegistryForAgent,
|
|
5
5
|
processEventsForConversation,
|
|
6
6
|
runTopLevelAgentLoop
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-V5XWUVF5.js";
|
|
8
8
|
import {
|
|
9
9
|
buildCachedPrompt,
|
|
10
10
|
computeDynamicContextHash,
|
|
11
11
|
getToolFingerprint
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UNNCD7A3.js";
|
|
13
13
|
import {
|
|
14
14
|
getAllInstructions,
|
|
15
15
|
getEnabledSkillMetadata
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
TurnMetrics,
|
|
19
19
|
createChatDoneEvent,
|
|
20
20
|
createMessageStartEvent
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-SE62ZBNX.js";
|
|
22
22
|
import {
|
|
23
23
|
buildAgentReminder,
|
|
24
24
|
buildAgentSmallReminder
|
|
@@ -325,4 +325,4 @@ export {
|
|
|
325
325
|
runChatTurn,
|
|
326
326
|
runAgentTurn
|
|
327
327
|
};
|
|
328
|
-
//# sourceMappingURL=chunk-
|
|
328
|
+
//# sourceMappingURL=chunk-6DDB67FN.js.map
|
|
@@ -163,7 +163,7 @@ async function runCli(options) {
|
|
|
163
163
|
break;
|
|
164
164
|
}
|
|
165
165
|
case "provider": {
|
|
166
|
-
const { runProviderCommand } = await import("./provider-
|
|
166
|
+
const { runProviderCommand } = await import("./provider-7YF42S7C.js");
|
|
167
167
|
const [, subcommand] = positionals;
|
|
168
168
|
await runProviderCommand(mode, subcommand);
|
|
169
169
|
break;
|
|
@@ -200,7 +200,7 @@ async function runCli(options) {
|
|
|
200
200
|
break;
|
|
201
201
|
}
|
|
202
202
|
case "update": {
|
|
203
|
-
const { runUpdate } = await import("./update-
|
|
203
|
+
const { runUpdate } = await import("./update-C3YVPKCR.js");
|
|
204
204
|
const code = await runUpdate();
|
|
205
205
|
if (code !== 0) {
|
|
206
206
|
process.exit(code);
|
|
@@ -213,7 +213,7 @@ async function runCli(options) {
|
|
|
213
213
|
if (!configExists) {
|
|
214
214
|
await runNetworkSetup(mode);
|
|
215
215
|
}
|
|
216
|
-
const { runServe } = await import("./serve-
|
|
216
|
+
const { runServe } = await import("./serve-V34QG72C.js");
|
|
217
217
|
const serveOptions = { mode };
|
|
218
218
|
if (values.port) serveOptions.port = parseInt(values.port);
|
|
219
219
|
if (values["no-browser"] === true) serveOptions.openBrowser = false;
|
|
@@ -225,4 +225,4 @@ async function runCli(options) {
|
|
|
225
225
|
export {
|
|
226
226
|
runCli
|
|
227
227
|
};
|
|
228
|
-
//# sourceMappingURL=chunk-
|
|
228
|
+
//# sourceMappingURL=chunk-AIFZNTUJ.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runAgentTurn
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6DDB67FN.js";
|
|
4
4
|
import {
|
|
5
5
|
executeSubAgent,
|
|
6
6
|
getToolRegistryForAgent
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-V5XWUVF5.js";
|
|
8
8
|
import {
|
|
9
9
|
TurnMetrics,
|
|
10
10
|
createMessageStartEvent
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-SE62ZBNX.js";
|
|
12
12
|
import {
|
|
13
13
|
checkAborted,
|
|
14
14
|
decodeUtf8,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
loadProjectWorkflows,
|
|
28
28
|
loadUserWorkflows,
|
|
29
29
|
normalizeWorkflowScope
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5FAPM2GM.js";
|
|
31
31
|
import {
|
|
32
32
|
getCurrentContextWindowId,
|
|
33
33
|
getEventStore
|
|
@@ -67,13 +67,13 @@ import { spawn } from "child_process";
|
|
|
67
67
|
function getGitDiffFiles(cwd) {
|
|
68
68
|
return new Promise((resolve) => {
|
|
69
69
|
const env = gitSpawnEnv();
|
|
70
|
-
const diffProc = spawn("git", ["diff", "--name-status", "HEAD"], {
|
|
70
|
+
const diffProc = spawn("git", ["diff", "--ignore-submodules=none", "--name-status", "HEAD"], {
|
|
71
71
|
cwd,
|
|
72
72
|
env,
|
|
73
73
|
stdio: ["ignore", "pipe", "pipe"],
|
|
74
74
|
windowsHide: true
|
|
75
75
|
});
|
|
76
|
-
const statusProc = spawn("git", ["status", "--porcelain"], {
|
|
76
|
+
const statusProc = spawn("git", ["status", "--porcelain", "--ignore-submodules=none"], {
|
|
77
77
|
cwd,
|
|
78
78
|
env,
|
|
79
79
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -1002,4 +1002,4 @@ export {
|
|
|
1002
1002
|
abortRunnerRun,
|
|
1003
1003
|
launchWorkflowRun
|
|
1004
1004
|
};
|
|
1005
|
-
//# sourceMappingURL=chunk-
|
|
1005
|
+
//# sourceMappingURL=chunk-AVQCOSOF.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getThinking,
|
|
14
14
|
mapFinishReason,
|
|
15
15
|
parseToolArguments
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-MIPQOHWS.js";
|
|
17
17
|
import {
|
|
18
18
|
LLMError,
|
|
19
19
|
OpenAIHttpClient
|
|
@@ -169,15 +169,6 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
169
169
|
...buildExtraParams(resolvedEffort)
|
|
170
170
|
});
|
|
171
171
|
const { params: streamingParams } = createParams;
|
|
172
|
-
const stream = httpClient.createChatCompletionStream(streamingParams, {
|
|
173
|
-
signal: request.signal
|
|
174
|
-
});
|
|
175
|
-
let fullContent = "";
|
|
176
|
-
let fullThinking = "";
|
|
177
|
-
const toolCalls = /* @__PURE__ */ new Map();
|
|
178
|
-
let finishReason = "stop";
|
|
179
|
-
let usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
180
|
-
let responseId = "";
|
|
181
172
|
let lastChunkTime = Date.now();
|
|
182
173
|
const idleTimeoutController = new AbortController();
|
|
183
174
|
const idleTimer = setInterval(() => {
|
|
@@ -187,6 +178,16 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
187
178
|
idleTimeoutController.abort();
|
|
188
179
|
}
|
|
189
180
|
}, 100);
|
|
181
|
+
const streamSignal = request.signal ? AbortSignal.any([request.signal, idleTimeoutController.signal]) : idleTimeoutController.signal;
|
|
182
|
+
const stream = httpClient.createChatCompletionStream(streamingParams, {
|
|
183
|
+
signal: streamSignal
|
|
184
|
+
});
|
|
185
|
+
let fullContent = "";
|
|
186
|
+
let fullThinking = "";
|
|
187
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
188
|
+
let finishReason = "stop";
|
|
189
|
+
let usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
190
|
+
let responseId = "";
|
|
190
191
|
const onAbort = () => clearInterval(idleTimer);
|
|
191
192
|
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
192
193
|
try {
|
|
@@ -203,9 +204,9 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
203
204
|
responseId = chunk.id;
|
|
204
205
|
if (chunk.usage) {
|
|
205
206
|
usage = {
|
|
206
|
-
promptTokens: chunk.usage.prompt_tokens,
|
|
207
|
-
completionTokens: chunk.usage.completion_tokens,
|
|
208
|
-
totalTokens: chunk.usage.total_tokens
|
|
207
|
+
promptTokens: chunk.usage.prompt_tokens ?? usage.promptTokens,
|
|
208
|
+
completionTokens: chunk.usage.completion_tokens ?? usage.completionTokens,
|
|
209
|
+
totalTokens: chunk.usage.total_tokens ?? usage.totalTokens
|
|
209
210
|
};
|
|
210
211
|
}
|
|
211
212
|
const choice = chunk.choices[0];
|
|
@@ -259,6 +260,11 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
259
260
|
}
|
|
260
261
|
}
|
|
261
262
|
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (idleTimeoutController.signal.aborted && !request.signal?.aborted) {
|
|
265
|
+
throw new Error(`LLM stream idle timeout: no chunks received for ${idleTimeout}ms`);
|
|
266
|
+
}
|
|
267
|
+
throw error;
|
|
262
268
|
} finally {
|
|
263
269
|
clearInterval(idleTimer);
|
|
264
270
|
request.signal?.removeEventListener("abort", onAbort);
|
|
@@ -297,7 +303,7 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
297
303
|
}
|
|
298
304
|
};
|
|
299
305
|
} catch (error) {
|
|
300
|
-
logger.error("LLM stream error", { error });
|
|
306
|
+
logger.error("LLM stream error", { error: String(error) });
|
|
301
307
|
yield {
|
|
302
308
|
type: "error",
|
|
303
309
|
error: error instanceof Error ? error.message : "Unknown LLM error"
|
|
@@ -310,4 +316,4 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
310
316
|
export {
|
|
311
317
|
createLLMClient
|
|
312
318
|
};
|
|
313
|
-
//# sourceMappingURL=chunk-
|
|
319
|
+
//# sourceMappingURL=chunk-J6KFWVZ3.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/server/providers/lmstudio.ts
|
|
2
|
+
function unwrap(raw) {
|
|
3
|
+
if (Array.isArray(raw)) return raw;
|
|
4
|
+
if (raw && typeof raw === "object") {
|
|
5
|
+
const record = raw;
|
|
6
|
+
if (Array.isArray(record.models)) return record.models;
|
|
7
|
+
if (Array.isArray(record.data)) return record.data;
|
|
8
|
+
}
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
function parseLmStudioModels(raw) {
|
|
12
|
+
return unwrap(raw).map((model) => {
|
|
13
|
+
const id = model.key ?? model.id ?? "";
|
|
14
|
+
const loaded = model.loaded_instances?.[0]?.config?.context_length;
|
|
15
|
+
const contextWindow = loaded ?? model.max_context_length;
|
|
16
|
+
return {
|
|
17
|
+
id,
|
|
18
|
+
...contextWindow ? { contextWindow } : {},
|
|
19
|
+
supportsVision: model.capabilities?.vision ?? false
|
|
20
|
+
};
|
|
21
|
+
}).filter((model) => model.id !== "");
|
|
22
|
+
}
|
|
23
|
+
function findLmStudioModel(raw, modelId) {
|
|
24
|
+
return parseLmStudioModels(raw).find((model) => model.id === modelId);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
parseLmStudioModels,
|
|
29
|
+
findLmStudioModel
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-K2QKX4ZJ.js.map
|
|
@@ -463,11 +463,12 @@ function parseToolArguments(raw, _meta) {
|
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
465
|
function buildModelParams(params) {
|
|
466
|
+
const isOmitted = (key) => params.omitParams?.includes(key) ?? false;
|
|
466
467
|
return {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
468
|
+
...!isOmitted("temperature") && params.temperature !== void 0 && { temperature: params.temperature },
|
|
469
|
+
...!isOmitted("top_p") && params.topP !== void 0 && { topP: params.topP },
|
|
470
|
+
...!isOmitted("top_k") && params.topK !== void 0 && { topK: params.topK },
|
|
471
|
+
...!isOmitted("max_tokens") && params.maxTokens !== void 0 && { maxTokens: params.maxTokens }
|
|
471
472
|
};
|
|
472
473
|
}
|
|
473
474
|
async function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
@@ -644,7 +645,20 @@ async function buildChatCompletionCreateParams(model, request, profile, capabili
|
|
|
644
645
|
};
|
|
645
646
|
}
|
|
646
647
|
}
|
|
647
|
-
const
|
|
648
|
+
const omitParams = request.modelSettings?.omitParams;
|
|
649
|
+
if (omitParams && omitParams.length > 0) {
|
|
650
|
+
const paramRecord = params;
|
|
651
|
+
for (const key of omitParams) {
|
|
652
|
+
delete paramRecord[key];
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
const modelParams = buildModelParams({
|
|
656
|
+
temperature,
|
|
657
|
+
topP,
|
|
658
|
+
topK,
|
|
659
|
+
maxTokens,
|
|
660
|
+
...omitParams !== void 0 && { omitParams }
|
|
661
|
+
});
|
|
648
662
|
return { params, modelParams };
|
|
649
663
|
}
|
|
650
664
|
async function buildCreateParamsFromInput(input, isStreaming) {
|
|
@@ -697,4 +711,4 @@ export {
|
|
|
697
711
|
buildStreamingCreateParams,
|
|
698
712
|
mapFinishReason
|
|
699
713
|
};
|
|
700
|
-
//# sourceMappingURL=chunk-
|
|
714
|
+
//# sourceMappingURL=chunk-MIPQOHWS.js.map
|