@preapexis/piexis 0.1.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +35 -0
- package/AGENTS.md +21 -41
- package/README.md +75 -142
- package/extensions/agents.ts +205 -0
- package/extensions/ask-question.ts +54 -95
- package/extensions/recommended-tools.ts +62 -0
- package/extensions/ui.ts +204 -58
- package/lib/agent-config.ts +55 -0
- package/lib/agents.ts +208 -0
- package/lib/question-model.ts +98 -0
- package/lib/question-ui.ts +214 -0
- package/lib/recommended-tools.ts +119 -0
- package/lib/subagent-runner.ts +146 -0
- package/lib/ui-tips.json +41 -0
- package/package.json +9 -12
- package/prompts/init.md +10 -2
- package/prompts/summary.md +7 -6
- package/schemas/agent.schema.json +48 -0
- package/scripts/release.mjs +32 -0
- package/skills/{claude-api/LICENSE.txt → caveman/LICENSE} +2 -2
- package/skills/caveman/LICENSE-MIT +21 -0
- package/skills/caveman/NOTICE +10 -0
- package/skills/caveman/SKILL.md +89 -0
- package/skills/find-skills/SKILL.md +141 -0
- package/skills/ponytail/LICENSE +21 -0
- package/skills/ponytail/NOTICE +9 -0
- package/skills/ponytail/SKILL.md +52 -0
- package/skills-lock.json +6 -0
- package/tests/agents.test.mjs +605 -0
- package/tests/ask-question-pty.test.mjs +16 -0
- package/tests/ask-question.test.mjs +269 -0
- package/tests/fixtures/agents-provider.ts +55 -0
- package/tests/fixtures/ask-question-pty.py +91 -0
- package/tests/fixtures/ask-question-terminal.mjs +69 -0
- package/tests/fixtures/recommended-tools-terminal.mjs +103 -0
- package/tests/init-workflow.test.mjs +31 -0
- package/tests/recommended-tools-pty.test.mjs +16 -0
- package/tests/recommended-tools.test.mjs +423 -0
- package/tests/resources.test.mjs +66 -0
- package/tests/skills-routing.test.mjs +7 -4
- package/tests/ui-tip-reload.test.mjs +70 -0
- package/tests/ui.test.mjs +450 -0
- package/tsconfig.json +1 -0
- package/.github/workflows/npm-publish.yml +0 -63
- package/PERMISSION_MODES_PLAN.md +0 -279
- package/WHAT_YOU_GET.md +0 -153
- package/eval/README.md +0 -72
- package/eval/permission-cases.json +0 -28
- package/eval/permissions.mjs +0 -103
- package/extensions/background-tasks.ts +0 -433
- package/extensions/background-worker.ts +0 -50
- package/extensions/glob.ts +0 -32
- package/extensions/mode.ts +0 -397
- package/lib/bash-approvals.ts +0 -113
- package/lib/bash-policy.ts +0 -164
- package/lib/mode-policy.ts +0 -174
- package/lib/path-policy.ts +0 -182
- package/lib/permission-classifier.ts +0 -128
- package/lib/permission-config.ts +0 -91
- package/lib/permission-denials.ts +0 -32
- package/lib/permission-intent.ts +0 -128
- package/lib/permission-taxonomy.ts +0 -15
- package/lib/task-broker.ts +0 -65
- package/lib/task-checkout.ts +0 -39
- package/lib/task-git.ts +0 -44
- package/lib/task-patch.ts +0 -106
- package/lib/task-permissions.ts +0 -51
- package/lib/task-report.ts +0 -62
- package/lib/task-worktree-policy.ts +0 -56
- package/skills/claude-api/SKILL.md +0 -572
- package/skills/claude-api/csharp/claude-api/README.md +0 -362
- package/skills/claude-api/csharp/claude-api/batches.md +0 -14
- package/skills/claude-api/csharp/claude-api/files-api.md +0 -25
- package/skills/claude-api/csharp/claude-api/streaming.md +0 -28
- package/skills/claude-api/csharp/claude-api/tool-use.md +0 -164
- package/skills/claude-api/curl/examples.md +0 -256
- package/skills/claude-api/curl/managed-agents.md +0 -371
- package/skills/claude-api/go/claude-api/README.md +0 -188
- package/skills/claude-api/go/claude-api/files-api.md +0 -23
- package/skills/claude-api/go/claude-api/streaming.md +0 -43
- package/skills/claude-api/go/claude-api/tool-use.md +0 -220
- package/skills/claude-api/go/managed-agents/README.md +0 -564
- package/skills/claude-api/java/claude-api/README.md +0 -238
- package/skills/claude-api/java/claude-api/files-api.md +0 -27
- package/skills/claude-api/java/claude-api/streaming.md +0 -24
- package/skills/claude-api/java/claude-api/tool-use.md +0 -228
- package/skills/claude-api/java/managed-agents/README.md +0 -443
- package/skills/claude-api/php/claude-api/README.md +0 -174
- package/skills/claude-api/php/claude-api/batches.md +0 -15
- package/skills/claude-api/php/claude-api/files-api.md +0 -13
- package/skills/claude-api/php/claude-api/streaming.md +0 -27
- package/skills/claude-api/php/claude-api/tool-use.md +0 -253
- package/skills/claude-api/php/managed-agents/README.md +0 -443
- package/skills/claude-api/python/claude-api/README.md +0 -565
- package/skills/claude-api/python/claude-api/batches.md +0 -198
- package/skills/claude-api/python/claude-api/files-api.md +0 -170
- package/skills/claude-api/python/claude-api/sdk-upgrade.md +0 -286
- package/skills/claude-api/python/claude-api/streaming.md +0 -179
- package/skills/claude-api/python/claude-api/tool-use.md +0 -627
- package/skills/claude-api/python/managed-agents/README.md +0 -335
- package/skills/claude-api/ruby/claude-api/README.md +0 -134
- package/skills/claude-api/ruby/claude-api/streaming.md +0 -16
- package/skills/claude-api/ruby/claude-api/tool-use.md +0 -41
- package/skills/claude-api/ruby/managed-agents/README.md +0 -394
- package/skills/claude-api/shared/admin-api.md +0 -179
- package/skills/claude-api/shared/agent-design.md +0 -101
- package/skills/claude-api/shared/anthropic-cli.md +0 -269
- package/skills/claude-api/shared/claude-platform-on-aws.md +0 -59
- package/skills/claude-api/shared/cost-optimization.md +0 -233
- package/skills/claude-api/shared/error-codes.md +0 -262
- package/skills/claude-api/shared/live-sources.md +0 -166
- package/skills/claude-api/shared/managed-agents-api-reference.md +0 -455
- package/skills/claude-api/shared/managed-agents-client-patterns.md +0 -220
- package/skills/claude-api/shared/managed-agents-core.md +0 -359
- package/skills/claude-api/shared/managed-agents-environments.md +0 -226
- package/skills/claude-api/shared/managed-agents-events.md +0 -290
- package/skills/claude-api/shared/managed-agents-memory.md +0 -201
- package/skills/claude-api/shared/managed-agents-multiagent.md +0 -260
- package/skills/claude-api/shared/managed-agents-onboarding.md +0 -82
- package/skills/claude-api/shared/managed-agents-outcomes.md +0 -108
- package/skills/claude-api/shared/managed-agents-overview.md +0 -77
- package/skills/claude-api/shared/managed-agents-scheduled-deployments.md +0 -156
- package/skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +0 -282
- package/skills/claude-api/shared/managed-agents-tools.md +0 -504
- package/skills/claude-api/shared/managed-agents-webhooks.md +0 -143
- package/skills/claude-api/shared/model-migration.md +0 -1872
- package/skills/claude-api/shared/models.md +0 -142
- package/skills/claude-api/shared/platform-availability.md +0 -53
- package/skills/claude-api/shared/prompt-audit.md +0 -223
- package/skills/claude-api/shared/prompt-caching.md +0 -292
- package/skills/claude-api/shared/token-counting.md +0 -56
- package/skills/claude-api/shared/tool-use-concepts.md +0 -526
- package/skills/claude-api/typescript/claude-api/README.md +0 -405
- package/skills/claude-api/typescript/claude-api/batches.md +0 -106
- package/skills/claude-api/typescript/claude-api/files-api.md +0 -98
- package/skills/claude-api/typescript/claude-api/streaming.md +0 -178
- package/skills/claude-api/typescript/claude-api/tool-use.md +0 -586
- package/skills/claude-api/typescript/managed-agents/README.md +0 -359
- package/tests/auto-permissions.test.mjs +0 -315
- package/tests/background-tasks.test.mjs +0 -27
- package/tests/background-worker.test.mjs +0 -60
- package/tests/bash-permissions.test.mjs +0 -276
- package/tests/glob.test.mjs +0 -31
- package/tests/mode.test.mjs +0 -62
- package/tests/permission-evaluation.test.mjs +0 -70
- package/tests/permission-foundation.test.mjs +0 -194
- package/tests/permission-policy.test.mjs +0 -158
- package/tests/runtime/README.md +0 -51
- package/tests/runtime/harness.mjs +0 -190
- package/tests/runtime/permissions.test.mjs +0 -192
- package/tests/runtime/tui.test.mjs +0 -60
- package/tests/task-integration.test.mjs +0 -324
- package/tests/task-permissions.test.mjs +0 -178
- package/tests/task-worktree-policy.test.mjs +0 -53
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
# Tool Use - PHP
|
|
2
|
-
|
|
3
|
-
For conceptual overview (tool definitions, tool choice, tips), see [shared/tool-use-concepts.md](../../shared/tool-use-concepts.md).
|
|
4
|
-
|
|
5
|
-
## Tool Use
|
|
6
|
-
|
|
7
|
-
### Tool Runner (Beta)
|
|
8
|
-
|
|
9
|
-
**Beta:** The PHP SDK provides a tool runner via `$client->beta->messages->toolRunner()`. Define tools with `BetaRunnableTool` - a definition array plus a `run` closure:
|
|
10
|
-
|
|
11
|
-
```php
|
|
12
|
-
use Anthropic\Lib\Tools\BetaRunnableTool;
|
|
13
|
-
|
|
14
|
-
$weatherTool = new BetaRunnableTool(
|
|
15
|
-
definition: [
|
|
16
|
-
'name' => 'get_weather',
|
|
17
|
-
'description' => 'Get the current weather for a location.',
|
|
18
|
-
'inputSchema' => [
|
|
19
|
-
'type' => 'object',
|
|
20
|
-
'properties' => [
|
|
21
|
-
'location' => ['type' => 'string', 'description' => 'City and state'],
|
|
22
|
-
],
|
|
23
|
-
'required' => ['location'],
|
|
24
|
-
],
|
|
25
|
-
],
|
|
26
|
-
run: function (array $input): string {
|
|
27
|
-
return "The weather in {$input['location']} is sunny and 72°F.";
|
|
28
|
-
},
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
$runner = $client->beta->messages->toolRunner(
|
|
32
|
-
maxTokens: 16000,
|
|
33
|
-
messages: [['role' => 'user', 'content' => 'What is the weather in Paris?']],
|
|
34
|
-
model: 'claude-opus-5',
|
|
35
|
-
tools: [$weatherTool],
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
foreach ($runner as $message) {
|
|
39
|
-
foreach ($message->content as $block) {
|
|
40
|
-
if ($block->type === 'text') {
|
|
41
|
-
echo $block->text;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Manual Loop
|
|
48
|
-
|
|
49
|
-
Tools are passed as arrays. **The SDK uses camelCase keys** (`inputSchema`, `toolUseID`, `stopReason`) and auto-maps to the API's snake_case on the wire - since v0.5.0. See [shared tool use concepts](../../shared/tool-use-concepts.md) for the loop pattern.
|
|
50
|
-
|
|
51
|
-
```php
|
|
52
|
-
use Anthropic\Messages\ToolUseBlock;
|
|
53
|
-
|
|
54
|
-
$tools = [
|
|
55
|
-
[
|
|
56
|
-
'name' => 'get_weather',
|
|
57
|
-
'description' => 'Get the current weather in a given location',
|
|
58
|
-
'inputSchema' => [ // camelCase, not input_schema
|
|
59
|
-
'type' => 'object',
|
|
60
|
-
'properties' => [
|
|
61
|
-
'location' => ['type' => 'string', 'description' => 'City and state'],
|
|
62
|
-
],
|
|
63
|
-
'required' => ['location'],
|
|
64
|
-
],
|
|
65
|
-
],
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
$messages = [['role' => 'user', 'content' => 'What is the weather in SF?']];
|
|
69
|
-
|
|
70
|
-
$response = $client->messages->create(
|
|
71
|
-
model: 'claude-opus-5',
|
|
72
|
-
maxTokens: 16000,
|
|
73
|
-
tools: $tools,
|
|
74
|
-
messages: $messages,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
while ($response->stopReason === 'tool_use') { // camelCase property
|
|
78
|
-
$toolResults = [];
|
|
79
|
-
foreach ($response->content as $block) {
|
|
80
|
-
if ($block instanceof ToolUseBlock) {
|
|
81
|
-
// $block->name : string - tool name to dispatch on
|
|
82
|
-
// $block->input : array<string,mixed> - parsed JSON input
|
|
83
|
-
// $block->id : string - pass back as toolUseID
|
|
84
|
-
$result = executeYourTool($block->name, $block->input);
|
|
85
|
-
$toolResults[] = [
|
|
86
|
-
'type' => 'tool_result',
|
|
87
|
-
'toolUseID' => $block->id, // camelCase, not tool_use_id
|
|
88
|
-
'content' => $result,
|
|
89
|
-
];
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Append assistant turn + user turn with tool results
|
|
94
|
-
$messages[] = ['role' => 'assistant', 'content' => $response->content];
|
|
95
|
-
$messages[] = ['role' => 'user', 'content' => $toolResults];
|
|
96
|
-
|
|
97
|
-
$response = $client->messages->create(
|
|
98
|
-
model: 'claude-opus-5',
|
|
99
|
-
maxTokens: 16000,
|
|
100
|
-
tools: $tools,
|
|
101
|
-
messages: $messages,
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Final text response
|
|
106
|
-
foreach ($response->content as $block) {
|
|
107
|
-
if ($block->type === 'text') {
|
|
108
|
-
echo $block->text;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
`$block->type === 'tool_use'` also works; `instanceof ToolUseBlock` narrows for PHPStan.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Structured Outputs
|
|
119
|
-
|
|
120
|
-
### Using StructuredOutputModel (Recommended)
|
|
121
|
-
|
|
122
|
-
Define a PHP class implementing `StructuredOutputModel` and pass it as `outputConfig`:
|
|
123
|
-
|
|
124
|
-
```php
|
|
125
|
-
use Anthropic\Lib\Contracts\StructuredOutputModel;
|
|
126
|
-
use Anthropic\Lib\Concerns\StructuredOutputModelTrait;
|
|
127
|
-
use Anthropic\Lib\Attributes\Constrained;
|
|
128
|
-
|
|
129
|
-
class Person implements StructuredOutputModel
|
|
130
|
-
{
|
|
131
|
-
use StructuredOutputModelTrait;
|
|
132
|
-
|
|
133
|
-
#[Constrained(description: 'Full name')]
|
|
134
|
-
public string $name;
|
|
135
|
-
|
|
136
|
-
public int $age;
|
|
137
|
-
|
|
138
|
-
public ?string $email = null; // nullable = optional field
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
$message = $client->messages->create(
|
|
142
|
-
model: 'claude-opus-5',
|
|
143
|
-
maxTokens: 16000,
|
|
144
|
-
messages: [['role' => 'user', 'content' => 'Generate a profile for Alice, age 30']],
|
|
145
|
-
outputConfig: ['format' => Person::class],
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
$person = $message->parsedOutput(); // Person instance
|
|
149
|
-
echo $person->name;
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Types are inferred from PHP type hints. Use `#[Constrained(description: '...')]` to add descriptions. Nullable properties (`?string`) become optional fields.
|
|
153
|
-
|
|
154
|
-
### Raw Schema
|
|
155
|
-
|
|
156
|
-
```php
|
|
157
|
-
$message = $client->messages->create(
|
|
158
|
-
model: 'claude-opus-5',
|
|
159
|
-
maxTokens: 16000,
|
|
160
|
-
messages: [['role' => 'user', 'content' => 'Extract: John (john@co.com), Enterprise plan']],
|
|
161
|
-
outputConfig: [
|
|
162
|
-
'format' => [
|
|
163
|
-
'type' => 'json_schema',
|
|
164
|
-
'schema' => [
|
|
165
|
-
'type' => 'object',
|
|
166
|
-
'properties' => [
|
|
167
|
-
'name' => ['type' => 'string'],
|
|
168
|
-
'email' => ['type' => 'string'],
|
|
169
|
-
'plan' => ['type' => 'string'],
|
|
170
|
-
],
|
|
171
|
-
'required' => ['name', 'email', 'plan'],
|
|
172
|
-
'additionalProperties' => false,
|
|
173
|
-
],
|
|
174
|
-
],
|
|
175
|
-
],
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
// First text block contains valid JSON
|
|
179
|
-
foreach ($message->content as $block) {
|
|
180
|
-
if ($block->type === 'text') {
|
|
181
|
-
$data = json_decode($block->text, true);
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Beta Features & Anthropic-Defined Tools
|
|
190
|
-
|
|
191
|
-
**`betas:` is NOT a param on `$client->messages->create()`** - it only exists on the beta namespace. Use it for features that need an explicit opt-in header:
|
|
192
|
-
|
|
193
|
-
```php
|
|
194
|
-
use Anthropic\Beta\Messages\BetaRequestMCPServerURLDefinition;
|
|
195
|
-
|
|
196
|
-
$response = $client->beta->messages->create(
|
|
197
|
-
model: 'claude-opus-5',
|
|
198
|
-
maxTokens: 16000,
|
|
199
|
-
mcpServers: [
|
|
200
|
-
BetaRequestMCPServerURLDefinition::with(
|
|
201
|
-
name: 'my-server',
|
|
202
|
-
url: 'https://example.com/mcp',
|
|
203
|
-
),
|
|
204
|
-
],
|
|
205
|
-
betas: ['mcp-client-2025-11-20'], // only valid on ->beta->messages
|
|
206
|
-
messages: [['role' => 'user', 'content' => 'Use the MCP tools']],
|
|
207
|
-
);
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Task budgets
|
|
211
|
-
|
|
212
|
-
```php
|
|
213
|
-
$response = $client->beta->messages->create(
|
|
214
|
-
model: 'claude-opus-5',
|
|
215
|
-
maxTokens: 16000,
|
|
216
|
-
outputConfig: ['taskBudget' => ['type' => 'tokens', 'total' => 64000]],
|
|
217
|
-
tools: [...],
|
|
218
|
-
messages: [...],
|
|
219
|
-
betas: ['task-budgets-2026-03-13'],
|
|
220
|
-
);
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Cache diagnostics
|
|
224
|
-
|
|
225
|
-
Pass the previous response's `id` on the next request; print the `diagnostics` object on the response:
|
|
226
|
-
|
|
227
|
-
```php
|
|
228
|
-
$r2 = $client->beta->messages->create(
|
|
229
|
-
model: 'claude-opus-5', maxTokens: 1024,
|
|
230
|
-
diagnostics: ['previousMessageId' => $r1->id],
|
|
231
|
-
betas: ['cache-diagnosis-2026-04-07'],
|
|
232
|
-
messages: [...],
|
|
233
|
-
);
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Anthropic-defined tools** (bash, web_search, text_editor, code_execution) are GA and work on both paths. Of these, web_search and code_execution are server-executed; bash and text_editor are client-executed (you handle the `tool_use` locally) - `Anthropic\Messages\ToolBash20250124` / `WebSearchTool20260209` / `ToolTextEditor20250728` / `CodeExecutionTool20260120` for non-beta, `Anthropic\Beta\Messages\BetaToolBash20250124` / `BetaWebSearchTool20260209` / `BetaToolTextEditor20250728` / `BetaCodeExecutionTool20260120` for beta. No `betas:` header needed for these.
|
|
237
|
-
|
|
238
|
-
### Tool search (non-beta, server-side)
|
|
239
|
-
|
|
240
|
-
```php
|
|
241
|
-
tools: [
|
|
242
|
-
['type' => 'tool_search_tool_regex_20251119', 'name' => 'tool_search_tool_regex'],
|
|
243
|
-
['name' => 'get_weather', 'description' => '...', 'inputSchema' => [...], 'deferLoading' => true],
|
|
244
|
-
// ... other user tools with 'deferLoading' => true
|
|
245
|
-
],
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### Memory tool (non-beta, client-executed)
|
|
249
|
-
|
|
250
|
-
Declare `['type' => 'memory_20250818', 'name' => 'memory']`. Handle the `tool_use` by reading/writing files under a fixed `/memories` directory. **Validate every model-supplied path**: resolve to its canonical form and verify it remains within the memory directory; reject traversal (`..`, symlinks) - see `shared/tool-use-concepts.md` § Client-Side Tools.
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
@@ -1,443 +0,0 @@
|
|
|
1
|
-
# Managed Agents - PHP
|
|
2
|
-
|
|
3
|
-
> **Bindings not shown here:** This README covers the most common managed-agents flows for PHP. If you need a class, method, namespace, field, or behavior that isn't shown, WebFetch the PHP SDK repo **or the relevant docs page** from `shared/live-sources.md` rather than guess. Do not extrapolate from cURL shapes or another language's SDK.
|
|
4
|
-
|
|
5
|
-
> **Agents are persistent - create once, reference by ID.** Store the agent ID returned by `$client->beta->agents->create` and pass it to every subsequent `->sessions->create`; do not call `agents->create` in the request path. **Recommended:** define agents and environments as version-controlled YAML applied with the `ant` CLI - see `shared/anthropic-cli.md` (its live-docs URL is in `shared/live-sources.md`). The CLI owns the control plane (create/update); your code owns the data plane (sessions with the stored ID). The examples below show in-code creation for when you must provision programmatically; in production the create call belongs in setup, not in the request path.
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
composer require "anthropic-ai/sdk" "guzzlehttp/guzzle:^7"
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Client Initialization
|
|
14
|
-
|
|
15
|
-
```php
|
|
16
|
-
use Anthropic\Client;
|
|
17
|
-
|
|
18
|
-
// Default (uses ANTHROPIC_API_KEY env var)
|
|
19
|
-
$client = new Client();
|
|
20
|
-
|
|
21
|
-
// Explicit API key
|
|
22
|
-
$client = new Client(apiKey: 'your-api-key');
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Create an Environment
|
|
28
|
-
|
|
29
|
-
```php
|
|
30
|
-
$environment = $client->beta->environments->create(
|
|
31
|
-
name: 'my-dev-env',
|
|
32
|
-
config: ['type' => 'cloud', 'networking' => ['type' => 'unrestricted']],
|
|
33
|
-
);
|
|
34
|
-
echo "Environment ID: {$environment->id}\n"; // env_...
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Create an Agent (required first step)
|
|
40
|
-
|
|
41
|
-
> Warning: **There is no inline agent config.** `model`/`system`/`tools` live on the agent object, not the session. Always start with `$client->beta->agents->create()` - the session takes either `agent: $agent->id` or the typed `BetaManagedAgentsAgentParams::with(type: 'agent', id: $agent->id, version: $agent->version)`.
|
|
42
|
-
|
|
43
|
-
### Minimal
|
|
44
|
-
|
|
45
|
-
```php
|
|
46
|
-
use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401Params;
|
|
47
|
-
|
|
48
|
-
// 1. Create the agent (reusable, versioned)
|
|
49
|
-
$agent = $client->beta->agents->create(
|
|
50
|
-
name: 'Coding Assistant',
|
|
51
|
-
model: 'claude-opus-5',
|
|
52
|
-
system: 'You are a helpful coding assistant.',
|
|
53
|
-
tools: [
|
|
54
|
-
BetaManagedAgentsAgentToolset20260401Params::with(
|
|
55
|
-
type: 'agent_toolset_20260401',
|
|
56
|
-
),
|
|
57
|
-
],
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
// 2. Start a session
|
|
61
|
-
$session = $client->beta->sessions->create(
|
|
62
|
-
agent: ['type' => 'agent', 'id' => $agent->id, 'version' => $agent->version],
|
|
63
|
-
environmentID: $environment->id,
|
|
64
|
-
title: 'Quickstart session',
|
|
65
|
-
);
|
|
66
|
-
echo "Session ID: {$session->id}\n";
|
|
67
|
-
echo "Trace: https://platform.claude.com/workspaces/default/sessions/{$session->id}\n"; // swap 'default' for your workspace ID if the API key is not in the Default workspace
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Updating an Agent
|
|
71
|
-
|
|
72
|
-
Updates create new versions; the agent object is immutable per version.
|
|
73
|
-
|
|
74
|
-
```php
|
|
75
|
-
$updatedAgent = $client->beta->agents->update(
|
|
76
|
-
$agent->id,
|
|
77
|
-
version: $agent->version,
|
|
78
|
-
system: 'You are a helpful coding agent. Always write tests.',
|
|
79
|
-
);
|
|
80
|
-
echo "New version: {$updatedAgent->version}\n";
|
|
81
|
-
|
|
82
|
-
// List all versions
|
|
83
|
-
foreach ($client->beta->agents->versions->list($agent->id)->pagingEachItem() as $version) {
|
|
84
|
-
echo "Version {$version->version}: {$version->updatedAt->format(DateTimeInterface::ATOM)}\n";
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Archive the agent
|
|
88
|
-
$archived = $client->beta->agents->archive($agent->id);
|
|
89
|
-
echo "Archived at: {$archived->archivedAt->format(DateTimeInterface::ATOM)}\n";
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Send a User Message
|
|
95
|
-
|
|
96
|
-
```php
|
|
97
|
-
$client->beta->sessions->events->send(
|
|
98
|
-
$session->id,
|
|
99
|
-
events: [
|
|
100
|
-
[
|
|
101
|
-
'type' => 'user.message',
|
|
102
|
-
'content' => [['type' => 'text', 'text' => 'Review the auth module']],
|
|
103
|
-
],
|
|
104
|
-
],
|
|
105
|
-
);
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
> Tip: **Stream-first:** Open the stream *before* (or concurrently with) sending the message. The stream only delivers events that occur after it opens - stream-after-send means early events arrive buffered in one batch. See [Steering Patterns](../../shared/managed-agents-events.md#steering-patterns).
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Stream Events (SSE)
|
|
113
|
-
|
|
114
|
-
> Note: **Streaming transporter:** PHP's default buffered PSR-18 client never returns for the open-ended session event stream. Use a streaming Guzzle transporter for `streamStream()` calls - other calls keep the default client.
|
|
115
|
-
|
|
116
|
-
```php
|
|
117
|
-
$streamingClient = new GuzzleHttp\Client(['stream' => true]);
|
|
118
|
-
|
|
119
|
-
// Open the stream first, then send the user message
|
|
120
|
-
$stream = $client->beta->sessions->events->streamStream(
|
|
121
|
-
$session->id,
|
|
122
|
-
requestOptions: ['transporter' => $streamingClient],
|
|
123
|
-
);
|
|
124
|
-
$client->beta->sessions->events->send(
|
|
125
|
-
$session->id,
|
|
126
|
-
events: [
|
|
127
|
-
[
|
|
128
|
-
'type' => 'user.message',
|
|
129
|
-
'content' => [['type' => 'text', 'text' => 'Summarize the repo README']],
|
|
130
|
-
],
|
|
131
|
-
],
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
foreach ($stream as $event) {
|
|
135
|
-
match ($event->type) {
|
|
136
|
-
'agent.message' => array_walk(
|
|
137
|
-
$event->content,
|
|
138
|
-
static fn($block) => $block->type === 'text' ? print($block->text) : null,
|
|
139
|
-
),
|
|
140
|
-
'agent.tool_use' => print("\n[Using tool: {$event->name}]\n"),
|
|
141
|
-
'session.error' => printf("\n[Error: %s]", $event->error?->message ?? 'unknown'),
|
|
142
|
-
default => null,
|
|
143
|
-
};
|
|
144
|
-
if ($event->type === 'session.status_idle' || $event->type === 'session.error') {
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
$stream->close();
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Reconnecting and Tailing
|
|
152
|
-
|
|
153
|
-
When reconnecting mid-session, list past events first to dedupe, then tail live events:
|
|
154
|
-
|
|
155
|
-
```php
|
|
156
|
-
$stream = $client->beta->sessions->events->streamStream(
|
|
157
|
-
$session->id,
|
|
158
|
-
requestOptions: ['transporter' => $streamingClient],
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
// Stream is open and buffering. List history before tailing live.
|
|
162
|
-
$seenEventIds = [];
|
|
163
|
-
foreach ($client->beta->sessions->events->list($session->id)->pagingEachItem() as $event) {
|
|
164
|
-
$seenEventIds[$event->id] = true;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Tail live events, skipping anything already seen
|
|
168
|
-
foreach ($stream as $event) {
|
|
169
|
-
if (isset($seenEventIds[$event->id])) {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
$seenEventIds[$event->id] = true;
|
|
173
|
-
match ($event->type) {
|
|
174
|
-
'agent.message' => array_walk(
|
|
175
|
-
$event->content,
|
|
176
|
-
static fn($block) => $block->type === 'text' ? print($block->text) : null,
|
|
177
|
-
),
|
|
178
|
-
default => null,
|
|
179
|
-
};
|
|
180
|
-
if ($event->type === 'session.status_idle') {
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
$stream->close();
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Provide Custom Tool Result
|
|
190
|
-
|
|
191
|
-
> Note: The PHP managed-agents bindings for `user.custom_tool_result` are not yet documented in this skill or in the apps source examples. Refer to `shared/managed-agents-events.md` for the wire format and the `anthropic-ai/sdk` PHP repository for the corresponding params.
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Poll Events
|
|
196
|
-
|
|
197
|
-
```php
|
|
198
|
-
foreach ($client->beta->sessions->events->list($session->id)->pagingEachItem() as $event) {
|
|
199
|
-
echo "{$event->type}: {$event->id}\n";
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## Upload a File
|
|
206
|
-
|
|
207
|
-
> Note: **PHP file upload:** The PHP SDK's beta managed-agents file upload binding is not shown in the apps source examples; the canonical PHP example uses raw cURL against `POST /v1/files`. If your codebase prefers the SDK, WebFetch the `anthropic-ai/sdk` PHP repository for the latest binding before writing code.
|
|
208
|
-
|
|
209
|
-
```php
|
|
210
|
-
use Anthropic\Beta\Sessions\BetaManagedAgentsFileResourceParams;
|
|
211
|
-
|
|
212
|
-
// Raw cURL upload (canonical example from the apps source)
|
|
213
|
-
$csvPath = 'data.csv';
|
|
214
|
-
$ch = curl_init('https://api.anthropic.com/v1/files');
|
|
215
|
-
curl_setopt_array($ch, [
|
|
216
|
-
CURLOPT_RETURNTRANSFER => true,
|
|
217
|
-
CURLOPT_POST => true,
|
|
218
|
-
CURLOPT_HTTPHEADER => [
|
|
219
|
-
'x-api-key: ' . getenv('ANTHROPIC_API_KEY'),
|
|
220
|
-
'anthropic-version: 2023-06-01',
|
|
221
|
-
'anthropic-beta: files-api-2025-04-14',
|
|
222
|
-
],
|
|
223
|
-
CURLOPT_POSTFIELDS => ['file' => new CURLFile($csvPath, 'text/csv', 'data.csv')],
|
|
224
|
-
]);
|
|
225
|
-
$file = json_decode(curl_exec($ch));
|
|
226
|
-
echo "File ID: {$file->id}\n";
|
|
227
|
-
|
|
228
|
-
// Mount in a session
|
|
229
|
-
$session = $client->beta->sessions->create(
|
|
230
|
-
agent: $agent->id,
|
|
231
|
-
environmentID: $environment->id,
|
|
232
|
-
resources: [
|
|
233
|
-
BetaManagedAgentsFileResourceParams::with(
|
|
234
|
-
type: 'file',
|
|
235
|
-
fileID: $file->id,
|
|
236
|
-
mountPath: '/workspace/data.csv',
|
|
237
|
-
),
|
|
238
|
-
],
|
|
239
|
-
);
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Add and Manage Resources on an Existing Session
|
|
243
|
-
|
|
244
|
-
```php
|
|
245
|
-
// Attach an additional file to an open session
|
|
246
|
-
$resource = $client->beta->sessions->resources->add(
|
|
247
|
-
$session->id,
|
|
248
|
-
type: 'file',
|
|
249
|
-
fileID: $file->id,
|
|
250
|
-
);
|
|
251
|
-
echo "{$resource->id}\n"; // "sesrsc_01ABC..."
|
|
252
|
-
|
|
253
|
-
// List resources on the session
|
|
254
|
-
$listed = $client->beta->sessions->resources->list($session->id);
|
|
255
|
-
foreach ($listed->data as $entry) {
|
|
256
|
-
echo "{$entry->id} {$entry->type}\n";
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Detach a resource
|
|
260
|
-
$client->beta->sessions->resources->delete($resource->id, sessionID: $session->id);
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
## List and Download Session Files
|
|
266
|
-
|
|
267
|
-
```php
|
|
268
|
-
$files = $client->beta->files->list(
|
|
269
|
-
scopeID: 'sesn_abc123',
|
|
270
|
-
betas: ['managed-agents-2026-04-01'],
|
|
271
|
-
);
|
|
272
|
-
$content = $client->beta->files->download($files->data[0]->id);
|
|
273
|
-
file_put_contents('output.txt', $content);
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
---
|
|
277
|
-
|
|
278
|
-
## Session Management
|
|
279
|
-
|
|
280
|
-
```php
|
|
281
|
-
// List environments
|
|
282
|
-
$environments = $client->beta->environments->list();
|
|
283
|
-
|
|
284
|
-
// Retrieve a specific environment
|
|
285
|
-
$env = $client->beta->environments->retrieve($environment->id);
|
|
286
|
-
|
|
287
|
-
// Archive an environment (read-only, existing sessions continue)
|
|
288
|
-
$client->beta->environments->archive($environment->id);
|
|
289
|
-
|
|
290
|
-
// Delete an environment (only if no sessions reference it)
|
|
291
|
-
$client->beta->environments->delete($environment->id);
|
|
292
|
-
|
|
293
|
-
// Delete a session
|
|
294
|
-
$client->beta->sessions->delete($session->id);
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
---
|
|
298
|
-
|
|
299
|
-
## MCP Server Integration
|
|
300
|
-
|
|
301
|
-
```php
|
|
302
|
-
use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401Params;
|
|
303
|
-
use Anthropic\Beta\Agents\BetaManagedAgentsMCPToolsetParams;
|
|
304
|
-
use Anthropic\Beta\Agents\BetaManagedAgentsURLMCPServerParams;
|
|
305
|
-
use Anthropic\Beta\Sessions\BetaManagedAgentsAgentParams;
|
|
306
|
-
|
|
307
|
-
// Agent declares MCP server (no auth here - auth goes in a vault)
|
|
308
|
-
$agent = $client->beta->agents->create(
|
|
309
|
-
name: 'GitHub Assistant',
|
|
310
|
-
model: 'claude-opus-5',
|
|
311
|
-
mcpServers: [
|
|
312
|
-
BetaManagedAgentsURLMCPServerParams::with(
|
|
313
|
-
type: 'url',
|
|
314
|
-
name: 'github',
|
|
315
|
-
url: 'https://api.githubcopilot.com/mcp/',
|
|
316
|
-
),
|
|
317
|
-
],
|
|
318
|
-
tools: [
|
|
319
|
-
BetaManagedAgentsAgentToolset20260401Params::with(type: 'agent_toolset_20260401'),
|
|
320
|
-
BetaManagedAgentsMCPToolsetParams::with(
|
|
321
|
-
type: 'mcp_toolset',
|
|
322
|
-
mcpServerName: 'github',
|
|
323
|
-
),
|
|
324
|
-
],
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
// Session attaches vault(s) containing credentials for those MCP server URLs
|
|
328
|
-
$session = $client->beta->sessions->create(
|
|
329
|
-
agent: BetaManagedAgentsAgentParams::with(
|
|
330
|
-
type: 'agent',
|
|
331
|
-
id: $agent->id,
|
|
332
|
-
version: $agent->version,
|
|
333
|
-
),
|
|
334
|
-
environmentID: $environment->id,
|
|
335
|
-
vaultIDs: [$vault->id],
|
|
336
|
-
);
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
See `shared/managed-agents-tools.md` §Vaults for creating vaults and adding credentials.
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## Vaults
|
|
344
|
-
|
|
345
|
-
```php
|
|
346
|
-
// Create a vault
|
|
347
|
-
$vault = $client->beta->vaults->create(
|
|
348
|
-
displayName: 'Alice',
|
|
349
|
-
metadata: ['external_user_id' => 'usr_abc123'],
|
|
350
|
-
);
|
|
351
|
-
echo $vault->id . "\n"; // "vlt_01ABC..."
|
|
352
|
-
|
|
353
|
-
// Add an OAuth credential
|
|
354
|
-
$credential = $client->beta->vaults->credentials->create(
|
|
355
|
-
vaultID: $vault->id,
|
|
356
|
-
displayName: "Alice's Slack",
|
|
357
|
-
auth: [
|
|
358
|
-
'type' => 'mcp_oauth',
|
|
359
|
-
'mcp_server_url' => 'https://mcp.slack.com/mcp',
|
|
360
|
-
'access_token' => 'xoxp-...',
|
|
361
|
-
'expires_at' => '2026-04-15T00:00:00Z',
|
|
362
|
-
'refresh' => [
|
|
363
|
-
'token_endpoint' => 'https://slack.com/api/oauth.v2.access',
|
|
364
|
-
'client_id' => '1234567890.0987654321',
|
|
365
|
-
'scope' => 'channels:read chat:write',
|
|
366
|
-
'refresh_token' => 'xoxe-1-...',
|
|
367
|
-
'token_endpoint_auth' => [
|
|
368
|
-
'type' => 'client_secret_post',
|
|
369
|
-
'client_secret' => 'abc123...',
|
|
370
|
-
],
|
|
371
|
-
],
|
|
372
|
-
],
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
// Rotate the credential (e.g., after a token refresh)
|
|
376
|
-
$client->beta->vaults->credentials->update(
|
|
377
|
-
$credential->id,
|
|
378
|
-
vaultID: $vault->id,
|
|
379
|
-
auth: [
|
|
380
|
-
'type' => 'mcp_oauth',
|
|
381
|
-
'access_token' => 'xoxp-new-...',
|
|
382
|
-
'expires_at' => '2026-05-15T00:00:00Z',
|
|
383
|
-
'refresh' => ['refresh_token' => 'xoxe-1-new-...'],
|
|
384
|
-
],
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
// Archive a vault
|
|
388
|
-
$client->beta->vaults->archive($vault->id);
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
---
|
|
392
|
-
|
|
393
|
-
## GitHub Repository Integration
|
|
394
|
-
|
|
395
|
-
Mount a GitHub repository as a session resource (a vault holds the GitHub MCP credential):
|
|
396
|
-
|
|
397
|
-
```php
|
|
398
|
-
$session = $client->beta->sessions->create(
|
|
399
|
-
agent: $agent->id,
|
|
400
|
-
environmentID: $environment->id,
|
|
401
|
-
vaultIDs: [$vault->id],
|
|
402
|
-
resources: [
|
|
403
|
-
[
|
|
404
|
-
'type' => 'github_repository',
|
|
405
|
-
'url' => 'https://github.com/org/repo',
|
|
406
|
-
'mount_path' => '/workspace/repo',
|
|
407
|
-
'authorization_token' => 'ghp_your_github_token',
|
|
408
|
-
],
|
|
409
|
-
],
|
|
410
|
-
);
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
Multiple repositories on the same session:
|
|
414
|
-
|
|
415
|
-
```php
|
|
416
|
-
$resources = [
|
|
417
|
-
[
|
|
418
|
-
'type' => 'github_repository',
|
|
419
|
-
'url' => 'https://github.com/org/frontend',
|
|
420
|
-
'mount_path' => '/workspace/frontend',
|
|
421
|
-
'authorization_token' => 'ghp_your_github_token',
|
|
422
|
-
],
|
|
423
|
-
[
|
|
424
|
-
'type' => 'github_repository',
|
|
425
|
-
'url' => 'https://github.com/org/backend',
|
|
426
|
-
'mount_path' => '/workspace/backend',
|
|
427
|
-
'authorization_token' => 'ghp_your_github_token',
|
|
428
|
-
],
|
|
429
|
-
];
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
Rotating a repository's authorization token:
|
|
433
|
-
|
|
434
|
-
```php
|
|
435
|
-
$listed = $client->beta->sessions->resources->list($session->id);
|
|
436
|
-
$repoResourceId = $listed->data[0]->id;
|
|
437
|
-
|
|
438
|
-
$client->beta->sessions->resources->update(
|
|
439
|
-
$repoResourceId,
|
|
440
|
-
sessionID: $session->id,
|
|
441
|
-
authorizationToken: 'ghp_your_new_github_token',
|
|
442
|
-
);
|
|
443
|
-
```
|