symposium 0.13.9 → 0.14.1

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
@@ -88,6 +88,17 @@ export default class Agent {
88
88
  this.callbacks[i + '-' + thread.id].push(callback);
89
89
  }
90
90
 
91
+ const model = Symposium.getModelByName(thread.state.model);
92
+ if (!model.supports_audio) {
93
+ for (let c of content) {
94
+ if (c.type === 'audio' && !c.content?.transcription) {
95
+ const words = await this.getPromptWordsForTranscription(thread);
96
+ const prompt = words.length ? 'Possibili parole usate: ' + words.join(', ') : null;
97
+ c.content.transcription = await Symposium.transcribe(c.content, prompt);
98
+ }
99
+ }
100
+ }
101
+
91
102
  await this.log('user_message', content);
92
103
  thread.addMessage('user', content);
93
104
 
@@ -205,19 +216,6 @@ export default class Agent {
205
216
  async generateCompletion(thread, options = {}, retry_counter = 1) {
206
217
  try {
207
218
  const model = Symposium.getModelByName(thread.state.model);
208
-
209
- for (let message of thread.messages) {
210
- for (let c of message.content) {
211
- if (c.type === 'audio' && !model.supports_audio) {
212
- const words = await this.getPromptWordsForTranscription(thread);
213
- const prompt = words.length ? 'Possibili parole usate: ' + words.join(', ') : null;
214
- const transcribed = await Symposium.transcribe(c.content, prompt);
215
- c.type = 'text';
216
- c.content = '[voice message] ' + transcribed;
217
- }
218
- }
219
- }
220
-
221
219
  const messages = await model.generate(thread, await this.getFunctions(), options);
222
220
  return model.supports_functions ? messages : messages.map(m => this.parseFunctions(m));
223
221
  } catch (error) {
@@ -261,6 +259,15 @@ export default class Agent {
261
259
  return i.output(thread, msg);
262
260
  }
263
261
 
262
+ async partial(thread, msg) {
263
+ if ((typeof msg) === 'text')
264
+ msg = {summary: msg};
265
+
266
+ const i = this.options.interfaces.find(i => i.name === thread.interface);
267
+ if (i)
268
+ return i.partial(thread, msg);
269
+ }
270
+
264
271
  parseFunctions(message) {
265
272
  const newContent = [];
266
273
  for (let m of message.content) {
@@ -373,11 +380,18 @@ export default class Agent {
373
380
  if (!functions.has(function_call.name))
374
381
  throw new Error('Unrecognized function ' + function_call.name);
375
382
 
383
+ const func = functions.get(function_call.name);
384
+ const partialOutput = func.partialOutput ? ((typeof func.partialOutput) === 'text' ? func.partialOutput : func.partialOutput.call(this, function_call.arguments)) : 'Uso lo strumento ' + function_call.name + '...';
385
+ this.partial(thread, partialOutput);
386
+
376
387
  await this.log('function_call', function_call);
377
388
 
378
389
  try {
379
- return await functions.get(function_call.name).tool.callFunction(thread, function_call.name, function_call.arguments);
390
+ const response = await func.tool.callFunction(thread, function_call.name, function_call.arguments);
391
+ this.partial(thread, 'Risposta ricevuta da ' + func.tool.name);
392
+ return response;
380
393
  } catch (error) {
394
+ this.partial(thread, 'Ricevuto errore da ' + func.tool.name);
381
395
  return {error};
382
396
  }
383
397
  }
package/Interface.js CHANGED
@@ -7,6 +7,9 @@ export default class Interface {
7
7
  static async output(thread, msg) {
8
8
  }
9
9
 
10
+ static async partial(thread, msg) {
11
+ }
12
+
10
13
  static async error(thread, error) {
11
14
  }
12
15
  }
@@ -148,6 +148,17 @@ export default class AnthropicModel extends Model {
148
148
  }
149
149
  break;
150
150
 
151
+ case 'audio':
152
+ if (c.content.transcription) {
153
+ content.push({
154
+ type: 'text',
155
+ text: '[transcribed] ' + c.content.transcription,
156
+ });
157
+ } else {
158
+ throw new Error('Audio content is not supported by this model');
159
+ }
160
+ break;
161
+
151
162
  default:
152
163
  throw new Error('Message type "' + c.type + '" unsupported by this model');
153
164
  }
@@ -158,6 +158,19 @@ export default class GroqModel extends Model {
158
158
  }
159
159
  break;
160
160
 
161
+
162
+ case 'audio':
163
+ if (c.content.transcription) {
164
+ messages.push({
165
+ role: message.role,
166
+ content: '[transcribed] ' + c.content.transcription,
167
+ name: message.name,
168
+ });
169
+ } else {
170
+ throw new Error('Audio content is not supported by this model');
171
+ }
172
+ break;
173
+
161
174
  default:
162
175
  throw new Error('Message type unsupported by this model');
163
176
  }
@@ -140,24 +140,34 @@ export default class OpenAIModel extends Model {
140
140
  break;
141
141
 
142
142
  case 'audio':
143
- if (c.content.type !== 'base64')
144
- throw new Error('Audio content must be base64 encoded for this model');
145
- if (!['audio/mpeg', 'audio/wav'].includes(c.content.mime))
146
- throw new Error('Audio content must have a valid MIME type');
143
+ if (this.supports_audio) {
144
+ if (c.content.type !== 'base64')
145
+ throw new Error('Audio content must be base64 encoded for this model');
146
+ if (!['audio/mpeg', 'audio/wav'].includes(c.content.mime))
147
+ throw new Error('Audio content must have a valid MIME type');
147
148
 
148
- messages.push({
149
- role,
150
- content: [
151
- {
152
- type: 'input_audio',
153
- input_audio: {
154
- data: c.content.data,
155
- format: c.content.mime === 'audio/mpeg' ? 'mp3' : 'wav',
149
+ messages.push({
150
+ role,
151
+ content: [
152
+ {
153
+ type: 'input_audio',
154
+ input_audio: {
155
+ data: c.content.data,
156
+ format: c.content.mime === 'audio/mpeg' ? 'mp3' : 'wav',
157
+ },
156
158
  },
157
- },
158
- ],
159
- name: message.name,
160
- });
159
+ ],
160
+ name: message.name,
161
+ });
162
+ } else if (c.content.transcription) {
163
+ messages.push({
164
+ role,
165
+ content: '[transcribed] ' + c.content.transcription,
166
+ name: message.name,
167
+ });
168
+ } else{
169
+ throw new Error('Audio content is not supported by this model');
170
+ }
161
171
  break;
162
172
 
163
173
  case 'function':
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "symposium",
4
- "version": "0.13.9",
4
+ "version": "0.14.1",
5
5
  "description": "Agents",
6
6
  "main": "index.js",
7
7
  "author": "Domenico Giambra",
8
8
  "license": "ISC",
9
9
  "dependencies": {
10
- "@anthropic-ai/sdk": "^0.53.0",
11
- "groq-sdk": "^0.23.0",
10
+ "@anthropic-ai/sdk": "^0.54.0",
11
+ "groq-sdk": "^0.25.0",
12
12
  "openai": "^5.0.0",
13
13
  "tiktoken": "^1.0.10"
14
14
  }