Skip to content

(Prototype) Multi-Agent AI UI Designer #774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions lib/apitoolgen/request_consolidator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
class APIDashRequestDescription {
final String endpoint;
final String method;
final Map<String, dynamic>? queryParams;
final List<Map>? formData;
final Map<String, dynamic>? headers;
final String? bodyTXT;
final Map? bodyJSON;
final String? responseType;
final dynamic response;

APIDashRequestDescription({
required this.endpoint,
required this.method,
this.queryParams,
this.formData,
this.headers,
this.bodyTXT,
this.bodyJSON,
this.responseType,
this.response,
});

String get generateREQDATA {
//Note Down the Query parameters
String queryParamStr = '';
if (queryParams != null) {
for (final x in queryParams!.keys) {
queryParamStr +=
'\t$x: ${queryParams![x]} <${queryParams![x].runtimeType}>\n';
}
queryParamStr = 'QUERY_PARAMETERS: {\n$queryParamStr}';
}

//Note Down the Headers
String headersStr = '';
if (headers != null) {
for (final x in headers!.keys) {
headersStr += '\t$x: ${headers![x]} <${headers![x].runtimeType}>\n';
}
headersStr = 'HEADERS: {\n$headersStr}';
}

String bodyDetails = '';
if (bodyTXT != null) {
bodyDetails = 'BODY_TYPE: TEXT\nBODY_TEXT:$bodyTXT';
} else if (bodyJSON != null) {
//Note Down the JSONData
String jsonBodyStr = '';
if (bodyJSON != null) {
getTyp(input, [i = 0]) {
String indent = "\t";
for (int j = 0; j < i; j++) indent += "\t";
if (input.runtimeType.toString().toLowerCase().contains('map')) {
String typd = '{';
for (final z in input.keys) {
typd += "$indent$z: TYPE: ${getTyp(input[z], i + 1)}\n";
}
return "$indent$typd}";
}
return input.runtimeType.toString();
}

for (final x in bodyJSON!.keys) {
jsonBodyStr += '\t$x: TYPE: <${getTyp(bodyJSON![x])}>\n';
}
jsonBodyStr = 'BODY_JSON: {\n$jsonBodyStr}';
}
bodyDetails = 'BODY_TYPE: JSON\n$jsonBodyStr';
} else if (formData != null) {
//Note Down the FormData
String formDataStr = '';
if (formData != null) {
for (final x in formData!) {
formDataStr += '\t$x\n';
}
formDataStr = 'BODY_FORM_DATA: {\n$formDataStr}';
}
bodyDetails = 'BODY_TYPE: FORM-DATA\n$formDataStr';
}

String responseDetails = '';
if (responseType != null && response != null) {
responseDetails =
'-----RESPONSE_DETAILS-----\nRESPONSE_TYPE: $responseType\nRESPONSE_BODY: $response';
}

return """REST API (HTTP)
METHOD: $method
ENDPOINT: $endpoint
HEADERS: ${headersStr.isEmpty ? '{}' : headersStr}
$queryParamStr
$bodyDetails
$responseDetails
""";
}
}
112 changes: 112 additions & 0 deletions lib/apitoolgen/tool_templates.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const GENERAL_ARG_PROPERTY_FORMAT_PY = """:ARG_NAME: {
"type": ":ARG_TYPE:",
"description: ":ARG_DESC:"
}""";

const GENERAL_PYTHON_TOOL_FORMAT = """
:FUNC:

api_tool = {
"function": func,
"definition": {
"name": ":TOOL_NAME:",
"description": ":TOOL_DESCRIPTION:",
"parameters": {
"type": "object",
"properties": :TOOL_PARAMS:,
"required": [:REQUIRED_PARAM_NAMES:],
"additionalProperties": False
}
}
}

__all__ = ["api_tool"]
""";

const GENERAL_JAVASCRIPT_TOOL_FORMAT = """
:FUNC:

const apiTool = {
function: func,
definition: {
type: 'function',
function: {
name: ':TOOL_NAME:',
description: ':TOOL_DESCRIPTION:',
parameters: {
type: 'object',
properties: :TOOL_PARAMS:,
required: [:REQUIRED_PARAM_NAMES:]
additionalProperties: false
}
}
}
};

export { apiTool };
""";

const LANGCHAIN_PYTHON_TOOL_FORMAT = """
from langchain.tools import StructuredTool

:INPUT_SCHEMA:

:FUNC:

api_tool = StructuredTool.from_function(
func=func,
name=":TOOL_NAME:",
description=":TOOL_DESCRIPTION:",
args_schema=INPUT_SCHEMA,
)
__all__ = ["api_tool"]
""";

const LANGCHAIN_JAVASCRIPT_TOOL_FORMAT = """
import { DynamicStructuredTool } from 'langchain/tools';
import { z } from 'zod';

:INPUT_SCHEMA:

:FUNC:

const apiTool = new DynamicStructuredTool({
func: func,
name: ':TOOL_NAME:',
description: ':TOOL_DESCRIPTION:',
schema: INPUT_SCHEMA
});

export { apiTool };
""";

const MICROSOFT_AUTOGEN_TOOL_FORMAT = """
:FUNC:

api_tool = {
"function": func,
"name": ":TOOL_NAME:",
"description": ":TOOL_DESCRIPTION:"
}

__all__ = ["api_tool"]
""";

class APIToolGenTemplateSelector {
static String getTemplate(String language, String agent) {
if (language == 'PYTHON') {
if (agent == 'MICROSOFT_AUTOGEN') {
return MICROSOFT_AUTOGEN_TOOL_FORMAT;
} else if (agent == 'LANGCHAIN') {
return LANGCHAIN_PYTHON_TOOL_FORMAT;
}
return GENERAL_PYTHON_TOOL_FORMAT;
} else if (language == 'JAVASCRIPT') {
if (agent == 'LANGCHAIN') {
return LANGCHAIN_JAVASCRIPT_TOOL_FORMAT;
}
return GENERAL_JAVASCRIPT_TOOL_FORMAT;
}
return 'NO_TEMPLATE';
}
}
13 changes: 13 additions & 0 deletions lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ enum CodegenLanguage {
final String ext;
}

enum LLMProvider {
ollama('Ollama', 'llama3'),
chatgpt('ChatGPT', '4o'),
gemini('Gemini', '2.0-flash'),
claude('Claude', '3.7'),
azureOpenAI('AzureOpenAI', 'custom');

const LLMProvider(this.label, this.model);
final String label;
final String model;
}

enum ImportFormat {
curl("cURL"),
postman("Postman Collection v2.1"),
Expand Down Expand Up @@ -485,3 +497,4 @@ const kMsgClearHistory =
const kMsgClearHistorySuccess = 'History cleared successfully';
const kMsgClearHistoryError = 'Error clearing history';
const kMsgShareError = "Unable to share";
const kLabelGenerateUI = "Generate UI";
2 changes: 2 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import 'providers/providers.dart';
import 'services/services.dart';
import 'consts.dart';
import 'app.dart';
import 'package:stac/stac.dart' as stac;

void main() async {
await stac.Stac.initialize();
WidgetsFlutterBinding.ensureInitialized();
var settingsModel = await getSettingsFromSharedPrefs();
var onboardingStatus = await getOnboardingStatusFromSharedPrefs();
Expand Down
43 changes: 42 additions & 1 deletion lib/models/settings_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class SettingsModel {
this.historyRetentionPeriod = HistoryRetentionPeriod.oneWeek,
this.workspaceFolderPath,
this.isSSLDisabled = false,
this.defaultLLMProvider = LLMProvider.ollama,
this.defaultLLMProviderCredentials = '',
});

final bool isDark;
Expand All @@ -31,6 +33,8 @@ class SettingsModel {
final HistoryRetentionPeriod historyRetentionPeriod;
final String? workspaceFolderPath;
final bool isSSLDisabled;
final LLMProvider defaultLLMProvider;
final String defaultLLMProviderCredentials;

SettingsModel copyWith({
bool? isDark,
Expand All @@ -45,6 +49,8 @@ class SettingsModel {
HistoryRetentionPeriod? historyRetentionPeriod,
String? workspaceFolderPath,
bool? isSSLDisabled,
LLMProvider? defaultLLMProvider,
String? defaultLLMProviderCredentials,
}) {
return SettingsModel(
isDark: isDark ?? this.isDark,
Expand All @@ -61,6 +67,9 @@ class SettingsModel {
historyRetentionPeriod ?? this.historyRetentionPeriod,
workspaceFolderPath: workspaceFolderPath ?? this.workspaceFolderPath,
isSSLDisabled: isSSLDisabled ?? this.isSSLDisabled,
defaultLLMProvider: defaultLLMProvider ?? this.defaultLLMProvider,
defaultLLMProviderCredentials:
defaultLLMProviderCredentials ?? this.defaultLLMProviderCredentials,
);
}

Expand All @@ -80,6 +89,8 @@ class SettingsModel {
historyRetentionPeriod: historyRetentionPeriod,
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
defaultLLMProvider: defaultLLMProvider,
defaultLLMProviderCredentials: defaultLLMProviderCredentials,
);
}

Expand Down Expand Up @@ -119,6 +130,28 @@ class SettingsModel {
// pass
}
}

final defaultLLMProviderStr = data["defaultLLMProvider"] as String?;
LLMProvider? defaultLLMProvider;
if (defaultLLMProviderStr != null) {
try {
defaultLLMProvider = LLMProvider.values.byName(defaultLLMProviderStr);
} catch (e) {
// pass
}
}

final defaultLLMProviderCredentialsStr =
data['defaultLLMProviderCredentials'] as String?;
String? defaultLLMProviderCredentials;
if (defaultLLMProviderCredentialsStr != null) {
try {
defaultLLMProviderCredentials = defaultLLMProviderCredentialsStr;
} catch (e) {
// pass
}
}

final saveResponses = data["saveResponses"] as bool?;
final promptBeforeClosing = data["promptBeforeClosing"] as bool?;
final activeEnvironmentId = data["activeEnvironmentId"] as String?;
Expand Down Expand Up @@ -151,6 +184,8 @@ class SettingsModel {
historyRetentionPeriod ?? HistoryRetentionPeriod.oneWeek,
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
defaultLLMProvider: defaultLLMProvider,
defaultLLMProviderCredentials: defaultLLMProviderCredentials,
);
}

Expand All @@ -170,6 +205,8 @@ class SettingsModel {
"historyRetentionPeriod": historyRetentionPeriod.name,
"workspaceFolderPath": workspaceFolderPath,
"isSSLDisabled": isSSLDisabled,
"defaultLLMProvider": defaultLLMProvider.name,
"defaultLLMProviderCredentials": defaultLLMProviderCredentials,
};
}

Expand All @@ -194,7 +231,9 @@ class SettingsModel {
other.activeEnvironmentId == activeEnvironmentId &&
other.historyRetentionPeriod == historyRetentionPeriod &&
other.workspaceFolderPath == workspaceFolderPath &&
other.isSSLDisabled == isSSLDisabled;
other.isSSLDisabled == isSSLDisabled &&
other.defaultLLMProvider == defaultLLMProvider &&
other.defaultLLMProviderCredentials == defaultLLMProviderCredentials;
}

@override
Expand All @@ -213,6 +252,8 @@ class SettingsModel {
historyRetentionPeriod,
workspaceFolderPath,
isSSLDisabled,
defaultLLMProvider,
defaultLLMProviderCredentials,
);
}
}
10 changes: 10 additions & 0 deletions lib/providers/settings_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import '../consts.dart';
final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) =>
ref.watch(settingsProvider.select((value) => value.defaultCodeGenLang)));

final llmProviderStateProvider = StateProvider<LLMProvider>((ref) =>
ref.watch(settingsProvider.select((value) => value.defaultLLMProvider)));

final llmProviderCredentialsProvider = StateProvider<String>((ref) => ref.watch(
settingsProvider.select((value) => value.defaultLLMProviderCredentials)));

final activeEnvironmentIdStateProvider = StateProvider<String?>((ref) =>
ref.watch(settingsProvider.select((value) => value.activeEnvironmentId)));

Expand All @@ -33,6 +39,8 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
HistoryRetentionPeriod? historyRetentionPeriod,
String? workspaceFolderPath,
bool? isSSLDisabled,
LLMProvider? defaultLLMProvider,
String? defaultLLMProviderCredentials,
}) async {
state = state.copyWith(
isDark: isDark,
Expand All @@ -47,6 +55,8 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
historyRetentionPeriod: historyRetentionPeriod,
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
defaultLLMProvider: defaultLLMProvider,
defaultLLMProviderCredentials: defaultLLMProviderCredentials,
);
await setSettingsToSharedPrefs(state);
}
Expand Down
Loading