openfox 0.2.4 → 1.0.1

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 (65) hide show
  1. package/dist/agent-defaults/builder.agent.md +3 -7
  2. package/dist/agent-defaults/code-reviewer.agent.md +1 -2
  3. package/dist/agent-defaults/explorer.agent.md +22 -0
  4. package/dist/agent-defaults/planner.agent.md +2 -9
  5. package/dist/agent-defaults/verifier.agent.md +4 -5
  6. package/dist/ask-3RK5YJZE.js +19 -0
  7. package/dist/auto-compaction-WRS52ERL.js +23 -0
  8. package/dist/{branch.api-WDHKZJS6.js → branch.api-XADFZZAA.js} +2 -2
  9. package/dist/chat-handler-226J7XYE.js +201 -0
  10. package/dist/chunk-22CTURMH.js +128 -0
  11. package/dist/chunk-2KSCZSXQ.js +680 -0
  12. package/dist/{chunk-4Z2OZ6NX.js → chunk-3EHGGBWE.js} +29 -2
  13. package/dist/{chunk-GZ7ZVJIW.js → chunk-3UQACISJ.js} +159 -49
  14. package/dist/{chunk-AF7XS4OI.js → chunk-5YQAXUKO.js} +4 -1
  15. package/dist/{chunk-MTX5Y3V3.js → chunk-7IOZFJBW.js} +2 -2
  16. package/dist/{chunk-FUUYYDVG.js → chunk-ARKA56ZM.js} +2842 -4508
  17. package/dist/chunk-BU2ZYOEA.js +1067 -0
  18. package/dist/{chunk-O4W4555H.js → chunk-HGMG5F72.js} +1353 -1134
  19. package/dist/chunk-M2C5GEQR.js +137 -0
  20. package/dist/chunk-OWDPT3M6.js +314 -0
  21. package/dist/{chunk-U62ZECSQ.js → chunk-PNBH3RAX.js} +2 -2
  22. package/dist/chunk-QDEKU5RL.js +75 -0
  23. package/dist/chunk-QYP5HQV4.js +438 -0
  24. package/dist/chunk-S4QKTRGJ.js +343 -0
  25. package/dist/{chunk-ARFK3RZW.js → chunk-TPT6HP4H.js} +1 -1
  26. package/dist/chunk-TVQOONDR.js +75 -0
  27. package/dist/{chunk-5ZUU23XF.js → chunk-U6BUT37A.js} +286 -33
  28. package/dist/{chunk-S5NRIWEU.js → chunk-VUQPJFMQ.js} +12 -12
  29. package/dist/{chunk-26NRL3HX.js → chunk-XFXOSPYH.js} +3 -2
  30. package/dist/{chunk-N2XYX4ZA.js → chunk-XKFPU2FA.js} +13 -2
  31. package/dist/cli/dev.js +4 -3
  32. package/dist/cli/index.js +4 -3
  33. package/dist/{config-GIXXE4VK.js → config-GIFCEJDU.js} +11 -6
  34. package/dist/events-G6CKHDNZ.js +114 -0
  35. package/dist/folding-O52L65VN.js +37 -0
  36. package/dist/{init-2EJ5AC7Z.js → init-MKTUIGZU.js} +46 -13
  37. package/dist/orchestrator-4CBESUGB.js +39 -0
  38. package/dist/package.json +9 -2
  39. package/dist/{paths-4BPXWB2W.js → paths-MM76AWYB.js} +2 -2
  40. package/dist/processor-LAKHPIG3.js +236 -0
  41. package/dist/{project-creator-CWPKRIKI.js → project-creator-KAQXMZCT.js} +9 -8
  42. package/dist/projects-GSMMEVSO.js +19 -0
  43. package/dist/{protocol-BFFz3WM0.d.ts → protocol-BZ6OIASP.d.ts} +71 -50
  44. package/dist/protocol-WQENDK72.js +88 -0
  45. package/dist/{provider-QEVVNYOX.js → provider-4KTWU6IV.js} +41 -9
  46. package/dist/runtime-config-2XJJIMSC.js +9 -0
  47. package/dist/{serve-RYEBLJVN.js → serve-5NHW3X5B.js} +50 -18
  48. package/dist/server/index.d.ts +81 -27
  49. package/dist/server/index.js +19 -11
  50. package/dist/{settings-D5O3TMLD.js → settings-NCLN4JDZ.js} +4 -4
  51. package/dist/shared/index.d.ts +2 -2
  52. package/dist/shared/index.js +1 -1
  53. package/dist/tools-WOZVXNEQ.js +48 -0
  54. package/dist/vision-fallback-63VPBSEN.js +22 -0
  55. package/dist/web/assets/{index-DHmZmhnR.css → index-BsaaC0X0.css} +32 -1
  56. package/dist/web/assets/index-CvO7QkGh.js +141 -0
  57. package/dist/web/index.html +2 -2
  58. package/dist/web/sounds/typing.mp3 +0 -0
  59. package/dist/workflow-defaults/default.workflow.json +1 -1
  60. package/package.json +9 -2
  61. package/dist/agent-defaults/debugger.agent.md +0 -21
  62. package/dist/agent-defaults/test-generator.agent.md +0 -22
  63. package/dist/chunk-L4XDA3V7.js +0 -218
  64. package/dist/tools-QMIIDJTV.js +0 -48
  65. package/dist/web/assets/index-CAD7Iv_d.js +0 -122
@@ -1,6 +1,10 @@
1
+ import {
2
+ describeImageFromDataUrl,
3
+ ensureVisionFallbackConfigLoaded
4
+ } from "./chunk-M2C5GEQR.js";
1
5
  import {
2
6
  logger
3
- } from "./chunk-U62ZECSQ.js";
7
+ } from "./chunk-PNBH3RAX.js";
4
8
 
5
9
  // src/server/llm/backend.ts
6
10
  var BACKEND_CAPABILITIES = {
@@ -288,7 +292,8 @@ var DEFAULT_PROFILE = {
288
292
  topP: 0.9,
289
293
  supportsReasoning: false,
290
294
  reasoningAsContent: false,
291
- defaultMaxTokens: 4096
295
+ defaultMaxTokens: 4096,
296
+ supportsVision: true
292
297
  };
293
298
  var MOCK_PROFILE = {
294
299
  name: "mock",
@@ -296,7 +301,8 @@ var MOCK_PROFILE = {
296
301
  topP: 0.9,
297
302
  supportsReasoning: false,
298
303
  reasoningAsContent: false,
299
- defaultMaxTokens: 1024
304
+ defaultMaxTokens: 1024,
305
+ supportsVision: false
300
306
  };
301
307
  var MODEL_PROFILES = [
302
308
  {
@@ -307,7 +313,8 @@ var MODEL_PROFILES = [
307
313
  topP: 0.9,
308
314
  supportsReasoning: false,
309
315
  reasoningAsContent: false,
310
- defaultMaxTokens: 4096
316
+ defaultMaxTokens: 16384,
317
+ supportsVision: false
311
318
  }
312
319
  },
313
320
  {
@@ -321,7 +328,8 @@ var MODEL_PROFILES = [
321
328
  // "This model supports only non-thinking mode and does not generate <think></think> blocks"
322
329
  supportsReasoning: false,
323
330
  reasoningAsContent: false,
324
- defaultMaxTokens: 8192
331
+ defaultMaxTokens: 16384,
332
+ supportsVision: false
325
333
  }
326
334
  },
327
335
  {
@@ -332,7 +340,20 @@ var MODEL_PROFILES = [
332
340
  topP: 0.9,
333
341
  supportsReasoning: true,
334
342
  reasoningAsContent: false,
335
- defaultMaxTokens: 4096
343
+ defaultMaxTokens: 16384,
344
+ supportsVision: false
345
+ }
346
+ },
347
+ {
348
+ pattern: "qwen3-vl",
349
+ profile: {
350
+ name: "Qwen3-VL",
351
+ temperature: 0.7,
352
+ topP: 0.9,
353
+ supportsReasoning: true,
354
+ reasoningAsContent: false,
355
+ defaultMaxTokens: 16384,
356
+ supportsVision: true
336
357
  }
337
358
  },
338
359
  {
@@ -343,7 +364,72 @@ var MODEL_PROFILES = [
343
364
  topP: 0.95,
344
365
  supportsReasoning: true,
345
366
  reasoningAsContent: false,
346
- defaultMaxTokens: 4096
367
+ defaultMaxTokens: 16384,
368
+ supportsVision: false
369
+ }
370
+ },
371
+ {
372
+ pattern: "minimax-m2.5",
373
+ profile: {
374
+ name: "MiniMax-M2.5",
375
+ temperature: 1,
376
+ topP: 0.95,
377
+ topK: 40,
378
+ supportsReasoning: true,
379
+ reasoningAsContent: false,
380
+ defaultMaxTokens: 16384,
381
+ supportsVision: false
382
+ }
383
+ },
384
+ {
385
+ pattern: "minimax-m2.7",
386
+ profile: {
387
+ name: "MiniMax-M2.7",
388
+ temperature: 1,
389
+ topP: 0.95,
390
+ topK: 40,
391
+ supportsReasoning: true,
392
+ reasoningAsContent: false,
393
+ defaultMaxTokens: 16384,
394
+ supportsVision: false
395
+ }
396
+ },
397
+ {
398
+ pattern: "minimax",
399
+ profile: {
400
+ name: "MiniMax",
401
+ temperature: 1,
402
+ topP: 0.95,
403
+ topK: 40,
404
+ supportsReasoning: true,
405
+ reasoningAsContent: false,
406
+ defaultMaxTokens: 16384,
407
+ supportsVision: false
408
+ }
409
+ },
410
+ {
411
+ pattern: "minimax-m3",
412
+ profile: {
413
+ name: "MiniMax-M3",
414
+ temperature: 1,
415
+ topP: 0.95,
416
+ topK: 40,
417
+ supportsReasoning: true,
418
+ reasoningAsContent: false,
419
+ defaultMaxTokens: 16384,
420
+ supportsVision: true
421
+ }
422
+ },
423
+ {
424
+ pattern: "llava",
425
+ profile: {
426
+ name: "LLaVA",
427
+ temperature: 0.7,
428
+ topP: 0.9,
429
+ supportsReasoning: false,
430
+ reasoningAsContent: false,
431
+ defaultMaxTokens: 16384,
432
+ supportsVision: true
347
433
  }
348
434
  },
349
435
  {
@@ -354,7 +440,8 @@ var MODEL_PROFILES = [
354
440
  topP: 0.9,
355
441
  supportsReasoning: false,
356
442
  reasoningAsContent: false,
357
- defaultMaxTokens: 4096
443
+ defaultMaxTokens: 16384,
444
+ supportsVision: false
358
445
  }
359
446
  },
360
447
  {
@@ -365,7 +452,20 @@ var MODEL_PROFILES = [
365
452
  topP: 0.9,
366
453
  supportsReasoning: true,
367
454
  reasoningAsContent: false,
368
- defaultMaxTokens: 4096
455
+ defaultMaxTokens: 16384,
456
+ supportsVision: false
457
+ }
458
+ },
459
+ {
460
+ pattern: "gemma-4",
461
+ profile: {
462
+ name: "Gemma 4",
463
+ temperature: 0.7,
464
+ topP: 0.9,
465
+ supportsReasoning: true,
466
+ reasoningAsContent: false,
467
+ defaultMaxTokens: 16384,
468
+ supportsVision: true
369
469
  }
370
470
  }
371
471
  ];
@@ -383,9 +483,50 @@ function getModelProfile(modelName) {
383
483
  }
384
484
 
385
485
  // src/server/llm/client-pure.ts
386
- function convertMessages(messages) {
486
+ function convertAttachmentSync(attachment, modelSupportsVision) {
487
+ if (modelSupportsVision) {
488
+ return {
489
+ type: "image_url",
490
+ image_url: { url: attachment.data }
491
+ };
492
+ }
493
+ return {
494
+ type: "text",
495
+ text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
496
+ };
497
+ }
498
+ async function convertAttachmentWithFallback(attachment, options) {
499
+ logger.debug("[VisionFallback] convertAttachmentWithFallback called", { filename: attachment.filename, id: attachment.id, hasCallbacks: !!options.onVisionFallbackStart });
500
+ if (options.modelSupportsVision) {
501
+ logger.debug("[VisionFallback] Model supports vision - passing image directly");
502
+ return {
503
+ type: "image_url",
504
+ image_url: { url: attachment.data }
505
+ };
506
+ }
507
+ if (!options.visionFallbackEnabled) {
508
+ logger.debug("[VisionFallback] Fallback disabled - returning placeholder");
509
+ return {
510
+ type: "text",
511
+ text: `[Image: ${attachment.filename || "image"}] (vision not supported)`
512
+ };
513
+ }
514
+ const attachmentId = attachment.id ?? crypto.randomUUID();
515
+ const filename = attachment.filename;
516
+ logger.debug("[VisionFallback] Starting delegation for:", { attachmentId, filename });
517
+ options.onVisionFallbackStart?.(attachmentId, filename);
518
+ const context = filename ? `File: ${filename}` : void 0;
519
+ const description = await describeImageFromDataUrl(attachment.data, context ? { context } : {});
520
+ logger.debug("[VisionFallback] Delegation complete:", { attachmentId, descriptionLength: description.length });
521
+ options.onVisionFallbackDone?.(attachmentId, description);
522
+ return {
523
+ type: "text",
524
+ text: `[Image: ${attachment.filename || "image"}] ${description}`
525
+ };
526
+ }
527
+ function convertMessages(messages, options) {
387
528
  const filtered = messages.filter((msg) => {
388
- return !(msg.role === "assistant" && !msg.content?.trim() && !msg.toolCalls?.length);
529
+ return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
389
530
  });
390
531
  return filtered.map((msg) => {
391
532
  if (msg.role === "tool") {
@@ -395,10 +536,7 @@ function convertMessages(messages) {
395
536
  content.push({ type: "text", text: msg.content });
396
537
  }
397
538
  for (const attachment of msg.attachments) {
398
- content.push({
399
- type: "image_url",
400
- image_url: { url: attachment.data }
401
- });
539
+ content.push(convertAttachmentSync(attachment, options.modelSupportsVision));
402
540
  }
403
541
  return {
404
542
  role: "tool",
@@ -432,13 +570,7 @@ function convertMessages(messages) {
432
570
  content.push({ type: "text", text: msg.content });
433
571
  }
434
572
  for (const attachment of msg.attachments) {
435
- content.push({
436
- type: "image_url",
437
- image_url: {
438
- url: attachment.data
439
- // base64 data URL
440
- }
441
- });
573
+ content.push(convertAttachmentSync(attachment, options.modelSupportsVision));
442
574
  }
443
575
  return {
444
576
  role: "user",
@@ -451,6 +583,80 @@ function convertMessages(messages) {
451
583
  };
452
584
  });
453
585
  }
586
+ async function convertMessagesWithFallback(messages, options) {
587
+ logger.debug("[VisionFallback] convertMessagesWithFallback called", { messageCount: messages.length });
588
+ const filtered = messages.filter((msg) => {
589
+ return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
590
+ });
591
+ const converted = [];
592
+ for (const msg of filtered) {
593
+ if (msg.role === "tool") {
594
+ if (msg.attachments && msg.attachments.length > 0) {
595
+ const content = [];
596
+ if (msg.content?.trim()) {
597
+ content.push({ type: "text", text: msg.content });
598
+ }
599
+ for (const attachment of msg.attachments) {
600
+ const convertedContent = await convertAttachmentWithFallback(
601
+ { data: attachment.data, filename: attachment.filename, id: attachment.id },
602
+ options
603
+ );
604
+ content.push(convertedContent);
605
+ }
606
+ converted.push({
607
+ role: "tool",
608
+ content,
609
+ tool_call_id: msg.toolCallId
610
+ });
611
+ } else {
612
+ converted.push({
613
+ role: "tool",
614
+ content: msg.content,
615
+ tool_call_id: msg.toolCallId
616
+ });
617
+ }
618
+ continue;
619
+ }
620
+ if (msg.role === "assistant" && msg.toolCalls?.length) {
621
+ converted.push({
622
+ role: "assistant",
623
+ content: msg.content || null,
624
+ tool_calls: msg.toolCalls.map((toolCall) => ({
625
+ id: toolCall.id,
626
+ type: "function",
627
+ function: {
628
+ name: toolCall.name,
629
+ arguments: JSON.stringify(toolCall.arguments)
630
+ }
631
+ }))
632
+ });
633
+ continue;
634
+ }
635
+ if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
636
+ const content = [];
637
+ if (msg.content?.trim()) {
638
+ content.push({ type: "text", text: msg.content });
639
+ }
640
+ for (const attachment of msg.attachments) {
641
+ const convertedContent = await convertAttachmentWithFallback(
642
+ { data: attachment.data, filename: attachment.filename, id: attachment.id },
643
+ options
644
+ );
645
+ content.push(convertedContent);
646
+ }
647
+ converted.push({
648
+ role: "user",
649
+ content
650
+ });
651
+ continue;
652
+ }
653
+ converted.push({
654
+ role: msg.role,
655
+ content: msg.content
656
+ });
657
+ }
658
+ return converted;
659
+ }
454
660
  function convertTools(tools) {
455
661
  return tools.map((tool) => ({
456
662
  type: "function",
@@ -461,11 +667,33 @@ function convertTools(tools) {
461
667
  }
462
668
  }));
463
669
  }
464
- function buildNonStreamingCreateParams(input) {
465
- const { model, request, profile, capabilities, disableThinking } = input;
670
+ function needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) {
671
+ const hasAttachments = messages.some(
672
+ (msg) => msg.attachments && msg.attachments.length > 0 || msg.role === "tool" && msg.attachments && msg.attachments.length > 0
673
+ );
674
+ const result = hasAttachments && !modelSupportsVision && visionFallbackEnabled;
675
+ logger.debug("[VisionFallback] needsVisionFallback check", {
676
+ hasAttachments,
677
+ modelSupportsVision,
678
+ visionFallbackEnabled,
679
+ result
680
+ });
681
+ return result;
682
+ }
683
+ async function buildNonStreamingCreateParams(input) {
684
+ const { model, request, profile, capabilities, disableThinking, visionFallbackEnabled = false, onVisionFallbackStart, onVisionFallbackDone } = input;
685
+ const messages = request.messages;
686
+ const modelSupportsVision = profile.supportsVision ?? false;
687
+ const options = {
688
+ modelSupportsVision,
689
+ visionFallbackEnabled,
690
+ onVisionFallbackStart,
691
+ onVisionFallbackDone
692
+ };
693
+ const convertedMessages = needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) ? await convertMessagesWithFallback(messages, options) : convertMessages(messages, { modelSupportsVision, visionFallbackEnabled: false });
466
694
  const params = {
467
695
  model,
468
- messages: convertMessages(request.messages),
696
+ messages: convertedMessages,
469
697
  ...request.tools ? { tools: convertTools(request.tools) } : {},
470
698
  ...request.toolChoice ? { tool_choice: request.toolChoice } : {},
471
699
  temperature: request.temperature ?? profile.temperature,
@@ -483,11 +711,15 @@ function buildNonStreamingCreateParams(input) {
483
711
  }
484
712
  return params;
485
713
  }
486
- function buildStreamingCreateParams(input) {
487
- const { model, request, profile, capabilities, disableThinking } = input;
714
+ async function buildStreamingCreateParams(input) {
715
+ const { model, request, profile, capabilities, disableThinking, visionFallbackEnabled = false, onVisionFallbackStart, onVisionFallbackDone } = input;
716
+ const messages = request.messages;
717
+ const modelSupportsVision = profile.supportsVision ?? false;
718
+ const options = { modelSupportsVision, visionFallbackEnabled, onVisionFallbackStart, onVisionFallbackDone };
719
+ const convertedMessages = needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) ? await convertMessagesWithFallback(messages, options) : convertMessages(messages, { modelSupportsVision, visionFallbackEnabled: false });
488
720
  const params = {
489
721
  model,
490
- messages: convertMessages(request.messages),
722
+ messages: convertedMessages,
491
723
  ...request.tools ? { tools: convertTools(request.tools) } : {},
492
724
  ...request.toolChoice ? { tool_choice: request.toolChoice } : {},
493
725
  temperature: request.temperature ?? profile.temperature,
@@ -585,13 +817,23 @@ function createLLMClient(config, initialBackend = "unknown") {
585
817
  });
586
818
  try {
587
819
  const shouldDisableThinking = disableThinking || request.disableThinking === true;
588
- const createParams = buildNonStreamingCreateParams({
820
+ await ensureVisionFallbackConfigLoaded();
821
+ const { isVisionFallbackEnabled } = await import("./vision-fallback-63VPBSEN.js");
822
+ const paramsOptions = {
589
823
  model,
590
824
  request,
591
825
  profile,
592
826
  capabilities,
593
- disableThinking: shouldDisableThinking
594
- });
827
+ disableThinking: shouldDisableThinking,
828
+ visionFallbackEnabled: isVisionFallbackEnabled()
829
+ };
830
+ if (request.onVisionFallbackStart) {
831
+ paramsOptions.onVisionFallbackStart = request.onVisionFallbackStart;
832
+ }
833
+ if (request.onVisionFallbackDone) {
834
+ paramsOptions.onVisionFallbackDone = request.onVisionFallbackDone;
835
+ }
836
+ const createParams = await buildNonStreamingCreateParams(paramsOptions);
595
837
  const response = await openai.chat.completions.create(createParams, {
596
838
  signal: request.signal
597
839
  });
@@ -653,8 +895,19 @@ function createLLMClient(config, initialBackend = "unknown") {
653
895
  idleTimeout
654
896
  });
655
897
  try {
898
+ await ensureVisionFallbackConfigLoaded();
899
+ const { isVisionFallbackEnabled } = await import("./vision-fallback-63VPBSEN.js");
656
900
  const shouldDisableThinking = disableThinking || request.disableThinking === true;
657
- const createParams = buildStreamingCreateParams({ model, request, profile, capabilities, disableThinking: shouldDisableThinking });
901
+ const createParams = await buildStreamingCreateParams({
902
+ model,
903
+ request,
904
+ profile,
905
+ capabilities,
906
+ disableThinking: shouldDisableThinking,
907
+ visionFallbackEnabled: isVisionFallbackEnabled(),
908
+ onVisionFallbackStart: request.onVisionFallbackStart,
909
+ onVisionFallbackDone: request.onVisionFallbackDone
910
+ });
658
911
  const stream = await openai.chat.completions.create(createParams, {
659
912
  signal: request.signal
660
913
  });
@@ -858,4 +1111,4 @@ export {
858
1111
  getLlmStatus,
859
1112
  clearModelCache
860
1113
  };
861
- //# sourceMappingURL=chunk-5ZUU23XF.js.map
1114
+ //# sourceMappingURL=chunk-U6BUT37A.js.map
@@ -24,8 +24,8 @@ Options:
24
24
  `);
25
25
  }
26
26
  async function runConfig(mode) {
27
- const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-GIXXE4VK.js");
28
- const { getGlobalConfigPath } = await import("./paths-4BPXWB2W.js");
27
+ const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-GIFCEJDU.js");
28
+ const { getGlobalConfigPath } = await import("./paths-MM76AWYB.js");
29
29
  const config = await loadGlobalConfig(mode);
30
30
  const configPath = getGlobalConfigPath(mode);
31
31
  const activeProvider = getActiveProvider(config);
@@ -75,8 +75,8 @@ async function runCli(options) {
75
75
  const [command] = positionals;
76
76
  switch (command) {
77
77
  case "init": {
78
- const { runInitWithSelect } = await import("./init-2EJ5AC7Z.js");
79
- const { loadGlobalConfig, getActiveProvider } = await import("./config-GIXXE4VK.js");
78
+ const { runInitWithSelect } = await import("./init-MKTUIGZU.js");
79
+ const { loadGlobalConfig, getActiveProvider } = await import("./config-GIFCEJDU.js");
80
80
  const config = await loadGlobalConfig(mode);
81
81
  const activeProvider = getActiveProvider(config);
82
82
  if (activeProvider) {
@@ -91,17 +91,17 @@ async function runCli(options) {
91
91
  break;
92
92
  }
93
93
  case "provider": {
94
- const { runProviderCommand } = await import("./provider-QEVVNYOX.js");
94
+ const { runProviderCommand } = await import("./provider-4KTWU6IV.js");
95
95
  const [, subcommand] = positionals;
96
96
  await runProviderCommand(mode, subcommand);
97
97
  break;
98
98
  }
99
99
  default: {
100
- const { configFileExists } = await import("./config-GIXXE4VK.js");
100
+ const { configFileExists } = await import("./config-GIFCEJDU.js");
101
101
  const configExists = await configFileExists(mode);
102
102
  if (!configExists) {
103
103
  console.log("Welcome to OpenFox!\n");
104
- const { trySmartDefaults, saveGlobalConfig, addProvider } = await import("./config-GIXXE4VK.js");
104
+ const { trySmartDefaults, saveGlobalConfig, addProvider } = await import("./config-GIFCEJDU.js");
105
105
  const detected = await trySmartDefaults(mode);
106
106
  if (detected) {
107
107
  console.log(`\u2713 Found ${detected.backend} (${detected.model}) at ${detected.url}`);
@@ -116,20 +116,20 @@ async function runCli(options) {
116
116
  name: "Default",
117
117
  url: detected.url,
118
118
  backend: detected.backend,
119
- maxContext: 2e5,
119
+ models: [],
120
120
  isActive: true
121
121
  });
122
- const { setDefaultModelSelection } = await import("./config-GIXXE4VK.js");
122
+ const { setDefaultModelSelection } = await import("./config-GIFCEJDU.js");
123
123
  const finalConfig = setDefaultModelSelection(configWithProvider, configWithProvider.providers[0].id, detected.model);
124
124
  await saveGlobalConfig(mode, finalConfig);
125
125
  console.log("Configuration saved!\n");
126
126
  } else {
127
127
  console.log("\u2717 No LLM server detected\n");
128
- const { runInitWithSelect } = await import("./init-2EJ5AC7Z.js");
128
+ const { runInitWithSelect } = await import("./init-MKTUIGZU.js");
129
129
  await runInitWithSelect(mode);
130
130
  }
131
131
  }
132
- const { runServe } = await import("./serve-RYEBLJVN.js");
132
+ const { runServe } = await import("./serve-5NHW3X5B.js");
133
133
  await runServe({
134
134
  mode,
135
135
  port: values.port ? parseInt(values.port) : void 0,
@@ -142,4 +142,4 @@ async function runCli(options) {
142
142
  export {
143
143
  runCli
144
144
  };
145
- //# sourceMappingURL=chunk-S5NRIWEU.js.map
145
+ //# sourceMappingURL=chunk-VUQPJFMQ.js.map
@@ -95,9 +95,10 @@ async function* streamWithSegments(client, request) {
95
95
  const ttft = ((firstTokenTime ?? endTime) - startTime) / 1e3;
96
96
  const completionTime = (endTime - (firstTokenTime ?? startTime)) / 1e3;
97
97
  const { promptTokens, completionTokens } = response.usage;
98
+ const effectiveThinkingContent = thinkingContent || content === "" && response.reasoning_content || "";
98
99
  return {
99
100
  content,
100
- thinkingContent,
101
+ thinkingContent: effectiveThinkingContent,
101
102
  toolCalls,
102
103
  response,
103
104
  segments,
@@ -113,4 +114,4 @@ async function* streamWithSegments(client, request) {
113
114
  export {
114
115
  streamWithSegments
115
116
  };
116
- //# sourceMappingURL=chunk-26NRL3HX.js.map
117
+ //# sourceMappingURL=chunk-XFXOSPYH.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./chunk-4Z2OZ6NX.js";
3
+ } from "./chunk-3EHGGBWE.js";
4
4
 
5
5
  // src/server/db/projects.ts
6
6
  function createProject(name, workdir) {
@@ -29,6 +29,16 @@ function getProject(id) {
29
29
  }
30
30
  return rowToProject(row);
31
31
  }
32
+ function getProjectByWorkdir(workdir) {
33
+ const db = getDatabase();
34
+ const row = db.prepare(`
35
+ SELECT * FROM projects WHERE workdir = ?
36
+ `).get(workdir);
37
+ if (!row) {
38
+ return null;
39
+ }
40
+ return rowToProject(row);
41
+ }
32
42
  function listProjects() {
33
43
  const db = getDatabase();
34
44
  const rows = db.prepare(`
@@ -76,8 +86,9 @@ function rowToProject(row) {
76
86
  export {
77
87
  createProject,
78
88
  getProject,
89
+ getProjectByWorkdir,
79
90
  listProjects,
80
91
  updateProject,
81
92
  deleteProject
82
93
  };
83
- //# sourceMappingURL=chunk-N2XYX4ZA.js.map
94
+ //# sourceMappingURL=chunk-XKFPU2FA.js.map
package/dist/cli/dev.js CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-S5NRIWEU.js";
4
+ } from "../chunk-VUQPJFMQ.js";
5
5
  import {
6
6
  logger
7
- } from "../chunk-U62ZECSQ.js";
7
+ } from "../chunk-PNBH3RAX.js";
8
8
 
9
9
  // src/cli/dev.ts
10
- runCli({ mode: "development" }).catch((error) => {
10
+ var mode = process.env["OPENFOX_MODE"] ?? "development";
11
+ runCli({ mode }).catch((error) => {
11
12
  logger.error("CLI fatal error", { error: error instanceof Error ? error.message : String(error) });
12
13
  process.exit(1);
13
14
  });
package/dist/cli/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-S5NRIWEU.js";
4
+ } from "../chunk-VUQPJFMQ.js";
5
5
  import {
6
6
  logger
7
- } from "../chunk-U62ZECSQ.js";
7
+ } from "../chunk-PNBH3RAX.js";
8
8
 
9
9
  // src/cli/index.ts
10
- runCli({ mode: "production" }).catch((error) => {
10
+ var mode = process.env["OPENFOX_MODE"] ?? "production";
11
+ runCli({ mode }).catch((error) => {
11
12
  logger.error("CLI fatal error", { error: error instanceof Error ? error.message : String(error) });
12
13
  process.exit(1);
13
14
  });
@@ -4,6 +4,8 @@ import {
4
4
  configFileExists,
5
5
  getActiveProvider,
6
6
  getDefaultModel,
7
+ getDefaultVisionFallback,
8
+ getVisionFallback,
7
9
  loadGlobalConfig,
8
10
  mergeConfigs,
9
11
  migrateConfig,
@@ -11,17 +13,20 @@ import {
11
13
  saveGlobalConfig,
12
14
  setDefaultModelSelection,
13
15
  trySmartDefaults
14
- } from "./chunk-GZ7ZVJIW.js";
15
- import "./chunk-5ZUU23XF.js";
16
- import "./chunk-26NRL3HX.js";
17
- import "./chunk-U62ZECSQ.js";
18
- import "./chunk-AF7XS4OI.js";
16
+ } from "./chunk-3UQACISJ.js";
17
+ import "./chunk-U6BUT37A.js";
18
+ import "./chunk-XFXOSPYH.js";
19
+ import "./chunk-5YQAXUKO.js";
20
+ import "./chunk-M2C5GEQR.js";
21
+ import "./chunk-PNBH3RAX.js";
19
22
  export {
20
23
  activateProvider,
21
24
  addProvider,
22
25
  configFileExists,
23
26
  getActiveProvider,
24
27
  getDefaultModel,
28
+ getDefaultVisionFallback,
29
+ getVisionFallback,
25
30
  loadGlobalConfig,
26
31
  mergeConfigs,
27
32
  migrateConfig,
@@ -30,4 +35,4 @@ export {
30
35
  setDefaultModelSelection,
31
36
  trySmartDefaults
32
37
  };
33
- //# sourceMappingURL=config-GIXXE4VK.js.map
38
+ //# sourceMappingURL=config-GIFCEJDU.js.map