Repository navigation
Releases
Looper v2.14.176
Looper v2.14.176
This is the patch release v2.14.176, a hotfix line in which each merged change ships at once. It documents one change: #1326 (two maintainer decisions recorded in the plan; docs only).
Release Decision
Who should upgrade: No one needs to upgrade for this release. It changes a plan document only; the installed software behaves as in v2.14.175.
What this release solves: #1326 records two maintainer decisions in the long-horizon plan. It does not change code.
Breaking changes: No. There is no API, schema or behavior change. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.176Contributors: Maintainer @foolzzz authored #1326; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.175 upgrades directly. There is no database change.
Behavior changes
Read in the diff of #1326, which touches one file, the Chinese long-horizon plan (docs/plans/2026-10-13-long-horizon-agent-context.zh-CN.md):
- No behavior change. Only plan text changed.
- Plan entry: request recording for more runtimes. A new non-core todo for the Codex, OMP, Pi and DSH runtimes (CLI and runner), which are not covered by model request recording and show
not_coveredtoday. Recording them needs a local gateway or request proxy per runtime. The maintainer decided on 2026-11-12 to list it as a non-core todo, moved from #1144. - Plan entry: keeper default-on. The todo now also closes #1067 and names its checks before the default turns on: keeper runs surviving a restart under Linux systemd, and a real PostgreSQL cluster restart, run at least once on Linux systemd. The default stays
offuntil then. - Model-visible changes: None. Prompts, tool schemas and
channel_contextare unchanged.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1326 reports plan text only and that the two entries were read back. It does not report a local full suite or reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.176(热修线,每个合并的改动立即发布),说明一项改动:#1326(在计划中记录两项维护者决定,仅文档)。
升级决策
**谁需要升级:**无需为本版本升级。它只改动一份计划文档,已安装的软件行为与 v2.14.175 相同。
解决了什么:#1326 在长程计划中记录两项维护者决定,不改动代码。
**是否有破坏性变更:**无。没有 API、schema 或行为变化。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.176。
**贡献者:**维护者 @foolzzz 提交 #1326;本版本无社区贡献。
looper --version # looper 2.14.176升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.175 上的安装可直接升级。没有数据库变更。
行为变化与入口
以下在 #1326 的差异中可见,它只改动一个文件,即中文长程计划(docs/plans/2026-10-13-long-horizon-agent-context.zh-CN.md):
- **无行为变化。**只有计划文本改变。
- **计划条目:更多运行时的请求录制。**为 Codex、OMP、Pi、DSH 运行时(CLI 和 runner)新增非核心待办;它们目前不在模型请求录制范围内,界面显示
not_covered。要录制需为各自接上本地网关或请求代理。维护者于 2026-11-12 决定将其列为非核心待办,原记在 #1144。 - **计划条目:保留运行默认开启。**该待办现在同时关闭 #1067,并列出默认开启前的检查:Linux systemd 下重启后保留运行存活,以及真实 PostgreSQL 集群重启,至少在 Linux systemd 上真跑一次。在此之前默认保持
off。 - **面向模型的变化:**无。提示词、工具 schema 和
channel_context均未改变。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1326 报告仅为计划文本,并读回了两个条目。未报告本地完整套件或评审。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件和构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.175
Looper v2.14.175
This is the patch release v2.14.175, a hotfix line in which each merged change ships at once. It documents one change: #1318 (a Lark bound chat can be opened to everyone in it, and bots that @-mention the bot are answered).
Release Decision
Who should upgrade: Installations that use Lark channels with chat bindings and want a chat open to everyone in it, or want allowlisted bots to be answered. Others need not upgrade, but see Behavior changes: bot messages are no longer dropped.
What this release solves: #1318 adds a per-binding sender policy, removes the drop of bot senders and picks up bot @-mentions in bound group chats.
Breaking changes: No. There is no API removal; the only schema change is an additive column. Behavior changes on purpose (maintainer decision, see Behavior changes): messages from allowlisted bots now reach the Manager. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.175Contributors: Maintainer @foolzzz authored #1318; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.174 upgrades directly. The database gains the column manager_chat_bindings.sender_policy (listed or chat, default listed) on the first start; it is additive and existing bindings keep listed.
Behavior changes
Read in the code of #1318:
- Sender policy per binding (
looper/db/chat_bindings.py,looper/agents/channels/chat_routing.py).listed(default) admits the channel's allowlist and the binding's extra senders.chat(Lark only; Telegram is refused) admits everyone in that bound group chat, people and bots, except the channel's own bot. Direct messages always uselisted. Rebinding to another Manager resets the policy tolisted; omitting it on the same Manager keeps it. The binding API and its result carrysender_policy; an audit entry records a change of policy. - Bots are answered (
looper/agents/channels/lark.py). The drop of messages with a bot sender type is removed: a bot passes the same admission as a person. The channel's own messages are ignored (matched by the bot's open id and app id). Extra senders and the allowlist now also accept bot app ids (cli_…). Each bot message logs onelark_bot_messageline with its outcome; repeated refusals of the same bot in a chat are logged once per hour. - Bot @-mentions are polled. Bound group chats are listed every 30 s, including their threads, for messages from bots that @-mention the bot; each is handled once (duplicates are skipped). At most 10 bot-triggered turns per chat per hour are admitted; the rest are dropped with a warning. A poll that fails for a chat retries from the same boundary.
- Replies stay in threads. An answer, status or report to a message that is inside a thread is sent with the reply-in-thread flag (
--reply-in-threadfor the CLI transport,reply_in_threadfor the bot-token transport). - Confirmation for open chats (
looper/agents/http_server.py,looper/agents/v1_domains/chat_bindings.py,managers.py,managers_api.py). Settingchaton a binding whose Manager has all tools asks for a confirmation, also for an operator. Updating a Manager to all tools while chats are open to everyone asks for one too and lists those chats. The write is refused with a conflict if the Manager's permission revision, or the set of open chats, changed since the confirmation.looper confirmnow accepts the operator credential arguments. - Settings page. The chat bindings of a Manager gain a "Who can reach this Manager" selector and the confirmation step; the Manager editor gains the "Confirm all tools" step; the allowlist fields accept
cli_…ids and their help text says that a chat open to everyone is not limited to them. - Model-visible changes: Messages from bots now reach the Manager when admitted, and a message inside a thread now carries
thread_idin itschannel_context. Prompts and tool schemas are unchanged.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1318 reports the tests that cover the change (tests/test_lark_bot_intake.py, tests/test_lark_catchup.py, tests/test_lark_history_transport.py, tests/test_lark_content.py, tests/test_lark_rich_bot.py, tests/test_lark_transport.py, tests/test_lark_cli_commands.py, tests/test_api_v1_chat_bindings.py, tests/test_api_v1_chat_bindings_db.py, tests/test_channel_chat_routing_db.py, tests/test_manager_chat_bindings_browser.py and three web component and API tests), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, a real Lark group with a second bot and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.175(热修线,每个合并的改动立即发布),说明一项改动:#1318(Lark 绑定聊天可对群内所有人开放,并回应 @ 本 bot 的其他 bot)。
升级决策
**谁需要升级:**使用 Lark 渠道和聊天绑定、希望让某个聊天对其中所有人开放,或希望已列入允许名单的 bot 得到回应的安装。其他安装无需升级,但请注意行为变化:bot 的消息不再被丢弃。
解决了什么:#1318 为每个绑定增加发送者策略,移除对 bot 发送者的丢弃,并在已绑定的群聊中处理 @ 本 bot 的 bot 消息。
**是否有破坏性变更:**无。没有 API 被移除,唯一的 schema 变更是新增列。行为有意改变(维护者决定,见行为变化):已列入允许名单的 bot 的消息现在会到达 Manager。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.175。
**贡献者:**维护者 @foolzzz 提交 #1318;本版本无社区贡献。
looper --version # looper 2.14.175升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.174 上的安装可直接升级。数据库在首次启动时新增列 manager_chat_bindings.sender_policy(listed 或 chat,默认 listed);该变更是增量的,现有绑定保持 listed。
行为变化与入口
以下在 #1318 的代码中可见:
- 每个绑定的发送者策略(
looper/db/chat_bindings.py、looper/agents/channels/chat_routing.py)。listed(默认)允许渠道允许名单和该绑定的额外发送者。chat(仅 Lark;Telegram 会被拒绝)允许该已绑定群聊中的所有人(包括人和 bot),渠道自身的 bot 除外。私聊始终使用listed。改绑到其他 Manager 会把策略重置为listed;在同一 Manager 上省略该字段则保持不变。绑定 API 及其结果带有sender_policy;策略变更会写入审计记录。 - 回应 bot(
looper/agents/channels/lark.py)。移除了对 bot 发送者类型消息的丢弃:bot 与人走相同的准入。渠道自身的消息被忽略(按 bot 的 open id 和 app id 匹配)。额外发送者和允许名单现在也接受 bot 的 app id(cli_…)。每条 bot 消息记录一行带结果的lark_bot_message日志;同一聊天中对同一 bot 的重复拒绝每小时只记录一次。 - **轮询 bot 的 @ 提及。**已绑定的群聊每 30 秒列出一次(含其线程),查找 @ 本 bot 的 bot 消息;每条只处理一次(重复的会被跳过)。每个聊天每小时最多准入 10 个由 bot 触发的回合,其余带警告丢弃。某个聊天轮询失败时会从同一边界重试。
- **回复留在线程内。**对线程内消息的回答、状态或报告,会带上线程内回复标志发送(CLI 传输为
--reply-in-thread,bot-token 传输为reply_in_thread)。 - 开放聊天需要确认(
looper/agents/http_server.py、looper/agents/v1_domains/chat_bindings.py、managers.py、managers_api.py)。把其 Manager 拥有全部工具的绑定设为chat需要确认,操作员也不例外。在有聊天对所有人开放时把 Manager 更新为全部工具同样需要确认,并列出这些聊天。如果自确认以来 Manager 的权限版本或开放聊天的集合发生变化,写入会以冲突被拒绝。looper confirm现在接受操作员凭据参数。 - **设置页。**Manager 的聊天绑定新增“Who can reach this Manager”选择器和确认步骤;Manager 编辑器新增“Confirm all tools”步骤;允许名单字段接受
cli_…,其帮助文字说明对所有人开放的聊天不受其限制。 - **面向模型的变化:**被准入的 bot 消息现在会到达 Manager,线程内的消息现在在
channel_context中带有thread_id。提示词和工具 schema 未改变。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1318 报告了覆盖该改动的测试(tests/test_lark_bot_intake.py、tests/test_lark_catchup.py、tests/test_lark_history_transport.py、tests/test_lark_content.py、tests/test_lark_rich_bot.py、tests/test_lark_transport.py、tests/test_lark_cli_commands.py、tests/test_api_v1_chat_bindings.py、tests/test_api_v1_chat_bindings_db.py、tests/test_channel_chat_routing_db.py、tests/test_manager_chat_bindings_browser.py 和三个 web 组件与 API 测试)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、带第二个 bot 的真实 Lark 群以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.174
Looper v2.14.174
This is the patch release v2.14.174, a hotfix line in which each merged change ships at once. It documents one change: #1321 (Lark catch-up reads a bounded set of threads).
Release Decision
Who should upgrade: Installations that use the Lark CLI channel in busy group chats or topics, where startup catch-up could fail the chat every time. Others need not upgrade.
What this release solves: #1321 (fixes #1315) bounds the thread discovery of Lark startup catch-up and stops one failing thread from failing its chat.
Breaking changes: No. There is no schema or API change. Behavior narrows on purpose (maintainer decision, see Behavior changes): catch-up no longer recovers old threads in which this channel was not active. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.174Contributors: Maintainer @foolzzz authored #1321; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.173 upgrades directly. There is no database migration; the Lark channel's local inbox file creates its new thread_activity table on the first start (CREATE TABLE IF NOT EXISTS).
Behavior changes
Read in the code of #1321:
- Bounded thread discovery (
looper/agents/channels/lark.py). For each chat, catch-up scans roots newest first and stops at the first root older than 24 hours (up to 5 pages of 50). Candidates also include threads this channel handled or sent a message in during the last 7 days. These come first. At most 50 distinct threads per chat are listed, 4 at a time. Dropped threads logthreads_skipped. Reaching the root page cap logs an INFO count and completes the chat's window. Replies inside chat-level pages are no longer followed into threads one by one; threads come from the candidate set. - A thread failure no longer fails the chat. A failed thread listing logs its id and counts
thread_failures; pages already read are still admitted, oldest first, and the chat's window is completed. A failed root discovery or chat listing still counts as a failure of the chat and leaves its window unfinished. - Stricter age check. A recovered message older than the recovery start is counted as too old (before, it was skipped silently). The first old reply that stops a thread listing is counted too. The
lark_catchupINFO summary gainsthreads_scanned,thread_failuresandthread_roots_capped. - Thread activity is remembered (
looper/agents/channels/lark_inbox.py,looper/agents/channels/lark_transport.py). A handled message with a thread id, and a send or reply by this channel into a thread, store(chat, thread, time)in the channel's local inbox, pruned after 7 days and capped at 1,000 entries. When a send's CLI output lacks the thread id or chat id, the transport makes one extraGETof the sent message as the bot to read them; a failure there only logs a warning and never retries the send. History events now carrythread_id. - Internal.
list_threadsreturnsroots(with times) instead ofthreads; the p2p case returns no roots.docs/architecture/agent-system.mddescribes the rule. The bot-token channel is unchanged. - Model-visible changes: None. Prompts, tool schemas and the Manager's tools are unchanged; the only effect is that recovered thread messages reach the Manager as before, but from the bounded set.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1321 reports the tests that cover the change (tests/test_lark_catchup.py, tests/test_lark_history_transport.py, tests/test_lark_transport.py, tests/test_lark_cli_commands.py), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, a real Lark catch-up against a busy chat and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.174(热修线,每个合并的改动立即发布),说明一项改动:#1321(Lark 追补只读取有界的线程集合)。
升级决策
**谁需要升级:**在繁忙的群聊或话题中使用 Lark CLI 渠道、启动追补每次都会失败的安装。其他安装无需升级。
解决了什么:#1321(修复 #1315)为 Lark 启动追补的线程发现设置上限,并且单个线程失败不再导致整个聊天失败。
**是否有破坏性变更:**无。没有 schema 或 API 变更。行为有意收窄(维护者决定,见行为变化):追补不再恢复本渠道未参与过的旧线程。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.174。
**贡献者:**维护者 @foolzzz 提交 #1321;本版本无社区贡献。
looper --version # looper 2.14.174升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.173 上的安装可直接升级。没有数据库迁移;Lark 渠道的本地 inbox 文件会在首次启动时创建新的 thread_activity 表(CREATE TABLE IF NOT EXISTS)。
行为变化与入口
以下在 #1321 的代码中可见:
- 有界的线程发现(
looper/agents/channels/lark.py)。每个聊天按从新到旧扫描根消息,遇到第一条早于 24 小时的根即停止(最多 5 页、每页 50 条)。候选还包括本渠道在最近 7 天内处理过或发送过消息的线程,并排在前面。每个聊天最多列出 50 个不同的线程,同时最多 4 个在读取。被舍弃的线程记录threads_skipped。达到根页数上限时记录 INFO 计数并完成该聊天的窗口。聊天页内的回复不再逐条追入线程,线程来自候选集合。 - **线程失败不再使聊天失败。**线程列表失败时记录其 id 并计入
thread_failures;已读取的页仍按线程内从旧到新的顺序处理,聊天窗口照常完成。根发现失败或聊天自身的列表失败仍算该聊天的失败,其窗口保持未完成。 - **更严格的时间检查。**早于恢复起点的消息现在计为 too-old(原先静默跳过);使线程列表停止的第一条旧回复也会计入。启动时的
lark_catchupINFO 摘要新增threads_scanned、thread_failures和thread_roots_capped。 - 记住线程活动(
looper/agents/channels/lark_inbox.py、looper/agents/channels/lark_transport.py)。已处理且带线程 id 的消息,以及本渠道在线程中的发送或回复,会把(聊天、线程、时间)存入渠道本地 inbox,7 天后清理,上限 1,000 条。当发送的 CLI 输出缺少线程 id 或聊天 id 时,传输层会额外以 bot 身份GET一次已发送的消息来读取;该步骤失败只记警告,不会重试发送。历史事件现在携带thread_id。 - 内部。
list_threads返回带时间的roots,不再返回threads;p2p 返回空。docs/architecture/agent-system.md描述了该规则。bot-token 渠道不变。 - **面向模型的变化:**无。提示词、工具 schema 和 Manager 的工具均未改变;恢复的线程消息照旧送达 Manager,只是来自有界集合。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1321 报告了覆盖该改动的测试(tests/test_lark_catchup.py、tests/test_lark_history_transport.py、tests/test_lark_transport.py、tests/test_lark_cli_commands.py)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、针对繁忙聊天的真实 Lark 追补以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.173
Looper v2.14.173
This is the patch release v2.14.173, a hotfix line in which each merged change ships at once. It documents one change: #1312 (model names may carry one bracketed parameter list).
Release Decision
Who should upgrade: Installations that want a model name with parameters, such as Cursor's grok-4.7[context=500k,reasoning_effort=high,fast=true], in the model catalog or an Agent Profile. Others need not upgrade for behavior, but see the narrowing below.
What this release solves: #1312 makes one shared rule decide what a model name is, and the rule accepts one trailing bracket list of key=value items. The complete name reaches the runtime as one command-line argument.
Breaking changes: No. Saved data keeps working, but new input is checked by a narrower rule (see Behavior changes). Names accepted before the release by the old rule but refused now are: brackets in the middle of a name, more than one bracket group, and surrounding whitespace. Saved rows are not rewritten or rejected. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.173Contributors: Maintainer @foolzzz authored #1312; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.172 upgrades directly. The first start replaces the checks on llm_models.name and llm_models.background_model with the new grammar (looper/db/connection.py, recorded as the migration model_name_parameters). The new checks are added NOT VALID, so rows that the old rule accepted stay; a check is validated at once when every row fits, and a fresh database has it validated from the start. New inserts and updates always enforce the new grammar.
Behavior changes
Read in the code of #1312:
- One shared grammar (
looper/agents/model_names.py,looper/agents/agent_settings.py). A name is a base id (a letter or digit first, then letters, digits,.,_,:,/,-), optionally followed by one bracket group: either a legacy token such as[1m], or comma-separatedkey=valueitems whose keys and values use letters, digits,.,_and-. The limit is 200 characters. The settings validator and the SQL checks use the same pattern, which also requires the true end of input, so a trailing newline is refused. - Narrower than the old rule. The old rule allowed
[and]anywhere after the first character and trimmed surrounding whitespace.model_namenow takes the string exactly: a name with whitespace around it, a bracket inside the base id, or two bracket groups is refused. An empty string for a profile's model is now refused as "not a model name" (it was "an Agent Profile needs a model" before); an emptybackground_modelstill means none. - Parameter lists are identities.
parse_model_namesplits only a legacy context suffix; a name with akey=valuelist stays whole and is never split into a base and a suffix.opus[1m]keeps working as before. Cursor runs use temporary configuration directories, so saved CursormodelParametersare not loaded; put the parameters in the name instead. - Database (
looper/db/schema.sql,looper/db/connection.py). See Upgrading.schema_change_pendingreports the migration as pending until it is recorded. - API and schemas (
looper/agents/v1_domains/models.py,looper/agents/v1_domains/registry.py). The v1 model entries and the model result'snameuse the shared pattern and length limit. - Docs (
docs/architecture/agent-system.md) describe the rule. - Model-visible changes: The Manager's model tools (
looper/agents/ops/config.py) declarename(create), thenameinside a model reference, andbackground_modelwith the shared pattern and a 200-character limit instead of a bare string; a name with a parameter list is now accepted there. Prompts are otherwise unchanged.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1312 reports the tests that cover the change (tests/test_agent_settings.py, tests/test_api_v1_models.py, tests/test_api_v1_models_db.py, tests/test_cursor_agent.py, tests/test_llm_model_schema_db.py, tests/test_model_listing.py, tests/test_model_names.py), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, a real Cursor run with a parameter list and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.173(热修线,每个合并的改动立即发布),说明一项改动:#1312(模型名可带一个方括号参数列表)。
升级决策
**谁需要升级:**希望在模型目录或 Agent Profile 中使用带参数的模型名(如 Cursor 的 grok-4.7[context=500k,reasoning_effort=high,fast=true])的安装。其他安装没有行为上的升级需求,但请留意下文的收窄。
解决了什么:#1312 由同一条规则判定什么是模型名,该规则接受末尾一个由 key=value 组成的方括号列表。完整名称作为一个命令行参数交给运行时。
**是否有破坏性变更:**无。已保存的数据照常可用,但新输入由更窄的规则检查(见行为变化)。旧规则接受、现在拒绝的是:名称中间的方括号、多于一组方括号、以及首尾空白。已保存的行不会被改写或拒绝。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.173。
**贡献者:**维护者 @foolzzz 提交 #1312;本版本无社区贡献。
looper --version # looper 2.14.173升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.172 上的安装可直接升级。首次启动会把 llm_models.name 和 llm_models.background_model 的检查约束替换为新规则(looper/db/connection.py,迁移名 model_name_parameters)。新约束以 NOT VALID 添加,旧规则接受的已有行得以保留;所有行都符合时立即校验,全新数据库从一开始就是已校验的。之后的插入和更新始终执行新规则。
行为变化与入口
以下在 #1312 的代码中可见:
- 统一的语法(
looper/agents/model_names.py、looper/agents/agent_settings.py)。名称由基础 id(首字符为字母或数字,其后为字母、数字、.、_、:、/、-)加可选的一组方括号构成:要么是[1m]这样的旧式标记,要么是以逗号分隔的key=value项,键和值只用字母、数字、.、_、-。长度上限 200 字符。设置校验与 SQL 约束使用同一个模式,并要求真正的输入结尾,因此末尾换行会被拒绝。 - **比旧规则更窄。**旧规则允许首字符之后任意位置出现
[和],并会去掉首尾空白。现在model_name原样接收字符串:首尾有空白、基础 id 内含方括号、或有两组方括号的名称会被拒绝。Profile 的模型为空字符串时,现在报「不是模型名」(原为「Agent Profile 需要模型」);空的background_model仍表示没有。 - 参数列表即身份。
parse_model_name只拆分旧式上下文后缀;带key=value列表的名称保持完整,不会拆成基础名和后缀。opus[1m]行为不变。Cursor 运行使用临时配置目录,因此不会加载已保存的 CursormodelParameters;请把参数写进名称。 - 数据库(
looper/db/schema.sql、looper/db/connection.py)。见升级。迁移记录之前,schema_change_pending报告其待执行。 - API 与 schema(
looper/agents/v1_domains/models.py、looper/agents/v1_domains/registry.py)。v1 的模型条目与模型结果中的name使用统一的模式和长度上限。 - 文档(
docs/architecture/agent-system.md)说明了该规则。 - **面向模型的变化:**Manager 的模型工具(
looper/agents/ops/config.py)的name(创建)、模型引用中的name和background_model改为声明统一的模式和 200 字符上限,不再是裸字符串;带参数列表的名称现在被接受。提示词其余部分不变。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1312 报告了覆盖该改动的测试(tests/test_agent_settings.py、tests/test_api_v1_models.py、tests/test_api_v1_models_db.py、tests/test_cursor_agent.py、tests/test_llm_model_schema_db.py、tests/test_model_listing.py、tests/test_model_names.py)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、带参数列表的真实 Cursor 运行以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.172
Looper v2.14.172
This is the patch release v2.14.172, a hotfix line in which each merged change ships at once. It documents one change: #1313 (Grok runs can turn off web search per Agent Profile).
Release Decision
Who should upgrade: Installations that run Grok and want an Agent Profile whose runs have no web search or web fetch tools. Others need not upgrade for behavior.
What this release solves: #1313 adds a web_search setting to Agent Profiles. It defaults to true, which keeps today's behavior; false adds --disable-web-search to Grok runs, and other runtimes refuse it.
Breaking changes: No. The new setting is an opt-in switch and every existing profile keeps web_search: true. The database gains one additive column, added on the next start (see Upgrading). The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.172Contributors: Maintainer @foolzzz authored #1313; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.171 upgrades directly. The first start adds the column agent_profiles.web_search BOOLEAN NOT NULL DEFAULT true (looper/db/connection.py, recorded as the migration profile_web_search); existing rows read true.
Behavior changes
Read in the code of #1313:
- New profile setting (
looper/agents/profile_registry.py,looper/db/profile_registry.py,looper/db/schema.sql). Agent Profiles carryweb_search, defaulttrue. It can be set on create and update, is part of the profile's view and list, and is validated: a non-boolean is refused, andfalseis refused with a message for any runtime whose type is notgrok. - Grok commands (
looper/agents/runtimes/grok.py,grok_acp.py). Withweb_search: false, headless and ACP Grok commands add--disable-web-search, which removes Grok's web search and web fetch tools. It is not a network sandbox: shell commands can still reach the network. The run'smetadata.commandrecords the flag. A fallback uses the target profile's own setting, and the setting is part of the profile's settings fingerprint (agent_settings.py). - Config export and import (
looper/agents/config_transfer.py,looper/db/config_transfer.py). The v3 config carriesweb_searchper profile; an entry without it imports astrue, and a changed value counts as a change when comparing with the current profile. - API and dashboard (
looper/agents/v1_domains/*,web/src/components/agent-profiles.tsx). The v1 profile schemas accept and returnweb_search. The Agent Profiles form shows a "Web search" switch only for Grok runtimes, with a hint that shell commands can still reach the network; the list marks a profile "web search off". Switching to a non-Grok runtime resets it to on. - Model-visible changes: The Manager's profile tool (
looper/agents/ops/config.py) gains a booleanweb_searchargument for create and update, described as "Default true. Only Grok supports false; false disables web search and web fetch tools", and its profile list output includesweb_search. A Grok run on a profile withweb_search: falsehas no web search or web fetch tools. Prompts are otherwise unchanged, and nothing changes for profiles left at the default.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1313 reports the tests that cover the change (tests/test_api_v1_profiles.py, tests/test_api_v1_profiles_db.py, tests/test_config_v3_export_db.py, tests/test_config_v3_import_db.py, tests/test_profile_web_search_schema_db.py, tests/test_grok_runtime.py, tests/test_grok_acp.py, tests/test_grok_worker_launch.py, tests/test_worker_profile_fallback.py, web/src/components/agent-profiles.test.tsx, web/src/lib/api-profiles.test.ts), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, a real Grok run with the flag and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.172(热修线,每个合并的改动立即发布),说明一项改动:#1313(Grok 运行可按 Agent Profile 关闭网页搜索)。
升级决策
**谁需要升级:**运行 Grok、并希望某个 Agent Profile 的运行没有网页搜索和网页抓取工具的安装。其他安装没有行为上的升级需求。
解决了什么:#1313 为 Agent Profile 增加 web_search 设置,默认 true,行为不变;false 会给 Grok 运行加上 --disable-web-search,其他运行时拒绝该值。
**是否有破坏性变更:**否。新设置是可选开关,现有 profile 都保持 web_search: true。数据库增加一个向后兼容的新列,下次启动时添加(见升级)。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.172。
**贡献者:**维护者 @foolzzz 提交 #1313;本版本无社区贡献。
looper --version # looper 2.14.172升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.171 上的安装可直接升级。首次启动会添加列 agent_profiles.web_search BOOLEAN NOT NULL DEFAULT true(looper/db/connection.py,迁移名 profile_web_search),已有行读取为 true。
行为变化与入口
以下在 #1313 的代码中可见:
- 新的 profile 设置(
looper/agents/profile_registry.py、looper/db/profile_registry.py、looper/db/schema.sql)。Agent Profile 带有web_search,默认true。创建和更新时可设置,出现在 profile 的详情和列表中,并受校验:非布尔值被拒绝;运行时类型不是grok时false被拒绝并给出提示。 - Grok 命令(
looper/agents/runtimes/grok.py、grok_acp.py)。web_search: false时,headless 和 ACP 的 Grok 命令加上--disable-web-search,移除 Grok 的网页搜索和网页抓取工具。它不是网络沙箱:shell 命令仍可访问网络。运行的metadata.command记录该参数。回退使用目标 profile 自己的设置,该设置也是 profile 设置指纹的一部分(agent_settings.py)。 - 配置导出与导入(
looper/agents/config_transfer.py、looper/db/config_transfer.py)。v3 配置按 profile 携带web_search;缺少该字段的条目按true导入,值变化在与当前 profile 比较时算作变更。 - API 与面板(
looper/agents/v1_domains/*、web/src/components/agent-profiles.tsx)。v1 的 profile 结构接受并返回web_search。Agent Profiles 表单仅对 Grok 运行时显示「Web search」开关,并提示 shell 命令仍可访问网络;列表会标出「web search off」。切换到非 Grok 运行时会重置为开启。 - **面向模型的变化:**Manager 的 profile 工具(
looper/agents/ops/config.py)在创建和更新时多了布尔参数web_search,描述为「Default true. Only Grok supports false; false disables web search and web fetch tools」,其 profile 列表输出也包含web_search。web_search: false的 profile 上的 Grok 运行没有网页搜索和网页抓取工具。提示词其余部分不变,保持默认值的 profile 不受影响。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1313 报告了覆盖该改动的测试(tests/test_api_v1_profiles.py、tests/test_api_v1_profiles_db.py、tests/test_config_v3_export_db.py、tests/test_config_v3_import_db.py、tests/test_profile_web_search_schema_db.py、tests/test_grok_runtime.py、tests/test_grok_acp.py、tests/test_grok_worker_launch.py、tests/test_worker_profile_fallback.py、web/src/components/agent-profiles.test.tsx、web/src/lib/api-profiles.test.ts)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、带该参数的真实 Grok 运行以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.171
Looper v2.14.171
This is the patch release v2.14.171, a hotfix line in which each merged change ships at once. It documents one change: #1314 (Manager: a slow stop of the old session does not fail the user's message).
Release Decision
Who should upgrade: Installations whose Manager runs a resident Claude session and whose user messages failed or stalled when the old or stale session was slow to stop. Others need not upgrade for behavior.
What this release solves: #1314 stops an idle stale or replaced resident session with a kill and waits only for its main process, so a slow stop no longer fails the user's message; a turn that fails before the model received the message is retried once.
Breaking changes: No. There is no migration or database schema change. The Manager's turn start behaves differently as described below, which the pull request calls an intended maintainer decision. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.171Contributors: Maintainer @foolzzz authored #1314; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.170 upgrades directly. There is no database schema change.
Behavior changes
Read in the code of #1314:
- Stopping the old session (
looper/agents/tiers/manager.py,looper/agents/claude_cli.py). When a turn starts and the resident session is stale or belongs to a replaced runtime, the Manager now stops it withstop(kill=True, wait_tree=False)(new_stop_replaced_session). That kills the main process and waits only until its exit is seen; the cleanup of its descendant processes continues in the background and is joined by a later default stop. The step's budget (claude_stop) rises from 10 s to 30 s.wait_tree=Falsewithoutkill=TrueraisesValueError. A kill also skips the stdin-close grace for the stop. Other runtime types that do not useResidentClaudestill get a plainstop(kill=True). - No resume beside a leftover process (
claude_cli.py). While a background-cleaned main process has not exited,stale()stays true, so a replacement does not resume next to its old main process. A user turn waits for tracked cleanup except the background ones. - One retry before delivery (
manager.py,looper/agents/tiers/turn_token.py). If a turn fails with a timeout,OSErrororTurnFailedin theclaude_stop,switch_sessionorclaude_startstep, the Manager waits 5 s and tries once more. It reuses the already admitted message and lock (TurnToken.prepared_ask) and a fresh run state. There is no retry when the message was already sent to the model, the turn was cancelled, a hosted runner'sclaude_startfailed (hosted runners own their startup recovery), a later step failed, or this was already the second attempt; the error then surfaces as before. - Model-visible changes: None to prompts or tool descriptions. The retry happens before the message reaches the model, so the model sees the message once.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1314 reports the tests that cover the change (tests/test_manager_startup_recovery.py, tests/test_manager_stop.py, tests/test_manager_stop_faults.py, tests/test_claude_cli.py), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, a real Manager session restart and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.171(热修线,每个合并的改动立即发布),说明一项改动:#1314(Manager:旧会话停得慢,不再让用户消息失败)。
升级决策
**谁需要升级:**Manager 使用常驻 Claude 会话,且用户消息曾因旧会话或过期会话停止缓慢而失败或卡住的安装。其他安装没有行为上的升级需求。
解决了什么:#1314 对空闲的过期或被替换的常驻会话用 kill 停止,只等待其主进程退出,慢停不再让用户消息失败;消息送达模型之前失败的轮次会重试一次。
**是否有破坏性变更:**否。没有迁移或数据库结构变更。Manager 的轮次启动行为按下文所述改变,PR 称这是维护者有意的决定。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.171。
**贡献者:**维护者 @foolzzz 提交 #1314;本版本无社区贡献。
looper --version # looper 2.14.171升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.170 上的安装可直接升级。数据库没有结构变更。
行为变化与入口
以下在 #1314 的代码中可见:
- 停止旧会话(
looper/agents/tiers/manager.py、looper/agents/claude_cli.py)。轮次开始时,若常驻会话已过期或所属运行时被替换,Manager 现在用stop(kill=True, wait_tree=False)(新增_stop_replaced_session)停止它:杀死主进程,只等到看见其退出;后代进程的清理在后台继续,之后的默认 stop 会等待它。claude_stop步骤的时限由 10 秒升到 30 秒。wait_tree=False而不带kill=True会抛ValueError。kill 同时跳过 stdin 关闭的宽限。不使用ResidentClaude的其他运行时仍用普通的stop(kill=True)。 - 旧进程未退出时不恢复(
claude_cli.py)。后台清理中的主进程尚未退出时,stale()保持为真,替换的会话不会与旧主进程并存地恢复。用户轮次会等待被跟踪的清理,后台清理的除外。 - 送达前重试一次(
manager.py、looper/agents/tiers/turn_token.py)。轮次在claude_stop、switch_session或claude_start步骤以超时、OSError或TurnFailed失败时,Manager 等 5 秒后重试一次,复用已受理的消息和锁(TurnToken.prepared_ask)以及新的运行状态。消息已发给模型、轮次已取消、托管运行器的claude_start失败(托管运行器自己负责启动恢复)、失败发生在其他步骤或这已是第二次尝试时不重试,错误照旧抛出。 - **面向模型的变化:**提示词和工具描述无变化。重试发生在消息到达模型之前,模型只会看到该消息一次。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1314 报告了覆盖该改动的测试(tests/test_manager_startup_recovery.py、tests/test_manager_stop.py、tests/test_manager_stop_faults.py、tests/test_claude_cli.py)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、真实的 Manager 会话重启以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.170
Looper v2.14.170
This is the patch release v2.14.170, a hotfix line in which each merged change ships at once. It documents one change: #1311 (Dashboard home: how many agents run now, and which task and project each belongs to).
Release Decision
Who should upgrade: Installations that use the web dashboard home page and want to see how many agents run and which task each belongs to. Others need not upgrade for behavior.
What this release solves: #1311 makes the dashboard's "Agents running now" section show a total and the project and task of each agent.
Breaking changes: No. There is no migration or database schema change. The section's layout changes as described below, which the pull request calls an intended maintainer decision. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.170Contributors: Maintainer @foolzzz authored #1311; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.169 upgrades directly. There is no database schema change.
Behavior changes
Read in the code of #1311:
- Total (
web/src/pages/dashboard.tsx). The "Agents running now" section header shows the number running: busy Managers, Planners and running Workers and Reviewers. Workers and Reviewers waiting for room under their task's limit are counted separately aswaiting. Worker and Reviewer rows readN running, with· M waitingwhen there are waiting runs. - Every Manager (
dashboard.tsx,looper/agents/overview.py). The Managers row lists every fleet Manager that is not stopped, by name with its state (busy shows a spinner), and counts the busy ones. With a single Manager the row is still titled "Manager"; with none it says "None". Against an older server that does not send the list, the single known Manager is shown as before. The overview's Manager state now readsfleet.is_running(agent_id)instead of the fleet state'srunningfield; the resulting busy, idle or stopped values are meant to be the same. - Project and task per agent (
dashboard.tsx). Planner, Worker and Reviewer lines showproject · task name, linking to the task page; long names are truncated with the full text in the tooltip. Under it a Worker or Reviewer line shows the first line of its instruction (or its step or agent ID), and a Planner line shows the first line of its requirement, orplanningwhen the task has no separate name. These lines still link to the agent's history. - API (
looper/agents/overview.py,looper/agents/v1_domains/task_controls.py,looper/db/tasks.py). Each step run in the overview gains a requiredtask_name, the task's current name (the task ID when the task is gone). It is read together with the task's current project in one query (names_and_projects_of, replacing the project-only lookup there). The overview schema lists the new field; clients that ignore unknown fields are unaffected. - Model-visible changes: None. Prompts and tool descriptions are unchanged; the change is to the dashboard and the overview API response.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1311 reports the tests that cover the change (tests/test_overview.py, tests/test_overview_db.py and the dashboard page test), automated reviews, and CI before the merge. It does not report a local full suite or the result of the reviews.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, the dashboard in a browser and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.170(热修线,每个合并的改动立即发布),说明一项改动:#1311(看板首页:显示当前有多少 agent 在运行,以及各自属于哪个任务和项目)。
升级决策
**谁需要升级:**使用网页看板首页、希望看到运行中 agent 数量及其所属任务的安装。其他安装没有行为上的升级需求。
解决了什么:#1311 让看板的"Agents running now"区块显示总数,以及每个 agent 的项目和任务。
**是否有破坏性变更:**否。没有迁移或数据库结构变更。区块布局按下文所述改变,PR 称这是维护者有意的决定。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.170。
**贡献者:**维护者 @foolzzz 提交 #1311;本版本无社区贡献。
looper --version # looper 2.14.170升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.169 上的安装可直接升级。数据库没有结构变更。
行为变化与入口
以下在 #1311 的代码中可见:
- 总数(
web/src/pages/dashboard.tsx)。区块标题显示运行数量:忙碌的 Manager、Planner 以及正在运行的 Worker 和 Reviewer。因任务并发上限而等待的 Worker 和 Reviewer 单独计为waiting。Worker 与 Reviewer 行显示N running,有等待时追加· M waiting。 - 列出所有 Manager(
dashboard.tsx、looper/agents/overview.py)。Managers 行列出所有未停止的 fleet Manager,显示名称和状态(忙碌时有转圈图标),并统计忙碌数。只有一个 Manager 时标题仍为 "Manager",没有时显示 "None"。对不返回该列表的旧服务端,仍显示原来的单个 Manager。概览中 Manager 的状态改为读取fleet.is_running(agent_id),而不是 fleet 状态的running字段,得到的 busy、idle、stopped 取值应保持一致。 - 每个 agent 的项目与任务(
dashboard.tsx)。Planner、Worker、Reviewer 行显示项目 · 任务名,链接到任务页;过长名称会截断,完整文本在提示中。其下,Worker 或 Reviewer 行显示指令第一行(或步骤、agent ID),Planner 行显示需求第一行,任务没有单独名称时显示planning。这些行仍链接到 agent 历史。 - API(
looper/agents/overview.py、looper/agents/v1_domains/task_controls.py、looper/db/tasks.py)。概览中的每个步骤运行新增必填字段task_name,为任务当前名称(任务已不存在时为任务 ID),与任务当前项目在一次查询中读取(names_and_projects_of,替换此处仅查项目的查询)。概览 schema 已列出该字段;忽略未知字段的客户端不受影响。 - **面向模型的变化:**无。提示词和工具描述不变;变化只在看板和概览 API 响应。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1311 报告了覆盖该改动的测试(tests/test_overview.py、tests/test_overview_db.py 和看板页面测试)、自动评审,以及合并前的 CI。未报告本地完整套件,也未报告评审结果。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、浏览器中的看板以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.169
Looper v2.14.169
This is the patch release v2.14.169, a hotfix line in which each merged change ships at once. It documents one change: #1310 (Recover Lark messages sent during service restarts).
Release Decision
Who should upgrade: Installations that run the lark-cli Lark channel and restart the service while users may be sending messages. Others need not upgrade for behavior.
What this release solves: #1310 answers eligible Lark messages sent while the service restarts, which the long connection does not replay.
Breaking changes: No. There is no migration or database schema change. The channel adds a small local state file per Lark channel in the runtime root. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.169Contributors: Maintainer @foolzzz authored #1310; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.168 upgrades directly. There is no database schema change.
Behavior changes
Read in the code of #1310:
- Restart state (
looper/agents/channels/lark_inbox.py,lark.py). Eachlark-clichannel keeps a SQLite file.local/lark/<channel>/inbox.sqlite3under the runtime root with a restart boundary, the latest 20,000 handled message IDs (no message content), and unfinished recovery windows. While the consumer is ready and no message is being handled, the boundary is saved every five seconds; a clean stop saves its stop time, and an interrupted handler or disconnected consumer keeps the earlier boundary. A missing boundary starts without replaying history. - Catch-up after start (
looper/agents/channels/lark.py,lark_transport.py,lark_cli.py). After the consumer reports readiness (thereadymarker, or its first live message; a 60 second wait otherwise ends with a warning), a background task lists raw chat history throughlark-cli api GET /open-apis/im/v1/messages --as bot, from the saved boundary minus 10 seconds. A boundary older than 15 minutes skips the whole window, and a recovered message older than 15 minutes is skipped. Threads are read too: embedded replies, and a separate root scan for groups and topics. - Which chats (
looper/db/chat_bindings.py). Chats with an explicit binding first, then, when the default Manager accepts unbound chats, chats observed in the last 24 hours; at most 100 chats, 5 pages per chat, 50 messages per page. A page limit reached or a failed listing warns and keeps that chat's window for the next start (dropped once older than 15 minutes). - Admission and deduplication (
lark.py). Recovered messages go through the same handler as live ones (admission, group bot-mention check, routing, attachments, disabled chats). Live and recovered input share a lock and the durable receipts, so a message is handled once. A failed chat or message does not block other chats or live input. Each start logs onelark_catchupINFO summary. - Limits. P2P chats are recovered only when the bot can resolve the chat mode and read its history; otherwise a warning is logged and the chat is skipped. A never-observed unbound chat cannot be discovered during downtime. An expired window is not listed, so its message count is unknown. The bot needs history and chat-info read permissions; there is no user-identity fallback. The bot-token Lark transport is unchanged, and messages sent to it during a restart can still be lost.
- Model-visible changes: None to prompts or tool descriptions. A Manager can receive a message later than it was sent, as the same input it would have received live.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1310 reports targeted tests passing (recovery and history transport, attachment failure variants, the schema upgrade case, catch-up candidate discovery, and a combined run of 18), an isolated real looper serve run with channels disabled and no real Lark traffic, and an independent read-only review with no blocking defects. A broader run was interrupted after seven failures; six timing or setup cases passed on rerun, and a foreign-key assertion that also fails on the original main test with the local PostgreSQL 18 (it expects ForeignKeyViolationError, the database reports RestrictViolationError) is outside the change. The pull request does not report a clean full suite, nor real Lark permissions or P2P access.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite, real Lark traffic and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.169(热修线,每个合并的改动立即发布),说明一项改动:#1310(恢复服务重启期间发送的 Lark 消息)。
升级决策
**谁需要升级:**运行 lark-cli Lark 渠道、且重启服务时可能有用户发消息的安装。其他安装没有行为上的升级需求。
解决了什么:#1310 在服务重启后回复重启期间发送的符合条件的 Lark 消息,这些消息长连接不会重放。
**是否有破坏性变更:**否。没有迁移或数据库结构变更。每个 Lark 渠道在运行时根目录下新增一个小的本地状态文件。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.169。
**贡献者:**维护者 @foolzzz 提交 #1310;本版本无社区贡献。
looper --version # looper 2.14.169升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.168 上的安装可直接升级。数据库没有结构变更。
行为变化与入口
以下在 #1310 的代码中可见:
- 重启状态(
looper/agents/channels/lark_inbox.py、lark.py)。每个lark-cli渠道在运行时根目录的.local/lark/<channel>/inbox.sqlite3保存重启边界、最近 20,000 个已处理消息 ID(不含消息内容)以及未完成的恢复窗口。消费者就绪且没有消息在处理时,每五秒保存一次边界;正常停止会保存停止时间,处理被打断或消费者断开则保留更早的边界。边界缺失时不回放历史。 - 启动后追补(
lark.py、lark_transport.py、lark_cli.py)。消费者报告就绪后(ready标记或首条实时消息;否则等待 60 秒后警告),后台任务通过lark-cli api GET /open-apis/im/v1/messages --as bot列出原始聊天历史,从保存的边界减 10 秒开始。边界早于 15 分钟则整个窗口跳过,早于 15 分钟的单条消息也跳过。话题线程同样会读取:内嵌回复,以及对群和话题的独立根消息扫描。 - 哪些聊天(
looper/db/chat_bindings.py)。先是有显式绑定的聊天,然后在默认 Manager 接受未绑定聊天时,加上最近 24 小时内观察到的聊天;最多 100 个聊天,每个聊天 5 页,每页 50 条。达到页数上限或列表失败会警告,并保留该聊天的窗口到下次启动(超过 15 分钟后丢弃)。 - 准入与去重(
lark.py)。恢复的消息走与实时消息相同的处理流程(准入、群内 @ 机器人检查、路由、附件、停用聊天)。实时与恢复输入共用锁和持久化回执,每条消息只处理一次。单个聊天或消息失败不会阻塞其他聊天或实时输入。每次启动记录一条lark_catchupINFO 摘要。 - **限制。**仅当机器人能解析聊天模式并读取历史时才恢复 P2P 聊天,否则记录警告并跳过。从未观察到的未绑定聊天无法在停机期间被发现。过期窗口不会被列出,因此其消息数未知。机器人需要历史与聊天信息读取权限,没有用户身份回退。bot-token 的 Lark 传输不变,发送给它的消息在重启期间仍可能丢失。
- **面向模型的变化:**提示词和工具描述没有变化。Manager 可能比发送时间更晚收到消息,其内容与实时收到的相同。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1310 报告了通过的定向测试(恢复与历史传输、附件失败变体、schema 升级用例、追补候选发现,以及合并运行的 18 个用例)、在禁用渠道且不发送真实 Lark 流量下的隔离 looper serve 运行,以及无阻塞缺陷的独立只读评审。更大范围的运行在七个失败后被中断;其中六个时序或准备问题重跑通过,另有一个外键断言在原 main 测试上、本地 PostgreSQL 18 下同样失败(期望 ForeignKeyViolationError,数据库返回 RestrictViolationError),与本改动无关。PR 未报告完整套件的干净通过,也未验证真实 Lark 权限或 P2P 访问。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件、真实 Lark 流量以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.168
Looper v2.14.168
This is the patch release v2.14.168, a hotfix line in which each merged change ships at once. It documents one change: #1306 (Dashboard follow-ups).
Release Decision
Who should upgrade: Installations that use the dashboard's agent history, LLM-request export, project deletion or Cursor login status, or that run TTADK profiles. Others need not upgrade for behavior.
What this release solves: #1306 fixes the listed valid items of the review follow-ups #1076, #1127, #1132 and #1140 (fixes #1140, #1127, #1076, part of #1132): agent history refreshes its Model requests, the dashboard export has a size limit, a TTADK sign-in check that could not finish is shown, project deletion shows its impact first, and the Cursor login status refreshes.
Breaking changes: No. There is no migration or database schema change. One additive API change: a new read operation project_admin.preview_delete, and an optional refreshing field on a provider's login. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.168Contributors: Maintainer @foolzzz authored #1306; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.167 upgrades directly. There is no database schema change.
Behavior changes
The pull request states that its behavior changes follow the triage notes' fixes (maintainer decision, intended). Read in the code of #1306:
- Agent history (
web/src/pages/agent-history.tsx). Opening the Model requests section re-fetches its rows. A run card shows a warning, "TTADK sign-in check before this run started", when the run's launch record carries attadk_checknote. - TTADK launch note (
looper/agents/runtimes/ttadk.py). For an inconclusive check the note recorded in the launch record is now "timed out or failed; the run started anyway" instead of "could not finish (…)". The check itself is unchanged. - LLM-request export (
web/src/lib/api.ts). The dashboard export fails with an error once it would exceed 256 MiB, pointing toloopercli llm-requests exportfor larger exports. Smaller exports are unchanged. - Project deletion (
looper/agents/v1_domains/projects.py,web/src/components/project-settings.tsx). The new read operationproject_admin.preview_deletereturns the same impact text that deletion confirms with, changing nothing. The dashboard's Delete button now calls it and shows that impact instead of a generic "cannot be undone" line; Cancel takes focus, and a delete or preview error is shown next to the button. Deleting itself is unchanged. - Cursor login status (
looper/agents/runtimes/cursor_login.py,looper/agents/v1_domains/registry.py,web/src/lib/use-registry.ts). While a background probe runs, the login view carriesrefreshing: truenext to the last known state, and the dashboard re-polls every second while any login is checking or refreshing. The field is optional in the schema. - Model-visible changes: None to prompts or tool descriptions for Planner, Worker or Reviewer. The new operation's description ("Preview deleting a project and its Manager-scope impact without changing anything.") appears in the v1 operation catalog that API clients read.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull request: #1306 lists the tests that cover the change (Python tests for Cursor login, the v1 registry and projects, and web tests for the registry hook, LLM export, agent history, project settings and the projects API), automated reviews, and CI before the merge. It does not report a local full suite.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.168(热修线,每个合并的改动立即发布),说明一项改动:#1306(Dashboard 后续修复)。
升级决策
**谁需要升级:**使用 dashboard 的 agent 历史、LLM 请求导出、项目删除或 Cursor 登录状态,或运行 TTADK profile 的安装。其他安装没有行为上的升级需求。
解决了什么:#1306 修复评审后续 #1076、#1127、#1132 和 #1140 中列出的有效项(修复 #1140、#1127、#1076,属于 #1132):agent 历史会刷新 Model requests,dashboard 导出有大小上限,未能完成的 TTADK 登录检查会显示出来,删除项目前先显示影响,Cursor 登录状态会刷新。
**是否有破坏性变更:**否。没有迁移或数据库结构变更。有一处增量 API 变更:新增只读操作 project_admin.preview_delete,以及 provider 登录上的可选字段 refreshing。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.168。
**贡献者:**维护者 @foolzzz 提交 #1306;本版本无社区贡献。
looper --version # looper 2.14.168升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.167 上的安装可直接升级。数据库没有结构变更。
行为变化与入口
该 PR 声明行为变化遵循分诊记录中的修复(维护者决定,符合预期)。#1306 在代码中可见:
- Agent 历史(
web/src/pages/agent-history.tsx)。展开 Model requests 时会重新获取其行。启动记录带有ttadk_check说明时,运行卡片显示 “TTADK sign-in check before this run started” 警告。 - TTADK 启动说明(
looper/agents/runtimes/ttadk.py)。检查未得出结论时,启动记录中的说明由 “could not finish (…)” 改为 “timed out or failed; the run started anyway”。检查本身不变。 - LLM 请求导出(
web/src/lib/api.ts)。dashboard 导出超过 256 MiB 时报错,并指向loopercli llm-requests export做更大的导出。较小的导出不变。 - 项目删除(
looper/agents/v1_domains/projects.py、web/src/components/project-settings.tsx)。新增只读操作project_admin.preview_delete,返回删除确认所用的同一影响文本,不做任何改动。dashboard 的删除按钮现在调用它并显示该影响,而不再是通用的“无法撤销”提示;焦点落在取消按钮,删除或预览的错误显示在按钮旁。删除本身不变。 - Cursor 登录状态(
looper/agents/runtimes/cursor_login.py、looper/agents/v1_domains/registry.py、web/src/lib/use-registry.ts)。后台探测运行期间,登录视图在最近已知状态之外带有refreshing: true,dashboard 在有登录处于 checking 或 refreshing 时每秒重新拉取。该字段在 schema 中是可选的。 - **面向模型的变化:**Planner、Worker、Reviewer 的提示词和工具描述没有变化。新操作的描述(“Preview deleting a project and its Manager-scope impact without changing anything.”)会出现在 API 客户端读取的 v1 操作目录中。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1306 列出覆盖该改动的测试(Cursor 登录、v1 registry 与 projects 的 Python 测试,以及 registry hook、LLM 导出、agent 历史、项目设置和 projects API 的 web 测试)、自动评审,以及合并前的 CI。它未报告本地完整套件。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件以及构建出的 wheel。发布文档 gate 只检查正文。
Looper v2.14.167
Looper v2.14.167
This is the patch release v2.14.167, a hotfix line in which each merged change ships at once. It documents two changes: #1305 (Planner profile refusals) and #1303 (Overview project counts and Lark admission).
Release Decision
Who should upgrade: Installations where a Planner changes Worker or Reviewer profiles, where tasks move between projects while Workers run, or that run a Lark bot channel. Others need not upgrade for behavior.
What this release solves: #1305 fixes the listed valid items of the review follow-up #1228 (fixes #1228): a refused Planner profile change now says which task role pins the profile and where it came from, and points to looper_task_role_set for a Planner-defined role. #1303 fixes the listed valid items of #1097 and #1132 (fixes #1097, part of #1132): the Overview counts runs by the task's current project, and the Lark bot decides sender admission once per event.
Breaking changes: No. There is no API change, migration or database schema change. The bridge boundary is unchanged: upgrade to v2.13.165 first if the installation is older.
How to verify: Check the installed version.
looper --version # looper 2.14.167Contributors: Maintainer @foolzzz authored #1305 and #1303; no community contribution was included in this release.
Upgrading
The bridge boundary is unchanged: an installation older than v2.13.165 must upgrade to v2.13.165 first (upgrade to v2.13.165 first) and be started once; see the Upgrading section of the v2.14.0 release for the steps and rollback. An installation on v2.14.0 to v2.14.166 upgrades directly. There is no database schema change.
Behavior changes
Both pull requests state that their behavior changes follow the triage notes' fixes (maintainer decision, intended). Read in the code:
- #1305, Planner profile refusals (
looper/agents/ops/planner.py). Whenlooper_task_profile_setis refused because a pin outranks the Planner's choice, the error for a task role pin now names the role key and its origin (Planner, workflow, task template or user edit). For a role the Planner defined, with the project's role tools enabled, it says to define a new version withlooper_task_role_setandprofile_id; in other cases it keeps the dashboard (task → Roles) or user-gate guidance. The refusal itself is unchanged: the same pins are refused and nothing changes. - #1303, Overview (
looper/agents/overview.py). Running Workers' project IDs are now always replaced by the task's current project, not only when the Overview is scoped to projects. Previously an unscoped Overview (including the manager-scoped one) could show the dispatch-time project of a task that moved while its Worker ran. Project-scoped filtering is unchanged. - #1303, Lark admission (
looper/agents/channels/lark.py,lark_stream.py). The bot stream's prefilter result is recorded on the event asadmitted. The adapter reuses it instead of resolving the chat and checking the allowlist again: a refused event is logged as dropped by the prefilter and rejected as before; an admitted one skips the second check; events without the field (CLI events) are decided in the adapter as before. The admission rule itself is unchanged. - Model-visible changes: #1305 changes the Planner prompt's text for
looper_task_profile_setand the tool's description, and the refusal message the Planner sees. #1303 has none.
Optional Capability Activation & Use
No new optional capability activation is introduced in this release.
Validation
Reported by the pull requests: #1305 lists the tests that cover the change (tests/test_planner_profile_choice_db.py), automated reviews, and CI before the merge. #1303 lists tests/test_overview.py, tests/test_lark_rich_bot.py and tests/test_lark_stream.py, automated reviews, and CI before the merge. Neither reports a local full suite.
CI: CI runs after the release is drafted; its result is not recorded here.
Not tested for this draft: a local full suite and the built wheel. The release documentation gate checks the body only.
中文摘要
本版本是 patch release v2.14.167(热修线,每个合并的改动立即发布),说明两项改动:#1305(Planner 的 profile 拒绝提示)和 #1303(Overview 项目计数与 Lark 准入)。
升级决策
**谁需要升级:**Planner 会更改 Worker 或 Reviewer profile 的安装、任务在 Worker 运行期间在项目间移动的安装,或运行 Lark bot 渠道的安装。其他安装没有行为上的升级需求。
解决了什么:#1305 修复评审后续 #1228 中列出的有效项(修复 #1228):Planner 的 profile 变更被拒时,现在会说明是哪个任务角色及其来源固定了 profile,并为 Planner 自己定义的角色指向 looper_task_role_set。#1303 修复 #1097 和 #1132 中列出的有效项(修复 #1097,属于 #1132):Overview 按任务当前所属项目统计运行,Lark bot 对每个事件只判定一次发送者准入。
**是否有破坏性变更:**否。没有 API、迁移或数据库结构变更。桥接边界不变:早于 v2.13.165 的安装须先升级到 v2.13.165。
**如何验证:**核对版本为 2.14.167。
**贡献者:**维护者 @foolzzz 提交 #1305 和 #1303;本版本无社区贡献。
looper --version # looper 2.14.167升级
桥接边界不变:早于 v2.13.165 的安装必须先升级到 v2.13.165 并启动一次(upgrade to v2.13.165 first 即先升级到 v2.13.165),步骤与回退见 v2.14.0 发布说明的升级一节。v2.14.0 至 v2.14.166 上的安装可直接升级。数据库没有结构变更。
行为变化与入口
两个 PR 都声明行为变化遵循分诊记录中的修复(维护者决定,符合预期)。代码中可见:
- #1305,Planner profile 拒绝提示(
looper/agents/ops/planner.py)。looper_task_profile_set因固定项优先于 Planner 的选择而被拒时,任务角色固定的错误信息现在会给出角色 key 及其来源(Planner、workflow、任务模板或用户编辑)。对 Planner 自己定义的角色,在项目启用角色工具时,提示用looper_task_role_set和profile_id定义新版本;其他情况仍给出 dashboard(task → Roles)或 user gate 的指引。拒绝本身不变:被拒的固定项相同,也不会有任何改动。 - #1303,Overview(
looper/agents/overview.py)。运行中 Worker 的项目 ID 现在总是替换为任务当前所属项目,而不再仅限按项目限定的 Overview。此前,未限定范围(含按 manager 限定)的 Overview 可能显示 Worker 运行期间已移动的任务的派发时项目。按项目过滤的行为不变。 - #1303,Lark 准入(
looper/agents/channels/lark.py、lark_stream.py)。bot 流的预过滤结果记录在事件的admitted字段上,适配器复用该结果,不再重新解析聊天并检查白名单:被拒事件记录为被预过滤丢弃,并照常被拒绝;已准入事件跳过第二次检查;没有该字段的事件(CLI 事件)仍在适配器中判定。准入规则本身不变。 - 面向模型的变化:#1305 改动了 Planner 提示词中
looper_task_profile_set的文字、该工具的描述,以及 Planner 看到的拒绝信息。#1303 没有。
可选能力启用与使用
本版本未新增可选能力启用入口。
验证
PR 报告的:#1305 列出覆盖该改动的测试(tests/test_planner_profile_choice_db.py)、自动评审,以及合并前的 CI。#1303 列出 tests/test_overview.py、tests/test_lark_rich_bot.py 和 tests/test_lark_stream.py、自动评审,以及合并前的 CI。两者都未报告本地完整套件。
**CI:**发布草稿后 CI 会运行,其结果未在此记录。
**本次草稿未测试:**本地完整套件以及构建出的 wheel。发布文档 gate 只检查正文。