@agentica/core 0.8.1 → 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 (55) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +404 -404
  3. package/lib/Agentica.d.ts +2 -2
  4. package/lib/Agentica.js +9 -3
  5. package/lib/Agentica.js.map +1 -1
  6. package/lib/chatgpt/ChatGptHistoryDecoder.js.map +1 -1
  7. package/lib/index.mjs +17 -15
  8. package/lib/index.mjs.map +1 -1
  9. package/lib/internal/AgenticaTokenUsageAggregator.js +7 -9
  10. package/lib/internal/AgenticaTokenUsageAggregator.js.map +1 -1
  11. package/lib/structures/IAgenticaTokenUsage.d.ts +7 -11
  12. package/package.json +1 -1
  13. package/prompts/cancel.md +4 -4
  14. package/prompts/common.md +2 -2
  15. package/prompts/describe.md +6 -6
  16. package/prompts/execute.md +6 -6
  17. package/prompts/initialize.md +2 -2
  18. package/prompts/select.md +6 -6
  19. package/src/Agentica.ts +318 -312
  20. package/src/chatgpt/ChatGptAgent.ts +71 -71
  21. package/src/chatgpt/ChatGptCallFunctionAgent.ts +445 -445
  22. package/src/chatgpt/ChatGptCancelFunctionAgent.ts +283 -283
  23. package/src/chatgpt/ChatGptDescribeFunctionAgent.ts +51 -51
  24. package/src/chatgpt/ChatGptHistoryDecoder.ts +87 -86
  25. package/src/chatgpt/ChatGptInitializeFunctionAgent.ts +88 -88
  26. package/src/chatgpt/ChatGptSelectFunctionAgent.ts +318 -318
  27. package/src/functional/createHttpLlmApplication.ts +63 -63
  28. package/src/index.ts +19 -19
  29. package/src/internal/AgenticaConstant.ts +4 -4
  30. package/src/internal/AgenticaDefaultPrompt.ts +39 -39
  31. package/src/internal/AgenticaOperationComposer.ts +82 -82
  32. package/src/internal/AgenticaPromptFactory.ts +30 -30
  33. package/src/internal/AgenticaPromptTransformer.ts +83 -83
  34. package/src/internal/AgenticaTokenUsageAggregator.ts +115 -123
  35. package/src/internal/MathUtil.ts +3 -3
  36. package/src/internal/Singleton.ts +22 -22
  37. package/src/internal/__map_take.ts +15 -15
  38. package/src/structures/IAgenticaConfig.ts +121 -121
  39. package/src/structures/IAgenticaContext.ts +128 -128
  40. package/src/structures/IAgenticaController.ts +130 -130
  41. package/src/structures/IAgenticaEvent.ts +224 -224
  42. package/src/structures/IAgenticaExecutor.ts +152 -152
  43. package/src/structures/IAgenticaOperation.ts +64 -64
  44. package/src/structures/IAgenticaOperationCollection.ts +50 -50
  45. package/src/structures/IAgenticaOperationSelection.ts +69 -69
  46. package/src/structures/IAgenticaPrompt.ts +173 -173
  47. package/src/structures/IAgenticaProps.ts +64 -64
  48. package/src/structures/IAgenticaProvider.ts +45 -45
  49. package/src/structures/IAgenticaSystemPrompt.ts +122 -122
  50. package/src/structures/IAgenticaTokenUsage.ts +107 -112
  51. package/src/structures/internal/__IChatCancelFunctionsApplication.ts +23 -23
  52. package/src/structures/internal/__IChatFunctionReference.ts +21 -21
  53. package/src/structures/internal/__IChatInitialApplication.ts +15 -15
  54. package/src/structures/internal/__IChatSelectFunctionsApplication.ts +24 -24
  55. package/src/typings/AgenticaSource.ts +6 -6
@@ -1,445 +1,445 @@
1
- import {
2
- ChatGptTypeChecker,
3
- HttpLlm,
4
- IChatGptSchema,
5
- IHttpMigrateRoute,
6
- IHttpResponse,
7
- } from "@samchon/openapi";
8
- import OpenAI from "openai";
9
- import { IValidation } from "typia";
10
-
11
- import { AgenticaConstant } from "../internal/AgenticaConstant";
12
- import { AgenticaDefaultPrompt } from "../internal/AgenticaDefaultPrompt";
13
- import { AgenticaPromptFactory } from "../internal/AgenticaPromptFactory";
14
- import { AgenticaSystemPrompt } from "../internal/AgenticaSystemPrompt";
15
- import { IAgenticaContext } from "../structures/IAgenticaContext";
16
- import { IAgenticaEvent } from "../structures/IAgenticaEvent";
17
- import { IAgenticaOperation } from "../structures/IAgenticaOperation";
18
- import { IAgenticaPrompt } from "../structures/IAgenticaPrompt";
19
- import { ChatGptCancelFunctionAgent } from "./ChatGptCancelFunctionAgent";
20
- import { ChatGptHistoryDecoder } from "./ChatGptHistoryDecoder";
21
-
22
- export namespace ChatGptCallFunctionAgent {
23
- export const execute = async (
24
- ctx: IAgenticaContext,
25
- ): Promise<IAgenticaPrompt[]> => {
26
- //----
27
- // EXECUTE CHATGPT API
28
- //----
29
- const completion: OpenAI.ChatCompletion = await ctx.request("call", {
30
- messages: [
31
- // COMMON SYSTEM PROMPT
32
- {
33
- role: "system",
34
- content: AgenticaDefaultPrompt.write(ctx.config),
35
- } satisfies OpenAI.ChatCompletionSystemMessageParam,
36
- // PREVIOUS HISTORIES
37
- ...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
38
- // USER INPUT
39
- {
40
- role: "user",
41
- content: ctx.prompt.text,
42
- },
43
- // SYSTEM PROMPT
44
- {
45
- role: "system",
46
- content:
47
- ctx.config?.systemPrompt?.execute?.(ctx.histories) ??
48
- AgenticaSystemPrompt.EXECUTE,
49
- },
50
- ],
51
- // STACKED FUNCTIONS
52
- tools: ctx.stack.map(
53
- (op) =>
54
- ({
55
- type: "function",
56
- function: {
57
- name: op.name,
58
- description: op.function.description,
59
- parameters: (op.function.separated
60
- ? (op.function.separated.llm ??
61
- ({
62
- type: "object",
63
- properties: {},
64
- required: [],
65
- additionalProperties: false,
66
- $defs: {},
67
- } satisfies IChatGptSchema.IParameters))
68
- : op.function.parameters) as Record<string, any>,
69
- },
70
- }) as OpenAI.ChatCompletionTool,
71
- ),
72
- tool_choice: "auto",
73
- parallel_tool_calls: false,
74
- });
75
-
76
- //----
77
- // PROCESS COMPLETION
78
- //----
79
- const closures: Array<
80
- () => Promise<
81
- Array<
82
- | IAgenticaPrompt.IExecute
83
- | IAgenticaPrompt.ICancel
84
- | IAgenticaPrompt.IText
85
- >
86
- >
87
- > = [];
88
- for (const choice of completion.choices) {
89
- for (const tc of choice.message.tool_calls ?? []) {
90
- if (tc.type === "function") {
91
- const operation: IAgenticaOperation | undefined =
92
- ctx.operations.flat.get(tc.function.name);
93
- if (operation === undefined) continue;
94
- closures.push(
95
- async (): Promise<
96
- [IAgenticaPrompt.IExecute, IAgenticaPrompt.ICancel]
97
- > => {
98
- const call: IAgenticaEvent.ICall = {
99
- type: "call",
100
- id: tc.id,
101
- operation,
102
- arguments: JSON.parse(tc.function.arguments),
103
- };
104
- if (call.operation.protocol === "http")
105
- fillHttpArguments({
106
- operation: call.operation,
107
- arguments: call.arguments,
108
- });
109
- await ctx.dispatch(call);
110
-
111
- const execute: IAgenticaPrompt.IExecute = await propagate(
112
- ctx,
113
- call,
114
- 0,
115
- );
116
- await ctx.dispatch({
117
- type: "execute",
118
- id: call.id,
119
- operation: call.operation,
120
- arguments: execute.arguments,
121
- value: execute.value,
122
- });
123
-
124
- await ChatGptCancelFunctionAgent.cancelFunction(ctx, {
125
- name: call.operation.name,
126
- reason: "completed",
127
- });
128
- await ctx.dispatch({
129
- type: "cancel",
130
- operation: call.operation,
131
- reason: "complete",
132
- });
133
- return [
134
- execute,
135
- {
136
- type: "cancel",
137
- id: call.id,
138
- operations: [
139
- AgenticaPromptFactory.selection({
140
- ...call.operation,
141
- reason: "complete",
142
- }),
143
- ],
144
- } satisfies IAgenticaPrompt.ICancel,
145
- ] as const;
146
- },
147
- );
148
- }
149
- }
150
- if (
151
- choice.message.role === "assistant" &&
152
- !!choice.message.content?.length
153
- )
154
- closures.push(async () => {
155
- const value: IAgenticaPrompt.IText = {
156
- type: "text",
157
- role: "assistant",
158
- text: choice.message.content!,
159
- };
160
- await ctx.dispatch(value);
161
- return [value];
162
- });
163
- }
164
- return (await Promise.all(closures.map((fn) => fn()))).flat();
165
- };
166
-
167
- const propagate = async (
168
- ctx: IAgenticaContext,
169
- call: IAgenticaEvent.ICall,
170
- retry: number,
171
- ): Promise<IAgenticaPrompt.IExecute> => {
172
- if (call.operation.protocol === "http") {
173
- //----
174
- // HTTP PROTOCOL
175
- //----
176
- try {
177
- // CALL HTTP API
178
- const response: IHttpResponse = call.operation.controller.execute
179
- ? await call.operation.controller.execute({
180
- connection: call.operation.controller.connection,
181
- application: call.operation.controller.application,
182
- function: call.operation.function,
183
- arguments: call.arguments,
184
- })
185
- : await HttpLlm.propagate({
186
- connection: call.operation.controller.connection,
187
- application: call.operation.controller.application,
188
- function: call.operation.function,
189
- input: call.arguments,
190
- });
191
- // CHECK STATUS
192
- const success: boolean =
193
- ((response.status === 400 ||
194
- response.status === 404 ||
195
- response.status === 422) &&
196
- retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY) &&
197
- typeof response.body) === false;
198
- // DISPATCH EVENT
199
- return (
200
- (success === false
201
- ? await correct(ctx, call, retry, response.body)
202
- : null) ??
203
- (await AgenticaPromptFactory.execute({
204
- type: "execute",
205
- protocol: "http",
206
- controller: call.operation.controller,
207
- function: call.operation.function,
208
- id: call.id,
209
- name: call.operation.name,
210
- arguments: call.arguments,
211
- value: response,
212
- }))
213
- );
214
- } catch (error) {
215
- // DISPATCH ERROR
216
- return AgenticaPromptFactory.execute({
217
- type: "execute",
218
- protocol: "http",
219
- controller: call.operation.controller,
220
- function: call.operation.function,
221
- id: call.id,
222
- name: call.operation.name,
223
- arguments: call.arguments,
224
- value: {
225
- status: 500,
226
- headers: {},
227
- body:
228
- error instanceof Error
229
- ? {
230
- ...error,
231
- name: error.name,
232
- message: error.message,
233
- }
234
- : error,
235
- },
236
- });
237
- }
238
- } else {
239
- //----
240
- // CLASS FUNCTION
241
- //----
242
- // VALIDATE FIRST
243
- const check: IValidation<unknown> = call.operation.function.validate(
244
- call.arguments,
245
- );
246
- if (check.success === false)
247
- return (
248
- (retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY)
249
- ? await correct(ctx, call, retry, check.errors)
250
- : null) ??
251
- AgenticaPromptFactory.execute({
252
- type: "execute",
253
- protocol: "class",
254
- controller: call.operation.controller,
255
- function: call.operation.function,
256
- id: call.id,
257
- name: call.operation.name,
258
- arguments: call.arguments,
259
- value: {
260
- name: "TypeGuardError",
261
- message: "Invalid arguments.",
262
- errors: check.errors,
263
- },
264
- })
265
- );
266
- // EXECUTE FUNCTION
267
- try {
268
- const value: any =
269
- typeof call.operation.controller.execute === "function"
270
- ? await call.operation.controller.execute({
271
- application: call.operation.controller.application,
272
- function: call.operation.function,
273
- arguments: call.arguments,
274
- })
275
- : await (call.operation.controller.execute as any)[
276
- call.operation.function.name
277
- ](call.arguments);
278
- return AgenticaPromptFactory.execute({
279
- type: "execute",
280
- protocol: "class",
281
- controller: call.operation.controller,
282
- function: call.operation.function,
283
- id: call.id,
284
- name: call.operation.name,
285
- arguments: call.arguments,
286
- value,
287
- });
288
- } catch (error) {
289
- return AgenticaPromptFactory.execute({
290
- type: "execute",
291
- protocol: "class",
292
- controller: call.operation.controller,
293
- function: call.operation.function,
294
- id: call.id,
295
- name: call.operation.name,
296
- arguments: call.arguments,
297
- value:
298
- error instanceof Error
299
- ? {
300
- ...error,
301
- name: error.name,
302
- message: error.message,
303
- }
304
- : error,
305
- });
306
- }
307
- }
308
- };
309
-
310
- const correct = async (
311
- ctx: IAgenticaContext,
312
- call: IAgenticaEvent.ICall,
313
- retry: number,
314
- error: unknown,
315
- ): Promise<IAgenticaPrompt.IExecute | null> => {
316
- //----
317
- // EXECUTE CHATGPT API
318
- //----
319
- const completion: OpenAI.ChatCompletion = await ctx.request("call", {
320
- messages: [
321
- // COMMON SYSTEM PROMPT
322
- {
323
- role: "system",
324
- content: AgenticaDefaultPrompt.write(ctx.config),
325
- } satisfies OpenAI.ChatCompletionSystemMessageParam,
326
- // PREVIOUS HISTORIES
327
- ...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
328
- // USER INPUT
329
- {
330
- role: "user",
331
- content: ctx.prompt.text,
332
- },
333
- // TYPE CORRECTION
334
- {
335
- role: "system",
336
- content:
337
- ctx.config?.systemPrompt?.execute?.(ctx.histories) ??
338
- AgenticaSystemPrompt.EXECUTE,
339
- },
340
- {
341
- role: "assistant",
342
- tool_calls: [
343
- {
344
- type: "function",
345
- id: call.id,
346
- function: {
347
- name: call.operation.name,
348
- arguments: JSON.stringify(call.arguments),
349
- },
350
- } satisfies OpenAI.ChatCompletionMessageToolCall,
351
- ],
352
- } satisfies OpenAI.ChatCompletionAssistantMessageParam,
353
- {
354
- role: "tool",
355
- content: typeof error === "string" ? error : JSON.stringify(error),
356
- tool_call_id: call.id,
357
- } satisfies OpenAI.ChatCompletionToolMessageParam,
358
- {
359
- role: "system",
360
- content: [
361
- "You A.I. assistant has composed wrong arguments.",
362
- "",
363
- "Correct it at the next function calling.",
364
- ].join("\n"),
365
- },
366
- ],
367
- // STACK FUNCTIONS
368
- tools: [
369
- {
370
- type: "function",
371
- function: {
372
- name: call.operation.name,
373
- description: call.operation.function.description,
374
- parameters: (call.operation.function.separated
375
- ? (call.operation.function.separated?.llm ??
376
- ({
377
- $defs: {},
378
- type: "object",
379
- properties: {},
380
- additionalProperties: false,
381
- required: [],
382
- } satisfies IChatGptSchema.IParameters))
383
- : call.operation.function.parameters) as any,
384
- },
385
- },
386
- ],
387
- tool_choice: "auto",
388
- parallel_tool_calls: false,
389
- });
390
-
391
- //----
392
- // PROCESS COMPLETION
393
- //----
394
- const toolCall: OpenAI.ChatCompletionMessageToolCall | undefined = (
395
- completion.choices[0]?.message.tool_calls ?? []
396
- ).find(
397
- (tc) =>
398
- tc.type === "function" && tc.function.name === call.operation.name,
399
- );
400
- if (toolCall === undefined) return null;
401
- return propagate(
402
- ctx,
403
- {
404
- id: toolCall.id,
405
- type: "call",
406
- operation: call.operation,
407
- arguments: JSON.parse(toolCall.function.arguments),
408
- },
409
- retry,
410
- );
411
- };
412
-
413
- const fillHttpArguments = (props: {
414
- operation: IAgenticaOperation;
415
- arguments: object;
416
- }): void => {
417
- if (props.operation.protocol !== "http") return;
418
- const route: IHttpMigrateRoute = props.operation.function.route();
419
- if (
420
- route.body &&
421
- route.operation().requestBody?.required === true &&
422
- (props.arguments as any).body === undefined &&
423
- isObject(
424
- props.operation.function.parameters.$defs,
425
- props.operation.function.parameters.properties.body!,
426
- )
427
- )
428
- (props.arguments as any).body = {};
429
- if (route.query && (props.arguments as any).query === undefined)
430
- (props.arguments as any).query = {};
431
- };
432
-
433
- const isObject = (
434
- $defs: Record<string, IChatGptSchema>,
435
- schema: IChatGptSchema,
436
- ): boolean => {
437
- return (
438
- ChatGptTypeChecker.isObject(schema) ||
439
- (ChatGptTypeChecker.isReference(schema) &&
440
- isObject($defs, $defs[schema.$ref.split("/").at(-1)!]!)) ||
441
- (ChatGptTypeChecker.isAnyOf(schema) &&
442
- schema.anyOf.every((schema) => isObject($defs, schema)))
443
- );
444
- };
445
- }
1
+ import {
2
+ ChatGptTypeChecker,
3
+ HttpLlm,
4
+ IChatGptSchema,
5
+ IHttpMigrateRoute,
6
+ IHttpResponse,
7
+ } from "@samchon/openapi";
8
+ import OpenAI from "openai";
9
+ import { IValidation } from "typia";
10
+
11
+ import { AgenticaConstant } from "../internal/AgenticaConstant";
12
+ import { AgenticaDefaultPrompt } from "../internal/AgenticaDefaultPrompt";
13
+ import { AgenticaPromptFactory } from "../internal/AgenticaPromptFactory";
14
+ import { AgenticaSystemPrompt } from "../internal/AgenticaSystemPrompt";
15
+ import { IAgenticaContext } from "../structures/IAgenticaContext";
16
+ import { IAgenticaEvent } from "../structures/IAgenticaEvent";
17
+ import { IAgenticaOperation } from "../structures/IAgenticaOperation";
18
+ import { IAgenticaPrompt } from "../structures/IAgenticaPrompt";
19
+ import { ChatGptCancelFunctionAgent } from "./ChatGptCancelFunctionAgent";
20
+ import { ChatGptHistoryDecoder } from "./ChatGptHistoryDecoder";
21
+
22
+ export namespace ChatGptCallFunctionAgent {
23
+ export const execute = async (
24
+ ctx: IAgenticaContext,
25
+ ): Promise<IAgenticaPrompt[]> => {
26
+ //----
27
+ // EXECUTE CHATGPT API
28
+ //----
29
+ const completion: OpenAI.ChatCompletion = await ctx.request("call", {
30
+ messages: [
31
+ // COMMON SYSTEM PROMPT
32
+ {
33
+ role: "system",
34
+ content: AgenticaDefaultPrompt.write(ctx.config),
35
+ } satisfies OpenAI.ChatCompletionSystemMessageParam,
36
+ // PREVIOUS HISTORIES
37
+ ...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
38
+ // USER INPUT
39
+ {
40
+ role: "user",
41
+ content: ctx.prompt.text,
42
+ },
43
+ // SYSTEM PROMPT
44
+ {
45
+ role: "system",
46
+ content:
47
+ ctx.config?.systemPrompt?.execute?.(ctx.histories) ??
48
+ AgenticaSystemPrompt.EXECUTE,
49
+ },
50
+ ],
51
+ // STACKED FUNCTIONS
52
+ tools: ctx.stack.map(
53
+ (op) =>
54
+ ({
55
+ type: "function",
56
+ function: {
57
+ name: op.name,
58
+ description: op.function.description,
59
+ parameters: (op.function.separated
60
+ ? (op.function.separated.llm ??
61
+ ({
62
+ type: "object",
63
+ properties: {},
64
+ required: [],
65
+ additionalProperties: false,
66
+ $defs: {},
67
+ } satisfies IChatGptSchema.IParameters))
68
+ : op.function.parameters) as Record<string, any>,
69
+ },
70
+ }) as OpenAI.ChatCompletionTool,
71
+ ),
72
+ tool_choice: "auto",
73
+ parallel_tool_calls: false,
74
+ });
75
+
76
+ //----
77
+ // PROCESS COMPLETION
78
+ //----
79
+ const closures: Array<
80
+ () => Promise<
81
+ Array<
82
+ | IAgenticaPrompt.IExecute
83
+ | IAgenticaPrompt.ICancel
84
+ | IAgenticaPrompt.IText
85
+ >
86
+ >
87
+ > = [];
88
+ for (const choice of completion.choices) {
89
+ for (const tc of choice.message.tool_calls ?? []) {
90
+ if (tc.type === "function") {
91
+ const operation: IAgenticaOperation | undefined =
92
+ ctx.operations.flat.get(tc.function.name);
93
+ if (operation === undefined) continue;
94
+ closures.push(
95
+ async (): Promise<
96
+ [IAgenticaPrompt.IExecute, IAgenticaPrompt.ICancel]
97
+ > => {
98
+ const call: IAgenticaEvent.ICall = {
99
+ type: "call",
100
+ id: tc.id,
101
+ operation,
102
+ arguments: JSON.parse(tc.function.arguments),
103
+ };
104
+ if (call.operation.protocol === "http")
105
+ fillHttpArguments({
106
+ operation: call.operation,
107
+ arguments: call.arguments,
108
+ });
109
+ await ctx.dispatch(call);
110
+
111
+ const execute: IAgenticaPrompt.IExecute = await propagate(
112
+ ctx,
113
+ call,
114
+ 0,
115
+ );
116
+ await ctx.dispatch({
117
+ type: "execute",
118
+ id: call.id,
119
+ operation: call.operation,
120
+ arguments: execute.arguments,
121
+ value: execute.value,
122
+ });
123
+
124
+ await ChatGptCancelFunctionAgent.cancelFunction(ctx, {
125
+ name: call.operation.name,
126
+ reason: "completed",
127
+ });
128
+ await ctx.dispatch({
129
+ type: "cancel",
130
+ operation: call.operation,
131
+ reason: "complete",
132
+ });
133
+ return [
134
+ execute,
135
+ {
136
+ type: "cancel",
137
+ id: call.id,
138
+ operations: [
139
+ AgenticaPromptFactory.selection({
140
+ ...call.operation,
141
+ reason: "complete",
142
+ }),
143
+ ],
144
+ } satisfies IAgenticaPrompt.ICancel,
145
+ ] as const;
146
+ },
147
+ );
148
+ }
149
+ }
150
+ if (
151
+ choice.message.role === "assistant" &&
152
+ !!choice.message.content?.length
153
+ )
154
+ closures.push(async () => {
155
+ const value: IAgenticaPrompt.IText = {
156
+ type: "text",
157
+ role: "assistant",
158
+ text: choice.message.content!,
159
+ };
160
+ await ctx.dispatch(value);
161
+ return [value];
162
+ });
163
+ }
164
+ return (await Promise.all(closures.map((fn) => fn()))).flat();
165
+ };
166
+
167
+ const propagate = async (
168
+ ctx: IAgenticaContext,
169
+ call: IAgenticaEvent.ICall,
170
+ retry: number,
171
+ ): Promise<IAgenticaPrompt.IExecute> => {
172
+ if (call.operation.protocol === "http") {
173
+ //----
174
+ // HTTP PROTOCOL
175
+ //----
176
+ try {
177
+ // CALL HTTP API
178
+ const response: IHttpResponse = call.operation.controller.execute
179
+ ? await call.operation.controller.execute({
180
+ connection: call.operation.controller.connection,
181
+ application: call.operation.controller.application,
182
+ function: call.operation.function,
183
+ arguments: call.arguments,
184
+ })
185
+ : await HttpLlm.propagate({
186
+ connection: call.operation.controller.connection,
187
+ application: call.operation.controller.application,
188
+ function: call.operation.function,
189
+ input: call.arguments,
190
+ });
191
+ // CHECK STATUS
192
+ const success: boolean =
193
+ ((response.status === 400 ||
194
+ response.status === 404 ||
195
+ response.status === 422) &&
196
+ retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY) &&
197
+ typeof response.body) === false;
198
+ // DISPATCH EVENT
199
+ return (
200
+ (success === false
201
+ ? await correct(ctx, call, retry, response.body)
202
+ : null) ??
203
+ (await AgenticaPromptFactory.execute({
204
+ type: "execute",
205
+ protocol: "http",
206
+ controller: call.operation.controller,
207
+ function: call.operation.function,
208
+ id: call.id,
209
+ name: call.operation.name,
210
+ arguments: call.arguments,
211
+ value: response,
212
+ }))
213
+ );
214
+ } catch (error) {
215
+ // DISPATCH ERROR
216
+ return AgenticaPromptFactory.execute({
217
+ type: "execute",
218
+ protocol: "http",
219
+ controller: call.operation.controller,
220
+ function: call.operation.function,
221
+ id: call.id,
222
+ name: call.operation.name,
223
+ arguments: call.arguments,
224
+ value: {
225
+ status: 500,
226
+ headers: {},
227
+ body:
228
+ error instanceof Error
229
+ ? {
230
+ ...error,
231
+ name: error.name,
232
+ message: error.message,
233
+ }
234
+ : error,
235
+ },
236
+ });
237
+ }
238
+ } else {
239
+ //----
240
+ // CLASS FUNCTION
241
+ //----
242
+ // VALIDATE FIRST
243
+ const check: IValidation<unknown> = call.operation.function.validate(
244
+ call.arguments,
245
+ );
246
+ if (check.success === false)
247
+ return (
248
+ (retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY)
249
+ ? await correct(ctx, call, retry, check.errors)
250
+ : null) ??
251
+ AgenticaPromptFactory.execute({
252
+ type: "execute",
253
+ protocol: "class",
254
+ controller: call.operation.controller,
255
+ function: call.operation.function,
256
+ id: call.id,
257
+ name: call.operation.name,
258
+ arguments: call.arguments,
259
+ value: {
260
+ name: "TypeGuardError",
261
+ message: "Invalid arguments.",
262
+ errors: check.errors,
263
+ },
264
+ })
265
+ );
266
+ // EXECUTE FUNCTION
267
+ try {
268
+ const value: any =
269
+ typeof call.operation.controller.execute === "function"
270
+ ? await call.operation.controller.execute({
271
+ application: call.operation.controller.application,
272
+ function: call.operation.function,
273
+ arguments: call.arguments,
274
+ })
275
+ : await (call.operation.controller.execute as any)[
276
+ call.operation.function.name
277
+ ](call.arguments);
278
+ return AgenticaPromptFactory.execute({
279
+ type: "execute",
280
+ protocol: "class",
281
+ controller: call.operation.controller,
282
+ function: call.operation.function,
283
+ id: call.id,
284
+ name: call.operation.name,
285
+ arguments: call.arguments,
286
+ value,
287
+ });
288
+ } catch (error) {
289
+ return AgenticaPromptFactory.execute({
290
+ type: "execute",
291
+ protocol: "class",
292
+ controller: call.operation.controller,
293
+ function: call.operation.function,
294
+ id: call.id,
295
+ name: call.operation.name,
296
+ arguments: call.arguments,
297
+ value:
298
+ error instanceof Error
299
+ ? {
300
+ ...error,
301
+ name: error.name,
302
+ message: error.message,
303
+ }
304
+ : error,
305
+ });
306
+ }
307
+ }
308
+ };
309
+
310
+ const correct = async (
311
+ ctx: IAgenticaContext,
312
+ call: IAgenticaEvent.ICall,
313
+ retry: number,
314
+ error: unknown,
315
+ ): Promise<IAgenticaPrompt.IExecute | null> => {
316
+ //----
317
+ // EXECUTE CHATGPT API
318
+ //----
319
+ const completion: OpenAI.ChatCompletion = await ctx.request("call", {
320
+ messages: [
321
+ // COMMON SYSTEM PROMPT
322
+ {
323
+ role: "system",
324
+ content: AgenticaDefaultPrompt.write(ctx.config),
325
+ } satisfies OpenAI.ChatCompletionSystemMessageParam,
326
+ // PREVIOUS HISTORIES
327
+ ...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
328
+ // USER INPUT
329
+ {
330
+ role: "user",
331
+ content: ctx.prompt.text,
332
+ },
333
+ // TYPE CORRECTION
334
+ {
335
+ role: "system",
336
+ content:
337
+ ctx.config?.systemPrompt?.execute?.(ctx.histories) ??
338
+ AgenticaSystemPrompt.EXECUTE,
339
+ },
340
+ {
341
+ role: "assistant",
342
+ tool_calls: [
343
+ {
344
+ type: "function",
345
+ id: call.id,
346
+ function: {
347
+ name: call.operation.name,
348
+ arguments: JSON.stringify(call.arguments),
349
+ },
350
+ } satisfies OpenAI.ChatCompletionMessageToolCall,
351
+ ],
352
+ } satisfies OpenAI.ChatCompletionAssistantMessageParam,
353
+ {
354
+ role: "tool",
355
+ content: typeof error === "string" ? error : JSON.stringify(error),
356
+ tool_call_id: call.id,
357
+ } satisfies OpenAI.ChatCompletionToolMessageParam,
358
+ {
359
+ role: "system",
360
+ content: [
361
+ "You A.I. assistant has composed wrong arguments.",
362
+ "",
363
+ "Correct it at the next function calling.",
364
+ ].join("\n"),
365
+ },
366
+ ],
367
+ // STACK FUNCTIONS
368
+ tools: [
369
+ {
370
+ type: "function",
371
+ function: {
372
+ name: call.operation.name,
373
+ description: call.operation.function.description,
374
+ parameters: (call.operation.function.separated
375
+ ? (call.operation.function.separated?.llm ??
376
+ ({
377
+ $defs: {},
378
+ type: "object",
379
+ properties: {},
380
+ additionalProperties: false,
381
+ required: [],
382
+ } satisfies IChatGptSchema.IParameters))
383
+ : call.operation.function.parameters) as any,
384
+ },
385
+ },
386
+ ],
387
+ tool_choice: "auto",
388
+ parallel_tool_calls: false,
389
+ });
390
+
391
+ //----
392
+ // PROCESS COMPLETION
393
+ //----
394
+ const toolCall: OpenAI.ChatCompletionMessageToolCall | undefined = (
395
+ completion.choices[0]?.message.tool_calls ?? []
396
+ ).find(
397
+ (tc) =>
398
+ tc.type === "function" && tc.function.name === call.operation.name,
399
+ );
400
+ if (toolCall === undefined) return null;
401
+ return propagate(
402
+ ctx,
403
+ {
404
+ id: toolCall.id,
405
+ type: "call",
406
+ operation: call.operation,
407
+ arguments: JSON.parse(toolCall.function.arguments),
408
+ },
409
+ retry,
410
+ );
411
+ };
412
+
413
+ const fillHttpArguments = (props: {
414
+ operation: IAgenticaOperation;
415
+ arguments: object;
416
+ }): void => {
417
+ if (props.operation.protocol !== "http") return;
418
+ const route: IHttpMigrateRoute = props.operation.function.route();
419
+ if (
420
+ route.body &&
421
+ route.operation().requestBody?.required === true &&
422
+ (props.arguments as any).body === undefined &&
423
+ isObject(
424
+ props.operation.function.parameters.$defs,
425
+ props.operation.function.parameters.properties.body!,
426
+ )
427
+ )
428
+ (props.arguments as any).body = {};
429
+ if (route.query && (props.arguments as any).query === undefined)
430
+ (props.arguments as any).query = {};
431
+ };
432
+
433
+ const isObject = (
434
+ $defs: Record<string, IChatGptSchema>,
435
+ schema: IChatGptSchema,
436
+ ): boolean => {
437
+ return (
438
+ ChatGptTypeChecker.isObject(schema) ||
439
+ (ChatGptTypeChecker.isReference(schema) &&
440
+ isObject($defs, $defs[schema.$ref.split("/").at(-1)!]!)) ||
441
+ (ChatGptTypeChecker.isAnyOf(schema) &&
442
+ schema.anyOf.every((schema) => isObject($defs, schema)))
443
+ );
444
+ };
445
+ }