@agentica/core 0.16.8 → 0.17.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/Agentica.js +2 -2
- package/lib/Agentica.js.map +1 -1
- package/lib/MicroAgentica.js +2 -2
- package/lib/MicroAgentica.js.map +1 -1
- package/lib/context/AgenticaOperation.d.ts +4 -2
- package/lib/context/internal/AgenticaOperationComposer.d.ts +0 -9
- package/lib/context/internal/AgenticaOperationComposer.js +105 -35
- package/lib/context/internal/AgenticaOperationComposer.js.map +1 -1
- package/lib/context/internal/AgenticaOperationComposer.spec.d.ts +1 -0
- package/lib/context/internal/AgenticaOperationComposer.spec.js +266 -0
- package/lib/context/internal/AgenticaOperationComposer.spec.js.map +1 -0
- package/lib/events/AgenticaDescribeEvent.d.ts +1 -1
- package/lib/events/AgenticaResponseEvent.d.ts +1 -1
- package/lib/events/AgenticaTextEvent.d.ts +1 -1
- package/lib/factory/events.d.ts +3 -3
- package/lib/functional/assertHttpLlmApplication.js +31 -31
- package/lib/functional/assertMcpLlmApplication.d.ts +15 -0
- package/lib/functional/assertMcpLlmApplication.js +59 -0
- package/lib/functional/assertMcpLlmApplication.js.map +1 -0
- package/lib/functional/validateHttpLlmApplication.js +27 -27
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +435 -220
- package/lib/index.mjs.map +1 -1
- package/lib/json/IAgenticaOperationJson.d.ts +1 -1
- package/lib/orchestrate/call.js +205 -95
- package/lib/orchestrate/call.js.map +1 -1
- package/lib/orchestrate/describe.js +1 -1
- package/lib/orchestrate/describe.js.map +1 -1
- package/lib/orchestrate/initialize.js +61 -61
- 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/IAgenticaController.d.ts +9 -2
- package/lib/structures/mcp/IMcpLlmApplication.d.ts +15 -0
- package/lib/structures/mcp/IMcpLlmApplication.js +3 -0
- package/lib/structures/mcp/IMcpLlmApplication.js.map +1 -0
- package/lib/structures/mcp/IMcpLlmFunction.d.ts +17 -0
- package/lib/structures/mcp/IMcpLlmFunction.js +3 -0
- package/lib/structures/mcp/IMcpLlmFunction.js.map +1 -0
- package/lib/structures/mcp/IMcpLlmTransportProps.d.ts +11 -0
- package/lib/structures/mcp/IMcpLlmTransportProps.js +3 -0
- package/lib/structures/mcp/IMcpLlmTransportProps.js.map +1 -0
- package/lib/structures/mcp/index.d.ts +3 -0
- package/lib/structures/mcp/index.js +20 -0
- package/lib/structures/mcp/index.js.map +1 -0
- package/lib/transformers/AgenticaEventTransformer.js +2 -2
- package/lib/transformers/AgenticaEventTransformer.js.map +1 -1
- package/lib/utils/StreamUtil.d.ts +4 -2
- package/lib/utils/StreamUtil.js +58 -10
- package/lib/utils/StreamUtil.js.map +1 -1
- package/package.json +11 -6
- package/src/Agentica.ts +3 -3
- package/src/MicroAgentica.ts +3 -3
- package/src/context/AgenticaOperation.ts +9 -2
- package/src/context/internal/AgenticaOperationComposer.spec.ts +314 -0
- package/src/context/internal/AgenticaOperationComposer.ts +119 -49
- package/src/events/AgenticaDescribeEvent.ts +1 -1
- package/src/events/AgenticaResponseEvent.ts +1 -1
- package/src/events/AgenticaTextEvent.ts +1 -1
- package/src/factory/events.ts +3 -3
- package/src/functional/assertMcpLlmApplication.ts +48 -0
- package/src/index.ts +6 -2
- package/src/json/IAgenticaOperationJson.ts +1 -1
- package/src/orchestrate/call.ts +239 -137
- package/src/orchestrate/describe.ts +2 -2
- package/src/orchestrate/initialize.ts +2 -2
- package/src/orchestrate/select.ts +2 -2
- package/src/structures/IAgenticaController.ts +12 -2
- package/src/structures/mcp/IMcpLlmApplication.ts +17 -0
- package/src/structures/mcp/IMcpLlmFunction.ts +19 -0
- package/src/structures/mcp/IMcpLlmTransportProps.ts +13 -0
- package/src/structures/mcp/index.ts +3 -0
- package/src/transformers/AgenticaEventTransformer.ts +3 -3
- package/src/utils/StreamUtil.ts +18 -8
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import type { IHttpLlmFunction, ILlmFunction, IValidation } from "@samchon/openapi";
|
|
2
|
+
|
|
3
|
+
import type { IAgenticaConfig } from "../../structures/IAgenticaConfig";
|
|
4
|
+
import type { IAgenticaController } from "../../structures/IAgenticaController";
|
|
5
|
+
import type { IMcpLlmFunction } from "../../structures/mcp/IMcpLlmFunction";
|
|
6
|
+
|
|
7
|
+
import { compose, divide, getOperations, toClassOperations, toHttpOperations, toMcpOperations } from "./AgenticaOperationComposer";
|
|
8
|
+
|
|
9
|
+
// test helper functions
|
|
10
|
+
function createMockHttpFunction(name: string, method: "get" | "post" | "patch" | "put" | "delete", path: string): IHttpLlmFunction<any> {
|
|
11
|
+
return {
|
|
12
|
+
name,
|
|
13
|
+
method,
|
|
14
|
+
path,
|
|
15
|
+
validate: () => ({ success: true, data: {} } as IValidation<unknown>),
|
|
16
|
+
operation: () => ({}),
|
|
17
|
+
route: () => ({
|
|
18
|
+
method,
|
|
19
|
+
path,
|
|
20
|
+
emendedPath: path,
|
|
21
|
+
accessor: [name],
|
|
22
|
+
body: null,
|
|
23
|
+
query: null,
|
|
24
|
+
parameters: [],
|
|
25
|
+
headers: null,
|
|
26
|
+
success: null,
|
|
27
|
+
exceptions: {},
|
|
28
|
+
comment: () => "OK",
|
|
29
|
+
operation: () => ({}),
|
|
30
|
+
}),
|
|
31
|
+
parameters: {},
|
|
32
|
+
output: {},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function createMockHttpController(name: string, functions: IHttpLlmFunction<any>[]): IAgenticaController.IHttp<any> {
|
|
37
|
+
return {
|
|
38
|
+
name,
|
|
39
|
+
protocol: "http",
|
|
40
|
+
connection: { host: "https://example.com" },
|
|
41
|
+
application: {
|
|
42
|
+
model: "chatgpt",
|
|
43
|
+
options: {},
|
|
44
|
+
functions,
|
|
45
|
+
errors: [],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function createMockClassController(name: string, functions: ILlmFunction<any>[]): IAgenticaController.IClass<any> {
|
|
51
|
+
return {
|
|
52
|
+
name,
|
|
53
|
+
protocol: "class",
|
|
54
|
+
application: {
|
|
55
|
+
model: "chatgpt",
|
|
56
|
+
options: {},
|
|
57
|
+
functions,
|
|
58
|
+
},
|
|
59
|
+
execute: {},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function createMockMcpController(name: string, functions: IMcpLlmFunction[]): IAgenticaController.IMcp {
|
|
64
|
+
return {
|
|
65
|
+
name,
|
|
66
|
+
protocol: "mcp",
|
|
67
|
+
application: {
|
|
68
|
+
transport: {
|
|
69
|
+
type: "sse",
|
|
70
|
+
url: new URL("https://example.com"),
|
|
71
|
+
},
|
|
72
|
+
functions,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
describe("a AgenticaOperationComposer", () => {
|
|
78
|
+
describe("compose", () => {
|
|
79
|
+
it("should compose operations from controllers", () => {
|
|
80
|
+
// Mock controllers
|
|
81
|
+
const mockHttpController = createMockHttpController("httpController", [
|
|
82
|
+
createMockHttpFunction("function1", "get", "/api/function1"),
|
|
83
|
+
createMockHttpFunction("function2", "post", "/api/function2"),
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
const mockClassController = createMockClassController("classController", [
|
|
87
|
+
{
|
|
88
|
+
name: "function3",
|
|
89
|
+
validate: () => ({ success: true, data: {} } as IValidation<unknown>),
|
|
90
|
+
parameters: {},
|
|
91
|
+
output: {},
|
|
92
|
+
},
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
const mockMcpController = createMockMcpController("mcpController", [
|
|
96
|
+
{
|
|
97
|
+
name: "function4",
|
|
98
|
+
parameters: {},
|
|
99
|
+
},
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
const controllers = [mockHttpController, mockClassController, mockMcpController];
|
|
103
|
+
|
|
104
|
+
const result = compose({ controllers });
|
|
105
|
+
|
|
106
|
+
expect(result.array).toHaveLength(4);
|
|
107
|
+
expect(result.flat).toBeInstanceOf(Map);
|
|
108
|
+
expect(result.group).toBeInstanceOf(Map);
|
|
109
|
+
expect(result.divided).toBeUndefined();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should divide operations when capacity is provided", () => {
|
|
113
|
+
// Mock controllers
|
|
114
|
+
const mockController = createMockHttpController("httpController", [
|
|
115
|
+
createMockHttpFunction("function1", "get", "/api/function1"),
|
|
116
|
+
createMockHttpFunction("function2", "post", "/api/function2"),
|
|
117
|
+
createMockHttpFunction("function3", "put", "/api/function3"),
|
|
118
|
+
createMockHttpFunction("function4", "delete", "/api/function4"),
|
|
119
|
+
createMockHttpFunction("function5", "patch", "/api/function5"),
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
const config: IAgenticaConfig<any> = {
|
|
123
|
+
capacity: 2,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const result = compose({ controllers: [mockController], config });
|
|
127
|
+
|
|
128
|
+
expect(result.array).toHaveLength(5);
|
|
129
|
+
expect(result.divided).toBeDefined();
|
|
130
|
+
expect(result.divided).toHaveLength(3); // 5 items with capacity 2 should be divided into 3 groups
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("getOperations", () => {
|
|
135
|
+
it("should get operations from http controllers", () => {
|
|
136
|
+
const mockController = createMockHttpController("httpController", [
|
|
137
|
+
createMockHttpFunction("function1", "get", "/api/function1"),
|
|
138
|
+
createMockHttpFunction("function2", "post", "/api/function2"),
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
const result = getOperations({ controllers: [mockController], naming: (func, idx) => `_${idx}_${func}` });
|
|
142
|
+
|
|
143
|
+
expect(result).toHaveLength(2);
|
|
144
|
+
expect(result[0]?.protocol).toBe("http");
|
|
145
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
146
|
+
expect(result[1]?.name).toBe("_0_function2");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("should get operations from class controllers", () => {
|
|
150
|
+
const mockController = createMockClassController("classController", [
|
|
151
|
+
{
|
|
152
|
+
name: "function1",
|
|
153
|
+
validate: () => ({ success: true, data: {} } as IValidation<unknown>),
|
|
154
|
+
parameters: {},
|
|
155
|
+
output: {},
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
const result = getOperations({ controllers: [mockController], naming: (func, idx) => `_${idx}_${func}` });
|
|
160
|
+
|
|
161
|
+
expect(result).toHaveLength(1);
|
|
162
|
+
expect(result[0]?.protocol).toBe("class");
|
|
163
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should get operations from mcp controllers", () => {
|
|
167
|
+
const mockController = createMockMcpController("mcpController", [
|
|
168
|
+
{
|
|
169
|
+
name: "function1",
|
|
170
|
+
parameters: {},
|
|
171
|
+
},
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
const result = getOperations({ controllers: [mockController], naming: (func, idx) => `_${idx}_${func}` });
|
|
175
|
+
|
|
176
|
+
expect(result).toHaveLength(1);
|
|
177
|
+
expect(result[0]?.protocol).toBe("mcp");
|
|
178
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("should throw error for unsupported protocol", () => {
|
|
182
|
+
const mockController: IAgenticaController.IHttp<any> = {
|
|
183
|
+
name: "unsupportedController",
|
|
184
|
+
protocol: "unsupported" as unknown as "http",
|
|
185
|
+
connection: { host: "https://example.com" },
|
|
186
|
+
application: { } as unknown as IAgenticaController.IHttp<any>["application"],
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
expect(() => getOperations({ controllers: [mockController], naming: (func, idx) => `_${idx}_${func}` })).toThrow("Unsupported protocol: unsupported");
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("toHttpOperations", () => {
|
|
194
|
+
it("should convert http controller to operations", () => {
|
|
195
|
+
const mockController = createMockHttpController("httpController", [
|
|
196
|
+
createMockHttpFunction("function1", "get", "/api/function1"),
|
|
197
|
+
createMockHttpFunction("function2", "post", "/api/function2"),
|
|
198
|
+
]);
|
|
199
|
+
|
|
200
|
+
const result = toHttpOperations({ controller: mockController, index: 0, naming: (func, idx) => `_${idx}_${func}` });
|
|
201
|
+
|
|
202
|
+
expect(result).toHaveLength(2);
|
|
203
|
+
expect(result[0]?.protocol).toBe("http");
|
|
204
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
205
|
+
expect(result[1]?.name).toBe("_0_function2");
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe("toClassOperations", () => {
|
|
210
|
+
it("should convert class controller to operations", () => {
|
|
211
|
+
const mockController = createMockClassController("classController", [
|
|
212
|
+
{
|
|
213
|
+
name: "function1",
|
|
214
|
+
validate: () => ({ success: true, data: {} } as IValidation<unknown>),
|
|
215
|
+
parameters: {},
|
|
216
|
+
output: {},
|
|
217
|
+
},
|
|
218
|
+
]);
|
|
219
|
+
|
|
220
|
+
const result = toClassOperations({ controller: mockController, index: 0, naming: (func, idx) => `_${idx}_${func}` });
|
|
221
|
+
|
|
222
|
+
expect(result).toHaveLength(1);
|
|
223
|
+
expect(result[0]?.protocol).toBe("class");
|
|
224
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe("toMcpOperations", () => {
|
|
229
|
+
it("should convert mcp controller to operations", () => {
|
|
230
|
+
const mockController = createMockMcpController("mcpController", [
|
|
231
|
+
{
|
|
232
|
+
name: "function1",
|
|
233
|
+
parameters: {},
|
|
234
|
+
},
|
|
235
|
+
]);
|
|
236
|
+
|
|
237
|
+
const result = toMcpOperations({ controller: mockController, index: 0, naming: (func, idx) => `_${idx}_${func}` });
|
|
238
|
+
|
|
239
|
+
expect(result).toHaveLength(1);
|
|
240
|
+
expect(result[0]?.protocol).toBe("mcp");
|
|
241
|
+
expect(result[0]?.name).toBe("_0_function1");
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe("divide with invalid capacity", () => {
|
|
245
|
+
it("should throw error when capacity is 0", () => {
|
|
246
|
+
const array = [1, 2, 3, 4, 5];
|
|
247
|
+
const capacity = 0;
|
|
248
|
+
|
|
249
|
+
expect(() => divide({ array, capacity })).toThrow("Capacity must be a positive integer");
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("should throw error when capacity is negative", () => {
|
|
253
|
+
const array = [1, 2, 3, 4, 5];
|
|
254
|
+
const capacity = -3;
|
|
255
|
+
|
|
256
|
+
expect(() => divide({ array, capacity })).toThrow("Capacity must be a positive integer");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("should throw error when capacity is decimal", () => {
|
|
260
|
+
const array = [1, 2, 3, 4, 5];
|
|
261
|
+
const capacity = 2.5;
|
|
262
|
+
const result = divide({ array, capacity });
|
|
263
|
+
expect(result).toEqual([[1, 2, 3], [4, 5]]);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should throw error when capacity is Infinity", () => {
|
|
267
|
+
const array = [1, 2, 3, 4, 5];
|
|
268
|
+
const capacity = Infinity;
|
|
269
|
+
|
|
270
|
+
expect(() => divide({ array, capacity })).toThrow("Capacity must be a positive integer");
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it("should throw error when capacity is NaN", () => {
|
|
274
|
+
const array = [1, 2, 3, 4, 5];
|
|
275
|
+
const capacity = Number.NaN;
|
|
276
|
+
|
|
277
|
+
expect(() => divide({ array, capacity })).toThrow("Capacity must be a positive integer");
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
describe("divide", () => {
|
|
282
|
+
it("should divide array into chunks based on capacity", () => {
|
|
283
|
+
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
284
|
+
const capacity = 3;
|
|
285
|
+
|
|
286
|
+
const result = divide({ array, capacity });
|
|
287
|
+
|
|
288
|
+
expect(result).toHaveLength(4); // 10 items with capacity 3 should be divided into 4 groups
|
|
289
|
+
expect(result[0]).toEqual([1, 2, 3]);
|
|
290
|
+
expect(result[1]).toEqual([4, 5, 6]);
|
|
291
|
+
expect(result[2]).toEqual([7, 8, 9]);
|
|
292
|
+
expect(result[3]).toEqual([10]);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should handle empty array", () => {
|
|
296
|
+
const array: number[] = [];
|
|
297
|
+
const capacity = 3;
|
|
298
|
+
|
|
299
|
+
const result = divide({ array, capacity });
|
|
300
|
+
|
|
301
|
+
expect(result).toHaveLength(0);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("should handle array smaller than capacity", () => {
|
|
305
|
+
const array = [1, 2];
|
|
306
|
+
const capacity = 3;
|
|
307
|
+
|
|
308
|
+
const result = divide({ array, capacity });
|
|
309
|
+
|
|
310
|
+
expect(result).toHaveLength(1);
|
|
311
|
+
expect(result[0]).toEqual([1, 2]);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
});
|
|
@@ -8,59 +8,27 @@ import type { AgenticaOperationCollection } from "../AgenticaOperationCollection
|
|
|
8
8
|
|
|
9
9
|
import { __map_take } from "../../utils/__map_take";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Compose the agentica operation collection.
|
|
13
|
+
*
|
|
14
|
+
* Compose the {@link AgenticaOperationCollection} from the given
|
|
15
|
+
* controllers and config.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
11
19
|
export function compose<Model extends ILlmSchema.Model>(props: {
|
|
12
20
|
controllers: IAgenticaController<Model>[];
|
|
13
21
|
config?: IAgenticaConfig<Model> | IMicroAgenticaConfig<Model> | undefined;
|
|
14
22
|
}): AgenticaOperationCollection<Model> {
|
|
15
|
-
const unique: boolean
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.map(controller =>
|
|
20
|
-
controller.application.functions.map(func => func.name),
|
|
21
|
-
)
|
|
22
|
-
.flat();
|
|
23
|
-
return new Set(names).size === names.length;
|
|
24
|
-
})();
|
|
25
|
-
const naming = (func: string, ci: number) =>
|
|
26
|
-
unique ? func : `_${ci}_${func}`;
|
|
27
|
-
|
|
28
|
-
const array: AgenticaOperation<Model>[] = props.controllers
|
|
29
|
-
.map((controller, ci) =>
|
|
30
|
-
controller.protocol === "http"
|
|
31
|
-
? controller.application.functions.map(
|
|
32
|
-
func =>
|
|
33
|
-
({
|
|
34
|
-
protocol: "http",
|
|
35
|
-
controller,
|
|
36
|
-
function: func,
|
|
37
|
-
name: naming(func.name, ci),
|
|
38
|
-
toJSON: () => ({
|
|
39
|
-
protocol: "http",
|
|
40
|
-
controller: controller.name,
|
|
41
|
-
function: func.name,
|
|
42
|
-
name: naming(func.name, ci),
|
|
43
|
-
}),
|
|
44
|
-
}) satisfies AgenticaOperation.Http<Model>,
|
|
45
|
-
)
|
|
46
|
-
: controller.application.functions.map(
|
|
47
|
-
func =>
|
|
48
|
-
({
|
|
49
|
-
protocol: "class",
|
|
50
|
-
controller,
|
|
51
|
-
function: func,
|
|
52
|
-
name: naming(func.name, ci),
|
|
53
|
-
toJSON: () => ({
|
|
54
|
-
protocol: "class",
|
|
55
|
-
controller: controller.name,
|
|
56
|
-
function: func.name,
|
|
57
|
-
name: naming(func.name, ci),
|
|
58
|
-
}),
|
|
59
|
-
}) satisfies AgenticaOperation.Class<Model>,
|
|
60
|
-
),
|
|
61
|
-
)
|
|
62
|
-
.flat();
|
|
23
|
+
const unique: boolean = (props.controllers.length === 1 || (() => {
|
|
24
|
+
const names = props.controllers.map(controllers => controllers.application.functions.map(func => func.name)).flat();
|
|
25
|
+
return new Set(names).size === names.length;
|
|
26
|
+
})());
|
|
63
27
|
|
|
28
|
+
const array: AgenticaOperation<Model>[] = getOperations({
|
|
29
|
+
controllers: props.controllers,
|
|
30
|
+
naming: (func: string, controllerIndex: number) => unique ? func : `_${controllerIndex}_${func}`,
|
|
31
|
+
});
|
|
64
32
|
const capacity: number | undefined = (props.config as IAgenticaConfig<Model>)?.capacity;
|
|
65
33
|
const divided: AgenticaOperation<Model>[][] | undefined
|
|
66
34
|
= capacity !== undefined && array.length > capacity
|
|
@@ -87,10 +55,112 @@ export function compose<Model extends ILlmSchema.Model>(props: {
|
|
|
87
55
|
};
|
|
88
56
|
}
|
|
89
57
|
|
|
90
|
-
|
|
58
|
+
/**
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
export function getOperations<Model extends ILlmSchema.Model>(props: {
|
|
62
|
+
controllers: IAgenticaController<Model>[];
|
|
63
|
+
naming: (func: string, controllerIndex: number) => string;
|
|
64
|
+
}): AgenticaOperation<Model>[] {
|
|
65
|
+
return props.controllers.flatMap((controller, idx) => {
|
|
66
|
+
switch (controller.protocol) {
|
|
67
|
+
case "http":{
|
|
68
|
+
return toHttpOperations({ controller, index: idx, naming: props.naming }); }
|
|
69
|
+
case "class":{
|
|
70
|
+
return toClassOperations({ controller, index: idx, naming: props.naming }); }
|
|
71
|
+
case "mcp": {
|
|
72
|
+
return toMcpOperations({ controller, index: idx, naming: props.naming });
|
|
73
|
+
}
|
|
74
|
+
default:
|
|
75
|
+
controller satisfies never;
|
|
76
|
+
throw new Error(`Unsupported protocol: ${(controller as { protocol: string }).protocol}`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
export function toHttpOperations<Model extends ILlmSchema.Model>(props: {
|
|
85
|
+
controller: IAgenticaController.IHttp<Model>;
|
|
86
|
+
index: number;
|
|
87
|
+
naming: (func: string, controllerIndex: number) => string;
|
|
88
|
+
}): AgenticaOperation<Model>[] {
|
|
89
|
+
return props.controller.application.functions.map(func => ({
|
|
90
|
+
protocol: "http",
|
|
91
|
+
controller: props.controller,
|
|
92
|
+
function: func,
|
|
93
|
+
name: props.naming(func.name, props.index),
|
|
94
|
+
toJSON: () => ({
|
|
95
|
+
protocol: "http",
|
|
96
|
+
controller: props.controller.name,
|
|
97
|
+
function: func.name,
|
|
98
|
+
name: props.naming(func.name, props.index),
|
|
99
|
+
}),
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @internal
|
|
105
|
+
*/
|
|
106
|
+
export function toClassOperations<Model extends ILlmSchema.Model>(props: {
|
|
107
|
+
controller: IAgenticaController.IClass<Model>;
|
|
108
|
+
index: number;
|
|
109
|
+
naming: (func: string, controllerIndex: number) => string;
|
|
110
|
+
}): AgenticaOperation<Model>[] {
|
|
111
|
+
return props.controller.application.functions.map(func => ({
|
|
112
|
+
protocol: "class",
|
|
113
|
+
controller: props.controller,
|
|
114
|
+
function: func,
|
|
115
|
+
name: props.naming(func.name, props.index),
|
|
116
|
+
toJSON: () => ({
|
|
117
|
+
protocol: "class",
|
|
118
|
+
controller: props.controller.name,
|
|
119
|
+
function: func.name,
|
|
120
|
+
name: props.naming(func.name, props.index),
|
|
121
|
+
}),
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
export function toMcpOperations<Model extends ILlmSchema.Model>(props: {
|
|
129
|
+
controller: IAgenticaController.IMcp;
|
|
130
|
+
index: number;
|
|
131
|
+
naming: (func: string, controllerIndex: number) => string;
|
|
132
|
+
}): AgenticaOperation<Model>[] {
|
|
133
|
+
return props.controller.application.functions.map(func => ({
|
|
134
|
+
protocol: "mcp",
|
|
135
|
+
controller: props.controller,
|
|
136
|
+
function: func,
|
|
137
|
+
name: props.naming(func.name, props.index),
|
|
138
|
+
toJSON: () => ({
|
|
139
|
+
protocol: "mcp",
|
|
140
|
+
controller: props.controller.name,
|
|
141
|
+
function: func.name,
|
|
142
|
+
name: props.naming(func.name, props.index),
|
|
143
|
+
}),
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
export function divide<T>(props: {
|
|
91
151
|
array: T[];
|
|
92
152
|
capacity: number;
|
|
93
153
|
}): T[][] {
|
|
154
|
+
if (props.capacity <= 0) {
|
|
155
|
+
throw new Error("Capacity must be a positive integer");
|
|
156
|
+
}
|
|
157
|
+
if (Number.isNaN(props.capacity)) {
|
|
158
|
+
throw new TypeError("Capacity must be a positive integer");
|
|
159
|
+
}
|
|
160
|
+
if (props.capacity === Infinity) {
|
|
161
|
+
throw new Error("Capacity must be a positive integer");
|
|
162
|
+
}
|
|
163
|
+
|
|
94
164
|
const size: number = Math.ceil(props.array.length / props.capacity);
|
|
95
165
|
const capacity: number = Math.ceil(props.array.length / size);
|
|
96
166
|
const replica: T[] = props.array.slice();
|
|
@@ -10,7 +10,7 @@ export interface AgenticaDescribeEvent<
|
|
|
10
10
|
Model extends ILlmSchema.Model,
|
|
11
11
|
> extends AgenticaEventBase<"describe"> {
|
|
12
12
|
executes: AgenticaExecuteHistory<Model>[];
|
|
13
|
-
stream:
|
|
13
|
+
stream: AsyncGenerator<string, undefined, undefined>;
|
|
14
14
|
|
|
15
15
|
join: () => Promise<string>;
|
|
16
16
|
toJSON: () => IAgenticaEventJson.IDescribe;
|
|
@@ -17,7 +17,7 @@ export interface AgenticaResponseEvent extends AgenticaEventBase<"response"> {
|
|
|
17
17
|
/**
|
|
18
18
|
* The text content stream.
|
|
19
19
|
*/
|
|
20
|
-
stream:
|
|
20
|
+
stream: AsyncGenerator<OpenAI.ChatCompletionChunk, undefined, undefined>;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Options for the request.
|
|
@@ -7,7 +7,7 @@ export interface AgenticaTextEvent<
|
|
|
7
7
|
Role extends "assistant" | "user" = "assistant" | "user",
|
|
8
8
|
> extends AgenticaEventBase<"text"> {
|
|
9
9
|
role: Role;
|
|
10
|
-
stream:
|
|
10
|
+
stream: AsyncGenerator<string, undefined, undefined>;
|
|
11
11
|
join: () => Promise<string>;
|
|
12
12
|
toJSON: () => IAgenticaEventJson.IText;
|
|
13
13
|
toHistory: () => AgenticaTextHistory;
|
package/src/factory/events.ts
CHANGED
|
@@ -136,7 +136,7 @@ export function createExecuteEvent<Model extends ILlmSchema.Model>(props: {
|
|
|
136
136
|
----------------------------------------------------------- */
|
|
137
137
|
export function createTextEvent<Role extends "user" | "assistant">(props: {
|
|
138
138
|
role: Role;
|
|
139
|
-
stream:
|
|
139
|
+
stream: AsyncGenerator<string, undefined, undefined>;
|
|
140
140
|
done: () => boolean;
|
|
141
141
|
get: () => string;
|
|
142
142
|
join: () => Promise<string>;
|
|
@@ -167,7 +167,7 @@ export function createTextEvent<Role extends "user" | "assistant">(props: {
|
|
|
167
167
|
|
|
168
168
|
export function createDescribeEvent<Model extends ILlmSchema.Model>(props: {
|
|
169
169
|
executes: AgenticaExecuteHistory<Model>[];
|
|
170
|
-
stream:
|
|
170
|
+
stream: AsyncGenerator<string, undefined, undefined>;
|
|
171
171
|
done: () => boolean;
|
|
172
172
|
get: () => string;
|
|
173
173
|
join: () => Promise<string>;
|
|
@@ -216,7 +216,7 @@ export function createResponseEvent(props: {
|
|
|
216
216
|
source: AgenticaEventSource;
|
|
217
217
|
body: OpenAI.ChatCompletionCreateParamsStreaming;
|
|
218
218
|
options?: OpenAI.RequestOptions | undefined;
|
|
219
|
-
stream:
|
|
219
|
+
stream: AsyncGenerator<OpenAI.ChatCompletionChunk, undefined, undefined>;
|
|
220
220
|
join: () => Promise<OpenAI.ChatCompletion>;
|
|
221
221
|
}): AgenticaResponseEvent {
|
|
222
222
|
return {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
3
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
|
+
import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
|
|
6
|
+
import type { IMcpLlmApplication, IMcpLlmTransportProps } from "../structures/mcp";
|
|
7
|
+
/**
|
|
8
|
+
* Create an MCP LLM application instance with type assertion.
|
|
9
|
+
*
|
|
10
|
+
* Create an {@link IMcpLlmApplication} instance which represents
|
|
11
|
+
* an MCP (Model Context Protocol) LLM application.
|
|
12
|
+
*
|
|
13
|
+
* @param props Properties to create the MCP LLM application instance
|
|
14
|
+
* @param props.name Name of the MCP implementation.
|
|
15
|
+
* @param props.url URL of the MCP server.
|
|
16
|
+
* @param props.version Describes version of an MCP implementation.
|
|
17
|
+
* @returns MCP LLM application instance
|
|
18
|
+
* @author Samchon
|
|
19
|
+
*/
|
|
20
|
+
export async function assertMcpLlmApplication(props: IMcpLlmTransportProps): Promise<IMcpLlmApplication> {
|
|
21
|
+
const client = new Client({
|
|
22
|
+
name: "get_tool_list",
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const transport = (() => {
|
|
27
|
+
switch (props.type) {
|
|
28
|
+
case "sse":
|
|
29
|
+
return new SSEClientTransport(props.url);
|
|
30
|
+
case "stdio":
|
|
31
|
+
return new StdioClientTransport(props);
|
|
32
|
+
default:
|
|
33
|
+
props satisfies never;
|
|
34
|
+
throw new Error("Invalid transport type");
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
await client.connect(transport);
|
|
38
|
+
|
|
39
|
+
const toolList = await client.request({ method: "tools/list" }, ListToolsResultSchema);
|
|
40
|
+
return {
|
|
41
|
+
functions: toolList.tools.map(tool => ({
|
|
42
|
+
name: tool.name,
|
|
43
|
+
description: tool.description,
|
|
44
|
+
parameters: tool.inputSchema,
|
|
45
|
+
})),
|
|
46
|
+
transport: props,
|
|
47
|
+
};
|
|
48
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,9 +6,9 @@ export * from "./context/AgenticaOperation";
|
|
|
6
6
|
export * from "./context/AgenticaOperationCollection";
|
|
7
7
|
export * from "./context/AgenticaOperationSelection";
|
|
8
8
|
export * from "./context/AgenticaTokenUsage";
|
|
9
|
+
|
|
9
10
|
export * from "./events/AgenticaCallEvent";
|
|
10
11
|
export * from "./events/AgenticaCancelEvent";
|
|
11
|
-
|
|
12
12
|
export * from "./events/AgenticaDescribeEvent";
|
|
13
13
|
export * from "./events/AgenticaEvent";
|
|
14
14
|
export * from "./events/AgenticaEventSource";
|
|
@@ -19,10 +19,14 @@ export * from "./events/AgenticaSelectEvent";
|
|
|
19
19
|
export * from "./events/AgenticaTextEvent";
|
|
20
20
|
export * from "./events/AgenticaValidateEvent";
|
|
21
21
|
export * from "./events/MicroAgenticaEvent";
|
|
22
|
+
|
|
22
23
|
export * as factory from "./factory";
|
|
23
|
-
export * from "./functional/assertHttpLlmApplication";
|
|
24
24
|
|
|
25
|
+
export * from "./functional/assertHttpLlmApplication";
|
|
26
|
+
export * from "./functional/assertMcpLlmApplication";
|
|
25
27
|
export * from "./functional/validateHttpLlmApplication";
|
|
28
|
+
// @TODO: implement validateMcpLlmApplication
|
|
29
|
+
|
|
26
30
|
export * from "./histories/AgenticaCancelHistory";
|
|
27
31
|
export * from "./histories/AgenticaDescribeHistory";
|
|
28
32
|
export * from "./histories/AgenticaExecuteHistory";
|