Repository navigation
Looper v2.13.198
Looper v2.13.198
Release Decision
Who should upgrade: Operators who set [runtimes] pi = "runner" in the ops file. Everyone else sees no difference: with the default pi = "cli" every Pi Worker, Reviewer and consult keeps its own process. It is a hotfix that ships the change merged since v2.13.197.
What this release solves: #842 lets the existing [runtimes] pi = "runner" opt-in host Pi Worker, Reviewer and consult runs on the shared runner, not only the Manager and Planner. Each run is one runner session behind the run handle added in v2.13.197.
Breaking changes: No. No command, database schema or setting changed. The default pi = "cli" is unchanged. Only a restart with pi = "runner" takes the new path, and that opt-in now covers every Pi role.
How to verify: Check the installed version.
Contributors: Maintainer @foolzzz authored #842; no community contribution was included in this patch release.
looper --version # looper 2.13.198Behavior changes
- Runner channel (
looper/agents/runtimes/runner/channel.py, new):RunnerChannelis one Worker, Reviewer or consult run on aRunnerSession; it is both the run handle and the run's input channel.launchmaps a full runner (CAPACITY) and an unavailable runner toRunStartErrorwith a reason that names the cause; the bound API key is redacted from the message.startsends the prompt without blocking. Events stream through an unbounded per-run queue so database writes by the consumer do not block the shared bridge.sendis a steer that is never cancelled, sent withif_idle=reject, and answers accepted, rejected or unknown; a steer the runner drops is reported throughdropped_input(), which the Planner already turns intomissed_messages.endstops the session once;waitwaits for the turn, then closes the session. A failure inside the run becomes an error result (the pi runner run failed (<ExceptionType>)) instead of an exception. A run with no platform tools answers a tool call with an error result. - Pi runner runtime (
looper/agents/runtimes/pi_runner.py):PiRunnerRuntime.hosts_runsis nowTrue, so with the opt-in Pi Workers, Reviewers and consults go throughhosted_run; other roles are refused. The runtime asserts the launch executable is the Pi the runner uses. The Descriptor carries the CLI tool sets (read,grep,find,lswhen read-only;read,bash,edit,writeotherwise).max_turnsbecomes the request limit (1000 when unset) and the run timeout becomes the bash tool ceiling (86400 seconds when unset). A consult forks a copy of the run's saved Pi session, made read-only (mode 0400), into its own private directory and removes that directory if setup fails; it is refused when the saved session has no unique file. A failed run reports the runner's error text (first 500 characters) as the failure detail. The CLI methodsrun_command,steer_commandandconsult_commandnow raiseRuntimeUnsupported, so there is no fallback to a Pi CLI process under the opt-in. Manager and Planner resident sessions are unchanged apart from sharing code. - Session cap: the runner keeps its 10-session cap, now shared by Manager, Planner and runs. A run started with no free session fails its step with the
CAPACITYreason and frees nothing else. - Text (
looper/ops_config.py,evals/prompt_regression/__main__.py): the ops file comment, the generated ops file and the--pi-runnerhelp now say the opt-in covers every Pi role, and the startup log line reads "Pi runner enabled for every Pi role (one runner, 10 sessions)". The generated ops file gains one comment line above[runtimes]. - Scope: 10 files, about 781 added lines including tests (the description reports tests 507, production 274, fixtures excluded).
- Model-visible changes: Under
pi = "runner"only: a Pi Worker, Reviewer or consult runs in the SDK runner, so its platform tools (room and vault) are in process rather than through MCP, with the same CLI built-in tool sets. A tool the run has no platform implementation for returns an error saying Looper has no platform tool of that name. The prompt text itself is built by the same code as for the resident sessions. With the defaultpi = "cli": none.
Upgrade and rollback
Re-run install.sh once v2.13.198 is published. There is nothing to configure; the runner stays off unless [runtimes] pi = "runner" is set, and changing it needs a restart. To roll back, set pi = "cli" and restart, or return to v2.13.197; there is no schema or setting change.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Retained implementation evidence: the description of #842 names the covering tests (tests/test_runner_channel.py, tests/test_runner_bridge.py, tests/test_runner_session.py, tests/test_pi_runner_opt_in.py, tests/test_pi_runner_serve_db.py), automated reviews and CI before the merge. It records no counts, verdicts or local full-suite result.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: Local test runs, a local full suite, a live service, a browser run, the built wheel. The release documentation gate checks the body only.
中文摘要
升级决策
**谁需要升级:**在 ops 文件中设置了 [runtimes] pi = "runner" 的运维者;其他用户无差别,默认 pi = "cli" 下每个 Pi Worker、Reviewer 和 consult 仍用自己的进程。本版本是随合并即发布的 hotfix,包含 v2.13.197 之后合并的改动。
解决了什么:#842 让已有的 [runtimes] pi = "runner" 开关不仅托管 Manager 和 Planner,也托管 Pi 的 Worker、Reviewer 和 consult 运行。每次运行是共享 runner 上的一个会话,位于 v2.13.197 引入的运行句柄之后。
**是否有破坏性变更:**无。命令、数据库 schema 和设置均未改变。默认 pi = "cli" 不变;只有设置 pi = "runner" 并重启才会走新路径,且该开关现在覆盖所有 Pi 角色。
**如何验证:**运行 looper --version 核对版本为 2.13.198。
**贡献者:**维护者 @foolzzz 提交 #842;本次 patch release 无社区贡献。
looper --version # looper 2.13.198行为变化与入口
- Runner channel(
looper/agents/runtimes/runner/channel.py,新增):RunnerChannel是RunnerSession上的一次 Worker、Reviewer 或 consult 运行,同时充当运行句柄和该运行的输入 channel。launch把 runner 已满(CAPACITY)和 runner 不可用映射为带原因的RunStartError,绑定的 API key 会从消息中脱敏。start不阻塞地发送提示词。事件经每次运行独立的无界队列传递,消费者写数据库不会阻塞共享 bridge。send是永不取消的 steer,以if_idle=reject发送,返回 accepted、rejected 或 unknown;runner 丢弃的 steer 通过dropped_input()报告,Planner 已将其转为missed_messages。end只停止会话一次;wait等待该轮结束后关闭会话。运行内部失败变为错误结果(the pi runner run failed (<异常类型>)),不再抛出异常。没有平台工具的运行对工具调用返回错误结果。 - Pi runner 运行时(
looper/agents/runtimes/pi_runner.py):PiRunnerRuntime.hosts_runs现为True,开启后 Pi 的 Worker、Reviewer 和 consult 经hosted_run运行,其他角色被拒绝。运行时会检查启动用的可执行文件就是 runner 使用的 Pi。Descriptor 带 CLI 的工具集(只读时为read、grep、find、ls,否则为read、bash、edit、write)。max_turns成为请求上限(未设置时为 1000),运行超时成为 bash 工具上限(未设置时为 86400 秒)。consult 把该运行已保存的 Pi 会话复制为只读(权限 0400)副本放入自己的私有目录,设置失败时删除该目录;已保存的会话没有唯一文件时被拒绝。运行失败时以 runner 的错误文本(前 500 字符)作为失败详情。run_command、steer_command和consult_command现在抛出RuntimeUnsupported,开关开启时不会回退为 Pi CLI 进程。Manager 和 Planner 常驻会话行为不变,仅共享代码。 - **会话上限:**runner 仍是 10 个会话的上限,现由 Manager、Planner 和运行共用。没有空闲会话时,运行以
CAPACITY原因使该步骤失败,不会释放其他会话。 - **文字(
looper/ops_config.py、evals/prompt_regression/__main__.py):**ops 文件注释、生成的 ops 文件和--pi-runner帮助现在说明该开关覆盖所有 Pi 角色,启动日志为 "Pi runner enabled for every Pi role (one runner, 10 sessions)"。生成的 ops 文件在[runtimes]上方多一行注释。 - **范围:**10 个文件,含测试约新增 781 行(描述写的是测试 507 行、生产代码 274 行,不含 fixtures)。
- **面向模型的变化:**仅在
pi = "runner"下:Pi 的 Worker、Reviewer 或 consult 在 SDK runner 中运行,平台工具(房间和知识库)在进程内而非经 MCP 提供,内置工具集与 CLI 相同。运行没有对应平台实现的工具时,返回说明 Looper 没有该名称平台工具的错误。提示词文本与常驻会话由同一代码生成。默认pi = "cli"下无变化。
升级与回退
v2.13.198 发布后重新运行 install.sh。无需配置;除非设置 [runtimes] pi = "runner",runner 保持关闭,修改后需重启。回退时将 pi 设回 "cli" 并重启,或回到 v2.13.197;无 schema 或设置变更。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
保留的实现证据:#842 的描述列出了覆盖的测试(tests/test_runner_channel.py、tests/test_runner_bridge.py、tests/test_runner_session.py、tests/test_pi_runner_opt_in.py、tests/test_pi_runner_serve_db.py)、自动评审和合并前的 CI,未记录数量、结论或本地完整套件结果。
**CI:**CI 在发布草稿后运行,其结果未在此记录。
**本次草稿未测试:**本地测试、本地完整套件、运行中的服务、浏览器运行、构建出的 wheel。发布文档 gate 只检查正文。