snow-ai 0.1.12 → 0.2.2

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 (97) hide show
  1. package/dist/api/chat.d.ts +65 -2
  2. package/dist/api/chat.js +299 -16
  3. package/dist/api/responses.d.ts +52 -0
  4. package/dist/api/responses.js +541 -0
  5. package/dist/api/systemPrompt.d.ts +4 -0
  6. package/dist/api/systemPrompt.js +43 -0
  7. package/dist/app.js +15 -4
  8. package/dist/cli.js +38 -2
  9. package/dist/hooks/useConversation.d.ts +32 -0
  10. package/dist/hooks/useConversation.js +403 -0
  11. package/dist/hooks/useGlobalNavigation.d.ts +6 -0
  12. package/dist/hooks/useGlobalNavigation.js +15 -0
  13. package/dist/hooks/useSessionManagement.d.ts +10 -0
  14. package/dist/hooks/useSessionManagement.js +43 -0
  15. package/dist/hooks/useSessionSave.d.ts +8 -0
  16. package/dist/hooks/useSessionSave.js +52 -0
  17. package/dist/hooks/useToolConfirmation.d.ts +18 -0
  18. package/dist/hooks/useToolConfirmation.js +49 -0
  19. package/dist/mcp/bash.d.ts +57 -0
  20. package/dist/mcp/bash.js +138 -0
  21. package/dist/mcp/filesystem.d.ts +307 -0
  22. package/dist/mcp/filesystem.js +520 -0
  23. package/dist/mcp/todo.d.ts +55 -0
  24. package/dist/mcp/todo.js +329 -0
  25. package/dist/test/logger-test.d.ts +1 -0
  26. package/dist/test/logger-test.js +7 -0
  27. package/dist/types/index.d.ts +1 -1
  28. package/dist/ui/components/ChatInput.d.ts +15 -2
  29. package/dist/ui/components/ChatInput.js +445 -59
  30. package/dist/ui/components/CommandPanel.d.ts +2 -2
  31. package/dist/ui/components/CommandPanel.js +11 -7
  32. package/dist/ui/components/DiffViewer.d.ts +9 -0
  33. package/dist/ui/components/DiffViewer.js +93 -0
  34. package/dist/ui/components/FileList.d.ts +14 -0
  35. package/dist/ui/components/FileList.js +131 -0
  36. package/dist/ui/components/MCPInfoPanel.d.ts +2 -0
  37. package/dist/ui/components/MCPInfoPanel.js +74 -0
  38. package/dist/ui/components/MCPInfoScreen.d.ts +7 -0
  39. package/dist/ui/components/MCPInfoScreen.js +27 -0
  40. package/dist/ui/components/MarkdownRenderer.d.ts +7 -0
  41. package/dist/ui/components/MarkdownRenderer.js +110 -0
  42. package/dist/ui/components/Menu.d.ts +5 -2
  43. package/dist/ui/components/Menu.js +60 -9
  44. package/dist/ui/components/MessageList.d.ts +30 -2
  45. package/dist/ui/components/MessageList.js +64 -12
  46. package/dist/ui/components/PendingMessages.js +1 -1
  47. package/dist/ui/components/ScrollableSelectInput.d.ts +29 -0
  48. package/dist/ui/components/ScrollableSelectInput.js +157 -0
  49. package/dist/ui/components/SessionListScreen.d.ts +7 -0
  50. package/dist/ui/components/SessionListScreen.js +196 -0
  51. package/dist/ui/components/SessionListScreenWrapper.d.ts +7 -0
  52. package/dist/ui/components/SessionListScreenWrapper.js +14 -0
  53. package/dist/ui/components/TodoTree.d.ts +15 -0
  54. package/dist/ui/components/TodoTree.js +60 -0
  55. package/dist/ui/components/ToolConfirmation.d.ts +8 -0
  56. package/dist/ui/components/ToolConfirmation.js +38 -0
  57. package/dist/ui/components/ToolResultPreview.d.ts +12 -0
  58. package/dist/ui/components/ToolResultPreview.js +115 -0
  59. package/dist/ui/pages/ChatScreen.d.ts +4 -0
  60. package/dist/ui/pages/ChatScreen.js +385 -196
  61. package/dist/ui/pages/MCPConfigScreen.d.ts +6 -0
  62. package/dist/ui/pages/MCPConfigScreen.js +55 -0
  63. package/dist/ui/pages/ModelConfigScreen.js +73 -12
  64. package/dist/ui/pages/WelcomeScreen.js +17 -11
  65. package/dist/utils/apiConfig.d.ts +12 -0
  66. package/dist/utils/apiConfig.js +95 -9
  67. package/dist/utils/commandExecutor.d.ts +2 -1
  68. package/dist/utils/commands/init.d.ts +2 -0
  69. package/dist/utils/commands/init.js +93 -0
  70. package/dist/utils/commands/mcp.d.ts +2 -0
  71. package/dist/utils/commands/mcp.js +12 -0
  72. package/dist/utils/commands/resume.d.ts +2 -0
  73. package/dist/utils/commands/resume.js +12 -0
  74. package/dist/utils/commands/yolo.d.ts +2 -0
  75. package/dist/utils/commands/yolo.js +12 -0
  76. package/dist/utils/fileUtils.d.ts +44 -0
  77. package/dist/utils/fileUtils.js +222 -0
  78. package/dist/utils/index.d.ts +4 -0
  79. package/dist/utils/index.js +6 -0
  80. package/dist/utils/logger.d.ts +31 -0
  81. package/dist/utils/logger.js +97 -0
  82. package/dist/utils/mcpToolsManager.d.ts +47 -0
  83. package/dist/utils/mcpToolsManager.js +476 -0
  84. package/dist/utils/messageFormatter.d.ts +12 -0
  85. package/dist/utils/messageFormatter.js +32 -0
  86. package/dist/utils/sessionConverter.d.ts +6 -0
  87. package/dist/utils/sessionConverter.js +61 -0
  88. package/dist/utils/sessionManager.d.ts +39 -0
  89. package/dist/utils/sessionManager.js +141 -0
  90. package/dist/utils/textBuffer.d.ts +36 -7
  91. package/dist/utils/textBuffer.js +265 -179
  92. package/dist/utils/todoPreprocessor.d.ts +5 -0
  93. package/dist/utils/todoPreprocessor.js +19 -0
  94. package/dist/utils/toolExecutor.d.ts +21 -0
  95. package/dist/utils/toolExecutor.js +28 -0
  96. package/package.json +12 -3
  97. package/readme.md +2 -2
@@ -1,6 +1,23 @@
1
+ import type { ChatCompletionTool } from 'openai/resources/chat/completions';
2
+ export interface ImageContent {
3
+ type: 'image';
4
+ data: string;
5
+ mimeType: string;
6
+ }
1
7
  export interface ChatMessage {
2
- role: 'system' | 'user' | 'assistant';
8
+ role: 'system' | 'user' | 'assistant' | 'tool';
3
9
  content: string;
10
+ tool_call_id?: string;
11
+ tool_calls?: ToolCall[];
12
+ images?: ImageContent[];
13
+ }
14
+ export interface ToolCall {
15
+ id: string;
16
+ type: 'function';
17
+ function: {
18
+ name: string;
19
+ arguments: string;
20
+ };
4
21
  }
5
22
  export interface ChatCompletionOptions {
6
23
  model: string;
@@ -8,6 +25,13 @@ export interface ChatCompletionOptions {
8
25
  stream?: boolean;
9
26
  temperature?: number;
10
27
  max_tokens?: number;
28
+ tools?: ChatCompletionTool[];
29
+ tool_choice?: 'auto' | 'none' | 'required' | {
30
+ type: 'function';
31
+ function: {
32
+ name: string;
33
+ };
34
+ };
11
35
  }
12
36
  export interface ChatCompletionChunk {
13
37
  id: string;
@@ -19,11 +43,50 @@ export interface ChatCompletionChunk {
19
43
  delta: {
20
44
  role?: string;
21
45
  content?: string;
46
+ tool_calls?: Array<{
47
+ index?: number;
48
+ id?: string;
49
+ type?: 'function';
50
+ function?: {
51
+ name?: string;
52
+ arguments?: string;
53
+ };
54
+ }>;
22
55
  };
23
56
  finish_reason?: string | null;
24
57
  }>;
25
58
  }
26
59
  export declare function resetOpenAIClient(): void;
60
+ /**
61
+ * Create chat completion with automatic function calling support
62
+ */
63
+ export declare function createChatCompletionWithTools(options: ChatCompletionOptions, maxToolRounds?: number): Promise<{
64
+ content: string;
65
+ toolCalls: ToolCall[];
66
+ }>;
27
67
  export declare function createChatCompletion(options: ChatCompletionOptions): Promise<string>;
28
- export declare function createStreamingChatCompletion(options: ChatCompletionOptions, abortSignal?: AbortSignal): AsyncGenerator<string, void, unknown>;
68
+ export interface UsageInfo {
69
+ prompt_tokens: number;
70
+ completion_tokens: number;
71
+ total_tokens: number;
72
+ }
73
+ export interface StreamChunk {
74
+ type: 'content' | 'tool_calls' | 'tool_call_delta' | 'reasoning_delta' | 'done' | 'usage';
75
+ content?: string;
76
+ tool_calls?: Array<{
77
+ id: string;
78
+ type: 'function';
79
+ function: {
80
+ name: string;
81
+ arguments: string;
82
+ };
83
+ }>;
84
+ delta?: string;
85
+ usage?: UsageInfo;
86
+ }
87
+ /**
88
+ * Simple streaming chat completion - only handles OpenAI interaction
89
+ * Tool execution should be handled by the caller
90
+ */
91
+ export declare function createStreamingChatCompletion(options: ChatCompletionOptions, abortSignal?: AbortSignal): AsyncGenerator<StreamChunk, void, unknown>;
29
92
  export declare function validateChatOptions(options: ChatCompletionOptions): string[];
package/dist/api/chat.js CHANGED
@@ -1,5 +1,68 @@
1
1
  import OpenAI from 'openai';
2
2
  import { getOpenAiConfig } from '../utils/apiConfig.js';
3
+ import { executeMCPTool } from '../utils/mcpToolsManager.js';
4
+ import { SYSTEM_PROMPT } from './systemPrompt.js';
5
+ /**
6
+ * Convert our ChatMessage format to OpenAI's ChatCompletionMessageParam format
7
+ * Automatically prepends system prompt if not present
8
+ */
9
+ function convertToOpenAIMessages(messages, includeSystemPrompt = true) {
10
+ let result = messages.map(msg => {
11
+ // 如果消息包含图片,使用 content 数组格式
12
+ if (msg.role === 'user' && msg.images && msg.images.length > 0) {
13
+ const contentParts = [];
14
+ // 添加文本内容
15
+ if (msg.content) {
16
+ contentParts.push({
17
+ type: 'text',
18
+ text: msg.content
19
+ });
20
+ }
21
+ // 添加图片内容
22
+ for (const image of msg.images) {
23
+ contentParts.push({
24
+ type: 'image_url',
25
+ image_url: {
26
+ url: image.data // Base64 data URL
27
+ }
28
+ });
29
+ }
30
+ return {
31
+ role: 'user',
32
+ content: contentParts
33
+ };
34
+ }
35
+ const baseMessage = {
36
+ role: msg.role,
37
+ content: msg.content
38
+ };
39
+ if (msg.role === 'assistant' && msg.tool_calls) {
40
+ return {
41
+ ...baseMessage,
42
+ tool_calls: msg.tool_calls
43
+ };
44
+ }
45
+ if (msg.role === 'tool' && msg.tool_call_id) {
46
+ return {
47
+ role: 'tool',
48
+ content: msg.content,
49
+ tool_call_id: msg.tool_call_id
50
+ };
51
+ }
52
+ return baseMessage;
53
+ });
54
+ // 如果需要系统提示词且第一条消息不是 system 消息,则添加
55
+ if (includeSystemPrompt && (result.length === 0 || result[0]?.role !== 'system')) {
56
+ result = [
57
+ {
58
+ role: 'system',
59
+ content: SYSTEM_PROMPT
60
+ },
61
+ ...result
62
+ ];
63
+ }
64
+ return result;
65
+ }
3
66
  let openaiClient = null;
4
67
  function getOpenAIClient() {
5
68
  if (!openaiClient) {
@@ -17,17 +80,134 @@ function getOpenAIClient() {
17
80
  export function resetOpenAIClient() {
18
81
  openaiClient = null;
19
82
  }
83
+ /**
84
+ * Create chat completion with automatic function calling support
85
+ */
86
+ export async function createChatCompletionWithTools(options, maxToolRounds = 5) {
87
+ const client = getOpenAIClient();
88
+ let messages = [...options.messages];
89
+ let allToolCalls = [];
90
+ let rounds = 0;
91
+ try {
92
+ while (rounds < maxToolRounds) {
93
+ const response = await client.chat.completions.create({
94
+ model: options.model,
95
+ messages: convertToOpenAIMessages(messages),
96
+ stream: false,
97
+ temperature: options.temperature || 0.7,
98
+ max_tokens: options.max_tokens,
99
+ tools: options.tools,
100
+ tool_choice: options.tool_choice,
101
+ });
102
+ const message = response.choices[0]?.message;
103
+ if (!message) {
104
+ throw new Error('No response from AI');
105
+ }
106
+ // Add assistant message to conversation
107
+ messages.push({
108
+ role: 'assistant',
109
+ content: message.content || '',
110
+ tool_calls: message.tool_calls
111
+ });
112
+ // Check if AI wants to call tools
113
+ if (message.tool_calls && message.tool_calls.length > 0) {
114
+ allToolCalls.push(...message.tool_calls);
115
+ // Execute each tool call
116
+ for (const toolCall of message.tool_calls) {
117
+ if (toolCall.type === 'function') {
118
+ try {
119
+ const args = JSON.parse(toolCall.function.arguments);
120
+ const result = await executeMCPTool(toolCall.function.name, args);
121
+ // Add tool result to conversation
122
+ messages.push({
123
+ role: 'tool',
124
+ content: JSON.stringify(result),
125
+ tool_call_id: toolCall.id
126
+ });
127
+ }
128
+ catch (error) {
129
+ // Add error result to conversation
130
+ messages.push({
131
+ role: 'tool',
132
+ content: `Error: ${error instanceof Error ? error.message : 'Tool execution failed'}`,
133
+ tool_call_id: toolCall.id
134
+ });
135
+ }
136
+ }
137
+ }
138
+ rounds++;
139
+ continue;
140
+ }
141
+ // No tool calls, return the content
142
+ return {
143
+ content: message.content || '',
144
+ toolCalls: allToolCalls
145
+ };
146
+ }
147
+ throw new Error(`Maximum tool calling rounds (${maxToolRounds}) exceeded`);
148
+ }
149
+ catch (error) {
150
+ if (error instanceof Error) {
151
+ throw new Error(`Chat completion with tools failed: ${error.message}`);
152
+ }
153
+ throw new Error('Chat completion with tools failed: Unknown error');
154
+ }
155
+ }
20
156
  export async function createChatCompletion(options) {
21
157
  const client = getOpenAIClient();
158
+ let messages = [...options.messages];
22
159
  try {
23
- const response = await client.chat.completions.create({
24
- model: options.model,
25
- messages: options.messages,
26
- stream: false,
27
- temperature: options.temperature || 0.7,
28
- max_tokens: options.max_tokens,
29
- });
30
- return response.choices[0]?.message?.content || '';
160
+ while (true) {
161
+ const response = await client.chat.completions.create({
162
+ model: options.model,
163
+ messages: convertToOpenAIMessages(messages),
164
+ stream: false,
165
+ temperature: options.temperature || 0.7,
166
+ max_tokens: options.max_tokens,
167
+ tools: options.tools,
168
+ tool_choice: options.tool_choice,
169
+ });
170
+ const message = response.choices[0]?.message;
171
+ if (!message) {
172
+ throw new Error('No response from AI');
173
+ }
174
+ // Add assistant message to conversation
175
+ messages.push({
176
+ role: 'assistant',
177
+ content: message.content || '',
178
+ tool_calls: message.tool_calls
179
+ });
180
+ // Check if AI wants to call tools
181
+ if (message.tool_calls && message.tool_calls.length > 0) {
182
+ // Execute each tool call
183
+ for (const toolCall of message.tool_calls) {
184
+ if (toolCall.type === 'function') {
185
+ try {
186
+ const args = JSON.parse(toolCall.function.arguments);
187
+ const result = await executeMCPTool(toolCall.function.name, args);
188
+ // Add tool result to conversation
189
+ messages.push({
190
+ role: 'tool',
191
+ content: JSON.stringify(result),
192
+ tool_call_id: toolCall.id
193
+ });
194
+ }
195
+ catch (error) {
196
+ // Add error result to conversation
197
+ messages.push({
198
+ role: 'tool',
199
+ content: `Error: ${error instanceof Error ? error.message : 'Tool execution failed'}`,
200
+ tool_call_id: toolCall.id
201
+ });
202
+ }
203
+ }
204
+ }
205
+ // Continue the conversation with tool results
206
+ continue;
207
+ }
208
+ // No tool calls, return the content
209
+ return message.content || '';
210
+ }
31
211
  }
32
212
  catch (error) {
33
213
  if (error instanceof Error) {
@@ -36,31 +216,129 @@ export async function createChatCompletion(options) {
36
216
  throw new Error('Chat completion failed: Unknown error');
37
217
  }
38
218
  }
219
+ /**
220
+ * Simple streaming chat completion - only handles OpenAI interaction
221
+ * Tool execution should be handled by the caller
222
+ */
39
223
  export async function* createStreamingChatCompletion(options, abortSignal) {
40
224
  const client = getOpenAIClient();
41
225
  try {
42
226
  const stream = await client.chat.completions.create({
43
227
  model: options.model,
44
- messages: options.messages,
228
+ messages: convertToOpenAIMessages(options.messages),
45
229
  stream: true,
230
+ stream_options: { include_usage: true }, // Request usage data in stream
46
231
  temperature: options.temperature || 0.7,
47
232
  max_tokens: options.max_tokens,
233
+ tools: options.tools,
234
+ tool_choice: options.tool_choice,
48
235
  }, {
49
236
  signal: abortSignal,
50
237
  });
238
+ let contentBuffer = '';
239
+ let toolCallsBuffer = {};
240
+ let hasToolCalls = false;
241
+ let usageData;
51
242
  for await (const chunk of stream) {
52
243
  if (abortSignal?.aborted) {
53
- break;
244
+ return;
245
+ }
246
+ // Capture usage information if available (usually in the last chunk)
247
+ const usageValue = chunk.usage;
248
+ if (usageValue !== null && usageValue !== undefined) {
249
+ usageData = {
250
+ prompt_tokens: usageValue.prompt_tokens || 0,
251
+ completion_tokens: usageValue.completion_tokens || 0,
252
+ total_tokens: usageValue.total_tokens || 0
253
+ };
54
254
  }
55
- const content = chunk.choices[0]?.delta?.content;
255
+ // Skip content processing if no choices (but usage is already captured above)
256
+ const choice = chunk.choices[0];
257
+ if (!choice) {
258
+ continue;
259
+ }
260
+ // Stream content chunks
261
+ const content = choice.delta?.content;
56
262
  if (content) {
57
- yield content;
263
+ contentBuffer += content;
264
+ yield {
265
+ type: 'content',
266
+ content
267
+ };
268
+ }
269
+ // Stream reasoning content (for o1 models, etc.)
270
+ // Note: reasoning_content is NOT included in the response, only counted for tokens
271
+ const reasoningContent = choice.delta?.reasoning_content;
272
+ if (reasoningContent) {
273
+ yield {
274
+ type: 'reasoning_delta',
275
+ delta: reasoningContent
276
+ };
277
+ }
278
+ // Accumulate tool calls and stream deltas
279
+ const deltaToolCalls = choice.delta?.tool_calls;
280
+ if (deltaToolCalls) {
281
+ hasToolCalls = true;
282
+ for (const deltaCall of deltaToolCalls) {
283
+ const index = deltaCall.index ?? 0;
284
+ if (!toolCallsBuffer[index]) {
285
+ toolCallsBuffer[index] = {
286
+ id: '',
287
+ type: 'function',
288
+ function: {
289
+ name: '',
290
+ arguments: ''
291
+ }
292
+ };
293
+ }
294
+ if (deltaCall.id) {
295
+ toolCallsBuffer[index].id = deltaCall.id;
296
+ }
297
+ // Yield tool call deltas for token counting
298
+ let deltaText = '';
299
+ if (deltaCall.function?.name) {
300
+ toolCallsBuffer[index].function.name += deltaCall.function.name;
301
+ deltaText += deltaCall.function.name;
302
+ }
303
+ if (deltaCall.function?.arguments) {
304
+ toolCallsBuffer[index].function.arguments += deltaCall.function.arguments;
305
+ deltaText += deltaCall.function.arguments;
306
+ }
307
+ // Stream the delta to frontend for real-time token counting
308
+ if (deltaText) {
309
+ yield {
310
+ type: 'tool_call_delta',
311
+ delta: deltaText
312
+ };
313
+ }
314
+ }
315
+ }
316
+ if (choice.finish_reason) {
317
+ break;
58
318
  }
59
319
  }
320
+ // If there are tool calls, yield them
321
+ if (hasToolCalls) {
322
+ yield {
323
+ type: 'tool_calls',
324
+ tool_calls: Object.values(toolCallsBuffer)
325
+ };
326
+ }
327
+ // Yield usage information if available
328
+ if (usageData) {
329
+ yield {
330
+ type: 'usage',
331
+ usage: usageData
332
+ };
333
+ }
334
+ // Signal completion
335
+ yield {
336
+ type: 'done'
337
+ };
60
338
  }
61
339
  catch (error) {
62
340
  if (error instanceof Error && error.name === 'AbortError') {
63
- return; // Silently handle abort
341
+ return;
64
342
  }
65
343
  if (error instanceof Error) {
66
344
  throw new Error(`Streaming chat completion failed: ${error.message}`);
@@ -77,11 +355,16 @@ export function validateChatOptions(options) {
77
355
  errors.push('At least one message is required');
78
356
  }
79
357
  for (const message of options.messages || []) {
80
- if (!message.role || !['system', 'user', 'assistant'].includes(message.role)) {
358
+ if (!message.role || !['system', 'user', 'assistant', 'tool'].includes(message.role)) {
81
359
  errors.push('Invalid message role');
82
360
  }
83
- if (!message.content || message.content.trim().length === 0) {
84
- errors.push('Message content cannot be empty');
361
+ // Tool messages must have tool_call_id
362
+ if (message.role === 'tool' && !message.tool_call_id) {
363
+ errors.push('Tool messages must have tool_call_id');
364
+ }
365
+ // Content can be empty for tool calls
366
+ if (message.role !== 'tool' && (!message.content || message.content.trim().length === 0)) {
367
+ errors.push('Message content cannot be empty (except for tool messages)');
85
368
  }
86
369
  }
87
370
  return errors;
@@ -0,0 +1,52 @@
1
+ import type { ChatMessage, ToolCall } from './chat.js';
2
+ export interface ResponseOptions {
3
+ model: string;
4
+ messages: ChatMessage[];
5
+ stream?: boolean;
6
+ temperature?: number;
7
+ max_tokens?: number;
8
+ tools?: Array<{
9
+ type: 'function';
10
+ function: {
11
+ name: string;
12
+ description?: string;
13
+ parameters?: Record<string, any>;
14
+ };
15
+ }>;
16
+ tool_choice?: 'auto' | 'none' | 'required';
17
+ reasoning?: {
18
+ summary?: 'auto' | 'none';
19
+ effort?: 'low' | 'medium' | 'high';
20
+ };
21
+ prompt_cache_key?: string;
22
+ store?: boolean;
23
+ include?: string[];
24
+ }
25
+ export interface UsageInfo {
26
+ prompt_tokens: number;
27
+ completion_tokens: number;
28
+ total_tokens: number;
29
+ }
30
+ export interface ResponseStreamChunk {
31
+ type: 'content' | 'tool_calls' | 'tool_call_delta' | 'reasoning_delta' | 'done' | 'usage';
32
+ content?: string;
33
+ tool_calls?: ToolCall[];
34
+ delta?: string;
35
+ usage?: UsageInfo;
36
+ }
37
+ export declare function resetOpenAIClient(): void;
38
+ /**
39
+ * 使用 Responses API 创建响应(非流式,带自动工具调用)
40
+ */
41
+ export declare function createResponse(options: ResponseOptions): Promise<string>;
42
+ /**
43
+ * 使用 Responses API 创建流式响应(带自动工具调用)
44
+ */
45
+ export declare function createStreamingResponse(options: ResponseOptions, abortSignal?: AbortSignal): AsyncGenerator<ResponseStreamChunk, void, unknown>;
46
+ /**
47
+ * 使用 Responses API 创建响应(限制工具调用轮数)
48
+ */
49
+ export declare function createResponseWithTools(options: ResponseOptions, maxToolRounds?: number): Promise<{
50
+ content: string;
51
+ toolCalls: ToolCall[];
52
+ }>;