synops/migrations/007_agent_system.sql
vegard 33a1b44946 Implementer Claude som chat-deltaker (Fase A: MVP)
Claude er nå en agent-node i grafen som kan delta i samtaler.
Når en bruker sender melding i en kommunikasjonsnode der Claude
er deltaker, enqueues en agent_respond-jobb som kaller claude CLI
direkte og skriver svaret tilbake til chatten.

Nye filer:
- migrations/007_agent_system.sql: agent_identities, agent_permissions, ai_usage_log
- maskinrommet/src/agent.rs: agent_respond job handler
- scripts/maskinrommet.service: systemd-tjeneste for native kjøring
- scripts/maskinrommet-env.sh: genererer env med Docker container-IPs

Endringer:
- intentions.rs: trigger agent_respond ved melding i agent-chat
- jobs.rs: dispatch agent_respond til agent-handler
- frontend chat: bot-badge (🤖) og amber-farge på agent-meldinger
- LiteLLM config: resonering-modellalias via OpenRouter

Maskinrommet kjører nå direkte på hosten (ikke i Docker) for å
ha tilgang til claude CLI. Caddy peker til host.docker.internal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:20:17 +00:00

107 lines
4.3 KiB
SQL

-- 007_agent_system.sql — Agentsystem for Claude som chat-deltaker.
--
-- Nye tabeller:
-- agent_identities — kobler agent-noder til config og nøkkel
-- agent_permissions — autorisasjonsnivåer (direct/propose)
-- ai_usage_log — tokenregnskap for AI-kall
--
-- Seed: Claude-agentnode med agent_identity + tillatelse for Vegard.
-- =============================================================================
-- 1. Agent-identiteter
-- =============================================================================
CREATE TABLE agent_identities (
node_id UUID PRIMARY KEY REFERENCES nodes(id) ON DELETE CASCADE,
agent_key TEXT UNIQUE NOT NULL, -- 'claude-main'
agent_type TEXT NOT NULL, -- 'claude'
is_active BOOLEAN NOT NULL DEFAULT true,
config JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
COMMENT ON TABLE agent_identities IS 'Agent-noder som kan delta i samtaler (Claude, fremtidige agenter)';
COMMENT ON COLUMN agent_identities.agent_key IS 'Unik nøkkel for oppslag (claude-main)';
COMMENT ON COLUMN agent_identities.config IS 'model_alias, system_prompt, max_context_messages, etc.';
-- =============================================================================
-- 2. Agent-tillatelser
-- =============================================================================
CREATE TABLE agent_permissions (
user_node_id UUID REFERENCES nodes(id) ON DELETE CASCADE,
agent_node_id UUID REFERENCES nodes(id) ON DELETE CASCADE,
permission TEXT NOT NULL CHECK (permission IN ('direct', 'propose')),
PRIMARY KEY (user_node_id, agent_node_id)
);
COMMENT ON TABLE agent_permissions IS 'Hvem kan be agenter om hva (direct = implementer, propose = foreslå)';
-- =============================================================================
-- 3. AI-brukslogg
-- =============================================================================
CREATE TABLE ai_usage_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
collection_node_id UUID REFERENCES nodes(id) ON DELETE SET NULL,
job_id UUID REFERENCES job_queue(id) ON DELETE SET NULL,
agent_node_id UUID REFERENCES nodes(id) ON DELETE SET NULL,
communication_id UUID REFERENCES nodes(id) ON DELETE SET NULL,
model_alias TEXT NOT NULL,
model_actual TEXT,
prompt_tokens INT NOT NULL DEFAULT 0,
completion_tokens INT NOT NULL DEFAULT 0,
total_tokens INT NOT NULL DEFAULT 0,
estimated_cost NUMERIC(10, 6),
job_type TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_ai_usage_created ON ai_usage_log (created_at);
CREATE INDEX idx_ai_usage_agent ON ai_usage_log (agent_node_id, created_at);
COMMENT ON TABLE ai_usage_log IS 'Tokenforbruk per AI-kall — kostnadskontroll og analyse';
-- =============================================================================
-- 4. Seed: Claude-agentnode
-- =============================================================================
-- Fast UUID for Claude (forutsigbar, enkel å referere til)
INSERT INTO nodes (id, node_kind, title, visibility, metadata, created_by)
VALUES (
'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44',
'agent',
'Claude',
'discoverable',
'{"agent_type": "claude", "capabilities": ["chat", "code"]}',
'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44' -- self-referencing
);
INSERT INTO agent_identities (node_id, agent_key, agent_type, is_active, config)
VALUES (
'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44',
'claude-main',
'claude',
true,
'{
"model_alias": "resonering",
"max_context_messages": 50,
"max_response_tokens": 2048,
"cooldown_seconds": 5,
"max_consecutive_agent_messages": 3,
"rate_limit_per_hour": 60
}'
);
-- Vegard har direct-tilgang (kan bestille endringer)
INSERT INTO agent_permissions (user_node_id, agent_node_id, permission)
VALUES (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', -- Vegard
'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44', -- Claude
'direct'
);
-- Gi synops_reader tilgang til nye tabeller
GRANT SELECT ON agent_identities TO synops_reader;
GRANT SELECT ON agent_permissions TO synops_reader;
GRANT SELECT ON ai_usage_log TO synops_reader;