Models on a GPU
Agent harnesses
Connect OpenCode, oh-my-pi, Crush, local-agent, or another coding agent to Chalupa's tunnelled model endpoint.
Reviewed 2026-10-21
A harness here is any coding agent that talks to an OpenAI-compatible or Ollama endpoint. Chalupa hosts the model and tunnels its endpoint to your laptop. Your agent runs locally with your tools and workspace.
Complete GPU inference setup and install your chosen agent
before launching it. launch opens the tunnel and checks the model; it does not
provision compute. When the agent exits, the tunnel closes and compute stays
running until you run chalupa down.
Supported by default
These harnesses have built-in endpoint and model configuration:
| Harness | Launch command | Endpoint injection | Never modified |
|---|---|---|---|
| OpenCode | chalupa launch opencode |
OPENCODE_CONFIG_CONTENT contains a chalupa provider using @ai-sdk/openai-compatible, the tunnel's /v1 URL, model and context limits. OpenCode merges this inline configuration over its project settings. |
Project opencode.json and global settings files. |
| oh-my-pi | chalupa launch omp |
OLLAMA_BASE_URL and OLLAMA_CONTEXT_LENGTH configure Ollama discovery and context. A temporary native agent dir (models.yml with the tunnel provider, config.yml pinning modelRoles.default to ollama/<model>) is served via a child-only PI_CODING_AGENT_DIR, plus --model ollama/<model> on the command line, and is deleted on exit; sessions link back to your real session store so resume keeps working. |
Project and global settings, including ~/.omp/agent/models.yml and config.yml. |
| Crush | chalupa launch crush |
A private temporary crush.json sets an OpenAI-compatible provider and both large/small model roles to the tunnel endpoint. Negotiated context and output limits are included. |
Global config and global selection state; project session history stays in .crush. |
| local-agent | chalupa launch local-agent |
Env-only profile; the local-agent binary must be installed on PATH (launch refuses otherwise). The child receives LOCAL_AGENT_PROVIDER=chalupa, LOCAL_AGENT_LOCAL_ONLY=false and LOCAL_AGENT_PROVIDER_CONFIG, a JSON profile of the tunnelled GPU endpoint: the local tunnel's base URL (127.0.0.1, port 11435 by default), the model from inference.model and the context window. Any LOCAL_AGENT_MODEL or LOCAL_AGENT_PROVIDER_* variables already in your shell are removed from the child so they cannot override the GPU. inference.agents.local-agent.args and arguments after -- pass through. chalupa connect --format local-agent prints the same profile as YAML. |
Its own config files; nothing is written. OLLAMA_HOST is left alone, so its local embeddings keep using your laptop's Ollama. |
| sonar / vecai | chalupa launch sonar · chalupa launch vecai |
Env-only profiles: the connected environment — the same exports chalupa exec --format env prints (CHALUPA_INFERENCE_*, OLLAMA_BASE_URL, OLLAMA_CONTEXT_LENGTH) — is handed to the named binary, which must be installed on PATH (launch refuses otherwise). inference.agents.<agent>.args and arguments after -- pass through; no config is rendered. |
Everything; no files are written and no settings are replaced. |
Crush integration was checked with v0.92.0 using its official configuration contract.
Install Crush separately, then use chalupa launch crush or set
inference.agents.default: crush. chalupa connect --format crush exports the JSON
for manual configuration. JSON is supported by this version, although upstream
now recommends crushrc for hand-written configuration.
Launch replaces global configuration and global selection state for the child
process only; temporary files are removed on exit. Existing project Crush
configuration still loads and can override these defaults. Put launch-specific
changes in inference.agents.crush.config, .args, or .env. The launcher uses
local process mode so an existing Crush server cannot retain another session's
endpoint. Normal tool permissions remain in effect.
A local protocol smoke verified that the installed Crush sends requests to the
configured /v1/chat/completions endpoint and model. This does not establish
GPU model quality or tool-calling reliability. Crush sessions and logs are local;
Chalupa inference receipts still require explicit reporting.
Model and context defaults come from inference.model and
inference.contextSize. Pass agent arguments after --, for example
chalupa launch omp -- --no-session. Use --context auto before -- to
negotiate context at connection time; see context limits.
Any other tool
Use chalupa exec -- <cmd> to run a local tool while Chalupa owns its tunnels.
The child receives these variables:
| Variable | Value |
|---|---|
CHALUPA_INFERENCE_BASE_URL |
Ollama URL on the local tunnel. |
CHALUPA_INFERENCE_OPENAI_BASE_URL |
OpenAI-compatible URL ending in /v1. |
CHALUPA_INFERENCE_MODEL |
Configured model tag. |
CHALUPA_INFERENCE_CONTEXT_SIZE |
Context window in tokens. |
Configure your tool to read those values or map them to its own settings.
exec cannot infer an arbitrary tool's flags or provider configuration.
OLLAMA_HOST remains inherited for other tools; only omp and ollama
receive a replacement, so local embeddings can keep their own daemon.
For manual wiring, chalupa exec --format env prints shell exports without
opening a tunnel or modifying files. It is an alias for
chalupa connect --format env. Keep chalupa tunnel running in another terminal,
then use this three-line example with a tool named my-agent that reads the
exported values:
chalupa exec --format env
eval "$(chalupa exec --format env)"
my-agent
Alternatively, chalupa exec -- my-agent manages the tunnel and passes the
variables directly to the child process. Configure the tool's endpoint mapping
before using either path. No prompts or inference requests are sent by the
export command.
MCP clients and service briefs
This page is about running a coding agent against a model on a GPU. The
read-only MCP server (chalupa mcp), the action contract
(chalupa explain --json) and the read-only service briefs
(agentAccess with chalupa connect --format app-brief) work with any
environment, not only GPU ones, so they have their own page:
Chalupa for agents.
Per-agent overrides
Put overrides in inference.agents.<agent>.config in your project's
chalupa.yml. OpenCode and oh-my-pi accept configuration overrides; these keys
are not a registry for arbitrary tools. The env-only agents (local-agent,
sonar, vecai) accept args and env only — they generate no config
document to merge into.
inference:
model: qwen3.8:27b
contextSize: 32768
maxModelBytes: 25769803776
agents:
default: opencode
opencode:
config:
small_model: chalupa/qwen3.8:27b
omp:
config:
modelRoles:
smol: ollama/qwen3.8:27b
This is an excerpt; keep the provider, SSH and session settings from setup.
Nested objects merge over the generated configuration; arrays and scalars
replace the generated values. Overrides win, so check any endpoint or model
changes you declare. OpenCode gets the merged inline JSON; launch omp gets
the merged temporary agent dir. Generic exec -- omp supplies environment
variables but does not create that agent dir.
inference.agents.default selects the agent for a bare chalupa launch.
Agent args precede arguments passed after --; env applies only to the
child process and cannot override reserved CHALUPA_* variables.
See the configuration reference.
Adding a first-class harness
Profiles live in src/cli/agent-profiles.ts. A profile must produce the agent's
configuration or process environment from a validated InferenceEndpoint:
model tag, local tunnel port and context size. Use the existing URL helpers
and override merge behavior. Profile rendering must stay pure: no network,
credentials, tunnel creation or edits to the agent's settings files.
To add launch support:
- Add the name and supported override fields in
src/config.ts. - Render the endpoint, model and context in
src/cli/agent-profiles.ts. - Build the command in
src/cli/agent-launch.tsand reuserunConnectedfromsrc/cli/exec.ts. If a temporary agent dir is needed, restrict its permissions and remove it on both success and failure. - Add profile tests in
tests/agent-profiles.test.tsfor endpoint validation, URL mapping, model/context values, overrides and shell quoting. Add launch tests intests/agent-launch.test.tsfor arguments, environment, unchanged user settings and temporary-file cleanup. Cover CLI parsing intests/inference.test.ts. - Update this table and CLI help. Run
bunx tsc --noEmitandbun test ./tests/*.test.tsbefore submitting.
PRs are welcome. Include the harness version and a real tool-call check against the tunnelled endpoint. A rendered profile alone does not establish model compatibility. Receipt reporting is a separate contract; see reporting model turns.