@opensumi/ide-ai-native 3.9.1-next-1749175927.0 → 3.9.1-next-1749181695.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.
Files changed (66) hide show
  1. package/lib/browser/chat/chat-manager.service.d.ts +0 -1
  2. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  3. package/lib/browser/chat/chat-manager.service.js +3 -9
  4. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  5. package/lib/browser/chat/chat-model.d.ts +1 -8
  6. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  7. package/lib/browser/chat/chat-model.js +78 -113
  8. package/lib/browser/chat/chat-model.js.map +1 -1
  9. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  10. package/lib/browser/chat/chat.view.js +16 -32
  11. package/lib/browser/chat/chat.view.js.map +1 -1
  12. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  13. package/lib/browser/components/ChatMentionInput.js +25 -3
  14. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  15. package/lib/browser/components/ChatReply.js +2 -2
  16. package/lib/browser/components/ChatReply.js.map +1 -1
  17. package/lib/browser/components/components.module.less +30 -8
  18. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  19. package/lib/browser/components/mention-input/mention-input.js +30 -36
  20. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  21. package/lib/browser/components/mention-input/mention-input.module.less +0 -1
  22. package/lib/browser/components/mention-input/mention-select.d.ts +28 -0
  23. package/lib/browser/components/mention-input/mention-select.d.ts.map +1 -0
  24. package/lib/browser/components/mention-input/mention-select.js +136 -0
  25. package/lib/browser/components/mention-input/mention-select.js.map +1 -0
  26. package/lib/browser/components/mention-input/mention-select.module.less +297 -0
  27. package/lib/browser/components/mention-input/types.d.ts +13 -0
  28. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  29. package/lib/browser/components/mention-input/types.js.map +1 -1
  30. package/lib/browser/model/msg-history-manager.d.ts +1 -47
  31. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  32. package/lib/browser/model/msg-history-manager.js +2 -127
  33. package/lib/browser/model/msg-history-manager.js.map +1 -1
  34. package/lib/browser/rules/rules.module.less +1 -0
  35. package/lib/browser/rules/rules.view.js +1 -1
  36. package/lib/browser/rules/rules.view.js.map +1 -1
  37. package/lib/browser/types.d.ts +0 -4
  38. package/lib/browser/types.d.ts.map +1 -1
  39. package/lib/browser/types.js.map +1 -1
  40. package/lib/common/model.d.ts +1 -0
  41. package/lib/common/model.d.ts.map +1 -1
  42. package/lib/common/model.js.map +1 -1
  43. package/lib/node/anthropic/anthropic-language-model.d.ts +1 -1
  44. package/lib/node/base-language-model.js +2 -1
  45. package/lib/node/base-language-model.js.map +1 -1
  46. package/lib/node/deepseek/deepseek-language-model.d.ts +1 -1
  47. package/package.json +26 -26
  48. package/src/browser/chat/chat-manager.service.ts +7 -16
  49. package/src/browser/chat/chat-model.ts +75 -130
  50. package/src/browser/chat/chat.view.tsx +14 -46
  51. package/src/browser/components/ChatMentionInput.tsx +37 -4
  52. package/src/browser/components/ChatReply.tsx +4 -4
  53. package/src/browser/components/components.module.less +30 -8
  54. package/src/browser/components/mention-input/mention-input.module.less +0 -1
  55. package/src/browser/components/mention-input/mention-input.tsx +38 -52
  56. package/src/browser/components/mention-input/mention-select.module.less +297 -0
  57. package/src/browser/components/mention-input/mention-select.tsx +256 -0
  58. package/src/browser/components/mention-input/types.ts +14 -0
  59. package/src/browser/model/msg-history-manager.ts +2 -181
  60. package/src/browser/rules/rules.module.less +1 -0
  61. package/src/browser/rules/rules.view.tsx +1 -1
  62. package/src/browser/types.ts +0 -6
  63. package/src/common/model.ts +1 -0
  64. package/src/node/base-language-model.ts +1 -1
  65. package/lib/common/MDC_PARSER_README.md +0 -171
  66. package/src/common/MDC_PARSER_README.md +0 -171
@@ -0,0 +1,256 @@
1
+ import cls from 'classnames';
2
+ import React, { useEffect, useRef, useState } from 'react';
3
+
4
+ import { ClickOutside } from '@opensumi/ide-components/lib/click-outside';
5
+ import { Icon, getIcon } from '@opensumi/ide-core-browser/lib/components';
6
+
7
+ import styles from './mention-select.module.less';
8
+
9
+ export interface ExtendedModelOption {
10
+ label: string;
11
+ value: string;
12
+ icon?: string;
13
+ iconClass?: string;
14
+ tags?: string[];
15
+ features?: string[];
16
+ description?: string;
17
+ disabled?: boolean;
18
+ badge?: string;
19
+ badgeColor?: string;
20
+ selected?: boolean;
21
+ }
22
+
23
+ export interface MentionSelectProps {
24
+ options: ExtendedModelOption[];
25
+ value?: string;
26
+ onChange?: (value: string) => void;
27
+ placeholder?: string;
28
+ disabled?: boolean;
29
+ className?: string;
30
+ size?: 'small' | 'medium' | 'large';
31
+ showThinking?: boolean;
32
+ thinkingEnabled?: boolean;
33
+ onThinkingChange?: (enabled: boolean) => void;
34
+ }
35
+
36
+ const ThinkingToggle: React.FC<{
37
+ enabled: boolean;
38
+ onChange: (enabled: boolean) => void;
39
+ }> = ({ enabled, onChange }) => (
40
+ <div className={styles.thinking_toggle} onClick={() => onChange(!enabled)}>
41
+ <Icon
42
+ iconClass={getIcon(enabled ? 'check' : 'circle-outline')}
43
+ className={cls(styles.thinking_icon, {
44
+ [styles.enabled]: enabled,
45
+ })}
46
+ />
47
+ <span className={styles.thinking_label}>Thinking</span>
48
+ </div>
49
+ );
50
+
51
+ export const MentionSelect: React.FC<MentionSelectProps> = ({
52
+ options,
53
+ value,
54
+ onChange,
55
+ placeholder,
56
+ disabled = false,
57
+ className,
58
+ size = 'small',
59
+ showThinking = false,
60
+ thinkingEnabled = false,
61
+ onThinkingChange,
62
+ }) => {
63
+ const [isOpen, setIsOpen] = useState(false);
64
+ const [activeIndex, setActiveIndex] = useState(-1);
65
+ const [dropdownDirection, setDropdownDirection] = useState<'up' | 'down'>('up');
66
+ const selectRef = useRef<HTMLDivElement>(null);
67
+ const dropdownRef = useRef<HTMLDivElement>(null);
68
+
69
+ const selectedOption = options.find((option) => option.selected) || options.find((option) => option.value === value);
70
+
71
+ const handleToggle = () => {
72
+ if (!disabled) {
73
+ setIsOpen(!isOpen);
74
+ setActiveIndex(-1);
75
+ }
76
+ };
77
+
78
+ const handleSelect = (option: ExtendedModelOption) => {
79
+ if (!option.disabled) {
80
+ onChange?.(option.value);
81
+ setIsOpen(false);
82
+ setActiveIndex(-1);
83
+ }
84
+ };
85
+
86
+ const handleKeyDown = (e: React.KeyboardEvent) => {
87
+ if (disabled) {
88
+ return;
89
+ }
90
+
91
+ switch (e.key) {
92
+ case 'Enter':
93
+ case ' ':
94
+ e.preventDefault();
95
+ if (!isOpen) {
96
+ setIsOpen(true);
97
+ } else if (activeIndex >= 0) {
98
+ handleSelect(options[activeIndex]);
99
+ }
100
+ break;
101
+ case 'Escape':
102
+ e.preventDefault();
103
+ setIsOpen(false);
104
+ setActiveIndex(-1);
105
+ break;
106
+ case 'ArrowDown':
107
+ e.preventDefault();
108
+ if (!isOpen) {
109
+ setIsOpen(true);
110
+ } else {
111
+ setActiveIndex((prev) => (prev < options.length - 1 ? prev + 1 : 0));
112
+ }
113
+ break;
114
+ case 'ArrowUp':
115
+ e.preventDefault();
116
+ if (isOpen) {
117
+ setActiveIndex((prev) => (prev > 0 ? prev - 1 : options.length - 1));
118
+ }
119
+ break;
120
+ }
121
+ };
122
+
123
+ const handleClickOutside = () => {
124
+ setIsOpen(false);
125
+ setActiveIndex(-1);
126
+ };
127
+
128
+ useEffect(() => {
129
+ if (isOpen && selectRef.current) {
130
+ const selectRect = selectRef.current.getBoundingClientRect();
131
+ const viewportHeight = window.innerHeight;
132
+ const dropdownHeight = Math.min(400, options.length * 60);
133
+
134
+ const spaceAbove = selectRect.top;
135
+ const spaceBelow = viewportHeight - selectRect.bottom;
136
+
137
+ if (spaceAbove < dropdownHeight && spaceBelow > spaceAbove) {
138
+ setDropdownDirection('down');
139
+ } else {
140
+ setDropdownDirection('up');
141
+ }
142
+ }
143
+ }, [isOpen, options.length]);
144
+
145
+ useEffect(() => {
146
+ if (isOpen && activeIndex >= 0 && dropdownRef.current) {
147
+ const activeElement = dropdownRef.current.children[activeIndex] as HTMLElement;
148
+ if (activeElement) {
149
+ activeElement.scrollIntoView({
150
+ behavior: 'smooth',
151
+ block: 'nearest',
152
+ });
153
+ }
154
+ }
155
+ }, [isOpen, activeIndex]);
156
+
157
+ return (
158
+ <ClickOutside onOutsideClick={handleClickOutside}>
159
+ <div
160
+ ref={selectRef}
161
+ className={cls(
162
+ styles.mention_select,
163
+ styles[`size_${size}`],
164
+ {
165
+ [styles.disabled]: disabled,
166
+ [styles.open]: isOpen,
167
+ [styles.dropdown_up]: dropdownDirection === 'up',
168
+ [styles.dropdown_down]: dropdownDirection === 'down',
169
+ },
170
+ className,
171
+ )}
172
+ onClick={handleToggle}
173
+ onKeyDown={handleKeyDown}
174
+ tabIndex={disabled ? -1 : 0}
175
+ role='combobox'
176
+ aria-expanded={isOpen}
177
+ aria-haspopup='listbox'
178
+ >
179
+ <div className={styles.select_trigger}>
180
+ <div className={styles.select_content}>
181
+ {selectedOption ? (
182
+ <div className={styles.selected_option}>
183
+ <span className={styles.option_label}>{selectedOption.label}</span>
184
+ {selectedOption.badge && (
185
+ <span className={styles.option_badge} style={{ backgroundColor: selectedOption.badgeColor }}>
186
+ {selectedOption.badge}
187
+ </span>
188
+ )}
189
+ </div>
190
+ ) : (
191
+ <span className={styles.placeholder}>{placeholder}</span>
192
+ )}
193
+ </div>
194
+ <Icon
195
+ iconClass={getIcon('down-arrow')}
196
+ className={cls(styles.dropdown_arrow, {
197
+ [styles.open]: isOpen,
198
+ })}
199
+ />
200
+ </div>
201
+
202
+ {isOpen && (
203
+ <div ref={dropdownRef} className={styles.dropdown} role='listbox'>
204
+ {showThinking && onThinkingChange && (
205
+ <div className={styles.thinking_section}>
206
+ <ThinkingToggle enabled={thinkingEnabled} onChange={onThinkingChange} />
207
+ <div className={styles.divider} />
208
+ </div>
209
+ )}
210
+
211
+ {options.map((option, index) => (
212
+ <div
213
+ key={option.value}
214
+ className={cls(styles.option, {
215
+ [styles.active]: index === activeIndex,
216
+ [styles.selected]: option.selected || option.value === value,
217
+ [styles.disabled]: option.disabled,
218
+ })}
219
+ onClick={() => handleSelect(option)}
220
+ role='option'
221
+ aria-selected={option.selected || option.value === value}
222
+ >
223
+ <div className={styles.option_main}>
224
+ <div className={styles.option_header}>
225
+ <div className={styles.option_title}>
226
+ {option.icon && <Icon icon={option.icon} className={styles.option_icon} />}
227
+ {option.iconClass && <Icon iconClass={option.iconClass} className={styles.option_icon} />}
228
+ <span className={styles.option_label}>{option.label}</span>
229
+ {option.badge && (
230
+ <span className={styles.option_badge} style={{ backgroundColor: option.badgeColor }}>
231
+ {option.badge}
232
+ </span>
233
+ )}
234
+ </div>
235
+ </div>
236
+
237
+ {option.description && <div className={styles.option_description}>{option.description}</div>}
238
+
239
+ {option.tags && option.tags.length > 0 && (
240
+ <div className={styles.option_tags}>
241
+ {option.tags.map((tag, idx) => (
242
+ <span key={idx} className={styles.tag}>
243
+ {tag}
244
+ </span>
245
+ ))}
246
+ </div>
247
+ )}
248
+ </div>
249
+ </div>
250
+ ))}
251
+ </div>
252
+ )}
253
+ </div>
254
+ </ClickOutside>
255
+ );
256
+ };
@@ -46,6 +46,17 @@ export interface MentionState {
46
46
  interface ModelOption {
47
47
  label: string;
48
48
  value: string;
49
+ icon?: string;
50
+ iconClass?: string;
51
+ tags?: string[];
52
+ description?: string;
53
+ badge?: string;
54
+ badgeColor?: string;
55
+ }
56
+
57
+ export interface ExtendedModelOption extends ModelOption {
58
+ disabled?: boolean;
59
+ selected?: boolean; // 由外部控制选中状态
49
60
  }
50
61
 
51
62
  export interface ExtendedModelOption {
@@ -89,6 +100,9 @@ export interface FooterConfig {
89
100
  buttons?: FooterButton[];
90
101
  showModelSelector?: boolean;
91
102
  disableModelSelector?: boolean;
103
+ showThinking?: boolean;
104
+ thinkingEnabled?: boolean;
105
+ onThinkingChange?: (enabled: boolean) => void;
92
106
  }
93
107
 
94
108
  export interface MentionInputProps {
@@ -1,61 +1,11 @@
1
1
  import { Disposable, Emitter, Event, uuid } from '@opensumi/ide-core-common';
2
2
  import { ChatMessageRole, IHistoryChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
3
3
 
4
- import { ChatFeatureRegistry } from '../chat/chat.feature.registry';
5
-
6
4
  type IExcludeMessage = Omit<IHistoryChatMessage, 'id' | 'order'>;
7
5
 
8
- interface IMemoryConfig {
9
- shortTermSize: number; // 最近消息窗口大小(10条)
10
- bufferSize: number; // 缓冲区大小(5条)
11
- }
12
-
13
- interface IMemorySummary {
14
- content: string;
15
- timestamp: number;
16
- messageIds: string[];
17
- }
18
-
19
- interface IToolCallInfo {
20
- id: string;
21
- name: string;
22
- args: Record<string, any>;
23
- result: any;
24
- }
25
-
26
- export interface MessageBufferManager {
27
- messages: IHistoryChatMessage[];
28
- add(message: IHistoryChatMessage): void;
29
- clear(): void;
30
- size(): number;
31
- }
32
-
33
- class SimpleMessageBuffer implements MessageBufferManager {
34
- private _messages: IHistoryChatMessage[] = [];
35
-
36
- get messages(): IHistoryChatMessage[] {
37
- return this._messages;
38
- }
39
-
40
- add(message: IHistoryChatMessage): void {
41
- this._messages.push(message);
42
- }
43
-
44
- clear(): void {
45
- this._messages = [];
46
- }
47
-
48
- size(): number {
49
- return this._messages.length;
50
- }
51
- }
52
-
53
6
  export class MsgHistoryManager extends Disposable {
54
7
  private messageMap: Map<string, IHistoryChatMessage> = new Map();
55
8
  private messageAdditionalMap: Map<string, Record<string, any>> = new Map();
56
- private memorySummaries: IMemorySummary[] = [];
57
- private toolCallMap: Map<string, IToolCallInfo> = new Map();
58
- private isCompressing = false; // 添加压缩锁,防止重复压缩
59
9
 
60
10
  private readonly _onMessageChange = new Emitter<IHistoryChatMessage[]>();
61
11
  public readonly onMessageChange: Event<IHistoryChatMessage[]> = this._onMessageChange.event;
@@ -63,33 +13,11 @@ export class MsgHistoryManager extends Disposable {
63
13
  private readonly _onMessageAdditionalChange = new Emitter<Record<string, any>>();
64
14
  public readonly onMessageAdditionalChange: Event<Record<string, any>> = this._onMessageAdditionalChange.event;
65
15
 
66
- private messageBuffer: MessageBufferManager;
67
-
68
- memoryConfig: IMemoryConfig = {
69
- shortTermSize: 10,
70
- bufferSize: 5,
71
- };
72
-
73
- constructor(
74
- private chatFeatureRegistry: ChatFeatureRegistry,
75
- data?: {
76
- additional: Record<string, any>;
77
- messages: IHistoryChatMessage[];
78
- toolCalls?: Record<string, IToolCallInfo>;
79
- memorySummaries?: IMemorySummary[];
80
- },
81
- ) {
16
+ constructor(data?: { additional: Record<string, any>; messages: IHistoryChatMessage[] }) {
82
17
  super();
83
- this.messageBuffer = new SimpleMessageBuffer();
84
18
  if (data) {
85
19
  this.messageMap = new Map(data.messages.map((item) => [item.id, item]));
86
20
  this.messageAdditionalMap = new Map(Object.entries(data.additional));
87
- if (data.toolCalls) {
88
- this.toolCallMap = new Map(Object.entries(data.toolCalls));
89
- }
90
- if (data.memorySummaries) {
91
- this.memorySummaries = data.memorySummaries;
92
- }
93
21
  }
94
22
  }
95
23
 
@@ -105,91 +33,6 @@ export class MsgHistoryManager extends Disposable {
105
33
  public clearMessages() {
106
34
  this.messageMap.clear();
107
35
  this.messageAdditionalMap.clear();
108
- this.memorySummaries = [];
109
- this.toolCallMap.clear();
110
- }
111
-
112
- /**
113
- * 压缩历史消息的方法:
114
- * 1. 保持最新的10条消息不变
115
- * 2. 当累积了5条超出限制的消息时,对这5条(最早的消息)进行总结
116
- * 3. 总结完成后删除这5条消息
117
- * 4. 重复这个过程,确保消息数量始终在可控范围内
118
- */
119
- private async compressMemory() {
120
- // 如果正在压缩中,直接返回
121
- if (this.isCompressing) {
122
- return;
123
- }
124
-
125
- const messages = this.messageList;
126
- // 只有当消息总数超过短期记忆限制时才进行压缩
127
- if (messages.length <= this.memoryConfig.shortTermSize) {
128
- return;
129
- }
130
-
131
- try {
132
- this.isCompressing = true;
133
-
134
- // 1. 获取超出短期记忆限制的最新一条消息
135
- const latestExcessMessage = messages[messages.length - this.memoryConfig.shortTermSize - 1];
136
-
137
- // 如果这条消息已经被总结过,就不需要再处理
138
- if (latestExcessMessage.isSummarized) {
139
- return;
140
- }
141
-
142
- // 2. 将这条消息添加到缓冲区
143
- this.messageBuffer.add(latestExcessMessage);
144
-
145
- // 3. 当缓冲区达到指定大小时,进行总结
146
- if (this.messageBuffer.size() >= this.memoryConfig.bufferSize) {
147
- const messagesToSummarize = this.messageBuffer.messages;
148
-
149
- const summaryProvider = this.chatFeatureRegistry.getMessageSummaryProvider?.();
150
- if (summaryProvider) {
151
- const messageContents = messagesToSummarize.map((msg) => ({
152
- role: msg.role,
153
- content: msg.content,
154
- }));
155
-
156
- const memorize = await summaryProvider.generateMemorizedMessage(messageContents);
157
- if (memorize) {
158
- // 添加新的记忆总结
159
- this.memorySummaries.push({
160
- content: memorize,
161
- timestamp: Date.now(),
162
- messageIds: messagesToSummarize.map((msg) => msg.id),
163
- });
164
-
165
- // 标记消息为已总结
166
- for (const msg of messagesToSummarize) {
167
- const existingMsg = this.messageMap.get(msg.id);
168
- if (existingMsg) {
169
- this.messageMap.set(msg.id, {
170
- ...existingMsg,
171
- isSummarized: true,
172
- });
173
- }
174
- }
175
-
176
- // 清空缓冲区
177
- this.messageBuffer.clear();
178
- }
179
- }
180
- }
181
- } finally {
182
- this.isCompressing = false;
183
- }
184
- }
185
-
186
- public addToolCall(toolCall: IToolCallInfo): void {
187
- this.toolCallMap.set(toolCall.id, toolCall);
188
- }
189
-
190
- public getToolCall(id: string): IToolCallInfo | undefined {
191
- const toolCall = this.toolCallMap.get(id);
192
- return toolCall;
193
36
  }
194
37
 
195
38
  private doAddMessage(message: IExcludeMessage): string {
@@ -205,19 +48,11 @@ export class MsgHistoryManager extends Disposable {
205
48
 
206
49
  this.messageMap.set(id, msg);
207
50
 
208
- // 在添加新消息后尝试压缩记忆
209
- this.compressMemory().catch((error) => {
210
- // eslint-disable-next-line no-console
211
- console.error('[MsgHistoryManager] Error compressing memory', error);
212
- });
213
-
214
- // 无论压缩是否完成,都触发消息变更事件
215
51
  this._onMessageChange.fire(this.getMessages());
216
52
  return id;
217
53
  }
218
54
 
219
55
  private get messageList(): IHistoryChatMessage[] {
220
- // 按 order 升序排序,保持消息的原始顺序
221
56
  return Array.from(this.messageMap.values()).sort((a, b) => a.order - b.order);
222
57
  }
223
58
 
@@ -230,17 +65,6 @@ export class MsgHistoryManager extends Disposable {
230
65
  return this.messageList;
231
66
  }
232
67
 
233
- public getMemorySummaries(): IMemorySummary[] {
234
- return this.memorySummaries;
235
- }
236
-
237
- public setMemoryConfig(config: Partial<IMemoryConfig>) {
238
- this.memoryConfig = {
239
- ...this.memoryConfig,
240
- ...config,
241
- };
242
- }
243
-
244
68
  public addUserMessage(
245
69
  message: Required<Pick<IExcludeMessage, 'agentId' | 'agentCommand' | 'content' | 'relationId' | 'images'>>,
246
70
  ): string {
@@ -294,12 +118,9 @@ export class MsgHistoryManager extends Disposable {
294
118
  }
295
119
 
296
120
  toJSON() {
297
- const data = {
121
+ return {
298
122
  messages: this.getMessages(),
299
123
  additional: Object.fromEntries(this.messageAdditionalMap.entries()),
300
- memorySummaries: this.memorySummaries,
301
- toolCalls: Object.fromEntries(this.toolCallMap.entries()),
302
124
  };
303
- return data;
304
125
  }
305
126
  }
@@ -80,6 +80,7 @@
80
80
  }
81
81
 
82
82
  .project_rules_header_left {
83
+ width: 100%;
83
84
  display: flex;
84
85
  flex-direction: column;
85
86
  }
@@ -37,7 +37,7 @@ export const RulesView: React.FC = () => {
37
37
  [rulesService],
38
38
  );
39
39
 
40
- const getFileNameFromPath = (path: string) => path.split('/').pop() || path;
40
+ const getFileNameFromPath = (path: string) => decodeURIComponent(path.split('/').pop() || path);
41
41
 
42
42
  const hasWarning = (rule: ProjectRule) => !rule.description && !rule.alwaysApply && !rule.globs;
43
43
 
@@ -308,12 +308,6 @@ export interface IMessageSummaryProvider {
308
308
  content: string;
309
309
  }>,
310
310
  ): Promise<string | undefined>;
311
- generateMemorizedMessage(
312
- messages: Array<{
313
- role: ChatMessageRole;
314
- content: string;
315
- }>,
316
- ): Promise<string | undefined>;
317
311
  }
318
312
 
319
313
  export const AINativeCoreContribution = Symbol('AINativeCoreContribution');
@@ -5,6 +5,7 @@ export interface ModelInfo {
5
5
  temperature?: number;
6
6
  topP?: number;
7
7
  topK?: number;
8
+ maxSteps?: number;
8
9
  }
9
10
 
10
11
  export const deepSeekModels = {
@@ -116,7 +116,7 @@ export abstract class BaseLanguageModel {
116
116
  messages,
117
117
  abortSignal: abortController.signal,
118
118
  experimental_toolCallStreaming: true,
119
- maxSteps: 12,
119
+ maxSteps: modelInfo?.maxSteps ?? 25,
120
120
  maxTokens,
121
121
  system: systemPrompt,
122
122
  providerOptions,