using MyAgent.Agents; using MyAgent.Core; using MyAgent.Tools; using Xunit; namespace MyAgent.Tests.Agents; public sealed class PlannerIntentWeightTests { [Fact] public void ParsePlan_HighSemanticWeightSelectsToolWithoutKeywordRules() { var json = """ { "nextAction":"NeedTool", "taskType":"FactCheck", "complexity":"Normal", "toolWeight":0.91, "memoryRecallWeight":0.08, "analysisWeight":0.2, "tools":[{ "name":"web_search", "query":"Acme Cloud service availability July 2026", "reason":"The answer depends on current external state", "maxResults":5, "confidence":0.88 }] } """; var plan = PlannerAgent.ParsePlan(json, Router(), new ToolCatalog()); Assert.True(plan.NeedsTool); Assert.Single(plan.Tools); Assert.Equal("web_search", plan.Tools[0].Name); Assert.Equal(0.91, plan.ToolWeight, 2); } [Fact] public void ParsePlan_LowWeightsDoNotTriggerToolsOrMemoryDespiteToolWords() { var json = """ { "nextAction":"NeedTool", "taskType":"Chat", "complexity":"Simple", "toolWeight":0.2, "memoryRecallWeight":0.3, "analysisWeight":0.1, "reason":"The user is discussing the words search, image and previous, not requesting actions", "tools":[{ "name":"image_search", "query":"wallpaper avatar image", "confidence":0.25 }] } """; var plan = PlannerAgent.ParsePlan(json, Router(), new ToolCatalog()); Assert.False(plan.NeedsTool); Assert.False(plan.NeedsMemoryRecall); Assert.False(plan.NeedsAnalysis); Assert.Empty(plan.Tools); Assert.Equal(PlannerNextAction.ReadyToReply, plan.NextAction); } [Theory] [InlineData(0.49, false)] [InlineData(0.5, true)] [InlineData(0.9, true)] public void ToolThreshold_IsStable(double weight, bool expected) { Assert.Equal(expected, IntentWeightPolicy.ShouldUseTool(weight)); } private static RouterDecisionEnvelope Router() => new() { ShouldReply = true, ShouldEnter = true, Target = ConversationTarget.Bot, Complexity = TaskComplexity.Simple, Route = new RouteDecision { ShouldReply = true } }; }