carmelosantana / php-agents
PHP 8.5 agent framework — interfaces, tools, and providers for building AI agents
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/carmelosantana/php-agents
Requires
- php: ^8.4
- psr/log: ^3.0
- symfony/http-client: ^7.0
Requires (Dev)
- pestphp/pest: ^3.0
- phpstan/phpstan: ^2.0
Suggests
- hkulekci/qdrant: Vector similarity search for persistent agent memory
- yethee/tiktoken-php: Accurate token counting for OpenAI models (cl100k_base, o200k_base)
README
PHP 8.4+ framework for building AI agents with tool-use loops, provider abstraction, and composable toolkits.
Build agents that can read files, browse the web, execute code, and use custom tools — powered by any OpenAI-compatible API, Anthropic, or local models via Ollama.
Features
- Agentic tool-use loop — automatic iteration: the LLM calls tools, processes results, and decides when it's done
- Multi-provider — Ollama (local), OpenAI, Anthropic, OpenRouter, or any OpenAI-compatible endpoint
- Bundled agents —
FileAgent,WebAgent,CodeAgentready to use out of the box - Composable toolkits — filesystem, web, shell, and memory toolkits that snap onto any agent
- Observer pattern — attach
SplObserverto watch agent lifecycle events in real time - OpenClaw config — centralized model routing with aliases, fallbacks, and per-provider settings
- Zero framework coupling — depends only on
symfony/http-clientandpsr/log
Requirements
- PHP 8.4 or later
- Extensions:
curl,json,mbstring - Composer 2.x
- Ollama (recommended for local inference)
Installation
composer require carmelosantana/php-agents
Quick Start
Create an agent that can read files and answer questions about them:
<?php declare(strict_types=1); require 'vendor/autoload.php'; use CarmeloSantana\PHPAgents\Agent\FileAgent; use CarmeloSantana\PHPAgents\Provider\OllamaProvider; use CarmeloSantana\PHPAgents\Message\UserMessage; $provider = new OllamaProvider(model: 'llama3.2'); $agent = new FileAgent( provider: $provider, rootPath: getcwd(), readOnly: true, ); $output = $agent->run(new UserMessage('Summarize the README.md file.')); echo $output->content . "\n";
Make sure Ollama is running:
ollama serveand a model is pulled:ollama pull llama3.2
Bundled Agents
| Agent | Description | Toolkits |
|---|---|---|
FileAgent |
Read, write, search, and manage files within a sandboxed root path | FilesystemToolkit |
WebAgent |
Make HTTP requests and optionally search the web | WebToolkit |
CodeAgent |
Filesystem access + shell command execution with an allowlist | FilesystemToolkit + ShellToolkit |
Providers
use CarmeloSantana\PHPAgents\Provider\OllamaProvider; use CarmeloSantana\PHPAgents\Provider\OpenAICompatibleProvider; use CarmeloSantana\PHPAgents\Provider\AnthropicProvider; // Ollama (local — no API key needed) $provider = new OllamaProvider(model: 'llama3.2'); // OpenAI $provider = new OpenAICompatibleProvider( model: 'gpt-4o', baseUrl: 'https://api.openai.com/v1', apiKey: getenv('OPENAI_API_KEY'), ); // Anthropic $provider = new AnthropicProvider( model: 'claude-sonnet-4-20250514', apiKey: getenv('ANTHROPIC_API_KEY'), );
Creating Custom Agents
Extend AbstractAgent and implement instructions():
<?php declare(strict_types=1); namespace MyPackage; use CarmeloSantana\PHPAgents\Agent\AbstractAgent; use CarmeloSantana\PHPAgents\Contract\ProviderInterface; final class DatabaseAgent extends AbstractAgent { public function __construct(ProviderInterface $provider) { parent::__construct($provider, maxIter: 10); } public function instructions(): string { return 'You are a database agent. Query databases and return results.'; } }
Register toolkits in the constructor with $this->addToolkit() to give your agent capabilities.
Creating Custom Tools
Define tools with typed parameters and a callback:
use CarmeloSantana\PHPAgents\Tool\Tool; use CarmeloSantana\PHPAgents\Tool\ToolResult; use CarmeloSantana\PHPAgents\Tool\Parameter\StringParameter; use CarmeloSantana\PHPAgents\Tool\Parameter\NumberParameter; $tool = new Tool( name: 'word_count', description: 'Count words in the given text', parameters: [ new StringParameter('text', 'The text to count words in', required: true), ], callback: function (array $args): ToolResult { $count = str_word_count($args['text']); return ToolResult::success("Word count: {$count}"); }, );
Group related tools into a toolkit by implementing ToolkitInterface:
use CarmeloSantana\PHPAgents\Contract\ToolkitInterface; final class MyToolkit implements ToolkitInterface { public function tools(): array { return [$this->buildWordCountTool(), /* ... */]; } public function guidelines(): string { return 'Use these tools to analyze text.'; } }
Examples
Working examples live in the examples/ directory:
| Example | Description | Run |
|---|---|---|
| CLI Chat | Interactive terminal conversation with an LLM | php examples/cli-chat.php |
| Web Summarizer | Web UI that auto-summarizes this README using a FileAgent | php -S localhost:8080 -t examples/web-summarizer/ |
Documentation
See QUICKSTART.md for comprehensive documentation including:
- All provider configurations (Ollama, OpenAI, Anthropic, OpenRouter)
ProviderFactoryfor automatic provider routing- Observer pattern for agent event monitoring
openclaw.jsonconfiguration reference- Memory toolkit and vector store usage
- Publishing your own agents as Composer packages
Project Structure
php-agents/
├── src/
│ ├── Agent/ — AbstractAgent, FileAgent, WebAgent, CodeAgent
│ ├── Config/ — OpenClawConfig, ModelDefinition
│ ├── Context/ — ContextWindow, token counting
│ ├── Contract/ — All interfaces
│ ├── Embedding/ — Embedding providers
│ ├── Enum/ — Role, FinishReason, ModelCapability
│ ├── Memory/ — FileMemory, MemoryEntry
│ ├── Message/ — System/User/Assistant messages, Conversation
│ ├── Prompt/ — SystemPrompt builder
│ ├── Provider/ — Provider implementations
│ ├── Tool/ — Tool, ToolResult, Parameters
│ ├── Toolkit/ — Filesystem, Web, Shell, Memory toolkits
│ └── VectorStore/ — In-memory vector search
├── examples/ — Working usage examples
└── tests/ — Pest test suite
License
MIT