[project] name = "yuki" version = "4.0.0" description = "具有持续身份、长期记忆与自主参与能力的多平台开源 AI Agent" readme = "README.md" license = "AGPL-3.0-only" license-files = ["LICENSE"] requires-python = ">=3.12,<3.13" dependencies = [ "cryptography>=48", "aiosqlite>=0.22.1,<1", "alembic>=1.14,<2", "httpcore>=1.0.9,<2", "httpx[socks]>=0.28.1,<1", "defusedxml>=0.7,<1", "jsonschema>=4.23,<5", "referencing>=0.35,<1", "nonebot-adapter-onebot>=2.4,<3", "nonebot2[fastapi]>=2.4,<3", "packaging>=24,<27", "pillow>=11,<13", "protobuf>=5,<8", "pydantic-settings>=2.7,<3", "python-dotenv>=1,<2", "python-socks[asyncio]>=2.7,<3", "pypdf>=6,<7", "sqlalchemy[asyncio]>=2.0.36,<3", "tenacity>=9,<10", "tzdata>=2025.2", "websockets>=16,<17", "yuki-semantic-participation @ https://github.com/Institute-of-Agent-Life/Yuki-Semantic-Participation/archive/a6a13d4f04ecc36da26adb5f364abdb4f032fc1e.tar.gz", "tomlkit>=0.13,<1", "agent-client-protocol==0.12.1", "opencc==1.4.2", ] [project.optional-dependencies] dev = [ "platformdirs>=4,<5", "mypy>=1.13,<2", "pytest>=8.3,<9", "pytest-asyncio>=0.24,<1", "ruff>=0.8,<1", "trustme>=1.2,<2", "types-jsonschema>=4.23,<5", "types-protobuf>=5,<8", "types-defusedxml>=0.7,<1", # Tests run the Connector source with this environment; on macOS it needs its screen. "pyobjc-framework-Quartz>=13,<14 ; sys_platform == 'darwin'", "pyobjc-framework-ScreenCaptureKit>=13,<14 ; sys_platform == 'darwin'", "pyobjc-framework-ApplicationServices>=13,<14 ; sys_platform == 'darwin'", ] [project.scripts] yuki = "yuki.cli:main" yuki-bot = "yuki.main:run" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build] exclude = ["src/yuki/_native", ".cache"] [tool.hatch.build.targets.wheel] packages = ["src/yuki", "src/yuki_plugin_sdk"] [tool.hatch.build.hooks.custom] path = "hatch_build.py" [tool.hatch.build.targets.sdist.force-include] "vendor/sqlite-vec1" = "vendor/sqlite-vec1" "scripts/build_vec1.py" = "scripts/build_vec1.py" "hatch_build.py" = "hatch_build.py" [tool.hatch.metadata] allow-direct-references = true [tool.ruff] target-version = "py312" line-length = 100 src = ["src", "tests"] [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "ASYNC", "RUF"] ignore = ["RUF001", "RUF002", "RUF003"] [tool.ruff.lint.per-file-ignores] "migrations/versions/*.py" = ["E501"] [tool.mypy] python_version = "3.12" strict = true packages = ["yuki", "yuki_plugin_sdk"] mypy_path = "src:packages/yuki-agent-connector/src" warn_unused_configs = true plugins = ["pydantic.mypy"] [[tool.mypy.overrides]] module = ["nonebot.*", "nonebot_adapter_onebot.*"] ignore_missing_imports = true # Built from the pinned Monty source by scripts/build_monty_worker.sh; optional # at import time so hosts without Code Mode still type-check and run. [[tool.mypy.overrides]] module = ["pydantic_monty", "pydantic_monty.*"] ignore_missing_imports = true [tool.pytest.ini_options] addopts = "-ra" asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" pythonpath = ["src", "packages/yuki-agent-connector/src"] testpaths = ["tests"] markers = [ "qwen_embedding_integration: opt-in test against the real DashScope embedding API", "native_worker: real pinned Monty worker/binding; executed by the native CI job", ]