Files
openworker/pyproject.toml
Devika Verma 4181039ac4 OpenShell provider: one sandbox per agent, with a registry and network profiles
Folders are bind-mounted at their real paths; the runner is a read-only mount and the main command.
The policy is rendered from the session's roots, with the owner's uid and Landlock as a hard requirement.
The runner's pipe is the gateway's gRPC exec stream; the registry caps and cleans up sandboxes.
2026-09-19 16:53:35 -07:00

110 lines
4.3 KiB
TOML

[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "openworker"
version = "0.2.3"
description = "OpenWorker — an open-source AI coworker you govern. The headless runtime and CLI."
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.10"
dependencies = [
"openai>=1.0",
"anthropic>=0.40", # native Claude Messages API provider
"google-genai>=1.0", # native Gemini provider
"google-auth>=2.23", # Vertex credentials (service account / ADC / MaaS bearer)
"textual>=1.0",
"fastapi>=0.110",
"uvicorn[standard]>=0.27",
# aisuite (tool metadata, toolkits, tracing). 0.2.0 is the first PyPI release with those modules.
"aisuite>=0.2.0",
"docstring_parser",
"pyyaml>=6", # persona manifest frontmatter (YAML)
"pydantic>=2",
"mcp>=1.28.1,<2", # MCP client (stdio + streamable-http); floor >=1.28.1 avoids PYSEC-2026-3481/3482/3483 (fixed in 1.27.2/1.28.1); <2 since 2.0.0 removed streamablehttp_client
"httpx>=0.27", # sync outbound senders for messaging connectors (send_message tool)
"websockets>=13", # managed Slack relay client transport (relay_client.py) + remote-home joiner
"cryptography>=42", # ed25519 machine identity for remote homes (already transitive via google-auth)
"ddgs>=9", # keyless default web-search provider (DuckDuckGo); Tavily/Brave use httpx
"croniter>=2", # cron next-fire math for the automation scheduler
# PDF attachments for models without native PDF support (pdf_support.py):
# pypdf = pure-python text extraction; pypdfium2 = page rasterization (BSD pdfium,
# ships its own libpdfium — NOT PyMuPDF, whose AGPL license can't ride in the DMG).
"pypdf>=5",
"pypdfium2>=4",
# IANA tz database for zoneinfo. Windows ships no system tz db, so without this every
# named schedule timezone (UTC, Asia/Kolkata, …) silently falls back to local time.
"tzdata; sys_platform == 'win32'",
# tomllib landed in the 3.11 stdlib; on the 3.10 floor config.py falls back to tomli.
"tomli>=2; python_version < '3.11'",
]
[project.urls]
Homepage = "https://openworker.com"
Source = "https://github.com/andrewyng/openworker"
[project.optional-dependencies]
dev = ["pytest>=8", "pytest-asyncio", "pytest-cov>=5", "httpx", "httpx2"]
# Inbound messaging listeners (outbound send_message needs only httpx, already a core dep).
# aiohttp is slack-bolt's Socket Mode transport at runtime (and the FakeSlack test harness
# drives the real handler) — declare it so CI installs it, not just transitively.
messaging = ["python-telegram-bot>=21", "slack-bolt>=1.18", "aiohttp>=3.9"]
# Interactive Cowork browser automation.
browser = ["playwright>=1.44"]
# AWS Bedrock provider (lazy-imported; desktop builds bundle it, pip users opt in).
bedrock = ["boto3>=1.34"]
# OpenShell sandbox provider: the runner's stream is a gRPC call to the OpenShell gateway.
openshell = ["grpcio>=1.60"]
[project.scripts]
openworker = "coworker.cli:main"
openworker-server = "coworker.server.run:main"
openworker-connectors = "coworker.connectors.cli:main"
openworker-acceptor = "coworker.remote.service:main"
# The board as an open surface (OPE-100): `ocw board …` / `ocw journal …`,
# including `ocw board mcp` — the stdio MCP server external harnesses attach to.
ocw = "coworker.teams.cli:main"
[tool.setuptools.packages.find]
where = ["."]
include = ["coworker*"]
[tool.setuptools.package-data]
coworker = [
"personas/builtin/*.md",
"personas/builtin/*/manifest.md",
"personas/builtin/*/skills/*/SKILL.md",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
# The reviewer-eval tests import from the repo-root scripts/ package; the pytest
# console script (CI) does not put the root on sys.path the way `python -m pytest` does.
pythonpath = ["."]
asyncio_mode = "auto"
[tool.coverage.run]
source = ["coworker"]
branch = true
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/migrations/*",
]
[tool.coverage.report]
show_missing = true
skip_covered = false
precision = 1
# Ratchet floor — only goes up, never down.
# Run `pytest tests --cov=coworker --cov-report=term-missing` to see current coverage.
fail_under = 0
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise NotImplementedError",
"if TYPE_CHECKING:",
"if __name__ == .__main__.:",
]