diff --git a/BlogWriter.Tests/BloggerAgentRoutingTests.cs b/BlogWriter.Tests/BloggerAgentRoutingTests.cs index 59b8298..de201a2 100644 --- a/BlogWriter.Tests/BloggerAgentRoutingTests.cs +++ b/BlogWriter.Tests/BloggerAgentRoutingTests.cs @@ -31,6 +31,26 @@ public async Task ResearchButNoDraft_RoutesToAuthor() Assert.Equal("author", decision.NextStep); } + [Fact] + public async Task RefinementResetsState_AndRoutesToResearcher() + { + var state = new ResearchState + { + MainTask = "topic", + ResearchFindings = ["some findings"], + CurrentSubTask = "Add a caching section.", + Draft = "a draft", + ReviewNotes = ResearchState.ApprovedMarker, + }; + + state.StartFollowUp("Add a caching section."); + BloggerDecision decision = await CreateAgent().InvokeAsync(state); + + Assert.Equal("researcher", decision.NextStep); + Assert.Empty(state.Draft); + Assert.Empty(state.ResearchFindings); + } + [Fact] public async Task DraftWithNoReview_RoutesToReviewer() { diff --git a/BlogWriter.Tests/ResearchStateTests.cs b/BlogWriter.Tests/ResearchStateTests.cs index 576c445..bf2d0b9 100644 --- a/BlogWriter.Tests/ResearchStateTests.cs +++ b/BlogWriter.Tests/ResearchStateTests.cs @@ -66,7 +66,7 @@ public void RevisionLimitReached_RequiresUnapprovedReviewAtCap( } [Fact] - public void StartFollowUp_PreservesDraftAndResearchButResetsReviewCycle() + public void StartFollowUp_ResetsResearchAndDraftSoRefinedSearchTriggersFreshResearch() { var state = new ResearchState { @@ -81,8 +81,8 @@ public void StartFollowUp_PreservesDraftAndResearchButResetsReviewCycle() state.StartFollowUp("Add a caching section."); Assert.Equal("Add a caching section.", state.CurrentSubTask); - Assert.Equal("draft", state.Draft); - Assert.Equal(["finding"], state.ResearchFindings); + Assert.Empty(state.Draft); + Assert.Empty(state.ResearchFindings); Assert.Empty(state.ReviewNotes); Assert.Equal(0, state.RevisionNumber); Assert.Empty(state.NextStep); diff --git a/ResearchState.cs b/ResearchState.cs index e29a80a..22a5ca6 100644 --- a/ResearchState.cs +++ b/ResearchState.cs @@ -77,7 +77,11 @@ public string BuildResearchQuery() return string.Join("\n\n", parts); } - /// Prepares an approved or revision-capped draft for a user-requested follow-up. + /// + /// Prepares a user-requested follow-up as a fresh research cycle. Any prior + /// draft or completed research is discarded so the blogger re-enters the + /// researcher stage and the refined query becomes the new source of truth. + /// public void StartFollowUp(string followUp) { ArgumentException.ThrowIfNullOrWhiteSpace(followUp); @@ -91,6 +95,12 @@ public void StartFollowUp(string followUp) SearchRefinements.Add(trimmed); CurrentSubTask = trimmed; + + // A refinement is a fresh research pass, not a continuation of the old + // one. Clear stale completion state so the blogger routes back to the + // researcher with the refined query instead of reusing the prior draft. + Draft = ""; + ResearchFindings.Clear(); ReviewNotes = ""; RevisionNumber = 0; NextStep = ""; diff --git a/ResearcherAgent.cs b/ResearcherAgent.cs index e73dc6b..8e4bcd6 100644 --- a/ResearcherAgent.cs +++ b/ResearcherAgent.cs @@ -74,6 +74,7 @@ public async Task ResearchNodeAsync(ResearchState state, Cancella ? state.CurrentSubTask : state.MainTask; + Console.WriteLine($"Researching topic: {query}"); _logger.LogInformation("Researching: {SubTask}", researchLabel); string findings;