mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-04 20:47:22 +00:00
Added a way to read what the AI received from your sources (#1100)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
e0d8e18f34
commit
cbc4ce5413
229 files changed
+12739
-1269
No files matched your search
@@ -1,6 +1,7 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Tools.RAG;
|
||||
|
||||
namespace AIStudio.Tools.ToolCallingSystem.Harness;
|
||||
|
||||
@@ -38,6 +39,7 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
var toolCallCount = 0;
|
||||
var toolResultCharacterCount = 0L;
|
||||
var toolSources = new List<Source>();
|
||||
var toolPassages = new List<SourcePassage>();
|
||||
var hasStreamedTextBefore = false;
|
||||
var isFirstRound = true;
|
||||
|
||||
@@ -111,11 +113,15 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
|
||||
//
|
||||
// No outcome means the round failed: the request errored out, or the stream ended
|
||||
// mid-sentence. Either way the adapter has already reported it.
|
||||
// mid-sentence. Either way the adapter has already reported it. The answer keeps what
|
||||
// was written so far, and with it what the tools of the earlier rounds contributed:
|
||||
//
|
||||
if (round is null)
|
||||
{
|
||||
await context.ResetToolRuntimeStatusAsync();
|
||||
if (toolSources.Count > 0 || toolPassages.Count > 0)
|
||||
yield return WithWhatTheToolsContributed(string.Empty);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -133,7 +139,7 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
var unanswerable = context.ToolExecutor.CreateInvalidToolCallResult(string.Empty, toolCallCount);
|
||||
await context.AddToolInvocationAsync(unanswerable.Trace);
|
||||
await context.ResetToolRuntimeStatusAsync();
|
||||
yield return new ContentStreamChunk(unanswerable.Content, [..toolSources]);
|
||||
yield return WithWhatTheToolsContributed(unanswerable.Content);
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -146,10 +152,7 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
// the tools contributed. An empty chunk is how sources travel on their own; the
|
||||
// streaming paths of the providers attach their annotations the same way.
|
||||
//
|
||||
yield return new ContentStreamChunk(
|
||||
roundAnswered ? string.Empty : NO_ANSWER_AFTER_LIMIT,
|
||||
[..toolSources]);
|
||||
|
||||
yield return WithWhatTheToolsContributed(roundAnswered ? string.Empty : NO_ANSWER_AFTER_LIMIT);
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -158,13 +161,13 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
await context.ResetToolRuntimeStatusAsync();
|
||||
if (roundAnswered)
|
||||
{
|
||||
yield return new ContentStreamChunk(string.Empty, [..toolSources]);
|
||||
yield return WithWhatTheToolsContributed(string.Empty);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (toolCallCount > 0)
|
||||
{
|
||||
yield return new ContentStreamChunk(NO_ANSWER_AFTER_TOOL_CALL, [..toolSources]);
|
||||
yield return WithWhatTheToolsContributed(NO_ANSWER_AFTER_TOOL_CALL);
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -239,6 +242,7 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
context.ChatThread.RequireOutboundDataRestriction(outcome.RequiredOutboundDataRestriction);
|
||||
context.ChatThread.RuntimeWebAddressesFromTools.UnionWith(outcome.ReturnedWebAddresses);
|
||||
toolSources.MergeSources(outcome.Sources);
|
||||
toolPassages.MergePassages(outcome.Passages);
|
||||
await context.AddToolInvocationAsync(outcome.Trace);
|
||||
|
||||
// A blocked call counts as a failure towards the model as much as an errored
|
||||
@@ -252,6 +256,13 @@ public sealed class ToolCallingLoop(ILogger<ToolCallingLoop> logger) : IToolCall
|
||||
await context.ResetToolRuntimeStatusAsync();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// What the tools contributed goes out with the last chunk of the conversation: the sources,
|
||||
// and the passages the model received from them. One way out for every way the conversation
|
||||
// ends, so none of them hands over the sources and forgets the passages.
|
||||
//
|
||||
ContentStreamChunk WithWhatTheToolsContributed(string content) => new(content, [..toolSources]) { Passages = [..toolPassages] };
|
||||
}
|
||||
|
||||
private static string GetDisplayName(ToolCallingLoopContext context, string toolName) => context.RunnableTools
|
||||
|
||||
Reference in new issue
Block a user