genai: Minor Refactoring and Corrections

This commit is contained in:
Manas Hejmadi
2025-08-11 15:10:13 +05:30
parent eb852df646
commit 30075a6d95
7 changed files with 60 additions and 70 deletions

View File

@@ -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,

View File

@@ -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,
); );
} }
} }

View File

@@ -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);
} }

View File

@@ -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,

View File

@@ -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,
}); });

View File

@@ -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;

View File

@@ -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),
);
}
} }