PHPackages                             pressgang-wp/helm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. pressgang-wp/helm

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

pressgang-wp/helm
=================

Provider-agnostic AI orchestration layer for the PressGang ecosystem.

00PHP

Since Feb 20Pushed 2mo agoCompare

[ Source](https://github.com/pressgang-wp/pressgang-helm)[ Packagist](https://packagist.org/packages/pressgang-wp/helm)[ RSS](/packages/pressgang-wp-helm/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

🛞 PressGang Helm
================

[](#-pressgang-helm)

**Helm is the AI orchestration layer for PressGang.**
Provider-agnostic, WordPress-friendly, and built for production workflows: chat, tools, and schema-constrained output without locking your stack to a single model vendor. Take the helm of your AI features without drifting into provider lock-in.

✅ Requirements
--------------

[](#-requirements)

- PHP `^8.3`

🚀 Installation
--------------

[](#-installation)

```
composer require pressgang-wp/helm
```

🌊 Why Helm
----------

[](#-why-helm)

- ⚓ Provider-agnostic core (`OpenAI`, `Anthropic`, `Gemini`, `Fake`)
- 🧰 Tool execution loop with explicit contracts and max-step guardrails
- 🧱 Structured output with JSON schema validation + repair retries
- 🧪 High test coverage and deterministic DTO contracts
- 🧩 PressGang adapter: zero-setup boot from `config/helm.php`
- 🛟 Clear failure modes with typed exceptions for safer debugging

📦 Current Status
----------------

[](#-current-status)

Implemented:

- Core public API: `Helm`, `ChatBuilder`, DTOs, contracts
- Providers: `OpenAiProvider`, `AnthropicProvider`, `GeminiProvider`, `FakeProvider`
- WordPress transport: `WpHttpTransport`
- Tool execution loop:
    - register tools via `->tools([...])` (`ToolContract` implementations)
    - provider tool-call parsing (`ToolCall`)
    - tool result replay into conversation (`ToolResult`)
    - `->maxSteps()` guard
- Structured output:
    - `->jsonSchema([...])` validation
    - `StructuredResponse` return type
    - `SchemaValidationException` with validation errors/raw output/request context
    - `->repair(n)` retry with validation feedback
- PressGang adapter:
    - `HelmServiceProvider` boots Helm from `config/helm.php`
    - `HookAwareProvider` fires lifecycle hooks (`pressgang_helm_request`, `pressgang_helm_response`, `pressgang_helm_error`)
    - Config-driven tool registration via `tools` key in `config/helm.php`
    - Dynamic tool collection via `pressgang_helm_tools` filter
    - Instance access via `pressgang_helm_instance` filter

Not implemented yet (on roadmap):

- Streaming API
- Embeddings API
- Conversation memory store
- Agent abstraction
- Provider failover/retry policy (implemented)

🗺️ What This Means Right Now
----------------------------

[](#️-what-this-means-right-now)

You can already build real provider-backed AI workflows in PHP with typed requests/responses, tool calls, and validated JSON outputs.
If you’re building AI features in PressGang, Helm gives you the stable orchestration surface now while the remaining adapter/runtime layers are finished. In short: you can ship today, then chart the next leg as the roadmap lands.

⚡ Quickstart (Fake Provider)
----------------------------

[](#-quickstart-fake-provider)

New here? Start with `FakeProvider` to learn the API shape before wiring real credentials.

```
use PressGang\Helm\Helm;
use PressGang\Helm\Providers\FakeProvider;

$helm = Helm::make(new FakeProvider(), ['model' => 'gpt-4o']);

$response = $helm
    ->chat()
    ->system('You are concise.')
    ->user('What is WordPress?')
    ->send();

echo $response->content;
```

🤖 Quickstart (OpenAI Provider)
------------------------------

[](#-quickstart-openai-provider)

When you’re ready for live responses, swap in a real provider and keep the same builder flow.

```
use PressGang\Helm\Helm;
use PressGang\Helm\Providers\OpenAiProvider;
use PressGang\Helm\WP\WpHttpTransport;

$config = [
    'provider' => 'openai',
    'model' => 'gpt-4o',
    'api_key' => 'sk-...',
    'timeout' => 30,
    'openai' => [
        'base_url' => 'https://api.openai.com/v1',
    ],
];

$transport = new WpHttpTransport($config);
$provider = new OpenAiProvider($transport, $config);
$helm = Helm::make($provider, $config);

$response = $helm->chat()->user('Say hello in one sentence.')->send();
echo $response->content;
```

🤖 Quickstart (Gemini Provider)
------------------------------

[](#-quickstart-gemini-provider)

```
use PressGang\Helm\Helm;
use PressGang\Helm\Providers\GeminiProvider;
use PressGang\Helm\WP\WpHttpTransport;

$config = [
    'provider' => 'gemini',
    'model' => 'gemini-2.5-flash',
    'api_key' => 'AIza...',
    'timeout' => 30,
    'gemini' => [
        'base_url' => 'https://generativelanguage.googleapis.com/v1beta',
    ],
];

$transport = new WpHttpTransport($config);
$provider = new GeminiProvider($transport, $config);
$helm = Helm::make($provider, $config);

$response = $helm->chat()->user('Say hello in one sentence.')->send();
echo $response->content;
```

🛠️ Tool Loop Example
--------------------

[](#️-tool-loop-example)

Tools are explicit and opt-in: you register them, Helm executes them, and the model gets the results fed back in.

```
use PressGang\Helm\Contracts\ToolContract;

class WeatherTool implements ToolContract
{
    public function name(): string { return 'get_weather'; }
    public function description(): string { return 'Get weather by city'; }
    public function inputSchema(): array {
        return [
            'type' => 'object',
            'properties' => ['city' => ['type' => 'string']],
            'required' => ['city'],
        ];
    }
    public function handle(array $input): array {
        return ['city' => $input['city'] ?? '', 'temp_c' => 21];
    }
}

$response = $helm
    ->chat()
    ->user('What is the weather in London?')
    ->tools([new WeatherTool()])
    ->maxSteps(5)
    ->send();
```

🧾 Structured Output Example
---------------------------

[](#-structured-output-example)

Need reliable payloads for downstream code? Add a schema and keep your output on a steady heading.

```
$response = $helm
    ->chat()
    ->user('Rate this code from 1-10 and explain why.')
    ->jsonSchema([
        'type' => 'object',
        'properties' => [
            'score' => ['type' => 'integer', 'minimum' => 1, 'maximum' => 10],
            'feedback' => ['type' => 'string'],
        ],
        'required' => ['score', 'feedback'],
    ])
    ->repair(1)
    ->send(); // StructuredResponse

echo $response['score'];
echo $response['feedback'];
```

🧩 PressGang Integration
-----------------------

[](#-pressgang-integration)

The `src/WP/` adapter layer is intended for PressGang themes and expects PressGang runtime classes (for example `ServiceProviderInterface` and `Config`). Helm core (`src/` outside `src/WP/`) remains provider-agnostic and framework-agnostic.

### Config

[](#config)

Add `config/helm.php` to your child theme. PressGang's `FileConfigLoader` picks it up automatically:

```
// config/helm.php
return [
    'provider' => 'anthropic',
    'model'    => 'claude-sonnet-4-20250514',
    'api_key'  => defined('HELM_API_KEY') ? HELM_API_KEY : getenv('HELM_API_KEY'),
    'timeout'  => 30,
    'tools'    => [],
];
```

### Service Provider Registration

[](#service-provider-registration)

Register Helm in your PressGang service provider config:

```
// config/service-providers.php
return [
    \PressGang\Helm\WP\HelmServiceProvider::class,
];
```

### Usage

[](#usage)

Retrieve the Helm instance anywhere in your theme:

```
$helm = apply_filters('pressgang_helm_instance', null);

$response = $helm
    ->chat()
    ->user('Summarise this page for accessibility.')
    ->send();

echo $response->content;
```

### Register Tools

[](#register-tools)

For static theme-level tools, set classes in `config/helm.php`:

```
return [
    'provider' => 'anthropic',
    'model'    => 'claude-sonnet-4-20250514',
    'api_key'  => defined('HELM_API_KEY') ? HELM_API_KEY : getenv('HELM_API_KEY'),
    'tools'    => [
        \App\Ai\Tools\SearchProducts::class,
        \App\Ai\Tools\GetOrderStatus::class,
    ],
];
```

For dynamic/plugin tools, use the `pressgang_helm_tools` filter:

```
add_filter('pressgang_helm_tools', function (array $tools) {
    $tools[] = new App\Ai\Tools\SearchProducts();
    $tools[] = new App\Ai\Tools\GetOrderStatus();
    return $tools;
});
```

### Retry &amp; Provider Failover

[](#retry--provider-failover)

Helm retries transient API failures (timeouts, 429 rate limits, 5xx server errors) with exponential backoff. Set retries in config or per-request:

```
// config/helm.php
return [
    'provider'  => 'openai',
    'model'     => 'gpt-4o',
    'api_key'   => defined('HELM_API_KEY') ? HELM_API_KEY : getenv('HELM_API_KEY'),
    'retries'   => 2,  // retry transient failures up to 2 times
    'fallback_providers' => ['anthropic', 'gemini'],  // try Anthropic then Gemini if OpenAI exhausted
    'anthropic' => [
        'api_key'     => defined('HELM_ANTHROPIC_KEY') ? HELM_ANTHROPIC_KEY : getenv('HELM_ANTHROPIC_KEY'),
        'base_url'    => 'https://api.anthropic.com/v1',
        'max_tokens'  => 4096,
        'api_version' => '2023-06-01',
    ],
    'gemini' => [
        'api_key'  => defined('HELM_GEMINI_KEY') ? HELM_GEMINI_KEY : getenv('HELM_GEMINI_KEY'),
        'base_url' => 'https://generativelanguage.googleapis.com/v1beta',
    ],
];
```

Override per-request via the builder:

```
$response = $helm
    ->chat()
    ->retries(3)
    ->fallbackProviders([$backupProvider])
    ->user('Hello')
    ->send();
```

Client errors (400, 401, 403, 404) are never retried — they skip directly to the next provider. All existing lifecycle hooks fire for each attempt, giving full observability.

Failure semantics:

- Retryable errors: `0` (timeout/network), `429`, and `500-599`.
- Non-retryable errors: client errors such as `400`, `401`, `403`, `404`.
- Fallback providers are tried in configured order after the primary is exhausted.
- Cross-provider fallback requires provider-specific credentials (for example `helm.anthropic.api_key` when falling back from OpenAI to Anthropic).

### Lifecycle Hooks

[](#lifecycle-hooks)

`HookAwareProvider` wraps every provider call with WordPress actions:

HookTypePayload`pressgang_helm_request`action`ChatRequest``pressgang_helm_response`action`Response`, `ChatRequest``pressgang_helm_error`action`Throwable`, `ChatRequest`Use these for logging, metrics, or debugging:

```
add_action('pressgang_helm_response', function ($response, $request) {
    error_log("Helm: {$request->model} returned " . strlen($response->content) . " chars");
}, 10, 2);
```

🧪 Testing
---------

[](#-testing)

Run test suite:

```
vendor/bin/phpunit -c phpunit.xml.dist --testdox
```

🧭 Roadmap
---------

[](#-roadmap)

See `docs/roadmap/` for milestone docs.

If you’re wondering what to build next, start with provider + schema-backed flows, then add adapter/runtime integrations.

📄 License
---------

[](#-license)

MIT

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance56

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1303610?v=4)[Benedict](/maintainers/benedict-w)[@benedict-w](https://github.com/benedict-w)

---

Top Contributors

[![benedict-w](https://avatars.githubusercontent.com/u/1303610?v=4)](https://github.com/benedict-w "benedict-w (14 commits)")

---

Tags

aianthropic-aigemini-aiopen-aiphptheme-developmentwordpress

### Embed Badge

![Health badge](/badges/pressgang-wp-helm/health.svg)

```
[![Health](https://phpackages.com/badges/pressgang-wp-helm/health.svg)](https://phpackages.com/packages/pressgang-wp-helm)
```

###  Alternatives

[eadesigndev/module-fullbreadcrumbs

Full breadcrumbs for product page

223.9k](/packages/eadesigndev-module-fullbreadcrumbs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
