Prompt — Beleg-Pipeline Session 2 (Gmail-API + PDF-Extraktion)

Session 1 ist fertig (2026-05-12) — Run-Bericht: _index. Layer-Code, Heartbeat, IAM, alle Secrets live. Hier geht’s um Session 2.

Copy-paste das in eine neue Claude-Code-Session in ~/source/agentic-ventures/:


Hi. Beleg-Pipeline Session 2 von 4. Voraussetzungen aus Session 1 sind alle erfuellt:

  • Layer agentic-common mit logging, secrets, telegram, bedrock live in av-production
  • Lambda agent-beleg-pipeline deployed, Heartbeat-Push laeuft alle 15 Min
  • 3 Secrets in Secrets Manager mit echten Werten (telegram-bot-token, gmail-oauth-refresh als Bundle hello+privat, github-pat)
  • IAM-Bugs aus Session 1 gefixt (Date-Tag-Modell, Account-Slot im Inference-Profile-ARN, -* im Secrets-ARN)
  • daily-briefing-Routine ist parallel live, hat als Referenz schon gmail_client.py + github_client.py in lambdas/daily-briefing/ implementiert

Diese Session: Session 2 von 4 — Gmail-Pull + PDF-Extraktion. Ziel am Ende: Lambda zieht die Belege aus dem Gmail-Label und hat den Text aus den PDFs verfuegbar. Noch kein Klassifikator, noch kein S3-Upload, noch kein Papierkram — nur die Roh-Datenbeschaffung.

Reihenfolge:

  1. Gmail-Client in agentic-common extrahieren (~30 Min)

    • lambdas/daily-briefing/gmail_client.py hat schon OAuth-Refresh + list_messages + get_message_metadata. Reicht fuer Beleg-Pipeline (Pattern „MCP-Helper extrahieren wenn 2+ Routinen ihn brauchen” aus SKILL).
    • Neuer Pfad: layers/agentic-common/python/agentic_common/gmail.py
    • Plus erweitern um get_message_with_attachments(account, oauth, msg_id) — Body + alle application/pdf-Attachments mit attachmentId (raw base64 nicht direkt, separater Call zu users/me/messages/{id}/attachments/{attachmentId}).
    • In daily-briefing Imports auf agentic_common.gmail umstellen, alten lokalen Pfad loeschen.
  2. PDF-Parsing-Modul (~30 Min)

    • Lambda braucht pypdfium2 — das ist eine native Dependency, muss im Layer-Build per pip installiert werden. Erweitere infra/lib/common-layer.ts:
      bundling: {
        image: lambda.Runtime.PYTHON_3_12.bundlingImage,
        command: [
          'bash', '-c',
          'pip install -r requirements.txt -t /asset-output/python && cp -r python /asset-output/',
        ],
      }
    • Requirements.txt im Layer-Root: pypdfium2>=4.30
    • Neues Modul agentic_common/pdf.py mit extract_text(pdf_bytes: bytes) -> str und extract_first_page_text(pdf_bytes: bytes) -> str (Empfaenger-Adresse steht meist auf S. 1).
    • CDK-Bundling brauch Docker — docker info checken vorher.
  3. Beleg-Pipeline main.py erweitern (~60 Min)

    • Bisheriger Heartbeat bleibt als Erfolg-Bullet drin (zeigt dass Pipeline-Run gestartet hat).
    • Neuer Pipeline-Block nach Bedrock-Probe: a) Gmail (hello@-Konto) listen mit Query label:Belege -label:processed has:attachment newer_than:30d, max 50 Messages b) Pro Message: alle PDF-Attachments holen, raw bytes via get_attachment c) Pro PDF: extract_first_page_text → Empfaenger-Block, ganzen Text fuer spaeter cachen
    • Ergebnis als report.successes.append(f"{N} Belege geholt: {filenames}"). Noch nichts archivieren.
    • State: stateless. „processed”-Label setzt Session 3 nach erfolgreichem Voucher-Anlegen. Session 2 ist read-only.
  4. Local-Smoke + Deploy + Cron-Run (~30 Min)

    • Local: PYTHONPATH=... AWS_PROFILE=av-production python3 -c "import main; main.handler({'source':'local'}, FakeContext())" — sehen ob Gmail + PDF durchgeht.
    • cdk deploy BelegPipelineStack — neuer Layer mit pypdfium2 wird gepackt (kann 1-2 Min dauern wegen Bundling).
    • Manueller Invoke + CloudWatch tail: pruefen wie viele Belege gezogen wurden, ob PDF-Extraktion ok.
    • Telegram-Push zeigt: ✓ 7 Belege gezogen: hetzner-2026-04.pdf, anthropic-2026-05.pdf, ...
  5. Doku + Commit (~15 Min)

    • email-agent/_index.md Phase 1.5.4-1.5.5-Stand auf done
    • agents-platform.md Aktive-Agents-Tabelle: Beleg-Pipeline-Status update
    • Run-Bericht in intern/runs/2026-05-1X-beleg-pipeline-session2-gmail-pdf/_index.md
    • Commit in beiden Repos (push macht Marvin manuell wegen Sandbox).

Definition of Done Session 2:

  • Layer hat pypdfium2 + agentic_common.gmail + agentic_common.pdf
  • Lambda zieht Belege aus Gmail-Label, extrahiert PDF-Text
  • Telegram-Push zeigt Anzahl + Filenamen der gezogenen Belege
  • Stateless — kein Archivieren, kein Label-Setzen, kein S3 (kommt Session 3)

Was bewusst NICHT in Session 2 reinkommt:

  • Klassifikator (Bedrock business/privat) — Session 3
  • S3-Upload — Session 3
  • Papierkram-Voucher — Session 3
  • Vault-Stub-Commit — Session 3
  • processed-Label setzen — Session 3
  • Backfill historischer Belege — Session 4

Fallstricke aus Session 1 (siehe aws-lambda-cron-fallstricke):

  • Bedrock + Secrets-ARN-Quirks sind im Stack schon korrekt — nicht erneut anfassen
  • Wenn neue IAM-Permission noetig: pruefen ob als IAM-Policy-Statement in beleg-pipeline-stack.ts adden (nicht im AgenticVenturesAgent-Construct ergaenzen — der ist generic)
  • Layer-Pip-Bundling braucht Docker — wenn Docker nicht laeuft, schlaegt cdk deploy fehl

Repo-Sync-Achtung:

  • Vault Lokal + Remote sind divergent (siehe wichtige-naechste-entscheidung-vault-repo-divergenz) — vor Session 2 idealerweise loesen (Option C empfohlen), sonst Push am Ende muehsam
  • agents-platform-Repo ist OK, hat aber 2 ungepushte Commits (24abf59 + 824cb78)

Tooling fuer Session 2:

  • gsuite-MCP (lokal) zum Verifizieren welche Mails das Label aktuell hat
  • Docker laufend fuer Layer-Bundling
  • AWS CLI mit av-production
  • ggf. aws bedrock list-inference-profiles falls neue Modelle dazukommen

Los geht’s mit Schritt 1: Gmail-Client aus daily-briefing in den Layer extrahieren.