Many-in-one AI client.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

215 linhas
6.4 KiB

  1. import { config } from 'dotenv';
  2. import {
  3. beforeAll,
  4. beforeEach,
  5. describe,
  6. expect,
  7. it,
  8. } from 'vitest';
  9. import {
  10. createAiClient,
  11. PlatformEventEmitter,
  12. OpenAi,
  13. } from '../src';
  14. describe('ai-utils', () => {
  15. beforeAll(() => {
  16. config();
  17. });
  18. describe('OpenAI', () => {
  19. let aiClient: PlatformEventEmitter;
  20. beforeEach(() => {
  21. aiClient = createAiClient({
  22. platform: OpenAi.PLATFORM_ID,
  23. platformConfiguration: {
  24. apiKey: process.env.OPENAI_API_KEY as string,
  25. organizationId: process.env.OPENAI_ORGANIZATION_ID as string,
  26. apiVersion: OpenAi.ApiVersion.V1,
  27. },
  28. });
  29. });
  30. describe.skip('createChatCompletion', () => {
  31. let result: Partial<OpenAi.ChatCompletion> | undefined;
  32. beforeEach(() => {
  33. result = undefined;
  34. aiClient.on<OpenAi.ChatCompletionChunkDataEvent>('data', (d) => {
  35. d.choices.forEach((c) => {
  36. if (!result) {
  37. result = {
  38. id: d.id,
  39. object: OpenAi.ChatCompletionDataEventObjectType.CHAT_COMPLETION,
  40. created: d.created,
  41. model: d.model,
  42. };
  43. }
  44. if (!Array.isArray(result?.choices)) {
  45. result.choices = [];
  46. }
  47. if (!result.choices[c.index]) {
  48. result.choices[c.index] = {
  49. message: { content: '' },
  50. index: c.index,
  51. finish_reason: c.finish_reason,
  52. };
  53. }
  54. if (result.choices[c.index].message) {
  55. if (c.delta.role) {
  56. (result.choices[c.index].message as Record<string, unknown>).role = c.delta.role;
  57. }
  58. if (c.delta.content) {
  59. (result.choices[c.index].message as Record<string, unknown>)
  60. .content += c.delta.content;
  61. }
  62. }
  63. if (c.finish_reason) {
  64. result.choices[c.index].finish_reason = c.finish_reason;
  65. }
  66. });
  67. });
  68. });
  69. it('works', () => new Promise<void>((resolve, reject) => {
  70. aiClient.on('end', () => {
  71. expect(result).toHaveProperty('id', expect.any(String));
  72. expect(result).toHaveProperty('object', OpenAi.ChatCompletionDataEventObjectType.CHAT_COMPLETION);
  73. expect(result).toHaveProperty('model', expect.any(String));
  74. expect(result).toHaveProperty('created', expect.any(Number));
  75. expect(result).toHaveProperty('choices', expect.any(Array));
  76. resolve();
  77. });
  78. aiClient.on('error', (error: Error) => {
  79. reject(error);
  80. });
  81. aiClient.createChatCompletion({
  82. messages: 'Count from 1 to 20 in increments of a random number from 1 to 10.',
  83. model: OpenAi.ChatCompletionModel.GPT_3_5_TURBO,
  84. n: 2,
  85. });
  86. }), { timeout: 10000 });
  87. });
  88. describe.skip('createImage', () => {
  89. it('works', () => new Promise<void>((resolve, reject) => {
  90. aiClient.on<OpenAi.CreateImageDataEvent>('data', (r) => {
  91. expect(r).toHaveProperty('created', expect.any(Number));
  92. expect(r).toHaveProperty('data', expect.any(Array));
  93. expect(r.data.every((d) => d instanceof Buffer)).toBe(true);
  94. });
  95. aiClient.on('end', () => {
  96. resolve();
  97. });
  98. aiClient.on('error', (error: Error) => {
  99. reject(error);
  100. });
  101. aiClient.createImage({
  102. prompt: 'A photo of a cat',
  103. size: OpenAi.CreateImageSize.SQUARE_256,
  104. });
  105. }), { timeout: 10000 });
  106. });
  107. describe.skip('createCompletion', () => {
  108. let result: Partial<OpenAi.TextCompletion> | undefined;
  109. beforeEach(() => {
  110. result = undefined;
  111. aiClient.on<OpenAi.TextCompletionChunkDataEvent>('data', (d) => {
  112. d.choices.forEach((c) => {
  113. if (!result) {
  114. result = {
  115. id: d.id,
  116. object: OpenAi.TextCompletionDataEventObjectType.TEXT_COMPLETION,
  117. created: d.created,
  118. model: d.model,
  119. };
  120. }
  121. if (!Array.isArray(result?.choices)) {
  122. result.choices = [];
  123. }
  124. if (!result.choices[c.index]) {
  125. result.choices[c.index] = {
  126. text: '',
  127. index: c.index,
  128. finish_reason: c.finish_reason,
  129. logprobs: c.logprobs, // TODO dunno how to use this?
  130. };
  131. }
  132. if (c.text) {
  133. result.choices[c.index].text += c.text;
  134. }
  135. if (c.finish_reason) {
  136. result.choices[c.index].finish_reason = c.finish_reason;
  137. }
  138. });
  139. });
  140. });
  141. it('works', () => new Promise<void>((resolve, reject) => {
  142. aiClient.on('end', () => {
  143. expect(result).toHaveProperty('id', expect.any(String));
  144. expect(result).toHaveProperty('object', OpenAi.TextCompletionDataEventObjectType.TEXT_COMPLETION);
  145. expect(result).toHaveProperty('model', expect.any(String));
  146. expect(result).toHaveProperty('created', expect.any(Number));
  147. expect(result).toHaveProperty('choices', expect.any(Array));
  148. resolve();
  149. });
  150. aiClient.on('error', (error: Error) => {
  151. reject(error);
  152. });
  153. aiClient.createCompletion({
  154. prompt: 'Say this is a test',
  155. model: OpenAi.TextCompletionModel.TEXT_DAVINCI_003,
  156. maxTokens: 7,
  157. temperature: 0,
  158. });
  159. }), { timeout: 10000 });
  160. });
  161. describe.skip('createEdit', () => {
  162. it('works', () => new Promise<void>((resolve, reject) => {
  163. aiClient.on<OpenAi.CreateEditDataEvent>('data', (r) => {
  164. expect(r).toHaveProperty('object', OpenAi.EditDataEventObjectType.EDIT);
  165. expect(r).toHaveProperty('created', expect.any(Number));
  166. expect(r).toHaveProperty('choices', expect.any(Array));
  167. });
  168. aiClient.on('end', () => {
  169. resolve();
  170. });
  171. aiClient.on('error', (error: Error) => {
  172. reject(error);
  173. });
  174. aiClient.createEdit({
  175. model: OpenAi.EditModel.TEXT_DAVINCI_EDIT_001,
  176. input: 'What day of the wek is it?',
  177. instruction: 'Fix the spelling mistakes',
  178. });
  179. }), { timeout: 10000 });
  180. });
  181. });
  182. });