Files
goclaw/migrations/000045_episodic_recall_tracking.up.sql
viettranx 4cf66eb379 feat(ts-port): reasoning strip, dreaming config + weighted scoring
Phase 6 — Reasoning token stripping:
- ReasoningDecision.StripThinking auto-flags Kimi + DeepSeek-Reasoner
- Guard clauses in Anthropic/OpenAI/Codex stream handlers
- Usage.ThinkingTokens + RawAssistantContent preserved (billing + tool passback safe)

Phase 8 — Per-agent dreaming config:
- MemoryConfig.Dreaming JSONB (no migration), resolver callback pattern
- Enabled/DebounceMs/Threshold/VerboseLog fields with partial-override merge
- ConsolidationDeps gains optional AgentStore

Phase 10 — Dreaming weighted scoring:
- Migration 000045 adds recall_count/recall_score/last_recalled_at on episodic_summaries
- ComputeRecallScore 4-component formula (freq/rel/recency/freshness, 14d half-life)
- memory_search fire-and-forget RecordRecall; ListUnpromotedScored in DreamingWorker
- Bootstrap-friendly filter: unrecalled entries bypass thresholds
- Debounce stamped on filter-empty skip to prevent starvation loop

Phase 5 follow-up — last_compaction_at in sessions.metadata JSONB:
- v3 PruneStage.CompactMessages and v2 maybeSummarize both stamp timestamp
- Zero migration; exported const SessionMetaKeyLastCompactionAt

RequiredSchemaVersion: 44 → 45 (PG), SchemaVersion: 12 → 13 (SQLite).
27 new tests; builds pass under PG and sqliteonly tags.
2026-04-10 13:32:02 +07:00

16 lines
972 B
SQL

-- Phase 10: dreaming weighted scoring. Track per-episode recall signals
-- that feed ComputeRecallScore() in internal/consolidation/scoring.go.
-- recall_score stores the running-average of search hit scores so the
-- dreaming worker can sort unpromoted entries by perceived usefulness
-- instead of strictly oldest-first.
ALTER TABLE episodic_summaries ADD COLUMN IF NOT EXISTS recall_count INT DEFAULT 0 NOT NULL;
ALTER TABLE episodic_summaries ADD COLUMN IF NOT EXISTS recall_score DOUBLE PRECISION DEFAULT 0 NOT NULL;
ALTER TABLE episodic_summaries ADD COLUMN IF NOT EXISTS last_recalled_at TIMESTAMPTZ;
-- Partial index for DreamingWorker.ListUnpromotedScored — only touches
-- unpromoted rows and orders by recall_score DESC to match the primary
-- query shape: "top-N unpromoted with highest recall signal".
CREATE INDEX IF NOT EXISTS idx_episodic_recall_unpromoted
ON episodic_summaries(agent_id, user_id, recall_score DESC)
WHERE promoted_at IS NULL;