embacle 0.20.0

LLM runner library — wraps 12 AI CLI tools as pluggable LLM providers with agent loop, guardrails, and cost tracking
Documentation
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
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
# Changelog

## [0.20.0] — 2026-08-07

### Fixed

- fix: clear the warnings the flag removal left behind



## [0.19.7] — 2026-07-28



## [0.19.6] — 2026-07-13



## [0.19.5] — 2026-07-10

### Fixed

- fix(claude-code): classify prompt-too-long as ContextLength (400), not 502
- fix(clippy): backtick doc addrs, is_ok_and, unwrap-free auth tests CI clippy --all-targets flagged doc_markdown (127.0.0.0/8, ::1) + map().unwrap_or -> is_ok_and in is_loopback_host; arch-validation counted 3 test unwrap()s — replaced with matches!. Fixes the 52d04d6 CI failure.

### Other

- test(copilot_headless): annotate safe test unwraps for arch-validation 15 test-only unwrap sites (tempdir/fs/serde setup) get same-line // Safe: comments; zero flagged remain



## [0.19.4] — 2026-06-29

### Added

- feat(ci): auto-validate Homebrew install after release release.yml now calls homebrew.yml (reusable workflow_call) as a final gated job once the tap formula is pushed, passing the released version for an exact match; drops the vestigial push:tags trigger (GITHUB_TOKEN tag pushes never fired it and would race the formula update). workflow_dispatch retained for manual runs.

### Fixed

- fix(copilot-headless): route ACP sessions to the configured model via settings.json copilot --acp routes by ~/.copilot/settings.json "model" and ignores both the session/new model field and the --model flag (cosmetic label only); write the model into settings.json before each spawn (preserving other keys), track the warm-process model and respawn on change, and log the real routing model — fixes ACP sessions silently falling through to the account GPT/Gemini default while logs claimed the requested model.
- fix(ci): trust dravr-ai tap for Homebrew 6.0 install (ubuntu) Homebrew 6.0 refuses untrusted third-party taps; brew trust dravr-ai/tap (|| true for older brew) before install. Last of 4 Homebrew jobs.
- fix(ci): make Homebrew test harness pass (llvm-nm, linuxbrew PATH, 503 health) macOS FFI symbols via toolchain llvm-nm (Apple nm can't read Rust 1.96 LLVM objects); add linuxbrew to PATH on ubuntu (brew not found); smoke test accepts degraded 503 /health (no provider CLIs in CI) by dropping curl -f. All validated locally.



## [0.19.3] — 2026-06-22

### Added

- feat(mcp): migrate to dravr-tronc 0.5.3; release v0.19.2 ActiveConfig->interior RwLock (provider/model/multiplex accessors &self async); init protocolVersion now 2025-11-25; -mcp/-server only.
- feat(release): adopt dravr-tronc 0.3 via coordinated republish (embacle-mcp/server 0.19.1) Republish embacle-mcp+embacle-server 0.19.1 on tronc 0.3.1 so the publish graph resolves a single tronc version; root embacle (no tronc dep) stays 0.19.0.

### Fixed

- fix(ci): combine publish dry-run into one workspace invocation Per-crate dry-run resolved internal embacle dep vs crates.io (only 0.19.0 there, not the unpublished 0.19.2) and failed; co-publishing all three resolves siblings locally. Verified cargo 1.96.0 exit 0.

### Other

- style(lints): enforce error-handling restriction lints; create_runner_with_config -> Result Sole prod fix: ClaudeWeb embedded-config parse propagated via ? (was expect); crate-root cfg_attr(test, allow) + tests/examples allow attrs; --all-targets clippy green.
- Revert "chore(deps): bump dravr-tronc 0.2 -> 0.3" (publish-dry-run version skew) embacle-server publishes against registry embacle-mcp 0.19.0 (tronc 0.2) -> two tronc versions clash; needs a coordinated member-crate release to adopt 0.3.
- chore(deps): bump dravr-tronc 0.2 -> 0.3 (now published to crates.io) Server/mcp crates compile against 0.3.1; picks up otel + NotifyLayer + error-handling fixes.



## [0.19.2] — 2026-06-19

### Changed

- deps: migrate `embacle-mcp` and `embacle-server` to dravr-tronc 0.5.3 (dual-era
  MCP engine). tronc 0.5 hands tools/handlers a shared `&Arc<ServerState>` with no
  outer `RwLock`, so the active provider/model/multiplex config moved to a
  per-field interior `RwLock<ActiveConfig>`; those accessors are now `&self` async
  (the runner cache was already interior `Mutex`). All three crates aligned to a
  single workspace version. The core `embacle` crate is unchanged.

## [0.19.0] — 2026-06-07



## [0.18.0] — 2026-06-06

### Added

- feat(acp): per-request mcp_servers for native Copilot ACP tool calling ChatRequest.mcp_servers flows into session/new; opt-in mcp_tool_calling re-enables SDK_TOOL_CALLING to route tool turns through converse().

### Fixed

- fix(example): Duration::from_mins in web_login for clippy 1.96



## [0.17.0] — 2026-06-05

### Added

- feat(web-ui): browser-driven Claude.ai provider (REST + MCP) via dravr-browser

### Other

- test(e2e): skip Copilot headless E2E when backend auth unavailable



## [0.16.0] — 2026-06-04



## [0.15.15] — 2026-06-02



## [0.15.14] — 2026-05-29

### Fixed

- fix(tool-sim): strip echoed <tool_result> scaffolding from CLI replies



## [0.15.13] — 2026-05-19



## [0.15.12] — 2026-05-19



## [0.15.11] — 2026-05-19



## [0.15.10] — 2026-05-19



## [0.15.9] — 2026-05-19



## [0.15.8] — 2026-05-19



## [0.15.7] — 2026-05-13

### Fixed

- fix(cli): surface stdout when stderr is empty claude-code on exit=1 writes the error to stdout while emitting zero bytes to stderr. Prefer stderr, fall back to stdout, truncate at 500 chars.

### Other

- build(deps): bump softprops/action-gh-release to v3
- build(deps): bump agent-client-protocol-schema to 0.12



## [0.15.6] — 2026-05-08



## [0.15.5] — 2026-05-01

### Other

- obs: payload logging across CLI runners, ACP path, and openai_api Process::run_cli_command emits info (lengths, latency) + trace (argv, full output) covering all 12 runners; copilot_headless::complete and openai_api gain matching pre/post call info+trace; agent::run logs each multi-turn iteration.



## [0.15.4] — 2026-04-23



## [0.15.3] — 2026-04-21



## [0.15.2] — 2026-04-21



## [0.15.1] — 2026-04-20



## [0.15.0] — 2026-04-17

### Added

- feat: ranked Copilot model catalog with self-heal + reasoning effort Replaces hardcoded default; adds ModelUnavailable kind and 1.95 clippy fixes.



## [0.14.11] — 2026-04-10

### Other

- build: reduce tokio feature footprint to minimal set



## [0.14.10] — 2026-04-03

### Fixed

- fix: use backticks for code identifiers in doc comment



## [0.14.9] — 2026-03-31



## [0.14.8] — 2026-03-31



## [0.14.7] — 2026-03-31

### Fixed

- fix: repair broken expect annotations in openai_types test code
- fix: add Safe annotation to test expect() calls in openai_types
- fix: resolve error handling violations found by dravr-build-config validation



## [0.14.6] — 2026-03-30



## [0.14.5] — 2026-03-30



## [0.14.4] — 2026-03-30

### Fixed

- fix: stop re-injecting system prompt into ACP prompt text, forward max_tokens

### Other

- deps: bump opentelemetry and opentelemetry_sdk from 0.28 to 0.31
- deps: bump toml from 0.8.23 to 1.1.0
- deps: bump agent-client-protocol-schema from 0.11.3 to 0.11.4
- deps: bump docker/build-push-action from 6 to 7
- deps: bump docker/login-action from 3 to 4
- deps: bump docker/setup-buildx-action from 3 to 4



## [0.14.3] — 2026-03-28



## [0.14.2] — 2026-03-26

### Other

- deps: bump dravr-tronc to 0.2 with error notification support



## [0.14.1] — 2026-03-23



## [0.13.5] — 2026-03-18



## [0.13.4] — 2026-03-18

### Added

- feat: make ACP session and prompt timeouts configurable via env vars



## [0.13.3] — 2026-03-18



## [0.13.2] — 2026-03-18



## [0.13.1] — 2026-03-18

### Fixed

- fix: inject system prompt into ACP prompt blocks



## [0.13.0] — 2026-03-13

### Added

- feat: add C FFI static library for Swift integration
- feat: materialize images to temp files for all 12 CLI runners



## [0.12.0] — 2026-03-13

### Added

- feat: add vision/image support and wire CopilotHeadless into provider system

### Fixed

- fix: resolve clippy and test count for copilot-headless wiring



## [0.11.0] — 2026-03-12

### Added

- feat: add Kilo Code CLI runner with NDJSON parsing and streaming
- feat: unify embacle-server with embacle-mcp into single binary
- feat: add guardrail middleware and cross-decorator scenario tests GuardrailProvider with 3 built-in guards, ScriptedProvider, 7 scenarios
- feat: add cost tracking, response cache, and OTel metrics export TokenPricing/PricingTable, CacheProvider, otel feature flag with instruments
- feat: add TOML config file loading behind config-file feature flag Declarative provider, fallback, alias setup via embacle.toml or ~/.config/embacle/
- feat: add retry with exponential backoff to FallbackProvider Add ErrorKind::is_transient(), RetryConfig, FallbackProvider::with_retry()
- feat: add Kiro CLI runner as 11th LLM provider

### Fixed

- fix: add kilo to --provider help text in server and mcp binaries
- fix: add permissions block to homebrew workflow
- fix: resolve clippy doc_markdown warnings for provider help strings
- fix: update health endpoint test to expect 11 providers



## [0.10.2] — 2026-03-11

### Added

- feat: add Kiro CLI runner as 11th LLM provider
- feat: add retry with exponential backoff to FallbackProvider
- feat: add TOML config file loading behind config-file feature flag
- feat: add cost tracking, response cache, and OTel metrics export
- feat: add guardrail middleware and cross-decorator scenario tests
- feat: unify embacle-server with embacle-mcp into single binary
- feat: add Kilo Code CLI runner with NDJSON parsing and streaming

### Fixed

- fix: resolve clippy doc_markdown warnings for provider help strings
- fix: add permissions block to homebrew workflow (code scanning alert #10)
- fix: filter artifact download to exclude Docker buildx cache

## [0.10.1] — 2026-03-11

### Fixed

- fix: Docker build uses -p flag for workspace binary targets

## [0.10.0] — 2026-03-11

### Added

- feat: add MCP Streamable HTTP to embacle-server, Homebrew tap with CI
- docs: add OpenAI API runner section to README



## [0.9.0] — 2026-03-11

### Added

- feat: add with_client() constructor for HTTP client injection
- feat: add OpenAI-compatible HTTP API client runner (openai-api feature) SSE streaming, tool calling, model discovery, 30 unit tests
- feat: add Docker image with ghcr.io release workflow

### Fixed

- fix: resolve 3 CodeQL uncontrolled-allocation-size alerts in stop field Use bounded to_bounded_vec() instead of clone+truncate to avoid copying unbounded user input
- fix: revert accidental version bump in Cargo.toml files
- fix: update OpenAI API default model to gpt-5.4
- fix: resolve 9 CodeQL security alerts (stop bounds, CI permissions)



## [0.8.1] — 2026-03-09



## [0.8.0] — 2026-03-09

### Added

- feat: add Warp terminal (oz) CLI runner as 10th provider

### Fixed

- fix: ACP prompt timeout, stdio error propagation, redact log output
- fix: timing-safe auth, dependabot config, remove Box::leak

### Other

- refactor: dedup factory/runner code, wire top_p/stop/response_format Move factory+parsing to core, add top_p/stop to OpenAI types, fix READMEs (0.6->0.7, 9 providers)
- Update Dependabot configuration version



## [0.7.0] — 2026-03-07

### Added

- feat: add InstalledAuthUnverified variant and env var auth checking
- feat: enhance JSON schema validation with recursion, enum, and bounds
- feat: add native tool calling types to core library

### Fixed

- fix: remove [Unreleased] section before v0.7.0 release
- fix: use npm prefix -g to locate copilot binary on CI
- fix: use npm bin -g to find copilot binary path on CI
- fix: symlink copilot-linux-x64 binary to copilot on CI PATH
- fix: use env var for secrets conditional in CI workflow
- fix: wire COPILOT_GITHUB_TOKEN secret into CI for headless e2e tests
- fix: CI now tests all workspace crates, fix workspace-wide clippy warnings
- fix: ACP permission response prefers AllowAlways, never falls back to reject
- fix: update AGENTS.md project overview to reflect full workspace scope
- fix: default to claude-opus-4.6-fast, update Copilot fallback model list
- fix: rewrite OpenCode NDJSON parser, add E2E test suite for all runners



## [0.6.0] — 2026-03-07

### Fixed

- fix: purge stale copilot-sdk references from docs, CI, and release workflow
- fix: complete headless tool calling + usage extraction Add SDK_TOOL_CALLING, ObservedToolCall tracking, converse() API, ACP usage parsing



## [0.5.0] — 2026-03-05

### Fixed

- fix: streaming downgrade for non-streaming providers, reduce lock scope Permissive mode now falls back to complete() + SSE instead of erroring

### Other

- refactor: deduplicate runners, remove as_any, async model discovery CliRunnerBase + macro (-528 lines), #[must_use] on RunnerError



## [0.4.1] — 2026-03-04

### Added

- feat: fix tool calling for coding-assistant LLMs, add index to ToolCall Code-generation framing for catalogs, ToolCall.index per OpenAI spec, live Copilot tests



## [0.3.0] — 2026-03-03

### Added

- feat: add agent loop, fallback chains, metrics, quality gate, MCP bridge, and structured output
- feat: add Goose, Cline, and Continue CLI runners Expand embacle from 6 to 9 CLI runners with JSON parsing, session resume, and streaming

### Fixed

- fix: restore trailing newlines stripped by LinesStream in SSE deltas



## [0.2.1] — 2026-03-02

### Added

- feat: add Gemini CLI and Codex CLI runners Add GeminiCliRunner and CodexCliRunner with streaming JSONL support, expanding embacle to 6 CLI tools

### Fixed

- fix: add GeminiCli and CodexCli to subcrate runner factories and provider lists



## [0.2.0] — 2026-03-02

### Added

- feat: add Gemini CLI and Codex CLI runners Add GeminiCliRunner and CodexCliRunner with streaming JSONL support, expanding embacle to 6 CLI tools



## [0.1.3] — 2026-03-01



## [0.1.2] — 2026-03-01



## [0.1.1] — 2026-03-01



## [0.1.0] — 2026-03-01

### Added

- feat: add embacle-server crate with OpenAI-compatible REST API Axum HTTP server with /v1/chat/completions, /v1/models, /health, SSE streaming, multiplex fan-out, bearer auth
- feat: add embacle-mcp binary crate with MCP server Stdio/HTTP transports, 7 tools, JSON-RPC 2.0, multiplex fan-out, README MCP section
- feat: add Timeout error kind, enhanced logging, and stdout capture on failure
- feat: add tool_simulation module for text-based tool calling Text-based tool loop for CLI runners with catalog generation, XML parsing, and async execution
- feat: address analysis weak spots, expand tests, add CI branch triggers Fix doc drift, propagate max_tokens, add gh-auth check, 44 new tests (18→62)
- feat: make available_models() configurable at runtime Change LlmProvider::available_models() return type from &'static [&'static str] to &[String] so models can be determined at runtime. Each runner stores its model list in a Vec<String>. CopilotRunner and CopilotSdkRunner discover models via `gh copilot models` at construction time, falling back to static defaults if the command fails.
- feat: default to claude-opus-4.6 for Copilot SDK, Copilot CLI, and Claude Code runners
- feat: add SDK_TOOL_CALLING capability and as_any() for downcasting Add flag for SDK-managed tool loops, as_any() on LlmProvider trait, re-export ToolHandler types
- feat: add Copilot SDK provider behind copilot-sdk feature flag

### Fixed

- fix: release workflow — use macos-14, build --workspace, reset versions to 0.0.1
- fix: rename remaining capitalized Embache references to Embacle
- fix: rename crate from embache to embacle
- fix: wire env keys to sandbox, guard streaming child lifecycle, remove dead ExecutionMode
- fix: use RunnerConfig::new in doc examples
- fix: correct rust-toolchain.toml format



## [0.1.0] — 2026-03-01

### Added

- feat: add embacle-server crate with OpenAI-compatible REST API Axum HTTP server with /v1/chat/completions, /v1/models, /health, SSE streaming, multiplex fan-out, bearer auth
- feat: add embacle-mcp binary crate with MCP server Stdio/HTTP transports, 7 tools, JSON-RPC 2.0, multiplex fan-out, README MCP section
- feat: add Timeout error kind, enhanced logging, and stdout capture on failure
- feat: add tool_simulation module for text-based tool calling Text-based tool loop for CLI runners with catalog generation, XML parsing, and async execution
- feat: address analysis weak spots, expand tests, add CI branch triggers Fix doc drift, propagate max_tokens, add gh-auth check, 44 new tests (18→62)
- feat: make available_models() configurable at runtime Change LlmProvider::available_models() return type from &'static [&'static str] to &[String] so models can be determined at runtime. Each runner stores its model list in a Vec<String>. CopilotRunner and CopilotSdkRunner discover models via `gh copilot models` at construction time, falling back to static defaults if the command fails.
- feat: default to claude-opus-4.6 for Copilot SDK, Copilot CLI, and Claude Code runners
- feat: add SDK_TOOL_CALLING capability and as_any() for downcasting Add flag for SDK-managed tool loops, as_any() on LlmProvider trait, re-export ToolHandler types
- feat: add Copilot SDK provider behind copilot-sdk feature flag

### Fixed

- fix: rename remaining capitalized Embache references to Embacle
- fix: rename crate from embache to embacle
- fix: wire env keys to sandbox, guard streaming child lifecycle, remove dead ExecutionMode
- fix: use RunnerConfig::new in doc examples
- fix: correct rust-toolchain.toml format