fix: ClassifyTask priority ordering — orchestration below operational types
Operational task types (debug, review, refactor, test, explain) now gate before orchestration in the keyword cascade. Previously, prompts like "review the orchestration layer" or "refactor the pipeline dispatch" matched "orchestrat"/"dispatch" and misclassified as TaskOrchestration. Planning is also moved below the operational types. Expanded orchestration keywords to cover common intent that the original four keywords missed: "fan out", "subtask", "delegate to", "spawn elf". Adds regression tests for false-positive cases and positive tests for new keywords.
This commit is contained in:
@@ -35,6 +35,47 @@ func TestClassifyTask(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyTask_OrchestrationNotFalsePositive(t *testing.T) {
|
||||
// Words like "coordinator", "pipeline", "dispatch" appear in non-orchestration contexts.
|
||||
// More specific classifications (debug, review, refactor, explain) must win.
|
||||
tests := []struct {
|
||||
prompt string
|
||||
want TaskType
|
||||
}{
|
||||
{"fix the coordinator bug", TaskDebug}, // "coordinator" contains "coordinate"
|
||||
{"review the orchestration layer", TaskReview}, // "orchestrat" present but review wins
|
||||
{"refactor the pipeline dispatch", TaskRefactor}, // "dispatch" present but refactor wins
|
||||
{"explain how coordination works", TaskExplain}, // "coordinat" present but explain wins
|
||||
{"debug the dispatch table", TaskDebug}, // "dispatch" present but debug wins
|
||||
}
|
||||
for _, tt := range tests {
|
||||
task := ClassifyTask(tt.prompt)
|
||||
if task.Type != tt.want {
|
||||
t.Errorf("ClassifyTask(%q).Type = %s, want %s", tt.prompt, task.Type, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyTask_OrchestrationKeywords(t *testing.T) {
|
||||
// Explicit orchestration-intent phrases should still classify correctly.
|
||||
tests := []struct {
|
||||
prompt string
|
||||
want TaskType
|
||||
}{
|
||||
{"orchestrate the migration across services", TaskOrchestration},
|
||||
{"fan out the work to 5 elfs", TaskOrchestration},
|
||||
{"split this into subtasks and run them in parallel", TaskOrchestration},
|
||||
{"delegate to worker elfs for parallel processing", TaskOrchestration},
|
||||
{"spawn elfs to handle this", TaskOrchestration},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
task := ClassifyTask(tt.prompt)
|
||||
if task.Type != tt.want {
|
||||
t.Errorf("ClassifyTask(%q).Type = %s, want %s", tt.prompt, task.Type, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyTask_RequiresTools(t *testing.T) {
|
||||
// Explain tasks don't require tools
|
||||
task := ClassifyTask("explain how generics work")
|
||||
|
||||
@@ -123,16 +123,14 @@ func ClassifyTask(prompt string) Task {
|
||||
RequiresTools: true, // assume tools needed by default
|
||||
}
|
||||
|
||||
// Check for task type keywords (order matters — more specific first)
|
||||
// Check for task type keywords (order matters — more specific/common first).
|
||||
// Orchestration is placed late: its keywords ("dispatch", "pipeline", "orchestrat")
|
||||
// appear as nouns in non-orchestration prompts (e.g. "refactor the pipeline dispatch",
|
||||
// "review the orchestration layer"). Operational task types must gate first.
|
||||
switch {
|
||||
case containsAny(lower, "security", "vulnerability", "cve", "owasp", "xss", "injection", "audit security"):
|
||||
task.Type = TaskSecurityReview
|
||||
task.Priority = PriorityHigh
|
||||
case containsAny(lower, "plan", "architect", "design", "strategy", "roadmap"):
|
||||
task.Type = TaskPlanning
|
||||
case containsAny(lower, "orchestrat", "coordinate", "dispatch", "pipeline"):
|
||||
task.Type = TaskOrchestration
|
||||
task.Priority = PriorityHigh
|
||||
case containsAny(lower, "debug", "fix", "troubleshoot", "not working", "error", "crash", "failing", "bug"):
|
||||
task.Type = TaskDebug
|
||||
case containsAny(lower, "review", "check", "analyze", "audit", "inspect"):
|
||||
@@ -144,6 +142,12 @@ func ClassifyTask(prompt string) Task {
|
||||
case containsAny(lower, "explain", "what is", "how does", "describe", "tell me about"):
|
||||
task.Type = TaskExplain
|
||||
task.RequiresTools = false
|
||||
case containsAny(lower, "plan", "architect", "design", "strategy", "roadmap"):
|
||||
task.Type = TaskPlanning
|
||||
case containsAny(lower, "orchestrat", "coordinate", "dispatch", "pipeline",
|
||||
"fan out", "subtask", "delegate to", "spawn elf"):
|
||||
task.Type = TaskOrchestration
|
||||
task.Priority = PriorityHigh
|
||||
case containsAny(lower, "create", "implement", "build", "add", "write", "generate", "make"):
|
||||
task.Type = TaskGeneration
|
||||
case containsAny(lower, "scaffold", "boilerplate", "template", "stub", "skeleton"):
|
||||
|
||||
Reference in New Issue
Block a user