Add SSE real-time Talk activity, file editor UI, and identity file API

- event_bus.py: in-process asyncio pub/sub (one Queue per SSE client)
- nextcloud_talk.py: publishes nct_message/nct_response events to bus
- chat.py: GET /events SSE endpoint streams Talk activity to browser
- routers/files.py: whitelist-protected GET/PUT for Inara identity .md files
- main.py: register files router
- static/index.html: real-time Talk feed, blue badge on Sessions btn,
  Files modal with preview/edit toggle and Ctrl+S save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-17 21:10:07 -04:00
parent fe854ee534
commit 3455c7a09c
9 changed files with 460 additions and 1 deletions

View File

@@ -13,6 +13,7 @@ from context_loader import load_context
from llm_client import complete
from session_logger import log_turn
from session_store import load as load_session, save as save_session
import event_bus
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
@@ -78,6 +79,14 @@ async def _process_message(conversation_token: str, user_text: str, actor_name:
history = load_session(session_id)
history.append({"role": "user", "content": user_text})
await event_bus.publish({
"type": "nct_message",
"session_id": session_id,
"role": "user",
"content": user_text,
"actor": actor_name,
})
try:
response_text, backend = await asyncio.wait_for(
complete(system_prompt=system_prompt, messages=history),
@@ -96,6 +105,15 @@ async def _process_message(conversation_token: str, user_text: str, actor_name:
history.append({"role": "assistant", "content": response_text})
save_session(session_id, history)
log_turn(session_id, user_text, response_text)
await event_bus.publish({
"type": "nct_response",
"session_id": session_id,
"role": "assistant",
"content": response_text,
"backend": backend,
})
await _send_reply(conversation_token, response_text)