opencode through the gateway¶
opencode is a real coding agent. For the demo video it plays DataBot:
its model calls and its tools both go through the gateway, so the same policy, controls,
session risk and audit apply to it as to the demo agent. docs/video.md has the beats.
Run it¶
make demo-up REMOTE=1 # the stack, demo overlay (demo-web) and the remote LLM
make opencode AS=anna # the TUI, as anna@demo
make opencode AS=bartek ARGS='run "How many customers do we have?"' # one turn, no TUI
make opencode (demo/opencode/launch.py):
- Mints a fresh token for
<AS>@demoon theopencodeagent from the operator API (POST /auth/demo-token). Every launch is therefore a new gateway session: no taint, no risk, fresh session budgets. The token lives one hour (the issuer's maximum). A session that runs longer starts failing with401 token_expired; quit and runmake opencodeagain (that is also how to reset a tainted session between takes). - Picks the model the selected upstream serves, from
/v1/models:deepseek-v4.1-flashin remote mode,qwen3:8bon local Ollama. - Starts the pinned opencode (
npx -y opencode-ai@1.18.34) indemo/opencode/.home/<AS>/(gitignored), withHOMEand everyXDG_*directory pointing there and the npm cache indemo/opencode/.home/npm-cache/. Nothing reads or writes~/.config/opencode,~/.claudeor~/.npm. (opencode reads skills from~/.claude/skillswhenHOMEis the real one; that is whyHOMEis isolated too.) The workspace is its own git repository, so opencode never takes this repo, or its instructions, as the project.
The token reaches opencode only through its environment (ACL_OPENCODE_TOKEN). The tracked
config, demo/opencode/opencode.json, refers to it as
{env:ACL_OPENCODE_TOKEN} and holds no secret. The environment is built from an allowlist
(PATH, TERM, locale), so no provider key from your shell (OpenAI, Anthropic, OpenRouter)
reaches opencode: it can only talk to models through the gateway. Delete
demo/opencode/.home/<AS>/ to clear opencode's local session history.
When scripting run, give it no stdin (`