koishi-plugin-openai-compatible 1.0.9 → 1.1.1

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/lib/index.d.ts CHANGED
@@ -36,6 +36,7 @@ declare class OpenAICompatible {
36
36
  private cooldownManager;
37
37
  private logger;
38
38
  constructor(ctx: Context, config: Config);
39
+ private ensureConfigDefaults;
39
40
  private registerService;
40
41
  private registerCommand;
41
42
  chat(message: string, options?: {
package/lib/index.js CHANGED
@@ -51,20 +51,30 @@ class OpenAICompatibleClient {
51
51
  this.logger = logger.extend(isEmotion ? 'emotion-client' : 'client');
52
52
  // 如果是情绪分析客户端,使用情绪分析配置(如果提供)
53
53
  if (isEmotion && config.emotionAnalysis.enabled) {
54
- this.endpoint = config.emotionAnalysis.endpoint || config.endpoint;
55
- this.endpoint = this.endpoint.replace(/\/$/, '');
56
- this.apiKey = config.emotionAnalysis.apiKey || config.apiKey;
54
+ // 使用情绪分析配置,如果为空则使用主配置
55
+ const emotionEndpoint = config.emotionAnalysis.endpoint || config.endpoint;
56
+ this.endpoint = (emotionEndpoint || 'https://api.openai.com/v1').replace(/\/$/, '');
57
+ this.apiKey = config.emotionAnalysis.apiKey || config.apiKey || '';
57
58
  this.timeout = config.emotionTimeout;
58
59
  }
59
60
  else {
60
- this.endpoint = config.endpoint.replace(/\/$/, '');
61
- this.apiKey = config.apiKey;
61
+ // 主客户端配置
62
+ this.endpoint = (config.endpoint || 'https://api.openai.com/v1').replace(/\/$/, '');
63
+ this.apiKey = config.apiKey || '';
62
64
  this.timeout = config.timeout;
63
65
  }
64
66
  this.maxRetries = config.maxRetries;
67
+ // 验证配置
68
+ if (!this.apiKey) {
69
+ this.logger.warn('API密钥未配置,部分功能可能无法正常工作');
70
+ }
65
71
  }
66
72
  async createChatCompletion(messages, config, isEmotion = false) {
67
73
  var _a, _b, _c, _d;
74
+ // 检查API密钥
75
+ if (!this.apiKey) {
76
+ throw new Error('API密钥未配置,请检查插件配置');
77
+ }
68
78
  const url = `${this.endpoint}/chat/completions`;
69
79
  const headers = {
70
80
  'Content-Type': 'application/json',
@@ -135,6 +145,11 @@ class OpenAICompatibleClient {
135
145
  }
136
146
  }
137
147
  async testConnection() {
148
+ // 检查API密钥
149
+ if (!this.apiKey) {
150
+ this.logger.error('无法测试连接:API密钥未配置');
151
+ return false;
152
+ }
138
153
  try {
139
154
  const url = `${this.endpoint}/models`;
140
155
  const controller = new AbortController();
@@ -313,12 +328,54 @@ class OpenAICompatible {
313
328
  this.ctx = ctx;
314
329
  this.config = config;
315
330
  this.logger = ctx.logger('openai-compatible');
316
- this.client = new OpenAICompatibleClient(config, this.logger);
317
- this.emotionAnalyzer = new EmotionAnalyzer(config, this.logger);
318
- this.cooldownManager = new CooldownManager(config.cooldown);
331
+ // 确保配置有默认值
332
+ this.ensureConfigDefaults();
333
+ this.client = new OpenAICompatibleClient(this.config, this.logger);
334
+ this.emotionAnalyzer = new EmotionAnalyzer(this.config, this.logger);
335
+ this.cooldownManager = new CooldownManager(this.config.cooldown);
319
336
  this.registerCommand();
320
337
  this.registerService();
321
338
  }
339
+ ensureConfigDefaults() {
340
+ // 确保所有必要的配置都有默认值
341
+ if (!this.config.endpoint) {
342
+ this.config.endpoint = 'https://api.openai.com/v1';
343
+ }
344
+ if (!this.config.model) {
345
+ this.config.model = 'gpt-3.5-turbo';
346
+ }
347
+ if (!this.config.apiKey) {
348
+ this.config.apiKey = '';
349
+ this.logger.warn('API密钥未配置,插件将无法正常工作');
350
+ }
351
+ // 确保情绪分析配置有默认值
352
+ if (this.config.emotionAnalysis) {
353
+ if (!this.config.emotionAnalysis.endpoint) {
354
+ this.config.emotionAnalysis.endpoint = '';
355
+ }
356
+ if (!this.config.emotionAnalysis.apiKey) {
357
+ this.config.emotionAnalysis.apiKey = '';
358
+ }
359
+ if (!this.config.emotionAnalysis.model) {
360
+ this.config.emotionAnalysis.model = 'gpt-3.5-turbo';
361
+ }
362
+ }
363
+ // 确保情绪表情配置有默认值
364
+ if (!this.config.emotionEmojis) {
365
+ this.config.emotionEmojis = {
366
+ 'happy': { text: '😊', image: '' },
367
+ 'sad': { text: '😢', image: '' },
368
+ 'angry': { text: '😠', image: '' },
369
+ 'neutral': { text: '😐', image: '' },
370
+ 'surprised': { text: '😲', image: '' },
371
+ 'fearful': { text: '😨', image: '' },
372
+ 'disgusted': { text: '🤢', image: '' },
373
+ 'excited': { text: '🤩', image: '' },
374
+ 'calm': { text: '😌', image: '' },
375
+ 'confused': { text: '😕', image: '' },
376
+ };
377
+ }
378
+ }
322
379
  registerService() {
323
380
  this.ctx.openai = this;
324
381
  this.ctx.on('dispose', () => {
@@ -338,7 +395,7 @@ class OpenAICompatible {
338
395
  return '请输入消息内容。';
339
396
  const userId = (session === null || session === void 0 ? void 0 : session.userId) || 'unknown';
340
397
  // 检查黑名单
341
- if (this.config.blacklist.includes(userId)) {
398
+ if (this.config.blacklist && this.config.blacklist.includes(userId)) {
342
399
  return showError ? '您已被加入黑名单,无法使用此功能。' : '';
343
400
  }
344
401
  // 检查冷却时间
@@ -379,7 +436,7 @@ class OpenAICompatible {
379
436
  }
380
437
  // 情绪分析(如果不禁用)
381
438
  let emotionResult = null;
382
- if (this.config.emotionAnalysis.enabled && !(options === null || options === void 0 ? void 0 : options.noEmotion)) {
439
+ if (this.config.emotionAnalysis && this.config.emotionAnalysis.enabled && !(options === null || options === void 0 ? void 0 : options.noEmotion)) {
383
440
  try {
384
441
  // 临时修改显示设置(如果指定了禁用图片)
385
442
  const showImage = !(options === null || options === void 0 ? void 0 : options.noImage) && this.config.showEmotionImage;
@@ -426,7 +483,7 @@ class OpenAICompatible {
426
483
  if (session) {
427
484
  await session.send('正在测试连接...');
428
485
  }
429
- if ((options === null || options === void 0 ? void 0 : options.emotion) && this.config.emotionAnalysis.enabled) {
486
+ if ((options === null || options === void 0 ? void 0 : options.emotion) && this.config.emotionAnalysis && this.config.emotionAnalysis.enabled) {
430
487
  const connected = await this.client.testConnection();
431
488
  if (connected) {
432
489
  // 测试情绪分析
@@ -477,7 +534,7 @@ class OpenAICompatible {
477
534
  .subcommand('.test <text:text>', '测试情绪分析')
478
535
  .option('image', '-i')
479
536
  .action(async ({ session, options }, text) => {
480
- if (!this.config.emotionAnalysis.enabled) {
537
+ if (!this.config.emotionAnalysis || !this.config.emotionAnalysis.enabled) {
481
538
  return '情绪分析功能未启用。';
482
539
  }
483
540
  if (!text) {
@@ -581,10 +638,10 @@ class OpenAICompatible {
581
638
  }
582
639
  // 公共API方法
583
640
  async chat(message, options) {
584
- var _a, _b;
641
+ var _a, _b, _c;
585
642
  const userId = (options === null || options === void 0 ? void 0 : options.userId) || 'anonymous';
586
643
  // 检查黑名单
587
- if (this.config.blacklist.includes(userId)) {
644
+ if (this.config.blacklist && this.config.blacklist.includes(userId)) {
588
645
  throw new Error('User is blacklisted');
589
646
  }
590
647
  // 检查冷却时间
@@ -615,11 +672,11 @@ class OpenAICompatible {
615
672
  });
616
673
  // 情绪分析
617
674
  let emotionResult = null;
618
- const enableEmotion = (_a = options === null || options === void 0 ? void 0 : options.enableEmotion) !== null && _a !== void 0 ? _a : this.config.emotionAnalysis.enabled;
675
+ const enableEmotion = (_a = options === null || options === void 0 ? void 0 : options.enableEmotion) !== null && _a !== void 0 ? _a : (((_b = this.config.emotionAnalysis) === null || _b === void 0 ? void 0 : _b.enabled) || false);
619
676
  if (enableEmotion) {
620
677
  try {
621
678
  // 临时修改显示设置
622
- const showImage = (_b = options === null || options === void 0 ? void 0 : options.showImage) !== null && _b !== void 0 ? _b : this.config.showEmotionImage;
679
+ const showImage = (_c = options === null || options === void 0 ? void 0 : options.showImage) !== null && _c !== void 0 ? _c : this.config.showEmotionImage;
623
680
  this.emotionAnalyzer.updateDisplaySettings(showImage, this.config.imageAsMarkdown);
624
681
  emotionResult = await this.emotionAnalyzer.analyze(mainResponse);
625
682
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-openai-compatible",
3
- "version": "1.0.9",
3
+ "version": "1.1.1",
4
4
  "description": "这是一个适用于Koishi的OpenAI兼容聊天插件,支持与所有兼容OpenAI API的大模型进行聊天交互。",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
package/src/index.ts CHANGED
@@ -57,17 +57,24 @@ class OpenAICompatibleClient {
57
57
 
58
58
  // 如果是情绪分析客户端,使用情绪分析配置(如果提供)
59
59
  if (isEmotion && config.emotionAnalysis.enabled) {
60
- this.endpoint = config.emotionAnalysis.endpoint || config.endpoint
61
- this.endpoint = this.endpoint.replace(/\/$/, '')
62
- this.apiKey = config.emotionAnalysis.apiKey || config.apiKey
60
+ // 使用情绪分析配置,如果为空则使用主配置
61
+ const emotionEndpoint = config.emotionAnalysis.endpoint || config.endpoint
62
+ this.endpoint = (emotionEndpoint || 'https://api.openai.com/v1').replace(/\/$/, '')
63
+ this.apiKey = config.emotionAnalysis.apiKey || config.apiKey || ''
63
64
  this.timeout = config.emotionTimeout
64
65
  } else {
65
- this.endpoint = config.endpoint.replace(/\/$/, '')
66
- this.apiKey = config.apiKey
66
+ // 主客户端配置
67
+ this.endpoint = (config.endpoint || 'https://api.openai.com/v1').replace(/\/$/, '')
68
+ this.apiKey = config.apiKey || ''
67
69
  this.timeout = config.timeout
68
70
  }
69
71
 
70
72
  this.maxRetries = config.maxRetries
73
+
74
+ // 验证配置
75
+ if (!this.apiKey) {
76
+ this.logger.warn('API密钥未配置,部分功能可能无法正常工作')
77
+ }
71
78
  }
72
79
 
73
80
  async createChatCompletion(
@@ -75,6 +82,11 @@ class OpenAICompatibleClient {
75
82
  config?: Partial<Config>,
76
83
  isEmotion: boolean = false
77
84
  ): Promise<string> {
85
+ // 检查API密钥
86
+ if (!this.apiKey) {
87
+ throw new Error('API密钥未配置,请检查插件配置')
88
+ }
89
+
78
90
  const url = `${this.endpoint}/chat/completions`
79
91
  const headers = {
80
92
  'Content-Type': 'application/json',
@@ -154,6 +166,12 @@ class OpenAICompatibleClient {
154
166
  }
155
167
 
156
168
  async testConnection(): Promise<boolean> {
169
+ // 检查API密钥
170
+ if (!this.apiKey) {
171
+ this.logger.error('无法测试连接:API密钥未配置')
172
+ return false
173
+ }
174
+
157
175
  try {
158
176
  const url = `${this.endpoint}/models`
159
177
  const controller = new AbortController()
@@ -383,14 +401,63 @@ class OpenAICompatible {
383
401
  private config: Config
384
402
  ) {
385
403
  this.logger = ctx.logger('openai-compatible')
386
- this.client = new OpenAICompatibleClient(config, this.logger)
387
- this.emotionAnalyzer = new EmotionAnalyzer(config, this.logger)
388
- this.cooldownManager = new CooldownManager(config.cooldown)
404
+
405
+ // 确保配置有默认值
406
+ this.ensureConfigDefaults()
407
+
408
+ this.client = new OpenAICompatibleClient(this.config, this.logger)
409
+ this.emotionAnalyzer = new EmotionAnalyzer(this.config, this.logger)
410
+ this.cooldownManager = new CooldownManager(this.config.cooldown)
389
411
 
390
412
  this.registerCommand()
391
413
  this.registerService()
392
414
  }
393
415
 
416
+ private ensureConfigDefaults() {
417
+ // 确保所有必要的配置都有默认值
418
+ if (!this.config.endpoint) {
419
+ this.config.endpoint = 'https://api.openai.com/v1'
420
+ }
421
+
422
+ if (!this.config.model) {
423
+ this.config.model = 'gpt-3.5-turbo'
424
+ }
425
+
426
+ if (!this.config.apiKey) {
427
+ this.config.apiKey = ''
428
+ this.logger.warn('API密钥未配置,插件将无法正常工作')
429
+ }
430
+
431
+ // 确保情绪分析配置有默认值
432
+ if (this.config.emotionAnalysis) {
433
+ if (!this.config.emotionAnalysis.endpoint) {
434
+ this.config.emotionAnalysis.endpoint = ''
435
+ }
436
+ if (!this.config.emotionAnalysis.apiKey) {
437
+ this.config.emotionAnalysis.apiKey = ''
438
+ }
439
+ if (!this.config.emotionAnalysis.model) {
440
+ this.config.emotionAnalysis.model = 'gpt-3.5-turbo'
441
+ }
442
+ }
443
+
444
+ // 确保情绪表情配置有默认值
445
+ if (!this.config.emotionEmojis) {
446
+ this.config.emotionEmojis = {
447
+ 'happy': { text: '😊', image: '' },
448
+ 'sad': { text: '😢', image: '' },
449
+ 'angry': { text: '😠', image: '' },
450
+ 'neutral': { text: '😐', image: '' },
451
+ 'surprised': { text: '😲', image: '' },
452
+ 'fearful': { text: '😨', image: '' },
453
+ 'disgusted': { text: '🤢', image: '' },
454
+ 'excited': { text: '🤩', image: '' },
455
+ 'calm': { text: '😌', image: '' },
456
+ 'confused': { text: '😕', image: '' },
457
+ }
458
+ }
459
+ }
460
+
394
461
  private registerService() {
395
462
  this.ctx.openai = this
396
463
 
@@ -414,7 +481,7 @@ class OpenAICompatible {
414
481
  const userId = session?.userId || 'unknown'
415
482
 
416
483
  // 检查黑名单
417
- if (this.config.blacklist.includes(userId)) {
484
+ if (this.config.blacklist && this.config.blacklist.includes(userId)) {
418
485
  return showError ? '您已被加入黑名单,无法使用此功能。' : ''
419
486
  }
420
487
 
@@ -464,7 +531,7 @@ class OpenAICompatible {
464
531
 
465
532
  // 情绪分析(如果不禁用)
466
533
  let emotionResult = null
467
- if (this.config.emotionAnalysis.enabled && !options?.noEmotion) {
534
+ if (this.config.emotionAnalysis && this.config.emotionAnalysis.enabled && !options?.noEmotion) {
468
535
  try {
469
536
  // 临时修改显示设置(如果指定了禁用图片)
470
537
  const showImage = !options?.noImage && this.config.showEmotionImage
@@ -517,7 +584,7 @@ class OpenAICompatible {
517
584
  await session.send('正在测试连接...')
518
585
  }
519
586
 
520
- if (options?.emotion && this.config.emotionAnalysis.enabled) {
587
+ if (options?.emotion && this.config.emotionAnalysis && this.config.emotionAnalysis.enabled) {
521
588
  const connected = await this.client.testConnection()
522
589
  if (connected) {
523
590
  // 测试情绪分析
@@ -566,7 +633,7 @@ class OpenAICompatible {
566
633
  .subcommand('.test <text:text>', '测试情绪分析')
567
634
  .option('image', '-i')
568
635
  .action(async ({ session, options }, text) => {
569
- if (!this.config.emotionAnalysis.enabled) {
636
+ if (!this.config.emotionAnalysis || !this.config.emotionAnalysis.enabled) {
570
637
  return '情绪分析功能未启用。'
571
638
  }
572
639
 
@@ -713,7 +780,7 @@ class OpenAICompatible {
713
780
  const userId = options?.userId || 'anonymous'
714
781
 
715
782
  // 检查黑名单
716
- if (this.config.blacklist.includes(userId)) {
783
+ if (this.config.blacklist && this.config.blacklist.includes(userId)) {
717
784
  throw new Error('User is blacklisted')
718
785
  }
719
786
 
@@ -751,7 +818,7 @@ class OpenAICompatible {
751
818
 
752
819
  // 情绪分析
753
820
  let emotionResult = null
754
- const enableEmotion = options?.enableEmotion ?? this.config.emotionAnalysis.enabled
821
+ const enableEmotion = options?.enableEmotion ?? (this.config.emotionAnalysis?.enabled || false)
755
822
  if (enableEmotion) {
756
823
  try {
757
824
  // 临时修改显示设置