Skip to content

feat(ai-echo): AI echo system — pgvector retrieval, personas, memories, generic engine#2735

Open
Innei wants to merge 8 commits into
masterfrom
feat/ai-echo-system
Open

feat(ai-echo): AI echo system — pgvector retrieval, personas, memories, generic engine#2735
Innei wants to merge 8 commits into
masterfrom
feat/ai-echo-system

Conversation

@Innei
Copy link
Copy Markdown
Member

@Innei Innei commented May 23, 2026

Summary

Adds a generic AI echo engine and three supporting modules, anchored on the recently (wishing-well / 树洞) module: every new recently entry receives AI-written replies voiced by configurable personas. The engine is scenario-pluggable so future scenarios (comment auto-reply, reader companion) plug in without touching the engine.

Four new modules under apps/core/src/modules/ai/:

  • ai-embeddings — pgvector corpus over post / note / page; chunker (paragraph-aware, deterministic, hash-diffed); EMBED_SYNC task + event listeners; admin backfill + stats; retrieval API returns similarity = 1 - cosine_distance.
  • ai-personaPERSONA_REGISTRY const with inner-self (dynamic, distilled) + passerby (static); persona_profiles table; single-pass LLM distillation with Redis lock; length-window + recency-weighted exemplar selection.
  • ai-memory — human-authored canonical-facts CRUD; recall supports salience-only (no query) and vector-ranked (with query, re-ranked by similarity × salience × confidence); KPI.
  • ai-echo — generic EchoScenario abstraction + ai_echoes table; ECHO_GENERATE task with status-guarded idempotent replay; daily quota; admin regenerate/edit/delete/list + public list. Ships one scenario: recently (triggers on RECENTLY_CREATE, cascades on RECENTLY_DELETE).

Shared foundation:

  • pgvector extension + vector custom Drizzle column type
  • 4 new tables, all migrated in 0015_ai_echo_system.sql (additive only; expand-contract safe)
  • AIFeatureKey.Echo / Embedding / PersonaDistill + matching AISchema config slots + AiService resolvers
  • 5 AITaskType entries with dedup keys
  • 18 new AppErrorCode entries with payload + definition mappings
  • 2 new BusinessEvents (RECENTLY_ECHO_LANDED, PERSONA_PROFILE_REFRESHED)

Specs

  • Root: docs/superpowers/specs/2026-05-23-ai-echo-system-root.md
  • Engine: docs/superpowers/specs/2026-05-23-ai-echo-engine-design.md
  • Embeddings: docs/superpowers/specs/2026-05-23-ai-embeddings-design.md
  • Persona: docs/superpowers/specs/2026-05-23-ai-persona-design.md
  • Memory: docs/superpowers/specs/2026-05-23-ai-memory-design.md

Implementation deviations (all reality adaptations)

  • EchoScenarioRegistry service replaces the spec's ECHO_SCENARIO multi-provider injection token — NestJS doesn't natively support multi: true (Angular concept); consumer modules self-register via OnModuleInit. Functionally equivalent.
  • AiService is locally provided in AiPersonaModule / AiMemoryModule to avoid circular import; stateless (only resolves config). Worth consolidating later.
  • The initial corpus backfill app-migration is a log-only marker — the slim migration runner has no Nest DI, so the admin runs POST /ai-embeddings/backfill after configuring an embedding model. Spec §12 already allows this fallback.
  • Test pg image switched to pgvector/pgvector:pg17 (one-line tag swap in pg-testcontainer.ts).

Test plan

  • pnpm exec eslint --fix — clean across all modified files
  • pnpm -C apps/core run lint:migrations — ok (16 files scanned)
  • npx vitest run --no-file-parallelism test/src/modules/ai/{ai-embeddings,ai-persona,ai-memory,ai-echo}110/110 passing (15 spec files)
  • Acceptance criteria from root spec §7 verified by integration tests:
    • Recently create → 2 echoes reach status='ready'; RECENTLY_ECHO_LANDED fires twice
    • Public GET /ai-echo/by-subject/recently/:id filters to ready + edited
    • Admin edit/delete/regenerate (force=true archives old)
    • Persona refresh: single-pass distill writes row; concurrent → 409
    • Embedding sync produces correct rows; unchanged source → no-op (hash diff)
    • Memory recall integrates into echo prompts; reflected in ai_echoes.metadata.memoryIds
    • Embedding model unconfigured → sync/retrieval graceful no-op; echoes still generate (without retrieval section)

Known infra debt (pre-existing, not introduced here)

Full-suite test runs have occasional flakes due to dbHelper.clear() (in test/helper/db-mock.helper.ts) issuing blanket TRUNCATE across parallel vitest worker processes that share the same pg-testcontainer. The new specs pass deterministically when run in isolation. A future cleanup should either scope dbHelper.clear() to per-spec tables or set poolOptions.forks.singleFork: true.

Follow-ups (deferred to v2 per spec)

  • Echo: rating endpoint, comment-reply + reader-companion scenarios, streaming via ai-inflight
  • Embeddings: recently embedding, reindex endpoint, HNSW/IVFFLAT migration when row count crosses threshold
  • Persona: map-reduce distill, auto-refresh (cron + threshold), vector-by-query exemplar selection
  • Memory: /from-passage LLM draft, MEMORY_EXTRACT + forced review, MEMORY_DECAY, supersede detection, KPI nudge widget

Innei added 7 commits May 23, 2026 19:46
…migrations)

Adds pgvector custom Drizzle type, four new tables (corpus_embeddings,
persona_profiles, ai_memories, ai_echoes), three AIFeatureKey entries
(Echo, Embedding, PersonaDistill) with matching AISchema config keys
and AiService resolvers, five new AITaskType entries with dedup keys,
two new BusinessEvents (RECENTLY_ECHO_LANDED, PERSONA_PROFILE_REFRESHED),
new AppErrorCode entries with payload + definition mappings, stub
modules registered in AiModule, deterministic test mocks for embedding
and chat runtimes.
Implements the human-authored canonical-facts layer for ai-echo: CRUD
endpoints, salience-only + vector-based recall, async embed-on-write
task, KPI counts. All v2 fields (confidence, salience, supersession,
expiry) accepted on input and surfaced in detail view but unused by MVP
logic. Recall gracefully no-ops when no embedding model is configured.
Add the ai-echo engine module (repository, service, controller, prompt
builder, scenario registry, ECHO_GENERATE task processor) plus the recently
scenario provider that registers via OnModuleInit. Engine is generic over
EchoScenario; recently is the first concrete consumer.

- Status state machine enforced via step-2 guard in the processor (replay-safe)
- Daily quota enforced via Redis INCR; over-limit rows persisted as failed
- Subject-delete cascade: in-flight rows -> failed/aborted, ready/edited -> archived
- Public read endpoint filters to ready/edited; admin manages full row
- 23 unit + integration tests cover prompt builder, scenario registry, quota,
  status guard, regenerate force, edit, runtime failures, replay, hypothetical
  extra scenario
@safedep
Copy link
Copy Markdown

safedep Bot commented May 23, 2026

SafeDep Report Summary

Green Malicious Packages Badge Green Vulnerable Packages Badge Green Risky License Badge

No dependency changes detected. Nothing to scan.

View complete scan results →

This report is generated by SafeDep Github App

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant