symposium 0.15.3 → 0.15.5
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 +88 -90
- package/README.md +2 -8
- package/package.json +1 -1
package/Agent.js
CHANGED
|
@@ -123,88 +123,88 @@ export default class Agent {
|
|
|
123
123
|
async execute(thread, counter = 0, existing_emitter = null) {
|
|
124
124
|
const emitter = existing_emitter || new BufferedEventEmitter();
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
const execution = new Promise(async (resolve, reject) => {
|
|
127
|
+
try {
|
|
128
|
+
if (counter === 0)
|
|
129
|
+
thread = await this.beforeExecute(thread, emitter);
|
|
130
|
+
|
|
131
|
+
const model = Symposium.getModelByName(thread.state.model);
|
|
132
|
+
|
|
133
|
+
const completion_options = {};
|
|
134
|
+
if (this.type === 'utility') {
|
|
135
|
+
if (['function', 'json'].includes(this.utility.type)) {
|
|
136
|
+
if (!this.utility.function || !this.utility.function.name || !this.utility.function.parameters)
|
|
137
|
+
throw new Error('Bad function definition');
|
|
138
|
+
|
|
139
|
+
let response_format = null;
|
|
140
|
+
if (this.utility.type === 'json' && model.supports_structured_output)
|
|
141
|
+
response_format = this.convertFunctionToResponseFormat(this.utility.function.parameters);
|
|
142
|
+
|
|
143
|
+
if (response_format && response_format.count <= 100) { // OpenAI does not support structured output if there are more than 100 parameters
|
|
144
|
+
completion_options.response_format = {
|
|
145
|
+
type: 'json_schema',
|
|
146
|
+
json_schema: {
|
|
147
|
+
name: this.utility.function.name,
|
|
148
|
+
schema: response_format.obj,
|
|
149
|
+
strict: true,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
} else {
|
|
153
|
+
completion_options.functions = [
|
|
154
|
+
this.utility.function,
|
|
155
|
+
];
|
|
156
|
+
completion_options.force_function = this.utility.function.name;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
130
160
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
strict: true,
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
} else {
|
|
151
|
-
completion_options.functions = [
|
|
152
|
-
this.utility.function,
|
|
153
|
-
];
|
|
154
|
-
completion_options.force_function = this.utility.function.name;
|
|
161
|
+
let completion;
|
|
162
|
+
try {
|
|
163
|
+
completion = await this.generateCompletion(thread, completion_options);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.error(e.message);
|
|
166
|
+
switch (this.type) {
|
|
167
|
+
case 'chat':
|
|
168
|
+
emitter.emit('error', e.message);
|
|
169
|
+
return resolve(e);
|
|
170
|
+
|
|
171
|
+
case 'utility':
|
|
172
|
+
throw e;
|
|
173
|
+
|
|
174
|
+
default:
|
|
175
|
+
throw new Error('Bad agent type');
|
|
176
|
+
}
|
|
155
177
|
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
178
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
} catch (e) {
|
|
163
|
-
console.error(e.message);
|
|
164
|
-
switch (this.type) {
|
|
165
|
-
case 'chat':
|
|
166
|
-
emitter.emit('error', e.message);
|
|
167
|
-
if (!existing_emitter)
|
|
168
|
-
emitter.emit('end');
|
|
169
|
-
return emitter;
|
|
170
|
-
|
|
171
|
-
case 'utility':
|
|
172
|
-
throw e;
|
|
173
|
-
|
|
174
|
-
default:
|
|
175
|
-
throw new Error('Bad agent type');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
179
|
+
try {
|
|
180
|
+
thread = await this.afterExecute(thread, completion, emitter);
|
|
181
|
+
const response = await this.handleCompletion(thread, completion, emitter);
|
|
178
182
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
case 'chat':
|
|
190
|
-
if (!existing_emitter) {
|
|
191
|
-
emitter.on('data', data => {
|
|
192
|
-
if (data.type === 'response' && data.content.type === 'continue')
|
|
193
|
-
this.execute(thread, 0, emitter);
|
|
194
|
-
}, false);
|
|
195
|
-
}
|
|
183
|
+
switch (this.type) {
|
|
184
|
+
case 'utility':
|
|
185
|
+
return resolve(response);
|
|
186
|
+
|
|
187
|
+
case 'chat':
|
|
188
|
+
if (response.type === 'continue')
|
|
189
|
+
return this.execute(thread, 0, emitter);
|
|
190
|
+
|
|
191
|
+
return resolve(null);
|
|
196
192
|
|
|
197
|
-
|
|
193
|
+
default:
|
|
194
|
+
throw new Error('Bad agent type');
|
|
195
|
+
}
|
|
196
|
+
} catch (e) {
|
|
197
|
+
console.error(e);
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
if (counter < this.max_retries)
|
|
200
|
+
await this.execute(thread, counter + 1, emitter);
|
|
201
|
+
}
|
|
202
|
+
} catch (e) {
|
|
203
|
+
reject(e);
|
|
201
204
|
}
|
|
202
|
-
}
|
|
203
|
-
console.error(e);
|
|
205
|
+
});
|
|
204
206
|
|
|
205
|
-
|
|
206
|
-
await this.execute(thread, counter + 1, emitter);
|
|
207
|
-
}
|
|
207
|
+
return this.type === 'chat' ? emitter : execution;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
convertFunctionToResponseFormat(obj) {
|
|
@@ -246,7 +246,7 @@ export default class Agent {
|
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
async afterExecute(thread, completion) {
|
|
249
|
+
async afterExecute(thread, completion, emitter) {
|
|
250
250
|
return thread;
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -315,12 +315,12 @@ export default class Agent {
|
|
|
315
315
|
case 'text':
|
|
316
316
|
if (this.type === 'utility') {
|
|
317
317
|
if (this.utility.type === 'text')
|
|
318
|
-
return this.afterHandle(thread, completion,
|
|
318
|
+
return this.afterHandle(thread, completion, m.content);
|
|
319
319
|
if (this.utility.type === 'json' && model.supports_structured_output)
|
|
320
|
-
return this.afterHandle(thread, completion,
|
|
320
|
+
return this.afterHandle(thread, completion, JSON.parse(m.content));
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
emitter.emit('
|
|
323
|
+
emitter.emit('output', m.content);
|
|
324
324
|
break;
|
|
325
325
|
|
|
326
326
|
case 'function':
|
|
@@ -334,7 +334,7 @@ export default class Agent {
|
|
|
334
334
|
if (functions.length) {
|
|
335
335
|
for (let f of functions) {
|
|
336
336
|
if (this.utility && ['function', 'json'].includes(this.utility.type))
|
|
337
|
-
return this.afterHandle(thread, completion,
|
|
337
|
+
return this.afterHandle(thread, completion, f.arguments);
|
|
338
338
|
|
|
339
339
|
const function_response = await this.callFunction(thread, f, emitter);
|
|
340
340
|
|
|
@@ -348,18 +348,15 @@ export default class Agent {
|
|
|
348
348
|
await this.log('function_response', function_response);
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
return this.afterHandle(thread, completion
|
|
351
|
+
return this.afterHandle(thread, completion);
|
|
352
352
|
} else {
|
|
353
353
|
await thread.storeState();
|
|
354
|
-
return this.afterHandle(thread, completion
|
|
354
|
+
return this.afterHandle(thread, completion);
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
async afterHandle(thread, completion,
|
|
359
|
-
return
|
|
360
|
-
type,
|
|
361
|
-
value,
|
|
362
|
-
};
|
|
358
|
+
async afterHandle(thread, completion, value = null) {
|
|
359
|
+
return value;
|
|
363
360
|
}
|
|
364
361
|
|
|
365
362
|
async getFunctions(parsed = true) {
|
|
@@ -392,16 +389,16 @@ export default class Agent {
|
|
|
392
389
|
|
|
393
390
|
const func = functions.get(function_call.name);
|
|
394
391
|
const partialOutput = func.partialOutput ? ((typeof func.partialOutput) === 'text' ? func.partialOutput : func.partialOutput.call(this, function_call.arguments)) : 'Uso lo strumento ' + function_call.name + '...';
|
|
395
|
-
emitter.emit('
|
|
392
|
+
emitter.emit('partial', partialOutput);
|
|
396
393
|
|
|
397
394
|
await this.log('function_call', function_call);
|
|
398
395
|
|
|
399
396
|
try {
|
|
400
397
|
const response = await func.tool.callFunction(thread, function_call.name, function_call.arguments);
|
|
401
|
-
emitter.emit('
|
|
398
|
+
emitter.emit('partial', 'Risposta ricevuta da ' + func.tool.name);
|
|
402
399
|
return response;
|
|
403
400
|
} catch (error) {
|
|
404
|
-
emitter.emit('
|
|
401
|
+
emitter.emit('partial', 'Ricevuto errore da ' + func.tool.name);
|
|
405
402
|
return {error};
|
|
406
403
|
}
|
|
407
404
|
}
|
|
@@ -423,6 +420,7 @@ export default class Agent {
|
|
|
423
420
|
return [this.name];
|
|
424
421
|
}
|
|
425
422
|
|
|
423
|
+
// Currently specific for OpenAI Realtime API
|
|
426
424
|
async createRealtimeSession(thread_id = null, options = {}) {
|
|
427
425
|
options = {
|
|
428
426
|
include_thread: true,
|
|
@@ -430,7 +428,7 @@ export default class Agent {
|
|
|
430
428
|
...options,
|
|
431
429
|
};
|
|
432
430
|
|
|
433
|
-
//
|
|
431
|
+
// If a thread is passed, it is used, otherwise a temporary thread is created
|
|
434
432
|
const thread = await this.getThread(thread_id || uuid());
|
|
435
433
|
|
|
436
434
|
const system_message = [], conversation = [];
|
package/README.md
CHANGED
|
@@ -82,14 +82,8 @@ async function main() {
|
|
|
82
82
|
|
|
83
83
|
const emitter = await agent.message('Hello, who are you?');
|
|
84
84
|
|
|
85
|
-
emitter.on('
|
|
86
|
-
|
|
87
|
-
process.stdout.write(data.content);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
emitter.on('end', () => {
|
|
92
|
-
console.log('\nConversation ended.');
|
|
85
|
+
emitter.on('output', (content) => {
|
|
86
|
+
process.stdout.write(content);
|
|
93
87
|
});
|
|
94
88
|
}
|
|
95
89
|
|