I've followed the official video on how they implemented custom streaming from Openai and been failing (like many it seems) to get it working - specially since the Flutterflow team provides a video and doesn't release the bloody working template.
I've been doing some forum searching, and found someone that implemented it with the Dio package
My setup is: From flutterflow, i connect to my backend running Langchain and FastAPI and I have endpoints to start streaming chat.
Here is my code. I added dependy as instructed: dio: ^5.3.3
All i get is this annoying generic error in the compiler that doens't tell me whats wrong.
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'dart:convert';
import 'package:dio/dio.dart';
Dio _dio = Dio();
class ChatbotResponse {
final String content;
final bool finalAnswer;
final String role;
ChatbotResponse({
required this.content,
required this.finalAnswer,
required this.role,
});
factory ChatbotResponse.fromJson(Map<String, dynamic> json) {
return ChatbotResponse(
content: json['content'],
finalAnswer: json['final_answer'] ?? false,
role: json['role'],
);
}
Map<String, dynamic> toJson() {
return {
'content': content,
'final_answer': finalAnswer,
'role': role,
};
}
}
final url = '.../start_chat';
final headers = {
"Content-Type": "application/json",
"Authorization": "Bearer ${FFAppState().jwt}",
};
String body = getApiBody(jsonBody);
// Create request
_dio.options.headers = headers;
_dio.options.responseType = ResponseType.stream;
final Response<ResponseBody> response = await _dio.post(
url,
data: body,
);
// Before streaming response, add an empty ChatResponse object to chatHistory
FFAppState().addToChatHistory(ChatResponseStruct(
author: "assistant",
content: "",
));
void addToChatHistory(String data, CallbackAction) {
if (data.contains("content")) {
ChatbotResponse contentResponse = ChatbotResponse.fromJson(jsonDecode(data));
String content = contentResponse.content;
FFAppState().updateChatHistoryAtIndex(
FFAppState().chatHistory.length - 1,
(e) {
e.content = "${e.content}$content";
return e;
},
);
// setState and scroll to last item in list
CallbackAction();
}
}
// Stream response
if (response.data != null) {
response.data!.stream.listen((List<int> value) {
var str = utf8.decode(value);
// Process the results or add it to UI
if (str.contains("data:")) {
String data = str.split("data:")[1];
addToChatHistory(data, CallbackAction);
}
});
}
}