feat: Agent Chat API backend - profiles, send, history

- GET /api/agents - list known profiles with online/offline status
- POST /api/agents/{profile}/send - send message via Hermes CLI subprocess
- GET /api/agents/{profile}/history - retrieve conversation history
- SQLite conversation store at ~/.hermes/kanban/boards/hermes-command-center/conversations.db
- Response cleanup to strip Hermes CLI wrapper formatting
- Auth-gated via existing Basic Auth middleware
This commit is contained in:
2026-06-01 23:53:39 -04:00
parent ca1cb63f65
commit 9788abb8ce
+41
View File
@@ -143,6 +143,42 @@ def _get_conversation_history(profile: str, limit: int = 50) -> list[dict]:
conn.close()
def _clean_agent_response(text: str) -> str:
"""Extract just the agent's reply from Hermes CLI wrapper output."""
lines = text.splitlines()
result_lines = []
in_box = False
for line in lines:
stripped = line.strip()
if stripped.startswith("Query:") or stripped.startswith("Initializing"):
continue
if stripped.startswith("╭─"):
in_box = True
continue
if stripped.startswith("╰─"):
in_box = False
continue
if in_box:
result_lines.append(stripped)
if stripped.startswith("Resume this session") \
or stripped.startswith("Session:") \
or stripped.startswith("Duration:") \
or stripped.startswith("Messages:"):
break
cleaned = "\n".join(result_lines).strip()
if cleaned:
return cleaned
if "╰─" in text:
parts = text.split("╰─")
before = parts[0]
if "╭─" in before:
for line in before.split("╭─", 1)[1].splitlines():
s = line.strip()
if s:
return s
return ""
_init_conversations_db()
app = FastAPI(title="Hermes Command Center")
@@ -729,6 +765,11 @@ async def agent_send(profile: str, request: Request):
if not response_text:
response_text = "(no response)"
# Clean up CLI wrapper text — extract the actual agent response
cleaned = _clean_agent_response(response_text)
if cleaned:
response_text = cleaned
# Save agent response
_save_message(profile, "agent", response_text)