* feat: wa working full stack * feat: writing assistance made anew * docs: migrate copilot docs to .github/instructions/ format - Create choreographer.instructions.md (applyTo: lib/pangea/choreographer/**) - Create events-and-tokens.instructions.md (applyTo: lib/pangea/events/**,lib/pangea/extensions/**) - Create modules.instructions.md (applyTo: lib/pangea/**) — full module map - Track copilot-instructions.md (remove .gitignore rule) - Add documentation reference table to copilot-instructions.md Content sourced from docs/copilot/ on writing-assistance branch. * docs: remove old docs/copilot/ (migrated to .github/instructions/) * docs: update choreographer + modules docs for writing-assistance audit - Mark IT (Interactive Translation) as deprecated throughout - Document new ReplacementTypeEnum taxonomy (grammar, surface, word-choice categories) - Add AssistanceStateEnum, AutocorrectPopup, feedback rerun flow - Mark SpanDataRepo/span_details as dead code - Mark SpanChoiceTypeEnum.bestCorrection/bestAnswer as deprecated - Add new files to modules listing (autocorrect_popup, start_igc_button, etc.) - Update API endpoints table with active/deprecated/dead status * formatting, replace deprecated withOpacity calls * fix linter issues from deprecated types * use better error color * move cloing of overlays into choreographer * reduce duplicate code on igc_controller, update UI on feedback * couple of adjustments * display prompt in span card by type * fix error in tests * translations * simplify span card feedback --------- Co-authored-by: ggurdin <ggurdin@gmail.com>
97 lines
2.3 KiB
Dart
97 lines
2.3 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
|
|
import 'package:fluffychat/pangea/common/models/base_request_model.dart';
|
|
|
|
class Requests {
|
|
late String? accessToken;
|
|
late String? choreoApiKey;
|
|
|
|
Requests({
|
|
this.accessToken,
|
|
this.choreoApiKey,
|
|
});
|
|
|
|
Future<http.Response> post({
|
|
required String url,
|
|
required Map<dynamic, dynamic> body,
|
|
}) async {
|
|
final enrichedBody = BaseRequestModel.injectUserContext(body);
|
|
|
|
dynamic encoded;
|
|
encoded = jsonEncode(enrichedBody);
|
|
|
|
final http.Response response = await http.post(
|
|
Uri.parse(url),
|
|
body: encoded,
|
|
headers: _headers,
|
|
);
|
|
|
|
handleError(response, body: body);
|
|
return response;
|
|
}
|
|
|
|
Future<http.Response> get({required String url}) async {
|
|
final http.Response response =
|
|
await http.get(Uri.parse(url), headers: _headers);
|
|
|
|
handleError(response);
|
|
return response;
|
|
}
|
|
|
|
void addBreadcrumb(
|
|
http.Response response, {
|
|
Map<dynamic, dynamic>? body,
|
|
}) {
|
|
debugPrint("Error - code: ${response.statusCode}");
|
|
debugPrint("api: ${response.request?.url}");
|
|
debugPrint("request body: $body");
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb.http(
|
|
url: response.request?.url ?? Uri(path: "not available"),
|
|
method: response.request?.method ?? "not available",
|
|
statusCode: response.statusCode,
|
|
),
|
|
);
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb(data: {"body": body}),
|
|
);
|
|
}
|
|
|
|
void handleError(
|
|
http.Response response, {
|
|
Map<dynamic, dynamic>? body,
|
|
}) {
|
|
if (response.statusCode == 401) {
|
|
final responseBody = jsonDecode(utf8.decode(response.bodyBytes));
|
|
if (responseBody['detail'] == 'No active subscription found') {
|
|
throw UnsubscribedException();
|
|
}
|
|
}
|
|
|
|
if (response.statusCode >= 400) {
|
|
addBreadcrumb(response, body: body);
|
|
throw response;
|
|
}
|
|
}
|
|
|
|
get _headers {
|
|
final Map<String, String> headers = {
|
|
"Content-Type": "application/json",
|
|
"Accept": "application/json",
|
|
};
|
|
if (accessToken != null) {
|
|
headers["Authorization"] = 'Bearer ${accessToken!}';
|
|
}
|
|
if (choreoApiKey != null) {
|
|
headers['api_key'] = choreoApiKey!;
|
|
}
|
|
return headers;
|
|
}
|
|
}
|
|
|
|
class UnsubscribedException implements Exception {}
|