@lukaplayground/aikit 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/aikit.umd.js CHANGED
@@ -892,187 +892,58 @@
892
892
  constructor() {
893
893
  super();
894
894
  this.baseURL = 'https://api.openai.com/v1';
895
- this.defaultModel = 'gpt-3.5-turbo';
895
+ this.defaultModel = 'gpt-4o-mini'; // ← 변경: gpt-3.5-turbo에서
896
+
897
+ // 사용 가능한 모델 목록
898
+ this.availableModels = [
899
+ 'gpt-4o',
900
+ 'gpt-4o-mini',
901
+ 'gpt-4-turbo',
902
+ 'gpt-3.5-turbo'
903
+ ];
896
904
  }
897
905
 
898
906
  /**
899
907
  * Send chat request to OpenAI
900
908
  * @override
901
909
  */
902
- async chat(request) {
903
- this.validateRequest(request);
904
-
905
- const { message, apiKey, options = {} } = request;
906
-
907
- const requestBody = {
908
- model: options.model || this.defaultModel,
909
- messages: this.buildMessages(message, options),
910
- temperature: options.temperature ?? 0.7,
911
- max_tokens: options.maxTokens || options.max_tokens,
912
- top_p: options.topP || options.top_p,
913
- frequency_penalty: options.frequencyPenalty || options.frequency_penalty,
914
- presence_penalty: options.presencePenalty || options.presence_penalty,
915
- stream: false
916
- };
917
-
918
- // Remove undefined values
919
- Object.keys(requestBody).forEach(key => {
920
- if (requestBody[key] === undefined) {
921
- delete requestBody[key];
922
- }
923
- });
924
-
925
- const fetchOptions = {
926
- method: 'POST',
927
- headers: this.buildHeaders(apiKey),
928
- body: JSON.stringify(requestBody)
929
- };
930
-
931
- const rawResponse = await this.withRetry(() =>
932
- this.makeRequest(`${this.baseURL}/chat/completions`, fetchOptions)
933
- );
934
-
935
- return this.normalizeResponse(rawResponse);
936
- }
937
-
938
- /**
939
- * Build messages array from user message
940
- * @private
941
- */
942
- buildMessages(message, options) {
943
- const messages = [];
944
-
945
- // Add system message if provided
946
- if (options.systemMessage) {
947
- messages.push({
948
- role: 'system',
949
- content: options.systemMessage
950
- });
951
- }
910
+ async chat(message, options = {}) {
911
+ const model = options.model || this.defaultModel;
912
+ const apiKey = options.apiKey || this.apiKey;
952
913
 
953
- // Add conversation history if provided
954
- if (options.history && Array.isArray(options.history)) {
955
- messages.push(...options.history);
914
+ if (!apiKey) {
915
+ throw new Error('OpenAI API key is required');
956
916
  }
957
917
 
958
- // Add current user message
959
- messages.push({
960
- role: 'user',
961
- content: message
918
+ const response = await fetch(`${this.baseURL}/chat/completions`, {
919
+ method: 'POST',
920
+ headers: {
921
+ 'Content-Type': 'application/json',
922
+ 'Authorization': `Bearer ${apiKey}`
923
+ },
924
+ body: JSON.stringify({
925
+ model: model,
926
+ messages: [
927
+ {
928
+ role: 'user',
929
+ content: message
930
+ }
931
+ ],
932
+ ...options
933
+ })
962
934
  });
963
935
 
964
- return messages;
965
- }
966
-
967
- /**
968
- * Extract text from OpenAI response
969
- * @override
970
- */
971
- extractText(rawResponse) {
972
- if (!rawResponse.choices || rawResponse.choices.length === 0) {
973
- throw new Error('Invalid OpenAI response: no choices returned');
936
+ if (!response.ok) {
937
+ const error = await response.text();
938
+ throw new Error(`HTTP ${response.status}: ${error}`);
974
939
  }
975
940
 
976
- const firstChoice = rawResponse.choices[0];
977
- return firstChoice.message?.content || '';
978
- }
979
-
980
- /**
981
- * Extract usage information
982
- * @override
983
- */
984
- extractUsage(rawResponse) {
985
- const usage = rawResponse.usage || {};
986
-
987
- return {
988
- promptTokens: usage.prompt_tokens || 0,
989
- completionTokens: usage.completion_tokens || 0,
990
- totalTokens: usage.total_tokens || 0,
991
- // Normalized names for compatibility
992
- input: usage.prompt_tokens || 0,
993
- output: usage.completion_tokens || 0,
994
- total: usage.total_tokens || 0
995
- };
996
- }
997
-
998
- /**
999
- * Extract model name
1000
- * @override
1001
- */
1002
- extractModel(rawResponse) {
1003
- return rawResponse.model || this.defaultModel;
1004
- }
1005
-
1006
- /**
1007
- * Extract finish reason
1008
- * @override
1009
- */
1010
- extractFinishReason(rawResponse) {
1011
- if (!rawResponse.choices || rawResponse.choices.length === 0) {
1012
- return 'unknown';
1013
- }
1014
-
1015
- return rawResponse.choices[0].finish_reason || 'unknown';
1016
- }
1017
-
1018
- /**
1019
- * Stream chat (for future implementation)
1020
- * @param {Object} request - Request object
1021
- * @param {Function} onChunk - Callback for each chunk
1022
- */
1023
- async streamChat(request, onChunk) {
1024
- // TODO: Implement streaming support
1025
- throw new Error('Streaming is not yet implemented for OpenAI adapter');
1026
- }
1027
-
1028
- /**
1029
- * List available models
1030
- * @param {string} apiKey - API key
1031
- */
1032
- async listModels(apiKey) {
1033
- const fetchOptions = {
1034
- method: 'GET',
1035
- headers: this.buildHeaders(apiKey)
1036
- };
1037
-
1038
- const response = await this.makeRequest(`${this.baseURL}/models`, fetchOptions);
1039
-
1040
- // Filter to chat models only
1041
- const chatModels = response.data.filter(model =>
1042
- model.id.includes('gpt') || model.id.includes('turbo')
1043
- );
1044
-
1045
- return chatModels.map(model => ({
1046
- id: model.id,
1047
- created: model.created,
1048
- ownedBy: model.owned_by
1049
- }));
1050
- }
941
+ const data = await response.json();
1051
942
 
1052
- /**
1053
- * Generate embeddings
1054
- * @param {string} text - Text to embed
1055
- * @param {string} apiKey - API key
1056
- * @param {Object} options - Options
1057
- */
1058
- async createEmbedding(text, apiKey, options = {}) {
1059
- const requestBody = {
1060
- model: options.model || 'text-embedding-ada-002',
1061
- input: text
1062
- };
1063
-
1064
- const fetchOptions = {
1065
- method: 'POST',
1066
- headers: this.buildHeaders(apiKey),
1067
- body: JSON.stringify(requestBody)
1068
- };
1069
-
1070
- const response = await this.makeRequest(`${this.baseURL}/embeddings`, fetchOptions);
1071
-
1072
943
  return {
1073
- embedding: response.data[0].embedding,
1074
- model: response.model,
1075
- usage: response.usage
944
+ content: data.choices[0].message.content,
945
+ model: data.model,
946
+ usage: data.usage
1076
947
  };
1077
948
  }
1078
949
  }
@@ -1087,192 +958,74 @@
1087
958
  constructor() {
1088
959
  super();
1089
960
  this.baseURL = 'https://api.anthropic.com/v1';
1090
- this.defaultModel = 'claude-3-sonnet-20240229';
961
+ this.defaultModel = 'claude-3-5-sonnet-20241022'; // ← 변경
1091
962
  this.apiVersion = '2023-06-01';
963
+
964
+ // 사용 가능한 모델 목록
965
+ this.availableModels = [
966
+ 'claude-3-5-sonnet-20241022',
967
+ 'claude-3-5-haiku-20241022',
968
+ 'claude-3-opus-20240229',
969
+ 'claude-3-sonnet-20240229',
970
+ 'claude-3-haiku-20240307'
971
+ ];
1092
972
  }
1093
973
 
1094
974
  /**
1095
975
  * Send chat request to Claude
1096
976
  * @override
1097
977
  */
1098
- async chat(request) {
1099
- this.validateRequest(request);
1100
-
1101
- const { message, apiKey, options = {} } = request;
1102
-
1103
- const requestBody = {
1104
- model: options.model || this.defaultModel,
1105
- messages: this.buildMessages(message, options),
1106
- max_tokens: options.maxTokens || options.max_tokens || 1024,
1107
- temperature: options.temperature ?? 1.0,
1108
- top_p: options.topP || options.top_p,
1109
- top_k: options.topK || options.top_k,
1110
- stream: false
1111
- };
978
+ async chat(message, options = {}) {
979
+ const model = options.model || this.defaultModel;
980
+ const apiKey = options.apiKey || this.apiKey;
981
+ const maxTokens = options.maxTokens || 1024;
1112
982
 
1113
- // Add system message if provided
1114
- if (options.systemMessage) {
1115
- requestBody.system = options.systemMessage;
983
+ if (!apiKey) {
984
+ throw new Error('Claude API key is required');
1116
985
  }
1117
986
 
1118
- // Remove undefined values
1119
- Object.keys(requestBody).forEach(key => {
1120
- if (requestBody[key] === undefined) {
1121
- delete requestBody[key];
1122
- }
1123
- });
1124
-
1125
- const fetchOptions = {
987
+ const response = await fetch(`${this.baseURL}/messages`, {
1126
988
  method: 'POST',
1127
- headers: this.buildHeaders(apiKey),
1128
- body: JSON.stringify(requestBody)
1129
- };
1130
-
1131
- const rawResponse = await this.withRetry(() =>
1132
- this.makeRequest(`${this.baseURL}/messages`, fetchOptions)
1133
- );
1134
-
1135
- return this.normalizeResponse(rawResponse);
1136
- }
1137
-
1138
- /**
1139
- * Build headers for Claude API
1140
- * @override
1141
- */
1142
- buildHeaders(apiKey) {
1143
- return {
1144
- 'Content-Type': 'application/json',
1145
- 'x-api-key': apiKey,
1146
- 'anthropic-version': this.apiVersion
1147
- };
1148
- }
1149
-
1150
- /**
1151
- * Build messages array from user message
1152
- * @private
1153
- */
1154
- buildMessages(message, options) {
1155
- const messages = [];
1156
-
1157
- // Add conversation history if provided
1158
- if (options.history && Array.isArray(options.history)) {
1159
- // Claude uses 'user' and 'assistant' roles
1160
- messages.push(...options.history.map(msg => ({
1161
- role: msg.role === 'system' ? 'user' : msg.role,
1162
- content: msg.content
1163
- })));
1164
- }
1165
-
1166
- // Add current user message
1167
- messages.push({
1168
- role: 'user',
1169
- content: message
989
+ headers: {
990
+ 'Content-Type': 'application/json',
991
+ 'x-api-key': apiKey,
992
+ 'anthropic-version': this.apiVersion
993
+ },
994
+ body: JSON.stringify({
995
+ model: model,
996
+ max_tokens: maxTokens,
997
+ messages: [
998
+ {
999
+ role: 'user',
1000
+ content: message
1001
+ }
1002
+ ]
1003
+ })
1170
1004
  });
1171
1005
 
1172
- return messages;
1173
- }
1174
-
1175
- /**
1176
- * Extract text from Claude response
1177
- * @override
1178
- */
1179
- extractText(rawResponse) {
1180
- if (!rawResponse.content || rawResponse.content.length === 0) {
1181
- throw new Error('Invalid Claude response: no content returned');
1006
+ if (!response.ok) {
1007
+ const error = await response.text();
1008
+ throw new Error(`HTTP ${response.status}: ${error}`);
1182
1009
  }
1183
1010
 
1184
- // Claude can return multiple content blocks
1185
- const textBlocks = rawResponse.content
1186
- .filter(block => block.type === 'text')
1187
- .map(block => block.text);
1188
-
1189
- return textBlocks.join('\n');
1190
- }
1011
+ const data = await response.json();
1191
1012
 
1192
- /**
1193
- * Extract usage information
1194
- * @override
1195
- */
1196
- extractUsage(rawResponse) {
1197
- const usage = rawResponse.usage || {};
1198
-
1199
1013
  return {
1200
- promptTokens: usage.input_tokens || 0,
1201
- completionTokens: usage.output_tokens || 0,
1202
- totalTokens: (usage.input_tokens || 0) + (usage.output_tokens || 0),
1203
- // Normalized names for compatibility
1204
- input: usage.input_tokens || 0,
1205
- output: usage.output_tokens || 0,
1206
- total: (usage.input_tokens || 0) + (usage.output_tokens || 0)
1207
- };
1208
- }
1209
-
1210
- /**
1211
- * Extract model name
1212
- * @override
1213
- */
1214
- extractModel(rawResponse) {
1215
- return rawResponse.model || this.defaultModel;
1216
- }
1217
-
1218
- /**
1219
- * Extract finish reason
1220
- * @override
1221
- */
1222
- extractFinishReason(rawResponse) {
1223
- return rawResponse.stop_reason || 'unknown';
1224
- }
1225
-
1226
- /**
1227
- * Stream chat (for future implementation)
1228
- * @param {Object} request - Request object
1229
- * @param {Function} onChunk - Callback for each chunk
1230
- */
1231
- async streamChat(request, onChunk) {
1232
- // TODO: Implement streaming support
1233
- throw new Error('Streaming is not yet implemented for Claude adapter');
1234
- }
1235
-
1236
- /**
1237
- * Get model information
1238
- */
1239
- getAvailableModels() {
1240
- return [
1241
- {
1242
- id: 'claude-3-opus-20240229',
1243
- name: 'Claude 3 Opus',
1244
- description: 'Most powerful model, best for complex tasks',
1245
- maxTokens: 4096
1246
- },
1247
- {
1248
- id: 'claude-3-sonnet-20240229',
1249
- name: 'Claude 3 Sonnet',
1250
- description: 'Balanced performance and speed',
1251
- maxTokens: 4096
1252
- },
1253
- {
1254
- id: 'claude-3-haiku-20240307',
1255
- name: 'Claude 3 Haiku',
1256
- description: 'Fastest model, best for simple tasks',
1257
- maxTokens: 4096
1258
- },
1259
- {
1260
- id: 'claude-2.1',
1261
- name: 'Claude 2.1',
1262
- description: 'Previous generation model',
1263
- maxTokens: 4096
1014
+ content: data.content[0].text,
1015
+ model: data.model,
1016
+ usage: {
1017
+ input_tokens: data.usage.input_tokens,
1018
+ output_tokens: data.usage.output_tokens
1264
1019
  }
1265
- ];
1020
+ };
1266
1021
  }
1267
1022
 
1268
1023
  /**
1269
- * Count tokens (approximate)
1270
- * Claude's tokenization is similar to GPT but not identical
1271
- * This is a rough estimate
1024
+ * Estimate token count (Claude uses characters)
1025
+ * @private
1272
1026
  */
1273
1027
  estimateTokens(text) {
1274
- // Rough estimate: ~4 characters per token for English
1275
- // ~2 characters per token for code
1028
+ // Claude roughly: 1 token ≈ 4 characters for English
1276
1029
  const avgCharsPerToken = text.match(/[a-zA-Z0-9_]/g) ? 4 : 3;
1277
1030
  return Math.ceil(text.length / avgCharsPerToken);
1278
1031
  }
@@ -1288,269 +1041,54 @@
1288
1041
  constructor() {
1289
1042
  super();
1290
1043
  this.baseURL = 'https://generativelanguage.googleapis.com/v1beta';
1291
- this.defaultModel = 'gemini-pro';
1044
+ this.defaultModel = 'gemini-1.5-flash'; // ← 변경
1045
+
1046
+ // 사용 가능한 모델 목록
1047
+ this.availableModels = [
1048
+ 'gemini-1.5-flash',
1049
+ 'gemini-1.5-flash-8b',
1050
+ 'gemini-1.5-pro',
1051
+ 'gemini-2.0-flash-exp'
1052
+ ];
1292
1053
  }
1293
1054
 
1294
1055
  /**
1295
1056
  * Send chat request to Gemini
1296
1057
  * @override
1297
1058
  */
1298
- async chat(request) {
1299
- this.validateRequest(request);
1300
-
1301
- const { message, apiKey, options = {} } = request;
1059
+ async chat(message, options = {}) {
1302
1060
  const model = options.model || this.defaultModel;
1061
+ const apiKey = options.apiKey || this.apiKey;
1303
1062
 
1304
- const requestBody = {
1305
- contents: this.buildContents(message, options),
1306
- generationConfig: {
1307
- temperature: options.temperature ?? 0.9,
1308
- topK: options.topK || options.top_k,
1309
- topP: (options.topP || options.top_p) ?? 1,
1310
- maxOutputTokens: options.maxTokens || options.max_tokens || options.maxOutputTokens,
1311
- stopSequences: options.stopSequences || options.stop
1312
- }
1313
- };
1314
-
1315
- // Add safety settings if provided
1316
- if (options.safetySettings) {
1317
- requestBody.safetySettings = options.safetySettings;
1318
- }
1319
-
1320
- // Remove undefined values
1321
- if (requestBody.generationConfig) {
1322
- Object.keys(requestBody.generationConfig).forEach(key => {
1323
- if (requestBody.generationConfig[key] === undefined) {
1324
- delete requestBody.generationConfig[key];
1325
- }
1326
- });
1063
+ if (!apiKey) {
1064
+ throw new Error('Gemini API key is required');
1327
1065
  }
1328
1066
 
1329
1067
  const url = `${this.baseURL}/models/${model}:generateContent?key=${apiKey}`;
1330
1068
 
1331
- const fetchOptions = {
1069
+ const response = await fetch(url, {
1332
1070
  method: 'POST',
1333
1071
  headers: {
1334
1072
  'Content-Type': 'application/json'
1335
1073
  },
1336
- body: JSON.stringify(requestBody)
1337
- };
1338
-
1339
- const rawResponse = await this.withRetry(() =>
1340
- this.makeRequest(url, fetchOptions)
1341
- );
1342
-
1343
- return this.normalizeResponse(rawResponse);
1344
- }
1345
-
1346
- /**
1347
- * Build contents array from user message
1348
- * @private
1349
- */
1350
- buildContents(message, options) {
1351
- const contents = [];
1352
-
1353
- // Add conversation history if provided
1354
- if (options.history && Array.isArray(options.history)) {
1355
- options.history.forEach(msg => {
1356
- contents.push({
1357
- role: msg.role === 'assistant' ? 'model' : 'user',
1358
- parts: [{ text: msg.content }]
1359
- });
1360
- });
1361
- }
1362
-
1363
- // Add current user message
1364
- contents.push({
1365
- role: 'user',
1366
- parts: [{ text: message }]
1074
+ body: JSON.stringify({
1075
+ contents: [{
1076
+ parts: [{
1077
+ text: message
1078
+ }]
1079
+ }]
1080
+ })
1367
1081
  });
1368
1082
 
1369
- return contents;
1370
- }
1371
-
1372
- /**
1373
- * Extract text from Gemini response
1374
- * @override
1375
- */
1376
- extractText(rawResponse) {
1377
- if (!rawResponse.candidates || rawResponse.candidates.length === 0) {
1378
- throw new Error('Invalid Gemini response: no candidates returned');
1083
+ if (!response.ok) {
1084
+ const error = await response.text();
1085
+ throw new Error(`HTTP ${response.status}: ${error}`);
1379
1086
  }
1380
1087
 
1381
- const candidate = rawResponse.candidates[0];
1382
-
1383
- if (!candidate.content || !candidate.content.parts) {
1384
- throw new Error('Invalid Gemini response: no content parts');
1385
- }
1386
-
1387
- // Combine all text parts
1388
- const textParts = candidate.content.parts
1389
- .filter(part => part.text)
1390
- .map(part => part.text);
1391
-
1392
- return textParts.join('\n');
1393
- }
1394
-
1395
- /**
1396
- * Extract usage information
1397
- * @override
1398
- */
1399
- extractUsage(rawResponse) {
1400
- const metadata = rawResponse.usageMetadata || {};
1401
-
1402
- return {
1403
- promptTokens: metadata.promptTokenCount || 0,
1404
- completionTokens: metadata.candidatesTokenCount || 0,
1405
- totalTokens: metadata.totalTokenCount || 0,
1406
- // Normalized names for compatibility
1407
- input: metadata.promptTokenCount || 0,
1408
- output: metadata.candidatesTokenCount || 0,
1409
- total: metadata.totalTokenCount || 0
1410
- };
1411
- }
1412
-
1413
- /**
1414
- * Extract model name
1415
- * @override
1416
- */
1417
- extractModel(rawResponse) {
1418
- return rawResponse.modelVersion || this.defaultModel;
1419
- }
1420
-
1421
- /**
1422
- * Extract finish reason
1423
- * @override
1424
- */
1425
- extractFinishReason(rawResponse) {
1426
- if (!rawResponse.candidates || rawResponse.candidates.length === 0) {
1427
- return 'unknown';
1428
- }
1429
-
1430
- return rawResponse.candidates[0].finishReason || 'STOP';
1431
- }
1432
-
1433
- /**
1434
- * Stream chat (for future implementation)
1435
- * @param {Object} request - Request object
1436
- * @param {Function} onChunk - Callback for each chunk
1437
- */
1438
- async streamChat(request, onChunk) {
1439
- // TODO: Implement streaming support
1440
- throw new Error('Streaming is not yet implemented for Gemini adapter');
1441
- }
1442
-
1443
- /**
1444
- * Get available models
1445
- */
1446
- getAvailableModels() {
1447
- return [
1448
- {
1449
- id: 'gemini-pro',
1450
- name: 'Gemini Pro',
1451
- description: 'Best for text generation',
1452
- maxTokens: 8192
1453
- },
1454
- {
1455
- id: 'gemini-pro-vision',
1456
- name: 'Gemini Pro Vision',
1457
- description: 'Multimodal model for text and images',
1458
- maxTokens: 4096
1459
- },
1460
- {
1461
- id: 'gemini-ultra',
1462
- name: 'Gemini Ultra',
1463
- description: 'Most capable model (limited access)',
1464
- maxTokens: 8192
1465
- }
1466
- ];
1467
- }
1468
-
1469
- /**
1470
- * List models via API
1471
- * @param {string} apiKey - API key
1472
- */
1473
- async listModels(apiKey) {
1474
- const url = `${this.baseURL}/models?key=${apiKey}`;
1475
-
1476
- const fetchOptions = {
1477
- method: 'GET',
1478
- headers: {
1479
- 'Content-Type': 'application/json'
1480
- }
1481
- };
1482
-
1483
- const response = await this.makeRequest(url, fetchOptions);
1484
-
1485
- return response.models
1486
- .filter(model => model.supportedGenerationMethods?.includes('generateContent'))
1487
- .map(model => ({
1488
- id: model.name.replace('models/', ''),
1489
- displayName: model.displayName,
1490
- description: model.description,
1491
- inputTokenLimit: model.inputTokenLimit,
1492
- outputTokenLimit: model.outputTokenLimit
1493
- }));
1494
- }
1495
-
1496
- /**
1497
- * Count tokens
1498
- * @param {string} text - Text to count tokens for
1499
- * @param {string} apiKey - API key
1500
- * @param {string} model - Model name
1501
- */
1502
- async countTokens(text, apiKey, model = this.defaultModel) {
1503
- const url = `${this.baseURL}/models/${model}:countTokens?key=${apiKey}`;
1504
-
1505
- const requestBody = {
1506
- contents: [{
1507
- role: 'user',
1508
- parts: [{ text }]
1509
- }]
1510
- };
1511
-
1512
- const fetchOptions = {
1513
- method: 'POST',
1514
- headers: {
1515
- 'Content-Type': 'application/json'
1516
- },
1517
- body: JSON.stringify(requestBody)
1518
- };
1519
-
1520
- const response = await this.makeRequest(url, fetchOptions);
1521
-
1522
- return {
1523
- totalTokens: response.totalTokens || 0
1524
- };
1525
- }
1526
-
1527
- /**
1528
- * Generate embeddings
1529
- * @param {string} text - Text to embed
1530
- * @param {string} apiKey - API key
1531
- */
1532
- async createEmbedding(text, apiKey) {
1533
- const model = 'embedding-001';
1534
- const url = `${this.baseURL}/models/${model}:embedContent?key=${apiKey}`;
1535
-
1536
- const requestBody = {
1537
- content: {
1538
- parts: [{ text }]
1539
- }
1540
- };
1541
-
1542
- const fetchOptions = {
1543
- method: 'POST',
1544
- headers: {
1545
- 'Content-Type': 'application/json'
1546
- },
1547
- body: JSON.stringify(requestBody)
1548
- };
1549
-
1550
- const response = await this.makeRequest(url, fetchOptions);
1088
+ const data = await response.json();
1551
1089
 
1552
1090
  return {
1553
- embedding: response.embedding.values,
1091
+ content: data.candidates[0].content.parts[0].text,
1554
1092
  model: model
1555
1093
  };
1556
1094
  }