项目概览
Whimbox(奇想盒)是面向《无限暖暖》的 AI 游戏助手;当前仓库承担后端职责,以 RPC 服务、模型调用和工具调用支持独立的奇想盒 app。README.md
用途与范围
本文介绍仓库定位、代码组织、安装元数据、程序入口与两种启动路径,以及从现有源码能够确认的启动边界。每日任务、地图导航、图像识别、agent 内部推理和 RPC 协议属于各自子系统;这里仅说明它们在整体中的位置,不推断其内部实现。前端 UI 在独立 app 中,本仓库不再提供 UI 界面。README.md README.md
概述
README 将能力分为每日任务、自动对话与采集等小功能、跑图和路线录制、操作宏、MIDI 转脚本、AI 对话与微信远程控制。项目说明强调其以截图、鼠标键盘模拟参与游戏,不修改游戏文件或读写游戏内存;这是项目声明,而非对兼容性或安全性的保证。开发说明写明 Python 3.12;包元数据将版本定为 3.1.0,并精确要求 ==3.12.8。README.md pyproject.toml
从仓库层次看,whimbox/ 包含入口、agent、RPC、任务、交互、地图、视觉模型接口与资源等目录;README 还列出仓库级 configs/、scripts/、logs/。这些是项目结构说明,不应据此推断某目录的持久化格式或每个模块的调用顺序。README.md
架构
下图仅描绘已在入口中明确出现的调用关系:main 选择启动分支,服务模式先准备环境、初始化插件,再在后台启动 agent 并在当前事件循环中等待 RPC 服务;一条龙模式直接执行任务。README 指明 app 是独立前端,故图中不将 app 画成已验证的具体 RPC 方法调用者。
Source: main.py
入口没有在 main.py 中定义 RPC 方法、插件加载规则或 agent 的模型策略:它们分别从 whimbox.rpc_server、whimbox.plugin_runtime 和 whimbox.agent 引入。架构图的箭头只表示入口代码可验证的调用,而不代表这些组件的全部依赖。main.py
启动流程与执行边界
分支选择和预检
pyproject.toml 将命令行脚本 whimbox 指向 whimbox.main:main。main() 只将第一个参数精确等于 startOneDragon 的调用路由至 run_one_dragon();不带参数或第一个参数为其他字符串时进入 run_whimbox()。因此未识别参数不会在此处产生用法错误,而会启动服务模式。pyproject.toml main.py
1def main():
2 if len(sys.argv) > 1:
3 if sys.argv[1] == "startOneDragon":
4 run_one_dragon()
5 else:
6 run_whimbox()
7 else:
8 run_whimbox()Source: main.py
两条路径都先调用 _prepare():尝试启用 DPI 感知;is_admin() 不通过时记录错误并退出;读取已安装包版本,若未安装则输出 dev;最后清理 LOG_PATH/screenshot 下的内容。目录不存在时会创建;对子项的删除逐个捕获 OSError 并继续,故清理失败不会在这里中断启动,但残留截图可能保留。main.py
1def _prepare():
2 enable_dpi_awareness()
3 from whimbox.common.utils.utils import is_admin
4 if not is_admin():
5 logger.error("请用管理员权限运行")
6 exit()
7 from importlib.metadata import PackageNotFoundError, version
8 try:
9 logger.info(f"奇想盒后台版本号: {version('whimbox')}")
10 except PackageNotFoundError:
11 logger.info(f"奇想盒后台版本号: dev")
12 _clear_temp_file()Source: main.py
服务模式
run_whimbox() 预检后才导入插件初始化器、agent 实例和 RPC 启动函数,随后用 asyncio.run 运行 _run_whimbox_services。此协程同步执行 init_plugins(),之后创建 agent 后台任务;后台任务通过 asyncio.to_thread 在工作线程里执行 asyncio.run(whimbox_agent.start())。主事件循环随即等待 start_rpc_server()。这是两个事件循环分置于主线程与工作线程的启动形态,而不是在同一个协程中顺序等待 agent 完成。main.py
Source: main.py
finally 在 RPC 协程退出时取消尚未完成的外层 agent_task,并用 gather(..., return_exceptions=True) 等待取消处理。源码没有提供后台线程内 whimbox_agent.start() 结束的显式协调或就绪握手,因此不能把“RPC 已开始等待”解释为“agent 已就绪”。agent 后台启动出现 Exception 会被记录并重新抛出;RPC 等待处并未在同一函数里显式检查 agent_task 的结果。main.py
一条龙模式
run_one_dragon() 在同一预检之后构造 AllInOneTask(session_id="default"),同步调用 task_run(),读取返回值的 message 并记日志。入口本身没有实现任务重试、进度持久化或结束后关闭游戏的逻辑;README 所述关闭设置是 app 的一条龙配置说明,不应等同于本入口的行为。main.py README.md
1def run_one_dragon():
2 _prepare()
3
4 from whimbox.task.daily_task.all_in_one_task import AllInOneTask
5
6 logger.info("开始执行一条龙任务...")
7 task = AllInOneTask(session_id="default")
8 task_result = task.task_run()
9 logger.info(f"一条龙任务完成: {task_result.message}")
10 logger.info("任务结束,程序退出")Source: main.py
用法示例与项目配置
以下示例是仓库中的实际入口和打包配置,不将 README 的 app 启动步骤误写成本仓库的 CLI 命令。README 推荐通过独立 app 运行后端;其命令行运行一条龙的说明是先在 app 中确认能正常运行并勾选自动运行,再启动 whimbox_app.exe。README.md
脚本入口与打包范围
1[project.scripts]
2whimbox = "whimbox.main:main"
3
4[tool.setuptools.packages.find]
5where = ["."]
6include = ["whimbox*"]Source: pyproject.toml
资源打包配置包含 whimbox.assets 中的 JSON、文本、YAML、Markdown、图标和图片,以及 whimbox.plugins 中的 JSON;同时排除 Python 缓存、日志和若干开发用原始地图图片。这区分了可分发包资源与运行时日志或仓库级脚本,并不证明运行时具体资源加载顺序。pyproject.toml
| 项目设置 | 类型 / 值 | 默认或约束 | 作用 |
|---|---|---|---|
project.version | 字符串 | 3.1.0 | 发布包版本;入口尝试读取已安装版本。 |
project.requires-python | 版本约束 | ==3.12.8 | 包元数据的精确 Python 版本要求;README 的“Python 3.12”表述更宽泛。 |
project.scripts.whimbox | 入口映射 | whimbox.main:main | 定义安装后的控制台脚本入口。 |
tool.setuptools.packages.find.include | 字符串列表 | whimbox* | 限定 setuptools 的包发现范围。 |
tool.setuptools.package-data | 文件模式映射 | whimbox.assets 和 whimbox.plugins 的模式 | 随包包含部分资源和插件 JSON。 |
tool.setuptools.exclude-package-data | 文件模式映射 | 缓存、日志及列出的地图原图 | 排除不应随包发布的文件。 |
以上均来自 pyproject.toml。README 还标注仓库级 configs/config.json 与 configs/agent_workspace/,但这里未核验配置文件内容,不提供其字段、默认值或读写语义。README.md
入口 API 速查
以下签名取自入口实现;未标注返回类型的函数也未在此假定具体返回契约。main.py
| 函数 | 参数 | 可确认行为 / 返回 |
|---|---|---|
main() | 无显式参数,读取 sys.argv | 依首个参数选择 run_one_dragon() 或 run_whimbox();无显式返回。 |
run_whimbox() | 无 | 准备环境并用 asyncio.run 启动服务协程;无显式返回。 |
run_one_dragon() | 无 | 准备环境,创建默认 session 的任务并调用 task_run();记录 task_result.message,无显式返回。 |
_prepare() | 无 | 执行 DPI 设置、管理员检查、版本日志及临时截图清理;权限不符时调用 exit()。 |
_run_whimbox_services(init_plugins, whimbox_agent, start_rpc_server) | 三个运行时传入的插件初始化器、agent 对象和 RPC 启动函数 | async def;先初始化插件,创建后台任务,再 await start_rpc_server();退出时处理外层任务取消。 |
这些是 Python 入口函数而非 HTTP 接口;RPC 的方法、地址与请求响应格式未在已核验的入口源码中定义,不能由 start_rpc_server() 的名称反推出协议。main.py
故障边界、并发与运行注意
- 预检和清理:管理员检查失败时记录错误并退出;找不到安装元数据只降级显示
dev;截图清理会忽略单个条目的OSError。截图目录会在清理之前创建。main.py - 启动传播:
init_plugins()位于后台任务创建之前,入口没有对其异常设置捕获;agent 后台启动异常被记录并重新抛出,但不会在 RPCawait之前被显式等待;RPC 退出触发finally清理外层任务。main.py - 执行负载与环境:README 提醒图像识别叠加游戏运行会额外占用 PC 性能,当前仅支持游戏以标准 16:9 分辨率运行,并提醒用户自行承担使用后果;这是项目使用限制而不是入口的运行时校验。README.md
- 扩展边界:若增加启动服务,
_run_whimbox_services是现有编排点,但必须处理后台任务、RPC 生命周期与线程中的独立事件循环;若增加 CLI 模式,现有main()只有一个精确匹配分支。关于插件注册契约、任务状态和测试覆盖,所读源码未提供实现细节,不能承诺其行为。main.py