Repository navigation
feat: session.run, wait_until_ready, opencode.testing fake server, faster import - #12
Merged
Merged
Conversation
shrijayan
force-pushed
the
feat/headless-helpers
branch
from
October 22, 2026 10:18
9836522 to
9c594a7
Compare
- codegen: HELPER_BASES lets a generated resource class inherit from a hand-written base in src/opencode/lib; SessionResource uses it for run() - client.session.run (sync/async): create or reuse a session, prompt, wait until idle, return RunResult (messages, text, outcome, error, usage); interrupts the session on KeyboardInterrupt, cancellation or errors - client.wait_until_ready: poll agents and MCP servers after boot - transport= on both clients, Opencode.fake() - opencode.testing.FakeServer: in-memory httpx transport for user tests
Generated resources now name response types as strings, resolved by type_adapter on first use, and import models only under TYPE_CHECKING. opencode.types is a lazy package attribute. import opencode no longer builds ~640 pydantic models (median ~400ms -> ~265ms locally; the model build moves to the first request, ~130ms).
shrijayan
force-pushed
the
feat/headless-helpers
branch
from
October 22, 2026 10:21
9c594a7 to
4eb17d6
Compare
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.
Adds high-level helpers for the headless use case in anomalyco/opencode#54300 (run an agent, wait, read the result), a fake server for users' tests, and a faster
import opencode.What's new
client.session.run(text, *, agent, model, files, session_id, timeout)(sync + async). It creates a session or reusessession_id(switching agent/model if given), prompts it, blocks onsession.wait, and returnsopencode.lib.RunResultwithsession, the newmessages,text,outcome,error, and per-runcost/tokens. If the wait ends early (KeyboardInterrupt, async cancellation, timeout, or any error), it callssession.interruptbefore re-raising. The async version shields that call from cancellation.HELPER_BASESincodegen/render.pylets a generated resource class inherit from a hand-written base insrc/opencode/lib/.SessionResource(SessionHelpers)uses it.client.wait_until_ready(*, agents=(), mcp_servers=(), timeout=60)(sync + async) pollsserver.info,agent.listandmcp.list. Connection errors and 503s count as still booting. On timeout it raisesTimeoutErrornaming what is missing.transport=on both client constructors (additive; can't be combined withhttp_client), plusOpencode.fake()/AsyncOpencode.fake().opencode.testing.FakeServeris anhttpx.MockTransportwith in-memory sessions, prompts (includingresume=Falsequeueing), wait, interrupt, paged messages, agents, MCP status, server info and the SSE event stream. Payloads are built from the generated models. Test hooks:fail()for error/exception injection,add_agent/set_mcp_status(after_polls=...),requests,prompts.docs/guides/headless.md,docs/guides/testing.md,docs/reference/testing.md.Import time (separate commit
perf: load opencode.types on first use)Generated resources now name response types as strings, which
type_adapterresolves on first use, and import models only underTYPE_CHECKING.opencode.typesis loaded lazily. Wall clock forimport opencode, median of 9 runs on macOS with Python 3.14:import opencodeThe model build (~130 ms) now happens on the first request. What remains at import is mostly httpx, pydantic and typing_extensions. A subprocess test guards that
import opencodedoesn't loadopencode.types._generated.Tests
tests/test_helpers.py(19 tests, all on the fake): run, reuse, paging, interrupt on 503, KeyboardInterrupt and async cancel, wait_until_ready, and fake CRUD/errors/events.wait_until_ready, plusrunagainst a model of a nonexistent provider. That flow fails before any network call, so no model is called. Note: a default-model prompt on a sandboxed server uses OpenCode's hosted free model, which is why the test pins an unroutable model.Don't merge without review: every merge to
mainpublishes a release.