@agent-native/core 0.133.2 → 0.133.3

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.
Files changed (58) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +6 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/use-action.ts +6 -0
  5. package/corpus/templates/content/actions/_batch-utils.ts +33 -0
  6. package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -81
  7. package/corpus/templates/content/actions/_content-files.ts +31 -21
  8. package/corpus/templates/content/actions/_database-source-utils.ts +653 -155
  9. package/corpus/templates/content/actions/_database-utils.ts +535 -41
  10. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +291 -240
  11. package/corpus/templates/content/actions/add-database-item.ts +15 -1
  12. package/corpus/templates/content/actions/attach-content-database-source.ts +156 -58
  13. package/corpus/templates/content/actions/bind-content-database-source-field.ts +2 -2
  14. package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +4 -1
  15. package/corpus/templates/content/actions/delete-database-items.ts +8 -2
  16. package/corpus/templates/content/actions/disconnect-content-database-source.ts +2 -2
  17. package/corpus/templates/content/actions/duplicate-database-item.ts +15 -1
  18. package/corpus/templates/content/actions/duplicate-database-items.ts +19 -1
  19. package/corpus/templates/content/actions/execute-builder-source-execution.ts +2 -1
  20. package/corpus/templates/content/actions/get-content-database.ts +12 -64
  21. package/corpus/templates/content/actions/move-database-item.ts +4 -1
  22. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
  23. package/corpus/templates/content/actions/prepare-builder-source-review.ts +4 -8
  24. package/corpus/templates/content/actions/preview-content-database-source-attach.ts +92 -0
  25. package/corpus/templates/content/actions/process-builder-body-hydration.ts +2 -1
  26. package/corpus/templates/content/actions/query-content-database-items.ts +64 -0
  27. package/corpus/templates/content/actions/refresh-content-database-source.ts +7 -0
  28. package/corpus/templates/content/actions/review-content-database-source-change-set.ts +1 -1
  29. package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +1 -1
  30. package/corpus/templates/content/actions/stage-builder-revision.ts +1 -1
  31. package/corpus/templates/content/actions/update-content-database-personal-view.ts +29 -3
  32. package/corpus/templates/content/actions/update-content-database-view.ts +1 -1
  33. package/corpus/templates/content/actions/validate-builder-source-execution.ts +1 -1
  34. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +3 -22
  35. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +267 -105
  36. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +82 -1
  37. package/corpus/templates/content/app/hooks/use-content-database.ts +285 -24
  38. package/corpus/templates/content/app/hooks/use-document-properties.ts +7 -6
  39. package/corpus/templates/content/app/i18n-data.ts +10 -0
  40. package/corpus/templates/content/changelog/2026-07-29-large-databases-keep-useful-rows-visible.md +6 -0
  41. package/corpus/templates/content/changelog/2026-07-30-builder-source-columns-now-appear-immediately-when-connected.md +6 -0
  42. package/corpus/templates/content/changelog/2026-07-30-large-builder-backed-tables-show-useful-rows-sooner-and-fini.md +6 -0
  43. package/corpus/templates/content/changelog/2026-08-01-large-builder-databases-now-show-rows-immediately-and-finish.md +6 -0
  44. package/corpus/templates/content/parity/matrix.md +2 -1
  45. package/corpus/templates/content/parity/matrix.ts +25 -0
  46. package/corpus/templates/content/shared/api.ts +54 -4
  47. package/corpus/templates/content/shared/database-query.ts +359 -0
  48. package/dist/client/use-action.d.ts.map +1 -1
  49. package/dist/client/use-action.js +6 -0
  50. package/dist/client/use-action.js.map +1 -1
  51. package/dist/notifications/routes.d.ts +1 -1
  52. package/dist/observability/routes.d.ts +3 -3
  53. package/dist/progress/routes.d.ts +1 -1
  54. package/dist/resources/handlers.d.ts +1 -1
  55. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  56. package/dist/server/transcribe-voice.d.ts +1 -1
  57. package/package.json +1 -1
  58. package/src/client/use-action.ts +6 -0
@@ -0,0 +1,92 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { assertAccess } from "@agent-native/core/sharing";
3
+ import { z } from "zod";
4
+
5
+ import type {
6
+ BuilderCmsAttachPreviewResponse,
7
+ ContentDatabaseItem,
8
+ } from "../shared/api.js";
9
+ import { readBuilderCmsContentEntries } from "./_builder-cms-read-client.js";
10
+ import {
11
+ builderCmsImportIds,
12
+ resolveDatabaseForSourceMutation,
13
+ } from "./_database-source-utils.js";
14
+ import { getContentDatabaseResponse } from "./_database-utils.js";
15
+
16
+ export default defineAction({
17
+ description:
18
+ "Preview the first projected Builder rows for a database source attachment without writing local or provider data.",
19
+ schema: z.object({
20
+ databaseId: z.string().optional(),
21
+ documentId: z.string().optional(),
22
+ sourceTable: z.string().min(1).max(500),
23
+ fieldPaths: z.array(z.string().max(500)).max(200).optional(),
24
+ }),
25
+ http: { method: "GET" },
26
+ readOnly: true,
27
+ run: async (args): Promise<BuilderCmsAttachPreviewResponse> => {
28
+ const database = await resolveDatabaseForSourceMutation(args);
29
+ if (!database) throw new Error("Database not found.");
30
+ await assertAccess("document", database.documentId, "editor");
31
+
32
+ const [read, base] = await Promise.all([
33
+ readBuilderCmsContentEntries({
34
+ model: args.sourceTable,
35
+ fieldPaths: args.fieldPaths,
36
+ allowCached: true,
37
+ maxPages: 1,
38
+ }),
39
+ getContentDatabaseResponse(database.id, { limit: 100, offset: 0 }),
40
+ ]);
41
+ if (read.state !== "live") {
42
+ throw new Error(
43
+ read.message ?? "Builder rows are not available for preview.",
44
+ );
45
+ }
46
+
47
+ const items: ContentDatabaseItem[] = read.entries.map((entry, index) => {
48
+ const ids = builderCmsImportIds({
49
+ ownerEmail: database.ownerEmail,
50
+ databaseId: database.id,
51
+ sourceTable: args.sourceTable,
52
+ entryId: entry.id,
53
+ });
54
+ return {
55
+ id: ids.itemId,
56
+ databaseId: database.id,
57
+ document: {
58
+ id: ids.documentId,
59
+ parentId: database.documentId,
60
+ title: entry.title.trim() || entry.id,
61
+ content: "",
62
+ icon: null,
63
+ position: index,
64
+ isFavorite: false,
65
+ hideFromSearch: false,
66
+ accessRole: "viewer",
67
+ canEdit: false,
68
+ canManage: false,
69
+ createdAt: entry.updatedAt,
70
+ updatedAt: entry.updatedAt,
71
+ },
72
+ position: index,
73
+ properties: [],
74
+ bodyHydration: {
75
+ status: "pending",
76
+ attemptedAt: null,
77
+ error: null,
78
+ version: null,
79
+ },
80
+ };
81
+ });
82
+ return {
83
+ databaseId: database.id,
84
+ documentId: database.documentId,
85
+ sourceTable: args.sourceTable,
86
+ base,
87
+ items,
88
+ fetchedAt: read.fetchedAt,
89
+ hasMore: read.progress.hasMore,
90
+ };
91
+ },
92
+ });
@@ -15,7 +15,7 @@ export default defineAction({
15
15
  schema: z.object({
16
16
  sourceId: z.string(),
17
17
  documentId: z.string().optional(),
18
- limit: z.number().int().positive().max(50).optional(),
18
+ limit: z.number().int().positive().max(600).optional(),
19
19
  }),
20
20
  agentTool: false,
21
21
  run: async (
@@ -42,6 +42,7 @@ export default defineAction({
42
42
  sourceId: args.sourceId,
43
43
  documentId: args.documentId,
44
44
  limit: args.limit,
45
+ preloadBodies: !args.documentId,
45
46
  });
46
47
  },
47
48
  });
@@ -0,0 +1,64 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+
4
+ import type {
5
+ ContentDatabaseItemsPageResponse,
6
+ ContentDatabaseUnavailableResponse,
7
+ } from "../shared/api.js";
8
+ import {
9
+ CONTENT_DATABASE_MAX_READ_LIMIT,
10
+ contentDatabaseTableQuerySchema,
11
+ getContentDatabasePageResponse,
12
+ resolveContentDatabaseRead,
13
+ } from "./_database-utils.js";
14
+
15
+ export default defineAction({
16
+ description:
17
+ "Query one ordered and filtered page of a content database without reopening its metadata.",
18
+ schema: z.object({
19
+ databaseId: z.string().optional().describe("Database ID"),
20
+ documentId: z.string().optional().describe("Database document/page ID"),
21
+ limit: z.coerce
22
+ .number()
23
+ .int()
24
+ .min(1)
25
+ .max(CONTENT_DATABASE_MAX_READ_LIMIT)
26
+ .optional(),
27
+ offset: z.coerce.number().int().min(0).optional(),
28
+ tableQuery: contentDatabaseTableQuerySchema,
29
+ }),
30
+ http: { method: "GET" },
31
+ readOnly: true,
32
+ agentTool: false,
33
+ run: async ({
34
+ databaseId,
35
+ documentId,
36
+ limit,
37
+ offset,
38
+ tableQuery,
39
+ }): Promise<
40
+ ContentDatabaseItemsPageResponse | ContentDatabaseUnavailableResponse
41
+ > => {
42
+ const resolved = await resolveContentDatabaseRead({
43
+ databaseId,
44
+ documentId,
45
+ });
46
+ if (!resolved.available) return resolved;
47
+
48
+ const page = await getContentDatabasePageResponse(resolved.database.id, {
49
+ // This action is the bounded table replacement path; unlike the legacy
50
+ // database response, an omitted limit must not turn it into a full read.
51
+ limit: limit ?? 100,
52
+ offset,
53
+ tableQuery,
54
+ database: resolved.database,
55
+ });
56
+ return {
57
+ items: page.items,
58
+ source: page.source,
59
+ sources: page.sources,
60
+ pagination: page.pagination,
61
+ tableQueryMode: page.tableQueryMode,
62
+ };
63
+ },
64
+ });
@@ -35,6 +35,12 @@ export default defineAction({
35
35
  .describe(
36
36
  "For paginated Builder CMS or Notion sources, read a bounded multi-page snapshot in this refresh.",
37
37
  ),
38
+ finishBuilderPagination: z
39
+ .boolean()
40
+ .optional()
41
+ .describe(
42
+ "Internal Builder continuation mode. Read every remaining page from the persisted continuation offset.",
43
+ ),
38
44
  expectedBuilderContinuationOffset: z
39
45
  .number()
40
46
  .int()
@@ -75,6 +81,7 @@ export default defineAction({
75
81
  source: claimedSource.source,
76
82
  now,
77
83
  runFullRefresh: args.fullRefresh === true,
84
+ finishPagination: args.finishBuilderPagination === true,
78
85
  refreshClaimId: claimedSource.claimId,
79
86
  }).catch(async (error: unknown) => {
80
87
  await releaseBuilderCmsSourceRefreshClaim({
@@ -116,6 +116,6 @@ export default defineAction({
116
116
  .set({ updatedAt: now })
117
117
  .where(eq(schema.contentDatabaseSources.id, source.id));
118
118
 
119
- return getContentDatabaseResponse(database.id);
119
+ return getContentDatabaseResponse(database.id, { limit: 100, offset: 0 });
120
120
  },
121
121
  });
@@ -121,6 +121,6 @@ export default defineAction({
121
121
  "Builder source settings changed repeatedly while saving write mode.",
122
122
  });
123
123
 
124
- return getContentDatabaseResponse(database.id);
124
+ return getContentDatabaseResponse(database.id, { limit: 100, offset: 0 });
125
125
  },
126
126
  });
@@ -114,6 +114,6 @@ export default defineAction({
114
114
  .set({ updatedAt: now })
115
115
  .where(eq(schema.contentDatabaseSources.id, source.id));
116
116
 
117
- return getContentDatabaseResponse(database.id);
117
+ return getContentDatabaseResponse(database.id, { limit: 100, offset: 0 });
118
118
  },
119
119
  });
@@ -1,14 +1,26 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { deleteUserSetting, putUserSetting } from "@agent-native/core/settings";
3
+ import { and, eq, inArray } from "drizzle-orm";
3
4
  import { z } from "zod";
4
5
 
6
+ import { getDb, schema } from "../server/db/index.js";
7
+ import { bulkChunkSizeForColumnCount, chunks } from "./_batch-utils.js";
5
8
  import {
6
9
  assertContentDatabaseViewerAccess,
7
10
  normalizePersonalDatabaseViewOverrides,
8
11
  personalDatabaseViewSettingKey,
9
12
  personalViewOverridesSchema,
10
13
  } from "./_content-database-personal-view.js";
11
- import { getContentDatabaseResponse } from "./_database-utils.js";
14
+
15
+ export function personalSidebarOrderItemIds(
16
+ overrides: z.infer<typeof personalViewOverridesSchema>,
17
+ ) {
18
+ return [
19
+ ...new Set(
20
+ overrides.views.flatMap((view) => view.sidebarOrder?.itemIds ?? []),
21
+ ),
22
+ ];
23
+ }
12
24
 
13
25
  export default defineAction({
14
26
  description:
@@ -23,10 +35,24 @@ export default defineAction({
23
35
 
24
36
  const key = personalDatabaseViewSettingKey(databaseId);
25
37
  if (overrides) {
26
- const visibleDatabase = await getContentDatabaseResponse(databaseId);
38
+ const requestedItemIds = personalSidebarOrderItemIds(overrides);
39
+ const validItemIds = new Set<string>();
40
+ const itemIdChunkSize = Math.max(1, bulkChunkSizeForColumnCount(1) - 1);
41
+ for (const itemIds of chunks(requestedItemIds, itemIdChunkSize)) {
42
+ const rows = await getDb()
43
+ .select({ id: schema.contentDatabaseItems.id })
44
+ .from(schema.contentDatabaseItems)
45
+ .where(
46
+ and(
47
+ eq(schema.contentDatabaseItems.databaseId, databaseId),
48
+ inArray(schema.contentDatabaseItems.id, itemIds),
49
+ ),
50
+ );
51
+ for (const row of rows) validItemIds.add(row.id);
52
+ }
27
53
  overrides = normalizePersonalDatabaseViewOverrides(
28
54
  overrides,
29
- new Set(visibleDatabase.items.map((item) => item.id)),
55
+ validItemIds,
30
56
  );
31
57
  await putUserSetting(ctx.userEmail, key, overrides);
32
58
  } else {
@@ -136,6 +136,6 @@ export default defineAction({
136
136
 
137
137
  await writeAppState("refresh-signal", { ts: Date.now() });
138
138
 
139
- return getContentDatabaseResponse(databaseId);
139
+ return getContentDatabaseResponse(databaseId, { limit: 100, offset: 0 });
140
140
  },
141
141
  });
@@ -153,6 +153,6 @@ export default defineAction({
153
153
  .set({ updatedAt: now })
154
154
  .where(eq(schema.contentDatabaseSources.id, source.id));
155
155
 
156
- return getContentDatabaseResponse(database.id);
156
+ return getContentDatabaseResponse(database.id, { limit: 100, offset: 0 });
157
157
  },
158
158
  });
@@ -19,10 +19,8 @@ import {
19
19
  } from "@dnd-kit/sortable";
20
20
  import { CSS } from "@dnd-kit/utilities";
21
21
  import type {
22
- AddContentDatabaseSourceFieldPropertyRequest,
23
22
  BindContentDatabaseSourceFieldRequest,
24
23
  ContentDatabaseResponse,
25
- ContentDatabaseSourceFieldPropertyResponse,
26
24
  ContentDatabaseSource,
27
25
  DocumentProperty,
28
26
  } from "@shared/api";
@@ -130,7 +128,7 @@ import {
130
128
  TooltipContent,
131
129
  TooltipTrigger,
132
130
  } from "@/components/ui/tooltip";
133
- import { applySourceFieldPropertyToDatabaseResponse } from "@/hooks/use-content-database";
131
+ import { useAddContentDatabaseSourceFieldProperty } from "@/hooks/use-content-database";
134
132
  import {
135
133
  documentPropertiesResponseMatchesScope,
136
134
  useConfigureDocumentProperty,
@@ -3148,25 +3146,8 @@ export function AddProperty({
3148
3146
  }) {
3149
3147
  const t = useT();
3150
3148
  const configure = useConfigureDocumentProperty(documentId, databaseId);
3151
- const queryClient = useQueryClient();
3152
- const addSourceFieldProperty = useActionMutation<
3153
- ContentDatabaseSourceFieldPropertyResponse,
3154
- AddContentDatabaseSourceFieldPropertyRequest
3155
- >("add-content-database-source-field-property", {
3156
- onSuccess: (data) => {
3157
- queryClient.setQueriesData<ContentDatabaseResponse>(
3158
- { queryKey: ["action", "get-content-database"] },
3159
- (current) => applySourceFieldPropertyToDatabaseResponse(current, data),
3160
- );
3161
- queryClient.invalidateQueries({
3162
- queryKey: [
3163
- "action",
3164
- "list-document-properties",
3165
- { documentId, databaseId },
3166
- ],
3167
- });
3168
- },
3169
- });
3149
+ const addSourceFieldProperty =
3150
+ useAddContentDatabaseSourceFieldProperty(documentId);
3170
3151
  const [open, setOpen] = useState(false);
3171
3152
  const [typeQuery, setTypeQuery] = useState("");
3172
3153
  const filteredPropertyTypes = filterDocumentPropertyTypes(typeQuery);