mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 10:49:49 +08:00
AIRequestFeature: Added Prompt, Authorization & Configuration Tabs
This commit is contained in:
@@ -127,6 +127,7 @@ class HistoryRequestPane extends ConsumerWidget {
|
|||||||
const HistoryScriptsTab(),
|
const HistoryScriptsTab(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
APIType.ai => FlutterLogo(),
|
||||||
_ => kSizedBoxEmpty,
|
_ => kSizedBoxEmpty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -204,6 +205,7 @@ class HisRequestBody extends ConsumerWidget {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
APIType.ai => FlutterLogo(),
|
||||||
_ => kSizedBoxEmpty,
|
_ => kSizedBoxEmpty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,6 +92,7 @@ class EditRequestBody extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
APIType.ai => FlutterLogo(),
|
||||||
_ => kSizedBoxEmpty,
|
_ => kSizedBoxEmpty,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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_core/apidash_core.dart';
|
||||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -17,6 +18,7 @@ class EditRequestPane extends ConsumerWidget {
|
|||||||
return switch (apiType) {
|
return switch (apiType) {
|
||||||
APIType.rest => const EditRestRequestPane(),
|
APIType.rest => const EditRestRequestPane(),
|
||||||
APIType.graphql => const EditGraphQLRequestPane(),
|
APIType.graphql => const EditGraphQLRequestPane(),
|
||||||
|
APIType.ai => const EditAIRequestPane(),
|
||||||
_ => kSizedBoxEmpty,
|
_ => kSizedBoxEmpty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user