openfox 0.2.3 → 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-YMUIRZUI.js → chunk-2TBNG7CS.js} +12 -12
- package/dist/{chunk-4Z2OZ6NX.js → chunk-3EHGGBWE.js} +29 -2
- package/dist/{chunk-L475ND2Z.js → chunk-3UQACISJ.js} +162 -52
- 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-3WOUSUW7.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-BMXSDOZB.js → config-GIFCEJDU.js} +11 -6
- package/dist/events-G6CKHDNZ.js +114 -0
- package/dist/folding-O52L65VN.js +37 -0
- package/dist/{init-PLRTRSDC.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-ETVY64A2.js → provider-4KTWU6IV.js} +41 -9
- package/dist/runtime-config-2XJJIMSC.js +9 -0
- package/dist/{serve-TL34LE77.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/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/png" href="/assets/openfox.png" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>OpenFox</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CvO7QkGh.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BsaaC0X0.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-bg-primary text-text-primary font-mono">
|
|
12
12
|
<div id="root"></div>
|
|
Binary file
|
package/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",
|
package/dist/chunk-L4XDA3V7.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
clearModelCache,
|
|
3
|
-
createLLMClient,
|
|
4
|
-
detectBackend,
|
|
5
|
-
detectModel
|
|
6
|
-
} from "./chunk-5ZUU23XF.js";
|
|
7
|
-
import {
|
|
8
|
-
logger
|
|
9
|
-
} from "./chunk-U62ZECSQ.js";
|
|
10
|
-
|
|
11
|
-
// src/server/provider-manager.ts
|
|
12
|
-
async function fetchAvailableModelsFromBackend(baseUrl, apiKey) {
|
|
13
|
-
const url = baseUrl.includes("/v1") ? `${baseUrl}/models` : `${baseUrl}/v1/models`;
|
|
14
|
-
try {
|
|
15
|
-
const headers = {
|
|
16
|
-
"Content-Type": "application/json"
|
|
17
|
-
};
|
|
18
|
-
if (apiKey) {
|
|
19
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
20
|
-
}
|
|
21
|
-
const response = await fetch(url, {
|
|
22
|
-
method: "GET",
|
|
23
|
-
headers,
|
|
24
|
-
signal: AbortSignal.timeout(1e4)
|
|
25
|
-
});
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
logger.debug("Failed to fetch models", { url, status: response.status });
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
const data = await response.json();
|
|
31
|
-
if (data.data && Array.isArray(data.data)) {
|
|
32
|
-
return data.data.map((m) => m.id).filter(Boolean);
|
|
33
|
-
}
|
|
34
|
-
return [];
|
|
35
|
-
} catch (error) {
|
|
36
|
-
logger.debug("Error fetching models from backend", { url, error: error instanceof Error ? error.message : String(error) });
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function parseDefaultModelSelection(selection) {
|
|
41
|
-
if (!selection) return { providerId: void 0, model: void 0 };
|
|
42
|
-
const parts = selection.split("/");
|
|
43
|
-
return {
|
|
44
|
-
providerId: parts[0],
|
|
45
|
-
model: parts[1] ?? "auto"
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function createProviderManager(config) {
|
|
49
|
-
let providers = [...config.providers ?? []];
|
|
50
|
-
const { providerId: initialProviderId, model: initialModel } = parseDefaultModelSelection(config.defaultModelSelection);
|
|
51
|
-
let defaultModelSelection = config.defaultModelSelection;
|
|
52
|
-
let llmClient = createLLMClient(config);
|
|
53
|
-
const providerStatus = /* @__PURE__ */ new Map();
|
|
54
|
-
for (const p of providers) {
|
|
55
|
-
providerStatus.set(p.id, "unknown");
|
|
56
|
-
}
|
|
57
|
-
function createConfigForProvider(provider, model) {
|
|
58
|
-
return {
|
|
59
|
-
...config,
|
|
60
|
-
llm: {
|
|
61
|
-
...config.llm,
|
|
62
|
-
baseUrl: provider.url.includes("/v1") ? provider.url : `${provider.url}/v1`,
|
|
63
|
-
model,
|
|
64
|
-
backend: provider.backend
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
getProviders() {
|
|
70
|
-
return [...providers];
|
|
71
|
-
},
|
|
72
|
-
getActiveProvider() {
|
|
73
|
-
const { providerId } = parseDefaultModelSelection(defaultModelSelection);
|
|
74
|
-
if (!providerId) return void 0;
|
|
75
|
-
return providers.find((p) => p.id === providerId);
|
|
76
|
-
},
|
|
77
|
-
getActiveProviderId() {
|
|
78
|
-
const { providerId } = parseDefaultModelSelection(defaultModelSelection);
|
|
79
|
-
return providerId;
|
|
80
|
-
},
|
|
81
|
-
getCurrentModel() {
|
|
82
|
-
const { model } = parseDefaultModelSelection(defaultModelSelection);
|
|
83
|
-
return model;
|
|
84
|
-
},
|
|
85
|
-
getLLMClient() {
|
|
86
|
-
return llmClient;
|
|
87
|
-
},
|
|
88
|
-
async activateProvider(providerId, options) {
|
|
89
|
-
const provider = providers.find((p) => p.id === providerId);
|
|
90
|
-
if (!provider) {
|
|
91
|
-
return { success: false, error: "Provider not found" };
|
|
92
|
-
}
|
|
93
|
-
const currentModel = parseDefaultModelSelection(defaultModelSelection).model ?? "auto";
|
|
94
|
-
const targetModel = options?.model ?? currentModel;
|
|
95
|
-
const isModelSwitch = providerId === parseDefaultModelSelection(defaultModelSelection).providerId && options?.model && options.model !== currentModel;
|
|
96
|
-
if (providerId === parseDefaultModelSelection(defaultModelSelection).providerId && !isModelSwitch) {
|
|
97
|
-
return { success: true };
|
|
98
|
-
}
|
|
99
|
-
logger.info("Switching provider", {
|
|
100
|
-
from: parseDefaultModelSelection(defaultModelSelection).providerId,
|
|
101
|
-
to: providerId,
|
|
102
|
-
providerName: provider.name,
|
|
103
|
-
url: provider.url,
|
|
104
|
-
model: targetModel
|
|
105
|
-
});
|
|
106
|
-
const providerConfig = createConfigForProvider(provider, targetModel);
|
|
107
|
-
const newClient = createLLMClient(providerConfig);
|
|
108
|
-
try {
|
|
109
|
-
const url = provider.url.includes("/v1") ? provider.url.replace("/v1", "") : provider.url;
|
|
110
|
-
clearModelCache(url);
|
|
111
|
-
if (provider.backend === "auto") {
|
|
112
|
-
const detected = await detectBackend(url);
|
|
113
|
-
newClient.setBackend(detected);
|
|
114
|
-
} else {
|
|
115
|
-
newClient.setBackend(provider.backend);
|
|
116
|
-
}
|
|
117
|
-
if (targetModel === "auto") {
|
|
118
|
-
const detected = await detectModel(url);
|
|
119
|
-
if (detected) {
|
|
120
|
-
newClient.setModel(detected);
|
|
121
|
-
}
|
|
122
|
-
} else {
|
|
123
|
-
newClient.setModel(targetModel);
|
|
124
|
-
}
|
|
125
|
-
providerStatus.set(providerId, "connected");
|
|
126
|
-
} catch (err) {
|
|
127
|
-
logger.warn("Could not connect to provider", {
|
|
128
|
-
providerId,
|
|
129
|
-
error: err instanceof Error ? err.message : String(err)
|
|
130
|
-
});
|
|
131
|
-
providerStatus.set(providerId, "disconnected");
|
|
132
|
-
}
|
|
133
|
-
providers = providers.map((p) => ({
|
|
134
|
-
...p,
|
|
135
|
-
isActive: p.id === providerId
|
|
136
|
-
}));
|
|
137
|
-
defaultModelSelection = `${providerId}/${targetModel}`;
|
|
138
|
-
llmClient = newClient;
|
|
139
|
-
logger.info("Provider activated", {
|
|
140
|
-
providerId,
|
|
141
|
-
providerName: provider.name,
|
|
142
|
-
model: llmClient.getModel(),
|
|
143
|
-
backend: llmClient.getBackend()
|
|
144
|
-
});
|
|
145
|
-
return { success: true };
|
|
146
|
-
},
|
|
147
|
-
addProvider(providerData) {
|
|
148
|
-
const id = crypto.randomUUID();
|
|
149
|
-
const provider = {
|
|
150
|
-
...providerData,
|
|
151
|
-
id,
|
|
152
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
153
|
-
};
|
|
154
|
-
if (providerData.isActive || providers.length === 0) {
|
|
155
|
-
providers = providers.map((p) => ({ ...p, isActive: false }));
|
|
156
|
-
provider.isActive = true;
|
|
157
|
-
defaultModelSelection = `${id}/auto`;
|
|
158
|
-
}
|
|
159
|
-
providers.push(provider);
|
|
160
|
-
providerStatus.set(id, "unknown");
|
|
161
|
-
return provider;
|
|
162
|
-
},
|
|
163
|
-
removeProvider(providerId) {
|
|
164
|
-
const index = providers.findIndex((p) => p.id === providerId);
|
|
165
|
-
if (index === -1) return false;
|
|
166
|
-
const wasActive = providers[index]?.isActive;
|
|
167
|
-
providers.splice(index, 1);
|
|
168
|
-
providerStatus.delete(providerId);
|
|
169
|
-
if (wasActive && providers.length > 0) {
|
|
170
|
-
providers[0].isActive = true;
|
|
171
|
-
defaultModelSelection = `${providers[0].id}/auto`;
|
|
172
|
-
} else if (providers.length === 0) {
|
|
173
|
-
defaultModelSelection = void 0;
|
|
174
|
-
}
|
|
175
|
-
return true;
|
|
176
|
-
},
|
|
177
|
-
setProviders(newProviders, newDefaultModelSelection) {
|
|
178
|
-
providers = [...newProviders];
|
|
179
|
-
defaultModelSelection = newDefaultModelSelection;
|
|
180
|
-
providerStatus.clear();
|
|
181
|
-
for (const p of providers) {
|
|
182
|
-
providerStatus.set(p.id, "unknown");
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
getProviderStatus(providerId) {
|
|
186
|
-
return providerStatus.get(providerId) ?? "unknown";
|
|
187
|
-
},
|
|
188
|
-
async getProviderModels(providerId) {
|
|
189
|
-
const provider = providers.find((p) => p.id === providerId);
|
|
190
|
-
if (!provider) {
|
|
191
|
-
return [];
|
|
192
|
-
}
|
|
193
|
-
const url = provider.url.includes("/v1") ? provider.url.replace("/v1", "") : provider.url;
|
|
194
|
-
return fetchAvailableModelsFromBackend(url, provider.apiKey);
|
|
195
|
-
},
|
|
196
|
-
async setDefaultModelSelection(providerId, model) {
|
|
197
|
-
const provider = providers.find((p) => p.id === providerId);
|
|
198
|
-
if (!provider) {
|
|
199
|
-
return { success: false, error: "Provider not found" };
|
|
200
|
-
}
|
|
201
|
-
logger.info("Setting default model selection", { providerId, model, providerName: provider.name });
|
|
202
|
-
defaultModelSelection = `${providerId}/${model}`;
|
|
203
|
-
providers = providers.map((p) => ({ ...p, isActive: p.id === providerId }));
|
|
204
|
-
const currentProviderId = parseDefaultModelSelection(defaultModelSelection).providerId;
|
|
205
|
-
if (currentProviderId === providerId) {
|
|
206
|
-
llmClient.setModel(model);
|
|
207
|
-
logger.info("Model updated", { providerId, model });
|
|
208
|
-
}
|
|
209
|
-
return { success: true };
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export {
|
|
215
|
-
fetchAvailableModelsFromBackend,
|
|
216
|
-
createProviderManager
|
|
217
|
-
};
|
|
218
|
-
//# sourceMappingURL=chunk-L4XDA3V7.js.map
|
package/dist/tools-QMIIDJTV.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AskUserInterrupt,
|
|
3
|
-
PathAccessDeniedError,
|
|
4
|
-
addAllowedPaths,
|
|
5
|
-
cancelPathConfirmation,
|
|
6
|
-
cancelPathConfirmationsForSession,
|
|
7
|
-
cancelQuestion,
|
|
8
|
-
cancelQuestionsForSession,
|
|
9
|
-
clearAllowedPaths,
|
|
10
|
-
clearTodos,
|
|
11
|
-
createToolRegistry,
|
|
12
|
-
getTodos,
|
|
13
|
-
getToolRegistryForAgent,
|
|
14
|
-
getToolRegistryForSubAgent,
|
|
15
|
-
provideAnswer,
|
|
16
|
-
providePathConfirmation,
|
|
17
|
-
requestPathAccess,
|
|
18
|
-
setTodoUpdateCallback,
|
|
19
|
-
stepDoneTool
|
|
20
|
-
} from "./chunk-FUUYYDVG.js";
|
|
21
|
-
import "./chunk-MTX5Y3V3.js";
|
|
22
|
-
import "./chunk-N2XYX4ZA.js";
|
|
23
|
-
import "./chunk-4Z2OZ6NX.js";
|
|
24
|
-
import "./chunk-ARFK3RZW.js";
|
|
25
|
-
import "./chunk-26NRL3HX.js";
|
|
26
|
-
import "./chunk-U62ZECSQ.js";
|
|
27
|
-
import "./chunk-AF7XS4OI.js";
|
|
28
|
-
export {
|
|
29
|
-
AskUserInterrupt,
|
|
30
|
-
PathAccessDeniedError,
|
|
31
|
-
addAllowedPaths,
|
|
32
|
-
cancelPathConfirmation,
|
|
33
|
-
cancelPathConfirmationsForSession,
|
|
34
|
-
cancelQuestion,
|
|
35
|
-
cancelQuestionsForSession,
|
|
36
|
-
clearAllowedPaths,
|
|
37
|
-
clearTodos,
|
|
38
|
-
createToolRegistry,
|
|
39
|
-
getTodos,
|
|
40
|
-
getToolRegistryForAgent,
|
|
41
|
-
getToolRegistryForSubAgent,
|
|
42
|
-
provideAnswer,
|
|
43
|
-
providePathConfirmation,
|
|
44
|
-
requestPathAccess,
|
|
45
|
-
setTodoUpdateCallback,
|
|
46
|
-
stepDoneTool
|
|
47
|
-
};
|
|
48
|
-
//# sourceMappingURL=tools-QMIIDJTV.js.map
|