From 40234343ffc08193816cce2a6cc907c42d97da6a Mon Sep 17 00:00:00 2001 From: ccnetcore Date: Wed, 7 Jan 2026 22:25:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=84=8F=E5=BF=83ai?= =?UTF-8?q?=20agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dtos/SessionCreateAndUpdateInput.cs | 9 +- .../Dtos/SessionDto.cs | 6 + .../Dtos/SessionGetListInput.cs | 10 +- .../Services/Chat/SessionService.cs | 3 +- .../Enums/SessionTypeEnum.cs | 17 + .../Chats/AnthropicChatCompletionsService.cs | 10 +- .../Entities/Chat/SessionAggregateRoot.cs | 8 +- .../Mcp/OnlineSearchTool.cs | 195 +++- Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 2 +- Yi.Ai.Vue3/src/api/agent/index.ts | 25 + Yi.Ai.Vue3/src/api/agent/types.ts | 51 + Yi.Ai.Vue3/src/api/index.ts | 1 + Yi.Ai.Vue3/src/api/session/types.ts | 22 + Yi.Ai.Vue3/src/assets/images/czld.png | Bin 0 -> 87723 bytes Yi.Ai.Vue3/src/pages/chat/agent/index.vue | 937 +++++++++++++++++- Yi.Ai.Vue3/src/stores/modules/agentSession.ts | 202 ++++ Yi.Ai.Vue3/src/stores/modules/session.ts | 2 + Yi.Ai.Vue3/types/components.d.ts | 1 + Yi.Ai.Vue3/types/import_meta.d.ts | 1 - 19 files changed, 1469 insertions(+), 33 deletions(-) create mode 100644 Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/SessionTypeEnum.cs create mode 100644 Yi.Ai.Vue3/src/api/agent/index.ts create mode 100644 Yi.Ai.Vue3/src/api/agent/types.ts create mode 100644 Yi.Ai.Vue3/src/assets/images/czld.png create mode 100644 Yi.Ai.Vue3/src/stores/modules/agentSession.ts diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionCreateAndUpdateInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionCreateAndUpdateInput.cs index c41d956f..cf1ffe89 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionCreateAndUpdateInput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionCreateAndUpdateInput.cs @@ -1,8 +1,15 @@ -namespace Yi.Framework.AiHub.Application.Contracts.Dtos; +using Yi.Framework.AiHub.Domain.Shared.Enums; + +namespace Yi.Framework.AiHub.Application.Contracts.Dtos; public class SessionCreateAndUpdateInput { public string SessionTitle { get; set; } public string SessionContent { get; set; } public string? Remark { get; set; } + + /// + /// 会话类型 + /// + public SessionTypeEnum SessionType { get; set; } = SessionTypeEnum.Chat; } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionDto.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionDto.cs index a4162aa0..0616f214 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionDto.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionDto.cs @@ -1,4 +1,5 @@ using Volo.Abp.Application.Dtos; +using Yi.Framework.AiHub.Domain.Shared.Enums; namespace Yi.Framework.AiHub.Application.Contracts.Dtos; @@ -7,4 +8,9 @@ public class SessionDto : FullAuditedEntityDto public string SessionTitle { get; set; } public string SessionContent { get; set; } public string Remark { get; set; } + + /// + /// 会话类型 + /// + public SessionTypeEnum SessionType { get; set; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionGetListInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionGetListInput.cs index c4dd072a..1b85c460 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionGetListInput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/SessionGetListInput.cs @@ -1,8 +1,14 @@ -using Yi.Framework.Ddd.Application.Contracts; +using Yi.Framework.AiHub.Domain.Shared.Enums; +using Yi.Framework.Ddd.Application.Contracts; namespace Yi.Framework.AiHub.Application.Contracts.Dtos; -public class SessionGetListInput:PagedAllResultRequestDto +public class SessionGetListInput : PagedAllResultRequestDto { public string? SessionTitle { get; set; } + + /// + /// 会话类型 + /// + public SessionTypeEnum? SessionType { get; set; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/SessionService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/SessionService.cs index 1a7cb4f0..4099883a 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/SessionService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/SessionService.cs @@ -84,7 +84,8 @@ public class SessionService : CrudAppService total = 0; var userId = CurrentUser.GetId(); var entities = await _repository._DbQueryable - .Where(x=>x.UserId == userId) + .Where(x => x.UserId == userId) + .WhereIF(input.SessionType.HasValue, x => x.SessionType == input.SessionType!.Value) .OrderByDescending(x => x.Id) .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); return new PagedResultDto(total, entities.Adapt>()); diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/SessionTypeEnum.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/SessionTypeEnum.cs new file mode 100644 index 00000000..adbf7041 --- /dev/null +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/SessionTypeEnum.cs @@ -0,0 +1,17 @@ +namespace Yi.Framework.AiHub.Domain.Shared.Enums; + +/// +/// 会话类型枚举 +/// +public enum SessionTypeEnum +{ + /// + /// 普通聊天 + /// + Chat = 0, + + /// + /// Agent智能体 + /// + Agent = 1 +} diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorClaude/Chats/AnthropicChatCompletionsService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorClaude/Chats/AnthropicChatCompletionsService.cs index 983deee6..dbd7de1c 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorClaude/Chats/AnthropicChatCompletionsService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorClaude/Chats/AnthropicChatCompletionsService.cs @@ -75,10 +75,7 @@ public class AnthropicChatCompletionsService( { Guid errorId = Guid.NewGuid(); var error = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - logger.LogError("Anthropic非流式对话异常 请求地址:{Address},ErrorId:{errorId}, StatusCode: {StatusCode.GetHashCode()} Response: {Response}", - options.Endpoint, - errorId, - response.StatusCode, error); + logger.LogError($"Anthropic非流式对话异常 请求地址:{options.Endpoint},ErrorId:{errorId}, StatusCode: {response.StatusCode.GetHashCode()}, Response: {error}"); throw new Exception( $"恭喜你运气爆棚遇到了错误,尊享包对话异常:StatusCode【{response.StatusCode.GetHashCode()}】,ErrorId【{errorId}】"); } @@ -125,10 +122,7 @@ public class AnthropicChatCompletionsService( { Guid errorId = Guid.NewGuid(); var error = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - logger.LogError("Anthropic流式对话异常 请求地址:{Address},ErrorId:{errorId}, StatusCode: {StatusCode.GetHashCode()} Response: {Response}", - options.Endpoint, - errorId, - response.StatusCode, error); + logger.LogError($"Anthropic流式对话异常 请求地址:{options.Endpoint},ErrorId:{errorId}, StatusCode: {response.StatusCode.GetHashCode()}, Response: {error}"); throw new Exception( $"恭喜你运气爆棚遇到了错误,尊享包对话异常:StatusCode【{response.StatusCode.GetHashCode()}】,ErrorId【{errorId}】"); } diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/SessionAggregateRoot.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/SessionAggregateRoot.cs index 8a25d8da..47614c0f 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/SessionAggregateRoot.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/SessionAggregateRoot.cs @@ -1,5 +1,6 @@ using SqlSugar; using Volo.Abp.Domain.Entities.Auditing; +using Yi.Framework.AiHub.Domain.Shared.Enums; namespace Yi.Framework.AiHub.Domain.Entities.Chat; @@ -9,8 +10,13 @@ public class SessionAggregateRoot : FullAuditedAggregateRoot { public Guid UserId { get; set; } public string SessionTitle { get; set; } - + [SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] public string SessionContent { get; set; } public string? Remark { get; set; } + + /// + /// 会话类型:0-普通聊天,1-Agent智能体 + /// + public SessionTypeEnum SessionType { get; set; } = SessionTypeEnum.Chat; } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Mcp/OnlineSearchTool.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Mcp/OnlineSearchTool.cs index 7935e221..6aebde0a 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Mcp/OnlineSearchTool.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Mcp/OnlineSearchTool.cs @@ -1,16 +1,199 @@ using System.ComponentModel; -using ModelContextProtocol.Server; +using System.Net.Http.Json; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Yi.Framework.AiHub.Domain.Shared.Attributes; namespace Yi.Framework.AiHub.Domain.Mcp; [YiAgentTool] -public class OnlineSearchTool:ISingletonDependency +public class OnlineSearchTool : ISingletonDependency { - [YiAgentTool("联网搜索"),DisplayName("OnlineSearch"), Description("进行在线搜索")] - public string OnlineSearch(string keyword) + private readonly IHttpClientFactory _httpClientFactory; + private readonly ILogger _logger; + private readonly string _baiduApiKey; + private const string BaiduSearchUrl = "https://qianfan.baidubce.com/v2/ai_search/web_search"; + + public OnlineSearchTool( + IHttpClientFactory httpClientFactory, + ILogger logger, + IConfiguration configuration) { - return "奥德赛第一中学学生会会长是:郭老板"; + _httpClientFactory = httpClientFactory; + _logger = logger; + _baiduApiKey = configuration["BaiduSearch:ApiKey"] ?? ""; } -} \ No newline at end of file + + [YiAgentTool("联网搜索"), DisplayName("OnlineSearch"), Description("进行在线搜索,获取最新的网络信息")] + public async Task OnlineSearch(string keyword) + { + if (string.IsNullOrWhiteSpace(keyword)) + { + return "搜索关键词不能为空"; + } + + try + { + var client = _httpClientFactory.CreateClient(); + + // 构建请求体 + var requestBody = new BaiduSearchRequest + { + Messages = new List + { + new() { Role = "user", Content = keyword } + } + }; + + var jsonContent = JsonSerializer.Serialize(requestBody, BaiduJsonContext.Default.BaiduSearchRequest); + var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); + + // 设置请求头 + var request = new HttpRequestMessage(HttpMethod.Post, BaiduSearchUrl) + { + Content = content + }; + request.Headers.Add("Authorization", $"Bearer {_baiduApiKey}"); + + // 发送请求 + var response = await client.SendAsync(request); + + if (!response.IsSuccessStatusCode) + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("百度搜索接口调用失败: {StatusCode}, {Error}", response.StatusCode, errorContent); + return $"搜索失败: {response.StatusCode}"; + } + + var responseJson = await response.Content.ReadAsStringAsync(); + var searchResult = JsonSerializer.Deserialize(responseJson, BaiduJsonContext.Default.BaiduSearchResponse); + + if (searchResult?.References == null || searchResult.References.Count == 0) + { + return "未找到相关搜索结果"; + } + + // 格式化搜索结果返回给AI + return FormatSearchResults(searchResult.References); + } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "百度搜索网络请求异常"); + return "搜索服务暂时不可用,请稍后重试"; + } + catch (TaskCanceledException ex) + { + _logger.LogError(ex, "百度搜索请求超时"); + return "搜索请求超时,请稍后重试"; + } + catch (JsonException ex) + { + _logger.LogError(ex, "百度搜索结果解析失败"); + return "搜索结果解析失败"; + } + catch (Exception ex) + { + _logger.LogError(ex, "百度搜索发生未知异常"); + return "搜索发生异常,请稍后重试"; + } + } + + /// + /// 格式化搜索结果 + /// + private string FormatSearchResults(List references) + { + var sb = new StringBuilder(); + sb.AppendLine("搜索结果:"); + sb.AppendLine(); + + var count = 0; + foreach (var item in references.Take(10)) // 最多返回10条 + { + count++; + sb.AppendLine($"【{count}】{item.Title}"); + sb.AppendLine($"来源:{item.Website} | 时间:{item.Date}"); + sb.AppendLine($"摘要:{item.Snippet}"); + sb.AppendLine($"链接:{item.Url}"); + sb.AppendLine(); + } + + return sb.ToString(); + } +} + +#region 百度搜索 DTO + +/// +/// 百度搜索请求 +/// +public class BaiduSearchRequest +{ + [JsonPropertyName("messages")] + public List Messages { get; set; } = new(); +} + +/// +/// 百度搜索消息 +/// +public class BaiduSearchMessage +{ + [JsonPropertyName("role")] + public string Role { get; set; } = "user"; + + [JsonPropertyName("content")] + public string Content { get; set; } = ""; +} + +/// +/// 百度搜索响应 +/// +public class BaiduSearchResponse +{ + [JsonPropertyName("request_id")] + public string? RequestId { get; set; } + + [JsonPropertyName("references")] + public List? References { get; set; } +} + +/// +/// 百度搜索结果项 +/// +public class BaiduSearchReference +{ + [JsonPropertyName("id")] + public int Id { get; set; } + + [JsonPropertyName("url")] + public string? Url { get; set; } + + [JsonPropertyName("title")] + public string? Title { get; set; } + + [JsonPropertyName("date")] + public string? Date { get; set; } + + [JsonPropertyName("snippet")] + public string? Snippet { get; set; } + + [JsonPropertyName("website")] + public string? Website { get; set; } +} + +#endregion + +#region JSON 序列化上下文 + +[JsonSerializable(typeof(BaiduSearchRequest))] +[JsonSerializable(typeof(BaiduSearchResponse))] +[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] +internal partial class BaiduJsonContext : JsonSerializerContext +{ +} + +#endregion \ No newline at end of file diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 33e89ad6..2caadf6c 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -360,7 +360,7 @@ namespace Yi.Abp.Web var app = context.GetApplicationBuilder(); app.UseRouting(); - //app.ApplicationServices.GetRequiredService().SqlSugarClient.CodeFirst.InitTables(); + //app.ApplicationServices.GetRequiredService().SqlSugarClient.CodeFirst.InitTables(); // app.ApplicationServices.GetRequiredService().SqlSugarClient.CodeFirst.InitTables(); // app.ApplicationServices.GetRequiredService().SqlSugarClient.CodeFirst.InitTables(); diff --git a/Yi.Ai.Vue3/src/api/agent/index.ts b/Yi.Ai.Vue3/src/api/agent/index.ts new file mode 100644 index 00000000..02a4952a --- /dev/null +++ b/Yi.Ai.Vue3/src/api/agent/index.ts @@ -0,0 +1,25 @@ +import type { AgentSendInput, AgentToolOutput } from './types'; +import { get, post } from '@/utils/request'; + +/** + * Agent 发送消息 + */ +export function agentSend(data: AgentSendInput) { + return post('/ai-chat/agent/send', data); +} + +/** + * 获取 Agent 工具列表 + */ +export function getAgentTools() { + return post('/ai-chat/agent/tool').json(); +} + +/** + * 获取 Agent 上下文 + */ +export function getAgentContext(sessionId: string) { + return post(`/ai-chat/agent/context/${sessionId}`).json(); +} + +export * from './types'; diff --git a/Yi.Ai.Vue3/src/api/agent/types.ts b/Yi.Ai.Vue3/src/api/agent/types.ts new file mode 100644 index 00000000..146ffae4 --- /dev/null +++ b/Yi.Ai.Vue3/src/api/agent/types.ts @@ -0,0 +1,51 @@ +/** + * Agent 发送消息输入 + */ +export interface AgentSendInput { + /** 会话id */ + sessionId: string; + /** 用户内容 */ + content: string; + /** api密钥Id */ + tokenId: string; + /** 模型id */ + modelId: string; + /** 已选择工具 */ + tools: string[]; +} + +/** + * Agent 工具输出 + */ +export interface AgentToolOutput { + /** 工具代码 */ + code: string; + /** 工具名称 */ + name: string; +} + +/** + * Agent 结果类型 + */ +export type AgentResultType = 'text' | 'toolCalling' | 'toolCalled' | 'usage' | 'toolCallUsage'; + +/** + * Agent 流式结果输出 + */ +export interface AgentResultOutput { + /** 类型 */ + type: AgentResultType; + /** 内容载体 */ + content: any; +} + +/** + * Agent 用量信息 + */ +export interface AgentUsage { + input_tokens?: number; + output_tokens?: number; + total_tokens?: number; + prompt_tokens?: number; + completion_tokens?: number; +} diff --git a/Yi.Ai.Vue3/src/api/index.ts b/Yi.Ai.Vue3/src/api/index.ts index b165d819..c798162f 100644 --- a/Yi.Ai.Vue3/src/api/index.ts +++ b/Yi.Ai.Vue3/src/api/index.ts @@ -1,4 +1,5 @@ export * from './announcement' +export * from './agent'; export * from './auth'; export * from './chat'; export * from './file'; diff --git a/Yi.Ai.Vue3/src/api/session/types.ts b/Yi.Ai.Vue3/src/api/session/types.ts index e8af8b63..31ac7ebe 100644 --- a/Yi.Ai.Vue3/src/api/session/types.ts +++ b/Yi.Ai.Vue3/src/api/session/types.ts @@ -1,5 +1,15 @@ import type { Component } from 'vue'; +/** + * 会话类型枚举 + */ +export enum SessionTypeEnum { + /** 普通聊天 */ + Chat = 0, + /** Agent智能体 */ + Agent = 1, +} + export interface GetSessionListParams { /** * 创建者 @@ -61,6 +71,10 @@ export interface GetSessionListParams { * 用户id */ userId: number; + /** + * 会话类型 + */ + sessionType?: SessionTypeEnum; } /** @@ -96,6 +110,10 @@ export interface ChatSessionVo { * 自定义的消息前缀图标字段 */ prefixIcon?: Component; + /** + * 会话类型 + */ + sessionType?: SessionTypeEnum; } /** @@ -147,6 +165,10 @@ export interface CreateSessionDTO { * 用户id */ userId: number; + /** + * 会话类型 + */ + sessionType?: SessionTypeEnum; } // export interface CreateSessionVO { diff --git a/Yi.Ai.Vue3/src/assets/images/czld.png b/Yi.Ai.Vue3/src/assets/images/czld.png new file mode 100644 index 0000000000000000000000000000000000000000..f0c18d45635a8e4f29a7ab59b55dc1dc124a1569 GIT binary patch literal 87723 zcmbq)Wm6nX(Cy;x?gY2R-GaL=z6%@NU4kdU-Q8UlcZcAzxGhee;1&oTh~3=x*828YBjuA2EUGd(q3r_bNbzyARUHB{7907ysx0Mb7L{M`XW0Nr;h^@m~`Hit%vrhynHG#Kquawx7{{Ejx|Gx|T9R(0! zq5@C>C`e2IWFjOKBBa0L03iSX83pMd0RIaVR3v0H06GTd|MmXE|N8&+NXRItXn(f> zxF|>fWI`0ee=Y>$w=o!*Be>YpgCm>8Gw4y#)C8!O(ZEb%waF@}#&~V&-=GZ>Ep9c; zZ6@!jtg=oUOS7J?1XUdUcE~~a{AS4daxUs4ygng>bFT4G{y3%RXLO5L?`mpIDQ$Kg zxovVck?3KceP57Ee{X@mpT91ZSkbZz`k)#8eJ&=N zw-=eu3I)D4SvFy9iiA`N&FT5vf5`kD1)#DaTxa+AKgR) z(+niJ>fAK8AsSja>4t2iNAI!p@@-B=tKwm?CF*_PwalkbS+UHgGCLGn1-3h5Hx^y6 zBoOu4Yn7z(+1q!#QrF8puD!pnzdwGWOpYx~?tZ5y;aKqZ$298zZ>ZB!F!~swpgxNq zrQYm%tMDCD5ECjgj`uhfR)@D1LJjS|H<8mLoPL*DX^w4=7Yh9W#r+iK>9R7U_gCB- zz}E%>?Sc>2DKtT<9~|<%LX!OE6uE5qj5Q3)vEHPmtxSWT$r-1Kv+E`~q0iUZrS0yK;?#0W>OkC@P5i^Q}gNwV#&SP`0 zVdqB)N?Us?s=9Q0>q1cV{CQu09=#&7JlPx>Z|S#v_tKB2iw*b|`qhICV;Rj~79jXf z@5B?Sz$@k2h-4m}> z;U7Q=Yn0aTM>L>02z6(5r#NvtDs-5FAW7tfd2zBPxEqB2z=PnwZ~O}|IqI@|_z<{$ zJn=Y$u|l6X{Uny7#^?vt)XVv8na_%a&Cs5Y3K(7-bbtWjw_HJ8toL^P{SBYJ1ju904}!~U`jb2DB&`kl zd(M+#XW@Ia{{AG(7=iRJQw)j{ISwghK&gH^v|1dY(Up6Dj--u+&dGNsDdD4WA$wYg ztg;9cEJfQ?+crcTdw)d~QzL`&$sj%FOE|BkSffK8MK!h+iJW1925m@PcajoqHTXlM z-!b=Di=PPl+|W=Cze{1+d!3 zwU7D?9p8xR?mrxl*ympOv1n?K&_tlNW>VI5tZ|fu=65+5C+SmFxaJps`k|b3Y12+% z$TCroeET7Rv_O5MnS>5?%1ek=*Lcd`PYa=wd=Ok(oItmXc1Qi9BWA?0NT7*33%C*Z zk_mcTs|puqb9ot%GFg8qsWJ~B9fBSF9%2yWwl{0rSJ?+HplH|tT0l+8ZQr)%X!%0$ zbPG#XzHX^k7B!|H^=lvY7L*!p^O?ow7E3-{bekj?vvh;h^WndC!lCr14{5>Fj<`U; z2};rzWtD@&!&m7`LeZNe6!_`J+L!y+o}D}T`C~qb8h#HOI-{#{qoFmroO50rhb_`s zRfA;%E<8h56w?=zoR3*NjgD3_)cy;!ZUt`!Oag-yiMhug1G<$m=ujWj-ILkt+5P3+ zui48%6zp*e_rJ=BkI#Z3QXe3C^?u_^?E4B3%$8`iKI)9A>US$cfe#5H8!m%TU84KX z{fFkinl-(|!B^WT*5+i*EMVILRbYFE{USlZH|eD5ZS5U%yZ85se3<2hPPH|G= zhA{*WTt#?$n=6u%X`}NpnYC{kbuvKCWK(V}8RQJ4BT*aG3t55RJ`{lkAT$z->Hz*% z+Yotog-TMdRVUw>y;-vo#h0mN8*l5-53*H17Ve8@ByU4ov*L7$!G1?{jWa?N7&43l zpBrXZC#c7Em;5;!I-2tA-r^6hti;a@r7i^X3!HhJEYhs2=V=Nbp1jVS2M#s?8a%M+ zwR=eF)cT!L#Oz5Oax~%!?$1!QrKXaeU+f-ULN!uJ<@*i#GuOI1%wE z31wh2W7e3-VEe%`-{JkeX6AW7l}|nvX+8tOzQmR^MXu)DtuFm9D8I(K%{|`>(@+U` ze@MFjTtlD*Sv`uo)|hxPo_ZjY){}XUl?O8B-ebw~eq$X}hh7gAW8Zv9vURHsr0#om z$^*l{@Okd3VU6Xso%EJiyjh~tvZsHN{gSgiMF}~A#aC|_u8M%4iCiz@vogj8(t>ikZ|}ZGw-LP5$i}l_Uje0QA2qR!OEqV;CB25e z#X0*;D^goO*z?v8t@d}@eD)_a4b6pb)|XPU8H;a|E(A{aie6*y!;pPRtw;wJJV)PJFEUUZ*5<9s#b5tBGTea~tM6B31cNbZ@54iqxJ~wmT z?}Mv<&g%gXg`O})wq`3_iIqmY2(5j_FHYIAa(|UxUEVpBS;{^ukhE4mE0F51Lsv7` zeS0lnvZ#(xfQV~jTDA;%u3l^(#ZYC}ujdAe`8A37X~eVyNMny+cSc)!VZXkWX#e_3 zA0`_0B^r%k;hdOi!+?r6E4*r}NnvuHZOE?o((s(2xc%32{rH;lTnvfQS?^RmukA*Y z*kYJVQHIUu*&y2VL4G@Ds;+RZyB(3@oLnUA`T93zp!9Zf>~+zx+KwhX2Mti$SrXI9 zAaa)T1*N?_={LYOQmFi-_v>`&xY`oc&?h$IeMnGZveN*L#G1blI^4p?cyuq?OXceZ z>FTKa@{7k-56Npt+TM1NfB+)7w>X*2+NHm5;rf6>NBV@X^ZuLd#Cd@Xd97L5CB4mb z@LvFpeP|zVf?b2C`F*lCLdBL=z|U34Pn@?)bZYTcs2&SEcliS6 zNC7jiK`>6J5mdUtZMdg5V_+gVNs#G!qfn>fSJqfiHLG<|W$qN&)RxTjI`2x(lPkko zqh;ny=PY@Y+bm}^-p6UA({wjuV%drwf^cXC*1@|NdS(qEl{UHPn(OhJ1==E9iI@j7 zZmhLw%za1LA~~yAIE~wc zzPLVY?!OuK0m(t`y;WF!lhWKN_!&~v6+h( zhZ6NVp1dt{ZMJ%ak8t?>L>*>3MbEb2>fY3O;^NzilJhB2pMliN3q{G90z5VabA#Zw z+*e}LMKU`%zJ9u@EdTPFDf0YBs0-&Ro$Ztt(e6OS`)0PB`uml7vpR2G`~i&ISKU~I z7p%;JFb7!^%S6nw$5zxi;*C8PU(?7#aqz^Yi!N)9b~$I+MzRWf)$s0=fvT9sycK&r z;X<`gZ@+he`TK+V1j#xet0f(MWeo@SY*~a~geiJUp&X~2^SB`QrdcbK+-7`E1}1i< z_|Mi>tO>9o`@6tKhwf~!dV^C{iW4=Lq<2({^rtsqJNfZG?{w zy_D4Y!Sf_z5yl5smx{7@W75{aE$SYppL`5gV&km>J1PF!X?yJ2Jih-DhKauRs@Jyc zL(UZ*Hz}-hea`iQ=3giyEk=l%iFOD3eg{B88K+>9;H2Cfed^f znJ!XpAKFVRWF%IFjPUdBxAtQwd_)s5K!YL`!`j&y*pTE!GI9^>-)Jjzy;m=HIO-y$ z>!tFz9C)7XK-_WL_8gfw@c$ycwJp46(P$>W3%pP8`H*mBG|g z!N0>TOijQ3 z`4ha&-pz4+6q~Eo8PG9)P9$y8hpY{>{r7QGHGDAaRzsQPFpL?hlMmzwBEgP zqm}Eq>Vaq)xs795I3^4pbfA%e!N00LdVCG}lQeqdGO-c}?HQl@GWks?$0}5La@e{W zjobd^wXmBh{@5n=$Lf;AgmDa>ewZn{LhaJoy#5447(D4uT`-v$n^~#6;h!ypL!w_) z#+nmAoQR<+sqDtmZ&yRS1g9skwFjs}dG>MLFWH7!7b#LUsBqxsuW9i+G9{hDe|Gh*cAj!e38%<|lT_=rH7pEH5a&F}` z(+&`_@c<-7^z_}UjibK2t-KwZ&$i{WVpI9AB3N2Yykq3?YA~}A z6(f$%#=+Jc@?PM9gVW*snNZH>vD%Ymtou3=I%}YF(ME^en{%>mq6C57^XKpTud;X$ zu2~@g&h-vcYSO^uIWK&ehLs+&$3qH&yecYNW;LZ2-$~K@o38qw$PDh}oJ~Q|) z06;8DAaG)U$QZdfKD&q$&_ycXGc6##m+dCK`!0X+FcF&|PeMBsiOL|GQ`$GevLY?z zERa!D@QvuszO|gytqPClC+T2?SHadbO**aVIkcfNv4sN^#UfVVI1i&ZN#f$UAYf%M z5Hov-p7IH(?tIa6dX9SeA@VFm&KT_G}8r z3;OlSuJ&h9$PUEq*()hQo}D=HjTGW}swp>7t3NzFmm*=`8AAK%Ci*@O)9Ieu zJ2o%7z%PwFzD^RSIYD#DGHn${hNM!<>&$R-`nY96URA4X@*$9Jh;E?cLOYjypS;=) z4?bub*^g{fyiLb#luYStILu35e~X3Wn`E6h=(_pYj2tQTJoY2!(62%C=92Z}nhmE9 z7Ld;cELb|0RFxsqFEs)J_ynO3VkY$a!Yx%!1@;UdAB1yT}s7@rl~d$#|4E z?l|Ls8H!py<4RjZO40Ce+Jm_l;i~PAa^ZC6395srb3QBWSwSZ9{4W||X~wFVPy1?% zEmz%V>5@T1Wk-KvQl>si(MP{8WWo@Am9V`J(lTu3R^Mc0QC>^-e5uQ90VtDK?y|D_ zcv1~&b`YNw*84WXPt(FGn{LaB6!fbw#KL_i7AqX)FT5_Blx~s)858J8+t%g-3pZSK ztH){iyHeHth4PcARC*h&U2uHFwV2EJ_a`1-+Lo6Tw+>tDH>7e;1*@*SKE%z|)Vex+ ze@!(|k$9M=AFhJGDF>_DPwQu$_X8`g?_y^+x@C~<+VWA&GRwi35$F!ZqSAxSx%Db+ ziUKT`@A40p>c^{&Iuhf&G8!*I6E~(fq(u`U8?|t0i)^$$F{PDOZu6hZPVP=}cGG+=6{s)_D zCfyWqnKYt1ca!sv7O5NbDHjJ~i`9c|ShLl&M4x$+*W~G~&{y6-G^;z;@$D+yfE3r<%cl`H%ex4Rd^env99P$t~YhKMDy?$tz>e-h=nbl?AKIPE%gb5_T2>-Hh2uFTellDYSFK zLB9(bk5#G(7GV@B1Izuzh^i);ajoWwwQFm{QyV&090Q1Ukb|~u= zsjsIN=jSo-zMjS)LWD^}1xU!>>KSt$J#68T+1<*%+xu}zsHtr+_w$}=HL2mFSXKQ% zHjrF~D=Sy-5mvTAdGc?X#Md4&K{w%EOYrc7%}ckC^_Q8p(1172N) zsxdEYXZCfsO%m>cxOM)17bZN2o9SHZL$AaNE6dMGnAf#b*?dGt@zoDSnk{Azv(6H5 zwQxXP(UdIL9~N&AMSt;V7MZ^&?lQ(1zL6gE%8;x9D@qlQLg9$1`1UmR%P}5U%>c7D z;mOLAtedW?q_r-^qgR2h2a#j?1I*EvqrK8wbmjhO%+q3rH>UpVt48{#c+!V;QL2ii zByDD@7GBrD!GoDY<^ak(<0V)L!JYkVx&Cc*XE%tpkA=2;yfqyCK{KJj0A=Y^|RE=WapNe3}#@>g;+n^$61qW}K+_ zgtg0tWG7+Sjwz@sK1&ogSubvSpP?#odB0_E^tzQVenoE!ynDWM#xUM`|`kw9CyVJmeSA$9sL#j5$_*|2Blhx~)!c8#|mFq?o>e329#2=Rh;gBiO` zA-OFzBFJ5=9O>MqBKg=q29iRW#rhuz`E-V~LiXmc6F7!^uV{33l`E-iZdSQUZzBDQ{7+>8t zK{Z^{j&t6Ap>##NpakSKd$zmO%RMZwR!e84KD%Cc_5Hw9VeYf`4~vj@dSt?Z-v2cs-oP*R(N5)&|0rc$?=+ght>%^8ik9?hE+d;)_MSJ}t z%12Ve^FqI0IYPQgXZN`?-R~`!|0~+!;7!I3A`VMPgq!`9d!kn6K@o}3_HdSEAD0S>?XFR;cWmQ;V+<=a zZ%0=+XqLZIjJAz7#SCY5@JiNkQ6{waOa5<+7-QQaZWFWOUv*3gdZDKIVxSj4SDrIc zCwIvB?CR`geuFFY7YH?o__cD#Z#|31x zF42T5)(5Ru+DZbsQEAbd{oFC}w9(z0JksG0`bG;D(K0Rw&fqdD^-vu8@C zRcqiRZ}yh#q$J}vSqJNSdg=8%n?i=|C|Mf)TPs@BZKF5%$YQId@%I`?BiDSDO%XDq zbSY~>we+PJR~>BeqecaGDykJ3pH%!Kk~3f~eA7#p0tnjWW(6_u#qoWpQm@f+yIdwR{3L1L@=x zqSAIaI}wJ@UnEBv`isxgJI|p|vPSrnN9H6_;Yx%Txex_SbhR8~5h2d9M1|Ta)e{@| zOp=G>>1g-HJw_%w<|?FLEu!`(bNw7xY%e#wssg&$n+m)oOcOXsFnBb>QGAV9+5p;5 z&b#YAiq_#^j?sHX8mA@uquvO_11HNSQEMYHNSnvetP)~L8X}AB7^*gQ0)5f;FGH~=;NH>bZGj4X8&dG za>kYAFQ7TPqW7jLA+CkEP?C>)dY}XCUb}WJMZEvDLeq+6er0AE>-6`#f=}S?Q%)DJ zJxCgPs<}QSpqu<+Mnr_OyfnluFO5~-MARg}G24#|nX%}=wLg}g+eKoo5Q8vTytYGz;-qXj&=DtfykHDZh z43r|It9{|RGT5UN0Cpr>Ifw(UXLUw-MzC_JNgY;zTBxF$T|i?y zaOn_XEb~wxy+yJwL0SQk{%YMsbc4=r5L6Sy!ioXG)`Ng3ST(m1j2)ff&8DQ(Juv++ z8($ZUwdbC>Mg_ih*vQ-JF|I$lxVWy?>z7la$5wtN4{Am8E2ZU|e3IR3= zE*XgP6o6hF-A>M%*M6r&J%zlsAlJt?y8hwy!6#J^j-k4AI`Xs`0>+Obm_d~W|f%9SDPqd`7IllFJxB#k~l zQUu7O_aaI=i-$Y>=+_ovJ2Oj9fjVJA?%LJu+ak-7C=5&Zr>wB@+NNok5I#yS9vd6< zxdfCWkZrL#7YK!~_a0uo27vesnmGB^dPVUjS%bGO+P8cOQ^a4ceev?AZcbs zonDfWRNi{SC%=ul^&aMUwcKB*?*hhu<5RC$Y{%79rp28Oz868!oR=wjB{{sf+cHNI zGPjXQp!oz%RKAW%Grb`0dRQ@t6<>2C?aU-OK=|-g5@8F0vVZ~&)eVa>4b~=RIB#q~ zHRd(Qs|`#Uv)8tV9&d&MnU>y}fnuP2%n80mY*JMn+Ri~ZEYMEJ?CANoR#E5G-Sav9 zNkc0&W};@_-NFotm?p@@va^Rw=w|>dhg-wF+V|g33vOo3w@xl+U|4>+(BH;3aVGho z+2N~hI^HmnQ1uyQAJXgfMf@c@7_sO0!XwmQ0u4)x@v^v40TCs3xB}%Xj=5MzI|)_z z$5^k=)U9B~+g-AI6wo*#hKgmId7E1j2F{y$9lNNw?x8r07t&$At|Y?7-m~_x&$ebN#WGkF>1&ct&L zkUguLW7`VQ5H>mk+8a1?UvD>n5WO_3pGj9Q__YT=Qs^$+c-I-N-v$OG`a(p0HNUlG z!dUD|ka(3Gi4pxG^e^po_b`#&3n-c>tRM_AHw^D?tiz_E-~cLPsj8QCA_AZAtLS5Z z@9i6=vOiagLV1e&GiIh>&_x;CGJ058y6-V&hX~n#eZXJ9$K-$u>8!9tFRf=f(T9Ss#7DxCU{7M}1>q8Iv?#AuuHVbZ z!gVHZwfca;Z)z7UG}G$1Z#dCXO|jEmjquW(?G|d&h@6vr-gGXxt{)cWF2Dm~hvIqp z%J=V}(eIS~=*#jf=xJDZret{A^LjSh_Tl%hfo~3M)J@>UT?4?;=-5JqPF?qOBrq*L`K?~DPd-aO@F%d$ z!q!%K2@+r5cEZozy!h z>?AK}XmlGE5;z+!#Igf?!f8G7^+zju8uGOX(JLfBO)nJ)UR%3J00P}eD{#!nDNOZ> znbN20D3%PdP8GIT{*J(Rylu(z?la^mTS=vh>l#2D(iA zLN|q4&sqRHF1+1@=hN~KW3eKT{ff4HB~Umam35C^W_e$5qwRVj6L9Q3%Qoj|9d&mP8a-IrzxWj+ZFf$6;@PLYvpv}f{pC_o z6WHLP6i01Bt)NX0J_~B{Wvp}2HtUFJhRAvPqU*WmFX&O<_a}=SiDazFM)a&l*&5DB z`07N~;U=-x5*w~(VW7qGY(8cMwKp^c>1&MkS>CwUE_TVEVTBn!zz?y+s3tB$NuYsq z9-Bi1`io9ZJ+gl1c69&o1@4BR=aG9=va3EwHFu^MhJ=3Ccvj)w0SqxtTkfm#ug* zh_2 z)yT4|QAU$~u7G|iuDBT3&wuo_6ChJ80*z3z;$UahAx3^`N2yJz&mSXmke? zn=nW9eyoU$3m^YNz3!6U^T!ary2)b9M@G2;!9mB1BpS}DyRCO-)W51*hO?W>jH*E8 zj8}s&!R*WQ1d(3U6Y3(y%cG4N*?s>xtObZjy%wtwYjRxqVqkxGH@YZMwpR`PqK|3l zr;?CHh>2NkEP4jf*kS|Q!@RZqD{4L3N9~f0Vl83%-RiXMImgphzq7|*mnOJ!Sl+YK zXDLDSQ2p0aiaP~u+Ak#Ac0v8nxD?L*RK(JaYOC}grUQck-G1tmvAyzDqr7-p7m z*32dGI=nVoef{x6U=rr<-b*qeW@VU2wlHy3^z!Uhi{hgD)N2N6Uvz7k@A~ziVz&GA zr1LCSag~a5Y+_W@nWLf7ib8$YQ0|cGe&D>rJl89D##HXt)1eDZiDFu?gH9gtWJKVG zFlJHOG)<>Et1}jV(K4yf%A@DRO73f0;8Cb`{$k0(V=ZOX7Mg>~#A6}jb%Fu;wwRF8 zZHAyfQ_HSH1E_CYNc@IsTj}_thAyYyhODs46qH7AG&%T;wY78vEeRt58cIPUI&ab6 zS}SV#^Aw`%BA}26h{t`P#HJ4pM@mG5`?yGqE*XJHDhw%>jT(&JkFBQjqV!wcSN;WP zk@+op^)VkfzqLYi3^%h4BVx_X?2>PP)i|7O3IGHr1SMKwM<9Jq;k9{>q}9} z+s)#?fXPb^y|AtO6S1j^8slG2UrmHpRgqXMFX#Df3-IOBXF6+j{ai1V8^2}~iPqXg zc|~epteE{Y(V}r-3V-XD)w5FxtCFYgDauRirAcV461D%<2s4vBUCPO?==q}E-m{^> z)^jBtFpt-$?m|bkuAqOvJI}|h75Q7hI{D}Ll<^E%eGvdRp?DYtg$`GlTG7kFj4+=* zUeSUJ%Y|DcPZcS@33|{EZ(`j~R^6O@fSkn3@wWY-c&EzB=C7YKNihAJ}FIffEXy?Pngds=j#o3Pd|>Pq&DLh`bK_O;G^SN zJ~fl8;;G!(r83#fxbyzw9JZdqE_jSPbII5W9q{1PUEAx z5h6Kt{&wJj`!;<+tlCy{swpYeN6HnJA(G*czeg^pQ{bz-?R=3}klyZ~TyJ>k>j(38 zl|sdm+}UVkJoyc<^(oy|Re|rjhr71B?cxYPQp!KYdoT0IV1lhVuMgSmd<_=Ltv7cY z)Fx+DnSuRm)i08CmFkJ^1Z};9%pbL;7kH2)p1* z&Z`@060OnFkWO0fE?oC*m%7DL*6Cf2GF!_?9wRs%NL4w`3=;ueA#`HRvJ|Y^r4kl=BMFeqMEu!-cM^95u`D6T`heUYd%2EI#6SbEoe9?nN z@D$-8`t7i9*$Bps4Xfl070}z&%`q?Q;`s(H1f__neN7lG-J5_Ya}_O62T2~T{A}! zaVkD>DT_YnmJzIv6;o&&QZ@@ATh#Krr+0AeoplF!A*Kygtl5q zh;O+R8%6hBHagQaNI*xlH!K$m?K0B1S_nfugl>vC%Wve6ew)qC$w^TToVQ?-8JyL? z&$_(Fjb94J4J+7n8-C&i74`VJGldNTp@-=+U6|(fT1c-Voa*1?n(oLox%oY{8p}J~ z<9?*Lm)-X|$%0vuUn(W5=6!2B7aa!OiXJO6Gcdx1aUwaKqsyZ}`PFei0^|Jsk;IN^ z`{HOkmn}z5q|94jay!R#vkN&Acaeba4%0n9H<1qS+Zzy{&wqnV0{VA;U@JsE?L*Y6iRH9BX0}AwJ%Mim+a6 zhmUxkW-LAh6gNq9LxX+ZQ@nX{PA?kx-a1nHvwD5ZnRRkBuhaaoMYE3!eA!-0szt+N zgbaxAwh78hDHE3&WI%rsW@LgV&%muy+3ELEn71r?^l^*TnI0;{8nx%HL z!{^@m#|<>DFYItdtMCY#edxH6ac9ly&?)*bxCoVUQPR-;S46$+tc!#qKe@E9VG?5= zCiz)5ys^)@TCZx&)gfo*=|wi#G!a+E>zU*H;U$s;KWp%(@`+_6gB+RqIOatgZ``dcDW?r&gqY;$3;}W%oY9{NAok3*BQT!y(@C2dD?-nH$k=7$1VZ zW7*(x1{Ww|C3^Dlfb5+c*?m1fiOc}a_BBbnHU`~HI@wJJlxqCV<6?m#1#auHwVLK@ zt84Fa%x?*$`;Ze&B#ocrl-Q<(8^ITMxy8>@uK~X+E4sUxP+vx zMOte|!o~=dB@Ym>g2KEqD6*F3QBDyc^h{~)ZxO5i;Z>?6|^$%t;h5%e&V&t)tPGq)^2+R8+s2&c`4vq z%FM!{G?K=_4I-#|nUxx{jXw2+ba>$EeU=KgHcfn236r7dmga_ZCl|i;ivkb=%%t7` z-{`N(*OqUx^4>NS7k|Vxl~}`k%>Eje%}v-nvtD*}WBU3RAZ{TdpE%ldPG)9F+3oHL3Oj53b^6Sb@)|!H`jt5toE$~6n(B8b6eK7S&f$kdfNjJJ@_@U5seW^h{(!y%R!FAJ~Tn0UA<2~8Dul_G{)B`b5#(q004TJ z(b)i&Dn+YN-Zxu*P1C+4M53Tx+gzCzT3DRdkGb3ZXSnA!E>aUsZ+&2Jl3B~dO+J>b z+4?5TM>+63FrEsE7c0Om!k8&zRKfHRO^8YV)saO%GMDbkJ>tI*qhmUBt<}UkQ+rcu z3VS*#2fLjr!w`Bvhy97-<6(b1uQT%l0{Ru4;`}I#`e9rIOFIO5h zSAgsP6%lG7a5jx02xdVFj@znQ&qL>=&eqnI+ai!u)z{({$vvMvbf?EZepE!~mM#Ct zwOLXik)`SI@B~+6w??PObQB~(@a$kG=bYGrj*$-07U_zhNPj>O#J)O2er=P;ofJM) zr>Bx2nU_lF}ZNkf4@mSK=GI{V1nyV@t{Ede@U{!*X_)boQ zM4Xjvt;~{@dwCxC83w}RF#WS7T=FPQYU=5dgY?<4v!SXWJ$j(I~jcc5g0Nb zpFm-wx#(i!UZf)Q&IQ;X#KP8f&M(zk63>oO3@Tle|gJ>oh4(Pv^8& z>%HoX5r#y@fuW5`#uKoBsOfV=3EN19aKZXPA?pN*_lkA69m(X# z{h$*TSF;#IEkSWQI9MoZ-;q;wOmr$!aBkzV4%Y6~Tc(n)^igm_i~Cnpl0T-Q?i(+K z%e_OkrR^-Jz4TeT%Iy14Q80noTeO1w&cNNOCR?3rTqIt_X7zpR@WGA)xN$pi^xo{U zPW{?id|EKGLR^#NbNNKCVlZYm$SwijHb1%Q$RC0jjN*JVdC|`8eU{$ToE%{%#O=&K zxY&O|aTT(I|A;}}B72!htH+<*%Vg;*!HHIy$*nkgqJC+|qgIE#$KqFJ{oC8gWr<@? z!26HeqXz^0*SD*U_HHVpVhdsHy!OFVz*fuPR~jb`>h(q6C0XNmzTsmM#yCiwOm+(I z@`k8IJ{Opk13SKrzClq$qWmmrHS4z9`w>|BX6$mwcgsX3M)Cx~{g1?z(MA^>CN_v8 z+ikjXrI+K2#N5OyH4pu*XVL*U@Jz$f$S;Vjj6hfa#N)S8 zZXZ>@v5+(UW$yR`_kR0i{Y~{0eM1|vjeDB$y>$k0UoT^}GU0#!DP35}`jDo1YYpR> z;mdE=iP~qAh=gIqNmL~@oJ-_X4ag>k_rZD0%?8*}ICD|JGuSB3^esx=#$BNG3UkhZ zdb9`fa{leO3Jz@H+W#mxg5+W_KqR{?oFGo8EW{Hj1zxn8wH-IN5FI3fJdDGub!j!f z6KqfnBNqB6(PSnBp!^eU{%ik(|EI$Qpb`SyBP-I_r@Az!G!pFZcgB0$oQe1``4^!5T+z&z z4ARwc({fPpi6OzKHAsjISK&OT1!1vYWwT3qW{b=}8r0rX6!+o1yPt&^fT>}OrATu) z!$Kt+fIn)SF}(e%9vB-zH1%PF^+D)!-bcSBTq*fKqV{T;E1#khG{Ibd%#5TxBiORm z*Am;|h30!ISVgFo?pC7|nB%YFjgR}$qbdUDEE!43&i<{*MONBrw+WOfNimZw3NJW| zr4kWmp#){W2o6hBDQRnWXxfI=FADK?sm|3!>|MoAD=?OR+C;F`KM7Twd-s0d{))6S zNG`OIJ5~rtHFr%sI5-WWQvWxlQ+&eFtJyp1g(3#47P8lKM%Thi3K?^TDf3dw+#aDq=1)kA@u{TqQ~IR_ z7#ppLMtR-Kp2%3m!)W zZEmEPT1GULKu;ZfmrGCU6H05ED^8JRiNz>7@wZ*zYEq*5FPg7@AMb)nUMxJ44Nq`S zOISSl->Uv#2>lDF5kFhnt!l^$ecZ9zj2#~S4=ynKS)Da@B;p5)B_{G;016i6)Pa8f z&viF#x}zU`Kr|VWi3wXcUL4z-i)fXSbbzrqK@cW0x&UxR9WPP+oD)wsX5&ZX8rH-} zlm;%wSvY_}@rA(wP=Kkez;P@0Tx+nwTGu(E7_PLzMFCs5<<;cT$S2kM@Lej1B zbzTttjqAq5FfPRCP^H@CM)QQ`=&f4L%x_$YPF56rGHkeC#xlpFR7R=EBXbhj>;}uGRM169g`UZVabr9>D|uN8l$#ktfn< zbFS_A+ne&&YNuFz6BfnFWfIe_eSrPBfq|sXYx<1#2iEILgr91f=efyaKpTi(U4ejBU$Di!pU?jLgYRqk`ql>HFCgLck6y1~%As&IE~RG-_D*c6 z9krD%ky3I+h)amUFC$+X)A>&%lw%r~5fm7=3*UJ?lPzBlul@omp2>wFyxXpBY-o35 z5o88(A(|nQAqF8*zqCGx8E6}#kD5>?PN4*g{7%ZAv9kN9^c&@I7-RXB8Drz)*Dph- zGa<=Ob6&&-Tv2g!lP*%2POj&6=BwZ-!te%u%Q0$4$iY*Gu}cJY;znP~1oM^Eu+QN6 zu-)B z7nhm;*bv+-xsi&; z)D~u1vhgl^7l-_Nzf>p%CV6hD*k>TI`=TsKN!-#%J{Y6sSQ2tlY8R!L^<6(uh*`uh z^X6!B=WAU49{_4VmA`MA6@>3-%tE4U!D1K+W9G{V$N`s*J1&kW~=a7%WHg> z!hDa!>1zcFs29(LUJM5a+0xwCBxJ&1N5tEf;$2t}d!70}T{-DYmMrV$vz)>pz?4PJ zg!tQO-gQ=EMwl1~H?g5FgqO9pw%2S_H{^8FT?BE2@f*`pH53#S_v`DU_#e>z2`%%# zGT3ufAeAp<0A*+@xiq9GJ{V^iH$E$8<3t4fdFBiQ&jxgj$ZW+7${Bq;A5*j4p5j

g+4MLn8+LA93AOmN&I_wl`N_OX4N*EAgqV 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�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 -// 智能体功能 - 预留 +import type { BubbleProps } from 'vue-element-plus-x/types/Bubble'; +import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList'; +import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking'; +import { Loading, Tools, Check, Plus, Delete } from '@element-plus/icons-vue'; +import { ElIcon, ElMessage, ElMessageBox } from 'element-plus'; +import { computed, onMounted, ref, watch } from 'vue'; +import { Sender } from 'vue-element-plus-x'; +import { agentSend, getAgentTools, getAgentContext } from '@/api/agent'; +import type { AgentToolOutput, AgentResultOutput, AgentUsage } from '@/api/agent/types'; +import { getSelectableTokenInfo } from '@/api'; +import { useUserStore } from '@/stores/modules/user'; +import { useAgentSessionStore } from '@/stores/modules/agentSession'; +import { getUserProfilePicture } from '@/utils/user.ts'; +import YMarkdown from '@/vue-element-plus-y/components/XMarkdown/index.vue'; +import agentAvatar from '@/assets/images/czld.png'; +import '@/styles/github-markdown.css'; +import '@/styles/yixin-markdown.scss'; + +// 消息类型定义 +type MessageItem = BubbleProps & { + key: number; + role: 'ai' | 'user' | 'assistant'; + avatar: string; + thinkingStatus?: ThinkingStatus; + thinlCollapse?: boolean; + reasoning_content?: string; + toolCalls?: { name: string; status: 'calling' | 'called'; result?: any; usage?: { prompt: number; completion: number; total: number } }[]; + tokenUsage?: { prompt: number; completion: number; total: number }; +}; + +const userStore = useUserStore(); +const agentSessionStore = useAgentSessionStore(); + +// 响应式数据 +const inputValue = ref(''); +const bubbleItems = ref([]); +const bubbleListRef = ref(null); +const isSending = ref(false); +const sessionId = ref(''); + +// 会话列表相关 +const showSessionList = ref(true); + +// 工具相关 +const availableTools = ref([]); +const selectedTools = ref([]); +const showToolsPanel = ref(false); + +// 配置相关 +const tokenId = ref(''); +const tokenOptions = ref([]); +const tokenLoading = ref(false); +const modelId = ref('gpt-5.2-chat'); + +// 加载Token列表 +async function loadTokens() { + tokenLoading.value = true; + try { + const res = await getSelectableTokenInfo(); + const data = Array.isArray(res) ? res : (res as any).data || []; + tokenOptions.value = data; + // 默认选中第一个可用的token + if (tokenOptions.value.length > 0 && !tokenId.value) { + const firstAvailable = tokenOptions.value.find(t => !t.isDisabled); + if (firstAvailable) { + tokenId.value = firstAvailable.tokenId; + } + } + } catch (error) { + console.error('加载Token列表失败:', error); + } finally { + tokenLoading.value = false; + } +} + +// 加载工具列表 +async function loadTools() { + try { + const res = await getAgentTools(); + availableTools.value = res.data || []; + // 默认选中所有工具 + selectedTools.value = availableTools.value.map(t => t.code); + } catch (error) { + console.error('加载工具列表失败:', error); + } +} + +onMounted(() => { + loadTokens(); + loadTools(); + // 加载会话列表 + if (userStore.token) { + agentSessionStore.requestSessionList(1); + } +}); + +// 创建新会话 +async function createNewSession() { + sessionId.value = ''; + bubbleItems.value = []; + agentSessionStore.setCurrentSession(null); +} + +// 选择会话 +async function selectSession(session: any) { + sessionId.value = session.id; + agentSessionStore.setCurrentSession(session); + bubbleItems.value = []; + + // 加载历史上下文 + await loadSessionContext(session.id); +} + +// 加载会话历史上下文 +async function loadSessionContext(sid: string) { + try { + const res = await getAgentContext(sid); + + // 获取实际数据,可能是 res.data 或直接是 res + let rawData = res?.data ?? res; + if (!rawData) return; + + // 如果是字符串则解析JSON + let contextData = typeof rawData === 'string' ? JSON.parse(rawData) : rawData; + + // 获取消息列表 + const messages = contextData?.storeState?.messages || []; + + if (messages.length === 0) return; + + // 转换为消息列表 + messages.forEach((msg: any, index: number) => { + const isUser = msg.role === 'user'; + const content = msg.contents + ?.filter((c: any) => c.$type === 'text') + ?.map((c: any) => c.text) + ?.join('') || ''; + + if (content) { + const obj: MessageItem = { + key: index, + avatar: isUser ? getUserProfilePicture() : agentAvatar, + avatarSize: '32px', + role: isUser ? 'user' : 'assistant', + placement: isUser ? 'end' : 'start', + isMarkdown: !isUser, + loading: false, + content, + reasoning_content: '', + thinkingStatus: 'end', + thinlCollapse: false, + noStyle: !isUser, + toolCalls: [], + }; + bubbleItems.value.push(obj); + } + }); + + // 滚动到底部 + setTimeout(() => { + bubbleListRef.value?.scrollToBottom(); + }, 100); + } catch (error) { + console.error('加载会话上下文失败:', error); + } +} + +// 删除会话 +async function handleDeleteSession(session: any, event: Event) { + event.stopPropagation(); + try { + await ElMessageBox.confirm('确定要删除该会话吗?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }); + await agentSessionStore.deleteSession([session.id]); + if (sessionId.value === session.id) { + createNewSession(); + } + ElMessage.success('删除成功'); + } catch { + // 取消删除 + } +} + +// 切换工具选择 +function toggleTool(code: string) { + const index = selectedTools.value.indexOf(code); + if (index > -1) { + selectedTools.value.splice(index, 1); + } else { + selectedTools.value.push(code); + } +} + +// 添加消息 +function addMessage(message: string, isUser: boolean) { + const i = bubbleItems.value.length; + const obj: MessageItem = { + key: i, + avatar: isUser ? getUserProfilePicture() : agentAvatar, + avatarSize: '32px', + role: isUser ? 'user' : 'assistant', + placement: isUser ? 'end' : 'start', + isMarkdown: !isUser, + loading: !isUser, + content: message || '', + reasoning_content: '', + thinkingStatus: 'start', + thinlCollapse: false, + noStyle: !isUser, + toolCalls: [], + }; + bubbleItems.value.push(obj); +} + +// AbortController 用于取消请求 +let abortController: AbortController | null = null; + +// 临时存储工具调用用量 +let pendingToolUsage: { prompt: number; completion: number; total: number } | null = null; + +// 处理Agent流式数据 +function handleAgentChunk(data: AgentResultOutput) { + const latest = bubbleItems.value[bubbleItems.value.length - 1]; + if (!latest) return; + + switch (data.type) { + case 'text': + latest.content += data.content || ''; + latest.loading = false; + break; + case 'toolCalling': + // 工具调用中 + if (!latest.toolCalls) latest.toolCalls = []; + latest.toolCalls.push({ + name: data.content as string, + status: 'calling', + }); + // 清空待处理的用量 + pendingToolUsage = null; + break; + case 'toolCallUsage': + // 工具调用用量统计 - 先保存,等 toolCalled 时再设置 + const toolUsage = data.content as AgentUsage; + pendingToolUsage = { + prompt: toolUsage.input_tokens || toolUsage.prompt_tokens || 0, + completion: toolUsage.output_tokens || toolUsage.completion_tokens || 0, + total: toolUsage.total_tokens || 0, + }; + // 同时尝试设置到最后一个工具调用 + if (latest.toolCalls && latest.toolCalls.length > 0) { + const lastTool = latest.toolCalls[latest.toolCalls.length - 1]; + if (lastTool) { + lastTool.usage = pendingToolUsage; + } + } + break; + case 'toolCalled': + // 工具调用完成 + if (latest.toolCalls && latest.toolCalls.length > 0) { + const lastTool = latest.toolCalls[latest.toolCalls.length - 1]; + if (lastTool) { + lastTool.status = 'called'; + lastTool.result = data.content; + // 如果有待处理的用量,设置到这个工具调用 + if (pendingToolUsage && !lastTool.usage) { + lastTool.usage = pendingToolUsage; + } + } + } + pendingToolUsage = null; + break; + case 'usage': + // 对话用量统计 + const chatUsage = data.content as AgentUsage; + latest.tokenUsage = { + prompt: chatUsage.input_tokens || chatUsage.prompt_tokens || 0, + completion: chatUsage.output_tokens || chatUsage.completion_tokens || 0, + total: chatUsage.total_tokens || 0, + }; + break; + } +} + +// 发送消息 +async function startSSE(chatContent: string) { + if (isSending.value) return; + if (!chatContent.trim()) { + ElMessage.warning('请输入消息内容'); + return; + } + if (!tokenId.value) { + ElMessage.warning('请先选择 API 密钥'); + showToolsPanel.value = true; + return; + } + + isSending.value = true; + inputValue.value = ''; + + // 如果没有会话ID,先创建会话 + let currentSessionId = sessionId.value; + if (!currentSessionId && userStore.token) { + const newSession = await agentSessionStore.createSession({ + sessionTitle: chatContent.slice(0, 20), + sessionContent: chatContent, + userId: userStore.userInfo?.userId as number, + }); + if (newSession) { + currentSessionId = newSession.id!; + sessionId.value = currentSessionId; + } else { + currentSessionId = crypto.randomUUID(); + sessionId.value = currentSessionId; + } + } else if (!currentSessionId) { + currentSessionId = crypto.randomUUID(); + sessionId.value = currentSessionId; + } + + // 添加用户消息和AI消息占位 + addMessage(chatContent, true); + addMessage('', false); + + // 滚动到底部 + setTimeout(() => { + bubbleListRef.value?.scrollToBottom(); + }, 100); + + abortController = new AbortController(); + + try { + const response = await fetch(`${import.meta.env.VITE_WEB_BASE_API}/ai-chat/agent/send`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${userStore.token}`, + }, + body: JSON.stringify({ + sessionId: currentSessionId, + content: chatContent, + tokenId: tokenId.value, + modelId: modelId.value, + tools: selectedTools.value, + }), + signal: abortController.signal, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const reader = response.body?.getReader(); + if (!reader) throw new Error('No reader available'); + + const decoder = new TextDecoder(); + let buffer = ''; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; + + for (const line of lines) { + if (line.startsWith('data: ')) { + const data = line.slice(6).trim(); + if (data === '[DONE]') { + break; + } + try { + const parsed = JSON.parse(data) as AgentResultOutput; + handleAgentChunk(parsed); + } catch (e) { + console.error('解析数据失败:', e); + } + } + } + } + } catch (err: any) { + if (err.name === 'AbortError') { + console.log('请求已取消'); + } else { + console.error('请求失败:', err); + ElMessage.error(err.message || '请求失败'); + } + } finally { + isSending.value = false; + abortController = null; + // 停止加载状态 + if (bubbleItems.value.length) { + const latest = bubbleItems.value[bubbleItems.value.length - 1]; + latest.loading = false; + } + } +} + +// 取消请求 +function cancelSSE() { + if (abortController) { + abortController.abort(); + isSending.value = false; + } +} diff --git a/Yi.Ai.Vue3/src/stores/modules/agentSession.ts b/Yi.Ai.Vue3/src/stores/modules/agentSession.ts new file mode 100644 index 00000000..cdd9f4b7 --- /dev/null +++ b/Yi.Ai.Vue3/src/stores/modules/agentSession.ts @@ -0,0 +1,202 @@ +import type { ChatSessionVo, CreateSessionDTO, GetSessionListParams } from '@/api/session/types'; +import { SessionTypeEnum } from '@/api/session/types'; +import { Monitor } from '@element-plus/icons-vue'; +import { defineStore } from 'pinia'; +import { markRaw, ref } from 'vue'; +import { + create_session, + delete_session, + get_session, + get_session_list, + update_session, +} from '@/api'; +import { useUserStore } from './user'; + +export const useAgentSessionStore = defineStore('agentSession', () => { + const userStore = useUserStore(); + + // 当前选中的会话信息 + const currentSession = ref(null); + + // 设置当前会话 + const setCurrentSession = (session: ChatSessionVo | null) => { + currentSession.value = session; + }; + + // 会话列表核心状态 + const sessionList = ref([]); + const currentPage = ref(1); + const pageSize = ref(25); + const hasMore = ref(true); + const isLoading = ref(false); + const isLoadingMore = ref(false); + + // 获取会话列表 + const requestSessionList = async (page: number = currentPage.value, force: boolean = false) => { + if (!userStore.token) { + sessionList.value = []; + return; + } + + if (!force && ((page > 1 && !hasMore.value) || isLoading.value || isLoadingMore.value)) + return; + + isLoading.value = page === 1; + isLoadingMore.value = page > 1; + + try { + const params: GetSessionListParams = { + userId: userStore.userInfo?.userId as number, + skipCount: page, + maxResultCount: pageSize.value, + isAsc: 'desc', + orderByColumn: 'createTime', + sessionType: SessionTypeEnum.Agent, // 只查询Agent类型 + }; + + const resArr = await get_session_list(params); + const res = processSessions(resArr.data.items); + + const allSessions = new Map(sessionList.value.map(item => [item.id, item])); + res.forEach(item => allSessions.set(item.id, { ...item })); + + if (page === 1) { + sessionList.value = [ + ...res, + ...Array.from(allSessions.values()).filter(item => !res.some(r => r.id === item.id)), + ]; + } + else { + sessionList.value = [ + ...sessionList.value.filter(item => !res.some(r => r.id === item.id)), + ...res, + ]; + } + + if (!force) + hasMore.value = (res?.length || 0) === pageSize.value; + if (!force) + currentPage.value = page; + } + catch (error) { + console.error('requestSessionList错误:', error); + } + finally { + isLoading.value = false; + isLoadingMore.value = false; + } + }; + + // 创建新会话 + const createSession = async (data: Omit) => { + if (!userStore.token) { + return null; + } + + try { + const res = await create_session({ + ...data, + sessionType: SessionTypeEnum.Agent, + }); + + await requestSessionList(1, true); + + const newSessionRes = await get_session(`${res.data.id}`); + setCurrentSession(newSessionRes.data); + + return newSessionRes.data; + } + catch (error) { + console.error('createSession错误:', error); + return null; + } + }; + + // 加载更多会话 + const loadMoreSessions = async () => { + if (hasMore.value) + await requestSessionList(currentPage.value + 1); + }; + + // 更新会话 + const updateSession = async (item: ChatSessionVo) => { + try { + await update_session(item); + const targetIndex = sessionList.value.findIndex(session => session.id === item.id); + const targetPage = targetIndex >= 0 + ? Math.floor(targetIndex / pageSize.value) + 1 + : 1; + await requestSessionList(targetPage, true); + } + catch (error) { + console.error('updateSession错误:', error); + } + }; + + // 删除会话 + const deleteSession = async (ids: string[]) => { + try { + await delete_session(ids); + const targetIndex = sessionList.value.findIndex(session => session.id === ids[0]); + const targetPage = targetIndex >= 0 + ? Math.floor(targetIndex / pageSize.value) + 1 + : 1; + await requestSessionList(targetPage, true); + + // 如果删除的是当前会话,清空当前会话 + if (currentSession.value && ids.includes(currentSession.value.id!)) { + setCurrentSession(null); + } + } + catch (error) { + console.error('deleteSession错误:', error); + } + }; + + // 预处理会话 + function processSessions(sessions: ChatSessionVo[]) { + const currentDate = new Date(); + + return sessions.map((session) => { + const createDate = new Date(session.creationTime!); + const diffDays = Math.floor( + (currentDate.getTime() - createDate.getTime()) / (1000 * 60 * 60 * 24), + ); + + let group: string; + if (diffDays < 7) { + group = '7 天内'; + } + else if (diffDays < 30) { + group = '30 天内'; + } + else { + const year = createDate.getFullYear(); + const month = String(createDate.getMonth() + 1).padStart(2, '0'); + group = `${year}-${month}`; + } + + return { + ...session, + group, + prefixIcon: markRaw(Monitor), + }; + }); + } + + return { + currentSession, + setCurrentSession, + sessionList, + currentPage, + pageSize, + hasMore, + isLoading, + isLoadingMore, + createSession, + requestSessionList, + loadMoreSessions, + updateSession, + deleteSession, + }; +}); diff --git a/Yi.Ai.Vue3/src/stores/modules/session.ts b/Yi.Ai.Vue3/src/stores/modules/session.ts index 84ffc750..d026e6df 100644 --- a/Yi.Ai.Vue3/src/stores/modules/session.ts +++ b/Yi.Ai.Vue3/src/stores/modules/session.ts @@ -1,4 +1,5 @@ import type { ChatSessionVo, CreateSessionDTO, GetSessionListParams } from '@/api/session/types'; +import { SessionTypeEnum } from '@/api/session/types'; import { ChatLineRound } from '@element-plus/icons-vue'; import { defineStore } from 'pinia'; import { markRaw } from 'vue'; @@ -64,6 +65,7 @@ export const useSessionStore = defineStore('session', () => { maxResultCount: pageSize.value, isAsc: 'desc', orderByColumn: 'createTime', + sessionType: SessionTypeEnum.Chat, }; const resArr = await get_session_list(params); diff --git a/Yi.Ai.Vue3/types/components.d.ts b/Yi.Ai.Vue3/types/components.d.ts index de4cbd56..b66d66bd 100644 --- a/Yi.Ai.Vue3/types/components.d.ts +++ b/Yi.Ai.Vue3/types/components.d.ts @@ -23,6 +23,7 @@ declare module 'vue' { ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] + ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition'] ElContainer: typeof import('element-plus/es')['ElContainer'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] diff --git a/Yi.Ai.Vue3/types/import_meta.d.ts b/Yi.Ai.Vue3/types/import_meta.d.ts index c98d612e..8f2a798b 100644 --- a/Yi.Ai.Vue3/types/import_meta.d.ts +++ b/Yi.Ai.Vue3/types/import_meta.d.ts @@ -7,7 +7,6 @@ interface ImportMetaEnv { readonly VITE_WEB_BASE_API: string; readonly VITE_API_URL: string; readonly VITE_FILE_UPLOAD_API: string; - readonly VITE_BUILD_COMPRESS: string; readonly VITE_SSO_SEVER_URL: string; readonly VITE_APP_VERSION: string; }