Skip to content

MauricioPerera/php-agent-shell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHPAgentShell

2-tool AI agent shell for PHP — vector discovery + CLI execution. Port of the Agent Shell pattern to native PHP.

composer require mauricioperera/php-agent-shell

The Problem

Traditional AI agent frameworks register every tool individually. 50 tools = ~10,000 tokens of context in every request, even if the agent only uses 2.

The Solution

PHPAgentShell exposes exactly 2 tools to the LLM:

Tool 1: cli_help()           → Interaction protocol (~185 tokens, constant)
Tool 2: cli_exec(cmd: str)   → Search, describe, execute any command

Commands are discovered via vector semantic search, not by listing all tools. The agent searches in natural language, describes what it finds, then executes.

Traditional: 19 tools × 200 tokens = 3,800 tokens PER REQUEST
Agent Shell: 2 tools  × 100 tokens =   200 tokens ALWAYS (94% reduction)

Quick Start

use PHPAgentShell\AgentShell;

$shell = new AgentShell(
    embedFn: fn(string $text) => myEmbedFunction($text),
    dimensions: 768,
);
$shell->registerDefaults(); // 19 built-in commands

// The LLM gets the protocol (once)
$protocol = $shell->help(); // ~185 tokens

// The LLM interacts via exec()
$shell->exec('search list files');
// → [{name: "file:list", score: 0.98, description: "List files..."}]

$shell->exec('describe file:list');
// → {definition: {...}, help: "file:list -- List files...  --path (required): ..."}

$shell->exec('file:list --path /my/project');
// → {entries: [{name: "src", type: "dir"}, ...], count: 7, code: 0}

How the Agent Uses It

Step 1: LLM receives help()          "Agent Shell — 19 commands..."
          ↓                            ~185 tokens (constant)
Step 2: exec("search deploy")        Vector search → top 5 matches
          ↓                            ~50 tokens per result
Step 3: exec("describe git:push")    Full definition + params
          ↓                            ~100 tokens
Step 4: exec("git:push --branch main")  Actual execution
          ↓                            Structured JSON response
Step 5: exec("search backup database")  Next task...

The LLM never sees all 19 commands. It discovers 2-3 at a time via semantic search.

Built-in Commands (19)

Namespace Commands Description
shell exec, which Execute CLI commands, find binaries
file read, write, list, exists, delete File operations
git status, log, diff, branch, add, commit Git operations
http get, post HTTP client
json parse JSON parsing with dot-notation path extraction
env get, list Environment variables
process list Process management

Discovery Commands

Command Description
search <query> Semantic vector search for commands
describe <name> Full definition + parameters
list [namespace] List all or by namespace
help Interaction protocol

Custom Commands

use PHPAgentShell\Command\CommandDefinition;
use PHPAgentShell\Command\CommandParam;

$shell->register(new CommandDefinition(
    name: 'deploy:run',
    description: 'Deploy the application to production',
    params: [
        new CommandParam('env', 'Target environment', 'string', true),
        new CommandParam('dry-run', 'Simulate without executing', 'boolean', false, false),
    ],
    namespace: 'deploy',
    dangerous: true,
    handler: function (array $args): array {
        $env = $args['env'];
        // ... deployment logic
        return ['status' => 'deployed', 'environment' => $env, 'code' => 0];
    },
));

The LLM can now discover it: search "deploy to production"deploy:run.

Neuron AI Integration

use PHPAgentShell\Integration\ShellToolkit;

class MyAgent extends \NeuronAI\Agent\Agent
{
    protected function tools(): array
    {
        return [
            new ShellToolkit($agentShell),
        ];
    }
}

Only 2 tools registered. The guidelines() method returns the protocol as system context.

Combined with PHPAgentMemory

use PHPAgentShell\Integration\ShellToolkit;
use PHPAgentMemory\Integration\Neuron\MemoryToolkit;

class FullAgent extends \NeuronAI\Agent\Agent
{
    protected function tools(): array
    {
        return [
            new ShellToolkit($shell),           // 2 tools: help + exec
            new MemoryToolkit($memory, ...),     // 4 tools: save, recall, search, store_skill
        ];
    }
}
// Total: 6 tools instead of 19+4 = 23 tools
// Tokens: ~400 instead of ~4,600

Response Format

Every exec() returns a structured response:

{
    "code": 0,
    "data": { "entries": [...], "count": 7 },
    "error": null,
    "meta": {
        "command": "file:list --path /my/project",
        "type": "exec",
        "duration_ms": 1.1
    }
}
Code Meaning
0 Success
1 Error
2 Command not found
124 Timeout
126 Blocked (dangerous pattern)
127 Execution failed

Safety

  • Blocked commands: rm -rf /, mkfs, dd if=, fork bombs — rejected before execution
  • Timeout: Default 30s, configurable per command via --timeout
  • Dangerous flag: Commands marked dangerous: true are visible in search results so the LLM can make informed decisions
  • Argument escaping: escapeshellarg() on user-provided values
  • Structured output: Commands return arrays, never raw shell output

Configuration

use PHPAgentShell\AgentShell;
use PHPAgentShell\Executor\ShellExecutor;

$executor = new ShellExecutor(
    defaultTimeout: 30,         // seconds
    workingDir: '/my/project',  // default cwd
    env: ['MY_VAR' => 'value'], // extra env vars
    blockedCommands: ['rm -rf /'], // additional blocks
);

$shell = new AgentShell(
    embedFn: fn(string $t) => embed($t),
    dimensions: 768,
    executor: $executor,
);

Embedding Providers

PHPAgentShell needs an embedding function to index and search commands. Any provider works:

// Cloudflare (free)
$shell = new AgentShell(fn($t) => cfEmbed($t), 768);

// OpenAI
$shell = new AgentShell(fn($t) => openaiEmbed($t), 1536);

// Ollama (local)
$shell = new AgentShell(fn($t) => ollamaEmbed($t), 768);

Testing

composer install
vendor/bin/phpunit                  # 26 tests, 59 assertions

# Demo with real embeddings (requires Cloudflare)
CF_ACCOUNT_ID=xxx CF_API_TOKEN=xxx php tests/demo-shell.php

Architecture

┌─────────────────────────────────────────────────────────┐
│                      AgentShell                          │
│                    help() + exec()                       │
├──────────┬──────────────────┬───────────────────────────┤
│  Parser  │  CommandRegistry  │     ShellExecutor          │
│          │  + VectorSearch   │     proc_open + timeout    │
├──────────┴──────────────────┴───────────────────────────┤
│                    19 Built-in Skills                    │
│  shell · file · git · http · json · env · process        │
├─────────────────────────────────────────────────────────┤
│                   php-vector-store                        │
│            HybridSearch (BM25 + Vector RRF)              │
└─────────────────────────────────────────────────────────┘

The PHP AI Agent Ecosystem

Package Purpose Analogy
php-vector-store Vector database The storage engine
php-agent-memory Agent memory + dream The brain
php-agent-shell CLI execution + discovery The hands
Neuron AI Agent framework The body

License

MIT

About

2-tool AI agent shell for PHP — vector discovery + CLI execution (94% token reduction)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages