mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-11-23 12:10:21 +00:00
Standardized AdditionalApiParameters type across providers to use IDictionary<string, string> and improved JSON parsing reliability.
This commit is contained in:
parent
17bc2f3e46
commit
955f212c57
@ -135,7 +135,7 @@
|
|||||||
<MudDivider />
|
<MudDivider />
|
||||||
<MudCollapse Expanded="@this.showExpertProviderSettings">
|
<MudCollapse Expanded="@this.showExpertProviderSettings">
|
||||||
<MudJustifiedText>@T("Please be aware: This is for experts only. You are responsible for verifying the correctness of the additional parameters you provide to the API call.")</MudJustifiedText>
|
<MudJustifiedText>@T("Please be aware: This is for experts only. You are responsible for verifying the correctness of the additional parameters you provide to the API call.")</MudJustifiedText>
|
||||||
<MudJustifiedText>@T("By default, AI Studio uses the OpenAI-compatible chat/completions API, provided it is supported by the underlying service.")</MudJustifiedText>
|
<MudJustifiedText>@T("By default, AI Studio uses the OpenAI-compatible chat/completions API, provided it is supported by the underlying service and model.")</MudJustifiedText>
|
||||||
<MudTextField T="string" Label=@T("Additional API parameters") Variant="Variant.Outlined" Lines="3" AutoGrow="true" HelperText=@T("Add the parameters in proper json formatting. E.g. \"temperature\": 0.5. Trailing commas have to be removed.") HelperTextOnFocus="true " @bind-Value="@ExpertProviderApiParameters" OnBlur="@OnInputChangeExpertSettings"></MudTextField>
|
<MudTextField T="string" Label=@T("Additional API parameters") Variant="Variant.Outlined" Lines="3" AutoGrow="true" HelperText=@T("Add the parameters in proper json formatting. E.g. \"temperature\": 0.5. Trailing commas have to be removed.") HelperTextOnFocus="true " @bind-Value="@ExpertProviderApiParameters" OnBlur="@OnInputChangeExpertSettings"></MudTextField>
|
||||||
</MudCollapse>
|
</MudCollapse>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|||||||
@ -20,6 +20,5 @@ public readonly record struct ChatRequest(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ public sealed class ProviderAnthropic() : BaseProvider("https://api.anthropic.co
|
|||||||
}).ToList()],
|
}).ToList()],
|
||||||
|
|
||||||
System = chatThread.PrepareSystemPrompt(settingsManager, chatThread),
|
System = chatThread.PrepareSystemPrompt(settingsManager, chatThread),
|
||||||
MaxTokens = apiParameters["max_tokens"] as int? ?? 4_096,
|
MaxTokens = int.TryParse(apiParameters["max_tokens"], out int parsed) ? parsed : 4_096,
|
||||||
|
|
||||||
// Right now, we only support streaming completions:
|
// Right now, we only support streaming completions:
|
||||||
Stream = true,
|
Stream = true,
|
||||||
|
|||||||
@ -530,14 +530,17 @@ public abstract class BaseProvider : IProvider, ISecretId
|
|||||||
/// optionally merging additional parameters and removing specific keys.
|
/// optionally merging additional parameters and removing specific keys.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="additionalUserProvidedParameters">A JSON string (without surrounding braces) containing the API parameters to be parsed.</param>
|
/// <param name="additionalUserProvidedParameters">A JSON string (without surrounding braces) containing the API parameters to be parsed.</param>
|
||||||
/// <param name="defaultParameters">Optional additional parameters to merge into the result. These will overwrite existing keys.</param>
|
|
||||||
/// <param name="keysToRemove">Optional list of keys to remove from the final dictionary (case-insensitive). stream, model and messages are removed by default.</param>
|
/// <param name="keysToRemove">Optional list of keys to remove from the final dictionary (case-insensitive). stream, model and messages are removed by default.</param>
|
||||||
protected Dictionary<string, object?> ParseApiParameters(
|
protected IDictionary<string, string> ParseApiParameters(
|
||||||
string additionalUserProvidedParameters,
|
string additionalUserProvidedParameters,
|
||||||
IEnumerable<string>? keysToRemove = null)
|
IEnumerable<string>? keysToRemove = null)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// we need to remove line breaks from the JSON string otherwise the server might have problems with parsing the call
|
||||||
|
var withoutLineBreak = additionalUserProvidedParameters.Replace("\n", string.Empty);
|
||||||
|
|
||||||
var json = $"{{{additionalUserProvidedParameters}}}";
|
var json = $"{{{withoutLineBreak}}}";
|
||||||
var jsonDoc = JsonSerializer.Deserialize<JsonElement>(json, JSON_SERIALIZER_OPTIONS);
|
var jsonDoc = JsonSerializer.Deserialize<JsonElement>(json, JSON_SERIALIZER_OPTIONS);
|
||||||
var dict = this.ConvertToDictionary(jsonDoc);
|
var dict = this.ConvertToDictionary(jsonDoc);
|
||||||
|
|
||||||
@ -554,25 +557,19 @@ public abstract class BaseProvider : IProvider, ISecretId
|
|||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
catch (JsonException ex)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid JSON in additionalUserProvidedParameters", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Dictionary<string, object?> ConvertToDictionary(JsonElement element)
|
private IDictionary<string, string> ConvertToDictionary(JsonElement element)
|
||||||
{
|
{
|
||||||
return element.EnumerateObject()
|
return element.EnumerateObject()
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
p => p.Name,
|
p => p.Name,
|
||||||
p => this.ConvertJsonElement(p.Value)
|
p => p.Value.GetRawText()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private object? ConvertJsonElement(JsonElement element) => element.ValueKind switch
|
|
||||||
{
|
|
||||||
JsonValueKind.String => element.GetString(),
|
|
||||||
JsonValueKind.Number => element.TryGetInt32(out var i) ? (object)i : element.GetDouble(),
|
|
||||||
JsonValueKind.True => true,
|
|
||||||
JsonValueKind.False => false,
|
|
||||||
JsonValueKind.Object => this.ConvertToDictionary(element),
|
|
||||||
JsonValueKind.Array => element.EnumerateArray().Select(this.ConvertJsonElement).ToList(),
|
|
||||||
JsonValueKind.Null => null,
|
|
||||||
_ => element.ToString()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
@ -15,6 +15,5 @@ public readonly record struct ChatRequest(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -15,7 +15,5 @@ public readonly record struct ChatRequest(
|
|||||||
bool Stream
|
bool Stream
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
[JsonExtensionData]
|
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -18,6 +18,5 @@ public readonly record struct ChatRequest(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -19,6 +19,5 @@ public readonly record struct ChatRequest(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ public sealed class ProviderMistral() : BaseProvider("https://api.mistral.ai/v1/
|
|||||||
|
|
||||||
// Right now, we only support streaming completions:
|
// Right now, we only support streaming completions:
|
||||||
Stream = true,
|
Stream = true,
|
||||||
SafePrompt = apiParameters["safe_prompt"] as bool? ?? false,
|
SafePrompt = bool.TryParse(apiParameters["safe_prompt"], out bool safePrompt) && safePrompt,
|
||||||
AdditionalApiParameters = apiParameters
|
AdditionalApiParameters = apiParameters
|
||||||
}, JSON_SERIALIZER_OPTIONS);
|
}, JSON_SERIALIZER_OPTIONS);
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,5 @@ public record ChatCompletionAPIRequest(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string>? AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object>? AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -21,6 +21,5 @@ public record ResponsesAPIRequest(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string>? AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object>? AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -15,6 +15,5 @@ public readonly record struct ChatRequest(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonExtensionData]
|
public IDictionary<string, string> AdditionalApiParameters { get; init; }
|
||||||
public Dictionary<string, object> AdditionalApiParameters { get; init; }
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user