@cat-factory/worker 0.96.3 → 0.97.0
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/infrastructure/repositories/D1ProviderApiKeyRepository.d.ts +2 -0
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.js +34 -10
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.js.map +1 -1
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.d.ts +2 -0
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.js +25 -3
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.js.map +1 -1
- package/migrations/0058_credential_enabled_default.sql +19 -0
- package/package.json +18 -18
|
@@ -17,6 +17,8 @@ export declare class D1ProviderApiKeyRepository implements ProviderApiKeyReposit
|
|
|
17
17
|
inputTokens: number;
|
|
18
18
|
outputTokens: number;
|
|
19
19
|
}, at: number, windowMs: number): Promise<void>;
|
|
20
|
+
setEnabled(scope: ApiKeyScope, scopeId: string, id: string, enabled: boolean): Promise<void>;
|
|
21
|
+
setDefault(scope: ApiKeyScope, scopeId: string, provider: ApiKeyProvider, id: string | null): Promise<void>;
|
|
20
22
|
softDelete(scope: ApiKeyScope, scopeId: string, id: string, at: number): Promise<void>;
|
|
21
23
|
}
|
|
22
24
|
//# sourceMappingURL=D1ProviderApiKeyRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"D1ProviderApiKeyRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderApiKeyRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"D1ProviderApiKeyRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderApiKeyRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAwC3D,4EAA4E;AAC5E,qBAAa,0BAA2B,YAAW,wBAAwB;IACzE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAE/B,YAAY,EAAE,EAAE,EAAE,EAAE;QAAE,EAAE,EAAE,UAAU,CAAA;KAAE,EAErC;IAEK,WAAW,CACf,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAYjC;IAEK,WAAW,CACf,MAAM,EAAE,cAAc,EAAE,EACxB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAejC;IAEK,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAajF;IAEK,OAAO,CACX,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAQtC;IAEK,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBrD;IAEK,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtD;IAEK,cAAc,CAClB,MAAM,EAAE,cAAc,EAAE,EACxB,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA+BtC;IAEK,WAAW,CACf,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EACpD,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA4Bf;IAEK,UAAU,CACd,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAOf;IAEK,UAAU,CACd,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,EACxB,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,OAAO,CAAC,IAAI,CAAC,CAiBf;IAEK,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;CACF"}
|
|
@@ -12,6 +12,8 @@ function rowToRecord(row) {
|
|
|
12
12
|
inputTokens: row.input_tokens,
|
|
13
13
|
outputTokens: row.output_tokens,
|
|
14
14
|
requestCount: row.request_count,
|
|
15
|
+
enabled: row.enabled !== 0,
|
|
16
|
+
isDefault: row.is_default !== 0,
|
|
15
17
|
deletedAt: row.deleted_at,
|
|
16
18
|
};
|
|
17
19
|
}
|
|
@@ -42,7 +44,7 @@ export class D1ProviderApiKeyRepository {
|
|
|
42
44
|
binds.push(provider);
|
|
43
45
|
const { results } = await this.db
|
|
44
46
|
.prepare(`SELECT * FROM provider_api_keys
|
|
45
|
-
WHERE (${pairs}) AND provider = ? AND deleted_at IS NULL
|
|
47
|
+
WHERE (${pairs}) AND provider = ? AND deleted_at IS NULL AND enabled = 1
|
|
46
48
|
ORDER BY created_at ASC`)
|
|
47
49
|
.bind(...binds)
|
|
48
50
|
.all();
|
|
@@ -57,7 +59,7 @@ export class D1ProviderApiKeyRepository {
|
|
|
57
59
|
binds.push(s.scope, s.scopeId);
|
|
58
60
|
const { results } = await this.db
|
|
59
61
|
.prepare(`SELECT DISTINCT provider FROM provider_api_keys
|
|
60
|
-
WHERE (${pairs}) AND deleted_at IS NULL`)
|
|
62
|
+
WHERE (${pairs}) AND deleted_at IS NULL AND enabled = 1`)
|
|
61
63
|
.bind(...binds)
|
|
62
64
|
.all();
|
|
63
65
|
return (results ?? []).map((r) => r.provider);
|
|
@@ -73,9 +75,9 @@ export class D1ProviderApiKeyRepository {
|
|
|
73
75
|
await this.db
|
|
74
76
|
.prepare(`INSERT INTO provider_api_keys
|
|
75
77
|
(id, scope, scope_id, provider, label, key_cipher, created_at, last_used_at,
|
|
76
|
-
window_started_at, input_tokens, output_tokens, request_count, deleted_at)
|
|
77
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`)
|
|
78
|
-
.bind(record.id, record.scope, record.scopeId, record.provider, record.label, record.keyCipher, record.createdAt, record.lastUsedAt, record.windowStartedAt, record.inputTokens, record.outputTokens, record.requestCount)
|
|
78
|
+
window_started_at, input_tokens, output_tokens, request_count, enabled, is_default, deleted_at)
|
|
79
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`)
|
|
80
|
+
.bind(record.id, record.scope, record.scopeId, record.provider, record.label, record.keyCipher, record.createdAt, record.lastUsedAt, record.windowStartedAt, record.inputTokens, record.outputTokens, record.requestCount, record.enabled ? 1 : 0, record.isDefault ? 1 : 0)
|
|
79
81
|
.run();
|
|
80
82
|
}
|
|
81
83
|
async markLeased(id, at) {
|
|
@@ -89,10 +91,11 @@ export class D1ProviderApiKeyRepository {
|
|
|
89
91
|
return null;
|
|
90
92
|
const pairs = scopes.map(() => '(scope = ? AND scope_id = ?)').join(' OR ');
|
|
91
93
|
// Select-and-mark in ONE statement: the winner is picked by the same policy as
|
|
92
|
-
// `chooseToken` (
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
94
|
+
// `chooseToken` — a pinned default (is_default = 1) wins first, then least rolling-window
|
|
95
|
+
// usage, then least-recently-leased (SQLite sorts NULL last_used_at first under ASC,
|
|
96
|
+
// matching "never leased first"), then oldest. DISABLED keys are excluded. `last_used_at`
|
|
97
|
+
// is stamped in the same write. D1 serialises writes, so a concurrent lease's sub-select
|
|
98
|
+
// sees this stamp and rotates to a different key instead of double-leasing.
|
|
96
99
|
const binds = [now];
|
|
97
100
|
for (const s of scopes)
|
|
98
101
|
binds.push(s.scope, s.scopeId);
|
|
@@ -101,8 +104,9 @@ export class D1ProviderApiKeyRepository {
|
|
|
101
104
|
.prepare(`UPDATE provider_api_keys SET last_used_at = ?
|
|
102
105
|
WHERE id = (
|
|
103
106
|
SELECT id FROM provider_api_keys
|
|
104
|
-
WHERE (${pairs}) AND provider = ? AND deleted_at IS NULL
|
|
107
|
+
WHERE (${pairs}) AND provider = ? AND deleted_at IS NULL AND enabled = 1
|
|
105
108
|
ORDER BY
|
|
109
|
+
is_default DESC,
|
|
106
110
|
(CASE WHEN window_started_at IS NULL OR ? - window_started_at >= ?
|
|
107
111
|
THEN 0 ELSE input_tokens + output_tokens END) ASC,
|
|
108
112
|
last_used_at ASC,
|
|
@@ -128,6 +132,26 @@ export class D1ProviderApiKeyRepository {
|
|
|
128
132
|
.bind(at, windowMs, at, at, windowMs, usage.inputTokens, at, windowMs, usage.outputTokens, at, windowMs, id)
|
|
129
133
|
.run();
|
|
130
134
|
}
|
|
135
|
+
async setEnabled(scope, scopeId, id, enabled) {
|
|
136
|
+
await this.db
|
|
137
|
+
.prepare('UPDATE provider_api_keys SET enabled = ? WHERE id = ? AND scope = ? AND scope_id = ? AND deleted_at IS NULL')
|
|
138
|
+
.bind(enabled ? 1 : 0, id, scope, scopeId)
|
|
139
|
+
.run();
|
|
140
|
+
}
|
|
141
|
+
async setDefault(scope, scopeId, provider, id) {
|
|
142
|
+
// Clear the group's default first (at most one per scope+scopeId+provider), then pin the
|
|
143
|
+
// chosen row. D1 serialises writes, so the two statements settle atomically enough.
|
|
144
|
+
await this.db
|
|
145
|
+
.prepare('UPDATE provider_api_keys SET is_default = 0 WHERE scope = ? AND scope_id = ? AND provider = ? AND deleted_at IS NULL AND is_default = 1')
|
|
146
|
+
.bind(scope, scopeId, provider)
|
|
147
|
+
.run();
|
|
148
|
+
if (id !== null) {
|
|
149
|
+
await this.db
|
|
150
|
+
.prepare('UPDATE provider_api_keys SET is_default = 1 WHERE id = ? AND scope = ? AND scope_id = ? AND provider = ? AND deleted_at IS NULL')
|
|
151
|
+
.bind(id, scope, scopeId, provider)
|
|
152
|
+
.run();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
131
155
|
async softDelete(scope, scopeId, id, at) {
|
|
132
156
|
await this.db
|
|
133
157
|
.prepare('UPDATE provider_api_keys SET deleted_at = ? WHERE id = ? AND scope = ? AND scope_id = ? AND deleted_at IS NULL')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"D1ProviderApiKeyRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderApiKeyRepository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"D1ProviderApiKeyRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderApiKeyRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,8 @@ export declare class D1ProviderSubscriptionTokenRepository implements ProviderSu
|
|
|
14
14
|
inputTokens: number;
|
|
15
15
|
outputTokens: number;
|
|
16
16
|
}, at: number, windowMs: number): Promise<void>;
|
|
17
|
+
setEnabled(workspaceId: string, id: string, enabled: boolean): Promise<void>;
|
|
18
|
+
setDefault(workspaceId: string, vendor: SubscriptionVendor, id: string | null): Promise<void>;
|
|
17
19
|
softDelete(workspaceId: string, id: string, at: number): Promise<void>;
|
|
18
20
|
}
|
|
19
21
|
//# sourceMappingURL=D1ProviderSubscriptionTokenRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"D1ProviderSubscriptionTokenRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,+BAA+B,EAC/B,mCAAmC,EACnC,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"D1ProviderSubscriptionTokenRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,+BAA+B,EAC/B,mCAAmC,EACnC,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AA0C3D,iFAAiF;AACjF,qBAAa,qCAAsC,YAAW,mCAAmC;IAC/F,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAE/B,YAAY,EAAE,EAAE,EAAE,EAAE;QAAE,EAAE,EAAE,UAAU,CAAA;KAAE,EAErC;IAEK,YAAY,CAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,+BAA+B,EAAE,CAAC,CAU5C;IAEK,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,+BAA+B,GAAG,IAAI,CAAC,CAQ9F;IAEK,GAAG,CAAC,MAAM,EAAE,+BAA+B,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhE;IAEK,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E;IAEK,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EACpD,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAgCf;IAEK,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjF;IAEK,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,OAAO,CAAC,IAAI,CAAC,CAiBf;IAEK,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E;CACF"}
|
|
@@ -17,6 +17,8 @@ function rowToRecord(row) {
|
|
|
17
17
|
inputTokens: row.input_tokens,
|
|
18
18
|
outputTokens: row.output_tokens,
|
|
19
19
|
requestCount: row.request_count,
|
|
20
|
+
enabled: row.enabled !== 0,
|
|
21
|
+
isDefault: row.is_default !== 0,
|
|
20
22
|
deletedAt: row.deleted_at,
|
|
21
23
|
};
|
|
22
24
|
}
|
|
@@ -46,9 +48,9 @@ export class D1ProviderSubscriptionTokenRepository {
|
|
|
46
48
|
await this.db
|
|
47
49
|
.prepare(`INSERT INTO provider_subscription_tokens
|
|
48
50
|
(id, workspace_id, vendor, label, token_cipher, created_at, last_used_at,
|
|
49
|
-
window_started_at, input_tokens, output_tokens, request_count, deleted_at)
|
|
50
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`)
|
|
51
|
-
.bind(record.id, record.workspaceId, record.vendor, record.label, record.tokenCipher, record.createdAt, record.lastUsedAt, record.windowStartedAt, record.inputTokens, record.outputTokens, record.requestCount)
|
|
51
|
+
window_started_at, input_tokens, output_tokens, request_count, enabled, is_default, deleted_at)
|
|
52
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`)
|
|
53
|
+
.bind(record.id, record.workspaceId, record.vendor, record.label, record.tokenCipher, record.createdAt, record.lastUsedAt, record.windowStartedAt, record.inputTokens, record.outputTokens, record.requestCount, record.enabled ? 1 : 0, record.isDefault ? 1 : 0)
|
|
52
54
|
.run();
|
|
53
55
|
}
|
|
54
56
|
async markLeased(workspaceId, id, at) {
|
|
@@ -74,6 +76,26 @@ export class D1ProviderSubscriptionTokenRepository {
|
|
|
74
76
|
.bind(at, windowMs, at, at, windowMs, usage.inputTokens, at, windowMs, usage.outputTokens, at, windowMs, id, workspaceId)
|
|
75
77
|
.run();
|
|
76
78
|
}
|
|
79
|
+
async setEnabled(workspaceId, id, enabled) {
|
|
80
|
+
await this.db
|
|
81
|
+
.prepare('UPDATE provider_subscription_tokens SET enabled = ? WHERE id = ? AND workspace_id = ? AND deleted_at IS NULL')
|
|
82
|
+
.bind(enabled ? 1 : 0, id, workspaceId)
|
|
83
|
+
.run();
|
|
84
|
+
}
|
|
85
|
+
async setDefault(workspaceId, vendor, id) {
|
|
86
|
+
// Clear the group's default first (at most one default per workspace+vendor), then pin
|
|
87
|
+
// the chosen row. D1 serialises writes, so the two statements settle atomically enough.
|
|
88
|
+
await this.db
|
|
89
|
+
.prepare('UPDATE provider_subscription_tokens SET is_default = 0 WHERE workspace_id = ? AND vendor = ? AND deleted_at IS NULL AND is_default = 1')
|
|
90
|
+
.bind(workspaceId, vendor)
|
|
91
|
+
.run();
|
|
92
|
+
if (id !== null) {
|
|
93
|
+
await this.db
|
|
94
|
+
.prepare('UPDATE provider_subscription_tokens SET is_default = 1 WHERE id = ? AND workspace_id = ? AND vendor = ? AND deleted_at IS NULL')
|
|
95
|
+
.bind(id, workspaceId, vendor)
|
|
96
|
+
.run();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
77
99
|
async softDelete(workspaceId, id, at) {
|
|
78
100
|
await this.db
|
|
79
101
|
.prepare('UPDATE provider_subscription_tokens SET deleted_at = ? WHERE id = ? AND workspace_id = ? AND deleted_at IS NULL')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"D1ProviderSubscriptionTokenRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"D1ProviderSubscriptionTokenRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Enable/disable + pinned default for the two credential pools (subscription tokens and
|
|
2
|
+
-- direct-provider API keys). A pool can hold several credentials "for the same thing"
|
|
3
|
+
-- (a vendor / a scope+provider); these flags let an operator take one out of rotation
|
|
4
|
+
-- without deleting it, and pin one as the preferred credential.
|
|
5
|
+
--
|
|
6
|
+
-- `enabled` — 1 (default) ⇒ eligible for leasing. 0 ⇒ kept in the pool (still listed and
|
|
7
|
+
-- re-enablable) but never leased and not counted as "configured".
|
|
8
|
+
-- `is_default` — 0 (default) ⇒ ordinary usage-aware rotation. 1 ⇒ the pinned default for its
|
|
9
|
+
-- group (workspace+vendor / scope+scope_id+provider): leased first when enabled.
|
|
10
|
+
-- At most one per group is enforced by the write path (set-default clears the
|
|
11
|
+
-- group's other flags first). A disabled default is ignored at lease time.
|
|
12
|
+
--
|
|
13
|
+
-- Existing rows read unchanged (enabled, not default) — pre-1.0, no back-fill needed.
|
|
14
|
+
|
|
15
|
+
ALTER TABLE provider_subscription_tokens ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1;
|
|
16
|
+
ALTER TABLE provider_subscription_tokens ADD COLUMN is_default INTEGER NOT NULL DEFAULT 0;
|
|
17
|
+
|
|
18
|
+
ALTER TABLE provider_api_keys ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1;
|
|
19
|
+
ALTER TABLE provider_api_keys ADD COLUMN is_default INTEGER NOT NULL DEFAULT 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.97.0",
|
|
4
4
|
"description": "Reusable Cloudflare Worker library (Hono + D1) exposing the Agent Architecture Board core: the `createApp()` Hono factory, the default fetch/scheduled/queue handler, and the Durable Object + Workflow classes. Deployments (see deploy/backend) supply the wrangler.toml + config and re-export these.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,22 +42,22 @@
|
|
|
42
42
|
"pino": "^10.3.1",
|
|
43
43
|
"valibot": "^1.4.2",
|
|
44
44
|
"workers-ai-provider": "^3.3.1",
|
|
45
|
-
"@cat-factory/
|
|
46
|
-
"@cat-factory/
|
|
47
|
-
"@cat-factory/consensus": "0.11.
|
|
48
|
-
"@cat-factory/contracts": "0.
|
|
49
|
-
"@cat-factory/eks": "0.1.
|
|
50
|
-
"@cat-factory/gates": "0.7.
|
|
51
|
-
"@cat-factory/gitlab": "0.11.
|
|
52
|
-
"@cat-factory/
|
|
53
|
-
"@cat-factory/
|
|
54
|
-
"@cat-factory/observability-langfuse": "0.7.
|
|
55
|
-
"@cat-factory/observability-otel": "0.2.
|
|
56
|
-
"@cat-factory/orchestration": "0.
|
|
57
|
-
"@cat-factory/prompt-fragments": "0.14.
|
|
58
|
-
"@cat-factory/provider-cloudflare": "0.7.
|
|
59
|
-
"@cat-factory/server": "0.
|
|
60
|
-
"@cat-factory/spend": "0.12.
|
|
45
|
+
"@cat-factory/caching": "0.10.31",
|
|
46
|
+
"@cat-factory/agents": "0.68.1",
|
|
47
|
+
"@cat-factory/consensus": "0.11.25",
|
|
48
|
+
"@cat-factory/contracts": "0.158.0",
|
|
49
|
+
"@cat-factory/eks": "0.1.125",
|
|
50
|
+
"@cat-factory/gates": "0.7.18",
|
|
51
|
+
"@cat-factory/gitlab": "0.11.18",
|
|
52
|
+
"@cat-factory/kernel": "0.152.0",
|
|
53
|
+
"@cat-factory/integrations": "0.91.0",
|
|
54
|
+
"@cat-factory/observability-langfuse": "0.7.249",
|
|
55
|
+
"@cat-factory/observability-otel": "0.2.32",
|
|
56
|
+
"@cat-factory/orchestration": "0.133.1",
|
|
57
|
+
"@cat-factory/prompt-fragments": "0.14.5",
|
|
58
|
+
"@cat-factory/provider-cloudflare": "0.7.275",
|
|
59
|
+
"@cat-factory/server": "0.143.0",
|
|
60
|
+
"@cat-factory/spend": "0.12.75"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@cloudflare/vitest-pool-workers": "^0.18.6",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"typescript": "7.0.2",
|
|
66
66
|
"vitest": "^4.1.10",
|
|
67
67
|
"wrangler": "^4.112.0",
|
|
68
|
-
"@cat-factory/conformance": "0.11.
|
|
68
|
+
"@cat-factory/conformance": "0.11.56"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsc -b tsconfig.build.json",
|