opencode-config/docs/decisions/032-pr-75-rename-openai-env-chunking.md
Sergey 80a4be1d21
refactor(memory): rename to memory, OpenAI env, chunking, batching, dedup (#75)
* refactor(memory): rename package second-brain to memory

* refactor(memory): use OpenAI env naming and fix trailing slash

* feat(memory): add chunking with env-configurable size and overlap

* feat(memory): dedup search results by source in top-K

* test(memory): add chunking, batching, dedup, live tests

* docs(memory): update README and project map after rename

* docs(handoff): add handoff and ADR-032 for memory refactor

* docs(handoff): set PR number

* fix(ci): reduce index.py complexity to rank A

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-26 16:13:05 +03:00

23 lines
No EOL
4.2 KiB
Markdown
Raw 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.

# ADR-032: Rename to memory, OpenAI env, chunking, batching, dedup (PR #75)
## Статус
Accepted (2026-07-26)
## Контекст
Python-пакет `src/memory/` (RAG CLI для opencode-memory plugin) имел 7 проблем: нейминг-путаница (3 разных имени для одного пакета), нестандартный env-нейминг (`AI_PROVIDER_API_URL``AI_PROVIDER_BASE_URL` из `.env.example`/`opencode.json`), реальная 404-бага из-за trailing slash, грубый индекс (1 эмбеддинг на файл без чанков), отсутствие batching (риск упереться в OpenAI лимит input), отсутствие дедупа в search (засорение top-K одним файлом), захардкоженная модель эмбеддингов.
PR #1 в серии из 2 — этот PR чинит CLI, PR #2 интегрирует CLI в плагин через setup-memory.sh.
## Решение
1. **Нейминг**: `pyproject.toml` name=`second-brain``memory`, `[project.scripts] rag = "src.memory.cli:main"` (script entry point, совместимость с wrapper). `cli.py` `prog="rag"``prog="memory"`. Модуль `src/memory/` НЕ переименован (src-layout, `packages=["src"]`).
2. **Env-нейминг OpenAI-стандарт**: `OPENAI_BASE_URL`/`OPENAI_API_KEY` (вместо `AI_PROVIDER_API_URL`/`AI_PROVIDER_API_KEY`). `API_URL.rstrip("/")` фиксит trailing-slash. `EMBEDDING_MODEL` из env `OPENAI_EMBEDDING_MODEL` (default `gemini-embedding-2-preview`).
3. **Chunking**: `_chunk_text(text, size, overlap)` в `index.py`, параметры из env `MEMORY_CHUNK_SIZE` (512)/`MEMORY_CHUNK_OVERLAP` (64). `file_map` с `chunk_idx`/`offset`/`text`. Graceful при `size<=overlap` (1 chunk, не infinite loop).
4. **Batching**: `BATCH_SIZE = int(os.environ.get("OPENAI_EMBEDDING_BATCH_SIZE", "2048"))` в `embedder.py`. `embed_texts` режет texts > BATCH_SIZE, конкатенирует результаты. Default 2048 = OpenAI лимит для text-embedding-3-small.
5. **Дедуп**: `search.py` после sort по score итерирует с `seen` set, оставляет highest score per source, останавливается на K уникальных source'ов.
6. **Тесты**: `test_chunking.py` (7 edge cases), `test_embedder_live.py` (2 live, skip без RUN_LIVE), + 4 embedder теста (default/custom model, trailing slash, batches), + 3 index теста (long file, env override, .rag skip), + 1 search тест (dedup).
## Альтернативы
- **Полный rename `src/memory/``src/rag/`** — отклонено: src-layout `packages=["src"]` в pyproject, rename модуля требует обновления всех imports (cli, embedder, index, search, tests, __main__). Script entry point `rag = "src.memory.cli:main"` даёт исполняемый `rag` без rename модуля. Module name `memory` (что package делает) + script name `rag` (как пользователь вызывает) — разумное разделение.
- **Читать `OPENAI_BASE_URL`/`EMBEDDING_MODEL`/`BATCH_SIZE` в `embed_texts` каждый вызов** (вместо module-level) — отклонено: лишний overhead на каждый вызов (env lookup + int parse), несовместимость с существующим `API_URL` module-level паттерном. Module-level + `importlib.reload` в тестах — trade-off: простой код, хрупкие reload-тесты.
- **Дропать empty files из индекса** (вместо 1 записи с пустым чанком) — отклонено: меняет существующее поведение (раньше empty files попадали в индекс с 1 embedding). Empty embedding даёт score 0, файл остаётся в index для completeness.
- **Параметризовать `_chunk_text` через argparse вместо env** — отклонено: env-параметры позволяют настраивать без правки CLI invocation, совместимо с setup-memory.sh wrapper (env передаётся через process env, не флаги).