@intx/db 0.1.2 → 0.2.2

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 (121) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +21 -2
  3. package/dist/asset-resolution.d.ts +52 -0
  4. package/dist/asset-resolution.js +66 -0
  5. package/dist/catalog-resolution.d.ts +76 -0
  6. package/dist/catalog-resolution.js +151 -0
  7. package/dist/client.d.ts +9 -0
  8. package/dist/client.js +18 -0
  9. package/dist/config.d.ts +11 -0
  10. package/dist/config.js +16 -0
  11. package/dist/connection.d.ts +3 -0
  12. package/dist/connection.js +23 -0
  13. package/dist/credential-resolution.d.ts +110 -0
  14. package/dist/credential-resolution.js +116 -0
  15. package/dist/grant-store.d.ts +3 -0
  16. package/dist/grant-store.js +37 -0
  17. package/dist/index.d.ts +13 -0
  18. package/dist/index.js +12 -0
  19. package/dist/migrate.d.ts +36 -0
  20. package/dist/migrate.js +135 -0
  21. package/dist/model-source-resolution.d.ts +69 -0
  22. package/dist/model-source-resolution.js +165 -0
  23. package/dist/parse-row.d.ts +193 -0
  24. package/dist/parse-row.js +141 -0
  25. package/dist/pg-error.d.ts +3 -0
  26. package/dist/pg-error.js +19 -0
  27. package/dist/pricing.d.ts +15 -0
  28. package/dist/pricing.js +24 -0
  29. package/dist/schema/agent-assets.d.ts +109 -0
  30. package/dist/schema/agent-assets.js +15 -0
  31. package/dist/schema/agents.d.ts +405 -0
  32. package/dist/schema/agents.js +57 -0
  33. package/dist/schema/assets.d.ts +143 -0
  34. package/{src/schema/assets.ts → dist/schema/assets.js} +7 -16
  35. package/dist/schema/auth.d.ts +606 -0
  36. package/dist/schema/auth.js +47 -0
  37. package/dist/schema/catalog.d.ts +794 -0
  38. package/dist/schema/catalog.js +102 -0
  39. package/dist/schema/column-types.d.ts +26 -0
  40. package/dist/schema/column-types.js +15 -0
  41. package/dist/schema/credentials.d.ts +305 -0
  42. package/{src/schema/credentials.ts → dist/schema/credentials.js} +16 -22
  43. package/dist/schema/git-tokens.d.ts +256 -0
  44. package/{src/schema/git-tokens.ts → dist/schema/git-tokens.js} +15 -38
  45. package/dist/schema/grants.d.ts +211 -0
  46. package/dist/schema/grants.js +24 -0
  47. package/dist/schema/index.d.ts +21 -0
  48. package/dist/schema/index.js +21 -0
  49. package/dist/schema/instances.d.ts +262 -0
  50. package/dist/schema/instances.js +39 -0
  51. package/dist/schema/messages.d.ts +414 -0
  52. package/dist/schema/messages.js +71 -0
  53. package/dist/schema/oauth-clients.d.ts +246 -0
  54. package/{src/schema/oauth-clients.ts → dist/schema/oauth-clients.js} +8 -14
  55. package/dist/schema/offerings.d.ts +160 -0
  56. package/dist/schema/offerings.js +18 -0
  57. package/dist/schema/principals.d.ts +128 -0
  58. package/{src/schema/principals.ts → dist/schema/principals.js} +7 -14
  59. package/dist/schema/providers.d.ts +220 -0
  60. package/{src/schema/providers.ts → dist/schema/providers.js} +5 -11
  61. package/dist/schema/roles.d.ts +242 -0
  62. package/dist/schema/roles.js +33 -0
  63. package/dist/schema/session-assets.d.ts +129 -0
  64. package/dist/schema/session-assets.js +28 -0
  65. package/dist/schema/sessions.d.ts +143 -0
  66. package/dist/schema/sessions.js +24 -0
  67. package/dist/schema/sidecar.d.ts +128 -0
  68. package/dist/schema/sidecar.js +18 -0
  69. package/dist/schema/tenants.d.ts +235 -0
  70. package/{src/schema/tenants.ts → dist/schema/tenants.js} +10 -27
  71. package/dist/schema/wallets.d.ts +354 -0
  72. package/dist/schema/wallets.js +41 -0
  73. package/dist/schema/workflow-deployments.d.ts +129 -0
  74. package/dist/schema/workflow-deployments.js +37 -0
  75. package/dist/tenant-hierarchy.d.ts +22 -0
  76. package/dist/tenant-hierarchy.js +55 -0
  77. package/migrations/0029_loose_warlock.sql +1 -0
  78. package/migrations/0030_session_asset_audit_split.sql +5 -0
  79. package/migrations/0031_gigantic_nicolaos.sql +68 -0
  80. package/migrations/0032_lethal_misty_knight.sql +1 -0
  81. package/migrations/0033_old_payback.sql +1 -0
  82. package/migrations/0034_sleepy_songbird.sql +11 -0
  83. package/migrations/0035_violet_giant_man.sql +3 -0
  84. package/migrations/0036_sharp_the_executioner.sql +2 -0
  85. package/migrations/meta/0029_snapshot.json +2664 -0
  86. package/migrations/meta/0030_snapshot.json +2670 -0
  87. package/migrations/meta/0031_snapshot.json +3100 -0
  88. package/migrations/meta/0032_snapshot.json +3106 -0
  89. package/migrations/meta/0033_snapshot.json +3112 -0
  90. package/migrations/meta/0034_snapshot.json +3198 -0
  91. package/migrations/meta/0035_snapshot.json +3225 -0
  92. package/migrations/meta/0036_snapshot.json +3237 -0
  93. package/migrations/meta/_journal.json +56 -0
  94. package/package.json +22 -11
  95. package/drizzle.config.ts +0 -23
  96. package/src/client.ts +0 -24
  97. package/src/config.ts +0 -19
  98. package/src/connection.ts +0 -27
  99. package/src/credential-resolution.ts +0 -378
  100. package/src/grant-store.ts +0 -51
  101. package/src/index.ts +0 -32
  102. package/src/migrate.test.ts +0 -35
  103. package/src/migrate.ts +0 -168
  104. package/src/parse-row.test.ts +0 -113
  105. package/src/parse-row.ts +0 -185
  106. package/src/schema/agent-assets.ts +0 -21
  107. package/src/schema/agents.ts +0 -49
  108. package/src/schema/auth.ts +0 -51
  109. package/src/schema/grants.ts +0 -26
  110. package/src/schema/index.ts +0 -19
  111. package/src/schema/instances.ts +0 -36
  112. package/src/schema/messages.ts +0 -108
  113. package/src/schema/offerings.ts +0 -20
  114. package/src/schema/roles.ts +0 -51
  115. package/src/schema/session-assets.ts +0 -49
  116. package/src/schema/sessions.ts +0 -26
  117. package/src/schema/sidecar.ts +0 -14
  118. package/src/schema/wallets.ts +0 -44
  119. package/src/tenant-hierarchy.ts +0 -34
  120. package/tsconfig.json +0 -4
  121. package/tsconfig.tsbuildinfo +0 -1
@@ -204,6 +204,62 @@
204
204
  "when": 1780502952568,
205
205
  "tag": "0028_wet_sugar_man",
206
206
  "breakpoints": true
207
+ },
208
+ {
209
+ "idx": 29,
210
+ "version": "7",
211
+ "when": 1780694869983,
212
+ "tag": "0029_loose_warlock",
213
+ "breakpoints": true
214
+ },
215
+ {
216
+ "idx": 30,
217
+ "version": "7",
218
+ "when": 1780899731435,
219
+ "tag": "0030_session_asset_audit_split",
220
+ "breakpoints": true
221
+ },
222
+ {
223
+ "idx": 31,
224
+ "version": "7",
225
+ "when": 1781823077761,
226
+ "tag": "0031_gigantic_nicolaos",
227
+ "breakpoints": true
228
+ },
229
+ {
230
+ "idx": 32,
231
+ "version": "7",
232
+ "when": 1781837038055,
233
+ "tag": "0032_lethal_misty_knight",
234
+ "breakpoints": true
235
+ },
236
+ {
237
+ "idx": 33,
238
+ "version": "7",
239
+ "when": 1781838311284,
240
+ "tag": "0033_old_payback",
241
+ "breakpoints": true
242
+ },
243
+ {
244
+ "idx": 34,
245
+ "version": "7",
246
+ "when": 1782164862412,
247
+ "tag": "0034_sleepy_songbird",
248
+ "breakpoints": true
249
+ },
250
+ {
251
+ "idx": 35,
252
+ "version": "7",
253
+ "when": 1783373028980,
254
+ "tag": "0035_violet_giant_man",
255
+ "breakpoints": true
256
+ },
257
+ {
258
+ "idx": 36,
259
+ "version": "7",
260
+ "when": 1783998502613,
261
+ "tag": "0036_sharp_the_executioner",
262
+ "breakpoints": true
207
263
  }
208
264
  ]
209
265
  }
package/package.json CHANGED
@@ -1,27 +1,38 @@
1
1
  {
2
2
  "name": "@intx/db",
3
- "version": "0.1.2",
3
+ "version": "0.2.2",
4
4
  "license": "LGPL-2.1-only",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
- "types": "./src/index.ts",
9
- "default": "./src/index.ts"
8
+ "intx-src": "./src/index.ts",
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
10
11
  },
11
12
  "./schema": {
12
- "types": "./src/schema/index.ts",
13
- "default": "./src/schema/index.ts"
13
+ "intx-src": "./src/schema/index.ts",
14
+ "types": "./dist/schema/index.d.ts",
15
+ "default": "./dist/schema/index.js"
14
16
  }
15
17
  },
16
- "scripts": {
17
- "db:generate": "drizzle-kit generate --config=drizzle.config.ts",
18
- "db:migrate": "drizzle-kit migrate --config=drizzle.config.ts"
19
- },
20
18
  "dependencies": {
21
- "@intx/log": "0.0.0",
22
- "@intx/types": "0.0.0",
19
+ "@intx/log": "0.2.2",
20
+ "@intx/types": "0.2.2",
23
21
  "arktype": "^2.1.29",
24
22
  "drizzle-orm": "^0.45.1",
25
23
  "postgres": "^3.4.8"
24
+ },
25
+ "devDependencies": {
26
+ "drizzle-kit": "^0.31.9"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "migrations",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "sideEffects": false,
35
+ "publishConfig": {
36
+ "access": "public"
26
37
  }
27
38
  }
package/drizzle.config.ts DELETED
@@ -1,23 +0,0 @@
1
- import { defineConfig } from "drizzle-kit";
2
-
3
- function env(name: string): string {
4
- const value = process.env[name];
5
- if (!value) {
6
- throw new Error(`Missing required environment variable: ${name}`);
7
- }
8
- return value;
9
- }
10
-
11
- export default defineConfig({
12
- dialect: "postgresql",
13
- schema: "./src/schema/index.ts",
14
- out: "./migrations",
15
- dbCredentials: {
16
- host: env("DB_HOST"),
17
- port: Number(process.env["DB_PORT"] ?? 5432),
18
- user: env("DB_USER"),
19
- password: process.env["DB_PASSWORD"] ?? "",
20
- database: env("DB_NAME"),
21
- ssl: process.env["DB_SSL"] === "true",
22
- },
23
- });
package/src/client.ts DELETED
@@ -1,24 +0,0 @@
1
- import { type } from "arktype";
2
- import { drizzle } from "drizzle-orm/postgres-js";
3
-
4
- import { DBConfig } from "./config";
5
- import { createConnection } from "./connection";
6
- import * as schema from "./schema";
7
-
8
- export function createDB(raw: unknown) {
9
- const config = DBConfig(raw);
10
- if (config instanceof type.errors) {
11
- throw new Error(`Invalid database config: ${config.summary}`);
12
- }
13
-
14
- const sql = createConnection(config);
15
- const db = drizzle(sql, { schema });
16
-
17
- return {
18
- db,
19
- transaction: db.transaction.bind(db),
20
- close: () => sql.end(),
21
- };
22
- }
23
-
24
- export type DB = ReturnType<typeof createDB>;
package/src/config.ts DELETED
@@ -1,19 +0,0 @@
1
- import { type } from "arktype";
2
-
3
- export const DBConfig = type({
4
- host: "string",
5
- port: "number.integer > 0",
6
- user: "string",
7
- password: "string",
8
- database: "string",
9
- "ssl?": "boolean",
10
- "max?": "number.integer > 0",
11
- // Postgres schema name. When set, the connection's `search_path` is
12
- // pinned to this schema and migrations apply into it. This is the
13
- // mechanism the integration-test harness uses to give each spawned
14
- // hub a dedicated, droppable schema. When unset, the connection uses
15
- // postgres' default `search_path` (which begins with `public`).
16
- "schema?": "string",
17
- });
18
-
19
- export type DBConfig = typeof DBConfig.infer;
package/src/connection.ts DELETED
@@ -1,27 +0,0 @@
1
- import postgres from "postgres";
2
-
3
- import type { DBConfig } from "./config";
4
-
5
- function quoteIdentifier(name: string): string {
6
- return `"${name.replace(/"/g, '""')}"`;
7
- }
8
-
9
- export function createConnection(config: DBConfig) {
10
- return postgres({
11
- host: config.host,
12
- port: config.port,
13
- user: config.user,
14
- password: config.password,
15
- database: config.database,
16
- max: config.max ?? 10,
17
- ...(config.ssl !== undefined && { ssl: config.ssl }),
18
- ...(config.schema !== undefined && {
19
- // Pin the connection's search_path so unqualified table
20
- // references resolve to the caller's schema. The migration
21
- // runner emits SQL with the schema baked into FK references,
22
- // but ORM-issued queries bind table names without a schema
23
- // qualifier and rely on this setting.
24
- connection: { search_path: quoteIdentifier(config.schema) },
25
- }),
26
- });
27
- }
@@ -1,378 +0,0 @@
1
- import { eq, and, isNull } from "drizzle-orm";
2
- import { type } from "arktype";
3
-
4
- import { getLogger } from "@intx/log";
5
- import { CredentialRequirement as CredentialRequirementType } from "@intx/types";
6
- import type { InferenceSource } from "@intx/types/runtime";
7
-
8
- import type { DB } from "./client";
9
- import { agent } from "./schema/agents";
10
- import { agentSession } from "./schema/sessions";
11
- import { credential } from "./schema/credentials";
12
- import { oauthClient } from "./schema/oauth-clients";
13
- import { provider } from "./schema/providers";
14
- import { getAncestorChain } from "./tenant-hierarchy";
15
-
16
- const log = getLogger(["db", "credentials"]);
17
-
18
- const CredentialRequirements = CredentialRequirementType.array();
19
-
20
- export const ProviderMetadata = type({ baseURL: "string" });
21
-
22
- const AgentModelConfig = type({ defaultModel: "string" });
23
-
24
- /**
25
- * Resolves a provider by name, walking up the tenant hierarchy.
26
- * Returns the first match (child shadows parent).
27
- */
28
- export async function resolveProviderByName(
29
- db: DB["db"],
30
- tenantId: string,
31
- name: string,
32
- ) {
33
- const chain = await getAncestorChain(db, tenantId);
34
-
35
- for (const tid of chain) {
36
- const row = await db.query.provider.findFirst({
37
- where: and(eq(provider.tenantId, tid), eq(provider.name, name)),
38
- });
39
- if (row) return row;
40
- }
41
-
42
- return null;
43
- }
44
-
45
- /**
46
- * Resolves an OAuth client for a provider, walking up the tenant hierarchy.
47
- * Returns the first match (child shadows parent).
48
- */
49
- export async function resolveOAuthClient(
50
- db: DB["db"],
51
- tenantId: string,
52
- providerId: string,
53
- ) {
54
- const chain = await getAncestorChain(db, tenantId);
55
-
56
- for (const tid of chain) {
57
- const row = await db.query.oauthClient.findFirst({
58
- where: and(
59
- eq(oauthClient.tenantId, tid),
60
- eq(oauthClient.providerId, providerId),
61
- ),
62
- });
63
- if (row) return row;
64
- }
65
-
66
- return null;
67
- }
68
-
69
- /**
70
- * Resolves a credential by name, walking up the tenant hierarchy.
71
- * Returns the first match (child shadows parent).
72
- */
73
- export async function resolveCredentialByName(
74
- db: DB["db"],
75
- tenantId: string,
76
- name: string,
77
- ) {
78
- const chain = await getAncestorChain(db, tenantId);
79
-
80
- for (const tid of chain) {
81
- const row = await db.query.credential.findFirst({
82
- where: and(eq(credential.tenantId, tid), eq(credential.name, name)),
83
- });
84
- if (row) return row;
85
- }
86
-
87
- return null;
88
- }
89
-
90
- /**
91
- * Resolves a credential by ID, validating that it belongs to the
92
- * given tenant or one of its ancestors.
93
- */
94
- export async function resolveCredentialById(
95
- db: DB["db"],
96
- tenantId: string,
97
- credentialId: string,
98
- ) {
99
- const row = await db.query.credential.findFirst({
100
- where: eq(credential.id, credentialId),
101
- });
102
-
103
- if (!row) return null;
104
-
105
- const chain = await getAncestorChain(db, tenantId);
106
- if (!chain.includes(row.tenantId)) return null;
107
-
108
- return row;
109
- }
110
-
111
- type CredentialRequirement = {
112
- providerName: string;
113
- scopes?: string[];
114
- source: "tenant" | "creator" | "invoker";
115
- name?: string;
116
- };
117
-
118
- /**
119
- * Resolves a credential matching an agent definition requirement.
120
- * Used at agent launch time by the control plane.
121
- */
122
- export async function resolveCredentialRequirement(
123
- db: DB["db"],
124
- tenantId: string,
125
- requirement: CredentialRequirement,
126
- creatorPrincipalId: string | null,
127
- invokerPrincipalId: string | null,
128
- ) {
129
- const resolvedProvider = await resolveProviderByName(
130
- db,
131
- tenantId,
132
- requirement.providerName,
133
- );
134
- if (!resolvedProvider) return null;
135
-
136
- const chain = await getAncestorChain(db, tenantId);
137
-
138
- const principalFilter =
139
- requirement.source === "tenant"
140
- ? null
141
- : requirement.source === "creator"
142
- ? creatorPrincipalId
143
- : invokerPrincipalId;
144
-
145
- for (const tid of chain) {
146
- const conditions = [
147
- eq(credential.tenantId, tid),
148
- eq(credential.providerId, resolvedProvider.id),
149
- eq(credential.status, "active"),
150
- ];
151
-
152
- if (principalFilter === null) {
153
- conditions.push(isNull(credential.principalId));
154
- } else if (principalFilter) {
155
- conditions.push(eq(credential.principalId, principalFilter));
156
- }
157
-
158
- if (requirement.name) {
159
- conditions.push(eq(credential.name, requirement.name));
160
- }
161
-
162
- const rows = await db.query.credential.findMany({
163
- where: and(...conditions),
164
- });
165
-
166
- const matching = rows.filter((row) => {
167
- if (!requirement.scopes || requirement.scopes.length === 0) return true;
168
- const rowScopes = row.scopes ?? [];
169
- return requirement.scopes.every((s) => rowScopes.includes(s));
170
- });
171
-
172
- const [sole] = matching;
173
- if (matching.length === 1 && sole) return sole;
174
- if (matching.length > 1) {
175
- throw new Error(
176
- `Ambiguous credential match: ${matching.length} credentials match ` +
177
- `provider=${requirement.providerName} source=${requirement.source} ` +
178
- `in tenant ${tid}. Specify a name to disambiguate.`,
179
- );
180
- }
181
- }
182
-
183
- return null;
184
- }
185
-
186
- /**
187
- * Outcome of resolving one credential requirement to an
188
- * `InferenceSource`. Callers map `failed` variants to their own
189
- * error-handling convention (the API route surfaces 409s; the
190
- * background credential pushers log and continue).
191
- */
192
- export type CredentialOutcome =
193
- | { ok: true; source: InferenceSource }
194
- | {
195
- ok: false;
196
- reason: "credential_error";
197
- requirement: CredentialRequirement;
198
- message: string;
199
- }
200
- | {
201
- ok: false;
202
- reason: "credential_missing";
203
- requirement: CredentialRequirement;
204
- }
205
- | {
206
- ok: false;
207
- reason: "skipped";
208
- requirement: CredentialRequirement;
209
- }
210
- | {
211
- ok: false;
212
- reason: "provider_missing";
213
- credentialId: string;
214
- }
215
- | {
216
- ok: false;
217
- reason: "provider_misconfigured";
218
- providerName: string;
219
- summary: string;
220
- };
221
-
222
- /**
223
- * Resolve one credential requirement to an `InferenceSource`, stamping
224
- * `defaultModel` as the model identity. Skips silently (`reason:
225
- * "skipped"`) when the requirement targets a principal that does not
226
- * exist (creator without a creator id, invoker without a session
227
- * principal); all other failure modes are surfaced with structured
228
- * reasons.
229
- */
230
- export async function resolveOneCredential(
231
- db: DB["db"],
232
- tenantId: string,
233
- req: CredentialRequirement,
234
- creatorPrincipalId: string | null,
235
- invokerPrincipalId: string | null,
236
- defaultModel: string,
237
- ): Promise<CredentialOutcome> {
238
- // Reject requirements whose targeted principal does not exist. Without
239
- // these guards a null creator or invoker would fall through to
240
- // `resolveCredentialRequirement`, where the principal filter becomes
241
- // `isNull(credential.principalId)` — the tenant-credential lookup — and
242
- // a tenant credential would be returned as if it satisfied the
243
- // creator- or invoker-source requirement.
244
- if (req.source === "creator" && !creatorPrincipalId) {
245
- return { ok: false, reason: "skipped", requirement: req };
246
- }
247
- if (req.source === "invoker" && !invokerPrincipalId) {
248
- return { ok: false, reason: "skipped", requirement: req };
249
- }
250
-
251
- let resolved;
252
- try {
253
- resolved = await resolveCredentialRequirement(
254
- db,
255
- tenantId,
256
- req,
257
- creatorPrincipalId,
258
- invokerPrincipalId,
259
- );
260
- } catch (err: unknown) {
261
- return {
262
- ok: false,
263
- reason: "credential_error",
264
- requirement: req,
265
- message: err instanceof Error ? err.message : String(err),
266
- };
267
- }
268
- if (!resolved) {
269
- return { ok: false, reason: "credential_missing", requirement: req };
270
- }
271
-
272
- const providerRow = await db.query.provider.findFirst({
273
- where: eq(provider.id, resolved.providerId),
274
- });
275
- if (!providerRow) {
276
- return { ok: false, reason: "provider_missing", credentialId: resolved.id };
277
- }
278
-
279
- const metadata = ProviderMetadata(providerRow.metadata ?? {});
280
- if (metadata instanceof type.errors) {
281
- return {
282
- ok: false,
283
- reason: "provider_misconfigured",
284
- providerName: providerRow.name,
285
- summary: metadata.summary,
286
- };
287
- }
288
-
289
- return {
290
- ok: true,
291
- source: {
292
- id: `${providerRow.plugin}:${defaultModel}`,
293
- provider: providerRow.plugin,
294
- baseURL: metadata.baseURL,
295
- apiKey: resolved.secret,
296
- model: defaultModel,
297
- },
298
- };
299
- }
300
-
301
- /**
302
- * Resolve the full `InferenceSource[]` for a single running instance by
303
- * re-resolving each credential requirement from the agent definition.
304
- *
305
- * Failure modes (invalid agent definition, malformed `modelConfig`, any
306
- * per-credential resolution failure) collapse to an empty array with
307
- * structured `db.credentials` log lines. Callers that need to surface
308
- * per-credential outcomes to operators should call `resolveOneCredential`
309
- * directly — see `packages/hub-api/src/routes/instances.ts` for the
310
- * 409-mapping pattern.
311
- */
312
- export async function resolveInstanceSources(
313
- db: DB["db"],
314
- tenantId: string,
315
- instance: { agentId: string; sessionId: string | null },
316
- ): Promise<InferenceSource[]> {
317
- const agentRow = await db.query.agent.findFirst({
318
- where: eq(agent.id, instance.agentId),
319
- });
320
- if (!agentRow) return [];
321
-
322
- const requirements = CredentialRequirements(
323
- agentRow.credentialRequirements ?? [],
324
- );
325
- if (requirements instanceof type.errors) {
326
- log.warn`Invalid credential requirements for agent ${agentRow.id}: ${requirements.summary}`;
327
- return [];
328
- }
329
-
330
- const modelConfig = AgentModelConfig(agentRow.modelConfig ?? {});
331
- if (modelConfig instanceof type.errors) {
332
- log.warn`Invalid modelConfig for agent ${agentRow.id}: ${modelConfig.summary}`;
333
- return [];
334
- }
335
- const defaultModel = modelConfig.defaultModel;
336
-
337
- let invokerPrincipalId: string | null = null;
338
- if (instance.sessionId) {
339
- const session = await db.query.agentSession.findFirst({
340
- where: eq(agentSession.id, instance.sessionId),
341
- });
342
- if (session) {
343
- invokerPrincipalId = session.principalId;
344
- }
345
- }
346
-
347
- const sources: InferenceSource[] = [];
348
- for (const req of requirements) {
349
- const outcome = await resolveOneCredential(
350
- db,
351
- tenantId,
352
- req,
353
- agentRow.creatorPrincipalId,
354
- invokerPrincipalId,
355
- defaultModel,
356
- );
357
- if (outcome.ok) {
358
- sources.push(outcome.source);
359
- continue;
360
- }
361
- switch (outcome.reason) {
362
- case "skipped":
363
- break;
364
- case "credential_error":
365
- log.warn`Failed to resolve credential for provider ${outcome.requirement.providerName}: ${outcome.message}`;
366
- break;
367
- case "credential_missing":
368
- break;
369
- case "provider_missing":
370
- break;
371
- case "provider_misconfigured":
372
- log.warn`Invalid provider metadata for provider ${outcome.providerName}: ${outcome.summary}`;
373
- break;
374
- }
375
- }
376
-
377
- return sources;
378
- }
@@ -1,51 +0,0 @@
1
- import { eq, and, or, isNull, gt, inArray } from "drizzle-orm";
2
-
3
- import type { GrantRule, GrantStore } from "@intx/types/authz";
4
-
5
- import type { DB } from "./client";
6
- import { grant } from "./schema/grants";
7
- import { principalRole } from "./schema/roles";
8
- import { parseGrantRow } from "./parse-row";
9
-
10
- function toGrantRule(row: typeof grant.$inferSelect): GrantRule {
11
- const parsed = parseGrantRow(row);
12
- return {
13
- id: parsed.id,
14
- resource: parsed.resource,
15
- action: parsed.action,
16
- effect: parsed.effect,
17
- origin: parsed.origin,
18
- conditions: parsed.conditions,
19
- expiresAt: parsed.expiresAt,
20
- roleId: parsed.roleId,
21
- principalId: parsed.principalId,
22
- };
23
- }
24
-
25
- export function createGrantStore(db: DB["db"]): GrantStore {
26
- return {
27
- async collectGrants(principalId, tenantId) {
28
- const roleAssignments = await db.query.principalRole.findMany({
29
- where: eq(principalRole.principalId, principalId),
30
- });
31
- const roleIds = roleAssignments.map((a) => a.roleId);
32
-
33
- const now = new Date();
34
-
35
- const ownership = [eq(grant.principalId, principalId)];
36
- if (roleIds.length > 0) {
37
- ownership.push(inArray(grant.roleId, roleIds));
38
- }
39
-
40
- const rows = await db.query.grant.findMany({
41
- where: and(
42
- eq(grant.tenantId, tenantId),
43
- or(...ownership),
44
- or(isNull(grant.expiresAt), gt(grant.expiresAt, now)),
45
- ),
46
- });
47
-
48
- return rows.map(toGrantRule);
49
- },
50
- };
51
- }
package/src/index.ts DELETED
@@ -1,32 +0,0 @@
1
- export { createDB, type DB } from "./client";
2
- export type { DBConfig } from "./config";
3
- export { runMigrations, dropSchema } from "./migrate";
4
- export { createGrantStore } from "./grant-store";
5
- export { getAncestorChain } from "./tenant-hierarchy";
6
- export {
7
- resolveProviderByName,
8
- resolveOAuthClient,
9
- resolveCredentialByName,
10
- resolveCredentialById,
11
- resolveCredentialRequirement,
12
- resolveOneCredential,
13
- resolveInstanceSources,
14
- type CredentialOutcome,
15
- ProviderMetadata,
16
- } from "./credential-resolution";
17
- export {
18
- parseAgentRow,
19
- parseAgentVersionRow,
20
- parseGrantRow,
21
- parseOfferingRow,
22
- parseCredentialRow,
23
- parseProviderRow,
24
- parseTenantRow,
25
- parseWalletRow,
26
- parseTransactionRow,
27
- parseOAuthClientRow,
28
- parseGitTokenRow,
29
- parseSidecarStatus,
30
- parseTurnPartType,
31
- } from "./parse-row";
32
- export * as schema from "./schema";