# Infrastruktur: Claude som chat-deltaker ## Oversikt Claude deltar i samtaler som en agent-node i grafen. Når en bruker sender en melding i en kommunikasjonsnode der Claude er deltaker, trigger maskinrommet en `agent_respond`-jobb som delegerer til `synops-respond` CLI-verktøyet. ## Arkitektur ``` Bruker sender melding (via frontend) → create_node() i maskinrommet → sjekker: har kommunikasjonsnoden en agent-deltaker? → ja: enqueue agent_respond-jobb (prioritet 8) → jobbkø-worker plukker opp (poll hvert 2s) → maskinrommet: kill switch, rate limit, loop-prevensjon → spawner: synops-respond --communication-id ... --write → henter meldingshistorikk + kontekst fra PG → bygger prompt → kaller: claude -p "" --output-format json → oppretter svar-node i PG, logger ai_usage + resource_usage → returnerer JSON med reply_node_id + response_text → PG NOTIFY propagerer til frontend via WebSocket → frontend viser melding i sanntid ``` Ansvarsdeling (unix-filosofi): - **Maskinrommet:** Auth, kill switch, rate limiting, loop-prevensjon, env-videresending - **synops-respond:** Kontekst-henting, URL-deteksjon, synops-clip-kall, prompt-bygging, claude-kall, PG-skriving - **synops-clip:** Artikkelhenting, parsing, paywall-deteksjon, AI-oppsummering, node-opprettelse Latens: ~3-5 sekunder uten URL, ~10-20 sekunder med URL (synops-clip + LLM-oppsummering). ### URL-klipping i chat (oppgave 25.3) Når en bruker limer inn en URL i chatten, gjenkjenner `synops-respond` URL-en og kaller `synops-clip --write` automatisk før Claude svarer: ``` Bruker: "Sjekk denne: https://nrk.no/artikkel" → synops-respond detekterer URL med regex → spawner: synops-clip --url ... --write --created-by → synops-clip henter, parser, oppsummerer, oppretter node → resultat (tittel, oppsummering, paywall) inkluderes i prompt → Claude svarer med oppsummering basert på klipp-kontekst ``` Ved betalingsmur: Claude informerer om at artikkelen er bak betalingsmur, presenterer det som er tilgjengelig (tittel/ingress), og ber brukeren lime inn innholdet om de vil dele resten. Begrensninger: Maks 3 URL-er per melding. 60 sekunders timeout per klipp. ## Noder og tabeller ### Claude-noden - **UUID:** `d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44` - **node_kind:** `agent` - **visibility:** `discoverable` ### agent_identities Kobler agent-noder til konfigurasjon og nøkkel. | Felt | Verdi | |------|-------| | agent_key | `claude-main` | | agent_type | `claude` | | config | max_context_messages, rate_limit_per_hour, etc. | ### agent_permissions Autorisasjonsnivåer per bruker/agent-par. | Nivå | Betydning | |------|-----------| | `direct` | Kan bestille endringer som implementeres direkte | | `propose` | Kan foreslå endringer som krever godkjenning | ### ai_usage_log Logger hvert agent-svar med timestamps, job_id, og kommunikasjons-ID. ## Sikkerhet | Mekanisme | Beskrivelse | |-----------|-------------| | **Kill switch** | `agent_identities.is_active = false` stopper all aktivitet | | **Rate limiting** | Maks 60 responser per time (konfigurerbart) | | **Loop-prevensjon** | Stopper hvis siste 3 meldinger er fra agenten | | **Egne meldinger** | Svarer aldri på egne meldinger (sjekk i trigger) | ## Oppsett av ny chat med Claude ```sql -- 1. Opprett kommunikasjonsnode INSERT INTO nodes (id, node_kind, title, visibility, metadata, created_by) VALUES ('', 'communication', 'Min chat med Claude', 'hidden', '{}', ''); -- 2. Legg til bruker som owner INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by) VALUES ('', '', '', 'owner', '{}', false, ''); -- 3. Legg til Claude som member_of INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by) VALUES ('', 'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44', '', 'member_of', '{}', false, ''); -- 4. Recompute access SELECT recompute_access('', '', 'owner', ''); SELECT recompute_access('d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44', '', 'member', ''); ``` Etter dette vil alle meldinger i chatten automatisk trigge Claude-svar. ## Drift Maskinrommet kjører som systemd-tjeneste direkte på hosten: ```bash sudo systemctl status maskinrommet # status sudo systemctl restart maskinrommet # restart etter ny build sudo journalctl -u maskinrommet -f # live-logger ``` Bygg og deploy: ```bash cd ~/synops/maskinrommet && cargo build --release sudo systemctl restart maskinrommet ``` ## Faser - **Fase A (MVP):** Chat-agent — implementert og verifisert - **Fase B:** Autorisasjon og oppgaver (direct vs propose flyt) - **Fase C:** Autonom implementering (claude Code som subprocess for kode-endringer) - **Fase D:** @mentions, typing-indikator, admin-panel