@agentica/core 0.7.0-dev.20250224
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 -0
- package/README.md +464 -0
- package/lib/Agentica.d.ts +124 -0
- package/lib/Agentica.js +271 -0
- package/lib/Agentica.js.map +1 -0
- package/lib/chatgpt/ChatGptAgent.d.ts +6 -0
- package/lib/chatgpt/ChatGptAgent.js +59 -0
- package/lib/chatgpt/ChatGptAgent.js.map +1 -0
- package/lib/chatgpt/ChatGptCallFunctionAgent.d.ts +5 -0
- package/lib/chatgpt/ChatGptCallFunctionAgent.js +362 -0
- package/lib/chatgpt/ChatGptCallFunctionAgent.js.map +1 -0
- package/lib/chatgpt/ChatGptCancelFunctionAgent.d.ts +8 -0
- package/lib/chatgpt/ChatGptCancelFunctionAgent.js +359 -0
- package/lib/chatgpt/ChatGptCancelFunctionAgent.js.map +1 -0
- package/lib/chatgpt/ChatGptDescribeFunctionAgent.d.ts +5 -0
- package/lib/chatgpt/ChatGptDescribeFunctionAgent.js +56 -0
- package/lib/chatgpt/ChatGptDescribeFunctionAgent.js.map +1 -0
- package/lib/chatgpt/ChatGptHistoryDecoder.d.ts +5 -0
- package/lib/chatgpt/ChatGptHistoryDecoder.js +77 -0
- package/lib/chatgpt/ChatGptHistoryDecoder.js.map +1 -0
- package/lib/chatgpt/ChatGptInitializeFunctionAgent.d.ts +5 -0
- package/lib/chatgpt/ChatGptInitializeFunctionAgent.js +1883 -0
- package/lib/chatgpt/ChatGptInitializeFunctionAgent.js.map +1 -0
- package/lib/chatgpt/ChatGptSelectFunctionAgent.d.ts +5 -0
- package/lib/chatgpt/ChatGptSelectFunctionAgent.js +381 -0
- package/lib/chatgpt/ChatGptSelectFunctionAgent.js.map +1 -0
- package/lib/functional/createHttpLlmApplication.d.ts +33 -0
- package/lib/functional/createHttpLlmApplication.js +7766 -0
- package/lib/functional/createHttpLlmApplication.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +35 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +10366 -0
- package/lib/index.mjs.map +1 -0
- package/lib/internal/AgenticaConstant.d.ts +4 -0
- package/lib/internal/AgenticaConstant.js +9 -0
- package/lib/internal/AgenticaConstant.js.map +1 -0
- package/lib/internal/AgenticaCostAggregator.d.ts +5 -0
- package/lib/internal/AgenticaCostAggregator.js +30 -0
- package/lib/internal/AgenticaCostAggregator.js.map +1 -0
- package/lib/internal/AgenticaDefaultPrompt.d.ts +4 -0
- package/lib/internal/AgenticaDefaultPrompt.js +32 -0
- package/lib/internal/AgenticaDefaultPrompt.js.map +1 -0
- package/lib/internal/AgenticaOperationComposer.d.ts +9 -0
- package/lib/internal/AgenticaOperationComposer.js +58 -0
- package/lib/internal/AgenticaOperationComposer.js.map +1 -0
- package/lib/internal/AgenticaPromptFactory.d.ts +6 -0
- package/lib/internal/AgenticaPromptFactory.js +9 -0
- package/lib/internal/AgenticaPromptFactory.js.map +1 -0
- package/lib/internal/AgenticaPromptTransformer.d.ts +9 -0
- package/lib/internal/AgenticaPromptTransformer.js +58 -0
- package/lib/internal/AgenticaPromptTransformer.js.map +1 -0
- package/lib/internal/AgenticaSystemPrompt.d.ts +8 -0
- package/lib/internal/AgenticaSystemPrompt.js +13 -0
- package/lib/internal/AgenticaSystemPrompt.js.map +1 -0
- package/lib/internal/MathUtil.d.ts +3 -0
- package/lib/internal/MathUtil.js +8 -0
- package/lib/internal/MathUtil.js.map +1 -0
- package/lib/internal/Singleton.d.ts +1 -0
- package/lib/internal/Singleton.js +23 -0
- package/lib/internal/Singleton.js.map +1 -0
- package/lib/internal/__map_take.d.ts +1 -0
- package/lib/internal/__map_take.js +16 -0
- package/lib/internal/__map_take.js.map +1 -0
- package/lib/structures/IAgenticaConfig.d.ts +112 -0
- package/lib/structures/IAgenticaConfig.js +3 -0
- package/lib/structures/IAgenticaConfig.js.map +1 -0
- package/lib/structures/IAgenticaContext.d.ts +106 -0
- package/lib/structures/IAgenticaContext.js +3 -0
- package/lib/structures/IAgenticaContext.js.map +1 -0
- package/lib/structures/IAgenticaController.d.ts +110 -0
- package/lib/structures/IAgenticaController.js +3 -0
- package/lib/structures/IAgenticaController.js.map +1 -0
- package/lib/structures/IAgenticaEvent.d.ts +191 -0
- package/lib/structures/IAgenticaEvent.js +3 -0
- package/lib/structures/IAgenticaEvent.js.map +1 -0
- package/lib/structures/IAgenticaExecutor.d.ts +144 -0
- package/lib/structures/IAgenticaExecutor.js +3 -0
- package/lib/structures/IAgenticaExecutor.js.map +1 -0
- package/lib/structures/IAgenticaOperation.d.ts +48 -0
- package/lib/structures/IAgenticaOperation.js +3 -0
- package/lib/structures/IAgenticaOperation.js.map +1 -0
- package/lib/structures/IAgenticaOperationCollection.d.ts +46 -0
- package/lib/structures/IAgenticaOperationCollection.js +3 -0
- package/lib/structures/IAgenticaOperationCollection.js.map +1 -0
- package/lib/structures/IAgenticaOperationSelection.d.ts +51 -0
- package/lib/structures/IAgenticaOperationSelection.js +3 -0
- package/lib/structures/IAgenticaOperationSelection.js.map +1 -0
- package/lib/structures/IAgenticaPrompt.d.ts +139 -0
- package/lib/structures/IAgenticaPrompt.js +3 -0
- package/lib/structures/IAgenticaPrompt.js.map +1 -0
- package/lib/structures/IAgenticaProps.d.ts +59 -0
- package/lib/structures/IAgenticaProps.js +3 -0
- package/lib/structures/IAgenticaProps.js.map +1 -0
- package/lib/structures/IAgenticaProvider.d.ts +41 -0
- package/lib/structures/IAgenticaProvider.js +3 -0
- package/lib/structures/IAgenticaProvider.js.map +1 -0
- package/lib/structures/IAgenticaSystemPrompt.d.ts +116 -0
- package/lib/structures/IAgenticaSystemPrompt.js +3 -0
- package/lib/structures/IAgenticaSystemPrompt.js.map +1 -0
- package/lib/structures/IAgenticaTokenUsage.d.ts +50 -0
- package/lib/structures/IAgenticaTokenUsage.js +3 -0
- package/lib/structures/IAgenticaTokenUsage.js.map +1 -0
- package/lib/structures/internal/__IChatCancelFunctionsApplication.d.ts +22 -0
- package/lib/structures/internal/__IChatCancelFunctionsApplication.js +3 -0
- package/lib/structures/internal/__IChatCancelFunctionsApplication.js.map +1 -0
- package/lib/structures/internal/__IChatFunctionReference.d.ts +20 -0
- package/lib/structures/internal/__IChatFunctionReference.js +3 -0
- package/lib/structures/internal/__IChatFunctionReference.js.map +1 -0
- package/lib/structures/internal/__IChatInitialApplication.d.ts +14 -0
- package/lib/structures/internal/__IChatInitialApplication.js +3 -0
- package/lib/structures/internal/__IChatInitialApplication.js.map +1 -0
- package/lib/structures/internal/__IChatSelectFunctionsApplication.d.ts +23 -0
- package/lib/structures/internal/__IChatSelectFunctionsApplication.js +3 -0
- package/lib/structures/internal/__IChatSelectFunctionsApplication.js.map +1 -0
- package/lib/typings/AgenticaSource.d.ts +1 -0
- package/lib/typings/AgenticaSource.js +3 -0
- package/lib/typings/AgenticaSource.js.map +1 -0
- package/package.json +74 -0
- package/prompts/cancel.md +5 -0
- package/prompts/common.md +3 -0
- package/prompts/describe.md +7 -0
- package/prompts/execute.md +7 -0
- package/prompts/initialize.md +3 -0
- package/prompts/select.md +7 -0
- package/src/Agentica.ts +322 -0
- package/src/chatgpt/ChatGptAgent.ts +71 -0
- package/src/chatgpt/ChatGptCallFunctionAgent.ts +445 -0
- package/src/chatgpt/ChatGptCancelFunctionAgent.ts +283 -0
- package/src/chatgpt/ChatGptDescribeFunctionAgent.ts +51 -0
- package/src/chatgpt/ChatGptHistoryDecoder.ts +86 -0
- package/src/chatgpt/ChatGptInitializeFunctionAgent.ts +88 -0
- package/src/chatgpt/ChatGptSelectFunctionAgent.ts +316 -0
- package/src/functional/createHttpLlmApplication.ts +63 -0
- package/src/index.ts +19 -0
- package/src/internal/AgenticaConstant.ts +4 -0
- package/src/internal/AgenticaCostAggregator.ts +35 -0
- package/src/internal/AgenticaDefaultPrompt.ts +39 -0
- package/src/internal/AgenticaOperationComposer.ts +82 -0
- package/src/internal/AgenticaPromptFactory.ts +30 -0
- package/src/internal/AgenticaPromptTransformer.ts +83 -0
- package/src/internal/AgenticaSystemPrompt.ts +14 -0
- package/src/internal/MathUtil.ts +3 -0
- package/src/internal/Singleton.ts +22 -0
- package/src/internal/__map_take.ts +15 -0
- package/src/structures/IAgenticaConfig.ts +121 -0
- package/src/structures/IAgenticaContext.ts +128 -0
- package/src/structures/IAgenticaController.ts +130 -0
- package/src/structures/IAgenticaEvent.ts +224 -0
- package/src/structures/IAgenticaExecutor.ts +152 -0
- package/src/structures/IAgenticaOperation.ts +64 -0
- package/src/structures/IAgenticaOperationCollection.ts +50 -0
- package/src/structures/IAgenticaOperationSelection.ts +69 -0
- package/src/structures/IAgenticaPrompt.ts +173 -0
- package/src/structures/IAgenticaProps.ts +64 -0
- package/src/structures/IAgenticaProvider.ts +45 -0
- package/src/structures/IAgenticaSystemPrompt.ts +122 -0
- package/src/structures/IAgenticaTokenUsage.ts +52 -0
- package/src/structures/internal/__IChatCancelFunctionsApplication.ts +23 -0
- package/src/structures/internal/__IChatFunctionReference.ts +21 -0
- package/src/structures/internal/__IChatInitialApplication.ts +15 -0
- package/src/structures/internal/__IChatSelectFunctionsApplication.ts +24 -0
- package/src/typings/AgenticaSource.ts +6 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { IHttpLlmFunction, ILlmApplication } from "@samchon/openapi";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
import typia, { IValidation } from "typia";
|
|
4
|
+
import { v4 } from "uuid";
|
|
5
|
+
|
|
6
|
+
import { AgenticaConstant } from "../internal/AgenticaConstant";
|
|
7
|
+
import { AgenticaDefaultPrompt } from "../internal/AgenticaDefaultPrompt";
|
|
8
|
+
import { AgenticaPromptFactory } from "../internal/AgenticaPromptFactory";
|
|
9
|
+
import { AgenticaSystemPrompt } from "../internal/AgenticaSystemPrompt";
|
|
10
|
+
import { IAgenticaContext } from "../structures/IAgenticaContext";
|
|
11
|
+
import { IAgenticaController } from "../structures/IAgenticaController";
|
|
12
|
+
import { IAgenticaEvent } from "../structures/IAgenticaEvent";
|
|
13
|
+
import { IAgenticaOperation } from "../structures/IAgenticaOperation";
|
|
14
|
+
import { IAgenticaOperationSelection } from "../structures/IAgenticaOperationSelection";
|
|
15
|
+
import { IAgenticaPrompt } from "../structures/IAgenticaPrompt";
|
|
16
|
+
import { __IChatFunctionReference } from "../structures/internal/__IChatFunctionReference";
|
|
17
|
+
import { __IChatSelectFunctionsApplication } from "../structures/internal/__IChatSelectFunctionsApplication";
|
|
18
|
+
import { ChatGptHistoryDecoder } from "./ChatGptHistoryDecoder";
|
|
19
|
+
|
|
20
|
+
export namespace ChatGptSelectFunctionAgent {
|
|
21
|
+
export const execute = async (
|
|
22
|
+
ctx: IAgenticaContext,
|
|
23
|
+
): Promise<IAgenticaPrompt[]> => {
|
|
24
|
+
if (ctx.operations.divided === undefined)
|
|
25
|
+
return step(ctx, ctx.operations.array, 0);
|
|
26
|
+
|
|
27
|
+
const stacks: IAgenticaOperationSelection[][] = ctx.operations.divided.map(
|
|
28
|
+
() => [],
|
|
29
|
+
);
|
|
30
|
+
const events: IAgenticaEvent[] = [];
|
|
31
|
+
const prompts: IAgenticaPrompt[][] = await Promise.all(
|
|
32
|
+
ctx.operations.divided.map((operations, i) =>
|
|
33
|
+
step(
|
|
34
|
+
{
|
|
35
|
+
...ctx,
|
|
36
|
+
stack: stacks[i]!,
|
|
37
|
+
dispatch: async (e) => {
|
|
38
|
+
events.push(e);
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
operations,
|
|
42
|
+
0,
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// NO FUNCTION SELECTION, SO THAT ONLY TEXT LEFT
|
|
48
|
+
if (stacks.every((s) => s.length === 0)) return prompts[0]!;
|
|
49
|
+
// ELITICISM
|
|
50
|
+
else if ((ctx.config?.eliticism ?? AgenticaConstant.ELITICISM) === true)
|
|
51
|
+
return step(
|
|
52
|
+
ctx,
|
|
53
|
+
stacks
|
|
54
|
+
.flat()
|
|
55
|
+
.map(
|
|
56
|
+
(s) =>
|
|
57
|
+
ctx.operations.group
|
|
58
|
+
.get(s.controller.name)!
|
|
59
|
+
.get(s.function.name)!,
|
|
60
|
+
),
|
|
61
|
+
0,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// RE-COLLECT SELECT FUNCTION EVENTS
|
|
65
|
+
const collection: IAgenticaPrompt.ISelect = {
|
|
66
|
+
id: v4(),
|
|
67
|
+
type: "select",
|
|
68
|
+
operations: [],
|
|
69
|
+
};
|
|
70
|
+
for (const e of events)
|
|
71
|
+
if (e.type === "select") {
|
|
72
|
+
collection.operations.push(
|
|
73
|
+
AgenticaPromptFactory.selection({
|
|
74
|
+
protocol: e.operation.protocol as "http",
|
|
75
|
+
controller: e.operation.controller as IAgenticaController.IHttp,
|
|
76
|
+
function: e.operation.function as IHttpLlmFunction<"chatgpt">,
|
|
77
|
+
reason: e.reason,
|
|
78
|
+
name: e.operation.name,
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
await selectFunction(ctx, {
|
|
82
|
+
name: e.operation.name,
|
|
83
|
+
reason: e.reason,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return [collection];
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const step = async (
|
|
90
|
+
ctx: IAgenticaContext,
|
|
91
|
+
operations: IAgenticaOperation[],
|
|
92
|
+
retry: number,
|
|
93
|
+
failures?: IFailure[],
|
|
94
|
+
): Promise<IAgenticaPrompt[]> => {
|
|
95
|
+
//----
|
|
96
|
+
// EXECUTE CHATGPT API
|
|
97
|
+
//----
|
|
98
|
+
const completion: OpenAI.ChatCompletion = await ctx.request("select", {
|
|
99
|
+
messages: [
|
|
100
|
+
// COMMON SYSTEM PROMPT
|
|
101
|
+
{
|
|
102
|
+
role: "system",
|
|
103
|
+
content: AgenticaDefaultPrompt.write(ctx.config),
|
|
104
|
+
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
105
|
+
// CANDIDATE FUNCTIONS
|
|
106
|
+
{
|
|
107
|
+
role: "assistant",
|
|
108
|
+
tool_calls: [
|
|
109
|
+
{
|
|
110
|
+
type: "function",
|
|
111
|
+
id: "getApiFunctions",
|
|
112
|
+
function: {
|
|
113
|
+
name: "getApiFunctions",
|
|
114
|
+
arguments: JSON.stringify({}),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
role: "tool",
|
|
121
|
+
tool_call_id: "getApiFunctions",
|
|
122
|
+
content: JSON.stringify(
|
|
123
|
+
operations.map((op) => ({
|
|
124
|
+
name: op.name,
|
|
125
|
+
description: op.function.description,
|
|
126
|
+
...(op.protocol === "http"
|
|
127
|
+
? {
|
|
128
|
+
method: op.function.method,
|
|
129
|
+
path: op.function.path,
|
|
130
|
+
tags: op.function.tags,
|
|
131
|
+
}
|
|
132
|
+
: {}),
|
|
133
|
+
})),
|
|
134
|
+
),
|
|
135
|
+
},
|
|
136
|
+
// PREVIOUS HISTORIES
|
|
137
|
+
...ctx.histories.map(ChatGptHistoryDecoder.decode).flat(),
|
|
138
|
+
// USER INPUT
|
|
139
|
+
{
|
|
140
|
+
role: "user",
|
|
141
|
+
content: ctx.prompt.text,
|
|
142
|
+
},
|
|
143
|
+
// SYSTEM PROMPT
|
|
144
|
+
{
|
|
145
|
+
role: "system",
|
|
146
|
+
content: AgenticaSystemPrompt.SELECT,
|
|
147
|
+
},
|
|
148
|
+
// TYPE CORRECTIONS
|
|
149
|
+
...emendMessages(failures ?? []),
|
|
150
|
+
],
|
|
151
|
+
// STACK FUNCTIONS
|
|
152
|
+
tools: CONTAINER.functions.map(
|
|
153
|
+
(func) =>
|
|
154
|
+
({
|
|
155
|
+
type: "function",
|
|
156
|
+
function: {
|
|
157
|
+
name: func.name,
|
|
158
|
+
description: func.description,
|
|
159
|
+
parameters: func.parameters as any,
|
|
160
|
+
},
|
|
161
|
+
}) satisfies OpenAI.ChatCompletionTool,
|
|
162
|
+
),
|
|
163
|
+
tool_choice: "auto",
|
|
164
|
+
parallel_tool_calls: false,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
//----
|
|
168
|
+
// VALIDATION
|
|
169
|
+
//----
|
|
170
|
+
if (retry++ < (ctx.config?.retry ?? AgenticaConstant.RETRY)) {
|
|
171
|
+
const failures: IFailure[] = [];
|
|
172
|
+
for (const choice of completion.choices)
|
|
173
|
+
for (const tc of choice.message.tool_calls ?? []) {
|
|
174
|
+
if (tc.function.name !== "selectFunctions") continue;
|
|
175
|
+
const input: object = JSON.parse(tc.function.arguments);
|
|
176
|
+
const validation: IValidation<__IChatFunctionReference.IProps> =
|
|
177
|
+
typia.validate<__IChatFunctionReference.IProps>(input);
|
|
178
|
+
if (validation.success === false)
|
|
179
|
+
failures.push({
|
|
180
|
+
id: tc.id,
|
|
181
|
+
name: tc.function.name,
|
|
182
|
+
validation,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (failures.length > 0) return step(ctx, operations, retry, failures);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
//----
|
|
189
|
+
// PROCESS COMPLETION
|
|
190
|
+
//----
|
|
191
|
+
const prompts: IAgenticaPrompt[] = [];
|
|
192
|
+
for (const choice of completion.choices) {
|
|
193
|
+
// TOOL CALLING HANDLER
|
|
194
|
+
if (choice.message.tool_calls)
|
|
195
|
+
for (const tc of choice.message.tool_calls) {
|
|
196
|
+
if (tc.type !== "function") continue;
|
|
197
|
+
|
|
198
|
+
const input: __IChatFunctionReference.IProps = JSON.parse(
|
|
199
|
+
tc.function.arguments,
|
|
200
|
+
);
|
|
201
|
+
if (typia.is(input) === false) continue;
|
|
202
|
+
else if (tc.function.name === "selectFunctions") {
|
|
203
|
+
const collection: IAgenticaPrompt.ISelect = {
|
|
204
|
+
id: tc.id,
|
|
205
|
+
type: "select",
|
|
206
|
+
operations: [],
|
|
207
|
+
};
|
|
208
|
+
for (const reference of input.functions) {
|
|
209
|
+
const operation: IAgenticaOperation | null = await selectFunction(
|
|
210
|
+
ctx,
|
|
211
|
+
reference,
|
|
212
|
+
);
|
|
213
|
+
if (operation !== null)
|
|
214
|
+
collection.operations.push(
|
|
215
|
+
AgenticaPromptFactory.selection({
|
|
216
|
+
protocol: operation.protocol as "http",
|
|
217
|
+
controller:
|
|
218
|
+
operation.controller as IAgenticaController.IHttp,
|
|
219
|
+
function: operation.function as IHttpLlmFunction<"chatgpt">,
|
|
220
|
+
name: operation.name,
|
|
221
|
+
reason: reference.reason,
|
|
222
|
+
}),
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
if (collection.operations.length !== 0) prompts.push(collection);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ASSISTANT MESSAGE
|
|
230
|
+
if (
|
|
231
|
+
choice.message.role === "assistant" &&
|
|
232
|
+
!!choice.message.content?.length
|
|
233
|
+
) {
|
|
234
|
+
const text: IAgenticaPrompt.IText = {
|
|
235
|
+
type: "text",
|
|
236
|
+
role: "assistant",
|
|
237
|
+
text: choice.message.content,
|
|
238
|
+
};
|
|
239
|
+
prompts.push(text);
|
|
240
|
+
await ctx.dispatch(text);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return prompts;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const selectFunction = async (
|
|
247
|
+
ctx: IAgenticaContext,
|
|
248
|
+
reference: __IChatFunctionReference,
|
|
249
|
+
): Promise<IAgenticaOperation | null> => {
|
|
250
|
+
const operation: IAgenticaOperation | undefined = ctx.operations.flat.get(
|
|
251
|
+
reference.name,
|
|
252
|
+
);
|
|
253
|
+
if (operation === undefined) return null;
|
|
254
|
+
|
|
255
|
+
ctx.stack.push(
|
|
256
|
+
AgenticaPromptFactory.selection({
|
|
257
|
+
protocol: operation.protocol as "http",
|
|
258
|
+
controller: operation.controller as IAgenticaController.IHttp,
|
|
259
|
+
function: operation.function as IHttpLlmFunction<"chatgpt">,
|
|
260
|
+
name: reference.name,
|
|
261
|
+
reason: reference.reason,
|
|
262
|
+
}),
|
|
263
|
+
);
|
|
264
|
+
await ctx.dispatch({
|
|
265
|
+
type: "select",
|
|
266
|
+
reason: reference.reason,
|
|
267
|
+
operation,
|
|
268
|
+
});
|
|
269
|
+
return operation;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const emendMessages = (
|
|
273
|
+
failures: IFailure[],
|
|
274
|
+
): OpenAI.ChatCompletionMessageParam[] =>
|
|
275
|
+
failures
|
|
276
|
+
.map((f) => [
|
|
277
|
+
{
|
|
278
|
+
role: "assistant",
|
|
279
|
+
tool_calls: [
|
|
280
|
+
{
|
|
281
|
+
type: "function",
|
|
282
|
+
id: f.id,
|
|
283
|
+
function: {
|
|
284
|
+
name: f.name,
|
|
285
|
+
arguments: JSON.stringify(f.validation.data),
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
} satisfies OpenAI.ChatCompletionAssistantMessageParam,
|
|
290
|
+
{
|
|
291
|
+
role: "tool",
|
|
292
|
+
content: JSON.stringify(f.validation.errors),
|
|
293
|
+
tool_call_id: f.id,
|
|
294
|
+
} satisfies OpenAI.ChatCompletionToolMessageParam,
|
|
295
|
+
{
|
|
296
|
+
role: "system",
|
|
297
|
+
content: [
|
|
298
|
+
"You A.I. assistant has composed wrong typed arguments.",
|
|
299
|
+
"",
|
|
300
|
+
"Correct it at the next function calling.",
|
|
301
|
+
].join("\n"),
|
|
302
|
+
} satisfies OpenAI.ChatCompletionSystemMessageParam,
|
|
303
|
+
])
|
|
304
|
+
.flat();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const CONTAINER: ILlmApplication<"chatgpt"> = typia.llm.application<
|
|
308
|
+
__IChatSelectFunctionsApplication,
|
|
309
|
+
"chatgpt"
|
|
310
|
+
>();
|
|
311
|
+
|
|
312
|
+
interface IFailure {
|
|
313
|
+
id: string;
|
|
314
|
+
name: string;
|
|
315
|
+
validation: IValidation.IFailure;
|
|
316
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HttpLlm,
|
|
3
|
+
IHttpLlmApplication,
|
|
4
|
+
OpenApi,
|
|
5
|
+
OpenApiV3,
|
|
6
|
+
OpenApiV3_1,
|
|
7
|
+
SwaggerV2,
|
|
8
|
+
} from "@samchon/openapi";
|
|
9
|
+
import typia, { IValidation } from "typia";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create an HTTP LLM application instance.
|
|
13
|
+
*
|
|
14
|
+
* Create an {@link IHttpLlmApplication} instance which represents
|
|
15
|
+
* the LLM (Large Language Model) function calling application schema
|
|
16
|
+
* from the given Swagger/OpenAPI document and the target LLM model.
|
|
17
|
+
*
|
|
18
|
+
* By the way, even though this `createHttpLlmApplication` function
|
|
19
|
+
* supports every version of Swagger/OpenAPI specification, there can
|
|
20
|
+
* be a type error in the given document. In that case, the function
|
|
21
|
+
* will return {@link IValidation.IFailure} instance with detailed
|
|
22
|
+
* type error tracing information.
|
|
23
|
+
*
|
|
24
|
+
* @param props Properties to create the HTTP LLM application instance
|
|
25
|
+
* @returns Validation result of the HTTP LLM application composition
|
|
26
|
+
* @author Samchon
|
|
27
|
+
*/
|
|
28
|
+
export const createHttpLlmApplication = (props: {
|
|
29
|
+
/**
|
|
30
|
+
* Target LLM model.
|
|
31
|
+
*/
|
|
32
|
+
model: "chatgpt";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Swagger/OpenAPI document.
|
|
36
|
+
*/
|
|
37
|
+
document:
|
|
38
|
+
| SwaggerV2.IDocument
|
|
39
|
+
| OpenApiV3.IDocument
|
|
40
|
+
| OpenApiV3_1.IDocument
|
|
41
|
+
| OpenApi.IDocument;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Options for the LLM function calling schema composition.
|
|
45
|
+
*/
|
|
46
|
+
options?: Partial<IHttpLlmApplication.IOptions<"chatgpt">>;
|
|
47
|
+
}): IValidation<IHttpLlmApplication<"chatgpt">> => {
|
|
48
|
+
const inspect: IValidation<
|
|
49
|
+
| SwaggerV2.IDocument
|
|
50
|
+
| OpenApiV3.IDocument
|
|
51
|
+
| OpenApiV3_1.IDocument
|
|
52
|
+
| OpenApi.IDocument
|
|
53
|
+
> = typia.validate(props.document);
|
|
54
|
+
if (inspect.success === false) return inspect;
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
data: HttpLlm.application({
|
|
58
|
+
model: props.model,
|
|
59
|
+
document: OpenApi.convert(props.document),
|
|
60
|
+
options: props.options,
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// TYPES
|
|
2
|
+
export * from "./structures/IAgenticaConfig";
|
|
3
|
+
export * from "./structures/IAgenticaContext";
|
|
4
|
+
export * from "./structures/IAgenticaController";
|
|
5
|
+
export * from "./structures/IAgenticaEvent";
|
|
6
|
+
export * from "./structures/IAgenticaExecutor";
|
|
7
|
+
export * from "./structures/IAgenticaOperation";
|
|
8
|
+
export * from "./structures/IAgenticaOperationCollection";
|
|
9
|
+
export * from "./structures/IAgenticaOperationSelection";
|
|
10
|
+
export * from "./structures/IAgenticaPrompt";
|
|
11
|
+
export * from "./structures/IAgenticaProps";
|
|
12
|
+
export * from "./structures/IAgenticaProvider";
|
|
13
|
+
export * from "./structures/IAgenticaSystemPrompt";
|
|
14
|
+
export * from "./structures/IAgenticaTokenUsage";
|
|
15
|
+
export * from "./typings/AgenticaSource";
|
|
16
|
+
|
|
17
|
+
// FACADE CLASS
|
|
18
|
+
export * from "./functional/createHttpLlmApplication";
|
|
19
|
+
export * from "./Agentica";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
|
|
3
|
+
import { IAgenticaTokenUsage } from "../structures/IAgenticaTokenUsage";
|
|
4
|
+
|
|
5
|
+
export namespace AgenticaCostAggregator {
|
|
6
|
+
export const aggregate = (
|
|
7
|
+
cost: IAgenticaTokenUsage,
|
|
8
|
+
completion: OpenAI.ChatCompletion,
|
|
9
|
+
): void => {
|
|
10
|
+
if (!completion.usage) return;
|
|
11
|
+
|
|
12
|
+
// TOTAL
|
|
13
|
+
cost.total += completion.usage.total_tokens;
|
|
14
|
+
|
|
15
|
+
// PROMPT
|
|
16
|
+
cost.prompt.total += completion.usage.prompt_tokens;
|
|
17
|
+
cost.prompt.audio +=
|
|
18
|
+
completion.usage.prompt_tokens_details?.audio_tokens ?? 0;
|
|
19
|
+
cost.prompt.cached +=
|
|
20
|
+
completion.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
21
|
+
|
|
22
|
+
// COMPLETION
|
|
23
|
+
cost.completion.total += completion.usage.total_tokens;
|
|
24
|
+
cost.completion.accepted_prediction +=
|
|
25
|
+
completion.usage.completion_tokens_details?.accepted_prediction_tokens ??
|
|
26
|
+
0;
|
|
27
|
+
cost.completion.audio +=
|
|
28
|
+
completion.usage.completion_tokens_details?.audio_tokens ?? 0;
|
|
29
|
+
cost.completion.reasoning +=
|
|
30
|
+
completion.usage.completion_tokens_details?.reasoning_tokens ?? 0;
|
|
31
|
+
cost.completion.rejected_prediction +=
|
|
32
|
+
completion.usage.completion_tokens_details?.rejected_prediction_tokens ??
|
|
33
|
+
0;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { IAgenticaConfig } from "../structures/IAgenticaConfig";
|
|
2
|
+
import { AgenticaSystemPrompt } from "./AgenticaSystemPrompt";
|
|
3
|
+
import { Singleton } from "./Singleton";
|
|
4
|
+
|
|
5
|
+
export namespace AgenticaDefaultPrompt {
|
|
6
|
+
export const write = (config?: IAgenticaConfig): string => {
|
|
7
|
+
if (config?.systemPrompt?.common)
|
|
8
|
+
return config?.systemPrompt?.common(config);
|
|
9
|
+
|
|
10
|
+
const locale: string = config?.locale ?? getLocale.get();
|
|
11
|
+
const timezone: string = config?.timezone ?? getTimezone.get();
|
|
12
|
+
|
|
13
|
+
return AgenticaSystemPrompt.COMMON.replace("${locale}", locale).replace(
|
|
14
|
+
"${timezone}",
|
|
15
|
+
timezone,
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const getLocale = new Singleton(() =>
|
|
21
|
+
isNode.get()
|
|
22
|
+
? (process.env.LANG?.split(".")[0] ?? "en-US")
|
|
23
|
+
: navigator.language,
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const getTimezone = new Singleton(
|
|
27
|
+
() => Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const isNode = new Singleton(() => {
|
|
31
|
+
const isObject = (obj: any) => typeof obj === "object" && obj !== null;
|
|
32
|
+
return (
|
|
33
|
+
typeof global === "object" &&
|
|
34
|
+
isObject(global) &&
|
|
35
|
+
isObject(global.process) &&
|
|
36
|
+
isObject(global.process.versions) &&
|
|
37
|
+
typeof global.process.versions.node !== "undefined"
|
|
38
|
+
);
|
|
39
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { IAgenticaConfig } from "../structures/IAgenticaConfig";
|
|
2
|
+
import { IAgenticaController } from "../structures/IAgenticaController";
|
|
3
|
+
import { IAgenticaOperation } from "../structures/IAgenticaOperation";
|
|
4
|
+
import { IAgenticaOperationCollection } from "../structures/IAgenticaOperationCollection";
|
|
5
|
+
import { __map_take } from "./__map_take";
|
|
6
|
+
|
|
7
|
+
export namespace AgenticaOperationComposer {
|
|
8
|
+
export const compose = (props: {
|
|
9
|
+
controllers: IAgenticaController[];
|
|
10
|
+
config?: IAgenticaConfig | undefined;
|
|
11
|
+
}): IAgenticaOperationCollection => {
|
|
12
|
+
const unique: boolean =
|
|
13
|
+
props.controllers.length === 1 ||
|
|
14
|
+
(() => {
|
|
15
|
+
const names: string[] = props.controllers
|
|
16
|
+
.map((controller) =>
|
|
17
|
+
controller.application.functions.map((func) => func.name),
|
|
18
|
+
)
|
|
19
|
+
.flat();
|
|
20
|
+
return new Set(names).size === names.length;
|
|
21
|
+
})();
|
|
22
|
+
const naming = (func: string, ci: number) =>
|
|
23
|
+
unique ? func : `_${ci}_${func}`;
|
|
24
|
+
|
|
25
|
+
const array: IAgenticaOperation[] = props.controllers
|
|
26
|
+
.map((controller, ci) =>
|
|
27
|
+
controller.protocol === "http"
|
|
28
|
+
? controller.application.functions.map(
|
|
29
|
+
(func) =>
|
|
30
|
+
({
|
|
31
|
+
protocol: "http",
|
|
32
|
+
controller,
|
|
33
|
+
function: func,
|
|
34
|
+
name: naming(func.name, ci),
|
|
35
|
+
}) satisfies IAgenticaOperation.IHttp,
|
|
36
|
+
)
|
|
37
|
+
: controller.application.functions.map(
|
|
38
|
+
(func) =>
|
|
39
|
+
({
|
|
40
|
+
protocol: "class",
|
|
41
|
+
controller,
|
|
42
|
+
function: func,
|
|
43
|
+
name: naming(func.name, ci),
|
|
44
|
+
}) satisfies IAgenticaOperation.IClass,
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
.flat();
|
|
48
|
+
const divided: IAgenticaOperation[][] | undefined =
|
|
49
|
+
!!props.config?.capacity && array.length > props.config.capacity
|
|
50
|
+
? divideOperations({
|
|
51
|
+
array,
|
|
52
|
+
capacity: props.config.capacity,
|
|
53
|
+
})
|
|
54
|
+
: undefined;
|
|
55
|
+
|
|
56
|
+
const flat: Map<string, IAgenticaOperation> = new Map();
|
|
57
|
+
const group: Map<string, Map<string, IAgenticaOperation>> = new Map();
|
|
58
|
+
for (const item of array) {
|
|
59
|
+
flat.set(item.name, item);
|
|
60
|
+
__map_take(group, item.controller.name, () => new Map()).set(
|
|
61
|
+
item.name,
|
|
62
|
+
item,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
array,
|
|
67
|
+
divided,
|
|
68
|
+
flat,
|
|
69
|
+
group,
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const divideOperations = (props: {
|
|
74
|
+
array: IAgenticaOperation[];
|
|
75
|
+
capacity: number;
|
|
76
|
+
}): IAgenticaOperation[][] => {
|
|
77
|
+
const size: number = Math.ceil(props.array.length / props.capacity);
|
|
78
|
+
const capacity: number = Math.ceil(props.array.length / size);
|
|
79
|
+
const replica: IAgenticaOperation[] = props.array.slice();
|
|
80
|
+
return new Array(size).fill(0).map(() => replica.splice(0, capacity));
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { IAgenticaOperationSelection } from "../structures/IAgenticaOperationSelection";
|
|
2
|
+
import { IAgenticaPrompt } from "../structures/IAgenticaPrompt";
|
|
3
|
+
|
|
4
|
+
export namespace AgenticaPromptFactory {
|
|
5
|
+
export const execute = (
|
|
6
|
+
props: Omit<IAgenticaPrompt.IExecute, "toJSON">,
|
|
7
|
+
): IAgenticaPrompt.IExecute =>
|
|
8
|
+
({
|
|
9
|
+
...props,
|
|
10
|
+
toJSON: () =>
|
|
11
|
+
({
|
|
12
|
+
...props,
|
|
13
|
+
controller: props.controller.name,
|
|
14
|
+
function: props.function.name,
|
|
15
|
+
}) as any,
|
|
16
|
+
}) as IAgenticaPrompt.IExecute;
|
|
17
|
+
|
|
18
|
+
export const selection = (
|
|
19
|
+
props: Omit<IAgenticaOperationSelection, "toJSON">,
|
|
20
|
+
): IAgenticaOperationSelection =>
|
|
21
|
+
({
|
|
22
|
+
...props,
|
|
23
|
+
toJSON: () =>
|
|
24
|
+
({
|
|
25
|
+
...props,
|
|
26
|
+
controller: props.controller.name,
|
|
27
|
+
function: props.function.name,
|
|
28
|
+
}) as any,
|
|
29
|
+
}) as IAgenticaOperationSelection;
|
|
30
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Primitive } from "typia";
|
|
2
|
+
|
|
3
|
+
import { IAgenticaOperation } from "../structures/IAgenticaOperation";
|
|
4
|
+
import { IAgenticaPrompt } from "../structures/IAgenticaPrompt";
|
|
5
|
+
import { AgenticaPromptFactory } from "./AgenticaPromptFactory";
|
|
6
|
+
|
|
7
|
+
export namespace AgenticaPromptTransformer {
|
|
8
|
+
export const transform = (props: {
|
|
9
|
+
operations: Map<string, Map<string, IAgenticaOperation>>;
|
|
10
|
+
input: Primitive<IAgenticaPrompt>;
|
|
11
|
+
}): IAgenticaPrompt => {
|
|
12
|
+
// TEXT
|
|
13
|
+
if (props.input.type === "text") return props.input;
|
|
14
|
+
// SELECT & CANCEL
|
|
15
|
+
else if (props.input.type === "select" || props.input.type === "cancel")
|
|
16
|
+
return {
|
|
17
|
+
...props.input,
|
|
18
|
+
operations: props.input.operations.map((func) =>
|
|
19
|
+
AgenticaPromptFactory.selection({
|
|
20
|
+
...findOperation({
|
|
21
|
+
operations: props.operations,
|
|
22
|
+
input: func,
|
|
23
|
+
}),
|
|
24
|
+
reason: func.reason,
|
|
25
|
+
}),
|
|
26
|
+
),
|
|
27
|
+
} satisfies IAgenticaPrompt.ISelect | IAgenticaPrompt.ICancel;
|
|
28
|
+
// EXECUTE
|
|
29
|
+
else if (props.input.type === "execute")
|
|
30
|
+
return transformExecute({
|
|
31
|
+
operations: props.operations,
|
|
32
|
+
input: props.input,
|
|
33
|
+
}) satisfies IAgenticaPrompt.IExecute;
|
|
34
|
+
// DESCRIBE
|
|
35
|
+
return {
|
|
36
|
+
type: "describe",
|
|
37
|
+
text: props.input.text,
|
|
38
|
+
executions: props.input.executions.map((next) =>
|
|
39
|
+
transformExecute({
|
|
40
|
+
operations: props.operations,
|
|
41
|
+
input: next,
|
|
42
|
+
}),
|
|
43
|
+
),
|
|
44
|
+
} satisfies IAgenticaPrompt.IDescribe;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const transformExecute = (props: {
|
|
48
|
+
operations: Map<string, Map<string, IAgenticaOperation>>;
|
|
49
|
+
input: Primitive<IAgenticaPrompt.IExecute>;
|
|
50
|
+
}): IAgenticaPrompt.IExecute => {
|
|
51
|
+
const operation = findOperation({
|
|
52
|
+
operations: props.operations,
|
|
53
|
+
input: props.input,
|
|
54
|
+
});
|
|
55
|
+
return AgenticaPromptFactory.execute({
|
|
56
|
+
type: "execute",
|
|
57
|
+
protocol: operation.protocol as "http",
|
|
58
|
+
controller: operation.controller,
|
|
59
|
+
function: operation.function,
|
|
60
|
+
id: props.input.id,
|
|
61
|
+
name: props.input.name,
|
|
62
|
+
arguments: props.input.arguments,
|
|
63
|
+
value: props.input.value,
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const findOperation = (props: {
|
|
68
|
+
operations: Map<string, Map<string, IAgenticaOperation>>;
|
|
69
|
+
input: {
|
|
70
|
+
controller: string;
|
|
71
|
+
function: string;
|
|
72
|
+
};
|
|
73
|
+
}): IAgenticaOperation.IHttp => {
|
|
74
|
+
const found: IAgenticaOperation | undefined = props.operations
|
|
75
|
+
.get(props.input.controller)
|
|
76
|
+
?.get(props.input.function);
|
|
77
|
+
if (found === undefined)
|
|
78
|
+
throw new Error(
|
|
79
|
+
`No operation found: (controller: ${props.input.controller}, function: ${props.input.function})`,
|
|
80
|
+
);
|
|
81
|
+
return found as IAgenticaOperation.IHttp;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export namespace AgenticaSystemPrompt {
|
|
2
|
+
export const CANCEL =
|
|
3
|
+
"You are a helpful assistant for cancelling functions which are prepared to call.\n\nUse the supplied tools to select some functions to cancel of `getApiFunctions()` returned.\n\nIf you can't find any proper function to select, don't talk, don't do anything.";
|
|
4
|
+
export const COMMON =
|
|
5
|
+
"At first, the user's language locale code is \"${locale}\". When you are conversating with the user or describing the function calling result, consider it and always translate to the target locale language. Never conversate with different locale language text with the user.\n\nAt second, the user's timezone is \"${timezone}\", and ISO datetime is ${datetime}. When you are conversating with the user, consider current time and user belonged timezone.";
|
|
6
|
+
export const DESCRIBE =
|
|
7
|
+
"You are a helpful assistant describing return values of function calls.\n\nAbove messages are the list of function call histories. When describing the return values, please do not too much shortly summarize them. Instead, provide detailed descriptions as much as.\n\nAlso, its content format must be markdown. If required, utilize the mermaid syntax for drawing some diagrams. When image contents are, just put them through the markdown image syntax.\n\nAt last, if user's language locale code is different with your description, please translate it to the user's language.";
|
|
8
|
+
export const EXECUTE =
|
|
9
|
+
"You are a helpful assistant for tool calling.\n\nUse the supplied tools to assist the user.\n\nIf previous messages are not enough to compose the arguments, you can ask the user to write more information. By the way, when asking the user to write more information, make the text concise and clear.\n\nFor reference, in the \"tool\" role message content, the `function` property means metadata of the API operation. In other words, it is the function schema describing its purpose, parameters and return value types. And then the `data` property is the return value from the target function calling.";
|
|
10
|
+
export const INITIALIZE =
|
|
11
|
+
"You are a helpful assistant.\n\nUse the supplied tools to assist the user.";
|
|
12
|
+
export const SELECT =
|
|
13
|
+
"You are a helpful assistant for selecting functions to call.\n\nUse the supplied tools to select some functions of `getApiFunctions()` returned.\n\nWhen selecting functions to call, pay attention to the relationship between functions. In particular, check the prerequisites between each function.\n\nIf you can't find any proper function to select, just type your own message. By the way, when typing your own message, please consider the user's language locale code. If your message is different with the user's language, please translate it to the user's.";
|
|
14
|
+
}
|