| 1 | package agent |
| 2 | |
| 3 | import "testing" |
| 4 | |
| 5 | func TestStripAutoResearchEvidenceBlocks(t *testing.T) { |
| 6 | cases := []struct { |
| 7 | name, in, want string |
| 8 | }{ |
| 9 | {"no block", "plain answer", "plain answer"}, |
| 10 | { |
| 11 | "single block", |
| 12 | "Findings so far.\n<autoresearch-evidence>{\"id\":\"e1\"}</autoresearch-evidence>\nNext steps.", |
| 13 | "Findings so far.\n\nNext steps.", |
| 14 | }, |
| 15 | { |
| 16 | "multiple blocks", |
| 17 | "<autoresearch-evidence>{\"id\":\"e1\"}</autoresearch-evidence>middle<autoresearch-evidence>{\"id\":\"e2\"}</autoresearch-evidence>", |
| 18 | "middle", |
| 19 | }, |
| 20 | { |
| 21 | "unterminated block drops the tail", |
| 22 | "answer\n<autoresearch-evidence>{\"id\":\"e1\"}", |
| 23 | "answer", |
| 24 | }, |
| 25 | } |
| 26 | for _, tc := range cases { |
| 27 | if got := StripAutoResearchEvidenceBlocks(tc.in); got != tc.want { |
| 28 | t.Errorf("%s: got %q, want %q", tc.name, got, tc.want) |
| 29 | } |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | // TestDisplayAssistantTextStripsAllProtocolArtifacts guards #6665: the single |
| 34 | // display filter must remove both goal markers and evidence blocks before |
| 35 | // answer text reaches any sink. |
| 36 | func TestDisplayAssistantTextStripsAllProtocolArtifacts(t *testing.T) { |
| 37 | in := "Done with the survey.\n[goal:continue]\n<autoresearch-evidence>{\"id\":\"e1\",\"summary\":\"x\"}</autoresearch-evidence>" |
| 38 | want := "Done with the survey." |
| 39 | if got := DisplayAssistantText(in); got != want { |
| 40 | t.Errorf("DisplayAssistantText = %q, want %q", got, want) |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // Planner conclusion markers are coordinator protocol; the display filter |
| 45 | // removes the standalone lines while parsing keeps reading the raw text |
| 46 | // (#6789: a relayed answer-only plan must not show "[no_changes]"). |
| 47 | func TestDisplayFilterStripsPlannerConclusionMarkers(t *testing.T) { |
| 48 | in := "The two agents differ mainly in orchestration.\n\n[no_changes]" |
| 49 | want := "The two agents differ mainly in orchestration." |
| 50 | if got := DisplayAssistantText(in); got != want { |
| 51 | t.Errorf("DisplayAssistantText = %q, want %q", got, want) |
| 52 | } |
| 53 | in = "Plan ready for review.\n[planner_requires_approval]" |
| 54 | want = "Plan ready for review." |
| 55 | if got := StripGoalMarkers(in); got != want { |
| 56 | t.Errorf("StripGoalMarkers = %q, want %q", got, want) |
| 57 | } |
| 58 | // Inline mentions survive — only standalone marker lines are protocol. |
| 59 | in = "The [no_changes] marker is emitted when done." |
| 60 | if got := DisplayAssistantText(in); got != in { |
| 61 | t.Errorf("inline mention altered: %q", got) |
| 62 | } |
| 63 | } |
| 64 |