1
1
import 'dart:convert' ;
2
+ import 'package:openapi_spec/openapi_spec.dart' ;
2
3
import 'package:apidash/dashbot/features/chat/models/chat_message.dart' ;
3
4
import 'package:apidash_core/apidash_core.dart' ;
4
5
import 'package:flutter/foundation.dart' ;
@@ -38,9 +39,7 @@ class ChatViewmodel extends StateNotifier<ChatState> {
38
39
39
40
List <ChatMessage > get currentMessages {
40
41
final id = _currentRequest? .id ?? 'global' ;
41
- debugPrint ('[Chat] Getting messages for request ID: $id ' );
42
42
final messages = state.chatSessions[id] ?? const [];
43
- debugPrint ('[Chat] Found ${messages .length } messages' );
44
43
return messages;
45
44
}
46
45
@@ -49,8 +48,6 @@ class ChatViewmodel extends StateNotifier<ChatState> {
49
48
ChatMessageType type = ChatMessageType .general,
50
49
bool countAsUser = true ,
51
50
}) async {
52
- debugPrint (
53
- '[Chat] sendMessage start: type=$type , countAsUser=$countAsUser ' );
54
51
final ai = _selectedAIModel;
55
52
if (text.trim ().isEmpty && countAsUser) return ;
56
53
if (ai == null &&
@@ -66,7 +63,6 @@ class ChatViewmodel extends StateNotifier<ChatState> {
66
63
67
64
final requestId = _currentRequest? .id ?? 'global' ;
68
65
final existingMessages = state.chatSessions[requestId] ?? const [];
69
- debugPrint ('[Chat] using requestId=$requestId ' );
70
66
71
67
if (countAsUser) {
72
68
_addMessage (
@@ -211,8 +207,6 @@ class ChatViewmodel extends StateNotifier<ChatState> {
211
207
userPrompt: userPrompt,
212
208
stream: false ,
213
209
);
214
- debugPrint (
215
- '[Chat] prompts prepared: system=${systemPrompt .length } chars, user=${userPrompt .length } chars' );
216
210
217
211
state = state.copyWith (isGenerating: true , currentStreamingResponse: '' );
218
212
try {
@@ -297,17 +291,20 @@ class ChatViewmodel extends StateNotifier<ChatState> {
297
291
298
292
Future <void > applyAutoFix (ChatAction action) async {
299
293
try {
294
+ if (action.actionType == ChatActionType .applyOpenApi) {
295
+ await _applyOpenApi (action);
296
+ return ;
297
+ }
298
+ if (action.actionType == ChatActionType .applyCurl) {
299
+ await _applyCurl (action);
300
+ return ;
301
+ }
302
+
300
303
final msg = await _ref.read (autoFixServiceProvider).apply (action);
301
304
if (msg != null && msg.isNotEmpty) {
302
- // Message type depends on action context; choose sensible defaults
303
- final t = (action.actionType == ChatActionType .applyCurl)
304
- ? ChatMessageType .importCurl
305
- : (action.actionType == ChatActionType .applyOpenApi)
306
- ? ChatMessageType .importOpenApi
307
- : ChatMessageType .general;
305
+ final t = ChatMessageType .general;
308
306
_appendSystem (msg, t);
309
307
}
310
- // Only target-specific 'other' actions remain here
311
308
if (action.actionType == ChatActionType .other) {
312
309
await _applyOtherAction (action);
313
310
}
@@ -344,7 +341,6 @@ class ChatViewmodel extends StateNotifier<ChatState> {
344
341
}
345
342
346
343
Future <void > _applyOpenApi (ChatAction action) async {
347
- final requestId = _currentRequest? .id;
348
344
final collection = _ref.read (collectionStateNotifierProvider.notifier);
349
345
final payload = action.value is Map <String , dynamic >
350
346
? (action.value as Map <String , dynamic >)
@@ -413,28 +409,26 @@ class ChatViewmodel extends StateNotifier<ChatState> {
413
409
}
414
410
}
415
411
416
- final withEnvUrl = await _maybeSubstituteBaseUrl (url, baseUrl);
417
- if (action.field == 'apply_to_selected' ) {
418
- if (requestId == null ) return ;
419
- final replacingBody =
420
- (formFlag || formData.isNotEmpty) ? '' : (body ?? '' );
421
- final replacingFormData =
422
- formData.isEmpty ? const < FormDataModel > [] : formData;
423
- collection.update (
424
- method: method,
425
- url: withEnvUrl,
426
- headers: headers,
427
- isHeaderEnabledList: List <bool >.filled (headers.length, true ),
428
- body: replacingBody,
429
- bodyContentType: bodyContentType,
430
- formData: replacingFormData,
431
- params: const [],
432
- isParamEnabledList: const [],
433
- authModel: null ,
434
- );
435
- _appendSystem ('Applied OpenAPI operation to the selected request.' ,
436
- ChatMessageType .importOpenApi);
437
- } else if (action.field == 'apply_to_new' ) {
412
+
413
+ String sourceTitle = (payload['sourceName' ] as String ? ) ?? '' ;
414
+ if (sourceTitle.trim ().isEmpty) {
415
+ final specObj = payload['spec' ];
416
+ if (specObj is OpenApi ) {
417
+ try {
418
+ final t = specObj.info.title.trim ();
419
+ if (t.isNotEmpty) sourceTitle = t;
420
+ } catch (_) {}
421
+ }
422
+ }
423
+ debugPrint ('[OpenAPI] baseUrl="$baseUrl " title="$sourceTitle " url="$url "' );
424
+ final withEnvUrl = await _maybeSubstituteBaseUrlForOpenApi (
425
+ url,
426
+ baseUrl,
427
+ sourceTitle,
428
+ );
429
+ debugPrint ('[OpenAPI] withEnvUrl="$withEnvUrl ' );
430
+ if (action.field == 'apply_to_new' ) {
431
+ debugPrint ('[OpenAPI] withEnvUrl="$withEnvUrl ' );
438
432
final model = HttpRequestModel (
439
433
method: method,
440
434
url: withEnvUrl,
@@ -936,17 +930,13 @@ class ChatViewmodel extends StateNotifier<ChatState> {
936
930
937
931
// Helpers
938
932
void _addMessage (String requestId, ChatMessage m) {
939
- debugPrint (
940
- '[Chat] Adding message to request ID: $requestId , actions: ${m .actions ?.map ((e ) => e .toJson ()).toList ()}' );
941
933
final msgs = state.chatSessions[requestId] ?? const [];
942
934
state = state.copyWith (
943
935
chatSessions: {
944
936
...state.chatSessions,
945
937
requestId: [...msgs, m],
946
938
},
947
939
);
948
- debugPrint (
949
- '[Chat] Message added, total messages for $requestId : ${(state .chatSessions [requestId ]?.length ?? 0 )}' );
950
940
}
951
941
952
942
void _appendSystem (String text, ChatMessageType type) {
@@ -1004,6 +994,24 @@ class ChatViewmodel extends StateNotifier<ChatState> {
1004
994
);
1005
995
}
1006
996
997
+ Future <String > _maybeSubstituteBaseUrlForOpenApi (
998
+ String url, String baseUrl, String title) async {
999
+ final svc = _ref.read (urlEnvServiceProvider);
1000
+ return svc.maybeSubstituteBaseUrl (
1001
+ url,
1002
+ baseUrl,
1003
+ ensure: (b) => svc.ensureBaseUrlEnvForOpenApi (
1004
+ b,
1005
+ title: title,
1006
+ readEnvs: () => _ref.read (environmentsStateNotifierProvider),
1007
+ readActiveEnvId: () => _ref.read (activeEnvironmentIdStateProvider),
1008
+ updateEnv: (id, {values}) => _ref
1009
+ .read (environmentsStateNotifierProvider.notifier)
1010
+ .updateEnvironment (id, values: values),
1011
+ ),
1012
+ );
1013
+ }
1014
+
1007
1015
HttpRequestModel _getSubstitutedHttpRequestModel (
1008
1016
HttpRequestModel httpRequestModel) {
1009
1017
final envMap = _ref.read (availableEnvironmentVariablesStateProvider);
0 commit comments