vite-plugin-opencode-assistant 1.0.15 → 1.0.17
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/es/client/App.vue.d.ts +6 -0
- package/es/client/App.vue.js +317 -0
- package/es/client/components/ChromeWarmupError-sfc.css +1 -0
- package/es/client/components/ChromeWarmupError.vue.d.ts +11 -0
- package/es/client/components/ChromeWarmupError.vue.js +196 -0
- package/es/client/components/LoadingContent.vue.d.ts +5 -0
- package/es/client/components/LoadingContent.vue.js +39 -0
- package/es/client/composables/useContext.d.ts +8 -0
- package/es/client/composables/useContext.js +63 -0
- package/es/client/composables/useHotkey.d.ts +12 -0
- package/es/client/composables/useHotkey.js +41 -0
- package/es/client/composables/useSSE.d.ts +20 -0
- package/es/client/composables/useSSE.js +61 -0
- package/es/client/composables/useSelectedElements.d.ts +19 -0
- package/es/client/composables/useSelectedElements.js +43 -0
- package/es/client/composables/useServiceStatus.d.ts +13 -0
- package/es/client/composables/useServiceStatus.js +53 -0
- package/es/client/composables/useSessions.d.ts +26 -0
- package/es/client/composables/useSessions.js +127 -0
- package/es/client/composables/useTheme.d.ts +12 -0
- package/es/client/composables/useTheme.js +42 -0
- package/es/client/index.d.ts +1 -1
- package/es/client/index.js +5 -675
- package/es/client/styles.css +1 -0
- package/es/core/api.d.ts +18 -6
- package/es/core/api.js +345 -89
- package/es/core/proxy-server.js +266 -2
- package/es/core/service.d.ts +9 -2
- package/es/core/service.js +35 -31
- package/es/endpoints/index.js +1 -1
- package/es/endpoints/sse.js +0 -3
- package/es/endpoints/start.d.ts +1 -2
- package/es/endpoints/start.js +2 -2
- package/es/endpoints/types.d.ts +5 -2
- package/es/endpoints/warmup.js +15 -3
- package/es/index.js +8 -12
- package/es/utils/system.d.ts +1 -0
- package/es/utils/system.js +28 -0
- package/lib/client/App.vue.d.ts +6 -0
- package/lib/client/App.vue.js +344 -0
- package/lib/client/components/ChromeWarmupError-sfc.css +1 -0
- package/lib/client/components/ChromeWarmupError.vue.d.ts +11 -0
- package/lib/client/components/ChromeWarmupError.vue.js +215 -0
- package/lib/client/components/LoadingContent.vue.d.ts +5 -0
- package/lib/client/components/LoadingContent.vue.js +58 -0
- package/lib/client/composables/useContext.d.ts +8 -0
- package/lib/client/composables/useContext.js +86 -0
- package/lib/client/composables/useHotkey.d.ts +12 -0
- package/lib/client/composables/useHotkey.js +66 -0
- package/lib/client/composables/useSSE.d.ts +20 -0
- package/lib/client/composables/useSSE.js +84 -0
- package/lib/client/composables/useSelectedElements.d.ts +19 -0
- package/lib/client/composables/useSelectedElements.js +66 -0
- package/lib/client/composables/useServiceStatus.d.ts +13 -0
- package/lib/client/composables/useServiceStatus.js +76 -0
- package/lib/client/composables/useSessions.d.ts +26 -0
- package/lib/client/composables/useSessions.js +148 -0
- package/lib/client/composables/useTheme.d.ts +12 -0
- package/lib/client/composables/useTheme.js +65 -0
- package/lib/client/index.d.ts +1 -1
- package/lib/client/index.js +22 -667
- package/lib/client/styles.css +1 -0
- package/lib/client.js +3280 -3109
- package/lib/core/api.d.ts +18 -6
- package/lib/core/api.js +342 -94
- package/lib/core/proxy-server.js +266 -2
- package/lib/core/service.d.ts +9 -2
- package/lib/core/service.js +31 -30
- package/lib/endpoints/index.js +1 -1
- package/lib/endpoints/sse.js +0 -3
- package/lib/endpoints/start.d.ts +1 -2
- package/lib/endpoints/start.js +2 -2
- package/lib/endpoints/types.d.ts +5 -2
- package/lib/endpoints/warmup.js +15 -3
- package/lib/index.js +8 -12
- package/lib/style.css +1 -1
- package/lib/utils/system.d.ts +1 -0
- package/lib/utils/system.js +29 -0
- package/package.json +4 -4
package/lib/core/api.d.ts
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import type { SessionInfo } from "@vite-plugin-opencode-assistant/shared";
|
|
2
|
+
import { ChromeMcpWarmupError } from "@vite-plugin-opencode-assistant/shared";
|
|
2
3
|
export declare class OpenCodeAPI {
|
|
3
4
|
private hostname;
|
|
4
5
|
private getPort;
|
|
6
|
+
private getProxyPort;
|
|
5
7
|
private warmupChromeMcpConfig;
|
|
6
|
-
|
|
8
|
+
private failedFreeModels;
|
|
9
|
+
constructor(hostname: string, getPort: () => number, getProxyPort: () => number, warmupChromeMcpConfig?: boolean);
|
|
10
|
+
markModelAsFailed(providerID: string, modelID: string): void;
|
|
11
|
+
clearFailedModels(): void;
|
|
7
12
|
private createHttpRequest;
|
|
8
|
-
getSessions(retries?: number): Promise<SessionInfo[]>;
|
|
9
|
-
createSession(retries?: number, title?: string): Promise<SessionInfo>;
|
|
13
|
+
getSessions(projectDir: string, retries?: number): Promise<SessionInfo[]>;
|
|
14
|
+
createSession(projectDir: string, retries?: number, title?: string): Promise<SessionInfo>;
|
|
15
|
+
getCheapestModel(): Promise<{
|
|
16
|
+
providerID: string;
|
|
17
|
+
modelID: string;
|
|
18
|
+
} | null>;
|
|
10
19
|
deleteSession(sessionId: string, retries?: number): Promise<void>;
|
|
11
20
|
getToolIds(retries?: number): Promise<string[]>;
|
|
12
|
-
warmupChromeMcp(viteOrigin?: string): Promise<void>;
|
|
13
|
-
getOrCreateSession(): Promise<string>;
|
|
14
|
-
retryWarmupChromeMcp(viteOrigin?: string): Promise<
|
|
21
|
+
warmupChromeMcp(projectDir: string, viteOrigin?: string): Promise<void>;
|
|
22
|
+
getOrCreateSession(projectDir: string): Promise<string>;
|
|
23
|
+
retryWarmupChromeMcp(projectDir: string, viteOrigin?: string): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
error?: ChromeMcpWarmupError;
|
|
26
|
+
}>;
|
|
15
27
|
}
|
package/lib/core/api.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
var __create = Object.create;
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
8
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
11
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
8
24
|
var __export = (target, all) => {
|
|
9
25
|
for (var name in all)
|
|
10
26
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -55,40 +71,27 @@ module.exports = __toCommonJS(api_exports);
|
|
|
55
71
|
var import_http = __toESM(require("http"));
|
|
56
72
|
var import_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
57
73
|
const log = (0, import_shared.createLogger)("API");
|
|
58
|
-
function sleep(ms) {
|
|
59
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
60
|
-
}
|
|
61
|
-
function base64Encode(str) {
|
|
62
|
-
return Buffer.from(str).toString("base64");
|
|
63
|
-
}
|
|
64
|
-
function extractTextFromResponse(data) {
|
|
65
|
-
if (!data || typeof data !== "object") return null;
|
|
66
|
-
const obj = data;
|
|
67
|
-
if (obj.parts && Array.isArray(obj.parts)) {
|
|
68
|
-
const textParts = obj.parts.filter(
|
|
69
|
-
(p) => p && typeof p === "object" && p.type === "text"
|
|
70
|
-
).map((p) => p.text).filter(Boolean);
|
|
71
|
-
if (textParts.length > 0) return textParts.join("");
|
|
72
|
-
}
|
|
73
|
-
if (obj.text && typeof obj.text === "string") {
|
|
74
|
-
return obj.text;
|
|
75
|
-
}
|
|
76
|
-
if (obj.content && typeof obj.content === "string") {
|
|
77
|
-
return obj.content;
|
|
78
|
-
}
|
|
79
|
-
if (obj.message && typeof obj.message === "string") {
|
|
80
|
-
return obj.message;
|
|
81
|
-
}
|
|
82
|
-
if (typeof data === "string") {
|
|
83
|
-
return data;
|
|
84
|
-
}
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
74
|
class OpenCodeAPI {
|
|
88
|
-
constructor(hostname, getPort, warmupChromeMcpConfig = false) {
|
|
75
|
+
constructor(hostname, getPort, getProxyPort, warmupChromeMcpConfig = false) {
|
|
89
76
|
__publicField(this, "hostname", hostname);
|
|
90
77
|
__publicField(this, "getPort", getPort);
|
|
78
|
+
__publicField(this, "getProxyPort", getProxyPort);
|
|
91
79
|
__publicField(this, "warmupChromeMcpConfig", warmupChromeMcpConfig);
|
|
80
|
+
__publicField(this, "failedFreeModels", /* @__PURE__ */ new Set());
|
|
81
|
+
}
|
|
82
|
+
markModelAsFailed(providerID, modelID) {
|
|
83
|
+
const key = `${providerID}:${modelID}`;
|
|
84
|
+
this.failedFreeModels.add(key);
|
|
85
|
+
log.debug("Marked model as failed", {
|
|
86
|
+
providerID,
|
|
87
|
+
modelID,
|
|
88
|
+
key,
|
|
89
|
+
failedCount: this.failedFreeModels.size
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
clearFailedModels() {
|
|
93
|
+
this.failedFreeModels.clear();
|
|
94
|
+
log.debug("Cleared failed models cache");
|
|
92
95
|
}
|
|
93
96
|
createHttpRequest(options, body, timeout) {
|
|
94
97
|
const timer = new import_shared.PerformanceTimer("HTTP Request", {
|
|
@@ -124,20 +127,26 @@ class OpenCodeAPI {
|
|
|
124
127
|
req.end();
|
|
125
128
|
});
|
|
126
129
|
}
|
|
127
|
-
getSessions() {
|
|
128
|
-
return __async(this, arguments, function* (retries = import_shared.DEFAULT_RETRIES) {
|
|
129
|
-
const timer = log.timer("getSessions", { retries });
|
|
130
|
+
getSessions(_0) {
|
|
131
|
+
return __async(this, arguments, function* (projectDir, retries = import_shared.DEFAULT_RETRIES) {
|
|
132
|
+
const timer = log.timer("getSessions", { retries, projectDir });
|
|
130
133
|
let lastError = null;
|
|
131
134
|
for (let i = 0; i < retries; i++) {
|
|
132
135
|
try {
|
|
133
|
-
log.debug(`Attempt ${i + 1}/${retries}`, { operation: "getSessions" });
|
|
136
|
+
log.debug(`Attempt ${i + 1}/${retries}`, { operation: "getSessions", projectDir });
|
|
134
137
|
const sessions = yield this.createHttpRequest({
|
|
135
138
|
hostname: this.hostname,
|
|
136
139
|
port: this.getPort(),
|
|
137
|
-
path: "/session"
|
|
140
|
+
path: "/session",
|
|
141
|
+
headers: {
|
|
142
|
+
"x-opencode-directory": encodeURIComponent(projectDir)
|
|
143
|
+
}
|
|
138
144
|
});
|
|
145
|
+
const sessionsWithUrl = sessions.map((s) => __spreadProps(__spreadValues({}, s), {
|
|
146
|
+
url: `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(s.directory)}/session/${s.id}`
|
|
147
|
+
}));
|
|
139
148
|
timer.end(`Found ${sessions.length} sessions`);
|
|
140
|
-
return
|
|
149
|
+
return sessionsWithUrl;
|
|
141
150
|
} catch (e) {
|
|
142
151
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
143
152
|
log.debug(`Attempt ${i + 1} failed: ${lastError.message}`, {
|
|
@@ -147,7 +156,7 @@ class OpenCodeAPI {
|
|
|
147
156
|
log.debug(`Retrying in ${import_shared.RETRY_DELAY}ms...`, {
|
|
148
157
|
operation: "getSessions"
|
|
149
158
|
});
|
|
150
|
-
yield sleep(import_shared.RETRY_DELAY);
|
|
159
|
+
yield (0, import_shared.sleep)(import_shared.RETRY_DELAY);
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
}
|
|
@@ -155,15 +164,16 @@ class OpenCodeAPI {
|
|
|
155
164
|
throw lastError;
|
|
156
165
|
});
|
|
157
166
|
}
|
|
158
|
-
createSession() {
|
|
159
|
-
return __async(this, arguments, function* (retries = import_shared.DEFAULT_RETRIES, title) {
|
|
160
|
-
const timer = log.timer("createSession", { retries, title });
|
|
167
|
+
createSession(_0) {
|
|
168
|
+
return __async(this, arguments, function* (projectDir, retries = import_shared.DEFAULT_RETRIES, title) {
|
|
169
|
+
const timer = log.timer("createSession", { retries, title, projectDir });
|
|
161
170
|
let lastError = null;
|
|
162
171
|
for (let i = 0; i < retries; i++) {
|
|
163
172
|
try {
|
|
164
173
|
log.debug(`Attempt ${i + 1}/${retries}`, {
|
|
165
174
|
operation: "createSession",
|
|
166
|
-
title
|
|
175
|
+
title,
|
|
176
|
+
projectDir
|
|
167
177
|
});
|
|
168
178
|
const requestBody = title ? JSON.stringify({ title }) : void 0;
|
|
169
179
|
const session = yield this.createHttpRequest(
|
|
@@ -172,12 +182,17 @@ class OpenCodeAPI {
|
|
|
172
182
|
port: this.getPort(),
|
|
173
183
|
path: "/session",
|
|
174
184
|
method: "POST",
|
|
175
|
-
headers: requestBody ? { "Content-Type": "application/json" } :
|
|
185
|
+
headers: __spreadProps(__spreadValues({}, requestBody ? { "Content-Type": "application/json" } : {}), {
|
|
186
|
+
"x-opencode-directory": encodeURIComponent(projectDir)
|
|
187
|
+
})
|
|
176
188
|
},
|
|
177
189
|
requestBody
|
|
178
190
|
);
|
|
191
|
+
const sessionWithUrl = __spreadProps(__spreadValues({}, session), {
|
|
192
|
+
url: `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${session.id}`
|
|
193
|
+
});
|
|
179
194
|
timer.end(`Created session: ${session.id}`);
|
|
180
|
-
return
|
|
195
|
+
return sessionWithUrl;
|
|
181
196
|
} catch (e) {
|
|
182
197
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
183
198
|
log.debug(`Attempt ${i + 1} failed: ${lastError.message}`, {
|
|
@@ -187,7 +202,7 @@ class OpenCodeAPI {
|
|
|
187
202
|
log.debug(`Retrying in ${import_shared.RETRY_DELAY}ms...`, {
|
|
188
203
|
operation: "createSession"
|
|
189
204
|
});
|
|
190
|
-
yield sleep(import_shared.RETRY_DELAY);
|
|
205
|
+
yield (0, import_shared.sleep)(import_shared.RETRY_DELAY);
|
|
191
206
|
}
|
|
192
207
|
}
|
|
193
208
|
}
|
|
@@ -195,6 +210,66 @@ class OpenCodeAPI {
|
|
|
195
210
|
throw lastError;
|
|
196
211
|
});
|
|
197
212
|
}
|
|
213
|
+
getCheapestModel() {
|
|
214
|
+
return __async(this, null, function* () {
|
|
215
|
+
var _a, _b;
|
|
216
|
+
try {
|
|
217
|
+
const response = yield this.createHttpRequest({
|
|
218
|
+
hostname: this.hostname,
|
|
219
|
+
port: this.getPort(),
|
|
220
|
+
path: "/provider",
|
|
221
|
+
method: "GET"
|
|
222
|
+
});
|
|
223
|
+
const connectedProviders = new Set(response.connected);
|
|
224
|
+
const allModels = [];
|
|
225
|
+
for (const provider of response.all) {
|
|
226
|
+
if (provider.id === "opencode") continue;
|
|
227
|
+
if (!connectedProviders.has(provider.id)) {
|
|
228
|
+
log.debug("Skipping not connected provider", { providerID: provider.id });
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
for (const [modelID, model] of Object.entries(provider.models)) {
|
|
232
|
+
allModels.push({
|
|
233
|
+
providerID: provider.id,
|
|
234
|
+
modelID,
|
|
235
|
+
name: model.name,
|
|
236
|
+
inputCost: (_b = (_a = model.cost) == null ? void 0 : _a.input) != null ? _b : 0,
|
|
237
|
+
releaseDate: model.release_date
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
allModels.sort((a, b) => a.inputCost - b.inputCost);
|
|
242
|
+
const availableModel = allModels.find(
|
|
243
|
+
(model) => !this.failedFreeModels.has(`${model.providerID}:${model.modelID}`)
|
|
244
|
+
);
|
|
245
|
+
if (!availableModel) {
|
|
246
|
+
log.debug("All models have failed", {
|
|
247
|
+
totalModels: allModels.length,
|
|
248
|
+
failedModels: this.failedFreeModels.size,
|
|
249
|
+
connectedProviders: response.connected
|
|
250
|
+
});
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
log.debug("Found cheapest available model for warmup", {
|
|
254
|
+
providerID: availableModel.providerID,
|
|
255
|
+
modelID: availableModel.modelID,
|
|
256
|
+
name: availableModel.name,
|
|
257
|
+
inputCost: availableModel.inputCost,
|
|
258
|
+
releaseDate: availableModel.releaseDate,
|
|
259
|
+
totalModels: allModels.length,
|
|
260
|
+
failedModels: this.failedFreeModels.size,
|
|
261
|
+
connectedProviders: response.connected
|
|
262
|
+
});
|
|
263
|
+
return {
|
|
264
|
+
providerID: availableModel.providerID,
|
|
265
|
+
modelID: availableModel.modelID
|
|
266
|
+
};
|
|
267
|
+
} catch (error) {
|
|
268
|
+
log.warn("Failed to get cheapest model", { error });
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
198
273
|
deleteSession(_0) {
|
|
199
274
|
return __async(this, arguments, function* (sessionId, retries = import_shared.DEFAULT_RETRIES) {
|
|
200
275
|
const timer = log.timer("deleteSession", { sessionId, retries });
|
|
@@ -224,7 +299,7 @@ class OpenCodeAPI {
|
|
|
224
299
|
operation: "deleteSession",
|
|
225
300
|
sessionId
|
|
226
301
|
});
|
|
227
|
-
yield sleep(import_shared.RETRY_DELAY);
|
|
302
|
+
yield (0, import_shared.sleep)(import_shared.RETRY_DELAY);
|
|
228
303
|
}
|
|
229
304
|
}
|
|
230
305
|
}
|
|
@@ -257,7 +332,7 @@ class OpenCodeAPI {
|
|
|
257
332
|
log.debug(`Retrying in ${import_shared.RETRY_DELAY}ms...`, {
|
|
258
333
|
operation: "getToolIds"
|
|
259
334
|
});
|
|
260
|
-
yield sleep(import_shared.RETRY_DELAY);
|
|
335
|
+
yield (0, import_shared.sleep)(import_shared.RETRY_DELAY);
|
|
261
336
|
}
|
|
262
337
|
}
|
|
263
338
|
}
|
|
@@ -265,23 +340,44 @@ class OpenCodeAPI {
|
|
|
265
340
|
throw lastError;
|
|
266
341
|
});
|
|
267
342
|
}
|
|
268
|
-
warmupChromeMcp(viteOrigin) {
|
|
343
|
+
warmupChromeMcp(projectDir, viteOrigin) {
|
|
269
344
|
return __async(this, null, function* () {
|
|
270
345
|
if (!this.warmupChromeMcpConfig) return;
|
|
271
346
|
const timer = log.timer("warmupChromeMcp", { viteOrigin });
|
|
272
347
|
let warmupSessionId = null;
|
|
348
|
+
let freeModel = null;
|
|
349
|
+
const chromeAvailable = yield (0, import_shared.checkChromeDevToolsAvailable)();
|
|
350
|
+
if (!chromeAvailable) {
|
|
351
|
+
const error = new import_shared.ChromeMcpWarmupError(
|
|
352
|
+
import_shared.ChromeMcpWarmupErrorType.CHROME_NOT_CONNECTED,
|
|
353
|
+
"Chrome DevTools Protocol is not available",
|
|
354
|
+
"Chrome remote debugging is not enabled or not running on port 9222. Please enable Chrome remote debugging first."
|
|
355
|
+
);
|
|
356
|
+
log.warn("Chrome DevTools not available", {
|
|
357
|
+
port: import_shared.CHROME_DEVTOOLS_PORT,
|
|
358
|
+
hint: "Enable Chrome remote debugging at chrome://inspect/#remote-debugging"
|
|
359
|
+
});
|
|
360
|
+
timer.end("Chrome DevTools not available");
|
|
361
|
+
throw error;
|
|
362
|
+
}
|
|
363
|
+
log.debug("Chrome DevTools is available, proceeding with warmup");
|
|
273
364
|
try {
|
|
274
|
-
const warmupSession = yield this.createSession(
|
|
365
|
+
const warmupSession = yield this.createSession(
|
|
366
|
+
projectDir,
|
|
367
|
+
import_shared.DEFAULT_RETRIES,
|
|
368
|
+
"__chrome_mcp_warmup__"
|
|
369
|
+
);
|
|
275
370
|
warmupSessionId = warmupSession.id;
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
371
|
+
freeModel = yield this.getCheapestModel();
|
|
372
|
+
if (freeModel) {
|
|
373
|
+
log.debug("Using cheapest model for warmup", {
|
|
374
|
+
providerID: freeModel.providerID,
|
|
375
|
+
modelID: freeModel.modelID
|
|
376
|
+
});
|
|
377
|
+
} else {
|
|
378
|
+
log.debug("No model available, using default model");
|
|
379
|
+
}
|
|
380
|
+
const WARMUP_TIMEOUT = 6e4;
|
|
285
381
|
const data = yield this.createHttpRequest(
|
|
286
382
|
{
|
|
287
383
|
hostname: this.hostname,
|
|
@@ -290,21 +386,87 @@ class OpenCodeAPI {
|
|
|
290
386
|
method: "POST",
|
|
291
387
|
headers: { "Content-Type": "application/json" }
|
|
292
388
|
},
|
|
293
|
-
JSON.stringify({
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
389
|
+
JSON.stringify(__spreadValues({
|
|
390
|
+
parts: [
|
|
391
|
+
{
|
|
392
|
+
type: "text",
|
|
393
|
+
text: "Test if the chrome-devtools_list_pages tool is available. If available, reply with: ready. If not available, explain why."
|
|
394
|
+
}
|
|
395
|
+
]
|
|
396
|
+
}, freeModel && {
|
|
397
|
+
model: {
|
|
398
|
+
providerID: freeModel.providerID,
|
|
399
|
+
modelID: freeModel.modelID
|
|
400
|
+
}
|
|
401
|
+
})),
|
|
297
402
|
WARMUP_TIMEOUT
|
|
298
403
|
);
|
|
299
|
-
const responseText = extractTextFromResponse(data);
|
|
300
|
-
if (!
|
|
301
|
-
throw new
|
|
404
|
+
const responseText = (0, import_shared.extractTextFromResponse)(data);
|
|
405
|
+
if (!responseText) {
|
|
406
|
+
throw new import_shared.ChromeMcpWarmupError(
|
|
407
|
+
import_shared.ChromeMcpWarmupErrorType.AI_RESPONSE_ERROR,
|
|
408
|
+
"AI did not respond to the warmup request",
|
|
409
|
+
"Empty response from AI"
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
const lowerResponse = responseText.toLowerCase();
|
|
413
|
+
if (!lowerResponse.includes("ready")) {
|
|
414
|
+
throw new import_shared.ChromeMcpWarmupError(
|
|
415
|
+
import_shared.ChromeMcpWarmupErrorType.AI_RESPONSE_ERROR,
|
|
416
|
+
"AI response does not indicate success",
|
|
417
|
+
`AI responded with: ${responseText.substring(0, 200)}`
|
|
418
|
+
);
|
|
302
419
|
}
|
|
303
420
|
timer.end("Chrome MCP warmed up");
|
|
304
421
|
} catch (e) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
422
|
+
if (e instanceof import_shared.ChromeMcpWarmupError) {
|
|
423
|
+
if (e.type === import_shared.ChromeMcpWarmupErrorType.SESSION_ERROR) {
|
|
424
|
+
timer.end("Session creation failed");
|
|
425
|
+
}
|
|
426
|
+
log.warn(`Chrome MCP warmup failed: ${e.type}`, __spreadValues({
|
|
427
|
+
message: e.message,
|
|
428
|
+
details: e.details
|
|
429
|
+
}, freeModel && {
|
|
430
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
431
|
+
}));
|
|
432
|
+
timer.end(`Chrome MCP warmup failed: ${e.type}`);
|
|
433
|
+
throw e;
|
|
434
|
+
}
|
|
435
|
+
if (freeModel) {
|
|
436
|
+
this.markModelAsFailed(freeModel.providerID, freeModel.modelID);
|
|
437
|
+
log.debug("Marked model as failed due to warmup error", {
|
|
438
|
+
providerID: freeModel.providerID,
|
|
439
|
+
modelID: freeModel.modelID,
|
|
440
|
+
error: e instanceof Error ? e.message : String(e)
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
444
|
+
if (errorMessage.includes("timeout") || errorMessage.includes("Timeout")) {
|
|
445
|
+
const error2 = new import_shared.ChromeMcpWarmupError(
|
|
446
|
+
import_shared.ChromeMcpWarmupErrorType.AI_TIMEOUT,
|
|
447
|
+
"AI response timeout",
|
|
448
|
+
"AI did not respond within 30 seconds. Please check if the OpenCode AI model is properly configured and available."
|
|
449
|
+
);
|
|
450
|
+
log.warn("Chrome MCP warmup timeout", __spreadValues({
|
|
451
|
+
error: errorMessage
|
|
452
|
+
}, freeModel && {
|
|
453
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
454
|
+
}));
|
|
455
|
+
timer.end("Chrome MCP warmup timeout");
|
|
456
|
+
throw error2;
|
|
457
|
+
}
|
|
458
|
+
const error = new import_shared.ChromeMcpWarmupError(
|
|
459
|
+
import_shared.ChromeMcpWarmupErrorType.UNKNOWN,
|
|
460
|
+
"Unknown error during Chrome MCP warmup",
|
|
461
|
+
errorMessage
|
|
462
|
+
);
|
|
463
|
+
log.warn("Chrome MCP warmup failed with unknown error", __spreadValues({
|
|
464
|
+
error: errorMessage
|
|
465
|
+
}, freeModel && {
|
|
466
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
467
|
+
}));
|
|
468
|
+
timer.end("Chrome MCP warmup failed");
|
|
469
|
+
throw error;
|
|
308
470
|
} finally {
|
|
309
471
|
if (warmupSessionId) {
|
|
310
472
|
try {
|
|
@@ -319,43 +481,63 @@ class OpenCodeAPI {
|
|
|
319
481
|
}
|
|
320
482
|
});
|
|
321
483
|
}
|
|
322
|
-
getOrCreateSession() {
|
|
484
|
+
getOrCreateSession(projectDir) {
|
|
323
485
|
return __async(this, null, function* () {
|
|
324
|
-
const timer = log.timer("getOrCreateSession");
|
|
325
|
-
const projectDir = process.cwd();
|
|
486
|
+
const timer = log.timer("getOrCreateSession", { projectDir });
|
|
326
487
|
log.debug("Getting sessions...", { projectDir });
|
|
327
|
-
const sessions = yield this.getSessions();
|
|
488
|
+
const sessions = yield this.getSessions(projectDir);
|
|
328
489
|
log.debug(`Found ${sessions.length} sessions`, {
|
|
329
490
|
sessions: sessions.map((s) => ({ id: s.id, directory: s.directory }))
|
|
330
491
|
});
|
|
331
492
|
const matchingSession = sessions.find((s) => s.directory === projectDir);
|
|
332
493
|
if (matchingSession) {
|
|
333
|
-
const url2 = `http://${this.hostname}:${this.
|
|
494
|
+
const url2 = `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${matchingSession.id}`;
|
|
334
495
|
timer.end(`Using existing session: ${matchingSession.id}`);
|
|
335
496
|
return url2;
|
|
336
497
|
}
|
|
337
498
|
log.debug("Creating new session...", { projectDir });
|
|
338
|
-
const newSession = yield this.createSession();
|
|
339
|
-
const url = `http://${this.hostname}:${this.
|
|
499
|
+
const newSession = yield this.createSession(projectDir);
|
|
500
|
+
const url = `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${newSession.id}`;
|
|
340
501
|
timer.end(`Created new session: ${newSession.id}`);
|
|
341
502
|
return url;
|
|
342
503
|
});
|
|
343
504
|
}
|
|
344
|
-
retryWarmupChromeMcp(viteOrigin) {
|
|
505
|
+
retryWarmupChromeMcp(projectDir, viteOrigin) {
|
|
345
506
|
return __async(this, null, function* () {
|
|
346
507
|
const timer = log.timer("retryWarmupChromeMcp", { viteOrigin });
|
|
347
508
|
let warmupSessionId = null;
|
|
509
|
+
let freeModel = null;
|
|
510
|
+
const chromeAvailable = yield (0, import_shared.checkChromeDevToolsAvailable)();
|
|
511
|
+
if (!chromeAvailable) {
|
|
512
|
+
const error = new import_shared.ChromeMcpWarmupError(
|
|
513
|
+
import_shared.ChromeMcpWarmupErrorType.CHROME_NOT_CONNECTED,
|
|
514
|
+
"Chrome DevTools Protocol is not available",
|
|
515
|
+
"Chrome remote debugging is not enabled or not running on port 9222. Please enable Chrome remote debugging first."
|
|
516
|
+
);
|
|
517
|
+
log.warn("Chrome DevTools not available for retry", {
|
|
518
|
+
port: import_shared.CHROME_DEVTOOLS_PORT,
|
|
519
|
+
hint: "Enable Chrome remote debugging at chrome://inspect/#remote-debugging"
|
|
520
|
+
});
|
|
521
|
+
timer.end("Chrome DevTools not available for retry");
|
|
522
|
+
return { success: false, error };
|
|
523
|
+
}
|
|
524
|
+
log.debug("Chrome DevTools is available, proceeding with retry warmup");
|
|
348
525
|
try {
|
|
349
|
-
const warmupSession = yield this.createSession(
|
|
526
|
+
const warmupSession = yield this.createSession(
|
|
527
|
+
projectDir,
|
|
528
|
+
import_shared.DEFAULT_RETRIES,
|
|
529
|
+
"__chrome_mcp_warmup__"
|
|
530
|
+
);
|
|
350
531
|
warmupSessionId = warmupSession.id;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
532
|
+
freeModel = yield this.getCheapestModel();
|
|
533
|
+
if (freeModel) {
|
|
534
|
+
log.debug("Using cheapest model for retry warmup", {
|
|
535
|
+
providerID: freeModel.providerID,
|
|
536
|
+
modelID: freeModel.modelID
|
|
537
|
+
});
|
|
538
|
+
} else {
|
|
539
|
+
log.debug("No model available for retry, using default model");
|
|
540
|
+
}
|
|
359
541
|
const WARMUP_TIMEOUT = 6e4;
|
|
360
542
|
const data = yield this.createHttpRequest(
|
|
361
543
|
{
|
|
@@ -365,23 +547,89 @@ class OpenCodeAPI {
|
|
|
365
547
|
method: "POST",
|
|
366
548
|
headers: { "Content-Type": "application/json" }
|
|
367
549
|
},
|
|
368
|
-
JSON.stringify({
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
550
|
+
JSON.stringify(__spreadValues({
|
|
551
|
+
parts: [
|
|
552
|
+
{
|
|
553
|
+
type: "text",
|
|
554
|
+
text: "Test if the chrome-devtools_list_pages tool is available. If available, reply with: ready. If not available, explain why."
|
|
555
|
+
}
|
|
556
|
+
]
|
|
557
|
+
}, freeModel && {
|
|
558
|
+
model: {
|
|
559
|
+
providerID: freeModel.providerID,
|
|
560
|
+
modelID: freeModel.modelID
|
|
561
|
+
}
|
|
562
|
+
})),
|
|
372
563
|
WARMUP_TIMEOUT
|
|
373
564
|
);
|
|
374
565
|
log.debug("Chrome MCP warmup response:", { data });
|
|
375
|
-
const responseText = extractTextFromResponse(data);
|
|
376
|
-
if (!
|
|
377
|
-
throw new
|
|
566
|
+
const responseText = (0, import_shared.extractTextFromResponse)(data);
|
|
567
|
+
if (!responseText) {
|
|
568
|
+
throw new import_shared.ChromeMcpWarmupError(
|
|
569
|
+
import_shared.ChromeMcpWarmupErrorType.AI_RESPONSE_ERROR,
|
|
570
|
+
"AI did not respond to the warmup request",
|
|
571
|
+
"Empty response from AI"
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
const lowerResponse = responseText.toLowerCase();
|
|
575
|
+
if (!lowerResponse.includes("ready")) {
|
|
576
|
+
throw new import_shared.ChromeMcpWarmupError(
|
|
577
|
+
import_shared.ChromeMcpWarmupErrorType.AI_RESPONSE_ERROR,
|
|
578
|
+
"AI response does not indicate success",
|
|
579
|
+
`AI responded with: ${responseText.substring(0, 200)}`
|
|
580
|
+
);
|
|
378
581
|
}
|
|
379
582
|
timer.end("Chrome MCP warmed up successfully");
|
|
380
|
-
return true;
|
|
583
|
+
return { success: true };
|
|
381
584
|
} catch (e) {
|
|
382
|
-
|
|
585
|
+
if (e instanceof import_shared.ChromeMcpWarmupError) {
|
|
586
|
+
if (e.type === import_shared.ChromeMcpWarmupErrorType.SESSION_ERROR) {
|
|
587
|
+
timer.end("Session creation failed");
|
|
588
|
+
}
|
|
589
|
+
log.warn(`Chrome MCP warmup retry failed: ${e.type}`, __spreadValues({
|
|
590
|
+
message: e.message,
|
|
591
|
+
details: e.details
|
|
592
|
+
}, freeModel && {
|
|
593
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
594
|
+
}));
|
|
595
|
+
timer.end(`Chrome MCP warmup retry failed: ${e.type}`);
|
|
596
|
+
return { success: false, error: e };
|
|
597
|
+
}
|
|
598
|
+
if (freeModel) {
|
|
599
|
+
this.markModelAsFailed(freeModel.providerID, freeModel.modelID);
|
|
600
|
+
log.debug("Marked model as failed due to retry warmup error", {
|
|
601
|
+
providerID: freeModel.providerID,
|
|
602
|
+
modelID: freeModel.modelID,
|
|
603
|
+
error: e instanceof Error ? e.message : String(e)
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
607
|
+
if (errorMessage.includes("timeout") || errorMessage.includes("Timeout")) {
|
|
608
|
+
const error2 = new import_shared.ChromeMcpWarmupError(
|
|
609
|
+
import_shared.ChromeMcpWarmupErrorType.AI_TIMEOUT,
|
|
610
|
+
"AI response timeout",
|
|
611
|
+
"AI did not respond within 60 seconds. Please check if the OpenCode AI model is properly configured and available."
|
|
612
|
+
);
|
|
613
|
+
log.warn("Chrome MCP warmup retry timeout", __spreadValues({
|
|
614
|
+
error: errorMessage
|
|
615
|
+
}, freeModel && {
|
|
616
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
617
|
+
}));
|
|
618
|
+
timer.end("Chrome MCP warmup retry timeout");
|
|
619
|
+
return { success: false, error: error2 };
|
|
620
|
+
}
|
|
621
|
+
const error = new import_shared.ChromeMcpWarmupError(
|
|
622
|
+
import_shared.ChromeMcpWarmupErrorType.UNKNOWN,
|
|
623
|
+
"Unknown error during Chrome MCP warmup retry",
|
|
624
|
+
errorMessage
|
|
625
|
+
);
|
|
626
|
+
log.warn("Chrome MCP warmup retry failed with unknown error", __spreadValues({
|
|
627
|
+
error: errorMessage
|
|
628
|
+
}, freeModel && {
|
|
629
|
+
model: `${freeModel.providerID}/${freeModel.modelID}`
|
|
630
|
+
}));
|
|
383
631
|
timer.end("Chrome MCP warmup retry failed");
|
|
384
|
-
return false;
|
|
632
|
+
return { success: false, error };
|
|
385
633
|
} finally {
|
|
386
634
|
if (warmupSessionId) {
|
|
387
635
|
try {
|