mirror of
https://github.com/foss42/apidash.git
synced 2025-12-04 03:46:57 +08:00
genai: Minor Refactoring and Corrections
This commit is contained in:
@@ -332,32 +332,14 @@ class CollectionStateNotifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
APIType apiType = executionRequestModel.apiType;
|
APIType apiType = executionRequestModel.apiType;
|
||||||
|
|
||||||
late HttpRequestModel substitutedHttpRequestModel;
|
|
||||||
AIRequestModel? aiRequestModel;
|
AIRequestModel? aiRequestModel;
|
||||||
bool noSSL = ref.read(settingsProvider).isSSLDisabled;
|
bool noSSL = ref.read(settingsProvider).isSSLDisabled;
|
||||||
|
HttpRequestModel substitutedHttpRequestModel;
|
||||||
|
|
||||||
if (apiType == APIType.ai) {
|
if (apiType == APIType.ai) {
|
||||||
aiRequestModel = requestModel.aiRequestModel!;
|
aiRequestModel = requestModel.aiRequestModel!;
|
||||||
|
substitutedHttpRequestModel =
|
||||||
final streamingMode = aiRequestModel.payload
|
getSubstitutedHttpRequestModel(aiRequestModel.convertToHTTPRequest());
|
||||||
.configMap[LLMConfigName.stream.name]?.configValue.value ??
|
|
||||||
false;
|
|
||||||
|
|
||||||
final genAIRequest = aiRequestModel.createRequest(stream: streamingMode);
|
|
||||||
substitutedHttpRequestModel = getSubstitutedHttpRequestModel(
|
|
||||||
HttpRequestModel(
|
|
||||||
method: HTTPVerb.post,
|
|
||||||
headers: [
|
|
||||||
...genAIRequest.headers.entries.map(
|
|
||||||
(x) => NameValueModel(name: x.key, value: x.value),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
url: genAIRequest.endpoint,
|
|
||||||
bodyContentType: ContentType.json,
|
|
||||||
body: jsonEncode(genAIRequest.body),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
substitutedHttpRequestModel = getSubstitutedHttpRequestModel(
|
substitutedHttpRequestModel = getSubstitutedHttpRequestModel(
|
||||||
executionRequestModel.httpRequestModel!);
|
executionRequestModel.httpRequestModel!);
|
||||||
@@ -371,6 +353,7 @@ class CollectionStateNotifier
|
|||||||
sendingTime: DateTime.now(),
|
sendingTime: DateTime.now(),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
bool streamingMode = true; //Default: Streaming First
|
||||||
|
|
||||||
final stream = await streamHttpRequest(
|
final stream = await streamHttpRequest(
|
||||||
requestId,
|
requestId,
|
||||||
@@ -388,8 +371,6 @@ class CollectionStateNotifier
|
|||||||
|
|
||||||
StreamSubscription? sub;
|
StreamSubscription? sub;
|
||||||
|
|
||||||
bool streaming = true; //DEFAULT to streaming
|
|
||||||
|
|
||||||
sub = stream.listen((rec) async {
|
sub = stream.listen((rec) async {
|
||||||
if (rec == null) return;
|
if (rec == null) return;
|
||||||
|
|
||||||
@@ -399,7 +380,7 @@ class CollectionStateNotifier
|
|||||||
final errorMessage = rec.$4;
|
final errorMessage = rec.$4;
|
||||||
|
|
||||||
if (isStreamingResponse == false) {
|
if (isStreamingResponse == false) {
|
||||||
streaming = false;
|
streamingMode = false;
|
||||||
if (!completer.isCompleted) {
|
if (!completer.isCompleted) {
|
||||||
completer.complete((response, duration, errorMessage));
|
completer.complete((response, duration, errorMessage));
|
||||||
}
|
}
|
||||||
@@ -467,9 +448,8 @@ class CollectionStateNotifier
|
|||||||
isStreamingResponse: isStreamingResponse,
|
isStreamingResponse: isStreamingResponse,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!streaming) {
|
|
||||||
//AI-FORMATTING for Non Streaming Varaint
|
//AI-FORMATTING for Non Streaming Varaint
|
||||||
if (apiType == APIType.ai) {
|
if (streamingMode == false && apiType == APIType.ai) {
|
||||||
final mT = httpResponseModel?.mediaType;
|
final mT = httpResponseModel?.mediaType;
|
||||||
final body = (mT?.subtype == kSubTypeJson)
|
final body = (mT?.subtype == kSubTypeJson)
|
||||||
? utf8.decode(response.bodyBytes)
|
? utf8.decode(response.bodyBytes)
|
||||||
@@ -481,7 +461,6 @@ class CollectionStateNotifier
|
|||||||
: formatBody(body, mT);
|
: formatBody(body, mT);
|
||||||
httpResponseModel = httpResponseModel?.copyWith(formattedBody: fb);
|
httpResponseModel = httpResponseModel?.copyWith(formattedBody: fb);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
newRequestModel = newRequestModel.copyWith(
|
newRequestModel = newRequestModel.copyWith(
|
||||||
responseStatus: statusCode,
|
responseStatus: statusCode,
|
||||||
|
|||||||
@@ -52,10 +52,7 @@ class ResponseDetails extends ConsumerWidget {
|
|||||||
selectedRequestModelProvider.select((value) => value?.responseStatus));
|
selectedRequestModelProvider.select((value) => value?.responseStatus));
|
||||||
final message = ref
|
final message = ref
|
||||||
.watch(selectedRequestModelProvider.select((value) => value?.message));
|
.watch(selectedRequestModelProvider.select((value) => value?.message));
|
||||||
|
final responseModel = ref.watch(selectedRequestModelProvider
|
||||||
HttpResponseModel? httpResponseModel;
|
|
||||||
|
|
||||||
httpResponseModel = ref.watch(selectedRequestModelProvider
|
|
||||||
.select((value) => value?.httpResponseModel));
|
.select((value) => value?.httpResponseModel));
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@@ -63,7 +60,7 @@ class ResponseDetails extends ConsumerWidget {
|
|||||||
ResponsePaneHeader(
|
ResponsePaneHeader(
|
||||||
responseStatus: responseStatus,
|
responseStatus: responseStatus,
|
||||||
message: message,
|
message: message,
|
||||||
time: httpResponseModel?.time,
|
time: responseModel?.time,
|
||||||
onClearResponse: () {
|
onClearResponse: () {
|
||||||
ref.read(collectionStateNotifierProvider.notifier).clearResponse();
|
ref.read(collectionStateNotifierProvider.notifier).clearResponse();
|
||||||
},
|
},
|
||||||
@@ -112,7 +109,8 @@ class ResponseHeadersTab extends ConsumerWidget {
|
|||||||
final requestHeaders =
|
final requestHeaders =
|
||||||
ref.watch(selectedRequestModelProvider.select((value) {
|
ref.watch(selectedRequestModelProvider.select((value) {
|
||||||
return value?.httpResponseModel!.requestHeaders;
|
return value?.httpResponseModel!.requestHeaders;
|
||||||
}));
|
})) ??
|
||||||
|
{};
|
||||||
|
|
||||||
final responseHeaders =
|
final responseHeaders =
|
||||||
ref.watch(selectedRequestModelProvider.select((value) {
|
ref.watch(selectedRequestModelProvider.select((value) {
|
||||||
@@ -122,7 +120,7 @@ class ResponseHeadersTab extends ConsumerWidget {
|
|||||||
|
|
||||||
return ResponseHeaders(
|
return ResponseHeaders(
|
||||||
responseHeaders: responseHeaders,
|
responseHeaders: responseHeaders,
|
||||||
requestHeaders: requestHeaders as Map? ?? {},
|
requestHeaders: requestHeaders,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,14 +124,12 @@ class URLTextField extends ConsumerWidget {
|
|||||||
?.httpRequestModel
|
?.httpRequestModel
|
||||||
?.url,
|
?.url,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final aim = ref
|
if (aiReqM != null) {
|
||||||
.read(collectionStateNotifierProvider)![selectedId]!
|
// Handle AI Endpoint Changes
|
||||||
.aiRequestModel;
|
aiReqM.payload.endpoint = value;
|
||||||
if (aim != null) {
|
|
||||||
aim.payload.endpoint = value;
|
|
||||||
ref
|
ref
|
||||||
.read(collectionStateNotifierProvider.notifier)
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
.update(aiRequestModel: aim.updatePayload(aim.payload));
|
.update(aiRequestModel: aiReqM.updatePayload(aiReqM.payload));
|
||||||
} else {
|
} else {
|
||||||
ref.read(collectionStateNotifierProvider.notifier).update(url: value);
|
ref.read(collectionStateNotifierProvider.notifier).update(url: value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,16 @@ class ResponseBody extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
HttpResponseModel? httpResponseModel =
|
final responseModel = selectedRequestModel?.httpResponseModel;
|
||||||
selectedRequestModel?.httpResponseModel;
|
|
||||||
|
|
||||||
if (httpResponseModel == null) {
|
if (responseModel == null) {
|
||||||
return const ErrorMessage(
|
return const ErrorMessage(
|
||||||
message: '$kNullResponseModelError $kUnexpectedRaiseIssue');
|
message: '$kNullResponseModelError $kUnexpectedRaiseIssue');
|
||||||
}
|
}
|
||||||
|
|
||||||
final isSSE = httpResponseModel.sseOutput?.isNotEmpty ?? false;
|
final isSSE = responseModel.sseOutput?.isNotEmpty ?? false;
|
||||||
var body = httpResponseModel.body;
|
var body = responseModel.body;
|
||||||
var formattedBody = httpResponseModel.formattedBody;
|
var formattedBody = responseModel.formattedBody;
|
||||||
|
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
return const ErrorMessage(
|
return const ErrorMessage(
|
||||||
@@ -42,11 +41,11 @@ class ResponseBody extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (isSSE) {
|
if (isSSE) {
|
||||||
body = httpResponseModel.sseOutput!.join();
|
body = responseModel.sseOutput!.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
final mediaType =
|
final mediaType =
|
||||||
httpResponseModel.mediaType ?? MediaType(kTypeText, kSubTypePlain);
|
responseModel.mediaType ?? MediaType(kTypeText, kSubTypePlain);
|
||||||
|
|
||||||
// Fix #415: Treat null Content-type as plain text instead of Error message
|
// Fix #415: Treat null Content-type as plain text instead of Error message
|
||||||
// if (mediaType == null) {
|
// if (mediaType == null) {
|
||||||
@@ -66,14 +65,14 @@ class ResponseBody extends StatelessWidget {
|
|||||||
options.remove(ResponseBodyView.code);
|
options.remove(ResponseBodyView.code);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpResponseModel.sseOutput?.isNotEmpty ?? false) {
|
if (responseModel.sseOutput?.isNotEmpty ?? false) {
|
||||||
return ResponseBodySuccess(
|
return ResponseBodySuccess(
|
||||||
key: Key("${selectedRequestModel!.id}-response"),
|
key: Key("${selectedRequestModel!.id}-response"),
|
||||||
mediaType: MediaType('text', 'event-stream'),
|
mediaType: MediaType('text', 'event-stream'),
|
||||||
options: [ResponseBodyView.sse, ResponseBodyView.raw],
|
options: [ResponseBodyView.sse, ResponseBodyView.raw],
|
||||||
bytes: utf8.encode((httpResponseModel.sseOutput!).toString()),
|
bytes: utf8.encode((responseModel.sseOutput!).toString()),
|
||||||
body: jsonEncode(httpResponseModel.sseOutput!),
|
body: jsonEncode(responseModel.sseOutput!),
|
||||||
formattedBody: httpResponseModel.sseOutput!.join('\n'),
|
formattedBody: responseModel.sseOutput!.join('\n'),
|
||||||
selectedModel: selectedRequestModel?.aiRequestModel?.model,
|
selectedModel: selectedRequestModel?.aiRequestModel?.model,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -82,7 +81,7 @@ class ResponseBody extends StatelessWidget {
|
|||||||
key: Key("${selectedRequestModel!.id}-response"),
|
key: Key("${selectedRequestModel!.id}-response"),
|
||||||
mediaType: mediaType,
|
mediaType: mediaType,
|
||||||
options: options,
|
options: options,
|
||||||
bytes: httpResponseModel.bodyBytes!,
|
bytes: responseModel.bodyBytes!,
|
||||||
body: body,
|
body: body,
|
||||||
formattedBody: formattedBody,
|
formattedBody: formattedBody,
|
||||||
highlightLanguage: highlightLanguage,
|
highlightLanguage: highlightLanguage,
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class ResponseBodySuccess extends StatefulWidget {
|
|||||||
required this.options,
|
required this.options,
|
||||||
required this.bytes,
|
required this.bytes,
|
||||||
this.formattedBody,
|
this.formattedBody,
|
||||||
// this.sseOutput,
|
|
||||||
this.highlightLanguage,
|
this.highlightLanguage,
|
||||||
this.selectedModel,
|
this.selectedModel,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:apidash/models/request_model.dart';
|
|
||||||
import 'package:apidash/providers/collection_providers.dart';
|
|
||||||
import 'package:apidash/providers/history_providers.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';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
import 'package:genai/genai.dart';
|
import 'package:genai/genai.dart';
|
||||||
import 'package:genai/models/ai_request_model.dart';
|
|
||||||
|
|
||||||
class SSEDisplay extends StatefulWidget {
|
class SSEDisplay extends StatefulWidget {
|
||||||
final LLMModel? selectedLLModel;
|
final LLMModel? selectedLLModel;
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:better_networking/better_networking.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:genai/llm_config.dart';
|
||||||
import '../llm_model.dart';
|
import '../llm_model.dart';
|
||||||
import '../llm_provider.dart';
|
import '../llm_provider.dart';
|
||||||
import '../llm_saveobject.dart';
|
import '../llm_saveobject.dart';
|
||||||
@@ -59,4 +63,22 @@ class AIRequestModel with _$AIRequestModel {
|
|||||||
provider: provider,
|
provider: provider,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpRequestModel convertToHTTPRequest() {
|
||||||
|
final streamingMode =
|
||||||
|
payload.configMap[LLMConfigName.stream.name]?.configValue.value ??
|
||||||
|
false;
|
||||||
|
final genAIRequest = createRequest(stream: streamingMode);
|
||||||
|
return HttpRequestModel(
|
||||||
|
method: HTTPVerb.post,
|
||||||
|
headers: [
|
||||||
|
...genAIRequest.headers.entries.map(
|
||||||
|
(x) => NameValueModel(name: x.key, value: x.value),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
url: genAIRequest.endpoint,
|
||||||
|
bodyContentType: ContentType.json,
|
||||||
|
body: jsonEncode(genAIRequest.body),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user