feat: agent variants — migration, API, service integration, frontend, tests

- Migration 027: agent_variants table with single-active enforcement,
  variant_id column on agent_performance_log
- API: full CRUD, clone from agent/variant, activate/deactivate,
  per-variant performance metrics and history endpoints
- Services: extractor, event classifier, thesis rewriter all wired
  to AgentConfigResolver with variant override support
- Frontend: variant list, comparison view, create/edit/clone forms,
  activate/delete actions on Agents page
- Tests: API tests + 5 property-based tests (single-active invariant,
  clone preservation, config resolution, slug determinism, update idempotence)
- Spec files for agent-variants feature
This commit is contained in:
Celes Renata
2026-04-17 05:15:42 +00:00
parent 734bf001a7
commit 7c23c044d7
14 changed files with 3118 additions and 120 deletions
+47
View File
@@ -0,0 +1,47 @@
-- Agent variant configurations: alternative model/prompt/parameter sets per agent.
-- Each agent can have multiple variants for A/B testing, model comparison,
-- and iterative prompt engineering. At most one variant per agent is active.
CREATE TABLE IF NOT EXISTS agent_variants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id UUID NOT NULL REFERENCES ai_agents(id) ON DELETE CASCADE,
variant_name VARCHAR(200) NOT NULL,
variant_slug VARCHAR(200) NOT NULL,
description TEXT NOT NULL DEFAULT '',
model_provider VARCHAR(50) NOT NULL DEFAULT 'ollama',
model_name VARCHAR(200) NOT NULL,
system_prompt TEXT NOT NULL DEFAULT '',
user_prompt_template TEXT NOT NULL DEFAULT '',
prompt_version VARCHAR(100) NOT NULL DEFAULT '',
temperature FLOAT DEFAULT 0.0,
max_tokens INTEGER DEFAULT 32768,
context_window INTEGER DEFAULT 0, -- Ollama num_ctx; 0 = use model default
input_token_limit INTEGER DEFAULT 0, -- max input tokens before truncation; 0 = no limit
token_budget INTEGER DEFAULT 0, -- total tokens per hour; 0 = unlimited
timeout_seconds INTEGER DEFAULT 120,
max_retries INTEGER DEFAULT 2,
is_active BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Each agent can have many variants, but variant slugs must be unique per agent.
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_variants_slug
ON agent_variants(agent_id, variant_slug);
-- At most one active variant per agent (database-enforced invariant).
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_variants_active
ON agent_variants(agent_id) WHERE is_active = TRUE;
-- Fast lookup by agent.
CREATE INDEX IF NOT EXISTS idx_agent_variants_agent
ON agent_variants(agent_id);
-- Add variant_id to performance log for per-variant attribution.
-- Nullable so existing rows are unaffected; ON DELETE SET NULL preserves
-- historical log entries when a variant is removed.
ALTER TABLE agent_performance_log
ADD COLUMN IF NOT EXISTS variant_id UUID REFERENCES agent_variants(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_agent_perf_variant
ON agent_performance_log(variant_id, recorded_at DESC);