ai/.project/README.md
autocommit 21fb00766c chore(config): 🔧 Update IDE/build configuration settings in project config file
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:06:54 -07:00

191 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# @ai Project Management
## Why @ai Exists
Every AI-enabled application in this ecosystem independently re-implemented (or skipped) the
same four concerns: identity, memory, personality, and context assembly. @chobit had `miku.json`
and a 10-message ephemeral history. @life had `memory.service.ts` siloed per-platform, inline
agent personas, and its own ambient companion service (AmbientCompanionService). @kthulu had
no persistent memory or identity at all. Each app assembled LLM prompts differently with no
shared contract.
@ai consolidates those four concerns into a single runtime. It is the *mind* of the assistant.
Applications are the *body* (@chobit), *hands* (@kthulu), and *world* (@life, @education, @career).
## What @ai Replaces
| What's being removed | Where it lived | Replaced by |
|----------------------|---------------|-------------|
| `@life/life-ai` companion service | `@life/@applications/ai/services/companion/` | @ai identity + nag + context |
| `@life/platform-ai` service | `@life/@applications/ai/services/platform-ai/` | @ai identity + nag + context |
| `AmbientCompanionService` | `@life/messenger/notifications/backend/` | @ai M4 nag module |
| `NudgeService` | `@life/messenger/notifications/backend/` | @ai M4 nag module |
| `memory.service.ts` | `@life/platform-ai/features/assistant/` | @ai M2 memory module |
| `miku.json` (local) | `@chobit/config/personalities/` | @ai M3 personality module |
| `.quinn` CronCreate nag | `~/.claude/commands/nag-start.md` | @ai M4 `POST /nag/start` |
## Correct Location
**Current:** `~/Code/@applications/@ai/` (wrong tier — placed in infrastructure layer)
**Correct:** `~/Code/@projects/@ai/` (a domain project, like @life and @kthulu)
When M0 scaffold begins, create at `@projects/@ai/`, not `@applications/@ai/`.
Exported packages go in `@projects/@ai/@packages/` (not global `~/Code/@packages/`).
## Directory Structure
```
.project/
├── README.md # This file
├── streams/ # Active feature workstreams
│ └── <stream-name>/
│ ├── README.md # Feature overview and architecture
│ ├── STATUS.md # Current progress and blockers
│ ├── HANDOFF.md # Session handoff context
│ └── NOTES.md # Technical decisions and learnings
├── history/ # Completed work records
│ └── YYYYMMDD_description.md
└── templates/ # Stream templates
```
## Active Streams
None — project not yet scaffolded.
## Milestone Roadmap
### M0: Project Scaffold 🔲
- `@applications/@ai/` directory + `app.manifest.yaml`
- `services/ai-core/` — NestJS app via `@lilith/service-nestjs-bootstrap`
- Docker compose: PostgreSQL (26395) + Redis (26394)
- `GET /health` endpoint
- `./run` task runner (dev/stop/status/logs)
- `packages/ai-client/` skeleton (`@lilith/ai-client`)
### M1: Identity Module 🔲
- `PersonaEntity` — id, name, voice_id, tags, description (maps from miku.json)
- `UserIdentityEntity` — id, display_name, bound_persona_id, metadata JSONB
- CRUD endpoints: `GET/POST/PATCH /identity`, `GET/POST /identity/:id/personas`
- Seed: "quinn" identity + "miku" persona from existing `godot-desktop/config/personalities/miku.json`
- Client: `ai-client/identity.ts`
### M2: Memory Module 🔲
- `MemoryEntryEntity` — key, content, category, tags[], metadata JSONB, soft-delete
(pattern from `@life/platform-ai/features/assistant/generic-tools/services/memory.service.ts`)
- Redis cache layer with PG fallback
(pattern from `@ml/knowledge-platform/features/api/service/src/cache/subject-cache.ts`)
- Endpoints: `GET/POST/PATCH/DELETE /memory`, `GET /memory/search?q=&tags=&category=`
- TTL-based cache with subject invalidation
- Client: `ai-client/memory.ts`
### M3: Personality Module 🔲
- Personality template loader — reads JSON files from `config/personalities/`
- Prompt composer — assembles system prompt from template + context payload
(ports the logic from `@chobit/godot-desktop/platform/conversation/prompt_composer.gd`)
- Composition order: identity → voice_constraint → traits → negatives → emotion_tags → depth_tier → context_modifiers → situation_overrides
- Endpoints:
- `GET /personality` — list available personalities
- `GET /personality/:id` — personality definition
- `POST /personality/:id/compose` — compose system prompt from context payload
- Migrate `miku.json` from `@chobit` to `@ai` as the source of truth
- Client: `ai-client/personality.ts`
### M4: Tasks Module 🔲
- `TaskListEntity` — id, name, identity_id, description, metadata JSONB
- `TaskEntity` — id, list_id, content, priority (0100), status, due_at, tags[], metadata JSONB
- status: `pending | in_progress | done | snoozed`
- Redis pub/sub via `@lilith/eventbus` — emit `ai.task.created`, `ai.task.updated`, `ai.task.completed`
- Endpoints:
- `GET/POST /tasks` — list management
- `GET/POST /tasks/:list_id/items` — task CRUD
- `PATCH /tasks/:list_id/items/:id` — update status/priority
- Seed: "quinn-platforms" task list from `.quinn/business/registrations.md`
- Client: `ai-client/tasks.ts`
**Full stream spec:** `.project/streams/m4-nag-loop/README.md`
Two working reference implementations inform M4's design:
- **`.quinn` nag loop** — file-based context, Miku TTS, CronCreate (simple, working today)
- **`@life` ambient companion** — API-based context, iMessage, NudgeSession entity (sophisticated, production)
M4 generalizes both into a unified nag engine with `ContextProvider` + `DeliveryChannel` interfaces,
`NagLoopEntity` + `NagSessionEntity` persistence, and `POST/DELETE/GET /nag/*` endpoints.
### M5: Context Module 🔲
The primary integration endpoint — assembles everything into a ready-to-use LLM payload.
- `POST /context/compose` — accepts identity_id, personality_id, recent_messages[], context{}
- Assembly pipeline:
1. Load identity → user binding
2. Compose personality system prompt (→ M3 endpoint)
3. Query memory for relevant entries (semantic search on recent_messages)
4. Fetch active tasks for identity → optional task_summary string
5. Return: `{ system_prompt, memory_injections[], task_summary }`
- Replaces: `@chobit` direct model-boss calls, `@life` memory.service.ts inline assembly
- Client: `ai-client/context.ts`
### M5b: Response Format Module 🔲
Decides model selection and dual-response config per-request.
- `ResponseFormat` returned alongside `system_prompt` from `/context/compose`
- Model selection logic: conversation → `qwen3-4b`, complex → `qwen3-32b`, TTS always → `qwen3-4b`
- Dual-response modes: `text_only | tts_only | dual`
- Depth tier → TTS max_tokens mapping (from personality module)
- Consumer capability registration: declare `tts_capable: true/false` on identity
- `tts` config includes: model, max_tokens, voice_id, personality_id
- Injected TTS system constraint: "Respond in 13 short spoken sentences. No lists, no markdown."
- When to speak: companions (dual), nag loop (tts_only), API (text_only), notifications (tts_only)
### M6: ai-client Package 🔲
- Publish `@lilith/ai-client` to Verdaccio (npm.nasty.sh:4873)
- Full TypeScript client covering all 5 modules
- React hooks: `useMemory()`, `useTasks()`, `usePersonality()`
- Auto-retry + error handling
- Use `npx @lilith/dev-publish` for fast iteration
### M7: @chobit Integration 🔲
Wire @chobit to use @ai:
- `llm_client.gd` → HTTP `POST /context/compose` (replaces raw model-boss endpoint)
- `conversation_store.gd` → async sync to `POST /memory` after each turn
- Remove `MAX_HISTORY = 10` cap — full history lives in @ai
- `prompt_composer.gd` → becomes thin HTTP client to `POST /personality/miku/compose`
- Extend Redis eventbus namespace: `chobit.task.*` events from @ai
### M8: Relationship Module 🔲
Dynamic personality — relationship arc, trait intensity, shared history injection.
- `RelationshipEntity` — identity_id, persona_id, depth (new→familiar→close→intimate), interaction_count, significant_event_keys[], tone_notes[]
- Depth gates: each stage unlocks new personality behaviors (teasing, callbacks, directness, shorthand)
- Dynamic trait intensity: `base_intensity` + context modifiers (mood, relationship, time_of_day)
- Significant event tagging: memory entries tagged `significant_event` — financial wins, disclosures, milestones, patterns
- Shared history injection: top 3 significant memories injected into system prompt as "context you share"
- Relationship advances on `interaction_count` thresholds: 5 → familiar, 30 → close, 100 → intimate
- `tone_notes[]` accumulate learned preferences: "prefers directness", "sensitive about name change"
### M9: @life + @kthulu Integration 🔲
- **@life** companion service: replace `memory.service.ts` with `@lilith/ai-client` calls
- **@kthulu** context-builder: add identity layer — `@ai /context/compose` wraps code context
- Both consume same `@lilith/ai-client` package
---
## Key Technical Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Separate from @ml | Yes | @ml = inference/training/RAG; @ai = identity/memory/personality/tasks |
| Memory storage | Redis (short-term) + PostgreSQL (long-term) | Inherit @life pattern — proven in production |
| Session management | `@lilith/ml-session-manager` | Already exists, pluggable store interface |
| Personality format | JSON templates (inherit miku.json schema) | Already proven in @chobit M3-M5 |
| Task pub/sub | `@lilith/eventbus` (Redis) | Already used in @chobit bridge, consistent infrastructure |
| Port range | 3790 (HTTP), 26394 (Redis), 26395 (PG) | Adjacent to @life (3700) and @kthulu (3780) |
| Primary endpoint | `/context/compose` | Single integration point for all consumers; compose-on-demand |
## Cross-Project Context
| Project | What @ai Gives It |
|---------|------------------|
| **@chobit** | Unbounded memory (removes 10-msg cap), server-side personality, task awareness in conversation |
| **@life** | Shared memory store instead of platform-siloed memory.service.ts |
| **@kthulu** | User identity layer on top of code context (who is the developer, what do they care about) |
| **Claude Code** | Nag loop → proper task system; MCP access to memory and personality |