bs-agent 0.0.12 → 0.0.16
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-BuA0m5H-.d.cts +305 -0
- package/dist/agent-BuA0m5H-.d.ts +305 -0
- package/dist/core/index.cjs +71 -20
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -120
- package/dist/core/index.d.ts +3 -120
- package/dist/core/index.js +71 -20
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +695 -427
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +28 -28
- package/dist/react/index.d.ts +28 -28
- package/dist/react/index.js +695 -427
- package/dist/react/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/types-DryLPWU9.d.cts +0 -160
- package/dist/types-DryLPWU9.d.ts +0 -160
package/dist/core/index.js
CHANGED
|
@@ -147,7 +147,13 @@ async function executeStream(options) {
|
|
|
147
147
|
throw error;
|
|
148
148
|
}
|
|
149
149
|
if (pendingAutoResumes.length > 0) {
|
|
150
|
-
await Promise.allSettled(pendingAutoResumes);
|
|
150
|
+
const handlerResults = await Promise.allSettled(pendingAutoResumes);
|
|
151
|
+
for (const settled of handlerResults) {
|
|
152
|
+
if (settled.status === "fulfilled" && settled.value) {
|
|
153
|
+
const { callId, result } = settled.value;
|
|
154
|
+
await onAutoResume?.(callId, result);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
151
157
|
}
|
|
152
158
|
callbacks.onComplete?.(fullText);
|
|
153
159
|
}
|
|
@@ -187,10 +193,21 @@ function handleEvent(event, _fullText, callbacks, clientTools, onPaused, onAutoR
|
|
|
187
193
|
const handlerPromise = (async () => {
|
|
188
194
|
try {
|
|
189
195
|
const result = await tool.handler(inputs);
|
|
190
|
-
|
|
191
|
-
|
|
196
|
+
callbacks.onEvent?.({
|
|
197
|
+
type: "tool_call_end",
|
|
198
|
+
data: {
|
|
199
|
+
callId,
|
|
200
|
+
toolName,
|
|
201
|
+
toolType: "client",
|
|
202
|
+
result
|
|
203
|
+
},
|
|
204
|
+
meta: event.meta
|
|
205
|
+
});
|
|
206
|
+
return { callId, result };
|
|
207
|
+
} catch (error) {
|
|
192
208
|
callbacks.onPaused?.(toolName, inputs);
|
|
193
209
|
onPaused?.({ callId, toolName, args: inputs });
|
|
210
|
+
return null;
|
|
194
211
|
}
|
|
195
212
|
})();
|
|
196
213
|
pendingAutoResumes.push(handlerPromise);
|
|
@@ -249,24 +266,26 @@ var AgentSession = class {
|
|
|
249
266
|
*
|
|
250
267
|
* @param message - The message to send
|
|
251
268
|
* @param callbacks - Event handlers for the stream
|
|
252
|
-
* @param
|
|
269
|
+
* @param callbacks - Event handlers for the stream
|
|
270
|
+
* @param options - Optional settings like context, headers, or body
|
|
253
271
|
* @returns This session (for chaining)
|
|
254
272
|
*/
|
|
255
|
-
async execute(message, callbacks,
|
|
273
|
+
async execute(message, callbacks, options) {
|
|
256
274
|
this._paused = false;
|
|
257
275
|
this._pausedToolInfo = null;
|
|
258
276
|
const body = {
|
|
277
|
+
...options?.body || {},
|
|
259
278
|
input: message,
|
|
260
279
|
stream: true
|
|
261
280
|
};
|
|
262
|
-
if (context) {
|
|
263
|
-
Object.assign(body, context);
|
|
281
|
+
if (options?.context) {
|
|
282
|
+
Object.assign(body, { context: options.context });
|
|
264
283
|
}
|
|
265
284
|
const clientToolDefs = this._getClientToolDefs();
|
|
266
285
|
if (clientToolDefs.length > 0) {
|
|
267
286
|
body.clientTools = clientToolDefs;
|
|
268
287
|
}
|
|
269
|
-
await this._run(body, callbacks);
|
|
288
|
+
await this._run(body, callbacks, options);
|
|
270
289
|
return this;
|
|
271
290
|
}
|
|
272
291
|
/**
|
|
@@ -274,15 +293,15 @@ var AgentSession = class {
|
|
|
274
293
|
*
|
|
275
294
|
* @param result - The result to send back to the agent
|
|
276
295
|
* @param callbacks - Event handlers for the resumed stream
|
|
296
|
+
* @param options - Optional settings like headers or body
|
|
277
297
|
* @returns This session (for chaining)
|
|
278
298
|
*/
|
|
279
|
-
async resume(result, callbacks) {
|
|
299
|
+
async resume(result, callbacks, options) {
|
|
280
300
|
if (!this._paused || !this._pausedToolInfo) {
|
|
281
|
-
throw new Error(
|
|
282
|
-
"AgentSession.resume(): session is not paused. Check isPaused() first."
|
|
283
|
-
);
|
|
301
|
+
throw new Error("AgentSession.resume(): session is not paused. Check isPaused() first.");
|
|
284
302
|
}
|
|
285
303
|
const body = {
|
|
304
|
+
...options?.body || {},
|
|
286
305
|
stream: true,
|
|
287
306
|
toolCallResult: {
|
|
288
307
|
callId: this._pausedToolInfo.callId,
|
|
@@ -295,7 +314,35 @@ var AgentSession = class {
|
|
|
295
314
|
}
|
|
296
315
|
this._paused = false;
|
|
297
316
|
this._pausedToolInfo = null;
|
|
298
|
-
await this._run(body, callbacks);
|
|
317
|
+
await this._run(body, callbacks, options);
|
|
318
|
+
return this;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Resume a session with an explicit tool call ID and result.
|
|
322
|
+
*
|
|
323
|
+
* Unlike `resume()`, this does NOT require the session to be in a paused state,
|
|
324
|
+
* making it suitable for external resume flows (e.g. React widget submissions)
|
|
325
|
+
* where the session object may have been re-created.
|
|
326
|
+
*
|
|
327
|
+
* @param callId - The tool call ID to resume
|
|
328
|
+
* @param result - The result to send back to the agent
|
|
329
|
+
* @param callbacks - Event handlers for the resumed stream
|
|
330
|
+
* @param options - Optional settings like headers or body
|
|
331
|
+
* @returns This session (for chaining)
|
|
332
|
+
*/
|
|
333
|
+
async resumeWithCallId(callId, result, callbacks, options) {
|
|
334
|
+
const body = {
|
|
335
|
+
...options?.body || {},
|
|
336
|
+
stream: true,
|
|
337
|
+
toolCallResult: { callId, result }
|
|
338
|
+
};
|
|
339
|
+
const clientToolDefs = this._getClientToolDefs();
|
|
340
|
+
if (clientToolDefs.length > 0) {
|
|
341
|
+
body.clientTools = clientToolDefs;
|
|
342
|
+
}
|
|
343
|
+
this._paused = false;
|
|
344
|
+
this._pausedToolInfo = null;
|
|
345
|
+
await this._run(body, callbacks, options);
|
|
299
346
|
return this;
|
|
300
347
|
}
|
|
301
348
|
/**
|
|
@@ -332,17 +379,20 @@ var AgentSession = class {
|
|
|
332
379
|
}
|
|
333
380
|
// ─── Private helpers ───────────────────────────────────────────────
|
|
334
381
|
/** @internal */
|
|
335
|
-
async _run(body, callbacks) {
|
|
382
|
+
async _run(body, callbacks, options) {
|
|
336
383
|
this._abortController = new AbortController();
|
|
384
|
+
const baseHeaders = this._agent._buildHeaders(this._sessionId);
|
|
385
|
+
const mergedHeaders = { ...baseHeaders, ...options?.headers || {} };
|
|
337
386
|
await executeStream({
|
|
338
387
|
url: this._agent._url,
|
|
339
388
|
body,
|
|
340
|
-
headers:
|
|
389
|
+
headers: mergedHeaders,
|
|
341
390
|
callbacks,
|
|
342
391
|
clientTools: this._agent._clientTools,
|
|
343
392
|
signal: this._abortController.signal,
|
|
344
|
-
onSessionId: (id) => {
|
|
393
|
+
onSessionId: (id, name) => {
|
|
345
394
|
this._sessionId = id;
|
|
395
|
+
options?.onSessionId?.(id, name);
|
|
346
396
|
},
|
|
347
397
|
onPaused: (info) => {
|
|
348
398
|
this._paused = true;
|
|
@@ -350,6 +400,7 @@ var AgentSession = class {
|
|
|
350
400
|
},
|
|
351
401
|
onAutoResume: async (callId, result) => {
|
|
352
402
|
const resumeBody = {
|
|
403
|
+
...options?.body || {},
|
|
353
404
|
stream: true,
|
|
354
405
|
toolCallResult: { callId, result }
|
|
355
406
|
};
|
|
@@ -357,7 +408,7 @@ var AgentSession = class {
|
|
|
357
408
|
if (clientToolDefs.length > 0) {
|
|
358
409
|
resumeBody.clientTools = clientToolDefs;
|
|
359
410
|
}
|
|
360
|
-
await this._run(resumeBody, callbacks);
|
|
411
|
+
await this._run(resumeBody, callbacks, options);
|
|
361
412
|
}
|
|
362
413
|
});
|
|
363
414
|
}
|
|
@@ -440,12 +491,12 @@ var BuildShipAgent = class {
|
|
|
440
491
|
*
|
|
441
492
|
* @param message - The message to send
|
|
442
493
|
* @param callbacks - Event handlers for the stream
|
|
443
|
-
* @param
|
|
494
|
+
* @param options - Optional execution settings (context, headers, body, onSessionId)
|
|
444
495
|
* @returns The new session
|
|
445
496
|
*/
|
|
446
|
-
async execute(message, callbacks,
|
|
497
|
+
async execute(message, callbacks, options) {
|
|
447
498
|
const session = new AgentSession(this);
|
|
448
|
-
await session.execute(message, callbacks,
|
|
499
|
+
await session.execute(message, callbacks, options);
|
|
449
500
|
return session;
|
|
450
501
|
}
|
|
451
502
|
/**
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/core/index.ts"],"sourcesContent":["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","// ─── 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"],"mappings":";AAGA,SAAS,aAAa,OAAqB;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,aAAO,KAAK,MAAM,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACnC,YACE,SACO,YACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAWA,eAAsB,cAAc,SAAuC;AACzE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,WAAW;AAGf,QAAM,qBAAsC,CAAC;AAG7C,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,GAAG;AAAA,IACL;AAAA,IACA,MAAM,KAAK,UAAU,IAAI;AAAA,IACzB;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,SAAS,QAAQ,IAAI,8BAA8B;AACrE,MAAI,aAAa,aAAa;AAC5B,UAAM,cAAc,SAAS,QAAQ,IAAI,gCAAgC,KAAK;AAC9E,gBAAY,WAAwB,WAAW;AAAA,EACjD;AAGA,eAAa,QAAQ;AAGrB,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,YAAY;AAChB,QAAI;AACF,kBAAY,MAAM,SAAS,KAAK;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,UAAM,QAAQ,IAAI;AAAA,MAChB,QAAQ,SAAS,MAAM,KAAK,aAAa,SAAS,UAAU;AAAA,MAC5D,SAAS;AAAA,IACX;AACA,cAAU,UAAU,KAAK;AACzB,UAAM;AAAA,EACR;AAGA,MAAI,CAAC,SAAS,MAAM;AAClB,cAAU,aAAa,QAAQ;AAC/B;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,YAAM,QAAQ,OAAO,MAAM,MAAM;AACjC,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,cAAM,cAAc,KAAK,KAAK;AAC9B,YAAI,CAAC,YAAa;AAGlB,YAAI,UAAU;AACd,mBAAW,QAAQ,YAAY,MAAM,IAAI,GAAG;AAC1C,cAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,uBAAW,KAAK,MAAM,CAAC;AAAA,UACzB,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,uBAAW,KAAK,MAAM,CAAC;AAAA,UACzB;AAAA,QACF;AAEA,kBAAU,QAAQ,KAAK;AACvB,YAAI,CAAC,QAAS;AAEd,YAAI;AACJ,YAAI;AACF,gBAAM,KAAK,MAAM,OAAO;AAAA,QAC1B,QAAQ;AAEN;AAAA,QACF;AAGA,cAAM,cAAc,eAAe,GAAG;AAEtC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAGA,YAAI,YAAY,SAAS,cAAc;AACrC,sBAAY,YAAY;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,GAAG;AACjB,UAAI,UAAU;AACd,iBAAW,QAAQ,OAAO,KAAK,EAAE,MAAM,IAAI,GAAG;AAC5C,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,qBAAW,KAAK,MAAM,CAAC;AAAA,QACzB,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,qBAAW,KAAK,MAAM,CAAC;AAAA,QACzB;AAAA,MACF;AAEA,gBAAU,QAAQ,KAAK;AACvB,UAAI,SAAS;AACX,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,gBAAM,cAAc,eAAe,GAAG;AACtC;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,cAAI,YAAY,SAAS,cAAc;AACrC,wBAAY,YAAY;AAAA,UAC1B;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AAEZ,QAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,YAAM;AAAA,IACR;AAEA,UAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,cAAU,UAAU,KAAK;AACzB,UAAM;AAAA,EACR;AAGA,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,QAAQ,WAAW,kBAAkB;AAAA,EAC7C;AAEA,YAAU,aAAa,QAAQ;AACjC;AAQA,SAAS,eAAe,KAAe;AACrC,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,MAAI,OAAO,OAAO,IAAI,SAAS,YAAY,QAAQ,IAAI,IAAI,GAAG;AAC5D,QAAI,OAAO,QAAQ,IAAI,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;AAMA,SAAS,YACP,OACA,WACA,WACA,aACA,UACA,cACA,oBACM;AAEN,YAAU,UAAU,KAAK;AAEzB,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK,cAAc;AACjB,gBAAU,SAAS,MAAM,IAAI;AAC7B;AAAA,IACF;AAAA,IAEA,KAAK,mBAAmB;AACtB,gBAAU,cAAc,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;AAC1D;AAAA,IACF;AAAA,IAEA,KAAK,iBAAiB;AACpB,gBAAU,iBAAiB,MAAM,KAAK,SAAS;AAC/C;AAAA,IACF;AAAA,IAEA,KAAK,mBAAmB;AACtB,YAAM,EAAE,QAAQ,UAAU,UAAU,QAAQ,WAAW,OAAO,IAAI,MAAM;AAExE,YAAM,SAAS,aAAa,SAAS;AAGrC,gBAAU,cAAc,UAAU,QAAQ;AAG1C,UAAI,aAAa,UAAU;AACzB,cAAM,OAAO,YAAY,IAAI,QAAQ;AACrC,YAAI,MAAM;AACR,cAAI,UAAU,KAAK,SAAS;AAE1B,kBAAM,kBAAkB,YAAY;AAClC,kBAAI;AACF,sBAAM,SAAS,MAAM,KAAK,QAAS,MAAM;AACzC,sBAAM,eAAe,QAAQ,MAAM;AAAA,cACrC,QAAQ;AAEN,0BAAU,WAAW,UAAU,MAAM;AACrC,2BAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAAA,cAC/C;AAAA,YACF,GAAG;AACH,+BAAmB,KAAK,cAAc;AAAA,UACxC,WAAW,QAAQ;AAEjB,sBAAU,WAAW,UAAU,MAAM;AACrC,uBAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAAA,UAC/C,WAAW,KAAK,SAAS;AAEvB,gBAAI;AACF,mBAAK,QAAQ,MAAM;AAAA,YACrB,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF,WAAW,QAAQ;AAEjB,oBAAU,WAAW,UAAU,MAAM;AACrC,qBAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAAA,QAC/C;AAAA,MACF;AACA;AAAA,IACF;AAAA,IAEA,KAAK,iBAAiB;AACpB,YAAM,EAAE,UAAU,QAAQ,MAAM,IAAI,MAAM;AAC1C,gBAAU,YAAY,UAAU,QAAQ,KAAK;AAC7C;AAAA,IACF;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM;AAChC,YAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,UAAI,QAAQ,KAAM,CAAC,MAAc,OAAO;AACxC,gBAAU,UAAU,KAAK;AACzB;AAAA,IACF;AAAA,EACF;AACF;;;ACxTA,SAAS,oBAAoC;AAQtC,IAAM,eAAN,MAAmB;AAAA;AAAA,EACC;AAAA;AAAA,EACA;AAAA;AAAA,EACA,UAAU;AAAA;AAAA,EACV,kBAAyC;AAAA;AAAA,EACzC,mBAA2C;AAAA;AAAA,EAGpE,YAAY,OAAuB,WAAuB;AACxD,SAAK,SAAS;AACd,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QACJ,SACA,WACA,SACuB;AACvB,SAAK,UAAU;AACf,SAAK,kBAAkB;AAEvB,UAAM,OAA2B;AAAA,MAC/B,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAGA,QAAI,SAAS;AACX,aAAO,OAAO,MAAM,OAAO;AAAA,IAC7B;AAGA,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,cAAc;AAAA,IACrB;AAEA,UAAM,KAAK,KAAK,MAAM,SAAS;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,QAAa,WAAmD;AAC3E,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,iBAAiB;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAA2B;AAAA,MAC/B,QAAQ;AAAA,MACR,gBAAgB;AAAA,QACd,QAAQ,KAAK,gBAAgB;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,cAAc;AAAA,IACrB;AAEA,SAAK,UAAU;AACf,SAAK,kBAAkB;AAEvB,UAAM,KAAK,KAAK,MAAM,SAAS;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAuC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAA0B;AACxB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,kBAAkB,MAAM;AAC7B,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA;AAAA,EAKA,MAAc,KACZ,MACA,WACe;AAEf,SAAK,mBAAmB,IAAI,gBAAgB;AAE5C,UAAM,cAAc;AAAA,MAClB,KAAK,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,SAAS,KAAK,OAAO,cAAc,KAAK,UAAU;AAAA,MAClD;AAAA,MACA,aAAa,KAAK,OAAO;AAAA,MACzB,QAAQ,KAAK,iBAAiB;AAAA,MAE9B,aAAa,CAAC,OAAO;AACnB,aAAK,aAAa;AAAA,MACpB;AAAA,MAEA,UAAU,CAAC,SAAS;AAClB,aAAK,UAAU;AACf,aAAK,kBAAkB;AAAA,MACzB;AAAA,MAEA,cAAc,OAAO,QAAQ,WAAW;AAEtC,cAAM,aAAiC;AAAA,UACrC,QAAQ;AAAA,UACR,gBAAgB,EAAE,QAAQ,OAAO;AAAA,QACnC;AAEA,cAAM,iBAAiB,KAAK,mBAAmB;AAC/C,YAAI,eAAe,SAAS,GAAG;AAC7B,qBAAW,cAAc;AAAA,QAC3B;AAEA,cAAM,KAAK,KAAK,YAAY,SAAS;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,qBAAqB;AAC3B,UAAM,OAA0C,CAAC;AACjD,eAAW,QAAQ,KAAK,OAAO,aAAa,OAAO,GAAG;AACpD,WAAK,KAAK;AAAA,QACR,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,YAAY,kBAAkB,KAAK,UAAU;AAAA,QAC7C,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AASA,SAAS,kBAAkB,QAAkC;AAC3D,MAAI;AAGJ,MAAI,UAAU,OAAO,WAAW,YAAY,UAAU,QAAQ;AAC5D,aAAS,aAAa,MAAmB;AAEzC,WAAO,OAAO;AAAA,EAChB,OAAO;AACL,aAAS,EAAE,GAAG,OAAO;AAAA,EACvB;AAEA,MAAI,OAAO,SAAS,UAAU;AAE5B,WAAO,uBAAuB;AAG9B,QAAI,OAAO,YAAY;AACrB,aAAO,WAAW,OAAO,KAAK,OAAO,UAAU;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;;;AC3NA,IAAM,mBAAmB;AAoBlB,IAAM,iBAAN,MAAqB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA,eAAe,oBAAI,IAAwB;AAAA,EAErE,YAAY,QAAqB;AAC/B,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AACA,SAAK,WAAW,OAAO;AACvB,SAAK,aAAa,OAAO;AACzB,SAAK,YAAY,OAAO,WAAW,kBAAkB,QAAQ,OAAO,EAAE;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAe;AACjB,WAAO,GAAG,KAAK,QAAQ,iBAAiB,KAAK,QAAQ;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,WAA+C;AAC3D,UAAM,UAAkC,CAAC;AACzC,QAAI,KAAK,YAAY;AACnB,cAAQ,eAAe,IAAI,UAAU,KAAK,UAAU;AAAA,IACtD;AACA,QAAI,WAAW;AACb,cAAQ,8BAA8B,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,QACJ,SACA,WACA,SACuB;AACvB,UAAM,UAAU,IAAI,aAAa,IAAI;AACrC,UAAM,QAAQ,QAAQ,SAAS,WAAW,OAAO;AACjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,WAA6C;AACnD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AACA,WAAO,IAAI,aAAa,MAAM,SAAsB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,MAAwB;AACzC,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,SAAK,aAAa,IAAI,KAAK,MAAM,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,MAAoB;AACvC,SAAK,aAAa,OAAO,IAAI;AAAA,EAC/B;AACF;;;AC7GA,SAAS,GAAG,gBAAAA,qBAAoB;","names":["toJSONSchema"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/core/index.ts"],"sourcesContent":["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<{ callId: string; result: unknown } | null>[] = [];\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 const handlerResults = await Promise.allSettled(pendingAutoResumes);\n for (const settled of handlerResults) {\n if (settled.status === \"fulfilled\" && settled.value) {\n const { callId, result } = settled.value;\n await onAutoResume?.(callId, result);\n }\n }\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<{ callId: string; result: unknown } | null>[],\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 (): Promise<{\n callId: string;\n result: unknown;\n } | null> => {\n try {\n const result = await tool.handler!(inputs);\n\n // Synthesize a tool_call_end event for local observers (like debug panels)\n // since the backend only emits for server-side executed tools\n callbacks.onEvent?.({\n type: \"tool_call_end\",\n data: {\n callId,\n toolName,\n toolType: \"client\",\n result,\n },\n meta: event.meta,\n });\n\n return { callId, result };\n } catch (error) {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n return null;\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 ExecuteOptions,\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 callbacks - Event handlers for the stream\n * @param options - Optional settings like context, headers, or body\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (options?.context) {\n Object.assign(body, { context: options.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, options);\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 * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resume(\n result: any,\n callbacks: StreamCallbacks,\n options?: Omit<ExecuteOptions, \"context\">,\n ): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\"AgentSession.resume(): session is not paused. Check isPaused() first.\");\n }\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\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, options);\n return this;\n }\n\n /**\n * Resume a session with an explicit tool call ID and result.\n *\n * Unlike `resume()`, this does NOT require the session to be in a paused state,\n * making it suitable for external resume flows (e.g. React widget submissions)\n * where the session object may have been re-created.\n *\n * @param callId - The tool call ID to resume\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resumeWithCallId(\n callId: string,\n result: any,\n callbacks: StreamCallbacks,\n options?: Omit<ExecuteOptions, \"context\">,\n ): Promise<AgentSession> {\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\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 // Clear any stale pause state\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\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 options?: Omit<ExecuteOptions, \"context\">,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n const baseHeaders = this._agent._buildHeaders(this._sessionId);\n const mergedHeaders = { ...baseHeaders, ...(options?.headers || {}) };\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: mergedHeaders,\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id, name) => {\n this._sessionId = id;\n options?.onSessionId?.(id, name);\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 ...(options?.body || {}),\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, options);\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 { AgentConfig, ClientTool, ExecuteOptions, SessionId, StreamCallbacks } 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 options - Optional execution settings (context, headers, body, onSessionId)\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, options);\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","// ─── 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"],"mappings":"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","names":["toJSONSchema"]}
|