PHP Classes

How to Implement PHP AI Prompt to Orchestrate Tools that Execute Automated Actions Using the Package POML Toolkit: Process prompts and execute actions with tools

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2025-09-15 (17 hours ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
poml-toolkit 1.0Custom (specified...7Web services, Artificial intelligence, P...
Description 

Author

This package can process prompts and execute actions with tools.

It can parse code in an XML format named POML (Prompt Orchestration Markup Language) that defines a sequence or one or more prompts that can query the artificial intelligence engines using a given prompt query and extract the results of the artificial intelligence engine.

The POML source code can also define clauses that evaluate conditions using assigned variables and execute actions using tools also provide by the package.

Currently, it can:

- Prompt Execution: Send prompts to AI models via connectors (e.g., dummy for testing or HTTP for real APIs like OpenAI).

- Tool Integration: Call PHP functions as tools within the workflow, with parameter resolution from state.

- Conditional Logic: Support for if/else steps with simple condition evaluation (e.g., {{var}} == 'value').

- Variable Extraction: Automatically extract values from JSON responses into state variables.

- State Management: Persistent state across steps for variable sharing and result tracking.

- Error Handling: Custom exceptions for engine and parser errors.
Architecture

Picture of Juan Camacho
  Performance   Level  
Name: Juan Camacho <contact>
Classes: 10 packages by
Country: Spain Spain
Age: 46
All time rank: 4036108 in Spain Spain
Week rank: 195 Up5 in Spain Spain Up
Innovation award
Innovation award
Nominee: 4x

Winner: 1x

Instructions

Please read this document learn more about the feature and how to create prompts that query artificial intelligence engines and execute automated actions with tools.

Example

<?php
declare(strict_types=1);

require
'vendor/autoload.php';


use
Poml\Toolkit\OrchestrationEngine;
use
Poml\Toolkit\Parsing\PomlParser;
use
Poml\Toolkit\Connectors\DummyConnector;
use
Poml\Toolkit\Connectors\HttpConnector;

echo
"--- POML Toolkit Advanced Example ---\\n\\n";

// 1. Define a tool (a simple PHP function)
function send_notification(string $message): string {
   
$output = "NOTIFICATION SENT: {$message}\\n";
    echo
$output;
    return
"Sent successfully";
}

// 2. Define the complex POML workflow
$pomlXml = <<<'XML'
<?xml version="1.0"?>
<poml>
    <prompt model="json-generator">
        <message>Generate a JSON object with a user 'name' and a 'status' of 'active'.</message>
        <!-- Extract the status field from the JSON response into a variable called 'user_status' -->
        <variable name="user_status" from="json" path="status"/>
    </prompt>

    <!-- Check the variable we just extracted -->
    <if condition="{{user_status}} == 'active'">
        <tool function="notify">
            <param name="message">User is active, proceeding to next step.</param>
        </tool>
        <else>
            <tool function="notify">
                <param name="message">User is not active, aborting.</param>
            </tool>
        </else>
    </if>
</poml>
XML;

// 3. Set up the Orchestration Engine
$engine = new OrchestrationEngine();
$parser = new PomlParser();

// 4. Register tools and connectors
$engine->registerTool('notify', 'send_notification');

// Use a DummyConnector that returns a valid JSON for this example.
class JsonDummyConnector extends DummyConnector {
    public function
execute(string $prompt): string {
        return
'{"name": "John Doe", "status": "active"}';
    }
}
$engine->registerConnector('json-generator', new JsonDummyConnector());

/*
// To use a real HTTP endpoint, you would do this instead:
$apiKey = getenv('OPENAI_API_KEY'); // It's best practice to use environment variables
$apiUrl = 'https://api.openai.com/v1/chat/completions';
$engine->registerConnector(
    'gpt-4',
    new HttpConnector($apiUrl, 'gpt-4', $apiKey)
);
*/

// 5. Parse and run the orchestration
try {
    echo
"Parsing POML...\\n";
   
$orchestration = $parser->parse($pomlXml);

    echo
"Running orchestration...\\n\\n";
   
$finalResult = $engine->run($orchestration);

    echo
"\\nOrchestration finished.\\n";
    echo
"Final Result (from 'last_result'): " . print_r($finalResult, true) . "\\n";

} catch (\
Exception $e) {
    echo
"\\nAn error occurred: " . $e->getMessage() . "\\n";
    echo
"Trace: \\n" . $e->getTraceAsString() . "\\n";
}


Details

POML Toolkit

Overview

The POML Toolkit is a PHP-based orchestration engine designed to manage complex prompt workflows using a custom XML-based language called POML (Prompt Orchestration Markup Language). Its primary purpose is to enable developers to define, parse, and execute multi-step AI prompt chains that integrate with language models, custom tools, conditional logic, and state management. This toolkit is particularly useful for building AI-driven applications where prompts need to be sequenced, variables extracted from responses, and decisions made based on runtime conditions.

Key Features

  • Prompt Execution: Send prompts to AI models via connectors (e.g., dummy for testing or HTTP for real APIs like OpenAI).
  • Tool Integration: Call PHP functions as tools within the workflow, with parameter resolution from state.
  • Conditional Logic: Support for if/else steps with simple condition evaluation (e.g., `{{var}} == 'value'`).
  • Variable Extraction: Automatically extract values from JSON responses into state variables.
  • State Management: Persistent state across steps for variable sharing and result tracking.
  • Error Handling: Custom exceptions for engine and parser errors.

Architecture

The toolkit follows a modular design with the following core components:

  • Steps (Implement StepInterface): Abstract interface for executable steps. - `PromptStep`: Executes a prompt via a connector and extracts variables. - `ToolStep`: Invokes a registered PHP callable with resolved parameters. - `ConditionalStep`: Evaluates a condition and executes then/else branches.
  • Orchestration: Container for a sequence of steps parsed from POML XML.
  • Connectors (Implement ModelConnectorInterface): Interfaces for AI model interactions. - `DummyConnector`: For testing, returns predefined responses. - `HttpConnector`: For real HTTP-based API calls (e.g., to OpenAI).
  • PomlParser: Parses POML XML using SimpleXML, validating structure and building step objects.
  • OrchestrationEngine: Central executor that registers connectors/tools, runs the orchestration, and manages state via `StateManager`.
  • StateManager: Handles variable resolution (e.g., `{{var}}`), storage, and retrieval.
  • Exceptions: `EngineException` for runtime errors, `ParserException` for XML issues.

Dependencies

From composer.json: - PHP ^8.0 (strict types enforced). - Autoloading via PSR-4 for Poml\Toolkit\ namespace mapping to src/. No external libraries are required beyond PHP's built-in extensions (e.g., SimpleXML for parsing, cURL implicitly via HTTP connector if used).

Architecture Diagram

graph TD
    A[Poml XML Input] --> B[PomlParser]
    B --> C[Orchestration Object with Steps]
    C --> D[OrchestrationEngine]
    D --> E[Register Connectors and Tools]
    E --> F[Run Orchestration]
    F --> G[StateManager for Variables and Results]
    G --> H[Execute Steps: Prompt, Tool, Conditional]
    H --> I[Connectors: Dummy or HTTP]
    I --> J[Tools: PHP Callables]
    J --> G
    H --> K[Variable Extraction from JSON]
    K --> G
    L[Conditional Evaluation] --> M[Then/Else Branches]
    M --> H

Implemented Changes and Improvements

This version includes several enhancements based on best practices for robustness and maintainability:

  • Autoloader Improvements: Switched to PSR-4 compliant autoloading for better namespace organization and Composer integration.
  • Error Handling Refactor: Introduced specific exceptions (`EngineException`, `ParserException`) instead of generic ones. For example, connector/tool not found throws `EngineException`; invalid XML throws `ParserException` with detailed libxml errors.
  • Step Refactorizations: `StepInterface` now enforces a clean `execute(StateManager $state): mixed` contract. Subclasses like `PromptStep` handle JSON decoding safely with `json_last_error()` checks. `ConditionalStep` uses regex for simple condition parsing (e.g., equality checks) with fallback to truthy evaluation.
  • Optimizations: Parsing uses efficient SimpleXML with internal error suppression and clear/reset. Engine execution avoids recursion depth issues by linear step processing; conditional branches are executed sequentially without loops. Variable resolution in `StateManager` (not shown but inferred) uses string replacement for efficiency.

These changes improve reliability, reduce boilerplate, and enhance debuggability.

Installation Instructions

  1. Prerequisites: Ensure PHP 8.0+ is installed with SimpleXML extension enabled.
  2. Clone or Download: Place the project in your workspace (e.g., `c:/Users/kuasa/Documents/VScode/poml`).
  3. Install Dependencies:
    composer install
    
    This sets up the autoloader; no additional packages are needed.
  4. Configuration: - For testing: No setup required (uses DummyConnector). - For real AI models: Set environment variables, e.g., `export OPENAI_API_KEY=your_key_here` (or use `putenv()` in PHP). - Edit connectors in code if needed (e.g., register `HttpConnector` with API URL and key).
  5. Execution: - Run the example: `php example.php` - This parses a sample POML XML, registers a tool and connector, and executes the workflow, printing outputs.

If issues arise (e.g., missing extensions), check PHP error logs.

Usage Examples

The example.php demonstrates a full workflow: generating JSON, extracting a variable, and conditionally calling a tool.

<?php
declare(strict_types=1);

require 'vendor/autoload.php';

use Poml\Toolkit\OrchestrationEngine;
use Poml\Toolkit\Parsing\PomlParser;
use Poml\Toolkit\Connectors\DummyConnector;
use Poml\Toolkit\Connectors\HttpConnector;

echo "--- POML Toolkit Advanced Example ---\n\n";

// 1. Define a tool (a simple PHP function)
function send_notification(string $message): string {
    $output = "NOTIFICATION SENT: {$message}\n";
    echo $output;
    return "Sent successfully";
}

// 2. Define the complex POML workflow
$pomlXml = <<<'XML'
<?xml version="1.0"?>
<poml>
    <prompt model="json-generator">
        <message>Generate a JSON object with a user 'name' and a 'status' of 'active'.</message>
        <!-- Extract the status field from the JSON response into a variable called 'user_status' -->
        <variable name="user_status" from="json" path="status"/>
    </prompt>

    <!-- Check the variable we just extracted -->
    <if condition="{{user_status}} == 'active'">
        <tool function="notify">
            <param name="message">User is active, proceeding to next step.</param>
        </tool>
        <else>
            <tool function="notify">
                <param name="message">User is not active, aborting.</param>
            </tool>
        </else>
    </if>
</poml>
XML;

// 3. Set up the Orchestration Engine
$engine = new OrchestrationEngine();
$parser = new PomlParser();

// 4. Register tools and connectors
$engine->registerTool('notify', 'send_notification');

// Use a DummyConnector that returns a valid JSON for this example.
class JsonDummyConnector extends DummyConnector {
    public function execute(string $prompt): string {
        return '{"name": "John Doe", "status": "active"}';
    }
}
$engine->registerConnector('json-generator', new JsonDummyConnector());

/*
To use a real HTTP endpoint, you would do this instead:
$apiKey = getenv('OPENAI_API_KEY'); // It's best practice to use environment variables
$apiUrl = 'https://api.openai.com/v1/chat/completions';
$engine->registerConnector(
    'gpt-4',
    new HttpConnector($apiUrl, 'gpt-4', $apiKey)
);
*/

// 5. Parse and run the orchestration
try {
    echo "Parsing POML...\n";
    $orchestration = $parser->parse($pomlXml);

    echo "Running orchestration...\n\n";
    $finalResult = $engine->run($orchestration);

    echo "\nOrchestration finished.\n";
    echo "Final Result (from 'last_result'): " . print_r($finalResult, true) . "\n";

} catch (\Exception $e) {
    echo "\nAn error occurred: " . $e->getMessage() . "\n";
    echo "Trace: \n" . $e->getTraceAsString() . "\n";
}
?>

Expected output includes parsed POML execution, notification sent, and final result.

Best Practices

  • Environment Variables: Always use `getenv()` for sensitive data like API keys to avoid hardcoding.
  • Input Validation: In custom tools, validate parameters to prevent injection attacks (e.g., sanitize strings).
  • Error Handling: Wrap `run()` in try-catch to handle `EngineException` or `ParserException` gracefully.
  • Testing: Use `DummyConnector` for unit tests; mock responses for integration.
  • Scalability: For complex workflows, break into multiple orchestrations; monitor state size to avoid memory issues.
  • POML Design: Keep XML concise; use meaningful variable names; test conditions thoroughly.

Security and Vulnerability Notes

  • Resolved Vulnerabilities: - Connector Errors: Previously unhandled missing connectors now throw `EngineException`, preventing silent failures. - Parsing Issues: XML parsing uses `libxml_use_internal_errors(true)` to suppress warnings and throws `ParserException` on invalid structure, mitigating XML injection risks. - Tool Invocation: Parameters are resolved but not executed as code; use strict types in tools to avoid type errors.
  • Corrected Inefficiencies: - Parsing Optimization: SimpleXML is lightweight; no recursive parsing depth issues. Variable extraction is top-level only for speed. - Condition Evaluation: Regex-based for simple ops, avoiding full expression parsers; no infinite loops as branches are linear.
  • Security Considerations: - Input Validation: POML XML should be trusted or sanitized externally; `resolve()` in StateManager replaces `{{var}}` but doesn't execute code?extend with filters if needed. - API Keys: Never commit keys; use `.env` files (add to `.gitignore`). - JSON Handling: `json_decode` with error checks prevents malformed response crashes. - Recommendations: Run in isolated environments for untrusted POML; audit tools for side effects; use HTTPS for `HttpConnector`.

For contributions or issues, please refer to the code structure in src/.


  Files folder image Files (20)  
File Role Description
Files folder imagesrc (1 file, 5 directories)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file composer.lock Data Auxiliary data
Accessible without login Plain text file example.php Example Example script
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file README.es.md Doc. Read me
Accessible without login Plain text file README.md Doc. Read me

  Files folder image Files (20)  /  src  
File Role Description
Files folder imageConnectors (3 files)
Files folder imageData (6 files)
Files folder imageException (2 files)
Files folder imageParsing (1 file)
Files folder imageState (1 file)
  Plain text file OrchestrationEngine.php Class Class source

  Files folder image Files (20)  /  src  /  Connectors  
File Role Description
  Plain text file DummyConnector.php Class Class source
  Plain text file HttpConnector.php Class Class source
  Plain text file ModelConnectorInterface.php Class Class source

  Files folder image Files (20)  /  src  /  Data  
File Role Description
  Plain text file ConditionalStep.php Class Class source
  Plain text file Orchestration.php Class Class source
  Plain text file PromptStep.php Class Class source
  Plain text file StepInterface.php Class Class source
  Plain text file ToolStep.php Class Class source
  Plain text file VariableExtraction.php Class Class source

  Files folder image Files (20)  /  src  /  Exception  
File Role Description
  Plain text file EngineException.php Class Class source
  Plain text file ParserException.php Class Class source

  Files folder image Files (20)  /  src  /  Parsing  
File Role Description
  Plain text file PomlParser.php Class Class source

  Files folder image Files (20)  /  src  /  State  
File Role Description
  Plain text file StateManager.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads  
 100%
Total:0
This week:0