Files
agent-desktop/pyproject.toml
T

206 lines
6.5 KiB
TOML

[project]
name = "pineagents"
dynamic = ["version"]
description = "QwenPaw is a **personal assistant** that runs in your own environment. It talks to you over multiple channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.) and runs scheduled tasks according to your configuration. **What it can do is driven by Skills — the possibilities are open-ended.** Built-in skills include cron, PDF/Office handling, news digest, file reading, and more; you can add custom skills. All data and tasks run on your machine; no third-party hosting."
readme = "README.md"
requires-python = ">=3.11,<3.14"
dependencies = [
"agentscope==2.0.4.post1",
"httpx>=0.27.0",
"packaging>=24.0",
"discord-py>=2.3",
"dingtalk-stream>=0.24.3",
"alibabacloud-dingtalk>=2.2.42",
"alibabacloud-tea-openapi>=0.4.4",
"alibabacloud-credentials>=0.3.0",
"alibabacloud-tea-util>=0.3.0",
"uvicorn>=0.40.0",
"apscheduler>=3.11.2,<4",
"playwright>=1.49.0",
"questionary>=2.1.1",
"mss>=9.0.0",
"reme-ai==0.4.1.3",
"transformers>=4.30.0",
"python-dotenv>=1.0.0",
"python-socks>=2.5.3",
"onnxruntime<1.24",
"lark-oapi>=1.5.3",
"python-telegram-bot>=20.0",
"slack-bolt>=1.22.0",
"twilio>=9.10.2",
"pywebview>=4.0",
"aiofiles>=24.1.0",
"paho-mqtt>=2.0.0",
"wecom-aibot-python-sdk==1.0.2",
"matrix-nio>=0.25.0",
"shortuuid>=1.0.0",
"google-genai>=1.67.0",
"tzdata>=2024.1",
"cryptography>=43.0.0",
"keyring>=25.0.0",
"pyyaml>=6.0",
"wcmatch>=10.0",
"json-repair>=0.30.0",
"segno>=1.6.6",
"modelscope>=1.35.0",
"huggingface_hub>=0.20.0",
"pillow>=10.0.0",
"agent-client-protocol>=0.9.0,<0.11.0",
# Streaming-markdown terminal UI for the bundled `qwenpaw` TUI
# (v4+ adds the streaming Markdown widget). 8.2.8 fixes parsing of
# multi-codepoint Kitty "associated text" so input methods (Chinese,
# Japanese, accents, ...) no longer leak escape sequences into the prompt
# (Textualize/textual#6592). Keep the temporary upper bound in sync with
# the TUI compatibility shim for Textualize/textual#6643; remove both
# after Textual ships and QwenPaw verifies the upstream fix.
"textual>=8.2.8,<8.2.9",
"psutil>=6.0.0",
"openai>=2.0.0,<=2.33.0",
# anyio 4.13.0: _deliver_cancellation busy-loop / getpid storm (QwenPaw#2632)
"anyio>=4.0.0,<4.13.0",
"watchfiles>=0.22",
"orjson>=3.9",
# Coding Mode — Python LSP server bundled as a zero-config fallback
# so the `lsp` tool always works for .py files (see PROPOSAL §3.4).
"python-lsp-server[all]>=1.10",
# Coding Mode — multi-language AST pattern matcher used by ast_search.
# Pure-Python wrapper around a prebuilt Rust binary; PyPI distributes
# wheels for all three OSes.
"ast-grep-cli>=0.20",
"html2text>=2024.2.26",
]
[project.urls]
Homepage = "https://qwenpaw.agentscope.io/"
Repository = "https://github.com/agentscope-ai/QwenPaw"
Documentation = "https://qwenpaw.agentscope.io/docs/"
Issues = "https://github.com/agentscope-ai/QwenPaw/issues"
[tool.setuptools.dynamic]
version = {attr = "pineagents.__version__.__version__"}
[tool.setuptools]
packages = { find = { where = ["src"] } }
include-package-data = true
[tool.setuptools.package-data]
# Dockerfile copies console build output to src/pineagents/console/ (no dist subdir).
"pineagents" = [
"console/**",
"agents/md_files/**",
"agents/skills/**",
"agents/context/visual_compression/assets/atlas-gray.ts",
"agents/context/visual_compression/assets/atlas-gray-medium.ts",
"agents/context/visual_compression/assets/atlas-gray-high.ts",
"agents/context/visual_compression/assets/JETBRAINS_MONO_LICENSE.txt",
"agents/context/visual_compression/assets/UNIFONT_LICENSE.txt",
"agents/context/visual_compression/assets/SPLEEN_LICENSE.txt",
"agents/tools/deprecated_browser/skills/**",
"tokenizer/**",
"security/tool_guard/rules/**",
"security/skill_scanner/rules/**",
"security/skill_scanner/data/**",
"browser/control_link/injected/*.js",
"docs/*.md",
"app/channels/yuanbao/proto/**",
]
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project.scripts]
# PineAgents 品牌命令;qwenpaw/copaw 为兼容别名。
pineagents = "pineagents.cli.main:cli"
# Optional doctor plugins: callable (DoctorRunContext) -> list[str]
# [project.entry-points."qwenpaw.doctor"]
# my_pkg = "my_pkg.doctor:doctor_notes"
# Legacy group "copaw.doctor" is still loaded when present.
[project.optional-dependencies]
test = [
"pytest>=8.3.5",
"pytest-asyncio>=0.23.0",
"pytest-cov>=6.2.1",
"pytest-timeout>=2.3.0",
"pytest-xdist>=3.5.0",
"hypothesis>=6.0.0",
"qoder-agent-sdk==1.0.9",
]
dev = [
"pre-commit>=4.2.0",
]
local = [
"huggingface_hub>=0.20.0",
]
whisper = [
"openai-whisper>=20231117",
]
codex = [
"openai-codex==0.144.4",
]
qoder = [
"qoder-agent-sdk==1.0.9",
]
full = [
"pineagents[local,whisper,codex,qoder]",
]
sip = [
"pyVoIP>=1.6.0",
"dashscope>=1.0.0",
"dashscope-realtime>=0.1.0",
"audioop-lts; python_version >= '3.13'",
]
sip-livekit = [
"pineagents[sip]",
"livekit>=1.0.0",
"livekit-api>=0.6.0",
]
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"p0: critical user flows (messaging, CRUD, global config, security); PR smoke gate",
"p1: supported features (settings, scoped overrides, helpers); nightly regression",
"p2: error paths, 404 handling, validation, contracts, metadata",
"unit: marks tests as unit tests",
"contract: marks tests as contract tests",
"integration: marks tests as integration tests",
"e2e: marks tests as end-to-end tests",
]
testpaths = [
"tests",
]
[tool.coverage.run]
source = ["src/pineagents"]
omit = [
"*/tests/*",
"*/test_*",
"*/__pycache__/*",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"pass",
]
# Coverage gate (raised in stages per the July quality plan):
# 30 (baseline) -> 45 (stage 1) -> 50 (current, ~1.6pt headroom under
# CI's measured 51.59% per the "leave 1-2pt to resist flaky" rule).
# Bump up only after natural coverage rises (bug-regression + contract
# gains), never chase a number.
fail_under = 50
show_missing = true
[tool.coverage.html]
directory = "htmlcov"