mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-27 21:33:58 +02:00
refactor: move handoff guidance into workflow builder
Move handoff routing and ownership rules out of per-agent system prompts and into the Agent Framework handoff builder guidance. This keeps AgentInstructionComposer focused on Aryx-owned system prompt content while letting WithHandoffInstructions supply the workflow-level handoff semantics. - remove handoff-mode runtime guidance from AgentInstructionComposer - expand HandoffWorkflowGuidance with the triage/specialist rules - update tests to pin the new split of responsibilities Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -51,27 +51,7 @@ internal static class AgentInstructionComposer
|
|||||||
return JoinInstructionBlocks(baseInstructions, repositoryInstructions, workspaceGuidance, planModeGuidance, groupChatGuidance);
|
return JoinInstructionBlocks(baseInstructions, repositoryInstructions, workspaceGuidance, planModeGuidance, groupChatGuidance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(pattern.Mode, "handoff", StringComparison.OrdinalIgnoreCase))
|
return JoinInstructionBlocks(baseInstructions, repositoryInstructions, workspaceGuidance, planModeGuidance);
|
||||||
{
|
|
||||||
return JoinInstructionBlocks(baseInstructions, repositoryInstructions, workspaceGuidance, planModeGuidance);
|
|
||||||
}
|
|
||||||
|
|
||||||
string runtimeGuidance = agentIndex == 0
|
|
||||||
? """
|
|
||||||
You are the routing gate for this handoff workflow.
|
|
||||||
Your job is to classify the request and hand it off to the most appropriate specialist as soon as you know who should own the substantive work.
|
|
||||||
For any substantive task, your next meaningful action must be the actual handoff rather than a plain-text promise to delegate later.
|
|
||||||
Do not inspect files, call tools, draft the implementation, or produce the final user-facing answer yourself once a specialist is appropriate.
|
|
||||||
Do not claim that you handed work off unless you actually executed the handoff.
|
|
||||||
Only answer directly if the user is asking for pure triage or a minimal clarification that must happen before delegation.
|
|
||||||
"""
|
|
||||||
: """
|
|
||||||
You are a specialist participating in a handoff workflow.
|
|
||||||
Once the triage agent hands work to you, you own the substantive answer within your specialty and should carry it through.
|
|
||||||
Do not push the actual work back to triage unless you are blocked or the request is clearly outside your specialty.
|
|
||||||
""";
|
|
||||||
|
|
||||||
return JoinInstructionBlocks(baseInstructions, repositoryInstructions, workspaceGuidance, planModeGuidance, runtimeGuidance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string JoinInstructionBlocks(params string[] blocks)
|
private static string JoinInstructionBlocks(params string[] blocks)
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ internal static class HandoffWorkflowGuidance
|
|||||||
{
|
{
|
||||||
return """
|
return """
|
||||||
This workflow uses explicit handoffs to transfer ownership between agents.
|
This workflow uses explicit handoffs to transfer ownership between agents.
|
||||||
|
If you are acting as the routing or triage agent, classify the request and hand it off to the best specialist as soon as ownership is clear.
|
||||||
If another agent should do the substantive work, perform an actual handoff instead of answering as though the handoff already happened.
|
If another agent should do the substantive work, perform an actual handoff instead of answering as though the handoff already happened.
|
||||||
|
For any substantive task, your next meaningful action must be the actual handoff rather than a plain-text promise to delegate later.
|
||||||
Do not claim that you delegated unless you actually executed the handoff.
|
Do not claim that you delegated unless you actually executed the handoff.
|
||||||
The triage agent should route to the best specialist promptly once ownership is clear.
|
If a specialist is appropriate, do not inspect files, call tools, draft the implementation, or produce the final user-facing answer before handing off.
|
||||||
In a specialist workflow, the triage agent should hand off before inspecting files, calling tools, or drafting the substantive implementation.
|
Only answer directly when the request is pure triage or a minimal clarification is required before delegation.
|
||||||
Do not narrate a handoff in plain text without executing the handoff itself.
|
Do not narrate a handoff in plain text without executing the handoff itself.
|
||||||
|
If you receive work as a specialist, own the substantive answer within your specialty and carry it through.
|
||||||
|
Do not push the work back to triage unless you are blocked or the request is clearly outside your specialty.
|
||||||
Specialists should complete the substantive work after handoff and only hand control back when the task needs re-routing, broader coordination, or is outside their specialty.
|
Specialists should complete the substantive work after handoff and only hand control back when the task needs re-routing, broader coordination, or is outside their specialty.
|
||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public sealed class AgentInstructionComposerTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Compose_StrengthensHandoffTriageInstructions()
|
public void Compose_LeavesHandoffTriagePromptFocusedOnAgentInstructions()
|
||||||
{
|
{
|
||||||
PatternDefinitionDto pattern = new()
|
PatternDefinitionDto pattern = new()
|
||||||
{
|
{
|
||||||
@@ -70,14 +70,13 @@ public sealed class AgentInstructionComposerTests
|
|||||||
|
|
||||||
string instructions = AgentInstructionComposer.Compose(pattern, triage, agentIndex: 0);
|
string instructions = AgentInstructionComposer.Compose(pattern, triage, agentIndex: 0);
|
||||||
|
|
||||||
Assert.Contains("routing gate", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Equal("You triage requests and must hand them off to the most appropriate specialist.", instructions);
|
||||||
Assert.Contains("Do not inspect files", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.DoesNotContain("routing", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("actual handoff", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.DoesNotContain("actual handoff", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Do not claim that you handed work off", instructions, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Compose_StrengthensHandoffSpecialistInstructions()
|
public void Compose_LeavesHandoffSpecialistPromptFocusedOnAgentInstructions()
|
||||||
{
|
{
|
||||||
PatternDefinitionDto pattern = new()
|
PatternDefinitionDto pattern = new()
|
||||||
{
|
{
|
||||||
@@ -93,8 +92,9 @@ public sealed class AgentInstructionComposerTests
|
|||||||
|
|
||||||
string instructions = AgentInstructionComposer.Compose(pattern, specialist, agentIndex: 1);
|
string instructions = AgentInstructionComposer.Compose(pattern, specialist, agentIndex: 1);
|
||||||
|
|
||||||
Assert.Contains("Once the triage agent hands work to you", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Equal("You focus on navigation, UX, and interaction details.", instructions);
|
||||||
Assert.Contains("own the substantive answer", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.DoesNotContain("triage agent", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.DoesNotContain("substantive answer", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -11,8 +11,12 @@ public sealed class HandoffWorkflowGuidanceTests
|
|||||||
string instructions = HandoffWorkflowGuidance.CreateWorkflowInstructions();
|
string instructions = HandoffWorkflowGuidance.CreateWorkflowInstructions();
|
||||||
|
|
||||||
Assert.Contains("explicit handoffs", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("explicit handoffs", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.Contains("routing or triage agent", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.Contains("best specialist", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.Contains("Do not inspect files", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Do not claim that you delegated", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Do not claim that you delegated", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Do not narrate a handoff", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Do not narrate a handoff", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.Contains("own the substantive answer", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Specialists should complete the substantive work", instructions, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Specialists should complete the substantive work", instructions, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user