Files
gnoma/internal/tool/agent/agent_test.go
vikingowl cb2d63d06f feat: Ollama/gemma4 compat — /init flow, stream filter, safety fixes
provider/openai:
- Fix doubled tool call args (argsComplete flag): Ollama sends complete
  args in the first streaming chunk then repeats them as delta, causing
  doubled JSON and 400 errors in elfs
- Handle fs: prefix (gemma4 uses fs:grep instead of fs.grep)
- Add Reasoning field support for Ollama thinking output

cmd/gnoma:
- Early TTY detection so logger is created with correct destination
  before any component gets a reference to it (fixes slog WARN bleed
  into TUI textarea)

permission:
- Exempt spawn_elfs and agent tools from safety scanner: elf prompt
  text may legitimately mention .env/.ssh/credentials patterns and
  should not be blocked

tui/app:
- /init retry chain: no-tool-calls → spawn_elfs nudge → write nudge
  (ask for plain text output) → TUI fallback write from streamBuf
- looksLikeAgentsMD + extractMarkdownDoc: validate and clean fallback
  content before writing (reject refusals, strip narrative preambles)
- Collapse thinking output to 3 lines; ctrl+o to expand (live stream
  and committed messages)
- Stream-level filter for model pseudo-tool-call blocks: suppresses
  <<tool_code>>...</tool_code>> and <<function_call>>...<tool_call|>
  from entering streamBuf across chunk boundaries
- sanitizeAssistantText regex covers both block formats
- Reset streamFilterClose at every turn start
2026-04-05 19:24:51 +02:00

53 lines
1.6 KiB
Go

package agent
import (
"testing"
"somegit.dev/Owlibou/gnoma/internal/router"
)
func TestParseTaskType_ExplicitHintTakesPrecedence(t *testing.T) {
// Explicit hints should override prompt classification
tests := []struct {
hint string
prompt string
want router.TaskType
}{
{"review", "fix the bug", router.TaskReview},
{"refactor", "write tests", router.TaskRefactor},
{"debug", "plan the architecture", router.TaskDebug},
{"explain", "implement the feature", router.TaskExplain},
{"planning", "debug the crash", router.TaskPlanning},
{"generation", "review the code", router.TaskGeneration},
}
for _, tt := range tests {
got := parseTaskType(tt.hint, tt.prompt)
if got != tt.want {
t.Errorf("parseTaskType(%q, %q) = %s, want %s", tt.hint, tt.prompt, got, tt.want)
}
}
}
func TestParseTaskType_AutoClassifiesWhenNoHint(t *testing.T) {
// No hint → classify from prompt instead of defaulting to TaskGeneration
tests := []struct {
prompt string
want router.TaskType
}{
{"review this pull request", router.TaskReview},
{"fix the failing test", router.TaskDebug},
{"refactor the auth module", router.TaskRefactor},
{"write unit tests for handler", router.TaskUnitTest},
{"explain how the router works", router.TaskExplain},
{"audit security of the API", router.TaskSecurityReview},
{"plan the migration strategy", router.TaskPlanning},
{"scaffold a new service", router.TaskBoilerplate},
}
for _, tt := range tests {
got := parseTaskType("", tt.prompt)
if got != tt.want {
t.Errorf("parseTaskType(%q) = %s, want %s (auto-classified)", tt.prompt, got, tt.want)
}
}
}