PHPackages                             vielhuber/aihelper - 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. [API Development](/categories/api)
4. /
5. vielhuber/aihelper

ActiveLibrary[API Development](/categories/api)

vielhuber/aihelper
==================

Consistent interface for multiple ai providers.

4.7.6(1w ago)11.1k↑228.6%3MITPHPPHP &gt;=8.1

Since Oct 20Pushed 4d agoCompare

[ Source](https://github.com/vielhuber/aihelper)[ Packagist](https://packagist.org/packages/vielhuber/aihelper)[ RSS](/packages/vielhuber-aihelper/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (48)Versions (378)Used By (3)

[![build status](https://github.com/vielhuber/aihelper/actions/workflows/ci.yml/badge.svg)](https://github.com/vielhuber/aihelper/actions)[![GitHub Tag](https://camo.githubusercontent.com/093deb68f473564b6cc0cfd8f75de094b939d844a4c1ac77c2e37c75ce29a2ba/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f7669656c68756265722f616968656c706572)](https://github.com/vielhuber/aihelper/tags)[![Code Style](https://camo.githubusercontent.com/1540f8ce219727155ab62506c77b818b720421c22c4cf0b18a5f160942132e2d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d7073722d2d31322d6666363962342e737667)](https://www.php-fig.org/psr/psr-12/)[![License](https://camo.githubusercontent.com/b6999e34e91c6aff9e76d15faff6b0399f4246bfa7da0279a343a281cb051618/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7669656c68756265722f616968656c706572)](https://github.com/vielhuber/aihelper/blob/main/LICENSE.md)[![Last Commit](https://camo.githubusercontent.com/4f8f3279b53301d82666a1a82facbc3505cb6bf3d1ae82e64812f2946335fc73/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f7669656c68756265722f616968656c706572)](https://github.com/vielhuber/aihelper/commits)[![PHP Version Support](https://camo.githubusercontent.com/4cb09b895d65e34a510d8d4e8ee5a80f5c86c44da643d16c762ce300a9210d61/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7669656c68756265722f616968656c706572)](https://packagist.org/packages/vielhuber/aihelper)[![Packagist Downloads](https://camo.githubusercontent.com/3a0274f801f7021d287159b26d2a8bd7909c70664f26a3ee93aaf2debb08b41b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7669656c68756265722f616968656c706572)](https://packagist.org/packages/vielhuber/aihelper)

🤖 aihelper 🤖
============

[](#-aihelper-)

aihelper provides a single, consistent php interface for multiple ai providers. it supports chat and vision use cases, session-aware conversations, robust retry logic, logging, simple cost tracking, and optional model context protocol (mcp) integration — all behind one method.

installation
------------

[](#installation)

```
composer require vielhuber/aihelper

```

usage
-----

[](#usage)

```
use vielhuber\aihelper\aihelper;

$ai = aihelper::create(
    provider: 'anthropic', // anthropic|google|openai|xai|deepseek|openrouter|cliproxyapi|elevenlabs|nvidia|llamacpp|lmstudio|claudecode|codex|opencode
    model: 'claude-opus-4-1', // claude-opus-4-1|gemini-2.5-pro|gpt-5|grok-4|deepseek-chat|qwen/qwen3-coder-next|...
    effort: null, // null|none|minimal|low|medium|high|xhigh|max — reasoning effort, ignored when the provider/model has no supported reasoning control
    temperature: 1.0, // controls the randomness of the text generated
    api_key: '**API Key**',
    log: 'output.log',
    max_tries: 1,
    timeout: 300, // maximum timeout (increase for long tasks)
    mcp_servers: [
        [
            'name' => 'example-mcp',
            'url' => 'https://modelcontextprotocol.io/mcp',
            'authorization_token' => '...',
            'allowed_tools' => ['tool_name_1', 'tool_name_2'], // optional: restrict to specific tools (null or omit = all tools allowed)
            'default_tool_arguments' => ['tool_name_1' => ['optional_argument' => 'default']],
            'forced_tool_arguments' => ['tool_name_1' => ['fixed_argument' => 'value']]
        ]
    ],
    mcp_servers_call_type: 'remote', // remote = provider calls mcp servers directly, local = client-side tool loop via aihelper
    session_id: null, // submit session to continue a conversation (get with $ai->getSessionId())
    history: null, // submit messages (get with $ai->getSessionContent()),
    system_prompt: null, // works with every provider — cli harnesses receive it as a real system prompt, everyone else gets it prepended to the session (same as writing it into `history` yourself or calling $ai->setSystemPrompt() later)
    stream: false,
    url: null, // overwrite connection url (e.g. for llamacpp/lmstudio)
    enable_thinking: null, // true|false|null — force reasoning/thinking on/off; null = provider default (see below)
    auto_compact: false // true = transparently compact the session when it approaches the model's context window
);

$ai->ask(prompt: 'Wer wurde 2018 Fußball-Weltmeister?');
// ['response' => 'Frankreich.', 'success' => true, 'costs' => 0.001]

$ai->ask(prompt: 'Was ist auf dem Bild zu sehen?', files: 'lorem.jpg');
// ['response' => 'Auf dem Bild ist eine Katze zu sehen.', 'success' => true, 'costs' => 0.001]

$ai->ask(prompt: 'Was wird in der Audiodatei gesagt?', files: 'lorem.mp3');
// ['response' => 'In der Aufnahme wird gesagt: "Hallo, wie geht es dir?"', 'success' => true, 'costs' => 0.001]

$ai->ask(prompt: 'Wie lautet das erste Wort in der PDF?', files: 'lorem.pdf');
// ['response' => 'Das erste Wort lautet "Lorem".', 'success' => true, 'costs' => 0.001]

$ai->ask(prompt: 'Fasse die folgenden Dokumente zusammen.', files: ['1.pdf', '2.jpg']);
// ['response' => '...', 'success' => true, 'costs' => 0.001]

$ai->ask(prompt: 'Was habe ich vorher gefragt?');
// ['response' => 'Du hast gefragt: "Wie lautet das erste Wort in der PDF?"', 'success' => true, 'costs' => 0.001]

$ai = aihelper::create(provider: 'openai', model: 'gpt-image-1', api_key: '**API Key**');

$ai->image(
    prompt: 'a red cat on a blue couch',  // text description of the desired image
    size: '1024x1024',                    // e.g. '512x512'|'1024x1024'|'1792x1024'
    n: 1,                                 // number of images to generate
    input_file: null,                     // path|url|base64 — switches to edit/variation mode
    output_file: null                     // path — when set, file is written and the path is returned instead base64
);
// ['response' => 'iVBORw0KGgo...', 'success' => true, 'costs' => 0.04]

$ai->image(prompt: 'a red cat on a blue couch', output_file: '/tmp/cat.png');
// ['response' => '/tmp/cat.png', 'success' => true, 'costs' => 0.04]

$ai->image(prompt: 'a red cat on a blue couch', n: 3, output_file: '/tmp/cat.png');
// ['response' => ['/tmp/cat-1.png', '/tmp/cat-2.png', '/tmp/cat-3.png'], 'success' => true, 'costs' => 0.12]

$ai->image(prompt: 'add a hat', input_file: 'cat.png'); // edit / variation

$ai = aihelper::create(provider: 'openai', model: 'gpt-4o-mini-tts', api_key: '**API Key**');

$ai->audio(
    prompt: 'Hallo, wie geht es dir?', // text to synthesize
    voice: 'alloy',                    // provider voice id (e.g. 'alloy'|'echo'|'nova')
    speed: null,                       // optional, e.g 1.2
    output_file: null                  // path — when set, file is written and the path is returned instead base64
);
// ['response' => 'SUQzBAA...', 'success' => true, 'costs' => 0.001]

$ai->audio(prompt: 'Hallo, wie geht es dir?', output_file: '/tmp/hi.mp3');
// ['response' => '/tmp/hi.mp3', 'success' => true, 'costs' => 0.001]

aihelper::getProviders() // gets overview of providers and models with costs and additional infos

aihelper::create(provider: '...', api_key: '...')->fetchModels() // get resolved model catalog

$ai->ping() // gets health, returns true|false

$ai->getSessionId() // get current session id

$ai->getSessionContent() // gets messages in chat history

// manually populate history
$ai = aihelper::create(...);
$ai->prependPromptToSession(prompt: '...', files: [...]);
$ai->appendPromptToSession(prompt: '...', files: [...]);

aihelper::getMcpOnlineStatus(
    url: 'https://modelcontextprotocol.io/mcp',
    authorization_token: '...'
);
// true|false

aihelper::getMcpMetaInfo(
    url: 'https://modelcontextprotocol.io/mcp',
    authorization_token: '...'
);
// ['name' => '...', 'online' => true, 'instructions' => '...', 'tools' => ['...']]

aihelper::callMcpTool(
    name: 'foo-123',
    args: ['foo' => 'bar'],
    url: 'https://modelcontextprotocol.io/mcp',
    authorization_token: '...'
);
// ['jsonrpc' => '2.0', 'id' => 123, 'result' => ['content' => [['type' => 'text', 'text' => '...']]]]
```

### cli harnesses

[](#cli-harnesses)

the providers `claudecode`, `codex` and `opencode` drive the locally installed cli agent instead of a chat completion endpoint. they own their system prompt, tools and history, so only the newest user turn is handed over. install and log them in once:

```
npm i -g @anthropic-ai/claude-code @openai/codex
curl -fsSL https://opencode.ai/install | bash
claude auth login
codex login --device-auth
opencode auth login

```

every turn continues the newest thread of `cli_workdir` and opens a new one only when that directory has none yet. codex keeps injected config and skills isolated per aihelper session while storing its threads in the native `~/.codex` state. to include threads originally started by aihelper's non-interactive `codex exec`, resume from an interactive terminal with `codex resume --last --include-non-interactive`.

set `cli_ssh_host` to run the agent on another machine instead of locally — the working directory, the login and the threads are then that machine's:

```
$ai = aihelper::create(
    provider: 'claudecode',
    system_prompt: 'Du bist ein Assistent für Tabellen und Tickets.',
    cli_workdir: '/var/www/project', // optional, defaults to a throwaway directory per session
    cli_ssh_host: 'host.docker.internal', // optional, runs locally when omitted
    cli_ssh_user: 'root', // optional
    cli_ssh_port: 22, // optional
    cli_ssh_key: '/root/.ssh/id_ed25519', // optional
    cli_skills: [
        'excel' =>
            "---\nname: excel\ndescription: create and read xlsx files. use for tables and grades.\n---\n\nuse the excel_create_file tool ...",
        'jira' =>
            "---\nname: jira\ndescription: read jira issues via jql. use for tickets, sprints, backlogs.\n---\n\n..."
    ]
);
// get cli usage limits for claude code, codex, opencode and antigravity
// to get exact opencode go usage limits, sign in at `https://opencode.ai`,
// set OPENCODE_GO_AUTH_COOKIE in .env to the value of cookie "auth"
$ai->getCliUsageLimits()
// [
//     ['type' => '5-hour', 'scope' => null, 'percent used' => 20, 'resets_at' => '2026-06-29T17:59:00+02:00'],
//     ['type' => 'weekly', 'scope' => null, 'percent used' => 10, 'resets_at' => '2026-07-06T03:03:00+02:00'],
//     ['type' => 'weekly', 'scope' => 'Fable', 'percent used' => 93, 'resets_at' => '2026-07-06T03:03:00+02:00']
// ]

// get manually redeemable codex reset credits
$ai->getCliUsageResetCredits()
// ['available_count' => 1, 'credits' => [['title' => 'Full reset', 'expires_at' => '...']]]

// redeem the next available codex reset credit
$ai->triggerCliUsageReset()
// ['success' => true, 'status' => 'reset', 'windows_reset' => 2]

// get all requests from a local clis
aihelper::getCliApiRequests(
    limit: 100, // null: all
    date_from: '2026-07-01 00:00:00', // null: all
    date_until: '2026-07-31 23:59:59', // null: all
    include_body: false,
    group_by: false // true = collapse per project
);

// delete request logs only
aihelper::purgeCliApiRequestLogs(
    date_from: null, // null: all
    date_until: null // null: all
);
```

### streaming

[](#streaming)

aihelper can stream model output to a browser using server‑sent events (see). in this mode the php backend connects to the model provider with http streaming and forwards chunks to the client as sse events in real time. see an example implementation at [/tests/stream/index.html](tests/stream/index.html).

```
$ai = aihelper::create(
    /* ... */
    stream: true
    /* ... */
);

$result = $ai->ask('Wer wurde 2018 Fußball-Weltmeister?');
/* ... */
// echoes stream
/* ... */
// $result = ['response' => 'Frankreich.', 'success' => true, 'costs' => 0.001]
```

`event: reasoning` contains native model reasoning and a provider-independent, redacted process transcript for tool, shell, file, search, plan and skill activity. Large details are shortened only in this visible stream; `getSessionContent()` retains the complete structured tool history. if streaming stutters on apache2 with php‑fpm, be sure that gzip is disabled for the streaming route and also adjust your virtualhost so fastcgi forwards packets immediately (no buffering):

**before**

```

  ...

    SetHandler "proxy:unix:/var/run/php/php8.5-fpm.sock|fcgi://localhost/"

  ...

```

**after**

```

  ...

      SetHandler "proxy:unix:/var/run/php/php8.5-fpm.sock|fcgi://localhost-stream/"
      SetEnv no-gzip 1
      RequestHeader unset Accept-Encoding

      SetHandler "proxy:unix:/var/run/php/php8.5-fpm.sock|fcgi://localhost/"

  ...

```

###  Health Score

53

—

FairBetter than 96% of packages

Maintenance99

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity64

Established project with proven stability

 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.

###  Release Activity

Cadence

Every ~1 days

Total

377

Last Release

11d ago

Major Versions

1.9.9 → 2.0.02026-03-03

2.9.9 → 3.0.02026-04-26

3.9.9 → 4.0.02026-07-08

PHP version history (2 changes)1.0.0PHP &gt;=7.1

1.1.4PHP &gt;=8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3183737?v=4)[David Vielhuber](/maintainers/vielhuber)[@vielhuber](https://github.com/vielhuber)

---

Top Contributors

[![vielhuber](https://avatars.githubusercontent.com/u/3183737?v=4)](https://github.com/vielhuber "vielhuber (411 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/vielhuber-aihelper/health.svg)

```
[![Health](https://phpackages.com/badges/vielhuber-aihelper/health.svg)](https://phpackages.com/packages/vielhuber-aihelper)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k6.0M777](/packages/sylius-sylius)[knuckleswtf/scribe

Generate API documentation for humans from your Laravel codebase.✍

2.3k15.0M69](/packages/knuckleswtf-scribe)[ovac/idoc

Generate beautiful API documentation from your Laravel application

185487.0k2](/packages/ovac-idoc)[elgg/elgg

Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications.

1.7k17.3k100](/packages/elgg-elgg)[verbb/formie

The most user-friendly forms plugin for Craft.

101400.6k78](/packages/verbb-formie)[solspace/craft-freeform

The most flexible and user-friendly form building plugin!

54686.7k25](/packages/solspace-craft-freeform)

PHPackages © 2026

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