@agentica/core 0.29.6 → 0.30.1
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 +231 -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 +198 -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 +272 -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),
|
|
@@ -164,275 +134,162 @@ async function station<Model extends ILlmSchema.Model>(
|
|
|
164
134
|
return executes;
|
|
165
135
|
}
|
|
166
136
|
|
|
167
|
-
async function
|
|
137
|
+
async function predicate<Model extends ILlmSchema.Model>(
|
|
168
138
|
ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
139
|
+
operation: AgenticaOperation<Model>,
|
|
140
|
+
toolCall: OpenAI.ChatCompletionMessageToolCall,
|
|
141
|
+
previousValidationErrors: AgenticaValidateEvent<Model>[],
|
|
142
|
+
life: number,
|
|
172
143
|
): 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
|
-
}
|
|
144
|
+
// CHECK INPUT ARGUMENT
|
|
145
|
+
const call: AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model>
|
|
146
|
+
= parseArguments(
|
|
147
|
+
operation,
|
|
148
|
+
toolCall,
|
|
149
|
+
);
|
|
150
|
+
ctx.dispatch(call);
|
|
151
|
+
if (call.type === "jsonParseError") {
|
|
152
|
+
return correctJsonError(ctx, call, previousValidationErrors, life - 1);
|
|
193
153
|
}
|
|
194
|
-
}
|
|
195
154
|
|
|
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
|
-
);
|
|
155
|
+
// CHECK TYPE VALIDATION
|
|
156
|
+
const check: IValidation<unknown> = operation.function.validate(call.arguments);
|
|
212
157
|
if (check.success === false) {
|
|
213
|
-
const
|
|
214
|
-
id:
|
|
215
|
-
operation
|
|
158
|
+
const event: AgenticaValidateEvent<Model> = createValidateEvent({
|
|
159
|
+
id: toolCall.id,
|
|
160
|
+
operation,
|
|
216
161
|
result: check,
|
|
217
162
|
});
|
|
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
|
-
})
|
|
163
|
+
ctx.dispatch(event);
|
|
164
|
+
return correctTypeError(
|
|
165
|
+
ctx,
|
|
166
|
+
call,
|
|
167
|
+
event,
|
|
168
|
+
[...previousValidationErrors, event],
|
|
169
|
+
life - 1,
|
|
261
170
|
);
|
|
262
171
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
172
|
+
|
|
173
|
+
// EXECUTE OPERATION
|
|
174
|
+
const execute: AgenticaExecuteEvent<Model> = await executeFunction(call, operation);
|
|
175
|
+
ctx.dispatch(execute);
|
|
176
|
+
return execute;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* -----------------------------------------------------------
|
|
180
|
+
ERROR CORRECTORS
|
|
181
|
+
----------------------------------------------------------- */
|
|
182
|
+
async function correctTypeError<Model extends ILlmSchema.Model>(
|
|
183
|
+
ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
|
|
184
|
+
callEvent: AgenticaCallEvent<Model>,
|
|
185
|
+
validateEvent: AgenticaValidateEvent<Model>,
|
|
186
|
+
previousValidationErrors: AgenticaValidateEvent<Model>[],
|
|
187
|
+
life: number,
|
|
188
|
+
): Promise<AgenticaExecuteEvent<Model>> {
|
|
189
|
+
return correctError<Model>(ctx, {
|
|
190
|
+
giveUp: () => createExecuteEvent({
|
|
191
|
+
operation: callEvent.operation,
|
|
192
|
+
arguments: callEvent.arguments,
|
|
268
193
|
value: {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
error instanceof Error
|
|
273
|
-
? {
|
|
274
|
-
...error,
|
|
275
|
-
name: error.name,
|
|
276
|
-
message: error.message,
|
|
277
|
-
}
|
|
278
|
-
: error,
|
|
194
|
+
name: "ValidationError",
|
|
195
|
+
message: `Invalid arguments. The validation failed after ${AgenticaConstant.RETRY} retries.`,
|
|
196
|
+
errors: validateEvent.result.errors,
|
|
279
197
|
},
|
|
280
|
-
})
|
|
281
|
-
|
|
198
|
+
}),
|
|
199
|
+
operation: callEvent.operation,
|
|
200
|
+
messageArguments: JSON.stringify(callEvent.arguments),
|
|
201
|
+
messageToolParam: {
|
|
202
|
+
role: "tool",
|
|
203
|
+
content: JSON.stringify(validateEvent.result.errors),
|
|
204
|
+
tool_call_id: callEvent.id,
|
|
205
|
+
} satisfies OpenAI.ChatCompletionToolMessageParam,
|
|
206
|
+
systemPrompt: ctx.config?.systemPrompt?.validate?.(previousValidationErrors.slice(0, -1))
|
|
207
|
+
?? [
|
|
208
|
+
AgenticaSystemPrompt.VALIDATE,
|
|
209
|
+
...(previousValidationErrors.length > 1
|
|
210
|
+
? [
|
|
211
|
+
"",
|
|
212
|
+
AgenticaSystemPrompt.VALIDATE_REPEATED.replace(
|
|
213
|
+
"${{HISTORICAL_ERRORS}}",
|
|
214
|
+
JSON.stringify(previousValidationErrors.slice(0, -1).map(e => e.result.errors)),
|
|
215
|
+
),
|
|
216
|
+
]
|
|
217
|
+
: []),
|
|
218
|
+
].join("\n"),
|
|
219
|
+
life,
|
|
220
|
+
previousValidationErrors,
|
|
221
|
+
});
|
|
282
222
|
}
|
|
283
223
|
|
|
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
|
-
}
|
|
224
|
+
async function correctJsonError<Model extends ILlmSchema.Model>(
|
|
225
|
+
ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
|
|
226
|
+
parseErrorEvent: AgenticaJsonParseErrorEvent<Model>,
|
|
227
|
+
previousValidationErrors: AgenticaValidateEvent<Model>[],
|
|
228
|
+
life: number,
|
|
229
|
+
): Promise<AgenticaExecuteEvent<Model>> {
|
|
230
|
+
return correctError<Model>(ctx, {
|
|
231
|
+
giveUp: () => createExecuteEvent({
|
|
232
|
+
operation: parseErrorEvent.operation,
|
|
233
|
+
arguments: {},
|
|
234
|
+
value: {
|
|
235
|
+
name: "JsonParseError",
|
|
236
|
+
message: `Invalid JSON format. The parsing failed after ${AgenticaConstant.RETRY} retries.`,
|
|
237
|
+
arguments: parseErrorEvent.arguments,
|
|
238
|
+
errorMessage: parseErrorEvent.errorMessage,
|
|
239
|
+
},
|
|
240
|
+
}),
|
|
241
|
+
operation: parseErrorEvent.operation,
|
|
242
|
+
messageArguments: parseErrorEvent.arguments,
|
|
243
|
+
messageToolParam: null,
|
|
244
|
+
systemPrompt: ctx.config?.systemPrompt?.jsonParseError?.(parseErrorEvent)
|
|
245
|
+
?? AgenticaSystemPrompt.JSON_PARSE_ERROR.replace(
|
|
246
|
+
"${{ERROR_MESSAGE}}",
|
|
247
|
+
parseErrorEvent.errorMessage,
|
|
248
|
+
),
|
|
249
|
+
life,
|
|
250
|
+
previousValidationErrors,
|
|
251
|
+
});
|
|
344
252
|
}
|
|
345
253
|
|
|
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
|
|
254
|
+
function parseArguments<Model extends ILlmSchema.Model>(
|
|
255
|
+
operation: AgenticaOperation<Model>,
|
|
256
|
+
toolCall: OpenAI.ChatCompletionMessageToolCall,
|
|
257
|
+
): AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model> {
|
|
357
258
|
try {
|
|
358
|
-
const
|
|
359
|
-
return
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
259
|
+
const data: Record<string, unknown> = JSON.parse(toolCall.function.arguments);
|
|
260
|
+
return createCallEvent({
|
|
261
|
+
id: toolCall.id,
|
|
262
|
+
operation,
|
|
263
|
+
arguments: data,
|
|
363
264
|
});
|
|
364
265
|
}
|
|
365
266
|
catch (error) {
|
|
366
|
-
return
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
? {
|
|
372
|
-
...error,
|
|
373
|
-
name: error.name,
|
|
374
|
-
message: error.message,
|
|
375
|
-
}
|
|
376
|
-
: error,
|
|
267
|
+
return createJsonParseErrorEvent({
|
|
268
|
+
id: toolCall.id,
|
|
269
|
+
operation,
|
|
270
|
+
arguments: toolCall.function.arguments,
|
|
271
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
377
272
|
});
|
|
378
273
|
}
|
|
379
274
|
}
|
|
380
275
|
|
|
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
|
-
});
|
|
276
|
+
async function correctError<Model extends ILlmSchema.Model>(
|
|
277
|
+
ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
|
|
278
|
+
props: {
|
|
279
|
+
giveUp: () => AgenticaExecuteEvent<Model>;
|
|
280
|
+
operation: AgenticaOperation<Model>;
|
|
281
|
+
messageArguments: string;
|
|
282
|
+
messageToolParam: null | OpenAI.ChatCompletionToolMessageParam;
|
|
283
|
+
systemPrompt: string;
|
|
284
|
+
life: number;
|
|
285
|
+
previousValidationErrors: AgenticaValidateEvent<Model>[];
|
|
286
|
+
},
|
|
287
|
+
): Promise<AgenticaExecuteEvent<Model>> {
|
|
288
|
+
if (props.life <= 0) {
|
|
289
|
+
return props.giveUp();
|
|
403
290
|
}
|
|
404
291
|
|
|
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", {
|
|
292
|
+
const stream: ReadableStream<OpenAI.ChatCompletionChunk> = await ctx.request("call", {
|
|
436
293
|
messages: [
|
|
437
294
|
// COMMON SYSTEM PROMPT
|
|
438
295
|
{
|
|
@@ -447,48 +304,31 @@ async function correct<Model extends ILlmSchema.Model>(
|
|
|
447
304
|
content: ctx.prompt.contents.map(decodeUserMessageContent),
|
|
448
305
|
},
|
|
449
306
|
// TYPE CORRECTION
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
:
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
?? AgenticaSystemPrompt.EXECUTE,
|
|
457
|
-
} satisfies OpenAI.ChatCompletionSystemMessageParam]
|
|
458
|
-
),
|
|
307
|
+
{
|
|
308
|
+
role: "system",
|
|
309
|
+
content:
|
|
310
|
+
ctx.config?.systemPrompt?.execute?.(ctx.histories as MicroAgenticaHistory<Model>[])
|
|
311
|
+
?? AgenticaSystemPrompt.EXECUTE,
|
|
312
|
+
},
|
|
459
313
|
{
|
|
460
314
|
role: "assistant",
|
|
461
315
|
tool_calls: [
|
|
462
316
|
{
|
|
463
317
|
type: "function",
|
|
464
|
-
id:
|
|
318
|
+
id: v4(),
|
|
465
319
|
function: {
|
|
466
|
-
name:
|
|
467
|
-
arguments:
|
|
320
|
+
name: props.operation.name,
|
|
321
|
+
arguments: props.messageArguments,
|
|
468
322
|
},
|
|
469
323
|
} satisfies OpenAI.ChatCompletionMessageToolCall,
|
|
470
324
|
],
|
|
471
325
|
} satisfies OpenAI.ChatCompletionAssistantMessageParam,
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
tool_call_id: call.id,
|
|
476
|
-
} satisfies OpenAI.ChatCompletionToolMessageParam,
|
|
326
|
+
...(props.messageToolParam !== null
|
|
327
|
+
? [props.messageToolParam]
|
|
328
|
+
: []),
|
|
477
329
|
{
|
|
478
330
|
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"),
|
|
331
|
+
content: props.systemPrompt,
|
|
492
332
|
},
|
|
493
333
|
],
|
|
494
334
|
// STACK FUNCTIONS
|
|
@@ -496,16 +336,16 @@ async function correct<Model extends ILlmSchema.Model>(
|
|
|
496
336
|
{
|
|
497
337
|
type: "function",
|
|
498
338
|
function: {
|
|
499
|
-
name:
|
|
500
|
-
description:
|
|
339
|
+
name: props.operation.name,
|
|
340
|
+
description: props.operation.function.description,
|
|
501
341
|
/**
|
|
502
342
|
* @TODO fix it
|
|
503
343
|
* The property and value have a type mismatch, but it works.
|
|
504
344
|
*/
|
|
505
345
|
parameters: (
|
|
506
|
-
("separated" in
|
|
507
|
-
&&
|
|
508
|
-
? (
|
|
346
|
+
("separated" in props.operation.function
|
|
347
|
+
&& props.operation.function.separated !== undefined)
|
|
348
|
+
? (props.operation.function.separated?.llm
|
|
509
349
|
?? ({
|
|
510
350
|
$defs: {},
|
|
511
351
|
type: "object",
|
|
@@ -514,79 +354,122 @@ async function correct<Model extends ILlmSchema.Model>(
|
|
|
514
354
|
required: [],
|
|
515
355
|
} satisfies IChatGptSchema.IParameters))
|
|
516
356
|
|
|
517
|
-
:
|
|
357
|
+
: props.operation.function.parameters) as unknown as Record<string, unknown>,
|
|
518
358
|
},
|
|
519
359
|
},
|
|
520
360
|
],
|
|
521
361
|
tool_choice: {
|
|
522
362
|
type: "function",
|
|
523
363
|
function: {
|
|
524
|
-
name:
|
|
364
|
+
name: props.operation.name,
|
|
525
365
|
},
|
|
526
366
|
},
|
|
527
367
|
// parallel_tool_calls: false,
|
|
528
368
|
});
|
|
369
|
+
const chunks: OpenAI.ChatCompletionChunk[] = await StreamUtil.readAll(stream);
|
|
370
|
+
const completion: OpenAI.ChatCompletion = ChatGptCompletionMessageUtil.merge(chunks);
|
|
529
371
|
|
|
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,
|
|
372
|
+
const toolCall: OpenAI.ChatCompletionMessageToolCall | undefined = completion.choices[0]?.message.tool_calls?.find(
|
|
373
|
+
s => s.function.name === props.operation.name,
|
|
554
374
|
);
|
|
375
|
+
return toolCall === undefined
|
|
376
|
+
? props.giveUp()
|
|
377
|
+
: predicate<Model>(
|
|
378
|
+
ctx,
|
|
379
|
+
props.operation,
|
|
380
|
+
toolCall,
|
|
381
|
+
props.previousValidationErrors,
|
|
382
|
+
props.life,
|
|
383
|
+
);
|
|
555
384
|
}
|
|
556
385
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
386
|
+
/* -----------------------------------------------------------
|
|
387
|
+
FUNCTION EXECUTORS
|
|
388
|
+
----------------------------------------------------------- */
|
|
389
|
+
async function executeFunction<Model extends ILlmSchema.Model>(
|
|
390
|
+
call: AgenticaCallEvent<Model>,
|
|
391
|
+
operation: AgenticaOperation<Model>,
|
|
392
|
+
): Promise<AgenticaExecuteEvent<Model>> {
|
|
393
|
+
try {
|
|
394
|
+
const value: unknown = await (async () => {
|
|
395
|
+
switch (operation.protocol) {
|
|
396
|
+
case "class":
|
|
397
|
+
return executeClassFunction(call, operation);
|
|
398
|
+
case "http":
|
|
399
|
+
return executeHttpOperation(call, operation);
|
|
400
|
+
case "mcp":
|
|
401
|
+
return executeMcpOperation(call, operation);
|
|
402
|
+
default:
|
|
403
|
+
operation satisfies never; // Ensure all cases are handled
|
|
404
|
+
throw new Error("Unknown protocol"); // never be happen
|
|
405
|
+
}
|
|
406
|
+
})();
|
|
407
|
+
return createExecuteEvent({
|
|
408
|
+
operation: call.operation,
|
|
409
|
+
arguments: call.arguments,
|
|
410
|
+
value,
|
|
411
|
+
});
|
|
563
412
|
}
|
|
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 = {};
|
|
413
|
+
catch (error) {
|
|
414
|
+
return createExecuteEvent({
|
|
415
|
+
operation: call.operation,
|
|
416
|
+
arguments: call.arguments,
|
|
417
|
+
value: error instanceof Error
|
|
418
|
+
? {
|
|
419
|
+
...error,
|
|
420
|
+
name: error.name,
|
|
421
|
+
message: error.message,
|
|
422
|
+
}
|
|
423
|
+
: error,
|
|
424
|
+
});
|
|
579
425
|
}
|
|
580
426
|
}
|
|
581
427
|
|
|
582
|
-
function
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
428
|
+
async function executeClassFunction<Model extends ILlmSchema.Model>(
|
|
429
|
+
call: AgenticaCallEvent<Model>,
|
|
430
|
+
operation: AgenticaOperation.Class<Model>,
|
|
431
|
+
): Promise<unknown> {
|
|
432
|
+
const execute = operation.controller.execute;
|
|
433
|
+
const value: unknown = typeof execute === "function"
|
|
434
|
+
? await execute({
|
|
435
|
+
application: operation.controller.application,
|
|
436
|
+
function: operation.function,
|
|
437
|
+
arguments: call.arguments,
|
|
438
|
+
})
|
|
439
|
+
: await (execute as Record<string, any>)[operation.function.name](
|
|
440
|
+
call.arguments,
|
|
441
|
+
);
|
|
442
|
+
return value;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function executeHttpOperation<Model extends ILlmSchema.Model>(
|
|
446
|
+
call: AgenticaCallEvent<Model>,
|
|
447
|
+
operation: AgenticaOperation.Http<Model>,
|
|
448
|
+
): Promise<unknown> {
|
|
449
|
+
const execute = operation.controller.execute;
|
|
450
|
+
const value: IHttpResponse = typeof execute === "function"
|
|
451
|
+
? await execute({
|
|
452
|
+
connection: operation.controller.connection,
|
|
453
|
+
application: operation.controller.application,
|
|
454
|
+
function: operation.function,
|
|
455
|
+
arguments: call.arguments,
|
|
456
|
+
})
|
|
457
|
+
: await HttpLlm.propagate({
|
|
458
|
+
connection: operation.controller.connection,
|
|
459
|
+
application: operation.controller.application,
|
|
460
|
+
function: operation.function,
|
|
461
|
+
input: call.arguments,
|
|
462
|
+
});
|
|
463
|
+
return value;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
async function executeMcpOperation<Model extends ILlmSchema.Model>(
|
|
467
|
+
call: AgenticaCallEvent<Model>,
|
|
468
|
+
operation: AgenticaOperation.Mcp<Model>,
|
|
469
|
+
): Promise<unknown> {
|
|
470
|
+
return operation.controller.client.callTool({
|
|
471
|
+
method: operation.function.name,
|
|
472
|
+
name: operation.function.name,
|
|
473
|
+
arguments: call.arguments,
|
|
474
|
+
}).then(v => v.content);
|
|
592
475
|
}
|