forked from Project-N-E-K-O/N.E.K.O
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
209 lines (197 loc) · 7.02 KB
/
pyproject.toml
File metadata and controls
209 lines (197 loc) · 7.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
[build-system]
requires = ["hatchling", "setuptools<70"]
build-backend = "hatchling.build"
[project]
name = "N.E.K.O"
dynamic = ["version"]
description = "N.E.K.O. Desktop"
readme = "README.MD"
requires-python = "==3.11.*"
dependencies = [
"fastapi~=0.115.9",
"websockets~=15.0.1",
"soxr~=0.5.0",
"numpy~=1.26.4",
"websocket-client~=1.8.0",
"jinja2",
"dashscope==1.25.4",
"python-multipart",
"pillow",
"regex",
"pyautogui",
"backoff",
"toml",
"openai",
"google-genai>=1.56.0",
"anthropic",
"uvicorn",
"pyobjc; sys_platform == 'darwin'",
"pytesseract",
"pywin32; sys_platform == 'win32'",
"pywinauto; sys_platform == 'win32'",
"pygetwindow; sys_platform == 'win32'",
"pyrnnoise>=0.4.3",
"beautifulsoup4>=4.12.0",
"bilibili-api-python>=17.4.0",
"googletrans>=4.0.2",
"translatepy",
"tomli>=2.3.0",
"tomli-w>=1.2.0",
# sts2_autoplay/strategy_parser.py parses YAML strategy frontmatter. Declared
# explicitly rather than leaning on bilibili-api-python's transitive pull, so a
# change upstream can't silently break strategy loading in the packaged build.
"pyyaml>=6.0",
# ⚠ 严禁再加 loguru / structlog / logbook。日志统一走 utils.logger_config。
# lint 守门:scripts/check_no_loguru.py(CI: .github/workflows/analyze.yml)
"pyzmq>=27.1.0",
"ormsgpack>=1.4.0",
"browser-use>=0.11.0",
"cryptography>=45.0.6",
"python-dotenv>=1.2.1",
"requests>=2.32.5",
"sqlalchemy>=2.0.0",
"qrcode>=8.2",
"httpx[socks]>=0.28.1",
"psutil>=7.0.0",
"portalocker>=2.10.1",
"pyncm-async==1.8.1",
"tornado>=6.5.4",
"jmespath>=1.1.0",
"orjson>=3.11.8",
# memory-evidence-rfc §3.6.6: tiktoken for persona/reflection render
# token budgeting (o200k_base encoding). PR-1 pins the dep; PR-3 ships
# utils/tokenize.py and wires render-time counting.
"tiktoken>=0.7.0",
"cachetools>=5.3",
# Local memory embeddings (memory/embeddings.py): ONNX + tokenizer. CPU
# SIMD detection reads numpy's __cpu_features__ (compiled-C probe) — we do
# NOT use py-cpuinfo, whose low-level CPU probe runs a generated native
# routine in a child process that Huorong's heuristic flags as a trojan.
"onnxruntime",
"tokenizers",
# Cross-platform screen capture used by galgame_plugin and potentially other
# plugins (mss is also a candidate for brain/computer_use). Tiny (<1MB).
"mss",
"dxcam ; sys_platform == 'win32'",
# Linux X11 window enumeration / geometry for galgame_plugin
# (cross-platform-capture-plan). Falls back to `wmctrl` subprocess
# when this dependency is unavailable. Skipped on Windows/macOS
# to keep dev installs lean.
"python-xlib ; sys_platform == 'linux'",
# NOTE: rapidocr-onnxruntime + cv2 cohort lives in [dependency-groups] galgame
# below — it brings opencv (~109 MB on disk) which the main program does not
# use. Build scripts (Nuitka/PyInstaller) install --group galgame explicitly
# so the packaged dist still bundles it; plain `uv sync` skips it.
"imagehash>=4.3.2",
]
[tool.hatch.version]
path = "config/__init__.py"
pattern = '''^APP_VERSION\s*=\s*["'](?P<version>[^"']+)["']'''
[project.scripts]
neko-plugin = "plugin.neko_plugin_cli.cli:main"
[tool.hatch.build.targets.wheel]
packages = [
"app",
"brain",
"config",
"main_logic",
"main_routers",
"memory",
"plugin",
"steamworks",
"utils",
]
exclude = [
"plugin/plugins",
]
[tool.hatch.build.targets.sdist]
include = [
"app",
"brain",
"config",
"main_logic",
"main_routers",
"memory",
"plugin",
"steamworks",
"utils",
"static",
"templates",
"assets",
"launcher.py",
"README.MD",
"LICENSE",
]
exclude = [
"plugin/plugins",
]
# pyncm-async 已从 PyPI 下架(连同上游 pyncm 与 GitHub 仓库),改为本地 wheel 安装。
# music plugin 已对该依赖做了 try/except 防御(main_routers/music_router.py),
# 但 deps/*.whl 本地存档可保证 uv lock/sync 在无网/CI 环境下仍可复现。
[tool.uv.sources]
pyncm-async = { path = "./deps/pyncm_async-1.8.1-py3-none-any.whl" }
# rapidocr-onnxruntime hard-depends on `opencv-python`, but we want
# `opencv-python-headless` to provide the cv2 module instead (no GUI/Qt → ~25 MB
# smaller). The override below blocks the opencv-python pin so only the
# headless variant (declared in [dependency-groups] galgame) ends up in .venv.
# Both wheels expose the same `cv2` module name, so rapidocr's `import cv2`
# works against either.
#
# python3-xlib (0.15, a stale 2016 py3 fork that pyautogui/mouseinfo pin) and
# python-xlib (0.33, the maintained fork we depend on directly for galgame_plugin
# X11 enumeration) both install into the same `Xlib` import namespace — having
# both means whichever lands last wins, a latent Linux import hazard. We block
# python3-xlib so the single, modern python-xlib provides `Xlib` for everyone;
# its API is a strict superset, so pyautogui's `from Xlib...` resolves fine.
[tool.uv]
override-dependencies = [
"opencv-python ; sys_platform == 'never'",
"python3-xlib ; sys_platform == 'never'",
]
[dependency-groups]
dev = [
"nest-asyncio>=1.6.0",
"playwright>=1.58.0",
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.1.0",
"pytest-playwright>=0.7.2",
"ruff>=0.15.4",
]
# galgame_plugin native deps. NOT installed by default `uv sync` — keeps dev
# install lean (~130 MB saved). Build scripts add `--group galgame` so packaged
# Nuitka/PyInstaller dist bundles everything; plugin code import-guards these
# so the plugin still loads (with degraded OCR backend) when the group is missing.
# See memory: project_galgame_native_deps_size.md
galgame = [
"rapidocr-onnxruntime",
"opencv-python-headless", # provides cv2 module; ~25 MB lighter than opencv-python
]
# ─────────────────────────────────────────────────────────────────────────────
# Ruff: enforce zero-blocking-call policy in async def bodies.
# Covers: time.sleep / requests / urllib.request / subprocess.* (run, Popen…).
# Gaps (threading.Thread.join timeout, queue.Queue.get, threading.Event.wait
# timeout, raw socket.recv/send/accept/connect) are caught by the companion
# script scripts/check_async_blocking.py which the CI Analyze job also runs.
# ─────────────────────────────────────────────────────────────────────────────
[tool.ruff]
target-version = "py311"
extend-exclude = [
"frontend",
"dist",
".venv",
]
[tool.ruff.lint]
select = [
"ASYNC210", # blocking HTTP call (requests / urllib / httpx.Client)
"ASYNC220", # create-subprocess (Popen) in async function
"ASYNC221", # subprocess.run / call / check_output / check_call
"ASYNC222", # Popen.wait / Popen.communicate
"ASYNC251", # time.sleep in async function
]
[tool.coverage.run]
source = ["plugin/plugins/study_companion"]
[tool.coverage.report]
fail_under = 80
show_missing = true
skip_covered = true