doomiaichat 7.1.29 → 7.1.30

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/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "doomiaichat",
3
- "version": "7.1.29",
3
+ "version": "7.1.30",
4
4
  "description": "Doomisoft OpenAI",
5
5
  "main": "dist/index.js",
6
+ "files": ["dist"],
6
7
  "scripts": {
7
8
  "build": "tsc"
8
9
  },
@@ -18,7 +19,7 @@
18
19
  "dependencies": {
19
20
  "@azure/openai": "^1.0.0-beta.11",
20
21
  "@coze/api": "^1.3.6",
21
- "axios": "^1.8.4",
22
+ "axios": "^1.12.0",
22
23
  "openai": "^5.19.1"
23
24
  }
24
25
  }
package/src/aimp.ts DELETED
@@ -1,125 +0,0 @@
1
- /**
2
- * 接入AI平台的中间层
3
- */
4
- import axios from 'axios';
5
- import { request } from "./declare";
6
- import GptBase from "./gptbase"
7
- import { Readable } from 'stream';
8
- // import { ChatReponse } from './declare';
9
- export default class AIMiddlePlatform extends GptBase {
10
-
11
- protected apikey: string;
12
- protected agent: { endpoint: string, agentid: string };
13
- /**
14
- *
15
- * @param apikey 调用AI中台 的key
16
- * @param agent 智能体信息
17
- */
18
- constructor(apikey: string, agent: { endpoint: string, agentid: string }) {
19
- super();
20
- this.apikey = apikey;
21
- this.agent = agent;
22
- }
23
-
24
- /**
25
- * 非流式传输聊天请求
26
- * @param chatText
27
- * @param callChatOption
28
- * @param axiosOption
29
- */
30
- public async chatRequest(chatText: string | any, callChatOption: any, axiosOption: any = {}): Promise<any> {
31
- if (!chatText) {
32
- // this.emit('chaterror', { successed: false, error: 'no text in chat' });
33
- return { successed: false, error: 'no text in chat' };
34
- }
35
- const question = typeof chatText === 'object' ? chatText.text ?? chatText.content : chatText;
36
- axiosOption = Object.assign({}, axiosOption || { timeout: 60000 })
37
- const opts: any = {
38
- headers: {
39
- 'Content-Type': 'application/json',
40
- 'authorization': `Bearer ${this.apikey}`
41
- },
42
- method: 'post',
43
- url: `${this.agent.endpoint}/api/v1/agents/${this.agent.agentid}/completions`,
44
- data: {
45
- question,
46
- session_id: callChatOption.session_id,
47
- optional: callChatOption.optional,
48
- stream: false
49
- },
50
- ...axiosOption
51
- }
52
- const response = await request(opts);
53
- if (!response.successed || response.data.code) return { successed: false, error: 'failed' };
54
- const {answer:message,session_id} = response.data.data;
55
- // this.emit('chatdone', { successed: true, segment: message, text: message, finish_reason: 'stop', index: 0, session_id })
56
- return { successed: true, message:[{message:{content:message}}],session_id };
57
- }
58
- /**
59
- * 流式传输聊天请求
60
- * @param chatText
61
- * @param callChatOption
62
- * @param attach
63
- * @param axiosOption
64
- * @returns
65
- */
66
- override async chatRequestInStream(chatText: string | any, callChatOption: any, attach?: any, axiosOption?: any): Promise<any> {
67
- if (!chatText) this.emit('chaterror', { successed: false, error: 'no text in chat' });
68
- // console.log('Question===>', chatText)
69
- const question = typeof chatText === 'object' ? chatText.text??chatText.content : chatText;
70
- axiosOption = Object.assign({}, axiosOption || { timeout: 60000 })
71
- let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000);
72
- try {
73
- const opts: any = {
74
- headers: {
75
- 'Content-Type': 'application/json',
76
- 'authorization': `Bearer ${this.apikey}`
77
- },
78
- method: 'post',
79
- url: `${this.agent.endpoint}/api/v1/agents/${this.agent.agentid}/completions`,
80
- data: {
81
- question,
82
- session_id: callChatOption.session_id,
83
- stream: true,
84
- optional: callChatOption.optional,
85
- },
86
- responseType: 'stream',
87
- ...axiosOption
88
- }
89
- const response = await axios(opts);
90
- const readableStream = Readable.from(response.data);
91
- let index = 0, session_id,fullanswer='',errorKeeped=[],chunks:any=[];
92
- for await (const chunk of readableStream) {
93
- ///可能接收到的数据不完整,导致JSON.parse失败
94
- let answerData = null, jsonStr = '';
95
- try{
96
- jsonStr = chunk.toString().split('data:')
97
- if (jsonStr.length) jsonStr = jsonStr[jsonStr.length-1]+''
98
- answerData = JSON.parse(errorKeeped.join('') + jsonStr);
99
- }catch(e){
100
- ////如果发生了JSON解析错误,则当前的数据不完整,留着拼凑下一回数据
101
- // console.log('json parse error===>', errorKeeped.join('') + jsonStr)
102
- errorKeeped.push(jsonStr)
103
- // console.log('After Push===>', errorKeeped.join('') )
104
- continue;
105
- }
106
- errorKeeped = [];
107
- const { answer, running_status, reference } = answerData.data;
108
- if (running_status === true) continue;
109
- const segment = answer ? answer.replace(fullanswer,''):''
110
- fullanswer = answer ?? fullanswer;
111
- if (!session_id) session_id = answerData.data.session_id;
112
- if (reference && reference.chunks && reference.chunks.length) chunks = chunks.concat(reference.chunks)
113
- const finished = answerData.data === true;
114
- let output = { successed: true, requestid, segment: segment, chunks, text: fullanswer, finish_reason: finished ? 'stop' : null, index: index++, session_id };
115
- if (attach) output = Object.assign({}, output, attach);
116
- this.emit(finished ? 'chatdone' : 'chattext', output)
117
- }
118
- return { successed: true, requestid }
119
- } catch (error) {
120
-
121
- // this.emit('requesterror', { successed: false, requestid, error: 'call axios faied ' + error });
122
- // return { successed: false, requestid }
123
- }
124
- }
125
- }
package/src/azureai.ts DELETED
@@ -1,180 +0,0 @@
1
- /**
2
- * 微软AZure OpenAI
3
- */
4
- import OpenAIBase from "./openaibase"
5
- import { AzureOpenAIPatameters, ChatReponse, EmbeddingResult, OpenAIApiParameters} from "./declare";
6
- import { OpenAIClient, AzureKeyCredential } from "@azure/openai";
7
- export default class AzureAI extends OpenAIBase<OpenAIClient> {
8
-
9
- protected readonly azureSetting: AzureOpenAIPatameters;
10
- constructor(apiKey: string, azureOption: AzureOpenAIPatameters, apiOption: OpenAIApiParameters = {}) {
11
- super(apiKey, apiOption);
12
- this.azureSetting = azureOption;
13
- if (!this.azureSetting.endpoint.toLowerCase().startsWith('https://')) {
14
- this.azureSetting.endpoint = 'https://' + this.azureSetting.endpoint;
15
- }
16
- }
17
- /**
18
- * 初始化OpenAI 的聊天对象Api
19
- */
20
- createOpenAI(apiKey: string): OpenAIClient {
21
- return new OpenAIClient(this.azureSetting.endpoint, new AzureKeyCredential(apiKey));
22
- }
23
-
24
- get EmbeddingUrl(): string {
25
- return `${this.azureSetting.endpoint}/openai/deployments/${this.embeddingmodel || 'openai-embedding-ada-002'}/embeddings?api-version=2022-12-01`
26
- }
27
-
28
- /**
29
- * 获得文字的向量
30
- * @param text
31
- */
32
- override async getTextEmbedding(text: string|string[], callOption: any = {}): Promise<EmbeddingResult> {
33
- if (!text) return { successed: false, error: { errcode: 2, errmsg: 'content required' } };
34
- if (!this.aiApi) this.aiApi = this.createOpenAI(this.apiKey);
35
- try{
36
- const result = await this.aiApi.getEmbeddings(this.embeddingmodel || 'openai-embedding-ada-002', typeof text === 'string' ? [text] : text, callOption)
37
- return { successed: true, embedding:result.data };
38
- }
39
- // if (!axiosOption.headers)
40
- // axiosOption.headers = { 'api-key': this.apiKey, 'Content-Type': 'application/json' };
41
- // else {
42
- // axiosOption.headers['api-key'] = this.apiKey;
43
- // axiosOption.headers['Content-Type'] = 'application/json';
44
- // }
45
-
46
- // try {
47
- // let param = {
48
- // ...axiosOption,
49
- // method: "post",
50
- // data: {
51
- // input: text
52
- // },
53
- // url: this.EmbeddingUrl
54
- // };
55
- // const response = await request(param)
56
- // if (response.successed && response.data) {
57
- // return { successed: true, embedding: response.data.data[0].embedding };
58
- // }
59
- // return { successed: false, ...response.data };
60
- catch (error) {
61
- return { successed: false, error };
62
- }
63
- }
64
-
65
- /**
66
- * 非流式聊天请求
67
- * @param _chatText
68
- * @param _paramOption
69
- * @param _axiosOption
70
- */
71
- public async chatRequest(chatText: string | Array<any>, callChatOption: OpenAIApiParameters, _axiosOption: any = {}): Promise<ChatReponse> {
72
- if (!chatText) return { successed: false, error: { errcode: 2, errmsg: '缺失聊天的内容' } };
73
- if (!this.aiApi) this.aiApi = this.createOpenAI(this.apiKey);
74
-
75
- let message: Array<any> = typeof (chatText) == 'string' ?
76
- [{ role: 'user', content: chatText }] : chatText;
77
- try {
78
- const response: any = await this.aiApi.getChatCompletions(
79
- callChatOption?.model || this.chatModel,
80
- message,
81
- {
82
- temperature: Number(callChatOption?.temperature || this.temperature),
83
- maxTokens: Number(callChatOption?.maxtoken || this.maxtoken),
84
- topP: Number(callChatOption?.top_p || this.top_p),
85
- presencePenalty: Number(callChatOption?.presence_penalty || this.presence_penalty),
86
- frequencyPenalty: Number(callChatOption?.frequency_penalty || this.frequency_penalty),
87
- n: Number(callChatOption?.replyCounts || 1) || 1,
88
- tools: (callChatOption?.enableToolCall === 1 && callChatOption?.tools) ? callChatOption.tools : undefined,
89
- toolChoice: callChatOption?.enableToolCall === 1 ? 'auto' : undefined
90
- });
91
- const { promptTokens: prompt_tokens, completionTokens: completion_tokens, totalTokens: total_tokens } = response.usage
92
- let rebuildChoice = [];
93
- for (const msg of response.choices) {
94
- const { index, finishReason: finish_reason, message } = msg
95
- rebuildChoice.push({ index, finish_reason, message })
96
- }
97
- // if (response.data.choices[0].finish_reason === 'content_filter') {
98
- // console.log('content_filter');
99
- // return { successed: false, error: 'content_filter' };
100
- // }
101
- return { successed: true, message: rebuildChoice, usage: { prompt_tokens, completion_tokens, total_tokens } };
102
-
103
- } catch (error) {
104
- console.log('result is error ', error)
105
- return { successed: false, error };
106
- }
107
-
108
- }
109
-
110
- /**
111
- * 流式的聊天模式
112
- * @param chatText
113
- * @param _paramOption
114
- * @param axiosOption
115
- */
116
- override async chatRequestInStream(chatText: string | Array<any>, callChatOption: OpenAIApiParameters, attach?: any, axiosOption?: any): Promise<any> {
117
- if (!chatText) this.emit('chaterror', { successed: false, error: 'no text in chat' });
118
- if (!this.aiApi) {
119
- this.aiApi = this.createOpenAI(this.apiKey);
120
- }
121
- let message: Array<any> = typeof (chatText) == 'string' ?[{ role: 'user', content: chatText }] : chatText;
122
- axiosOption = Object.assign({}, axiosOption || { timeout: 60000 })
123
- let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000);
124
- let has_tool_calls=0,currentIndex, previous_index=-1, tool_calls:any[] = [];// 使用数组来存储工具调用
125
- try {
126
- const response: any = await this.aiApi.streamChatCompletions(
127
- callChatOption?.model || this.chatModel,
128
- message,
129
- {
130
- temperature: Number(callChatOption?.temperature || this.temperature),
131
- maxTokens: Number(callChatOption?.maxtoken || this.maxtoken),
132
- topP: Number(callChatOption?.top_p || this.top_p),
133
- presencePenalty: Number(callChatOption?.presence_penalty || this.presence_penalty),
134
- frequencyPenalty: Number(callChatOption?.frequency_penalty || this.frequency_penalty),
135
- n: Number(callChatOption?.replyCounts || 1) || 1,
136
- tools: (callChatOption?.enableToolCall===1 && callChatOption?.tools) ? callChatOption.tools : undefined,
137
- toolChoice: callChatOption?.enableToolCall === 1 ?'auto':undefined
138
- });
139
- //console.log('tools', callChatOption.enableToolCall, callChatOption.tools)
140
- let replytext: string[] = [];
141
- for await (const event of response) {
142
- for (const choice of event.choices) {
143
- const { finishReason: finishreason, index } = choice;
144
- const toolCalls = choice.delta?.toolCalls;
145
- ///存在了toolCalls
146
- if (toolCalls && toolCalls.length){
147
- currentIndex = toolCalls[0].index;
148
- has_tool_calls = 1;
149
- // 检查index是否发生变化
150
- //console.log('currentIndex,previous_index', currentIndex, previous_index)
151
- if (currentIndex !== previous_index) {
152
- tool_calls.push({
153
- id: toolCalls[0].id,
154
- type: 'function',
155
- function: {
156
- name: toolCalls[0].function.name,
157
- arguments: toolCalls[0].function.arguments
158
- }
159
- });
160
- // 更新previousIndex以供下次比较
161
- previous_index = currentIndex;
162
- } else {
163
- tool_calls[previous_index].function.arguments += toolCalls[0].function.arguments
164
- }
165
- }else{
166
- const content = choice.delta?.content;
167
- replytext.push(content);
168
- }
169
- let output = { successed: true, requestid, segment: choice.delta?.content, text: replytext.join(''), finish_reason: finishreason, index, has_tool_calls: has_tool_calls, tool_calls: tool_calls };
170
- if (attach) output = Object.assign({}, output, attach);
171
- this.emit(finishreason ? 'chatdone' : 'chattext', output)
172
- }
173
- }
174
- return { successed: true, requestid }
175
- } catch (error) {
176
- this.emit('requesterror', { successed: false, requestid, error: 'call axios faied ' +error });
177
- return { successed: false, requestid }
178
- }
179
- }
180
- }
package/src/baiduai.ts DELETED
@@ -1,86 +0,0 @@
1
- import { ApiResult, CacheProvider, request } from "./declare";
2
- import GptBase from "./gptbase"
3
- const TOKEN_CACHE_KEY = "key:_doomisoft:baiduwenxin:"
4
- export default class BaiduWenXinAI extends GptBase {
5
-
6
- protected credential: ApiCredential;
7
- private Cacher: CacheProvider|undefined;
8
- /**
9
- *
10
- * @param credential 调用OpenAI 的key
11
- * @param cacher 用作accesstoken的缓存
12
- * @param apiOption 用作accesstoken的缓存
13
- */
14
- constructor(credential: ApiCredential, cacher?:CacheProvider) {
15
- super();
16
- this.credential = credential;
17
- this.Cacher = cacher;
18
- }
19
- /**
20
- * 获取调用Api的Token
21
- */
22
- async getAccessToken():Promise<AccessTokenResult>{
23
- ////如果当前应用是一个委托到第三方的
24
- ///公众号或小程序,则需要用关联的第三方平台来获取api调用的accesstoken
25
- ////如果是需要缓存token,则首先看缓存中是否有AccessToken
26
- const accesstoken = this.Cacher ? (await this.Cacher.get(TOKEN_CACHE_KEY+this.credential.apikey)):null;
27
- if (accesstoken) return { successed: true, access_token: accesstoken };
28
- const option = {
29
- url: `https://wenxin.baidu.com/moduleApi/portal/api/oauth/token?grant_type=client_credentials&client_id=${this.credential.apikey}&client_secret=${this.credential.securitykey}`,
30
- method:"post",
31
- };
32
- const tokenData = await request(option);
33
- if (tokenData.successed == true && !tokenData.data.code) {
34
- ///把api accesstoken缓存起来
35
- if (this.Cacher){
36
- this.Cacher.set(TOKEN_CACHE_KEY + this.credential.apikey, tokenData.data.data,3600*20);
37
- }
38
- return { successed: true, access_token: tokenData.data.data };
39
- }
40
- return { successed: false, error: tokenData.data.msg }
41
- }
42
-
43
- /**
44
- * 请求GPT接口
45
- */
46
- public async chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption: any = {}): Promise<ApiResult> {
47
- console.log('call baidu')
48
- if (!chatText) return { successed: false, error: { errcode: 2, errmsg: '缺失聊天的内容' } };
49
- const accessToken = await this.getAccessToken();
50
- if (!accessToken.successed || !accessToken.access_token) return {successed:false,error:'accesstoken get failed'}
51
- try {
52
- let param = {
53
- ...axiosOption,
54
- method: "post",
55
- data: {
56
- text: `问题:${chatText}\n回答:`,
57
- seq_len: 512,
58
- topp: 0.5,
59
- penalty_score: 1.2,
60
- min_dec_len: 12,
61
- min_dec_penalty_text: "。?:![<S>]",
62
- task_prompt: "qa",
63
- mask_type: "paragraph"
64
- },
65
- url:`https://wenxin.baidu.com/moduleApi/portal/api/rest/1.0/ernie/3.0.25/zeus?access_token=${accessToken.access_token}`
66
- };
67
- console.log('param', param)
68
- const response = await request(param)
69
- if (response.successed && !response.data.code) {
70
- return { successed: true, ...response.data };
71
- }
72
- return { successed: false, ...response.data };
73
- } catch (error) {
74
- console.log('result is error ', error)
75
- return { successed: false, error };
76
- }
77
-
78
- }
79
- }
80
- export interface AccessTokenResult extends ApiResult {
81
- 'access_token'?: string
82
- }
83
- export interface ApiCredential{
84
- 'apikey':string,
85
- 'securitykey': string
86
- }
@@ -1,59 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { getJWTToken, COZE_CN_BASE_URL } from '@coze/api';
4
- export class CorzAuthorization {
5
- private accessToken: string | null |undefined;
6
- private expiresAt: number = 0;
7
- private pemfile: string;
8
- private secret: string;
9
- private sessionName: string;
10
- constructor(public appid: string,setting:Record<string,any>) {
11
- this.secret = setting["keyid"];
12
- this.pemfile = setting["pemfile"] || "private.pem"
13
- this.sessionName = setting["sessionName"] || "default";
14
- }
15
- /**
16
- * 获取授权令牌
17
- * @returns
18
- */
19
- async getAccessToken():Promise<string|null> {
20
- // 检查令牌是否存在且未过期,如果有效直接放回
21
- if (this.accessToken && Date.now() < this.expiresAt) return this.accessToken;
22
- // 开始新的授权
23
- const result = await this.doAuthorize();
24
- if (!result.successed) return null;
25
- // 缓存授权令牌和过期时间
26
- this.accessToken = result.accessToken!;
27
- // 将 expires_in 转换为绝对时间戳
28
- this.expiresAt = result.expires_in! * 1000; // 将秒转换为毫秒
29
- return this.accessToken;
30
- }
31
- /**
32
- * 进行授权
33
- * @returns
34
- */
35
- private async doAuthorize(): Promise<{ successed: boolean, accessToken?: string, expires_in?: number,error?:any }> {
36
- try {
37
- // 提取您的 COZE API 授权参数
38
- //const keyid = "H7rAk-5s0TPOs9-rXnCr7pvkPhpJZGArT__UuMyhbkg";
39
- const aud = "api.coze.cn";
40
- // 读取私钥
41
- const fileFullPath =path.join(process.cwd(), this.pemfile);
42
- if (!fs.existsSync(fileFullPath)) return { successed: false, error: `${fileFullPath} not existed`}
43
- const privateKey = fs.readFileSync(fileFullPath).toString();
44
-
45
- // 获取JWT令牌
46
- const result = await getJWTToken({
47
- baseURL: COZE_CN_BASE_URL,
48
- appId:this.appid,
49
- aud,
50
- keyid:this.secret,
51
- privateKey,
52
- sessionName:this.sessionName,
53
- });
54
- return {successed: true, accessToken: result.access_token, expires_in: result.expires_in}
55
- } catch (error) {
56
- return { successed: true, error }
57
- }
58
- }
59
- }