mirror of
https://github.com/foss42/apidash.git
synced 2025-12-01 18:28:25 +08:00
AI Request History & Duplication Feature
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:genai/genai.dart';
|
||||
import 'models.dart';
|
||||
|
||||
part 'history_request_model.freezed.dart';
|
||||
@@ -14,7 +15,8 @@ class HistoryRequestModel with _$HistoryRequestModel {
|
||||
const factory HistoryRequestModel({
|
||||
required String historyId,
|
||||
required HistoryMetaModel metaData,
|
||||
required HttpRequestModel httpRequestModel,
|
||||
HttpRequestModel? httpRequestModel,
|
||||
AIRequestModel? aiRequestModel,
|
||||
required HttpResponseModel httpResponseModel,
|
||||
String? preRequestScript,
|
||||
String? postRequestScript,
|
||||
|
||||
@@ -22,7 +22,8 @@ HistoryRequestModel _$HistoryRequestModelFromJson(Map<String, dynamic> json) {
|
||||
mixin _$HistoryRequestModel {
|
||||
String get historyId => throw _privateConstructorUsedError;
|
||||
HistoryMetaModel get metaData => throw _privateConstructorUsedError;
|
||||
HttpRequestModel get httpRequestModel => throw _privateConstructorUsedError;
|
||||
HttpRequestModel? get httpRequestModel => throw _privateConstructorUsedError;
|
||||
AIRequestModel? get aiRequestModel => throw _privateConstructorUsedError;
|
||||
HttpResponseModel get httpResponseModel => throw _privateConstructorUsedError;
|
||||
String? get preRequestScript => throw _privateConstructorUsedError;
|
||||
String? get postRequestScript => throw _privateConstructorUsedError;
|
||||
@@ -47,14 +48,16 @@ abstract class $HistoryRequestModelCopyWith<$Res> {
|
||||
$Res call(
|
||||
{String historyId,
|
||||
HistoryMetaModel metaData,
|
||||
HttpRequestModel httpRequestModel,
|
||||
HttpRequestModel? httpRequestModel,
|
||||
AIRequestModel? aiRequestModel,
|
||||
HttpResponseModel httpResponseModel,
|
||||
String? preRequestScript,
|
||||
String? postRequestScript,
|
||||
AuthModel? authModel});
|
||||
|
||||
$HistoryMetaModelCopyWith<$Res> get metaData;
|
||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel;
|
||||
$HttpRequestModelCopyWith<$Res>? get httpRequestModel;
|
||||
$AIRequestModelCopyWith<$Res>? get aiRequestModel;
|
||||
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
||||
$AuthModelCopyWith<$Res>? get authModel;
|
||||
}
|
||||
@@ -76,7 +79,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
|
||||
$Res call({
|
||||
Object? historyId = null,
|
||||
Object? metaData = null,
|
||||
Object? httpRequestModel = null,
|
||||
Object? httpRequestModel = freezed,
|
||||
Object? aiRequestModel = freezed,
|
||||
Object? httpResponseModel = null,
|
||||
Object? preRequestScript = freezed,
|
||||
Object? postRequestScript = freezed,
|
||||
@@ -91,10 +95,14 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
|
||||
? _value.metaData
|
||||
: metaData // ignore: cast_nullable_to_non_nullable
|
||||
as HistoryMetaModel,
|
||||
httpRequestModel: null == httpRequestModel
|
||||
httpRequestModel: freezed == httpRequestModel
|
||||
? _value.httpRequestModel
|
||||
: httpRequestModel // ignore: cast_nullable_to_non_nullable
|
||||
as HttpRequestModel,
|
||||
as HttpRequestModel?,
|
||||
aiRequestModel: freezed == aiRequestModel
|
||||
? _value.aiRequestModel
|
||||
: aiRequestModel // ignore: cast_nullable_to_non_nullable
|
||||
as AIRequestModel?,
|
||||
httpResponseModel: null == httpResponseModel
|
||||
? _value.httpResponseModel
|
||||
: httpResponseModel // ignore: cast_nullable_to_non_nullable
|
||||
@@ -128,12 +136,30 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel {
|
||||
return $HttpRequestModelCopyWith<$Res>(_value.httpRequestModel, (value) {
|
||||
$HttpRequestModelCopyWith<$Res>? get httpRequestModel {
|
||||
if (_value.httpRequestModel == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $HttpRequestModelCopyWith<$Res>(_value.httpRequestModel!, (value) {
|
||||
return _then(_value.copyWith(httpRequestModel: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of HistoryRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$AIRequestModelCopyWith<$Res>? get aiRequestModel {
|
||||
if (_value.aiRequestModel == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $AIRequestModelCopyWith<$Res>(_value.aiRequestModel!, (value) {
|
||||
return _then(_value.copyWith(aiRequestModel: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of HistoryRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@@ -170,7 +196,8 @@ abstract class _$$HistoryRequestModelImplCopyWith<$Res>
|
||||
$Res call(
|
||||
{String historyId,
|
||||
HistoryMetaModel metaData,
|
||||
HttpRequestModel httpRequestModel,
|
||||
HttpRequestModel? httpRequestModel,
|
||||
AIRequestModel? aiRequestModel,
|
||||
HttpResponseModel httpResponseModel,
|
||||
String? preRequestScript,
|
||||
String? postRequestScript,
|
||||
@@ -179,7 +206,9 @@ abstract class _$$HistoryRequestModelImplCopyWith<$Res>
|
||||
@override
|
||||
$HistoryMetaModelCopyWith<$Res> get metaData;
|
||||
@override
|
||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel;
|
||||
$HttpRequestModelCopyWith<$Res>? get httpRequestModel;
|
||||
@override
|
||||
$AIRequestModelCopyWith<$Res>? get aiRequestModel;
|
||||
@override
|
||||
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
||||
@override
|
||||
@@ -201,7 +230,8 @@ class __$$HistoryRequestModelImplCopyWithImpl<$Res>
|
||||
$Res call({
|
||||
Object? historyId = null,
|
||||
Object? metaData = null,
|
||||
Object? httpRequestModel = null,
|
||||
Object? httpRequestModel = freezed,
|
||||
Object? aiRequestModel = freezed,
|
||||
Object? httpResponseModel = null,
|
||||
Object? preRequestScript = freezed,
|
||||
Object? postRequestScript = freezed,
|
||||
@@ -216,10 +246,14 @@ class __$$HistoryRequestModelImplCopyWithImpl<$Res>
|
||||
? _value.metaData
|
||||
: metaData // ignore: cast_nullable_to_non_nullable
|
||||
as HistoryMetaModel,
|
||||
httpRequestModel: null == httpRequestModel
|
||||
httpRequestModel: freezed == httpRequestModel
|
||||
? _value.httpRequestModel
|
||||
: httpRequestModel // ignore: cast_nullable_to_non_nullable
|
||||
as HttpRequestModel,
|
||||
as HttpRequestModel?,
|
||||
aiRequestModel: freezed == aiRequestModel
|
||||
? _value.aiRequestModel
|
||||
: aiRequestModel // ignore: cast_nullable_to_non_nullable
|
||||
as AIRequestModel?,
|
||||
httpResponseModel: null == httpResponseModel
|
||||
? _value.httpResponseModel
|
||||
: httpResponseModel // ignore: cast_nullable_to_non_nullable
|
||||
@@ -247,7 +281,8 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
||||
const _$HistoryRequestModelImpl(
|
||||
{required this.historyId,
|
||||
required this.metaData,
|
||||
required this.httpRequestModel,
|
||||
this.httpRequestModel,
|
||||
this.aiRequestModel,
|
||||
required this.httpResponseModel,
|
||||
this.preRequestScript,
|
||||
this.postRequestScript,
|
||||
@@ -261,7 +296,9 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
||||
@override
|
||||
final HistoryMetaModel metaData;
|
||||
@override
|
||||
final HttpRequestModel httpRequestModel;
|
||||
final HttpRequestModel? httpRequestModel;
|
||||
@override
|
||||
final AIRequestModel? aiRequestModel;
|
||||
@override
|
||||
final HttpResponseModel httpResponseModel;
|
||||
@override
|
||||
@@ -273,7 +310,7 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HistoryRequestModel(historyId: $historyId, metaData: $metaData, httpRequestModel: $httpRequestModel, httpResponseModel: $httpResponseModel, preRequestScript: $preRequestScript, postRequestScript: $postRequestScript, authModel: $authModel)';
|
||||
return 'HistoryRequestModel(historyId: $historyId, metaData: $metaData, httpRequestModel: $httpRequestModel, aiRequestModel: $aiRequestModel, httpResponseModel: $httpResponseModel, preRequestScript: $preRequestScript, postRequestScript: $postRequestScript, authModel: $authModel)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -287,6 +324,8 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
||||
other.metaData == metaData) &&
|
||||
(identical(other.httpRequestModel, httpRequestModel) ||
|
||||
other.httpRequestModel == httpRequestModel) &&
|
||||
(identical(other.aiRequestModel, aiRequestModel) ||
|
||||
other.aiRequestModel == aiRequestModel) &&
|
||||
(identical(other.httpResponseModel, httpResponseModel) ||
|
||||
other.httpResponseModel == httpResponseModel) &&
|
||||
(identical(other.preRequestScript, preRequestScript) ||
|
||||
@@ -304,6 +343,7 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
||||
historyId,
|
||||
metaData,
|
||||
httpRequestModel,
|
||||
aiRequestModel,
|
||||
httpResponseModel,
|
||||
preRequestScript,
|
||||
postRequestScript,
|
||||
@@ -330,7 +370,8 @@ abstract class _HistoryRequestModel implements HistoryRequestModel {
|
||||
const factory _HistoryRequestModel(
|
||||
{required final String historyId,
|
||||
required final HistoryMetaModel metaData,
|
||||
required final HttpRequestModel httpRequestModel,
|
||||
final HttpRequestModel? httpRequestModel,
|
||||
final AIRequestModel? aiRequestModel,
|
||||
required final HttpResponseModel httpResponseModel,
|
||||
final String? preRequestScript,
|
||||
final String? postRequestScript,
|
||||
@@ -344,7 +385,9 @@ abstract class _HistoryRequestModel implements HistoryRequestModel {
|
||||
@override
|
||||
HistoryMetaModel get metaData;
|
||||
@override
|
||||
HttpRequestModel get httpRequestModel;
|
||||
HttpRequestModel? get httpRequestModel;
|
||||
@override
|
||||
AIRequestModel? get aiRequestModel;
|
||||
@override
|
||||
HttpResponseModel get httpResponseModel;
|
||||
@override
|
||||
|
||||
@@ -11,8 +11,14 @@ _$HistoryRequestModelImpl _$$HistoryRequestModelImplFromJson(Map json) =>
|
||||
historyId: json['historyId'] as String,
|
||||
metaData: HistoryMetaModel.fromJson(
|
||||
Map<String, Object?>.from(json['metaData'] as Map)),
|
||||
httpRequestModel: HttpRequestModel.fromJson(
|
||||
httpRequestModel: json['httpRequestModel'] == null
|
||||
? null
|
||||
: HttpRequestModel.fromJson(
|
||||
Map<String, Object?>.from(json['httpRequestModel'] as Map)),
|
||||
aiRequestModel: json['aiRequestModel'] == null
|
||||
? null
|
||||
: AIRequestModel.fromJson(
|
||||
Map<String, Object?>.from(json['aiRequestModel'] as Map)),
|
||||
httpResponseModel: HttpResponseModel.fromJson(
|
||||
Map<String, Object?>.from(json['httpResponseModel'] as Map)),
|
||||
preRequestScript: json['preRequestScript'] as String?,
|
||||
@@ -28,7 +34,8 @@ Map<String, dynamic> _$$HistoryRequestModelImplToJson(
|
||||
<String, dynamic>{
|
||||
'historyId': instance.historyId,
|
||||
'metaData': instance.metaData.toJson(),
|
||||
'httpRequestModel': instance.httpRequestModel.toJson(),
|
||||
'httpRequestModel': instance.httpRequestModel?.toJson(),
|
||||
'aiRequestModel': instance.aiRequestModel?.toJson(),
|
||||
'httpResponseModel': instance.httpResponseModel.toJson(),
|
||||
'preRequestScript': instance.preRequestScript,
|
||||
'postRequestScript': instance.postRequestScript,
|
||||
|
||||
@@ -187,10 +187,15 @@ class CollectionStateNotifier
|
||||
|
||||
var itemIds = ref.read(requestSequenceProvider);
|
||||
var currentModel = historyRequestModel;
|
||||
|
||||
final aT = currentModel.aiRequestModel != null ? APIType.ai : APIType.rest;
|
||||
|
||||
final newModel = RequestModel(
|
||||
apiType: aT,
|
||||
id: newId,
|
||||
name: "${currentModel.metaData.name} (history)",
|
||||
httpRequestModel: currentModel.httpRequestModel,
|
||||
aiRequestModel: currentModel.aiRequestModel,
|
||||
httpRequestModel: currentModel.httpRequestModel ?? HttpRequestModel(),
|
||||
responseStatus: currentModel.metaData.responseStatus,
|
||||
message: kResponseCodeReasons[currentModel.metaData.responseStatus],
|
||||
httpResponseModel: currentModel.httpResponseModel,
|
||||
@@ -461,6 +466,7 @@ class CollectionStateNotifier
|
||||
timeStamp: DateTime.now(),
|
||||
),
|
||||
httpRequestModel: substitutedHttpRequestModel,
|
||||
aiRequestModel: aiRequestModel,
|
||||
httpResponseModel: httpResponseModel!,
|
||||
preRequestScript: requestModel.preRequestScript,
|
||||
postRequestScript: requestModel.postRequestScript,
|
||||
|
||||
@@ -28,6 +28,13 @@ class CodePane extends ConsumerWidget {
|
||||
final selectedRequestModel = isHistoryRequest
|
||||
? getRequestModelFromHistoryModel(selectedHistoryRequestModel!)
|
||||
: ref.watch(selectedRequestModelProvider);
|
||||
|
||||
if (selectedRequestModel!.apiType == APIType.ai) {
|
||||
return const ErrorMessage(
|
||||
message: "Code generation for AI Requests is currently not available.",
|
||||
);
|
||||
}
|
||||
|
||||
final defaultUriScheme =
|
||||
ref.watch(settingsProvider.select((value) => value.defaultUriScheme));
|
||||
|
||||
|
||||
178
lib/screens/history/history_widgets/ai_history_page.dart
Normal file
178
lib/screens/history/history_widgets/ai_history_page.dart
Normal file
@@ -0,0 +1,178 @@
|
||||
import 'package:apidash/providers/collection_providers.dart';
|
||||
import 'package:apidash/providers/history_providers.dart';
|
||||
import 'package:apidash/widgets/editor.dart';
|
||||
import 'package:apidash_design_system/tokens/measurements.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/llm_config.dart';
|
||||
import 'package:genai/widgets/ai_config_widgets.dart';
|
||||
|
||||
class HisAIRequestPromptSection extends ConsumerWidget {
|
||||
const HisAIRequestPromptSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedHistoryModel =
|
||||
ref.watch(selectedHistoryRequestModelProvider)!;
|
||||
|
||||
final aiReqM = selectedHistoryModel.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',
|
||||
),
|
||||
),
|
||||
kVSpacer10,
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: TextFieldEditor(
|
||||
key: Key(
|
||||
"${selectedHistoryModel.historyId}-aireq-sysprompt-body"),
|
||||
fieldKey:
|
||||
"${selectedHistoryModel.historyId}-aireq-sysprompt-body",
|
||||
initialValue: systemPrompt,
|
||||
readOnly: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 25.0),
|
||||
child: Text(
|
||||
'User Prompt / Input',
|
||||
),
|
||||
),
|
||||
kVSpacer10,
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: TextFieldEditor(
|
||||
key: Key(
|
||||
"${selectedHistoryModel.historyId}-aireq-userprompt-body"),
|
||||
fieldKey:
|
||||
"${selectedHistoryModel.historyId}-aireq-userprompt-body",
|
||||
initialValue: userPrompt,
|
||||
readOnly: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HisAIRequestAuthorizationSection extends ConsumerWidget {
|
||||
const HisAIRequestAuthorizationSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedHistoryModel =
|
||||
ref.watch(selectedHistoryRequestModelProvider)!;
|
||||
|
||||
final aiReqM = selectedHistoryModel.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(
|
||||
"${selectedHistoryModel.historyId}-aireq-authvalue-body"),
|
||||
fieldKey:
|
||||
"${selectedHistoryModel.historyId}-aireq-authvalue-body",
|
||||
initialValue: cred,
|
||||
readOnly: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HisAIRequestConfigSection extends ConsumerWidget {
|
||||
const HisAIRequestConfigSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedHistoryModel =
|
||||
ref.watch(selectedHistoryRequestModelProvider)!;
|
||||
|
||||
final aiReqM = selectedHistoryModel.aiRequestModel!;
|
||||
|
||||
final payload = aiReqM.payload;
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: EdgeInsets.symmetric(vertical: 20),
|
||||
child: Column(
|
||||
key: ValueKey(selectedHistoryModel.historyId),
|
||||
children: [
|
||||
...payload.configMap.values.map(
|
||||
(el) => ListTile(
|
||||
title: Text(el.configName),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
el.configDescription,
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
if (el.configType == LLMModelConfigurationType.boolean) ...[
|
||||
BooleanAIConfig(
|
||||
readonly: true,
|
||||
configuration: el,
|
||||
onConfigUpdated: (x) {},
|
||||
),
|
||||
] else if (el.configType ==
|
||||
LLMModelConfigurationType.numeric) ...[
|
||||
WritableAIConfig(
|
||||
configuration: el,
|
||||
onConfigUpdated: (x) {},
|
||||
readonly: true,
|
||||
numeric: true,
|
||||
),
|
||||
] else if (el.configType ==
|
||||
LLMModelConfigurationType.text) ...[
|
||||
WritableAIConfig(
|
||||
configuration: el,
|
||||
onConfigUpdated: (x) {},
|
||||
readonly: true,
|
||||
),
|
||||
] else if (el.configType ==
|
||||
LLMModelConfigurationType.slider) ...[
|
||||
SliderAIConfig(
|
||||
configuration: el,
|
||||
onSliderUpdated: (x) {},
|
||||
readonly: true,
|
||||
),
|
||||
],
|
||||
SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:apidash/screens/history/history_widgets/ai_history_page.dart';
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -22,22 +23,38 @@ class HistoryRequestPane extends ConsumerWidget {
|
||||
final codePaneVisible = ref.watch(historyCodePaneVisibleStateProvider);
|
||||
final apiType = ref.watch(selectedHistoryRequestModelProvider
|
||||
.select((value) => value?.metaData.apiType));
|
||||
final headersMap = ref.watch(selectedHistoryRequestModelProvider
|
||||
.select((value) => value?.httpRequestModel.headersMap)) ??
|
||||
|
||||
final headersMap = ref.watch(selectedHistoryRequestModelProvider.select(
|
||||
(value) {
|
||||
if (apiType == APIType.ai) return <String, String>{};
|
||||
return value?.httpRequestModel!.headersMap;
|
||||
},
|
||||
)) ??
|
||||
{};
|
||||
final headerLength = headersMap.length;
|
||||
|
||||
final paramsMap = ref.watch(selectedHistoryRequestModelProvider
|
||||
.select((value) => value?.httpRequestModel.paramsMap)) ??
|
||||
final paramsMap = ref.watch(selectedHistoryRequestModelProvider.select(
|
||||
(value) {
|
||||
if (apiType == APIType.ai) return <String, String>{};
|
||||
return value?.httpRequestModel!.paramsMap;
|
||||
},
|
||||
)) ??
|
||||
{};
|
||||
final paramLength = paramsMap.length;
|
||||
|
||||
final hasBody = ref.watch(selectedHistoryRequestModelProvider
|
||||
.select((value) => value?.httpRequestModel.hasBody)) ??
|
||||
final hasBody = ref.watch(selectedHistoryRequestModelProvider.select(
|
||||
(value) {
|
||||
if (apiType == APIType.ai) return false;
|
||||
return value?.httpRequestModel!.hasBody;
|
||||
},
|
||||
)) ??
|
||||
false;
|
||||
|
||||
final hasQuery = ref.watch(selectedHistoryRequestModelProvider
|
||||
.select((value) => value?.httpRequestModel.hasQuery)) ??
|
||||
final hasQuery =
|
||||
ref.watch(selectedHistoryRequestModelProvider.select((value) {
|
||||
if (apiType == APIType.ai) return false;
|
||||
return value?.httpRequestModel!.hasQuery;
|
||||
})) ??
|
||||
false;
|
||||
|
||||
final scriptsLength = ref.watch(selectedHistoryRequestModelProvider
|
||||
@@ -127,7 +144,27 @@ class HistoryRequestPane extends ConsumerWidget {
|
||||
const HistoryScriptsTab(),
|
||||
],
|
||||
),
|
||||
APIType.ai => FlutterLogo(),
|
||||
APIType.ai => RequestPane(
|
||||
key: const Key("history-request-pane-ai"),
|
||||
selectedId: selectedId,
|
||||
codePaneVisible: codePaneVisible,
|
||||
onPressedCodeButton: () {
|
||||
ref.read(historyCodePaneVisibleStateProvider.notifier).state =
|
||||
!codePaneVisible;
|
||||
},
|
||||
showViewCodeButton: !isCompact,
|
||||
showIndicators: [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
],
|
||||
tabLabels: const ["Prompts", "Authorization", "Configuration"],
|
||||
children: [
|
||||
const HisAIRequestPromptSection(),
|
||||
const HisAIRequestAuthorizationSection(),
|
||||
const HisAIRequestConfigSection(),
|
||||
],
|
||||
),
|
||||
_ => kSizedBoxEmpty,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,16 +13,20 @@ class HistoryResponsePane extends ConsumerWidget {
|
||||
final selectedId = ref.watch(selectedHistoryIdStateProvider);
|
||||
final selectedHistoryRequest =
|
||||
ref.watch(selectedHistoryRequestModelProvider);
|
||||
|
||||
final historyHttpResponseModel = selectedHistoryRequest?.httpResponseModel;
|
||||
|
||||
if (selectedId != null) {
|
||||
final requestModel =
|
||||
getRequestModelFromHistoryModel(selectedHistoryRequest!);
|
||||
|
||||
final statusCode = historyHttpResponseModel?.statusCode;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
ResponsePaneHeader(
|
||||
responseStatus: historyHttpResponseModel?.statusCode,
|
||||
message: kResponseCodeReasons[historyHttpResponseModel?.statusCode],
|
||||
responseStatus: statusCode,
|
||||
message: kResponseCodeReasons[statusCode],
|
||||
time: historyHttpResponseModel?.time,
|
||||
),
|
||||
Expanded(
|
||||
|
||||
@@ -13,6 +13,7 @@ RequestModel getRequestModelFromHistoryModel(HistoryRequestModel model) {
|
||||
name: model.metaData.name,
|
||||
responseStatus: model.httpResponseModel.statusCode,
|
||||
message: kResponseCodeReasons[model.httpResponseModel.statusCode],
|
||||
aiRequestModel: model.aiRequestModel,
|
||||
httpRequestModel: model.httpRequestModel,
|
||||
httpResponseModel: model.httpResponseModel,
|
||||
);
|
||||
|
||||
@@ -4,10 +4,12 @@ import 'package:genai/llm_config.dart';
|
||||
class SliderAIConfig extends StatelessWidget {
|
||||
final LLMModelConfiguration configuration;
|
||||
final Function(LLMModelConfiguration) onSliderUpdated;
|
||||
final bool readonly;
|
||||
const SliderAIConfig({
|
||||
super.key,
|
||||
required this.configuration,
|
||||
required this.onSliderUpdated,
|
||||
this.readonly = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -23,6 +25,7 @@ class SliderAIConfig extends StatelessWidget {
|
||||
max: (configuration.configValue.value as (double, double, double))
|
||||
.$3,
|
||||
onChanged: (x) {
|
||||
if (readonly) return;
|
||||
final z =
|
||||
configuration.configValue.value as (double, double, double);
|
||||
configuration.configValue.value = (z.$1, x, z.$3);
|
||||
@@ -43,11 +46,13 @@ class WritableAIConfig extends StatelessWidget {
|
||||
final bool numeric;
|
||||
final LLMModelConfiguration configuration;
|
||||
final Function(LLMModelConfiguration) onConfigUpdated;
|
||||
final bool readonly;
|
||||
const WritableAIConfig({
|
||||
super.key,
|
||||
this.numeric = false,
|
||||
required this.configuration,
|
||||
required this.onConfigUpdated,
|
||||
this.readonly = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -55,6 +60,7 @@ class WritableAIConfig extends StatelessWidget {
|
||||
return TextFormField(
|
||||
initialValue: configuration.configValue.value.toString(),
|
||||
onChanged: (x) {
|
||||
if (readonly) return;
|
||||
if (numeric) {
|
||||
if (x.isEmpty) x = '0';
|
||||
if (num.tryParse(x) == null) return;
|
||||
@@ -71,10 +77,12 @@ class WritableAIConfig extends StatelessWidget {
|
||||
class BooleanAIConfig extends StatelessWidget {
|
||||
final LLMModelConfiguration configuration;
|
||||
final Function(LLMModelConfiguration) onConfigUpdated;
|
||||
final bool readonly;
|
||||
const BooleanAIConfig({
|
||||
super.key,
|
||||
required this.configuration,
|
||||
required this.onConfigUpdated,
|
||||
this.readonly = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -82,6 +90,7 @@ class BooleanAIConfig extends StatelessWidget {
|
||||
return Switch(
|
||||
value: configuration.configValue.value as bool,
|
||||
onChanged: (x) {
|
||||
if (readonly) return;
|
||||
configuration.configValue.value = x;
|
||||
onConfigUpdated(configuration);
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@ void main() {
|
||||
|
||||
expect(
|
||||
find.text(
|
||||
historyRequestModel.httpRequestModel.method.name.toUpperCase()),
|
||||
historyRequestModel.httpRequestModel!.method.name.toUpperCase()),
|
||||
findsOneWidget);
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ void main() {
|
||||
);
|
||||
|
||||
expect(
|
||||
find.text(historyRequestModel.httpRequestModel.url), findsOneWidget);
|
||||
find.text(historyRequestModel.httpRequestModel!.url), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user