mirror of
https://github.com/Tencent/teamai-cli.git
synced 2026-10-02 03:14:40 +08:00
* fix(votes): keep votes with the scope they were cast in (#787) Every scope recorded into one ~/.teamai/votes/<user>.yaml, so a vote cast in one project (recall feedback, a recall search, a Stop whose push failed) was pushed to the team of whichever scope synced next: the leak usage.jsonl had before #758. Votes now live in the data home of the scope that resolves for the session: <dataHome>/votes/ for a project, ~/.teamai/user-votes/ for the user scope. The Stop hook uses the config the dispatcher resolved; the pull report, recall search, `recall feedback` and the vote view read only that scope's votes, and the CLI readers resolve it with resolveConfigForDir, so an unreadable project config falls back to no other scope: `recall feedback` exits 1 and the vote view names the broken file. The shared ~/.teamai/votes/ is never read. Its V2 `votes` map is the last merged remote snapshot of whichever team synced, not this scope's history, and seeding a scope from it would let `recall feedback --negative` push a decrement and merged timestamps derived from another team. The remote votes/<user>.yaml format is unchanged. * fix(votes): address pre-review findings (#787) - recall search: in a project whose config cannot be read, detection falls back to another scope; record no recalled count there, so the vote cannot reach that scope's team. Which scope the search itself uses stays #796's. - recall feedback: with no project config and an empty or invalid user config, name the file and the fix (requireInit's error) instead of "not set up here". - CHANGELOG: note the recall search case; the shared directory is never read or pushed "by this release" (an earlier release still pushes it). - Design doc: getUserVotesDir() is the exception to "getters unchanged". * fix(votes): address second pre-review round (#787) - recall feedback: name an unusable user config through throwMissingOrInvalid (now exported) instead of re-running requireInit, which loaded the config twice and printed its parse error twice. - recall search: a project detection that throws is treated like an unreadable config, so no recalled count lands in the fallback scope. - The recall-search test now asserts the search ran and that neither the shared directory nor the broken project's votes/ was written; it fails on origin/main too. - Design doc: re-wrap the edited paragraph. * fix(votes): record recall votes from a deleted cwd in the user scope (#787) The previous commit treated any throw from recall's project detection as an unreadable project, including a cwd that no longer exists. Such a cwd holds no project and resolves to the user scope everywhere else (resolveConfigForDir, detectTeam), so its recalled counts belong there. Tests pin that case and the single parse-error line for an invalid user config in recall feedback. * fix(votes): address CI review findings (#787) - getVotesDir: a historical project-scoped ~/.teamai/config.yaml with no projectRoot (schema-valid, not backfilled) made getDataHome throw, so recall, feedback and the Stop hook recorded no vote. It lives in ~/.teamai, as recall and viz already treat it, so its votes go to the user scope's user-votes/. - git-native-memory design doc: the local votes path is user-votes/. * fix(votes): address CI review (#787) - recall feedback --negative counts the upvotes the scope's own team already holds (its reports checkout's votes/<user>.yaml plus the deltas not yet pushed). A scope's file starts empty on upgrade, so a doc upvoted before it was rejected as not found, or as having no upvotes once a later recall counted it. The shared ~/.teamai/votes and other scopes' teams are never read. - The adoption judge (#723, merged meanwhile) recorded into and synced from the user scope's votes in every scope, which pushed the user scope's pending votes to the project's team. It uses the scope's votes like the Stop handler. - votes-scope tests: Stop transcripts prove adoption with a Read of the recalled file (#723), and the update.js mock keeps the real lock.
5.7 KiB
5.7 KiB
Git-Native Memory System (Hindsight-Inspired)
Generated by /plan-ceo-review on 2026-03-28 Branch: master | Mode: SELECTIVE EXPANSION Repo: teamai/teamai-cli Reference: vectorize-io/hindsight — Agent Memory Framework
Overview
借鉴 Hindsight 的 retain/recall/reflect 三层记忆模型,用 Git + 本地搜索索引实现团队知识的自动回忆。补全 session contribute(写入路径)缺失的"读出路径",让 AI 在工作时自动"想起"别人的经验。
Vision
把 teamai 从"文件同步工具"升级为"团队记忆系统"。知识飞轮:
写入 → 索引 → 搜索 → 投票 → 排序 → 更好的搜索
Architecture
┌─────────────────────────────────┐
│ TEAM GIT REPO │
│ learnings/ │
│ ├── k8s-oom-排查-2026-03-15.md │
│ └── api-timeout-修复-2026-03-20.md │
│ votes/ │
│ ├── jeff.yaml │
│ └── alice.yaml │
└──────────┬────────────────────────┘
│
┌──────────┴──────────┐
│ │
teamai pull teamai contribute
+ index rebuild (existing, enhanced)
│ │
▼ │
┌───────────────────────────┐ │
│ ~/.teamai/ │ │
│ learnings/ (local copy)│◀────────┘
│ search-index.json │
│ user-votes/<user>.yaml │
└──────────┬───────────────┘
│
teamai recall "api timeout"
│
▼
Ranked results → recalled_count++
│
(adoption evidence: agent opens the doc, or
opt-in LLM-judge) → upvoted_count++
Hindsight Mapping
| Hindsight Concept | TeamAI Implementation | Status |
|---|---|---|
| Retain (store) | teamai contribute → learnings/ in git + frontmatter |
✅ Done (enhanced) |
| Recall (retrieve) | teamai recall <query> → local search index (BM25 + Intl.Segmenter) |
🔨 This plan |
| Reflect (learn) | teamai reflect → LLM analyzes learnings → meta-insights |
⏳ Deferred |
| Memory Bank isolation | Per-user directories in git repo | ✅ Existing |
| Ranking/relevance | Recall bumps recalled_count; adoption evidence (agent opened the doc, or the opt-in LLM-judge) bumps upvoted_count → votes/.yaml → aggregate at pull (#723) |
🔨 This plan |
Key Design Decisions
| # | Decision | Choice | Rationale |
|---|---|---|---|
| 1 | Storage backend | Git repo (no PostgreSQL/vector DB) | Zero external dependencies, matches teamai philosophy |
| 2 | Search method | Keyword matching + Intl.Segmenter | Handles CJK text, no embedding cost, sufficient for V1 |
| 3 | Index location | Local-only search-index.json | Rebuilt at pull time, no sync conflicts |
| 4 | Vote mechanism | Per-user YAML; recall bumps recalled_count, adoption evidence (tool-use / opt-in LLM-judge) bumps upvoted_count (#723) |
Idempotent, zero Git conflict, knowledge self-curates |
| 5 | Frontmatter | Required in SKILL.md template | Structured metadata improves search precision |
| 6 | AI integration | Rule injection → AI calls recall via Bash | Works across all AI tools, no tool-specific integration |
Implementation Phases
Phase 1: Foundation (pull sync + index)
src/types.ts— LearningDoc, SearchIndex typessrc/utils/search-index.ts— buildIndex(), loadIndex(), search() with Intl.Segmentersrc/pull.ts— syncLearnings() step + index rebuildskill-data/share/SKILL.md— frontmatter 标准化(由teamai skill get share提供,不再部署到各 agent)- Tests: index build, search, CJK, edge cases
Phase 2: Recall + Voting
src/recall.ts— teamai recall CLI command + autoUpvote()src/index.ts— register recall commandrules/teamai-recall.md— Rule synced to AI tools- Tests: recall CLI, upvote idempotency, vote push
Phase 3: Integration
- Wire votes into search ranking (pull-time aggregation)
- Full integration test
Scope Decisions
| # | Proposal | Effort | Decision | Reasoning |
|---|---|---|---|---|
| 1 | Auto-Recall on SessionStart | M | SUPERSEDED | 已被 teamai-recall subagent + builtin-rules 主动检索替代 |
| 2 | 投票机制:recalled_count + 采纳 upvote | S | ACCEPTED | Recall 累加 recalled_count;采纳证据(工具使用 / 可选 LLM-judge)累加 upvoted_count(#723)。零冲突,飞轮反馈机制的关键一环 |
| 3 | Frontmatter 标准化 | S | ACCEPTED | 提升搜索质量,向后兼容 |
| 4 | Reflect 层 | L | DEFERRED | 知识库冷启动阶段,数据不足 |
Deferred to TODOS.md
Auto-Recall on SessionStart (P2)— 已被teamai-recallsubagent + builtin-rules 主动检索替代(#106)- Reflect 层 (P3) — LLM 分析 learnings 生成 meta-insights,需知识库积累到 20+ 篇