@lazyingart/agintiflow 0.20.169 → 0.20.170

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.
@@ -31,6 +31,8 @@ The npm trust setup may require the package to exist before trust can be attache
31
31
  4. Push the release commit and create a GitHub Release, or run the publish workflow manually.
32
32
  5. Confirm the npm package page shows provenance.
33
33
 
34
+ If local token publishing fails with `E401` or `E404`, do not treat that as terminal when Trusted Publishing is configured. Use the GitHub Actions workflow with an account that can dispatch workflows for `lazyingart/AgInTiFlow`, then verify the registry and install the published package. See `references/agintiflow-npm-publication-memory.md` for the 2026-05-20 `0.20.169` publication evidence and the known working command sequence.
35
+
34
36
  ## Local Token Fallback
35
37
 
36
38
  Trusted Publishing is preferred. A local automation token can be used only for bootstrap or emergency fallback:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.169",
3
+ "version": "0.20.170",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
package/public/app.js CHANGED
@@ -834,6 +834,7 @@ let selectedArtifactId = "";
834
834
  let currentArtifactTab = "canvas";
835
835
  let artifactUnreadCount = 0;
836
836
  let lastAnnouncedRunKey = "";
837
+ let quickVeniceModeActive = false;
837
838
 
838
839
  function normalizeLanguage(language) {
839
840
  const lower = String(language || "").toLowerCase();
@@ -1266,6 +1267,31 @@ function providerModelOptions(provider = providerField.value) {
1266
1267
  return (modelCatalog[provider] || []).filter((item) => !item.hidden);
1267
1268
  }
1268
1269
 
1270
+ function modelIdsForProvider(provider = "") {
1271
+ return new Set(providerModelOptions(provider).map((item) => String(item.id || "")));
1272
+ }
1273
+
1274
+ function modelDefaultValues() {
1275
+ return new Set(Object.values(defaults).filter(Boolean));
1276
+ }
1277
+
1278
+ function fallbackModelForProvider(provider = "deepseek", role = "primary") {
1279
+ if (provider === "deepseek" && role === "main") return "deepseek-v4-pro";
1280
+ if (provider === "deepseek") return "deepseek-v4-flash";
1281
+ if (provider === "openai" && role === "spare") return "gpt-5.4";
1282
+ return defaults[provider] || providerModelOptions(provider)[0]?.id || "";
1283
+ }
1284
+
1285
+ function coerceModelForProvider(provider = "deepseek", currentModel = "", fallbackModel = "") {
1286
+ const current = String(currentModel || "").trim();
1287
+ const fallback = String(fallbackModel || fallbackModelForProvider(provider)).trim();
1288
+ const providerModelIds = modelIdsForProvider(provider);
1289
+ const knownDefault = modelDefaultValues().has(current);
1290
+ const wrongProviderModel = providerModelIds.size > 0 && current && !providerModelIds.has(current);
1291
+ if (!current || knownDefault || wrongProviderModel) return fallback;
1292
+ return current;
1293
+ }
1294
+
1269
1295
  function mergeModelOptions(...groups) {
1270
1296
  const seen = new Set();
1271
1297
  const merged = [];
@@ -1327,24 +1353,32 @@ function setSelectOptions(select, options, selectedValue = "", fallbackValue = "
1327
1353
  function refreshModelDropdowns() {
1328
1354
  refreshProviderDropdowns();
1329
1355
  const provider = providerField?.value || "deepseek";
1330
- setSelectOptions(modelField, providerModelOptions(provider), fieldValue(modelField), defaults[provider]);
1356
+ setSelectOptions(
1357
+ modelField,
1358
+ providerModelOptions(provider),
1359
+ coerceModelForProvider(provider, fieldValue(modelField), fallbackModelForProvider(provider, "primary")),
1360
+ fallbackModelForProvider(provider, "primary")
1361
+ );
1362
+ const routeProvider = routeProviderField?.value || "deepseek";
1331
1363
  setSelectOptions(
1332
1364
  routeModelField,
1333
- providerModelOptions(routeProviderField?.value || "deepseek"),
1334
- fieldValue(routeModelField),
1335
- modelRoles.route?.model || "deepseek-v4-flash"
1365
+ providerModelOptions(routeProvider),
1366
+ coerceModelForProvider(routeProvider, fieldValue(routeModelField), fallbackModelForProvider(routeProvider, "route")),
1367
+ fallbackModelForProvider(routeProvider, "route")
1336
1368
  );
1369
+ const mainProvider = mainProviderField?.value || "deepseek";
1337
1370
  setSelectOptions(
1338
1371
  mainModelField,
1339
- providerModelOptions(mainProviderField?.value || "deepseek"),
1340
- fieldValue(mainModelField),
1341
- modelRoles.main?.model || "deepseek-v4-pro"
1372
+ providerModelOptions(mainProvider),
1373
+ coerceModelForProvider(mainProvider, fieldValue(mainModelField), fallbackModelForProvider(mainProvider, "main")),
1374
+ fallbackModelForProvider(mainProvider, "main")
1342
1375
  );
1376
+ const spareProvider = spareProviderField?.value || "openai";
1343
1377
  setSelectOptions(
1344
1378
  spareModelField,
1345
- providerModelOptions(spareProviderField?.value || "openai"),
1346
- fieldValue(spareModelField),
1347
- modelRoles.spare?.model || "gpt-5.4"
1379
+ providerModelOptions(spareProvider),
1380
+ coerceModelForProvider(spareProvider, fieldValue(spareModelField), fallbackModelForProvider(spareProvider, "spare")),
1381
+ fallbackModelForProvider(spareProvider, "spare")
1348
1382
  );
1349
1383
  setSelectOptions(wrapperModelField, wrapperModelOptions(), fieldValue(wrapperModelField), modelRoles.wrapper?.model || "gpt-5.5");
1350
1384
  setSelectOptions(
@@ -1364,13 +1398,9 @@ function selectedVeniceTextModel() {
1364
1398
  );
1365
1399
  }
1366
1400
 
1367
- function inferVeniceMode() {
1368
- return [providerField?.value, routeProviderField?.value, mainProviderField?.value].includes("venice");
1369
- }
1370
-
1371
1401
  function syncQuickModeControls() {
1372
1402
  if (aapsModeToggle) aapsModeToggle.checked = (taskProfileField?.value || "auto") === "aaps";
1373
- if (veniceModeToggle) veniceModeToggle.checked = inferVeniceMode();
1403
+ if (veniceModeToggle) veniceModeToggle.checked = quickVeniceModeActive;
1374
1404
  if (quickModeStatusEl) {
1375
1405
  const scs = enableScsField?.value || "on";
1376
1406
  const profile = taskProfileField?.value || "auto";
@@ -1388,10 +1418,13 @@ function applyAapsMode(enabled) {
1388
1418
  }
1389
1419
 
1390
1420
  function applyVeniceMode(enabled) {
1421
+ quickVeniceModeActive = Boolean(enabled);
1391
1422
  if (enabled) {
1392
1423
  const model = selectedVeniceTextModel();
1393
1424
  routingModeField.value = "smart";
1394
- providerField.value = "deepseek";
1425
+ providerField.value = "venice";
1426
+ refreshModelDropdowns();
1427
+ if (modelField) setSelectOptions(modelField, providerModelOptions("venice"), model, defaults.venice);
1395
1428
  if (routeProviderField) routeProviderField.value = "venice";
1396
1429
  refreshModelDropdowns();
1397
1430
  if (routeModelField) setSelectOptions(routeModelField, providerModelOptions("venice"), model, defaults.venice);
@@ -1400,10 +1433,13 @@ function applyVeniceMode(enabled) {
1400
1433
  if (mainModelField) setSelectOptions(mainModelField, providerModelOptions("venice"), model, defaults.venice);
1401
1434
  } else {
1402
1435
  routingModeField.value = "smart";
1403
- providerField.value = "deepseek";
1436
+ if (providerField?.value === "venice") providerField.value = "deepseek";
1404
1437
  if (routeProviderField?.value === "venice") routeProviderField.value = "deepseek";
1405
1438
  if (mainProviderField?.value === "venice") mainProviderField.value = "deepseek";
1406
1439
  refreshModelDropdowns();
1440
+ if (modelField && providerField?.value === "deepseek") {
1441
+ setSelectOptions(modelField, providerModelOptions("deepseek"), "deepseek-v4-flash", "deepseek-v4-flash");
1442
+ }
1407
1443
  if (routeModelField && routeProviderField?.value === "deepseek") {
1408
1444
  setSelectOptions(routeModelField, providerModelOptions("deepseek"), "deepseek-v4-flash", "deepseek-v4-flash");
1409
1445
  }
@@ -1673,6 +1709,7 @@ function formPayload() {
1673
1709
  allowParallelScouts: allowParallelScoutsField?.checked ?? true,
1674
1710
  enableScs: enableScsField?.value || "on",
1675
1711
  dynamicSteps: dynamicStepsField?.value || "auto",
1712
+ veniceMode: quickVeniceModeActive,
1676
1713
  parallelScoutCount: Math.min(Math.max(Number(parallelScoutCountField?.value) || 3, 1), 10),
1677
1714
  allowWrapperTools: allowWrapperToolsField.checked,
1678
1715
  preferredWrapper: preferredWrapperField.value,
@@ -3122,16 +3159,8 @@ providerField.addEventListener("change", () => {
3122
3159
  routingModeField.value = "manual";
3123
3160
  }
3124
3161
 
3125
- if (
3126
- !fieldValue(modelField) ||
3127
- modelField.value === defaults.openai ||
3128
- modelField.value === defaults.deepseek ||
3129
- modelField.value === defaults.qwen ||
3130
- modelField.value === defaults.venice ||
3131
- modelField.value === defaults.mock
3132
- ) {
3133
- modelField.value = defaults[providerField.value] || "";
3134
- }
3162
+ if (providerField.value !== "venice") quickVeniceModeActive = false;
3163
+ refreshModelDropdowns();
3135
3164
  updateRoutingHint();
3136
3165
  syncQuickModeControls();
3137
3166
  schedulePreferenceSave();
@@ -3394,6 +3423,7 @@ async function loadConfig() {
3394
3423
  defaults.mock = data.defaults?.mock?.model || defaults.mock;
3395
3424
 
3396
3425
  applyLanguage(prefs.language || normalizeLanguage(navigator.language || "en"), { persist: false });
3426
+ quickVeniceModeActive = prefs.veniceMode === true;
3397
3427
  refreshProviderDropdowns();
3398
3428
 
3399
3429
  routingModeField.value = prefs.routingMode || "smart";
@@ -3404,24 +3434,41 @@ async function loadConfig() {
3404
3434
  if (spareReasoningField) spareReasoningField.value = prefs.spareReasoning || modelRoles.spare?.reasoning || "medium";
3405
3435
  if (wrapperReasoningField) wrapperReasoningField.value = prefs.wrapperReasoning || modelRoles.wrapper?.reasoning || "medium";
3406
3436
  if (auxiliaryProviderField) auxiliaryProviderField.value = prefs.auxiliaryProvider || modelRoles.auxiliary?.provider || "grsai";
3407
- setSelectOptions(modelField, providerModelOptions(providerField.value), prefs.model || defaults[providerField.value], defaults[providerField.value]);
3437
+ setSelectOptions(
3438
+ modelField,
3439
+ providerModelOptions(providerField.value),
3440
+ coerceModelForProvider(providerField.value, prefs.model, fallbackModelForProvider(providerField.value, "primary")),
3441
+ fallbackModelForProvider(providerField.value, "primary")
3442
+ );
3408
3443
  setSelectOptions(
3409
3444
  routeModelField,
3410
3445
  providerModelOptions(routeProviderField?.value || "deepseek"),
3411
- prefs.routeModel || modelRoles.route?.model,
3412
- "deepseek-v4-flash"
3446
+ coerceModelForProvider(
3447
+ routeProviderField?.value || "deepseek",
3448
+ prefs.routeModel || modelRoles.route?.model,
3449
+ fallbackModelForProvider(routeProviderField?.value || "deepseek", "route")
3450
+ ),
3451
+ fallbackModelForProvider(routeProviderField?.value || "deepseek", "route")
3413
3452
  );
3414
3453
  setSelectOptions(
3415
3454
  mainModelField,
3416
3455
  providerModelOptions(mainProviderField?.value || "deepseek"),
3417
- prefs.mainModel || modelRoles.main?.model,
3418
- "deepseek-v4-pro"
3456
+ coerceModelForProvider(
3457
+ mainProviderField?.value || "deepseek",
3458
+ prefs.mainModel || modelRoles.main?.model,
3459
+ fallbackModelForProvider(mainProviderField?.value || "deepseek", "main")
3460
+ ),
3461
+ fallbackModelForProvider(mainProviderField?.value || "deepseek", "main")
3419
3462
  );
3420
3463
  setSelectOptions(
3421
3464
  spareModelField,
3422
3465
  providerModelOptions(spareProviderField?.value || "openai"),
3423
- prefs.spareModel || modelRoles.spare?.model,
3424
- "gpt-5.4"
3466
+ coerceModelForProvider(
3467
+ spareProviderField?.value || "openai",
3468
+ prefs.spareModel || modelRoles.spare?.model,
3469
+ fallbackModelForProvider(spareProviderField?.value || "openai", "spare")
3470
+ ),
3471
+ fallbackModelForProvider(spareProviderField?.value || "openai", "spare")
3425
3472
  );
3426
3473
  setSelectOptions(wrapperModelField, wrapperModelOptions(), prefs.wrapperModel || modelRoles.wrapper?.model, "gpt-5.5");
3427
3474
  setSelectOptions(
@@ -3463,6 +3510,7 @@ async function loadConfig() {
3463
3510
  renderMcpPanel(data.mcp || null);
3464
3511
  await refreshWorkspaceChanges();
3465
3512
  renderSandboxLogs(data.sandbox?.logs || []);
3513
+ if (quickVeniceModeActive) applyVeniceMode(true);
3466
3514
  updateRoutingHint();
3467
3515
  updatePermissionHint();
3468
3516
  updatePackageWarning();
@@ -0,0 +1,89 @@
1
+ # AgInTiFlow npm Publication Memory
2
+
3
+ Date: 2026-05-20
4
+
5
+ This note records the working publication route for AgInTiFlow so future release work does not get blocked by stale local npm tokens or repeated discussion about why direct `npm publish` failed.
6
+
7
+ ## Published Evidence
8
+
9
+ - Package: `@lazyingart/agintiflow`
10
+ - Version: `0.20.169`
11
+ - Commit: `6ef3768`
12
+ - GitHub Actions run: `https://github.com/lazyingart/AgInTiFlow/actions/runs/26149627377`
13
+ - Workflow result: success
14
+ - npm registry check:
15
+
16
+ ```bash
17
+ npm view @lazyingart/agintiflow version dist-tags.latest --registry=https://registry.npmjs.org
18
+ ```
19
+
20
+ Expected result:
21
+
22
+ ```text
23
+ version = '0.20.169'
24
+ dist-tags.latest = '0.20.169'
25
+ ```
26
+
27
+ Installed verification:
28
+
29
+ ```bash
30
+ npm install -g @lazyingart/agintiflow@0.20.169
31
+ aginti --version
32
+ aginti webapp restart --port 3210
33
+ curl -fsS http://127.0.0.1:3210/health
34
+ ```
35
+
36
+ Expected result:
37
+
38
+ ```text
39
+ 0.20.169
40
+ ```
41
+
42
+ The health endpoint should report `version":"0.20.169"` and a global npm package path.
43
+
44
+ ## Working Publication Route
45
+
46
+ Use GitHub Actions Trusted Publishing as the primary route.
47
+
48
+ Workflow:
49
+
50
+ - `.github/workflows/npm-publish.yml`
51
+ - permissions include `id-token: write`
52
+ - publish command uses `npm publish --access public --provenance`
53
+
54
+ The successful dispatch used the configured `lazyingart` GitHub CLI account because the default `lachlanchen` account has `workflow` scope but does not have repository admin permission for workflow dispatch on `lazyingart/AgInTiFlow`.
55
+
56
+ Reliable command sequence:
57
+
58
+ ```bash
59
+ cd /home/lachlan/ProjectsLFS/Agent/AgInTiFlow
60
+ git status --short
61
+ npm test
62
+ npm pack --dry-run
63
+ git push
64
+ gh auth switch -u lazyingart
65
+ gh workflow run npm-publish.yml --ref main
66
+ gh run watch <run-id> --exit-status
67
+ npm view @lazyingart/agintiflow version dist-tags.latest --registry=https://registry.npmjs.org
68
+ npm install -g @lazyingart/agintiflow@<version>
69
+ aginti --version
70
+ aginti webapp restart --port 3210
71
+ curl -fsS http://127.0.0.1:3210/health
72
+ gh auth switch -u lachlanchen
73
+ ```
74
+
75
+ Do not print tokens. Do not copy token values into notes, logs, or final answers.
76
+
77
+ ## Local Token Failure Is Not Terminal
78
+
79
+ On 2026-05-20, the env-based local publish path failed:
80
+
81
+ - `npm whoami` through the env publish script returned `E401`.
82
+ - direct publish returned `E404 PUT https://registry.npmjs.org/@lazyingart%2fagintiflow`.
83
+ - the registry still showed the prior version until the trusted-publishing workflow was dispatched.
84
+
85
+ Treat this as an auth/scope problem in local npm credentials, not as a package or registry existence problem. When this happens, use GitHub Trusted Publishing before spending time debating the local token path.
86
+
87
+ ## Operational Rule
88
+
89
+ For future AgInTiFlow releases, do not stop after local token publish failure if the trusted-publishing workflow is available. Trigger the trusted-publishing workflow with the owner account, watch it, verify npm, install globally, restart the webapp, and only then report completion.
@@ -119,6 +119,7 @@ try {
119
119
  if (config.preferences?.workspaceWritePolicy !== "allow") throw new Error("web did not default to workspace writes allowed");
120
120
  if (config.preferences?.enableScs !== "on") throw new Error("web did not default to CLI-aligned SCS on mode");
121
121
  if (config.preferences?.dynamicSteps !== "auto") throw new Error("web did not default to CLI-aligned dynamic steps auto mode");
122
+ if (config.preferences?.veniceMode !== false) throw new Error("web should default Venice shortcut mode off");
122
123
  if (Number(config.preferences?.maxSteps) < 24) throw new Error("web default max steps is too low");
123
124
  if (!Array.isArray(config.taskProfiles) || !config.taskProfiles.some((profile) => profile.id === "latex")) {
124
125
  throw new Error("task profiles are not advertised by /api/config");
@@ -94,17 +94,38 @@ try {
94
94
  await page.waitForFunction(() => document.querySelectorAll("#command-cwd-suggestions option").length > 0);
95
95
  if ((await page.locator(".project-status-chip").count()) < 4) throw new Error("project folder status did not render structured chips");
96
96
  await page.locator("#run-defaults-card summary").click();
97
+ if (await page.locator("#veniceModeToggle").isChecked()) throw new Error("Venice quick mode should default off");
98
+ if ((await page.locator("#routeProvider").inputValue()) !== "deepseek") throw new Error("route provider should default to DeepSeek");
99
+ if ((await page.locator("#mainProvider").inputValue()) !== "deepseek") throw new Error("main provider should default to DeepSeek");
97
100
 
98
101
  await page.selectOption("#enableScs", "auto");
99
102
  await page.locator("label:has(#aapsModeToggle)").click();
100
103
  if ((await page.locator("#taskProfile").inputValue()) !== "aaps") throw new Error("AAPS toggle did not select the AAPS task profile");
101
104
  await page.locator("label:has(#veniceModeToggle)").click();
105
+ if ((await page.locator("#provider").inputValue()) !== "venice") throw new Error("Venice toggle did not set primary provider");
106
+ if (!/^venice|^e2ee|^gemma|^qwen|^openai|^claude/.test(await page.locator("#model").inputValue())) {
107
+ throw new Error(`Venice toggle did not update primary model: ${await page.locator("#model").inputValue()}`);
108
+ }
102
109
  if ((await page.locator("#routeProvider").inputValue()) !== "venice") throw new Error("Venice toggle did not set route provider");
103
110
  if ((await page.locator("#mainProvider").inputValue()) !== "venice") throw new Error("Venice toggle did not set main provider");
111
+ if (!/^venice|^e2ee|^gemma|^qwen|^openai|^claude/.test(await page.locator("#routeModel").inputValue())) {
112
+ throw new Error(`Venice toggle did not update route model: ${await page.locator("#routeModel").inputValue()}`);
113
+ }
114
+ if (!/^venice|^e2ee|^gemma|^qwen|^openai|^claude/.test(await page.locator("#mainModel").inputValue())) {
115
+ throw new Error(`Venice toggle did not update main model: ${await page.locator("#mainModel").inputValue()}`);
116
+ }
104
117
  const quickStatus = await page.locator("#quick-mode-status").innerText();
105
118
  if (!/scs=auto/.test(quickStatus) || !/profile=aaps/.test(quickStatus) || !/route venice\//.test(quickStatus)) {
106
119
  throw new Error(`quick mode status did not reflect CLI modes: ${quickStatus}`);
107
120
  }
121
+ await page.locator("label:has(#veniceModeToggle)").click();
122
+ if (await page.locator("#veniceModeToggle").isChecked()) throw new Error("Venice quick mode did not turn off");
123
+ if ((await page.locator("#provider").inputValue()) !== "deepseek") throw new Error("Venice off did not restore primary provider");
124
+ if ((await page.locator("#model").inputValue()) !== "deepseek-v4-flash") throw new Error("Venice off did not restore primary model");
125
+ if ((await page.locator("#routeProvider").inputValue()) !== "deepseek") throw new Error("Venice off did not restore route provider");
126
+ if ((await page.locator("#routeModel").inputValue()) !== "deepseek-v4-flash") throw new Error("Venice off did not restore route model");
127
+ if ((await page.locator("#mainProvider").inputValue()) !== "deepseek") throw new Error("Venice off did not restore main provider");
128
+ if ((await page.locator("#mainModel").inputValue()) !== "deepseek-v4-pro") throw new Error("Venice off did not restore main model");
108
129
  const quickBoxes = await Promise.all([
109
130
  page.locator(".quick-mode-select").boundingBox(),
110
131
  page.locator("label:has(#aapsModeToggle)").boundingBox(),
@@ -136,8 +157,8 @@ try {
136
157
  if (firstPayload.dynamicSteps !== "off") {
137
158
  throw new Error(`dynamic steps payload mismatch: ${runPayloads.at(-1) || ""}`);
138
159
  }
139
- if (firstPayload.routeProvider !== "venice" || firstPayload.mainProvider !== "venice") {
140
- throw new Error(`Venice route/main payload mismatch: ${runPayloads.at(-1) || ""}`);
160
+ if (firstPayload.veniceMode !== false || firstPayload.routeProvider !== "deepseek" || firstPayload.mainProvider !== "deepseek") {
161
+ throw new Error(`default route/main payload mismatch after Venice off: ${runPayloads.at(-1) || ""}`);
141
162
  }
142
163
  await waitForRunState(page, "running");
143
164
  if (!(await page.locator("#stop-run").isVisible())) throw new Error("stop button did not appear while run was active");
@@ -176,6 +197,9 @@ try {
176
197
  "working-directory-search-top",
177
198
  "project-status-chips",
178
199
  "run-defaults-folded",
200
+ "venice-mode-default-off",
201
+ "venice-mode-model-sync",
202
+ "venice-mode-off-restores-deepseek",
179
203
  "quick-scs-aaps-venice-controls",
180
204
  "quick-mode-control-alignment",
181
205
  "dynamic-steps-dropdown",
package/src/web-db.js CHANGED
@@ -7,7 +7,7 @@ import { deleteSessionIndex, renameSessionIndex, upsertSessionIndex } from "./se
7
7
  import { loadDatabaseSync } from "./sqlite.js";
8
8
  import { permissionModeDefaults } from "./permission-modes.js";
9
9
 
10
- const PREFERENCES_SCHEMA_VERSION = 9;
10
+ const PREFERENCES_SCHEMA_VERSION = 10;
11
11
 
12
12
  function jsonStatePath(dbPath) {
13
13
  return dbPath.replace(/\.sqlite$/i, ".json");
@@ -73,6 +73,7 @@ function defaultPreferences(baseDir) {
73
73
  allowParallelScouts: true,
74
74
  enableScs: process.env.AGINTI_SCS_MODE || "on",
75
75
  dynamicSteps: process.env.AGINTI_DYNAMIC_STEPS || "auto",
76
+ veniceMode: false,
76
77
  parallelScoutCount: 3,
77
78
  allowWrapperTools: false,
78
79
  preferredWrapper: "codex",
@@ -228,6 +229,20 @@ export class WebDatabase {
228
229
  preferences.enableScs = preferences.enableScs || process.env.AGINTI_SCS_MODE || "on";
229
230
  preferences.dynamicSteps = preferences.dynamicSteps || process.env.AGINTI_DYNAMIC_STEPS || "auto";
230
231
  }
232
+ if ((parsed.preferencesSchemaVersion || 1) < 10) {
233
+ preferences.veniceMode = false;
234
+ const legacyQuickVenice =
235
+ (parsed.routingMode || preferences.routingMode) === "smart" &&
236
+ (parsed.provider || preferences.provider) === "deepseek" &&
237
+ (parsed.routeProvider || preferences.routeProvider) === "venice" &&
238
+ (parsed.mainProvider || preferences.mainProvider) === "venice";
239
+ if (legacyQuickVenice) {
240
+ preferences.routeProvider = "deepseek";
241
+ preferences.routeModel = "deepseek-v4-flash";
242
+ preferences.mainProvider = "deepseek";
243
+ preferences.mainModel = "deepseek-v4-pro";
244
+ }
245
+ }
231
246
  this.savePreferences(preferences);
232
247
  }
233
248
  return preferences;
package/web.js CHANGED
@@ -282,6 +282,7 @@ function normalizePreferencePayload(body = {}, current = db.getPreferences()) {
282
282
  typeof body.allowParallelScouts === "boolean" ? body.allowParallelScouts : current.allowParallelScouts !== false,
283
283
  enableScs: normalizeScsMode(body.enableScs || current.enableScs || process.env.AGINTI_SCS_MODE || "on"),
284
284
  dynamicSteps: normalizeDynamicStepsMode(body.dynamicSteps || current.dynamicSteps || process.env.AGINTI_DYNAMIC_STEPS || "auto"),
285
+ veniceMode: typeof body.veniceMode === "boolean" ? body.veniceMode : current.veniceMode === true,
285
286
  parallelScoutCount:
286
287
  Number.isFinite(parsedParallelScoutCount) && parsedParallelScoutCount > 0
287
288
  ? Math.min(Math.max(parsedParallelScoutCount, 1), 10)