code_index — AgentTeamsModule¶
Build and query a vector-space retrieval index over repository scripts and the
external APIs they use — the code-retrieval sibling of memory_index.
Where memory_index covers durable prose (work summaries, CHANGELOG, plans),
code_index covers code: the repository's own scripts (source_kind =
local-script), the external API modules those scripts import (api-module), and
the documentation for those APIs (api-doc) — the two api-* kinds collected
statically by code_sources. Every indexed document carries a
source_kind label, so a query can be filtered to one kind with --code-kind.
Source:
agentteams/code_index.py
Design Principles¶
- Gitignored local cache, never committed. The index lives under
references/code-index/as amanifest.jsonplus per-kind partition files (local.json,api-modules.json,api-docs.json). It is a rebuildable cache — not committed, not drift-tracked, and never staged by a git hook. Theapi-*partitions embed machine-specific resolved paths and installed versions, so committing them would leak per-developer state; keeping the cache local sidesteps that entirely. - Stdlib-only sparse TF·IDF vector space. The default representation is a
sparse tf·idf vector-space model (BM25 lexical + cosine vector strategies) —
the same class
memory_indexuses. No dense embeddings, no FAISS/chroma, no heavy dependencies.vector_model_id/vector_dimare reserved (null) for an optional future dense tier. - Own copy of the scorers, parity-tested. The BM25/cosine math is a
deliberate, behaviour-identical copy of
memory_index's scorers (the shipped, grid-tuned module is left untouched);tests/test_code_index.py::test_scoring_parity_*proves the copy cannot silently drift. - Code-aware tokenizer. Unlike the prose tokenizer, it keeps short
identifiers (
os,re,id), keeps dotted import paths whole and split, and splitssnake_case/camelCaseso a query forbatchUpdatematchesbatch_update. - Never executes third-party code. API modules/docs are read via static
astparsing andimportlib.metadataonly — neverimport, neverfind_spec. Correctness (deps may be uninstallable/side-effecting) and security (RAG/vector poisoning; treat retrieved API docstrings as data, not instructions). - Robust to absence — an empty source set yields an empty-but-schema-valid
partition; a missing/stale/malformed cache never blocks a query
(
fallback_policy = non-blocking-file-read-then-search): open the referenced file, then fall back to filesystem search. - Deterministic, atomic — documents are sorted by
(source_kind, path, symbol); a no-op rebuild is content-fingerprinted and skipped so the on-disk partition stays stable; writes are atomic (*.tmp+os.replace).
CLI¶
# Rebuild the gitignored cache (references/code-index/)
agentteams --refresh-code-index --description brief.json # or --self
# Query it (auto-refreshes a stale local partition first)
agentteams --query-code "where is the retry backoff" --description brief.json
agentteams --query-code "http client session" --code-kind api # API modules only
agentteams --query-code "authentication flow" --code-query-strategy vector --code-query-k 8
--code-kind {local,api,doc,all}— filter bysource_kind(defaultall).--code-query-strategy {lexical,vector}—lexicalBM25 (default, best for identifiers) orvectorcosine.
See the CLI reference for the complete code-index flag surface.
The /code-recall skill wraps --query-code for in-session retrieval and is the
code sibling of the /recall (memory-index) skill.
Auto-update triggers¶
- Query-time staleness (primary).
--query-coderebuilds a stale partition before answering. Thelocalpartition is stale when any source file's hash/mtime changed; theapi-*partitions are stale when the dependency fingerprint (dependency-manifest contents + external import-name set + dist→version map) changed — because API source lives in site-packages and a local mtime cannot witness a dependency upgrade. --updatekeeps an existing cache fresh (never imposes the build cost on a project that never queried it).- Optional pre-commit warm-up (
--install-git-hooks --code-index-hook, off by default) pre-warms the gitignored cache on commit without staging it.
Domain boundary¶
code_index (code + API) is a distinct retrieval surface from memory_index
(durable prose) and from any project-level relational retrieval-integrator
contract — the three address different questions and must not be conflated.
Public API¶
__all__ also exports these constants:
CODE_INDEX_SCHEMA_VERSION("1.0")INDEX_FORMAT_VERSION("json-code-bm25-v1")INDEX_WRITE_OWNER("agentteams.code_index")VECTOR_RUNTIME_MODE("sparse-tfidf-cosine")FALLBACK_POLICY("non-blocking-file-read-then-search")MANIFEST_ARTIFACT_TYPE("code-index-manifest")PARTITION_ARTIFACT_TYPE("code-index-partition")SOURCE_KINDS(("local-script", "api-module", "api-doc"))
Functions:
build_code_partition(units, *, source_kind, project_name="", framework="", dependency_fingerprint=None) -> dictlocal_units(paths) -> list[dict]query_partition(partition, query, *, k=5, strategy="lexical") -> list[dict]query_partitions(partitions, query, *, k=5, strategy="lexical", kind="all") -> list[dict]is_partition_stale(partition, sources=None, *, dependency_fingerprint=None) -> booldependency_fingerprint(manifest_texts, import_names, dist_versions) -> strpartition_content_fingerprint(partition) -> strbuild_manifest(partition_meta, *, ...) -> dictatomic_write_json(path, obj) -> None
See agentteams/schemas/code-index.schema.json for the artifact contract and
references/plans/code-api-vector-index.plan.md for the audited design (v3).
Query result shape¶
query_partition()/query_partitions() each hit dict contains: doc_id, path, title,
source_kind (local-script / api-module / api-doc), language, symbol, signature,
provenance, score (rounded to 6 decimal places), confidence, snippet, snippets.
confidence is "reliable" / "candidate" / "weak", computed from score against the same
per-strategy thresholds as memory_index's query_index() — lexical: ≥3.0
reliable, 1.0–3.0 candidate; vector: ≥0.30 reliable, 0.20–0.30 candidate.
This module keeps its own copy of the threshold logic (not an import from memory_index) per the
module's existing R2-M3 no-import invariant; tests/test_code_index.py's scoring-parity tests
assert confidence stays in lockstep with memory_index's copy, not just score.