@agentica/core 0.8.2 → 0.8.3-dev.20250227

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 (53) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +404 -404
  3. package/lib/Agentica.js +1 -4
  4. package/lib/Agentica.js.map +1 -1
  5. package/lib/index.mjs +8 -13
  6. package/lib/index.mjs.map +1 -1
  7. package/lib/internal/AgenticaTokenUsageAggregator.js +7 -9
  8. package/lib/internal/AgenticaTokenUsageAggregator.js.map +1 -1
  9. package/lib/structures/IAgenticaTokenUsage.d.ts +7 -11
  10. package/package.json +1 -1
  11. package/prompts/cancel.md +4 -4
  12. package/prompts/common.md +2 -2
  13. package/prompts/describe.md +6 -6
  14. package/prompts/execute.md +6 -6
  15. package/prompts/initialize.md +2 -2
  16. package/prompts/select.md +6 -6
  17. package/src/Agentica.ts +318 -322
  18. package/src/chatgpt/ChatGptAgent.ts +71 -71
  19. package/src/chatgpt/ChatGptCallFunctionAgent.ts +445 -445
  20. package/src/chatgpt/ChatGptCancelFunctionAgent.ts +283 -283
  21. package/src/chatgpt/ChatGptDescribeFunctionAgent.ts +51 -51
  22. package/src/chatgpt/ChatGptHistoryDecoder.ts +87 -87
  23. package/src/chatgpt/ChatGptInitializeFunctionAgent.ts +88 -88
  24. package/src/chatgpt/ChatGptSelectFunctionAgent.ts +318 -318
  25. package/src/functional/createHttpLlmApplication.ts +63 -63
  26. package/src/index.ts +19 -19
  27. package/src/internal/AgenticaConstant.ts +4 -4
  28. package/src/internal/AgenticaDefaultPrompt.ts +39 -39
  29. package/src/internal/AgenticaOperationComposer.ts +82 -82
  30. package/src/internal/AgenticaPromptFactory.ts +30 -30
  31. package/src/internal/AgenticaPromptTransformer.ts +83 -83
  32. package/src/internal/AgenticaTokenUsageAggregator.ts +115 -123
  33. package/src/internal/MathUtil.ts +3 -3
  34. package/src/internal/Singleton.ts +22 -22
  35. package/src/internal/__map_take.ts +15 -15
  36. package/src/structures/IAgenticaConfig.ts +121 -121
  37. package/src/structures/IAgenticaContext.ts +128 -128
  38. package/src/structures/IAgenticaController.ts +130 -130
  39. package/src/structures/IAgenticaEvent.ts +224 -224
  40. package/src/structures/IAgenticaExecutor.ts +152 -152
  41. package/src/structures/IAgenticaOperation.ts +64 -64
  42. package/src/structures/IAgenticaOperationCollection.ts +50 -50
  43. package/src/structures/IAgenticaOperationSelection.ts +69 -69
  44. package/src/structures/IAgenticaPrompt.ts +173 -173
  45. package/src/structures/IAgenticaProps.ts +64 -64
  46. package/src/structures/IAgenticaProvider.ts +45 -45
  47. package/src/structures/IAgenticaSystemPrompt.ts +122 -122
  48. package/src/structures/IAgenticaTokenUsage.ts +107 -112
  49. package/src/structures/internal/__IChatCancelFunctionsApplication.ts +23 -23
  50. package/src/structures/internal/__IChatFunctionReference.ts +21 -21
  51. package/src/structures/internal/__IChatInitialApplication.ts +15 -15
  52. package/src/structures/internal/__IChatSelectFunctionsApplication.ts +24 -24
  53. package/src/typings/AgenticaSource.ts +6 -6
package/src/Agentica.ts CHANGED
@@ -1,322 +1,318 @@
1
- import OpenAI from "openai";
2
-
3
- import { ChatGptAgent } from "./chatgpt/ChatGptAgent";
4
- import { AgenticaOperationComposer } from "./internal/AgenticaOperationComposer";
5
- import { AgenticaPromptTransformer } from "./internal/AgenticaPromptTransformer";
6
- import { AgenticaTokenUsageAggregator } from "./internal/AgenticaTokenUsageAggregator";
7
- import { __map_take } from "./internal/__map_take";
8
- import { IAgenticaConfig } from "./structures/IAgenticaConfig";
9
- import { IAgenticaContext } from "./structures/IAgenticaContext";
10
- import { IAgenticaController } from "./structures/IAgenticaController";
11
- import { IAgenticaEvent } from "./structures/IAgenticaEvent";
12
- import { IAgenticaOperation } from "./structures/IAgenticaOperation";
13
- import { IAgenticaOperationCollection } from "./structures/IAgenticaOperationCollection";
14
- import { IAgenticaOperationSelection } from "./structures/IAgenticaOperationSelection";
15
- import { IAgenticaPrompt } from "./structures/IAgenticaPrompt";
16
- import { IAgenticaProps } from "./structures/IAgenticaProps";
17
- import { IAgenticaProvider } from "./structures/IAgenticaProvider";
18
- import { IAgenticaTokenUsage } from "./structures/IAgenticaTokenUsage";
19
-
20
- /**
21
- * Nestia A.I. chatbot agent.
22
- *
23
- * `Agentica` is a facade class for the super A.I. chatbot agent
24
- * which performs the {@link conversate user's conversation function}
25
- * with LLM (Large Language Model) function calling and manages the
26
- * {@link getPromptHistories prompt histories}.
27
- *
28
- * To understand and compose the `Agentica` class exactly, reference
29
- * below types concentrating on the documentation comments please.
30
- * Especially, you have to be careful about the {@link IAgenticaProps}
31
- * type which is used in the {@link constructor} function.
32
- *
33
- * - Constructors
34
- * - {@link IAgenticaProps}
35
- * - {@link IAgenticaProvider}
36
- * - {@link IAgenticaController}
37
- * - {@link IAgenticaConfig}
38
- * - {@link IAgenticaSystemPrompt}
39
- * - Accessors
40
- * - {@link IAgenticaOperation}
41
- * - {@link IAgenticaPrompt}
42
- * - {@link IAgenticaEvent}
43
- * - {@link IAgenticaTokenUsage}
44
- *
45
- * @author Samchon
46
- */
47
- export class Agentica {
48
- // THE OPERATIONS
49
- private readonly operations_: IAgenticaOperationCollection;
50
-
51
- // STACK
52
- private readonly stack_: IAgenticaOperationSelection[];
53
- private readonly prompt_histories_: IAgenticaPrompt[];
54
- private readonly listeners_: Map<string, Set<Function>>;
55
-
56
- // STATUS
57
- private readonly token_usage_: IAgenticaTokenUsage;
58
- private ready_: boolean;
59
- private readonly executor_: (
60
- ctx: IAgenticaContext,
61
- ) => Promise<IAgenticaPrompt[]>;
62
-
63
- /* -----------------------------------------------------------
64
- CONSTRUCTOR
65
- ----------------------------------------------------------- */
66
- /**
67
- * Initializer constructor.
68
- *
69
- * @param props Properties to construct the agent
70
- */
71
- public constructor(private readonly props: IAgenticaProps) {
72
- // OPERATIONS
73
- this.operations_ = AgenticaOperationComposer.compose({
74
- controllers: props.controllers,
75
- config: props.config,
76
- });
77
-
78
- // STATUS
79
- this.stack_ = [];
80
- this.listeners_ = new Map();
81
- this.prompt_histories_ = (props.histories ?? []).map((input) =>
82
- AgenticaPromptTransformer.transform({
83
- operations: this.operations_.group,
84
- input,
85
- }),
86
- );
87
-
88
- // STATUS
89
- this.token_usage_ = AgenticaTokenUsageAggregator.zero();
90
- this.ready_ = false;
91
- this.executor_ =
92
- typeof props.config?.executor === "function"
93
- ? props.config.executor
94
- : ChatGptAgent.execute(props.config?.executor ?? null);
95
- }
96
-
97
- /**
98
- * @internal
99
- */
100
- public clone(): Agentica {
101
- return new Agentica({
102
- ...this.props,
103
- histories: this.props.histories?.slice(),
104
- });
105
- }
106
-
107
- /* -----------------------------------------------------------
108
- ACCESSORS
109
- ----------------------------------------------------------- */
110
- /**
111
- * Conversate with the A.I. chatbot.
112
- *
113
- * User talks to the A.I. chatbot with the content.
114
- *
115
- * When the user's conversation implies the A.I. chatbot to execute a
116
- * function calling, the returned chat prompts will contain the
117
- * function calling information like {@link IAgenticaPrompt.IExecute}.
118
- *
119
- * @param content The content to talk
120
- * @returns List of newly created chat prompts
121
- */
122
- public async conversate(content: string): Promise<IAgenticaPrompt[]> {
123
- const prompt: IAgenticaPrompt.IText<"user"> = {
124
- type: "text",
125
- role: "user",
126
- text: content,
127
- };
128
- await this.dispatch(prompt);
129
-
130
- const newbie: IAgenticaPrompt[] = await this.executor_(
131
- this.getContext({
132
- prompt,
133
- usage: this.token_usage_,
134
- }),
135
- );
136
- this.prompt_histories_.push(prompt, ...newbie);
137
- return [prompt, ...newbie];
138
- }
139
-
140
- /**
141
- * Get configuration.
142
- */
143
- public getConfig(): IAgenticaConfig | undefined {
144
- return this.props.config;
145
- }
146
-
147
- /**
148
- * Get LLM Provider.
149
- */
150
- public getProvider(): IAgenticaProvider {
151
- return this.props.provider;
152
- }
153
-
154
- /**
155
- * Get controllers.
156
- *
157
- * Get list of controllers, which are the collection of functions that
158
- * the "Super A.I. Chatbot" can execute.
159
- */
160
- public getControllers(): ReadonlyArray<IAgenticaController> {
161
- return this.props.controllers;
162
- }
163
-
164
- /**
165
- * Get operations.
166
- *
167
- * Get list of operations, which has capsuled the pair of controller
168
- * and function from the {@link getControllers controllers}.
169
- *
170
- * @returns
171
- */
172
- public getOperations(): ReadonlyArray<IAgenticaOperation> {
173
- return this.operations_.array;
174
- }
175
-
176
- /**
177
- * Get the chatbot's prompt histories.
178
- *
179
- * Get list of chat prompts that the chatbot has been conversated.
180
- *
181
- * @returns List of chat prompts
182
- */
183
- public getPromptHistories(): IAgenticaPrompt[] {
184
- return this.prompt_histories_;
185
- }
186
-
187
- /**
188
- * Get token usage of the A.I. chatbot.
189
- *
190
- * Entire token usage of the A.I. chatbot during the conversating
191
- * with the user by {@link conversate} method callings.
192
- *
193
- * @returns Cost of the A.I. chatbot
194
- */
195
- public getTokenUsage(): IAgenticaTokenUsage {
196
- return this.token_usage_;
197
- }
198
-
199
- /**
200
- * @internal
201
- */
202
- public getContext(props: {
203
- prompt: IAgenticaPrompt.IText<"user">;
204
- usage: IAgenticaTokenUsage;
205
- }): IAgenticaContext {
206
- const dispatch = (event: IAgenticaEvent) => this.dispatch(event);
207
- return {
208
- // APPLICATION
209
- operations: this.operations_,
210
- config: this.props.config,
211
-
212
- // STATES
213
- histories: this.prompt_histories_,
214
- stack: this.stack_,
215
- ready: () => this.ready_,
216
- prompt: props.prompt,
217
-
218
- // HANDLERS
219
- dispatch: async (event: IAgenticaEvent) => {
220
- await this.dispatch(event);
221
- },
222
- request: async (kind, body) => {
223
- // request information
224
- const event: IAgenticaEvent.IRequest = {
225
- type: "request",
226
- source: kind,
227
- body: {
228
- ...body,
229
- model: this.props.provider.model,
230
- },
231
- options: this.props.provider.options,
232
- };
233
- await dispatch(event);
234
-
235
- // completion
236
- const completion: OpenAI.ChatCompletion =
237
- await this.props.provider.api.chat.completions.create(
238
- event.body,
239
- event.options,
240
- );
241
- AgenticaTokenUsageAggregator.aggregate({
242
- kind,
243
- completion,
244
- usage: props.usage,
245
- });
246
- await dispatch({
247
- type: "response",
248
- source: kind,
249
- body: event.body,
250
- options: event.options,
251
- value: completion,
252
- });
253
- return completion;
254
- },
255
- initialize: async () => {
256
- this.ready_ = true;
257
- await dispatch({
258
- type: "initialize",
259
- });
260
- },
261
- };
262
- }
263
-
264
- /* -----------------------------------------------------------
265
- EVENT HANDLERS
266
- ----------------------------------------------------------- */
267
- /**
268
- * Add an event listener.
269
- *
270
- * Add an event listener to be called whenever the event is emitted.
271
- *
272
- * @param type Type of event
273
- * @param listener Callback function to be called whenever the event is emitted
274
- */
275
- public on<Type extends IAgenticaEvent.Type>(
276
- type: Type,
277
- listener: (event: IAgenticaEvent.Mapper[Type]) => void | Promise<void>,
278
- ): this {
279
- __map_take(this.listeners_, type, () => new Set()).add(listener);
280
- return this;
281
- }
282
-
283
- /**
284
- * Erase an event listener.
285
- *
286
- * Erase an event listener to stop calling the callback function.
287
- *
288
- * @param type Type of event
289
- * @param listener Callback function to erase
290
- */
291
- public off<Type extends IAgenticaEvent.Type>(
292
- type: Type,
293
- listener: (event: IAgenticaEvent.Mapper[Type]) => void | Promise<void>,
294
- ): this {
295
- const set = this.listeners_.get(type);
296
- if (set) {
297
- set.delete(listener);
298
- if (set.size === 0) this.listeners_.delete(type);
299
- }
300
- return this;
301
- }
302
-
303
- private async dispatch<Event extends IAgenticaEvent>(
304
- event: Event,
305
- ): Promise<this> {
306
- const set = this.listeners_.get(event.type);
307
- if (set) {
308
- await Promise.all(
309
- Array.from(set).map(async (listener) => {
310
- try {
311
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
312
- await listener(event);
313
- } catch {
314
- /* empty */
315
- }
316
- }),
317
- );
318
- }
319
-
320
- return this;
321
- }
322
- }
1
+ import OpenAI from "openai";
2
+
3
+ import { ChatGptAgent } from "./chatgpt/ChatGptAgent";
4
+ import { AgenticaOperationComposer } from "./internal/AgenticaOperationComposer";
5
+ import { AgenticaPromptTransformer } from "./internal/AgenticaPromptTransformer";
6
+ import { AgenticaTokenUsageAggregator } from "./internal/AgenticaTokenUsageAggregator";
7
+ import { __map_take } from "./internal/__map_take";
8
+ import { IAgenticaConfig } from "./structures/IAgenticaConfig";
9
+ import { IAgenticaContext } from "./structures/IAgenticaContext";
10
+ import { IAgenticaController } from "./structures/IAgenticaController";
11
+ import { IAgenticaEvent } from "./structures/IAgenticaEvent";
12
+ import { IAgenticaOperation } from "./structures/IAgenticaOperation";
13
+ import { IAgenticaOperationCollection } from "./structures/IAgenticaOperationCollection";
14
+ import { IAgenticaOperationSelection } from "./structures/IAgenticaOperationSelection";
15
+ import { IAgenticaPrompt } from "./structures/IAgenticaPrompt";
16
+ import { IAgenticaProps } from "./structures/IAgenticaProps";
17
+ import { IAgenticaProvider } from "./structures/IAgenticaProvider";
18
+ import { IAgenticaTokenUsage } from "./structures/IAgenticaTokenUsage";
19
+
20
+ /**
21
+ * Nestia A.I. chatbot agent.
22
+ *
23
+ * `Agentica` is a facade class for the super A.I. chatbot agent
24
+ * which performs the {@link conversate user's conversation function}
25
+ * with LLM (Large Language Model) function calling and manages the
26
+ * {@link getPromptHistories prompt histories}.
27
+ *
28
+ * To understand and compose the `Agentica` class exactly, reference
29
+ * below types concentrating on the documentation comments please.
30
+ * Especially, you have to be careful about the {@link IAgenticaProps}
31
+ * type which is used in the {@link constructor} function.
32
+ *
33
+ * - Constructors
34
+ * - {@link IAgenticaProps}
35
+ * - {@link IAgenticaProvider}
36
+ * - {@link IAgenticaController}
37
+ * - {@link IAgenticaConfig}
38
+ * - {@link IAgenticaSystemPrompt}
39
+ * - Accessors
40
+ * - {@link IAgenticaOperation}
41
+ * - {@link IAgenticaPrompt}
42
+ * - {@link IAgenticaEvent}
43
+ * - {@link IAgenticaTokenUsage}
44
+ *
45
+ * @author Samchon
46
+ */
47
+ export class Agentica {
48
+ // THE OPERATIONS
49
+ private readonly operations_: IAgenticaOperationCollection;
50
+
51
+ // STACK
52
+ private readonly stack_: IAgenticaOperationSelection[];
53
+ private readonly prompt_histories_: IAgenticaPrompt[];
54
+ private readonly listeners_: Map<string, Set<Function>>;
55
+
56
+ // STATUS
57
+ private readonly token_usage_: IAgenticaTokenUsage;
58
+ private ready_: boolean;
59
+ private readonly executor_: (
60
+ ctx: IAgenticaContext,
61
+ ) => Promise<IAgenticaPrompt[]>;
62
+
63
+ /* -----------------------------------------------------------
64
+ CONSTRUCTOR
65
+ ----------------------------------------------------------- */
66
+ /**
67
+ * Initializer constructor.
68
+ *
69
+ * @param props Properties to construct the agent
70
+ */
71
+ public constructor(private readonly props: IAgenticaProps) {
72
+ // OPERATIONS
73
+ this.operations_ = AgenticaOperationComposer.compose({
74
+ controllers: props.controllers,
75
+ config: props.config,
76
+ });
77
+
78
+ // STATUS
79
+ this.stack_ = [];
80
+ this.listeners_ = new Map();
81
+ this.prompt_histories_ = (props.histories ?? []).map((input) =>
82
+ AgenticaPromptTransformer.transform({
83
+ operations: this.operations_.group,
84
+ input,
85
+ }),
86
+ );
87
+
88
+ // STATUS
89
+ this.token_usage_ = AgenticaTokenUsageAggregator.zero();
90
+ this.ready_ = false;
91
+ this.executor_ =
92
+ typeof props.config?.executor === "function"
93
+ ? props.config.executor
94
+ : ChatGptAgent.execute(props.config?.executor ?? null);
95
+ }
96
+
97
+ /**
98
+ * @internal
99
+ */
100
+ public clone(): Agentica {
101
+ return new Agentica({
102
+ ...this.props,
103
+ histories: this.props.histories?.slice(),
104
+ });
105
+ }
106
+
107
+ /* -----------------------------------------------------------
108
+ ACCESSORS
109
+ ----------------------------------------------------------- */
110
+ /**
111
+ * Conversate with the A.I. chatbot.
112
+ *
113
+ * User talks to the A.I. chatbot with the content.
114
+ *
115
+ * When the user's conversation implies the A.I. chatbot to execute a
116
+ * function calling, the returned chat prompts will contain the
117
+ * function calling information like {@link IAgenticaPrompt.IExecute}.
118
+ *
119
+ * @param content The content to talk
120
+ * @returns List of newly created chat prompts
121
+ */
122
+ public async conversate(content: string): Promise<IAgenticaPrompt[]> {
123
+ const prompt: IAgenticaPrompt.IText<"user"> = {
124
+ type: "text",
125
+ role: "user",
126
+ text: content,
127
+ };
128
+ await this.dispatch(prompt);
129
+
130
+ const newbie: IAgenticaPrompt[] = await this.executor_(
131
+ this.getContext({
132
+ prompt,
133
+ usage: this.token_usage_,
134
+ }),
135
+ );
136
+ this.prompt_histories_.push(prompt, ...newbie);
137
+ return [prompt, ...newbie];
138
+ }
139
+
140
+ /**
141
+ * Get configuration.
142
+ */
143
+ public getConfig(): IAgenticaConfig | undefined {
144
+ return this.props.config;
145
+ }
146
+
147
+ /**
148
+ * Get LLM Provider.
149
+ */
150
+ public getProvider(): IAgenticaProvider {
151
+ return this.props.provider;
152
+ }
153
+
154
+ /**
155
+ * Get controllers.
156
+ *
157
+ * Get list of controllers, which are the collection of functions that
158
+ * the "Super A.I. Chatbot" can execute.
159
+ */
160
+ public getControllers(): ReadonlyArray<IAgenticaController> {
161
+ return this.props.controllers;
162
+ }
163
+
164
+ /**
165
+ * Get operations.
166
+ *
167
+ * Get list of operations, which has capsuled the pair of controller
168
+ * and function from the {@link getControllers controllers}.
169
+ *
170
+ * @returns
171
+ */
172
+ public getOperations(): ReadonlyArray<IAgenticaOperation> {
173
+ return this.operations_.array;
174
+ }
175
+
176
+ /**
177
+ * Get the chatbot's prompt histories.
178
+ *
179
+ * Get list of chat prompts that the chatbot has been conversated.
180
+ *
181
+ * @returns List of chat prompts
182
+ */
183
+ public getPromptHistories(): IAgenticaPrompt[] {
184
+ return this.prompt_histories_;
185
+ }
186
+
187
+ /**
188
+ * Get token usage of the A.I. chatbot.
189
+ *
190
+ * Entire token usage of the A.I. chatbot during the conversating
191
+ * with the user by {@link conversate} method callings.
192
+ *
193
+ * @returns Cost of the A.I. chatbot
194
+ */
195
+ public getTokenUsage(): IAgenticaTokenUsage {
196
+ return this.token_usage_;
197
+ }
198
+
199
+ /**
200
+ * @internal
201
+ */
202
+ public getContext(props: {
203
+ prompt: IAgenticaPrompt.IText<"user">;
204
+ usage: IAgenticaTokenUsage;
205
+ }): IAgenticaContext {
206
+ const dispatch = (event: IAgenticaEvent) => this.dispatch(event);
207
+ return {
208
+ // APPLICATION
209
+ operations: this.operations_,
210
+ config: this.props.config,
211
+
212
+ // STATES
213
+ histories: this.prompt_histories_,
214
+ stack: this.stack_,
215
+ ready: () => this.ready_,
216
+ prompt: props.prompt,
217
+
218
+ // HANDLERS
219
+ dispatch: (event) => this.dispatch(event),
220
+ request: async (kind, body) => {
221
+ // request information
222
+ const event: IAgenticaEvent.IRequest = {
223
+ type: "request",
224
+ source: kind,
225
+ body: {
226
+ ...body,
227
+ model: this.props.provider.model,
228
+ },
229
+ options: this.props.provider.options,
230
+ };
231
+ await dispatch(event);
232
+
233
+ // completion
234
+ const completion: OpenAI.ChatCompletion =
235
+ await this.props.provider.api.chat.completions.create(
236
+ event.body,
237
+ event.options,
238
+ );
239
+ AgenticaTokenUsageAggregator.aggregate({
240
+ kind,
241
+ completion,
242
+ usage: props.usage,
243
+ });
244
+ await dispatch({
245
+ type: "response",
246
+ source: kind,
247
+ body: event.body,
248
+ options: event.options,
249
+ value: completion,
250
+ });
251
+ return completion;
252
+ },
253
+ initialize: async () => {
254
+ this.ready_ = true;
255
+ await dispatch({
256
+ type: "initialize",
257
+ });
258
+ },
259
+ };
260
+ }
261
+
262
+ /* -----------------------------------------------------------
263
+ EVENT HANDLERS
264
+ ----------------------------------------------------------- */
265
+ /**
266
+ * Add an event listener.
267
+ *
268
+ * Add an event listener to be called whenever the event is emitted.
269
+ *
270
+ * @param type Type of event
271
+ * @param listener Callback function to be called whenever the event is emitted
272
+ */
273
+ public on<Type extends IAgenticaEvent.Type>(
274
+ type: Type,
275
+ listener: (event: IAgenticaEvent.Mapper[Type]) => void | Promise<void>,
276
+ ): this {
277
+ __map_take(this.listeners_, type, () => new Set()).add(listener);
278
+ return this;
279
+ }
280
+
281
+ /**
282
+ * Erase an event listener.
283
+ *
284
+ * Erase an event listener to stop calling the callback function.
285
+ *
286
+ * @param type Type of event
287
+ * @param listener Callback function to erase
288
+ */
289
+ public off<Type extends IAgenticaEvent.Type>(
290
+ type: Type,
291
+ listener: (event: IAgenticaEvent.Mapper[Type]) => void | Promise<void>,
292
+ ): this {
293
+ const set = this.listeners_.get(type);
294
+ if (set) {
295
+ set.delete(listener);
296
+ if (set.size === 0) this.listeners_.delete(type);
297
+ }
298
+ return this;
299
+ }
300
+
301
+ private async dispatch<Event extends IAgenticaEvent>(
302
+ event: Event,
303
+ ): Promise<void> {
304
+ const set = this.listeners_.get(event.type);
305
+ if (set) {
306
+ await Promise.all(
307
+ Array.from(set).map(async (listener) => {
308
+ try {
309
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
310
+ await listener(event);
311
+ } catch {
312
+ /* empty */
313
+ }
314
+ }),
315
+ );
316
+ }
317
+ }
318
+ }