@sixb/sqlite 0.1.6 → 0.1.8
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/dist/agents/rows.d.ts +7 -4
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +3 -2
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/agents/threads.d.ts.map +1 -1
- package/dist/ai-cost-groups.d.ts +5 -0
- package/dist/ai-cost-groups.d.ts.map +1 -0
- package/dist/ai-cost-storage.d.ts +2 -1
- package/dist/ai-cost-storage.d.ts.map +1 -1
- package/dist/ai-limit-storage.d.ts +35 -0
- package/dist/ai-limit-storage.d.ts.map +1 -0
- package/dist/ai-usage-storage.d.ts +1 -0
- package/dist/ai-usage-storage.d.ts.map +1 -1
- package/dist/auth-storage/access-tokens.d.ts +1 -1
- package/dist/auth-storage/access-tokens.d.ts.map +1 -1
- package/dist/auth-storage/auth-storage.d.ts +4 -1
- package/dist/auth-storage/auth-storage.d.ts.map +1 -1
- package/dist/auth-storage/device-authorizations.d.ts +29 -0
- package/dist/auth-storage/device-authorizations.d.ts.map +1 -0
- package/dist/auth-storage/rows.d.ts +19 -1
- package/dist/auth-storage/rows.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +1 -1
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/execution-storage.d.ts +3 -2
- package/dist/execution-storage.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3443 -789
- package/dist/index.js.map +29 -20
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/index.d.ts +3 -0
- package/dist/objects/index.d.ts.map +1 -0
- package/dist/{object-query-compiler.d.ts → objects/query-compiler.d.ts} +16 -1
- package/dist/objects/query-compiler.d.ts.map +1 -0
- package/dist/objects/read-scope.d.ts +17 -0
- package/dist/objects/read-scope.d.ts.map +1 -0
- package/dist/objects/reader.d.ts +51 -0
- package/dist/objects/reader.d.ts.map +1 -0
- package/dist/objects/rows.d.ts +33 -0
- package/dist/objects/rows.d.ts.map +1 -0
- package/dist/objects/selected-reader.d.ts +9 -0
- package/dist/objects/selected-reader.d.ts.map +1 -0
- package/dist/{object-storage.d.ts → objects/storage.d.ts} +12 -9
- package/dist/objects/storage.d.ts.map +1 -0
- package/dist/share-grant-storage.d.ts +20 -0
- package/dist/share-grant-storage.d.ts.map +1 -0
- package/dist/share-session-storage.d.ts +19 -0
- package/dist/share-session-storage.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +1 -0
- package/dist/storage-errors.d.ts.map +1 -1
- package/dist/transactions.d.ts +8 -0
- package/dist/transactions.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/rows.ts +36 -9
- package/src/agents/runs.ts +152 -13
- package/src/agents/threads.ts +2 -17
- package/src/ai-cost-groups.ts +100 -0
- package/src/ai-cost-storage.ts +67 -25
- package/src/ai-limit-storage.ts +981 -0
- package/src/ai-usage-storage.ts +24 -1
- package/src/auth-storage/access-tokens.ts +77 -68
- package/src/auth-storage/auth-storage.ts +80 -1
- package/src/auth-storage/device-authorizations.ts +153 -0
- package/src/auth-storage/rows.ts +41 -0
- package/src/auth-storage/shared.ts +1 -0
- package/src/execution-storage.ts +22 -3
- package/src/index.ts +24 -3
- package/src/migrations/029-model-accounting.sql +79 -0
- package/src/migrations/030-ai-usage-limits.sql +100 -0
- package/src/migrations/031-subagent-runs.sql +231 -0
- package/src/migrations/032-conversation-run-spec.sql +78 -0
- package/src/migrations/033-retire-agent-definitions.sql +89 -0
- package/src/migrations/034-device-authorizations.sql +22 -0
- package/src/migrations/035-share-grants.sql +66 -0
- package/src/migrations/036-share-sessions.sql +226 -0
- package/src/migrations.ts +22 -0
- package/src/objects/index.ts +2 -0
- package/src/{object-query-compiler.ts → objects/query-compiler.ts} +104 -54
- package/src/objects/read-scope.ts +316 -0
- package/src/objects/reader.ts +526 -0
- package/src/objects/rows.ts +123 -0
- package/src/objects/selected-reader.ts +119 -0
- package/src/objects/storage.ts +296 -0
- package/src/share-grant-storage.ts +252 -0
- package/src/share-session-storage.ts +189 -0
- package/src/storage-errors.ts +4 -0
- package/src/transactions.ts +32 -0
- package/src/workflow-run-storage.ts +8 -8
- package/dist/object-query-compiler.d.ts.map +0 -1
- package/dist/object-storage.d.ts.map +0 -1
- package/src/object-storage.ts +0 -709
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { ProviderMaterializationTransactionLifecycle } from "@sixb/core/internal
|
|
|
13
13
|
import {
|
|
14
14
|
createAgentOperationScope,
|
|
15
15
|
createAuthOperationScope,
|
|
16
|
+
createObjectOperationScope,
|
|
16
17
|
createOntologyOperationScope,
|
|
17
18
|
createOperationScopedFacade,
|
|
18
19
|
createStorageOperationScope,
|
|
@@ -20,14 +21,18 @@ import {
|
|
|
20
21
|
} from "@sixb/core/internal/storage-operation-scope"
|
|
21
22
|
import {
|
|
22
23
|
type AiCostStorage,
|
|
24
|
+
type AiLimitStorage,
|
|
23
25
|
type AiUsageStorage,
|
|
24
26
|
createTransactionStorageProxy,
|
|
27
|
+
type ShareGrantStorage,
|
|
28
|
+
type ShareSessionStorage,
|
|
25
29
|
StorageTransactionError,
|
|
26
30
|
throwNestedStorageTransaction,
|
|
27
31
|
} from "@sixb/core/storage"
|
|
28
32
|
import { SqliteActionRunStorage } from "./action-run-storage"
|
|
29
33
|
import { SqliteAgentStorage } from "./agents"
|
|
30
34
|
import { SqliteAiCostStorage } from "./ai-cost-storage"
|
|
35
|
+
import { SqliteAiLimitStorage } from "./ai-limit-storage"
|
|
31
36
|
import { SqliteAiUsageStorage } from "./ai-usage-storage"
|
|
32
37
|
import { SqliteAuthStorage } from "./auth-storage"
|
|
33
38
|
import { SqliteConnectorConnectionStorage } from "./connector-connection-storage"
|
|
@@ -37,11 +42,13 @@ import {
|
|
|
37
42
|
installFreshSqliteSchema,
|
|
38
43
|
sqliteStoragePath,
|
|
39
44
|
} from "./migrations"
|
|
40
|
-
import { SqliteObjectStorage } from "./
|
|
45
|
+
import { SqliteObjectStorage } from "./objects"
|
|
41
46
|
import { SqliteOntologyStorage, type SqliteOntologyTransactionContext } from "./ontology-storage"
|
|
42
47
|
import { SqlitePipelineRunStorage } from "./pipeline-run-storage"
|
|
43
48
|
import { SqliteProjectionRunStorage } from "./projection-run-storage"
|
|
44
49
|
import { SqliteRulesStorage } from "./rules-storage"
|
|
50
|
+
import { SqliteShareGrantStorage } from "./share-grant-storage"
|
|
51
|
+
import { SqliteShareSessionStorage } from "./share-session-storage"
|
|
45
52
|
import { SqliteSyncRunStorage } from "./sync-run-storage"
|
|
46
53
|
import { registerSqliteStorageTestingAdapter } from "./testing"
|
|
47
54
|
import { SqliteTimeseriesStorage } from "./timeseries-storage"
|
|
@@ -84,6 +91,7 @@ export class SqliteStorage implements MigrationCapableStorage {
|
|
|
84
91
|
readonly agents: SqliteAgentStorage
|
|
85
92
|
readonly aiUsage: AiUsageStorage
|
|
86
93
|
readonly aiCosts: AiCostStorage
|
|
94
|
+
readonly aiLimits: AiLimitStorage
|
|
87
95
|
readonly actionRuns: SqliteActionRunStorage
|
|
88
96
|
readonly pipelineRuns: SqlitePipelineRunStorage
|
|
89
97
|
readonly syncRuns: SqliteSyncRunStorage
|
|
@@ -93,6 +101,8 @@ export class SqliteStorage implements MigrationCapableStorage {
|
|
|
93
101
|
readonly timeseries: Storage["timeseries"]
|
|
94
102
|
readonly webhookRuns: SqliteWebhookRunStorage
|
|
95
103
|
readonly rules: SqliteRulesStorage
|
|
104
|
+
readonly shareGrants: ShareGrantStorage
|
|
105
|
+
readonly shareSessions: ShareSessionStorage
|
|
96
106
|
readonly connectorConnections: SqliteConnectorConnectionStorage
|
|
97
107
|
readonly migrators: readonly StorageMigrator[]
|
|
98
108
|
|
|
@@ -140,13 +150,14 @@ export class SqliteStorage implements MigrationCapableStorage {
|
|
|
140
150
|
const readTimeseries = path
|
|
141
151
|
? new SqliteTimeseriesStorage({ connection: this.readConnection })
|
|
142
152
|
: stores.timeseries
|
|
143
|
-
this.objects =
|
|
153
|
+
this.objects = createObjectOperationScope(readObjects, readScope)
|
|
144
154
|
this.ontology = createOntologyOperationScope(stores.ontology, ontologyScope)
|
|
145
155
|
this.auth = createAuthOperationScope(stores.auth, scope)
|
|
146
156
|
this.executions = createOperationScopedFacade(stores.executions, scope)
|
|
147
157
|
this.agents = createAgentOperationScope(stores.agents, scope)
|
|
148
158
|
this.aiUsage = createOperationScopedFacade(stores.aiUsage, scope)
|
|
149
159
|
this.aiCosts = createOperationScopedFacade(stores.aiCosts, scope)
|
|
160
|
+
this.aiLimits = createOperationScopedFacade(stores.aiLimits, scope)
|
|
150
161
|
this.actionRuns = createOperationScopedFacade(stores.actionRuns, scope)
|
|
151
162
|
this.pipelineRuns = createOperationScopedFacade(stores.pipelineRuns, scope)
|
|
152
163
|
this.timeseries = createOperationScopedFacade(readTimeseries, readScope)
|
|
@@ -156,6 +167,8 @@ export class SqliteStorage implements MigrationCapableStorage {
|
|
|
156
167
|
this.workflowInterventions = createOperationScopedFacade(stores.workflowInterventions, scope)
|
|
157
168
|
this.webhookRuns = createOperationScopedFacade(stores.webhookRuns, scope)
|
|
158
169
|
this.rules = createOperationScopedFacade(stores.rules, scope)
|
|
170
|
+
this.shareGrants = createOperationScopedFacade(stores.shareGrants, scope)
|
|
171
|
+
this.shareSessions = createOperationScopedFacade(stores.shareSessions, scope)
|
|
159
172
|
this.connectorConnections = createOperationScopedFacade(stores.connectorConnections, scope)
|
|
160
173
|
this.migrators = options.path ? createSqliteStorageMigrators(options.path) : []
|
|
161
174
|
registerSqliteStorageTestingAdapter(this, (durationMs) =>
|
|
@@ -290,7 +303,9 @@ function createSqliteStores(
|
|
|
290
303
|
}
|
|
291
304
|
): SqliteStoreSet {
|
|
292
305
|
const auth = new SqliteAuthStorage({ connection })
|
|
293
|
-
const
|
|
306
|
+
const shareGrants = new SqliteShareGrantStorage({ connection })
|
|
307
|
+
const shareSessions = new SqliteShareSessionStorage({ connection })
|
|
308
|
+
const executions = new SqliteExecutionStorage(connection.db, auth, shareSessions)
|
|
294
309
|
return {
|
|
295
310
|
objects: new SqliteObjectStorage({ connection }),
|
|
296
311
|
ontology: new SqliteOntologyStorage({
|
|
@@ -303,6 +318,7 @@ function createSqliteStores(
|
|
|
303
318
|
agents: new SqliteAgentStorage({ connection, executions }),
|
|
304
319
|
aiUsage: new SqliteAiUsageStorage({ connection }),
|
|
305
320
|
aiCosts: new SqliteAiCostStorage(connection),
|
|
321
|
+
aiLimits: new SqliteAiLimitStorage({ connection }),
|
|
306
322
|
actionRuns: new SqliteActionRunStorage({ connection, executions }),
|
|
307
323
|
pipelineRuns: new SqlitePipelineRunStorage({ connection, executions }),
|
|
308
324
|
timeseries: new SqliteTimeseriesStorage({ connection }),
|
|
@@ -312,6 +328,8 @@ function createSqliteStores(
|
|
|
312
328
|
workflowInterventions: new SqliteWorkflowInterventionStorage({ connection }),
|
|
313
329
|
webhookRuns: new SqliteWebhookRunStorage({ connection, executions }),
|
|
314
330
|
rules: new SqliteRulesStorage({ connection }),
|
|
331
|
+
shareGrants,
|
|
332
|
+
shareSessions,
|
|
315
333
|
connectorConnections: new SqliteConnectorConnectionStorage(connection),
|
|
316
334
|
}
|
|
317
335
|
}
|
|
@@ -324,6 +342,7 @@ interface SqliteStoreSet {
|
|
|
324
342
|
readonly agents: SqliteAgentStorage
|
|
325
343
|
readonly aiUsage: SqliteAiUsageStorage
|
|
326
344
|
readonly aiCosts: SqliteAiCostStorage
|
|
345
|
+
readonly aiLimits: SqliteAiLimitStorage
|
|
327
346
|
readonly actionRuns: SqliteActionRunStorage
|
|
328
347
|
readonly pipelineRuns: SqlitePipelineRunStorage
|
|
329
348
|
readonly syncRuns: SqliteSyncRunStorage
|
|
@@ -333,6 +352,8 @@ interface SqliteStoreSet {
|
|
|
333
352
|
readonly timeseries: SqliteTimeseriesStorage
|
|
334
353
|
readonly webhookRuns: SqliteWebhookRunStorage
|
|
335
354
|
readonly rules: SqliteRulesStorage
|
|
355
|
+
readonly shareGrants: SqliteShareGrantStorage
|
|
356
|
+
readonly shareSessions: SqliteShareSessionStorage
|
|
336
357
|
readonly connectorConnections: SqliteConnectorConnectionStorage
|
|
337
358
|
}
|
|
338
359
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
-- Call-time model configuration and provider identity. Historical identity remains unknown.
|
|
2
|
+
ALTER TABLE ai_model_call_usage
|
|
3
|
+
ADD COLUMN requested_reasoning TEXT
|
|
4
|
+
CHECK (
|
|
5
|
+
requested_reasoning IS NULL OR (
|
|
6
|
+
json_valid(requested_reasoning) AND
|
|
7
|
+
json_type(requested_reasoning) IN ('text', 'object')
|
|
8
|
+
)
|
|
9
|
+
);
|
|
10
|
+
ALTER TABLE ai_model_call_usage ADD COLUMN provider_ids TEXT
|
|
11
|
+
CHECK (provider_ids IS NULL OR json_valid(provider_ids));
|
|
12
|
+
|
|
13
|
+
-- Upgrade the shipped valuation reason while retaining the selected-cost projection.
|
|
14
|
+
CREATE TABLE ai_model_call_valuations_next (
|
|
15
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
16
|
+
usage_record_id TEXT NOT NULL CHECK (length(trim(usage_record_id)) > 0),
|
|
17
|
+
status TEXT NOT NULL CHECK (status IN ('rated', 'unpriceable')),
|
|
18
|
+
provider_id TEXT CHECK (provider_id IS NULL OR length(trim(provider_id)) > 0),
|
|
19
|
+
model_id TEXT CHECK (model_id IS NULL OR length(trim(model_id)) > 0),
|
|
20
|
+
currency TEXT CHECK (
|
|
21
|
+
currency IS NULL OR (length(currency) = 3 AND currency GLOB '[A-Z][A-Z][A-Z]')
|
|
22
|
+
),
|
|
23
|
+
amount_nanos INTEGER CHECK (
|
|
24
|
+
amount_nanos IS NULL OR (typeof(amount_nanos) = 'integer' AND amount_nanos >= 0)
|
|
25
|
+
),
|
|
26
|
+
reason TEXT CHECK (
|
|
27
|
+
reason IS NULL OR reason IN (
|
|
28
|
+
'missingBillingIdentity',
|
|
29
|
+
'missingRateCard',
|
|
30
|
+
'missingUsageMeter',
|
|
31
|
+
'unsupportedPricingDimension',
|
|
32
|
+
'invalidUsageForFormula'
|
|
33
|
+
)
|
|
34
|
+
),
|
|
35
|
+
details TEXT NOT NULL CHECK (json_valid(details) AND json_type(details) = 'object'),
|
|
36
|
+
rated_at TEXT NOT NULL CHECK (length(trim(rated_at)) > 0),
|
|
37
|
+
PRIMARY KEY (project_id, usage_record_id),
|
|
38
|
+
FOREIGN KEY (project_id, usage_record_id)
|
|
39
|
+
REFERENCES ai_model_call_usage(project_id, id)
|
|
40
|
+
ON DELETE RESTRICT,
|
|
41
|
+
CHECK (
|
|
42
|
+
(
|
|
43
|
+
status = 'rated'
|
|
44
|
+
AND provider_id IS NOT NULL
|
|
45
|
+
AND model_id IS NOT NULL
|
|
46
|
+
AND currency IS NOT NULL
|
|
47
|
+
AND amount_nanos IS NOT NULL
|
|
48
|
+
AND reason IS NULL
|
|
49
|
+
)
|
|
50
|
+
OR
|
|
51
|
+
(
|
|
52
|
+
status = 'unpriceable'
|
|
53
|
+
AND currency IS NULL
|
|
54
|
+
AND amount_nanos IS NULL
|
|
55
|
+
AND reason IS NOT NULL
|
|
56
|
+
AND (
|
|
57
|
+
(reason = 'missingBillingIdentity' AND provider_id IS NULL AND model_id IS NULL)
|
|
58
|
+
OR
|
|
59
|
+
(reason <> 'missingBillingIdentity' AND provider_id IS NOT NULL AND model_id IS NOT NULL)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
INSERT INTO ai_model_call_valuations_next (
|
|
66
|
+
project_id, usage_record_id, status, provider_id, model_id,
|
|
67
|
+
currency, amount_nanos, reason, details, rated_at
|
|
68
|
+
)
|
|
69
|
+
SELECT project_id, usage_record_id, status, provider_id, model_id,
|
|
70
|
+
currency, amount_nanos,
|
|
71
|
+
CASE WHEN reason = 'missingCatalogEntry' THEN 'missingRateCard' ELSE reason END,
|
|
72
|
+
details, rated_at
|
|
73
|
+
FROM ai_model_call_valuations;
|
|
74
|
+
|
|
75
|
+
DROP TABLE ai_model_call_valuations;
|
|
76
|
+
ALTER TABLE ai_model_call_valuations_next RENAME TO ai_model_call_valuations;
|
|
77
|
+
|
|
78
|
+
CREATE INDEX idx_ai_model_call_valuations_summary
|
|
79
|
+
ON ai_model_call_valuations (project_id, status, currency, usage_record_id);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
CREATE TABLE ai_usage_limits (
|
|
2
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
4
|
+
subject_type TEXT NOT NULL CHECK (
|
|
5
|
+
subject_type IN ('project', 'group', 'user', 'serviceAccount')
|
|
6
|
+
),
|
|
7
|
+
subject_id TEXT NOT NULL CHECK (
|
|
8
|
+
(subject_type = 'project' AND subject_id = '')
|
|
9
|
+
OR (subject_type <> 'project' AND length(trim(subject_id)) > 0)
|
|
10
|
+
),
|
|
11
|
+
meter TEXT NOT NULL CHECK (meter IN ('tokens.total', 'cost.catalogEstimated')),
|
|
12
|
+
currency TEXT NOT NULL CHECK (
|
|
13
|
+
(meter = 'tokens.total' AND currency = '')
|
|
14
|
+
OR (meter = 'cost.catalogEstimated' AND currency = 'USD')
|
|
15
|
+
),
|
|
16
|
+
limit_amount TEXT NOT NULL CHECK (
|
|
17
|
+
limit_amount = '0'
|
|
18
|
+
OR (
|
|
19
|
+
limit_amount NOT GLOB '*[^0-9]*'
|
|
20
|
+
AND substr(limit_amount, 1, 1) BETWEEN '1' AND '9'
|
|
21
|
+
)
|
|
22
|
+
),
|
|
23
|
+
period_kind TEXT NOT NULL CHECK (period_kind = 'calendarMonth'),
|
|
24
|
+
enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
|
|
25
|
+
created_at TEXT NOT NULL,
|
|
26
|
+
updated_at TEXT NOT NULL,
|
|
27
|
+
PRIMARY KEY (project_id, id),
|
|
28
|
+
UNIQUE (project_id, subject_type, subject_id, meter, currency)
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX idx_ai_usage_limits_project_enabled
|
|
32
|
+
ON ai_usage_limits (project_id, enabled, subject_type, subject_id, meter, currency);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE ai_usage_limit_periods (
|
|
35
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
36
|
+
subject_type TEXT NOT NULL CHECK (
|
|
37
|
+
subject_type IN ('project', 'group', 'user', 'serviceAccount')
|
|
38
|
+
),
|
|
39
|
+
subject_id TEXT NOT NULL CHECK (
|
|
40
|
+
(subject_type = 'project' AND subject_id = '')
|
|
41
|
+
OR (subject_type <> 'project' AND length(trim(subject_id)) > 0)
|
|
42
|
+
),
|
|
43
|
+
meter TEXT NOT NULL CHECK (meter IN ('tokens.total', 'cost.catalogEstimated')),
|
|
44
|
+
currency TEXT NOT NULL CHECK (
|
|
45
|
+
(meter = 'tokens.total' AND currency = '')
|
|
46
|
+
OR (meter = 'cost.catalogEstimated' AND currency = 'USD')
|
|
47
|
+
),
|
|
48
|
+
period_start TEXT NOT NULL,
|
|
49
|
+
period_end TEXT NOT NULL,
|
|
50
|
+
actual_amount TEXT NOT NULL DEFAULT '0',
|
|
51
|
+
reserved_amount TEXT NOT NULL DEFAULT '0',
|
|
52
|
+
unknown_amount TEXT NOT NULL DEFAULT '0',
|
|
53
|
+
accounting_status TEXT NOT NULL DEFAULT 'complete' CHECK (
|
|
54
|
+
accounting_status IN ('complete', 'unavailable')
|
|
55
|
+
),
|
|
56
|
+
updated_at TEXT NOT NULL,
|
|
57
|
+
PRIMARY KEY (
|
|
58
|
+
project_id, subject_type, subject_id, meter, currency, period_start
|
|
59
|
+
)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX idx_ai_usage_limit_periods_subject_period
|
|
63
|
+
ON ai_usage_limit_periods (
|
|
64
|
+
project_id, subject_type, subject_id, period_start, period_end, meter, currency
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
CREATE TABLE ai_model_call_reservations (
|
|
68
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
69
|
+
execution_id TEXT NOT NULL CHECK (length(trim(execution_id)) > 0),
|
|
70
|
+
attempt INTEGER NOT NULL CHECK (attempt >= 1),
|
|
71
|
+
call_id TEXT NOT NULL CHECK (length(trim(call_id)) > 0),
|
|
72
|
+
buckets TEXT NOT NULL CHECK (json_valid(buckets) AND json_type(buckets) = 'array'),
|
|
73
|
+
request_key TEXT NOT NULL,
|
|
74
|
+
period_start TEXT NOT NULL,
|
|
75
|
+
period_end TEXT NOT NULL,
|
|
76
|
+
state TEXT NOT NULL CHECK (state IN ('active', 'reconciled', 'unknown')),
|
|
77
|
+
usage_record_id TEXT,
|
|
78
|
+
reserved_at TEXT NOT NULL,
|
|
79
|
+
updated_at TEXT NOT NULL,
|
|
80
|
+
PRIMARY KEY (project_id, execution_id, attempt, call_id),
|
|
81
|
+
FOREIGN KEY (project_id, execution_id)
|
|
82
|
+
REFERENCES executions(project_id, id)
|
|
83
|
+
ON DELETE RESTRICT,
|
|
84
|
+
FOREIGN KEY (project_id, usage_record_id)
|
|
85
|
+
REFERENCES ai_model_call_usage(project_id, id)
|
|
86
|
+
ON DELETE RESTRICT,
|
|
87
|
+
CHECK (
|
|
88
|
+
(
|
|
89
|
+
state = 'reconciled'
|
|
90
|
+
AND usage_record_id IS NOT NULL
|
|
91
|
+
)
|
|
92
|
+
OR (
|
|
93
|
+
state <> 'reconciled'
|
|
94
|
+
AND usage_record_id IS NULL
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
CREATE INDEX idx_ai_model_call_reservations_active
|
|
100
|
+
ON ai_model_call_reservations (project_id, state, period_end, execution_id, attempt, call_id);
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
-- SQLite cannot alter a CHECK constraint in place. Rebuild the execution table to align SQL with
|
|
2
|
+
-- the durable Agent authority model: managed service account or exact inherited user/disabled.
|
|
3
|
+
CREATE TABLE executions_v3 (
|
|
4
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
5
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
6
|
+
executor_kind TEXT NOT NULL CHECK (
|
|
7
|
+
executor_kind IN (
|
|
8
|
+
'request', 'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow',
|
|
9
|
+
'agent', 'kernel'
|
|
10
|
+
)
|
|
11
|
+
),
|
|
12
|
+
executor_id TEXT NOT NULL CHECK (length(trim(executor_id)) > 0),
|
|
13
|
+
source_kind TEXT NOT NULL CHECK (
|
|
14
|
+
source_kind IN ('http', 'webhook', 'schedule', 'event', 'datasetVersion', 'execution')
|
|
15
|
+
),
|
|
16
|
+
source_id TEXT NOT NULL CHECK (length(trim(source_id)) > 0),
|
|
17
|
+
requested_by_user_id TEXT,
|
|
18
|
+
requested_by_service_account_id TEXT,
|
|
19
|
+
correlation_id TEXT NOT NULL CHECK (length(trim(correlation_id)) > 0),
|
|
20
|
+
parent_execution_id TEXT,
|
|
21
|
+
authority_kind TEXT NOT NULL CHECK (
|
|
22
|
+
authority_kind IN ('principal', 'trustedPrimitive', 'kernel', 'disabled')
|
|
23
|
+
),
|
|
24
|
+
authority_user_id TEXT,
|
|
25
|
+
authority_service_account_id TEXT,
|
|
26
|
+
authority_session_id TEXT,
|
|
27
|
+
authority_access_token_id TEXT,
|
|
28
|
+
authority_primitive_kind TEXT CHECK (
|
|
29
|
+
authority_primitive_kind IS NULL
|
|
30
|
+
OR authority_primitive_kind IN (
|
|
31
|
+
'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow'
|
|
32
|
+
)
|
|
33
|
+
),
|
|
34
|
+
authority_primitive_id TEXT,
|
|
35
|
+
authority_kernel_operation TEXT CHECK (
|
|
36
|
+
authority_kernel_operation IS NULL OR authority_kernel_operation = 'ontology.recover'
|
|
37
|
+
),
|
|
38
|
+
created_at TEXT NOT NULL,
|
|
39
|
+
PRIMARY KEY (project_id, id),
|
|
40
|
+
FOREIGN KEY (project_id, parent_execution_id) REFERENCES executions (project_id, id),
|
|
41
|
+
FOREIGN KEY (project_id, requested_by_user_id) REFERENCES auth_users (project_id, id),
|
|
42
|
+
FOREIGN KEY (project_id, requested_by_service_account_id)
|
|
43
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
44
|
+
FOREIGN KEY (project_id, authority_user_id) REFERENCES auth_users (project_id, id),
|
|
45
|
+
FOREIGN KEY (project_id, authority_service_account_id)
|
|
46
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
47
|
+
FOREIGN KEY (project_id, authority_session_id) REFERENCES auth_sessions (project_id, id),
|
|
48
|
+
FOREIGN KEY (project_id, authority_access_token_id)
|
|
49
|
+
REFERENCES auth_access_tokens (project_id, id),
|
|
50
|
+
CHECK ((requested_by_user_id IS NOT NULL) + (requested_by_service_account_id IS NOT NULL) <= 1),
|
|
51
|
+
CHECK (
|
|
52
|
+
(source_kind = 'execution' AND parent_execution_id = source_id)
|
|
53
|
+
OR (source_kind <> 'execution' AND parent_execution_id IS NULL)
|
|
54
|
+
),
|
|
55
|
+
CHECK (
|
|
56
|
+
(
|
|
57
|
+
authority_kind = 'principal'
|
|
58
|
+
AND (authority_user_id IS NOT NULL) + (authority_service_account_id IS NOT NULL) = 1
|
|
59
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) <= 1
|
|
60
|
+
AND (authority_session_id IS NULL OR authority_user_id IS NOT NULL)
|
|
61
|
+
AND authority_primitive_kind IS NULL
|
|
62
|
+
AND authority_primitive_id IS NULL
|
|
63
|
+
AND authority_kernel_operation IS NULL
|
|
64
|
+
)
|
|
65
|
+
OR (
|
|
66
|
+
authority_kind = 'trustedPrimitive'
|
|
67
|
+
AND authority_user_id IS NULL
|
|
68
|
+
AND authority_service_account_id IS NULL
|
|
69
|
+
AND authority_session_id IS NULL
|
|
70
|
+
AND authority_access_token_id IS NULL
|
|
71
|
+
AND authority_primitive_kind IS NOT NULL
|
|
72
|
+
AND authority_primitive_id IS NOT NULL
|
|
73
|
+
AND length(trim(authority_primitive_id)) > 0
|
|
74
|
+
AND authority_kernel_operation IS NULL
|
|
75
|
+
)
|
|
76
|
+
OR (
|
|
77
|
+
authority_kind = 'kernel'
|
|
78
|
+
AND authority_user_id IS NULL
|
|
79
|
+
AND authority_service_account_id IS NULL
|
|
80
|
+
AND authority_session_id IS NULL
|
|
81
|
+
AND authority_access_token_id IS NULL
|
|
82
|
+
AND authority_primitive_kind IS NULL
|
|
83
|
+
AND authority_primitive_id IS NULL
|
|
84
|
+
AND authority_kernel_operation IS NOT NULL
|
|
85
|
+
)
|
|
86
|
+
OR (
|
|
87
|
+
authority_kind = 'disabled'
|
|
88
|
+
AND authority_user_id IS NULL
|
|
89
|
+
AND authority_service_account_id IS NULL
|
|
90
|
+
AND authority_session_id IS NULL
|
|
91
|
+
AND authority_access_token_id IS NULL
|
|
92
|
+
AND authority_primitive_kind IS NULL
|
|
93
|
+
AND authority_primitive_id IS NULL
|
|
94
|
+
AND authority_kernel_operation IS NULL
|
|
95
|
+
)
|
|
96
|
+
),
|
|
97
|
+
CHECK (
|
|
98
|
+
(
|
|
99
|
+
executor_kind = 'request'
|
|
100
|
+
AND source_kind = 'http'
|
|
101
|
+
AND executor_id = source_id
|
|
102
|
+
AND (
|
|
103
|
+
(
|
|
104
|
+
authority_kind = 'principal'
|
|
105
|
+
AND requested_by_user_id IS authority_user_id
|
|
106
|
+
AND requested_by_service_account_id IS authority_service_account_id
|
|
107
|
+
)
|
|
108
|
+
OR (
|
|
109
|
+
authority_kind = 'disabled'
|
|
110
|
+
AND requested_by_user_id IS NULL
|
|
111
|
+
AND requested_by_service_account_id IS NULL
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
OR (
|
|
116
|
+
executor_kind IN ('action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow')
|
|
117
|
+
AND authority_kind = 'trustedPrimitive'
|
|
118
|
+
AND executor_kind = authority_primitive_kind
|
|
119
|
+
)
|
|
120
|
+
OR (
|
|
121
|
+
executor_kind = 'agent'
|
|
122
|
+
AND source_kind = 'execution'
|
|
123
|
+
AND (
|
|
124
|
+
(
|
|
125
|
+
authority_kind = 'principal'
|
|
126
|
+
AND authority_service_account_id IS NOT NULL
|
|
127
|
+
AND authority_session_id IS NULL
|
|
128
|
+
AND authority_access_token_id IS NULL
|
|
129
|
+
)
|
|
130
|
+
OR (
|
|
131
|
+
authority_kind = 'principal'
|
|
132
|
+
AND authority_user_id IS NOT NULL
|
|
133
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) = 1
|
|
134
|
+
)
|
|
135
|
+
OR authority_kind = 'disabled'
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
OR (executor_kind = 'kernel' AND authority_kind = 'kernel')
|
|
139
|
+
)
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
INSERT INTO executions_v3 SELECT * FROM executions;
|
|
143
|
+
DROP TABLE executions;
|
|
144
|
+
ALTER TABLE executions_v3 RENAME TO executions;
|
|
145
|
+
|
|
146
|
+
CREATE TABLE agent_runs_v3 (
|
|
147
|
+
project_id TEXT NOT NULL,
|
|
148
|
+
id TEXT NOT NULL,
|
|
149
|
+
execution_id TEXT NOT NULL,
|
|
150
|
+
kind TEXT NOT NULL DEFAULT 'conversation' CHECK (kind IN ('conversation', 'subagent')),
|
|
151
|
+
thread_id TEXT,
|
|
152
|
+
agent_id TEXT,
|
|
153
|
+
trigger_message_id TEXT,
|
|
154
|
+
parent_run_id TEXT,
|
|
155
|
+
spawn_key TEXT,
|
|
156
|
+
spec TEXT CHECK (spec IS NULL OR json_valid(spec)),
|
|
157
|
+
result TEXT CHECK (result IS NULL OR json_valid(result)),
|
|
158
|
+
requester_group_ids TEXT NOT NULL DEFAULT '[]'
|
|
159
|
+
CHECK (json_valid(requester_group_ids) AND json_type(requester_group_ids) = 'array'),
|
|
160
|
+
status TEXT NOT NULL CHECK (
|
|
161
|
+
status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')
|
|
162
|
+
),
|
|
163
|
+
model_id TEXT,
|
|
164
|
+
finish_reason TEXT,
|
|
165
|
+
error TEXT CHECK (error IS NULL OR json_valid(error)),
|
|
166
|
+
diagnostics TEXT,
|
|
167
|
+
attempt INTEGER NOT NULL DEFAULT 0 CHECK (attempt >= 0),
|
|
168
|
+
execution_token TEXT,
|
|
169
|
+
execution_queue_lease_expires_at TEXT,
|
|
170
|
+
created_at TEXT NOT NULL,
|
|
171
|
+
started_at TEXT,
|
|
172
|
+
completed_at TEXT,
|
|
173
|
+
PRIMARY KEY (project_id, id),
|
|
174
|
+
UNIQUE (project_id, execution_id),
|
|
175
|
+
UNIQUE (project_id, parent_run_id, spawn_key),
|
|
176
|
+
FOREIGN KEY (project_id, execution_id)
|
|
177
|
+
REFERENCES executions (project_id, id)
|
|
178
|
+
ON DELETE RESTRICT,
|
|
179
|
+
FOREIGN KEY (project_id, parent_run_id)
|
|
180
|
+
REFERENCES agent_runs_v3 (project_id, id)
|
|
181
|
+
ON DELETE RESTRICT,
|
|
182
|
+
CHECK ((execution_token IS NULL) = (execution_queue_lease_expires_at IS NULL)),
|
|
183
|
+
CHECK (
|
|
184
|
+
(
|
|
185
|
+
kind = 'conversation'
|
|
186
|
+
AND thread_id IS NOT NULL
|
|
187
|
+
AND agent_id IS NOT NULL
|
|
188
|
+
AND trigger_message_id IS NOT NULL
|
|
189
|
+
AND parent_run_id IS NULL
|
|
190
|
+
AND spawn_key IS NULL
|
|
191
|
+
AND spec IS NULL
|
|
192
|
+
AND result IS NULL
|
|
193
|
+
)
|
|
194
|
+
OR
|
|
195
|
+
(
|
|
196
|
+
kind = 'subagent'
|
|
197
|
+
AND thread_id IS NULL
|
|
198
|
+
AND agent_id IS NULL
|
|
199
|
+
AND trigger_message_id IS NULL
|
|
200
|
+
AND parent_run_id IS NOT NULL
|
|
201
|
+
AND spawn_key IS NOT NULL
|
|
202
|
+
AND spec IS NOT NULL
|
|
203
|
+
)
|
|
204
|
+
),
|
|
205
|
+
CHECK (kind <> 'subagent' OR status <> 'succeeded' OR result IS NOT NULL)
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
INSERT INTO agent_runs_v3 (
|
|
209
|
+
project_id, id, execution_id, kind, thread_id, agent_id, trigger_message_id,
|
|
210
|
+
requester_group_ids, status, model_id, finish_reason, error, diagnostics, attempt,
|
|
211
|
+
execution_token, execution_queue_lease_expires_at, created_at, started_at, completed_at
|
|
212
|
+
)
|
|
213
|
+
SELECT
|
|
214
|
+
project_id, id, execution_id, 'conversation', thread_id, agent_id, trigger_message_id,
|
|
215
|
+
requester_group_ids, status, model_id, finish_reason, error, diagnostics, attempt,
|
|
216
|
+
execution_token, execution_queue_lease_expires_at, created_at, started_at, completed_at
|
|
217
|
+
FROM agent_runs;
|
|
218
|
+
|
|
219
|
+
DROP TABLE agent_runs;
|
|
220
|
+
ALTER TABLE agent_runs_v3 RENAME TO agent_runs;
|
|
221
|
+
|
|
222
|
+
CREATE INDEX idx_agent_runs_project_started
|
|
223
|
+
ON agent_runs(project_id, COALESCE(started_at, created_at) DESC);
|
|
224
|
+
CREATE INDEX idx_agent_runs_project_thread_started
|
|
225
|
+
ON agent_runs(project_id, thread_id, COALESCE(started_at, created_at) DESC);
|
|
226
|
+
CREATE INDEX idx_agent_runs_project_agent_started
|
|
227
|
+
ON agent_runs(project_id, agent_id, COALESCE(started_at, created_at) DESC);
|
|
228
|
+
CREATE INDEX idx_agent_runs_project_status_started
|
|
229
|
+
ON agent_runs(project_id, status, COALESCE(started_at, created_at) DESC);
|
|
230
|
+
CREATE INDEX idx_agent_runs_project_parent_started
|
|
231
|
+
ON agent_runs(project_id, parent_run_id, status, COALESCE(started_at, created_at) DESC);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
CREATE TABLE agent_runs_v4 (
|
|
2
|
+
project_id TEXT NOT NULL,
|
|
3
|
+
id TEXT NOT NULL,
|
|
4
|
+
execution_id TEXT NOT NULL,
|
|
5
|
+
kind TEXT NOT NULL DEFAULT 'conversation' CHECK (kind IN ('conversation', 'subagent')),
|
|
6
|
+
thread_id TEXT,
|
|
7
|
+
agent_id TEXT,
|
|
8
|
+
trigger_message_id TEXT,
|
|
9
|
+
parent_run_id TEXT,
|
|
10
|
+
spawn_key TEXT,
|
|
11
|
+
spec TEXT CHECK (spec IS NULL OR json_valid(spec)),
|
|
12
|
+
result TEXT CHECK (result IS NULL OR json_valid(result)),
|
|
13
|
+
requester_group_ids TEXT NOT NULL DEFAULT '[]'
|
|
14
|
+
CHECK (json_valid(requester_group_ids) AND json_type(requester_group_ids) = 'array'),
|
|
15
|
+
status TEXT NOT NULL CHECK (
|
|
16
|
+
status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')
|
|
17
|
+
),
|
|
18
|
+
model_id TEXT,
|
|
19
|
+
finish_reason TEXT,
|
|
20
|
+
error TEXT CHECK (error IS NULL OR json_valid(error)),
|
|
21
|
+
diagnostics TEXT,
|
|
22
|
+
attempt INTEGER NOT NULL DEFAULT 0 CHECK (attempt >= 0),
|
|
23
|
+
execution_token TEXT,
|
|
24
|
+
execution_queue_lease_expires_at TEXT,
|
|
25
|
+
created_at TEXT NOT NULL,
|
|
26
|
+
started_at TEXT,
|
|
27
|
+
completed_at TEXT,
|
|
28
|
+
PRIMARY KEY (project_id, id),
|
|
29
|
+
UNIQUE (project_id, execution_id),
|
|
30
|
+
UNIQUE (project_id, parent_run_id, spawn_key),
|
|
31
|
+
FOREIGN KEY (project_id, execution_id)
|
|
32
|
+
REFERENCES executions (project_id, id)
|
|
33
|
+
ON DELETE RESTRICT,
|
|
34
|
+
FOREIGN KEY (project_id, parent_run_id)
|
|
35
|
+
-- Use the final name: Bun's legacy ALTER mode preserves references when foreign keys are off.
|
|
36
|
+
REFERENCES agent_runs (project_id, id)
|
|
37
|
+
ON DELETE RESTRICT,
|
|
38
|
+
CHECK ((execution_token IS NULL) = (execution_queue_lease_expires_at IS NULL)),
|
|
39
|
+
CHECK (
|
|
40
|
+
(
|
|
41
|
+
kind = 'conversation'
|
|
42
|
+
AND thread_id IS NOT NULL
|
|
43
|
+
AND agent_id IS NOT NULL
|
|
44
|
+
AND trigger_message_id IS NOT NULL
|
|
45
|
+
AND parent_run_id IS NULL
|
|
46
|
+
AND spawn_key IS NULL
|
|
47
|
+
AND result IS NULL
|
|
48
|
+
)
|
|
49
|
+
OR
|
|
50
|
+
(
|
|
51
|
+
kind = 'subagent'
|
|
52
|
+
AND thread_id IS NULL
|
|
53
|
+
AND agent_id IS NULL
|
|
54
|
+
AND trigger_message_id IS NULL
|
|
55
|
+
AND parent_run_id IS NOT NULL
|
|
56
|
+
AND spawn_key IS NOT NULL
|
|
57
|
+
AND spec IS NOT NULL
|
|
58
|
+
)
|
|
59
|
+
),
|
|
60
|
+
CHECK (kind <> 'subagent' OR status <> 'succeeded' OR result IS NOT NULL)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
INSERT INTO agent_runs_v4 SELECT * FROM agent_runs;
|
|
64
|
+
DROP TABLE agent_runs;
|
|
65
|
+
ALTER TABLE agent_runs_v4 RENAME TO agent_runs;
|
|
66
|
+
|
|
67
|
+
CREATE INDEX idx_agent_runs_project_thread_started
|
|
68
|
+
ON agent_runs (project_id, thread_id, COALESCE(started_at, created_at) DESC, id DESC);
|
|
69
|
+
CREATE INDEX idx_agent_runs_project_status_created
|
|
70
|
+
ON agent_runs (project_id, status, created_at, id);
|
|
71
|
+
CREATE INDEX idx_agent_runs_project_parent_started
|
|
72
|
+
ON agent_runs (
|
|
73
|
+
project_id,
|
|
74
|
+
parent_run_id,
|
|
75
|
+
status,
|
|
76
|
+
COALESCE(started_at, created_at) DESC,
|
|
77
|
+
id DESC
|
|
78
|
+
);
|