symposium 2.4.2 → 3.0.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.
@@ -27,16 +27,16 @@ export default class GroqModel extends Model {
27
27
  return this.groq;
28
28
  }
29
29
 
30
- async generate(model, thread, functions = [], options = {}) {
31
- const parsed = this.parseOptions(options, functions);
30
+ async *generate(model, thread, tools = [], options = {}) {
31
+ const parsed = this.parseOptions(options, tools);
32
32
  options = parsed.options;
33
- functions = parsed.functions;
33
+ tools = parsed.tools;
34
34
 
35
35
  let messages = thread.messages;
36
36
 
37
- if (functions.length && !model.tools) {
38
- // Se il modello non supporta nativamente le funzioni, inserisco il prompt ad hoc come ultimo messaggio di sistema
39
- const functions_prompt = this.promptFromFunctions(options, functions);
37
+ if (tools.length && !model.tools) {
38
+ // Se il modello non supporta nativamente gli strumenti, inserisco il prompt ad hoc come ultimo messaggio di sistema
39
+ const tools_prompt = this.promptFromTools(options, tools);
40
40
  let system_messages = [], other_messages = [], first_found = false;
41
41
  for (let message of messages) {
42
42
  if (!first_found && message.role !== 'system')
@@ -48,10 +48,10 @@ export default class GroqModel extends Model {
48
48
  other_messages.push(message);
49
49
  }
50
50
 
51
- system_messages.push(new Message('system', functions_prompt));
51
+ system_messages.push(new Message('system', tools_prompt));
52
52
 
53
53
  messages = [...system_messages, ...other_messages];
54
- functions = [];
54
+ tools = [];
55
55
  }
56
56
 
57
57
  const convertedMessages = [];
@@ -61,45 +61,71 @@ export default class GroqModel extends Model {
61
61
  const completion_payload = {
62
62
  model: model.name,
63
63
  messages: convertedMessages,
64
- tools: functions.map(f => ({
64
+ tools: tools.map(t => ({
65
65
  type: 'function',
66
- function: f,
66
+ function: t,
67
67
  })),
68
68
  };
69
69
 
70
- if (options.force_function) {
70
+ if (options.force_tool) {
71
71
  completion_payload.tool_choice = {
72
72
  type: 'function',
73
- function: {name: options.force_function},
73
+ function: {name: options.force_tool},
74
74
  };
75
75
  }
76
76
 
77
77
  if (!completion_payload.tools.length)
78
78
  delete completion_payload.tools;
79
79
 
80
- const chatCompletion = await this.getGroq().chat.completions.create(completion_payload);
81
- const completion = chatCompletion.choices[0].message;
80
+ const stream = await this.getGroq().chat.completions.create({...completion_payload, stream: true});
82
81
 
83
- const message_content = [];
84
- if (completion.content)
85
- message_content.push({type: 'text', content: completion.content});
82
+ let fullText = '';
83
+ const toolBuffer = new Map();
86
84
 
87
- if (completion.tool_calls?.length) {
88
- message_content.push({
89
- type: 'function',
90
- content: completion.tool_calls.map(tool_call => {
91
- if (tool_call.type !== 'function')
92
- throw new Error('Unsupported tool type ' + tool_call.type);
93
-
94
- return {
95
- id: tool_call.id,
96
- name: tool_call.function.name,
97
- arguments: tool_call.function.arguments ? JSON.parse(tool_call.function.arguments) : {},
98
- };
99
- }),
100
- });
85
+ for await (const chunk of stream) {
86
+ const delta = chunk.choices?.[0]?.delta;
87
+ if (!delta)
88
+ continue;
89
+
90
+ if (delta.content) {
91
+ fullText += delta.content;
92
+ yield {type: 'text_delta', content: delta.content};
93
+ }
94
+
95
+ if (delta.tool_calls) {
96
+ for (const tc of delta.tool_calls) {
97
+ const idx = tc.index;
98
+ if (!toolBuffer.has(idx))
99
+ toolBuffer.set(idx, {id: '', name: '', argumentsRaw: ''});
100
+ const buf = toolBuffer.get(idx);
101
+ if (tc.id)
102
+ buf.id = tc.id;
103
+ if (tc.function?.name)
104
+ buf.name = tc.function.name;
105
+ if (tc.function?.arguments)
106
+ buf.argumentsRaw += tc.function.arguments;
107
+ }
108
+ }
101
109
  }
102
110
 
111
+ const toolCalls = [];
112
+ for (const [, buf] of [...toolBuffer.entries()].sort((a, b) => a[0] - b[0])) {
113
+ const tc = {
114
+ id: buf.id,
115
+ name: buf.name,
116
+ arguments: buf.argumentsRaw ? JSON.parse(buf.argumentsRaw) : {},
117
+ };
118
+ toolCalls.push(tc);
119
+ yield {type: 'tool_call', content: tc};
120
+ }
121
+
122
+ const message_content = [];
123
+ if (fullText)
124
+ message_content.push({type: 'text', content: fullText});
125
+
126
+ if (toolCalls.length)
127
+ message_content.push({type: 'tool_call', content: toolCalls});
128
+
103
129
  return [
104
130
  new Message('assistant', message_content),
105
131
  ];
@@ -132,7 +158,7 @@ export default class GroqModel extends Model {
132
158
  });
133
159
  break;
134
160
 
135
- case 'function':
161
+ case 'tool_call':
136
162
  if (model.tools) {
137
163
  messages.push({
138
164
  role: message.role,
@@ -149,13 +175,13 @@ export default class GroqModel extends Model {
149
175
  } else {
150
176
  messages.push({
151
177
  role: message.role,
152
- content: c.content.map(f => '```CALL \n' + f.name + '\n' + JSON.stringify(f.arguments || {}) + '\n```').join("\n\n"),
178
+ content: c.content.map(t => '```CALL \n' + t.name + '\n' + JSON.stringify(t.arguments || {}) + '\n```').join("\n\n"),
153
179
  name: message.name,
154
180
  });
155
181
  }
156
182
  break;
157
183
 
158
- case 'function_response':
184
+ case 'tool_result':
159
185
  if (model.tools) {
160
186
  messages.push({
161
187
  role: message.role,
@@ -166,7 +192,7 @@ export default class GroqModel extends Model {
166
192
  } else {
167
193
  messages.push({
168
194
  role: 'user',
169
- content: 'FUNCTION RESPONSE:\n' + JSON.stringify(c.content.response),
195
+ content: 'TOOL RESPONSE:\n' + JSON.stringify(c.content.response),
170
196
  name: message.name,
171
197
  });
172
198
  }
@@ -17,16 +17,16 @@ export default class LegacyOpenAIModel extends Model {
17
17
  return this.openai;
18
18
  }
19
19
 
20
- async generate(model, thread, functions = [], options = {}) {
21
- const parsed = this.parseOptions(options, functions);
20
+ async *generate(model, thread, tools = [], options = {}) {
21
+ const parsed = this.parseOptions(options, tools);
22
22
  options = parsed.options;
23
- functions = parsed.functions;
23
+ tools = parsed.tools;
24
24
 
25
25
  let messages = thread.messages;
26
26
 
27
- if (functions.length && !model.tools) {
28
- // Se il modello non supporta nativamente le funzioni, inserisco il prompt ad hoc come ultimo messaggio di sistema
29
- const functions_prompt = this.promptFromFunctions(options, functions);
27
+ if (tools.length && !model.tools) {
28
+ // Se il modello non supporta nativamente gli strumenti, inserisco il prompt ad hoc come ultimo messaggio di sistema
29
+ const tools_prompt = this.promptFromTools(options, tools);
30
30
  let system_messages = [], other_messages = [], first_found = false;
31
31
  for (let message of messages) {
32
32
  if (!first_found && message.role !== 'system')
@@ -38,10 +38,10 @@ export default class LegacyOpenAIModel extends Model {
38
38
  other_messages.push(message);
39
39
  }
40
40
 
41
- system_messages.push(new Message('system', functions_prompt));
41
+ system_messages.push(new Message('system', tools_prompt));
42
42
 
43
43
  messages = [...system_messages, ...other_messages];
44
- functions = [];
44
+ tools = [];
45
45
  }
46
46
 
47
47
  const convertedMessages = [];
@@ -51,16 +51,16 @@ export default class LegacyOpenAIModel extends Model {
51
51
  const completion_payload = {
52
52
  model: model.name,
53
53
  messages: convertedMessages,
54
- tools: functions.map(f => ({
54
+ tools: tools.map(t => ({
55
55
  type: 'function',
56
- function: f,
56
+ function: t,
57
57
  })),
58
58
  };
59
59
 
60
- if (options.force_function) {
60
+ if (options.force_tool) {
61
61
  completion_payload.tool_choice = {
62
62
  type: 'function',
63
- function: {name: options.force_function},
63
+ function: {name: options.force_tool},
64
64
  };
65
65
  }
66
66
 
@@ -70,29 +70,55 @@ export default class LegacyOpenAIModel extends Model {
70
70
  if (!completion_payload.tools.length)
71
71
  delete completion_payload.tools;
72
72
 
73
- const chatCompletion = await this.getOpenAi().chat.completions.create(completion_payload);
74
- const completion = chatCompletion.choices[0].message;
73
+ const stream = await this.getOpenAi().chat.completions.create({...completion_payload, stream: true});
75
74
 
76
- const message_content = [];
77
- if (completion.content)
78
- message_content.push({type: 'text', content: completion.content});
75
+ let fullText = '';
76
+ const toolBuffer = new Map();
79
77
 
80
- if (completion.tool_calls?.length) {
81
- message_content.push({
82
- type: 'function',
83
- content: completion.tool_calls.map(tool_call => {
84
- if (tool_call.type !== 'function')
85
- throw new Error('Unsupported tool type ' + tool_call.type);
86
-
87
- return {
88
- id: tool_call.id,
89
- name: tool_call.function.name,
90
- arguments: tool_call.function.arguments ? JSON.parse(tool_call.function.arguments) : {},
91
- };
92
- }),
93
- });
78
+ for await (const chunk of stream) {
79
+ const delta = chunk.choices?.[0]?.delta;
80
+ if (!delta)
81
+ continue;
82
+
83
+ if (delta.content) {
84
+ fullText += delta.content;
85
+ yield {type: 'text_delta', content: delta.content};
86
+ }
87
+
88
+ if (delta.tool_calls) {
89
+ for (const tc of delta.tool_calls) {
90
+ const idx = tc.index;
91
+ if (!toolBuffer.has(idx))
92
+ toolBuffer.set(idx, {id: '', name: '', argumentsRaw: ''});
93
+ const buf = toolBuffer.get(idx);
94
+ if (tc.id)
95
+ buf.id = tc.id;
96
+ if (tc.function?.name)
97
+ buf.name = tc.function.name;
98
+ if (tc.function?.arguments)
99
+ buf.argumentsRaw += tc.function.arguments;
100
+ }
101
+ }
94
102
  }
95
103
 
104
+ const toolCalls = [];
105
+ for (const [, buf] of [...toolBuffer.entries()].sort((a, b) => a[0] - b[0])) {
106
+ const tc = {
107
+ id: buf.id,
108
+ name: buf.name,
109
+ arguments: buf.argumentsRaw ? JSON.parse(buf.argumentsRaw) : {},
110
+ };
111
+ toolCalls.push(tc);
112
+ yield {type: 'tool_call', content: tc};
113
+ }
114
+
115
+ const message_content = [];
116
+ if (fullText)
117
+ message_content.push({type: 'text', content: fullText});
118
+
119
+ if (toolCalls.length)
120
+ message_content.push({type: 'tool_call', content: toolCalls});
121
+
96
122
  return [
97
123
  new Message('assistant', message_content),
98
124
  ];
@@ -173,7 +199,7 @@ export default class LegacyOpenAIModel extends Model {
173
199
  }
174
200
  break;
175
201
 
176
- case 'function':
202
+ case 'tool_call':
177
203
  if (model.tools) {
178
204
  messages.push({
179
205
  role,
@@ -190,13 +216,13 @@ export default class LegacyOpenAIModel extends Model {
190
216
  } else {
191
217
  messages.push({
192
218
  role,
193
- content: c.content.map(f => '```CALL \n' + f.name + '\n' + JSON.stringify(f.arguments || {}) + '\n```').join("\n\n"),
219
+ content: c.content.map(t => '```CALL \n' + t.name + '\n' + JSON.stringify(t.arguments || {}) + '\n```').join("\n\n"),
194
220
  name: message.name,
195
221
  });
196
222
  }
197
223
  break;
198
224
 
199
- case 'function_response':
225
+ case 'tool_result':
200
226
  if (model.tools) {
201
227
  messages.push({
202
228
  role,
@@ -207,7 +233,7 @@ export default class LegacyOpenAIModel extends Model {
207
233
  } else {
208
234
  messages.push({
209
235
  role: 'user',
210
- content: 'FUNCTION RESPONSE:\n' + JSON.stringify(c.content.response),
236
+ content: 'TOOL RESPONSE:\n' + JSON.stringify(c.content.response),
211
237
  name: message.name,
212
238
  });
213
239
  }
@@ -3,9 +3,13 @@ import Model from "../Model.js";
3
3
  import Message from "../Message.js";
4
4
 
5
5
  export default class OllamaModel extends Model {
6
+ getOllama() {
7
+ return ollama;
8
+ }
9
+
6
10
  async getModels() {
7
11
  try {
8
- const {models} = await ollama.list();
12
+ const {models} = await this.getOllama().list();
9
13
 
10
14
  const map = new Map();
11
15
 
@@ -25,16 +29,16 @@ export default class OllamaModel extends Model {
25
29
  }
26
30
  }
27
31
 
28
- async generate(model, thread, functions = [], options = {}) {
29
- const parsed = this.parseOptions(options, functions);
32
+ async *generate(model, thread, tools = [], options = {}) {
33
+ const parsed = this.parseOptions(options, tools);
30
34
  options = parsed.options;
31
- functions = parsed.functions;
35
+ tools = parsed.tools;
32
36
 
33
37
  let messages = thread.messages;
34
38
 
35
- if (functions.length && !model.tools) {
36
- // Se il modello non supporta nativamente le funzioni, inserisco il prompt ad hoc come ultimo messaggio di sistema
37
- const functions_prompt = this.promptFromFunctions(options, functions);
39
+ if (tools.length && !model.tools) {
40
+ // Se il modello non supporta nativamente gli strumenti, inserisco il prompt ad hoc come ultimo messaggio di sistema
41
+ const tools_prompt = this.promptFromTools(options, tools);
38
42
  let system_messages = [], other_messages = [], first_found = false;
39
43
  for (let message of messages) {
40
44
  if (!first_found && message.role !== 'system')
@@ -46,10 +50,10 @@ export default class OllamaModel extends Model {
46
50
  other_messages.push(message);
47
51
  }
48
52
 
49
- system_messages.push(new Message('system', functions_prompt));
53
+ system_messages.push(new Message('system', tools_prompt));
50
54
 
51
55
  messages = [...system_messages, ...other_messages];
52
- functions = [];
56
+ tools = [];
53
57
  }
54
58
 
55
59
  const convertedMessages = [];
@@ -59,16 +63,17 @@ export default class OllamaModel extends Model {
59
63
  const completion_payload = {
60
64
  model: model.name,
61
65
  messages: convertedMessages,
62
- tools: functions.map(f => ({
66
+ tools: tools.map(t => ({
63
67
  type: 'function',
64
- function: f,
68
+ function: t,
65
69
  })),
70
+ stream: true,
66
71
  };
67
72
 
68
- if (options.force_function) {
73
+ if (options.force_tool) {
69
74
  completion_payload.tool_choice = {
70
75
  type: 'function',
71
- function: {name: options.force_function},
76
+ function: {name: options.force_tool},
72
77
  };
73
78
  }
74
79
 
@@ -81,31 +86,52 @@ export default class OllamaModel extends Model {
81
86
  if (!completion_payload.tools.length)
82
87
  delete completion_payload.tools;
83
88
 
84
- const chatCompletion = await ollama.chat(completion_payload);
85
- const completion = chatCompletion.message;
89
+ const stream = await this.getOllama().chat(completion_payload);
86
90
 
87
- const message_content = [];
88
- if (completion.thinking)
89
- message_content.push({type: 'reasoning', content: completion.thinking});
91
+ let fullText = '';
92
+ let fullThinking = '';
93
+ const toolCalls = [];
90
94
 
91
- if (completion.content)
92
- message_content.push({type: 'text', content: completion.content});
95
+ for await (const chunk of stream) {
96
+ const m = chunk.message;
97
+ if (!m)
98
+ continue;
93
99
 
94
- if (completion.tool_calls?.length) {
95
- message_content.push({
96
- type: 'function',
97
- content: completion.tool_calls.map(tool_call => {
100
+ if (m.thinking) {
101
+ fullThinking += m.thinking;
102
+ yield {type: 'reasoning_delta', content: m.thinking};
103
+ }
104
+
105
+ if (m.content) {
106
+ fullText += m.content;
107
+ yield {type: 'text_delta', content: m.content};
108
+ }
109
+
110
+ if (m.tool_calls?.length) {
111
+ for (const tool_call of m.tool_calls) {
98
112
  if (!tool_call.function)
99
113
  throw new Error('Unsupported tool type');
100
114
 
101
- return {
115
+ const tc = {
102
116
  name: tool_call.function.name,
103
117
  arguments: tool_call.function.arguments || {},
104
118
  };
105
- }),
106
- });
119
+ toolCalls.push(tc);
120
+ yield {type: 'tool_call', content: tc};
121
+ }
122
+ }
107
123
  }
108
124
 
125
+ const message_content = [];
126
+ if (fullThinking)
127
+ message_content.push({type: 'reasoning', content: fullThinking});
128
+
129
+ if (fullText)
130
+ message_content.push({type: 'text', content: fullText});
131
+
132
+ if (toolCalls.length)
133
+ message_content.push({type: 'tool_call', content: toolCalls});
134
+
109
135
  return [
110
136
  new Message('assistant', message_content),
111
137
  ];
@@ -130,7 +156,7 @@ export default class OllamaModel extends Model {
130
156
  });
131
157
  break;
132
158
 
133
- case 'function':
159
+ case 'tool_call':
134
160
  if (model.tools) {
135
161
  messages.push({
136
162
  role,
@@ -148,12 +174,12 @@ export default class OllamaModel extends Model {
148
174
  messages.push({
149
175
  role,
150
176
  thinking: reasoning || undefined,
151
- content: c.content.map(f => '```CALL \n' + f.name + '\n' + JSON.stringify(f.arguments || {}) + '\n```').join("\n\n"),
177
+ content: c.content.map(t => '```CALL \n' + t.name + '\n' + JSON.stringify(t.arguments || {}) + '\n```').join("\n\n"),
152
178
  });
153
179
  }
154
180
  break;
155
181
 
156
- case 'function_response':
182
+ case 'tool_result':
157
183
  if (model.tools) {
158
184
  messages.push({
159
185
  role: 'tool',
@@ -163,7 +189,7 @@ export default class OllamaModel extends Model {
163
189
  } else {
164
190
  messages.push({
165
191
  role: 'user',
166
- content: 'FUNCTION RESPONSE:\n' + JSON.stringify(c.content.response),
192
+ content: 'TOOL RESPONSE:\n' + JSON.stringify(c.content.response),
167
193
  });
168
194
  }
169
195
  break;
@@ -58,6 +58,15 @@ export default class OpenAIModel extends Model {
58
58
  audio: false,
59
59
  image_generation: false,
60
60
  }],
61
+ ['gpt-5.4', {
62
+ name: 'gpt-5.4',
63
+ tiktoken: 'gpt-4',
64
+ tokens: 1000000,
65
+ tools: true,
66
+ structured_output: true,
67
+ audio: false,
68
+ image_generation: false,
69
+ }],
61
70
  ]);
62
71
  }
63
72
 
@@ -68,16 +77,16 @@ export default class OpenAIModel extends Model {
68
77
  return this.openai;
69
78
  }
70
79
 
71
- async generate(model, thread, functions = [], options = {}) {
72
- const parsed = this.parseOptions(options, functions);
80
+ async *generate(model, thread, tools = [], options = {}) {
81
+ const parsed = this.parseOptions(options, tools);
73
82
  options = parsed.options;
74
- functions = parsed.functions;
83
+ tools = parsed.tools;
75
84
 
76
85
  let messages = thread.messages;
77
86
 
78
- if (functions.length && !model.tools) {
79
- // Se il modello non supporta nativamente le funzioni, inserisco il prompt ad hoc come ultimo messaggio di sistema
80
- const functions_prompt = this.promptFromFunctions(options, functions);
87
+ if (tools.length && !model.tools) {
88
+ // Se il modello non supporta nativamente gli strumenti, inserisco il prompt ad hoc come ultimo messaggio di sistema
89
+ const tools_prompt = this.promptFromTools(options, tools);
81
90
  let system_messages = [], other_messages = [], first_found = false;
82
91
  for (let message of messages) {
83
92
  if (!first_found && message.role !== 'system')
@@ -89,39 +98,39 @@ export default class OpenAIModel extends Model {
89
98
  other_messages.push(message);
90
99
  }
91
100
 
92
- system_messages.push(new Message('system', functions_prompt));
101
+ system_messages.push(new Message('system', tools_prompt));
93
102
 
94
103
  messages = [...system_messages, ...other_messages];
95
- functions = [];
104
+ tools = [];
96
105
  }
97
106
 
98
107
  const convertedMessages = [];
99
108
  for (let m of messages)
100
109
  convertedMessages.push(...(await this.convertMessage(m, model)));
101
110
 
102
- const tools = functions.map(f => ({
111
+ const apiTools = tools.map(t => ({
103
112
  type: 'function',
104
- ...f,
113
+ ...t,
105
114
  }));
106
115
 
107
116
  if (model.tools && model.image_generation && options.image_generation)
108
- tools.push({type: 'image_generation'});
117
+ apiTools.push({type: 'image_generation'});
109
118
 
110
119
  const completion_payload = {
111
120
  model: model.name,
112
121
  input: convertedMessages,
113
122
  store: false,
114
123
  include: ['reasoning.encrypted_content'],
115
- tools,
124
+ tools: apiTools,
116
125
  reasoning: {
117
126
  summary: 'auto',
118
127
  },
119
128
  };
120
129
 
121
- if (options.force_function) {
130
+ if (options.force_tool) {
122
131
  completion_payload.tool_choice = {
123
132
  type: 'function',
124
- name: options.force_function,
133
+ name: options.force_tool,
125
134
  };
126
135
  }
127
136
 
@@ -131,7 +140,52 @@ export default class OpenAIModel extends Model {
131
140
  if (!completion_payload.tools.length)
132
141
  delete completion_payload.tools;
133
142
 
134
- const completion = await this.getOpenAi().responses.create(completion_payload);
143
+ const stream = this.getOpenAi().responses.stream(completion_payload);
144
+
145
+ for await (const event of stream) {
146
+ switch (event.type) {
147
+ case 'response.output_text.delta':
148
+ if (event.delta)
149
+ yield {type: 'text_delta', content: event.delta};
150
+ break;
151
+
152
+ case 'response.reasoning_summary_text.delta':
153
+ if (event.delta)
154
+ yield {type: 'reasoning_delta', content: event.delta};
155
+ break;
156
+
157
+ case 'response.output_item.done':
158
+ if (event.item?.type === 'function_call') {
159
+ yield {
160
+ type: 'tool_call',
161
+ content: {
162
+ id: event.item.call_id,
163
+ name: event.item.name,
164
+ arguments: event.item.arguments ? JSON.parse(event.item.arguments) : {},
165
+ },
166
+ };
167
+ } else if (event.item?.type === 'image_generation_call') {
168
+ const mime = event.item.output_format === 'png' ? 'image/png' : 'image/jpeg';
169
+ yield {
170
+ type: 'image',
171
+ content: {
172
+ type: 'base64',
173
+ mime,
174
+ data: event.item.result,
175
+ },
176
+ meta: {
177
+ id: event.item.id,
178
+ status: event.item.status,
179
+ prompt: event.item.revised_prompt,
180
+ size: event.item.size,
181
+ },
182
+ };
183
+ }
184
+ break;
185
+ }
186
+ }
187
+
188
+ const completion = await stream.finalResponse();
135
189
 
136
190
  const message_content = [];
137
191
  for (let output of completion.output) {
@@ -161,7 +215,7 @@ export default class OpenAIModel extends Model {
161
215
 
162
216
  case 'function_call':
163
217
  message_content.push({
164
- type: 'function',
218
+ type: 'tool_call',
165
219
  content: [
166
220
  {
167
221
  id: output.call_id,
@@ -275,7 +329,7 @@ export default class OpenAIModel extends Model {
275
329
  }
276
330
  break;
277
331
 
278
- case 'function':
332
+ case 'tool_call':
279
333
  if (model.tools) {
280
334
  messages.push({
281
335
  type: 'function_call',
@@ -286,12 +340,12 @@ export default class OpenAIModel extends Model {
286
340
  } else {
287
341
  messages.push({
288
342
  role,
289
- content: c.content.map(f => '```CALL \n' + f.name + '\n' + JSON.stringify(f.arguments || {}) + '\n```').join("\n\n"),
343
+ content: c.content.map(t => '```CALL \n' + t.name + '\n' + JSON.stringify(t.arguments || {}) + '\n```').join("\n\n"),
290
344
  });
291
345
  }
292
346
  break;
293
347
 
294
- case 'function_response':
348
+ case 'tool_result':
295
349
  if (model.tools) {
296
350
  messages.push({
297
351
  type: 'function_call_output',
@@ -301,7 +355,7 @@ export default class OpenAIModel extends Model {
301
355
  } else {
302
356
  messages.push({
303
357
  role: 'user',
304
- content: 'FUNCTION RESPONSE:\n' + JSON.stringify(c.content.response),
358
+ content: 'TOOL RESPONSE:\n' + JSON.stringify(c.content.response),
305
359
  });
306
360
  }
307
361
  break;