diff --git a/.gemini/GEMINI.md b/.gemini/GEMINI.md index 89cba82..502dbeb 100644 --- a/.gemini/GEMINI.md +++ b/.gemini/GEMINI.md @@ -81,14 +81,14 @@ BUILD_ID=$(gcloud builds list --project=propane-will-491900-m5 --limit=1 --forma gcloud builds log $BUILD_ID --project=propane-will-491900-m5 2>&1 | tail -100 # 2. Les Cloud Run-logg -gcloud logging read \ - 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' \ - --project=propane-will-491900-m5 --limit=50 --order=desc \ +gcloud logging read + 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' + --project=propane-will-491900-m5 --limit=50 --order=desc --format="table(timestamp,textPayload,jsonPayload.message)" # 3. Sjekk service-state -gcloud run services describe osvauco-agent \ - --project=propane-will-491900-m5 --region=us-central1 \ +gcloud run services describe osvauco-agent + --project=propane-will-491900-m5 --region=us-central1 --format="value(status.conditions)" ``` @@ -206,16 +206,16 @@ TOKEN=$(gcloud auth print-identity-token) curl -si $SMOKE_URL/health -H "Authorization: Bearer $TOKEN" # Auth — IAP Load Balancer opax.vauco.no (MUST use metadata server + SA token) -TOKEN=$(curl -s -H "Metadata-Flavor: Google" \ +TOKEN=$(curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=357036551735-kq8nt7ld38hfqlcfb3n52ef7tala4meo.apps.googleusercontent.com&format=full") curl -si https://opax.vauco.no/health -H "Authorization: Bearer $TOKEN" # Forventet: HTTP/2 200 # Ny Cloud Run-tjeneste: gi invoker-rettighet med en gang -gcloud run services add-iam-policy-binding [SERVICE] \ - --region=us-central1 \ - --member="serviceAccount:357036551735@cloudbuild.gserviceaccount.com" \ - --role="roles/run.invoker" \ +gcloud run services add-iam-policy-binding [SERVICE] + --region=us-central1 + --member="serviceAccount:357036551735@cloudbuild.gserviceaccount.com" + --role="roles/run.invoker" --project=propane-will-491900-m5 ``` @@ -252,8 +252,8 @@ gcloud run services add-iam-policy-binding [SERVICE] \ ### Bootstrap ```bash -bash <(curl -s "http://chris:$(gcloud secrets versions access latest \ - --secret=gitea-api-token --project=propane-will-491900-m5 \ +bash <(curl -s "http://chris:$(gcloud secrets versions access latest + --secret=gitea-api-token --project=propane-will-491900-m5 )@34.59.131.162:3000/chris/OSVauco/raw/branch/main/emma/setup.sh") echo 'source ~/.emma_env' >> ~/.bashrc && source ~/.emma_env @@ -291,3 +291,100 @@ IKKE utfør noe — vent på PLAN APPROVED. HUSK: internett-søk er forbudt for diagnose. Bruk gcloud/cat/grep/git. Bekreft: Emma rapporterer til chris.christiansen@vauco.no. Gitea er primær Git. ``` + +--- + +## Cloud Run / Secret Manager + +**Koble secrets til Cloud Run (standard fremgangsmåte):** +Bruk alltid `--update-secrets` for å mounte Secret Manager-secrets som env-vars. +Format: `ENV_VAR_NAME=SECRET_NAME:latest` + +Eksempel (generisk — bytt ut navn): +``` +gcloud run services update + --region= + --update-secrets="VAR1=SECRET1:latest,VAR2=SECRET2:latest" +``` + +**Regler:** +1. Secrets lagres ALLTID i Secret Manager — aldri hardkodet i kode eller YAML +2. Service account må ha `roles/secretmanager.secretAccessor` på hvert secret +3. Bruk `--update-secrets` (ikke YAML-edit) for enkeltstående env-var-endringer +4. Bruk YAML-metoden KUN når du endrer flere ting samtidig (scaling, image, osv.) +5. Etter `--update-secrets` trengs IKKE ny `gcloud run deploy` — endringen er umiddelbar + +**Gi tilgang:** +``` +gcloud secrets add-iam-policy-binding + --member="serviceAccount:" + --role="roles/secretmanager.secretAccessor" +``` + +--- + +## Hva som er gjort — 2026-07-02 + +**Twilio SMS — operativ** +- Secrets i Secret Manager: TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER +- Koblet til osvauco-agent via --update-secrets +- Endepunkt: POST /notify/sms — felt: to, body, tier, sender_id (Optional, default="OSVauco") +- Tier-nivåer: guard, shield, enterprise +- Testet og bekreftet — SMS mottatt på +4794171703 kl 17:47 2026-07-02 +- Alphanumeric Sender ID skal aktiveres i Twilio Console (Settings → Sender IDs) + +**Auth-arkitektur avklart** +- requireiap middleware (linje 89) sjekker x-goog-authenticated-user-email ELLER Bearer token +- requireauth decorator sjekker session-cookie ELLER Bearer token (Cloud Run identity token) +- Token audience: https://osvauco-agent-zjbqp3prqq-uc.a.run.app (ikke IAP client ID) +- Token hentes fra: http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=&format=full + +--- + +## Kommunikasjonsagent — Arkitektur og visjon + +**Konsept:** Emma fungerer som et kommunikasjonslag mellom Chris og verden. +Alle kanaler (SMS, WhatsApp, telefon) går via agenten — ikke direkte. + +**Tre flytyper:** + +1. Innkommende melding (SMS/WhatsApp/andre) + - Agent mottar → vurderer hastegrad og avsender + - Lav prioritet → sammenfatter til neste pause + - Høy prioritet → leser opp på AirPods umiddelbart + - Chris svarer muntlig → agent oversetter og sender tilbake + +2. Chris er i aktiv telefonsamtale + - Agent holder andre kanaler stille + - Etter samtale: "Du har X meldinger, vil du høre dem?" + +3. Agent tar dialog selv + - Definerte regler for hvem Emma kan svare autonomt + - Eskalerer til Chris ved tvil + - Logger alt for gjennomgang + +**Sender ID-strategi:** +- Klient/billing-varsler: sender_id = "CostGuard" +- Plattform-meldinger: sender_id = "OSVauco" +- Privat/personlig: eget Twilio-nummer med tale-støtte + +**Teknisk status:** + +| Komponent | Status | +|---|---| +| Utgående SMS (/notify/sms) | ✅ Operativ | +| Twilio-konto | ✅ Operativ (trial — oppgrader for fjerne trial-tekst) | +| Emma-agent | ✅ Operativ | +| sender_id-felt i SmsNotifyRequest | ⬜ Implementer (Optional[str], default="OSVauco") | +| Alphanumeric Sender ID i Twilio Console | ⬜ Aktiver manuelt | +| Innkommende SMS-webhook → /notify/sms-inbound | ⬜ Neste steg | +| Twilio-nummer med tale+SMS | ⬜ Neste steg | +| WhatsApp-kanal (Twilio har dette) | ⬜ Fremtidig | +| Voice/samtale-integrasjon med Emma | ⬜ Fremtidig | +| AirPods-integrasjon (iOS Shortcuts / app) | ⬜ Fremtidig | + +**Neste konkrete steg:** +1. Legg til sender_id i SmsNotifyRequest (linje 437 i main.py) +2. Implementer POST /notify/sms-inbound (Twilio webhook for innkommende) +3. Koble inbound til Emma for auto-svar logikk +4. Kjøp Twilio-nummer med voice-støtte for personlig bruk diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index cd4d7b1..5e2b295 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -127,3 +127,57 @@ - CI1 `cloudbuild.mcp.yaml` ✅ - **Prinsipp fastslått:** Ingen tredjepartsverktøy. Alt eies i eget GCP/GitHub. - CI1-trigger gjenstår — manuelt steg i GCP Console av Chris + +--- + +## Fase D — Secrets & Sikkerhet (🟠 IN PROGRESS) + +> **Fokus:** Integrere eksterne tjenester (Twilio, etc.) sikkert via Secret Manager og IAM. + +| ID | Oppgave | Status | Prioritet | +|----|---------|--------|-----------| +| **TW-1** | Twilio Secrets (SID, Auth, Number) i Secret Manager | 🟠 in progress | Høy | +| **TW-2** | Koble Twilio Secrets til opax-mcp | 🔴 | Høy | +| **TW-3** | Test `send_sms` tool | 🔴 | Høy | +| **INFRA-1** | Automatic restart på `osvauco-dev-vm` | 🔴 | Medium | +| **INFRA-2** | Statisk IP på `osvauco-dev-vm` | 🔴 | Medium | +| **OLLAMA-1** | Sikre Ollama-endepunkt på `osvauco-dev-vm` | 🔴 | Medium | + + +--- + +## Fase E — AI-agent Telefoni (🟡 LATER) + +> **Fokus:** Aktivere toveis talestyrt kommunikasjon med Emma-agenten. + +**Kommunikasjonsagent (Emma som kommunikasjonslag)** +- Utgående SMS operativ ✅ +- Neste: innkommende SMS → Emma → auto-svar +- Fremtidig: WhatsApp, voice, AirPods-integrasjon + +### Uke 3-4: Inngående AI-telefonsvarer +| ID | Oppgave | Status | Notat | +|----|---------|--------|-------| +| **VOICE-1** | `/voice` webhook i opax-mcp | 🟡 | | +| **VOICE-2** | Konfigurer Twilio Voice URL | 🟡 | | +| **VOICE-3** | Bygg ConversationRelay WebSocket | 🟡 | | +| **VOICE-4** | Definer Emma telefon-persona | 🟡 | | + +### Uke 5-6: Utgående AI-anrop +| ID | Oppgave | Status | Notat | +|----|---------|--------|-------| +| **CALL-1** | Trigger-logikk for utgående anrop | 🟡 | | +| **CALL-2** | Implementer anrop via Twilio Outbound API | 🟡 | | +| **CALL-3** | Definer caser (kostnad, møte, etc) | 🟡 | | + +--- + +## Fase F — Multikanal-orkestrering (🟡 LATER) + +> **Fokus:** La Emma velge den mest effektive kommunikasjonskanalen autonomt. + +| ID | Oppgave | Status | Notat | +|----|---------|--------|-------| +| **CHAN-1** | Kanalvalg-logikk i Emma | 🟡 | | +| **CHAN-2** | Integrer med `main.py` | 🟡 | | + diff --git a/docs/TODO.md b/docs/TODO.md index fdf9a9d..c238f4a 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -7,3 +7,23 @@ > og [`docs/HANDOFF.md`](HANDOFF.md) for gjeldende sesjonsstatus. **Historisk TODO-innhold** (status per 2026-05-25) er bevart i Git-historikken. + +--- + +## Kommende oppgaver (per 2026-07-02) + +> Disse er knyttet til Fase D, E og F i `ROADMAP.md`. + +- **Twilio SMS-grunnlag:** ✅ DONE +- [ ] **sender_id-felt** i SmsNotifyRequest +- [ ] **/notify/sms-inbound** webhook +- [ ] **Alphanumeric Sender ID** i Twilio Console + +--- + +### Senere (Phase E/F) + +- **Skrue 10:** Implementer `/voice` webhook for inngående anrop (Lag 2). +- **Skrue 11:** Implementer logikk for utgående anrop via Twilio API (Lag 3). +- **Skrue 12:** Bygg ConversationRelay WebSocket-handler (Lag 2). +- **Skrue 13:** Implementer logikk for kanalvalg i `main.py` (Lag 4). diff --git a/infrastructure/PLAN.md b/infrastructure/PLAN.md index faa673b..34f6c54 100644 --- a/infrastructure/PLAN.md +++ b/infrastructure/PLAN.md @@ -34,10 +34,19 @@ Stabilisere dev-serveren som aktiv plattform nå, ferdigstille sikker og robust - Koble secret til opax-mcp Cloud Run - Test send_email-verktøy -### 5. Twilio -- Legg `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, `TWILIO_FROM` i Secret Manager -- Koble secrets til opax-mcp Cloud Run -- Test send_sms-verktøy +### 5. Twilio (✅ Fullført 2026-07-02) + +**Twilio SMS — fullført 2026-07-02** +- Secrets i Secret Manager: TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER +- Koblet til osvauco-agent via --update-secrets +- POST /notify/sms operativ — felt: to, body, tier, sender_id +- Testet og bekreftet ✅ + +### Åpne skruer (Twilio) +- [ ] Legg til sender_id (Optional[str]) i SmsNotifyRequest i main.py +- [ ] Implementer POST /notify/sms-inbound (Twilio webhook for innkommende SMS) +- [ ] Aktiver Alphanumeric Sender ID i Twilio Console +- [ ] Kjøp Twilio-nummer med voice+SMS-støtte ### 6. Sikre Gitea-eksponering - Steng port 3000 eksternt