@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
|
@@ -24,6 +24,9 @@ export type ContentPart = {
|
|
|
24
24
|
args: Record<string, string>;
|
|
25
25
|
result?: string;
|
|
26
26
|
isError?: boolean;
|
|
27
|
+
approvalPause?: true;
|
|
28
|
+
approvalPauseCandidate?: true;
|
|
29
|
+
approvalResumeCandidate?: true;
|
|
27
30
|
/**
|
|
28
31
|
* Set when the stream ended while this tool was still in flight. We know
|
|
29
32
|
* it started and NOT whether its side effect landed, so it is deliberately
|
|
@@ -90,6 +93,7 @@ export interface SSEEvent {
|
|
|
90
93
|
result?: string;
|
|
91
94
|
isError?: boolean;
|
|
92
95
|
completedSideEffect?: boolean;
|
|
96
|
+
approvalPause?: boolean;
|
|
93
97
|
artifacts?: ArtifactReceipt[];
|
|
94
98
|
mcpApp?: AgentMcpAppPayload;
|
|
95
99
|
chatUI?: ActionChatUIConfig;
|
|
@@ -293,6 +297,24 @@ export type PreparingActionState = {
|
|
|
293
297
|
entries?: Map<string, PreparingActionEntry>;
|
|
294
298
|
toolEntries?: Map<string, PreparingActionEntry>;
|
|
295
299
|
};
|
|
300
|
+
/**
|
|
301
|
+
* Locate the tool call an `approval_required` event refers to.
|
|
302
|
+
*
|
|
303
|
+
* Stricter than `findPendingToolCallIndex`: when the server supplies a call id
|
|
304
|
+
* we never fall back to "newest pending call with this name". A paused
|
|
305
|
+
* `tool_done` resolves the call right after the gate fires, so a replayed or
|
|
306
|
+
* reordered approval would otherwise miss on id and silently attach this call's
|
|
307
|
+
* approvalKey to a *different* in-flight call of the same action — putting the
|
|
308
|
+
* wrong key behind a visible Approve button. A resumed paused call is eligible
|
|
309
|
+
* only after its exact `tool_start` marks it as an approval-resume candidate.
|
|
310
|
+
*
|
|
311
|
+
* Without an event id, the required input must identify one pending call or
|
|
312
|
+
* explicitly resumed pause by itself. A name-only match can attach a stale
|
|
313
|
+
* approval to a different same-name call. With an event id, the only tolerated
|
|
314
|
+
* fallback is a single unambiguous reader-local (`tc_N`) placeholder, which is
|
|
315
|
+
* how a call looks when an older server omitted the id on `tool_start`.
|
|
316
|
+
*/
|
|
317
|
+
export declare function findApprovalToolCallIndex(content: readonly ContentPart[], toolName: string, toolCallId?: string, approvalInput?: unknown): number;
|
|
296
318
|
export declare function appendMissingFinalResponseWarning(content: ContentPart[], completedToolNames?: Iterable<string>): {
|
|
297
319
|
message: string;
|
|
298
320
|
errorCode: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "../agent/engine/credential-errors.js";
|
|
2
2
|
import { BUILDER_GATEWAY_INTERNAL_ERROR_CODE, PROVIDER_TRANSIENT_REJECTION_ERROR_CODE, } from "../agent/engine/error-detail.js";
|
|
3
3
|
import { normalizeConnectRequiredResult } from "../shared/connect-required.js";
|
|
4
|
+
import { toolInputsMatch } from "../shared/tool-inputs.js";
|
|
4
5
|
import { emitChatFirstOpenApp } from "./chat-first-state.js";
|
|
5
6
|
import { formatChatErrorText, normalizeChatError } from "./error-format.js";
|
|
6
7
|
import { humanizeToolLabelText, humanizeToolName, isToolCallActive, runningToolLabel, } from "./tool-display.js";
|
|
@@ -274,25 +275,60 @@ function findPendingToolCallIndexById(content, toolCallId) {
|
|
|
274
275
|
* `tool_done` resolves the call right after the gate fires, so a replayed or
|
|
275
276
|
* reordered approval would otherwise miss on id and silently attach this call's
|
|
276
277
|
* approvalKey to a *different* in-flight call of the same action — putting the
|
|
277
|
-
* wrong key behind a visible Approve button.
|
|
278
|
+
* wrong key behind a visible Approve button. A resumed paused call is eligible
|
|
279
|
+
* only after its exact `tool_start` marks it as an approval-resume candidate.
|
|
278
280
|
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
281
|
+
* Without an event id, the required input must identify one pending call or
|
|
282
|
+
* explicitly resumed pause by itself. A name-only match can attach a stale
|
|
283
|
+
* approval to a different same-name call. With an event id, the only tolerated
|
|
284
|
+
* fallback is a single unambiguous reader-local (`tc_N`) placeholder, which is
|
|
285
|
+
* how a call looks when an older server omitted the id on `tool_start`.
|
|
282
286
|
*/
|
|
283
|
-
function findApprovalToolCallIndex(content, toolName, toolCallId) {
|
|
287
|
+
export function findApprovalToolCallIndex(content, toolName, toolCallId, approvalInput) {
|
|
284
288
|
if (!toolCallId) {
|
|
285
|
-
|
|
289
|
+
if (!approvalInput)
|
|
290
|
+
return -1;
|
|
291
|
+
const matchingInputCandidates = [];
|
|
292
|
+
for (let i = 0; i < content.length; i += 1) {
|
|
293
|
+
const part = content[i];
|
|
294
|
+
if (part.type === "tool-call" &&
|
|
295
|
+
part.toolName === toolName &&
|
|
296
|
+
(part.result === undefined ||
|
|
297
|
+
(part.approvalPause === true &&
|
|
298
|
+
part.approvalResumeCandidate === true)) &&
|
|
299
|
+
toolInputsMatch(part.args, approvalInput)) {
|
|
300
|
+
matchingInputCandidates.push(i);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return matchingInputCandidates.length === 1
|
|
304
|
+
? matchingInputCandidates[0]
|
|
305
|
+
: -1;
|
|
286
306
|
}
|
|
287
307
|
const exactIndex = findPendingToolCallIndexById(content, toolCallId);
|
|
288
308
|
if (exactIndex >= 0)
|
|
289
309
|
return exactIndex;
|
|
310
|
+
const resumedCandidates = [];
|
|
311
|
+
for (let i = 0; i < content.length; i += 1) {
|
|
312
|
+
const part = content[i];
|
|
313
|
+
if (part.type === "tool-call" &&
|
|
314
|
+
part.toolCallId === toolCallId &&
|
|
315
|
+
part.toolName === toolName &&
|
|
316
|
+
part.result !== undefined &&
|
|
317
|
+
part.approvalPause === true &&
|
|
318
|
+
part.approvalResumeCandidate === true &&
|
|
319
|
+
(approvalInput === undefined || toolInputsMatch(part.args, approvalInput))) {
|
|
320
|
+
resumedCandidates.push(i);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (resumedCandidates.length === 1)
|
|
324
|
+
return resumedCandidates[0];
|
|
290
325
|
const readerLocalCandidates = [];
|
|
291
326
|
for (let i = 0; i < content.length; i += 1) {
|
|
292
327
|
const part = content[i];
|
|
293
328
|
if (part.type === "tool-call" &&
|
|
294
329
|
part.toolName === toolName &&
|
|
295
330
|
part.result === undefined &&
|
|
331
|
+
toolInputsMatch(part.args, approvalInput) &&
|
|
296
332
|
/^tc_\d+$/.test(part.toolCallId)) {
|
|
297
333
|
readerLocalCandidates.push(i);
|
|
298
334
|
}
|
|
@@ -1268,7 +1304,15 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
|
|
|
1268
1304
|
if (ev.type === "tool_start") {
|
|
1269
1305
|
const args = (ev.input ?? {});
|
|
1270
1306
|
const tool = ev.tool ?? "unknown";
|
|
1271
|
-
|
|
1307
|
+
const completedIndex = findCompletedToolCallIndex(content, ev.id);
|
|
1308
|
+
if (completedIndex >= 0) {
|
|
1309
|
+
const completedPart = content[completedIndex];
|
|
1310
|
+
if (completedPart?.type === "tool-call") {
|
|
1311
|
+
if (completedPart.approvalPause === true) {
|
|
1312
|
+
completedPart.approvalResumeCandidate = true;
|
|
1313
|
+
}
|
|
1314
|
+
delete completedPart.approvalPauseCandidate;
|
|
1315
|
+
}
|
|
1272
1316
|
return { action: "continue" };
|
|
1273
1317
|
}
|
|
1274
1318
|
if (typeof window !== "undefined") {
|
|
@@ -1339,7 +1383,7 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
|
|
|
1339
1383
|
// `toolCallId` is the model-side id in the `approval_required` contract;
|
|
1340
1384
|
// `id` is only carried by older frames. Same precedence as the runtime
|
|
1341
1385
|
// path so both processors resolve an event to the same call.
|
|
1342
|
-
const idx = findApprovalToolCallIndex(content, approvalTool, ev.toolCallId ?? ev.id);
|
|
1386
|
+
const idx = findApprovalToolCallIndex(content, approvalTool, ev.toolCallId ?? ev.id, ev.input);
|
|
1343
1387
|
if (idx >= 0) {
|
|
1344
1388
|
const part = content[idx];
|
|
1345
1389
|
if (part.type === "tool-call") {
|
|
@@ -1350,6 +1394,8 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
|
|
|
1350
1394
|
? { allowPersistentApproval: false }
|
|
1351
1395
|
: {}),
|
|
1352
1396
|
};
|
|
1397
|
+
part.approvalPauseCandidate = true;
|
|
1398
|
+
delete part.approvalResumeCandidate;
|
|
1353
1399
|
}
|
|
1354
1400
|
}
|
|
1355
1401
|
}
|
|
@@ -1363,8 +1409,29 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
|
|
|
1363
1409
|
// so a tool_done frame with an undefined tool name still matches its
|
|
1364
1410
|
// pending tool-call entry instead of leaving it forever unresolved.
|
|
1365
1411
|
const doneTool = ev.tool ?? "unknown";
|
|
1366
|
-
|
|
1367
|
-
|
|
1412
|
+
const completedIndex = findCompletedToolCallIndex(content, ev.id);
|
|
1413
|
+
let approvedResumeIndex = -1;
|
|
1414
|
+
if (completedIndex >= 0) {
|
|
1415
|
+
const completedPart = content[completedIndex];
|
|
1416
|
+
if (completedPart?.type !== "tool-call") {
|
|
1417
|
+
return { action: "continue" };
|
|
1418
|
+
}
|
|
1419
|
+
const legacyApprovalPause = ev.approvalPause === undefined &&
|
|
1420
|
+
completedPart.approvalPauseCandidate === true;
|
|
1421
|
+
const renewedApprovalPause = ev.approvalPause === true &&
|
|
1422
|
+
completedPart.approvalPause === true &&
|
|
1423
|
+
completedPart.approvalPauseCandidate === true;
|
|
1424
|
+
if ((ev.approvalPause === true && completedPart.approvalPause !== true) ||
|
|
1425
|
+
legacyApprovalPause ||
|
|
1426
|
+
renewedApprovalPause ||
|
|
1427
|
+
(completedPart.approvalPause === true &&
|
|
1428
|
+
completedPart.approvalResumeCandidate === true &&
|
|
1429
|
+
ev.approvalPause !== true)) {
|
|
1430
|
+
approvedResumeIndex = completedIndex;
|
|
1431
|
+
}
|
|
1432
|
+
else {
|
|
1433
|
+
return { action: "continue" };
|
|
1434
|
+
}
|
|
1368
1435
|
}
|
|
1369
1436
|
emitFirstPartyOpenAppHandoff(ev);
|
|
1370
1437
|
if (typeof window !== "undefined") {
|
|
@@ -1385,11 +1452,24 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
|
|
|
1385
1452
|
dispatchActivityClear(tabId);
|
|
1386
1453
|
// Use id-based lookup when available so parallel same-name tool calls
|
|
1387
1454
|
// get their results correctly assigned; fall back to name-matching.
|
|
1388
|
-
const doneIdx =
|
|
1455
|
+
const doneIdx = approvedResumeIndex >= 0
|
|
1456
|
+
? approvedResumeIndex
|
|
1457
|
+
: findPendingToolCallIndex(content, doneTool, ev.id);
|
|
1389
1458
|
if (doneIdx >= 0) {
|
|
1390
1459
|
const part = content[doneIdx];
|
|
1391
1460
|
if (part.type === "tool-call") {
|
|
1392
1461
|
part.result = ev.result ?? "";
|
|
1462
|
+
const legacyApprovalPause = ev.approvalPause === undefined &&
|
|
1463
|
+
part.approvalPauseCandidate === true;
|
|
1464
|
+
if (ev.approvalPause === true || legacyApprovalPause) {
|
|
1465
|
+
part.approvalPause = true;
|
|
1466
|
+
}
|
|
1467
|
+
else {
|
|
1468
|
+
delete part.approvalPause;
|
|
1469
|
+
delete part.approval;
|
|
1470
|
+
}
|
|
1471
|
+
delete part.approvalPauseCandidate;
|
|
1472
|
+
delete part.approvalResumeCandidate;
|
|
1393
1473
|
if (ev.isError !== undefined)
|
|
1394
1474
|
part.isError = ev.isError;
|
|
1395
1475
|
if (ev.completedSideEffect !== undefined) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type WorkspaceConnectionCapability = "search" | "import" | "messages" | "meetings" | "crm" | "code" | "docs";
|
|
2
2
|
export type WorkspaceConnectionTemplateUse = "analytics" | "brain" | "calendar" | "clips" | "content" | "crm" | "design" | "dispatch" | "factory" | "forms" | "mail" | "slides";
|
|
3
|
-
export type WorkspaceConnectionProviderId = "slack" | "github" | "figma" | "notion" | "gmail" | "google_calendar" | "google_drive" | "google_docs" | "google_sheets" | "google_slides" | "hubspot" | "salesforce" | "jira" | "sentry" | "granola" | "clips" | "dbt" | "sigma" | "anthropic-managed-agents" | "generic";
|
|
3
|
+
export type WorkspaceConnectionProviderId = "slack" | "github" | "figma" | "notion" | "gmail" | "google_calendar" | "google_drive" | "bigquery" | "google_docs" | "google_sheets" | "google_slides" | "hubspot" | "salesforce" | "jira" | "sentry" | "granola" | "clips" | "dbt" | "sigma" | "anthropic-managed-agents" | "generic";
|
|
4
4
|
export interface WorkspaceConnectionCredentialKey {
|
|
5
5
|
key: string;
|
|
6
6
|
label: string;
|
|
@@ -145,6 +145,29 @@ export declare const WORKSPACE_CONNECTION_PROVIDERS: readonly [{
|
|
|
145
145
|
provider: string;
|
|
146
146
|
scopes: readonly string[];
|
|
147
147
|
};
|
|
148
|
+
}, {
|
|
149
|
+
readonly id: "bigquery";
|
|
150
|
+
readonly label: "BigQuery";
|
|
151
|
+
readonly description: "BigQuery datasets and SQL jobs for analytics and data exploration.";
|
|
152
|
+
readonly credentialKeys: readonly [{
|
|
153
|
+
readonly key: "GOOGLE_CLIENT_ID";
|
|
154
|
+
readonly label: "Managed Google OAuth client ID";
|
|
155
|
+
readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
|
|
156
|
+
readonly required: true;
|
|
157
|
+
}, {
|
|
158
|
+
readonly key: "GOOGLE_CLIENT_SECRET";
|
|
159
|
+
readonly label: "Managed Google OAuth client secret";
|
|
160
|
+
readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
|
|
161
|
+
readonly required: true;
|
|
162
|
+
}];
|
|
163
|
+
readonly capabilities: readonly ["search"];
|
|
164
|
+
readonly recommendedTemplateUses: readonly ["analytics"];
|
|
165
|
+
readonly oauth: {
|
|
166
|
+
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
|
|
167
|
+
tokenUrl: "https://oauth2.googleapis.com/token";
|
|
168
|
+
provider: string;
|
|
169
|
+
scopes: readonly string[];
|
|
170
|
+
};
|
|
148
171
|
}, {
|
|
149
172
|
readonly id: "google_drive";
|
|
150
173
|
readonly label: "Google Drive";
|
|
@@ -133,6 +133,18 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
133
133
|
"https://www.googleapis.com/auth/calendar.events",
|
|
134
134
|
]),
|
|
135
135
|
}),
|
|
136
|
+
defineWorkspaceConnectionProvider({
|
|
137
|
+
id: "bigquery",
|
|
138
|
+
label: "BigQuery",
|
|
139
|
+
description: "BigQuery datasets and SQL jobs for analytics and data exploration.",
|
|
140
|
+
credentialKeys: GOOGLE_CREDENTIAL_KEYS,
|
|
141
|
+
capabilities: ["search"],
|
|
142
|
+
recommendedTemplateUses: ["analytics"],
|
|
143
|
+
oauth: googleOAuth([
|
|
144
|
+
...GOOGLE_IDENTITY_SCOPES,
|
|
145
|
+
"https://www.googleapis.com/auth/bigquery",
|
|
146
|
+
]),
|
|
147
|
+
}),
|
|
136
148
|
defineWorkspaceConnectionProvider({
|
|
137
149
|
id: "google_drive",
|
|
138
150
|
label: "Google Drive",
|
|
@@ -458,6 +458,7 @@ export declare const DATA_PROGRAMS_CREATE_SQL = "CREATE TABLE IF NOT EXISTS data
|
|
|
458
458
|
export declare const DATA_PROGRAM_SHARES_CREATE_SQL = "CREATE TABLE IF NOT EXISTS data_program_shares (\n id TEXT PRIMARY KEY,\n resource_id TEXT NOT NULL,\n principal_type TEXT NOT NULL,\n principal_id TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_by TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT now(),\n notified_at TEXT\n)";
|
|
459
459
|
export declare const DATA_PROGRAMS_APP_OWNER_INDEX_SQL = "CREATE INDEX IF NOT EXISTS data_programs_app_owner_idx ON data_programs (app_id, owner_email)";
|
|
460
460
|
export declare const DATA_PROGRAMS_APP_NAME_INDEX_SQL = "CREATE INDEX IF NOT EXISTS data_programs_app_name_idx ON data_programs (app_id, name)";
|
|
461
|
+
export declare const DATA_PROGRAM_SHARES_NOTIFIED_AT_COLUMN_SQL = "ALTER TABLE data_program_shares ADD COLUMN IF NOT EXISTS notified_at TEXT";
|
|
461
462
|
export declare const DATA_PROGRAM_SHARES_RESOURCE_INDEX_SQL = "CREATE INDEX IF NOT EXISTS data_program_shares_resource_idx ON data_program_shares (resource_id)";
|
|
462
463
|
export declare function dataProgramRunsCreateSql(integerType: string): string;
|
|
463
464
|
export declare const DATA_PROGRAM_RUNS_TRUNCATED_COLUMN_SQL = "ALTER TABLE data_program_runs ADD COLUMN IF NOT EXISTS truncated INTEGER NOT NULL DEFAULT 0";
|
|
@@ -51,6 +51,9 @@ export const DATA_PROGRAM_SHARES_CREATE_SQL = `CREATE TABLE IF NOT EXISTS data_p
|
|
|
51
51
|
)`;
|
|
52
52
|
export const DATA_PROGRAMS_APP_OWNER_INDEX_SQL = `CREATE INDEX IF NOT EXISTS data_programs_app_owner_idx ON data_programs (app_id, owner_email)`;
|
|
53
53
|
export const DATA_PROGRAMS_APP_NAME_INDEX_SQL = `CREATE INDEX IF NOT EXISTS data_programs_app_name_idx ON data_programs (app_id, name)`;
|
|
54
|
+
// data_program_shares tables created before notified_at existed never got it
|
|
55
|
+
// from the CREATE TABLE IF NOT EXISTS above, and every share insert names it.
|
|
56
|
+
export const DATA_PROGRAM_SHARES_NOTIFIED_AT_COLUMN_SQL = `ALTER TABLE data_program_shares ADD COLUMN IF NOT EXISTS notified_at TEXT`;
|
|
54
57
|
export const DATA_PROGRAM_SHARES_RESOURCE_INDEX_SQL = `CREATE INDEX IF NOT EXISTS data_program_shares_resource_idx ON data_program_shares (resource_id)`;
|
|
55
58
|
export function dataProgramRunsCreateSql(integerType) {
|
|
56
59
|
return `CREATE TABLE IF NOT EXISTS data_program_runs (
|
|
@@ -6,7 +6,7 @@ import { ensureTableExists, ensureIndexExists, ensureColumnExists, } from "../db
|
|
|
6
6
|
import { retainRequestDbPoolScope } from "../db/request-pool-context.js";
|
|
7
7
|
import { accessFilter } from "../sharing/access.js";
|
|
8
8
|
import { registerShareableResource } from "../sharing/registry.js";
|
|
9
|
-
import { dataPrograms, dataProgramShares, DATA_PROGRAMS_CREATE_SQL, DATA_PROGRAM_SHARES_CREATE_SQL, DATA_PROGRAMS_APP_OWNER_INDEX_SQL, DATA_PROGRAMS_APP_NAME_INDEX_SQL, DATA_PROGRAM_SHARES_RESOURCE_INDEX_SQL, dataProgramRunsCreateSql, DATA_PROGRAM_RUNS_TRUNCATED_COLUMN_SQL, DATA_PROGRAM_RUNS_LOOKUP_INDEX_SQL, } from "./schema.js";
|
|
9
|
+
import { dataPrograms, dataProgramShares, DATA_PROGRAMS_CREATE_SQL, DATA_PROGRAM_SHARES_CREATE_SQL, DATA_PROGRAMS_APP_OWNER_INDEX_SQL, DATA_PROGRAMS_APP_NAME_INDEX_SQL, DATA_PROGRAM_SHARES_RESOURCE_INDEX_SQL, DATA_PROGRAM_SHARES_NOTIFIED_AT_COLUMN_SQL, dataProgramRunsCreateSql, DATA_PROGRAM_RUNS_TRUNCATED_COLUMN_SQL, DATA_PROGRAM_RUNS_LOOKUP_INDEX_SQL, } from "./schema.js";
|
|
10
10
|
export const MAX_PROGRAM_ROWS = 10_000;
|
|
11
11
|
export const MAX_PROGRAM_RESULT_BYTES = 4 * 1024 * 1024;
|
|
12
12
|
export const MAX_ACTIVE_PROGRAMS_PER_APP = 200;
|
|
@@ -21,6 +21,7 @@ export async function ensureDataProgramTables() {
|
|
|
21
21
|
const runsCreateSql = dataProgramRunsCreateSql(integerType);
|
|
22
22
|
await ensureTableExists("data_programs", DATA_PROGRAMS_CREATE_SQL);
|
|
23
23
|
await ensureTableExists("data_program_shares", DATA_PROGRAM_SHARES_CREATE_SQL);
|
|
24
|
+
await ensureColumnExists("data_program_shares", "notified_at", DATA_PROGRAM_SHARES_NOTIFIED_AT_COLUMN_SQL);
|
|
24
25
|
await ensureTableExists("data_program_runs", runsCreateSql);
|
|
25
26
|
await ensureColumnExists("data_program_runs", "truncated", DATA_PROGRAM_RUNS_TRUNCATED_COLUMN_SQL);
|
|
26
27
|
await ensureIndexExists("data_programs_app_owner_idx", DATA_PROGRAMS_APP_OWNER_INDEX_SQL);
|
package/dist/deploy/build.js
CHANGED
|
@@ -21,6 +21,7 @@ import { DEFAULT_SPECULATION_RULES_PATH, resolveChunkRecoveryCacheHeaders, resol
|
|
|
21
21
|
import { EMBED_TARGET_QUERY_PARAM, EMBED_TOKEN_QUERY_PARAM, } from "../shared/embed-auth.js";
|
|
22
22
|
import { FRAMEWORK_INTERNAL_ROUTE_PREFIX, normalizeFrameworkRoutePrefix, toPublicFrameworkPath, } from "../shared/framework-route-prefix.js";
|
|
23
23
|
import { mcpEmbedStaticAssetRouteRules } from "../shared/mcp-embed-headers.js";
|
|
24
|
+
import { CORE_BUNDLED_INGESTION_OPTIONAL_PEERS, getMissingCoreOptionalPeers, } from "../shared/optional-peer-ssr.js";
|
|
24
25
|
import { CHUNK_RECOVERY_PATH_SUFFIX, CHUNK_RECOVERY_QUERY_PARAM, CHUNK_RECOVERY_QUERY_VALUE, } from "../shared/route-chunk-recovery-bootstrap.js";
|
|
25
26
|
import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
|
|
26
27
|
import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, } from "../shared/social-meta.js";
|
|
@@ -35,6 +36,10 @@ import { discoverPlugins, DEFAULT_PLUGIN_REGISTRY, } from "./route-discovery.js"
|
|
|
35
36
|
import { getWorkspaceCoreExports, } from "./workspace-core.js";
|
|
36
37
|
const cwd = process.cwd();
|
|
37
38
|
const preset = process.env.NITRO_PRESET || "node";
|
|
39
|
+
function packageExternalPattern(packageName) {
|
|
40
|
+
const escaped = packageName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
41
|
+
return new RegExp(`^${escaped}(?:/|$)`);
|
|
42
|
+
}
|
|
38
43
|
export const CLOUDFLARE_MODULE_PRESETS = [
|
|
39
44
|
"cloudflare_module",
|
|
40
45
|
"cloudflare-module",
|
|
@@ -3544,13 +3549,6 @@ const NETLIFY_DEFAULT_FUNCTION_URL_REDIRECT = "/* /.netlify/functions/server 200
|
|
|
3544
3549
|
function hasBareYjsRuntimeImport(source) {
|
|
3545
3550
|
return /\b(?:from\s*|import\s*\(\s*|import\s*)["']yjs(?:\/[^"']*)?["']/.test(source);
|
|
3546
3551
|
}
|
|
3547
|
-
const NETLIFY_BUNDLED_INGESTION_DEPENDENCIES = [
|
|
3548
|
-
"fast-xml-parser",
|
|
3549
|
-
"jszip",
|
|
3550
|
-
"officeparser",
|
|
3551
|
-
"pdf-parse",
|
|
3552
|
-
"pdfjs-dist",
|
|
3553
|
-
];
|
|
3554
3552
|
function hasBareRuntimeImport(source, packageName) {
|
|
3555
3553
|
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3556
3554
|
const quote = `["\'\\\`]`;
|
|
@@ -3892,7 +3890,7 @@ export function assertSingleTemplateNetlifyBuildOutput(projectCwd) {
|
|
|
3892
3890
|
const bareIngestionImports = [];
|
|
3893
3891
|
walkServerJavaScriptFiles(serverDir, (filePath) => {
|
|
3894
3892
|
const source = fs.readFileSync(filePath, "utf-8");
|
|
3895
|
-
for (const dependency of
|
|
3893
|
+
for (const dependency of CORE_BUNDLED_INGESTION_OPTIONAL_PEERS) {
|
|
3896
3894
|
if (hasBareRuntimeImport(source, dependency)) {
|
|
3897
3895
|
bareIngestionImports.push(`${dependency} in ${path.relative(projectCwd, filePath)}`);
|
|
3898
3896
|
}
|
|
@@ -4785,6 +4783,14 @@ export default bundle;
|
|
|
4785
4783
|
const providedPluginsNitroPlugin = await writeProvidedPluginsNitroPlugin();
|
|
4786
4784
|
const awsLambdaStreaming = isAwsLambdaStreamingBuild(preset, nitroEnvironment);
|
|
4787
4785
|
const nitroServerCodeSplittingConfig = nitroServerCodeSplittingConfigForPreset(preset);
|
|
4786
|
+
const nodeExternalPreset = preset === "netlify" ||
|
|
4787
|
+
preset === "vercel" ||
|
|
4788
|
+
isAwsLambdaPreset(preset) ||
|
|
4789
|
+
preset === "node" ||
|
|
4790
|
+
preset === "node-server";
|
|
4791
|
+
const optionalPeerExternals = nodeExternalPreset
|
|
4792
|
+
? getMissingCoreOptionalPeers(cwd).map(packageExternalPattern)
|
|
4793
|
+
: [];
|
|
4788
4794
|
const sentryServerSourceMapPlugins = await createSentryServerSourceMapUploadPlugins(nitroEnvironment);
|
|
4789
4795
|
const nitroVirtual = {
|
|
4790
4796
|
"virtual:agents-bundle": agentsBundleModuleSource,
|
|
@@ -4828,12 +4834,8 @@ export default bundle;
|
|
|
4828
4834
|
resolveHarnessBuildReplacement(nitroAgentConfig)),
|
|
4829
4835
|
rolldownConfig: nitroServerCodeSplittingConfig,
|
|
4830
4836
|
rollupConfig: {
|
|
4831
|
-
...(
|
|
4832
|
-
|
|
4833
|
-
isAwsLambdaPreset(preset) ||
|
|
4834
|
-
preset === "node" ||
|
|
4835
|
-
preset === "node-server"
|
|
4836
|
-
? { external: ["yjs"] }
|
|
4837
|
+
...(nodeExternalPreset
|
|
4838
|
+
? { external: ["yjs", ...optionalPeerExternals] }
|
|
4837
4839
|
: {}),
|
|
4838
4840
|
plugins: [
|
|
4839
4841
|
...(preset.startsWith("cloudflare")
|