vg-coder-cli 2.0.59 → 2.0.61
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/package.json
CHANGED
package/src/server/task-queue.js
CHANGED
|
@@ -163,7 +163,13 @@ class TaskQueue {
|
|
|
163
163
|
if (wasUnknown && email !== existing.email) {
|
|
164
164
|
// shouldn't happen — kept for clarity (email already assigned above)
|
|
165
165
|
}
|
|
166
|
-
|
|
166
|
+
// Re-establish pin từ URL hiện tại của tab worker. Khắc phục race khi
|
|
167
|
+
// open-tab handler set _pinnedModelByEmail nhưng launcher email lúc đó
|
|
168
|
+
// null (chưa scrape) → pin bị mất → recycle reopen với default.
|
|
169
|
+
if (meta?.pinnedModel && !email.startsWith('unknown:')) {
|
|
170
|
+
this._pinnedModelByEmail.set(email, meta.pinnedModel);
|
|
171
|
+
}
|
|
172
|
+
console.log(chalk.green(`[TaskQueue] Worker re-register: ${socket.id} (${email})${meta?.pinnedModel ? ` pinned=${meta.pinnedModel}` : ''}`));
|
|
167
173
|
setImmediate(() => this._drain());
|
|
168
174
|
return true;
|
|
169
175
|
}
|
|
@@ -184,7 +190,11 @@ class TaskQueue {
|
|
|
184
190
|
if (meta?.chromeId && email && !email.startsWith('unknown:')) {
|
|
185
191
|
this._bindChromeIdToEmail(meta.chromeId, email);
|
|
186
192
|
}
|
|
187
|
-
|
|
193
|
+
// Re-establish pin từ URL hiện tại (xem comment ở re-register branch).
|
|
194
|
+
if (meta?.pinnedModel && !email.startsWith('unknown:')) {
|
|
195
|
+
this._pinnedModelByEmail.set(email, meta.pinnedModel);
|
|
196
|
+
}
|
|
197
|
+
console.log(chalk.green(`[TaskQueue] Worker registered: ${socket.id} (${email})${meta?.pinnedModel ? ` pinned=${meta.pinnedModel}` : ''}`));
|
|
188
198
|
setImmediate(() => this._drain());
|
|
189
199
|
return true;
|
|
190
200
|
}
|
|
@@ -199,7 +199,7 @@ function throwIfRateLimited(stage = '') {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
// Đọc model ID thật từ AI Studio sidebar — bắt được redirect AI Studio làm khi
|
|
202
|
-
// account thiếu access tới preview model (vd request gemini-3-pro-preview, run
|
|
202
|
+
// account thiếu access tới preview model (vd request gemini-3.1-pro-preview, run
|
|
203
203
|
// thật trên gemini-3-flash-preview). URL param không reliable vì AI Studio
|
|
204
204
|
// không update URL khi fallback. Sidebar `<ms-model-selector>` mới là source-
|
|
205
205
|
// of-truth.
|
|
@@ -256,6 +256,18 @@ async function handleTaskExecute(payload) {
|
|
|
256
256
|
}
|
|
257
257
|
await new Promise(r => setTimeout(r, 600)); // settle after navigation
|
|
258
258
|
|
|
259
|
+
// 1b. Pre-flight model check: AI Studio có thể fallback sang paid agent
|
|
260
|
+
// (vd "deep-research-preview-04-2026") khi pin model không có access.
|
|
261
|
+
// Submit task lên Deep Research → rate limit ngay (paid quota), URL không
|
|
262
|
+
// có ?model= để recycle pin lại → loop fail. Fail-fast nếu detect agent
|
|
263
|
+
// không phải gemini.
|
|
264
|
+
const preFlightModel = await readActualModel();
|
|
265
|
+
if (preFlightModel && !/^gemini[-.]/i.test(preFlightModel)) {
|
|
266
|
+
const e = new Error(`Worker tab loaded non-Gemini model: ${preFlightModel}. Pin model unavailable for this account.`);
|
|
267
|
+
e.code = 'model_unavailable';
|
|
268
|
+
throw e;
|
|
269
|
+
}
|
|
270
|
+
|
|
259
271
|
if (cancelFlags.has(taskId)) {
|
|
260
272
|
cancelFlags.delete(taskId);
|
|
261
273
|
console.log(`[TaskWorker] ${taskId} canceled before send — skipping`);
|
|
@@ -347,12 +359,20 @@ function connect() {
|
|
|
347
359
|
// Register with whatever email we have right now (may be null on cold load).
|
|
348
360
|
const initialEmail = extractEmail();
|
|
349
361
|
const chromeId = (window.vetgo && window.vetgo.chromeId) || null;
|
|
362
|
+
// pinnedModel: lấy từ URL ?model=X — server dùng để re-establish pin
|
|
363
|
+
// sau khi worker register với email thật (không lúc open-tab vì lúc đó
|
|
364
|
+
// launcher có thể chưa scrape email).
|
|
365
|
+
const pinnedModel = (() => {
|
|
366
|
+
try { return new URLSearchParams(location.search).get('model') || null; }
|
|
367
|
+
catch (_) { return null; }
|
|
368
|
+
})();
|
|
350
369
|
socket.emit('worker:register', {
|
|
351
370
|
domain: location.hostname,
|
|
352
371
|
chatId: window.AIChat?.getChatIdFromUrl?.() || null,
|
|
353
372
|
userAgent: navigator.userAgent,
|
|
354
373
|
email: initialEmail,
|
|
355
|
-
chromeId
|
|
374
|
+
chromeId,
|
|
375
|
+
pinnedModel
|
|
356
376
|
});
|
|
357
377
|
console.log(`[TaskWorker] Initial email: ${initialEmail || '(pending)'}, chromeId: ${chromeId || '(none)'}`);
|
|
358
378
|
|
|
@@ -368,14 +388,19 @@ function connect() {
|
|
|
368
388
|
try {
|
|
369
389
|
const resolved = await resolveEmail(3000, emailAbort?.signal);
|
|
370
390
|
if (!resolved || !socket.connected) return;
|
|
391
|
+
const pm = (() => {
|
|
392
|
+
try { return new URLSearchParams(location.search).get('model') || null; }
|
|
393
|
+
catch (_) { return null; }
|
|
394
|
+
})();
|
|
371
395
|
socket.emit('worker:register', {
|
|
372
396
|
domain: location.hostname,
|
|
373
397
|
chatId: window.AIChat?.getChatIdFromUrl?.() || null,
|
|
374
398
|
userAgent: navigator.userAgent,
|
|
375
399
|
email: resolved,
|
|
376
|
-
chromeId: (window.vetgo && window.vetgo.chromeId) || null
|
|
400
|
+
chromeId: (window.vetgo && window.vetgo.chromeId) || null,
|
|
401
|
+
pinnedModel: pm
|
|
377
402
|
});
|
|
378
|
-
console.log(`[TaskWorker] Re-registered with email: ${resolved}`);
|
|
403
|
+
console.log(`[TaskWorker] Re-registered with email: ${resolved} (pinnedModel=${pm || 'none'})`);
|
|
379
404
|
} catch (err) {
|
|
380
405
|
console.error('[TaskWorker] Email retry failed:', err);
|
|
381
406
|
}
|