@agent-native/core 0.208.0 → 0.208.1-nightly-20261013212700
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/dist/agent/context-xray/tokenize.js +12 -3
- package/dist/agent/run-manager.js +47 -10
- package/dist/agent/run-store.d.ts +10 -0
- package/dist/agent/run-store.js +37 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/fetch-tool.js +114 -23
- package/dist/extensions/web-content.d.ts +5 -1
- package/dist/extensions/web-content.js +24 -6
- package/dist/observability/routes.d.ts +5 -5
- package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +10 -10
- 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/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/shared/context-status.js +1 -1
- 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/triggers/actions/manage-automation.d.ts +2 -2
- 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
|
@@ -7,9 +7,18 @@ async function loadTokenizer() {
|
|
|
7
7
|
// browser fallback, while the documented estimate below is sufficient
|
|
8
8
|
// when an edge runtime cannot resolve the tokenizer.
|
|
9
9
|
tokenizerPromise = import(/* @vite-ignore */ TOKENIZER_MODULE_ID)
|
|
10
|
-
.then((mod) =>
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
.then((mod) => {
|
|
11
|
+
// The package's countTokens rebuilds the BPE encoder on every call
|
|
12
|
+
// (~20 ms); counting a whole context part by part before each model
|
|
13
|
+
// call turned that into seconds of dead time per turn.
|
|
14
|
+
if (typeof mod.getTokenizer === "function") {
|
|
15
|
+
const encoder = mod.getTokenizer();
|
|
16
|
+
return (text) => encoder.encode(text.normalize("NFKC"), "all").length;
|
|
17
|
+
}
|
|
18
|
+
return typeof mod.countTokens === "function"
|
|
19
|
+
? mod.countTokens
|
|
20
|
+
: null;
|
|
21
|
+
})
|
|
13
22
|
.catch(() => null);
|
|
14
23
|
}
|
|
15
24
|
return tokenizerPromise;
|
|
@@ -10,7 +10,7 @@ import { classifyTerminalErrorCode, describeErrorWithCauses, isProviderConnectio
|
|
|
10
10
|
import { runErrorTelemetryProperties } from "./engine/error-telemetry.js";
|
|
11
11
|
import { getAgentEngineEntry } from "./engine/registry.js";
|
|
12
12
|
import { EngineError } from "./engine/types.js";
|
|
13
|
-
import { insertRun, insertRunEvent, updateRunStatusIfRunning, markRunAborted, getRunAbortState, getRunStatus, getRunEventsSince, getCurrentTurnRunEventsForThread, getRunById, getRunByThread, getRunTurnRef, markTurnAborted, cleanupOldRuns, updateRunHeartbeat, bumpRunProgress, setRunInFlightMarker, reapIfStale, reapUnclaimedBackgroundRun, shouldRedispatchUnclaimedBackgroundRun, reconcileTerminalRunFromEvents, ensureTerminalRunEvent, getLastTerminalRunEvent, resolveErroredRunTerminalEvent, setRunError, setRunTerminalReason, persistRunCheckpointEvent, recordRunDiagnostic, RUN_DIAG_STAGE, terminalEventForAbortReason, RUN_RECORD_MISSING_ERROR_EVENT, RUN_RECORD_MISSING_GRACE_MS, RUN_TERMINAL_LOOKUP_FAILED_ERROR_EVENT, UNKNOWN_RUN_STATUS_ERROR_EVENT, } from "./run-store.js";
|
|
13
|
+
import { insertRun, insertRunEvent, insertRunEvents, updateRunStatusIfRunning, markRunAborted, getRunAbortState, getRunStatus, getRunEventsSince, getCurrentTurnRunEventsForThread, getRunById, getRunByThread, getRunTurnRef, markTurnAborted, cleanupOldRuns, updateRunHeartbeat, bumpRunProgress, setRunInFlightMarker, reapIfStale, reapUnclaimedBackgroundRun, shouldRedispatchUnclaimedBackgroundRun, reconcileTerminalRunFromEvents, ensureTerminalRunEvent, getLastTerminalRunEvent, resolveErroredRunTerminalEvent, setRunError, setRunTerminalReason, persistRunCheckpointEvent, recordRunDiagnostic, RUN_DIAG_STAGE, terminalEventForAbortReason, RUN_RECORD_MISSING_ERROR_EVENT, RUN_RECORD_MISSING_GRACE_MS, RUN_TERMINAL_LOOKUP_FAILED_ERROR_EVENT, UNKNOWN_RUN_STATUS_ERROR_EVENT, } from "./run-store.js";
|
|
14
14
|
import { isContinuationTerminalReason } from "./types.js";
|
|
15
15
|
const activeRuns = new Map();
|
|
16
16
|
const threadToRun = new Map();
|
|
@@ -232,6 +232,11 @@ function isTerminalRunEvent(event) {
|
|
|
232
232
|
event.type === "loop_limit" ||
|
|
233
233
|
event.type === "auto_continue");
|
|
234
234
|
}
|
|
235
|
+
function isBatchableRunEvent(event) {
|
|
236
|
+
return (event.type !== "tool_start" &&
|
|
237
|
+
event.type !== "tool_done" &&
|
|
238
|
+
!isTerminalRunEvent(event));
|
|
239
|
+
}
|
|
235
240
|
/**
|
|
236
241
|
* A tool result with no later assistant text is an unfinished turn, not a
|
|
237
242
|
* successful terminal response. Keep this predicate beside the run-manager's
|
|
@@ -570,6 +575,10 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
570
575
|
throw error;
|
|
571
576
|
});
|
|
572
577
|
let persistenceChain = Promise.resolve();
|
|
578
|
+
// Streamed deltas arrive hundreds per tool call, and a write tool waits for
|
|
579
|
+
// every queued event to persist first; one round trip per event put tens of
|
|
580
|
+
// seconds between the model finishing and the tool starting.
|
|
581
|
+
let openEventBatch = null;
|
|
573
582
|
const PROGRESS_BUMP_INTERVAL_MS = 1_000;
|
|
574
583
|
let lastProgressBumpAt = 0;
|
|
575
584
|
let progressWriteInFlight = null;
|
|
@@ -1029,18 +1038,20 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1029
1038
|
},
|
|
1030
1039
|
});
|
|
1031
1040
|
};
|
|
1032
|
-
const
|
|
1041
|
+
const persistEventHook = options?.persistEvent;
|
|
1042
|
+
const persistRunEvent = async (runEvent, eventData, eventAt) => {
|
|
1033
1043
|
if (runEvent.event.type === "tool_start")
|
|
1034
1044
|
await insertRunPromise;
|
|
1035
1045
|
const write = () => runEvent.event.type === "tool_start" ||
|
|
1036
1046
|
runEvent.event.type === "tool_done"
|
|
1037
1047
|
? insertRunEvent(runId, runEvent.seq, eventData, {
|
|
1048
|
+
eventAt,
|
|
1038
1049
|
toolInputSource: "execution",
|
|
1039
1050
|
...(runEvent.event.type === "tool_start"
|
|
1040
1051
|
? { requireInserted: true }
|
|
1041
1052
|
: {}),
|
|
1042
1053
|
})
|
|
1043
|
-
: insertRunEvent(runId, runEvent.seq, eventData);
|
|
1054
|
+
: insertRunEvent(runId, runEvent.seq, eventData, { eventAt });
|
|
1044
1055
|
return options?.persistEvent
|
|
1045
1056
|
? options.persistEvent(write, {
|
|
1046
1057
|
terminal: isTerminalRunEvent(runEvent.event),
|
|
@@ -1052,6 +1063,7 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1052
1063
|
};
|
|
1053
1064
|
const emitRunEvent = (runEvent, options) => {
|
|
1054
1065
|
const eventData = JSON.stringify(runEvent.event);
|
|
1066
|
+
const eventAt = Date.now();
|
|
1055
1067
|
run.events.push(runEvent);
|
|
1056
1068
|
for (const subscriber of run.subscribers) {
|
|
1057
1069
|
try {
|
|
@@ -1066,9 +1078,9 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1066
1078
|
lastRealProgressAt = Date.now();
|
|
1067
1079
|
bumpProgressIfDue();
|
|
1068
1080
|
}
|
|
1069
|
-
const
|
|
1081
|
+
const retryOnce = async (write) => {
|
|
1070
1082
|
try {
|
|
1071
|
-
await
|
|
1083
|
+
await write();
|
|
1072
1084
|
}
|
|
1073
1085
|
catch (error) {
|
|
1074
1086
|
if (!eventPersistenceErrorCaptured) {
|
|
@@ -1078,11 +1090,36 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1078
1090
|
eventType: runEvent.event.type,
|
|
1079
1091
|
});
|
|
1080
1092
|
}
|
|
1081
|
-
await
|
|
1093
|
+
await write();
|
|
1082
1094
|
}
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1095
|
+
};
|
|
1096
|
+
let persistence;
|
|
1097
|
+
if (isBatchableRunEvent(runEvent.event) && !persistEventHook) {
|
|
1098
|
+
if (!openEventBatch) {
|
|
1099
|
+
const batch = {
|
|
1100
|
+
events: [],
|
|
1101
|
+
write: persistenceChain.then(() => {
|
|
1102
|
+
if (openEventBatch === batch)
|
|
1103
|
+
openEventBatch = null;
|
|
1104
|
+
return retryOnce(() => insertRunEvents(runId, batch.events));
|
|
1105
|
+
}),
|
|
1106
|
+
};
|
|
1107
|
+
openEventBatch = batch;
|
|
1108
|
+
persistenceChain = batch.write;
|
|
1109
|
+
}
|
|
1110
|
+
openEventBatch.events.push({
|
|
1111
|
+
seq: runEvent.seq,
|
|
1112
|
+
eventAt,
|
|
1113
|
+
eventData,
|
|
1114
|
+
});
|
|
1115
|
+
persistence = openEventBatch.write;
|
|
1116
|
+
}
|
|
1117
|
+
else {
|
|
1118
|
+
// Anything emitted after this event must not persist before it.
|
|
1119
|
+
openEventBatch = null;
|
|
1120
|
+
persistence = persistenceChain.then(() => retryOnce(() => persistRunEvent(runEvent, eventData, eventAt)));
|
|
1121
|
+
persistenceChain = persistence;
|
|
1122
|
+
}
|
|
1086
1123
|
if (!options?.surfacePersistenceError) {
|
|
1087
1124
|
persistence.catch(() => { });
|
|
1088
1125
|
}
|
|
@@ -1275,7 +1312,7 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1275
1312
|
console.error("[run-manager] terminal event persistence error:", err instanceof Error ? err.message : err);
|
|
1276
1313
|
if (!eventPersistenceError) {
|
|
1277
1314
|
try {
|
|
1278
|
-
await persistRunEvent(terminal, JSON.stringify(terminal.event));
|
|
1315
|
+
await persistRunEvent(terminal, JSON.stringify(terminal.event), Date.now());
|
|
1279
1316
|
terminalPersistenceError = null;
|
|
1280
1317
|
}
|
|
1281
1318
|
catch (retryError) {
|
|
@@ -285,7 +285,17 @@ export declare class AgentRunEventNotPersistedError extends Error {
|
|
|
285
285
|
export declare function insertRunEvent(runId: string, seq: number, eventData: string, options?: {
|
|
286
286
|
toolInputSource?: "execution";
|
|
287
287
|
requireInserted?: boolean;
|
|
288
|
+
eventAt?: number;
|
|
288
289
|
}): Promise<void>;
|
|
290
|
+
/**
|
|
291
|
+
* Same guarantees as `insertRunEvent` without execution-input fingerprints,
|
|
292
|
+
* so tool_start/tool_done must keep going through `insertRunEvent`.
|
|
293
|
+
*/
|
|
294
|
+
export declare function insertRunEvents(runId: string, events: ReadonlyArray<{
|
|
295
|
+
seq: number;
|
|
296
|
+
eventAt: number;
|
|
297
|
+
eventData: string;
|
|
298
|
+
}>): Promise<void>;
|
|
289
299
|
export declare const CHECKPOINT_TERMINAL_EVENT_SEQ = 1000000000;
|
|
290
300
|
export declare function persistRunCheckpointEvent(runId: string, event: AgentChatEvent, terminalReason: string): Promise<void>;
|
|
291
301
|
export declare function getRunEventsSince(runId: string, fromSeq: number, opts?: {
|
package/dist/agent/run-store.js
CHANGED
|
@@ -1910,7 +1910,7 @@ export async function insertRunEvent(runId, seq, eventData, options) {
|
|
|
1910
1910
|
args: [
|
|
1911
1911
|
runId,
|
|
1912
1912
|
seq,
|
|
1913
|
-
Date.now(),
|
|
1913
|
+
options?.eventAt ?? Date.now(),
|
|
1914
1914
|
storedEventData,
|
|
1915
1915
|
...(options?.requireInserted ? [] : [runId]),
|
|
1916
1916
|
],
|
|
@@ -1918,6 +1918,42 @@ export async function insertRunEvent(runId, seq, eventData, options) {
|
|
|
1918
1918
|
if (options?.requireInserted && rowsAffected !== 1)
|
|
1919
1919
|
throw new AgentRunEventNotPersistedError(runId, seq);
|
|
1920
1920
|
}
|
|
1921
|
+
// Stays well under PostgreSQL's 65,535 bind-parameter limit at 4 per row.
|
|
1922
|
+
const RUN_EVENT_BATCH_ROWS = 500;
|
|
1923
|
+
/**
|
|
1924
|
+
* Same guarantees as `insertRunEvent` without execution-input fingerprints,
|
|
1925
|
+
* so tool_start/tool_done must keep going through `insertRunEvent`.
|
|
1926
|
+
*/
|
|
1927
|
+
export async function insertRunEvents(runId, events) {
|
|
1928
|
+
if (events.length === 0)
|
|
1929
|
+
return;
|
|
1930
|
+
await ensureRunTables();
|
|
1931
|
+
const client = getDbExec();
|
|
1932
|
+
for (let start = 0; start < events.length; start += RUN_EVENT_BATCH_ROWS) {
|
|
1933
|
+
const chunk = events.slice(start, start + RUN_EVENT_BATCH_ROWS);
|
|
1934
|
+
await client.execute({
|
|
1935
|
+
sql: `INSERT INTO agent_run_events (run_id, seq, event_at, event_data)
|
|
1936
|
+
SELECT v.run_id, v.seq, v.event_at, v.event_data
|
|
1937
|
+
FROM (VALUES ${chunk
|
|
1938
|
+
.map(() => "(CAST(? AS TEXT), CAST(? AS BIGINT), CAST(? AS BIGINT), CAST(? AS TEXT))")
|
|
1939
|
+
.join(", ")}) AS v(run_id, seq, event_at, event_data)
|
|
1940
|
+
WHERE NOT EXISTS (
|
|
1941
|
+
SELECT 1 FROM agent_runs
|
|
1942
|
+
WHERE id = ? AND status <> 'running'
|
|
1943
|
+
)
|
|
1944
|
+
ON CONFLICT (run_id, seq) DO NOTHING`,
|
|
1945
|
+
args: [
|
|
1946
|
+
...chunk.flatMap(({ seq, eventAt, eventData }) => [
|
|
1947
|
+
runId,
|
|
1948
|
+
seq,
|
|
1949
|
+
eventAt,
|
|
1950
|
+
persistedRunEventData(eventData),
|
|
1951
|
+
]),
|
|
1952
|
+
runId,
|
|
1953
|
+
],
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1921
1957
|
export const CHECKPOINT_TERMINAL_EVENT_SEQ = 1_000_000_000;
|
|
1922
1958
|
export async function persistRunCheckpointEvent(runId, event, terminalReason) {
|
|
1923
1959
|
await insertRunEvent(runId, CHECKPOINT_TERMINAL_EVENT_SEQ, JSON.stringify(event));
|
|
@@ -38,19 +38,19 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
38
38
|
error: string;
|
|
39
39
|
states?: undefined;
|
|
40
40
|
} | {
|
|
41
|
-
error?: undefined;
|
|
42
41
|
states: {
|
|
43
42
|
clientId: number;
|
|
44
43
|
state: string;
|
|
45
44
|
}[];
|
|
45
|
+
error?: undefined;
|
|
46
46
|
}>>;
|
|
47
47
|
export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
48
48
|
error: string;
|
|
49
49
|
users?: undefined;
|
|
50
50
|
} | {
|
|
51
|
-
error?: undefined;
|
|
52
51
|
users: {
|
|
53
52
|
clientId: number;
|
|
54
53
|
lastSeen: number;
|
|
55
54
|
}[];
|
|
55
|
+
error?: undefined;
|
|
56
56
|
}>>;
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
13
13
|
};
|
|
14
14
|
}>>;
|
|
15
15
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
error: string;
|
|
17
16
|
ok?: undefined;
|
|
17
|
+
error: string;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|
|
@@ -27,39 +27,39 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
27
27
|
thumbsUpRate: number;
|
|
28
28
|
avgEvalScore: number;
|
|
29
29
|
} | {
|
|
30
|
+
ok?: undefined;
|
|
30
31
|
error: string;
|
|
31
32
|
message: string;
|
|
32
33
|
summary?: undefined;
|
|
33
34
|
spans?: undefined;
|
|
34
|
-
ok?: undefined;
|
|
35
35
|
} | {
|
|
36
36
|
error?: undefined;
|
|
37
|
+
ok?: undefined;
|
|
37
38
|
message?: undefined;
|
|
38
39
|
summary: import("./types.js").TraceSummary;
|
|
39
40
|
spans: import("./types.js").TraceSpan[];
|
|
40
|
-
ok?: undefined;
|
|
41
41
|
} | {
|
|
42
42
|
error?: undefined;
|
|
43
|
+
ok?: undefined;
|
|
43
44
|
message?: undefined;
|
|
44
45
|
summary?: undefined;
|
|
45
46
|
spans?: undefined;
|
|
46
47
|
traceMissing: true;
|
|
47
48
|
id: string;
|
|
48
|
-
ok?: undefined;
|
|
49
49
|
} | {
|
|
50
50
|
error?: undefined;
|
|
51
|
+
ok?: undefined;
|
|
51
52
|
message?: undefined;
|
|
52
53
|
summary?: undefined;
|
|
53
54
|
spans?: undefined;
|
|
54
55
|
traceMissing?: undefined;
|
|
55
56
|
id: string;
|
|
56
|
-
ok?: undefined;
|
|
57
57
|
} | {
|
|
58
|
+
ok?: undefined;
|
|
58
59
|
message?: undefined;
|
|
59
60
|
summary?: undefined;
|
|
60
61
|
spans?: undefined;
|
|
61
62
|
error: any;
|
|
62
|
-
ok?: undefined;
|
|
63
63
|
} | {
|
|
64
64
|
error?: undefined;
|
|
65
65
|
message?: undefined;
|
|
@@ -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
78
|
id?: undefined;
|
|
80
79
|
provider?: undefined;
|
|
81
80
|
deleted?: undefined;
|
|
81
|
+
message?: undefined;
|
|
82
82
|
providers: {
|
|
83
83
|
id: string;
|
|
84
84
|
label: string;
|
|
@@ -93,9 +93,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
93
93
|
registered?: undefined;
|
|
94
94
|
label?: undefined;
|
|
95
95
|
} | {
|
|
96
|
-
message?: undefined;
|
|
97
96
|
id?: undefined;
|
|
98
97
|
deleted?: undefined;
|
|
98
|
+
message?: undefined;
|
|
99
99
|
providers?: undefined;
|
|
100
100
|
count?: undefined;
|
|
101
101
|
found: boolean;
|
|
@@ -103,9 +103,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
103
103
|
registered?: undefined;
|
|
104
104
|
label?: undefined;
|
|
105
105
|
} | {
|
|
106
|
-
message?: undefined;
|
|
107
106
|
provider?: undefined;
|
|
108
107
|
deleted?: undefined;
|
|
108
|
+
message?: undefined;
|
|
109
109
|
providers?: undefined;
|
|
110
110
|
count?: undefined;
|
|
111
111
|
found: boolean;
|
|
@@ -113,8 +113,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
113
113
|
registered?: undefined;
|
|
114
114
|
label?: undefined;
|
|
115
115
|
} | {
|
|
116
|
-
message?: undefined;
|
|
117
116
|
provider?: undefined;
|
|
117
|
+
message?: undefined;
|
|
118
118
|
providers?: undefined;
|
|
119
119
|
count?: undefined;
|
|
120
120
|
found?: undefined;
|
|
@@ -39,8 +39,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
39
39
|
error: string;
|
|
40
40
|
}>;
|
|
41
41
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
42
|
-
error: string;
|
|
43
42
|
ok?: undefined;
|
|
43
|
+
error: string;
|
|
44
44
|
} | {
|
|
45
45
|
error?: undefined;
|
|
46
46
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -57,39 +57,39 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
57
57
|
} | {
|
|
58
58
|
error: string;
|
|
59
59
|
errorCode?: undefined;
|
|
60
|
-
status?: undefined;
|
|
61
60
|
ok?: undefined;
|
|
61
|
+
status?: undefined;
|
|
62
62
|
} | {
|
|
63
63
|
error: string;
|
|
64
64
|
errorCode: string;
|
|
65
|
-
status?: undefined;
|
|
66
65
|
ok?: undefined;
|
|
66
|
+
status?: undefined;
|
|
67
67
|
} | {
|
|
68
|
-
error?: undefined;
|
|
69
68
|
errorCode?: undefined;
|
|
70
69
|
ok: boolean;
|
|
71
70
|
status: string;
|
|
71
|
+
error?: undefined;
|
|
72
72
|
} | {
|
|
73
|
+
ok?: undefined;
|
|
73
74
|
error: string;
|
|
74
75
|
removed?: undefined;
|
|
75
|
-
ok?: undefined;
|
|
76
76
|
} | {
|
|
77
|
-
error?: undefined;
|
|
78
77
|
ok: boolean;
|
|
79
78
|
removed: boolean;
|
|
79
|
+
error?: undefined;
|
|
80
80
|
}>>;
|
|
81
81
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
82
|
+
ok?: undefined;
|
|
82
83
|
error: string;
|
|
83
84
|
note?: undefined;
|
|
84
|
-
ok?: undefined;
|
|
85
85
|
} | {
|
|
86
|
-
error?: undefined;
|
|
87
86
|
ok: boolean;
|
|
88
87
|
note?: undefined;
|
|
89
|
-
} | {
|
|
90
88
|
error?: undefined;
|
|
89
|
+
} | {
|
|
91
90
|
ok: boolean;
|
|
92
91
|
note: string;
|
|
92
|
+
error?: undefined;
|
|
93
93
|
} | {
|
|
94
94
|
note?: undefined;
|
|
95
95
|
ok: boolean;
|
|
@@ -117,11 +117,11 @@ export declare function createAdHocSecretHandler(): import("h3").EventHandlerWit
|
|
|
117
117
|
} | {
|
|
118
118
|
error: string;
|
|
119
119
|
} | {
|
|
120
|
-
error?: undefined;
|
|
121
120
|
ok: boolean;
|
|
122
121
|
key: string;
|
|
123
|
-
} | {
|
|
124
122
|
error?: undefined;
|
|
123
|
+
} | {
|
|
125
124
|
ok: boolean;
|
|
126
125
|
removed: boolean;
|
|
126
|
+
error?: undefined;
|
|
127
127
|
}>>;
|
|
@@ -9,16 +9,16 @@ export declare const AGENT_ENGINE_API_KEY_ACTION_NAME = "agent-engine-api-key";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function createAgentEngineDisconnectHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
11
11
|
error: string;
|
|
12
|
-
scope?: undefined;
|
|
13
12
|
ok?: undefined;
|
|
13
|
+
scope?: undefined;
|
|
14
14
|
} | {
|
|
15
15
|
ok: boolean;
|
|
16
16
|
error: any;
|
|
17
17
|
scope?: undefined;
|
|
18
18
|
} | {
|
|
19
|
+
error?: undefined;
|
|
19
20
|
ok: boolean;
|
|
20
21
|
scope: "org" | "user";
|
|
21
|
-
error?: undefined;
|
|
22
22
|
}>>;
|
|
23
23
|
export interface DefaultModelSelectionRequest {
|
|
24
24
|
engine: string;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { readComposerWebsiteSource, type ComposerWebsiteExtraction, } from "./composer-website-source.js";
|
|
2
2
|
export { isAgentKitFigmaSourceAvailable, listAgentKitCapabilities, readAgentKitIntegrationIntent, type AgentKitCapabilityAppId, type AgentKitCapabilityCatalog, type AgentKitIntegrationCapability, } from "../agentkit/capabilities.js";
|
|
3
3
|
export { defineAppConfig, getAppConfig, resolveAppHomePath, resetAppConfigForTests, appConfigSchema, type AppConfig, type AppConfigInput, } from "../app-config/index.js";
|
|
4
|
+
export { platformWaitUntil } from "./background-work.js";
|
|
4
5
|
export { resolveDeployEnvironment } from "./deploy-environment.js";
|
|
5
6
|
export { isTestIdentity, testIdentitySql } from "./test-identity.js";
|
|
6
7
|
export { inferWorkspaceAppRootHomePath, readConfiguredWorkspaceAppHomePath, } from "../workspace-app-config.js";
|
|
@@ -16,7 +17,7 @@ export { createSSEHandler, type SSEHandlerOptions } from "./sse.js";
|
|
|
16
17
|
export { isCredentialMembershipUnavailable } from "./credential-membership-unavailable.js";
|
|
17
18
|
export { mountAuthMiddleware, autoMountAuth, registerAuthPublicPaths, getSession, isSessionResolutionUnavailable, getMcpOAuthBearerSession, logout, COOKIE_NAME, addSession, removeSession, getSessionEmail, getFrameworkSessionCookieValues, setFrameworkSessionCookie, setFirstRunOnboardingCookie, clearFrameworkSessionCookies, runAuthGuard, registerDesktopExchange, prepareDesktopOAuthBrowserBinding, matchesDesktopOAuthBrowserBinding, DESKTOP_OAUTH_BROWSER_BINDING_COOKIE, setDesktopExchange, setDesktopExchangeError, safeReturnPath, type DesktopExchangeErrorPayload, type AuthSession, type AuthOptions, } from "./auth.js";
|
|
18
19
|
export { handleIdentitySso, ensureIdentityUser, getIdentityHubUrl, isIdentitySsoEnabled, isIdentitySsoBypassPath, identitySsoLoginButtonHtml, IDENTITY_SSO_BOOTSTRAP_ACTIVATE_PATH, IDENTITY_SSO_BOOTSTRAP_BINDING_COOKIE, clearIdentitySsoBootstrapBindingCookie, getIdentitySsoBootstrapBindingCookie, setIdentitySsoBootstrapBindingCookie, IDENTITY_SSO_PROVIDER_ID, IDENTITY_SSO_SCOPE, IDENTITY_SSO_DESKTOP_COMPLETE_PATH, } from "./identity-sso.js";
|
|
19
|
-
export { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, hasGoogleAuthIdentity, setBetterAuthSessionCookie, } from "./better-auth-instance.js";
|
|
20
|
+
export { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, getBetterAuthUserIdForEmail, hasGoogleAuthIdentity, setBetterAuthSessionCookie, } from "./better-auth-instance.js";
|
|
20
21
|
export { setIdentityGoogleAuthCookie } from "./identity-auth-provider.js";
|
|
21
22
|
export { requireEnvKey, type MissingKeyResponse } from "./missing-key.js";
|
|
22
23
|
export { assertCurrentRequestUserIsOrgAdmin, currentRequestUserIsOrgAdmin, } from "./org-admin.js";
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { readComposerWebsiteSource, } from "./composer-website-source.js";
|
|
2
2
|
export { isAgentKitFigmaSourceAvailable, listAgentKitCapabilities, readAgentKitIntegrationIntent, } from "../agentkit/capabilities.js";
|
|
3
3
|
export { defineAppConfig, getAppConfig, resolveAppHomePath, resetAppConfigForTests, appConfigSchema, } from "../app-config/index.js";
|
|
4
|
+
export { platformWaitUntil } from "./background-work.js";
|
|
4
5
|
export { resolveDeployEnvironment } from "./deploy-environment.js";
|
|
5
6
|
export { isTestIdentity, testIdentitySql } from "./test-identity.js";
|
|
6
7
|
export { inferWorkspaceAppRootHomePath, readConfiguredWorkspaceAppHomePath, } from "../workspace-app-config.js";
|
|
@@ -16,7 +17,7 @@ export { createSSEHandler } from "./sse.js";
|
|
|
16
17
|
export { isCredentialMembershipUnavailable } from "./credential-membership-unavailable.js";
|
|
17
18
|
export { mountAuthMiddleware, autoMountAuth, registerAuthPublicPaths, getSession, isSessionResolutionUnavailable, getMcpOAuthBearerSession, logout, COOKIE_NAME, addSession, removeSession, getSessionEmail, getFrameworkSessionCookieValues, setFrameworkSessionCookie, setFirstRunOnboardingCookie, clearFrameworkSessionCookies, runAuthGuard, registerDesktopExchange, prepareDesktopOAuthBrowserBinding, matchesDesktopOAuthBrowserBinding, DESKTOP_OAUTH_BROWSER_BINDING_COOKIE, setDesktopExchange, setDesktopExchangeError, safeReturnPath, } from "./auth.js";
|
|
18
19
|
export { handleIdentitySso, ensureIdentityUser, getIdentityHubUrl, isIdentitySsoEnabled, isIdentitySsoBypassPath, identitySsoLoginButtonHtml, IDENTITY_SSO_BOOTSTRAP_ACTIVATE_PATH, IDENTITY_SSO_BOOTSTRAP_BINDING_COOKIE, clearIdentitySsoBootstrapBindingCookie, getIdentitySsoBootstrapBindingCookie, setIdentitySsoBootstrapBindingCookie, IDENTITY_SSO_PROVIDER_ID, IDENTITY_SSO_SCOPE, IDENTITY_SSO_DESKTOP_COMPLETE_PATH, } from "./identity-sso.js";
|
|
19
|
-
export { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, hasGoogleAuthIdentity, setBetterAuthSessionCookie, } from "./better-auth-instance.js";
|
|
20
|
+
export { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, getBetterAuthUserIdForEmail, hasGoogleAuthIdentity, setBetterAuthSessionCookie, } from "./better-auth-instance.js";
|
|
20
21
|
export { setIdentityGoogleAuthCookie } from "./identity-auth-provider.js";
|
|
21
22
|
export { requireEnvKey } from "./missing-key.js";
|
|
22
23
|
export { assertCurrentRequestUserIsOrgAdmin, currentRequestUserIsOrgAdmin, } from "./org-admin.js";
|
|
@@ -50,5 +50,5 @@ export const SELECTION_CONTEXT_UNAVAILABLE_NOTE = wrapNote("Selected text unavai
|
|
|
50
50
|
/** `partial` when another source did deliver context this turn. */
|
|
51
51
|
export function preloadedContextUnavailableNote(status, options = {}) {
|
|
52
52
|
const reason = status === "timed_out" ? "timed out" : "failed";
|
|
53
|
-
return wrapNote(`${options.partial ? "Some preloaded context" : "Preloaded context"} was unavailable this turn (${reason}); search for
|
|
53
|
+
return wrapNote(`${options.partial ? "Some preloaded context" : "Preloaded context"} was unavailable this turn (${reason}); if the request depends on workspace knowledge, such as prior work, team docs, brand defaults, or people, search for it with the available tools before answering; otherwise continue without it.`);
|
|
54
54
|
}
|
|
@@ -2,7 +2,6 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
2
2
|
resourceType: string;
|
|
3
3
|
resourceId: string;
|
|
4
4
|
}, {
|
|
5
|
-
role?: undefined;
|
|
6
5
|
ownerEmail: any;
|
|
7
6
|
visibility: any;
|
|
8
7
|
shares: any[];
|
|
@@ -12,6 +11,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
12
11
|
supportsGroupShares?: boolean;
|
|
13
12
|
};
|
|
14
13
|
orgId?: undefined;
|
|
14
|
+
role?: undefined;
|
|
15
15
|
agentReadable?: undefined;
|
|
16
16
|
} | {
|
|
17
17
|
ownerEmail: string;
|
package/dist/tracking/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { track, identify, flushTracking, registerTrackingProvider, unregisterTrackingProvider, listTrackingProviders, type TrackingMeta, type TrackingSource, } from "./registry.js";
|
|
2
2
|
export { registerBuiltinProviders } from "./providers.js";
|
|
3
|
+
export { readAnalyticsAnonymousId } from "../server/attribution.js";
|
|
3
4
|
export { AGENT_NATIVE_ACTION_EVENTS, AGENT_NATIVE_LIFECYCLE_EVENTS, trackActionEvent, trackLifecycleEvent, type AgentNativeActionEventName, type AgentNativeLifecycleEventName, } from "./lifecycle.js";
|
|
4
5
|
export { captureException, type TrackingExceptionContext, type TrackingExceptionLevel, } from "./error-capture.js";
|
|
5
6
|
export { classifyTrackingFailure, type TrackingFailureCategory, } from "./failure-category.js";
|
package/dist/tracking/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { track, identify, flushTracking, registerTrackingProvider, unregisterTrackingProvider, listTrackingProviders, } from "./registry.js";
|
|
2
2
|
export { registerBuiltinProviders } from "./providers.js";
|
|
3
|
+
export { readAnalyticsAnonymousId } from "../server/attribution.js";
|
|
3
4
|
export { AGENT_NATIVE_ACTION_EVENTS, AGENT_NATIVE_LIFECYCLE_EVENTS, trackActionEvent, trackLifecycleEvent, } from "./lifecycle.js";
|
|
4
5
|
export { captureException, } from "./error-capture.js";
|
|
5
6
|
export { classifyTrackingFailure, } from "./failure-category.js";
|
|
@@ -29,8 +29,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
29
29
|
executionEngine?: undefined;
|
|
30
30
|
executionCwd?: undefined;
|
|
31
31
|
} | {
|
|
32
|
-
created?: undefined;
|
|
33
32
|
scope?: undefined;
|
|
33
|
+
created?: undefined;
|
|
34
34
|
triggerType?: undefined;
|
|
35
35
|
event?: undefined;
|
|
36
36
|
deleted: boolean;
|
|
@@ -45,8 +45,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
45
45
|
nextRun?: undefined;
|
|
46
46
|
webhookPath?: undefined;
|
|
47
47
|
} | {
|
|
48
|
-
created?: undefined;
|
|
49
48
|
scope?: undefined;
|
|
49
|
+
created?: undefined;
|
|
50
50
|
triggerType?: undefined;
|
|
51
51
|
event?: undefined;
|
|
52
52
|
deleted?: undefined;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare const SAVE_TO_FILE_MAX_BYTES: number;
|
|
1
|
+
import { MAX_FILE_BYTES, MAX_SCOPE_BYTES, SAVE_TO_FILE_MAX_BYTES } from "./constants.js";
|
|
2
|
+
export { MAX_FILE_BYTES, MAX_SCOPE_BYTES, SAVE_TO_FILE_MAX_BYTES };
|
|
4
3
|
export interface WorkspaceFilesScope {
|
|
5
4
|
scope: "user" | "org";
|
|
6
5
|
scopeId: string;
|
|
@@ -2,9 +2,8 @@ import { getOrgRoleForEmail } from "../mcp/actions/service-token-access.js";
|
|
|
2
2
|
import { canManageOrg } from "../org/permissions.js";
|
|
3
3
|
import { SHARED_OWNER, isLegacyOrganizationWorkspaceFile, sharedResourceOwner, resourceDeleteIfCurrent, resourceGetByPath, resourceList, resourcePut, } from "../resources/store.js";
|
|
4
4
|
import { getRequestUserEmail } from "../server/request-context.js";
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
export const SAVE_TO_FILE_MAX_BYTES = 20 * 1024 * 1024;
|
|
5
|
+
import { MAX_FILE_BYTES, MAX_SCOPE_BYTES, SAVE_TO_FILE_MAX_BYTES, } from "./constants.js";
|
|
6
|
+
export { MAX_FILE_BYTES, MAX_SCOPE_BYTES, SAVE_TO_FILE_MAX_BYTES };
|
|
8
7
|
function ownerForScope(scope) {
|
|
9
8
|
return scope.scope === "org"
|
|
10
9
|
? sharedResourceOwner(scope.scopeId)
|
|
@@ -290,19 +290,25 @@ Placeholders are resolved **server-side** after the agent emits the tool call
|
|
|
290
290
|
|
|
291
291
|
### Parameters {#web-request-params}
|
|
292
292
|
|
|
293
|
-
| Parameter | Type | Default | Description
|
|
294
|
-
| -------------- | ------- | ------------- |
|
|
295
|
-
| `url` | string | — | Full URL. May contain `${keys.NAME}` references.
|
|
296
|
-
| `method` | string | `GET` | HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD).
|
|
297
|
-
| `headers` | string | `{}` | JSON object of headers. May contain `${keys.NAME}`.
|
|
298
|
-
| `body` | string | — | Request body. May contain `${keys.NAME}`.
|
|
299
|
-
| `timeout_ms` | number | 15000 | Timeout in milliseconds (max 30000).
|
|
300
|
-
| `maxChars` | number | 32000 | Maximum response characters
|
|
301
|
-
| `responseMode` | string | `auto` | How to return the response: `auto` (HTML becomes markdown, JSON/text stays raw), `raw`, `text`, `markdown`, `links`, `metadata`, or `matches`
|
|
302
|
-
| `extract` | string | `readability` | HTML extraction strategy: `readability`, `all-visible` (full visible body text), or `none` (full document).
|
|
303
|
-
| `includeLinks` | boolean |
|
|
304
|
-
| `search` | object | — | Optional post-fetch search over the extracted content: `{ query, queries, terms, regex, regexFlags, source, maxMatches, contextChars, caseSensitive }`.
|
|
305
|
-
| `saveToFile` | string | — | Workspace file path
|
|
293
|
+
| Parameter | Type | Default | Description |
|
|
294
|
+
| -------------- | ------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
295
|
+
| `url` | string | — | Full URL. May contain `${keys.NAME}` references. |
|
|
296
|
+
| `method` | string | `GET` | HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD). |
|
|
297
|
+
| `headers` | string | `{}` | JSON object of headers. May contain `${keys.NAME}`. |
|
|
298
|
+
| `body` | string | — | Request body. May contain `${keys.NAME}`. |
|
|
299
|
+
| `timeout_ms` | number | 15000 | Timeout in milliseconds (max 30000). |
|
|
300
|
+
| `maxChars` | number | 32000 | Maximum response-body characters returned in the agent's context (max 200000). It caps body characters, not the whole formatted tool response, so optional metadata and links can add characters. This does not limit a saved file. |
|
|
301
|
+
| `responseMode` | string | `auto` | How to return the response: `auto` (HTML becomes markdown, JSON/text stays raw), `raw`, `text`, `markdown`, `links`, `metadata`, or `matches` with `search`. |
|
|
302
|
+
| `extract` | string | `readability` | HTML extraction strategy: `readability`, `all-visible` (full visible body text), or `none` (full document). |
|
|
303
|
+
| `includeLinks` | boolean | varies | Whether extracted HTML responses include a compact links list. Defaults to `true` for inline responses and `false` when `saveToFile` is set. |
|
|
304
|
+
| `search` | object | — | Optional post-fetch search over the extracted content: `{ query, queries, terms, regex, regexFlags, source, maxMatches, contextChars, caseSensitive }`. |
|
|
305
|
+
| `saveToFile` | string | — | Workspace file path for saving the full response, up to 20 MiB. With `search`, returns full matches up to `maxChars`; otherwise returns a 2,000-character preview. |
|
|
306
|
+
|
|
307
|
+
By default, `maxChars` caps only response-body characters returned in the agent's context. It does not cap the whole formatted tool response, so optional metadata and links can add characters. Inline responses are limited to 1 MiB, except extracted HTML or XHTML, which can be up to 20 MiB. Raw HTML and other inline responses remain limited to 1 MiB.
|
|
308
|
+
|
|
309
|
+
`saveToFile` supports responses up to 20 MiB. HTML or XHTML saved with a non-raw `responseMode` is written as extracted Markdown or text. Raw mode and non-HTML responses are saved as decoded response body text without HTML extraction. When `saveToFile` is used with `search`, the tool returns full search matches bounded by `maxChars`. Without `search`, it returns a 2,000-character preview. `searchResultsTruncated` means `maxChars` cut the formatted result. `searchSourceTruncated` means the tool scanned only the first 500,000 characters of the selected search source.
|
|
310
|
+
|
|
311
|
+
An over-limit error reports the observed size and applicable cap, and explains how to recover. Use `saveToFile` for responses up to 20 MiB, or request a smaller response if it exceeds that limit.
|
|
306
312
|
|
|
307
313
|
## Keys {#keys}
|
|
308
314
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.208.
|
|
3
|
+
"version": "0.208.1-nightly-20261013212700",
|
|
4
4
|
"description": "The agentic application framework for building autonomous agents with intuitive UIs",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -703,7 +703,7 @@
|
|
|
703
703
|
"yaml": "^2.9.0",
|
|
704
704
|
"yjs": "^13.6.33",
|
|
705
705
|
"zod": "^4.3.6",
|
|
706
|
-
"@agent-native/agentkit": "^0.208.
|
|
706
|
+
"@agent-native/agentkit": "^0.208.1-nightly-20261013212700",
|
|
707
707
|
"@agent-native/recap-cli": "^0.5.71"
|
|
708
708
|
},
|
|
709
709
|
"devDependencies": {
|
|
@@ -774,7 +774,7 @@
|
|
|
774
774
|
"xlsx": "^0.18.5"
|
|
775
775
|
},
|
|
776
776
|
"peerDependencies": {
|
|
777
|
-
"@agent-native/core-corpus": "
|
|
777
|
+
"@agent-native/core-corpus": "0.208.1-nightly-20261013212700",
|
|
778
778
|
"@ai-sdk/anthropic": ">=3",
|
|
779
779
|
"@ai-sdk/cohere": ">=3",
|
|
780
780
|
"@ai-sdk/google": ">=3",
|