@rkat/mobkit-sdk 0.4.9
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/dist/agent-builder.d.ts +44 -0
- package/dist/agent-builder.d.ts.map +1 -0
- package/dist/agent-builder.js +111 -0
- package/dist/agent-builder.js.map +1 -0
- package/dist/builder.d.ts +74 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +145 -0
- package/dist/builder.js.map +1 -0
- package/dist/cjs/agent-builder.cjs +114 -0
- package/dist/cjs/builder.cjs +182 -0
- package/dist/cjs/client.cjs +182 -0
- package/dist/cjs/config/auth.cjs +44 -0
- package/dist/cjs/config/index.cjs +51 -0
- package/dist/cjs/config/memory.cjs +28 -0
- package/dist/cjs/config/session-store.cjs +41 -0
- package/dist/cjs/errors.cjs +82 -0
- package/dist/cjs/events.cjs +176 -0
- package/dist/cjs/helpers.cjs +72 -0
- package/dist/cjs/index.cjs +130 -0
- package/dist/cjs/models.cjs +124 -0
- package/dist/cjs/runtime.cjs +476 -0
- package/dist/cjs/sse.cjs +79 -0
- package/dist/cjs/transport.cjs +282 -0
- package/dist/cjs/types.cjs +376 -0
- package/dist/client.d.ts +79 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +178 -0
- package/dist/client.js.map +1 -0
- package/dist/config/auth.d.ts +28 -0
- package/dist/config/auth.d.ts.map +1 -0
- package/dist/config/auth.js +39 -0
- package/dist/config/auth.js.map +1 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +16 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/memory.d.ts +16 -0
- package/dist/config/memory.d.ts.map +1 -0
- package/dist/config/memory.js +25 -0
- package/dist/config/memory.js.map +1 -0
- package/dist/config/session-store.d.ts +23 -0
- package/dist/config/session-store.d.ts.map +1 -0
- package/dist/config/session-store.js +36 -0
- package/dist/config/session-store.js.map +1 -0
- package/dist/errors.d.ts +48 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +74 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +126 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +164 -0
- package/dist/events.js.map +1 -0
- package/dist/helpers.d.ts +58 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +62 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +61 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +118 -0
- package/dist/models.js.map +1 -0
- package/dist/runtime.d.ts +131 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +470 -0
- package/dist/runtime.js.map +1 -0
- package/dist/sse.d.ts +21 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +76 -0
- package/dist/sse.js.map +1 -0
- package/dist/transport.d.ts +84 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +275 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +209 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +348 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MobKit runtime — the running instance returned by the builder.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const rt = await MobKit.builder().mob("mob.toml").gateway(bin).build();
|
|
8
|
+
* const handle = rt.mobHandle();
|
|
9
|
+
*
|
|
10
|
+
* const status = await handle.status();
|
|
11
|
+
* console.log(status.contractVersion, status.loadedModules);
|
|
12
|
+
*
|
|
13
|
+
* await rt.shutdown();
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.SseBridge = exports.ToolCaller = exports.MobHandle = exports.MobKitRuntime = void 0;
|
|
18
|
+
const node_http_1 = require("node:http");
|
|
19
|
+
const node_https_1 = require("node:https");
|
|
20
|
+
const node_fs_1 = require("node:fs");
|
|
21
|
+
const agent_builder_js_1 = require("./agent-builder.cjs");
|
|
22
|
+
const errors_js_1 = require("./errors.cjs");
|
|
23
|
+
const transport_js_1 = require("./transport.cjs");
|
|
24
|
+
const sse_js_1 = require("./sse.cjs");
|
|
25
|
+
const events_js_1 = require("./events.cjs");
|
|
26
|
+
const models_js_1 = require("./models.cjs");
|
|
27
|
+
const types_js_1 = require("./types.cjs");
|
|
28
|
+
// -- Request ID counter ---------------------------------------------------
|
|
29
|
+
let requestCounter = 0;
|
|
30
|
+
function nextRequestId(method) {
|
|
31
|
+
return `${method}:${++requestCounter}`;
|
|
32
|
+
}
|
|
33
|
+
// -- MobKitRuntime --------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Running MobKit runtime instance.
|
|
36
|
+
*
|
|
37
|
+
* Supports explicit lifecycle (`connect` / `shutdown`).
|
|
38
|
+
*/
|
|
39
|
+
class MobKitRuntime {
|
|
40
|
+
_config;
|
|
41
|
+
_transport;
|
|
42
|
+
_running = false;
|
|
43
|
+
_dispatcher = new agent_builder_js_1.CallbackDispatcher();
|
|
44
|
+
_rustHttpBase = null;
|
|
45
|
+
/** @internal */
|
|
46
|
+
constructor(config, transport) {
|
|
47
|
+
this._config = config;
|
|
48
|
+
this._transport = transport ?? null;
|
|
49
|
+
}
|
|
50
|
+
/** @internal */
|
|
51
|
+
static async _create(config) {
|
|
52
|
+
const runtime = new MobKitRuntime(config);
|
|
53
|
+
await runtime._bootstrap();
|
|
54
|
+
return runtime;
|
|
55
|
+
}
|
|
56
|
+
/** Explicitly connect to the runtime. Idempotent. */
|
|
57
|
+
async connect() {
|
|
58
|
+
if (this._running)
|
|
59
|
+
return;
|
|
60
|
+
await this._bootstrap();
|
|
61
|
+
}
|
|
62
|
+
async _bootstrap() {
|
|
63
|
+
if (this._config.gatewayBin) {
|
|
64
|
+
this._transport = new transport_js_1.PersistentTransport(this._config.gatewayBin);
|
|
65
|
+
// Register builder FIRST — init may trigger callback/build_agent
|
|
66
|
+
if (this._config.sessionBuilder) {
|
|
67
|
+
this._dispatcher.registerBuilder(this._config.sessionBuilder);
|
|
68
|
+
}
|
|
69
|
+
if (this._config.errorCallback !== null) {
|
|
70
|
+
this._dispatcher.registerErrorCallback(this._config.errorCallback);
|
|
71
|
+
}
|
|
72
|
+
this._transport.setCallbackHandler(this._dispatcher.handleCallback.bind(this._dispatcher));
|
|
73
|
+
this._transport.start();
|
|
74
|
+
if (!this._transport.isRunning()) {
|
|
75
|
+
throw new errors_js_1.TransportError(`gateway binary failed to start: ${this._config.gatewayBin}`);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const initResult = await this._rpc("mobkit/init", this._buildInitParams());
|
|
79
|
+
if (typeof initResult === "object" &&
|
|
80
|
+
initResult !== null &&
|
|
81
|
+
"http_base_url" in initResult) {
|
|
82
|
+
this._rustHttpBase = String(initResult.http_base_url ?? "") || null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
if (this._transport !== null && !this._transport.isRunning()) {
|
|
87
|
+
throw new errors_js_1.TransportError("gateway process died during bootstrap");
|
|
88
|
+
}
|
|
89
|
+
throw new errors_js_1.TransportError("mobkit/init failed — runtime could not be initialized");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else if (this._config.sessionBuilder) {
|
|
93
|
+
this._dispatcher.registerBuilder(this._config.sessionBuilder);
|
|
94
|
+
}
|
|
95
|
+
this._running = true;
|
|
96
|
+
}
|
|
97
|
+
_buildInitParams() {
|
|
98
|
+
const params = {};
|
|
99
|
+
if (this._config.mobConfigPath) {
|
|
100
|
+
params.mob_config = (0, node_fs_1.readFileSync)(this._config.mobConfigPath, "utf-8");
|
|
101
|
+
}
|
|
102
|
+
if (this._config.modules.length > 0) {
|
|
103
|
+
params.modules = this._config.modules;
|
|
104
|
+
}
|
|
105
|
+
params.has_session_builder = Boolean(this._config.sessionBuilder);
|
|
106
|
+
params.runtime_options = {};
|
|
107
|
+
return params;
|
|
108
|
+
}
|
|
109
|
+
/** @internal */
|
|
110
|
+
async _rpc(method, params) {
|
|
111
|
+
if (this._transport === null) {
|
|
112
|
+
throw new errors_js_1.NotConnectedError("runtime not started — no transport available");
|
|
113
|
+
}
|
|
114
|
+
const rid = nextRequestId(method);
|
|
115
|
+
const request = (0, transport_js_1.buildJsonRpcRequest)(rid, method, params ?? {});
|
|
116
|
+
const response = (await this._transport.sendAsync(request));
|
|
117
|
+
if ("error" in response) {
|
|
118
|
+
const err = response.error;
|
|
119
|
+
throw new errors_js_1.RpcError(Number(err.code ?? -1), String(err.message ?? String(err)), rid, method);
|
|
120
|
+
}
|
|
121
|
+
return response.result;
|
|
122
|
+
}
|
|
123
|
+
get rustHttpBaseUrl() {
|
|
124
|
+
return this._rustHttpBase;
|
|
125
|
+
}
|
|
126
|
+
setRustHttpBase(url) {
|
|
127
|
+
this._rustHttpBase = url;
|
|
128
|
+
}
|
|
129
|
+
mobHandle() {
|
|
130
|
+
return new MobHandle(this);
|
|
131
|
+
}
|
|
132
|
+
sseBridge() {
|
|
133
|
+
return new SseBridge(this);
|
|
134
|
+
}
|
|
135
|
+
async shutdown() {
|
|
136
|
+
this._running = false;
|
|
137
|
+
if (this._transport !== null) {
|
|
138
|
+
this._transport.stop();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
get isRunning() {
|
|
142
|
+
return this._running;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.MobKitRuntime = MobKitRuntime;
|
|
146
|
+
// -- MobHandle ------------------------------------------------------------
|
|
147
|
+
/**
|
|
148
|
+
* Proxy for the MobKit RPC API. Returns typed result objects.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const handle = runtime.mobHandle();
|
|
153
|
+
* const members = await handle.listMembers();
|
|
154
|
+
* await handle.send(members[0].meerkatId, "Hello!");
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
class MobHandle {
|
|
158
|
+
_runtime;
|
|
159
|
+
/** @internal */
|
|
160
|
+
constructor(_runtime) {
|
|
161
|
+
this._runtime = _runtime;
|
|
162
|
+
}
|
|
163
|
+
// -- Status & capabilities ----------------------------------------------
|
|
164
|
+
async status() {
|
|
165
|
+
return (0, types_js_1.parseStatusResult)(await this._runtime._rpc("mobkit/status"));
|
|
166
|
+
}
|
|
167
|
+
async capabilities() {
|
|
168
|
+
return (0, types_js_1.parseCapabilitiesResult)(await this._runtime._rpc("mobkit/capabilities"));
|
|
169
|
+
}
|
|
170
|
+
// -- Spawn & reconcile --------------------------------------------------
|
|
171
|
+
async spawn(spec) {
|
|
172
|
+
return (0, types_js_1.parseSpawnResult)(await this._runtime._rpc("mobkit/spawn_member", (0, models_js_1.discoverySpecToDict)(spec)));
|
|
173
|
+
}
|
|
174
|
+
async spawnMember(moduleId) {
|
|
175
|
+
return (0, types_js_1.parseSpawnResult)(await this._runtime._rpc("mobkit/spawn_member", { module_id: moduleId }));
|
|
176
|
+
}
|
|
177
|
+
async reconcile(modules) {
|
|
178
|
+
return (0, types_js_1.parseReconcileResult)(await this._runtime._rpc("mobkit/reconcile", { modules }));
|
|
179
|
+
}
|
|
180
|
+
// -- Event subscription -------------------------------------------------
|
|
181
|
+
async subscribeEvents(scope = "mob", lastEventId, agentId) {
|
|
182
|
+
const params = { scope };
|
|
183
|
+
if (lastEventId !== undefined)
|
|
184
|
+
params.last_event_id = lastEventId;
|
|
185
|
+
if (agentId !== undefined)
|
|
186
|
+
params.agent_id = agentId;
|
|
187
|
+
return (0, types_js_1.parseSubscribeResult)(await this._runtime._rpc("mobkit/events/subscribe", params));
|
|
188
|
+
}
|
|
189
|
+
async *subscribeAgent(memberId) {
|
|
190
|
+
const bridge = this._runtime.sseBridge();
|
|
191
|
+
for await (const sse of bridge.agentEvents(memberId)) {
|
|
192
|
+
yield (0, events_js_1.parseAgentEventFromSse)(sse);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async *subscribeMob() {
|
|
196
|
+
const bridge = this._runtime.sseBridge();
|
|
197
|
+
for await (const sse of bridge.mobEvents()) {
|
|
198
|
+
yield (0, events_js_1.parseMobEventFromSse)(sse);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async queryEvents(query) {
|
|
202
|
+
const params = query ? (0, types_js_1.eventQueryToDict)(query) : {};
|
|
203
|
+
const raw = await this._runtime._rpc("mobkit/query_events", params);
|
|
204
|
+
if (typeof raw === "object" &&
|
|
205
|
+
raw !== null &&
|
|
206
|
+
raw.status === "no_event_log_configured") {
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
if (Array.isArray(raw)) {
|
|
210
|
+
return raw.map(types_js_1.parsePersistedEvent);
|
|
211
|
+
}
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
// -- Messaging ----------------------------------------------------------
|
|
215
|
+
async send(memberId, message) {
|
|
216
|
+
return (0, types_js_1.parseSendMessageResult)(await this._runtime._rpc("mobkit/send_message", {
|
|
217
|
+
member_id: memberId,
|
|
218
|
+
message,
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
/** Alias for {@link send}. */
|
|
222
|
+
sendMessage = this.send.bind(this);
|
|
223
|
+
async ensureMember(memberId, profile, options) {
|
|
224
|
+
const params = {
|
|
225
|
+
profile,
|
|
226
|
+
meerkat_id: memberId,
|
|
227
|
+
};
|
|
228
|
+
if (options?.labels)
|
|
229
|
+
params.labels = options.labels;
|
|
230
|
+
if (options?.context !== undefined)
|
|
231
|
+
params.context = options.context;
|
|
232
|
+
if (options?.resumeSessionId) {
|
|
233
|
+
params.resume_session_id = options.resumeSessionId;
|
|
234
|
+
}
|
|
235
|
+
if (options?.additionalInstructions) {
|
|
236
|
+
params.additional_instructions = options.additionalInstructions;
|
|
237
|
+
}
|
|
238
|
+
return (0, types_js_1.parseMemberSnapshot)(await this._runtime._rpc("mobkit/ensure_member", params));
|
|
239
|
+
}
|
|
240
|
+
async findMembers(labelKey, labelValue) {
|
|
241
|
+
const raw = await this._runtime._rpc("mobkit/find_members", {
|
|
242
|
+
label_key: labelKey,
|
|
243
|
+
label_value: labelValue,
|
|
244
|
+
});
|
|
245
|
+
if (Array.isArray(raw)) {
|
|
246
|
+
return raw.map(types_js_1.parseMemberSnapshot);
|
|
247
|
+
}
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
// -- Roster -------------------------------------------------------------
|
|
251
|
+
async listMembers() {
|
|
252
|
+
const raw = await this._runtime._rpc("mobkit/list_members");
|
|
253
|
+
if (Array.isArray(raw)) {
|
|
254
|
+
return raw.map(types_js_1.parseMemberSnapshot);
|
|
255
|
+
}
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
async getMember(memberId) {
|
|
259
|
+
return (0, types_js_1.parseMemberSnapshot)(await this._runtime._rpc("mobkit/get_member", { member_id: memberId }));
|
|
260
|
+
}
|
|
261
|
+
async retireMember(memberId) {
|
|
262
|
+
await this._runtime._rpc("mobkit/retire_member", {
|
|
263
|
+
member_id: memberId,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
async respawnMember(memberId) {
|
|
267
|
+
await this._runtime._rpc("mobkit/respawn_member", {
|
|
268
|
+
member_id: memberId,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
// -- Routing ------------------------------------------------------------
|
|
272
|
+
async resolveRouting(recipient, options) {
|
|
273
|
+
return (0, types_js_1.parseRoutingResolution)(await this._runtime._rpc("mobkit/routing/resolve", {
|
|
274
|
+
recipient,
|
|
275
|
+
...(options ?? {}),
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
async listRoutes() {
|
|
279
|
+
const raw = await this._runtime._rpc("mobkit/routing/routes/list");
|
|
280
|
+
const routes = typeof raw === "object" && raw !== null
|
|
281
|
+
? raw.routes ?? []
|
|
282
|
+
: [];
|
|
283
|
+
return routes.map(types_js_1.parseRuntimeRouteResult);
|
|
284
|
+
}
|
|
285
|
+
async addRoute(routeKey, recipient, sink, targetModule, channel) {
|
|
286
|
+
const params = {
|
|
287
|
+
route_key: routeKey,
|
|
288
|
+
recipient,
|
|
289
|
+
sink,
|
|
290
|
+
target_module: targetModule,
|
|
291
|
+
};
|
|
292
|
+
if (channel !== undefined)
|
|
293
|
+
params.channel = channel;
|
|
294
|
+
const raw = await this._runtime._rpc("mobkit/routing/routes/add", params);
|
|
295
|
+
const routeData = typeof raw === "object" && raw !== null
|
|
296
|
+
? raw.route ?? raw
|
|
297
|
+
: raw;
|
|
298
|
+
return (0, types_js_1.parseRuntimeRouteResult)(routeData);
|
|
299
|
+
}
|
|
300
|
+
async deleteRoute(routeKey) {
|
|
301
|
+
const raw = await this._runtime._rpc("mobkit/routing/routes/delete", {
|
|
302
|
+
route_key: routeKey,
|
|
303
|
+
});
|
|
304
|
+
const deletedData = typeof raw === "object" && raw !== null
|
|
305
|
+
? raw.deleted ?? raw
|
|
306
|
+
: raw;
|
|
307
|
+
return (0, types_js_1.parseRuntimeRouteResult)(deletedData);
|
|
308
|
+
}
|
|
309
|
+
// -- Delivery -----------------------------------------------------------
|
|
310
|
+
async sendDelivery(options) {
|
|
311
|
+
return (0, types_js_1.parseDeliveryResult)(await this._runtime._rpc("mobkit/delivery/send", options));
|
|
312
|
+
}
|
|
313
|
+
async deliveryHistory(recipient, sink, limit = 20) {
|
|
314
|
+
const params = { limit };
|
|
315
|
+
if (recipient !== undefined)
|
|
316
|
+
params.recipient = recipient;
|
|
317
|
+
if (sink !== undefined)
|
|
318
|
+
params.sink = sink;
|
|
319
|
+
return (0, types_js_1.parseDeliveryHistoryResult)(await this._runtime._rpc("mobkit/delivery/history", params));
|
|
320
|
+
}
|
|
321
|
+
// -- Memory -------------------------------------------------------------
|
|
322
|
+
async memoryQuery(query, options) {
|
|
323
|
+
return (0, types_js_1.parseMemoryQueryResult)(await this._runtime._rpc("mobkit/memory/query", {
|
|
324
|
+
query,
|
|
325
|
+
...(options ?? {}),
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
async memoryStores() {
|
|
329
|
+
const raw = await this._runtime._rpc("mobkit/memory/stores");
|
|
330
|
+
const stores = typeof raw === "object" && raw !== null
|
|
331
|
+
? raw.stores ?? []
|
|
332
|
+
: [];
|
|
333
|
+
return stores.map(types_js_1.parseMemoryStoreInfo);
|
|
334
|
+
}
|
|
335
|
+
async memoryIndex(entity, topic, store, options) {
|
|
336
|
+
return (0, types_js_1.parseMemoryIndexResult)(await this._runtime._rpc("mobkit/memory/index", {
|
|
337
|
+
entity,
|
|
338
|
+
topic,
|
|
339
|
+
store,
|
|
340
|
+
...(options ?? {}),
|
|
341
|
+
}));
|
|
342
|
+
}
|
|
343
|
+
// -- Tools --------------------------------------------------------------
|
|
344
|
+
async callTool(moduleId, tool, args) {
|
|
345
|
+
const params = { module_id: moduleId, tool };
|
|
346
|
+
if (args)
|
|
347
|
+
params.arguments = args;
|
|
348
|
+
return (0, types_js_1.parseCallToolResult)(await this._runtime._rpc("mobkit/call_tool", params));
|
|
349
|
+
}
|
|
350
|
+
toolCaller(moduleId) {
|
|
351
|
+
return new ToolCaller(this, moduleId);
|
|
352
|
+
}
|
|
353
|
+
// -- Gating -------------------------------------------------------------
|
|
354
|
+
async gatingEvaluate(action, actorId, options) {
|
|
355
|
+
return (0, types_js_1.parseGatingEvaluateResult)(await this._runtime._rpc("mobkit/gating/evaluate", {
|
|
356
|
+
action,
|
|
357
|
+
actor_id: actorId,
|
|
358
|
+
...(options ?? {}),
|
|
359
|
+
}));
|
|
360
|
+
}
|
|
361
|
+
async gatingPending() {
|
|
362
|
+
const raw = await this._runtime._rpc("mobkit/gating/pending");
|
|
363
|
+
const entries = typeof raw === "object" && raw !== null
|
|
364
|
+
? raw.pending ?? []
|
|
365
|
+
: [];
|
|
366
|
+
return entries.map(types_js_1.parseGatingPendingEntry);
|
|
367
|
+
}
|
|
368
|
+
async gatingDecide(pendingId, decision, approverId, options) {
|
|
369
|
+
return (0, types_js_1.parseGatingDecisionResult)(await this._runtime._rpc("mobkit/gating/decide", {
|
|
370
|
+
pending_id: pendingId,
|
|
371
|
+
decision,
|
|
372
|
+
approver_id: approverId,
|
|
373
|
+
...(options ?? {}),
|
|
374
|
+
}));
|
|
375
|
+
}
|
|
376
|
+
async gatingAudit(limit = 100) {
|
|
377
|
+
const raw = await this._runtime._rpc("mobkit/gating/audit", { limit });
|
|
378
|
+
const entries = typeof raw === "object" && raw !== null
|
|
379
|
+
? raw.entries ?? []
|
|
380
|
+
: [];
|
|
381
|
+
return entries.map(types_js_1.parseGatingAuditEntry);
|
|
382
|
+
}
|
|
383
|
+
// -- Topology -----------------------------------------------------------
|
|
384
|
+
async rediscover() {
|
|
385
|
+
const raw = await this._runtime._rpc("mobkit/rediscover");
|
|
386
|
+
if (typeof raw === "object" &&
|
|
387
|
+
raw !== null &&
|
|
388
|
+
"status" in raw) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
return (0, types_js_1.parseRediscoverReport)(raw);
|
|
392
|
+
}
|
|
393
|
+
async reconcileEdges() {
|
|
394
|
+
return (0, types_js_1.parseReconcileEdgesReport)(await this._runtime._rpc("mobkit/reconcile_edges"));
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
exports.MobHandle = MobHandle;
|
|
398
|
+
// -- ToolCaller -----------------------------------------------------------
|
|
399
|
+
/**
|
|
400
|
+
* Bound callable scoped to one MCP module.
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```ts
|
|
404
|
+
* const gmail = handle.toolCaller("google-workspace");
|
|
405
|
+
* const messages = await gmail.call("gmail_search", { query: "is:unread" });
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
class ToolCaller {
|
|
409
|
+
_mobHandle;
|
|
410
|
+
_moduleId;
|
|
411
|
+
constructor(_mobHandle, _moduleId) {
|
|
412
|
+
this._mobHandle = _mobHandle;
|
|
413
|
+
this._moduleId = _moduleId;
|
|
414
|
+
}
|
|
415
|
+
async call(tool, args) {
|
|
416
|
+
const result = await this._mobHandle.callTool(this._moduleId, tool, args);
|
|
417
|
+
return result.result;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
exports.ToolCaller = ToolCaller;
|
|
421
|
+
// -- SseBridge ------------------------------------------------------------
|
|
422
|
+
/**
|
|
423
|
+
* Bridge for streaming SSE from the Rust backend's HTTP server.
|
|
424
|
+
*/
|
|
425
|
+
class SseBridge {
|
|
426
|
+
_runtime;
|
|
427
|
+
constructor(_runtime) {
|
|
428
|
+
this._runtime = _runtime;
|
|
429
|
+
}
|
|
430
|
+
_baseUrl() {
|
|
431
|
+
const base = this._runtime.rustHttpBaseUrl;
|
|
432
|
+
if (base === null) {
|
|
433
|
+
throw new errors_js_1.NotConnectedError("SSE bridge requires rustHttpBaseUrl — set it via " +
|
|
434
|
+
"runtime.setRustHttpBase('http://127.0.0.1:8081') or " +
|
|
435
|
+
"ensure the Rust binary reports it during bootstrap");
|
|
436
|
+
}
|
|
437
|
+
return base;
|
|
438
|
+
}
|
|
439
|
+
async *agentEvents(agentId) {
|
|
440
|
+
const url = `${this._baseUrl()}/agents/${agentId}/events`;
|
|
441
|
+
yield* this._streamSse(url);
|
|
442
|
+
}
|
|
443
|
+
async *mobEvents() {
|
|
444
|
+
const url = `${this._baseUrl()}/mob/events`;
|
|
445
|
+
yield* this._streamSse(url);
|
|
446
|
+
}
|
|
447
|
+
async *_streamSse(url) {
|
|
448
|
+
const body = await this._fetchSseStream(url);
|
|
449
|
+
yield* (0, sse_js_1.parseSseStream)(body);
|
|
450
|
+
}
|
|
451
|
+
_fetchSseStream(url) {
|
|
452
|
+
const parsed = new URL(url);
|
|
453
|
+
const requester = parsed.protocol === "https:" ? node_https_1.request : node_http_1.request;
|
|
454
|
+
return new Promise((resolve, reject) => {
|
|
455
|
+
const req = requester(url, { method: "GET", headers: { accept: "text/event-stream" } }, (res) => {
|
|
456
|
+
if (!res.statusCode || res.statusCode >= 400) {
|
|
457
|
+
reject(new Error(`SSE request failed: ${res.statusCode} ${res.statusMessage}`));
|
|
458
|
+
res.resume();
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
// Convert Node readable stream to AsyncIterable<Uint8Array>
|
|
462
|
+
const stream = (async function* () {
|
|
463
|
+
for await (const chunk of res) {
|
|
464
|
+
yield chunk instanceof Uint8Array
|
|
465
|
+
? chunk
|
|
466
|
+
: new TextEncoder().encode(String(chunk));
|
|
467
|
+
}
|
|
468
|
+
})();
|
|
469
|
+
resolve(stream);
|
|
470
|
+
});
|
|
471
|
+
req.on("error", reject);
|
|
472
|
+
req.end();
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
exports.SseBridge = SseBridge;
|
package/dist/cjs/sse.cjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SSE (Server-Sent Events) parsing and encoding.
|
|
4
|
+
*
|
|
5
|
+
* Internal module — not exported from the barrel. Used by the runtime
|
|
6
|
+
* SSE bridge for streaming agent and mob events.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.encodeSseEvent = encodeSseEvent;
|
|
10
|
+
exports.parseSseStream = parseSseStream;
|
|
11
|
+
// -- Encoding -------------------------------------------------------------
|
|
12
|
+
/** Serialize an SSE event to the wire format. */
|
|
13
|
+
function encodeSseEvent(event) {
|
|
14
|
+
const lines = [];
|
|
15
|
+
if (event.id !== null) {
|
|
16
|
+
lines.push(`id: ${event.id}`);
|
|
17
|
+
}
|
|
18
|
+
if (event.event !== "message") {
|
|
19
|
+
lines.push(`event: ${event.event}`);
|
|
20
|
+
}
|
|
21
|
+
for (const line of event.data.split("\n")) {
|
|
22
|
+
lines.push(`data: ${line}`);
|
|
23
|
+
}
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push("");
|
|
26
|
+
return lines.join("\n");
|
|
27
|
+
}
|
|
28
|
+
// -- Parsing --------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Parse an SSE byte stream into typed {@link SseEvent} objects.
|
|
31
|
+
*
|
|
32
|
+
* Handles `id:`, `event:`, `data:` fields and comment lines (`:` prefix).
|
|
33
|
+
* Events are emitted on blank-line boundaries per the SSE spec.
|
|
34
|
+
*/
|
|
35
|
+
async function* parseSseStream(body) {
|
|
36
|
+
const decoder = new TextDecoder("utf-8");
|
|
37
|
+
let buffer = "";
|
|
38
|
+
let currentId = null;
|
|
39
|
+
let currentEvent = "message";
|
|
40
|
+
const currentData = [];
|
|
41
|
+
for await (const chunk of body) {
|
|
42
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
43
|
+
while (buffer.includes("\n")) {
|
|
44
|
+
const idx = buffer.indexOf("\n");
|
|
45
|
+
let line = buffer.slice(0, idx);
|
|
46
|
+
buffer = buffer.slice(idx + 1);
|
|
47
|
+
line = line.replace(/\r$/, "");
|
|
48
|
+
if (line === "") {
|
|
49
|
+
// Blank line — emit event if we have data
|
|
50
|
+
if (currentData.length > 0) {
|
|
51
|
+
yield {
|
|
52
|
+
id: currentId,
|
|
53
|
+
event: currentEvent,
|
|
54
|
+
data: currentData.join("\n"),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
currentId = null;
|
|
58
|
+
currentEvent = "message";
|
|
59
|
+
currentData.length = 0;
|
|
60
|
+
}
|
|
61
|
+
else if (line.startsWith(":")) {
|
|
62
|
+
// Comment — skip
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
else if (line.startsWith("id: ")) {
|
|
66
|
+
currentId = line.slice(4);
|
|
67
|
+
}
|
|
68
|
+
else if (line.startsWith("event: ")) {
|
|
69
|
+
currentEvent = line.slice(7);
|
|
70
|
+
}
|
|
71
|
+
else if (line.startsWith("data: ")) {
|
|
72
|
+
currentData.push(line.slice(6));
|
|
73
|
+
}
|
|
74
|
+
else if (line.startsWith("data:")) {
|
|
75
|
+
currentData.push(line.slice(5));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|