@cogitator-ai/core 0.1.0 → 0.3.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/README.md +920 -15
- package/dist/__tests__/agent.test.js +2 -2
- package/dist/__tests__/agent.test.js.map +1 -1
- package/dist/__tests__/base64.test.js +1 -1
- package/dist/__tests__/base64.test.js.map +1 -1
- package/dist/__tests__/calculator.test.js +1 -1
- package/dist/__tests__/calculator.test.js.map +1 -1
- package/dist/__tests__/cogitator-memory.test.js +2 -2
- package/dist/__tests__/cogitator-memory.test.js.map +1 -1
- package/dist/__tests__/datetime.test.js +1 -1
- package/dist/__tests__/datetime.test.js.map +1 -1
- package/dist/__tests__/exec.test.js +1 -1
- package/dist/__tests__/exec.test.js.map +1 -1
- package/dist/__tests__/filesystem.test.js +1 -1
- package/dist/__tests__/filesystem.test.js.map +1 -1
- package/dist/__tests__/google-backend.test.js +1 -1
- package/dist/__tests__/google-backend.test.js.map +1 -1
- package/dist/__tests__/hash.test.js +1 -1
- package/dist/__tests__/hash.test.js.map +1 -1
- package/dist/__tests__/http.test.js +1 -1
- package/dist/__tests__/http.test.js.map +1 -1
- package/dist/__tests__/json.test.js +1 -1
- package/dist/__tests__/json.test.js.map +1 -1
- package/dist/__tests__/logger.test.js +1 -1
- package/dist/__tests__/logger.test.js.map +1 -1
- package/dist/__tests__/random.test.js +1 -1
- package/dist/__tests__/random.test.js.map +1 -1
- package/dist/__tests__/regex.test.js +1 -1
- package/dist/__tests__/regex.test.js.map +1 -1
- package/dist/__tests__/registry.test.js +2 -2
- package/dist/__tests__/registry.test.js.map +1 -1
- package/dist/__tests__/sleep.test.js +1 -1
- package/dist/__tests__/sleep.test.js.map +1 -1
- package/dist/__tests__/tool.test.js +1 -1
- package/dist/__tests__/tool.test.js.map +1 -1
- package/dist/__tests__/uuid.test.js +1 -1
- package/dist/__tests__/uuid.test.js.map +1 -1
- package/dist/cogitator.d.ts +46 -1
- package/dist/cogitator.d.ts.map +1 -1
- package/dist/cogitator.js +274 -17
- package/dist/cogitator.js.map +1 -1
- package/dist/constitutional/constitution.d.ts +9 -0
- package/dist/constitutional/constitution.d.ts.map +1 -0
- package/dist/constitutional/constitution.js +215 -0
- package/dist/constitutional/constitution.js.map +1 -0
- package/dist/constitutional/constitutional-ai.d.ts +36 -0
- package/dist/constitutional/constitutional-ai.d.ts.map +1 -0
- package/dist/constitutional/constitutional-ai.js +163 -0
- package/dist/constitutional/constitutional-ai.js.map +1 -0
- package/dist/constitutional/critique-reviser.d.ts +20 -0
- package/dist/constitutional/critique-reviser.d.ts.map +1 -0
- package/dist/constitutional/critique-reviser.js +98 -0
- package/dist/constitutional/critique-reviser.js.map +1 -0
- package/dist/constitutional/index.d.ts +13 -0
- package/dist/constitutional/index.d.ts.map +1 -0
- package/dist/constitutional/index.js +8 -0
- package/dist/constitutional/index.js.map +1 -0
- package/dist/constitutional/input-filter.d.ts +19 -0
- package/dist/constitutional/input-filter.d.ts.map +1 -0
- package/dist/constitutional/input-filter.js +88 -0
- package/dist/constitutional/input-filter.js.map +1 -0
- package/dist/constitutional/output-filter.d.ts +19 -0
- package/dist/constitutional/output-filter.d.ts.map +1 -0
- package/dist/constitutional/output-filter.js +86 -0
- package/dist/constitutional/output-filter.js.map +1 -0
- package/dist/constitutional/prompts.d.ts +11 -0
- package/dist/constitutional/prompts.d.ts.map +1 -0
- package/dist/constitutional/prompts.js +202 -0
- package/dist/constitutional/prompts.js.map +1 -0
- package/dist/constitutional/tool-guard.d.ts +18 -0
- package/dist/constitutional/tool-guard.d.ts.map +1 -0
- package/dist/constitutional/tool-guard.js +125 -0
- package/dist/constitutional/tool-guard.js.map +1 -0
- package/dist/cost-routing/budget-enforcer.d.ts +26 -0
- package/dist/cost-routing/budget-enforcer.d.ts.map +1 -0
- package/dist/cost-routing/budget-enforcer.js +86 -0
- package/dist/cost-routing/budget-enforcer.js.map +1 -0
- package/dist/cost-routing/cost-router.d.ts +34 -0
- package/dist/cost-routing/cost-router.d.ts.map +1 -0
- package/dist/cost-routing/cost-router.js +80 -0
- package/dist/cost-routing/cost-router.js.map +1 -0
- package/dist/cost-routing/cost-tracker.d.ts +20 -0
- package/dist/cost-routing/cost-tracker.d.ts.map +1 -0
- package/dist/cost-routing/cost-tracker.js +85 -0
- package/dist/cost-routing/cost-tracker.js.map +1 -0
- package/dist/cost-routing/index.d.ts +6 -0
- package/dist/cost-routing/index.d.ts.map +1 -0
- package/dist/cost-routing/index.js +6 -0
- package/dist/cost-routing/index.js.map +1 -0
- package/dist/cost-routing/model-selector.d.ts +15 -0
- package/dist/cost-routing/model-selector.d.ts.map +1 -0
- package/dist/cost-routing/model-selector.js +216 -0
- package/dist/cost-routing/model-selector.js.map +1 -0
- package/dist/cost-routing/task-analyzer.d.ts +13 -0
- package/dist/cost-routing/task-analyzer.d.ts.map +1 -0
- package/dist/cost-routing/task-analyzer.js +185 -0
- package/dist/cost-routing/task-analyzer.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/learning/ab-testing.d.ts +45 -0
- package/dist/learning/ab-testing.d.ts.map +1 -0
- package/dist/learning/ab-testing.js +267 -0
- package/dist/learning/ab-testing.js.map +1 -0
- package/dist/learning/agent-optimizer.d.ts +42 -0
- package/dist/learning/agent-optimizer.d.ts.map +1 -0
- package/dist/learning/agent-optimizer.js +273 -0
- package/dist/learning/agent-optimizer.js.map +1 -0
- package/dist/learning/auto-optimizer.d.ts +38 -0
- package/dist/learning/auto-optimizer.d.ts.map +1 -0
- package/dist/learning/auto-optimizer.js +229 -0
- package/dist/learning/auto-optimizer.js.map +1 -0
- package/dist/learning/demo-selector.d.ts +29 -0
- package/dist/learning/demo-selector.d.ts.map +1 -0
- package/dist/learning/demo-selector.js +235 -0
- package/dist/learning/demo-selector.js.map +1 -0
- package/dist/learning/index.d.ts +24 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +13 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/instruction-optimizer.d.ts +29 -0
- package/dist/learning/instruction-optimizer.d.ts.map +1 -0
- package/dist/learning/instruction-optimizer.js +175 -0
- package/dist/learning/instruction-optimizer.js.map +1 -0
- package/dist/learning/metrics.d.ts +37 -0
- package/dist/learning/metrics.d.ts.map +1 -0
- package/dist/learning/metrics.js +310 -0
- package/dist/learning/metrics.js.map +1 -0
- package/dist/learning/postgres-trace-store.d.ts +53 -0
- package/dist/learning/postgres-trace-store.d.ts.map +1 -0
- package/dist/learning/postgres-trace-store.js +692 -0
- package/dist/learning/postgres-trace-store.js.map +1 -0
- package/dist/learning/prompt-logger.d.ts +29 -0
- package/dist/learning/prompt-logger.d.ts.map +1 -0
- package/dist/learning/prompt-logger.js +157 -0
- package/dist/learning/prompt-logger.js.map +1 -0
- package/dist/learning/prompt-monitor.d.ts +29 -0
- package/dist/learning/prompt-monitor.d.ts.map +1 -0
- package/dist/learning/prompt-monitor.js +243 -0
- package/dist/learning/prompt-monitor.js.map +1 -0
- package/dist/learning/prompts.d.ts +28 -0
- package/dist/learning/prompts.d.ts.map +1 -0
- package/dist/learning/prompts.js +195 -0
- package/dist/learning/prompts.js.map +1 -0
- package/dist/learning/rollback-manager.d.ts +36 -0
- package/dist/learning/rollback-manager.d.ts.map +1 -0
- package/dist/learning/rollback-manager.js +177 -0
- package/dist/learning/rollback-manager.js.map +1 -0
- package/dist/learning/trace-store.d.ts +26 -0
- package/dist/learning/trace-store.d.ts.map +1 -0
- package/dist/learning/trace-store.js +218 -0
- package/dist/learning/trace-store.js.map +1 -0
- package/dist/llm/google.d.ts.map +1 -1
- package/dist/llm/google.js +1 -2
- package/dist/llm/google.js.map +1 -1
- package/dist/reasoning/branch-evaluator.d.ts +28 -0
- package/dist/reasoning/branch-evaluator.d.ts.map +1 -0
- package/dist/reasoning/branch-evaluator.js +143 -0
- package/dist/reasoning/branch-evaluator.js.map +1 -0
- package/dist/reasoning/branch-generator.d.ts +9 -0
- package/dist/reasoning/branch-generator.d.ts.map +1 -0
- package/dist/reasoning/branch-generator.js +60 -0
- package/dist/reasoning/branch-generator.js.map +1 -0
- package/dist/reasoning/index.d.ts +5 -0
- package/dist/reasoning/index.d.ts.map +1 -0
- package/dist/reasoning/index.js +5 -0
- package/dist/reasoning/index.js.map +1 -0
- package/dist/reasoning/prompts.d.ts +19 -0
- package/dist/reasoning/prompts.d.ts.map +1 -0
- package/dist/reasoning/prompts.js +161 -0
- package/dist/reasoning/prompts.js.map +1 -0
- package/dist/reasoning/thought-tree.d.ts +32 -0
- package/dist/reasoning/thought-tree.d.ts.map +1 -0
- package/dist/reasoning/thought-tree.js +352 -0
- package/dist/reasoning/thought-tree.js.map +1 -0
- package/dist/reflection/index.d.ts +4 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/dist/reflection/index.js +4 -0
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/insight-store.d.ts +19 -0
- package/dist/reflection/insight-store.d.ts.map +1 -0
- package/dist/reflection/insight-store.js +129 -0
- package/dist/reflection/insight-store.js.map +1 -0
- package/dist/reflection/prompts.d.ts +18 -0
- package/dist/reflection/prompts.d.ts.map +1 -0
- package/dist/reflection/prompts.js +157 -0
- package/dist/reflection/prompts.js.map +1 -0
- package/dist/reflection/reflection-engine.d.ts +25 -0
- package/dist/reflection/reflection-engine.d.ts.map +1 -0
- package/dist/reflection/reflection-engine.js +202 -0
- package/dist/reflection/reflection-engine.js.map +1 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +3 -0
- package/dist/registry.js.map +1 -1
- package/dist/time-travel/checkpoint-store.d.ts +34 -0
- package/dist/time-travel/checkpoint-store.d.ts.map +1 -0
- package/dist/time-travel/checkpoint-store.js +240 -0
- package/dist/time-travel/checkpoint-store.js.map +1 -0
- package/dist/time-travel/comparator.d.ts +26 -0
- package/dist/time-travel/comparator.d.ts.map +1 -0
- package/dist/time-travel/comparator.js +253 -0
- package/dist/time-travel/comparator.js.map +1 -0
- package/dist/time-travel/forker.d.ts +22 -0
- package/dist/time-travel/forker.d.ts.map +1 -0
- package/dist/time-travel/forker.js +118 -0
- package/dist/time-travel/forker.js.map +1 -0
- package/dist/time-travel/index.d.ts +6 -0
- package/dist/time-travel/index.d.ts.map +1 -0
- package/dist/time-travel/index.js +6 -0
- package/dist/time-travel/index.js.map +1 -0
- package/dist/time-travel/replayer.d.ts +20 -0
- package/dist/time-travel/replayer.d.ts.map +1 -0
- package/dist/time-travel/replayer.js +147 -0
- package/dist/time-travel/replayer.js.map +1 -0
- package/dist/time-travel/time-travel.d.ts +41 -0
- package/dist/time-travel/time-travel.d.ts.map +1 -0
- package/dist/time-travel/time-travel.js +127 -0
- package/dist/time-travel/time-travel.js.map +1 -0
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +2 -0
- package/dist/tool.js.map +1 -1
- package/dist/tools/base64.d.ts.map +1 -1
- package/dist/tools/base64.js +2 -8
- package/dist/tools/base64.js.map +1 -1
- package/dist/tools/datetime.d.ts.map +1 -1
- package/dist/tools/datetime.js.map +1 -1
- package/dist/tools/exec.d.ts.map +1 -1
- package/dist/tools/exec.js +1 -4
- package/dist/tools/exec.js.map +1 -1
- package/dist/tools/filesystem.d.ts.map +1 -1
- package/dist/tools/filesystem.js +4 -1
- package/dist/tools/filesystem.js.map +1 -1
- package/dist/tools/hash.d.ts.map +1 -1
- package/dist/tools/hash.js +1 -4
- package/dist/tools/hash.js.map +1 -1
- package/dist/tools/http.d.ts.map +1 -1
- package/dist/tools/http.js +1 -4
- package/dist/tools/http.js.map +1 -1
- package/dist/tools/regex.d.ts.map +1 -1
- package/dist/tools/regex.js +4 -1
- package/dist/tools/regex.js.map +1 -1
- package/dist/utils/circuit-breaker.d.ts.map +1 -1
- package/dist/utils/circuit-breaker.js.map +1 -1
- package/dist/utils/fallback.d.ts.map +1 -1
- package/dist/utils/fallback.js +1 -4
- package/dist/utils/fallback.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +8 -13
- package/dist/utils/retry.js.map +1 -1
- package/package.json +17 -8
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
export class PostgresTraceStore {
|
|
3
|
+
pool = null;
|
|
4
|
+
config;
|
|
5
|
+
schema;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.schema = config.schema ?? 'cogitator';
|
|
9
|
+
}
|
|
10
|
+
async connect() {
|
|
11
|
+
const pg = await import('pg');
|
|
12
|
+
const { Pool } = pg.default ?? pg;
|
|
13
|
+
this.pool = new Pool({
|
|
14
|
+
connectionString: this.config.connectionString,
|
|
15
|
+
max: this.config.poolSize ?? 10,
|
|
16
|
+
});
|
|
17
|
+
const client = await this.pool.connect();
|
|
18
|
+
client.release();
|
|
19
|
+
await this.initSchema();
|
|
20
|
+
}
|
|
21
|
+
async disconnect() {
|
|
22
|
+
if (this.pool) {
|
|
23
|
+
await this.pool.end();
|
|
24
|
+
this.pool = null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async initSchema() {
|
|
28
|
+
if (!this.pool)
|
|
29
|
+
return;
|
|
30
|
+
await this.pool.query(`CREATE SCHEMA IF NOT EXISTS ${this.schema}`);
|
|
31
|
+
await this.pool.query(`
|
|
32
|
+
CREATE TABLE IF NOT EXISTS ${this.schema}.traces (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
run_id TEXT NOT NULL,
|
|
35
|
+
agent_id TEXT NOT NULL,
|
|
36
|
+
thread_id TEXT NOT NULL,
|
|
37
|
+
input TEXT NOT NULL,
|
|
38
|
+
output TEXT NOT NULL,
|
|
39
|
+
context JSONB,
|
|
40
|
+
steps JSONB NOT NULL,
|
|
41
|
+
tool_calls JSONB NOT NULL,
|
|
42
|
+
reflections JSONB,
|
|
43
|
+
metrics JSONB NOT NULL,
|
|
44
|
+
score REAL NOT NULL,
|
|
45
|
+
model TEXT NOT NULL,
|
|
46
|
+
duration INTEGER NOT NULL,
|
|
47
|
+
usage JSONB NOT NULL,
|
|
48
|
+
labels TEXT[],
|
|
49
|
+
is_demo BOOLEAN DEFAULT FALSE,
|
|
50
|
+
expected JSONB,
|
|
51
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
52
|
+
)
|
|
53
|
+
`);
|
|
54
|
+
await this.pool.query(`
|
|
55
|
+
CREATE TABLE IF NOT EXISTS ${this.schema}.prompts (
|
|
56
|
+
id TEXT PRIMARY KEY,
|
|
57
|
+
run_id TEXT NOT NULL,
|
|
58
|
+
agent_id TEXT NOT NULL,
|
|
59
|
+
thread_id TEXT NOT NULL,
|
|
60
|
+
model TEXT NOT NULL,
|
|
61
|
+
provider TEXT NOT NULL,
|
|
62
|
+
system_prompt TEXT NOT NULL,
|
|
63
|
+
messages JSONB NOT NULL,
|
|
64
|
+
tools JSONB,
|
|
65
|
+
injected_demos TEXT,
|
|
66
|
+
injected_insights TEXT,
|
|
67
|
+
temperature REAL,
|
|
68
|
+
top_p REAL,
|
|
69
|
+
max_tokens INTEGER,
|
|
70
|
+
prompt_tokens INTEGER NOT NULL,
|
|
71
|
+
response_content TEXT,
|
|
72
|
+
response_tool_calls JSONB,
|
|
73
|
+
completion_tokens INTEGER,
|
|
74
|
+
finish_reason TEXT,
|
|
75
|
+
latency_ms INTEGER,
|
|
76
|
+
metadata JSONB,
|
|
77
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
78
|
+
)
|
|
79
|
+
`);
|
|
80
|
+
await this.pool.query(`
|
|
81
|
+
CREATE TABLE IF NOT EXISTS ${this.schema}.ab_tests (
|
|
82
|
+
id TEXT PRIMARY KEY,
|
|
83
|
+
agent_id TEXT NOT NULL,
|
|
84
|
+
name TEXT NOT NULL,
|
|
85
|
+
description TEXT,
|
|
86
|
+
status TEXT NOT NULL,
|
|
87
|
+
control_instructions TEXT NOT NULL,
|
|
88
|
+
treatment_instructions TEXT NOT NULL,
|
|
89
|
+
treatment_allocation REAL NOT NULL,
|
|
90
|
+
min_sample_size INTEGER NOT NULL,
|
|
91
|
+
max_duration BIGINT NOT NULL,
|
|
92
|
+
confidence_level REAL NOT NULL,
|
|
93
|
+
metric_to_optimize TEXT NOT NULL,
|
|
94
|
+
control_results JSONB NOT NULL DEFAULT '{"sampleSize":0,"successRate":0,"avgScore":0,"avgLatency":0,"totalCost":0,"scores":[]}',
|
|
95
|
+
treatment_results JSONB NOT NULL DEFAULT '{"sampleSize":0,"successRate":0,"avgScore":0,"avgLatency":0,"totalCost":0,"scores":[]}',
|
|
96
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
97
|
+
started_at TIMESTAMPTZ,
|
|
98
|
+
completed_at TIMESTAMPTZ
|
|
99
|
+
)
|
|
100
|
+
`);
|
|
101
|
+
await this.pool.query(`
|
|
102
|
+
CREATE TABLE IF NOT EXISTS ${this.schema}.instruction_versions (
|
|
103
|
+
id TEXT PRIMARY KEY,
|
|
104
|
+
agent_id TEXT NOT NULL,
|
|
105
|
+
version INTEGER NOT NULL,
|
|
106
|
+
instructions TEXT NOT NULL,
|
|
107
|
+
source TEXT NOT NULL,
|
|
108
|
+
source_id TEXT,
|
|
109
|
+
deployed_at TIMESTAMPTZ NOT NULL,
|
|
110
|
+
retired_at TIMESTAMPTZ,
|
|
111
|
+
run_count INTEGER DEFAULT 0,
|
|
112
|
+
avg_score REAL DEFAULT 0,
|
|
113
|
+
success_rate REAL DEFAULT 0,
|
|
114
|
+
avg_latency REAL DEFAULT 0,
|
|
115
|
+
total_cost REAL DEFAULT 0,
|
|
116
|
+
parent_version_id TEXT
|
|
117
|
+
)
|
|
118
|
+
`);
|
|
119
|
+
await this.pool.query(`
|
|
120
|
+
CREATE INDEX IF NOT EXISTS idx_traces_agent_id
|
|
121
|
+
ON ${this.schema}.traces(agent_id, created_at)
|
|
122
|
+
`);
|
|
123
|
+
await this.pool.query(`
|
|
124
|
+
CREATE INDEX IF NOT EXISTS idx_traces_score
|
|
125
|
+
ON ${this.schema}.traces(agent_id, score)
|
|
126
|
+
`);
|
|
127
|
+
await this.pool.query(`
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_traces_is_demo
|
|
129
|
+
ON ${this.schema}.traces(agent_id, is_demo) WHERE is_demo = TRUE
|
|
130
|
+
`);
|
|
131
|
+
await this.pool.query(`
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_agent_id
|
|
133
|
+
ON ${this.schema}.prompts(agent_id, created_at)
|
|
134
|
+
`);
|
|
135
|
+
await this.pool.query(`
|
|
136
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_run_id
|
|
137
|
+
ON ${this.schema}.prompts(run_id)
|
|
138
|
+
`);
|
|
139
|
+
await this.pool.query(`
|
|
140
|
+
CREATE INDEX IF NOT EXISTS idx_ab_tests_agent_id
|
|
141
|
+
ON ${this.schema}.ab_tests(agent_id, status)
|
|
142
|
+
`);
|
|
143
|
+
await this.pool.query(`
|
|
144
|
+
CREATE INDEX IF NOT EXISTS idx_instruction_versions_agent
|
|
145
|
+
ON ${this.schema}.instruction_versions(agent_id, version DESC)
|
|
146
|
+
`);
|
|
147
|
+
}
|
|
148
|
+
generateId(prefix) {
|
|
149
|
+
return `${prefix}_${nanoid(12)}`;
|
|
150
|
+
}
|
|
151
|
+
async storeTrace(trace) {
|
|
152
|
+
if (!this.pool)
|
|
153
|
+
throw new Error('Not connected');
|
|
154
|
+
await this.pool.query(`INSERT INTO ${this.schema}.traces
|
|
155
|
+
(id, run_id, agent_id, thread_id, input, output, context, steps, tool_calls, reflections, metrics, score, model, duration, usage, labels, is_demo, expected, created_at)
|
|
156
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)`, [
|
|
157
|
+
trace.id,
|
|
158
|
+
trace.runId,
|
|
159
|
+
trace.agentId,
|
|
160
|
+
trace.threadId,
|
|
161
|
+
trace.input,
|
|
162
|
+
trace.output,
|
|
163
|
+
trace.context ?? null,
|
|
164
|
+
trace.steps,
|
|
165
|
+
trace.toolCalls,
|
|
166
|
+
trace.reflections ?? null,
|
|
167
|
+
trace.metrics,
|
|
168
|
+
trace.score,
|
|
169
|
+
trace.model,
|
|
170
|
+
trace.duration,
|
|
171
|
+
trace.usage,
|
|
172
|
+
trace.labels ?? [],
|
|
173
|
+
trace.isDemo,
|
|
174
|
+
trace.expected ?? null,
|
|
175
|
+
trace.createdAt,
|
|
176
|
+
]);
|
|
177
|
+
}
|
|
178
|
+
async storeTraceMany(traces) {
|
|
179
|
+
for (const trace of traces) {
|
|
180
|
+
await this.storeTrace(trace);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async getTrace(id) {
|
|
184
|
+
if (!this.pool)
|
|
185
|
+
throw new Error('Not connected');
|
|
186
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.traces WHERE id = $1`, [id]);
|
|
187
|
+
if (result.rows.length === 0)
|
|
188
|
+
return null;
|
|
189
|
+
return this.rowToTrace(result.rows[0]);
|
|
190
|
+
}
|
|
191
|
+
async getTraceByRunId(runId) {
|
|
192
|
+
if (!this.pool)
|
|
193
|
+
throw new Error('Not connected');
|
|
194
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.traces WHERE run_id = $1`, [runId]);
|
|
195
|
+
if (result.rows.length === 0)
|
|
196
|
+
return null;
|
|
197
|
+
return this.rowToTrace(result.rows[0]);
|
|
198
|
+
}
|
|
199
|
+
async queryTraces(query) {
|
|
200
|
+
if (!this.pool)
|
|
201
|
+
throw new Error('Not connected');
|
|
202
|
+
let sql = `SELECT * FROM ${this.schema}.traces WHERE 1=1`;
|
|
203
|
+
const params = [];
|
|
204
|
+
let paramIndex = 1;
|
|
205
|
+
if (query.agentId) {
|
|
206
|
+
sql += ` AND agent_id = $${paramIndex++}`;
|
|
207
|
+
params.push(query.agentId);
|
|
208
|
+
}
|
|
209
|
+
if (query.minScore !== undefined) {
|
|
210
|
+
sql += ` AND score >= $${paramIndex++}`;
|
|
211
|
+
params.push(query.minScore);
|
|
212
|
+
}
|
|
213
|
+
if (query.isDemo !== undefined) {
|
|
214
|
+
sql += ` AND is_demo = $${paramIndex++}`;
|
|
215
|
+
params.push(query.isDemo);
|
|
216
|
+
}
|
|
217
|
+
if (query.labels && query.labels.length > 0) {
|
|
218
|
+
sql += ` AND labels && $${paramIndex++}`;
|
|
219
|
+
params.push(query.labels);
|
|
220
|
+
}
|
|
221
|
+
if (query.fromDate) {
|
|
222
|
+
sql += ` AND created_at >= $${paramIndex++}`;
|
|
223
|
+
params.push(query.fromDate);
|
|
224
|
+
}
|
|
225
|
+
if (query.toDate) {
|
|
226
|
+
sql += ` AND created_at <= $${paramIndex++}`;
|
|
227
|
+
params.push(query.toDate);
|
|
228
|
+
}
|
|
229
|
+
sql += ' ORDER BY created_at DESC';
|
|
230
|
+
if (query.limit) {
|
|
231
|
+
sql += ` LIMIT $${paramIndex++}`;
|
|
232
|
+
params.push(query.limit);
|
|
233
|
+
}
|
|
234
|
+
const result = await this.pool.query(sql, params);
|
|
235
|
+
return result.rows.map((row) => this.rowToTrace(row));
|
|
236
|
+
}
|
|
237
|
+
async getAllTraces(agentId) {
|
|
238
|
+
if (!this.pool)
|
|
239
|
+
throw new Error('Not connected');
|
|
240
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.traces WHERE agent_id = $1 ORDER BY created_at DESC`, [agentId]);
|
|
241
|
+
return result.rows.map((row) => this.rowToTrace(row));
|
|
242
|
+
}
|
|
243
|
+
async getDemos(agentId, limit = 10) {
|
|
244
|
+
if (!this.pool)
|
|
245
|
+
throw new Error('Not connected');
|
|
246
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.traces WHERE agent_id = $1 AND is_demo = TRUE ORDER BY score DESC LIMIT $2`, [agentId, limit]);
|
|
247
|
+
return result.rows.map((row) => this.rowToTrace(row));
|
|
248
|
+
}
|
|
249
|
+
async markAsDemo(id) {
|
|
250
|
+
if (!this.pool)
|
|
251
|
+
throw new Error('Not connected');
|
|
252
|
+
await this.pool.query(`UPDATE ${this.schema}.traces SET is_demo = TRUE WHERE id = $1`, [id]);
|
|
253
|
+
}
|
|
254
|
+
async unmarkAsDemo(id) {
|
|
255
|
+
if (!this.pool)
|
|
256
|
+
throw new Error('Not connected');
|
|
257
|
+
await this.pool.query(`UPDATE ${this.schema}.traces SET is_demo = FALSE WHERE id = $1`, [id]);
|
|
258
|
+
}
|
|
259
|
+
async deleteTrace(id) {
|
|
260
|
+
if (!this.pool)
|
|
261
|
+
throw new Error('Not connected');
|
|
262
|
+
const result = await this.pool.query(`DELETE FROM ${this.schema}.traces WHERE id = $1`, [id]);
|
|
263
|
+
return result.rowCount > 0;
|
|
264
|
+
}
|
|
265
|
+
async pruneTraces(agentId, maxTraces) {
|
|
266
|
+
if (!this.pool)
|
|
267
|
+
throw new Error('Not connected');
|
|
268
|
+
const result = await this.pool.query(`DELETE FROM ${this.schema}.traces
|
|
269
|
+
WHERE id IN (
|
|
270
|
+
SELECT id FROM ${this.schema}.traces
|
|
271
|
+
WHERE agent_id = $1 AND is_demo = FALSE
|
|
272
|
+
ORDER BY created_at ASC
|
|
273
|
+
OFFSET $2
|
|
274
|
+
)`, [agentId, maxTraces]);
|
|
275
|
+
return result.rowCount;
|
|
276
|
+
}
|
|
277
|
+
async clearTraces(agentId) {
|
|
278
|
+
if (!this.pool)
|
|
279
|
+
throw new Error('Not connected');
|
|
280
|
+
await this.pool.query(`DELETE FROM ${this.schema}.traces WHERE agent_id = $1`, [agentId]);
|
|
281
|
+
}
|
|
282
|
+
async getTraceStats(agentId) {
|
|
283
|
+
if (!this.pool)
|
|
284
|
+
throw new Error('Not connected');
|
|
285
|
+
const countResult = await this.pool.query(`SELECT COUNT(*) as total, COUNT(*) FILTER (WHERE is_demo) as demos, AVG(score) as avg_score
|
|
286
|
+
FROM ${this.schema}.traces WHERE agent_id = $1`, [agentId]);
|
|
287
|
+
const row = countResult.rows[0];
|
|
288
|
+
return {
|
|
289
|
+
totalTraces: parseInt(row.total, 10),
|
|
290
|
+
demoCount: parseInt(row.demos, 10),
|
|
291
|
+
averageScore: parseFloat(row.avg_score) || 0,
|
|
292
|
+
scoreDistribution: [],
|
|
293
|
+
topPerformers: [],
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
rowToTrace(row) {
|
|
297
|
+
return {
|
|
298
|
+
id: row.id,
|
|
299
|
+
runId: row.run_id,
|
|
300
|
+
agentId: row.agent_id,
|
|
301
|
+
threadId: row.thread_id,
|
|
302
|
+
input: row.input,
|
|
303
|
+
output: row.output,
|
|
304
|
+
context: row.context,
|
|
305
|
+
steps: row.steps,
|
|
306
|
+
toolCalls: row.tool_calls,
|
|
307
|
+
reflections: row.reflections,
|
|
308
|
+
metrics: row.metrics,
|
|
309
|
+
score: row.score,
|
|
310
|
+
model: row.model,
|
|
311
|
+
duration: row.duration,
|
|
312
|
+
usage: row.usage,
|
|
313
|
+
labels: row.labels,
|
|
314
|
+
isDemo: row.is_demo,
|
|
315
|
+
expected: row.expected,
|
|
316
|
+
createdAt: new Date(row.created_at),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
async capture(prompt) {
|
|
320
|
+
if (!this.pool)
|
|
321
|
+
throw new Error('Not connected');
|
|
322
|
+
await this.pool.query(`INSERT INTO ${this.schema}.prompts
|
|
323
|
+
(id, run_id, agent_id, thread_id, model, provider, system_prompt, messages, tools, injected_demos, injected_insights, temperature, top_p, max_tokens, prompt_tokens, response_content, response_tool_calls, completion_tokens, finish_reason, latency_ms, metadata, created_at)
|
|
324
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`, [
|
|
325
|
+
prompt.id,
|
|
326
|
+
prompt.runId,
|
|
327
|
+
prompt.agentId,
|
|
328
|
+
prompt.threadId,
|
|
329
|
+
prompt.model,
|
|
330
|
+
prompt.provider,
|
|
331
|
+
prompt.systemPrompt,
|
|
332
|
+
prompt.messages,
|
|
333
|
+
prompt.tools ?? null,
|
|
334
|
+
prompt.injectedDemos ?? null,
|
|
335
|
+
prompt.injectedInsights ?? null,
|
|
336
|
+
prompt.temperature ?? null,
|
|
337
|
+
prompt.topP ?? null,
|
|
338
|
+
prompt.maxTokens ?? null,
|
|
339
|
+
prompt.promptTokens,
|
|
340
|
+
prompt.response?.content ?? null,
|
|
341
|
+
prompt.response?.toolCalls ?? null,
|
|
342
|
+
prompt.response?.completionTokens ?? null,
|
|
343
|
+
prompt.response?.finishReason ?? null,
|
|
344
|
+
prompt.response?.latencyMs ?? null,
|
|
345
|
+
prompt.metadata ?? null,
|
|
346
|
+
prompt.timestamp,
|
|
347
|
+
]);
|
|
348
|
+
}
|
|
349
|
+
async getPrompt(id) {
|
|
350
|
+
if (!this.pool)
|
|
351
|
+
throw new Error('Not connected');
|
|
352
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.prompts WHERE id = $1`, [id]);
|
|
353
|
+
if (result.rows.length === 0)
|
|
354
|
+
return null;
|
|
355
|
+
return this.rowToPrompt(result.rows[0]);
|
|
356
|
+
}
|
|
357
|
+
async getByRun(runId) {
|
|
358
|
+
if (!this.pool)
|
|
359
|
+
throw new Error('Not connected');
|
|
360
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.prompts WHERE run_id = $1 ORDER BY created_at ASC`, [runId]);
|
|
361
|
+
return result.rows.map((row) => this.rowToPrompt(row));
|
|
362
|
+
}
|
|
363
|
+
async query(query) {
|
|
364
|
+
if (!this.pool)
|
|
365
|
+
throw new Error('Not connected');
|
|
366
|
+
let sql = `SELECT * FROM ${this.schema}.prompts WHERE 1=1`;
|
|
367
|
+
const params = [];
|
|
368
|
+
let paramIndex = 1;
|
|
369
|
+
if (query.agentId) {
|
|
370
|
+
sql += ` AND agent_id = $${paramIndex++}`;
|
|
371
|
+
params.push(query.agentId);
|
|
372
|
+
}
|
|
373
|
+
if (query.model) {
|
|
374
|
+
sql += ` AND model = $${paramIndex++}`;
|
|
375
|
+
params.push(query.model);
|
|
376
|
+
}
|
|
377
|
+
if (query.fromDate) {
|
|
378
|
+
sql += ` AND created_at >= $${paramIndex++}`;
|
|
379
|
+
params.push(query.fromDate);
|
|
380
|
+
}
|
|
381
|
+
if (query.toDate) {
|
|
382
|
+
sql += ` AND created_at <= $${paramIndex++}`;
|
|
383
|
+
params.push(query.toDate);
|
|
384
|
+
}
|
|
385
|
+
if (query.minLatency !== undefined) {
|
|
386
|
+
sql += ` AND latency_ms >= $${paramIndex++}`;
|
|
387
|
+
params.push(query.minLatency);
|
|
388
|
+
}
|
|
389
|
+
if (query.maxLatency !== undefined) {
|
|
390
|
+
sql += ` AND latency_ms <= $${paramIndex++}`;
|
|
391
|
+
params.push(query.maxLatency);
|
|
392
|
+
}
|
|
393
|
+
sql += ' ORDER BY created_at DESC';
|
|
394
|
+
if (query.limit) {
|
|
395
|
+
sql += ` LIMIT $${paramIndex++}`;
|
|
396
|
+
params.push(query.limit);
|
|
397
|
+
}
|
|
398
|
+
if (query.offset) {
|
|
399
|
+
sql += ` OFFSET $${paramIndex++}`;
|
|
400
|
+
params.push(query.offset);
|
|
401
|
+
}
|
|
402
|
+
const result = await this.pool.query(sql, params);
|
|
403
|
+
return result.rows.map((row) => this.rowToPrompt(row));
|
|
404
|
+
}
|
|
405
|
+
async deletePrompt(id) {
|
|
406
|
+
if (!this.pool)
|
|
407
|
+
throw new Error('Not connected');
|
|
408
|
+
const result = await this.pool.query(`DELETE FROM ${this.schema}.prompts WHERE id = $1`, [id]);
|
|
409
|
+
return result.rowCount > 0;
|
|
410
|
+
}
|
|
411
|
+
async prune(beforeDate) {
|
|
412
|
+
if (!this.pool)
|
|
413
|
+
throw new Error('Not connected');
|
|
414
|
+
const result = await this.pool.query(`DELETE FROM ${this.schema}.prompts WHERE created_at < $1`, [beforeDate]);
|
|
415
|
+
return result.rowCount;
|
|
416
|
+
}
|
|
417
|
+
rowToPrompt(row) {
|
|
418
|
+
const response = row.response_content
|
|
419
|
+
? {
|
|
420
|
+
content: row.response_content,
|
|
421
|
+
toolCalls: row.response_tool_calls,
|
|
422
|
+
completionTokens: row.completion_tokens,
|
|
423
|
+
finishReason: row.finish_reason,
|
|
424
|
+
latencyMs: row.latency_ms,
|
|
425
|
+
}
|
|
426
|
+
: undefined;
|
|
427
|
+
return {
|
|
428
|
+
id: row.id,
|
|
429
|
+
runId: row.run_id,
|
|
430
|
+
agentId: row.agent_id,
|
|
431
|
+
threadId: row.thread_id,
|
|
432
|
+
model: row.model,
|
|
433
|
+
provider: row.provider,
|
|
434
|
+
timestamp: new Date(row.created_at),
|
|
435
|
+
systemPrompt: row.system_prompt,
|
|
436
|
+
messages: row.messages,
|
|
437
|
+
tools: row.tools,
|
|
438
|
+
injectedDemos: row.injected_demos,
|
|
439
|
+
injectedInsights: row.injected_insights,
|
|
440
|
+
temperature: row.temperature,
|
|
441
|
+
topP: row.top_p,
|
|
442
|
+
maxTokens: row.max_tokens,
|
|
443
|
+
promptTokens: row.prompt_tokens,
|
|
444
|
+
response: response,
|
|
445
|
+
metadata: row.metadata,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
async create(test) {
|
|
449
|
+
if (!this.pool)
|
|
450
|
+
throw new Error('Not connected');
|
|
451
|
+
const id = this.generateId('abtest');
|
|
452
|
+
const now = new Date();
|
|
453
|
+
await this.pool.query(`INSERT INTO ${this.schema}.ab_tests
|
|
454
|
+
(id, agent_id, name, description, status, control_instructions, treatment_instructions, treatment_allocation, min_sample_size, max_duration, confidence_level, metric_to_optimize, control_results, treatment_results, created_at, started_at, completed_at)
|
|
455
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)`, [
|
|
456
|
+
id,
|
|
457
|
+
test.agentId,
|
|
458
|
+
test.name,
|
|
459
|
+
test.description ?? null,
|
|
460
|
+
test.status,
|
|
461
|
+
test.controlInstructions,
|
|
462
|
+
test.treatmentInstructions,
|
|
463
|
+
test.treatmentAllocation,
|
|
464
|
+
test.minSampleSize,
|
|
465
|
+
test.maxDuration,
|
|
466
|
+
test.confidenceLevel,
|
|
467
|
+
test.metricToOptimize,
|
|
468
|
+
test.controlResults,
|
|
469
|
+
test.treatmentResults,
|
|
470
|
+
now,
|
|
471
|
+
test.startedAt ?? null,
|
|
472
|
+
test.completedAt ?? null,
|
|
473
|
+
]);
|
|
474
|
+
return { ...test, id, createdAt: now };
|
|
475
|
+
}
|
|
476
|
+
async getABTest(id) {
|
|
477
|
+
if (!this.pool)
|
|
478
|
+
throw new Error('Not connected');
|
|
479
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.ab_tests WHERE id = $1`, [id]);
|
|
480
|
+
if (result.rows.length === 0)
|
|
481
|
+
return null;
|
|
482
|
+
return this.rowToABTest(result.rows[0]);
|
|
483
|
+
}
|
|
484
|
+
async getActive(agentId) {
|
|
485
|
+
if (!this.pool)
|
|
486
|
+
throw new Error('Not connected');
|
|
487
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.ab_tests WHERE agent_id = $1 AND status = 'running' LIMIT 1`, [agentId]);
|
|
488
|
+
if (result.rows.length === 0)
|
|
489
|
+
return null;
|
|
490
|
+
return this.rowToABTest(result.rows[0]);
|
|
491
|
+
}
|
|
492
|
+
async update(id, updates) {
|
|
493
|
+
if (!this.pool)
|
|
494
|
+
throw new Error('Not connected');
|
|
495
|
+
const setClauses = [];
|
|
496
|
+
const params = [];
|
|
497
|
+
let paramIndex = 1;
|
|
498
|
+
if (updates.status !== undefined) {
|
|
499
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
500
|
+
params.push(updates.status);
|
|
501
|
+
}
|
|
502
|
+
if (updates.startedAt !== undefined) {
|
|
503
|
+
setClauses.push(`started_at = $${paramIndex++}`);
|
|
504
|
+
params.push(updates.startedAt);
|
|
505
|
+
}
|
|
506
|
+
if (updates.completedAt !== undefined) {
|
|
507
|
+
setClauses.push(`completed_at = $${paramIndex++}`);
|
|
508
|
+
params.push(updates.completedAt);
|
|
509
|
+
}
|
|
510
|
+
if (updates.controlResults !== undefined) {
|
|
511
|
+
setClauses.push(`control_results = $${paramIndex++}`);
|
|
512
|
+
params.push(updates.controlResults);
|
|
513
|
+
}
|
|
514
|
+
if (updates.treatmentResults !== undefined) {
|
|
515
|
+
setClauses.push(`treatment_results = $${paramIndex++}`);
|
|
516
|
+
params.push(updates.treatmentResults);
|
|
517
|
+
}
|
|
518
|
+
params.push(id);
|
|
519
|
+
const result = await this.pool.query(`UPDATE ${this.schema}.ab_tests SET ${setClauses.join(', ')} WHERE id = $${paramIndex} RETURNING *`, params);
|
|
520
|
+
return this.rowToABTest(result.rows[0]);
|
|
521
|
+
}
|
|
522
|
+
async recordResult(testId, variant, score, latency, cost) {
|
|
523
|
+
if (!this.pool)
|
|
524
|
+
throw new Error('Not connected');
|
|
525
|
+
const test = await this.getABTest(testId);
|
|
526
|
+
if (!test)
|
|
527
|
+
return;
|
|
528
|
+
const results = variant === 'control' ? test.controlResults : test.treatmentResults;
|
|
529
|
+
const newResults = {
|
|
530
|
+
sampleSize: results.sampleSize + 1,
|
|
531
|
+
successRate: (results.successRate * results.sampleSize + (score >= 0.5 ? 1 : 0)) / (results.sampleSize + 1),
|
|
532
|
+
avgScore: (results.avgScore * results.sampleSize + score) / (results.sampleSize + 1),
|
|
533
|
+
avgLatency: (results.avgLatency * results.sampleSize + latency) / (results.sampleSize + 1),
|
|
534
|
+
totalCost: results.totalCost + cost,
|
|
535
|
+
scores: [...results.scores, score],
|
|
536
|
+
};
|
|
537
|
+
const column = variant === 'control' ? 'control_results' : 'treatment_results';
|
|
538
|
+
await this.pool.query(`UPDATE ${this.schema}.ab_tests SET ${column} = $1 WHERE id = $2`, [newResults, testId]);
|
|
539
|
+
}
|
|
540
|
+
async list(agentId, status) {
|
|
541
|
+
if (!this.pool)
|
|
542
|
+
throw new Error('Not connected');
|
|
543
|
+
let sql = `SELECT * FROM ${this.schema}.ab_tests WHERE 1=1`;
|
|
544
|
+
const params = [];
|
|
545
|
+
let paramIndex = 1;
|
|
546
|
+
if (agentId) {
|
|
547
|
+
sql += ` AND agent_id = $${paramIndex++}`;
|
|
548
|
+
params.push(agentId);
|
|
549
|
+
}
|
|
550
|
+
if (status) {
|
|
551
|
+
sql += ` AND status = $${paramIndex++}`;
|
|
552
|
+
params.push(status);
|
|
553
|
+
}
|
|
554
|
+
sql += ' ORDER BY created_at DESC';
|
|
555
|
+
const result = await this.pool.query(sql, params);
|
|
556
|
+
return result.rows.map((row) => this.rowToABTest(row));
|
|
557
|
+
}
|
|
558
|
+
async deleteABTest(id) {
|
|
559
|
+
if (!this.pool)
|
|
560
|
+
throw new Error('Not connected');
|
|
561
|
+
const result = await this.pool.query(`DELETE FROM ${this.schema}.ab_tests WHERE id = $1`, [id]);
|
|
562
|
+
return result.rowCount > 0;
|
|
563
|
+
}
|
|
564
|
+
rowToABTest(row) {
|
|
565
|
+
return {
|
|
566
|
+
id: row.id,
|
|
567
|
+
agentId: row.agent_id,
|
|
568
|
+
name: row.name,
|
|
569
|
+
description: row.description,
|
|
570
|
+
status: row.status,
|
|
571
|
+
controlInstructions: row.control_instructions,
|
|
572
|
+
treatmentInstructions: row.treatment_instructions,
|
|
573
|
+
treatmentAllocation: row.treatment_allocation,
|
|
574
|
+
minSampleSize: row.min_sample_size,
|
|
575
|
+
maxDuration: parseInt(row.max_duration, 10),
|
|
576
|
+
confidenceLevel: row.confidence_level,
|
|
577
|
+
metricToOptimize: row.metric_to_optimize,
|
|
578
|
+
controlResults: row.control_results,
|
|
579
|
+
treatmentResults: row.treatment_results,
|
|
580
|
+
createdAt: new Date(row.created_at),
|
|
581
|
+
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
582
|
+
completedAt: row.completed_at ? new Date(row.completed_at) : undefined,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
async save(version) {
|
|
586
|
+
if (!this.pool)
|
|
587
|
+
throw new Error('Not connected');
|
|
588
|
+
const id = this.generateId('ver');
|
|
589
|
+
await this.pool.query(`INSERT INTO ${this.schema}.instruction_versions
|
|
590
|
+
(id, agent_id, version, instructions, source, source_id, deployed_at, retired_at, run_count, avg_score, success_rate, avg_latency, total_cost, parent_version_id)
|
|
591
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, [
|
|
592
|
+
id,
|
|
593
|
+
version.agentId,
|
|
594
|
+
version.version,
|
|
595
|
+
version.instructions,
|
|
596
|
+
version.source,
|
|
597
|
+
version.sourceId ?? null,
|
|
598
|
+
version.deployedAt,
|
|
599
|
+
version.retiredAt ?? null,
|
|
600
|
+
version.metrics.runCount,
|
|
601
|
+
version.metrics.avgScore,
|
|
602
|
+
version.metrics.successRate,
|
|
603
|
+
version.metrics.avgLatency,
|
|
604
|
+
version.metrics.totalCost,
|
|
605
|
+
version.parentVersionId ?? null,
|
|
606
|
+
]);
|
|
607
|
+
return { ...version, id };
|
|
608
|
+
}
|
|
609
|
+
async getVersion(id) {
|
|
610
|
+
if (!this.pool)
|
|
611
|
+
throw new Error('Not connected');
|
|
612
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.instruction_versions WHERE id = $1`, [id]);
|
|
613
|
+
if (result.rows.length === 0)
|
|
614
|
+
return null;
|
|
615
|
+
return this.rowToVersion(result.rows[0]);
|
|
616
|
+
}
|
|
617
|
+
async getCurrent(agentId) {
|
|
618
|
+
if (!this.pool)
|
|
619
|
+
throw new Error('Not connected');
|
|
620
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.instruction_versions
|
|
621
|
+
WHERE agent_id = $1 AND retired_at IS NULL
|
|
622
|
+
ORDER BY version DESC LIMIT 1`, [agentId]);
|
|
623
|
+
if (result.rows.length === 0)
|
|
624
|
+
return null;
|
|
625
|
+
return this.rowToVersion(result.rows[0]);
|
|
626
|
+
}
|
|
627
|
+
async getHistory(agentId, limit = 10) {
|
|
628
|
+
if (!this.pool)
|
|
629
|
+
throw new Error('Not connected');
|
|
630
|
+
const result = await this.pool.query(`SELECT * FROM ${this.schema}.instruction_versions
|
|
631
|
+
WHERE agent_id = $1
|
|
632
|
+
ORDER BY version DESC LIMIT $2`, [agentId, limit]);
|
|
633
|
+
return result.rows.map((row) => this.rowToVersion(row));
|
|
634
|
+
}
|
|
635
|
+
async retire(id) {
|
|
636
|
+
if (!this.pool)
|
|
637
|
+
throw new Error('Not connected');
|
|
638
|
+
await this.pool.query(`UPDATE ${this.schema}.instruction_versions SET retired_at = NOW() WHERE id = $1`, [id]);
|
|
639
|
+
}
|
|
640
|
+
async updateMetrics(id, metrics) {
|
|
641
|
+
if (!this.pool)
|
|
642
|
+
throw new Error('Not connected');
|
|
643
|
+
const setClauses = [];
|
|
644
|
+
const params = [];
|
|
645
|
+
let paramIndex = 1;
|
|
646
|
+
if (metrics.runCount !== undefined) {
|
|
647
|
+
setClauses.push(`run_count = $${paramIndex++}`);
|
|
648
|
+
params.push(metrics.runCount);
|
|
649
|
+
}
|
|
650
|
+
if (metrics.avgScore !== undefined) {
|
|
651
|
+
setClauses.push(`avg_score = $${paramIndex++}`);
|
|
652
|
+
params.push(metrics.avgScore);
|
|
653
|
+
}
|
|
654
|
+
if (metrics.successRate !== undefined) {
|
|
655
|
+
setClauses.push(`success_rate = $${paramIndex++}`);
|
|
656
|
+
params.push(metrics.successRate);
|
|
657
|
+
}
|
|
658
|
+
if (metrics.avgLatency !== undefined) {
|
|
659
|
+
setClauses.push(`avg_latency = $${paramIndex++}`);
|
|
660
|
+
params.push(metrics.avgLatency);
|
|
661
|
+
}
|
|
662
|
+
if (metrics.totalCost !== undefined) {
|
|
663
|
+
setClauses.push(`total_cost = $${paramIndex++}`);
|
|
664
|
+
params.push(metrics.totalCost);
|
|
665
|
+
}
|
|
666
|
+
if (setClauses.length === 0)
|
|
667
|
+
return;
|
|
668
|
+
params.push(id);
|
|
669
|
+
await this.pool.query(`UPDATE ${this.schema}.instruction_versions SET ${setClauses.join(', ')} WHERE id = $${paramIndex}`, params);
|
|
670
|
+
}
|
|
671
|
+
rowToVersion(row) {
|
|
672
|
+
return {
|
|
673
|
+
id: row.id,
|
|
674
|
+
agentId: row.agent_id,
|
|
675
|
+
version: row.version,
|
|
676
|
+
instructions: row.instructions,
|
|
677
|
+
source: row.source,
|
|
678
|
+
sourceId: row.source_id,
|
|
679
|
+
deployedAt: new Date(row.deployed_at),
|
|
680
|
+
retiredAt: row.retired_at ? new Date(row.retired_at) : undefined,
|
|
681
|
+
metrics: {
|
|
682
|
+
runCount: row.run_count,
|
|
683
|
+
avgScore: row.avg_score,
|
|
684
|
+
successRate: row.success_rate,
|
|
685
|
+
avgLatency: row.avg_latency,
|
|
686
|
+
totalCost: row.total_cost,
|
|
687
|
+
},
|
|
688
|
+
parentVersionId: row.parent_version_id,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
//# sourceMappingURL=postgres-trace-store.js.map
|