@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.
- package/LICENSE +176 -0
- package/README.md +21 -2
- package/dist/asset-resolution.d.ts +52 -0
- package/dist/asset-resolution.js +66 -0
- package/dist/catalog-resolution.d.ts +76 -0
- package/dist/catalog-resolution.js +151 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +18 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +16 -0
- package/dist/connection.d.ts +3 -0
- package/dist/connection.js +23 -0
- package/dist/credential-resolution.d.ts +110 -0
- package/dist/credential-resolution.js +116 -0
- package/dist/grant-store.d.ts +3 -0
- package/dist/grant-store.js +37 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/migrate.d.ts +36 -0
- package/dist/migrate.js +135 -0
- package/dist/model-source-resolution.d.ts +69 -0
- package/dist/model-source-resolution.js +165 -0
- package/dist/parse-row.d.ts +193 -0
- package/dist/parse-row.js +141 -0
- package/dist/pg-error.d.ts +3 -0
- package/dist/pg-error.js +19 -0
- package/dist/pricing.d.ts +15 -0
- package/dist/pricing.js +24 -0
- package/dist/schema/agent-assets.d.ts +109 -0
- package/dist/schema/agent-assets.js +15 -0
- package/dist/schema/agents.d.ts +405 -0
- package/dist/schema/agents.js +57 -0
- package/dist/schema/assets.d.ts +143 -0
- package/{src/schema/assets.ts → dist/schema/assets.js} +7 -16
- package/dist/schema/auth.d.ts +606 -0
- package/dist/schema/auth.js +47 -0
- package/dist/schema/catalog.d.ts +794 -0
- package/dist/schema/catalog.js +102 -0
- package/dist/schema/column-types.d.ts +26 -0
- package/dist/schema/column-types.js +15 -0
- package/dist/schema/credentials.d.ts +305 -0
- package/{src/schema/credentials.ts → dist/schema/credentials.js} +16 -22
- package/dist/schema/git-tokens.d.ts +256 -0
- package/{src/schema/git-tokens.ts → dist/schema/git-tokens.js} +15 -38
- package/dist/schema/grants.d.ts +211 -0
- package/dist/schema/grants.js +24 -0
- package/dist/schema/index.d.ts +21 -0
- package/dist/schema/index.js +21 -0
- package/dist/schema/instances.d.ts +262 -0
- package/dist/schema/instances.js +39 -0
- package/dist/schema/messages.d.ts +414 -0
- package/dist/schema/messages.js +71 -0
- package/dist/schema/oauth-clients.d.ts +246 -0
- package/{src/schema/oauth-clients.ts → dist/schema/oauth-clients.js} +8 -14
- package/dist/schema/offerings.d.ts +160 -0
- package/dist/schema/offerings.js +18 -0
- package/dist/schema/principals.d.ts +128 -0
- package/{src/schema/principals.ts → dist/schema/principals.js} +7 -14
- package/dist/schema/providers.d.ts +220 -0
- package/{src/schema/providers.ts → dist/schema/providers.js} +5 -11
- package/dist/schema/roles.d.ts +242 -0
- package/dist/schema/roles.js +33 -0
- package/dist/schema/session-assets.d.ts +129 -0
- package/dist/schema/session-assets.js +28 -0
- package/dist/schema/sessions.d.ts +143 -0
- package/dist/schema/sessions.js +24 -0
- package/dist/schema/sidecar.d.ts +128 -0
- package/dist/schema/sidecar.js +18 -0
- package/dist/schema/tenants.d.ts +235 -0
- package/{src/schema/tenants.ts → dist/schema/tenants.js} +10 -27
- package/dist/schema/wallets.d.ts +354 -0
- package/dist/schema/wallets.js +41 -0
- package/dist/schema/workflow-deployments.d.ts +129 -0
- package/dist/schema/workflow-deployments.js +37 -0
- package/dist/tenant-hierarchy.d.ts +22 -0
- package/dist/tenant-hierarchy.js +55 -0
- package/migrations/0029_loose_warlock.sql +1 -0
- package/migrations/0030_session_asset_audit_split.sql +5 -0
- package/migrations/0031_gigantic_nicolaos.sql +68 -0
- package/migrations/0032_lethal_misty_knight.sql +1 -0
- package/migrations/0033_old_payback.sql +1 -0
- package/migrations/0034_sleepy_songbird.sql +11 -0
- package/migrations/0035_violet_giant_man.sql +3 -0
- package/migrations/0036_sharp_the_executioner.sql +2 -0
- package/migrations/meta/0029_snapshot.json +2664 -0
- package/migrations/meta/0030_snapshot.json +2670 -0
- package/migrations/meta/0031_snapshot.json +3100 -0
- package/migrations/meta/0032_snapshot.json +3106 -0
- package/migrations/meta/0033_snapshot.json +3112 -0
- package/migrations/meta/0034_snapshot.json +3198 -0
- package/migrations/meta/0035_snapshot.json +3225 -0
- package/migrations/meta/0036_snapshot.json +3237 -0
- package/migrations/meta/_journal.json +56 -0
- package/package.json +22 -11
- package/drizzle.config.ts +0 -23
- package/src/client.ts +0 -24
- package/src/config.ts +0 -19
- package/src/connection.ts +0 -27
- package/src/credential-resolution.ts +0 -378
- package/src/grant-store.ts +0 -51
- package/src/index.ts +0 -32
- package/src/migrate.test.ts +0 -35
- package/src/migrate.ts +0 -168
- package/src/parse-row.test.ts +0 -113
- package/src/parse-row.ts +0 -185
- package/src/schema/agent-assets.ts +0 -21
- package/src/schema/agents.ts +0 -49
- package/src/schema/auth.ts +0 -51
- package/src/schema/grants.ts +0 -26
- package/src/schema/index.ts +0 -19
- package/src/schema/instances.ts +0 -36
- package/src/schema/messages.ts +0 -108
- package/src/schema/offerings.ts +0 -20
- package/src/schema/roles.ts +0 -51
- package/src/schema/session-assets.ts +0 -49
- package/src/schema/sessions.ts +0 -26
- package/src/schema/sidecar.ts +0 -14
- package/src/schema/wallets.ts +0 -44
- package/src/tenant-hierarchy.ts +0 -34
- package/tsconfig.json +0 -4
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { and, eq } from "drizzle-orm";
|
|
2
|
+
import { InvokerModelPreferences, ModelRequirements, } from "@intx/types";
|
|
3
|
+
import { listVisibleOfferings, } from "./catalog-resolution.js";
|
|
4
|
+
import { resolveCredentialById } from "./credential-resolution.js";
|
|
5
|
+
import { agent } from "./schema/agents.js";
|
|
6
|
+
function byPriority(a, b) {
|
|
7
|
+
if (a.offering.priority !== b.offering.priority) {
|
|
8
|
+
return a.offering.priority - b.offering.priority;
|
|
9
|
+
}
|
|
10
|
+
// Deterministic tiebreak so the head/defaultSource never flaps across
|
|
11
|
+
// resolutions. Equal-priority load balancing is future work.
|
|
12
|
+
return a.offering.id < b.offering.id ? -1 : 1;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Applies a provider preference over an already-priority-sorted candidate
|
|
16
|
+
* list. `pin` restricts to the named providers (ordered by the preference);
|
|
17
|
+
* `prefer` fronts the named providers in preference order and keeps the rest
|
|
18
|
+
* as fallback. With no preference the priority order stands.
|
|
19
|
+
*/
|
|
20
|
+
function applyPreference(candidates, preference) {
|
|
21
|
+
if (preference === undefined)
|
|
22
|
+
return candidates;
|
|
23
|
+
const rank = new Map(preference.order.map((name, i) => [name, i]));
|
|
24
|
+
// Partition by whether the preference names the provider, capturing the
|
|
25
|
+
// rank as we go. `ranked` only ever holds named providers, so the sort
|
|
26
|
+
// reads a concrete rank and never needs a fallback for a missing one.
|
|
27
|
+
const ranked = [];
|
|
28
|
+
const rest = [];
|
|
29
|
+
for (const offering of candidates) {
|
|
30
|
+
const position = rank.get(offering.provider.name);
|
|
31
|
+
if (position === undefined) {
|
|
32
|
+
rest.push(offering);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
ranked.push({ offering, rank: position });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ranked.sort((a, b) => a.rank - b.rank);
|
|
39
|
+
const named = ranked.map((entry) => entry.offering);
|
|
40
|
+
// `pin` drops every provider the preference did not name; `prefer` keeps
|
|
41
|
+
// the rest as fallback after the named providers.
|
|
42
|
+
return preference.mode === "pin" ? named : [...named, ...rest];
|
|
43
|
+
}
|
|
44
|
+
async function buildSource(db, tenantId, resolved) {
|
|
45
|
+
const { provider, model, offering } = resolved;
|
|
46
|
+
if (provider.credentialId === null) {
|
|
47
|
+
// No credential reference. A wallet-backed provider is a valid catalog
|
|
48
|
+
// row but not launchable in this credential-backed-only release;
|
|
49
|
+
// anything else is a misconfigured row.
|
|
50
|
+
if (provider.walletId !== null) {
|
|
51
|
+
return {
|
|
52
|
+
ok: false,
|
|
53
|
+
skip: { reason: "wallet_backed", provider: provider.name },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
skip: { reason: "provider_misconfigured", provider: provider.name },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Resolve the secret through the tenant-scoped credential resolver so a
|
|
62
|
+
// provider row referencing a credential outside the tenant's ancestor
|
|
63
|
+
// chain cannot leak that secret (INTR-203: the chain is the authority).
|
|
64
|
+
const credential = await resolveCredentialById(db, tenantId, provider.credentialId);
|
|
65
|
+
if (credential === null) {
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
skip: { reason: "credential_unresolved", provider: provider.name },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
ok: true,
|
|
73
|
+
source: {
|
|
74
|
+
id: offering.id,
|
|
75
|
+
provider: provider.plugin,
|
|
76
|
+
baseURL: provider.baseURL,
|
|
77
|
+
apiKey: credential.secret,
|
|
78
|
+
model: model.canonicalName,
|
|
79
|
+
capabilities: offering.capabilities,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Resolves an agent's model requirements against the tenant catalog into an
|
|
85
|
+
* ordered `InferenceSource[]` for the harness.
|
|
86
|
+
*
|
|
87
|
+
* For each requirement, the tenant-visible offerings for the named model are
|
|
88
|
+
* filtered by the required capabilities, ordered by catalog priority, then
|
|
89
|
+
* reordered by the creator preference and finally the invoker preference
|
|
90
|
+
* (invoker preferences key on the canonical model name). Each surviving
|
|
91
|
+
* offering is resolved to a credential-backed source; offerings that cannot
|
|
92
|
+
* produce one are skipped. A required model that yields no source makes the
|
|
93
|
+
* agent unlaunchable.
|
|
94
|
+
*/
|
|
95
|
+
export async function resolveModelSources(db, tenantId, requirements, opts) {
|
|
96
|
+
if (requirements.length === 0) {
|
|
97
|
+
return { ok: false, reason: "no_requirements" };
|
|
98
|
+
}
|
|
99
|
+
const visible = await listVisibleOfferings(db, tenantId);
|
|
100
|
+
const sources = [];
|
|
101
|
+
for (const requirement of requirements) {
|
|
102
|
+
let candidates = visible
|
|
103
|
+
.filter((o) => o.model.canonicalName === requirement.model)
|
|
104
|
+
.sort(byPriority);
|
|
105
|
+
if (requirement.capabilities && requirement.capabilities.length > 0) {
|
|
106
|
+
const required = requirement.capabilities;
|
|
107
|
+
candidates = candidates.filter((o) => required.every((c) => o.offering.capabilities.includes(c)));
|
|
108
|
+
}
|
|
109
|
+
candidates = applyPreference(candidates, requirement.providers);
|
|
110
|
+
candidates = applyPreference(candidates, opts?.invokerPreferences?.[requirement.model]);
|
|
111
|
+
const skips = [];
|
|
112
|
+
const modelSources = [];
|
|
113
|
+
for (const candidate of candidates) {
|
|
114
|
+
const built = await buildSource(db, tenantId, candidate);
|
|
115
|
+
if (built.ok) {
|
|
116
|
+
modelSources.push(built.source);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
skips.push(built.skip);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (modelSources.length === 0) {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
reason: "model_unavailable",
|
|
126
|
+
model: requirement.model,
|
|
127
|
+
skips,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
sources.push(...modelSources);
|
|
131
|
+
}
|
|
132
|
+
return { ok: true, sources };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolves the ordered sources for a running instance from persisted state:
|
|
136
|
+
* the agent definition's model requirements and the invoker's launch-time
|
|
137
|
+
* preferences stored on the instance row. Launch, credential-rotation push,
|
|
138
|
+
* and sidecar reconnect all resolve through this, so a running instance's
|
|
139
|
+
* source list is a pure function of persisted state — re-resolution
|
|
140
|
+
* reproduces the launch ordering, including the invoker's reorder/restrict.
|
|
141
|
+
*/
|
|
142
|
+
export async function resolveInstanceModelSources(db, tenantId, instance) {
|
|
143
|
+
// Scope the agent lookup to the resolving tenant, matching the launch
|
|
144
|
+
// route. A cross-tenant agentId resolves to nothing rather than
|
|
145
|
+
// contributing another tenant's model names or preferences.
|
|
146
|
+
const agentRow = await db.query.agent.findFirst({
|
|
147
|
+
where: and(eq(agent.id, instance.agentId), eq(agent.tenantId, tenantId)),
|
|
148
|
+
});
|
|
149
|
+
if (agentRow === undefined) {
|
|
150
|
+
return { ok: false, reason: "no_requirements" };
|
|
151
|
+
}
|
|
152
|
+
const requirements = agentRow.modelRequirements !== null
|
|
153
|
+
? ModelRequirements.assert(agentRow.modelRequirements)
|
|
154
|
+
: [];
|
|
155
|
+
const preferences = instance.modelPreferences !== null
|
|
156
|
+
? InvokerModelPreferences.assert(instance.modelPreferences)
|
|
157
|
+
: [];
|
|
158
|
+
const invokerPreferences = {};
|
|
159
|
+
for (const preference of preferences) {
|
|
160
|
+
invokerPreferences[preference.model] = preference.providers;
|
|
161
|
+
}
|
|
162
|
+
return resolveModelSources(db, tenantId, requirements, {
|
|
163
|
+
invokerPreferences,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { agent, agentVersion, credential, gitToken, grant, modelOffering, modelProvider, oauthClient, offering, provider, tenant, transaction, turnPart, wallet } from "./schema/index.js";
|
|
2
|
+
export declare const GitTokenKindValidator: import("arktype/internal/variants/string.ts").StringType<"pat" | "svc", {}>;
|
|
3
|
+
export declare function parseAgentRow(row: typeof agent.$inferSelect): {
|
|
4
|
+
contextConfig: Record<string, unknown> | null;
|
|
5
|
+
initialState: Record<string, unknown> | null;
|
|
6
|
+
modelConfig: Record<string, unknown> | null;
|
|
7
|
+
capabilities: Record<string, unknown> | null;
|
|
8
|
+
credentialRequirements: {
|
|
9
|
+
providerName: string;
|
|
10
|
+
source: "tenant" | "creator" | "invoker";
|
|
11
|
+
scopes?: string[];
|
|
12
|
+
name?: string;
|
|
13
|
+
}[] | null;
|
|
14
|
+
modelRequirements: {
|
|
15
|
+
model: string;
|
|
16
|
+
capabilities?: ("vision" | "audio-input" | "tool-use" | "extended-thinking" | "structured-output" | "long-context" | "prompt-caching")[];
|
|
17
|
+
providers?: {
|
|
18
|
+
mode: "prefer" | "pin";
|
|
19
|
+
order: string[];
|
|
20
|
+
};
|
|
21
|
+
}[] | null;
|
|
22
|
+
grantRequirements: {
|
|
23
|
+
resource: string;
|
|
24
|
+
action: string;
|
|
25
|
+
source: "creator" | "invoker";
|
|
26
|
+
effect?: "allow" | "deny" | "ask";
|
|
27
|
+
conditions?: Record<string, unknown> | null;
|
|
28
|
+
}[] | null;
|
|
29
|
+
toolPackages: {
|
|
30
|
+
name: string;
|
|
31
|
+
version: string;
|
|
32
|
+
}[];
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
createdAt: Date;
|
|
36
|
+
updatedAt: Date;
|
|
37
|
+
tenantId: string;
|
|
38
|
+
status: "deployed" | "stopped";
|
|
39
|
+
creatorPrincipalId: string;
|
|
40
|
+
description: string | null;
|
|
41
|
+
systemPrompt: string | null;
|
|
42
|
+
currentVersion: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function parseAgentVersionRow(row: typeof agentVersion.$inferSelect): {
|
|
45
|
+
status: "active" | "inactive" | "failed";
|
|
46
|
+
id: string;
|
|
47
|
+
createdAt: Date;
|
|
48
|
+
agentId: string;
|
|
49
|
+
version: string;
|
|
50
|
+
};
|
|
51
|
+
export declare function parseGrantRow(row: typeof grant.$inferSelect): {
|
|
52
|
+
effect: "allow" | "deny" | "ask";
|
|
53
|
+
origin: "role" | "system" | "creator" | "invoker";
|
|
54
|
+
conditions: Record<string, unknown> | null;
|
|
55
|
+
id: string;
|
|
56
|
+
createdAt: Date;
|
|
57
|
+
updatedAt: Date;
|
|
58
|
+
expiresAt: Date | null;
|
|
59
|
+
tenantId: string;
|
|
60
|
+
roleId: string | null;
|
|
61
|
+
principalId: string | null;
|
|
62
|
+
resource: string;
|
|
63
|
+
action: string;
|
|
64
|
+
};
|
|
65
|
+
export declare function parseOfferingRow(row: typeof offering.$inferSelect): {
|
|
66
|
+
pricing: Record<string, unknown> | null;
|
|
67
|
+
schema: Record<string, unknown> | null;
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
createdAt: Date;
|
|
71
|
+
updatedAt: Date;
|
|
72
|
+
tenantId: string;
|
|
73
|
+
description: string | null;
|
|
74
|
+
agentId: string;
|
|
75
|
+
};
|
|
76
|
+
export declare function parseCredentialRow(row: typeof credential.$inferSelect): {
|
|
77
|
+
type: "api_key" | "oauth_token" | "certificate" | "other";
|
|
78
|
+
status: "active" | "expired" | "revoked" | "error";
|
|
79
|
+
metadata: Record<string, unknown> | null;
|
|
80
|
+
id: string;
|
|
81
|
+
name: string;
|
|
82
|
+
createdAt: Date;
|
|
83
|
+
updatedAt: Date;
|
|
84
|
+
expiresAt: Date | null;
|
|
85
|
+
providerId: string;
|
|
86
|
+
tenantId: string;
|
|
87
|
+
description: string | null;
|
|
88
|
+
principalId: string | null;
|
|
89
|
+
scopes: string[] | null;
|
|
90
|
+
oauthClientId: string | null;
|
|
91
|
+
secret: string;
|
|
92
|
+
refreshSecret: string | null;
|
|
93
|
+
};
|
|
94
|
+
export declare function parseProviderRow(row: typeof provider.$inferSelect): {
|
|
95
|
+
metadata: Record<string, unknown> | null;
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
createdAt: Date;
|
|
99
|
+
updatedAt: Date;
|
|
100
|
+
tenantId: string;
|
|
101
|
+
plugin: string;
|
|
102
|
+
authorizationUrl: string | null;
|
|
103
|
+
tokenUrl: string | null;
|
|
104
|
+
userInfoUrl: string | null;
|
|
105
|
+
scopes: string[] | null;
|
|
106
|
+
};
|
|
107
|
+
export declare function parseModelProviderRow(row: typeof modelProvider.$inferSelect): {
|
|
108
|
+
plugin: "anthropic" | "openai" | "openai-compatible" | "google-genai";
|
|
109
|
+
id: string;
|
|
110
|
+
name: string;
|
|
111
|
+
createdAt: Date;
|
|
112
|
+
updatedAt: Date;
|
|
113
|
+
tenantId: string;
|
|
114
|
+
walletId: string | null;
|
|
115
|
+
disabled: boolean;
|
|
116
|
+
baseURL: string;
|
|
117
|
+
credentialId: string | null;
|
|
118
|
+
};
|
|
119
|
+
export declare function parseModelOfferingRow(row: typeof modelOffering.$inferSelect): {
|
|
120
|
+
capabilities: ("vision" | "audio-input" | "tool-use" | "extended-thinking" | "structured-output" | "long-context" | "prompt-caching")[];
|
|
121
|
+
id: string;
|
|
122
|
+
createdAt: Date;
|
|
123
|
+
updatedAt: Date;
|
|
124
|
+
providerId: string;
|
|
125
|
+
tenantId: string;
|
|
126
|
+
disabled: boolean;
|
|
127
|
+
modelId: string;
|
|
128
|
+
priority: number;
|
|
129
|
+
deploymentTags: string[];
|
|
130
|
+
};
|
|
131
|
+
export declare function parseTenantRow(row: typeof tenant.$inferSelect): {
|
|
132
|
+
config: Record<string, unknown> | null;
|
|
133
|
+
domain: string;
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
createdAt: Date;
|
|
137
|
+
updatedAt: Date;
|
|
138
|
+
slug: string;
|
|
139
|
+
parentId: string | null;
|
|
140
|
+
};
|
|
141
|
+
export declare function parseWalletRow(row: typeof wallet.$inferSelect): {
|
|
142
|
+
backendType: "crypto" | "fiat" | "credits";
|
|
143
|
+
config: Record<string, unknown> | null;
|
|
144
|
+
id: string;
|
|
145
|
+
name: string;
|
|
146
|
+
createdAt: Date;
|
|
147
|
+
updatedAt: Date;
|
|
148
|
+
tenantId: string;
|
|
149
|
+
currency: string;
|
|
150
|
+
balance: string;
|
|
151
|
+
};
|
|
152
|
+
export declare function parseTransactionRow(row: typeof transaction.$inferSelect): {
|
|
153
|
+
direction: "inbound" | "outbound";
|
|
154
|
+
status: "failed" | "pending" | "completed";
|
|
155
|
+
id: string;
|
|
156
|
+
createdAt: Date;
|
|
157
|
+
agentId: string | null;
|
|
158
|
+
currency: string;
|
|
159
|
+
walletId: string;
|
|
160
|
+
amount: string;
|
|
161
|
+
recipientId: string | null;
|
|
162
|
+
senderId: string | null;
|
|
163
|
+
requestId: string | null;
|
|
164
|
+
};
|
|
165
|
+
export declare function parseOAuthClientRow(row: typeof oauthClient.$inferSelect): {
|
|
166
|
+
metadata: Record<string, unknown> | null;
|
|
167
|
+
id: string;
|
|
168
|
+
name: string;
|
|
169
|
+
createdAt: Date;
|
|
170
|
+
updatedAt: Date;
|
|
171
|
+
providerId: string;
|
|
172
|
+
tenantId: string;
|
|
173
|
+
clientId: string;
|
|
174
|
+
clientSecret: string;
|
|
175
|
+
redirectUris: string[] | null;
|
|
176
|
+
defaultScopes: string[] | null;
|
|
177
|
+
};
|
|
178
|
+
export declare function parseGitTokenRow(row: typeof gitToken.$inferSelect): {
|
|
179
|
+
kind: "pat" | "svc";
|
|
180
|
+
actions: ("init" | "writeTree" | "receivePack" | "createPack" | "resolveRef")[];
|
|
181
|
+
id: string;
|
|
182
|
+
name: string;
|
|
183
|
+
createdAt: Date;
|
|
184
|
+
userId: string;
|
|
185
|
+
expiresAt: Date;
|
|
186
|
+
tenantId: string | null;
|
|
187
|
+
principalId: string | null;
|
|
188
|
+
resource: string;
|
|
189
|
+
tokenHashSha256: Uint8Array<ArrayBufferLike>;
|
|
190
|
+
refPattern: string;
|
|
191
|
+
revokedAt: Date | null;
|
|
192
|
+
};
|
|
193
|
+
export declare function parseTurnPartType(partType: string): (typeof turnPart.$inferInsert)["type"];
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import { Capability, CredentialRequirement, GrantRequirement, grantEffects, grantOrigins, ModelProviderPlugin, ModelRequirements, } from "@intx/types";
|
|
3
|
+
import { RepoAction } from "@intx/types/sidecar";
|
|
4
|
+
import { ToolPackagePinArray } from "@intx/types/tool-packages";
|
|
5
|
+
const JSONObject = type("Record<string, unknown>");
|
|
6
|
+
const GrantEffectValidator = type.enumerated(...grantEffects);
|
|
7
|
+
const GrantOriginValidator = type.enumerated(...grantOrigins);
|
|
8
|
+
const agentVersionStatuses = ["active", "inactive", "failed"];
|
|
9
|
+
const AgentVersionStatusValidator = type.enumerated(...agentVersionStatuses);
|
|
10
|
+
const credentialTypes = [
|
|
11
|
+
"api_key",
|
|
12
|
+
"oauth_token",
|
|
13
|
+
"certificate",
|
|
14
|
+
"other",
|
|
15
|
+
];
|
|
16
|
+
const CredentialTypeValidator = type.enumerated(...credentialTypes);
|
|
17
|
+
const credentialStatuses = ["active", "expired", "revoked", "error"];
|
|
18
|
+
const CredentialStatusValidator = type.enumerated(...credentialStatuses);
|
|
19
|
+
const walletBackendTypes = ["crypto", "fiat", "credits"];
|
|
20
|
+
const WalletBackendTypeValidator = type.enumerated(...walletBackendTypes);
|
|
21
|
+
const transactionDirections = ["inbound", "outbound"];
|
|
22
|
+
const TransactionDirectionValidator = type.enumerated(...transactionDirections);
|
|
23
|
+
const transactionStatuses = ["pending", "completed", "failed"];
|
|
24
|
+
const TransactionStatusValidator = type.enumerated(...transactionStatuses);
|
|
25
|
+
const gitTokenKinds = ["pat", "svc"];
|
|
26
|
+
export const GitTokenKindValidator = type.enumerated(...gitTokenKinds);
|
|
27
|
+
const turnPartTypes = [
|
|
28
|
+
"text",
|
|
29
|
+
"reasoning",
|
|
30
|
+
"tool",
|
|
31
|
+
"file",
|
|
32
|
+
"error",
|
|
33
|
+
"refusal",
|
|
34
|
+
"step-start",
|
|
35
|
+
"step-finish",
|
|
36
|
+
"snapshot",
|
|
37
|
+
"patch",
|
|
38
|
+
];
|
|
39
|
+
const TurnPartTypeValidator = type.enumerated(...turnPartTypes);
|
|
40
|
+
export function parseAgentRow(row) {
|
|
41
|
+
return {
|
|
42
|
+
...row,
|
|
43
|
+
contextConfig: row.contextConfig !== null ? JSONObject.assert(row.contextConfig) : null,
|
|
44
|
+
initialState: row.initialState !== null ? JSONObject.assert(row.initialState) : null,
|
|
45
|
+
modelConfig: row.modelConfig !== null ? JSONObject.assert(row.modelConfig) : null,
|
|
46
|
+
capabilities: row.capabilities !== null ? JSONObject.assert(row.capabilities) : null,
|
|
47
|
+
credentialRequirements: row.credentialRequirements !== null
|
|
48
|
+
? CredentialRequirement.array().assert(row.credentialRequirements)
|
|
49
|
+
: null,
|
|
50
|
+
modelRequirements: row.modelRequirements !== null
|
|
51
|
+
? ModelRequirements.assert(row.modelRequirements)
|
|
52
|
+
: null,
|
|
53
|
+
grantRequirements: row.grantRequirements !== null
|
|
54
|
+
? GrantRequirement.array().assert(row.grantRequirements)
|
|
55
|
+
: null,
|
|
56
|
+
toolPackages: ToolPackagePinArray.assert(row.toolPackages),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function parseAgentVersionRow(row) {
|
|
60
|
+
return {
|
|
61
|
+
...row,
|
|
62
|
+
status: AgentVersionStatusValidator.assert(row.status),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function parseGrantRow(row) {
|
|
66
|
+
return {
|
|
67
|
+
...row,
|
|
68
|
+
effect: GrantEffectValidator.assert(row.effect),
|
|
69
|
+
origin: GrantOriginValidator.assert(row.origin),
|
|
70
|
+
conditions: row.conditions !== null ? JSONObject.assert(row.conditions) : null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function parseOfferingRow(row) {
|
|
74
|
+
return {
|
|
75
|
+
...row,
|
|
76
|
+
pricing: row.pricing !== null ? JSONObject.assert(row.pricing) : null,
|
|
77
|
+
schema: row.schema !== null ? JSONObject.assert(row.schema) : null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function parseCredentialRow(row) {
|
|
81
|
+
return {
|
|
82
|
+
...row,
|
|
83
|
+
type: CredentialTypeValidator.assert(row.type),
|
|
84
|
+
status: CredentialStatusValidator.assert(row.status),
|
|
85
|
+
metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function parseProviderRow(row) {
|
|
89
|
+
return {
|
|
90
|
+
...row,
|
|
91
|
+
metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export function parseModelProviderRow(row) {
|
|
95
|
+
return {
|
|
96
|
+
...row,
|
|
97
|
+
plugin: ModelProviderPlugin.assert(row.plugin),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function parseModelOfferingRow(row) {
|
|
101
|
+
return {
|
|
102
|
+
...row,
|
|
103
|
+
capabilities: Capability.array().assert(row.capabilities),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function parseTenantRow(row) {
|
|
107
|
+
return {
|
|
108
|
+
...row,
|
|
109
|
+
config: row.config !== null ? JSONObject.assert(row.config) : null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export function parseWalletRow(row) {
|
|
113
|
+
return {
|
|
114
|
+
...row,
|
|
115
|
+
backendType: WalletBackendTypeValidator.assert(row.backendType),
|
|
116
|
+
config: row.config !== null ? JSONObject.assert(row.config) : null,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function parseTransactionRow(row) {
|
|
120
|
+
return {
|
|
121
|
+
...row,
|
|
122
|
+
direction: TransactionDirectionValidator.assert(row.direction),
|
|
123
|
+
status: TransactionStatusValidator.assert(row.status),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export function parseOAuthClientRow(row) {
|
|
127
|
+
return {
|
|
128
|
+
...row,
|
|
129
|
+
metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export function parseGitTokenRow(row) {
|
|
133
|
+
return {
|
|
134
|
+
...row,
|
|
135
|
+
kind: GitTokenKindValidator.assert(row.kind),
|
|
136
|
+
actions: RepoAction.array().assert(row.actions),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export function parseTurnPartType(partType) {
|
|
140
|
+
return TurnPartTypeValidator.assert(partType);
|
|
141
|
+
}
|
package/dist/pg-error.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { hasCode } from "@intx/types";
|
|
2
|
+
// Postgres SQLSTATE codes. https://www.postgresql.org/docs/current/errcodes-appendix.html
|
|
3
|
+
export const PG_UNIQUE_VIOLATION = "23505";
|
|
4
|
+
export const PG_FOREIGN_KEY_VIOLATION = "23503";
|
|
5
|
+
// Extract a Postgres SQLSTATE from an error that a driver or ORM may have
|
|
6
|
+
// wrapped. postgres-js sets the code on the error it throws; Drizzle
|
|
7
|
+
// re-wraps that as the `cause` of a DrizzleQueryError, so the code can sit
|
|
8
|
+
// one or more levels down the cause chain. Walk the chain (depth-bounded so
|
|
9
|
+
// a self-referential cause cannot loop) and return the first code found.
|
|
10
|
+
export function pgErrorCode(err) {
|
|
11
|
+
let cur = err;
|
|
12
|
+
for (let depth = 0; cur != null && depth < 8; depth++) {
|
|
13
|
+
if (hasCode(cur)) {
|
|
14
|
+
return cur.code;
|
|
15
|
+
}
|
|
16
|
+
cur = cur.cause;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { modelPricing } from "./schema/catalog.js";
|
|
2
|
+
export type ModelPricingRow = typeof modelPricing.$inferSelect;
|
|
3
|
+
/**
|
|
4
|
+
* Selects the active pricing row per currency from an offering's append-only
|
|
5
|
+
* price history. For each currency, the active row is the one with the
|
|
6
|
+
* greatest `effectiveFrom` that is at or before `asOf`; rows dated after
|
|
7
|
+
* `asOf` are not yet in effect. The `(offeringId, currency, effectiveFrom)`
|
|
8
|
+
* uniqueness on the table guarantees no ties, so the selection is
|
|
9
|
+
* unambiguous.
|
|
10
|
+
*
|
|
11
|
+
* Pure: `asOf` is a parameter, never read from the clock, so the same
|
|
12
|
+
* function serves discovery (asOf = now) and historical cost attribution
|
|
13
|
+
* (asOf = the call's billing timestamp).
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveActivePrice(rows: ModelPricingRow[], asOf: Date): ModelPricingRow[];
|
package/dist/pricing.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selects the active pricing row per currency from an offering's append-only
|
|
3
|
+
* price history. For each currency, the active row is the one with the
|
|
4
|
+
* greatest `effectiveFrom` that is at or before `asOf`; rows dated after
|
|
5
|
+
* `asOf` are not yet in effect. The `(offeringId, currency, effectiveFrom)`
|
|
6
|
+
* uniqueness on the table guarantees no ties, so the selection is
|
|
7
|
+
* unambiguous.
|
|
8
|
+
*
|
|
9
|
+
* Pure: `asOf` is a parameter, never read from the clock, so the same
|
|
10
|
+
* function serves discovery (asOf = now) and historical cost attribution
|
|
11
|
+
* (asOf = the call's billing timestamp).
|
|
12
|
+
*/
|
|
13
|
+
export function resolveActivePrice(rows, asOf) {
|
|
14
|
+
const byCurrency = new Map();
|
|
15
|
+
for (const row of rows) {
|
|
16
|
+
if (row.effectiveFrom > asOf)
|
|
17
|
+
continue;
|
|
18
|
+
const current = byCurrency.get(row.currency);
|
|
19
|
+
if (current === undefined || row.effectiveFrom > current.effectiveFrom) {
|
|
20
|
+
byCurrency.set(row.currency, row);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return Array.from(byCurrency.values());
|
|
24
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export declare const agentAsset: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
2
|
+
name: "agent_asset";
|
|
3
|
+
schema: undefined;
|
|
4
|
+
columns: {
|
|
5
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
6
|
+
name: "id";
|
|
7
|
+
tableName: "agent_asset";
|
|
8
|
+
dataType: "string";
|
|
9
|
+
columnType: "PgText";
|
|
10
|
+
data: string;
|
|
11
|
+
driverParam: string;
|
|
12
|
+
notNull: true;
|
|
13
|
+
hasDefault: false;
|
|
14
|
+
isPrimaryKey: true;
|
|
15
|
+
isAutoincrement: false;
|
|
16
|
+
hasRuntimeDefault: false;
|
|
17
|
+
enumValues: [string, ...string[]];
|
|
18
|
+
baseColumn: never;
|
|
19
|
+
identity: undefined;
|
|
20
|
+
generated: undefined;
|
|
21
|
+
}, {}, {}>;
|
|
22
|
+
agentId: import("drizzle-orm/pg-core").PgColumn<{
|
|
23
|
+
name: "agent_id";
|
|
24
|
+
tableName: "agent_asset";
|
|
25
|
+
dataType: "string";
|
|
26
|
+
columnType: "PgText";
|
|
27
|
+
data: string;
|
|
28
|
+
driverParam: string;
|
|
29
|
+
notNull: true;
|
|
30
|
+
hasDefault: false;
|
|
31
|
+
isPrimaryKey: false;
|
|
32
|
+
isAutoincrement: false;
|
|
33
|
+
hasRuntimeDefault: false;
|
|
34
|
+
enumValues: [string, ...string[]];
|
|
35
|
+
baseColumn: never;
|
|
36
|
+
identity: undefined;
|
|
37
|
+
generated: undefined;
|
|
38
|
+
}, {}, {}>;
|
|
39
|
+
assetId: import("drizzle-orm/pg-core").PgColumn<{
|
|
40
|
+
name: "asset_id";
|
|
41
|
+
tableName: "agent_asset";
|
|
42
|
+
dataType: "string";
|
|
43
|
+
columnType: "PgText";
|
|
44
|
+
data: string;
|
|
45
|
+
driverParam: string;
|
|
46
|
+
notNull: true;
|
|
47
|
+
hasDefault: false;
|
|
48
|
+
isPrimaryKey: false;
|
|
49
|
+
isAutoincrement: false;
|
|
50
|
+
hasRuntimeDefault: false;
|
|
51
|
+
enumValues: [string, ...string[]];
|
|
52
|
+
baseColumn: never;
|
|
53
|
+
identity: undefined;
|
|
54
|
+
generated: undefined;
|
|
55
|
+
}, {}, {}>;
|
|
56
|
+
ref: import("drizzle-orm/pg-core").PgColumn<{
|
|
57
|
+
name: "ref";
|
|
58
|
+
tableName: "agent_asset";
|
|
59
|
+
dataType: "string";
|
|
60
|
+
columnType: "PgText";
|
|
61
|
+
data: string;
|
|
62
|
+
driverParam: string;
|
|
63
|
+
notNull: true;
|
|
64
|
+
hasDefault: false;
|
|
65
|
+
isPrimaryKey: false;
|
|
66
|
+
isAutoincrement: false;
|
|
67
|
+
hasRuntimeDefault: false;
|
|
68
|
+
enumValues: [string, ...string[]];
|
|
69
|
+
baseColumn: never;
|
|
70
|
+
identity: undefined;
|
|
71
|
+
generated: undefined;
|
|
72
|
+
}, {}, {}>;
|
|
73
|
+
accessMode: import("drizzle-orm/pg-core").PgColumn<{
|
|
74
|
+
name: "access_mode";
|
|
75
|
+
tableName: "agent_asset";
|
|
76
|
+
dataType: "string";
|
|
77
|
+
columnType: "PgText";
|
|
78
|
+
data: string;
|
|
79
|
+
driverParam: string;
|
|
80
|
+
notNull: true;
|
|
81
|
+
hasDefault: true;
|
|
82
|
+
isPrimaryKey: false;
|
|
83
|
+
isAutoincrement: false;
|
|
84
|
+
hasRuntimeDefault: false;
|
|
85
|
+
enumValues: [string, ...string[]];
|
|
86
|
+
baseColumn: never;
|
|
87
|
+
identity: undefined;
|
|
88
|
+
generated: undefined;
|
|
89
|
+
}, {}, {}>;
|
|
90
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
91
|
+
name: "created_at";
|
|
92
|
+
tableName: "agent_asset";
|
|
93
|
+
dataType: "date";
|
|
94
|
+
columnType: "PgTimestamp";
|
|
95
|
+
data: Date;
|
|
96
|
+
driverParam: string;
|
|
97
|
+
notNull: true;
|
|
98
|
+
hasDefault: true;
|
|
99
|
+
isPrimaryKey: false;
|
|
100
|
+
isAutoincrement: false;
|
|
101
|
+
hasRuntimeDefault: false;
|
|
102
|
+
enumValues: undefined;
|
|
103
|
+
baseColumn: never;
|
|
104
|
+
identity: undefined;
|
|
105
|
+
generated: undefined;
|
|
106
|
+
}, {}, {}>;
|
|
107
|
+
};
|
|
108
|
+
dialect: "pg";
|
|
109
|
+
}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { pgTable, text, timestamp, unique } from "drizzle-orm/pg-core";
|
|
2
|
+
import { agent } from "./agents.js";
|
|
3
|
+
import { asset } from "./assets.js";
|
|
4
|
+
export const agentAsset = pgTable("agent_asset", {
|
|
5
|
+
id: text("id").primaryKey(),
|
|
6
|
+
agentId: text("agent_id")
|
|
7
|
+
.notNull()
|
|
8
|
+
.references(() => agent.id, { onDelete: "cascade" }),
|
|
9
|
+
assetId: text("asset_id")
|
|
10
|
+
.notNull()
|
|
11
|
+
.references(() => asset.id, { onDelete: "cascade" }),
|
|
12
|
+
ref: text("ref").notNull(),
|
|
13
|
+
accessMode: text("access_mode").notNull().default("read-only"),
|
|
14
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
15
|
+
}, (t) => [unique("agent_asset_agent_asset").on(t.agentId, t.assetId)]);
|