@mantyx/sdk 0.1.1 → 0.3.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/CHANGELOG.md +19 -1
- package/README.md +213 -14
- package/dist/a2a-server.cjs +404 -0
- package/dist/a2a-server.cjs.map +1 -0
- package/dist/a2a-server.d.cts +170 -0
- package/dist/a2a-server.d.ts +170 -0
- package/dist/a2a-server.js +344 -0
- package/dist/a2a-server.js.map +1 -0
- package/dist/chunk-ZJINVTHD.js +1080 -0
- package/dist/chunk-ZJINVTHD.js.map +1 -0
- package/dist/client-Ce02_fV8.d.cts +591 -0
- package/dist/client-Ce02_fV8.d.ts +591 -0
- package/dist/index.cjs +591 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -261
- package/dist/index.d.ts +3 -261
- package/dist/index.js +30 -587
- package/dist/index.js.map +1 -1
- package/docs/agent-runs-protocol.md +370 -18
- package/package.json +24 -3
package/dist/index.js
CHANGED
|
@@ -1,592 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
constructor(message = "Invalid or missing API key") {
|
|
25
|
-
super(message, { code: "unauthorized", status: 401 });
|
|
26
|
-
this.name = "MantyxAuthError";
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var MantyxToolError = class extends MantyxError {
|
|
30
|
-
toolName;
|
|
31
|
-
constructor(toolName, message) {
|
|
32
|
-
super(`Local tool ${JSON.stringify(toolName)} failed: ${message}`, {
|
|
33
|
-
code: "local_tool_failed"
|
|
34
|
-
});
|
|
35
|
-
this.name = "MantyxToolError";
|
|
36
|
-
this.toolName = toolName;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var MantyxRunError = class extends MantyxError {
|
|
40
|
-
runId;
|
|
41
|
-
subtype;
|
|
42
|
-
constructor(runId, subtype, message) {
|
|
43
|
-
super(message, { code: subtype });
|
|
44
|
-
this.name = "MantyxRunError";
|
|
45
|
-
this.runId = runId;
|
|
46
|
-
this.subtype = subtype;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// src/sse.ts
|
|
51
|
-
async function* readSseStream(body, opts = {}) {
|
|
52
|
-
if (!body) return;
|
|
53
|
-
const reader = body.getReader();
|
|
54
|
-
const decoder = new TextDecoder("utf-8");
|
|
55
|
-
let buffer = "";
|
|
56
|
-
let cancelled = false;
|
|
57
|
-
const onAbort = () => {
|
|
58
|
-
cancelled = true;
|
|
59
|
-
try {
|
|
60
|
-
void reader.cancel();
|
|
61
|
-
} catch {
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
if (opts.signal) {
|
|
65
|
-
if (opts.signal.aborted) {
|
|
66
|
-
onAbort();
|
|
67
|
-
} else {
|
|
68
|
-
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
while (!cancelled) {
|
|
73
|
-
const { done, value } = await reader.read();
|
|
74
|
-
if (done) break;
|
|
75
|
-
buffer += decoder.decode(value, { stream: true });
|
|
76
|
-
let sepIdx;
|
|
77
|
-
while ((sepIdx = findSeparator(buffer)) !== -1) {
|
|
78
|
-
const raw = buffer.slice(0, sepIdx);
|
|
79
|
-
buffer = buffer.slice(sepIdx + (buffer.startsWith("\r", sepIdx) ? 4 : 2));
|
|
80
|
-
const ev = parseEventBlock(raw);
|
|
81
|
-
if (ev) yield ev;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
} finally {
|
|
85
|
-
if (opts.signal) opts.signal.removeEventListener("abort", onAbort);
|
|
86
|
-
try {
|
|
87
|
-
reader.releaseLock();
|
|
88
|
-
} catch {
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
function findSeparator(s) {
|
|
93
|
-
const lf = s.indexOf("\n\n");
|
|
94
|
-
const crlf = s.indexOf("\r\n\r\n");
|
|
95
|
-
if (lf === -1) return crlf;
|
|
96
|
-
if (crlf === -1) return lf;
|
|
97
|
-
return Math.min(lf, crlf);
|
|
98
|
-
}
|
|
99
|
-
function parseEventBlock(block) {
|
|
100
|
-
const lines = block.split(/\r?\n/);
|
|
101
|
-
let id;
|
|
102
|
-
let event;
|
|
103
|
-
const dataLines = [];
|
|
104
|
-
for (const line of lines) {
|
|
105
|
-
if (line.length === 0) continue;
|
|
106
|
-
if (line.startsWith(":")) continue;
|
|
107
|
-
const colonIdx = line.indexOf(":");
|
|
108
|
-
const field = colonIdx === -1 ? line : line.slice(0, colonIdx);
|
|
109
|
-
let value = colonIdx === -1 ? "" : line.slice(colonIdx + 1);
|
|
110
|
-
if (value.startsWith(" ")) value = value.slice(1);
|
|
111
|
-
if (field === "id") id = value;
|
|
112
|
-
else if (field === "event") event = value;
|
|
113
|
-
else if (field === "data") dataLines.push(value);
|
|
114
|
-
}
|
|
115
|
-
if (dataLines.length === 0 && id === void 0 && event === void 0) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
...id !== void 0 ? { id } : {},
|
|
120
|
-
...event !== void 0 ? { event } : {},
|
|
121
|
-
data: dataLines.join("\n")
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// src/tools.ts
|
|
126
|
-
function defineLocalTool(opts) {
|
|
127
|
-
if (!/^[a-zA-Z0-9_]{1,64}$/.test(opts.name)) {
|
|
128
|
-
throw new Error(
|
|
129
|
-
`Invalid local tool name ${JSON.stringify(opts.name)}: must match /^[a-zA-Z0-9_]{1,64}$/`
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
kind: "local",
|
|
134
|
-
name: opts.name,
|
|
135
|
-
description: opts.description ?? "",
|
|
136
|
-
parameters: opts.parameters,
|
|
137
|
-
execute: opts.execute
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
function mantyxTool(id) {
|
|
141
|
-
if (typeof id !== "string" || id.length === 0) {
|
|
142
|
-
throw new Error("mantyxTool(id): id must be a non-empty string");
|
|
143
|
-
}
|
|
144
|
-
return { kind: "mantyx", id };
|
|
145
|
-
}
|
|
146
|
-
function mantyxPluginTool(name) {
|
|
147
|
-
if (typeof name !== "string" || !name.startsWith("@") || !name.includes("/")) {
|
|
148
|
-
throw new Error(
|
|
149
|
-
`mantyxPluginTool(name): expected "@plugin-slug/tool-name", got ${JSON.stringify(name)}`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
return { kind: "mantyx_plugin", name };
|
|
153
|
-
}
|
|
154
|
-
function isLocalTool(t) {
|
|
155
|
-
return t.kind === "local";
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// src/zod-to-json-schema.ts
|
|
159
|
-
import { z } from "zod";
|
|
160
|
-
function zodToJsonSchema(schema) {
|
|
161
|
-
const builtIn = z.toJSONSchema;
|
|
162
|
-
if (typeof builtIn === "function") {
|
|
163
|
-
try {
|
|
164
|
-
const out = builtIn.call(z, schema);
|
|
165
|
-
if (out && typeof out === "object") return out;
|
|
166
|
-
} catch {
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return convertNode(schema);
|
|
170
|
-
}
|
|
171
|
-
function convertNode(schema) {
|
|
172
|
-
const def = schema._def;
|
|
173
|
-
const typeName = def?.typeName;
|
|
174
|
-
switch (typeName) {
|
|
175
|
-
case "ZodString":
|
|
176
|
-
return { type: "string" };
|
|
177
|
-
case "ZodNumber":
|
|
178
|
-
return { type: "number" };
|
|
179
|
-
case "ZodBoolean":
|
|
180
|
-
return { type: "boolean" };
|
|
181
|
-
case "ZodNull":
|
|
182
|
-
return { type: "null" };
|
|
183
|
-
case "ZodLiteral": {
|
|
184
|
-
const value = def.value;
|
|
185
|
-
return { const: value, type: typeof value };
|
|
186
|
-
}
|
|
187
|
-
case "ZodEnum": {
|
|
188
|
-
const values = def.values ?? [];
|
|
189
|
-
return { type: "string", enum: [...values] };
|
|
190
|
-
}
|
|
191
|
-
case "ZodArray": {
|
|
192
|
-
const inner = def.type;
|
|
193
|
-
return {
|
|
194
|
-
type: "array",
|
|
195
|
-
items: inner ? convertNode(inner) : {}
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
case "ZodOptional":
|
|
199
|
-
case "ZodNullable": {
|
|
200
|
-
const inner = def.innerType;
|
|
201
|
-
return inner ? convertNode(inner) : {};
|
|
202
|
-
}
|
|
203
|
-
case "ZodDefault": {
|
|
204
|
-
const inner = def.innerType;
|
|
205
|
-
return inner ? convertNode(inner) : {};
|
|
206
|
-
}
|
|
207
|
-
case "ZodObject": {
|
|
208
|
-
const shape = def.shape;
|
|
209
|
-
const fields = typeof shape === "function" ? shape() : shape;
|
|
210
|
-
const properties = {};
|
|
211
|
-
const required = [];
|
|
212
|
-
if (fields) {
|
|
213
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
214
|
-
properties[key] = convertNode(value);
|
|
215
|
-
const innerDef = value._def;
|
|
216
|
-
const innerTypeName = innerDef?.typeName;
|
|
217
|
-
if (innerTypeName !== "ZodOptional" && innerTypeName !== "ZodDefault") {
|
|
218
|
-
required.push(key);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const out = { type: "object", properties };
|
|
223
|
-
if (required.length > 0) out.required = required;
|
|
224
|
-
return out;
|
|
225
|
-
}
|
|
226
|
-
default:
|
|
227
|
-
return {};
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
function toToolParametersWire(parameters) {
|
|
231
|
-
if (!parameters) return { type: "object", properties: {} };
|
|
232
|
-
if (typeof parameters._def !== "undefined") {
|
|
233
|
-
return zodToJsonSchema(parameters);
|
|
234
|
-
}
|
|
235
|
-
return parameters;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// src/client.ts
|
|
239
|
-
var DEFAULT_BASE_URL = "https://api.mantyx.com";
|
|
240
|
-
var MantyxClient = class {
|
|
241
|
-
options;
|
|
242
|
-
constructor(opts) {
|
|
243
|
-
if (!opts.apiKey || typeof opts.apiKey !== "string") {
|
|
244
|
-
throw new MantyxError("apiKey is required");
|
|
245
|
-
}
|
|
246
|
-
if (!opts.workspaceSlug || typeof opts.workspaceSlug !== "string") {
|
|
247
|
-
throw new MantyxError("workspaceSlug is required");
|
|
248
|
-
}
|
|
249
|
-
const f = opts.fetch ?? globalThis.fetch;
|
|
250
|
-
if (typeof f !== "function") {
|
|
251
|
-
throw new MantyxError(
|
|
252
|
-
"Global fetch is not available; pass a custom `fetch` implementation in MantyxClientOptions."
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
this.options = {
|
|
256
|
-
apiKey: opts.apiKey,
|
|
257
|
-
workspaceSlug: opts.workspaceSlug,
|
|
258
|
-
baseUrl: (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, ""),
|
|
259
|
-
fetch: f,
|
|
260
|
-
timeoutMs: opts.timeoutMs ?? 6e4
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
// -------------------------------------------------------------- Models
|
|
264
|
-
async listModels() {
|
|
265
|
-
return this.request({
|
|
266
|
-
method: "GET",
|
|
267
|
-
path: "/models"
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
// ------------------------------------------------------------- One-shot
|
|
271
|
-
async runAgent(spec) {
|
|
272
|
-
const handlers = collectLocalHandlers(spec.tools ?? []);
|
|
273
|
-
const created = await this.request({
|
|
274
|
-
method: "POST",
|
|
275
|
-
path: "/agent-runs",
|
|
276
|
-
body: serializeAgentSpec(spec, {
|
|
277
|
-
prompt: spec.prompt,
|
|
278
|
-
messages: spec.messages
|
|
279
|
-
})
|
|
280
|
-
});
|
|
281
|
-
return this.driveRun(created.runId, handlers, {
|
|
282
|
-
...spec.onAssistantDelta ? { onAssistantDelta: spec.onAssistantDelta } : {},
|
|
283
|
-
...spec.onEvent ? { onEvent: spec.onEvent } : {},
|
|
284
|
-
...spec.signal ? { signal: spec.signal } : {}
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
async *streamAgent(spec) {
|
|
288
|
-
const handlers = collectLocalHandlers(spec.tools ?? []);
|
|
289
|
-
const created = await this.request({
|
|
290
|
-
method: "POST",
|
|
291
|
-
path: "/agent-runs",
|
|
292
|
-
body: serializeAgentSpec(spec, {
|
|
293
|
-
prompt: spec.prompt,
|
|
294
|
-
messages: spec.messages
|
|
295
|
-
})
|
|
296
|
-
});
|
|
297
|
-
yield* this.streamRunEvents(created.runId, handlers, spec.signal);
|
|
298
|
-
}
|
|
299
|
-
// ------------------------------------------------------------- Sessions
|
|
300
|
-
async createSession(spec) {
|
|
301
|
-
const handlers = collectLocalHandlers(spec.tools ?? []);
|
|
302
|
-
const created = await this.request({
|
|
303
|
-
method: "POST",
|
|
304
|
-
path: "/agent-sessions",
|
|
305
|
-
body: serializeAgentSpec(spec)
|
|
306
|
-
});
|
|
307
|
-
return new AgentSession(this, created.sessionId, handlers);
|
|
308
|
-
}
|
|
309
|
-
async resumeSession(sessionId, opts = {}) {
|
|
310
|
-
await this.getSessionInfo(sessionId);
|
|
311
|
-
const handlers = collectLocalHandlers(opts.tools ?? []);
|
|
312
|
-
return new AgentSession(this, sessionId, handlers, opts.tools);
|
|
313
|
-
}
|
|
314
|
-
async endSession(sessionId) {
|
|
315
|
-
await this.request({
|
|
316
|
-
method: "DELETE",
|
|
317
|
-
path: `/agent-sessions/${encodeURIComponent(sessionId)}`
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
async getSessionInfo(sessionId) {
|
|
321
|
-
return this.request({
|
|
322
|
-
method: "GET",
|
|
323
|
-
path: `/agent-sessions/${encodeURIComponent(sessionId)}`
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
// ----------------------------------------------------------- Internals
|
|
327
|
-
/** Drive an existing run to completion (collect events, dispatch local tools). */
|
|
328
|
-
async driveRun(runId, handlers, opts = {}) {
|
|
329
|
-
const collected = [];
|
|
330
|
-
let finalText = "";
|
|
331
|
-
for await (const ev of this.streamRunEvents(runId, handlers, opts.signal)) {
|
|
332
|
-
collected.push(ev);
|
|
333
|
-
if (opts.onEvent) opts.onEvent(ev);
|
|
334
|
-
if (ev.type === "assistant_delta" && opts.onAssistantDelta) {
|
|
335
|
-
opts.onAssistantDelta(ev.text);
|
|
336
|
-
}
|
|
337
|
-
if (ev.type === "result") {
|
|
338
|
-
const r = ev;
|
|
339
|
-
if (r.subtype === "success") {
|
|
340
|
-
finalText = typeof r.text === "string" ? r.text : "";
|
|
341
|
-
} else {
|
|
342
|
-
throw new MantyxRunError(runId, r.subtype, r.error ?? r.subtype);
|
|
343
|
-
}
|
|
344
|
-
} else if (ev.type === "error") {
|
|
345
|
-
const e = ev;
|
|
346
|
-
throw new MantyxRunError(runId, e.code ?? "error", e.error);
|
|
347
|
-
} else if (ev.type === "cancelled") {
|
|
348
|
-
throw new MantyxRunError(runId, "cancelled", "Run was cancelled");
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return { runId, text: finalText, events: collected };
|
|
352
|
-
}
|
|
353
|
-
async *streamRunEvents(runId, handlers, signal) {
|
|
354
|
-
const url = this.absoluteUrl(`/agent-runs/${encodeURIComponent(runId)}/stream`);
|
|
355
|
-
let lastSeq = 0;
|
|
356
|
-
while (true) {
|
|
357
|
-
const reqUrl = lastSeq > 0 ? `${url}?lastSeq=${lastSeq}` : url;
|
|
358
|
-
const res = await this.options.fetch(reqUrl, {
|
|
359
|
-
method: "GET",
|
|
360
|
-
headers: {
|
|
361
|
-
...this.authHeaders(),
|
|
362
|
-
Accept: "text/event-stream",
|
|
363
|
-
...lastSeq > 0 ? { "Last-Event-ID": String(lastSeq) } : {}
|
|
364
|
-
},
|
|
365
|
-
...signal ? { signal } : {}
|
|
366
|
-
}).catch((err) => {
|
|
367
|
-
throw new MantyxNetworkError(`Failed to open SSE stream: ${err.message}`, {
|
|
368
|
-
cause: err
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
if (!res.ok) {
|
|
372
|
-
throw await this.errorFromResponse(res);
|
|
373
|
-
}
|
|
374
|
-
let terminal = false;
|
|
375
|
-
try {
|
|
376
|
-
for await (const sseEvent of readSseStream(res.body, { ...signal ? { signal } : {} })) {
|
|
377
|
-
let data = {};
|
|
378
|
-
try {
|
|
379
|
-
data = JSON.parse(sseEvent.data || "{}");
|
|
380
|
-
} catch {
|
|
381
|
-
data = {};
|
|
382
|
-
}
|
|
383
|
-
const evType = sseEvent.event ?? data.type ?? "message";
|
|
384
|
-
const seq = typeof data.seq === "number" ? data.seq : lastSeq;
|
|
385
|
-
if (typeof seq === "number" && seq > lastSeq) lastSeq = seq;
|
|
386
|
-
const ev = { seq, type: evType, ...data };
|
|
387
|
-
yield ev;
|
|
388
|
-
if (evType === "local_tool_call") {
|
|
389
|
-
const localEv = ev;
|
|
390
|
-
void this.dispatchLocalTool(runId, localEv, handlers).catch((err) => {
|
|
391
|
-
console.error("[mantyx-sdk] local tool dispatch failed:", err);
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
if (evType === "result" || evType === "error" || evType === "cancelled") {
|
|
395
|
-
terminal = true;
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
} catch (err) {
|
|
400
|
-
if (signal?.aborted) {
|
|
401
|
-
throw new MantyxRunError(runId, "cancelled", "Run was cancelled by the client");
|
|
402
|
-
}
|
|
403
|
-
await sleep(500);
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
if (terminal) return;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
async dispatchLocalTool(runId, ev, handlers) {
|
|
410
|
-
const handler = handlers.get(ev.name);
|
|
411
|
-
if (!handler) {
|
|
412
|
-
await this.postToolResult(runId, ev.toolUseId, {
|
|
413
|
-
error: `No local handler registered for tool ${JSON.stringify(ev.name)}`
|
|
414
|
-
});
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
try {
|
|
418
|
-
const args = handler.parameters ? handler.parameters.parse?.(ev.args) ?? ev.args : ev.args;
|
|
419
|
-
const out = await handler.execute(args);
|
|
420
|
-
const resultText = typeof out === "string" ? out : JSON.stringify(out);
|
|
421
|
-
await this.postToolResult(runId, ev.toolUseId, { result: resultText });
|
|
422
|
-
} catch (err) {
|
|
423
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
424
|
-
await this.postToolResult(runId, ev.toolUseId, {
|
|
425
|
-
error: new MantyxToolError(handler.name, message).message
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
async postToolResult(runId, toolUseId, payload) {
|
|
430
|
-
await this.request({
|
|
431
|
-
method: "POST",
|
|
432
|
-
path: `/agent-runs/${encodeURIComponent(runId)}/tool-results`,
|
|
433
|
-
body: { toolUseId, ...payload }
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
async cancelRun(runId) {
|
|
437
|
-
await this.request({
|
|
438
|
-
method: "POST",
|
|
439
|
-
path: `/agent-runs/${encodeURIComponent(runId)}/cancel`
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
// -------------------------------------------------------------- HTTP
|
|
443
|
-
absoluteUrl(path) {
|
|
444
|
-
return `${this.options.baseUrl}/api/v1/workspaces/${encodeURIComponent(this.options.workspaceSlug)}${path}`;
|
|
445
|
-
}
|
|
446
|
-
authHeaders() {
|
|
447
|
-
return { Authorization: `Bearer ${this.options.apiKey}` };
|
|
448
|
-
}
|
|
449
|
-
async request(args) {
|
|
450
|
-
const url = this.absoluteUrl(args.path);
|
|
451
|
-
const ctrl = new AbortController();
|
|
452
|
-
const t = setTimeout(() => ctrl.abort(), args.timeoutMs ?? this.options.timeoutMs);
|
|
453
|
-
try {
|
|
454
|
-
const res = await this.options.fetch(url, {
|
|
455
|
-
method: args.method,
|
|
456
|
-
headers: {
|
|
457
|
-
...this.authHeaders(),
|
|
458
|
-
...args.body !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
459
|
-
Accept: "application/json"
|
|
460
|
-
},
|
|
461
|
-
...args.body !== void 0 ? { body: JSON.stringify(args.body) } : {},
|
|
462
|
-
signal: ctrl.signal
|
|
463
|
-
}).catch((err) => {
|
|
464
|
-
if (ctrl.signal.aborted) {
|
|
465
|
-
throw new MantyxNetworkError(`Request timed out after ${args.timeoutMs ?? this.options.timeoutMs}ms`);
|
|
466
|
-
}
|
|
467
|
-
throw new MantyxNetworkError(`Network error: ${err.message}`, { cause: err });
|
|
468
|
-
});
|
|
469
|
-
if (!res.ok) {
|
|
470
|
-
throw await this.errorFromResponse(res);
|
|
471
|
-
}
|
|
472
|
-
const text = await res.text();
|
|
473
|
-
if (!text) return void 0;
|
|
474
|
-
try {
|
|
475
|
-
return JSON.parse(text);
|
|
476
|
-
} catch (err) {
|
|
477
|
-
throw new MantyxError(`Failed to parse JSON response: ${err.message}`);
|
|
478
|
-
}
|
|
479
|
-
} finally {
|
|
480
|
-
clearTimeout(t);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
async errorFromResponse(res) {
|
|
484
|
-
let body = {};
|
|
485
|
-
try {
|
|
486
|
-
body = await res.json();
|
|
487
|
-
} catch {
|
|
488
|
-
}
|
|
489
|
-
if (res.status === 401) {
|
|
490
|
-
return new MantyxAuthError(body.error ?? "Invalid API key");
|
|
491
|
-
}
|
|
492
|
-
return new MantyxError(body.error ?? `HTTP ${res.status}`, {
|
|
493
|
-
code: body.code ?? `http_${res.status}`,
|
|
494
|
-
status: res.status,
|
|
495
|
-
...body.hint ? { hint: body.hint } : {}
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
};
|
|
499
|
-
var AgentSession = class {
|
|
500
|
-
id;
|
|
501
|
-
client;
|
|
502
|
-
handlers;
|
|
503
|
-
toolsForResume;
|
|
504
|
-
constructor(client, id, handlers, toolsForResume) {
|
|
505
|
-
this.client = client;
|
|
506
|
-
this.id = id;
|
|
507
|
-
this.handlers = handlers;
|
|
508
|
-
this.toolsForResume = toolsForResume;
|
|
509
|
-
}
|
|
510
|
-
async send(prompt, opts = {}) {
|
|
511
|
-
const created = await this.client.request({
|
|
512
|
-
method: "POST",
|
|
513
|
-
path: `/agent-sessions/${encodeURIComponent(this.id)}/messages`,
|
|
514
|
-
body: {
|
|
515
|
-
prompt,
|
|
516
|
-
...this.toolsForResume ? { tools: serializeToolRefs(this.toolsForResume) } : {},
|
|
517
|
-
...opts.metadata && Object.keys(opts.metadata).length > 0 ? { metadata: opts.metadata } : {}
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
return this.client.driveRun(created.runId, this.handlers, {
|
|
521
|
-
...opts.onAssistantDelta ? { onAssistantDelta: opts.onAssistantDelta } : {},
|
|
522
|
-
...opts.signal ? { signal: opts.signal } : {}
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
async *stream(prompt, opts = {}) {
|
|
526
|
-
const created = await this.client.request({
|
|
527
|
-
method: "POST",
|
|
528
|
-
path: `/agent-sessions/${encodeURIComponent(this.id)}/messages`,
|
|
529
|
-
body: {
|
|
530
|
-
prompt,
|
|
531
|
-
...this.toolsForResume ? { tools: serializeToolRefs(this.toolsForResume) } : {},
|
|
532
|
-
...opts.metadata && Object.keys(opts.metadata).length > 0 ? { metadata: opts.metadata } : {}
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
yield* this.client.streamRunEvents(created.runId, this.handlers, opts.signal);
|
|
536
|
-
}
|
|
537
|
-
async history() {
|
|
538
|
-
const info = await this.client.getSessionInfo(this.id);
|
|
539
|
-
return info.messages;
|
|
540
|
-
}
|
|
541
|
-
async info() {
|
|
542
|
-
return this.client.getSessionInfo(this.id);
|
|
543
|
-
}
|
|
544
|
-
async end() {
|
|
545
|
-
await this.client.endSession(this.id);
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
function serializeAgentSpec(spec, extra = {}) {
|
|
549
|
-
if (!spec.agentId && (typeof spec.systemPrompt !== "string" || spec.systemPrompt.length === 0)) {
|
|
550
|
-
throw new MantyxError("Either `agentId` or `systemPrompt` is required");
|
|
551
|
-
}
|
|
552
|
-
const body = {
|
|
553
|
-
tools: serializeToolRefs(spec.tools ?? [])
|
|
554
|
-
};
|
|
555
|
-
if (typeof spec.systemPrompt === "string") body.systemPrompt = spec.systemPrompt;
|
|
556
|
-
if (spec.agentId) body.agentId = spec.agentId;
|
|
557
|
-
if (spec.name) body.name = spec.name;
|
|
558
|
-
if (spec.modelId) body.modelId = spec.modelId;
|
|
559
|
-
if (spec.budgets) body.budgets = spec.budgets;
|
|
560
|
-
if (spec.metadata && Object.keys(spec.metadata).length > 0) body.metadata = spec.metadata;
|
|
561
|
-
if (extra.prompt !== void 0) body.prompt = extra.prompt;
|
|
562
|
-
if (extra.messages !== void 0) body.messages = extra.messages;
|
|
563
|
-
return body;
|
|
564
|
-
}
|
|
565
|
-
function serializeToolRefs(tools) {
|
|
566
|
-
return tools.map((t) => {
|
|
567
|
-
if (t.kind === "mantyx") return { kind: "mantyx", id: t.id };
|
|
568
|
-
if (t.kind === "mantyx_plugin") return { kind: "mantyx_plugin", name: t.name };
|
|
569
|
-
return {
|
|
570
|
-
kind: "local",
|
|
571
|
-
name: t.name,
|
|
572
|
-
description: t.description,
|
|
573
|
-
parameters: toToolParametersWire(t.parameters)
|
|
574
|
-
};
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
function collectLocalHandlers(tools) {
|
|
578
|
-
const map = /* @__PURE__ */ new Map();
|
|
579
|
-
for (const t of tools) {
|
|
580
|
-
if (isLocalTool(t)) map.set(t.name, t);
|
|
581
|
-
}
|
|
582
|
-
return map;
|
|
583
|
-
}
|
|
584
|
-
function sleep(ms) {
|
|
585
|
-
return new Promise((r) => setTimeout(r, ms));
|
|
586
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
AgentSession,
|
|
3
|
+
DEFAULT_BASE_URL,
|
|
4
|
+
MantyxAuthError,
|
|
5
|
+
MantyxClient,
|
|
6
|
+
MantyxError,
|
|
7
|
+
MantyxNetworkError,
|
|
8
|
+
MantyxRunError,
|
|
9
|
+
MantyxToolError,
|
|
10
|
+
defineLocalA2A,
|
|
11
|
+
defineLocalMcp,
|
|
12
|
+
defineLocalTool,
|
|
13
|
+
isLocalA2ATool,
|
|
14
|
+
isLocalMcpServer,
|
|
15
|
+
isLocalTool,
|
|
16
|
+
mantyxA2A,
|
|
17
|
+
mantyxMcp,
|
|
18
|
+
mantyxPluginTool,
|
|
19
|
+
mantyxTool,
|
|
20
|
+
readSseStream,
|
|
21
|
+
toToolParametersWire,
|
|
22
|
+
zodToJsonSchema
|
|
23
|
+
} from "./chunk-ZJINVTHD.js";
|
|
587
24
|
|
|
588
25
|
// src/version.ts
|
|
589
|
-
var SDK_VERSION = "0.
|
|
26
|
+
var SDK_VERSION = "0.3.0";
|
|
590
27
|
export {
|
|
591
28
|
AgentSession,
|
|
592
29
|
DEFAULT_BASE_URL,
|
|
@@ -597,8 +34,14 @@ export {
|
|
|
597
34
|
MantyxRunError,
|
|
598
35
|
MantyxToolError,
|
|
599
36
|
SDK_VERSION,
|
|
37
|
+
defineLocalA2A,
|
|
38
|
+
defineLocalMcp,
|
|
600
39
|
defineLocalTool,
|
|
40
|
+
isLocalA2ATool,
|
|
41
|
+
isLocalMcpServer,
|
|
601
42
|
isLocalTool,
|
|
43
|
+
mantyxA2A,
|
|
44
|
+
mantyxMcp,
|
|
602
45
|
mantyxPluginTool,
|
|
603
46
|
mantyxTool,
|
|
604
47
|
readSseStream,
|