bs-agent 0.0.9 → 0.0.12
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/README.md +496 -410
- package/dist/core/index.cjs +520 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +133 -0
- package/dist/core/index.d.ts +133 -0
- package/dist/core/index.js +489 -0
- package/dist/core/index.js.map +1 -0
- package/dist/react/index.cjs +1318 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +287 -0
- package/dist/react/index.d.ts +287 -0
- package/dist/react/index.js +1286 -0
- package/dist/react/index.js.map +1 -0
- package/dist/types-DryLPWU9.d.cts +160 -0
- package/dist/types-DryLPWU9.d.ts +160 -0
- package/package.json +26 -11
- package/dist/index.cjs +0 -915
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -196
- package/dist/index.d.ts +0 -196
- package/dist/index.js +0 -886
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/core/index.ts
|
|
21
|
+
var core_exports = {};
|
|
22
|
+
__export(core_exports, {
|
|
23
|
+
AgentSession: () => AgentSession,
|
|
24
|
+
BuildShipAgent: () => BuildShipAgent,
|
|
25
|
+
executeStream: () => executeStream,
|
|
26
|
+
toJSONSchema: () => import_zod2.toJSONSchema,
|
|
27
|
+
z: () => import_zod2.z
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(core_exports);
|
|
30
|
+
|
|
31
|
+
// src/core/stream.ts
|
|
32
|
+
function tryParseJSON(value) {
|
|
33
|
+
if (typeof value === "string") {
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(value);
|
|
36
|
+
} catch {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
var FatalStreamError = class extends Error {
|
|
43
|
+
constructor(message, statusCode) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.statusCode = statusCode;
|
|
46
|
+
this.name = "FatalStreamError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
async function executeStream(options) {
|
|
50
|
+
const {
|
|
51
|
+
url,
|
|
52
|
+
body,
|
|
53
|
+
headers,
|
|
54
|
+
callbacks,
|
|
55
|
+
clientTools,
|
|
56
|
+
signal,
|
|
57
|
+
onSessionId,
|
|
58
|
+
onPaused,
|
|
59
|
+
onAutoResume,
|
|
60
|
+
onResponse
|
|
61
|
+
} = options;
|
|
62
|
+
let fullText = "";
|
|
63
|
+
const pendingAutoResumes = [];
|
|
64
|
+
const response = await fetch(url, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: {
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
Accept: "text/event-stream",
|
|
69
|
+
...headers
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(body),
|
|
72
|
+
signal
|
|
73
|
+
});
|
|
74
|
+
const sessionId = response.headers.get("X-BuildShip-Agent-Session-ID");
|
|
75
|
+
if (sessionId && onSessionId) {
|
|
76
|
+
const sessionName = response.headers.get("X-BuildShip-Agent-Session-Name") || void 0;
|
|
77
|
+
onSessionId(sessionId, sessionName);
|
|
78
|
+
}
|
|
79
|
+
onResponse?.(response);
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
let errorBody = "";
|
|
82
|
+
try {
|
|
83
|
+
errorBody = await response.text();
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
const error = new FatalStreamError(
|
|
87
|
+
`HTTP ${response.status}: ${errorBody || response.statusText}`,
|
|
88
|
+
response.status
|
|
89
|
+
);
|
|
90
|
+
callbacks.onError?.(error);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
if (!response.body) {
|
|
94
|
+
callbacks.onComplete?.(fullText);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const reader = response.body.getReader();
|
|
98
|
+
const decoder = new TextDecoder();
|
|
99
|
+
let buffer = "";
|
|
100
|
+
try {
|
|
101
|
+
while (true) {
|
|
102
|
+
const { done, value } = await reader.read();
|
|
103
|
+
if (done) break;
|
|
104
|
+
buffer += decoder.decode(value, { stream: true });
|
|
105
|
+
const parts = buffer.split("\n\n");
|
|
106
|
+
buffer = parts.pop() || "";
|
|
107
|
+
for (const part of parts) {
|
|
108
|
+
const trimmedPart = part.trim();
|
|
109
|
+
if (!trimmedPart) continue;
|
|
110
|
+
let jsonStr = "";
|
|
111
|
+
for (const line of trimmedPart.split("\n")) {
|
|
112
|
+
if (line.startsWith("data: ")) {
|
|
113
|
+
jsonStr += line.slice(6);
|
|
114
|
+
} else if (line.startsWith("data:")) {
|
|
115
|
+
jsonStr += line.slice(5);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
jsonStr = jsonStr.trim();
|
|
119
|
+
if (!jsonStr) continue;
|
|
120
|
+
let raw;
|
|
121
|
+
try {
|
|
122
|
+
raw = JSON.parse(jsonStr);
|
|
123
|
+
} catch {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const streamEvent = normalizeEvent(raw);
|
|
127
|
+
handleEvent(
|
|
128
|
+
streamEvent,
|
|
129
|
+
fullText,
|
|
130
|
+
callbacks,
|
|
131
|
+
clientTools,
|
|
132
|
+
onPaused,
|
|
133
|
+
onAutoResume,
|
|
134
|
+
pendingAutoResumes
|
|
135
|
+
);
|
|
136
|
+
if (streamEvent.type === "text_delta") {
|
|
137
|
+
fullText += streamEvent.data;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (buffer.trim()) {
|
|
142
|
+
let jsonStr = "";
|
|
143
|
+
for (const line of buffer.trim().split("\n")) {
|
|
144
|
+
if (line.startsWith("data: ")) {
|
|
145
|
+
jsonStr += line.slice(6);
|
|
146
|
+
} else if (line.startsWith("data:")) {
|
|
147
|
+
jsonStr += line.slice(5);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
jsonStr = jsonStr.trim();
|
|
151
|
+
if (jsonStr) {
|
|
152
|
+
try {
|
|
153
|
+
const raw = JSON.parse(jsonStr);
|
|
154
|
+
const streamEvent = normalizeEvent(raw);
|
|
155
|
+
handleEvent(
|
|
156
|
+
streamEvent,
|
|
157
|
+
fullText,
|
|
158
|
+
callbacks,
|
|
159
|
+
clientTools,
|
|
160
|
+
onPaused,
|
|
161
|
+
onAutoResume,
|
|
162
|
+
pendingAutoResumes
|
|
163
|
+
);
|
|
164
|
+
if (streamEvent.type === "text_delta") {
|
|
165
|
+
fullText += streamEvent.data;
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} catch (err) {
|
|
172
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
173
|
+
throw err;
|
|
174
|
+
}
|
|
175
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
176
|
+
callbacks.onError?.(error);
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
if (pendingAutoResumes.length > 0) {
|
|
180
|
+
await Promise.allSettled(pendingAutoResumes);
|
|
181
|
+
}
|
|
182
|
+
callbacks.onComplete?.(fullText);
|
|
183
|
+
}
|
|
184
|
+
function normalizeEvent(raw) {
|
|
185
|
+
const typeMap = {
|
|
186
|
+
llm_text_delta: "text_delta",
|
|
187
|
+
llm_reasoning_delta: "reasoning_delta"
|
|
188
|
+
};
|
|
189
|
+
if (raw && typeof raw.type === "string" && typeMap[raw.type]) {
|
|
190
|
+
raw.type = typeMap[raw.type];
|
|
191
|
+
}
|
|
192
|
+
return raw;
|
|
193
|
+
}
|
|
194
|
+
function handleEvent(event, _fullText, callbacks, clientTools, onPaused, onAutoResume, pendingAutoResumes) {
|
|
195
|
+
callbacks.onEvent?.(event);
|
|
196
|
+
switch (event.type) {
|
|
197
|
+
case "text_delta": {
|
|
198
|
+
callbacks.onText?.(event.data);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
case "reasoning_delta": {
|
|
202
|
+
callbacks.onReasoning?.(event.data.delta, event.data.index);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case "agent_handoff": {
|
|
206
|
+
callbacks.onAgentHandoff?.(event.data.agentName);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
case "tool_call_start": {
|
|
210
|
+
const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;
|
|
211
|
+
const inputs = tryParseJSON(rawInputs);
|
|
212
|
+
callbacks.onToolStart?.(toolName, toolType);
|
|
213
|
+
if (toolType === "client") {
|
|
214
|
+
const tool = clientTools.get(toolName);
|
|
215
|
+
if (tool) {
|
|
216
|
+
if (paused && tool.handler) {
|
|
217
|
+
const handlerPromise = (async () => {
|
|
218
|
+
try {
|
|
219
|
+
const result = await tool.handler(inputs);
|
|
220
|
+
await onAutoResume?.(callId, result);
|
|
221
|
+
} catch {
|
|
222
|
+
callbacks.onPaused?.(toolName, inputs);
|
|
223
|
+
onPaused?.({ callId, toolName, args: inputs });
|
|
224
|
+
}
|
|
225
|
+
})();
|
|
226
|
+
pendingAutoResumes.push(handlerPromise);
|
|
227
|
+
} else if (paused) {
|
|
228
|
+
callbacks.onPaused?.(toolName, inputs);
|
|
229
|
+
onPaused?.({ callId, toolName, args: inputs });
|
|
230
|
+
} else if (tool.handler) {
|
|
231
|
+
try {
|
|
232
|
+
tool.handler(inputs);
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} else if (paused) {
|
|
237
|
+
callbacks.onPaused?.(toolName, inputs);
|
|
238
|
+
onPaused?.({ callId, toolName, args: inputs });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
case "tool_call_end": {
|
|
244
|
+
const { toolName, result, error } = event.data;
|
|
245
|
+
callbacks.onToolEnd?.(toolName, result, error);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case "run_error": {
|
|
249
|
+
const { message, code } = event.data;
|
|
250
|
+
const error = new Error(message);
|
|
251
|
+
if (code != null) error.code = code;
|
|
252
|
+
callbacks.onError?.(error);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/core/session.ts
|
|
259
|
+
var import_zod = require("zod");
|
|
260
|
+
var AgentSession = class {
|
|
261
|
+
/** @internal */
|
|
262
|
+
_agent;
|
|
263
|
+
/** @internal */
|
|
264
|
+
_sessionId;
|
|
265
|
+
/** @internal */
|
|
266
|
+
_paused = false;
|
|
267
|
+
/** @internal */
|
|
268
|
+
_pausedToolInfo = null;
|
|
269
|
+
/** @internal */
|
|
270
|
+
_abortController = null;
|
|
271
|
+
/** @internal */
|
|
272
|
+
constructor(agent, sessionId) {
|
|
273
|
+
this._agent = agent;
|
|
274
|
+
this._sessionId = sessionId;
|
|
275
|
+
}
|
|
276
|
+
// ─── Public API ────────────────────────────────────────────────────
|
|
277
|
+
/**
|
|
278
|
+
* Send a message in this session.
|
|
279
|
+
*
|
|
280
|
+
* @param message - The message to send
|
|
281
|
+
* @param callbacks - Event handlers for the stream
|
|
282
|
+
* @param context - Optional additional context data
|
|
283
|
+
* @returns This session (for chaining)
|
|
284
|
+
*/
|
|
285
|
+
async execute(message, callbacks, context) {
|
|
286
|
+
this._paused = false;
|
|
287
|
+
this._pausedToolInfo = null;
|
|
288
|
+
const body = {
|
|
289
|
+
input: message,
|
|
290
|
+
stream: true
|
|
291
|
+
};
|
|
292
|
+
if (context) {
|
|
293
|
+
Object.assign(body, context);
|
|
294
|
+
}
|
|
295
|
+
const clientToolDefs = this._getClientToolDefs();
|
|
296
|
+
if (clientToolDefs.length > 0) {
|
|
297
|
+
body.clientTools = clientToolDefs;
|
|
298
|
+
}
|
|
299
|
+
await this._run(body, callbacks);
|
|
300
|
+
return this;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Resume a paused session with a tool result.
|
|
304
|
+
*
|
|
305
|
+
* @param result - The result to send back to the agent
|
|
306
|
+
* @param callbacks - Event handlers for the resumed stream
|
|
307
|
+
* @returns This session (for chaining)
|
|
308
|
+
*/
|
|
309
|
+
async resume(result, callbacks) {
|
|
310
|
+
if (!this._paused || !this._pausedToolInfo) {
|
|
311
|
+
throw new Error(
|
|
312
|
+
"AgentSession.resume(): session is not paused. Check isPaused() first."
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
const body = {
|
|
316
|
+
stream: true,
|
|
317
|
+
toolCallResult: {
|
|
318
|
+
callId: this._pausedToolInfo.callId,
|
|
319
|
+
result
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const clientToolDefs = this._getClientToolDefs();
|
|
323
|
+
if (clientToolDefs.length > 0) {
|
|
324
|
+
body.clientTools = clientToolDefs;
|
|
325
|
+
}
|
|
326
|
+
this._paused = false;
|
|
327
|
+
this._pausedToolInfo = null;
|
|
328
|
+
await this._run(body, callbacks);
|
|
329
|
+
return this;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if this session is waiting for a tool result.
|
|
333
|
+
*/
|
|
334
|
+
isPaused() {
|
|
335
|
+
return this._paused;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Get information about the paused tool call.
|
|
339
|
+
* Returns `null` if the session is not paused.
|
|
340
|
+
*/
|
|
341
|
+
getPausedTool() {
|
|
342
|
+
return this._pausedToolInfo;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get the session ID.
|
|
346
|
+
* May be `undefined` if the session hasn't executed yet.
|
|
347
|
+
*/
|
|
348
|
+
getSessionId() {
|
|
349
|
+
if (!this._sessionId) {
|
|
350
|
+
throw new Error(
|
|
351
|
+
"AgentSession.getSessionId(): session ID not yet available. Call execute() first."
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
return this._sessionId;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Cancel the current streaming operation.
|
|
358
|
+
*/
|
|
359
|
+
abort() {
|
|
360
|
+
this._abortController?.abort();
|
|
361
|
+
this._abortController = null;
|
|
362
|
+
}
|
|
363
|
+
// ─── Private helpers ───────────────────────────────────────────────
|
|
364
|
+
/** @internal */
|
|
365
|
+
async _run(body, callbacks) {
|
|
366
|
+
this._abortController = new AbortController();
|
|
367
|
+
await executeStream({
|
|
368
|
+
url: this._agent._url,
|
|
369
|
+
body,
|
|
370
|
+
headers: this._agent._buildHeaders(this._sessionId),
|
|
371
|
+
callbacks,
|
|
372
|
+
clientTools: this._agent._clientTools,
|
|
373
|
+
signal: this._abortController.signal,
|
|
374
|
+
onSessionId: (id) => {
|
|
375
|
+
this._sessionId = id;
|
|
376
|
+
},
|
|
377
|
+
onPaused: (info) => {
|
|
378
|
+
this._paused = true;
|
|
379
|
+
this._pausedToolInfo = info;
|
|
380
|
+
},
|
|
381
|
+
onAutoResume: async (callId, result) => {
|
|
382
|
+
const resumeBody = {
|
|
383
|
+
stream: true,
|
|
384
|
+
toolCallResult: { callId, result }
|
|
385
|
+
};
|
|
386
|
+
const clientToolDefs = this._getClientToolDefs();
|
|
387
|
+
if (clientToolDefs.length > 0) {
|
|
388
|
+
resumeBody.clientTools = clientToolDefs;
|
|
389
|
+
}
|
|
390
|
+
await this._run(resumeBody, callbacks);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
/** @internal */
|
|
395
|
+
_getClientToolDefs() {
|
|
396
|
+
const defs = [];
|
|
397
|
+
for (const tool of this._agent._clientTools.values()) {
|
|
398
|
+
defs.push({
|
|
399
|
+
name: tool.name,
|
|
400
|
+
description: tool.description,
|
|
401
|
+
parameters: resolveParameters(tool.parameters),
|
|
402
|
+
await: tool.await
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
return defs;
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
function resolveParameters(params) {
|
|
409
|
+
let schema;
|
|
410
|
+
if (params && typeof params === "object" && "_def" in params) {
|
|
411
|
+
schema = (0, import_zod.toJSONSchema)(params);
|
|
412
|
+
delete schema.$schema;
|
|
413
|
+
} else {
|
|
414
|
+
schema = { ...params };
|
|
415
|
+
}
|
|
416
|
+
if (schema.type === "object") {
|
|
417
|
+
schema.additionalProperties = false;
|
|
418
|
+
if (schema.properties) {
|
|
419
|
+
schema.required = Object.keys(schema.properties);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return schema;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/core/agent.ts
|
|
426
|
+
var DEFAULT_BASE_URL = "https://api.buildship.run";
|
|
427
|
+
var BuildShipAgent = class {
|
|
428
|
+
/** @internal */
|
|
429
|
+
_agentId;
|
|
430
|
+
/** @internal */
|
|
431
|
+
_accessKey;
|
|
432
|
+
/** @internal */
|
|
433
|
+
_baseUrl;
|
|
434
|
+
/** @internal */
|
|
435
|
+
_clientTools = /* @__PURE__ */ new Map();
|
|
436
|
+
constructor(config) {
|
|
437
|
+
if (!config.agentId) {
|
|
438
|
+
throw new Error("BuildShipAgent: agentId is required");
|
|
439
|
+
}
|
|
440
|
+
this._agentId = config.agentId;
|
|
441
|
+
this._accessKey = config.accessKey;
|
|
442
|
+
this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* The URL for the agent's execute endpoint.
|
|
446
|
+
* @internal
|
|
447
|
+
*/
|
|
448
|
+
get _url() {
|
|
449
|
+
return `${this._baseUrl}/executeAgent/${this._agentId}`;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Build the authorization / common headers.
|
|
453
|
+
* @internal
|
|
454
|
+
*/
|
|
455
|
+
_buildHeaders(sessionId) {
|
|
456
|
+
const headers = {};
|
|
457
|
+
if (this._accessKey) {
|
|
458
|
+
headers["Authorization"] = `Bearer ${this._accessKey}`;
|
|
459
|
+
}
|
|
460
|
+
if (sessionId) {
|
|
461
|
+
headers["X-BuildShip-Agent-Session-ID"] = sessionId;
|
|
462
|
+
}
|
|
463
|
+
return headers;
|
|
464
|
+
}
|
|
465
|
+
// ─── Public API ────────────────────────────────────────────────────
|
|
466
|
+
/**
|
|
467
|
+
* Start a new conversation.
|
|
468
|
+
*
|
|
469
|
+
* Creates a fresh session and sends the first message.
|
|
470
|
+
*
|
|
471
|
+
* @param message - The message to send
|
|
472
|
+
* @param callbacks - Event handlers for the stream
|
|
473
|
+
* @param context - Optional additional context data
|
|
474
|
+
* @returns The new session
|
|
475
|
+
*/
|
|
476
|
+
async execute(message, callbacks, context) {
|
|
477
|
+
const session = new AgentSession(this);
|
|
478
|
+
await session.execute(message, callbacks, context);
|
|
479
|
+
return session;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Get an existing session by ID to continue a conversation.
|
|
483
|
+
*
|
|
484
|
+
* @param sessionId - The session ID from a previous conversation
|
|
485
|
+
* @returns The session object
|
|
486
|
+
*/
|
|
487
|
+
session(sessionId) {
|
|
488
|
+
if (!sessionId) {
|
|
489
|
+
throw new Error("BuildShipAgent.session(): sessionId is required");
|
|
490
|
+
}
|
|
491
|
+
return new AgentSession(this, sessionId);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Register a client-side tool that the agent can call.
|
|
495
|
+
*/
|
|
496
|
+
registerClientTool(tool) {
|
|
497
|
+
if (!tool.name) {
|
|
498
|
+
throw new Error("registerClientTool: tool.name is required");
|
|
499
|
+
}
|
|
500
|
+
this._clientTools.set(tool.name, tool);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Remove a registered client tool.
|
|
504
|
+
*/
|
|
505
|
+
unregisterClientTool(name) {
|
|
506
|
+
this._clientTools.delete(name);
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
// src/core/index.ts
|
|
511
|
+
var import_zod2 = require("zod");
|
|
512
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
513
|
+
0 && (module.exports = {
|
|
514
|
+
AgentSession,
|
|
515
|
+
BuildShipAgent,
|
|
516
|
+
executeStream,
|
|
517
|
+
toJSONSchema,
|
|
518
|
+
z
|
|
519
|
+
});
|
|
520
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/index.ts","../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts"],"sourcesContent":["// ─── Classes ─────────────────────────────────────────────────────────────────\nexport { BuildShipAgent } from \"./agent\";\nexport { AgentSession } from \"./session\";\n\n// ─── Stream executor ─────────────────────────────────────────────────────────\nexport { executeStream } from \"./stream\";\n\n// ─── Zod (re-exported for convenience) ───────────────────────────────────────\nexport { z, toJSONSchema } from \"zod\";\nexport type { ZodSchema } from \"zod\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\nexport type {\n AgentConfig,\n SessionId,\n ToolType,\n StreamCallbacks,\n StreamOptions,\n ExecuteRequestBody,\n ClientTool,\n PausedToolInfo,\n // Stream event types (for advanced consumers)\n StreamEvent,\n StreamEventMeta,\n TextDeltaEvent,\n ReasoningDeltaEvent,\n AgentHandoffEvent,\n ToolCallStartEvent,\n ToolCallEndEvent,\n RunErrorEvent,\n} from \"./types\";\n","import type { StreamEvent, StreamOptions, SessionId } from \"./types\";\n\n/** Safely parse a value as JSON if it's a string, otherwise return as-is. */\nfunction tryParseJSON(value: unknown): any {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n return value;\n}\n\n/**\n * Fatal error — will NOT be retried.\n */\nclass FatalStreamError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = \"FatalStreamError\";\n }\n}\n\n/**\n * Opens an SSE connection to the BuildShip agent endpoint using native\n * `fetch` + `ReadableStream`, parses events, and dispatches to the\n * appropriate callbacks.\n *\n * Zero runtime dependencies — works in both browser and Node.js.\n *\n * @internal\n */\nexport async function executeStream(options: StreamOptions): Promise<void> {\n const {\n url,\n body,\n headers,\n callbacks,\n clientTools,\n signal,\n onSessionId,\n onPaused,\n onAutoResume,\n onResponse,\n } = options;\n\n let fullText = \"\";\n\n // Track pending auto-resume operations so we don't call onComplete prematurely\n const pendingAutoResumes: Promise<void>[] = [];\n\n // ── Make the request ────────────────────────────────────────────────\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n ...headers,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n // ── Extract session ID and name from response headers ──────────────\n const sessionId = response.headers.get(\"X-BuildShip-Agent-Session-ID\");\n if (sessionId && onSessionId) {\n const sessionName = response.headers.get(\"X-BuildShip-Agent-Session-Name\") || undefined;\n onSessionId(sessionId as SessionId, sessionName);\n }\n\n // Expose the raw Response object\n onResponse?.(response);\n\n // ── Handle HTTP errors ─────────────────────────────────────────────\n if (!response.ok) {\n let errorBody = \"\";\n try {\n errorBody = await response.text();\n } catch {\n // ignore\n }\n const error = new FatalStreamError(\n `HTTP ${response.status}: ${errorBody || response.statusText}`,\n response.status,\n );\n callbacks.onError?.(error);\n throw error;\n }\n\n // ── Read the SSE stream ────────────────────────────────────────────\n if (!response.body) {\n callbacks.onComplete?.(fullText);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // SSE events are separated by double newlines\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue;\n\n // Extract the data field from SSE format\n let jsonStr = \"\";\n for (const line of trimmedPart.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (!jsonStr) continue;\n\n let raw: any;\n try {\n raw = JSON.parse(jsonStr);\n } catch {\n // Skip malformed events\n continue;\n }\n\n // Normalize backend event type names (llm_text_delta → text_delta, etc.)\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n\n // Accumulate text\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim()) {\n let jsonStr = \"\";\n for (const line of buffer.trim().split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (jsonStr) {\n try {\n const raw = JSON.parse(jsonStr);\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n } catch {\n // Skip malformed trailing data\n }\n }\n }\n } catch (err) {\n // AbortError — re-throw\n if (err instanceof Error && err.name === \"AbortError\") {\n throw err;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError?.(error);\n throw error;\n }\n\n // Wait for any pending auto-resume handlers before signaling completion\n if (pendingAutoResumes.length > 0) {\n await Promise.allSettled(pendingAutoResumes);\n }\n\n callbacks.onComplete?.(fullText);\n}\n\n/**\n * Normalize backend event type names.\n * The backend sends `llm_text_delta` / `llm_reasoning_delta` but the SDK\n * exposes them as `text_delta` / `reasoning_delta`.\n * @internal\n */\nfunction normalizeEvent(raw: any): any {\n const typeMap: Record<string, string> = {\n llm_text_delta: \"text_delta\",\n llm_reasoning_delta: \"reasoning_delta\",\n };\n if (raw && typeof raw.type === \"string\" && typeMap[raw.type]) {\n raw.type = typeMap[raw.type];\n }\n return raw;\n}\n\n/**\n * Dispatch a parsed stream event to the appropriate callbacks.\n * @internal\n */\nfunction handleEvent(\n event: StreamEvent,\n _fullText: string,\n callbacks: StreamOptions[\"callbacks\"],\n clientTools: StreamOptions[\"clientTools\"],\n onPaused: StreamOptions[\"onPaused\"],\n onAutoResume: StreamOptions[\"onAutoResume\"],\n pendingAutoResumes: Promise<void>[],\n): void {\n // Notify raw event consumers\n callbacks.onEvent?.(event);\n\n switch (event.type) {\n case \"text_delta\": {\n callbacks.onText?.(event.data);\n break;\n }\n\n case \"reasoning_delta\": {\n callbacks.onReasoning?.(event.data.delta, event.data.index);\n break;\n }\n\n case \"agent_handoff\": {\n callbacks.onAgentHandoff?.(event.data.agentName);\n break;\n }\n\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;\n // Backend sends toolCall.arguments as a JSON string — parse it\n const inputs = tryParseJSON(rawInputs);\n\n // Notify callback\n callbacks.onToolStart?.(toolName, toolType);\n\n // Handle client tools\n if (toolType === \"client\") {\n const tool = clientTools.get(toolName);\n if (tool) {\n if (paused && tool.handler) {\n // Blocking tool with handler → auto-execute and resume\n const handlerPromise = (async () => {\n try {\n const result = await tool.handler!(inputs);\n await onAutoResume?.(callId, result);\n } catch {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n })();\n pendingAutoResumes.push(handlerPromise);\n } else if (paused) {\n // Blocking tool without handler → pause for user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n } else if (tool.handler) {\n // Fire-and-forget tool with handler\n try {\n tool.handler(inputs);\n } catch {\n // Swallow errors on fire-and-forget\n }\n }\n } else if (paused) {\n // No registered tool but paused — notify user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n }\n break;\n }\n\n case \"tool_call_end\": {\n const { toolName, result, error } = event.data;\n callbacks.onToolEnd?.(toolName, result, error);\n break;\n }\n\n case \"run_error\": {\n const { message, code } = event.data;\n const error = new Error(message);\n if (code != null) (error as any).code = code;\n callbacks.onError?.(error);\n break;\n }\n }\n}\n","import type {\n SessionId,\n StreamCallbacks,\n PausedToolInfo,\n ExecuteRequestBody,\n} from \"./types\";\nimport type { BuildShipAgent } from \"./agent\";\nimport { executeStream } from \"./stream\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\n/**\n * Represents a conversation session with a BuildShip agent.\n *\n * Sessions maintain history across multiple turns and support\n * pause/resume for blocking client tools.\n */\nexport class AgentSession {\n /** @internal */ private _agent: BuildShipAgent;\n /** @internal */ private _sessionId: SessionId | undefined;\n /** @internal */ private _paused = false;\n /** @internal */ private _pausedToolInfo: PausedToolInfo | null = null;\n /** @internal */ private _abortController: AbortController | null = null;\n\n /** @internal */\n constructor(agent: BuildShipAgent, sessionId?: SessionId) {\n this._agent = agent;\n this._sessionId = sessionId;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Send a message in this session.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param context - Optional additional context data\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n context?: Record<string, any>,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (context) {\n Object.assign(body, context);\n }\n\n // Include client tool definitions\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n await this._run(body, callbacks);\n return this;\n }\n\n /**\n * Resume a paused session with a tool result.\n *\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @returns This session (for chaining)\n */\n async resume(result: any, callbacks: StreamCallbacks): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\n \"AgentSession.resume(): session is not paused. Check isPaused() first.\",\n );\n }\n\n const body: ExecuteRequestBody = {\n stream: true,\n toolCallResult: {\n callId: this._pausedToolInfo.callId,\n result,\n },\n };\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks);\n return this;\n }\n\n /**\n * Check if this session is waiting for a tool result.\n */\n isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get information about the paused tool call.\n * Returns `null` if the session is not paused.\n */\n getPausedTool(): PausedToolInfo | null {\n return this._pausedToolInfo;\n }\n\n /**\n * Get the session ID.\n * May be `undefined` if the session hasn't executed yet.\n */\n getSessionId(): SessionId {\n if (!this._sessionId) {\n throw new Error(\n \"AgentSession.getSessionId(): session ID not yet available. Call execute() first.\",\n );\n }\n return this._sessionId;\n }\n\n /**\n * Cancel the current streaming operation.\n */\n abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n // ─── Private helpers ───────────────────────────────────────────────\n\n /** @internal */\n private async _run(\n body: ExecuteRequestBody,\n callbacks: StreamCallbacks,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: this._agent._buildHeaders(this._sessionId),\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id) => {\n this._sessionId = id;\n },\n\n onPaused: (info) => {\n this._paused = true;\n this._pausedToolInfo = info;\n },\n\n onAutoResume: async (callId, result) => {\n // Auto-resume: send the tool result back immediately\n const resumeBody: ExecuteRequestBody = {\n stream: true,\n toolCallResult: { callId, result },\n };\n\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n resumeBody.clientTools = clientToolDefs;\n }\n\n await this._run(resumeBody, callbacks);\n },\n });\n }\n\n /** @internal */\n private _getClientToolDefs() {\n const defs: ExecuteRequestBody[\"clientTools\"] = [];\n for (const tool of this._agent._clientTools.values()) {\n defs.push({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n });\n }\n return defs;\n }\n}\n\n/**\n * Convert tool parameters to a JSON Schema object.\n * - If it's a Zod schema, uses Zod's built-in `toJSONSchema` to convert.\n * - Always ensures `additionalProperties: false` is set (required by the backend).\n * - Always ensures `required` includes every key in `properties` (Gemini requirement).\n * @internal\n */\nfunction resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n // Remove $schema key if present\n delete schema.$schema;\n } else {\n schema = { ...params };\n }\n\n if (schema.type === \"object\") {\n // Backend requires additionalProperties: false\n schema.additionalProperties = false;\n\n // Gemini requires `required` to include every key in `properties`\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n","import type {\n AgentConfig,\n ClientTool,\n SessionId,\n StreamCallbacks,\n} from \"./types\";\nimport { AgentSession } from \"./session\";\n\nconst DEFAULT_BASE_URL = \"https://api.buildship.run\";\n\n/**\n * Main entry point for interacting with a BuildShip agent.\n *\n * @example\n * ```ts\n * import { BuildShipAgent } from \"buildship-agent-sdk/core\";\n *\n * const agent = new BuildShipAgent({\n * agentId: \"your-agent-id\",\n * accessKey: \"your-access-key\",\n * });\n *\n * const session = await agent.execute(\"Hello!\", {\n * onText: (text) => console.log(text),\n * onComplete: (fullText) => console.log(\"Done!\", fullText),\n * });\n * ```\n */\nexport class BuildShipAgent {\n /** @internal */ readonly _agentId: string;\n /** @internal */ readonly _accessKey?: string;\n /** @internal */ readonly _baseUrl: string;\n /** @internal */ readonly _clientTools = new Map<string, ClientTool>();\n\n constructor(config: AgentConfig) {\n if (!config.agentId) {\n throw new Error(\"BuildShipAgent: agentId is required\");\n }\n this._agentId = config.agentId;\n this._accessKey = config.accessKey;\n this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n /**\n * The URL for the agent's execute endpoint.\n * @internal\n */\n get _url(): string {\n return `${this._baseUrl}/executeAgent/${this._agentId}`;\n }\n\n /**\n * Build the authorization / common headers.\n * @internal\n */\n _buildHeaders(sessionId?: SessionId): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this._accessKey) {\n headers[\"Authorization\"] = `Bearer ${this._accessKey}`;\n }\n if (sessionId) {\n headers[\"X-BuildShip-Agent-Session-ID\"] = sessionId;\n }\n return headers;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Start a new conversation.\n *\n * Creates a fresh session and sends the first message.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param context - Optional additional context data\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n context?: Record<string, any>,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, context);\n return session;\n }\n\n /**\n * Get an existing session by ID to continue a conversation.\n *\n * @param sessionId - The session ID from a previous conversation\n * @returns The session object\n */\n session(sessionId: SessionId | string): AgentSession {\n if (!sessionId) {\n throw new Error(\"BuildShipAgent.session(): sessionId is required\");\n }\n return new AgentSession(this, sessionId as SessionId);\n }\n\n /**\n * Register a client-side tool that the agent can call.\n */\n registerClientTool(tool: ClientTool): void {\n if (!tool.name) {\n throw new Error(\"registerClientTool: tool.name is required\");\n }\n this._clientTools.set(tool.name, tool);\n }\n\n /**\n * Remove a registered client tool.\n */\n unregisterClientTool(name: string): void {\n this._clientTools.delete(name);\n }\n}\n"],"mappings":"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","names":["import_zod"]}
|