Publish harness and TUI open-source
initial sync from the monorepo
This commit is contained in:
commit
c68e39f604
2734 changed files with 1437016 additions and 0 deletions
313
crates/codegen/xai-grok-agent/README.md
Normal file
313
crates/codegen/xai-grok-agent/README.md
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
# `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).
|
||||
|
||||
```rust
|
||||
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)
|
||||
|
||||
```rust
|
||||
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
|
||||
|
||||
```rust
|
||||
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:
|
||||
|
||||
```markdown
|
||||
---
|
||||
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)
|
||||
|
||||
```markdown
|
||||
---
|
||||
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
|
||||
|
||||
```markdown
|
||||
---
|
||||
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)
|
||||
|
||||
```markdown
|
||||
---
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
|
||||
|
||||
Loading…
Reference in a new issue