Merge remote-tracking branch 'origin/master' into fix/worker-timer-clamp

This commit is contained in:
Chinesezjc
2026-07-27 20:06:15 +08:00
5 changed files with 11 additions and 3 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md
2026-07-16-persistent-pty-sessions.md: 43c87bb159cfe1ab9f8d3a80c2adf25a57ae6e3b
2026-07-16-persistent-pty-sessions.zh.md: 8afc2103447cc58b1fcbc1062b9564e8ed643477
2026-07-16-persistent-pty-sessions.md: 4fff1742721fa13ea11f1b8ec833e5e5b7e68df8
2026-07-16-persistent-pty-sessions.zh.md: 88e7a0bc4b8af21dc51b6a654a1c9f93760b3e81

View File

@@ -80,6 +80,8 @@ On macOS there is no exact syscall tier. Output silence returns `inferred_idle`
Tier 2 returns `inferred_idle` after `idleSilenceMs` without output. A sleeping or network-blocked command can therefore look ready. Tier 3 returns `timeout` after `timeoutMs` so a foreground tool call cannot hold the agent indefinitely. The result preserves the distinction; callers may wait through `ctx.tasks`, signal the foreground group, or inspect from another session.
Once a send settles under any tier, `PtySendOperation.append` stops accepting output, so later child output no longer reaches that settled operation; it still reaches the scrollback, and any send that is active when it arrives. A test that waits for a marker on the operation it started must therefore set `idleSilenceMs` and `timeoutMs` above the child's own startup latency; interpreter startup on a loaded macOS runner otherwise ends the send before the marker is printed.
`node-pty` data notifications feed one terminal parser. Parser carry state handles control sequences and a trailing carriage return split across callbacks, so a divided CRLF produces one newline rather than a pagination-changing blank line. The implementation normalizes line-oriented output, but it does not promise correct interaction with a full-screen application.
### Model-visible output and durability

View File

@@ -80,6 +80,8 @@ macOS 没有精确 syscall 层。任何前台进程组输出静默都会返回 `
Tier 2 在持续 `idleSilenceMs` 没有输出后返回 `inferred_idle`,因此 sleep 或网络阻塞的命令可能看似 ready。Tier 3 在 `timeoutMs` 后返回 `timeout`,避免前台工具调用无限占住 agent。结果保留这些区别调用方可以通过 `ctx.tasks` 等待、向前台组发信号,或从另一个会话排查。
一次 send 在任一层级 settle 之后,`PtySendOperation.append` 就不再接受输出,此后子进程的输出不会再进入那个已 settle 的 operation它仍然会进入 scrollback以及此时恰好处于活跃状态的任何 send。因此等待自己所启动的 operation 上出现标记的测试,必须把 `idleSilenceMs``timeoutMs` 设得高于子进程自身的启动耗时;否则在负载较高的 macOS runner 上,解释器启动会在标记打印之前就结束这次 send。
`node-pty` data 通知进入同一个终端 parser。parser 的 carry state 会处理跨 callback 的控制序列和位于 callback 末尾的回车;因此,即使 CRLF 被拆开,也只会生成一个换行,而不会产生改变分页的空行。实现会规范化行式输出,但不承诺正确操作全屏应用。
### 模型可见输出与持久性

View File

@@ -66,6 +66,10 @@ async function harness(
return { ctx, root, agent, fiber, sandbox: ctx.sandbox as PassthroughSandbox }
}
// PtySendOperation.append drops output once the operation settles, so this only
// observes a marker the child prints while `operation` is still active. A caller
// whose child is slow to print must raise the harness `timing` bounds too;
// extending this deadline alone cannot recover output the operation never collected.
async function waitForOutput(operation: PtySendOperation, expected: string, timeoutMs = 2_000): Promise<void> {
const deadline = Date.now() + timeoutMs
let output = ''

View File

@@ -191,7 +191,7 @@ function resolveRoute(
function systemPrompt(config: ResolvedSessionTitleLlmConfig): string {
return [
'Create a concise title for an AI coding-assistant session from the supplied human messages.',
'Return only the title on one line, with no quotes, prefix, explanation, Markdown, or terminal control codes.',
'Return only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.',
'Use the language of the messages.',
`Aim for about ${config.targetWords} words in non-CJK languages or ${config.targetCjkCharacters} CJK characters.`,
].join('\n')