PHP code example of forgeomni / superagent

1. Go to this page and download the library: Download forgeomni/superagent library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

forgeomni / superagent example snippets


$agent = new SuperAgent\Agent([
    'provider' => 'openai-responses',
    'model'    => 'gpt-5',
]);

$result = $agent->run('Summarise docs/ADVANCED_USAGE.md in one paragraph');
echo $result->text();

$agent = new SuperAgent\Agent(['provider' => 'anthropic']);
$result = $agent->run('what day is it?');
echo $result->text();

$agent = (new SuperAgent\Agent(['provider' => 'openai']))
    ->loadTools(['read', 'write', 'bash']);

$result = $agent->run('inspect composer.json and tell me what PHP version this project targets');
echo $result->text();

new Agent([
    'provider'         => 'openai',
    'env_http_headers' => [
        'OpenAI-Project'      => 'OPENAI_PROJECT',      // sent only when env set + non-empty
        'OpenAI-Organization' => 'OPENAI_ORGANIZATION',
    ],
    'http_headers' => [
        'x-app' => 'my-host-app',                       // static header
    ],
]);

$agent = new Agent([
    'provider' => 'openai-responses',
    'model'    => 'gpt-5.6-sol',   // default; `gpt-5.6` alias resolves here
]);

$result = $agent->run('analyse this codebase and propose refactors', [
    'reasoning'        => ['effort' => 'high', 'summary' => 'auto'],
    'verbosity'        => 'low',
    'prompt_cache_key' => 'session:42',
    'service_tier'     => 'priority',
    'store'            => true,           // 

new Agent([
    'provider'     => 'openai-responses',
    'access_token' => $token,
    'account_id'   => $accountId,   // adds chatgpt-account-id header
]);

new Agent([
    'provider'          => 'openai-responses',
    'base_url'          => 'https://my-resource.openai.azure.com/openai/deployments/gpt-5',
    'api_key'           => $azureKey,
    'azure_api_version' => '2024-12-01-preview',   // optional override
]);

$tc = SuperAgent\Support\TraceContext::fresh();              // mint fresh
// OR: SuperAgent\Support\TraceContext::parse($headerValue); // from incoming HTTP header

$agent->run($prompt, ['trace_context' => $tc]);
// OR: $agent->run($prompt, ['traceparent' => '00-0af7-...', 'tracestate' => 'v=1']);

use SuperAgent\Conversation\HandoffPolicy;

$agent = new Agent(['provider' => 'anthropic', 'api_key' => $key, 'model' => 'claude-opus-4-7']);
$agent->run('analyse this codebase');

// Hand off to a cheaper / faster model for the next phase:
$agent->switchProvider('kimi', ['api_key' => $kimiKey, 'model' => 'kimi-k3'])
      ->run('write the unit tests');

// Token-window check after switching — different tokenizers count
// the same history differently (Anthropic vs GPT-4 drift 20–30%):
$status = $agent->lastHandoffTokenStatus();
if ($status !== null && ! $status['fits']) {
    // Trigger your existing IncrementalContext compression before the next call.
}

HandoffPolicy::default()      // keep tool history, drop signed thinking, append handoff marker
HandoffPolicy::preserveAll()  // keep everything — useful when swap is temporary and you'll come back
HandoffPolicy::freshStart()   // collapse history to (latest user turn) — fresh shot at a stuck conversation

use SuperAgent\Conversation\Transcoder;
use SuperAgent\Conversation\WireFamily;

$wire = (new Transcoder())->encode($messages, WireFamily::Gemini);

$agent = new Agent([
    'provider' => 'anthropic',
    'api_key'  => getenv('ANTHROPIC_API_KEY'),
    'model'    => 'claude-fable-5',             // or the `fable` alias
]);

// Effort dial → output_config.effort
$agent->run('long-horizon agentic task', ['reasoning_effort' => 'xhigh']);

// Thinking is on by default; drive it explicitly via the features API too
$agent->run('hard reasoning prompt', ['features' => ['thinking' => true]]);

$agent = new Agent([
    'provider' => 'anthropic',
    'api_key'  => getenv('ANTHROPIC_API_KEY'),
    // 'model' => 'claude-opus-5',   // implied — this is the zero-config default
]);

$agent->run('complex agentic coding task', ['reasoning_effort' => 'xhigh']);

$agent = new Agent([
    'provider' => 'openai-responses',
    'model'    => 'gpt-5.6-sol',
]);

$result = $agent->run('design then implement the migration', [
    'reasoning_effort'     => 'max',              // 5.6 dial: none|low|medium|high|xhigh|max
    'reasoning_mode'       => 'pro',              // Sol Pro — same weights, more parallel compute
    'reasoning_context'    => 'all_turns',        // persisted-reasoning reuse across turns
    'prompt_cache_options' => ['mode' => 'explicit'],
]);

$agent = new Agent([
    'provider' => 'grok',
    'api_key'  => getenv('XAI_API_KEY'),
    'model'    => 'grok-4.6',                    // or the `grok` alias
]);

$agent->run('deep agentic coding task', ['reasoning_effort' => 'medium']);

new Agent(['provider' => 'grok', 'conversation_id' => 'session:42']);

// OpenAI-wire: native DeepSeekProvider
$agent = new Agent([
    'provider' => 'deepseek',
    'api_key'  => getenv('DEEPSEEK_API_KEY'),
    'model'    => 'deepseek-v4-pro',           // or 'deepseek-v4-flash'
]);

// Anthropic-wire: reuse AnthropicProvider with a custom base_url
$agent = new Agent([
    'provider' => 'anthropic',
    'api_key'  => getenv('DEEPSEEK_API_KEY'),
    'base_url' => 'https://api.deepseek.com/anthropic',
    'model'    => 'deepseek-v4-pro',
]);

$result = $agent->run('hard reasoning prompt', ['thinking' => true]);

foreach ($result->message()->content as $block) {
    if ($block->type === 'thinking') {
        // model's reasoning chain
    } elseif ($block->type === 'text') {
        // user-facing answer
    }
}

// Cheapest: thinking off entirely.
$agent->run('translate this paragraph', options: ['reasoning_effort' => 'off']);

// Standard thinking budget (V4-Pro tier default).
$agent->run('design a queue with at-least-once semantics', options: ['reasoning_effort' => 'high']);

// Deepest CoT — V4-Pro "think harder". Slower, more expensive.
$agent->run('audit this migration for race conditions', options: ['reasoning_effort' => 'max']);

$agent = new Agent([
    'provider' => 'deepseek',
    'upstream' => 'fireworks',          // or nvidia_nim / novita / openrouter / sglang
    'options'  => ['model' => 'deepseek-v4-pro'],
]);

// Self-hosted SGLang 

$agent = new Agent([
    'provider' => 'deepseek',
    'region'   => 'beta',
]);

$completed = $agent->provider()->completeFim(
    prefix: "function fibonacci(\$n) {\n    ",
    suffix: "\n}\n",
    options: ['max_tokens' => 64],
);

use SuperAgent\Routing\AutoModelStrategy;

$strategy = new AutoModelStrategy();
$model    = $strategy->select($messages, $systemPrompt, $options);
// → 'deepseek-v4-pro' or 'deepseek-v4-flash'

$agent = new Agent([
    'provider' => 'deepseek',
    'options'  => ['model' => $model, 'reasoning_effort' => 'high'],
]);

use SuperAgent\Context\Strategies\CacheAwareCompressor;
use SuperAgent\Context\Strategies\ConversationCompressor;

$compactor = new CacheAwareCompressor(
    delegate:       new ConversationCompressor($estimator, $config, $provider),
    tokenEstimator: $estimator,
    config:         $config,
    pinHead:        4,        // first 4 messages stay byte-stable
    pinSystem:      true,     // also pin the system message
);

$agent = new Agent([
    'provider' => 'minimax',
    'api_key'  => getenv('MINIMAX_API_KEY'),
    'model'    => 'MiniMax-M3',                 // or the `minimax` alias
    'region'   => 'intl',                       // intl | cn
]);

// 1. Direct toggle — 'enabled' | 'disabled' | 'adaptive' (or true)
$agent->run('hard reasoning prompt', ['thinking' => 'adaptive']);

// 2. Reasoning-effort dial — off → disabled, adaptive, low…max → enabled
$agent->run('hard reasoning prompt', ['reasoning_effort' => 'adaptive']);

// 3. Cross-provider features API
$agent->run('hard reasoning prompt', ['features' => ['thinking' => ['budget' => 4000]]]);

$agent = new Agent([
    'provider' => 'glm',
    'api_key'  => getenv('GLM_API_KEY'),
    'model'    => 'glm-5.2',                    // or the `glm` alias
    'region'   => 'intl',                       // intl | cn
]);

// 1. Direct thinking toggle — true | 'enabled' | 'disabled'
$agent->run('hard reasoning prompt', ['thinking' => true]);

// 2. Reasoning-effort dial — off → disabled, low…high → high, max → max
//    (on glm-5.3: off/low → low, medium/high → high, max → max — thinking
//    cannot be disabled there)
$agent->run('hard reasoning prompt', ['reasoning_effort' => 'max']);

// 3. Cross-provider features API
$agent->run('hard reasoning prompt', ['features' => ['thinking' => ['budget' => 4000]]]);

use SuperAgent\Goals\GoalManager;
use SuperAgent\Goals\InMemoryGoalStore;
use SuperAgent\Tools\Builtin\CreateGoalTool;
use SuperAgent\Tools\Builtin\GetGoalTool;
use SuperAgent\Tools\Builtin\UpdateGoalTool;

$threadId = 'session-42';
$goals    = new GoalManager(new InMemoryGoalStore());

$agent->registerTool(new CreateGoalTool($goals, $threadId));
$agent->registerTool(new GetGoalTool($goals, $threadId));
$agent->registerTool(new UpdateGoalTool($goals, $threadId));

// On each turn, account tokens and inject continuation when idle:
$agent->onTurnEnd(function ($usage) use ($goals, $threadId) {
    $goal = $goals->getActive($threadId);
    if ($goal === null) return;
    $updated = $goals->recordUsage($goal->id, $usage->inputTokens + $usage->outputTokens);
    if ($updated->status === GoalStatus::BudgetLimited) {
        $agent->injectSystemMessage($goals->renderBudgetLimitPrompt($updated));
    } elseif ($updated->status === GoalStatus::Active) {
        $agent->injectSystemMessage($goals->renderContinuationPrompt($updated));
    }
});

use SuperAgent\Security\UntrustedInput;

$wrapped = UntrustedInput::wrap($userInput, kind: 'note');
// → "The text below is user-provided data..." + "<untrusted_note>...</untrusted_note>"

use SuperAgent\Swarm\AgentDepthGuard;

// Set the cap (default 5; env: SUPERAGENT_MAX_AGENT_DEPTH).
AgentDepthGuard::setMax(8);

// In the spawn site, before launching the child:
AgentDepthGuard::check();                       // throws AgentDepthExceededException at cap
$childEnv = AgentDepthGuard::forChild();        // pass to proc_open / Symfony\Process

use SuperAgent\Providers\Transport\TokenBucket;

$bucket = new TokenBucket(ratePerSecond: 8.0, burst: 16);

$bucket->consume();          // blocks until capacity
if (! $bucket->tryConsume()) { /* skip / queue */ }

use SuperAgent\Conversation\Fork;

$fork = Fork::from($parentMessages);
$fork->extend(new UserMessage('try the alternative approach'),
              $sideAssistantReply);

// Either discard or promote selected side messages back into parent:
$parentNext = $fork->discard();          // throw the side away
$parentNext = $fork->promote(2);         // bring back side message #2 only
$parentNext = $fork->promoteAll();       // bring everything back

use SuperAgent\Memory\AdHocMemoryProvider;

$adhoc = new AdHocMemoryProvider();
$adhoc->push('CI is currently red on main', ttlSeconds: 1800, untrusted: true);
$adhoc->push('You MUST output JSON', ttlSeconds: 0, untrusted: false);  // sticky + trusted

$memoryManager->setExternalProvider($adhoc);
// Next turn sees both entries via onTurnStart(); ad-hoc is push-only —
// search() returns []. Compose alongside BuiltinMemoryProvider, not in place of.

$agent->loadTools(['grep', 'agent_grep']);   // both registered, pick per call

// Default: regex-based extractor (dependency-free, ~95% accuracy)
$agent->run('find every caller of MyClass::handle and show me which method contains it');

use SuperAgent\Tools\Builtin\AgentGrepTool;
use SuperAgent\Tools\Builtin\Symbols\CompositeSymbolExtractor;
use SuperAgent\Tools\Builtin\Symbols\TreeSitterSymbolExtractor;
use SuperAgent\Tools\Builtin\Symbols\RegexSymbolExtractor;

$agent->registerTool(new AgentGrepTool(symbolExtractor: new CompositeSymbolExtractor([
    new TreeSitterSymbolExtractor(),     // shells out to `tree-sitter` CLI; ~15 grammars
    new RegexSymbolExtractor(),          // pure-PHP fallback; always works
])));

$ledger = $worktreeManager->fileLedger();
$ledger->setEmitter(function (FileShiftedEvent $event, string $toAgent) {
    // event = {path, byAgent, at, summary, shaBefore, shaAfter}
    $mailbox->push($toAgent, $event);
});

$ledger->recordRead($agentB, '/abs/file.php');
$ledger->recordWrite($agentA, '/abs/file.php', shaBefore: '...', shaAfter: '...', summary: 'fixed null guard');
// → emitter fires with toAgent=$agentB

$worker = new AmbientWorker(
    memoryProvider: $memProvider,
    usageReporter:  fn(Usage $u) => $costMeter->record($u, source: 'ambient'),
    passBudgetSeconds: 3,
);

while ($host->running()) {
    $worker->tick();          // call from cron, swoole, react, or plain `while sleep`
    sleep(60);
}

$agent->registerTool(new FirefoxBridgeTool());

$agent->run('open https://example.com, take a screenshot, click the "Sign in" link, screenshot again');

use SuperAgent\Skills\SemanticSkillRouter;
use SuperAgent\Memory\Embeddings\OllamaEmbeddingProvider;

$router = new SemanticSkillRouter(
    embedder: new OllamaEmbeddingProvider(),    // or any EmbeddingProvider
    topK: 5,
);
// Falls back to keyword overlap when no embedder; vector cache keyed by skill content hash.

$result = $agent->run('...', [
    'model'             => 'claude-sonnet-4-5-20250929',  // per-call override
    'max_tokens'        => 8192,
    'temperature'       => 0.3,
    'response_format'   => ['type' => 'json_schema', 'json_schema' => [...]],
    'idempotency_key'   => 'job-42:turn-7',               // since v0.9.1
    'system_prompt'     => 'You are a precise analyst.',
]);

echo $result->text();
$result->turns();          // turn count
$result->totalUsage();     // Usage{inputTokens, outputTokens, cache*}
$result->totalCostUsd;     // float, across all turns
$result->idempotencyKey;   // passthrough for usage-log dedup (since v0.9.1)

$agent = (new Agent(['provider' => 'openai']))
    ->withMaxTurns(50)
    ->withMaxBudget(5.00);            // USD — hard cap; aborts mid-loop if breached

foreach ($agent->stream('...') as $assistantMessage) {
    echo $assistantMessage->text();
}

new Agent([
    'provider'  => 'anthropic',
    'auto_mode' => true,               // delegates to TaskAnalyzer to pick model + tools
]);

use SuperAgent\Squad\{TaskDecomposer, PeerOrchestrator, SquadCheckpointStore};

$subTasks = (new TaskDecomposer())->decompose(
    "1. Research the auth module\n".
    "2. Architect a migration plan (敲定方案需要人工审核)\n".
    "3. Implement OAuth2"
);

$orchestrator = new PeerOrchestrator(
    agentDispatcher: $myDispatcher,                          // (SquadDispatchRequest $r) => string|array
    checkpointStore: new SquadCheckpointStore('/tmp/cp'),    // per-step crash recovery
    output: $consoleOutput,                                  // streams progress events
    maxCostUsd: 5.00,                                        // downshift remaining steps at 80% of cap
);

$result = $orchestrator->run('refactor-2026-05', $subTasks);

'squad' => [
    'prefer_squad'   => true,
    'max_cost_usd'   => 5.00,
    'checkpoint_dir' => '/var/lib/superagent/squad',
    'tier_map' => [                  // override any/all bands; defaults fill the rest
        'expert' => ['provider' => 'openai', 'model' => 'gpt-5-pro'],
    ],
],

use SuperAgent\Squad\TeamRegistry;

$plan = (new TeamRegistry())-> /* … */);

use SuperAgent\Modes\{ModeContext, ModeRouter, CrossModePolicy};

$ctx = ModeContext::root('squad', policy: new CrossModePolicy(
    maxDepth: 4,
    budgetCapUsd: 5.00,
    autoEscalateOnFailure: true,
    escalateTo: 'smart',
));

$router = new ModeRouter();
$router->register(new AutoModeAdapter($autoModeAgent));
$router->register(new SmartModeAdapter($smartOrchestrator));
$router->register(new SquadModeAdapter());

$result = $router->dispatch('squad', $task, $ctx);
// $ctx->costLedger->total()  → every leaf dispatch summed
// $ctx->costLedger->byMode() → {squad: 0.31, smart: 0.18, auto: 0.02}
// $ctx->blackboard->entries() → every claim / evidence / risk / decision

$agent = new Agent([
    'provider' => 'gemini',
    'model'    => 'gemini-3.5-pro',
    'options'  => [
        'thinking'      => \SuperAgent\Thinking\ThinkingConfig::adaptive(),   // → thinkingLevel: HIGH
        'grounding'     => true,                                              // → tools[].googleSearch
        'url_context'   => true,                                              // → tools[].urlContext
    ],
]);

$flash = new GeminiProvider(['model' => 'gemini-3.5-flash', 'api_key' => env('GEMINI_API_KEY')]);
$checker = new LlmLoopChecker($flash);
foreach ($turns as $i => $turn) {
    if ($v = $checker->turnStarted($i, $conversationHistory, $originalPrompt)) {
        // $v->type === LoopType::LlmDetected; halt and surface to user
    }
}

use SuperAgent\Tracing\TraceCollector;

$end = TraceCollector::getInstance()->span('llm.dispatch', 'llm', 'session:abc');
$result = $provider->call(...);
$end(['model' => $result->model, 'cost_usd' => $result->cost]);

// At a trigger point — error, end-of-debate, agent self-snapshot, etc.
$path = TraceCollector::getInstance()->dump(trigger: 'manual', reason: 'inspect after demo');
// → /tmp/superagent-traces/trace_superagent_{session}_{ts}_manual.json

use SuperAgent\Tracing\PiEventStream;
use SuperAgent\Tracing\PiEventStreamWriter;

PiEventStream::subscribe(new PiEventStreamWriter('/path/to/session.events.jsonl'));

PiEventStream::emit(PiEventStream::AGENT_START, ['sessionId' => 's-1']);
PiEventStream::emit(PiEventStream::TURN_START, ['turnId' => 't-1', 'sessionId' => 's-1', 'model' => 'claude-opus-4-7']);
// ...
PiEventStream::emit(PiEventStream::AGENT_END, ['sessionId' => 's-1']);

// While agent is mid-turn, from a separate event handler:
$agent->steer('Stop, the bug is in src/Auth/Session.php, not src/Auth/Login.php');
// The next QueryEngine iteration drains the queue and prepends the steer as a synthetic user message.

// Or queue a follow-up that fires AFTER the current turn ends:
$agent->followUp('Once you finish, also run the tests in tests/Unit/Auth/');

use SuperAgent\Tools\Schema\Schema;
use SuperAgent\Tools\Schema\ProviderNormalizer;

$inputSchema = Schema::object([
    'mode' => Schema::stringEnum(['read', 'write', 'delete']),
    'path' => Schema::string('Absolute path'),
], ini($inputSchema);
// → Gemini variant has `oneOf` flattened to `enum`, `$ref`/`$defs` removed, unsupported `format` stripped.

use SuperAgent\Session\SessionManager;

$newBranchId = $sessionManager->fork(
    sourceSessionId: 's-current',
    forkAtIndex: 12,
    summaryFn: function(array $abandoned) use ($llm) {
        return $llm->summarize($abandoned);   // one-line summary stored on the source
    },
    displayName: 'try-event-sourcing-instead',
);

// Drop-in Anthropic-shaped requests against Qwen:
$agent = new Agent([
    'provider' => 'qwen-anthropic',
    'api_key'  => env('DASHSCOPE_API_KEY'),
    'model'    => 'qwen3.7-max',          // 1M ctx, $2.50 / $7.50 per 1M
]);

// Or the OpenAI-compat path with the new default model:
$agent = new Agent(['provider' => 'qwen']);   // → defaults to qwen3.7-max

$result = $agent->run($prompt, ['idempotency_key' => $queueJobId . ':' . $turnNumber]);
// $result->idempotencyKey is truncated to 80 chars; surfaces on the AgentResult
// so hosts that write ai_usage_logs can dedupe on it.

$agent = (new Agent(['provider' => 'anthropic']))
    ->loadTools(['read', 'write', 'bash'])
    ->registerTool(new MyDomainTool());

$result = $agent->run('apply the refactor plan in ./plan.md');

$agent->registerTool(new AgentTool());

$result = $agent->run(<<<PROMPT
Run these three investigations in parallel:
1. Read CHANGELOG.md and summarise the last three releases
2. Read composer.json and list all runtime dependencies
3. Grep for TODO comments in src/
Collate the three reports.
PROMPT);

[
    'status'              => 'completed',          // or 'completed_empty' / 'async_launched'
    'filesWritten'        => ['/abs/path/a.md'],   // deduped absolute paths
    'toolCallsByName'     => ['Read' => 3, 'Write' => 1],
    'totalToolUseCount'   => 4,                    // observed, not self-reported turn count
    'productivityWarning' => null,                 // or advisory string (CJK-localised — since v0.9.1)
    'outputWarnings'      => [],                   // since v0.9.1 — filesystem audit findings
]

$agent->run('...', [
    'output_subdir' => '/abs/path/to/reports/analyst-1',
]);
// Audit catches:
//   - non-whitelisted extensions (defaults to .md / .csv / .png)
//   - consolidator-reserved filenames (summary.md / 摘要.md / mindmap.md / ...)
//   - sibling-role sub-dirs (ceo / cfo / cto / marketing / ... or kebab-case role slugs)
// Configurable via AgentOutputAuditor constructor. Never modifies disk.

$factory = new SuperAgent\CLI\AgentFactory();
[$emitter, $transport] = $factory->makeWireEmitterForDsn('listen://unix//tmp/agent.sock');

// IDE plugin attaches, then:
$agent->run($prompt, ['wire_emitter' => $emitter]);

$transport->close();

new Agent([
    'provider'               => 'openai',
    'request_max_retries'    => 4,       // HTTP connect / 4xx / 5xx (default 3)
    'stream_max_retries'     => 5,       // reserved for mid-stream resume (Responses API)
    'stream_idle_timeout_ms' => 60_000,  // cURL low-speed cutoff on SSE (default 300 000)
]);

try {
    $agent->run($prompt);
} catch (\SuperAgent\Exceptions\Provider\ContextWindowExceededException $e) {
    // prompt was too long; compact history or swap models
} catch (\SuperAgent\Exceptions\Provider\QuotaExceededException $e) {
    // monthly cap hit; notify operator
} catch (\SuperAgent\Exceptions\Provider\UsageNotIncludedException $e) {
    // ChatGPT plan doesn't ions\ProviderException $e) {
    // catch-all base; every subclass above extends this
}

new Agent([
    'provider'        => 'openai',
    'loop_detection'  => true,           // defaults
    // OR per-detector overrides:
    // 'loop_detection' => ['TOOL_LOOP' => 10, 'STAGNATION' => 15],
]);

use SuperAgent\Checkpoint\CheckpointManager;
use SuperAgent\Checkpoint\GitShadowStore;

$mgr = new CheckpointManager(shadowStore: new GitShadowStore('/path/to/project'));
$mgr->createCheckpoint($agentState, label: 'after-refactor');

// Later:
$checkpoints = $mgr->list();
$mgr->restore($checkpoints[0]->id);
$mgr->restoreFiles($checkpoints[0]);   // plays back the shadow commit

new Agent([
    'provider'        => 'anthropic',
    'permission_mode' => 'ask',     // or 'default' / 'plan' / 'bypassPermissions'
]);

// config/superagent.php
return [
    'default_provider' => env('SUPERAGENT_PROVIDER', 'anthropic'),
    'providers' => [
        'anthropic'         => ['api_key' => env('ANTHROPIC_API_KEY')],
        'openai'            => ['api_key' => env('OPENAI_API_KEY')],
        'openai-responses'  => ['api_key' => env('OPENAI_API_KEY'), 'model' => 'gpt-5'],
        // ...
    ],
    'agent' => [
        'max_turns'      => 50,
        'max_budget_usd' => 5.00,
    ],
];

use SuperAgent\Facades\SuperAgent;

$result = SuperAgent::agent(['provider' => 'openai'])
    ->run('summarise this week\'s commits');

use SuperAgent\SmartFlow\{FlowEngine, FlowDefinition, FlowOptions, Flow};

$def = FlowDefinition::make('review', 'Review a diff', function (Flow $flow) {
    $reviews = $flow->parallel([
        $flow->call('Review for correctness: ' . $flow->args['diff'], ['role' => 'reviewer']),
        $flow->call('Review for security: '    . $flow->args['diff'], ['role' => 'reviewer', 'provider' => 'openai']),
    ]);
    $verdict = $flow->agent('Consolidate: ' . json_encode($reviews), [
        'role' => 'chair',
        'schema' => ['type' => 'object', '

use SuperAgent\Providers\ProviderRegistry;

// One call, every provider — no `match ($type)` on the host side.
$agent = ProviderRegistry::createForHost($sdkKey, [
    'api_key'     => $aiProvider->decrypted_api_key,
    'base_url'    => $aiProvider->base_url,
    'model'       => $resolvedModel,
    'max_tokens'  => $extra['max_tokens']  ?? null,
    'region'      => $extra['region']      ?? null,
    'credentials' => $extra,                // opaque blob; adapter picks what it needs
    'extra'       => $extra,                // provider-specific passthrough (organization, reasoning, verbosity, ...)
]);

ProviderRegistry::registerHostConfigAdapter('my-custom-provider', function (array $host): array {
    return [
        'api_key' => $host['credentials']['my_custom_token'] ?? null,
        'model'   => $host['model'] ?? 'default-model',
        // ... arbitrary transform
    ];
});
bash
php artisan superagent:chat "fix the bug"
php artisan superagent:mcp sync
php artisan superagent:models refresh
php artisan superagent:health --json