@agent-native/core 0.210.0 → 0.210.1-nightly-20261020010058
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/action.js +16 -1
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.js +2 -0
- package/dist/agent/reaped-run-thread.d.ts +1 -1
- package/dist/agent/reaped-run-thread.js +21 -6
- package/dist/agent/run-store.fencing.worker.js +58 -0
- package/dist/agent/run-store.js +7 -5
- package/dist/agent/run-thread-projector.d.ts +27 -0
- package/dist/agent/run-thread-projector.js +79 -0
- package/dist/agent/thread-data-builder.js +38 -13
- package/dist/automation/index.d.ts +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +30 -27
- package/dist/cli/package-lifecycle.js +3 -2
- package/dist/cli/setup-agents.d.ts +5 -0
- package/dist/cli/setup-agents.js +91 -34
- package/dist/cli/skills.js +8 -14
- package/dist/cli/tar-command.d.ts +1 -0
- package/dist/cli/tar-command.js +9 -0
- package/dist/cli/template-baseline.js +6 -3
- package/dist/cli/template-sync.d.ts +2 -1
- package/dist/cli/template-sync.js +2 -1
- package/dist/client/agent-chat.d.ts +1 -0
- package/dist/client/agent-chat.js +1 -1
- package/dist/client/api-path.d.ts +1 -0
- package/dist/client/api-path.js +6 -0
- package/dist/client/chat/agentkit-agent-native.js +6 -2
- package/dist/client/chat/runtime.js +3 -0
- package/dist/client/use-agent-chat-context.js +6 -3
- package/dist/client/use-db-sync.js +3 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +2 -2
- package/dist/deploy/immutable-assets.d.ts +1 -1
- package/dist/deploy/immutable-assets.js +1 -1
- package/dist/deploy/workspace-deploy.js +12 -5
- package/dist/file-upload/actions/upload-image.d.ts +3 -3
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/jobs/background-automation-runner.js +16 -7
- package/dist/mcp/build-server.js +5 -1
- package/dist/mcp/embed-app.js +84 -17
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +7 -7
- package/dist/org/actions/invite-organization-member.js +1 -0
- package/dist/org/actions/list-organization-members.js +1 -0
- package/dist/org/index.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/scripts/db/exec.js +18 -6
- package/dist/scripts/db/patch.js +20 -8
- package/dist/scripts/db/postgres-client.d.ts +2 -0
- package/dist/scripts/db/postgres-client.js +17 -1
- package/dist/scripts/db/query.js +7 -6
- package/dist/scripts/db/safety.js +2 -1
- package/dist/secrets/routes.d.ts +10 -10
- package/dist/server/agent-chat-plugin.js +17 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-teams.js +9 -3
- package/dist/server/framework-request-handler.js +19 -0
- package/dist/server/fusion-app.d.ts +7 -0
- package/dist/server/fusion-app.js +11 -2
- package/dist/templates/builder-code-starter/.agents/skills/actions/SKILL.md.patch +1 -1
- package/dist/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +26 -45
- package/dist/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +2 -1
- package/dist/templates/chat/.agents/skills/context-awareness/SKILL.md +5 -0
- package/dist/templates/chat/app/components/chat/ChatHomeRedirect.tsx +2 -2
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +51 -22
- package/dist/templates/chat/server/plugins/agent-chat.ts +1 -0
- package/dist/templates/default/.agents/skills/context-awareness/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +5 -0
- package/dist/triggers/actions/manage-automation.d.ts +5 -5
- package/package.json +5 -5
- package/src/templates/builder-code-starter/.agents/skills/actions/SKILL.md.patch +1 -1
- package/src/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +26 -45
- package/src/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +2 -1
- package/src/templates/chat/.agents/skills/context-awareness/SKILL.md +5 -0
- package/src/templates/chat/app/components/chat/ChatHomeRedirect.tsx +2 -2
- package/src/templates/chat/app/hooks/use-navigation-state.ts +51 -22
- package/src/templates/chat/server/plugins/agent-chat.ts +1 -0
- package/src/templates/default/.agents/skills/context-awareness/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +5 -0
package/dist/mcp/embed-app.js
CHANGED
|
@@ -1266,18 +1266,53 @@ export function embedApp(options = {}) {
|
|
|
1266
1266
|
|
|
1267
1267
|
// Best-effort telemetry sink so inline-embed failures are visible in
|
|
1268
1268
|
// Sentry (handshake timeout, transplant fetch status/CORS, auth, CSP).
|
|
1269
|
-
// The shell is a sandboxed opaque-origin iframe, so it POSTs to the app
|
|
1270
|
-
//
|
|
1271
|
-
//
|
|
1269
|
+
// The shell is a sandboxed opaque-origin iframe, so it POSTs to the app's
|
|
1270
|
+
// CORS-open /_agent-native/mcp/embed-error route. Deduped per stage+message
|
|
1271
|
+
// so a retry loop can't spam.
|
|
1272
1272
|
const reportedEmbedErrorKeys = new Set();
|
|
1273
1273
|
let embedErrorReportCount = 0;
|
|
1274
|
-
function
|
|
1275
|
-
|
|
1274
|
+
function embedReportUrls() {
|
|
1275
|
+
const embedStartPath = "/_agent-native/embed/start";
|
|
1276
|
+
const reportPath = "/_agent-native/mcp/embed-error";
|
|
1277
|
+
const values = [openStartUrl, openUrl, lastFrameSrc];
|
|
1278
|
+
for (const value of values) {
|
|
1276
1279
|
if (typeof value === "string" && value) {
|
|
1277
|
-
|
|
1280
|
+
if (!URL.canParse(value, window.location.href)) continue;
|
|
1281
|
+
const url = new URL(value, window.location.href);
|
|
1282
|
+
url.username = "";
|
|
1283
|
+
url.password = "";
|
|
1284
|
+
if (!url.pathname.endsWith(embedStartPath)) continue;
|
|
1285
|
+
const appBasePath = url.pathname.slice(0, -embedStartPath.length);
|
|
1286
|
+
url.pathname = appBasePath + "/_agent-native/mcp/embed-error";
|
|
1287
|
+
url.search = "";
|
|
1288
|
+
url.hash = "";
|
|
1289
|
+
return [url.href];
|
|
1278
1290
|
}
|
|
1279
1291
|
}
|
|
1280
|
-
|
|
1292
|
+
|
|
1293
|
+
const value = [openUrl, lastFrameSrc, openStartUrl].find(
|
|
1294
|
+
(candidate) =>
|
|
1295
|
+
typeof candidate === "string" &&
|
|
1296
|
+
candidate &&
|
|
1297
|
+
URL.canParse(candidate, window.location.href),
|
|
1298
|
+
);
|
|
1299
|
+
if (!value) return [];
|
|
1300
|
+
|
|
1301
|
+
const url = new URL(value, window.location.href);
|
|
1302
|
+
url.username = "";
|
|
1303
|
+
url.password = "";
|
|
1304
|
+
const routeMarker = url.pathname.indexOf("/_agent-native/");
|
|
1305
|
+
if (routeMarker >= 0) {
|
|
1306
|
+
url.pathname = url.pathname.slice(0, routeMarker) + reportPath;
|
|
1307
|
+
url.search = "";
|
|
1308
|
+
url.hash = "";
|
|
1309
|
+
return [url.href];
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
url.pathname = reportPath;
|
|
1313
|
+
url.search = "";
|
|
1314
|
+
url.hash = "";
|
|
1315
|
+
return [url.href];
|
|
1281
1316
|
}
|
|
1282
1317
|
function reportEmbedError(stage, message, detail, status) {
|
|
1283
1318
|
try {
|
|
@@ -1285,28 +1320,60 @@ export function embedApp(options = {}) {
|
|
|
1285
1320
|
if (reportedEmbedErrorKeys.has(key) || embedErrorReportCount >= 8) return;
|
|
1286
1321
|
reportedEmbedErrorKeys.add(key);
|
|
1287
1322
|
embedErrorReportCount += 1;
|
|
1288
|
-
const
|
|
1289
|
-
if (!
|
|
1323
|
+
const reportUrls = embedReportUrls();
|
|
1324
|
+
if (!reportUrls.length) return;
|
|
1325
|
+
const contextUrl = [openStartUrl, openUrl, lastFrameSrc].find(
|
|
1326
|
+
(value) =>
|
|
1327
|
+
typeof value === "string" &&
|
|
1328
|
+
value &&
|
|
1329
|
+
URL.canParse(value, window.location.href),
|
|
1330
|
+
);
|
|
1331
|
+
let embedUrl = "";
|
|
1332
|
+
if (contextUrl) {
|
|
1333
|
+
const url = new URL(contextUrl, window.location.href);
|
|
1334
|
+
// Embed paths can contain private resource identifiers.
|
|
1335
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
1336
|
+
embedUrl = url.origin;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1290
1339
|
let renderMode = "";
|
|
1291
1340
|
try { renderMode = renderModeSource().mode || ""; } catch {}
|
|
1292
1341
|
const body = JSON.stringify({
|
|
1293
1342
|
stage: String(stage || ""),
|
|
1294
1343
|
message: String(message || "").slice(0, 500),
|
|
1295
1344
|
detail: detail ? String(detail).slice(0, 1200) : undefined,
|
|
1296
|
-
url:
|
|
1345
|
+
url: embedUrl,
|
|
1297
1346
|
status: typeof status === "number" ? status : undefined,
|
|
1298
1347
|
host: window.location.hostname || "",
|
|
1299
1348
|
renderMode: renderMode,
|
|
1300
1349
|
bridge: openAiBridge ? "openai" : app ? "native" : "none",
|
|
1301
1350
|
userAgent: navigator.userAgent || ""
|
|
1302
1351
|
});
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1352
|
+
void (async () => {
|
|
1353
|
+
let lastFetchError;
|
|
1354
|
+
let lastResponseStatus;
|
|
1355
|
+
for (const reportUrl of reportUrls) {
|
|
1356
|
+
try {
|
|
1357
|
+
const response = await fetch(reportUrl, {
|
|
1358
|
+
method: "POST",
|
|
1359
|
+
credentials: "omit",
|
|
1360
|
+
keepalive: true,
|
|
1361
|
+
headers: { "Content-Type": "application/json" },
|
|
1362
|
+
body: body
|
|
1363
|
+
});
|
|
1364
|
+
if (response.status === 204) return;
|
|
1365
|
+
lastResponseStatus = response.status;
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
lastFetchError = error;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (lastFetchError || lastResponseStatus !== undefined) {
|
|
1371
|
+
console.warn("[agent-native] MCP embed error report was not accepted", {
|
|
1372
|
+
status: lastResponseStatus,
|
|
1373
|
+
error: lastFetchError
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
})();
|
|
1310
1377
|
} catch {}
|
|
1311
1378
|
}
|
|
1312
1379
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
2
|
-
error?: undefined;
|
|
3
2
|
count: number;
|
|
4
3
|
updated?: undefined;
|
|
4
|
+
error?: undefined;
|
|
5
5
|
ok?: undefined;
|
|
6
6
|
} | {
|
|
7
|
-
error?: undefined;
|
|
8
7
|
count?: undefined;
|
|
9
8
|
updated: number;
|
|
9
|
+
error?: undefined;
|
|
10
10
|
ok?: undefined;
|
|
11
11
|
} | {
|
|
12
12
|
count?: undefined;
|
|
@@ -14,8 +14,8 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
14
14
|
error: string;
|
|
15
15
|
ok?: undefined;
|
|
16
16
|
} | {
|
|
17
|
-
error?: undefined;
|
|
18
17
|
count?: undefined;
|
|
19
18
|
updated?: undefined;
|
|
19
|
+
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
21
21
|
}>>;
|
|
@@ -27,43 +27,43 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
27
27
|
thumbsUpRate: number;
|
|
28
28
|
avgEvalScore: number;
|
|
29
29
|
} | {
|
|
30
|
-
ok?: undefined;
|
|
31
30
|
error: string;
|
|
32
31
|
message: string;
|
|
33
32
|
summary?: undefined;
|
|
34
33
|
spans?: undefined;
|
|
35
|
-
} | {
|
|
36
|
-
error?: undefined;
|
|
37
34
|
ok?: undefined;
|
|
35
|
+
} | {
|
|
38
36
|
message?: undefined;
|
|
39
37
|
summary: import("./types.js").TraceSummary;
|
|
40
38
|
spans: import("./types.js").TraceSpan[];
|
|
41
|
-
} | {
|
|
42
39
|
error?: undefined;
|
|
43
40
|
ok?: undefined;
|
|
41
|
+
} | {
|
|
44
42
|
message?: undefined;
|
|
45
43
|
summary?: undefined;
|
|
46
44
|
spans?: undefined;
|
|
47
45
|
traceMissing: true;
|
|
48
46
|
id: string;
|
|
49
|
-
} | {
|
|
50
47
|
error?: undefined;
|
|
51
48
|
ok?: undefined;
|
|
49
|
+
} | {
|
|
52
50
|
message?: undefined;
|
|
53
51
|
summary?: undefined;
|
|
54
52
|
spans?: undefined;
|
|
55
53
|
traceMissing?: undefined;
|
|
56
54
|
id: string;
|
|
57
|
-
|
|
55
|
+
error?: undefined;
|
|
58
56
|
ok?: undefined;
|
|
57
|
+
} | {
|
|
59
58
|
message?: undefined;
|
|
60
59
|
summary?: undefined;
|
|
61
60
|
spans?: undefined;
|
|
62
61
|
error: any;
|
|
62
|
+
ok?: undefined;
|
|
63
63
|
} | {
|
|
64
|
-
error?: undefined;
|
|
65
64
|
message?: undefined;
|
|
66
65
|
summary?: undefined;
|
|
67
66
|
spans?: undefined;
|
|
67
|
+
error?: undefined;
|
|
68
68
|
ok: boolean;
|
|
69
69
|
}>>;
|
|
@@ -4,6 +4,7 @@ import { orgAdminAudit } from "../../audit/org-admin.js";
|
|
|
4
4
|
import { getDbExec } from "../../db/client.js";
|
|
5
5
|
import { requireOrgMember } from "../actions.js";
|
|
6
6
|
export default defineAction({
|
|
7
|
+
mcpTool: true,
|
|
7
8
|
description: "Invite one person to the active organization as a member and email them the invitation. Every call needs the user's approval. Only organization owners and admins may invite. Admin invitations are sent from Settings > Members.",
|
|
8
9
|
schema: z.object({ email: z.string().trim().email() }),
|
|
9
10
|
// The invitation email reaches a real person, so a saved "always allow"
|
|
@@ -4,6 +4,7 @@ import { getDbExec } from "../../db/client.js";
|
|
|
4
4
|
import { requireOrgMember } from "../actions.js";
|
|
5
5
|
const MAX_PENDING_INVITATIONS = 100;
|
|
6
6
|
export default defineAction({
|
|
7
|
+
mcpTool: true,
|
|
7
8
|
description: "List members of the active organization with their roles, sorted by email. Owners and admins also get pending invitations.",
|
|
8
9
|
http: { method: "GET" },
|
|
9
10
|
schema: z.object({
|
package/dist/org/index.d.ts
CHANGED
|
@@ -162,9 +162,9 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
|
|
|
162
162
|
soloDeploymentAdmin: boolean;
|
|
163
163
|
}>>;
|
|
164
164
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
165
|
+
name?: undefined;
|
|
165
166
|
success: boolean;
|
|
166
167
|
id?: undefined;
|
|
167
|
-
name?: undefined;
|
|
168
168
|
role?: undefined;
|
|
169
169
|
} | {
|
|
170
170
|
success?: undefined;
|
|
@@ -75,10 +75,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
75
75
|
user: "user";
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
|
-
|
|
78
|
+
id?: undefined;
|
|
79
79
|
deleted?: undefined;
|
|
80
80
|
found?: undefined;
|
|
81
|
-
id?: undefined;
|
|
82
81
|
providers: {
|
|
83
82
|
id: string;
|
|
84
83
|
label: string;
|
|
@@ -92,18 +91,18 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
92
91
|
provider?: undefined;
|
|
93
92
|
registered?: undefined;
|
|
94
93
|
label?: undefined;
|
|
95
|
-
} | {
|
|
96
94
|
message?: undefined;
|
|
97
|
-
|
|
95
|
+
} | {
|
|
98
96
|
id?: undefined;
|
|
97
|
+
deleted?: undefined;
|
|
99
98
|
providers?: undefined;
|
|
100
99
|
count?: 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
|
deleted?: undefined;
|
|
108
107
|
providers?: undefined;
|
|
109
108
|
count?: undefined;
|
|
@@ -112,8 +111,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
112
111
|
id: string;
|
|
113
112
|
registered?: undefined;
|
|
114
113
|
label?: undefined;
|
|
115
|
-
} | {
|
|
116
114
|
message?: undefined;
|
|
115
|
+
} | {
|
|
117
116
|
found?: undefined;
|
|
118
117
|
providers?: undefined;
|
|
119
118
|
count?: undefined;
|
|
@@ -122,6 +121,7 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
122
121
|
id: string;
|
|
123
122
|
registered?: undefined;
|
|
124
123
|
label?: undefined;
|
|
124
|
+
message?: undefined;
|
|
125
125
|
} | {
|
|
126
126
|
deleted?: undefined;
|
|
127
127
|
found?: undefined;
|
|
@@ -316,10 +316,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
316
316
|
notes?: string | undefined;
|
|
317
317
|
scope?: "org" | "user" | undefined;
|
|
318
318
|
}, {
|
|
319
|
+
message?: undefined;
|
|
320
|
+
deleted?: undefined;
|
|
319
321
|
id?: undefined;
|
|
320
322
|
provider?: undefined;
|
|
321
|
-
deleted?: undefined;
|
|
322
|
-
message?: undefined;
|
|
323
323
|
found?: undefined;
|
|
324
324
|
providers: {
|
|
325
325
|
id: string;
|
|
@@ -334,9 +334,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
334
334
|
registered?: undefined;
|
|
335
335
|
label?: undefined;
|
|
336
336
|
} | {
|
|
337
|
-
id?: undefined;
|
|
338
|
-
deleted?: undefined;
|
|
339
337
|
message?: undefined;
|
|
338
|
+
deleted?: undefined;
|
|
339
|
+
id?: undefined;
|
|
340
340
|
providers?: undefined;
|
|
341
341
|
count?: undefined;
|
|
342
342
|
found: boolean;
|
|
@@ -344,9 +344,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
344
344
|
registered?: undefined;
|
|
345
345
|
label?: undefined;
|
|
346
346
|
} | {
|
|
347
|
-
provider?: undefined;
|
|
348
|
-
deleted?: undefined;
|
|
349
347
|
message?: undefined;
|
|
348
|
+
deleted?: undefined;
|
|
349
|
+
provider?: undefined;
|
|
350
350
|
providers?: undefined;
|
|
351
351
|
count?: undefined;
|
|
352
352
|
found: boolean;
|
|
@@ -354,8 +354,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
354
354
|
registered?: undefined;
|
|
355
355
|
label?: undefined;
|
|
356
356
|
} | {
|
|
357
|
-
provider?: undefined;
|
|
358
357
|
message?: undefined;
|
|
358
|
+
provider?: undefined;
|
|
359
359
|
found?: undefined;
|
|
360
360
|
providers?: undefined;
|
|
361
361
|
count?: undefined;
|
|
@@ -364,8 +364,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
364
364
|
registered?: undefined;
|
|
365
365
|
label?: undefined;
|
|
366
366
|
} | {
|
|
367
|
-
provider?: undefined;
|
|
368
367
|
deleted?: undefined;
|
|
368
|
+
provider?: undefined;
|
|
369
369
|
found?: undefined;
|
|
370
370
|
providers?: undefined;
|
|
371
371
|
count?: undefined;
|
package/dist/scripts/db/exec.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getDatabaseUrl } from "../../db/client.js";
|
|
3
3
|
import { parseArgs, fail } from "../utils.js";
|
|
4
|
-
import { createPostgresScriptClient } from "./postgres-client.js";
|
|
4
|
+
import { createPostgresScriptClient, withPostgresStatementDeadline, } from "./postgres-client.js";
|
|
5
5
|
import { finalRawDbSql, rawDbInsertTarget, readRawDbWriteStatement, verifyRawDbStatement, } from "./safety.js";
|
|
6
6
|
import { buildScopingPostgres } from "./scoping.js";
|
|
7
7
|
function parseSqlArgs(raw, label = "--args") {
|
|
@@ -151,9 +151,11 @@ Options:
|
|
|
151
151
|
try {
|
|
152
152
|
const results = [];
|
|
153
153
|
await client.begin(async (tx) => {
|
|
154
|
-
const
|
|
154
|
+
const timedTx = withPostgresStatementDeadline(tx);
|
|
155
|
+
const scoping = await buildScopingPostgres(timedTx);
|
|
155
156
|
for (const statement of scoping.setup)
|
|
156
|
-
await
|
|
157
|
+
await timedTx.unsafe(statement);
|
|
158
|
+
let operationFailed = false;
|
|
157
159
|
try {
|
|
158
160
|
for (let index = 0; index < statements.length; index++) {
|
|
159
161
|
const statement = statements[index];
|
|
@@ -162,13 +164,13 @@ Options:
|
|
|
162
164
|
// final SQL and check it against this transaction's state right
|
|
163
165
|
// before it runs, after any earlier statement in the batch.
|
|
164
166
|
const executed = finalRawDbSql(injectOwnership(statement.statement, scoping), "write", label);
|
|
165
|
-
await verifyRawDbStatement(
|
|
167
|
+
await verifyRawDbStatement(timedTx, executed.statement, {
|
|
166
168
|
columnsByTable: scoping.columnsByTable,
|
|
167
169
|
label,
|
|
168
170
|
});
|
|
169
171
|
const sql = executed.sql;
|
|
170
172
|
try {
|
|
171
|
-
const result = await
|
|
173
|
+
const result = await timedTx.unsafe(sql, statement.args, {
|
|
172
174
|
singleStatement: true,
|
|
173
175
|
});
|
|
174
176
|
results.push({
|
|
@@ -185,9 +187,19 @@ Options:
|
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
operationFailed = true;
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
188
194
|
finally {
|
|
189
195
|
for (const statement of scoping.teardown) {
|
|
190
|
-
|
|
196
|
+
try {
|
|
197
|
+
await timedTx.unsafe(statement);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
if (!operationFailed)
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
191
203
|
}
|
|
192
204
|
}
|
|
193
205
|
});
|
package/dist/scripts/db/patch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getDatabaseUrl } from "../../db/client.js";
|
|
3
3
|
import { parseArgs, fail } from "../utils.js";
|
|
4
|
-
import { createPostgresScriptClient } from "./postgres-client.js";
|
|
4
|
+
import { createPostgresScriptClient, withPostgresStatementDeadline, } from "./postgres-client.js";
|
|
5
5
|
import { assertNoRawDbAccessControlPatchTarget, assertNoSensitiveFrameworkTables, finalRawDbSql, readRawDbPatchStatement, validateRawDbPatchWhere, verifyRawDbStatement, } from "./safety.js";
|
|
6
6
|
import { buildScopingPostgres } from "./scoping.js";
|
|
7
7
|
function isValidIdentifier(value) {
|
|
@@ -348,12 +348,14 @@ Options:
|
|
|
348
348
|
try {
|
|
349
349
|
let output;
|
|
350
350
|
await client.begin(async (tx) => {
|
|
351
|
-
const
|
|
351
|
+
const timedTx = withPostgresStatementDeadline(tx);
|
|
352
|
+
const scoping = await buildScopingPostgres(timedTx);
|
|
352
353
|
for (const statement of scoping.setup)
|
|
353
|
-
await
|
|
354
|
+
await timedTx.unsafe(statement);
|
|
355
|
+
let operationFailed = false;
|
|
354
356
|
try {
|
|
355
|
-
await verifyRawDbStatement(
|
|
356
|
-
const selected = await
|
|
357
|
+
await verifyRawDbStatement(timedTx, select.statement);
|
|
358
|
+
const selected = await timedTx.unsafe(select.sql, [], {
|
|
357
359
|
singleStatement: true,
|
|
358
360
|
});
|
|
359
361
|
if (selected.length === 0) {
|
|
@@ -369,8 +371,8 @@ Options:
|
|
|
369
371
|
}
|
|
370
372
|
const edited = applyEditsToValue(original, options);
|
|
371
373
|
if (edited.applied > 0) {
|
|
372
|
-
await verifyRawDbStatement(
|
|
373
|
-
await
|
|
374
|
+
await verifyRawDbStatement(timedTx, update.statement);
|
|
375
|
+
await timedTx.unsafe(update.sql, [edited.content], {
|
|
374
376
|
singleStatement: true,
|
|
375
377
|
});
|
|
376
378
|
}
|
|
@@ -384,9 +386,19 @@ Options:
|
|
|
384
386
|
results: edited.results,
|
|
385
387
|
};
|
|
386
388
|
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
operationFailed = true;
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
387
393
|
finally {
|
|
388
394
|
for (const statement of scoping.teardown) {
|
|
389
|
-
|
|
395
|
+
try {
|
|
396
|
+
await timedTx.unsafe(statement);
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
if (!operationFailed)
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
390
402
|
}
|
|
391
403
|
}
|
|
392
404
|
});
|
|
@@ -13,4 +13,6 @@ export interface PostgresScriptClient {
|
|
|
13
13
|
begin<T>(fn: (tx: PostgresScriptClient) => Promise<T>): Promise<T>;
|
|
14
14
|
end(): Promise<void>;
|
|
15
15
|
}
|
|
16
|
+
export declare function setRawDbStatementTimeout(client: Pick<PostgresScriptClient, "unsafe">): Promise<void>;
|
|
17
|
+
export declare function withPostgresStatementDeadline(client: Pick<PostgresScriptClient, "unsafe">, timeoutMs?: number): Pick<PostgresScriptClient, "unsafe">;
|
|
16
18
|
export declare function createPostgresScriptClient(url: string): Promise<PostgresScriptClient>;
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
import { getPgliteClient, isPgliteUrl, toPostgresParams, } from "../../db/client.js";
|
|
1
|
+
import { dbOpTimeoutMs, getPgliteClient, isPgliteUrl, postgresStatementTimeoutMs, toPostgresParams, } from "../../db/client.js";
|
|
2
|
+
export async function setRawDbStatementTimeout(client) {
|
|
3
|
+
await client.unsafe(`SET LOCAL statement_timeout = ${postgresStatementTimeoutMs(dbOpTimeoutMs())}`);
|
|
4
|
+
}
|
|
5
|
+
export function withPostgresStatementDeadline(client, timeoutMs = dbOpTimeoutMs()) {
|
|
6
|
+
const deadline = Date.now() + timeoutMs;
|
|
7
|
+
return {
|
|
8
|
+
async unsafe(sql, args, options) {
|
|
9
|
+
const remainingMs = Math.floor(deadline - Date.now());
|
|
10
|
+
if (remainingMs <= 0) {
|
|
11
|
+
throw new Error(`Database transaction timed out after ${timeoutMs}ms.`);
|
|
12
|
+
}
|
|
13
|
+
await client.unsafe(`SET LOCAL statement_timeout = ${postgresStatementTimeoutMs(remainingMs)}`);
|
|
14
|
+
return client.unsafe(sql, args, options);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
2
18
|
function rowsResult(rows, affectedRows) {
|
|
3
19
|
const records = (rows ?? []);
|
|
4
20
|
const result = records;
|
package/dist/scripts/db/query.js
CHANGED
|
@@ -3,7 +3,7 @@ import { assertHostedRuntimeDatabase, getLocalDatabaseUrl, } from "../../db/clie
|
|
|
3
3
|
import { getRequestOrgId, getRequestUserEmail, } from "../../server/request-context.js";
|
|
4
4
|
import { parseArgs, fail } from "../utils.js";
|
|
5
5
|
import { tryForwardDbQueryToDevServer } from "./dev-query-proxy.js";
|
|
6
|
-
import { createPostgresScriptClient } from "./postgres-client.js";
|
|
6
|
+
import { createPostgresScriptClient, withPostgresStatementDeadline, } from "./postgres-client.js";
|
|
7
7
|
import { finalRawDbSql, readRawDbReadStatement, verifyRawDbStatement, } from "./safety.js";
|
|
8
8
|
import { buildScopingPostgres } from "./scoping.js";
|
|
9
9
|
function parseSqlArgs(raw) {
|
|
@@ -67,14 +67,15 @@ export async function runDbQuery(options) {
|
|
|
67
67
|
let rows = [];
|
|
68
68
|
try {
|
|
69
69
|
await client.begin(async (tx) => {
|
|
70
|
-
const
|
|
70
|
+
const timedTx = withPostgresStatementDeadline(tx);
|
|
71
|
+
const scoping = await buildScopingPostgres(timedTx);
|
|
71
72
|
for (const setup of scoping.setup)
|
|
72
|
-
await
|
|
73
|
+
await timedTx.unsafe(setup);
|
|
73
74
|
// From here on the transaction cannot write, so a data-modifying CTE,
|
|
74
75
|
// SELECT INTO, or EXPLAIN ANALYZE of a write fails instead of running.
|
|
75
|
-
await
|
|
76
|
-
await verifyRawDbStatement(
|
|
77
|
-
const result = await
|
|
76
|
+
await timedTx.unsafe("SET TRANSACTION READ ONLY");
|
|
77
|
+
await verifyRawDbStatement(timedTx, executed.statement);
|
|
78
|
+
const result = await timedTx.unsafe(executed.sql, sqlArgs, {
|
|
78
79
|
singleStatement: true,
|
|
79
80
|
});
|
|
80
81
|
rows = Array.from(result);
|
|
@@ -50,6 +50,7 @@ const SENSITIVE_FRAMEWORK_TABLES = new Set([
|
|
|
50
50
|
"users",
|
|
51
51
|
"session",
|
|
52
52
|
"sessions",
|
|
53
|
+
"chat_threads",
|
|
53
54
|
"account",
|
|
54
55
|
"accounts",
|
|
55
56
|
"verification",
|
|
@@ -83,7 +84,7 @@ function assertNoSensitiveFrameworkTableTokens(tokens, operation) {
|
|
|
83
84
|
const name = token.value.toLowerCase();
|
|
84
85
|
if (!SENSITIVE_FRAMEWORK_TABLES.has(name))
|
|
85
86
|
continue;
|
|
86
|
-
fail(`Sensitive framework table "${name}" is not ${sensitiveVerb(operation)} through raw DB tools. Use the framework
|
|
87
|
+
fail(`Sensitive framework table "${name}" is not ${sensitiveVerb(operation)} through raw DB tools. Use the appropriate framework API instead.`);
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
export function assertNoSensitiveFrameworkTables(sql, operation) {
|
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
|
-
ok?: undefined;
|
|
61
60
|
status?: undefined;
|
|
61
|
+
ok?: undefined;
|
|
62
62
|
} | {
|
|
63
63
|
error: string;
|
|
64
64
|
errorCode: string;
|
|
65
|
-
ok?: undefined;
|
|
66
65
|
status?: undefined;
|
|
66
|
+
ok?: 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;
|
|
74
73
|
error: string;
|
|
75
74
|
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;
|
|
83
82
|
error: string;
|
|
84
83
|
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
|
}>>;
|
|
@@ -25,6 +25,7 @@ import { applyProviderModelSelection, providerForEngineName, resolveProviderMode
|
|
|
25
25
|
import { startRun } from "../agent/run-manager.js";
|
|
26
26
|
import { callerHasRunAccess, callerHasThreadAccess, } from "../agent/run-ownership.js";
|
|
27
27
|
import { readBackgroundRunClaim } from "../agent/run-store.js";
|
|
28
|
+
import { buildAssistantMessageFromRunJournal } from "../agent/run-thread-projector.js";
|
|
28
29
|
import { buildCurrentTimeUserContext, buildRuntimeContextPrompt, } from "../agent/runtime-context.js";
|
|
29
30
|
import { buildAssistantMessage, buildUserMessage, applySubmittedUserMessage, containsInlineAttachmentPayload, foldAgentChatRunCompletion, extractThreadMeta, foldUnstartedTurnFailure, mergeThreadDataForClientSave, } from "../agent/thread-data-builder.js";
|
|
30
31
|
import { appendThreadDebugHistory } from "../agent/thread-debug-history.js";
|
|
@@ -2824,21 +2825,29 @@ export function createAgentChatPlugin(options) {
|
|
|
2824
2825
|
}
|
|
2825
2826
|
}
|
|
2826
2827
|
// Callback to persist agent response when run finishes (even if client disconnected).
|
|
2827
|
-
// Reconstructs the assistant message from
|
|
2828
|
+
// Reconstructs the assistant message from the durable run journal.
|
|
2828
2829
|
const onRunComplete = async (run, threadId, trackingSource) => {
|
|
2829
2830
|
const runThreadId = String(run?.threadId ?? threadId ?? "");
|
|
2830
2831
|
const chatScope = getRequestRunContext()?.chatScope;
|
|
2831
|
-
const
|
|
2832
|
+
const assistantOptions = {
|
|
2832
2833
|
scope: chatScope,
|
|
2833
2834
|
suppressInternalContinuation: true,
|
|
2834
|
-
|
|
2835
|
-
? run.turnId
|
|
2836
|
-
: undefined,
|
|
2837
|
-
runDurationMs: typeof run.startedAt === "number" &&
|
|
2838
|
-
Number.isFinite(run.startedAt)
|
|
2835
|
+
runDurationMs: typeof run.startedAt === "number" && Number.isFinite(run.startedAt)
|
|
2839
2836
|
? Math.max(0, Date.now() - run.startedAt)
|
|
2840
2837
|
: undefined,
|
|
2841
|
-
}
|
|
2838
|
+
};
|
|
2839
|
+
const assistantMsg = runThreadId && run.turnId
|
|
2840
|
+
? await buildAssistantMessageFromRunJournal({
|
|
2841
|
+
threadId: runThreadId,
|
|
2842
|
+
turnId: run.turnId,
|
|
2843
|
+
runId: run.runId,
|
|
2844
|
+
runEvents: run.events ?? [],
|
|
2845
|
+
options: assistantOptions,
|
|
2846
|
+
})
|
|
2847
|
+
: buildAssistantMessage(run.events ?? [], run.runId, {
|
|
2848
|
+
...assistantOptions,
|
|
2849
|
+
turnId: run.turnId,
|
|
2850
|
+
});
|
|
2842
2851
|
const runContext = getRequestRunContext();
|
|
2843
2852
|
const failureCode = run.status === "errored"
|
|
2844
2853
|
? [...(run.events ?? [])]
|