# Workweaver Runtime Dependencies
# Used for Docker images / production runtime (keeps images small).
# Python 3.14+ compatible

# -----------------------------------------------------------------------------
# Web Framework & ASGI
# -----------------------------------------------------------------------------
fastapi==0.141.1
uvicorn[standard]==0.51.0
mangum==0.21.0
slowapi==0.1.10

# -----------------------------------------------------------------------------
# Data Validation
# -----------------------------------------------------------------------------
pydantic==2.13.5
pydantic-settings==2.14.2
email-validator==2.3.0

# -----------------------------------------------------------------------------
# HTTP Client (aiohttp required by Twilio mock)
# -----------------------------------------------------------------------------
httpx==0.28.1
aiohttp==3.14.1

# -----------------------------------------------------------------------------
# AWS SDK
# -----------------------------------------------------------------------------
boto3==1.43.36
botocore==1.43.36

# -----------------------------------------------------------------------------
# PostgreSQL / pgvector-backed WorkMemory recall + durable metering
# -----------------------------------------------------------------------------
psycopg[binary]==3.3.4
psycopg-pool==3.3.1
# asyncpg powers (a) PostgresMeteringProvider's durable cost-attribution
# writes (#4217) and (b) the self-host migration applicator that creates
# the metering_events table on fresh deploys (#4240). MUST stay in the
# runtime requirements so the workweaver/backend image used by the
# self-host migrations init container can resolve `import asyncpg`.
asyncpg==0.31.0

# Valkey/Redis client (#10192 AC4). The /health/ready + /health/deep probes
# ping Valkey via REDIS_URL to prove the dependency is usable (200 only when
# reachable, 503 when down). Without this package the probe raises
# ModuleNotFoundError and reports "down" on every healthy self-host stack — a
# false 503. The self-host compose exports REDIS_URL so the probe treats
# Valkey as required; the client must be installed for that to be honest.
redis==8.1.0

# -----------------------------------------------------------------------------
# Third-Party Integrations (canonical product-contract dependencies)
# -----------------------------------------------------------------------------
# Telephony (legacy P1.2): Voice, WhatsApp, SMS
twilio==9.10.9

# Document Processing (legacy P1.7D): PDF, DOCX, TXT extraction
pypdf==6.14.2
python-docx==1.2.0
reportlab==5.0.0
python-pptx==1.0.2
openpyxl==3.1.5
# #15516 selective page raster for the document ingest cascade (vision path).
# Self-contained PDFium wheel — no poppler system dependency.
pypdfium2==5.13.0

# Numerical Compute — foundational direct runtime dependency powering the
# embedding cosine paths (skill_selector, chat_router shadow embedding), the
# ONNX rerank dispatcher, openpyxl xlsx cell typing (np.short), and the
# semantic consolidator centroids. Previously this arrived transitively via
# Previously this arrived transitively via a retired voice dependency; it MUST be
# pinned explicitly here. Do NOT remove without confirming every consumer has
# an alternative, or the conftest fallback stub (only bool_/ndarray/isscalar)
# activates and every np.array/asarray/short caller fails.
numpy==2.5.1

# Audio processing (Python 3.14 has no stdlib audioop; provided by audioop-lts)
audioop-lts==0.2.2

# xAI Grok (legacy P1.3): Voice Agent, LLM orchestration
websockets==16.1.1

# Payments (legacy P1.10): Checkout, billing
stripe==15.1.0

# -----------------------------------------------------------------------------
# Cryptography & Security
# -----------------------------------------------------------------------------
cryptography==48.0.1
PyJWT==2.13.0
bcrypt==5.0.0
# Issue #3515 — portable_e2e per-tenant credential encryption (Argon2id KDF).
argon2-cffi==25.1.0
eth-hash[pycryptodome]==0.8.0
pycryptodome==3.23.0
# Issue #4216 — AWS Nitro Enclaves attestation document
# parsing (parent-side strict CBOR/COSE_Sign1 verifier).
# Pinned to 6.1.1 to address CVE-2025-68131 + CVE-2026-26209.
cbor2==6.1.3
# Issue #4216 — BLS12_381 (G2 ProofOfPossession) signing inside the
# Nitro Enclave child. Imported lazily from the keystore; bundled in
# the parent backend container so test fixtures can verify signatures.
py_ecc==8.0.0
# Issue #4216 — BIP340 Schnorr signing via libsecp256k1. Installed from the
# committed cp314 wheels under vendor/wheels via --find-links (below).
# coincurve 21.0.0 ships no upstream cp314 wheel and its sdist build fails on
# 3.14 (cffi 2.0 dropped the LICENSE file coincurve's hatch_build.py expects),
# so we vendor cp314 wheels built from coincurve master @ 7829b29c (the commit
# that fixes the cffi-2.0/3.14 build): manylinux_2_28 aarch64 + manylinux x86_64
# for glibc Linux (Graviton ECS/Lambda/enclave + amd64 self-host), musllinux_1_2
# x86_64 for Alpine (#13259), and macosx arm64 for mac-local dev (mirroring
# biscuit-python's layout). The marker covers Linux x86_64/aarch64 (glibc or
# musl — pip matches the wheel tag) and macOS arm64. Windows stays excluded
# (no wheel; Schnorr unused there). Repo is 3.14-only.
# Agent capability tokens (Biscuit) are likewise installed from committed cp314
# wheels under vendor/wheels so Docker/Lambda/CI builds resolve offline
# (the repo is private; release-asset URLs 404 to unauthenticated pip). Built
# from biscuit-python upstream @ c0fa698 (pyo3 0.28, Python 3.14 support).
# pip auto-selects the manylinux_2_28_aarch64 (Graviton), the manylinux x86_64
# (amd64 self-host/CI), the musllinux x86_64 (Alpine) or the macosx arm64 wheel
# (dev/macOS CI) by platform tag. Cross-platform self-host is a founder hard
# requirement (#13259); arches without a wheel (e.g. riscv64) fail closed at
# the adapter gate with a loud typed error.
--find-links vendor/wheels
coincurve==21.0.0 ; (platform_system == 'Linux' and platform_machine == 'aarch64') or (platform_system == 'Linux' and platform_machine == 'x86_64') or (platform_system == 'Darwin' and platform_machine == 'arm64')
biscuit-python==0.4.0 ; platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
# Issue #12134 — SAML 2.0 assertion verification. signxml verifies enveloped
# XML signatures on top of the already-pinned cryptography wheel (no external
# xmlsec1 binary, no pyopenssl version cap); defusedxml prevents XXE/entity
# expansion. pysaml2 was rejected: its pyopenssl<24.3.0 cap is unsatisfiable
# against cryptography==48.0.1 (worker build 7558590c resolver proof).
# ADR: docs/adr/2026-08-21-saml-verifier-toolkit-selection.md
signxml==5.1.0
defusedxml>=0.7.1

# -----------------------------------------------------------------------------
# Utilities
# -----------------------------------------------------------------------------
python-dotenv==1.2.2
python-dateutil==2.9.0.post0
orjson==3.11.9
# PR #13458 / #13429 — inference-trace lake bundles compress with zstandard.
# Declared in root pyproject as zstandard>=0.23.0; pinned here (==, matching
# this lockfile's convention) so the CI check-delta lane — which resolves its
# environment from apps/backend/requirements.txt, not pyproject — resolves
# the apps/backend/services/trace_bundle_store.py import.
zstandard==0.25.0
prompt-toolkit==3.0.53
python-multipart==0.0.32
PyYAML==6.0.3
jsonschema==4.26.0
ulid-py==1.1.0
structlog==26.1.0
# Issue #8989 — standardized tenacity retry on persistence/channel/idempotent
# paths (17 routers/services import it). Declared in root pyproject as
# tenacity>=9.0; pinned here (==, matching this lockfile's convention) so
# Docker/Lambda/CI venvs that install requirements.runtime.txt resolve the
# import at runtime.
tenacity==9.1.4
croniter==6.2.4
phonenumbers==9.0.35
sqlite-vec==0.1.9
beautifulsoup4>=4.12.0
dnspython==2.8.0
# Canonical Agent Client Protocol SDK (issue #4338). Powers `ww acp start`
# and is imported by tests/integration/test_acp_daemon_canonical.py.
agent-client-protocol>=0.11.1
# Official A2A SDK pinned to the released v1 model surface (#1370).
a2a-sdk==1.1.2
# Issue #16578 — the WASI skill isolation backend (`WasiSkillIsolationBackend`)
# is the only serverless-legal isolation path, but its health probe requires
# `import wasmtime`. The package lived only in the optional `[wasm]` extra, so
# prod images built from this file never carried it and every WASI activation
# denied with `isolation_backend_unavailable`. Pinned here so the deployed
# runtime honestly reports wasmtime availability.
wasmtime==49.0.0
# Issue #16626 — real SourceTreeProvider on the code-projection reconcile rail.
# tree-sitter grammars power symbol/call-edge extraction (python + typescript);
# the same family is already a production dependency of WorkMemory chunking.
tree-sitter==0.26.0
tree-sitter-python==0.25.0
tree-sitter-typescript==0.23.2
