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