Update claude-api skill: auth, cloud providers, Managed Agents fixes, token counting (#1276)

* Sync claude-api skill with latest upstream updates

- Add token-counting.md and SKILL.md trigger description update
- Add auth guidance: env credential resolution, ant auth login, OAuth/WIF doc links, 401 causes
- Add mid-conversation system messages (beta) to prompt-caching, agent-design, SKILL.md, Python/TS READMEs
- Add cache pre-warming (max_tokens: 0) section to prompt-caching
- Add Managed Agents pre-flight viability check to onboarding and overview
- Add Bedrock model-ID section to model-migration; add Bedrock row to live-sources
- Add /claude-api migrate subcommand row and migrate-entry callout
- Fix MA networking config: limited type with allow_package_managers/allow_mcp_servers
- Bump MA create-operations rate limit to 300 RPM
- Fix MA SDK drift: sessions.events.stream(), event.name, typed event arrays
- Add SDK coverage: stop_details, error .type, C# tool runner + MA support, Go model constants, Java 2.34.0, client config, response helpers, auto-pagination, advisor tool
- Move Sonnet 4 / Opus 4 to deprecated in models.md

* Add Anthropic CLI and Claude Platform on AWS docs to claude-api skill

- Add shared/anthropic-cli.md: install, auth profiles, OAuth scopes, command
  structure, version-controlled Managed Agents resources, credential traps
- Add shared/claude-platform-on-aws.md: AnthropicAWS clients, SigV4 auth,
  workspace_id, regions, feature availability
- Restore cross-references to both files throughout SKILL.md and the
  managed-agents docs (previously rewritten to live-sources.md pointers)
- Restore Claude Platform on AWS provider taxonomy in SKILL.md, the
  migration-guide section, and live-sources rows
This commit is contained in:
Lance Martin
2026-06-07 13:21:33 -07:00
committed by GitHub
parent da20c92503
commit c30d329f58
30 changed files with 960 additions and 83 deletions
+120 -4
View File
@@ -11,10 +11,12 @@ pip install anthropic
```python
import anthropic
# Default (uses ANTHROPIC_API_KEY env var)
# Default — resolves credentials from the environment:
# ANTHROPIC_API_KEY, or ANTHROPIC_AUTH_TOKEN, or an `ant auth login` profile.
# Prefer this for local dev; don't hardcode a key.
client = anthropic.Anthropic()
# Explicit API key
# Explicit API key (only when you must inject a specific key)
client = anthropic.Anthropic(api_key="your-api-key")
# Async client
@@ -23,6 +25,67 @@ async_client = anthropic.AsyncAnthropic()
---
## Client Configuration
### Per-request overrides
Use `with_options()` to override client settings for a single call without mutating the client:
```python
client.with_options(timeout=5.0, max_retries=5).messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
```
### Timeouts
Default request timeout is 10 minutes. Pass a float (seconds) or an `httpx.Timeout` for granular control. On timeout the SDK raises `anthropic.APITimeoutError` (and retries per `max_retries`).
```python
import httpx
client = anthropic.Anthropic(timeout=20.0)
client = anthropic.Anthropic(
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)
```
### Retries
The SDK auto-retries connection errors, 408, 409, 429, and ≥500 with exponential backoff (default 2 retries). Set `max_retries` on the client or via `with_options()`; `max_retries=0` disables.
### Async performance (aiohttp backend)
For high-concurrency async workloads, install `anthropic[aiohttp]` and pass `DefaultAioHttpClient` instead of the default httpx backend:
```python
from anthropic import AsyncAnthropic, DefaultAioHttpClient
async with AsyncAnthropic(http_client=DefaultAioHttpClient()) as client:
...
```
### Custom HTTP client (proxy, base URL)
Use `DefaultHttpxClient` / `DefaultAsyncHttpxClient` — not raw `httpx.Client` — so the SDK's default timeouts and connection limits are preserved:
```python
from anthropic import Anthropic, DefaultHttpxClient
client = Anthropic(
base_url="http://my.test.server.example.com:8083", # or ANTHROPIC_BASE_URL env var
http_client=DefaultHttpxClient(proxy="http://my.test.proxy.example.com"),
)
```
### Logging
Set `ANTHROPIC_LOG=debug` (or `info`) to enable SDK logging via the standard `logging` module.
---
## Basic Message Request
```python
@@ -53,6 +116,23 @@ response = client.messages.create(
)
```
### Mid-conversation system messages (beta, model-gated)
For operator instructions that arrive mid-conversation (mode switches, injected state), append `{"role": "system", ...}` to `messages` instead of editing top-level `system` — this preserves the cached prefix and carries operator authority. Must follow a user message; cannot be `messages[0]`. Unsupported models return a 400 (`role 'system' is not supported on this model`). See `shared/prompt-caching.md` for when to use this vs. top-level `system`.
```python
response = client.messages.create(
model=MODEL_ID, # must support mid-conversation system messages
max_tokens=16000,
system=[{"type": "text", "text": STABLE_SYSTEM, "cache_control": {"type": "ephemeral"}}],
messages=history + [
{"role": "user", "content": user_message},
{"role": "system", "content": "Terse mode enabled — keep responses under 40 words."},
],
extra_headers={"anthropic-beta": "mid-conversation-system-2026-04-07"},
)
```
---
## Vision (Images)
@@ -222,6 +302,31 @@ except anthropic.APIConnectionError:
---
## Response Helpers
Every response object exposes `_request_id` (populated from the `request-id` header) — log it when reporting failures to Anthropic. Despite the underscore prefix, this property is public.
```python
message = client.messages.create(...)
print(message._request_id) # req_018EeWyXxfu5pfWkrYcMdjWG
print(message.to_json()) # serialize the Pydantic model
print(message.to_dict()) # plain dict
```
To access raw headers or other response metadata, use `.with_raw_response`:
```python
raw = client.messages.with_raw_response.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(raw.headers.get("request-id"))
message = raw.parse() # the Message object messages.create() would have returned
```
---
## Multi-Turn Conversations
The API is stateless — send the full conversation history each time.
@@ -268,8 +373,9 @@ response2 = conversation.send("What's my name?") # Claude remembers "Alice"
**Rules:**
- Messages must alternate between `user` and `assistant`
- Consecutive same-role messages are allowed — the API combines them into a single turn
- First message must be `user`
- `role: "system"` messages are allowed mid-conversation under the `mid-conversation-system-2026-04-07` beta on supporting models — see § Mid-conversation system messages above
---
@@ -320,7 +426,17 @@ The `stop_reason` field in the response indicates why the model stopped generati
| `stop_sequence` | Hit a custom stop sequence |
| `tool_use` | Claude wants to call a tool — execute it and continue |
| `pause_turn` | Model paused and can be resumed (agentic flows) |
| `refusal` | Claude refused for safety reasons — output may not match your schema |
| `refusal` | Claude refused for safety reasons — check `stop_details` |
### Structured Stop Details
When `stop_reason` is `"refusal"`, the response includes a `stop_details` object with structured information about the refusal:
```python
if response.stop_reason == "refusal" and response.stop_details:
print(f"Category: {response.stop_details.category}") # "cyber" | "bio" | None
print(f"Explanation: {response.stop_details.explanation}")
```
---
@@ -100,6 +100,19 @@ print(f"Status: {cancelled.processing_status}") # "canceling"
---
## List Batches (auto-pagination)
Iterating the return value of any `list()` call auto-paginates across all pages — do not index into `.data` if you want the full set:
```python
for batch in client.messages.batches.list(limit=20):
print(batch.id, batch.processing_status)
```
For manual control, use `first_page.has_next_page()` / `first_page.get_next_page()` / `first_page.next_page_info()`; `first_page.data` holds the current page's items and `first_page.last_id` is the cursor.
---
## Batch with Prompt Caching
```python
@@ -16,14 +16,18 @@ The Files API uploads files for use in Messages API requests. Reference files vi
## Upload a File
The `file` argument accepts a `(filename, content, content_type)` tuple, a `pathlib.Path` (or any `PathLike` — read for you, async-safe with `AsyncAnthropic`), or an open binary file object.
```python
import anthropic
from pathlib import Path
client = anthropic.Anthropic()
uploaded = client.beta.files.upload(
file=("report.pdf", open("report.pdf", "rb"), "application/pdf"),
)
# or: client.beta.files.upload(file=Path("report.pdf"))
print(f"File ID: {uploaded.id}")
print(f"Size: {uploaded.size_bytes} bytes")
```
@@ -87,9 +91,10 @@ response = client.beta.messages.create(
### List Files
Iterate the list result directly — the SDK auto-paginates across all pages. Only use `.data` if you want the first page only.
```python
files = client.beta.files.list()
for f in files.data:
for f in client.beta.files.list():
print(f"{f.id}: {f.filename} ({f.size_bytes} bytes)")
```
@@ -24,6 +24,22 @@ async with async_client.messages.stream(
print(text, end="", flush=True)
```
### Low-level: `stream=True`
`messages.stream()` (above) is the recommended helper — it accumulates state and exposes `text_stream` / `get_final_message()`. If you only need the raw event iterator and want lower memory use, pass `stream=True` to `messages.create()` instead:
```python
for event in client.messages.create(
model="claude-opus-4-8",
max_tokens=64000,
messages=[{"role": "user", "content": "Write a story"}],
stream=True,
):
print(event.type)
```
No final-message accumulation is done for you in this form.
---
## Handling Different Content Types
@@ -160,3 +176,4 @@ except anthropic.APIStatusError as e:
3. **Track token usage** — The `message_delta` event contains usage information
4. **Use timeouts** — Set appropriate timeouts for your application
5. **Default to streaming** — Use `.get_final_message()` to get the complete response even when streaming, giving you timeout protection without needing to handle individual events
6. **Large `max_tokens` without streaming raises `ValueError`** — The SDK refuses non-streaming requests it estimates will exceed ~10 minutes (idle connections drop). Pass `stream=True` / use `messages.stream()`, or explicitly override `timeout`, to suppress the guard.