Metadata-Version: 2.5
Name: harnessweaver-anthropic
Version: 0.2.0
Summary: HarnessWeaver plugin: Anthropic models.
Author-email: Muthu Kumaran R <rsmk7new@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,ai,governance,guardrails,harness,llm,observability
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: anthropic>=1.12
Requires-Dist: harnessweaver>=0.18.0
Description-Content-Type: text/markdown

# harnessweaver-anthropic

A first-party [HarnessWeaver](../../../README.md) plugin for Claude models. It is built on the same plugin contract any third-party plugin uses: one `hw.Plugin` object, published through the `harnessweaver.plugins` entry point under the namespace `anthropic` (see DESIGNS.md No. 13).

```bash
uv add harnessweaver-anthropic     # or: uv add "harnessweaver[anthropic]"
```

## `anthropic.messages`: a model provider

```yaml
models:
  provider: anthropic.messages
  default: strong
  aliases: { strong: claude-opus-5-5, fast: claude-haiku-5-5 }
  effort: high
```

| Setting | Default | Meaning |
| --- | --- | --- |
| `model` | `claude-opus-5-5` | When a request names no model |
| `max_tokens` / `stream_max_tokens` | `16000` / `64000` | When a request sets none |
| `thinking` | `adaptive` | Or `none` to omit the parameter |
| `effort` | the model's default | `low`, `medium`, `high`, `xhigh`, `max` |
| `fallbacks` | `default` | Server-side refusal fallbacks (beta `server-side-fallback-2026-07-01`); `none` turns them off |
| `structured_outputs` | `false` | Send output schemas as `output_config.format` (they must meet its rules); otherwise the schema goes in the system prompt |
| `sampling` | `false` | Forward `temperature` (older models only); current models reject sampling parameters |
| `timeout` | `600s` | Per request |
| `max_retries` | `2` | SDK retries; set `0` behind a gateway, which then owns retries (R5) |
| `cost_header` | `x-litellm-response-cost` | A gateway's reported cost, used before `models.prices` |
| `base_url`, `api_key_env` | SDK defaults | Client settings. Credentials follow the SDK's own resolution unless `api_key_env` names a variable |
| `hold_stream` | `false` | Deliver a streamed answer's chunks only once it has finished, so nothing from a declined answer reaches the app. Output is no longer live |

Server-side fallbacks are on by default: a request a model declines for policy reasons is re-run on Anthropic's recommended fallback model, and on a model without fallbacks the request simply runs alone. A request that is still declined ends the run `blocked` with code `model_refusal`, and its tokens still count.

Each answer's own content blocks, thinking included, are replayed unchanged on the next request of a tool loop, so the model's reasoning carries over (ADR-0022). An answer the harness changed (a redaction) is replayed without its thinking, consistently, so the history stays append-only.

## `harness.instrument(client)`

```python
client = harness.instrument(AsyncAnthropic())
message = await client.messages.create(model="claude-opus-5-5", max_tokens=1024, messages=[...])
```

`messages.create` calls are governed: traced, budgeted and guarded (`input.before` on the system prompt and message text, `output.before` on the answer), with redactions written back. Everything else, including `client.beta.messages`, passes through. Streaming through an instrumented client is *planned* and raises for now.

## Conformance

From this package's directory (at the repository root, `make conformance` checks every first-party plugin):

```bash
uv run pytest --harnessweaver-conformance=anthropic
```
