@agent-native/core 0.208.0 → 0.209.0-nightly-20261014070126
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/agent-native.eject.json +1 -0
- package/dist/agent/approval-key.d.ts +2 -0
- package/dist/agent/approval-key.js +12 -0
- package/dist/agent/context-xray/tokenize.js +12 -3
- package/dist/agent/engine/translate-anthropic.js +4 -0
- package/dist/agent/engine/types.d.ts +2 -0
- package/dist/agent/production-agent.d.ts +20 -5
- package/dist/agent/production-agent.js +227 -34
- package/dist/agent/run-manager.js +57 -11
- package/dist/agent/run-store.d.ts +10 -0
- package/dist/agent/run-store.js +49 -4
- package/dist/agent/thread-data-builder.d.ts +2 -0
- package/dist/agent/thread-data-builder.js +288 -14
- package/dist/agent/tool-approval-store.d.ts +3 -1
- package/dist/agent/tool-approval-store.js +26 -12
- package/dist/agent/tool-call-journal.d.ts +1 -1
- package/dist/agent/tool-call-journal.js +5 -3
- package/dist/agent/types.d.ts +7 -0
- package/dist/client/chat/agentkit-agent-native.js +18 -0
- package/dist/client/chat/agentkit-protocol.js +56 -5
- package/dist/client/chat/runtime.d.ts +10 -0
- package/dist/client/chat/runtime.js +257 -26
- package/dist/client/sse-event-processor.d.ts +22 -0
- package/dist/client/sse-event-processor.js +91 -11
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +24 -1
- package/dist/connections/catalog.js +12 -0
- package/dist/data-programs/schema.d.ts +1 -0
- package/dist/data-programs/schema.js +3 -0
- package/dist/data-programs/store.js +2 -1
- package/dist/deploy/build.js +16 -14
- package/dist/eject/workspace-connections.js +1 -0
- package/dist/extensions/fetch-tool.js +114 -23
- package/dist/extensions/schema.d.ts +1 -0
- package/dist/extensions/schema.js +3 -0
- package/dist/extensions/store.js +2 -1
- package/dist/extensions/web-content.d.ts +5 -1
- package/dist/extensions/web-content.js +24 -6
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +9 -9
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts +2 -0
- package/dist/provider-api/index.js +95 -12
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/auth.js +1 -0
- package/dist/server/core-routes-plugin.js +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.js +2 -0
- package/dist/shared/context-status.js +1 -1
- package/dist/shared/optional-peer-ssr.d.ts +2 -0
- package/dist/shared/optional-peer-ssr.js +123 -0
- package/dist/shared/tool-inputs.d.ts +2 -0
- package/dist/shared/tool-inputs.js +56 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/tracking/index.d.ts +1 -0
- package/dist/tracking/index.js +1 -0
- package/dist/vite/client.js +46 -3
- package/dist/workspace-connections/store.d.ts +3 -1
- package/dist/workspace-connections/store.js +18 -8
- package/dist/workspace-files/constants.d.ts +3 -0
- package/dist/workspace-files/constants.js +3 -0
- package/dist/workspace-files/store.d.ts +2 -3
- package/dist/workspace-files/store.js +2 -3
- package/docs/content/automations.mdx +19 -13
- package/package.json +3 -3
- package/src/eject/workspace-connections.ts +1 -0
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
* the raw secret never enters the model's context.
|
|
11
11
|
*/
|
|
12
12
|
import { fail, isActionContractError } from "../action.js";
|
|
13
|
+
import { SAVE_TO_FILE_MAX_BYTES } from "../workspace-files/constants.js";
|
|
13
14
|
import { collectSecretValues, MAX_EXTENSION_PROXY_RESPONSE_SIZE, normalizeExtensionProxyMethod, readResponseBytesWithLimit, readResponseTextWithLimit, redactSecrets, redactString, sanitizeOutboundHeaders, } from "./proxy-security.js";
|
|
14
15
|
import { createSsrfSafeDispatcher, isBlockedExtensionUrlWithDns, } from "./url-safety.js";
|
|
15
|
-
import { formatWebContentResult, parseWebContentSearchOptions, processWebContent, } from "./web-content.js";
|
|
16
|
+
import { formatWebContentResult, hasWebContentSearch, parseWebContentSearchOptions, processWebContent, } from "./web-content.js";
|
|
16
17
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
18
|
+
const MAX_WEB_REQUEST_HTML_BYTES = SAVE_TO_FILE_MAX_BYTES;
|
|
17
19
|
const VISION_IMAGE_CONTENT_TYPES = new Set([
|
|
18
20
|
"image/jpeg",
|
|
19
21
|
"image/png",
|
|
@@ -21,6 +23,20 @@ const VISION_IMAGE_CONTENT_TYPES = new Set([
|
|
|
21
23
|
"image/webp",
|
|
22
24
|
]);
|
|
23
25
|
const CREDENTIAL_NAME_RE = /(?:^|[-_])(access[-_]?token|api[-_]?key|auth(?:orization)?|credential|expires?|key[-_]?pair[-_]?id|key|password|passwd|policy|secret|session|signature|sig|token|jwt|assertion)(?:$|[-_])/i;
|
|
26
|
+
function isHtmlResponseContentType(contentType) {
|
|
27
|
+
const mediaType = contentType.toLowerCase();
|
|
28
|
+
return (mediaType === "text/html" ||
|
|
29
|
+
mediaType === "application/xhtml+xml" ||
|
|
30
|
+
mediaType.endsWith("+html"));
|
|
31
|
+
}
|
|
32
|
+
function truncateToolText(value, maxChars) {
|
|
33
|
+
if (value.length <= maxChars)
|
|
34
|
+
return value;
|
|
35
|
+
const marker = "\n...[truncated]";
|
|
36
|
+
if (maxChars <= marker.length)
|
|
37
|
+
return marker.slice(0, maxChars);
|
|
38
|
+
return `${value.slice(0, maxChars - marker.length)}${marker}`;
|
|
39
|
+
}
|
|
24
40
|
function uint8ArrayToBase64(bytes) {
|
|
25
41
|
if (typeof Buffer !== "undefined")
|
|
26
42
|
return Buffer.from(bytes).toString("base64");
|
|
@@ -85,7 +101,7 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
85
101
|
return {
|
|
86
102
|
"web-request": {
|
|
87
103
|
tool: {
|
|
88
|
-
description: `Make an outbound HTTP request to
|
|
104
|
+
description: `Make an outbound HTTP request to an external URL: APIs, webhooks, or web pages. HTML/XHTML responses up to 20 MB are extracted before maxChars limits the response body; optional metadata and links can add characters. Raw and other inline responses remain capped at 1 MB. saveToFile can stage responses up to 20 MB. For HTML, it saves extracted Markdown or text unless responseMode is raw; with search, it returns bounded matches instead of a preview. Sends realistic Chrome-on-macOS headers by default; explicit headers override them. Supports \${keys.NAME} placeholders in url, headers, and body, resolved server-side so raw secrets never enter context. Never use this for internal /_agent-native/ endpoints or localhost action URLs; call registered actions directly.`,
|
|
89
105
|
parameters: {
|
|
90
106
|
type: "object",
|
|
91
107
|
properties: {
|
|
@@ -112,7 +128,7 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
112
128
|
},
|
|
113
129
|
maxChars: {
|
|
114
130
|
type: "number",
|
|
115
|
-
description: "Maximum response
|
|
131
|
+
description: "Maximum response-body characters returned to context. Default: 32000; max: 200000. Metadata and optional links are additional. This limits extracted content, not the HTML download. Use saveToFile for a longer extracted document.",
|
|
116
132
|
},
|
|
117
133
|
responseMode: {
|
|
118
134
|
type: "string",
|
|
@@ -134,11 +150,11 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
134
150
|
},
|
|
135
151
|
includeLinks: {
|
|
136
152
|
type: "boolean",
|
|
137
|
-
description: "Whether extracted HTML responses should include a compact links list. Default: true for
|
|
153
|
+
description: "Whether extracted HTML responses should include a compact links list. Default: true for inline responses and false when saveToFile is set.",
|
|
138
154
|
},
|
|
139
155
|
search: {
|
|
140
156
|
type: "object",
|
|
141
|
-
description: "Optional post-fetch search over extracted content by default. Supports {query, queries, terms, regex, regexFlags, source:'extracted'|'raw', maxMatches, contextChars, caseSensitive}. Regex is safety-checked and bounded; prefer query/terms for simple grep-like searches.",
|
|
157
|
+
description: "Optional post-fetch search over extracted content by default. Searches at most the first 500,000 characters of the selected source; saved results report searchSourceTruncated when this limit is reached. Supports {query, queries, terms, regex, regexFlags, source:'extracted'|'raw', maxMatches, contextChars, caseSensitive}. Regex is safety-checked and bounded; prefer query/terms for simple grep-like searches.",
|
|
142
158
|
properties: {
|
|
143
159
|
query: { type: "string" },
|
|
144
160
|
queries: { type: "array", items: { type: "string" } },
|
|
@@ -153,7 +169,7 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
153
169
|
},
|
|
154
170
|
saveToFile: {
|
|
155
171
|
type: "string",
|
|
156
|
-
description: "Workspace
|
|
172
|
+
description: "Workspace path to stage a response up to 20 MB (e.g. 'scratch/research/page.md'). HTML saves full extracted Markdown/text unless responseMode is raw; non-HTML and raw mode save the response body. With search, returns matches bounded by maxChars and reports when source scanning was capped; without search, returns a preview.",
|
|
157
173
|
},
|
|
158
174
|
},
|
|
159
175
|
required: ["url"],
|
|
@@ -295,6 +311,9 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
295
311
|
}
|
|
296
312
|
const contentType = response.headers.get("content-type")?.split(";")[0].trim() ??
|
|
297
313
|
"text/plain";
|
|
314
|
+
const requestedResponseMode = String(args.responseMode ?? "auto");
|
|
315
|
+
const normalizedResponseMode = requestedResponseMode.toLowerCase();
|
|
316
|
+
const isHtmlContentType = isHtmlResponseContentType(contentType);
|
|
298
317
|
const httpErrorCode = response.ok
|
|
299
318
|
? undefined
|
|
300
319
|
: `http_${response.status}`;
|
|
@@ -335,10 +354,11 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
335
354
|
}
|
|
336
355
|
let body;
|
|
337
356
|
let bodyResult;
|
|
357
|
+
const readLimit = saveToFilePath ||
|
|
358
|
+
(isHtmlContentType && normalizedResponseMode !== "raw")
|
|
359
|
+
? MAX_WEB_REQUEST_HTML_BYTES
|
|
360
|
+
: MAX_EXTENSION_PROXY_RESPONSE_SIZE;
|
|
338
361
|
try {
|
|
339
|
-
const readLimit = saveToFilePath
|
|
340
|
-
? 20 * 1024 * 1024
|
|
341
|
-
: MAX_EXTENSION_PROXY_RESPONSE_SIZE;
|
|
342
362
|
bodyResult = await readResponseTextWithLimit(response, readLimit);
|
|
343
363
|
}
|
|
344
364
|
catch {
|
|
@@ -347,8 +367,15 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
347
367
|
});
|
|
348
368
|
}
|
|
349
369
|
if (bodyResult.truncated) {
|
|
350
|
-
|
|
351
|
-
|
|
370
|
+
const declaredBytes = Number(response.headers.get("content-length"));
|
|
371
|
+
const exceedsSaveLimit = readLimit === MAX_WEB_REQUEST_HTML_BYTES ||
|
|
372
|
+
(Number.isFinite(declaredBytes) &&
|
|
373
|
+
declaredBytes > MAX_WEB_REQUEST_HTML_BYTES);
|
|
374
|
+
const recovery = exceedsSaveLimit
|
|
375
|
+
? `The response exceeds web-request's ${MAX_WEB_REQUEST_HTML_BYTES}-byte limit.`
|
|
376
|
+
: `Retry with saveToFile to stage responses up to ${MAX_WEB_REQUEST_HTML_BYTES} bytes.`;
|
|
377
|
+
fail(`HTTP ${response.status} ${response.statusText}\n\nResponse too large: at least ${bodyResult.size} bytes observed; maximum ${readLimit} bytes. ${recovery}`, {
|
|
378
|
+
errorCode: "web_request_response_too_large",
|
|
352
379
|
});
|
|
353
380
|
}
|
|
354
381
|
body = bodyResult.text;
|
|
@@ -361,21 +388,69 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
361
388
|
}
|
|
362
389
|
let displayBody;
|
|
363
390
|
let processedMode = "raw";
|
|
391
|
+
let searchResultsTruncated = false;
|
|
392
|
+
let searchSourceTruncated = false;
|
|
393
|
+
let fileContent = body;
|
|
394
|
+
let fileContentType = contentType;
|
|
395
|
+
const search = parseWebContentSearchOptions(args.search);
|
|
396
|
+
const hasSearch = hasWebContentSearch(search);
|
|
397
|
+
const includeLinks = args.includeLinks === undefined
|
|
398
|
+
? !saveToFilePath
|
|
399
|
+
: parseBooleanArg(args.includeLinks);
|
|
400
|
+
const saveContentFormat = saveToFilePath &&
|
|
401
|
+
isHtmlContentType &&
|
|
402
|
+
normalizedResponseMode !== "raw"
|
|
403
|
+
? normalizedResponseMode === "text"
|
|
404
|
+
? "text"
|
|
405
|
+
: "markdown"
|
|
406
|
+
: undefined;
|
|
364
407
|
try {
|
|
365
408
|
const processed = await processWebContent({
|
|
366
409
|
url: resolvedUrl,
|
|
367
410
|
body,
|
|
368
411
|
contentType,
|
|
369
|
-
responseMode:
|
|
412
|
+
responseMode: saveToFilePath && hasSearch ? "matches" : requestedResponseMode,
|
|
370
413
|
extract: String(args.extract ?? "readability"),
|
|
371
|
-
includeLinks
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
maxChars,
|
|
414
|
+
includeLinks,
|
|
415
|
+
search,
|
|
416
|
+
maxChars: saveContentFormat ? null : maxChars,
|
|
417
|
+
saveContentFormat,
|
|
376
418
|
});
|
|
377
419
|
processedMode = processed.mode;
|
|
420
|
+
searchSourceTruncated = processed.searchTruncated ?? false;
|
|
378
421
|
displayBody = formatWebContentResult(processed);
|
|
422
|
+
if (saveToFilePath && hasSearch && displayBody.length > maxChars) {
|
|
423
|
+
searchResultsTruncated = true;
|
|
424
|
+
displayBody = truncateToolText(displayBody, maxChars);
|
|
425
|
+
}
|
|
426
|
+
if (saveContentFormat) {
|
|
427
|
+
if (processed.fullContent === undefined) {
|
|
428
|
+
throw new Error("HTML extraction did not produce saved content");
|
|
429
|
+
}
|
|
430
|
+
fileContent = formatWebContentResult({
|
|
431
|
+
...processed,
|
|
432
|
+
mode: saveContentFormat,
|
|
433
|
+
content: processed.fullContent,
|
|
434
|
+
fullContent: undefined,
|
|
435
|
+
matches: undefined,
|
|
436
|
+
totalMatches: undefined,
|
|
437
|
+
omittedMatches: undefined,
|
|
438
|
+
searchSource: undefined,
|
|
439
|
+
searchTruncated: undefined,
|
|
440
|
+
truncated: false,
|
|
441
|
+
});
|
|
442
|
+
fileContentType =
|
|
443
|
+
saveContentFormat === "markdown"
|
|
444
|
+
? "text/markdown"
|
|
445
|
+
: "text/plain";
|
|
446
|
+
}
|
|
447
|
+
if (!saveToFilePath &&
|
|
448
|
+
isHtmlContentType &&
|
|
449
|
+
normalizedResponseMode !== "raw" &&
|
|
450
|
+
processed.truncated &&
|
|
451
|
+
processed.contentLength !== undefined) {
|
|
452
|
+
displayBody += `\n\nFull extracted content: ${processed.contentLength} characters. Retry with saveToFile (up to ${MAX_WEB_REQUEST_HTML_BYTES} bytes), then use workspace-files grep or read with offsets.`;
|
|
453
|
+
}
|
|
379
454
|
}
|
|
380
455
|
catch (err) {
|
|
381
456
|
fail(`web-request post-processing error: ${err?.message ?? String(err)}`, { errorCode: httpErrorCode ?? "web_request_processing_failed" });
|
|
@@ -383,7 +458,7 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
383
458
|
console.log(`[fetch-tool] ${method} ${rawUrl} → ${response.status} (${elapsed}ms, keys: ${allUsedKeys.join(",") || "none"})`);
|
|
384
459
|
if (saveToFilePath) {
|
|
385
460
|
try {
|
|
386
|
-
const { writeWorkspaceFile,
|
|
461
|
+
const { writeWorkspaceFile, isScratchWorkspacePath, toWorkspaceFileCard, } = await import("../workspace-files/store.js");
|
|
387
462
|
const { getRequestOrgId, getRequestUserEmail } = await import("../server/request-context.js");
|
|
388
463
|
const orgId = getRequestOrgId();
|
|
389
464
|
const email = getRequestUserEmail();
|
|
@@ -398,21 +473,37 @@ export function createFetchToolEntry(opts = {}) {
|
|
|
398
473
|
if (!response.ok && !scratchPath) {
|
|
399
474
|
throw new Error(`Refusing to save a failed response to durable workspace file "${saveToFilePath}" (status ${response.status}). Use a scratch/... path for diagnostics.`);
|
|
400
475
|
}
|
|
401
|
-
const
|
|
476
|
+
const savedFormat = saveContentFormat ?? "raw";
|
|
477
|
+
const meta = await writeWorkspaceFile(scope, saveToFilePath, fileContent, fileContentType, {
|
|
402
478
|
maxFileBytes: SAVE_TO_FILE_MAX_BYTES,
|
|
403
479
|
});
|
|
404
|
-
const bytes = Buffer.byteLength(
|
|
405
|
-
const
|
|
480
|
+
const bytes = Buffer.byteLength(fileContent, "utf8");
|
|
481
|
+
const previewSource = saveContentFormat
|
|
482
|
+
? fileContent
|
|
483
|
+
: displayBody;
|
|
484
|
+
const preview = previewSource.slice(0, 2000);
|
|
406
485
|
if (!response.ok)
|
|
407
|
-
fail(`HTTP ${response.status} ${response.statusText}\n\n${displayBody}`, { errorCode: `http_${response.status}` });
|
|
486
|
+
fail(`HTTP ${response.status} ${response.statusText}\n\n${truncateToolText(displayBody, maxChars)}`, { errorCode: `http_${response.status}` });
|
|
408
487
|
return JSON.stringify({
|
|
409
488
|
savedToFile: true,
|
|
410
489
|
savedTo: saveToFilePath,
|
|
411
490
|
status: response.status,
|
|
412
491
|
bytes,
|
|
492
|
+
chars: fileContent.length,
|
|
413
493
|
contentType,
|
|
494
|
+
savedFormat,
|
|
414
495
|
responseMode: processedMode,
|
|
415
|
-
|
|
496
|
+
...(hasSearch
|
|
497
|
+
? {
|
|
498
|
+
searchResults: displayBody,
|
|
499
|
+
searchResultsTruncated,
|
|
500
|
+
searchSourceTruncated,
|
|
501
|
+
}
|
|
502
|
+
: {
|
|
503
|
+
preview: preview.length < previewSource.length
|
|
504
|
+
? `${preview}…`
|
|
505
|
+
: preview,
|
|
506
|
+
}),
|
|
416
507
|
...(scratchPath ? {} : { file: toWorkspaceFileCard(meta) }),
|
|
417
508
|
});
|
|
418
509
|
}
|
|
@@ -914,6 +914,7 @@ export declare const EXTENSIONS_HIDDEN_AT_COLUMN_SQL = "ALTER TABLE tools ADD CO
|
|
|
914
914
|
export declare const EXTENSIONS_HIDDEN_BY_COLUMN_SQL = "ALTER TABLE tools ADD COLUMN IF NOT EXISTS hidden_by TEXT";
|
|
915
915
|
export declare const EXTENSIONS_HIDDEN_AT_INDEX_SQL = "CREATE INDEX IF NOT EXISTS tools_hidden_at_idx ON tools (hidden_at)";
|
|
916
916
|
export declare const EXTENSION_SHARES_RESOURCE_INDEX_SQL = "CREATE INDEX IF NOT EXISTS tool_shares_resource_idx ON tool_shares (resource_id)";
|
|
917
|
+
export declare const EXTENSION_SHARES_NOTIFIED_AT_COLUMN_SQL = "ALTER TABLE tool_shares ADD COLUMN IF NOT EXISTS notified_at TEXT";
|
|
917
918
|
export declare const EXTENSION_HIDES_CREATE_SQL = "CREATE TABLE IF NOT EXISTS tool_hidden_extensions (\n id TEXT PRIMARY KEY,\n tool_id TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT now()\n)";
|
|
918
919
|
export declare const EXTENSION_HIDES_UNIQUE_INDEX_SQL = "CREATE UNIQUE INDEX IF NOT EXISTS tool_hidden_extensions_user_tool_idx\n ON tool_hidden_extensions (owner_email, tool_id)";
|
|
919
920
|
export declare const EXTENSION_HIDES_OWNER_INDEX_SQL = "CREATE INDEX IF NOT EXISTS tool_hidden_extensions_owner_idx\n ON tool_hidden_extensions (owner_email)";
|
|
@@ -118,6 +118,9 @@ export const EXTENSIONS_HIDDEN_AT_COLUMN_SQL = `ALTER TABLE tools ADD COLUMN IF
|
|
|
118
118
|
export const EXTENSIONS_HIDDEN_BY_COLUMN_SQL = `ALTER TABLE tools ADD COLUMN IF NOT EXISTS hidden_by TEXT`;
|
|
119
119
|
export const EXTENSIONS_HIDDEN_AT_INDEX_SQL = `CREATE INDEX IF NOT EXISTS tools_hidden_at_idx ON tools (hidden_at)`;
|
|
120
120
|
export const EXTENSION_SHARES_RESOURCE_INDEX_SQL = `CREATE INDEX IF NOT EXISTS tool_shares_resource_idx ON tool_shares (resource_id)`;
|
|
121
|
+
// tool_shares tables created before notified_at existed never got it from the
|
|
122
|
+
// CREATE TABLE IF NOT EXISTS above, and every share insert names the column.
|
|
123
|
+
export const EXTENSION_SHARES_NOTIFIED_AT_COLUMN_SQL = `ALTER TABLE tool_shares ADD COLUMN IF NOT EXISTS notified_at TEXT`;
|
|
121
124
|
export const EXTENSION_HIDES_CREATE_SQL = `CREATE TABLE IF NOT EXISTS tool_hidden_extensions (
|
|
122
125
|
id TEXT PRIMARY KEY,
|
|
123
126
|
tool_id TEXT NOT NULL,
|
package/dist/extensions/store.js
CHANGED
|
@@ -11,7 +11,7 @@ import { accessFilter, assertAccess, resolveAccess, ForbiddenError, } from "../s
|
|
|
11
11
|
import { registerShareableResource } from "../sharing/registry.js";
|
|
12
12
|
import { EXTENSION_CHANGE_MARKER_KEY, extensionChangeMarkerSession, extensionChangeMarkerValue, } from "./change-marker.js";
|
|
13
13
|
import { applyExtensionContentUpdate, ExtensionContentEditError, } from "./content-patch.js";
|
|
14
|
-
import { extensions, extensionHides, extensionShares, extensionHistory, EXTENSIONS_CREATE_SQL, EXTENSION_SHARES_CREATE_SQL, EXTENSION_DATA_CREATE_SQL, EXTENSION_DATA_ITEM_INDEX_SQL, EXTENSION_DATA_DROP_OLD_INDEX_SQL, EXTENSIONS_OWNER_INDEX_SQL, EXTENSIONS_ORG_INDEX_SQL, EXTENSIONS_UPDATED_INDEX_SQL, EXTENSIONS_ARCHIVED_AT_COLUMN_SQL, EXTENSIONS_ARCHIVED_AT_INDEX_SQL, EXTENSIONS_HIDDEN_AT_COLUMN_SQL, EXTENSIONS_HIDDEN_BY_COLUMN_SQL, EXTENSIONS_HIDDEN_AT_INDEX_SQL, EXTENSION_SHARES_RESOURCE_INDEX_SQL, EXTENSION_HIDES_CREATE_SQL, EXTENSION_HIDES_UNIQUE_INDEX_SQL, EXTENSION_HIDES_OWNER_INDEX_SQL, EXTENSION_HISTORY_CREATE_SQL, EXTENSION_HISTORY_VERSION_INDEX_SQL, EXTENSION_HISTORY_CREATED_INDEX_SQL, EXTENSION_CONSENTS_CREATE_SQL, EXTENSION_CONSENTS_VIEWER_INDEX_SQL, } from "./schema.js";
|
|
14
|
+
import { extensions, extensionHides, extensionShares, extensionHistory, EXTENSIONS_CREATE_SQL, EXTENSION_SHARES_CREATE_SQL, EXTENSION_DATA_CREATE_SQL, EXTENSION_DATA_ITEM_INDEX_SQL, EXTENSION_DATA_DROP_OLD_INDEX_SQL, EXTENSIONS_OWNER_INDEX_SQL, EXTENSIONS_ORG_INDEX_SQL, EXTENSIONS_UPDATED_INDEX_SQL, EXTENSIONS_ARCHIVED_AT_COLUMN_SQL, EXTENSIONS_ARCHIVED_AT_INDEX_SQL, EXTENSIONS_HIDDEN_AT_COLUMN_SQL, EXTENSIONS_HIDDEN_BY_COLUMN_SQL, EXTENSIONS_HIDDEN_AT_INDEX_SQL, EXTENSION_SHARES_RESOURCE_INDEX_SQL, EXTENSION_SHARES_NOTIFIED_AT_COLUMN_SQL, EXTENSION_HIDES_CREATE_SQL, EXTENSION_HIDES_UNIQUE_INDEX_SQL, EXTENSION_HIDES_OWNER_INDEX_SQL, EXTENSION_HISTORY_CREATE_SQL, EXTENSION_HISTORY_VERSION_INDEX_SQL, EXTENSION_HISTORY_CREATED_INDEX_SQL, EXTENSION_CONSENTS_CREATE_SQL, EXTENSION_CONSENTS_VIEWER_INDEX_SQL, } from "./schema.js";
|
|
15
15
|
const getDb = createGetDb({
|
|
16
16
|
extensions,
|
|
17
17
|
extensionShares,
|
|
@@ -27,6 +27,7 @@ export async function ensureExtensionsTables() {
|
|
|
27
27
|
await ensureTableExists("tools", EXTENSIONS_CREATE_SQL);
|
|
28
28
|
await migrateMisnamedExtensionsTable(client);
|
|
29
29
|
await ensureTableExists("tool_shares", EXTENSION_SHARES_CREATE_SQL);
|
|
30
|
+
await ensureColumnExists("tool_shares", "notified_at", EXTENSION_SHARES_NOTIFIED_AT_COLUMN_SQL);
|
|
30
31
|
await ensureTableExists("tool_data", EXTENSION_DATA_CREATE_SQL);
|
|
31
32
|
await ensureExtensionDataItemId();
|
|
32
33
|
await ensureExtensionDataScope();
|
|
@@ -20,7 +20,9 @@ export interface WebContentProcessOptions {
|
|
|
20
20
|
extract?: string;
|
|
21
21
|
includeLinks?: boolean;
|
|
22
22
|
search?: WebContentSearchOptions | null;
|
|
23
|
-
|
|
23
|
+
/** `null` keeps the complete content available for a saved workspace file. */
|
|
24
|
+
maxChars?: number | null;
|
|
25
|
+
saveContentFormat?: "markdown" | "text";
|
|
24
26
|
}
|
|
25
27
|
export interface WebContentLink {
|
|
26
28
|
text: string;
|
|
@@ -45,6 +47,8 @@ export interface WebContentResult {
|
|
|
45
47
|
publishedTime?: string;
|
|
46
48
|
agentMetadata?: unknown[];
|
|
47
49
|
content?: string;
|
|
50
|
+
fullContent?: string;
|
|
51
|
+
contentLength?: number;
|
|
48
52
|
links?: WebContentLink[];
|
|
49
53
|
matches?: WebContentMatch[];
|
|
50
54
|
totalMatches?: number;
|
|
@@ -68,16 +68,33 @@ export async function processWebContent(options) {
|
|
|
68
68
|
const html = isHtmlResponse(contentType, options.body);
|
|
69
69
|
const mode = resolveMode(requestedMode, html, search);
|
|
70
70
|
const emptyHtmlBody = html && !options.body.trim();
|
|
71
|
-
const maxChars =
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const maxChars = options.maxChars === null
|
|
72
|
+
? Number.POSITIVE_INFINITY
|
|
73
|
+
: normalizeBoundedNumber(options.maxChars, DEFAULT_MAX_CONTENT_CHARS, 1, 200_000);
|
|
74
|
+
const extracted = html &&
|
|
75
|
+
!emptyHtmlBody &&
|
|
76
|
+
(mode !== "raw" || hasWebContentSearch(search) || options.saveContentFormat)
|
|
77
|
+
? await extractHtml(options.body, options.url, extract, mode === "markdown" ||
|
|
78
|
+
mode === "matches" ||
|
|
79
|
+
options.saveContentFormat === "markdown")
|
|
74
80
|
: null;
|
|
75
81
|
const baseContent = contentForMode(mode, options.body, extracted);
|
|
82
|
+
const fullContent = options.saveContentFormat
|
|
83
|
+
? options.saveContentFormat === "text"
|
|
84
|
+
? (extracted?.text ?? (extracted ? "" : options.body))
|
|
85
|
+
: extracted?.markdown ||
|
|
86
|
+
extracted?.text ||
|
|
87
|
+
(extracted ? "" : options.body)
|
|
88
|
+
: undefined;
|
|
76
89
|
const result = {
|
|
77
90
|
mode,
|
|
78
91
|
extract,
|
|
79
92
|
contentType,
|
|
80
93
|
...metadataFromExtraction(extracted),
|
|
94
|
+
...(fullContent !== undefined ? { fullContent } : {}),
|
|
95
|
+
...(mode !== "links" && mode !== "metadata"
|
|
96
|
+
? { contentLength: baseContent.length }
|
|
97
|
+
: {}),
|
|
81
98
|
};
|
|
82
99
|
if (emptyHtmlBody &&
|
|
83
100
|
mode !== "raw" &&
|
|
@@ -183,9 +200,10 @@ function resolveMode(requestedMode, html, search) {
|
|
|
183
200
|
}
|
|
184
201
|
function isHtmlResponse(contentType, body) {
|
|
185
202
|
if (contentType) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
203
|
+
const mediaType = contentType.toLowerCase();
|
|
204
|
+
return (mediaType === "text/html" ||
|
|
205
|
+
mediaType === "application/xhtml+xml" ||
|
|
206
|
+
mediaType.endsWith("+html"));
|
|
189
207
|
}
|
|
190
208
|
return /<!doctype html|<html[\s>]|<body[\s>]|<article[\s>]/i.test(body.slice(0, 2_000));
|
|
191
209
|
}
|
|
@@ -75,10 +75,10 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
75
75
|
user: "user";
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
|
-
message?: undefined;
|
|
79
|
-
id?: undefined;
|
|
80
78
|
provider?: undefined;
|
|
81
79
|
deleted?: undefined;
|
|
80
|
+
id?: undefined;
|
|
81
|
+
found?: undefined;
|
|
82
82
|
providers: {
|
|
83
83
|
id: string;
|
|
84
84
|
label: string;
|
|
@@ -89,45 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
89
89
|
updatedAt: number;
|
|
90
90
|
}[];
|
|
91
91
|
count: number;
|
|
92
|
-
found?: undefined;
|
|
93
92
|
registered?: undefined;
|
|
94
93
|
label?: undefined;
|
|
95
|
-
} | {
|
|
96
94
|
message?: undefined;
|
|
97
|
-
|
|
95
|
+
} | {
|
|
98
96
|
deleted?: undefined;
|
|
99
|
-
|
|
97
|
+
id?: undefined;
|
|
100
98
|
count?: undefined;
|
|
99
|
+
providers?: undefined;
|
|
101
100
|
found: boolean;
|
|
102
101
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
103
102
|
registered?: undefined;
|
|
104
103
|
label?: undefined;
|
|
105
|
-
} | {
|
|
106
104
|
message?: undefined;
|
|
105
|
+
} | {
|
|
107
106
|
provider?: undefined;
|
|
108
107
|
deleted?: undefined;
|
|
109
|
-
providers?: undefined;
|
|
110
108
|
count?: undefined;
|
|
109
|
+
providers?: undefined;
|
|
111
110
|
found: boolean;
|
|
112
111
|
id: string;
|
|
113
112
|
registered?: undefined;
|
|
114
113
|
label?: undefined;
|
|
115
|
-
} | {
|
|
116
114
|
message?: undefined;
|
|
115
|
+
} | {
|
|
117
116
|
provider?: undefined;
|
|
118
|
-
providers?: undefined;
|
|
119
117
|
count?: undefined;
|
|
120
118
|
found?: undefined;
|
|
119
|
+
providers?: undefined;
|
|
121
120
|
deleted: boolean;
|
|
122
121
|
id: string;
|
|
123
122
|
registered?: undefined;
|
|
124
123
|
label?: undefined;
|
|
124
|
+
message?: undefined;
|
|
125
125
|
} | {
|
|
126
126
|
provider?: undefined;
|
|
127
127
|
deleted?: undefined;
|
|
128
|
-
providers?: undefined;
|
|
129
128
|
count?: undefined;
|
|
130
129
|
found?: undefined;
|
|
130
|
+
providers?: undefined;
|
|
131
131
|
registered: boolean;
|
|
132
132
|
id: string;
|
|
133
133
|
label: string;
|
|
@@ -311,10 +311,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
311
311
|
notes?: string | undefined;
|
|
312
312
|
scope?: "org" | "user" | undefined;
|
|
313
313
|
}, {
|
|
314
|
-
provider?: undefined;
|
|
315
|
-
deleted?: undefined;
|
|
316
314
|
id?: undefined;
|
|
315
|
+
deleted?: undefined;
|
|
317
316
|
message?: undefined;
|
|
317
|
+
found?: undefined;
|
|
318
318
|
providers: {
|
|
319
319
|
id: string;
|
|
320
320
|
label: string;
|
|
@@ -325,12 +325,12 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
325
325
|
updatedAt: number;
|
|
326
326
|
}[];
|
|
327
327
|
count: number;
|
|
328
|
-
|
|
328
|
+
provider?: undefined;
|
|
329
329
|
registered?: undefined;
|
|
330
330
|
label?: undefined;
|
|
331
331
|
} | {
|
|
332
|
-
deleted?: undefined;
|
|
333
332
|
id?: undefined;
|
|
333
|
+
deleted?: undefined;
|
|
334
334
|
count?: undefined;
|
|
335
335
|
message?: undefined;
|
|
336
336
|
providers?: undefined;
|
|
@@ -339,31 +339,31 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
339
339
|
registered?: undefined;
|
|
340
340
|
label?: undefined;
|
|
341
341
|
} | {
|
|
342
|
-
provider?: undefined;
|
|
343
342
|
deleted?: undefined;
|
|
344
343
|
count?: undefined;
|
|
345
344
|
message?: undefined;
|
|
346
345
|
providers?: undefined;
|
|
346
|
+
provider?: undefined;
|
|
347
347
|
found: boolean;
|
|
348
348
|
id: string;
|
|
349
349
|
registered?: undefined;
|
|
350
350
|
label?: undefined;
|
|
351
351
|
} | {
|
|
352
|
-
provider?: undefined;
|
|
353
352
|
count?: undefined;
|
|
354
353
|
message?: undefined;
|
|
355
|
-
providers?: undefined;
|
|
356
354
|
found?: undefined;
|
|
355
|
+
providers?: undefined;
|
|
356
|
+
provider?: undefined;
|
|
357
357
|
deleted: boolean;
|
|
358
358
|
id: string;
|
|
359
359
|
registered?: undefined;
|
|
360
360
|
label?: undefined;
|
|
361
361
|
} | {
|
|
362
|
-
provider?: undefined;
|
|
363
362
|
deleted?: undefined;
|
|
364
363
|
count?: undefined;
|
|
365
|
-
providers?: undefined;
|
|
366
364
|
found?: undefined;
|
|
365
|
+
providers?: undefined;
|
|
366
|
+
provider?: undefined;
|
|
367
367
|
registered: boolean;
|
|
368
368
|
id: string;
|
|
369
369
|
label: string;
|
|
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
73
73
|
offset?: unknown;
|
|
74
74
|
limit?: unknown;
|
|
75
75
|
}, {
|
|
76
|
+
deleted?: undefined;
|
|
76
77
|
jobs: {
|
|
77
78
|
id: string;
|
|
78
79
|
name: string;
|
|
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
83
84
|
updatedAt: string;
|
|
84
85
|
}[];
|
|
85
86
|
total: number;
|
|
86
|
-
deleted?: undefined;
|
|
87
87
|
jobId?: undefined;
|
|
88
88
|
} | {
|
|
89
89
|
jobs?: undefined;
|
|
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
91
91
|
deleted: boolean;
|
|
92
92
|
jobId: string;
|
|
93
93
|
} | {
|
|
94
|
+
deleted?: undefined;
|
|
94
95
|
jobs?: undefined;
|
|
95
96
|
total?: undefined;
|
|
96
|
-
deleted?: undefined;
|
|
97
97
|
jobId?: undefined;
|
|
98
98
|
hits: Record<string, unknown>[];
|
|
99
99
|
offset: number;
|