Skip to main content

ainvoke

Go Report Card ci codecov version npm PyPI license Go Reference

ainvoke provides a focused runner for invoking agent CLIs with a normalized JSON I/O contract.

Installation

Go

go install github.com/metalagman/ainvoke/cmd/ainvoke@latest

npm (Node.js)

npx @metalagman/ainvoke quickstart

# Or install globally
npm install -g @metalagman/ainvoke
ainvoke quickstart

uv / pip (Python)

uvx ainvoke quickstart

# Or install
uv pip install ainvoke
ainvoke quickstart

Pre-built binaries

Download pre-built binaries from GitHub Releases:

# Linux/macOS
curl -L https://github.com/metalagman/ainvoke/releases/latest/download/ainvoke-linux-amd64 -o ainvoke
chmod +x ainvoke
sudo mv ainvoke /usr/local/bin/

# Verify checksum (recommended)
curl -L https://github.com/metalagman/ainvoke/releases/latest/download/checksums.txt -o checksums.txt
sha256sum -c checksums.txt

CLI

Usage

ainvoke <command> [flags]

Common flags (all commands)

  • --input-schema (default {"type":"object","properties":{"input":{"type":"string"}},"required":["input"]})
  • --output-schema (default {"type":"object","properties":{"output":{"type":"string"}},"required":["output"]})
  • --input-schema-file
  • --output-schema-file
  • --prompt
  • --input
  • --extra-args
  • --work-dir (must already exist; returns an error otherwise)
  • --debug (forward agent stdout/stderr to stderr)

quickstart

Displays a guide with common usage examples and instructions for all supported agents.

ainvoke quickstart

version

Prints the build version, git commit, and build date embedded at build time.

ainvoke version

exec (generic runner)

Flags:

  • Common flags
  • --tty (default true)
ainvoke exec codex \
  --input-schema='{"type":"object","properties":{"input":{"type":"string"}},"required":["input"]}' \
  --output-schema='{"type":"object","properties":{"output":{"type":"string"}},"required":["output"]}' \
  --prompt="input is a name, answer as Hello, <name>!" \
  --input='{"input":"Bro"}' \
  --extra-args="--model=gpt-5.1-codex-mini,--sandbox=workspace-write" \
  --work-dir=.
ainvoke exec codex \
  --input-schema-file=./schemas/input.json \
  --output-schema-file=./schemas/output.json \
  --prompt="input is a name, answer as Hello, <name>!" \
  --input='{"input":"Bro"}' \
  --extra-args="--model=gpt-5.1-codex-mini,--sandbox=workspace-write" \
  --work-dir=.

claude (wrapper, no defaults)

Flags:

  • Common flags
  • --model (optional)

Defaults:

  • Runs in headless mode (no TTY).
ainvoke claude \
  --model="claude-3-5-sonnet-latest" \
  --prompt="Input is a name, answer as Salam, <name>!" \
  --input='{"input":"Bro"}' \
  --work-dir=.

codex (wrapper with default flags)

Flags:

  • Common flags
  • --model (optional)

Defaults:

  • Inserts exec subcommand when missing.
  • Runs in headless mode (no TTY).
ainvoke codex \
  --model="gpt-5.1-codex-mini" \
  --prompt="Input is a name, answer as Salam, <name>!" \
  --input='{"input":"Bro"}' \
  --work-dir=.
ainvoke codex \
  --input-schema='{"type":"string"}' \
  --output-schema='{"type":"string"}' \
  --prompt="Input is a name, answer as Salam, <name>!" \
  --input="Bro" \
  --model="gpt-5.1-codex-mini" \
  --work-dir=.

gemini (wrapper with default flags)

Flags:

  • Common flags
  • --model (optional)

Defaults:

  • Adds --output-format text unless provided.
  • Runs in headless mode (no TTY).
ainvoke gemini \
  --model="gemini-3-flash-preview" \
  --prompt="Input is a name, answer as Salam, <name>!" \
  --input='{"input":"Bro"}' \
  --work-dir=.

opencode (wrapper with default flags)

Flags:

  • Common flags
  • --model (optional)

Defaults:

  • Inserts run subcommand when missing.
  • Runs in headless mode (no TTY).
ainvoke opencode \
  --model="opencode/big-pickle" \
  --prompt="Input is a name, answer as Salam, <name>!" \
  --input='{"input":"Bro"}' \
  --work-dir=.

Notes:

  • Use --input-schema-file or --output-schema-file to load schemas from files.
  • On success, the CLI prints output.json to stdout and preserves the agent exit code.
  • --tty=false disables pseudo-terminal execution for exec.
  • --debug forwards agent stdout/stderr to stderr for troubleshooting.

Schema examples

Object schemas

const inputSchema = `{"type":"object","properties":{"input":{"type":"string"}},"required":["input"]}`
const outputSchema = `{"type":"object","properties":{"output":{"type":"string"}},"required":["output"]}`

String schemas

const inputSchema = `{"type":"string"}`
const outputSchema = `{"type":"string"}`

Notes

  • Ensure the agent CLI specified by cmd is installed and available on PATH.
  • RunDir must already exist; the runner does not create it and returns an error if it is missing.
  • The runner writes input.json from Invocation.Input (or expects it to already exist if Input is nil).
  • The runner validates input.json against InputSchema before running the agent.
  • The agent must write output.json in RunDir; on success the runner validates it against OutputSchema.
  • SystemPrompt is optional and should be used for extra instructions beyond the built-in schema and I/O requirements.
  • WithStdout and WithStderr are optional; omit them to disable streaming output (output bytes are still captured and returned).
  • WithTTY(true) runs the agent inside a pseudo-terminal for CLIs that require one.

Library usage

package main

import (
	"context"
	"log"
	"os"

	"github.com/metalagman/ainvoke"
)

func main() {
	runDir := "./run"
	_ = os.MkdirAll(runDir, 0o755)

	const inputSchema = `{
  "type":"object",
  "properties":{
    "input":{"type":"string"}
  },
  "required":["input"]
}`

	const outputSchema = `{
  "type":"object",
  "properties":{
    "output":{"type":"string"}
  },
  "required":["output"]
}`

	inv := ainvoke.Invocation{
		RunDir: runDir,
		SystemPrompt: `Output "Hello, <input>!" in the output field.`,
		Input: map[string]any{
			"input": "Ada",
		},
		InputSchema:  inputSchema,
		OutputSchema: outputSchema,
	}

	cfg := ainvoke.AgentConfig{
		Cmd: []string{"./my-agent-binary"},
	}

	runner, err := ainvoke.NewRunner(cfg)
	if err != nil {
		log.Fatal(err)
	}

	stdout, _ := os.Create("stdout.log")
	stderr, _ := os.Create("stderr.log")
	defer stdout.Close()
	defer stderr.Close()

	_, _, _, err = runner.Run(
		context.Background(),
		inv,
		ainvoke.WithStdout(stdout),
		ainvoke.WithStderr(stderr),
	)
	if err != nil {
		log.Fatal(err)
	}
}

Agent Development Kit (ADK)

The ADK provides utilities for building agent integrations, including the ExecAgent for executing external commands.

ExecAgent

The ExecAgent executes external commands and manages their input/output according to the ainvoke protocol.

Constructor

The NewExecAgent constructor uses functional options with automatic validation:

import "github.com/metalagman/ainvoke/adk"
import "time"

// Minimal configuration
agent, err := adk.NewExecAgent(
    "MyAgent",                    // name (required)
    "Description of my agent",       // description (required)
    []string{"my-agent-binary"},     // cmd (required)
)

// With functional options
agent, err := adk.NewExecAgent(
    "MyAgent",
    "Description of my agent",
    []string{"my-agent-binary"},
    adk.WithExecAgentPrompt("Custom system prompt"),
    adk.WithExecAgentUseTTY(true),
    adk.WithExecAgentTimeout(30*time.Second),
    adk.WithExecAgentRunDir("./work-dir"),
    adk.WithExecAgentExtraArgs("--verbose", "--debug"),
    adk.WithExecAgentInputSchema(`{"type":"string"}`),
    adk.WithExecAgentOutputSchema(`{"type":"string"}`),
)

Available Options

  • WithExecAgentPrompt(string) - Set system prompt
  • WithExecAgentExtraArgs(...string) - Add command arguments (variadic)
  • WithExecAgentUseTTY(bool) - Enable/disable pseudo-terminal
  • WithExecAgentTimeout(time.Duration) - Set execution timeout
  • WithExecAgentInputSchema(string) - Override input JSON schema
  • WithExecAgentOutputSchema(string) - Override output JSON schema
  • WithExecAgentRunDir(string) - Set custom working directory

Complete Example (CLI Agent)

The following example shows how to create a standalone CLI agent using ExecAgent and the standard ADK launcher. This makes the agent fully compatible with ainvoke and other ADK-compliant tools.

package main

import (
	"context"
	"log"
	"os"

	"github.com/metalagman/ainvoke/adk"
	"google.golang.org/adk/agent"
	"google.golang.org/adk/cmd/launcher"
	"google.golang.org/adk/cmd/launcher/full"
)

func main() {
	// 1. Create the ExecAgent
	// This wraps the codex CLI in exec mode.
	myAgent, err := adk.NewExecAgent(
		"CodexAssistant",
		"A codex-backed assistant agent",
		[]string{"codex", "exec", "--sandbox", "workspace-write"},
		adk.WithExecAgentInputSchema(`{"type":"object","properties":{"input":{"type":"string"}},"required":["input"]}`),
		adk.WithExecAgentOutputSchema(`{"type":"object","properties":{"output":{"type":"string"}},"required":["output"]}`),
	)
	if err != nil {
		log.Fatalf("Failed to create agent: %v", err)
	}

	// 2. Configure the ADK launcher
	config := &launcher.Config{
		AgentLoader: agent.NewSingleLoader(myAgent),
	}

	// 3. Execute the launcher
	// This provides a standard CLI interface (e.g., --input, --work-dir)
	l := full.NewLauncher()
	if err := l.Execute(context.Background(), config, os.Args[1:]); err != nil {
		log.Fatalf("Run failed: %v", err)
	}
}

RunDir Behavior

  • Empty RunDir: Uses current working directory (.)
  • Custom RunDir: Validates that the directory exists; returns an error otherwise
  • Persistence: Files created in the run directory (like input.json and output.json) are preserved after execution

Validation

The NewExecAgent constructor includes automatic validation:

  • Required fields: name, description, cmd must be provided
  • Command array: Must not be empty
  • All validations are performed at construction time with clear error messages

Contributing

Refer to AGENTS.md for development guidelines.

Metadata

Release files for ainvoke 1.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for ainvoke 1.4.1
File
ainvoke-1.4.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
ainvoke-1.4.1-py3-none-manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
ainvoke-1.4.1-py3-none-manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
ainvoke-1.4.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
ainvoke-1.4.1-py3-none-macosx_10_13_x86_64.whl Python 3 none macOS 10.13+ x86-64 Details

Total release size: 44.3 MB

Release files / ainvoke-1.4.1-py3-none-win_amd64.whl

Download URL ainvoke-1.4.1-py3-none-win_amd64.whl
Size 9.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
54ba135225dc52e1bd358c0905411719848c92f731442c11d57f4801f54515d7
BLAKE2b-256 checksum
How to use checksums
eafe2107fe155048f11885a9c70091fcb56f109f0d8bd2f43a8406e21265f877
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ainvoke-1.4.1-py3-none-manylinux2014_x86_64.whl

Download URL ainvoke-1.4.1-py3-none-manylinux2014_x86_64.whl
Size 9.0 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
09e7644e826d21ca2eaf6be65ac38b03d872db0c155922d1012de10e8f500a4f
BLAKE2b-256 checksum
How to use checksums
5d9a6bd9ff44d518466a715f0f20c27b60e10a804b0168c976f6eb43c54d2796
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ainvoke-1.4.1-py3-none-manylinux2014_aarch64.whl

Download URL ainvoke-1.4.1-py3-none-manylinux2014_aarch64.whl
Size 8.4 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
f3f297706dfa84ee3f6b6dbade0d326e7449719697153f52aa4e413aa2eef158
BLAKE2b-256 checksum
How to use checksums
15fde854c99267d0ab63fdcfff09a8036f0648b3f9274603d558cc0f2ca5fecd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ainvoke-1.4.1-py3-none-macosx_11_0_arm64.whl

Download URL ainvoke-1.4.1-py3-none-macosx_11_0_arm64.whl
Size 8.6 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
af36377bfebc6981ef23354adfaca1833608b62ddf21dfd96291e09d172575e0
BLAKE2b-256 checksum
How to use checksums
94e11031768cdb96b7ef1a74172e9bd8b0dfd44f9fa06aa88188ee8a2a52c6ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ainvoke-1.4.1-py3-none-macosx_10_13_x86_64.whl

Download URL ainvoke-1.4.1-py3-none-macosx_10_13_x86_64.whl
Size 9.1 MB
Tags Python 3 macOS 10.13+ x86-64
SHA-256 checksum
How to use checksums
1682074f93bd9d057ade5f98de4e784a82b9f3268c50ce2379093cc62f5bb17f
BLAKE2b-256 checksum
How to use checksums
19c3eb5015738e25fc24d3befdc925ef3c0beb7376ff2c2999cc828aa18f5d49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.4.1 This release

5 release files

1.4.0

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page