A Hermes-powered meeting memory tracker. Ingests transcripts (VTT/TXT) or
audio (WAV/MP3 → Modal-hosted Whisper + pyannote diarization) on a
per-workspace basis, extracts eight kinds of typed memory cards
(decisions, action items, pain points, requirements, risks, open
questions, quotes, technical details), and lets users browse a per-meeting
narrative summary or ask Hermes natural-language questions across the
whole workspace with [card] / [src] clickable citations.
Three FastAPI services + one Vite/React SPA, all in this monorepo. The
LLM backend is provider-switchable at runtime (LLM_PROVIDER=anthropic
or LLM_PROVIDER=openai); the same SKILL.md prompts run under either
dispatcher. Data is isolated per workspace (workspace_id filter at the
SQL layer for every read path).
browser
|
v
SPA (React Router)
/ws/:workspaceId/*
|
v
storage-router (port 8050)
├── Postgres-15 (meetings, transcripts, memory_cards, workspaces)
├── Hermes runtime (src/hermes_plugin/, anthropic | openai)
├── transcript-ingest (HTTP, port 8011) ← VTT/SRT/TXT/MD/JSON parser
└── voice-ingest (HTTP, Modal) ← faster-whisper + pyannote
| Path | What it is |
|---|---|
src/storage_router/ | FastAPI gateway. Hosts /api/conversations/import, /api/meetings*, /api/memory-cards*, /api/workspaces*, /api/search/*, /docs (Swagger), and serves the SPA when FRONTEND_DIST is set. |
src/transcript_ingest/ | Standalone FastAPI service. Detects format (txt/md/vtt/srt/json) and parses speakers + timestamps. |
src/voice_ingest/ | Standalone FastAPI service. Runs faster-whisper STT + pyannote diarization. mp4 video containers are accepted; audio is stripped via ffmpeg before transcribe. |
src/hermes_plugin/ | Hermes plugin loader + skill runtime. Skills live in src/hermes_plugin/skills/<name>/SKILL.md (prompt template + tool bindings + max-iterations metadata). |
src/ (frontend roots: src/api/, src/pages/, src/components/, src/layouts/, src/hooks/, src/lib/, src/mocks/) | Vite + React + TypeScript SPA. Routes in src/App.tsx. |
schemas/, migrations/, openapi/, fixtures/ | Tier-0 contracts shared by all services. |
alembic/ | Storage-router migrations (Postgres). |
tests/storage_router/, tests/transcript_ingest/, tests/voice_ingest/, tests/hermes_plugin/ | Per-service test suites. |
e2e/ | Playwright end-to-end tests for the SPA. |
All routes are workspace-scoped under /ws/:workspaceId/.
| Route | Purpose |
|---|---|
/meetings | Home — list of meetings in this workspace; click into one to review. |
/import | Upload a transcript (VTT/TXT/SRT) or audio file (WAV/MP3/mp4-video → audio extracted server-side). Auto-finalize after parse. |
/live | Real-time mic capture + on-the-fly extraction: live current-topic banner, live-summary, interview-questioner proposing follow-up questions every 60 s. |
/ask | Workspace-level Ask Hermes — natural-language QA across every meeting in the workspace, with [card] / [src] citations that deep-link back into the source meeting. |
/meetings/:id/processing | Status page while a meeting is mid-extraction; auto-advances when finalized. |
/meetings/:id | Review tabs: Summary (narrative TL;DR + What we covered + Notes), Transcript (with click-to-Ask), Memory Cards (8 typed kinds), Ask Hermes (in-meeting QA), Share/Export (disabled — Phase 8). |
/action-items | Aggregated action_item cards across all workspace meetings. |
/open-questions | Aggregated open_question cards across all workspace meetings. |
/settings | Workspace settings (placeholder). |
riz0b05s7yg7ab ("tracker-app-2026-05-12")https://riz0b05s7yg7ab-8050.proxy.runpod.net/tracker DB).ssh -p 41734 -i ~/.ssh/id_ed25519 root@213.192.2.103/workspace/app (git checkout of this repo, on main)/var/log/tracker-app.log (storage-router), /var/log/transcript-ingest.logkill <uvicorn-pid> and re-run the launcher in start-router.sh (or the inline env+nohup snippet captured in the launch logs).hao-ai-lab Modal workspace as voice-ingest.https://hao-ai-lab--voice-ingest-fastapi.modal.runlarge-v3, pyannote.audio 3.3.2.hf-token-tracker.
Do NOT overwrite the older Modal Secret named hf-token — it
belongs to a different teammate.python3.12 -m venv .venv && source .venv/bin/activate && pip install -e .DATABASE_URL=... alembic upgrade headnpm install && npm run dev (Vite, port 5173)OPENAI_API_KEY or ANTHROPIC_API_KEY (the runtime picks one based on LLM_PROVIDER)Import & ingest
Live recording
Memory cards (8 typed kinds)
hidden_at).Summary tab
AnswerBody component.Ask Hermes
/ws/:workspaceId/ask with citations that
deep-link back to the source meeting + segment.[card], [card:<id>], [seg:<id>],
[project:<ws>:meeting:<m>:card:<c>].Workspace switcher
/ws/:workspaceId/....Cross-meeting aggregation
/action-items and /open-questions roll up cards across the workspace.Speaker rename
PATCH /api/meetings/:id/speakers with {from, to} rewrites
speaker_label_map and re-applies to all transcript segments + cards.There is no explicit Undo button in the UI yet. The reversible primitives in the system today:
POST /api/memory-cards/:id/hide) — soft-deletes via
hidden_at. Hidden cards survive in the row store; pass
?include_hidden=true on the list endpoint to fetch them.POST /api/memory-cards/:loser/supersede-into/:winner)
— consolidation merges duplicates: loser is hidden, winner stays.{from: to, to: from}.useMeetings prunes localStorage
entries the server no longer recognizes (stale bookmark, deleted meeting).DELETE /api/meetings/:id route does not exist yet).workspace-qa to a per-project subagent is deferred.MeetingReviewPage).speaker_label_map history stack).README-storage-router.md — storage-router setup + DSN configREADME-transcript-ingest.md — transcript-ingest setup + supported formatsREADME-voice-ingest.md — voice-ingest setup (Whisper, diarization, HF token, model defaults)38 commits
Python
65.5%
TypeScript
29.7%
Shell
3.3%
JavaScript
1.0%
A Hermes-powered meeting memory tracker. Ingests transcripts (VTT/TXT) or
audio (WAV/MP3 → Modal-hosted Whisper + pyannote diarization) on a
per-workspace basis, extracts eight kinds of typed memory cards
(decisions, action items, pain points, requirements, risks, open
questions, quotes, technical details), and lets users browse a per-meeting
narrative summary or ask Hermes natural-language questions across the
whole workspace with [card] / [src] clickable citations.
Three FastAPI services + one Vite/React SPA, all in this monorepo. The
LLM backend is provider-switchable at runtime (LLM_PROVIDER=anthropic
or LLM_PROVIDER=openai); the same SKILL.md prompts run under either
dispatcher. Data is isolated per workspace (workspace_id filter at the
SQL layer for every read path).
browser
|
v
SPA (React Router)
/ws/:workspaceId/*
|
v
storage-router (port 8050)
├── Postgres-15 (meetings, transcripts, memory_cards, workspaces)
├── Hermes runtime (src/hermes_plugin/, anthropic | openai)
├── transcript-ingest (HTTP, port 8011) ← VTT/SRT/TXT/MD/JSON parser
└── voice-ingest (HTTP, Modal) ← faster-whisper + pyannote
| Path | What it is |
|---|---|
src/storage_router/ | FastAPI gateway. Hosts /api/conversations/import, /api/meetings*, /api/memory-cards*, /api/workspaces*, /api/search/*, /docs (Swagger), and serves the SPA when FRONTEND_DIST is set. |
src/transcript_ingest/ | Standalone FastAPI service. Detects format (txt/md/vtt/srt/json) and parses speakers + timestamps. |
src/voice_ingest/ | Standalone FastAPI service. Runs faster-whisper STT + pyannote diarization. mp4 video containers are accepted; audio is stripped via ffmpeg before transcribe. |
src/hermes_plugin/ | Hermes plugin loader + skill runtime. Skills live in src/hermes_plugin/skills/<name>/SKILL.md (prompt template + tool bindings + max-iterations metadata). |
src/ (frontend roots: src/api/, src/pages/, src/components/, src/layouts/, src/hooks/, src/lib/, src/mocks/) | Vite + React + TypeScript SPA. Routes in src/App.tsx. |
schemas/, migrations/, openapi/, fixtures/ | Tier-0 contracts shared by all services. |
alembic/ | Storage-router migrations (Postgres). |
tests/storage_router/, tests/transcript_ingest/, tests/voice_ingest/, tests/hermes_plugin/ | Per-service test suites. |
e2e/ | Playwright end-to-end tests for the SPA. |
All routes are workspace-scoped under /ws/:workspaceId/.
| Route | Purpose |
|---|---|
/meetings | Home — list of meetings in this workspace; click into one to review. |
/import | Upload a transcript (VTT/TXT/SRT) or audio file (WAV/MP3/mp4-video → audio extracted server-side). Auto-finalize after parse. |
/live | Real-time mic capture + on-the-fly extraction: live current-topic banner, live-summary, interview-questioner proposing follow-up questions every 60 s. |
/ask | Workspace-level Ask Hermes — natural-language QA across every meeting in the workspace, with [card] / [src] citations that deep-link back into the source meeting. |
/meetings/:id/processing | Status page while a meeting is mid-extraction; auto-advances when finalized. |
/meetings/:id | Review tabs: Summary (narrative TL;DR + What we covered + Notes), Transcript (with click-to-Ask), Memory Cards (8 typed kinds), Ask Hermes (in-meeting QA), Share/Export (disabled — Phase 8). |
/action-items | Aggregated action_item cards across all workspace meetings. |
/open-questions | Aggregated open_question cards across all workspace meetings. |
/settings | Workspace settings (placeholder). |
riz0b05s7yg7ab ("tracker-app-2026-05-12")https://riz0b05s7yg7ab-8050.proxy.runpod.net/tracker DB).ssh -p 41734 -i ~/.ssh/id_ed25519 root@213.192.2.103/workspace/app (git checkout of this repo, on main)/var/log/tracker-app.log (storage-router), /var/log/transcript-ingest.logkill <uvicorn-pid> and re-run the launcher in start-router.sh (or the inline env+nohup snippet captured in the launch logs).hao-ai-lab Modal workspace as voice-ingest.https://hao-ai-lab--voice-ingest-fastapi.modal.runlarge-v3, pyannote.audio 3.3.2.hf-token-tracker.
Do NOT overwrite the older Modal Secret named hf-token — it
belongs to a different teammate.python3.12 -m venv .venv && source .venv/bin/activate && pip install -e .DATABASE_URL=... alembic upgrade headnpm install && npm run dev (Vite, port 5173)OPENAI_API_KEY or ANTHROPIC_API_KEY (the runtime picks one based on LLM_PROVIDER)Import & ingest
Live recording
Memory cards (8 typed kinds)
hidden_at).Summary tab
AnswerBody component.Ask Hermes
/ws/:workspaceId/ask with citations that
deep-link back to the source meeting + segment.[card], [card:<id>], [seg:<id>],
[project:<ws>:meeting:<m>:card:<c>].Workspace switcher
/ws/:workspaceId/....Cross-meeting aggregation
/action-items and /open-questions roll up cards across the workspace.Speaker rename
PATCH /api/meetings/:id/speakers with {from, to} rewrites
speaker_label_map and re-applies to all transcript segments + cards.There is no explicit Undo button in the UI yet. The reversible primitives in the system today:
POST /api/memory-cards/:id/hide) — soft-deletes via
hidden_at. Hidden cards survive in the row store; pass
?include_hidden=true on the list endpoint to fetch them.POST /api/memory-cards/:loser/supersede-into/:winner)
— consolidation merges duplicates: loser is hidden, winner stays.{from: to, to: from}.useMeetings prunes localStorage
entries the server no longer recognizes (stale bookmark, deleted meeting).DELETE /api/meetings/:id route does not exist yet).workspace-qa to a per-project subagent is deferred.MeetingReviewPage).speaker_label_map history stack).README-storage-router.md — storage-router setup + DSN configREADME-transcript-ingest.md — transcript-ingest setup + supported formatsREADME-voice-ingest.md — voice-ingest setup (Whisper, diarization, HF token, model defaults)38 commits
Python
65.5%
TypeScript
29.7%
Shell
3.3%
JavaScript
1.0%