Skip to content

Commit 3420472

Browse files
authored
Merge pull request #77 from cnblogs/add-application-call
feat: add application call
2 parents d3b95b4 + 47ea4c7 commit 3420472

File tree

57 files changed

+3400
-1665
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+3400
-1665
lines changed

README.md

+69
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class YourService(IDashScopeClient client)
7676
- Image Generation - `CreateWanxImageGenerationTaskAsync()` and `GetWanxImageGenerationTaskAsync()`
7777
- Background Image Generation - `CreateWanxBackgroundGenerationTaskAsync()` and `GetWanxBackgroundGenerationTaskAsync()`
7878
- File API that used by Qwen-Long - `dashScopeClient.UploadFileAsync()` and `dashScopeClient.DeleteFileAsync`
79+
- Application call - `GetApplicationResponseAsync()` and `GetApplicationResponseStreamAsync()`
7980

8081
# Examples
8182

@@ -208,3 +209,71 @@ Delete file if needed
208209
```csharp
209210
var deletionResult = await dashScopeClient.DeleteFileAsync(uploadedFile.Id);
210211
```
212+
213+
## Application call
214+
215+
Use `GetApplicationResponseAsync` to call an application.
216+
217+
Use `GetApplicationResponseStreamAsync` for streaming output.
218+
219+
```csharp
220+
var request =
221+
new ApplicationRequest()
222+
{
223+
Input = new ApplicationInput() { Prompt = "Summarize this file." },
224+
Parameters = new ApplicationParameters()
225+
{
226+
TopK = 100,
227+
TopP = 0.8f,
228+
Seed = 1234,
229+
Temperature = 0.85f,
230+
RagOptions = new ApplicationRagOptions()
231+
{
232+
PipelineIds = ["thie5bysoj"],
233+
FileIds = ["file_d129d632800c45aa9e7421b30561f447_10207234"]
234+
}
235+
}
236+
};
237+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
238+
Console.WriteLine(response.Output.Text);
239+
```
240+
241+
`ApplicationRequest` use an `Dictionary<string, object?>` as `BizParams` by default.
242+
243+
```csharp
244+
var request =
245+
new ApplicationRequest()
246+
{
247+
Input = new ApplicationInput()
248+
{
249+
Prompt = "Summarize this file.",
250+
BizParams = new Dictionary<string, object?>()
251+
{
252+
{ "customKey1", "custom-value" }
253+
}
254+
}
255+
};
256+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
257+
Console.WriteLine(response.Output.Text);
258+
```
259+
260+
You can use the generic version `ApplicationRequest<TBizParams>` for strong-typed `BizParams`. But keep in mind that client use `snake_case` by default when doing json serialization, you may need to use `[JsonPropertyName("camelCase")]` for other type of naming policy.
261+
262+
```csharp
263+
public record TestApplicationBizParam(
264+
[property: JsonPropertyName("sourceCode")]
265+
string SourceCode);
266+
267+
var request =
268+
new ApplicationRequest<TestApplicationBizParam>()
269+
{
270+
Input = new ApplicationInput<TestApplicationBizParam>()
271+
{
272+
Prompt = "Summarize this file.",
273+
BizParams = new TestApplicationBizParam("test")
274+
}
275+
};
276+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
277+
Console.WriteLine(response.Output.Text);
278+
```
279+

README.zh-Hans.md

+69
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class YourService(IDashScopeClient client)
7676
- 人像风格重绘 - `CreateWanxImageGenerationTaskAsync()` and `GetWanxImageGenerationTaskAsync()`
7777
- 图像背景生成 - `CreateWanxBackgroundGenerationTaskAsync()` and `GetWanxBackgroundGenerationTaskAsync()`
7878
- 适用于 QWen-Long 的文件 API `dashScopeClient.UploadFileAsync()` and `dashScopeClient.DeleteFileAsync`
79+
- 应用调用 `dashScopeClient.GetApplicationResponseAsync``dashScopeClient.GetApplicationResponseStreamAsync()`
7980
- 其他使用相同 Endpoint 的模型
8081

8182
# 示例
@@ -204,3 +205,71 @@ Console.WriteLine(completion.Output.Choices[0].Message.Content);
204205
```csharp
205206
var deletionResult = await dashScopeClient.DeleteFileAsync(uploadedFile.Id);
206207
```
208+
209+
## 应用调用
210+
211+
`GetApplicationResponseAsync` 用于进行应用调用。
212+
213+
`GetApplicationResponseStreamAsync` 用于流式调用。
214+
215+
```csharp
216+
var request =
217+
new ApplicationRequest()
218+
{
219+
Input = new ApplicationInput() { Prompt = "Summarize this file." },
220+
Parameters = new ApplicationParameters()
221+
{
222+
TopK = 100,
223+
TopP = 0.8f,
224+
Seed = 1234,
225+
Temperature = 0.85f,
226+
RagOptions = new ApplicationRagOptions()
227+
{
228+
PipelineIds = ["thie5bysoj"],
229+
FileIds = ["file_d129d632800c45aa9e7421b30561f447_10207234"]
230+
}
231+
}
232+
};
233+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
234+
Console.WriteLine(response.Output.Text);
235+
```
236+
237+
`ApplicationRequest` 默认使用 `Dictionary<string, object?>` 作为 `BizParams` 的类型。
238+
239+
```csharp
240+
var request =
241+
new ApplicationRequest()
242+
{
243+
Input = new ApplicationInput()
244+
{
245+
Prompt = "Summarize this file.",
246+
BizParams = new Dictionary<string, object?>()
247+
{
248+
{ "customKey1", "custom-value" }
249+
}
250+
}
251+
};
252+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
253+
Console.WriteLine(response.Output.Text);
254+
```
255+
256+
如需强类型支持,可以使用泛型类 `ApplicationRequest<TBizParams>`
257+
注意 SDK 在 JSON 序列化时使用 `snake_case`。如果你的应用采用其他的命名规则,请使用 `[JsonPropertyName("camelCase")]` 来手动指定序列化时的属性名称。
258+
259+
```csharp
260+
public record TestApplicationBizParam(
261+
[property: JsonPropertyName("sourceCode")]
262+
string SourceCode);
263+
264+
var request =
265+
new ApplicationRequest<TestApplicationBizParam>()
266+
{
267+
Input = new ApplicationInput<TestApplicationBizParam>()
268+
{
269+
Prompt = "Summarize this file.",
270+
BizParams = new TestApplicationBizParam("test")
271+
}
272+
};
273+
var response = await client.GetApplicationResponseAsync("your-application-id", request);
274+
Console.WriteLine(response.Output.Text);
275+
```

src/Cnblogs.DashScope.AspNetCore/ServiceCollectionInjector.cs

+11-4
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public static IHttpClientBuilder AddDashScopeClient(this IServiceCollection serv
3838
var apiKey = section["apiKey"]
3939
?? throw new InvalidOperationException("There is no apiKey provided in given section");
4040
var baseAddress = section["baseAddress"];
41-
return string.IsNullOrEmpty(baseAddress)
42-
? services.AddDashScopeClient(apiKey)
43-
: services.AddDashScopeClient(apiKey, baseAddress);
41+
var workspaceId = section["workspaceId"];
42+
return services.AddDashScopeClient(apiKey, baseAddress, workspaceId);
4443
}
4544

4645
/// <summary>
@@ -49,16 +48,24 @@ public static IHttpClientBuilder AddDashScopeClient(this IServiceCollection serv
4948
/// <param name="services">The service collection to add service to.</param>
5049
/// <param name="apiKey">The DashScope api key.</param>
5150
/// <param name="baseAddress">The DashScope api base address, you may change this value if you are using proxy.</param>
51+
/// <param name="workspaceId">Default workspace id to use.</param>
5252
/// <returns></returns>
5353
public static IHttpClientBuilder AddDashScopeClient(
5454
this IServiceCollection services,
5555
string apiKey,
56-
string baseAddress = "https://dashscope.aliyuncs.com/api/v1/")
56+
string? baseAddress = null,
57+
string? workspaceId = null)
5758
{
59+
baseAddress ??= "https://dashscope.aliyuncs.com/api/v1/";
5860
return services.AddHttpClient<IDashScopeClient, DashScopeClientCore>(
5961
h =>
6062
{
6163
h.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
64+
if (string.IsNullOrWhiteSpace(workspaceId) == false)
65+
{
66+
h.DefaultRequestHeaders.Add("X-DashScope-WorkSpace", workspaceId);
67+
}
68+
6269
h.BaseAddress = new Uri(baseAddress);
6370
});
6471
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// One reference for application output.
5+
/// </summary>
6+
/// <param name="IndexId">The index id of the doc.</param>
7+
/// <param name="Title">Text slice title.</param>
8+
/// <param name="DocId">Unique id of the doc been referenced.</param>
9+
/// <param name="DocName">Name of the doc been referenced.</param>
10+
/// <param name="Text">Referenced content.</param>
11+
/// <param name="Images">Image URLs beed referenced.</param>
12+
/// <param name="PageNumber">Page numbers of referenced content belongs to.</param>
13+
public record ApplicationDocReference(
14+
string IndexId,
15+
string Title,
16+
string DocId,
17+
string DocName,
18+
string Text,
19+
List<string>? Images,
20+
List<int>? PageNumber);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// Inputs for application call.
5+
/// </summary>
6+
/// <typeparam name="TBizParams">Type of the BizContent.</typeparam>
7+
public class ApplicationInput<TBizParams>
8+
where TBizParams : class
9+
{
10+
/// <summary>
11+
/// The prompt for model to generate response upon. Optional when <see cref="Messages"/> has been set.
12+
/// </summary>
13+
/// <remarks>
14+
/// Prompt will be appended to <see cref="Messages"/> when both set.
15+
/// </remarks>
16+
public string? Prompt { get; set; }
17+
18+
/// <summary>
19+
/// The session id for conversation history. This will be ignored if <see cref="Messages"/> has been set.
20+
/// </summary>
21+
public string? SessionId { get; set; }
22+
23+
/// <summary>
24+
/// The conversation history.
25+
/// </summary>
26+
public IEnumerable<ApplicationMessage>? Messages { get; set; }
27+
28+
/// <summary>
29+
/// The id of memory when enabled.
30+
/// </summary>
31+
public string? MemoryId { get; set; }
32+
33+
/// <summary>
34+
/// List of image urls for inputs.
35+
/// </summary>
36+
public IEnumerable<string>? ImageList { get; set; }
37+
38+
/// <summary>
39+
/// User defined content.
40+
/// </summary>
41+
public TBizParams? BizParams { get; set; } = null;
42+
}
43+
44+
/// <summary>
45+
/// Inputs for application call.
46+
/// </summary>
47+
public class ApplicationInput : ApplicationInput<Dictionary<string, object?>>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// A single message for application call.
5+
/// </summary>
6+
/// <param name="Role">The role of this message belongs to.</param>
7+
/// <param name="Content">The content of the message.</param>
8+
public record ApplicationMessage(string Role, string Content)
9+
{
10+
/// <summary>
11+
/// Creates a user message.
12+
/// </summary>
13+
/// <param name="content">Content of the message.</param>
14+
/// <returns></returns>
15+
public static ApplicationMessage User(string content) => new("user", content);
16+
17+
/// <summary>
18+
/// Creates a system message.
19+
/// </summary>
20+
/// <param name="content">Content of the message.</param>
21+
/// <returns></returns>
22+
public static ApplicationMessage System(string content) => new("system", content);
23+
24+
/// <summary>
25+
/// Creates a assistant message.
26+
/// </summary>
27+
/// <param name="content">Content of the message.</param>
28+
/// <returns></returns>
29+
public static ApplicationMessage Assistant(string content) => new("assistant", content);
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// Token usages for one model.
5+
/// </summary>
6+
/// <param name="ModelId">The id of the model.</param>
7+
/// <param name="InputTokens">Total input tokens of this model.</param>
8+
/// <param name="OutputTokens">Total output tokens from this model.</param>
9+
public record ApplicationModelUsage(string ModelId, int InputTokens, int OutputTokens);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// The output of application call.
5+
/// </summary>
6+
/// <param name="Text">Output text from application.</param>
7+
/// <param name="FinishReason">Finish reason from application.</param>
8+
/// <param name="SessionId">Unique id of current session.</param>
9+
/// <param name="Thoughts">Thoughts from application.</param>
10+
/// <param name="DocReferences">Doc references from application output.</param>
11+
public record ApplicationOutput(
12+
string Text,
13+
string FinishReason,
14+
string SessionId,
15+
List<ApplicationOutputThought>? Thoughts,
16+
List<ApplicationDocReference>? DocReferences);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// The model thought output.
5+
/// </summary>
6+
/// <param name="Thought">The thought content of the model.</param>
7+
/// <param name="ActionType">Type of the action. e.g. <c>agentRag</c>, <c>reasoning</c>.</param>
8+
/// <param name="ActionName">The name of the action.</param>
9+
/// <param name="Action">The action been executed.</param>
10+
/// <param name="ActionInputStream">The streaming result of action input.</param>
11+
/// <param name="ActionInput">The input of the action.</param>
12+
/// <param name="Observation">Lookup or plugin output.</param>
13+
/// <param name="Response">Reasoning output when using DeepSeek-R1.</param>
14+
/// <param name="Arguments">Arguments of the action.</param>
15+
public record ApplicationOutputThought(
16+
string? Thought,
17+
string? ActionType,
18+
string? ActionName,
19+
string? Action,
20+
string? ActionInputStream,
21+
string? ActionInput,
22+
string? Observation,
23+
string? Response,
24+
string? Arguments);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace Cnblogs.DashScope.Core;
2+
3+
/// <summary>
4+
/// Parameters for application call.
5+
/// </summary>
6+
public class ApplicationParameters : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter
7+
{
8+
/// <inheritdoc />
9+
public bool? IncrementalOutput { get; set; }
10+
11+
/// <summary>
12+
/// Output format for flow application. Can be <c>full_thoughts</c> or <c>agent_format</c>. Defaults to <c>full_thoughts</c>.
13+
/// </summary>
14+
public string? FlowStreamMode { get; set; }
15+
16+
/// <summary>
17+
/// Options for RAG applications.
18+
/// </summary>
19+
public ApplicationRagOptions? RagOptions { get; set; }
20+
21+
/// <inheritdoc />
22+
public ulong? Seed { get; set; }
23+
24+
/// <inheritdoc />
25+
public float? TopP { get; set; }
26+
27+
/// <inheritdoc />
28+
public int? TopK { get; set; }
29+
30+
/// <inheritdoc />
31+
public float? Temperature { get; set; }
32+
33+
/// <summary>
34+
/// Controls whether output contains think block.
35+
/// </summary>
36+
public bool? HasThoughts { get; set; }
37+
}

0 commit comments

Comments
 (0)