Skip to main content

Rust runtime for Python AI apps. Drop-in for openai/anthropic SDKs with native SSE streaming, an agent loop with concurrent tool dispatch, and Logfire-compatible OTel emission.

Project description

f3dx

The Rust runtime your Python imports. Drop-in for openai and anthropic SDKs with native SSE streaming, an agent loop with concurrent tool dispatch, and Logfire-compatible OTel emission. PyO3 + abi3 wheels for ubuntu/macos/windows. Built for pydantic-ai.

The intellectual frame is Cruz's "AI Runtime Infrastructure" (arXiv:2603.00495, Feb 2026): a distinct execution-time layer above the model and below the application that observes, reasons over, and intervenes in agent behavior at runtime. f3dx is that layer, in Rust, for Python apps.

pip install f3dx
import f3dx

# 5x faster streaming, drop-in for openai SDK
client = f3dx.OpenAI(api_key="...", base_url="https://api.openai.com/v1")
for chunk in client.chat_completions_create_stream({"model": "gpt-4", "messages": [...]}):
    print(chunk["choices"][0]["delta"].get("content", ""), end="")

# Drop-in for anthropic SDK with native Messages event handling
client = f3dx.Anthropic(api_key="...")
for event in client.messages_create_stream({"model": "claude-3-5-sonnet", "max_tokens": 1024, "messages": [...]}):
    if event.get("type") == "content_block_delta":
        print(event["delta"].get("text", ""), end="")

# 5-10x faster agent runtime via concurrent tool dispatch
agent = f3dx.AgentRuntime(system_prompt="...", concurrent_tool_dispatch=True)
result = agent.run(user_prompt, tools={...}, mock_responses=[...])

# Tool-call streaming reassembly: skip the accumulate-fragments boilerplate
for ev in client.chat_completions_create_stream_assembled({...}):
    if ev["type"] == "tool_call":
        result = dispatch(ev["name"], ev["arguments"])  # arguments is parsed dict, ready

# Validated structured output: skip accumulate-then-json.loads at end
for ev in client.chat_completions_create_stream_assembled(req, validate_json=True):
    if ev["type"] == "validated_output":
        process(ev["data"])  # already parsed
    elif ev["type"] == "validation_error":
        log.warning("model emitted invalid JSON: %s", ev["error"])

# Logfire-compatible OTel spans by default — gen_ai.* semconv
f3dx.configure_otel(
    endpoint="https://logfire-api.pydantic.dev/v1/traces",
    headers={"Authorization": f"Bearer {LOGFIRE_TOKEN}"},
)
# Every Agent.run + every chat_completions / messages call now emits
# spans with gen_ai.system, gen_ai.request.model, gen_ai.usage.{input,output}_tokens, etc.

Why

Compound AI systems (Zaharia BAIR 2024, Mei AIOS arXiv:2403.16971) are the dominant production pattern. The orchestration + HTTP layer is now the bottleneck, not the model. Every other AI infra layer is non-Python by 2026 (vLLM C++, TGI Rust, mistral.rs Rust, Outlines-core Rust, XGrammar C++). Orchestration is the last lane; f3dx ships it.

Bench results (reproducible from bench/)

What vs Speedup
f3dx.AgentRuntime concurrent dispatch pure-python sequential agent loop 5-10x at 5-10 tools/turn
f3dx.OpenAI streaming openai Python SDK 5.10x at 1000 chunks
f3dx.Anthropic streaming anthropic Python SDK 2.9-5.2x at 50-1000 events
Tool-call assembled stream raw fragment iteration 17 chunks -> 2 events
validate_json=True accumulate + json.loads + try/except one extra event, zero user code

All benches live under bench/, all use the stdlib mock servers in the same dir, all single-thread.

Architecture

Cargo workspace, five crates, one PyPI package:

f3dx/
  crates/
    f3dx-py/      PyO3 bridge cdylib (the only crate with #[pymodule])
    f3dx-rt/      agent runtime + concurrent tool dispatch
    f3dx-http/    LLM HTTP client (reqwest + native SSE + streaming JSON validation)
    f3dx-trace/   OpenTelemetry span emission (Logfire-compatible, gen_ai.* semconv)
    f3dx-mcp/     Model Context Protocol client (rmcp + stdio transport)

OpenAI-compatible endpoints (vLLM, Mistral, xAI, Groq, Together, Fireworks) all work via f3dx.OpenAI by setting base_url.

Observability

Configure once with f3dx.configure_otel(endpoint, headers, service_name, stdout). Every AgentRuntime.run emits a root span with gen_ai.system="f3dx" + gen_ai.prompt.length_chars + f3dx.{concurrent_tool_dispatch,iterations,tool_calls_executed,duration_ms,output.length_chars}.

Every chat_completions_create* / messages_create* emits a SpanKind::Client span:

gen_ai.system               openai | anthropic
gen_ai.operation.name       chat | messages
gen_ai.request.model        from request
gen_ai.request.{temperature, top_p, max_tokens, stream}
gen_ai.response.{id, model, finish_reasons}
gen_ai.usage.{input_tokens, output_tokens}

Streaming spans hold open until terminal chunk; usage attrs land when the closing chunk carries them (auto-injects stream_options.include_usage=true for OpenAI; reads message_start.message.usage + message_delta.usage for Anthropic).

Status: Ok on success, Status::error("<msg>") on HTTP failure.

JSONL trace sink for downstream replay-eval tools:

f3dx.configure_traces("traces.jsonl", capture_messages=True)
# every AgentRuntime.run appends one row with prompt + system_prompt +
# output + input_tokens + output_tokens (capture_messages off by default;
# opt-in because PII-sensitive). Polars/DuckDB scan via pl.scan_ndjson /
# duckdb.read_json. Replay via tracewright.

# Or convert to columnar parquet for fast analytics:
# pip install f3dx[arrow]
from f3dx.analytics import jsonl_to_parquet
jsonl_to_parquet("traces.jsonl", "traces.parquet")
# pl.scan_parquet("traces.parquet").filter(pl.col("output_tokens") > 100).collect()

Layout

f3dx/
  bench/                            reproducible benches + verify scripts + stdlib mock servers
  crates/                           cargo workspace member crates
  python/f3dx/__init__.py           core Python wrapper (AgentRuntime, OpenAI, Anthropic, configure_otel)
  python/f3dx/compat/               opt-in subclass shims (f3dx[openai-compat])
  python/f3dx/pydantic_ai/          pydantic-ai integration (f3dx[pydantic-ai])
  python/f3dx/langchain/            langchain-openai integration (f3dx[langchain])
  pyproject.toml                    maturin build, optional extras
  Cargo.toml                        cargo workspace root + workspace lints
  rust-toolchain.toml               pinned to 1.90.0 for reproducible builds
  .github/workflows/ci.yml          ubuntu/macos/windows + clippy gate + built-wheel install
  .github/workflows/release.yml     glibc/musl x86_64+aarch64 wheels + macos x86_64+aarch64 + windows + sdist + OIDC PyPI publish

What this is not

f3dx is a Python-from-Rust runtime — a Rust core that ships as a Python wheel via PyO3. If you're building a pure Rust application and want an agent framework in your binary, look at AutoAgents (Rust agent framework with role-based multi-agent), rig (provider abstraction + RAG primitives in Rust), or mistral.rs (local inference engine). Different audience, different scope.

f3dx is not an inference engine. Use vLLM, TGI, mistral.rs, llama.cpp, or any OpenAI-compatible endpoint underneath; f3dx talks to them.

f3dx is not a multi-agent orchestration framework. It is the runtime layer below frameworks like pydantic-ai, LangChain, LlamaIndex, CrewAI, AutoGen.

Sibling project

tracewright — replay-driven eval over f3dx and pydantic-ai JSONL traces. Take a recorded trace, swap the candidate model, get a per-case diff. Closes the loop from "we have observability" to "we have regression tests".

MCP client

import f3dx, json

# spawn an MCP server over stdio (npm-based, Python-based, any binary)
client = f3dx.MCPClient.stdio("npx", ["-y", "@modelcontextprotocol/server-everything"])

for tool in client.list_tools():
    print(tool["name"], tool["description"])

result = client.call_tool("get-sum", json.dumps({"a": 7, "b": 35}))
# 'The sum of 7 and 35 is 42.'

f3dx-mcp is a sibling cargo crate; the rmcp Rust SDK drives the JSON-RPC handshake + stdio transport. SSE + streamable-HTTP transports + sampling callback bridge land in V0.1.

Adapter packages

# pip install f3dx[openai-compat]
from f3dx.compat import OpenAI, AsyncOpenAI    # subclass openai.OpenAI / openai.AsyncOpenAI
import openai
client = OpenAI(api_key=...)
isinstance(client, openai.OpenAI)               # True — passes isinstance checks in
                                                # instructor, litellm, smolagents, langchain
out = client.chat.completions.create(...)       # routes through Rust, returns
                                                # openai.types.chat.ChatCompletion

# pip install f3dx[anthropic-compat]
from f3dx.compat import AsyncAnthropic         # subclass anthropic.AsyncAnthropic
client = AsyncAnthropic(api_key=...)           # also intercepts client.beta.messages.create
                                               # for pydantic-ai's BetaMessage validation path

# pip install f3dx[pydantic-ai]
from f3dx.pydantic_ai import openai_model, anthropic_model, F3dxCapability
from pydantic_ai import Agent
cap = F3dxCapability()
agent = Agent(openai_model('gpt-4', api_key=...), capabilities=[cap])
result = await agent.run('hi')                  # f3dx-routed HTTP, capability counts requests
# anthropic_model('claude-haiku-4', api_key=...) likewise

# pip install f3dx[langchain]
from f3dx.langchain import ChatOpenAI
llm = ChatOpenAI(model='gpt-4', api_key=...)    # subclass of langchain_openai.ChatOpenAI
msg = llm.invoke('hi')                          # sync + ainvoke both routed via f3dx

What's not here yet

  • Gemini adapter (Phase C.2)
  • MCP V0.1: SSE + streamable-HTTP transports + sampling callback bridge (V0 ships stdio only; covers Claude Desktop + every npm-based server + python-based servers via python -m)
  • Parent-child trace context propagation between AgentRuntime span and HTTP child spans (needs Python-side context bridge)
  • Phase E V0.2.1: incremental per-token schema validation in the streaming pump (V0.2 ships terminal-time output_schema= via jsonschema-rs; per-token needs a streaming JSON parser + schema state machine on top, planned next)
  • Phase G V0.2: live parquet sink (V0.1 ships JSONL append-only + the f3dx.analytics.jsonl_to_parquet converter under f3dx[arrow]; rolling-parquet with row-group flush is the next step)
  • langchain-f3dx standalone PyPI package per LangChain partner-package convention (today integrated via the f3dx[langchain] extra; standalone-package split happens before LangChain partner-registry submission)

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

f3dx-0.0.10.tar.gz (53.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

f3dx-0.0.10-cp310-abi3-win_amd64.whl (4.9 MB view details)

Uploaded CPython 3.10+Windows x86-64

f3dx-0.0.10-cp310-abi3-musllinux_1_2_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

f3dx-0.0.10-cp310-abi3-musllinux_1_2_aarch64.whl (4.7 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

f3dx-0.0.10-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

f3dx-0.0.10-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

f3dx-0.0.10-cp310-abi3-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

f3dx-0.0.10-cp310-abi3-macosx_10_12_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file f3dx-0.0.10.tar.gz.

File metadata

  • Download URL: f3dx-0.0.10.tar.gz
  • Upload date:
  • Size: 53.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for f3dx-0.0.10.tar.gz
Algorithm Hash digest
SHA256 182350c7c53ab4d9d5bd6078af96ae360cfe080a3bb44ceda43825f3f47ca969
MD5 f222a5b9387e1325a90a9f7f78d8cf7b
BLAKE2b-256 32300150cf3a6e8fd25b1d46f0ad6237da6a8110cd391aee4583c1d3f1b64d30

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10.tar.gz:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: f3dx-0.0.10-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 4.9 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 fe68698737ef8aa4e6206b5e138f0aa03cb6e0cc75d1b3c74f0fccca141cc797
MD5 f5ce2c80327e75336c793f0b037a7b6f
BLAKE2b-256 e8b2937ec2faf31cddd2bec898708a2c6e7c5338d95db4d901f854e9c8c3d5a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-win_amd64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b0e12f61e7541c9a9a1326c08f8ae665f3cfc183da87517dcef336f4a9316b55
MD5 581bb6060164e7c224aaaf7eeec146ec
BLAKE2b-256 ac5a6b2ebb1f360801f1a922c7247520407c8c54a6f908f5af08d1cfdcb07aee

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 17c63dd60ded05342d62395c8195317dcd1a87f2b2cf5a98cb7f02157a33644c
MD5 7c04345ae2cd99d03df4a757a4c1c209
BLAKE2b-256 a1cf47d441e2358c843bb7253ec08e55618dd820434fcdaf497992b507dd317f

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 340efd6268ad03bc98ee89f1b0405dbf77db9fc54aba537e5830b81a24edcca2
MD5 664539e51b57e7a7c9d6ebddd6845ce8
BLAKE2b-256 bd683246b0a8bdeec0a487452775a49742f9e096b3218efcc43e221e609638ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0a50278dcd2ecaaec217b5518c8712dcfbae528d88f9c3805dc9cf95151e9980
MD5 27b84b84aa3abf7c55883af637dd0e1f
BLAKE2b-256 37e56c268d462d601384bc54ad59a9c4319f9a594919408f1a1adad33b1a8cd8

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1aec371ab68f48c8fdc984e05fb45f1577058b460e18e3a75b0e77370cc69ff3
MD5 e03efd971a15a6fdeea6cabad323a92a
BLAKE2b-256 6df6213370a2819aa3e9ee008758dfdc8c96a8fde65e132ae266177c05ab2914

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file f3dx-0.0.10-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for f3dx-0.0.10-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ad00afda15b708d53f4d6d1ad81cea6e8fb9841073720fb572d095bcc0b68797
MD5 0cbacc9ff0ff668f219baf73884a871c
BLAKE2b-256 67df4049fc26d0cb17f4032c893478ec8af3a682a4ac506a99cb0f459014ea97

See more details on using hashes here.

Provenance

The following attestation bundles were made for f3dx-0.0.10-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on smigolsmigol/f3dx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page