From 30075a6d95f3114d05f8deb1b0865570ef2b9169 Mon Sep 17 00:00:00 2001 From: Manas Hejmadi Date: Mon, 11 Aug 2025 15:10:13 +0530 Subject: [PATCH] genai: Minor Refactoring and Corrections --- lib/providers/collection_providers.dart | 53 ++++++------------- .../details_card/response_pane.dart | 14 +++-- .../home_page/editor_pane/url_card.dart | 10 ++-- lib/widgets/response_body.dart | 25 +++++---- lib/widgets/response_body_success.dart | 1 - lib/widgets/sse_display.dart | 5 -- .../genai/lib/models/ai_request_model.dart | 22 ++++++++ 7 files changed, 60 insertions(+), 70 deletions(-) diff --git a/lib/providers/collection_providers.dart b/lib/providers/collection_providers.dart index 6d427ac3..fec5f0e0 100644 --- a/lib/providers/collection_providers.dart +++ b/lib/providers/collection_providers.dart @@ -332,32 +332,14 @@ class CollectionStateNotifier } APIType apiType = executionRequestModel.apiType; - - late HttpRequestModel substitutedHttpRequestModel; AIRequestModel? aiRequestModel; bool noSSL = ref.read(settingsProvider).isSSLDisabled; + HttpRequestModel substitutedHttpRequestModel; if (apiType == APIType.ai) { aiRequestModel = requestModel.aiRequestModel!; - - final streamingMode = aiRequestModel.payload - .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), - ), - ); + substitutedHttpRequestModel = + getSubstitutedHttpRequestModel(aiRequestModel.convertToHTTPRequest()); } else { substitutedHttpRequestModel = getSubstitutedHttpRequestModel( executionRequestModel.httpRequestModel!); @@ -371,6 +353,7 @@ class CollectionStateNotifier sendingTime: DateTime.now(), ), }; + bool streamingMode = true; //Default: Streaming First final stream = await streamHttpRequest( requestId, @@ -388,8 +371,6 @@ class CollectionStateNotifier StreamSubscription? sub; - bool streaming = true; //DEFAULT to streaming - sub = stream.listen((rec) async { if (rec == null) return; @@ -399,7 +380,7 @@ class CollectionStateNotifier final errorMessage = rec.$4; if (isStreamingResponse == false) { - streaming = false; + streamingMode = false; if (!completer.isCompleted) { completer.complete((response, duration, errorMessage)); } @@ -467,20 +448,18 @@ class CollectionStateNotifier isStreamingResponse: isStreamingResponse, ); - if (!streaming) { - //AI-FORMATTING for Non Streaming Varaint - if (apiType == APIType.ai) { - final mT = httpResponseModel?.mediaType; - final body = (mT?.subtype == kSubTypeJson) - ? utf8.decode(response.bodyBytes) - : response.body; + //AI-FORMATTING for Non Streaming Varaint + if (streamingMode == false && apiType == APIType.ai) { + final mT = httpResponseModel?.mediaType; + final body = (mT?.subtype == kSubTypeJson) + ? utf8.decode(response.bodyBytes) + : response.body; - final fb = response.statusCode == 200 - ? aiRequestModel?.model.provider.modelController - .outputFormatter(jsonDecode(body)) - : formatBody(body, mT); - httpResponseModel = httpResponseModel?.copyWith(formattedBody: fb); - } + final fb = response.statusCode == 200 + ? aiRequestModel?.model.provider.modelController + .outputFormatter(jsonDecode(body)) + : formatBody(body, mT); + httpResponseModel = httpResponseModel?.copyWith(formattedBody: fb); } newRequestModel = newRequestModel.copyWith( diff --git a/lib/screens/home_page/editor_pane/details_card/response_pane.dart b/lib/screens/home_page/editor_pane/details_card/response_pane.dart index 9bb3ab58..0e701d5f 100644 --- a/lib/screens/home_page/editor_pane/details_card/response_pane.dart +++ b/lib/screens/home_page/editor_pane/details_card/response_pane.dart @@ -52,10 +52,7 @@ class ResponseDetails extends ConsumerWidget { selectedRequestModelProvider.select((value) => value?.responseStatus)); final message = ref .watch(selectedRequestModelProvider.select((value) => value?.message)); - - HttpResponseModel? httpResponseModel; - - httpResponseModel = ref.watch(selectedRequestModelProvider + final responseModel = ref.watch(selectedRequestModelProvider .select((value) => value?.httpResponseModel)); return Column( @@ -63,7 +60,7 @@ class ResponseDetails extends ConsumerWidget { ResponsePaneHeader( responseStatus: responseStatus, message: message, - time: httpResponseModel?.time, + time: responseModel?.time, onClearResponse: () { ref.read(collectionStateNotifierProvider.notifier).clearResponse(); }, @@ -111,8 +108,9 @@ class ResponseHeadersTab extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final requestHeaders = ref.watch(selectedRequestModelProvider.select((value) { - return value?.httpResponseModel!.requestHeaders; - })); + return value?.httpResponseModel!.requestHeaders; + })) ?? + {}; final responseHeaders = ref.watch(selectedRequestModelProvider.select((value) { @@ -122,7 +120,7 @@ class ResponseHeadersTab extends ConsumerWidget { return ResponseHeaders( responseHeaders: responseHeaders, - requestHeaders: requestHeaders as Map? ?? {}, + requestHeaders: requestHeaders, ); } } diff --git a/lib/screens/home_page/editor_pane/url_card.dart b/lib/screens/home_page/editor_pane/url_card.dart index 6875cd0d..2cbd8870 100644 --- a/lib/screens/home_page/editor_pane/url_card.dart +++ b/lib/screens/home_page/editor_pane/url_card.dart @@ -124,14 +124,12 @@ class URLTextField extends ConsumerWidget { ?.httpRequestModel ?.url, onChanged: (value) { - final aim = ref - .read(collectionStateNotifierProvider)![selectedId]! - .aiRequestModel; - if (aim != null) { - aim.payload.endpoint = value; + if (aiReqM != null) { + // Handle AI Endpoint Changes + aiReqM.payload.endpoint = value; ref .read(collectionStateNotifierProvider.notifier) - .update(aiRequestModel: aim.updatePayload(aim.payload)); + .update(aiRequestModel: aiReqM.updatePayload(aiReqM.payload)); } else { ref.read(collectionStateNotifierProvider.notifier).update(url: value); } diff --git a/lib/widgets/response_body.dart b/lib/widgets/response_body.dart index 8d7e12e4..84774837 100644 --- a/lib/widgets/response_body.dart +++ b/lib/widgets/response_body.dart @@ -18,17 +18,16 @@ class ResponseBody extends StatelessWidget { @override Widget build(BuildContext context) { - HttpResponseModel? httpResponseModel = - selectedRequestModel?.httpResponseModel; + final responseModel = selectedRequestModel?.httpResponseModel; - if (httpResponseModel == null) { + if (responseModel == null) { return const ErrorMessage( message: '$kNullResponseModelError $kUnexpectedRaiseIssue'); } - final isSSE = httpResponseModel.sseOutput?.isNotEmpty ?? false; - var body = httpResponseModel.body; - var formattedBody = httpResponseModel.formattedBody; + final isSSE = responseModel.sseOutput?.isNotEmpty ?? false; + var body = responseModel.body; + var formattedBody = responseModel.formattedBody; if (body == null) { return const ErrorMessage( @@ -42,11 +41,11 @@ class ResponseBody extends StatelessWidget { ); } if (isSSE) { - body = httpResponseModel.sseOutput!.join(); + body = responseModel.sseOutput!.join(); } 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 // if (mediaType == null) { @@ -66,14 +65,14 @@ class ResponseBody extends StatelessWidget { options.remove(ResponseBodyView.code); } - if (httpResponseModel.sseOutput?.isNotEmpty ?? false) { + if (responseModel.sseOutput?.isNotEmpty ?? false) { return ResponseBodySuccess( key: Key("${selectedRequestModel!.id}-response"), mediaType: MediaType('text', 'event-stream'), options: [ResponseBodyView.sse, ResponseBodyView.raw], - bytes: utf8.encode((httpResponseModel.sseOutput!).toString()), - body: jsonEncode(httpResponseModel.sseOutput!), - formattedBody: httpResponseModel.sseOutput!.join('\n'), + bytes: utf8.encode((responseModel.sseOutput!).toString()), + body: jsonEncode(responseModel.sseOutput!), + formattedBody: responseModel.sseOutput!.join('\n'), selectedModel: selectedRequestModel?.aiRequestModel?.model, ); } @@ -82,7 +81,7 @@ class ResponseBody extends StatelessWidget { key: Key("${selectedRequestModel!.id}-response"), mediaType: mediaType, options: options, - bytes: httpResponseModel.bodyBytes!, + bytes: responseModel.bodyBytes!, body: body, formattedBody: formattedBody, highlightLanguage: highlightLanguage, diff --git a/lib/widgets/response_body_success.dart b/lib/widgets/response_body_success.dart index 7690344b..d7b1329c 100644 --- a/lib/widgets/response_body_success.dart +++ b/lib/widgets/response_body_success.dart @@ -18,7 +18,6 @@ class ResponseBodySuccess extends StatefulWidget { required this.options, required this.bytes, this.formattedBody, - // this.sseOutput, this.highlightLanguage, this.selectedModel, }); diff --git a/lib/widgets/sse_display.dart b/lib/widgets/sse_display.dart index 1d787525..6d0bee1f 100644 --- a/lib/widgets/sse_display.dart +++ b/lib/widgets/sse_display.dart @@ -1,12 +1,7 @@ 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:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:genai/genai.dart'; -import 'package:genai/models/ai_request_model.dart'; class SSEDisplay extends StatefulWidget { final LLMModel? selectedLLModel; diff --git a/packages/genai/lib/models/ai_request_model.dart b/packages/genai/lib/models/ai_request_model.dart index 724a567c..07d66392 100644 --- a/packages/genai/lib/models/ai_request_model.dart +++ b/packages/genai/lib/models/ai_request_model.dart @@ -1,4 +1,8 @@ +import 'dart:convert'; + +import 'package:better_networking/better_networking.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:genai/llm_config.dart'; import '../llm_model.dart'; import '../llm_provider.dart'; import '../llm_saveobject.dart'; @@ -59,4 +63,22 @@ class AIRequestModel with _$AIRequestModel { 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), + ); + } }