[project] name = "parlant" version = "4.0.4" description = "Parlant is a vibe-coding platform for chat agents that talk to customers." readme = "README.md" license = "Apache-2.0" authors = [ {name = "Yam Marcovitz", email = "yam@emcie.co"}, {name = "Dor Zohar", email = "dor@emcie.co"}, ] requires-python = ">=3.10,<3.15" dependencies = [ "aiofiles>=24.1.0", "aiosqlite>=0.21.0", "aiopenapi3>=0.8.1,<0.9.0", # 0.9.0 hard-pins pydantic==2.11.9, which conflicts with downstream pydantic>=2.12 consumers "aiorwlock>=1.5.0", "authlib>=1.6.11", "boto3>=1.35.70", "cachetools>=6.0.0", "click>=8.1.7", "colorama>=0.4.6", "coloredlogs>=15.0.1", "contextvars>=2.4", "croniter>=5.0.1", "fastapi>=0.120.0", "fastmcp>=3.2.0", "httpx>=0.28.1", "httpx-sse>=0.4.3", # Imported directly by the OpenAI/OpenRouter adapters: openai 3.0 moved its # client onto HTTPX2, so a timeout handed to it must be an httpx2 object. "httpx2>=2.13.1", "keyring>=25.0.0", "jinja2>=3.1.6", "jsonfinder>=0.4.2", "jsonschema>=4.23.0", "lagom>=2.6.0", "limits>=5.5.0", "maxminddb>=2.6.0", # local GeoIP lookups (no network) for session client locations "mcp>=1.23.0", "more-itertools>=10.3.0", "nano-vectordb>=0.0.4.3", "nanoid>=2.0.0", "networkx[default]>=3.3", "numpy>=1.26.0", # The OpenAI SDK powers both the built-in OpenAI and OpenRouter adapters. # Keep it in the base install so OpenRouter never requires an extra. "openai>=3.26.0", "openapi3-parser==1.1.21", "platformdirs>=4.0.0", "opentelemetry-api>=1.37.0", "opentelemetry-exporter-otlp>=1.37.0", "opentelemetry-instrumentation>=0.58b0", "opentelemetry-sdk>=1.37.0", "python-dateutil>=2.8.2", "python-dotenv>=1.0.1", "python-multipart>=0.0.30", "requests>=2.33.0", "rich>=14.0.0", "semver>=3.0.2", "starlette>=0.49.0", # Specified for fix vulnerability of lower versions. Can be removed in case of future conflicts. "structlog>=24.4.0", "tabulate>=0.9.0", "tiktoken>=0.12", "tokenizers>=0.21", "toml>=0.10.2", "types-aiofiles>=24.1.0.20240626", "types-cachetools>=6.0.0.20250525", "types-croniter>=4.0.0.20241030", "types-jsonschema>=4.22.0.20240610", "uvicorn>=0.38.0", "watchfiles>=1.0.0", "websockets>=16.0", "websocket-client>=1.5.3", "wsproto>=1.2.0", "xxhash>=3.5.0", "grpcio-status>=1.83.1", ] [project.urls] Homepage = "https://parlant.io" Documentation = "https://parlant.io/docs" [project.scripts] parlant = "parlant.bin.cli:main" [project.optional-dependencies] # onnxruntime arrives through chromadb, and 1.24 dropped Python 3.10. The # [tool.uv] override below covers uv; this one is what pip reads, so a pip # install on 3.10 resolves a version that still supports it. chroma = ["chromadb>=1.1.1", "onnxruntime<1.24; python_full_version < '3.11'"] qdrant = ["qdrant-client>=1.7.0"] mongo = ["pymongo>=4.11.1"] anthropic = ["anthropic>=1.0.0"] gemini = ["google-genai>=2.32.0", "google-api-core>=2.24.2"] # LiteLLM is a unified gateway over 100+ providers with built-in cost tracking; # the adapter uses its Python SDK (litellm.acompletion/aembedding) and reads the # provider-reported cost it returns. litellm = ["litellm>=1.60.0"] [dependency-groups] dev = [ "moto[s3,server]>=5.1,<6", "ipython>=8.26.0", "mypy>=1.18.1", "pep8-naming>=0.13.3", "pytest>=9.0.3", "pytest-asyncio>=0.23.5", "pytest-bdd>=8.1.0", "pytest-cov>=5.0.0", "pytest-tap>=3.4", "pytest-timing @ git+https://github.com/emcie-co/mc-spitfyre.git@timing_v0.1.4#subdirectory=pytest-timing", "python-dotenv>=1.0.1", "ruff>=0.9.1", "types-python-dateutil>=2.8.19.20240106", "types-requests>=2.32.0.20240712", "types-toml>=0.10.8", "pytest-xdist>=3.6.1", "types-grpcio>=1.0.0.20251009", "pymongo-inmemory>=0.5.0", ] [tool.uv] override-dependencies = [ "onnxruntime<1.24; python_full_version < '3.11'", # 1.24+ dropped Python 3.10 support "onnxruntime; python_full_version >= '3.11'", # counterpart: without it, the override erases the requirement entirely on newer Pythons ] constraint-dependencies = [ # Minimum safe versions for transitive dependencies with known CVEs. # These constraints only affect resolution — they do not force installation. "aiohttp>=3.13.4", "azure-core>=1.38.0", "cryptography>=46.0.7", "diskcache>=5.6.4", "filelock>=3.20.3", "fonttools>=4.60.2", "Mako>=1.3.12", "orjson>=3.11.6", "pillow>=12.2.0", "protobuf>=6.33.5", "pyasn1>=0.6.3", "Pygments>=2.20.0", "pyopenssl>=26.0.0", "python-multipart>=0.0.30", "urllib3>=2.7.0", "werkzeug>=3.1.6", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.metadata] allow-direct-references = true [tool.hatch.build.targets.sdist] # The sdist otherwise takes the whole project directory. The wheel's exclude # list below does not cover it, and force-include ignores excludes entirely, # so scripts/publish.py re-checks every artifact before uploading. # Gitignore-style patterns: the leading slashes anchor these to the project # root, so "dist" does not also match src/parlant/api/chat/dist. uv builds the # wheel from the sdist, so anything excluded here is absent from both. exclude = [ "/pro", "/pro/**", "/tests/pro", "/tests/pro/**", "/dist", "/dist/**", "/widget/dist", "/widget/dist/**", "**/node_modules", "**/node_modules/**", "**/parlant-data", "**/parlant-data/**", "**/.env", "**/*.tsbuildinfo", ] [tool.hatch.build.targets.wheel] packages = ["src/parlant"] # The chat widget ships inside the package so `parlant widget init` can vendor # it without a network fetch. Only the source travels: node_modules (~127MB), # build output, and any local runtime data are excluded. exclude = [ "**/node_modules", "**/node_modules/**", "**/parlant-data", "**/parlant-data/**", "widget/dist", "widget/dist/**", "**/.env", "**/*.tsbuildinfo", ] [tool.hatch.build.targets.wheel.force-include] # Enumerated rather than including widget/ wholesale: force-include ignores # the exclude patterns above, so a blanket entry would ship widget/node_modules # (~127MB) into the wheel. tests/bin/test_packaging.py guards this. "widget/parlant-chat" = "parlant/_widget/parlant-chat" "widget/example" = "parlant/_widget/example" "widget/sample-agent" = "parlant/_widget/sample-agent" "widget/index.html" = "parlant/_widget/index.html" "widget/package.json" = "parlant/_widget/package.json" "widget/package-lock.json" = "parlant/_widget/package-lock.json" "widget/postcss.config.js" = "parlant/_widget/postcss.config.js" "widget/tailwind.config.js" = "parlant/_widget/tailwind.config.js" "widget/tsconfig.json" = "parlant/_widget/tsconfig.json" "widget/vite.config.ts" = "parlant/_widget/vite.config.ts" # The widget's own tests ship inside parlant-chat/ and example/; without this # config `npm test` in a vendored copy fails on a missing config. "widget/vitest.config.ts" = "parlant/_widget/vitest.config.ts" "widget/.env.example" = "parlant/_widget/.env.example" "widget/README.md" = "parlant/_widget/README.md"