# Claude Code pointed at a model running on the NODE ITSELF. # # The third variation on one idea: `agent-claude` talks to Anthropic, # `agent-glm` to z.ai, `agent-kimi` to Moonshot, and this one to the Ollama # already installed on every GPU node. Ollama has served a native # Anthropic-compatible `/v1/messages` since v0.14, so this costs an env contract # rather than a translation layer — MEASURED on both nodes: a tools request # comes back with a well-formed `tool_use` block and `stop_reason=tool_use`. # # Why the base URL is loopback INSIDE the guest, not a hostname: # # The VM has no network interface. `fcagent` listens on 127.0.0.1:11434 and # pumps to vsock 9003, where `clawmates-node::local_model` splices it onto the # node's own `127.0.0.1:11434`. There is no destination anywhere in that path — # it is a pipe to a fixed address, so a compromised guest cannot redirect it. # `NO_PROXY` already contains 127.0.0.1, so this bypasses the egress proxy # rather than trying to CONNECT through it. # # Build (on a node with a GPU — architect or tank): # # ssh architect "cd ~/clawmates && \ # docker build -f images/agent-ornith/Dockerfile -t clawmates/agent-ornith:dev images/agent-ornith/" # scripts/fc-build-rootfs.sh architect clawmates/agent-ornith:dev local-ornith 8G # # Building it ONLY on GPU nodes is deliberate and is the whole placement story: # a node advertises `rootfs-local-ornith.ext4` in `capabilities.rootfs`, and # `nodes::online_for_backend` already filters on exactly that. No GPU capability # key, no migration — morpheus simply never offers this backend. FROM clawmates/agent-toolchain:dev # Pinned to the SAME version as agent-claude and agent-glm. A run that differs # by provider should differ by nothing else, or "the local backend behaved # differently" is ambiguous between the model and the harness. ARG CLAUDE_CODE_VERSION=2.1.223 RUN npm install -g "@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}" \ && npm cache clean --force \ && rm -rf /root/.npm \ && claude --version # `ornith-fleet:9b`, NOT `ornith:9b`. Ollama defaults to a ~2K context window # whatever the model card says, and it truncates silently: MEASURED, stock # ornith:9b reported input_tokens=2050 for a 48000-word prompt and answered as # though nothing had been dropped. The fleet tag pins num_ctx=131072 and is # created by `scripts/fleet-model-setup.sh`. An agent turn is exactly the # workload that would hit the default and never say so. ENV HOME=/root \ CLAWMATES_AGENT_CLI=claude \ ANTHROPIC_BASE_URL=http://127.0.0.1:11434 \ ANTHROPIC_MODEL=ornith-fleet:9b \ ANTHROPIC_SMALL_FAST_MODEL=ornith-fleet:9b RUN mkdir -p /root/.claude # No provider key of any kind. `microvm_credential_for` hands this backend a # literal placeholder because Ollama ignores the bearer and Claude Code refuses # to start without one. There is no secret in this image and none reaches it.