@lazyingart/agintiflow 0.20.166 → 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.
- package/docs/npm-publishing.md +2 -0
- package/package.json +1 -1
- package/public/app.js +194 -55
- package/public/index.html +37 -17
- package/public/styles.css +194 -14
- package/references/agintiflow-npm-publication-memory.md +89 -0
- package/scripts/smoke-cli-chat.js +60 -0
- package/scripts/smoke-web-api.js +7 -2
- package/scripts/smoke-web-ui.js +49 -2
- package/scripts/smoke-webapp-command.js +21 -11
- package/src/interactive-cli.js +16 -0
- package/src/web-autostart.js +2 -1
- package/src/web-db.js +16 -1
- package/web.js +89 -0
package/docs/npm-publishing.md
CHANGED
|
@@ -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.
|
|
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
|
@@ -52,6 +52,7 @@ const translations = {
|
|
|
52
52
|
goalPlaceholder: "Open a site and summarize it, or use run_command for simple terminal inspection.",
|
|
53
53
|
runDefaultsTitle: "Run defaults",
|
|
54
54
|
runDefaultsHelp: "The chat box is the first goal for a new run. These controls set how that run starts.",
|
|
55
|
+
runDefaultsFoldHint: "Routing, safety, tool toggles, and key status.",
|
|
55
56
|
scsModeLabel: "SCS",
|
|
56
57
|
scsOnOption: "On",
|
|
57
58
|
scsAutoOption: "Auto",
|
|
@@ -64,6 +65,8 @@ const translations = {
|
|
|
64
65
|
allowedDomainsLabel: "Allowed domains",
|
|
65
66
|
allowedDomainsPlaceholder: "news.ycombinator.com,github.com",
|
|
66
67
|
commandCwdLabel: "Working directory",
|
|
68
|
+
commandCwdHelp: "Runs start from this working directory.",
|
|
69
|
+
commandCwdPlaceholder: "/home/user/project",
|
|
67
70
|
maxStepsLabel: "Max steps",
|
|
68
71
|
sandboxModeLabel: "Sandbox mode",
|
|
69
72
|
permissionModeLabel: "Permission shortcut",
|
|
@@ -718,6 +721,8 @@ const setupApiKeyField = document.querySelector("#setup-api-key");
|
|
|
718
721
|
const saveApiKeyButton = document.querySelector("#save-api-key");
|
|
719
722
|
const setupStatusEl = document.querySelector("#setup-status");
|
|
720
723
|
const taskProfileField = document.querySelector("#taskProfile");
|
|
724
|
+
const commandCwdField = document.querySelector("#commandCwd");
|
|
725
|
+
const commandCwdSuggestionsEl = document.querySelector("#command-cwd-suggestions");
|
|
721
726
|
const permissionModeField = document.querySelector("#permissionMode");
|
|
722
727
|
const permissionHintEl = document.querySelector("#permission-hint");
|
|
723
728
|
const sandboxModeField = document.querySelector("#sandboxMode");
|
|
@@ -727,6 +732,7 @@ const logsEl = document.querySelector("#logs");
|
|
|
727
732
|
const runMetaEl = document.querySelector("#run-meta");
|
|
728
733
|
const stopRunButton = document.querySelector("#stop-run");
|
|
729
734
|
const keyStatusEl = document.querySelector("#key-status");
|
|
735
|
+
const keyStatusListEl = document.querySelector("#key-status-list");
|
|
730
736
|
const allowAuxiliaryToolsField = document.querySelector("#allowAuxiliaryTools");
|
|
731
737
|
const allowWebSearchField = document.querySelector("#allowWebSearch");
|
|
732
738
|
const allowMcpToolsField = document.querySelector("#allowMcpTools");
|
|
@@ -828,6 +834,7 @@ let selectedArtifactId = "";
|
|
|
828
834
|
let currentArtifactTab = "canvas";
|
|
829
835
|
let artifactUnreadCount = 0;
|
|
830
836
|
let lastAnnouncedRunKey = "";
|
|
837
|
+
let quickVeniceModeActive = false;
|
|
831
838
|
|
|
832
839
|
function normalizeLanguage(language) {
|
|
833
840
|
const lower = String(language || "").toLowerCase();
|
|
@@ -928,31 +935,99 @@ function setRunStatus(status = "", { sessionId, detail = "", announce = false }
|
|
|
928
935
|
function renderKeyStatus(status = lastKeyStatus) {
|
|
929
936
|
lastKeyStatus = status;
|
|
930
937
|
if (!status) return;
|
|
931
|
-
|
|
932
|
-
status.openai
|
|
933
|
-
|
|
934
|
-
status.qwen
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
938
|
+
const providers = [
|
|
939
|
+
["OpenAI", status.openai],
|
|
940
|
+
["DeepSeek", status.deepseek],
|
|
941
|
+
["Qwen", status.qwen],
|
|
942
|
+
["Venice", status.venice],
|
|
943
|
+
["GRS AI", status.grsai],
|
|
944
|
+
[t("mockLabel"), status.mock],
|
|
945
|
+
];
|
|
946
|
+
const available = providers.filter(([, ready]) => Boolean(ready)).length;
|
|
947
|
+
if (keyStatusEl) {
|
|
948
|
+
keyStatusEl.textContent = `${t("keysLabel")} ${available}/${providers.length}`;
|
|
949
|
+
keyStatusEl.dataset.ready = String(available > 0);
|
|
950
|
+
}
|
|
951
|
+
if (keyStatusListEl) {
|
|
952
|
+
keyStatusListEl.replaceChildren(
|
|
953
|
+
...providers.map(([name, ready]) => {
|
|
954
|
+
const chip = document.createElement("div");
|
|
955
|
+
chip.className = "key-status-chip";
|
|
956
|
+
chip.dataset.ready = String(Boolean(ready));
|
|
957
|
+
const title = document.createElement("strong");
|
|
958
|
+
title.textContent = name;
|
|
959
|
+
const value = document.createElement("span");
|
|
960
|
+
value.textContent = ready ? t("availableLabel") : t("missingLabel");
|
|
961
|
+
chip.append(title, value);
|
|
962
|
+
return chip;
|
|
963
|
+
})
|
|
964
|
+
);
|
|
965
|
+
}
|
|
942
966
|
if (setupCardEl) setupCardEl.hidden = Boolean(status.openai || status.deepseek || status.qwen || status.venice);
|
|
943
967
|
}
|
|
944
968
|
|
|
945
969
|
function renderProjectStatus(info = projectInfo) {
|
|
946
970
|
projectInfo = info;
|
|
947
971
|
if (!projectStatusEl || !info) return;
|
|
948
|
-
|
|
949
|
-
info.platform?.label
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
].
|
|
972
|
+
const rows = [
|
|
973
|
+
["OS", info.platform?.label || ""],
|
|
974
|
+
["Root", info.root || ""],
|
|
975
|
+
["CWD", info.commandCwd || ""],
|
|
976
|
+
["Sessions", info.sessionsDir || ""],
|
|
977
|
+
["Database", info.sessionDbPath || ""],
|
|
978
|
+
["Shared", info.sharedSessionFolder ? "yes" : "no"],
|
|
979
|
+
].filter(([, value]) => value !== "");
|
|
980
|
+
projectStatusEl.replaceChildren(
|
|
981
|
+
...rows.map(([label, value]) => {
|
|
982
|
+
const chip = document.createElement("div");
|
|
983
|
+
chip.className = "project-status-chip";
|
|
984
|
+
if (String(value).length > 54) chip.dataset.wide = "true";
|
|
985
|
+
const title = document.createElement("strong");
|
|
986
|
+
title.textContent = label;
|
|
987
|
+
const body = document.createElement("span");
|
|
988
|
+
body.textContent = value;
|
|
989
|
+
chip.append(title, body);
|
|
990
|
+
return chip;
|
|
991
|
+
})
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
function baseDirectorySuggestions(info = projectInfo) {
|
|
996
|
+
const projectLfsRoot = info?.root?.includes("/ProjectsLFS/")
|
|
997
|
+
? `${info.root.split("/ProjectsLFS/")[0]}/ProjectsLFS`
|
|
998
|
+
: "";
|
|
999
|
+
const values = [
|
|
1000
|
+
info?.commandCwd,
|
|
1001
|
+
info?.root,
|
|
1002
|
+
info?.sessionsDir ? info.sessionsDir.replace(/\/\.agintiflow\/sessions$/, "") : "",
|
|
1003
|
+
projectLfsRoot,
|
|
1004
|
+
].filter(Boolean);
|
|
1005
|
+
return [...new Set(values)];
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
function renderCommandCwdSuggestions(suggestions = []) {
|
|
1009
|
+
if (!commandCwdSuggestionsEl) return;
|
|
1010
|
+
commandCwdSuggestionsEl.replaceChildren(
|
|
1011
|
+
...suggestions.slice(0, 16).map((value) => {
|
|
1012
|
+
const option = document.createElement("option");
|
|
1013
|
+
option.value = value;
|
|
1014
|
+
return option;
|
|
1015
|
+
})
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
async function refreshCommandCwdSuggestions(query = "") {
|
|
1020
|
+
const fallback = baseDirectorySuggestions();
|
|
1021
|
+
renderCommandCwdSuggestions(fallback);
|
|
1022
|
+
try {
|
|
1023
|
+
const response = await fetch(`/api/path-suggestions?q=${encodeURIComponent(query || "")}`);
|
|
1024
|
+
const data = await response.json();
|
|
1025
|
+
if (response.ok && Array.isArray(data.suggestions)) {
|
|
1026
|
+
renderCommandCwdSuggestions([...new Set([...data.suggestions, ...fallback])]);
|
|
1027
|
+
}
|
|
1028
|
+
} catch {
|
|
1029
|
+
renderCommandCwdSuggestions(fallback);
|
|
1030
|
+
}
|
|
956
1031
|
}
|
|
957
1032
|
|
|
958
1033
|
function renderTaskProfiles(selected = "auto") {
|
|
@@ -1192,6 +1267,31 @@ function providerModelOptions(provider = providerField.value) {
|
|
|
1192
1267
|
return (modelCatalog[provider] || []).filter((item) => !item.hidden);
|
|
1193
1268
|
}
|
|
1194
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
|
+
|
|
1195
1295
|
function mergeModelOptions(...groups) {
|
|
1196
1296
|
const seen = new Set();
|
|
1197
1297
|
const merged = [];
|
|
@@ -1253,24 +1353,32 @@ function setSelectOptions(select, options, selectedValue = "", fallbackValue = "
|
|
|
1253
1353
|
function refreshModelDropdowns() {
|
|
1254
1354
|
refreshProviderDropdowns();
|
|
1255
1355
|
const provider = providerField?.value || "deepseek";
|
|
1256
|
-
setSelectOptions(
|
|
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";
|
|
1257
1363
|
setSelectOptions(
|
|
1258
1364
|
routeModelField,
|
|
1259
|
-
providerModelOptions(
|
|
1260
|
-
fieldValue(routeModelField),
|
|
1261
|
-
|
|
1365
|
+
providerModelOptions(routeProvider),
|
|
1366
|
+
coerceModelForProvider(routeProvider, fieldValue(routeModelField), fallbackModelForProvider(routeProvider, "route")),
|
|
1367
|
+
fallbackModelForProvider(routeProvider, "route")
|
|
1262
1368
|
);
|
|
1369
|
+
const mainProvider = mainProviderField?.value || "deepseek";
|
|
1263
1370
|
setSelectOptions(
|
|
1264
1371
|
mainModelField,
|
|
1265
|
-
providerModelOptions(
|
|
1266
|
-
fieldValue(mainModelField),
|
|
1267
|
-
|
|
1372
|
+
providerModelOptions(mainProvider),
|
|
1373
|
+
coerceModelForProvider(mainProvider, fieldValue(mainModelField), fallbackModelForProvider(mainProvider, "main")),
|
|
1374
|
+
fallbackModelForProvider(mainProvider, "main")
|
|
1268
1375
|
);
|
|
1376
|
+
const spareProvider = spareProviderField?.value || "openai";
|
|
1269
1377
|
setSelectOptions(
|
|
1270
1378
|
spareModelField,
|
|
1271
|
-
providerModelOptions(
|
|
1272
|
-
fieldValue(spareModelField),
|
|
1273
|
-
|
|
1379
|
+
providerModelOptions(spareProvider),
|
|
1380
|
+
coerceModelForProvider(spareProvider, fieldValue(spareModelField), fallbackModelForProvider(spareProvider, "spare")),
|
|
1381
|
+
fallbackModelForProvider(spareProvider, "spare")
|
|
1274
1382
|
);
|
|
1275
1383
|
setSelectOptions(wrapperModelField, wrapperModelOptions(), fieldValue(wrapperModelField), modelRoles.wrapper?.model || "gpt-5.5");
|
|
1276
1384
|
setSelectOptions(
|
|
@@ -1290,13 +1398,9 @@ function selectedVeniceTextModel() {
|
|
|
1290
1398
|
);
|
|
1291
1399
|
}
|
|
1292
1400
|
|
|
1293
|
-
function inferVeniceMode() {
|
|
1294
|
-
return [providerField?.value, routeProviderField?.value, mainProviderField?.value].includes("venice");
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
1401
|
function syncQuickModeControls() {
|
|
1298
1402
|
if (aapsModeToggle) aapsModeToggle.checked = (taskProfileField?.value || "auto") === "aaps";
|
|
1299
|
-
if (veniceModeToggle) veniceModeToggle.checked =
|
|
1403
|
+
if (veniceModeToggle) veniceModeToggle.checked = quickVeniceModeActive;
|
|
1300
1404
|
if (quickModeStatusEl) {
|
|
1301
1405
|
const scs = enableScsField?.value || "on";
|
|
1302
1406
|
const profile = taskProfileField?.value || "auto";
|
|
@@ -1314,10 +1418,13 @@ function applyAapsMode(enabled) {
|
|
|
1314
1418
|
}
|
|
1315
1419
|
|
|
1316
1420
|
function applyVeniceMode(enabled) {
|
|
1421
|
+
quickVeniceModeActive = Boolean(enabled);
|
|
1317
1422
|
if (enabled) {
|
|
1318
1423
|
const model = selectedVeniceTextModel();
|
|
1319
1424
|
routingModeField.value = "smart";
|
|
1320
|
-
providerField.value = "
|
|
1425
|
+
providerField.value = "venice";
|
|
1426
|
+
refreshModelDropdowns();
|
|
1427
|
+
if (modelField) setSelectOptions(modelField, providerModelOptions("venice"), model, defaults.venice);
|
|
1321
1428
|
if (routeProviderField) routeProviderField.value = "venice";
|
|
1322
1429
|
refreshModelDropdowns();
|
|
1323
1430
|
if (routeModelField) setSelectOptions(routeModelField, providerModelOptions("venice"), model, defaults.venice);
|
|
@@ -1326,10 +1433,13 @@ function applyVeniceMode(enabled) {
|
|
|
1326
1433
|
if (mainModelField) setSelectOptions(mainModelField, providerModelOptions("venice"), model, defaults.venice);
|
|
1327
1434
|
} else {
|
|
1328
1435
|
routingModeField.value = "smart";
|
|
1329
|
-
providerField.value = "deepseek";
|
|
1436
|
+
if (providerField?.value === "venice") providerField.value = "deepseek";
|
|
1330
1437
|
if (routeProviderField?.value === "venice") routeProviderField.value = "deepseek";
|
|
1331
1438
|
if (mainProviderField?.value === "venice") mainProviderField.value = "deepseek";
|
|
1332
1439
|
refreshModelDropdowns();
|
|
1440
|
+
if (modelField && providerField?.value === "deepseek") {
|
|
1441
|
+
setSelectOptions(modelField, providerModelOptions("deepseek"), "deepseek-v4-flash", "deepseek-v4-flash");
|
|
1442
|
+
}
|
|
1333
1443
|
if (routeModelField && routeProviderField?.value === "deepseek") {
|
|
1334
1444
|
setSelectOptions(routeModelField, providerModelOptions("deepseek"), "deepseek-v4-flash", "deepseek-v4-flash");
|
|
1335
1445
|
}
|
|
@@ -1584,7 +1694,7 @@ function formPayload() {
|
|
|
1584
1694
|
auxiliaryModel: fieldValue(auxiliaryModelField) || "nano-banana-2",
|
|
1585
1695
|
startUrl: document.querySelector("#startUrl").value.trim(),
|
|
1586
1696
|
allowedDomains: document.querySelector("#allowedDomains").value.trim(),
|
|
1587
|
-
commandCwd:
|
|
1697
|
+
commandCwd: commandCwdField?.value.trim() || "",
|
|
1588
1698
|
maxSteps: Number(document.querySelector("#maxSteps").value) || 24,
|
|
1589
1699
|
permissionMode: permissionModeField?.value || "normal",
|
|
1590
1700
|
sandboxMode: sandboxModeField.value,
|
|
@@ -1599,6 +1709,7 @@ function formPayload() {
|
|
|
1599
1709
|
allowParallelScouts: allowParallelScoutsField?.checked ?? true,
|
|
1600
1710
|
enableScs: enableScsField?.value || "on",
|
|
1601
1711
|
dynamicSteps: dynamicStepsField?.value || "auto",
|
|
1712
|
+
veniceMode: quickVeniceModeActive,
|
|
1602
1713
|
parallelScoutCount: Math.min(Math.max(Number(parallelScoutCountField?.value) || 3, 1), 10),
|
|
1603
1714
|
allowWrapperTools: allowWrapperToolsField.checked,
|
|
1604
1715
|
preferredWrapper: preferredWrapperField.value,
|
|
@@ -3048,16 +3159,8 @@ providerField.addEventListener("change", () => {
|
|
|
3048
3159
|
routingModeField.value = "manual";
|
|
3049
3160
|
}
|
|
3050
3161
|
|
|
3051
|
-
if (
|
|
3052
|
-
|
|
3053
|
-
modelField.value === defaults.openai ||
|
|
3054
|
-
modelField.value === defaults.deepseek ||
|
|
3055
|
-
modelField.value === defaults.qwen ||
|
|
3056
|
-
modelField.value === defaults.venice ||
|
|
3057
|
-
modelField.value === defaults.mock
|
|
3058
|
-
) {
|
|
3059
|
-
modelField.value = defaults[providerField.value] || "";
|
|
3060
|
-
}
|
|
3162
|
+
if (providerField.value !== "venice") quickVeniceModeActive = false;
|
|
3163
|
+
refreshModelDropdowns();
|
|
3061
3164
|
updateRoutingHint();
|
|
3062
3165
|
syncQuickModeControls();
|
|
3063
3166
|
schedulePreferenceSave();
|
|
@@ -3146,6 +3249,22 @@ saveApiKeyButton?.addEventListener("click", async () => {
|
|
|
3146
3249
|
form.addEventListener("input", schedulePreferenceSave);
|
|
3147
3250
|
form.addEventListener("change", schedulePreferenceSave);
|
|
3148
3251
|
|
|
3252
|
+
let commandCwdSuggestTimer = null;
|
|
3253
|
+
commandCwdField?.addEventListener("focus", () => {
|
|
3254
|
+
refreshCommandCwdSuggestions(commandCwdField.value).catch(() => {});
|
|
3255
|
+
});
|
|
3256
|
+
commandCwdField?.addEventListener("input", () => {
|
|
3257
|
+
schedulePreferenceSave();
|
|
3258
|
+
clearTimeout(commandCwdSuggestTimer);
|
|
3259
|
+
commandCwdSuggestTimer = setTimeout(() => {
|
|
3260
|
+
refreshCommandCwdSuggestions(commandCwdField.value).catch(() => {});
|
|
3261
|
+
}, 120);
|
|
3262
|
+
});
|
|
3263
|
+
commandCwdField?.addEventListener("change", () => {
|
|
3264
|
+
schedulePreferenceSave();
|
|
3265
|
+
refreshCommandCwdSuggestions(commandCwdField.value).catch(() => {});
|
|
3266
|
+
});
|
|
3267
|
+
|
|
3149
3268
|
chatInputEl.addEventListener("keydown", (event) => {
|
|
3150
3269
|
if (event.key === "Enter" && !event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
3151
3270
|
event.preventDefault();
|
|
@@ -3304,6 +3423,7 @@ async function loadConfig() {
|
|
|
3304
3423
|
defaults.mock = data.defaults?.mock?.model || defaults.mock;
|
|
3305
3424
|
|
|
3306
3425
|
applyLanguage(prefs.language || normalizeLanguage(navigator.language || "en"), { persist: false });
|
|
3426
|
+
quickVeniceModeActive = prefs.veniceMode === true;
|
|
3307
3427
|
refreshProviderDropdowns();
|
|
3308
3428
|
|
|
3309
3429
|
routingModeField.value = prefs.routingMode || "smart";
|
|
@@ -3314,24 +3434,41 @@ async function loadConfig() {
|
|
|
3314
3434
|
if (spareReasoningField) spareReasoningField.value = prefs.spareReasoning || modelRoles.spare?.reasoning || "medium";
|
|
3315
3435
|
if (wrapperReasoningField) wrapperReasoningField.value = prefs.wrapperReasoning || modelRoles.wrapper?.reasoning || "medium";
|
|
3316
3436
|
if (auxiliaryProviderField) auxiliaryProviderField.value = prefs.auxiliaryProvider || modelRoles.auxiliary?.provider || "grsai";
|
|
3317
|
-
setSelectOptions(
|
|
3437
|
+
setSelectOptions(
|
|
3438
|
+
modelField,
|
|
3439
|
+
providerModelOptions(providerField.value),
|
|
3440
|
+
coerceModelForProvider(providerField.value, prefs.model, fallbackModelForProvider(providerField.value, "primary")),
|
|
3441
|
+
fallbackModelForProvider(providerField.value, "primary")
|
|
3442
|
+
);
|
|
3318
3443
|
setSelectOptions(
|
|
3319
3444
|
routeModelField,
|
|
3320
3445
|
providerModelOptions(routeProviderField?.value || "deepseek"),
|
|
3321
|
-
|
|
3322
|
-
|
|
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")
|
|
3323
3452
|
);
|
|
3324
3453
|
setSelectOptions(
|
|
3325
3454
|
mainModelField,
|
|
3326
3455
|
providerModelOptions(mainProviderField?.value || "deepseek"),
|
|
3327
|
-
|
|
3328
|
-
|
|
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")
|
|
3329
3462
|
);
|
|
3330
3463
|
setSelectOptions(
|
|
3331
3464
|
spareModelField,
|
|
3332
3465
|
providerModelOptions(spareProviderField?.value || "openai"),
|
|
3333
|
-
|
|
3334
|
-
|
|
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")
|
|
3335
3472
|
);
|
|
3336
3473
|
setSelectOptions(wrapperModelField, wrapperModelOptions(), prefs.wrapperModel || modelRoles.wrapper?.model, "gpt-5.5");
|
|
3337
3474
|
setSelectOptions(
|
|
@@ -3343,7 +3480,7 @@ async function loadConfig() {
|
|
|
3343
3480
|
renderTaskProfiles(prefs.taskProfile || "auto");
|
|
3344
3481
|
document.querySelector("#startUrl").value = prefs.startUrl || "";
|
|
3345
3482
|
document.querySelector("#allowedDomains").value = prefs.allowedDomains || "";
|
|
3346
|
-
|
|
3483
|
+
if (commandCwdField) commandCwdField.value = prefs.commandCwd || data.project?.root || "";
|
|
3347
3484
|
document.querySelector("#headless").checked = prefs.headless ?? data.defaults.headless;
|
|
3348
3485
|
document.querySelector("#maxSteps").value = prefs.maxSteps ?? data.defaults.maxSteps;
|
|
3349
3486
|
if (permissionModeField) permissionModeField.value = prefs.permissionMode || "normal";
|
|
@@ -3366,12 +3503,14 @@ async function loadConfig() {
|
|
|
3366
3503
|
|
|
3367
3504
|
renderKeyStatus(data.keyStatus);
|
|
3368
3505
|
renderProjectStatus(data.project);
|
|
3506
|
+
await refreshCommandCwdSuggestions(commandCwdField?.value || "");
|
|
3369
3507
|
renderWrapperStatus(data.wrappers || []);
|
|
3370
3508
|
refreshProviderDropdowns();
|
|
3371
3509
|
renderWorkspacePanel(data.workspace, []);
|
|
3372
3510
|
renderMcpPanel(data.mcp || null);
|
|
3373
3511
|
await refreshWorkspaceChanges();
|
|
3374
3512
|
renderSandboxLogs(data.sandbox?.logs || []);
|
|
3513
|
+
if (quickVeniceModeActive) applyVeniceMode(true);
|
|
3375
3514
|
updateRoutingHint();
|
|
3376
3515
|
updatePermissionHint();
|
|
3377
3516
|
updatePackageWarning();
|
package/public/index.html
CHANGED
|
@@ -36,13 +36,30 @@
|
|
|
36
36
|
<p class="subtle" data-i18n="intro">
|
|
37
37
|
Project-aware, low-cost agent for real problems
|
|
38
38
|
</p>
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
<section class="workspace-search-card" aria-labelledby="workspace-search-title">
|
|
40
|
+
<div class="workspace-search-head">
|
|
41
|
+
<div>
|
|
42
|
+
<strong id="workspace-search-title" data-i18n="projectStatusTitle">Project folder</strong>
|
|
43
|
+
<p class="subtle" data-i18n="commandCwdHelp">Runs start from this working directory.</p>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
<label class="workspace-search-field">
|
|
47
|
+
<span data-i18n="commandCwdLabel">Working directory</span>
|
|
48
|
+
<input
|
|
49
|
+
id="commandCwd"
|
|
50
|
+
name="commandCwd"
|
|
51
|
+
type="search"
|
|
52
|
+
value="/home/lachlan/ProjectsLFS/Agent"
|
|
53
|
+
list="command-cwd-suggestions"
|
|
54
|
+
autocomplete="off"
|
|
55
|
+
spellcheck="false"
|
|
56
|
+
data-i18n-placeholder="commandCwdPlaceholder"
|
|
57
|
+
placeholder="/home/lachlan/ProjectsLFS/Agent"
|
|
58
|
+
/>
|
|
59
|
+
<datalist id="command-cwd-suggestions"></datalist>
|
|
60
|
+
</label>
|
|
61
|
+
<div id="project-status" class="project-status-grid" aria-live="polite">Loading project context...</div>
|
|
62
|
+
</section>
|
|
46
63
|
|
|
47
64
|
<section id="setup-card" class="setup-card" hidden>
|
|
48
65
|
<div>
|
|
@@ -84,14 +101,20 @@
|
|
|
84
101
|
</div>
|
|
85
102
|
</section>
|
|
86
103
|
|
|
87
|
-
<
|
|
88
|
-
<
|
|
89
|
-
<
|
|
104
|
+
<details id="run-defaults-card" class="run-defaults-card">
|
|
105
|
+
<summary class="run-defaults-summary">
|
|
106
|
+
<span>
|
|
90
107
|
<strong data-i18n="runDefaultsTitle">Run defaults</strong>
|
|
108
|
+
<span class="subtle" data-i18n="runDefaultsFoldHint">Routing, safety, tool toggles, and key status.</span>
|
|
109
|
+
</span>
|
|
110
|
+
<span id="key-status" class="key-status-summary"></span>
|
|
111
|
+
<span class="project-card-toggle" aria-hidden="true"></span>
|
|
112
|
+
</summary>
|
|
113
|
+
<form id="run-form" class="run-defaults-form">
|
|
114
|
+
<div class="run-defaults-head">
|
|
91
115
|
<p class="subtle" data-i18n="runDefaultsHelp">The chat box is the first goal for a new run. These controls set how that run starts.</p>
|
|
116
|
+
<div id="key-status-list" class="key-status-list" aria-live="polite"></div>
|
|
92
117
|
</div>
|
|
93
|
-
<span id="key-status" class="subtle"></span>
|
|
94
|
-
</div>
|
|
95
118
|
|
|
96
119
|
<label>
|
|
97
120
|
<span data-i18n="routingModeLabel">Routing policy</span>
|
|
@@ -135,10 +158,6 @@
|
|
|
135
158
|
</label>
|
|
136
159
|
|
|
137
160
|
<div class="grid">
|
|
138
|
-
<label>
|
|
139
|
-
<span data-i18n="commandCwdLabel">Working directory</span>
|
|
140
|
-
<input id="commandCwd" name="commandCwd" type="text" value="/home/lachlan/ProjectsLFS/Agent" />
|
|
141
|
-
</label>
|
|
142
161
|
<label>
|
|
143
162
|
<span data-i18n="maxStepsLabel">Max steps</span>
|
|
144
163
|
<input id="maxSteps" name="maxSteps" type="number" min="1" max="50" value="24" />
|
|
@@ -202,7 +221,8 @@
|
|
|
202
221
|
</div>
|
|
203
222
|
|
|
204
223
|
<button id="open-settings" type="button" class="secondary settings-button">Advanced settings</button>
|
|
205
|
-
|
|
224
|
+
</form>
|
|
225
|
+
</details>
|
|
206
226
|
</section>
|
|
207
227
|
|
|
208
228
|
<section class="stack">
|