@soleri/core 2.5.0 → 2.7.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/brain/intelligence.d.ts +1 -0
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +160 -148
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/control/identity-manager.d.ts +3 -1
- package/dist/control/identity-manager.d.ts.map +1 -1
- package/dist/control/identity-manager.js +53 -51
- package/dist/control/identity-manager.js.map +1 -1
- package/dist/control/intent-router.d.ts +1 -0
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +41 -32
- package/dist/control/intent-router.js.map +1 -1
- package/dist/curator/curator.d.ts +1 -0
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +58 -99
- package/dist/curator/curator.js.map +1 -1
- package/dist/facades/facade-factory.js +1 -1
- package/dist/facades/facade-factory.js.map +1 -1
- package/dist/governance/governance.d.ts +1 -0
- package/dist/governance/governance.d.ts.map +1 -1
- package/dist/governance/governance.js +51 -68
- package/dist/governance/governance.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/persistence/index.d.ts +2 -1
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +1 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/persistence/postgres-provider.d.ts +46 -0
- package/dist/persistence/postgres-provider.d.ts.map +1 -0
- package/dist/persistence/postgres-provider.js +115 -0
- package/dist/persistence/postgres-provider.js.map +1 -0
- package/dist/persistence/sqlite-provider.d.ts +5 -2
- package/dist/persistence/sqlite-provider.d.ts.map +1 -1
- package/dist/persistence/sqlite-provider.js +37 -1
- package/dist/persistence/sqlite-provider.js.map +1 -1
- package/dist/persistence/types.d.ts +23 -1
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/project/project-registry.d.ts +4 -4
- package/dist/project/project-registry.d.ts.map +1 -1
- package/dist/project/project-registry.js +32 -50
- package/dist/project/project-registry.js.map +1 -1
- package/dist/runtime/admin-extra-ops.d.ts +3 -3
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +33 -3
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/core-ops.d.ts +4 -4
- package/dist/runtime/core-ops.js +4 -4
- package/dist/runtime/runtime.js +1 -1
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +3 -2
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.js +40 -2
- package/dist/runtime/vault-extra-ops.js.map +1 -1
- package/dist/vault/vault.d.ts +21 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +99 -0
- package/dist/vault/vault.js.map +1 -1
- package/package.json +4 -2
- package/src/__tests__/admin-extra-ops.test.ts +2 -2
- package/src/__tests__/core-ops.test.ts +8 -2
- package/src/__tests__/persistence.test.ts +66 -0
- package/src/__tests__/postgres-provider.test.ts +58 -0
- package/src/__tests__/vault-extra-ops.test.ts +2 -2
- package/src/__tests__/vault.test.ts +184 -0
- package/src/brain/intelligence.ts +258 -307
- package/src/control/identity-manager.ts +77 -75
- package/src/control/intent-router.ts +55 -57
- package/src/curator/curator.ts +124 -145
- package/src/facades/facade-factory.ts +1 -1
- package/src/governance/governance.ts +90 -107
- package/src/index.ts +2 -0
- package/src/persistence/index.ts +2 -0
- package/src/persistence/postgres-provider.ts +157 -0
- package/src/persistence/sqlite-provider.ts +55 -2
- package/src/persistence/types.ts +31 -1
- package/src/project/project-registry.ts +69 -74
- package/src/runtime/admin-extra-ops.ts +36 -3
- package/src/runtime/core-ops.ts +4 -4
- package/src/runtime/runtime.ts +1 -1
- package/src/runtime/vault-extra-ops.ts +42 -2
- package/src/vault/vault.ts +118 -0
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
* IdentityManager — Agent identity CRUD with versioning and rollback.
|
|
3
3
|
*
|
|
4
4
|
* Follows the Curator/BrainIntelligence pattern: separate class, own SQLite
|
|
5
|
-
* tables, takes Vault as constructor dep.
|
|
5
|
+
* tables, takes Vault as constructor dep. Uses PersistenceProvider abstraction
|
|
6
|
+
* for all database access.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import { randomUUID } from 'node:crypto';
|
|
9
10
|
import type { Vault } from '../vault/vault.js';
|
|
11
|
+
import type { PersistenceProvider } from '../persistence/types.js';
|
|
10
12
|
import type {
|
|
11
13
|
AgentIdentity,
|
|
12
14
|
IdentityVersion,
|
|
@@ -20,17 +22,18 @@ import type {
|
|
|
20
22
|
|
|
21
23
|
export class IdentityManager {
|
|
22
24
|
private vault: Vault;
|
|
25
|
+
private provider: PersistenceProvider;
|
|
23
26
|
|
|
24
27
|
constructor(vault: Vault) {
|
|
25
28
|
this.vault = vault;
|
|
29
|
+
this.provider = vault.getProvider();
|
|
26
30
|
this.initializeTables();
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
// ─── Table Initialization ───────────────────────────────────────────
|
|
30
34
|
|
|
31
35
|
private initializeTables(): void {
|
|
32
|
-
|
|
33
|
-
db.exec(`
|
|
36
|
+
this.provider.execSql(`
|
|
34
37
|
CREATE TABLE IF NOT EXISTS agent_identity (
|
|
35
38
|
agent_id TEXT PRIMARY KEY,
|
|
36
39
|
name TEXT NOT NULL,
|
|
@@ -38,7 +41,7 @@ export class IdentityManager {
|
|
|
38
41
|
description TEXT NOT NULL DEFAULT '',
|
|
39
42
|
personality TEXT NOT NULL DEFAULT '[]',
|
|
40
43
|
version INTEGER NOT NULL DEFAULT 1,
|
|
41
|
-
updated_at
|
|
44
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
42
45
|
);
|
|
43
46
|
|
|
44
47
|
CREATE TABLE IF NOT EXISTS agent_identity_versions (
|
|
@@ -48,7 +51,7 @@ export class IdentityManager {
|
|
|
48
51
|
snapshot TEXT NOT NULL,
|
|
49
52
|
changed_by TEXT NOT NULL DEFAULT 'system',
|
|
50
53
|
change_reason TEXT NOT NULL DEFAULT '',
|
|
51
|
-
created_at
|
|
54
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
52
55
|
UNIQUE(agent_id, version)
|
|
53
56
|
);
|
|
54
57
|
|
|
@@ -58,8 +61,8 @@ export class IdentityManager {
|
|
|
58
61
|
category TEXT NOT NULL CHECK(category IN ('behavior', 'preference', 'restriction', 'style')),
|
|
59
62
|
text TEXT NOT NULL,
|
|
60
63
|
priority INTEGER NOT NULL DEFAULT 0,
|
|
61
|
-
created_at
|
|
62
|
-
updated_at
|
|
64
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
65
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
63
66
|
);
|
|
64
67
|
|
|
65
68
|
CREATE INDEX IF NOT EXISTS idx_guidelines_agent
|
|
@@ -72,10 +75,9 @@ export class IdentityManager {
|
|
|
72
75
|
// ─── Identity CRUD ──────────────────────────────────────────────────
|
|
73
76
|
|
|
74
77
|
getIdentity(agentId: string): AgentIdentity | null {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| undefined;
|
|
78
|
+
const row = this.provider.get<IdentityRow>('SELECT * FROM agent_identity WHERE agent_id = ?', [
|
|
79
|
+
agentId,
|
|
80
|
+
]);
|
|
79
81
|
if (!row) return null;
|
|
80
82
|
|
|
81
83
|
const guidelines = this.getGuidelines(agentId);
|
|
@@ -83,25 +85,25 @@ export class IdentityManager {
|
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
setIdentity(agentId: string, input: IdentityUpdateInput): AgentIdentity {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
| undefined;
|
|
88
|
+
this.provider.transaction(() => {
|
|
89
|
+
const existing = this.provider.get<IdentityRow>(
|
|
90
|
+
'SELECT * FROM agent_identity WHERE agent_id = ?',
|
|
91
|
+
[agentId],
|
|
92
|
+
);
|
|
92
93
|
|
|
93
94
|
if (existing) {
|
|
94
95
|
// Snapshot current state before updating
|
|
95
96
|
const snapshot = JSON.stringify(rowToIdentitySnapshot(existing));
|
|
96
|
-
|
|
97
|
+
this.provider.run(
|
|
97
98
|
`INSERT INTO agent_identity_versions (agent_id, version, snapshot, changed_by, change_reason)
|
|
98
99
|
VALUES (?, ?, ?, ?, ?)`,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
[
|
|
101
|
+
agentId,
|
|
102
|
+
existing.version,
|
|
103
|
+
snapshot,
|
|
104
|
+
input.changedBy ?? 'system',
|
|
105
|
+
input.changeReason ?? '',
|
|
106
|
+
],
|
|
105
107
|
);
|
|
106
108
|
|
|
107
109
|
const newVersion = existing.version + 1;
|
|
@@ -112,12 +114,13 @@ export class IdentityManager {
|
|
|
112
114
|
? JSON.stringify(input.personality)
|
|
113
115
|
: existing.personality;
|
|
114
116
|
|
|
115
|
-
|
|
117
|
+
this.provider.run(
|
|
116
118
|
`UPDATE agent_identity
|
|
117
119
|
SET name = ?, role = ?, description = ?, personality = ?,
|
|
118
|
-
version = ?, updated_at =
|
|
120
|
+
version = ?, updated_at = unixepoch()
|
|
119
121
|
WHERE agent_id = ?`,
|
|
120
|
-
|
|
122
|
+
[name, role, description, personality, newVersion, agentId],
|
|
123
|
+
);
|
|
121
124
|
} else {
|
|
122
125
|
// First identity creation — version 1
|
|
123
126
|
const name = input.name ?? agentId;
|
|
@@ -125,12 +128,13 @@ export class IdentityManager {
|
|
|
125
128
|
const description = input.description ?? '';
|
|
126
129
|
const personality = JSON.stringify(input.personality ?? []);
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
this.provider.run(
|
|
129
132
|
`INSERT INTO agent_identity (agent_id, name, role, description, personality, version)
|
|
130
133
|
VALUES (?, ?, ?, ?, ?, 1)`,
|
|
131
|
-
|
|
134
|
+
[agentId, name, role, description, personality],
|
|
135
|
+
);
|
|
132
136
|
}
|
|
133
|
-
})
|
|
137
|
+
});
|
|
134
138
|
|
|
135
139
|
return this.getIdentity(agentId)!;
|
|
136
140
|
}
|
|
@@ -138,94 +142,92 @@ export class IdentityManager {
|
|
|
138
142
|
// ─── Guidelines ─────────────────────────────────────────────────────
|
|
139
143
|
|
|
140
144
|
addGuideline(agentId: string, input: GuidelineInput): Guideline {
|
|
141
|
-
const db = this.vault.getDb();
|
|
142
145
|
const id = randomUUID();
|
|
143
146
|
const priority = input.priority ?? 0;
|
|
144
147
|
|
|
145
|
-
|
|
148
|
+
this.provider.run(
|
|
146
149
|
`INSERT INTO agent_guidelines (id, agent_id, category, text, priority)
|
|
147
150
|
VALUES (?, ?, ?, ?, ?)`,
|
|
148
|
-
|
|
151
|
+
[id, agentId, input.category, input.text, priority],
|
|
152
|
+
);
|
|
149
153
|
|
|
150
|
-
const row =
|
|
151
|
-
|
|
154
|
+
const row = this.provider.get<GuidelineRow>('SELECT * FROM agent_guidelines WHERE id = ?', [
|
|
155
|
+
id,
|
|
156
|
+
]);
|
|
157
|
+
return rowToGuideline(row!);
|
|
152
158
|
}
|
|
153
159
|
|
|
154
160
|
removeGuideline(guidelineId: string): boolean {
|
|
155
|
-
const
|
|
156
|
-
const result = db.prepare('DELETE FROM agent_guidelines WHERE id = ?').run(guidelineId);
|
|
161
|
+
const result = this.provider.run('DELETE FROM agent_guidelines WHERE id = ?', [guidelineId]);
|
|
157
162
|
return result.changes > 0;
|
|
158
163
|
}
|
|
159
164
|
|
|
160
165
|
getGuidelines(agentId: string, category?: GuidelineCategory): Guideline[] {
|
|
161
|
-
const db = this.vault.getDb();
|
|
162
166
|
if (category) {
|
|
163
|
-
const rows =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.all(agentId, category) as GuidelineRow[];
|
|
167
|
+
const rows = this.provider.all<GuidelineRow>(
|
|
168
|
+
'SELECT * FROM agent_guidelines WHERE agent_id = ? AND category = ? ORDER BY priority DESC, created_at ASC',
|
|
169
|
+
[agentId, category],
|
|
170
|
+
);
|
|
168
171
|
return rows.map(rowToGuideline);
|
|
169
172
|
}
|
|
170
|
-
const rows =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
.all(agentId) as GuidelineRow[];
|
|
173
|
+
const rows = this.provider.all<GuidelineRow>(
|
|
174
|
+
'SELECT * FROM agent_guidelines WHERE agent_id = ? ORDER BY priority DESC, created_at ASC',
|
|
175
|
+
[agentId],
|
|
176
|
+
);
|
|
175
177
|
return rows.map(rowToGuideline);
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
// ─── Versioning ─────────────────────────────────────────────────────
|
|
179
181
|
|
|
180
182
|
getVersionHistory(agentId: string, limit = 20): IdentityVersion[] {
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
)
|
|
186
|
-
.all(agentId, limit) as VersionRow[];
|
|
183
|
+
const rows = this.provider.all<VersionRow>(
|
|
184
|
+
'SELECT * FROM agent_identity_versions WHERE agent_id = ? ORDER BY version DESC LIMIT ?',
|
|
185
|
+
[agentId, limit],
|
|
186
|
+
);
|
|
187
187
|
return rows.map(rowToVersion);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
rollback(agentId: string, version: number): AgentIdentity {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
.get(agentId, version) as VersionRow | undefined;
|
|
191
|
+
this.provider.transaction(() => {
|
|
192
|
+
const versionRow = this.provider.get<VersionRow>(
|
|
193
|
+
'SELECT * FROM agent_identity_versions WHERE agent_id = ? AND version = ?',
|
|
194
|
+
[agentId, version],
|
|
195
|
+
);
|
|
197
196
|
|
|
198
197
|
if (!versionRow) {
|
|
199
198
|
throw new Error(`Version ${version} not found for agent ${agentId}`);
|
|
200
199
|
}
|
|
201
200
|
|
|
202
201
|
const snapshot = JSON.parse(versionRow.snapshot) as IdentitySnapshot;
|
|
203
|
-
const current =
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
const current = this.provider.get<IdentityRow>(
|
|
203
|
+
'SELECT * FROM agent_identity WHERE agent_id = ?',
|
|
204
|
+
[agentId],
|
|
205
|
+
)!;
|
|
206
206
|
|
|
207
207
|
// Snapshot current state before rollback
|
|
208
208
|
const currentSnapshot = JSON.stringify(rowToIdentitySnapshot(current));
|
|
209
|
-
|
|
209
|
+
this.provider.run(
|
|
210
210
|
`INSERT INTO agent_identity_versions (agent_id, version, snapshot, changed_by, change_reason)
|
|
211
211
|
VALUES (?, ?, ?, ?, ?)`,
|
|
212
|
-
|
|
212
|
+
[agentId, current.version, currentSnapshot, 'system', `Before rollback to v${version}`],
|
|
213
|
+
);
|
|
213
214
|
|
|
214
215
|
const newVersion = current.version + 1;
|
|
215
|
-
|
|
216
|
+
this.provider.run(
|
|
216
217
|
`UPDATE agent_identity
|
|
217
218
|
SET name = ?, role = ?, description = ?, personality = ?,
|
|
218
|
-
version = ?, updated_at =
|
|
219
|
+
version = ?, updated_at = unixepoch()
|
|
219
220
|
WHERE agent_id = ?`,
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
[
|
|
222
|
+
snapshot.name,
|
|
223
|
+
snapshot.role,
|
|
224
|
+
snapshot.description,
|
|
225
|
+
JSON.stringify(snapshot.personality),
|
|
226
|
+
newVersion,
|
|
227
|
+
agentId,
|
|
228
|
+
],
|
|
227
229
|
);
|
|
228
|
-
})
|
|
230
|
+
});
|
|
229
231
|
|
|
230
232
|
return this.getIdentity(agentId)!;
|
|
231
233
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { Vault } from '../vault/vault.js';
|
|
12
|
+
import type { PersistenceProvider } from '../persistence/types.js';
|
|
12
13
|
import type {
|
|
13
14
|
IntentType,
|
|
14
15
|
OperationalMode,
|
|
@@ -96,10 +97,12 @@ const DEFAULT_MODES: ModeConfig[] = [
|
|
|
96
97
|
|
|
97
98
|
export class IntentRouter {
|
|
98
99
|
private vault: Vault;
|
|
100
|
+
private provider: PersistenceProvider;
|
|
99
101
|
private currentMode: OperationalMode = 'GENERAL-MODE';
|
|
100
102
|
|
|
101
103
|
constructor(vault: Vault) {
|
|
102
104
|
this.vault = vault;
|
|
105
|
+
this.provider = vault.getProvider();
|
|
103
106
|
this.initializeTables();
|
|
104
107
|
this.seedDefaultModes();
|
|
105
108
|
}
|
|
@@ -107,8 +110,7 @@ export class IntentRouter {
|
|
|
107
110
|
// ─── Table Initialization ───────────────────────────────────────────
|
|
108
111
|
|
|
109
112
|
private initializeTables(): void {
|
|
110
|
-
|
|
111
|
-
db.exec(`
|
|
113
|
+
this.provider.execSql(`
|
|
112
114
|
CREATE TABLE IF NOT EXISTS agent_modes (
|
|
113
115
|
mode TEXT PRIMARY KEY,
|
|
114
116
|
intent TEXT NOT NULL,
|
|
@@ -130,20 +132,21 @@ export class IntentRouter {
|
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
private seedDefaultModes(): void {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
135
|
+
this.provider.transaction(() => {
|
|
136
|
+
for (const m of DEFAULT_MODES) {
|
|
137
|
+
this.provider.run(
|
|
138
|
+
`INSERT OR IGNORE INTO agent_modes (mode, intent, description, behavior_rules, keywords)
|
|
139
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
140
|
+
[
|
|
141
|
+
m.mode,
|
|
142
|
+
m.intent,
|
|
143
|
+
m.description,
|
|
144
|
+
JSON.stringify(m.behaviorRules),
|
|
145
|
+
JSON.stringify(m.keywords),
|
|
146
|
+
],
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
// ─── Intent Classification ──────────────────────────────────────────
|
|
@@ -194,26 +197,23 @@ export class IntentRouter {
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
private logRouting(prompt: string, classification: IntentClassification): void {
|
|
197
|
-
|
|
198
|
-
db.prepare(
|
|
200
|
+
this.provider.run(
|
|
199
201
|
`INSERT INTO agent_routing_log (prompt, intent, mode, confidence, matched_keywords)
|
|
200
202
|
VALUES (?, ?, ?, ?, ?)`,
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
[
|
|
204
|
+
prompt,
|
|
205
|
+
classification.intent,
|
|
206
|
+
classification.mode,
|
|
207
|
+
classification.confidence,
|
|
208
|
+
JSON.stringify(classification.matchedKeywords),
|
|
209
|
+
],
|
|
207
210
|
);
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
// ─── Mode Management ───────────────────────────────────────────────
|
|
211
214
|
|
|
212
215
|
morph(mode: OperationalMode): MorphResult {
|
|
213
|
-
const
|
|
214
|
-
const row = db.prepare('SELECT * FROM agent_modes WHERE mode = ?').get(mode) as
|
|
215
|
-
| ModeRow
|
|
216
|
-
| undefined;
|
|
216
|
+
const row = this.provider.get<ModeRow>('SELECT * FROM agent_modes WHERE mode = ?', [mode]);
|
|
217
217
|
|
|
218
218
|
if (!row) {
|
|
219
219
|
throw new Error(`Unknown mode: ${mode}`);
|
|
@@ -231,41 +231,40 @@ export class IntentRouter {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
getBehaviorRules(mode?: OperationalMode): string[] {
|
|
234
|
-
const db = this.vault.getDb();
|
|
235
234
|
const target = mode ?? this.currentMode;
|
|
236
|
-
const row =
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
const row = this.provider.get<{ behavior_rules: string }>(
|
|
236
|
+
'SELECT behavior_rules FROM agent_modes WHERE mode = ?',
|
|
237
|
+
[target],
|
|
238
|
+
);
|
|
239
239
|
|
|
240
240
|
if (!row) return [];
|
|
241
241
|
return JSON.parse(row.behavior_rules) as string[];
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
getModes(): ModeConfig[] {
|
|
245
|
-
const
|
|
246
|
-
const rows = db.prepare('SELECT * FROM agent_modes ORDER BY mode').all() as ModeRow[];
|
|
245
|
+
const rows = this.provider.all<ModeRow>('SELECT * FROM agent_modes ORDER BY mode');
|
|
247
246
|
return rows.map(rowToModeConfig);
|
|
248
247
|
}
|
|
249
248
|
|
|
250
249
|
registerMode(config: ModeConfig): void {
|
|
251
|
-
|
|
252
|
-
db.prepare(
|
|
250
|
+
this.provider.run(
|
|
253
251
|
`INSERT OR REPLACE INTO agent_modes (mode, intent, description, behavior_rules, keywords)
|
|
254
252
|
VALUES (?, ?, ?, ?, ?)`,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
253
|
+
[
|
|
254
|
+
config.mode,
|
|
255
|
+
config.intent,
|
|
256
|
+
config.description,
|
|
257
|
+
JSON.stringify(config.behaviorRules),
|
|
258
|
+
JSON.stringify(config.keywords),
|
|
259
|
+
],
|
|
261
260
|
);
|
|
262
261
|
}
|
|
263
262
|
|
|
264
263
|
updateModeRules(mode: OperationalMode, rules: string[]): void {
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
264
|
+
const result = this.provider.run('UPDATE agent_modes SET behavior_rules = ? WHERE mode = ?', [
|
|
265
|
+
JSON.stringify(rules),
|
|
266
|
+
mode,
|
|
267
|
+
]);
|
|
269
268
|
if (result.changes === 0) {
|
|
270
269
|
throw new Error(`Unknown mode: ${mode}`);
|
|
271
270
|
}
|
|
@@ -278,22 +277,21 @@ export class IntentRouter {
|
|
|
278
277
|
byIntent: Record<string, number>;
|
|
279
278
|
byMode: Record<string, number>;
|
|
280
279
|
} {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
.all() as Array<{ intent: string; count: number }>;
|
|
280
|
+
const total = this.provider.get<{ count: number }>(
|
|
281
|
+
'SELECT COUNT(*) as count FROM agent_routing_log',
|
|
282
|
+
)!.count;
|
|
283
|
+
|
|
284
|
+
const intentRows = this.provider.all<{ intent: string; count: number }>(
|
|
285
|
+
'SELECT intent, COUNT(*) as count FROM agent_routing_log GROUP BY intent',
|
|
286
|
+
);
|
|
289
287
|
const byIntent: Record<string, number> = {};
|
|
290
288
|
for (const row of intentRows) {
|
|
291
289
|
byIntent[row.intent] = row.count;
|
|
292
290
|
}
|
|
293
291
|
|
|
294
|
-
const modeRows =
|
|
295
|
-
|
|
296
|
-
|
|
292
|
+
const modeRows = this.provider.all<{ mode: string; count: number }>(
|
|
293
|
+
'SELECT mode, COUNT(*) as count FROM agent_routing_log GROUP BY mode',
|
|
294
|
+
);
|
|
297
295
|
const byMode: Record<string, number> = {};
|
|
298
296
|
for (const row of modeRows) {
|
|
299
297
|
byMode[row.mode] = row.count;
|