mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 06:15:58 -10:00
Approach from PR #5040: _close_verdict holds while </tool_call> is still arriving, and the streaming scan of a body whose end is known runs as final. #4701 (final call) and #4702 (longer code fence) are already fixed on the base; the corpus gets the four 4701 specimens (PR #4762 and #5040 fixtures) and runs them whole, in pieces and cut at every byte, with streamed arguments on and off.
This commit is contained in:
1 parent
ff36fa9282
commit
3bbf0f399e
2 files changed
+15
-2
No files matched your search
+6
-2
@@ -794,7 +794,10 @@ def _close_verdict(after: str, final: bool) -> str:
|
||||
text decide, so a call is never held longer than that."""
|
||||
m = re.match(r"(?:</function>)?\s*</tool_call>", after)
|
||||
if not m:
|
||||
return "end" # only `</function>` so far, or the call is cut: as before
|
||||
tail = after[len(FUNC_END):].lstrip() if after.startswith(FUNC_END) else after
|
||||
if not final and CALL_END.startswith(tail):
|
||||
return "hold" # #5040: `</tool_call>` is still arriving: a streamed view must not end the value yet
|
||||
return "end" # the call is cut, or it has no wrapper: as before
|
||||
rest = after[m.end():].lstrip()
|
||||
if not rest:
|
||||
return "end" if final else "hold" # the usual call: the turn ends right after it
|
||||
@@ -1861,9 +1864,10 @@ class OutputParser:
|
||||
if self.stream_tools:
|
||||
if i >= 0:
|
||||
whole, self.buf = self.buf, self.buf[:i] # scan only the body
|
||||
final, self._final = self._final, True # #5040: its end is known, so no closing tag is still arriving
|
||||
out += self._scan()
|
||||
out += self._close_scan()
|
||||
self.buf = whole
|
||||
self.buf, self._final = whole, final
|
||||
else:
|
||||
out += self._scan()
|
||||
if i < 0 or drop is None:
|
||||
|
||||
@@ -105,6 +105,15 @@ add("4078-heredoc", qwen("bash", command=HEREDOC), [("bash", {"command": HEREDOC
|
||||
add("4078-call-format-in-a-file", qwen("write_file", path="DOC.md", content="Close a call with </function> and then </tool_call>.\nlike this."),
|
||||
[("write_file", {"path": "DOC.md", "content": "Close a call with </function> and then </tool_call>.\nlike this."})],
|
||||
source="#210: a file that documents the format")
|
||||
CLOSE_DOC = ("# Tool calls\n\nThe closing tags, in order:\n\n</parameter>\n</function>\n</tool_call>\n\nNothing may follow the last one.")
|
||||
add("4701-closing-tags-in-a-file", "I will save the doc.\n\n" + qwen("write_file", path="TOOLS.md", content=CLOSE_DOC),
|
||||
[("write_file", {"path": "TOOLS.md", "content": CLOSE_DOC})], content="I will save the doc.", source="#4701, #5040: streamed arguments too")
|
||||
add("4701-closing-tags-in-a-file-recover", qwen("write_file", path="TOOLS.md", content=CLOSE_DOC),
|
||||
[("write_file", {"path": "TOOLS.md", "content": CLOSE_DOC})], recover=True, source="#4701, recover on")
|
||||
add("4701-text-after-a-whole-call", qwen("read", path="a.txt") + "\n\nThat is the read.", [("read", {"path": "a.txt"})],
|
||||
content="That is the read.", source="#4701: with no later close, the first one is the end")
|
||||
add("4701-two-calls-with-text-between", qwen("read", path="a.txt") + "\n\nAnd the next:\n" + qwen("read", path="b.txt"),
|
||||
[("read", {"path": "a.txt"}), ("read", {"path": "b.txt"})], content="And the next:", source="#4701: a later call is not a later close")
|
||||
add("4077-stray-think-line", "The user wants a file with a literal.\n" + STRAY_VALUE + "\nSo I write it.\n</think>\n\n" +
|
||||
qwen("write_file", path="out.txt", content=STRAY_VALUE),
|
||||
[("write_file", {"path": "out.txt", "content": STRAY_VALUE})], thinking=True,
|
||||
|
||||
Reference in new issue
Block a user