Create agent CLI for scripted agentic tasks

t-319·WorkTask·
·
·
·Omni/Agent.hs
Created1 month ago·Updated1 month ago

Dependencies

Description

Edit

Summary

Create a simple, Unix-native CLI for agentic tasks. This replaces pi and amp usage in the repo with a Haskell-native tool that integrates with the existing agent infrastructure.

Design Philosophy

  • Unix-native: Pipes, stdin/stdout, composable with other tools
  • Simple tool set: Minimal tools, agent reads skills as needed
  • Single-shot: No REPL, no sessions, no state
  • Non-streaming: Wait for completion, print result
  • Multi-provider: Support multiple LLM backends
  • Skills are just files: No special skill loading - agent reads them via read_file

CLI Interface

agent [OPTIONS] [PROMPT]

Options:
  --provider=NAME   LLM provider (see below)
  --model=MODEL     Model override (default: claude-sonnet-4)
  --max-cost=CENTS  Cost limit (default: 50)
  --max-iter=N      Iteration limit (default: 20)
  --verbose         Show tool calls to stderr
  --json            Output structured JSON
  --dry-run         Show what would happen (no tool execution)
  -h, --help        Show help
  -v, --version     Show version

Input:
  PROMPT            From argument, or stdin if absent/empty

Output:
  Final response to stdout
  Tool calls to stderr (if --verbose)
  Exit 0 on success, 1 on failure

Note: No --skill flag. Skills are just markdown files the agent can read via read_file. The agent sees the skill index in AGENTS.md and loads skills as needed.

Provider/Auth Support (REQUIRED)

Must support multiple LLM backends, similar to pi's auth system:

Providers

| Provider | Auth Method | Env Var | |----------|-------------|---------| | anthropic | API key | ANTHROPIC_API_KEY | | openai | API key | OPENAI_API_KEY | | openrouter | API key | OPENROUTER_API_KEY | | claude-code | OAuth (Claude Max/Pro subscription) | - | | ollama | None (local) | - |

Claude Code OAuth

Critical: Must support Claude Code OAuth for users with Claude Max/Pro subscriptions. This allows using Claude without API costs.

Reference pi's implementation:

  • OAuth flow stores tokens in ~/.pi/agent/auth.json
  • Tokens refresh automatically
  • See ~/src/badlogic/pi-mono/packages/coding-agent/ for implementation details

Auth Resolution

1. Check --provider flag 2. Check env vars in order: ANTHROPIC_API_KEY, OPENROUTER_API_KEY, etc. 3. Check auth file (~/.config/agent/auth.json or similar) 4. Fallback to ollama if available

Examples

# Use default (first available)
agent "hello"

# Explicit provider
agent --provider=openrouter "hello"
agent --provider=claude-code "hello"  # Uses OAuth
agent --provider=ollama --model=llama3 "hello"

# Provider-specific model
agent --provider=openai --model=gpt-4o "hello"

Context Loading

The agent always loads AGENTS.md as initial context. This file contains:

  • Project conventions and rules
  • Skill index (table of available skills with paths)
  • Common commands

The agent can then read any skill file via read_file as needed. Skills are not pre-injected - the agent decides what to load based on the task.

Examples

# Simple one-off
agent "what's my public IP"

# Pipe input
journalctl -p err --since="24h ago" | agent "summarize these errors"
cat flake.nix | agent "what version of nixpkgs is this using"

# Task integration (via composition, not baked in)
task show t-123 --json | agent "implement this task"
# Agent reads AGENTS.md, sees skill index, reads Omni/Ide/Coder.md, follows it

# Verbose mode (see tool calls)
agent --verbose "find all TODO comments in Omni/Agent/"

# Using Claude subscription (no API costs)
agent --provider=claude-code "refactor this function"

Tools

Minimal set:

| Tool | Description | |------|-------------| | read_file | Read file contents (text or image) | | write_file | Write/create file, creates parent dirs | | edit_file | Surgical text replacement | | bash | Run command, capture stdout/stderr | | web_search | Search web (requires KAGI_API_KEY) | | read_webpage | Fetch and extract URL content |

Skills are just files - the agent reads them with read_file and follows the instructions.

Base System Prompt

You are a command-line agent. You help with tasks by reading files, running commands, and making edits.

Your context file is AGENTS.md - read it to understand project conventions and available skills.

Be concise. Output only what's needed.

When you're done, provide a clear final answer.

What This Replaces

| Current | New | |---------|-----| | pi "..." | agent "..." | | pi -p "..." | agent "..." | | pi --skill=X | agent "..." (agent reads skills as needed) | | pi --provider=X | agent --provider=X | | amp "..." | agent "..." |

Implementation Notes

Provider Abstraction

Use/extend Omni/Agent/Provider.hs which already has:

  • OpenRouter support
  • Ollama support

Need to add:

  • Direct Anthropic API
  • Direct OpenAI API
  • Claude Code OAuth flow

OAuth Implementation

For Claude Code OAuth, reference:

  • ~/src/badlogic/pi-mono/packages/ai/src/auth/
  • ~/src/badlogic/pi-mono/packages/coding-agent/src/auth.ts

The OAuth flow: 1. Open browser to Anthropic auth URL 2. User authorizes 3. Receive callback with auth code 4. Exchange for tokens 5. Store tokens, refresh as needed

Testing

1. Basic prompt: agent "echo hello" 2. Stdin: echo 'test' | agent "reverse this" 3. Context loading: verify agent reads AGENTS.md 4. Skill loading: verify agent can read skill files on demand 5. Verbose: agent --verbose "list files" 6. Provider selection: agent --provider=openrouter "..." 7. OAuth flow: agent --provider=claude-code "..." 8. Run bild --test Omni/Agent.hs

Files

  • Omni/Agent.hs - Main CLI (new, or repurpose existing)
  • Omni/Agent/Provider.hs - Extend with new providers
  • Omni/Agent/Auth.hs - New module for auth/OAuth (if needed)
  • Uses existing: Omni/Agent/Engine.hs, Omni/Agent/Tools.hs

Acceptance Criteria

  • [ ] agent "prompt" runs agentic loop and prints result
  • [ ] Stdin works: echo x | agent "..."
  • [ ] Agent reads AGENTS.md as context
  • [ ] Agent can read skill files via read_file
  • [ ] --verbose prints tool calls to stderr
  • [ ] --json outputs structured result
  • [ ] --max-cost and --max-iter respected
  • [ ] --provider selects LLM backend
  • [ ] OpenRouter provider works
  • [ ] Anthropic direct API works
  • [ ] Claude Code OAuth works (critical for subscription users)
  • [ ] Ollama provider works
  • [ ] Auth tokens stored and refreshed properly
  • [ ] Exit 0 on success, 1 on failure
  • [ ] Replaces need for pi in scripts

Timeline (4)

🔄[human]Open → InProgress1 month ago
💬[human]1 month ago

MVP implementation complete. Working features:

  • agent CLI with docopt argument parsing
  • Multi-provider support (anthropic, openrouter, ollama, auto-detect)
  • Direct Anthropic API implementation
  • Skill file loading (--skill=PATH)
  • Stdin piping with prompt combination
  • Verbose, JSON, dry-run modes
  • Cost/iteration limits

Still missing:

  • Claude Code OAuth (for Claude Max/Pro subscriptions)
  • Auth token storage/refresh

The OAuth implementation is complex - see pi's implementation in ~/src/badlogic/pi-mono/packages/ai/src/utils/oauth/ for reference. This could be a follow-up task.

🔄[human]InProgress → Done1 month ago