Files
forge/apps/api/pyproject.toml
T
nihalashetty ae67bff5a3 feat: deep-agent canvas, live observability, and multi-environment tooling
Self-hosted platform for building, testing, and shipping LangChain/LangGraph agents. Deep-agent sub-agents on the canvas, a live tracing/observability timeline, auto-provisioned built-in tools with import/export, per-environment tool variables, streamed evaluations, and per-user auth token forwarding.
2026-07-28 01:49:19 +05:30

120 lines
4.7 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "forge-api"
version = "0.1.0"
description = "Forge - self-hosted platform for visually building, testing, and shipping LangChain/LangGraph agents & workflows."
readme = "README.md"
requires-python = ">=3.11,<3.14"
license = { text = "MIT" }
# Pins validated against PyPI on 2026-06-07.
# Semver promise: langchain/langgraph 1.x minor upgrades are non-breaking. Re-verify each phase.
dependencies = [
# --- Web / API ---
"fastapi>=0.115,<1",
"uvicorn[standard]>=0.32,<1",
"sse-starlette>=2.1,<4",
"python-multipart>=0.0.18",
# --- Data / settings ---
"pydantic>=2.9,<3",
"pydantic-settings>=2.6,<3",
"email-validator>=2.2,<3",
# --- Persistence (SQLite default; Postgres is a documented prod swap) ---
"sqlalchemy[asyncio]>=2.0.36,<3",
"aiosqlite>=0.20,<1",
"alembic>=1.14,<2",
"greenlet>=3.1",
# --- LangChain / LangGraph (MIT framework only; never langgraph-api/LangSmith) ---
"langchain>=1.3,<2",
"langchain-core>=1.3,<2",
"langgraph>=1.2,<2",
"langgraph-checkpoint>=4,<5",
"langgraph-checkpoint-sqlite>=3,<4",
# Deep Agents harness (planning/subagents/filesystem/sandbox). Core, not optional:
# the `deep_agent` node is always registered in the palette, so it must always import.
"deepagents>=0.6,<1",
# --- Tooling primitives ---
"jmespath>=1.0,<2",
"jsonschema>=4.23,<5",
"httpx>=0.27,<1",
"RestrictedPython>=7.4,<9",
# Accurate token counting for the cost meter / budgets (graceful len/4 fallback if absent).
"tiktoken>=0.7",
# --- Secrets / auth (platform) ---
"cryptography>=43",
"python-jose[cryptography]>=3.3,<4",
# bcrypt directly (passlib 1.7.x is unmaintained and crashes probing bcrypt>=4.1).
"bcrypt>=4,<6",
]
[project.optional-dependencies]
# Vector store (user-mandated: Chroma). Embedded persistent client - zero infra.
vectors = ["chromadb>=1.5,<2"]
# Native big-three model providers + universal gateways.
providers = [
"langchain-openai>=1,<2",
"langchain-anthropic>=1,<2",
# deepagents (core) requires google-genai >=4.2.2; keep this compatible so
# `pip install -e ".[providers]"` resolves cleanly alongside it.
"langchain-google-genai>=4.2.2,<5",
]
# MCP: consume external servers + expose projects as MCP servers.
mcp = ["langchain-mcp-adapters>=0.2,<1", "mcp>=1.9", "fastmcp>=3,<4"]
# Background workers + cache (prod). Local default uses in-process fakes.
# croniter powers cron `schedule` triggers (interval schedules need nothing extra).
workers = ["redis>=5,<9", "arq>=0.26,<1", "croniter>=2,<7"]
# Durable Postgres checkpointer + async driver (prod run/HITL state, shared across workers).
# Set FORGE_CHECKPOINT_BACKEND=postgres and FORGE_DATABASE_URL to a postgresql+asyncpg URL.
postgres = ["langgraph-checkpoint-postgres>=2,<5", "psycopg[binary,pool]>=3.2", "asyncpg>=0.30"]
# OpenTelemetry export (point at an OTLP collector or Langfuse). Opt-in: no-op if absent.
observability = [
"opentelemetry-sdk>=1.20",
"opentelemetry-exporter-otlp-proto-http>=1.20",
]
# Knowledge ingestion loaders/splitters + lexical (BM25) ranking for hybrid search +
# fastembed (local open-source ONNX embedder, no API cost / no PyTorch).
knowledge = ["langchain-text-splitters>=1,<2", "pypdf>=5", "beautifulsoup4>=4.12", "rank-bm25>=0.2,<1", "fastembed>=0.3,<1"]
# One-shot convenience for a fully-functional local app: vector store + model providers
# + knowledge loaders + MCP. Excludes prod-only infra (workers, observability), which
# the local stack fakes in-process. Install with: pip install -e ".[dev,all]"
all = ["forge-api[vectors,providers,knowledge,mcp]"]
dev = [
"pytest>=8.3,<10",
"pytest-asyncio>=0.24,<2",
"anyio>=4.6",
# Pin the minor so CI lint is reproducible (an unbounded ruff pulls new rule sets that
# can turn CI red without a code change). Bump deliberately.
"ruff>=0.15,<0.16",
"mypy>=1.13,<3",
]
[tool.hatch.build.targets.wheel]
packages = ["forge"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
filterwarnings = ["ignore::DeprecationWarning"]
[tool.mypy]
python_version = "3.11"
# Most runtime deps (langchain, chromadb, fastmcp, …) ship without type stubs.
ignore_missing_imports = true
warn_redundant_casts = true
warn_unused_ignores = true
# Gradual typing: the engine predates static type-checking, so a full strict pass is a
# tracked backlog (~90 findings, dominated by dynamic SQLAlchemy Row/column access). CI
# runs mypy in advisory (non-blocking) mode today; newly written / refactored modules are
# kept clean. The gate is tightened as the backlog is cleared - see CONTRIBUTING.md.
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]
ignore = ["E501", "B008"]