openfox 2.0.0-beta.4 → 2.0.0-beta.6

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 (50) hide show
  1. package/dist/{chat-handler-IUWEBZG7.js → chat-handler-27FY5TEH.js} +15 -29
  2. package/dist/{chunk-WBYS7AQN.js → chunk-3FFHHYWP.js} +178 -99
  3. package/dist/{chunk-HGAMIPFO.js → chunk-7FDY3EOH.js} +18 -176
  4. package/dist/{chunk-CEZNMLOO.js → chunk-7TTEGAO6.js} +12 -13
  5. package/dist/{chunk-FQLK5GL5.js → chunk-BVHFMAVN.js} +1 -1
  6. package/dist/{chunk-HW3U4XSZ.js → chunk-CDDMHSZF.js} +4 -4
  7. package/dist/{chunk-HHAJ3QF6.js → chunk-EMJGF3A7.js} +9 -24
  8. package/dist/{chunk-KEF4O3UM.js → chunk-FRCLNAE2.js} +2952 -3256
  9. package/dist/{chunk-RF2JGDSS.js → chunk-IGSZUXQP.js} +3 -3
  10. package/dist/{chunk-HLZV4S2I.js → chunk-NPHYEUYE.js} +127 -35
  11. package/dist/{chunk-NNEHZT3V.js → chunk-QUSUEN5R.js} +3 -3
  12. package/dist/{chunk-EYCCASW3.js → chunk-R3EK3ODJ.js} +6 -6
  13. package/dist/{chunk-7IKUIYFZ.js → chunk-RBJ25FIR.js} +135 -147
  14. package/dist/{chunk-PSJIT5LZ.js → chunk-RFNEDBVO.js} +4 -4
  15. package/dist/chunk-RI6GAMNP.js +13 -0
  16. package/dist/{chunk-26DZZZDC.js → chunk-XJEOP6XU.js} +5 -11
  17. package/dist/cli/dev.js +1 -1
  18. package/dist/cli/index.js +1 -1
  19. package/dist/compactor-TDNRM3A7.js +9 -0
  20. package/dist/{config-YU7NYZYG.js → config-VBBMTXJZ.js} +5 -6
  21. package/dist/{events-YO52472Q.js → events-PQ3KTI5H.js} +8 -8
  22. package/dist/{folding-K5L6M4WK.js → folding-CXORTBAU.js} +2 -3
  23. package/dist/{orchestrator-F75DNQKQ.js → orchestrator-QDCVUBCL.js} +18 -23
  24. package/dist/package.json +1 -1
  25. package/dist/{processor-FTEASNGS.js → processor-K4B7QRO2.js} +8 -10
  26. package/dist/{protocol-K62EPEGS.js → protocol-CN24IKQN.js} +3 -5
  27. package/dist/{protocol-BQ12Aw5J.d.ts → protocol-De-Pzgry.d.ts} +12 -38
  28. package/dist/{provider-HTJEB3ON.js → provider-NRWSSO55.js} +9 -10
  29. package/dist/{serve-CEQ2QMM5.js → serve-J6EM3G6N.js} +25 -27
  30. package/dist/server/index.d.ts +1 -6
  31. package/dist/server/index.js +15 -17
  32. package/dist/{settings-VRAOAPLA.js → settings-6XX56F3F.js} +2 -2
  33. package/dist/shared/index.d.ts +2 -2
  34. package/dist/shared/index.js +1 -1
  35. package/dist/{tools-OPEU2E5M.js → tools-GCANYSB7.js} +12 -15
  36. package/dist/web/assets/{index-bDyDeCAz.css → index-aa3jRAZ9.css} +2 -2
  37. package/dist/web/assets/index-ntDiC8b_.js +299 -0
  38. package/dist/web/index.html +2 -2
  39. package/dist/web/sw.js +1 -1
  40. package/dist/workflow-defaults/default.workflow.json +3 -3
  41. package/package.json +1 -1
  42. package/dist/auto-compaction-A3PIMGLF.js +0 -28
  43. package/dist/chunk-CGZHLM3K.js +0 -70
  44. package/dist/chunk-MCPID4EJ.js +0 -28
  45. package/dist/chunk-SZKEGZIB.js +0 -140
  46. package/dist/optimize-storage-2N6BY5KZ.js +0 -7
  47. package/dist/runtime-config-NPSPMRDA.js +0 -9
  48. package/dist/vision-fallback-3MIZZ6NQ.js +0 -22
  49. package/dist/web/assets/index-ZTEHxmVW.js +0 -317
  50. /package/dist/web/{workbox-7fc22fbe.js → workbox-8c29f6e4.js} +0 -0
@@ -2,11 +2,11 @@ import {
2
2
  clearModelCache,
3
3
  createLLMClient,
4
4
  detectModel
5
- } from "./chunk-HHAJ3QF6.js";
5
+ } from "./chunk-EMJGF3A7.js";
6
6
  import {
7
7
  detectBackend,
8
8
  getModelProfile
9
- } from "./chunk-HGAMIPFO.js";
9
+ } from "./chunk-7FDY3EOH.js";
10
10
  import {
11
11
  logger
12
12
  } from "./chunk-K44MW7JJ.js";
@@ -511,4 +511,4 @@ export {
511
511
  parseDefaultModelSelection,
512
512
  createProviderManager
513
513
  };
514
- //# sourceMappingURL=chunk-RF2JGDSS.js.map
514
+ //# sourceMappingURL=chunk-IGSZUXQP.js.map
@@ -1,6 +1,3 @@
1
- import {
2
- getDatabase
3
- } from "./chunk-FBGWG4N6.js";
4
1
  import {
5
2
  buildContextMessagesFromEventHistory,
6
3
  buildMessagesFromStoredEvents,
@@ -8,13 +5,10 @@ import {
8
5
  foldContextState,
9
6
  foldSessionState,
10
7
  spreadOptionalMessageFields
11
- } from "./chunk-26DZZZDC.js";
8
+ } from "./chunk-XJEOP6XU.js";
12
9
  import {
13
- stripPromptContextMessages
14
- } from "./chunk-MCPID4EJ.js";
15
- import {
16
- getRuntimeConfig
17
- } from "./chunk-CGZHLM3K.js";
10
+ getDatabase
11
+ } from "./chunk-FBGWG4N6.js";
18
12
  import {
19
13
  logger
20
14
  } from "./chunk-K44MW7JJ.js";
@@ -107,6 +101,18 @@ var EventStore = class {
107
101
  CREATE INDEX IF NOT EXISTS idx_events_session_type
108
102
  ON events(session_id, event_type)
109
103
  `);
104
+ this.db.exec(`
105
+ CREATE TABLE IF NOT EXISTS tombstones (
106
+ session_id TEXT NOT NULL,
107
+ seq INTEGER NOT NULL,
108
+ timestamp INTEGER NOT NULL,
109
+ UNIQUE(session_id, seq)
110
+ )
111
+ `);
112
+ this.db.exec(`
113
+ CREATE INDEX IF NOT EXISTS idx_tombstones_session_seq
114
+ ON tombstones(session_id, seq)
115
+ `);
110
116
  }
111
117
  // --------------------------------------------------------------------------
112
118
  // Append
@@ -185,10 +191,41 @@ var EventStore = class {
185
191
  * Get all events for a session, optionally starting from a specific seq
186
192
  */
187
193
  getEvents(sessionId, fromSeq) {
188
- const query = fromSeq !== void 0 ? `SELECT * FROM events WHERE session_id = ? AND seq >= ? ORDER BY seq` : `SELECT * FROM events WHERE session_id = ? ORDER BY seq`;
194
+ const query = fromSeq !== void 0 ? `SELECT e.* FROM events e
195
+ LEFT JOIN tombstones t ON e.session_id = t.session_id AND e.seq = t.seq
196
+ WHERE e.session_id = ? AND e.seq >= ? AND t.seq IS NULL
197
+ ORDER BY e.seq` : `SELECT e.* FROM events e
198
+ LEFT JOIN tombstones t ON e.session_id = t.session_id AND e.seq = t.seq
199
+ WHERE e.session_id = ? AND t.seq IS NULL
200
+ ORDER BY e.seq`;
189
201
  const rows = fromSeq !== void 0 ? this.db.prepare(query).all(sessionId, fromSeq) : this.db.prepare(query).all(sessionId);
190
202
  return rows.map((row) => this.rowToStoredEvent(row));
191
203
  }
204
+ /**
205
+ * Soft-delete (tombstone) events by sequence number.
206
+ * Tombstoned events are hidden from getEvents but remain in the database.
207
+ *
208
+ * @param sessionId - The session ID
209
+ * @param seqs - Array of sequence numbers to tombstone
210
+ * @returns The number of events tombstoned
211
+ */
212
+ tombstoneEvents(sessionId, seqs) {
213
+ if (seqs.length === 0) return 0;
214
+ const timestamp = Date.now();
215
+ const insert = this.db.prepare(
216
+ `INSERT OR IGNORE INTO tombstones (session_id, seq, timestamp)
217
+ VALUES (?, ?, ?)`
218
+ );
219
+ let count = 0;
220
+ const transaction = this.db.transaction(() => {
221
+ for (const seq of seqs) {
222
+ const result = insert.run(sessionId, seq, timestamp);
223
+ count += result.changes;
224
+ }
225
+ });
226
+ transaction();
227
+ return count;
228
+ }
192
229
  /**
193
230
  * Get the latest sequence number for a session
194
231
  */
@@ -377,13 +414,10 @@ var EventStore = class {
377
414
  return result.changes;
378
415
  }
379
416
  /**
380
- * One-time storage optimization: delete old snapshots and strip
381
- * promptContext.messages from remaining snapshots across all sessions.
417
+ * One-time storage optimization: delete old snapshots across all sessions.
382
418
  * Safe to run multiple times (idempotent).
383
419
  */
384
420
  optimizeStorage() {
385
- let deletedSnapshots = 0;
386
- let strippedSnapshots = 0;
387
421
  const deleteResult = this.db.prepare(
388
422
  `
389
423
  DELETE FROM events
@@ -399,20 +433,7 @@ var EventStore = class {
399
433
  )
400
434
  `
401
435
  ).run();
402
- deletedSnapshots = deleteResult.changes;
403
- const snapshots = this.db.prepare(`SELECT id, payload FROM events WHERE event_type = 'turn.snapshot'`).all();
404
- const updateStmt = this.db.prepare(`UPDATE events SET payload = ? WHERE id = ?`);
405
- for (const row of snapshots) {
406
- const data = JSON.parse(row.payload);
407
- const messages = data.messages;
408
- if (!messages) continue;
409
- const changed = stripPromptContextMessages(messages);
410
- if (changed) {
411
- updateStmt.run(JSON.stringify(data), row.id);
412
- strippedSnapshots++;
413
- }
414
- }
415
- return { deletedSnapshots, strippedSnapshots };
436
+ return { deletedSnapshots: deleteResult.changes };
416
437
  }
417
438
  /**
418
439
  * Get the latest snapshot sequence number for a session
@@ -523,7 +544,7 @@ function initEventStore(db) {
523
544
  }
524
545
  resetStaleRunningSessions(eventStoreInstance, db);
525
546
  const result = eventStoreInstance.optimizeStorage();
526
- if (result.deletedSnapshots > 0 || result.strippedSnapshots > 0) {
547
+ if (result.deletedSnapshots > 0) {
527
548
  logger.info("Storage optimized", result);
528
549
  }
529
550
  setImmediate(() => {
@@ -810,6 +831,70 @@ function mapSessionSummaryRow(row) {
810
831
  };
811
832
  }
812
833
 
834
+ // src/server/config.ts
835
+ import { z } from "zod";
836
+ var backendSchema = z.enum(["auto", "vllm", "sglang", "ollama", "llamacpp"]).default("auto");
837
+ var envSchema = z.object({
838
+ // New env var name, with fallback to old name for backward compatibility
839
+ OPENFOX_LLM_URL: z.string().url().optional(),
840
+ OPENFOX_VLLM_URL: z.string().url().optional(),
841
+ OPENFOX_BACKEND: backendSchema,
842
+ OPENFOX_MODEL_NAME: z.string().default("qwen3.5-122b-int4-autoround"),
843
+ OPENFOX_MAX_CONTEXT: z.coerce.number().default(2e5),
844
+ OPENFOX_PORT: z.coerce.number().default(10369),
845
+ OPENFOX_HOST: z.string().optional(),
846
+ OPENFOX_WORKDIR: z.string().optional(),
847
+ OPENFOX_DB_PATH: z.string().default("./openfox.db"),
848
+ OPENFOX_LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
849
+ OPENFOX_DISABLE_THINKING: z.coerce.boolean().default(false),
850
+ OPENFOX_DEV: z.coerce.boolean().default(false)
851
+ });
852
+ function loadConfig() {
853
+ const env = envSchema.parse(process.env);
854
+ const llmUrl = env.OPENFOX_LLM_URL ?? env.OPENFOX_VLLM_URL ?? "http://localhost:8000/v1";
855
+ const workdir = env.OPENFOX_WORKDIR ?? process.cwd();
856
+ return {
857
+ llm: {
858
+ baseUrl: llmUrl,
859
+ model: env.OPENFOX_MODEL_NAME,
860
+ timeout: 3e5,
861
+ // 5 minutes (deprecated, kept for backward compatibility)
862
+ idleTimeout: 3e5,
863
+ // 5 minutes of inactivity
864
+ backend: env.OPENFOX_BACKEND,
865
+ disableThinking: env.OPENFOX_DISABLE_THINKING
866
+ },
867
+ context: {
868
+ maxTokens: env.OPENFOX_MAX_CONTEXT,
869
+ compactionThreshold: 0.85,
870
+ compactionTarget: 0.6
871
+ },
872
+ agent: {
873
+ maxIterations: 10,
874
+ maxConsecutiveFailures: 3,
875
+ toolTimeout: 3e5
876
+ },
877
+ server: {
878
+ port: env.OPENFOX_PORT,
879
+ ...env.OPENFOX_HOST !== void 0 ? { host: env.OPENFOX_HOST } : {}
880
+ },
881
+ database: {
882
+ path: env.OPENFOX_DB_PATH
883
+ },
884
+ mode: env.OPENFOX_DEV ? "development" : "production",
885
+ workdir
886
+ };
887
+ }
888
+
889
+ // src/server/runtime-config.ts
890
+ var runtimeConfig = null;
891
+ function setRuntimeConfig(config) {
892
+ runtimeConfig = config;
893
+ }
894
+ function getRuntimeConfig() {
895
+ return runtimeConfig ?? loadConfig();
896
+ }
897
+
813
898
  // src/server/events/session.ts
814
899
  function toSnapshotMessage(message) {
815
900
  return {
@@ -892,6 +977,10 @@ function getCurrentContextWindowId(sessionId) {
892
977
  const contextResult = foldContextState(events, "");
893
978
  return contextResult.currentContextWindowId || void 0;
894
979
  }
980
+ function getCurrentWindowMessageOptions(sessionId) {
981
+ const contextWindowId = getCurrentContextWindowId(sessionId);
982
+ return contextWindowId ? { contextWindowId } : void 0;
983
+ }
895
984
  function getReadFilesCache(sessionId) {
896
985
  const state = getSessionState(sessionId);
897
986
  return state?.readFiles ?? [];
@@ -978,7 +1067,6 @@ function emitMessageDone(sessionId, messageId, options) {
978
1067
  ...options?.stats !== void 0 && { stats: options.stats },
979
1068
  ...options?.segments !== void 0 && { segments: options.segments },
980
1069
  ...options?.partial !== void 0 && { partial: options.partial },
981
- ...options?.promptContext !== void 0 && { promptContext: options.promptContext },
982
1070
  ...options?.tokenCount !== void 0 && { tokenCount: options.tokenCount }
983
1071
  }
984
1072
  });
@@ -1117,11 +1205,11 @@ function emitChatError(sessionId, error, recoverable) {
1117
1205
  data: { error, recoverable }
1118
1206
  });
1119
1207
  }
1120
- function emitFormatRetry(sessionId, attempt, maxAttempts) {
1208
+ function emitPatternRetry(sessionId, messageId, pattern, field, attempt, maxAttempts, matchedContent) {
1121
1209
  const eventStore = getEventStore();
1122
1210
  eventStore.append(sessionId, {
1123
- type: "format.retry",
1124
- data: { attempt, maxAttempts }
1211
+ type: "pattern.retry",
1212
+ data: { messageId, pattern, field, attempt, maxAttempts, matchedContent }
1125
1213
  });
1126
1214
  }
1127
1215
  function emitTurnSnapshot(sessionId, snapshot) {
@@ -1247,10 +1335,14 @@ export {
1247
1335
  listSessions,
1248
1336
  listSessionsByProject,
1249
1337
  deleteSession,
1338
+ loadConfig,
1339
+ setRuntimeConfig,
1340
+ getRuntimeConfig,
1250
1341
  getSessionState,
1251
1342
  getCurrentWindowMessages,
1252
1343
  getContextMessages,
1253
1344
  getCurrentContextWindowId,
1345
+ getCurrentWindowMessageOptions,
1254
1346
  getReadFilesCache,
1255
1347
  isFileInCache,
1256
1348
  emitSessionInitialized,
@@ -1275,10 +1367,10 @@ export {
1275
1367
  emitContextState,
1276
1368
  emitChatDone,
1277
1369
  emitChatError,
1278
- emitFormatRetry,
1370
+ emitPatternRetry,
1279
1371
  emitTurnSnapshot,
1280
1372
  truncateSessionMessages,
1281
1373
  compactContext,
1282
1374
  getRecentUserPromptsForSession
1283
1375
  };
1284
- //# sourceMappingURL=chunk-HLZV4S2I.js.map
1376
+ //# sourceMappingURL=chunk-NPHYEUYE.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  detectModel
3
- } from "./chunk-HHAJ3QF6.js";
3
+ } from "./chunk-EMJGF3A7.js";
4
4
  import {
5
5
  detectBackend
6
- } from "./chunk-HGAMIPFO.js";
6
+ } from "./chunk-7FDY3EOH.js";
7
7
  import {
8
8
  getGlobalConfigPath
9
9
  } from "./chunk-CQGTEGKL.js";
@@ -435,4 +435,4 @@ export {
435
435
  activateProvider,
436
436
  mergeConfigs
437
437
  };
438
- //# sourceMappingURL=chunk-NNEHZT3V.js.map
438
+ //# sourceMappingURL=chunk-QUSUEN5R.js.map
@@ -33,7 +33,7 @@ Options:
33
33
  }
34
34
  async function runNetworkSetup(mode) {
35
35
  const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-56SIRACI.js");
36
- const { saveGlobalConfig } = await import("./config-YU7NYZYG.js");
36
+ const { saveGlobalConfig } = await import("./config-VBBMTXJZ.js");
37
37
  const { getAuthKeyPath } = await import("./paths-X46PPOI2.js");
38
38
  const existingAuth = await loadAuthConfig(mode);
39
39
  if (existingAuth) {
@@ -94,7 +94,7 @@ async function runNetworkSetup(mode) {
94
94
  console.log("\u2713 Configuration saved!\n");
95
95
  }
96
96
  async function runConfig(mode) {
97
- const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-YU7NYZYG.js");
97
+ const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-VBBMTXJZ.js");
98
98
  const { getGlobalConfigPath } = await import("./paths-X46PPOI2.js");
99
99
  const config = await loadGlobalConfig(mode);
100
100
  const configPath = getGlobalConfigPath(mode);
@@ -151,7 +151,7 @@ async function runCli(options) {
151
151
  break;
152
152
  }
153
153
  case "provider": {
154
- const { runProviderCommand } = await import("./provider-HTJEB3ON.js");
154
+ const { runProviderCommand } = await import("./provider-NRWSSO55.js");
155
155
  const [, subcommand] = positionals;
156
156
  await runProviderCommand(mode, subcommand);
157
157
  break;
@@ -188,12 +188,12 @@ async function runCli(options) {
188
188
  break;
189
189
  }
190
190
  default: {
191
- const { configFileExists } = await import("./config-YU7NYZYG.js");
191
+ const { configFileExists } = await import("./config-VBBMTXJZ.js");
192
192
  const configExists = await configFileExists(mode);
193
193
  if (!configExists) {
194
194
  await runNetworkSetup(mode);
195
195
  }
196
- const { runServe } = await import("./serve-CEQ2QMM5.js");
196
+ const { runServe } = await import("./serve-J6EM3G6N.js");
197
197
  const serveOptions = { mode };
198
198
  if (values.port) serveOptions.port = parseInt(values.port);
199
199
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -205,4 +205,4 @@ async function runCli(options) {
205
205
  export {
206
206
  runCli
207
207
  };
208
- //# sourceMappingURL=chunk-EYCCASW3.js.map
208
+ //# sourceMappingURL=chunk-R3EK3ODJ.js.map