openfox 0.2.4 → 1.0.0
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/builder.agent.md +3 -7
- package/dist/agent-defaults/code-reviewer.agent.md +1 -2
- package/dist/agent-defaults/debugger.agent.md +1 -2
- package/dist/agent-defaults/planner.agent.md +2 -9
- package/dist/agent-defaults/test-generator.agent.md +1 -1
- package/dist/agent-defaults/verifier.agent.md +4 -5
- package/dist/ask-3RK5YJZE.js +19 -0
- package/dist/auto-compaction-7LNZ5J3W.js +23 -0
- package/dist/{branch.api-WDHKZJS6.js → branch.api-XADFZZAA.js} +2 -2
- package/dist/chat-handler-T7SLWZ4E.js +201 -0
- package/dist/chunk-22CTURMH.js +128 -0
- package/dist/chunk-2KSCZSXQ.js +680 -0
- package/dist/{chunk-S5NRIWEU.js → chunk-2TBNG7CS.js} +12 -12
- package/dist/{chunk-4Z2OZ6NX.js → chunk-3EHGGBWE.js} +29 -2
- package/dist/{chunk-GZ7ZVJIW.js → chunk-3UQACISJ.js} +159 -49
- package/dist/{chunk-AF7XS4OI.js → chunk-5YQAXUKO.js} +4 -1
- package/dist/{chunk-MTX5Y3V3.js → chunk-7IOZFJBW.js} +2 -2
- package/dist/chunk-BU2ZYOEA.js +1067 -0
- package/dist/chunk-M2C5GEQR.js +137 -0
- package/dist/{chunk-U62ZECSQ.js → chunk-PNBH3RAX.js} +2 -2
- package/dist/chunk-QDEKU5RL.js +75 -0
- package/dist/chunk-QYP5HQV4.js +438 -0
- package/dist/{chunk-O4W4555H.js → chunk-RAZQTQK2.js} +1353 -1134
- package/dist/chunk-S4QKTRGJ.js +343 -0
- package/dist/{chunk-ARFK3RZW.js → chunk-TPT6HP4H.js} +1 -1
- package/dist/chunk-TVQOONDR.js +75 -0
- package/dist/{chunk-5ZUU23XF.js → chunk-U6BUT37A.js} +286 -33
- package/dist/chunk-VZXXJKSQ.js +314 -0
- package/dist/{chunk-26NRL3HX.js → chunk-XFXOSPYH.js} +3 -2
- package/dist/{chunk-N2XYX4ZA.js → chunk-XKFPU2FA.js} +13 -2
- package/dist/{chunk-FUUYYDVG.js → chunk-YB2574C6.js} +2841 -4507
- package/dist/cli/dev.js +4 -3
- package/dist/cli/index.js +4 -3
- package/dist/{config-GIXXE4VK.js → config-GIFCEJDU.js} +11 -6
- package/dist/events-G6CKHDNZ.js +114 -0
- package/dist/folding-O52L65VN.js +37 -0
- package/dist/{init-2EJ5AC7Z.js → init-MKTUIGZU.js} +46 -13
- package/dist/orchestrator-UGXX7JRQ.js +39 -0
- package/dist/package.json +9 -2
- package/dist/{paths-4BPXWB2W.js → paths-MM76AWYB.js} +2 -2
- package/dist/processor-KLHKDILM.js +236 -0
- package/dist/{project-creator-CWPKRIKI.js → project-creator-KAQXMZCT.js} +9 -8
- package/dist/projects-GSMMEVSO.js +19 -0
- package/dist/{protocol-BFFz3WM0.d.ts → protocol-BZ6OIASP.d.ts} +71 -50
- package/dist/protocol-WQENDK72.js +88 -0
- package/dist/{provider-QEVVNYOX.js → provider-4KTWU6IV.js} +41 -9
- package/dist/runtime-config-2XJJIMSC.js +9 -0
- package/dist/{serve-RYEBLJVN.js → serve-UK6B6G2O.js} +38 -18
- package/dist/server/index.d.ts +81 -27
- package/dist/server/index.js +19 -11
- package/dist/{settings-D5O3TMLD.js → settings-NCLN4JDZ.js} +4 -4
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +1 -1
- package/dist/tools-SGBQE736.js +48 -0
- package/dist/vision-fallback-63VPBSEN.js +22 -0
- package/dist/web/assets/{index-DHmZmhnR.css → index-BsaaC0X0.css} +32 -1
- package/dist/web/assets/index-CvO7QkGh.js +141 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sounds/typing.mp3 +0 -0
- package/dist/workflow-defaults/default.workflow.json +1 -1
- package/package.json +9 -2
- package/dist/chunk-L4XDA3V7.js +0 -218
- package/dist/tools-QMIIDJTV.js +0 -48
- package/dist/web/assets/index-CAD7Iv_d.js +0 -122
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-
|
|
4
|
+
} from "../chunk-2TBNG7CS.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-PNBH3RAX.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/dev.ts
|
|
10
|
-
|
|
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-
|
|
4
|
+
} from "../chunk-2TBNG7CS.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-PNBH3RAX.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/index.ts
|
|
10
|
-
|
|
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-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
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-
|
|
38
|
+
//# sourceMappingURL=config-GIFCEJDU.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EventStore,
|
|
3
|
+
compactContext,
|
|
4
|
+
createEvent,
|
|
5
|
+
emitAssistantMessageStart,
|
|
6
|
+
emitChatDone,
|
|
7
|
+
emitChatError,
|
|
8
|
+
emitContextCompacted,
|
|
9
|
+
emitContextState,
|
|
10
|
+
emitCriteriaSet,
|
|
11
|
+
emitCriterionUpdated,
|
|
12
|
+
emitFileRead,
|
|
13
|
+
emitFormatRetry,
|
|
14
|
+
emitMessageDelta,
|
|
15
|
+
emitMessageDone,
|
|
16
|
+
emitMessageThinking,
|
|
17
|
+
emitModeChanged,
|
|
18
|
+
emitPhaseChanged,
|
|
19
|
+
emitRunningChanged,
|
|
20
|
+
emitSessionInitialized,
|
|
21
|
+
emitTodosUpdated,
|
|
22
|
+
emitToolCall,
|
|
23
|
+
emitToolOutput,
|
|
24
|
+
emitToolPreparing,
|
|
25
|
+
emitToolResult,
|
|
26
|
+
emitTurnSnapshot,
|
|
27
|
+
emitUserMessage,
|
|
28
|
+
getContextMessages,
|
|
29
|
+
getCurrentContextWindowId,
|
|
30
|
+
getCurrentWindowMessages,
|
|
31
|
+
getEventStore,
|
|
32
|
+
getReadFilesCache,
|
|
33
|
+
getRecentUserPromptsForSession,
|
|
34
|
+
getSessionState,
|
|
35
|
+
initEventStore,
|
|
36
|
+
isFileInCache,
|
|
37
|
+
isStoredEvent,
|
|
38
|
+
isTurnEvent
|
|
39
|
+
} from "./chunk-BU2ZYOEA.js";
|
|
40
|
+
import {
|
|
41
|
+
buildContextMessagesFromEventHistory,
|
|
42
|
+
buildContextMessagesFromMessages,
|
|
43
|
+
buildContextMessagesFromStoredEvents,
|
|
44
|
+
buildMessagesFromStoredEvents,
|
|
45
|
+
buildSnapshot,
|
|
46
|
+
buildSnapshotFromSessionState,
|
|
47
|
+
foldContextState,
|
|
48
|
+
foldCriteria,
|
|
49
|
+
foldIsRunning,
|
|
50
|
+
foldMode,
|
|
51
|
+
foldPhase,
|
|
52
|
+
foldSessionState,
|
|
53
|
+
foldTodos,
|
|
54
|
+
foldTurnEventsToSnapshotMessages,
|
|
55
|
+
getMessagesForWindow
|
|
56
|
+
} from "./chunk-2KSCZSXQ.js";
|
|
57
|
+
import "./chunk-3EHGGBWE.js";
|
|
58
|
+
import "./chunk-TVQOONDR.js";
|
|
59
|
+
import "./chunk-PNBH3RAX.js";
|
|
60
|
+
export {
|
|
61
|
+
EventStore,
|
|
62
|
+
buildContextMessagesFromEventHistory,
|
|
63
|
+
buildContextMessagesFromMessages,
|
|
64
|
+
buildContextMessagesFromStoredEvents,
|
|
65
|
+
buildMessagesFromStoredEvents,
|
|
66
|
+
buildSnapshot,
|
|
67
|
+
buildSnapshotFromSessionState,
|
|
68
|
+
compactContext,
|
|
69
|
+
createEvent,
|
|
70
|
+
emitAssistantMessageStart,
|
|
71
|
+
emitChatDone,
|
|
72
|
+
emitChatError,
|
|
73
|
+
emitContextCompacted,
|
|
74
|
+
emitContextState,
|
|
75
|
+
emitCriteriaSet,
|
|
76
|
+
emitCriterionUpdated,
|
|
77
|
+
emitFileRead,
|
|
78
|
+
emitFormatRetry,
|
|
79
|
+
emitMessageDelta,
|
|
80
|
+
emitMessageDone,
|
|
81
|
+
emitMessageThinking,
|
|
82
|
+
emitModeChanged,
|
|
83
|
+
emitPhaseChanged,
|
|
84
|
+
emitRunningChanged,
|
|
85
|
+
emitSessionInitialized,
|
|
86
|
+
emitTodosUpdated,
|
|
87
|
+
emitToolCall,
|
|
88
|
+
emitToolOutput,
|
|
89
|
+
emitToolPreparing,
|
|
90
|
+
emitToolResult,
|
|
91
|
+
emitTurnSnapshot,
|
|
92
|
+
emitUserMessage,
|
|
93
|
+
foldContextState,
|
|
94
|
+
foldCriteria,
|
|
95
|
+
foldIsRunning,
|
|
96
|
+
foldMode,
|
|
97
|
+
foldPhase,
|
|
98
|
+
foldSessionState,
|
|
99
|
+
foldTodos,
|
|
100
|
+
foldTurnEventsToSnapshotMessages,
|
|
101
|
+
getContextMessages,
|
|
102
|
+
getCurrentContextWindowId,
|
|
103
|
+
getCurrentWindowMessages,
|
|
104
|
+
getEventStore,
|
|
105
|
+
getMessagesForWindow,
|
|
106
|
+
getReadFilesCache,
|
|
107
|
+
getRecentUserPromptsForSession,
|
|
108
|
+
getSessionState,
|
|
109
|
+
initEventStore,
|
|
110
|
+
isFileInCache,
|
|
111
|
+
isStoredEvent,
|
|
112
|
+
isTurnEvent
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=events-G6CKHDNZ.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildContextMessagesFromEventHistory,
|
|
3
|
+
buildContextMessagesFromMessages,
|
|
4
|
+
buildContextMessagesFromStoredEvents,
|
|
5
|
+
buildMessagesFromStoredEvents,
|
|
6
|
+
buildSnapshot,
|
|
7
|
+
buildSnapshotFromSessionState,
|
|
8
|
+
foldContextState,
|
|
9
|
+
foldCriteria,
|
|
10
|
+
foldIsRunning,
|
|
11
|
+
foldMode,
|
|
12
|
+
foldPendingConfirmations,
|
|
13
|
+
foldPhase,
|
|
14
|
+
foldSessionState,
|
|
15
|
+
foldTodos,
|
|
16
|
+
foldTurnEventsToSnapshotMessages,
|
|
17
|
+
getMessagesForWindow
|
|
18
|
+
} from "./chunk-2KSCZSXQ.js";
|
|
19
|
+
export {
|
|
20
|
+
buildContextMessagesFromEventHistory,
|
|
21
|
+
buildContextMessagesFromMessages,
|
|
22
|
+
buildContextMessagesFromStoredEvents,
|
|
23
|
+
buildMessagesFromStoredEvents,
|
|
24
|
+
buildSnapshot,
|
|
25
|
+
buildSnapshotFromSessionState,
|
|
26
|
+
foldContextState,
|
|
27
|
+
foldCriteria,
|
|
28
|
+
foldIsRunning,
|
|
29
|
+
foldMode,
|
|
30
|
+
foldPendingConfirmations,
|
|
31
|
+
foldPhase,
|
|
32
|
+
foldSessionState,
|
|
33
|
+
foldTodos,
|
|
34
|
+
foldTurnEventsToSnapshotMessages,
|
|
35
|
+
getMessagesForWindow
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=folding-O52L65VN.js.map
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addProvider,
|
|
3
3
|
saveGlobalConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3UQACISJ.js";
|
|
5
5
|
import {
|
|
6
6
|
detectBackend,
|
|
7
7
|
detectModel
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-U6BUT37A.js";
|
|
9
|
+
import "./chunk-XFXOSPYH.js";
|
|
10
|
+
import "./chunk-5YQAXUKO.js";
|
|
11
|
+
import "./chunk-M2C5GEQR.js";
|
|
12
|
+
import "./chunk-PNBH3RAX.js";
|
|
12
13
|
|
|
13
14
|
// src/cli/init.ts
|
|
14
15
|
import { select, text, spinner, outro, confirm } from "@clack/prompts";
|
|
@@ -21,11 +22,14 @@ var LLM_OPTIONS = [
|
|
|
21
22
|
function createBaseConfig() {
|
|
22
23
|
return {
|
|
23
24
|
providers: [],
|
|
25
|
+
defaultModelSelection: void 0,
|
|
24
26
|
activeProviderId: void 0,
|
|
27
|
+
activeWorkflowId: void 0,
|
|
25
28
|
server: { port: 10369, host: "127.0.0.1", openBrowser: true },
|
|
26
29
|
logging: { level: "info" },
|
|
27
30
|
database: { path: "" },
|
|
28
|
-
workspace: { workdir: process.cwd() }
|
|
31
|
+
workspace: { workdir: process.cwd() },
|
|
32
|
+
visionFallback: { enabled: false, url: "http://localhost:11434", model: "qwen3-vl:2b", timeout: 120 }
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
35
|
async function promptNetworkAccessibility() {
|
|
@@ -95,7 +99,7 @@ async function runInitWithSelect(mode, existingConfig) {
|
|
|
95
99
|
name: "Default",
|
|
96
100
|
url: found.url,
|
|
97
101
|
backend: found.backend,
|
|
98
|
-
|
|
102
|
+
models: [],
|
|
99
103
|
isActive: true
|
|
100
104
|
});
|
|
101
105
|
} else {
|
|
@@ -129,10 +133,10 @@ async function runInitWithSelect(mode, existingConfig) {
|
|
|
129
133
|
name: "Default",
|
|
130
134
|
url,
|
|
131
135
|
backend,
|
|
132
|
-
|
|
136
|
+
models: [],
|
|
133
137
|
isActive: true
|
|
134
138
|
});
|
|
135
|
-
const { setDefaultModelSelection } = await import("./config-
|
|
139
|
+
const { setDefaultModelSelection } = await import("./config-GIFCEJDU.js");
|
|
136
140
|
config = setDefaultModelSelection(config, config.providers[config.providers.length - 1].id, model ?? "auto");
|
|
137
141
|
} catch {
|
|
138
142
|
s2.stop("Server isn't available");
|
|
@@ -153,10 +157,10 @@ async function runInitWithSelect(mode, existingConfig) {
|
|
|
153
157
|
name: "Default",
|
|
154
158
|
url,
|
|
155
159
|
backend: "auto",
|
|
156
|
-
|
|
160
|
+
models: [],
|
|
157
161
|
isActive: true
|
|
158
162
|
});
|
|
159
|
-
const { setDefaultModelSelection } = await import("./config-
|
|
163
|
+
const { setDefaultModelSelection } = await import("./config-GIFCEJDU.js");
|
|
160
164
|
config = setDefaultModelSelection(config, config.providers[config.providers.length - 1].id, "auto");
|
|
161
165
|
}
|
|
162
166
|
}
|
|
@@ -172,8 +176,37 @@ async function runInitWithSelect(mode, existingConfig) {
|
|
|
172
176
|
}
|
|
173
177
|
});
|
|
174
178
|
config.workspace = { workdir: String(workdirChoice).replace(/\/$/, "") };
|
|
179
|
+
const visionChoice = await confirm({
|
|
180
|
+
message: "Configure vision fallback for non-vision models?",
|
|
181
|
+
initialValue: false
|
|
182
|
+
});
|
|
183
|
+
if (visionChoice === true) {
|
|
184
|
+
const visionUrl = await text({
|
|
185
|
+
message: "Vision fallback server URL",
|
|
186
|
+
placeholder: "http://localhost:11434",
|
|
187
|
+
initialValue: config.visionFallback?.url || "http://localhost:11434",
|
|
188
|
+
validate: (value) => {
|
|
189
|
+
if (!value || value.length === 0) return "URL is required";
|
|
190
|
+
if (!value.startsWith("http")) return "Must start with http://";
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
const visionModel = await text({
|
|
194
|
+
message: "Vision fallback model name",
|
|
195
|
+
placeholder: "qwen3-vl:2b",
|
|
196
|
+
initialValue: config.visionFallback?.model || "qwen3-vl:2b",
|
|
197
|
+
validate: (value) => {
|
|
198
|
+
if (!value || value.length === 0) return "Model name is required";
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
config.visionFallback = {
|
|
202
|
+
enabled: true,
|
|
203
|
+
url: String(visionUrl),
|
|
204
|
+
model: String(visionModel),
|
|
205
|
+
timeout: 120
|
|
206
|
+
};
|
|
207
|
+
}
|
|
175
208
|
if (config.providers.length > 0 && !config.defaultModelSelection) {
|
|
176
|
-
const { setDefaultModelSelection } = await import("./config-
|
|
209
|
+
const { setDefaultModelSelection } = await import("./config-GIFCEJDU.js");
|
|
177
210
|
config = setDefaultModelSelection(config, config.providers[0].id, "auto");
|
|
178
211
|
}
|
|
179
212
|
await saveGlobalConfig(mode, config);
|
|
@@ -182,4 +215,4 @@ async function runInitWithSelect(mode, existingConfig) {
|
|
|
182
215
|
export {
|
|
183
216
|
runInitWithSelect
|
|
184
217
|
};
|
|
185
|
-
//# sourceMappingURL=init-
|
|
218
|
+
//# sourceMappingURL=init-MKTUIGZU.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterToolRegistryForStepDone,
|
|
3
|
+
runBuilderTurn,
|
|
4
|
+
runChatTurn,
|
|
5
|
+
runVerifierTurn
|
|
6
|
+
} from "./chunk-VZXXJKSQ.js";
|
|
7
|
+
import {
|
|
8
|
+
TurnMetrics,
|
|
9
|
+
createChatDoneEvent,
|
|
10
|
+
createMessageDoneEvent,
|
|
11
|
+
createMessageStartEvent,
|
|
12
|
+
createToolCallEvent,
|
|
13
|
+
createToolResultEvent
|
|
14
|
+
} from "./chunk-YB2574C6.js";
|
|
15
|
+
import "./chunk-BU2ZYOEA.js";
|
|
16
|
+
import "./chunk-2KSCZSXQ.js";
|
|
17
|
+
import "./chunk-S4QKTRGJ.js";
|
|
18
|
+
import "./chunk-22CTURMH.js";
|
|
19
|
+
import "./chunk-7IOZFJBW.js";
|
|
20
|
+
import "./chunk-XKFPU2FA.js";
|
|
21
|
+
import "./chunk-3EHGGBWE.js";
|
|
22
|
+
import "./chunk-TPT6HP4H.js";
|
|
23
|
+
import "./chunk-TVQOONDR.js";
|
|
24
|
+
import "./chunk-XFXOSPYH.js";
|
|
25
|
+
import "./chunk-5YQAXUKO.js";
|
|
26
|
+
import "./chunk-PNBH3RAX.js";
|
|
27
|
+
export {
|
|
28
|
+
TurnMetrics,
|
|
29
|
+
createChatDoneEvent,
|
|
30
|
+
createMessageDoneEvent,
|
|
31
|
+
createMessageStartEvent,
|
|
32
|
+
createToolCallEvent,
|
|
33
|
+
createToolResultEvent,
|
|
34
|
+
filterToolRegistryForStepDone,
|
|
35
|
+
runBuilderTurn,
|
|
36
|
+
runChatTurn,
|
|
37
|
+
runVerifierTurn
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=orchestrator-UGXX7JRQ.js.map
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openfox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Local-LLM-first agentic coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
"test": "vitest run --reporter=dot --silent=passed-only && vitest run --reporter=dot --silent=passed-only --config e2e/vitest.config.ts",
|
|
35
35
|
"test:unit": "vitest run --reporter=dot --silent=passed-only",
|
|
36
36
|
"test:e2e": "vitest run --reporter=dot --silent=passed-only --config e2e/vitest.config.ts",
|
|
37
|
+
"test:playwright": "playwright test --config=e2e-playwright/playwright.config.ts",
|
|
38
|
+
"test:playwright:ui": "playwright test --config=e2e-playwright/playwright.config.ts --ui",
|
|
39
|
+
"test:playwright:headed": "playwright test --config=e2e-playwright/playwright.config.ts --headed",
|
|
37
40
|
"test:cov": "vitest run --reporter=dot --silent=passed-only --coverage && vitest run --reporter=dot --silent=passed-only --config e2e/vitest.config.ts --coverage",
|
|
38
41
|
"test:cov:unit": "vitest run --reporter=dot --silent=passed-only --coverage",
|
|
39
42
|
"test:cov:e2e": "vitest run --reporter=dot --silent=passed-only --config e2e/vitest.config.ts --coverage",
|
|
@@ -59,12 +62,12 @@
|
|
|
59
62
|
"gray-matter": "^4.0.3",
|
|
60
63
|
"html2canvas": "^1.4.1",
|
|
61
64
|
"ignore": "^7.0.5",
|
|
65
|
+
"node-pty": "^1.1.0",
|
|
62
66
|
"open": "^11.0.0",
|
|
63
67
|
"openai": "^6.33.0",
|
|
64
68
|
"pyright": "^1.1.408",
|
|
65
69
|
"react-markdown": "^10.1.0",
|
|
66
70
|
"react-syntax-highlighter": "^16.1.1",
|
|
67
|
-
"react-virtuoso": "4.18.3",
|
|
68
71
|
"remark-gfm": "^4.0.1",
|
|
69
72
|
"sql-language-server": "^1.7.1",
|
|
70
73
|
"turndown": "^7.2.2",
|
|
@@ -82,6 +85,10 @@
|
|
|
82
85
|
},
|
|
83
86
|
"devDependencies": {
|
|
84
87
|
"@eslint/js": "^10.0.1",
|
|
88
|
+
"@playwright/test": "^1.58.2",
|
|
89
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
90
|
+
"@testing-library/react": "^16.3.2",
|
|
91
|
+
"@testing-library/user-event": "^14.6.1",
|
|
85
92
|
"@types/better-sqlite3": "^7.6.13",
|
|
86
93
|
"@types/node": "^22.19.15",
|
|
87
94
|
"@types/react": "^19.0.8",
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getGlobalConfigPath,
|
|
6
6
|
getGlobalDataDir,
|
|
7
7
|
getSkillsDir
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5YQAXUKO.js";
|
|
9
9
|
export {
|
|
10
10
|
ensureDataDirExists,
|
|
11
11
|
getDatabasePath,
|
|
@@ -14,4 +14,4 @@ export {
|
|
|
14
14
|
getGlobalDataDir,
|
|
15
15
|
getSkillsDir
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=paths-
|
|
17
|
+
//# sourceMappingURL=paths-MM76AWYB.js.map
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateSessionName,
|
|
3
|
+
needsNameGeneration
|
|
4
|
+
} from "./chunk-QDEKU5RL.js";
|
|
5
|
+
import {
|
|
6
|
+
getEventStore,
|
|
7
|
+
updateSessionMetadata
|
|
8
|
+
} from "./chunk-BU2ZYOEA.js";
|
|
9
|
+
import {
|
|
10
|
+
buildMessagesFromStoredEvents,
|
|
11
|
+
foldPendingConfirmations
|
|
12
|
+
} from "./chunk-2KSCZSXQ.js";
|
|
13
|
+
import {
|
|
14
|
+
createChatMessageMessage,
|
|
15
|
+
createContextStateMessage,
|
|
16
|
+
createSessionRunningMessage,
|
|
17
|
+
createSessionStateMessage
|
|
18
|
+
} from "./chunk-S4QKTRGJ.js";
|
|
19
|
+
import "./chunk-3EHGGBWE.js";
|
|
20
|
+
import "./chunk-TPT6HP4H.js";
|
|
21
|
+
import "./chunk-TVQOONDR.js";
|
|
22
|
+
import {
|
|
23
|
+
logger
|
|
24
|
+
} from "./chunk-PNBH3RAX.js";
|
|
25
|
+
|
|
26
|
+
// src/server/queue/processor.ts
|
|
27
|
+
var QueueProcessor = class {
|
|
28
|
+
deps;
|
|
29
|
+
unsubscribe = null;
|
|
30
|
+
activeAgents = /* @__PURE__ */ new Map();
|
|
31
|
+
constructor(deps) {
|
|
32
|
+
this.deps = deps;
|
|
33
|
+
}
|
|
34
|
+
start() {
|
|
35
|
+
if (this.unsubscribe) {
|
|
36
|
+
logger.warn("QueueProcessor already started");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.unsubscribe = this.deps.sessionManager.subscribe((event) => {
|
|
40
|
+
if (event.type === "queue_added") {
|
|
41
|
+
this.handleQueueAdded(event.sessionId);
|
|
42
|
+
} else if (event.type === "running_changed" && !event.isRunning) {
|
|
43
|
+
this.handleTurnDone(event.sessionId);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
logger.debug("QueueProcessor started");
|
|
47
|
+
}
|
|
48
|
+
stop() {
|
|
49
|
+
if (this.unsubscribe) {
|
|
50
|
+
this.unsubscribe();
|
|
51
|
+
this.unsubscribe = null;
|
|
52
|
+
}
|
|
53
|
+
for (const controller of this.activeAgents.values()) {
|
|
54
|
+
controller.abort();
|
|
55
|
+
}
|
|
56
|
+
this.activeAgents.clear();
|
|
57
|
+
logger.debug("QueueProcessor stopped");
|
|
58
|
+
}
|
|
59
|
+
abortSession(sessionId) {
|
|
60
|
+
const controller = this.activeAgents.get(sessionId);
|
|
61
|
+
if (controller) {
|
|
62
|
+
controller.abort();
|
|
63
|
+
this.activeAgents.delete(sessionId);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
handleQueueAdded(sessionId) {
|
|
69
|
+
const { sessionManager } = this.deps;
|
|
70
|
+
const session = sessionManager.getSession(sessionId);
|
|
71
|
+
if (!session) return;
|
|
72
|
+
if (session.isRunning) {
|
|
73
|
+
logger.debug("Session is running, not starting new turn", { sessionId });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!sessionManager.hasQueuedMessages(sessionId)) {
|
|
77
|
+
logger.debug("No queued messages", { sessionId });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.startTurn(sessionId);
|
|
81
|
+
}
|
|
82
|
+
handleTurnDone(sessionId) {
|
|
83
|
+
logger.debug("Turn done, checking for more queued messages", { sessionId });
|
|
84
|
+
const { sessionManager } = this.deps;
|
|
85
|
+
if (!sessionManager.hasQueuedMessages(sessionId)) {
|
|
86
|
+
logger.debug("No more queued messages", { sessionId });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.startTurn(sessionId);
|
|
90
|
+
}
|
|
91
|
+
startTurn(sessionId) {
|
|
92
|
+
const { sessionManager, broadcastForSession } = this.deps;
|
|
93
|
+
logger.info("Starting turn from queue processor", { sessionId });
|
|
94
|
+
const session = sessionManager.getSession(sessionId);
|
|
95
|
+
if (!session || session.isRunning) {
|
|
96
|
+
logger.warn("Cannot start turn: session not found or already running", { sessionId });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const queue = sessionManager.getQueueState(sessionId);
|
|
100
|
+
if (queue.length === 0) {
|
|
101
|
+
logger.warn("Cannot start turn: queue is empty", { sessionId });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
this.activeAgents.set(sessionId, controller);
|
|
106
|
+
sessionManager.setRunning(sessionId, true);
|
|
107
|
+
broadcastForSession(sessionId, createSessionRunningMessage(true));
|
|
108
|
+
const nextAsap = queue.find((m) => m.mode === "asap") ?? queue[0];
|
|
109
|
+
if (nextAsap) {
|
|
110
|
+
sessionManager.cancelQueuedMessage(sessionId, nextAsap.queueId);
|
|
111
|
+
const userMessage = sessionManager.addMessage(sessionId, {
|
|
112
|
+
role: "user",
|
|
113
|
+
content: nextAsap.content,
|
|
114
|
+
...nextAsap.attachments ? { attachments: nextAsap.attachments } : {}
|
|
115
|
+
});
|
|
116
|
+
broadcastForSession(sessionId, createChatMessageMessage(userMessage));
|
|
117
|
+
logger.debug("Added queued message to session", { sessionId, queueId: nextAsap.queueId, messageId: userMessage.id });
|
|
118
|
+
const messageCount = this.getSessionMessageCount(sessionId);
|
|
119
|
+
const currentSession = sessionManager.getSession(sessionId);
|
|
120
|
+
logger.debug("Session name generation check (queue)", {
|
|
121
|
+
sessionId,
|
|
122
|
+
title: currentSession?.metadata.title,
|
|
123
|
+
messageCount,
|
|
124
|
+
needsGeneration: currentSession ? needsNameGeneration(currentSession.metadata.title, messageCount) : false
|
|
125
|
+
});
|
|
126
|
+
if (currentSession && needsNameGeneration(currentSession.metadata.title, messageCount)) {
|
|
127
|
+
const eventStore = getEventStore();
|
|
128
|
+
generateSessionName({
|
|
129
|
+
userMessage: nextAsap.content,
|
|
130
|
+
llmClient: this.deps.getLLMClient(),
|
|
131
|
+
signal: controller.signal
|
|
132
|
+
}).then((result) => {
|
|
133
|
+
logger.debug("Session name generation result (queue)", {
|
|
134
|
+
sessionId,
|
|
135
|
+
success: result.success,
|
|
136
|
+
name: result.name,
|
|
137
|
+
error: result.error
|
|
138
|
+
});
|
|
139
|
+
if (result.success && result.name) {
|
|
140
|
+
updateSessionMetadata(sessionId, { title: result.name });
|
|
141
|
+
eventStore.append(sessionId, {
|
|
142
|
+
type: "session.name_generated",
|
|
143
|
+
data: { name: result.name }
|
|
144
|
+
});
|
|
145
|
+
const updatedSession = sessionManager.getSession(sessionId);
|
|
146
|
+
if (updatedSession) {
|
|
147
|
+
const events = eventStore.getEvents(sessionId);
|
|
148
|
+
const messages = buildMessagesFromStoredEvents(events);
|
|
149
|
+
const pendingConfirmations = foldPendingConfirmations(events);
|
|
150
|
+
broadcastForSession(sessionId, createSessionStateMessage(updatedSession, messages, pendingConfirmations));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}).catch((error) => {
|
|
154
|
+
logger.error("Session name generation failed (queue)", {
|
|
155
|
+
sessionId,
|
|
156
|
+
error: error instanceof Error ? error.message : String(error)
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
this.runTurn(sessionId, controller);
|
|
162
|
+
}
|
|
163
|
+
async runTurn(sessionId, controller) {
|
|
164
|
+
const { sessionManager, getLLMClient, getActiveProvider, broadcastForSession, providerManager } = this.deps;
|
|
165
|
+
const session = sessionManager.getSession(sessionId);
|
|
166
|
+
if (session?.providerId && session.providerModel) {
|
|
167
|
+
const currentActiveProviderId = providerManager.getActiveProviderId();
|
|
168
|
+
const currentModel = providerManager.getCurrentModel();
|
|
169
|
+
if (currentActiveProviderId !== session.providerId || currentModel !== session.providerModel) {
|
|
170
|
+
logger.info("Switching to session provider", {
|
|
171
|
+
sessionId,
|
|
172
|
+
fromProvider: currentActiveProviderId,
|
|
173
|
+
fromModel: currentModel,
|
|
174
|
+
toProvider: session.providerId,
|
|
175
|
+
toModel: session.providerModel
|
|
176
|
+
});
|
|
177
|
+
const result = await providerManager.activateProvider(session.providerId, { model: session.providerModel });
|
|
178
|
+
if (!result.success) {
|
|
179
|
+
logger.error("Failed to activate session provider", { sessionId, error: result.error });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const llmClient = getLLMClient();
|
|
184
|
+
const provider = getActiveProvider?.();
|
|
185
|
+
const statsIdentity = {
|
|
186
|
+
providerId: provider?.id ?? `provider:${llmClient.getModel()}`,
|
|
187
|
+
providerName: provider?.name ?? "Unknown Provider",
|
|
188
|
+
backend: provider?.backend ?? llmClient.getBackend(),
|
|
189
|
+
model: llmClient.getModel()
|
|
190
|
+
};
|
|
191
|
+
const { runChatTurn } = await import("./orchestrator-UGXX7JRQ.js");
|
|
192
|
+
runChatTurn({
|
|
193
|
+
sessionManager,
|
|
194
|
+
sessionId,
|
|
195
|
+
llmClient,
|
|
196
|
+
statsIdentity,
|
|
197
|
+
signal: controller.signal,
|
|
198
|
+
onMessage: (msg) => broadcastForSession(sessionId, msg)
|
|
199
|
+
}).catch((error) => {
|
|
200
|
+
if (error instanceof Error && error.message === "Aborted") {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
logger.error("QueueProcessor turn error", { sessionId, error });
|
|
204
|
+
}).finally(() => {
|
|
205
|
+
this.activeAgents.delete(sessionId);
|
|
206
|
+
const session2 = this.deps.sessionManager.getSession(sessionId);
|
|
207
|
+
if (!session2) return;
|
|
208
|
+
const hasMore = sessionManager.hasQueuedMessages(sessionId);
|
|
209
|
+
if (!hasMore) {
|
|
210
|
+
sessionManager.setRunning(sessionId, false);
|
|
211
|
+
const contextState = sessionManager.getContextState(sessionId);
|
|
212
|
+
broadcastForSession(sessionId, createContextStateMessage(contextState));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.startTurn(sessionId);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
getSessionMessageCount(sessionId) {
|
|
219
|
+
const eventStore = getEventStore();
|
|
220
|
+
const events = eventStore.getEvents(sessionId);
|
|
221
|
+
let count = 0;
|
|
222
|
+
for (const event of events) {
|
|
223
|
+
if (event.type === "message.start") {
|
|
224
|
+
const data = event.data;
|
|
225
|
+
if (data.role === "user") {
|
|
226
|
+
count++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return count;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
export {
|
|
234
|
+
QueueProcessor
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=processor-KLHKDILM.js.map
|