openfox 2.0.0-beta.1 → 2.0.0-beta.11
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/dist/agent-defaults/code-reviewer.agent.md +2 -1
- package/dist/{chat-handler-IVIWOR3D.js → chat-handler-NMJCOCCB.js} +14 -27
- package/dist/{chunk-ZLUBZ4K4.js → chunk-4RLDN2LL.js} +222 -106
- package/dist/{chunk-CEZNMLOO.js → chunk-7TTEGAO6.js} +12 -13
- package/dist/chunk-BU56QFHW.js +315 -0
- package/dist/{chunk-FQLK5GL5.js → chunk-BVHFMAVN.js} +1 -1
- package/dist/{chunk-RF2JGDSS.js → chunk-DMH6JVPF.js} +13 -10
- package/dist/{chunk-ALH4KM2Y.js → chunk-EQQDA4D3.js} +2967 -3248
- package/dist/{chunk-QFSSKIQ3.js → chunk-EXYMWI7A.js} +4 -4
- package/dist/{chunk-NNEHZT3V.js → chunk-EZUR7OEP.js} +11 -3
- package/dist/{chunk-NONI4CRP.js → chunk-ITWVFGFV.js} +5 -61
- package/dist/{chunk-4U4CSRBE.js → chunk-LCRJWUW7.js} +6 -6
- package/dist/{chunk-XKR3HCAL.js → chunk-NSBYORD5.js} +177 -34
- package/dist/{chunk-PSJIT5LZ.js → chunk-RFNEDBVO.js} +4 -4
- package/dist/chunk-RI6GAMNP.js +13 -0
- package/dist/{chunk-HHAJ3QF6.js → chunk-UKTPL5ZG.js} +16 -28
- package/dist/{chunk-HGAMIPFO.js → chunk-VIIRNJDT.js} +39 -178
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/compactor-TDNRM3A7.js +9 -0
- package/dist/{config-YU7NYZYG.js → config-TDVA7MQN.js} +9 -8
- package/dist/{events-OHJWCI3S.js → events-UGTGGFG3.js} +8 -7
- package/dist/{folding-U6UHQAS5.js → folding-YOCGTZYH.js} +2 -2
- package/dist/{orchestrator-7ZXM4J22.js → orchestrator-75L5UGDU.js} +18 -22
- package/dist/package.json +1 -1
- package/dist/{processor-TKBJLQ2N.js → processor-GHESQ2YV.js} +8 -9
- package/dist/{protocol-BQ12Aw5J.d.ts → protocol-B9R1CUvt.d.ts} +14 -39
- package/dist/{protocol-K62EPEGS.js → protocol-CN24IKQN.js} +3 -5
- package/dist/{provider-HTJEB3ON.js → provider-BGH4MBLH.js} +25 -10
- package/dist/{serve-5KA6SSSP.js → serve-I6T7V62Z.js} +25 -26
- package/dist/server/index.d.ts +1 -6
- package/dist/server/index.js +15 -16
- package/dist/{settings-VRAOAPLA.js → settings-6XX56F3F.js} +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +1 -1
- package/dist/{tools-Z7X4HXZN.js → tools-D3WWIOQD.js} +11 -13
- package/dist/web/assets/{index-BY8EbT5Z.css → index-CSOB8dwI.css} +1 -1
- package/dist/web/assets/index-tJDr1ODC.js +299 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/dist/workflow-defaults/default.workflow.json +9 -4
- package/package.json +1 -1
- package/dist/auto-compaction-UIWTO3H5.js +0 -27
- package/dist/chunk-CGZHLM3K.js +0 -70
- package/dist/chunk-SZKEGZIB.js +0 -140
- package/dist/chunk-UFY4I643.js +0 -332
- package/dist/runtime-config-NPSPMRDA.js +0 -9
- package/dist/vision-fallback-3MIZZ6NQ.js +0 -22
- package/dist/web/assets/index-CqOJgw7l.js +0 -299
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getEventStore,
|
|
3
3
|
updateSessionMetadata
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NSBYORD5.js";
|
|
5
5
|
import {
|
|
6
6
|
buildMessagesFromStoredEvents,
|
|
7
7
|
foldPendingConfirmations
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ITWVFGFV.js";
|
|
9
9
|
import {
|
|
10
10
|
createContextStateMessage,
|
|
11
11
|
createSessionStateMessage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7TTEGAO6.js";
|
|
13
13
|
import {
|
|
14
14
|
logger
|
|
15
15
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -143,4 +143,4 @@ export {
|
|
|
143
143
|
needsNameGenerationCheck,
|
|
144
144
|
applyGeneratedSessionName
|
|
145
145
|
};
|
|
146
|
-
//# sourceMappingURL=chunk-
|
|
146
|
+
//# sourceMappingURL=chunk-EXYMWI7A.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectModel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UKTPL5ZG.js";
|
|
4
4
|
import {
|
|
5
5
|
detectBackend
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VIIRNJDT.js";
|
|
7
7
|
import {
|
|
8
8
|
getGlobalConfigPath
|
|
9
9
|
} from "./chunk-CQGTEGKL.js";
|
|
@@ -71,6 +71,7 @@ var providerSchema = z.object({
|
|
|
71
71
|
models: z.array(modelConfigSchema).default([]),
|
|
72
72
|
isActive: z.boolean(),
|
|
73
73
|
createdAt: z.string(),
|
|
74
|
+
isLocal: z.boolean().optional(),
|
|
74
75
|
// Deprecated: model field kept for migration, will be removed after migration
|
|
75
76
|
model: z.string().optional(),
|
|
76
77
|
// Deprecated: maxContext kept for migration
|
|
@@ -323,6 +324,12 @@ function addProvider(config, provider) {
|
|
|
323
324
|
}
|
|
324
325
|
};
|
|
325
326
|
}
|
|
327
|
+
function updateProvider(config, providerId, updates) {
|
|
328
|
+
return {
|
|
329
|
+
...config,
|
|
330
|
+
providers: config.providers.map((p) => p.id === providerId ? { ...p, ...updates } : p)
|
|
331
|
+
};
|
|
332
|
+
}
|
|
326
333
|
function removeProvider(config, providerId) {
|
|
327
334
|
const currentProviders = config.providers ?? [];
|
|
328
335
|
const filtered = currentProviders.filter((p) => p.id !== providerId);
|
|
@@ -431,8 +438,9 @@ export {
|
|
|
431
438
|
getDefaultModel,
|
|
432
439
|
setDefaultModelSelection,
|
|
433
440
|
addProvider,
|
|
441
|
+
updateProvider,
|
|
434
442
|
removeProvider,
|
|
435
443
|
activateProvider,
|
|
436
444
|
mergeConfigs
|
|
437
445
|
};
|
|
438
|
-
//# sourceMappingURL=chunk-
|
|
446
|
+
//# sourceMappingURL=chunk-EZUR7OEP.js.map
|
|
@@ -40,7 +40,6 @@ function updateMessageDone(msg, data) {
|
|
|
40
40
|
if (data.stats) msg.stats = data.stats;
|
|
41
41
|
if (data.segments) msg.segments = data.segments;
|
|
42
42
|
if (data.partial) msg.partial = true;
|
|
43
|
-
if (data.promptContext) msg.promptContext = data.promptContext;
|
|
44
43
|
if (data.tokenCount !== void 0) msg.tokenCount = data.tokenCount;
|
|
45
44
|
if ("preparingToolCalls" in msg) {
|
|
46
45
|
msg.preparingToolCalls = [];
|
|
@@ -135,9 +134,10 @@ function applyEvents(initialMessages, events, options) {
|
|
|
135
134
|
}
|
|
136
135
|
break;
|
|
137
136
|
}
|
|
138
|
-
case "
|
|
137
|
+
case "pattern.retry": {
|
|
139
138
|
const data = event.data;
|
|
140
|
-
|
|
139
|
+
const msg = messages.get(data.messageId);
|
|
140
|
+
if (msg) {
|
|
141
141
|
const retries = msg.formatRetries ?? [];
|
|
142
142
|
retries.push({ attempt: data.attempt, maxAttempts: data.maxAttempts, timestamp: event.timestamp });
|
|
143
143
|
msg.formatRetries = retries;
|
|
@@ -210,30 +210,6 @@ function deepCloneMessage(msg) {
|
|
|
210
210
|
return cloned;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
// src/server/events/optimize-storage.ts
|
|
214
|
-
function stripPromptContextMessages(messages) {
|
|
215
|
-
let lastAssistantIdx = -1;
|
|
216
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
217
|
-
const msg = messages[i];
|
|
218
|
-
if (!msg) continue;
|
|
219
|
-
if (msg.role === "assistant" && msg.promptContext) {
|
|
220
|
-
lastAssistantIdx = i;
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
let changed = false;
|
|
225
|
-
for (let i = 0; i < messages.length; i++) {
|
|
226
|
-
const msg = messages[i];
|
|
227
|
-
if (!msg) continue;
|
|
228
|
-
const pc = msg.promptContext;
|
|
229
|
-
if (pc && pc.messages && pc.messages.length > 0 && i !== lastAssistantIdx) {
|
|
230
|
-
pc.messages = [];
|
|
231
|
-
changed = true;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return changed;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
213
|
// src/server/events/folding.ts
|
|
238
214
|
import stripAnsi from "strip-ansi";
|
|
239
215
|
function cloneMessage(message) {
|
|
@@ -266,7 +242,6 @@ function spreadOptionalMessageFields(message) {
|
|
|
266
242
|
...message.messageKind !== void 0 && { messageKind: message.messageKind },
|
|
267
243
|
...message.contextWindowId !== void 0 && { contextWindowId: message.contextWindowId },
|
|
268
244
|
...message.isCompactionSummary !== void 0 && { isCompactionSummary: message.isCompactionSummary },
|
|
269
|
-
...message.promptContext !== void 0 && { promptContext: message.promptContext },
|
|
270
245
|
...message.attachments !== void 0 && { attachments: message.attachments },
|
|
271
246
|
...message.preparingToolCalls !== void 0 && message.preparingToolCalls.length > 0 && { preparingToolCalls: message.preparingToolCalls },
|
|
272
247
|
...message.metadata !== void 0 && { metadata: message.metadata }
|
|
@@ -646,30 +621,12 @@ function foldSessionState(events, initialWindowId, maxTokens, initialMessages) {
|
|
|
646
621
|
dynamicContextChanged: false
|
|
647
622
|
};
|
|
648
623
|
const contextState = baseContextState.compactionCount !== contextResult.compactionCount || baseContextState.maxTokens !== maxTokens ? { ...baseContextState, compactionCount: contextResult.compactionCount, maxTokens } : { ...baseContextState, maxTokens };
|
|
649
|
-
let messageReminderMode;
|
|
650
|
-
let snapshotReminderMode;
|
|
651
624
|
let cachedSystemPrompt;
|
|
652
625
|
let dynamicContextHash;
|
|
653
626
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
654
627
|
const event = events[i];
|
|
655
|
-
if (event.type === "message.start") {
|
|
656
|
-
const data = event.data;
|
|
657
|
-
if (data.role === "user" && data.messageKind === "auto-prompt" && data.content?.includes("<system-reminder>")) {
|
|
658
|
-
if (data.content.includes("Plan Mode")) {
|
|
659
|
-
messageReminderMode = { seq: event.seq, mode: "planner" };
|
|
660
|
-
} else if (data.content.includes("Build Mode")) {
|
|
661
|
-
messageReminderMode = { seq: event.seq, mode: "builder" };
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
628
|
if (event.type === "turn.snapshot") {
|
|
666
629
|
const snapshotData = event.data;
|
|
667
|
-
if (snapshotData.lastModeWithReminder) {
|
|
668
|
-
snapshotReminderMode = {
|
|
669
|
-
seq: event.seq,
|
|
670
|
-
mode: snapshotData.lastModeWithReminder
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
630
|
if (snapshotData.cachedSystemPrompt && !cachedSystemPrompt) {
|
|
674
631
|
cachedSystemPrompt = snapshotData.cachedSystemPrompt;
|
|
675
632
|
}
|
|
@@ -681,14 +638,6 @@ function foldSessionState(events, initialWindowId, maxTokens, initialMessages) {
|
|
|
681
638
|
}
|
|
682
639
|
}
|
|
683
640
|
}
|
|
684
|
-
let lastModeWithReminder;
|
|
685
|
-
if (messageReminderMode && snapshotReminderMode) {
|
|
686
|
-
lastModeWithReminder = messageReminderMode.seq > snapshotReminderMode.seq ? messageReminderMode.mode : snapshotReminderMode.mode;
|
|
687
|
-
} else if (snapshotReminderMode) {
|
|
688
|
-
lastModeWithReminder = snapshotReminderMode.mode;
|
|
689
|
-
} else if (messageReminderMode) {
|
|
690
|
-
lastModeWithReminder = messageReminderMode.mode;
|
|
691
|
-
}
|
|
692
641
|
let sessionInit;
|
|
693
642
|
let sessionTitle;
|
|
694
643
|
const visionFallbacks = [];
|
|
@@ -734,7 +683,7 @@ function foldSessionState(events, initialWindowId, maxTokens, initialMessages) {
|
|
|
734
683
|
}
|
|
735
684
|
break;
|
|
736
685
|
}
|
|
737
|
-
case "
|
|
686
|
+
case "pattern.retry": {
|
|
738
687
|
const data = event.data;
|
|
739
688
|
formatRetries.push({
|
|
740
689
|
attempt: data.attempt,
|
|
@@ -783,7 +732,6 @@ function foldSessionState(events, initialWindowId, maxTokens, initialMessages) {
|
|
|
783
732
|
contextState,
|
|
784
733
|
currentContextWindowId: contextResult.currentContextWindowId,
|
|
785
734
|
readFiles: contextResult.readFiles,
|
|
786
|
-
...lastModeWithReminder !== void 0 && { lastModeWithReminder },
|
|
787
735
|
...cachedSystemPrompt !== void 0 && { cachedSystemPrompt },
|
|
788
736
|
...dynamicContextHash !== void 0 && { dynamicContextHash },
|
|
789
737
|
pendingConfirmations,
|
|
@@ -809,7 +757,6 @@ function buildSnapshot(foldedState, latestSeq, snapshotAt = Date.now()) {
|
|
|
809
757
|
currentContextWindowId: foldedState.currentContextWindowId,
|
|
810
758
|
todos: foldedState.todos,
|
|
811
759
|
readFiles: foldedState.readFiles,
|
|
812
|
-
...foldedState.lastModeWithReminder !== void 0 && { lastModeWithReminder: foldedState.lastModeWithReminder },
|
|
813
760
|
...foldedState.cachedSystemPrompt !== void 0 && { cachedSystemPrompt: foldedState.cachedSystemPrompt },
|
|
814
761
|
...foldedState.dynamicContextHash !== void 0 && { dynamicContextHash: foldedState.dynamicContextHash },
|
|
815
762
|
snapshotSeq: latestSeq,
|
|
@@ -845,7 +792,6 @@ function buildSnapshotFromSessionState(input) {
|
|
|
845
792
|
latestSnapshotEvent.data.messages,
|
|
846
793
|
events.slice(latestSnapshotIndex + 1)
|
|
847
794
|
) : foldedState.messages;
|
|
848
|
-
stripPromptContextMessages(messages);
|
|
849
795
|
return {
|
|
850
796
|
mode: session.mode,
|
|
851
797
|
phase: session.phase,
|
|
@@ -867,7 +813,6 @@ function buildSnapshotFromSessionState(input) {
|
|
|
867
813
|
snapshotSeq: latestSeq,
|
|
868
814
|
snapshotAt,
|
|
869
815
|
...foldedState.sessionInit !== void 0 && { sessionInit: foldedState.sessionInit },
|
|
870
|
-
...foldedState.lastModeWithReminder !== void 0 && { lastModeWithReminder: foldedState.lastModeWithReminder },
|
|
871
816
|
...input.cachedSystemPrompt !== void 0 ? { cachedSystemPrompt: input.cachedSystemPrompt } : foldedState.cachedSystemPrompt !== void 0 ? { cachedSystemPrompt: foldedState.cachedSystemPrompt } : {},
|
|
872
817
|
...input.dynamicContextHash !== void 0 ? { dynamicContextHash: input.dynamicContextHash } : foldedState.dynamicContextHash !== void 0 ? { dynamicContextHash: foldedState.dynamicContextHash } : {}
|
|
873
818
|
};
|
|
@@ -886,7 +831,6 @@ function buildContextMessagesFromMessages(messages, windowId) {
|
|
|
886
831
|
}
|
|
887
832
|
|
|
888
833
|
export {
|
|
889
|
-
stripPromptContextMessages,
|
|
890
834
|
spreadOptionalMessageFields,
|
|
891
835
|
buildMessagesFromStoredEvents,
|
|
892
836
|
buildContextMessagesFromStoredEvents,
|
|
@@ -912,4 +856,4 @@ export {
|
|
|
912
856
|
getMessagesForWindow,
|
|
913
857
|
buildContextMessagesFromMessages
|
|
914
858
|
};
|
|
915
|
-
//# sourceMappingURL=chunk-
|
|
859
|
+
//# sourceMappingURL=chunk-ITWVFGFV.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-
|
|
36
|
+
const { saveGlobalConfig } = await import("./config-TDVA7MQN.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-
|
|
97
|
+
const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-TDVA7MQN.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-
|
|
154
|
+
const { runProviderCommand } = await import("./provider-BGH4MBLH.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-
|
|
191
|
+
const { configFileExists } = await import("./config-TDVA7MQN.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-
|
|
196
|
+
const { runServe } = await import("./serve-I6T7V62Z.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-
|
|
208
|
+
//# sourceMappingURL=chunk-LCRJWUW7.js.map
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getDatabase
|
|
3
|
-
} from "./chunk-FBGWG4N6.js";
|
|
4
1
|
import {
|
|
5
2
|
buildContextMessagesFromEventHistory,
|
|
6
3
|
buildMessagesFromStoredEvents,
|
|
7
4
|
buildSnapshot,
|
|
8
5
|
foldContextState,
|
|
9
6
|
foldSessionState,
|
|
10
|
-
spreadOptionalMessageFields
|
|
11
|
-
|
|
12
|
-
} from "./chunk-NONI4CRP.js";
|
|
7
|
+
spreadOptionalMessageFields
|
|
8
|
+
} from "./chunk-ITWVFGFV.js";
|
|
13
9
|
import {
|
|
14
|
-
|
|
15
|
-
} from "./chunk-
|
|
10
|
+
getDatabase
|
|
11
|
+
} from "./chunk-FBGWG4N6.js";
|
|
16
12
|
import {
|
|
17
13
|
logger
|
|
18
14
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -105,6 +101,18 @@ var EventStore = class {
|
|
|
105
101
|
CREATE INDEX IF NOT EXISTS idx_events_session_type
|
|
106
102
|
ON events(session_id, event_type)
|
|
107
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
|
+
`);
|
|
108
116
|
}
|
|
109
117
|
// --------------------------------------------------------------------------
|
|
110
118
|
// Append
|
|
@@ -183,10 +191,41 @@ var EventStore = class {
|
|
|
183
191
|
* Get all events for a session, optionally starting from a specific seq
|
|
184
192
|
*/
|
|
185
193
|
getEvents(sessionId, fromSeq) {
|
|
186
|
-
const query = fromSeq !== void 0 ? `SELECT
|
|
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`;
|
|
187
201
|
const rows = fromSeq !== void 0 ? this.db.prepare(query).all(sessionId, fromSeq) : this.db.prepare(query).all(sessionId);
|
|
188
202
|
return rows.map((row) => this.rowToStoredEvent(row));
|
|
189
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
|
+
}
|
|
190
229
|
/**
|
|
191
230
|
* Get the latest sequence number for a session
|
|
192
231
|
*/
|
|
@@ -224,6 +263,55 @@ var EventStore = class {
|
|
|
224
263
|
events
|
|
225
264
|
};
|
|
226
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Get ALL events for a session, including synthetic events reconstructed
|
|
268
|
+
* from the latest snapshot's messages. This provides a unified view of the
|
|
269
|
+
* full event history even after cleanupOldEvents has deleted raw events.
|
|
270
|
+
*
|
|
271
|
+
* Synthetic events have seq=0 and are reconstructed as message.start +
|
|
272
|
+
* message.done pairs from snapshot messages. Real events since the snapshot
|
|
273
|
+
* keep their original seq numbers.
|
|
274
|
+
*/
|
|
275
|
+
getAllEvents(sessionId) {
|
|
276
|
+
const { snapshot, events } = this.getEventsSinceSnapshot(sessionId);
|
|
277
|
+
if (!snapshot) {
|
|
278
|
+
return events;
|
|
279
|
+
}
|
|
280
|
+
const syntheticEvents = [];
|
|
281
|
+
for (const msg of snapshot.messages) {
|
|
282
|
+
syntheticEvents.push({
|
|
283
|
+
seq: 0,
|
|
284
|
+
timestamp: msg.timestamp,
|
|
285
|
+
sessionId,
|
|
286
|
+
type: "message.start",
|
|
287
|
+
data: {
|
|
288
|
+
messageId: msg.id,
|
|
289
|
+
role: msg.role,
|
|
290
|
+
content: msg.content,
|
|
291
|
+
...msg.contextWindowId !== void 0 && { contextWindowId: msg.contextWindowId },
|
|
292
|
+
...msg.isSystemGenerated !== void 0 && { isSystemGenerated: msg.isSystemGenerated },
|
|
293
|
+
...msg.messageKind !== void 0 && { messageKind: msg.messageKind },
|
|
294
|
+
...msg.metadata !== void 0 && { metadata: msg.metadata },
|
|
295
|
+
...msg.subAgentId !== void 0 && { subAgentId: msg.subAgentId },
|
|
296
|
+
...msg.subAgentType !== void 0 && { subAgentType: msg.subAgentType },
|
|
297
|
+
...msg.isCompactionSummary !== void 0 && { isCompactionSummary: msg.isCompactionSummary },
|
|
298
|
+
...msg.attachments !== void 0 && { attachments: msg.attachments }
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
syntheticEvents.push({
|
|
302
|
+
seq: 0,
|
|
303
|
+
timestamp: msg.timestamp,
|
|
304
|
+
sessionId,
|
|
305
|
+
type: "message.done",
|
|
306
|
+
data: { messageId: msg.id }
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return [...syntheticEvents, ...events].sort((a, b) => {
|
|
310
|
+
const tsDiff = a.timestamp - b.timestamp;
|
|
311
|
+
if (tsDiff !== 0) return tsDiff;
|
|
312
|
+
return a.seq - b.seq;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
227
315
|
rowToStoredEvent(row) {
|
|
228
316
|
return {
|
|
229
317
|
seq: row.seq,
|
|
@@ -375,13 +463,10 @@ var EventStore = class {
|
|
|
375
463
|
return result.changes;
|
|
376
464
|
}
|
|
377
465
|
/**
|
|
378
|
-
* One-time storage optimization: delete old snapshots
|
|
379
|
-
* promptContext.messages from remaining snapshots across all sessions.
|
|
466
|
+
* One-time storage optimization: delete old snapshots across all sessions.
|
|
380
467
|
* Safe to run multiple times (idempotent).
|
|
381
468
|
*/
|
|
382
469
|
optimizeStorage() {
|
|
383
|
-
let deletedSnapshots = 0;
|
|
384
|
-
let strippedSnapshots = 0;
|
|
385
470
|
const deleteResult = this.db.prepare(
|
|
386
471
|
`
|
|
387
472
|
DELETE FROM events
|
|
@@ -397,20 +482,7 @@ var EventStore = class {
|
|
|
397
482
|
)
|
|
398
483
|
`
|
|
399
484
|
).run();
|
|
400
|
-
deletedSnapshots
|
|
401
|
-
const snapshots = this.db.prepare(`SELECT id, payload FROM events WHERE event_type = 'turn.snapshot'`).all();
|
|
402
|
-
const updateStmt = this.db.prepare(`UPDATE events SET payload = ? WHERE id = ?`);
|
|
403
|
-
for (const row of snapshots) {
|
|
404
|
-
const data = JSON.parse(row.payload);
|
|
405
|
-
const messages = data.messages;
|
|
406
|
-
if (!messages) continue;
|
|
407
|
-
const changed = stripPromptContextMessages(messages);
|
|
408
|
-
if (changed) {
|
|
409
|
-
updateStmt.run(JSON.stringify(data), row.id);
|
|
410
|
-
strippedSnapshots++;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return { deletedSnapshots, strippedSnapshots };
|
|
485
|
+
return { deletedSnapshots: deleteResult.changes };
|
|
414
486
|
}
|
|
415
487
|
/**
|
|
416
488
|
* Get the latest snapshot sequence number for a session
|
|
@@ -521,7 +593,7 @@ function initEventStore(db) {
|
|
|
521
593
|
}
|
|
522
594
|
resetStaleRunningSessions(eventStoreInstance, db);
|
|
523
595
|
const result = eventStoreInstance.optimizeStorage();
|
|
524
|
-
if (result.deletedSnapshots > 0
|
|
596
|
+
if (result.deletedSnapshots > 0) {
|
|
525
597
|
logger.info("Storage optimized", result);
|
|
526
598
|
}
|
|
527
599
|
setImmediate(() => {
|
|
@@ -808,6 +880,70 @@ function mapSessionSummaryRow(row) {
|
|
|
808
880
|
};
|
|
809
881
|
}
|
|
810
882
|
|
|
883
|
+
// src/server/config.ts
|
|
884
|
+
import { z } from "zod";
|
|
885
|
+
var backendSchema = z.enum(["auto", "vllm", "sglang", "ollama", "llamacpp"]).default("auto");
|
|
886
|
+
var envSchema = z.object({
|
|
887
|
+
// New env var name, with fallback to old name for backward compatibility
|
|
888
|
+
OPENFOX_LLM_URL: z.string().url().optional(),
|
|
889
|
+
OPENFOX_VLLM_URL: z.string().url().optional(),
|
|
890
|
+
OPENFOX_BACKEND: backendSchema,
|
|
891
|
+
OPENFOX_MODEL_NAME: z.string().default("qwen3.5-122b-int4-autoround"),
|
|
892
|
+
OPENFOX_MAX_CONTEXT: z.coerce.number().default(2e5),
|
|
893
|
+
OPENFOX_PORT: z.coerce.number().default(10369),
|
|
894
|
+
OPENFOX_HOST: z.string().optional(),
|
|
895
|
+
OPENFOX_WORKDIR: z.string().optional(),
|
|
896
|
+
OPENFOX_DB_PATH: z.string().default("./openfox.db"),
|
|
897
|
+
OPENFOX_LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
|
|
898
|
+
OPENFOX_DISABLE_THINKING: z.coerce.boolean().default(false),
|
|
899
|
+
OPENFOX_DEV: z.coerce.boolean().default(false)
|
|
900
|
+
});
|
|
901
|
+
function loadConfig() {
|
|
902
|
+
const env = envSchema.parse(process.env);
|
|
903
|
+
const llmUrl = env.OPENFOX_LLM_URL ?? env.OPENFOX_VLLM_URL ?? "http://localhost:8000/v1";
|
|
904
|
+
const workdir = env.OPENFOX_WORKDIR ?? process.cwd();
|
|
905
|
+
return {
|
|
906
|
+
llm: {
|
|
907
|
+
baseUrl: llmUrl,
|
|
908
|
+
model: env.OPENFOX_MODEL_NAME,
|
|
909
|
+
timeout: 3e5,
|
|
910
|
+
// 5 minutes (deprecated, kept for backward compatibility)
|
|
911
|
+
idleTimeout: 3e5,
|
|
912
|
+
// 5 minutes of inactivity
|
|
913
|
+
backend: env.OPENFOX_BACKEND,
|
|
914
|
+
disableThinking: env.OPENFOX_DISABLE_THINKING
|
|
915
|
+
},
|
|
916
|
+
context: {
|
|
917
|
+
maxTokens: env.OPENFOX_MAX_CONTEXT,
|
|
918
|
+
compactionThreshold: 0.85,
|
|
919
|
+
compactionTarget: 0.6
|
|
920
|
+
},
|
|
921
|
+
agent: {
|
|
922
|
+
maxIterations: 10,
|
|
923
|
+
maxConsecutiveFailures: 3,
|
|
924
|
+
toolTimeout: 3e5
|
|
925
|
+
},
|
|
926
|
+
server: {
|
|
927
|
+
port: env.OPENFOX_PORT,
|
|
928
|
+
...env.OPENFOX_HOST !== void 0 ? { host: env.OPENFOX_HOST } : {}
|
|
929
|
+
},
|
|
930
|
+
database: {
|
|
931
|
+
path: env.OPENFOX_DB_PATH
|
|
932
|
+
},
|
|
933
|
+
mode: env.OPENFOX_DEV ? "development" : "production",
|
|
934
|
+
workdir
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// src/server/runtime-config.ts
|
|
939
|
+
var runtimeConfig = null;
|
|
940
|
+
function setRuntimeConfig(config) {
|
|
941
|
+
runtimeConfig = config;
|
|
942
|
+
}
|
|
943
|
+
function getRuntimeConfig() {
|
|
944
|
+
return runtimeConfig ?? loadConfig();
|
|
945
|
+
}
|
|
946
|
+
|
|
811
947
|
// src/server/events/session.ts
|
|
812
948
|
function toSnapshotMessage(message) {
|
|
813
949
|
return {
|
|
@@ -890,6 +1026,10 @@ function getCurrentContextWindowId(sessionId) {
|
|
|
890
1026
|
const contextResult = foldContextState(events, "");
|
|
891
1027
|
return contextResult.currentContextWindowId || void 0;
|
|
892
1028
|
}
|
|
1029
|
+
function getCurrentWindowMessageOptions(sessionId) {
|
|
1030
|
+
const contextWindowId = getCurrentContextWindowId(sessionId);
|
|
1031
|
+
return contextWindowId ? { contextWindowId } : void 0;
|
|
1032
|
+
}
|
|
893
1033
|
function getReadFilesCache(sessionId) {
|
|
894
1034
|
const state = getSessionState(sessionId);
|
|
895
1035
|
return state?.readFiles ?? [];
|
|
@@ -976,7 +1116,6 @@ function emitMessageDone(sessionId, messageId, options) {
|
|
|
976
1116
|
...options?.stats !== void 0 && { stats: options.stats },
|
|
977
1117
|
...options?.segments !== void 0 && { segments: options.segments },
|
|
978
1118
|
...options?.partial !== void 0 && { partial: options.partial },
|
|
979
|
-
...options?.promptContext !== void 0 && { promptContext: options.promptContext },
|
|
980
1119
|
...options?.tokenCount !== void 0 && { tokenCount: options.tokenCount }
|
|
981
1120
|
}
|
|
982
1121
|
});
|
|
@@ -1115,11 +1254,11 @@ function emitChatError(sessionId, error, recoverable) {
|
|
|
1115
1254
|
data: { error, recoverable }
|
|
1116
1255
|
});
|
|
1117
1256
|
}
|
|
1118
|
-
function
|
|
1257
|
+
function emitPatternRetry(sessionId, messageId, pattern, field, attempt, maxAttempts, matchedContent) {
|
|
1119
1258
|
const eventStore = getEventStore();
|
|
1120
1259
|
eventStore.append(sessionId, {
|
|
1121
|
-
type: "
|
|
1122
|
-
data: { attempt, maxAttempts }
|
|
1260
|
+
type: "pattern.retry",
|
|
1261
|
+
data: { messageId, pattern, field, attempt, maxAttempts, matchedContent }
|
|
1123
1262
|
});
|
|
1124
1263
|
}
|
|
1125
1264
|
function emitTurnSnapshot(sessionId, snapshot) {
|
|
@@ -1245,10 +1384,14 @@ export {
|
|
|
1245
1384
|
listSessions,
|
|
1246
1385
|
listSessionsByProject,
|
|
1247
1386
|
deleteSession,
|
|
1387
|
+
loadConfig,
|
|
1388
|
+
setRuntimeConfig,
|
|
1389
|
+
getRuntimeConfig,
|
|
1248
1390
|
getSessionState,
|
|
1249
1391
|
getCurrentWindowMessages,
|
|
1250
1392
|
getContextMessages,
|
|
1251
1393
|
getCurrentContextWindowId,
|
|
1394
|
+
getCurrentWindowMessageOptions,
|
|
1252
1395
|
getReadFilesCache,
|
|
1253
1396
|
isFileInCache,
|
|
1254
1397
|
emitSessionInitialized,
|
|
@@ -1273,10 +1416,10 @@ export {
|
|
|
1273
1416
|
emitContextState,
|
|
1274
1417
|
emitChatDone,
|
|
1275
1418
|
emitChatError,
|
|
1276
|
-
|
|
1419
|
+
emitPatternRetry,
|
|
1277
1420
|
emitTurnSnapshot,
|
|
1278
1421
|
truncateSessionMessages,
|
|
1279
1422
|
compactContext,
|
|
1280
1423
|
getRecentUserPromptsForSession
|
|
1281
1424
|
};
|
|
1282
|
-
//# sourceMappingURL=chunk-
|
|
1425
|
+
//# sourceMappingURL=chunk-NSBYORD5.js.map
|
|
@@ -15,9 +15,9 @@ var SETTINGS_KEYS = {
|
|
|
15
15
|
DISPLAY_USER_PRESETS: "display.userPresets",
|
|
16
16
|
DISPLAY_FOLLOW_SYSTEM_THEME: "display.followSystemTheme",
|
|
17
17
|
DISPLAY_SHOW_OPEN_IN_EDITOR: "display.showOpenInEditorLinks",
|
|
18
|
-
LLM_DISABLE_XML_PROTECTION: "llm.disableXmlProtection",
|
|
19
18
|
LLM_DYNAMIC_SYSTEM_PROMPT: "llm.dynamicSystemPrompt",
|
|
20
|
-
KEYBINDINGS: "keybindings"
|
|
19
|
+
KEYBINDINGS: "keybindings",
|
|
20
|
+
RETRY_PATTERNS: "agent.retryPatterns"
|
|
21
21
|
};
|
|
22
22
|
var SETTINGS_DEFAULTS = {
|
|
23
23
|
[SETTINGS_KEYS.DISPLAY_SHOW_THINKING]: "true",
|
|
@@ -29,8 +29,8 @@ var SETTINGS_DEFAULTS = {
|
|
|
29
29
|
[SETTINGS_KEYS.DISPLAY_THEME]: JSON.stringify({ preset: "dark" }),
|
|
30
30
|
[SETTINGS_KEYS.DISPLAY_FOLLOW_SYSTEM_THEME]: "true",
|
|
31
31
|
[SETTINGS_KEYS.DISPLAY_SHOW_OPEN_IN_EDITOR]: "false",
|
|
32
|
-
[SETTINGS_KEYS.LLM_DISABLE_XML_PROTECTION]: "false",
|
|
33
32
|
[SETTINGS_KEYS.LLM_DYNAMIC_SYSTEM_PROMPT]: "false",
|
|
33
|
+
[SETTINGS_KEYS.RETRY_PATTERNS]: JSON.stringify({ patterns: [], maxRetriesPerTurn: 10 }),
|
|
34
34
|
[SETTINGS_KEYS.KEYBINDINGS]: JSON.stringify({
|
|
35
35
|
terminalToggle: { type: "double-press", key: "Control", threshold: 300 },
|
|
36
36
|
quickAction: { type: "double-press", key: "Shift", threshold: 300 },
|
|
@@ -88,4 +88,4 @@ export {
|
|
|
88
88
|
deleteSetting,
|
|
89
89
|
getAllSettings
|
|
90
90
|
};
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
91
|
+
//# sourceMappingURL=chunk-RFNEDBVO.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/server/context/compactor.ts
|
|
2
|
+
function shouldCompact(currentTokens, maxTokens, threshold) {
|
|
3
|
+
return currentTokens > maxTokens * threshold;
|
|
4
|
+
}
|
|
5
|
+
function getCompactionTarget(maxTokens, targetRatio) {
|
|
6
|
+
return Math.floor(maxTokens * targetRatio);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
shouldCompact,
|
|
11
|
+
getCompactionTarget
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=chunk-RI6GAMNP.js.map
|