diff --git a/src/agents/claude_client.py b/src/agents/claude_client.py index 3282cba..661180d 100644 --- a/src/agents/claude_client.py +++ b/src/agents/claude_client.py @@ -41,12 +41,14 @@ class UsageAccumulator: async def call_claude(prompt: str, tools: str | None = "WebSearch,WebFetch", model: str | None = None) -> tuple[str, ClaudeUsage]: """Ruft Claude CLI auf. Gibt (result_text, usage) zurück. + Prompt wird via stdin uebergeben um OS ARG_MAX Limits zu vermeiden. + Args: - prompt: Der Prompt für Claude + prompt: Der Prompt fuer Claude tools: Kommagetrennte erlaubte Tools (None = keine Tools, --max-turns 1) - model: Optionales Modell (z.B. CLAUDE_MODEL_FAST für Haiku). None = CLI-Default (Opus). + model: Optionales Modell (z.B. CLAUDE_MODEL_FAST fuer Haiku). None = CLI-Default (Opus). """ - cmd = [CLAUDE_PATH, "-p", prompt, "--output-format", "json"] + cmd = [CLAUDE_PATH, "-p", "-", "--output-format", "json"] if model: cmd.extend(["--model", model]) if tools: @@ -56,6 +58,7 @@ async def call_claude(prompt: str, tools: str | None = "WebSearch,WebFetch", mod process = await asyncio.create_subprocess_exec( *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, + stdin=asyncio.subprocess.PIPE, env={ "PATH": "/usr/local/bin:/usr/bin:/bin", "HOME": "/home/claude-dev", @@ -64,7 +67,9 @@ async def call_claude(prompt: str, tools: str | None = "WebSearch,WebFetch", mod }, ) try: - stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=CLAUDE_TIMEOUT) + stdout, stderr = await asyncio.wait_for( + process.communicate(input=prompt.encode("utf-8")), timeout=CLAUDE_TIMEOUT + ) except asyncio.TimeoutError: process.kill() raise TimeoutError(f"Claude CLI Timeout nach {CLAUDE_TIMEOUT}s") diff --git a/src/database.py b/src/database.py index eb4ff00..2e95118 100644 --- a/src/database.py +++ b/src/database.py @@ -350,6 +350,26 @@ async def init_db(): await db.execute("ALTER TABLE fact_checks ADD COLUMN tenant_id INTEGER REFERENCES organizations(id)") await db.commit() + # Migration: status_history fuer fact_checks (Faktencheck-Verlauf) + if "status_history" not in fc_columns: + await db.execute("ALTER TABLE fact_checks ADD COLUMN status_history TEXT DEFAULT '[]'") + # Bestehende Eintraege initialisieren + cursor2 = await db.execute("SELECT id, status, checked_at FROM fact_checks") + for row2 in await cursor2.fetchall(): + import json as _json + initial_history = _json.dumps([{"status": row2[1], "at": str(row2[2])}]) + await db.execute("UPDATE fact_checks SET status_history = ? WHERE id = ?", (initial_history, row2[0])) + await db.commit() + logger.info("Migration: status_history zu fact_checks hinzugefuegt") + + # Migration: category fuer article_locations (Marker-Klassifizierung) + cursor = await db.execute("PRAGMA table_info(article_locations)") + al_columns = [row[1] for row in await cursor.fetchall()] + if "category" not in al_columns: + await db.execute("ALTER TABLE article_locations ADD COLUMN category TEXT DEFAULT 'mentioned'") + await db.commit() + logger.info("Migration: category zu article_locations hinzugefuegt") + # Migration: tenant_id fuer incident_snapshots cursor = await db.execute("PRAGMA table_info(incident_snapshots)") snap_columns2 = [row[1] for row in await cursor.fetchall()]