Consolidator & Tool Templates Done

This commit is contained in:
Manas Hejmadi
2025-04-06 22:38:09 +05:30
parent 6ad1f1e43e
commit c1246b538d
5 changed files with 378 additions and 53 deletions

View File

@@ -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
""";
}
}

View File

@@ -0,0 +1,93 @@
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"]
""";

View File

@@ -3,3 +3,4 @@ export 'semantic_analyser.dart';
export 'stac2flutter.dart';
export 'stacgen.dart';
export 'stacmodifier.dart';
export 'apitool_funcgen.dart';

View File

@@ -0,0 +1,47 @@
import 'package:genai/agentic_engine/blueprint.dart';
const String _sysprompt = """
You are an expert LANGUAGE SPECIFIC API CALL METHOD Creator.
You will be provided a complete API Details Text named (REQDATA) which consists of the method, endpoint, params, headers, body
and so on.
You are also provided with a Target Language named (TARGET_LANGUAGE).
Using this data, Create a method EXPLICITLY named `func`.
The method `func` should accept any variables if present (refer REQDATA for all details) and include it as part of the arguments
Use the Industry standard best practices while calling the API provided by REQDATA.
If REQDATA contains any Authorization (Eg: bearer key), embed that into the function itself and dont expect it to be passed in the function
same goes for any header details.
REQDATA: :REQDATA:
TARGET_LANGUAGE: :TARGET_LANGUAGE:
if REQDATA.BODY_TYPE is TEXT => use it as-is
if REQDATA.BODY_TYPE is JSON or FORM-DATA => use the types provided to create variables passed from the function arguments
ALWAYS return the output as code only and do not start or begin with any introduction or conclusion. ONLY THE CODE.
""";
class APIToolFunctionGenerator extends APIDashAIAgent {
@override
String get agentName => 'APITOOL_FUNCGEN';
@override
String getSystemPrompt() {
return _sysprompt;
}
@override
Future<bool> validator(String aiResponse) async {
//Add any specific validations here as needed
return true;
}
@override
Future outputFormatter(String validatedResponse) async {
return {
'FUNC': validatedResponse,
};
}
}

View File

@@ -1,9 +1,16 @@
import 'dart:convert';
import 'package:apidash/apitoolgen/request_consolidator.dart';
import 'package:apidash/providers/collection_providers.dart';
import 'package:apidash/services/agentic_services/agent_caller.dart';
import 'package:apidash/services/agentic_services/agents/apitool_funcgen.dart';
import 'package:apidash/widgets/ai_ui_desginer_widgets.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:flutter/material.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart';
import 'package:genai/agentic_engine/blueprint.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'button_clear_response.dart';
@@ -27,8 +34,10 @@ class ResponsePaneHeader extends ConsumerWidget {
return Padding(
padding: kPv8,
child: SizedBox(
height: kHeaderHeight,
child: Row(
// height: kHeaderHeight,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
kHSpacer10,
@@ -46,6 +55,95 @@ class ResponsePaneHeader extends ConsumerWidget {
),
),
),
kHSpacer10,
Text(
humanizeDuration(time),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontFamily: kCodeStyle.fontFamily,
color: Theme.of(context).colorScheme.secondary,
),
),
kHSpacer10,
showClearButton
? ClearResponseButton(
onPressed: onClearResponse,
)
: const SizedBox.shrink(),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FilledButton.tonalIcon(
style: FilledButton.styleFrom(
padding: kPh12,
minimumSize: const Size(44, 44),
),
onPressed: () async {
final requestModel = ref.watch(selectedRequestModelProvider
.select((value) => value?.httpRequestModel));
final responseModel = ref.watch(selectedRequestModelProvider
.select((value) => value?.httpResponseModel));
if (requestModel == null) return;
if (responseModel == null) {
print("AA");
return;
}
String? bodyTXT;
Map? bodyJSON;
List<Map>? bodyFormData;
if (requestModel.bodyContentType == ContentType.formdata) {
bodyFormData = requestModel.formDataMapList;
} else if (requestModel.bodyContentType ==
ContentType.json) {
bodyJSON = jsonDecode(requestModel.body.toString());
} else {
bodyTXT = requestModel.body!;
}
final reqDesModel = APIDashRequestDescription(
endpoint: requestModel.url,
method: requestModel.method.name.toUpperCase(),
responseType: responseModel.contentType.toString(),
headers: requestModel.headersMap,
response: responseModel.body,
formData: bodyFormData,
bodyTXT: bodyTXT,
bodyJSON: bodyJSON,
);
print(reqDesModel.generateREQDATA);
return;
final x = await APIDashAgentCaller.instance.call(
APIToolFunctionGenerator(),
ref: ref,
input: AgentInputs(variables: {
'REQDATA': reqDesModel.generateREQDATA,
'TARGET_LANGUAGE': 'JAVASCRIPT'
}),
);
print(x);
// print(reqDesModel.generateREQDATA);
// final model = ref.watch(selectedRequestModelProvider
// .select((value) => value?.httpResponseModel));
// showCustomDialog(context, model?.formattedBody ?? "");
},
icon: Icon(
Icons.token_outlined,
),
label: const SizedBox(
child: Text(
"Generate Tool",
),
),
),
kHSpacer10,
FilledButton.tonalIcon(
style: FilledButton.styleFrom(
padding: kPh12,
@@ -70,19 +168,8 @@ class ResponsePaneHeader extends ConsumerWidget {
),
),
kHSpacer10,
Text(
humanizeDuration(time),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontFamily: kCodeStyle.fontFamily,
color: Theme.of(context).colorScheme.secondary,
),
),
kHSpacer10,
showClearButton
? ClearResponseButton(
onPressed: onClearResponse,
],
)
: const SizedBox.shrink(),
],
),
),