@quanta-intellect/vessel-browser 0.1.68 → 0.1.69
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/out/main/index.js
CHANGED
|
@@ -65,6 +65,7 @@ const defaults = {
|
|
|
65
65
|
domainPolicy: { allowedDomains: [], blockedDomains: [] },
|
|
66
66
|
downloadPath: "",
|
|
67
67
|
telemetryEnabled: true,
|
|
68
|
+
defaultSearchEngine: "duckduckgo",
|
|
68
69
|
premium: {
|
|
69
70
|
status: "free",
|
|
70
71
|
customerId: "",
|
|
@@ -3754,6 +3755,24 @@ const VERIFICATION_API = process.env.VESSEL_PREMIUM_API || "https://vesselpremiu
|
|
|
3754
3755
|
const FREE_TOOL_ITERATION_LIMIT = 50;
|
|
3755
3756
|
const REVALIDATION_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
3756
3757
|
const OFFLINE_GRACE_PERIOD_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
3758
|
+
const MAX_API_ERROR_LOG_LENGTH = 300;
|
|
3759
|
+
async function readApiErrorDetail(res) {
|
|
3760
|
+
try {
|
|
3761
|
+
const text = (await res.text()).trim();
|
|
3762
|
+
if (!text) return "";
|
|
3763
|
+
try {
|
|
3764
|
+
const data = JSON.parse(text);
|
|
3765
|
+
const detail = data.error || data.message;
|
|
3766
|
+
if (typeof detail === "string" && detail.trim()) {
|
|
3767
|
+
return detail.trim().slice(0, MAX_API_ERROR_LOG_LENGTH);
|
|
3768
|
+
}
|
|
3769
|
+
} catch {
|
|
3770
|
+
}
|
|
3771
|
+
return text.slice(0, MAX_API_ERROR_LOG_LENGTH);
|
|
3772
|
+
} catch {
|
|
3773
|
+
return "";
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3757
3776
|
const PREMIUM_TOOLS = /* @__PURE__ */ new Set([
|
|
3758
3777
|
"screenshot",
|
|
3759
3778
|
"save_session",
|
|
@@ -3843,7 +3862,12 @@ async function verifySubscription(identifier) {
|
|
|
3843
3862
|
body: JSON.stringify({ identifier: verificationIdentifier })
|
|
3844
3863
|
});
|
|
3845
3864
|
if (!res.ok) {
|
|
3846
|
-
|
|
3865
|
+
const detail = await readApiErrorDetail(res);
|
|
3866
|
+
logger$f.warn(
|
|
3867
|
+
"Verification API returned a non-OK status:",
|
|
3868
|
+
res.status,
|
|
3869
|
+
detail
|
|
3870
|
+
);
|
|
3847
3871
|
return current;
|
|
3848
3872
|
}
|
|
3849
3873
|
const data = await res.json();
|
|
@@ -6326,7 +6350,7 @@ class AnthropicProvider {
|
|
|
6326
6350
|
});
|
|
6327
6351
|
continue;
|
|
6328
6352
|
}
|
|
6329
|
-
const argSummary = [tb.input.url, tb.input.text, tb.input.direction].map((v) => typeof v === "string" ? v : "").find((v) => v.length > 0) ?? "";
|
|
6353
|
+
const argSummary = [tb.input.url, tb.input.query, tb.input.text, tb.input.direction].map((v) => typeof v === "string" ? v : "").find((v) => v.length > 0) ?? "";
|
|
6330
6354
|
onChunk(`
|
|
6331
6355
|
<<tool:${tb.name}${argSummary ? ":" + argSummary : ""}>>
|
|
6332
6356
|
`);
|
|
@@ -6517,11 +6541,52 @@ const SAFE_TOOL_ALIASES = {
|
|
|
6517
6541
|
scroll_up: "scroll",
|
|
6518
6542
|
read: "read_page",
|
|
6519
6543
|
read_current_page: "read_page",
|
|
6520
|
-
scan_page: "read_page"
|
|
6544
|
+
scan_page: "read_page",
|
|
6545
|
+
save_bookmark: "save_bookmark",
|
|
6546
|
+
bookmark: "save_bookmark",
|
|
6547
|
+
bookmark_page: "save_bookmark",
|
|
6548
|
+
bookmark_url: "save_bookmark",
|
|
6549
|
+
add_bookmark: "save_bookmark",
|
|
6550
|
+
create_bookmark: "save_bookmark"
|
|
6521
6551
|
};
|
|
6552
|
+
const CANONICAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
6553
|
+
"archive_bookmark",
|
|
6554
|
+
"click",
|
|
6555
|
+
"create_bookmark_folder",
|
|
6556
|
+
"current_tab",
|
|
6557
|
+
"go_back",
|
|
6558
|
+
"go_forward",
|
|
6559
|
+
"inspect_element",
|
|
6560
|
+
"list_bookmarks",
|
|
6561
|
+
"navigate",
|
|
6562
|
+
"open_bookmark",
|
|
6563
|
+
"organize_bookmark",
|
|
6564
|
+
"read_page",
|
|
6565
|
+
"save_bookmark",
|
|
6566
|
+
"scroll",
|
|
6567
|
+
"search",
|
|
6568
|
+
"type_text"
|
|
6569
|
+
]);
|
|
6570
|
+
function repeatedTokenMatch(value, token) {
|
|
6571
|
+
if (value === token) return true;
|
|
6572
|
+
if (token.length === 0 || value.length <= token.length) return false;
|
|
6573
|
+
if (value.length % token.length !== 0) return false;
|
|
6574
|
+
return token.repeat(value.length / token.length) === value;
|
|
6575
|
+
}
|
|
6522
6576
|
function normalizeToolAlias(name) {
|
|
6523
6577
|
const normalized = name.trim().toLowerCase().replace(/[.\s/-]+/g, "_");
|
|
6524
|
-
|
|
6578
|
+
const direct = SAFE_TOOL_ALIASES[normalized] ?? normalized;
|
|
6579
|
+
if (CANONICAL_TOOL_NAMES.has(direct)) return direct;
|
|
6580
|
+
const knownTokens = [
|
|
6581
|
+
...Object.keys(SAFE_TOOL_ALIASES),
|
|
6582
|
+
...CANONICAL_TOOL_NAMES
|
|
6583
|
+
];
|
|
6584
|
+
for (const token of knownTokens) {
|
|
6585
|
+
if (repeatedTokenMatch(normalized, token)) {
|
|
6586
|
+
return SAFE_TOOL_ALIASES[token] ?? token;
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6589
|
+
return name;
|
|
6525
6590
|
}
|
|
6526
6591
|
function parseModelSizeInBillions(model) {
|
|
6527
6592
|
const match = model.toLowerCase().match(/(?:^|[:/_\-\s])(\d+(?:\.\d+)?)b(?:$|[:/_\-\s])/i);
|
|
@@ -6845,8 +6910,62 @@ function scalarArgsForTool(name, scalar) {
|
|
|
6845
6910
|
const mode = trimmed.replace(/^["']|["']$/g, "").toLowerCase();
|
|
6846
6911
|
if (mode) return { mode };
|
|
6847
6912
|
}
|
|
6913
|
+
if (name === "save_bookmark") {
|
|
6914
|
+
const url = toLikelyUrl(trimmed);
|
|
6915
|
+
if (url) return { url };
|
|
6916
|
+
const lastSpace = trimmed.lastIndexOf(" ");
|
|
6917
|
+
if (lastSpace > 0) {
|
|
6918
|
+
const maybeUrl = toLikelyUrl(trimmed.slice(lastSpace + 1));
|
|
6919
|
+
if (maybeUrl) return { url: maybeUrl, title: trimmed.slice(0, lastSpace).replace(/^["']|["']$/g, "") };
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
return null;
|
|
6923
|
+
}
|
|
6924
|
+
function firstStringArg(args, keys) {
|
|
6925
|
+
for (const key of keys) {
|
|
6926
|
+
const value = args[key];
|
|
6927
|
+
if (typeof value === "string" && value.trim()) {
|
|
6928
|
+
return value.trim();
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6848
6931
|
return null;
|
|
6849
6932
|
}
|
|
6933
|
+
function normalizeElementTargetArgs(args) {
|
|
6934
|
+
const normalized = { ...args };
|
|
6935
|
+
if (typeof normalized.index === "string" && /^\d+$/.test(normalized.index.trim())) {
|
|
6936
|
+
normalized.index = Number(normalized.index.trim());
|
|
6937
|
+
}
|
|
6938
|
+
if (typeof normalized.selector !== "string" || !normalized.selector.trim()) {
|
|
6939
|
+
const selector = firstStringArg(normalized, [
|
|
6940
|
+
"cssSelector",
|
|
6941
|
+
"css_selector",
|
|
6942
|
+
"querySelector",
|
|
6943
|
+
"query_selector"
|
|
6944
|
+
]);
|
|
6945
|
+
if (selector) normalized.selector = selector;
|
|
6946
|
+
}
|
|
6947
|
+
if (typeof normalized.text !== "string" || !normalized.text.trim()) {
|
|
6948
|
+
const text = firstStringArg(normalized, [
|
|
6949
|
+
"label",
|
|
6950
|
+
"title",
|
|
6951
|
+
"name",
|
|
6952
|
+
"target",
|
|
6953
|
+
"element",
|
|
6954
|
+
"linkText",
|
|
6955
|
+
"link_text",
|
|
6956
|
+
"ariaLabel",
|
|
6957
|
+
"aria_label"
|
|
6958
|
+
]);
|
|
6959
|
+
if (text) normalized.text = text;
|
|
6960
|
+
}
|
|
6961
|
+
return normalized;
|
|
6962
|
+
}
|
|
6963
|
+
function hasElementTarget(args) {
|
|
6964
|
+
return typeof args.index === "number" || typeof args.selector === "string" && args.selector.trim().length > 0 || typeof args.text === "string" && args.text.trim().length > 0;
|
|
6965
|
+
}
|
|
6966
|
+
function isTargetlessClickArgs(args) {
|
|
6967
|
+
return !hasElementTarget(normalizeElementTargetArgs(args));
|
|
6968
|
+
}
|
|
6850
6969
|
function tryParseJsonWithCommonRepairs(raw) {
|
|
6851
6970
|
const trimmed = raw.trim();
|
|
6852
6971
|
if (!trimmed) return {};
|
|
@@ -6900,7 +7019,10 @@ function parseToolArgsWithRepair(name, argsJson) {
|
|
|
6900
7019
|
return scalarArgs ? { args: scalarArgs, repaired: true } : null;
|
|
6901
7020
|
}
|
|
6902
7021
|
function coerceToolArgsForExecution(name, args) {
|
|
6903
|
-
|
|
7022
|
+
let coerced = { ...args };
|
|
7023
|
+
if (name === "click" || name === "inspect_element" || name === "scroll_to_element") {
|
|
7024
|
+
coerced = normalizeElementTargetArgs(coerced);
|
|
7025
|
+
}
|
|
6904
7026
|
if (name === "search") {
|
|
6905
7027
|
if (typeof coerced.query !== "string" || !coerced.query.trim()) {
|
|
6906
7028
|
if (typeof coerced.text === "string" && coerced.text.trim()) {
|
|
@@ -6921,6 +7043,25 @@ function coerceToolArgsForExecution(name, args) {
|
|
|
6921
7043
|
}
|
|
6922
7044
|
}
|
|
6923
7045
|
}
|
|
7046
|
+
if (name === "save_bookmark") {
|
|
7047
|
+
if (typeof coerced.url !== "string" || !coerced.url.trim()) {
|
|
7048
|
+
if (typeof coerced.link === "string" && coerced.link.trim()) {
|
|
7049
|
+
coerced.url = coerced.link.trim();
|
|
7050
|
+
} else if (typeof coerced.href === "string" && coerced.href.trim()) {
|
|
7051
|
+
coerced.url = coerced.href.trim();
|
|
7052
|
+
}
|
|
7053
|
+
}
|
|
7054
|
+
if (typeof coerced.folderName !== "string" || !coerced.folderName.trim()) {
|
|
7055
|
+
if (typeof coerced.folder === "string" && coerced.folder.trim()) {
|
|
7056
|
+
coerced.folderName = coerced.folder.trim();
|
|
7057
|
+
} else if (typeof coerced.category === "string" && coerced.category.trim()) {
|
|
7058
|
+
coerced.folderName = coerced.category.trim();
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
7061
|
+
if (coerced.folderName && typeof coerced.createFolderIfMissing === "undefined") {
|
|
7062
|
+
coerced.createFolderIfMissing = true;
|
|
7063
|
+
}
|
|
7064
|
+
}
|
|
6924
7065
|
return coerced;
|
|
6925
7066
|
}
|
|
6926
7067
|
function canonicalizeArgsForTool(name, args) {
|
|
@@ -6937,6 +7078,24 @@ function canonicalizeArgsForTool(name, args) {
|
|
|
6937
7078
|
}
|
|
6938
7079
|
return canonical;
|
|
6939
7080
|
}
|
|
7081
|
+
function unsupportedToolHint(name) {
|
|
7082
|
+
const normalized = name.trim().toLowerCase().replace(/[.\s/-]+/g, "_");
|
|
7083
|
+
const BOOKMARK_NAMES = [
|
|
7084
|
+
"organize_bookmark",
|
|
7085
|
+
"organize_bookmarks",
|
|
7086
|
+
"manage_bookmark",
|
|
7087
|
+
"manage_bookmarks",
|
|
7088
|
+
"add_to_bookmarks",
|
|
7089
|
+
"save_to_bookmarks",
|
|
7090
|
+
"bookmark_link",
|
|
7091
|
+
"save_link",
|
|
7092
|
+
"store_bookmark"
|
|
7093
|
+
];
|
|
7094
|
+
if (BOOKMARK_NAMES.includes(normalized) || /bookmark|save.*link|organize/.test(normalized)) {
|
|
7095
|
+
return `Error: "${name}" is not a supported tool. Use save_bookmark to save a page as a bookmark, or create_bookmark_folder to create a folder. Example: save_bookmark with {"url": "...", "title": "...", "folderName": "..."}`;
|
|
7096
|
+
}
|
|
7097
|
+
return `Error: ${name} is not a supported tool. Choose one of the available browser tools instead.`;
|
|
7098
|
+
}
|
|
6940
7099
|
function resolveToolCallName(rawName, args, availableToolNames) {
|
|
6941
7100
|
const aliased = normalizeToolAlias(rawName);
|
|
6942
7101
|
if (availableToolNames.has(aliased)) return aliased;
|
|
@@ -7241,6 +7400,7 @@ class OpenAICompatProvider {
|
|
|
7241
7400
|
);
|
|
7242
7401
|
if (recoveredToolCalls.length > 0) {
|
|
7243
7402
|
toolCalls = recoveredToolCalls;
|
|
7403
|
+
if (textAccum.trim()) onChunk("<<erase_prev>>");
|
|
7244
7404
|
} else {
|
|
7245
7405
|
const narratedToolCalls = recoverNarratedActionToolCalls(
|
|
7246
7406
|
textAccum,
|
|
@@ -7248,6 +7408,7 @@ class OpenAICompatProvider {
|
|
|
7248
7408
|
);
|
|
7249
7409
|
if (narratedToolCalls.length > 0) {
|
|
7250
7410
|
toolCalls = narratedToolCalls;
|
|
7411
|
+
if (textAccum.trim()) onChunk("<<erase_prev>>");
|
|
7251
7412
|
}
|
|
7252
7413
|
}
|
|
7253
7414
|
}
|
|
@@ -7314,6 +7475,25 @@ class OpenAICompatProvider {
|
|
|
7314
7475
|
compactRecoveryCount = 0;
|
|
7315
7476
|
const iterationToolResultPreviews = [];
|
|
7316
7477
|
for (const tc of toolCalls) {
|
|
7478
|
+
if (!availableToolNames.has(tc.name)) {
|
|
7479
|
+
const hint = unsupportedToolHint(tc.name);
|
|
7480
|
+
onChunk(`
|
|
7481
|
+
<<tool:${tc.name}:⚠ unsupported>>
|
|
7482
|
+
`);
|
|
7483
|
+
messages.push({
|
|
7484
|
+
role: "tool",
|
|
7485
|
+
tool_call_id: tc.id,
|
|
7486
|
+
content: hint
|
|
7487
|
+
});
|
|
7488
|
+
compactCorrectionCount += 1;
|
|
7489
|
+
if (compactCorrectionCount >= 2) {
|
|
7490
|
+
messages.push({
|
|
7491
|
+
role: "user",
|
|
7492
|
+
content: `[System] You are calling unsupported tools. Stop inventing tool names. Use the supported tools you were given and take the next concrete step.`
|
|
7493
|
+
});
|
|
7494
|
+
}
|
|
7495
|
+
continue;
|
|
7496
|
+
}
|
|
7317
7497
|
if (malformedToolCalls.has(tc.id)) {
|
|
7318
7498
|
onChunk(`
|
|
7319
7499
|
<<tool:${tc.name}:⚠ invalid args>>
|
|
@@ -7340,25 +7520,23 @@ class OpenAICompatProvider {
|
|
|
7340
7520
|
}
|
|
7341
7521
|
args = repairedArgs.args;
|
|
7342
7522
|
args = coerceToolArgsForExecution(tc.name, args);
|
|
7343
|
-
|
|
7523
|
+
const toolSignature = stableToolSignature(tc.name, args);
|
|
7524
|
+
if (this.agentToolProfile === "compact" && tc.name === "click" && isTargetlessClickArgs(args)) {
|
|
7344
7525
|
onChunk(`
|
|
7345
|
-
<<tool
|
|
7526
|
+
<<tool:${tc.name}:⚠ missing target>>
|
|
7346
7527
|
`);
|
|
7347
7528
|
messages.push({
|
|
7348
7529
|
role: "tool",
|
|
7349
7530
|
tool_call_id: tc.id,
|
|
7350
|
-
content: `Error:
|
|
7531
|
+
content: `Error: click requires an element target. Use click with {"index": N} from the latest read_page result, or {"text": "exact visible link/button text"}. If you do not have a current result index, call read_page(mode="results_only") first and then click one listed result.`
|
|
7532
|
+
});
|
|
7533
|
+
messages.push({
|
|
7534
|
+
role: "user",
|
|
7535
|
+
content: `[System] Your last click had no target. Do not call click with empty arguments. Refresh the page state with read_page(mode="results_only") if needed, then click exactly one result by index or exact visible text.`
|
|
7351
7536
|
});
|
|
7352
7537
|
compactCorrectionCount += 1;
|
|
7353
|
-
if (compactCorrectionCount >= 2) {
|
|
7354
|
-
messages.push({
|
|
7355
|
-
role: "user",
|
|
7356
|
-
content: `[System] You are calling unsupported tools. Stop inventing tool names. Use the supported tools you were given and take the next concrete step.`
|
|
7357
|
-
});
|
|
7358
|
-
}
|
|
7359
7538
|
continue;
|
|
7360
7539
|
}
|
|
7361
|
-
const toolSignature = stableToolSignature(tc.name, args);
|
|
7362
7540
|
const neverSuppressDuplicate = [
|
|
7363
7541
|
"read_page",
|
|
7364
7542
|
"current_tab",
|
|
@@ -10579,6 +10757,14 @@ function pruneToolsForContext(tools, pageType, query = "", options = {}) {
|
|
|
10579
10757
|
return description !== tool.description ? { ...tool, description } : tool;
|
|
10580
10758
|
});
|
|
10581
10759
|
}
|
|
10760
|
+
const SEARCH_ENGINE_PRESETS = {
|
|
10761
|
+
duckduckgo: { label: "DuckDuckGo", url: "https://duckduckgo.com/?q=" },
|
|
10762
|
+
google: { label: "Google", url: "https://www.google.com/search?q=" },
|
|
10763
|
+
bing: { label: "Bing", url: "https://www.bing.com/search?q=" },
|
|
10764
|
+
brave: { label: "Brave Search", url: "https://search.brave.com/search?q=" },
|
|
10765
|
+
ecosia: { label: "Ecosia", url: "https://www.ecosia.org/search?q=" },
|
|
10766
|
+
kagi: { label: "Kagi", url: "https://kagi.com/search?q=" }
|
|
10767
|
+
};
|
|
10582
10768
|
function trimText(value) {
|
|
10583
10769
|
return typeof value === "string" ? value.trim() : "";
|
|
10584
10770
|
}
|
|
@@ -14966,8 +15152,19 @@ function buildCommonSearchUrlShortcut(currentUrl, rawQuery) {
|
|
|
14966
15152
|
appliedFilters: existingParam ? [`updated ${existingParam} query`] : []
|
|
14967
15153
|
};
|
|
14968
15154
|
}
|
|
14969
|
-
function
|
|
14970
|
-
|
|
15155
|
+
function buildDefaultEngineShortcut(rawQuery) {
|
|
15156
|
+
const settings2 = loadSettings();
|
|
15157
|
+
const engineId = settings2.defaultSearchEngine ?? "duckduckgo";
|
|
15158
|
+
if (engineId === "none") return null;
|
|
15159
|
+
const preset = SEARCH_ENGINE_PRESETS[engineId];
|
|
15160
|
+
if (!preset) return null;
|
|
15161
|
+
const query = normalizeSearchQuery(rawQuery);
|
|
15162
|
+
if (!query) return null;
|
|
15163
|
+
return {
|
|
15164
|
+
url: preset.url + encodeURIComponent(query),
|
|
15165
|
+
source: "default search engine",
|
|
15166
|
+
appliedFilters: []
|
|
15167
|
+
};
|
|
14971
15168
|
}
|
|
14972
15169
|
async function locateSearchTarget(wc, explicitSelector) {
|
|
14973
15170
|
if (explicitSelector) {
|
|
@@ -15020,7 +15217,7 @@ async function locateSearchTarget(wc, explicitSelector) {
|
|
|
15020
15217
|
const seen = new Set();
|
|
15021
15218
|
const ordered = [];
|
|
15022
15219
|
const specific = document.querySelectorAll(
|
|
15023
|
-
'input[type="search"], input[name="q"], input[name="query"], input[name="search"], input[role="searchbox"], input[aria-label*="search" i], input[placeholder*="search" i]'
|
|
15220
|
+
'input[type="search"], input[name="q"], input[name="query"], input[name="search"], input[role="searchbox"], input[aria-label*="search" i], input[placeholder*="search" i], textarea[name="q"], textarea[name="query"], textarea[name="search"], textarea[role="searchbox"], textarea[aria-label*="search" i], textarea[placeholder*="search" i]'
|
|
15024
15221
|
);
|
|
15025
15222
|
specific.forEach((el) => {
|
|
15026
15223
|
if (!seen.has(el)) {
|
|
@@ -15028,7 +15225,7 @@ async function locateSearchTarget(wc, explicitSelector) {
|
|
|
15028
15225
|
ordered.push(el);
|
|
15029
15226
|
}
|
|
15030
15227
|
});
|
|
15031
|
-
document.querySelectorAll('input[type="text"], input:not([type])').forEach((el) => {
|
|
15228
|
+
document.querySelectorAll('input[type="text"], input:not([type]), textarea').forEach((el) => {
|
|
15032
15229
|
if (seen.has(el)) return;
|
|
15033
15230
|
const scope = nearestSearchScope(el);
|
|
15034
15231
|
if (!scope) return;
|
|
@@ -15039,9 +15236,10 @@ async function locateSearchTarget(wc, explicitSelector) {
|
|
|
15039
15236
|
}
|
|
15040
15237
|
|
|
15041
15238
|
function scoreInput(el) {
|
|
15042
|
-
if (!(el instanceof HTMLInputElement)) return -1;
|
|
15239
|
+
if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) return -1;
|
|
15043
15240
|
if (isDisabled(el) || !isVisible(el)) return -1;
|
|
15044
|
-
const
|
|
15241
|
+
const isTextarea = el instanceof HTMLTextAreaElement;
|
|
15242
|
+
const type = isTextarea ? "text" : normalize(el.getAttribute("type") || el.type);
|
|
15045
15243
|
if (type && !["search", "text", ""].includes(type)) return -1;
|
|
15046
15244
|
|
|
15047
15245
|
let score = 0;
|
|
@@ -15188,16 +15386,19 @@ async function searchPage(wc, args) {
|
|
|
15188
15386
|
if (looksLikeCurrentSiteNameQuery(query, wc.getURL(), wc.getTitle() || "")) {
|
|
15189
15387
|
return `Error: "${query}" looks like the current site's name, not a product query. You are already on ${wc.getURL()}. Open a section like staff picks/new releases or search for actual book titles, authors, or genres instead.`;
|
|
15190
15388
|
}
|
|
15389
|
+
const runShortcut = async (shortcut) => {
|
|
15390
|
+
const beforeUrl2 = wc.getURL();
|
|
15391
|
+
await loadPermittedUrl(wc, shortcut.url);
|
|
15392
|
+
await waitForPotentialNavigation(wc, beforeUrl2, 4e3);
|
|
15393
|
+
const afterUrl2 = wc.getURL();
|
|
15394
|
+
const applied = shortcut.appliedFilters.length > 0 ? ` (${shortcut.appliedFilters.join(", ")})` : "";
|
|
15395
|
+
const destination = shortcut.section ? ` ${shortcut.section}` : "";
|
|
15396
|
+
return `Searched "${query}" via ${shortcut.source}${destination} shortcut${applied} → ${afterUrl2}${await getPostSearchSummary(wc)}`;
|
|
15397
|
+
};
|
|
15191
15398
|
if (typeof args.selector !== "string") {
|
|
15192
|
-
const shortcut =
|
|
15399
|
+
const shortcut = buildHuggingFaceSearchShortcut(wc.getURL(), query) ?? buildCommonSearchUrlShortcut(wc.getURL(), query);
|
|
15193
15400
|
if (shortcut) {
|
|
15194
|
-
|
|
15195
|
-
await loadPermittedUrl(wc, shortcut.url);
|
|
15196
|
-
await waitForPotentialNavigation(wc, beforeUrl2, 4e3);
|
|
15197
|
-
const afterUrl2 = wc.getURL();
|
|
15198
|
-
const applied = shortcut.appliedFilters.length > 0 ? ` (${shortcut.appliedFilters.join(", ")})` : "";
|
|
15199
|
-
const destination = shortcut.section ? ` ${shortcut.section}` : "";
|
|
15200
|
-
return `Searched "${query}" via ${shortcut.source}${destination} shortcut${applied} → ${afterUrl2}${await getPostSearchSummary(wc)}`;
|
|
15401
|
+
return runShortcut(shortcut);
|
|
15201
15402
|
}
|
|
15202
15403
|
}
|
|
15203
15404
|
const searchInfo = await locateSearchTarget(
|
|
@@ -15208,6 +15409,12 @@ async function searchPage(wc, args) {
|
|
|
15208
15409
|
return pageBusyError("search");
|
|
15209
15410
|
}
|
|
15210
15411
|
if (!searchInfo?.selector) {
|
|
15412
|
+
if (typeof args.selector !== "string") {
|
|
15413
|
+
const fallback = buildDefaultEngineShortcut(query);
|
|
15414
|
+
if (fallback) {
|
|
15415
|
+
return runShortcut(fallback);
|
|
15416
|
+
}
|
|
15417
|
+
}
|
|
15211
15418
|
return 'Error: Could not find a visible search input. Try read_page(mode="visible_only") or provide a selector.';
|
|
15212
15419
|
}
|
|
15213
15420
|
const fillResult = await setElementValue(wc, searchInfo.selector, query);
|
|
@@ -23387,6 +23594,21 @@ class AgentRuntime {
|
|
|
23387
23594
|
}
|
|
23388
23595
|
setApprovalMode(mode) {
|
|
23389
23596
|
this.state.supervisor.approvalMode = mode;
|
|
23597
|
+
if (mode === "auto" && !this.state.supervisor.paused) {
|
|
23598
|
+
const approvals = this.state.supervisor.pendingApprovals;
|
|
23599
|
+
if (approvals.length > 0) {
|
|
23600
|
+
const actionIds = new Set(approvals.map((approval) => approval.actionId));
|
|
23601
|
+
this.state.supervisor.pendingApprovals = [];
|
|
23602
|
+
this.state.actions = this.state.actions.map(
|
|
23603
|
+
(action) => actionIds.has(action.id) ? { ...action, status: "running", error: void 0 } : action
|
|
23604
|
+
);
|
|
23605
|
+
for (const approval of approvals) {
|
|
23606
|
+
const resolve = this.pendingResolvers.get(approval.id);
|
|
23607
|
+
this.pendingResolvers.delete(approval.id);
|
|
23608
|
+
resolve?.(true);
|
|
23609
|
+
}
|
|
23610
|
+
}
|
|
23611
|
+
}
|
|
23390
23612
|
this.emit();
|
|
23391
23613
|
return this.getState();
|
|
23392
23614
|
}
|
|
@@ -24285,6 +24507,11 @@ function closeSplash(splash, delayMs = 0) {
|
|
|
24285
24507
|
}
|
|
24286
24508
|
const logger = createLogger("Bootstrap");
|
|
24287
24509
|
let runtime = null;
|
|
24510
|
+
function configureUserAgent() {
|
|
24511
|
+
const originalUA = electron.session.defaultSession.getUserAgent();
|
|
24512
|
+
const maskedUA = originalUA.replace(/ Electron\/[^\s]+/, "") + " Vessel/" + electron.app.getVersion();
|
|
24513
|
+
electron.session.defaultSession.setUserAgent(maskedUA);
|
|
24514
|
+
}
|
|
24288
24515
|
function checkWritableUserData(userDataPath) {
|
|
24289
24516
|
const issues = [];
|
|
24290
24517
|
try {
|
|
@@ -24348,6 +24575,7 @@ Action: Open Settings (Ctrl+,) to choose a different port, then save to restart
|
|
|
24348
24575
|
});
|
|
24349
24576
|
}
|
|
24350
24577
|
async function bootstrap() {
|
|
24578
|
+
configureUserAgent();
|
|
24351
24579
|
const splash = createSplashWindow();
|
|
24352
24580
|
const settings2 = loadSettings();
|
|
24353
24581
|
const userDataPath = electron.app.getPath("userData");
|