@agentica/core 0.12.0 → 0.12.2-dev.20250314
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.
- package/LICENSE +21 -21
- package/README.md +461 -461
- package/lib/Agentica.js +3 -1
- package/lib/Agentica.js.map +1 -1
- package/lib/context/internal/AgenticaTokenUsageAggregator.js +1 -1
- package/lib/context/internal/AgenticaTokenUsageAggregator.js.map +1 -1
- package/lib/index.mjs +5 -2
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/prompts/cancel.md +4 -4
- package/prompts/common.md +2 -2
- package/prompts/describe.md +6 -6
- package/prompts/execute.md +6 -6
- package/prompts/initialize.md +2 -2
- package/prompts/select.md +6 -6
- package/src/Agentica.ts +359 -356
- package/src/chatgpt/ChatGptAgent.ts +76 -76
- package/src/chatgpt/ChatGptCallFunctionAgent.ts +466 -466
- package/src/chatgpt/ChatGptCancelFunctionAgent.ts +280 -280
- package/src/chatgpt/ChatGptCompletionMessageUtil.ts +166 -166
- package/src/chatgpt/ChatGptDescribeFunctionAgent.ts +122 -122
- package/src/chatgpt/ChatGptHistoryDecoder.ts +88 -88
- package/src/chatgpt/ChatGptInitializeFunctionAgent.ts +96 -96
- package/src/chatgpt/ChatGptSelectFunctionAgent.ts +311 -311
- package/src/chatgpt/ChatGptUsageAggregator.ts +62 -62
- package/src/context/AgenticaCancelPrompt.ts +32 -32
- package/src/context/AgenticaClassOperation.ts +23 -23
- package/src/context/AgenticaContext.ts +130 -130
- package/src/context/AgenticaHttpOperation.ts +27 -27
- package/src/context/AgenticaOperation.ts +66 -66
- package/src/context/AgenticaOperationBase.ts +57 -57
- package/src/context/AgenticaOperationCollection.ts +52 -52
- package/src/context/AgenticaOperationSelection.ts +27 -27
- package/src/context/AgenticaTokenUsage.ts +170 -170
- package/src/context/internal/AgenticaTokenUsageAggregator.ts +66 -66
- package/src/context/internal/__IChatCancelFunctionsApplication.ts +23 -23
- package/src/context/internal/__IChatFunctionReference.ts +21 -21
- package/src/context/internal/__IChatInitialApplication.ts +15 -15
- package/src/context/internal/__IChatSelectFunctionsApplication.ts +24 -24
- package/src/events/AgenticaCallEvent.ts +36 -36
- package/src/events/AgenticaCancelEvent.ts +28 -28
- package/src/events/AgenticaDescribeEvent.ts +66 -66
- package/src/events/AgenticaEvent.ts +36 -36
- package/src/events/AgenticaEventBase.ts +7 -7
- package/src/events/AgenticaEventSource.ts +6 -6
- package/src/events/AgenticaExecuteEvent.ts +50 -50
- package/src/events/AgenticaInitializeEvent.ts +14 -14
- package/src/events/AgenticaRequestEvent.ts +45 -45
- package/src/events/AgenticaResponseEvent.ts +48 -48
- package/src/events/AgenticaSelectEvent.ts +37 -37
- package/src/events/AgenticaTextEvent.ts +62 -62
- package/src/functional/assertHttpLlmApplication.ts +55 -55
- package/src/functional/validateHttpLlmApplication.ts +66 -66
- package/src/index.ts +44 -44
- package/src/internal/AgenticaConstant.ts +4 -4
- package/src/internal/AgenticaDefaultPrompt.ts +43 -43
- package/src/internal/AgenticaOperationComposer.ts +96 -96
- package/src/internal/ByteArrayUtil.ts +5 -5
- package/src/internal/MPSCUtil.ts +111 -111
- package/src/internal/MathUtil.ts +3 -3
- package/src/internal/Singleton.ts +22 -22
- package/src/internal/StreamUtil.ts +64 -64
- package/src/internal/__map_take.ts +15 -15
- package/src/json/IAgenticaEventJson.ts +178 -178
- package/src/json/IAgenticaOperationJson.ts +36 -36
- package/src/json/IAgenticaOperationSelectionJson.ts +19 -19
- package/src/json/IAgenticaPromptJson.ts +130 -130
- package/src/json/IAgenticaTokenUsageJson.ts +107 -107
- package/src/prompts/AgenticaCancelPrompt.ts +32 -32
- package/src/prompts/AgenticaDescribePrompt.ts +41 -41
- package/src/prompts/AgenticaExecutePrompt.ts +52 -52
- package/src/prompts/AgenticaPrompt.ts +14 -14
- package/src/prompts/AgenticaPromptBase.ts +27 -27
- package/src/prompts/AgenticaSelectPrompt.ts +32 -32
- package/src/prompts/AgenticaTextPrompt.ts +31 -31
- package/src/structures/IAgenticaConfig.ts +123 -123
- package/src/structures/IAgenticaController.ts +133 -133
- package/src/structures/IAgenticaExecutor.ts +157 -157
- package/src/structures/IAgenticaProps.ts +69 -69
- package/src/structures/IAgenticaSystemPrompt.ts +125 -125
- package/src/structures/IAgenticaVendor.ts +39 -39
- package/src/transformers/AgenticaEventTransformer.ts +165 -165
- package/src/transformers/AgenticaPromptTransformer.ts +134 -134
|
@@ -1,311 +1,311 @@
|
|
|
1
|
-
import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
|
|
2
|
-
import OpenAI from "openai";
|
|
3
|
-
import typia, { IValidation } from "typia";
|
|
4
|
-
import { v4 } from "uuid";
|
|
5
|
-
|
|
6
|
-
import { AgenticaContext } from "../context/AgenticaContext";
|
|
7
|
-
import { AgenticaOperation } from "../context/AgenticaOperation";
|
|
8
|
-
import { AgenticaOperationSelection } from "../context/AgenticaOperationSelection";
|
|
9
|
-
import { __IChatFunctionReference } from "../context/internal/__IChatFunctionReference";
|
|
10
|
-
import { __IChatSelectFunctionsApplication } from "../context/internal/__IChatSelectFunctionsApplication";
|
|
11
|
-
import { AgenticaEvent } from "../events/AgenticaEvent";
|
|
12
|
-
import { AgenticaSelectEvent } from "../events/AgenticaSelectEvent";
|
|
13
|
-
import { AgenticaTextEvent } from "../events/AgenticaTextEvent";
|
|
14
|
-
import { AgenticaConstant } from "../internal/AgenticaConstant";
|
|
15
|
-
import { AgenticaDefaultPrompt } from "../internal/AgenticaDefaultPrompt";
|
|
16
|
-
import { AgenticaSystemPrompt } from "../internal/AgenticaSystemPrompt";
|
|
17
|
-
import { StreamUtil } from "../internal/StreamUtil";
|
|
18
|
-
import { AgenticaPrompt } from "../prompts/AgenticaPrompt";
|
|
19
|
-
import { AgenticaSelectPrompt } from "../prompts/AgenticaSelectPrompt";
|
|
20
|
-
import { AgenticaTextPrompt } from "../prompts/AgenticaTextPrompt";
|
|
21
|
-
import { ChatGptCompletionMessageUtil } from "./ChatGptCompletionMessageUtil";
|
|
22
|
-
import { ChatGptHistoryDecoder } from "./ChatGptHistoryDecoder";
|
|
23
|
-
|
|
24
|
-
export namespace ChatGptSelectFunctionAgent {
|
|
25
|
-
export const execute = async <Model extends ILlmSchema.Model>(
|
|
26
|
-
ctx: AgenticaContext<Model>,
|
|
27
|
-
): Promise<AgenticaPrompt<Model>[]> => {
|
|
28
|
-
if (ctx.operations.divided === undefined)
|
|
29
|
-
return step(ctx, ctx.operations.array, 0);
|
|
30
|
-
|
|
31
|
-
const stacks: AgenticaOperationSelection<Model>[][] =
|
|
32
|
-
ctx.operations.divided.map(() => []);
|
|
33
|
-
const events: AgenticaEvent<Model>[] = [];
|
|
34
|
-
const prompts: AgenticaPrompt<Model>[][] = await Promise.all(
|
|
35
|
-
ctx.operations.divided.map((operations, i) =>
|
|
36
|
-
step(
|
|
37
|
-
{
|
|
38
|
-
...ctx,
|
|
39
|
-
stack: stacks[i]!,
|
|
40
|
-
dispatch: async (e) => {
|
|
41
|
-
events.push(e);
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
operations,
|
|
45
|
-
0,
|
|
46
|
-
),
|
|
47
|
-
),
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// NO FUNCTION SELECTION, SO THAT ONLY TEXT LEFT
|
|
51
|
-
if (stacks.every((s) => s.length === 0)) return prompts[0]!;
|
|
52
|
-
// ELITICISM
|
|
53
|
-
else if ((ctx.config?.eliticism ?? AgenticaConstant.ELITICISM) === true)
|
|
54
|
-
return step(
|
|
55
|
-
ctx,
|
|
56
|
-
stacks
|
|
57
|
-
.flat()
|
|
58
|
-
.map(
|
|
59
|
-
(s) =>
|
|
60
|
-
ctx.operations.group
|
|
61
|
-
.get(s.operation.controller.name)!
|
|
62
|
-
.get(s.operation.function.name)!,
|
|
63
|
-
),
|
|
64
|
-
0,
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// RE-COLLECT SELECT FUNCTION EVENTS
|
|
68
|
-
const collection: AgenticaSelectPrompt<Model> = new AgenticaSelectPrompt({
|
|
69
|
-
id: v4(),
|
|
70
|
-
selections: [],
|
|
71
|
-
});
|
|
72
|
-
for (const e of events)
|
|
73
|
-
if (e.type === "select") {
|
|
74
|
-
collection.selections.push(e.selection);
|
|
75
|
-
await selectFunction(ctx, {
|
|
76
|
-
name: e.selection.operation.name,
|
|
77
|
-
reason: e.selection.reason,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
return [collection];
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const step = async <Model extends ILlmSchema.Model>(
|
|
84
|
-
ctx: AgenticaContext<Model>,
|
|
85
|
-
operations: AgenticaOperation<Model>[],
|
|
86
|
-
retry: number,
|
|
87
|
-
failures?: IFailure[],
|
|
88
|
-
): Promise<AgenticaPrompt<Model>[]> => {
|
|
89
|
-
//----
|
|
90
|
-
// EXECUTE CHATGPT API
|
|
91
|
-
//----
|
|
92
|
-
const completionStream = await ctx.request("select", {
|
|
93
|
-
messages: [
|
|
94
|
-
// COMMON SYSTEM PROMPT
|
|
95
|
-
{
|
|
96
|
-
role: "system",
|
|
97
|
-
content: AgenticaDefaultPrompt.write(ctx.config),
|
|
98
|
-
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
99
|
-
// CANDIDATE FUNCTIONS
|
|
100
|
-
{
|
|
101
|
-
role: "assistant",
|
|
102
|
-
tool_calls: [
|
|
103
|
-
{
|
|
104
|
-
type: "function",
|
|
105
|
-
id: "getApiFunctions",
|
|
106
|
-
function: {
|
|
107
|
-
name: "getApiFunctions",
|
|
108
|
-
arguments: JSON.stringify({}),
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
role: "tool",
|
|
115
|
-
tool_call_id: "getApiFunctions",
|
|
116
|
-
content: JSON.stringify(
|
|
117
|
-
operations.map((op) => ({
|
|
118
|
-
name: op.name,
|
|
119
|
-
description: op.function.description,
|
|
120
|
-
...(op.protocol === "http"
|
|
121
|
-
? {
|
|
122
|
-
method: op.function.method,
|
|
123
|
-
path: op.function.path,
|
|
124
|
-
tags: op.function.tags,
|
|
125
|
-
}
|
|
126
|
-
: {}),
|
|
127
|
-
})),
|
|
128
|
-
),
|
|
129
|
-
},
|
|
130
|
-
// PREVIOUS HISTORIES
|
|
131
|
-
...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
|
|
132
|
-
// USER INPUT
|
|
133
|
-
{
|
|
134
|
-
role: "user",
|
|
135
|
-
content: ctx.prompt.text,
|
|
136
|
-
},
|
|
137
|
-
// SYSTEM PROMPT
|
|
138
|
-
{
|
|
139
|
-
role: "system",
|
|
140
|
-
content:
|
|
141
|
-
ctx.config?.systemPrompt?.select?.(ctx.histories) ??
|
|
142
|
-
AgenticaSystemPrompt.SELECT,
|
|
143
|
-
},
|
|
144
|
-
// TYPE CORRECTIONS
|
|
145
|
-
...emendMessages(failures ?? []),
|
|
146
|
-
],
|
|
147
|
-
// STACK FUNCTIONS
|
|
148
|
-
tools: CONTAINER.functions.map(
|
|
149
|
-
(func) =>
|
|
150
|
-
({
|
|
151
|
-
type: "function",
|
|
152
|
-
function: {
|
|
153
|
-
name: func.name,
|
|
154
|
-
description: func.description,
|
|
155
|
-
parameters: func.parameters as any,
|
|
156
|
-
},
|
|
157
|
-
}) satisfies OpenAI.ChatCompletionTool,
|
|
158
|
-
),
|
|
159
|
-
tool_choice: "auto",
|
|
160
|
-
parallel_tool_calls: false,
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const chunks = await StreamUtil.readAll(completionStream);
|
|
164
|
-
const completion = ChatGptCompletionMessageUtil.merge(chunks);
|
|
165
|
-
//----
|
|
166
|
-
// VALIDATION
|
|
167
|
-
//----
|
|
168
|
-
if (retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY)) {
|
|
169
|
-
const failures: IFailure[] = [];
|
|
170
|
-
for (const choice of completion.choices)
|
|
171
|
-
for (const tc of choice.message.tool_calls ?? []) {
|
|
172
|
-
if (tc.function.name !== "selectFunctions") continue;
|
|
173
|
-
const input: object = JSON.parse(tc.function.arguments);
|
|
174
|
-
const validation: IValidation<__IChatFunctionReference.IProps> =
|
|
175
|
-
typia.validate<__IChatFunctionReference.IProps>(input);
|
|
176
|
-
if (validation.success === false)
|
|
177
|
-
failures.push({
|
|
178
|
-
id: tc.id,
|
|
179
|
-
name: tc.function.name,
|
|
180
|
-
validation,
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
if (failures.length > 0) return step(ctx, operations, retry, failures);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
//----
|
|
187
|
-
// PROCESS COMPLETION
|
|
188
|
-
//----
|
|
189
|
-
const prompts: AgenticaPrompt<Model>[] = [];
|
|
190
|
-
for (const choice of completion.choices) {
|
|
191
|
-
// TOOL CALLING HANDLER
|
|
192
|
-
if (choice.message.tool_calls)
|
|
193
|
-
for (const tc of choice.message.tool_calls) {
|
|
194
|
-
if (tc.type !== "function") continue;
|
|
195
|
-
|
|
196
|
-
const input: __IChatFunctionReference.IProps = JSON.parse(
|
|
197
|
-
tc.function.arguments,
|
|
198
|
-
);
|
|
199
|
-
if (typia.is(input) === false) continue;
|
|
200
|
-
else if (tc.function.name === "selectFunctions") {
|
|
201
|
-
const collection: AgenticaSelectPrompt<Model> =
|
|
202
|
-
new AgenticaSelectPrompt({
|
|
203
|
-
id: tc.id,
|
|
204
|
-
selections: [],
|
|
205
|
-
});
|
|
206
|
-
for (const reference of input.functions) {
|
|
207
|
-
const operation: AgenticaOperation<Model> | null =
|
|
208
|
-
await selectFunction(ctx, reference);
|
|
209
|
-
if (operation !== null)
|
|
210
|
-
collection.selections.push(
|
|
211
|
-
new AgenticaOperationSelection({
|
|
212
|
-
operation,
|
|
213
|
-
reason: reference.reason,
|
|
214
|
-
}),
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
if (collection.selections.length !== 0) prompts.push(collection);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// ASSISTANT MESSAGE
|
|
222
|
-
if (
|
|
223
|
-
choice.message.role === "assistant" &&
|
|
224
|
-
!!choice.message.content?.length
|
|
225
|
-
) {
|
|
226
|
-
const text: AgenticaTextPrompt = new AgenticaTextPrompt({
|
|
227
|
-
role: "assistant",
|
|
228
|
-
text: choice.message.content,
|
|
229
|
-
});
|
|
230
|
-
prompts.push(text);
|
|
231
|
-
await ctx.dispatch(
|
|
232
|
-
new AgenticaTextEvent({
|
|
233
|
-
role: "assistant",
|
|
234
|
-
stream: StreamUtil.to(text.text),
|
|
235
|
-
join: () => Promise.resolve(text.text),
|
|
236
|
-
done: () => true,
|
|
237
|
-
get: () => text.text,
|
|
238
|
-
}),
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return prompts;
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
const selectFunction = async <Model extends ILlmSchema.Model>(
|
|
246
|
-
ctx: AgenticaContext<Model>,
|
|
247
|
-
reference: __IChatFunctionReference,
|
|
248
|
-
): Promise<AgenticaOperation<Model> | null> => {
|
|
249
|
-
const operation: AgenticaOperation<Model> | undefined =
|
|
250
|
-
ctx.operations.flat.get(reference.name);
|
|
251
|
-
if (operation === undefined) return null;
|
|
252
|
-
|
|
253
|
-
const selection: AgenticaOperationSelection<Model> =
|
|
254
|
-
new AgenticaOperationSelection({
|
|
255
|
-
operation,
|
|
256
|
-
reason: reference.reason,
|
|
257
|
-
});
|
|
258
|
-
ctx.stack.push(selection);
|
|
259
|
-
void ctx.dispatch(
|
|
260
|
-
new AgenticaSelectEvent({
|
|
261
|
-
selection,
|
|
262
|
-
}),
|
|
263
|
-
);
|
|
264
|
-
return operation;
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const emendMessages = (
|
|
268
|
-
failures: IFailure[],
|
|
269
|
-
): OpenAI.ChatCompletionMessageParam[] =>
|
|
270
|
-
failures
|
|
271
|
-
.map((f) => [
|
|
272
|
-
{
|
|
273
|
-
role: "assistant",
|
|
274
|
-
tool_calls: [
|
|
275
|
-
{
|
|
276
|
-
type: "function",
|
|
277
|
-
id: f.id,
|
|
278
|
-
function: {
|
|
279
|
-
name: f.name,
|
|
280
|
-
arguments: JSON.stringify(f.validation.data),
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
],
|
|
284
|
-
} satisfies OpenAI.ChatCompletionAssistantMessageParam,
|
|
285
|
-
{
|
|
286
|
-
role: "tool",
|
|
287
|
-
content: JSON.stringify(f.validation.errors),
|
|
288
|
-
tool_call_id: f.id,
|
|
289
|
-
} satisfies OpenAI.ChatCompletionToolMessageParam,
|
|
290
|
-
{
|
|
291
|
-
role: "system",
|
|
292
|
-
content: [
|
|
293
|
-
"You A.I. assistant has composed wrong typed arguments.",
|
|
294
|
-
"",
|
|
295
|
-
"Correct it at the next function calling.",
|
|
296
|
-
].join("\n"),
|
|
297
|
-
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
298
|
-
])
|
|
299
|
-
.flat();
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const CONTAINER: ILlmApplication<"chatgpt"> = typia.llm.application<
|
|
303
|
-
__IChatSelectFunctionsApplication,
|
|
304
|
-
"chatgpt"
|
|
305
|
-
>();
|
|
306
|
-
|
|
307
|
-
interface IFailure {
|
|
308
|
-
id: string;
|
|
309
|
-
name: string;
|
|
310
|
-
validation: IValidation.IFailure;
|
|
311
|
-
}
|
|
1
|
+
import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
import typia, { IValidation } from "typia";
|
|
4
|
+
import { v4 } from "uuid";
|
|
5
|
+
|
|
6
|
+
import { AgenticaContext } from "../context/AgenticaContext";
|
|
7
|
+
import { AgenticaOperation } from "../context/AgenticaOperation";
|
|
8
|
+
import { AgenticaOperationSelection } from "../context/AgenticaOperationSelection";
|
|
9
|
+
import { __IChatFunctionReference } from "../context/internal/__IChatFunctionReference";
|
|
10
|
+
import { __IChatSelectFunctionsApplication } from "../context/internal/__IChatSelectFunctionsApplication";
|
|
11
|
+
import { AgenticaEvent } from "../events/AgenticaEvent";
|
|
12
|
+
import { AgenticaSelectEvent } from "../events/AgenticaSelectEvent";
|
|
13
|
+
import { AgenticaTextEvent } from "../events/AgenticaTextEvent";
|
|
14
|
+
import { AgenticaConstant } from "../internal/AgenticaConstant";
|
|
15
|
+
import { AgenticaDefaultPrompt } from "../internal/AgenticaDefaultPrompt";
|
|
16
|
+
import { AgenticaSystemPrompt } from "../internal/AgenticaSystemPrompt";
|
|
17
|
+
import { StreamUtil } from "../internal/StreamUtil";
|
|
18
|
+
import { AgenticaPrompt } from "../prompts/AgenticaPrompt";
|
|
19
|
+
import { AgenticaSelectPrompt } from "../prompts/AgenticaSelectPrompt";
|
|
20
|
+
import { AgenticaTextPrompt } from "../prompts/AgenticaTextPrompt";
|
|
21
|
+
import { ChatGptCompletionMessageUtil } from "./ChatGptCompletionMessageUtil";
|
|
22
|
+
import { ChatGptHistoryDecoder } from "./ChatGptHistoryDecoder";
|
|
23
|
+
|
|
24
|
+
export namespace ChatGptSelectFunctionAgent {
|
|
25
|
+
export const execute = async <Model extends ILlmSchema.Model>(
|
|
26
|
+
ctx: AgenticaContext<Model>,
|
|
27
|
+
): Promise<AgenticaPrompt<Model>[]> => {
|
|
28
|
+
if (ctx.operations.divided === undefined)
|
|
29
|
+
return step(ctx, ctx.operations.array, 0);
|
|
30
|
+
|
|
31
|
+
const stacks: AgenticaOperationSelection<Model>[][] =
|
|
32
|
+
ctx.operations.divided.map(() => []);
|
|
33
|
+
const events: AgenticaEvent<Model>[] = [];
|
|
34
|
+
const prompts: AgenticaPrompt<Model>[][] = await Promise.all(
|
|
35
|
+
ctx.operations.divided.map((operations, i) =>
|
|
36
|
+
step(
|
|
37
|
+
{
|
|
38
|
+
...ctx,
|
|
39
|
+
stack: stacks[i]!,
|
|
40
|
+
dispatch: async (e) => {
|
|
41
|
+
events.push(e);
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
operations,
|
|
45
|
+
0,
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// NO FUNCTION SELECTION, SO THAT ONLY TEXT LEFT
|
|
51
|
+
if (stacks.every((s) => s.length === 0)) return prompts[0]!;
|
|
52
|
+
// ELITICISM
|
|
53
|
+
else if ((ctx.config?.eliticism ?? AgenticaConstant.ELITICISM) === true)
|
|
54
|
+
return step(
|
|
55
|
+
ctx,
|
|
56
|
+
stacks
|
|
57
|
+
.flat()
|
|
58
|
+
.map(
|
|
59
|
+
(s) =>
|
|
60
|
+
ctx.operations.group
|
|
61
|
+
.get(s.operation.controller.name)!
|
|
62
|
+
.get(s.operation.function.name)!,
|
|
63
|
+
),
|
|
64
|
+
0,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// RE-COLLECT SELECT FUNCTION EVENTS
|
|
68
|
+
const collection: AgenticaSelectPrompt<Model> = new AgenticaSelectPrompt({
|
|
69
|
+
id: v4(),
|
|
70
|
+
selections: [],
|
|
71
|
+
});
|
|
72
|
+
for (const e of events)
|
|
73
|
+
if (e.type === "select") {
|
|
74
|
+
collection.selections.push(e.selection);
|
|
75
|
+
await selectFunction(ctx, {
|
|
76
|
+
name: e.selection.operation.name,
|
|
77
|
+
reason: e.selection.reason,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return [collection];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const step = async <Model extends ILlmSchema.Model>(
|
|
84
|
+
ctx: AgenticaContext<Model>,
|
|
85
|
+
operations: AgenticaOperation<Model>[],
|
|
86
|
+
retry: number,
|
|
87
|
+
failures?: IFailure[],
|
|
88
|
+
): Promise<AgenticaPrompt<Model>[]> => {
|
|
89
|
+
//----
|
|
90
|
+
// EXECUTE CHATGPT API
|
|
91
|
+
//----
|
|
92
|
+
const completionStream = await ctx.request("select", {
|
|
93
|
+
messages: [
|
|
94
|
+
// COMMON SYSTEM PROMPT
|
|
95
|
+
{
|
|
96
|
+
role: "system",
|
|
97
|
+
content: AgenticaDefaultPrompt.write(ctx.config),
|
|
98
|
+
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
99
|
+
// CANDIDATE FUNCTIONS
|
|
100
|
+
{
|
|
101
|
+
role: "assistant",
|
|
102
|
+
tool_calls: [
|
|
103
|
+
{
|
|
104
|
+
type: "function",
|
|
105
|
+
id: "getApiFunctions",
|
|
106
|
+
function: {
|
|
107
|
+
name: "getApiFunctions",
|
|
108
|
+
arguments: JSON.stringify({}),
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
role: "tool",
|
|
115
|
+
tool_call_id: "getApiFunctions",
|
|
116
|
+
content: JSON.stringify(
|
|
117
|
+
operations.map((op) => ({
|
|
118
|
+
name: op.name,
|
|
119
|
+
description: op.function.description,
|
|
120
|
+
...(op.protocol === "http"
|
|
121
|
+
? {
|
|
122
|
+
method: op.function.method,
|
|
123
|
+
path: op.function.path,
|
|
124
|
+
tags: op.function.tags,
|
|
125
|
+
}
|
|
126
|
+
: {}),
|
|
127
|
+
})),
|
|
128
|
+
),
|
|
129
|
+
},
|
|
130
|
+
// PREVIOUS HISTORIES
|
|
131
|
+
...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
|
|
132
|
+
// USER INPUT
|
|
133
|
+
{
|
|
134
|
+
role: "user",
|
|
135
|
+
content: ctx.prompt.text,
|
|
136
|
+
},
|
|
137
|
+
// SYSTEM PROMPT
|
|
138
|
+
{
|
|
139
|
+
role: "system",
|
|
140
|
+
content:
|
|
141
|
+
ctx.config?.systemPrompt?.select?.(ctx.histories) ??
|
|
142
|
+
AgenticaSystemPrompt.SELECT,
|
|
143
|
+
},
|
|
144
|
+
// TYPE CORRECTIONS
|
|
145
|
+
...emendMessages(failures ?? []),
|
|
146
|
+
],
|
|
147
|
+
// STACK FUNCTIONS
|
|
148
|
+
tools: CONTAINER.functions.map(
|
|
149
|
+
(func) =>
|
|
150
|
+
({
|
|
151
|
+
type: "function",
|
|
152
|
+
function: {
|
|
153
|
+
name: func.name,
|
|
154
|
+
description: func.description,
|
|
155
|
+
parameters: func.parameters as any,
|
|
156
|
+
},
|
|
157
|
+
}) satisfies OpenAI.ChatCompletionTool,
|
|
158
|
+
),
|
|
159
|
+
tool_choice: "auto",
|
|
160
|
+
parallel_tool_calls: false,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const chunks = await StreamUtil.readAll(completionStream);
|
|
164
|
+
const completion = ChatGptCompletionMessageUtil.merge(chunks);
|
|
165
|
+
//----
|
|
166
|
+
// VALIDATION
|
|
167
|
+
//----
|
|
168
|
+
if (retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY)) {
|
|
169
|
+
const failures: IFailure[] = [];
|
|
170
|
+
for (const choice of completion.choices)
|
|
171
|
+
for (const tc of choice.message.tool_calls ?? []) {
|
|
172
|
+
if (tc.function.name !== "selectFunctions") continue;
|
|
173
|
+
const input: object = JSON.parse(tc.function.arguments);
|
|
174
|
+
const validation: IValidation<__IChatFunctionReference.IProps> =
|
|
175
|
+
typia.validate<__IChatFunctionReference.IProps>(input);
|
|
176
|
+
if (validation.success === false)
|
|
177
|
+
failures.push({
|
|
178
|
+
id: tc.id,
|
|
179
|
+
name: tc.function.name,
|
|
180
|
+
validation,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (failures.length > 0) return step(ctx, operations, retry, failures);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
//----
|
|
187
|
+
// PROCESS COMPLETION
|
|
188
|
+
//----
|
|
189
|
+
const prompts: AgenticaPrompt<Model>[] = [];
|
|
190
|
+
for (const choice of completion.choices) {
|
|
191
|
+
// TOOL CALLING HANDLER
|
|
192
|
+
if (choice.message.tool_calls)
|
|
193
|
+
for (const tc of choice.message.tool_calls) {
|
|
194
|
+
if (tc.type !== "function") continue;
|
|
195
|
+
|
|
196
|
+
const input: __IChatFunctionReference.IProps = JSON.parse(
|
|
197
|
+
tc.function.arguments,
|
|
198
|
+
);
|
|
199
|
+
if (typia.is(input) === false) continue;
|
|
200
|
+
else if (tc.function.name === "selectFunctions") {
|
|
201
|
+
const collection: AgenticaSelectPrompt<Model> =
|
|
202
|
+
new AgenticaSelectPrompt({
|
|
203
|
+
id: tc.id,
|
|
204
|
+
selections: [],
|
|
205
|
+
});
|
|
206
|
+
for (const reference of input.functions) {
|
|
207
|
+
const operation: AgenticaOperation<Model> | null =
|
|
208
|
+
await selectFunction(ctx, reference);
|
|
209
|
+
if (operation !== null)
|
|
210
|
+
collection.selections.push(
|
|
211
|
+
new AgenticaOperationSelection({
|
|
212
|
+
operation,
|
|
213
|
+
reason: reference.reason,
|
|
214
|
+
}),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
if (collection.selections.length !== 0) prompts.push(collection);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ASSISTANT MESSAGE
|
|
222
|
+
if (
|
|
223
|
+
choice.message.role === "assistant" &&
|
|
224
|
+
!!choice.message.content?.length
|
|
225
|
+
) {
|
|
226
|
+
const text: AgenticaTextPrompt = new AgenticaTextPrompt({
|
|
227
|
+
role: "assistant",
|
|
228
|
+
text: choice.message.content,
|
|
229
|
+
});
|
|
230
|
+
prompts.push(text);
|
|
231
|
+
await ctx.dispatch(
|
|
232
|
+
new AgenticaTextEvent({
|
|
233
|
+
role: "assistant",
|
|
234
|
+
stream: StreamUtil.to(text.text),
|
|
235
|
+
join: () => Promise.resolve(text.text),
|
|
236
|
+
done: () => true,
|
|
237
|
+
get: () => text.text,
|
|
238
|
+
}),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return prompts;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const selectFunction = async <Model extends ILlmSchema.Model>(
|
|
246
|
+
ctx: AgenticaContext<Model>,
|
|
247
|
+
reference: __IChatFunctionReference,
|
|
248
|
+
): Promise<AgenticaOperation<Model> | null> => {
|
|
249
|
+
const operation: AgenticaOperation<Model> | undefined =
|
|
250
|
+
ctx.operations.flat.get(reference.name);
|
|
251
|
+
if (operation === undefined) return null;
|
|
252
|
+
|
|
253
|
+
const selection: AgenticaOperationSelection<Model> =
|
|
254
|
+
new AgenticaOperationSelection({
|
|
255
|
+
operation,
|
|
256
|
+
reason: reference.reason,
|
|
257
|
+
});
|
|
258
|
+
ctx.stack.push(selection);
|
|
259
|
+
void ctx.dispatch(
|
|
260
|
+
new AgenticaSelectEvent({
|
|
261
|
+
selection,
|
|
262
|
+
}),
|
|
263
|
+
);
|
|
264
|
+
return operation;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const emendMessages = (
|
|
268
|
+
failures: IFailure[],
|
|
269
|
+
): OpenAI.ChatCompletionMessageParam[] =>
|
|
270
|
+
failures
|
|
271
|
+
.map((f) => [
|
|
272
|
+
{
|
|
273
|
+
role: "assistant",
|
|
274
|
+
tool_calls: [
|
|
275
|
+
{
|
|
276
|
+
type: "function",
|
|
277
|
+
id: f.id,
|
|
278
|
+
function: {
|
|
279
|
+
name: f.name,
|
|
280
|
+
arguments: JSON.stringify(f.validation.data),
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
} satisfies OpenAI.ChatCompletionAssistantMessageParam,
|
|
285
|
+
{
|
|
286
|
+
role: "tool",
|
|
287
|
+
content: JSON.stringify(f.validation.errors),
|
|
288
|
+
tool_call_id: f.id,
|
|
289
|
+
} satisfies OpenAI.ChatCompletionToolMessageParam,
|
|
290
|
+
{
|
|
291
|
+
role: "system",
|
|
292
|
+
content: [
|
|
293
|
+
"You A.I. assistant has composed wrong typed arguments.",
|
|
294
|
+
"",
|
|
295
|
+
"Correct it at the next function calling.",
|
|
296
|
+
].join("\n"),
|
|
297
|
+
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
298
|
+
])
|
|
299
|
+
.flat();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const CONTAINER: ILlmApplication<"chatgpt"> = typia.llm.application<
|
|
303
|
+
__IChatSelectFunctionsApplication,
|
|
304
|
+
"chatgpt"
|
|
305
|
+
>();
|
|
306
|
+
|
|
307
|
+
interface IFailure {
|
|
308
|
+
id: string;
|
|
309
|
+
name: string;
|
|
310
|
+
validation: IValidation.IFailure;
|
|
311
|
+
}
|