@inkeep/agents-core 0.0.0-dev-20260118170655 → 0.0.0-dev-20260119163620

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.
@@ -0,0 +1,237 @@
1
+ import { SpiceDbRelations, SpiceDbResourceTypes, isAuthzEnabled } from "./config.js";
2
+ import { deleteRelationship, getSpiceClient, readRelationships, writeRelationship } from "./client.js";
3
+
4
+ //#region src/auth/authz/sync.ts
5
+ /**
6
+ * SpiceDB Sync Utilities
7
+ *
8
+ * Functions for syncing data between better-auth and SpiceDB.
9
+ */
10
+ const RELATIONSHIP_OPERATION_CREATE = 1;
11
+ const RELATIONSHIP_OPERATION_TOUCH = 2;
12
+ const RELATIONSHIP_OPERATION_DELETE = 3;
13
+ /**
14
+ * Sync a user's org membership to SpiceDB.
15
+ * Call when: user joins org, role changes, user leaves org.
16
+ */
17
+ async function syncOrgMemberToSpiceDb(params) {
18
+ if (!isAuthzEnabled(params.tenantId)) return;
19
+ if (params.action === "add") await writeRelationship({
20
+ resourceType: SpiceDbResourceTypes.ORGANIZATION,
21
+ resourceId: params.tenantId,
22
+ relation: params.role,
23
+ subjectType: SpiceDbResourceTypes.USER,
24
+ subjectId: params.userId
25
+ });
26
+ else await deleteRelationship({
27
+ resourceType: SpiceDbResourceTypes.ORGANIZATION,
28
+ resourceId: params.tenantId,
29
+ relation: params.role,
30
+ subjectType: SpiceDbResourceTypes.USER,
31
+ subjectId: params.userId
32
+ });
33
+ }
34
+ /**
35
+ * Change a user's organization role.
36
+ * Removes the old role and adds the new one atomically in a single transaction.
37
+ * Call when: user's org role is updated (e.g., member -> admin).
38
+ */
39
+ async function changeOrgRole(params) {
40
+ if (!isAuthzEnabled(params.tenantId)) return;
41
+ if (params.oldRole === params.newRole) return;
42
+ await getSpiceClient().promises.writeRelationships({
43
+ updates: [{
44
+ operation: RELATIONSHIP_OPERATION_DELETE,
45
+ relationship: {
46
+ resource: {
47
+ objectType: SpiceDbResourceTypes.ORGANIZATION,
48
+ objectId: params.tenantId
49
+ },
50
+ relation: params.oldRole,
51
+ subject: {
52
+ object: {
53
+ objectType: SpiceDbResourceTypes.USER,
54
+ objectId: params.userId
55
+ },
56
+ optionalRelation: ""
57
+ },
58
+ optionalCaveat: void 0
59
+ }
60
+ }, {
61
+ operation: RELATIONSHIP_OPERATION_TOUCH,
62
+ relationship: {
63
+ resource: {
64
+ objectType: SpiceDbResourceTypes.ORGANIZATION,
65
+ objectId: params.tenantId
66
+ },
67
+ relation: params.newRole,
68
+ subject: {
69
+ object: {
70
+ objectType: SpiceDbResourceTypes.USER,
71
+ objectId: params.userId
72
+ },
73
+ optionalRelation: ""
74
+ },
75
+ optionalCaveat: void 0
76
+ }
77
+ }],
78
+ optionalPreconditions: [],
79
+ optionalTransactionMetadata: void 0
80
+ });
81
+ }
82
+ /**
83
+ * Sync a new project to SpiceDB.
84
+ * Links project to org and grants creator project_admin role.
85
+ * Call when: project is created.
86
+ */
87
+ async function syncProjectToSpiceDb(params) {
88
+ if (!isAuthzEnabled(params.tenantId)) return;
89
+ await getSpiceClient().promises.writeRelationships({
90
+ updates: [{
91
+ operation: RELATIONSHIP_OPERATION_CREATE,
92
+ relationship: {
93
+ resource: {
94
+ objectType: SpiceDbResourceTypes.PROJECT,
95
+ objectId: params.projectId
96
+ },
97
+ relation: SpiceDbRelations.ORGANIZATION,
98
+ subject: {
99
+ object: {
100
+ objectType: SpiceDbResourceTypes.ORGANIZATION,
101
+ objectId: params.tenantId
102
+ },
103
+ optionalRelation: ""
104
+ },
105
+ optionalCaveat: void 0
106
+ }
107
+ }, {
108
+ operation: RELATIONSHIP_OPERATION_CREATE,
109
+ relationship: {
110
+ resource: {
111
+ objectType: SpiceDbResourceTypes.PROJECT,
112
+ objectId: params.projectId
113
+ },
114
+ relation: SpiceDbRelations.PROJECT_ADMIN,
115
+ subject: {
116
+ object: {
117
+ objectType: SpiceDbResourceTypes.USER,
118
+ objectId: params.creatorUserId
119
+ },
120
+ optionalRelation: ""
121
+ },
122
+ optionalCaveat: void 0
123
+ }
124
+ }],
125
+ optionalPreconditions: [],
126
+ optionalTransactionMetadata: void 0
127
+ });
128
+ }
129
+ /**
130
+ * Grant project access to a user.
131
+ */
132
+ async function grantProjectAccess(params) {
133
+ if (!isAuthzEnabled(params.tenantId)) throw new Error("Authorization is not enabled");
134
+ await writeRelationship({
135
+ resourceType: SpiceDbResourceTypes.PROJECT,
136
+ resourceId: params.projectId,
137
+ relation: params.role,
138
+ subjectType: SpiceDbResourceTypes.USER,
139
+ subjectId: params.userId
140
+ });
141
+ }
142
+ /**
143
+ * Revoke project access from a user.
144
+ */
145
+ async function revokeProjectAccess(params) {
146
+ if (!isAuthzEnabled(params.tenantId)) throw new Error("Authorization is not enabled");
147
+ await deleteRelationship({
148
+ resourceType: SpiceDbResourceTypes.PROJECT,
149
+ resourceId: params.projectId,
150
+ relation: params.role,
151
+ subjectType: SpiceDbResourceTypes.USER,
152
+ subjectId: params.userId
153
+ });
154
+ }
155
+ /**
156
+ * Change a user's project role.
157
+ * Removes the old role and adds the new one atomically in a single transaction.
158
+ */
159
+ async function changeProjectRole(params) {
160
+ if (!isAuthzEnabled(params.tenantId)) throw new Error("Authorization is not enabled");
161
+ if (params.oldRole === params.newRole) return;
162
+ await getSpiceClient().promises.writeRelationships({
163
+ updates: [{
164
+ operation: RELATIONSHIP_OPERATION_DELETE,
165
+ relationship: {
166
+ resource: {
167
+ objectType: SpiceDbResourceTypes.PROJECT,
168
+ objectId: params.projectId
169
+ },
170
+ relation: params.oldRole,
171
+ subject: {
172
+ object: {
173
+ objectType: SpiceDbResourceTypes.USER,
174
+ objectId: params.userId
175
+ },
176
+ optionalRelation: ""
177
+ },
178
+ optionalCaveat: void 0
179
+ }
180
+ }, {
181
+ operation: RELATIONSHIP_OPERATION_TOUCH,
182
+ relationship: {
183
+ resource: {
184
+ objectType: SpiceDbResourceTypes.PROJECT,
185
+ objectId: params.projectId
186
+ },
187
+ relation: params.newRole,
188
+ subject: {
189
+ object: {
190
+ objectType: SpiceDbResourceTypes.USER,
191
+ objectId: params.userId
192
+ },
193
+ optionalRelation: ""
194
+ },
195
+ optionalCaveat: void 0
196
+ }
197
+ }],
198
+ optionalPreconditions: [],
199
+ optionalTransactionMetadata: void 0
200
+ });
201
+ }
202
+ /**
203
+ * Remove a project from SpiceDB.
204
+ * Call when: project is deleted.
205
+ */
206
+ async function removeProjectFromSpiceDb(params) {
207
+ if (!isAuthzEnabled(params.tenantId)) return;
208
+ await getSpiceClient().promises.deleteRelationships({
209
+ relationshipFilter: {
210
+ resourceType: SpiceDbResourceTypes.PROJECT,
211
+ optionalResourceId: params.projectId,
212
+ optionalResourceIdPrefix: "",
213
+ optionalRelation: ""
214
+ },
215
+ optionalPreconditions: [],
216
+ optionalLimit: 0,
217
+ optionalAllowPartialDeletions: false,
218
+ optionalTransactionMetadata: void 0
219
+ });
220
+ }
221
+ /**
222
+ * List all explicit project members from SpiceDB.
223
+ * Returns users with project_admin, project_member, or project_viewer roles.
224
+ */
225
+ async function listProjectMembers(params) {
226
+ if (!isAuthzEnabled(params.tenantId)) return [];
227
+ return (await readRelationships({
228
+ resourceType: SpiceDbResourceTypes.PROJECT,
229
+ resourceId: params.projectId
230
+ })).filter((rel) => rel.subjectType === SpiceDbResourceTypes.USER && (rel.relation === SpiceDbRelations.PROJECT_ADMIN || rel.relation === SpiceDbRelations.PROJECT_MEMBER || rel.relation === SpiceDbRelations.PROJECT_VIEWER)).map((rel) => ({
231
+ userId: rel.subjectId,
232
+ role: rel.relation
233
+ }));
234
+ }
235
+
236
+ //#endregion
237
+ export { changeOrgRole, changeProjectRole, grantProjectAccess, listProjectMembers, removeProjectFromSpiceDb, revokeProjectAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb };
@@ -1,29 +1,29 @@
1
- import * as better_auth_plugins55 from "better-auth/plugins";
1
+ import * as better_auth_plugins0 from "better-auth/plugins";
2
2
  import { AccessControl } from "better-auth/plugins/access";
3
3
  import { organizationClient } from "better-auth/client/plugins";
4
4
 
5
5
  //#region src/auth/permissions.d.ts
6
6
  declare const ac: AccessControl;
7
7
  declare const memberRole: {
8
- authorize<K_1 extends "function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key] | {
9
- actions: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key];
8
+ authorize<K_1 extends "project" | "organization" | "team" | "member" | "ac" | "invitation">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key] | {
9
+ actions: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key];
10
10
  connector: "OR" | "AND";
11
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins55.AuthorizeResponse;
12
- statements: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>;
11
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
12
+ statements: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>;
13
13
  };
14
14
  declare const adminRole: {
15
- authorize<K_1 extends "function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key] | {
16
- actions: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key];
15
+ authorize<K_1 extends "project" | "organization" | "team" | "member" | "ac" | "invitation">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key] | {
16
+ actions: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key];
17
17
  connector: "OR" | "AND";
18
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins55.AuthorizeResponse;
19
- statements: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>;
18
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
19
+ statements: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>;
20
20
  };
21
21
  declare const ownerRole: {
22
- authorize<K_1 extends "function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key] | {
23
- actions: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>[key];
22
+ authorize<K_1 extends "project" | "organization" | "team" | "member" | "ac" | "invitation">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key] | {
23
+ actions: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>[key];
24
24
  connector: "OR" | "AND";
25
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins55.AuthorizeResponse;
26
- statements: better_auth_plugins55.Subset<"function" | "agent" | "project" | "organization" | "credential" | "tool" | "member" | "invitation" | "ac" | "sub_agent" | "api_key" | "data_component" | "artifact_component" | "external_agent" | "context_config" | "team", better_auth_plugins55.Statements>;
25
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
26
+ statements: better_auth_plugins0.Subset<"project" | "organization" | "team" | "member" | "ac" | "invitation", better_auth_plugins0.Statements>;
27
27
  };
28
28
  //#endregion
29
29
  export { ac, adminRole, memberRole, organizationClient, ownerRole };
@@ -10,138 +10,19 @@ const statement = {
10
10
  "read",
11
11
  "update",
12
12
  "delete"
13
- ],
14
- agent: [
15
- "create",
16
- "read",
17
- "update",
18
- "delete"
19
- ],
20
- sub_agent: [
21
- "create",
22
- "read",
23
- "update",
24
- "delete"
25
- ],
26
- tool: [
27
- "create",
28
- "read",
29
- "update",
30
- "delete"
31
- ],
32
- api_key: [
33
- "create",
34
- "read",
35
- "update",
36
- "delete"
37
- ],
38
- credential: [
39
- "create",
40
- "read",
41
- "update",
42
- "delete"
43
- ],
44
- data_component: [
45
- "create",
46
- "read",
47
- "update",
48
- "delete"
49
- ],
50
- artifact_component: [
51
- "create",
52
- "read",
53
- "update",
54
- "delete"
55
- ],
56
- external_agent: [
57
- "create",
58
- "read",
59
- "update",
60
- "delete"
61
- ],
62
- function: [
63
- "create",
64
- "read",
65
- "update",
66
- "delete"
67
- ],
68
- context_config: [
69
- "create",
70
- "read",
71
- "update",
72
- "delete"
73
13
  ]
74
14
  };
75
15
  const ac = createAccessControl(statement);
76
16
  const memberRole = ac.newRole({
77
17
  project: ["read"],
78
- agent: ["read"],
79
- sub_agent: ["read"],
80
- tool: ["read"],
81
- api_key: ["read"],
82
- credential: ["read"],
83
- data_component: ["read"],
84
- artifact_component: ["read"],
85
- external_agent: ["read"],
86
- function: ["read"],
87
- context_config: ["read"],
88
18
  ...memberAc.statements
89
19
  });
90
20
  const adminRole = ac.newRole({
91
21
  project: [
92
22
  "create",
93
23
  "read",
94
- "update"
95
- ],
96
- agent: [
97
- "create",
98
- "read",
99
- "update"
100
- ],
101
- sub_agent: [
102
- "create",
103
- "read",
104
- "update"
105
- ],
106
- tool: [
107
- "create",
108
- "read",
109
- "update"
110
- ],
111
- api_key: [
112
- "create",
113
- "read",
114
- "update"
115
- ],
116
- credential: [
117
- "create",
118
- "read",
119
- "update"
120
- ],
121
- data_component: [
122
- "create",
123
- "read",
124
- "update"
125
- ],
126
- artifact_component: [
127
- "create",
128
- "read",
129
- "update"
130
- ],
131
- external_agent: [
132
- "create",
133
- "read",
134
- "update"
135
- ],
136
- function: [
137
- "create",
138
- "read",
139
- "update"
140
- ],
141
- context_config: [
142
- "create",
143
- "read",
144
- "update"
24
+ "update",
25
+ "delete"
145
26
  ],
146
27
  ...adminAc.statements
147
28
  });
@@ -152,66 +33,6 @@ const ownerRole = ac.newRole({
152
33
  "update",
153
34
  "delete"
154
35
  ],
155
- agent: [
156
- "create",
157
- "read",
158
- "update",
159
- "delete"
160
- ],
161
- sub_agent: [
162
- "create",
163
- "read",
164
- "update",
165
- "delete"
166
- ],
167
- tool: [
168
- "create",
169
- "read",
170
- "update",
171
- "delete"
172
- ],
173
- api_key: [
174
- "create",
175
- "read",
176
- "update",
177
- "delete"
178
- ],
179
- credential: [
180
- "create",
181
- "read",
182
- "update",
183
- "delete"
184
- ],
185
- data_component: [
186
- "create",
187
- "read",
188
- "update",
189
- "delete"
190
- ],
191
- artifact_component: [
192
- "create",
193
- "read",
194
- "update",
195
- "delete"
196
- ],
197
- external_agent: [
198
- "create",
199
- "read",
200
- "update",
201
- "delete"
202
- ],
203
- function: [
204
- "create",
205
- "read",
206
- "update",
207
- "delete"
208
- ],
209
- context_config: [
210
- "create",
211
- "read",
212
- "update",
213
- "delete"
214
- ],
215
36
  ...ownerAc.statements
216
37
  });
217
38
 
@@ -103,6 +103,7 @@ interface ListProjectsWithMetadataResult {
103
103
  declare const listProjectsWithMetadataPaginated: (runDb: AgentsRunDatabaseClient, configDb: AgentsManageDatabaseClient) => (params: {
104
104
  tenantId: string;
105
105
  pagination?: PaginationConfig;
106
+ projectIds?: string[];
106
107
  }) => Promise<ListProjectsWithMetadataResult>;
107
108
  /**
108
109
  * Get a single project with metadata from both runtime and config DBs
@@ -177,10 +177,11 @@ async function getProjectMetadataFromBranch(configDb, branchName, tenantId, proj
177
177
  * @param configDb - Config database client (Doltgres)
178
178
  */
179
179
  const listProjectsWithMetadataPaginated = (runDb, configDb) => async (params) => {
180
- const { tenantId, pagination } = params;
180
+ const { tenantId, pagination, projectIds } = params;
181
181
  const projectMetadataResult = await listProjectsMetadataPaginated(runDb)({
182
182
  tenantId,
183
- pagination
183
+ pagination,
184
+ projectIds
184
185
  });
185
186
  return {
186
187
  data: await Promise.all(projectMetadataResult.data.map(async (projectMetadata) => {
@@ -6,16 +6,20 @@ import { ProjectInsert, ProjectSelect, ProjectUpdate } from "../../types/entitie
6
6
 
7
7
  /**
8
8
  * List all unique project IDs within a tenant by scanning all resource tables
9
+ * @param projectIds - Optional array of project IDs to filter by. If undefined, returns all projects.
9
10
  */
10
11
  declare const listProjects: (db: AgentsManageDatabaseClient) => (params: {
11
12
  tenantId: string;
13
+ projectIds?: string[];
12
14
  }) => Promise<ProjectInfo[]>;
13
15
  /**
14
16
  * List all unique project IDs within a tenant with pagination
17
+ * Optionally filter by a list of project IDs (for access control)
15
18
  */
16
19
  declare const listProjectsPaginated: (db: AgentsManageDatabaseClient) => (params: {
17
20
  tenantId: string;
18
21
  pagination?: PaginationConfig;
22
+ projectIds?: string[];
19
23
  }) => Promise<{
20
24
  data: ProjectSelect[];
21
25
  pagination: PaginationResult;
@@ -1,12 +1,15 @@
1
1
  import { agents, artifactComponents, contextConfigs, credentialReferences, dataComponents, externalAgents, projects, subAgentArtifactComponents, subAgentDataComponents, subAgentRelations, subAgentToolRelations, subAgents, tools } from "../../db/manage/manage-schema.js";
2
- import { and, count, desc, eq } from "drizzle-orm";
2
+ import { and, count, desc, eq, inArray } from "drizzle-orm";
3
3
 
4
4
  //#region src/data-access/manage/projects.ts
5
5
  /**
6
6
  * List all unique project IDs within a tenant by scanning all resource tables
7
+ * @param projectIds - Optional array of project IDs to filter by. If undefined, returns all projects.
7
8
  */
8
9
  const listProjects = (db) => async (params) => {
9
- const projectsFromTable = await db.select({ projectId: projects.id }).from(projects).where(eq(projects.tenantId, params.tenantId));
10
+ if (params.projectIds !== void 0 && params.projectIds.length === 0) return [];
11
+ const whereClause = params.projectIds ? and(eq(projects.tenantId, params.tenantId), inArray(projects.id, params.projectIds)) : eq(projects.tenantId, params.tenantId);
12
+ const projectsFromTable = await db.select({ projectId: projects.id }).from(projects).where(whereClause);
10
13
  if (projectsFromTable.length > 0) return projectsFromTable.map((p) => ({ projectId: p.projectId }));
11
14
  const projectIdSets = await Promise.all([
12
15
  db.selectDistinct({ projectId: subAgents.projectId }).from(subAgents).where(eq(subAgents.tenantId, params.tenantId)),
@@ -25,19 +28,23 @@ const listProjects = (db) => async (params) => {
25
28
  const allProjectIds = /* @__PURE__ */ new Set();
26
29
  projectIdSets.forEach((results) => {
27
30
  results.forEach((row) => {
28
- if (row.projectId) allProjectIds.add(row.projectId);
31
+ if (row.projectId) {
32
+ if (!params.projectIds || params.projectIds.includes(row.projectId)) allProjectIds.add(row.projectId);
33
+ }
29
34
  });
30
35
  });
31
36
  return Array.from(allProjectIds).sort().map((projectId) => ({ projectId }));
32
37
  };
33
38
  /**
34
39
  * List all unique project IDs within a tenant with pagination
40
+ * Optionally filter by a list of project IDs (for access control)
35
41
  */
36
42
  const listProjectsPaginated = (db) => async (params) => {
37
43
  const page = params.pagination?.page || 1;
38
44
  const limit = params.pagination?.limit || 10;
39
45
  const offset = (page - 1) * limit;
40
- const [data, totalResult] = await Promise.all([db.select().from(projects).where(eq(projects.tenantId, params.tenantId)).limit(limit).offset(offset).orderBy(desc(projects.createdAt)), db.select({ count: count() }).from(projects).where(eq(projects.tenantId, params.tenantId))]);
46
+ const whereClause = params.projectIds ? and(eq(projects.tenantId, params.tenantId), inArray(projects.id, params.projectIds)) : eq(projects.tenantId, params.tenantId);
47
+ const [data, totalResult] = await Promise.all([db.select().from(projects).where(whereClause).limit(limit).offset(offset).orderBy(desc(projects.createdAt)), db.select({ count: count() }).from(projects).where(whereClause)]);
41
48
  const total = totalResult[0]?.count || 0;
42
49
  return {
43
50
  data,
@@ -16,19 +16,19 @@ declare const getMessageById: (db: AgentsRunDatabaseClient) => (params: {
16
16
  updatedAt: string;
17
17
  metadata: MessageMetadata | null;
18
18
  content: MessageContent;
19
- conversationId: string;
20
- role: string;
21
19
  fromSubAgentId: string | null;
22
20
  toSubAgentId: string | null;
23
21
  fromExternalAgentId: string | null;
24
22
  toExternalAgentId: string | null;
23
+ taskId: string | null;
24
+ a2aTaskId: string | null;
25
+ conversationId: string;
26
+ role: string;
25
27
  fromTeamAgentId: string | null;
26
28
  toTeamAgentId: string | null;
27
29
  visibility: string;
28
30
  messageType: string;
29
- taskId: string | null;
30
31
  parentMessageId: string | null;
31
- a2aTaskId: string | null;
32
32
  a2aSessionId: string | null;
33
33
  } | undefined>;
34
34
  declare const listMessages: (db: AgentsRunDatabaseClient) => (params: {
@@ -147,19 +147,19 @@ declare const createMessage: (db: AgentsRunDatabaseClient) => (params: MessageIn
147
147
  updatedAt: string;
148
148
  metadata: MessageMetadata | null;
149
149
  content: MessageContent;
150
- conversationId: string;
151
- role: string;
152
150
  fromSubAgentId: string | null;
153
151
  toSubAgentId: string | null;
154
152
  fromExternalAgentId: string | null;
155
153
  toExternalAgentId: string | null;
154
+ taskId: string | null;
155
+ a2aTaskId: string | null;
156
+ conversationId: string;
157
+ role: string;
156
158
  fromTeamAgentId: string | null;
157
159
  toTeamAgentId: string | null;
158
160
  visibility: string;
159
161
  messageType: string;
160
- taskId: string | null;
161
162
  parentMessageId: string | null;
162
- a2aTaskId: string | null;
163
163
  a2aSessionId: string | null;
164
164
  }>;
165
165
  declare const updateMessage: (db: AgentsRunDatabaseClient) => (params: {
@@ -200,19 +200,19 @@ declare const deleteMessage: (db: AgentsRunDatabaseClient) => (params: {
200
200
  updatedAt: string;
201
201
  metadata: MessageMetadata | null;
202
202
  content: MessageContent;
203
- conversationId: string;
204
- role: string;
205
203
  fromSubAgentId: string | null;
206
204
  toSubAgentId: string | null;
207
205
  fromExternalAgentId: string | null;
208
206
  toExternalAgentId: string | null;
207
+ taskId: string | null;
208
+ a2aTaskId: string | null;
209
+ conversationId: string;
210
+ role: string;
209
211
  fromTeamAgentId: string | null;
210
212
  toTeamAgentId: string | null;
211
213
  visibility: string;
212
214
  messageType: string;
213
- taskId: string | null;
214
215
  parentMessageId: string | null;
215
- a2aTaskId: string | null;
216
216
  a2aSessionId: string | null;
217
217
  }>;
218
218
  declare const countMessagesByConversation: (db: AgentsRunDatabaseClient) => (params: {
@@ -27,10 +27,12 @@ declare const listProjectsMetadata: (db: AgentsRunDatabaseClient) => (params: {
27
27
  }) => Promise<ProjectMetadataSelect[]>;
28
28
  /**
29
29
  * List runtimeProjects with pagination from the runtime DB
30
+ * @param projectIds - Optional array of project IDs to filter by. If undefined, returns all projects.
30
31
  */
31
32
  declare const listProjectsMetadataPaginated: (db: AgentsRunDatabaseClient) => (params: {
32
33
  tenantId: string;
33
34
  pagination?: PaginationConfig;
35
+ projectIds?: string[];
34
36
  }) => Promise<ProjectMetadataPaginatedResult>;
35
37
  /**
36
38
  * Create a project in the runtime DB