Generate for any long task configs/task_loop/<task_id>.json and optional scripts/task_loop_adapters/<task_id>_adapter.py, integrate into the generic loop.
Reference implementation: ⚠ The original reference implementation as of 2026-08 has been migrated/packaged (path invalid); scripts can be self-built according to the templates/ template.
Deliverables of this repository:
| Path | Description |
|---|---|
templates/adapter.template.py |
poll adapter template (Python 3, compatible with 2.7) |
templates/config.template.json |
task config template |
templates/fetch.template.sh |
remote fetch script template |
reference.md |
Mode/contract/example reference |
Runtime layout(generated according to the template into the reference repository/project; the original reference implementation has been migrated/packaged, path invalid—see above):
| Path | Description |
|---|---|
scripts/task_loop_poll.py |
Poll according to config (derived from adapter.template.py + config) |
scripts/task_loop_start.sh / task_loop_stop.sh |
Start/stop loop |
scripts/task_loop_scaffold.py |
One-click generation of config + adapter |
configs/task_loop/ |
Task configuration |
reports/task_loops/<task_id>/live.md |
Read by the Agent every tick |
Other repositories: copy templates/ to the target repository, and generate the above runtime files according to reference.md .
When to use
- The user wants to add a 60s (or configurable) progress loop for anew long taskadd a 60s (or configurable) progress loop
- Progress is inlocal file / remote SSH / custom shell / terminal outputone or a combination
- Need config + adapter template or have the Agent generate automatically
Workflow (in order)
1. Collect (AskQuestion or confirm via conversation)
| Item | Description |
|---|---|
task_id |
lowercase + underscore, e.g. ecs_disk_collect |
title |
Chinese display name |
progress_source |
See reference.md four modes |
interval_sec |
Default 60 |
tick_env |
Optional, e.g. AGENT_LOOP_TICK_ECS_DISK; default is AGENT_LOOP_TICK_<TASK_ID> |
| Remote/path | Host, log, progress JSON, etc. (write into poll_command / fetch script,do notwrite into the loop core) |
2. Choose mode → generate files
Prefer: If the reference repository already has scripts/task_loop_scaffold.py, execute directly; otherwise generate manually according to templates/ (main path):
## 1) 复制模板到目标仓库
cp templates/config.template.json configs/task_loop/<task_id>.json # 按 reference.md 填空
cp templates/adapter.template.py scripts/task_loop_adapters/<task_id>_adapter.py # 按 mode 改解析逻辑
## 2) (可选)remote_fetch 模式:复制 templates/fetch.template.sh 为 scripts/<task_id>_fetch.sh 并填主机/命令
# 3) (可选)参考仓库有 scaffold 时可用:
# python3 scripts/task_loop_scaffold.py \
# --task-id <task_id> \
# --title "<title>" \
# --mode <local_json|local_log|remote_fetch|stdout_json|custom> \
# [--fetch-script scripts/<name>.sh] \
# [--progress-file /path/to/progress.json] \
# [--log-file /path/to/exec.log] \
# [--terminal-pattern 'substring in terminal cmd'] \
# [--tick-env AGENT_LOOP_TICK_XXX]
orManual: copy the templates under templates/ , fill in according to reference.md .
After generation, there must be:
configs/task_loop/<task_id>.json- If
poll_adapteris non-empty:scripts/task_loop_adapters/<task_id>_adapter.py(chmod +xnot required, called by python3)
3. Validate
When the reference repository has scripts/task_loop_poll.py :
python3 scripts/task_loop_poll.py --task <task_id>
When there is no poll script: manually validate according to the reference.md contract—feed the adapter with poll_command 's stdout, and confirm that the output chat_line is non-empty and status is valid. If it fails, fix poll_command / adapter,do notstart the loop.
4. Start loop (before the long task begins)
The Agent must use the Shell tool to start(block_until_ms: 0) and configure notify_on_output pattern=^<tick_env>. Writing logs only is prohibited, and running in the background via a subagent without reporting back to Chat is prohibited.
./scripts/task_loop_start.sh <task_id> # 参考仓库脚本;本仓库需先按模板生成
Record the output's tick_env=. When starting the long task in another Shell, the pattern includes HEARTBEAT。
5. When the Agent receives a tick
- Read
reports/task_loops/<task_id>/live.md(orlive.jsonofchat_line) - Send one line in Chat
chat_line(must not only read without sending) status=doneor the task has ended →./scripts/task_loop_stop.sh <task_id>
Comply with long-running-progress rule: ≤60s must have Chat feedback.
Standard contract (adapter output / poll direct output)
adapter output and poll direct output share the same standard JSON;poll_command when this contract has already been output, mayomit adapter:
{
"status": "running|done|idle|error",
"finished": false,
"chat_line": "给用户的一行摘要",
"progress": { "offset": 5, "total": 10 },
"metrics": {},
"log_tail": ["最近日志行"]
}
progresschoose any of the three types:{offset,total}(numeric value) /{pct}(percentage 0-100) /{stage,stage_total}(stage)chat_line/statusoptional (defaults to being derived by consumer from progress/finished)- adapter is a generic interpreter: reads
progress_extractextraction (config-driven,zero code changes per task); if the input is already the standard contract, pass it through as-is - Python 3(
from __future__ import print_functionretain dual compatibility); when the path contains Chinese, useu8()see template
Mode quick reference
| mode | poll_command typical | adapter |
|---|---|---|
stdout_json |
command directly echo/print standard JSON | None |
local_json |
cat reports/foo/progress.json |
Yes, parse offset/total |
local_log |
tail -20 /path/log |
Yes, extract from log via regex |
remote_fetch |
bash scripts/<task>_fetch.sh |
Yes, parse fetch wrapper JSON |
custom |
user-given shell | As needed |
See reference.md and templates/。
Example task
| task_id | Reference |
|---|---|
cm_drop_stage_a |
configs/task_loop/cm_drop_stage_a.json + cm_drop_adapter.py |
Prohibited
- write plaintext passwords in config / skill / logs; for SSH use
credentials-and-access+ parse inside fetch script - copy the polling core for each task (
task_loop_poll.pyor adapter template); only add config + adapter (and optional fetch.sh) - start the loop before validation (poll contract verification) succeeds
Reporting template
已为 **<title>** 创建 task loop:
- config: `configs/task_loop/<task_id>.json`
- adapter: `scripts/task_loop_adapters/<task_id>_adapter.py`(或无)
- tick: `<tick_env>`
- 校验: `chat_line` = …
启动: `./scripts/task_loop_start.sh <task_id>`