v0.1.0
Praxis AI v0.1.0
The first release of Praxis AI — AI features and capabilities for Praxis.
Praxis AI extends the Praxis proxy framework with AI-specific filters for inference routing, provider APIs, agentic protocols, token counting, guardrails, response storage, and prompt enrichment.
Highlights
OpenAI Responses API (partial)
Proxy foundation for the OpenAI Responses API: request classification, validation, model rewrite, response storage (SQLite/PostgreSQL), conversation rehydration, streaming SSE accumulation, and conversation management endpoints and vLLM backend compatibility (including input_file document conversion). The full agentic loop (tool call detection → tool execution → re-inference) is not yet implemented.
Anthropic Messages API
Request classification, protocol normalization, streaming SSE translation between OpenAI and Anthropic formats, request body translation, and validation.
Agentic Protocols
- MCP (Model Context Protocol): broker with tool discovery, tool resolution, and tool dispatch via the filter pipeline
- A2A (Agent-to-Agent): task routing with context-based ownership and SSE support
AI Inference Routing
Model-based routing via header promotion, per-cluster credential injection, and prompt enrichment at the proxy layer.
Web Search
Model-driven web search dispatch with pluggable providers (OpenAI built-in, You.com).
Security & Observability
- AI guardrails filter for external content safety evaluation (NeMo)
- Token usage header injection across multiple providers (OpenAI, Anthropic, Bedrock)
- MCP metadata endpoint blocking and credential redaction
API Routing
Dedicated backend routing for /v1/files, /v1/prompts, and /v1/vector_stores endpoints.
Not Yet Supported
- Agentic loop orchestration (tool call → execute → re-inference loop)
- Responses API file inputs resolution
- Provider abstraction / unified types
- Multi-tenancy
- Mixture-of-models / intelligent routing
- Multi-provider guardrails
- llm-d integration
See the Responses API & Agentic Loop epic for the full roadmap.
What's Changed
Dependencies
- chore(deps): bump actions/cache from 6.0.0 to 6.1.0 by @dependabot[bot] in #222
- chore(deps): bump docker/build-push-action from 7.2.0 to 7.3.0 by @dependabot[bot] in #223
- chore(deps): bump actions/github-script from 7.0.1 to 9.0.0 by @dependabot[bot] in #306
- chore(deps): bump jsonwebtoken from 9.3.1 to 10.4.0 in the rust-dependencies group by @dependabot[bot] in #307
- chore(deps): bump github/codeql-action/analyze from 4.36.2 to 4.36.3 by @dependabot[bot] in #303
- chore(deps): bump docker/metadata-action from 6.1.0 to 6.2.0 by @dependabot[bot] in #304
- chore(deps): bump github/codeql-action/init from 4.36.2 to 4.36.3 by @dependabot[bot] in #305
- chore(deps): bump docker/login-action from 4.2.0 to 4.4.0 by @dependabot[bot] in #302
- chore(deps): bump github/codeql-action/analyze from 4.36.3 to 4.37.0 by @dependabot[bot] in #341
- chore(deps): bump github/codeql-action/init from 4.36.3 to 4.37.0 by @dependabot[bot] in #342
- chore(deps): bump the rust-dependencies group across 1 directory with 5 updates by @dependabot[bot] in #343
- chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 by @dependabot[bot] in #465
- chore(deps): bump alpine from 3.23 to 3.24 by @dependabot[bot] in #467
- chore(deps): bump rust from 1.96-alpine to 1.97-alpine by @dependabot[bot] in #468
- chore(deps): bump github/codeql-action/init from 4.37.0 to 4.37.3 by @dependabot[bot] in #469
- chore(deps): bump astral-sh/setup-uv from 8.3.2 to 9.0.0 by @dependabot[bot] in #470
- chore(deps): bump github/codeql-action/analyze from 4.37.0 to 4.37.3 by @dependabot[bot] in #466
- chore(deps): bump the rust-dependencies group with 11 updates by @dependabot[bot] in #471
- chore(deps): bump Praxis crates to 0.4.1 by @nerdalert in #486
Other
- fix(build): print actual coverage percentage before failing gate by @leseb in #228
- docs(mcp): restore static catalog example by @nerdalert in #227
- fix(ai): map Anthropic max_tokens to OpenAI max_completion_tokens by @dimakis in #225
- fix(xtask): restore filter doc generation for AI repo by @leseb in #238
- chore: remove stale ai-inference feature flag by @leseb in #245
- SSE optimizations by @alexsnaps in #250
- fix: correct README links to point to ai repo by @leseb in #251
- test(store): add unit tests for SQLite backend and storage traits by @leseb in #237
- test: add unit tests for Response Store filter and config by @leseb in #236
- fix(apis): match OpenAI JSON field ordering in conversation responses by @leseb in #241
- refactor(headers): Do no clone when not needed, rely on laziness by @alexsnaps in #253
- ci(integration): add integration test workflow and enable test crates by @leseb in #244
- test(conversations): add unit tests for handlers, config, and filter by @leseb in #235
- test: add unit tests for chat_completions translation module by @leseb in #234
- lint(xtask): add separator width lint rule by @leseb in #256
- ci(coverage): bump line coverage threshold to 93% by @leseb in #255
- test(store): add scoping, pool, migration, and concurrency tests by @leseb in #254
- feat(filter): add streaming persistence support to response store by @leseb in #242
- feat(mcp): add configurable 2026-07-28 stateless profile by @nerdalert in #247
- feat(a2a): promote context IDs for classifier routing by @nerdalert in #226
- test(xtask): fix example lint assertion message by @nerdalert in #265
- ci: add unicode safety check for PR context poisoning by @aslakknutsen in #257
- refactor: remove ai-inference feature gate by @leseb in #259
- docs: fix stale local documentation links by @nerdalert in #264
- fix(apis): percent-decode SQLite path before traversal check in response-store by @leseb in #271
- fix: point issue template discussions link to ai repo by @leseb in #269
- fix(responses): case-insensitive SSE content-type detection by @leseb in #272
- ci: add aggregate CI status check for merge queue by @leseb in #258
- docs(a2a): add agent-card routing example by @nerdalert in #263
- refactor(apis): extract shared is_event_stream_content_type helper by @leseb in #274
- fix anthropic parallel tool call streaming by @franciscojavierarceo in #273
- chore(deps): update crossbeam-epoch 0.9.18 -> 0.9.20 (RUSTSEC-2026-0204) by @leseb in #290
- feat(filter): add openai_stream_events SSE accumulator filter by @leseb in #270
- docs(config): add openai_stream_events to full-flow example by @leseb in #293
- docs(filters): add missing openai_stream_events doc and CI lint by @leseb in #299
- fix(xtask): resolve praxis shared types from cargo registry in CI by @leseb in #308
- Add agent Rust data ownership guidance by @franciscojavierarceo in #295
- feat(conversations): rehydrate and append via conversation.id by @leseb in #248
- test(mcp): add unit tests for broker config validation by @leseb in #291
- test: replay sanitized agent sessions by @franciscojavierarceo in #289
- ci(fmt): include test crates in rustfmt checks by @nerdalert in #310
- test(a2a): add unit tests for envelope parsing by @leseb in #311
- feat(filter): add tool_parse filter for Responses API tool classification by @leseb in #309
- feat(apis): add Deserialize to TokenUsageProvider and streaming token… by @szedan-rh in #261
- test: add unit tests for remaining config modules by @leseb in #315
- docs: use language-neutral type names in generated filter docs by @leseb in #317
- add token_count filter for streaming and non streaming reponses by @szedan-rh in #262
- test(a2a): add unit tests for config validation by @leseb in #318
- ci: bump coverage threshold from 93% to 94% by @leseb in #322
- test(token_usage): add unit tests for provider parsers by @leseb in #321
- Preserve source records in session replay fixtures by @franciscojavierarceo in #314
- test(guardrails): add unit tests for config validation by @leseb in #323
- feat(a2a): route task traffic by context ownership by @nerdalert in #324
- test: add unit tests to boost coverage to 95% by @leseb in #325
- ci: bump coverage threshold from 94% to 95% by @leseb in #329
- Preserve split Claude tool replay turns by @franciscojavierarceo in #332
- feat(token_count): add Bedrock InvokeModel header-based extraction by @mkoushni in #240
- docs(proposals): streaming token accumulation (#119) by @henschwartz in #239
- feat(filter): add mcp_tool_resolve filter for MCP tool discovery by @leseb in #331
- fix(container): restore container image builds by @nerdalert in #333
- feat/220 token counting integration tests by @mkoushni in #243
- docs(proposals): add How? section for streaming token accumulation (#119) by @henschwartz in #338
- refactor(token_usage): move functions to
TokenUsageProviderdirectly by @alexsnaps in #330 - fix(tool_parse): remove unnecessary MCP tool JSON cloning by @leseb in #345
- Add Claude thinking replay fixture by @franciscojavierarceo in #337
- refactor: prefix OpenAI Responses filters with
openai_by @leseb in #346 - fix(token_count): flush SSE at EOF and fix streaming finalization (#119) by @henschwartz in #348
- Remove redundant replay proxy drops by @franciscojavierarceo in #350
- fix(anthropic): stop double-counting cached tokens in usage transform… by @mkoushni in #387
- fix(a2a): capture task route for non-SSE responses to streaming methods by @mkoushni in #388
- fix(conversations): avoid per-call String allocation in normalize_message_item by @Nitjsefnie in #391
- feat(filter): add openai_web_search filter for model-driven search dispatch by @leseb in #349
- docs(store): clarify no-cascade delete for conversation items by @leseb in #390
- fix: delete dead responses/classifier duplicate by @leseb in #389
- ci: add optional praxis main testing and known-issue label by @leseb in #326
- feat: add You.com web search provider by @franciscojavierarceo in #400
- feat(rehydrate): add max_history_bytes and max_history_items caps by @crstrn13 in #336
- fix(stream_events): remove duplicate is_event_stream_content_type by @Nitjsefnie in #393
- ci: add live vLLM CPU integration tests for Responses API by @leseb in #398
- Preserve Anthropic replay edge cases by @franciscojavierarceo in #399
- docs: add git workflow conventions to AGENTS.md by @leseb in #433
- docs: document bot-generated issue review process by @leseb in #424
- docs: add community interaction guidelines by @leseb in #437
- docs(conventions): document praxis-bot PR review process by @leseb in #434
- refactor(openai): keep Responses output in response object by @leseb in #431
- fix(openai): arm SSE accumulation only for POST /v1/responses by @leseb in #428
- fix(openai): accumulate Responses usage across rounds by @leseb in #430
- docs: add vLLM Agentic API passthrough example by @franciscojavierarceo in #402
- feat(apis): resolve Responses file IDs via Files API by @leseb in #401
- fix(openai): update Content-Length after stripping conversation field by @leseb in #443
- docs(conventions): add issue assignment rule by @leseb in #442
- Fix multiline SSE data event parsing by @franciscojavierarceo in #445
- feat(store): add conversation message compare-and-swap by @leseb in #432
- fix(openai): preserve first-pass Responses requests by @leseb in #429
- fix(mcp): block Alibaba metadata endpoint by @onatozmenn in #436
- fix(mcp): redact credentials from error URLs by @onatozmenn in #438
- docs: move conventions.md to CONTRIBUTING.md at repo root by @leseb in #451
- Keep Anthropic tool-error replay compatible by @franciscojavierarceo in #449
- feat(mcp): add openai_mcp_dispatch filter for MCP tool execution by @leseb in #404
- feat(apis): convert Responses input_file to input_text for vLLM by @leseb in #453
- fix(openai): replay only canonical OpenResponses input items by @leseb in #444
- ci: add merge_group triggers to integration, vLLM, and unicode-safety by @leseb in #457
- refactor(openai): extract shared API client for callout filters by @leseb in #456
- ci(coverage): update step name to reflect 95% threshold by @leseb in #472
- perf(a2a): bound task route capture parsing to O(n) with a balance scan by @mkoushni in #450
- feat(routing): add /v1/vector_stores routing to dedicated backend by @leseb in #482
- feat(openai): route /v1/files to the Files API backend by @leseb in #481
- feat(openai): route /v1/prompts to a dedicated Prompts API backend by @leseb in #483
- feat(openai): add bounded JSON POST callouts by @leseb in #473
- fix(ci): add buildx setup and integration tests to release workflow by @leseb in #487
New Contributors
- @leseb made their first contribution in #228
- @nerdalert made their first contribution in #227
- @dependabot[bot] made their first contribution in #222
- @dimakis made their first contribution in #225
- @alexsnaps made their first contribution in #250
- @aslakknutsen made their first contribution in #257
- @franciscojavierarceo made their first contribution in #273
- @szedan-rh made their first contribution in #261
- @mkoushni made their first contribution in #240
- @henschwartz made their first contribution in #239
- @Nitjsefnie made their first contribution in #391
- @crstrn13 made their first contribution in #336
- @onatozmenn made their first contribution in #436
- @shaneutt made their first contribution in #486
Full Changelog: https://github.com/praxis-proxy/ai/commits/v0.1.0