openai-node

Форк
0
194 строки · 6.3 Кб
1
import 'openai/shims/node';
2
import OpenAI, { toFile } from 'openai';
3
import { TranscriptionCreateParams } from 'openai/resources/audio/transcriptions';
4
import fetch from 'node-fetch';
5
import { File as FormDataFile, Blob as FormDataBlob } from 'formdata-node';
6
import * as fs from 'fs';
7
import { distance } from 'fastest-levenshtein';
8
import { ChatCompletion } from 'openai/resources/chat/completions';
9

10
const url = 'https://audio-samples.github.io/samples/mp3/blizzard_biased/sample-1.mp3';
11
const filename = 'sample-1.mp3';
12

13
const correctAnswer =
14
  'It was anxious to find him no one that expectation of a man who were giving his father enjoyment. But he was avoided in sight in the minister to which indeed,';
15
const model = 'whisper-1';
16

17
const client = new OpenAI();
18

19
async function typeTests() {
20
  // @ts-expect-error this should error if the `Uploadable` type was resolved correctly
21
  await client.audio.transcriptions.create({ file: { foo: true }, model: 'whisper-1' });
22
  // @ts-expect-error this should error if the `Uploadable` type was resolved correctly
23
  await client.audio.transcriptions.create({ file: null, model: 'whisper-1' });
24
  // @ts-expect-error this should error if the `Uploadable` type was resolved correctly
25
  await client.audio.transcriptions.create({ file: 'test', model: 'whisper-1' });
26
}
27

28
declare global {
29
  namespace jest {
30
    interface Matchers<R> {
31
      toBeSimilarTo(comparedTo: string, expectedDistance: number): R;
32
    }
33
  }
34
}
35
expect.extend({
36
  toBeSimilarTo(received, comparedTo: string, expectedDistance: number) {
37
    const message = () =>
38
      [
39
        `Received: ${JSON.stringify(received)}`,
40
        `Expected: ${JSON.stringify(comparedTo)}`,
41
        `Expected distance: ${expectedDistance}`,
42
        `Received distance: ${actualDistance}`,
43
      ].join('\n');
44

45
    const actualDistance = distance(received, comparedTo);
46
    if (actualDistance < expectedDistance) {
47
      return {
48
        message,
49
        pass: true,
50
      };
51
    }
52

53
    return {
54
      message,
55
      pass: false,
56
    };
57
  },
58
});
59

60
it(`raw response`, async function () {
61
  const response = await client.chat.completions
62
    .create({
63
      model: 'gpt-4',
64
      messages: [{ role: 'user', content: 'Say this is a test' }],
65
    })
66
    .asResponse();
67

68
  // test that we can use node-fetch Response API
69
  const chunks: string[] = [];
70
  response.body.on('data', (chunk) => chunks.push(chunk));
71
  await new Promise<void>((resolve, reject) => {
72
    response.body.once('end', resolve);
73
    response.body.once('error', reject);
74
  });
75
  const json: ChatCompletion = JSON.parse(chunks.join(''));
76
  expect(json.choices[0]?.message.content || '').toBeSimilarTo('This is a test', 10);
77
});
78

79
it(`streaming works`, async function () {
80
  const stream = await client.chat.completions.create({
81
    model: 'gpt-4',
82
    messages: [{ role: 'user', content: 'Say this is a test' }],
83
    stream: true,
84
  });
85
  const chunks = [];
86
  for await (const part of stream) {
87
    chunks.push(part);
88
  }
89
  expect(chunks.map((c) => c.choices[0]?.delta.content || '').join('')).toBeSimilarTo('This is a test', 10);
90
});
91

92
it('handles formdata-node File', async function () {
93
  const file = await fetch(url)
94
    .then((x) => x.arrayBuffer())
95
    .then((x) => new FormDataFile([x], filename));
96

97
  const params: TranscriptionCreateParams = { file, model };
98

99
  const result = await client.audio.transcriptions.create(params);
100
  expect(result.text).toBeSimilarTo(correctAnswer, 12);
101
});
102

103
// @ts-ignore avoid DOM lib for testing purposes
104
if (typeof File !== 'undefined') {
105
  it('handles builtinFile', async function () {
106
    const file = await fetch(url)
107
      .then((x) => x.arrayBuffer())
108
      // @ts-ignore avoid DOM lib for testing purposes
109
      .then((x) => new File([x], filename));
110

111
    const result = await client.audio.transcriptions.create({ file, model });
112
    expect(result.text).toBeSimilarTo(correctAnswer, 12);
113
  });
114
}
115

116
it('handles Response', async function () {
117
  const file = await fetch(url);
118

119
  const result = await client.audio.transcriptions.create({ file, model });
120
  expect(result.text).toBeSimilarTo(correctAnswer, 12);
121
});
122

123
it('handles fs.ReadStream', async function () {
124
  const result = await client.audio.transcriptions.create({
125
    file: fs.createReadStream('sample1.mp3'),
126
    model,
127
  });
128
  expect(result.text).toBeSimilarTo(correctAnswer, 12);
129
});
130

131
const fineTune = `{"prompt": "<prompt text>", "completion": "<ideal generated text>"}`;
132

133
describe('toFile', () => {
134
  it('handles form-data Blob', async function () {
135
    const result = await client.files.create({
136
      file: await toFile(
137
        new FormDataBlob([
138
          // @ts-ignore avoid DOM lib for testing purposes
139
          new TextEncoder().encode(fineTune),
140
        ]),
141
        'finetune.jsonl',
142
      ),
143
      purpose: 'fine-tune',
144
    });
145
    expect(result.filename).toEqual('finetune.jsonl');
146
  });
147
  // @ts-ignore avoid DOM lib for testing purposes
148
  if (typeof Blob !== 'undefined') {
149
    it('handles builtin Blob', async function () {
150
      const result = await client.files.create({
151
        file: await toFile(
152
          // @ts-ignore avoid DOM lib for testing purposes
153
          new Blob([new TextEncoder().encode(fineTune)]),
154
          'finetune.jsonl',
155
        ),
156
        purpose: 'fine-tune',
157
      });
158
      expect(result.filename).toEqual('finetune.jsonl');
159
    });
160
  }
161
  it('handles Uint8Array', async function () {
162
    const result = await client.files.create({
163
      file: await toFile(
164
        // @ts-ignore avoid DOM lib for testing purposes
165
        new TextEncoder().encode(fineTune),
166
        'finetune.jsonl',
167
      ),
168
      purpose: 'fine-tune',
169
    });
170
    expect(result.filename).toEqual('finetune.jsonl');
171
  });
172
  it('handles ArrayBuffer', async function () {
173
    const result = await client.files.create({
174
      file: await toFile(
175
        // @ts-ignore avoid DOM lib for testing purposes
176
        new TextEncoder().encode(fineTune).buffer,
177
        'finetune.jsonl',
178
      ),
179
      purpose: 'fine-tune',
180
    });
181
    expect(result.filename).toEqual('finetune.jsonl');
182
  });
183
  it('handles DataView', async function () {
184
    const result = await client.files.create({
185
      file: await toFile(
186
        // @ts-ignore avoid DOM lib for testing purposes
187
        new DataView(new TextEncoder().encode(fineTune).buffer),
188
        'finetune.jsonl',
189
      ),
190
      purpose: 'fine-tune',
191
    });
192
    expect(result.filename).toEqual('finetune.jsonl');
193
  });
194
});
195

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.