symposium 0.3.3 → 0.3.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 CHANGED
@@ -105,13 +105,7 @@ export default class Agent {
105
105
  }
106
106
  }
107
107
 
108
- const completion_payload = {};
109
- if (this.options.talking_function) {
110
- completion_payload.functions = [this.options.talking_function];
111
- completion_payload.function_call = {name: this.options.talking_function.name};
112
- }
113
-
114
- const completion = await this.generateCompletion(thread, completion_payload);
108
+ const completion = await this.generateCompletion(thread);
115
109
 
116
110
  await this.handleCompletion(thread, completion);
117
111
 
@@ -127,27 +121,8 @@ export default class Agent {
127
121
 
128
122
  async generateCompletion(thread, payload = {}, retry_counter = 1) {
129
123
  try {
130
- const completion_payload = {
131
- model: thread.state.model,
132
- messages: thread.getMessagesJson(),
133
- functions: await this.getFunctions(),
134
- ...payload,
135
- };
136
-
137
- if (!completion_payload.functions?.length) {
138
- delete completion_payload.functions;
139
- if (completion_payload.hasOwnProperty('function_call'))
140
- delete completion_payload.function_call;
141
- }
142
-
143
- const openai = await Symposium.getOpenAi();
144
- const chatCompletion = await openai.chat.completions.create(completion_payload);
145
-
146
- let completion = chatCompletion.choices[0].message;
147
- if (completion.function_call && completion.function_call.arguments)
148
- completion.function_call.arguments = JSON.parse(completion.function_call.arguments);
149
-
150
- return completion;
124
+ const model = Symposium.getModelByName(thread.state.model);
125
+ return model.generate(thread, payload, await this.getFunctions())
151
126
  } catch (error) {
152
127
  if (error.response) {
153
128
  console.error(error.response.status);
@@ -173,18 +148,11 @@ export default class Agent {
173
148
  }
174
149
 
175
150
  async handleCompletion(thread, completion) {
176
- if (this.options.talking_function && completion.function_call) {
177
- const text = completion.function_call.arguments[Object.keys(this.options.talking_function.parameters.properties)[0]];
178
- thread.addAssistantMessage(text);
179
- await this.log('ai_message', text);
180
- await thread.reply(text);
181
- return thread.storeState()
182
- }
183
-
184
151
  thread.addAssistantMessage(completion.content, completion.function_call ? {
185
152
  ...completion.function_call,
186
153
  arguments: JSON.stringify(completion.function_call.arguments),
187
154
  } : null);
155
+
188
156
  if (completion.content) {
189
157
  await this.log('ai_message', completion.content);
190
158
  await thread.reply(completion.content);
@@ -238,6 +206,14 @@ export default class Agent {
238
206
  await this.execute(thread);
239
207
  }
240
208
 
209
+ async setModel(thread, label) {
210
+ const model_to_switch = Symposium.getModelByLabel(label);
211
+ if (model_to_switch && model_to_switch.type === 'llm')
212
+ await thread.setState({model: model_to_switch.name});
213
+ else
214
+ throw new Error("Versione modello non riconosciuta!\nModelli disponibili:\n" + Array.from(Symposium.models.values()).filter(m => m.type === 'llm').map(m => m.label).join("\n"));
215
+ }
216
+
241
217
  async log(type, payload) {
242
218
  if (this.options.logger)
243
219
  return this.options.logger.log(this.name, type, payload);
package/Model.js CHANGED
@@ -1,13 +1,18 @@
1
1
  export default class Model {
2
+ vendor;
3
+ type = 'llm';
2
4
  name;
3
5
  name_for_tiktoken;
4
6
  label;
5
7
  tokens;
8
+ supports_tools = false;
6
9
 
7
- constructor(name, label, tokens, name_for_tiktoken = null) {
8
- this.name = name;
9
- this.label = label;
10
- this.tokens = tokens;
11
- this.name_for_tiktoken = name_for_tiktoken || name;
10
+ constructor() {
11
+ if (!this.name_for_tiktoken)
12
+ this.name_for_tiktoken = this.name;
13
+ }
14
+
15
+ async generate(thread) {
16
+ return null;
12
17
  }
13
18
  }
package/Symposium.js CHANGED
@@ -1,47 +1,32 @@
1
1
  import Redis from "@travio/redis";
2
- import OpenAI from "openai";
3
- import Model from "./Model.js";
2
+ import Gpt35 from "./models/Gpt35.js";
3
+ import Gpt4 from "./models/Gpt4.js";
4
+ import Gpt4Turbo from "./models/Gpt4Turbo.js";
5
+ import Gpt4Vision from "./models/Gpt4Vision.js";
6
+ import Whisper from "./models/Whisper.js";
4
7
 
5
8
  export default class Symposium {
6
- static openai;
7
- static models = [];
9
+ static models = new Map();
8
10
 
9
11
  static async init() {
10
- this.loadModel(new Model('gpt-3.5-turbo-0125', 'gpt-3.5', 16384));
11
- this.loadModel(new Model('gpt-4', 'gpt-4', 8192));
12
- this.loadModel(new Model('gpt-4-turbo-preview', 'gpt-4-turbo', 128000, 'gpt-4'));
13
- this.loadModel(new Model('gpt-4-vision-preview', 'gpt-4-vision', 128000, 'gpt-4'));
12
+ this.loadModel(new Gpt35());
13
+ this.loadModel(new Gpt4());
14
+ this.loadModel(new Gpt4Turbo());
15
+ this.loadModel(new Gpt4Vision());
16
+ this.loadModel(new Whisper());
14
17
 
15
18
  return Redis.init();
16
19
  }
17
20
 
18
21
  static loadModel(model) {
19
- this.models.push(model);
20
- }
21
-
22
- static async getOpenAi() {
23
- if (!this.openai)
24
- this.openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY});
25
-
26
- return this.openai;
27
- }
28
-
29
- static getModelByLabel(label) {
30
- return this.models.find(model => model.label === label);
22
+ this.models.set(model.name, model);
31
23
  }
32
24
 
33
25
  static getModelByName(name) {
34
- return this.models.find(model => model.name === name);
26
+ return this.models.get(name);
35
27
  }
36
28
 
37
- static async transcribe(agent, file, thread) {
38
- const words = await agent.getPromptWordsForTranscription(thread);
39
-
40
- const response = await this.getOpenAi().then(openai => openai.audio.transcriptions.create({
41
- file,
42
- model: 'whisper-1',
43
- prompt: words.join(', '),
44
- }));
45
- return response.text;
29
+ static getModelByLabel(label) {
30
+ return Array.from(this.models.values()).find(model => model.label === label);
46
31
  }
47
32
  }
@@ -0,0 +1,8 @@
1
+ import OpenAIModel from "./OpenAIModel.js";
2
+
3
+ export default class Gpt35 extends OpenAIModel {
4
+ vendor = 'openai';
5
+ name = 'gpt-3.5-turbo';
6
+ label = 'gpt-3.5';
7
+ tokens = 16384;
8
+ }
package/models/Gpt4.js ADDED
@@ -0,0 +1,7 @@
1
+ import OpenAIModel from "./OpenAIModel.js";
2
+
3
+ export default class Gpt4 extends OpenAIModel {
4
+ name = 'gpt-4';
5
+ label = 'gpt-4';
6
+ tokens = 8192;
7
+ }
@@ -0,0 +1,8 @@
1
+ import OpenAIModel from "./OpenAIModel.js";
2
+
3
+ export default class Gpt4Turbo extends OpenAIModel {
4
+ name = 'gpt-4-turbo-preview';
5
+ label = 'gpt-4-turbo';
6
+ name_for_tiktoken = 'gpt-4';
7
+ tokens = 128000;
8
+ }
@@ -0,0 +1,9 @@
1
+ import OpenAIModel from "./OpenAIModel.js";
2
+
3
+ export default class Gpt4Vision extends OpenAIModel {
4
+ name = 'gpt-4-vision-preview';
5
+ label = 'gpt-4-vision';
6
+ name_for_tiktoken = 'gpt-4';
7
+ tokens = 128000;
8
+ supports_tools = false;
9
+ }
@@ -0,0 +1,38 @@
1
+ import Model from "../Model.js";
2
+ import OpenAI from "openai";
3
+
4
+ export default class OpenAIModel extends Model {
5
+ openai;
6
+ vendor = 'openai';
7
+ supports_tools = true;
8
+
9
+ getOpenAi() {
10
+ if (!this.openai)
11
+ this.openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY});
12
+
13
+ return this.openai;
14
+ }
15
+
16
+ async generate(thread, payload = {}, functions = []) {
17
+ const completion_payload = {
18
+ model: this.name,
19
+ messages: thread.getMessagesJson(),
20
+ functions,
21
+ ...payload,
22
+ };
23
+
24
+ if (!completion_payload.functions?.length) {
25
+ delete completion_payload.functions;
26
+ if (completion_payload.hasOwnProperty('function_call'))
27
+ delete completion_payload.function_call;
28
+ }
29
+
30
+ const chatCompletion = await this.getOpenAi().chat.completions.create(completion_payload);
31
+
32
+ const completion = chatCompletion.choices[0].message;
33
+ if (completion.function_call && completion.function_call.arguments)
34
+ completion.function_call.arguments = JSON.parse(completion.function_call.arguments);
35
+
36
+ return completion;
37
+ }
38
+ }
@@ -0,0 +1,16 @@
1
+ import OpenAIModel from "./OpenAIModel.js";
2
+
3
+ export default class Whisper extends OpenAIModel {
4
+ type = 'stt';
5
+
6
+ async transcribe(agent, thread, file) {
7
+ const words = await agent.getPromptWordsForTranscription(thread);
8
+
9
+ const response = await this.getOpenAi().then(openai => openai.audio.transcriptions.create({
10
+ file,
11
+ model: 'whisper-1',
12
+ prompt: words.join(', '),
13
+ }));
14
+ return response.text;
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "symposium",
4
- "version": "0.3.3",
4
+ "version": "0.3.5",
5
5
  "description": "Agents",
6
6
  "main": "index.js",
7
7
  "author": "Domenico Giambra",