18 changed files with 608 additions and 1 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,31 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.AI.Tools.Http</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.AI.Tools.Http</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\AI\Tools\Http\Localization\Resources\*.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\AI\Tools\Http\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Http.Client" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.Contracts" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.AI.Tools\LINGYUN.Abp.AI.Tools.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,42 @@ |
|||
using LINGYUN.Abp.AI.Localization; |
|||
using LINGYUN.Abp.AI.Tools.Http.ApplicationConfigurations; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAIToolsModule), |
|||
typeof(AbpHttpClientModule), |
|||
typeof(AbpAspNetCoreMvcContractsModule))] |
|||
public class AbpAIToolsHttpModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpAIToolsApplicationConfigurationOptions>(context.Configuration.GetSection("AITools:Http:ApplicationConfiguration")); |
|||
|
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAIToolsHttpModule>(); |
|||
}); |
|||
|
|||
Configure<AbpAIToolsOptions>(options => |
|||
{ |
|||
// Http工具
|
|||
options.AIToolProviders.Add<HttpAIToolProvider>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AbpAIResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/AI/Tools/Http/Localization/Resources"); |
|||
}); |
|||
|
|||
context.Services.AddHttpAIToolClient(); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public class AbpAIToolsHttpOptiions |
|||
{ |
|||
public List<Action<IHttpClientBuilder>> ClientBuildActions { get; } |
|||
|
|||
public List<Action<IServiceProvider, HttpClient>> ClientActions { get; } |
|||
|
|||
public List<Action<IServiceProvider, HttpClientHandler>> ClientHandlerActions { get; } |
|||
/// <summary>
|
|||
/// 自定义Http请求响应处理
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参数1: HttpAITool工具名称
|
|||
/// 参数2: IServiceProvider
|
|||
/// 参数3: 请求响应
|
|||
/// </remarks>
|
|||
public IDictionary<string, Func<IServiceProvider, HttpResponseMessage, Task<object>>> HttpResponseActions { get; } |
|||
public AbpAIToolsHttpOptiions() |
|||
{ |
|||
ClientBuildActions = new List<Action<IHttpClientBuilder>>(); |
|||
ClientActions = new List<Action<IServiceProvider, HttpClient>>(); |
|||
ClientHandlerActions = new List<Action<IServiceProvider, HttpClientHandler>>(); |
|||
HttpResponseActions = new Dictionary<string, Func<IServiceProvider, HttpResponseMessage, Task<object>>>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace LINGYUN.Abp.AI.Tools.Http.ApplicationConfigurations; |
|||
public class AbpAIToolsApplicationConfigurationOptions |
|||
{ |
|||
public bool IsEnabled { get; set; } |
|||
public string EndPoint { get; set; } |
|||
public AbpAIToolsApplicationConfigurationOptions() |
|||
{ |
|||
IsEnabled = false; |
|||
EndPoint = "http://localhost:8080/api/abp/application-configuration"; |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using LINGYUN.Abp.AI.Localization; |
|||
using LINGYUN.Abp.AI.Tools.Http.ApplicationConfigurations; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Net.Http; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public class GlobalHttpAIToolDefinitionProvider : AIToolDefinitionProvider |
|||
{ |
|||
protected AbpAIToolsApplicationConfigurationOptions Options { get; } |
|||
public GlobalHttpAIToolDefinitionProvider(IOptions<AbpAIToolsApplicationConfigurationOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public override void Define(IAIToolDefinitionContext context) |
|||
{ |
|||
if (Options.IsEnabled) |
|||
{ |
|||
context.Add( |
|||
new AIToolDefinition( |
|||
"GetApplicationConfiguration", |
|||
HttpAIToolProvider.ProviderName, |
|||
L("Tools:GetApplicationConfiguration")) |
|||
.WithHttpEndpoint(Options.EndPoint) |
|||
.WithHttpMethod(HttpMethod.Get) |
|||
.WithHttpHeaders("_AbpDontWrapResult", "true")// 无需包装结果
|
|||
.UseHttpCurrentAccessToken()); |
|||
} |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AbpAIResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,136 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Globalization; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Headers; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Timing; |
|||
using Volo.Abp.Tracing; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public class HttpAITool |
|||
{ |
|||
protected HttpAIToolInvokeContext Context { get; } |
|||
|
|||
public HttpAITool(HttpAIToolInvokeContext context) |
|||
{ |
|||
Context = context; |
|||
} |
|||
|
|||
public async virtual Task<object?> InvokeAsync() |
|||
{ |
|||
// Abp远程服务适配
|
|||
//var remoteService = Context.ToolDefinition.GetRemoteServiceOrNull();
|
|||
//var remoteMethod = Context.ToolDefinition.GetRemoteMethodOrNull();
|
|||
//if (!remoteService.IsNullOrWhiteSpace() && !remoteMethod.IsNullOrWhiteSpace())
|
|||
//{
|
|||
// var abpHttpClientOptions = Context.ServiceProvider.GetRequiredService<IOptions<AbpHttpClientOptions>>().Value;
|
|||
// HttpClientProxyConfig? clientProxyConfig = null;
|
|||
|
|||
// foreach (var httpClientProxyConfig in abpHttpClientOptions.HttpClientProxies.Values)
|
|||
// {
|
|||
// if (httpClientProxyConfig.RemoteServiceName.Equals(remoteService))
|
|||
// {
|
|||
// clientProxyConfig = httpClientProxyConfig;
|
|||
// continue;
|
|||
// }
|
|||
// }
|
|||
|
|||
// if (clientProxyConfig != null)
|
|||
// {
|
|||
// // var serviceType = clientProxyConfig.Type.GetProperty(nameof(IHttpClientProxy<object>.Service));
|
|||
// var serviceMethod = clientProxyConfig.Type.GetMethod(remoteMethod);
|
|||
// if (serviceMethod != null)
|
|||
// {
|
|||
// var httpClientProxyType = typeof(IHttpClientProxy<>).MakeGenericType(clientProxyConfig.Type);
|
|||
// var httpClientProxy = Context.ServiceProvider.GetRequiredService(httpClientProxyType);
|
|||
// var service = httpClientProxyType.GetProperty(nameof(IHttpClientProxy<object>.Service))!.GetValue(httpClientProxy);
|
|||
// // TODO: 暂不支持有参远程服务调用
|
|||
// var task = (Task)serviceMethod.Invoke(service, null)!;
|
|||
// await task;
|
|||
// // TODO: 必须为Task<XXX>返回结构
|
|||
// return typeof(Task<>).MakeGenericType(serviceMethod.ReturnType.GenericTypeArguments[0])
|
|||
// .GetProperty(nameof(Task<object>.Result), BindingFlags.Public | BindingFlags.Instance)!
|
|||
// .GetValue(task);
|
|||
// }
|
|||
// }
|
|||
//}
|
|||
|
|||
var options = Context.ServiceProvider.GetRequiredService<IOptions<AbpAIToolsHttpOptiions>>().Value; |
|||
var httpClientFactory = Context.ServiceProvider.GetRequiredService<IHttpClientFactory>(); |
|||
var httpClient = httpClientFactory.GetHttpAIToolClient(); |
|||
|
|||
var httpRequestMessage = new HttpRequestMessage( |
|||
Context.ToolDefinition.GetHttpMethod(), |
|||
Context.ToolDefinition.GetHttpEndpoint()); |
|||
|
|||
var headers = Context.ToolDefinition.GetHttpHeaders(); |
|||
foreach (var header in headers) |
|||
{ |
|||
httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value); |
|||
} |
|||
|
|||
if (Context.ToolDefinition.IsUseHttpCurrentAccessToken()) |
|||
{ |
|||
var accessTokenProvider = Context.ServiceProvider.GetRequiredService<IAbpAccessTokenProvider>(); |
|||
|
|||
var token = await accessTokenProvider.GetTokenAsync(); |
|||
if (!token.IsNullOrWhiteSpace()) |
|||
{ |
|||
httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); |
|||
} |
|||
} |
|||
|
|||
AddDefaultHeaders(httpRequestMessage); |
|||
|
|||
var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage); |
|||
|
|||
if (options.HttpResponseActions.TryGetValue(Context.ToolDefinition.Name, out var customHandler)) |
|||
{ |
|||
return await customHandler(Context.ServiceProvider, httpResponseMessage); |
|||
} |
|||
|
|||
return await httpResponseMessage.Content.ReadAsStringAsync(); |
|||
} |
|||
|
|||
protected virtual void AddDefaultHeaders(HttpRequestMessage requestMessage) |
|||
{ |
|||
//CorrelationId
|
|||
var correlationIdProvider = Context.ServiceProvider.GetRequiredService<ICorrelationIdProvider>(); |
|||
var correlationId = correlationIdProvider.Get(); |
|||
if (correlationId != null) |
|||
{ |
|||
var correlationIdOptions = Context.ServiceProvider.GetRequiredService<IOptions<AbpCorrelationIdOptions>>(); |
|||
requestMessage.Headers.Add(correlationIdOptions.Value.HttpHeaderName, correlationId); |
|||
} |
|||
|
|||
//TenantId
|
|||
var currentTenant = Context.ServiceProvider.GetRequiredService<ICurrentTenant>(); |
|||
if (currentTenant.Id.HasValue) |
|||
{ |
|||
//TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key
|
|||
requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, currentTenant.Id.Value.ToString()); |
|||
} |
|||
|
|||
//Culture
|
|||
//TODO: Is that the way we want? Couldn't send the culture (not ui culture)
|
|||
var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name; |
|||
if (!currentCulture.IsNullOrEmpty()) |
|||
{ |
|||
requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture)); |
|||
} |
|||
|
|||
//X-Requested-With
|
|||
requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest"); |
|||
|
|||
//Timezone
|
|||
var currentTimezoneProvider = Context.ServiceProvider.GetRequiredService<ICurrentTimezoneProvider>(); |
|||
if (!currentTimezoneProvider.TimeZone.IsNullOrWhiteSpace()) |
|||
{ |
|||
requestMessage.Headers.Add(TimeZoneConsts.DefaultTimeZoneKey, currentTimezoneProvider.TimeZone); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,150 @@ |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public static class HttpAIToolDefinitionExtenssions |
|||
{ |
|||
private const string RemoteService = "RemoteService"; |
|||
private const string RemoteController = "RemoteController"; |
|||
private const string RemoteMethod = "RemoteMethod"; |
|||
|
|||
private const string Endpoint = "HttpEndpoint"; |
|||
private const string Method = "HttpMethod"; |
|||
private const string Headers = "HttpHeaders"; |
|||
|
|||
private const string CurrentAccessToken = "UseHttpCurrentAccessToken"; |
|||
|
|||
public static AIToolDefinition UseHttpCurrentAccessToken(this AIToolDefinition definition, bool useCurrentAccessToken = true) |
|||
{ |
|||
definition.WithProperty(CurrentAccessToken, useCurrentAccessToken); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static AIToolDefinition WithRemoteService(this AIToolDefinition definition, string service, string controllerName, string uniqueMethodName) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(service, nameof(service)); |
|||
Check.NotNullOrWhiteSpace(controllerName, nameof(controllerName)); |
|||
Check.NotNullOrWhiteSpace(uniqueMethodName, nameof(uniqueMethodName)); |
|||
|
|||
definition.WithProperty(RemoteService, service); |
|||
definition.WithProperty(RemoteController, controllerName); |
|||
definition.WithProperty(RemoteMethod, uniqueMethodName); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static AIToolDefinition WithHttpEndpoint(this AIToolDefinition definition, string endPoint) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(endPoint, nameof(endPoint)); |
|||
|
|||
definition.WithProperty(Endpoint, endPoint); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static AIToolDefinition WithHttpMethod(this AIToolDefinition definition, HttpMethod method) |
|||
{ |
|||
Check.NotNull(method, nameof(method)); |
|||
|
|||
definition.WithProperty(Method, method.Method); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static AIToolDefinition WithHttpHeaders(this AIToolDefinition definition, IDictionary<string, string> headers) |
|||
{ |
|||
Check.NotNullOrEmpty(headers, nameof(headers)); |
|||
|
|||
var currentHeaders = definition.GetHttpHeaders(); |
|||
|
|||
currentHeaders.AddIfNotContains(headers); |
|||
|
|||
definition.WithProperty(Headers, currentHeaders); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static AIToolDefinition WithHttpHeaders(this AIToolDefinition definition, string key, string value) |
|||
{ |
|||
Check.NotNullOrEmpty(key, nameof(key)); |
|||
Check.NotNullOrEmpty(value, nameof(value)); |
|||
|
|||
var currentHeaders = definition.GetHttpHeaders(); |
|||
|
|||
currentHeaders.TryAdd(key, value); |
|||
|
|||
definition.WithProperty(Headers, currentHeaders); |
|||
|
|||
return definition; |
|||
} |
|||
|
|||
public static bool IsUseHttpCurrentAccessToken(this AIToolDefinition definition) |
|||
{ |
|||
if (definition.Properties.TryGetValue(CurrentAccessToken, out var useCurrentAccessTokenObj) && useCurrentAccessTokenObj != null |
|||
&& bool.TryParse(useCurrentAccessTokenObj.ToString(), out var useCurrentAccessToken)) |
|||
{ |
|||
return useCurrentAccessToken; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public static string? GetRemoteServiceOrNull(this AIToolDefinition definition) |
|||
{ |
|||
definition.Properties.TryGetValue(RemoteService, out var remoteServiceObj); |
|||
|
|||
return remoteServiceObj?.ToString(); |
|||
} |
|||
|
|||
public static string? GetRemoteControllerOrNull(this AIToolDefinition definition) |
|||
{ |
|||
definition.Properties.TryGetValue(RemoteController, out var remoteControllerObj); |
|||
|
|||
return remoteControllerObj?.ToString(); |
|||
} |
|||
|
|||
public static string? GetRemoteMethodOrNull(this AIToolDefinition definition) |
|||
{ |
|||
definition.Properties.TryGetValue(RemoteMethod, out var remoteMethodObj); |
|||
|
|||
return remoteMethodObj?.ToString(); |
|||
} |
|||
|
|||
public static string GetHttpEndpoint(this AIToolDefinition definition) |
|||
{ |
|||
definition.Properties.TryGetValue(Endpoint, out var endpointObj); |
|||
|
|||
Check.NotNull(endpointObj, nameof(Endpoint)); |
|||
|
|||
return endpointObj.ToString()!; |
|||
} |
|||
|
|||
public static HttpMethod GetHttpMethod(this AIToolDefinition definition) |
|||
{ |
|||
if (definition.Properties.TryGetValue(Method, out var methodObj) && methodObj != null) |
|||
{ |
|||
try |
|||
{ |
|||
return HttpMethod.Parse(methodObj.ToString()); |
|||
} |
|||
catch { } |
|||
} |
|||
|
|||
return HttpMethod.Get; |
|||
} |
|||
|
|||
public static IDictionary<string, string> GetHttpHeaders(this AIToolDefinition definition) |
|||
{ |
|||
if (definition.Properties.TryGetValue(Headers, out var headersObj) && headersObj != null) |
|||
{ |
|||
if (headersObj is IDictionary<string, string> h) |
|||
{ |
|||
return h; |
|||
} |
|||
} |
|||
|
|||
return new Dictionary<string, string>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public class HttpAIToolInvokeContext |
|||
{ |
|||
public IServiceProvider ServiceProvider { get; } |
|||
public AIToolDefinition ToolDefinition { get; } |
|||
public HttpAIToolInvokeContext( |
|||
IServiceProvider serviceProvider, |
|||
AIToolDefinition toolDefinition) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
ToolDefinition = toolDefinition; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using Microsoft.Extensions.AI; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.AI.Tools.Http; |
|||
public class HttpAIToolProvider : IAIToolProvider, ITransientDependency |
|||
{ |
|||
public const string ProviderName = "Http"; |
|||
public string Name => ProviderName; |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
public HttpAIToolProvider(IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
|
|||
public virtual Task<AITool[]> CreateToolsAsync(AIToolDefinition definition) |
|||
{ |
|||
string? description = null; |
|||
if (definition.Description != null) |
|||
{ |
|||
var localizerFactory = ServiceProvider.GetRequiredService<IStringLocalizerFactory>(); |
|||
description = definition.Description.Localize(localizerFactory)?.Value; |
|||
} |
|||
|
|||
var httpAITool = AIFunctionFactory.Create( |
|||
method: typeof(HttpAITool).GetMethod(nameof(HttpAITool.InvokeAsync))!, |
|||
createInstanceFunc: (AIFunctionArguments args) => |
|||
{ |
|||
var context = new HttpAIToolInvokeContext( |
|||
args.Services ?? ServiceProvider, |
|||
definition); |
|||
|
|||
return new HttpAITool(context); |
|||
}, |
|||
options: new AIFunctionFactoryOptions |
|||
{ |
|||
Name = definition.Name, |
|||
Description = description, |
|||
AdditionalProperties = definition.Properties, |
|||
}); |
|||
|
|||
return Task.FromResult<AITool[]>([httpAITool]); |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Tools:GetApplicationConfiguration": "Get Application Configuration" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Tools:GetApplicationConfiguration": "获取应用程序配置" |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using LINGYUN.Abp.AI.Tools.Http; |
|||
using System.Net.Http; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection; |
|||
internal static class HttpClientHttpAIToolExtenssions |
|||
{ |
|||
private const string HttpAIToolClient = "__AbpAIHttpToolClient"; |
|||
public static IServiceCollection AddHttpAIToolClient(this IServiceCollection services) |
|||
{ |
|||
var preOptions = services.ExecutePreConfiguredActions<AbpAIToolsHttpOptiions>(); |
|||
|
|||
var clientBuilder = services.AddHttpClient(HttpAIToolClient, (provider, client) => |
|||
{ |
|||
foreach (var clientBuildAction in preOptions.ClientActions) |
|||
{ |
|||
clientBuildAction(provider, client); |
|||
} |
|||
}).ConfigurePrimaryHttpMessageHandler(provider => |
|||
{ |
|||
var handler = new HttpClientHandler(); |
|||
|
|||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))) |
|||
{ |
|||
handler.UseCookies = false; |
|||
} |
|||
|
|||
foreach (var handlerAction in preOptions.ClientHandlerActions) |
|||
{ |
|||
handlerAction(provider, handler); |
|||
} |
|||
|
|||
return handler; |
|||
}); |
|||
|
|||
foreach (var clientBuildAction in preOptions.ClientBuildActions) |
|||
{ |
|||
clientBuildAction(clientBuilder); |
|||
} |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static HttpClient GetHttpAIToolClient(this IHttpClientFactory httpClientFactory) |
|||
{ |
|||
return httpClientFactory.CreateClient(HttpAIToolClient); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue