openfox 0.2.4 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-defaults/builder.agent.md +3 -7
- package/dist/agent-defaults/code-reviewer.agent.md +1 -2
- package/dist/agent-defaults/explorer.agent.md +22 -0
- package/dist/agent-defaults/planner.agent.md +2 -9
- package/dist/agent-defaults/verifier.agent.md +4 -5
- package/dist/ask-3RK5YJZE.js +19 -0
- package/dist/auto-compaction-WRS52ERL.js +23 -0
- package/dist/{branch.api-WDHKZJS6.js → branch.api-XADFZZAA.js} +2 -2
- package/dist/chat-handler-226J7XYE.js +201 -0
- package/dist/chunk-22CTURMH.js +128 -0
- package/dist/chunk-2KSCZSXQ.js +680 -0
- 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-FUUYYDVG.js → chunk-ARKA56ZM.js} +2842 -4508
- package/dist/chunk-BU2ZYOEA.js +1067 -0
- package/dist/{chunk-O4W4555H.js → chunk-HGMG5F72.js} +1353 -1134
- package/dist/chunk-M2C5GEQR.js +137 -0
- package/dist/chunk-OWDPT3M6.js +314 -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-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-S5NRIWEU.js → chunk-VUQPJFMQ.js} +12 -12
- package/dist/{chunk-26NRL3HX.js → chunk-XFXOSPYH.js} +3 -2
- package/dist/{chunk-N2XYX4ZA.js → chunk-XKFPU2FA.js} +13 -2
- 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-4CBESUGB.js +39 -0
- package/dist/package.json +9 -2
- package/dist/{paths-4BPXWB2W.js → paths-MM76AWYB.js} +2 -2
- package/dist/processor-LAKHPIG3.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-5NHW3X5B.js} +50 -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-WOZVXNEQ.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/agent-defaults/debugger.agent.md +0 -21
- package/dist/agent-defaults/test-generator.agent.md +0 -22
- package/dist/chunk-L4XDA3V7.js +0 -218
- package/dist/tools-QMIIDJTV.js +0 -48
- package/dist/web/assets/index-CAD7Iv_d.js +0 -122
|
@@ -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-OWDPT3M6.js";
|
|
7
|
+
import {
|
|
8
|
+
TurnMetrics,
|
|
9
|
+
createChatDoneEvent,
|
|
10
|
+
createMessageDoneEvent,
|
|
11
|
+
createMessageStartEvent,
|
|
12
|
+
createToolCallEvent,
|
|
13
|
+
createToolResultEvent
|
|
14
|
+
} from "./chunk-ARKA56ZM.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-4CBESUGB.js.map
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openfox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
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-4CBESUGB.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-LAKHPIG3.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createProject
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-XKFPU2FA.js";
|
|
4
|
+
import "./chunk-3EHGGBWE.js";
|
|
5
|
+
import "./chunk-PNBH3RAX.js";
|
|
6
6
|
|
|
7
7
|
// src/server/utils/project-creator.ts
|
|
8
8
|
import { mkdir } from "fs/promises";
|
|
@@ -12,11 +12,11 @@ function validateProjectName(name) {
|
|
|
12
12
|
if (!name || name.trim() === "") {
|
|
13
13
|
return { valid: false, error: "Project name cannot be empty" };
|
|
14
14
|
}
|
|
15
|
-
const validPattern = /^[a-zA-Z0-9._-]+$/;
|
|
15
|
+
const validPattern = /^[a-zA-Z0-9._ -]+$/;
|
|
16
16
|
if (!validPattern.test(name)) {
|
|
17
17
|
return {
|
|
18
18
|
valid: false,
|
|
19
|
-
error: "Project name can only contain letters, numbers, hyphens, underscores, and
|
|
19
|
+
error: "Project name can only contain letters, numbers, hyphens, underscores, dots, and spaces"
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
if (name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
@@ -39,7 +39,8 @@ async function createDirectoryWithGit(projectName, workdir) {
|
|
|
39
39
|
if (!validation.valid) {
|
|
40
40
|
throw new Error(validation.error);
|
|
41
41
|
}
|
|
42
|
-
const
|
|
42
|
+
const sanitizedName = projectName.trim().replace(/\s+/g, "-");
|
|
43
|
+
const fullPath = join(workdir, sanitizedName);
|
|
43
44
|
const exists = await directoryExists(fullPath);
|
|
44
45
|
if (exists) {
|
|
45
46
|
throw new Error(`Directory already exists: ${fullPath}. Please choose a different name or use the existing directory from Browse Projects.`);
|
|
@@ -58,7 +59,7 @@ async function createDirectoryWithGit(projectName, workdir) {
|
|
|
58
59
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
59
60
|
throw new Error(`Failed to initialize git repository: ${errorMessage}`);
|
|
60
61
|
}
|
|
61
|
-
const project = createProject(projectName,
|
|
62
|
+
const project = createProject(projectName, workdir);
|
|
62
63
|
return project;
|
|
63
64
|
}
|
|
64
65
|
export {
|
|
@@ -66,4 +67,4 @@ export {
|
|
|
66
67
|
directoryExists,
|
|
67
68
|
validateProjectName
|
|
68
69
|
};
|
|
69
|
-
//# sourceMappingURL=project-creator-
|
|
70
|
+
//# sourceMappingURL=project-creator-KAQXMZCT.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProject,
|
|
3
|
+
deleteProject,
|
|
4
|
+
getProject,
|
|
5
|
+
getProjectByWorkdir,
|
|
6
|
+
listProjects,
|
|
7
|
+
updateProject
|
|
8
|
+
} from "./chunk-XKFPU2FA.js";
|
|
9
|
+
import "./chunk-3EHGGBWE.js";
|
|
10
|
+
import "./chunk-PNBH3RAX.js";
|
|
11
|
+
export {
|
|
12
|
+
createProject,
|
|
13
|
+
deleteProject,
|
|
14
|
+
getProject,
|
|
15
|
+
getProjectByWorkdir,
|
|
16
|
+
listProjects,
|
|
17
|
+
updateProject
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=projects-GSMMEVSO.js.map
|