@agent-native/core 0.196.0-nightly-20260928172902 → 0.196.0
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +17 -0
- package/corpus/templates/assets/CHANGELOG.md +18 -0
- package/corpus/templates/brain/CHANGELOG.md +6 -0
- package/corpus/templates/calendar/CHANGELOG.md +4 -0
- package/corpus/templates/clips/CHANGELOG.md +19 -0
- package/corpus/templates/clips/actions/create-recording-agent-link.ts +8 -2
- package/corpus/templates/clips/actions/update-recording.ts +5 -1
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +10 -3
- package/corpus/templates/clips/changelog/2026-09-28-agent-links-stay-valid-when-clip-details-change.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-28-password-changes-immediately-invalidate-old-recording-links.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-28-password-protected-recording-links-stop-working-when-the-pas.md +6 -0
- package/corpus/templates/clips/server/db/schema.ts +3 -0
- package/corpus/templates/clips/server/lib/player-video-url.ts +9 -1
- package/corpus/templates/clips/server/lib/public-agent-context.ts +12 -4
- package/corpus/templates/clips/server/lib/share-password.ts +25 -0
- package/corpus/templates/clips/server/plugins/db.ts +36 -0
- package/corpus/templates/clips/server/routes/[...page].get.ts +8 -1
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +33 -6
- package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +34 -6
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +26 -5
- package/corpus/templates/content/CHANGELOG.md +1 -0
- package/corpus/templates/crm/CHANGELOG.md +12 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +265 -3
- package/corpus/templates/design/CHANGELOG.md +21 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +463 -6
- package/corpus/templates/design/app/pages/Index.tsx +1 -1
- package/corpus/templates/design/changelog/2026-09-27-auto-focused-app-fields-no-longer-interrupt-canvas-shortcuts.md +6 -0
- package/corpus/templates/design/changelog/2026-09-28-model-picker-loads-available-models.md +6 -0
- package/corpus/templates/design/changelog/2026-09-28-template-menus-stay-available-on-hover.md +6 -0
- package/corpus/templates/dispatch/CHANGELOG.md +18 -0
- package/corpus/templates/forms/CHANGELOG.md +6 -0
- package/corpus/templates/mail/.env.example +1 -1
- package/corpus/templates/mail/CHANGELOG.md +33 -0
- package/corpus/templates/mail/changelog/2026-09-28-fixed-inbox-loading-stalls-and-showed-progress-during-google-2.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-28-fixed-inbox-loading-stalls-and-showed-progress-during-google.md +6 -0
- package/corpus/templates/mail/server/db/schema.ts +7 -0
- package/corpus/templates/mail/server/lib/ai-filter-backfill.ts +4 -0
- package/corpus/templates/mail/server/lib/jobs.ts +5 -2
- package/corpus/templates/mail/server/plugins/db.ts +16 -0
- package/corpus/templates/mail/server/plugins/mail-jobs.ts +355 -44
- package/corpus/templates/slides/CHANGELOG.md +28 -0
- package/corpus/templates/slides/app/pages/Index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-09-28-model-picker-loads-available-models.md +6 -0
- package/corpus/templates/slides/changelog/2026-09-28-template-menus-stay-available-on-hover.md +6 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/auth/AuthPage.js +3 -2
- package/dist/client/org/OrgSwitcher.js +31 -19
- package/dist/client/settings/UsageSection.js +3 -3
- package/dist/client/use-action.js +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/jobs/background-automation-runner.d.ts +2 -0
- package/dist/jobs/background-automation-runner.js +20 -1
- package/dist/jobs/sweep-hooks.d.ts +6 -2
- package/dist/jobs/sweep-hooks.js +17 -9
- package/dist/localization/core-messages/ar-SA.js +2 -2
- package/dist/localization/core-messages/de-DE.js +2 -2
- package/dist/localization/core-messages/en-US.d.ts +2 -2
- package/dist/localization/core-messages/en-US.js +2 -2
- package/dist/localization/core-messages/es-ES.js +2 -2
- package/dist/localization/core-messages/fr-FR.js +2 -2
- package/dist/localization/core-messages/hi-IN.js +2 -2
- package/dist/localization/core-messages/ja-JP.js +2 -2
- package/dist/localization/core-messages/ko-KR.js +2 -2
- package/dist/localization/core-messages/pt-BR.js +2 -2
- package/dist/localization/core-messages/zh-CN.js +2 -2
- package/dist/localization/core-messages/zh-TW.js +2 -2
- package/dist/localization/core-messages.d.ts +2 -2
- package/dist/notifications/routes.d.ts +5 -5
- package/dist/observability/routes.d.ts +6 -6
- package/dist/progress/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 +7 -7
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +4 -4
- package/dist/server/agent-chat-plugin.js +6 -2
- 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-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/triggers/dispatcher.js +167 -36
- package/dist/triggers/event-queue.d.ts +18 -1
- package/dist/triggers/event-queue.js +143 -10
- package/package.json +4 -4
|
@@ -4,14 +4,17 @@ import { getDbExec } from "../db/client.js";
|
|
|
4
4
|
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
5
5
|
import { runMigrations } from "../db/migrations.js";
|
|
6
6
|
const TABLE = "automation_trigger_event_queue";
|
|
7
|
+
const SWEEP_STATE_TABLE = "automation_trigger_event_queue_sweep_state";
|
|
7
8
|
const COMPLETED_PAYLOAD = '{"kind":"completed"}';
|
|
8
9
|
const UNIQUE_INDEX = "idx_automation_trigger_event_queue_dedupe";
|
|
9
10
|
const ORDER_INDEX = "idx_automation_trigger_event_queue_order";
|
|
10
11
|
const READY_INDEX = "idx_automation_trigger_event_queue_ready";
|
|
11
12
|
const COMPLETED_INDEX = "idx_automation_trigger_event_queue_completed";
|
|
12
13
|
const FAILED_INDEX = "idx_automation_trigger_event_queue_failed";
|
|
14
|
+
const STALE_EVENT_INDEX = "idx_automation_trigger_event_queue_stale_event";
|
|
13
15
|
export const AUTOMATION_TRIGGER_EVENT_DEDUPE_RETENTION_MS = 7 * 24 * 60 * 60_000;
|
|
14
16
|
export const AUTOMATION_TRIGGER_EVENT_PURGE_BATCH_SIZE = 1_000;
|
|
17
|
+
export const AUTOMATION_TRIGGER_EVENT_EXPIRY_BATCH_SIZE = 1_000;
|
|
15
18
|
export const MAX_AUTOMATION_TRIGGER_EVENT_FAILURES = 8;
|
|
16
19
|
const CLAIM_LEASE_MS = () => Math.ceil(resolveBackgroundRunHardTimeoutMs() * 1.5);
|
|
17
20
|
const CREATE_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ${TABLE} (
|
|
@@ -35,6 +38,12 @@ const CREATE_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ${TABLE} (
|
|
|
35
38
|
completed_at BIGINT,
|
|
36
39
|
last_error TEXT
|
|
37
40
|
)`;
|
|
41
|
+
const CREATE_SWEEP_STATE_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ${SWEEP_STATE_TABLE} (
|
|
42
|
+
scope_key TEXT PRIMARY KEY,
|
|
43
|
+
last_trigger_id TEXT,
|
|
44
|
+
purge_after BIGINT NOT NULL DEFAULT 0,
|
|
45
|
+
updated_at BIGINT NOT NULL
|
|
46
|
+
)`;
|
|
38
47
|
export const AUTOMATION_TRIGGER_EVENT_MIGRATIONS = [
|
|
39
48
|
{
|
|
40
49
|
version: 1,
|
|
@@ -59,6 +68,18 @@ export const AUTOMATION_TRIGGER_EVENT_MIGRATIONS = [
|
|
|
59
68
|
CREATE INDEX IF NOT EXISTS ${FAILED_INDEX}
|
|
60
69
|
ON ${TABLE} (completed_at) WHERE status = 'failed'`,
|
|
61
70
|
},
|
|
71
|
+
{
|
|
72
|
+
version: 3,
|
|
73
|
+
name: "automation-trigger-event-stale-mail-index",
|
|
74
|
+
sql: `CREATE INDEX IF NOT EXISTS ${STALE_EVENT_INDEX}
|
|
75
|
+
ON ${TABLE} (app_id, event_name, emitted_at)
|
|
76
|
+
WHERE status = 'pending'`,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
version: 4,
|
|
80
|
+
name: "automation-trigger-event-queue-sweep-state",
|
|
81
|
+
sql: CREATE_SWEEP_STATE_TABLE_SQL,
|
|
82
|
+
},
|
|
62
83
|
];
|
|
63
84
|
export async function runAutomationTriggerEventMigrations(nitroApp) {
|
|
64
85
|
await runMigrations(AUTOMATION_TRIGGER_EVENT_MIGRATIONS, {
|
|
@@ -70,6 +91,7 @@ export async function ensureAutomationTriggerEventQueue() {
|
|
|
70
91
|
if (!_initPromise) {
|
|
71
92
|
_initPromise = (async () => {
|
|
72
93
|
await ensureTableExists(TABLE, CREATE_TABLE_SQL);
|
|
94
|
+
await ensureTableExists(SWEEP_STATE_TABLE, CREATE_SWEEP_STATE_TABLE_SQL);
|
|
73
95
|
await ensureColumnExists(TABLE, "failure_attempts", `ALTER TABLE ${TABLE}
|
|
74
96
|
ADD COLUMN IF NOT EXISTS failure_attempts BIGINT NOT NULL DEFAULT 0`);
|
|
75
97
|
await ensureIndexExists(UNIQUE_INDEX, `CREATE UNIQUE INDEX IF NOT EXISTS ${UNIQUE_INDEX}
|
|
@@ -80,6 +102,9 @@ export async function ensureAutomationTriggerEventQueue() {
|
|
|
80
102
|
ON ${TABLE} (app_id, status, available_at, claimed_at)`);
|
|
81
103
|
await ensureIndexExists(FAILED_INDEX, `CREATE INDEX IF NOT EXISTS ${FAILED_INDEX}
|
|
82
104
|
ON ${TABLE} (completed_at) WHERE status = 'failed'`);
|
|
105
|
+
await ensureIndexExists(STALE_EVENT_INDEX, `CREATE INDEX IF NOT EXISTS ${STALE_EVENT_INDEX}
|
|
106
|
+
ON ${TABLE} (app_id, event_name, emitted_at)
|
|
107
|
+
WHERE status = 'pending'`);
|
|
83
108
|
await ensureIndexExists(COMPLETED_INDEX, `CREATE INDEX IF NOT EXISTS ${COMPLETED_INDEX}
|
|
84
109
|
ON ${TABLE} (completed_at) WHERE status = 'completed'`);
|
|
85
110
|
})().catch((error) => {
|
|
@@ -174,29 +199,89 @@ function appScopePredicate(appId) {
|
|
|
174
199
|
? { sql: "app_id = ?", args: [appId.trim()] }
|
|
175
200
|
: { sql: "app_id IS NULL", args: [] };
|
|
176
201
|
}
|
|
177
|
-
export async function listReadyAutomationTriggerIds(appId, limit = 100) {
|
|
202
|
+
export async function listReadyAutomationTriggerIds(appId, limit = 100, cursor = {}) {
|
|
178
203
|
await ensureAutomationTriggerEventQueue();
|
|
179
204
|
const now = Date.now();
|
|
180
205
|
const scope = appScopePredicate(appId);
|
|
206
|
+
const afterClause = cursor.afterTriggerId === undefined ? "" : "AND trigger_id > ?";
|
|
207
|
+
const throughClause = cursor.throughTriggerId === undefined ? "" : "AND trigger_id <= ?";
|
|
208
|
+
const args = [
|
|
209
|
+
...scope.args,
|
|
210
|
+
now,
|
|
211
|
+
now - CLAIM_LEASE_MS(),
|
|
212
|
+
...(cursor.afterTriggerId === undefined ? [] : [cursor.afterTriggerId]),
|
|
213
|
+
...(cursor.throughTriggerId === undefined ? [] : [cursor.throughTriggerId]),
|
|
214
|
+
Math.max(1, Math.min(limit, 500)),
|
|
215
|
+
];
|
|
181
216
|
const { rows } = await getDbExec().execute({
|
|
182
|
-
sql: `SELECT trigger_id
|
|
217
|
+
sql: `SELECT DISTINCT trigger_id
|
|
183
218
|
FROM ${TABLE}
|
|
184
219
|
WHERE ${scope.sql}
|
|
185
220
|
AND ((status = 'pending' AND available_at <= ?)
|
|
186
221
|
OR (status = 'processing' AND
|
|
187
222
|
(claimed_at IS NULL OR claimed_at <= ?)))
|
|
188
|
-
|
|
189
|
-
|
|
223
|
+
${afterClause}
|
|
224
|
+
${throughClause}
|
|
225
|
+
ORDER BY trigger_id ASC
|
|
190
226
|
LIMIT ?`,
|
|
191
|
-
args
|
|
192
|
-
...scope.args,
|
|
193
|
-
now,
|
|
194
|
-
now - CLAIM_LEASE_MS(),
|
|
195
|
-
Math.max(1, Math.min(limit, 500)),
|
|
196
|
-
],
|
|
227
|
+
args,
|
|
197
228
|
});
|
|
198
229
|
return rows.map((row) => String(row.trigger_id));
|
|
199
230
|
}
|
|
231
|
+
export async function reserveAutomationTriggerEventPurge(appId, now = Date.now()) {
|
|
232
|
+
await ensureAutomationTriggerEventQueue();
|
|
233
|
+
const { rows } = await getDbExec().execute({
|
|
234
|
+
sql: `INSERT INTO ${SWEEP_STATE_TABLE}
|
|
235
|
+
(scope_key, last_trigger_id, purge_after, updated_at)
|
|
236
|
+
VALUES (?, NULL, ?, ?)
|
|
237
|
+
ON CONFLICT (scope_key) DO UPDATE
|
|
238
|
+
SET purge_after = excluded.purge_after,
|
|
239
|
+
updated_at = excluded.updated_at
|
|
240
|
+
WHERE ${SWEEP_STATE_TABLE}.purge_after <= ?
|
|
241
|
+
RETURNING scope_key`,
|
|
242
|
+
args: [appId?.trim() ?? "", now + 60_000, now, now],
|
|
243
|
+
});
|
|
244
|
+
return rows.length > 0;
|
|
245
|
+
}
|
|
246
|
+
export async function scheduleAutomationTriggerEventPurge(appId, nextAt) {
|
|
247
|
+
await ensureAutomationTriggerEventQueue();
|
|
248
|
+
await getDbExec().execute({
|
|
249
|
+
sql: `UPDATE ${SWEEP_STATE_TABLE}
|
|
250
|
+
SET purge_after = ?, updated_at = ?
|
|
251
|
+
WHERE scope_key = ?`,
|
|
252
|
+
args: [nextAt, Date.now(), appId?.trim() ?? ""],
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
export async function getAutomationTriggerSweepCursor(appId) {
|
|
256
|
+
await ensureAutomationTriggerEventQueue();
|
|
257
|
+
const { rows } = await getDbExec().execute({
|
|
258
|
+
sql: `SELECT last_trigger_id FROM ${SWEEP_STATE_TABLE} WHERE scope_key = ?`,
|
|
259
|
+
args: [appId?.trim() ?? ""],
|
|
260
|
+
});
|
|
261
|
+
const cursor = rows[0]
|
|
262
|
+
?.last_trigger_id;
|
|
263
|
+
return cursor == null ? null : String(cursor);
|
|
264
|
+
}
|
|
265
|
+
export async function setAutomationTriggerSweepCursor(appId, triggerId) {
|
|
266
|
+
await ensureAutomationTriggerEventQueue();
|
|
267
|
+
const scopeKey = appId?.trim() ?? "";
|
|
268
|
+
if (triggerId === null) {
|
|
269
|
+
await getDbExec().execute({
|
|
270
|
+
sql: `DELETE FROM ${SWEEP_STATE_TABLE} WHERE scope_key = ?`,
|
|
271
|
+
args: [scopeKey],
|
|
272
|
+
});
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
await getDbExec().execute({
|
|
276
|
+
sql: `INSERT INTO ${SWEEP_STATE_TABLE}
|
|
277
|
+
(scope_key, last_trigger_id, updated_at)
|
|
278
|
+
VALUES (?, ?, ?)
|
|
279
|
+
ON CONFLICT (scope_key) DO UPDATE
|
|
280
|
+
SET last_trigger_id = excluded.last_trigger_id,
|
|
281
|
+
updated_at = excluded.updated_at`,
|
|
282
|
+
args: [scopeKey, triggerId, Date.now()],
|
|
283
|
+
});
|
|
284
|
+
}
|
|
200
285
|
export async function claimNextAutomationTriggerEvent(triggerId, appId) {
|
|
201
286
|
await ensureAutomationTriggerEventQueue();
|
|
202
287
|
const now = Date.now();
|
|
@@ -247,6 +332,53 @@ export async function completeAutomationTriggerEvent(id, claimedAt, attempts) {
|
|
|
247
332
|
args: [COMPLETED_PAYLOAD, Date.now(), id, claimedAt, attempts],
|
|
248
333
|
});
|
|
249
334
|
}
|
|
335
|
+
export async function expireAutomationTriggerEvent(id, claimedAt, attempts, reason) {
|
|
336
|
+
await ensureAutomationTriggerEventQueue();
|
|
337
|
+
await getDbExec().execute({
|
|
338
|
+
sql: `UPDATE ${TABLE}
|
|
339
|
+
SET status = 'completed', payload = ?, claimed_at = NULL,
|
|
340
|
+
completed_at = ?, last_error = ?
|
|
341
|
+
WHERE id = ? AND status = 'processing'
|
|
342
|
+
AND claimed_at = ? AND attempts = ?`,
|
|
343
|
+
args: [
|
|
344
|
+
COMPLETED_PAYLOAD,
|
|
345
|
+
Date.now(),
|
|
346
|
+
reason.slice(0, 500),
|
|
347
|
+
id,
|
|
348
|
+
claimedAt,
|
|
349
|
+
attempts,
|
|
350
|
+
],
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
export async function expireStaleAutomationTriggerEvents(input) {
|
|
354
|
+
await ensureAutomationTriggerEventQueue();
|
|
355
|
+
const limit = Math.max(1, Math.min(input.limit ?? AUTOMATION_TRIGGER_EVENT_EXPIRY_BATCH_SIZE, 10_000));
|
|
356
|
+
const { rowsAffected } = await getDbExec().execute({
|
|
357
|
+
sql: `WITH expired AS (
|
|
358
|
+
SELECT id FROM ${TABLE}
|
|
359
|
+
WHERE app_id = ? AND event_name = ? AND status = 'pending'
|
|
360
|
+
AND emitted_at < ?
|
|
361
|
+
ORDER BY emitted_at ASC
|
|
362
|
+
LIMIT ?
|
|
363
|
+
FOR UPDATE SKIP LOCKED
|
|
364
|
+
)
|
|
365
|
+
UPDATE ${TABLE} AS queued
|
|
366
|
+
SET status = 'completed', payload = ?, claimed_at = NULL,
|
|
367
|
+
completed_at = ?, last_error = ?
|
|
368
|
+
FROM expired
|
|
369
|
+
WHERE queued.id = expired.id`,
|
|
370
|
+
args: [
|
|
371
|
+
input.appId,
|
|
372
|
+
input.eventName,
|
|
373
|
+
input.emittedBefore,
|
|
374
|
+
limit,
|
|
375
|
+
COMPLETED_PAYLOAD,
|
|
376
|
+
Date.now(),
|
|
377
|
+
input.reason.slice(0, 500),
|
|
378
|
+
],
|
|
379
|
+
});
|
|
380
|
+
return rowsAffected;
|
|
381
|
+
}
|
|
250
382
|
export async function retryAutomationTriggerEvent(id, claimedAt, attempts, failureAttempts, error, options = {}) {
|
|
251
383
|
await ensureAutomationTriggerEventQueue();
|
|
252
384
|
const message = error instanceof Error ? error.message : String(error ?? "Unknown error");
|
|
@@ -313,5 +445,6 @@ export async function purgeExpiredAutomationTriggerEvents(now = Date.now()) {
|
|
|
313
445
|
}
|
|
314
446
|
export const __automationTriggerEventQueue = {
|
|
315
447
|
table: TABLE,
|
|
448
|
+
sweepStateTable: SWEEP_STATE_TABLE,
|
|
316
449
|
claimLeaseMs: CLAIM_LEASE_MS,
|
|
317
450
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.196.0
|
|
3
|
+
"version": "0.196.0",
|
|
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": {
|
|
@@ -533,9 +533,9 @@
|
|
|
533
533
|
"yaml": "^2.9.0",
|
|
534
534
|
"yjs": "^13.6.32",
|
|
535
535
|
"zod": "^4.3.6",
|
|
536
|
-
"@agent-native/agentkit": "^0.5.0
|
|
537
|
-
"@agent-native/recap-cli": "0.5.
|
|
538
|
-
"@agent-native/toolkit": "^0.23.0
|
|
536
|
+
"@agent-native/agentkit": "^0.5.0",
|
|
537
|
+
"@agent-native/recap-cli": "0.5.48",
|
|
538
|
+
"@agent-native/toolkit": "^0.23.0"
|
|
539
539
|
},
|
|
540
540
|
"devDependencies": {
|
|
541
541
|
"@ai-sdk/anthropic": "^3.0.71",
|