symposium 0.6.7 → 0.6.9

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/Agent.js CHANGED
@@ -162,7 +162,7 @@ export default class Agent {
162
162
 
163
163
  const match = text.match(/^CALL ([A-Za-z0-9_]+)\n([\s\S]*)$/);
164
164
  if (match)
165
- newContent.push({type: 'function', content: {name: match[1], arguments: JSON.parse(match[2] || '{}')}});
165
+ newContent.push({type: 'function', content: [{name: match[1], arguments: JSON.parse(match[2] || '{}')}]});
166
166
  else
167
167
  newContent.push({type: 'text', content: text});
168
168
  }
@@ -176,7 +176,7 @@ export default class Agent {
176
176
  }
177
177
 
178
178
  async handleCompletion(thread, completion) {
179
- let call_function = null;
179
+ const functions = [];
180
180
  for (let message of completion) {
181
181
  thread.addDirectMessage(message);
182
182
  await this.log('ai_message', message.content);
@@ -188,19 +188,30 @@ export default class Agent {
188
188
  break;
189
189
 
190
190
  case 'function':
191
- if (call_function)
192
- throw new Error('The model replied with more than one function');
193
- else
194
- call_function = m.content;
191
+ functions.push(m.content);
195
192
  break;
196
193
  }
197
194
  }
198
195
  }
199
196
 
200
- if (call_function)
201
- return this.callFunction(thread, call_function);
202
- else
203
- return thread.storeState();
197
+ if (functions.length) {
198
+ for(let f of functions) {
199
+ const response = await this.callFunction(thread, f);
200
+
201
+ thread.addMessage('tool', [
202
+ {
203
+ type: 'function_response',
204
+ content: {name: f.name, response, id: f.id || undefined},
205
+ },
206
+ ], f.name);
207
+
208
+ await this.log('function_response', response);
209
+ }
210
+
211
+ await this.execute(thread);
212
+ }else {
213
+ await thread.storeState();
214
+ }
204
215
  }
205
216
 
206
217
  async getFunctions(parsed = true) {
@@ -234,25 +245,10 @@ export default class Agent {
234
245
  await this.log('function_call', function_call);
235
246
 
236
247
  try {
237
- const response = await functions.get(function_call.name).tool.callFunction(thread, function_call.name, function_call.arguments);
238
- thread.addMessage('tool', [
239
- {
240
- type: 'function_response',
241
- content: {response, id: function_call.id || undefined},
242
- },
243
- ], function_call.name);
244
- await this.log('function_response', response);
248
+ return await functions.get(function_call.name).tool.callFunction(thread, function_call.name, function_call.arguments);
245
249
  } catch (error) {
246
- thread.addMessage('function', [
247
- {
248
- type: 'function_response',
249
- content: {response: {error}},
250
- },
251
- ], function_call.name);
252
- await this.log('function_response', {error});
250
+ return {error};
253
251
  }
254
-
255
- await this.execute(thread);
256
252
  }
257
253
 
258
254
  async setModel(thread, label) {
package/Summarizer.js CHANGED
@@ -78,11 +78,11 @@ export default class Summarizer extends MemoryHandler {
78
78
  if (message.role === 'system' && !message.tags.includes('summary')) {
79
79
  summarizedThread.messages.push(message);
80
80
  } else {
81
- const functionResponse = Symposium.extractFunctionFromResponse(summary);
82
- if (functionResponse)
81
+ const functionsResponse = Symposium.extractFunctionsFromResponse(summary);
82
+ if (functionsResponse.length)
83
83
  throw new Error('Errore durante la generazione di un riassunto interno');
84
84
 
85
- summarizedThread.addMessage('system', "This is what happened until now:\n" + functionResponse.summary, undefined, ['summary']);
85
+ summarizedThread.addMessage('system', "This is what happened until now:\n" + functionsResponse[0].summary, undefined, ['summary']);
86
86
  break;
87
87
  }
88
88
  }
package/Symposium.js CHANGED
@@ -2,7 +2,6 @@ import Redis from "@travio/redis";
2
2
  import Gpt35 from "./models/Gpt35.js";
3
3
  import Gpt4 from "./models/Gpt4.js";
4
4
  import Gpt4Turbo from "./models/Gpt4Turbo.js";
5
- import Gpt4Vision from "./models/Gpt4Vision.js";
6
5
  import Whisper from "./models/Whisper.js";
7
6
  import Claude3Haiku from "./models/Claude3Haiku.js";
8
7
  import Claude3Sonnet from "./models/Claude3Sonnet.js";
@@ -15,7 +14,6 @@ export default class Symposium {
15
14
  this.loadModel(new Gpt35());
16
15
  this.loadModel(new Gpt4());
17
16
  this.loadModel(new Gpt4Turbo());
18
- this.loadModel(new Gpt4Vision());
19
17
  this.loadModel(new Whisper());
20
18
 
21
19
  this.loadModel(new Claude3Haiku());
@@ -37,13 +35,14 @@ export default class Symposium {
37
35
  return Array.from(this.models.values()).find(model => model.label === label);
38
36
  }
39
37
 
40
- static extractFunctionFromResponse(messages) {
38
+ static extractFunctionsFromResponse(messages) {
39
+ const functions = [];
41
40
  for (let message of messages) {
42
41
  const functionResponse = message.content.filter(c => c.type === 'function');
43
42
  if (functionResponse.length)
44
- return functionResponse[0].content.arguments;
43
+ functions.push(functionResponse[0].content.arguments)
45
44
  }
46
45
 
47
- return null;
46
+ return functions;
48
47
  }
49
48
  }
@@ -62,11 +62,13 @@ export default class AnthropicModel extends Model {
62
62
  case 'tool_use':
63
63
  message_content.push({
64
64
  type: 'function',
65
- content: {
66
- id: m.id,
67
- name: m.name,
68
- arguments: m.input,
69
- },
65
+ content: [
66
+ {
67
+ id: m.id,
68
+ name: m.name,
69
+ arguments: m.input,
70
+ },
71
+ ],
70
72
  });
71
73
  break;
72
74
 
@@ -100,9 +102,9 @@ export default class AnthropicModel extends Model {
100
102
  case 'function':
101
103
  return {
102
104
  type: 'tool_use',
103
- name: c.content.name,
104
- input: c.content.arguments,
105
- id: c.content.id,
105
+ name: c.content[0].name,
106
+ input: c.content[0].arguments,
107
+ id: c.content[0].id,
106
108
  };
107
109
 
108
110
  case 'function_response':
@@ -62,8 +62,8 @@ export default class OpenAIModel extends Model {
62
62
  };
63
63
  }
64
64
 
65
- if (!completion_payload.functions.length)
66
- delete completion_payload.functions;
65
+ if (!completion_payload.tools.length)
66
+ delete completion_payload.tools;
67
67
 
68
68
  const chatCompletion = await this.getOpenAi().chat.completions.create(completion_payload);
69
69
  const completion = chatCompletion.choices[0].message;
@@ -72,20 +72,20 @@ export default class OpenAIModel extends Model {
72
72
  if (completion.content)
73
73
  message_content.push({type: 'text', content: completion.content});
74
74
 
75
- if (completion.tool_calls) {
76
- for (let tool_call of completion.tool_calls) {
77
- if (tool_call.type !== 'function')
78
- throw new Error('Unsupported tool type ' + tool_call.type);
75
+ if (completion.tool_calls?.length) {
76
+ message_content.push({
77
+ type: 'function',
78
+ content: completion.tool_calls.map(tool_call => {
79
+ if (tool_call.type !== 'function')
80
+ throw new Error('Unsupported tool type ' + tool_call.type);
79
81
 
80
- message_content.push({
81
- type: 'function',
82
- content: {
82
+ return {
83
83
  id: tool_call.id,
84
84
  name: tool_call.function.name,
85
85
  arguments: tool_call.function.arguments ? JSON.parse(tool_call.function.arguments) : {},
86
- },
87
- });
88
- }
86
+ };
87
+ }),
88
+ });
89
89
  }
90
90
 
91
91
  return [
@@ -123,21 +123,19 @@ export default class OpenAIModel extends Model {
123
123
  messages.push({
124
124
  role: message.role,
125
125
  name: message.name,
126
- tool_calls: [
127
- {
128
- id: c.content.id,
129
- type: 'function',
130
- function: {
131
- name: c.content.name,
132
- arguments: c.content.arguments ? JSON.stringify(c.content.arguments) : '{}',
133
- },
126
+ tool_calls: c.content.map(tool_call => ({
127
+ id: tool_call.id,
128
+ type: 'function',
129
+ function: {
130
+ name: tool_call.name,
131
+ arguments: tool_call.arguments ? JSON.stringify(tool_call.arguments) : '{}',
134
132
  },
135
- ],
133
+ })),
136
134
  });
137
135
  } else {
138
136
  messages.push({
139
137
  role: message.role,
140
- content: '```CALL \n' + c.content.name + '\n' + JSON.stringify(c.content.arguments || {}) + '\n```',
138
+ content: c.content.map(f => '```CALL \n' + f.name + '\n' + JSON.stringify(f.arguments || {}) + '\n```').join("\n\n"),
141
139
  name: message.name,
142
140
  });
143
141
  }
@@ -147,7 +145,6 @@ export default class OpenAIModel extends Model {
147
145
  if (this.supports_functions) {
148
146
  messages.push({
149
147
  role: message.role,
150
- type: 'tool_result',
151
148
  tool_call_id: c.content.id,
152
149
  content: JSON.stringify(c.content.response),
153
150
  name: message.name,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "symposium",
4
- "version": "0.6.7",
4
+ "version": "0.6.9",
5
5
  "description": "Agents",
6
6
  "main": "index.js",
7
7
  "author": "Domenico Giambra",