Skip to content

feat: add text generation parameters #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions Cnblogs.DashScope.Sdk.sln
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cnblogs.DashScope.AspNetCor
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cnblogs.DashScope.Core", "src\Cnblogs.DashScope.Core\Cnblogs.DashScope.Core.csproj", "{CC389455-A3EA-4F09-B524-4DC351A1E1AA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cnblogs.DashScope.Sdk.SnapshotGenerator", "test\Cnblogs.DashScope.Sdk.SnapshotGenerator\Cnblogs.DashScope.Sdk.SnapshotGenerator.csproj", "{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cnblogs.DashScope.AI", "src\Cnblogs.DashScope.AI\Cnblogs.DashScope.AI.csproj", "{5D5AD75A-8084-4738-AC56-B8A23E649452}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cnblogs.DashScope.AI.UnitTests", "test\Cnblogs.DashScope.AI.UnitTests\Cnblogs.DashScope.AI.UnitTests.csproj", "{25EE79E1-147B-42FD-AFEA-E1550EDD1D36}"
Expand All @@ -35,7 +33,6 @@ Global
{8885149A-78F0-4C8E-B9AA-87A46EA69219} = {2E15D1EC-4A07-416E-8BE6-D907F509FD35}
{C910495B-87AB-4AC1-989C-B6720695A139} = {008988ED-0A3B-4272-BCC3-7B4110699345}
{CC389455-A3EA-4F09-B524-4DC351A1E1AA} = {008988ED-0A3B-4272-BCC3-7B4110699345}
{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1} = {CFC8ECB3-5248-46CD-A56C-EC088F2A3804}
{5D5AD75A-8084-4738-AC56-B8A23E649452} = {008988ED-0A3B-4272-BCC3-7B4110699345}
{25EE79E1-147B-42FD-AFEA-E1550EDD1D36} = {CFC8ECB3-5248-46CD-A56C-EC088F2A3804}
{06F0AF23-445B-4C6F-9E19-570DA9B7435D} = {CFC8ECB3-5248-46CD-A56C-EC088F2A3804}
Expand All @@ -61,10 +58,6 @@ Global
{CC389455-A3EA-4F09-B524-4DC351A1E1AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC389455-A3EA-4F09-B524-4DC351A1E1AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC389455-A3EA-4F09-B524-4DC351A1E1AA}.Release|Any CPU.Build.0 = Release|Any CPU
{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5088DE77-1CE3-46FB-B9D0-27A6C9A5EED1}.Release|Any CPU.Build.0 = Release|Any CPU
{5D5AD75A-8084-4738-AC56-B8A23E649452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D5AD75A-8084-4738-AC56-B8A23E649452}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D5AD75A-8084-4738-AC56-B8A23E649452}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
28 changes: 27 additions & 1 deletion src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ namespace Cnblogs.DashScope.Core;
/// The text generation options.
/// </summary>
public interface ITextGenerationParameters
: IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter, IPenaltyParameter, IMaxTokenParameter, IStopTokenParameter
: IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter, IPenaltyParameter, IMaxTokenParameter,
IStopTokenParameter
{
/// <summary>
/// The format of the result, must be <c>text</c> or <c>message</c>.
Expand Down Expand Up @@ -40,11 +41,31 @@ public interface ITextGenerationParameters
/// </summary>
public bool? EnableSearch { get; }

/// <summary>
/// Search options. <see cref="EnableSearch"/> should set to true.
/// </summary>
public TextGenerationSearchOptions? SearchOptions { get; set; }

/// <summary>
/// Thinking option. Valid for supported models.(e.g. qwen3)
/// </summary>
public bool? EnableThinking { get; }

/// <summary>
/// Maximum length of thinking content. Valid for supported models.(e.g. qwen3)
/// </summary>
public int? ThinkingBudget { get; set; }

/// <summary>
/// Include log possibilities in response.
/// </summary>
public bool? Logprobs { get; set; }

/// <summary>
/// How many choices should be returned. Range: [0, 5]
/// </summary>
public int? TopLogprobs { get; set; }

/// <summary>
/// Available tools for model to call.
/// </summary>
Expand All @@ -59,4 +80,9 @@ public interface ITextGenerationParameters
/// Whether to enable parallel tool calling
/// </summary>
public bool? ParallelToolCalls { get; }

/// <summary>
/// Options when using QWen-MT models.
/// </summary>
public TextGenerationTranslationOptions? TranslationOptions { get; set; }
}
43 changes: 43 additions & 0 deletions src/Cnblogs.DashScope.Core/Internals/ByteArrayLiteralConvertor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Cnblogs.DashScope.Core.Internals;

internal class ByteArrayLiteralConvertor : JsonConverter<byte[]>
{
/// <inheritdoc />
public override byte[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartArray)
{
reader.Read(); // read out start of array
var list = new List<byte>(8); // should fit most tokens
while (reader.TokenType != JsonTokenType.EndArray)
{
list.Add(reader.GetByte());
reader.Read();
}

return list.ToArray();
}

if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

return reader.GetBytesFromBase64();
}

/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var b in value)
{
writer.WriteNumberValue(b);
}

writer.WriteEndArray();
}
}
5 changes: 5 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationChoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ public class TextGenerationChoice
/// The generated message.
/// </summary>
public TextChatMessage Message { get; set; } = new(Array.Empty<DashScopeFileId>());

/// <summary>
/// Token array with log possibility info.
/// </summary>
public TextGenerationLogprobs? Logprobs { get; set; }
}
18 changes: 18 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationLogprobContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
using Cnblogs.DashScope.Core.Internals;

namespace Cnblogs.DashScope.Core;

/// <summary>
/// Represents a possible choice of token.
/// </summary>
/// <param name="Token">Token content.</param>
/// <param name="Bytes">Token content in UTF-8 byte array.</param>
/// <param name="Logprob">Possibility, <c>null</c> when it's too low.</param>
/// <param name="TopLogprobs">The most possible alternatives.</param>
public record TextGenerationLogprobContent(
string Token,
[property: JsonConverter(typeof(ByteArrayLiteralConvertor))]
byte[] Bytes,
float? Logprob,
List<TextGenerationTopLogprobContent> TopLogprobs);
7 changes: 7 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationLogprobs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Possibilities of token choices.
/// </summary>
/// <param name="Content">The choices with their possibility.</param>
public record TextGenerationLogprobs(List<TextGenerationLogprobContent> Content);
5 changes: 5 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ public class TextGenerationOutput
/// Not null when <see cref="TextGenerationParameters"/>.<see cref="TextGenerationParameters.ResultFormat"/> is "message".
/// </summary>
public List<TextGenerationChoice>? Choices { get; set; }

/// <summary>
/// Not null when <see cref="TextGenerationParameters"/>.<see cref="TextGenerationParameters.SearchOptions"/> configured to show source.
/// </summary>
public TextGenerationWebSearchInfo? SearchInfo { get; set; }
}
15 changes: 15 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,21 @@ public class TextGenerationParameters : ITextGenerationParameters
/// <inheritdoc />
public bool? EnableSearch { get; set; }

/// <inheritdoc />
public TextGenerationSearchOptions? SearchOptions { get; set; }

/// <inheritdoc />
public bool? EnableThinking { get; set; }

/// <inheritdoc />
public int? ThinkingBudget { get; set; }

/// <inheritdoc />
public bool? Logprobs { get; set; }

/// <inheritdoc />
public int? TopLogprobs { get; set; }

/// <inheritdoc />
public IEnumerable<ToolDefinition>? Tools { get; set; }

Expand All @@ -50,6 +62,9 @@ public class TextGenerationParameters : ITextGenerationParameters
/// <inheritdoc />
public bool? ParallelToolCalls { get; set; }

/// <inheritdoc />
public TextGenerationTranslationOptions? TranslationOptions { get; set; }

/// <inheritdoc />
public bool? IncrementalOutput { get; set; }
}
32 changes: 32 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationSearchOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Web search options
/// </summary>
public class TextGenerationSearchOptions
{
/// <summary>
/// Show search result in response. Defaults to false.
/// </summary>
public bool? EnableSource { get; set; }

/// <summary>
/// Include citation in output. Defaults to false.
/// </summary>
public bool? EnableCitation { get; set; }

/// <summary>
/// Citation format. Defaults to "[&lt;number&gt;]"
/// </summary>
public string? CitationFormat { get; set; }

/// <summary>
/// Force model to use web search. Defaults to false.
/// </summary>
public bool? ForcedSearch { get; set; }

/// <summary>
/// How many search records should be provided to model. "standard" - 5 records. "pro" - 10 records.
/// </summary>
public string? SearchStrategy { get; set; }
}
16 changes: 16 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationTopLogprobContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
using Cnblogs.DashScope.Core.Internals;

namespace Cnblogs.DashScope.Core;

/// <summary>
/// Represents one choice of most possibility alternative tokens.
/// </summary>
/// <param name="Token">The token content.</param>
/// <param name="Bytes">The token content in UTF-8 byte array.</param>
/// <param name="Logprob">Possibility, <c>null</c> when possibility is too low.</param>
public record TextGenerationTopLogprobContent(
string Token,
[property: JsonConverter(typeof(ByteArrayLiteralConvertor))]
byte[] Bytes,
float? Logprob);
32 changes: 32 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationTranslationOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Configurations when using translation models.
/// </summary>
public class TextGenerationTranslationOptions
{
/// <summary>
/// The language name of the input text. Use 'auto' to enable auto-detection.
/// </summary>
public string SourceLang { get; set; } = "auto";

/// <summary>
/// The language name of the output text.
/// </summary>
public string TargetLang { get; set; } = string.Empty;

/// <summary>
/// Term list for translation.
/// </summary>
public IEnumerable<TranslationReference>? Terms { get; set; }

/// <summary>
/// Sample texts for translation
/// </summary>
public IEnumerable<TranslationReference>? TmList { get; set; }

/// <summary>
/// Domain info about the source text. Only supports English.
/// </summary>
public string? Domains { get; set; }
}
7 changes: 7 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationWebSearchInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Web search information.
/// </summary>
/// <param name="SearchResults">Web search results.</param>
public record TextGenerationWebSearchInfo(List<TextGenerationWebSearchResult> SearchResults);
11 changes: 11 additions & 0 deletions src/Cnblogs.DashScope.Core/TextGenerationWebSearchResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Represents one web search record.
/// </summary>
/// <param name="SiteName">Source site name.</param>
/// <param name="Icon">Source site favicon url.</param>
/// <param name="Index">Serial number of search records.</param>
/// <param name="Title">Page title.</param>
/// <param name="Url">Page url.</param>
public record TextGenerationWebSearchResult(string SiteName, string Icon, int Index, string Title, string Url);
8 changes: 8 additions & 0 deletions src/Cnblogs.DashScope.Core/TranslationReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// A text pair that used for translation reference.
/// </summary>
/// <param name="Source">The text in source language.</param>
/// <param name="Target">The text in target language.</param>
public record TranslationReference(string Source, string Target);

This file was deleted.

Loading