feat(brain): Live-Tool-Events im Gedanken-Stream
Proxy-Patch hookt Claude-CLI `assistant`-Events: bei jedem tool_use- Block (Bash, Read, Edit, Grep, ...) wird per HTTP-POST an die Bridge gemeldet. Bridge spiegelt das als `agent_activity tool=<name>` an die RVS-Clients. App- und Diagnostic-Gedanken-Stream zeigen damit live mit was ARIA gerade macht — vorher kam pro Brain-Call nur EIN „💭 denkt" am Anfang und EIN „✓ fertig" am Ende. Drei neue Bausteine: - proxy-patches/routes.js: kompletter Replacement der npm-Version mit `_attachToolHook(subprocess)` — feuert pro tool_use-Block ein HTTP- POST an http://aria-bridge:8090/internal/agent-activity (URL via ARIA_TOOL_HOOK_URL Env-Variable ueberschreibbar). Fire-and-forget, fail-open — Brain-Call bricht NICHT ab wenn Bridge mal nicht da ist. - docker-compose.yml: vierter cp-Schritt im proxy-Service kopiert routes.js ueber die npm-Version (analog zu openai-to-cli + cli-to- openai). - bridge/aria_bridge.py: neuer `/internal/agent-activity`-Endpoint im bestehenden _serve_internal_http. Plus _emit_activity hat jetzt force=True-Param damit wiederholte gleiche Tool-Aufrufe (3x Bash in Folge) als drei Eintraege im Stream sichtbar bleiben. App + Diagnostic: pushThought-Dedup laesst tool-Events durch (3x Bash hintereinander gibt 3 Eintraege im Gedanken-Stream). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+26
-3
@@ -2519,17 +2519,22 @@ class ARIABridge:
|
||||
status = await asyncio.get_event_loop().run_in_executor(None, _do_request)
|
||||
logger.info("[cancel] Diagnostic /api/cancel: %s", status)
|
||||
|
||||
async def _emit_activity(self, activity: str, tool: str = "") -> None:
|
||||
async def _emit_activity(self, activity: str, tool: str = "", force: bool = False) -> None:
|
||||
"""Sendet agent_activity an die App — nur wenn sich der State geaendert hat.
|
||||
|
||||
Trailing Agent-Events nach chat:final werden 3s lang unterdrueckt
|
||||
(nur 'idle' kommt immer durch)."""
|
||||
(nur 'idle' kommt immer durch).
|
||||
|
||||
force=True: kein State-Dedup — wird vom Proxy-Tool-Hook genutzt
|
||||
damit auch wiederholte gleiche Tool-Aufrufe (z.B. 3x Bash
|
||||
hintereinander) im Gedanken-Stream als eigene Eintraege sichtbar
|
||||
bleiben."""
|
||||
if activity != "idle" and self._last_chat_final_at > 0:
|
||||
since_final = asyncio.get_event_loop().time() - self._last_chat_final_at
|
||||
if since_final < 3.0:
|
||||
return
|
||||
state = (activity, tool)
|
||||
if state == self._last_activity_state:
|
||||
if not force and state == self._last_activity_state:
|
||||
return
|
||||
self._last_activity_state = state
|
||||
await self._send_to_rvs({
|
||||
@@ -2677,6 +2682,24 @@ class ARIABridge:
|
||||
self._handle_trigger_fired(reply, trigger_name, ttype, events)
|
||||
)
|
||||
await _send_response(writer, 200, {"ok": True})
|
||||
elif method == "POST" and path == "/internal/agent-activity":
|
||||
# Vom Proxy gefeuert bei jedem Claude-Code-tool_use-Event
|
||||
# (Bash, Read, Edit, Grep, ...). Wir spiegeln das als
|
||||
# RVS agent_activity an App+Diagnostic damit der Gedanken-
|
||||
# Stream live mitlaufen kann.
|
||||
try:
|
||||
data = json.loads(body.decode("utf-8", "ignore"))
|
||||
except Exception as exc:
|
||||
await _send_response(writer, 400, {"error": f"bad json: {exc}"})
|
||||
return
|
||||
tool = (data.get("tool") or "").strip()
|
||||
if not tool:
|
||||
await _send_response(writer, 400, {"error": "tool erforderlich"})
|
||||
return
|
||||
# Force-emit (kein Dedup): User soll JEDEN Tool-Call sehen
|
||||
# selbst wenn derselbe Name zweimal in Folge kommt.
|
||||
asyncio.create_task(self._emit_activity("tool", tool, force=True))
|
||||
await _send_response(writer, 200, {"ok": True})
|
||||
elif method == "POST" and path == "/internal/delete-chat-message":
|
||||
try:
|
||||
data = json.loads(body.decode("utf-8", "ignore"))
|
||||
|
||||
Reference in New Issue
Block a user