mirror of
https://github.com/anthropics/skills.git
synced 2026-08-02 21:15:27 +08:00
Update claude-api skill: Managed Agents July launch wave, partner pricing, tool-runner corrections (#1463)
Syncs the claude-api skill with the current upstream source.
## Managed Agents — five new features
- `effort` on the agent's `model` object (a level string or `{"type": "<level>"}`).
It is agent-configuration only: setting it in a per-session `model` override is
silently ignored.
- Optional `version` on agent update, for optimistic concurrency. Omit it for
last-write-wins.
- `initial_events` on session create, collapsing create plus first send into one
call. Validation is all-or-nothing and only `user.message` and
`user.define_outcome` are accepted.
- Environment and memory-store webhooks: four `environment.*` events and three
`memory_store.*` events.
- Event deltas on per-thread streams. Previews are thread-scoped, so a child
thread's previews never reach the session-level stream.
## Corrections to behavior the skill already documented
- Tool output offload triggers at 100,000 characters (~25k tokens), not 100K
tokens, and covers built-in tools rather than MCP alone.
- `system.message` works on four models, checks only the primary model, appends
system context instead of replacing the prompt, and is accepted during a
`requires_action` idle when it trails a tool result in the same request.
- Vault-to-MCP credential matching is normalized (scheme and host lowercased,
default ports and trailing slashes stripped), not byte-exact.
- Multiagent depth greater than 1 is a validation error, not silently ignored.
- Outcome `interrupted` fires even when evaluation never started, and then
carries an empty-string `outcome_evaluation_start_id`.
- Deployment jitter is 15% of the run interval, floor 5s, cap 9 minutes.
- Webhooks retry three times with jittered 5-120s backoff, then drop silently.
Auto-disable is duration-based with three named triggers.
- `session.status_terminated` means completion or error.
- `agent.thinking` is a progress signal and carries no thinking content.
- `processed_at` is already populated on first sighting for
`user.define_outcome`, `user.custom_tool_result`, and `user.tool_result`.
- Session creation does not provision the sandbox.
- Skill `version` applies to Anthropic-authored skills too.
- Console-created vault credentials are header-injection only, and vault
environment-variable substitution skips secrets in URL paths.
- Console trace URLs need the real workspace ID when the API key is not in the
Default workspace.
## Elsewhere in the skill
- Note partner pricing under the first-party price table: Microsoft Foundry
bills at standard API rates, while Amazon Bedrock and Vertex AI are
partner-operated with separate pricing.
- Correct the tool-runner human-in-the-loop guidance, which previously pointed
readers at the manual loop for approval gates the runner's per-turn hooks
already cover.
- Repoint links away from the retired documentation hosts.
- Dedupe eagerly loaded SKILL.md content that the per-section files already
cover.
This commit is contained in:
@@ -73,7 +73,7 @@ with client.messages.stream(
|
||||
|
||||
## Streaming with Tool Use
|
||||
|
||||
The Python tool runner currently returns complete messages. Use streaming for individual API calls within a manual loop if you need per-token streaming with tools:
|
||||
The Python tool runner supports streaming: pass `stream=True` to `client.beta.messages.tool_runner(...)` and each iteration yields a stream you consume event-by-event, with `get_final_message()` for the accumulated message per turn (see `shared/tool-use-concepts.md` → Tool Runner vs Manual Loop). Use the manual-loop pattern below only when you're not using the tool runner and need per-token streaming with tools:
|
||||
|
||||
```python
|
||||
with client.messages.stream(
|
||||
|
||||
@@ -47,6 +47,43 @@ For async usage, use `@beta_async_tool` with `async def` functions.
|
||||
- Tool schemas are generated automatically from function signatures
|
||||
- Iteration stops automatically when Claude has no more tool calls
|
||||
|
||||
### Server tools with the tool runner
|
||||
|
||||
The runner's `tools` list accepts raw server-tool definitions (`web_search_20260209`, `web_fetch_20260209`, code execution) alongside decorated tools — pass the literal tool dict; server tools run on Anthropic's servers, so there is no function to implement.
|
||||
|
||||
**Caution — the runner does not auto-resume `pause_turn` (as of `anthropic` 0.116.0).** A long-running server-tool turn can stop with `stop_reason: "pause_turn"`. The runner only continues after a client tool produces a result, so a paused turn ends the loop and is returned as the final message — no error, no warning, just a silently truncated answer. Unlike the TypeScript runner, the Python runner cannot be resumed mid-loop: it exits unconditionally when no client tool ran, and `runner.append_messages(...)` does not prevent the exit. To handle `pause_turn`, mirror the conversation history as you iterate, then restart the runner with the paused turn appended:
|
||||
|
||||
```python
|
||||
messages = [{"role": "user", "content": user_input}]
|
||||
|
||||
max_restarts = 5 # cap pause_turn restarts, mirroring max_continuations advice
|
||||
restarts = 0
|
||||
while True:
|
||||
runner = client.beta.messages.tool_runner(
|
||||
model="claude-opus-4-8",
|
||||
max_tokens=16000,
|
||||
tools=tools, # may mix @beta_tool functions and server-tool definitions
|
||||
messages=messages,
|
||||
)
|
||||
last = None
|
||||
for message in runner:
|
||||
last = message
|
||||
# Mirror the history — the runner keeps its own copy and does not expose it
|
||||
messages.append({"role": "assistant", "content": message.content})
|
||||
tool_response = runner.generate_tool_call_response() # cached; tools still run once
|
||||
if tool_response is not None:
|
||||
messages.append(tool_response)
|
||||
if last is None or last.stop_reason != "pause_turn":
|
||||
break
|
||||
restarts += 1
|
||||
if restarts > max_restarts:
|
||||
raise RuntimeError("giving up: turn still paused after max_restarts")
|
||||
# Paused mid-turn: `messages` already ends with the paused assistant
|
||||
# turn, so the next runner resumes it
|
||||
```
|
||||
|
||||
Alternatively, use the manual loop below, which handles `pause_turn` explicitly.
|
||||
|
||||
---
|
||||
|
||||
## MCP Tool Conversion Helpers
|
||||
@@ -130,7 +167,9 @@ Conversion functions raise `UnsupportedMCPValueError` if an MCP value cannot be
|
||||
|
||||
## Manual Agentic Loop
|
||||
|
||||
Use this when you need fine-grained control over the loop (e.g., custom logging, conditional tool execution, human-in-the-loop approval):
|
||||
Prefer the tool runner above. Drop to a manual loop only when you need control the runner does not expose (e.g., a custom transport, request shapes the SDK cannot build, or avoiding a beta dependency — the runner is beta). Human-in-the-loop approval does *not* require a manual loop — gate inside the tool function (return a "user declined" result) or inspect pending `tool_use` blocks in the `for message in runner:` body and call `runner.set_messages_params()`.
|
||||
|
||||
If you do need a manual loop:
|
||||
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
Reference in New Issue
Block a user