Skip to content

feat: OpenCode Go as the first chat provider - #377

Merged
yw0nam merged 4 commits into
mainfrom
feat/opencode-provider
Oct 19, 2026
Merged

yw0nam merged 4 commits into
mainfrom
feat/opencode-provider

Conversation

@yw0nam

@yw0nam yw0nam commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

OpenCode Go is the first chat provider. The chat model is called in one place: the CSV branch, which summarizes a sampled table into one card.

  • Selection order: opencode → zai → openai → claude → vllm; the first non-empty API key wins.
  • OPENCODE_API_KEY selects it; OPENCODE_MODEL names the model (default deepseek-v4.1-flash). The endpoint is fixed: https://opencode.ai/inference/go/openai/v1.
  • The opencode client sends User-Agent: memory-base/<version> and a new x-opencode-session per chat_json call, as the OpenCode Go request policy asks. Other providers send neither.
  • No thinking parameter is sent to opencode: glm-5.3-flash on Go refuses thinking: disabled; sending nothing works for both measured models. z.ai keeps thinking: disabled.
  • zai_provider(env) builds the z.ai provider from its own keys; the LongMemEval extractor and answer model use it, so they keep working when OPENCODE_API_KEY is also set.
  • Provider specs are a named tuple (_KeyedSpec) instead of positional tuples.
  • Wiring and docs: docker-compose.yml, .env.example, docs/configuration.md, README, AGENTS.md, docs/benchmarks/longmemeval.md.

Related issues

Closes #376

Deploy runbook

No schema change. OPENCODE_API_KEY is already in .env.

cd <main checkout>
git fetch origin
git checkout --detach origin/feat/opencode-provider
docker compose up -d --build api mcp

Runtime evidence (required for ingest / retrieval / serving behavior)

Branch deploy verified: the CSV branch summarized a 3-row CSV through OpenCode Go (chat model: opencode / deepseek-v4.1-flash, job succeeded, 0 retries); details in the evidence comment.

Verification

  • uv run pytest passes — unit: 1670 passed, 1 skipped.
  • uv run ruff format --check . and uv run ruff check . pass
  • docker compose build mcp passes — branch deploy built api and mcp
  • Runtime evidence attached above

Checklist (core principles)

  • Selective storage — notes stay distilled; verbatim text lives only in doc_rows and the turns lane
  • Source-specific logic stays out of the source-agnostic core (ingest pipeline, retrieval, serving)
  • No hardcoded endpoints/models — configuration lives in .env (the OpenCode Go endpoint is the vendor's fixed URL, like the z.ai default)
  • New/changed behavior ships a test in this PR (tests/core/test_llm_provider.py, LongMemEval builder tests, compose wiring)

@yw0nam

yw0nam commented Oct 19, 2026

Copy link
Copy Markdown
Owner Author

Runtime evidence — branch deploy

Deployed b62e130 (origin/feat/opencode-provider) with docker compose up -d --build api mcp at 2026-10-19 16:54 KST. OPENCODE_API_KEY and ZAI_API_KEY are both set in .env; OPENCODE_MODEL is unset.

Provider resolved inside the api container

opencode deepseek-v4.1-flash https://opencode.ai/inference/go/openai/v1
{'User-Agent': 'memory-base/0.5.0', 'x-opencode-session': '7348485debf845118931d43ce6402525'}

CSV upload through the CSV branch (POST /ingest/document, 3-row CSV, document_id=probe-opencode-376)

{"job_id":"6b1526ef06ae44149a9c8ce87d9f8178","status":"succeeded","error":null,"created_at":"2026-10-19T07:55:41.270875+00:00","updated_at":"2026-10-19T07:55:46.286205+00:00","document_id":"probe-opencode-376","stage":"done","chunks_total":1,"chunks_done":1,"chunks_dropped":0,"rows_written":1,"enrichment_retries":0,"content_hash":"2e5c3f3ff8212cd23d32a4237fbbce13720f39875b677384872c0f07d83b8c18"}

api log:

07:55:41.703 | INFO | memory_base.core.llm:166 | chat model: opencode / deepseek-v4.1-flash

Stored card (memory_chunks, chunk_kind=doc), 3 rows in doc_rows:

doc|The sample is a three-column table of cities with their populations and country codes. Fields are city (text), population (integer count of residents), and country (two-letter code such as KR for South Korea and JP for Japan). The three data rows list Seoul with 9,400,000 people in KR, Busan with 3,300,000 in KR, and Tokyo with 14,000,000 in JP. Useful patterns include grouping by country to compare urban populations, ranking cities by population size, and filtering for a specific country code. Tokyo is the largest city in the sample, while Busan is the smallest. The country field uses short ISO-style abbreviations rather than full country names, so joins or lookups may be needed to display readable country labels. Population values are numeric and suitable for aggregation, sorting, and averages by country.|["city population table", "country codes", "urban demographics", "tabular data sample", "population ranking", "iso-style country abbreviations"]|

Cleanup: DELETE /ingest/documents/probe-opencode-376?namespace=default → {"deleted":1}; afterwards 0 chunks and 0 doc_rows for the document.

Health: GET /health/services → {"status":"ok","checks":{"db":true,"embedding":true,"rerank":true,"llm":true}}. No tracebacks, 5xx or ERROR lines in the api/mcp logs over the run.

Reviews: Sonnet standards, Opus spec, gpt-6.1-sol. Accepted findings are in 3bb0d47 (named provider spec fields) and b62e130 (compose wiring and fixture cover OPENCODE_*; benchmark docs name zai_provider; two header tests merged). gpt-6.1-sol: no code defects.

@yw0nam
yw0nam merged commit 8a8918d into main Oct 19, 2026
4 checks passed
@yw0nam
yw0nam deleted the feat/opencode-provider branch October 19, 2026 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: OpenCode Go as the first chat provider

1 participant