mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +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:apidash_core/apidash_core.dart';
|
||||||
|
import 'package:genai/genai.dart';
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
|
||||||
part 'history_request_model.freezed.dart';
|
part 'history_request_model.freezed.dart';
|
||||||
@@ -14,7 +15,8 @@ class HistoryRequestModel with _$HistoryRequestModel {
|
|||||||
const factory HistoryRequestModel({
|
const factory HistoryRequestModel({
|
||||||
required String historyId,
|
required String historyId,
|
||||||
required HistoryMetaModel metaData,
|
required HistoryMetaModel metaData,
|
||||||
required HttpRequestModel httpRequestModel,
|
HttpRequestModel? httpRequestModel,
|
||||||
|
AIRequestModel? aiRequestModel,
|
||||||
required HttpResponseModel httpResponseModel,
|
required HttpResponseModel httpResponseModel,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript,
|
String? postRequestScript,
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ HistoryRequestModel _$HistoryRequestModelFromJson(Map<String, dynamic> json) {
|
|||||||
mixin _$HistoryRequestModel {
|
mixin _$HistoryRequestModel {
|
||||||
String get historyId => throw _privateConstructorUsedError;
|
String get historyId => throw _privateConstructorUsedError;
|
||||||
HistoryMetaModel get metaData => 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;
|
HttpResponseModel get httpResponseModel => throw _privateConstructorUsedError;
|
||||||
String? get preRequestScript => throw _privateConstructorUsedError;
|
String? get preRequestScript => throw _privateConstructorUsedError;
|
||||||
String? get postRequestScript => throw _privateConstructorUsedError;
|
String? get postRequestScript => throw _privateConstructorUsedError;
|
||||||
@@ -47,14 +48,16 @@ abstract class $HistoryRequestModelCopyWith<$Res> {
|
|||||||
$Res call(
|
$Res call(
|
||||||
{String historyId,
|
{String historyId,
|
||||||
HistoryMetaModel metaData,
|
HistoryMetaModel metaData,
|
||||||
HttpRequestModel httpRequestModel,
|
HttpRequestModel? httpRequestModel,
|
||||||
|
AIRequestModel? aiRequestModel,
|
||||||
HttpResponseModel httpResponseModel,
|
HttpResponseModel httpResponseModel,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript,
|
String? postRequestScript,
|
||||||
AuthModel? authModel});
|
AuthModel? authModel});
|
||||||
|
|
||||||
$HistoryMetaModelCopyWith<$Res> get metaData;
|
$HistoryMetaModelCopyWith<$Res> get metaData;
|
||||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel;
|
$HttpRequestModelCopyWith<$Res>? get httpRequestModel;
|
||||||
|
$AIRequestModelCopyWith<$Res>? get aiRequestModel;
|
||||||
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
||||||
$AuthModelCopyWith<$Res>? get authModel;
|
$AuthModelCopyWith<$Res>? get authModel;
|
||||||
}
|
}
|
||||||
@@ -76,7 +79,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? historyId = null,
|
Object? historyId = null,
|
||||||
Object? metaData = null,
|
Object? metaData = null,
|
||||||
Object? httpRequestModel = null,
|
Object? httpRequestModel = freezed,
|
||||||
|
Object? aiRequestModel = freezed,
|
||||||
Object? httpResponseModel = null,
|
Object? httpResponseModel = null,
|
||||||
Object? preRequestScript = freezed,
|
Object? preRequestScript = freezed,
|
||||||
Object? postRequestScript = freezed,
|
Object? postRequestScript = freezed,
|
||||||
@@ -91,10 +95,14 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
|
|||||||
? _value.metaData
|
? _value.metaData
|
||||||
: metaData // ignore: cast_nullable_to_non_nullable
|
: metaData // ignore: cast_nullable_to_non_nullable
|
||||||
as HistoryMetaModel,
|
as HistoryMetaModel,
|
||||||
httpRequestModel: null == httpRequestModel
|
httpRequestModel: freezed == httpRequestModel
|
||||||
? _value.httpRequestModel
|
? _value.httpRequestModel
|
||||||
: httpRequestModel // ignore: cast_nullable_to_non_nullable
|
: 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
|
httpResponseModel: null == httpResponseModel
|
||||||
? _value.httpResponseModel
|
? _value.httpResponseModel
|
||||||
: httpResponseModel // ignore: cast_nullable_to_non_nullable
|
: 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.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel {
|
$HttpRequestModelCopyWith<$Res>? get httpRequestModel {
|
||||||
return $HttpRequestModelCopyWith<$Res>(_value.httpRequestModel, (value) {
|
if (_value.httpRequestModel == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $HttpRequestModelCopyWith<$Res>(_value.httpRequestModel!, (value) {
|
||||||
return _then(_value.copyWith(httpRequestModel: value) as $Val);
|
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
|
/// Create a copy of HistoryRequestModel
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@@ -170,7 +196,8 @@ abstract class _$$HistoryRequestModelImplCopyWith<$Res>
|
|||||||
$Res call(
|
$Res call(
|
||||||
{String historyId,
|
{String historyId,
|
||||||
HistoryMetaModel metaData,
|
HistoryMetaModel metaData,
|
||||||
HttpRequestModel httpRequestModel,
|
HttpRequestModel? httpRequestModel,
|
||||||
|
AIRequestModel? aiRequestModel,
|
||||||
HttpResponseModel httpResponseModel,
|
HttpResponseModel httpResponseModel,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript,
|
String? postRequestScript,
|
||||||
@@ -179,7 +206,9 @@ abstract class _$$HistoryRequestModelImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
$HistoryMetaModelCopyWith<$Res> get metaData;
|
$HistoryMetaModelCopyWith<$Res> get metaData;
|
||||||
@override
|
@override
|
||||||
$HttpRequestModelCopyWith<$Res> get httpRequestModel;
|
$HttpRequestModelCopyWith<$Res>? get httpRequestModel;
|
||||||
|
@override
|
||||||
|
$AIRequestModelCopyWith<$Res>? get aiRequestModel;
|
||||||
@override
|
@override
|
||||||
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
$HttpResponseModelCopyWith<$Res> get httpResponseModel;
|
||||||
@override
|
@override
|
||||||
@@ -201,7 +230,8 @@ class __$$HistoryRequestModelImplCopyWithImpl<$Res>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? historyId = null,
|
Object? historyId = null,
|
||||||
Object? metaData = null,
|
Object? metaData = null,
|
||||||
Object? httpRequestModel = null,
|
Object? httpRequestModel = freezed,
|
||||||
|
Object? aiRequestModel = freezed,
|
||||||
Object? httpResponseModel = null,
|
Object? httpResponseModel = null,
|
||||||
Object? preRequestScript = freezed,
|
Object? preRequestScript = freezed,
|
||||||
Object? postRequestScript = freezed,
|
Object? postRequestScript = freezed,
|
||||||
@@ -216,10 +246,14 @@ class __$$HistoryRequestModelImplCopyWithImpl<$Res>
|
|||||||
? _value.metaData
|
? _value.metaData
|
||||||
: metaData // ignore: cast_nullable_to_non_nullable
|
: metaData // ignore: cast_nullable_to_non_nullable
|
||||||
as HistoryMetaModel,
|
as HistoryMetaModel,
|
||||||
httpRequestModel: null == httpRequestModel
|
httpRequestModel: freezed == httpRequestModel
|
||||||
? _value.httpRequestModel
|
? _value.httpRequestModel
|
||||||
: httpRequestModel // ignore: cast_nullable_to_non_nullable
|
: 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
|
httpResponseModel: null == httpResponseModel
|
||||||
? _value.httpResponseModel
|
? _value.httpResponseModel
|
||||||
: httpResponseModel // ignore: cast_nullable_to_non_nullable
|
: httpResponseModel // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -247,7 +281,8 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
|||||||
const _$HistoryRequestModelImpl(
|
const _$HistoryRequestModelImpl(
|
||||||
{required this.historyId,
|
{required this.historyId,
|
||||||
required this.metaData,
|
required this.metaData,
|
||||||
required this.httpRequestModel,
|
this.httpRequestModel,
|
||||||
|
this.aiRequestModel,
|
||||||
required this.httpResponseModel,
|
required this.httpResponseModel,
|
||||||
this.preRequestScript,
|
this.preRequestScript,
|
||||||
this.postRequestScript,
|
this.postRequestScript,
|
||||||
@@ -261,7 +296,9 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
|||||||
@override
|
@override
|
||||||
final HistoryMetaModel metaData;
|
final HistoryMetaModel metaData;
|
||||||
@override
|
@override
|
||||||
final HttpRequestModel httpRequestModel;
|
final HttpRequestModel? httpRequestModel;
|
||||||
|
@override
|
||||||
|
final AIRequestModel? aiRequestModel;
|
||||||
@override
|
@override
|
||||||
final HttpResponseModel httpResponseModel;
|
final HttpResponseModel httpResponseModel;
|
||||||
@override
|
@override
|
||||||
@@ -273,7 +310,7 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
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
|
@override
|
||||||
@@ -287,6 +324,8 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
|||||||
other.metaData == metaData) &&
|
other.metaData == metaData) &&
|
||||||
(identical(other.httpRequestModel, httpRequestModel) ||
|
(identical(other.httpRequestModel, httpRequestModel) ||
|
||||||
other.httpRequestModel == httpRequestModel) &&
|
other.httpRequestModel == httpRequestModel) &&
|
||||||
|
(identical(other.aiRequestModel, aiRequestModel) ||
|
||||||
|
other.aiRequestModel == aiRequestModel) &&
|
||||||
(identical(other.httpResponseModel, httpResponseModel) ||
|
(identical(other.httpResponseModel, httpResponseModel) ||
|
||||||
other.httpResponseModel == httpResponseModel) &&
|
other.httpResponseModel == httpResponseModel) &&
|
||||||
(identical(other.preRequestScript, preRequestScript) ||
|
(identical(other.preRequestScript, preRequestScript) ||
|
||||||
@@ -304,6 +343,7 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
|
|||||||
historyId,
|
historyId,
|
||||||
metaData,
|
metaData,
|
||||||
httpRequestModel,
|
httpRequestModel,
|
||||||
|
aiRequestModel,
|
||||||
httpResponseModel,
|
httpResponseModel,
|
||||||
preRequestScript,
|
preRequestScript,
|
||||||
postRequestScript,
|
postRequestScript,
|
||||||
@@ -330,7 +370,8 @@ abstract class _HistoryRequestModel implements HistoryRequestModel {
|
|||||||
const factory _HistoryRequestModel(
|
const factory _HistoryRequestModel(
|
||||||
{required final String historyId,
|
{required final String historyId,
|
||||||
required final HistoryMetaModel metaData,
|
required final HistoryMetaModel metaData,
|
||||||
required final HttpRequestModel httpRequestModel,
|
final HttpRequestModel? httpRequestModel,
|
||||||
|
final AIRequestModel? aiRequestModel,
|
||||||
required final HttpResponseModel httpResponseModel,
|
required final HttpResponseModel httpResponseModel,
|
||||||
final String? preRequestScript,
|
final String? preRequestScript,
|
||||||
final String? postRequestScript,
|
final String? postRequestScript,
|
||||||
@@ -344,7 +385,9 @@ abstract class _HistoryRequestModel implements HistoryRequestModel {
|
|||||||
@override
|
@override
|
||||||
HistoryMetaModel get metaData;
|
HistoryMetaModel get metaData;
|
||||||
@override
|
@override
|
||||||
HttpRequestModel get httpRequestModel;
|
HttpRequestModel? get httpRequestModel;
|
||||||
|
@override
|
||||||
|
AIRequestModel? get aiRequestModel;
|
||||||
@override
|
@override
|
||||||
HttpResponseModel get httpResponseModel;
|
HttpResponseModel get httpResponseModel;
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -11,8 +11,14 @@ _$HistoryRequestModelImpl _$$HistoryRequestModelImplFromJson(Map json) =>
|
|||||||
historyId: json['historyId'] as String,
|
historyId: json['historyId'] as String,
|
||||||
metaData: HistoryMetaModel.fromJson(
|
metaData: HistoryMetaModel.fromJson(
|
||||||
Map<String, Object?>.from(json['metaData'] as Map)),
|
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)),
|
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(
|
httpResponseModel: HttpResponseModel.fromJson(
|
||||||
Map<String, Object?>.from(json['httpResponseModel'] as Map)),
|
Map<String, Object?>.from(json['httpResponseModel'] as Map)),
|
||||||
preRequestScript: json['preRequestScript'] as String?,
|
preRequestScript: json['preRequestScript'] as String?,
|
||||||
@@ -28,7 +34,8 @@ Map<String, dynamic> _$$HistoryRequestModelImplToJson(
|
|||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'historyId': instance.historyId,
|
'historyId': instance.historyId,
|
||||||
'metaData': instance.metaData.toJson(),
|
'metaData': instance.metaData.toJson(),
|
||||||
'httpRequestModel': instance.httpRequestModel.toJson(),
|
'httpRequestModel': instance.httpRequestModel?.toJson(),
|
||||||
|
'aiRequestModel': instance.aiRequestModel?.toJson(),
|
||||||
'httpResponseModel': instance.httpResponseModel.toJson(),
|
'httpResponseModel': instance.httpResponseModel.toJson(),
|
||||||
'preRequestScript': instance.preRequestScript,
|
'preRequestScript': instance.preRequestScript,
|
||||||
'postRequestScript': instance.postRequestScript,
|
'postRequestScript': instance.postRequestScript,
|
||||||
|
|||||||
@@ -187,10 +187,15 @@ class CollectionStateNotifier
|
|||||||
|
|
||||||
var itemIds = ref.read(requestSequenceProvider);
|
var itemIds = ref.read(requestSequenceProvider);
|
||||||
var currentModel = historyRequestModel;
|
var currentModel = historyRequestModel;
|
||||||
|
|
||||||
|
final aT = currentModel.aiRequestModel != null ? APIType.ai : APIType.rest;
|
||||||
|
|
||||||
final newModel = RequestModel(
|
final newModel = RequestModel(
|
||||||
|
apiType: aT,
|
||||||
id: newId,
|
id: newId,
|
||||||
name: "${currentModel.metaData.name} (history)",
|
name: "${currentModel.metaData.name} (history)",
|
||||||
httpRequestModel: currentModel.httpRequestModel,
|
aiRequestModel: currentModel.aiRequestModel,
|
||||||
|
httpRequestModel: currentModel.httpRequestModel ?? HttpRequestModel(),
|
||||||
responseStatus: currentModel.metaData.responseStatus,
|
responseStatus: currentModel.metaData.responseStatus,
|
||||||
message: kResponseCodeReasons[currentModel.metaData.responseStatus],
|
message: kResponseCodeReasons[currentModel.metaData.responseStatus],
|
||||||
httpResponseModel: currentModel.httpResponseModel,
|
httpResponseModel: currentModel.httpResponseModel,
|
||||||
@@ -461,6 +466,7 @@ class CollectionStateNotifier
|
|||||||
timeStamp: DateTime.now(),
|
timeStamp: DateTime.now(),
|
||||||
),
|
),
|
||||||
httpRequestModel: substitutedHttpRequestModel,
|
httpRequestModel: substitutedHttpRequestModel,
|
||||||
|
aiRequestModel: aiRequestModel,
|
||||||
httpResponseModel: httpResponseModel!,
|
httpResponseModel: httpResponseModel!,
|
||||||
preRequestScript: requestModel.preRequestScript,
|
preRequestScript: requestModel.preRequestScript,
|
||||||
postRequestScript: requestModel.postRequestScript,
|
postRequestScript: requestModel.postRequestScript,
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ class CodePane extends ConsumerWidget {
|
|||||||
final selectedRequestModel = isHistoryRequest
|
final selectedRequestModel = isHistoryRequest
|
||||||
? getRequestModelFromHistoryModel(selectedHistoryRequestModel!)
|
? getRequestModelFromHistoryModel(selectedHistoryRequestModel!)
|
||||||
: ref.watch(selectedRequestModelProvider);
|
: ref.watch(selectedRequestModelProvider);
|
||||||
|
|
||||||
|
if (selectedRequestModel!.apiType == APIType.ai) {
|
||||||
|
return const ErrorMessage(
|
||||||
|
message: "Code generation for AI Requests is currently not available.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final defaultUriScheme =
|
final defaultUriScheme =
|
||||||
ref.watch(settingsProvider.select((value) => value.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_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';
|
||||||
@@ -22,22 +23,38 @@ class HistoryRequestPane extends ConsumerWidget {
|
|||||||
final codePaneVisible = ref.watch(historyCodePaneVisibleStateProvider);
|
final codePaneVisible = ref.watch(historyCodePaneVisibleStateProvider);
|
||||||
final apiType = ref.watch(selectedHistoryRequestModelProvider
|
final apiType = ref.watch(selectedHistoryRequestModelProvider
|
||||||
.select((value) => value?.metaData.apiType));
|
.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 headerLength = headersMap.length;
|
||||||
|
|
||||||
final paramsMap = ref.watch(selectedHistoryRequestModelProvider
|
final paramsMap = ref.watch(selectedHistoryRequestModelProvider.select(
|
||||||
.select((value) => value?.httpRequestModel.paramsMap)) ??
|
(value) {
|
||||||
|
if (apiType == APIType.ai) return <String, String>{};
|
||||||
|
return value?.httpRequestModel!.paramsMap;
|
||||||
|
},
|
||||||
|
)) ??
|
||||||
{};
|
{};
|
||||||
final paramLength = paramsMap.length;
|
final paramLength = paramsMap.length;
|
||||||
|
|
||||||
final hasBody = ref.watch(selectedHistoryRequestModelProvider
|
final hasBody = ref.watch(selectedHistoryRequestModelProvider.select(
|
||||||
.select((value) => value?.httpRequestModel.hasBody)) ??
|
(value) {
|
||||||
|
if (apiType == APIType.ai) return false;
|
||||||
|
return value?.httpRequestModel!.hasBody;
|
||||||
|
},
|
||||||
|
)) ??
|
||||||
false;
|
false;
|
||||||
|
|
||||||
final hasQuery = ref.watch(selectedHistoryRequestModelProvider
|
final hasQuery =
|
||||||
.select((value) => value?.httpRequestModel.hasQuery)) ??
|
ref.watch(selectedHistoryRequestModelProvider.select((value) {
|
||||||
|
if (apiType == APIType.ai) return false;
|
||||||
|
return value?.httpRequestModel!.hasQuery;
|
||||||
|
})) ??
|
||||||
false;
|
false;
|
||||||
|
|
||||||
final scriptsLength = ref.watch(selectedHistoryRequestModelProvider
|
final scriptsLength = ref.watch(selectedHistoryRequestModelProvider
|
||||||
@@ -127,7 +144,27 @@ class HistoryRequestPane extends ConsumerWidget {
|
|||||||
const HistoryScriptsTab(),
|
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,
|
_ => kSizedBoxEmpty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,20 @@ class HistoryResponsePane extends ConsumerWidget {
|
|||||||
final selectedId = ref.watch(selectedHistoryIdStateProvider);
|
final selectedId = ref.watch(selectedHistoryIdStateProvider);
|
||||||
final selectedHistoryRequest =
|
final selectedHistoryRequest =
|
||||||
ref.watch(selectedHistoryRequestModelProvider);
|
ref.watch(selectedHistoryRequestModelProvider);
|
||||||
|
|
||||||
final historyHttpResponseModel = selectedHistoryRequest?.httpResponseModel;
|
final historyHttpResponseModel = selectedHistoryRequest?.httpResponseModel;
|
||||||
|
|
||||||
if (selectedId != null) {
|
if (selectedId != null) {
|
||||||
final requestModel =
|
final requestModel =
|
||||||
getRequestModelFromHistoryModel(selectedHistoryRequest!);
|
getRequestModelFromHistoryModel(selectedHistoryRequest!);
|
||||||
|
|
||||||
|
final statusCode = historyHttpResponseModel?.statusCode;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
ResponsePaneHeader(
|
ResponsePaneHeader(
|
||||||
responseStatus: historyHttpResponseModel?.statusCode,
|
responseStatus: statusCode,
|
||||||
message: kResponseCodeReasons[historyHttpResponseModel?.statusCode],
|
message: kResponseCodeReasons[statusCode],
|
||||||
time: historyHttpResponseModel?.time,
|
time: historyHttpResponseModel?.time,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ RequestModel getRequestModelFromHistoryModel(HistoryRequestModel model) {
|
|||||||
name: model.metaData.name,
|
name: model.metaData.name,
|
||||||
responseStatus: model.httpResponseModel.statusCode,
|
responseStatus: model.httpResponseModel.statusCode,
|
||||||
message: kResponseCodeReasons[model.httpResponseModel.statusCode],
|
message: kResponseCodeReasons[model.httpResponseModel.statusCode],
|
||||||
|
aiRequestModel: model.aiRequestModel,
|
||||||
httpRequestModel: model.httpRequestModel,
|
httpRequestModel: model.httpRequestModel,
|
||||||
httpResponseModel: model.httpResponseModel,
|
httpResponseModel: model.httpResponseModel,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import 'package:genai/llm_config.dart';
|
|||||||
class SliderAIConfig extends StatelessWidget {
|
class SliderAIConfig extends StatelessWidget {
|
||||||
final LLMModelConfiguration configuration;
|
final LLMModelConfiguration configuration;
|
||||||
final Function(LLMModelConfiguration) onSliderUpdated;
|
final Function(LLMModelConfiguration) onSliderUpdated;
|
||||||
|
final bool readonly;
|
||||||
const SliderAIConfig({
|
const SliderAIConfig({
|
||||||
super.key,
|
super.key,
|
||||||
required this.configuration,
|
required this.configuration,
|
||||||
required this.onSliderUpdated,
|
required this.onSliderUpdated,
|
||||||
|
this.readonly = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -23,6 +25,7 @@ class SliderAIConfig extends StatelessWidget {
|
|||||||
max: (configuration.configValue.value as (double, double, double))
|
max: (configuration.configValue.value as (double, double, double))
|
||||||
.$3,
|
.$3,
|
||||||
onChanged: (x) {
|
onChanged: (x) {
|
||||||
|
if (readonly) return;
|
||||||
final z =
|
final z =
|
||||||
configuration.configValue.value as (double, double, double);
|
configuration.configValue.value as (double, double, double);
|
||||||
configuration.configValue.value = (z.$1, x, z.$3);
|
configuration.configValue.value = (z.$1, x, z.$3);
|
||||||
@@ -43,11 +46,13 @@ class WritableAIConfig extends StatelessWidget {
|
|||||||
final bool numeric;
|
final bool numeric;
|
||||||
final LLMModelConfiguration configuration;
|
final LLMModelConfiguration configuration;
|
||||||
final Function(LLMModelConfiguration) onConfigUpdated;
|
final Function(LLMModelConfiguration) onConfigUpdated;
|
||||||
|
final bool readonly;
|
||||||
const WritableAIConfig({
|
const WritableAIConfig({
|
||||||
super.key,
|
super.key,
|
||||||
this.numeric = false,
|
this.numeric = false,
|
||||||
required this.configuration,
|
required this.configuration,
|
||||||
required this.onConfigUpdated,
|
required this.onConfigUpdated,
|
||||||
|
this.readonly = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -55,6 +60,7 @@ class WritableAIConfig extends StatelessWidget {
|
|||||||
return TextFormField(
|
return TextFormField(
|
||||||
initialValue: configuration.configValue.value.toString(),
|
initialValue: configuration.configValue.value.toString(),
|
||||||
onChanged: (x) {
|
onChanged: (x) {
|
||||||
|
if (readonly) return;
|
||||||
if (numeric) {
|
if (numeric) {
|
||||||
if (x.isEmpty) x = '0';
|
if (x.isEmpty) x = '0';
|
||||||
if (num.tryParse(x) == null) return;
|
if (num.tryParse(x) == null) return;
|
||||||
@@ -71,10 +77,12 @@ class WritableAIConfig extends StatelessWidget {
|
|||||||
class BooleanAIConfig extends StatelessWidget {
|
class BooleanAIConfig extends StatelessWidget {
|
||||||
final LLMModelConfiguration configuration;
|
final LLMModelConfiguration configuration;
|
||||||
final Function(LLMModelConfiguration) onConfigUpdated;
|
final Function(LLMModelConfiguration) onConfigUpdated;
|
||||||
|
final bool readonly;
|
||||||
const BooleanAIConfig({
|
const BooleanAIConfig({
|
||||||
super.key,
|
super.key,
|
||||||
required this.configuration,
|
required this.configuration,
|
||||||
required this.onConfigUpdated,
|
required this.onConfigUpdated,
|
||||||
|
this.readonly = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -82,6 +90,7 @@ class BooleanAIConfig extends StatelessWidget {
|
|||||||
return Switch(
|
return Switch(
|
||||||
value: configuration.configValue.value as bool,
|
value: configuration.configValue.value as bool,
|
||||||
onChanged: (x) {
|
onChanged: (x) {
|
||||||
|
if (readonly) return;
|
||||||
configuration.configValue.value = x;
|
configuration.configValue.value = x;
|
||||||
onConfigUpdated(configuration);
|
onConfigUpdated(configuration);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void main() {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
find.text(
|
find.text(
|
||||||
historyRequestModel.httpRequestModel.method.name.toUpperCase()),
|
historyRequestModel.httpRequestModel!.method.name.toUpperCase()),
|
||||||
findsOneWidget);
|
findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
find.text(historyRequestModel.httpRequestModel.url), findsOneWidget);
|
find.text(historyRequestModel.httpRequestModel!.url), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user