grammar: the last two model calls that were still free text
The replier and the meeting summariser were the two call sites without a
GBNF. Both are exactly the shape that makes a Thinking variant answer with
its reasoning as prose, and neither had anything downstream that could
remove it.
The replier already parses {"response","mood"}, so it now sends the phraser's
grammar for that contract, exported once as phraser.ResponseGrammar so the
two definitions cannot drift.
The summariser stays text-in/text-out. The JSON wrapper is attached and
unwrapped in the daemon's Completer, so internal/capture is unchanged and a
Completer without a grammar still works.
The simulator told routing from phrasing by "has a grammar", which stopped
being true here; it now looks for the intent enum.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -116,3 +116,29 @@ func TestStopReturnsTranscriptAndNotesItWithoutASummary(t *testing.T) {
|
||||
t.Fatalf("the meeting left no note behind: %+v", notes)
|
||||
}
|
||||
}
|
||||
|
||||
// The summary path is JSON-wrapped by summaryGrammar, and internal/capture must
|
||||
// keep seeing plain prose. These cover the wrapper and every way it can be
|
||||
// absent or broken, because a meeting summary is written once and not retried.
|
||||
func TestUnwrapSummary(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"grammar output", `{"summary": "решили купить насос"}`, "решили купить насос"},
|
||||
{"multiline field", `{"summary": "- насос\n- бюджет"}`, "- насос\n- бюджет"},
|
||||
{"empty marker survives", `{"summary": "пусто"}`, "пусто"},
|
||||
{"empty field says nothing", `{"summary": ""}`, ""},
|
||||
{"thinking prefix", "<think>hm</think>\n{\"summary\": \"итог\"}", "итог"},
|
||||
{"no grammar, plain prose", "решили купить насос", "решили купить насос"},
|
||||
{"broken json falls back", `{"summary": "обрыв`, `{"summary": "обрыв`},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
if got := unwrapSummary(c.in); got != c.want {
|
||||
t.Errorf("unwrapSummary(%q) = %q, want %q", c.in, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user