diff --git a/lib/services/ollama_service.dart b/lib/services/ollama_service.dart index 73a43c18..dd266c6e 100644 --- a/lib/services/ollama_service.dart +++ b/lib/services/ollama_service.dart @@ -69,6 +69,7 @@ Analysis: [structured analysis]'''; return generateResponse(prompt); } + // Debugging Failed API Requests Future debugApi({required dynamic requestModel, required dynamic responseModel}) async { if (requestModel == null || responseModel == null) { return "There are no recent API Requests to debug."; @@ -100,6 +101,7 @@ Analysis: [structured analysis]'''; return generateResponse(prompt); } + // Generating test cases for API Future generateTestCases({required dynamic requestModel, required dynamic responseModel}) async { final method = requestModel.httpRequestModel?.method @@ -136,6 +138,7 @@ here is an example test case for the given:$exampleParams return generateResponse(prompt); } + // Generating Example Programming on API for different languages Future> generateExampleParams({required dynamic requestModel, required dynamic responseModel,}) async { final ollamaService = OllamaService(); @@ -195,29 +198,46 @@ generate same to same type of test case url for test purpose final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {}; final params = requestModel.httpRequestModel?.enabledParamsMap ?? {}; final body = requestModel.httpRequestModel?.body; - - final isFrontend = language.contains('(UI)'); - final baseLanguage = language.replaceAll(' (UI)', '').replaceAll(' (Console)', ''); + final responseBody = responseModel.body; final prompt = ''' -Generate complete, runnable $baseLanguage code for this API call: +Generate complete $language code for this API integration: -API Details: +API Request: - URL: $endpoint - Method: $method - Headers: ${headers.isEmpty ? 'None' : jsonEncode(headers)} - Params: ${params.isEmpty ? 'None' : jsonEncode(params)} - Body: ${body ?? 'None'} -Requirements: -1. Generate complete code that runs directly when copied. -2. ${isFrontend ? 'Include UI components to display response data.' : 'Print the response to the console.'} -3. Handle all parameter types (query, headers, body). -4. Add proper error handling. +Response Structure: +${_formatResponse(responseBody)} -Generate only the code with necessary imports. +Requirements: +1. Single-file solution with no external config +2. Direct API URL implementation +3. Error handling for network/status errors +4. UI components matching response data +5. Ready-to-run code with example data display + +Generate complete implementation code only. '''; return generateResponse(prompt); } + + String _formatResponse(dynamic response) { + if (response is Map) { + return response.entries + .map((e) => '${e.key}: ${_valueType(e.value)}') + .join('\n'); + } + return response?.toString() ?? 'No response body'; + } + + String _valueType(dynamic value) { + if (value is List) return 'List[${value.isNotEmpty ? _valueType(value.first) : '?'}]'; + if (value is Map) return 'Object'; + return value.runtimeType.toString(); + } } diff --git a/lib/widgets/chatbot_widget.dart b/lib/widgets/chatbot_widget.dart index 47bbcc22..d21cda31 100644 --- a/lib/widgets/chatbot_widget.dart +++ b/lib/widgets/chatbot_widget.dart @@ -22,19 +22,24 @@ class _ChatbotWidgetState extends ConsumerState { context: context, builder: (context) => AlertDialog( title: const Text('Select Language'), - content: SizedBox( - width: 300, - child: ListView( - shrinkWrap: true, + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - _buildLanguageTile('Flutter (UI)'), - _buildLanguageTile('React (UI)'), - _buildLanguageTile('Dart (Console)'), - _buildLanguageTile('Python'), - _buildLanguageTile('JavaScript'), - _buildLanguageTile('Node.js'), - _buildLanguageTile('Java'), - _buildLanguageTile('C#'), + for (var lang in [ + 'Flutter (UI)', + 'React (UI)', + 'Dart (Console)', + 'Python', + 'JavaScript', + 'Node.js', + 'Java', + 'C#' + ]) + ListTile( + title: Text(lang), + onTap: () => Navigator.pop(context, lang), + ), ], ), ), @@ -46,13 +51,6 @@ class _ChatbotWidgetState extends ConsumerState { } } - ListTile _buildLanguageTile(String language) { - return ListTile( - title: Text(language), - onTap: () => Navigator.pop(context, language), - ); - } - void _sendMessage(String message) async { if (message.trim().isEmpty) return; final ollamaService = ref.read(ollamaServiceProvider); @@ -97,7 +95,7 @@ class _ChatbotWidgetState extends ConsumerState { setState(() { _messages.add({ 'role': 'bot', - 'message': response.contains("```") ? response : "```$response```" + 'message': response.contains("```") ? response : "```\n$response\n```" }); }); } catch (error) { @@ -116,7 +114,7 @@ class _ChatbotWidgetState extends ConsumerState { final showDebugButton = statusCode != null && statusCode >= 400; return Container( - height: 400, + height: 450, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, @@ -127,36 +125,35 @@ class _ChatbotWidgetState extends ConsumerState { ), child: Column( children: [ - Row( + Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.center, children: [ ElevatedButton.icon( onPressed: () => _sendMessage("Explain API"), icon: const Icon(Icons.info_outline), label: const Text("Explain API"), ), - if (showDebugButton) ...[ - const SizedBox(width: 8), + if (showDebugButton) ElevatedButton.icon( onPressed: () => _sendMessage("Debug API"), icon: const Icon(Icons.bug_report), label: const Text("Debug"), ), - ], - const SizedBox(width: 8), ElevatedButton.icon( onPressed: () => _sendMessage("Generate Test Case"), icon: const Icon(Icons.developer_mode), label: const Text("Test Case"), ), - const SizedBox(width: 8), ElevatedButton.icon( onPressed: _handleCodeGeneration, icon: const Icon(Icons.code), label: const Text("Generate Code"), ), - const Spacer(), ], ), + const SizedBox(height: 12), Expanded( child: ListView.builder( reverse: true, @@ -175,24 +172,31 @@ class _ChatbotWidgetState extends ConsumerState { padding: EdgeInsets.all(8.0), child: CircularProgressIndicator(), ), - Row( - children: [ - Expanded( - child: TextField( - controller: _controller, - decoration: InputDecoration( - hintText: 'Ask something...', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8)), + const SizedBox(height: 10), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Theme.of(context).colorScheme.surfaceVariant, + ), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: TextField( + controller: _controller, + decoration: const InputDecoration( + hintText: 'Ask something...', + border: InputBorder.none, + ), + onSubmitted: _sendMessage, ), - onSubmitted: _sendMessage, ), - ), - IconButton( - icon: const Icon(Icons.send), - onPressed: () => _sendMessage(_controller.text), - ), - ], + IconButton( + icon: const Icon(Icons.send), + onPressed: () => _sendMessage(_controller.text), + ), + ], + ), ), ], ), @@ -211,7 +215,7 @@ class ChatBubble extends StatelessWidget { return Align( alignment: isUser ? Alignment.centerRight : Alignment.centerLeft, child: Container( - margin: const EdgeInsets.symmetric(vertical: 4), + margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isUser