[project] name = "opensquilla" version = "0.5.0rc3" description = "OpenSquilla — microkernel Python agent runtime with MCP-native tools and multi-channel messaging" license = "Apache-2.0" readme = "README.md" authors = [ { name = "OpenSquilla contributors" }, ] classifiers = [ "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3.12", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", ] requires-python = ">=3.12" dependencies = [ "starlette>=0.40", "python-multipart>=0.0.20", "uvicorn[standard]>=0.30", "pydantic>=2.0", "pydantic-settings>=2.0", "sqlmodel>=0.0.20", "sqlalchemy>=2.0", "anyio>=4.0", "httpx>=0.27", "brotli>=1.1", "jinja2>=3.1", "structlog>=24.0", "typer>=0.12", "rich>=13.0", "websockets>=13.0", "aiosqlite>=0.20", "apscheduler>=3.10", "pyyaml>=6.0", "sqlite-vec>=0.1", "html2text>=2024.2", "readability-lxml>=0.8", "beautifulsoup4>=4.12", "cachetools>=5.3", "pdfplumber>=0.11", "pillow>=10.0", "croniter>=2.0", "tomli-w>=1.0", "yoyo-migrations>=8.2,<10", # >=2.1: the onboarding wizard's provider select relies on # ``use_search_filter`` (type-to-filter), added in questionary 2.1. "questionary>=2.1", "python-docx>=1.1.0", "python-pptx>=1.0.0", "openpyxl>=3.1.0", "pypdf>=4.0.0", "reportlab>=4.0.0", "lark-oapi>=1.5.3,<2", "python-telegram-bot>=20.0", "dingtalk-stream>=0.24.3,<0.25", "qq-botpy>=1.2.1,<1.3", "cryptography>=42", "duckduckgo-search>=8.1.1", ] [project.optional-dependencies] dev = [ "pytest>=8.0", "pytest-asyncio>=0.24", "mypy>=1.10", "ruff>=0.5", ] mcp = ["mcp>=1.2.0"] # Optional Outlook .msg attachment extraction. Heavy transitive deps # (oletools, msoffcrypto-tool, …), so it is opt-in; .msg uploads degrade # gracefully with a clear message when this extra is not installed. msg = ["extract-msg>=0.48"] memory = [ "tiktoken>=0.5", "jieba>=0.42", ] recommended = [ "tiktoken>=0.5", "jieba>=0.42", "numpy>=1.26", "lightgbm>=4.0", "joblib>=1.3", "scikit-learn>=1.3", "onnxruntime>=1.17", "tokenizers>=0.15", ] matrix = ["matrix-nio>=0.25,<0.26", "markdown>=3.0"] matrix-e2e = ["matrix-nio[e2e]>=0.25,<0.26", "markdown>=3.0"] document-extras = [ "weasyprint>=60.0", ] swebench = [ "datasets>=2.19", "swebench>=4.0", ] [project.scripts] opensquilla = "opensquilla.cli.main:app" gateway = "opensquilla.cli.main:gateway_app" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/opensquilla"] exclude = [ "src/opensquilla/scheduler/templates/*.md", "src/opensquilla/skills/bundled/**/THIRD_PARTY_NOTICES.md", "src/opensquilla/skills/bundled/**/README.md", "src/opensquilla/skills/bundled/**/LICENSE.md", "src/opensquilla/skills/bundled/**/skill-card.md", "src/opensquilla/skills/bundled/**/references/*.md", "src/opensquilla/skills/exp/**", "src/opensquilla/skills/meta/META_SKILL_AUTHORING.md", ] [tool.hatch.build.targets.wheel.force-include] "migrations/" = "opensquilla/_migrations/" "src/opensquilla/skills/bundled/html-coder/references/add-css-style.md" = "opensquilla/skills/bundled/html-coder/references/add-css-style.md" "src/opensquilla/skills/bundled/html-coder/references/add-javascript.md" = "opensquilla/skills/bundled/html-coder/references/add-javascript.md" "src/opensquilla/skills/bundled/html-coder/references/attributes.md" = "opensquilla/skills/bundled/html-coder/references/attributes.md" "src/opensquilla/skills/bundled/html-coder/references/essentials.md" = "opensquilla/skills/bundled/html-coder/references/essentials.md" "src/opensquilla/skills/bundled/html-coder/references/global-attributes.md" = "opensquilla/skills/bundled/html-coder/references/global-attributes.md" "src/opensquilla/skills/bundled/html-coder/references/glossary.md" = "opensquilla/skills/bundled/html-coder/references/glossary.md" "src/opensquilla/skills/bundled/html-coder/references/standards.md" = "opensquilla/skills/bundled/html-coder/references/standards.md" "src/opensquilla/skills/bundled/pptx/references/pptxgenjs.md" = "opensquilla/skills/bundled/pptx/references/pptxgenjs.md" "src/opensquilla/skills/bundled/pptx/references/python_pptx.md" = "opensquilla/skills/bundled/pptx/references/python_pptx.md" [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" norecursedirs = ["tests/_private", "tests/fixtures", ".omx", ".codex", ".claude"] markers = [ "llm: marks tests that make real external model/provider API calls (deselect with '-m \"not llm\"')", "llm_smoke: low-cost live LLM smoke tests", "llm_costly: slower or more expensive live model/provider tests", "llm_tools: live model tests that exercise tool calling", "llm_embedding: live embedding/vector-provider tests", "llm_reasoning: live reasoning-capable model tests", "llm_gateway: live gateway/end-to-end runtime tests", "llm_image: live image-generation model API tests", "llm_router_acc: live multi-model routing accuracy tests", "agent_context_boundary: agent context budget and compaction boundary tests", "local_golden: local opt-in synthetic complex-task golden tests", "webui_browser: real browser Web UI tests driven by Playwright", "tui_real_terminal: real terminal TUI integration tests driven through tmux or PTY", "live_channel: marks tests that hit a real channel platform (deselect with '-m \"not live_channel\"')", "live_search: marks opt-in tests that hit real search providers (deselect with '-m \"not live_search\"')", ] [tool.ruff] target-version = "py312" line-length = 100 [tool.ruff.lint] select = ["E", "F", "I", "N", "W", "UP"] [tool.ruff.lint.per-file-ignores] # Skill-creator template scripts: long lines carry help strings and # example code meant to be copy-pasted verbatim; reformatting would # harm readability. E402 imports-after-sys.path-munge is intentional. "src/opensquilla/skills/bundled/skill-creator/scripts/*.py" = ["E501", "N806", "E402"] "src/opensquilla/skills/bundled/skill-creator-linter/scripts/*.py" = ["E402", "I001"] # meta-short-drama subprocess scripts: long lines hold argv arrays, # ffmpeg filter graphs, Chinese error strings, and OpenRouter payload # field comments meant to stay readable as one unit. "src/opensquilla/skills/bundled/ai-video-script/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/AwesomeWebpageMetaSkill/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/nano-banana-pro/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/seedance-2-prompt/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/srt-from-script/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/subtitle-burner/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/text-file-read/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/title-card-image/scripts/*.py" = ["E501"] "src/opensquilla/skills/bundled/video-merger/scripts/*.py" = ["E501"] # video-merger src/ is vendored from upstream MIT-0 clawhub package; keep # its Chinese docstrings + ffmpeg argv lines unwrapped. "src/opensquilla/skills/bundled/video-merger/src/*.py" = ["E501", "F401"] "src/opensquilla/skills/bundled/video-still-animator/scripts/*.py" = ["E501"] # meta-short-drama DAG generator: template strings embed YAML blocks # whose original line breaks must be preserved. "scripts/_gen_meta_short_drama.py" = ["E501"] [tool.mypy] python_version = "3.12" warn_return_any = true warn_unused_configs = true exclude = [ "^src/opensquilla/squilla_router/models/", "^src/opensquilla/skills/bundled/.*/scripts/", # video-merger ships an upstream MIT-0 library under src/; same # treatment as the per-skill scripts/ trees. "^src/opensquilla/skills/bundled/video-merger/src/", ] [[tool.mypy.overrides]] module = [ "botbuilder.*", "botpy.*", "cachetools.*", "datasets.*", "dingtalk_stream.*", "extract_msg.*", "jieba", "nio.*", "numpy.*", "onnxruntime.*", "readability.*", "src.router.*", "swebench.*", "tiktoken.*", "tokenizers.*", "websockets.*", "yaml.*", "yoyo.*", ] ignore_missing_imports = true [dependency-groups] dev = [ "laboratory>=1.0.2", "syrupy>=5.1.0", ]