@agentica/rpc 0.12.0 → 0.12.2-dev.20250314
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +284 -284
- package/package.json +2 -2
- package/src/AgenticaRpcService.ts +120 -120
- package/src/IAgenticaRpcListener.ts +118 -118
- package/src/IAgenticaRpcService.ts +40 -40
- package/src/index.ts +3 -3
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Wrtn Technologies
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wrtn Technologies
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,285 +1,285 @@
|
|
|
1
|
-
# `@agentica/rpc`
|
|
2
|
-

|
|
3
|
-
|
|
4
|
-
[](https://github.com/wrtnlabs/agentica/blob/master/LICENSE)
|
|
5
|
-
[](https://www.npmjs.com/package/@agentica/rpc)
|
|
6
|
-
[](https://www.npmjs.com/package/@agentica/rpc)
|
|
7
|
-
[](https://github.com/wrtnlabs/agentica/actions?query=workflow%3Abuild)
|
|
8
|
-
|
|
9
|
-
RPC module of Agentica for WebSocket Communication
|
|
10
|
-
|
|
11
|
-
Agentica is the simplest Agentic AI library specialized in **LLM Function Calling**, and `@agentica/rpc` is an RPC (Remote Procedure Call) wrapper module. If you combine the RPC wrapper module with [`TGrid`](https://github.com/samchon/tgrid), you can develop the WebSocket AI Chatbot.
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
15
|
-
import { Driver, WebSocketConnector } from "tgrid";
|
|
16
|
-
|
|
17
|
-
const connector: WebSocketConnector<
|
|
18
|
-
null,
|
|
19
|
-
IAgenticaRpcListener,
|
|
20
|
-
IAgenticaRpcService
|
|
21
|
-
> = new WebSocketConnector(null, {
|
|
22
|
-
text: async (evt) => {
|
|
23
|
-
console.log(evt.role, evt.text);
|
|
24
|
-
},
|
|
25
|
-
describe: async (evt) => {
|
|
26
|
-
console.log("describer", evt.text);
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
await connector.connect("ws://localhost:3001");
|
|
30
|
-
|
|
31
|
-
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
32
|
-
await driver.conversate("Hello, what you can do?");
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## How to use
|
|
39
|
-
### Setup
|
|
40
|
-
```bash
|
|
41
|
-
# SERVER APPLICATION
|
|
42
|
-
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid typia
|
|
43
|
-
npx typia setup
|
|
44
|
-
|
|
45
|
-
# CLIENT APPLICATION
|
|
46
|
-
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Install `@agentica/rpc` with its dependent libraries.
|
|
50
|
-
|
|
51
|
-
Note that, you have to install not only `@agentica/core` and `@agentica/rpc`, but also [`@samchon/openapi`](https://github.com/samchon/openapi) and [`tgrid`](https://github.com/samchon/tgrid) too. If you're developing server application, you have to install `typia` too.
|
|
52
|
-
|
|
53
|
-
`@samchon/openapi` is an OpenAPI specification library which can convert Swagger/OpenAPI document to LLM function calling schema. And `typia` is a transformer (compiler) library which can compose LLM function calling schema from a TypeScript class type. And then `tgrid` is an RPC (REmote Procedure Call) framework supporting the websocket protocol.
|
|
54
|
-
|
|
55
|
-
By the way, as `typia` is a transformer library analyzing TypeScript source code in the compilation level, it needs additional setup command `npx typia setup` when developing server application. Also, if your client (frontend) application is not using the standard TypeScript compiler (not `tsc`), you have to setup [`@ryoppippi/unplugin-typia`](https://typia.io/docs/setup/#unplugin-typia) too.
|
|
56
|
-
|
|
57
|
-
### Server Application
|
|
58
|
-
```typescript
|
|
59
|
-
import { Agentica } from "@agentica/core";
|
|
60
|
-
import {
|
|
61
|
-
AgenticaRpcService,
|
|
62
|
-
IAgenticaRpcListener,
|
|
63
|
-
IAgenticaRpcService,
|
|
64
|
-
} from "@agentica/rpc";
|
|
65
|
-
import { WebSocketServer } from "tgrid";
|
|
66
|
-
|
|
67
|
-
const server: WebSocketServer<
|
|
68
|
-
null,
|
|
69
|
-
IAgenticaRpcService,
|
|
70
|
-
IAgenticaRpcListener
|
|
71
|
-
> = new WebSocketServer();
|
|
72
|
-
await server.open(3001, async (acceptor) => {
|
|
73
|
-
await acceptor.accept(
|
|
74
|
-
new AgenticaRpcService({
|
|
75
|
-
agent: new Agentica({ ... }),
|
|
76
|
-
listener: acceptor.getDriver(),
|
|
77
|
-
}),
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
When developing backend server, wrap `Agentica` to `AgenticaRpcService`.
|
|
83
|
-
|
|
84
|
-
If you're developing WebSocket protocol backend server, create a new `Agentica` instance, and wrap it to the `AgenticaRpcService` class. And then open the websocket server like above code. The WebSocket server will call the client functions of the `IAgenticaRpcListener` remotely.
|
|
85
|
-
|
|
86
|
-
### Client Application
|
|
87
|
-
```typescript
|
|
88
|
-
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
89
|
-
import { Driver, WebSocketConnector } from "tgrid";
|
|
90
|
-
|
|
91
|
-
const connector: WebSocketConnector<
|
|
92
|
-
null,
|
|
93
|
-
IAgenticaRpcListener,
|
|
94
|
-
IAgenticaRpcService
|
|
95
|
-
> = new WebSocketConnector(null, {
|
|
96
|
-
text: async (evt) => {
|
|
97
|
-
console.log(evt.role, evt.text);
|
|
98
|
-
},
|
|
99
|
-
describe: async (evt) => {
|
|
100
|
-
console.log("describer", evt.text);
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
await connector.connect("ws://localhost:3001");
|
|
104
|
-
|
|
105
|
-
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
106
|
-
await driver.conversate("Hello, what you can do?");
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
When developing frontend application, define `IAgenticaRpcListener` instance.
|
|
110
|
-
|
|
111
|
-
Otherwise you're developing WebSocket protocol client application, connect to the websocket backend server with its URL address, and provide `IAgenticaRpcListener` instance for event listening.
|
|
112
|
-
|
|
113
|
-
And then call the backend server's function `IAgenticaRpcService.conversate()` remotely through the `Driver<IAgenticaRpcService>` wrapping. The backend server will call your `IAgenticaRpcListener` functions remotely through the RPC paradigm.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
## NestJS Application
|
|
119
|
-
### Bootstrap
|
|
120
|
-
```bash
|
|
121
|
-
npx nestia start <directory>
|
|
122
|
-
cd <directory>
|
|
123
|
-
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
You can integrate `@agentica` with [NestJS Framework](https://nestjs.com) utilizing [Nestia](https://nestia.io).
|
|
127
|
-
|
|
128
|
-
At first, create a boilerplate project of NestJS combined with Nestia by running `npx nesta start` command. And then install `@agentica/rpc` with its dependency packages.
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { WebSocketAdaptor } from "@nestia/core";
|
|
132
|
-
import { INestApplication } from "@nestjs/common";
|
|
133
|
-
import { NestFactory } from "@nestjs/core";
|
|
134
|
-
|
|
135
|
-
import { MyConfiguration } from "./MyConfiguration";
|
|
136
|
-
import { MyModule } from "./MyModule";
|
|
137
|
-
|
|
138
|
-
export class MyBackend {
|
|
139
|
-
private application_?: INestApplication;
|
|
140
|
-
|
|
141
|
-
public async open(): Promise<void> {
|
|
142
|
-
//----
|
|
143
|
-
// OPEN THE BACKEND SERVER
|
|
144
|
-
//----
|
|
145
|
-
// MOUNT CONTROLLERS
|
|
146
|
-
this.application_ = await NestFactory.create(MyModule, { logger: false });
|
|
147
|
-
WebSocketAdaptor.upgrade(this.application_);
|
|
148
|
-
...
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
After setup, update `src/MyBackend.ts` file to call `WebSocketAdaptor.upgrade()` function to the NestJS application instance. The function `WebSocketAdaptor.upgrade()` will make the NestJS backend server to compatible with WebSocket protocol.
|
|
154
|
-
|
|
155
|
-
### API Controller
|
|
156
|
-
```typescript
|
|
157
|
-
import { AgenticaRpcService, IAgenticaRpcListener } from "@agentica/rpc";
|
|
158
|
-
import { WebSocketRoute } from "@nestia/core";
|
|
159
|
-
import { Controller } from "@nestjs/common";
|
|
160
|
-
import { WebSocketAcceptor } from "tgrid";
|
|
161
|
-
|
|
162
|
-
@Controller("chat")
|
|
163
|
-
export class ChatController {
|
|
164
|
-
@WebSocketRoute()
|
|
165
|
-
public async start(
|
|
166
|
-
// @WebSocketRoute.Param("id") id: string,
|
|
167
|
-
@WebSocketRoute.Acceptor()
|
|
168
|
-
acceptor: WebSocketAcceptor<
|
|
169
|
-
null, // header
|
|
170
|
-
AgenticaRpcService,
|
|
171
|
-
IAgenticaRpcListener
|
|
172
|
-
>,
|
|
173
|
-
): Promise<void> {
|
|
174
|
-
await acceptor.accept(
|
|
175
|
-
new AgenticaRpcService({
|
|
176
|
-
agent: new Agentica({ ... }),
|
|
177
|
-
listener: acceptor.getDriver(),
|
|
178
|
-
}),
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Make a new NestJS controller class like above.
|
|
185
|
-
|
|
186
|
-
When a client connects to the server with `ws://localhost:3001/chat` URL, Agentica made chatbot would be started in the WebSocket protocol.
|
|
187
|
-
|
|
188
|
-
If you need path or query parameters, utilize `@WebSocketRoute.Path()` or `@WebSocketRoute.Query()` decorator functions.
|
|
189
|
-
|
|
190
|
-
### Software Development Kit
|
|
191
|
-
```bash
|
|
192
|
-
npx nestia sdk
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
When backend server development has been completed, you can generate SDK (Software Development Kit) library for client developers by running `npx nestia sdk` command.
|
|
196
|
-
|
|
197
|
-
Client developers can utilize the SDK library like below.
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
import { IAgenticaRpcListener } from "@agentica/rpc";
|
|
201
|
-
import api from "@ORGANIZATION/PROJECT-api";
|
|
202
|
-
|
|
203
|
-
const { connector, driver } = await api.functional.chat.start(
|
|
204
|
-
{
|
|
205
|
-
host: "http://localhost:3000",
|
|
206
|
-
} satisfies api.IConnection,
|
|
207
|
-
{
|
|
208
|
-
text: async (evt) => {
|
|
209
|
-
console.log(evt.role, evt.text);
|
|
210
|
-
},
|
|
211
|
-
describe: async (evt) => {
|
|
212
|
-
console.log("describer", evt.text);
|
|
213
|
-
},
|
|
214
|
-
} satisfies IAgenticaRpcListener,
|
|
215
|
-
);
|
|
216
|
-
await driver.conversate("Hello, what you can do?");s
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
## Principles
|
|
223
|
-
### Remote Procedure Call
|
|
224
|
-
```mermaid
|
|
225
|
-
sequenceDiagram
|
|
226
|
-
box Client Application
|
|
227
|
-
actor User
|
|
228
|
-
participant Driver as Driver<Listener>
|
|
229
|
-
participant Connector as Communicator (Client)
|
|
230
|
-
end
|
|
231
|
-
box Server Application
|
|
232
|
-
participant Acceptor as Communicator (Server)
|
|
233
|
-
actor Provider
|
|
234
|
-
end
|
|
235
|
-
User->>Driver: 1. calls a function
|
|
236
|
-
Activate User
|
|
237
|
-
Activate Driver
|
|
238
|
-
Driver->>Connector: 2. delivers the function call
|
|
239
|
-
Activate Connector
|
|
240
|
-
Deactivate Driver
|
|
241
|
-
Connector-->>Acceptor: 3. sends a protocolized<br/>network message<br/>meaning a function call
|
|
242
|
-
Deactivate Connector
|
|
243
|
-
Activate Acceptor
|
|
244
|
-
Acceptor->>Provider: 4. calls the function
|
|
245
|
-
Provider->>Acceptor: 5. returns a value
|
|
246
|
-
Acceptor-->>Connector: 6. sends a protocolized<br/>network message<br/>meaning a return value
|
|
247
|
-
Deactivate Acceptor
|
|
248
|
-
Activate Connector
|
|
249
|
-
Connector->>Driver: 7. delivers the return value
|
|
250
|
-
Deactivate Connector
|
|
251
|
-
Activate Driver
|
|
252
|
-
Driver->>User: 8. returns the value
|
|
253
|
-
Deactivate Driver
|
|
254
|
-
Deactivate User
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
WebSocket protocol with RPC paradigm for AI chatbot.
|
|
258
|
-
|
|
259
|
-
`@agentica/rpc` supports WebSocket protocol that is utilizing [`TGrid`](https://github.com/samchon/tgrid) and its RPC (Remote Procedure Call) paradigm for easy and type safe development. In the RPC paradigm, client application can call a function of `IAgenticaRpcService` remotely as if it were its own object.
|
|
260
|
-
|
|
261
|
-
Internally, the RPC has composed with three elements; [`Communicator`](https://tgrid.com/docs/features/components/#communicator), [`Provider`](https://tgrid.com/docs/features/components/#provider) and [`Driver`](https://tgrid.com/docs/features/components/#driver). The first `Communicator` takes a responsibility of (WebSocket) network communication. The next `Provider` means an object providing to the remote system for RPC, and `Driver` is a proxy instance realizing the RPC to the remote provided `Provider` instance.
|
|
262
|
-
|
|
263
|
-
For example, below client application code is calling `IAgenticaRpcService.conversate()` function remotely through the `Driver<IAgenticaRpcService>` typed instance. In that case, `IAgenticaRpcService` is the `Provider` instance from server to client. And `WebSocketConnector` is the communicator taking responsibility of WebSocket communication.
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
267
|
-
import { Driver, WebSocketConnector } from "tgrid";
|
|
268
|
-
|
|
269
|
-
const connector: WebSocketConnector<
|
|
270
|
-
null,
|
|
271
|
-
IAgenticaRpcListener,
|
|
272
|
-
IAgenticaRpcService
|
|
273
|
-
> = new WebSocketConnector(null, {
|
|
274
|
-
text: async (evt) => {
|
|
275
|
-
console.log(evt.role, evt.text);
|
|
276
|
-
},
|
|
277
|
-
describe: async (evt) => {
|
|
278
|
-
console.log("describer", evt.text);
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
await connector.connect("ws://localhost:3001");
|
|
282
|
-
|
|
283
|
-
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
284
|
-
await driver.conversate("Hello, what you can do?");
|
|
1
|
+
# `@agentica/rpc`
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
[](https://github.com/wrtnlabs/agentica/blob/master/LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/@agentica/rpc)
|
|
6
|
+
[](https://www.npmjs.com/package/@agentica/rpc)
|
|
7
|
+
[](https://github.com/wrtnlabs/agentica/actions?query=workflow%3Abuild)
|
|
8
|
+
|
|
9
|
+
RPC module of Agentica for WebSocket Communication
|
|
10
|
+
|
|
11
|
+
Agentica is the simplest Agentic AI library specialized in **LLM Function Calling**, and `@agentica/rpc` is an RPC (Remote Procedure Call) wrapper module. If you combine the RPC wrapper module with [`TGrid`](https://github.com/samchon/tgrid), you can develop the WebSocket AI Chatbot.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
15
|
+
import { Driver, WebSocketConnector } from "tgrid";
|
|
16
|
+
|
|
17
|
+
const connector: WebSocketConnector<
|
|
18
|
+
null,
|
|
19
|
+
IAgenticaRpcListener,
|
|
20
|
+
IAgenticaRpcService
|
|
21
|
+
> = new WebSocketConnector(null, {
|
|
22
|
+
text: async (evt) => {
|
|
23
|
+
console.log(evt.role, evt.text);
|
|
24
|
+
},
|
|
25
|
+
describe: async (evt) => {
|
|
26
|
+
console.log("describer", evt.text);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
await connector.connect("ws://localhost:3001");
|
|
30
|
+
|
|
31
|
+
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
32
|
+
await driver.conversate("Hello, what you can do?");
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## How to use
|
|
39
|
+
### Setup
|
|
40
|
+
```bash
|
|
41
|
+
# SERVER APPLICATION
|
|
42
|
+
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid typia
|
|
43
|
+
npx typia setup
|
|
44
|
+
|
|
45
|
+
# CLIENT APPLICATION
|
|
46
|
+
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Install `@agentica/rpc` with its dependent libraries.
|
|
50
|
+
|
|
51
|
+
Note that, you have to install not only `@agentica/core` and `@agentica/rpc`, but also [`@samchon/openapi`](https://github.com/samchon/openapi) and [`tgrid`](https://github.com/samchon/tgrid) too. If you're developing server application, you have to install `typia` too.
|
|
52
|
+
|
|
53
|
+
`@samchon/openapi` is an OpenAPI specification library which can convert Swagger/OpenAPI document to LLM function calling schema. And `typia` is a transformer (compiler) library which can compose LLM function calling schema from a TypeScript class type. And then `tgrid` is an RPC (REmote Procedure Call) framework supporting the websocket protocol.
|
|
54
|
+
|
|
55
|
+
By the way, as `typia` is a transformer library analyzing TypeScript source code in the compilation level, it needs additional setup command `npx typia setup` when developing server application. Also, if your client (frontend) application is not using the standard TypeScript compiler (not `tsc`), you have to setup [`@ryoppippi/unplugin-typia`](https://typia.io/docs/setup/#unplugin-typia) too.
|
|
56
|
+
|
|
57
|
+
### Server Application
|
|
58
|
+
```typescript
|
|
59
|
+
import { Agentica } from "@agentica/core";
|
|
60
|
+
import {
|
|
61
|
+
AgenticaRpcService,
|
|
62
|
+
IAgenticaRpcListener,
|
|
63
|
+
IAgenticaRpcService,
|
|
64
|
+
} from "@agentica/rpc";
|
|
65
|
+
import { WebSocketServer } from "tgrid";
|
|
66
|
+
|
|
67
|
+
const server: WebSocketServer<
|
|
68
|
+
null,
|
|
69
|
+
IAgenticaRpcService,
|
|
70
|
+
IAgenticaRpcListener
|
|
71
|
+
> = new WebSocketServer();
|
|
72
|
+
await server.open(3001, async (acceptor) => {
|
|
73
|
+
await acceptor.accept(
|
|
74
|
+
new AgenticaRpcService({
|
|
75
|
+
agent: new Agentica({ ... }),
|
|
76
|
+
listener: acceptor.getDriver(),
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
When developing backend server, wrap `Agentica` to `AgenticaRpcService`.
|
|
83
|
+
|
|
84
|
+
If you're developing WebSocket protocol backend server, create a new `Agentica` instance, and wrap it to the `AgenticaRpcService` class. And then open the websocket server like above code. The WebSocket server will call the client functions of the `IAgenticaRpcListener` remotely.
|
|
85
|
+
|
|
86
|
+
### Client Application
|
|
87
|
+
```typescript
|
|
88
|
+
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
89
|
+
import { Driver, WebSocketConnector } from "tgrid";
|
|
90
|
+
|
|
91
|
+
const connector: WebSocketConnector<
|
|
92
|
+
null,
|
|
93
|
+
IAgenticaRpcListener,
|
|
94
|
+
IAgenticaRpcService
|
|
95
|
+
> = new WebSocketConnector(null, {
|
|
96
|
+
text: async (evt) => {
|
|
97
|
+
console.log(evt.role, evt.text);
|
|
98
|
+
},
|
|
99
|
+
describe: async (evt) => {
|
|
100
|
+
console.log("describer", evt.text);
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
await connector.connect("ws://localhost:3001");
|
|
104
|
+
|
|
105
|
+
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
106
|
+
await driver.conversate("Hello, what you can do?");
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
When developing frontend application, define `IAgenticaRpcListener` instance.
|
|
110
|
+
|
|
111
|
+
Otherwise you're developing WebSocket protocol client application, connect to the websocket backend server with its URL address, and provide `IAgenticaRpcListener` instance for event listening.
|
|
112
|
+
|
|
113
|
+
And then call the backend server's function `IAgenticaRpcService.conversate()` remotely through the `Driver<IAgenticaRpcService>` wrapping. The backend server will call your `IAgenticaRpcListener` functions remotely through the RPC paradigm.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## NestJS Application
|
|
119
|
+
### Bootstrap
|
|
120
|
+
```bash
|
|
121
|
+
npx nestia start <directory>
|
|
122
|
+
cd <directory>
|
|
123
|
+
npm install @agentica/core @agentica/rpc @samchon/openapi tgrid
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
You can integrate `@agentica` with [NestJS Framework](https://nestjs.com) utilizing [Nestia](https://nestia.io).
|
|
127
|
+
|
|
128
|
+
At first, create a boilerplate project of NestJS combined with Nestia by running `npx nesta start` command. And then install `@agentica/rpc` with its dependency packages.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { WebSocketAdaptor } from "@nestia/core";
|
|
132
|
+
import { INestApplication } from "@nestjs/common";
|
|
133
|
+
import { NestFactory } from "@nestjs/core";
|
|
134
|
+
|
|
135
|
+
import { MyConfiguration } from "./MyConfiguration";
|
|
136
|
+
import { MyModule } from "./MyModule";
|
|
137
|
+
|
|
138
|
+
export class MyBackend {
|
|
139
|
+
private application_?: INestApplication;
|
|
140
|
+
|
|
141
|
+
public async open(): Promise<void> {
|
|
142
|
+
//----
|
|
143
|
+
// OPEN THE BACKEND SERVER
|
|
144
|
+
//----
|
|
145
|
+
// MOUNT CONTROLLERS
|
|
146
|
+
this.application_ = await NestFactory.create(MyModule, { logger: false });
|
|
147
|
+
WebSocketAdaptor.upgrade(this.application_);
|
|
148
|
+
...
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
After setup, update `src/MyBackend.ts` file to call `WebSocketAdaptor.upgrade()` function to the NestJS application instance. The function `WebSocketAdaptor.upgrade()` will make the NestJS backend server to compatible with WebSocket protocol.
|
|
154
|
+
|
|
155
|
+
### API Controller
|
|
156
|
+
```typescript
|
|
157
|
+
import { AgenticaRpcService, IAgenticaRpcListener } from "@agentica/rpc";
|
|
158
|
+
import { WebSocketRoute } from "@nestia/core";
|
|
159
|
+
import { Controller } from "@nestjs/common";
|
|
160
|
+
import { WebSocketAcceptor } from "tgrid";
|
|
161
|
+
|
|
162
|
+
@Controller("chat")
|
|
163
|
+
export class ChatController {
|
|
164
|
+
@WebSocketRoute()
|
|
165
|
+
public async start(
|
|
166
|
+
// @WebSocketRoute.Param("id") id: string,
|
|
167
|
+
@WebSocketRoute.Acceptor()
|
|
168
|
+
acceptor: WebSocketAcceptor<
|
|
169
|
+
null, // header
|
|
170
|
+
AgenticaRpcService,
|
|
171
|
+
IAgenticaRpcListener
|
|
172
|
+
>,
|
|
173
|
+
): Promise<void> {
|
|
174
|
+
await acceptor.accept(
|
|
175
|
+
new AgenticaRpcService({
|
|
176
|
+
agent: new Agentica({ ... }),
|
|
177
|
+
listener: acceptor.getDriver(),
|
|
178
|
+
}),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Make a new NestJS controller class like above.
|
|
185
|
+
|
|
186
|
+
When a client connects to the server with `ws://localhost:3001/chat` URL, Agentica made chatbot would be started in the WebSocket protocol.
|
|
187
|
+
|
|
188
|
+
If you need path or query parameters, utilize `@WebSocketRoute.Path()` or `@WebSocketRoute.Query()` decorator functions.
|
|
189
|
+
|
|
190
|
+
### Software Development Kit
|
|
191
|
+
```bash
|
|
192
|
+
npx nestia sdk
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
When backend server development has been completed, you can generate SDK (Software Development Kit) library for client developers by running `npx nestia sdk` command.
|
|
196
|
+
|
|
197
|
+
Client developers can utilize the SDK library like below.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { IAgenticaRpcListener } from "@agentica/rpc";
|
|
201
|
+
import api from "@ORGANIZATION/PROJECT-api";
|
|
202
|
+
|
|
203
|
+
const { connector, driver } = await api.functional.chat.start(
|
|
204
|
+
{
|
|
205
|
+
host: "http://localhost:3000",
|
|
206
|
+
} satisfies api.IConnection,
|
|
207
|
+
{
|
|
208
|
+
text: async (evt) => {
|
|
209
|
+
console.log(evt.role, evt.text);
|
|
210
|
+
},
|
|
211
|
+
describe: async (evt) => {
|
|
212
|
+
console.log("describer", evt.text);
|
|
213
|
+
},
|
|
214
|
+
} satisfies IAgenticaRpcListener,
|
|
215
|
+
);
|
|
216
|
+
await driver.conversate("Hello, what you can do?");s
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
## Principles
|
|
223
|
+
### Remote Procedure Call
|
|
224
|
+
```mermaid
|
|
225
|
+
sequenceDiagram
|
|
226
|
+
box Client Application
|
|
227
|
+
actor User
|
|
228
|
+
participant Driver as Driver<Listener>
|
|
229
|
+
participant Connector as Communicator (Client)
|
|
230
|
+
end
|
|
231
|
+
box Server Application
|
|
232
|
+
participant Acceptor as Communicator (Server)
|
|
233
|
+
actor Provider
|
|
234
|
+
end
|
|
235
|
+
User->>Driver: 1. calls a function
|
|
236
|
+
Activate User
|
|
237
|
+
Activate Driver
|
|
238
|
+
Driver->>Connector: 2. delivers the function call
|
|
239
|
+
Activate Connector
|
|
240
|
+
Deactivate Driver
|
|
241
|
+
Connector-->>Acceptor: 3. sends a protocolized<br/>network message<br/>meaning a function call
|
|
242
|
+
Deactivate Connector
|
|
243
|
+
Activate Acceptor
|
|
244
|
+
Acceptor->>Provider: 4. calls the function
|
|
245
|
+
Provider->>Acceptor: 5. returns a value
|
|
246
|
+
Acceptor-->>Connector: 6. sends a protocolized<br/>network message<br/>meaning a return value
|
|
247
|
+
Deactivate Acceptor
|
|
248
|
+
Activate Connector
|
|
249
|
+
Connector->>Driver: 7. delivers the return value
|
|
250
|
+
Deactivate Connector
|
|
251
|
+
Activate Driver
|
|
252
|
+
Driver->>User: 8. returns the value
|
|
253
|
+
Deactivate Driver
|
|
254
|
+
Deactivate User
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
WebSocket protocol with RPC paradigm for AI chatbot.
|
|
258
|
+
|
|
259
|
+
`@agentica/rpc` supports WebSocket protocol that is utilizing [`TGrid`](https://github.com/samchon/tgrid) and its RPC (Remote Procedure Call) paradigm for easy and type safe development. In the RPC paradigm, client application can call a function of `IAgenticaRpcService` remotely as if it were its own object.
|
|
260
|
+
|
|
261
|
+
Internally, the RPC has composed with three elements; [`Communicator`](https://tgrid.com/docs/features/components/#communicator), [`Provider`](https://tgrid.com/docs/features/components/#provider) and [`Driver`](https://tgrid.com/docs/features/components/#driver). The first `Communicator` takes a responsibility of (WebSocket) network communication. The next `Provider` means an object providing to the remote system for RPC, and `Driver` is a proxy instance realizing the RPC to the remote provided `Provider` instance.
|
|
262
|
+
|
|
263
|
+
For example, below client application code is calling `IAgenticaRpcService.conversate()` function remotely through the `Driver<IAgenticaRpcService>` typed instance. In that case, `IAgenticaRpcService` is the `Provider` instance from server to client. And `WebSocketConnector` is the communicator taking responsibility of WebSocket communication.
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/rpc";
|
|
267
|
+
import { Driver, WebSocketConnector } from "tgrid";
|
|
268
|
+
|
|
269
|
+
const connector: WebSocketConnector<
|
|
270
|
+
null,
|
|
271
|
+
IAgenticaRpcListener,
|
|
272
|
+
IAgenticaRpcService
|
|
273
|
+
> = new WebSocketConnector(null, {
|
|
274
|
+
text: async (evt) => {
|
|
275
|
+
console.log(evt.role, evt.text);
|
|
276
|
+
},
|
|
277
|
+
describe: async (evt) => {
|
|
278
|
+
console.log("describer", evt.text);
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
await connector.connect("ws://localhost:3001");
|
|
282
|
+
|
|
283
|
+
const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
284
|
+
await driver.conversate("Hello, what you can do?");
|
|
285
285
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentica/rpc",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2-dev.20250314",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "Agentic AI Library specialized in LLM Function Calling",
|
|
6
6
|
"scripts": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"src"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@agentica/core": "^0.12.
|
|
40
|
+
"@agentica/core": "^0.12.2-dev.20250314",
|
|
41
41
|
"@samchon/openapi": "^3.0.0",
|
|
42
42
|
"chalk": "4.1.2",
|
|
43
43
|
"openai": "^4.80.0",
|
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
import { Agentica, IAgenticaController } from "@agentica/core";
|
|
2
|
-
import { ILlmSchema } from "@samchon/openapi";
|
|
3
|
-
import { Primitive } from "typia";
|
|
4
|
-
|
|
5
|
-
import { IAgenticaRpcListener } from "./IAgenticaRpcListener";
|
|
6
|
-
import { IAgenticaRpcService } from "./IAgenticaRpcService";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* RPC service for the {@link Agentica}.
|
|
10
|
-
*
|
|
11
|
-
* `AgenticaRpcService` is class defining an AI agent service
|
|
12
|
-
* provided from the server to clients through the RPC (Remote Procedure Call)
|
|
13
|
-
* paradigm in the websocket protocol.
|
|
14
|
-
*
|
|
15
|
-
* Client connecting to the `AgenticaRpcService` providing websocket server
|
|
16
|
-
* will call the {@link conversate} function remotely through its basic
|
|
17
|
-
* interface type {@link IAgenticaRpcService} with the RPC paradigm.
|
|
18
|
-
*
|
|
19
|
-
* Also, the client provides the {@link IAgenticaRpcListener} type to the
|
|
20
|
-
* server, so that `AgenticaRpcService` will remotely call the
|
|
21
|
-
* {@link IAgenticaRpcListener listener}'s functions internally.
|
|
22
|
-
*
|
|
23
|
-
* You can open the WebSocket server of the AI agent like below:
|
|
24
|
-
*
|
|
25
|
-
* ```typescript
|
|
26
|
-
* import {
|
|
27
|
-
* IAgenticaRpcListener,
|
|
28
|
-
* IAgenticaRpcService,
|
|
29
|
-
* Agentica,
|
|
30
|
-
* AgenticaRpcService,
|
|
31
|
-
* } from "@agentica/core";
|
|
32
|
-
* import { WebSocketServer } from "tgrid";
|
|
33
|
-
*
|
|
34
|
-
* const server: WebSocketServer<
|
|
35
|
-
* null,
|
|
36
|
-
* IAgenticaRpcService,
|
|
37
|
-
* IAgenticaRpcListener
|
|
38
|
-
* > = new WebSocketServer();
|
|
39
|
-
* await server.open(3001, async (acceptor) => {
|
|
40
|
-
* await acceptor.accept(
|
|
41
|
-
* new AgenticaRpcService({
|
|
42
|
-
* agent: new Agentica({ ... }),
|
|
43
|
-
* listener: acceptor.getDriver(),
|
|
44
|
-
* }),
|
|
45
|
-
* );
|
|
46
|
-
* });
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* @author Samchon
|
|
50
|
-
*/
|
|
51
|
-
export class AgenticaRpcService<Model extends ILlmSchema.Model>
|
|
52
|
-
implements IAgenticaRpcService<Model>
|
|
53
|
-
{
|
|
54
|
-
/**
|
|
55
|
-
* Initializer Constructor.
|
|
56
|
-
*
|
|
57
|
-
* @param props Properties to construct the RPC service
|
|
58
|
-
*/
|
|
59
|
-
public constructor(private readonly props: AgenticaRpcService.IProps<Model>) {
|
|
60
|
-
const { agent, listener } = props;
|
|
61
|
-
|
|
62
|
-
// ESSENTIAL LISTENERS
|
|
63
|
-
agent.on("text", async (evt) =>
|
|
64
|
-
listener.text(Object.assign(primitive(evt), { text: await evt.join() })),
|
|
65
|
-
);
|
|
66
|
-
agent.on("describe", async (evt) =>
|
|
67
|
-
listener.describe(
|
|
68
|
-
Object.assign(primitive(evt), { text: await evt.join() }),
|
|
69
|
-
),
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
// OPTIONAL LISTENERS
|
|
73
|
-
agent.on("initialize", (evt) => listener.initialize!(primitive(evt)));
|
|
74
|
-
agent.on("select", (evt) => listener.select!(primitive(evt)));
|
|
75
|
-
agent.on("cancel", (evt) => listener.cancel!(primitive(evt)));
|
|
76
|
-
agent.on("call", async (evt) => {
|
|
77
|
-
const args: object | null | undefined = await listener.call!(
|
|
78
|
-
primitive(evt),
|
|
79
|
-
);
|
|
80
|
-
if (args) evt.arguments = args;
|
|
81
|
-
});
|
|
82
|
-
agent.on("execute", (evt) => listener.execute!(primitive(evt as any)));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @inheritDoc
|
|
87
|
-
*/
|
|
88
|
-
public async conversate(content: string): Promise<void> {
|
|
89
|
-
await this.props.agent.conversate(content);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @inheritDoc
|
|
94
|
-
*/
|
|
95
|
-
public async getControllers(): Promise<IAgenticaController<Model>[]> {
|
|
96
|
-
return this.props.agent.getControllers() as IAgenticaController<Model>[];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export namespace AgenticaRpcService {
|
|
100
|
-
/**
|
|
101
|
-
* Properties of the {@link AgenticaRpcService}.
|
|
102
|
-
*/
|
|
103
|
-
export interface IProps<Model extends ILlmSchema.Model> {
|
|
104
|
-
/**
|
|
105
|
-
* Target agent to provide as RPC service.
|
|
106
|
-
*/
|
|
107
|
-
agent: Agentica<Model>;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Listener to be binded on the agent.
|
|
111
|
-
*/
|
|
112
|
-
listener: IAgenticaRpcListener;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* @internal
|
|
118
|
-
*/
|
|
119
|
-
const primitive = <T>(obj: T): Primitive<T> =>
|
|
120
|
-
JSON.parse(JSON.stringify(obj)) as Primitive<T>;
|
|
1
|
+
import { Agentica, IAgenticaController } from "@agentica/core";
|
|
2
|
+
import { ILlmSchema } from "@samchon/openapi";
|
|
3
|
+
import { Primitive } from "typia";
|
|
4
|
+
|
|
5
|
+
import { IAgenticaRpcListener } from "./IAgenticaRpcListener";
|
|
6
|
+
import { IAgenticaRpcService } from "./IAgenticaRpcService";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* RPC service for the {@link Agentica}.
|
|
10
|
+
*
|
|
11
|
+
* `AgenticaRpcService` is class defining an AI agent service
|
|
12
|
+
* provided from the server to clients through the RPC (Remote Procedure Call)
|
|
13
|
+
* paradigm in the websocket protocol.
|
|
14
|
+
*
|
|
15
|
+
* Client connecting to the `AgenticaRpcService` providing websocket server
|
|
16
|
+
* will call the {@link conversate} function remotely through its basic
|
|
17
|
+
* interface type {@link IAgenticaRpcService} with the RPC paradigm.
|
|
18
|
+
*
|
|
19
|
+
* Also, the client provides the {@link IAgenticaRpcListener} type to the
|
|
20
|
+
* server, so that `AgenticaRpcService` will remotely call the
|
|
21
|
+
* {@link IAgenticaRpcListener listener}'s functions internally.
|
|
22
|
+
*
|
|
23
|
+
* You can open the WebSocket server of the AI agent like below:
|
|
24
|
+
*
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import {
|
|
27
|
+
* IAgenticaRpcListener,
|
|
28
|
+
* IAgenticaRpcService,
|
|
29
|
+
* Agentica,
|
|
30
|
+
* AgenticaRpcService,
|
|
31
|
+
* } from "@agentica/core";
|
|
32
|
+
* import { WebSocketServer } from "tgrid";
|
|
33
|
+
*
|
|
34
|
+
* const server: WebSocketServer<
|
|
35
|
+
* null,
|
|
36
|
+
* IAgenticaRpcService,
|
|
37
|
+
* IAgenticaRpcListener
|
|
38
|
+
* > = new WebSocketServer();
|
|
39
|
+
* await server.open(3001, async (acceptor) => {
|
|
40
|
+
* await acceptor.accept(
|
|
41
|
+
* new AgenticaRpcService({
|
|
42
|
+
* agent: new Agentica({ ... }),
|
|
43
|
+
* listener: acceptor.getDriver(),
|
|
44
|
+
* }),
|
|
45
|
+
* );
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @author Samchon
|
|
50
|
+
*/
|
|
51
|
+
export class AgenticaRpcService<Model extends ILlmSchema.Model>
|
|
52
|
+
implements IAgenticaRpcService<Model>
|
|
53
|
+
{
|
|
54
|
+
/**
|
|
55
|
+
* Initializer Constructor.
|
|
56
|
+
*
|
|
57
|
+
* @param props Properties to construct the RPC service
|
|
58
|
+
*/
|
|
59
|
+
public constructor(private readonly props: AgenticaRpcService.IProps<Model>) {
|
|
60
|
+
const { agent, listener } = props;
|
|
61
|
+
|
|
62
|
+
// ESSENTIAL LISTENERS
|
|
63
|
+
agent.on("text", async (evt) =>
|
|
64
|
+
listener.text(Object.assign(primitive(evt), { text: await evt.join() })),
|
|
65
|
+
);
|
|
66
|
+
agent.on("describe", async (evt) =>
|
|
67
|
+
listener.describe(
|
|
68
|
+
Object.assign(primitive(evt), { text: await evt.join() }),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// OPTIONAL LISTENERS
|
|
73
|
+
agent.on("initialize", (evt) => listener.initialize!(primitive(evt)));
|
|
74
|
+
agent.on("select", (evt) => listener.select!(primitive(evt)));
|
|
75
|
+
agent.on("cancel", (evt) => listener.cancel!(primitive(evt)));
|
|
76
|
+
agent.on("call", async (evt) => {
|
|
77
|
+
const args: object | null | undefined = await listener.call!(
|
|
78
|
+
primitive(evt),
|
|
79
|
+
);
|
|
80
|
+
if (args) evt.arguments = args;
|
|
81
|
+
});
|
|
82
|
+
agent.on("execute", (evt) => listener.execute!(primitive(evt as any)));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @inheritDoc
|
|
87
|
+
*/
|
|
88
|
+
public async conversate(content: string): Promise<void> {
|
|
89
|
+
await this.props.agent.conversate(content);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @inheritDoc
|
|
94
|
+
*/
|
|
95
|
+
public async getControllers(): Promise<IAgenticaController<Model>[]> {
|
|
96
|
+
return this.props.agent.getControllers() as IAgenticaController<Model>[];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export namespace AgenticaRpcService {
|
|
100
|
+
/**
|
|
101
|
+
* Properties of the {@link AgenticaRpcService}.
|
|
102
|
+
*/
|
|
103
|
+
export interface IProps<Model extends ILlmSchema.Model> {
|
|
104
|
+
/**
|
|
105
|
+
* Target agent to provide as RPC service.
|
|
106
|
+
*/
|
|
107
|
+
agent: Agentica<Model>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Listener to be binded on the agent.
|
|
111
|
+
*/
|
|
112
|
+
listener: IAgenticaRpcListener;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
119
|
+
const primitive = <T>(obj: T): Primitive<T> =>
|
|
120
|
+
JSON.parse(JSON.stringify(obj)) as Primitive<T>;
|
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
import { IAgenticaEventJson } from "@agentica/core";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* RPC interface of AI agent listener.
|
|
5
|
-
*
|
|
6
|
-
* `IAgenticaRpcListener` is an interface defining an AI agent listener
|
|
7
|
-
* provided from the client to server through the RPC (Remote Procedure Call)
|
|
8
|
-
* paradigm in the websocket protocol.
|
|
9
|
-
*
|
|
10
|
-
* It has defined the event listener functions of {@link AgenticaEvent}
|
|
11
|
-
* types. If you skip some event typed functions' implementations,
|
|
12
|
-
* the skipped event would be ignored.
|
|
13
|
-
*
|
|
14
|
-
* Also, the event like listener functions of `IAgenticaRpcListener` type
|
|
15
|
-
* are remotely called when a client calls the
|
|
16
|
-
* {@link IAgenticaRpcService.conversate} function remotely, so that the
|
|
17
|
-
* server responses to the client by the event listener functions.
|
|
18
|
-
*
|
|
19
|
-
* You can connect to the WebSocket server of the AI agent like below:
|
|
20
|
-
*
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/core";
|
|
23
|
-
* import { Driver, WebSocketConnector } from "tgrid";
|
|
24
|
-
*
|
|
25
|
-
* const connector: WebSocketConnector<
|
|
26
|
-
* null,
|
|
27
|
-
* IAgenticaRpcListener,
|
|
28
|
-
* IAgenticaRpcService
|
|
29
|
-
* > = new WebSocketConnector(null, {
|
|
30
|
-
* text: async (evt) => {
|
|
31
|
-
* console.log(evt.role, evt.text);
|
|
32
|
-
* },
|
|
33
|
-
* describe: async (evt) => {
|
|
34
|
-
* console.log("describer", evt.text);
|
|
35
|
-
* },
|
|
36
|
-
* });
|
|
37
|
-
* await connector.connect("ws://localhost:3001");
|
|
38
|
-
*
|
|
39
|
-
* const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
40
|
-
* await driver.conversate("Hello, what you can do?");
|
|
41
|
-
* ```
|
|
42
|
-
*
|
|
43
|
-
* @author Samchon
|
|
44
|
-
*/
|
|
45
|
-
export interface IAgenticaRpcListener {
|
|
46
|
-
/**
|
|
47
|
-
* Describe the function executions' results.
|
|
48
|
-
*
|
|
49
|
-
* Inform description message of the function execution's results from
|
|
50
|
-
* the AI agent server to client.
|
|
51
|
-
*
|
|
52
|
-
* @param evt Event of a description of function execution results
|
|
53
|
-
*/
|
|
54
|
-
describe(evt: IAgenticaEventJson.IDescribe): Promise<void>;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Text conversation message.
|
|
58
|
-
*
|
|
59
|
-
* @param evt Event of a text conversation message
|
|
60
|
-
*/
|
|
61
|
-
text(evt: IAgenticaEventJson.IText): Promise<void>;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Initialize the AI agent.
|
|
65
|
-
*
|
|
66
|
-
* Informs an initialization of controller functions from
|
|
67
|
-
* the AI agent server to client.
|
|
68
|
-
*
|
|
69
|
-
* @param evt Event of initialization
|
|
70
|
-
*/
|
|
71
|
-
initialize?(evt: IAgenticaEventJson.IInitialize): Promise<void>;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Select a function to call.
|
|
75
|
-
*
|
|
76
|
-
* Informs a selected function to call from the AI agent server to client.
|
|
77
|
-
*
|
|
78
|
-
* @param evt Event of selecting a function to call
|
|
79
|
-
*/
|
|
80
|
-
select?(evt: IAgenticaEventJson.ISelect): Promise<void>;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Cancel a function to call.
|
|
84
|
-
*
|
|
85
|
-
* Informs a canceling function to call from the AI agent server to client.
|
|
86
|
-
*
|
|
87
|
-
* @param evt Event of canceling a function to call
|
|
88
|
-
*/
|
|
89
|
-
cancel?(evt: IAgenticaEventJson.ICancel): Promise<void>;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Call a function.
|
|
93
|
-
*
|
|
94
|
-
* Informs a function calling from the AI agent server to client.
|
|
95
|
-
*
|
|
96
|
-
* This event comes before the function execution, so that if you return
|
|
97
|
-
* a different value from the original {@link IAgenticaEventJson.ICall.arguments},
|
|
98
|
-
* you can modify the arguments of the function calling.
|
|
99
|
-
*
|
|
100
|
-
* Otherwise you do not return anything (`undefined`) or `null` value, the
|
|
101
|
-
* arguments of the function calling would not be modified. Also, if you are
|
|
102
|
-
* not interested in the function calling event, you can skit its
|
|
103
|
-
* implementation.
|
|
104
|
-
*
|
|
105
|
-
* @param evt Event of a function calling
|
|
106
|
-
* @return New arguments if you want to modify, otherwise null or undefined
|
|
107
|
-
*/
|
|
108
|
-
call?(evt: IAgenticaEventJson.ICall): Promise<object | null | undefined>;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Executition of a function.
|
|
112
|
-
*
|
|
113
|
-
* Informs a function execution from the AI agent server to client.
|
|
114
|
-
*
|
|
115
|
-
* @param evt Event of a function execution
|
|
116
|
-
*/
|
|
117
|
-
execute?(evt: IAgenticaEventJson.IExecute): Promise<void>;
|
|
118
|
-
}
|
|
1
|
+
import { IAgenticaEventJson } from "@agentica/core";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RPC interface of AI agent listener.
|
|
5
|
+
*
|
|
6
|
+
* `IAgenticaRpcListener` is an interface defining an AI agent listener
|
|
7
|
+
* provided from the client to server through the RPC (Remote Procedure Call)
|
|
8
|
+
* paradigm in the websocket protocol.
|
|
9
|
+
*
|
|
10
|
+
* It has defined the event listener functions of {@link AgenticaEvent}
|
|
11
|
+
* types. If you skip some event typed functions' implementations,
|
|
12
|
+
* the skipped event would be ignored.
|
|
13
|
+
*
|
|
14
|
+
* Also, the event like listener functions of `IAgenticaRpcListener` type
|
|
15
|
+
* are remotely called when a client calls the
|
|
16
|
+
* {@link IAgenticaRpcService.conversate} function remotely, so that the
|
|
17
|
+
* server responses to the client by the event listener functions.
|
|
18
|
+
*
|
|
19
|
+
* You can connect to the WebSocket server of the AI agent like below:
|
|
20
|
+
*
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { IAgenticaRpcListener, IAgenticaRpcService } from "@agentica/core";
|
|
23
|
+
* import { Driver, WebSocketConnector } from "tgrid";
|
|
24
|
+
*
|
|
25
|
+
* const connector: WebSocketConnector<
|
|
26
|
+
* null,
|
|
27
|
+
* IAgenticaRpcListener,
|
|
28
|
+
* IAgenticaRpcService
|
|
29
|
+
* > = new WebSocketConnector(null, {
|
|
30
|
+
* text: async (evt) => {
|
|
31
|
+
* console.log(evt.role, evt.text);
|
|
32
|
+
* },
|
|
33
|
+
* describe: async (evt) => {
|
|
34
|
+
* console.log("describer", evt.text);
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* await connector.connect("ws://localhost:3001");
|
|
38
|
+
*
|
|
39
|
+
* const driver: Driver<IAgenticaRpcService> = connector.getDriver();
|
|
40
|
+
* await driver.conversate("Hello, what you can do?");
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @author Samchon
|
|
44
|
+
*/
|
|
45
|
+
export interface IAgenticaRpcListener {
|
|
46
|
+
/**
|
|
47
|
+
* Describe the function executions' results.
|
|
48
|
+
*
|
|
49
|
+
* Inform description message of the function execution's results from
|
|
50
|
+
* the AI agent server to client.
|
|
51
|
+
*
|
|
52
|
+
* @param evt Event of a description of function execution results
|
|
53
|
+
*/
|
|
54
|
+
describe(evt: IAgenticaEventJson.IDescribe): Promise<void>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Text conversation message.
|
|
58
|
+
*
|
|
59
|
+
* @param evt Event of a text conversation message
|
|
60
|
+
*/
|
|
61
|
+
text(evt: IAgenticaEventJson.IText): Promise<void>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Initialize the AI agent.
|
|
65
|
+
*
|
|
66
|
+
* Informs an initialization of controller functions from
|
|
67
|
+
* the AI agent server to client.
|
|
68
|
+
*
|
|
69
|
+
* @param evt Event of initialization
|
|
70
|
+
*/
|
|
71
|
+
initialize?(evt: IAgenticaEventJson.IInitialize): Promise<void>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Select a function to call.
|
|
75
|
+
*
|
|
76
|
+
* Informs a selected function to call from the AI agent server to client.
|
|
77
|
+
*
|
|
78
|
+
* @param evt Event of selecting a function to call
|
|
79
|
+
*/
|
|
80
|
+
select?(evt: IAgenticaEventJson.ISelect): Promise<void>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Cancel a function to call.
|
|
84
|
+
*
|
|
85
|
+
* Informs a canceling function to call from the AI agent server to client.
|
|
86
|
+
*
|
|
87
|
+
* @param evt Event of canceling a function to call
|
|
88
|
+
*/
|
|
89
|
+
cancel?(evt: IAgenticaEventJson.ICancel): Promise<void>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Call a function.
|
|
93
|
+
*
|
|
94
|
+
* Informs a function calling from the AI agent server to client.
|
|
95
|
+
*
|
|
96
|
+
* This event comes before the function execution, so that if you return
|
|
97
|
+
* a different value from the original {@link IAgenticaEventJson.ICall.arguments},
|
|
98
|
+
* you can modify the arguments of the function calling.
|
|
99
|
+
*
|
|
100
|
+
* Otherwise you do not return anything (`undefined`) or `null` value, the
|
|
101
|
+
* arguments of the function calling would not be modified. Also, if you are
|
|
102
|
+
* not interested in the function calling event, you can skit its
|
|
103
|
+
* implementation.
|
|
104
|
+
*
|
|
105
|
+
* @param evt Event of a function calling
|
|
106
|
+
* @return New arguments if you want to modify, otherwise null or undefined
|
|
107
|
+
*/
|
|
108
|
+
call?(evt: IAgenticaEventJson.ICall): Promise<object | null | undefined>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Executition of a function.
|
|
112
|
+
*
|
|
113
|
+
* Informs a function execution from the AI agent server to client.
|
|
114
|
+
*
|
|
115
|
+
* @param evt Event of a function execution
|
|
116
|
+
*/
|
|
117
|
+
execute?(evt: IAgenticaEventJson.IExecute): Promise<void>;
|
|
118
|
+
}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { IAgenticaController } from "@agentica/core";
|
|
2
|
-
import { ILlmSchema } from "@samchon/openapi";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* RPC interface of AI agent service.
|
|
6
|
-
*
|
|
7
|
-
* `IAgenticaRpcService` is an interface defining an AI agent service
|
|
8
|
-
* provided from the server to client through the RPC (Remote Procedure Call)
|
|
9
|
-
* paradigm in the websocket protocol.
|
|
10
|
-
*
|
|
11
|
-
* The client will call the {@link conversate} function remotely, and the
|
|
12
|
-
* server responses to the client by calling the client's
|
|
13
|
-
* {@link IAgenticaRpcListener} functions remotely too.
|
|
14
|
-
*
|
|
15
|
-
* @author Samchon
|
|
16
|
-
*/
|
|
17
|
-
export interface IAgenticaRpcService<Model extends ILlmSchema.Model> {
|
|
18
|
-
/**
|
|
19
|
-
* Conversate with the AI agent.
|
|
20
|
-
*
|
|
21
|
-
* User talks to the AI agent with the content.
|
|
22
|
-
*
|
|
23
|
-
* When AI agent responds some actions like conversating or executing
|
|
24
|
-
* LLM (Large Language Model) function calling, the functions defined in the
|
|
25
|
-
* {@link IAgenticaRpcListener} would be called through the RPC
|
|
26
|
-
* (Remote Procedure Call) paradigm.
|
|
27
|
-
*
|
|
28
|
-
* @param content The content to talk
|
|
29
|
-
* @returns Returned when the conversation process is completely done
|
|
30
|
-
*/
|
|
31
|
-
conversate(content: string): Promise<void>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get controllers.
|
|
35
|
-
*
|
|
36
|
-
* Get controllers, collection of functions that would be
|
|
37
|
-
* called by the AI chatbot.
|
|
38
|
-
*/
|
|
39
|
-
getControllers(): Promise<IAgenticaController<Model>[]>;
|
|
40
|
-
}
|
|
1
|
+
import { IAgenticaController } from "@agentica/core";
|
|
2
|
+
import { ILlmSchema } from "@samchon/openapi";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* RPC interface of AI agent service.
|
|
6
|
+
*
|
|
7
|
+
* `IAgenticaRpcService` is an interface defining an AI agent service
|
|
8
|
+
* provided from the server to client through the RPC (Remote Procedure Call)
|
|
9
|
+
* paradigm in the websocket protocol.
|
|
10
|
+
*
|
|
11
|
+
* The client will call the {@link conversate} function remotely, and the
|
|
12
|
+
* server responses to the client by calling the client's
|
|
13
|
+
* {@link IAgenticaRpcListener} functions remotely too.
|
|
14
|
+
*
|
|
15
|
+
* @author Samchon
|
|
16
|
+
*/
|
|
17
|
+
export interface IAgenticaRpcService<Model extends ILlmSchema.Model> {
|
|
18
|
+
/**
|
|
19
|
+
* Conversate with the AI agent.
|
|
20
|
+
*
|
|
21
|
+
* User talks to the AI agent with the content.
|
|
22
|
+
*
|
|
23
|
+
* When AI agent responds some actions like conversating or executing
|
|
24
|
+
* LLM (Large Language Model) function calling, the functions defined in the
|
|
25
|
+
* {@link IAgenticaRpcListener} would be called through the RPC
|
|
26
|
+
* (Remote Procedure Call) paradigm.
|
|
27
|
+
*
|
|
28
|
+
* @param content The content to talk
|
|
29
|
+
* @returns Returned when the conversation process is completely done
|
|
30
|
+
*/
|
|
31
|
+
conversate(content: string): Promise<void>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get controllers.
|
|
35
|
+
*
|
|
36
|
+
* Get controllers, collection of functions that would be
|
|
37
|
+
* called by the AI chatbot.
|
|
38
|
+
*/
|
|
39
|
+
getControllers(): Promise<IAgenticaController<Model>[]>;
|
|
40
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./IAgenticaRpcListener";
|
|
2
|
-
export * from "./IAgenticaRpcService";
|
|
3
|
-
export * from "./AgenticaRpcService";
|
|
1
|
+
export * from "./IAgenticaRpcListener";
|
|
2
|
+
export * from "./IAgenticaRpcService";
|
|
3
|
+
export * from "./AgenticaRpcService";
|