Persona Manager
Two video-conversation workflows on top of Human.work.
What it does
| Workflow | Purpose | Who it's for | Output |
|---|---|---|---|
| Onboarding | Single ~60-min structured video intake with the AI Specialist when a client first deploys it. | Client manager | An Environment Profile (systems, processes, vocabulary, guardrails, stakeholders, priorities) that the Specialist uses as operating context day-to-day. |
| Reporting | Periodic or ad-hoc video check-in with the Specialist. | Client manager | Decisions, priority changes, escalations, environment-change flags, scheduled next check-in — all captured as durable, audited rows. |
The video frontend is Tavus. The system prompts, brief assembly, function-call dispatch, audit, and the queue/escalation surface all live inside the existing Human.work API.
Architecture in a paragraph
A meeting record is created in the new meetings table (onboarding | reporting). The API renders a per-meeting system prompt from agent/prompts/{onboarding,reporting}_meeting.txt, fetches the active function-call definitions for the meeting kind from tavus_function_definitions, then calls Tavus to create a persona and a conversation. The conversation URL goes back to the client manager. As the call progresses, Tavus posts function-call events to /tavus/webhooks/function-call (HMAC-SHA256 verified, Redis-deduped). Those events route to onboarding handlers (which mutate the environment_profiles row) or reporting handlers (which write meeting_decisions + the existing actions table, and route escalations through ExpertQueueService.createQueueItem). Socket.io events (meeting_started, meeting_function_call, meeting_completed) fan out on the existing /notifications namespace.
Integration philosophy
We added new modules to the existing monorepo without modifying production code. The full philosophy is in prompts/persona-builder.md and ADR-0001 below. Three permitted touches to existing files:
frontend/src/lib/api.ts— additive functions only.api/src/app.module.ts— single-line module imports +imports[]entries..github/workflows/nightly-isolation.yml— additive entity entries.
Every other existing file is read-only.
File map
api/src/
tavus/ Tavus client, webhook verifier, router,
function-call CRUD + controller
environment-profiles/ env profile entity + service + onboarding
function-call handlers + SOUL.md generator
meetings/ meeting/decision/priority entities,
service (onboarding + reporting start),
brief assembler, persona generator,
reporting handlers, BullMQ cleanup processor
agent/prompts/
onboarding_meeting.txt system prompt for the onboarding persona
reporting_meeting.txt system prompt for the reporting persona
(with {{ BRIEF_JSON }} placeholder)
api/migrations/
1746000000010-PersonaManagerInit.ts five new tables + RLS
1746000000011-SeedPersonaManagerFunctions.ts 12 v1 function definitions
frontend/src/app/
client/admin/specialists/[id]/onboarding/ client-side onboarding flow
client/admin/specialists/[id]/meetings/ list, detail (start + outputs)
ops/personas/function-calls/ SuperAdmin function-call CRUD
ops/personas/replicas/ SuperAdmin replica catalogue
ops/personas/templates/ SuperAdmin template reference
frontend/e2e/persona-manager/
01-onboarding.spec.ts full onboarding E2E
02-reporting.spec.ts full reporting E2E
03-replica-not-set.spec.ts negative 409 path
docs/
decisions/persona-manager/ADR-0001-integration-approach.md
specs/persona-manager-integration.md
persona-manager/README.md (this file), api.md, function-calls.md
Configuration
| Env var | Purpose |
|---|---|
TAVUS_API_KEY | Auth for Tavus REST calls. |
TAVUS_API_BASE_URL | Defaults to https://tavusapi.com. Override for staging. |
TAVUS_WEBHOOK_SECRET | HMAC-SHA256 secret for verifying inbound webhooks. Hard-fails at boot in deployed envs if unset. |
TAVUS_DEFAULT_REPLICA_ID | The Tavus replica id used as the default for persona creation. |
TAVUS_WEBHOOK_BASE_URL | The public URL Tavus posts back to. Defaults to APP_BASE_URL. |
PERSONA_CLEANUP_AFTER_DAYS | How old ended_at must be before the cleanup sweep archives a persona. Default 14. |
PERSONA_CLEANUP_CADENCE_MS | How often the BullMQ cleanup job runs. Default 86_400_000 (24h). Requires REDIS_URL. |
HWORK_ORGS_DIR | Where SOUL.proposed.md files are written. Default: repo orgs/ directory. |
HWORK_AGENT_PROMPTS_DIR | Where the prompt templates live. Default: repo agent/prompts/. |
Status
- Phase 0 — Foundation: schema, entities, isolation env var ✓
- Phase 1 — Tavus integration layer: client, webhook verifier, router, controller ✓
- Phase 2 — Function-call library: CRUD, seed migration, SuperAdmin UI ✓
- Phase 3 — Environment Profile + onboarding: service, handlers, SOUL.md generator, start endpoint, prompt, frontend ✓
- Phase 4 — Brief assembly + reporting: brief assembler, persona generator, reporting handlers, Socket.io events, frontend ✓
- Phase 5 — SuperAdmin surfaces: replicas catalogue, templates reference, audit-via-existing-viewer ✓
- Phase 6 — Hardening: Playwright E2Es (skip-by-default unless
PERSONA_MANAGER_E2E=1), cross-tenant isolation spec, BullMQ cleanup job, rate-limit inheritance ✓ - Docs: this README, api.md, function-calls.md.
See BUILD_LOG.jsonl for the per-task trail and TODO_PERSONA.md for the canonical task list.