Skip to content

未声明工具批次时,不把半截调用交给客户端 - #4

Open
dovela wants to merge 1 commit into
spancerxing:mainfrom
dovela:tool-batch-deadline
Open

dovela wants to merge 1 commit into
spancerxing:mainfrom
dovela:tool-batch-deadline

Conversation

@dovela

@dovela dovela commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

实际遇到两次。一次是 glob,参数为 {},流开了 10 分 15 秒,Cursor 用 ERROR_NOT_LOGGED_IN 结束,正文是 “Authentication error: If you are logged in, try logging out and back in.”,聊天接口的 HTTP 状态仍是 200。同一次会话里,前两步工具调用大约 15 秒就正常结束。另一次是 shell,参数同样是 {},流开了 39 分 27 秒,响应体以 unexpected EOF 断开,插件把它报成 502。两次的工具调用号里都有一个换行,插件把它写成 __。

Cursor 先发出工具调用,再声明这一批的数量。数量没到时,插件以前会一直读着这条流,空参数的调用也会先交给客户端。客户端要等流结束才执行工具,于是两边互等,连接最后被掐断。现在调用先留在插件里,等数量对齐再一次性交出。30 秒从最后一次调用、本地代答或数量声明重新计时。到点仍不齐,或流先断开,就以 502 结束,并丢弃这些半截调用。go test ./... 已通过。

Made with Cursor

A missing count used to leave the stream open and could deliver an empty call; silence now fails the turn after 30 seconds without publishing those calls.

Co-authored-by: Cursor <cursoragent@cursor.com>

Copy link
Copy Markdown
Owner

感谢排查得这么细,两次现场的分析很有说服力。“先缓存、数量对齐后再一次交出”的方向我认同,不过合并前有两点想请你调整:

  1. 超时可能误杀正常调用
    代码注释里说 Cursor 在参数写完后才发出调用。如果一批里后一个调用是写大文件,生成参数很容易超过 30 秒,而这期间的文字和推理帧不会重置计时,正常的请求也会被 502 掉。建议把 toolBatchWait 调大(比如 120 秒以上)并做成可配置,或者收到任何帧都重置计时。

  2. 保留“没有数量声明但正常结束”的兜底
    原来流正常结束时,即使没收到数量声明,已有的调用也会交出。现在这种情况一律返回 502。你能确认 Cursor 的每个工具批次都一定会带数量吗?如果不能保证,建议:收到 end frame 或 turn end 时仍交出已缓存的调用,只在超时或异常断开时丢弃。

另外请补两条测试:

  • 数量声明晚到,但最终和调用数对齐,应当放行
  • 没有数量声明、流正常结束,行为和之前一致

改完我再看一遍,辛苦了!

— Hark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants