Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add types and functionality to pass through api-information about usage etc. from OpenAI #80

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion examples/sentiment/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ processRequests("😀> ", process.argv[2], async (request) => {
console.log(response.message);
return;
}
console.log(`The sentiment is ${response.data.sentiment}`);

console.log(`The sentiment is ${response.data.sentiment}. The request used ${response.api?.usage.total_tokens ?? -1} tokens.`);
});
9 changes: 7 additions & 2 deletions src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,14 @@ function createAxiosLanguageModel(url: string, config: object, defaultParams: Re
temperature: 0,
n: 1
};
const result = await client.post(url, params, { validateStatus: status => true });
const result = await client.post(url, params, {
validateStatus: (_status) => true
});

const { choices, ...apiData } = result.data;

if (result.status === 200) {
return success(result.data.choices[0].message?.content ?? "");
return success(result.data.choices[0].message?.content ?? "", apiData);
}
if (!isTransientHttpError(result.status) || retryCount >= retryMaxAttempts) {
return error(`REST API error ${result.status}: ${result.statusText}`);
Expand Down
29 changes: 25 additions & 4 deletions src/result.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
/**
* An object representing a successful operation with a result of type `T`.
*/
export type Success<T> = { success: true, data: T };
export type Success<T> = {
success: true;
data: T;
api?: OpenAiInfo;
};

/**
* An object representing an operation that failed for the reason given in `message`.
*/
export type Error = { success: false, message: string };
export type Error = { success: false; message: string };

/**
* An object representing a successful or failed operation of type `T`.
*/
export type Result<T> = Success<T> | Error;

/**
* An object containing the information returned by the OpenAI-Api. It contains
* information on the tokens used, the model used, a timestamp, and the specific
* id the prompt has in the backend.
*/
export type OpenAiInfo = {
id: string;
object: string;
created: number;
model: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
};

/**
* Returns a `Success<T>` object.
* @param data The value for the `data` property of the result.
* @returns A `Success<T>` object.
*/
export function success<T>(data: T): Success<T> {
return { success: true, data };
export function success<T>(data: T, info?: OpenAiInfo): Success<T> {
return info ? { success: true, data, api: info } : { success: true, data };
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/typechat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ export function createJsonTranslator<T extends object>(model: TypeChatLanguageMo
if (!response.success) {
return response;
}
const responseText = response.data;

const { api, data: responseText } = response;

const startIndex = responseText.indexOf("{");
const endIndex = responseText.lastIndexOf("}");
if (!(startIndex >= 0 && endIndex > startIndex)) {
Expand All @@ -106,7 +108,7 @@ export function createJsonTranslator<T extends object>(model: TypeChatLanguageMo
const jsonText = responseText.slice(startIndex, endIndex + 1);
const validation = validator.validate(jsonText);
if (validation.success) {
return validation;
return api ? { ...validation, api } : validation;
}
if (!attemptRepair) {
return error(`JSON validation failed: ${validation.message}\n${jsonText}`);
Expand Down