Building an Adapter
An adapter connects phpclaw/phpclaw to one framework or CMS: its configuration, its users and
permissions, its database, its command line and its HTTP layer. There is no adapter base class or
interface to implement. Each adapter uses the platform’s own idioms and calls the same core classes.
Which guide
Section titled “Which guide”- Framework Adapter Guide: Composer-installed, configured in code or environment variables, no admin screens. Laravel and Symfony ship today; CakePHP, CodeIgniter and Yii are unreleased.
- CMS Adapter Guide: installed through the platform, configured on an admin settings screen, with chat and admin pages. WordPress, Joomla, Drupal, Magento, PrestaShop and OpenCart ship today.
What every adapter hands the app
Section titled “What every adapter hands the app”An agent implementing PhpClaw\Contracts\ClawInterface:
public function send(string $message): AgentResponse;public function stream(string $message, callable $onToken): AgentResponse;public function conversation(string $id = '', array $metadata = []): Conversation;public function sendInConversation(Conversation $conversation, string $message): ConversationTurn;public function streamInConversation(Conversation $conversation, string $message, callable $onToken, ?callable $beforePersist = null): ConversationTurn;public function memory(): ?MemoryInterface;public function storeMessages(): bool;The core pieces every adapter wires
Section titled “The core pieces every adapter wires”| Step | Core API |
|---|---|
| Discover and register built-in classes | PhpClaw\AutoDiscovery\Bootstrap::boot() |
| Register the default guards | GuardRegistry::registerDefaults() |
| Register the platform’s memory drivers | MemoryRegistry::register($slug, $factory) |
| Honour the message-storage setting | new PrivacyAwareMemory($memory, $storeMessages) |
| Add core’s default tools | ToolCatalogue::instantiateDefaults([...]) |
| Remove denied tools | ToolProfileResolver::filter($tools, $deny, $groups) |
| Cap tools for small models | ->maxToolsPerTurn(ToolProfileResolver::maxTools(ToolProfileResolver::resolve($provider, $model))) |
| Ask before changing things | ->approvalGate(new PhpClaw\Agent\CliApprovalGate) |
| Forward lifecycle events to the platform | new HookEventBridge($dispatcher) then ->register() |
| Activate skills | SkillCatalogue::activateDefaults() |
| Boot cloud, only while messages are stored | CloudManager::boot($key, $disable, $signingSecret) |
The agent itself is built with Claw::builder(). See Architecture.
Platform tools
Section titled “Platform tools”A platform tool uses core’s PhpClaw\Tools\Concerns\HasToolExecutionContract. The adapter supplies
two methods that tie it to the platform:
runningInConsole(): bool, true only for the adapter’s own interactive command, never for a queue worker or a web request;callerHasCapability(string $capability): bool, the platform’s permission check.
The tool supplies plan(), perform(), verify(), complete() and requiredCapability(). See
Tools.
Package naming
Section titled “Package naming”Name a community adapter {vendor}/phpclaw-{platform}, for example acme/phpclaw-statamic: lowercase,
no abbreviations. In the PHP namespace, keep the platform’s own spelling, as the shipped adapters do
with PhpClaw\CakePHP and PhpClaw\CodeIgniter.
Before you publish
Section titled “Before you publish”-
composer test,composer lintandcomposer analysepass, with test coverage at 80% or more, the threshold phpClaw’s own packages check. -
Install it on a real copy of the platform and run a message through the command line and HTTP.
-
Check who can reach each tool, and that one user cannot open another user’s conversation.
-
Update
CHANGELOG.md, tag a release, and publish the package to Packagist under its{vendor}/phpclaw-{platform}name.
To contribute an adapter to the monorepo, see Contributing.