feat(cli+api+mcp): agent walk-aware CLI + council doc fixes + 5 AI-user friction fixes#82
Merged
Conversation
Council review flagged the v1 CLI as operator-only and the docs as having a stale endpoint table + unsourced headline benchmark. This commit closes both gaps: - **CLI agent surface**: add `helix packet`, `helix gene get|preview`, `helix neighbors`, `helix refresh-targets`. Agents can now drive full retrieval+walk loops via subprocess calls without an MCP host or running HTTP server. JSON shapes match the matching HTTP endpoints + MCP tools so callers swap surfaces without changing logic. - **api.py**: promote `gene_get` / `packet` / `refresh_targets` / `neighbors` from v1.1-deferred to v1 on `HelixSession`. Pure in-process wrappers over `Genome.get_gene`, `build_context_packet`, and the existing SEMA codec. Read-only. - **README**: new "Agent CLI surface (no server required)" section; headline `28.7× / 5.4×` claim now cites `benchmarks/bench_rag_vs_sike_tokens.py` (reproducer) and `docs/benchmarks/BENCHMARKS.md` (methodology). - **ROSETTA**: new "Response & routing types (STAYS)" section covering `ContextWindow` / `ContextPacket` / `KnowBlock` / `MissBlock` / `RefreshTarget` / `ContextHealth` / `ContextItem` / `QueryResult` / `IngestResult` / `StatsResult`. Annotate the `HGT → cross_store_import` row as forward-pointer (no code under either name today). Annotate `OPEN/EUCHROMATIN/HETEROCHROMATIN → OPEN/WARM/COLD` as deferred-to-R3 since `ChromatinState` in `schemas.py` still emits bio names. - **cli.md**: title-page "agent vs. operator" decision table + per- subcommand reference for the four new commands. Tests: 28 new (10 api_walk + 18 cli_*); full mock suite stays green (1914 passed, 0 failures). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reported against origin/master@93deaf2. Each fix has a focused unit
test; full mock suite stays green (1924 passed, 0 failures).
1. **api.py: open_session() now honors HELIX_CONFIG / HELIX_GENOME_PATH.**
Pre-fix every cold-start CLI subcommand (query, diag corpus, packet,
gene, neighbors, refresh-targets) instantiated HelixConfig() directly
and silently created/read ./genome.db regardless of the operator's
config — so `helix status` looked at the configured genome but
`helix query` looked at an empty one. Route through load_config() so
HELIX_CONFIG + HELIX_GENOME_PATH work the same way as `helix status`
already honors them.
2. **helix_status.py: bump /health probe timeout 1.5s → 10s, override via
HELIX_STATUS_TIMEOUT_S.** Cold-start /health can take 5-10s under
model warmup + manager init + WAL replay; the old 1.5s timeout
silently reported a healthy-but-slow server as unreachable in
`helix status --json`. New default + env-var override + malformed-
value fallback warning.
3. **mcp_server.py: unwrap the Continue list shape in helix_context /
helix_document_query tools.** /context returns the Continue HTTP
context-provider list ([{name, description, content, ...}]) to stay
drop-in compatible with Continue IDE. MCP hosts validate tool returns
against the declared Dict[str, Any] schema and rejected the list.
New _unwrap_context_list helper flattens the single-entry list,
passes _http error envelopes through, defensively wraps unexpected
list shapes with a diagnostic note.
4. **config.py: auto-fallback ingestion.backend → "cpu" when
ribosome.enabled = false.** The two settings contradicted each other
— ingest with the ribosome disabled raised TranscriptionError: Pack
failed: Ribosome is disabled on the first chunk. The CpuTagger
(spaCy + heuristic) was always available but never reached because
ingestion.backend defaulted to "ollama". load_config() now flips
ingestion to the CPU path and logs a WARNING. Honors explicit cpu /
hybrid settings without override. Keeps the LLM-free pillar
intact and finally makes cold-start `helix ingest` actually work
on a fresh install.
5. **cli/__main__.py + cli.md: `python -m helix_context.cli` works as a
console-script fallback.** When the pip-installed `helix.exe` points
at a deleted editable-install path or the Scripts dir is off PATH
(common AI-user environment issue), agents now have a module-direct
invocation that bypasses the console script entirely. Documented
alongside the `pip install --force-reinstall --no-deps` recipe.
Tests: 10 new unit tests (1 api_walk + 3 config + 6 mcp_server).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two commits, two slices of work, both surfaced by AI-user testing of the CLI+MCP surface:
9dbd960— Council prioritized doc fixes + agent walk-aware CLI. Closes the gap the first council flagged on the v1 CLI (PR feat(cli): v1 cold-start helix-cli (query/ingest/status/diag/config) #71): agents now drive genome lookups via subprocess CLI calls instead of MCP-injected context. Plus the README / ROSETTA / docs fixes the council prioritized.0a68896— Five friction points reported by a second AI-user pass on origin/master@93deaf2. Each is a one-shot fix with a focused unit test.Branch is two commits ahead of
origin/master. Full mock suite green (1924 passed, 0 failures, ~8min).Commit 1 — Agent walk-aware CLI + council doc fixes
CLI agent surface (4 new subcommands; identical JSON shape to the matching MCP tools + HTTP endpoints):
helix packet <text> --task-type edit|ops|...— agent-safe bundle withverified/stale_risk/refresh_targetshelix gene get <id>/helix gene preview <id> --chars N— single-document inspectionhelix neighbors <text> --k N— SEMA graph walkhelix refresh-targets <text>— reread plan onlyapi.HelixSession: promotegene_get,packet,refresh_targets,neighborsfrom v1.1-deferred to v1 — they back the four new CLI subcommands without requiring an HTTP server or MCP host. Pure in-process wrappers overGenome.get_gene,build_context_packet, and the existing SEMA codec. Read-only.Docs: README adds an "Agent CLI surface (no server required)" section and sources the
28.7× / 5.4×headline against the reproducer atbenchmarks/bench_rag_vs_sike_tokens.py. ROSETTA adds a "Response & routing types (STAYS — no biology twin)" section coveringContextWindow/ContextPacket/KnowBlock/MissBlock/RefreshTarget/ContextHealth/ContextItem/QueryResult/IngestResult/StatsResult. TheHGT → cross_store_importrow is annotated as a forward-pointer; theOPEN/EUCHROMATIN/HETEROCHROMATIN → OPEN/WARM/COLDrow notes the rename is deferred to R3.Commit 2 — Five AI-user friction fixes
helix queryandhelix diag corpussilently ignoredHELIX_CONFIG/HELIX_GENOME_PATH— read/created./genome.dbwhilehelix statuslooked at the configured genomeapi.py: open_session()now routes throughload_config()(single-source withhelix status)helix status --jsonfalsely reported a healthy-but-slow server asunreachable(1.5s timeout, cold-start/healthtakes 5-10s)helix_status.py: default 1.5s → 10s, override viaHELIX_STATUS_TIMEOUT_S, malformed-value fallback warns instead of crasheshelix_contextfailed schema validation —/contextreturns the Continue HTTP list shape, MCP host expectedDict[str, Any]_unwrap_context_list()helper unwraps the single-entry list; applied tohelix_contextandhelix_document_query. Continue IDE compatibility untouched.helix ingest README.mdraisedTranscriptionError: Pack failed: Ribosome is disabledon cold-start installconfig.py: load_config()auto-flipsingestion.backend→"cpu"when ribosome is disabled. Routes to the spaCy/heuristic CpuTagger that's already in tree. Explicit cpu/hybrid configs untouched. LLM-free pillar intact. Logs WARNING.helix.exebroken (pip console script pointed at deleted editable path; Scripts dir off PATH)helix_context/cli/__main__.pysopython -m helix_context.cliworks as a fallback. Recovery recipe +pip install --force-reinstall --no-depsdocumented indocs/clients/cli.md.Test plan
python -m pytest -m "not live and not requires_rocm and not requires_real_cuda and not requires_mps"→ 1924 passed, 0 failures, 10 skipped, 26 deselected, 2 xfailed in 470s.helix packet "foo" --json,helix gene get <id> --json,helix refresh-targets "edit X"— not done here; reviewer should sanity-check on their workstation before merge.helix_contextreturning a dict (not a list) after the unwrap fix.Related issues
This PR does not close any open issue outright. Two issues partially overlap and should be reconciled at merge time:
packet,gene get/preview,neighbors,refresh-targets), but under different command names than MCP slimdown — Move 2: CLI parity for 13 deprecation candidates #80 specifies (top-levelhelix packetetc. vs. spec'shelix diag packet/helix diag refresh-plan). The remaining 9 candidates are not addressed here. See "Note on the MCP slimdown plan" below.Note on the MCP slimdown plan (#78 / #79 / #80 / #81)
Building the four CLI peers in this PR was originally framed under the council's recommendation to "complete the CLI as an agent tool." The earlier round of analysis on PR #78 (MCP slimdown spec) found that:
Recommendation kept from that analysis: don't merge #78 as written. What stays valuable from the slimdown work:
helix_document_*) — they're redundant after R2 and shipping is no-cost.🤖 Generated with Claude Code