#pragma once #include "IService.hpp" #include "../shared/llm/ILLMProvider.hpp" #include "../shared/llm/ToolRegistry.hpp" #include #include #include #include #include #include #include #include #include #include namespace aissia { /** * @brief LLM Service - Async HTTP calls to LLM providers * * Handles all LLM API calls in a background thread. * Modules communicate via IIO: * * Subscribes to: * - "llm:request" : { query, systemPrompt?, tools?, conversationId? } * * Publishes: * - "llm:response" : { text, conversationId, tokens, iterations } * - "llm:error" : { message, conversationId } * - "llm:thinking" : { conversationId } (during agentic loop) */ class LLMService : public IService { public: LLMService(); ~LLMService() override; bool initialize(grove::IIO* io) override; void process() override; void shutdown() override; std::string getName() const override { return "LLMService"; } bool isHealthy() const override { return m_provider != nullptr; } /// Load provider from config file bool loadConfig(const std::string& configPath); /// Register a tool that can be called by the LLM void registerTool(const std::string& name, const std::string& description, const nlohmann::json& schema, std::function handler); private: struct Request { std::string query; std::string systemPrompt; std::string conversationId; nlohmann::json tools; int maxIterations = 10; }; struct Response { std::string text; std::string conversationId; int tokens = 0; int iterations = 0; bool isError = false; }; // Configuration std::string m_providerName = "claude"; std::string m_defaultSystemPrompt; int m_maxIterations = 10; // State std::unique_ptr m_provider; ToolRegistry m_toolRegistry; std::map m_conversations; // conversationId -> history // Threading std::thread m_workerThread; std::atomic m_running{false}; std::queue m_requestQueue; std::queue m_responseQueue; std::mutex m_requestMutex; std::mutex m_responseMutex; std::condition_variable m_requestCV; // Services grove::IIO* m_io = nullptr; std::shared_ptr m_logger; // Worker thread void workerLoop(); Response processRequest(const Request& request); nlohmann::json agenticLoop(const std::string& query, const std::string& systemPrompt, nlohmann::json& messages, const nlohmann::json& tools, int maxIterations); // Message handling void processIncomingMessages(); void publishResponses(); }; } // namespace aissia