tabby-ai-assistant 1.0.10 → 1.0.12

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.
Files changed (104) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +3 -3
  3. package/src/components/chat/ai-sidebar.component.scss +43 -0
  4. package/src/components/chat/ai-sidebar.component.ts +43 -1
  5. package/src/components/settings/ai-settings-tab.component.html +13 -5
  6. package/src/components/settings/ai-settings-tab.component.scss +164 -33
  7. package/src/components/settings/ai-settings-tab.component.ts +1 -0
  8. package/src/components/settings/context-settings.component.html +87 -0
  9. package/src/components/settings/context-settings.component.scss +133 -0
  10. package/src/components/settings/context-settings.component.ts +91 -0
  11. package/src/components/settings/provider-config.component.ts +12 -6
  12. package/src/i18n/translations/en-US.ts +27 -1
  13. package/src/i18n/translations/ja-JP.ts +27 -1
  14. package/src/i18n/translations/zh-CN.ts +27 -1
  15. package/src/i18n/types.ts +28 -0
  16. package/src/index.ts +6 -0
  17. package/src/services/chat/ai-sidebar.service.ts +1 -1
  18. package/src/services/chat/chat-session.service.ts +91 -2
  19. package/src/services/context/manager.ts +33 -2
  20. package/src/services/core/ai-assistant.service.ts +35 -11
  21. package/src/services/core/config-provider.service.ts +66 -0
  22. package/src/services/core/toast.service.ts +70 -0
  23. package/src/services/providers/anthropic-provider.service.ts +12 -4
  24. package/src/services/providers/glm-provider.service.ts +12 -4
  25. package/src/services/providers/minimax-provider.service.ts +12 -4
  26. package/src/styles/ai-assistant.scss +23 -0
  27. package/src/types/ai.types.ts +3 -3
  28. package/src/types/provider.types.ts +1 -0
  29. package/dist/components/chat/ai-sidebar.component.d.ts +0 -160
  30. package/dist/components/chat/chat-input.component.d.ts +0 -69
  31. package/dist/components/chat/chat-interface.component.d.ts +0 -124
  32. package/dist/components/chat/chat-message.component.d.ts +0 -53
  33. package/dist/components/chat/chat-settings.component.d.ts +0 -72
  34. package/dist/components/common/error-message.component.d.ts +0 -11
  35. package/dist/components/common/loading-spinner.component.d.ts +0 -4
  36. package/dist/components/security/consent-dialog.component.d.ts +0 -11
  37. package/dist/components/security/password-prompt.component.d.ts +0 -10
  38. package/dist/components/security/risk-confirm-dialog.component.d.ts +0 -36
  39. package/dist/components/settings/ai-settings-tab.component.d.ts +0 -82
  40. package/dist/components/settings/general-settings.component.d.ts +0 -94
  41. package/dist/components/settings/provider-config.component.d.ts +0 -300
  42. package/dist/components/settings/security-settings.component.d.ts +0 -33
  43. package/dist/components/terminal/ai-toolbar-button.component.d.ts +0 -10
  44. package/dist/components/terminal/command-preview.component.d.ts +0 -53
  45. package/dist/components/terminal/command-suggestion.component.d.ts +0 -16
  46. package/dist/i18n/index.d.ts +0 -48
  47. package/dist/i18n/translations/en-US.d.ts +0 -5
  48. package/dist/i18n/translations/ja-JP.d.ts +0 -5
  49. package/dist/i18n/translations/zh-CN.d.ts +0 -5
  50. package/dist/i18n/types.d.ts +0 -198
  51. package/dist/index-full.d.ts +0 -8
  52. package/dist/index-minimal.d.ts +0 -3
  53. package/dist/index.d.ts +0 -12
  54. package/dist/main.d.ts +0 -8
  55. package/dist/providers/tabby/ai-config.provider.d.ts +0 -70
  56. package/dist/providers/tabby/ai-hotkey.provider.d.ts +0 -15
  57. package/dist/providers/tabby/ai-settings-tab.provider.d.ts +0 -11
  58. package/dist/providers/tabby/ai-toolbar-button.provider.d.ts +0 -16
  59. package/dist/services/chat/ai-sidebar.service.d.ts +0 -111
  60. package/dist/services/chat/chat-history.service.d.ts +0 -145
  61. package/dist/services/chat/chat-session.service.d.ts +0 -113
  62. package/dist/services/chat/command-generator.service.d.ts +0 -49
  63. package/dist/services/context/compaction.d.ts +0 -90
  64. package/dist/services/context/manager.d.ts +0 -69
  65. package/dist/services/context/memory.d.ts +0 -116
  66. package/dist/services/context/token-budget.d.ts +0 -105
  67. package/dist/services/core/ai-assistant.service.d.ts +0 -127
  68. package/dist/services/core/ai-provider-manager.service.d.ts +0 -119
  69. package/dist/services/core/checkpoint.service.d.ts +0 -130
  70. package/dist/services/core/config-provider.service.d.ts +0 -137
  71. package/dist/services/core/logger.service.d.ts +0 -21
  72. package/dist/services/core/theme.service.d.ts +0 -53
  73. package/dist/services/core/toast.service.d.ts +0 -15
  74. package/dist/services/platform/escape-sequence.service.d.ts +0 -132
  75. package/dist/services/platform/platform-detection.service.d.ts +0 -146
  76. package/dist/services/providers/anthropic-provider.service.d.ts +0 -44
  77. package/dist/services/providers/base-provider.service.d.ts +0 -142
  78. package/dist/services/providers/glm-provider.service.d.ts +0 -96
  79. package/dist/services/providers/minimax-provider.service.d.ts +0 -102
  80. package/dist/services/providers/ollama-provider.service.d.ts +0 -76
  81. package/dist/services/providers/openai-compatible.service.d.ts +0 -44
  82. package/dist/services/providers/openai-provider.service.d.ts +0 -43
  83. package/dist/services/providers/vllm-provider.service.d.ts +0 -82
  84. package/dist/services/security/consent-manager.service.d.ts +0 -65
  85. package/dist/services/security/password-manager.service.d.ts +0 -67
  86. package/dist/services/security/risk-assessment.service.d.ts +0 -65
  87. package/dist/services/security/security-validator.service.d.ts +0 -36
  88. package/dist/services/terminal/buffer-analyzer.service.d.ts +0 -128
  89. package/dist/services/terminal/command-analyzer.service.d.ts +0 -20
  90. package/dist/services/terminal/context-menu.service.d.ts +0 -24
  91. package/dist/services/terminal/hotkey.service.d.ts +0 -28
  92. package/dist/services/terminal/terminal-context.service.d.ts +0 -100
  93. package/dist/services/terminal/terminal-manager.service.d.ts +0 -185
  94. package/dist/services/terminal/terminal-tools.service.d.ts +0 -79
  95. package/dist/types/ai.types.d.ts +0 -199
  96. package/dist/types/provider.types.d.ts +0 -105
  97. package/dist/types/security.types.d.ts +0 -85
  98. package/dist/types/terminal.types.d.ts +0 -150
  99. package/dist/utils/encryption.utils.d.ts +0 -83
  100. package/dist/utils/formatting.utils.d.ts +0 -106
  101. package/dist/utils/validation.utils.d.ts +0 -83
  102. package/jest.config.js +0 -47
  103. package/webpack-docker.config.js +0 -42
  104. package/webpack.config.js +0 -81
@@ -3,6 +3,7 @@ import { Subject, Observable } from 'rxjs';
3
3
  import { LoggerService } from './logger.service';
4
4
  import { SecurityConfig } from '../../types/security.types';
5
5
  import { ProviderConfig } from '../../types/provider.types';
6
+ import { ContextConfig } from '../../types/ai.types';
6
7
 
7
8
  /**
8
9
  * AI助手配置
@@ -203,6 +204,32 @@ export class ConfigProviderService {
203
204
  return { ...this.config.providers };
204
205
  }
205
206
 
207
+ /**
208
+ * 获取活跃供应商的上下文窗口大小
209
+ */
210
+ getActiveProviderContextWindow(): number {
211
+ const activeProvider = this.config.defaultProvider;
212
+ if (!activeProvider) {
213
+ return 200000; // 默认值
214
+ }
215
+ const providerConfig = this.getProviderConfig(activeProvider);
216
+ const contextWindow = providerConfig?.contextWindow;
217
+ if (contextWindow && contextWindow > 0) {
218
+ return contextWindow;
219
+ }
220
+ // 返回供应商默认值
221
+ const defaults: { [key: string]: number } = {
222
+ 'openai': 128000,
223
+ 'anthropic': 200000,
224
+ 'minimax': 128000,
225
+ 'glm': 128000,
226
+ 'ollama': 8192,
227
+ 'vllm': 8192,
228
+ 'openai-compatible': 128000
229
+ };
230
+ return defaults[activeProvider] || 200000;
231
+ }
232
+
206
233
  /**
207
234
  * 获取默认提供商
208
235
  */
@@ -344,4 +371,43 @@ export class ConfigProviderService {
344
371
  errors
345
372
  };
346
373
  }
374
+
375
+ // ==================== 上下文配置 ====================
376
+
377
+ /**
378
+ * 获取上下文配置
379
+ */
380
+ getContextConfig(): ContextConfig | null {
381
+ try {
382
+ const key = 'tabby-ai-assistant-context-config';
383
+ const stored = localStorage.getItem(key);
384
+ return stored ? JSON.parse(stored) : null;
385
+ } catch {
386
+ return null;
387
+ }
388
+ }
389
+
390
+ /**
391
+ * 设置上下文配置
392
+ */
393
+ setContextConfig(config: ContextConfig): void {
394
+ const key = 'tabby-ai-assistant-context-config';
395
+ localStorage.setItem(key, JSON.stringify(config));
396
+ }
397
+
398
+ /**
399
+ * 获取自动压缩开关状态
400
+ */
401
+ isAutoCompactEnabled(): boolean {
402
+ const key = 'tabby-ai-assistant-auto-compact';
403
+ return localStorage.getItem(key) !== 'false';
404
+ }
405
+
406
+ /**
407
+ * 设置自动压缩开关状态
408
+ */
409
+ setAutoCompactEnabled(enabled: boolean): void {
410
+ const key = 'tabby-ai-assistant-auto-compact';
411
+ localStorage.setItem(key, String(enabled));
412
+ }
347
413
  }
@@ -15,9 +15,79 @@ export class ToastService {
15
15
 
16
16
  show(type: ToastMessage['type'], message: string, duration = 3000): void {
17
17
  const id = `toast-${Date.now()}`;
18
+
19
+ // 确保容器存在
20
+ let container = document.getElementById('ai-toast-container');
21
+ if (!container) {
22
+ container = document.createElement('div');
23
+ container.id = 'ai-toast-container';
24
+ container.className = 'ai-toast-container';
25
+ container.style.cssText = `
26
+ position: fixed;
27
+ bottom: 20px;
28
+ right: 20px;
29
+ z-index: 99999;
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 10px;
33
+ pointer-events: none;
34
+ `;
35
+ document.body.appendChild(container);
36
+ }
37
+
38
+ // 创建 Toast 元素
39
+ const toast = document.createElement('div');
40
+ toast.id = id;
41
+ toast.className = `ai-toast ai-toast-${type}`;
42
+ toast.style.cssText = `
43
+ padding: 12px 16px;
44
+ border-radius: 8px;
45
+ color: white;
46
+ font-size: 14px;
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 8px;
50
+ animation: toastSlideIn 0.3s ease;
51
+ cursor: pointer;
52
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
53
+ pointer-events: auto;
54
+ min-width: 200px;
55
+ max-width: 350px;
56
+ ${type === 'success' ? 'background: linear-gradient(135deg, #22c55e, #16a34a);' : ''}
57
+ ${type === 'error' ? 'background: linear-gradient(135deg, #ef4444, #dc2626);' : ''}
58
+ ${type === 'warning' ? 'background: linear-gradient(135deg, #f59e0b, #d97706);' : ''}
59
+ ${type === 'info' ? 'background: linear-gradient(135deg, #3b82f6, #2563eb);' : ''}
60
+ `;
61
+
62
+ const icon = type === 'success' ? '✓' : type === 'error' ? '✗' : type === 'warning' ? '⚠' : 'ℹ';
63
+ toast.innerHTML = `<span style="font-size: 16px;">${icon}</span><span>${message}</span>`;
64
+
65
+ toast.onclick = () => {
66
+ this.removeToast(toast);
67
+ };
68
+
69
+ container.appendChild(toast);
70
+
71
+ // 自动消失
72
+ setTimeout(() => {
73
+ this.removeToast(toast);
74
+ }, duration);
75
+
76
+ // 发射事件(兼容现有订阅)
18
77
  this.toastSubject.next({ id, type, message, duration });
19
78
  }
20
79
 
80
+ private removeToast(toast: HTMLElement): void {
81
+ if (toast && toast.parentNode) {
82
+ toast.style.animation = 'toastSlideOut 0.3s ease forwards';
83
+ setTimeout(() => {
84
+ if (toast.parentNode) {
85
+ toast.remove();
86
+ }
87
+ }, 300);
88
+ }
89
+ }
90
+
21
91
  success(message: string, duration = 3000): void {
22
92
  this.show('success', message, duration);
23
93
  }
@@ -385,16 +385,24 @@ export class AnthropicProviderService extends BaseAiProvider {
385
385
  - read_terminal_output: 读取终端输出
386
386
  - get_terminal_list: 获取所有终端列表
387
387
  - get_terminal_cwd: 获取当前工作目录
388
+ - focus_terminal: 切换到指定索引的终端(需要参数 terminal_index)
389
+ - get_terminal_selection: 获取终端中选中的文本
388
390
 
389
391
  ## 重要规则
390
392
  1. 当用户请求执行命令(如"查看当前目录"、"列出文件"等),你必须使用 write_to_terminal 工具来执行
391
- 2. 不要只是描述你"将要做什么",而是直接调用工具执行
392
- 3. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
393
- 4. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
393
+ 2. **当用户请求切换终端(如"切换到终端0"、"打开终端4"等),你必须使用 focus_terminal 工具**
394
+ 3. 不要只是描述你"将要做什么",而是直接调用工具执行
395
+ 4. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
396
+ 5. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
397
+ 6. **永远不要假装执行了操作,必须真正调用工具**
394
398
 
395
399
  ## 示例
396
400
  用户:"查看当前目录的文件"
397
401
  正确做法:调用 write_to_terminal 工具,参数 { "command": "dir", "execute": true }
398
- 错误做法:仅回复文字"我将执行 dir 命令"`;
402
+ 错误做法:仅回复文字"我将执行 dir 命令"
403
+
404
+ 用户:"切换到终端4"
405
+ 正确做法:调用 focus_terminal 工具,参数 { "terminal_index": 4 }
406
+ 错误做法:仅回复文字"已切换到终端4"(不调用工具)`;
399
407
  }
400
408
  }
@@ -479,16 +479,24 @@ export class GlmProviderService extends BaseAiProvider {
479
479
  - read_terminal_output: 读取终端输出
480
480
  - get_terminal_list: 获取所有终端列表
481
481
  - get_terminal_cwd: 获取当前工作目录
482
+ - focus_terminal: 切换到指定索引的终端(需要参数 terminal_index)
483
+ - get_terminal_selection: 获取终端中选中的文本
482
484
 
483
485
  ## 重要规则
484
486
  1. 当用户请求执行命令(如"查看当前目录"、"列出文件"等),你必须使用 write_to_terminal 工具来执行
485
- 2. 不要只是描述你"将要做什么",而是直接调用工具执行
486
- 3. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
487
- 4. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
487
+ 2. **当用户请求切换终端(如"切换到终端0"、"打开终端4"等),你必须使用 focus_terminal 工具**
488
+ 3. 不要只是描述你"将要做什么",而是直接调用工具执行
489
+ 4. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
490
+ 5. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
491
+ 6. **永远不要假装执行了操作,必须真正调用工具**
488
492
 
489
493
  ## 示例
490
494
  用户:"查看当前目录的文件"
491
495
  正确做法:调用 write_to_terminal 工具,参数 { "command": "dir", "execute": true }
492
- 错误做法:仅回复文字"我将执行 dir 命令"`;
496
+ 错误做法:仅回复文字"我将执行 dir 命令"
497
+
498
+ 用户:"切换到终端4"
499
+ 正确做法:调用 focus_terminal 工具,参数 { "terminal_index": 4 }
500
+ 错误做法:仅回复文字"已切换到终端4"(不调用工具)`;
493
501
  }
494
502
  }
@@ -610,16 +610,24 @@ export class MinimaxProviderService extends BaseAiProvider {
610
610
  - read_terminal_output: 读取终端输出
611
611
  - get_terminal_list: 获取所有终端列表
612
612
  - get_terminal_cwd: 获取当前工作目录
613
+ - focus_terminal: 切换到指定索引的终端(需要参数 terminal_index)
614
+ - get_terminal_selection: 获取终端中选中的文本
613
615
 
614
616
  ## 重要规则
615
617
  1. 当用户请求执行命令(如"查看当前目录"、"列出文件"等),你必须使用 write_to_terminal 工具来执行
616
- 2. 不要只是描述你"将要做什么",而是直接调用工具执行
617
- 3. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
618
- 4. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
618
+ 2. **当用户请求切换终端(如"切换到终端0"、"打开终端4"等),你必须使用 focus_terminal 工具**
619
+ 3. 不要只是描述你"将要做什么",而是直接调用工具执行
620
+ 4. 执行命令后,使用 read_terminal_output 读取结果并报告给用户
621
+ 5. 如果不确定当前目录或终端状态,先使用 get_terminal_cwd 或 get_terminal_list 获取信息
622
+ 6. **永远不要假装执行了操作,必须真正调用工具**
619
623
 
620
624
  ## 示例
621
625
  用户:"查看当前目录的文件"
622
626
  正确做法:调用 write_to_terminal 工具,参数 { "command": "dir", "execute": true }
623
- 错误做法:仅回复文字"我将执行 dir 命令"`;
627
+ 错误做法:仅回复文字"我将执行 dir 命令"
628
+
629
+ 用户:"切换到终端4"
630
+ 正确做法:调用 focus_terminal 工具,参数 { "terminal_index": 4 }
631
+ 错误做法:仅回复文字"已切换到终端4"(不调用工具)`;
624
632
  }
625
633
  }
@@ -438,4 +438,27 @@
438
438
  .modal-backdrop {
439
439
  background-color: rgba(0, 0, 0, 0.3) !important;
440
440
  }
441
+ }
442
+
443
+ // Toast 动画
444
+ @keyframes toastSlideIn {
445
+ from {
446
+ transform: translateX(100%);
447
+ opacity: 0;
448
+ }
449
+ to {
450
+ transform: translateX(0);
451
+ opacity: 1;
452
+ }
453
+ }
454
+
455
+ @keyframes toastSlideOut {
456
+ from {
457
+ transform: translateX(0);
458
+ opacity: 1;
459
+ }
460
+ to {
461
+ transform: translateX(100%);
462
+ opacity: 0;
463
+ }
441
464
  }
@@ -192,6 +192,7 @@ export interface ContextConfig {
192
192
  pruneThreshold: number; // 裁剪触发阈值 (0-1)
193
193
  messagesToKeep: number; // 保留的最近消息数
194
194
  bufferPercentage: number; // 安全缓冲区百分比
195
+ summaryPrompt?: string; // 自定义摘要提示词
195
196
  }
196
197
 
197
198
  // 默认配置
@@ -201,10 +202,9 @@ export const DEFAULT_CONTEXT_CONFIG: ContextConfig = {
201
202
  compactThreshold: 0.85,
202
203
  pruneThreshold: 0.70,
203
204
  messagesToKeep: 3,
204
- bufferPercentage: 0.10
205
+ bufferPercentage: 0.10,
206
+ summaryPrompt: '请用一句话总结以下对话的要点,保留关键信息和用户意图:'
205
207
  };
206
-
207
- // 压缩结果
208
208
  export interface CompactionResult {
209
209
  success: boolean;
210
210
  messages: ApiMessage[];
@@ -29,6 +29,7 @@ export interface ProviderConfig {
29
29
  retries?: number;
30
30
  authConfig?: AuthConfig;
31
31
  enabled?: boolean;
32
+ contextWindow?: number; // 供应商上下文窗口限制
32
33
  }
33
34
 
34
35
  // 提供商信息
@@ -1,160 +0,0 @@
1
- import { OnInit, OnDestroy, ElementRef, AfterViewChecked, AfterViewInit } from '@angular/core';
2
- import { ChatMessage } from '../../types/ai.types';
3
- import { AiAssistantService } from '../../services/core/ai-assistant.service';
4
- import { ConfigProviderService } from '../../services/core/config-provider.service';
5
- import { LoggerService } from '../../services/core/logger.service';
6
- import { ChatHistoryService } from '../../services/chat/chat-history.service';
7
- import { AiSidebarService } from '../../services/chat/ai-sidebar.service';
8
- import { ThemeService } from '../../services/core/theme.service';
9
- /**
10
- * AI Sidebar 组件 - 替代 ChatInterfaceComponent
11
- * 使用内联模板和样式,支持 Tabby 主题
12
- */
13
- export declare class AiSidebarComponent implements OnInit, OnDestroy, AfterViewChecked, AfterViewInit {
14
- private aiService;
15
- private config;
16
- private logger;
17
- private chatHistory;
18
- private themeService;
19
- displayStyle: string;
20
- flexDirection: string;
21
- heightStyle: string;
22
- widthStyle: string;
23
- overflowStyle: string;
24
- chatContainerRef: ElementRef;
25
- textInput: ElementRef<HTMLTextAreaElement>;
26
- sidebarService: AiSidebarService;
27
- messages: ChatMessage[];
28
- isLoading: boolean;
29
- currentProvider: string;
30
- currentSessionId: string;
31
- showScrollTop: boolean;
32
- showScrollBottom: boolean;
33
- inputValue: string;
34
- isComposing: boolean;
35
- charLimit: number;
36
- private destroy$;
37
- private shouldScrollToBottom;
38
- constructor(aiService: AiAssistantService, config: ConfigProviderService, logger: LoggerService, chatHistory: ChatHistoryService, themeService: ThemeService);
39
- ngOnInit(): void;
40
- ngOnDestroy(): void;
41
- ngAfterViewInit(): void;
42
- /**
43
- * 强制设置滚动容器样式
44
- * 使用 JavaScript 直接设置,优先级最高
45
- */
46
- private forceScrollStyles;
47
- ngAfterViewChecked(): void;
48
- /**
49
- * 加载当前提供商信息
50
- */
51
- private loadCurrentProvider;
52
- /**
53
- * 加载聊天历史
54
- */
55
- private loadChatHistory;
56
- /**
57
- * 发送欢迎消息
58
- */
59
- private sendWelcomeMessage;
60
- /**
61
- * 处理发送消息
62
- */
63
- onSendMessage(content: string): Promise<void>;
64
- /**
65
- * 清空聊天记录
66
- */
67
- clearChat(): void;
68
- /**
69
- * 导出聊天记录
70
- */
71
- exportChat(): void;
72
- /**
73
- * 切换提供商
74
- */
75
- switchProvider(): Promise<void>;
76
- /**
77
- * 隐藏侧边栏
78
- */
79
- hideSidebar(): void;
80
- /**
81
- * 滚动到底部(公开方法)
82
- */
83
- scrollToBottom(): void;
84
- /**
85
- * 滚动到顶部
86
- */
87
- scrollToTop(): void;
88
- /**
89
- * 实际执行滚动到底部
90
- */
91
- private performScrollToBottom;
92
- /**
93
- * 处理滚动事件
94
- */
95
- onScroll(event: Event): void;
96
- /**
97
- * 检查滚动状态(初始化时调用)
98
- */
99
- private checkScrollState;
100
- /**
101
- * 更新滚动按钮显示状态
102
- */
103
- private updateScrollButtons;
104
- /**
105
- * 保存聊天历史
106
- */
107
- private saveChatHistory;
108
- /**
109
- * 生成会话 ID
110
- */
111
- private generateSessionId;
112
- /**
113
- * 生成唯一ID
114
- */
115
- private generateId;
116
- /**
117
- * 获取消息时间格式
118
- */
119
- formatTimestamp(timestamp: Date): string;
120
- /**
121
- * 格式化消息内容(支持换行和基本格式化)
122
- */
123
- formatMessage(content: string): string;
124
- /**
125
- * 检查是否为今天的消息
126
- */
127
- isToday(date: Date): boolean;
128
- /**
129
- * 检查是否为同一天的消息
130
- */
131
- isSameDay(date1: Date, date2: Date): boolean;
132
- /**
133
- * 处理键盘事件
134
- */
135
- onKeydown(event: KeyboardEvent): void;
136
- /**
137
- * 处理输入事件
138
- */
139
- onInput(event: Event): void;
140
- /**
141
- * 提交消息
142
- */
143
- submit(): void;
144
- /**
145
- * 自动调整输入框高度
146
- */
147
- private autoResize;
148
- /**
149
- * 获取字符计数
150
- */
151
- getCharCount(): number;
152
- /**
153
- * 检查是否接近限制
154
- */
155
- isNearLimit(): boolean;
156
- /**
157
- * 检查是否超过限制
158
- */
159
- isOverLimit(): boolean;
160
- }
@@ -1,69 +0,0 @@
1
- import { EventEmitter, ElementRef, OnInit, OnDestroy } from '@angular/core';
2
- import { ConfigProviderService } from '../../services/core/config-provider.service';
3
- export declare class ChatInputComponent implements OnInit, OnDestroy {
4
- private config;
5
- disabled: boolean;
6
- placeholder: string;
7
- send: EventEmitter<string>;
8
- textInput: ElementRef<HTMLTextAreaElement>;
9
- inputValue: string;
10
- private inputSubject;
11
- private destroy$;
12
- isComposing: boolean;
13
- enterToSend: boolean;
14
- constructor(config: ConfigProviderService);
15
- ngOnInit(): void;
16
- ngOnDestroy(): void;
17
- /**
18
- * 处理输入变化
19
- */
20
- onInputChange(value: string): void;
21
- /**
22
- * 处理键盘事件
23
- */
24
- onKeydown(event: KeyboardEvent): void;
25
- /**
26
- * 处理输入事件
27
- */
28
- onInput(event: Event): void;
29
- /**
30
- * 处理composition开始(输入法)
31
- */
32
- onCompositionStart(): void;
33
- /**
34
- * 处理composition结束(输入法)
35
- */
36
- onCompositionEnd(): void;
37
- /**
38
- * 提交消息
39
- */
40
- submit(): void;
41
- /**
42
- * 清空输入
43
- */
44
- clear(): void;
45
- /**
46
- * 自动调整高度
47
- */
48
- private autoResize;
49
- /**
50
- * 获取字符计数
51
- */
52
- getCharCount(): number;
53
- /**
54
- * 获取字符限制
55
- */
56
- getCharLimit(): number;
57
- /**
58
- * 检查是否接近限制
59
- */
60
- isNearLimit(): boolean;
61
- /**
62
- * 检查是否超过限制
63
- */
64
- isOverLimit(): boolean;
65
- /**
66
- * 聚焦输入框
67
- */
68
- focus(): void;
69
- }
@@ -1,124 +0,0 @@
1
- import { OnInit, OnDestroy, ElementRef, AfterViewChecked } from '@angular/core';
2
- import { ChatMessage } from '../../types/ai.types';
3
- import { AiAssistantService } from '../../services/core/ai-assistant.service';
4
- import { ConfigProviderService } from '../../services/core/config-provider.service';
5
- import { LoggerService } from '../../services/core/logger.service';
6
- import { ChatHistoryService } from '../../services/chat/chat-history.service';
7
- import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
8
- import { TranslateService } from '../../i18n';
9
- export declare class ChatInterfaceComponent implements OnInit, OnDestroy, AfterViewChecked {
10
- private aiService;
11
- private config;
12
- private logger;
13
- private modal;
14
- private chatHistory;
15
- private translate;
16
- chatContainerRef: ElementRef;
17
- messages: ChatMessage[];
18
- isLoading: boolean;
19
- currentProvider: string;
20
- currentSessionId: string;
21
- showScrollTop: boolean;
22
- showScrollBottom: boolean;
23
- showTimestamps: boolean;
24
- showAvatars: boolean;
25
- soundEnabled: boolean;
26
- compactMode: boolean;
27
- fontSize: number;
28
- t: any;
29
- private destroy$;
30
- private shouldScrollToBottom;
31
- private notificationSound;
32
- constructor(aiService: AiAssistantService, config: ConfigProviderService, logger: LoggerService, modal: NgbModal, chatHistory: ChatHistoryService, translate: TranslateService);
33
- ngOnInit(): void;
34
- /**
35
- * 加载 UI 设置
36
- */
37
- private loadUISettings;
38
- /**
39
- * 应用存储的 UI 设置
40
- */
41
- private applyStoredSettings;
42
- ngOnDestroy(): void;
43
- ngAfterViewChecked(): void;
44
- /**
45
- * 加载当前提供商信息
46
- */
47
- private loadCurrentProvider;
48
- /**
49
- * 加载聊天历史
50
- */
51
- private loadChatHistory;
52
- /**
53
- * 发送欢迎消息
54
- */
55
- private sendWelcomeMessage;
56
- /**
57
- * 处理发送消息
58
- */
59
- onSendMessage(content: string): Promise<void>;
60
- /**
61
- * 清空聊天记录
62
- */
63
- clearChat(): void;
64
- /**
65
- * 导出聊天记录
66
- */
67
- exportChat(): void;
68
- /**
69
- * 切换提供商
70
- */
71
- switchProvider(): Promise<void>;
72
- /**
73
- * 滚动到底部(公开方法)
74
- */
75
- scrollToBottom(): void;
76
- /**
77
- * 滚动到顶部
78
- */
79
- scrollToTop(): void;
80
- /**
81
- * 实际执行滚动到底部
82
- */
83
- private performScrollToBottom;
84
- /**
85
- * 处理滚动事件
86
- */
87
- onScroll(event: Event): void;
88
- /**
89
- * 检查滚动状态(初始化时调用)
90
- */
91
- private checkScrollState;
92
- /**
93
- * 更新滚动按钮显示状态
94
- */
95
- private updateScrollButtons;
96
- /**
97
- * 保存聊天历史
98
- */
99
- private saveChatHistory;
100
- /**
101
- * 生成会话 ID
102
- */
103
- private generateSessionId;
104
- /**
105
- * 生成唯一ID
106
- */
107
- private generateId;
108
- /**
109
- * 获取消息时间格式
110
- */
111
- formatTimestamp(timestamp: Date): string;
112
- /**
113
- * 播放提示音
114
- */
115
- private playNotificationSound;
116
- /**
117
- * 检查是否为今天的消息
118
- */
119
- isToday(date: Date): boolean;
120
- /**
121
- * 检查是否为同一天的消息
122
- */
123
- isSameDay(date1: Date, date2: Date): boolean;
124
- }