doomiaichat 2.1.0 → 2.2.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/azureai.js CHANGED
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const axios_1 = __importDefault(require("axios"));
15
+ const declare_1 = require("./declare");
16
16
  const openai_1 = __importDefault(require("./openai"));
17
17
  class AzureAI extends openai_1.default {
18
18
  constructor(apiKey, azureOption, apiOption = {}) {
@@ -44,20 +44,14 @@ class AzureAI extends openai_1.default {
44
44
  }
45
45
  let messages = typeof (chatText) == 'string' ?
46
46
  [{ role: 'user', content: chatText }] : chatText;
47
- //let axios = new Axios(axiosOption)
48
47
  try {
49
- // const response = await axios.post(this.BaseUrl, {
50
- // messages,
51
- // temperature: Number(paramOption?.temperature || this.temperature),
52
- // max_tokens: Number(paramOption?.maxtoken || this.maxtoken),
53
- // })
54
48
  let param = Object.assign(Object.assign({}, axiosOption), { method: "post", data: {
55
49
  messages,
56
50
  temperature: Number((paramOption === null || paramOption === void 0 ? void 0 : paramOption.temperature) || this.temperature),
57
51
  max_tokens: Number((paramOption === null || paramOption === void 0 ? void 0 : paramOption.maxtoken) || this.maxtoken),
58
52
  }, url: this.BaseUrl });
59
- console.log('axiosOption', param);
60
- const response = yield (0, axios_1.default)(param);
53
+ // console.log('axiosOption', param)
54
+ const response = yield (0, declare_1.request)(param);
61
55
  if (response.data.choices) {
62
56
  return { successed: true, message: response.data.choices };
63
57
  }
@@ -0,0 +1,34 @@
1
+ import { EmotionResult, SimilarityResult, ChatReponse, SummaryReponse, ExaminationPaperResult, ApiResult, CacheProvider } from "./declare";
2
+ import GptBase from "./gptbase";
3
+ export default class BaiduWenXinAI extends GptBase {
4
+ protected credential: ApiCredential;
5
+ private Cacher;
6
+ /**
7
+ *
8
+ * @param credential 调用OpenAI 的key
9
+ * @param cacher 用作accesstoken的缓存
10
+ * @param apiOption 用作accesstoken的缓存
11
+ */
12
+ constructor(credential: ApiCredential, cacher?: CacheProvider);
13
+ /**
14
+ * 获取调用Api的Token
15
+ */
16
+ getAccessToken(): Promise<AccessTokenResult>;
17
+ /**
18
+ * 请求GPT接口
19
+ */
20
+ chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption?: any): Promise<ApiResult>;
21
+ getScentenceEmotional(_s1: string, _axiosOption: any): Promise<EmotionResult>;
22
+ getScentenseSimilarity(_s1: string, _s2: string, _axiosOption: any): Promise<SimilarityResult>;
23
+ getSimilarityContent(_content: string, _count: number, _axiosOption: any): Promise<ChatReponse>;
24
+ getSummaryOfContent(_content: string | any[], _axiosOption: any): Promise<SummaryReponse>;
25
+ generateQuestionsFromContent(_content: string, _count: number, _axiosOption: any): Promise<ChatReponse>;
26
+ generateExaminationPaperFromContent(_content: string, _paperOption: any, _axiosOption: any): Promise<ExaminationPaperResult>;
27
+ }
28
+ export interface AccessTokenResult extends ApiResult {
29
+ 'access_token'?: string;
30
+ }
31
+ export interface ApiCredential {
32
+ 'apikey': string;
33
+ 'securitykey': string;
34
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const declare_1 = require("./declare");
16
+ const gptbase_1 = __importDefault(require("./gptbase"));
17
+ const TOKEN_CACHE_KEY = "key:_doomisoft:baiduwenxin:";
18
+ class BaiduWenXinAI extends gptbase_1.default {
19
+ /**
20
+ *
21
+ * @param credential 调用OpenAI 的key
22
+ * @param cacher 用作accesstoken的缓存
23
+ * @param apiOption 用作accesstoken的缓存
24
+ */
25
+ constructor(credential, cacher) {
26
+ super();
27
+ this.credential = credential;
28
+ this.Cacher = cacher;
29
+ }
30
+ /**
31
+ * 获取调用Api的Token
32
+ */
33
+ getAccessToken() {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ ////如果当前应用是一个委托到第三方的
36
+ ///公众号或小程序,则需要用关联的第三方平台来获取api调用的accesstoken
37
+ ////如果是需要缓存token,则首先看缓存中是否有AccessToken
38
+ const accesstoken = this.Cacher ? (yield this.Cacher.get(TOKEN_CACHE_KEY + this.credential.apikey)) : null;
39
+ if (accesstoken)
40
+ return { successed: true, access_token: accesstoken };
41
+ const option = {
42
+ url: `https://wenxin.baidu.com/moduleApi/portal/api/oauth/token?grant_type=client_credentials&client_id=${this.credential.apikey}&client_secret=${this.credential.securitykey}`,
43
+ method: "post",
44
+ };
45
+ const tokenData = yield (0, declare_1.request)(option);
46
+ if (tokenData.successed == true && !tokenData.data.code) {
47
+ ///把api accesstoken缓存起来
48
+ if (this.Cacher) {
49
+ this.Cacher.set(TOKEN_CACHE_KEY + this.credential.apikey, tokenData.data.data, 3600 * 20);
50
+ }
51
+ return { successed: true, access_token: tokenData.data.data };
52
+ }
53
+ return { successed: false, error: tokenData.data.msg };
54
+ });
55
+ }
56
+ /**
57
+ * 请求GPT接口
58
+ */
59
+ chatRequest(chatText, _paramOption, axiosOption = {}) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ console.log('call baidu');
62
+ if (!chatText)
63
+ return { successed: false, error: { errcode: 2, errmsg: '缺失聊天的内容' } };
64
+ const accessToken = yield this.getAccessToken();
65
+ if (!accessToken.successed || !accessToken.access_token)
66
+ return { successed: false, error: 'accesstoken get failed' };
67
+ try {
68
+ let param = Object.assign(Object.assign({}, axiosOption), { method: "post", data: {
69
+ text: `问题:${chatText}\n回答:`,
70
+ seq_len: 512,
71
+ topp: 0.5,
72
+ penalty_score: 1.2,
73
+ min_dec_len: 12,
74
+ min_dec_penalty_text: "。?:![<S>]",
75
+ task_prompt: "qa",
76
+ mask_type: "paragraph"
77
+ }, url: `https://wenxin.baidu.com/moduleApi/portal/api/rest/1.0/ernie/3.0.25/zeus?access_token=${accessToken.access_token}` });
78
+ console.log('param', param);
79
+ const response = yield (0, declare_1.request)(param);
80
+ if (response.successed && !response.data.code) {
81
+ return Object.assign({ successed: true }, response.data);
82
+ }
83
+ return Object.assign({ successed: false }, response.data);
84
+ }
85
+ catch (error) {
86
+ console.log('result is error ', error);
87
+ return { successed: false, error };
88
+ }
89
+ });
90
+ }
91
+ getScentenceEmotional(_s1, _axiosOption) {
92
+ throw new Error("Method not implemented.");
93
+ }
94
+ getScentenseSimilarity(_s1, _s2, _axiosOption) {
95
+ throw new Error("Method not implemented.");
96
+ }
97
+ getSimilarityContent(_content, _count, _axiosOption) {
98
+ throw new Error("Method not implemented.");
99
+ }
100
+ getSummaryOfContent(_content, _axiosOption) {
101
+ throw new Error("Method not implemented.");
102
+ }
103
+ generateQuestionsFromContent(_content, _count, _axiosOption) {
104
+ throw new Error("Method not implemented.");
105
+ }
106
+ generateExaminationPaperFromContent(_content, _paperOption, _axiosOption) {
107
+ throw new Error("Method not implemented.");
108
+ }
109
+ }
110
+ exports.default = BaiduWenXinAI;
package/dist/declare.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- interface ApiResult {
1
+ export interface ApiResult {
2
2
  /**
3
3
  * return the result of api called
4
4
  * @type {boolean}
@@ -96,4 +96,36 @@ export interface SimilarityResult extends ApiResult {
96
96
  export interface EmotionResult extends ApiResult {
97
97
  'emotion'?: string;
98
98
  }
99
- export {};
99
+ /**
100
+ * 远程请求的返回
101
+ */
102
+ export interface RpcResult extends ApiResult {
103
+ 'data'?: any;
104
+ }
105
+ /**
106
+ * Axios远程请求封装
107
+ * @param opts
108
+ * @returns
109
+ */
110
+ export declare function request(opts?: any): Promise<RpcResult>;
111
+ /**
112
+ * 数据缓存提供者接口
113
+ */
114
+ export interface CacheProvider {
115
+ /**
116
+ * 缓存数据
117
+ * @param key 数据的键名称
118
+ * @param value 数据的键值
119
+ */
120
+ set(key: string, value: string | object, exp?: number): void;
121
+ /**
122
+ * 从缓存中读取数据
123
+ * @param key 数据的键名称
124
+ */
125
+ get(key: string): Promise<string | null>;
126
+ /**
127
+ * 删除缓存信息
128
+ * @param key 数据的键名称
129
+ */
130
+ delete(key: string): void;
131
+ }
package/dist/declare.js CHANGED
@@ -1,2 +1,35 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.request = void 0;
16
+ const axios_1 = __importDefault(require("axios"));
17
+ /**
18
+ * Axios远程请求封装
19
+ * @param opts
20
+ * @returns
21
+ */
22
+ function request(opts = {}) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ if (!opts.data)
25
+ opts.data = opts.body;
26
+ try {
27
+ let result = yield (0, axios_1.default)(opts);
28
+ return { successed: true, data: result.data };
29
+ }
30
+ catch (err) {
31
+ return { successed: false, error: err };
32
+ }
33
+ });
34
+ }
35
+ exports.request = request;
@@ -0,0 +1,56 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from "events";
3
+ import { ChatReponse, SummaryReponse, ExaminationPaperResult, EmotionResult, SimilarityResult, ApiResult } from './declare';
4
+ export default abstract class GptBase extends EventEmitter {
5
+ /**
6
+ * 构造函数
7
+ */
8
+ constructor();
9
+ /**
10
+ * 自由聊天模式
11
+ * @param chatText
12
+ * @param _paramOption
13
+ * @param axiosOption
14
+ */
15
+ abstract chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption: any): Promise<ApiResult>;
16
+ /**
17
+ * 获取句子的情感
18
+ * @param s1
19
+ * @param axiosOption
20
+ */
21
+ abstract getScentenceEmotional(s1: string, axiosOption: any): Promise<EmotionResult>;
22
+ /**
23
+ * 获取两段文本的相似度
24
+ * @param s1
25
+ * @param s2
26
+ * @param axiosOption
27
+ */
28
+ abstract getScentenseSimilarity(s1: string, s2: string, axiosOption: any): Promise<SimilarityResult>;
29
+ /**
30
+ * 获取一段文本的相似内容
31
+ * @param content
32
+ * @param count
33
+ * @param axiosOption
34
+ */
35
+ abstract getSimilarityContent(content: string, count: number, axiosOption: any): Promise<ChatReponse>;
36
+ /**
37
+ * 获取内容的摘要
38
+ * @param content
39
+ * @param axiosOption
40
+ */
41
+ abstract getSummaryOfContent(content: string | Array<any>, axiosOption: any): Promise<SummaryReponse>;
42
+ /**
43
+ * 从内容中提取问题和答案及管件子
44
+ * @param content
45
+ * @param count
46
+ * @param axiosOption
47
+ */
48
+ abstract generateQuestionsFromContent(content: string, count: number, axiosOption: any): Promise<ChatReponse>;
49
+ /**
50
+ * 从内容中提取单选多选判断填空题
51
+ * @param content
52
+ * @param paperOption
53
+ * @param axiosOption
54
+ */
55
+ abstract generateExaminationPaperFromContent(content: string, paperOption: any, axiosOption: any): Promise<ExaminationPaperResult>;
56
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const events_1 = require("events");
4
+ class GptBase extends events_1.EventEmitter {
5
+ /**
6
+ * 构造函数
7
+ */
8
+ constructor() {
9
+ super();
10
+ }
11
+ }
12
+ exports.default = GptBase;
@@ -0,0 +1,20 @@
1
+ import { ApiCredential } from './baiduai';
2
+ import GptBase from './gptbase';
3
+ /**
4
+ * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
5
+ */
6
+ export declare const GptProviderEnum: {
7
+ readonly OPENAI: "openai";
8
+ readonly MICROSOFT: "microsoft";
9
+ readonly BAIDU: "baidu";
10
+ readonly GOOGLE: "google";
11
+ };
12
+ export type GptProviderEnum = typeof GptProviderEnum[keyof typeof GptProviderEnum];
13
+ /**
14
+ * 根据类型创建不同的TTS引擎对象
15
+ * @param {*} provider
16
+ * @param {*} apikey
17
+ * @param {*} setting
18
+ * @returns
19
+ */
20
+ export declare function createGpt(provider: GptProviderEnum, apikey: string | ApiCredential, setting: any): GptBase | null;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createGpt = exports.GptProviderEnum = void 0;
7
+ //ts check
8
+ /**
9
+ * 语音转文字服务商工厂
10
+ */
11
+ const openai_1 = __importDefault(require("./openai"));
12
+ const azureai_1 = __importDefault(require("./azureai"));
13
+ const baiduai_1 = __importDefault(require("./baiduai"));
14
+ /**
15
+ * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
16
+ */
17
+ exports.GptProviderEnum = {
18
+ OPENAI: 'openai',
19
+ MICROSOFT: 'microsoft',
20
+ BAIDU: 'baidu',
21
+ GOOGLE: 'google'
22
+ };
23
+ /**
24
+ * 根据类型创建不同的TTS引擎对象
25
+ * @param {*} provider
26
+ * @param {*} apikey
27
+ * @param {*} setting
28
+ * @returns
29
+ */
30
+ function createGpt(provider, apikey, setting) {
31
+ let { model, maxtoken, temperature, endpoint, engine, version } = setting || {};
32
+ switch (provider) {
33
+ case exports.GptProviderEnum.OPENAI:
34
+ return new openai_1.default(apikey + '', { model, maxtoken, temperature });
35
+ case exports.GptProviderEnum.MICROSOFT:
36
+ return new azureai_1.default(apikey + '', { endpoint, engine, version }, { model, maxtoken, temperature });
37
+ case exports.GptProviderEnum.BAIDU:
38
+ let cred = typeof (apikey) === 'string' ? { apikey, securitykey: apikey } : apikey;
39
+ return new baiduai_1.default(cred);
40
+ default: return null;
41
+ }
42
+ }
43
+ exports.createGpt = createGpt;
44
+ ;
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export * as AIFactory from "./openaiprovider";
1
+ export * as GptFactory from "./gptprovider";
2
+ export * as GptBase from "./gptbase";
package/dist/index.js CHANGED
@@ -23,5 +23,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.AIFactory = void 0;
27
- exports.AIFactory = __importStar(require("./openaiprovider"));
26
+ exports.GptBase = exports.GptFactory = void 0;
27
+ exports.GptFactory = __importStar(require("./gptprovider"));
28
+ exports.GptBase = __importStar(require("./gptbase"));
package/dist/openai.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- /// <reference types="node" />
2
1
  import { OpenAIApi, ChatCompletionRequestMessage } from "openai";
3
- import { EventEmitter } from "events";
2
+ import GptBase from "./gptbase";
4
3
  import { OpenAIApiParameters, ChatReponse, SummaryReponse, FaqItem, ExaminationPaperResult, EmotionResult, SimilarityResult, QuestionItem } from './declare';
5
- export default class OpenAIGpt extends EventEmitter {
4
+ export default class OpenAIGpt extends GptBase {
6
5
  protected readonly apiKey: string;
7
6
  private aiApi;
8
7
  protected readonly chatModel: string;
package/dist/openai.js CHANGED
@@ -8,9 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  const openai_1 = require("openai");
13
- const events_1 = require("events");
16
+ // import { EventEmitter } from "events";
17
+ const gptbase_1 = __importDefault(require("./gptbase"));
14
18
  const SECTION_LENGTH = 1600; ///每2400个字符分成一组
15
19
  const MESSAGE_LENGTH = 1; ///每次送8句话给openai 进行解析,送多了,会报错
16
20
  //请将答案放在最后,标记为答案:()
@@ -21,7 +25,7 @@ const QUESTION_TEXT_MAPPING = {
21
25
  completion: '你是一名专业的出题老师,根据以下内容,请生成@ITEMCOUNT@道填空题和对应答案,输出结果必须是JSON数组并按照[{"question":"","answer":["填空答案1","填空答案2"]}]的结构输出' //请将答案放在最后,标记为答案:()
22
26
  };
23
27
  const QUESTION_TYPE = ['singlechoice', 'multiplechoice', 'trueorfalse', 'completion'];
24
- class OpenAIGpt extends events_1.EventEmitter {
28
+ class OpenAIGpt extends gptbase_1.default {
25
29
  /**
26
30
  *
27
31
  * @param apiKey 调用OpenAI 的key
@@ -195,7 +199,7 @@ class OpenAIGpt extends events_1.EventEmitter {
195
199
  //subarray.push({ role: 'user', content:'请根据上述内容,给出一道提问与答案以及答案关键词,按照先问题内容,再标准答案,再关键词的顺序输出,关键词之间用、分开'})
196
200
  subarray.unshift({ role: 'system', content: `你是一位专业培训师,从以下内容中提取${itemCount}条提问及答案,并从答案内容提取出至少2个关键词,最终结果按照[{"question":"提问内容","answer":"答案内容","keywords":["关键词1","关键词2"]}]的JSON数组结构输出。` });
197
201
  //subarray.unshift({ role: 'system', content: `你是一位专业程序开发工程师,根据以下内容,按照[{"question":"问题内容","answer":"答案内容","keywords":["关键词1","关键词2"]}]JSON数组结构,给出${itemCount}条提问问题及答案以及答案关键词` })
198
- console.log('subarray', subarray);
202
+ // console.log('subarray', subarray)
199
203
  let result = yield this.chatRequest(subarray, { replyCounts: 1 }, axiosOption);
200
204
  if (result.successed && result.message) {
201
205
  // console.log('result is ', result.message[0].message.content)
@@ -213,7 +217,7 @@ class OpenAIGpt extends events_1.EventEmitter {
213
217
  arrContent = []; /// 释放内存
214
218
  ///发出信号,解析完毕
215
219
  this.emit('parseover', { type: 'qa', items: faqs });
216
- return { successed: true, message: faqs };
220
+ return { successed: true, message: faqs.slice(0, count) };
217
221
  });
218
222
  }
219
223
  /**
@@ -433,42 +437,6 @@ class OpenAIGpt extends events_1.EventEmitter {
433
437
  console.log('error happened:', err);
434
438
  }
435
439
  return returnItems.filter(i => { return i != null; }).slice(0, count);
436
- // let item = result.map(m => {
437
- // ////防止输出的JSON格式不合法
438
- // try {
439
- // let jsonObj = JSON.parse(m.message.content)
440
- // jsonObj.score = score;
441
- // if (jsonObj.choice && Array.isArray(jsonObj.choice) && questiontype != 'completion') {
442
- // jsonObj.fullanswer = (jsonObj.answer + '').replace(/,|[^ABCDE]/g, '');
443
- // jsonObj.choice = jsonObj.choice.map((item:string, index:number) => {
444
- // let seqNo = String.fromCharCode(65 + index);
445
- // let correctReg = new RegExp(`${seqNo}.|${seqNo}`, 'ig')
446
- // //let answer = jsonObj.fullanswer
447
- // return {
448
- // id: seqNo,
449
- // content: item.replace(correctReg, '').trim(),
450
- // iscorrect: (jsonObj.fullanswer.indexOf(seqNo) >= 0 || jsonObj.fullanswer.indexOf(m)) >= 0 ? 1 : 0
451
- // }
452
- // })
453
- // }
454
- // switch (questiontype) {
455
- // case 'singlechoice':
456
- // jsonObj.answer = (jsonObj.answer + '').replace(/,|[^ABCDEFG]/g, '').split('').slice(0, 1);
457
- // break;
458
- // case 'multiplechoice':
459
- // jsonObj.answer = (jsonObj.answer + '').replace(/,|[^ABCDEFG]/g, '').split('');
460
- // break;
461
- // case 'trueorfalse':
462
- // jsonObj.answer = [(jsonObj.answer + '').indexOf('正确') >= 0 ? 'A' : 'B']
463
- // break;
464
- // }
465
- // return jsonObj;
466
- // } catch (err) {
467
- // console.log('error happened:', err);
468
- // return null;
469
- // }
470
- // })
471
- // return item.filter(i => { return i != null; });
472
440
  }
473
441
  /**
474
442
  * 将一段很长的文本,按1024长度来划分到多个中
@@ -1,7 +1,5 @@
1
- /**
2
- * 语音转文字服务商工厂
3
- */
4
- import OpenAIGpt from './openai';
1
+ import { ApiCredential } from './baiduai';
2
+ import GptBase from './gptbase';
5
3
  /**
6
4
  * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
7
5
  */
@@ -19,4 +17,4 @@ export type AIProviderEnum = typeof AIProviderEnum[keyof typeof AIProviderEnum];
19
17
  * @param {*} setting
20
18
  * @returns
21
19
  */
22
- export declare function createAIInstance(provider: AIProviderEnum, apikey: string, setting: any): OpenAIGpt | null;
20
+ export declare function createAIInstance(provider: AIProviderEnum, apikey: string | ApiCredential, setting: any): GptBase | null;
@@ -9,6 +9,7 @@ exports.createAIInstance = exports.AIProviderEnum = void 0;
9
9
  */
10
10
  const openai_1 = __importDefault(require("./openai"));
11
11
  const azureai_1 = __importDefault(require("./azureai"));
12
+ const baiduai_1 = __importDefault(require("./baiduai"));
12
13
  /**
13
14
  * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
14
15
  */
@@ -26,12 +27,15 @@ exports.AIProviderEnum = {
26
27
  * @returns
27
28
  */
28
29
  function createAIInstance(provider, apikey, setting) {
29
- let { model, maxtoken, temperature, endpoint, engine, version } = setting;
30
+ let { model, maxtoken, temperature, endpoint, engine, version } = setting || {};
30
31
  switch (provider) {
31
32
  case exports.AIProviderEnum.OPENAI:
32
- return new openai_1.default(apikey, { model, maxtoken, temperature });
33
+ return new openai_1.default(apikey + '', { model, maxtoken, temperature });
33
34
  case exports.AIProviderEnum.MICROSOFT:
34
- return new azureai_1.default(apikey, { endpoint, engine, version }, { model, maxtoken, temperature });
35
+ return new azureai_1.default(apikey + '', { endpoint, engine, version }, { model, maxtoken, temperature });
36
+ case exports.AIProviderEnum.BAIDU:
37
+ let cred = typeof (apikey) === 'string' ? { apikey, securitykey: apikey } : apikey;
38
+ return new baiduai_1.default(cred);
35
39
  default: return null;
36
40
  }
37
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doomiaichat",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Doomisoft OpenAI",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/azureai.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { AzureOpenAIPatameters, ChatReponse, OpenAIApiParameters } from "./declare";
2
- import axios from 'axios';
1
+ import { AzureOpenAIPatameters, ChatReponse, OpenAIApiParameters, request } from "./declare";
3
2
  import OpenAIGpt from "./openai"
4
3
  import { ChatCompletionRequestMessage } from "openai";
5
4
  export default class AzureAI extends OpenAIGpt {
@@ -32,13 +31,7 @@ export default class AzureAI extends OpenAIGpt {
32
31
 
33
32
  let messages: Array<ChatCompletionRequestMessage> = typeof (chatText) == 'string' ?
34
33
  [{ role: 'user', content: chatText }] : chatText;
35
- //let axios = new Axios(axiosOption)
36
34
  try{
37
- // const response = await axios.post(this.BaseUrl, {
38
- // messages,
39
- // temperature: Number(paramOption?.temperature || this.temperature),
40
- // max_tokens: Number(paramOption?.maxtoken || this.maxtoken),
41
- // })
42
35
  let param = {
43
36
  ...axiosOption,
44
37
  method: "post",
@@ -49,9 +42,8 @@ export default class AzureAI extends OpenAIGpt {
49
42
  },
50
43
  url: this.BaseUrl
51
44
  };
52
- console.log('axiosOption', param)
53
-
54
- const response = await axios(param)
45
+ // console.log('axiosOption', param)
46
+ const response =await request(param)
55
47
  if (response.data.choices){
56
48
  return { successed: true, message: response.data.choices };
57
49
  }
package/src/baiduai.ts ADDED
@@ -0,0 +1,103 @@
1
+ import { EmotionResult, SimilarityResult, ChatReponse, SummaryReponse, ExaminationPaperResult, 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
+ protected credential: ApiCredential;
6
+ private Cacher: CacheProvider|undefined;
7
+ /**
8
+ *
9
+ * @param credential 调用OpenAI 的key
10
+ * @param cacher 用作accesstoken的缓存
11
+ * @param apiOption 用作accesstoken的缓存
12
+ */
13
+ constructor(credential: ApiCredential, cacher?:CacheProvider) {
14
+ super();
15
+ this.credential = credential;
16
+ this.Cacher = cacher;
17
+ }
18
+ /**
19
+ * 获取调用Api的Token
20
+ */
21
+ async getAccessToken():Promise<AccessTokenResult>{
22
+ ////如果当前应用是一个委托到第三方的
23
+ ///公众号或小程序,则需要用关联的第三方平台来获取api调用的accesstoken
24
+ ////如果是需要缓存token,则首先看缓存中是否有AccessToken
25
+ const accesstoken = this.Cacher ? (await this.Cacher.get(TOKEN_CACHE_KEY+this.credential.apikey)):null;
26
+ if (accesstoken) return { successed: true, access_token: accesstoken };
27
+ const option = {
28
+ url: `https://wenxin.baidu.com/moduleApi/portal/api/oauth/token?grant_type=client_credentials&client_id=${this.credential.apikey}&client_secret=${this.credential.securitykey}`,
29
+ method:"post",
30
+ };
31
+ const tokenData = await request(option);
32
+ if (tokenData.successed == true && !tokenData.data.code) {
33
+ ///把api accesstoken缓存起来
34
+ if (this.Cacher){
35
+ this.Cacher.set(TOKEN_CACHE_KEY + this.credential.apikey, tokenData.data.data,3600*20);
36
+ }
37
+ return { successed: true, access_token: tokenData.data.data };
38
+ }
39
+ return { successed: false, error: tokenData.data.msg }
40
+ }
41
+ /**
42
+ * 请求GPT接口
43
+ */
44
+ public async chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption: any = {}): Promise<ApiResult> {
45
+ console.log('call baidu')
46
+ if (!chatText) return { successed: false, error: { errcode: 2, errmsg: '缺失聊天的内容' } };
47
+ const accessToken = await this.getAccessToken();
48
+ if (!accessToken.successed || !accessToken.access_token) return {successed:false,error:'accesstoken get failed'}
49
+ try {
50
+ let param = {
51
+ ...axiosOption,
52
+ method: "post",
53
+ data: {
54
+ text: `问题:${chatText}\n回答:`,
55
+ seq_len: 512,
56
+ topp: 0.5,
57
+ penalty_score: 1.2,
58
+ min_dec_len: 12,
59
+ min_dec_penalty_text: "。?:![<S>]",
60
+ task_prompt: "qa",
61
+ mask_type: "paragraph"
62
+ },
63
+ url:`https://wenxin.baidu.com/moduleApi/portal/api/rest/1.0/ernie/3.0.25/zeus?access_token=${accessToken.access_token}`
64
+ };
65
+ console.log('param', param)
66
+ const response = await request(param)
67
+ if (response.successed && !response.data.code) {
68
+ return { successed: true, ...response.data };
69
+ }
70
+ return { successed: false, ...response.data };
71
+ } catch (error) {
72
+ console.log('result is error ', error)
73
+ return { successed: false, error };
74
+ }
75
+
76
+ }
77
+ getScentenceEmotional(_s1: string, _axiosOption: any): Promise<EmotionResult> {
78
+ throw new Error("Method not implemented.");
79
+ }
80
+ getScentenseSimilarity(_s1: string, _s2: string, _axiosOption: any): Promise<SimilarityResult> {
81
+ throw new Error("Method not implemented.");
82
+ }
83
+ getSimilarityContent(_content: string, _count: number, _axiosOption: any): Promise<ChatReponse> {
84
+ throw new Error("Method not implemented.");
85
+ }
86
+ getSummaryOfContent(_content: string | any[], _axiosOption: any): Promise<SummaryReponse> {
87
+ throw new Error("Method not implemented.");
88
+ }
89
+ generateQuestionsFromContent(_content: string, _count: number, _axiosOption: any): Promise<ChatReponse> {
90
+ throw new Error("Method not implemented.");
91
+ }
92
+ generateExaminationPaperFromContent(_content: string, _paperOption: any, _axiosOption: any): Promise<ExaminationPaperResult> {
93
+ throw new Error("Method not implemented.");
94
+ }
95
+
96
+ }
97
+ export interface AccessTokenResult extends ApiResult {
98
+ 'access_token'?: string
99
+ }
100
+ export interface ApiCredential{
101
+ 'apikey':string,
102
+ 'securitykey': string
103
+ }
package/src/declare.ts CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
- interface ApiResult {
2
+ import axios from 'axios';
3
+ export interface ApiResult {
3
4
  /**
4
5
  * return the result of api called
5
6
  * @type {boolean}
@@ -102,4 +103,51 @@ export interface SimilarityResult extends ApiResult {
102
103
  */
103
104
  export interface EmotionResult extends ApiResult {
104
105
  'emotion'?: string; ///情绪
106
+ }
107
+ /**
108
+ * 远程请求的返回
109
+ */
110
+ export interface RpcResult extends ApiResult {
111
+ 'data'?: any;
112
+ }
113
+
114
+ /**
115
+ * Axios远程请求封装
116
+ * @param opts
117
+ * @returns
118
+ */
119
+ export async function request(opts: any = {}): Promise<RpcResult> {
120
+ if (!opts.data) opts.data = opts.body;
121
+ try {
122
+ let result = await axios(opts);
123
+ return { successed: true, data: result.data }
124
+ } catch (err) {
125
+ return { successed: false, error: err }
126
+ }
127
+ }
128
+
129
+
130
+ /**
131
+ * 数据缓存提供者接口
132
+ */
133
+ export interface CacheProvider {
134
+ /**
135
+ * 缓存数据
136
+ * @param key 数据的键名称
137
+ * @param value 数据的键值
138
+ */
139
+ set(key: string, value: string | object, exp?: number): void;
140
+ /**
141
+ * 从缓存中读取数据
142
+ * @param key 数据的键名称
143
+ */
144
+ get(key: string): Promise<string | null>;
145
+
146
+
147
+ /**
148
+ * 删除缓存信息
149
+ * @param key 数据的键名称
150
+ */
151
+ delete(key: string): void;
152
+
105
153
  }
package/src/gptbase.ts ADDED
@@ -0,0 +1,58 @@
1
+ import { EventEmitter } from "events"
2
+ import { ChatReponse, SummaryReponse, ExaminationPaperResult, EmotionResult, SimilarityResult, ApiResult } from './declare'
3
+
4
+ export default abstract class GptBase extends EventEmitter {
5
+ /**
6
+ * 构造函数
7
+ */
8
+ constructor() {
9
+ super();
10
+ }
11
+ /**
12
+ * 自由聊天模式
13
+ * @param chatText
14
+ * @param _paramOption
15
+ * @param axiosOption
16
+ */
17
+ abstract chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption: any): Promise<ApiResult>;
18
+ /**
19
+ * 获取句子的情感
20
+ * @param s1
21
+ * @param axiosOption
22
+ */
23
+ abstract getScentenceEmotional(s1: string, axiosOption: any ): Promise<EmotionResult> ;
24
+ /**
25
+ * 获取两段文本的相似度
26
+ * @param s1
27
+ * @param s2
28
+ * @param axiosOption
29
+ */
30
+ abstract getScentenseSimilarity(s1: string, s2: string, axiosOption: any): Promise<SimilarityResult>;
31
+ /**
32
+ * 获取一段文本的相似内容
33
+ * @param content
34
+ * @param count
35
+ * @param axiosOption
36
+ */
37
+ abstract getSimilarityContent(content: string, count: number, axiosOption: any): Promise<ChatReponse>;
38
+ /**
39
+ * 获取内容的摘要
40
+ * @param content
41
+ * @param axiosOption
42
+ */
43
+ abstract getSummaryOfContent(content: string | Array<any>, axiosOption: any): Promise<SummaryReponse>;
44
+ /**
45
+ * 从内容中提取问题和答案及管件子
46
+ * @param content
47
+ * @param count
48
+ * @param axiosOption
49
+ */
50
+ abstract generateQuestionsFromContent(content: string, count: number, axiosOption: any): Promise<ChatReponse>;
51
+ /**
52
+ * 从内容中提取单选多选判断填空题
53
+ * @param content
54
+ * @param paperOption
55
+ * @param axiosOption
56
+ */
57
+ abstract generateExaminationPaperFromContent(content: string, paperOption: any, axiosOption: any): Promise<ExaminationPaperResult>;
58
+ }
@@ -0,0 +1,38 @@
1
+ //ts check
2
+ /**
3
+ * 语音转文字服务商工厂
4
+ */
5
+ import OpenAIGpt from './openai';
6
+ import AzureAI from './azureai'
7
+ import BaiduWenXinAI, { ApiCredential } from './baiduai'
8
+ import GptBase from './gptbase';
9
+ /**
10
+ * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
11
+ */
12
+ export const GptProviderEnum = {
13
+ OPENAI: 'openai',
14
+ MICROSOFT: 'microsoft',
15
+ BAIDU: 'baidu',
16
+ GOOGLE:'google'
17
+ } as const;
18
+ export type GptProviderEnum = typeof GptProviderEnum[keyof typeof GptProviderEnum];
19
+ /**
20
+ * 根据类型创建不同的TTS引擎对象
21
+ * @param {*} provider
22
+ * @param {*} apikey
23
+ * @param {*} setting
24
+ * @returns
25
+ */
26
+ export function createGpt(provider: GptProviderEnum, apikey: string|ApiCredential, setting: any): GptBase | null {
27
+ let { model, maxtoken, temperature,endpoint,engine,version } = setting || {};
28
+ switch (provider) {
29
+ case GptProviderEnum.OPENAI:
30
+ return new OpenAIGpt(apikey+'', { model, maxtoken, temperature });
31
+ case GptProviderEnum.MICROSOFT:
32
+ return new AzureAI(apikey+'', { endpoint, engine, version }, { model, maxtoken, temperature }, );
33
+ case GptProviderEnum.BAIDU:
34
+ let cred: ApiCredential = typeof (apikey) === 'string' ? { apikey, securitykey: apikey } : apikey
35
+ return new BaiduWenXinAI(cred);
36
+ default: return null;
37
+ }
38
+ };
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
- export * as AIFactory from "./openaiprovider";
1
+ export * as GptFactory from "./gptprovider";
2
+ export * as GptBase from "./gptbase";
package/src/openai.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Configuration, OpenAIApi, ChatCompletionRequestMessage } from "openai"
2
- import { EventEmitter } from "events";
2
+ // import { EventEmitter } from "events";
3
+ import GptBase from "./gptbase"
3
4
  import { OpenAIApiParameters, ChatReponse, OutlineSummaryItem, SummaryReponse, FaqItem, ExaminationPaperResult, EmotionResult, SimilarityResult, QuestionItem } from './declare'
4
5
  const SECTION_LENGTH = 1600; ///每2400个字符分成一组
5
6
  const MESSAGE_LENGTH = 1; ///每次送8句话给openai 进行解析,送多了,会报错
@@ -13,7 +14,7 @@ const QUESTION_TEXT_MAPPING: any = {
13
14
 
14
15
  const QUESTION_TYPE: string[] = ['singlechoice', 'multiplechoice', 'trueorfalse', 'completion']
15
16
 
16
- export default class OpenAIGpt extends EventEmitter {
17
+ export default class OpenAIGpt extends GptBase {
17
18
  protected readonly apiKey: string;
18
19
  private aiApi: OpenAIApi | undefined;
19
20
  protected readonly chatModel: string;
@@ -171,7 +172,7 @@ export default class OpenAIGpt extends EventEmitter {
171
172
  ///没20句话分为一组,适应大文件内容多次请求组合结果
172
173
  ///每一句话需要产生的题目
173
174
  let questions4EverySentense: number = count / arrContent.length; //Math.ceil(arrContent.length / 20);
174
- let faqs: Array<FaqItem> = [], gotted: number = 0;
175
+ let faqs: FaqItem[] = [], gotted: number = 0;
175
176
  while (arrContent.length > 0 && gotted < count) {
176
177
  questions4EverySentense = (count - gotted) / arrContent.length
177
178
  ////每次最多送MESSAGE_LENGTH句话给openai
@@ -180,7 +181,7 @@ export default class OpenAIGpt extends EventEmitter {
180
181
  //subarray.push({ role: 'user', content:'请根据上述内容,给出一道提问与答案以及答案关键词,按照先问题内容,再标准答案,再关键词的顺序输出,关键词之间用、分开'})
181
182
  subarray.unshift({ role: 'system', content: `你是一位专业培训师,从以下内容中提取${itemCount}条提问及答案,并从答案内容提取出至少2个关键词,最终结果按照[{"question":"提问内容","answer":"答案内容","keywords":["关键词1","关键词2"]}]的JSON数组结构输出。` })
182
183
  //subarray.unshift({ role: 'system', content: `你是一位专业程序开发工程师,根据以下内容,按照[{"question":"问题内容","answer":"答案内容","keywords":["关键词1","关键词2"]}]JSON数组结构,给出${itemCount}条提问问题及答案以及答案关键词` })
183
- console.log('subarray', subarray)
184
+ // console.log('subarray', subarray)
184
185
  let result = await this.chatRequest(subarray, { replyCounts: 1 }, axiosOption);
185
186
  if (result.successed && result.message) {
186
187
  // console.log('result is ', result.message[0].message.content)
@@ -200,7 +201,7 @@ export default class OpenAIGpt extends EventEmitter {
200
201
  arrContent = []; /// 释放内存
201
202
  ///发出信号,解析完毕
202
203
  this.emit('parseover', { type: 'qa', items: faqs })
203
- return { successed: true, message: faqs };
204
+ return { successed: true, message: faqs.slice(0, count) };
204
205
  }
205
206
 
206
207
  /**
@@ -415,42 +416,6 @@ export default class OpenAIGpt extends EventEmitter {
415
416
  console.log('error happened:', err);
416
417
  }
417
418
  return returnItems.filter(i => { return i != null; }).slice(0, count);
418
- // let item = result.map(m => {
419
- // ////防止输出的JSON格式不合法
420
- // try {
421
- // let jsonObj = JSON.parse(m.message.content)
422
- // jsonObj.score = score;
423
- // if (jsonObj.choice && Array.isArray(jsonObj.choice) && questiontype != 'completion') {
424
- // jsonObj.fullanswer = (jsonObj.answer + '').replace(/,|[^ABCDE]/g, '');
425
- // jsonObj.choice = jsonObj.choice.map((item:string, index:number) => {
426
- // let seqNo = String.fromCharCode(65 + index);
427
- // let correctReg = new RegExp(`${seqNo}.|${seqNo}`, 'ig')
428
- // //let answer = jsonObj.fullanswer
429
- // return {
430
- // id: seqNo,
431
- // content: item.replace(correctReg, '').trim(),
432
- // iscorrect: (jsonObj.fullanswer.indexOf(seqNo) >= 0 || jsonObj.fullanswer.indexOf(m)) >= 0 ? 1 : 0
433
- // }
434
- // })
435
- // }
436
- // switch (questiontype) {
437
- // case 'singlechoice':
438
- // jsonObj.answer = (jsonObj.answer + '').replace(/,|[^ABCDEFG]/g, '').split('').slice(0, 1);
439
- // break;
440
- // case 'multiplechoice':
441
- // jsonObj.answer = (jsonObj.answer + '').replace(/,|[^ABCDEFG]/g, '').split('');
442
- // break;
443
- // case 'trueorfalse':
444
- // jsonObj.answer = [(jsonObj.answer + '').indexOf('正确') >= 0 ? 'A' : 'B']
445
- // break;
446
- // }
447
- // return jsonObj;
448
- // } catch (err) {
449
- // console.log('error happened:', err);
450
- // return null;
451
- // }
452
- // })
453
- // return item.filter(i => { return i != null; });
454
419
  }
455
420
  /**
456
421
  * 将一段很长的文本,按1024长度来划分到多个中
@@ -1,32 +0,0 @@
1
- /**
2
- * 语音转文字服务商工厂
3
- */
4
- import OpenAIGpt from './openai';
5
- import AzureAI from './azureai'
6
- /**
7
- * OpenAI/NLP 的服务提供商 OpenAI,微软,百度文心(待接入),google(待接入)
8
- */
9
- export const AIProviderEnum = {
10
- OPENAI: 'openai',
11
- MICROSOFT: 'microsoft',
12
- BAIDU: 'baidu',
13
- GOOGLE:'google'
14
- } as const;
15
- export type AIProviderEnum = typeof AIProviderEnum[keyof typeof AIProviderEnum];
16
- /**
17
- * 根据类型创建不同的TTS引擎对象
18
- * @param {*} provider
19
- * @param {*} apikey
20
- * @param {*} setting
21
- * @returns
22
- */
23
- export function createAIInstance(provider: AIProviderEnum, apikey: string, setting: any): OpenAIGpt | null {
24
- let { model, maxtoken, temperature,endpoint,engine,version } = setting;
25
- switch (provider) {
26
- case AIProviderEnum.OPENAI:
27
- return new OpenAIGpt(apikey, { model, maxtoken, temperature });
28
- case AIProviderEnum.MICROSOFT:
29
- return new AzureAI(apikey, { endpoint, engine, version }, { model, maxtoken, temperature }, );
30
- default: return null;
31
- }
32
- };