Browse Source

Implement example CLI app

Use basic chat implementation.
master
TheoryOfNekomata 1 year ago
parent
commit
6a6c4b7a50
5 changed files with 96 additions and 77 deletions
  1. +17
    -0
      examples/cli/package.json
  2. +5
    -5
      examples/cli/src/app.ts
  3. +69
    -69
      examples/cli/src/index.ts
  4. +3
    -3
      package.json
  5. +2
    -0
      src/platforms/openai/index.ts

+ 17
- 0
examples/cli/package.json View File

@@ -53,5 +53,22 @@
"esbuild-plugin-wasm": "^1.0.0", "esbuild-plugin-wasm": "^1.0.0",
"inquirer": "^9.1.5", "inquirer": "^9.1.5",
"yargs": "^17.7.1" "yargs": "^17.7.1"
},
"types": "./dist/types/index.d.ts",
"main": "./dist/cjs/production/index.js",
"module": "./dist/esm/production/index.js",
"exports": {
".": {
"development": {
"require": "./dist/cjs/development/index.js",
"import": "./dist/esm/development/index.js"
},
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"typesVersions": {
"*": {}
} }
} }

+ 5
- 5
examples/cli/src/app.ts View File

@@ -1,4 +1,4 @@
import { createAiClient, OpenAi } from '@modal-sh/mio-ai';
import { OpenAi, createAiClient } from '@modal-sh/mio-ai';


export interface CreateOpenAiClientParams { export interface CreateOpenAiClientParams {
apiKey: string; apiKey: string;
@@ -6,13 +6,13 @@ export interface CreateOpenAiClientParams {
apiVersion?: OpenAi.ApiVersion; apiVersion?: OpenAi.ApiVersion;
} }


export const createOpenAiClient = (params: CreateOpenAiClientParams) => {
return createAiClient({
export const createOpenAiClient = (params: CreateOpenAiClientParams) => (
createAiClient({
platform: OpenAi.PLATFORM_ID, platform: OpenAi.PLATFORM_ID,
platformConfiguration: { platformConfiguration: {
apiKey: params.apiKey, apiKey: params.apiKey,
organizationId: params.organizationId, organizationId: params.organizationId,
apiVersion: params.apiVersion ?? OpenAi.ApiVersion.V1, apiVersion: params.apiVersion ?? OpenAi.ApiVersion.V1,
}, },
});
};
})
);

+ 69
- 69
examples/cli/src/index.ts View File

@@ -1,90 +1,90 @@
import yargs from 'yargs'; import yargs from 'yargs';
import { hideBin } from 'yargs/helpers'; import { hideBin } from 'yargs/helpers';
import inquirer from 'inquirer';
import { createOpenAiClient } from './app'; import { createOpenAiClient } from './app';
import { OpenAi } from '@modal-sh/mio-ai';
import { OpenAi, PlatformEventEmitter } from '@modal-sh/mio-ai';


export type Argv = Record<string, unknown>; export type Argv = Record<string, unknown>;


const main = (argv: Argv) => new Promise<number>((resolve) => {
const aiClient = createOpenAiClient({
apiKey: process.env.OPENAI_API_KEY as string,
organizationId: process.env.OPENAI_ORGANIZATION_ID as string,
apiVersion: OpenAi.ApiVersion.V1,
});
let result: Partial<OpenAi.ChatCompletion> | undefined;
let done = false;

const receiveData = (aiClient: PlatformEventEmitter, theContent: string, argv: Record<string, unknown>) => new Promise<void>((r2, rj) => {
let countTokens: number;
aiClient.on<OpenAi.ChatCompletionChunkDataEvent>('data', (d) => { aiClient.on<OpenAi.ChatCompletionChunkDataEvent>('data', (d) => {
d.choices.forEach((c) => {
if (!result) {
result = {
id: d.id,
object: OpenAi.ChatCompletionDataEventObjectType.CHAT_COMPLETION,
created: d.created,
model: d.model,
};
}

if (!Array.isArray(result?.choices)) {
result.choices = [];
}

if (!result.choices[c.index]) {
result.choices[c.index] = {
message: { content: '' },
index: c.index,
finish_reason: c.finish_reason,
};
}

if (result.choices[c.index].message) {
if (c.delta.role) {
(result.choices[c.index].message as Record<string, unknown>).role = c.delta.role;
}

if (c.delta.content) {
(result.choices[c.index].message as Record<string, unknown>)
.content += c.delta.content;
}
}
if (d.choices?.[0]?.delta?.role) {
process.stdout.write(`${d.choices[0].delta.role}: `);
}


if (c.finish_reason) {
result.choices[c.index].finish_reason = c.finish_reason;
}
});
if (d.choices?.[0]?.delta?.content) {
countTokens += 1;
process.stdout.write(d.choices[0].delta.content);
}
}); });


aiClient.on('end', () => { aiClient.on('end', () => {
// resolve?.(result);
process.stdout.write('\n\n');
process.stdout.write(`info: ${countTokens} completion tokens.\n\n`);
// TODO count tokens
r2();
}); });


aiClient.on('error', (error: Error) => { aiClient.on('error', (error: Error) => {
done = true;
resolve(-1);
process.stderr.write(error.message);
process.stderr.write('\n');
rj(error);
});

countTokens = 0;
aiClient.createChatCompletion({
model: OpenAi.ChatCompletionModel.GPT_3_5_TURBO,
messages: theContent,
temperature: argv.temperature as number,
maxTokens: argv.maxTokens as number,
topP: argv.topP as number,
}); });
});

const main = (argv: Argv) => new Promise<number>(async (resolve) => {
let done = false;
let resolveResult = 0;


inquirer.prompt([
{
type: 'input',
message: 'Type your inquiry.',
},
])
.then((answers) => {
console.log(answers);
// aiClient.createChatCompletion({
// model: OpenAi.ChatCompletionModel.GPT_3_5_TURBO,
// messages: {
// role: OpenAi.MessageRole.USER,
// content: answers[0] as string,
// },
// });
})
.catch(() => {
resolve(-1);
process.stdout.write('Welcome to mio-ai CLI!\n\n');

process.stdout.write('This is a simple example of how to use mio-ai.\n');
process.stdout.write('You can send messages to the OpenAI API.\n');
process.stdout.write('You can also send empty messages to exit.\n');
process.stdout.write('Alternatively, you can press Ctrl+C anytime to exit.\n\n');
do {
process.stdout.write('---\n\n');
const aiClient = createOpenAiClient({
apiKey: process.env.OPENAI_API_KEY as string,
organizationId: process.env.OPENAI_ORGANIZATION_ID as string,
apiVersion: OpenAi.ApiVersion.V1,
}); });
const { createPromptModule } = await import('inquirer');
const prompt = createPromptModule();
let content: string;
try {
const answers = await prompt([
{
type: 'input',
name: 'content',
prefix: '',
message: `${OpenAi.MessageRole.USER}:`,
},
]);
content = answers.content;
if (content.trim().length < 1) {
done = true;
break;
}
process.stdout.write('\n');
await receiveData(aiClient, content, argv);
} catch {
resolveResult = -1;
done = true;
}
} while (!done);


resolve(0);
process.stdout.write('Bye!\n');
resolve(resolveResult);
}); });


main(yargs(hideBin(process.argv)).argv as unknown as Argv) main(yargs(hideBin(process.argv)).argv as unknown as Argv)


+ 3
- 3
package.json View File

@@ -36,12 +36,12 @@
"private": false, "private": false,
"description": "Many-in-one AI client.", "description": "Many-in-one AI client.",
"repository": { "repository": {
"url": "https://code.modal.sh/modal-soft/openai-utils",
"url": "https://code.modal.sh/modal-soft/mio-ai",
"type": "git" "type": "git"
}, },
"homepage": "https://code.modal.sh/modal-soft/openai-utils",
"homepage": "https://code.modal.sh/modal-soft/mio-ai",
"bugs": { "bugs": {
"url": "https://code.modal.sh/modal-soft/openai-utils/issues"
"url": "https://code.modal.sh/modal-soft/mio-ai/issues"
}, },
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>", "author": "TheoryOfNekomata <allan.crisostomo@outlook.com>",
"publishConfig": { "publishConfig": {


+ 2
- 0
src/platforms/openai/index.ts View File

@@ -3,7 +3,9 @@ import { Configuration } from './common';
export * from './chat'; export * from './chat';
export * from './models'; export * from './models';
export * from './common'; export * from './common';
// FIXME wasm module imports don't work with commojs
export * from './usage'; export * from './usage';

export { PlatformEventEmitter, PlatformEventEmitterImpl } from './events'; export { PlatformEventEmitter, PlatformEventEmitterImpl } from './events';
export { export {
ChatCompletion, ChatCompletion,


Loading…
Cancel
Save