@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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/use-action.ts +6 -0
- package/corpus/templates/content/actions/_batch-utils.ts +33 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -81
- package/corpus/templates/content/actions/_content-files.ts +31 -21
- package/corpus/templates/content/actions/_database-source-utils.ts +653 -155
- package/corpus/templates/content/actions/_database-utils.ts +535 -41
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +291 -240
- package/corpus/templates/content/actions/add-database-item.ts +15 -1
- package/corpus/templates/content/actions/attach-content-database-source.ts +156 -58
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +2 -2
- package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +4 -1
- package/corpus/templates/content/actions/delete-database-items.ts +8 -2
- package/corpus/templates/content/actions/disconnect-content-database-source.ts +2 -2
- package/corpus/templates/content/actions/duplicate-database-item.ts +15 -1
- package/corpus/templates/content/actions/duplicate-database-items.ts +19 -1
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +2 -1
- package/corpus/templates/content/actions/get-content-database.ts +12 -64
- package/corpus/templates/content/actions/move-database-item.ts +4 -1
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +4 -8
- package/corpus/templates/content/actions/preview-content-database-source-attach.ts +92 -0
- package/corpus/templates/content/actions/process-builder-body-hydration.ts +2 -1
- package/corpus/templates/content/actions/query-content-database-items.ts +64 -0
- package/corpus/templates/content/actions/refresh-content-database-source.ts +7 -0
- package/corpus/templates/content/actions/review-content-database-source-change-set.ts +1 -1
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +1 -1
- package/corpus/templates/content/actions/stage-builder-revision.ts +1 -1
- package/corpus/templates/content/actions/update-content-database-personal-view.ts +29 -3
- package/corpus/templates/content/actions/update-content-database-view.ts +1 -1
- package/corpus/templates/content/actions/validate-builder-source-execution.ts +1 -1
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +3 -22
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +267 -105
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +82 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +285 -24
- package/corpus/templates/content/app/hooks/use-document-properties.ts +7 -6
- package/corpus/templates/content/app/i18n-data.ts +10 -0
- package/corpus/templates/content/changelog/2026-07-29-large-databases-keep-useful-rows-visible.md +6 -0
- package/corpus/templates/content/changelog/2026-07-30-builder-source-columns-now-appear-immediately-when-connected.md +6 -0
- package/corpus/templates/content/changelog/2026-07-30-large-builder-backed-tables-show-useful-rows-sooner-and-fini.md +6 -0
- package/corpus/templates/content/changelog/2026-08-01-large-builder-databases-now-show-rows-immediately-and-finish.md +6 -0
- package/corpus/templates/content/parity/matrix.md +2 -1
- package/corpus/templates/content/parity/matrix.ts +25 -0
- package/corpus/templates/content/shared/api.ts +54 -4
- package/corpus/templates/content/shared/database-query.ts +359 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +6 -0
- package/dist/client/use-action.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
- 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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
55
|
+
validItemIds,
|
|
30
56
|
);
|
|
31
57
|
await putUserSetting(ctx.userEmail, key, overrides);
|
|
32
58
|
} else {
|
|
@@ -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 {
|
|
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
|
|
3152
|
-
|
|
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);
|