symposium 0.15.4 → 0.15.6
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 +87 -81
- package/README.md +2 -8
- package/package.json +1 -1
package/Agent.js
CHANGED
|
@@ -123,84 +123,91 @@ 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
|
-
return emitter;
|
|
168
|
-
|
|
169
|
-
case 'utility':
|
|
170
|
-
throw e;
|
|
171
|
-
|
|
172
|
-
default:
|
|
173
|
-
throw new Error('Bad agent type');
|
|
174
|
-
}
|
|
175
|
-
}
|
|
179
|
+
try {
|
|
180
|
+
thread = await this.afterExecute(thread, completion, emitter);
|
|
181
|
+
const response = await this.handleCompletion(thread, completion, emitter);
|
|
176
182
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
switch (this.type) {
|
|
182
|
-
case 'utility':
|
|
183
|
-
return response;
|
|
184
|
-
|
|
185
|
-
case 'chat':
|
|
186
|
-
if (!existing_emitter) {
|
|
187
|
-
emitter.on('data', data => {
|
|
188
|
-
if (data.type === 'response' && data.content.type === 'continue')
|
|
189
|
-
this.execute(thread, 0, emitter);
|
|
190
|
-
}, false);
|
|
191
|
-
}
|
|
183
|
+
switch (this.type) {
|
|
184
|
+
case 'utility':
|
|
185
|
+
if (response.type !== 'response')
|
|
186
|
+
throw new Error('Utility agent did not return a response');
|
|
192
187
|
|
|
193
|
-
|
|
188
|
+
return resolve(response.value);
|
|
194
189
|
|
|
195
|
-
|
|
196
|
-
|
|
190
|
+
case 'chat':
|
|
191
|
+
if (response?.type === 'continue')
|
|
192
|
+
return this.execute(thread, 0, emitter);
|
|
193
|
+
|
|
194
|
+
return resolve(null);
|
|
195
|
+
|
|
196
|
+
default:
|
|
197
|
+
throw new Error('Bad agent type');
|
|
198
|
+
}
|
|
199
|
+
} catch (e) {
|
|
200
|
+
console.error(e);
|
|
201
|
+
|
|
202
|
+
if (counter < this.max_retries)
|
|
203
|
+
await this.execute(thread, counter + 1, emitter);
|
|
204
|
+
}
|
|
205
|
+
} catch (e) {
|
|
206
|
+
reject(e);
|
|
197
207
|
}
|
|
198
|
-
}
|
|
199
|
-
console.error(e);
|
|
208
|
+
});
|
|
200
209
|
|
|
201
|
-
|
|
202
|
-
await this.execute(thread, counter + 1, emitter);
|
|
203
|
-
}
|
|
210
|
+
return this.type === 'chat' ? emitter : execution;
|
|
204
211
|
}
|
|
205
212
|
|
|
206
213
|
convertFunctionToResponseFormat(obj) {
|
|
@@ -242,7 +249,7 @@ export default class Agent {
|
|
|
242
249
|
};
|
|
243
250
|
}
|
|
244
251
|
|
|
245
|
-
async afterExecute(thread, completion) {
|
|
252
|
+
async afterExecute(thread, completion, emitter) {
|
|
246
253
|
return thread;
|
|
247
254
|
}
|
|
248
255
|
|
|
@@ -311,9 +318,9 @@ export default class Agent {
|
|
|
311
318
|
case 'text':
|
|
312
319
|
if (this.type === 'utility') {
|
|
313
320
|
if (this.utility.type === 'text')
|
|
314
|
-
return this.afterHandle(thread, completion,
|
|
321
|
+
return {type: 'response', value: this.afterHandle(thread, completion, m.content)};
|
|
315
322
|
if (this.utility.type === 'json' && model.supports_structured_output)
|
|
316
|
-
return this.afterHandle(thread, completion,
|
|
323
|
+
return {type: 'response', value: this.afterHandle(thread, completion, JSON.parse(m.content))};
|
|
317
324
|
}
|
|
318
325
|
|
|
319
326
|
emitter.emit('output', m.content);
|
|
@@ -330,7 +337,7 @@ export default class Agent {
|
|
|
330
337
|
if (functions.length) {
|
|
331
338
|
for (let f of functions) {
|
|
332
339
|
if (this.utility && ['function', 'json'].includes(this.utility.type))
|
|
333
|
-
return this.afterHandle(thread, completion,
|
|
340
|
+
return {type: 'response', value: this.afterHandle(thread, completion, f.arguments)};
|
|
334
341
|
|
|
335
342
|
const function_response = await this.callFunction(thread, f, emitter);
|
|
336
343
|
|
|
@@ -344,18 +351,17 @@ export default class Agent {
|
|
|
344
351
|
await this.log('function_response', function_response);
|
|
345
352
|
}
|
|
346
353
|
|
|
347
|
-
|
|
354
|
+
await this.afterHandle(thread, completion);
|
|
355
|
+
return {type: 'continue'};
|
|
348
356
|
} else {
|
|
349
357
|
await thread.storeState();
|
|
350
|
-
|
|
358
|
+
await this.afterHandle(thread, completion);
|
|
359
|
+
return {type: 'void'};
|
|
351
360
|
}
|
|
352
361
|
}
|
|
353
362
|
|
|
354
|
-
async afterHandle(thread, completion,
|
|
355
|
-
return
|
|
356
|
-
type,
|
|
357
|
-
value,
|
|
358
|
-
};
|
|
363
|
+
async afterHandle(thread, completion, value = null) {
|
|
364
|
+
return value;
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
async getFunctions(parsed = true) {
|
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
|
|