|
12 | 12 | import { Service } from 'egg'; |
13 | 13 | import Transformer from '@opentiny/tiny-engine-transform'; |
14 | 14 | import { E_FOUNDATION_MODEL } from '../../lib/enum'; |
| 15 | +import * as fs from 'fs'; |
| 16 | +import * as path from 'path'; |
| 17 | + |
| 18 | +const OpenAI = require('openai'); |
| 19 | + |
| 20 | +const client = new OpenAI({ |
| 21 | + apiKey: 'sk-uORejJaJs7ZXP6MFQkY9FzYhgPWZms1iOTCBUHA0ipQJRhRt', |
| 22 | + baseURL: 'https://api.moonshot.cn/v1' |
| 23 | +}); |
15 | 24 |
|
16 | 25 | export type AiMessage = { |
17 | 26 | role: string; // 角色 |
18 | 27 | name?: string; // 名称 |
19 | 28 | content: string; // 聊天内容 |
20 | 29 | }; |
21 | 30 |
|
| 31 | +interface ConfigModel { |
| 32 | + model: string; |
| 33 | + token: string; |
| 34 | +} |
| 35 | + |
22 | 36 | export default class AiChat extends Service { |
23 | 37 | /** |
24 | 38 | * 获取ai的答复 |
@@ -53,7 +67,7 @@ export default class AiChat extends Service { |
53 | 67 | const aiChatConfig = this.config.aiChat(messages, chatConfig.token); |
54 | 68 | const { httpRequestUrl, httpRequestOption } = aiChatConfig[chatConfig.model]; |
55 | 69 | this.ctx.logger.debug(httpRequestOption); |
56 | | - |
| 70 | + |
57 | 71 | res = await ctx.curl(httpRequestUrl, httpRequestOption); |
58 | 72 |
|
59 | 73 | } catch (e: any) { |
@@ -165,5 +179,62 @@ export default class AiChat extends Service { |
165 | 179 | } |
166 | 180 | return messages; |
167 | 181 | } |
| 182 | + |
| 183 | + /** |
| 184 | + * 文件上传 |
| 185 | + * |
| 186 | + * @param model |
| 187 | + * @return |
| 188 | + */ |
| 189 | + |
| 190 | + async getFileContentFromAi(fileStream: any, chatConfig: ConfigModel) { |
| 191 | + const answer = await this.requestFileContentFromAi(fileStream, chatConfig); |
| 192 | + return this.ctx.helper.getResponseData({ |
| 193 | + originalResponse: answer |
| 194 | + }); |
| 195 | + } |
| 196 | + |
| 197 | + async requestFileContentFromAi(file: any, chatConfig: ConfigModel) { |
| 198 | + const { ctx } = this; |
| 199 | + // // @ts-ignore |
| 200 | + const filename = Math.random().toString(36).substr(2) + new Date().getTime() + path.extname(file.filename).toLocaleLowerCase(); |
| 201 | + const savePath = path.join(__dirname, filename); |
| 202 | + const writeStream = fs.createWriteStream(savePath); |
| 203 | + file.pipe(writeStream); |
| 204 | + await new Promise(resolve => writeStream.on('close', resolve)); |
| 205 | + |
| 206 | + let res: any = null; |
| 207 | + try { |
| 208 | + //上传文件 |
| 209 | + const fileObject = await client.files.create({ |
| 210 | + file: fs.createReadStream(savePath), |
| 211 | + purpose: 'file-extract' |
| 212 | + }); |
| 213 | + |
| 214 | + // 文件解析 |
| 215 | + const imageAnalysisConfig = this.config.parsingFile(fileObject.id, chatConfig.token); |
| 216 | + const { analysisImageHttpRequestUrl, analysisImageHttpRequestOption } = imageAnalysisConfig[chatConfig.model]; |
| 217 | + res = await ctx.curl(analysisImageHttpRequestUrl, analysisImageHttpRequestOption); |
| 218 | + res.data = JSON.parse(res.res.data.toString()); |
| 219 | + console.log(res.data); |
| 220 | + } catch (e: any) { |
| 221 | + this.ctx.logger.debug(`调用上传图片接口失败: ${(e as Error).message}`); |
| 222 | + return this.ctx.helper.getResponseData(`调用上传图片接口失败: ${(e as Error).message}`); |
| 223 | + } finally { |
| 224 | + // 删除本地文件 |
| 225 | + try { |
| 226 | + await fs.promises.unlink(savePath); |
| 227 | + console.log('文件已删除:', savePath); |
| 228 | + } catch (err) { |
| 229 | + console.error('文件删除失败:', err); |
| 230 | + } |
| 231 | + } |
| 232 | + |
| 233 | + if (!res) { |
| 234 | + return this.ctx.helper.getResponseData(`调用上传图片接口未返回正确数据.`); |
| 235 | + } |
| 236 | + |
| 237 | + return res.data; |
| 238 | + } |
168 | 239 | } |
169 | 240 |
|
0 commit comments