@sixb/sqlite 0.1.25 → 0.2.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/agents/agent-storage.d.ts +8 -3
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/computers.d.ts +22 -0
- package/dist/agents/computers.d.ts.map +1 -0
- package/dist/agents/messages.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +6 -0
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +2 -1
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/agents/threads.d.ts +4 -1
- package/dist/agents/threads.d.ts.map +1 -1
- package/dist/agents/token-rates.d.ts +13 -0
- package/dist/agents/token-rates.d.ts.map +1 -0
- package/dist/ai-accounting-filters.d.ts +14 -0
- package/dist/ai-accounting-filters.d.ts.map +1 -0
- package/dist/ai-cost-groups.d.ts +1 -1
- package/dist/ai-cost-groups.d.ts.map +1 -1
- package/dist/ai-cost-storage.d.ts.map +1 -1
- package/dist/index.js +465 -63
- package/dist/index.js.map +17 -14
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/query-compiler.d.ts.map +1 -1
- package/dist/ontology-storage/commits.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts +2 -1
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +10 -3
- package/src/agents/computers.ts +112 -0
- package/src/agents/messages.ts +13 -0
- package/src/agents/rows.ts +14 -0
- package/src/agents/runs.ts +52 -4
- package/src/agents/threads.ts +108 -4
- package/src/agents/token-rates.ts +90 -0
- package/src/ai-accounting-filters.ts +51 -0
- package/src/ai-cost-groups.ts +52 -14
- package/src/ai-cost-storage.ts +101 -39
- package/src/migrations/080-agent-run-cancel-requests.sql +3 -0
- package/src/migrations/081-agent-thread-runs-on.sql +4 -0
- package/src/migrations/082-agent-token-rates.sql +17 -0
- package/src/migrations/083-agent-computer-sessions.sql +27 -0
- package/src/migrations.ts +12 -0
- package/src/objects/query-compiler.ts +44 -28
- package/src/ontology-storage/commits.ts +9 -0
- package/src/ontology-storage/materializations.ts +18 -1
package/dist/migrations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAmI3B,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAmI3B,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,eAAO,MAAM,uBAAuB,wBA6KlC,CAAA;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAQ9E;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC1C,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,QAAQ,CAAC,CAEzB;AAOD,mGAAmG;AACnG,wBAAgB,mBAAmB,IAAI,QAAQ,CAY9C;AAaD,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAOzF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CAC5C,GAAG,eAAe,CAoBlB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../../src/objects/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,oBAAoB,EAG1B,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../../src/objects/query-compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/commits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EACV,sCAAsC,EACtC,0BAA0B,EAC1B,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,
|
|
1
|
+
{"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/commits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EACV,sCAAsC,EACtC,0BAA0B,EAC1B,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAOL,KAAK,mBAAmB,EACzB,MAAM,UAAU,CAAA;AAEjB,qBAAa,2BAA4B,YAAW,qBAAqB;IAErE,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,mBAAmB;IAGlD,mBAAmB,CACvB,KAAK,EAAE,sCAAsC,GAC5C,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAYjC,OAAO,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAQhF,WAAW,CAAC,KAAK,EAAE,8BAA8B,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAyBxF,IAAI,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAqD/E,OAAO,CAAC,OAAO;CAShB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
-
import type { AppliedMaterialization, ApplyMaterializationInput, ApplyMaterializationResult, FinalizeMaterializationInput, MaterializationPlanHeader, MaterializationSession, MaterializationStatePage, MaterializationVectorChangePage, OntologyMaterializationStorage, StageMaterializationWorkInput, StreamMaterializationStateInput, StreamMaterializationVectorChangesInput } from "@sixb/core/storage";
|
|
2
|
+
import type { AppliedMaterialization, ApplyMaterializationInput, ApplyMaterializationResult, FinalizeMaterializationInput, MaterializationPlanHeader, MaterializationSession, MaterializationState, MaterializationStatePage, MaterializationVectorChangePage, OntologyMaterializationStorage, ReadMaterializationStateInput, StageMaterializationWorkInput, StreamMaterializationStateInput, StreamMaterializationVectorChangesInput } from "@sixb/core/storage";
|
|
3
3
|
import { type SqliteOntologyTransactionContext } from "./materialization-session";
|
|
4
4
|
export declare class SqliteOntologyMaterializationStorage implements OntologyMaterializationStorage {
|
|
5
5
|
private readonly db;
|
|
@@ -9,6 +9,7 @@ export declare class SqliteOntologyMaterializationStorage implements OntologyMat
|
|
|
9
9
|
assertVectorSession(session: MaterializationSession, projectId: string, commitId?: string): void;
|
|
10
10
|
begin(input: MaterializationPlanHeader): Promise<MaterializationSession>;
|
|
11
11
|
streamState(input: StreamMaterializationStateInput): AsyncIterable<MaterializationStatePage>;
|
|
12
|
+
readState(input: ReadMaterializationStateInput): Promise<MaterializationState>;
|
|
12
13
|
stageWork(input: StageMaterializationWorkInput): Promise<void>;
|
|
13
14
|
streamVectorChanges(input: StreamMaterializationVectorChangesInput): AsyncIterable<MaterializationVectorChangePage>;
|
|
14
15
|
apply(input: ApplyMaterializationInput): Promise<AppliedMaterialization>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materializations.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materializations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"materializations.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materializations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AA+B1C,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EAEzB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,EAE/B,8BAA8B,EAC9B,6BAA6B,EAE7B,6BAA6B,EAC7B,+BAA+B,EAC/B,uCAAuC,EACxC,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,2BAA2B,CAAA;AAmElC,qBAAa,oCAAqC,YAAW,8BAA8B;IAKvF,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;gBAGjC,EAAE,EAAE,QAAQ,EAC7B,OAAO,EAAE,gCAAgC,GAAG,IAAI;IAMlD,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAY1F,KAAK,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAqCvE,WAAW,CAChB,KAAK,EAAE,+BAA+B,GACrC,aAAa,CAAC,wBAAwB,CAAC;IA+DpC,SAAS,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAc9E,SAAS,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7D,mBAAmB,CACxB,KAAK,EAAE,uCAAuC,GAC7C,aAAa,CAAC,+BAA+B,CAAC;IAa3C,KAAK,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA2CxE,QAAQ,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAYxF,kBAAkB,IAAI,IAAI;IAI1B,OAAO,CAAC,kBAAkB;IA+C1B,OAAO,CAAC,YAAY;YAgBN,kBAAkB;IAsDhC,OAAO,CAAC,sBAAsB;IAkD9B,OAAO,CAAC,cAAc;IAsGtB,OAAO,CAAC,YAAY;IAkDpB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,SAAS;CAYlB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/sqlite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SQLite storage provider for Sixb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sixb",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"prepack": "bun run build"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@sixb/core": "0.
|
|
40
|
+
"@sixb/core": "0.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@sixb/core": "0.
|
|
43
|
+
"@sixb/core": "0.2.0",
|
|
44
44
|
"@types/bun": "latest",
|
|
45
45
|
"typescript": "^5.7.0"
|
|
46
46
|
},
|
|
@@ -6,11 +6,13 @@ import {
|
|
|
6
6
|
} from "../transactions"
|
|
7
7
|
import { SqliteAgentApprovalStore } from "./approvals"
|
|
8
8
|
import { SqliteAgentContextCheckpointStore } from "./checkpoints"
|
|
9
|
+
import { SqliteAgentComputerSessionStore } from "./computers"
|
|
9
10
|
import { SqliteAgentMemoryStore } from "./memory"
|
|
10
11
|
import { SqliteAgentMessageStore } from "./messages"
|
|
11
12
|
import { SqliteAgentRunStore } from "./runs"
|
|
12
13
|
import { SqliteAgentApprovalModeStore } from "./settings"
|
|
13
14
|
import { SqliteAgentThreadStore } from "./threads"
|
|
15
|
+
import { SqliteAgentTokenRateStore } from "./token-rates"
|
|
14
16
|
|
|
15
17
|
export interface SqliteAgentStorageOptions {
|
|
16
18
|
/** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */
|
|
@@ -22,9 +24,10 @@ export interface SqliteAgentStorageOptions {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
|
-
* SQLite-backed agent persistence: thread, run, message, context-checkpoint, memory, approval
|
|
26
|
-
* approval-mode sub-stores sharing one connection. Cross-table writes run in
|
|
27
|
-
* serializes them for single-flight and
|
|
27
|
+
* SQLite-backed agent persistence: thread, run, message, context-checkpoint, memory, approval,
|
|
28
|
+
* approval-mode, computer-session and token-rate sub-stores sharing one connection. Cross-table writes run in
|
|
29
|
+
* SQLite transactions; the bundled {@link SqliteStorage} serializes them for single-flight and
|
|
30
|
+
* checkpoint compare-and-swap safety.
|
|
28
31
|
*/
|
|
29
32
|
export class SqliteAgentStorage implements AgentStorage {
|
|
30
33
|
readonly threads: SqliteAgentThreadStore
|
|
@@ -34,6 +37,8 @@ export class SqliteAgentStorage implements AgentStorage {
|
|
|
34
37
|
readonly memory: SqliteAgentMemoryStore
|
|
35
38
|
readonly approvals: SqliteAgentApprovalStore
|
|
36
39
|
readonly approvalModes: SqliteAgentApprovalModeStore
|
|
40
|
+
readonly computers: SqliteAgentComputerSessionStore
|
|
41
|
+
readonly tokenRates: SqliteAgentTokenRateStore
|
|
37
42
|
|
|
38
43
|
private readonly connection: SqliteStoreConnection
|
|
39
44
|
|
|
@@ -47,6 +52,8 @@ export class SqliteAgentStorage implements AgentStorage {
|
|
|
47
52
|
this.memory = new SqliteAgentMemoryStore(this.connection.db)
|
|
48
53
|
this.approvals = new SqliteAgentApprovalStore(this.connection.db)
|
|
49
54
|
this.approvalModes = new SqliteAgentApprovalModeStore(this.connection.db)
|
|
55
|
+
this.computers = new SqliteAgentComputerSessionStore(this.connection.db)
|
|
56
|
+
this.tokenRates = new SqliteAgentTokenRateStore(this.connection.db)
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
close(): void {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { Database } from "bun:sqlite"
|
|
2
|
+
import { assertAgentComputerSession } from "@sixb/core/internal/agent-run-storage-provider"
|
|
3
|
+
import type {
|
|
4
|
+
AgentComputerSessionRecord,
|
|
5
|
+
AgentComputerSessionStore,
|
|
6
|
+
Principal,
|
|
7
|
+
} from "@sixb/core/storage"
|
|
8
|
+
|
|
9
|
+
interface AgentComputerSessionRow {
|
|
10
|
+
project_id: string
|
|
11
|
+
owner_principal_type: Principal["type"]
|
|
12
|
+
owner_principal_id: string
|
|
13
|
+
id: string
|
|
14
|
+
computer_id: string
|
|
15
|
+
computer_name: string
|
|
16
|
+
folder: string
|
|
17
|
+
expires_at: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class SqliteAgentComputerSessionStore implements AgentComputerSessionStore {
|
|
21
|
+
constructor(private readonly db: Database) {}
|
|
22
|
+
|
|
23
|
+
async hold(input: AgentComputerSessionRecord): Promise<void> {
|
|
24
|
+
assertAgentComputerSession(input, "SixbSqlite")
|
|
25
|
+
this.db
|
|
26
|
+
.query(
|
|
27
|
+
`INSERT INTO agent_computer_sessions (
|
|
28
|
+
project_id, owner_principal_type, owner_principal_id, id,
|
|
29
|
+
computer_id, computer_name, folder, expires_at
|
|
30
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
31
|
+
ON CONFLICT (project_id, owner_principal_type, owner_principal_id, id)
|
|
32
|
+
DO UPDATE SET
|
|
33
|
+
computer_id = excluded.computer_id,
|
|
34
|
+
computer_name = excluded.computer_name,
|
|
35
|
+
folder = excluded.folder,
|
|
36
|
+
expires_at = excluded.expires_at`
|
|
37
|
+
)
|
|
38
|
+
.run(
|
|
39
|
+
input.projectId,
|
|
40
|
+
input.ownerPrincipal.type,
|
|
41
|
+
input.ownerPrincipal.id,
|
|
42
|
+
input.id,
|
|
43
|
+
input.computer.id,
|
|
44
|
+
input.computer.name,
|
|
45
|
+
input.computer.folder,
|
|
46
|
+
input.expiresAt.toISOString()
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async release(input: {
|
|
51
|
+
readonly projectId: string
|
|
52
|
+
readonly id: string
|
|
53
|
+
readonly ownerPrincipal: Principal
|
|
54
|
+
}): Promise<AgentComputerSessionRecord | null> {
|
|
55
|
+
const row = this.db
|
|
56
|
+
.query(
|
|
57
|
+
`DELETE FROM agent_computer_sessions
|
|
58
|
+
WHERE project_id = ? AND owner_principal_type = ? AND owner_principal_id = ? AND id = ?
|
|
59
|
+
RETURNING *`
|
|
60
|
+
)
|
|
61
|
+
.get(
|
|
62
|
+
input.projectId,
|
|
63
|
+
input.ownerPrincipal.type,
|
|
64
|
+
input.ownerPrincipal.id,
|
|
65
|
+
input.id
|
|
66
|
+
) as AgentComputerSessionRow | null
|
|
67
|
+
return row && rowToSession(row)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async listLive(input: {
|
|
71
|
+
readonly projectId: string
|
|
72
|
+
readonly ownerPrincipal: Principal
|
|
73
|
+
readonly now: Date
|
|
74
|
+
}): Promise<readonly AgentComputerSessionRecord[]> {
|
|
75
|
+
const rows = this.db
|
|
76
|
+
.query(
|
|
77
|
+
`SELECT * FROM agent_computer_sessions
|
|
78
|
+
WHERE project_id = ? AND owner_principal_type = ? AND owner_principal_id = ?
|
|
79
|
+
AND expires_at > ?
|
|
80
|
+
ORDER BY id`
|
|
81
|
+
)
|
|
82
|
+
.all(
|
|
83
|
+
input.projectId,
|
|
84
|
+
input.ownerPrincipal.type,
|
|
85
|
+
input.ownerPrincipal.id,
|
|
86
|
+
input.now.toISOString()
|
|
87
|
+
) as AgentComputerSessionRow[]
|
|
88
|
+
return rows.map(rowToSession)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async removeLapsed(input: {
|
|
92
|
+
readonly projectId: string
|
|
93
|
+
readonly now: Date
|
|
94
|
+
}): Promise<readonly AgentComputerSessionRecord[]> {
|
|
95
|
+
const rows = this.db
|
|
96
|
+
.query(
|
|
97
|
+
`DELETE FROM agent_computer_sessions WHERE project_id = ? AND expires_at <= ? RETURNING *`
|
|
98
|
+
)
|
|
99
|
+
.all(input.projectId, input.now.toISOString()) as AgentComputerSessionRow[]
|
|
100
|
+
return rows.map(rowToSession)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function rowToSession(row: AgentComputerSessionRow): AgentComputerSessionRecord {
|
|
105
|
+
return {
|
|
106
|
+
projectId: row.project_id,
|
|
107
|
+
id: row.id,
|
|
108
|
+
ownerPrincipal: { type: row.owner_principal_type, id: row.owner_principal_id },
|
|
109
|
+
computer: { id: row.computer_id, name: row.computer_name, folder: row.folder },
|
|
110
|
+
expiresAt: new Date(row.expires_at),
|
|
111
|
+
}
|
|
112
|
+
}
|
package/src/agents/messages.ts
CHANGED
|
@@ -120,6 +120,19 @@ export class SqliteAgentMessageStore implements AgentMessageStore {
|
|
|
120
120
|
|
|
121
121
|
async deleteByRunId(input: DeleteAgentMessagesByRunInput): Promise<number> {
|
|
122
122
|
return this.db.transaction(() => {
|
|
123
|
+
if (input.fence) {
|
|
124
|
+
const owner = this.db
|
|
125
|
+
.query(
|
|
126
|
+
"SELECT 1 AS present FROM agent_runs WHERE project_id = ? AND id = ? AND status = 'running' AND execution_token = ?"
|
|
127
|
+
)
|
|
128
|
+
.get(input.projectId, input.fence.runId, input.fence.executionToken)
|
|
129
|
+
if (!owner) {
|
|
130
|
+
throw new AgentStorageError(
|
|
131
|
+
"execution_lost",
|
|
132
|
+
`[SixbSqlite] Execution token is no longer current on agent run '${input.fence.runId}'.`
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
123
136
|
const thread = this.db
|
|
124
137
|
.query("SELECT 1 AS present FROM agent_threads WHERE project_id = ? AND id = ?")
|
|
125
138
|
.get(input.projectId, input.threadId) as { present: number } | null
|
package/src/agents/rows.ts
CHANGED
|
@@ -32,6 +32,11 @@ export interface AgentThreadRow {
|
|
|
32
32
|
title: string | null
|
|
33
33
|
sandbox_params: string | null
|
|
34
34
|
sandbox_state: string | null
|
|
35
|
+
runs_on: "computer" | null
|
|
36
|
+
computer_id: string | null
|
|
37
|
+
computer_name: string | null
|
|
38
|
+
computer_folder: string | null
|
|
39
|
+
moved_at: string | null
|
|
35
40
|
status: AgentThreadRecord["status"]
|
|
36
41
|
active_run_id: string | null
|
|
37
42
|
last_message_at: string | null
|
|
@@ -69,6 +74,7 @@ export interface AgentRunRow {
|
|
|
69
74
|
attempt: number
|
|
70
75
|
execution_token: string | null
|
|
71
76
|
execution_queue_lease_expires_at: string | null
|
|
77
|
+
cancel_requested_at: string | null
|
|
72
78
|
created_at: string
|
|
73
79
|
started_at: string | null
|
|
74
80
|
completed_at: string | null
|
|
@@ -133,6 +139,13 @@ export function rowToThreadRecord(row: AgentThreadRow): AgentThreadRecord {
|
|
|
133
139
|
...(row.sandbox_params == null
|
|
134
140
|
? {}
|
|
135
141
|
: { sandboxParams: snapshotAgentThreadSandboxParams(JSON.parse(row.sandbox_params)) }),
|
|
142
|
+
...(row.runs_on == null ? {} : { runsOn: row.runs_on }),
|
|
143
|
+
...(row.computer_id == null || row.computer_name == null || row.computer_folder == null
|
|
144
|
+
? {}
|
|
145
|
+
: {
|
|
146
|
+
computer: { id: row.computer_id, name: row.computer_name, folder: row.computer_folder },
|
|
147
|
+
}),
|
|
148
|
+
...(row.moved_at == null ? {} : { movedAt: new Date(row.moved_at) }),
|
|
136
149
|
status: row.status,
|
|
137
150
|
activeRunId: row.active_run_id,
|
|
138
151
|
lastMessageAt: row.last_message_at ? new Date(row.last_message_at) : undefined,
|
|
@@ -161,6 +174,7 @@ export function rowToRunRecord(row: AgentRunRow): AgentRunRecord {
|
|
|
161
174
|
queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),
|
|
162
175
|
}
|
|
163
176
|
: undefined,
|
|
177
|
+
cancelRequestedAt: row.cancel_requested_at ? new Date(row.cancel_requested_at) : undefined,
|
|
164
178
|
createdAt: new Date(row.created_at),
|
|
165
179
|
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
166
180
|
completedAt: row.completed_at ? new Date(row.completed_at) : undefined,
|
package/src/agents/runs.ts
CHANGED
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
assertConversationAgentRunSpec,
|
|
8
8
|
assertConversationThreadRow,
|
|
9
9
|
assertCreateSubagentRunInput,
|
|
10
|
+
assertStartsOnComputer,
|
|
10
11
|
assertSubagentThreadTakesRun,
|
|
12
|
+
assertTurnInThreadPlace,
|
|
11
13
|
newSubagentThreadRecord,
|
|
12
14
|
subagentRunMatchesCreateInput,
|
|
13
15
|
} from "@sixb/core/internal/agent-run-storage-provider"
|
|
@@ -29,6 +31,7 @@ import {
|
|
|
29
31
|
type ListAgentRunsResult,
|
|
30
32
|
type ListThreadSubagentsInput,
|
|
31
33
|
type ReclaimAgentRunInput,
|
|
34
|
+
type RequestAgentRunCancelInput,
|
|
32
35
|
type StartAgentRunInput,
|
|
33
36
|
type SubagentRunRecord,
|
|
34
37
|
} from "@sixb/core/storage"
|
|
@@ -62,10 +65,12 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
62
65
|
|
|
63
66
|
return this.db.transaction(() => {
|
|
64
67
|
const thread = this.db
|
|
65
|
-
.query(
|
|
68
|
+
.query(
|
|
69
|
+
"SELECT id, kind, active_run_id, runs_on FROM agent_threads WHERE project_id = ? AND id = ?"
|
|
70
|
+
)
|
|
66
71
|
.get(input.projectId, input.threadId) as Pick<
|
|
67
72
|
AgentThreadRow,
|
|
68
|
-
"id" | "kind" | "active_run_id"
|
|
73
|
+
"id" | "kind" | "active_run_id" | "runs_on"
|
|
69
74
|
> | null
|
|
70
75
|
|
|
71
76
|
if (!thread) {
|
|
@@ -81,6 +86,7 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
81
86
|
`[SixbSqlite] Agent thread '${input.threadId}' already has an active run '${thread.active_run_id}'.`
|
|
82
87
|
)
|
|
83
88
|
}
|
|
89
|
+
assertTurnInThreadPlace(thread.runs_on, input.spec, input.threadId, "SixbSqlite")
|
|
84
90
|
|
|
85
91
|
try {
|
|
86
92
|
this.db
|
|
@@ -270,7 +276,20 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
270
276
|
async start(input: StartAgentRunInput): Promise<AgentRunRecord> {
|
|
271
277
|
const startedAt = input.startedAt ?? new Date()
|
|
272
278
|
return this.db.transaction(() => {
|
|
273
|
-
this.requireStatus(input.projectId, input.id, "queued")
|
|
279
|
+
const run = this.requireStatus(input.projectId, input.id, "queued")
|
|
280
|
+
if (input.onComputer) {
|
|
281
|
+
const thread = this.db
|
|
282
|
+
.query(
|
|
283
|
+
"SELECT computer_id AS id, computer_folder AS folder FROM agent_threads WHERE project_id = ? AND id = ?"
|
|
284
|
+
)
|
|
285
|
+
.get(input.projectId, run.thread_id) as { id: string; folder: string } | null
|
|
286
|
+
assertStartsOnComputer(
|
|
287
|
+
rowToRunRecord(run),
|
|
288
|
+
thread?.id ? thread : undefined,
|
|
289
|
+
input.onComputer,
|
|
290
|
+
"SixbSqlite"
|
|
291
|
+
)
|
|
292
|
+
}
|
|
274
293
|
this.db
|
|
275
294
|
.query(
|
|
276
295
|
`
|
|
@@ -326,7 +345,17 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
326
345
|
|
|
327
346
|
async reclaim(input: ReclaimAgentRunInput): Promise<AgentRunRecord> {
|
|
328
347
|
return this.db.transaction(() => {
|
|
329
|
-
this.requireRunning(input.projectId, input.id)
|
|
348
|
+
const run = this.requireRunning(input.projectId, input.id)
|
|
349
|
+
if (
|
|
350
|
+
input.ifLapsedBy &&
|
|
351
|
+
run.execution_queue_lease_expires_at !== null &&
|
|
352
|
+
new Date(run.execution_queue_lease_expires_at).getTime() > input.ifLapsedBy.getTime()
|
|
353
|
+
) {
|
|
354
|
+
throw new AgentStorageError(
|
|
355
|
+
"invalid_state",
|
|
356
|
+
`[SixbSqlite] Agent run '${input.id}' is still held by its runner, whose lease has not lapsed.`
|
|
357
|
+
)
|
|
358
|
+
}
|
|
330
359
|
this.db
|
|
331
360
|
.query(
|
|
332
361
|
`
|
|
@@ -373,6 +402,21 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
373
402
|
})()
|
|
374
403
|
}
|
|
375
404
|
|
|
405
|
+
async requestCancel(input: RequestAgentRunCancelInput): Promise<AgentRunRecord> {
|
|
406
|
+
return this.db.transaction(() => {
|
|
407
|
+
this.db
|
|
408
|
+
.query(
|
|
409
|
+
`
|
|
410
|
+
UPDATE agent_runs
|
|
411
|
+
SET cancel_requested_at = ?
|
|
412
|
+
WHERE project_id = ? AND id = ? AND status = 'running' AND cancel_requested_at IS NULL
|
|
413
|
+
`
|
|
414
|
+
)
|
|
415
|
+
.run((input.at ?? new Date()).toISOString(), input.projectId, input.id)
|
|
416
|
+
return this.requireRun(input.projectId, input.id)
|
|
417
|
+
})()
|
|
418
|
+
}
|
|
419
|
+
|
|
376
420
|
async finish(input: FinishAgentRunInput): Promise<AgentRunRecord> {
|
|
377
421
|
const completedAt = input.completedAt ?? new Date()
|
|
378
422
|
const errorValue =
|
|
@@ -560,6 +604,10 @@ export class SqliteAgentRunStore implements AgentRunStore {
|
|
|
560
604
|
args.push(input.parentRunId)
|
|
561
605
|
}
|
|
562
606
|
|
|
607
|
+
if (input.excludeComputerTurns) {
|
|
608
|
+
whereClauses.push("json_extract(spec, '$.runsOn') IS NOT 'computer'")
|
|
609
|
+
}
|
|
610
|
+
|
|
563
611
|
appendRunListFilters(whereClauses, args, input, "COALESCE(started_at, created_at)")
|
|
564
612
|
|
|
565
613
|
const { rows, total, hasMore } = queryRunList<AgentRunRow>({
|
package/src/agents/threads.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite"
|
|
2
2
|
import {
|
|
3
|
+
assertAgentThreadComputer,
|
|
4
|
+
assertAssignableComputer,
|
|
5
|
+
assertComputerPlace,
|
|
3
6
|
assertConversationThreadRow,
|
|
7
|
+
assertMovableToCloud,
|
|
8
|
+
movesComputerPlace,
|
|
4
9
|
participantsToAdd,
|
|
5
10
|
planAgentThreadFork,
|
|
11
|
+
queuedTurnInCloud,
|
|
6
12
|
remapArtifactIds,
|
|
7
13
|
snapshotAgentThreadSandboxParams,
|
|
8
14
|
transitionAgentThreadSandbox,
|
|
@@ -10,17 +16,21 @@ import {
|
|
|
10
16
|
import {
|
|
11
17
|
type AddAgentThreadParticipantsInput,
|
|
12
18
|
type AgentContextCheckpointRecord,
|
|
19
|
+
type AgentRunRecord,
|
|
13
20
|
AgentStorageError,
|
|
14
21
|
type AgentThreadParticipantRecord,
|
|
15
22
|
type AgentThreadRecord,
|
|
16
23
|
type AgentThreadSandboxState,
|
|
17
24
|
type AgentThreadStore,
|
|
25
|
+
type AssignAgentThreadComputerInput,
|
|
18
26
|
type CreateAgentThreadInput,
|
|
19
27
|
type ForkAgentThreadInput,
|
|
20
28
|
type ListAgentThreadChildrenInput,
|
|
21
29
|
type ListAgentThreadParticipantsInput,
|
|
22
30
|
type ListAgentThreadsInput,
|
|
23
31
|
type ListAgentThreadsResult,
|
|
32
|
+
type MoveAgentThreadToCloudInput,
|
|
33
|
+
type MoveAgentThreadToCloudResult,
|
|
24
34
|
type RemoveAgentThreadParticipantInput,
|
|
25
35
|
type TransitionAgentThreadSandboxInput,
|
|
26
36
|
} from "@sixb/core/storage"
|
|
@@ -64,6 +74,7 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
async create(input: CreateAgentThreadInput): Promise<AgentThreadRecord> {
|
|
77
|
+
assertComputerPlace(input.runsOn, input.computer, "SixbSqlite")
|
|
67
78
|
const sandboxParams =
|
|
68
79
|
input.sandboxParams === undefined
|
|
69
80
|
? null
|
|
@@ -82,13 +93,17 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
82
93
|
owner_principal_id,
|
|
83
94
|
title,
|
|
84
95
|
sandbox_params,
|
|
96
|
+
runs_on,
|
|
97
|
+
computer_id,
|
|
98
|
+
computer_name,
|
|
99
|
+
computer_folder,
|
|
85
100
|
status,
|
|
86
101
|
active_run_id,
|
|
87
102
|
last_message_at,
|
|
88
103
|
message_count,
|
|
89
104
|
created_at,
|
|
90
105
|
updated_at
|
|
91
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, 0, ?, ?)
|
|
106
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, 0, ?, ?)
|
|
92
107
|
`
|
|
93
108
|
)
|
|
94
109
|
.run(
|
|
@@ -98,6 +113,10 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
98
113
|
input.ownerPrincipal.id,
|
|
99
114
|
input.title ?? null,
|
|
100
115
|
sandboxParams,
|
|
116
|
+
input.runsOn ?? null,
|
|
117
|
+
input.computer?.id ?? null,
|
|
118
|
+
input.computer?.name ?? null,
|
|
119
|
+
input.computer?.folder ?? null,
|
|
101
120
|
input.status ?? "active",
|
|
102
121
|
createdAt.toISOString(),
|
|
103
122
|
updatedAt.toISOString()
|
|
@@ -116,16 +135,25 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
116
135
|
return this.requireThread(input.projectId, input.id)
|
|
117
136
|
}
|
|
118
137
|
|
|
138
|
+
private activeRunOf(projectId: string, thread: AgentThreadRecord | null): AgentRunRecord | null {
|
|
139
|
+
const row = thread?.activeRunId
|
|
140
|
+
? (this.db
|
|
141
|
+
.query("SELECT * FROM agent_runs WHERE project_id = ? AND id = ?")
|
|
142
|
+
.get(projectId, thread.activeRunId) as AgentRunRow | null)
|
|
143
|
+
: null
|
|
144
|
+
return row ? rowToRunRecord(row) : null
|
|
145
|
+
}
|
|
146
|
+
|
|
119
147
|
async fork(input: ForkAgentThreadInput): Promise<AgentThreadRecord> {
|
|
120
148
|
return this.db
|
|
121
149
|
.transaction(() => {
|
|
122
150
|
const source = this.db
|
|
123
151
|
.query(
|
|
124
|
-
"SELECT id, kind, active_run_id FROM agent_threads WHERE project_id = ? AND id = ?"
|
|
152
|
+
"SELECT id, kind, active_run_id, runs_on, moved_at FROM agent_threads WHERE project_id = ? AND id = ?"
|
|
125
153
|
)
|
|
126
154
|
.get(input.projectId, input.sourceThreadId) as Pick<
|
|
127
155
|
AgentThreadRow,
|
|
128
|
-
"id" | "kind" | "active_run_id"
|
|
156
|
+
"id" | "kind" | "active_run_id" | "runs_on" | "moved_at"
|
|
129
157
|
> | null
|
|
130
158
|
|
|
131
159
|
if (!source) {
|
|
@@ -172,6 +200,7 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
172
200
|
const plan = planAgentThreadFork(
|
|
173
201
|
input,
|
|
174
202
|
{
|
|
203
|
+
workspace: { runsOn: source.runs_on, movedAt: source.moved_at },
|
|
175
204
|
...(activeRun?.trigger_message_id
|
|
176
205
|
? { triggerMessageId: activeRun.trigger_message_id }
|
|
177
206
|
: {}),
|
|
@@ -328,6 +357,11 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
328
357
|
args.push(input.participantPrincipal.type, input.participantPrincipal.id)
|
|
329
358
|
}
|
|
330
359
|
|
|
360
|
+
if (input.activeOnComputer) {
|
|
361
|
+
whereClauses.push("computer_id = ? AND computer_folder = ? AND active_run_id IS NOT NULL")
|
|
362
|
+
args.push(input.activeOnComputer.id, input.activeOnComputer.folder)
|
|
363
|
+
}
|
|
364
|
+
|
|
331
365
|
const dir = input.order === "asc" ? "ASC" : "DESC"
|
|
332
366
|
const { rows, total, hasMore } = queryAgentList<AgentThreadRow>({
|
|
333
367
|
db: this.db,
|
|
@@ -403,6 +437,74 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
403
437
|
return result.changes > 0
|
|
404
438
|
}
|
|
405
439
|
|
|
440
|
+
async assignComputer(input: AssignAgentThreadComputerInput): Promise<AgentThreadRecord> {
|
|
441
|
+
assertAgentThreadComputer(input.computer, "SixbSqlite")
|
|
442
|
+
return this.db
|
|
443
|
+
.transaction(() => {
|
|
444
|
+
const row = this.db
|
|
445
|
+
.query("SELECT * FROM agent_threads WHERE project_id = ? AND id = ?")
|
|
446
|
+
.get(input.projectId, input.id) as AgentThreadRow | null
|
|
447
|
+
const thread = row ? rowToThreadRecord(row) : null
|
|
448
|
+
assertAssignableComputer(
|
|
449
|
+
thread,
|
|
450
|
+
this.activeRunOf(input.projectId, thread),
|
|
451
|
+
input.computer,
|
|
452
|
+
input.id,
|
|
453
|
+
"SixbSqlite"
|
|
454
|
+
)
|
|
455
|
+
const movedAt = movesComputerPlace(thread, input.computer)
|
|
456
|
+
? (input.movedAt ?? new Date()).toISOString()
|
|
457
|
+
: null
|
|
458
|
+
this.db
|
|
459
|
+
.query(`
|
|
460
|
+
UPDATE agent_threads
|
|
461
|
+
SET computer_id = ?, computer_name = ?, computer_folder = ?,
|
|
462
|
+
moved_at = COALESCE(?, moved_at)
|
|
463
|
+
WHERE project_id = ? AND id = ?
|
|
464
|
+
`)
|
|
465
|
+
.run(
|
|
466
|
+
input.computer.id,
|
|
467
|
+
input.computer.name,
|
|
468
|
+
input.computer.folder,
|
|
469
|
+
movedAt,
|
|
470
|
+
input.projectId,
|
|
471
|
+
input.id
|
|
472
|
+
)
|
|
473
|
+
return this.requireThread(input.projectId, input.id)
|
|
474
|
+
})
|
|
475
|
+
.immediate()
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
async moveToCloud(input: MoveAgentThreadToCloudInput): Promise<MoveAgentThreadToCloudResult> {
|
|
479
|
+
return this.db
|
|
480
|
+
.transaction(() => {
|
|
481
|
+
const row = this.db
|
|
482
|
+
.query("SELECT * FROM agent_threads WHERE project_id = ? AND id = ?")
|
|
483
|
+
.get(input.projectId, input.id) as AgentThreadRow | null
|
|
484
|
+
const thread = row ? rowToThreadRecord(row) : null
|
|
485
|
+
const active = this.activeRunOf(input.projectId, thread)
|
|
486
|
+
assertMovableToCloud(thread, active, input.id, "SixbSqlite")
|
|
487
|
+
|
|
488
|
+
const queued = queuedTurnInCloud(active)
|
|
489
|
+
if (queued) {
|
|
490
|
+
this.db
|
|
491
|
+
.query("UPDATE agent_runs SET spec = ? WHERE project_id = ? AND id = ?")
|
|
492
|
+
.run(JSON.stringify(queued.spec), input.projectId, queued.id)
|
|
493
|
+
}
|
|
494
|
+
this.db
|
|
495
|
+
.query(`
|
|
496
|
+
UPDATE agent_threads
|
|
497
|
+
SET runs_on = NULL, computer_id = NULL, computer_name = NULL, computer_folder = NULL,
|
|
498
|
+
moved_at = ?
|
|
499
|
+
WHERE project_id = ? AND id = ?
|
|
500
|
+
`)
|
|
501
|
+
.run((input.movedAt ?? new Date()).toISOString(), input.projectId, input.id)
|
|
502
|
+
const moved = this.requireThread(input.projectId, input.id)
|
|
503
|
+
return { thread: moved, ...(queued ? { queued } : {}) }
|
|
504
|
+
})
|
|
505
|
+
.immediate()
|
|
506
|
+
}
|
|
507
|
+
|
|
406
508
|
async listParticipants(
|
|
407
509
|
input: ListAgentThreadParticipantsInput
|
|
408
510
|
): Promise<readonly AgentThreadParticipantRecord[]> {
|
|
@@ -456,9 +558,10 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
456
558
|
active_run_id,
|
|
457
559
|
last_message_at,
|
|
458
560
|
message_count,
|
|
561
|
+
moved_at,
|
|
459
562
|
created_at,
|
|
460
563
|
updated_at
|
|
461
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?)
|
|
564
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?)
|
|
462
565
|
`
|
|
463
566
|
)
|
|
464
567
|
.run(
|
|
@@ -472,6 +575,7 @@ export class SqliteAgentThreadStore implements AgentThreadStore {
|
|
|
472
575
|
thread.status,
|
|
473
576
|
thread.lastMessageAt?.toISOString() ?? null,
|
|
474
577
|
thread.messageCount,
|
|
578
|
+
thread.movedAt?.toISOString() ?? null,
|
|
475
579
|
thread.createdAt.toISOString(),
|
|
476
580
|
thread.updatedAt.toISOString()
|
|
477
581
|
)
|