@agentica/core 0.32.3 → 0.32.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.
Files changed (47) hide show
  1. package/lib/context/MicroAgenticaContext.d.ts +4 -0
  2. package/lib/events/AgenticaJsonParseErrorEvent.d.ts +1 -0
  3. package/lib/events/AgenticaValidateEvent.d.ts +1 -0
  4. package/lib/factory/events.d.ts +2 -0
  5. package/lib/factory/events.js +3 -0
  6. package/lib/factory/events.js.map +1 -1
  7. package/lib/index.mjs +44 -28
  8. package/lib/index.mjs.map +1 -1
  9. package/lib/json/IAgenticaEventJson.d.ts +2 -0
  10. package/lib/orchestrate/call.js +8 -6
  11. package/lib/orchestrate/call.js.map +1 -1
  12. package/lib/orchestrate/cancel.js +1 -1
  13. package/lib/orchestrate/cancel.js.map +1 -1
  14. package/lib/orchestrate/describe.js +1 -1
  15. package/lib/orchestrate/describe.js.map +1 -1
  16. package/lib/orchestrate/initialize.js +1 -1
  17. package/lib/orchestrate/initialize.js.map +1 -1
  18. package/lib/orchestrate/select.js +5 -5
  19. package/lib/orchestrate/select.js.map +1 -1
  20. package/lib/utils/AssistantMessageEmptyError.js +9 -0
  21. package/lib/utils/AssistantMessageEmptyError.js.map +1 -1
  22. package/lib/utils/ChatGptCompletionStreamingUtil.d.ts +1 -1
  23. package/lib/utils/ChatGptCompletionStreamingUtil.js +2 -2
  24. package/lib/utils/ChatGptCompletionStreamingUtil.js.map +1 -1
  25. package/lib/utils/StreamUtil.d.ts +7 -4
  26. package/lib/utils/StreamUtil.js +17 -14
  27. package/lib/utils/StreamUtil.js.map +1 -1
  28. package/lib/utils/StreamUtil.spec.js +12 -12
  29. package/lib/utils/StreamUtil.spec.js.map +1 -1
  30. package/lib/utils/request.js +5 -4
  31. package/lib/utils/request.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/context/MicroAgenticaContext.ts +4 -0
  34. package/src/events/AgenticaJsonParseErrorEvent.ts +1 -0
  35. package/src/events/AgenticaValidateEvent.ts +2 -0
  36. package/src/factory/events.ts +5 -0
  37. package/src/json/IAgenticaEventJson.ts +4 -0
  38. package/src/orchestrate/call.ts +5 -1
  39. package/src/orchestrate/cancel.ts +1 -1
  40. package/src/orchestrate/describe.ts +1 -1
  41. package/src/orchestrate/initialize.ts +1 -1
  42. package/src/orchestrate/select.ts +2 -2
  43. package/src/utils/AssistantMessageEmptyError.ts +8 -1
  44. package/src/utils/ChatGptCompletionStreamingUtil.ts +2 -2
  45. package/src/utils/StreamUtil.spec.ts +12 -9
  46. package/src/utils/StreamUtil.ts +15 -11
  47. package/src/utils/request.ts +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentica/core",
3
- "version": "0.32.3",
3
+ "version": "0.32.5",
4
4
  "description": "Agentic AI Library specialized in LLM Function Calling",
5
5
  "author": "Wrtn Technologies",
6
6
  "license": "MIT",
@@ -68,6 +68,10 @@ export interface MicroAgenticaContext<Model extends ILlmSchema.Model> {
68
68
  */
69
69
  prompt: AgenticaUserMessageHistory;
70
70
 
71
+ /**
72
+ * Abort signal.
73
+ */
74
+ abortSignal?: AbortSignal;
71
75
  // ----
72
76
  // HANDLERS
73
77
  // ----
@@ -9,4 +9,5 @@ export interface AgenticaJsonParseErrorEvent<Model extends ILlmSchema.Model>
9
9
  operation: AgenticaOperation<Model>;
10
10
  arguments: string;
11
11
  errorMessage: string;
12
+ life: number;
12
13
  }
@@ -29,5 +29,7 @@ export interface AgenticaValidateEvent<
29
29
  */
30
30
  result: IValidation.IFailure;
31
31
 
32
+ life: number;
33
+
32
34
  toJSON: () => IAgenticaEventJson.IValidate;
33
35
  }
@@ -118,6 +118,7 @@ export function createJsonParseErrorEvent<Model extends ILlmSchema.Model>(props:
118
118
  operation: AgenticaOperation<Model>;
119
119
  arguments: string;
120
120
  errorMessage: string;
121
+ life: number;
121
122
  }): AgenticaJsonParseErrorEvent<Model> {
122
123
  const created_at: string = new Date().toISOString();
123
124
  return {
@@ -127,6 +128,7 @@ export function createJsonParseErrorEvent<Model extends ILlmSchema.Model>(props:
127
128
  operation: props.operation,
128
129
  arguments: props.arguments,
129
130
  errorMessage: props.errorMessage,
131
+ life: props.life,
130
132
  };
131
133
  }
132
134
 
@@ -134,6 +136,7 @@ export function createValidateEvent<Model extends ILlmSchema.Model>(props: {
134
136
  id: string;
135
137
  operation: AgenticaOperation<Model>;
136
138
  result: IValidation.IFailure;
139
+ life: number;
137
140
  }): AgenticaValidateEvent<Model> {
138
141
  const created_at: string = new Date().toISOString();
139
142
  return {
@@ -142,12 +145,14 @@ export function createValidateEvent<Model extends ILlmSchema.Model>(props: {
142
145
  created_at,
143
146
  operation: props.operation,
144
147
  result: props.result,
148
+ life: props.life,
145
149
  toJSON: () => ({
146
150
  type: "validate",
147
151
  id: props.id,
148
152
  created_at,
149
153
  operation: props.operation.toJSON(),
150
154
  result: props.result,
155
+ life: props.life,
151
156
  }),
152
157
  };
153
158
  }
@@ -119,6 +119,8 @@ export namespace IAgenticaEventJson {
119
119
  * Validation result as a failure.
120
120
  */
121
121
  result: IValidation.IFailure;
122
+
123
+ life: number;
122
124
  }
123
125
 
124
126
  export interface IJsonParseError extends IBase<"jsonParseError"> {
@@ -138,6 +140,8 @@ export namespace IAgenticaEventJson {
138
140
  * Error message of the JSON parse error.
139
141
  */
140
142
  errorMessage: string;
143
+
144
+ life: number;
141
145
  }
142
146
 
143
147
  /**
@@ -35,7 +35,7 @@ export async function call<Model extends ILlmSchema.Model>(
35
35
  ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
36
36
  operations: AgenticaOperation<Model>[],
37
37
  ): Promise<AgenticaExecuteEvent<Model>[]> {
38
- const _retryFn = __get_retry(ctx.config?.retry ?? AgenticaConstant.RETRY);
38
+ const _retryFn = __get_retry(1);
39
39
  const retryFn = async (fn: (prevError?: unknown) => Promise<OpenAI.ChatCompletion>) => {
40
40
  return _retryFn(fn).catch((e) => {
41
41
  if (e instanceof AssistantMessageEmptyError) {
@@ -182,6 +182,7 @@ async function predicate<Model extends ILlmSchema.Model>(
182
182
  = parseArguments(
183
183
  operation,
184
184
  toolCall,
185
+ life,
185
186
  );
186
187
  await ctx.dispatch(call);
187
188
  if (call.type === "jsonParseError") {
@@ -195,6 +196,7 @@ async function predicate<Model extends ILlmSchema.Model>(
195
196
  id: toolCall.id,
196
197
  operation,
197
198
  result: check,
199
+ life,
198
200
  });
199
201
  await ctx.dispatch(event);
200
202
  return correctTypeError(
@@ -292,6 +294,7 @@ async function correctJsonError<Model extends ILlmSchema.Model>(
292
294
  function parseArguments<Model extends ILlmSchema.Model>(
293
295
  operation: AgenticaOperation<Model>,
294
296
  toolCall: OpenAI.ChatCompletionMessageToolCall,
297
+ life: number,
295
298
  ): AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model> {
296
299
  try {
297
300
  const data: Record<string, unknown> = JSON.parse(toolCall.function.arguments);
@@ -307,6 +310,7 @@ function parseArguments<Model extends ILlmSchema.Model>(
307
310
  operation,
308
311
  arguments: toolCall.function.arguments,
309
312
  errorMessage: error instanceof Error ? error.message : String(error),
313
+ life,
310
314
  });
311
315
  }
312
316
  }
@@ -171,7 +171,7 @@ async function step<Model extends ILlmSchema.Model>(
171
171
  // parallel_tool_calls: true,
172
172
  });
173
173
 
174
- const chunks = await StreamUtil.readAll(completionStream);
174
+ const chunks = await StreamUtil.readAll(completionStream, ctx.abortSignal);
175
175
  const completion = ChatGptCompletionMessageUtil.merge(chunks);
176
176
 
177
177
  // ----
@@ -45,7 +45,7 @@ export async function describe<Model extends ILlmSchema.Model>(
45
45
  ...props,
46
46
  });
47
47
  ctx.dispatch(event);
48
- });
48
+ }, ctx.abortSignal);
49
49
  }
50
50
 
51
51
  export const ChatGptDescribeFunctionAgent = {
@@ -66,7 +66,7 @@ export async function initialize<Model extends ILlmSchema.Model>(ctx: AgenticaCo
66
66
  const completion = await reduceStreamingWithDispatch(completionStream, (props) => {
67
67
  const event: AgenticaAssistantMessageEvent = createAssistantMessageEvent(props);
68
68
  ctx.dispatch(event);
69
- });
69
+ }, ctx.abortSignal);
70
70
 
71
71
  if (completion === null) {
72
72
  throw new Error("No completion received");
@@ -95,7 +95,7 @@ async function step<Model extends ILlmSchema.Model>(
95
95
  retry: number,
96
96
  failures?: IFailure[],
97
97
  ): Promise<void> {
98
- const _retryFn = __get_retry(ctx.config?.retry ?? AgenticaConstant.RETRY);
98
+ const _retryFn = __get_retry(1);
99
99
  const retryFn = async (fn: (prevError?: unknown) => Promise<OpenAI.ChatCompletion>) => {
100
100
  return _retryFn(fn).catch((e) => {
101
101
  if (e instanceof AssistantMessageEmptyError) {
@@ -194,7 +194,7 @@ async function step<Model extends ILlmSchema.Model>(
194
194
  const completion = await reduceStreamingWithDispatch(stream, (props) => {
195
195
  const event: AgenticaAssistantMessageEvent = createAssistantMessageEvent(props);
196
196
  void ctx.dispatch(event).catch(() => {});
197
- });
197
+ }, ctx.abortSignal);
198
198
  const allAssistantMessagesEmpty = completion.choices.every(v => v.message.tool_calls == null && v.message.content === "");
199
199
  if (allAssistantMessagesEmpty) {
200
200
  const firstChoice = completion.choices.at(0);
@@ -1,6 +1,13 @@
1
1
  export class AssistantMessageEmptyError extends Error {
2
2
  constructor() {
3
3
  super();
4
+ const proto = new.target.prototype;
5
+ // eslint-disable-next-line
6
+ if (Object.setPrototypeOf) { Object.setPrototypeOf(this, proto); }
7
+ else {
8
+ // eslint-disable-next-line
9
+ (this as any).__proto__ = proto;
10
+ }
4
11
  }
5
12
  }
6
13
 
@@ -10,4 +17,4 @@ export class AssistantMessageEmptyWithReasoningError extends AssistantMessageEmp
10
17
  super();
11
18
  this.reasoning = reasoning;
12
19
  }
13
- }
20
+ }
@@ -7,7 +7,7 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
7
7
  done: () => boolean;
8
8
  get: () => string;
9
9
  join: () => Promise<string>;
10
- }) => void) {
10
+ }) => void, abortSignal?: AbortSignal) {
11
11
  const streamContext = new Map<number, { content: string; mpsc: MPSC<string> }>();
12
12
 
13
13
  const nullableCompletion = await StreamUtil.reduce<ChatCompletionChunk, Promise<ChatCompletion>>(stream, async (accPromise, chunk) => {
@@ -59,7 +59,7 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
59
59
  }
60
60
  registerContext(chunk.choices);
61
61
  return ChatGptCompletionMessageUtil.accumulate(acc, chunk);
62
- });
62
+ }, { abortSignal });
63
63
 
64
64
  if (nullableCompletion == null) {
65
65
  throw new Error(
@@ -149,7 +149,7 @@ describe("streamUtil", () => {
149
149
  const stringResult = await StreamUtil.reduce<number, string>(
150
150
  stringStream,
151
151
  (acc, cur) => acc + cur.toString(),
152
- "",
152
+ { initial: ""},
153
153
  );
154
154
 
155
155
  expect(stringResult).toBe("123");
@@ -160,7 +160,7 @@ describe("streamUtil", () => {
160
160
  const sumResult = await StreamUtil.reduce<number, number>(
161
161
  sumStream,
162
162
  (acc, cur) => acc + cur,
163
- 0,
163
+ { initial: 0 },
164
164
  );
165
165
 
166
166
  expect(sumResult).toBe(15);
@@ -171,6 +171,7 @@ describe("streamUtil", () => {
171
171
  const noInitialResult = await StreamUtil.reduce<number>(
172
172
  noInitialStream,
173
173
  (acc, cur) => acc + cur,
174
+ { initial: 0 },
174
175
  );
175
176
 
176
177
  expect(noInitialResult).toBe(10);
@@ -181,7 +182,7 @@ describe("streamUtil", () => {
181
182
  const emptyResult = await StreamUtil.reduce<number, string>(
182
183
  emptyStream,
183
184
  (acc, cur) => acc + cur.toString(),
184
- "initial value",
185
+ { initial: "initial value" },
185
186
  );
186
187
 
187
188
  expect(emptyResult).toBe("initial value");
@@ -192,6 +193,7 @@ describe("streamUtil", () => {
192
193
  const emptyNoInitialResult = await StreamUtil.reduce<number>(
193
194
  emptyNoInitialStream,
194
195
  (acc, cur) => acc + cur,
196
+ { initial: 0 },
195
197
  );
196
198
 
197
199
  expect(emptyNoInitialResult).toBeNull();
@@ -202,7 +204,7 @@ describe("streamUtil", () => {
202
204
  const stringResult = await StreamUtil.reduce<number, string>(
203
205
  stringStream,
204
206
  (acc, cur) => acc + cur.toString(),
205
- "",
207
+ { initial: "" },
206
208
  );
207
209
 
208
210
  expect(stringResult).toBe("123");
@@ -213,6 +215,7 @@ describe("streamUtil", () => {
213
215
  const noInitialResult = await StreamUtil.reduce<number>(
214
216
  noInitialStream,
215
217
  (acc, cur) => acc + cur,
218
+ { initial: 0 },
216
219
  );
217
220
 
218
221
  expect(noInitialResult).toBe(10);
@@ -229,7 +232,7 @@ describe("streamUtil", () => {
229
232
  }
230
233
  return [...acc, `item${cur}`];
231
234
  },
232
- [],
235
+ { initial: [] },
233
236
  );
234
237
 
235
238
  expect(transformResult).toEqual(["item1", "item2", "item3"]);
@@ -240,7 +243,7 @@ describe("streamUtil", () => {
240
243
  const emptyResult = await StreamUtil.reduce<number, string>(
241
244
  emptyStream,
242
245
  (acc, cur) => acc + cur.toString(),
243
- "initial",
246
+ { initial: "initial" },
244
247
  );
245
248
 
246
249
  expect(emptyResult).toBe("initial");
@@ -256,7 +259,7 @@ describe("streamUtil", () => {
256
259
  const delayResult = await StreamUtil.reduce<number, number>(
257
260
  delayStream,
258
261
  (acc, cur) => acc + cur,
259
- 0,
262
+ { initial: 0 },
260
263
  );
261
264
 
262
265
  expect(delayResult).toBe(6);
@@ -274,7 +277,7 @@ describe("streamUtil", () => {
274
277
  }
275
278
  return acc + cur;
276
279
  },
277
- 0,
280
+ { initial: 0 },
278
281
  ),
279
282
  ).rejects.toThrow("Test error");
280
283
  });
@@ -285,7 +288,7 @@ describe("streamUtil", () => {
285
288
  const result = await StreamUtil.reduce<number | null | undefined, number>(
286
289
  stream,
287
290
  (acc, cur) => (acc ?? 0) + (cur ?? 0),
288
- 0,
291
+ { initial: 0 },
289
292
  );
290
293
 
291
294
  expect(result).toBe(9); // 1 + 0 + 3 + 0 + 5 = 9
@@ -4,12 +4,12 @@
4
4
  * Utility functions for streams.
5
5
  */
6
6
 
7
- async function readAll<T>(stream: ReadableStream<T>): Promise<T[]> {
7
+ async function readAll<T>(stream: ReadableStream<T>, abortSignal?: AbortSignal): Promise<T[]> {
8
8
  const reader = stream.getReader();
9
9
  const result: T[] = [];
10
10
  while (true) {
11
11
  const { done, value } = await reader.read();
12
- if (done) {
12
+ if (done || abortSignal?.aborted === true) {
13
13
  break;
14
14
  }
15
15
  result.push(value);
@@ -17,12 +17,16 @@ async function readAll<T>(stream: ReadableStream<T>): Promise<T[]> {
17
17
  return result;
18
18
  }
19
19
 
20
- async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, initial?: R): Promise<R | null> {
20
+ async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, options: { initial?: R, abortSignal?: AbortSignal }): Promise<R | null> {
21
21
  const reader = stream.getReader();
22
22
  const iterator = streamDefaultReaderToAsyncGenerator(reader);
23
- let acc = (initial ?? null) as R | null | T;
23
+ let acc = (options.initial ?? null) as R | null | T;
24
24
 
25
25
  for await (const value of iterator) {
26
+ if (options.abortSignal?.aborted === true) {
27
+ break;
28
+ }
29
+
26
30
  if (acc === null) {
27
31
  acc = value;
28
32
  continue;
@@ -49,28 +53,28 @@ export async function* toAsyncGenerator<T>(value: T): AsyncGenerator<T, undefine
49
53
  yield value;
50
54
  }
51
55
 
52
- export async function* streamDefaultReaderToAsyncGenerator<T>(reader: ReadableStreamDefaultReader<T>): AsyncGenerator<Awaited<T>, undefined, undefined> {
56
+ export async function* streamDefaultReaderToAsyncGenerator<T>(reader: ReadableStreamDefaultReader<T>, abortSignal?: AbortSignal): AsyncGenerator<Awaited<T>, undefined, undefined> {
53
57
  while (true) {
54
58
  const { done, value } = await reader.read();
55
- if (done) {
59
+ if (done || abortSignal?.aborted === true) {
56
60
  break;
57
61
  }
58
62
  yield value;
59
63
  }
60
64
  }
61
65
 
62
- function transform<T, R>(stream: ReadableStream<T>, transformer: (value: T) => R): ReadableStream<R> {
66
+ function transform<T, R>(stream: ReadableStream<T>, transformer: (value: T) => R, abortSignal?: AbortSignal): ReadableStream<R> {
63
67
  const reader = stream.getReader();
64
68
 
65
69
  return new ReadableStream<R>({
66
70
  pull: async (controller) => {
67
71
  const { done, value } = await reader.read();
68
- if (!done) {
69
- controller.enqueue(transformer(value));
70
- }
71
- else {
72
+ if (done === true || abortSignal?.aborted === true) {
72
73
  controller.close();
74
+ return;
73
75
  }
76
+
77
+ controller.enqueue(transformer(value));
74
78
  },
75
79
  });
76
80
  }
@@ -61,6 +61,7 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
61
61
  completion.toReadableStream() as ReadableStream<Uint8Array>,
62
62
  value =>
63
63
  ChatGptCompletionMessageUtil.transformCompletionChunk(value),
64
+ props.abortSignal,
64
65
  ).tee();
65
66
 
66
67
  const [streamForAggregate, streamForReturn] = temporaryStream.tee();
@@ -69,7 +70,7 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
69
70
  const reader = streamForAggregate.getReader();
70
71
  while (true) {
71
72
  const chunk = await reader.read();
72
- if (chunk.done) {
73
+ if (chunk.done || props.abortSignal?.aborted === true) {
73
74
  break;
74
75
  }
75
76
  if (chunk.value.usage != null) {
@@ -87,11 +88,11 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
87
88
  id: v4(),
88
89
  type: "response",
89
90
  source,
90
- stream: streamDefaultReaderToAsyncGenerator(streamForStream.getReader()),
91
+ stream: streamDefaultReaderToAsyncGenerator(streamForStream.getReader(), props.abortSignal),
91
92
  body: event.body,
92
93
  options: event.options,
93
94
  join: async () => {
94
- const chunks = await StreamUtil.readAll(streamForJoin);
95
+ const chunks = await StreamUtil.readAll(streamForJoin, props.abortSignal);
95
96
  return ChatGptCompletionMessageUtil.merge(chunks);
96
97
  },
97
98
  created_at: new Date().toISOString(),