AIRequestFeature: Added Prompt, Authorization & Configuration Tabs

This commit is contained in:
Manas Hejmadi
2025-06-07 21:48:14 +05:30
parent d923996dc8
commit 22b8168b73
7 changed files with 330 additions and 0 deletions

View File

@@ -127,6 +127,7 @@ class HistoryRequestPane extends ConsumerWidget {
const HistoryScriptsTab(),
],
),
APIType.ai => FlutterLogo(),
_ => kSizedBoxEmpty,
};
}
@@ -204,6 +205,7 @@ class HisRequestBody extends ConsumerWidget {
readOnly: true,
),
),
APIType.ai => FlutterLogo(),
_ => kSizedBoxEmpty,
};
}

View File

@@ -0,0 +1,43 @@
import 'package:apidash/providers/collection_providers.dart';
import 'package:apidash/widgets/editor.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AIRequestAuthorizationSection extends ConsumerWidget {
const AIRequestAuthorizationSection({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider);
final reqM = ref.read(collectionStateNotifierProvider)![selectedId]!;
final aiReqM = reqM.aiRequestModel!;
final payload = aiReqM.payload;
final cred = payload.credential;
return Container(
padding: EdgeInsets.symmetric(vertical: 20),
child: Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: TextFieldEditor(
key: Key("$selectedId-aireq-authvalue-body"),
fieldKey: "$selectedId-aireq-authvalue-body",
initialValue: cred,
onChanged: (String value) {
payload.credential = value;
ref
.read(collectionStateNotifierProvider.notifier)
.update(aiRequestModel: aiReqM.updatePayload(payload));
},
hintText: 'Enter API key or Authorization Credentials',
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,153 @@
import 'package:apidash/providers/collection_providers.dart';
import 'package:apidash/widgets/editor.dart';
import 'package:apidash_design_system/widgets/textfield_outlined.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:genai/genai.dart';
class AIRequestConfigSection extends ConsumerStatefulWidget {
const AIRequestConfigSection({super.key});
@override
ConsumerState<AIRequestConfigSection> createState() =>
_AIRequestConfigSectionState();
}
class _AIRequestConfigSectionState
extends ConsumerState<AIRequestConfigSection> {
@override
Widget build(BuildContext context) {
final selectedId = ref.watch(selectedIdStateProvider);
final reqM = ref.read(collectionStateNotifierProvider)![selectedId]!;
final aiReqM = reqM.aiRequestModel!;
final payload = aiReqM.payload;
return SingleChildScrollView(
padding: EdgeInsets.symmetric(vertical: 20),
child: Column(
key: ValueKey(selectedId),
children: [
...payload.configMap.values.map(
(el) => ListTile(
title: Text(el.configName),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
el.configDescription,
style: TextStyle(color: Colors.white30),
),
SizedBox(height: 5),
if (el.configType == LLMModelConfigurationType.boolean) ...[
Switch(
value: el.configValue.value as bool,
onChanged: (x) {
el.configValue.value = x;
payload.configMap[el.configId] = el;
ref
.read(collectionStateNotifierProvider.notifier)
.update(
aiRequestModel: aiReqM.updatePayload(payload),
);
setState(() {});
},
)
] else if (el.configType ==
LLMModelConfigurationType.numeric) ...[
ADOutlinedTextField(
initialValue: el.configValue.value.toString(),
onChanged: (x) {
if (x.isEmpty) x = '0';
if (num.tryParse(x) == null) return;
el.configValue.value = num.parse(x);
payload.configMap[el.configId] = el;
ref
.read(collectionStateNotifierProvider.notifier)
.update(
aiRequestModel: aiReqM.updatePayload(payload),
);
setState(() {});
},
)
] else if (el.configType ==
LLMModelConfigurationType.text) ...[
ADOutlinedTextField(
initialValue: el.configValue.value.toString(),
onChanged: (x) {
el.configValue.value = x;
payload.configMap[el.configId] = el;
ref
.read(collectionStateNotifierProvider.notifier)
.update(
aiRequestModel: aiReqM.updatePayload(payload),
);
setState(() {});
},
)
] else if (el.configType ==
LLMModelConfigurationType.slider) ...[
Row(
children: [
Expanded(
child: Slider(
min: (el.configValue.value as (
double,
double,
double
))
.$1,
value: (el.configValue.value as (
double,
double,
double
))
.$2,
max: (el.configValue.value as (
double,
double,
double
))
.$3,
onChanged: (x) {
final z = el.configValue.value as (
double,
double,
double
);
el.configValue.value = (z.$1, x, z.$3);
payload.configMap[el.configId] = el;
ref
.read(
collectionStateNotifierProvider.notifier)
.update(
aiRequestModel:
aiReqM.updatePayload(payload),
);
setState(() {});
},
),
),
Text((el.configValue.value as (double, double, double))
.$2
.toStringAsFixed(2)),
],
)
],
SizedBox(height: 10),
// Divider(color: Colors.white10),
// SizedBox(height: 10),
],
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,80 @@
import 'package:apidash/providers/collection_providers.dart';
import 'package:apidash/widgets/editor.dart';
import 'package:apidash_design_system/tokens/measurements.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AIRequestPromptSection extends ConsumerWidget {
const AIRequestPromptSection({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider);
final reqM = ref.read(collectionStateNotifierProvider)![selectedId]!;
final aiReqM = reqM.aiRequestModel!;
final payload = aiReqM.payload;
final systemPrompt = payload.systemPrompt;
final userPrompt = payload.userPrompt;
return Container(
padding: EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 25.0),
child: Text(
'System Prompt',
style: TextStyle(color: Colors.white54),
),
),
kVSpacer10,
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: TextFieldEditor(
key: Key("$selectedId-aireq-sysprompt-body"),
fieldKey: "$selectedId-aireq-sysprompt-body",
initialValue: systemPrompt,
onChanged: (String value) {
payload.systemPrompt = value;
ref
.read(collectionStateNotifierProvider.notifier)
.update(aiRequestModel: aiReqM.updatePayload(payload));
},
hintText: 'Enter System Prompt',
),
),
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 25.0),
child: Text(
'User Prompt / Input',
style: TextStyle(color: Colors.white54),
),
),
kVSpacer10,
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: TextFieldEditor(
key: Key("$selectedId-aireq-userprompt-body"),
fieldKey: "$selectedId-aireq-userprompt-body",
initialValue: userPrompt,
onChanged: (String value) {
payload.userPrompt = value;
ref
.read(collectionStateNotifierProvider.notifier)
.update(aiRequestModel: aiReqM.updatePayload(payload));
},
hintText: 'Enter User Prompt',
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:apidash/screens/home_page/editor_pane/details_card/request_pane/ai_request/aireq_authorization.dart';
import 'package:apidash/screens/home_page/editor_pane/details_card/request_pane/ai_request/aireq_configs.dart';
import 'package:apidash/screens/home_page/editor_pane/details_card/request_pane/ai_request/aireq_prompt.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
class EditAIRequestPane extends ConsumerWidget {
const EditAIRequestPane({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider);
final codePaneVisible = ref.watch(codePaneVisibleStateProvider);
final tabIndex = ref.watch(
selectedRequestModelProvider.select((value) => value?.requestTabIndex));
return RequestPane(
selectedId: selectedId,
codePaneVisible: false,
tabIndex: tabIndex,
onPressedCodeButton: () {
ref.read(codePaneVisibleStateProvider.notifier).state =
!codePaneVisible;
},
onTapTabBar: (index) {
ref
.read(collectionStateNotifierProvider.notifier)
.update(requestTabIndex: index);
},
showIndicators: [
false,
false,
false,
],
tabLabels: const [
"Prompt",
"Authorization",
"Configurations",
],
children: const [
AIRequestPromptSection(),
AIRequestAuthorizationSection(),
AIRequestConfigSection(),
],
);
}
}

View File

@@ -92,6 +92,7 @@ class EditRequestBody extends ConsumerWidget {
),
),
),
APIType.ai => FlutterLogo(),
_ => kSizedBoxEmpty,
}
],

View File

@@ -1,3 +1,4 @@
import 'package:apidash/screens/home_page/editor_pane/details_card/request_pane/ai_request/request_pane_ai.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
@@ -17,6 +18,7 @@ class EditRequestPane extends ConsumerWidget {
return switch (apiType) {
APIType.rest => const EditRestRequestPane(),
APIType.graphql => const EditGraphQLRequestPane(),
APIType.ai => const EditAIRequestPane(),
_ => kSizedBoxEmpty,
};
}