Allow retry 3 times for format response in Routing.

This commit is contained in:
hchen 2023-10-10 16:53:04 -05:00
parent c9822dd7ee
commit 578362c411
12 changed files with 370 additions and 42 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -48,4 +48,24 @@ public class TransferToCsrRoutingHandler : IRoutingHandler
}
```
## Routing - Redirection
Router will maintain an Agent call stack and automatically set the currently active Agent based on the conversation status and redirection configuration.
![calling stack](./assets/routing-calling-stack.png)
You can configure redirection rules based on your business needs.
```json
{
"routingRules": [
{
"field": "order_number",
"required": true,
"description": "pizza order number",
"redirectTo": "c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd"
}
]
}
```

View file

@ -0,0 +1,92 @@
<mxfile host="Electron" modified="2023-09-05T01:58:45.080Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.8 Chrome/114.0.5735.289 Electron/25.5.0 Safari/537.36" etag="JZhE_J1lWIuWd_gVRcGi" version="21.6.8" type="device">
<diagram name="Page-1" id="kO8wPeW4tp55nROlIybF">
<mxGraphModel dx="1434" dy="836" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="X3GvA0o1aQpa0wGmxsrW-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-1" target="X3GvA0o1aQpa0wGmxsrW-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-1" value="&lt;b&gt;User&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="370" y="150" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-4" value="&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;My previous order is P123-01, it&#39;s a slice of cheese pizza.&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;If the baking can be done in 10 minutes, I want to order more slices.&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;/div&gt;" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="290" y="50" width="230" height="110" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-5" target="X3GvA0o1aQpa0wGmxsrW-6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="558" y="325" />
<mxPoint x="558" y="240" />
<mxPoint x="670" y="240" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-19" value="How long does it take to &lt;br&gt;bake a slice of cheese pizza?" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontStyle=1" vertex="1" connectable="0" parent="X3GvA0o1aQpa0wGmxsrW-8">
<mxGeometry x="-0.0526" y="-1" relative="1" as="geometry">
<mxPoint x="-19" y="28" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-5" target="X3GvA0o1aQpa0wGmxsrW-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-5" value="&lt;b&gt;&lt;font style=&quot;font-size: 15px;&quot;&gt;BotSharp&lt;/font&gt;&lt;/b&gt;&lt;br&gt;Routing with Reasoning" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="295" y="310" width="180" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-6" target="X3GvA0o1aQpa0wGmxsrW-5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="670" y="440" />
<mxPoint x="558" y="440" />
<mxPoint x="558" y="355" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-18" value="15 minutes remaining" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontStyle=1" vertex="1" connectable="0" parent="X3GvA0o1aQpa0wGmxsrW-9">
<mxGeometry x="-0.3214" relative="1" as="geometry">
<mxPoint x="-68" y="-40" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-6" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Baking&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="640" y="290" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-12">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="200" y="510" />
<mxPoint x="200" y="210" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-17" value="&lt;b&gt;I&#39;m sorry, but the baking for your &lt;br&gt;previous order&amp;nbsp;will take 15 minutes, &lt;br&gt;which is longer than the 10 minutes &lt;br&gt;you requested. &lt;br&gt;Therefore, we can&#39;t proceed &lt;br&gt;with ordering more slices at this time.&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="X3GvA0o1aQpa0wGmxsrW-16">
<mxGeometry x="-0.0341" y="-1" relative="1" as="geometry">
<mxPoint x="-21" y="-18" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-10" value="&lt;b&gt;Interrupt/&lt;br&gt;Continue&lt;/b&gt;" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="345" y="470" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;entryX=1;entryY=0.3333333333333333;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-12" target="X3GvA0o1aQpa0wGmxsrW-1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="410" y="170" as="targetPoint" />
<Array as="points">
<mxPoint x="620" y="683" />
<mxPoint x="620" y="170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-20" value="Sure, I can help you with that. &lt;br&gt;How many slices of pizza would you like to order?" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontStyle=1" vertex="1" connectable="0" parent="X3GvA0o1aQpa0wGmxsrW-14">
<mxGeometry x="-0.2928" y="1" relative="1" as="geometry">
<mxPoint y="1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-12" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Ordering&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="355" y="630" width="60" height="70" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -0,0 +1,96 @@
<mxfile host="Electron" modified="2023-10-10T21:37:46.499Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.2 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="0ntWy2UIdZMf8bWTgWaW" version="22.0.2" type="device">
<diagram name="Page-1" id="kO8wPeW4tp55nROlIybF">
<mxGraphModel dx="1434" dy="844" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="X3GvA0o1aQpa0wGmxsrW-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="X3GvA0o1aQpa0wGmxsrW-1" target="X3GvA0o1aQpa0wGmxsrW-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-1" value="&lt;b&gt;User&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="370" y="150" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-4" value="&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;May I know the order payment status?&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="285" y="90" width="225" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-5" target="X3GvA0o1aQpa0wGmxsrW-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-5" value="&lt;b&gt;&lt;font style=&quot;font-size: 15px;&quot;&gt;BotSharp&lt;/font&gt;&lt;/b&gt;&lt;br&gt;Routing with redirection" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="295" y="310" width="180" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-6" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Payment&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="220" y="467" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-12">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-19" value="&lt;b&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Redirect to Ordering&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-3">
<mxGeometry x="-0.7634" relative="1" as="geometry">
<mxPoint y="10" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-10" value="&lt;b&gt;Have Order Number?&lt;/b&gt;" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="345" y="480" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-12" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Ordering&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="608" y="620" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.3333333333333333;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-6" target="X3GvA0o1aQpa0wGmxsrW-1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="168" y="520" />
<mxPoint x="168" y="170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-13" value="&lt;b style=&quot;border-color: var(--border-color);&quot;&gt;&lt;font style=&quot;border-color: var(--border-color); font-size: 12px;&quot;&gt;The order of P12345 &lt;br&gt;has been paid successfully&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-12">
<mxGeometry x="-0.2864" y="2" relative="1" as="geometry">
<mxPoint x="2" y="-18" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-12" target="6MggG28vB1jrAnJqoctb-16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-15" value="&lt;b&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Do you have the order number?&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-14">
<mxGeometry x="0.1208" relative="1" as="geometry">
<mxPoint y="24" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="6MggG28vB1jrAnJqoctb-16" target="X3GvA0o1aQpa0wGmxsrW-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-16" value="&lt;b&gt;User&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="638" y="320" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-17" value="&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;The order is P12345&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;direction=east;" vertex="1" parent="1">
<mxGeometry x="578" y="240" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-20" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;lid=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="258.53999999999996" y="877" width="91.49" height="120" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-21" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Router&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="278.57000000000005" y="917" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-22" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Payment&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="413.99999999999994" y="787" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-23" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Ordering&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="150" y="737" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-24" value="" style="html=1;shadow=0;dashed=0;align=center;verticalAlign=middle;shape=mxgraph.arrows2.jumpInArrow;dy=15;dx=38;arrowHead=55;direction=south;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="212.5" y="777" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-25" value="" style="html=1;shadow=0;dashed=0;align=center;verticalAlign=middle;shape=mxgraph.arrows2.jumpInArrow;dy=15;dx=38;arrowHead=55;direction=east;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="330" y="797" width="70" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-26" value="&lt;b&gt;Router maintains the agent calling stack &lt;br&gt;according to conversation state&lt;/b&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="396" y="908" width="248" height="41" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -0,0 +1,96 @@
<mxfile host="Electron" modified="2023-10-10T21:37:42.505Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.2 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="-dbqqSJbNwoyw_Kk7Jn3" version="22.0.2" type="device">
<diagram name="Page-1" id="kO8wPeW4tp55nROlIybF">
<mxGraphModel dx="1434" dy="844" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="X3GvA0o1aQpa0wGmxsrW-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="X3GvA0o1aQpa0wGmxsrW-1" target="X3GvA0o1aQpa0wGmxsrW-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-1" value="&lt;b&gt;User&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="370" y="150" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-4" value="&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;May I know the order payment status?&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="285" y="90" width="225" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-5" target="X3GvA0o1aQpa0wGmxsrW-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-5" value="&lt;b&gt;&lt;font style=&quot;font-size: 15px;&quot;&gt;BotSharp&lt;/font&gt;&lt;/b&gt;&lt;br&gt;Routing with redirection" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="295" y="310" width="180" height="60" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-6" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Payment&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="220" y="467" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-12">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-19" value="&lt;b&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Redirect to Ordering&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-3">
<mxGeometry x="-0.7634" relative="1" as="geometry">
<mxPoint y="10" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-10" target="X3GvA0o1aQpa0wGmxsrW-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-10" value="&lt;b&gt;Have Order Number?&lt;/b&gt;" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="345" y="480" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="X3GvA0o1aQpa0wGmxsrW-12" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Ordering&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="608" y="620" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.3333333333333333;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-6" target="X3GvA0o1aQpa0wGmxsrW-1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="168" y="520" />
<mxPoint x="168" y="170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-13" value="&lt;b style=&quot;border-color: var(--border-color);&quot;&gt;&lt;font style=&quot;border-color: var(--border-color); font-size: 12px;&quot;&gt;The order of P12345 &lt;br&gt;has been paid successfully&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-12">
<mxGeometry x="-0.2864" y="2" relative="1" as="geometry">
<mxPoint x="2" y="-18" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="X3GvA0o1aQpa0wGmxsrW-12" target="6MggG28vB1jrAnJqoctb-16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-15" value="&lt;b&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Do you have the order number?&lt;/font&gt;&lt;/b&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6MggG28vB1jrAnJqoctb-14">
<mxGeometry x="0.1208" relative="1" as="geometry">
<mxPoint y="24" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="6MggG28vB1jrAnJqoctb-16" target="X3GvA0o1aQpa0wGmxsrW-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-16" value="&lt;b&gt;User&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="638" y="320" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-17" value="&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;font color=&quot;#1e1e1e&quot;&gt;&lt;b&gt;The order is P12345&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;direction=east;" vertex="1" parent="1">
<mxGeometry x="578" y="240" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-20" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;lid=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="258.53999999999996" y="877" width="91.49" height="120" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-21" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Router&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="278.57000000000005" y="917" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-22" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Payment&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="413.99999999999994" y="787" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-23" value="&lt;b&gt;&lt;br&gt;&lt;br&gt;Ordering&lt;br&gt;&lt;/b&gt;" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="150" y="737" width="51.43" height="60" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-24" value="" style="html=1;shadow=0;dashed=0;align=center;verticalAlign=middle;shape=mxgraph.arrows2.jumpInArrow;dy=15;dx=38;arrowHead=55;direction=south;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="212.5" y="777" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-25" value="" style="html=1;shadow=0;dashed=0;align=center;verticalAlign=middle;shape=mxgraph.arrows2.jumpInArrow;dy=15;dx=38;arrowHead=55;direction=east;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="330" y="797" width="70" height="70" as="geometry" />
</mxCell>
<mxCell id="6MggG28vB1jrAnJqoctb-26" value="&lt;b&gt;Router maintains the agent calling stack &lt;br&gt;according to conversation state&lt;/b&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="396" y="908" width="248" height="41" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View file

@ -6,9 +6,12 @@ Routing is an important function that allows multiple Agents to work together to
The Routing feature is the core technology used by BotSharp to manage multiple Agents. BotSharp has a built-in intelligent Agent called `Router`. When you enable this function, all user requests will be pre-processed by the Router to determine which Agent to distribute the request to for processing. The advantage of Routing technology is that it can isolate different Agents and allow them to work together to achieve the user's goals. The adoption of `Routing` ensures that Agent can be scalable, flexible and robust enough in enterprise applications.
![routing with reasoning](./assets/routing-redirection.png)
## Reasoner
For simple questions raised by users, the ordinary routing function can already handle it. However, for the scenario where the user has a long description and needs to disassemble the task, ordinary routing cannot handle it. At this time, the `Reasoning` feature needs to be turned on, and LLM will respond according to the problem. The complexity is broken down into different small tasks. These small tasks can be processed by the corresponding Agent. During the processing process, the Router will constantly adjust the next step plan to deal with the different results returned by the Agent.
![routing with reasoning](./assets/routing-reasoner.png)
For more **Routing** related information, please go to [Agent Routing](../agent/router.md).

View file

@ -7,6 +7,9 @@ namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
#if !DEBUG
[MemoryCache(10 * 60)]
#endif
public async Task<List<Agent>> GetAgents()
{
var query = from a in _db.Agents

View file

@ -34,20 +34,26 @@ public class RouteToAgentFn : IFunctionCallback
}
else
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var targetAgent = db.Agents.FirstOrDefault(x => x.Name.ToLower() == args.AgentName.ToLower());
if (targetAgent == null)
{
message.ExecutionData = JsonSerializer.Deserialize<JsonElement>(message.FunctionArgs);
return false;
}
var missingfield = HasMissingRequiredField(message, out var agentId);
if (missingfield && message.CurrentAgentId != agentId)
{
// Stack original Agent
_context.Push(targetAgent.Id);
message.CurrentAgentId = agentId;
}
else
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var record = db.Agents.FirstOrDefault(x => x.Name.ToLower() == args.AgentName.ToLower());
if (record != null)
{
message.CurrentAgentId = record.Id;
message.ExecutionResult = $"Routing to {args.AgentName}";
}
message.CurrentAgentId = targetAgent.Id;
message.ExecutionResult = $"Routing to {args.AgentName}";
}
}

View file

@ -18,9 +18,10 @@ public partial class RoutingService
var content = $"{prompt} Response must be in JSON format {responseFormat}";
var state = _services.GetRequiredService<IConversationStateService>();
RoleDialogModel response = default;
var args = new FunctionCallFromLlm();
if (_settings.UseTextCompletion)
{
var completion = CompletionProvider.GetTextCompletion(_services,
@ -37,47 +38,58 @@ public partial class RoutingService
provider: _settings.Provider,
model: _settings.Model);
response = completion.GetChatCompletions(_routerInstance.Router, new List<RoleDialogModel>
int retryCount = 0;
while (retryCount < 3)
{
new RoleDialogModel(AgentRole.User, content)
});
try
{
response = completion.GetChatCompletions(_routerInstance.Router, new List<RoleDialogModel>
{
new RoleDialogModel(AgentRole.User, content)
});
var pattern = @"\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\}";
response.Content = Regex.Match(response.Content, pattern).Value;
args = JsonSerializer.Deserialize<FunctionCallFromLlm>(response.Content);
break;
}
catch (Exception ex)
{
_logger.LogError($"{ex.Message}: {response.Content}");
args.Function = "response_to_user";
args.Answer = ex.Message;
args.AgentName = _settings.RouterName;
content += "\r\nPlease response in JSON format.";
}
finally
{
retryCount++;
}
}
}
var args = new FunctionCallFromLlm();
try
{
#if DEBUG
Console.WriteLine(response.Content, Color.Gray);
Console.WriteLine(response.Content, Color.Gray);
#else
_logger.LogInformation(response.Content);
_logger.LogInformation(response.Content);
#endif
var pattern = @"\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\}";
response.Content = Regex.Match(response.Content, pattern).Value;
args = JsonSerializer.Deserialize<FunctionCallFromLlm>(response.Content);
// Sometimes it populate malformed Function in Agent name
if (!string.IsNullOrEmpty(args.Function) && args.Function == args.AgentName)
{
args.Function = "route_to_agent";
_logger.LogWarning($"Captured LLM malformed response");
}
// Another case of malformed response
var agentService = _services.GetRequiredService<IAgentService>();
var agents = await agentService.GetAgents();
if (string.IsNullOrEmpty(args.AgentName) && agents.Select(x => x.Name).Contains(args.Function))
{
args.AgentName = args.Function;
args.Function = "route_to_agent";
_logger.LogWarning($"Captured LLM malformed response");
}
}
catch (Exception ex)
// Sometimes it populate malformed Function in Agent name
if (!string.IsNullOrEmpty(args.Function) && args.Function == args.AgentName)
{
_logger.LogError($"{ex.Message}: {response.Content}");
args.Function = "response_to_user";
args.Answer = ex.Message;
args.AgentName = _settings.RouterName;
args.Function = "route_to_agent";
_logger.LogWarning($"Captured LLM malformed response");
}
// Another case of malformed response
var agentService = _services.GetRequiredService<IAgentService>();
var agents = await agentService.GetAgents();
if (string.IsNullOrEmpty(args.AgentName) && agents.Select(x => x.Name).Contains(args.Function))
{
args.AgentName = args.Function;
args.Function = "route_to_agent";
_logger.LogWarning($"Captured LLM malformed response");
}
if (args.Arguments != null)

View file

@ -62,7 +62,7 @@ public partial class RoutingService
response.Role = recursiveResponse.Role;
response.Content = recursiveResponse.Content;
response.ExecutionResult = recursiveResponse.ExecutionResult;
response.ExecutionData = recursiveResponse.ExecutionData;
response.ExecutionData = recursiveResponse.ExecutionData ?? response.ExecutionData;
response.StopCompletion = recursiveResponse.StopCompletion;
}
}