@agentica/core 0.29.5 → 0.30.0

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/constants/AgenticaSystemPrompt.d.ts +1 -0
  2. package/lib/constants/AgenticaSystemPrompt.js +2 -1
  3. package/lib/constants/AgenticaSystemPrompt.js.map +1 -1
  4. package/lib/events/AgenticaEvent.d.ts +3 -1
  5. package/lib/events/AgenticaJsonParseErrorEvent.d.ts +8 -0
  6. package/lib/events/AgenticaJsonParseErrorEvent.js +3 -0
  7. package/lib/events/AgenticaJsonParseErrorEvent.js.map +1 -0
  8. package/lib/events/MicroAgenticaEvent.d.ts +3 -1
  9. package/lib/events/index.d.ts +1 -0
  10. package/lib/events/index.js +1 -0
  11. package/lib/events/index.js.map +1 -1
  12. package/lib/factory/events.d.ts +8 -1
  13. package/lib/factory/events.js +14 -2
  14. package/lib/factory/events.js.map +1 -1
  15. package/lib/functional/assertHttpController.js +14 -14
  16. package/lib/functional/assertHttpLlmApplication.js +14 -14
  17. package/lib/functional/validateHttpController.js +14 -14
  18. package/lib/functional/validateHttpLlmApplication.js +14 -14
  19. package/lib/index.mjs +764 -1722
  20. package/lib/index.mjs.map +1 -1
  21. package/lib/json/IAgenticaEventJson.d.ts +18 -5
  22. package/lib/orchestrate/call.d.ts +1 -1
  23. package/lib/orchestrate/call.js +199 -285
  24. package/lib/orchestrate/call.js.map +1 -1
  25. package/lib/orchestrate/cancel.js +23 -20
  26. package/lib/orchestrate/cancel.js.map +1 -1
  27. package/lib/orchestrate/initialize.js +565 -1560
  28. package/lib/orchestrate/initialize.js.map +1 -1
  29. package/lib/orchestrate/select.js +24 -21
  30. package/lib/orchestrate/select.js.map +1 -1
  31. package/lib/structures/IAgenticaSystemPrompt.d.ts +31 -0
  32. package/lib/structures/IMicroAgenticaSystemPrompt.d.ts +31 -0
  33. package/package.json +5 -5
  34. package/prompts/json_parse_error.md +32 -0
  35. package/prompts/validate.md +61 -13
  36. package/src/constants/AgenticaSystemPrompt.ts +3 -1
  37. package/src/events/AgenticaEvent.ts +3 -0
  38. package/src/events/AgenticaJsonParseErrorEvent.ts +12 -0
  39. package/src/events/MicroAgenticaEvent.ts +4 -1
  40. package/src/events/index.ts +1 -0
  41. package/src/factory/events.ts +19 -1
  42. package/src/json/IAgenticaEventJson.ts +20 -4
  43. package/src/orchestrate/call.ts +273 -389
  44. package/src/orchestrate/initialize.ts +2 -2
  45. package/src/orchestrate/select.ts +2 -2
  46. package/src/structures/IAgenticaSystemPrompt.ts +32 -0
  47. package/src/structures/IMicroAgenticaSystemPrompt.ts +32 -0
@@ -1,30 +1,28 @@
1
1
  import type {
2
2
  IChatGptSchema,
3
- IHttpMigrateRoute,
4
3
  IHttpResponse,
5
4
  ILlmSchema,
5
+ IValidation,
6
6
  } from "@samchon/openapi";
7
7
  import type OpenAI from "openai";
8
- import type { IValidation } from "typia";
9
8
 
10
- import {
11
- ChatGptTypeChecker,
12
- HttpLlm,
13
- LlmTypeCheckerV3_1,
14
- } from "@samchon/openapi";
9
+ import { HttpLlm } from "@samchon/openapi";
10
+ import { v4 } from "uuid";
15
11
 
16
12
  import type { AgenticaContext } from "../context/AgenticaContext";
17
13
  import type { AgenticaOperation } from "../context/AgenticaOperation";
18
14
  import type { MicroAgenticaContext } from "../context/MicroAgenticaContext";
19
- import type { AgenticaAssistantMessageEvent, AgenticaExecuteEvent, AgenticaValidateEvent } from "../events";
15
+ import type { AgenticaAssistantMessageEvent, AgenticaValidateEvent } from "../events";
20
16
  import type { AgenticaCallEvent } from "../events/AgenticaCallEvent";
17
+ import type { AgenticaExecuteEvent } from "../events/AgenticaExecuteEvent";
18
+ import type { AgenticaJsonParseErrorEvent } from "../events/AgenticaJsonParseErrorEvent";
21
19
  import type { MicroAgenticaHistory } from "../histories/MicroAgenticaHistory";
22
20
 
23
21
  import { AgenticaConstant } from "../constants/AgenticaConstant";
24
22
  import { AgenticaDefaultPrompt } from "../constants/AgenticaDefaultPrompt";
25
23
  import { AgenticaSystemPrompt } from "../constants/AgenticaSystemPrompt";
26
24
  import { isAgenticaContext } from "../context/internal/isAgenticaContext";
27
- import { creatAssistantMessageEvent, createCallEvent, createExecuteEvent, createValidateEvent } from "../factory/events";
25
+ import { createAssistantMessageEvent, createCallEvent, createExecuteEvent, createJsonParseErrorEvent, createValidateEvent } from "../factory/events";
28
26
  import { decodeHistory, decodeUserMessageContent } from "../factory/histories";
29
27
  import { ChatGptCompletionMessageUtil } from "../utils/ChatGptCompletionMessageUtil";
30
28
  import { StreamUtil, toAsyncGenerator } from "../utils/StreamUtil";
@@ -35,18 +33,7 @@ export async function call<Model extends ILlmSchema.Model>(
35
33
  ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
36
34
  operations: AgenticaOperation<Model>[],
37
35
  ): Promise<AgenticaExecuteEvent<Model>[]> {
38
- return station(ctx, operations, []);
39
- }
40
-
41
- async function station<Model extends ILlmSchema.Model>(
42
- ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
43
- operations: AgenticaOperation<Model>[],
44
- validateEvents: AgenticaValidateEvent<Model>[],
45
- ): Promise<AgenticaExecuteEvent<Model>[]> {
46
- // ----
47
- // EXECUTE CHATGPT API
48
- // ----
49
- const completionStream = await ctx.request("call", {
36
+ const stream: ReadableStream<OpenAI.ChatCompletionChunk> = await ctx.request("call", {
50
37
  messages: [
51
38
  // COMMON SYSTEM PROMPT
52
39
  {
@@ -99,48 +86,31 @@ async function station<Model extends ILlmSchema.Model>(
99
86
  tool_choice: "auto",
100
87
  // parallel_tool_calls: false,
101
88
  });
102
-
103
- // ----
104
- // PROCESS COMPLETION
105
- // ----
106
- const chunks = await StreamUtil.readAll(completionStream);
107
- const completion = ChatGptCompletionMessageUtil.merge(chunks);
89
+ const chunks: OpenAI.ChatCompletionChunk[] = await StreamUtil.readAll(stream);
90
+ const completion: OpenAI.ChatCompletion = ChatGptCompletionMessageUtil.merge(chunks);
108
91
  const executes: AgenticaExecuteEvent<Model>[] = [];
109
92
 
110
93
  for (const choice of completion.choices) {
111
94
  for (const tc of choice.message.tool_calls ?? []) {
112
95
  if (tc.type === "function") {
113
- const operation: AgenticaOperation<Model> | undefined
114
- = ctx.operations.flat.get(tc.function.name);
96
+ const operation: AgenticaOperation<Model> | undefined = operations.find(
97
+ s => s.name === tc.function.name,
98
+ );
115
99
  if (operation === undefined) {
116
- continue;
117
- }
118
- const call: AgenticaCallEvent<Model> = createCallEvent({
119
- id: tc.id,
120
- operation,
121
- // @TODO add type assertion!
122
- arguments: JSON.parse(tc.function.arguments) as Record<string, unknown>,
123
- });
124
- if (call.operation.protocol === "http") {
125
- fillHttpArguments({
126
- operation: call.operation,
127
- arguments: call.arguments,
128
- });
100
+ continue; // Ignore unknown tool calls
129
101
  }
130
- ctx.dispatch(call);
131
-
132
- const exec: AgenticaExecuteEvent<Model> = await propagate(
102
+ const event: AgenticaExecuteEvent<Model> = await predicate(
133
103
  ctx,
134
- call,
135
- 0,
136
- validateEvents,
104
+ operation,
105
+ tc,
106
+ [],
107
+ ctx.config?.retry ?? AgenticaConstant.RETRY,
137
108
  );
138
- ctx.dispatch(exec);
139
- executes.push(exec);
140
-
109
+ ctx.dispatch(event);
110
+ executes.push(event);
141
111
  if (isAgenticaContext(ctx)) {
142
112
  cancelFunctionFromContext(ctx, {
143
- name: call.operation.name,
113
+ name: event.operation.name,
144
114
  reason: "completed",
145
115
  });
146
116
  }
@@ -152,7 +122,7 @@ async function station<Model extends ILlmSchema.Model>(
152
122
  && choice.message.content.length !== 0
153
123
  ) {
154
124
  const text: string = choice.message.content;
155
- const event: AgenticaAssistantMessageEvent = creatAssistantMessageEvent({
125
+ const event: AgenticaAssistantMessageEvent = createAssistantMessageEvent({
156
126
  get: () => text,
157
127
  done: () => true,
158
128
  stream: toAsyncGenerator(text),
@@ -161,278 +131,166 @@ async function station<Model extends ILlmSchema.Model>(
161
131
  ctx.dispatch(event);
162
132
  }
163
133
  }
134
+ console.error("call", executes);
164
135
  return executes;
165
136
  }
166
137
 
167
- async function propagate<Model extends ILlmSchema.Model>(
138
+ async function predicate<Model extends ILlmSchema.Model>(
168
139
  ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
169
- call: AgenticaCallEvent<Model>,
170
- retry: number,
171
- validateEvents: AgenticaValidateEvent<Model>[],
140
+ operation: AgenticaOperation<Model>,
141
+ toolCall: OpenAI.ChatCompletionMessageToolCall,
142
+ previousValidationErrors: AgenticaValidateEvent<Model>[],
143
+ life: number,
172
144
  ): Promise<AgenticaExecuteEvent<Model>> {
173
- switch (call.operation.protocol) {
174
- case "http": {
175
- return propagateHttp({
176
- ctx,
177
- operation: call.operation,
178
- call,
179
- retry,
180
- validateEvents,
181
- });
182
- }
183
- case "class": {
184
- return propagateClass({ ctx, operation: call.operation, call, retry, validateEvents });
185
- }
186
- case "mcp": {
187
- return propagateMcp({ ctx, operation: call.operation, call, retry, validateEvents });
188
- }
189
- default: {
190
- call.operation satisfies never;
191
- throw new Error("Unsupported protocol");
192
- }
145
+ // CHECK INPUT ARGUMENT
146
+ const call: AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model>
147
+ = parseArguments(
148
+ operation,
149
+ toolCall,
150
+ );
151
+ ctx.dispatch(call);
152
+ if (call.type === "jsonParseError") {
153
+ return correctJsonError(ctx, call, previousValidationErrors, life - 1);
193
154
  }
194
- }
195
155
 
196
- async function propagateHttp<Model extends ILlmSchema.Model>(
197
- props: {
198
- ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>;
199
- operation: AgenticaOperation.Http<Model>;
200
- call: AgenticaCallEvent<Model>;
201
- validateEvents: AgenticaValidateEvent<Model>[];
202
- retry: number;
203
- },
204
- ): Promise<AgenticaExecuteEvent<Model>> {
205
- // ----
206
- // HTTP PROTOCOL
207
- // ----
208
- // NESTED VALIDATOR
209
- const check: IValidation<unknown> = props.operation.function.validate(
210
- props.call.arguments,
211
- );
156
+ // CHECK TYPE VALIDATION
157
+ const check: IValidation<unknown> = operation.function.validate(call.arguments);
212
158
  if (check.success === false) {
213
- const ve: AgenticaValidateEvent<Model> = createValidateEvent({
214
- id: props.call.id,
215
- operation: props.call.operation,
159
+ const event: AgenticaValidateEvent<Model> = createValidateEvent({
160
+ id: toolCall.id,
161
+ operation,
216
162
  result: check,
217
163
  });
218
- props.ctx.dispatch(ve);
219
- props.validateEvents.push(ve);
220
-
221
- if (props.retry++ < (props.ctx.config?.retry ?? AgenticaConstant.RETRY)) {
222
- const trial: AgenticaExecuteEvent<Model> | null = await correct(
223
- props.ctx,
224
- props.call,
225
- props.retry,
226
- check.errors,
227
- props.validateEvents,
228
- );
229
- if (trial !== null) {
230
- return trial;
231
- }
232
- }
233
- }
234
-
235
- try {
236
- // CALL HTTP API
237
- const response: IHttpResponse = await executeHttpOperation(props.operation, props.call.arguments);
238
- // CHECK STATUS
239
- const success: boolean
240
- = ((response.status === 400
241
- || response.status === 404
242
- || response.status === 422)
243
- && props.retry++ < (props.ctx.config?.retry ?? AgenticaConstant.RETRY)
244
- && typeof response.body) === false;
245
- // DISPATCH EVENT
246
- return (
247
- (success === false
248
- ? await correct(
249
- props.ctx,
250
- props.call,
251
- props.retry,
252
- response.body,
253
- props.validateEvents,
254
- )
255
- : null)
256
- ?? createExecuteEvent({
257
- operation: props.call.operation,
258
- arguments: props.call.arguments,
259
- value: response,
260
- })
164
+ ctx.dispatch(event);
165
+ return correctTypeError(
166
+ ctx,
167
+ call,
168
+ event,
169
+ [...previousValidationErrors, event],
170
+ life - 1,
261
171
  );
262
172
  }
263
- catch (error) {
264
- // DISPATCH ERROR
265
- return createExecuteEvent({
266
- operation: props.call.operation,
267
- arguments: props.call.arguments,
173
+
174
+ // EXECUTE OPERATION
175
+ const execute: AgenticaExecuteEvent<Model> = await executeFunction(call, operation);
176
+ ctx.dispatch(execute);
177
+ return execute;
178
+ }
179
+
180
+ /* -----------------------------------------------------------
181
+ ERROR CORRECTORS
182
+ ----------------------------------------------------------- */
183
+ async function correctTypeError<Model extends ILlmSchema.Model>(
184
+ ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
185
+ callEvent: AgenticaCallEvent<Model>,
186
+ validateEvent: AgenticaValidateEvent<Model>,
187
+ previousValidationErrors: AgenticaValidateEvent<Model>[],
188
+ life: number,
189
+ ): Promise<AgenticaExecuteEvent<Model>> {
190
+ return correctError<Model>(ctx, {
191
+ giveUp: () => createExecuteEvent({
192
+ operation: callEvent.operation,
193
+ arguments: callEvent.arguments,
268
194
  value: {
269
- status: 500,
270
- headers: {},
271
- body:
272
- error instanceof Error
273
- ? {
274
- ...error,
275
- name: error.name,
276
- message: error.message,
277
- }
278
- : error,
195
+ name: "ValidationError",
196
+ message: `Invalid arguments. The validation failed after ${AgenticaConstant.RETRY} retries.`,
197
+ errors: validateEvent.result.errors,
279
198
  },
280
- });
281
- }
199
+ }),
200
+ operation: callEvent.operation,
201
+ messageArguments: JSON.stringify(callEvent.arguments),
202
+ messageToolParam: {
203
+ role: "tool",
204
+ content: JSON.stringify(validateEvent.result.errors),
205
+ tool_call_id: callEvent.id,
206
+ } satisfies OpenAI.ChatCompletionToolMessageParam,
207
+ systemPrompt: ctx.config?.systemPrompt?.validate?.(previousValidationErrors.slice(0, -1))
208
+ ?? [
209
+ AgenticaSystemPrompt.VALIDATE,
210
+ ...(previousValidationErrors.length > 1
211
+ ? [
212
+ "",
213
+ AgenticaSystemPrompt.VALIDATE_REPEATED.replace(
214
+ "${{HISTORICAL_ERRORS}}",
215
+ JSON.stringify(previousValidationErrors.slice(0, -1).map(e => e.result.errors)),
216
+ ),
217
+ ]
218
+ : []),
219
+ ].join("\n"),
220
+ life,
221
+ previousValidationErrors,
222
+ });
282
223
  }
283
224
 
284
- async function propagateClass<Model extends ILlmSchema.Model>(props: {
285
- ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>;
286
- operation: AgenticaOperation.Class<Model>;
287
- call: AgenticaCallEvent<Model>;
288
- validateEvents: AgenticaValidateEvent<Model>[];
289
- retry: number;
290
- }): Promise<AgenticaExecuteEvent<Model>> {
291
- // ----
292
- // CLASS FUNCTION
293
- // ----
294
- // VALIDATE FIRST
295
- const check: IValidation<unknown> = props.operation.function.validate(
296
- props.call.arguments,
297
- );
298
- if (check.success === false) {
299
- const ve: AgenticaValidateEvent<Model> = createValidateEvent({
300
- id: props.call.id,
301
- operation: props.call.operation,
302
- result: check,
303
- });
304
- props.ctx.dispatch(ve);
305
- props.validateEvents.push(ve);
306
- return (
307
- (props.retry++ < (props.ctx.config?.retry ?? AgenticaConstant.RETRY)
308
- ? await correct(props.ctx, props.call, props.retry, check.errors, props.validateEvents)
309
- : null)
310
- ?? createExecuteEvent({
311
- operation: props.call.operation,
312
- arguments: props.call.arguments,
313
- value: {
314
- name: "TypeGuardError",
315
- message: "Invalid arguments.",
316
- errors: check.errors,
317
- },
318
- })
319
- );
320
- }
321
- // EXECUTE FUNCTION
322
- try {
323
- const value = await executeClassOperation(props.operation, props.call.arguments);
324
- return createExecuteEvent({
325
- operation: props.call.operation,
326
- arguments: props.call.arguments,
327
- value,
328
- });
329
- }
330
- catch (error) {
331
- return createExecuteEvent({
332
- operation: props.call.operation,
333
- arguments: props.call.arguments,
334
- value:
335
- error instanceof Error
336
- ? {
337
- ...error,
338
- name: error.name,
339
- message: error.message,
340
- }
341
- : error,
342
- });
343
- }
225
+ async function correctJsonError<Model extends ILlmSchema.Model>(
226
+ ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
227
+ parseErrorEvent: AgenticaJsonParseErrorEvent<Model>,
228
+ previousValidationErrors: AgenticaValidateEvent<Model>[],
229
+ life: number,
230
+ ): Promise<AgenticaExecuteEvent<Model>> {
231
+ return correctError<Model>(ctx, {
232
+ giveUp: () => createExecuteEvent({
233
+ operation: parseErrorEvent.operation,
234
+ arguments: {},
235
+ value: {
236
+ name: "JsonParseError",
237
+ message: `Invalid JSON format. The parsing failed after ${AgenticaConstant.RETRY} retries.`,
238
+ arguments: parseErrorEvent.arguments,
239
+ errorMessage: parseErrorEvent.errorMessage,
240
+ },
241
+ }),
242
+ operation: parseErrorEvent.operation,
243
+ messageArguments: parseErrorEvent.arguments,
244
+ messageToolParam: null,
245
+ systemPrompt: ctx.config?.systemPrompt?.jsonParseError?.(parseErrorEvent)
246
+ ?? AgenticaSystemPrompt.JSON_PARSE_ERROR.replace(
247
+ "${{ERROR_MESSAGE}}",
248
+ parseErrorEvent.errorMessage,
249
+ ),
250
+ life,
251
+ previousValidationErrors,
252
+ });
344
253
  }
345
254
 
346
- async function propagateMcp<Model extends ILlmSchema.Model>(props: {
347
- ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>;
348
- operation: AgenticaOperation.Mcp<Model>;
349
- call: AgenticaCallEvent<Model>;
350
- validateEvents: AgenticaValidateEvent<Model>[];
351
- retry: number;
352
- }): Promise<AgenticaExecuteEvent<Model>> {
353
- // ----
354
- // MCP PROTOCOL
355
- // ----
356
- // @TODO: implement argument validation logic
255
+ function parseArguments<Model extends ILlmSchema.Model>(
256
+ operation: AgenticaOperation<Model>,
257
+ toolCall: OpenAI.ChatCompletionMessageToolCall,
258
+ ): AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model> {
357
259
  try {
358
- const value = await executeMcpOperation(props.operation, props.call.arguments);
359
- return createExecuteEvent({
360
- operation: props.call.operation,
361
- arguments: props.call.arguments,
362
- value,
260
+ const data: Record<string, unknown> = JSON.parse(toolCall.function.arguments);
261
+ return createCallEvent({
262
+ id: toolCall.id,
263
+ operation,
264
+ arguments: data,
363
265
  });
364
266
  }
365
267
  catch (error) {
366
- return createExecuteEvent({
367
- operation: props.call.operation,
368
- arguments: props.call.arguments,
369
- value:
370
- error instanceof Error
371
- ? {
372
- ...error,
373
- name: error.name,
374
- message: error.message,
375
- }
376
- : error,
268
+ return createJsonParseErrorEvent({
269
+ id: toolCall.id,
270
+ operation,
271
+ arguments: toolCall.function.arguments,
272
+ errorMessage: error instanceof Error ? error.message : String(error),
377
273
  });
378
274
  }
379
275
  }
380
276
 
381
- async function executeHttpOperation<Model extends ILlmSchema.Model>(operation: AgenticaOperation.Http<Model>, operationArguments: Record<string, unknown>): Promise<IHttpResponse> {
382
- const controllerBaseArguments = {
383
- connection: operation.controller.connection,
384
- application: operation.controller.application,
385
- function: operation.function,
386
- };
387
- return operation.controller.execute !== undefined
388
- ? operation.controller.execute({ ...controllerBaseArguments, arguments: operationArguments })
389
- : HttpLlm.propagate({ ...controllerBaseArguments, input: operationArguments });
390
- }
391
-
392
- /**
393
- * @throws {TypeError}
394
- */
395
- async function executeClassOperation<Model extends ILlmSchema.Model>(operation: AgenticaOperation.Class<Model>, operationArguments: Record<string, unknown>): Promise<unknown> {
396
- const execute = operation.controller.execute;
397
- if (typeof execute === "function") {
398
- return await execute({
399
- application: operation.controller.application,
400
- function: operation.function,
401
- arguments: operationArguments,
402
- });
277
+ async function correctError<Model extends ILlmSchema.Model>(
278
+ ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
279
+ props: {
280
+ giveUp: () => AgenticaExecuteEvent<Model>;
281
+ operation: AgenticaOperation<Model>;
282
+ messageArguments: string;
283
+ messageToolParam: null | OpenAI.ChatCompletionToolMessageParam;
284
+ systemPrompt: string;
285
+ life: number;
286
+ previousValidationErrors: AgenticaValidateEvent<Model>[];
287
+ },
288
+ ): Promise<AgenticaExecuteEvent<Model>> {
289
+ if (props.life <= 0) {
290
+ return props.giveUp();
403
291
  }
404
292
 
405
- // As you know, it's very unstable logic.
406
- // But this is an intended error.
407
- // There are two types of errors that can occur here.
408
- // One is a TypeError caused by referencing an undefined value, and the other is a TypeError caused by calling something that isn't a function.
409
- // These errors are intentional, and any call to this function must be wrapped in a try-catch block.
410
- // Unless there is an overall structural improvement, this function will remain as-is.
411
- return ((execute as Record<string, unknown>)[operation.function.name] as (...args: unknown[]) => Promise<unknown>)(operationArguments);
412
- }
413
-
414
- async function executeMcpOperation<Model extends ILlmSchema.Model>(
415
- operation: AgenticaOperation.Mcp<Model>,
416
- operationArguments: Record<string, unknown>,
417
- ): Promise<unknown> {
418
- return operation.controller.client.callTool({
419
- method: operation.function.name,
420
- name: operation.function.name,
421
- arguments: operationArguments,
422
- }).then(v => v.content);
423
- }
424
-
425
- async function correct<Model extends ILlmSchema.Model>(
426
- ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
427
- call: AgenticaCallEvent<Model>,
428
- retry: number,
429
- error: unknown,
430
- validateEvents: AgenticaValidateEvent<Model>[],
431
- ): Promise<AgenticaExecuteEvent<Model> | null> {
432
- // ----
433
- // EXECUTE CHATGPT API
434
- // ----
435
- const completionStream = await ctx.request("call", {
293
+ const stream: ReadableStream<OpenAI.ChatCompletionChunk> = await ctx.request("call", {
436
294
  messages: [
437
295
  // COMMON SYSTEM PROMPT
438
296
  {
@@ -447,48 +305,31 @@ async function correct<Model extends ILlmSchema.Model>(
447
305
  content: ctx.prompt.contents.map(decodeUserMessageContent),
448
306
  },
449
307
  // TYPE CORRECTION
450
- ...(ctx.config?.systemPrompt?.execute === null
451
- ? []
452
- : [{
453
- role: "system",
454
- content:
455
- ctx.config?.systemPrompt?.execute?.(ctx.histories as MicroAgenticaHistory<Model>[])
456
- ?? AgenticaSystemPrompt.EXECUTE,
457
- } satisfies OpenAI.ChatCompletionSystemMessageParam]
458
- ),
308
+ {
309
+ role: "system",
310
+ content:
311
+ ctx.config?.systemPrompt?.execute?.(ctx.histories as MicroAgenticaHistory<Model>[])
312
+ ?? AgenticaSystemPrompt.EXECUTE,
313
+ },
459
314
  {
460
315
  role: "assistant",
461
316
  tool_calls: [
462
317
  {
463
318
  type: "function",
464
- id: call.id,
319
+ id: v4(),
465
320
  function: {
466
- name: call.operation.name,
467
- arguments: JSON.stringify(call.arguments),
321
+ name: props.operation.name,
322
+ arguments: props.messageArguments,
468
323
  },
469
324
  } satisfies OpenAI.ChatCompletionMessageToolCall,
470
325
  ],
471
326
  } satisfies OpenAI.ChatCompletionAssistantMessageParam,
472
- {
473
- role: "tool",
474
- content: typeof error === "string" ? error : JSON.stringify(error),
475
- tool_call_id: call.id,
476
- } satisfies OpenAI.ChatCompletionToolMessageParam,
327
+ ...(props.messageToolParam !== null
328
+ ? [props.messageToolParam]
329
+ : []),
477
330
  {
478
331
  role: "system",
479
- content: ctx.config?.systemPrompt?.validate?.(validateEvents.slice(0, -1))
480
- ?? [
481
- AgenticaSystemPrompt.VALIDATE,
482
- ...(validateEvents.length > 1
483
- ? [
484
- "",
485
- AgenticaSystemPrompt.VALIDATE_REPEATED.replace(
486
- "${{HISTORICAL_ERRORS}}",
487
- JSON.stringify(validateEvents.slice(0, -1).map(e => e.result.errors)),
488
- ),
489
- ]
490
- : []),
491
- ].join("\n"),
332
+ content: props.systemPrompt,
492
333
  },
493
334
  ],
494
335
  // STACK FUNCTIONS
@@ -496,16 +337,16 @@ async function correct<Model extends ILlmSchema.Model>(
496
337
  {
497
338
  type: "function",
498
339
  function: {
499
- name: call.operation.name,
500
- description: call.operation.function.description,
340
+ name: props.operation.name,
341
+ description: props.operation.function.description,
501
342
  /**
502
343
  * @TODO fix it
503
344
  * The property and value have a type mismatch, but it works.
504
345
  */
505
346
  parameters: (
506
- ("separated" in call.operation.function
507
- && call.operation.function.separated !== undefined)
508
- ? (call.operation.function.separated?.llm
347
+ ("separated" in props.operation.function
348
+ && props.operation.function.separated !== undefined)
349
+ ? (props.operation.function.separated?.llm
509
350
  ?? ({
510
351
  $defs: {},
511
352
  type: "object",
@@ -514,79 +355,122 @@ async function correct<Model extends ILlmSchema.Model>(
514
355
  required: [],
515
356
  } satisfies IChatGptSchema.IParameters))
516
357
 
517
- : call.operation.function.parameters) as unknown as Record<string, unknown>,
358
+ : props.operation.function.parameters) as unknown as Record<string, unknown>,
518
359
  },
519
360
  },
520
361
  ],
521
362
  tool_choice: {
522
363
  type: "function",
523
364
  function: {
524
- name: call.operation.name,
365
+ name: props.operation.name,
525
366
  },
526
367
  },
527
368
  // parallel_tool_calls: false,
528
369
  });
370
+ const chunks: OpenAI.ChatCompletionChunk[] = await StreamUtil.readAll(stream);
371
+ const completion: OpenAI.ChatCompletion = ChatGptCompletionMessageUtil.merge(chunks);
529
372
 
530
- const chunks = await StreamUtil.readAll(completionStream);
531
- const completion = ChatGptCompletionMessageUtil.merge(chunks);
532
-
533
- // ----
534
- // PROCESS COMPLETION
535
- // ----
536
- const toolCall: OpenAI.ChatCompletionMessageToolCall | undefined = (
537
- completion.choices[0]?.message.tool_calls ?? []
538
- ).find(
539
- tc =>
540
- tc.type === "function" && tc.function.name === call.operation.name,
541
- );
542
- if (toolCall === undefined) {
543
- return null;
544
- }
545
- return propagate(
546
- ctx,
547
- createCallEvent({
548
- id: toolCall.id,
549
- operation: call.operation,
550
- arguments: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,
551
- }),
552
- retry,
553
- validateEvents,
373
+ const toolCall: OpenAI.ChatCompletionMessageToolCall | undefined = completion.choices[0]?.message.tool_calls?.find(
374
+ s => s.function.name === props.operation.name,
554
375
  );
376
+ return toolCall === undefined
377
+ ? props.giveUp()
378
+ : predicate<Model>(
379
+ ctx,
380
+ props.operation,
381
+ toolCall,
382
+ props.previousValidationErrors,
383
+ props.life,
384
+ );
555
385
  }
556
386
 
557
- function fillHttpArguments<Model extends ILlmSchema.Model>(props: {
558
- operation: AgenticaOperation<Model>;
559
- arguments: Record<string, unknown>;
560
- }): void {
561
- if (props.operation.protocol !== "http") {
562
- return;
387
+ /* -----------------------------------------------------------
388
+ FUNCTION EXECUTORS
389
+ ----------------------------------------------------------- */
390
+ async function executeFunction<Model extends ILlmSchema.Model>(
391
+ call: AgenticaCallEvent<Model>,
392
+ operation: AgenticaOperation<Model>,
393
+ ): Promise<AgenticaExecuteEvent<Model>> {
394
+ try {
395
+ const value: unknown = await (async () => {
396
+ switch (operation.protocol) {
397
+ case "class":
398
+ return executeClassFunction(call, operation);
399
+ case "http":
400
+ return executeHttpOperation(call, operation);
401
+ case "mcp":
402
+ return executeMcpOperation(call, operation);
403
+ default:
404
+ operation satisfies never; // Ensure all cases are handled
405
+ throw new Error("Unknown protocol"); // never be happen
406
+ }
407
+ })();
408
+ return createExecuteEvent({
409
+ operation: call.operation,
410
+ arguments: call.arguments,
411
+ value,
412
+ });
563
413
  }
564
- const route: IHttpMigrateRoute = props.operation.function.route();
565
- if (
566
- route.body !== null
567
- && route.operation().requestBody?.required === true
568
- && "body" in props.arguments
569
- && isObject(
570
- (props.operation.function.parameters as IChatGptSchema.IParameters)
571
- .$defs,
572
- (props.operation.function.parameters as IChatGptSchema.IParameters)
573
- .properties
574
- .body!,
575
- )
576
- ) { props.arguments.body = {}; }
577
- if (route.query !== null && "query" in props.arguments && props.arguments.query === undefined) {
578
- props.arguments.query = {};
414
+ catch (error) {
415
+ return createExecuteEvent({
416
+ operation: call.operation,
417
+ arguments: call.arguments,
418
+ value: error instanceof Error
419
+ ? {
420
+ ...error,
421
+ name: error.name,
422
+ message: error.message,
423
+ }
424
+ : error,
425
+ });
579
426
  }
580
427
  }
581
428
 
582
- function isObject($defs: Record<string, IChatGptSchema>, schema: IChatGptSchema): boolean {
583
- return (
584
- ChatGptTypeChecker.isObject(schema)
585
- || (ChatGptTypeChecker.isReference(schema)
586
- && isObject($defs, $defs[schema.$ref.split("/").at(-1)!]!))
587
- || (ChatGptTypeChecker.isAnyOf(schema)
588
- && schema.anyOf.every(schema => isObject($defs, schema)))
589
- || (LlmTypeCheckerV3_1.isOneOf(schema)
590
- && schema.oneOf.every(schema => isObject($defs, schema)))
591
- );
429
+ async function executeClassFunction<Model extends ILlmSchema.Model>(
430
+ call: AgenticaCallEvent<Model>,
431
+ operation: AgenticaOperation.Class<Model>,
432
+ ): Promise<unknown> {
433
+ const execute = operation.controller.execute;
434
+ const value: unknown = typeof execute === "function"
435
+ ? await execute({
436
+ application: operation.controller.application,
437
+ function: operation.function,
438
+ arguments: call.arguments,
439
+ })
440
+ : await (execute as Record<string, any>)[operation.function.name](
441
+ call.arguments,
442
+ );
443
+ return value;
444
+ }
445
+
446
+ async function executeHttpOperation<Model extends ILlmSchema.Model>(
447
+ call: AgenticaCallEvent<Model>,
448
+ operation: AgenticaOperation.Http<Model>,
449
+ ): Promise<unknown> {
450
+ const execute = operation.controller.execute;
451
+ const value: IHttpResponse = typeof execute === "function"
452
+ ? await execute({
453
+ connection: operation.controller.connection,
454
+ application: operation.controller.application,
455
+ function: operation.function,
456
+ arguments: call.arguments,
457
+ })
458
+ : await HttpLlm.propagate({
459
+ connection: operation.controller.connection,
460
+ application: operation.controller.application,
461
+ function: operation.function,
462
+ input: call.arguments,
463
+ });
464
+ return value;
465
+ }
466
+
467
+ async function executeMcpOperation<Model extends ILlmSchema.Model>(
468
+ call: AgenticaCallEvent<Model>,
469
+ operation: AgenticaOperation.Mcp<Model>,
470
+ ): Promise<unknown> {
471
+ return operation.controller.client.callTool({
472
+ method: operation.function.name,
473
+ name: operation.function.name,
474
+ arguments: call.arguments,
475
+ }).then(v => v.content);
592
476
  }