openfox 1.6.21 → 1.6.23
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/README.md +46 -13
- package/dist/{auto-compaction-U75EINMB.js → auto-compaction-7LK3QGPI.js} +4 -3
- package/dist/{chat-handler-JEMPI5UF.js → chat-handler-ZU74RXED.js} +6 -5
- package/dist/{chunk-HZP2V5Z6.js → chunk-4O3C2JMB.js} +5 -9
- package/dist/{chunk-AU33PQAB.js → chunk-BOEXJCOD.js} +2 -2
- package/dist/{chunk-6NPMZFMP.js → chunk-CJNQGEYG.js} +2 -2
- package/dist/{chunk-XYD5JXRM.js → chunk-D4ZLSV6P.js} +292 -1
- package/dist/{chunk-HWOYZ245.js → chunk-FTJPNCAV.js} +6 -6
- package/dist/{chunk-FX4SUY2S.js → chunk-KSASIV4B.js} +10 -287
- package/dist/{chunk-XRGMFOVG.js → chunk-P6GUT2QQ.js} +3 -3
- package/dist/{chunk-WINI5HX7.js → chunk-PYBB34ZK.js} +3 -3
- package/dist/{chunk-SJVEX2NR.js → chunk-YCQSAFAQ.js} +19 -19
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-SWDAJMQ3.js → config-ACVEHBKG.js} +5 -5
- package/dist/{orchestrator-T2IPRZ7B.js → orchestrator-OE7WFEW6.js} +5 -4
- package/dist/package.json +3 -3
- package/dist/{processor-VKFEOK46.js → processor-GAOK7TPI.js} +2 -2
- package/dist/{provider-CDM4LQAC.js → provider-RLQMVV2Z.js} +7 -7
- package/dist/{serve-X3PKC27B.js → serve-IBJ3SN3Q.js} +9 -9
- package/dist/server/index.js +7 -7
- package/dist/{tools-4ODVFMW7.js → tools-CSV7G554.js} +4 -3
- package/dist/{vision-fallback-VXGCQKLA.js → vision-fallback-QJ26DCEF.js} +2 -2
- package/dist/web/assets/{index-DHP3d5Cl.js → index-BrZqZwpA.js} +56 -54
- package/dist/web/assets/{index-B9-lT3Kc.css → index-DF26vcqg.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
Autonomous coding agent for local LLMs with contract-driven execution.
|
|
6
6
|
|
|
7
|
+
*Session — Criteria tracking, tool calls, and streaming responses*
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
*Providers — Local LLM backend configuration*
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
*Workflows — Contract-driven execution pipeline*
|
|
14
|
+

|
|
15
|
+
|
|
7
16
|
## Quick Start
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
|
-
|
|
19
|
+
npm i -g openfox
|
|
20
|
+
openfox
|
|
11
21
|
```
|
|
12
22
|
|
|
13
23
|
On first run, OpenFox automatically detects your local LLM backend (vLLM, sglang, ollama, llamacpp) and configures itself.
|
|
@@ -16,25 +26,22 @@ On first run, OpenFox automatically detects your local LLM backend (vLLM, sglang
|
|
|
16
26
|
|
|
17
27
|
```bash
|
|
18
28
|
# Start server for current project
|
|
19
|
-
|
|
29
|
+
openfox
|
|
20
30
|
|
|
21
31
|
# Start on custom port
|
|
22
|
-
|
|
32
|
+
openfox --port 8080
|
|
23
33
|
|
|
24
34
|
# Start without opening browser
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Interactive configuration setup
|
|
28
|
-
npx openfox init
|
|
35
|
+
openfox --no-browser
|
|
29
36
|
|
|
30
37
|
# Show current configuration
|
|
31
|
-
|
|
38
|
+
openfox config
|
|
32
39
|
|
|
33
40
|
# Manage LLM providers
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
openfox provider add # Add new provider
|
|
42
|
+
openfox provider list # List configured providers
|
|
43
|
+
openfox provider use # Switch active provider
|
|
44
|
+
openfox provider remove # Remove provider
|
|
38
45
|
```
|
|
39
46
|
|
|
40
47
|
## CLI Options
|
|
@@ -63,6 +70,32 @@ npx openfox provider remove # Remove provider
|
|
|
63
70
|
- **LSP Integration**: Immediate feedback on code validity
|
|
64
71
|
- **Real-Time Metrics**: Prefill time, generation speed, context usage
|
|
65
72
|
|
|
73
|
+
## Screenshots
|
|
74
|
+
|
|
75
|
+
*Homepage — Project overview and session history*
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
*Project Selected — Active session with context stats*
|
|
79
|
+

|
|
80
|
+
|
|
81
|
+
*Stats — Prefill time, generation speed, token usage*
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
*Terminal — Integrated terminal for running commands*
|
|
85
|
+

|
|
86
|
+
|
|
87
|
+
*Notifications — Event log and system messages*
|
|
88
|
+

|
|
89
|
+
|
|
90
|
+
*Agents — Sub-agent management and execution*
|
|
91
|
+

|
|
92
|
+
|
|
93
|
+
*General Instructions — Global custom instructions*
|
|
94
|
+

|
|
95
|
+
|
|
96
|
+
*Vision Fallback — Image processing configuration*
|
|
97
|
+

|
|
98
|
+
|
|
66
99
|
## License
|
|
67
100
|
|
|
68
|
-
MIT
|
|
101
|
+
MIT
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
maybeAutoCompactContext,
|
|
3
3
|
performManualContextCompaction,
|
|
4
4
|
resolveCompactionStatsIdentity
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4O3C2JMB.js";
|
|
6
6
|
import "./chunk-NBU6KIOD.js";
|
|
7
7
|
import "./chunk-574HZVLE.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-D4ZLSV6P.js";
|
|
9
9
|
import "./chunk-PMDJEJYY.js";
|
|
10
10
|
import "./chunk-EEPU4INU.js";
|
|
11
11
|
import "./chunk-DZHZ3UUR.js";
|
|
@@ -16,10 +16,11 @@ import "./chunk-3EHGGBWE.js";
|
|
|
16
16
|
import "./chunk-Y6HBEACI.js";
|
|
17
17
|
import "./chunk-R4HADRYO.js";
|
|
18
18
|
import "./chunk-TVQOONDR.js";
|
|
19
|
+
import "./chunk-CJNQGEYG.js";
|
|
19
20
|
import "./chunk-PNBH3RAX.js";
|
|
20
21
|
export {
|
|
21
22
|
maybeAutoCompactContext,
|
|
22
23
|
performManualContextCompaction,
|
|
23
24
|
resolveCompactionStatsIdentity
|
|
24
25
|
};
|
|
25
|
-
//# sourceMappingURL=auto-compaction-
|
|
26
|
+
//# sourceMappingURL=auto-compaction-7LK3QGPI.js.map
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
} from "./chunk-AV45GQ7B.js";
|
|
11
11
|
import {
|
|
12
12
|
runChatTurn
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-BOEXJCOD.js";
|
|
14
|
+
import "./chunk-4O3C2JMB.js";
|
|
15
15
|
import "./chunk-NBU6KIOD.js";
|
|
16
16
|
import "./chunk-574HZVLE.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-D4ZLSV6P.js";
|
|
18
18
|
import {
|
|
19
19
|
getEventStore
|
|
20
20
|
} from "./chunk-PMDJEJYY.js";
|
|
@@ -31,6 +31,7 @@ import "./chunk-3EHGGBWE.js";
|
|
|
31
31
|
import "./chunk-Y6HBEACI.js";
|
|
32
32
|
import "./chunk-R4HADRYO.js";
|
|
33
33
|
import "./chunk-TVQOONDR.js";
|
|
34
|
+
import "./chunk-CJNQGEYG.js";
|
|
34
35
|
import {
|
|
35
36
|
logger
|
|
36
37
|
} from "./chunk-PNBH3RAX.js";
|
|
@@ -61,7 +62,7 @@ async function startChatSession(sessionId, content, deps, options) {
|
|
|
61
62
|
sessionManager.setRunning(sessionId, true);
|
|
62
63
|
broadcastForSession(sessionId, createSessionRunningMessage(true));
|
|
63
64
|
try {
|
|
64
|
-
const { maybeAutoCompactContext } = await import("./auto-compaction-
|
|
65
|
+
const { maybeAutoCompactContext } = await import("./auto-compaction-7LK3QGPI.js");
|
|
65
66
|
await maybeAutoCompactContext({
|
|
66
67
|
sessionManager,
|
|
67
68
|
sessionId,
|
|
@@ -170,4 +171,4 @@ export {
|
|
|
170
171
|
startChatSession,
|
|
171
172
|
stopSessionExecution
|
|
172
173
|
};
|
|
173
|
-
//# sourceMappingURL=chat-handler-
|
|
174
|
+
//# sourceMappingURL=chat-handler-ZU74RXED.js.map
|
|
@@ -12,10 +12,11 @@ import {
|
|
|
12
12
|
getSessionProcessCount
|
|
13
13
|
} from "./chunk-574HZVLE.js";
|
|
14
14
|
import {
|
|
15
|
+
buildModelParams,
|
|
15
16
|
getBackendCapabilities,
|
|
16
17
|
getModelProfile,
|
|
17
18
|
streamWithSegments
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-D4ZLSV6P.js";
|
|
19
20
|
import {
|
|
20
21
|
getContextMessages,
|
|
21
22
|
getCurrentContextWindowId,
|
|
@@ -542,12 +543,7 @@ async function* streamLLMPure(options) {
|
|
|
542
543
|
const maxTokens = userMaxTokens ?? profile.defaultMaxTokens;
|
|
543
544
|
const topP = userTopP ?? profile.topP;
|
|
544
545
|
const topK = userTopK ?? (backend.supportsTopK ? profile.topK : void 0);
|
|
545
|
-
const modelParams = {
|
|
546
|
-
...temperature !== void 0 && { temperature },
|
|
547
|
-
...topP !== void 0 && { topP },
|
|
548
|
-
...topK !== void 0 && { topK },
|
|
549
|
-
...maxTokens !== void 0 && { maxTokens }
|
|
550
|
-
};
|
|
546
|
+
const modelParams = buildModelParams({ temperature, topP, topK, maxTokens });
|
|
551
547
|
logger.debug("LLM request settings", {
|
|
552
548
|
model: llmClient.getModel(),
|
|
553
549
|
profile: profile.name,
|
|
@@ -3351,7 +3347,7 @@ var callSubAgentTool = {
|
|
|
3351
3347
|
};
|
|
3352
3348
|
}
|
|
3353
3349
|
try {
|
|
3354
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3350
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-CSV7G554.js");
|
|
3355
3351
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3356
3352
|
const turnMetrics = new TurnMetrics();
|
|
3357
3353
|
const result = await executeSubAgent({
|
|
@@ -4480,4 +4476,4 @@ export {
|
|
|
4480
4476
|
getToolRegistryForAgent,
|
|
4481
4477
|
createToolRegistry
|
|
4482
4478
|
};
|
|
4483
|
-
//# sourceMappingURL=chunk-
|
|
4479
|
+
//# sourceMappingURL=chunk-4O3C2JMB.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getToolRegistryForAgent,
|
|
14
14
|
loadAllAgentsDefault,
|
|
15
15
|
runTopLevelAgentLoop
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4O3C2JMB.js";
|
|
17
17
|
import {
|
|
18
18
|
getCurrentContextWindowId,
|
|
19
19
|
getEventStore
|
|
@@ -293,4 +293,4 @@ export {
|
|
|
293
293
|
runBuilderTurn,
|
|
294
294
|
runVerifierTurn
|
|
295
295
|
};
|
|
296
|
-
//# sourceMappingURL=chunk-
|
|
296
|
+
//# sourceMappingURL=chunk-BOEXJCOD.js.map
|
|
@@ -29,7 +29,7 @@ function isVisionFallbackEnabled() {
|
|
|
29
29
|
async function ensureVisionFallbackConfigLoaded() {
|
|
30
30
|
if (configLoaded) return;
|
|
31
31
|
try {
|
|
32
|
-
const { loadGlobalConfig, getVisionFallback } = await import("./config-
|
|
32
|
+
const { loadGlobalConfig, getVisionFallback } = await import("./config-ACVEHBKG.js");
|
|
33
33
|
const { getRuntimeConfig } = await import("./runtime-config-2XJJIMSC.js");
|
|
34
34
|
const runtimeConfig = getRuntimeConfig();
|
|
35
35
|
const mode = runtimeConfig.mode ?? "production";
|
|
@@ -135,4 +135,4 @@ export {
|
|
|
135
135
|
describeImage,
|
|
136
136
|
describeImageFromDataUrl
|
|
137
137
|
};
|
|
138
|
-
//# sourceMappingURL=chunk-
|
|
138
|
+
//# sourceMappingURL=chunk-CJNQGEYG.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describeImageFromDataUrl
|
|
3
|
+
} from "./chunk-CJNQGEYG.js";
|
|
1
4
|
import {
|
|
2
5
|
logger
|
|
3
6
|
} from "./chunk-PNBH3RAX.js";
|
|
@@ -360,6 +363,289 @@ function getModelProfile(modelName) {
|
|
|
360
363
|
return DEFAULT_PROFILE;
|
|
361
364
|
}
|
|
362
365
|
|
|
366
|
+
// src/server/llm/client-pure.ts
|
|
367
|
+
function buildModelParams(params) {
|
|
368
|
+
return {
|
|
369
|
+
...params.temperature !== void 0 && { temperature: params.temperature },
|
|
370
|
+
...params.topP !== void 0 && { topP: params.topP },
|
|
371
|
+
...params.topK !== void 0 && { topK: params.topK },
|
|
372
|
+
...params.maxTokens !== void 0 && { maxTokens: params.maxTokens }
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
376
|
+
const content = [];
|
|
377
|
+
if (msgContent?.trim()) {
|
|
378
|
+
content.push({ type: "text", text: msgContent });
|
|
379
|
+
}
|
|
380
|
+
for (const attachment of attachments) {
|
|
381
|
+
content.push(convertAttachmentSync(attachment, modelSupportsVision));
|
|
382
|
+
}
|
|
383
|
+
return content;
|
|
384
|
+
}
|
|
385
|
+
async function convertMessagesWithOptions(messages, profile, visionFallbackEnabled, signal, onVisionFallbackStart, onVisionFallbackDone) {
|
|
386
|
+
const modelSupportsVision = profile.supportsVision ?? false;
|
|
387
|
+
const options = {
|
|
388
|
+
modelSupportsVision,
|
|
389
|
+
visionFallbackEnabled,
|
|
390
|
+
signal,
|
|
391
|
+
onVisionFallbackStart,
|
|
392
|
+
onVisionFallbackDone
|
|
393
|
+
};
|
|
394
|
+
return needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) ? await convertMessagesWithFallback(messages, options) : convertMessages(messages, { modelSupportsVision, visionFallbackEnabled: false });
|
|
395
|
+
}
|
|
396
|
+
function convertToolCalls(toolCalls) {
|
|
397
|
+
return toolCalls.map((toolCall) => ({
|
|
398
|
+
id: toolCall.id,
|
|
399
|
+
type: "function",
|
|
400
|
+
function: {
|
|
401
|
+
name: toolCall.name,
|
|
402
|
+
arguments: JSON.stringify(toolCall.arguments)
|
|
403
|
+
}
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
function convertAttachmentSync(attachment, modelSupportsVision) {
|
|
407
|
+
if (modelSupportsVision) {
|
|
408
|
+
return {
|
|
409
|
+
type: "image_url",
|
|
410
|
+
image_url: { url: attachment.data }
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
type: "text",
|
|
415
|
+
text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function createAttachmentForConversion(data, filename, id) {
|
|
419
|
+
return {
|
|
420
|
+
data,
|
|
421
|
+
...filename !== void 0 && { filename },
|
|
422
|
+
...id !== void 0 && { id }
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
async function convertAttachmentWithFallback(attachment, options) {
|
|
426
|
+
logger.debug("[VisionFallback] convertAttachmentWithFallback called", { filename: attachment.filename, id: attachment.id, hasCallbacks: !!options.onVisionFallbackStart });
|
|
427
|
+
if (options.modelSupportsVision) {
|
|
428
|
+
logger.debug("[VisionFallback] Model supports vision - passing image directly");
|
|
429
|
+
return {
|
|
430
|
+
type: "image_url",
|
|
431
|
+
image_url: { url: attachment.data }
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (!options.visionFallbackEnabled) {
|
|
435
|
+
logger.debug("[VisionFallback] Fallback disabled - returning placeholder");
|
|
436
|
+
return {
|
|
437
|
+
type: "text",
|
|
438
|
+
text: `[Image: ${attachment.filename || "image"}] (vision not supported)`
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const attachmentId = attachment.id ?? crypto.randomUUID();
|
|
442
|
+
const filename = attachment.filename;
|
|
443
|
+
logger.debug("[VisionFallback] Starting delegation for:", { attachmentId, filename });
|
|
444
|
+
options.onVisionFallbackStart?.(attachmentId, filename);
|
|
445
|
+
const context = filename ? `File: ${filename}` : void 0;
|
|
446
|
+
const description = await describeImageFromDataUrl(attachment.data, { context, signal: options.signal });
|
|
447
|
+
logger.debug("[VisionFallback] Delegation complete:", { attachmentId, descriptionLength: description.length });
|
|
448
|
+
options.onVisionFallbackDone?.(attachmentId, description);
|
|
449
|
+
return {
|
|
450
|
+
type: "text",
|
|
451
|
+
text: `[Image: ${attachment.filename || "image"}] ${description}`
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
async function buildAttachmentContentWithFallback(msgContent, attachments, options) {
|
|
455
|
+
const content = [];
|
|
456
|
+
if (msgContent?.trim()) {
|
|
457
|
+
content.push({ type: "text", text: msgContent });
|
|
458
|
+
}
|
|
459
|
+
for (const attachment of attachments) {
|
|
460
|
+
const convertedContent = await convertAttachmentWithFallback(
|
|
461
|
+
createAttachmentForConversion(attachment.data, attachment.filename, attachment.id),
|
|
462
|
+
options
|
|
463
|
+
);
|
|
464
|
+
content.push(convertedContent);
|
|
465
|
+
}
|
|
466
|
+
return content;
|
|
467
|
+
}
|
|
468
|
+
function convertMessages(messages, options) {
|
|
469
|
+
const filtered = messages.filter((msg) => {
|
|
470
|
+
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
471
|
+
});
|
|
472
|
+
return filtered.map((msg) => {
|
|
473
|
+
if (msg.role === "tool") {
|
|
474
|
+
if (msg.attachments && msg.attachments.length > 0) {
|
|
475
|
+
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
476
|
+
return {
|
|
477
|
+
role: "tool",
|
|
478
|
+
content,
|
|
479
|
+
tool_call_id: msg.toolCallId
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
role: "tool",
|
|
484
|
+
content: msg.content,
|
|
485
|
+
tool_call_id: msg.toolCallId
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
489
|
+
return {
|
|
490
|
+
role: "assistant",
|
|
491
|
+
content: msg.content || null,
|
|
492
|
+
tool_calls: convertToolCalls(msg.toolCalls)
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
496
|
+
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
497
|
+
return {
|
|
498
|
+
role: "user",
|
|
499
|
+
content
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
role: msg.role,
|
|
504
|
+
content: msg.content
|
|
505
|
+
};
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
async function convertMessagesWithFallback(messages, options) {
|
|
509
|
+
logger.debug("[VisionFallback] convertMessagesWithFallback called", { messageCount: messages.length });
|
|
510
|
+
const filtered = messages.filter((msg) => {
|
|
511
|
+
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
512
|
+
});
|
|
513
|
+
const converted = [];
|
|
514
|
+
for (const msg of filtered) {
|
|
515
|
+
if (msg.role === "tool") {
|
|
516
|
+
if (msg.attachments && msg.attachments.length > 0) {
|
|
517
|
+
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
518
|
+
converted.push({
|
|
519
|
+
role: "tool",
|
|
520
|
+
content,
|
|
521
|
+
tool_call_id: msg.toolCallId
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
converted.push({
|
|
525
|
+
role: "tool",
|
|
526
|
+
content: msg.content,
|
|
527
|
+
tool_call_id: msg.toolCallId
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
533
|
+
converted.push({
|
|
534
|
+
role: "assistant",
|
|
535
|
+
content: msg.content || null,
|
|
536
|
+
tool_calls: convertToolCalls(msg.toolCalls)
|
|
537
|
+
});
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
541
|
+
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
542
|
+
converted.push({
|
|
543
|
+
role: "user",
|
|
544
|
+
content
|
|
545
|
+
});
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
converted.push({
|
|
549
|
+
role: msg.role,
|
|
550
|
+
content: msg.content
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return converted;
|
|
554
|
+
}
|
|
555
|
+
function convertTools(tools) {
|
|
556
|
+
return tools.map((tool) => ({
|
|
557
|
+
type: "function",
|
|
558
|
+
function: {
|
|
559
|
+
name: tool.function.name,
|
|
560
|
+
description: tool.function.description,
|
|
561
|
+
parameters: tool.function.parameters
|
|
562
|
+
}
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
565
|
+
function needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) {
|
|
566
|
+
const hasAttachments = messages.some(
|
|
567
|
+
(msg) => msg.attachments && msg.attachments.length > 0 || msg.role === "tool" && msg.attachments && msg.attachments.length > 0
|
|
568
|
+
);
|
|
569
|
+
const result = hasAttachments && !modelSupportsVision && visionFallbackEnabled;
|
|
570
|
+
logger.debug("[VisionFallback] needsVisionFallback check", {
|
|
571
|
+
hasAttachments,
|
|
572
|
+
modelSupportsVision,
|
|
573
|
+
visionFallbackEnabled,
|
|
574
|
+
result
|
|
575
|
+
});
|
|
576
|
+
return result;
|
|
577
|
+
}
|
|
578
|
+
async function buildChatCompletionCreateParams(model, request, profile, capabilities, disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone) {
|
|
579
|
+
const convertedMessages = await convertMessagesWithOptions(
|
|
580
|
+
request.messages,
|
|
581
|
+
profile,
|
|
582
|
+
visionFallbackEnabled,
|
|
583
|
+
request.signal,
|
|
584
|
+
onVisionFallbackStart,
|
|
585
|
+
onVisionFallbackDone
|
|
586
|
+
);
|
|
587
|
+
const temperature = request.temperature ?? profile.temperature;
|
|
588
|
+
const maxTokens = request.maxTokens ?? profile.defaultMaxTokens;
|
|
589
|
+
const topP = profile.topP;
|
|
590
|
+
const topK = capabilities.supportsTopK ? profile.topK : void 0;
|
|
591
|
+
const params = {
|
|
592
|
+
model,
|
|
593
|
+
messages: convertedMessages,
|
|
594
|
+
...request.tools ? { tools: convertTools(request.tools) } : {},
|
|
595
|
+
...request.toolChoice ? { tool_choice: request.toolChoice } : {},
|
|
596
|
+
temperature,
|
|
597
|
+
max_tokens: maxTokens,
|
|
598
|
+
top_p: topP,
|
|
599
|
+
stream: isStreaming,
|
|
600
|
+
...isStreaming ? { stream_options: { include_usage: true } } : {}
|
|
601
|
+
};
|
|
602
|
+
if (topK !== void 0) {
|
|
603
|
+
;
|
|
604
|
+
params["top_k"] = topK;
|
|
605
|
+
}
|
|
606
|
+
const shouldDisableThinking = isStreaming ? disableThinking || request.disableThinking : disableThinking;
|
|
607
|
+
if (capabilities.supportsChatTemplateKwargs && profile.supportsReasoning && shouldDisableThinking) {
|
|
608
|
+
;
|
|
609
|
+
params["chat_template_kwargs"] = { enable_thinking: false };
|
|
610
|
+
}
|
|
611
|
+
const modelParams = buildModelParams({ temperature, topP, topK, maxTokens });
|
|
612
|
+
return { params, modelParams };
|
|
613
|
+
}
|
|
614
|
+
async function buildCreateParamsFromInput(input, isStreaming) {
|
|
615
|
+
const { model, request, profile, capabilities, disableThinking, visionFallbackEnabled = false, onVisionFallbackStart, onVisionFallbackDone } = input;
|
|
616
|
+
return buildChatCompletionCreateParams(model, request, profile, capabilities, !!disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone);
|
|
617
|
+
}
|
|
618
|
+
var buildNonStreamingCreateParams = (input) => buildCreateParamsFromInput(input, false);
|
|
619
|
+
var buildStreamingCreateParams = (input) => buildCreateParamsFromInput(input, true);
|
|
620
|
+
function mapFinishReason(reason) {
|
|
621
|
+
switch (reason) {
|
|
622
|
+
case "stop":
|
|
623
|
+
return "stop";
|
|
624
|
+
case "tool_calls":
|
|
625
|
+
return "tool_calls";
|
|
626
|
+
case "length":
|
|
627
|
+
return "length";
|
|
628
|
+
case "content_filter":
|
|
629
|
+
return "content_filter";
|
|
630
|
+
default:
|
|
631
|
+
return "stop";
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function extractThinking(content) {
|
|
635
|
+
const thinkRegex = /<think>([\s\S]*?)<\/think>/g;
|
|
636
|
+
let thinkingContent = "";
|
|
637
|
+
let cleanContent = content;
|
|
638
|
+
let match;
|
|
639
|
+
while ((match = thinkRegex.exec(content)) !== null) {
|
|
640
|
+
thinkingContent += match[1];
|
|
641
|
+
cleanContent = cleanContent.replace(match[0], "");
|
|
642
|
+
}
|
|
643
|
+
return {
|
|
644
|
+
content: cleanContent.trim(),
|
|
645
|
+
thinkingContent: thinkingContent.trim() || null
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
363
649
|
// src/server/llm/streaming.ts
|
|
364
650
|
var XML_TOOL_PATTERNS = ["<tool_call>", "<function=", "</tool_call>", "<parameter="];
|
|
365
651
|
function hasXmlToolPattern(text) {
|
|
@@ -478,6 +764,11 @@ export {
|
|
|
478
764
|
getBackendCapabilities,
|
|
479
765
|
detectBackend,
|
|
480
766
|
getBackendDisplayName,
|
|
767
|
+
buildModelParams,
|
|
768
|
+
buildNonStreamingCreateParams,
|
|
769
|
+
buildStreamingCreateParams,
|
|
770
|
+
mapFinishReason,
|
|
771
|
+
extractThinking,
|
|
481
772
|
streamWithSegments
|
|
482
773
|
};
|
|
483
|
-
//# sourceMappingURL=chunk-
|
|
774
|
+
//# sourceMappingURL=chunk-D4ZLSV6P.js.map
|
|
@@ -27,7 +27,7 @@ Options:
|
|
|
27
27
|
}
|
|
28
28
|
async function runNetworkSetup(mode) {
|
|
29
29
|
const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-JF2HDJ6P.js");
|
|
30
|
-
const { saveGlobalConfig } = await import("./config-
|
|
30
|
+
const { saveGlobalConfig } = await import("./config-ACVEHBKG.js");
|
|
31
31
|
const { getAuthKeyPath } = await import("./paths-ZRI56O63.js");
|
|
32
32
|
const existingAuth = await loadAuthConfig(mode);
|
|
33
33
|
if (existingAuth) {
|
|
@@ -88,7 +88,7 @@ async function runNetworkSetup(mode) {
|
|
|
88
88
|
console.log("\u2713 Configuration saved!\n");
|
|
89
89
|
}
|
|
90
90
|
async function runConfig(mode) {
|
|
91
|
-
const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-
|
|
91
|
+
const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-ACVEHBKG.js");
|
|
92
92
|
const { getGlobalConfigPath } = await import("./paths-ZRI56O63.js");
|
|
93
93
|
const config = await loadGlobalConfig(mode);
|
|
94
94
|
const configPath = getGlobalConfigPath(mode);
|
|
@@ -143,18 +143,18 @@ async function runCli(options) {
|
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
145
145
|
case "provider": {
|
|
146
|
-
const { runProviderCommand } = await import("./provider-
|
|
146
|
+
const { runProviderCommand } = await import("./provider-RLQMVV2Z.js");
|
|
147
147
|
const [, subcommand] = positionals;
|
|
148
148
|
await runProviderCommand(mode, subcommand);
|
|
149
149
|
break;
|
|
150
150
|
}
|
|
151
151
|
default: {
|
|
152
|
-
const { configFileExists } = await import("./config-
|
|
152
|
+
const { configFileExists } = await import("./config-ACVEHBKG.js");
|
|
153
153
|
const configExists = await configFileExists(mode);
|
|
154
154
|
if (!configExists) {
|
|
155
155
|
await runNetworkSetup(mode);
|
|
156
156
|
}
|
|
157
|
-
const { runServe } = await import("./serve-
|
|
157
|
+
const { runServe } = await import("./serve-IBJ3SN3Q.js");
|
|
158
158
|
await runServe({
|
|
159
159
|
mode,
|
|
160
160
|
port: values.port ? parseInt(values.port) : void 0,
|
|
@@ -167,4 +167,4 @@ async function runCli(options) {
|
|
|
167
167
|
export {
|
|
168
168
|
runCli
|
|
169
169
|
};
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
170
|
+
//# sourceMappingURL=chunk-FTJPNCAV.js.map
|