grok-build-upstream-mirror/crates/codegen/xai-grok-agent
Repository files (latest commit first)
Filename Latest commit message Latest commit date
grokkybara[bot] 3af4d5d398 Synced from monorepo
Synced from monorepo

Changes:
- Shell: accept target response id on rewind execute
- Shell: stamp response id on chat user message chunks
- Worktree: optional rebuild and stale git registration cleanup in auto-GC
- Worktree: kind-aware auto-GC TTLs and config knobs
- Worktree: macOS process CWD scan and Unix PID liveness for GC guards
- Worktree: automatic throttled GC on startup (Linux age-based; non-Linux dead-only)
- Pager: add `[ui].combine_queued_prompts` to batch queued follow-ups
- Shell: stop overwriting user skills
- Tools: read markdown in `skills/` directories untruncated
- `/usage` shows per-session token and dollar usage in the TUI
- Security: prompt on environment-dumping `ps` variants
- Security: always-safe `kubectl` no longer runs arbitrary kubeconfig credential plugins without permission
- Tools: make scheduler deletion durable
- Shell: add relocation storage primitives
- Shell: give side model calls their own conversation ids
- Fix five workflow-runtime bugs (budget, pause, cancel, reconnect)
- Security: peel `env -S` / `--split-string` operands in the Bash permission gate (managed deny/ask)
- Pager: expose doctor in the TUI
- Security: block unauthorized RCE via abused safe commands
- Pager idle watcher cue: "1 subagent still running" instead of "watching · 1 subagent"
- Security: block `rg --pre` arbitrary code execution in auto-mode
- Voice: diagnose silent-mic failures (macOS permission) and add doctor/terminal-setup Voice section
- App builder deployer: `allow_forking` and `show_built_with_grok`
- Pager: stop stacking duplicate "Worked for" markers on parked turns
- Shell: support `max` as a distinct reasoning effort tier
- Tools: serialize background `/loop` fires on the whole work unit
- Shell: add working-directory relocation state primitives
- Proto: `ClientToolResult` and `ChatConfig` client-side tools
- Shell: model providers
- Chat: select App Builder product on the Build path
- Shell: attach author identity to feedback when the deployment opts in
- Doctor: fix for SSH wrap setup
- Workflow authoring skills: create-workflow and import-claude-workflow docs
- Add read-only grok doctor
- Sandbox: apply Landlock without a controlling TTY
- Pager: recover image paste over grok wrap on headless remotes
- Pager: make actions screen-mode aware
- Shell: resume sessions when the working directory moves
- Pager: centralize terminal diagnostics
- Workspace: gate inline shell file access
- Pager: centralize terminal probes
- Pager: edit minimal prompts in an external editor
- Pager: standardize backgrounding on Ctrl+B
- Shell: recap rides the parent turn's prompt cache
- Tools: add scheduler lifecycle version clock

Source-Revision: 0f4d7c91b8b2b408333f6de1e8a76cb8eaa71899
2026-07-21 18:10:23 +00:00
..
scripts Publish harness and TUI open-source 2026-07-16 06:46:02 +01:00
src Synced from monorepo 2026-07-21 18:10:23 +00:00
templates Publish harness and TUI open-source 2026-07-16 06:46:02 +01:00
Cargo.toml Synced from monorepo 2026-07-18 19:48:28 +01:00
README.md Publish harness and TUI open-source 2026-07-16 06:46:02 +01:00

xai-grok-agent

Agent builder, definition parsing, and system prompt assembly.

This crate extracts a first-class Agent type from xai-grok-shell. An Agent bundles tools, system prompt, system-reminder policy, compaction policy, and model configuration into a single, portable object that any host can consume — whether that host is xai-grok-shell, another in-process host, or a headless batch runner.

Quick Start

From a definition file

Agent definitions are Markdown files with YAML frontmatter, stored in .grok/agents/ (project-level) or ~/.grok/agents/ (user-level).

use xai_grok_agent::{AgentDefinition, AgentBuilder};
use xai_grok_tools::notification::ToolNotificationHandle;

// 1. Parse the definition file
let def = AgentDefinition::from_file(".grok/agents/code-reviewer.md")?;

// 2. Build the agent
let agent = AgentBuilder::new(cwd, None, ToolNotificationHandle::noop())
    .from_definition(def)
    .build()
    .await?;

// 3. Use it
println!("Agent: {}", agent.name());
println!("Prompt: {}", agent.system_prompt());
let tool_defs = agent.tool_definitions().await;

Programmatic (no file)

let agent = AgentBuilder::new(cwd, None, ToolNotificationHandle::noop())
    .with_name("my-agent")
    .with_description("A custom agent")
    .with_tools(vec!["read_file".into(), "grep".into()])
    .build()
    .await?;

Discover all definitions

use xai_grok_agent::discovery;

// Find all .md files in .grok/agents/ directories
let definitions = discovery::discover(&cwd);

// Find a specific agent by name (checks built-ins, then user dirs)
let reviewer = discovery::by_name("code-reviewer");

// Find with project-level priority
let agent = discovery::by_name_in_cwd("my-agent", &cwd);

Agent Definition File Format

Agent definitions are Markdown files with YAML frontmatter:

---
name: my-agent
description: What this agent does
# ... additional config fields
---

System prompt body goes here...

The frontmatter (between --- delimiters) is YAML configuration. The body (after the closing ---) is the system prompt content.

Minimal example (extends base template)

---
name: code-reviewer
description: Reviews code for quality and security
tools:
  - read_file
  - grep
  - list_dir
permissionMode: plan
---

You are a senior code reviewer. Analyze code and provide
actionable feedback organized by severity.

With promptMode: extend (the default), the body is appended to the base template which includes tool calling conventions, formatting rules, and user info. The author only writes persona-specific content.

Full prompt override

---
name: custom-agent
description: Agent with full control over the system prompt
promptMode: full
tools:
  - read_file
  - search_replace
  - run_terminal_cmd
---

You are a custom agent.

Use ${{ tools.read_file }} to read files.
Use ${{ tools.search_replace }} to edit files.

${%- if tools.run_terminal_cmd %}
Use ${{ tools.run_terminal_cmd }} for shell commands.
${%- endif %}

<user_info>
OS: ${{ os_name }}
Shell: ${{ shell_path }}
Working Directory: ${{ working_directory }}
Date: ${{ current_date }}
</user_info>

With promptMode: full, the body IS the complete system prompt, rendered through MiniJinja with custom ${{ }}/${% %} delimiters (to avoid collisions with literal {{ }} in prose).

With completion requirement (orchestrated mode)

---
name: orchestrator-worker
description: Worker agent that must signal completion before ending a turn
completionRequirement:
  tool: complete_task
  reminder: >
    You stopped without calling `complete_task`.
    Please continue and call it when done.
  recovery:
    maxRetries: 5
    baseDelayMs: 5000
    maxDelayMs: 60000
toolConfig:
  wait_for_instruction:
    retry:
      maxRetries: 1440
      baseDelayMs: 5000
      maxDelayMs: 30000
---

You are a worker agent in an orchestrated multi-agent workflow.
You MUST call `complete_task` before ending your response.

Frontmatter Schema Reference

All frontmatter keys use camelCase.

Field Type Required Default Description
name string Yes Unique agent ID (lowercase, hyphens)
description string Yes When/why to use this agent
promptMode string No "extend" "extend" or "full"
tools string[] No inherit all Tool allowlist. Omit = all tools. [] = none
disallowedTools string[] No [] Denylist (takes priority over tools)
permissionMode string No "default" "default", "acceptEdits", "dontAsk", "plan"
skills string[] No [] Skill names to pre-load
agentsMd bool No true Discover and inject AGENTS.md files
outputFormat string No "default" "default" or "concise"
bash object No defaults Bash tool config overrides
bash.timeoutSecs float No 120.0 Bash command timeout
bash.outputByteLimit int No 200000 Max output bytes
bash.cmdPrefix string No null Command prefix
toolNameOverrides map<string,string> No {} Canonical → model-facing name map
paramNameOverrides map<string,map> No {} Per-tool param name map
completionRequirement object No null Tool that must be called before turn ends
completionRequirement.tool string Yes* Canonical tool name
completionRequirement.reminder string Yes* Reminder text when not called
completionRequirement.recovery object No null Recovery policy for the harness
toolConfig map<string,object> No {} Per-tool execution config
toolConfig.*.retry object No null Retry config for a tool

*Required only when completionRequirement is set.

Prompt Assembly

promptMode: extend                     promptMode: full
──────────────────                     ─────────────────
1. Base template (MiniJinja)           1. Markdown body (MiniJinja, ${{ }}/${% %})
   (tool conventions, formatting,      2. AGENTS.md section (if agentsMd: true)
    user_info, background tasks)       3. Skills section
2. Markdown body (appended raw)
3. AGENTS.md section (if agentsMd: true)
4. Skills section

Template Variables (full mode)

Variable Description
${{ tools.read_file }} Resolved name for read_file (or empty if disabled)
${{ tools.search_replace }} Resolved name for search_replace
${{ tools.run_terminal_cmd }} Resolved name for run_terminal_cmd
${{ tools.grep }} Resolved name for grep
${{ tools.list_dir }} Resolved name for list_dir
${{ tools.todo_write }} Resolved name for todo_write
${{ tools.skill }} Resolved name for skill
${{ tools.get_task_output }} Resolved name for get_task_output
${{ tools.kill_task }} Resolved name for kill_task
${{ tools.web_search }} Resolved name for web_search
${{ os_name }} Operating system (e.g. "macos", "linux")
${{ shell_path }} Shell path (e.g. "/bin/zsh")
${{ working_directory }} Workspace path
${{ current_date }} Current date in the user's local timezone (YYYY-MM-DD)

Conditionals: ${%- if tools.todo_write %}...${%- endif %} — block is omitted when the tool is disabled.

Discovery Rules

Agent definitions are discovered from multiple locations with priority:

  1. Project-level (highest priority): .grok/agents/*.md — walk from cwd up to the git repository root. Files found closer to cwd take priority.
  2. User-level: ~/.grok/agents/*.md
  3. Compat paths (lowest priority): additional vendor agent directories under the user home (when enabled)
  4. Built-in: default_grok_build(), browser_use()

Name-based dedup ensures the highest-priority definition wins. For example, a project .grok/agents/code-reviewer.md shadows a user-level definition with the same name.

Crate Relationships

┌──────────────────┐
│  xai-grok-agent  │  ← This crate
│  (Agent, Builder, │
│   Definition)     │
└────────┬─────────┘
         │ depends on
         ▼
┌──────────────────┐
│  xai-grok-tools  │
│  (ToolBridge,    │
│   ToolRegistry,  │
│   ToolState)     │
└────────▲─────────┘
         │ depends on
┌────────┴─────────┐
│  xai-grok-shell  │  uses AgentBuilder to create
│  (session host)  │  Agent during session setup
└──────────────────┘
  • xai-grok-tools: Provides ToolBridge, ToolRegistry, ToolState, SystemReminderLayer, and tool implementations. xai-grok-agent depends on it for tool setup.
  • xai-grok-shell: The application shell. Uses AgentBuilder to construct an Agent during session creation. The shell re-exports some modules from xai-grok-agent (AGENTS.md discovery, skills discovery, base prompt rendering).

Built-in Agents

Name Prompt Mode Description
grok-build extend Default agent for software engineering tasks
browser-use full Web browsing and interaction agent

Error Handling

AgentBuilder::build() returns Result<Agent, AgentBuildError>:

Error When
ParseError Bad YAML, missing ---, wrong types
MissingField Required field (name/description) absent
UnknownToolOverride toolNameOverrides references nonexistent tool
IoError File read error during AGENTS.md/skills discovery
MiniJinjaError Template rendering failure

Unknown frontmatter fields are silently ignored for forward compatibility — definitions written for newer versions work on older ones.

Development

# Check
cargo check -p xai-grok-agent

# Test
cargo test -p xai-grok-agent

# Clippy
cargo clippy -p xai-grok-agent --fix --allow-dirty

# Format
cargo fmt --all