Files
m 13bbcdf747
CI / test (push) Successful in 1m19s
Preserve specialized research routes
2026-08-25 22:46:20 +03:00

83 lines
3.3 KiB
Go

package main
import (
"sort"
"git.cin.su/m/Assistant/contracts/capability"
interactiondomain "git.cin.su/m/Assistant/modules/interaction/domain"
)
type chatRouteKind string
const (
chatRouteResearch chatRouteKind = "RESEARCH"
chatRouteConversation chatRouteKind = "CONVERSATION"
chatRouteMedia chatRouteKind = "MEDIA"
chatRouteAction chatRouteKind = "ACTION"
chatRouteAgent chatRouteKind = "AGENT"
)
type chatRoute struct {
Kind chatRouteKind
Capability capability.CapabilityKind
Profile string
Order int
}
// buildChatRoutePlan creates one bounded route per meaning-bearing capability.
// A failed research route must not suppress the local conversational route or
// an unrelated action route.
func buildChatRoutePlan(result interactiondomain.SemanticResult) []chatRoute {
seen := make(map[capability.CapabilityKind]struct{})
routes := make([]chatRoute, 0, len(result.CapabilityHints)+1)
add := func(kind chatRouteKind, capabilityKind capability.CapabilityKind, profile string, order int) {
if capabilityKind != "" {
if _, exists := seen[capabilityKind]; exists {
return
}
seen[capabilityKind] = struct{}{}
}
routes = append(routes, chatRoute{Kind: kind, Capability: capabilityKind, Profile: profile, Order: order})
}
for _, hint := range result.CapabilityHints {
switch capability.CapabilityKind(hint) {
case capability.CapabilityKindWebResearch:
add(chatRouteResearch, capability.CapabilityKindWebResearch, "truth-research-v1", 10)
case capability.CapabilityKindImageGeneration:
add(chatRouteMedia, capability.CapabilityKindImageGeneration, "local-image-generation-v1", 5)
case capability.CapabilityKindCognitiveReasoning, capability.CapabilityKindVerifyFact:
add(chatRouteConversation, capability.CapabilityKind(hint), "local-reasoning-v1", 20)
case capability.CapabilityKindScheduleReminder:
add(chatRouteAction, capability.CapabilityKindScheduleReminder, "continuity-reminder-v1", 30)
case capability.CapabilityKindModifyCode, capability.CapabilityKindRunTests, capability.CapabilityKindInspectProject:
add(chatRouteAgent, capability.CapabilityKind(hint), "software-agent-v1", 40)
case capability.CapabilityKindSendEmail, capability.CapabilityKindReadEmail:
add(chatRouteAgent, capability.CapabilityKind(hint), "communication-agent-v1", 50)
case capability.CapabilityKindReadDatabase, capability.CapabilityKindQueryLogs:
add(chatRouteAgent, capability.CapabilityKind(hint), "diagnostics-agent-v1", 60)
}
}
if result.NeedsCognition || len(routes) == 0 {
add(chatRouteConversation, capability.CapabilityKindCognitiveReasoning, "local-reasoning-v1", 20)
}
sort.SliceStable(routes, func(i, j int) bool { return routes[i].Order < routes[j].Order })
return routes
}
func hasChatRoute(routes []chatRoute, kind chatRouteKind) bool {
for _, route := range routes {
if route.Kind == kind {
return true
}
}
return false
}
// specializedRouteBypassesGeneralInterpretation keeps a concrete capability
// route stable. General cognition may still be used later to assess evidence,
// but it must not replace an executable research or media route with a vague
// conversational clarification before the capability is attempted.
func specializedRouteBypassesGeneralInterpretation(routes []chatRoute) bool {
return hasChatRoute(routes, chatRouteMedia) || hasChatRoute(routes, chatRouteResearch)
}