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
53 lines
1.6 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|