using BotSharp.Abstraction.Instructs.Models; using BotSharp.Abstraction.Options; using BotSharp.Abstraction.Templating; using System.Collections; using System.Reflection; namespace BotSharp.Core.Instructs; public partial class InstructService { public async Task Instruct(string instruction, string agentId, InstructOptions options) where T : class { var prompt = GetPrompt(instruction, options.Data); var response = await GetAiResponse(agentId, prompt, options); if (string.IsNullOrWhiteSpace(response.Content)) return null; var type = typeof(T); T? result = null; try { var botsharpOptions = _services.GetRequiredService(); if (IsStringType(type)) { result = response.Content as T; } else if (IsListType(type)) { var text = response.Content.JsonArrayContent(); if (!string.IsNullOrWhiteSpace(text)) { result = JsonSerializer.Deserialize(text, botsharpOptions.JsonSerializerOptions); } } else { var text = response.Content.JsonContent(); if (!string.IsNullOrWhiteSpace(text)) { result = JsonSerializer.Deserialize(text, botsharpOptions.JsonSerializerOptions); } } } catch (Exception ex) { _logger.LogWarning($"Error when getting ai response, {ex.Message}\r\n{ex.InnerException}"); } return result; } private string GetPrompt(string instruction, Dictionary data) { var render = _services.GetRequiredService(); return render.Render(instruction, data ?? new Dictionary()); } private async Task GetAiResponse(string agentId, string prompt, InstructOptions options) { var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(agentId); var localAgent = new Agent { Id = agentId, Name = agent?.Name ?? "Unknown", Instruction = prompt, TemplateDict = new() }; var messages = BuildDialogs(options); var provider = options.Provider ?? agent?.LlmConfig?.Provider ?? "openai"; var model = options.Model ?? agent?.LlmConfig?.Model ?? "gpt-4o"; var completion = CompletionProvider.GetChatCompletion(_services, provider: provider, model: model); return await completion.GetChatCompletions(localAgent, messages); } private List BuildDialogs(InstructOptions options) { var messages = new List(); if (!string.IsNullOrWhiteSpace(options.ConversationId)) { var conv = _services.GetRequiredService(); var dialogs = conv.GetDialogHistory(); messages.AddRange(dialogs); } if (!string.IsNullOrWhiteSpace(options.Message)) { messages.Add(new RoleDialogModel(AgentRole.User, options.Message)); } return messages; } private bool IsStringType(Type? type) { if (type == null) return false; return type == typeof(string); } private bool IsListType(Type? type) { if (type == null) return false; var interfaces = type.GetTypeInfo().ImplementedInterfaces; return type.IsArray || interfaces.Any(x => x.Name == typeof(IEnumerable).Name); } }