@@ -1766,63 +1766,146 @@ func (s *UniqueSlice[T]) GetAll() []T {
17661766
17671767var errNoTestSuiteFound = errors .New ("no test suite found" )
17681768
1769- // AI Plugin Communication Methods
1770- // These methods provide communication interface for AI plugins using the existing ExtManager
1769+ // CallAI calls an AI plugin to generate content
1770+ func (s * server ) CallAI (ctx context.Context , req * AIRequest ) (* AIResponse , error ) {
1771+ if req .GetPluginName () == "" {
1772+ return & AIResponse {
1773+ Success : false ,
1774+ Error : "plugin_name is required" ,
1775+ }, nil
1776+ }
17711777
1772- // GetAIPlugins returns all plugins with "ai" category
1773- func (s * server ) GetAIPlugins (ctx context.Context , req * Empty ) (* StoreKinds , error ) {
1774- stores , err := s .GetStoreKinds (ctx , req )
1778+ // Get the loader for the AI plugin
1779+ loader , err := s .getLoaderByStoreName (req .GetPluginName ())
17751780 if err != nil {
1776- return nil , err
1777- }
1778-
1779- var aiPlugins []* StoreKind
1780- for _ , store := range stores .Data {
1781- for _ , category := range store .Categories {
1782- if category == "ai" {
1783- aiPlugins = append (aiPlugins , store )
1784- break
1785- }
1781+ return & AIResponse {
1782+ Success : false ,
1783+ Error : fmt .Sprintf ("failed to get AI plugin '%s': %v" , req .GetPluginName (), err ),
1784+ }, nil
1785+ }
1786+ defer loader .Close ()
1787+
1788+ // Prepare query parameters
1789+ query := map [string ]string {
1790+ "method" : AIMethodGenerate ,
1791+ "model" : req .GetModel (),
1792+ "prompt" : req .GetPrompt (),
1793+ }
1794+
1795+ // Add config (always include, even if empty)
1796+ query ["config" ] = req .GetConfig ()
1797+
1798+ // Call the plugin using the Query interface
1799+ result , err := loader .Query (query )
1800+ if err != nil {
1801+ return & AIResponse {
1802+ Success : false ,
1803+ Error : fmt .Sprintf ("AI plugin call failed: %v" , err ),
1804+ }, nil
1805+ }
1806+
1807+ // Extract response from result
1808+ response := & AIResponse {
1809+ Success : true ,
1810+ }
1811+
1812+ // Get content from result
1813+ if content , ok := result .Pairs ["content" ]; ok {
1814+ response .Content = content
1815+ }
1816+
1817+ // Get metadata if available
1818+ if meta , ok := result .Pairs ["meta" ]; ok {
1819+ response .Meta = meta
1820+ }
1821+
1822+ // Check for errors from plugin
1823+ if errorMsg , ok := result .Pairs ["error" ]; ok && errorMsg != "" {
1824+ response .Success = false
1825+ response .Error = errorMsg
1826+ }
1827+
1828+ // Check success flag from plugin
1829+ if success , ok := result .Pairs ["success" ]; ok && success == "false" {
1830+ response .Success = false
1831+ if response .Error == "" {
1832+ response .Error = "AI plugin returned failure status"
17861833 }
17871834 }
1788-
1789- return & StoreKinds {Data : aiPlugins }, nil
1790- }
1791-
1792- // SendAIRequest sends a request to an AI plugin using the standard plugin communication protocol
1793- func (s * server ) SendAIRequest (ctx context.Context , pluginName string , req * AIRequest ) (* AIResponse , error ) {
1794- // This would communicate with the AI plugin via unix socket using PluginRequest/PluginResponse
1795- // Implementation would be similar to other plugin communications
1796-
1797- // TODO: Send pluginReq to plugin via storeExtMgr communication channel
1798- // pluginReq := &PluginRequest{
1799- // Method: AIMethodGenerate,
1800- // Payload: req,
1801- // }
1802-
1803- remoteServerLogger .Info ("Sending AI request" , "plugin" , pluginName , "model" , req .Model )
1804-
1805- return & AIResponse {
1806- Content : "AI response placeholder - implementation needed" ,
1807- Meta : map [string ]interface {}{"plugin" : pluginName , "model" : req .Model },
1808- }, nil
1809- }
1810-
1811- // GetAICapabilities gets capabilities from an AI plugin
1812- func (s * server ) GetAICapabilities (ctx context.Context , pluginName string ) (* AICapabilities , error ) {
1813- // TODO: Send pluginReq to plugin via storeExtMgr communication channel
1814- // pluginReq := &PluginRequest{
1815- // Method: AIMethodCapabilities,
1816- // Payload: &Empty{},
1817- // }
1818-
1819- remoteServerLogger .Info ("Getting AI capabilities" , "plugin" , pluginName )
1820-
1821- return & AICapabilities {
1822- Models : []string {"placeholder-model" },
1823- Features : []string {"generate" , "capabilities" },
1824- Limits : map [string ]int {"max_tokens" : 4096 },
1825- Description : "AI plugin capabilities placeholder" ,
1826- Version : "1.0.0" ,
1827- }, nil
1835+
1836+ remoteServerLogger .Info ("AI plugin called" ,
1837+ "plugin" , req .GetPluginName (),
1838+ "model" , req .GetModel (),
1839+ "success" , response .GetSuccess ())
1840+
1841+ return response , nil
1842+ }
1843+
1844+ // GetAICapabilities gets the capabilities of an AI plugin
1845+ func (s * server ) GetAICapabilities (ctx context.Context , req * AICapabilitiesRequest ) (* AICapabilitiesResponse , error ) {
1846+ if req .GetPluginName () == "" {
1847+ return & AICapabilitiesResponse {
1848+ Success : false ,
1849+ Error : "plugin_name is required" ,
1850+ }, nil
1851+ }
1852+
1853+ // Get the loader for the AI plugin
1854+ loader , err := s .getLoaderByStoreName (req .GetPluginName ())
1855+ if err != nil {
1856+ return & AICapabilitiesResponse {
1857+ Success : false ,
1858+ Error : fmt .Sprintf ("failed to get AI plugin '%s': %v" , req .GetPluginName (), err ),
1859+ }, nil
1860+ }
1861+ defer loader .Close ()
1862+
1863+ // Query for capabilities
1864+ query := map [string ]string {
1865+ "method" : AIMethodCapabilities ,
1866+ }
1867+
1868+ result , err := loader .Query (query )
1869+ if err != nil {
1870+ return & AICapabilitiesResponse {
1871+ Success : false ,
1872+ Error : fmt .Sprintf ("failed to get capabilities: %v" , err ),
1873+ }, nil
1874+ }
1875+
1876+ // Build response from result
1877+ response := & AICapabilitiesResponse {
1878+ Success : true ,
1879+ }
1880+
1881+ // Parse capabilities from result
1882+ if models , ok := result .Pairs ["models" ]; ok {
1883+ // Try to parse as JSON array first
1884+ response .Models = strings .Split (models , "," )
1885+ }
1886+
1887+ if features , ok := result .Pairs ["features" ]; ok {
1888+ response .Features = strings .Split (features , "," )
1889+ }
1890+
1891+ if description , ok := result .Pairs ["description" ]; ok {
1892+ response .Description = description
1893+ }
1894+
1895+ if version , ok := result .Pairs ["version" ]; ok {
1896+ response .Version = version
1897+ }
1898+
1899+ // Check for errors
1900+ if errorMsg , ok := result .Pairs ["error" ]; ok && errorMsg != "" {
1901+ response .Success = false
1902+ response .Error = errorMsg
1903+ }
1904+
1905+ remoteServerLogger .Info ("AI plugin capabilities retrieved" ,
1906+ "plugin" , req .GetPluginName (),
1907+ "models" , len (response .GetModels ()),
1908+ "features" , len (response .GetFeatures ()))
1909+
1910+ return response , nil
18281911}
0 commit comments