@aigne/core 0.4.205-0 → 0.4.205-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.
Files changed (54) hide show
  1. package/lib/cjs/agent.js +60 -0
  2. package/lib/cjs/definitions/data-type-schema.js +46 -0
  3. package/lib/cjs/definitions/memory.js +21 -0
  4. package/lib/cjs/function-agent.js +1 -1
  5. package/lib/cjs/function-runner.js +2 -2
  6. package/lib/cjs/index.js +1 -1
  7. package/lib/cjs/llm-agent.js +19 -126
  8. package/lib/cjs/llm-decision-agent.js +40 -33
  9. package/lib/cjs/llm-model.js +2 -2
  10. package/lib/cjs/local-function-agent.js +11 -9
  11. package/lib/cjs/pipeline-agent.js +2 -4
  12. package/lib/cjs/runnable.js +3 -1
  13. package/lib/cjs/tsconfig.tsbuildinfo +1 -1
  14. package/lib/cjs/utils/message-utils.js +62 -0
  15. package/lib/cjs/utils/nullable.js +2 -0
  16. package/lib/cjs/utils/ordered-map.js +12 -0
  17. package/lib/cjs/utils/stream-utils.js +43 -5
  18. package/lib/esm/agent.js +53 -0
  19. package/lib/esm/definitions/data-type-schema.js +43 -0
  20. package/lib/esm/definitions/memory.js +18 -0
  21. package/lib/esm/function-agent.js +1 -1
  22. package/lib/esm/function-runner.js +2 -2
  23. package/lib/esm/index.js +1 -1
  24. package/lib/esm/llm-agent.js +21 -125
  25. package/lib/esm/llm-decision-agent.js +41 -34
  26. package/lib/esm/llm-model.js +2 -2
  27. package/lib/esm/local-function-agent.js +11 -9
  28. package/lib/esm/pipeline-agent.js +2 -4
  29. package/lib/esm/runnable.js +3 -1
  30. package/lib/esm/tsconfig.tsbuildinfo +1 -1
  31. package/lib/esm/utils/message-utils.js +57 -0
  32. package/lib/esm/utils/nullable.js +1 -0
  33. package/lib/esm/utils/ordered-map.js +12 -0
  34. package/lib/esm/utils/stream-utils.js +42 -5
  35. package/lib/types/agent.d.ts +42 -0
  36. package/lib/types/definitions/data-type-schema.d.ts +40 -0
  37. package/lib/types/definitions/memory.d.ts +40 -0
  38. package/lib/types/function-agent.d.ts +1 -1
  39. package/lib/types/function-runner.d.ts +2 -1
  40. package/lib/types/index.d.ts +1 -1
  41. package/lib/types/llm-agent.d.ts +34 -63
  42. package/lib/types/llm-decision-agent.d.ts +54 -30
  43. package/lib/types/llm-model.d.ts +2 -1
  44. package/lib/types/local-function-agent.d.ts +50 -19
  45. package/lib/types/memorable.d.ts +2 -1
  46. package/lib/types/pipeline-agent.d.ts +2 -3
  47. package/lib/types/runnable.d.ts +8 -2
  48. package/lib/types/tsconfig.tsbuildinfo +1 -1
  49. package/lib/types/utils/message-utils.d.ts +18 -0
  50. package/lib/types/utils/nullable.d.ts +7 -0
  51. package/lib/types/utils/ordered-map.d.ts +3 -0
  52. package/lib/types/utils/stream-utils.d.ts +12 -1
  53. package/lib/types/utils/union.d.ts +1 -1
  54. package/package.json +1 -1
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Agent = void 0;
7
+ const logger_1 = __importDefault(require("./logger"));
8
+ const runnable_1 = require("./runnable");
9
+ const utils_1 = require("./utils");
10
+ class Agent extends runnable_1.Runnable {
11
+ async getMemoryQuery(input, query) {
12
+ if (query?.from === 'variable') {
13
+ const i = utils_1.OrderedRecord.find(this.definition.inputs, (i) => i.id === query.fromVariableId);
14
+ if (!i)
15
+ throw new Error(`Input variable ${query.fromVariableId} not found`);
16
+ const value = input[i.name];
17
+ return (0, utils_1.renderMessage)('{{value}}', { value });
18
+ }
19
+ return Object.entries(input)
20
+ .map(([key, value]) => `${key} ${value}`)
21
+ .join('\n');
22
+ }
23
+ /**
24
+ * Load memories that are defined in the agent definition.
25
+ * @param input The agent input.
26
+ * @param context The AIGNE context.
27
+ * @returns A dictionary of memories, where the key is the memory name and the value is an array of memory items.
28
+ */
29
+ async loadMemories(input, context) {
30
+ const { memories } = this.definition;
31
+ const { userId, sessionId } = context?.state ?? {};
32
+ return Object.fromEntries((await Promise.all(utils_1.OrderedRecord.map(memories, async ({ name, memory, query, options }) => {
33
+ if (!name || !memory)
34
+ return null;
35
+ const q = await this.getMemoryQuery(input, query);
36
+ const { results: memories } = await memory.search(q, { ...options, userId, sessionId });
37
+ return [name, memories];
38
+ }))).filter(utils_1.isNonNullable));
39
+ }
40
+ /**
41
+ * Update memories by user messages and assistant responses.
42
+ * @param messages Messages to be added to memories.
43
+ */
44
+ async updateMemories(messages) {
45
+ const { memories } = this.definition;
46
+ const { userId, sessionId } = this.context?.state ?? {};
47
+ await Promise.all(utils_1.OrderedRecord.map(memories, async ({ memory }) => {
48
+ if (!memory) {
49
+ logger_1.default.warn(`Memory is not defined in agent ${this.name || this.id}`);
50
+ return;
51
+ }
52
+ return await memory.add(messages, { userId, sessionId });
53
+ }));
54
+ }
55
+ async run(input, options) {
56
+ const memories = await this.loadMemories(input, this.context);
57
+ return this.process(input, { ...options, memories });
58
+ }
59
+ }
60
+ exports.Agent = Agent;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.schemaToDataType = schemaToDataType;
4
+ const nanoid_1 = require("nanoid");
5
+ const utils_1 = require("../utils");
6
+ function schemaToDataType(dataType) {
7
+ return utils_1.OrderedRecord.fromArray(Object.entries(dataType).map(([name, schema]) => {
8
+ const base = {
9
+ ...schema,
10
+ id: (0, nanoid_1.nanoid)(),
11
+ name,
12
+ };
13
+ switch (schema.type) {
14
+ case 'string':
15
+ return {
16
+ ...base,
17
+ type: 'string',
18
+ };
19
+ case 'number':
20
+ return {
21
+ ...base,
22
+ type: 'number',
23
+ };
24
+ case 'boolean':
25
+ return {
26
+ ...base,
27
+ type: 'boolean',
28
+ };
29
+ case 'object':
30
+ return {
31
+ ...base,
32
+ type: 'object',
33
+ properties: schemaToDataType(schema.properties),
34
+ };
35
+ case 'array':
36
+ return {
37
+ ...base,
38
+ type: 'array',
39
+ items: utils_1.OrderedRecord.find(schemaToDataType({ items: schema.items }), (i) => i.name === 'items'),
40
+ };
41
+ default: {
42
+ throw new Error(`Unknown data type: ${schema.type}`);
43
+ }
44
+ }
45
+ }));
46
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toRunnableMemories = toRunnableMemories;
4
+ const nanoid_1 = require("nanoid");
5
+ const utils_1 = require("../utils");
6
+ function toRunnableMemories(agentName, inputs, memories) {
7
+ return utils_1.OrderedRecord.fromArray(Object.entries(memories).map(([name, { memory, query, options }]) => {
8
+ const queryFromVariable = query?.fromVariable
9
+ ? utils_1.OrderedRecord.find(inputs, (j) => j.name === query.fromVariable)
10
+ : null;
11
+ if (query?.fromVariable && !queryFromVariable)
12
+ throw new Error(`LLMAgent ${agentName} -> Memory ${name} -> Query variable ${query.fromVariable.toString()} not found`);
13
+ return {
14
+ id: name || (0, nanoid_1.nanoid)(),
15
+ name: name,
16
+ memory: memory,
17
+ query: queryFromVariable ? { from: 'variable', fromVariableId: queryFromVariable.id } : undefined,
18
+ options,
19
+ };
20
+ }));
21
+ }
@@ -18,7 +18,7 @@ exports.createFunctionAgentDefinition = createFunctionAgentDefinition;
18
18
  const nanoid_1 = require("nanoid");
19
19
  const tsyringe_1 = require("tsyringe");
20
20
  const constants_1 = require("./constants");
21
- const data_type_schema_1 = require("./data-type-schema");
21
+ const data_type_schema_1 = require("./definitions/data-type-schema");
22
22
  const function_runner_1 = require("./function-runner");
23
23
  const runnable_1 = require("./runnable");
24
24
  const utils_1 = require("./utils");
@@ -4,7 +4,7 @@ exports.FunctionRunner = void 0;
4
4
  const runnable_1 = require("./runnable");
5
5
  const utils_1 = require("./utils");
6
6
  class FunctionRunner extends runnable_1.Runnable {
7
- constructor() {
7
+ constructor(context) {
8
8
  super({
9
9
  id: 'function_runner',
10
10
  type: 'function_runner',
@@ -23,7 +23,7 @@ class FunctionRunner extends runnable_1.Runnable {
23
23
  type: 'object',
24
24
  },
25
25
  ]),
26
- });
26
+ }, context);
27
27
  }
28
28
  }
29
29
  exports.FunctionRunner = FunctionRunner;
package/lib/cjs/index.js CHANGED
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./utils"), exports);
18
18
  __exportStar(require("./constants"), exports);
19
19
  __exportStar(require("./data-type"), exports);
20
- __exportStar(require("./data-type-schema"), exports);
20
+ __exportStar(require("./definitions/data-type-schema"), exports);
21
21
  __exportStar(require("./context"), exports);
22
22
  __exportStar(require("./runnable"), exports);
23
23
  __exportStar(require("./pipeline-agent"), exports);
@@ -11,45 +11,39 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
- var __importDefault = (this && this.__importDefault) || function (mod) {
15
- return (mod && mod.__esModule) ? mod : { "default": mod };
16
- };
17
14
  var LLMAgent_1;
18
15
  Object.defineProperty(exports, "__esModule", { value: true });
19
16
  exports.LLMAgent = void 0;
20
17
  exports.createLLMAgentDefinition = createLLMAgentDefinition;
21
- const remove_1 = __importDefault(require("lodash/remove"));
22
18
  const nanoid_1 = require("nanoid");
23
19
  const tsyringe_1 = require("tsyringe");
20
+ const agent_1 = require("./agent");
24
21
  const constants_1 = require("./constants");
25
- const data_type_schema_1 = require("./data-type-schema");
22
+ const data_type_schema_1 = require("./definitions/data-type-schema");
23
+ const memory_1 = require("./definitions/memory");
26
24
  const llm_model_1 = require("./llm-model");
27
- const logger_1 = __importDefault(require("./logger"));
28
- const runnable_1 = require("./runnable");
29
25
  const utils_1 = require("./utils");
30
26
  const message_utils_1 = require("./utils/message-utils");
31
27
  const mustache_utils_1 = require("./utils/mustache-utils");
32
28
  const ordered_map_1 = require("./utils/ordered-map");
33
29
  const structured_output_schema_1 = require("./utils/structured-output-schema");
34
- let LLMAgent = LLMAgent_1 = class LLMAgent extends runnable_1.Runnable {
30
+ let LLMAgent = LLMAgent_1 = class LLMAgent extends agent_1.Agent {
35
31
  definition;
36
32
  model;
37
- context;
38
33
  static create(options) {
39
34
  const definition = createLLMAgentDefinition(options);
40
35
  return new LLMAgent_1(definition);
41
36
  }
42
- constructor(definition, model, context) {
43
- super(definition);
37
+ constructor(definition, context, model) {
38
+ super(definition, context);
44
39
  this.definition = definition;
45
40
  this.model = model;
46
- this.context = context;
47
41
  }
48
- async run(input, options) {
42
+ async process(input, options) {
49
43
  const { definition, model } = this;
50
44
  if (!model)
51
45
  throw new Error('LLM model is required');
52
- const { originalMessages, messagesWithMemory } = await this.prepareMessages(input);
46
+ const { originalMessages, messagesWithMemory } = (0, message_utils_1.prepareMessages)(definition, input, options.memories);
53
47
  const llmInputs = {
54
48
  messages: messagesWithMemory,
55
49
  modelOptions: definition.modelOptions,
@@ -95,35 +89,6 @@ let LLMAgent = LLMAgent_1 = class LLMAgent extends runnable_1.Runnable {
95
89
  await updateMemories($text, json);
96
90
  return { $text, ...json };
97
91
  }
98
- async prepareMessages(input) {
99
- const { definition } = this;
100
- const originalMessages = ordered_map_1.OrderedRecord.toArray(definition.messages).map(({ role, content }) => ({
101
- role,
102
- // TODO: support use memory variables in message content
103
- content: typeof content === 'string' ? (0, mustache_utils_1.renderMessage)(content, input) : content,
104
- }));
105
- if (!originalMessages.length)
106
- throw new Error('Messages are required');
107
- const { primaryMemory, memory } = await this.getMemories(input);
108
- let messagesWithMemory = [...originalMessages];
109
- // Add memory to a system message
110
- if (memory) {
111
- const message = {
112
- role: 'system',
113
- content: `\
114
- Here are the memories about the user:
115
- ${memory}
116
- `,
117
- };
118
- const lastSystemMessageIndex = messagesWithMemory.findLastIndex((i) => i.role === 'assistant');
119
- messagesWithMemory.splice(lastSystemMessageIndex + 1, 0, message);
120
- }
121
- // Add primary memory to messages
122
- if (primaryMemory.length)
123
- messagesWithMemory = (0, message_utils_1.mergeHistoryMessages)(messagesWithMemory, primaryMemory);
124
- // TODO: support comment/image for messages
125
- return { originalMessages, messagesWithMemory };
126
- }
127
92
  async runWithStructuredOutput(llmInputs) {
128
93
  const jsonOutputs = ordered_map_1.OrderedRecord.filter(this.definition.outputs, (i) => i.name !== constants_1.StreamTextOutputName // ignore `$text` output
129
94
  );
@@ -156,74 +121,14 @@ let LLMAgent = LLMAgent_1 = class LLMAgent extends runnable_1.Runnable {
156
121
  throw new Error('LLM model is required');
157
122
  return model.run(llmInputs, { stream: true });
158
123
  }
159
- async getMemoryQuery(input, query) {
160
- if (query?.from === 'variable') {
161
- const i = ordered_map_1.OrderedRecord.find(this.definition.inputs, (i) => i.id === query.fromVariableId);
162
- if (!i)
163
- throw new Error(`Input variable ${query.fromVariableId} not found`);
164
- const value = input[i.name];
165
- return (0, mustache_utils_1.renderMessage)('{{value}}', { value });
166
- }
167
- return Object.entries(input)
168
- .map(([key, value]) => `${key} ${value}`)
169
- .join('\n');
170
- }
171
- async getMemories(input) {
172
- const { memories } = this.definition;
173
- const { userId, sessionId } = this.context?.state ?? {};
174
- const list = (await Promise.all(ordered_map_1.OrderedRecord.map(memories, async ({ id, memory, query, options }) => {
175
- if (!memory) {
176
- logger_1.default.warn(`Memory is not defined in agent ${this.name || this.id}`);
177
- return null;
178
- }
179
- const q = await this.getMemoryQuery(input, query);
180
- const { results: memories } = await memory.search(q, { ...options, userId, sessionId });
181
- return { id, memories };
182
- }))).filter(utils_1.isNonNullable);
183
- const primary = (0, remove_1.default)(list, (i) => i.id === this.definition.primaryMemoryId)[0]?.memories || [];
184
- const primaryMemory = primary
185
- .map((i) => {
186
- const content = (0, mustache_utils_1.renderMessage)('{{memory}}', { memory: i.memory }).trim();
187
- const role = ['user', 'assistant'].includes(i.metadata.role) ? i.metadata.role : undefined;
188
- if (!role || !content)
189
- return null;
190
- return { role, content };
191
- })
192
- .filter(utils_1.isNonNullable);
193
- const memory = list
194
- .map((i) => i.memories
195
- .map((j) => (0, mustache_utils_1.renderMessage)('{{memory}}\n{{metadata}}', j).trim() || null)
196
- .filter(utils_1.isNonNullable)
197
- .join('\n'))
198
- .join('\n');
199
- return {
200
- primaryMemory,
201
- memory,
202
- };
203
- }
204
- /**
205
- * Update memories by user messages and assistant responses.
206
- * @param messages Messages to be added to memories.
207
- */
208
- async updateMemories(messages) {
209
- const { memories } = this.definition;
210
- const { userId, sessionId } = this.context?.state ?? {};
211
- await Promise.all(ordered_map_1.OrderedRecord.map(memories, async ({ memory }) => {
212
- if (!memory) {
213
- logger_1.default.warn(`Memory is not defined in agent ${this.name || this.id}`);
214
- return;
215
- }
216
- return await memory.add(messages, { userId, sessionId });
217
- }));
218
- }
219
124
  };
220
125
  exports.LLMAgent = LLMAgent;
221
126
  exports.LLMAgent = LLMAgent = LLMAgent_1 = __decorate([
222
127
  (0, tsyringe_1.injectable)(),
223
128
  __param(0, (0, tsyringe_1.inject)(constants_1.TYPES.definition)),
224
- __param(1, (0, tsyringe_1.inject)(constants_1.TYPES.llmModel)),
225
- __param(2, (0, tsyringe_1.inject)(constants_1.TYPES.context)),
226
- __metadata("design:paramtypes", [Object, llm_model_1.LLMModel, Object])
129
+ __param(1, (0, tsyringe_1.inject)(constants_1.TYPES.context)),
130
+ __param(2, (0, tsyringe_1.inject)(constants_1.TYPES.llmModel)),
131
+ __metadata("design:paramtypes", [Object, Object, llm_model_1.LLMModel])
227
132
  ], LLMAgent);
228
133
  /**
229
134
  * Create LLMAgent definition.
@@ -232,27 +137,15 @@ exports.LLMAgent = LLMAgent = LLMAgent_1 = __decorate([
232
137
  */
233
138
  function createLLMAgentDefinition(options) {
234
139
  const agentId = options.name || (0, nanoid_1.nanoid)();
235
- const primaryMemories = options.memories?.filter((i) => i.primary);
236
- if (primaryMemories && primaryMemories.length > 1) {
237
- throw new Error('Only one primary memory is allowed');
238
- }
239
140
  const inputs = (0, data_type_schema_1.schemaToDataType)(options.inputs);
240
141
  const outputs = (0, data_type_schema_1.schemaToDataType)(options.outputs);
241
- const memories = ordered_map_1.OrderedRecord.fromArray(options.memories?.map((i) => {
242
- const { name, memory, query, options } = i;
243
- const queryFromVariable = query?.fromVariable
244
- ? ordered_map_1.OrderedRecord.find(inputs, (j) => j.name === query.fromVariable)
245
- : null;
246
- if (query?.fromVariable && !queryFromVariable)
247
- throw new Error(`LLMAgent ${agentId} -> Memory ${name} -> Query variable ${query.fromVariable.toString()} not found`);
248
- return {
249
- id: name || (0, nanoid_1.nanoid)(),
250
- name: name,
251
- memory: memory,
252
- query: queryFromVariable ? { from: 'variable', fromVariableId: queryFromVariable.id } : undefined,
253
- options,
254
- };
255
- }));
142
+ const memories = (0, memory_1.toRunnableMemories)(agentId, inputs, options.memories ?? {});
143
+ const primaryMemoryNames = Object.entries(options.memories ?? {})
144
+ .filter(([, i]) => i.primary)
145
+ .map(([name]) => name);
146
+ if (primaryMemoryNames && primaryMemoryNames.length > 1) {
147
+ throw new Error('Only one primary memory is allowed');
148
+ }
256
149
  const messages = ordered_map_1.OrderedRecord.fromArray(options.messages?.map((i) => ({
257
150
  id: (0, nanoid_1.nanoid)(),
258
151
  role: i.role,
@@ -264,7 +157,7 @@ function createLLMAgentDefinition(options) {
264
157
  type: 'llm_agent',
265
158
  inputs,
266
159
  outputs,
267
- primaryMemoryId: primaryMemories?.at(0)?.name,
160
+ primaryMemoryId: primaryMemoryNames?.at(0),
268
161
  memories,
269
162
  modelOptions: options.modelOptions,
270
163
  messages,
@@ -17,33 +17,31 @@ exports.LLMDecisionAgent = void 0;
17
17
  exports.createLLMDecisionAgentDefinition = createLLMDecisionAgentDefinition;
18
18
  const nanoid_1 = require("nanoid");
19
19
  const tsyringe_1 = require("tsyringe");
20
+ const agent_1 = require("./agent");
20
21
  const constants_1 = require("./constants");
22
+ const memory_1 = require("./definitions/memory");
21
23
  const llm_model_1 = require("./llm-model");
22
- const runnable_1 = require("./runnable");
23
24
  const utils_1 = require("./utils");
24
- let LLMDecisionAgent = LLMDecisionAgent_1 = class LLMDecisionAgent extends runnable_1.Runnable {
25
+ const message_utils_1 = require("./utils/message-utils");
26
+ let LLMDecisionAgent = LLMDecisionAgent_1 = class LLMDecisionAgent extends agent_1.Agent {
25
27
  definition;
26
28
  model;
27
- context;
28
29
  static create(options) {
29
30
  const definition = createLLMDecisionAgentDefinition(options);
30
31
  return new LLMDecisionAgent_1(definition);
31
32
  }
32
- constructor(definition, model, context) {
33
- super(definition);
33
+ constructor(definition, context, model) {
34
+ super(definition, context);
34
35
  this.definition = definition;
35
36
  this.model = model;
36
- this.context = context;
37
37
  }
38
- async run(input, options) {
38
+ async process(input, options) {
39
39
  const { definition, context, model } = this;
40
40
  if (!model)
41
41
  throw new Error('LLM model is required');
42
42
  if (!context)
43
43
  throw new Error('Context is required');
44
- const messages = utils_1.OrderedRecord.toArray(definition.messages);
45
- if (!messages.length)
46
- throw new Error('Messages are required');
44
+ const { originalMessages, messagesWithMemory } = (0, message_utils_1.prepareMessages)(definition, input, options.memories);
47
45
  const cases = await Promise.all(utils_1.OrderedRecord.map(definition.cases, async (t) => {
48
46
  if (!t.runnable?.id)
49
47
  throw new Error('Runnable is required');
@@ -52,13 +50,10 @@ let LLMDecisionAgent = LLMDecisionAgent_1 = class LLMDecisionAgent extends runna
52
50
  const name = t.name || runnable.name;
53
51
  if (!name)
54
52
  throw new Error('Case name is required');
55
- return { name, description: t.description, runnable, input: t.input };
53
+ return { name, description: t.description, runnable };
56
54
  }));
57
55
  const llmInputs = {
58
- messages: messages.map(({ role, content }) => ({
59
- role,
60
- content: typeof content === 'string' ? (0, utils_1.renderMessage)(content, input) : content,
61
- })),
56
+ messages: messagesWithMemory,
62
57
  modelOptions: definition.modelOptions,
63
58
  tools: cases.map((t) => {
64
59
  // TODO: auto generate parameters by llm model if needed
@@ -82,40 +77,52 @@ let LLMDecisionAgent = LLMDecisionAgent_1 = class LLMDecisionAgent extends runna
82
77
  if (!caseToCall)
83
78
  throw new Error('Case not found');
84
79
  // TODO: check result structure and omit undefined values
85
- return (await caseToCall.runnable.run(input, options));
80
+ const output = (await caseToCall.runnable.run(input, options));
81
+ return (0, utils_1.extractOutputsFromRunnableOutput)(output, ({ $text, ...json }) => this.updateMemories([
82
+ ...originalMessages,
83
+ { role: 'assistant', content: (0, utils_1.renderMessage)('{{$text}}\n{{json}}', { $text, json }).trim() },
84
+ ]));
86
85
  }
87
86
  };
88
87
  exports.LLMDecisionAgent = LLMDecisionAgent;
89
88
  exports.LLMDecisionAgent = LLMDecisionAgent = LLMDecisionAgent_1 = __decorate([
90
89
  (0, tsyringe_1.injectable)(),
91
90
  __param(0, (0, tsyringe_1.inject)(constants_1.TYPES.definition)),
92
- __param(1, (0, tsyringe_1.inject)(constants_1.TYPES.llmModel)),
93
- __param(2, (0, tsyringe_1.inject)(constants_1.TYPES.context)),
94
- __metadata("design:paramtypes", [Object, llm_model_1.LLMModel, Object])
91
+ __param(1, (0, tsyringe_1.inject)(constants_1.TYPES.context)),
92
+ __param(2, (0, tsyringe_1.inject)(constants_1.TYPES.llmModel)),
93
+ __metadata("design:paramtypes", [Object, Object, llm_model_1.LLMModel])
95
94
  ], LLMDecisionAgent);
96
95
  function createLLMDecisionAgentDefinition(options) {
97
- const messages = utils_1.OrderedRecord.fromArray([
98
- {
99
- id: (0, nanoid_1.nanoid)(),
100
- role: 'system',
101
- content: options.messages,
102
- },
103
- ]);
104
- const cases = utils_1.OrderedRecord.fromArray(options.cases.map((c) => ({
96
+ const agentId = options.name || (0, nanoid_1.nanoid)();
97
+ const cases = utils_1.OrderedRecord.fromArray(Object.entries(options.cases).map(([name, c]) => ({
105
98
  id: (0, nanoid_1.nanoid)(),
106
- name: c.name || c.runnable.name,
99
+ name: name || c.runnable.name,
107
100
  description: c.description,
108
101
  runnable: { id: c.runnable.id },
109
102
  })));
103
+ const inputs = utils_1.OrderedRecord.merge(...Object.values(options.cases).map((i) => i.runnable.definition.inputs));
104
+ const outputs = utils_1.OrderedRecord.fromArray(utils_1.OrderedRecord.map(utils_1.OrderedRecord.merge(...Object.values(options.cases).map((i) => i.runnable.definition.outputs)), (o) => ({ ...o, required: false })));
105
+ const memories = (0, memory_1.toRunnableMemories)(agentId, inputs, options.memories ?? {});
106
+ const primaryMemoryNames = Object.entries(options.memories ?? {})
107
+ .filter(([, i]) => i.primary)
108
+ .map(([name]) => name);
109
+ if (primaryMemoryNames && primaryMemoryNames.length > 1) {
110
+ throw new Error('Only one primary memory is allowed');
111
+ }
112
+ const messages = utils_1.OrderedRecord.fromArray(options.messages?.map((i) => ({
113
+ id: (0, nanoid_1.nanoid)(),
114
+ role: i.role,
115
+ content: i.content,
116
+ })));
110
117
  return {
111
- id: options.id || options.name || (0, nanoid_1.nanoid)(),
118
+ id: agentId,
112
119
  name: options.name,
113
120
  type: 'llm_decision_agent',
114
- // TODO: decision agent inputs should be the intersection of all case inputs
115
- inputs: utils_1.OrderedRecord.fromArray([]),
116
- // TODO: decision agent outputs should be the union of all case outputs
117
- outputs: utils_1.OrderedRecord.fromArray([]),
121
+ inputs,
122
+ outputs,
118
123
  messages,
124
+ primaryMemoryId: primaryMemoryNames?.at(0),
125
+ memories,
119
126
  modelOptions: options.modelOptions,
120
127
  cases,
121
128
  };
@@ -4,7 +4,7 @@ exports.LLMModel = void 0;
4
4
  const runnable_1 = require("./runnable");
5
5
  const utils_1 = require("./utils");
6
6
  class LLMModel extends runnable_1.Runnable {
7
- constructor() {
7
+ constructor(context) {
8
8
  super({
9
9
  id: 'llm_model',
10
10
  type: 'llm_model',
@@ -21,7 +21,7 @@ class LLMModel extends runnable_1.Runnable {
21
21
  { id: '$text', name: '$text', type: 'string' },
22
22
  { id: 'toolCalls', name: 'toolCalls', type: 'object' },
23
23
  ]),
24
- });
24
+ }, context);
25
25
  }
26
26
  }
27
27
  exports.LLMModel = LLMModel;
@@ -17,29 +17,28 @@ exports.LocalFunctionAgent = void 0;
17
17
  exports.createLocalFunctionAgentDefinition = createLocalFunctionAgentDefinition;
18
18
  const nanoid_1 = require("nanoid");
19
19
  const tsyringe_1 = require("tsyringe");
20
+ const agent_1 = require("./agent");
20
21
  const constants_1 = require("./constants");
21
- const data_type_schema_1 = require("./data-type-schema");
22
- const runnable_1 = require("./runnable");
22
+ const data_type_schema_1 = require("./definitions/data-type-schema");
23
+ const memory_1 = require("./definitions/memory");
23
24
  const utils_1 = require("./utils");
24
- let LocalFunctionAgent = LocalFunctionAgent_1 = class LocalFunctionAgent extends runnable_1.Runnable {
25
+ let LocalFunctionAgent = LocalFunctionAgent_1 = class LocalFunctionAgent extends agent_1.Agent {
25
26
  definition;
26
- context;
27
27
  static create(options) {
28
28
  const definition = createLocalFunctionAgentDefinition(options);
29
29
  return new LocalFunctionAgent_1(definition);
30
30
  }
31
31
  constructor(definition, context) {
32
- super(definition);
32
+ super(definition, context);
33
33
  this.definition = definition;
34
- this.context = context;
35
34
  }
36
- async run(input, options) {
35
+ async process(input, options) {
37
36
  const { definition: { function: func }, context, } = this;
38
37
  if (!func)
39
38
  throw new Error('Function is required');
40
39
  if (!context)
41
40
  throw new Error('Context is required');
42
- const result = (await func(input, { context }));
41
+ const result = await func(input, { context, memories: options.memories });
43
42
  // TODO: validate the result against the definition.outputs
44
43
  return options?.stream
45
44
  ? result instanceof ReadableStream
@@ -58,14 +57,17 @@ exports.LocalFunctionAgent = LocalFunctionAgent = LocalFunctionAgent_1 = __decor
58
57
  __metadata("design:paramtypes", [Object, Object])
59
58
  ], LocalFunctionAgent);
60
59
  function createLocalFunctionAgentDefinition(options) {
60
+ const agentId = options.name || (0, nanoid_1.nanoid)();
61
61
  const inputs = (0, data_type_schema_1.schemaToDataType)(options.inputs);
62
62
  const outputs = (0, data_type_schema_1.schemaToDataType)(options.outputs);
63
+ const memories = (0, memory_1.toRunnableMemories)(agentId, inputs, options.memories || {});
63
64
  return {
64
- id: options.id || options.name || (0, nanoid_1.nanoid)(),
65
+ id: agentId,
65
66
  name: options.name,
66
67
  type: 'local_function_agent',
67
68
  inputs,
68
69
  outputs,
70
+ memories,
69
71
  function: options.function,
70
72
  };
71
73
  }
@@ -22,7 +22,7 @@ const lodash_1 = require("lodash");
22
22
  const nanoid_1 = require("nanoid");
23
23
  const tsyringe_1 = require("tsyringe");
24
24
  const constants_1 = require("./constants");
25
- const data_type_schema_1 = require("./data-type-schema");
25
+ const data_type_schema_1 = require("./definitions/data-type-schema");
26
26
  const logger_1 = __importDefault(require("./logger"));
27
27
  const runnable_1 = require("./runnable");
28
28
  const utils_1 = require("./utils");
@@ -30,15 +30,13 @@ const is_non_nullable_1 = require("./utils/is-non-nullable");
30
30
  const ordered_map_1 = require("./utils/ordered-map");
31
31
  let PipelineAgent = PipelineAgent_1 = class PipelineAgent extends runnable_1.Runnable {
32
32
  definition;
33
- context;
34
33
  static create(options) {
35
34
  const definition = createPipelineAgentDefinition(options);
36
35
  return new PipelineAgent_1(definition);
37
36
  }
38
37
  constructor(definition, context) {
39
- super(definition);
38
+ super(definition, context);
40
39
  this.definition = definition;
41
- this.context = context;
42
40
  }
43
41
  async run(input, options) {
44
42
  // TODO: validate the input against the definition
@@ -6,8 +6,10 @@ exports.isRunnableResponseError = isRunnableResponseError;
6
6
  const ordered_map_1 = require("./utils/ordered-map");
7
7
  class Runnable {
8
8
  definition;
9
- constructor(definition) {
9
+ context;
10
+ constructor(definition, context) {
10
11
  this.definition = definition;
12
+ this.context = context;
11
13
  this.inputs = Object.fromEntries(ordered_map_1.OrderedRecord.map(definition.inputs, (i) => [i.name || i.id, i]));
12
14
  this.outputs = Object.fromEntries(ordered_map_1.OrderedRecord.map(definition.outputs, (i) => [i.name || i.id, i]));
13
15
  }