There is no native tool for this, and images are shell data like any other, so the surface is a bash function the model pipes into: curl -sL https://example.com/photo.png | see, or see path.png. The name reads as a sentence in the pipe position, keeps working as a plain argument for local files, and is one const in vision.rs if it ever needs to change. Two halves, joined by a staging directory. Provision writes the BASH_ENV init file one non-interactive bash sources; see() execs the rhema binary's hidden __vision mode, which sniffs magic bytes, stages them under a 0700 per-process dir, and says so on stdout. 5 MB per image (the strictest API ceiling), png/jpeg/gif/webp only, and a refusal exits 2 with the reason on stderr so the model reads the limit in-band rather than losing the bytes to a silent drop. Attach runs after every bash command that reaches an exit: ShellTools drains the staging dir into ToolResult.images, a new core field. Bytes never ride stdout, so output caps and truncation cannot eat them, and a staged image attaches even when the command failed. The model staged it, so it belongs in the context. The caps: 5 MB staged, 8 images per result, the rest named in the result's text, because a for loop staging 30 screenshots must not cost a context window. serde keeps the field default, so old checkpoints load unchanged. Anthropic carries native image blocks in the tool_result content array, text first. OpenAI-dialect tool messages (llama.cpp, Copilot, OpenRouter, DeepSeek) and Gemini carry text only, so each withheld image is named in a trailing note the model can act on. The transcript's byte accounting and summaries count the images; the coding-agent config carries the prompt section, and the render adds the section only when wired. Frontends provision only where their bash runs locally: the TUI's session_agent_config, the headless one-shot, the ACP adapter, the claw's daemon, the same gate the MCP wire applies, because a session whose bash runs elsewhere cannot write where the drain reads. The vision wiring lands before the MCP wire so BASH_ENV names the MCP file last and its baked predecessor line reaches the vision init; both functions end up defined. Subagent inner shells inherit the parent's wiring, so a spawned agent keeps the macro in its own commands. SPEC's decision bullet, AGENTS.md's scope line, and the README row land with the feature.
1.1 KiB
You are the resident agent on this machine. This session's key is {{ session }}. You answer chat here. Your shell runs in the workspace at {{ workspace }}. Keep replies concrete. Do the work with tools instead of narrating it. Your final message, the one you end the turn on with no tool calls after it, is the reply the user sees.
Soul
{{ soul }}
User
{{ user }}
Environment
{{ environment }}
{% if tools %}
Tools
You act through these tools (name | description | arguments). The arguments are the JSON schema a call must satisfy.
{% for tool in tools %}
- {{ tool.name }} | {{ tool.description }} | {{ tool.parameters | tojson }} {% endfor %} {% endif %}
{% if vision %}
Viewing images
{{ vision }} {% endif %}
Memory
You keep persistent memory across sessions. memory_save stores what is worth remembering: decisions, conventions, corrections, pointers. memory_search recalls it; search before asking the user for something they have likely said before. memory_forget removes a record on request. Never save secrets into memory.
{% if onboarding %} {{ onboarding }} {% endif %}