Skip to content

Commit

Permalink
Feat/assistant beta (#22)
Browse files Browse the repository at this point in the history
* feat: Introduce Thread model and createThread API method

* feat: Introduce addThreadMessage method

* feat: Add the rest of the models and calls for Assistant Thread API

* refactor: Rename Trascription to TraNscription

* feat: Add documentation

* chore: Update CHANGELOG.md
  • Loading branch information
Defuera authored Nov 27, 2023
1 parent 3690c48 commit fa9e47d
Show file tree
Hide file tree
Showing 20 changed files with 3,915 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 0.3.6

- Introduce Assistant API https://platform.openai.com/docs/assistants/overview

## 0.3.0

- Support GPT4 version
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ APIs have been supported by this library. Update to support latest models. Now y
- Audio Transcription

```dart
final result = await client.createTrascription(
final result = await client.createTranscription(
TranscriptionRequest(
file: 'assets/ttsmaker-file-2023-3-22-14-57-0.mp3',
),
Expand Down
1 change: 1 addition & 0 deletions lib/openai_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export 'src/image/image_variation.dart';
export 'src/model.dart';
export 'package:cancellation_token_http/http.dart'
show CancellationToken, CancelledException, TimeoutCancellationToken;
export 'src/thread/exports.dart';
31 changes: 22 additions & 9 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const dataPrefix = "data: ";
class OpenaiClient {
late OpenaiConfig _config;
late http.Client _client;

OpenaiClient({
required OpenaiConfig config,
http.Client? httpClient,
Expand All @@ -19,13 +20,15 @@ class OpenaiClient {
}

OpenaiConfig get config => _config;

http.Client get client => _client;

Future<dynamic> sendFormRequest(
http.MultipartRequest request, {
bool isBeta = false,
http.CancellationToken? cancellationToken,
}) async {
request.headers.addAll(_authenticateHeaders());
request.headers.addAll(_authenticateHeaders(isBeta));
final response = await http.Response.fromStream(await client.send(
request,
cancellationToken: cancellationToken,
Expand All @@ -37,19 +40,26 @@ class OpenaiClient {
Future<dynamic> sendRequest(
String endpoint,
dynamic body, {
bool isBeta = false,
http.CancellationToken? cancellationToken,
}) async {
return jsonDecode(utf8.decode(await sendRequestRaw(endpoint, body)));
return jsonDecode(utf8.decode(await sendRequestRaw(
endpoint,
body,
isBeta: isBeta,
cancellationToken: cancellationToken,
)));
}

Future<dynamic> sendRequestRaw(
String endpoint,
dynamic body, {
bool isBeta = false,
http.CancellationToken? cancellationToken,
}) async {
final response = await client.post(
Uri.parse("${config.baseUrl}/$endpoint"),
headers: _authenticateHeaders()..addAll(kJsonTypeHeader),
headers: _authenticateHeaders(isBeta)..addAll(kJsonTypeHeader),
body: jsonEncode(body),
cancellationToken: cancellationToken,
);
Expand All @@ -59,11 +69,12 @@ class OpenaiClient {

Future<dynamic> get(
String endpoint, {
bool isBeta = false,
http.CancellationToken? cancellationToken,
}) async {
final response = await client.get(
Uri.parse("${config.baseUrl}/$endpoint"),
headers: _authenticateHeaders(),
headers: _authenticateHeaders(isBeta),
cancellationToken: cancellationToken,
);
handleException(response);
Expand All @@ -73,14 +84,15 @@ class OpenaiClient {
Future sendStreamRequest(
String endpoint,
dynamic body, {
bool isBeta = false,
Function(dynamic)? onSuccess,
http.CancellationToken? cancellationToken,
}) async {
var request = http.Request(
'POST',
Uri.parse("${config.baseUrl}/$endpoint"),
);
request.headers.addAll(_authenticateHeaders());
request.headers.addAll(_authenticateHeaders(isBeta));
request.headers.addAll(kJsonTypeHeader);

if (body != null) {
Expand Down Expand Up @@ -133,9 +145,10 @@ class OpenaiClient {
});
}

Map<String, String> _authenticateHeaders() {
Map<String, String> _authenticateHeaders(bool isBeta) {
return {
'Authorization': 'Bearer ${config.apiKey}',
if (isBeta) 'OpenAI-Beta': 'assistants=v1',
};
}

Expand All @@ -159,9 +172,9 @@ class OpenaiClient {

/// receive a valid http status code but invalid error object
throw OpenaiException(
code: response.statusCode,
error:
OpenaiError(message: "unkown http error", type: "unkown_type"));
code: response.statusCode,
error: OpenaiError(message: "unkown http error", type: "unkown_type"),
);
} on FormatException catch (e) {
// server returns invalid json oject
throw OpenaiException(
Expand Down
5 changes: 5 additions & 0 deletions lib/src/thread/exports.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export './thread.dart';
export './thread_message.dart';
export './thread_run.dart';
export './thread_run_step.dart';
export './thread_requests.dart';
28 changes: 28 additions & 0 deletions lib/src/thread/thread.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'thread.freezed.dart';

part 'thread.g.dart';

/// Represents a thread that contains messages.
/// https://platform.openai.com/docs/api-reference/threads
@freezed
class Thread with _$Thread {
factory Thread({
/// The identifier, which can be referenced in API endpoints.
required String id,

/// The object type, which is always thread.
@Default('thread') String object,

/// The Unix timestamp (in seconds) for when the thread was created.
required int createdAt,

/// Set of 16 key-value pairs that can be attached to an object. This can be useful
/// for storing additional information about the object in a structured format.
/// Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long.
@Default(<String, dynamic>{}) Map<String, dynamic> metadata,
}) = _Thread;

factory Thread.fromJson(Map<String, dynamic> json) => _$ThreadFromJson(json);
}
Loading

0 comments on commit fa9e47d

Please sign in to comment.