@agent-native/core 0.154.4 → 0.154.5
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/content/.agents/skills/content/SKILL.md +2 -2
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +20 -4
- package/corpus/templates/content/actions/_database-row-mutation.ts +1490 -0
- package/corpus/templates/content/actions/_database-utils.ts +44 -0
- package/corpus/templates/content/actions/_property-utils.ts +4 -1
- package/corpus/templates/content/actions/add-database-item.ts +62 -240
- package/corpus/templates/content/actions/configure-document-property.ts +165 -1
- package/corpus/templates/content/actions/delete-document-property.ts +18 -0
- package/corpus/templates/content/actions/set-document-property.ts +78 -1
- package/corpus/templates/content/actions/update-database-item.ts +62 -0
- package/corpus/templates/content/actions/upsert-database-item-by-key.ts +43 -796
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +10 -8
- package/corpus/templates/content/app/hooks/use-content-database.ts +33 -32
- package/corpus/templates/content/changelog/2026-08-10-database-row-actions-now-validate-exact-schemas-and-safe-ret.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +2 -0
- package/corpus/templates/content/server/db/schema.ts +39 -3
- package/corpus/templates/content/server/plugins/db.ts +30 -0
- package/corpus/templates/content/shared/api.ts +75 -2
- package/dist/action.d.ts +22 -0
- package/dist/action.js +27 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +6 -6
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/action-routes.js +10 -2
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1631,6 +1631,11 @@ function DatabaseTable({
|
|
|
1631
1631
|
) {
|
|
1632
1632
|
if (!databaseId) return null;
|
|
1633
1633
|
if (isWorkspaceCatalog) return null;
|
|
1634
|
+
const mutationContract = data?.mutationContract;
|
|
1635
|
+
if (!mutationContract) {
|
|
1636
|
+
toast.error(dbText("failedToCreateRow"));
|
|
1637
|
+
return null;
|
|
1638
|
+
}
|
|
1634
1639
|
const propertyValues = {
|
|
1635
1640
|
...databasePropertyValuesForNewItem(filters, properties, filterMode),
|
|
1636
1641
|
...propertyValueOverrides,
|
|
@@ -1638,8 +1643,10 @@ function DatabaseTable({
|
|
|
1638
1643
|
let response;
|
|
1639
1644
|
try {
|
|
1640
1645
|
response = await addItem.mutateAsync({
|
|
1641
|
-
|
|
1642
|
-
|
|
1646
|
+
target: mutationContract.target,
|
|
1647
|
+
expectedSchemaRevision: mutationContract.schemaRevision,
|
|
1648
|
+
idempotencyKey: crypto.randomUUID(),
|
|
1649
|
+
...(title.trim() ? { title } : {}),
|
|
1643
1650
|
propertyValues:
|
|
1644
1651
|
Object.keys(propertyValues).length > 0 ? propertyValues : undefined,
|
|
1645
1652
|
});
|
|
@@ -1650,12 +1657,7 @@ function DatabaseTable({
|
|
|
1650
1657
|
});
|
|
1651
1658
|
return null;
|
|
1652
1659
|
}
|
|
1653
|
-
const createdItem =
|
|
1654
|
-
databaseId,
|
|
1655
|
-
parentDocument: document,
|
|
1656
|
-
title,
|
|
1657
|
-
propertyValues,
|
|
1658
|
-
});
|
|
1660
|
+
const createdItem = response.createdItem ?? null;
|
|
1659
1661
|
const needsPreview =
|
|
1660
1662
|
!!createdItem &&
|
|
1661
1663
|
databaseCreatedItemNeedsPreview(items, createdItem, options);
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
CancelPreparedBuilderSourceUpdateResponse,
|
|
13
13
|
ChangeContentDatabaseSourceRoleRequest,
|
|
14
14
|
ContentDatabaseResponse,
|
|
15
|
+
ContentDatabaseRowMutationResult,
|
|
15
16
|
ContentDatabaseSourceAttachmentAck,
|
|
16
17
|
ContentDatabaseSourceAttachmentResult,
|
|
17
18
|
ContentDatabaseItemsPageResponse,
|
|
@@ -819,40 +820,40 @@ export function useTrashedContentDatabases() {
|
|
|
819
820
|
|
|
820
821
|
export function useAddDatabaseItem(documentId: string) {
|
|
821
822
|
const queryClient = useQueryClient();
|
|
822
|
-
return useActionMutation<
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
)
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
823
|
+
return useActionMutation<
|
|
824
|
+
ContentDatabaseRowMutationResult,
|
|
825
|
+
AddDatabaseItemRequest
|
|
826
|
+
>("add-database-item", {
|
|
827
|
+
skipActionQueryInvalidation: true,
|
|
828
|
+
onSuccess: (data) => {
|
|
829
|
+
if (data.createdItem) {
|
|
830
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
831
|
+
{
|
|
832
|
+
queryKey: ["action", "get-content-database"],
|
|
833
|
+
predicate: (query) => {
|
|
834
|
+
if (
|
|
835
|
+
!isContentDatabaseQueryForDocument(query.queryKey, documentId)
|
|
836
|
+
) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
const params = query.queryKey[2] as {
|
|
840
|
+
tableQuery?: unknown;
|
|
841
|
+
};
|
|
842
|
+
return params.tableQuery === undefined;
|
|
842
843
|
},
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
}
|
|
844
|
+
},
|
|
845
|
+
(current) =>
|
|
846
|
+
applyOptimisticItemToContentDatabase(current, data.createdItem!),
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
queryClient.invalidateQueries({
|
|
850
|
+
queryKey: contentDatabaseQueryKey(documentId),
|
|
851
|
+
});
|
|
852
|
+
queryClient.invalidateQueries({
|
|
853
|
+
queryKey: ["action", "list-documents"],
|
|
854
|
+
});
|
|
854
855
|
},
|
|
855
|
-
);
|
|
856
|
+
});
|
|
856
857
|
}
|
|
857
858
|
|
|
858
859
|
export function useSubmitContentDatabaseForm(documentId: string) {
|
|
@@ -9,7 +9,7 @@ This generated matrix tracks whether high-value Content UI operations use the sa
|
|
|
9
9
|
| database.lifecycle-and-trash | database | Create, soft-delete, restore, list, and inspect content databases | action-backed | `create-content-database`, `create-inline-content-database`, `delete-content-database`, `get-content-database`, `list-content-databases`, `list-trashed-content-databases`, `restore-content-database` | `app/components/editor/SlashCommandMenu.tsx`, `app/hooks/use-content-database.ts`, `app/hooks/use-documents.ts` | Database pages and database records are created, read, soft-deleted, restored, and listed. | - | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts` | `database-source-scope` | - |
|
|
10
10
|
| database.private-preview-drafts | database | Persist and reconcile a user's private database-page preview draft | action-backed | `get-preview-document-draft`, `update-preview-document-draft` | `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-documents.ts` | A user's private preview draft is read, saved, conflict-checked, or deleted without changing the shared database page until the normal save flow applies it. | These per-user editor-state actions are intentionally hidden from agent tools because preview drafts are a private UI recovery mechanism. | - | P1 | covered | `actions/preview-document-draft.db.test.ts` | - | - |
|
|
11
11
|
| database.properties-and-view-config | database | Configure properties, values, ordering, and saved views | action-backed | `configure-document-property`, `delete-document-property`, `duplicate-document-property`, `get-content-database-personal-view`, `list-document-properties`, `reorder-document-property`, `set-document-property`, `update-content-database-personal-view`, `update-content-database-view` | `app/components/editor/DocumentProperties.tsx`, `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-document-properties.ts` | Property schemas, property values, property order, filters, sorts, grouping, hidden columns, view type, and view settings are stored. | - | - | P0 | covered | `actions/bind-content-database-source-field.db.test.ts`, `actions/content-database-source-actions.test.ts`, `actions/resync-content-database-source.db.test.ts` | `database-source-scope` | - |
|
|
12
|
-
| database.rows | database | Add, duplicate, move, open, edit, and remove database rows | action-backed | `add-database-item`, `upsert-database-item-by-key`, `remove-database-items`, `duplicate-database-items`, `duplicate-database-item`, `migrate-content-database-rows`, `move-database-item`, `set-document-property`
|
|
12
|
+
| database.rows | database | Add, duplicate, move, open, edit, and remove database rows | action-backed | `add-database-item`, `update-database-item`, `upsert-database-item-by-key`, `remove-database-items`, `duplicate-database-items`, `duplicate-database-item`, `migrate-content-database-rows`, `move-database-item`, `set-document-property` | `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx` | Database row memberships and ordering are created, duplicated, moved, edited, and removed without deleting the backing page; bounded migrations atomically update row bodies and properties through the same canonical data model. | - | - | P0 | covered | `actions/database-row-batch-actions.db.test.ts`, `actions/upsert-database-item-by-key.db.test.ts`, `actions/migrate-content-database-rows.db.test.ts`, `parity/__tests__/database-row-batch-reliability.test.ts` | `database-bulk-row-reliability` | - |
|
|
13
13
|
| database.table-query-page | database | Query one constrained page while retaining database metadata | action-backed | `query-content-database-items` | `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-content-database.ts` | - | This UI-only bounded projection is intentionally hidden with agentTool: false; agents use get-content-database for the complete database contract. | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts`, `app/hooks/use-content-database.test.ts` | - | - |
|
|
14
14
|
| editor.agent-assist-prompts | editor | Ask AI from slash generation or comment context | client-assist | - | `app/components/editor/SlashCommandMenu.tsx`, `app/components/editor/CommentsSidebar.tsx` | No direct durable mutation; the prompt asks the agent to use document actions when it decides to write. | - | - | P1 | none | - | - | - |
|
|
15
15
|
| editor.client-formatting-and-insertions | editor | Rich text formatting, selection state, slash block insertion, and copy actions | client-only-ephemeral | - | `app/components/editor/BubbleToolbar.tsx`, `app/components/editor/SlashCommandMenu.tsx`, `app/components/editor/DocumentToolbar.tsx` | - | - | - | P1 | none | - | - | - |
|
|
@@ -345,6 +345,7 @@ export const parityMatrix: ParityRow[] = [
|
|
|
345
345
|
status: "action-backed",
|
|
346
346
|
actions: [
|
|
347
347
|
"add-database-item",
|
|
348
|
+
"update-database-item",
|
|
348
349
|
"upsert-database-item-by-key",
|
|
349
350
|
"remove-database-items",
|
|
350
351
|
"duplicate-database-items",
|
|
@@ -360,6 +361,7 @@ export const parityMatrix: ParityRow[] = [
|
|
|
360
361
|
followUpPR: null,
|
|
361
362
|
coverageRefs: [
|
|
362
363
|
"actions/database-row-batch-actions.db.test.ts",
|
|
364
|
+
"actions/upsert-database-item-by-key.db.test.ts",
|
|
363
365
|
"actions/migrate-content-database-rows.db.test.ts",
|
|
364
366
|
"parity/__tests__/database-row-batch-reliability.test.ts",
|
|
365
367
|
],
|
|
@@ -234,6 +234,7 @@ export const contentDatabases = table(
|
|
|
234
234
|
ownerBlockId: text("owner_block_id"),
|
|
235
235
|
title: text("title").notNull().default("Untitled database"),
|
|
236
236
|
systemRole: text("system_role"),
|
|
237
|
+
naturalKeyPropertyId: text("natural_key_property_id"),
|
|
237
238
|
viewConfigJson: text("view_config_json").notNull().default("{}"),
|
|
238
239
|
filesSystemPropertiesSeeded: integer("files_system_properties_seeded")
|
|
239
240
|
.notNull()
|
|
@@ -287,9 +288,9 @@ export const contentDatabaseItems = table(
|
|
|
287
288
|
],
|
|
288
289
|
);
|
|
289
290
|
|
|
290
|
-
// Opt-in stable-key claims are the durable concurrency fence for
|
|
291
|
-
//
|
|
292
|
-
// property
|
|
291
|
+
// Opt-in stable-key claims are the durable concurrency fence for configured
|
|
292
|
+
// natural-key upserts. Ordinary property editing stays independent until a
|
|
293
|
+
// text property is explicitly selected as the database's natural key.
|
|
293
294
|
export const contentDatabaseItemKeyClaims = table(
|
|
294
295
|
"content_database_item_key_claims",
|
|
295
296
|
{
|
|
@@ -494,6 +495,41 @@ export const contentDatabaseMigrationReceipts = table(
|
|
|
494
495
|
],
|
|
495
496
|
);
|
|
496
497
|
|
|
498
|
+
export const contentDatabaseRowMutationReceipts = table(
|
|
499
|
+
"content_database_row_mutation_receipts",
|
|
500
|
+
{
|
|
501
|
+
id: text("id").primaryKey(),
|
|
502
|
+
ownerEmail: text("owner_email").notNull().default("local@localhost"),
|
|
503
|
+
orgId: text("org_id"),
|
|
504
|
+
spaceId: text("space_id").notNull(),
|
|
505
|
+
databaseId: text("database_id").notNull(),
|
|
506
|
+
databaseDocumentId: text("database_document_id").notNull(),
|
|
507
|
+
operation: text("operation").notNull(),
|
|
508
|
+
itemId: text("item_id").notNull(),
|
|
509
|
+
documentId: text("document_id").notNull(),
|
|
510
|
+
idempotencyKey: text("idempotency_key").notNull(),
|
|
511
|
+
payloadDigest: text("payload_digest").notNull(),
|
|
512
|
+
schemaRevision: text("schema_revision").notNull(),
|
|
513
|
+
preRowRevision: text("pre_row_revision"),
|
|
514
|
+
postRowRevision: text("post_row_revision").notNull(),
|
|
515
|
+
resultJson: text("result_json").notNull().default("{}"),
|
|
516
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
517
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
518
|
+
},
|
|
519
|
+
(receipt) => [
|
|
520
|
+
uniqueIndex(
|
|
521
|
+
"content_database_row_mutation_receipts_database_key_unique",
|
|
522
|
+
).on(receipt.databaseId, receipt.idempotencyKey),
|
|
523
|
+
index("content_database_row_mutation_receipts_owner_database_idx").on(
|
|
524
|
+
receipt.ownerEmail,
|
|
525
|
+
receipt.databaseId,
|
|
526
|
+
),
|
|
527
|
+
index("content_database_row_mutation_receipts_document_idx").on(
|
|
528
|
+
receipt.documentId,
|
|
529
|
+
),
|
|
530
|
+
],
|
|
531
|
+
);
|
|
532
|
+
|
|
497
533
|
export const documentPropertyValues = table("document_property_values", {
|
|
498
534
|
id: text("id").primaryKey(),
|
|
499
535
|
ownerEmail: text("owner_email").notNull().default("local@localhost"),
|
|
@@ -1011,6 +1011,36 @@ export const runContentMigrations = runMigrations(
|
|
|
1011
1011
|
ALTER TABLE document_blocks ALTER COLUMN addressable SET DEFAULT true`,
|
|
1012
1012
|
},
|
|
1013
1013
|
},
|
|
1014
|
+
{
|
|
1015
|
+
version: 84,
|
|
1016
|
+
name: "content-database-row-mutation-contract",
|
|
1017
|
+
sql: `ALTER TABLE content_databases ADD COLUMN IF NOT EXISTS natural_key_property_id TEXT;
|
|
1018
|
+
CREATE TABLE IF NOT EXISTS content_database_row_mutation_receipts (
|
|
1019
|
+
id TEXT PRIMARY KEY,
|
|
1020
|
+
owner_email TEXT NOT NULL DEFAULT 'local@localhost',
|
|
1021
|
+
org_id TEXT,
|
|
1022
|
+
space_id TEXT NOT NULL,
|
|
1023
|
+
database_id TEXT NOT NULL,
|
|
1024
|
+
database_document_id TEXT NOT NULL,
|
|
1025
|
+
operation TEXT NOT NULL,
|
|
1026
|
+
item_id TEXT NOT NULL,
|
|
1027
|
+
document_id TEXT NOT NULL,
|
|
1028
|
+
idempotency_key TEXT NOT NULL,
|
|
1029
|
+
payload_digest TEXT NOT NULL,
|
|
1030
|
+
schema_revision TEXT NOT NULL,
|
|
1031
|
+
pre_row_revision TEXT,
|
|
1032
|
+
post_row_revision TEXT NOT NULL,
|
|
1033
|
+
result_json TEXT NOT NULL DEFAULT '{}',
|
|
1034
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
1035
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
1036
|
+
);
|
|
1037
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_database_row_mutation_receipts_database_key_unique
|
|
1038
|
+
ON content_database_row_mutation_receipts (database_id, idempotency_key);
|
|
1039
|
+
CREATE INDEX IF NOT EXISTS content_database_row_mutation_receipts_owner_database_idx
|
|
1040
|
+
ON content_database_row_mutation_receipts (owner_email, database_id);
|
|
1041
|
+
CREATE INDEX IF NOT EXISTS content_database_row_mutation_receipts_document_idx
|
|
1042
|
+
ON content_database_row_mutation_receipts (document_id)`,
|
|
1043
|
+
},
|
|
1014
1044
|
],
|
|
1015
1045
|
{ table: "content_migrations" },
|
|
1016
1046
|
);
|
|
@@ -225,6 +225,7 @@ export interface ConfigureDocumentPropertyRequest {
|
|
|
225
225
|
description?: string;
|
|
226
226
|
visibility?: DocumentPropertyVisibility;
|
|
227
227
|
options?: DocumentPropertyOptions;
|
|
228
|
+
naturalKey?: boolean;
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
export interface SetDocumentPropertyRequest {
|
|
@@ -258,8 +259,10 @@ export interface ReorderDocumentPropertyRequest {
|
|
|
258
259
|
export interface ContentDatabase {
|
|
259
260
|
id: string;
|
|
260
261
|
documentId: string;
|
|
262
|
+
spaceId?: string | null;
|
|
261
263
|
title: string;
|
|
262
264
|
systemRole?: string | null;
|
|
265
|
+
naturalKeyPropertyId?: string | null;
|
|
263
266
|
description?: string;
|
|
264
267
|
viewConfig: ContentDatabaseViewConfig;
|
|
265
268
|
createdAt: string;
|
|
@@ -469,6 +472,62 @@ export interface ContentDatabaseItem {
|
|
|
469
472
|
// a secondary source contributes on top of it. Absent for non-federated rows.
|
|
470
473
|
canonicalKey?: string | null;
|
|
471
474
|
sourceOverlays?: ContentDatabaseSourceOverlay[];
|
|
475
|
+
rowRevision?: string;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export interface ContentDatabaseMutationTarget {
|
|
479
|
+
authorityScope:
|
|
480
|
+
| { kind: "personal"; id: string }
|
|
481
|
+
| { kind: "organization"; id: string };
|
|
482
|
+
spaceId: string;
|
|
483
|
+
databaseId: string;
|
|
484
|
+
databaseDocumentId: string;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export interface ContentDatabaseMutationContract {
|
|
488
|
+
target: ContentDatabaseMutationTarget;
|
|
489
|
+
schemaRevision: string;
|
|
490
|
+
naturalKeyPropertyId: string | null;
|
|
491
|
+
properties: Array<{
|
|
492
|
+
id: string;
|
|
493
|
+
name: string;
|
|
494
|
+
type: DocumentPropertyType;
|
|
495
|
+
writable: boolean;
|
|
496
|
+
sourceManaged: boolean;
|
|
497
|
+
acceptedShape: string | null;
|
|
498
|
+
options: DocumentPropertyOptions;
|
|
499
|
+
}>;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export interface ContentDatabaseRowMutationReceipt {
|
|
503
|
+
receiptId: string;
|
|
504
|
+
operation: "create" | "update" | "upsert";
|
|
505
|
+
outcome: "created" | "updated" | "unchanged";
|
|
506
|
+
target: ContentDatabaseMutationTarget;
|
|
507
|
+
schemaRevision: string;
|
|
508
|
+
row: {
|
|
509
|
+
itemId: string;
|
|
510
|
+
documentId: string;
|
|
511
|
+
urlPath: string;
|
|
512
|
+
rowRevision: string;
|
|
513
|
+
};
|
|
514
|
+
affected: { title: boolean; propertyIds: string[] };
|
|
515
|
+
idempotency: {
|
|
516
|
+
key: string;
|
|
517
|
+
result: "applied" | "replayed";
|
|
518
|
+
payloadDigest: string;
|
|
519
|
+
};
|
|
520
|
+
revisions: { before: string | null; after: string };
|
|
521
|
+
readback: {
|
|
522
|
+
verified: true;
|
|
523
|
+
title: string;
|
|
524
|
+
propertyValues: Record<string, DocumentPropertyValue>;
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export interface ContentDatabaseRowMutationResult {
|
|
529
|
+
receipt: ContentDatabaseRowMutationReceipt;
|
|
530
|
+
createdItem?: ContentDatabaseItem;
|
|
472
531
|
}
|
|
473
532
|
|
|
474
533
|
// A secondary source's read-only contribution to a federated row, matched on the
|
|
@@ -828,6 +887,7 @@ export interface ContentDatabaseResponse {
|
|
|
828
887
|
removedCount?: number;
|
|
829
888
|
timings?: BuilderActionTiming[];
|
|
830
889
|
tableQueryMode?: "server" | "client-required";
|
|
890
|
+
mutationContract?: ContentDatabaseMutationContract;
|
|
831
891
|
/** Client-only optimistic state while real provider rows are being attached. */
|
|
832
892
|
attachPreview?: {
|
|
833
893
|
sourceTable: string;
|
|
@@ -892,9 +952,22 @@ export interface CreateInlineDatabaseResponse {
|
|
|
892
952
|
}
|
|
893
953
|
|
|
894
954
|
export interface AddDatabaseItemRequest {
|
|
895
|
-
|
|
955
|
+
target: ContentDatabaseMutationTarget;
|
|
956
|
+
expectedSchemaRevision: string;
|
|
957
|
+
idempotencyKey: string;
|
|
896
958
|
title?: string;
|
|
897
|
-
propertyValues?: Record<string,
|
|
959
|
+
propertyValues?: Record<string, unknown>;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
export interface UpdateDatabaseItemRequest extends AddDatabaseItemRequest {
|
|
963
|
+
itemId: string;
|
|
964
|
+
documentId: string;
|
|
965
|
+
expectedRowRevision: string;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
export interface UpsertDatabaseItemByKeyRequest extends AddDatabaseItemRequest {
|
|
969
|
+
keyValue: string;
|
|
970
|
+
expectedRowRevision: string | null;
|
|
898
971
|
}
|
|
899
972
|
|
|
900
973
|
export interface SubmitContentDatabaseFormRequest {
|
package/dist/action.d.ts
CHANGED
|
@@ -135,6 +135,28 @@ export interface AgentActionStopOptions {
|
|
|
135
135
|
/** Optional short tool-result text. Defaults to the user-facing message. */
|
|
136
136
|
toolResult?: string;
|
|
137
137
|
}
|
|
138
|
+
export interface ActionContractErrorOptions {
|
|
139
|
+
/** Stable machine-readable code safe to expose on every action transport. */
|
|
140
|
+
errorCode: string;
|
|
141
|
+
/** Safe structured context for callers. Never include secrets or raw driver errors. */
|
|
142
|
+
details?: Record<string, unknown>;
|
|
143
|
+
/** HTTP status for the action route. Contract conflicts normally use 409. */
|
|
144
|
+
statusCode?: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* A deterministic, caller-correctable action contract failure.
|
|
148
|
+
*
|
|
149
|
+
* Unlike an ordinary Error, its code and explicitly safe details survive the
|
|
150
|
+
* framework HTTP transport. Internal failures remain generic 500 responses.
|
|
151
|
+
*/
|
|
152
|
+
export declare class ActionContractError extends Error {
|
|
153
|
+
readonly actionContractError = true;
|
|
154
|
+
readonly errorCode: string;
|
|
155
|
+
readonly details?: Record<string, unknown>;
|
|
156
|
+
readonly statusCode: number;
|
|
157
|
+
constructor(message: string, options: ActionContractErrorOptions);
|
|
158
|
+
}
|
|
159
|
+
export declare function isActionContractError(error: unknown): error is ActionContractError;
|
|
138
160
|
/**
|
|
139
161
|
* Throw from an action when the agent should stop the current turn instead of
|
|
140
162
|
* feeding the failure back to the model for another retry.
|
package/dist/action.js
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { normalizeActionChatUIConfig, } from "./action-ui.js";
|
|
2
2
|
import { normalizeAuditConfig, resolveAuditAttach } from "./audit/config.js";
|
|
3
|
+
/**
|
|
4
|
+
* A deterministic, caller-correctable action contract failure.
|
|
5
|
+
*
|
|
6
|
+
* Unlike an ordinary Error, its code and explicitly safe details survive the
|
|
7
|
+
* framework HTTP transport. Internal failures remain generic 500 responses.
|
|
8
|
+
*/
|
|
9
|
+
export class ActionContractError extends Error {
|
|
10
|
+
actionContractError = true;
|
|
11
|
+
errorCode;
|
|
12
|
+
details;
|
|
13
|
+
statusCode;
|
|
14
|
+
constructor(message, options) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "ActionContractError";
|
|
17
|
+
this.errorCode = options.errorCode;
|
|
18
|
+
this.details = options.details;
|
|
19
|
+
this.statusCode = options.statusCode ?? 409;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function isActionContractError(error) {
|
|
23
|
+
return (error instanceof ActionContractError ||
|
|
24
|
+
(!!error &&
|
|
25
|
+
typeof error === "object" &&
|
|
26
|
+
error.actionContractError ===
|
|
27
|
+
true &&
|
|
28
|
+
typeof error.errorCode === "string"));
|
|
29
|
+
}
|
|
3
30
|
/**
|
|
4
31
|
* Throw from an action when the agent should stop the current turn instead of
|
|
5
32
|
* feeding the failure back to the model for another retry.
|
|
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
62
62
|
error: string;
|
|
63
63
|
states?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
states: {
|
|
66
67
|
clientId: number;
|
|
67
68
|
state: string;
|
|
68
69
|
}[];
|
|
69
|
-
error?: undefined;
|
|
70
70
|
}>>;
|
|
71
71
|
/**
|
|
72
72
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
77
77
|
error: string;
|
|
78
78
|
users?: undefined;
|
|
79
79
|
} | {
|
|
80
|
+
error?: undefined;
|
|
80
81
|
users: {
|
|
81
82
|
clientId: number;
|
|
82
83
|
lastSeen: number;
|
|
83
84
|
}[];
|
|
84
|
-
error?: undefined;
|
|
85
85
|
}>>;
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from "./config.js";
|
|
|
2
2
|
export { addContextToAgentChat, appendAgentChatContextToMessage, clearAgentChatContext, formatAgentChatContextItemsForPrompt, listAgentChatContext, refreshAgentChatContext, removeAgentChatContextItem, sendToAgentChat, sendToAgentChatAndConfirm, setAgentChatContextItem, setContextToAgentChat, isEmbedMcpChatBridgeActive, useAgentChatContext, useAgentChatGenerating, useDevMode, useSendToAgentChat, AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES, getMcpAppHostContext, openMcpAppHostLink, requestMcpAppDisplayMode, sendMcpAppHostMessage, updateMcpAppModelContext, useMcpAppHostContext, CodeRequiredDialog, AgentNativeI18nProvider, LanguagePicker, getLocaleInitScript, localeDirection, normalizeLocaleCode, normalizeLocalePreference, normalizeLocalizationPreference, resolveLocaleFromCandidates, resolveLocaleFromPreference, useFormatters, useLocale, useT, DEFAULT_LOCALE, LOCALE_HYDRATION_GLOBAL, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, useDbSync, useFileWatcher, useSession, cn, ApiKeySettings, type AgentChatContextItem, type AgentChatContextMessage, type AgentChatContextMutationOptions, type AgentChatContextRemoveOptions, type AgentChatContextSetOptions, type AgentChatContextState, type AgentChatMessage, type AgentNativeMcpAppHostMessageType, type McpAppDisplayMode, type McpAppHostChatMessage, type McpAppHostCapabilities, type McpAppHostContext, type McpAppHostContextSnapshot, type McpAppModelContextContentPart, type McpAppModelContextUpdate, type CodeRequiredDialogProps, type AuthSession, type UseAgentChatContextResult, type AgentNativeI18nCatalog, type AgentNativeI18nProviderProps, type LocaleCode, type LocaleHydrationPayload, type LocaleMessages, type LocaleMetadata, type LocalePreference, type LocalizationPreference, } from "./client/index.js";
|
|
3
3
|
export { agentChat } from "./shared/index.js";
|
|
4
4
|
export { parseArgs, camelCaseArgs } from "./scripts/parse-args.js";
|
|
5
|
-
export { defineAction, AgentActionStopError, isAgentActionStopError, type ActionHttpConfig, type AgentActionStopOptions, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
|
|
5
|
+
export { defineAction, ActionContractError, isActionContractError, type ActionContractErrorOptions, AgentActionStopError, isAgentActionStopError, type ActionHttpConfig, type AgentActionStopOptions, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
|
|
6
6
|
export { normalizeUserProfileName, USER_PROFILE_SETTING_KEY, type UserProfile, } from "./user-profile/index.js";
|
|
7
7
|
export { ACTION_CHAT_UI_DATA_CHART_RENDERER, ACTION_CHAT_UI_DATA_INSIGHTS_RENDERER, ACTION_CHAT_UI_DATA_TABLE_RENDERER, ACTION_CHAT_UI_DATA_WIDGET_RENDERER, ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER, ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER, type ActionChatUIConfig, } from "./action-ui.js";
|
|
8
8
|
export { DATA_CHART_WIDGET, DATA_INSIGHTS_WIDGET, DATA_TABLE_WIDGET, createDataChartWidgetResult, createDataInsightsWidgetResult, createDataTableWidgetResult, dataChartWidgetResultSchema, dataChartWidgetSchema, dataInsightsWidgetResultSchema, dataTableWidgetResultSchema, dataTableWidgetSchema, dataWidgetResultSchema, isDataChartWidget, isDataTableWidget, isDataWidgetResult, normalizeDataWidgetKind, normalizeDataWidgetResult, type DataChartSeriesDefinition, type DataChartWidget, type DataChartWidgetResult, type DataChartWidgetResultInput, type DataInsightsWidgetResult, type DataInsightsWidgetResultInput, type DataTableColumn, type DataTableWidget, type DataTableWidgetResult, type DataTableWidgetResultInput, type DataWidgetDisplay, type DataWidgetKind, type DataWidgetResult, type DataWidgetResultMetadata, } from "./data-widgets/index.js";
|
package/dist/index.browser.js
CHANGED
|
@@ -9,7 +9,7 @@ export { agentChat } from "./shared/index.js";
|
|
|
9
9
|
// Pure utilities (no Node.js deps — safe for browser and SSR)
|
|
10
10
|
export { parseArgs, camelCaseArgs } from "./scripts/parse-args.js";
|
|
11
11
|
// defineAction — used by template actions, no Node.js deps
|
|
12
|
-
export { defineAction, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
|
|
12
|
+
export { defineAction, ActionContractError, isActionContractError, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
|
|
13
13
|
export { normalizeUserProfileName, USER_PROFILE_SETTING_KEY, } from "./user-profile/index.js";
|
|
14
14
|
export { ACTION_CHAT_UI_DATA_CHART_RENDERER, ACTION_CHAT_UI_DATA_INSIGHTS_RENDERER, ACTION_CHAT_UI_DATA_TABLE_RENDERER, ACTION_CHAT_UI_DATA_WIDGET_RENDERER, ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER, ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER, } from "./action-ui.js";
|
|
15
15
|
export { DATA_CHART_WIDGET, DATA_INSIGHTS_WIDGET, DATA_TABLE_WIDGET, createDataChartWidgetResult, createDataInsightsWidgetResult, createDataTableWidgetResult, dataChartWidgetResultSchema, dataChartWidgetSchema, dataInsightsWidgetResultSchema, dataTableWidgetResultSchema, dataTableWidgetSchema, dataWidgetResultSchema, isDataChartWidget, isDataTableWidget, isDataWidgetResult, normalizeDataWidgetKind, normalizeDataWidgetResult, } from "./data-widgets/index.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./config.js";
|
|
2
2
|
export { createProductionAgentHandler, type ActionEntry, type ScriptEntry, type ProductionAgentOptions, type ActionTool, type ScriptTool, type AgentMessage, type AgentChatRequest, type AgentChatEvent, type AgentChatAttachment, DEFAULT_MODEL, TripWire, type Processor, type ProcessorState, type ProcessorAbort, } from "./agent/index.js";
|
|
3
|
-
export { defineAction, AgentActionStopError, isAgentActionStopError, type ActionDefinition, type ActionHttpConfig, type AgentActionStopOptions, type PublicAgentActionConfig, type ActionDeepLink, type ActionLinkBuilder, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
|
|
3
|
+
export { defineAction, ActionContractError, isActionContractError, type ActionContractErrorOptions, AgentActionStopError, isAgentActionStopError, type ActionDefinition, type ActionHttpConfig, type AgentActionStopOptions, type PublicAgentActionConfig, type ActionDeepLink, type ActionLinkBuilder, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
|
|
4
4
|
export * from "./user-profile/index.js";
|
|
5
5
|
export { embedApp, MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, type EmbedAppOptions, } from "./mcp/embed-app.js";
|
|
6
6
|
export { embedRoute, type EmbedRouteContext, type EmbedRouteOptions, type EmbedRoutePathBuilder, type EmbedRouteResult, } from "./mcp/embed-route.js";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export * from "./config.js";
|
|
|
5
5
|
export { createProductionAgentHandler, DEFAULT_MODEL,
|
|
6
6
|
// In-loop processors (observers/guardrails for runAgentLoop)
|
|
7
7
|
TripWire, } from "./agent/index.js";
|
|
8
|
-
export { defineAction, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
|
|
8
|
+
export { defineAction, ActionContractError, isActionContractError, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
|
|
9
9
|
export * from "./user-profile/index.js";
|
|
10
10
|
export { embedApp, MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, } from "./mcp/embed-app.js";
|
|
11
11
|
export { embedRoute, } from "./mcp/embed-route.js";
|
|
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
41
41
|
thumbsUpRate: number;
|
|
42
42
|
avgEvalScore: number;
|
|
43
43
|
} | {
|
|
44
|
+
ok?: undefined;
|
|
45
|
+
error?: undefined;
|
|
44
46
|
summary: import("./types.js").TraceSummary;
|
|
45
47
|
spans: import("./types.js").TraceSpan[];
|
|
46
48
|
id?: undefined;
|
|
47
|
-
error?: undefined;
|
|
48
|
-
ok?: undefined;
|
|
49
49
|
} | {
|
|
50
|
+
ok?: undefined;
|
|
51
|
+
error?: undefined;
|
|
50
52
|
summary?: undefined;
|
|
51
53
|
spans?: undefined;
|
|
52
54
|
id: string;
|
|
53
|
-
error?: undefined;
|
|
54
|
-
ok?: undefined;
|
|
55
55
|
} | {
|
|
56
|
+
ok?: undefined;
|
|
56
57
|
summary?: undefined;
|
|
57
58
|
spans?: undefined;
|
|
58
59
|
id?: undefined;
|
|
59
60
|
error: any;
|
|
60
|
-
ok?: undefined;
|
|
61
61
|
} | {
|
|
62
|
+
error?: undefined;
|
|
62
63
|
summary?: undefined;
|
|
63
64
|
spans?: undefined;
|
|
64
65
|
id?: undefined;
|
|
65
|
-
error?: undefined;
|
|
66
66
|
ok: boolean;
|
|
67
67
|
}>>;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -34,16 +34,16 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
|
|
|
34
34
|
/** POST /_agent-native/secrets/:key — write a secret. */
|
|
35
35
|
export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
36
36
|
error: string;
|
|
37
|
-
status?: undefined;
|
|
38
37
|
ok?: undefined;
|
|
38
|
+
status?: undefined;
|
|
39
39
|
} | {
|
|
40
40
|
ok: boolean;
|
|
41
41
|
status: string;
|
|
42
42
|
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
+
ok?: undefined;
|
|
44
45
|
error: string;
|
|
45
46
|
removed?: undefined;
|
|
46
|
-
ok?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
ok: boolean;
|
|
49
49
|
removed: boolean;
|
|
@@ -54,9 +54,9 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
54
54
|
* or the current stored value without changing anything.
|
|
55
55
|
*/
|
|
56
56
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
57
|
+
ok?: undefined;
|
|
57
58
|
error: string;
|
|
58
59
|
note?: undefined;
|
|
59
|
-
ok?: undefined;
|
|
60
60
|
} | {
|
|
61
61
|
ok: boolean;
|
|
62
62
|
note?: undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, getRequestURL, } from "h3";
|
|
2
2
|
import { verifyA2ATokenWithClaims } from "../a2a-claims.js";
|
|
3
|
-
import { isAgentActionStopError } from "../action.js";
|
|
3
|
+
import { isActionContractError, isAgentActionStopError } from "../action.js";
|
|
4
4
|
import { declaresFeatureFlagDelegation } from "../feature-flags/a2a-action-route.js";
|
|
5
5
|
import { resolveOrgByDomain, resolveOrgIdForEmail } from "../org/context.js";
|
|
6
6
|
import { readBody } from "../server/h3-helpers.js";
|
|
@@ -507,7 +507,15 @@ export function mountActionRoutes(nitroApp, actions, options) {
|
|
|
507
507
|
isAgentActionStopError(err) ||
|
|
508
508
|
(explicitStatus !== undefined && explicitStatus < 500);
|
|
509
509
|
if (isUserFacing) {
|
|
510
|
-
return
|
|
510
|
+
return isActionContractError(err)
|
|
511
|
+
? {
|
|
512
|
+
error: msg,
|
|
513
|
+
errorCode: err.errorCode,
|
|
514
|
+
...(err.details === undefined
|
|
515
|
+
? {}
|
|
516
|
+
: { details: err.details }),
|
|
517
|
+
}
|
|
518
|
+
: { error: msg };
|
|
511
519
|
}
|
|
512
520
|
const requestId = getHttpRequestTelemetryId(event);
|
|
513
521
|
const captureId = captureError(err, {
|