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.
Files changed (28) hide show
  1. package/README.md +46 -13
  2. package/dist/{auto-compaction-U75EINMB.js → auto-compaction-7LK3QGPI.js} +4 -3
  3. package/dist/{chat-handler-JEMPI5UF.js → chat-handler-ZU74RXED.js} +6 -5
  4. package/dist/{chunk-HZP2V5Z6.js → chunk-4O3C2JMB.js} +5 -9
  5. package/dist/{chunk-AU33PQAB.js → chunk-BOEXJCOD.js} +2 -2
  6. package/dist/{chunk-6NPMZFMP.js → chunk-CJNQGEYG.js} +2 -2
  7. package/dist/{chunk-XYD5JXRM.js → chunk-D4ZLSV6P.js} +292 -1
  8. package/dist/{chunk-HWOYZ245.js → chunk-FTJPNCAV.js} +6 -6
  9. package/dist/{chunk-FX4SUY2S.js → chunk-KSASIV4B.js} +10 -287
  10. package/dist/{chunk-XRGMFOVG.js → chunk-P6GUT2QQ.js} +3 -3
  11. package/dist/{chunk-WINI5HX7.js → chunk-PYBB34ZK.js} +3 -3
  12. package/dist/{chunk-SJVEX2NR.js → chunk-YCQSAFAQ.js} +19 -19
  13. package/dist/cli/dev.js +1 -1
  14. package/dist/cli/index.js +1 -1
  15. package/dist/{config-SWDAJMQ3.js → config-ACVEHBKG.js} +5 -5
  16. package/dist/{orchestrator-T2IPRZ7B.js → orchestrator-OE7WFEW6.js} +5 -4
  17. package/dist/package.json +3 -3
  18. package/dist/{processor-VKFEOK46.js → processor-GAOK7TPI.js} +2 -2
  19. package/dist/{provider-CDM4LQAC.js → provider-RLQMVV2Z.js} +7 -7
  20. package/dist/{serve-X3PKC27B.js → serve-IBJ3SN3Q.js} +9 -9
  21. package/dist/server/index.js +7 -7
  22. package/dist/{tools-4ODVFMW7.js → tools-CSV7G554.js} +4 -3
  23. package/dist/{vision-fallback-VXGCQKLA.js → vision-fallback-QJ26DCEF.js} +2 -2
  24. package/dist/web/assets/{index-DHP3d5Cl.js → index-BrZqZwpA.js} +56 -54
  25. package/dist/web/assets/{index-B9-lT3Kc.css → index-DF26vcqg.css} +1 -1
  26. package/dist/web/index.html +2 -2
  27. package/dist/web/sw.js +1 -1
  28. 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
+ ![Session](docs/screenshots/session.png)
9
+
10
+ *Providers — Local LLM backend configuration*
11
+ ![Providers](docs/screenshots/providers.png)
12
+
13
+ *Workflows — Contract-driven execution pipeline*
14
+ ![Workflows](docs/screenshots/workflows.png)
15
+
7
16
  ## Quick Start
8
17
 
9
18
  ```bash
10
- npx openfox
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
- npx openfox
29
+ openfox
20
30
 
21
31
  # Start on custom port
22
- npx openfox --port 8080
32
+ openfox --port 8080
23
33
 
24
34
  # Start without opening browser
25
- npx openfox --no-browser
26
-
27
- # Interactive configuration setup
28
- npx openfox init
35
+ openfox --no-browser
29
36
 
30
37
  # Show current configuration
31
- npx openfox config
38
+ openfox config
32
39
 
33
40
  # Manage LLM providers
34
- npx openfox provider add # Add new provider
35
- npx openfox provider list # List configured providers
36
- npx openfox provider use # Switch active provider
37
- npx openfox provider remove # Remove provider
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
+ ![Homepage](docs/screenshots/homepage.png)
77
+
78
+ *Project Selected — Active session with context stats*
79
+ ![Project Selected](docs/screenshots/project-selected.png)
80
+
81
+ *Stats — Prefill time, generation speed, token usage*
82
+ ![Stats](docs/screenshots/stats.png)
83
+
84
+ *Terminal — Integrated terminal for running commands*
85
+ ![Terminal](docs/screenshots/terminal.png)
86
+
87
+ *Notifications — Event log and system messages*
88
+ ![Notifications](docs/screenshots/notifications.png)
89
+
90
+ *Agents — Sub-agent management and execution*
91
+ ![Agents](docs/screenshots/agents.png)
92
+
93
+ *General Instructions — Global custom instructions*
94
+ ![General Instructions](docs/screenshots/general-instructions.png)
95
+
96
+ *Vision Fallback — Image processing configuration*
97
+ ![Vision Fallback](docs/screenshots/vision-fallback.png)
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-HZP2V5Z6.js";
5
+ } from "./chunk-4O3C2JMB.js";
6
6
  import "./chunk-NBU6KIOD.js";
7
7
  import "./chunk-574HZVLE.js";
8
- import "./chunk-XYD5JXRM.js";
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-U75EINMB.js.map
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-AU33PQAB.js";
14
- import "./chunk-HZP2V5Z6.js";
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-XYD5JXRM.js";
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-U75EINMB.js");
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-JEMPI5UF.js.map
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-XYD5JXRM.js";
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-4ODVFMW7.js");
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-HZP2V5Z6.js.map
4479
+ //# sourceMappingURL=chunk-4O3C2JMB.js.map
@@ -13,7 +13,7 @@ import {
13
13
  getToolRegistryForAgent,
14
14
  loadAllAgentsDefault,
15
15
  runTopLevelAgentLoop
16
- } from "./chunk-HZP2V5Z6.js";
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-AU33PQAB.js.map
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-SWDAJMQ3.js");
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-6NPMZFMP.js.map
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-XYD5JXRM.js.map
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-SWDAJMQ3.js");
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-SWDAJMQ3.js");
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-CDM4LQAC.js");
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-SWDAJMQ3.js");
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-X3PKC27B.js");
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-HWOYZ245.js.map
170
+ //# sourceMappingURL=chunk-FTJPNCAV.js.map