daimon 0.17.0

A Rust-native AI agent framework
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.17.0] - 2026-07-06

### Removed

- **Non-spec MCP WebSocket transport**`WebSocketTransport` and `McpWsServer` have been removed. stdio and HTTP are the MCP specification transports; the WebSocket transport was non-standard.
- **gRPC MCP transport**`McpGrpcServer` and `McpGrpcTransport` have been removed. The gRPC transport was non-spec and its `notify()` was a no-op.
- The `tokio-tungstenite` dependency has been dropped from the `mcp` feature.

### Changed

- **BREAKING: `DaimonError` is now `#[non_exhaustive]`.** Downstream code that matches on `DaimonError` exhaustively must add a wildcard (`_`) arm.
- **BREAKING: `prompt_stream` now runs the full ReAct loop like `prompt`.** It loads and **persists** conversation memory, fires lifecycle hooks, enforces `max_budget`, and applies input/output guardrails — previously it did none of these, so a streamed turn left the agent amnesiac and unguarded.
- **Streaming tool-call arguments are now correctly correlated** — argument deltas are matched to their tool call by block index. Previously the delta id was empty, so streamed tool calls were dropped or executed with empty arguments.
- **All five streaming parsers now handle UTF-8 split across chunks** — byte-accurate line buffering prevents multi-byte characters split across chunk boundaries from degrading to U+FFFD.
- **`Dag` and `Workflow` now share one topological scheduler** — the duplicated Kahn's-algorithm implementation was extracted into `orchestration::toposort`.

### Fixed

- **Anthropic/Bedrock streaming tool-calls executed with empty arguments** — the argument deltas were not correlated to their tool call, so tools ran with `{}` input.
- **Bedrock negative-integer corruption** — negative integers were cast through `PosInt` and corrupted; they now map to `NegInt`.
- **`FileCheckpoint` path traversal and non-atomic writes**`run_id` is now validated (traversal and absolute paths rejected) and writes are performed write-then-rename atomically.
- **NATS/AMQP ack-before-processing** — acknowledgement is now deferred until the task is processed, making the documented at-least-once guarantee real.
- **MCP stdio response cross-wiring** — the write+read round trip is serialized so concurrent tool calls can no longer receive each other's responses.
- **Unbounded MCP Content-Length** — the framing layer now caps Content-Length (32 MiB) before allocating.
- **Timing-unsafe API-key comparison**`AgentServer` now compares API keys in constant time.
- **Unbounded A2A task map** — the task map is now bounded with terminal-state eviction.
- **OTel endpoint ignored** — the configured OTLP endpoint is now actually applied.
- **pgvector table-name SQL injection and unbounded L2 score** — table identifiers are validated and a bounded L2 score is used.
- **Ollama `max_tokens` ignored**`max_tokens` is now honored via `num_predict`.
- **API keys leaked via `Debug`**`api_key` is now redacted in `Debug` output for OpenAI/Gemini/Azure.

### Added

- **`Message::assistant_with_text_and_tool_calls`** — preserves assistant text emitted alongside tool calls in conversation history.
- **`A2aHandler::with_max_tasks`** — configures the bound on the A2A task map.
- **`DistanceMetric` now derives `Default`.**
- **docs.rs all-features metadata** on every crate.
- **Runnable pgvector and opensearch RAG examples** (`examples/rag_pgvector.rs`, `examples/rag_opensearch.rs`).

## [0.16.0] - 2026-03-04

### Added

- **`daimon-plugin-opensearch` crate** — OpenSearch k-NN backed `VectorStore` implementation using the official `opensearch-rs` client. Supports cosine similarity, L2, and inner-product distance metrics with HNSW indexing via Lucene, NMSLIB, or FAISS engines. Auto-creates k-NN index by default; JSON exported in `index_settings` module for manual setups.
- **`OpenSearchVectorStoreBuilder`** — builder pattern for configuring index name, space type, engine, HNSW `m` and `ef_construction` parameters, with `build_with_client()` for custom transport (AWS SigV4, etc.).
- **`opensearch` feature flag** in the main `daimon` crate for opt-in OpenSearch support (included in `full`).
- **`aws-auth` feature** on `daimon-plugin-opensearch` for Amazon OpenSearch Service SigV4 authentication.

## [0.15.0] - 2026-03-04

### Added

- **`daimon-plugin-pgvector` crate** — pgvector-backed `VectorStore` implementation using `tokio-postgres` and `deadpool-postgres` for connection pooling. Supports cosine, L2, and inner-product distance metrics with HNSW indexing. Auto-migrates schema by default; raw SQL exported in `migrations` module for manual setups.
- **`PgVectorStoreBuilder`** — builder pattern for configuring table name, distance metric, pool size, HNSW `m` and `ef_construction` parameters.
- **`pgvector` feature flag** in the main `daimon` crate for opt-in pgvector support (included in `full`).

### Changed

- **Moved `Document`, `ScoredDocument`, `VectorStore`, `ErasedVectorStore`, `SharedVectorStore` to `daimon-core`** — plugin crates can now implement `VectorStore` by depending only on `daimon-core`. The main `daimon` crate re-exports everything; existing code is unaffected.

## [0.14.0] - 2026-03-04

### Changed

- **ToolRegistry: generation-based cache invalidation**`tool_specs()` now uses a generation counter to detect stale caches. Added `tool_specs_mut()` for callers with `&mut self` that need to persist the computed specs into the cache. `warm_cache()` now delegates to `tool_specs_mut()`, avoiding duplicate logic. Uncached spec generation **-33%** (10.4us to 6.9us).
- **SlidingWindowMemory & TokenWindowMemory: contiguous slice clone**`get_messages()` now calls `make_contiguous().to_vec()` instead of `iter().cloned().collect()`, producing a single memcpy when the deque is already contiguous and avoiding per-element overhead.
- **SlidingWindowMemory: single-pop eviction** — replaced `while messages.len() > max` loop with a single `if len >= max { pop_front() }` since at most one message is added at a time.
- **ReAct loop: reduced cloning** — tool calls are now moved out with `std::mem::take` instead of `.to_vec()` when the response message is consumed. Middleware short-circuit paths move messages instead of cloning them.
- **MiddlewareStack: early return when empty** — all three middleware pipeline methods (`run_on_request`, `run_on_response`, `run_on_tool_call`) now return `Continue` immediately when no middleware is registered, avoiding async iteration overhead on the hot path. Chain transforms benchmark **-30%** (287ns to 210ns).
- **Fixed unused assignment warning** in `runner.rs` short-circuit branch.

### Added

- **New benchmarks** for `HotSwapAgent` (prompt, swap_model), `InProcessBroker` (submit/receive/complete roundtrip), `InProcessEventBus` (publish/receive), `InMemoryCheckpoint` (save/load), and `SerializableStreamEvent` (serialize/deserialize).

## [0.13.0] - 2026-03-04

### Added

- **TaskBroker trait moved to `daimon-core`**: `TaskBroker`, `ErasedTaskBroker`, `AgentTask`, `TaskResult`, and `TaskStatus` now live in `daimon-core::distributed`, enabling provider crates to implement cloud-native brokers. The main `daimon` crate re-exports everything — existing code is unaffected.

- **AWS SQS task broker** (`daimon-provider-bedrock`, `feature = "sqs"`):
  - `SqsBroker` implementing `TaskBroker` via `aws-sdk-sqs`.
  - Uses SQS visibility timeout for in-flight task tracking, long polling for `receive()`.
  - `new()` with default credentials, `with_region()`, `from_client()` constructors.
  - Configurable visibility timeout via `with_visibility_timeout()`.
  - Deletes messages on `complete()`, releases visibility on `fail()`.

- **Google Cloud Pub/Sub task broker** (`daimon-provider-gemini`, `feature = "pubsub"`):
  - `PubSubBroker` implementing `TaskBroker` via Pub/Sub REST API.
  - Base64-encoded JSON message bodies for cross-platform compatibility.
  - `with_api_key()` and `with_bearer_token()` authentication modes.
  - Refreshable bearer token via `set_bearer_token()`.
  - Acknowledges messages on `complete()`, drops ack on `fail()` for automatic retry.

- **Azure Service Bus task broker** (`daimon-provider-azure`, `feature = "servicebus"`):
  - `ServiceBusBroker` implementing `TaskBroker` via Service Bus REST API.
  - Peek-lock receive with configurable lock duration.
  - SAS token authentication.
  - Deletes messages on `complete()`, releases lock on `fail()` for redelivery.

- **New feature flags** in the main `daimon` crate: `sqs`, `pubsub`, `servicebus` (all included in `full`).

## [0.12.0] - 2026-03-04

### Added

- **NATS KV checkpoint backend** (`src/checkpoint/nats_kv.rs`, `feature = "nats"`):
  - `NatsKvCheckpoint` implementing `Checkpoint` using NATS JetStream key-value store.
  - Distributed, replicated checkpoint storage with no external database.
  - `connect()` creates or opens a KV bucket; `from_store()` wraps an existing handle.
  - Keys prefixed with `cp.` for namespace isolation.

- **Redis checkpoint backend** (`src/checkpoint/redis.rs`, `feature = "redis"`):
  - `RedisCheckpoint` implementing `Checkpoint` using Redis hashes.
  - Fast, shared checkpoint storage accessible from multiple processes.
  - Uses `{prefix}:data` hash key for all checkpoint data.

- **Agent hot-reload** (`src/agent/hot_swap.rs`):
  - `HotSwapAgent` wraps an `Agent` behind a `RwLock` for runtime reconfiguration.
  - `swap_model()`, `swap_system_prompt()`, `swap_memory()`, `swap_hooks()` for swapping core components.
  - `add_tool()`, `remove_tool()` for dynamic tool management.
  - `swap_middleware()`, `add_middleware()` for middleware stack changes.
  - `add_input_guardrail()`, `add_output_guardrail()`, `clear_input_guardrails()`, `clear_output_guardrails()`.
  - `set_max_iterations()`, `set_temperature()`, `set_max_tokens()`, `set_validate_tool_inputs()`, `set_tool_retry_policy()`.
  - `replace()` for atomic full-agent swap.
  - Clone-friendly: all clones share the same underlying agent.

- **Streaming distributed execution** (`src/distributed/streaming.rs`):
  - `TaskEventBus` trait for publishing stream events across process boundaries.
  - `InProcessEventBus` backed by `tokio::sync::broadcast` for single-process use.
  - `StreamingTaskWorker` uses `Agent::prompt_stream()` and publishes each `StreamEvent` through the event bus.
  - `TaskStreamEvent` and `SerializableStreamEvent` for cross-process serializable stream events.
  - All `StreamEvent` variants mapped to serializable equivalents with full round-trip support.

## [0.11.0] - 2026-03-03

### Added

- **NATS JetStream task broker** (`src/distributed/nats_broker.rs`, `feature = "nats"`):
  - `NatsBroker` implementing `TaskBroker` for durable, at-least-once task delivery via NATS JetStream.
  - Uses a JetStream stream with `WorkQueue` retention and pull-based consumers with explicit ack.
  - `NatsBroker::connect(url, stream_name)` auto-creates the stream and configures subjects.
  - New `nats` feature flag adding `async-nats` dependency.
  - Re-exported from `daimon::distributed::NatsBroker` and prelude.

- **RabbitMQ task broker** (`src/distributed/amqp_broker.rs`, `feature = "amqp"`):
  - `AmqpBroker` implementing `TaskBroker` via AMQP 0-9-1 (RabbitMQ).
  - Durable queue with `delivery_mode = 2` (persistent messages) and manual acknowledgement.
  - `AmqpBroker::connect(url, queue_name)` declares the queue and creates a channel.
  - New `amqp` feature flag adding `lapin` dependency.
  - Re-exported from `daimon::distributed::AmqpBroker` and prelude.

- **gRPC MCP transport** (`src/mcp/grpc_transport.rs`, `feature = "grpc"` + `feature = "mcp"`):
  - `McpGrpcServer` wraps an `McpServer` and serves MCP tools over gRPC with typed RPCs for Initialize, ToolsList, ToolsCall, plus a raw HandleRaw passthrough.
  - `McpGrpcTransport` implements `McpTransport` by connecting to a remote gRPC MCP server, enabling transparent gRPC-backed MCP tool discovery and execution.
  - Proto definition in `proto/daimon_mcp.proto`.
  - Conditionally compiled when both `grpc` and `mcp` features are enabled.
  - Re-exported from `daimon::mcp::{McpGrpcServer, McpGrpcTransport}` and prelude.

- **Distributed checkpoint sync** (`src/checkpoint/sync.rs`):
  - `CheckpointSync` — write-through checkpoint combining a local (fast) and remote (shared) backend. Saves write to both; loads prefer local with remote fallback and automatic backfill. `list_runs()` returns the union.
  - `CheckpointSync::pull_all()` / `push_all()` for bulk bidirectional synchronization.
  - `CheckpointReplicator` — background task that periodically pulls new checkpoints from remote to local at a configurable interval.
  - Both implement/compose the existing `Checkpoint` trait; no new feature flag required.
  - Re-exported from `daimon::checkpoint::{CheckpointSync, CheckpointReplicator}` and prelude.

- **Redis task broker** (`src/distributed/redis_broker.rs`, `feature = "redis"`):
  - `RedisBroker` implementing `TaskBroker` for multi-process distributed execution.
  - Uses Redis Lists (`LPUSH`/`BRPOP`) for the task queue with 1-second blocking pop.
  - Status tracked in a Redis Hash (`{prefix}:status`); results stored in `{prefix}:results`.
  - Supports configurable key prefix for namespace isolation.
  - Serializes `AgentTask` and `TaskResult` as JSON for cross-language interoperability.

- **Builder-style agent fork** (`src/agent/fork.rs`):
  - `Agent::fork_builder()` returns a `ForkBuilder` pre-populated with the parent agent's config.
  - Mutate any field before building: `system_prompt()`, `no_system_prompt()`, `model()`, `tool()`, `remove_tool()`, `memory()`, `hooks()`, `middleware()`, `input_guardrail()`, `output_guardrail()`, `max_iterations()`, `temperature()`, `max_tokens()`, `validate_tool_inputs()`, `tool_retry_policy()`.
  - `build()` produces an independent forked agent with the specified mutations applied.
  - Enables patterns like A/B testing agent configurations, role specialization from a base agent, and checkpoint-based branching with modified tools.

- **`ToolRegistry::unregister()`** (`src/tool/registry.rs`):
  - Removes a tool by name. Returns `true` if the tool was present.
  - Invalidates spec and validator caches on removal.

- **WebSocket MCP server** (`src/mcp/ws_server.rs`, `feature = "mcp"`):
  - `McpWsServer` listens on a TCP port and serves MCP tools over WebSocket connections.
  - Each connection handled in a separate task for concurrent multi-client support.
  - Reuses `McpServer::handle_request_raw()` for JSON-RPC dispatch (initialize, tools/list, tools/call).
  - `McpWsServer::new(registry)` or `McpWsServer::from_server(server)` constructors.
  - `serve(addr)` for production (runs indefinitely) and `serve_one(addr)` for testing.
  - Re-exported from `daimon::mcp::McpWsServer` and `daimon::prelude::McpWsServer`.

- **gRPC transport for distributed execution** (`src/distributed/grpc.rs`, `feature = "grpc"`):
  - `GrpcBrokerServer` wraps any `TaskBroker` (or `ErasedTaskBroker`) and serves it as a gRPC service.
  - `GrpcBrokerClient` connects to a remote gRPC broker and implements `TaskBroker` transparently.
  - Proto service definition in `proto/daimon_distributed.proto` with Submit, GetStatus, Complete, and Fail RPCs.
  - JSON encoding for task/result payloads ensures cross-language compatibility.
  - New `grpc` feature flag adding `tonic` and `prost` dependencies.
  - `tonic-build` compiles proto at build time (conditional on `grpc` feature).
  - Re-exported from `daimon::distributed::{GrpcBrokerServer, GrpcBrokerClient}` and prelude.

- **Streaming cost tracking** (`daimon-core/src/stream.rs`, `src/agent/runner.rs`):
  - New `StreamEvent::Usage { iteration, input_tokens, output_tokens, estimated_cost }` variant emitted after each ReAct iteration in `prompt_stream()`.
  - Token counts are estimated from character length (~4 chars/token) since streaming providers typically don't report usage inline.
  - When a `CostModel` is configured on the agent, `estimated_cost` accumulates across iterations.
  - Non-breaking addition to the existing streaming API (new enum variant).

- **Agent cloning / forking** (`src/agent/fork.rs`):
  - `Agent::fork()` — creates a new agent sharing the same model, tools, hooks, middleware, and guardrails but with independent (empty) memory.
  - `Agent::fork_from_checkpoint(run_id, checkpoint)` — forks with memory pre-loaded from a saved checkpoint. Enables "what-if" branching: modify tools or system prompt on the fork and diverge from a historical run.
  - `Agent::fork_with_memory(memory)` — forks with a custom memory backend (e.g. switch from in-memory to SQLite).
  - All forked agents share model/tools via `Arc` — lightweight and memory-efficient.

- **Distributed agent execution** (`src/distributed/`):
  - `TaskBroker` trait with `submit`, `status`, `receive`, `complete`, and `fail` methods for distributing agent tasks across workers.
  - `ErasedTaskBroker` object-safe wrapper for dynamic dispatch.
  - `InProcessBroker` backed by tokio MPSC channels for single-process parallelism and testing.
  - `AgentTask` — serializable unit of work with input, optional run ID, and metadata.
  - `TaskResult` — serializable output with text, iterations, cost, and error fields.
  - `TaskStatus` enum: `Pending`, `Running`, `Completed(TaskResult)`, `Failed(String)`.
  - `TaskWorker` with `run_once()`, `run()` (continuous loop), and `run_parallel(concurrency)` for concurrent task processing.
  - Agent factory pattern ensures each task gets independent memory.
  - Implement `TaskBroker` for Redis, NATS, or RabbitMQ to enable multi-process/multi-machine execution.

- **WebSocket transport for MCP** (`src/mcp/websocket.rs`):
  - `WebSocketTransport` implementing `McpTransport` for persistent WebSocket connections.
  - Supports `ws://` and `wss://` (TLS via rustls) connections.
  - JSON-RPC messages sent as text frames; automatic ping/pong handling.
  - Thread-safe via internal mutex on the WebSocket stream.
  - New `tokio-tungstenite` dependency (optional, behind `mcp` feature).
  - Re-exported from `daimon::mcp::WebSocketTransport`.

- **Middleware pipeline** (`src/middleware/`):
  - `Middleware` trait with `on_request(&mut ChatRequest)`, `on_response(&mut ChatResponse)`, and `on_tool_call(&mut ToolCall)` hooks.
  - `MiddlewareAction` enum: `Continue` or `ShortCircuit(ChatResponse)` for early exit.
  - `MiddlewareStack` chains layers in registration order; first non-`Continue` action short-circuits.
  - Object-safe `ErasedMiddleware` wrapper for dynamic dispatch.
  - `AgentBuilder::middleware()` to add layers.
  - Wired into the ReAct loop (request/response mutation) and tool execution path.

- **Guardrails** (`src/guardrails/`):
  - `InputGuardrail` trait: validates user input before the model sees it.
  - `OutputGuardrail` trait: validates model output before returning to caller.
  - `GuardrailResult` enum: `Pass`, `Block(String)`, `Transform(String)`.
  - Built-in `MaxTokenGuardrail` — rejects inputs exceeding an estimated token limit.
  - Built-in `RegexFilterGuardrail` — block or redact text matching regex patterns (PII, profanity).
  - `AgentBuilder::input_guardrail()` and `AgentBuilder::output_guardrail()` methods.
  - `DaimonError::GuardrailBlocked` error variant.

- **Prompt templates** (`src/prompt/`):
  - `PromptTemplate` with `{variable}` placeholder interpolation via `render_static()` and `render_with()`.
  - `PromptBuilder` for composing sections: persona, instructions, constraints, examples, and custom sections.
  - `AgentBuilder::prompt_template()` as an alternative to `system_prompt()`.

- **Cost tracking and budget limits** (`src/cost/`):
  - `CostModel` trait mapping `(model_id, TokenDirection)` to per-token USD cost.
  - Built-in `OpenAiCostModel` and `AnthropicCostModel` with approximate pricing.
  - `CostTracker` with lock-free atomic accumulation (micro-dollar precision).
  - `AgentBuilder::cost_model()` and `AgentBuilder::max_budget()` — aborts with `DaimonError::BudgetExceeded` when limit is crossed.
  - `AgentResponse.cost` field for per-prompt cost in USD.

- **Embeddings API** (`daimon-core/src/embedding.rs`):
  - `EmbeddingModel` trait with `embed(&[&str]) -> Vec<Vec<f32>>` and `dimensions()`.
  - `ErasedEmbeddingModel` object-safe wrapper and `SharedEmbeddingModel` type alias.
  - `OpenAiEmbedding` provider (text-embedding-3-small/large) behind `openai` feature.
  - `OllamaEmbedding` provider behind `ollama` feature.

- **Vector store integrations** (`src/retriever/`):
  - `InMemoryVectorStore` — brute-force cosine similarity for development and testing, no feature gate required.
  - `QdrantRetriever` (`feature = "qdrant"`) — retriever backed by Qdrant vector database via `qdrant-client`.
  - Both accept an `EmbeddingModel` and implement the existing `Retriever` trait.

- **Self-healing tool retry** (`src/tool/retry.rs`):
  - `ToolRetryPolicy` with `BackoffStrategy::Fixed` and `BackoffStrategy::Exponential`.
  - Configurable retryable error patterns — only retry errors matching specified substrings.
  - `AgentBuilder::tool_retry_policy()` applies to all tool calls.
  - Integrated into `execute_tools_parallel()` with backoff delays between attempts.

- **Deployment helpers** (`src/server/`, `feature = "http-server"`):
  - `AgentServer` wrapping an `Agent` behind an `axum` router.
  - `POST /prompt` — JSON request/response endpoint.
  - `POST /prompt/stream` — Server-Sent Events streaming endpoint.
  - `GET /health` — health check returning `"ok"`.
  - `AgentServer::new(agent).bind("0.0.0.0:8080").serve().await`.

- **Evaluation harness** (`src/eval/`, `feature = "eval"`):
  - `EvalScenario` with configurable input, scorers, max iterations, and max cost.
  - `Scorer` strategies: `ExactMatch`, `Contains`, `Regex`, and `Custom(Box<dyn Fn>)`.
  - `EvalRunner` executes scenarios with configurable concurrency.
  - `EvalResult` with pass/fail, output text, latency, cost, iteration count, and error details.

- **Time-travel debugging** (`src/checkpoint/replay.rs`):
  - `inspect_run()` reconstructs an `ExecutionTrace` from checkpoint message history.
  - `list_runs()` returns `RunSummary` for all checkpointed runs.
  - `TraceStep` captures per-iteration messages, tool calls, response text, and usage.
  - `ExecutionTrace` with `final_text()` and `total_tool_calls()` helpers.

- **`ContentPolicyGuardrail`** (`src/guardrails/content_policy.rs`):
  - LLM-as-judge guardrail that evaluates content against a policy description.
  - Implements both `InputGuardrail` and `OutputGuardrail` — usable on either side.
  - Configurable with any `SharedModel` and custom policy string.

- **`DynamicContext` trait** (`src/prompt/dynamic.rs`):
  - `DynamicContext` trait with `key()` and async `resolve()` for runtime prompt variable injection.
  - `ErasedDynamicContext` object-safe wrapper for dynamic dispatch.
  - `PromptTemplate::render_dynamic(&[&dyn ErasedDynamicContext])` resolves async contexts at render time.

- **`FewShotTemplate`** (`src/prompt/few_shot.rs`):
  - Builder for composing example input/output pairs with configurable labels and prefix.
  - `render()` produces a formatted string suitable for injection into prompts.

- **`SemanticSimilarity` scorer** (`src/eval/scoring.rs`):
  - New `Scorer::SemanticSimilarity` variant using `EmbeddingModel` for cosine similarity.
  - `Scorer::semantic(expected, embedding_model, threshold)` constructor.
  - `EvalScenario::expect_semantic()` convenience method.

- **`LlmJudge` scorer** (`src/eval/scoring.rs`):
  - New `Scorer::LlmJudge` variant using a `Model` to grade output against a rubric.
  - `Scorer::llm_judge(rubric, model)` constructor.
  - `EvalScenario::expect_llm_judge()` convenience method.
  - All `Scorer::evaluate()` methods are now async to support these advanced scorers.

- **`Agent::replay()`** (`src/agent/resumable.rs`):
  - Re-run a previous agent execution from a checkpoint with optionally modified context.
  - `from_iteration` parameter truncates to a specific iteration for "what-if" debugging.
  - Useful for testing changes to tools, system prompts, or models against prior runs.

- **Per-tool retry policy** (`src/tool/traits.rs`):
  - `Tool::retry_policy() -> Option<ToolRetryPolicy>` with default `None`.
  - Per-tool policy takes precedence over agent-level `tool_retry_policy` in the ReAct loop.
  - `ErasedTool` object-safe wrapper updated to forward `retry_policy()`.

- **API key authentication** (`src/server/mod.rs`):
  - `AgentServer::api_key()` builder method enables request authentication.
  - Supports `Authorization: Bearer <key>` and `X-API-Key: <key>` headers.
  - Returns 401 Unauthorized for missing or invalid keys.

- **Additional embedding providers**:
  - `GeminiEmbedding` (`daimon-provider-gemini`) — Google batchEmbedContents API.
  - `AzureOpenAiEmbedding` (`daimon-provider-azure`) — Azure OpenAI Embeddings API.
  - `BedrockEmbedding` (`daimon-provider-bedrock`) — Amazon Titan Embeddings via InvokeModel.

- **Vector Store plugin system** (`src/retriever/vector_store.rs`, `src/retriever/knowledge_base.rs`):
  - `VectorStore` trait with `upsert()`, `query()`, `delete()`, `count()` operations.
  - `ErasedVectorStore` object-safe wrapper and `SharedVectorStore` type alias.
  - `ScoredDocument` struct pairing documents with similarity scores.
  - `KnowledgeBase` trait for high-level ingest/search/remove/count operations.
  - `SimpleKnowledgeBase<V: VectorStore>` composing `EmbeddingModel` + `VectorStore`.
  - `SimpleKnowledgeBase` auto-implements `Retriever` for seamless agent integration.
  - `InMemoryVectorStoreBackend` implementing `VectorStore` for development/testing.
  - `ErasedKnowledgeBase` object-safe wrapper and `SharedKnowledgeBase` type alias.

- New feature flags: `http-server`, `qdrant`, `eval`.
- New dependencies: `regex-lite`, `axum` (optional), `tower-http` (optional), `qdrant-client` (optional).
- Updated `prelude` module with all new types.

## [0.2.0] - 2026-03-03

### Added

- **Provider prompt caching** across all backends:
  - **Anthropic**: `with_prompt_caching()` now correctly injects `cache_control` blocks on the system message and the last tool definition, enabling actual cache hits. Parses `cache_creation_input_tokens` and `cache_read_input_tokens` from usage with tracing.
  - **OpenAI**: Parses `prompt_tokens_details.cached_tokens` from the usage response (automatic prompt caching).
  - **Azure OpenAI**: Same as OpenAI — parses `prompt_tokens_details.cached_tokens`.
  - **Google Gemini**: New `with_cached_content(name)` builder method to reference a `cachedContents/<id>` resource. Parses `cachedContentTokenCount` from usage metadata.
  - **AWS Bedrock**: New `with_prompt_caching()` builder inserts `CachePoint` blocks after system messages and tool definitions. Parses `cache_read_input_tokens` from the Converse API response.
  - **Ollama**: New `with_keep_alive(duration)` builder to control KV cache retention (e.g. `"5m"`, `"1h"`, `"0"`).
- `Usage::cached_tokens` field — number of input tokens served from the provider's cache (subset of `input_tokens`, defaults to 0).

### Fixed

- **Anthropic caching was non-functional**: the `with_prompt_caching()` flag sent the beta header but never added `cache_control` content blocks, so no caching actually occurred. Now correctly marks the system prompt and last tool definition as cache breakpoints.

## [0.1.0] - 2026-03-03

### Added

- **Core framework** with ReAct (Reason-Act-Observe) agent loop.
- `Agent` struct with builder pattern for fluent configuration.
- `Agent::prompt()` for synchronous (non-streaming) agent responses.
- `Agent::prompt_stream()` with full streaming ReAct loop — accumulates tool call deltas, executes tools, re-invokes the model, all within a single `ResponseStream`.
- `Agent::prompt_with_messages()` for pre-built conversation histories.
- `Agent::prompt_with_cancellation()` with `tokio_util::CancellationToken` support.
- `AgentResponse` with aggregated `Usage` across all iterations.
- **Model trait** with `generate()` and `generate_stream()` async methods, plus object-safe `ErasedModel` wrapper for dynamic dispatch.
- **OpenAI provider** (`feature = "openai"`, default) — Chat Completions API with SSE streaming, tool calling, `response_format`, and `parallel_tool_calls` support.
- **Anthropic provider** (`feature = "anthropic"`, default) — Messages API with streaming, tool use blocks, prompt caching (`cache_control` beta header), and 529 overloaded retry.
- **Google Gemini provider** (`feature = "gemini"`) — Generative Language REST API with function calling, SSE streaming via `streamGenerateContent`, system instruction support. Configurable for Vertex AI via `with_base_url()` and `with_bearer_token()` for OAuth2.
- **Azure OpenAI provider** (`feature = "azure"`) — Azure OpenAI Service deployments with the same wire format as OpenAI. Supports both `api-key` header and Microsoft Entra ID bearer token authentication, configurable `api-version`.
- **AWS Bedrock provider** (`feature = "bedrock"`) — Converse/ConverseStream API via `aws-sdk-bedrockruntime`, with guardrails configuration.
- All providers: configurable HTTP timeout, max retries with exponential backoff for 429/5xx errors.
- **Tool trait** with `name()`, `description()`, `parameters_schema()`, and `execute()`, plus object-safe `ErasedTool` wrapper.
- `ToolRegistry` for named tool management with duplicate detection.
- `ToolOutput::text()`, `ToolOutput::json()`, and `ToolOutput::error()` constructors.
- Parallel tool execution within iterations via `tokio::task::JoinSet`.
- **Memory trait** with `add_message()`, `get_messages()`, and `clear()`, plus object-safe `ErasedMemory` wrapper.
- `SlidingWindowMemory` with configurable message window size.
- Tool-call messages (assistant + tool results) now persisted to memory alongside user/assistant messages.
- **AgentHook trait** for lifecycle events: `on_iteration_start`, `on_model_response`, `on_tool_call`, `on_tool_result`, `on_iteration_end`, `on_error`.
- **Streaming types**: `StreamEvent` enum with `TextDelta`, `ToolCallStart`, `ToolCallDelta`, `ToolCallEnd`, `ToolResult`, `Error`, and `Done` variants.
- **Error handling**: `DaimonError` with `Timeout` and `Cancelled` variants; retry logic in all providers.
- **Observability**: `tracing::instrument` spans on all agent methods and provider calls with structured fields (model_id, tool name/id, iteration, token counts).
- `prelude` module re-exporting common types including `CancellationToken`.
- Rustdoc on all public types, traits, methods, and modules.
- Six runnable examples: `simple_agent`, `with_tools`, `streaming`, `bedrock_agent`, `gemini_agent`, `azure_agent`.
- `cargo-husky` dev-dependency with `user-hooks` for automatic Git hook installation on `cargo test`.
- `pre-commit` hook: `cargo fmt --check` + `cargo clippy --features full -- -D warnings`.
- `commit-msg` hook: Conventional Commits validation via `cargo-commitlint`.
- `pre-push` hook: full test suite + documentation build check.
- GitHub Actions CI workflow (check, fmt, clippy, test, coverage gate at 90%, example compilation).
- `deny.toml` for `cargo-deny` license and advisory auditing.
- `commitlint.toml` for Conventional Commits enforcement.
- `rustfmt.toml` and `clippy.toml` for consistent code style.

[Unreleased]: https://github.com/Lexmata/daimon/compare/v0.17.0...HEAD
[0.17.0]: https://github.com/Lexmata/daimon/compare/v0.16.0...v0.17.0
[0.16.0]: https://github.com/Lexmata/daimon/compare/v0.15.0...v0.16.0
[0.15.0]: https://github.com/Lexmata/daimon/compare/v0.14.0...v0.15.0
[0.14.0]: https://github.com/Lexmata/daimon/compare/v0.13.0...v0.14.0
[0.13.0]: https://github.com/Lexmata/daimon/compare/v0.12.0...v0.13.0
[0.12.0]: https://github.com/Lexmata/daimon/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/Lexmata/daimon/compare/v0.2.0...v0.11.0
[0.2.0]: https://github.com/Lexmata/daimon/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/Lexmata/daimon/releases/tag/v0.1.0