跳到主要内容

Model ABI

There is only one model ABI:

/ctx/model/<provider>/<model> one-shot inference executable
/ctx/model/<provider>/<model>.sock optional CortexFS session socket
/ctx/model/<provider>/<model>.d/ control files
/ctx/model/main default model symlink
/ctx/model/helper helper model symlink

<provider>/<model> is represented as two path components. For native model providers, <provider> is the original provider identity:

/ctx/model/openai/gpt-4o
/ctx/model/anthropic/claude-sonnet-4
/ctx/model/google/gemini-2.5-pro

For a custom base URL without a declared original provider mapping, <provider> is the normalized host name. For example, https://api.lmm.best:9000/ projects models under:

/ctx/model/api.lmm.best/gpt-5.4-mini

The custom base URL is provider-adapter configuration, not a root ABI namespace. It may be shown in model/<provider>/<model>.d/default for inspection, but secrets never appear in model metadata or .d/ files.

Bottom-layer AI API formats do not enter the ABI. OpenAI Responses, Anthropic Messages, Gemini GenerateContent, OpenAI-compatible chat, local runtimes, and aggregator-specific request formats are Rig or provider-adapter details. Bottom-layer stateful/stateless behavior does not enter the ABI. Rig adapts provider connections, API compatibility, and streaming into the canonical CortexFS request and JSONL event stream.

Example:

/ctx/model/
main -> /ctx/model/debug/echo
helper -> /ctx/model/debug/echo
debug/
echo
echo.d/
id
driver
cap
default
session
status
log
openai/
gpt-4o
gpt-4o.d/
id
driver
cap
default
session
status
log

Control files:

id provider-native model id or runtime-internal model id
driver driver route table; see below
cap capability list, one per line
default default parameters, KEY=VALUE, one per line
session none or socket
status dynamic status
log short call log or pointer to log location

driver may be a legacy single driver name:

debug

or a route table:

default=openai-chat
exec=openai-chat
socket=openai-chat
agent=openai-responses,openai-chat

Route keys:

default fallback route
exec direct one-shot model file execution
socket direct model socket calls
agent agent-owned model calls

Each value is a comma-separated priority list. Runtime selection checks the use-case route first, then default. This lets direct model usage choose a classic chat driver while agents prefer a richer Responses-style driver with a chat fallback. Driver names are adapter names, not stable model names.

Secrets are never stored in model files or .d/ control files. Provider credentials use this priority:

environment variable
system keychain
unconfigured

For example, a provider adapter may first read LMM_API_KEY, then look up a system keychain item such as service=cortexfs:lmm account=default. If both are absent, the model is not configured and must return a stable error.

One-Shot Exec

/ctx/model/<provider>/<model> is a read-only executable object. Reading it returns CortexFS metadata text for that model. Executing it performs one-shot inference through CortexFS/Rust runtime code or a provider adapter; model objects must not be shell-script implementations.

The first metadata keys mirror Rig 0.39 model listing fields:

id
name
description
type
created_at
owned_by
context_length

Provider adapters may populate those fields from ModelListingClient::list_models() / ModelList. The built-in debug/echo model is local debug metadata and does not imply a provider default.

/ctx/model/debug/echo "hello"
echo "hello" | /ctx/model/openai/gpt-4o
echo '{"messages":[{"role":"user","content":"hello"}]}' | /ctx/model/openai/gpt-4o

Semantics:

one invocation
no durable session mutation
stdout is the canonical JSONL event stream
exit code is the process-level summary
file content is inspectable metadata, not provider code or secrets

Even if the underlying provider has native state, /ctx/model/<provider>/<model> behaves as a stateless single call.

Model Socket

/ctx/model/<provider>/<model>.sock is the only multi-turn model entry. It uses the shared JSONL socket protocol from object-abi.md.

Examples:

{"op":"send","id":"msg-1","session":"default","input":"hello"}
{"op":"resume","session":"default","after":"event-123"}
{"op":"cancel","id":"run-1"}
{"op":"ping"}

A model socket session is CortexFS session semantics, not provider-native session semantics. Native threads, response ids, context caches, and simulated message logs are hidden behind the canonical protocol.

model/<provider>/<model>.d/session has only two stable values:

none no /ctx/model/<provider>/<model>.sock
socket /ctx/model/<provider>/<model>.sock exists and supports CortexFS sessions

The value never describes provider-native state.

Capabilities

Use stable semantic capability words:

chat
stream
session
vision
audio_input
audio_output
json_schema
tool_call_syntax
reasoning
embedding
rerank

Provider-private or API-format-private capability words are forbidden in stable ABI:

openai_responses
anthropic_messages
gemini_generate_content
native_thread
native_stateful
native_stateless

tool_call_syntax only means the model event stream may contain tool-call-shaped events. It does not mean the model can execute tools. It grants no tool permission.

Canonical Event Stream

v1 model and agent streams use these event types:

start
delta
message
reasoning_delta
reasoning_message
tool_call
usage
error
done

Example:

{"type":"start","run":"r1","model":"debug/echo"}
{"type":"delta","run":"r1","text":"hello"}
{"type":"message","run":"r1","role":"assistant","content":[{"type":"text","text":"hello"}]}
{"type":"usage","run":"r1","input_tokens":10,"output_tokens":1}
{"type":"done","run":"r1","status":"ok"}

Error example:

{"type":"error","run":"r1","code":"EACCES","message":"permission denied"}
{"type":"done","run":"r1","status":"error"}

code uses stable errno names. Clients must not parse message.

Native Diagnostics

model/<provider>/<model>.d/native may exist for diagnostics only:

native is diagnostic only
native is not stable ABI
strict clients must not depend on it

Tool Boundary

Model execution is not tool execution.

Hard rule:

model may emit tool_call events
model must not execute tools
agent decides whether to execute tools
agent policy decides whether execution is allowed

Model processes must not receive project mounts, tool credentials, or write access outside runtime-owned cache. Provider tool calling must not become a backdoor around agent policy.