adachsoft/ai-tool-call

Unified AI tool-calling abstraction for PHP 8.3 with a clean Public API and an extensible SPI for custom tools.

Installs: 3

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/adachsoft/ai-tool-call

v0.2.0 2025-11-12 14:10 UTC

This package is not auto-updated.

Last update: 2025-11-12 13:11:09 UTC


README

Unified AI tool-calling abstraction for PHP 8.3 with a clean Public API and an extensible SPI for custom tools.

  • Public API to list and call tools via a simple facade.
  • SPI to implement your own tools (providers) in a framework-agnostic way.
  • Zero framework assumptions, manual wiring via a small Builder.
  • Uses adachsoft/collection for strict, immutable collections.

Requirements

  • PHP ^8.3
  • adachsoft/collection ^2.4

Installation

composer require adachsoft/ai-tool-call

Quick Start

use AdachSoft\AiToolCall\PublicApi\Builder\AiToolCallFacadeBuilder;
use AdachSoft\AiToolCall\PublicApi\Dto\ToolCallRequestDto;

$facade = (new AiToolCallFacadeBuilder())
    ->withToolDirectory(__DIR__ . '/src/Infrastructure/Tools') // optional, default points to package tools directory
    ->build();

// List available tools
$tools = $facade->listAvailableTools();
foreach ($tools as $tool) {
    echo $tool->name . PHP_EOL;
}

// Call a tool
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'current_datetime',
    parameters: []
));

var_dump($result->result);

Public API

  • Facade: AdachSoft\AiToolCall\PublicApi\AiToolCallFacadeInterface
    • callTool(ToolCallRequestDto): ToolCallResultDto
    • listAvailableTools(): AvailableToolCollection
    • listAvailableToolsByTags(array $tags): AvailableToolCollection

DTOs

  • ToolCallRequestDto(string $toolName, array $parameters)
  • ToolCallResultDto(string $toolName, mixed $result)
  • AvailableToolDto(string $name, string $description, array $parametersSchema, array $tags)
  • AvailableToolCollection
  • ToolConfigurationDto(string $toolName, array $arguments = [], ?bool $enabled = null)

SPI (Service Provider Interface)

Implement custom tools by fulfilling the SPI contracts.

  • AdachSoft\AiToolCall\SPI\ToolInterface

    • callTool(ToolCallRequestDto): ToolCallResultDto
    • static getDefinition(): ToolDefinitionDto
    • configure(ConfigMap): void
    • static factory(): ?ToolFactoryInterface
  • ToolDefinitionDto

    • name: string
    • description: string
    • parametersSchema: array<string, mixed>
    • tags: TagsCollection
    • enabled: bool
  • Collections used in SPI:

    • TagsCollection (immutable list of strings)
    • KeyValueMap (immutable map string->mixed)
    • ConfigMap (immutable map string->mixed)
  • Optional factory:

    • AdachSoft\AiToolCall\SPI\Factory\ToolFactoryInterface

Minimal tool example

use AdachSoft\AiToolCall\SPI\ToolInterface;
use AdachSoft\AiToolCall\SPI\Dto\ToolDefinitionDto;
use AdachSoft\AiToolCall\SPI\Dto\ToolCallRequestDto as SpiRequest;
use AdachSoft\AiToolCall\SPI\Dto\ToolCallResultDto as SpiResult;
use AdachSoft\AiToolCall\SPI\Collection\TagsCollection;
use AdachSoft\AiToolCall\SPI\Collection\KeyValueMap;

final class EchoTool implements ToolInterface
{
    public static function getDefinition(): ToolDefinitionDto
    {
        return new ToolDefinitionDto(
            name: 'echo',
            description: 'Returns input as output',
            parametersSchema: ['type' => 'object', 'properties' => ['text' => ['type' => 'string']]],
            tags: new TagsCollection(['demo']),
            enabled: true,
        );
    }

    public function callTool(SpiRequest $request): SpiResult
    {
        return new SpiResult('echo', new KeyValueMap(['text' => $request->parameters->get('text')]));
    }

    public function configure(\AdachSoft\AiToolCall\SPI\Collection\ConfigMap $config): void
    {
        // optional configuration
    }

    public static function factory(): ?\AdachSoft\AiToolCall\SPI\Factory\ToolFactoryInterface
    {
        return null; // or return a factory instance
    }
}

Tool discovery & configuration

  • The builder loads tools from a directory (default points to package tools) via Infrastructure\Provider\DirectoryToolProvider.
  • You can add SPI tools or factories using the builder:
    $facade = (new AiToolCallFacadeBuilder())
      ->withToolDirectory('/path/to/my/tools')
      ->withSpiTools([new EchoTool()])
      ->withToolConfigurations([
          new \AdachSoft\AiToolCall\PublicApi\Dto\ToolConfigurationDto('echo', enabled: true)
      ])
      ->build();
    

Error handling

  • Public API throws PublicApi\Exception\ToolCallFailedException on errors.
  • SPI exceptions:
    • SPI\Exception\InvalidToolCallException
    • SPI\Exception\ToolExecutionException These are mapped through the adapter when calling SPI tools through the Domain.

Versioning

  • Semantic Versioning.
  • Package version is controlled by Git tags (do not set version in composer.json).
  • Proposed first release tag: v0.1.0.

License

MIT