mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 19:52:10 +00:00
Codex-based code review
This commit is contained in:
parent
c827ba2cd8
commit
c13255fe77
@ -2,6 +2,7 @@ using System.Globalization;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools;
|
using AIStudio.Tools;
|
||||||
@ -79,6 +80,18 @@ public sealed record ChatThread
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DataSourceSecurity DataSecurity { get; set; } = DataSourceSecurity.NOT_SPECIFIED;
|
public DataSourceSecurity DataSecurity { get; set; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum confidence required for providers that continue this chat after a tool returned sensitive data.
|
||||||
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
|
public ConfidenceLevel RequiredProviderConfidence { get; private set; } = ConfidenceLevel.NONE;
|
||||||
|
|
||||||
|
public void RequireProviderConfidence(ConfidenceLevel minimumProviderConfidence)
|
||||||
|
{
|
||||||
|
if (minimumProviderConfidence > this.RequiredProviderConfidence)
|
||||||
|
this.RequiredProviderConfidence = minimumProviderConfidence;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -27,6 +27,17 @@ public static class ChatThreadExtensions
|
|||||||
if (chatThread is null)
|
if (chatThread is null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
var settingsManager = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
|
||||||
|
var providerConfidence = provider switch
|
||||||
|
{
|
||||||
|
IProvider p => p.Provider.GetConfidence(settingsManager).Level,
|
||||||
|
AIStudio.Settings.Provider p => p.UsedLLMProvider.GetConfidence(settingsManager).Level,
|
||||||
|
|
||||||
|
_ => ConfidenceLevel.UNKNOWN,
|
||||||
|
};
|
||||||
|
if (providerConfidence < chatThread.RequiredProviderConfidence)
|
||||||
|
return false;
|
||||||
|
|
||||||
// The chat thread is available, but the data security is not specified.
|
// The chat thread is available, but the data security is not specified.
|
||||||
// Means, we never used RAG or RAG was enabled, but no data sources were selected.
|
// Means, we never used RAG or RAG was enabled, but no data sources were selected.
|
||||||
// That's fine as well:
|
// That's fine as well:
|
||||||
@ -36,7 +47,6 @@ public static class ChatThreadExtensions
|
|||||||
//
|
//
|
||||||
// Is the provider trusted for data-source security checks?
|
// Is the provider trusted for data-source security checks?
|
||||||
//
|
//
|
||||||
var settingsManager = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
|
|
||||||
var isTrustedProvider = provider switch
|
var isTrustedProvider = provider switch
|
||||||
{
|
{
|
||||||
IProvider p => p.IsTrustedForDataSourceSecurityChecks(settingsManager),
|
IProvider p => p.IsTrustedForDataSourceSecurityChecks(settingsManager),
|
||||||
|
|||||||
@ -1083,48 +1083,54 @@ public abstract class BaseProvider : IProvider, ISecretId
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ShowToolRuntimeStatusAsync(toolCalls
|
try
|
||||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Function.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Function.Name));
|
|
||||||
|
|
||||||
internalMessages.Add(new AssistantToolCallMessage
|
|
||||||
{
|
{
|
||||||
Content = responseMessage.Content,
|
await ShowToolRuntimeStatusAsync(toolCalls
|
||||||
ToolCalls = toolCalls,
|
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Function.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Function.Name));
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var toolCall in toolCalls)
|
internalMessages.Add(new AssistantToolCallMessage
|
||||||
{
|
|
||||||
if (toolCallCount >= ToolSelectionRules.MAX_TOOL_CALLS)
|
|
||||||
{
|
{
|
||||||
var finalResponseInstruction = ToolSelectionRules.GetMaxToolCallsFinalResponseInstruction();
|
Content = responseMessage.Content,
|
||||||
|
ToolCalls = toolCalls,
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var toolCall in toolCalls)
|
||||||
|
{
|
||||||
|
if (toolCallCount >= ToolSelectionRules.MAX_TOOL_CALLS)
|
||||||
|
{
|
||||||
|
var finalResponseInstruction = ToolSelectionRules.GetMaxToolCallsFinalResponseInstruction();
|
||||||
|
internalMessages.Add(new ToolResultMessage
|
||||||
|
{
|
||||||
|
Content = finalResponseInstruction,
|
||||||
|
ToolCallId = toolCall.Id,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolCallCount++;
|
||||||
|
var (toolContent, trace, requiredProviderConfidence) = await toolExecutor.ExecuteAsync(
|
||||||
|
toolCall.Id,
|
||||||
|
toolCall.Function.Name,
|
||||||
|
toolCall.Function.Arguments,
|
||||||
|
runnableTools,
|
||||||
|
this.Provider.GetConfidence(settingsManager).Level,
|
||||||
|
toolCallCount,
|
||||||
|
token);
|
||||||
|
|
||||||
|
chatThread.RequireProviderConfidence(requiredProviderConfidence);
|
||||||
|
currentAssistantContent?.ToolInvocations.Add(trace);
|
||||||
internalMessages.Add(new ToolResultMessage
|
internalMessages.Add(new ToolResultMessage
|
||||||
{
|
{
|
||||||
Content = finalResponseInstruction,
|
Content = toolContent,
|
||||||
ToolCallId = toolCall.Id,
|
ToolCallId = toolCall.Id,
|
||||||
});
|
});
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toolCallCount++;
|
|
||||||
var (toolContent, trace) = await toolExecutor.ExecuteAsync(
|
|
||||||
toolCall.Id,
|
|
||||||
toolCall.Function.Name,
|
|
||||||
toolCall.Function.Arguments,
|
|
||||||
runnableTools,
|
|
||||||
this.Provider.GetConfidence(settingsManager).Level,
|
|
||||||
toolCallCount,
|
|
||||||
token);
|
|
||||||
|
|
||||||
currentAssistantContent?.ToolInvocations.Add(trace);
|
|
||||||
internalMessages.Add(new ToolResultMessage
|
|
||||||
{
|
|
||||||
Content = toolContent,
|
|
||||||
ToolCallId = toolCall.Id,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
if (currentAssistantContent is not null)
|
{
|
||||||
await currentAssistantContent.StreamingEvent();
|
await ResetToolRuntimeStatusAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -227,8 +227,10 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
|||||||
{
|
{
|
||||||
await foreach (var content in this.StreamResponsesWithLocalTools(
|
await foreach (var content in this.StreamResponsesWithLocalTools(
|
||||||
chatModel,
|
chatModel,
|
||||||
|
chatThread,
|
||||||
baseInput,
|
baseInput,
|
||||||
apiParameters,
|
apiParameters,
|
||||||
|
providerTools,
|
||||||
runnableTools,
|
runnableTools,
|
||||||
toolExecutor,
|
toolExecutor,
|
||||||
currentAssistantContent,
|
currentAssistantContent,
|
||||||
@ -308,8 +310,10 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
|||||||
|
|
||||||
private async IAsyncEnumerable<ContentStreamChunk> StreamResponsesWithLocalTools(
|
private async IAsyncEnumerable<ContentStreamChunk> StreamResponsesWithLocalTools(
|
||||||
Model chatModel,
|
Model chatModel,
|
||||||
|
ChatThread chatThread,
|
||||||
IList<object> baseInput,
|
IList<object> baseInput,
|
||||||
IDictionary<string, object> apiParameters,
|
IDictionary<string, object> apiParameters,
|
||||||
|
IList<object> providerTools,
|
||||||
IReadOnlyList<(ToolDefinition Definition, IToolImplementation Implementation)> runnableTools,
|
IReadOnlyList<(ToolDefinition Definition, IToolImplementation Implementation)> runnableTools,
|
||||||
ToolExecutor toolExecutor,
|
ToolExecutor toolExecutor,
|
||||||
ContentText? currentAssistantContent,
|
ContentText? currentAssistantContent,
|
||||||
@ -317,9 +321,16 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
|||||||
ConfidenceLevel providerConfidence,
|
ConfidenceLevel providerConfidence,
|
||||||
[EnumeratorCancellation] CancellationToken token)
|
[EnumeratorCancellation] CancellationToken token)
|
||||||
{
|
{
|
||||||
var providerTools = runnableTools
|
var localProviderTools = runnableTools
|
||||||
.Select(x => (object)ProviderToolAdapters.ToResponsesTool(x.Definition))
|
.Select(x => (object)ProviderToolAdapters.ToResponsesTool(x.Definition))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
var localFunctionNames = runnableTools
|
||||||
|
.Select(x => x.Definition.Function.Name)
|
||||||
|
.ToHashSet(StringComparer.Ordinal);
|
||||||
|
var effectiveProviderTools = providerTools
|
||||||
|
.Where(x => x is not ProviderTool providerTool || !localFunctionNames.Contains(providerTool.Type))
|
||||||
|
.Concat(localProviderTools)
|
||||||
|
.ToList();
|
||||||
// Preserve every output item required to continue the response, including
|
// Preserve every output item required to continue the response, including
|
||||||
// reasoning items emitted alongside function calls.
|
// reasoning items emitted alongside function calls.
|
||||||
var internalItems = new List<object>();
|
var internalItems = new List<object>();
|
||||||
@ -344,7 +355,7 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
|||||||
Input = requestInput,
|
Input = requestInput,
|
||||||
Stream = false,
|
Stream = false,
|
||||||
Store = false,
|
Store = false,
|
||||||
Tools = finalResponseRequired ? [] : providerTools,
|
Tools = finalResponseRequired ? [] : effectiveProviderTools,
|
||||||
AdditionalApiParameters = apiParameters,
|
AdditionalApiParameters = apiParameters,
|
||||||
};
|
};
|
||||||
var response = await this.ExecuteResponsesRequest(requestDto, requestedSecret, token);
|
var response = await this.ExecuteResponsesRequest(requestDto, requestedSecret, token);
|
||||||
@ -381,45 +392,51 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ShowToolRuntimeStatusAsync(currentAssistantContent, functionCalls
|
try
|
||||||
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Name));
|
|
||||||
|
|
||||||
foreach (var outputItem in response.Output)
|
|
||||||
internalItems.Add(outputItem);
|
|
||||||
|
|
||||||
foreach (var functionCall in functionCalls)
|
|
||||||
{
|
{
|
||||||
if (toolCallCount >= ToolSelectionRules.MAX_TOOL_CALLS)
|
await ShowToolRuntimeStatusAsync(currentAssistantContent, functionCalls
|
||||||
|
.Select(x => runnableTools.FirstOrDefault(tool => tool.Definition.Function.Name.Equals(x.Name, StringComparison.Ordinal)).Implementation?.GetDisplayName() ?? x.Name));
|
||||||
|
|
||||||
|
foreach (var outputItem in response.Output)
|
||||||
|
internalItems.Add(outputItem);
|
||||||
|
|
||||||
|
foreach (var functionCall in functionCalls)
|
||||||
{
|
{
|
||||||
var finalResponseInstruction = ToolSelectionRules.GetMaxToolCallsFinalResponseInstruction();
|
if (toolCallCount >= ToolSelectionRules.MAX_TOOL_CALLS)
|
||||||
|
{
|
||||||
|
var finalResponseInstruction = ToolSelectionRules.GetMaxToolCallsFinalResponseInstruction();
|
||||||
|
internalItems.Add(new ResponsesFunctionCallOutputItem
|
||||||
|
{
|
||||||
|
CallId = functionCall.CallId,
|
||||||
|
Output = finalResponseInstruction,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolCallCount++;
|
||||||
|
var (toolContent, trace, requiredProviderConfidence) = await toolExecutor.ExecuteAsync(
|
||||||
|
functionCall.CallId,
|
||||||
|
functionCall.Name,
|
||||||
|
functionCall.Arguments,
|
||||||
|
runnableTools,
|
||||||
|
providerConfidence,
|
||||||
|
toolCallCount,
|
||||||
|
token);
|
||||||
|
|
||||||
|
chatThread.RequireProviderConfidence(requiredProviderConfidence);
|
||||||
|
currentAssistantContent?.ToolInvocations.Add(trace);
|
||||||
internalItems.Add(new ResponsesFunctionCallOutputItem
|
internalItems.Add(new ResponsesFunctionCallOutputItem
|
||||||
{
|
{
|
||||||
CallId = functionCall.CallId,
|
CallId = functionCall.CallId,
|
||||||
Output = finalResponseInstruction,
|
Output = toolContent,
|
||||||
});
|
});
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toolCallCount++;
|
|
||||||
var (toolContent, trace) = await toolExecutor.ExecuteAsync(
|
|
||||||
functionCall.CallId,
|
|
||||||
functionCall.Name,
|
|
||||||
functionCall.Arguments,
|
|
||||||
runnableTools,
|
|
||||||
providerConfidence,
|
|
||||||
toolCallCount,
|
|
||||||
token);
|
|
||||||
|
|
||||||
currentAssistantContent?.ToolInvocations.Add(trace);
|
|
||||||
internalItems.Add(new ResponsesFunctionCallOutputItem
|
|
||||||
{
|
|
||||||
CallId = functionCall.CallId,
|
|
||||||
Output = toolContent,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
if (currentAssistantContent is not null)
|
{
|
||||||
await currentAssistantContent.StreamingEvent();
|
await ResetToolRuntimeStatusAsync(currentAssistantContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -136,7 +136,8 @@ public sealed class ReadWebPageTool(WebPageRetrievalService webPageRetrievalServ
|
|||||||
|
|
||||||
return new ToolExecutionResult
|
return new ToolExecutionResult
|
||||||
{
|
{
|
||||||
JsonContent = BuildModelContent(page, extractedPage, retrievedPage.RetrievedAtUtc, markdown, originalContentCharacters, contentTruncated, warnings)
|
JsonContent = BuildModelContent(page, extractedPage, retrievedPage.RetrievedAtUtc, markdown, originalContentCharacters, contentTruncated, warnings),
|
||||||
|
RequiredProviderConfidence = retrievedPage.RequiredProviderConfidence,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,8 @@ public sealed class ToolExecutionResult
|
|||||||
|
|
||||||
public JsonNode? JsonContent { get; init; }
|
public JsonNode? JsonContent { get; init; }
|
||||||
|
|
||||||
|
public ConfidenceLevel RequiredProviderConfidence { get; init; } = ConfidenceLevel.NONE;
|
||||||
|
|
||||||
public string ToModelContent()
|
public string ToModelContent()
|
||||||
{
|
{
|
||||||
if (this.JsonContent is not null)
|
if (this.JsonContent is not null)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace AIStudio.Tools.ToolCallingSystem;
|
|||||||
|
|
||||||
public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogger<ToolExecutor> logger)
|
public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogger<ToolExecutor> logger)
|
||||||
{
|
{
|
||||||
public async Task<(string Content, ToolInvocationTrace Trace)> ExecuteAsync(
|
public async Task<(string Content, ToolInvocationTrace Trace, ConfidenceLevel RequiredProviderConfidence)> ExecuteAsync(
|
||||||
string toolCallId,
|
string toolCallId,
|
||||||
string toolName,
|
string toolName,
|
||||||
string argumentsJson,
|
string argumentsJson,
|
||||||
@ -49,7 +49,7 @@ public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogge
|
|||||||
StatusMessage = "Tool is not available in the current context.",
|
StatusMessage = "Tool is not available in the current context.",
|
||||||
Arguments = formattedArguments,
|
Arguments = formattedArguments,
|
||||||
Result = error,
|
Result = error,
|
||||||
});
|
}, ConfidenceLevel.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
var definition = runnableTool.Definition;
|
var definition = runnableTool.Definition;
|
||||||
@ -83,7 +83,7 @@ public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogge
|
|||||||
implementation.FormatTraceResult(result.ToModelContent()),
|
implementation.FormatTraceResult(result.ToModelContent()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (resultModelContent, toolInvocationTrace);
|
return (resultModelContent, toolInvocationTrace, result.RequiredProviderConfidence);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@ -106,7 +106,7 @@ public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogge
|
|||||||
Result = exception.Message,
|
Result = exception.Message,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (exception.Message, toolInvocationTrace);
|
return (exception.Message, toolInvocationTrace, ConfidenceLevel.NONE);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ public sealed class ToolExecutor(ToolSettingsService toolSettingsService, ILogge
|
|||||||
Result = error,
|
Result = error,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (error, toolInvocationTrace);
|
return (error, toolInvocationTrace, ConfidenceLevel.NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ public sealed class WebPageRetrievalService(HTMLParser htmlParser)
|
|||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var triedOsSso = false;
|
var triedOsSso = false;
|
||||||
|
var requiredProviderConfidence = ConfidenceLevel.NONE;
|
||||||
HTMLParserWebPage page;
|
HTMLParserWebPage page;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -21,7 +22,14 @@ public sealed class WebPageRetrievalService(HTMLParser htmlParser)
|
|||||||
url,
|
url,
|
||||||
token,
|
token,
|
||||||
options.TimeoutSeconds,
|
options.TimeoutSeconds,
|
||||||
async (candidateUrl, validationToken) => await ResolveValidatedUrlAddressesAsync(candidateUrl, options, validationToken),
|
async (candidateUrl, validationToken) =>
|
||||||
|
{
|
||||||
|
var addresses = await ResolveValidatedUrlAddressesAsync(candidateUrl, options, validationToken);
|
||||||
|
if (addresses.Any(IsNonPublicAddress))
|
||||||
|
requiredProviderConfidence = ConfidenceLevel.HIGH;
|
||||||
|
|
||||||
|
return addresses;
|
||||||
|
},
|
||||||
MAX_RESPONSE_BYTES,
|
MAX_RESPONSE_BYTES,
|
||||||
options.UseOsSso ? ExternalWebAuthenticationMode.OS_DEFAULT_CREDENTIALS : ExternalWebAuthenticationMode.NONE,
|
options.UseOsSso ? ExternalWebAuthenticationMode.OS_DEFAULT_CREDENTIALS : ExternalWebAuthenticationMode.NONE,
|
||||||
shouldUseDefaultCredentials: (candidateUrl, addresses) =>
|
shouldUseDefaultCredentials: (candidateUrl, addresses) =>
|
||||||
@ -58,6 +66,7 @@ public sealed class WebPageRetrievalService(HTMLParser htmlParser)
|
|||||||
Page = page,
|
Page = page,
|
||||||
ExtractedPage = WebPageContentExtractor.Extract(htmlParser, page.Document, page.FinalUrl),
|
ExtractedPage = WebPageContentExtractor.Extract(htmlParser, page.Document, page.FinalUrl),
|
||||||
RetrievedAtUtc = DateTimeOffset.UtcNow,
|
RetrievedAtUtc = DateTimeOffset.UtcNow,
|
||||||
|
RequiredProviderConfidence = requiredProviderConfidence,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,4 +254,6 @@ public sealed class RetrievedWebPage
|
|||||||
public required ExtractedWebPage ExtractedPage { get; init; }
|
public required ExtractedWebPage ExtractedPage { get; init; }
|
||||||
|
|
||||||
public required DateTimeOffset RetrievedAtUtc { get; init; }
|
public required DateTimeOffset RetrievedAtUtc { get; init; }
|
||||||
|
|
||||||
|
public ConfidenceLevel RequiredProviderConfidence { get; init; } = ConfidenceLevel.NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,9 +41,9 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.NET.ILLink.Tasks": {
|
"Microsoft.NET.ILLink.Tasks": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[9.0.12, )",
|
"requested": "[9.0.18, )",
|
||||||
"resolved": "9.0.12",
|
"resolved": "9.0.18",
|
||||||
"contentHash": "StA3kyImQHqDo8A8ZHaSxgASbEuT5UIqgeCvK5SzUPj//xE1QSys421J9pEs4cYuIVwq7CJvWSKxtyH7aPr1LA=="
|
"contentHash": "ztGVXB28bi8SeplFmAx+4MkqP1ieA4UNzj/M3qyyz5tLa37Ln8x8LuaXdxzzoOdaucjQBKXSdCMFSbpQaNGIEg=="
|
||||||
},
|
},
|
||||||
"MudBlazor": {
|
"MudBlazor": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
@ -212,6 +212,6 @@
|
|||||||
"type": "Project"
|
"type": "Project"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"net9.0/win-x64": {}
|
"net9.0/osx-arm64": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
# v26.7.4, build 249 (2026-07-xx xx:xx UTC)
|
# v26.7.4, build 249 (2026-07-xx xx:xx UTC)
|
||||||
|
|
||||||
|
- Added model-driven Web Search and Read Web Page tools for supported AI models.
|
||||||
- Added organization-wide management for tool availability and all Web Search and Read Web Page settings.
|
- Added organization-wide management for tool availability and all Web Search and Read Web Page settings.
|
||||||
|
|||||||
@ -78,7 +78,7 @@ Example:
|
|||||||
"demoLabel"
|
"demoLabel"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"policyInstructions": "Use this tool only when the user asks for current weather conditions.",
|
"systemPromptInstructions": "Use this tool only when the user asks for current weather conditions.",
|
||||||
"function": {
|
"function": {
|
||||||
"name": "get_current_weather",
|
"name": "get_current_weather",
|
||||||
"descriptionForLLM": "Get the current weather in a given location.",
|
"descriptionForLLM": "Get the current weather in a given location.",
|
||||||
@ -116,7 +116,7 @@ Example:
|
|||||||
|
|
||||||
Use stable lower-case IDs with underscores. Keep `id`, `implementationKey`, and `function.name` identical unless there is a clear compatibility reason not to.
|
Use stable lower-case IDs with underscores. Keep `id`, `implementationKey`, and `function.name` identical unless there is a clear compatibility reason not to.
|
||||||
|
|
||||||
Keep `function.descriptionForLLM` focused on what the tool does. This value is mapped to the provider's function `description` field and is only shown to the LLM. Put sequencing rules, answer-format guidance, or other behavior instructions in `policyInstructions`. When runnable tools are selected, their non-empty policy text is combined centrally and appended to the effective system prompt.
|
Keep `function.descriptionForLLM` focused on what the tool does. This value is mapped to the provider's function `description` field and is only shown to the LLM. Put sequencing rules, answer-format guidance, or other behavior instructions in `systemPromptInstructions`. When runnable tools are selected, their non-empty policy text is combined centrally and appended to the effective system prompt.
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
@ -189,6 +189,8 @@ Use `ValidateConfigurationAsync` when a setting needs more than "required field
|
|||||||
|
|
||||||
Use `SensitiveTraceArgumentNames` for model-provided arguments that must not be shown in tool traces. Do not return secrets in `TextContent`, `JsonContent`, exception messages, logs, or trace formatting.
|
Use `SensitiveTraceArgumentNames` for model-provided arguments that must not be shown in tool traces. Do not return secrets in `TextContent`, `JsonContent`, exception messages, logs, or trace formatting.
|
||||||
|
|
||||||
|
When a tool returns data that future messages must only send to providers at or above a specific confidence level, set `ToolExecutionResult.RequiredProviderConfidence`. AI Studio persists the highest requirement reached by the chat and applies it to later provider checks.
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
Treat model-provided tool arguments as untrusted input.
|
Treat model-provided tool arguments as untrusted input.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user