# Agent Design Patterns Source: https://docs.agentuse.io/guides/agent-design-patterns Best practices for building production-ready AgentUse agents ## Core Design Principles ### Writing Instructions as SOPs Writing agent instructions is like creating a Standard Operating Procedure (SOP) for an employee. Just as SOPs provide clear, repeatable instructions for human workers, agent instructions should be precise, actionable, and comprehensive. When crafting agent instructions, think of yourself as a manager writing detailed procedures that any employee could follow: * **Be specific**: Like an SOP, leave no room for ambiguity * **Include all context**: Provide all necessary information upfront * **Define success criteria**: Clearly state what "done" looks like * **Handle edge cases**: Anticipate and document how to handle exceptions ### 1. Non-Interactive by Design AgentUse agents run without interactive prompts, making them perfect for automation, CI/CD pipelines, and cron jobs. Agents are designed to: * Run autonomously from start to finish * Complete tasks without user intervention * Work in headless environments * Integrate into automated workflows Because nobody is watching the run, the rehearsal has to happen beforehand: [`agentuse test`](/guides/testing-agents) exercises the whole SOP, including approval branches, with side effects fabricated. ### 2. Agent as Delegated Employee Think of agents as specialized employees you delegate work to. Once you hand off a task with clear instructions, they work autonomously until completion, just like delegating to a trusted team member. This delegation model means: * **Set and forget**: Give clear instructions and let the agent work independently * **No micromanagement**: The agent handles the task from start to finish * **Clear handoff**: Define input requirements and expected outputs * **Trust the process**: Like a well-trained employee, the agent follows your SOPs ### 3. Communication Through Tools Just as employees communicate and hand off work through tools like Slack and Notion, agents should use MCP servers and external integrations to report progress and deliver results. Agents communicate through: * **Status updates**: Use Slack MCP to send progress notifications * **Documentation**: Update Notion databases with results * **Handoffs**: Save artifacts to shared filesystems for other agents * **Reporting**: Post summaries to webhooks or APIs This approach mirrors how remote teams collaborate, asynchronously through shared tools rather than constant direct interaction. ### 4. Separation of Concerns Use sub-agents to separate different responsibilities, keeping each agent focused on a single task. Each agent should: * Have a single, clear purpose * Delegate complex subtasks to sub-agents * Use appropriate models for the task (Haiku for simple tasks, Sonnet for complex reasoning) * Maintain clear boundaries between concerns ## Implementation Patterns ### Multi-Agent Workflow Pattern Complex tasks can be decomposed into specialized agents that work together through sub-agent composition. This mirrors how organizations structure teams, each specialist handles their domain, communicating through established channels. #### Example: Content Pipeline Gathers information using web search or MCP tools ```markdown research.agentuse theme={"system"} --- model: anthropic:claude-haiku-4-5 mcpServers: filesystem: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-filesystem", "./research"] --- You are a research specialist. Find and save relevant information. ## Task 1. Research the given topic thoroughly 2. Save findings to research folder 3. Return key insights summary ``` Creates content based on research ```markdown writer.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 --- You are a content writer. Create engaging, accurate content. ## Task 1. Review provided research 2. Create well-structured content 3. Ensure factual accuracy ``` Coordinates the workflow ```markdown orchestrator.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./research.agentuse maxSteps: 50 - path: ./writer.agentuse maxSteps: 100 --- You coordinate content creation workflow. ## Task 1. Use research agent to gather information 2. Pass findings to writer agent 3. Review and finalize output ``` ### State Management with External Systems Since AgentUse agents are stateless between runs, use MCP servers to manage state: ```yaml notion-state.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: notion: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-notion"] requiredEnvVars: ["NOTION_TOKEN"] --- You track workflow state in Notion. ## Task 1. Check current state in Notion database 2. Process next pending item 3. Update state after completion ``` ```yaml file-state.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: filesystem: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-filesystem", "./state"] --- You manage state using local files. ## Task 1. Read state from state/current.json 2. Process based on current state 3. Write updated state back ``` ### Error Handling Build resilient agents with proper error handling: ```markdown robust-agent.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./validator.agentuse - path: ./processor.agentuse - path: ./error-handler.agentuse --- You execute tasks with comprehensive error handling. ## Error Handling Strategy 1. Validate input with validator agent 2. If validation fails, use error-handler to log and notify 3. Process with processor agent 4. If processing fails, use error-handler for recovery 5. Always provide clear status at completion ``` ### Chain of Responsibility Process data through a sequential pipeline where each agent handles a specific transformation step: ```markdown chain-pipeline.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./validator.agentuse - path: ./transformer.agentuse - path: ./publisher.agentuse --- You coordinate a data processing pipeline. ## Processing Pipeline 1. Use validator agent to validate input data 2. Pass validated data to transformer agent for processing 3. Send transformed data to publisher agent for final output 4. Return confirmation once all steps complete successfully ``` ### Conditional Routing Route requests to different handlers based on complexity or type: ```markdown conditional-router.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./simple-handler.agentuse - path: ./complex-handler.agentuse --- You route requests to appropriate handlers based on complexity. ## Routing Strategy 1. Analyze the incoming request complexity 2. For simple requests (< 3 steps), use simple-handler agent 3. For complex requests (>= 3 steps), use complex-handler agent 4. Return the handler's response with routing decision details ``` ### Retry with Fallback Implement resilient processing with automatic fallback on failures: ```markdown retry-fallback.agentuse theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./primary-agent.agentuse - path: ./fallback-agent.agentuse --- You ensure task completion through retry and fallback mechanisms. ## Execution Strategy 1. Attempt task with primary-agent first 2. If primary-agent succeeds, return its results 3. If primary-agent fails or times out, use fallback-agent 4. Log which path was taken and why 5. Always provide task results, regardless of path taken ``` # Agent Revisions Source: https://docs.agentuse.io/guides/agent-revisions Safely improve an agent from its source or the evidence in a completed or approval-paused run AgentUse can turn an agent's current source or the evidence from a real run into a reviewable change. Start a revision from an agent that has never run, a completed run, a failed run, or a run paused at an approval gate. The revision changes future runs; it does not rewrite or resume an originating run. ## Start a revision Open the run in the dashboard and choose **Revise agent file**. For an agent that has never run, open its detail page and start the revision there. Describe the behavior you want to fix or improve, choose the authoring model, and start the revision. AgentUse creates a durable internal session linked to the originating run when one exists. The reviser compares the current agent source, the available run transcript, and a sanitized, read-only view of the project. If one material decision is missing, it asks for that decision inside the same session instead of guessing. Only one active revision can belong to an originating run at a time. Return to the origin session to see its current revision and revision history. ## Review the result The reviser returns one of two outcomes: * a validated source proposal, with the source diff and any capability changes * a `no-agent-change` diagnosis explaining why changing the agent is not the right response to the run Review the proposal from the internal revision session. You can apply it, request changes and continue the same session, or discard it. A no-change diagnosis can likewise be accepted or reconsidered. Use **Copy prompt for Coding Agent** when the work belongs in project code or a custom integration rather than in the agent file. ## Write safety and recovery Nothing changes the agent source until an operator applies the proposal. AgentUse validates the proposed source and displays capability changes before the write. A source-hash check rejects the apply if the agent changed after the proposal was created, so a revision cannot overwrite newer work. The accepted replacement is atomic. After an apply, **Restore previous source** puts back the immediately preceding agent source. The revision session and originating run retain durable links so the diagnosis, proposal, decision, and restore path remain inspectable. ## Find revision sessions The Sessions list and feed label these AgentUse-owned jobs as **internal revision** and group them under **Internal revisions**. Their titles read **Revising *agent***, and each links back to the originating run. An agent's **Revisions** tab collects its revision history. Internal revision sessions are different from delegated subagents and automated Judge sessions. They are an operator-started workflow for changing an agent's future behavior. Agent revision is unavailable when `serve.hideAgentSource` or `--hide-agent-source` is enabled. A deployment that does not expose agent source cannot review or apply source revisions. See [Session Logs](/guides/session-logs) for the complete run record and [Operations Dashboard](/guides/serve-dashboard) for the surrounding workflow. # Approval Gates Source: https://docs.agentuse.io/guides/approval-gates Pause an agent run for human review, then approve, reject, or comment from the AgentUse approval dashboard Approval gates let an agent prepare work, pause before finalizing it, and continue only after a reviewer approves, rejects, or comments. Every run is a session. The review surface is the unified **session page** at `/sessions/` in `agentuse serve`: it shows the run log, and when the session is suspended on an approval gate it also offers approve / reject / comment right there. `/approvals` remains as a filtered list of sessions currently waiting for review, and each row links to the session page. Slack is optional: it can notify reviewers and link them into the session page, but Slack is not where approval state lives. ## How It Works 1. Add `approval: true` to the agent frontmatter. 2. Run `agentuse serve`. 3. The agent works normally until it reaches the approval point. 4. AgentUse suspends the session on a pending approval gate. 5. Reviewers open the session page (`/sessions/`), either from `/approvals` or from a tokenized link. 6. A reviewer approves, rejects, or comments. 7. AgentUse resumes the suspended session with the reviewer result. 8. After the session finishes, reviewers can send follow-up instructions from the same session page to continue the session with its existing context. A leaf agent's approval gate works the **same whether the agent is run directly or delegated by a `type: manager`** agent. See [Approval in delegated sub-agents](#approval-in-delegated-sub-agents) below. ## Create an Agent with Approval Use the smallest possible config: ```md theme={"system"} --- model: anthropic:claude-sonnet-5 approval: true --- Write a polished launch email from the user request. ``` The markdown body stays focused on the work. You do not need to write instructions like "wait for approval before publishing." If an approval should expire, set a timeout: ```yaml theme={"system"} approval: timeout: 24h ``` By default, approvals do not expire. ## Define the Approval Boundary Approval gates are agent-driven: the agent calls the internal `await_human` tool when it reaches the point where review is needed. AgentUse injects the approval mechanism, but your agent instructions can still define the policy boundary for your workflow. Write the boundary in business terms. Describe what the agent may prepare without approval, and what it must not finalize until approval is granted. For a social publishing agent: ```md theme={"system"} --- model: anthropic:claude-sonnet-5 approval: true channels: slack: events: [approval] --- Draft the social post and save any working files under `.agentuse/tmp/`. You may create drafts, previews, and local artifacts without approval. Before scheduling or publishing the post through any external service, request approval with: - a short summary of the post - the final post text - the target account or channel - the scheduled time, if any - any risks or assumptions ``` For a release agent: ```md theme={"system"} --- model: anthropic:claude-sonnet-5 approval: timeout: 24h --- Prepare the release notes and open a draft pull request if needed. Do not publish the package, tag the release, merge the PR, or announce the release until the approval gate is approved. ``` Good approval boundaries usually separate reversible preparation from external side effects: * Usually safe before approval: local temp files, drafts, previews, dry runs, summaries, draft PRs * Usually approval-required: publishing, sending email, scheduling posts, deploying, merging, deleting, charging, or changing production/external state * If unsure, ask for approval before the action ## Gated commands (mechanical enforcement) The boundary above is guidance the model follows. For irreversible **bash commands** you can also enforce it mechanically, so the command cannot run before you approve it even if the model tries. List those commands under `tools.bash.gated`: ```yaml theme={"system"} model: anthropic:claude-sonnet-5 tools: bash: commands: # auto-run, no approval - "birdc read *" - "birdc search *" gated: # run only after you approve the exact action - "birdc reply *" ``` Read it as: `commands` is what the agent can do; `gated` is what it can't do without you. A gated command is still allowed to run (the effective allowlist is `commands` plus `gated`), but only after a human approves the exact action. A command matching both lists is gated (gated wins), so a broad `birdc *` in `commands` cannot un-gate `birdc reply *`. Declaring `gated` enables the approval machinery automatically, you do not also need `approval: true`. For a plain yes/no decision, the agent emits `await_human` and the gated command together. AgentUse attaches the exact command to the request, blocks it from executing, and lets the agent re-issue it only after you approve. The guarantee is two-fold, enforced per action (not once per session): 1. A gated command never runs before approval. 2. A gated command never runs anything other than what you approved. Approval binds to the exact complete shell command shown in `changes[]`; payload text by itself grants nothing. If the agent revises the command or its payload, the old approval no longer covers it and it must re-gate. 3. Each approved entry is one-shot. It is consumed before dispatch, so an ambiguous failed external action is never retried silently. Listing the same exact command twice authorizes two executions. Notes: * **You rarely hand-write this.** Skills that ship posting commands, the interactive command prompt, and generated agent files add `gated` for you. `agentuse doctor ` also flags an allowlisted command that looks irreversible (`reply`, `post`, `delete`, `git push`, `curl -X POST`, ...) but is not gated. AgentUse never auto-gates from a keyword guess, it only suggests. * **Plain gates auto-attach the command.** Emit `await_human` and the exact gated bash command in the same model step. The command is shown to the reviewer but remains blocked until approval; after approval the agent re-issues it once. Non-gated tools still cannot ride beside a gate. * **Pick gates scope actions explicitly.** Give each `changes[]` action an `optionId` referencing the corresponding `options[].id`. When `content` is an executable command, also set `displayContent` to the exact human-facing post, reply, message, or body. The reviewer sees the business content first with the command de-emphasized inside the same option. Approval grants only the selected option plus any action with no `optionId`. This is the safe one-approval pattern for choosing among several irreversible commands. * **Show the complete command.** Whether auto-attached or option-scoped, the lease covers the exact executable command (`birdc reply "text"`), not payload text alone. For browser automation, gate and show the step that carries the words (`agent-browser type "..."`), not a contentless click. * **Unattended runs suspend only on a declared gate**, never on a tooling question. You approve outcomes, not commands. ## Start the Server Start the AgentUse daemon: ```bash theme={"system"} agentuse serve ``` Open the sessions dashboard (every run) or the approvals view (sessions waiting for review): ```text theme={"system"} http://127.0.0.1:12233/sessions http://127.0.0.1:12233/approvals ``` Both link into the per-session page at `/sessions/`. If reviewers open links from another machine, start `serve` with a reachable public URL: ```bash theme={"system"} agentuse serve --public-url https://agentuse.mycompany.com ``` AgentUse runs one serve daemon at a time. When the daemon is serving this project, approval links use its registered port. Use `--public-url` when reviewers need a URL other than the local server address. ## Optional Slack Channel Slack can alert reviewers when an approval is waiting. Approval state still lives in the AgentUse session page. The Slack channel message stays concise, and supporting approval details are posted in the message thread when the agent provides them. Those thread details can include summary, draft, artifact, context, and risk. ```yaml theme={"system"} approval: true channels: slack: events: [approval] ``` See [Channels](/guides/channels) for Slack setup, channel ids, events, and completion/failure channel messages. ## Reviewer Flow Make each approval understandable without opening Draft or Context or reading "Why this request". Choose one primary review surface: * **Actions:** use `prompt` + `changes`. Put the exact caption/body in `displayContent` when `content` is a command, attach the media in `media_urls`, and name the destination account/platform and timing in the action label. Material revisions belong in the visible prompt or action label, and critical consequences belong in `risk`. * **Standalone deliverables:** first create and save the report, proposal, or other artifact using `tools__artifact_save` when available or another suitable creation tool. Wait for success, then call `await_human` with its returned `artifact_path` (or `artifact_paths` for several files). Use `artifact_url` for an existing hosted deliverable. Never invent paths or URLs. Artifacts appear in an expanded section; supported local formats and hosted media have inline previews, and hosted documents have a visible open link. Omit `draft`, `summary`, and `context` by default. Existing payloads remain supported. The session page supports these review fields: * `prompt`: the reviewer-facing decision prompt * `changes`: the exact actions taken on approval, one `{ label, content }` entry per discrete action. Each renders as a highlighted "On approval" box with a copy button and character count, so the reviewer skims the verbatim payload first. When `content` is a command, `displayContent` carries the human-facing body; for a thread or any multi-post submission, pass `displayContent` as a list of strings, one per post, and the card renders them as numbered posts. Add `media_urls` when an action carries an external image, video, or audio asset; supported media renders inline in the same action card for review * `reference`: the original item the action responds to (`{ label, author, title, url, excerpt }`), such as the post being commented on or the message being replied to. On a wide screen it renders in a column beside the changes, so the reviewer reads original and response together; on a narrow one it stacks above them * `options`: two or more choices for the reviewer, each with an `id`, `label`, and optional `description` / `recommended`. The session page renders a single-choice picker before the decision controls. On approval, the selected id reaches the agent as `toolResult.choice` * `summary`: optional background under "Why this request"; never the only place essential review information appears * `draft`: legacy inline Markdown, retained for compatibility. Use actions or saved artifacts in new requests. When `changes` carries the verbatim payload, the draft renders collapsed as supporting detail * `draft_url`: URL to a draft artifact * `artifact_url`: URL to the primary review artifact, such as a PR, preview, document, or generated artifact * `artifact_path` / `artifact_paths`: project-relative local files the session page can open in the artifact viewer. Images, HTML, and PDF artifacts render inline; MP4/WebM/MOV/M4V video and MP3/M4A/WAV/OGG audio use native players. Files are snapshotted at gate time so the reviewer approves immutable bytes * `context`: background the other fields do not already carry (constraints, inputs used, process notes); agents are steered to omit it rather than repeat the reference, changes, or summary * `risk`: known risks, unresolved questions, or reviewer attention areas * Session logs before and after the decision Review bodies support Markdown, including headings, emphasis, links, blockquotes, numbered lists (`1.` or `1)`), bullet lists, tables, and fenced code. This includes `changes[].displayContent`, individual thread posts, and `reference.excerpt`. Preserve the exact submitted body and original quote, including any existing Markdown. Copy buttons retain the source text; rendering does not change the approved payload or executable command. Raw HTML is escaped. ### The original is mandatory on a response gate When the gate approves a reply, comment, answer, or any other response to something someone else wrote, `reference` is required and its `excerpt` must carry the **complete verbatim original**, not a summary and not the first few lines. The schema rejects three shapes that force the reviewer to leave the card and open the source: * a response gate with no `reference` at all (putting the original in `context` prose does not count) * a `reference` that carries an author, title, or `url` but no `excerpt` * an `excerpt` with an explicit elision marker such as `[truncated]` or `(full text at the link)` A gate for a *fresh* post, email, or document is unaffected: it answers nothing, so it has no original to quote. Reviewer actions are fixed: * `Approve`: resumes the agent with `status: "approve"` * `Reject`: resumes the agent with `status: "reject"` * `Comment`: resumes the agent with `status: "comment"` and the reviewer comment `Comment` is the revise-and-re-gate path, not a failed selection. On a choice gate, an actionable edit or direct replacement in the comment takes precedence over the absence of a selected option. For example, `reply "very nice!"` means to replace the proposed reply with `very nice!` and request approval again; it is not ambiguous merely because it names no option. Only an explicit request to cancel, abandon, or stop makes a comment terminal. For a choice gate, AgentUse preselects the recommended option, or the first option when none is recommended. The reviewer can change that selection before approving. The result retains the normal approval status and adds the selected option id: ```json theme={"system"} { "status": "approve", "choice": "ship_tuesday" } ``` Use stable machine-readable ids. Labels and descriptions may change without breaking the agent logic that consumes `toolResult.choice`. On reject, AgentUse passes the decision back to the agent instead of applying a universal workflow state change. If the agent tracks drafts, queue items, or tasks in a store, describe the rejected-state transition in the agent instructions, such as "when rejected, mark the current draft item `rejected`" or "when rejected with feedback, mark it `needs_revision`." When Slack Socket Mode is configured, the approval details thread can also accept Approve, Reject, Comment, and normal thread replies. Without Socket Mode, reviewers open the session page link to decide. When the agent receives a comment, it decides whether to revise, ask for approval again, or stop with a clear explanation. After the run completes, the same session page becomes a lightweight continuation surface. Add a follow-up instruction in the **Resume session** box to resume the completed or errored session with its existing context. This matches Slack thread replies, but keeps the web session page as the source of truth for details and logs. If an approval decision was submitted but the resumed run failed downstream, the session page may offer **Retry**. Retry reopens the latest resolved approval gate, preserves the original session token, and lets the reviewer submit the decision again. Use it only when it is safe to retry the downstream work; the UI warns about possible duplicate external side effects. If a decision itself fails, the approval card says what failed, whether the decision was applied, and what to do next: **Reconnect** or **Connect** for a provider sign-in, **Retry** for a transient worker or provider failure, and nothing when the gate was already answered, changed, ended, or expired. Your typed comment is kept. Draft, revision, and change set pages show the same panel. ## Approval in delegated sub-agents A leaf agent's approval gate behaves identically whether you run it directly or a `type: manager` agent delegates to it. You define `approval: true` once on the leaf, and the same human gate fires in both modes. Only the channel the request surfaces through changes. ```md title="reply-to-post.agentuse — the leaf, reused in both modes" theme={"system"} --- model: anthropic:claude-sonnet-5 approval: true --- Draft a reply to the given post in the brand voice, then publish it. ``` * **Run it directly** (`agentuse run reply-to-post.agentuse`) and you get the gate, as for any top-level agent. * **Delegate it** from a manager and the *same* gate fires inside the sub-agent. The request surfaces **on the manager run's session page** (and the `/approvals` inbox, and Slack if configured), labeled with the originating leaf. Approve / reject / comment there: the decision resolves the leaf's gate, the leaf finishes, and the manager resumes automatically. ```md title="manager.agentuse — delegates to the same leaf, unchanged" theme={"system"} --- type: manager schedule: "0 9 * * *" subagents: - path: ./reply-to-post.agentuse --- For each post worth replying to, delegate to reply-to-post. ``` This works for an interactive manager and for a scheduled/headless one: the run suspends durably and resumes when the decision arrives. **Approve at the manager root.** The delegated leaf's own session page is view-only and links up to the manager run, where the decision is made. This keeps one canonical approval surface per run. **v1 behavior and limits:** * One approval at a time per manager run. To gate several items, have a single leaf loop and call the gate once per item (it re-suspends and re-surfaces at the root each time), rather than fanning out to many sub-agents that suspend simultaneously, concurrent multi-gate fan-out is not yet supported. * The human always decides outward/irreversible actions (human relay). Automatic, classifier-based approval of low-risk calls is a separate, later option. * Resolve a delegated gate from the manager's approval page, `/approvals` inbox, or Slack, not `agentuse sessions resume`, which handles only single-session gates. ## Configuration Fields Approval config is intentionally small: ```yaml theme={"system"} approval: true ``` or: ```yaml theme={"system"} approval: timeout: 24h ``` * `approval`: `true` or an object to enable the approval gate * `approval.timeout`: optional suspension timeout, such as `30m`, `24h`, or `7d`. A bare number means seconds. * `tools.bash.gated`: bash command patterns that run only after human approval, enforced by a per-action lease. Declaring it implies the approval gate. See [Gated commands](#gated-commands-mechanical-enforcement). Channel config is separate: ```yaml theme={"system"} channels: slack: events: [approval] channel_id: C0123456789 ``` * `channels`: optional external collaboration channels, such as `channels: [slack]` * `channels.slack.events`: events for Slack. Approval gates use `approval`; terminal run events are documented in [Channels](/guides/channels). * `channels.slack.channel_id`: Slack channel id. If omitted, AgentUse uses `SLACK_APPROVAL_CHANNEL`. * `channels.slack.enabled`: optional switch for temporarily disabling Slack ## Auth and the session token Authentication follows the deployment invariant: * **Local bind** (`127.0.0.1` / `localhost` / `::1`): no API key, no token. View and approve are fully open. A keyless daemon only answers requests addressed to `localhost`, `127.0.0.1`, `[::1]`, `*.localhost`, or the host of its [public URL](/reference/configuration-files); anything else gets `403 HOST_NOT_ALLOWED`. * **Exposed host**: `serve` refuses to start without `AGENTUSE_API_KEY` (use `--no-auth` to bypass, dangerous). The API key (`Authorization: Bearer`) authorizes everything. Because a `Bearer` header is not clickable from a Slack message or an email, each session also has a **session token**: a stateless, per-session value that stands in for the API key on that one session's page. ```text theme={"system"} sessionToken = base64url( HMAC-SHA256(key = AGENTUSE_API_KEY, msg = sessionId) ) ``` One token grants both **view** and **approve** for its session, and the same value works for every gate in that session. It is unguessable without the API key and is scoped to a single session (a token for session A never authorizes session B). On localhost there is no API key, so there is no token and links omit it. `await_human` mints this token when it builds the reviewer link, so Slack/email links are clickable without an API-key login. The token covers viewing and deciding only. It cannot continue a run with a new prompt, add or discard learnings, reach the parent session, or open project files other than that session's gate artifacts, snapshots, and saved deliverables. Those need the API key, or a local keyless daemon. While a run is suspended, anyone with its session link can approve it. A completed run has no pending gate, so a shared completed-log link cannot approve anything. The view + approve conflation only matters during the approval window. ## Experimental session / approval API The API is experimental and mirrors the web session page contract. Use it to build custom review UIs or integrations. JSON endpoints live under the `/api/*` prefix and are always API-key gated on an exposed host. The HTML session page and its action subroutes carry their own capability auth (session token / API key / local), so a tokenized link works without a `Bearer` header. List sessions as JSON (filter by `agent`, `trigger`, or time window with `days`): ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions?trigger=scheduled&days=7" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` Fetch one session (summary + run-log entries): ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions/session_abc123" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` Poll a session's live status (session token works in place of a header): ```bash theme={"system"} curl "http://127.0.0.1:12233/sessions/session_abc123/status?token=$sessionToken" ``` Submit a decision. Authorize with the session token (`?token=`) or a `Bearer` header; the current pending gate is resolved server-side, so you do not pass a gate token: ```bash theme={"system"} curl -X POST "http://127.0.0.1:12233/sessions/session_abc123/decision?token=$sessionToken" \ -H "Content-Type: application/json" \ -d '{ "status": "approve", "comment": "Looks good" }' ``` When a decision fails, the open-gate payload carries `actionFailure: { kind, provider?, retryable }` (plus `action`, `code`, and `message`), which the approval card uses to pick Reconnect, Retry, or nothing. The decision endpoint returns immediately while the suspended session resumes in the background: ```json theme={"system"} { "sessionId": "session_abc123", "status": "resuming" } ``` Continue a completed or errored session (operator only; a session token is refused with `403 OPERATOR_REQUIRED`): ```bash theme={"system"} curl -X POST "http://127.0.0.1:12233/sessions/session_abc123/continue" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Please revise the CTA and run the smoke test again" }' ``` The continuation endpoint also returns immediately while AgentUse starts the follow-up run: ```json theme={"system"} { "sessionId": "session_abc123", "status": "continuing" } ``` Reopen the latest resolved approval gate on an ended session: ```bash theme={"system"} curl -X POST "http://127.0.0.1:12233/sessions/session_abc123/reopen?token=$sessionToken" \ -H "Content-Type: application/json" \ -d '{}' ``` The reopen endpoint returns the session to `suspended` so the normal decision flow can run again: ```json theme={"system"} { "success": true, "sessionId": "session_abc123", "status": "suspended" } ``` **Legacy approval routes.** `GET /approvals/:id` now redirects to `/sessions/:id`, and the older `/approvals` JSON list plus the `/api/approvals/:id/{status,decision,continue}` action endpoints remain available for backward compatibility. Those legacy action endpoints still take a gate `resumeToken` in the body. In-flight Slack links from before the upgrade keep working: the session page also accepts a valid gate `resumeToken` as a credential until those approvals expire. The legacy `/api/approvals/:id/continue` endpoint is operator-only as well. Prefer the `/sessions` routes and the session token for new integrations. ## Local Testing For development or manual testing, you can resume a suspended session from the CLI: ```bash theme={"system"} agentuse sessions resume session_abc123 --approve ``` You can also reject or comment without writing JSON: ```bash theme={"system"} agentuse sessions resume session_abc123 --reject "Not ready" agentuse sessions resume session_abc123 --comment "Shorten this and add pricing" ``` Prefer the `/approvals` UI for normal review, Slack for reviewer alerts, the Approval API for custom review surfaces, and `agentuse sessions resume` for local testing. ### Testing gate flows unattended Resuming by hand is fine for one gate. To check that each branch behaves, let `agentuse test` play the reviewer deterministically: ```bash theme={"system"} agentuse test my-agent.agentuse --approval approve agentuse test my-agent.agentuse --approval reject agentuse test my-agent.agentuse --approval comment:"tighten the subject line" ``` The run finishes with no human involved, and an approval grants the gated-command lease exactly like a real reviewer, so `tools.bash.gated` flows complete end to end without executing anything irreversible. See [Testing Agents](/guides/testing-agents). # Channels Source: https://docs.agentuse.io/guides/channels Connect AgentUse lifecycle events such as approval, completion, and failure to Slack Channel event names and the `channels` configuration contract are experimental and may change without migration as AgentUse adds destinations. Channels connect AgentUse lifecycle events to external collaboration surfaces. In the current release, Slack is the implemented channel. Use channels when a person should know that an agent needs review, finished successfully, or failed, or when Slack thread replies should continue a run. ## Basic Slack Setup Add Slack to the agent frontmatter: ```yaml theme={"system"} channels: [slack] ``` For explicit event selection: ```yaml theme={"system"} channels: slack: events: [completion, failure] channel_id: C0123456789 ``` Set a Slack bot token and default channel: ```bash theme={"system"} export SLACK_BOT_TOKEN="xoxb-..." export SLACK_APPROVAL_CHANNEL="C0123456789" ``` To get a Slack bot token: 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create or open a Slack app. 2. Open **OAuth & Permissions**. 3. Add the bot token scope `chat:write`. 4. Click **Install to Workspace** or **Reinstall to Workspace**. 5. Copy the **Bot User OAuth Token**. It starts with `xoxb-`. Optional: add `assistant:write` if you want Slack Assistant thread status while a live run is active. Approval channel threads can also accept decisions. For Approve/Reject buttons and comment-by-thread-reply, configure Socket Mode: ```bash theme={"system"} export SLACK_APP_TOKEN="xapp-..." ``` The app-level token needs `connections:write`. To resume from normal thread replies, enable Slack event subscriptions for `message.channels` and, if you use private channels, `message.groups`; add `channels:history` and/or `groups:history` bot scopes as needed. To get a channel id: 1. Open the channel in Slack. 2. Click the channel name. 3. Copy the channel id from the channel details panel. It starts with `C...` for public channels or `G...` for private channels. You can also copy a channel link and use the `C...` or `G...` value from the URL. Invite the bot to the target channel before sending channel messages. For private channels, this is required. ## Slack Config V1 supports one Slack channel per agent. ```yaml theme={"system"} channels: slack: events: [approval, completion, failure] channel_id: C0123456789 ``` Fields: * `channels.slack`: `true` or an object to enable Slack * `channels.slack.enabled`: set to `false` to temporarily disable Slack * `channels.slack.events`: event or list of events * `channels.slack.channel_id`: Slack channel id for this agent Slack can be written in any of these forms: ```yaml theme={"system"} channels: [slack] ``` ```yaml theme={"system"} channels: slack: true ``` ```yaml theme={"system"} channels: slack: events: [approval] channel_id: C0123456789 ``` If `channel_id` is omitted, AgentUse uses `SLACK_APPROVAL_CHANNEL`. ## Events Supported event names: * `approval`: the agent created an approval request and is waiting for review * `completion`: the agent finished successfully * `failure`: the agent ended with an execution error A run whose blocker is a person (waiting on an approval or review, or rejected by one) does not fire `failure`. Its live run card settles as **run incomplete** with the agent's reason. Use `completion`, not `complete` or `completed`. If `events` is omitted, AgentUse enables all supported events. `completion` and `failure` are terminal run events. A Slack channel that listens for `approval`, or for both `completion` and `failure`, posts a run-start card immediately and updates the same card when the run completes, fails, or waits for approval. Single-outcome channels such as `events: [failure]` stay terminal-only so they do not leave stale running messages. ## Slack Messages Slack uses one concise channel message as the status card and puts approval details in that message's thread. Approval channel messages include: * Channel card with prompt, session/project metadata, status, and a Review approval button * Thread details with summary, draft, artifact, context, and risk when the agent provides them * Thread actions for Approve, Reject, and Comment when Socket Mode interactivity is enabled * Plain thread replies become `comment` decisions when Socket Mode message events are enabled The AgentUse session page (`/sessions/`) remains the source of truth for review state. Completion channel messages include: * Channel card with agent name, session id, status, and duration * Thread details with the final answer, tool call count, and token count when available Failure channel messages include: * Channel card with agent name, session id, status, and duration when available * Thread details with the error message and run metadata When Slack Socket Mode message events are enabled, a reviewer can reply in a completed or failed run channel thread to continue from that session with the reply as the new instruction. For live run cards, AgentUse also tries Slack Assistant thread status while the run is active. This is best effort; Slack may ignore it when the app does not have Assistant support. ## Approval Gates Approval Gates use channels only to alert reviewers. Configure the approval policy separately: ```yaml theme={"system"} approval: true channels: slack: events: [approval] ``` See [Approval Gates](/guides/approval-gates) for the approval dashboard, reviewer flow, and Approval API. # CI/CD Source: https://docs.agentuse.io/guides/cicd Configure AgentUse agents to run in GitHub Actions for automated PR reviews, comment responses, and custom workflows. This guide uses [agentuse/pr-review-agent](https://github.com/agentuse/pr-review-agent) as a comprehensive example. You can copy its workflows and agents directly to your project. ## Overview GitHub Actions can run AgentUse agents in response to repository events: * **PR Reviews**: Automatic code review when PRs are opened/updated * **Comment Replies**: Respond to @mentions in PR/issue comments * **Custom Workflows**: Manual or scheduled agent runs ## Quick Start ### 1. Copy Workflow Files From the [agentuse-pr-agents](https://github.com/agentuse/agentuse-pr-agents) repository: ```bash theme={"system"} # Copy workflows and agents to your project cp -r .github/agents .github/workflows your-project/.github/ ``` This gives you: ``` .github/ ├── workflows/ │ ├── agentuse-code-review.yml # PR review automation │ └── agentuse-comment-reply.yml # @mention responses └── agents/ ├── code-review.agentuse # Review agent prompt └── comment-reply.agentuse # Reply agent prompt ``` ### 2. Configure API Keys Add ONE of these secrets to your repository (**Settings → Secrets → Actions**): | Secret Name | Provider | Get From | Best For | | - | - | - | - | | `ANTHROPIC_API_KEY` | Anthropic | [console.anthropic.com](https://console.anthropic.com) | Pay-per-use | | `OPENAI_API_KEY` | OpenAI | [platform.openai.com](https://platform.openai.com) | GPT models | | `OPENROUTER_API_KEY` | OpenRouter | [openrouter.ai](https://openrouter.ai) | Multi-provider | | `OPENCODE_GO_API_KEY` | OpenCode Go | [opencode.ai/auth](https://opencode.ai/auth) | Open coding models | | `CLAUDE_CODE_OAUTH_TOKEN` | Claude Pro/Max | `npx agentuse auth setup-github` | Subscription users; provider plugin required | For Claude Pro/Max users, install the Claude Code subscription provider plugin in the project or runner image, then run `npx agentuse auth setup-github` in your project directory. The command writes the token secret to GitHub; the token alone does not install or activate its transport. ### 3. Done Open a PR to trigger automatic review, or mention `@agentuse` in any comment. ## Workflow Configuration ### PR Code Review Workflow **File**: `.github/workflows/agentuse-code-review.yml` #### Key Configuration ```yaml theme={"system"} on: pull_request: types: [opened, synchronize, reopened] workflow_dispatch: inputs: pr_number: description: 'PR number to review' required: true type: number permissions: contents: read pull-requests: write concurrency: group: pr-review-${{ github.event.pull_request.number }} cancel-in-progress: true ``` #### Environment Variables The workflow sets these variables for the agent: | Variable | Description | | - | - | | `GITHUB_REPOSITORY` | Repo name (e.g., `user/repo`) | | `PR_NUMBER` | Pull request number | | `BASE_REF` | Target branch (e.g., `main`) | | `HEAD_REF` | Source branch | | `GH_TOKEN` | GitHub token for API access | ### Comment Reply Workflow **File**: `.github/workflows/agentuse-comment-reply.yml` #### Key Configuration ```yaml theme={"system"} if: | github.event.issue.pull_request && contains(github.event.comment.body, '@agentuse') ``` #### Context Variables | Variable | Description | | - | - | | `COMMENT_ID` | Comment ID for threading | | `COMMENT_AUTHOR` | Who mentioned the bot | | `COMMENT_BODY` | Full comment text | ## Agent File Configuration ### Structure Agent files use YAML frontmatter + markdown: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 maxSteps: 50 tools: bash: commands: - "gh *" - "git *" filesystem: - path: "${root}" permissions: [read] --- # Your Agent Instructions Instructions here in markdown... ``` ### Model Selection Override the default model in three ways: **1. Agent file** (recommended for consistency): ```yaml theme={"system"} model: anthropic:claude-opus-5 ``` **2. Workflow dispatch input** (one-time override): ```yaml theme={"system"} workflow_dispatch: inputs: model: description: 'Model override' type: string ``` **3. Environment variable** (all runs): ```yaml theme={"system"} env: MODEL: openai:gpt-5.6 ``` Priority: Dispatch input → Env var → Agent file ### Tool Permissions Limit what the agent can do: ```yaml theme={"system"} tools: bash: commands: - "gh *" # GitHub CLI only - "git log *" # Limited git access filesystem: - path: "src/**" # Read source files only permissions: [read] ``` ### Timeout & Step Limits ```yaml theme={"system"} maxSteps: 50 # Maximum agent steps ``` ```bash theme={"system"} # In workflow npx agentuse run agent.agentuse --timeout 300 # 5 minute timeout ``` ## Advanced Configuration ### Filter PRs by Path ```yaml theme={"system"} on: pull_request: paths: - 'src/**' - '!**/*.test.ts' ``` ### Different Models per Task ```yaml theme={"system"} # .github/agents/quick-review.agentuse model: anthropic:claude-haiku-4-5 maxSteps: 20 ``` ### Skip Draft PRs ```yaml theme={"system"} jobs: review: if: github.event.pull_request.draft == false ``` ### Monorepo: Pass Affected Packages Set environment variable in workflow: ```yaml theme={"system"} env: AFFECTED_PACKAGES: ${{ steps.detect.outputs.packages }} ``` Agent reads it at runtime: ````markdown theme={"system"} ## Step 1: Check Affected Packages Run this command to see which packages changed: \```bash echo $AFFECTED_PACKAGES \``` Focus your review on these packages only. ```` ### Custom Review Standards Edit `.github/agents/code-review.agentuse`: ```markdown theme={"system"} ## Security Checks - No hardcoded secrets - Input validation on endpoints ## Performance - No N+1 queries - Pagination on large lists ``` ## Debugging Enable debug mode in workflow: ```yaml theme={"system"} env: AGENTUSE_DEBUG: true ``` Common issues: | Issue | Solution | | - | - | | Agent times out | Increase timeout: `--timeout 600`, reduce maxSteps, use faster model | | Review not posting | Check `pull-requests: write` permission, verify API key | | Wrong files reviewed | Check path filters, verify filesystem permissions | Before pushing a workflow change, run the agent locally with [`agentuse test`](/guides/testing-agents): it exercises the whole run without posting comments or touching the repository. ## Security Limit agent access in CI: ```yaml theme={"system"} tools: bash: commands: - "gh pr *" # Only PR commands, not repo admin filesystem: - path: "src/**" # Don't expose .env, secrets/ permissions: [read] # Never [write] in CI ``` ## Cost Optimization ### Use Cheaper Models ```yaml theme={"system"} # For simple PRs model: anthropic:claude-haiku-4-5 # ~$0.01/review # For complex PRs model: anthropic:claude-sonnet-5 # ~$0.05/review ``` ### Reduce Token Usage ```yaml theme={"system"} maxSteps: 20 # Limit agent execution ``` In agent prompt: ```markdown theme={"system"} Focus only on changed files. Ignore tests unless broken. Provide concise summaries (2-3 sentences max per section). ``` ### Skip Low-Value PRs ```yaml theme={"system"} if: | github.event.pull_request.draft == false && github.event.pull_request.additions > 10 ``` ## Reference Common bash commands in agents: ```bash theme={"system"} # Get PR metadata gh pr view $PR_NUMBER --json title,body,files # Get diff gh pr diff $PR_NUMBER # Post comment gh pr comment $PR_NUMBER --body "Review complete" ``` ## Next Steps * **Customize agents**: Edit `.github/agents/*.agentuse` to match your workflow * **Add more workflows**: Create agents for deployment, testing, documentation * **Share across repos**: Use organization-level secrets and reusable workflows * See [Agent Design Patterns](/guides/agent-design-patterns) for advanced prompt engineering # Coding agent integrations Source: https://docs.agentuse.io/guides/coding-agent-integrations # Coding-agent integrations Use AgentUse from Codex, Claude Code, or Pi to turn a workflow in your current conversation into a reusable `.agentuse` file. The integration helps define the agent, prepare its runtime, and validate it before its first real run. ## Install Install the repository skill with the cross-host Agent Skills installer: ```bash theme={"system"} npx skills add agentuse/agentuse ``` This is the supported installation path for Codex, Claude Code, Cursor, Gemini CLI, GitHub Copilot, Goose, OpenCode, Windsurf, and other compatible hosts. New GitHub Releases do not contain separate coding-assistant packages. Start a new conversation after installation, then ask your assistant: ```text theme={"system"} Use AgentUse to turn the workflow we just completed into a reusable agent. ``` The installed discovery skill loads the `automate`, `core`, `creator`, and `tester` guidance from the installed AgentUse CLI. This keeps the authoring workflow aligned with the CLI version that will validate and run the resulting agent. The Pi-specific adapter is currently available to contributors from a source checkout. Run `bun run integrations:build`, install `./dist/integrations/pi` with Pi, and start a new session before using `/automate`. ## Validate and run the resulting agent The assistant loads current AgentUse guidance from the installed `agentuse` command. Running and validating the file requires the [AgentUse CLI](/installation) and a configured model provider. Review the generated source and setup requirements, then validate and test it: ```bash theme={"system"} agentuse doctor my-agent.agentuse agentuse test workflow my-agent.agentuse ``` See [testing agents](/guides/testing-agents) for test scope and limitations. Review the test output before a real run or enabling a schedule. ## Updates and local development Run `npx skills add agentuse/agentuse` again when you want the latest discovery skill. Its workflow guidance is version-matched at runtime by the AgentUse CLI. Contributors can run `bun run integrations:build` in the AgentUse repository. The generated local-development marketplaces use `agentuse-development`; their installation commands are in the repository's `integrations` READMEs. # Context Management Source: https://docs.agentuse.io/guides/context-management How AgentUse manages conversation context efficiently ## Overview AgentUse automatically manages conversation context to keep your agents running efficiently within token limits. This ensures long-running agents don't hit token limits while preserving important information. ## Automatic Compaction When conversations approach token limits, AgentUse automatically: 1. Detects when context usage exceeds the threshold 2. Compacts older messages into a concise summary 3. Preserves recent messages for continuity 4. Continues the conversation seamlessly Compaction happens transparently - your agent continues working without interruption. ## How It Works ### Token Tracking AgentUse tracks token usage throughout the conversation and compacts when approaching limits. The system uses character-based estimation (approximately 4 characters per token) and updates with actual usage data from the AI models. ### Compaction Strategy AgentUse uses a **summarization-based** approach: * Older messages are summarized using the same model as the agent * Recent messages are preserved intact for continuity * The summary captures key decisions, tool results, and progress * System prompts and tool definitions are always preserved ## Configuration ### Environment Variables Control context management globally using environment variables: ```bash theme={"system"} # Enable/disable context compaction (default: enabled) CONTEXT_COMPACTION=true # Set compaction threshold as percentage (default: 0.7 = 70%) COMPACTION_THRESHOLD=0.8 # Number of recent messages to preserve (default: 3) COMPACTION_KEEP_RECENT=5 # Compact at approval gates once active context reaches this size (default: 64000) APPROVAL_COMPACTION_MIN_TOKENS=64000 # Compact between LLM steps after tool calls once active context reaches this size (default: 64000) STEP_COMPACTION_MIN_TOKENS=64000 # Maximum agent steps before stopping (default: 1000) MAX_STEPS=2000 ``` ## What Gets Preserved ### Always Preserved * System prompts * Recent messages (last 3 by default, configurable) * Tool definitions remain available ### What Gets Compacted * Older conversation history * Previous tool calls and results * Assistant responses from earlier in the conversation The compaction creates a summary that preserves: * Key decisions and outcomes * Important tool results and errors * Current state and progress * Critical information needed for continuation ## Compaction Details ### Compaction Process When compaction is triggered: 1. Older messages are separated from recent ones 2. A summarization request is sent to the same model 3. The summary is created with a specialized system prompt 4. Recent messages are kept intact for continuity 5. The conversation continues with the compacted context ### Compaction Prompt The system uses this prompt for summarization: ``` You are a conversation summarizer. Summarize the following agent context concisely, preserving: 1. Key decisions and outcomes 2. Important tool results and errors 3. Current state and progress 4. Any critical information needed for continuation Be concise but comprehensive. ``` ## Monitoring ### Token Usage AgentUse displays token usage at the end of each run: ``` Tokens used: 12,450 ``` For agents with sub-agents: ``` Tokens used: 18,750 (main: 12,450, sub-agents: 6,300) ``` ### Compaction Events When compaction occurs, you'll see: ``` Context approaching limit (85% used). Compacting agent context... Context compacted successfully. Continuing... ``` ## Context Limits by Model AgentUse automatically detects context limits for different models: * **Anthropic models**: Retrieved from models.dev API * **OpenAI models**: Retrieved from models.dev API * **Unknown models**: Default to 32,000 tokens (conservative) The system updates context limits dynamically based on the latest model information. ## Performance Considerations Compaction requires an additional API call to summarize context, adding 1-3 seconds to processing time Compaction itself uses tokens (up to 2000 for the summary), but saves significantly more in long conversations Summaries preserve key information but some nuance may be lost. Recent messages remain fully intact ## Best Practices ### 1. Set Appropriate Thresholds ```bash theme={"system"} # Conservative (compact early, better context preservation) COMPACTION_THRESHOLD=0.6 # Aggressive (compact late, more context before compaction) COMPACTION_THRESHOLD=0.9 # Balanced (recommended default) COMPACTION_THRESHOLD=0.7 ``` ### 2. Adjust Recent Messages ```bash theme={"system"} # Keep more recent messages (better continuity, more tokens used) COMPACTION_KEEP_RECENT=5 # Keep fewer recent messages (more aggressive compaction) COMPACTION_KEEP_RECENT=2 ``` ### 3. Tune Approval-Boundary Compaction ```bash theme={"system"} # Compact earlier at human approval pauses to reduce repeated input spend APPROVAL_COMPACTION_MIN_TOKENS=32000 # Disable approval-boundary compaction but keep model-limit compaction APPROVAL_COMPACTION_MIN_TOKENS=0 ``` Approval-boundary compaction is useful for long runs with human review gates. It can compact before the model window is close to full because the goal is to avoid resending a large active context after the session resumes. ### 4. Tune Step-Boundary Compaction ```bash theme={"system"} # Compact less often during autonomous tool loops STEP_COMPACTION_MIN_TOKENS=128000 # Disable split-turn step compaction but keep approval and model-limit compaction STEP_COMPACTION_MIN_TOKENS=0 ``` Step-boundary compaction runs after the agent has already made at least one tool call. It preserves the initial prompt, then summarizes older context before later model calls in long single-turn runs. ### 5. Disable if Not Needed ```bash theme={"system"} # Disable for short conversations CONTEXT_COMPACTION=false ``` ### 6. Cap and Reduce Tool Output Every tool result is re-sent to the model on each subsequent step, so a single large output (a big diff, a verbose log, a huge file read) is one of the biggest drivers of input-token usage, often before compaction ever triggers. The most effective fix is to not generate the bloat in the first place, for example `git diff --stat` instead of a full `git diff` of high-churn files. As a safety net, direct JSON and text results over 10KB become a reusable handle with one partial value in `preview` and a compact `omitted` map showing what was left out at each jq-style path. The read-only `results` tool can return up to 20KB of selected text matches or JSON fields without repeating the preview or creating another handle. Provider-native and binary results using native model-output conversion remain on their direct delivery path. Bash separately retains a head + tail preview up to 30KB and saves a complete session artifact when its stream is larger. `read_file` defaults to 2000 lines. Tune these with the [Tool Output environment variables](/reference/environment-variables#tool-output): ```bash theme={"system"} # Allow larger bash output before truncation AGENTUSE_TOOL_MAX_OUTPUT_BYTES=61440 # Allow a larger direct result to remain inline AGENTUSE_TOOL_INLINE_RESULT_BYTES=16384 # Allow larger intentional result queries AGENTUSE_RESULT_QUERY_BYTES=32768 # Return more lines per read_file call AGENTUSE_TOOL_MAX_LINES=5000 ``` ## Technical Details ### Token Estimation * Uses character-based estimation: \~4 characters per token * Updates with actual token usage from AI models * Tracks both input and output tokens ### Model Integration * Context limits are fetched from models.dev API * Falls back to conservative 32,000 token limit for unknown models * Caches model information for 24 hours ### Error Handling * If compaction fails, creates a fallback summary * Continues execution even if compaction encounters errors * Logs compaction failures for debugging ## Troubleshooting * Increase `COMPACTION_KEEP_RECENT` for more preserved messages * Lower `COMPACTION_THRESHOLD` to compact earlier with more context * The same model is used for summarization, so quality should be consistent * Lower `COMPACTION_THRESHOLD` to compact earlier * Reduce `COMPACTION_KEEP_RECENT` for more aggressive compaction * Consider the model's actual context limit vs your usage * Check that `CONTEXT_COMPACTION` is not set to 'false' * Verify the model supports the context limits being used * Check logs for compaction errors ## Example: Long-Running Agent ```yaml theme={"system"} --- name: data-analyzer model: anthropic:claude-sonnet-5 --- You analyze large datasets over extended periods. Process data systematically and maintain detailed progress tracking. ``` ```bash theme={"system"} # Configure for long-running analysis export MAX_STEPS=2000 export COMPACTION_THRESHOLD=0.8 export COMPACTION_KEEP_RECENT=5 # Run the agent agentuse run data-analyzer.agentuse ``` The agent will automatically: * Track token usage throughout the analysis * Compact context when approaching 80% of the model's limit * Preserve the last 5 messages for continuity * Continue analysis without interruption ## Next Steps Build efficient agents Configuration options # Creating Agents Source: https://docs.agentuse.io/guides/creating-agents Define AI agents in markdown and run on cron, CI/CD, or serverless ## Agent File Format AgentUse agents are markdown files with a `.agentuse` extension. They consist of: 1. **Frontmatter** - YAML configuration 2. **Agent Prompt** - Agent instructions ## Basic Structure ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 description: "General-purpose AI assistant for various tasks" --- You are a helpful assistant. ## Task Help the user with their request. ``` The agent name is automatically derived from the filename. You don't need to specify it in the frontmatter. ## Frontmatter Configuration ### Required Field The AI model to use. Format: `provider:model-name` Examples: * `anthropic:claude-opus-5` * `anthropic:claude-sonnet-5` * `anthropic:claude-haiku-4-5` * `openai:gpt-5.6` * `openai:gpt-5.4-mini` * `openai:gpt-5.4-nano` * `openrouter:z-ai/glm-5.3` You can also specify environment variable suffixes: * `anthropic:claude-sonnet-5:dev` (uses ANTHROPIC\_API\_KEY\_DEV) * `openai:gpt-5.6:prod` (uses OPENAI\_API\_KEY\_PROD) * `openai:gpt-5.6:OPENAI_API_KEY_PERSONAL` (uses specific env var) ### Optional Fields A concise description of the agent's purpose. This appears in: * Tool descriptions when used as a sub-agent * CLI output when running the agent * Plugin events for logging Best practices: * Keep under 80-120 characters * Be action-oriented * Focus on primary capability MCP server configurations. Each server can have: * `command` + `args`: For stdio-based servers * `url`: For HTTP-based servers * `env`: Environment variables for the server * `requiredEnvVars`: Required environment variables (fail if missing) * `allowedEnvVars`: Optional environment variables to pass * `allowedTools`: Array of tool names/patterns to load; every other tool stays off * `disallowedTools`: Array of tool names/patterns to exclude * `auth`: Authentication for HTTP servers * `headers`: HTTP headers for HTTP servers List of sub-agent configurations. Each sub-agent can have: * `path`: Path to the agent file (required) * `name`: Optional custom name for the sub-agent * `maxSteps`: Optional maximum number of steps the sub-agent can take ## MCP Server Integration Connect to Model Context Protocol servers for external tools and data sources: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: filesystem: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-filesystem", "."] --- ``` See the complete reference for stdio servers, HTTP servers, environment variables, authentication, and tool restrictions. ## Using Sub-Agents Agents can delegate to other agents. All sub-agent paths are resolved relative to the parent agent file's directory: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: "Coordinator agent that manages research and writing tasks" subagents: - path: ./research-agent.agentuse # Same directory as parent name: "research_specialist" # Optional custom name maxSteps: 100 # Optional: limit sub-agent steps - path: ../utils/writer-agent.agentuse # Parent directory - path: ./team/editor.agentuse # Subdirectory --- You coordinate between research and writing agents. ## Task When asked to create content: 1. Use the research agent to gather information 2. Use the writer agent to create the content ``` Sub-agents can be local files or HTTPS URLs. Remote agents must end with `.agentuse` extension. ## Environment Variables Environment variables configure API keys, behavior settings, and MCP server credentials. See the complete reference for API keys, behavior control, MCP server configuration, and security best practices. ## Runtime Customization You can append additional prompts when running agents without modifying the agent file: ```bash theme={"system"} # Run with base instructions agentuse run code-review.agentuse # Add specific focus areas agentuse run code-review.agentuse "focus on security and performance" # Customize behavior temporarily agentuse run assistant.agentuse "respond in a formal tone" # Provide additional context agentuse run analyzer.agentuse "use production database settings" ``` This is useful for: * Testing different approaches without editing files * Providing context-specific instructions * Reusing agents with slight variations * Quick experimentation ## Examples For a comprehensive collection of agent examples, including data analysis, code review, API integration, and more, visit the [AgentUse Templates](https://github.com/agentuse/agentuse/tree/main/templates/agents). ## Project Structure and Path Resolution ### Project Root Detection AgentUse automatically detects your project root by searching upward for `.git/`, `.agentuse/`, or `package.json`. ### Recommended Project Structure ``` my-agent-project/ ├── .env # Project-wide environment variables ├── .agentuse/ │ └── plugins/ # Custom plugins │ └── logger.js ├── agents/ │ ├── main.agentuse # Main orchestrator │ ├── research/ │ │ ├── web.agentuse │ │ └── docs.agentuse │ └── processing/ │ ├── analyzer.agentuse │ └── formatter.agentuse ├── utils/ │ ├── helper.agentuse │ └── validator.agentuse └── tools/ └── custom-mcp-server # Custom MCP server executable ``` ### Path Resolution All paths (subagents, MCP server commands) are resolved relative to the **agent file's directory**, ensuring portability. See [Agent Syntax - Subagents](/reference/agent-syntax#subagents) for complete path resolution examples. ### Benefits of This Structure 1. **Portability**: Share entire agent projects without breaking paths 2. **Organization**: Clear separation of concerns 3. **Reusability**: Utils and helpers can be shared across agents 4. **Version Control**: Everything in one repository 5. **Environment Management**: Single `.env` file for all agents ## Validate Before You Run It for Real A new agent has two things worth checking before it touches anything that matters. `agentuse doctor` checks the configuration: skills that don't exist, skills with no grants, commands the agent's own instructions mention but that it was never granted, and what the whole prompt costs per model request. ```bash theme={"system"} agentuse doctor my-agent.agentuse ``` `agentuse test` checks the behaviour. It runs the agent end to end in mock mode: side effects are fabricated rather than executed, approval gates resolve automatically so the run finishes unattended, and stores are isolated from your real data. ```bash theme={"system"} agentuse test my-agent.agentuse ``` The full edit-test-inspect loop, mock scope, approval branches, and what mock mode does and does not prove. ## Next Steps Learn about delegating tasks to other agents Best practices and patterns for building agents See more agent examples # Learning Source: https://docs.agentuse.io/guides/learning Capture what reviewers teach an agent, vet it, and apply the best of it in future runs The `learning` configuration, capture behavior, and corrections-file format are experimental and may change without migration. Discuss feedback in [GitHub Discussions](https://github.com/agentuse/agentuse/discussions). ## What is Learning? Learning lets reviewers deliberately teach an agent from real work. Leave a comment at review time and check **Learn from this comment** when the feedback should help in similar future situations. An unchecked comment revises the current run only. AgentUse turns checked feedback into concise, appropriately scoped guidance, stores it in a readable markdown file, and applies it to later runs when relevant. A learning is durable guidance, not an unconditional rule: the current task and the agent's authored instructions still take precedence. That deliberate human choice is the default. Automatic observation of a run is advanced capability and remains available through explicit capture channels, but it is never enabled merely by writing `learning: true`. Everything a channel produces then passes a **vet** against the agent's complete instructions before it can reach a future run, and everything that reaches a future run is stamped with the version of those instructions it was checked against. ## Quick Start A single switch applies deliberate human learnings on future runs: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 approval: true # exposes review comments and the Learn checkbox learning: true # apply checked feedback on similar future runs --- # Blog Writer Write short productivity blog posts. ## Guidelines - Start with a relatable hook - Include 3 actionable tips ``` During review, write the correction and check **Learn from this comment**. The same operation is available as `--remember` in the CLI. AgentUse grounds the comment in the work being reviewed, vets it against the agent's instructions, and stores it. Unchecked comments are never added to durable memory. `learning: true` is sugar for `{ capture: true, apply: true }`: it applies explicitly saved human learnings, while automatic observation remains off. Learnings accumulate in a learnings file inside the AgentUse state directory, not in your repository. `agentuse learnings ./blog-writer.agentuse --path` prints where; see [Storage](#storage). `capture: true` used to mean free-form auto-capture. As of v0.19.0 it enables no automatic observation channels. Human feedback is saved through the Learn checkbox, `--remember`, or manual add. See [Upgrading an existing agent](#upgrading-an-existing-agent). ## Store Without Applying To collect explicitly selected human learnings without putting them into future prompts yet: ```yaml theme={"system"} learning: capture: true apply: false # accumulate for manual review, never auto-inject ``` The Learn checkbox and `--remember` still save guidance. `apply: false` only keeps it out of future prompts until you turn application back on. ## Advanced: Automatic Capture Channels Most agents should stop at `learning: true`. Use capture channels only when you also want AgentUse to learn without a reviewer checking Learn on a comment. ```yaml theme={"system"} learning: capture: addons: [tool-errors] # typed, structurally-verified channels custom: | # scoped free-form capture, built-in evaluator Only note selector changes. # agent: ./capture.agentuse # instead of custom: replace the evaluator apply: true max: 15 ``` `capture: {}` is the same as `capture: true`. This mirrors the [verify](/guides/verify) schema deliberately: `custom` plays the role of `verify.criteria` (tune the built-in), `agent` plays the role of `verify.judge` (replace it), and setting both is a parse error with the same message style. ### deliberate human learning The Learn checkbox, `--remember`, and manual add are the standard human path. They are not automatic capture channels: the reviewer explicitly decides which comments become durable. Ordinary approval comments affect the current run only. ### `tool-errors` (addon) ```yaml theme={"system"} learning: capture: addons: [tool-errors] ``` Learns a failed tool call followed by a **corrected** call and a confirmed success. Its value is that the verification happens **in code**, not in a prompt: a record is stored only when the run's trace contains the failed call, a later successful call of the same tool, and a different input on the retry. A retry with identical input that happened to work is flakiness, not a lesson, and is not captured. The stored record carries the tool, a normalized failure signature, and both calls as evidence: ```markdown theme={"system"} ### [error-fix] browser.uploadFile: files.length remained # When browser.uploadFile fails with "files.length remained #", use the corrected call shape that succeeded: {"path":"/Users/me/shot.png"} ``` Because these records capture mechanics rather than policy, they cannot conflict with your instructions, so they skip the model-judged vet below. They dedupe by `(tool, failure signature)` and supersede structurally (one record per failure mode, replaced when a better recovery is observed), and they never go through the free-text merge path in [tidy](#tidying-up). ### `custom` (scoped free-form) ```yaml theme={"system"} learning: capture: custom: | Only capture rules about selectors and page structure. Ignore anything about content or tone. ``` The built-in evaluator, now allowed to extract from the execution itself and scoped by your guidance text. Free-form candidates carry no structural proof, so they rest entirely on the [vet](#every-candidate-is-vetted), which is why the channel is opt-in and its candidates never skip vetting. ### `agent` (evaluator replacement) ```yaml theme={"system"} learning: capture: agent: ./capture.agentuse ``` An `.agentuse` file replaces the built-in evaluator for free-form capture, the same pattern as `verify.judge`. The path resolves relative to the agent file that declares it. The capture agent receives the run's evidence and the learnings the agent already carries with their ids, and records its result by calling `submit_learnings` once with 0-5 candidates: ```yaml theme={"system"} --- model: anthropic:claude-haiku-4-5 --- # Capture Evaluator Read the run and record only rules about API pagination and rate limits. Never record anything about the content the agent produced. ``` Replacing the evaluator does not buy a bypass. Its candidates still pass the common vet, provenance stamping, and lifecycle validation. Deliberate human learning stays on the separate Learn/`--remember` path either way; it never depends on a user-supplied capture agent behaving. A nested `learning:` or `verify:` block on the capture agent is ignored (a helper pass must not recurse into a tree of helper passes), and a capture agent that suspends on an approval gate is an error. `learning: true` makes no post-run evaluator call. The built-in evaluator runs only when `capture.custom` is configured; use `capture.agent` when that automatic judgment is genuinely domain-specific. ## Configuration Options | Option | Type | Description | | - | - | - | | `learning: true` | `boolean` | Apply learnings explicitly saved through Learn, `--remember`, or manual add. Automatic observation remains off. | | `capture` | `boolean \| object` | Automatic observation configuration. `true` or `{}` enables no automatic channel; name `addons`, `custom`, or `agent` to opt in. Default `true` for compatibility. | | `capture.addons` | `string[]` | Typed, structurally-verified channels. `tool-errors` is the only entry today. Defaults to `[]`. | | `capture.custom` | `string` | Guidance that scopes free-form observation capture through the built-in evaluator. Mutually exclusive with `agent`. | | `capture.agent` | `string` | Path to an `.agentuse` file that replaces the built-in evaluator, relative to this agent file. Mutually exclusive with `custom`. | | `apply` | `boolean` | Inject vetted, active learnings into instructions before each run. Defaults to `true`. | | `max` | `number` | How many rules this agent keeps, and therefore how many apply per run. Defaults to `15`, range 1-50. Enforced when capture writes, not just when rules are injected, see [An agent keeps 15 rules](#an-agent-keeps-15-rules-not-15-of-many). Each one is paid for on every model request; `agentuse doctor` prints the token cost. | | `model` | `string` | Model for the helper calls (capture, vet, and tidy-up). Defaults to the agent's own model. | **`criteria` was removed in v0.19.0** and is a hard parse error: ``` "criteria" was removed — free-form capture is opt-in now. To restore scoped free-form capture, move it to capture: { custom: "..." } ``` The only faithful mapping would keep free-form policy capture running automatically, which is exactly what the redesign exists to stop, so the rewrite is yours to make consciously. Setting both `custom` and `agent` is likewise a parse error: `set either "custom" (built-in evaluator) or "agent" (agent file), not both`. Two keys were removed in v0.17.0 and remain rejected by name: `evaluate` (long deprecated) and `file` (a custom learnings path, now that learnings live outside your repository, see [Storage](#storage)). An agent file still carrying one fails loudly rather than quietly ignoring it. ## Every candidate is vetted Nothing becomes active on the strength of having been extracted. Every free-form candidate, corrections included, is checked against the agent's **complete** instructions, the rules already in force, and the run's own trace, before it can be injected into anything. | Verdict | What it means | What happens | | - | - | - | | **pass** | Genuinely new, consistent with the contract and the rules in force, and supported by the run | Becomes active | | **duplicate** | Restates something the instructions or an active rule already say, in any wording | Model-authored: rejected. Human correction: quarantined | | **contradiction** | Conflicts with the instructions or an active rule, or narrows one so far the two cannot both be satisfied | Quarantined, with the conflicting text named | | **ungrounded** | The trace contradicts the claim, or does not contain the events it describes | Rejected. Never raised against a human-authored entry | Two properties are worth stating plainly: * **Human corrections are never dropped.** A reviewer's rule that fails the vet is quarantined with the reason, not discarded. If the vet call itself fails, corrections are stored active and observation candidates are dropped. Free-form capture's entire safety case is the vet, so it fails closed while human input fails open. * **The vet sees the whole contract.** The fixed 3,000-character truncation that used to hide every rule past the cut is gone. On any real agent that truncation is what let the evaluator "rediscover" an explicit instruction as a brand-new learning. ### Quarantine A quarantined entry is set aside, never injected, and never deleted. It stays visible with its reason in `agentuse learnings `, the serve UI's Learnings panel, and `agentuse doctor`: ``` 2 learnings quarantined (failed the vet, never injected): [warning] Reuse the prior run item on same-day re-invocation — contradicts the contract: "Every invocation creates one new run item and terminalizes it" [tip] Always resolve ids with store_list — duplicates the contract: "a type name is not an item ID; never call store_get on one" ``` The second one is a reviewer's own note. A model-authored duplicate would have been rejected outright, with nothing lost: the rule already exists. A human wrote that one, so it is kept and shown instead. The fix is one of two things, and the reason line tells you which: correct the agent file so the rule is no longer in conflict, or discard the rule. Typed `tool-errors` records skip this step. They are verified structurally in code, and they describe mechanics rather than policy, so there is nothing for them to contradict. ## Rules are stamped with the instructions they were checked against Every stored learning records the hash of the agent instructions it was captured (or last re-vetted) against, alongside its channel, source session, and evidence. The hash covers your own instructions with the machine-managed [graduated block](#what-makes-a-learning-permanent) excised, so a rule graduating never marks every other rule stale. When you rewrite the agent file, the hash no longer matches and the affected rules go **stale**: * Stale rules are **held out of injection**. A rule vetted against instructions that no longer exist does not get to keep applying unexamined. * The next capture or `agentuse learnings tidy` **re-vets** them against the current instructions: passes are re-stamped and start injecting again, failures are quarantined with the reason. Nothing is deleted. * Rules with **no hash at all**, anything captured before v0.19.0, are *not* stale. They stay injectable until the first capture or tidy backfills them. `agentuse doctor` says so when it matters: ``` learned guidelines: 12 of 15 applied, ~1.8k tokens/model request 3 learnings are stale: the instructions changed since they were vetted. They are held out of injection until the next capture or tidy re-vets them. ``` ## Storage Learnings are stored in the AgentUse state directory, alongside session logs, not in your repository: ``` $AGENTUSE_DATA_DIR/project/{project-hash}/ ├── session/ # execution logs ├── consolidations/ # tidy-up undo snapshots └── learnings/ └── agents/blog/write.learnings.md # one agent's learnings ``` `$AGENTUSE_DATA_DIR` defaults to `~/.local/share/agentuse`; when it is unset, `$XDG_DATA_HOME/agentuse` remains the standards-compatible fallback. `{project-hash}` is a digest of your git root, so two repositories that both contain `agents/blog/write.agentuse` keep separate learnings, and one agent resolves to one file whichever directory you run it from. The file itself is named after the agent's path relative to the project root, so subdirectories are preserved. That path is not one you can type from memory, so nothing asks you to: ```bash theme={"system"} agentuse learnings ./blog-writer.agentuse --path # print it agentuse learnings ./blog-writer.agentuse --edit # open it in $EDITOR ``` `agentuse doctor ./blog-writer.agentuse` prints it too, as does `agentuse learnings ./blog-writer.agentuse --json` in its `file` field. Every learnings file also records which agent it belongs to, on the line under its heading: ```markdown theme={"system"} # Learnings for write ``` ### Why it is not next to your agent file Every run rewrites this file, not only the runs that capture something: injecting a learning updates its counters. Kept in the repository, that is a permanently dirty working tree and a stream of commits carrying no decision. The file was never meant to be the durable artifact. It is a staging buffer; your agent file is the thing that gets diffed and reviewed, and [graduation](#what-makes-a-learning-permanent) is how a proven learning crosses over into it. **The trade:** learnings are no longer in git. There is no backup, no teammate sharing, and nothing survives a machine rebuild. The state directory holds locally generated data, like session logs. Graduation is the supported path into version control: a rule that has earned its way into your `.agentuse` file is committed, reviewable, and travels with the repository. Renaming or moving an agent file also starts its learnings over, because the file is keyed by the agent's path. Rules already graduated into the agent file move with it and are unaffected. ### Moving learnings from before v0.17.0 Learnings used to live beside the agent file, named after it: `blog-writer.agentuse` paired with `blog-writer.agentuse.learnings.md`. That location is no longer read, not as a fallback, not once. Move them: ```bash theme={"system"} agentuse learnings migrate --all git commit -am "chore: move learnings to the agentuse state dir" ``` ``` agentuse learnings migrate [|--all] [--dry-run] [--keep-source|--delete-source] ``` Name one agent file, or pass `--all` to walk every `.agentuse` file under the project root. **It copies first and asks before deleting anything.** Once the copies are on disk it lists the originals and asks once whether to remove them; anything other than an explicit yes leaves them alone. Deleting files out of your repository is not something a migration should do on its own, so the destructive half is always yours to confirm. `--delete-source` answers yes up front (for scripts and non-interactive shells, where nothing is ever deleted without it), `--keep-source` answers no, and `--dry-run` reports what would be copied without writing anything. It refuses rather than merges when the destination already holds learnings, and it lists any `*.learnings.md` with no agent file of that name as **orphaned, not migrated**. Those are usually left behind by a rename, and this is the only place they are ever mentioned. If you skip the migration, the agent simply starts with an empty learnings store. Graduated rules are unaffected. The old files sit inert until you delete them, which is itself the point: inert means they stop churning. A run that finds learnings stranded at the old location says so once, and so do `agentuse doctor` and the learnings panel in the serve web UI: ``` learnings found at the old location for agents/blog/write.agentuse agents/blog/write.agentuse.learnings.md No longer read. Move them: agentuse learnings migrate --all ``` This reads only whether that file exists, never what is in it, so the agent behaves identically with or without it. It keeps saying so even after the agent has captured new learnings into the new location, that is exactly when a populated panel makes a half-migrated agent look healthy. ## How capture works After a run finishes with an automatic channel configured: 1. **Gather candidates per channel.** `custom` uses the built-in evaluator, `agent` runs the replacement evaluator, and `tool-errors` scans the run's tool traces in code. Deliberate human learnings are saved immediately by the Learn/`--remember` path rather than inferred here. 2. **Vet the free-form candidates** against the complete contract, the rules in force, and the trace. Passes become active, contradictions and failed human corrections are quarantined, and model-authored duplicates and ungrounded claims are rejected. 3. **Stamp provenance** (channel, source session, evidence, and the instruction hash) and write to the store, enforcing `max` ([the cap](#an-agent-keeps-15-rules-not-15-of-many)). 4. **Re-vet stored rules the contract has moved out from under**: anything stale, and anything with no hash at all, is checked against the current instructions and either re-stamped or quarantined. This is what backfills a pre-v0.19.0 store the first time capture runs after an upgrade. The result is reported in the run's output and in the session log: ``` Extracted 2 learning(s), 1 quarantined → ~/.local/share/agentuse/project/…/blog-writer.learnings.md ``` ## Deliberate Learning from Review Comments At an [Approval Gate](/guides/approval-gates), a comment normally revises the current run and nothing more. Check **Learn from this comment** when AgentUse should remember the feedback for similar future situations. That explicit choice is what makes the comment durable. ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 approval: true learning: true --- # Blog Writer ... ``` The same comment serves both purposes: it revises the current work, and when checked, the learning processor grounds it in the reviewed output and rewrites it as appropriately scoped guidance. For example, “this intro is too salesy” can become “For informational posts, keep intros factual rather than promotional,” not the universal rule “Never use promotional language.” Checking Learn works even when the agent has no learning configuration; the guidance is stored but reaches future runs only when `learning.apply` is enabled. Explicit human learnings are stored as `src:manual` and rank ahead of automatic observations. The CLI equivalent is: ```bash theme={"system"} agentuse sessions resume 01K... \ --comment "Please revise this pass with citations" \ --remember "Always include source links before publishing." ``` A note you write this way is reconciled against the rules the agent already carries, exactly as a captured learning is. If it restates or **contradicts** one of them, it replaces that rule rather than being filed beside it, and the run names what it replaced: ``` [Learning] Replaced an earlier rule: "Cite the source inline" (archived, id:a1b2c3d4) ``` This matters most on this path, because `--remember` is what you reach for when you are correcting an earlier note of your own. Left unreconciled, the rule and its own correction both stay in force, and the agent has to satisfy two instructions that disagree. A note can also collide with the agent file itself rather than with another rule. It is saved either way, but quarantined rather than injected, and the run says which instruction it conflicts with: ``` [Learning] Saved but quarantined "Publish drafts without review": contradicts the contract: "Never publish without an approval gate". It will not be injected; resolve the conflict in ./blog-writer.agentuse or discard the rule. ``` ## How Application Works On next run or approval resume (when `apply: true`): 1. Loads the agent's active rules from storage, skipping quarantined and [stale](#rules-are-stamped-with-the-instructions-they-were-checked-against) ones 2. Injects the top `max` of them (15 by default) as a `## Relevant Learnings` section 3. Counts the injection against each rule's `injectedCount` The runtime tells the model to apply each learning only when its situation is relevant, preserve its intended scope, and never let it override the current task or authored agent instructions. A clearly relevant learning can refine a soft skill default without becoming a universal checklist item. Learnings that have [graduated](#tidying-up) live in your agent file's own `## Learned Guidance` block. Graduation changes storage and reviewability, not these contextual semantics. **`injectedCount` counts cost, not value.** It is how many runs a rule was paid for on, and it is never evidence the rule worked. The effectiveness signal is `approvedRuns` (runs the rule was in force for that ended in an approval with no comment), and that is what [graduation](#what-makes-a-learning-permanent) is gated on. The store field was named `applied:` before v0.19.0 and is read as an alias; files are rewritten with `injected:` on the next save. ### An agent keeps 15 rules, not 15 of many `max` is how many rules an agent **keeps**, not how many of a larger pile get injected. Capture enforces it when it writes, so the set stays small enough that every rule in it has been weighed against every other one. That last part is the reason for the cap, and it matters more than the token cost. While the store could grow without limit and only the top slice was injected, nothing ever compared one rule against another. An agent could hold two corrections that could not both be satisfied - captured weeks apart, from separate rejections, each perfectly reasonable alone - and nothing would notice. So when the set is full, a new learning has to be paid for. In order: 1. **Fold.** The evaluator sees every rule the agent already carries, each with its id, and is asked to reconcile rather than merely avoid duplicating. If its new learning restates, sharpens, or *contradicts* an existing rule, it returns **one** rule that satisfies both, naming the id it replaces. The replaced rule is retired, not deleted. 2. **Trade.** Nothing related in the set? The weakest auto-extracted rule is retired to make room - but only if the new rule is worth more than the one it displaces, so the set keeps the best rules rather than the last ones. Once the set is full this applies to reviewer corrections too. They cannot be traded away, so for them the answer is always to fold. That is the part that keeps the set at its size. Folding is not picking a winner. The merged wording has to carry every case the originals covered, and the model writing it can see all of them. Two things are never evicted: a rule you wrote or approved, and a rule you have repeated. A repeat means the wording is not landing, which is a reason to rewrite it, not to drop it. Precedence within the set is unchanged - rules you saved yourself, then reviewer comments, then self-extracted - with the most recent first inside each group. ### When a correction does not fit If the capture model returns a correction without naming a rule to fold it into, and no auto-extracted rule is left to trade away, the correction is kept anyway, outside the cap. It is not dropped - losing a reviewer's correction because a helper model failed to pick an id would be worse. But a rule outside the cap is never injected, so the run tells you plainly: ``` learned guidelines: 15 of 16 applied, ~1.8k tokens/model request 1 correction(s) sit outside this agent's 15-rule limit and do NOT reach it - they could not be folded into an existing rule, and no auto-extracted rule was left to trade away. Fold the set down: agentuse learnings tidy ./blog-writer.agentuse ``` This should be rare. If it is not, the corrections are carrying what your agent file should have said, and the fix is in the instructions rather than the store. A rule outside the cap cannot recover on its own. It is never injected, so nothing about it is ever observed, and it is a human correction so it is never evicted either. Left alone it stays there having no effect. This is why a full set folds rather than grows - an earlier design let corrections accumulate past the cap, and one agent reached 70 of them, permanently unreachable. A store written before the cap was enforced can hold far more than `max`. The first capture after upgrading drains the excess by retiring auto-extracted rules from the bottom of the ranking - the ones that were not reaching the model anyway. Nothing is deleted, and rules you wrote or repeated are never touched, so the drain tends to *promote* a starved correction into force. ## Tidying up When learnings outgrow the cap, or the agent file has been rewritten under them, one action gets them back in order: ```bash theme={"system"} agentuse learnings tidy ./blog-writer.agentuse ``` or the **Tidy up** button in the serve UI, on the session view and the agent's Learnings tab. Both run the same thing. It makes six kinds of change: * **re-vet** every rule that is stale or was never vetted against the current instructions, re-stamping the ones that still hold and **quarantining** the ones that no longer do, with the reason * **merge** near-duplicates into one rule * **rewrite** a learning you have repeated, a repeat means the wording is not landing, so restating it sharply is the fix * **retire** what has been superseded. A retired rule is removed, and re-asserting it later simply adds it back * **graduate** the learnings that have proven themselves into the agent's own instructions, where they apply on every run and cost no cap slot * **rewrite the permanent block** in your agent file as one document, combining rules that overlap and dropping any another rule now fully states The re-vet pass is why a tidy-up is worth running after you edit an agent file, even on a set that is comfortably under the cap: it is what gets stale rules injecting again, and what backfills a store captured before v0.19.0. That last change is the only thing that ever makes the permanent block smaller. Graduation alone only ever added to it, so on a long-running agent it accumulated the same way the staging file did, and more expensively: those rules apply on every single run. The rewrite reads the whole block at once, which is what lets it combine two rules that are halves of one procedure, or fold a correction into the rule it corrects. Two things check the result, because it edits a file you wrote: * **Nothing may vanish.** Every rule that goes in must come back inside some rule, or be named as dropped with a reason. If one goes missing the whole rewrite is discarded rather than written. * **Nothing may be quietly summarised away.** Each rewritten rule is then audited against the originals it claims, and asked what instructions it no longer carries, a case, a threshold, an exception, a worked example. Anything reported missing puts those originals back untouched, and the rest of the rewrite still applies. The audit asks about meaning, not length. A merge that halves the wording while keeping every instruction passes; one that keeps the length but drops an exception does not. That matters because the tidy-up is supposed to make the block *denser*, shorter for the same instructions, and a length-based check would have blocked exactly the merges worth having. It applies immediately and then shows you what changed: a summary, the rules that became permanent named individually, each edit to the permanent block, and the diff of **both** files. Undo with `agentuse learnings undo ./blog-writer.agentuse` or the Undo button, which covers the re-vet pass along with everything else. ``` $ agentuse learnings tidy ./blog-writer.agentuse reading 58 learnings to see what repeats… rewriting 4 rules… pass 2: reading 41 learnings to see what repeats… pass 2: rewriting 3 rules… writing both files… Done 3 merged, 1 rewritten, 12 retired, 2 quarantined, 9 now permanent — 58 → 15 in force ``` Each pass reads every learning still in force, so a pass takes about a minute. It runs in two stages: first it decides which learnings relate to which, in small groups weighed in parallel, then it writes each replacement rule in its own call, again in parallel. **One tidy-up keeps going until another pass would not help.** A single pass is cautious by design, and it compares learnings in small groups, so two duplicates that never share a group both survive it. Rather than making you press the button again, the tidy-up goes back over whatever is left, up to five passes, and stops as soon as a pass frees no slot. It all happens in memory: both files are written once at the end, so however many passes it took, one tidy-up is one Undo. In the web UI it runs on its own page, counting the rules as it writes them and naming the pass it is on; leaving that page does not stop it, and the result waits there with its Undo button. The agent's Learnings tab links back to the last tidy-up (`Tidied up 5m ago, see what changed or undo it`) for as long as it is undoable, whether it was run from the browser or the terminal. ### When it ends still over the cap That is a normal ending for a well-used agent, not a failure, so the result says which rule kept each learning that is still in force: ``` Still 20 over the cap, and that is as far as tidying up can take it. The rest are still there for a reason: 18 say different things, so there is nothing left to merge them into 2 are less than 14 days old, and a new learning gets that long to prove itself before it can be retired None of the corrections still in force can move into the agent file yet. That takes 3 runs approved without a comment, or 10 runs in force; the closest of them has been applied in 6. They become eligible on their own as the agent keeps running. ``` The counts add up to the number still in force, so nothing is unaccounted for. When pressing again genuinely would get further (the five passes ran out, or a group of learnings could not be planned), it says so instead. "You wrote it by hand" is not on that list, and used to be. A rule you typed was once exempt from retirement entirely, which sounds protective and is not: the only thing that can retire one of your rules is a later correction of your own, and a veto put that out of reach. One agent reached 85 corrections it could neither apply nor consolidate. Authorship now weighs heavily in the judgement instead of ending it. What still cannot be retired is a rule you have **repeated**, a repeat means the wording is not landing, so it gets sharpened rather than dropped. Inspect first with `agentuse learnings ./blog-writer.agentuse` (a list by status) or `agentuse learnings tidy ./blog-writer.agentuse --dry-run` (the plan and both diffs, nothing written). ### What makes a learning permanent Graduation is earned, not guessed. A learning qualifies when any of: * **you repeated it** (`re:` above zero), saying the same thing twice is the clearest evidence a rule matters, or * **it was in force across 3 runs you approved without leaving a comment.** Approving with no notes is a vote for every rule that applied that run; a run you commented on credits nothing, because you had to correct something, or * **it has been in force for 10 runs.** Surviving that long without ever being contradicted is weaker evidence than the other two, but it is evidence, and without it a rule nobody comments on either way waits forever. Writing a rule yourself does not graduate it on its own. It used to, and the result was that hand-written rules went permanent before they had ever been checked against the rules already there. Graduated rules are written into your agent file inside a marked block: ```markdown theme={"system"} ## Learned Guidance Guidance consolidated from previous runs. Apply each learning only when its situation is relevant. Preserve its intended scope; do not turn examples or past incidents into universal requirements. The current task and the agent's authored instructions take precedence. A clearly relevant learning may refine a soft skill default: - [tip] Cite sources before publishing ``` Only the bytes inside the markers ever change; your frontmatter, comments and formatting are left exactly as they were. Because the block is part of the agent file, it is diffable, reviewable in a pull request, and readable by a teammate who wants to know what this agent has been taught. Re-running the tidy-up replaces the block rather than appending a second copy. The block in the file is the source of truth for these rules, not a printout of one held elsewhere: the tidy-up reads it back before every edit, so wording you change by hand survives, and is what the next rewrite works from. The block is also excluded from the instruction hash, so a rule graduating never makes the rest of the set stale. Rules still on probation are injected under a separate `## Relevant Learnings` heading, so the two tiers never collide. Graduation is skipped, and the result says so, when the agent file is not writable. Nothing else can stop it: there is one learnings file per agent, so making a rule permanent never affects another agent. ## Seeing what capture is doing "Capture is producing junk" should be measurable, not anecdotal. Three surfaces show the same numbers. `agentuse learnings ` lists every rule by status, grouped: ``` Applied (12 of 15) applied [warning] Keep intros factual src:approval · injected:31 · ch:corrections · approved:4 · ready to make permanent · 2026-07-02 · id:a1b2c3d4 Stale — instructions changed, awaiting re-vet (3) dormant [tip] Cite the primary source, never a summary src:approval · injected:12 · ch:corrections · 2026-07-19 · id:e5f6g7h8 Quarantined (2) quarantined [tip] Reuse the prior run item on same-day re-invocation src:auto · injected:0 · ch:custom · 2026-08-14 · id:i9j0k1l2 why: contradicts the contract: "Every invocation creates one new run item" ``` `agentuse doctor ` adds the per-channel breakdown and the token cost: ``` learned guidelines: 12 of 15 applied, ~1.8k tokens/model request 3 learnings are stale: the instructions changed since they were vetted. They are held out of injection until the next capture or tidy re-vets them. learnings file: ~/.local/share/agentuse/project/a1b2c3/learnings/blog-writer.learnings.md by channel: corrections:11, tool-errors:4, custom:2, legacy:3 2 learnings quarantined (failed the vet, never injected): [tip] Reuse the prior run item on same-day re-invocation — contradicts the contract: "Every invocation creates one new run item" ``` `legacy` in that breakdown is entries captured before channels existed. The serve UI's Learnings panel shows the same states with quarantine reasons inline, and links to the last tidy-up. Everything is agent-operable: `agentuse learnings --json` reports `cap`, `active`, `injected`, `dormant`, `stale`, and `quarantined` counts at the top level, and each entry carries its full record plus computed `state`, `injected`, and `stale` flags. `agentuse learnings tidy --dry-run` prints the plan without writing. No step in the lifecycle needs a human at a terminal, so a scheduled maintenance agent can do the cleanup. ## Learning Categories Learnings are categorized for context: * **tip** - General best practices * **warning** - Things to avoid * **pattern** - Successful approaches * **tool-usage** - How to use specific tools * **error-fix** - Solutions to known errors (the `tool-errors` channel always uses this one) ### How long a learning should be A captured rule is written as an order, not an explanation: one behaviour, a few sentences, and under 800 characters. It keeps the specifics that change what the agent does - a threshold, a trigger, an exception, the one example that shows what the rule means - and drops the incident it came from. Dates, session ids, names and quoted complaints are almost never load-bearing. This matters more than it looks. A rule too long to hold beside its peers cannot be compared against them, and comparison is what stops two contradicting rules being in force at once. If a rule needs headings or numbered sections, it is more than one rule. ## Storage Format Learnings are stored as readable markdown: ```markdown theme={"system"} # Learnings for blog-writer ### [tip] Use specific examples over generic advice When writing productivity tips, include concrete scenarios like "checking emails before coffee" rather than abstract advice. ### [error-fix] browser.uploadFile: files.length remained # When browser.uploadFile fails with "files.length remained #", use the corrected call shape that succeeded: {"path":"/Users/me/shot.png"} ### [tip] Cite sources before publishing Always include source links before publishing. ### [tip] Reuse the prior run item on same-day re-invocation On a same-day re-invocation, reuse the run item the previous invocation created. ``` Every field except the date is optional, so older files load unchanged, and unknown tokens are ignored rather than rejected: * `src:` records who authored it, `auto` (an evaluator), `approval` (promoted from a reviewer comment), or `manual` (explicitly saved by a reviewer). Files without it load as `auto`. * `ch:` records the capture channel, one of `corrections`, `tool-errors`, `custom`, `agent`. Absent on entries written before channels existed. * `ih:` is the [instruction hash](#rules-are-stamped-with-the-instructions-they-were-checked-against) the rule was last vetted against. Absent on entries that predate it; those count as fresh, not stale, until a capture or tidy backfills them. * `injected:` counts injections into a run's prompt. `applied:` is the pre-v0.19.0 name and reads as an alias; the file is rewritten with `injected:` on the next save. * `tool:` and `sig:` are the `tool-errors` dedupe key, the tool and its normalized failure signature. * `sess:` is the session the rule was captured in. * `state:graduated` means the rule now lives in the agent file and this staged copy is on its way out. `state:quarantined` means it failed the vet and is never injected; the reason is on the `` line beneath. Absent means active. A `state:retired` entry in an older file is skipped on read and dropped on the next write, so retired rules do not accumulate. * `re:` counts how many times a human repeated the learning; `ok:` counts the approved, uncommented runs it was in force for. These are the evidence the tidy-up uses to decide what to rewrite and what to make permanent. * `` carries the one-line evidence trail, for `tool-errors` the failed and corrected calls. The `` line under the heading is a breadcrumb, so a file sitting in the state directory can be traced back to the agent that wrote it. Nothing reads it back; it is there for you. ## Upgrading an existing agent No migration is needed and no file moves. Existing learnings files load as they are; the first capture or tidy after the upgrade backfills the instruction hash and vets the entries it finds, quarantining rather than deleting anything that no longer holds. `undo` covers that pass like any other. The dividing rule for config: **hard-error and quit when honoring the key would resurrect risky behavior or the config contradicts itself; warn once and continue when the faithful mapping is strictly safer than what you had.** Nothing is ever silently ignored. | What you have | What happens | Behavior | | - | - | - | | `learning: true` | Warns once, continues | Applies deliberately saved human learnings. Ordinary comments affect only the current run and free-form capture stops. The warning names the explicit form and is echoed by `agentuse doctor`. | | `capture: true` | Still parses; meaning narrows | Old meaning: free-form auto-capture. New meaning: no automatic observation channels. Human learning uses Learn/`--remember`; a one-time notice names `capture: { custom: "..." }` as the way to restore scoped free-form capture. | | `capture: false` | Unchanged | Capture off. | | `apply: true` / `apply: false` | Unchanged | Same boolean, same meaning; `true` now injects only vetted, active, non-stale learnings. | | `criteria: "..."` | **Hard error, agent quits** | The only mapping that honors it would keep free-form policy capture running automatically. Rewrite it as `capture: { custom: "..." }`; the error and `doctor` both say so. | | `custom` + `agent` both set | **Hard error, agent quits** | A contradiction the parser cannot resolve. Pick one. | | `evaluate`, `file` | **Hard error** (unchanged) | Rejected by name since v0.17.0. | | `max`, `model` | Unchanged | | If you were relying on free-form capture and want it back, the one-line answer is a `custom` block naming what is worth keeping: ```yaml theme={"system"} learning: capture: custom: | Capture rules about tone and sourcing. Ignore anything about scheduling, tooling, or this run's specific content. ``` If you reached for `apply: false` to stop bad auto-captured rules from reaching the agent, try turning it back on. The vet is what `apply: false` was standing in for, and it discriminates: it drops the junk instead of throwing away the valid corrections along with it. ## Example: Manual Review Workflow ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 learning: capture: custom: Keep rules about structure and hooks; ignore anything about a specific post. apply: false --- # Blog Writer Write short productivity blog posts (150-200 words). ## Requirements - Start with a relatable hook - Include 3 actionable tips - End with a clear call-to-action ``` After 5-10 runs, review what it captured with `agentuse learnings ./blog-writer.agentuse` (a list by status) or `agentuse learnings ./blog-writer.agentuse --edit` (the file itself): ```markdown theme={"system"} ### [tip] Use specific examples over generic advice When writing productivity tips, include concrete scenarios like "checking emails before coffee" rather than abstract advice. ### [pattern] Structure with time estimates Each actionable tip should include a specific time estimate (e.g., "5-minute brain dump") to make it feel achievable. ``` Then update your agent instructions with the best insights: ```yaml theme={"system"} ## Requirements - Start with a relatable hook - Include 3 actionable tips with specific time estimates # ← from learnings - Use concrete scenarios, not abstract advice # ← from learnings - End with a clear call-to-action ``` This keeps you in control while still benefiting from extracted patterns. ## Best Practices The default channel is the one a human authored. Run on it for a while before opening free-form capture with `custom` or `agent` When you do enable `custom`, say what is worth keeping *and* what to ignore. An unscoped evaluator finds something every run A quarantined rule names the instruction it collided with. That is usually a defect in the agent file worth fixing, not just a bad rule Rewriting instructions makes rules stale and holds them out of injection. `agentuse learnings tidy` re-vets them and graduates the proven ones ## Next Steps Persistent data storage for agents Orchestrate teams of learning agents # macOS Desktop App Source: https://docs.agentuse.io/guides/macos-desktop Run the AgentUse dashboard as a native macOS menu-bar app AgentUse for Mac keeps scheduled agents, approvals, and active runs available from the menu bar without leaving a Terminal window open. It can start quietly at login, opens the operations dashboard in its own window, and includes the complete AgentUse runtime, so Node.js and a separate CLI installation are not required. The app and CLI use the same projects and session history, letting you move between Desktop and Terminal without duplicate setup or configuration. ## Install Download the signed DMG from the [latest GitHub release](https://github.com/agentuse/agentuse/releases/latest), open it, and move **AgentUse** to Applications. Open AgentUse from Applications to start setup. ## First launch The Desktop setup screen has two independent options: * **Launch AgentUse at login** starts the app quietly in the menu bar so schedules, approvals, and background runs remain available. It is selected by default but is not added to macOS Login Items until you select **Continue**. * **Add CLI launcher** creates `~/.local/bin/agentuse`, pointing to the CLI bundled inside AgentUse.app. It is optional and never blocks **Continue**. After **Continue**, Desktop joins the same onboarding flow as the Web UI: create a project, run the credential-free sample, connect a runtime provider, and hand the first agent to your coding assistant. Desktop reads provider status from the same bundled runtime that will run the agent. If login is required, the coding agent stops and asks you to run it in Terminal rather than passing credentials or OAuth details through coding-agent chat. After you copy the first-agent prompt, onboarding stays on the current screen and checks for the new agent. When it appears, select **Open agent** to review and run it. If creation takes too long, you can copy the prompt again or check for the agent manually. ## Command line launcher The optional launcher makes the bundled CLI available at: ```text theme={"system"} ~/.local/bin/agentuse ``` `~/.local/bin` must be on your shell's `PATH` before a bare `agentuse` command can resolve to it. Desktop does not edit shell configuration automatically. Settings lists every executable named `agentuse` found on the login-shell `PATH`, in resolution order. The first path is the command the shell runs when you enter `agentuse`. You can add or replace the launcher at `~/.local/bin/agentuse` even when npm, pnpm, Bun, Yarn, Homebrew, or another installation exists elsewhere. Desktop never modifies those other installations. Use **Add**, **Replace**, or **Remove** in Settings to manage only the bundled launcher. If a different installation appears first, either call the displayed launcher path directly or change your shell's `PATH` order. ## Global shortcut The global shortcut is off by default so AgentUse does not take over a key combination used by macOS or another app. Record one in Settings to show or hide the Dashboard from anywhere. Open **Settings → General** and select the shortcut button to record a different combination. Hyper shortcuts are supported: the star in `✦ A` represents Control+Option+Command+Shift (`⌃⌥⌘⇧`), including Caps Lock mappings that emit those modifiers. Select **Clear** to disable the shortcut. If macOS or another app already owns a combination, AgentUse keeps the previous working shortcut and asks you to choose another. ## How it behaves Launching AgentUse opens the dashboard. Closing the window hides it without stopping the backend, so schedules, approvals, and active runs remain available. Use the AgentUse menu-bar icon to: * show the AgentUse dashboard * open Settings * quit AgentUse Settings shows whether the local server is running, lets you start or stop a server owned by the desktop app, configures launch at login and the CLI launcher, controls native approval and session-completion notifications, and displays the current server log. The Settings window uses native SwiftUI controls while the dashboard remains the existing web interface. A server started outside the app is identified as external and is never stopped by the desktop controls. If that external server restarts, Desktop keeps its port available and reconnects instead of starting a competing server. Use **Start Server** explicitly if the external server has been retired and you want Desktop to replace it. Login launches start in the background so the menu-bar status and approvals are available without opening the dashboard window. The dashboard gear opens **Dashboard preferences** for theme, Home layout, session list style, and reloading the dashboard. Select **Open Mac Settings…** there for server, login, shortcut, CLI, native notification, and log controls. ## Updates AgentUse checks quietly for updates on a recurring schedule while the menu-bar app is running, without requiring Settings or the dashboard to stay open, and downloads available updates in the background. When an update is ready, choose **Restart Now** in the native prompt or **Later** to keep working. You can also open **Settings → About** to check manually or restart and install a downloaded update. AgentUse never installs an update without an explicit restart decision. Closing the Dashboard, using Command+Q, or choosing Quit from the Dock hides the app without stopping its backend. Only **Quit AgentUse** from the menu-bar item fully exits the app and stops a backend it started. A backend that was already running when the app launched is left alone. Only one desktop app instance can run at a time. When the app owns the running server, choosing **Quit AgentUse** from the menu-bar item asks for confirmation and explains that the server will stop with the app. Choose **Keep AgentUse Running** and hide the Dashboard window instead when schedules and approvals should remain available in the background. The desktop window accepts only the loopback dashboard origin. Links to normal `http` or `https` sites open in the default browser; other external navigation is blocked. Electron renderer access to Node.js is disabled and context isolation is enabled. ## Troubleshooting If the window does not load, open **Settings** from the menu-bar item and check the server status and **Logs** tab. You can also use the CLI independently: ```bash theme={"system"} agentuse serve ps agentuse serve logs ``` See [Operations Dashboard](/guides/serve-dashboard) for dashboard behavior and [CLI Commands](/reference/cli-commands) for the full `serve` reference. Run the Desktop app from source, install local builds, and create signed releases. # Developing AgentUse for Mac Source: https://docs.agentuse.io/guides/macos-desktop-development Run, package, sign, and notarize the AgentUse macOS app This page is for contributors working on the AgentUse Desktop app. For normal installation and usage, see [macOS Desktop App](/guides/macos-desktop). ## Requirements Desktop development requires: * Node.js 22 or later * Bun and pnpm * Xcode, including its command-line tools Xcode is required because the build compiles the native SwiftUI Settings helper and uses Apple's asset-catalog compiler for the app icon. ## Run from source From the repository root, install workspace dependencies, build the CLI and Web UI, then start Electron: ```bash theme={"system"} pnpm install bun run build pnpm desktop:dev ``` The Desktop process attaches to a registered `agentuse serve` daemon when one is already running. Otherwise it starts the compiled local CLI on a loopback port. The browser dashboard remains available at the URL shown in the menu. Set `AGENTUSE_CLI_PATH` to test against a specific CLI build: ```bash theme={"system"} AGENTUSE_CLI_PATH=/absolute/path/to/bin/cli.js pnpm desktop:dev ``` ## Install a local build For routine testing, install and launch one canonical app copy: ```bash theme={"system"} pnpm desktop:install-local ``` The installer builds in temporary staging, gracefully terminates running AgentUse Desktop copies, replaces `~/Applications/AgentUse.app`, and launches that copy. Avoid opening `apps/desktop/dist/*/AgentUse.app` directly; using one canonical installation prevents Launch Services from retaining several copies with the same bundle identifier. ## Package the app Create a package for the current Mac architecture: ```bash theme={"system"} pnpm desktop:package:mac ``` For an unsigned development package: ```bash theme={"system"} CSC_IDENTITY_AUTO_DISCOVERY=false pnpm desktop:package:mac ``` The Settings helper builds for the current architecture by default. For a universal `arm64` and `x86_64` package, include both architectures in the nested SwiftUI helper: ```bash theme={"system"} AGENTUSE_SETTINGS_UNIVERSAL=1 pnpm desktop:package:mac ``` The package includes the AgentUse runtime, dashboard, built-in skills, and required metadata. Source, tests, prior Desktop builds, and workspace caches are excluded. ## Sign and notarize a release For a manual release, store notarization credentials in the login Keychain so the app-specific password does not enter shell history: ```bash theme={"system"} xcrun notarytool store-credentials agentuse-notary \ --apple-id \ --team-id APPLE_KEYCHAIN_PROFILE=agentuse-notary pnpm desktop:package:mac ``` `notarytool` prompts securely for the app-specific password. electron-builder uses the Developer ID Application identity installed in the login Keychain. For CI, configure repository Actions secrets named `MAC_CSC_LINK` and `MAC_CSC_KEY_PASSWORD`, plus `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`. The certificate value is the base64-encoded Developer ID Application `.p12`. Keep all signing credentials in CI secrets. Hardened runtime is enabled, and the packaged native Settings helper is placed under `Contents/Frameworks` before notarization. ## Prepare an updater-enabled release The root package and Desktop app share one release version. Use the repository release script to prepare that version; do not edit the Desktop version separately: ```bash theme={"system"} bun scripts/release.ts prepare X.Y.Z ``` Push the prepared tag to the public repository. After the portable release gate passes, GitHub Actions builds on native Apple Silicon and Intel runners. Each package is signed, notarized, stapled, and verified before it is preserved as a workflow artifact. The publishing job merges their update metadata and uploads two DMGs, two Mac ZIPs, four blockmaps, and one `latest-mac.yml` to the release. Every artifact filename includes `arm64` or `x64`, and the merged metadata lists both architectures so electron-updater selects the matching ZIP. Confirm the completed GitHub Release contains that nine-file set. Test the feed from an older signed build on each architecture: confirm that the update downloads in the background, choose **Later** in the native prompt, install it from **Settings → About**, and confirm the new version launches. Repeat with **Restart Now**, then repeat a check while offline and confirm the app continues working while the About tab reports the failure. # Manager Agents Source: https://docs.agentuse.io/guides/manager-agents Orchestrate teams of agents with delegation, tracking, and scheduling The `type: manager` configuration and orchestration behavior are experimental and may change without migration. Discuss feedback in [GitHub Discussions](https://github.com/agentuse/agentuse/discussions). ## What are Manager Agents? Manager agents are specialized agents designed for orchestration. Instead of doing work directly, they coordinate teams of subagents, track progress, and make decisions about what work to delegate next. ## When to Use Manager Agents Use a manager agent when you need to: * **Coordinate multiple specialists** - Different agents for research, writing, review, etc. * **Track complex workflows** - Multi-phase projects with dependencies * **Run scheduled operations** - Regular tasks that span multiple runs * **Maintain state across runs** - Track what's done, what's pending, what's blocked ## Basic Configuration Set `type: manager` in your agent frontmatter: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 type: manager subagents: - path: ./researcher.agentuse - path: ./writer.agentuse --- # Content Manager ## Goal Create articles on trending topics. ## SOP 1. Research trending topics 2. Write articles for each topic 3. Review and publish ``` ## Configuration Options ### Required * `type: manager` - Enables manager mode with orchestration prompts ### Recommended * `subagents` - Team of agents to delegate to * `store` - Persistent storage for tracking work items ### Optional * `schedule` - Cron expression for scheduled runs ## The Manager Prompt When `type: manager` is set, your agent automatically receives instructions with orchestration guidelines. You don't need to write these yourself - they're included automatically. ### Automatic Orchestration Loop The manager follows this loop automatically (shown for reference - you don't need to include this in your agent file): 1. **UNDERSTAND** - Parse goal and SOP from your instructions 2. **CHECK** - Review current state (pending work, in-progress items) 3. **DECIDE** - Determine what needs to happen next based on goal and state 4. **DELEGATE** - Call subagents with clear, specific instructions 5. **TRACK** - Update store items with outcomes from delegation 6. **REPEAT** - Continue until the goal is achieved or no further progress can be made This means you only need to define your **Goal** and **SOP** - the manager handles the orchestration mechanics. ### Schedule Awareness If your manager has a `schedule`, it receives context about run frequency: ```yaml theme={"system"} --- type: manager schedule: "0 9 * * *" # Daily at 9 AM --- ``` The manager learns to pace work appropriately - not rushing to complete everything in one run if there's time, checking progress vs targets before starting new work. ## Work Tracking with Store Managers work best with a persistent store: ```yaml theme={"system"} --- type: manager store: "my-project" # Shared store name subagents: - path: ./researcher.agentuse - path: ./writer.agentuse --- ``` All subagents can share the same store by using the same store name. This enables coordination without explicit communication. See [Store Guide](/guides/store) for available store tools. ## Writing SOPs (Standard Operating Procedures) A good SOP clearly defines the workflow phases: ```markdown theme={"system"} ## SOP (Standard Operating Procedure) ### Phase 1: Research - Use the researcher to find 3 interesting topics - Store each topic with type "topic" and status "pending" ### Phase 2: Writing - For each pending topic, delegate to the writer - Update status to "in_progress" when started - Update status to "written" when complete ### Phase 3: Review - For each written article, delegate to the reviewer - If approved, update status to "done" - If revisions needed, send back to writer ### Completion - All items should have status "done" - Summarize completed work ``` ## Complete Example: Content Team ### Manager Agent ```yaml theme={"system"} # manager.agentuse --- model: anthropic:claude-sonnet-5 type: manager store: "content-pipeline" schedule: "0 * * * *" # Every hour subagents: - path: ./agents/researcher.agentuse - path: ./agents/writer.agentuse - path: ./agents/reviewer.agentuse --- # Content Team Manager ## Goal Produce 3 high-quality articles per day. ## SOP ### Phase 1: Topic Discovery - Check store for pending topics - If fewer than 3 pending topics, use researcher to find more - Store topics with type "topic", status "pending" ### Phase 2: Writing - For each pending topic, delegate to writer - Pass topic context and target word count (500 words) - Store article with type "article", parentId = topic id ### Phase 3: Review - For each unreviewed article, delegate to reviewer - If approved, mark article as "done" - If revisions needed, mark as "needs_revision" with feedback ### Completion Criteria - 3 articles with status "done" today - Report progress and any blockers ``` ### Researcher Subagent ```yaml theme={"system"} # agents/researcher.agentuse --- model: anthropic:claude-haiku-4-5 store: "content-pipeline" --- You are a research specialist. Find trending topics. When given a research task: 1. Search for trending topics in the specified area 2. Evaluate each topic for article potential 3. Create store items for promising topics Return a summary of topics found. ``` ### Writer Subagent ```yaml theme={"system"} # agents/writer.agentuse --- model: anthropic:claude-sonnet-5 store: "content-pipeline" --- You are a content writer. Create engaging articles. When given a writing task: 1. Get the topic from the store using the provided ID 2. Research and write a compelling article 3. Create a store item for the article linked to the topic 4. Update the topic status to "written" Return the completed article. ``` ### Reviewer Subagent ```yaml theme={"system"} # agents/reviewer.agentuse --- model: anthropic:claude-haiku-4-5 store: "content-pipeline" --- You are an editor. Review articles for quality. When given a review task: 1. Get the article from the store 2. Check for: accuracy, clarity, engagement, grammar 3. Either approve (update status to "done") or request revisions Return your review decision with feedback. ``` ## Delegation Guidelines When managers delegate to subagents: Be specific about what you need. Include context from previous work. ``` writer({ task: "Write a 500-word article about AI productivity tools", context: { topicId: "...", keywords: [...], targetAudience: "..." } }) ``` So subagents can update the same items: ``` reviewer({ task: "Review article for publication", context: { articleId: "01HX...", topicId: "01HW..." } }) ``` What output do you expect? What quality bar? ``` task: "Write article. Must include: 3 actionable tips, real examples, conclusion with CTA" ``` ## Handling Blockers Managers should stop and report when blocked: ```markdown theme={"system"} ## When Blocked If I need human input, I will: 1. State what I'm blocked on 2. Explain what decision/input I need 3. List available options if applicable Example blockers: - Need approval for topic selection - External resource required (API key, credentials) - Quality issue that requires human judgment ``` ## Best Practices Each subagent should have one clear purpose Track all work items in the store, not in prompts Define phases, transitions, and completion criteria Don't rush if you run frequently ## Debugging Manager Agents ### Enable Verbose Logging ```bash theme={"system"} agentuse run manager.agentuse --verbose ``` ### Check Store State ```bash theme={"system"} # View store contents cat .agentuse/store/content-pipeline/items.json | jq ``` ### Test Subagents Independently ```bash theme={"system"} # Run subagent directly agentuse run ./agents/writer.agentuse "Write about AI tools" ``` ## Next Steps Learn about persistent data storage Run managers on a schedule Deep dive into subagent configuration See complete manager examples # Model Configuration Source: https://docs.agentuse.io/guides/model-configuration Configure AI providers and models for your agents ## Overview AgentUse supports multiple AI providers. You need to authenticate with at least one provider to run agents. ## Supported Providers Claude models (Opus, Sonnet, Haiku) Anthropic API-key authentication GPT models including GPT-5, GPT-4, GPT-4o Supports OAuth and API keys Access to 100+ models via unified API API key authentication Low-cost open coding models curated by OpenCode API key authentication Claude, Llama, Mistral, Nova and more via AWS AWS SigV4 or Bearer token Any OpenAI-compatible endpoint: Ollama, LM Studio, vLLM, llama.cpp, etc. ## Naming a Model Without a Version Pinning an exact model id means editing every agent file when a new release ships. Three ways to avoid that, in increasing order of scope: **1. Drop the version.** A model id with its version left off means "the newest in this line": ```yaml theme={"system"} --- model: anthropic:claude-sonnet # newest Sonnet model: openai:gpt-mini # newest small GPT --- ``` The lineup behind these aliases is refreshed each AgentUse release, so an alias always points at a model the release shipped with. A real model id always wins over an alias, so anything you pin keeps its exact meaning. See [Version Aliases](/reference/models#version-aliases) for the current table. **2. Name your own.** A `models.aliases` block in `~/.agentuse/config.json` lets one edit repoint every agent that uses it: ```json theme={"system"} { "models": { "aliases": { "fast": "anthropic:claude-haiku", "smart": "anthropic:claude-opus" } } } ``` ```yaml theme={"system"} --- model: "@fast" --- ``` An alias can also carry an ordered fallback list: ```json theme={"system"} { "models": { "aliases": { "smart": { "candidates": ["anthropic:claude-opus", "openai:gpt"], "cooldown": "5m" } } } } ``` AgentUse falls back when an execution segment cannot get started on a candidate: a transient first-request failure (rate limit, timeout, provider 5xx, transport error), or a model it cannot authenticate to at all (no login, an OAuth token that will not refresh, a 401/403). This includes a segment resumed after an approval gate. Either way it only happens before the model emits new output or invokes a tool in that segment. The selected model and remaining ordered fallback policy are persisted for later resumes. `cooldown` keeps new runs in the same process from repeatedly waiting on a model that just failed; it resets when the process restarts. **3. Set a default and stop naming models.** With `models.default` (or `AGENTUSE_MODEL`) configured, `model:` becomes optional: ```json theme={"system"} { "models": { "default": "anthropic:claude-sonnet" } } ``` Aliases resolve to concrete models before execution, so session logs and cost accounting record the model that actually ran. A suspended run first resumes on its last selected model, even if the alias has moved since; a fallback-eligible failure before new output may then advance through its persisted policy. To migrate agent files you already have, `agentuse models unpin` swaps pinned versions for aliases (`--dry-run` to preview), and `agentuse models bump` moves stale pins forward for files you want to keep pinned. ## Authentication Methods ### 1. Interactive Login (Recommended) The simplest way to authenticate: ```bash theme={"system"} # Interactive menu agentuse provider login # Or login to specific provider agentuse provider login openai agentuse provider login openrouter agentuse provider login opencode-go ``` Anthropic API keys remain built in. Claude Pro/Max OAuth is supplied by the shortlisted community plugin and can be installed from provider setup or from the CLI: ```bash theme={"system"} agentuse plugins install cb7337/agentuse-claude-code-provider@v0.1.0 agentuse provider login anthropic ``` Users upgrading with an Anthropic OAuth credential created by the former core flow do not need to run these commands. AgentUse installs the pinned compatibility plugin and adopts that credential automatically. The explicit community-plugin installation flow is shown only for new configuration. Community providers that use an external CLI can also appear during onboarding when their required executable is on the AgentUse server's PATH. Installing one uses that CLI's existing credentials and runs the provider's readiness check before continuing. If the check fails, setup shows the provider's error and setup instructions. Installed CLI providers remain available for retrying setup. ### 2. Environment Variables Set API keys as environment variables: ```bash theme={"system"} # Add to ~/.bashrc, ~/.zshrc, or ~/.profile export ANTHROPIC_API_KEY="sk-ant-api03-..." export OPENAI_API_KEY="sk-proj-..." export OPENROUTER_API_KEY="sk-or-v1-..." export OPENCODE_GO_API_KEY="..." ``` ### 3. Configuration File Create a `.env` file in your project: ```bash theme={"system"} # .env ANTHROPIC_API_KEY=sk-ant-api03-... OPENAI_API_KEY=sk-proj-... OPENROUTER_API_KEY=sk-or-v1-... OPENCODE_GO_API_KEY=... ``` ### Advanced Environment Variable Configuration AgentUse supports flexible environment variable patterns for multiple API keys: ```bash theme={"system"} # Using environment suffixes for different keys export ANTHROPIC_API_KEY_DEV=sk-ant-api03-dev-key export ANTHROPIC_API_KEY_PROD=sk-ant-api03-prod-key export OPENAI_API_KEY_PERSONAL=sk-proj-personal-key export OPENCODE_GO_API_KEY_TEAM=opencode-go-team-key # Then specify in model string agentuse run agent.md --model anthropic:claude-sonnet-5:dev agentuse run agent.md --model openai:gpt-5.6:OPENAI_API_KEY_PERSONAL agentuse run agent.md --model opencode-go:kimi-k2.7-code:OPENCODE_GO_API_KEY_TEAM ``` Never commit `.env` files to version control! Add to `.gitignore`: ``` .env .env.local .env.*.local ``` ## OpenCode Go OpenCode Go provides curated open coding models through a low-cost OpenCode subscription. AgentUse treats it as a built-in provider and automatically routes each model to the correct OpenCode Go API shape. ```bash theme={"system"} agentuse provider login opencode-go agentuse run agent.agentuse -m opencode-go:kimi-k2.7-code agentuse run agent.agentuse -m opencode-go:minimax-m3 agentuse run agent.agentuse -m opencode-go:qwen3.7-plus ``` Or configure it with an environment variable: ```bash theme={"system"} export OPENCODE_GO_API_KEY="..." ``` OpenCode Go publishes its live model list at `https://opencode.ai/zen/go/v1/models`, so `opencode-go:` model IDs are passed through rather than validated against AgentUse's static model registry. ## Amazon Bedrock Bedrock authenticates with standard AWS credentials rather than `agentuse provider login`. Three modes are supported (in priority order): **1. Static IAM access keys (SigV4)** ```bash theme={"system"} export AWS_REGION=us-east-1 export AWS_ACCESS_KEY_ID="AKIA..." export AWS_SECRET_ACCESS_KEY="..." # Optional, for STS / assumed-role temporary credentials export AWS_SESSION_TOKEN="..." ``` **2. Bedrock API key (Bearer token)** ```bash theme={"system"} export AWS_REGION=us-east-1 export AWS_BEARER_TOKEN_BEDROCK="..." ``` **3. AWS SDK credential provider chain**, used automatically when neither of the above is set. Resolves `AWS_PROFILE`, `~/.aws/credentials`, SSO cache, EC2/ECS/EKS instance roles, etc. ```bash theme={"system"} # Refresh SSO / assume-role credentials for your profile, then run: export AWS_REGION=eu-west-1 export AWS_PROFILE=my-bedrock-profile agentuse run agent.agentuse -m bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0 ``` Use the full Bedrock model ID (which contains colons) as-is, or an inference profile ARN: ```bash theme={"system"} agentuse run agent.agentuse -m bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0 agentuse run agent.agentuse -m bedrock:meta.llama3-70b-instruct-v1:0 agentuse run agent.agentuse -m bedrock:arn:aws:bedrock:eu-west-1:123456789012:application-inference-profile/abcd1234 ``` Your IAM user/role needs `AmazonBedrockFullAccess` (or an equivalent custom policy) and you must have requested access to the foundation model in the AWS console. The `bedrock:` prefix bypasses the static model registry, so any Bedrock model ID or inference-profile ARN is accepted. ## Custom Providers Connect hosted or local endpoints from **Dashboard Settings → Providers**. A custom provider can use OpenAI Chat Completions, OpenAI Responses, or Anthropic Messages. Dashboard setup discovers available models, lets you choose which to save, and verifies the selected protocol with a minimal completion before the provider is ready. Saved custom providers remain editable in Settings. The CLI supports adding OpenAI-compatible endpoints such as Ollama, LM Studio, vLLM, and llama.cpp. ### Adding a Custom Provider ```bash theme={"system"} # Ollama (default port 11434) agentuse provider add ollama --url http://localhost:11434/v1 # LM Studio (default port 1234) agentuse provider add lmstudio --url http://localhost:1234/v1 # With optional API key agentuse provider add myserver --url https://my-gpu-server.example.com/v1 --key sk-mykey123 ``` ### Using Custom Providers In your agent file: ```yaml theme={"system"} --- model: ollama:glm-5-flash:q4_K_M --- ``` ```yaml theme={"system"} --- model: lmstudio:qwen/qwen3.5-9b --- ``` Or override at runtime: ```bash theme={"system"} agentuse run agent.agentuse -m ollama:glm-5-flash:q4_K_M agentuse run agent.agentuse -m lmstudio:qwen/qwen3.5-9b ``` Custom providers support colons in model names, `ollama:qwen3.5:0.8b` is parsed as provider `ollama`, model `qwen3.5:0.8b`. ### Environment Variable Overrides Custom providers support env var overrides using the uppercased provider name: ```bash theme={"system"} # Override base URL and API key for a custom provider named "ollama" export OLLAMA_BASE_URL=http://192.168.1.100:11434/v1 export OLLAMA_API_KEY=sk-optional-key ``` ### Managing Custom Providers ```bash theme={"system"} # List all providers (including custom) agentuse provider list # Remove a custom provider agentuse provider remove ollama ``` **Local model limitations:** * **Quality**: Small models (under 30B parameters) often struggle with complex tool use, multi-step reasoning, and following detailed agent instructions. For best results, use 30B+ parameter models. * **Context window**: Ensure your model is loaded with a context size of at least 8192 tokens. AgentUse's system prompts can exceed 4096 tokens. * **Tool calling**: Many local models have limited or no native tool/function calling support, which may cause agents with tools to fail or behave unpredictably. ## Managing Credentials ### List Stored Credentials ```bash theme={"system"} agentuse provider list ``` Output: ``` 📁 Credentials stored in: ~/.local/share/agentuse/auth.json Stored credentials: 🔑 anthropic (Claude subscription OAuth) → Use as: anthropic:claude-sonnet-5 🎫 openai (api) → Use as: openai:gpt-5.6 Environment variables: 🌍 openrouter (OPENROUTER_API_KEY) → Use as: openrouter:z-ai/glm-5.3 Custom Providers: 🔌 ollama → http://localhost:11434/v1 (stored), key ****abcd (from OLLAMA_API_KEY) 🔌 lmstudio → http://localhost:1234/v1 (stored) ``` ### Remove Credentials ```bash theme={"system"} # Remove specific provider agentuse provider logout anthropic # Remove a custom provider agentuse provider remove ollama ``` ### Rotate API Keys ```bash theme={"system"} # Logout and login again agentuse provider logout openai agentuse provider login openai ``` ## Getting API Keys Get API keys from provider consoles: * **Anthropic**: [console.anthropic.com](https://console.anthropic.com) → API Keys → Create Key (starts with `sk-ant-api03-`) * **OpenAI**: [platform.openai.com](https://platform.openai.com) → API Keys → Create new secret key (starts with `sk-proj-`) * **OpenRouter**: [openrouter.ai](https://openrouter.ai) → Keys → Create Key (starts with `sk-or-v1-`) * **OpenCode Go**: [opencode.ai/auth](https://opencode.ai/auth) → Subscribe to Go → Copy API key Keys are shown only once. Store them securely and never commit to version control. ## Authentication Priority Order AgentUse checks authentication sources in this order: 1. **OAuth tokens** - Checked first and refreshed automatically 2. **Stored API keys** (via `agentuse provider login`) - Stored in `~/.local/share/agentuse/auth.json` 3. **Environment variables** - `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`, `OPENCODE_GO_API_KEY` 4. **Custom environment variables** - Using suffix patterns (e.g., `ANTHROPIC_API_KEY_DEV`) or full variable names ## Runtime Model Override Override the model at runtime using the `--model` flag: ```bash theme={"system"} agentuse run agent.agentuse --model anthropic:claude-haiku-4-5 agentuse run agent.agentuse -m openai:gpt-5.4-mini agentuse run agent.agentuse -m opencode-go:kimi-k2.7-code agentuse run agent.agentuse -m anthropic:claude-sonnet # version alias agentuse run agent.agentuse -m @fast # configured alias ``` Without `--model`, a parent and each delegated sub-agent use their own declared models. An explicit runtime override is run-wide: it applies at every sub-agent depth, including the full candidate order of a fallback alias, and is preserved when a session resumes. See the complete reference for model override format, environment-specific keys, CI/CD examples, and sub-agent inheritance behavior. ## Multi-Provider Setup Use different providers for different agents: ```markdown theme={"system"} --- name: fast-agent model: anthropic:claude-haiku-4-5 # Uses Anthropic --- ``` ```markdown theme={"system"} --- name: powerful-agent model: openai:gpt-5.6 # Uses OpenAI GPT-5 openai: reasoningEffort: high # More thorough reasoning textVerbosity: medium # Balanced response length --- ``` ```markdown theme={"system"} --- name: specialized-agent model: openrouter:z-ai/glm-5.3 # Uses OpenRouter --- ``` ```markdown theme={"system"} --- name: open-coding-agent model: opencode-go:kimi-k2.7-code # Uses OpenCode Go --- ``` ```markdown theme={"system"} --- name: local-agent model: ollama:glm-5-flash:q4_K_M # Uses local Ollama --- ``` ## Provider Options Configure provider-specific settings for fine-tuned model behavior: ### Reasoning Effort (recommended, provider-agnostic) The simplest way to control how hard a model thinks is the top-level `reasoning`. AgentUse normalizes the level to the selected model's supported vocabulary, then applies the corresponding provider control. For example, GPT-5.6 maps `minimal` to `low`, while modern Claude uses adaptive thinking, so one setting works whether the agent runs on Claude or GPT-5: ```yaml theme={"system"} --- model: anthropic:claude-opus-5 reasoning: high # none | minimal | low | medium | high | xhigh | max --- ``` Use `medium`/`high` for genuine judgment (hard multi-constraint calls, planning, debugging), `low`/`minimal` for lighter work, omit for the model default, and `none` to force reasoning off. It is opt-in and bills reasoning tokens at **output rates**. Reach for `reasoning` first. The provider-specific `openai.reasoningEffort` and `anthropic.thinking.budgetTokens` below are escape hatches for exact wire-level control, honored only when the top-level `reasoning` is unset. Being top-level, `reasoning` also avoids a subtle trap: a provider-specific key placed at the wrong nesting level is silently dropped (the agent parses and runs with the tuning never applied). ### OpenAI Provider Options For OpenAI models (especially GPT-5), you can control thinking effort and verbosity: ```yaml theme={"system"} --- model: openai:gpt-5.6 openai: reasoningEffort: high # Options: 'none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max' reasoningSummary: auto # Options: 'auto', 'detailed' — surface reasoning in the session trace textVerbosity: low # Options: 'low', 'medium', 'high' promptCacheRetention: 24h # Optional: extended prompt caching on supported models --- ``` **reasoningEffort**: Controls thinking effort for reasoning * `none`: Disable reasoning when the selected model supports it * `minimal`: Use the lightest reasoning mode * `low`: Faster responses with less thorough reasoning * `medium`: Balanced performance (default) * `high`: More comprehensive reasoning, slower responses * `xhigh`: Maximum reasoning for models that support it **reasoningSummary**: Streams a natural-language summary of the model's reasoning so it appears inline in the session trace (`auto` or `detailed`). On reasoning-capable models this **defaults to `auto`**, the reasoning tokens are billed whether or not you ask for the summary, so surfacing it is near-free. Non-reasoning models (e.g. `gpt-4o`) omit it automatically. **textVerbosity**: Controls response length and detail * `low`: Concise, minimal prose * `medium`: Balanced detail (default) * `high`: Verbose, detailed explanations **prompt caching**: AgentUse automatically sends a stable OpenAI `promptCacheKey` per agent so repeated runs with the same prompt prefix are easier for OpenAI to route to cache. You usually do not need to configure this. Set `promptCacheRetention: 24h` only when you want extended retention and the selected OpenAI model supports it. If you omit `reasoningEffort`, `textVerbosity`, or `promptCacheRetention`, AgentUse leaves those fields unset and uses the OpenAI/AI SDK defaults. Reasoning effort is typically `medium` on reasoning models. `none`, `xhigh`, and `24h` retention are model-specific OpenAI options; if a model does not support a selected option, OpenAI will reject the request. Whether a reasoning summary actually streams also depends on the effort level and task complexity. ### Anthropic Provider Options For Claude models, you can enable extended thinking so the model's reasoning streams into the session trace: ```yaml theme={"system"} --- model: anthropic:claude-haiku-4-5 anthropic: thinking: budgetTokens: 4096 # Minimum 1024 --- ``` Extended thinking is **off by default**, an explicit opt-in. Enabling it generates new thinking tokens billed at **output rates**, a real cost increase that scales with the budget (unlike OpenAI's `reasoningSummary`, where the reasoning is billed either way). AgentUse automatically raises `max_tokens` above the budget so Anthropic's `max_tokens > budget` constraint is met and there's headroom for the answer. Only older Claude models such as Claude Haiku 4.5 accept a manual budget. Claude Opus 4.7 and later, Sonnet 5 and later, Fable, and Claude Haiku 5.5 reject it, so set their depth with `reasoning` instead. These options help you optimize for: * **Speed vs Quality**: Lower reasoning effort for faster responses * **Conciseness vs Detail**: Lower verbosity for more direct answers * **Cost Optimization**: Lower settings reduce token usage * **Reasoning visibility**: `reasoningSummary` (OpenAI) and `thinking` (Anthropic) surface the model's "why" inline in the session view ## Troubleshooting * Verify API key is correct * Check key hasn't expired * Ensure key has required permissions * Try logging out and back in * Check your API tier and limits * Implement exponential backoff * Consider upgrading your plan * Use different keys for different projects ## CI/CD Authentication For automated environments: ### GitHub Actions ```yaml theme={"system"} name: Run Agent on: [push] jobs: agent: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: pnpm install -g agentuse - run: agentuse run my-agent.agentuse env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} OPENCODE_GO_API_KEY: ${{ secrets.OPENCODE_GO_API_KEY }} ``` ### Docker ```dockerfile theme={"system"} FROM node:20 RUN npm install -g pnpm && pnpm install -g agentuse ENV ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} ENV OPENAI_API_KEY=${OPENAI_API_KEY} ENV OPENROUTER_API_KEY=${OPENROUTER_API_KEY} ENV OPENCODE_GO_API_KEY=${OPENCODE_GO_API_KEY} CMD ["agentuse", "run", "agent.agentuse"] ``` ## Next Steps Start using your authenticated providers Build agents with your providers # Plugins Source: https://docs.agentuse.io/guides/plugins # Plugins An AgentUse plugin is an installable package. A plugin can contribute executable extensions today, with other resource types such as skills and agents able to use the same package boundary in the future. An extension is a TypeScript or JavaScript module that exports one activation function. The function receives a stable API and registers events, providers, or provider patches. AgentUse waits for async activation before model discovery and execution begin. ```ts theme={"system"} import type { AgentUseExtension } from "agentuse/plugin-api"; const extension: AgentUseExtension = async (agentuse) => { agentuse.on("agent:complete", async (event) => { agentuse.log.info(`${event.agent.name} completed`); }); agentuse.registerProvider({ // provider definition }); }; export default extension; ``` Extensions run as trusted code with the same operating-system permissions as AgentUse. Review third-party plugins before installing them. ## Loose project and global extensions Single-file extensions are discovered automatically from the existing plugin directories: * `.agentuse/plugins/*.{ts,js}` for the current project. * `$AGENTUSE_CONFIG_DIR/plugins/*.{ts,js}` for every project (defaults to `~/.agentuse/plugins/*.{ts,js}`). Project registrations are scoped to the current asynchronous execution, so concurrent server runs from different projects do not share project providers or event handlers. The historical event-object format remains supported: ```ts theme={"system"} export default { "agent:complete": async (event) => { console.log(event.result.text); }, }; ``` It is equivalent to calling `agentuse.on("agent:complete", handler)`. New extensions should use the activation API. ## Event API `agentuse.on(event, handler)` returns a disposable registration. Handlers run sequentially in registration order and receive a context containing an abort signal. Logging stays on the activation API so handlers can close over `agentuse.log`. ```ts theme={"system"} const registration = agentuse.on("agent:complete", async (event, context) => { agentuse.log.info(`${event.agent.name}: ${event.result.text}`); }); await registration.dispose(); ``` There are three intercepting events and five observational events: | Event | Can affect execution? | Purpose | | - | - | - | | `tool:call` | Mutate `event.input`; return `{ block, reason, terminate }` | Inspect, rewrite, or deny a tool call before AgentUse policy and execution | | `tool:result` | Return `{ output, isError }` | Rewrite the result passed back to the model or recover/convert an error | | `agent:complete` | Return `{ text }` | Rewrite the final outward response before channels and callers receive it | | `agent:start` | No | Observe an execution starting | | `agent:error` | No | Observe a terminal execution error | | `agent:suspend` | No | Observe suspension for human approval | | `agent:resume` | No | Observe an approval or continuation resume | | `model:fallback` | No | Observe a model fallback before the next attempt | Observational events and non-input fields are immutable snapshots. `tool:call` is the deliberate exception: every handler shares the same mutable `input` object, so later handlers, AgentUse approval policy, and the tool see prior mutations. Return-based transformations from `tool:result` and `agent:complete` are also chained through later handlers. A handler failure is logged and does not prevent later handlers from running. ### Intercepting tools ```ts theme={"system"} agentuse.on("tool:call", async (event) => { if (event.toolName === "search") { event.input.limit ??= 10; } if (event.toolName === "bash" && event.input.command === "forbidden") { return { block: true, reason: "Blocked by project policy", terminate: true }; } }); agentuse.on("tool:result", async (event) => { if (event.toolName === "search" && !event.isError) { return { output: redactSecrets(event.output) }; } }); ``` `block` denies the tool call. `reason` is returned to the model. `terminate` stops the agent loop after the denied result instead of allowing another model turn. ### Transforming the final response ```ts theme={"system"} agentuse.on("agent:complete", async (event) => { return { text: addFooter(event.result.text) }; }); ``` The replacement becomes the returned and delivered final text. The session timeline remains the raw streamed execution trace. ### Event shapes ```ts theme={"system"} interface AgentReference { name: string; model: string; description?: string; filePath?: string; } interface AgentCompleteEvent { agent: AgentReference; result: { text: string; duration: number; tokens?: number; toolCalls: number; toolCallTraces?: ToolCallTrace[]; finishReason?: string; finishReasons?: string[]; hasTextOutput: boolean; }; isSubAgent: boolean; consoleOutput: string; } interface AgentStartEvent { agent: AgentReference; sessionId?: string; trigger: "scheduled" | "manual" | "slack" | "api" | "onboarding"; } interface AgentErrorEvent { agent: AgentReference; sessionId?: string; error: { name?: string; message: string; code?: string }; duration: number; } interface AgentSuspendEvent { agent: AgentReference; sessionId: string; reason: "approval"; toolCallId?: string; approvalUrl?: string; } interface AgentResumeEvent { agent: AgentReference; sessionId: string; reason: "approval" | "continue"; } interface ModelFallbackEvent { agent: AgentReference; sessionId?: string; from: string; to: string; reason: string; attempt: number; } ``` ## Provider API Register a provider with a unique model prefix, model catalog, transport, and optional authentication and prompt behavior: ```ts theme={"system"} agentuse.registerProvider({ id: "acme", name: "Acme Models", models: [ { id: "acme-large", name: "Acme Large", input: ["text", "image"], reasoning: true, contextWindow: 128_000, maxOutputTokens: 16_384, cost: { input: 0, output: 0 }, capabilities: { tools: true }, }, ], transport: { kind: "openai-responses", baseURL: "https://models.acme.test/v1", }, }); ``` Models are addressed as `acme:acme-large`. Declared model limits and modalities participate in validation, context compaction, output-token limits, media tools, and `agentuse models`. ### Model catalogs Providers can declare models directly, inherit a built-in catalog, or discover models asynchronously during activation: ```ts theme={"system"} models: { inherit: "anthropic", include: ["claude-sonnet-*"] } ``` An adapter can retain those model IDs while replacing transport-specific metadata such as subscription pricing: ```ts theme={"system"} models: { inherit: "anthropic", patch: { cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } }, } ``` ```ts theme={"system"} models: async ({ fetch, signal }) => { const response = await fetch("http://localhost:11434/v1/models", { signal }); return convertModels(await response.json()); } ``` ### Transports AgentUse includes declarative transports: * `anthropic-messages` * `openai-responses` * `openai-chat-completions` Use `custom` when a provider needs a different protocol or a subprocess-backed runtime: ```ts theme={"system"} transport: { kind: "custom", apiVersion: 1, async *stream(request, context) { for await (const event of runCustomProtocol({ modelId: context.modelId, messages: request.messages, tools: request.tools, signal: request.signal, })) { yield event; } }, } ``` The custom boundary is owned and versioned by AgentUse; extensions do not import AI SDK types or receive internal provider factories. A request contains normalized messages, function tools, tool choice, common sampling options, provider options, and an abort signal. Custom streams emit these events: * `warning` before any response output. * `text-delta` and `reasoning-delta`, with optional stable block IDs. * `tool-call` with an ID, name, and structured input. * Optional `response-metadata` or `error` events. * Exactly one terminal `finish` event with a normalized reason and optional token usage. AgentUse adapts this contract to its internal model runtime. A stream that ends without `finish` is rejected. When the consumer cancels a run, the request's abort signal fires and the stream's iterator is closed, so check `request.signal` in long-running loops. If the custom transport speaks a known wire protocol, say so with `protocol: "anthropic"` or `protocol: "openai"`. AgentUse then applies that protocol's behavior, such as Anthropic output-token limits and which `providerOptions` block reaches the model. Omit it for a bespoke API. ```ts theme={"system"} transport: { kind: "custom", apiVersion: 1, protocol: "anthropic", async *stream(request, context) { /* ... */ }, } ``` ### Authentication AgentUse core owns restrictive credential-file permissions, credential persistence, cross-process refresh locking, status reporting, and deletion. Plugins return opaque credentials and implement provider-specific login, refresh, and request resolution. ```ts theme={"system"} auth: { methods: [{ id: "oauth", type: "oauth", name: "Acme SSO", environment: ["ACME_TOKEN"], async login(interaction, context) { await interaction.openBrowser({ url: authorizationUrl }); const code = await interaction.prompt({ message: "Paste the authorization code:", secret: true, }); return exchangeCode(code, context.signal); }, async refresh(credential, context) { return refreshToken(credential, context.signal); }, resolve({ credential }, context) { const token = context.env.ACME_TOKEN ?? credential?.access; return token ? { bearerToken: token, source: "Acme OAuth" } : undefined; }, }], } ``` Login interaction is UI-neutral and supports browser authorization, device codes, prompts, selections, and notifications. The same plugin therefore works in the terminal, desktop app, server, and CI environments. Credentials with a numeric `expires` property are refreshed five minutes before expiry. AgentUse serializes refreshes and persists the returned credential before resolving request authentication. Declared environment credentials are resolved first, so an explicit process token is never blocked by an expired stored credential. When an adapter takes ownership of legacy provider OAuth, AgentUse moves it atomically into the adapter's method-specific credential slot. ### Readiness checks A provider that needs something on the machine besides a credential, such as a bridged local CLI, declares an optional `check()`. AgentUse runs it for `agentuse provider list`, the dashboard Providers tab, and right after `agentuse plugins install`, and refuses to build a model for the provider while it fails, so an installed bridge never reports as connected when it cannot run. ```ts theme={"system"} agentuse.registerProvider({ id: 'acme-cli', name: 'Acme CLI', models: discoverAcmeModels, transport: { kind: 'custom', apiVersion: 1, stream: streamAcme }, async check({ env, signal }) { try { const version = await runAcme(['--version'], { env, signal }); return { ok: true, detail: `acme ${version}` }; } catch (error) { return { ok: false, message: `Acme CLI not found: ${error.message}.`, fix: 'npm install -g @acme/cli', }; } }, }); ``` `detail` is shown beside the connected badge. `message` says what is missing and `fix` is a command the user can run. A check that throws or takes longer than ten seconds counts as not ready. The dashboard Providers tab renders saved providers immediately, then updates each row as readiness and recent connection checks finish. A row distinguishes **Connected**, **Not verified** or **Not checked**, **Reconnect required**, **Temporarily unavailable**, and **Not connected**, so a stored credential is not presented as proof of a working connection. From the Plugins tab, **open in Providers** uses a `?provider=` link that opens Settings with the matching provider row expanded. ### Provider-owned prompts Prompt contributions have stable IDs and ownership metadata: ```ts theme={"system"} prompts: { system() { return [{ id: "identity", content: "You are the Acme coding agent.", position: "prepend", portable: false, }]; }, } ``` Non-portable contributions are removed when model fallback crosses providers. Their IDs are scoped to the registering provider; extensions do not need to compare raw system-message strings. ### Built-in provider adapters, patches, and overrides A plugin can conditionally contribute a transport to an existing provider namespace. The adapter is evaluated before the built-in transport; when its predicate returns `false`, the built-in provider continues unchanged: ```ts theme={"system"} agentuse.registerProvider("openai", { name: "Acme SSO transport", models: { inherit: "openai", patch: { cost: { input: 0, output: 0 } }, }, transport: { kind: "openai-responses", baseURL: "https://models.acme.test/v1", }, auth: { methods: [acmeSso] }, async when(context) { return Boolean(await context.auth.resolve("sso")); }, priority: 100, }); ``` Registering an adapter does not activate it by itself. Its `when` function receives the normal provider runtime context, including scoped authentication, and is evaluated whenever AgentUse selects provider behavior. If several adapters match, the highest `priority` wins; equal priorities retain plugin registration order. The selected adapter owns transport, authentication, model metadata, prompt contributions, and media capabilities for that request. If `models` is omitted, the existing provider catalog and model IDs are inherited unchanged. A plugin can patch a built-in endpoint without replacing its models: ```ts theme={"system"} agentuse.registerProvider("anthropic", { baseURL: "https://proxy.acme.test/anthropic", headers: { "X-Acme-Tenant": "engineering" }, }); ``` A complete replacement must be explicit: ```ts theme={"system"} agentuse.registerProvider({ id: "anthropic", name: "Acme Anthropic", override: true, models: { inherit: "anthropic" }, transport: { kind: "anthropic-messages" }, }); ``` Accidental built-in ID collisions are rejected. Registrations are removed when their plugin host is disposed. ## Distributed packages ### Curated provider plugins AgentUse maintains a deliberately small, release-reviewed shortlist for the provider setup experience. These plugins remain third-party executable code: review their source and project status before installing them. Browse the current choices in **Settings > Providers**. Each provider card shows its publisher, reviewed version, installation source, and authentication requirements. Community providers maintain their own setup instructions; follow the linked repository for provider-specific credentials and limitations. Some providers use credentials managed by an external application rather than an AgentUse login. The shortlist is bundled with AgentUse rather than fetched from a mutable remote marketplace. A new or changed listing therefore goes through the normal AgentUse release review. The dashboard also exposes an advanced GitHub installation path. It requires an explicit tag or full commit, reads only `package.json` before showing consent, and installs the exact commit that was inspected. The resulting plugin is labelled **Unreviewed**. Installed provider plugins can be updated or removed from **Settings > Providers**; removing a package does not delete its saved credential. The v0.21 compatibility migration is narrower than normal installation: when AgentUse finds an Anthropic OAuth credential written by the removed core flow, it installs the pinned compatibility plugin and adopts the credential without interrupting the user. New users still choose the plugin explicitly. A Git repository package declares its resources in `package.json`: ```json theme={"system"} { "name": "@example/agentuse-provider", "version": "1.0.0", "keywords": ["agentuse-plugin"], "peerDependencies": { "agentuse": "*" }, "agentuse": { "apiVersion": 1, "extensions": ["./src/index.ts"], "providers": [ { "id": "acme", "auth": ["oauth"] } ] } } ``` `agentuse.providers` is optional static metadata for the dashboard's safe pre-install preview. It does not register the provider; the extension still does that during activation. Extension entry paths must stay inside the plugin package. Runtime dependencies belong in `dependencies`. Git installation uses `npm install --omit=dev --ignore-scripts`; package lifecycle scripts never run implicitly. ## Installing and managing packages ```bash theme={"system"} agentuse plugins install owner/repository agentuse plugins install git:github.com/owner/repository@v1 agentuse plugins install https://github.com/owner/repository.git agentuse plugins list agentuse plugins update agentuse plugins update @example/agentuse-provider agentuse plugins remove @example/agentuse-provider agentuse plugins uninstall @example/agentuse-provider # alias ``` Use `-l` for project scope: ```bash theme={"system"} agentuse plugins install -l ./my-plugin agentuse plugins install -l owner/repository agentuse plugins list -l agentuse plugins update -l agentuse plugins remove -l @example/agentuse-provider ``` `agentuse plugins install ./my-plugin` links the local directory directly, globally by default or into the project with `-l`. AgentUse validates and activates its current working tree without cloning it, so the folder does not need to be a Git repository and uncommitted edits are available on the next process start. Updating a linked plugin revalidates its manifest; removing it only removes the registry record and never deletes the source directory. `plugins update` reports "already up to date" when a linked package's version is unchanged or a source pinned to a tag or commit still resolves to the installed commit. Append a full commit SHA (`./my-plugin@`) to clone and pin a local Git checkout instead of linking it. Global packages live under `$AGENTUSE_DATA_DIR/plugins`, which defaults to `~/.local/share/agentuse/plugins`. Managed project packages live under `.agentuse/packages`; linked plugins in either scope remain in their original directories. Both are recorded in `.agentuse/plugins.json`. `agentuse plugins list --all-scopes` displays every scope and marks linked entries. Git tags, branches, and commits can be selected with `@ref`. Updates retain the configured ref. Git installation and updates clone into staging, install safe runtime dependencies, compile and activate every entry, and only then replace the active checkout. A failed validation leaves the working version in place. The shorter `agentuse install|update|list|remove` commands remain as compatibility aliases. # Remote Agents Source: https://docs.agentuse.io/guides/remote-agents Run agents directly from URLs ## Overview AgentUse can execute agents directly from HTTPS URLs, enabling: * Shared agent libraries * Version-controlled agents * Community agent repositories * Dynamic agent loading Remote agents must use HTTPS and have the `.agentuse` file extension for security. ## Running Remote Agents ### Basic Usage ```bash theme={"system"} # Run from GitHub agentuse run https://raw.githubusercontent.com/user/repo/main/agent.agentuse # Run from your server agentuse run https://example.com/agents/helper.agentuse # Run from Gist agentuse run https://gist.githubusercontent.com/user/id/raw/agent.agentuse ``` ### With Arguments ```bash theme={"system"} agentuse run https://example.com/agent.agentuse "Process this data" ``` ## Security Remote agents run with the same permissions as local agents. Always review the agent content before execution. Only run agents from trusted sources! ### Security Prompt When running a remote agent, you'll see a security prompt: ``` ⚠️ WARNING: You are about to execute an agent from: https://example.com/agent.agentuse Only continue if you trust the source and have audited the agent. [p]review / [y]es / [N]o: ``` **Options:** * `p` or `preview` - Show the agent content before deciding * `y` or `yes` - Execute the agent immediately * `N` or `no` - Abort execution (default) ## Performance Remote agents are downloaded and executed directly without caching. Each run fetches the latest version from the URL, ensuring you always run the most up-to-date agent code. ## Publishing Agents ### GitHub Repository 1. Create a repository for your agents: ``` my-agents/ ├── README.md ├── data-processor.agentuse ├── text-analyzer.agentuse └── api-caller.agentuse ``` 2. Access raw files: ```bash theme={"system"} agentuse run https://raw.githubusercontent.com/username/my-agents/main/data-processor.agentuse ``` ### GitHub Gist 1. Create a Gist with your agent 2. Get the raw URL 3. Share the URL for others to use ### Self-Hosted Serve agents from your server: ```javascript theme={"system"} // Express example app.get('/agents/:name', (req, res) => { const agentContent = getAgent(req.params.name); res.type('text/plain').send(agentContent); }); ``` For local development, AgentUse allows HTTPS URLs with localhost or 127.0.0.1 and will accept self-signed certificates for these addresses only. ## Versioning ### Using Git Tags ```bash theme={"system"} # Specific version agentuse run https://raw.githubusercontent.com/user/repo/v1.0.0/agent.agentuse # Latest stable agentuse run https://raw.githubusercontent.com/user/repo/stable/agent.agentuse # Development version agentuse run https://raw.githubusercontent.com/user/repo/dev/agent.agentuse ``` ### Version in URL ```bash theme={"system"} # Semantic versioning in path agentuse run https://example.com/agents/v2/processor.agentuse agentuse run https://example.com/agents/v1/processor.agentuse ``` ## Advanced Usage ### Dynamic Loading Load agents based on conditions: ```javascript theme={"system"} // Dynamic agent loader const agentUrl = process.env.PROD ? 'https://prod.example.com/agent.agentuse' : 'https://dev.example.com/agent.agentuse'; execSync(`agentuse run ${agentUrl}`); ``` ### Agent Composition Remote agents as sub-agents: ```yaml theme={"system"} --- name: orchestrator model: anthropic:claude-sonnet-5 subagents: - path: https://example.com/agents/analyzer.agentuse - path: https://example.com/agents/reporter.agentuse --- ``` ### CI/CD Integration For automation, you can use expect or other tools to handle the security prompt: ```yaml theme={"system"} # GitHub Actions name: Run Remote Agent on: [push] jobs: agent: runs-on: ubuntu-latest steps: - run: pnpm install -g agentuse - run: | echo "y" | agentuse run https://example.com/agents/ci-checker.agentuse \ "Check PR #${{ github.event.pull_request.number }}" ``` ## Best Practices AgentUse enforces HTTPS URLs to prevent man-in-the-middle attacks. HTTP URLs will be rejected. Remote agents must have the `.agentuse` file extension for security validation. Use the preview option to review agent code before execution in untrusted environments. Include version information in URLs or use Git tags for reproducible deployments. Clearly document what MCP tools and environment variables your agent needs. ## Example: Shared Team Agents ### Repository Structure ``` team-agents/ ├── README.md ├── daily/ │ ├── standup.agentuse │ └── report.agentuse ├── development/ │ ├── code-review.agentuse │ └── test-runner.agentuse └── deployment/ ├── pre-deploy.agentuse └── post-deploy.agentuse ``` ### Team Usage ```bash theme={"system"} # Daily standup agentuse run https://raw.githubusercontent.com/team/agents/main/daily/standup.agentuse # Code review agentuse run https://raw.githubusercontent.com/team/agents/main/development/code-review.agentuse # Deployment agentuse run https://raw.githubusercontent.com/team/agents/main/deployment/pre-deploy.agentuse ``` ## Troubleshooting * AgentUse only accepts HTTPS URLs for security * Ensure your URL starts with `https://` * HTTP URLs will be rejected with an error * Remote agents must have the `.agentuse` file extension * Ensure your URL ends with `.agentuse` * Ensure you're using the raw file URL, not the GitHub page URL * For GitHub: use `https://raw.githubusercontent.com/...` * Check if the repository is public * Verify the branch/tag name * Verify the URL is correct and accessible * Check if corporate proxy or firewall is interfering * Ensure the remote server has valid SSL certificates ## Security Checklist * [ ] Only run agents from trusted sources * [ ] Use the preview option to review agent code before running * [ ] Ensure remote URLs use HTTPS and have `.agentuse` extension * [ ] Implement access controls on agent servers * [ ] Monitor agent execution logs * [ ] Rotate API keys regularly * [ ] Use environment-specific agents * [ ] Verify server SSL certificates are valid ## Next Steps Compose agents together See remote agent examples # Replay recorded inputs Source: https://docs.agentuse.io/guides/replay Test current instructions against a real session's recorded tool results, without live tool operations. For instruction improvement, start with `agentuse test result --session `: it supplies source evidence directly without depending on matching tool calls. See [Testing agents](/guides/testing-agents). This page documents the advanced strict-replay compatibility command. Use replay when you are changing an agent's instructions and want to hold its external inputs fixed: ```bash theme={"system"} agentuse test agents/x/reply.agentuse --replay ``` The writer runs again. Its tools return recorded results instead of opening browsers, running commands, updating stores, or starting child agents. No mock model is needed. This is a fresh generation, not a continuation of the source session. ## What stays fixed and what changes * **Current:** the local agent definition and configured model, explicit preloaded skills, applicable learnings, and explicitly granted read-only reference files. Replay reads learnings without recording usage. * **Recorded:** the original additional user prompt, tool schemas, external results and errors. Relative dates use the original session's start date. * **Withheld from the writer:** the old assistant draft, its approval proposal, later revisions and human feedback. Those appear only in the comparison. Explicit read-only **file** grants are snapshotted before generation so edits to writing briefs take effect. Directory and wildcard grants stay recorded because they may contain source data or drafts. The report lists refreshed files and hashes; do not treat a refreshed data file as frozen evidence. Inline agent instructions and preloaded skills are always current. Dynamic skill/tool requests use their recordings. ## Where it stops Replay captures the first `await_human` input **before gate preflight, automated verification or human approval**. It does not grant approval, run revisions, or publish. An agent that finishes without a gate yields its final output. An explicit incomplete report remains incomplete. A tool call without a matching recording stops the test with `REPLAY_INPUT_MISSING`. No live lookup or LLM fabrication fills the gap. The failed call and its exact inputs appear in the report. Matching uses the tool name and arguments. Object key order and the narration field `intent` do not matter; filesystem read paths are normalized. Other arguments, including shell commands, URLs, prompts and array order, must match. Repeated calls consume matching recordings in their original order. `store_list` permits a different field projection when filters are identical and the requested page is contained in the recorded page and every requested value or known absence is recorded. Metadata requests (such as `id` and `title`) use the metadata already present on each row. Unknown data fields still stop the replay. Projection provenance appears in the report. `store_create` writes to an isolated in-memory store with fresh `replay-` IDs. Those items support `store_get`, `store_update`, and `store_delete`, so new drafts can change without touching production. Queries after these writes are not yet supported; replay stops rather than returning stale recorded lists. Only recordings before the source's **first** approval gate are available. For an ungated run, later user continuations are excluded. Mock and replay sessions cannot be used as sources. An actively running source must first finish or reach approval. ## Read the result The CLI prints the old and new proposal/output and a path to `replay.json`. With `--json`, it emits the structured comparison, refreshed-reference hashes, per-call recording provenance and any mismatch: ```bash theme={"system"} agentuse test agents/x/reply.agentuse --replay --json ``` The new session is marked as a test (`mock: true`) and stores `config.replaySourceSessionId`. It does not modify or resume the original session. Replay sessions cannot be resumed as live runs; run another replay to try the next instruction change. Exit status is 0 for a captured proposal or completed output, and 1 for a mismatch, incomplete outcome or execution error. Success means the comparison was captured, **not** that the draft passed a quality review. ## First-version limits Replay supports recorded text/JSON tool results. Tool schemas are frozen, so this command measures instruction changes, not a migration to new tools. A changed query, a new research request, or a write/dry-run containing newly generated text may not have a matching recording. That is a visible mismatch, not permission to return unrelated old data. No shell command executes, including commands that are usually read-only or called “dry run.” This command does not support `--scope`, `--approval`, `--mock-model`, a remote agent URL, or an additional prompt. Use ordinary `agentuse test` for mocked flow testing. Judge regression against past human decisions is a separate operation; replay deliberately captures the writer before the judge intervenes. ## Experimental fixed-input extraction Full workflow replay still depends on recorded calls. For testing an agent's output from fixed evidence, the prototype `scripts/extract-fixed-inputs.ts` asks a model to classify the source session's pre-approval tool results. It works across tool names and output formats; it does not assume the output is writing. It does not grade the output or rerun the agent. The selector distinguishes source evidence, agent-produced material, feedback, reference instructions, irrelevant records, and uncertain provenance. It sees call arguments to detect generated material read back through another tool. Only tool-result text is selectable. Code validates complete classification, source IDs, exact excerpts, and exclusion of known mutation outputs. Classifier reasons stay in a separate audit, not the evidence pack. This is LLM-assisted selection, not a guarantee of semantic purity: arbitrary tools can return mixed evidence and generated content, and classification can be wrong. Inspect the audit before treating a pack as a regression fixture. The model receives broader historical tool data than the eventual input pack; use an endpoint authorized for that data. No tool executes during extraction. From the source checkout, build the standalone prototype for Node: ```bash theme={"system"} bun build scripts/extract-fixed-inputs.ts --target node --packages external --outfile scripts/extract-fixed-inputs.local.mjs ``` Then run from the original agent's project so session storage resolves correctly: ```bash theme={"system"} node /path/to/agentuse/scripts/extract-fixed-inputs.local.mjs SESSION_ID /path/to/new-output-directory openai:gpt-5.6-sol ``` The output is `input-pack.json`, `selection-audit.json`, `source-records.json`, and a separate `baseline.json`. The pack contains exact excerpts, hashes, and UTF-16 string offsets; old assistant output and classifier explanations are not copied into it. Reference instructions should be supplied fresh to the output-generation step. Large sessions currently fail an explicit size limit instead of silently truncating evidence. The public `agentuse test result` command now uses this validated selection primitive and caches evidence for reuse. The standalone script remains useful for inspecting extraction separately. ## Experimental output loop `scripts/loop-x-output.ts` reuses an existing fixed-input pack for a controlled X reply experiment. It performs fresh generation, conversation and evidence checks, then instruction revision only after failure. The canonical brief, source pack, model and evaluator criteria remain fixed. A passing draft stops the loop without forced polishing; three failed rounds exhaust the run. The reviser produces a separate test-guidance paragraph. The next writer sees that guidance, not the prior drafts, judgments, or historical baseline. Nothing is written back to production instructions and no publishing tools exist in the experiment. Automated acceptance is not proof of improvement or permission to publish. A single example cannot establish a general instruction improvement. Build from the source checkout and run from the source agent's project: ```bash theme={"system"} bun build scripts/loop-x-output.ts --target node --packages external --outfile scripts/loop-x-output.local.mjs node /path/to/agentuse/scripts/loop-x-output.local.mjs /path/to/input-pack.json /path/to/brief.md /path/to/judge.agentuse /path/to/new-output-dir openai:gpt-5.6-sol /path/to/baseline.json ``` The result directory preserves every role's exact request/response, each round's judgment and instruction revision, frozen inputs, hashes, and the final status. The optional historical baseline is loaded only after all model calls finish. This prototype is separate from the public `agentuse test` command. # Sandbox Source: https://docs.agentuse.io/guides/sandbox Run agent commands in an isolated Docker container The `sandbox` configuration and container execution contract are experimental and may change without migration. This label is not a security guarantee; use the isolation boundaries documented below when evaluating untrusted work. The sandbox runs agent commands inside a Docker container while the **filesystem tool** handles all file I/O on the host. This separation means the agent can execute arbitrary shell commands safely without risking your host system, while file changes flow bidirectionally through bind mounts. ## Quick Start Add `sandbox: true` and configure filesystem paths: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 sandbox: true tools: filesystem: - path: ${root} permissions: [read, write] --- Analyze the project. Run tsc --noEmit to find type errors, then fix them. ``` **Docker** must be installed and running. The image is pulled automatically if needed. ## How Sandbox and Filesystem Work Together The sandbox **only** provides command execution. All file access is controlled by the filesystem tool: ```mermaid theme={"system"} flowchart TB Agent["🤖 Agent"] FS["Filesystem tool
read / write / edit"] SB["sandbox__exec
run shell commands"] Host["Host Files"] Container["Docker Container"] Agent --> FS Agent --> SB FS --> Host SB --> Container Host <-->|"bind mount
(same paths)"| Container ``` * **Filesystem tool** reads/writes files on the host — changes appear inside the container instantly via bind mount * **`sandbox__exec`** runs commands inside the container — if the mount is read-write, file changes flow back to the host * **Paths are identical** in host and container (no `/workspace/` alias) ### What Gets Mounted Each filesystem path from your config is mounted at its **real host path** with the mode derived from its permissions: ```yaml theme={"system"} tools: filesystem: - path: ${root} permissions: [read] # → mounted read-only - path: ${root}/src permissions: [read, write] # → mounted read-write - path: ${tmpDir} permissions: [read, write] # → mounted read-write (e.g. /tmp) ``` Glob patterns (e.g. `${root}/**/*.ts`) are skipped — only concrete directories can be mounted. If no filesystem tool is configured, the project root is mounted read-only. Sandbox refuses to bind-mount `$HOME` (or any ancestor) as the project root. If a project marker like `.git`, `.agentuse`, or `package.json` exists at `$HOME` (common for dotfile repos or per-user config dirs), creation fails with a clear error. Run the agent from inside a real project directory, or declare an explicit `filesystem` mount. ## Configuration Use `sandbox: true` for defaults (Docker, `node:22-slim`), or provide a config object: ```yaml theme={"system"} sandbox: true # defaults sandbox: # full config provider: docker image: python:3.12-slim # default: node:22-slim timeout: 10m # default: 300 seconds setup: # run after container starts - pip install pandas numpy ``` | Field | Type | Default | Description | | - | - | - | - | | `provider` | `string` | — | Must be `docker` | | `image` | `string` | `node:22-slim` | Docker image (auto-pulled if missing) | | `timeout` | `number \| string` | `300` | Max container lifetime. Bare numbers mean seconds; duration strings such as `"10m"` are accepted | | `setup` | `string \| string[]` | — | Commands to run before agent starts | | `env` | `string[]` | — | Host env var names to forward into the container | If any setup command fails (non-zero exit), sandbox creation is aborted. **Common images:** * `node:22-slim` — Node.js / TypeScript (default) * `python:3.12-slim` — Python / data science * `ubuntu:24.04` — General purpose * `golang:1.23` / `rust:1.84-slim` — Go / Rust Need multiple runtimes? Use `setup` to install them (e.g. `apt-get install -y nodejs`). ### Environment Variables The container starts with a **clean environment** — no host env vars are passed in, even if they are defined in your project's `.env` file. AgentUse loads `.env` into the host process, but the sandbox container does not inherit them. To forward specific env vars into the container, use the `env` allowlist: ```yaml theme={"system"} sandbox: provider: docker env: - OPENAI_API_KEY # from .env or shell environment - DATABASE_URL ``` Only declared vars that exist on the host are forwarded. Unset vars are silently skipped. ## Examples ### TypeScript Code Fix ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 sandbox: true tools: filesystem: - path: ${root} permissions: [read, write] # write also grants edit --- You are a code quality agent. Run tsc --noEmit to find type errors, then fix them and verify. ``` ### Python Data Processing ```yaml theme={"system"} --- model: openai:gpt-5.4-mini sandbox: provider: docker image: python:3.12-slim setup: pip install pandas matplotlib tools: filesystem: - path: ${root} permissions: [read, write] store: true --- You are a data analysis agent. Run analysis scripts, save charts to the project, and store key metrics. ``` ### Security Scanning (Read-Only) ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 sandbox: provider: docker setup: npm install -g snyk tools: filesystem: - path: ${root} permissions: [read] store: true --- You are a security scanning agent. Run snyk test, identify critical vulnerabilities, and store findings. ``` ## Lifecycle 1. **Cleanup** — Remove any orphaned containers from previous runs (crash/force-quit safe) 2. **Pull** — Auto-pull the Docker image if not available locally 3. **Create** — Start container with filesystem paths bind-mounted at real host paths 4. **Setup** — Run `setup` commands sequentially inside the container 5. **Execute** — Agent uses `sandbox__exec` for commands, filesystem tool for file I/O 6. **Teardown** — Container is stopped and removed when the session ends, times out, or is aborted Need to run AgentUse itself inside Docker? See the self-hosting guide. # Scheduled Agents Source: https://docs.agentuse.io/guides/schedule Run agents on a recurring schedule using cron expressions or intervals Run agents automatically on a schedule using `agentuse serve`. Configure schedules in agent frontmatter with cron expressions or intervals. ## Quick Start 1. Add a `schedule` config to your agent: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 schedule: "1h" --- Check the system status and send a summary report. ``` 2. Start the server: ```bash theme={"system"} agentuse serve ``` The server displays scheduled agents on startup: ``` Scheduled (1) Agent Schedule Next Run monitor.agentuse 0 * * * * Jan 01, 12:00 ``` ## Pause or resume a schedule Pause a declared schedule without editing the agent file: ```bash theme={"system"} agentuse schedules agentuse schedules pause agents/daily.agentuse agentuse schedules resume agents/daily.agentuse ``` The agent's `schedule` frontmatter remains unchanged and visible. Pause state is stored for the current deployment, so another deployment of the same project can run the schedule independently. You can use the same controls from the agent page or the Schedules page in the dashboard. Newly suggested schedules created through guided project discovery start paused until you test and enable them. ## Schedule Formats The `schedule` field accepts a single string value. The format is auto-detected: ### Intervals Simple duration format for recurring tasks: ```yaml theme={"system"} schedule: "30m" ``` Supported units: | Unit | Example | Max | Description | | - | - | - | - | | `s` | `30s` | 59 | Seconds | | `m` | `10m` | 59 | Minutes | | `h` | `2h` | 23 | Hours | For daily or longer schedules, use cron expressions. ### Cron Expressions Standard cron syntax for precise control: ```yaml theme={"system"} schedule: "0 9 * * 1-5" # Weekdays at 9am ``` Common patterns: | Pattern | Description | | - | - | | `0 * * * *` | Every hour | | `*/15 * * * *` | Every 15 minutes | | `0 9 * * *` | Daily at 9am | | `0 0 * * 0` | Weekly on Sunday | | `0 0 1 * *` | Monthly on the 1st | | `0 9 * * 1-5` | Weekdays at 9am | Use [crontab.guru](https://crontab.guru) to build and validate cron expressions. ### Timezone Cron expressions and intervals are evaluated in the **local timezone of the machine running `agentuse serve`**, not UTC. The times you write are literal wall-clock times for that server. Daylight saving transitions are handled automatically, so `0 9 * * 1-5` stays at 9am local across the year. To pin a schedule to a specific zone, run the server with `TZ` set (for example `TZ=UTC agentuse serve` or `TZ=America/New_York agentuse serve`). ## Example A scheduled agent for daily reports: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: Generate daily analytics report schedule: "0 8 * * 1-5" # Weekdays at 8am tools: filesystem: - path: ${root}/data permissions: [read] bash: commands: - "curl *" --- Generate the daily analytics report and save it to reports/daily.md. ``` Use cheaper models like `openrouter:minimax/minimax-m3` for frequent, straightforward tasks (health checks, simple monitoring). Reserve `claude-sonnet-4-6` and `claude-opus-4-8` for complex creative tasks. ## Server Options See [CLI Commands - agentuse serve](/reference/cli-commands#agentuse-serve) for all server options including port, host, and authentication configuration. ## Monitoring The server logs each scheduled execution: ``` [12:00:00] Running scheduled agent: monitor.agentuse [12:00:05] Completed: monitor.agentuse (5.2s) ``` Enable debug mode for detailed logs: ```bash theme={"system"} agentuse serve --debug ``` ## Scheduler Ownership and Recovery Only one `agentuse serve` process arms schedules for a project. The daemon records that ownership in `.agentuse/scheduler.lock`; other daemons keep serving the project but skip its schedules to prevent duplicate side effects. Lock and filesystem errors fail closed: AgentUse skips schedules rather than risking two daemons running them. A stale daemon lock is reclaimed automatically. Reclamation itself uses the short-lived `.agentuse/scheduler.lock.reclaim` guard. If a process is killed during that critical section, the guard can be left behind and scheduling stays disabled. After confirming no daemon is currently reclaiming the lock, remove `.agentuse/scheduler.lock.reclaim`, then touch an agent file or restart `agentuse serve`. The warning prints the exact file path to remove. ## Next Steps Trigger agents via HTTP Deploy in production # Self-Hosting Source: https://docs.agentuse.io/guides/self-hosting Run AgentUse in Docker for local development or production deployment ## Why Self-Host? Host on your infrastructure. Your data and API keys never leave your network. Deploy multiple instances behind a load balancer as demand grows. Expose agents via HTTP API for integration with other services. Same container runs identically across machines. Share your setup with teammates. ## Quick Start ```bash theme={"system"} docker run -d --name agentuse \ -p 12233:12233 \ -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \ -v $(pwd)/agents:/agents \ ghcr.io/agentuse/agentuse:latest ``` Test it: ```bash theme={"system"} curl http://localhost:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "/agents/hello.agentuse"}' ``` ## Local Development For local development, mount your credentials and workspace instead of using environment variables: ```bash theme={"system"} docker run -d --name agentuse-dev \ -p 12233:12233 \ -v ~/.local/share/agentuse:/root/.local/share/agentuse \ -v $(pwd):/workspace \ -w /workspace \ ghcr.io/agentuse/agentuse:latest ``` This gives the container access to your OAuth tokens, API keys, and session logs from `agentuse auth login`. Run agents via exec: ```bash theme={"system"} docker exec -it agentuse-dev agentuse run my-agent.agentuse ``` Add `alias agentuse-docker='docker exec -it agentuse-dev agentuse'` to your shell profile for convenience. OAuth tokens may expire. If you encounter auth errors, run `agentuse auth login` on your host to refresh. ## Configuration ### Environment Variables | Variable | Description | | - | - | | `ANTHROPIC_API_KEY` | Anthropic Claude API key | | `CLAUDE_CODE_OAUTH_TOKEN` | Claude subscription OAuth token; requires the Claude Code subscription provider plugin | | `OPENAI_API_KEY` | OpenAI API key | | `OPENROUTER_API_KEY` | OpenRouter API key | | `OPENCODE_GO_API_KEY` | OpenCode Go API key | | `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_REGION` | Amazon Bedrock (SigV4 auth) | | `AWS_SESSION_TOKEN` | Optional Bedrock session token (temporary credentials) | | `AWS_BEARER_TOKEN_BEDROCK` | Amazon Bedrock API key (Bearer auth, alternative to SigV4) | At least one AI provider authentication is required. `ANTHROPIC_API_KEY` works with the built-in provider. `CLAUDE_CODE_OAUTH_TOKEN` works only when the Claude Code subscription provider plugin is installed in the container or mounted project scope. ### Using an Environment File ```bash theme={"system"} docker run -d -p 12233:12233 --env-file .env \ -v $(pwd)/agents:/agents \ ghcr.io/agentuse/agentuse:latest ``` ### Restarts and Worker Memory `agentuse serve` runs agents in per-project worker processes, and two behaviours matter when you put it behind `pm2`, `systemd`, or a container supervisor. **A restart releases workers rather than killing them.** Runs already in flight keep going in the released worker and finish normally; only the daemon is replaced. A released worker still has a hard deadline, by default the longest in-flight run's own timeout plus ten minutes of grace, tunable with `AGENTUSE_RELEASE_BACKSTOP_SECONDS`. Set `AGENTUSE_RELEASE_WORKERS=0` if you want the old kill-on-shutdown behaviour instead. **Idle workers are recycled once they get heavy.** A fresh worker peaks around 130MB of heap; after it has executed runs, that settles at roughly 350-450MB, which a long-lived daemon would otherwise hold forever. When an idle worker is above `AGENTUSE_WORKER_RECYCLE_MB` (default 300) it is retired through the same release path, so a replacement starts serving immediately. Recycling only happens while the worker is idle, and never within two minutes of it starting. Set `AGENTUSE_WORKER_RECYCLE_MB=0` to disable it. **After a crash, settle the stragglers.** If the host or the container died outright, sessions can be left marked `running` with no process behind them. `agentuse serve` sweeps these at startup, but only back 30 days: ```bash theme={"system"} docker exec -it agentuse agentuse sessions reconcile --all --dry-run docker exec -it agentuse agentuse sessions reconcile --all ``` Runs that are genuinely still executing are never touched. See [CLI Commands](/reference/cli-commands#reconcile-stuck-sessions). ## Including Your Agents **Volume mount** (best for development): ```bash theme={"system"} -v $(pwd)/agents:/agents ``` **Bake into image** (best for production): ```dockerfile theme={"system"} FROM ghcr.io/agentuse/agentuse:latest COPY ./agents /agents ``` ## Docker Compose ```yaml theme={"system"} # docker-compose.yml version: '3.8' services: agentuse: image: ghcr.io/agentuse/agentuse:latest ports: - "12233:12233" environment: - ANTHROPIC_API_KEY - OPENAI_API_KEY volumes: - ./agents:/agents restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:12233/api"] interval: 30s timeout: 10s retries: 3 ``` ## Extending the Base Image ```dockerfile theme={"system"} FROM ghcr.io/agentuse/agentuse:latest RUN apk add --no-cache ffmpeg imagemagick RUN pip3 install --no-cache-dir pandas numpy requests RUN npm install -g typescript puppeteer COPY ./agents /agents ``` ### Multi-arch Build ```bash theme={"system"} docker buildx build \ --platform linux/amd64,linux/arm64 \ -t myregistry/agentuse:latest \ --push . ``` ## Production Deployment ### Reverse Proxy with nginx ```nginx theme={"system"} server { listen 443 ssl; server_name agents.example.com; location / { proxy_pass http://127.0.0.1:12233; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 300s; } } ``` Start serve with `--public-url https://agents.example.com` (or set `serve.publicUrl`) so approval links use the public address and a keyless daemon accepts requests for that host. ```nginx theme={"system"} limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; location / { limit_req zone=api burst=20 nodelay; proxy_pass http://127.0.0.1:12233; } ``` ```bash theme={"system"} certbot --nginx -d agents.example.com ``` ## Troubleshooting Check logs with `docker logs agentuse`. Common causes: missing API keys, port already in use. The official image binds to `0.0.0.0` by default. If using a custom image, ensure: ```dockerfile theme={"system"} ENTRYPOINT ["/usr/local/bin/agentuse", "serve", "-H", "0.0.0.0"] ``` Check the volume mount with `docker exec -it agentuse ls /agents`. Ensure API request paths match container paths. # Operations Dashboard Source: https://docs.agentuse.io/guides/serve-dashboard Monitor runs, approvals, results, metrics, and notifications in the AgentUse serve web app The dashboard and approval UI are supported product surfaces. The JSON API response shapes and Web Push delivery contract remain experimental and may change without migration while those integrations mature. `agentuse serve` includes an operations dashboard for the agents loaded from your served projects: ```bash theme={"system"} agentuse serve ``` Open `http://127.0.0.1:12233`. The Home page streams: * agents running now, with recent output tickers * sessions waiting for approval * failed or verification-failed runs that need review * recent outcomes and upcoming schedules * deterministic metrics written through `record_metric` Pending approvals show one row per agent, with the newest gate on top. Older asks from the same agent sit under **N older asks**, and a red **blocking N runs** tag shows how many runs are held up. Gates more than two days old get a **reject N older** action. Failed runs from the last 30 days that you have not dismissed are grouped by blocker and subject. Each group shows its run count, the newest run's own words, and how the blocker was established. When the cached npm `latest` version is newer than the installed version, Home also shows a dismissible update banner. Its copy action uses the package manager that installed AgentUse. Dismissal is stored in that browser for that version, so a later release can appear normally. Mock and test sessions are excluded by default from all of these list-backed surfaces, and they never fire push notifications, so validating an agent does not distort the picture of what production is doing. They are still stored in full and remain inspectable: a mock session's page is reachable by id at any time, and the sessions list can show them on request. ## Review results Home's **Results** section groups the metrics recorded by each agent over the selected time window. Opening an agent row leads to the recent jobs behind those metrics. Each agent page also has a **Results** tab with that agent's own metric tiles; opening a tile shows the matching records in the metrics store. Recent jobs and the Sessions page mark finished runs whose result has not been opened yet. Opening the run clears that state. Completed, incomplete, and failed runs remain distinct, so partial work is not presented as a successful report. Sessions, Agents, Approvals, Schedules, Stores, and Dashboard preferences remain directly addressable routes. A session page is the durable record for one run: its activity, approval gate, tool output, result, metrics, verification verdict, and follow-up controls stay together. Press Command+Shift+C on macOS or Ctrl+Shift+C elsewhere to copy a shareable link to the current dashboard route. A confirmation appears after the URL is copied. From a completed, failed, or approval-paused session, **Revise agent file** starts a visible internal session that diagnoses the run and proposes a validated change for operator review. An agent that has never run can start the same workflow from its detail page, using the agent file as the starting evidence. The agent detail hub keeps the resulting history in its **Revisions** tab. See [Agent Revisions](/guides/agent-revisions) for apply, request-changes, discard, stale-source, and restore behavior. Settings can add an existing project or create a managed one, and can disconnect a project without deleting its files. For an existing project, guided discovery scans a sanitized, read-only view, accounts for agents already present, and proposes evidence-backed recurring work. Agent creation runs as a visible session, and any proposed schedule starts paused until you test and enable it. The agent and Schedules pages show declared cron expressions and deployment-local paused state. Pause or resume a schedule there, or with `agentuse schedules pause` and `agentuse schedules resume`, without editing agent frontmatter. Choose **Run with custom** from an agent or session action menu to supply a one-off instruction, select a different configured model, or do both. Leaving the model unchanged preserves the model declared by the agent. Provider setup in Settings supports Anthropic and OpenAI login or API keys, OpenRouter and OpenCode Go keys, plus custom OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages endpoints. ## Viewer preferences Dashboard preferences are local to the current Dashboard. In a browser they are saved in that browser only; in AgentUse for Mac they are saved in the Dashboard on that Mac. They do not change agents or server configuration. * Home sections and metric tiles can be hidden and reordered * Results can use 1, 7, 14, or 30-day windows * Metric tiles can render as a number, bars, or line chart * Agents can use cards, tables, metadata columns, grouping, and filters * Sessions can use list or feed views and combine status, agent, trigger, triage, and time-window filters * Sessions can set a "mock runs" filter to hidden (the default), shown, or only mock Preferences are stored in `localStorage` and synchronize between tabs through browser storage events. Clearing site data resets them. ## Install as a web app The dashboard ships a manifest, home-screen icons, self-hosted fonts, and a cache-first service worker. * **iPhone/iPad:** open the dashboard in Safari, use Share → **Add to Home Screen**, then launch the installed app * **Android/desktop Chromium:** use the browser's Install action when offered The manifest and icons are available before operator authentication so a token-only session link can still be installed. Cached static assets make repeat loads fast and tolerate a temporary network outage; live data and actions still require the daemon. If a browser deployment leaves a stale cached bundle after an update, open **Dashboard preferences** and use **Clear cached files & reload**. The service worker activates updates on the next open, and stale chunk failures trigger one controlled reload automatically. ## Web Push notifications Notification bells on Approvals, Sessions, and Dashboard preferences control two independent categories: * approval requests * session completions and failures (runs stopped on a person send no "Session failed" push) The first enable action registers the service worker, requests browser permission, creates a push subscription, and stores that subscription in the daemon. Later toggles update only the category preference. Turning off the last category removes the server record and unsubscribes the browser. Subscriptions and VAPID keys persist under the AgentUse XDG data directory. Endpoints reported gone by the push provider are removed automatically. Push delivery is best-effort; the dashboard and session log remain the source of truth. iOS Web Push works only from an installed Home Screen app. A normal Safari tab shows installation guidance instead of requesting a permission it cannot use. If permission is denied, AgentUse cannot reopen the browser prompt. Re-enable notifications in the browser or operating-system site settings, then return to Dashboard preferences. ## Badges and notification links Approval pushes carry the current pending count as an app badge. The dashboard resynchronizes the badge when the approvals list changes or a reviewer decides a gate, correcting any race between the run and the push. Notification taps open the associated session: * a warm installed app focuses an existing matching session window when possible * a cold iOS launch uses Declarative Web Push navigation and a short-lived cached target so the app can recover the requested session * the cached cold-launch target expires after two minutes ## Live updates and recovery The dashboard uses Server-Sent Events for live session and list updates. When a mobile tab returns to the foreground it reconnects automatically. An immediate HTTP status fetch paints a session before the event stream catches up, so a buffered or remote connection does not leave the page on an indefinite loading state. Long-running bash calls publish a bounded recent stdout/stderr tail after about two seconds. This preview is for people only: it is not added to model context, is removed when the call settles, and does not replace the final durable output. ## Security and deployment Local loopback deployments are open by default. Exposed hosts require `AGENTUSE_API_KEY` unless auth is explicitly disabled. Session capability links carry a token scoped to one session; operator pages and APIs still require the operator credential. The daemon sends `Content-Security-Policy: frame-ancestors 'self'`, `X-Frame-Options: SAMEORIGIN`, `Referrer-Policy: same-origin`, and `X-Content-Type-Options: nosniff` on its responses. For client-facing or demo deployments: ```json theme={"system"} { "serve": { "hideAgentSource": true, "brand": { "name": "Acme Operations" }, "terms": { "project": "workspace", "folder": "team|teams" } } } ``` See [Configuration Files](/reference/configuration-files) for these keys, [Approval Gates](/guides/approval-gates) for review behavior, and [Self-Hosting](/guides/self-hosting) for reverse-proxy deployment. # Session logs Source: https://docs.agentuse.io/guides/session-logs # Session Logs AgentUse automatically tracks every agent execution with detailed logs, providing full visibility into what happened during each run. ## Quick Start ```bash theme={"system"} # List recent sessions agentuse sessions # View session details (partial ID match supported) agentuse sessions show 01JFN8 # Show full tool inputs/outputs agentuse sessions show 01JFN8 --full # Export as JSON agentuse sessions show 01JFN8 --json ``` ## What Gets Tracked Each session captures: | Category | Data | | - | - | | **Session** | Agent name, model, MCP servers, project context, timestamps | | **Messages** | User prompts, system prompts, token usage, cost, duration | | **Parts** | Text output, tool calls, reasoning, step boundaries | | **Tools** | Tool name, input, output, duration, errors | ## CLI Reference ### List Sessions ```bash theme={"system"} agentuse sessions list [options] agentuse sessions ls [options] ``` **Options:** * `-s, --subagents` - Include subagent sessions * `-n, --limit ` - Limit results (default: 10) * `-j, --json` - Output as JSON * `--all` - Show sessions across all projects * `--project [path]` - Show sessions for a project path; defaults to the current project * `--no-mock` - Hide mock/test runs. The CLI lists them by default, marked `· mock` **Example output:** ``` Sessions for current project: /Users/you/project ID STATUS AGENT DATE -------------------------------------------------- 01JFN8K3M2P1 done daily-reporter Today 14:32 01JFN7XYZAB suspended seo-analyzer Yesterday 09:15 01JFN6DEFGH fail code-reviewer Mon 16:45 ``` Session state is stored globally and partitioned by project. The CLI defaults to the current project; use `agentuse sessions list --all` when you are looking for a session but are not sure which project owns it. ### Show Session Details ```bash theme={"system"} agentuse sessions show [options] ``` **Options:** * `-f, --full` - Show complete tool input/output (not truncated) * `-j, --json` - Output as JSON * `--project [path]` - Search a project path; defaults to the current project * `--all-search` - Search all projects if not found in the selected project **Example output:** ``` ════════════════════════════════════════════════════════════ SESSION: 01JFN8K3M2P1NRXZW4Y5V6Q7B8 ════════════════════════════════════════════════════════════ Agent: daily-reporter Description: Generate daily motivation quotes Model: anthropic:claude-sonnet-5 Started: 12/21/2025, 2:32:45 PM MCP Servers: postgres Project: /Users/you/project Working Dir: /Users/you/project ──────────────────────────────────────────────────────────── Task: Generate a daily motivation quote with an interesting fact Tokens: 1523 (in: 892, out: 631) Duration: 3.2s Parts: text: 2, tool: 3 Output: Here's today's motivation quote... ─── ✓ Postgres{query} (SELECT * FROM quotes...) 0.8s ──────── {"rows": [{"id": 1, "quote": "..."}]} ──────────────────────────────────────────────────────────── Generated your daily quote successfully! ``` ### Show Storage Path ```bash theme={"system"} agentuse sessions path agentuse sessions path --project ../other-project ``` Shows where session data is stored for the current project. ## Subagent Sessions Use `--subagents` to include subagent sessions in listings: ```bash theme={"system"} agentuse sessions list --subagents ``` ## Use Cases ### Debugging Failed Runs ```bash theme={"system"} # Find recent failed session agentuse sessions list | grep -i fail # View full details with complete tool outputs agentuse sessions show 01JFN8 --full ``` ### Cost Tracking ```bash theme={"system"} # Export sessions as JSON for analysis agentuse sessions list --json > sessions.json # Query costs with jq cat sessions.json | jq '.[].cost' ``` ### Audit Logging Session logs provide a complete audit trail: * What prompts were sent * Which tools were called with what inputs * What outputs were generated * Token usage and costs * Error details and stack traces ## Browse Sessions in the Browser When `agentuse serve` is running, the same sessions are browsable as web pages: * `/sessions` lists every run, newest first. Filter the list with `?agent=`, `?status=running|suspended|completed|error|incomplete` (`incomplete` matches only runs blocked on a person; other incomplete runs are listed under `error`), `?trigger=scheduled|manual|slack|api`, `?days=`, and `?mock=include|only`. Mock/test runs are hidden by default; `include` adds them to the list and `only` shows nothing else. A mock session's detail page is always reachable by id, filter or not. * `/sessions/` is the per-session page: the full run log, and when the session is suspended on an approval gate, the approve / reject / comment and resume controls. ### Internal agent-revision sessions A completed, failed, or approval-paused run can start a reviewable agent revision. The original session remains the launch point and durable history, with a link to each revision. An agent that has never run can instead start from its detail page and use the current agent file as evidence. The revision session links back to its origin when one exists and holds the diagnosis, source proposal or no-change result, reviewer feedback, apply decision, and restore action. The Sessions list and feed label these AgentUse-owned jobs as `internal revision`, group them under **Internal revisions**, and name them **Revising *agent***. They are distinct from delegated subagents and automated Judge sessions. See [Agent Revisions](/guides/agent-revisions) for the full review and write-safety workflow. For delegated runs, the parent timeline also surfaces important work from nested descendants. Reviewer comments appear as timestamped feedback; a child working on that feedback is labeled `revising`, and its next gate is labeled `awaiting-approval`. Judge sessions are identified as automated pre-review attempts so they are not mistaken for human decisions. The `/agents` page opens each agent's detail hub, where you can inspect source, recent runs and revisions, and start a run. Schedule rows also link to the agent detail hub; last-run badges still link to the matching session page. When the model streams its reasoning, it renders inline in the log as dimmed "Reasoning" entries (the model's "why", subordinate to the visible answer it precedes). This is on by default for reasoning-capable OpenAI models; for Claude it requires opting into extended thinking. See [model configuration](/guides/model-configuration#provider-options) for the `openai.reasoningSummary` and `anthropic.thinking` options. ```bash theme={"system"} agentuse serve open http://127.0.0.1:12233/sessions ``` If a session is stuck at `running` long after its process is gone, usually after a crashed daemon or a killed container, settle it with [`agentuse sessions reconcile`](/reference/cli-commands#reconcile-stuck-sessions). Runs that are still executing are never touched. On an exposed host these pages require the API key, or a per-session token on the session page link. See [Approval Gates](/guides/approval-gates#auth-and-the-session-token). ## Related * [Session Storage Reference](/reference/session-storage) - Directory structure and data schemas * [Environment Variables](/reference/environment-variables#storage) - Configure storage location with `AGENTUSE_DATA_DIR` # Skills Source: https://docs.agentuse.io/guides/skills # Skills Skills are based on the [Agent Skills](https://agentskills.io) open standard, originally developed by Anthropic. AgentUse implements this standard to enable portable, reusable instruction modules across different AI agent platforms. ## What Are Skills? Skills are reusable instruction modules that agents can load on-demand. Think of them as specialized knowledge packages - each skill contains detailed guidance for a specific type of task. Unlike sub-agents that execute independently, skills provide instructions that the agent follows directly. This makes skills ideal for: * **Specialized workflows**: Code review checklists, deployment procedures, data analysis patterns * **Domain expertise**: Writing guidelines, compliance requirements, best practices * **Reusable templates**: Project scaffolding, documentation formats, testing strategies * **Cross-agent knowledge**: Share instructions across multiple agents without duplication ## Quick Start 1. Create a skill directory: ```bash theme={"system"} mkdir -p .agentuse/skills/code-review ``` 2. Add a `SKILL.md` file with YAML frontmatter and markdown content: ```yaml theme={"system"} --- name: code-review description: Review code for quality, security, and maintainability. allowed-tools: Read Bash(git:*) --- ``` Then add your skill instructions in markdown below the frontmatter. 3. The skill is automatically available to your agents! ## Skill Locations Skills are discovered from these directories (in priority order): | Location | Scope | Purpose | | - | - | - | | `.agentuse/skills/` | Project | Project-specific skills | | `$AGENTUSE_CONFIG_DIR/skills/` | User | Personal skills across projects; defaults to `~/.agentuse/skills/` | | `.claude/skills/` | Project | Claude ecosystem compatibility | | `~/.claude/skills/` | User | Claude ecosystem compatibility | | `~/.agents/skills/` | User | Shared agent skills compatibility | If duplicate skill names exist, the first discovered skill takes precedence. Symlinked skill directories and `SKILL.md` files are supported. AgentUse skips dangling links and resolves directory real paths to prevent circular traversal. ### For AI Coding Assistants Install the assistant-facing AgentUse skill so Claude Code, Codex, Cursor, and other assistants can drive AgentUse workflows: ```bash theme={"system"} npx skills add agentuse/agentuse ``` The stub redirects to `agentuse skills get core`, keeping instructions aligned with the installed CLI version. `core` is the entry point: it points on to `runner` (running, listing, sessions, serve, schedules), `creator` (authoring and reviewing `.agentuse` files), and `tester` (validating agents with mock runs), each fetched the same way. Dashboard creator sessions can read these version-matched builtins directly, including `core`, `creator`, and `tester`, without shell access. The creator guide is already included in the authoring context. Builtin guidance is separate from the installed skill catalog, and reading it grants no execution tools. ## Skill Structure Each skill lives in its own directory with a `SKILL.md` file: ``` .agentuse/skills/ └── my-skill/ # Directory name should match the skill name └── SKILL.md # Skill definition file ``` ### SKILL.md Format Skills use markdown with YAML frontmatter: ```yaml theme={"system"} --- name: my-skill description: What this skill does allowed-tools: Read Write license: MIT compatibility: ">=0.3.0" metadata: author: your-name version: "1.0.0" --- ``` Below the frontmatter, add your skill instructions in markdown. ### Frontmatter Fields | Field | Required | Description | | - | - | - | | `name` | Yes | Skill identifier (1-64 chars, no spaces or slashes; lowercase with hyphens recommended). See [Name Requirements](#name-requirements) | | `description` | Yes | What the skill does and when to use it (max 1024 chars) | | `allowed-tools` | No | Required tools: a space- or comma-separated string, or a YAML list | | `license` | No | Skill license (e.g., MIT, Apache-2.0) | | `compatibility` | No | Version requirements or environment notes | | `metadata` | No | Custom annotations. Values may be strings or nested objects; the runtime never interprets them | `metadata` is free-form on purpose. AgentUse preserves and surfaces these keys (`agentuse skills installed list --json`) but never reads them, so a skill shared with another tool can carry that tool's nested config here without AgentUse rejecting the skill. ### Name Requirements A skill name is accepted when it: * Is 1-64 characters long * Contains no spaces, forward slashes (`/`), or backslashes (`\`) When `name` is omitted, the directory name is used, and it must meet the same rules. Agent config (`skills:`) accepts every name discovery accepts, so any discovered skill can be listed or trusted. For new skills, we recommend: * Lowercase letters, numbers, and single hyphens (`code-review`, `seo-analyzer`), with an optional `namespace:` prefix (`team:code-review`) * A `name` that matches the parent directory name **Recommended:** `code-review`, `seo-analyzer`, `db-migration` **Accepted for compatibility:** `Code-Review`, `my_skill`, `too--many`, `my.skill` **Rejected:** `my skill`, `team/review`, a name over 64 characters ## Allowed Tools The `allowed-tools` field documents which tools your skill needs, for **documentation purposes** and to drive [skill trust](#trusting-a-skill). Write it as a space-separated string, a comma-separated string, or a YAML list. All three are accepted: ```yaml theme={"system"} allowed-tools: Read Write Bash(git:*) mcp__github ``` ```yaml theme={"system"} allowed-tools: Bash(agent-browser:*), Bash(npx agent-browser:*) ``` ```yaml theme={"system"} allowed-tools: - Bash(npm run *) - Read ``` A `Bash(...)` pattern may contain spaces, so multi-word command prefixes work: `Bash(git commit *)` and `Bash(npm run *)` are split as single patterns, not on their internal spaces. The two trailing-wildcard spellings are equivalent, matching Claude Code's permission syntax: `Bash(ls:*)` and `Bash(ls *)` mean the same thing. A wildcard anywhere other than the end (`Bash(git * main)`) is kept as documentation but grants nothing, because narrowing it to a prefix would grant more than the pattern describes. Skills use whatever tools the **agent** has configured. The `allowed-tools` field documents dependencies and provides validation warnings for builtin tools. ### Validation Only builtin tools are validated against the agent's configuration: * `Read`, `Write`, `Edit` - checked against `tools.filesystem` * `Bash`, `Bash(command:*)` - checked against `tools.bash.commands` ### Bash Tool Configuration | Field | Type | Description | | - | - | - | | `commands` | `string[]` | Allowlist of command patterns (supports `*` wildcard) | | `gated` | `string[]` | Command patterns that require an approved per-action lease | | `allowedPaths` | `string[]` | Additional directories accessible beyond project root. Supports `~` for home directory. | | `timeout` | `string` | Command timeout as a suffixed duration such as `"30s"`, `"2m"`, or `"500ms"`; bare numbers are rejected | Other tool names (like MCP tools) are accepted but not validated - they serve as documentation only. If validation fails: * A warning is logged to the console * The LLM sees a warning message * The skill still loads (graceful degradation) ## Agent Tool Configuration Skills run with the **agent's tools**. For a skill to use the tools it documents, the agent must have them configured. Agents use `skills: auto` by default, even when the field is omitted. This makes installed skills discoverable and lets the model load relevant skills on demand. By default a skill is discovered but granted **nothing**: to run a command a skill documents, it must be in `tools.bash.commands`, or you must trust the skill. **Trusting a skill grants it the bash commands it declares** in its SKILL.md `allowed-tools`, so you do not have to re-list them. Trust per skill: ```yaml theme={"system"} skills: linkedin: trusted ``` or trust every discovered skill (the blunt shortcut, use deliberately): ```yaml theme={"system"} skills: trusted ``` Trusting a skill is a real trust decision, the same class as installing an editor extension: you are granting a skill you may not have written the commands it asks for. Trust only **grants** (adds the commands so they can run); it never invents gates. Gating stays your explicit call: * To require approval for a subset of what a skill grants, list that pattern in [`tools.bash.gated`](/guides/approval-gates#gated-commands-mechanical-enforcement). For example, a skill declares `Bash(birdc:*)`, so trusting it grants `birdc *`. If you want `birdc reply *` behind approval, add it to `tools.bash.gated`. Gated-wins precedence gates `birdc reply` while `birdc read` still auto-runs. ```yaml theme={"system"} skills: x-personal: trusted # grants birdc * tools: bash: gated: - "birdc reply *" # ...but reply needs your approval ``` `agentuse doctor` flags granted commands that look irreversible, so you know what to consider gating. ### Preloading skills List a skill to **preload** it: its instructions are injected before the task starts, so the agent does not have to infer the trigger from the user instruction. Use this when a skill is core to the agent's job. ```yaml theme={"system"} skills: [linkedin, x-personal] ``` Listing a skill preloads it; **it never hides the others.** Discovery stays on, so every unlisted skill is still loadable on demand. Listing is "these are the skills I use," not "forbid all others." This reverses pre-`0.16.0` behavior, where `skills: [x]` was an allowlist that silently hid every other skill. Restricting is now an explicit, deliberate act (see below). To pin the agent to a **closed set** (only the listed skills are visible, everything else is hidden), opt in explicitly with `auto: false`: ```yaml theme={"system"} skills: linkedin: # bare = include, no special grant auto: false # ...and hide every other discovered skill ``` Because hiding skills is the rarer, higher-consequence choice, it is loud (`auto: false`) rather than a silent side effect of listing. Per-skill map values may be empty or `trusted` (including the object form `{ trusted: true }`). The pre-0.16 `allow` key has been removed. Grant individual commands through `tools.bash.commands` instead. ### Skill config forms | Config | Discovery | Preloaded | Trusted | | - | - | - | - | | omitted / `skills: auto` | all | none | none | | `skills: [linkedin]` | all | linkedin | none | | `skills: { linkedin: trusted }` | all | linkedin | linkedin | | `skills: { linkedin:, auto: false }` | **only linkedin** | linkedin | none | | `skills: trusted` | all | none | all | To inspect a skill's grants: ```bash theme={"system"} agentuse doctor path/to/agent.agentuse agentuse doctor path/to/agent.agentuse --last-run ``` Doctor also shows command-looking snippets mentioned by the skill. This is advisory: it extracts command names from shell code blocks, inline command snippets, `allowed-tools`, pipes, and command substitutions. AgentUse does not treat the output as a permission manifest. Add `--last-run` when the agent has already failed or behaved unexpectedly. Doctor will inspect the latest recorded session for that agent and report actual blocked bash commands from runtime, which is more accurate than static skill-doc extraction. ### Example **Skill** (`code-review/SKILL.md`): ```yaml theme={"system"} --- name: code-review description: Review code for quality and security. allowed-tools: Read Bash(git:*) mcp__github --- ``` **Agent** (`reviewer.agentuse`): ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 tools: filesystem: - path: ${root} # Grants access to all files under project root permissions: [read] bash: commands: - "git *" allowedPaths: # Optional: directories beyond projectRoot - ~/workspace/other-repo - /tmp mcpServers: github: command: npx args: ["-y", "@anthropic/mcp-server-github"] env: GITHUB_TOKEN: ${env:GITHUB_TOKEN} --- You are a code reviewer. Use the code-review skill to analyze changes. ``` The skill documents needing `Read`, `Bash(git:*)`, and `mcp__github`. The agent provides all three through its `tools` and `mcpServers` configuration. If a skill's instructions reference tools that the agent hasn't configured, those operations will fail at runtime. ## How Agents Use Skills Skills are exposed to agents via a special `skill` tool. The agent sees available skills listed in XML format and can load them on demand. When the agent loads a skill, it receives: * The skill name and base directory * Any tool warnings (if required tools are missing) * The full markdown content with instructions ### Skill File Reader After loading a skill, agents can read additional files from the skill directory using the `skill_read` tool. This is useful for accessing: * Helper scripts bundled with the skill * Data files or templates * Configuration examples ``` skill_read(skill: "code-review", path: "templates/pr-template.md") ``` The skill must be loaded first before reading files from its directory. ### Skill Directory Variables When a skill is loaded, AgentUse substitutes these placeholders in the skill's content with the skill's absolute directory path. Use them so bundled scripts and assets resolve regardless of where the skill is installed: | Placeholder | Purpose | | - | - | | `${skillDir}` | Legacy AgentUse placeholder | | `${SKILL_DIR}` | Cross-agent convention | | `${CLAUDE_SKILL_DIR}` | Claude ecosystem compatibility | ```markdown theme={"system"} Run `bash ${SKILL_DIR}/scripts/setup.sh` before generating output. ``` Only the curly-brace form is replaced. Literal `$SKILL_DIR` (no braces) is left untouched so runtime shell expansion still works inside scripts. ## Example Skills ### Git Commit Guidelines **Frontmatter:** ```yaml theme={"system"} --- name: commit-guidelines description: Create well-structured git commits following conventional commit format. allowed-tools: Bash(git:*) --- ``` **Content:** Include guidance on conventional commit format, commit types (feat, fix, docs, refactor, test, chore), and best practices like keeping subject lines under 72 characters. ### API Documentation Writer **Frontmatter:** ```yaml theme={"system"} --- name: api-docs description: Generate comprehensive API documentation from code. allowed-tools: Read --- ``` **Content:** Include templates for endpoint documentation (HTTP method, path, parameters, response format, error codes) and function documentation (purpose, parameters, return values, examples). ### Database Migration Checker **Frontmatter:** ```yaml theme={"system"} --- name: migration-check description: Validate database migrations for safety before production. allowed-tools: Read Bash(psql:*) --- ``` **Content:** Include checklists for backwards compatibility, data safety, performance considerations, and rollback planning. ## Skills vs Sub-agents | Aspect | Skills | Sub-agents | | - | - | - | | **Execution** | Instructions followed by parent agent | Runs as separate agent | | **Context** | Shared with parent agent | Isolated context | | **Tools** | Uses parent agent's tools (no own config) | Has own tool configuration | | **Tool declaration** | `allowed-tools` for documentation/validation | Full `tools` config in agent file | | **Output** | Integrated into parent's response | Returns result to parent | | **Use case** | Guidelines, procedures, knowledge | Independent tasks | Use skills for knowledge and procedures. Use sub-agents for independent task execution. # Store Source: https://docs.agentuse.io/guides/store Persistent data storage for tracking work items across agent runs The `store` configuration and on-disk item format are experimental and may change without migration. Discuss feedback in [GitHub Discussions](https://github.com/agentuse/agentuse/discussions). ## What is the Store? The store is a local file-based storage system that allows agents to track work items and remember information across multiple runs. It's particularly useful for: * **Multi-run workflows** - Track progress when agents run on a schedule * **Multi-agent coordination** - Share state between agents working together * **Task management** - Track tasks through status workflows * **Agent memory** - Remember facts, preferences, and context across runs Stores live at the AgentUse project root: ```text theme={"system"} /.agentuse/store//items.json ``` When you run `agentuse serve -C path/to/agents`, `-C` is the served scope for agent files. AgentUse still walks upward to find the project root, so agent folders inside the same repository can share the same store. Under `agentuse test` and any other mock run, every store is re-rooted at `/.agentuse/store-mock/-/`, seeded on first use by copying the real store so the agent still reads realistic data. Nothing a mock run writes reaches production state, including the reserved `metrics` store behind the dashboards. The scratch copy is kept so you can inspect what the run would have written, and swept after 7 days. When you enable the store, your agent automatically gets tools for creating, reading, updating, deleting, and listing items. Tell the agent what to store and when in your agent file's instructions. ## Configuration ### Isolated Store Use `store: true` for a store that's private to one agent: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 store: true --- ``` The store is named after the agent (e.g., `myagent` from `myagent.agentuse`). ### Shared Store Use a string name to share a store across multiple agents: ```yaml theme={"system"} # manager.agentuse --- type: manager store: "my-project" subagents: - path: ./writer.agentuse --- # writer.agentuse --- store: "my-project" # Same store as manager --- ``` All agents using the same store name can read and write to the same data, enabling coordination without explicit communication. ## Capabilities When `store` is configured, your agent can: | Operation | Description | | - | - | | **Create** | Add new items with type, title, status, data, and tags | | **Get** | Retrieve a single item by ID (full data, or only selected `fields`) | | **Update** | Modify existing items (merges changes, doesn't replace) | | **Conditional update** | Compare current status, data fields, or `updatedAt` and update only on a match | | **Claim** | Atomically select and transition one matching item | | **Delete** | Remove items by ID | | **List** | Query and search items with filters, full-text search, and projection | **Keep each item compact.** Store rows are workflow records, not document or analytics containers. Aim to keep `data` at or below 8 KiB. Normalize repeated records into separate typed items, and keep large reports or datasets as file artifacts. Larger items are accepted, but store tools warn because reading and updating them consumes substantial model context. ## Listing and searching `store_list` is built to be **token-efficient**: by default it returns lightweight summary rows (id, type, title, status, tags, parent, timestamps) **without the `data` payload**. The agent scans the summaries, then calls `store_get` for the full data of the one item it needs, instead of pulling every payload into context. It accepts these parameters: | Parameter | Type | Description | | - | - | - | | `type` | string | Filter by item type | | `status` | string | Filter by status | | `parentId` | string | Filter by parent item ID | | `tag` | string | Filter by a single tag | | `ids` | string\[] | Fetch these specific item IDs in one call (batch get) | | `where` | object | Exact-match filters on keys **inside** `data`, e.g. `{ "stage": "review" }`. Numbers and booleans also match their string form (`"5"` matches `5`) | | `q` | string | Case-insensitive substring search across title, type, tags, and `data`. Matching summary rows include a short `match` snippet showing where it hit | | `includeData` | boolean | Return the full `data` payload of each item (default `false`) | | `fields` | string\[] | Return only these keys from each item's `data` (ignored when `includeData` is true) | | `since` | string | Only items updated within this window: a relative span (`"7d"`, `"12h"`, `"30m"`), a bare date (`"2026-03-01"`, read as UTC midnight), or a full ISO timestamp | | `countOnly` | boolean | Return counts instead of rows (see below) | | `limit` | number | Maximum number of items to return | | `offset` | number | Number of items to skip (pagination) | The response is `{ count, total, items }`: * `count` is the number of rows returned and `total` is how many items match the filters before `limit`/`offset`, so the agent knows whether more remain. * Alongside the rows, the response carries a single top-level `dataKeysByType` map listing the `data` keys seen for each item type, so the agent knows what it could request via `fields` or `store_get` without paying for the key list once per row. On a 243-item store, a 40-row listing went from 6,639 tokens to 3,785 this way. When you pass `fields`, the key list is dropped entirely and each row instead reports `missingFields` for any key it doesn't have. An unparseable `since`, or an impossible calendar date like `2026-02-31`, comes back as a tool error naming the accepted forms rather than being silently ignored. ### Counting To size a store before reading it, use `countOnly: true`. It returns `total` plus `byType`, `byStatus`, `oldest`, and `newest`, with no rows at all, for around 140 tokens. It respects every filter and ignores `limit`/`offset`, so it always describes the whole matching set. This matters because `store_list` has **no default limit**: an unfiltered call returns every item and fails loudly against the tool-output cap rather than silently truncating. Ask for the shape first, then ask for rows. **Keep retrieval cheap.** Size it (`countOnly`), narrow it (`since`, `type`, `status`, `q`), scan the summary rows, then `store_get` the single item you want. Only set `includeData: true` (or list `fields`) when you genuinely need payloads for several items at once. For a known set of IDs, pass `ids` to fetch them in one `store_list` call. The same projection applies to `store_get`: pass `fields: ["url", "score"]` to return only those keys from a large item instead of the whole payload. ## Atomic coordination Use `store_claim` for a shared work queue. Selection and transition happen under one store lock, so two concurrent runs cannot claim the same matching row: ```typescript theme={"system"} const claim = await tools.store_claim({ type: "job", status: "ready", order: "oldest", update: { status: "in_progress", data: { claimedBy: "worker" } } }); ``` An empty queue returns `{ success: true, claimed: false, item: null }`. Use `store_update_if` for compare-and-set updates. Conditions can include the current `status`, exact values inside `data` through `where`, and the prior `updatedAt` value. A stale condition returns `matched: false` without modifying the item. Do not implement claiming as `store_list` followed by `store_update`. Another run can select the same item between those calls. Code Mode makes control flow deterministic, but only atomic store primitives make concurrent transitions atomic. ## Writing Instructions Guide your agent's store usage through clear SOP instructions. Here are common patterns: ### State Machine ```markdown theme={"system"} ## Workflow 1. Create items with status "pending" 2. When starting work, update to "in_progress" 3. When complete, update to "done" 4. For failures, update to "failed" with error in data ## Progress Check - List items with status "pending" to find work - List items with status "in_progress" to check active work ``` ### Parent-Child Relationships ```markdown theme={"system"} ## Structure - Topic (parent) - Article (child linked to topic) - Review (child linked to article) ## Finding Related Items - List articles filtered by parent topic ID - List reviews filtered by parent article ID ``` ### Tagging for Priorities ```markdown theme={"system"} ## Priority Handling - Tag urgent items with "urgent" - When checking for work, prioritize items tagged "urgent" - Use tags like "bug", "feature", "review" for categorization ``` ### Agent Memory ```markdown theme={"system"} ## Memory Management - Store important facts with type "memory" - Use tags to categorize: "user-preference", "learned-fact", "context" - Before starting work, list recent memories for relevant context - When learning something important, store it for future runs ## What to Remember - User preferences discovered during tasks - Decisions made and their reasoning - Facts that will be useful in future runs - Corrections or feedback received ``` ## Storage Location Stores are saved to: ``` .agentuse/ store/ {storeName}/ items.json # The data lock # Process lock file ``` Don't edit `items.json` directly while an agent is running. The lock file prevents corruption from concurrent access. ## Example: Content Pipeline ```yaml theme={"system"} # manager.agentuse --- type: manager store: "content" subagents: - path: ./researcher.agentuse - path: ./writer.agentuse --- ## SOP ### Research Phase 1. Delegate to researcher to find topics 2. Store each topic with type "topic" and status "pending" ### Writing Phase 1. List pending topics from the store 2. For each topic, delegate to writer with the topic ID 3. Writer creates an article linked to the topic (as parent) 4. Update topic status to "written" ### Status Workflow - Topics: pending → in_progress → written - Articles: draft → review → done ``` ## Debugging ### View Store Contents If you are running `agentuse serve`, open the store browser: ```bash theme={"system"} http://127.0.0.1:12233/stores ``` Each store has its own table: ```bash theme={"system"} http://127.0.0.1:12233/stores/my-project ``` Session and approval logs link store tool activity to the matching store table. When AgentUse knows the item ID, the link highlights the changed row: ```bash theme={"system"} http://127.0.0.1:12233/stores/my-project?highlight=01KQTG63ZQHFH9PP2B17QWMQZP ``` ```bash theme={"system"} # Pretty print store cat .agentuse/store/my-project/items.json | jq # Count items by status cat .agentuse/store/my-project/items.json | jq '.items | group_by(.status) | map({status: .[0].status, count: length})' ``` ### Check Lock Status ```bash theme={"system"} # See who holds the lock cat .agentuse/store/my-project/lock # Remove stale lock (only if agent crashed) rm .agentuse/store/my-project/lock ``` ### Reset Store ```bash theme={"system"} # Clear all items (be careful!) rm -rf .agentuse/store/my-project ``` ## Best Practices Name your types clearly: "topic", "article", "review" instead of "item1", "item2". Document valid status values and transitions in your SOP. Put operation results in the `data` field for later reference. Periodically delete completed items to keep the store manageable. ## Next Steps Build orchestrating agents with store integration Run agents on schedules with persistent state Coordinate teams sharing a store # Sub-Agents Source: https://docs.agentuse.io/guides/subagents Compose agents that can delegate to other agents ## What are Sub-Agents? Sub-agents allow you to create modular, reusable agents that can be composed together. A parent agent can delegate specific tasks to specialized sub-agents through tool calls. Sub-agents are automatically converted to tools that parent agents can call. Each sub-agent uses the parent entry's `maxSteps`, then the leaf agent's own `maxSteps`, then the 100-step default. ## Basic Usage ### Define a Sub-Agent Create `researcher.agentuse`: ```markdown theme={"system"} --- model: anthropic:claude-haiku-4-5 --- You are a research specialist. Find accurate, relevant information. ## Task Research the requested topic and provide comprehensive findings. ``` The agent name is automatically derived from the filename (e.g., `researcher.agentuse` becomes `researcher`). ### Use the Sub-Agent Create `main.agentuse`: ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./researcher.agentuse --- You coordinate research tasks using specialized agents. ## Task When asked for information, use the researcher tool to gather data. ``` Sub-agents are called as tools using their filename (without `.agentuse`). The `researcher.agentuse` becomes available as the `researcher` tool. ## Multiple Sub-Agents ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./agents/researcher.agentuse - path: ./agents/writer.agentuse - path: ./agents/editor.agentuse --- You manage content creation using specialized agents. ## Workflow 1. Use researcher tool to gather information 2. Use writer tool to create initial draft 3. Use editor tool to polish and finalize ``` ## Sub-Agent Configuration You can customize sub-agent behavior: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./researcher.agentuse name: custom_researcher # Override default name maxSteps: 25 # Override the default step budget - path: ./writer.agentuse maxSteps: 100 # Allow more steps for complex writing --- ``` ## Path Resolution All sub-agent paths are resolved relative to the **parent agent file's directory**, ensuring portability across different execution contexts. See [Agent Syntax - Subagents](/reference/agent-syntax#subagents) for complete path resolution examples and directory structure recommendations. ## Remote Sub-Agents Remote sub-agents are **not currently supported**. Sub-agents must be local files accessible via the filesystem. ## Passing Context Sub-agents accept optional parameters when called as tools: ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./data-processor.agentuse --- You analyze data using specialized processors. ## Task When given data: 1. Call data_processor tool with task parameter and context 2. Interpret the results 3. Provide insights Example: data_processor(task="Analyze sales data", context={"period": "Q4 2023"}) ``` ### Sub-Agent Tool Schema Each sub-agent tool accepts: * `task` (optional string): Additional instructions for the sub-agent * `context` (optional object): Structured data to pass to the sub-agent The sub-agent receives its original instructions plus any additional task and context. ## Advanced Patterns ### Conditional Delegation ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./technical-expert.agentuse - path: ./creative-writer.agentuse - path: ./data-analyst.agentuse --- You route requests to appropriate specialists. ## Routing Logic - Technical questions → call technical_expert tool - Creative tasks → call creative_writer tool - Data requests → call data_analyst tool ``` ### Recursive Delegation Sub-agents can declare and invoke their own `subagents`. Each relative path is resolved from the directory of the file that declares it, so a team can be organized into reusable folders without depending on the root agent's location. Delegation is bounded. AgentUse rejects circular dependencies and allows two sub-agent levels by default. Set `MAX_SUBAGENT_DEPTH` to a positive integer when a workflow intentionally needs a different limit; declarations beyond the active limit are skipped with a warning. ```yaml theme={"system"} # orchestrator.agentuse --- model: anthropic:claude-sonnet-5 subagents: - path: ./team-lead.agentuse --- # team-lead.agentuse --- model: anthropic:claude-sonnet-5 subagents: - path: ./developer.agentuse - path: ./tester.agentuse --- ``` Each sub-agent receives only its own configured tools and declared sub-agent tools. MCP connections remain isolated to the agent that configured them. ### Parallel Processing ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./analyzer-1.agentuse - path: ./analyzer-2.agentuse - path: ./analyzer-3.agentuse --- You process data in parallel using multiple analyzers. ## Task Split the data and send parts to different analyzer tools. Combine their results for comprehensive analysis. You can call multiple tools in sequence or use them to analyze different aspects of the same data. ``` Sub-agents run sequentially, not in true parallel. The parent agent calls each sub-agent tool one at a time. ## Sub-Agent Communication ### Tool and Resource Inheritance Sub-agents create their own isolated tool environments: ```yaml theme={"system"} # parent.agentuse --- model: anthropic:claude-sonnet-5 mcpServers: database: command: "node" args: ["./database-server.js"] # Relative to parent.agentuse location subagents: - path: ./child.agentuse --- # child.agentuse --- model: anthropic:claude-haiku-4-5 mcpServers: # Child defines its own MCP servers filesystem: command: "npx" args: ["@modelcontextprotocol/server-filesystem"] custom: command: "../tools/my-server" # Relative to child.agentuse location --- ``` MCP server commands with relative paths are resolved from the agent file's directory, ensuring consistent behavior across different execution contexts. Each sub-agent manages its own MCP connections and tools. They don't automatically inherit parent tools. ### System Context All sub-agents receive consistent system context: * Date and time information * Autonomous agent behavior prompts * Model-specific system messages (e.g., "Claude Code" for Anthropic models) ## Best Practices Each sub-agent should have one clear purpose. This makes them reusable and easier to maintain. Define clear expectations for what each sub-agent receives and returns. Parent agents should handle sub-agent failures gracefully. Use lighter models (like Haiku) for simple sub-agents to reduce costs and latency. Test sub-agents independently before composing them. ## Example: Customer Support System ```yaml theme={"system"} # support-system.agentuse --- model: anthropic:claude-sonnet-5 subagents: - path: ./agents/ticket-classifier.agentuse - path: ./agents/knowledge-base.agentuse - path: ./agents/escalation-handler.agentuse --- You manage customer support requests. ## Workflow 1. Call ticket_classifier tool to categorize the issue 2. Call knowledge_base tool to find solutions 3. If unresolved, call escalation_handler tool Each tool returns structured output you can use to make decisions. ``` ```yaml theme={"system"} # ticket-classifier.agentuse --- model: anthropic:claude-haiku-4-5 --- Classify support tickets into categories: - Technical issue - Billing question - Feature request - General inquiry ``` ## Performance Optimization ### Model Selection ```yaml theme={"system"} # Optimize model usage --- model: anthropic:claude-sonnet-5 # Smart coordinator subagents: - path: ./simple-task.agentuse # Can use claude-3-5-haiku-latest - path: ./complex-task.agentuse # Can use anthropic:claude-opus-5 --- ``` ### Model Override Inheritance Ordinarily, every agent uses the `model:` declared in its own file. A parent's configured model does not replace its children's models. When you explicitly use `--model`, that run-wide override applies to the parent and every nested sub-agent: ```bash theme={"system"} agentuse run orchestrator.agentuse --model openai:gpt-5.4-mini ``` Configured aliases keep their complete fallback order and cooldown at every depth. The resolved override is also stored with the session, so a suspended or restarted run resumes with the same policy even if the alias configuration has changed since the run began. See [CLI Commands - Model Override](/reference/cli-commands#model-override) for complete details on model override behavior and sub-agent inheritance. ### Step Limits Control sub-agent execution limits: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 subagents: - path: ./quick-task.agentuse maxSteps: 10 # Limit for simple tasks - path: ./complex-task.agentuse maxSteps: 200 # More steps for complex work --- ``` Default step limit for sub-agents is 50 (compared to 1000 for main agents). ## Debugging Sub-Agents ### Enable Verbose Logging ```bash theme={"system"} agentuse run main.agentuse --verbose ``` ### Trace Execution ```bash theme={"system"} DEBUG=agent:* agentuse run main.agentuse ``` ### Test Sub-Agents Individually ```bash theme={"system"} # Test sub-agent directly agentuse run ./agents/researcher.agentuse "test query" ``` ## Security Considerations Sub-agents run with the same system permissions as the parent process. Each sub-agent: * Creates its own MCP connections with full permissions * Can access any tools defined in its configuration * Runs with the same file system and network access * Has access to environment variables ### Best Practices for Security * Audit sub-agent configurations carefully * Use minimal necessary permissions in MCP server configs * Avoid loading sub-agents from untrusted sources * Review sub-agent instructions for potentially harmful commands * Use `allowedTools` in MCP configs to load only the tools an agent needs, or `disallowedTools` to block specific ones ## Next Steps Learn about remote agent execution See sub-agent examples # Testing Agents Source: https://docs.agentuse.io/guides/testing-agents Test workflow steps or compare a new result using evidence from a past job ## Choose what to test | Command | Question | What runs | | - | - | - | | `agentuse test workflow ` | Does the agent carry out its steps correctly? | The agent with simulated tool responses and approval decisions. | | `agentuse test result --session ` | What result do updated instructions produce from the same evidence? | Fresh generation from saved source evidence, without workflow tools. | Run `agentuse test --help` to see both choices. Put options after `workflow` or `result`. Both commands use real model calls and can incur provider costs. ## Compare a result from a past job ```bash theme={"system"} agentuse test result reply.agentuse --session agentuse test result reply.agentuse --session --judge quality.agentuse ``` On first use, a selector model extracts external evidence from the original session before its first approval gate. Exact excerpts and a selection audit are saved under `/.agentuse/test-evidence/`. Later tests of that source reuse the selection, even after you edit the instructions or change the writer model. `--selector-model ` chooses the extractor on first use; otherwise it uses the agent model. It does not replace already saved evidence. The writer receives current agent instructions, explicit preloaded skills, applicable learnings, the original additional prompt, and the selected evidence. Explicit read-only file grants are loaded as current references and their hashes appear in the report. Directory and wildcard grants are not expanded into fresh references. A changed reference can change the result even with fixed evidence. Relative dates use the original session date. The original output and human feedback stay out of the writer and judge context and appear only in the report. This tests the deliverable, not research, delegation, tool behavior, approval, or publishing. No workflow tool or Code Mode executes. If required evidence or capabilities are missing, the writer should report `incomplete`. Model-assisted selection can make mistakes; inspect the saved audit before relying on a test. Sources must be real sessions that have finished or reached approval and contain recorded tool evidence. Unsupported/media-only evidence, invalid selections, and inputs exceeding the context budget fail explicitly without truncation. `--judge ` supplies quality criteria from a separate agent. Its current explicit skills, learnings and read-only file references are available, but it has no tools. It evaluates the new result against the task and evidence; a pass is not a claim of improvement over the original. Use `--model` to change the writer model; the judge uses its own configured model. | Status | Meaning | Exit code | | - | - | - | | `generated` | A new result is available; no quality verdict | 0 | | `passed` | The judge accepted the new result against its criteria | 0 | | `failed` | The judge rejected it | 1 | | `incomplete` | The writer could not produce the deliverable | 1 | | `error` | Extraction, generation, validation, or judging failed | 1 | `--json` emits the structured report. The printed report path contains the comparison, evidence provenance, current reference hashes, and any judgment. Each invocation creates a test session excluded from operational views; it cannot be resumed as a live run. `--timeout` bounds selection, generation and judging together. `-C` and `--env-file` work as on `run`. ## Test workflow steps An agent that sends email, pushes commits, posts to Slack, or deletes rows is hard to debug by running it. The first real run is also the first irreversible one, and reading the agent file only tells you what you wrote, not what the model does with it. `agentuse test workflow` closes that gap. It runs the agent all the way through, on its own model, with its own instructions and its own tools, but fabricates the side effects instead of performing them. You get a full session log of a complete run with simulated external tool responses and isolated store writes by default. ## Run a workflow test ```bash theme={"system"} agentuse test workflow my-agent.agentuse agentuse test workflow my-agent.agentuse "focus on the March invoices" ``` It takes the same run options you already know (`--quiet`, `--debug`, `--no-tty`, `--compact`, `--timeout`, `-C`, `--env-file`, `-m/--model`, `--json`) plus the workflow options below. ### A Mock Model Is Required Mock mode fires an LLM call for **every** tool result, so it needs a model it can reach: ```bash theme={"system"} agentuse test workflow my-agent.agentuse --mock-model anthropic:claude-haiku-4-5 ``` Set it once instead of per run via `AGENTUSE_MOCK_MODEL` in your shell, `~/.agentuse/.env`, or the [`env` block of `~/.agentuse/config.json`](/reference/configuration-files#global-env-defaults). The flag wins over all of them. **Use the lowest-end model you can reach.** Mocking is not a reasoning task: the model only has to fabricate a plausible result for a tool given its name and arguments. Your agent's *actual* reasoning still runs on its own model, untouched. Deliberately not defaulted to the agent's own model, because running one mock call per tool result on a premium, rate-limited token produced opaque `429`s. ## Choose which tools to simulate New `test workflow` invocations default to **all**: external tool results are simulated. `--scope gated` explicitly simulates only matching gated bash commands; other tools execute for real. Approval decisions are simulated in both modes, and stores are isolated. ```bash theme={"system"} agentuse test workflow my-agent.agentuse --scope all agentuse test workflow my-agent.agentuse --scope gated ``` Gated scope only covers gated **bash**. An effectful MCP tool or a channel post still runs for real, so pair it with a scratch copy of the project when the agent writes through those. And a fabricated command changes nothing on disk: a later real command that checks its effect (`git log` after a fabricated `git push`) sees the unchanged state. An agent with no `tools.bash.gated` patterns run under gated scope gets a warning: nothing is mocked, everything runs real, with gates still auto-resolved. ## Approval Gates, Unattended A test run must finish without a human, so the gate resolves deterministically instead of suspending. No model plays the reviewer. ```bash theme={"system"} agentuse test workflow my-agent.agentuse --approval approve # default agentuse test workflow my-agent.agentuse --approval reject agentuse test workflow my-agent.agentuse --approval comment:"tighten the subject line" ``` | Decision | What it exercises | | - | - | | `approve` | The happy path. Grants the [gated-command lease](/guides/approval-gates) from the gate's `changes[]` exactly like a real reviewer, so `tools.bash.gated` flows complete end to end. On a pick gate it takes the recommended option, else the first | | `reject` | The cleanup branch. The gate seals and the run ends there | | `comment:` | The revise-and-re-gate branch, with `` as reviewer feedback | The comment applies to the **first** gate only; the re-gate that follows is approved, so the run exercises the revision path and still finishes. Repeating it on every gate would loop an obedient agent until it gave up. ## What Is Isolated * **Stores.** Every store, including the reserved `metrics` store behind the dashboards, is re-rooted at `/.agentuse/store-mock/-/`. Reads are seeded by copying the real store, so the agent still sees realistic data; writes land in the scratch copy, which is kept for inspection and swept after 7 days. See [the store guide](/guides/store). * **Operational views.** Mock sessions are excluded by default from the serve home dashboard, agent health, and the sessions list, and they never fire push notifications, so a test loop does not buzz anyone's phone or distort the picture of production. ## The Closed Loop Testing is meant to be iterated, not performed once: 1. Edit the agent file. 2. `agentuse test workflow my-agent.agentuse`. 3. Read the session log: what the agent actually did, in order, with what arguments. 4. Repeat. ```bash theme={"system"} agentuse test workflow my-agent.agentuse agentuse sessions show --full ``` In the dashboard, find the run by flipping the sessions list's "mock runs" filter to `only mock` (API: `?mock=only`). A mock session's detail page is always reachable by id whatever the filter says, and the CLI marks these runs with a trailing `· mock` (hide them with `agentuse sessions list --no-mock`). For a `tools.bash.gated` flow, the log shows the whole gate sequence: the `await_human` call with its `changes[]`, the deterministic decision, and the fabricated command result. In the effect WAL, a fabricated gated command has a `lease-approved` entry but **no** `bash-spawn` entry, which is the audit signal that it never executed. ## What a Passing Test Does and Doesn't Prove * **Mock outputs are non-deterministic.** They are LLM-generated, so two runs can hand the agent different plausible results. That is useful for probing how the agent copes with variation, and useless as a regression assertion. * **Mocked approval decisions are deterministic.** The branch you asked for is the branch you get, every time. * **MCP servers still connect at startup** for tool discovery. Under full mock, their tool calls are simulated; gated scope leaves MCP calls live. * **Gate enforcement is still real.** Mock mode does not relax the permission model: a gated command the agent tries to run without a lease is still denied, exactly as in production. ## Lower-Level Plumbing `agentuse test workflow` is the front door. The same machinery is exposed on `run` for scripts and unusual cases: ```bash theme={"system"} agentuse run agent.agentuse --mock --mock-model anthropic:claude-haiku-4-5 ``` Note that `run --mock` keeps the approval gate **real**: `await_human` still suspends, which is useful when you specifically want to verify the agent pauses. Add `--mock-approval` for the unattended behaviour `agentuse test workflow` defaults to. See [CLI Commands](/reference/cli-commands#agentuse-test) for the full flag reference and [Environment Variables](/reference/environment-variables#mock-mode-testing) for the `AGENTUSE_MOCK_*` equivalents. If you drive AgentUse from an AI coding assistant, `agentuse skills get tester` hands it this workflow directly, version-matched to the installed CLI. ## Related Gate configuration, reviewer flows, and lease enforcement Reading what a run actually did How mock runs isolate persistent state Writing the agent you are about to test ## Compatibility and advanced debugging `agentuse test ` retains the older adaptive scope: gated when the agent has gated bash patterns, otherwise all. Existing scripts keep that behavior. The new `test workflow` command defaults to all even when gated patterns exist. For an agent file literally named `workflow` or `result`, use an explicit path such as `./workflow` with the compatibility form. `agentuse test --replay ` remains an advanced strict recorded-call debugger. A changed tool argument without a matching recording stops it. It is not the same as `test result`, which supplies evidence directly. See [Replay recorded inputs](/guides/replay). # Verify Source: https://docs.agentuse.io/guides/verify Judge the agent's output before it ships, and redo it with the critique on failure The `verify` configuration, verdict contract, and redo behavior are experimental and may change without migration. Discuss feedback in [GitHub Discussions](https://github.com/agentuse/agentuse/discussions). ## What is Verify? Verify puts a quality gate between your agent's final output and delivery. After the run finishes, a judge evaluates the output against your criteria. If it fails, the judge's critique is injected back into the same session as a revision instruction and the agent **redoes the output**, with all its tool results and completed work still in context, up to `maxRedos` times. Only then does the output ship to channels, a delegating manager, or the CLI. The redo is a continuation, not a re-run: the agent sees everything it already did (including side effects like sent messages or filed issues), so it revises the deliverable instead of repeating actions. ## Quick Start ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 verify: true # generic rubric: does the output fulfill the task? --- # Weekly Report Writer Summarize this week's metrics into a report. ``` Or with your own rubric: ```yaml theme={"system"} verify: "Every metric cited must come from a tool result; includes a risks section; no filler" ``` ## Configuration Options | Option | Type | Description | | - | - | - | | `criteria` | string | Rubric for the built-in judge (one LLM call). Mutually exclusive with `judge`. | | `judge` | string | Path to a `.agentuse` file to run as the evaluator, relative to this agent file. Mutually exclusive with `criteria`. | | `at` | `gate` \| `output` \| `both` | Where the judge runs. Defaults to `gate` when the agent has an approval gate, `output` otherwise. | | `maxRedos` | number | Maximum critique-informed redos before output ships or the gate applies its configured exhaustion behavior (default `1`, max `10`, `0` = judge only). | | `model` | string | Model for the built-in judge. Defaults to the agent's own model. Invalid with `judge`. | `verify: true` uses a generic task-fulfillment rubric. `verify: ""` is shorthand for `{ criteria: "" }`. ## Gate Placement (approval agents) For agents with an [approval gate](/guides/approval-gates), verify defaults to `at: gate`: the judge reviews each `await_human` request **before** it suspends to the human. * **Fail** → the run does not suspend. The critique returns as a rejection-with-comment tool result, the same protocol as a human rejection, so the agent revises its draft and requests approval again. The human never sees the failed draft. * **Pass** → the gate suspends to the human as normal. * **After a human Comment** → the next gate skips pre-review and goes directly back to that reviewer. Their requested revision is authoritative for that review cycle; an automated judge cannot reinterpret or override it. Machine pre-review feedback does not trigger this bypass. * **Fail-open** → after `maxRedos` pre-review rejections, or on any judge error, the request goes to the human regardless, with the unresolved critique in the session log. The judge protects your attention; it can never deadlock a run or replace your decision. A gate that reaches the human this way records a `skipped` verify marker, so the approval card and `sessions show` say "not judged" and why. [`gateReview: fresh`](#fresh-gate-review) instead opens a feedback-only human gate and keeps approval blocked. When a gate offers several drafts (a slate keyed by `options` / `changes[].optionId`), the judge returns one verdict per candidate and lists every failing candidate in one pass. A candidate that passed keeps its pass on the next attempt as long as the reviewed content is byte-identical (the visible text, the exact command, and the media URLs): the gate carries it forward, tells the judge not to re-judge it, and skips the judge call entirely when nothing changed. The bounce sent back to the agent names the passing candidates so it leaves them alone. A rejection of the whole request holds even when every candidate passed. With a [judge agent](#using-a-judge-agent), the attempts on one gate share **one judge session**: the second attempt resumes the first attempt's child session and sends only the revised request plus which candidates changed. The judge keeps its own reasoning about what it already read, and the provider serves the long prefix from cache, so extra redos cost a fraction of the first. The session is dropped whenever the gate suspends, so a human decision always gets a fresh judge, and a resume is declined when the judge history grows past a fixed size or the `judge` file changed. Otherwise, the judge receives the full approval payload (draft, exact on-approval content, target reference/excerpt, context) plus bounded prior human decisions from the session, so write criteria against what the reviewer would see. Because the check runs before anything posts, this placement is the quality gate; `at: output` is a post-run audit. Gate placement also works for delegated sub-agents: a leaf's gate is judged in the leaf, before the request cascades to the root. The payload is **all** the built-in judge sees. It runs without tools, so a criterion about a file on disk is really judged against the agent's *account* of that file. A payload that paraphrases its own artifact gets rejected even when the artifact is correct, and a payload that flatters a broken artifact passes silently. When the criteria describe something on disk, use a [judge agent](#using-a-judge-agent) that can open it. ## Using a Judge Agent When a one-line rubric isn't enough, the evaluation needs its own files, tools, or a stronger model, point `judge` at another agent file: ```yaml theme={"system"} verify: judge: ./shared/reply-judge.agentuse maxRedos: 1 ``` The path resolves relative to the agent file that declares it. `judge` and `criteria` are mutually exclusive, and `model` is invalid alongside `judge` (the judge agent declares its own). **The judge's body is the rubric.** Where the built-in judge gets your `criteria`, an agent judge is handed `Apply the evaluation standard defined in your own instructions.` in that slot, so the standard has to live in the judge agent itself. Everything else it needs, the task and the candidate output, arrives around it. The judge is otherwise a normal agent: its own frontmatter controls its model, reasoning effort, and tools. That is the point of using one. Grant it read access to the rubric files, exemplars, or the artifact under review, and it evaluates what is actually on disk instead of what the payload claims. It runs as an inspectable child session, so which files it opened and why it decided are visible in the session log, not just the one-line verdict. It records its decision by calling `submit_verdict`, a tool injected into every judge agent, exactly once: ```json theme={"system"} {"pass": false, "critique": "The reply restates the target's framing. Add one distinct layer: a concrete example from practice."} ``` The tool call **is** the verdict; a judge should not also write a JSON object in its text. (A trailing JSON object is still parsed as a fallback, which is how the built-in judge reports, but new judge agents should call the tool.) When `pass` is `false`, `critique` is required and must be actionable in one revision, it is injected verbatim into the redo turn. Everything else the judge writes stays in its own reasoning. Judges conventionally stay read-only (they evaluate, the parent revises), but this is not enforced, a judge that runs your test suite is a legitimate design. Judges cannot suspend on approval gates, so never give a judge agent `approval: true`; a suspended judge counts as a judge error. A nested `verify:` on a judge is ignored. ## What Happens on Failure 1. The verdict and critique are recorded in the session log (visible in the web UI). 2. The critique is injected as a revision instruction: attempt count, criteria, the critique verbatim, and directives (revise, don't argue with the review, completed side effects stand, tools allowed for new information). 3. The agent's revised output is judged again, up to `maxRedos`. 4. If every attempt fails, the **last output still ships**, and the session is marked `verification: failed`, a needs-attention signal for you or a delegating manager, not a crash. A judge that itself errors (model/auth/parse failure) never blocks the run: the output ships unverified with a visible `error` marker. ## Cost and Behavior Notes * Each verification is one extra LLM call; each redo is a continuation of the existing session (prompt caching keeps it near generation-only cost). Redo steps count against `maxSteps`. * On a gate with a judge agent, the judge's own session is resumed across attempts, so raising `maxRedos` on a slate agent is cheaper than the count suggests: later attempts re-read a cached prefix and re-judge only the candidates that changed. * The built-in judge defaults to the agent's own model so authentication always works; set `model` to use a cheaper judge. * Verify requires session storage (the default), it is skipped when no session substrate is available, and skipped for runs that declared themselves incomplete via `report_outcome`. * If a redo hits an approval gate, the run suspends normally; verification resolves at the end of the resumed run. ## Verify vs. Learning Verify catches a bad output **now**; [Learning](/guides/learning) makes the agent better **next run**. They compose: a verify critique that fixed the output this run is exactly the kind of rule worth promoting into learnings (automatic promotion is planned). ## Fresh gate review For editorial workflows that require a new reading of every approval request, opt in with `gateReview: fresh`: ```yaml theme={"system"} verify: judge: ./shared/reply-judge.agentuse gateReview: fresh maxRedos: 2 ``` Each judged gate gets a fresh judge session and all candidates are checked again. No previous candidate verdict is carried forward, so unchanged wording is rechecked when the source or evidence changes. A gate that directly follows a human Comment skips the judge, exactly as in the default mode: the revision returns straight to the reviewer who asked for it, with a `skipped` marker saying it was not judged. The judge filters what reaches the reviewer's first look; it does not second-guess a reviewer who is already in the loop. Fresh mode never lets an agent's own unreviewed replacement reach approval. When failed verdicts or reviewer errors consume the review budget, the current draft returns to the human in a feedback-only gate with the latest critique. Approval stays unavailable. The reviewer can comment with guidance to resume the same session, which returns the revision straight to them, or reject to stop the action. The current draft, prior human comments, and automated critique remain in the session rather than being discarded by a terminal failure. With `maxRedos: 0`, the initial request is still judged once. A failure then opens the same feedback-only gate. A reviewer error consumes one attempt. An approval still requires the human's decision after the automated pass. Without this option, existing incremental review and fail-open behavior remain unchanged. This setting only affects gate placement, not final-output review. # Webhooks Source: https://docs.agentuse.io/guides/webhooks Trigger agents via HTTP using the serve API Run agents on-demand via HTTP webhooks using `agentuse serve`. Integrate with external services, CI/CD pipelines, or any system that can make HTTP requests. ## Quick Start 1. Start the daemon: ```bash theme={"system"} agentuse serve ``` 2. Trigger an agent via HTTP: ```bash theme={"system"} curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "assistant.agentuse"}' ``` ## Serving Multiple Projects AgentUse runs one serve daemon at a time. Repeat `-C` on that daemon to serve multiple project roots: ```bash theme={"system"} agentuse serve -C ./projA -C ./projB ``` Project ids default to directory basenames. Duplicate ids fail startup. Select a project in the request body: ```bash theme={"system"} curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"project": "projA", "agent": "assistant.agentuse"}' ``` Without `project`, multi-project requests return `400 PROJECT_REQUIRED` unless a default is set: ```bash theme={"system"} agentuse serve -C ./projA -C ./projB --default projA ``` Explicit `project` fields override the default. ### Global config You can put serve defaults in `~/.agentuse/config.json`. See [Configuration Files](/reference/configuration-files#global-serve-config) for the schema and CLI override behavior. ### Environment isolation Each project loads its own `.env` / `.env.local` in its worker process; env vars never mix across projects. ## API Reference All JSON endpoints live under the `/api/*` prefix. The root paths (`/agents`, `/sessions`, `/schedules`, `/stores`, `/approvals`) serve the HTML dashboard pages instead. The per-session page `/sessions/:id` and its action subroutes carry their own capability auth (session token / API key / local); see [Approval Gates](/guides/approval-gates#auth-and-the-session-token). `POST /run`, `POST /resume/:id`, and the `POST /approvals/:id/...` action endpoints are also still reachable at their original (un-prefixed) paths for backward compatibility. `GET /approvals/:id` now redirects to `/sessions/:id`. Prefer the `/api/*` and `/sessions` paths; the legacy aliases will be removed in a future release. ### GET /api Returns version, default project, and served projects. (`GET /` serves the HTML dashboard built from the same data.) ```json theme={"system"} { "version": "0.12.0", "default": "projA", "projects": [ { "id": "projA", "path": "/abs/path/to/projA", "agentCount": 3, "scheduleCount": 1 }, { "id": "projB", "path": "/abs/path/to/projB", "agentCount": 2, "scheduleCount": 0 } ] } ``` ### POST /api/run Execute an agent and receive the result. (Legacy alias: `POST /run`.) **Request:** ```json theme={"system"} { "agent": "path/to/agent.agentuse", "project": "projA", "prompt": "Optional additional instructions", "model": "anthropic:claude-sonnet-5", "timeout": 300, "maxSteps": 100 } ``` | Field | Type | Required | Description | | - | - | - | - | | `agent` | string | Yes | Path to agent file (relative to that project's root) | | `project` | string | Conditional | Required in multi-project mode unless `--default` is set | | `prompt` | string | No | Additional prompt appended to agent instructions | | `model` | string | No | Override model in agent file | | `timeout` | number | No | Max execution time in seconds (default: 300) | | `maxSteps` | number | No | Max tool call steps | **Response:** ```json theme={"system"} { "success": true, "result": { "text": "Agent response", "finishReason": "end-turn", "duration": 1234, "tokens": { "input": 500, "output": 200 }, "toolCalls": 3 } } ``` **Error Response:** ```json theme={"system"} { "success": false, "error": { "code": "AGENT_NOT_FOUND", "message": "Agent file not found: my-agent.agentuse" } } ``` | Error Code | HTTP Status | Description | | - | - | - | | `AGENT_NOT_FOUND` | 404 | Agent file doesn't exist | | `PROJECT_NOT_FOUND` | 404 | Unknown project id in multi-project mode | | `PROJECT_REQUIRED` | 400 | Multi-project request without `project` or `--default` | | `INVALID_PATH` | 400 | Path outside project root | | `INVALID_REQUEST` | 400 | Invalid JSON body | | `MISSING_FIELD` | 400 | Required field missing | | `TIMEOUT` | 504 | Execution timed out | | `EXECUTION_ERROR` | 500 | Runtime error | ### GET /api/agents Lists the agents the daemon loaded as JSON. `path` matches what `POST /api/run` expects. (The browsable HTML page is at `/agents`.) For one agent's capability summary and raw source, use `GET /api/agents/detail?project=&path=`. The path must match an agent already loaded by that project; the browsable detail hub is at `/agents//`. ```json theme={"system"} { "success": true, "agents": [ { "projectId": "projA", "path": "daily.agentuse", "name": "Daily Digest", "model": "anthropic:claude-sonnet-5", "schedule": "0 9 * * *" } ], "errors": [] } ``` ### GET /api/schedules Lists scheduled agents as JSON, soonest next run first. (The browsable HTML page is at `/schedules`.) ```json theme={"system"} { "success": true, "schedules": [ { "projectId": "projA", "agentPath": "daily.agentuse", "expression": "0 9 * * *", "human": "Daily 9am", "enabled": true, "nextRun": "2026-06-03T16:00:00.000Z", "lastRun": null } ] } ``` From the terminal, `agentuse serve agents` and `agentuse serve schedules` render these as tables. See [CLI Commands](/reference/cli-commands#serve-agents). ### GET /api/sessions Lists every run (top-level sessions; subagent sessions are excluded) as JSON, newest first. Filter with `?agent=`, `?trigger=scheduled|manual|slack|api`, and `?days=` (default \~7 days). The browsable HTML page is at `/sessions`. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions?trigger=scheduled" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` ```json theme={"system"} { "success": true, "sessions": [ { "project": "projA", "sessionId": "01JFN8K3M2P1", "agent": { "id": "daily", "name": "Daily Digest" }, "status": "completed", "trigger": "scheduled", "createdAt": 1717430400000, "updatedAt": 1717430412000 } ], "window": { "days": 7, "createdAfter": 1716825600000 }, "errors": [] } ``` `trigger` records how the run started: `scheduled` (the built-in scheduler), `api` (`POST /api/run`), `slack`, or `manual` (CLI runs and the default). ### GET /api/sessions/:id Returns one session including its run-log entries. API-key gated. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions/01JFN8K3M2P1" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` For the human-facing view + approve page, the redirect target, and the session token, see [Approval Gates](/guides/approval-gates#experimental-session--approval-api). ## Streaming Response For real-time output, request NDJSON streaming: ```bash theme={"system"} curl -N -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -H "Accept: application/x-ndjson" \ -d '{"agent": "analyzer.agentuse"}' ``` Each line is a JSON event: ```json theme={"system"} {"type": "text", "text": "Analyzing..."} {"type": "tool-call", "name": "read_file", "args": {"path": "data.txt"}} {"type": "tool-result", "name": "read_file", "result": "..."} {"type": "text", "text": "Complete!"} {"type": "finish", "finishReason": "end-turn", "duration": 2345} ``` ## Authentication When exposing the server externally, authentication is required: ```bash theme={"system"} # Set API key export AGENTUSE_API_KEY="your-secret-key" # Start on all interfaces agentuse serve --host 0.0.0.0 ``` Include the key in requests: ```bash theme={"system"} curl -X POST http://server:12233/api/run \ -H "Authorization: Bearer your-secret-key" \ -H "Content-Type: application/json" \ -d '{"agent": "assistant.agentuse"}' ``` Use `--no-auth` to bypass authentication (dangerous for production). ## Exposing Your Local Server Access from your devices or team only: ```bash theme={"system"} brew install tailscale tailscale up agentuse serve --public-url https://..ts.net tailscale serve --bg 12233 ``` `agentuse serve` binds `127.0.0.1` by default, so put it behind `tailscale serve` and pass the resulting URL as `--public-url`. Without it, a keyless daemon rejects requests addressed to the tailnet hostname. Expose to the internet for external webhooks: ```bash theme={"system"} brew install cloudflared cloudflared tunnel --url http://localhost:12233 # in another terminal, once the tunnel prints its URL: AGENTUSE_API_KEY=your-secret-key agentuse serve --public-url https://xxx.trycloudflare.com ``` The tunnel prints a public `https://xxx.trycloudflare.com` URL with automatic HTTPS. Set `AGENTUSE_API_KEY` so the public endpoint is not open, and pass the tunnel URL as `--public-url` so approval links and the host check use it. ## Integration Examples ### GitHub Webhook Create an agent to handle GitHub events: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: Process GitHub webhook events tools: bash: commands: - "gh *" - "git *" --- Process the incoming GitHub event and take appropriate action. ``` Configure a GitHub webhook to POST to your server: ``` URL: https://your-server.com/api/run Content-Type: application/json Body: {"agent": "github-handler.agentuse", "prompt": ""} ``` ### Slack Integration Slack slash commands require a response within 3 seconds and signature verification. Use a workflow tool as middleware: **With n8n or Make:** 1. Add Slack trigger node (receives slash commands) 2. Add HTTP Request node → POST to `http://server:12233/api/run` 3. Return agent response to Slack **With Zapier:** 1. Trigger: Slack → New Slash Command 2. Action: Webhooks → POST to AgentUse `/run` 3. Action: Slack → Send Channel Message with result Direct Slack integration requires handling the 3-second timeout, form-urlencoded parsing, and request signature verification. Workflow tools handle this automatically. ### n8n / Make / Zapier Use HTTP request nodes to trigger agents: 1. Set URL to `http://your-server:12233/api/run` 2. Method: POST 3. Headers: `Content-Type: application/json` 4. Body: ```json theme={"system"} { "agent": "workflow-agent.agentuse", "prompt": "{{trigger.data}}" } ``` ### Cron Job (External) Trigger from system cron instead of built-in scheduler: ```bash theme={"system"} # /etc/cron.d/agent-tasks 0 * * * * curl -s -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "hourly-task.agentuse"}' ``` ## Server Configuration See [CLI Commands - agentuse serve](/reference/cli-commands#agentuse-serve) for all server options including port, host, debug mode, and authentication configuration. ## Production Deployment For deploying `agentuse serve` in production with reverse proxies (nginx), process management (PM2), and Docker, see [Self-Hosting](/guides/self-hosting#production-deployment). ## Next Steps Run agents on a cron schedule Deploy in production # Installation Source: https://docs.agentuse.io/installation Install AgentUse for macOS or from the command line ## macOS Desktop Download the signed DMG from the [latest GitHub release](https://github.com/agentuse/agentuse/releases/latest), open it, and move **AgentUse** to Applications. The app includes the AgentUse runtime and dashboard, so it does not require Node.js or a separate CLI installation. On first launch, Desktop setup offers two choices: * **Launch AgentUse at login** is selected by default and is applied when you select **Continue**. * **Add CLI launcher** optionally creates `~/.local/bin/agentuse` for use in Terminal. Setup remains available even if you skip it. After continuing, the app joins the same guided sample and first-agent flow as the Web UI. Learn how the menu-bar app, CLI launcher, and login-shell PATH work together. ## Requirements These requirements apply to command-line installations. The macOS app bundles its own runtime. Node.js 22 or later macOS, Linux, or Windows with WSL Check your Node.js version before installing: ```bash theme={"system"} node --version ``` ## Install the CLI globally A global installation gives you the `agentuse` command in every terminal. ```bash theme={"system"} npm install -g agentuse agentuse --version ``` ```bash theme={"system"} pnpm install -g agentuse agentuse --version ``` ```bash theme={"system"} bun add -g agentuse agentuse --version ``` ```bash theme={"system"} yarn global add agentuse agentuse --version ``` Create a project, run the built-in sample, and create your first agent. ## Run without installing Package runners download AgentUse into their cache and run it without adding a global command: ```bash theme={"system"} npx agentuse@latest setup ``` ```bash theme={"system"} pnpm dlx agentuse@latest setup ``` ```bash theme={"system"} bunx agentuse@latest setup ``` Use the same runner prefix for later commands. For example: ```bash theme={"system"} npx agentuse@latest serve ``` Install AgentUse globally if you expect to use it regularly. ## Upgrade The AgentUse Mac app downloads updates in the background and prompts when they are ready. Use **Settings → About** for a manual check or to install an update you deferred. See [AgentUse for Mac](/guides/macos-desktop#updates) for details. For command-line installations, run the install command again to move to the latest release: ```bash theme={"system"} npm install -g agentuse@latest ``` ```bash theme={"system"} pnpm install -g agentuse@latest ``` ```bash theme={"system"} bun add -g agentuse@latest ``` ```bash theme={"system"} yarn global add agentuse@latest ``` Confirm which version your shell resolves: ```bash theme={"system"} agentuse --version ``` ## Uninstall Removing the CLI does not remove your projects or AgentUse configuration under `~/.agentuse`. ```bash theme={"system"} npm uninstall -g agentuse ``` ```bash theme={"system"} pnpm remove -g agentuse ``` ```bash theme={"system"} bun remove -g agentuse ``` ```bash theme={"system"} yarn global remove agentuse ``` ## Install from source Use this path when contributing to AgentUse or testing an unreleased build. It requires Node.js 22+, Bun, and pnpm. ```bash theme={"system"} git clone https://github.com/agentuse/agentuse.git cd agentuse corepack enable pnpm install --frozen-lockfile pnpm build npm link agentuse --version ``` `npm link` points the global `agentuse` command at this checkout. Re-run `pnpm build` after source changes, or use the repository's development scripts for watch mode. ## Docker You do not need Docker to use AgentUse. The official image is intended for self-hosting and containerized execution. Run the Web UI, webhooks, schedules, and agents in a container. ## Troubleshooting Confirm that your package manager's global binary directory is on `PATH`: ```bash theme={"system"} npm prefix -g pnpm bin -g bun pm bin -g ``` Restart your terminal after changing `PATH`. You can also use `npx agentuse@latest --version` without changing your global installation. AgentUse requires Node.js 22 or later: ```bash theme={"system"} node --version ``` With [nvm](https://github.com/nvm-sh/nvm), install and select Node.js 22: ```bash theme={"system"} nvm install 22 nvm use 22 ``` Avoid installing with `sudo`. Use a Node.js version manager such as [nvm](https://github.com/nvm-sh/nvm) or [Volta](https://volta.sh), then retry the global installation. Check which executable your shell resolves: ```bash theme={"system"} command -v agentuse agentuse --version ``` Remove an older installation made by another package manager, or put the intended package manager's global binary directory earlier on `PATH`. Use the terminal setup path on a remote, headless, or SSH environment: ```bash theme={"system"} agentuse setup --terminal ``` # Introduction Source: https://docs.agentuse.io/introduction Own and operate Markdown-defined AI agents on infrastructure you control AgentUse Logo AgentUse Logo Dark ## Own the agents doing your company's work **AgentUse** is an open-source agent runtime. Define agents in Markdown, run them with Claude, OpenAI, or open models on infrastructure you control, and keep every definition as a plain file in your repository. Let agents work autonomously. Put consequential actions behind human approval. Run your first agent without installing AgentUse or configuring an API key Define instructions, models, tools, and runtime behavior in Markdown Pause consequential actions for human review, then resume the same session Run AgentUse locally, on a server, in CI, or inside Docker ## Why AgentUse? Managed agent platforms provide a runtime but make their hosted environment the operational center. Agent frameworks provide flexible libraries but leave you to assemble the application and operations layer. AgentUse starts with a plain agent file and supplies the runtime around it: the agent loop, tools, durable sessions, schedules, approvals, HTTP endpoints, and an operations dashboard. Instructions are natural-language Markdown and configuration is readable YAML. Diff, review, version, and adapt agents using the tools you already use for source code. AgentUse manages tool calls, sessions, schedules, failures, approval waits, artifacts, and results without requiring you to build an SDK application. Use the same agent file from the command line, a schedule, an HTTP trigger, CI/CD, or Docker. No hosted AgentUse control plane is required. Add `approval: true` when work should pause for review. A reviewer can approve, reject, or comment, and AgentUse resumes the durable session with that decision. Your agent definitions, runtime, and operational state stay under your control. ## Key Features Put model configuration and capabilities in YAML frontmatter, then describe the work in plain language. Use Anthropic, OpenAI, OpenRouter, OpenCode Go, Amazon Bedrock, or a compatible local endpoint. Override the model at runtime without rewriting the agent. Use allowlisted filesystem and shell access, built-in runtime tools, reusable skills, subagents, stores, and Model Context Protocol servers. Trigger agents from the CLI, schedules, HTTP, CI/CD, or Docker. Inspect durable sessions and review consequential actions from the operations dashboard. ## Try It Now No API key is needed for this hosted example: ```bash theme={"system"} npx -y agentuse@latest run https://agentuse.io/hello.agentuse ``` ## How It Works An AgentUse agent is a Markdown file with YAML configuration and plain-English instructions: ```markdown theme={"system"} --- model: anthropic:claude-haiku-4-5 --- You are a helpful assistant. ## Task Say hello to the user and ask how you can help them today. ``` Save the file as `hello.agentuse` and run: ```bash theme={"system"} npx -y agentuse@latest run hello.agentuse ``` The filename becomes the default agent id. The same file can later gain tools, a schedule, approval requirements, skills, subagents, or persistent stores without becoming an application project. ## What Can You Build? * **Operational agents** that monitor systems, prepare reports, and surface work that needs attention * **Approval-gated agents** that draft, validate, and pause before sending, publishing, deploying, or deleting * **Repository and CI agents** that inspect changes, run checks, and produce reviewable artifacts * **MCP-powered agents** that work with databases, APIs, browsers, and business systems * **Multi-agent systems** that delegate bounded work to specialized child agents * **Stateful agents** that preserve structured knowledge and metrics across runs # Quick Start Source: https://docs.agentuse.io/quickstart Set up AgentUse and run your first agent ## Choose how to start ### macOS Desktop Download AgentUse from the [latest GitHub release](https://github.com/agentuse/agentuse/releases/latest), move it to Applications, and open it. On the Desktop setup screen, choose whether AgentUse should launch at login and optionally add its bundled CLI launcher for Terminal. Select **Continue** to enter the guided setup. The app includes the runtime, so macOS Desktop users do not need to install Node.js or AgentUse globally. ### Command line ```bash theme={"system"} npm install -g agentuse agentuse --version ``` See [Installation](/installation) for pnpm, Bun, Docker, and development setup options. Start the guided Web setup: ```bash theme={"system"} agentuse setup ``` On Apple silicon Macs you can also choose **Mac app**, which opens the download page; the app bundles its own runtime. Otherwise choose **Browser** for the guided setup. AgentUse opens its Web UI and keeps the server running in your terminal. Both routes now follow the same onboarding flow. Keep the suggested name, `my-agents`, to create a dedicated project under `~/.agentuse/projects/`, or attach an existing project. AgentUse shows the full path before anything writes an agent file. For an existing project, the guided flow can scan a sanitized, read-only view and suggest recurring work grounded in the repository while accounting for agents already there. Select **Run sample agent** to see a complete session in the dashboard. The sample uses built-in data, needs no provider credentials, and does not create an agent file. In the sample result, select **Create my first agent**. If no provider is ready, AgentUse opens the same provider setup used in Preferences before any model call or agent file write. Describe what the agent should do, choose a creator model from a connected provider, and select **Create agent**. That model is used only to design and name a focused agent using AgentUse authoring guidance; it independently chooses a suitable runtime model from the connected providers. AgentUse validates the generated source, runtime-model choice, and static safety guardrails, then performs a separate read-only model review of whether the declared tools can support the draft's operations. For example, exact parser diagnostics require a callable parser, not just permission to read files. Review the draft, request changes if needed, then select **Save agent**. This capability review does not execute or test the finished agent, which still needs validation before its first real run. A schedule proposed by project discovery starts paused until you test and enable it. If you prefer to work hands-on, use **Copy prompt to coding agent** instead; the prepared handoff carries your task and keeps the existing validation workflow as an escape hatch. When AgentUse detects the new agent, select **Review agent**, review it, and start its first real run. If detection takes too long, you can copy the prompt again or check manually without leaving onboarding. Your coding agent's own login does not authenticate the agents it creates. Connect the runtime provider in AgentUse onboarding or Preferences. Do not paste API keys, authorization codes, or OAuth callback URLs into coding-agent chat. ### Terminal or headless setup If a browser cannot be opened, use the same setup flow in the terminal: ```bash theme={"system"} agentuse setup --terminal ``` AgentUse creates and registers the project, prints its full path, and gives you the exact next steps. The dashboard is optional for this path. ## Create an agent without a coding agent You do not need Codex, Claude Code, or another coding agent. Complete `agentuse setup` first, then use the project path shown by setup. ### 1. Configure a runtime provider ```bash theme={"system"} cd ~/.agentuse/projects/my-agents agentuse provider list agentuse provider login ``` Choose a provider in the login prompt, then list its current models: ```bash theme={"system"} agentuse models ``` ### 2. Write one agent file Create `agents/hello.agentuse` and replace `:` with an exact model ID from the previous command: ```markdown theme={"system"} --- model: : description: Write a friendly greeting --- Write a short greeting and suggest one useful task you can help with. ``` ### 3. Validate and run it ```bash theme={"system"} agentuse doctor agents/hello.agentuse agentuse run agents/hello.agentuse ``` To inspect the result later: ```bash theme={"system"} agentuse sessions ``` ## Start AgentUse again Setup is only required once. Later, start the registered project and Web UI with: ```bash theme={"system"} agentuse serve ``` ## What's next? Learn agent syntax and design patterns Configure providers, credentials, and model defaults Run an agent automatically Browse all AgentUse commands # Agent Syntax Reference Source: https://docs.agentuse.io/reference/agent-syntax Complete syntax guide for AgentUse agent files ## File Format AgentUse agents are markdown files with YAML frontmatter for configuration and plain English instructions. ```markdown theme={"system"} --- # YAML configuration name: agent-name model: provider:model --- # Markdown content (system prompt) You are an AI assistant. ## Optional sections Additional instructions or context. ``` ## Frontmatter Reference ### Required Fields AI model to use for the agent. Format: `provider:model-name` Supported providers: * `anthropic` - Anthropic Claude models * `openai` - OpenAI GPT models * `openrouter` - OpenRouter models * `opencode-go` - OpenCode Go open coding models * `bedrock` - Amazon Bedrock (Claude, Llama, Mistral, Nova, etc.) ```yaml theme={"system"} model: anthropic:claude-sonnet-5 model: openai:gpt-5.4-mini model: openrouter:z-ai/glm-5.3 model: opencode-go:kimi-k2.7-code model: bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0 ``` **Version aliases.** Leave the version off and the agent tracks the newest model in that line, so it needs no edit when a new release ships: ```yaml theme={"system"} model: anthropic:claude-sonnet # newest Sonnet model: openai:gpt-mini # newest small GPT model: openrouter:x-ai/grok # newest Grok ``` A real model id always wins over an alias, so anything you pin keeps its exact meaning. See [Version Aliases](/reference/models#version-aliases) for the full table, and run `agentuse models` to see what each alias resolves to today. **Named aliases.** `@name` resolves through the `models.aliases` block of your AgentUse config, which lets many agent files be repointed at once: ```yaml theme={"system"} model: "@fast" ``` A named alias may be configured with ordered fallback candidates. Fallback is limited to transient or authentication failures before the current execution segment receives model output or a tool call. A resumed segment starts on the concrete model already recorded, then may advance through its persisted remaining candidates. **Omitting `model`.** With `models.default` (or `AGENTUSE_MODEL`) configured, the field is optional and the agent uses that default. Without a default, a file that omits `model` fails to parse. See [Configuration Files](/reference/configuration-files#model-defaults-and-aliases). You can also specify a custom environment variable suffix, which composes with aliases: ```yaml theme={"system"} model: anthropic:claude-sonnet-5:dev # Uses ANTHROPIC_API_KEY_DEV model: anthropic:claude-sonnet:dev # Newest Sonnet, ANTHROPIC_API_KEY_DEV model: opencode-go:kimi-k2.7-code:dev # Uses OPENCODE_GO_API_KEY_DEV ``` ### Optional Fields Maximum execution time before the agent is terminated. A bare number means seconds; a suffixed duration string (`"90s"`, `"10m"`, `"1h"`) also works. Default: 300 (5 minutes) This prevents runaway agents and provides a safety ceiling for execution time. Execution receives one wrap-up notice at the next model boundary once the remaining budget is within the larger of 20% of its effective budget and twice the slowest model latency observed so far. The agent should return established findings and identify unfinished work; verification and approval requirements still apply. A running tool is not interrupted by the notice, so delivery can be later. The hard deadline remains in force. A delegated agent that sets its own `timeout` is held to it, constrained by its parent's remaining budget. One that omits `timeout` inherits the parent's remaining budget rather than taking a shorter deadline of its own. A child timeout returns a failed outcome to the parent; parent cancellation stops descendants. Active time is preserved across approval suspension and resume, excluding human waiting time. A new follow-up on an ended session starts a new budget. Historical sessions without a saved budget begin accounting on their next execution. Session details show “Wrapping up” after delivery. A returned incomplete response is labelled “Wrapped up before timeout”; a hard expiry still reads “Timed out.” A completed task remains “Completed,” with the notice in its details. Receiving a notice alone never counts as graceful completion. **Precedence:** CLI `--timeout` flag overrides this value. ```yaml theme={"system"} timeout: 600 # 10 minutes (bare number = seconds) timeout: 30m # duration string ``` Choose a timeout appropriate for your agent's expected workload. Simple tasks may complete in seconds, while complex multi-step workflows may need 10-30 minutes. Maximum number of LLM generation steps (tool call cycles) the agent can take. Default: 100 This prevents infinite loops and controls cost by limiting the number of LLM calls. **Precedence:** `MAX_STEPS` environment variable overrides this value. ```yaml theme={"system"} maxSteps: 50 # Conservative limit for simple tasks maxSteps: 200 # Higher limit for complex workflows ``` Each step typically involves an LLM call. Higher values increase potential cost if the agent gets stuck in a loop. Maximum tokens the model may generate in a **single response** (the provider's `max_tokens`). This is a per-step ceiling, not a run-wide total. Leave it unset in almost all cases. When unset, first-class Anthropic models default to their real output limit capped at **32,000**, and other providers use their own model-max default. Raise it only for an agent that must emit a large single response or write a big file in one tool call; the value is clamped down to the model's real output limit when that limit is known. ```yaml theme={"system"} maxOutputTokens: 64000 # allow a bigger single response / file write ``` This exists because a model id newer than the underlying SDK's model table (e.g. `claude-sonnet-5`) would otherwise be capped at a tiny 4096 `max_tokens`, silently truncating normal-length outputs and tool-call arguments. A truncated response ends the run, so AgentUse sets the cap from its own model registry instead. Extended thinking (`anthropic.thinking`) computes its own ceiling and takes precedence over this field. Tool-call intent phrases. When enabled (the default), every tool schema gains an optional `intent` parameter: one short phrase from the model stating what each specific call is trying to achieve (for example, "Running runner tests to verify the resume fix"). The CLI and the serve session view show the phrase as the call's activity label, and it is recorded in the session log; the real tool never sees the parameter (it is stripped before dispatch). Set `intent: false` to keep tool schemas pristine, for example when a provider or a third-party MCP server is sensitive to extra parameters, or to save the few output tokens the phrase costs on every call. ```yaml theme={"system"} intent: false # disable intent phrases for this agent ``` A brief description of what the agent does. This description is used in multiple contexts: * **As subagent tool description**: When this agent is used as a subagent, this becomes the tool description that parent agents see * **CLI output**: Displayed when running the agent to provide context * **Plugin events**: Available to plugins for logging or monitoring * **Documentation**: Self-documenting agents for teams Best practices: * Keep it concise (80-120 characters recommended) * Be action-oriented (describe what the agent does, not what it is) * Focus on the primary capability or purpose ```yaml theme={"system"} description: "Reviews code for security vulnerabilities and best practices" description: "Generates unit tests for JavaScript/TypeScript functions" description: "Analyzes logs and identifies potential issues" ``` Version identifier for the agent. For developer documentation only - not displayed or used at runtime. ```yaml theme={"system"} version: "1.0.0" version: "2024-01-15" ``` Developer notes for setup instructions, requirements, or other documentation. Not displayed at runtime. ```yaml theme={"system"} notes: | Setup: 1. Set NEWS_API_KEY environment variable 2. Install jq: brew install jq ``` Free-form annotations for you and your tooling. The framework never interprets these keys, it only preserves and surfaces them. This is the sanctioned home for custom keys, which are otherwise stripped from frontmatter. ```yaml theme={"system"} metadata: draft: true owner: leon team: growth ``` Metadata is shown by `agentuse agents`: top-level keys render as chips after the description (a `true` flag prints its bare key, a scalar prints `key=value`, falsey flags are omitted), and the full object is available in `agentuse agents --json` under `.metadata` for filtering. ```bash theme={"system"} # List only draft agents agentuse agents --json | jq '.agents[] | select(.metadata.draft)' ``` Metadata is an annotation, not runtime input: it is not injected into the agent's prompt. Configuration for Model Context Protocol (MCP) servers that provide tools and resources to the agent. Each server is defined as a key-value pair where the key is the server name and the value is the server configuration. Array of sub-agent configurations that this agent can delegate tasks to. Each sub-agent must specify a `path` to the `.agentuse` file, with optional `name` and `maxSteps` parameters. **Path Resolution**: Subagent paths are resolved relative to the **parent agent file's directory**, not the current working directory. This ensures portability and consistency. ```yaml theme={"system"} # In /project/agents/main.agentuse subagents: - path: ../utils/helper.agentuse # Resolves to /project/utils/helper.agentuse - path: ./local-agent.agentuse # Resolves to /project/agents/local-agent.agentuse ``` Declare agents whose output this agent consumes, usually through a shared store. Paths resolve relative to the current agent file, using the same path rules as `subagents`. ```yaml theme={"system"} dependsOn: - ./collect-sources.agentuse - ./normalize-records.agentuse ``` `dependsOn` is advisory metadata. AgentUse exposes the relationship through the agents API and relationship graph, but it does **not** serialize runs or delay schedules. Use compatible schedules or a manager agent when execution order must be enforced. A single dependency can use the string shorthand: ```yaml theme={"system"} dependsOn: ./collect-sources.agentuse ``` Let the agent keep what reviewers tell it and apply the best of it to later runs. See the [Learning guide](/guides/learning). `learning: true` applies feedback a reviewer explicitly saved with **Learn from this comment**, `--remember`, or manual add. An unchecked comment affects the current run only. Free-form observation capture is opt-in through `capture.custom` or `capture.agent`. ```yaml theme={"system"} learning: capture: addons: [tool-errors] # typed, structurally-verified channels custom: | # or: agent: ./capture.agentuse Only keep instructions about tone and sourcing. apply: true max: 20 model: anthropic:claude-haiku-4-5 ``` | Key | Type | Description | | - | - | - | | `capture` | boolean \| object | Automatic observation configuration. `true` or `{}` enables no automatic channel; human learning uses Learn/`--remember`. Name `addons`, `custom`, or `agent` to opt in. Default `true` | | `capture.addons` | string\[] | Channels verified structurally in code rather than by prompt. `tool-errors` (failed call → corrected call → confirmed success) is the only entry today. Default `[]` | | `capture.custom` | string | What is worth keeping, in your own words. Enables free-form observation capture through the built-in evaluator, scoped by this text. Mutually exclusive with `agent` | | `capture.agent` | string | Path to an `.agentuse` file that replaces the built-in evaluator, relative to this agent file, the same pattern as `verify.judge`. Its candidates are still vetted. Mutually exclusive with `custom` | | `apply` | boolean | Inject stored, vetted, active learnings into future runs. Default `true` | | `max` | number | How many learnings this agent keeps, and so how many may reach the model per run. 1-50, default 15. `agentuse doctor` shows what this costs and how many are stored but never injected | | `model` | string | Helper model used for capture, vetting, and `agentuse learnings tidy`. Defaults to the agent's own model | `criteria` was removed in v0.18.0 and is a hard parse error: ``` "criteria" was removed — free-form capture is opt-in now. To restore scoped free-form capture, move it to capture: { custom: "..." } ``` Setting both `custom` and `agent` is likewise a parse error. Boolean `capture: true` still parses, but its meaning narrowed in v0.18.0: it enables no automatic observation channel. Human feedback becomes durable only when the reviewer chooses Learn (or uses `--remember`). An agent carrying it (or `learning: true`) warns once at parse time; `agentuse doctor` echoes the notice. `file` and `evaluate` were removed in v0.17.0 and are rejected by name at parse time, e.g. `Unrecognized key(s) in object: 'file'`. Learnings live in the AgentUse state directory (`agentuse learnings migrate --all` moves older ones), and an agent that used `evaluate` to capture without applying should now set `apply: false`. Provider-agnostic reasoning effort, the recommended knob. AgentUse normalizes the requested level to the selected model's supported vocabulary, then uses the AI SDK or a native provider option to apply it. For example, GPT-5.6 maps `minimal` to `low`, while modern Claude uses adaptive thinking. One setting works across Claude and OpenAI without forwarding incompatible values. ```yaml theme={"system"} model: anthropic:claude-opus-5 reasoning: high # none | minimal | low | medium | high | xhigh | max ``` Use `medium`/`high` for genuine judgment (hard calls under competing constraints, planning, debugging), `low`/`minimal` for lighter work, omit for the model default, and `none` to force reasoning off. It is opt-in and bills reasoning tokens at **output rates**. Prefer this over the provider-specific `openai.reasoningEffort` / `anthropic.thinking.budgetTokens` below, which are escape hatches for exact wire-level control and are honored only when the top-level `reasoning` is unset. Being top-level, it also avoids the "wrong-level key silently dropped" trap a misplaced `thinking:` hits. OpenAI-specific options for GPT-5 and other OpenAI models. `reasoningEffort` here is the exact-control alternative to the top-level `reasoning` above. **Supported Options:** * `reasoningEffort`: Controls thinking effort for reasoning models (`'none'`, `'minimal'`, `'low'`, `'medium'`, `'high'`, `'xhigh'`, `'max'`) * `reasoningSummary`: Requests a streamed natural-language summary of the model's reasoning (`'auto'` or `'detailed'`), so the reasoning shows up inline in the [session trace](/reference/session-storage). **Defaults to `'auto'` on reasoning-capable models** (the reasoning tokens are billed either way, so the summary is near-free visibility). Non-reasoning models (e.g. `gpt-4o`) omit it. * `textVerbosity`: Controls response length and detail (`'low'`, `'medium'`, `'high'`) * `promptCacheKey`: Optional OpenAI prompt-cache routing key. AgentUse sets a stable default per agent when omitted. * `promptCacheRetention`: Optional OpenAI prompt-cache retention policy (`'in_memory'` or `'24h'`) * Defaults: when `reasoningEffort`, `textVerbosity`, or `promptCacheRetention` are omitted, AgentUse leaves them unset and uses the OpenAI/AI SDK defaults. When `promptCacheKey` is omitted, AgentUse generates a stable key per agent. `reasoningSummary` defaults to `'auto'` on reasoning-capable models; set it explicitly (or to disable, you currently cannot turn it off via config without leaving a non-reasoning model). ```yaml theme={"system"} openai: reasoningEffort: high # More thorough reasoning reasoningSummary: auto # Surface reasoning in the trace (default on reasoning models) textVerbosity: low # Concise responses promptCacheRetention: 24h # Optional extended prompt caching on supported models ``` These options are particularly useful with GPT-5 models to balance response quality, latency, and cost. Some effort levels are model-specific; for example, `xhigh` and `none` are only accepted by OpenAI models that support them. Whether a reasoning summary actually streams depends on `reasoningEffort` and task complexity, the model may emit nothing for trivial tasks. Anthropic-specific options for Claude models. `thinking.budgetTokens` is the exact-budget alternative to the top-level `reasoning` above; use it only when you need to pin an exact token budget. **Supported Options:** * `thinking.budgetTokens`: Enables Claude [extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) with the given token budget (minimum `1024`). When set, Claude streams its reasoning, which appears inline in the [session trace](/reference/session-storage). Honored only when the top-level `reasoning` is unset. ```yaml theme={"system"} anthropic: thinking: budgetTokens: 4096 ``` Extended thinking is **off by default** and is an explicit opt-in: enabling it generates new thinking tokens billed at **output rates** (a real cost increase that scales with the budget). AgentUse automatically raises `max_tokens` above the budget to satisfy Anthropic's constraint and reserve room for the answer. Controls which installed skills are available to the agent. Default: `auto` ```yaml theme={"system"} skills: auto ``` `auto` preserves the default behavior: all discovered skills are available for on-demand loading when relevant. A discovered skill is granted nothing until trusted (or its commands are listed in `tools.bash.commands`). **Trusting a skill grants it the bash commands it declares** in its SKILL.md `allowed-tools`. Trust per skill (recommended) or globally: ```yaml theme={"system"} skills: linkedin: trusted # grant just this skill's declared commands # or: skills: trusted # trust every discovered skill (blunt shortcut) ``` Trust only grants (the commands can run); gating is your explicit call. To require approval for a subset a skill grants (e.g. trust grants `birdc *` but you want `birdc reply *` approved), add that pattern to [`tools.bash.gated`](/guides/approval-gates#gated-commands-mechanical-enforcement); gated-wins precedence gates it while the rest of the family auto-runs. `agentuse doctor` flags granted commands that look irreversible. To preload a skill before the task starts without trusting it, define it explicitly (grant its commands yourself via `tools.bash.commands`): ```yaml theme={"system"} skills: [linkedin] ``` Inspect what trust granted with `agentuse doctor `. You can combine auto discovery with explicit preloads: ```yaml theme={"system"} skills: auto: true linkedin: # preload, but grant no commands x-personal: trusted ``` Per-skill entries accept only the `trusted` grant. To grant a command without trusting the skill, list the command explicitly in `tools.bash.commands`. The removed `allow` key is invalid. Run `agentuse doctor ` to inspect skill grants. Doctor can show commands mentioned in the skill docs, but the output is advisory and not a permission manifest. Add `--last-run` to inspect the latest recorded session and diagnose actual blocked commands from runtime. Run agent commands inside an isolated Docker container. Requires Docker to be installed and running. Use `sandbox: true` for defaults or provide a config object. **Fields (when using object form):** * `provider`: Must be `docker` (required) * `image`: Docker image to use (default: `node:22-slim`) * `timeout`: Container timeout: bare number = seconds (default: `300`), or a duration string like `"10m"` * `setup`: Shell command(s) to run after container starts * `env`: Host env var names to forward into the container ```yaml theme={"system"} sandbox: provider: docker image: python:3.12-slim timeout: 600 setup: - pip install pandas numpy ``` When enabled, the agent receives `sandbox__exec` for running commands in the container. File I/O uses the existing filesystem tool, each filesystem path is mounted at its real host path with per-path ro/rw mode derived from permissions. This feature is experimental. See the [Sandbox guide](/guides/sandbox) for full documentation. Schedule for automatic agent execution in serve mode. The format is auto-detected. **Supported Formats:** * **Interval**: `5s`, `10m`, `2h` (sub-daily) * **Cron**: `"0 * * * *"`, `"0 9 * * 1-5"` (daily+) ```yaml theme={"system"} schedule: "30m" # Every 30 minutes (interval) schedule: "0 9 * * 1-5" # Weekdays at 9am (cron) ``` Schedules only run when the agent is loaded via `agentuse serve`. Use `agentuse run` for one-off executions. Add a human approval gate without putting approval instructions in the agent prompt. When `approval` is present, AgentUse automatically enables the internal `await_human` tool and injects the approval behavior for you. The markdown body should describe the work the agent needs to do; the YAML declares that the work must be reviewed before it is finalized. ```yaml theme={"system"} approval: true ``` Optional timeout: ```yaml theme={"system"} approval: timeout: 24h ``` **Fields:** * `timeout`: optional suspension timeout such as `24h` or `7d`. A bare number means seconds. Approvals do not expire by default. Approval requests render best when the agent can provide `summary`, `draft` or `artifact_url`, `context`, and `risk` fields to the internal approval tool. You can define the approval boundary in the agent instructions. For example: ```md theme={"system"} You may create local drafts and preview artifacts without approval. Before scheduling, publishing, sending, deploying, merging, or changing external production state, request approval. Include the final content, target destination, timing, and risks in the approval request. ``` See [Approval Gates](/guides/approval-gates) for the full setup guide and Approval API examples. Configure optional external collaboration channels separately from approval policy. ```yaml theme={"system"} channels: [slack] ``` ```yaml theme={"system"} channels: slack: events: [approval, completion, failure] channel_id: C0123456789 ``` **Fields:** * `channels`: `[slack]` enables Slack with default events and channel env fallback. * `channels.slack`: `true` or an object to enable Slack. * `channels.slack.enabled`: optional switch for temporarily disabling Slack. * `channels.slack.events`: event or list of events. Supported values are `approval`, `completion`, and `failure`. Use `completion`, not `complete` or `completed`. * `channels.slack.channel_id`: Slack channel id. If omitted, AgentUse uses `SLACK_APPROVAL_CHANNEL`. See [Channels](/guides/channels) for event semantics, Slack setup, and examples. ## Tools Configuration Tools are available to agents through: 1. **Built-in Tools** - Sandboxed Code Mode plus filesystem, Bash, and artifact tools with configurable permissions 2. **MCP Servers** - Connect to any Model Context Protocol server 3. **Sub-Agents** - Delegate tasks to other agents ### Built-in Tools `code_exec` is available automatically and can compose only the tools resolved for the current agent. Eligible JSON tools are normally called through its `tools.` catalog, including for a single call, and hidden from the top-level tool list. Tools that require approval, suspension, subagent delegation, binary or provider-native result delivery, or outcome submission stay on the direct path. Bash is available on both paths: Code Mode can compose structured results from commands in the effective auto-run allowlist, while commands matching `tools.bash.gated` are rejected there and must use direct Bash after approval. A transport-sensitive tool may likewise appear on both paths so its JSON/text result can be composed in Code Mode while its special result is delivered directly. Configure filesystem, bash, and artifact capabilities via the `tools` field: ```yaml theme={"system"} tools: filesystem: - path: ${root} permissions: [read, write] # write also grants edit bash: commands: # auto-run allowlist - "git *" - "npm *" gated: # run only after human approval (per-action lease) - "npm publish *" artifacts: true # enables artifact_save and artifact_list metrics: true # enables record_metric ``` `tools.bash.gated` lists commands that need human sign-off: they run only after an approval covering the exact action, and declaring `gated` enables the approval gate automatically. See [Gated commands](/guides/approval-gates#gated-commands-mechanical-enforcement). See full configuration options for filesystem, bash, and artifact tools ## MCP Servers ### Stdio MCP Configuration ```yaml theme={"system"} mcpServers: filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory", "--read-only"] requiredEnvVars: # Variables that must exist - API_KEY allowedEnvVars: # Optional variables - DEBUG_MODE allowedTools: # Optional: load only these tools - read_* - list_directory disallowedTools: # Optional: tools to exclude - write_file - delete_file toolTimeout: 90 # Optional per-tool-call timeout: bare number = seconds # (default 60), or a duration string like "2m". # Env fallback: MCP_TOOL_TIMEOUT (seconds). ``` ### HTTP MCP Configuration ```yaml theme={"system"} mcpServers: remote_server: url: https://api.example.com/mcp sessionId: my-session-123 # Optional session ID auth: # Optional authentication type: bearer token: ${env:API_TOKEN} headers: # Optional custom headers X-Custom-Header: custom-value requiredEnvVars: # Variables that must exist - API_TOKEN allowedEnvVars: # Optional variables - DEBUG_MODE allowedTools: # Optional: load only these tools - search disallowedTools: # Optional: tools to exclude - dangerous_operation ``` HTTP servers speak the newest MCP protocol (2026-07-28) and fall back to older servers on their own. ### OAuth MCP Servers Most hosted MCP servers sign you in with OAuth. You don't configure anything for that: give the server's URL and nothing else. ```yaml theme={"system"} mcpServers: linear: url: https://mcp.linear.app/mcp ``` If the server asks for a login, the agent's page in `agentuse serve` shows a **Log in** button next to it, and a run fails that server with a message telling you to log in. You can also log in from the terminal: ```bash theme={"system"} agentuse mcp login ./triage.agentuse linear ``` AgentUse registers itself with the server. The login is saved per server URL, so every agent that uses the same server shares it, and runs refresh it on their own. A run never waits for a browser. `agentuse mcp status ` shows each server's state, and `agentuse mcp logout ` forgets a login. A server that refuses the connection but offers no OAuth login wants a key instead: set `auth.token` or an `Authorization` header. Setting either one also turns OAuth off for that server. Set `auth.type: oauth` only when the server needs a pre-registered client or specific scopes: ```yaml theme={"system"} auth: type: oauth clientId: abc123 clientSecret: ${env:LINEAR_SECRET} # Optional, with clientId scopes: [read, write] # Optional ``` ### Multiple MCP Servers ```yaml theme={"system"} mcpServers: filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "./data"] database: command: "npx" args: ["-y", "@modelcontextprotocol/server-postgresql"] requiredEnvVars: - DATABASE_URL # Must be set in .env or shell custom: command: node args: ["./custom-mcp-server.js"] allowedEnvVars: - CUSTOM_CONFIG # Optional configuration http_api: url: https://api.example.com/mcp sessionId: unique-session-id auth: type: bearer token: ${env:API_TOKEN} requiredEnvVars: - API_TOKEN ``` The `mcpServers` field uses a map format where each server has a name as the key. ## Sub-Agents ### Sub-Agent Configuration ```yaml theme={"system"} subagents: - path: ./agents/researcher.agentuse name: researcher # Optional custom name maxSteps: 100 # Optional step limit (default: 100) - path: ./agents/writer.agentuse - path: ../shared/validator.agentuse ``` ### Remote Sub-Agents ```yaml theme={"system"} subagents: - path: https://example.com/agents/helper.agentuse - path: https://raw.githubusercontent.com/user/repo/main/agent.agentuse ``` Sub-agents can call the main agent or other sub-agents, enabling complex multi-agent workflows. ## Environment Variables in MCP Configuration **Security by Design**: AgentUse prevents hardcoding secrets in agent files. Use `requiredEnvVars` and `allowedEnvVars` to control which environment variables are passed to MCP servers. ```yaml theme={"system"} mcpServers: github: command: "npx" args: ["-y", "@modelcontextprotocol/server-github"] requiredEnvVars: - GITHUB_TOKEN # Fails if not set allowedEnvVars: - GITHUB_DEBUG # Optional, warns if missing ``` See the complete reference for security model, setting environment variables, error messages, and examples. ### MCP Server Configuration Fields #### Common Fields (All Server Types) * **`requiredEnvVars`**: Variables that MUST exist. Agent fails if missing. * **`allowedEnvVars`**: Optional variables to pass through if they exist. * **`allowedTools`**: When set, only tools matching these names/patterns load (supports wildcards). Tools the server adds later stay off until you list them. Use it when you want a few tools from a large server. Both lists also cover the `list_resources` and `read_resource` tools AgentUse adds for servers with resources. * **`disallowedTools`**: Tool names/patterns to exclude (supports wildcards). When both are set, `disallowedTools` wins. #### Stdio Server Fields * **`command`**: Executable command (required). Relative paths resolve from agent file's directory. * **`args`**: Command-line arguments (optional) * **`env`**: Additional environment variables (optional) #### HTTP Server Fields * **`url`**: HTTPS URL of the MCP server (required) * **`sessionId`**: Session identifier (optional) * **`auth`**: Optional. `token` sends a bearer token (supports `${env:VAR_NAME}`). Without it, a server that asks for an OAuth login gets one (see OAuth MCP Servers); `type: oauth` adds an optional `clientId`, `clientSecret` and `scopes` * **`headers`**: Custom HTTP headers (optional) ## System Prompt Sections ### Basic Structure ```markdown theme={"system"} --- name: agent model: anthropic:claude-sonnet-5 --- You are a helpful assistant. ## Your Role Detailed description of the agent's role. ## Guidelines - Guideline 1 - Guideline 2 - Guideline 3 ## Task What the agent should do. ``` ### Using Context in Prompts ```markdown theme={"system"} --- name: personalized model: anthropic:claude-sonnet-5 --- You are a helpful AI assistant. ## Context Provide assistance based on the user's specific needs and context. ``` Direct variable interpolation in prompts is not currently supported. Context should be provided through conversation or MCP tools. ### Conditional Sections ```markdown theme={"system"} --- name: adaptive model: anthropic:claude-sonnet-5 --- You adapt based on user needs. ## For Technical Users Provide detailed technical explanations. ## For Non-Technical Users Use simple language and analogies. ## Task Determine user level and respond appropriately. ``` ## Special Syntax ### Commands ```markdown theme={"system"} ## Available Commands !help - Show help !reset - Reset context !compact - Compact context !status - Show status ``` ### Structured Output ````markdown theme={"system"} ## Output Format Return responses as JSON: ```json { "status": "success", "data": "...", "metadata": {} } ```` ```` ### Examples in Prompt ```markdown ## Examples ### Example 1 Input: "Translate hello to Spanish" Output: "Hola" ### Example 2 Input: "What's 2+2?" Output: "4" ```` ## Complete Example ```markdown theme={"system"} --- model: openai:gpt-5.6 description: "Multi-capability AI assistant with file, GitHub, and research capabilities" timeout: 900 maxSteps: 150 openai: reasoningEffort: high textVerbosity: medium mcpServers: filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "./data", "--read-only"] github: command: "npx" args: ["-y", "@modelcontextprotocol/server-github"] requiredEnvVars: - GITHUB_TOKEN # Must be set in .env or shell allowedEnvVars: - GITHUB_DEBUG # Optional debug flag disallowedTools: - delete_* # Prevent deletion operations api_server: url: https://api.example.com/mcp sessionId: agent-session-123 auth: type: bearer token: ${env:API_TOKEN} requiredEnvVars: - API_TOKEN subagents: - path: ./helpers/researcher.agentuse name: researcher # Optional custom name maxSteps: 100 # Optional step limit - path: ./helpers/writer.agentuse --- # Multi-Capability Agent You are an advanced AI assistant with multiple capabilities. ## Your Capabilities 1. **File Access**: Read and write files via the filesystem MCP server 2. **GitHub Access**: Interact with GitHub repositories 3. **Research**: Delegate research tasks to the researcher sub-agent 4. **Writing**: Delegate writing tasks to the writer sub-agent ## Guidelines - Use the appropriate tool for each task - Delegate complex tasks to specialized sub-agents - Handle errors gracefully - Provide clear, concise responses ## Task Assist the user with their request using all available capabilities. ``` ## Validation Rules 1. **File Extension**: Agent files must use `.agentuse` extension 2. **Model**: Must be a non-empty string (required field) 3. **MCP Server Configuration**: * Stdio servers: Must have `command` field * HTTP servers: Must have `url` field with `http://` or `https://` protocol * Cannot have both `command` and `url` in the same server config 4. **Environment Variables**: * `requiredEnvVars` and `allowedEnvVars` must be arrays of strings * Use `${env:VAR_NAME}` syntax to reference environment variables (e.g., in `auth.token`) 5. **Sub-agents**: * Must be an array of objects * Each object must have a `path` field (string) * Optional `name` (string) and `maxSteps` (number) fields 6. **Authentication**: Only `bearer` type is supported for HTTP MCP servers 7. **Tool Restrictions**: `allowedTools` and `disallowedTools` must be arrays of strings (support wildcards) 8. **OpenAI Options**: * `openai` field is only valid for OpenAI models * `reasoningEffort` must be one of: `'none'`, `'minimal'`, `'low'`, `'medium'`, `'high'`, `'xhigh'`, `'max'` * `textVerbosity` must be one of: `'low'`, `'medium'`, `'high'` * `promptCacheKey` must be a non-empty string of 64 characters or fewer * `promptCacheRetention` must be one of: `'in_memory'`, `'24h'` * No other options are allowed under `openai` ## Next Steps Learn about sub-agents Configure environment See it in action # Built-in Tools Source: https://docs.agentuse.io/reference/builtin-tools Configuration reference for Code Mode, filesystem, bash, and artifact tools AgentUse provides built-in tools for file operations, command execution, and session-linked artifacts. This reference documents their configuration options and path matching behavior. ## Reusable results Successful direct JSON and text results larger than 10KB are stored outside the model conversation. The first response contains the original `resultId`, capabilities, and the first contiguous text page in `content`. `pagination` contains `page`, `totalPages`, `pageSizeBytes`, `totalBytes`, and `hasMore`. Follow the returned `next` call unchanged; the last page has `next: null`. The model can use the read-only `results` tool with `list`, `read`, `grep`, or `jq`. Direct `read` uses numbered pages; legacy `offset`/`maxBytes` calls still return byte pages with `nextOffset`. Do not mix the two pagination modes. Small `jq` responses retain `{values, truncated}`. Oversized responses, or explicit `page`/`pageSizeBytes` requests, page the serialized `{values, truncated}` response. The query expression and optional stream `limit` stay in every continuation, using the same original result ID. Queries execute again on each page, within existing time/memory/output limits; no derived result is stored. A query's stream-limit `truncated` flag is separate from page availability and survives reconstruction. Use deterministic expressions when paging: the stored source is immutable, but time-dependent expressions such as `now` can change when the query executes again. Pages are UTF-8-safe text chunks, not necessarily valid JSON individually. Concatenate `content` before parsing. The default requested size is 16,384 bytes; JSON escaping and envelope overhead can reduce it. Actual boundaries determine `totalPages`, and `next` preserves the effective size. Result responses remain within the configured 20KB wire budget. Exceptionally small budgets or large query metadata can still fail explicitly when the envelope itself cannot fit. Structured command results also support `grep` on their searchable output text; `list` returns reference metadata only. References are immutable and scoped to one session and agent. Reading one never replays its tool or side effect. Refresh the original tool only when current external state is required or an intervening mutation may have invalidated the stored snapshot. Provider-native and binary results that use native model-output conversion stay on their direct delivery path and are not replaced with reusable handles. ## Code Mode Every normal agent run receives `code_exec` automatically. It executes a TypeScript function body in an isolated QuickJS-WASM heap so the model can use ordinary code for loops, filtering, joins, branching, batching, aggregation, and bounded parallel tool calls. ```typescript theme={"system"} const result = await tools.store_list({ status: "ready", includeData: true }); if (!result.success) throw new Error(result.error); if (!("items" in result)) throw new Error("Expected item rows"); return { highPriority: result.items .filter(item => item.data?.priority === "high") .map(item => item.id) }; ``` There is no frontmatter switch. The guest receives functions only for tools already resolved from the agent's `.agentuse` configuration. Eligible JSON tools are normally hidden from the top-level tool list and called through `code_exec`, including when the program needs only one tool call. Each nested call uses the same input object as the direct tool and passes through the runtime dispatcher, including schema validation, plugin policy, mock isolation, effect WAL, and session tracing. Before any nested tool starts, the runtime strictly type-checks the program against declarations generated from the effective tool schemas. AgentUse-owned tools can publish trusted output contracts, including the built-in store and Bash tools, so misspelled inputs, unhandled result variants, and invalid result paths fail before an effect occurs. External provider and MCP output schemas remain untrusted and appear as `-> ?`. Inspect an unknown result first, then narrow it with runtime checks before using its fields in a later program. Completed JSON-serializable nested calls use the same immutable, same-session result references, including results too large to read directly into Code Mode: ```typescript theme={"system"} const recent = await results.list(); const reference = recent[0]; if (reference.capabilities.read) { const previous = await results.read(reference.resultId); } if (reference.kind === "text") { const matches = await results.grep(reference.resultId, { pattern: "timeout", limit: 20, contextLines: 2, }); } if (reference.kind === "json") { const selected = await results.jq(reference.resultId, { expression: '.items[] | select(.status == "ready") | { id, status }', limit: 100, }); } ``` For a text page of a larger stored payload, supply byte options: ```typescript theme={"system"} const page = await results.read(reference.resultId, { offset: 0, maxBytes: 6000 }); return { content: page.content, nextOffset: page.nextOffset }; ``` Continue from `nextOffset` until it is `null`. Pages preserve UTF-8 characters and share the direct results tool's response limits. JSON pages need not parse individually. The one-argument `results.read(resultId)` still returns the original bounded value. Both forms count toward Code Mode's result-read budget. Numbered pages are also available through `results.page`: ```typescript theme={"system"} const page = await results.page({ action: "read", resultId: reference.resultId, page: 1, pageSizeBytes: 6000 }); const more = page.next ? await results.page(page.next) : null; ``` Pass the returned `next` back unchanged; it is `null` on the last page. When numbered page fields are present they take precedence over the legacy `offset` and `maxBytes` options, which are still supported. Bash returns `{ output, stdout?, stderr?, metadata? }`. Completed processes have separate `stdout` and `stderr` strings, including empty strings for empty streams. Parse `stdout` for JSON or other structured command output after checking `metadata.exitCode`, `timedOut`, `aborted`, and `truncated`. The compatible `output` field remains combined display text with stderr and runtime diagnostics; it is not a machine-readable stdout field. Refusals, startup errors, and historical stored results may lack stream fields. Refusal errors remain JSON text in `output`; there is no `value` field. Search declarations retain parameter descriptions and small integer ranges, including `context_lines` from 0 to 5 for filesystem search. Preflight reports up to eight diagnostics, bounded to 6,000 characters, with source locations, TypeScript error codes, and relevant signatures or repair hints. Annotate helper parameters, such as `function summarize(r: unknown)`, and narrow unknown values before reading their fields. A failed preflight executes no nested tools. Use these references for immediate retries and continued analysis instead of repeating the same tool call. Refresh the tool when current external state is required or an intervening mutation may have invalidated the earlier result. References never cross session or subagent boundaries and do not replay tools or side effects. `results.grep()` performs bounded, case-insensitive literal text search by default. Patterns are not regular expressions and characters such as `$` should not be escaped. `results.jq()` also accepts the legacy `results.jq(resultId, expression, { limit })` form. It uses real jq syntax and returns jq's ordered output stream as `{ values, truncated }`. AgentUse runs bundled jq 1.8.2 WebAssembly in a resource-limited worker, without a shell, host environment access, jq modules, or a machine-level jq installation. Code Mode has no direct filesystem, network, environment, process, package, shell, or import access. It can invoke only capabilities exposed through the host tool bridge. This includes Bash commands from the agent's effective auto-run allowlist; the same command validator, path policy, safe environment, plugin policy, mocks, cancellation, and effect journal apply on both paths. Commands matching `tools.bash.gated` are rejected in Code Mode and must use the direct Bash tool after human approval. Approval gates, outcome tools, internal creator tools, subagents, and any tool marked as approval-required remain direct-only. Binary media results also stay on the direct path because the guest bridge is JSON-only. Programs are bounded by source, memory, stack, computation, output, nested-call, and concurrency limits. Time awaiting Bash is governed by the Bash timeout and does not consume the guest computation timeout. The 128 nested tool-call limit applies to each `code_exec` program, including failed attempts. A later program receives a fresh allowance; continue unfinished work without repeating completed effects. Active nested calls (up to 8) and guest memory (32 MiB) remain shared across programs in the same run. The agent run retains its own execution timeout and step limits. Use Code Mode for eligible JSON tools, including a single call, and for an auto-run Bash command whose output feeds parsing, filtering, branching, batching, or another tool. Bash remains separately visible for gated commands and simple standalone process execution. Call other tools directly when they require suspension, approval, subagent delegation, binary or provider-native result delivery, or outcome submission. A transport-sensitive tool can appear on both paths: use its Code Mode form for JSON/text composition and its direct form only for the special result delivery. Code Mode does not make several store calls atomic; use `store_claim` or `store_update_if` for concurrent state transitions. ### Controlled comparison and rollback Code Mode is part of the runtime, not `.agentuse` syntax. To compare the same agent with and without deterministic tool composition, run it once normally and once with the runtime-only kill switch: ```bash theme={"system"} agentuse run agents/example.agentuse "process the ready jobs" agentuse run agents/example.agentuse "process the ready jobs" --no-code-mode ``` `--no-code-mode` applies to the whole run tree, including delegated agents. Use `AGENTUSE_CODE_MODE=0` for test harnesses or to disable Code Mode for every run launched by a serve daemon. `agentuse serve --no-code-mode` is the CLI equivalent for one daemon process. These switches are for evaluation, debugging, and emergency rollback, not permanent per-agent configuration. ## Path Matching Behavior Filesystem paths and Bash `allowedPaths` use **containment-based** path matching by default: | Pattern | Mode | Matches | | - | - | - | | `${root}` | Containment | All files under project root | | `${root}/src` | Containment | All files under src directory | | `${root}/**/*.ts` | Glob | Only `.ts` files anywhere in project | | `${root}/*.json` | Glob | Only `.json` files in root (not subdirs) | **Rule:** If the path contains glob characters (`*`, `?`, `[`), it uses glob matching. Otherwise, it uses containment (path = path/\*\*). ## Filesystem Tool Controls access for Read, Write, and Edit operations. Granting a permission exposes the matching tool to the agent: `read` → `filesystem_read`, `write` → `filesystem_write` (and `filesystem_edit`), `edit` → `filesystem_edit`. ### Configuration ```yaml theme={"system"} tools: filesystem: - path: ${root} permissions: [read] - path: ${root}/src permissions: [read, write] # write also grants edit - paths: - ${root}/docs - ${root}/tests permissions: [read] ``` ### Fields | Field | Type | Description | | - | - | - | | `path` | `string` | Single path or pattern | | `paths` | `string[]` | Multiple paths or patterns (alternative to `path`) | | `permissions` | `Permission[]` | Array of allowed operations: `read`, `write`, `edit` | ### Permission Model The capability hierarchy is `read` \< `edit` \< `write`: * **`read`**, read file contents. * **`edit`**, replace strings inside an *existing* file (cannot create new files or overwrite a file wholesale). * **`write`**, create or overwrite any file. Because this is strictly stronger than `edit`, **granting `write` also grants `edit`** (the agent gets both the write and edit tools). In practice this means `[read, write]` is all most agents need, the agent can read, do targeted edits, and do full writes. List `edit` on its own only when you want the narrower grant: modify existing files but never create or clobber them. Prefer `[read, write]` over `[read, write, edit]`, `edit` is redundant alongside `write`. Use `[read, edit]` deliberately when an agent should tweak existing files without the ability to create or overwrite them. ### Reading images and PDFs `filesystem_read` returns text files with line numbers, but it also reads **images (PNG, JPEG, GIF, WebP) and PDFs**, handing the actual image or document to the model so an agent can reason over a chart, screenshot, or scanned page directly. File type is detected by content (magic bytes), not by extension. This requires a model whose input modalities include `image`/`pdf` (Claude, GPT-4o, Gemini, and most modern models). On a text-only model, an image/PDF read returns a clear error instead of breaking the run. The same path allowlist applies as for text reads. Size caps: images up to \~5MB, PDFs up to \~32MB; `offset`/`limit` are ignored for media files. ### Path Variables | Variable | Description | | - | - | | `${root}` | Project root directory | | `${agentDir}` | Directory containing the agent file | | `${tmpDir}` | System temp directory (or custom if configured) | | `~` | User's home directory | ### Examples ```yaml theme={"system"} # Containment mode (recommended for most cases) filesystem: - path: ${root} permissions: [read, write] # read + edit + write # Restrict to specific subdirectory filesystem: - path: ${root}/src permissions: [read, write] - path: ${root}/docs permissions: [read] # Fine-grained control with glob patterns filesystem: - path: ${root}/**/*.ts permissions: [edit] # edit existing files only, no create/overwrite - path: ${root}/**/*.md permissions: [read] ``` ### Read Limits `read_file` returns up to **2000 lines** per call by default (`AGENTUSE_TOOL_MAX_LINES`); pass an explicit `limit` to read more, or an `offset` to page through a larger file. Individual lines longer than **2000 characters** (`AGENTUSE_TOOL_MAX_LINE_LENGTH`) are truncated with a `... (truncated)` suffix. See [Tool Output environment variables](/reference/environment-variables#tool-output) to tune these. ### Edit Operations The edit tool replaces exact strings rather than rewriting whole files. It uses fuzzy matching to tolerate minor whitespace, indentation, and line-ending differences. **Prefer editing over full writes on large files**, rewriting a large file regenerates its entire contents as output tokens, which is slow and can exhaust a run's time budget. A single edit replaces one string: | Parameter | Type | Description | | - | - | - | | `file_path` | `string` | Absolute path to the file | | `old_string` | `string` | Exact string to find and replace | | `new_string` | `string` | Replacement string | | `replace_all` | `boolean` | Replace all occurrences (default: `false`, first match only) | To make several changes in one call, pass an `edits` array instead of the top-level `old_string`/`new_string`: | Parameter | Type | Description | | - | - | - | | `file_path` | `string` | Absolute path to the file | | `edits` | `Edit[]` | Array of `{ old_string, new_string, replace_all? }` | Batched edits apply **sequentially** (each to the result of the previous) and are **all-or-nothing**: if any edit fails to match, the file is left unchanged. Provide either the single form or the `edits` array, not both. ## Artifact Tools Artifact tools let an agent save substantial deliverables for the user to view in the session UI without granting broad filesystem write access. ### Configuration ```yaml theme={"system"} tools: artifacts: true ``` Optional custom project-relative directory: ```yaml theme={"system"} tools: artifacts: dir: .agentuse/artifacts ``` When enabled, the agent receives: | Tool | Description | | - | - | | `artifact_save` | Save a report, plan, spec, HTML page, chart, or other deliverable under the artifact directory and link it to the current run | | `artifact_list` | List saved artifacts from the manifest, filterable by current session or group | `artifact_save` writes under `.agentuse/artifacts/` by default, records metadata in a manifest, and returns a viewable session URL when a session is active. Markdown artifacts can include `title` and `tags`, which are merged into frontmatter. To read an artifact's content later, use `filesystem_read` on the returned path. ## Metrics Tool The metrics tool lets an agent record business-metric facts (counts and amounts) about work it just completed, e.g. "chased 4 invoices totaling \$11,200". Records land in the reserved shared `metrics` store and roll up on the serve Home page and over the JSON API, so the numbers a dashboard shows are deterministic tool writes, never model-computed sums. ### Configuration ```yaml theme={"system"} tools: metrics: true ``` When enabled, the agent receives: | Tool | Description | | - | - | | `record_metric` | Record a metric fact `{ metric, value?, unit?, count?, note? }` into the shared `metrics` store | ### Fields | Field | Type | Description | | - | - | - | | `metric` | `string` | Stable snake\_case name in verb\_object form (e.g. `invoices_chased`). The grouping key: keep it identical across runs | | `value` | `number` | Numeric magnitude, e.g. total amount in whole currency units | | `unit` | `string` | Unit of `value` (e.g. `usd`, `minutes`). A metric name should always use the same unit | | `count` | `number` | Number of items handled | | `note` | `string` | Short human context shown alongside the number | At least one of `value` or `count` is required. ### Idempotency Records are upserted keyed on `(sessionId, metric)`: a retried or resumed run overwrites its own earlier record instead of double-counting, and recording the same metric twice in one run is last-write-wins. This is what makes the numbers trustworthy enough to display. Runs without a session id (rare) cannot be deduplicated and always create a new record. The runtime stamps `sessionId` and the agent id onto every record; the model cannot spoof provenance. Each record is a regular store item (`type: "metric"`, tagged with the metric name) in `.agentuse/store/metrics/`, browsable at `/stores/metrics` and readable programmatically via `GET /api/stores/metrics`. In mock mode the write is not skipped, it is isolated: the `metrics` store is re-rooted along with every other store under `.agentuse/store-mock/`, so a test run's records are inspectable there and never enter the real `metrics` store the dashboards read. See [the store guide's note on mock runs](/guides/store#what-is-the-store). ## Bash Tool Controls which shell commands can be executed and in which directories. ### Configuration ```yaml theme={"system"} tools: bash: commands: - "git *" - "npm *" - "pnpm *" gated: - "npm publish *" allowedPaths: - /tmp - ~/workspace timeout: 2m ``` ### Fields | Field | Type | Default | Description | | - | - | - | - | | `commands` | `string[]` | `[]` | Auto-run allowlist of command patterns (supports `*` wildcard). May be omitted when every allowed command comes from `gated` or trusted skills | | `gated` | `string[]` | `[]` | Command patterns that run only after human approval, enforced by a per-action lease. Also runnable (the effective allowlist is `commands` plus `gated`); a match in both is gated. Declaring `gated` implies the approval gate. See [Gated commands](/guides/approval-gates#gated-commands-mechanical-enforcement). | | `allowedPaths` | `string[]` | `[]` | Additional directories beyond project root | | `timeout` | `string` | `"2m"` | Command timeout as a duration string (`"30s"`, `"2m"`, `"500ms"`). Bare numbers are **rejected** with a corrective error: this field was historically milliseconds while every other timeout field is seconds, so a bare number is ambiguous by construction | When no config timeout is set, the model may pass a per-call `timeout`: a duration string, or a bare number meaning milliseconds (kept for model familiarity). A bare per-call number under 1000 is rejected with a corrective error (it is always a seconds-vs-milliseconds mixup; a real sub-second timeout must be written as `"500ms"`). ### Command Patterns Both `commands` and `gated` support `${root}`, `${agentDir}`, and `${tmpDir}`. These resolve from the runtime path context before matching, including approval enforcement and gated mocks. For example, `python3 ${agentDir}/check.py *` matches the resolved script path. This does not expand shell input or environment variables. `${agentDir}` requires an agent loaded from a file. Replacement paths containing whitespace or shell/wildcard metacharacters fail configuration rather than changing pattern meaning; use a project-relative command for those paths. Commands use simple wildcard matching: | Pattern | Matches | | - | - | | `git *` | Any git command (git status, git commit, etc.) | | `npm install` | Only `npm install` (exact match) | | `*` | Any command (use with caution) | ### allowedPaths Behavior The `allowedPaths` field uses **containment** - a path grants access to all files and subdirectories within it: ```yaml theme={"system"} bash: allowedPaths: - /tmp # Allows /tmp, /tmp/foo, /tmp/foo/bar, etc. - ~/workspace # Allows all of ~/workspace/** ``` Project root is always accessible for bash commands. Use `allowedPaths` for directories outside the project. ### Examples ```yaml theme={"system"} # Development setup with common tools bash: commands: - "git *" - "npm *" - "pnpm *" - "bun *" - "tsc *" - "eslint *" # CI/CD with restricted access bash: commands: - "npm test" - "npm run build" timeout: 5m # Multi-project setup bash: commands: - "git *" - "make *" allowedPaths: - ~/projects/shared-lib - /opt/tools ``` ### Output Limits The Bash tool retains at most **4MB** (`AGENTUSE_BASH_CAPTURE_BYTES`) as canonical output for reusable results. When command output exceeds that cap, AgentUse keeps a **head + tail** slice (40% head / 60% tail by default), saves the complete stream as a session artifact, and marks the result as truncated. A truncated capture never receives a reusable `resultId` because that ID must always represent complete data. Independently, any direct JSON or text result over **10KB** (`AGENTUSE_TOOL_INLINE_RESULT_BYTES`) becomes a reusable result handle before it reaches the model. This smaller limit prevents a large result from being re-sent on every subsequent model step. Queries through the `results` tool can return up to **20KB** (`AGENTUSE_RESULT_QUERY_BYTES`) inline. They never create recursive result handles. Bash stream fields use the same bounded captures as `output`. Check `metadata.truncated` before parsing them. Keeping `output` for compatibility means the serialized result also contains a combined copy of the streams, so it can reach the inline-result limit sooner. Stored results preserve the separate fields: use a query such as `.stdout | fromjson | .items` to inspect JSON stdout without including stderr diagnostics. Provider-native and binary results with native model-output conversion are excluded from this inline-result limit. Because every tool result is re-sent to the model on each subsequent step, a single large output inflates input-token usage for the rest of the run. Prefer commands that emit only what you need, for example `git diff --stat` instead of a full `git diff` over high-churn files. See [Tool Output environment variables](/reference/environment-variables#tool-output) to tune the caps. ## Sandbox Tool When a `sandbox` is configured in the agent frontmatter, the `sandbox__exec` tool is injected for running commands inside the Docker container. File I/O is handled by the filesystem tool, no separate sandbox file tools are needed. The sandbox tool is only available when `sandbox` is configured. See the [Sandbox guide](/guides/sandbox) for setup instructions. ### `sandbox__exec` Execute a shell command inside the Docker container. | Parameter | Type | Default | Description | | - | - | - | - | | `command` | `string` | Required | Shell command to execute | | `cwd` | `string` | Project root | Working directory inside the container | Returns `stdout`, `stderr`, and `exitCode`. ### Mount Mode Each filesystem path is mounted at its **real host path** with per-path mode derived from permissions: * **Read-only**, No `write` or `edit` permissions for that path * **Read-write**, `write` or `edit` permissions granted for that path Paths inside the container mirror the host (no `/workspace/` alias). Changes made by the filesystem tool on the host are visible inside the container via the bind mount. ## Run Outcome Tool The `report_outcome` tool is always available, no configuration needed. Every agent ends its run by calling it once with one of three statuses. ### `report_outcome` | Parameter | Type | Default | Description | | - | - | - | - | | `status` | `"complete" \| "idle" \| "incomplete"` | Required | How the run ended, judged against the requested objective | | `headline` | `string` | Required | One line. Complete: what the run achieved. Idle: what it checked and why nothing was due. Incomplete: the blocker and what a human must fix | | `details` | `string` | Optional | Markdown body, only when the headline cannot carry the substance | | `artifacts` | `string[]` | Required | Paths or URLs of substantive deliverables produced or changed in this run. Excludes routine bookkeeping and pre-existing outputs. `[]` for idle runs | | `rejectionOnly` | `boolean` | Optional | Incomplete only. `true` when a human rejection is the sole blocker | | `blocker` | `{ kind, subject }` | Required when `incomplete` | Why the run stopped. `kind` is one of `missing_tool`, `missing_package`, `bad_input`, `no_access`, `service_down`, `waiting_on_human`, `rejected_by_human`, `other`. `subject` is the one stuck thing as a short exact name (`birdc`, `boto3`, `quora.com`), not a sentence | What each status does: * **`complete`**: the objective was achieved. The call is the run's answer and ends the run. The session is `completed`. * **`idle`**: a successful check found no action due: nothing eligible, no alert condition met, or the intended work was already handled before this run. Routine logs, checkpoints, watermarks, audit notes, and monitoring-state updates do not turn an idle check into delivered work; exclude them from `artifacts`, which must be `[]`. A requested report, analysis, or other substantive deliverable actually produced by this run is `complete`, even when it recommends no action. An idle run ends successfully and its durable session status remains `completed`; the run JSON carries `result.idle: true`, and the sessions list exposes an Idle badge and filter separately from Done. A stretch of idle runs can help reveal changes in an agent's supply of eligible work. * **`incomplete`**: a required outcome was not delivered because something failed, including due work the agent found but could not move. The run keeps going only for bookkeeping. When it ends, the session is persisted as `error` with code `INCOMPLETE`. The blocker kind is stored in `error.cause`, with `error.subject` and `error.causeSource` (`runtime`, `approval`, `agent`, or `inferred`) saying how it was established: * A failed tool call about the same thing (`command not found`, `No module named`, `Cannot find module`) overrides the agent's chosen kind * A sub-agent's proven blocker passes to its parent * `waiting_on_human` and `rejected_by_human` show as `incomplete` in the session list, exit 0, and settle the Slack run card as "run incomplete" without a failure push * Any other blocker, or none, stays an `error`: the `failure` event fires and the exit code is 1 * `agentuse sessions show` displays the headline under the error section The runtime system prompt already teaches every agent these statuses and tells it to choose `incomplete` when unsure between idle and incomplete. Agent files should not restate this mechanic; only add domain judgment about what counts as blocked, done, or genuinely empty for that agent. Sessions recorded before `report_outcome` used two tools, `report_complete` and `report_incomplete`. They still display and reconcile the same way, and a session suspended before the change resumes with those tools. An old `report_complete` never reads as idle, since it cannot say whether the run did anything. ## Security Considerations ### Filesystem Tool * **Sensitive files blocked**: `.env`, `.env.local`, etc. are blocked by default * **Symlink resolution**: Symlinks are resolved to prevent escape attacks * **Path traversal prevention**: `../` sequences are normalized and validated ### Bash Tool * **Command allowlist**: Only explicitly allowed commands can run * **Directory restrictions**: Commands can only access project root and `allowedPaths` * **Environment sanitization**: Dangerous environment variables are cleared * **Timeout enforcement**: Commands are killed after timeout Be careful with broad command patterns like `*` or `bash *`. Prefer explicit command allowlists. # Chart Blocks Source: https://docs.agentuse.io/reference/chart-blocks Emit inline charts from agent responses with agentuse:chart fenced blocks Agents can embed small charts directly in their responses by writing a fenced code block tagged `agentuse:chart`. The serve web UI renders the block as an inline SVG chart in the session log; every other surface (CLI, plain text, push) sees the raw JSON block, so sessions stay portable and greppable. The block carries **data, not presentation**. Layout, colors, and theming are owned by the renderer, so old sessions keep improving as the renderer does. ## Format ````markdown theme={"system"} ```agentuse:chart { "type": "bar", "title": "New subscribers by day", "categories": ["Jul 7", "Jul 8", "Jul 9", "Jul 10", "Jul 11"], "series": [ { "name": "Trials", "values": [12, 18, 9, 22, 17] }, { "name": "Paid", "values": [3, 5, 2, 7, 6] } ] } ``` ```` ## Fields | Field | Type | Required | Notes | | - | - | - | - | | `type` | `"bar"` \| `"line"` | yes | Grouped bars, or one line per series | | `title` | string | no | Names the chart; shown as the figure caption. Always set it, without one the legend is the only label | | `categories` | string\[] | yes | Ordinal x-axis values, max 60 | | `series` | `{ name, values }[]` | yes | 1 to 6 series; each `values` array must match `categories` in length; numbers only. `data` is accepted as an alias for `values`, but emit `values` | | `yLabel` | string | no | Y-axis label shown beside the title | | `unit` | string | no | e.g. `"%"`, `"ms"`; shown in the caption, tooltips, and the data table | ## Constraints and fallback * Max 6 series and 60 categories; labels are capped at 120 characters. More series than that should be folded into an "Other" series by the agent. * Values must be finite JSON numbers. Negative values are supported (bars extend below the zero line). * Unknown fields are ignored. Anything that fails validation, including malformed JSON, renders as a plain code block instead of a chart: the content is never lost, it just isn't drawn. * Pick `bar` for magnitude comparisons and funnels, `line` for change-over-time. One chart, one y-scale: for two measures of different scale, emit two chart blocks. ## Rendering guarantees * Chart colors follow the app theme (light and dark) from a fixed, colorblind-validated palette. Series are colored by position, so keep the most important series first. * Every chart includes hover tooltips per mark, a legend when there are two or more series, and a collapsible **Data** table for accessibility and copy-paste. # CLI Commands Source: https://docs.agentuse.io/reference/cli-commands Complete reference for all AgentUse CLI commands ## agentuse run Execute an agent file. ### Syntax ```bash theme={"system"} agentuse run [prompt...] [options] ``` ### Arguments Path to agent file (.agentuse or .md extension) or HTTPS URL Optional additional prompt to append to the agent's instructions ### Options ```bash theme={"system"} -q, --quiet Suppress info messages (only show warnings/errors) -d, --debug Enable verbose debug logging --no-code-mode Disable the default code_exec tool for controlled comparison and debugging --no-tty Disable TUI output (plain logs for piping/automation) -v, --verbose Show detailed execution information --timeout Maximum execution time in seconds (default: 300) -C, --directory Run as if agentuse was started in instead of the current directory --env-file Path to custom .env file -m, --model Override the model specified in the agent file --mock Mock all tool outputs with the LLM instead of executing them (no real side effects). Requires --mock-model. --mock-model Model that generates mock tool outputs (required with --mock; pick a cheap, reachable model) --mock-approval [d] Resolve the await_human gate deterministically instead of suspending: approve (default), reject, or comment: ``` The `--quiet` and `--debug` options cannot be used together. You can also set `NO_TTY=true` to force plain logging without spinners. ### Directory and Path Resolution #### Directory Override (-C, --directory) The `-C` or `--directory` option is the starting directory for the command: ```bash theme={"system"} # Without -C: runs from current directory agentuse run agent.agentuse # With -C: starts from the specified directory agentuse run agent.agentuse -C /path/to/project-or-subdir ``` #### Project Root Detection AgentUse searches from the current directory upward for `.agentuse/`, `.git/`, or `package.json`. If none are found, the starting directory is the project root. The project root is used for: * Loading `.env` files * Finding plugins in `.agentuse/plugins/` * Owning shared stores in `.agentuse/store/` * Grouping session state For `agentuse serve`, `-C` also defines the served scope: only `.agentuse` files under that directory are exposed, while state still belongs to the detected project root. This is useful for: * Running agents from different projects * CI/CD environments with complex directory structures * Testing with different configurations #### Path Resolution Rules Subagent paths and MCP server commands are resolved relative to the **agent file's directory**. See [Agent Syntax - Subagents](/reference/agent-syntax#subagents) for complete path resolution examples. ### Model Override The `--model` option allows you to override the model specified in an agent file at runtime. This is useful for: * **Testing**: Compare agent behavior across different models * **Cost Optimization**: Use cheaper models for development/testing * **Environment-Specific Models**: Different models for dev/staging/production * **Quick Experiments**: Try new models without editing files #### Format ``` provider:model[:env] ``` Where: * `provider`: A built-in provider (`anthropic`, `openai`, `openrouter`, `opencode-go`, `bedrock`) or a custom provider name * `model`: The specific model name (e.g., `claude-sonnet-4-6`, `gpt-5.5`, `glm-5-flash:q4_K_M`), or a [version alias](/reference/models#version-aliases) such as `claude-sonnet` * `env`: Optional environment suffix for API keys (e.g., `dev`, `prod`, or full env var name), built-in providers only A configured `@name` alias also works: `--model @fast`. #### Examples ```bash theme={"system"} # Override with OpenAI GPT-5 agentuse run agent.agentuse --model openai:gpt-5.6 agentuse run agent.agentuse --model opencode-go:kimi-k2.7-code # Use Anthropic Claude Haiku for quick testing agentuse run agent.agentuse -m anthropic:claude-haiku-4-5 # Track the newest model in a line, or use a configured alias agentuse run agent.agentuse -m anthropic:claude-sonnet agentuse run agent.agentuse -m @fast # Use different API key via environment suffix agentuse run agent.agentuse --model openai:gpt-5.6:dev agentuse run agent.agentuse --model opencode-go:kimi-k2.7-code:dev # This will use OPENAI_API_KEY_DEV instead of OPENAI_API_KEY # Use specific environment variable agentuse run agent.agentuse --model anthropic:claude-sonnet-5:ANTHROPIC_API_KEY_PERSONAL ``` When overriding models, provider-specific options (like OpenAI's `reasoningEffort`) will be ignored if you switch to a different provider. An explicit model override propagates to every nested sub-agent. Without `--model`, each agent uses the model declared in its own file; a parent's configured model is not inherited. Alias fallback candidates and cooldowns propagate as one resolved policy and remain stable across session resume. ## agentuse test Choose what you want to check: | Command | Description | | - | - | | `agentuse test workflow [prompt...]` | Check the agent's steps and approval branches using simulated tool responses. | | `agentuse test result --session ` | Generate from a past job's evidence and compare the new result with the original. | ### Workflow options ```text theme={"system"} --scope all|gated Default: all. Gated simulates only gated bash; other tools run live. --approval approve (default), reject, or comment: --mock-model Model fabricating responses; or set AGENTUSE_MOCK_MODEL --no-code-mode Disable code_exec for comparison ``` ### Result options ```text theme={"system"} --session Required real source session; finished or awaiting approval --selector-model Evidence selector on first use; defaults to the agent model --judge Optional local agent defining quality criteria, run without tools ``` Result tests reuse the first validated evidence selection for the source session. They load current instructions and explicit read-only reference files. They do not execute workflow tools or expose the old draft to the writer or judge. Without a judge, `generated` means comparison available, not quality passed. With a judge, `passed` means the new result meets its criteria, not proof of improvement. `failed`, `incomplete`, and `error` return exit code 1; `generated` and `passed` return 0. Reports include the evidence path and reference hashes. Both modes accept `--quiet`, `--debug`, `--no-tty`, `--compact`, `--timeout`, `-C`, `--env-file`, `--model`, and `--json`. Put options after the mode. ```bash theme={"system"} agentuse test workflow reply.agentuse --approval reject agentuse test result reply.agentuse --session agentuse test result reply.agentuse --session --judge quality.agentuse --json ``` Compatibility: `test [prompt...]` retains adaptive mocking, and `test --replay ` retains strict recorded-call replay. Use `./workflow` or `./result` to refer to files whose names collide with the new subcommands. See [Testing agents](/guides/testing-agents) for evidence selection, isolation, limitations, approval simulation, and the complete workflow. ### Full mock (`--scope all`, or `run --mock`) Full-scope mock answers **every** tool call with an LLM-generated result instead of executing it. The agent runs for real; only tool execution is faked. The same mode is available as low-level plumbing on `run`: ```bash theme={"system"} agentuse run agent.agentuse --mock --mock-model anthropic:claude-haiku-4-5 ``` **Use the lowest-end model you can reach for `--mock-model`.** Mocking is not a reasoning task: the model only has to fabricate a plausible result for a tool given its name and arguments. Your agent's *actual* reasoning still runs on its own model, untouched. A small, fast model produces fine mock output while keeping cost and rate-limit pressure low, which matters because mock fires one LLM call for **every** tool result (and they run concurrently when the agent batches tool calls). Good low-end picks, by provider: | Provider | Suggested `--mock-model` | | - | - | | `anthropic` | `anthropic:claude-haiku-4-5` | | `openai` | `openai:gpt-5.4-nano` | | `openrouter` | `openrouter:deepseek/deepseek-v4-flash` | Pick one in a provider you're authenticated for. (Model IDs drift over time; the current low-end tier is the rule, not these exact names.) * **A mock model is required.** Mock fires an LLM call for *every* tool result, so it must run on a model you can reach. It is deliberately **not** defaulted to the agent's own model: that ran mock onto the agent's premium, rate-limited token and produced opaque `429`s. Provide it per run with `--mock-model`, or set a global default once via `AGENTUSE_MOCK_MODEL` in the shell, `~/.agentuse/.env`, or the [`env` block of `~/.agentuse/config.json`](/reference/configuration-files#global-env-defaults). The flag wins over all of them. * **Sub-agents run for real**; their leaf tools are mocked. * **The approval gate stays real under `run --mock`**: `await_human` still suspends so you can verify the agent pauses for approval. Pass `--mock-approval` for fully-unattended runs (`agentuse test` defaults to this): the gate resolves **deterministically** (no LLM plays the reviewer) instead of suspending. * `--mock-approval` (or `--mock-approval approve`) auto-approves. The approval grants the [gated-command lease](/guides/approval-gates) derived from the gate's `changes[]` exactly like a real reviewer approval, so `tools.bash.gated` flows complete end-to-end. On a pick gate the recommended option is chosen (else the first), returned as `choice`. * `--mock-approval reject` forces the reject branch: the gate seals (terminal for the run) so you can test the agent's cleanup path. * `--mock-approval comment:` forces the revise-and-re-gate branch with `` as the reviewer comment. The comment applies to the **first** gate only; the re-gate that follows is approved, so the run exercises the revision path and still finishes. (Repeating the comment on every gate would loop an obedient agent until it gave up.) MCP servers still connect at startup for tool discovery, but no tool executes (no mutations). Mock outputs are non-deterministic; mocked approval decisions are deterministic. ### Remote Agent Security When running agents from remote URLs: 1. **HTTPS Only**: Only HTTPS URLs are allowed for security 2. **File Extension**: Remote agents must have `.agentuse` extension 3. **Interactive Confirmation**: AgentUse will show a security warning with options: * `[p]review` - Fetch and display the agent content before running * `[y]es` - Execute the agent directly * `[N]o` - Abort execution (default) Example security prompt: ``` ⚠️ WARNING: You are about to execute an agent from: https://example.com/agent.agentuse Only continue if you trust the source and have audited the agent. [p]review / [y]es / [N]o: ``` ### Examples ```bash theme={"system"} # Run agent from current directory agentuse run hello.agentuse # Run agent from subdirectory cd agents/subfolder agentuse run my-agent.agentuse # Finds .env and plugins at project root # Change to different directory first with -C agentuse run agent.agentuse -C /my/project # Same as: cd /my/project && agentuse run agent.agentuse # Run agent from a different project agentuse run newsletter/writer.agentuse -C ~/projects/content # Use custom environment file agentuse run agent.agentuse --env-file .env.production # Run with additional prompt agentuse run assistant.agentuse "Help me write an email" # Run with multi-word prompt agentuse run code-review.agentuse "focus on security and performance issues" # Run remote agent (requires HTTPS and .agentuse extension) # Shows security warning and requires confirmation agentuse run https://example.com/agent.agentuse # Run remote agent with additional prompt agentuse run https://example.com/agent.agentuse "use production settings" # Run with debug output agentuse run agent.agentuse --debug # Run with additional prompt and verbose output agentuse run agent.agentuse "be thorough" --verbose # Run with custom timeout agentuse run agent.agentuse --timeout 600 # Run quietly (only warnings/errors) agentuse run agent.agentuse --quiet # Disable TUI output for piping/automation agentuse run agent.agentuse --no-tty # Override model at runtime agentuse run agent.agentuse --model openai:gpt-5.4-mini # Override model and add prompt agentuse run agent.agentuse "be concise" --model anthropic:claude-haiku-4-5 # Use development API key with model override agentuse run agent.agentuse -m openai:gpt-5.6:dev # Override model for agent with sub-agents (all will use the same model) agentuse run orchestrator.agentuse --model openai:gpt-5.4-mini ``` ### Replay a recorded session ```bash theme={"system"} agentuse test --replay [--json] [--model ] ``` Generate with current instructions and recorded tool results. Stops at the first proposal before automated review, final output, or an unmatched call. Never executes live tool operations or fabricates missing results. See [Replay recorded inputs](/guides/replay) for matching and reference-file behavior. ## agentuse sessions View and resume AgentUse sessions. ### Syntax ```bash theme={"system"} agentuse sessions list [options] agentuse sessions show [options] agentuse sessions resume [options] agentuse sessions reconcile [options] agentuse sessions backfill-blockers [options] agentuse sessions path [options] ``` `agentuse sessions` is a shortcut for `agentuse sessions list`. Session data is stored globally and partitioned by project. CLI session commands default to the current project; use `--all` or `--all-search` when you are not sure which project owns a session. ### List Sessions ```bash theme={"system"} agentuse sessions list agentuse sessions list --all agentuse sessions list --project ../other-project ``` List options: ```bash theme={"system"} -s, --subagents Include subagent sessions -n, --limit Limit number of sessions to show -j, --json Output as JSON --no-mock Hide mock/test runs (listed by default, marked "· mock") --all Show sessions across all projects --project [path] Show sessions for a project path; defaults to current project ``` ### Show a Session ```bash theme={"system"} agentuse sessions show 01K... agentuse sessions show 01K... --all-search agentuse sessions show 01K... --project ../other-project ``` Show options: ```bash theme={"system"} -j, --json Output as JSON -f, --full Show full tool input/output --project [path] Search a project path; defaults to current project --all-search Search all projects if not found in the selected project ``` ### Resume a Session Use `agentuse sessions resume` for local continuation. It supports suspended approval sessions and ended sessions. For a suspended approval session: ```bash theme={"system"} agentuse sessions resume 01K... --approve agentuse sessions resume 01K... --approve "Looks good" agentuse sessions resume 01K... --approve --choice candidate-2 agentuse sessions resume 01K... --reject "Not ready" agentuse sessions resume 01K... --comment "Please revise the CTA" agentuse sessions resume 01K... --comment "Keep intros factual, not salesy" --remember agentuse sessions resume 01K... --comment "Please revise with citations" --remember "Always include source links before publishing." ``` The CLI uses local session access as the trust boundary, so approval resumes do not require a resume token. The decision rules are the same as on the approval page: a pick gate (one with `options`) needs `--choice ` naming the option to approve, `--choice` only goes with `--approve`, and a draft that strict automated review sent back for revision guidance can be commented on or rejected but not approved. `--remember` saves the comment as a future instruction, and requires `--comment` (a non-empty one). Bare `--remember` reuses the comment text; passing a value (`--remember "..."`) overrides it. Passing `--remember` is itself the opt-in, so saving needs no `learning` config on the agent. The comment is still the feedback for this revision; the instruction is distilled from it, stored as `src:manual`, and injected into future runs once the agent has `learning.apply` enabled. It is also vetted against the agent's own instructions: a note that contradicts them is still saved, but quarantined with the conflict named rather than injected. For a suspended non-approval `await_*` tool (approval gates refuse `--tool-result`; use the decision flags above): ```bash theme={"system"} agentuse sessions resume 01K... --tool-result '{"status":"done"}' ``` For a completed or errored session, AgentUse starts a new run from the original agent file with continuation context: ```bash theme={"system"} agentuse sessions resume 01K... --prompt "Continue from here and add tests" ``` Resume options: ```bash theme={"system"} -C, --directory Run as if agentuse was started in --project [path] Search a project path; defaults to current project --all-search Search all projects if not found in the selected project -d, --debug Enable debug logging for resume ``` ### Reconcile Stuck Sessions Settle sessions still marked `running` whose owning process is gone. This is the same owner-liveness check `agentuse serve` performs at startup, but it sweeps as far back as you ask instead of the daemon's 30-day window. ```bash theme={"system"} agentuse sessions reconcile [options] ``` Reconcile options: ```bash theme={"system"} --lookback How far back to scan: a day count, or "all" (default: all) --dry-run Report what would be settled without writing -j, --json Output as JSON --all Reconcile across all projects --project [path] Reconcile a project path; defaults to current project ``` A run that is still executing anywhere is never touched: a live worker, a worker released across a daemon restart, or a plain terminal `agentuse run` all keep their session as-is, because the session records its owning process and reconcile checks that the process is actually alive. A 10-minute recency window backs that up, so a session written to very recently is left alone even if it comes from a build that predates owner tracking. Sessions suspended on a subagent that died are settled the same way, so a manager waiting on a child that will never report back stops sitting in limbo. Why this exists: runs orphaned before serve's 30-day startup window stayed `running` forever, inflating the dashboard's needs-attention counts with work that ended long ago. ```bash theme={"system"} # See what is stuck without changing anything agentuse sessions reconcile --dry-run # Settle everything in this project, however old agentuse sessions reconcile # Sweep the last week across every project, as JSON agentuse sessions reconcile --all --lookback 7 --json ``` ### Backfill Blockers Give older `INCOMPLETE` runs a blocker so they group with new ones, and dismiss failures too old to act on. It only adds fields: status and messages are never rewritten. ```bash theme={"system"} agentuse sessions backfill-blockers [options] ``` Backfill options: ```bash theme={"system"} --days Backfill failures last touched within this many days; dismiss older ones (default: 14) --dry-run Report what would change without writing -j, --json Output as JSON --all Sweep every project --project [path] Sweep a project path; defaults to current project ``` ### Show Storage Path ```bash theme={"system"} agentuse sessions path agentuse sessions path --project ../other-project ``` ## agentuse serve Start the AgentUse HTTP daemon to run agents via API. This enables integration with external applications, webhooks, approvals, Slack notifications, or any system that can make HTTP requests. ### Syntax ```bash theme={"system"} agentuse serve [options] ``` ### Options ```bash theme={"system"} -p, --port Port to listen on (default: 12233) -H, --host Host to bind to (default: 127.0.0.1) -C, --directory Directory to serve agents from; project state is detected upward --default Default project for POST /api/run when `project` is omitted -d, --debug Enable debug mode --no-code-mode Disable the default code_exec tool for every run launched by this daemon --public-url Externally reachable base URL used in approval links (or config serve.publicUrl) --no-auth Disable API key requirement for exposed hosts (dangerous) --no-log-file Disable writing serve logs to a file --open Open the Web UI in the default browser after startup --hide-agent-source Hide raw agent source in the dashboard and /api/agents/detail ``` ### Serving Multiple Projects AgentUse runs one serve daemon at a time. Repeat `-C` on that daemon to serve multiple scopes/projects: ```bash theme={"system"} agentuse serve -C ./projA -C ./projB ``` Project ids default to the `-C` directory basename. Duplicate ids fail startup. Each scope detects its project root independently, and each project loads its own `.env` / `.env.local` in its worker process. Use the request `project` field to choose a project. In multi-project mode, omitting it returns `400 PROJECT_REQUIRED` unless `--default ` is set. Starting a second daemon fails with the PID, address, projects, and log path of the daemon that is already running. This keeps approval links, Slack replies, session resumes, and API traffic routed through one owner. ### Global Config You can put serve defaults in `~/.agentuse/config.json`. See [Configuration Files](/reference/configuration-files#global-serve-config) for the schema and CLI override behavior. ### Authentication When binding to exposed hosts (not `127.0.0.1` or `localhost`), API key authentication is required: ```bash theme={"system"} # Set API key for authentication export AGENTUSE_API_KEY="your-secret-key" # Start server on all interfaces agentuse serve --host 0.0.0.0 ``` Clients must include the key in requests: ```bash theme={"system"} curl -X POST http://server:12233/api/run \ -H "Authorization: Bearer your-secret-key" \ -H "Content-Type: application/json" \ -d '{"agent": "my-agent.agentuse"}' ``` Use `--no-auth` to bypass authentication (dangerous for production). ### API Endpoints All JSON endpoints are served under the `/api/*` prefix; the un-prefixed root paths (`/`, `/agents`, `/sessions`, `/schedules`, `/stores`, `/approvals`) serve HTML dashboard pages. `GET /` is the dashboard home: it links to those pages and lists the served projects with their agent and schedule counts. The per-session page `/sessions/:id` and its action subroutes (`/decision`, `/continue`, `/status`) carry their own capability auth (session token / API key / local). `POST /run`, `POST /resume/:id`, and the `POST /approvals/:id/...` action endpoints remain reachable at their original paths for backward compatibility, and `GET /approvals/:id` redirects to `/sessions/:id` (prefer the `/api/*` and `/sessions` paths; the legacy aliases will be removed later). #### GET /api Returns version, default project, and served projects. (`GET /` serves the HTML dashboard built from the same data.) ```json theme={"system"} { "version": "0.12.0", "update": { "currentVersion": "0.12.0", "latestVersion": "0.18.0", "packageManager": "npm", "command": "npm install -g agentuse@latest" }, "default": "projA", "projects": [ { "id": "projA", "path": "/abs/path/to/projA", "agentCount": 3, "scheduleCount": 1 }, { "id": "projB", "path": "/abs/path/to/projB", "agentCount": 2, "scheduleCount": 0 } ] } ``` `update` is present only when the cached npm registry result contains a newer AgentUse version from npm's `latest` dist-tag. The dashboard uses it for its dismissible update banner. `default` is `null` in multi-project mode without `--default`; single-project mode returns the sole project id. #### POST /api/run Execute an agent and receive the result. (Legacy alias: `POST /run`.) **Request Body:** ```json theme={"system"} { "agent": "path/to/agent.agentuse", "project": "projA", "prompt": "Optional additional prompt", "model": "anthropic:claude-sonnet-5", "timeout": 300, "maxSteps": 100 } ``` | Field | Type | Required | Description | | - | - | - | - | | `agent` | string | Yes | Path to agent file (relative to that project's root) | | `project` | string | Conditional | Required in multi-project mode unless `--default` is set | | `prompt` | string | No | Additional prompt to append to agent instructions | | `model` | string | No | Override the model specified in agent file | | `timeout` | number | No | Maximum execution time in seconds (default: 300) | | `maxSteps` | number | No | Maximum number of tool call steps | **Response (JSON):** ```json theme={"system"} { "success": true, "result": { "text": "Agent response text", "finishReason": "end-turn", "duration": 1234, "tokens": { "input": 500, "output": 200 }, "toolCalls": 3 } } ``` **Error Response:** ```json theme={"system"} { "success": false, "error": { "code": "AGENT_NOT_FOUND", "message": "Agent file not found: my-agent.agentuse" } } ``` #### GET /api/agents Lists the agents loaded by the daemon as JSON. `path` is relative to the project root, exactly as accepted by `POST /api/run`. Agents that fail to parse are reported in `errors` rather than failing the request. The browsable HTML page is at `/agents`. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/agents" ``` ```json theme={"system"} { "success": true, "agents": [ { "projectId": "projA", "path": "daily.agentuse", "name": "Daily Digest", "description": "Posts a daily digest", "model": "anthropic:claude-sonnet-5", "schedule": "0 9 * * *" } ], "errors": [] } ``` `description` and `schedule` are present only when the agent declares them. #### GET /api/agents/detail Returns the capability summary and raw `.agentuse` source for one loaded agent. The endpoint is operator-gated like the rest of `/api/*`, and `path` must match an agent already loaded by the project. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/agents/detail?project=projA&path=daily.agentuse" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` The browsable agent detail hub is at `/agents//`. #### GET /api/schedules Lists the scheduled agents currently registered with the running daemon as JSON, sorted by next run (soonest first, disabled last). The browsable HTML page is at `/schedules`. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/schedules" ``` ```json theme={"system"} { "success": true, "schedules": [ { "id": "3252d076-d203-4921-b1c4-013d8748406b", "projectId": "projA", "agentPath": "daily.agentuse", "expression": "0 9 * * *", "human": "Daily 9am", "timezone": "America/Vancouver", "enabled": true, "jitterMs": 78721, "nextRun": "2026-06-03T16:00:00.000Z", "lastRun": null, "createdAt": "2026-06-02T21:00:42.371Z" } ] } ``` `nextRun` and `lastRun` are ISO timestamps (or `null`). `lastResult` is included once a scheduled run has completed, and carries the run's `sessionId` so the dashboard can deep-link to its log. #### GET /api/sessions Lists top-level runs as JSON, live first and then by most recent activity. Filters: `?agent=`, `?trigger=scheduled|manual|slack|api`, and `?window=<1h|6h|24h|7d|30d|90d|all>` (default `24h`). Time windows use the last update, so a recently completed long-running session remains visible. The browsable HTML page is at `/sessions`. `?status=incomplete` matches only runs blocked on a person; incomplete runs with any other blocker are listed under `error`. Use `?status=idle` for successful checks with no action due, or `?status=completed` for Done runs excluding idle. Idle rows retain the durable `status: "completed"` and carry `outcome: "idle"`; the list's `counts.idle` and `counts.done` are separate. Older recorded idle outcomes are recovered from the structured tool call. Runs that reported complete are not reclassified from their output text. ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions?agent=daily&trigger=scheduled" \ -H "Authorization: Bearer $AGENTUSE_API_KEY" ``` ```json theme={"system"} { "success": true, "sessions": [ { "project": "projA", "sessionId": "01JFN8K3M2P1", "agent": { "id": "daily", "name": "Daily Digest", "description": "Posts a daily digest" }, "status": "completed", "trigger": "scheduled", "createdAt": 1717430400000, "updatedAt": 1717430412000 } ], "window": { "value": "24h", "hours": 24, "updatedAfter": 1717344000000 }, "errors": [] } ``` `trigger` is `scheduled`, `api`, `slack`, or `manual` (CLI runs and the default). For large histories, opt into cursor pagination with `limit` (maximum 100) and the opaque `nextCursor` returned by the prior response: ```bash theme={"system"} curl "http://127.0.0.1:12233/api/sessions?limit=50" ``` Supplying `limit` changes only the list length and adds `limit` and (when more records exist) `nextCursor`; requests without it retain the complete legacy response. Cursors are bound to the active filters and should be treated as opaque. #### GET /api/sessions/:id Returns one session including its run-log entries (`logs`). API-key gated. The human-facing view + approve page is `/sessions/:id`; see [Approval Gates](/guides/approval-gates#experimental-session--approval-api). | Error Code | HTTP Status | Description | | - | - | - | | `NOT_FOUND` | 404 | Endpoint not found (use `POST /api/run` or `GET /api`) | | `AGENT_NOT_FOUND` | 404 | Agent file doesn't exist | | `PROJECT_NOT_FOUND` | 404 | Unknown project id in multi-project mode | | `PROJECT_REQUIRED` | 400 | Multi-project request without `project` or `--default` | | `INVALID_PATH` | 400 | Agent path outside project root | | `INVALID_REQUEST` | 400 | Invalid JSON body | | `MISSING_FIELD` | 400 | Required field missing | | `TIMEOUT` | 504 | Agent execution timed out | | `EXECUTION_ERROR` | 500 | Runtime error during execution | | `INTERNAL_ERROR` | 500 | Unexpected server error | ### Streaming Response For real-time output, request NDJSON streaming by setting the `Accept` header: ```bash theme={"system"} curl -N -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -H "Accept: application/x-ndjson" \ -d '{"agent": "my-agent.agentuse"}' ``` Each line is a JSON object representing an execution event: ```json theme={"system"} {"type": "text", "text": "Analyzing..."} {"type": "tool-call", "name": "read_file", "args": {"path": "data.txt"}} {"type": "tool-result", "name": "read_file", "result": "..."} {"type": "text", "text": "Complete!"} {"type": "finish", "finishReason": "end-turn", "duration": 2345} ``` ### Examples ```bash theme={"system"} # Start server with defaults (127.0.0.1:12233) agentuse serve # Start on custom port agentuse serve --port 8080 # Bind to all interfaces (for external access) agentuse serve --host 0.0.0.0 --port 3000 # Set the public URL used in approval review links agentuse serve --public-url https://agentuse.mycompany.com # Provide Slack credentials for agents that enable Slack channels SLACK_BOT_TOKEN=xoxb-... SLACK_APPROVAL_CHANNEL=C0123456789 agentuse serve # Serve agents from a project or subdirectory agentuse serve -C /path/to/project-or-subdir # Host multiple projects from one process agentuse serve -C ./projA -C ./projB # Default POST /api/run to projA when `project` is omitted agentuse serve -C ./projA -C ./projB --default projA # Start with debug logging agentuse serve --debug ``` **API Usage Examples:** ```bash theme={"system"} # Run an agent (JSON response) curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "agents/assistant.agentuse"}' # Run with additional prompt curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "agents/writer.agentuse", "prompt": "Write about AI"}' # Override model curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"agent": "agents/helper.agentuse", "model": "openai:gpt-5.4-mini"}' # Streaming response curl -N -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -H "Accept: application/x-ndjson" \ -d '{"agent": "agents/analyzer.agentuse"}' # Multi-project: pick which project runs the agent curl -X POST http://127.0.0.1:12233/api/run \ -H "Content-Type: application/json" \ -d '{"project": "projA", "agent": "assistant.agentuse"}' # Discovery: list served projects curl http://127.0.0.1:12233/ ``` ### Scheduled Agents Agents with a `schedule` config in their frontmatter are automatically executed on schedule: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 schedule: "1h" --- ``` See the complete guide for intervals and cron expressions. The server enables CORS by default. For production, run behind a reverse proxy with authentication. ### serve ps Show the running `agentuse serve` daemon. ```bash theme={"system"} agentuse serve ps [--json] ``` Shows PID, port, every served project, total agent/schedule counts, and uptime. Multi-project daemons render one project per row under the same daemon. ``` PID PORT PROJECTS AGENTS SCHEDULES UPTIME ──────────────────────────────────────────────────────────────────────────── 63398 12233 projA 12 3 2h 15m projB projC ``` Use `--json` for scripting. Stale entries are automatically cleaned up. While `serve ps` shows counts across daemons, use `serve agents` and `serve schedules` to inspect what a single running daemon actually loaded. ### serve agents List the agents loaded by the running daemon (queries its live `GET /api/agents` endpoint). ```bash theme={"system"} agentuse serve agents [pid] [--json] ``` ``` AGENT NAME MODEL SCHEDULE ──────────────────────────────────────────────────────────────────── adhoc.agentuse Adhoc Helper anthropic:claude-haiku-4-5 — daily.agentuse Daily Digest anthropic:claude-sonnet-5 0 9 * * * ``` Omit `pid` when only one daemon is running. Agents that failed to parse are listed after the table. Use `--json` for the raw payload. When the daemon requires an API key, set `AGENTUSE_API_KEY` so the command can authenticate. ### serve schedules List the scheduled agents in the running daemon (queries its live `GET /api/schedules` endpoint), sorted by next run. ```bash theme={"system"} agentuse serve schedules [pid] [--json] ``` ``` NEXT RUN AGENT SCHEDULE LAST RUN ────────────────────────────────────────────────── Jun 03, 09:00 daily.agentuse Daily 9am never ``` *** ## agentuse schedules Inspect and control deployment-local schedule state without changing agent frontmatter. ```bash theme={"system"} agentuse schedules agentuse schedules pause agentuse schedules resume ``` `agentuse schedules` lists declared schedules and whether each one is active or paused. `pause` and `resume` persist the override for the current deployment and notify a running daemon, when present. The declared cron expression or interval stays in the agent file and remains visible in the dashboard. *** ## agentuse models List the recommended models, the aliases they can be reached by, and your configured default. ```bash theme={"system"} agentuse models # recommended lineup + aliases agentuse models anthropic # one provider agentuse models --all # every model in the registry agentuse models --verbose # context limits, capabilities, alias per model ``` The **Version aliases** section shows what each version-less id (`anthropic:claude-sonnet`) resolves to right now. **Your aliases** and **Default model** appear when a `models` block is configured (see [Configuration Files](/reference/configuration-files#model-defaults-and-aliases)). ### models unpin Replace pinned model versions in agent files with version aliases, so those files track the newest release and stop needing edits: ```bash theme={"system"} agentuse models unpin --dry-run # preview, current directory agentuse models unpin ./agents # apply to a directory agentuse models unpin one.agentuse # apply to a single file ``` ``` agents/researcher.agentuse anthropic:claude-sonnet-5 → anthropic:claude-sonnet (currently anthropic:claude-sonnet-5) ``` ### models bump Move superseded pins forward to the current model of the same product line, for files you want to keep pinned: ```bash theme={"system"} agentuse models bump --dry-run agentuse models bump ./agents ``` Both commands only rewrite model references inside an agent file's YAML frontmatter. Instructions below the frontmatter are left alone, since prose may legitimately name a specific model version. Version aliases are never rewritten by `bump`: they already track the line. *** ## agentuse plugins Install and manage trusted AgentUse packages from Git repositories. ```bash theme={"system"} agentuse plugins install owner/repository agentuse plugins install git:github.com/owner/repository@v1 agentuse plugins list [--json] [--all-scopes] agentuse plugins update [name] agentuse plugins remove agentuse plugins uninstall # alias ``` Add `-l` to any subcommand to use project-local package settings. `install` accepts `owner/repo`, `github:owner/repo`, `git:github.com/owner/repo@ref`, HTTPS or SSH GitHub URLs, and local directory paths (linked in place rather than cloned). `update` without a name updates every plugin in the selected scope, and reports "already up to date" for a pinned source or unchanged linked package. The shorter `agentuse install|update|list|remove` commands remain as compatibility aliases. *** ## agentuse provider Manage providers and authentication credentials. (`auth` still works as a hidden alias.) ### provider login ```bash theme={"system"} agentuse provider login [provider] # built-ins plus installed provider plugins agentuse provider login opencode-go ``` Amazon Bedrock authenticates via standard AWS environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, optional `AWS_SESSION_TOKEN`) or `AWS_BEARER_TOKEN_BEDROCK`. There is no `provider login bedrock` command. ### provider add Add a custom OpenAI-compatible endpoint from the CLI (Ollama, LM Studio, vLLM, etc.). The dashboard can additionally configure OpenAI Responses and Anthropic Messages endpoints; see [Model Configuration](/guides/model-configuration#custom-providers). ```bash theme={"system"} agentuse provider add ollama --url http://localhost:11434/v1 agentuse provider add lmstudio --url http://localhost:1234/v1 agentuse provider add myserver --url https://gpu.example.com/v1 --key sk-mykey ``` Then use: `agentuse run agent.agentuse -m ollama:glm-5-flash:q4_K_M` The command prints `URL`, `API`, `Key`, and `Models` lines. Each URL and key is labelled `stored` or `from _BASE_URL` / `from _API_KEY` when an environment variable overrides it. Colons in model names are supported, `ollama:qwen3.5:0.8b` parses as provider `ollama`, model `qwen3.5:0.8b`. ### provider remove / logout ```bash theme={"system"} agentuse provider remove ollama # remove custom provider agentuse provider logout openai # remove built-in credentials ``` ### provider list ```bash theme={"system"} agentuse provider list agentuse provider list --json # machine-readable status; never includes secrets ``` ## agentuse mcp Manage logins for the HTTP MCP servers an agent uses. See [OAuth MCP Servers](/reference/agent-syntax#oauth-mcp-servers) for the agent-file side. ```bash theme={"system"} agentuse mcp login # Log in; every agent using the same server URL shares it agentuse mcp login --no-browser # Print the login URL instead of opening a browser agentuse mcp status # Show how each of the agent's MCP servers signs in agentuse mcp logout # Forget the saved login ``` `` is the agent file and `` is the server's name under `mcpServers`. *** ## agentuse skills List and retrieve AgentUse builtin skills that ship with the installed CLI version. Use the `installed` subcommand to inspect project and user-installed skills. ### Syntax ```bash theme={"system"} agentuse skills [subcommand] [options] ``` ### Subcommands ```bash theme={"system"} agentuse skills # List AgentUse builtin skills agentuse skills list # Explicit builtin list command agentuse skills get # Output builtin skill content agentuse skills get --full agentuse skills get --all # Output every builtin skill agentuse skills path [name] # Print builtin skill paths agentuse skills installed # List installed/discovered skills agentuse skills installed get agentuse skills installed path [name] ``` ### Options ```bash theme={"system"} -v, --verbose Show skill file paths and tool requirements when listing -j, --json Output machine-readable JSON --full Include supporting files when using get --all Output every skill for the selected source when using get ``` ### Builtin Skills Builtin skills are stored in the AgentUse package `skill-data/` directory and match the installed CLI version. This mirrors the `agent-browser skills` model: agents can fetch current official instructions without reading a user's entire local skill library. | Skill | Covers | | - | - | | `core` | The entry point: what AgentUse is, and which of the three below to fetch next | | `runner` | Running agents, listing them, sessions, `serve`, schedules | | `creator` | Authoring, improving, and reviewing `.agentuse` files | | `tester` | Validating agents without real side effects: choosing a mock model and scope, exercising approval gates unattended, the edit-run-inspect loop, and the fidelity caveats of mock output | ### AI Coding Assistants Install the assistant-facing AgentUse skill stub: ```bash theme={"system"} npx skills add agentuse/agentuse ``` For local development, install from this checkout: ```bash theme={"system"} npx skills add . ``` This installs the thin `agentuse` skill from `skills/agentuse/SKILL.md`. The stub points assistants at `agentuse skills get core`, so the real workflow guidance stays version-aligned with the installed AgentUse CLI. ### Installed Skill Locations Installed skills are discovered from these directories (in priority order): 1. `.agentuse/skills/` - Project-specific skills 2. `$AGENTUSE_CONFIG_DIR/skills/` - User-global skills (defaults to `~/.agentuse/skills/`) 3. `.claude/skills/` - Claude ecosystem compatibility 4. `~/.claude/skills/` - Claude ecosystem compatibility 5. `~/.agents/skills/` - Shared agent skills compatibility Symlinked skill directories and `SKILL.md` files are supported. AgentUse skips dangling links, resolves directory real paths, and avoids circular traversal. ### Examples ```bash theme={"system"} # List AgentUse builtin skills agentuse skills agentuse skills list # Show verbose output with file paths and tool requirements agentuse skills -v agentuse skills --verbose # Return machine-readable metadata agentuse skills --json agentuse skills list --json # Print builtin skill content for an agent or script agentuse skills get core agentuse skills get runner agentuse skills get creator agentuse skills get tester agentuse skills get core --full agentuse skills get --all --json # Print builtin paths agentuse skills path agentuse skills path core # Inspect project and user-installed skills agentuse skills installed agentuse skills installed list --json agentuse skills installed get code-review agentuse skills installed get code-review --full agentuse skills installed path code-review ``` ### Output Example ``` Found 3 builtin skill(s): agentuse builtins core Core AgentUse usage guide... creator Create, improve, and review AgentUse agent files... runner Run and manage AgentUse agents from the CLI... ``` Installed skills: ``` Found 2 installed skill(s): .agentuse/skills code-review Review code for quality, security, and maintainability... ``` With verbose mode (`-v`): ``` Found 2 installed skill(s): .agentuse/skills code-review Review code for quality, security, and maintainability... /path/to/project/.agentuse/skills/code-review/SKILL.md tools: Read, Bash(git:*) ``` For detailed information on creating and using skills, see the [Skills Guide](/guides/skills). *** ## agentuse doctor Diagnose an agent's skill capability configuration. Static mode inspects the agent file; `--last-run` inspects the most recent recorded session. ### Syntax ```bash theme={"system"} agentuse doctor [--last-run] ``` ### What It Checks Static mode: * Recurring prompt cost per model request: the agent body, the full text of each preloaded skill, and the visible skill catalog, with a total. * Explicit skills that don't exist on disk. * Explicit skills with no `allow` grants. * Commands mentioned in skill docs vs. what the agent has granted (advisory; not a permission manifest). * Learnings: how many of the stored ones are actually applied per run, and how many are over `learning.max` and so never reach the model, with `agentuse learnings tidy ` as the fix. It also reports how many are **stale** (the agent instructions changed since they were vetted, so they are held out of injection until the next capture or tidy re-vets them), a `by channel:` breakdown of what captured them (`corrections`, `tool-errors`, `custom`, `agent`, or `legacy` for entries predating channels), and every **quarantined** entry with the reason it failed the vet. It prints the resolved `learnings file:` path, echoes any one-time notice about a legacy `learning:` form, and warns when learnings are still sitting beside the agent file at the pre-0.17.0 location where nothing reads them. `--last-run` mode: * Finds the latest non-subagent session for this agent. * Reports blocked bash commands from runtime and prints a suggested `tools.bash.commands` snippet. ### Examples ```bash theme={"system"} # Static inspection agentuse doctor agents/research.agentuse # Diagnose actual blocked commands from the last run agentuse doctor agents/research.agentuse --last-run ``` ### Prompt Size Warnings Two costs recur on **every** model request, so doctor flags them: | What | Warns above | Warns harder above | | - | - | - | | Preloaded skills (the full text of everything in `skills:`) | \~2,000 tokens | \~4,000 tokens | | Visible skill catalog (a name and description per discoverable skill) | \~1,500 tokens | \~3,000 tokens | The fix for either is the same shape: preload only what every run needs, and close discovery with `skills.auto: false` plus a shorter explicit list. Open discovery is the expensive default at scale, a machine with 100 skills installed pays roughly 11k tokens per request for the catalog alone. Use `--last-run` after an agent fails or behaves unexpectedly. It uses real tool errors and is more accurate than static skill-doc extraction. *** ## agentuse learnings Inspect and tidy an agent's stored learnings. Only the top few apply per run (15 by default, `learning.max`); anything past that is stored but never reaches the model, and so are entries that are quarantined (failed the vet) or stale (the agent instructions changed since they were vetted). See the [Learning guide](/guides/learning). ### Syntax ```bash theme={"system"} agentuse learnings [--json] [--path] [--edit] agentuse learnings tidy [--dry-run] [--model ] agentuse learnings undo agentuse learnings migrate [|--all] [--dry-run] [--keep-source|--delete-source] ``` ### Subcommands | Command | Description | | - | - | | *(none)* | List every learning by status: applied, never reaches the agent, stale (instructions changed, awaiting re-vet), quarantined (failed the vet, with the reason), in the agent file, retired. | | `tidy` | Re-vet every learning the agent instructions have moved out from under, merge near-duplicates, sharpen learnings you have repeated, retire what is superseded, and make proven learnings permanent in the agent file. Applies immediately, then shows both diffs. Keeps making passes until another one would not help, up to five, and writes both files once at the end, so one run is one undo. Says what it is doing as it goes: a long list takes a few minutes. If it ends still over the cap, it accounts for every learning it left in force. | | `undo` | Restore the learnings file **and** the agent file to their state before the last tidy-up, including anything that pass quarantined. | | `migrate` | Move learnings written before v0.17.0 from beside the agent file into the AgentUse state directory. Copies first, then asks once before deleting the originals; refuses a destination that already holds learnings rather than merging; also lists any `*.learnings.md` with no matching agent file as orphaned. | ### Options | Option | Description | | - | - | | `-j, --json` | Machine-readable listing. Top level: `file` (the resolved learnings path), `cap`, and `active` / `injected` / `dormant` / `stale` / `quarantined` counts. Each entry in `learnings` carries its full record, including `channel`, `injectedCount`, `approvedRuns`, `instructionsHash`, and `quarantineReason`, plus a resolved `state` and computed `injected` and `stale` flags. | | `--path` | Print the path of the learnings file and exit. | | `--edit` | Open the learnings file in `$EDITOR` (or `$VISUAL`), creating its directory if needed. | | `--dry-run` | (`tidy`) Show the plan and both diffs without writing anything. (`migrate`) Report what would move, including refusals, without writing anything. | | `--model ` | (`tidy`) Plan with this model instead of the agent's own. | | `--all` | (`migrate`) Every agent file in the project, not one named agent. | | `--keep-source` | (`migrate`) Keep the old files without asking. | | `--delete-source` | (`migrate`) Delete the old files without asking. Required to delete anything when stdin is not a terminal, a non-interactive run never deletes on its own. | ### Examples ```bash theme={"system"} # What is actually reaching this agent? agentuse learnings agents/blog-writer.agentuse # Where does this agent's learnings file live? agentuse learnings agents/blog-writer.agentuse --path # See what a tidy-up would do, then do it agentuse learnings tidy agents/blog-writer.agentuse --dry-run agentuse learnings tidy agents/blog-writer.agentuse # Changed your mind agentuse learnings undo agents/blog-writer.agentuse # Upgrading from before v0.17.0 agentuse learnings migrate --all --dry-run agentuse learnings migrate --all git commit -am "chore: move learnings to the agentuse state dir" ``` A tidy-up writes proven learnings into a marked block in your `.agentuse` file. Only the bytes inside the markers change, frontmatter, comments and formatting are left exactly as they were, and `undo` restores both files byte for byte. Learnings no longer live beside your agent file. As of v0.17.0 they live under the AgentUse state directory, and the old location is never read. Run `agentuse learnings migrate --all` once per repo to copy them across; it will ask before removing the originals. `migrate` exits non-zero if it refused any file. *** ## agentuse agents Discover and list all agent files in the current project. ### Syntax ```bash theme={"system"} agentuse agents [options] ``` ### Options ```bash theme={"system"} -v, --verbose Show agent file paths ``` ### Examples ```bash theme={"system"} # List all agents in the project agentuse agents # Show verbose output with file paths agentuse agents -v ``` ### Output Example ``` Found 3 agent(s): agents/ assistant General-purpose AI assistant code-reviewer Reviews code for quality and security researcher Researches topics and summarizes findings ``` *** ## agentuse add Add skills and agents from GitHub repos or local paths. ### Syntax ```bash theme={"system"} agentuse add [options] ``` ### Arguments Source to add. Supports: * GitHub shorthand: `user/repo` or `user/repo#branch` * Git URL: `https://github.com/user/repo.git` * Local path: `./path/to/repo` * Direct skill: `./path/to/skill` (directory containing SKILL.md) ### Options ```bash theme={"system"} --force Overwrite existing skills/agents without prompting --all Install all skills and agents without prompting --list List available skills and agents without installing -s, --skill Install specific skill(s) by name (repeatable) -a, --agent Install specific agent(s) by path (repeatable) ``` `--skill` and `--agent` install exactly the named items: `--skill` alone installs no agents, and `--agent` alone installs no skills. Combine them to install both. ### What Gets Added | Source Pattern | Destination | | - | - | | `**/SKILL.md` (parent dir) | `.agentuse/skills/{skill-name}/` | | `SKILL.md` at the source root | `.agentuse/skills/{repo-or-directory-name}/` | | `**/*.agentuse` | Same relative path in project | ### Examples ```bash theme={"system"} # Add from GitHub (interactive selection) agentuse add vercel-labs/agent-skills agentuse add vercel-labs/agent-skills#v1.0.0 # List available skills/agents without installing agentuse add vercel-labs/agent-skills --list # Install specific skills agentuse add vercel-labs/agent-skills --skill react-best-practices agentuse add vercel-labs/agent-skills -s skill-a -s skill-b # Install specific agents agentuse add user/repo --agent deploy.agentuse # Install all without prompting agentuse add user/repo --all # Overwrite existing without prompting agentuse add user/repo --force # Add from local path agentuse add ./my-skills-repo agentuse add ./path/to/single-skill ``` ### Conflict Handling When a skill or agent already exists, you'll be prompted: ``` Skill "my-skill" already exists. [s] Skip [o] Overwrite [a] Skip all [O] Overwrite all ``` *** ## agentuse setup First-run setup. Run it without flags in a terminal to choose how to continue: * **Mac app** (Apple silicon only): opens `https://agentuse.io/download/mac`. The app includes its own runtime. * **Browser**: starts `agentuse serve` and opens the guided setup in the Web UI. * **Terminal**: creates your first project and prints the next steps. ```bash theme={"system"} agentuse setup agentuse setup --terminal --name my-agents --yes ``` Options: ```bash theme={"system"} --web Continue setup in the Web UI --terminal Continue setup in the terminal --name Managed project name (terminal) -y, --yes Accept the default project name without prompting -p, --port Web setup server port (default: 12233) -H, --host Web setup server host (default: 127.0.0.1) --no-auth Disable server API key requirement (dangerous on publicly reachable hosts) ``` `--name` and `--yes` imply `--terminal`; `--web` cannot be combined with them. Without a terminal, pass `--web` or `--terminal`. ## agentuse help Show help information. ### Syntax ```bash theme={"system"} agentuse --help agentuse -h # Command-specific help agentuse run --help agentuse auth --help ``` ### Examples ```bash theme={"system"} # General help agentuse --help # Command-specific help agentuse run --help agentuse auth --help # Show help when no arguments provided agentuse ``` The `agentuse config` command is not yet implemented. Configuration is currently managed through environment variables only. ## Global Options ```bash theme={"system"} --version Show version number --help, -h Show help for command ``` ## Environment Variables Control AgentUse behavior with environment variables. See [Environment Variables Reference](/reference/environment-variables) for complete documentation. ## Exit Codes AgentUse uses standard exit codes: | Code | Meaning | | - | - | | 0 | Success | | 1 | General error, including an `incomplete` run (exit 0 only when the blocker is a person: `waiting_on_human` or `rejected_by_human`) | | 2 | Authentication error | | 3 | File not found | | 4 | Model error | | 5 | Tool error | | 6 | MCP error | | 7 | Network error | | 130 | User interrupted (Ctrl+C) | ## Available Commands AgentUse currently supports these commands: ```bash theme={"system"} agentuse run [prompt...] # Run an agent with optional prompt agentuse test workflow # Check steps with simulated tool responses agentuse test result --session # Compare results using a past job’s evidence agentuse serve [options] # Start the HTTP daemon to run agents via API agentuse serve ps [--json] # Show the running serve daemon agentuse serve schedules [pid] [--json] # List schedules the running daemon is tracking agentuse serve agents [pid] [--json] # List agents the running daemon has loaded agentuse sessions [list|show|resume|path] # View and resume sessions agentuse sessions reconcile [--all] # Settle runs stuck at "running" agentuse sessions backfill-blockers # Add blockers to older incomplete runs agentuse setup [--web|--terminal] # First-run setup in the Mac app, browser, or terminal agentuse provider login [provider] # Authenticate with a provider agentuse provider add --url # Add custom provider (Ollama, LM Studio, etc.) agentuse provider logout [provider] # Remove stored credentials agentuse provider remove # Remove a custom provider agentuse provider list # Show all providers and credentials agentuse provider help # Show detailed auth help agentuse mcp login # Log in to an OAuth MCP server agentuse mcp status # Show how an agent's MCP servers sign in agentuse mcp logout # Forget an MCP server login agentuse models [provider] [options] # List models, aliases, and the configured default agentuse models unpin [path] # Swap pinned model versions for version aliases agentuse models bump [path] # Move superseded pins to the current model agentuse skills [subcommand] [options] # List/get builtin or installed skills agentuse doctor [--last-run] # Diagnose agent skill capability config agentuse learnings [--json] # List an agent's stored learnings by status agentuse learnings --path # Print where the learnings file lives agentuse learnings tidy # Merge, sharpen, retire and make proven ones permanent agentuse learnings undo # Restore both files to their pre-tidy state agentuse learnings migrate --all # Move pre-0.17.0 learnings into the state directory agentuse agents [options] # Discover and list project agents agentuse add [options] # Add skills/agents from GitHub or local path agentuse --version # Show version agentuse --help # Show help ``` The `agentuse auth` command still works as a backward-compatible alias for `agentuse provider`. ## Advanced Usage ### Piping ```bash theme={"system"} # Pipe input to agent echo "Translate this to Spanish" | agentuse run translator.agentuse # Pipe agent output agentuse run generator.agentuse | tee output.txt # Chain agents agentuse run analyzer.agentuse < data.txt | agentuse run summarizer.agentuse ``` ### Shell Integration ```bash theme={"system"} # Bash function agent() { agentuse run "$1.agentuse" "${@:2}" } # Usage agent translator "Hello world" ``` ### Batch Processing ```bash theme={"system"} # Process multiple files for file in *.txt; do agentuse run processor.agentuse < "$file" > "processed_$file" done # Parallel processing find . -name "*.md" | parallel agentuse run formatter.agentuse {} ``` ## Troubleshooting Ensure AgentUse is installed globally: ```bash theme={"system"} pnpm install -g agentuse ``` On Unix systems, you may need sudo: ```bash theme={"system"} sudo pnpm install -g agentuse ``` If you see authentication errors, AgentUse will show specific guidance: ```bash theme={"system"} [ERROR] No API key found for anthropic To authenticate, run: agentuse provider login Or set your API key: export ANTHROPIC_API_KEY='your-key-here' For more options: agentuse provider --help ``` Increase timeout for long-running agents: ```bash theme={"system"} agentuse run agent.agentuse --timeout 600 # or via environment MAX_STEPS=2000 agentuse run agent.agentuse ``` Enable debug output: ```bash theme={"system"} agentuse run agent.agentuse --debug ``` ## Next Steps Learn agent file format Create your first agent # Configuration Files Source: https://docs.agentuse.io/reference/configuration-files User-facing files and directories that configure AgentUse AgentUse reads configuration from agent files, environment files, global defaults, and project or user-level extension directories. ## Quick reference | Path | Scope | Purpose | | - | - | - | | `*.agentuse` | Agent | Defines an agent with YAML frontmatter and Markdown instructions | | `.env.local` | Project | Local environment variables loaded before `.env` when present | | `.env` | Project | Environment variables for API keys, model providers, MCP servers, and runtime behavior | | `--env-file ` | Run command | Load a specific environment file for `agentuse run` | | `~/.agentuse/config.json` | User | Global `agentuse serve` defaults and an `env` block of variable defaults | | `AGENTUSE_CONFIG_DIR=/path/to/profile` | Process | Override the directory containing user-global config, env, managed projects, plugins, and skills | | `AGENTUSE_CONFIG=/path/to/config.json` | Process | Deprecated file-level config override; compatibility only | | `AGENTUSE_ENV=/path/to/.env` | Process | Deprecated file-level env override; compatibility only | | `ABOUT.md` | Directory | Optional dashboard identity and description for the project or folder containing it | | `.agentuse/plugins/*.{ts,js}` | Project | Project-local plugins | | `$AGENTUSE_CONFIG_DIR/plugins/*.{ts,js}` | User | User-global plugins; defaults to `~/.agentuse/plugins/*.{ts,js}` | | `.agentuse/skills/` | Project | Project-local skills | | `$AGENTUSE_CONFIG_DIR/skills/` | User | User-global skills; defaults to `~/.agentuse/skills/` | | `.claude/skills/` | Project | Claude ecosystem skill compatibility | | `~/.claude/skills/` | User | Claude ecosystem skill compatibility | | `~/.agents/skills/` | User | Shared agent skills compatibility | | `{agent-name}.store.json` | Agent | Persistent store file for agents with store enabled | ## Agent files Agent files use the `.agentuse` extension. They combine YAML frontmatter with Markdown instructions: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: Summarize pull requests schedule: "0 9 * * 1" tools: bash: commands: - "gh *" --- Review open pull requests and summarize anything blocked. ``` Common frontmatter fields include `model`, `tools`, `schedule`, `mcpServers`, `subagents`, `store`, `learning`, `sandbox`, `approval`, `channels`, `timeout`, and `maxSteps`. See [Agent Syntax](/reference/agent-syntax) for the full schema. Approval channels are configured separately from approval policy: ```yaml theme={"system"} approval: true channels: slack: events: [approval] channel_id: C0123456789 ``` See [Channels](/guides/channels) for event semantics and [Approval Gates](/guides/approval-gates) for the approval dashboard and API workflow. ## Environment files AgentUse loads environment variables from the project root. Project roots are detected by walking upward from the starting directory until `.agentuse/`, `.git/`, or `package.json` is found. If none are found, the starting directory is the project root. For `agentuse run`, `.env.local` takes priority when present, otherwise `.env` is used. You can also pass a specific file: ```bash theme={"system"} agentuse run agent.agentuse --env-file .env.production ``` For `agentuse serve`, `-C` selects the directory whose agents are served, while the detected project root owns `.env.local`, `.env`, `.agentuse/store`, and session state. Each served project loads its own `.env.local` or `.env` in that project's worker process. Environment variables do not mix across served projects. Use environment files for provider API keys, MCP server credentials, and runtime controls such as `MAX_STEPS`, `LOG_LEVEL`, and `AGENTUSE_TELEMETRY_DISABLED`. Never commit `.env`, `.env.local`, or other secret-bearing environment files. See [Environment Variables](/reference/environment-variables) for supported variables and examples. ## Global serve config Put long-lived `agentuse serve` defaults in `~/.agentuse/config.json`: ```json theme={"system"} { "serve": { "projects": [ { "path": "~/work/projA" }, { "id": "b", "path": "~/work/projB" } ], "default": "projA", "port": 12233, "host": "127.0.0.1", "auth": true, "logFile": true, "hideAgentSource": false, "brand": { "name": "Acme Operations" }, "terms": { "project": "workspace", "folder": "team|teams" } } } ``` Use `AGENTUSE_CONFIG_DIR=/path/to/profile` to isolate the complete configuration profile. AgentUse reads `config.json` and `.env` from that directory and uses its `projects/`, `plugins/`, and `skills/` subdirectories for user-global resources. Project paths inside `config.json` may start with `~` or `~/`. `AGENTUSE_CONFIG` and `AGENTUSE_ENV` remain as deprecated file-level overrides for compatibility and take precedence over `AGENTUSE_CONFIG_DIR` when set. They are scheduled for removal no earlier than December 1, 2026; new integrations should use only `AGENTUSE_CONFIG_DIR`. AgentUse runs one serve daemon at a time. Put every project that should accept `/run`, approval, and notification traffic into `serve.projects`, or pass repeated `-C` flags when starting the daemon. | Config key | Type | Description | | | - | - | - | - | | `serve.projects` | array | Directories to serve agents from. Each item needs `path`; AgentUse detects the project root upward; `id` is optional | | | `serve.default` | string | Default project id when `POST /run` omits `project` | | | `serve.port` | number | Port to listen on | | | `serve.host` | string | Host to bind to | | | `serve.publicUrl` | string | Externally reachable base URL, used in approval links. A keyless daemon also accepts requests addressed to this URL's host | | | `serve.auth` | boolean | Require API key authentication for exposed hosts | | | `serve.logFile` | boolean | Write serve logs to a file | | | `serve.hideAgentSource` | boolean | Hide raw `.agentuse` source in the dashboard and `/api/agents/detail`; capability summaries (model, tools, schedule) stay visible. For deployments where visitors may run and observe agents but should not read their instructions (demos, client sandboxes) | | | `serve.brand.name` | string | Your company name, shown beside the AgentUse wordmark, in page titles, and as the installed app name (max 60 chars) | | | `serve.terms.project` | string | Dashboard display noun for a project. Routes, API fields, and CLI output keep the technical name | | | `serve.terms.folder` | string | Dashboard display noun for a folder. Add an explicit plural as \`singular | plural\` for irregular nouns | CLI flags override config values: | Config key | CLI override | | - | - | | `serve.projects` | `-C, --directory` replaces the configured project list | | `serve.default` | `--default ` | | `serve.port` | `--port ` | | `serve.host` | `--host ` | | `serve.publicUrl` | `--public-url ` | | `serve.auth` | `--no-auth` sets auth to `false` | | `serve.logFile` | `--no-log-file` sets log files to `false` | | `serve.hideAgentSource` | `--hide-agent-source` sets it to `true` (the flag can only hide, never re-expose a config that hides) | `AGENTUSE_API_KEY` remains env-only and is not read from config. See [Webhooks](/guides/webhooks) and [CLI Commands](/reference/cli-commands#agentuse-serve) for serve usage. ## Directory identity with `ABOUT.md` Place an optional `ABOUT.md` in a served project root or a directory containing agents. The dashboard uses the file to label and describe that directory. It does not alter agent prompts, API routes, or scheduling. Plain Markdown becomes the longer body shown on the directory detail surface: ```md theme={"system"} Automations owned by the Revenue Operations team. ``` Optional YAML frontmatter supplies compact display fields: ```md theme={"system"} --- name: Revenue Operations description: Pipeline and renewal automations owner: Operations Platform --- These agents reconcile CRM events and prepare renewal follow-ups. ``` Recognized frontmatter keys are `name`, `description`, and `owner`; scalar string or numeric values are normalized for display. Unknown keys and other value types are ignored. The body remains the longer description. AgentUse rejects symlinked and oversized `ABOUT.md` files so directory identity cannot disclose an unrelated local file or inflate API responses. `serve.brand.name` labels the whole deployment; `ABOUT.md` labels one served directory within it. Use `serve.terms` when the deployment calls projects or folders by different nouns. ## Global env defaults Alongside `serve`, `~/.agentuse/config.json` accepts an `env` block of environment variable defaults, mirroring the `env` key in Claude Code's `settings.json`. Use it for non-secret defaults you want applied to every run without maintaining a separate `~/.agentuse/.env` file: ```json theme={"system"} { "env": { "AGENTUSE_MOCK_MODEL": "anthropic:claude-haiku-4-5" } } ``` Values must be strings. The block is applied at startup and **never overrides a variable that is already set**, so the precedence is: ``` shell env > ~/.agentuse/.env > config.json "env" ``` Per-command flags still win over all of these. For example, `--mock-model ` overrides `AGENTUSE_MOCK_MODEL` from any source, and `--mock` is satisfied by a mock model coming from the flag, the shell, `~/.agentuse/.env`, or the config `env` block. Keep secrets (like `AGENTUSE_API_KEY` and provider API keys) in an environment file rather than `config.json`, which is plain non-secret configuration. ## Model defaults and aliases A `models` block in `~/.agentuse/config.json` sets the model used by agent files that omit `model`, and names models that agent files reference as `@name`: ```json theme={"system"} { "models": { "default": "anthropic:claude-sonnet", "aliases": { "fast": "anthropic:claude-haiku", "smart": "anthropic:claude-opus", "cheap-dev": "openai:gpt-mini:dev", "judgment": { "candidates": ["anthropic:claude-opus", "openai:gpt"], "cooldown": "5m" } } } } ``` ```yaml theme={"system"} --- model: "@fast" --- ``` * **`default`** applies to any agent file with no `model:` field. `AGENTUSE_MODEL` overrides it, and an explicit `model:` in the file overrides both. * **`aliases`** keys are alphanumeric with hyphens or underscores, referenced with the `@` sigil (define `fast`, write `@fast`). The `@` is required in the reference because a bare name is already a valid OpenAI model id. * A string value may be a concrete id, a [version alias](/reference/models#version-aliases), another `@name`, or any of those with an `:env` auth suffix. * An object value defines ordered fallback `candidates`. AgentUse tries the next candidate on a transient first-request failure (rate limit, timeout, provider 5xx, or transport failure) or when the candidate cannot be authenticated at all (no login, an OAuth token that will not refresh, a 401/403), and only if the model has not produced output or invoked a tool in the current execution segment. The resolved order is persisted so the same policy remains available after an approval resume. * Optional `cooldown` is a duration string such as `"30s"` or `"5m"`. A concrete model that just failed this way is skipped by new runs in the same process until the cooldown expires. Cooldowns are in memory: restarting `agentuse serve` or starting a separate CLI process resets them. Aliases are resolved when the agent file is parsed. A fallback alias keeps its ordered concrete candidates until execution. Session logs, cost accounting, and context limits record the concrete model that actually ran. A suspended run first resumes on its last selected model, even if the alias has since changed, and can advance through the remaining persisted candidates if that resumed segment fails before producing new output or invoking a tool. To point a repo at its own aliases rather than your user-global ones, put `config.json` in a dedicated directory and set `AGENTUSE_CONFIG_DIR` to that directory. Run `agentuse models` to see every alias and what it currently resolves to. ## Plugins Loose plugins are TypeScript or JavaScript modules loaded from these directories: 1. `.agentuse/plugins/*.{ts,js}` 2. `$AGENTUSE_CONFIG_DIR/plugins/*.{ts,js}` (defaults to `~/.agentuse/plugins/*.{ts,js}`) Project plugins load before user-global plugins. Installed global packages are recorded under `$AGENTUSE_DATA_DIR/plugins`, which defaults to `~/.local/share/agentuse/plugins`. Plugins installed with `agentuse plugins install -l` live under `.agentuse/packages` and are recorded in `.agentuse/plugins.json`. See [Plugins](/guides/plugins) for the plugin API. ## Skills Skills are reusable instruction packs stored as `SKILL.md` files. AgentUse discovers skills in this order: 1. `.agentuse/skills/` 2. `$AGENTUSE_CONFIG_DIR/skills/` (defaults to `~/.agentuse/skills/`) 3. `.claude/skills/` 4. `~/.claude/skills/` 5. `~/.agents/skills/` Use `.agentuse/skills/` for project-specific skills and `$AGENTUSE_CONFIG_DIR/skills/` for personal skills shared across projects. The latter defaults to `~/.agentuse/skills/`. The `.claude/skills/` locations provide compatibility with existing Claude skills, while `~/.agents/skills/` supports the shared agent-skills convention. Symlinked skill directories and `SKILL.md` files are supported; dangling links are skipped and circular directory links are ignored safely. See [Skills](/guides/skills) for authoring and discovery details. ## Generated files and data locations These files are generated by features rather than hand-written as primary configuration: | Path | Created by | Purpose | | - | - | - | | `{agent-name}.store.json` | Store | Stores persistent key-value data for the agent | | `.agentuse/sandbox/` | Sandbox | Stores sandbox-related working data | | `.agentuse/benchmark/` | Benchmark | Stores local benchmark suites and results | | `$AGENTUSE_DATA_DIR/` | AgentUse runtime | Credentials, sessions, learnings, schedules, registry, logs, push, telemetry, and update state; defaults to `~/.local/share/agentuse/` | Configuration and durable application data have separate roots. `AGENTUSE_CONFIG_DIR` moves user-controlled configuration; `AGENTUSE_DATA_DIR` moves AgentUse-owned data. `XDG_DATA_HOME` remains a compatible base-directory fallback. Isolated test or development servers should set the two AgentUse-specific variables. State that a run generates rather than a person writes lives outside the project, under a per-project directory keyed by a digest of the git root: ``` $AGENTUSE_DATA_DIR/project/{project-hash}/ ├── session/ # execution logs ├── learnings/ # agent learnings, one file per agent └── consolidations/ # undo snapshots for `agentuse learnings tidy` ``` Learnings moved here in v0.17.0; they used to sit beside the agent file as `{agent-file}.learnings.md`, where every run rewrote them into your working tree. `agentuse learnings --path` prints the new location and `agentuse learnings migrate --all` moves existing files into it. See [Learning](/guides/learning), [Store](/guides/store), [Sandbox](/guides/sandbox), and [Session Storage](/reference/session-storage) for details. # Environment Variables Source: https://docs.agentuse.io/reference/environment-variables Environment variables used by AgentUse ## Configuration Profile Directory containing AgentUse's user-controlled `config.json`, `.env`, managed `projects/`, user-global `plugins/`, and user-global `skills/`. Set this together with `AGENTUSE_DATA_DIR` when isolating a test or development server. ```bash theme={"system"} export AGENTUSE_CONFIG_DIR="/tmp/agentuse-test/config" export AGENTUSE_DATA_DIR="/tmp/agentuse-test/data" ``` The older `AGENTUSE_CONFIG` and `AGENTUSE_ENV` file-level overrides are deprecated compatibility controls. When present they take precedence for their respective file and are scheduled for removal no earlier than December 1, 2026. ## API Configuration These environment variables are required for authenticating with AI providers. API key for Anthropic Claude models. ```bash theme={"system"} export ANTHROPIC_API_KEY="sk-ant-api03-..." ``` Claude subscription OAuth is provided by the shortlisted [Claude Code Subscription plugin](/guides/plugins#curated-provider-plugins). Long-lived Claude subscription token used by the shortlisted Claude Code Subscription plugin. It is not used by the built-in Anthropic API transport. Install the plugin before using this variable: ```bash theme={"system"} agentuse plugins install cb7337/agentuse-claude-code-provider@v0.1.0 export CLAUDE_CODE_OAUTH_TOKEN="your-access-token" ``` API key for OpenAI GPT models. ```bash theme={"system"} export OPENAI_API_KEY="sk-proj-..." ``` API key for OpenRouter service. ```bash theme={"system"} export OPENROUTER_API_KEY="sk-or-v1-..." ``` API key for OpenCode Go open coding models. ```bash theme={"system"} export OPENCODE_GO_API_KEY="..." ``` Optional base URL override for OpenCode Go. Defaults to `https://opencode.ai/zen/go/v1`. ```bash theme={"system"} export OPENCODE_GO_BASE_URL="https://opencode.ai/zen/go/v1" ``` AWS access key ID for Amazon Bedrock authentication (SigV4). Used together with `AWS_SECRET_ACCESS_KEY` and `AWS_REGION`. ```bash theme={"system"} export AWS_ACCESS_KEY_ID="AKIA..." ``` AWS secret access key for Amazon Bedrock authentication (SigV4). ```bash theme={"system"} export AWS_SECRET_ACCESS_KEY="..." ``` AWS region for Amazon Bedrock API calls (e.g. `us-east-1`). Falls back to `AWS_DEFAULT_REGION` if unset. Required when using Bedrock. ```bash theme={"system"} export AWS_REGION="us-east-1" ``` Optional AWS session token for temporary credentials (e.g. STS / assumed roles) when using Amazon Bedrock. ```bash theme={"system"} export AWS_SESSION_TOKEN="..." ``` Bedrock API key (Bearer token). When set, used instead of AWS SigV4 authentication. ```bash theme={"system"} export AWS_BEARER_TOKEN_BEDROCK="..." ``` AWS named profile from `~/.aws/credentials` / `~/.aws/config`. Used when no static keys or Bearer token are set: the SDK credential provider chain resolves SSO cache, assumed roles, instance metadata, etc. ```bash theme={"system"} export AWS_REGION=eu-west-1 export AWS_PROFILE=my-bedrock-profile ``` ## Custom API Key Suffixes You can use multiple API keys by adding suffixes: ```bash theme={"system"} # For development environment export ANTHROPIC_API_KEY_DEV="sk-ant-api03-dev..." export OPENAI_API_KEY_DEV="sk-proj-dev..." # For production environment export ANTHROPIC_API_KEY_PROD="sk-ant-api03-prod..." export OPENAI_API_KEY_PROD="sk-proj-prod..." ``` Then reference them in your agent: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5:dev # Uses ANTHROPIC_API_KEY_DEV --- ``` ## Serve Mode API key for authenticating requests to the serve mode HTTP server. Required when binding to exposed hosts (not `127.0.0.1` or `localhost`). The daemon reads it once at startup and removes it from its environment, so bash commands, MCP servers, and skill scripts that agents launch do not inherit it. ```bash theme={"system"} export AGENTUSE_API_KEY="your-secret-key" agentuse serve --host 0.0.0.0 ``` Clients authenticate via Bearer token: ```bash theme={"system"} curl -X POST http://server:12233/api/run \ -H "Authorization: Bearer your-secret-key" \ -d '{"agent": "my-agent.agentuse"}' ``` GitHub repository (`owner/name`) that the "Report to AgentUse" link on a changeset review points at. The reviser sets it when a no-change diagnosis blames the AgentUse runtime rather than the agent. Point it at a fork or an internal tracker when your team triages framework bugs elsewhere. ```bash theme={"system"} export AGENTUSE_ISSUE_REPO="my-org/agentuse-fork" ``` Heap size, in MB, at which an idle per-project worker is retired and replaced. ```bash theme={"system"} export AGENTUSE_WORKER_RECYCLE_MB="300" ``` A worker bank starts around 130MB of peak heap and settles at roughly 350-450MB once it has executed runs, so a long-lived daemon otherwise holds that memory indefinitely. When an idle worker is over the threshold it is retired through the same release path used at shutdown: runs already in flight finish in the old worker while a replacement starts serving immediately. A worker is only ever recycled while idle, and never within 2 minutes of starting. Set `0` to disable recycling. Set to `0` to restore the old kill-on-shutdown behavior. By default `agentuse serve` releases its workers on shutdown instead of killing them, so a `pm2` or `systemd` restart does not destroy runs that are mid-flight. ```bash theme={"system"} export AGENTUSE_RELEASE_WORKERS="0" ``` Hard deadline, in seconds, for a released worker to exit after the daemon goes away. Defaults to the longest in-flight run's own timeout plus 10 minutes of grace. ```bash theme={"system"} export AGENTUSE_RELEASE_BACKSTOP_SECONDS="1800" ``` ## Approval Gates Slack bot token used to post and update channel messages when `channels.slack` listens for `approval`, `completion`, or `failure`. The app needs the `chat:write` bot scope, and the bot must be in the target channel unless you also grant `chat:write.public` for public channels. ```bash theme={"system"} export SLACK_BOT_TOKEN="xoxb-..." ``` Optional Slack app-level token used for Socket Mode approval actions in Slack. Web approval pages and channel-only Slack messages do not require this token. If set, the app-level token needs `connections:write`; plain thread-reply comments also require Slack message event subscriptions and the relevant channel history scopes. ```bash theme={"system"} export SLACK_APP_TOKEN="xapp-..." ``` Default Slack channel id for Slack channels. Agents can override this with `channels.slack.channel_id`. ```bash theme={"system"} export SLACK_APPROVAL_CHANNEL="C0123456789" ``` Fallback public base URL used to build approval review links. Its host also joins the keyless daemon's allowed request hosts. Prefer `agentuse serve --public-url ...` or `serve.publicUrl` for hosted deployments. ```bash theme={"system"} export AGENTUSE_RESUME_PUBLIC_URL="https://agentuse.mycompany.com" ``` ## Behavior Control Model used by agent files that omit `model:`. ```bash theme={"system"} export AGENTUSE_MODEL="anthropic:claude-sonnet" ``` Accepts anything a `model:` field accepts: a concrete id, a [version alias](/reference/models#version-aliases), a configured `@name`, or any of those with an `:env` auth suffix. **Precedence:** an explicit `model:` in the agent file wins; otherwise this variable wins over `models.default` in the AgentUse config. With none of the three set, an agent file without `model:` fails to parse. Override the maximum number of conversation steps (LLM generation cycles) an agent can take. Default: 100 ```bash theme={"system"} export MAX_STEPS="200" ``` **Precedence:** This environment variable overrides the `maxSteps` value in agent YAML files. This prevents infinite loops and controls cost by limiting the number of LLM calls. Each step typically involves an LLM generation with potential tool calls. The default was reduced from 1000 to 100 for better cost protection. Most agents complete successfully within 100 steps. Default timeout in seconds for individual MCP tool calls. Default: 60 ```bash theme={"system"} export MCP_TOOL_TIMEOUT="120" ``` **Precedence:** A server's `toolTimeout` in agent YAML overrides this variable; this variable overrides the built-in 60-second default. ## Code Mode Code Mode is enabled by default. Set this to `0` to omit `code_exec` from normal runs. The policy is inherited by recursive subagents and serve worker processes, which makes it suitable for controlled before-and-after tests or emergency rollback. This is a runtime switch only; do not add it to an agent's frontmatter. ```bash theme={"system"} AGENTUSE_CODE_MODE=0 agentuse run agent.agentuse AGENTUSE_CODE_MODE=0 agentuse serve ``` The CLI equivalents are `agentuse run --no-code-mode` and `agentuse serve --no-code-mode`. ## Mock Mode (Testing) Mock all tool outputs with the LLM instead of executing them. Mirror the `--mock` flags on `agentuse run`; see [Testing with Mocked Tools](/reference/cli-commands#testing-with-mocked-tools). `1` to mock all tool outputs (no real bash/filesystem/MCP/store side effects). Same as `--mock`. Requires `AGENTUSE_MOCK_MODEL`. Model that generates mock outputs. **Required** whenever mock mode is on (same as `--mock-model`). Not defaulted to the agent's model on purpose: mock fires an LLM call per tool result, and running that on the agent's premium, rate-limited token caused opaque `429`s. Use the **lowest-end model you can reach** here: mocking only fabricates a plausible tool result, not real reasoning, so a small fast model is plenty and keeps cost and rate-limit pressure low. Good picks: `anthropic:claude-haiku-4-5`, `openai:gpt-5.4-nano`, or `openrouter:deepseek/deepseek-v4-flash`. Set it for one run with `--mock-model`, or as a global default in the shell, `~/.agentuse/.env`, or the [`env` block of `~/.agentuse/config.json`](/reference/configuration-files#global-env-defaults). `--mock-model` overrides whichever source supplies it. What mock mode covers. Unset (or `all`) mocks every tool result, same as `--mock`. `gated` mocks only bash commands matching the agent's `tools.bash.gated` patterns and leaves every other tool real, same as `agentuse test --scope gated`. Only read when mock mode is on. Resolve the `await_human` approval gate deterministically instead of suspending (mock mode only). Same as `--mock-approval`. Values: `approve` (also `1`/`true`), `reject`, or `comment:`. An approve grants the gated-command lease from the gate's `changes[]` exactly like a real reviewer approval; a reject seals the gate (terminal), and a comment forces the revise-and-re-gate branch on the first gate then approves the re-gate. ## Context Management Enable or disable automatic context compaction when approaching model limits. Default: true (enabled) ```bash theme={"system"} # Disable context compaction export CONTEXT_COMPACTION="false" ``` When enabled, AgentUse automatically compacts older messages when context approaches the model's token limit. Percentage of context limit to trigger compaction. Default: 0.7 (70%) ```bash theme={"system"} export COMPACTION_THRESHOLD="0.8" # Trigger at 80% ``` Must be a decimal between 0 and 1. Number of recent messages to preserve during compaction. Default: 3 ```bash theme={"system"} export COMPACTION_KEEP_RECENT="5" # Keep last 5 messages ``` These messages are never compacted to maintain conversation flow. Minimum active-context size that triggers opportunistic compaction at an approval gate. Default: 64000 ```bash theme={"system"} export APPROVAL_COMPACTION_MIN_TOKENS="32000" ``` This is separate from `COMPACTION_THRESHOLD`: a 64k-token context may be far below a large model's window, but still expensive to resend after a human approval pause. Set to `0` to disable approval-boundary compaction while keeping normal model-limit compaction enabled. Minimum active-context size that triggers opportunistic compaction between LLM steps after the first tool call. Default: 64000 ```bash theme={"system"} export STEP_COMPACTION_MIN_TOKENS="128000" ``` This enables split-turn compaction for long autonomous runs: older context can be summarized before the next model call even when the full model window is not close to exhausted. Set to `0` to disable step-boundary compaction while keeping approval-boundary and model-limit compaction enabled. ## Tool Output Large tool results are re-sent to the model on every subsequent step. AgentUse stores oversized direct JSON and text results outside model context and returns a queryable handle instead. Bash keeps a larger bounded canonical capture for that result store, with the complete stream saved as a session artifact if the capture ceiling is crossed. Maximum serialized size of a direct JSON or text response returned inline. Larger results become a reusable `resultId` handle with a partial `preview` and jq-style `omitted` map, and can be narrowed with the `results` tool. Default: 10240 (10KB) ```bash theme={"system"} export AGENTUSE_TOOL_INLINE_RESULT_BYTES="16384" # 16KB ``` Maximum serialized size returned inline by one `results` tool query. Queries above this limit ask for a narrower selection and never create another result handle. Default: 20480 (20KB) ```bash theme={"system"} export AGENTUSE_RESULT_QUERY_BYTES="32768" # 32KB ``` Maximum canonical output retained by the built-in `bash` accumulator for reusable results. Output over this limit is reduced to a head + tail slice and the complete stream is saved as a session artifact; AgentUse does not issue a reusable `resultId` for that incomplete capture. Default: 4194304 (4MB) ```bash theme={"system"} export AGENTUSE_BASH_CAPTURE_BYTES="8388608" # 8MB ``` Legacy general tool-output limit. It remains the fallback for Bash canonical capture and the inline result limit when their dedicated variables are unset, preserving existing configurations. Prefer `AGENTUSE_BASH_CAPTURE_BYTES` and `AGENTUSE_TOOL_INLINE_RESULT_BYTES` for independent control. Default: 30720 (30KB) ```bash theme={"system"} export AGENTUSE_TOOL_MAX_OUTPUT_BYTES="61440" # 60KB ``` Fraction of a truncated output budget kept as the head; the remainder is kept as the tail. Errors and context often appear early, while the most recent output appears at the end, so both ends are preserved. Default: 0.4 (40% head / 60% tail) ```bash theme={"system"} export AGENTUSE_TOOL_OUTPUT_HEAD_RATIO="0.5" # even split ``` Must be a decimal between 0 and 1. Default number of lines `read_file` returns when no explicit `limit` is given (and the truncation cap for file reads). Default: 2000 ```bash theme={"system"} export AGENTUSE_TOOL_MAX_LINES="5000" ``` Per-line character cap for `read_file` output. Longer lines are truncated with a `... (truncated)` suffix. Default: 2000 ```bash theme={"system"} export AGENTUSE_TOOL_MAX_LINE_LENGTH="4000" ``` Prefer not generating bloat in the first place over raising these caps. For example, use `git diff --stat` instead of a full `git diff` of high-churn files. Truncation is a safety net, not a substitute for asking the tool for less. ## Logging and Debug Set the logging level for AgentUse output. Default: INFO ```bash theme={"system"} export LOG_LEVEL="DEBUG" # Available: DEBUG, INFO, WARN, ERROR ``` Controls which messages are displayed during execution. Enable debug logging and verbose output. Default: false ```bash theme={"system"} export DEBUG="true" # or DEBUG="1" ``` Shows detailed execution information, tool calls, and internal state. ## Telemetry Disable all anonymous telemetry, including CLI, daemon, execution, and bundled dashboard telemetry. AgentUse records installation and first-execution lifecycle events, execution metadata, and a fixed top-level dashboard page category. The browser sends that category only to its local AgentUse daemon, which batches delivery; it does not contact PostHog directly. Server telemetry reports only the kind of bind address (`host_class`: `loopback`, `any`, or `other`), never the host itself. No prompts, code, or file paths are ever collected. Default: false (telemetry enabled) ```bash theme={"system"} export AGENTUSE_TELEMETRY_DISABLED=true ``` ## Update Checks Disable the daily npm registry check and all CLI/Web UI update reminders. Update checks are cached locally, run off the command's critical path, and are also disabled automatically in CI, local development builds, and `npx` cache executions. Interactive CLI reminders appear at most once per version every seven days and are suppressed for non-TTY, `--quiet`, and `--json` output. The dashboard keeps its dismissal per browser and version. ```bash theme={"system"} export AGENTUSE_UPDATE_CHECK_DISABLED=true ``` ## Storage Exact directory containing AgentUse-owned durable data: provider credentials, installed global plugins, sessions, learnings, schedules, server registry and logs, push state, telemetry identity, and update state. ```bash theme={"system"} export AGENTUSE_DATA_DIR="/custom/agentuse-data" ``` AgentUse does not append another `agentuse/` component to this path. This variable takes precedence over `XDG_DATA_HOME`. Standards-compatible fallback base directory. AgentUse uses `$XDG_DATA_HOME/agentuse` only when `AGENTUSE_DATA_DIR` is unset. Default XDG base: `~/.local/share`. ```bash theme={"system"} export XDG_DATA_HOME="/custom/data/path" ``` Everything a run generates is stored per project, under the resolved AgentUse data directory: ``` $AGENTUSE_DATA_DIR/project/{git-hash}/ ├── session/ # execution logs ├── learnings/ # agent learnings └── consolidations/ # undo snapshots for `agentuse learnings tidy` ``` For a fully isolated development daemon, set `AGENTUSE_DATA_DIR` and `AGENTUSE_CONFIG_DIR`. Existing XDG-based integrations remain compatible. See [Session Logs](/guides/session-logs) and [Learning](/guides/learning) for more details. ## Development Variables For local development with self-signed certificates (HTTPS testing). ```bash theme={"system"} # Only for development - allows self-signed certs export NODE_TLS_REJECT_UNAUTHORIZED="0" ``` Never use this in production. It disables SSL certificate verification. ## MCP Server Environment Variables **Security by Design**: AgentUse intentionally prevents hardcoding secrets in `.agentuse` files. All sensitive values must come from environment variables, keeping your secrets secure and out of version control. ### The Security Model MCP servers can access environment variables through two fields: * **`requiredEnvVars`**: Variables that MUST exist or the agent fails immediately * **`allowedEnvVars`**: Variables that are passed through if they exist (optional) ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: notion: command: "pnpx" args: ["-y", "@notionhq/notion-mcp-server"] requiredEnvVars: - NOTION_API_KEY # Fails immediately if missing allowedEnvVars: - NOTION_DEBUG_MODE # Optional, warns if missing - NOTION_WORKSPACE_ID # Optional, warns if missing --- ``` ### Why This Design? 1. **No Secrets in Code**: `.agentuse` files are often committed to version control 2. **Clear Requirements**: Developers know exactly what env vars are needed 3. **Early Failure**: Missing required vars fail fast with clear error messages 4. **Security Allowlist**: Only explicitly allowed vars are passed to MCP servers ### Setting Environment Variables Create a `.env` file in your project root: ```bash theme={"system"} # .env NOTION_API_KEY=secret_abc123 GITHUB_TOKEN=ghp_xyz789 OPENAI_API_KEY=sk-proj-... ``` AgentUse automatically loads `.env` files from the project root (detected via `.git/`, `.agentuse/`, or `package.json`). **Override Options:** ```bash theme={"system"} # Use a specific .env file agentuse run agent.agentuse --env-file .env.production # Run from a different directory agentuse run agent.agentuse -C /path/to/project ``` Add `.env` to your `.gitignore` to prevent committing secrets! Export variables in your shell session: ```bash theme={"system"} export NOTION_API_KEY="secret_abc123" export GITHUB_TOKEN="ghp_xyz789" # Then run your agent agentuse run my-agent.agentuse ``` For permanent setup, add to `~/.zshrc` or `~/.bashrc`: ```bash theme={"system"} # ~/.zshrc export NOTION_API_KEY="secret_abc123" export GITHUB_TOKEN="ghp_xyz789" ``` Pass variables directly when running: ```bash theme={"system"} NOTION_API_KEY="secret_abc123" agentuse run my-agent.agentuse ``` Useful for CI/CD or one-time runs. For production, use secret managers: ```bash theme={"system"} # AWS Secrets Manager export NOTION_API_KEY=$(aws secretsmanager get-secret-value \ --secret-id notion-api-key --query SecretString --output text) # 1Password CLI export NOTION_API_KEY=$(op read "op://vault/notion/api-key") # HashiCorp Vault export NOTION_API_KEY=$(vault kv get -field=api_key secret/notion) ``` ### Error Messages AgentUse provides clear, actionable error messages: ```bash theme={"system"} # Missing required variable Error: Missing required environment variables for MCP server 'notion': NOTION_API_KEY Please set these in your .env file or export them in your shell. # Missing optional variable (warning only) [WARN] Optional environment variable 'NOTION_DEBUG_MODE' not set for server 'notion' # Connection failure with hint Failed to connect to MCP server 'github' Note: The following optional environment variables are not set: GITHUB_TOKEN If this server requires these variables, please set them in your .env file. ``` ### Complete Example ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: # API-based service requiring authentication notion: command: "pnpx" args: ["-y", "@notionhq/notion-mcp-server"] requiredEnvVars: - NOTION_API_KEY # Must be set or fails allowedEnvVars: - NOTION_DEBUG # Optional debug flag # Database connection postgres: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-postgresql"] requiredEnvVars: - DATABASE_URL # Required connection string allowedEnvVars: - PG_STATEMENT_TIMEOUT # Optional timeout - PG_POOL_SIZE # Optional pool config # Local filesystem (no auth needed) filesystem: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-filesystem", "./data"] # No env vars needed for local filesystem --- ``` With `.env` file: ```bash theme={"system"} # Required vars (agent won't start without these) NOTION_API_KEY=secret_abc123 DATABASE_URL=postgresql://user:pass@localhost/mydb # Optional vars (agent works without these) NOTION_DEBUG=true PG_POOL_SIZE=20 ``` ## Using .env Files For a full overview of user-facing configuration files and directories, see [Configuration Files](/reference/configuration-files). AgentUse automatically loads `.env` files if present in your project directory: ```bash theme={"system"} # .env ANTHROPIC_API_KEY=sk-ant-api03-... OPENAI_API_KEY=sk-proj-... OPENROUTER_API_KEY=sk-or-v1-... OPENCODE_GO_API_KEY=... GITHUB_TOKEN=ghp_... DATABASE_URL=postgresql://user:pass@localhost/db # Behavior control MAX_STEPS=500 # Context management CONTEXT_COMPACTION=true COMPACTION_THRESHOLD=0.7 COMPACTION_KEEP_RECENT=3 APPROVAL_COMPACTION_MIN_TOKENS=64000 STEP_COMPACTION_MIN_TOKENS=64000 # Logging and debug LOG_LEVEL=INFO DEBUG=false # Telemetry (opt-out) AGENTUSE_TELEMETRY_DISABLED=false ``` Never commit `.env` files to version control. Add them to `.gitignore`. ## Priority Order Environment variables are loaded in this order (later overrides earlier): 1. System environment variables 2. `.env` file in current directory 3. Command-line environment variables Example: ```bash theme={"system"} # This overrides any existing MAX_STEPS value MAX_STEPS=100 agentuse run agent.agentuse ``` ## Security Best Practices ### Store Secrets Securely Never hardcode API keys in agent files: ```yaml theme={"system"} # ❌ Bad - Would be insecure (but AgentUse doesn't allow this) mcpServers: github: env: GITHUB_TOKEN: "ghp_actualTokenHere" # Not supported by design! # ✅ Good - Use environment variable allowlist mcpServers: github: command: "pnpx" args: ["-y", "@modelcontextprotocol/server-github"] requiredEnvVars: - GITHUB_TOKEN # Must be in .env or shell environment ``` ### Use .gitignore Always exclude sensitive files: ```gitignore theme={"system"} # Environment files .env .env.local .env.*.local # API keys *.key *.pem ``` ### Validate Required Variables For MCP servers that require specific environment variables, they will fail with clear error messages if the variables are not set. ## Troubleshooting Verify the environment variable is set: ```bash theme={"system"} echo $ANTHROPIC_API_KEY ``` If empty, set it: ```bash theme={"system"} export ANTHROPIC_API_KEY="your-key-here" ``` Or use the auth command: ```bash theme={"system"} agentuse auth login ``` Check which key is being used: ```bash theme={"system"} agentuse auth list ``` When the Claude Code Subscription plugin is installed, subscription OAuth takes priority over the built-in Anthropic API-key transport. Ensure you're setting it before running the agent: ```bash theme={"system"} export MAX_STEPS=100 agentuse run agent.agentuse # Or inline: MAX_STEPS=100 agentuse run agent.agentuse ``` ## Next Steps Set up model providers and API keys Configure MCP servers # Model Reference Source: https://docs.agentuse.io/reference/models Recommended AI models for AgentUse # Model Reference This page lists recommended models for AgentUse, organized by provider. > **Note**: Other models from these providers may also work. These are the ones we recommend and test against. > **Auto-generated**: Run `pnpm generate:models` to update. ## Quick Reference **Default models:** * **Anthropic**: `anthropic:claude-sonnet-5-5` (balanced performance) * **OpenAI**: `openai:gpt-5.6` (general-purpose GPT) * **OpenRouter**: `openrouter:z-ai/glm-5.3` (open source) * **OpenCode Go**: `opencode-go:gpt-6-luna` (open coding models) * **Amazon Bedrock**: `bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0` ## Version Aliases Leave the version off a model id and you get whichever release is current, so an agent file does not need editing every time a new model ships: ```yaml theme={"system"} --- model: anthropic:claude-sonnet # -> anthropic:claude-sonnet-5-5 today --- ``` Aliases follow the lineup below, which is refreshed per AgentUse release. An id that exists for real always wins, so nothing you pin can be reinterpreted. | Alias | Currently resolves to | | - | - | | `anthropic:claude-opus` | `anthropic:claude-opus-5-5` | | `anthropic:claude-haiku` | `anthropic:claude-haiku-5-5` | | `anthropic:claude-sonnet` | `anthropic:claude-sonnet-5-5` | | `anthropic:claude-fable` | `anthropic:claude-fable-5-1` | | `openai:gpt-sol` | `openai:gpt-6.1-sol` | | `openai:gpt-luna` | `openai:gpt-6-luna` | | `openai:gpt-astra` | `openai:gpt-6-astra` | | `openai:gpt` | `openai:gpt-5.6` | | `openai:gpt-terra` | `openai:gpt-5.6-terra` | | `openai:gpt-pro` | `openai:gpt-5.5-pro` | | `openai:gpt-nano` | `openai:gpt-5.4-nano` | | `openai:gpt-mini` | `openai:gpt-5.4-mini` | | `openai:gpt-codex` | `openai:gpt-5.3-codex` | | `openai:gpt-codex-spark` | `openai:gpt-5.3-codex-spark` | | `openai:gpt-chat-latest` | `openai:gpt-5.3-chat-latest` | | `openrouter:z-ai/glm` | `openrouter:z-ai/glm-5.3` | | `openrouter:z-ai/glm-prime` | `openrouter:z-ai/glm-5.3-prime` | | `openrouter:z-ai/glm-flash` | `openrouter:z-ai/glm-5.3-flash` | | `openrouter:z-ai/glm-flashx` | `openrouter:z-ai/glm-5.3-flashx` | | `openrouter:z-ai/glm-turbo` | `openrouter:z-ai/glm-5v-turbo` | | `openrouter:x-ai/grok` | `openrouter:x-ai/grok-4.7` | | `openrouter:deepseek/deepseek-pro` | `openrouter:deepseek/deepseek-v4-pro` | | `openrouter:deepseek/deepseek-flash` | `openrouter:deepseek/deepseek-v4-flash` | | `openrouter:qwen/qwen-max` | `openrouter:qwen/qwen3.8-max-0902` | | `openrouter:google/gemini-flash` | `openrouter:google/gemini-3.8-flash` | | `openrouter:google/gemini-pro-preview` | `openrouter:google/gemini-3.1-pro-preview` | | `openrouter:minimax/minimax` | `openrouter:minimax/minimax-m3` | | `openrouter:moonshotai/kimi` | `openrouter:moonshotai/kimi-k3` | | `openrouter:google/gemini-flash-preview` | `openrouter:google/gemini-3-flash-preview` | | `opencode-go:gpt-luna` | `opencode-go:gpt-6-luna` | | `opencode-go:glm` | `opencode-go:glm-5.3` | | `opencode-go:glm-flash` | `opencode-go:glm-5.3-flash` | | `opencode-go:grok` | `opencode-go:grok-4.7` | | `opencode-go:hy-preview` | `opencode-go:hy4-preview` | | `opencode-go:deepseek-pro` | `opencode-go:deepseek-v4-pro` | | `opencode-go:qwen-max` | `opencode-go:qwen3.8-max` | | `opencode-go:qwen-flash` | `opencode-go:qwen3.8-flash` | | `opencode-go:qwen-plus` | `opencode-go:qwen3.7-plus` | | `opencode-go:kimi` | `opencode-go:kimi-k3` | | `opencode-go:minimax` | `opencode-go:minimax-m3` | | `opencode-go:kimi-code` | `opencode-go:kimi-k2.7-code` | | `opencode-go:mimo-pro` | `opencode-go:mimo-v2.6-pro` | | `opencode-go:mimo` | `opencode-go:mimo-v2.5` | Run `agentuse models` to see what each alias resolves to on your install, and `agentuse models unpin` to convert pinned ids in your agent files into aliases. To name your own, add a `models.aliases` block to `~/.agentuse/config.json` and reference it with the `@` sigil (see [Configuration Files](/reference/configuration-files#models)): ```json theme={"system"} { "models": { "default": "anthropic:claude-sonnet", "aliases": { "fast": "anthropic:claude-haiku" } } } ``` ```yaml theme={"system"} --- model: "@fast" --- ``` Aliases can include a reasoning preset. Use `reasoning`, the same field as agent frontmatter, and give each fallback its own setting: ```json theme={"system"} { "models": { "aliases": { "astra-high": { "model": "openai:gpt-6-astra", "reasoning": "high" }, "deep": { "candidates": [ "@astra-high", { "model": "anthropic:claude-opus", "reasoning": "high" }, { "model": "openai:gpt", "reasoning": "medium" } ], "cooldown": "1m" } } } } ``` Select this chain with `model: "@deep"`. A candidate's explicit reasoning takes precedence over agent frontmatter. Candidates without a preset use the agent's reasoning setting, or the model default when that is omitted. Effort is never inherited from the previous candidate. Existing model-specific reasoning compatibility rules still apply. Presets support `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`. `agentuse models` shows configured effort alongside each resolved candidate. The resolved settings are captured with the session for approval resume and with run-wide model overrides. If a preset references another fallback alias, its reasoning override applies only to that alias's primary candidate. Repeating a concrete model with conflicting reasoning settings is a configuration error. Named aliases may also define ordered fallback candidates and an in-memory cooldown. See [Model defaults and aliases](/reference/configuration-files#model-defaults-and-aliases). ## Recommended Models ### Anthropic | Model ID | Name | Input Context | Output | Capabilities | | - | - | - | - | - | | `anthropic:claude-opus-5-5` | Claude Opus 5.5 | 1,000,000 | 128,000 | Reasoning, Vision, Tools | | `anthropic:claude-haiku-5-5` | Claude Haiku 5.5 | 1,000,000 | 128,000 | Reasoning, Vision, Tools | | `anthropic:claude-sonnet-5-5` | Claude Sonnet 5.5 | 1,000,000 | 128,000 | Reasoning, Vision, Tools | | `anthropic:claude-fable-5-1` | Claude Fable 5.1 | 1,000,000 | 128,000 | Reasoning, Vision, Tools | ### OpenAI | Model ID | Name | Input Context | Output | Capabilities | | - | - | - | - | - | | `openai:gpt-6.1-sol` | GPT-6.1 Sol | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-6-luna` | GPT-6 Luna | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-6-astra` | GPT-6 Astra | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.6` | GPT-5.6 | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.6-terra` | GPT-5.6 Terra | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.5-pro` | GPT-5.5 Pro | 922,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.4-nano` | GPT-5.4 nano | 272,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.4-mini` | GPT-5.4 mini | 272,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.3-codex` | GPT-5.3 Codex | 272,000 | 128,000 | Reasoning, Vision, Tools | | `openai:gpt-5.3-codex-spark` | GPT-5.3 Codex Spark | 100,000 | 32,000 | Reasoning, Vision, Tools | | `openai:gpt-5.3-chat-latest` | GPT-5.3 Chat (latest) | 128,000 | 16,384 | Vision, Tools | ### OpenRouter | Model ID | Name | Input Context | Output | Capabilities | | - | - | - | - | - | | `openrouter:z-ai/glm-5.3` | GLM-5.3 | 1,048,576 | 943,718 | Reasoning, Tools | | `openrouter:z-ai/glm-5.3-prime` | GLM 5.3 Prime | 1,000,000 | 131,072 | Reasoning, Tools | | `openrouter:z-ai/glm-5.3-flash` | GLM-5.3-Flash | 1,048,576 | 943,717 | Reasoning, Vision, Tools | | `openrouter:z-ai/glm-5.3-flashx` | GLM 5.3 FlashX | 1,048,576 | 131,072 | Reasoning, Vision, Tools | | `openrouter:z-ai/glm-5v-turbo` | GLM-5V-Turbo | 202,752 | 131,072 | Reasoning, Vision, Tools | | `openrouter:x-ai/grok-4.7` | Grok 4.7 | 500,000 | 450,000 | Reasoning, Vision, Tools | | `openrouter:deepseek/deepseek-v4-pro` | DeepSeek V4 Pro | 1,048,576 | 384,000 | Reasoning, Tools | | `openrouter:deepseek/deepseek-v4-flash` | DeepSeek V4 Flash | 1,048,576 | 943,717 | Reasoning, Tools | | `openrouter:qwen/qwen3.8-max-0902` | Qwen3.8 Max 0902 | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `openrouter:google/gemini-3.8-flash` | Gemini 3.8 Flash | 1,048,576 | 65,536 | Reasoning, Vision, Tools | | `openrouter:qwen/qwen3.7-plus` | Qwen3.7 Plus | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `openrouter:google/gemini-3.1-pro-preview` | Gemini 3.1 Pro Preview | 1,048,576 | 65,536 | Reasoning, Vision, Tools | | `openrouter:minimax/minimax-m3` | MiniMax-M3 | 1,048,576 | 512,000 | Reasoning, Vision, Tools | | `openrouter:moonshotai/kimi-k3` | Kimi K3 | 1,048,576 | 943,718 | Reasoning, Vision, Tools | | `openrouter:google/gemini-3-flash-preview` | Gemini 3 Flash Preview | 1,048,576 | 65,536 | Reasoning, Vision, Tools | ### OpenCode Go | Model ID | Name | Input Context | Output | Capabilities | | - | - | - | - | - | | `opencode-go:gpt-6-luna` | GPT-6 Luna | 922,000 | 128,000 | Reasoning, Vision, Tools | | `opencode-go:glm-5.3` | GLM-5.3 | 1,000,000 | 131,072 | Reasoning, Tools | | `opencode-go:glm-5.3-flash` | GLM-5.3-Flash | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:grok-4.7` | Grok 4.7 | 500,000 | 500,000 | Reasoning, Vision, Tools | | `opencode-go:hy4-preview` | Hy4 preview | 1,024,000 | 64,000 | Reasoning, Tools | | `opencode-go:deepseek-v4-pro` | DeepSeek V4 Pro (New) | 1,000,000 | 384,000 | Reasoning, Tools | | `opencode-go:qwen3.8-max` | Qwen3.8 Max | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:qwen3.8-flash` | Qwen3.8 Flash | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:qwen3.7-plus` | Qwen3.7 Plus | 1,000,000 | 65,536 | Reasoning, Vision, Tools | | `opencode-go:kimi-k3` | Kimi K3 | 1,048,576 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:minimax-m3` | MiniMax-M3 | 1,000,000 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:kimi-k2.7-code` | Kimi K2.7 Code | 262,144 | 262,144 | Reasoning, Vision, Tools | | `opencode-go:mimo-v2.6-pro` | MiMo-V2.6-Pro | 1,048,576 | 131,072 | Reasoning, Vision, Tools | | `opencode-go:mimo-v2.5` | MiMo V2.5 | 1,000,000 | 128,000 | Reasoning, Vision, Tools | ### Amazon Bedrock Bedrock model IDs are passed through unchanged and are not validated against the static registry. Use any model ID supported by your AWS account and region. | Model ID (example) | Notes | | - | - | | `bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0` | Claude Sonnet 4.5 (US cross-region inference profile) | | `bedrock:anthropic.claude-3-5-sonnet-20241022-v2:0` | Claude 3.5 Sonnet v2 | | `bedrock:anthropic.claude-3-haiku-20240307-v1:0` | Claude 3 Haiku | | `bedrock:meta.llama3-70b-instruct-v1:0` | Llama 3 70B Instruct | | `bedrock:mistral.mistral-large-2402-v1:0` | Mistral Large | | `bedrock:us.amazon.nova-pro-v1:0` | Amazon Nova Pro | See the [Amazon Bedrock model catalog](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html) for the full list. Model availability depends on the AWS region and on the [model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) granted in your account. Authentication uses standard AWS environment variables (`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_REGION`, optional `AWS_SESSION_TOKEN`) or `AWS_BEARER_TOKEN_BEDROCK`. See the [Model Configuration guide](/guides/model-configuration#amazon-bedrock) for details. ## Custom Providers In addition to the built-in providers above, Dashboard Settings can connect custom OpenAI Chat Completions, OpenAI Responses, or Anthropic Messages endpoints. It discovers and saves available models and verifies the selected protocol with a minimal completion. For OpenAI-compatible local endpoints, you can also use the CLI: ```bash theme={"system"} # Add Ollama agentuse provider add ollama --url http://localhost:11434/v1 # Add LM Studio agentuse provider add lmstudio --url http://localhost:1234/v1 ``` Then use any model available on those endpoints: ```bash theme={"system"} agentuse run agent.agentuse -m ollama:glm-5-flash:q4_K_M agentuse run agent.agentuse -m ollama:qwen3.5:0.8b agentuse run agent.agentuse -m lmstudio:qwen/qwen3.5-9b ``` See [Model Configuration](/guides/model-configuration#custom-providers) for full setup details. ## Usage Specify a model in your agent file, pinned to a version or tracking the line: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5-5 # pinned --- ``` ```yaml theme={"system"} --- model: anthropic:claude-sonnet # newest in this line --- ``` Omit `model` entirely to use the configured default (`models.default` or `AGENTUSE_MODEL`). Or override via CLI, which accepts the same aliases: ```bash theme={"system"} agentuse run agent.agentuse -m openai:gpt-5.6 agentuse run agent.agentuse -m openai:gpt agentuse run agent.agentuse -m ollama:glm-5-flash:q4_K_M ``` # Session Storage Source: https://docs.agentuse.io/reference/session-storage Storage structure and data schemas for session logs ## Failure classification Terminal execution errors retain their broad `code` and human-readable `message`. New failures also carry an evidence-based `cause`, shared by the runtime, CLI JSON output, API run responses, and plugin error events. Session-list responses expose it as `errorCause`; full session records use `error.cause`. | Cause | Meaning | | - | - | | `run_deadline` | The execution deadline fired. Broad code remains `TIMEOUT`. | | `user_stopped`, `user_interrupt` | Explicit stop or CLI interruption. | | `client_disconnect` | The attached client disconnected mid-run. Broad code is `CLIENT_DISCONNECT`. | | `interrupted_unknown` | An abort without evidence of its source. Not a timeout. | | `model_stall` | No model progress or model-step hard limit. `phase` and optional `attempts` provide detail. | | `model_transport` | The model stream connection dropped. May include `attempts`. | | `provider_rate_limit`, `provider_overloaded` | HTTP 429 or a structured provider overload response. | | `provider_timeout`, `provider_server` | Provider request timeout or another provider server error, not the run deadline. | | `provider_content_filter` | The provider's content filter truncated the response. Broad code is `CONTENT_FILTER`. | | `provider_request`, `provider_permission` | Other provider request failure or HTTP 403. | | `authentication`, `configuration` | Authentication or validated configuration failure. | | `resume_state` | An approved run could not be resumed. The broad code is the specific resume failure. | | `worker_interrupted`, `worker_protocol` | Worker loss or an unreadable worker response. | | `request_deadline` | The daemon stopped waiting for a worker response. Does not prove the run stopped. | | `unknown` | No more specific classification is supported by the evidence. | Causes are additive. Consumers must tolerate missing or future values. Historical errors are not rewritten or guessed from message text. `INCOMPLETE` remains an agent-declared outcome, not a crash: its `cause` is the blocker kind (`missing_tool`, `no_access`, `waiting_on_human`, and so on), with `error.subject` naming the stuck thing and `error.causeSource` (`runtime`, `approval`, `agent`, or `inferred`) saying how it was established. `agentuse sessions list --json` exposes these as `errorCause` and `errorCauseSource`. Failure classification does not change retry policy or imply that replaying a run with prior side effects is safe. ## Reviewer-rejected incomplete runs A human rejection can leave a run `error/INCOMPLETE` while automatically setting `dismissedAt`, which removes it from attention queues without erasing history. An incomplete `report_outcome` accepts an optional `rejectionOnly` boolean: set it to `true` when a human rejection in the run or a delegated child is the sole blocker. The runtime verifies the recorded human decision and leaves the run visible if any descendant is still active or has an independent failure. Machine review rejections and manually dismissed failures do not establish human rejection. When independent failures remain, set `rejectionOnly: false` and describe those unresolved failures in `reason`, rather than repeating the rejected action. Older declarations without the field retain same-session rejection handling; propagating dismissal to a parent requires an explicit rejection-only declaration. Existing historical sessions are not rewritten. ## Directory Structure Sessions are stored under `AGENTUSE_DATA_DIR`, which defaults through XDG conventions to `~/.local/share/agentuse`: ``` ~/.local/share/agentuse/ └── project/ └── {git-hash}/ # Per-project isolation (or "global" for non-git) └── session/ └── {sessionID}-{agentName}/ ├── session.json └── {messageID}/ ├── message.json └── part/ ├── {partID}.json └── ... ``` ### Path Components | Component | Description | | - | - | | `{git-hash}` | First 16 chars of SHA-256 hash of git root path | | `{sessionID}` | ULID (time-sortable unique ID) | | `{agentName}` | Sanitized agent name (lowercase, alphanumeric) | | `{messageID}` | ULID for message exchange | | `{partID}` | ULID for individual parts | ### Subagent Sessions When an agent invokes subagents, their sessions are nested: ``` {sessionID}-{agentName}/ ├── session.json ├── {messageID}/ └── subagent/ └── {subSessionID}-{subAgentName}/ ├── session.json ├── {messageID}/ └── subagent/ └── {nestedSessionID}-{nestedAgentName}/ ├── session.json └── ... ``` Each descendant repeats the same structure beneath its direct parent. The stored `parentSessionID` preserves that hierarchy for recursive delegation and lets session views render important nested work in context. ## Data Schemas ### SessionInfo Stored in `session.json` at the root of each session directory. ```typescript theme={"system"} interface SessionInfo { id: string; // ULID parentSessionID?: string; // For subagent sessions agent: { name: string; // Agent name from YAML filePath?: string; // Path to .agentuse file description?: string; // Agent description isSubAgent: boolean; // True if subagent execution }; model: string; // e.g., "anthropic:claude-sonnet-5" version: string; // AgentUse version mock?: boolean; // True when the run executed in mock mode config: { timeout?: number; // Timeout in seconds maxSteps?: number; // Max steps configured mcpServers?: string[]; // MCP server names subagents?: Array<{ path: string; name?: string; }>; }; project: { root: string; // Project root directory cwd: string; // Working directory }; time: { created: number; // Unix timestamp (ms) updated: number; // Unix timestamp (ms) }; } ``` ### Message Stored in `{messageID}/message.json`. Contains both user input and assistant response. ```typescript theme={"system"} interface Message { id: string; // Message exchange ID sessionID: string; time: { created: number; // When user sent message completed?: number; // When assistant finished }; user: { prompt: { task: string; // From .agentuse markdown body user?: string; // From CLI args (optional) }; }; assistant: { system: string[]; // System prompts used modelID: string; providerID: string; mode: string; // 'build', 'plan', etc. path: { cwd: string; root: string; }; cost: number; tokens: { input: number; output: number; reasoning: number; cache: { read: number; write: number; }; }; error?: { message: string; type?: string; stack?: string; }; }; } ``` ### Parts Stored in `{messageID}/part/{partID}.json`. Each part represents a discrete unit of content. #### Base Fields All parts include these fields: ```typescript theme={"system"} interface PartBase { id: string; // Part ID (ULID) sessionID: string; // Session this part belongs to messageID: string; // Message this part belongs to } ``` #### Part Types | Type | Description | | - | - | | `text` | Text output from the model | | `reasoning` | Internal reasoning/thinking content | | `tool` | Tool call with input, output, status, duration | | `file` | File references | | `agent` | Subagent invocations | | `step-start` | Step boundary markers | | `step-finish` | Step completion with token counts | #### TextPart ```typescript theme={"system"} interface TextPart extends PartBase { type: 'text'; text: string; synthetic?: boolean; time?: { start: number; end?: number; }; } ``` #### ReasoningPart ```typescript theme={"system"} interface ReasoningPart extends PartBase { type: 'reasoning'; text: string; metadata?: Record; time: { start: number; end?: number; }; } ``` #### ToolPart ```typescript theme={"system"} interface ToolPart extends PartBase { type: 'tool'; callID: string; // Tool call ID from AI SDK tool: string; // Tool name state: ToolState; } type ToolState = | { status: 'pending' } | { status: 'running'; input: unknown; title?: string; metadata?: Record; time: { start: number }; } | { status: 'completed'; input: unknown; output: unknown; title?: string; metadata?: Record; time: { start: number; end: number }; } | { status: 'error'; input: unknown; error: string; metadata?: Record; time: { start: number; end: number }; }; ``` #### FilePart ```typescript theme={"system"} interface FilePart extends PartBase { type: 'file'; mime: string; filename?: string; url: string; source?: { type: 'file' | 'symbol'; path: string; text?: { value: string; start: number; end: number; }; }; } ``` #### AgentPart ```typescript theme={"system"} interface AgentPart extends PartBase { type: 'agent'; name: string; source?: { value: string; start: number; end: number; }; } ``` #### StepStartPart ```typescript theme={"system"} interface StepStartPart extends PartBase { type: 'step-start'; } ``` #### StepFinishPart ```typescript theme={"system"} interface StepFinishPart extends PartBase { type: 'step-finish'; cost: number; tokens: { input: number; output: number; reasoning: number; cache: { read: number; write: number; }; }; } ``` The `mock` flag is what keeps test runs out of the operational views. It is set by `agentuse test` and `agentuse run --mock`, and absent on a normal run. `agentuse sessions show` surfaces it as a warning line so a fabricated result is never mistaken for a real one: ``` Mock: ⚠ mock run: some or all tool results were fabricated, not executed ``` List views mark the same sessions with a trailing `· mock`. ## Related * [Testing Agents](/guides/testing-agents) - Validating an agent in mock mode * [Session Logs Guide](/guides/session-logs) - How to use the sessions CLI * [Environment Variables](/reference/environment-variables#storage) - Configure storage location # Variables Source: https://docs.agentuse.io/reference/variables Variable placeholders available in AgentUse agent files AgentUse supports variable placeholders in agent files (both YAML frontmatter and markdown content) to make your agent definitions more flexible and secure. ## Available Variables | Variable | Syntax | Usage Locations | Description | | - | - | - | - | | Project Root | `${root}` | Filesystem paths, System prompt | Expands to the project root directory | | Agent Directory | `${agentDir}` | Filesystem paths, System prompt | Expands to the directory containing the agent file | | Temp Directory | `${tmpDir}` | Filesystem paths, System prompt | Expands to the system temp directory | | Environment Variable | `${env:VAR_NAME}` | `mcpServers..auth.token` only | Expands to the value of an environment variable | `${env:VAR_NAME}` is intentionally NOT supported in the system prompt (markdown content) to prevent accidental secret exposure to the LLM. To show path-placeholder syntax literally in the model prompt instead of resolving it, escape the dollar sign with a backslash: `\${root}` becomes the literal text `${root}`. This is useful when an agent reviews or authors another AgentUse file. The escape applies to `${root}`, `${agentDir}`, and `${tmpDir}`; it does not enable environment-variable expansion. ## `${root}` - Project Root The `${root}` variable expands to your project's root directory, which is detected by looking for markers like `.git`, `package.json`, or `.agentuse` directory. ### Usage Use `${root}` in filesystem tool path configurations to reference paths relative to your project root, regardless of where you run the agent from. ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 tools: filesystem: - path: ${root}/src permissions: [read, write] - paths: - ${root}/docs - ${root}/tests permissions: [read] --- ``` ### Benefits * **Portable**: Paths work regardless of current working directory * **Consistent**: Always references the same location relative to project * **Safe**: Restricts file access to defined project paths ## `${agentDir}` - Agent Directory The `${agentDir}` variable expands to the directory containing the agent file. This is useful for referencing files bundled with your agent. ### Usage Use `${agentDir}` to access files that are distributed alongside your agent file, such as scripts, configs, or data files. ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 tools: filesystem: - path: ${agentDir}/scripts permissions: [read] - path: ${agentDir}/data permissions: [read, write] --- ``` ### Benefits * **Self-contained agents**: Bundle resources with your agent file * **Relocatable**: Agent works regardless of where it's installed * **No absolute paths**: Avoid hardcoding paths in agent definitions `${agentDir}` is only available when the agent is loaded from a file. If the agent is loaded from a string or other source, this variable will not be resolved. ## `${tmpDir}` - Temp Directory The `${tmpDir}` variable expands to the system's temporary directory (`os.tmpdir()`). ### Usage Use `${tmpDir}` for temporary file storage that doesn't need to persist across agent runs. ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 tools: filesystem: - path: ${tmpDir}/agentuse permissions: [read, write] --- ``` ### Benefits * **Platform-independent**: Works on macOS, Linux, and Windows * **No cleanup needed**: Temp files are typically cleaned by the OS * **Safe for scratch work**: Ideal for intermediate processing files ## `${env:VAR_NAME}` - Environment Variables The `${env:VAR_NAME}` syntax allows you to reference environment variables in your configuration. This is particularly useful for sensitive values like API tokens. ### Usage Currently supported in HTTP MCP server authentication: ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 mcpServers: api_server: url: https://api.example.com/mcp auth: type: bearer token: ${env:API_TOKEN} requiredEnvVars: - API_TOKEN # Validates the variable exists before connecting --- ``` ### How It Works 1. When the agent starts, `${env:API_TOKEN}` is replaced with `process.env.API_TOKEN` 2. If the environment variable is not set, a warning is logged 3. Use `requiredEnvVars` to ensure the variable exists before the agent runs ### Security Benefits * **No hardcoded secrets**: Tokens stay in environment variables, not in code * **Version control safe**: `.agentuse` files can be committed without exposing secrets * **Explicit requirements**: `requiredEnvVars` documents what's needed to run the agent ## Variables in System Prompt You can use path variables (`${root}`, `${agentDir}`, `${tmpDir}`) in the markdown content (system prompt) of your agent file. This helps the agent understand its environment. ### Usage ```markdown theme={"system"} --- model: anthropic:claude-sonnet-5 tools: filesystem: - path: ${root}/data permissions: [read, write] --- You are a data processing agent. ## Your Environment - Project root: ${root} - Agent location: ${agentDir} - Temp workspace: ${tmpDir} You have read/write access to the project's data directory. ``` When the agent runs, these variables are resolved to actual paths, so the agent receives: ``` You are a data processing agent. ## Your Environment - Project root: /home/user/my-project - Agent location: /home/user/my-project/agents - Temp workspace: /tmp You have read/write access to the project's data directory. ``` ### Security Note `${env:VAR_NAME}` is **not supported** in the system prompt to prevent accidental secret exposure. Environment variables should only be used for authentication tokens in MCP server configuration, where they are handled securely and never sent to the LLM. ## Examples ### Complete Agent with All Path Variables ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: "Agent with multiple filesystem paths" tools: filesystem: - path: ${root}/data permissions: [read, write] - path: ${agentDir}/templates permissions: [read] - path: ${tmpDir}/workspace permissions: [read, write] mcpServers: external_api: url: https://api.example.com/mcp auth: type: bearer token: ${env:EXTERNAL_API_KEY} requiredEnvVars: - EXTERNAL_API_KEY --- You are an agent with access to project files, bundled templates, and temp workspace. ``` ### Self-Contained Agent with Bundled Resources ```yaml theme={"system"} --- model: anthropic:claude-sonnet-5 description: "Agent with bundled scripts and data" tools: filesystem: - path: ${agentDir}/scripts permissions: [read] - path: ${agentDir}/prompts permissions: [read] - path: ${tmpDir}/output permissions: [read, write] --- You have access to bundled scripts in ./scripts and prompt templates in ./prompts. Write output files to the temp workspace. ``` ### Multiple Environment Variables ```yaml theme={"system"} mcpServers: service_a: url: https://a.example.com/mcp auth: type: bearer token: ${env:SERVICE_A_TOKEN} requiredEnvVars: - SERVICE_A_TOKEN service_b: url: https://b.example.com/mcp auth: type: bearer token: ${env:SERVICE_B_TOKEN} requiredEnvVars: - SERVICE_B_TOKEN ``` ## Variable Resolution Variables are resolved at different times: | Variable | Resolution Time | Scope | | - | - | - | | `${root}` | Agent initialization | Filesystem paths, System prompt | | `${agentDir}` | Agent initialization | Filesystem paths, System prompt | | `${tmpDir}` | Agent initialization | Filesystem paths, System prompt | | `${env:VAR_NAME}` | MCP connection setup | HTTP auth tokens only | ## Troubleshooting Ensure you're using the correct syntax: * Project root: `${root}` (lowercase) * Agent directory: `${agentDir}` (camelCase) * Temp directory: `${tmpDir}` (camelCase) * Environment variables: `${env:VAR_NAME}` (with `env:` prefix) The old `${VAR_NAME}` syntax without the `env:` prefix is not supported. `${agentDir}` is only available when the agent is loaded from a file path. It will not resolve when: * The agent is loaded from a URL * The agent is loaded from a string * The agent file path is not passed to the runner In these cases, `${agentDir}` will remain as literal text and path validation may fail. If you see a warning about an environment variable not being set: 1. Check that the variable is exported in your shell or defined in `.env` 2. Verify the variable name matches exactly (case-sensitive) 3. Add the variable to `requiredEnvVars` for early validation If `${root}` isn't pointing to the expected directory: 1. Ensure your project has a recognizable marker (`.git`, `package.json`, etc.) 2. Run the agent from within your project directory 3. Use `agentuse run -C /path/to/project` to specify the project root ## Next Steps Complete YAML configuration reference All environment variables used by AgentUse