Never block the user on work in flight — aligning the tool, agent, and session layers #3567
shaokeyibb
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
English
Opening this at @Astro-Han's suggestion on #3540, to give the shared direction one place to live rather than three.
The through-line
Three threads are currently open that look like separate features but are the same principle at three layers. Astro-Han put it well in #3540: the user wants to inspect and steer the agent at any given time without being blocked by running subagents or any specific job.
Bashwithbackground=falseholds the whole agent until the command returns — and past roughly five minutes the provider's KV cache expires, so the block costs money as well as timeagent_spawnawaits the child to a terminal AgentRun, so delegating freezes the session for as long as the delegated work takesEach is defensible on its own. Read together they say something stronger: whenever Maka starts work, the user should keep the ability to watch it, redirect it, and stop it. Today that holds for exactly one case —
Bashwithrun_in_background: true, which already has retrieval viaRead({ref}), cancellation viaStopBackgroundTask, and input viaWriteStdin. Everywhere else, starting work means surrendering the session until it finishes.Worth noting the project already committed to this principle inside a single turn: mid-turn steering exists so a user can intervene while the model is working (#3529, #3530). What is missing is the same guarantee once work crosses a boundary — into a tool, into a child agent, into another session.
The part that is genuinely undecided
The two threads that propose a mechanism do not propose the same one, and I do not think the project can adopt both without the surfaces drifting apart.
#3342 argues for yield + poll, following Codex:
exec_commandreturns a session id after a short yield window, and the agent polls withwrite_stdin. The stated advantages are that no single tool call can hang the agent, and that polling is cheap when the KV cache is warm.#3540 argues for spawn + notify, following the shape Claude Code and
dsh-plugin-product-subagentsconverge on: start work in the background, keep the parent turn alive, deliver a follow-up to a named child, and let the host wake the parent when something needs attention.They are not interchangeable. Yield/poll keeps the model in control of cadence and needs no new wake machinery, but every observation costs a tool call and the model has to remember to look. Spawn/notify frees the model from polling, but requires a live-children registry, a wake path, and a decision about what a parent turn is while background work continues.
Maka also already has a third answer for the agent layer — the Agent Graph — which is durable and log-backed but ends the parent turn at
yield_agent_graphand resumes it as a new turn at a reconciliation checkpoint. That is a good fit for dependency-driven batch work and a poor one for "start this and stay with me", so it does not settle the question either.Questions worth settling here
Bashto be Codex-shaped while agents are graph-shaped?agent_pollanalogous towrite_stdin, and does that make the Agent Graph the odd one out?What I would find most useful
A decision on question 2 before anyone builds. #3342 and #3540 can each be implemented in isolation and would then be hard to reconcile — the cost of picking late is much higher than the cost of picking now.
Happy to keep #3540 narrow and defer to whatever this thread lands on. cc @likun666661, who Astro-Han suggested would have context on the swarm and graph design.
Investigated with AI assistance (Claude Code); Maka behaviour cited in #3540 was verified against source.
中文
应 @Astro-Han 在 #3540 中的建议开设此讨论,让这个共同方向有一个统一的落脚点,而不是分散在三处。
共同的主线
目前有三条线看起来是彼此独立的需求,实际上是同一条原则在三个层次上的体现。Astro-Han 在 #3540 里的表述很准确:用户希望随时能够观察和引导 agent,而不被运行中的子 agent 或任何具体任务阻塞。
Bash在background=false时会占住整个 agent 直到命令返回 —— 而一旦超过约五分钟,provider 的 KV cache 就会过期,于是这次阻塞不只耗时间,还要花钱agent_spawn会等待子 agent 抵达终态 AgentRun,因此委派工作会把会话冻结整个委派时长每一条单独看都站得住。合起来看,它们说的是一件更强的事:只要 Maka 开始工作,用户就应当保有观察它、重定向它、停止它的能力。 今天满足这一点的只有一个地方 ——
Bash的run_in_background: true,它已经具备取回(Read({ref}))、取消(StopBackgroundTask)和输入(WriteStdin)。其余任何地方,启动工作都意味着交出会话直到它结束。值得一提的是,项目在单轮内部已经承认了这条原则:mid-turn steering 之所以存在,就是为了让用户能在模型工作时介入(#3529、#3530)。缺的是同一条保证在工作跨越边界之后是否继续成立 —— 进入工具、进入子 agent、进入另一个会话。
真正尚未决定的部分
两条提出了具体机制的线程,提的并不是同一种机制;而我认为项目无法同时采纳两者又不让各个界面产生分裂。
#3342 主张 yield + poll,沿用 Codex:
exec_command在一小段 yield 窗口后返回 session id,之后由 agent 通过write_stdin轮询。其列出的优势是:任何单次 tool call 都不会挂死 agent;且在 KV cache 命中的前提下轮询开销很低。#3540 主张 spawn + notify,沿用 Claude Code 与
dsh-plugin-product-subagents收敛出的形态:在后台启动工作、保持父轮存活、向具名子 agent 追加指令,并由 host 在需要关注时唤醒父轮。两者不可互换。yield/poll 让模型自己掌握节奏、无需新的唤醒机制,但每一次观察都要花掉一次 tool call,而且需要模型记得去看。spawn/notify 免去了轮询,但需要一份 live-children 注册表、一条唤醒路径,以及对「后台工作进行时父轮究竟算什么」的明确定义。
Maka 在 agent 层其实还有第三种既有答案 —— Agent Graph。它是持久化且以日志为底的,但会在
yield_agent_graph处终结父轮,并在协调检查点以新的一轮恢复。这对依赖驱动的批量工作是合适的,对「先起个任务、你继续陪着我」则不合适,所以它同样没有为这个问题收尾。值得在此明确的问题
Bash走 Codex 形态、agent 走 graph 形态也没问题?write_stdin的agent_poll?这是否会让 Agent Graph 变成体系里的例外?我认为最有价值的推进
在任何人动工之前先就问题 2 达成结论。 #3342 与 #3540 各自都能被独立实现,而一旦都落地就很难再对齐 —— 晚做选择的代价,远高于现在就做选择。
我很乐意让 #3540 保持窄范围,并以本讨论的结论为准。cc @likun666661,Astro-Han 提到他对 swarm 与 graph 的设计更有上下文。
本调查借助 AI(Claude Code)完成;#3540 中引用的 Maka 行为均已对照源码验证。
All reactions