Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.22.0-SNAPSHOT
7.24.0
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The OpenAI REST API. Please see https://platform.openai.com/docs/api-reference f
This Motoko client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.

- API version: 2.3.0
- Generator version: 7.22.0-SNAPSHOT
- Generator version: 7.24.0
- Build package: org.openapitools.codegen.languages.MotokoClientCodegen

## API Subset
Expand Down Expand Up @@ -105,7 +105,6 @@ This package ships a **curated subset** of the upstream OpenAPI surface. Only th
- AuditLogUserDeleted
- AuditLogUserUpdated
- AuditLogUserUpdatedChangesRequested
- AutoChunkingStrategy
- AutoChunkingStrategyRequestParam
- AutoChunkingStrategyRequestParamType
- Batch
Expand Down Expand Up @@ -1108,7 +1107,6 @@ This package ships a **curated subset** of the upstream OpenAPI surface. Only th
- SimpleInputMessage
- StaticChunkingStrategy
- StaticChunkingStrategyRequestParam
- StaticChunkingStrategyResponseParam
- StaticChunkingStrategyStatic
- StaticChunkingStrategyType
- StopConfiguration
Expand Down
508 changes: 176 additions & 332 deletions mops.lock

Large diffs are not rendered by default.

15 changes: 5 additions & 10 deletions mops.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
[toolchain]
moc = "1.4.1"
moc = "1.6.0"

[package]
name = "openai-client"
version = "0.2.5"
version = "0.3.0"
description = "Generated Motoko client for OpenAI API"
repository = "https://github.com/caffeinelabs/openai-client"
repository = "https://github.com/caffeinelabs/skills"
license = "Apache-2.0"
files = ["src/Config.mo", "src/Apis/**/*.mo", "src/Models/**/*.mo"]

[dependencies]
core = "2.4.0"
serde-core = "0.1.4" # ggreif/serde fork: skip_null_fields (NatLabs/serde#44) + Map<K,V> cycle fix + decodeOne/fromCandidWith re-exports + \u-escape & surrogate-pair JSON parser (aviate-labs/json.mo#8) + RFC 8259 §7 string escaping in JSON.fromCandid (root: aviate-labs/json.mo#9)
"cbor@4.1.0" = "4.1.0"
"itertools@0.2.2" = "0.2.2" # because for serde-core
base = "0.16.0" # because serde-core uses json.mo submodule
xtended-numbers = "2.3.0"
"sha2@0.1.6" = "0.1.6"
core = "2.6.0"
serde-core = "0.2.1" # ggreif/serde fork (branch `core`), DE-BASED: skip_null_fields (NatLabs/serde#44) + Map<K,V> cycle fix + \u-escape/surrogate-pair/RFC 8259 §7 JSON escaping. A build depending on it resolves core + sha2 ONLY — no base, no buffer, no second core: 0.2.1 vendors buffer/cbor/xtended-numbers/ByteUtils behind relative imports (verified with a consumer probe). base is dev-only upstream. Supersedes 0.2.0, whose residual base@0.16 came via buffer@0.1.0 (edjCase/motoko_buffer#1, still unanswered).
116 changes: 48 additions & 68 deletions src/Apis/AudioApi.mo

Large diffs are not rendered by default.

226 changes: 125 additions & 101 deletions src/Apis/ChatApi.mo

Large diffs are not rendered by default.

66 changes: 20 additions & 46 deletions src/Apis/CompletionsApi.mo
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,30 @@ import Array "mo:core/Array";
import List "mo:core/List";
import Error "mo:core/Error";
import Base64 "mo:core/Base64";
import Char "mo:core/Char";
import Nat8 "mo:core/Nat8";
import Nat32 "mo:core/Nat32";
import { JSON; Candid } "mo:serde-core";
import { type CreateCompletionRequest; JSON = CreateCompletionRequest } "../Models/CreateCompletionRequest";
import { type CreateCompletionResponse; JSON = CreateCompletionResponse } "../Models/CreateCompletionResponse";
import { type Config } "../Config";
import { type Config; _Helpers; _Ic } "../Config";

module {
// Management Canister interface for HTTP outcalls
// Based on https://github.com/dfinity/interface-spec/blob/master/spec/ic.did
type http_header = {
name : Text;
value : Text;
};

type http_method = {
#get;
#head;
#post;
#put; // Non-replicated only (is_replicated forced to ?false in generated code)
#delete; // Non-replicated only (is_replicated forced to ?false in generated code)
};

type http_request_args = {
url : Text;
max_response_bytes : ?Nat64;
method : http_method;
headers : [http_header];
body : ?Blob;
transform : ?{
function : shared query ({ response : http_request_result; context : Blob }) -> async http_request_result;
context : Blob;
};
is_replicated : ?Bool;
};

type http_request_result = {
status : Nat;
headers : [http_header];
body : Blob;
};

let http_request = (actor "aaaaa-aa" : actor { http_request : (http_request_args) -> async http_request_result }).http_request;

// mo:core/Base64 provides `decode` (caffeinelabs/motoko-core#507); alias it
// instead of inlining. `_`-prefixed so it never triggers an unused-identifier
// warning in modules that import Base64 only for encoding.
let _decode = Base64.decode;

/// Creates a completion for the provided prompt and parameters.
public func createCompletion(config : Config, createCompletionRequest : CreateCompletionRequest) : async* CreateCompletionResponse {
// x-server-override (set by spec-merge per input) pins this
// operation to the right host for multi-spec merged clients;
// when absent we use config.baseUrl as before.
let {baseUrl; cycles} = config;
let baseUrl__ = baseUrl # "/completions";

// Add API key as query parameter if using apiKey auth
let url = switch (config.auth) {
let url__ = switch (config.auth) {
case _ baseUrl__;
};

Expand All @@ -82,13 +56,13 @@ module {
case null [];
};

let headers = Array.flatten<http_header>([
let headers = Array.flatten<_Ic.HttpHeader>([
baseHeaders,
authHeaders
]);

let request : http_request_args = { config with
url;
let request : _Ic.HttpRequestArgs = { config with
url = url__;
method = #post;
headers;
body = do ? {
Expand All @@ -100,22 +74,22 @@ module {
};

// Call the management canister's http_request method with cycles
let response : http_request_result = await (with cycles) http_request(request);
let response : _Ic.HttpRequestResult = await (with cycles) _Ic.http_request(request);

// Check HTTP status code before parsing
if (response.status >= 200 and response.status < 300) {
// Success response (2xx): parse as expected return type
(switch (Text.decodeUtf8(response.body)) {
case (?text) text;
case null throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to decode response body as UTF-8");
case null throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to decode response body as UTF-8"));
}) |>
(switch (JSON.toCandid(_)) {
case (#ok(c__)) c__;
case (#err(msg)) throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to parse JSON: " # msg);
case (#err(msg)) throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to parse JSON: ") # msg);
}) |>
(switch (CreateCompletionResponse.fromCandidValue(_)) {
case (?value) value;
case null throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to convert response to CreateCompletionResponse");
case null throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to convert response to CreateCompletionResponse"));
})
} else {
// Error response (4xx, 5xx): parse error models and throw
Expand All @@ -126,7 +100,7 @@ module {


// Fallback for status codes not defined in OpenAPI spec
throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Unexpected error" #
throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Unexpected error") #
(if (responseText != "") { " - " # responseText } else { "" }));
}
};
Expand Down
66 changes: 20 additions & 46 deletions src/Apis/EmbeddingsApi.mo
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,30 @@ import Array "mo:core/Array";
import List "mo:core/List";
import Error "mo:core/Error";
import Base64 "mo:core/Base64";
import Char "mo:core/Char";
import Nat8 "mo:core/Nat8";
import Nat32 "mo:core/Nat32";
import { JSON; Candid } "mo:serde-core";
import { type CreateEmbeddingRequest; JSON = CreateEmbeddingRequest } "../Models/CreateEmbeddingRequest";
import { type CreateEmbeddingResponse; JSON = CreateEmbeddingResponse } "../Models/CreateEmbeddingResponse";
import { type Config } "../Config";
import { type Config; _Helpers; _Ic } "../Config";

module {
// Management Canister interface for HTTP outcalls
// Based on https://github.com/dfinity/interface-spec/blob/master/spec/ic.did
type http_header = {
name : Text;
value : Text;
};

type http_method = {
#get;
#head;
#post;
#put; // Non-replicated only (is_replicated forced to ?false in generated code)
#delete; // Non-replicated only (is_replicated forced to ?false in generated code)
};

type http_request_args = {
url : Text;
max_response_bytes : ?Nat64;
method : http_method;
headers : [http_header];
body : ?Blob;
transform : ?{
function : shared query ({ response : http_request_result; context : Blob }) -> async http_request_result;
context : Blob;
};
is_replicated : ?Bool;
};

type http_request_result = {
status : Nat;
headers : [http_header];
body : Blob;
};

let http_request = (actor "aaaaa-aa" : actor { http_request : (http_request_args) -> async http_request_result }).http_request;

// mo:core/Base64 provides `decode` (caffeinelabs/motoko-core#507); alias it
// instead of inlining. `_`-prefixed so it never triggers an unused-identifier
// warning in modules that import Base64 only for encoding.
let _decode = Base64.decode;

/// Creates an embedding vector representing the input text.
public func createEmbedding(config : Config, createEmbeddingRequest : CreateEmbeddingRequest) : async* CreateEmbeddingResponse {
// x-server-override (set by spec-merge per input) pins this
// operation to the right host for multi-spec merged clients;
// when absent we use config.baseUrl as before.
let {baseUrl; cycles} = config;
let baseUrl__ = baseUrl # "/embeddings";

// Add API key as query parameter if using apiKey auth
let url = switch (config.auth) {
let url__ = switch (config.auth) {
case _ baseUrl__;
};

Expand All @@ -82,13 +56,13 @@ module {
case null [];
};

let headers = Array.flatten<http_header>([
let headers = Array.flatten<_Ic.HttpHeader>([
baseHeaders,
authHeaders
]);

let request : http_request_args = { config with
url;
let request : _Ic.HttpRequestArgs = { config with
url = url__;
method = #post;
headers;
body = do ? {
Expand All @@ -100,22 +74,22 @@ module {
};

// Call the management canister's http_request method with cycles
let response : http_request_result = await (with cycles) http_request(request);
let response : _Ic.HttpRequestResult = await (with cycles) _Ic.http_request(request);

// Check HTTP status code before parsing
if (response.status >= 200 and response.status < 300) {
// Success response (2xx): parse as expected return type
(switch (Text.decodeUtf8(response.body)) {
case (?text) text;
case null throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to decode response body as UTF-8");
case null throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to decode response body as UTF-8"));
}) |>
(switch (JSON.toCandid(_)) {
case (#ok(c__)) c__;
case (#err(msg)) throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to parse JSON: " # msg);
case (#err(msg)) throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to parse JSON: ") # msg);
}) |>
(switch (CreateEmbeddingResponse.fromCandidValue(_)) {
case (?value) value;
case null throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Failed to convert response to CreateEmbeddingResponse");
case null throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Failed to convert response to CreateEmbeddingResponse"));
})
} else {
// Error response (4xx, 5xx): parse error models and throw
Expand All @@ -126,7 +100,7 @@ module {


// Fallback for status codes not defined in OpenAPI spec
throw Error.reject("HTTP " # Int.toText(response.status) # " body[" # Nat.toText(response.body.size()) # "B]=" # (switch (Text.decodeUtf8(response.body)) { case (?t) (if (t.size() > 100) Text.fromIter(Iter.take<Char>(t.chars(), 100)) # "..." else t); case null "(undecodable)" }) # ": Unexpected error" #
throw Error.reject(_Helpers.rejectMessage(response.status, response.body, "Unexpected error") #
(if (responseText != "") { " - " # responseText } else { "" }));
}
};
Expand Down
Loading