openfox 1.6.20 → 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 (35) hide show
  1. package/README.md +46 -13
  2. package/dist/{auto-compaction-NFLWKJAO.js → auto-compaction-7LK3QGPI.js} +4 -3
  3. package/dist/{chat-handler-2RVTVNPF.js → chat-handler-ZU74RXED.js} +6 -5
  4. package/dist/{chunk-KOBGCNUE.js → chunk-4O3C2JMB.js} +58 -14
  5. package/dist/{chunk-QY7BMXWT.js → chunk-B7E3BICY.js} +6 -2
  6. package/dist/{chunk-U3KMU3UE.js → chunk-BOEXJCOD.js} +2 -2
  7. package/dist/{chunk-IN5EP4ZB.js → chunk-CJNQGEYG.js} +2 -2
  8. package/dist/{chunk-OVLFEBRR.js → chunk-D4ZLSV6P.js} +133 -468
  9. package/dist/{chunk-LTPZ4GTW.js → chunk-FTJPNCAV.js} +6 -6
  10. package/dist/chunk-KSASIV4B.js +486 -0
  11. package/dist/{chunk-ZDNXCVW4.js → chunk-P6GUT2QQ.js} +11 -5
  12. package/dist/{chunk-KOUMYBYM.js → chunk-PYBB34ZK.js} +54 -3
  13. package/dist/{chunk-R7UAGXQW.js → chunk-YCQSAFAQ.js} +42 -24
  14. package/dist/cli/dev.js +1 -1
  15. package/dist/cli/index.js +1 -1
  16. package/dist/{config-67AX6CNS.js → config-ACVEHBKG.js} +5 -5
  17. package/dist/{orchestrator-ZICQ5NIZ.js → orchestrator-OE7WFEW6.js} +5 -4
  18. package/dist/package.json +3 -3
  19. package/dist/{processor-MPSYT534.js → processor-GAOK7TPI.js} +2 -2
  20. package/dist/{protocol-I7rn7Msg.d.ts → protocol-BYM6rZvW.d.ts} +12 -0
  21. package/dist/{provider-DKGBQHUS.js → provider-RLQMVV2Z.js} +9 -8
  22. package/dist/{serve-B5A52252.js → serve-IBJ3SN3Q.js} +10 -10
  23. package/dist/server/index.d.ts +24 -1
  24. package/dist/server/index.js +8 -8
  25. package/dist/shared/index.d.ts +2 -2
  26. package/dist/shared/index.js +1 -1
  27. package/dist/{tools-ERJ3QRQU.js → tools-CSV7G554.js} +4 -3
  28. package/dist/{vision-fallback-ADYRFFD4.js → vision-fallback-QJ26DCEF.js} +2 -2
  29. package/dist/web/assets/index-BrZqZwpA.js +153 -0
  30. package/dist/web/assets/{index-vBklayFL.css → index-DF26vcqg.css} +1 -1
  31. package/dist/web/index.html +2 -2
  32. package/dist/web/sw.js +1 -1
  33. package/package.json +3 -3
  34. package/dist/chunk-55N6FAAZ.js +0 -117
  35. package/dist/web/assets/index-vOba1XKB.js +0 -151
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-KOBGCNUE.js";
5
+ } from "./chunk-4O3C2JMB.js";
6
6
  import "./chunk-NBU6KIOD.js";
7
7
  import "./chunk-574HZVLE.js";
8
- import "./chunk-55N6FAAZ.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-NFLWKJAO.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-U3KMU3UE.js";
14
- import "./chunk-KOBGCNUE.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-55N6FAAZ.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-NFLWKJAO.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-2RVTVNPF.js.map
174
+ //# sourceMappingURL=chat-handler-ZU74RXED.js.map
@@ -12,8 +12,11 @@ import {
12
12
  getSessionProcessCount
13
13
  } from "./chunk-574HZVLE.js";
14
14
  import {
15
+ buildModelParams,
16
+ getBackendCapabilities,
17
+ getModelProfile,
15
18
  streamWithSegments
16
- } from "./chunk-55N6FAAZ.js";
19
+ } from "./chunk-D4ZLSV6P.js";
17
20
  import {
18
21
  getContextMessages,
19
22
  getCurrentContextWindowId,
@@ -515,7 +518,7 @@ function computeAggregatedStats(input) {
515
518
  }
516
519
 
517
520
  // src/server/chat/stream-pure.ts
518
- function createEmptyStreamResult(aborted, xmlFormatError) {
521
+ function createEmptyStreamResult(aborted, xmlFormatError, modelParams) {
519
522
  return {
520
523
  content: "",
521
524
  toolCalls: [],
@@ -523,12 +526,38 @@ function createEmptyStreamResult(aborted, xmlFormatError) {
523
526
  usage: { promptTokens: 0, completionTokens: 0 },
524
527
  timing: { ttft: 0, completionTime: 0, tps: 0, prefillTps: 0 },
525
528
  aborted,
526
- xmlFormatError
529
+ xmlFormatError,
530
+ modelParams
527
531
  };
528
532
  }
529
533
  async function* streamLLMPure(options) {
530
534
  const { messageId, systemPrompt, llmClient, messages, tools, toolChoice, signal, disableThinking, onVisionFallbackStart, onVisionFallbackDone } = options;
531
535
  const llmMessages = [{ role: "system", content: systemPrompt }, ...messages];
536
+ const profile = getModelProfile(llmClient.getModel());
537
+ const backend = getBackendCapabilities(llmClient.getBackend());
538
+ const userTemp = options.modelSettings?.temperature;
539
+ const userTopP = options.modelSettings?.topP;
540
+ const userTopK = options.modelSettings?.topK;
541
+ const userMaxTokens = options.modelSettings?.maxTokens;
542
+ const temperature = userTemp ?? profile.temperature;
543
+ const maxTokens = userMaxTokens ?? profile.defaultMaxTokens;
544
+ const topP = userTopP ?? profile.topP;
545
+ const topK = userTopK ?? (backend.supportsTopK ? profile.topK : void 0);
546
+ const modelParams = buildModelParams({ temperature, topP, topK, maxTokens });
547
+ logger.debug("LLM request settings", {
548
+ model: llmClient.getModel(),
549
+ profile: profile.name,
550
+ temperature,
551
+ maxTokens,
552
+ topP,
553
+ topK,
554
+ userConfigured: {
555
+ temperature: userTemp !== void 0 ? `user:${userTemp}` : "default",
556
+ topP: userTopP !== void 0 ? `user:${userTopP}` : "default",
557
+ topK: userTopK !== void 0 ? `user:${userTopK}` : "default",
558
+ maxTokens: userMaxTokens !== void 0 ? `user:${userMaxTokens}` : "default"
559
+ }
560
+ });
532
561
  const stream = buildStreamRequest(llmClient, {
533
562
  messages: llmMessages,
534
563
  tools,
@@ -636,7 +665,7 @@ async function* streamLLMPure(options) {
636
665
  }
637
666
  }
638
667
  if (!result) {
639
- return createEmptyStreamResult(aborted, xmlFormatError);
668
+ return createEmptyStreamResult(aborted, xmlFormatError, modelParams);
640
669
  }
641
670
  const baseResult = {
642
671
  content: result.content,
@@ -648,7 +677,8 @@ async function* streamLLMPure(options) {
648
677
  },
649
678
  timing: result.timing,
650
679
  aborted,
651
- xmlFormatError
680
+ xmlFormatError,
681
+ modelParams
652
682
  };
653
683
  if (result.thinkingContent) {
654
684
  baseResult.thinkingContent = result.thinkingContent;
@@ -666,16 +696,20 @@ var TurnMetrics = class {
666
696
  totalToolTime = 0;
667
697
  // seconds
668
698
  llmCalls = [];
699
+ modelParams = {};
669
700
  constructor() {
670
701
  this.startTime = performance.now();
671
702
  }
672
703
  /** Add metrics from an LLM call */
673
- addLLMCall(timing, promptTokens, completionTokens) {
704
+ addLLMCall(timing, promptTokens, completionTokens, modelParams) {
674
705
  const callIndex = this.llmCalls.length + 1;
675
706
  this.totalPrefillTokens += promptTokens;
676
707
  this.totalPrefillTime += timing.ttft;
677
708
  this.totalGenTokens += completionTokens;
678
709
  this.totalGenTime += timing.completionTime;
710
+ if (modelParams) {
711
+ this.modelParams = modelParams;
712
+ }
679
713
  this.llmCalls = [
680
714
  ...this.llmCalls,
681
715
  {
@@ -687,10 +721,18 @@ var TurnMetrics = class {
687
721
  prefillSpeed: timing.ttft > 0 ? Math.round(promptTokens / timing.ttft * 10) / 10 : 0,
688
722
  generationSpeed: timing.completionTime > 0 ? Math.round(completionTokens / timing.completionTime * 10) / 10 : 0,
689
723
  totalTime: Math.round((timing.ttft + timing.completionTime) * 10) / 10,
690
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
724
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
725
+ ...this.modelParams.temperature !== void 0 && { temperature: this.modelParams.temperature },
726
+ ...this.modelParams.topP !== void 0 && { topP: this.modelParams.topP },
727
+ ...this.modelParams.topK !== void 0 && { topK: this.modelParams.topK },
728
+ ...this.modelParams.maxTokens !== void 0 && { maxTokens: this.modelParams.maxTokens }
691
729
  }
692
730
  ];
693
731
  }
732
+ /** Set model parameters for tracking */
733
+ setModelParams(params) {
734
+ this.modelParams = params;
735
+ }
694
736
  /** Add tool execution time (in milliseconds) */
695
737
  addToolTime(durationMs) {
696
738
  this.totalToolTime += durationMs / 1e3;
@@ -802,7 +844,7 @@ async function consumeStreamWithToolLoop(options) {
802
844
  let iterations = 0;
803
845
  for (; ; ) {
804
846
  if (signal?.aborted) {
805
- return createEmptyStreamResult(true, false);
847
+ return createEmptyStreamResult(true, false, {});
806
848
  }
807
849
  if (++iterations > MAX_TOOL_LOOP_ITERATIONS) {
808
850
  throw new Error("Max tool loop iterations exceeded during compaction");
@@ -826,7 +868,7 @@ async function consumeStreamWithToolLoop(options) {
826
868
  currentMessages = [...currentMessages, correctionMsg];
827
869
  continue;
828
870
  }
829
- turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens);
871
+ turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
830
872
  if (result.toolCalls.length > 0) {
831
873
  const stats = turnMetrics.buildStats(statsIdentity, "compaction");
832
874
  onEvent(createMessageDoneEvent(messageId, {
@@ -2850,6 +2892,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
2850
2892
  });
2851
2893
  doOnMessage(createChatVisionFallbackMessage({ type: "done", messageId: assistantMsgId, attachmentId, description }));
2852
2894
  };
2895
+ const modelSettings = sessionManager.getCurrentModelSettings();
2853
2896
  const streamGen = streamLLMPure({
2854
2897
  messageId: assistantMsgId,
2855
2898
  systemPrompt: assembledRequest.systemPrompt,
@@ -2859,7 +2902,8 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
2859
2902
  toolChoice: "auto",
2860
2903
  signal,
2861
2904
  onVisionFallbackStart,
2862
- onVisionFallbackDone
2905
+ onVisionFallbackDone,
2906
+ ...modelSettings && { modelSettings }
2863
2907
  });
2864
2908
  const result = await consumeStreamGenerator(streamGen, (event) => {
2865
2909
  eventStore.append(sessionId, event);
@@ -2881,7 +2925,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
2881
2925
  emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, assembledRequest.promptContext, eventStore);
2882
2926
  throw new Error("Aborted");
2883
2927
  }
2884
- turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens);
2928
+ turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
2885
2929
  sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens);
2886
2930
  if (result.toolCalls.length > 0) {
2887
2931
  eventStore.append(sessionId, createMessageDoneEvent(assistantMsgId, {
@@ -3135,7 +3179,7 @@ async function executeSubAgent(options) {
3135
3179
  eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "stopped", stats));
3136
3180
  throw new Error("Aborted");
3137
3181
  }
3138
- turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens);
3182
+ turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
3139
3183
  sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens, subAgentId);
3140
3184
  finalContent = result.content;
3141
3185
  customMessages.push({
@@ -3303,7 +3347,7 @@ var callSubAgentTool = {
3303
3347
  };
3304
3348
  }
3305
3349
  try {
3306
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-ERJ3QRQU.js");
3350
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-CSV7G554.js");
3307
3351
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3308
3352
  const turnMetrics = new TurnMetrics();
3309
3353
  const result = await executeSubAgent({
@@ -4432,4 +4476,4 @@ export {
4432
4476
  getToolRegistryForAgent,
4433
4477
  createToolRegistry
4434
4478
  };
4435
- //# sourceMappingURL=chunk-KOBGCNUE.js.map
4479
+ //# sourceMappingURL=chunk-4O3C2JMB.js.map
@@ -69,7 +69,11 @@ function buildSessionStats(messagesWithStats) {
69
69
  completionTime: call.completionTime,
70
70
  prefillSpeed: call.prefillSpeed,
71
71
  generationSpeed: call.generationSpeed,
72
- totalTime: call.totalTime
72
+ totalTime: call.totalTime,
73
+ ...call.temperature !== void 0 && { temperature: call.temperature },
74
+ ...call.topP !== void 0 && { topP: call.topP },
75
+ ...call.topK !== void 0 && { topK: call.topK },
76
+ ...call.maxTokens !== void 0 && { maxTokens: call.maxTokens }
73
77
  });
74
78
  }
75
79
  }
@@ -121,4 +125,4 @@ function computeSessionStats(messages) {
121
125
  export {
122
126
  computeSessionStats
123
127
  };
124
- //# sourceMappingURL=chunk-QY7BMXWT.js.map
128
+ //# sourceMappingURL=chunk-B7E3BICY.js.map
@@ -13,7 +13,7 @@ import {
13
13
  getToolRegistryForAgent,
14
14
  loadAllAgentsDefault,
15
15
  runTopLevelAgentLoop
16
- } from "./chunk-KOBGCNUE.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-U3KMU3UE.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-67AX6CNS.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-IN5EP4ZB.js.map
138
+ //# sourceMappingURL=chunk-CJNQGEYG.js.map