diff --git a/lib/main.dart b/lib/main.dart index c4457ad6..04eb9592 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:apidash_core/apidash_core.dart'; import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -10,6 +11,10 @@ import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + //Load all LLMs + // await LLMManager.fetchAvailableLLMs(); + await ModelManager.fetchAvailableModels(); + var settingsModel = await getSettingsFromSharedPrefs(); var onboardingStatus = await getOnboardingStatusFromSharedPrefs(); initializeJsRuntime(); diff --git a/lib/services/agentic/agent_caller.dart b/lib/services/agentic/agent_caller.dart new file mode 100644 index 00000000..f27e349b --- /dev/null +++ b/lib/services/agentic/agent_caller.dart @@ -0,0 +1,29 @@ +import 'package:apidash/providers/providers.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:genai/agentic_engine/agent_service.dart'; +import 'package:genai/agentic_engine/blueprint.dart'; +import 'package:genai/genai.dart'; + +class APIDashAgentCaller { + static APIDashAgentCaller instance = APIDashAgentCaller(); + + Future<(String? output, String error)> call( + APIDashAIAgent agent, { + required WidgetRef ref, + required AgentInputs input, + }) async { + final defaultAIModel = + ref.read(settingsProvider.select((e) => e.defaultAIModel)); + if (defaultAIModel == null) { + return (null, 'NO_DEFAULT_LLM'); + } + final baseAIRequestObject = AIRequestModel.fromJson(defaultAIModel); + final ans = await GenAIAgenticService.callAgent( + agent, + baseAIRequestObject, + query: input.query, + variables: input.variables, + ); + return ans; + } +} diff --git a/packages/genai/lib/agentic_engine/agent_service.dart b/packages/genai/lib/agentic_engine/agent_service.dart new file mode 100644 index 00000000..275e9974 --- /dev/null +++ b/packages/genai/lib/agentic_engine/agent_service.dart @@ -0,0 +1,90 @@ +import 'package:genai/agentic_engine/blueprint.dart'; +import 'package:genai/genai.dart'; + +class GenAIAgenticService { + static Future _call_provider({ + required AIRequestModel baseAIRequestObject, + required String systemPrompt, + required String input, + }) async { + final aiRequest = baseAIRequestObject.copyWith( + systemPrompt: systemPrompt, + userPrompt: input, + ); + return await executeGenAIRequest(aiRequest); + } + + static Future _orchestrator( + APIDashAIAgent agent, + AIRequestModel baseAIRequestObject, { + String? query, + Map? variables, + }) async { + String sP = agent.getSystemPrompt(); + + //Perform Templating + if (variables != null) { + for (final v in variables.keys) { + sP = sP.substitutePromptVariable(v, variables[v]); + } + } + + return await _call_provider( + systemPrompt: sP, + input: query ?? '', + baseAIRequestObject: baseAIRequestObject, + ); + } + + static Future _governor( + APIDashAIAgent agent, + AIRequestModel baseAIRequestObject, { + String? query, + Map? variables, + }) async { + int RETRY_COUNT = 0; + List backoffDelays = [200, 400, 800, 1600, 3200]; + do { + try { + final res = await _orchestrator( + agent, + baseAIRequestObject, + query: query, + variables: variables, + ); + if (res != null) { + if (await agent.validator(res)) { + return agent.outputFormatter(res); + } + } + } catch (e) { + "APIDashAIService::Governor: Exception Occured: $e"; + } + // Exponential Backoff + if (RETRY_COUNT < backoffDelays.length) { + await Future.delayed( + Duration(milliseconds: backoffDelays[RETRY_COUNT]), + ); + } + RETRY_COUNT += 1; + print( + "Retrying AgentCall for (${agent.agentName}): ATTEMPT: $RETRY_COUNT", + ); + } while (RETRY_COUNT < 5); + return null; + } + + static Future callAgent( + APIDashAIAgent agent, + AIRequestModel baseAIRequestObject, { + String? query, + Map? variables, + }) async { + return await _governor( + agent, + baseAIRequestObject, + query: query, + variables: variables, + ); + } +} diff --git a/packages/genai/lib/agentic_engine/blueprint.dart b/packages/genai/lib/agentic_engine/blueprint.dart new file mode 100644 index 00000000..7a365ac7 --- /dev/null +++ b/packages/genai/lib/agentic_engine/blueprint.dart @@ -0,0 +1,18 @@ +abstract class APIDashAIAgent { + String get agentName; + String getSystemPrompt(); + Future validator(String aiResponse); + Future outputFormatter(String validatedResponse); +} + +extension SystemPromptTemplating on String { + String substitutePromptVariable(String variable, String value) { + return this.replaceAll(":$variable:", value); + } +} + +class AgentInputs { + final String? query; + final Map? variables; + AgentInputs({this.query, this.variables}); +}