SolarOS

SolarOS 4.6.8 manual · app

Native Agent Service

service.agent is the native control plane for connecting SolarOS to remote language models. app.agent is a resumable foreground chat frontend for display and port shells.

The first provider supports both the OpenAI Responses API and compatible Chat Completions endpoints. Configure the complete endpoint URL rather than a provider base URL. Responses is recommended for OpenAI reasoning models:

agent config endpoint https://api.openai.com/v1/responses
agent config model gpt-model
agent config key api-key
agent config reasoning medium
agent config tools confirm
agent config max-tools 16
agent status

The endpoint path selects the wire protocol: URLs ending in /responses use typed Responses events, while other URLs use Chat Completions. Reasoning effort may be none, minimal, low, medium, high, xhigh, or max; support still depends on the selected model. The default is medium.

Responses tool continuations use previous_response_id, so reasoning context is retained without copying reasoning tokens through the device. Responses are stored by the provider for that request chain. Instructions are sent again on the continuation because Responses does not carry previous instructions forward automatically.

For the official OpenAI Chat Completions endpoint, the adapter instead sends reasoning_effort: none so function tools remain compatible with that API. Other Chat-compatible endpoints do not receive this provider-specific field.

Configuration is stored in the agent NVS namespace. The API key is used as a Bearer token and is never returned by status. Use agent config key clear for a local or self-hosted endpoint without authentication, or agent forget to erase all agent configuration.

Start the foreground chat with:

agent
agent new

Enter sends a message, Page Up/Down scrolls the terminal transcript, and Esc or the app-exit key returns to the shell. The prompt uses the configured SolarOS username, agent labels are bold, and the protected bottom status bar shows the latest input, output, and total token counts without adding usage lines to the conversation or scrollback. Narrow displays abbreviate those fields as I, O, and T. Completed turns are stored under .solar/agent/conversations on the preferred persistent filesystem. Use agent list, agent resume SLOT, and agent delete SLOT to manage them. New conversations use slots 1 through 3 on internal flash or 1 through 8 on SD; once full, the oldest slot is replaced atomically. Exiting and launching bare agent again still starts a new conversation; restoring an old one is always explicit.

Each provider adapter declares its resume mode. Responses resumes from the saved provider response ID. Chat Completions rebuilds a bounded request from normalized local user and assistant messages. Restoring the visible transcript streams checked records from storage rather than placing the entire conversation in internal SRAM.

Only completed turns are committed. Each conversation is an independently checksummed file replaced through temporary and backup names, so an interrupted write cannot damage other conversations. With internal flash selected, the store keeps at most three 10 KiB conversations; with SD selected, it keeps at most eight 48 KiB conversations. Oldest conversations are evicted deterministically. Provider, model, title, timestamps, messages, tool summaries, and continuation IDs are stored; the bearer key remains only in NVS.

For a single request, use:

agent ask Describe the current device status.

The one-request frontend stays open after completion so the response remains readable. It is not persisted. Use Esc or the app-exit key to return to the shell.

On full builds, the same 16 KiB foreground worker can run a Python or Lua source string or file through the reusable script-runner contract:

agent script python -c "print(6 * 7)"
agent script lua -c "print(6 * 7)"
agent script python /script.py argument
agent script lua /script.lua argument

This manual path captures output instead of streaming directly from the interpreter. Output is limited to 4095 bytes and execution to 30 seconds. The Esc or the app-exit key cancels a running script. Python and Lua each have a single-owner guard, so a captured run cannot overlap their foreground app or REPL. Exceptions, cancellation, deadlines, truncation, and completion are returned as structured runner status.

The adapter requests server-sent streaming events and emits provider-neutral events for text deltas, usage, tool calls, errors, and completion. Cancellation uses the shared HTTP client's cross-task cancellation path. TLS certificate validation uses the firmware certificate bundle. A stateless local provider turn that contains neither text nor a tool call is retried once; a second empty turn is reported as an invalid response instead of silently returning to the prompt.

Typed tools

agent tools shows the canonical registry, domain and risk metadata, runtime availability, current policy disposition, and any required capability. The registry can be larger than the schema set sent to the provider. Every request starts with only three bootstrap tools:

Selected workflow dependencies such as script_run_file may activate on demand when they were not selected for the current request. SolarOS advertises the schema and asks the provider to retry. The first call is not executed and cannot bypass normal confirmation. Other inactive tools still require tool_search, preventing a model from activating an unsuitable operation by guessing its name.

The package- and policy-gated tools discoverable through tool_search are:

Tool policy is NVS-backed and enforced again inside the canonical executor:

PolicyBehavior
offAdvertise and execute no tools.
readonlyAdvertise and execute only read-only tools. Sensitive reads are excluded.
confirmRun read-only tools automatically and require one local confirmation for every sensitive, mutating, or disruptive call. This is the default.
allRun every available tool without confirmation. This must be selected explicitly.

Under confirm, the foreground app prints the exact bounded JSON arguments and waits up to 30 seconds at Allow once? [y/N]. Only y allows that call; n, Enter, or the timeout denies it. Esc or the app-exit key cancels the whole request. A denial is returned to the model as a structured result so it can explain or choose another approach rather than losing the conversation turn. agent status includes executed, denied, and failed tool counters.

The service permits up to 16 sequential tool calls by default and always reserves a separate provider turn for the final response. Set the per-request limit with agent config max-tools COUNT; accepted values are 1 through 32 and the selection is stored in NVS. Once the budget is consumed, the reserved final turn advertises no tools, so the model must conclude from the results already collected instead of failing by requesting another tool. This supports bounded inspect/read/change/test/repair workflows without allowing an unbounded autonomous loop. Unsupported tools, multiple simultaneous tool calls, and malformed arguments still fail the request. Definitions, input/output schemas, availability checks, risk metadata, and executors live in one declarative registry. Only available tools are sent to the provider. Discovery also filters tools denied by the current policy. The agent rejects calls to tools outside the currently advertised set, and every successful executor result is parsed as a JSON object before it is returned to the model.

Resource bounds

agent status records tool calls used versus the last request's configured budget, internal free memory, the lowest sample observed during HTTP streaming, largest internal blocks, and PSRAM before and at request completion. The completion sample still includes the foreground worker stack; run mem policy after the app returns to confirm that the task stack was reclaimed.

The agent package requires Wi-Fi and PSRAM but does not require Python or Lua. The manual command and model tool are advertised only when the corresponding runtime is in the firmware; the agent app supplies the optional adapter callback without making either interpreter a package dependency. Larger-file editing, mutating job/network/hardware operations, additional providers, remote interfaces, and scheduling are later phases.

Quick reference

The native agent uses the configured OpenAI-compatible Responses endpoint, applies the selected confirmation policy, and exposes bounded typed tools for installed SolarOS features. Completed chat turns are stored locally; agent list, agent resume SLOT, and agent delete SLOT manage them. Responses uses a provider continuation ID and Chat Completions uses bounded local history. agent status reports provider, policy, requests, tool activity, and memory. This page defines the tool contract and resource limits; man agent is the task-oriented usage guide.