For AI Agents

This page is for AI agents that use powerglide as a subprocess tool, and for developers building orchestration layers on top of it. The key design properties that make powerglide composable: deterministic terminal signals, structured session state on disk, and configurable safety limits that an orchestrator can set without cooperation from the agent itself.

Using powerglide as a Tool

When an AI agent invokes powerglide, it needs to know when the session is done and whether it succeeded. powerglide provides two explicit terminal signals emitted to stdout:

  • <POWERGLIDE_DONE> — All tasks in the queue were processed. The session ended cleanly.
  • <POWERGLIDE_ERROR> — An unrecoverable error occurred. Check the session log for details.

These signals are unambiguous even in a stream of mixed output. Grep for them rather than relying on process exit codes, which can be swallowed by shell wrappers or process managers.

Basic Invocation

powerglide run "implement a binary search tree in Zig"

With Parameters

powerglide run \
  --agent hephaestus \
  --velocity 2.0 \
  --model "claude-opus-4-6" \
  "add unit tests for the authentication module"

Setting --velocity 2.0 halves the inter-step delay (500ms). This is appropriate when the calling agent is monitoring output and doesn’t need time for human review. For unattended long-running tasks, --velocity 1.0 (the default 1000ms) adds breathing room.

Building on powerglide

Session Management

Sessions persist to ~/.powerglide/sessions/{id}/ as JSON and JSONL files. Using an explicit --session-id lets you resume work across invocations: the session file records which tasks have been completed, so a resumed session picks up where the previous one left off rather than re-executing finished work.

# Start a session with an explicit ID
powerglide run --session-id my-session "task 1"

# Resume the same session — picks up from where task 1 left off
powerglide run --session-id my-session "task 2"

# Inspect what sessions exist
powerglide session list

Swarm Orchestration

For multi-agent workflows, the swarm commands manage the full lifecycle: creation, task assignment, status monitoring, and teardown. The status subcommand polls the worker heartbeat files and reports each worker’s current loop state — useful for an orchestrating agent that needs to know when all workers are idle before aggregating results.

# Create a 3-worker swarm
powerglide swarm create dev-team --agents 3

# Assign a task to the swarm — distributed across workers via task-queue.json
powerglide swarm run dev-team "implement the API layer"

# Poll worker states — reports loop state, steps completed, last heartbeat
powerglide swarm status dev-team

Tool Interface

All powerglide tools follow a consistent interface. The parameters field is a raw JSON Schema string, formatted identically to Claude’s tool use API and OpenAI’s function calling API, so tool definitions can be forwarded directly to either model family without transformation.

pub const Tool = struct {
    name: []const u8,
    description: []const u8,
    parameters: ?[]const u8 = null,
    
    pub fn execute(self: *Tool, args: []const u8) !ToolResult {
        // Implementation
    }
};

pub const ToolResult = struct {
    success: bool,
    output: []const u8,
    err: ?[]const u8 = null,
};

Available Tools

ToolDescription
bashExecute shell commands
readRead file contents
writeWrite files
editEdit files with precision
grepSearch code
globFind files by pattern

Best Practices

For Agent Developers

  1. Emit <POWERGLIDE_DONE> explicitly — The loop checks for this signal; without it, the calling code cannot distinguish a clean exit from a crash. Always emit it when all work is complete.
  2. Write velocity to the session file for risky operations — If your agent is about to touch production data or make irreversible changes, write VELOCITY=0.25 to ~/.config/powerglide/session-<id>.json first. The orchestrator will slow the loop, giving monitoring systems time to detect and stop the action.
  3. Use the failed state for recovery, not for logging — The failed state triggers retry logic if configured. If you reach it, the failure should be recorded with enough context to determine whether a retry would succeed.
  4. Write structured progress to the session file — The steps_completed and last_activity fields are polled by the monitor. Keeping them updated accurately is how you stay alive past the heartbeat timeout.
  5. Respect step limits — A session that approaches max_steps without completing its task should report partial progress in its result file rather than silently truncating.

For Agent Consumers

  1. Set max_steps to match task scope — A small refactor might complete in 20 steps; a full feature implementation might need 150. The default 200 is a safety net, not a target.
  2. Monitor heartbeat age, not just process liveness — A process can be running but fully stuck inside a hung subprocess. The heartbeat file age is the reliable indicator.
  3. Always use --session-id for recoverable work — Without an explicit session ID, a crashed session leaves no restart point. Named sessions can be resumed after transient failures.
  4. Check the session result file before declaring success — The process exit code alone doesn’t tell you whether the task completed. Read ~/.powerglide/sessions/{id}/result.json for the authoritative outcome.

Integration Examples

Python Integration

import subprocess

def run_powerglide(task: str, agent: str = "hephaestus"):
    result = subprocess.run([
        "powerglide", "run",
        "--agent", agent,
        task
    ], capture_output=True, text=True)
    return result.stdout

Node.js Integration

import { execSync } from 'child_process';

function runPowerglide(task, options = {}) {
    const args = ['powerglide', 'run'];
    if (options.agent) args.push('--agent', options.agent);
    if (options.velocity) args.push('--velocity', options.velocity);
    args.push(task);
    
    return execSync(args.join(' '), { encoding: 'utf8' });
}

Zig Integration

const std = @import("std");

fn runPowerglide(allocator: std.mem.Allocator, task: []const u8) !void {
    const result = try std.process.Child.run(.{
        .allocator = allocator,
        .argv = &[_][]const u8{
            "powerglide",
            "run",
            task,
        },
    });
    defer result.deinit();
    
    std.debug.print("Output: {s}\n", .{result.stdout});
}

API Reference

LoopState (src/agent/loop.zig)

The full 11-state enum. When monitoring a running agent, the status field in its session file will contain one of these values as a string.

pub const LoopState = enum {
    idle,        // initialized, no task dispatched yet
    load_tasks,  // reading task queue from disk
    pick_task,   // selecting and claiming the next task
    thinking,    // awaiting LLM response
    tool_call,   // parsing LLM's tool invocation
    executing,   // running tool subprocess in PTY
    observing,   // feeding tool output back to LLM
    verify,      // running validation checks
    commit,      // writing completion record
    done,        // all tasks complete, emitting POWERGLIDE_DONE
    failed,      // unrecoverable error
};

ModelProvider (src/models/router.zig)

pub const ModelProvider = enum {
    anthropic,          // Anthropic Messages API (Claude)
    openai,             // OpenAI Chat Completions API
    openai_compatible,  // Any /v1/chat/completions endpoint — set base_url in config
};

Debugging

Enable Debug Logging

export POWERGLIDE_DEBUG=1
powerglide run "task"

Session Logs

# View session logs
powerglide session show abc123 --logs

# Export logs
powerglide session export abc123 --logs > session.log

Common Issues

IssueSolution
Agent stuckCheck heartbeat timeout, increase if needed
Step limit hitIncrease max_steps config
Tool timeoutIncrease tool timeout in config
API errorsCheck API key, rate limits

Security Considerations

  1. API Keys - Store in environment variables, not config files
  2. Tool Permissions - Restrict bash commands when possible
  3. Session Data - Review before sharing/exporting
  4. Network Access - Monitor outbound connections

Back to Home · Configuration · Architecture