fix(devin-connect): merge consecutive same-role text turns before wire encoding - #270
Merged
Merged
Conversation
…e encoding
Clients that persist streamed output per-part can store one logical turn as
several consecutive same-role entries. Encoded verbatim, those runs produce
back-to-back same-source ChatMessages, and the upstream request validator
rejects a same-source run of length >= 3 with invalid_argument ("an internal
error occurred") — the request decodes and begins processing, then the
trailer fails.
Coalesce runs of consecutive same-role text-only messages before the wire
loop. Entries carrying tool_calls / tool_call_id / reasoning / non-text
content are never merged (they encode to distinct wire types); system turns
are skipped for adjacency since they hoist to field dwgx#2; the merge produces
fresh objects so the caller array stays intact for retry/failover.
Pins the merge contract with wire-level assertions: a [user,assistant x3,
user x2] history collapses to sources [1,2,1] with joined text, while
tool_call / tool_result / reasoning entries are never absorbed into a merge.
dwgx
added a commit
that referenced
this pull request
Sep 14, 2026
dwgx
added a commit
that referenced
this pull request
Sep 14, 2026
Owner
|
评审: 四条 wire 断言实测 185/185。对抗:image_url 数组不合并、CJK/ZWJ 码点保留、空+文本不被 empty-drop 吃掉、调用方数组不改。Linux CI 34799913540 6/6。 两件合并后我这边补的,不是你的疏漏:
#267 还是 |
dwgx
added a commit
that referenced
this pull request
Sep 14, 2026
User-visible: consecutive same-role Connect text no longer trips run>=3 invalid_argument (#270); Responses tool-output images reach Connect tag 10 and docker nginx is 32m/900s with the real cap still MAX_BODY_SIZE=10MB (#265); local import finds Devin desktop userData and a 160KB windsurfAuthStatus is no longer silently skipped (#264); swe-2 is in the Connect catalog and gpt-5.6 Local is opt-in (#266). No API breakage. ACU ^22 still default off. FREE_TIER_SELECTOR still swe-1-6-slow. Mutation specs stay 49/588; baselines were remeasured at merge.
dwgx
added a commit
that referenced
this pull request
Sep 15, 2026
The #270 negative test sat a tool_calls turn next to role:tool, so deleting isMergeableText's tool_calls/image checks stayed green. Same-role tool_calls+text and two image_url users now fail if those guards vanish. credit-cost-top-level 186->188, reasoning-continuity 313->315. README 三套->四套 and lists SWE-2.
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 摘要
EN: Split off from #267 per review — this is only the
mergedMessageshalf, with the requested assertions. Clients that persist streamed output per-part can store one logical turn as several consecutive same-role entries. Encoded verbatim, those runs produce back-to-back same-source ChatMessages, and the upstream request validator rejects a same-source run of length >= 3 withinvalid_argument("an internal error occurred").中文: 按 #267 评审意见拆分——本 PR 只含
mergedMessages那一半,并补上要求的断言。客户端把一个回合按 part 拆存时,历史里会出现连续同 role 的纯文本消息;原样编码后 wire 上出现连续同源 ChatMessage,run 长度 ≥ 3 时上游校验器返回invalid_argument("an internal error occurred")。Changes / 修改
EN:
tool_calls/tool_call_id/ reasoning / non-text content are never merged (they encode to distinct wire types); system turns are skipped for adjacency (they hoist to 大佬,这个非常厉害,calude code 不支持好像 #2); merge produces fresh objects — the caller array is reused by retry/failover and is never mutated.中文:
tool_calls/tool_call_id/ reasoning / 非文本内容的条目不参与合并(编码为不同 wire 类型);system 不参与相邻判断(会提升到 大佬,这个非常厉害,calude code 不支持好像 #2);合并生成新对象,不改调用方数组(重试/failover 会复用同一 messages)。Tests / 测试
EN: Four wire-level assertions in
devin-connect.test.js:[user, assistant×3, user×2]→ encoded Firebase 登入失敗: 信箱或密碼錯誤 #3 source sequence collapses to[1,2,1], merged texta1\n\na2\n\na3;tool_calls/tool_call_id/ reasoning entries are never absorbed into a merge (sources[2,4,2,2], <(0o0)> #6/language_server_linux_x64文件如何得到 #7/当前项目似乎会瞬间触发速率限制? #11 intact);messagesarray is not mutated.devin-connect.test.js: 185/185 pass.中文:
devin-connect.test.js新增四条 wire 级断言:[user, assistant×3, user×2]→ 编码后 Firebase 登入失敗: 信箱或密碼錯誤 #3 source 序列塌缩为[1,2,1],合并文本a1\n\na2\n\na3;tool_calls/tool_call_id/ reasoning 的条目不被合并(sources[2,4,2,2],<(0o0)> #6/language_server_linux_x64文件如何得到 #7/当前项目似乎会瞬间触发速率限制? #11 完好);messages数组。devin-connect.test.js:185/185 通过。