sk-wang / hao-code
PHP agent SDK for Anthropic, OpenAI Responses, and OpenAI Chat Completions APIs.
Requires
- php: ^8.1
- ext-dom: *
- nyholm/psr7: ^1.8
- open-telemetry/exporter-otlp: ^1.0
- open-telemetry/sdk: ^1.0
- open-telemetry/sem-conv: ^1.0
- swaggest/json-schema: ^0.12.43
- symfony/clock: ^6.4 || ^7.0 || ^8.0
- symfony/http-client: ^6.4 || ^7.0 || ^8.0
- symfony/yaml: ^6.4 || ^7.0 || ^8.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^10.5 || ^11.5
Suggests
- ext-pcntl: Required for daemon signal handling (SIGTERM/SIGINT)
- ext-pdo_sqlite: Required for durable run-state recovery and daemon SQLite storage
- ext-posix: Required for daemon PID management and stale-pid detection
- ext-sqlite3: For daemon mode (cron job persistence via SQLite)
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v1.24.2
- v1.24.1
- v1.24.0
- v1.23.0
- v1.22.0
- v1.21.1
- v1.21.0
- v1.20.2
- v1.20.1
- v1.20.0
- v1.19.10
- v1.19.9
- v1.19.8
- v1.19.7
- v1.19.6
- v1.19.5
- v1.19.4
- v1.19.3
- v1.19.2
- v1.19.1
- v1.19.0
- v1.18.62
- v1.18.61
- v1.18.60
- v1.18.59
- v1.18.58
- v1.18.57
- v1.18.56
- v1.18.55
- v1.18.54
- v1.18.53
- v1.18.52
- v1.18.51
- v1.18.50
- v1.18.49
- v1.18.48
- v1.18.47
- v1.18.46
- v1.18.45
- v1.18.44
- v1.18.43
- v1.18.42
- v1.18.41
- v1.18.40
- v1.18.39
- v1.18.38
- v1.18.37
- v1.18.36
- v1.18.35
- v1.18.34
- v1.18.33
- v1.18.32
- v1.18.31
- v1.18.30
- v1.18.29
- v1.18.28
- v1.18.27
- v1.18.26
- v1.18.25
- v1.18.24
- v1.18.23
- v1.18.22
- v1.18.21
- v1.18.20
- v1.18.19
- v1.18.18
- v1.18.17
- v1.18.16
- v1.18.15
- v1.18.14
- v1.18.13
- v1.18.12
- v1.18.11
- v1.18.10
- v1.18.9
- v1.18.8
- v1.18.7
- v1.18.6
- v1.18.5
- v1.18.4
- v1.18.3
- v1.18.2
- v1.18.1
- v1.18.0
- v1.17.2
- v1.17.1
- v1.17.0
- v1.16.0
- v1.15.0
- v1.14.0
- v1.13.1
- v1.13.0
- v1.12.1
- v1.12.0
- v1.11.1
- v1.11.0
- v1.10.2
- v1.10.1
- v1.10.0
- v1.9.1
- v1.9.0
- v1.8.0
- v1.7.0
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.0
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.1
- 1.0.0
- v0.4.0
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.0
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.9
- v0.0.8
- v0.0.7
- v0.0.6
- v0.0.5
- v0.0.4
- v0.0.3
- 0.0.2
- v0.0.1
- dev-agent/hao-code-tool-sandbox/haoc-8
- dev-agent/hao-code-tool-sandbox/haoc-11
- dev-agent/haoc-7-websearch-contract
- dev-codex/sdk-tool-concurrency-v1.21.1
- dev-codex/architecture-closure-v1.21.0
This package is auto-updated.
Last update: 2026-09-07 03:38:42 UTC
README
A framework-free PHP Agent SDK for Anthropic, OpenAI Responses, and OpenAI Chat Completions-compatible APIs.
hao-code lets PHP applications embed an AI coding agent with tools, skills, streaming output, multi-turn sessions, structured JSON results, cost tracking, abort control, credential pools, and isolated runtime storage.
For the complete SDK reference, see docs/SDK.md.
Install
composer require sk-wang/hao-code
Quick Start
<?php
require __DIR__.'/vendor/autoload.php';
use HaoCode\Sdk\HaoCode;
use HaoCode\Sdk\HaoCodeConfig;
$result = HaoCode::query('Explain this repository', new HaoCodeConfig(
apiKey: getenv('ANTHROPIC_API_KEY') ?: '',
cwd: __DIR__,
allowedTools: ['Read', 'Grep', 'Glob'],
));
echo $result->text;
What It Provides
| Area | Capability |
|---|---|
| Agent execution | One-shot queries, streaming responses, multi-turn conversations, session resume, continue latest session |
| Providers | Anthropic, OpenAI Responses API, OpenAI Chat Completions-compatible gateways |
| Tools | Built-in file, search, patch, shell, web, MCP, task, memory, and planning tools, plus custom PHP tools |
| Sandbox | Optional temporary filesystem for Read, Write, Glob, Grep, and sandboxed Bash |
| Skills | Prompt-packaged domain guidance through SdkSkill |
| Structured output | JSON schema guided responses via HaoCode::structured() |
| Runtime control | Working directory, allowed tools, denied tools, permission mode, max turns, max tokens, thinking options |
| Operations | Cost budget, usage metadata, abort controller, callbacks for text/tool/turn events |
| State | Session IDs, conversation handles, memory summary levels, custom memory storage path |
| Reliability | Credential pools, rate-limit tracking, provider abstraction, SDK-only runtime without Laravel dependency |
Main APIs
| Need | API |
|---|---|
| One-shot query | HaoCode::query() |
| Streaming messages | HaoCode::stream() |
| Multi-turn conversation | HaoCode::conversation() |
| Resume a session | HaoCode::resume() |
| Continue latest session | HaoCode::continueLatest() |
| Structured JSON result | HaoCode::structured() |
Configuration
Pass HaoCodeConfig when you need explicit runtime configuration:
use HaoCode\Sdk\HaoCodeConfig;
$config = new HaoCodeConfig(
apiKey: getenv('OPENAI_API_KEY') ?: '',
providerType: 'openai_chat',
baseUrl: 'https://api.openai.com',
model: 'gpt-4.1',
maxTokens: 4096,
cwd: __DIR__,
maxTurns: 30,
permissionMode: 'bypass_permissions',
allowedTools: ['Read', 'Grep', 'Glob'],
disallowedTools: ['Bash'],
);
If no explicit config is provided, the SDK reads environment and settings values such as ANTHROPIC_API_KEY, HAOCODE_MODEL, HAOCODE_API_BASE_URL, and HAOCODE_MAX_TOKENS.
Sandbox Runtime
Use a sandbox when the agent needs file or shell tools but must not mutate the
PHP host project directory. Sandbox mode replaces Read, Write, Glob, and
Grep with sandbox-scoped tools. Set mode: 'full' to also replace Bash with
a sandbox-scoped shell. Host-only tools such as Edit, apply_patch,
NotebookEdit, Lsp, worktree tools, and sub-agent messaging are disabled while
sandbox mode is active.
use HaoCode\Sdk\HaoCode;
use HaoCode\Sdk\HaoCodeConfig;
use HaoCode\Sdk\Sandbox\SandboxConfig;
$result = HaoCode::query('Review this project and write notes to notes.md', new HaoCodeConfig(
cwd: __DIR__,
sandbox: SandboxConfig::local(
mode: 'filesystem', // Read/Write/Glob/Grep only; Bash disabled
sync: 'upload-cwd', // copy cwd snapshot into /workspace
),
allowedTools: ['Read', 'Write', 'Grep', 'Glob'],
));
Alibaba Cloud AgentRun
SandboxConfig::agentRun() uses Alibaba Cloud AgentRun as a remote temporary
filesystem and execution environment. Use it when the PHP server should not touch
local files or run untrusted commands locally.
export AGENTRUN_ACCOUNT_ID=1887527099427005
export AGENTRUN_API_KEY=ak_xxx
export AGENTRUN_TEMPLATE_NAME=sandbox-lagal
export AGENTRUN_REGION=cn-hangzhou
php scripts/agentrun-verify.php
Use AGENTRUN_TEMPLATE_NAME to create a fresh temporary sandbox from a template.
Only set AGENTRUN_SANDBOX_ID when you already have a live sandbox instance ID;
a template ID is not a sandbox instance ID.
$config = new HaoCodeConfig(
sandbox: SandboxConfig::agentRun(
accountId: getenv('AGENTRUN_ACCOUNT_ID'),
templateName: getenv('AGENTRUN_TEMPLATE_NAME') ?: 'sandbox-lagal',
apiKey: getenv('AGENTRUN_API_KEY'),
mode: 'full',
remoteCwd: '/tmp',
),
allowedTools: ['Read', 'Write', 'Bash'],
);
For the current AgentRun code-interpreter template, write demo files under
/tmp/workspace; creating /workspace at the filesystem root can be denied by
the container. See examples/agentrun-ml-clustering-agent.php for a complete
agent-generated data + Python k-means demo.
Streaming
Use HaoCode::stream() when the caller needs incremental output:
foreach (HaoCode::stream('Summarize the current project') as $message) {
if ($message->isError()) {
throw new RuntimeException($message->error);
}
if ($message->text !== null) {
echo $message->text;
}
}
Conversations
Use a conversation handle when later prompts should keep the same message history and session:
$conversation = HaoCode::conversation(new HaoCodeConfig(cwd: __DIR__));
$conversation->send('Read the service layer and remember the architecture.');
$result = $conversation->send('Now review the newest changes.');
echo $result->text;
echo $conversation->getSessionId();
Structured Output
Use structured() for machine-readable results:
$result = HaoCode::structured('Classify: "payment failed"', [
'type' => 'object',
'properties' => [
'category' => ['type' => 'string'],
'priority' => ['type' => 'string', 'enum' => ['low', 'medium', 'high']],
],
'required' => ['category', 'priority'],
]);
echo $result->category;
Custom Tools
Define domain-specific PHP tools by extending SdkTool:
use HaoCode\Sdk\HaoCode;
use HaoCode\Sdk\HaoCodeConfig;
use HaoCode\Sdk\SdkTool;
$lookupOrder = new class extends SdkTool {
public function name(): string { return 'LookupOrder'; }
public function description(): string { return 'Look up an order by ID.'; }
public function parameters(): array
{
return [
'order_id' => ['type' => 'string', 'required' => true],
];
}
public function handle(array $input): string
{
return json_encode(['status' => 'paid']);
}
};
$result = HaoCode::query('Check order A123', new HaoCodeConfig(
tools: [$lookupOrder],
));
By default SdkTool is treated as read-only. Override isReadOnly() and return false for stateful or mutating tools.
Custom Skills
Use SdkSkill to package reusable prompt guidance:
use HaoCode\Sdk\SdkSkill;
$skill = new SdkSkill(
name: 'security-review',
description: 'Review code for common security risks.',
prompt: 'Check $ARGUMENTS for injection, auth bypass, secrets, and unsafe IO.',
allowedTools: ['Read', 'Grep'],
);
$result = HaoCode::query('Use security-review on app/Auth.php', new HaoCodeConfig(
skills: [$skill],
));
Credentials And Budgets
Use credential pools when you have multiple API keys, and cost budgets when the caller needs a hard spending guard:
use HaoCode\Sdk\Credential;
use HaoCode\Sdk\CredentialPool;
$pool = new CredentialPool([
new Credential(apiKey: getenv('ANTHROPIC_API_KEY_1') ?: ''),
new Credential(apiKey: getenv('ANTHROPIC_API_KEY_2') ?: ''),
]);
$config = new HaoCodeConfig(
credentialPool: $pool,
maxBudgetUsd: 1.00,
);
Callbacks And Abort
HaoCodeConfig supports callbacks for text deltas, tool starts, tool completions, and turn starts. It also supports AbortController for external cancellation:
use HaoCode\Sdk\AbortController;
$abort = new AbortController();
$config = new HaoCodeConfig(
abortController: $abort,
onText: fn (string $delta) => print $delta,
onToolStart: fn (string $name, array $input) => error_log("tool: {$name}"),
);
Storage And Memory
Runtime data is stored under ~/.haocode/storage by default when installed through Composer. Set HAOCODE_STORAGE_PATH for an application-specific runtime directory.
Session memory can be customized with memorySummaryLevel and memoryStoragePath:
$config = new HaoCodeConfig(
memorySummaryLevel: 'l1',
memoryStoragePath: __DIR__.'/var/haocode-memory.json',
);
Examples
| Example | Purpose |
|---|---|
examples/code-review-agent.php | Code review workflow |
examples/agentrun-ml-clustering-agent.php | AgentRun sandbox ML clustering demo |
examples/support-ops-agent.php | End-to-end support operations agent |
examples/weather-agent.php | Custom tool example |
examples/sdk-suite/ | Focused examples for query, streaming, conversation, structured output, abort, credential pools, patching, MCP, and provider matrix |
Documentation
Version
v1.0.0 is the first SDK-only release.
License
MIT