@agentica/core 0.44.0-dev.20260313-2 → 0.44.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 (154) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +218 -218
  3. package/lib/context/internal/__IChatInitialApplication.d.ts +1 -2
  4. package/lib/errors/AgenticaJsonParseError.js +6 -6
  5. package/lib/index.mjs +47 -7
  6. package/lib/index.mjs.map +1 -1
  7. package/lib/orchestrate/call.js +16 -16
  8. package/lib/orchestrate/cancel.js +1 -1
  9. package/lib/orchestrate/cancel.js.map +1 -1
  10. package/lib/orchestrate/initialize.js +44 -2
  11. package/lib/orchestrate/initialize.js.map +1 -1
  12. package/lib/orchestrate/select.js +1 -1
  13. package/lib/orchestrate/select.js.map +1 -1
  14. package/lib/structures/IAgenticaController.d.ts +143 -143
  15. package/lib/utils/ChatGptCompletionMessageUtil.js +6 -6
  16. package/package.json +6 -6
  17. package/prompts/cancel.md +5 -5
  18. package/prompts/common.md +3 -3
  19. package/prompts/describe.md +7 -7
  20. package/prompts/execute.md +122 -122
  21. package/prompts/initialize.md +3 -3
  22. package/prompts/json_parse_error.md +35 -35
  23. package/prompts/select.md +7 -7
  24. package/prompts/validate.md +123 -123
  25. package/prompts/validate_repeated.md +31 -31
  26. package/src/Agentica.ts +367 -367
  27. package/src/MicroAgentica.ts +357 -357
  28. package/src/constants/AgenticaConstant.ts +4 -4
  29. package/src/constants/AgenticaDefaultPrompt.ts +44 -44
  30. package/src/constants/index.ts +2 -2
  31. package/src/context/AgenticaContext.ts +136 -136
  32. package/src/context/AgenticaContextRequestResult.ts +14 -14
  33. package/src/context/AgenticaOperation.ts +73 -73
  34. package/src/context/AgenticaOperationCollection.ts +49 -49
  35. package/src/context/AgenticaOperationSelection.ts +9 -9
  36. package/src/context/AgenticaTokenUsage.ts +186 -186
  37. package/src/context/MicroAgenticaContext.ts +99 -99
  38. package/src/context/index.ts +5 -5
  39. package/src/context/internal/AgenticaOperationComposer.ts +177 -177
  40. package/src/context/internal/AgenticaTokenUsageAggregator.ts +66 -66
  41. package/src/context/internal/__IChatCancelFunctionsApplication.ts +23 -23
  42. package/src/context/internal/__IChatFunctionReference.ts +21 -21
  43. package/src/context/internal/__IChatInitialApplication.ts +13 -15
  44. package/src/context/internal/__IChatSelectFunctionsApplication.ts +24 -24
  45. package/src/context/internal/isAgenticaContext.ts +11 -11
  46. package/src/errors/AgenticaJsonParseError.ts +52 -52
  47. package/src/errors/AgenticaValidationError.ts +49 -49
  48. package/src/errors/index.ts +2 -2
  49. package/src/events/AgenticaAssistantMessageEvent.ts +12 -12
  50. package/src/events/AgenticaCallEvent.ts +27 -27
  51. package/src/events/AgenticaCancelEvent.ts +9 -9
  52. package/src/events/AgenticaDescribeEvent.ts +14 -14
  53. package/src/events/AgenticaEvent.ts +59 -59
  54. package/src/events/AgenticaEvent.type.ts +19 -19
  55. package/src/events/AgenticaEventBase.ts +18 -18
  56. package/src/events/AgenticaEventSource.ts +6 -6
  57. package/src/events/AgenticaExecuteEvent.ts +45 -45
  58. package/src/events/AgenticaInitializeEvent.ts +7 -7
  59. package/src/events/AgenticaJsonParseErrorEvent.ts +16 -16
  60. package/src/events/AgenticaRequestEvent.ts +27 -27
  61. package/src/events/AgenticaResponseEvent.ts +32 -32
  62. package/src/events/AgenticaSelectEvent.ts +11 -11
  63. package/src/events/AgenticaUserMessageEvent.ts +12 -12
  64. package/src/events/AgenticaValidateEvent.ts +32 -32
  65. package/src/events/MicroAgenticaEvent.ts +45 -45
  66. package/src/events/index.ts +15 -15
  67. package/src/factory/events.ts +357 -357
  68. package/src/factory/histories.ts +348 -348
  69. package/src/factory/index.ts +3 -3
  70. package/src/factory/operations.ts +16 -16
  71. package/src/functional/assertHttpController.ts +106 -106
  72. package/src/functional/assertHttpLlmApplication.ts +52 -52
  73. package/src/functional/assertMcpController.ts +47 -47
  74. package/src/functional/createMcpLlmApplication.ts +72 -72
  75. package/src/functional/index.ts +7 -7
  76. package/src/functional/validateHttpController.ts +113 -113
  77. package/src/functional/validateHttpLlmApplication.ts +65 -65
  78. package/src/functional/validateMcpController.ts +53 -53
  79. package/src/histories/AgenticaAssistantMessageHistory.ts +10 -10
  80. package/src/histories/AgenticaCancelHistory.ts +8 -8
  81. package/src/histories/AgenticaDescribeHistory.ts +18 -18
  82. package/src/histories/AgenticaExecuteHistory.ts +64 -64
  83. package/src/histories/AgenticaHistory.ts +28 -28
  84. package/src/histories/AgenticaHistoryBase.ts +35 -35
  85. package/src/histories/AgenticaSelectHistory.ts +8 -8
  86. package/src/histories/AgenticaSystemMessageHistory.ts +10 -10
  87. package/src/histories/AgenticaUserMessageHistory.ts +11 -11
  88. package/src/histories/MicroAgenticaHistory.ts +19 -19
  89. package/src/histories/contents/AgenticaUserMessageAudioContent.ts +21 -21
  90. package/src/histories/contents/AgenticaUserMessageContent.ts +19 -19
  91. package/src/histories/contents/AgenticaUserMessageContentBase.ts +6 -6
  92. package/src/histories/contents/AgenticaUserMessageFileContent.ts +25 -25
  93. package/src/histories/contents/AgenticaUserMessageImageContent.ts +33 -33
  94. package/src/histories/contents/AgenticaUserMessageTextContent.ts +15 -15
  95. package/src/histories/contents/index.ts +5 -5
  96. package/src/histories/index.ts +10 -10
  97. package/src/index.ts +15 -15
  98. package/src/json/IAgenticaEventJson.ts +265 -265
  99. package/src/json/IAgenticaEventJson.type.ts +19 -19
  100. package/src/json/IAgenticaHistoryJson.ts +165 -165
  101. package/src/json/IAgenticaHistoryJson.type.ts +19 -19
  102. package/src/json/IAgenticaOperationJson.ts +36 -36
  103. package/src/json/IAgenticaOperationSelectionJson.ts +26 -26
  104. package/src/json/IAgenticaTokenUsageJson.ts +107 -107
  105. package/src/json/IMicroAgenticaEventJson.ts +22 -22
  106. package/src/json/IMicroAgenticaHistoryJson.ts +25 -25
  107. package/src/json/index.ts +7 -7
  108. package/src/orchestrate/call.ts +542 -542
  109. package/src/orchestrate/cancel.ts +265 -265
  110. package/src/orchestrate/describe.ts +66 -66
  111. package/src/orchestrate/execute.ts +61 -61
  112. package/src/orchestrate/index.ts +6 -6
  113. package/src/orchestrate/initialize.ts +102 -102
  114. package/src/orchestrate/internal/cancelFunctionFromContext.ts +33 -33
  115. package/src/orchestrate/internal/selectFunctionFromContext.ts +34 -34
  116. package/src/orchestrate/select.ts +320 -320
  117. package/src/structures/IAgenticaConfig.ts +83 -83
  118. package/src/structures/IAgenticaConfigBase.ts +87 -87
  119. package/src/structures/IAgenticaController.ts +143 -143
  120. package/src/structures/IAgenticaExecutor.ts +167 -167
  121. package/src/structures/IAgenticaProps.ts +78 -78
  122. package/src/structures/IAgenticaSystemPrompt.ts +236 -236
  123. package/src/structures/IAgenticaVendor.ts +54 -54
  124. package/src/structures/IMcpTool.ts +60 -60
  125. package/src/structures/IMicroAgenticaConfig.ts +56 -56
  126. package/src/structures/IMicroAgenticaExecutor.ts +67 -67
  127. package/src/structures/IMicroAgenticaProps.ts +77 -77
  128. package/src/structures/IMicroAgenticaSystemPrompt.ts +169 -169
  129. package/src/structures/index.ts +10 -10
  130. package/src/transformers/transformHistory.ts +172 -172
  131. package/src/utils/AssistantMessageEmptyError.ts +20 -20
  132. package/src/utils/AsyncQueue.spec.ts +355 -355
  133. package/src/utils/AsyncQueue.ts +95 -95
  134. package/src/utils/ByteArrayUtil.ts +5 -5
  135. package/src/utils/ChatGptCompletionMessageUtil.spec.ts +314 -314
  136. package/src/utils/ChatGptCompletionMessageUtil.ts +210 -210
  137. package/src/utils/ChatGptCompletionStreamingUtil.spec.ts +909 -909
  138. package/src/utils/ChatGptCompletionStreamingUtil.ts +91 -91
  139. package/src/utils/ChatGptTokenUsageAggregator.spec.ts +226 -226
  140. package/src/utils/ChatGptTokenUsageAggregator.ts +57 -57
  141. package/src/utils/MPSC.spec.ts +276 -276
  142. package/src/utils/MPSC.ts +42 -42
  143. package/src/utils/Singleton.spec.ts +138 -138
  144. package/src/utils/Singleton.ts +42 -42
  145. package/src/utils/StreamUtil.spec.ts +512 -512
  146. package/src/utils/StreamUtil.ts +87 -87
  147. package/src/utils/__map_take.spec.ts +140 -140
  148. package/src/utils/__map_take.ts +13 -13
  149. package/src/utils/__retry.spec.ts +198 -198
  150. package/src/utils/__retry.ts +18 -18
  151. package/src/utils/assertExecuteFailure.ts +16 -16
  152. package/src/utils/index.ts +4 -4
  153. package/src/utils/request.ts +140 -140
  154. package/src/utils/types.ts +50 -50
@@ -1,357 +1,357 @@
1
- import { Semaphore } from "tstl";
2
-
3
- import type { AgenticaOperation } from "./context/AgenticaOperation";
4
- import type { AgenticaOperationCollection } from "./context/AgenticaOperationCollection";
5
- import type { MicroAgenticaContext } from "./context/MicroAgenticaContext";
6
- import type { AgenticaUserMessageEvent } from "./events";
7
- import type { MicroAgenticaEvent } from "./events/MicroAgenticaEvent";
8
- import type { AgenticaUserMessageContent } from "./histories";
9
- import type { AgenticaExecuteHistory } from "./histories/AgenticaExecuteHistory";
10
- import type { MicroAgenticaHistory } from "./histories/MicroAgenticaHistory";
11
- import type { IAgenticaController } from "./structures/IAgenticaController";
12
- import type { IAgenticaVendor } from "./structures/IAgenticaVendor";
13
- import type { IMicroAgenticaConfig } from "./structures/IMicroAgenticaConfig";
14
- import type { IMicroAgenticaProps } from "./structures/IMicroAgenticaProps";
15
-
16
- import { AgenticaTokenUsage } from "./context/AgenticaTokenUsage";
17
- import { AgenticaOperationComposer } from "./context/internal/AgenticaOperationComposer";
18
- import { createUserMessageEvent } from "./factory/events";
19
- import { call, describe } from "./orchestrate";
20
- import { transformHistory } from "./transformers/transformHistory";
21
- import { __map_take } from "./utils/__map_take";
22
- import { assertExecuteFailure } from "./utils/assertExecuteFailure";
23
- import { getChatCompletionFunction } from "./utils/request";
24
-
25
- /**
26
- * Micro AI chatbot.
27
- *
28
- * `MicroAgentica` is a facade class for the micro AI chatbot agent
29
- * which performs LLM (Large Language Model) function calling from the
30
- * {@link conversate user's conversation} and manages the
31
- * {@link getHistories prompt histories}.
32
- *
33
- * Different between `MicroAgentica` and {@link Agentica} is that
34
- * `MicroAgentica` does not have function selecting filter. It directly
35
- * list up every functions to the agent. Besides, {@link Agentica} has
36
- * a function selecting mechanism to reduce the number of functions to
37
- * be listed up to the agent.
38
- *
39
- * Therefore, if you have a lot of functions to call, you must not
40
- * use this `MicroAgentica` class. Use this `MicroAgentica` class only
41
- * when you have a few functions to call.
42
- *
43
- * - [Multi-agent orchestration of `@agentica`](https://wrtnlabs.io/agentica/docs/concepts/function-calling/#orchestration-strategy)
44
- * - Internal agents of `MicroAgentica`
45
- * - executor
46
- * - describier
47
- * - Internal agents of {@link Agentica}
48
- * - initializer
49
- * - **selector**
50
- * - executor
51
- * - describer
52
- *
53
- * @author Samchon
54
- */
55
- export class MicroAgentica {
56
- private readonly operations_: AgenticaOperationCollection;
57
- private readonly histories_: MicroAgenticaHistory[];
58
- private readonly token_usage_: AgenticaTokenUsage;
59
- private readonly listeners_: Map<
60
- string,
61
- Set<(event: MicroAgenticaEvent) => Promise<void>>
62
- >;
63
-
64
- private readonly semaphore_: Semaphore | null;
65
-
66
- /* -----------------------------------------------------------
67
- CONSTRUCTOR
68
- ----------------------------------------------------------- */
69
- /**
70
- * Initializer Constructor.
71
- *
72
- * @param props Properties to construct the micro agent
73
- */
74
- public constructor(private readonly props: IMicroAgenticaProps) {
75
- this.operations_ = AgenticaOperationComposer.compose({
76
- controllers: props.controllers,
77
- config: props.config,
78
- });
79
- this.histories_ = (props.histories ?? []).map(input =>
80
- transformHistory({
81
- operations: this.operations_.group,
82
- history: input,
83
- }) as MicroAgenticaHistory,
84
- );
85
- this.token_usage_ = this.props.tokenUsage !== undefined
86
- ? this.props.tokenUsage instanceof AgenticaTokenUsage
87
- ? this.props.tokenUsage
88
- : new AgenticaTokenUsage(this.props.tokenUsage)
89
- : AgenticaTokenUsage.zero();
90
- this.listeners_ = new Map();
91
- this.semaphore_ = props.vendor.semaphore != null
92
- ? typeof props.vendor.semaphore === "object"
93
- ? props.vendor.semaphore
94
- : new Semaphore(props.vendor.semaphore)
95
- : null;
96
- }
97
-
98
- /**
99
- * @internal
100
- */
101
- public clone(): MicroAgentica {
102
- return new MicroAgentica({
103
- ...this.props,
104
- histories: this.props.histories?.slice(),
105
- });
106
- }
107
-
108
- /* -----------------------------------------------------------
109
- ACCESSORS
110
- ----------------------------------------------------------- */
111
- /**
112
- * Conversate with the micro agent.
113
- *
114
- * User talks to the AI chatbot with the given content.
115
- *
116
- * When the user's conversation implies the AI chatbot to execute a
117
- * function calling, the returned chat prompts will contain the
118
- * function callinng information like {@link AgenticaExecuteHistory}
119
- *
120
- * @param content The content to talk
121
- * @returns List of newly created histories
122
- */
123
- public async conversate(
124
- content: string | AgenticaUserMessageContent | Array<AgenticaUserMessageContent>,
125
- options: {
126
- abortSignal?: AbortSignal;
127
- } = {},
128
- ): Promise<MicroAgenticaHistory[]> {
129
- const histories: Array<() => Promise<MicroAgenticaHistory>> = [];
130
- const dispatch = async (event: MicroAgenticaEvent): Promise<void> => {
131
- try {
132
- await this.dispatch(event);
133
- if ("toHistory" in event) {
134
- if ("join" in event) {
135
- histories.push(async () => {
136
- await event.join();
137
- return event.toHistory();
138
- });
139
- }
140
- else {
141
- histories.push(async () => event.toHistory());
142
- }
143
- }
144
- }
145
- catch {}
146
- };
147
-
148
- const prompt: AgenticaUserMessageEvent = createUserMessageEvent({
149
- contents: Array.isArray(content)
150
- ? content
151
- : typeof content === "string"
152
- ? [{
153
- type: "text",
154
- text: content,
155
- }]
156
- : [content],
157
- });
158
- void dispatch(prompt).catch(() => {});
159
-
160
- const ctx: MicroAgenticaContext = this.getContext({
161
- prompt,
162
- dispatch,
163
- usage: this.token_usage_,
164
- abortSignal: options.abortSignal,
165
- });
166
- const executes: AgenticaExecuteHistory[] = await call(
167
- ctx,
168
- this.operations_.array,
169
- );
170
-
171
- // eslint-disable-next-line
172
- if (executes.length && !!this.props.config?.executor?.describe) {
173
- const func = typeof this.props.config.executor.describe === "function"
174
- ? this.props.config.executor.describe
175
- : describe;
176
- await func(ctx, executes);
177
- }
178
-
179
- const completed: MicroAgenticaHistory[] = await Promise.all(
180
- histories.map(async h => h()),
181
- );
182
- this.histories_.push(...completed);
183
-
184
- // throw exception about failed execution
185
- if (this.props.config?.throw !== false) {
186
- for (const execute of executes) {
187
- assertExecuteFailure(execute);
188
- }
189
- }
190
- return completed;
191
- }
192
-
193
- /**
194
- * Get configuration.
195
- */
196
- public getConfig(): IMicroAgenticaConfig | undefined {
197
- return this.props.config;
198
- }
199
-
200
- /**
201
- * Get LLM vendor.
202
- */
203
- public getVendor(): IAgenticaVendor {
204
- return this.props.vendor;
205
- }
206
-
207
- /**
208
- * Get operations.
209
- *
210
- * Get list of operations, which has capsuled the pair of controller
211
- * and function from the {@link getControllers controllers}.
212
- *
213
- * @returns List of operations
214
- */
215
- public getOperations(): ReadonlyArray<AgenticaOperation> {
216
- return this.operations_.array;
217
- }
218
-
219
- /**
220
- * Get controllers.
221
- *
222
- * Get list of controllers, which are the collection of functions that
223
- * the agent can execute.
224
- */
225
- public getControllers(): ReadonlyArray<IAgenticaController> {
226
- return this.props.controllers;
227
- }
228
-
229
- /**
230
- * Get the chatbot's histories.
231
- *
232
- * Get list of chat histories that the chatbot has been conversated.
233
- *
234
- * @returns List of chat histories
235
- */
236
- public getHistories(): MicroAgenticaHistory[] {
237
- return this.histories_;
238
- }
239
-
240
- /**
241
- * Get token usage of the AI chatbot.
242
- *
243
- * Entire token usage of the AI chatbot during the conversating
244
- * with the user by {@link conversate} method callings.
245
- *
246
- * @returns Cost of the AI chatbot
247
- */
248
- public getTokenUsage(): AgenticaTokenUsage {
249
- return this.token_usage_;
250
- }
251
-
252
- /**
253
- * @internal
254
- */
255
- public getContext(props: {
256
- prompt: AgenticaUserMessageEvent;
257
- usage: AgenticaTokenUsage;
258
- dispatch: (event: MicroAgenticaEvent) => Promise<void>;
259
- abortSignal?: AbortSignal;
260
- }): MicroAgenticaContext {
261
- const request = getChatCompletionFunction({
262
- vendor: this.props.vendor,
263
- config: this.props.config,
264
- dispatch: props.dispatch,
265
- abortSignal: props.abortSignal,
266
- usage: this.token_usage_,
267
- });
268
- return {
269
- operations: this.operations_,
270
- config: this.props.config,
271
-
272
- histories: this.histories_,
273
- prompt: props.prompt,
274
- dispatch: props.dispatch,
275
- request: this.semaphore_ === null
276
- ? request
277
- : async (source, body) => {
278
- await this.semaphore_!.acquire();
279
- try {
280
- return await request(source, body);
281
- }
282
- finally {
283
- void this.semaphore_!.release().catch(() => {});
284
- }
285
- },
286
- };
287
- }
288
-
289
- /* -----------------------------------------------------------
290
- EVENT HANDLERS
291
- ----------------------------------------------------------- */
292
- /**
293
- * Add an event listener.
294
- *
295
- * Add an event listener to be called whenever the event is emitted.
296
- *
297
- * @param type Type of event
298
- * @param listener Callback function to be called whenever the event is emitted
299
- */
300
- public on<Type extends MicroAgenticaEvent.Type>(
301
- type: Type,
302
- listener: (
303
- event: MicroAgenticaEvent.Mapper[Type],
304
- ) => void | Promise<void>,
305
- ): this {
306
- /**
307
- * @TODO remove `as`
308
- */
309
- __map_take(this.listeners_, type, () => new Set()).add(listener as (event: MicroAgenticaEvent) => Promise<void>);
310
- return this;
311
- }
312
-
313
- /**
314
- * Erase an event listener.
315
- *
316
- * Erase an event listener to stop calling the callback function.
317
- *
318
- * @param type Type of event
319
- * @param listener Callback function to erase
320
- */
321
- public off<Type extends MicroAgenticaEvent.Type>(
322
- type: Type,
323
- listener: (
324
- event: MicroAgenticaEvent.Mapper[Type],
325
- ) => void | Promise<void>,
326
- ): this {
327
- const set = this.listeners_.get(type);
328
- if (set !== undefined) {
329
- /**
330
- * @TODO remove `as`
331
- */
332
- set.delete(listener as (event: MicroAgenticaEvent) => Promise<void>);
333
- if (set.size === 0) {
334
- this.listeners_.delete(type);
335
- }
336
- }
337
- return this;
338
- }
339
-
340
- private async dispatch<Event extends MicroAgenticaEvent>(
341
- event: Event,
342
- ): Promise<void> {
343
- const set = this.listeners_.get(event.type);
344
- if (set !== undefined) {
345
- await Promise.all(
346
- Array.from(set).map(async (listener) => {
347
- try {
348
- await listener(event);
349
- }
350
- catch {
351
- /* empty */
352
- }
353
- }),
354
- );
355
- }
356
- }
357
- }
1
+ import { Semaphore } from "tstl";
2
+
3
+ import type { AgenticaOperation } from "./context/AgenticaOperation";
4
+ import type { AgenticaOperationCollection } from "./context/AgenticaOperationCollection";
5
+ import type { MicroAgenticaContext } from "./context/MicroAgenticaContext";
6
+ import type { AgenticaUserMessageEvent } from "./events";
7
+ import type { MicroAgenticaEvent } from "./events/MicroAgenticaEvent";
8
+ import type { AgenticaUserMessageContent } from "./histories";
9
+ import type { AgenticaExecuteHistory } from "./histories/AgenticaExecuteHistory";
10
+ import type { MicroAgenticaHistory } from "./histories/MicroAgenticaHistory";
11
+ import type { IAgenticaController } from "./structures/IAgenticaController";
12
+ import type { IAgenticaVendor } from "./structures/IAgenticaVendor";
13
+ import type { IMicroAgenticaConfig } from "./structures/IMicroAgenticaConfig";
14
+ import type { IMicroAgenticaProps } from "./structures/IMicroAgenticaProps";
15
+
16
+ import { AgenticaTokenUsage } from "./context/AgenticaTokenUsage";
17
+ import { AgenticaOperationComposer } from "./context/internal/AgenticaOperationComposer";
18
+ import { createUserMessageEvent } from "./factory/events";
19
+ import { call, describe } from "./orchestrate";
20
+ import { transformHistory } from "./transformers/transformHistory";
21
+ import { __map_take } from "./utils/__map_take";
22
+ import { assertExecuteFailure } from "./utils/assertExecuteFailure";
23
+ import { getChatCompletionFunction } from "./utils/request";
24
+
25
+ /**
26
+ * Micro AI chatbot.
27
+ *
28
+ * `MicroAgentica` is a facade class for the micro AI chatbot agent
29
+ * which performs LLM (Large Language Model) function calling from the
30
+ * {@link conversate user's conversation} and manages the
31
+ * {@link getHistories prompt histories}.
32
+ *
33
+ * Different between `MicroAgentica` and {@link Agentica} is that
34
+ * `MicroAgentica` does not have function selecting filter. It directly
35
+ * list up every functions to the agent. Besides, {@link Agentica} has
36
+ * a function selecting mechanism to reduce the number of functions to
37
+ * be listed up to the agent.
38
+ *
39
+ * Therefore, if you have a lot of functions to call, you must not
40
+ * use this `MicroAgentica` class. Use this `MicroAgentica` class only
41
+ * when you have a few functions to call.
42
+ *
43
+ * - [Multi-agent orchestration of `@agentica`](https://wrtnlabs.io/agentica/docs/concepts/function-calling/#orchestration-strategy)
44
+ * - Internal agents of `MicroAgentica`
45
+ * - executor
46
+ * - describier
47
+ * - Internal agents of {@link Agentica}
48
+ * - initializer
49
+ * - **selector**
50
+ * - executor
51
+ * - describer
52
+ *
53
+ * @author Samchon
54
+ */
55
+ export class MicroAgentica {
56
+ private readonly operations_: AgenticaOperationCollection;
57
+ private readonly histories_: MicroAgenticaHistory[];
58
+ private readonly token_usage_: AgenticaTokenUsage;
59
+ private readonly listeners_: Map<
60
+ string,
61
+ Set<(event: MicroAgenticaEvent) => Promise<void>>
62
+ >;
63
+
64
+ private readonly semaphore_: Semaphore | null;
65
+
66
+ /* -----------------------------------------------------------
67
+ CONSTRUCTOR
68
+ ----------------------------------------------------------- */
69
+ /**
70
+ * Initializer Constructor.
71
+ *
72
+ * @param props Properties to construct the micro agent
73
+ */
74
+ public constructor(private readonly props: IMicroAgenticaProps) {
75
+ this.operations_ = AgenticaOperationComposer.compose({
76
+ controllers: props.controllers,
77
+ config: props.config,
78
+ });
79
+ this.histories_ = (props.histories ?? []).map(input =>
80
+ transformHistory({
81
+ operations: this.operations_.group,
82
+ history: input,
83
+ }) as MicroAgenticaHistory,
84
+ );
85
+ this.token_usage_ = this.props.tokenUsage !== undefined
86
+ ? this.props.tokenUsage instanceof AgenticaTokenUsage
87
+ ? this.props.tokenUsage
88
+ : new AgenticaTokenUsage(this.props.tokenUsage)
89
+ : AgenticaTokenUsage.zero();
90
+ this.listeners_ = new Map();
91
+ this.semaphore_ = props.vendor.semaphore != null
92
+ ? typeof props.vendor.semaphore === "object"
93
+ ? props.vendor.semaphore
94
+ : new Semaphore(props.vendor.semaphore)
95
+ : null;
96
+ }
97
+
98
+ /**
99
+ * @internal
100
+ */
101
+ public clone(): MicroAgentica {
102
+ return new MicroAgentica({
103
+ ...this.props,
104
+ histories: this.props.histories?.slice(),
105
+ });
106
+ }
107
+
108
+ /* -----------------------------------------------------------
109
+ ACCESSORS
110
+ ----------------------------------------------------------- */
111
+ /**
112
+ * Conversate with the micro agent.
113
+ *
114
+ * User talks to the AI chatbot with the given content.
115
+ *
116
+ * When the user's conversation implies the AI chatbot to execute a
117
+ * function calling, the returned chat prompts will contain the
118
+ * function callinng information like {@link AgenticaExecuteHistory}
119
+ *
120
+ * @param content The content to talk
121
+ * @returns List of newly created histories
122
+ */
123
+ public async conversate(
124
+ content: string | AgenticaUserMessageContent | Array<AgenticaUserMessageContent>,
125
+ options: {
126
+ abortSignal?: AbortSignal;
127
+ } = {},
128
+ ): Promise<MicroAgenticaHistory[]> {
129
+ const histories: Array<() => Promise<MicroAgenticaHistory>> = [];
130
+ const dispatch = async (event: MicroAgenticaEvent): Promise<void> => {
131
+ try {
132
+ await this.dispatch(event);
133
+ if ("toHistory" in event) {
134
+ if ("join" in event) {
135
+ histories.push(async () => {
136
+ await event.join();
137
+ return event.toHistory();
138
+ });
139
+ }
140
+ else {
141
+ histories.push(async () => event.toHistory());
142
+ }
143
+ }
144
+ }
145
+ catch {}
146
+ };
147
+
148
+ const prompt: AgenticaUserMessageEvent = createUserMessageEvent({
149
+ contents: Array.isArray(content)
150
+ ? content
151
+ : typeof content === "string"
152
+ ? [{
153
+ type: "text",
154
+ text: content,
155
+ }]
156
+ : [content],
157
+ });
158
+ void dispatch(prompt).catch(() => {});
159
+
160
+ const ctx: MicroAgenticaContext = this.getContext({
161
+ prompt,
162
+ dispatch,
163
+ usage: this.token_usage_,
164
+ abortSignal: options.abortSignal,
165
+ });
166
+ const executes: AgenticaExecuteHistory[] = await call(
167
+ ctx,
168
+ this.operations_.array,
169
+ );
170
+
171
+ // eslint-disable-next-line
172
+ if (executes.length && !!this.props.config?.executor?.describe) {
173
+ const func = typeof this.props.config.executor.describe === "function"
174
+ ? this.props.config.executor.describe
175
+ : describe;
176
+ await func(ctx, executes);
177
+ }
178
+
179
+ const completed: MicroAgenticaHistory[] = await Promise.all(
180
+ histories.map(async h => h()),
181
+ );
182
+ this.histories_.push(...completed);
183
+
184
+ // throw exception about failed execution
185
+ if (this.props.config?.throw !== false) {
186
+ for (const execute of executes) {
187
+ assertExecuteFailure(execute);
188
+ }
189
+ }
190
+ return completed;
191
+ }
192
+
193
+ /**
194
+ * Get configuration.
195
+ */
196
+ public getConfig(): IMicroAgenticaConfig | undefined {
197
+ return this.props.config;
198
+ }
199
+
200
+ /**
201
+ * Get LLM vendor.
202
+ */
203
+ public getVendor(): IAgenticaVendor {
204
+ return this.props.vendor;
205
+ }
206
+
207
+ /**
208
+ * Get operations.
209
+ *
210
+ * Get list of operations, which has capsuled the pair of controller
211
+ * and function from the {@link getControllers controllers}.
212
+ *
213
+ * @returns List of operations
214
+ */
215
+ public getOperations(): ReadonlyArray<AgenticaOperation> {
216
+ return this.operations_.array;
217
+ }
218
+
219
+ /**
220
+ * Get controllers.
221
+ *
222
+ * Get list of controllers, which are the collection of functions that
223
+ * the agent can execute.
224
+ */
225
+ public getControllers(): ReadonlyArray<IAgenticaController> {
226
+ return this.props.controllers;
227
+ }
228
+
229
+ /**
230
+ * Get the chatbot's histories.
231
+ *
232
+ * Get list of chat histories that the chatbot has been conversated.
233
+ *
234
+ * @returns List of chat histories
235
+ */
236
+ public getHistories(): MicroAgenticaHistory[] {
237
+ return this.histories_;
238
+ }
239
+
240
+ /**
241
+ * Get token usage of the AI chatbot.
242
+ *
243
+ * Entire token usage of the AI chatbot during the conversating
244
+ * with the user by {@link conversate} method callings.
245
+ *
246
+ * @returns Cost of the AI chatbot
247
+ */
248
+ public getTokenUsage(): AgenticaTokenUsage {
249
+ return this.token_usage_;
250
+ }
251
+
252
+ /**
253
+ * @internal
254
+ */
255
+ public getContext(props: {
256
+ prompt: AgenticaUserMessageEvent;
257
+ usage: AgenticaTokenUsage;
258
+ dispatch: (event: MicroAgenticaEvent) => Promise<void>;
259
+ abortSignal?: AbortSignal;
260
+ }): MicroAgenticaContext {
261
+ const request = getChatCompletionFunction({
262
+ vendor: this.props.vendor,
263
+ config: this.props.config,
264
+ dispatch: props.dispatch,
265
+ abortSignal: props.abortSignal,
266
+ usage: this.token_usage_,
267
+ });
268
+ return {
269
+ operations: this.operations_,
270
+ config: this.props.config,
271
+
272
+ histories: this.histories_,
273
+ prompt: props.prompt,
274
+ dispatch: props.dispatch,
275
+ request: this.semaphore_ === null
276
+ ? request
277
+ : async (source, body) => {
278
+ await this.semaphore_!.acquire();
279
+ try {
280
+ return await request(source, body);
281
+ }
282
+ finally {
283
+ void this.semaphore_!.release().catch(() => {});
284
+ }
285
+ },
286
+ };
287
+ }
288
+
289
+ /* -----------------------------------------------------------
290
+ EVENT HANDLERS
291
+ ----------------------------------------------------------- */
292
+ /**
293
+ * Add an event listener.
294
+ *
295
+ * Add an event listener to be called whenever the event is emitted.
296
+ *
297
+ * @param type Type of event
298
+ * @param listener Callback function to be called whenever the event is emitted
299
+ */
300
+ public on<Type extends MicroAgenticaEvent.Type>(
301
+ type: Type,
302
+ listener: (
303
+ event: MicroAgenticaEvent.Mapper[Type],
304
+ ) => void | Promise<void>,
305
+ ): this {
306
+ /**
307
+ * @TODO remove `as`
308
+ */
309
+ __map_take(this.listeners_, type, () => new Set()).add(listener as (event: MicroAgenticaEvent) => Promise<void>);
310
+ return this;
311
+ }
312
+
313
+ /**
314
+ * Erase an event listener.
315
+ *
316
+ * Erase an event listener to stop calling the callback function.
317
+ *
318
+ * @param type Type of event
319
+ * @param listener Callback function to erase
320
+ */
321
+ public off<Type extends MicroAgenticaEvent.Type>(
322
+ type: Type,
323
+ listener: (
324
+ event: MicroAgenticaEvent.Mapper[Type],
325
+ ) => void | Promise<void>,
326
+ ): this {
327
+ const set = this.listeners_.get(type);
328
+ if (set !== undefined) {
329
+ /**
330
+ * @TODO remove `as`
331
+ */
332
+ set.delete(listener as (event: MicroAgenticaEvent) => Promise<void>);
333
+ if (set.size === 0) {
334
+ this.listeners_.delete(type);
335
+ }
336
+ }
337
+ return this;
338
+ }
339
+
340
+ private async dispatch<Event extends MicroAgenticaEvent>(
341
+ event: Event,
342
+ ): Promise<void> {
343
+ const set = this.listeners_.get(event.type);
344
+ if (set !== undefined) {
345
+ await Promise.all(
346
+ Array.from(set).map(async (listener) => {
347
+ try {
348
+ await listener(event);
349
+ }
350
+ catch {
351
+ /* empty */
352
+ }
353
+ }),
354
+ );
355
+ }
356
+ }
357
+ }