@amigo-ai/platform-sdk 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.md +1 -0
- package/dist/index.cjs +120 -3
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +120 -3
- package/dist/index.mjs.map +2 -2
- package/dist/resources/conversations.js +156 -1
- package/dist/resources/conversations.js.map +1 -1
- package/dist/types/resources/conversations.d.ts +38 -1
- package/dist/types/resources/conversations.d.ts.map +1 -1
- package/package.json +1 -1
package/api.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1979,11 +1979,22 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
1979
1979
|
}
|
|
1980
1980
|
});
|
|
1981
1981
|
}
|
|
1982
|
-
|
|
1982
|
+
/**
|
|
1983
|
+
* Send a user message and receive the agent's synchronous JSON response.
|
|
1984
|
+
*
|
|
1985
|
+
* Pass `options.includeToolCalls: true` to request tool-call metadata
|
|
1986
|
+
* alongside the response turns. Server-side default is `false` — without
|
|
1987
|
+
* this opt-in the `tool_calls` array on the `TurnResponse` will be empty
|
|
1988
|
+
* even when the agent invoked tools during the turn.
|
|
1989
|
+
*/
|
|
1990
|
+
async createTurn(conversationId, request, options) {
|
|
1983
1991
|
return extractData(
|
|
1984
1992
|
await this.client.POST("/v1/{workspace_id}/conversations/{conversation_id}/turns", {
|
|
1985
1993
|
params: {
|
|
1986
|
-
path: { workspace_id: this.workspaceId, conversation_id: conversationId }
|
|
1994
|
+
path: { workspace_id: this.workspaceId, conversation_id: conversationId },
|
|
1995
|
+
...options?.includeToolCalls !== void 0 && {
|
|
1996
|
+
query: { include_tool_calls: options.includeToolCalls }
|
|
1997
|
+
}
|
|
1987
1998
|
},
|
|
1988
1999
|
body: request,
|
|
1989
2000
|
headers: { Accept: "application/json" }
|
|
@@ -2013,7 +2024,10 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
2013
2024
|
"/v1/{workspace_id}/conversations/{conversation_id}/turns",
|
|
2014
2025
|
{
|
|
2015
2026
|
params: {
|
|
2016
|
-
path: { workspace_id: this.workspaceId, conversation_id: conversationId }
|
|
2027
|
+
path: { workspace_id: this.workspaceId, conversation_id: conversationId },
|
|
2028
|
+
...options?.includeToolCalls !== void 0 && {
|
|
2029
|
+
query: { include_tool_calls: options.includeToolCalls }
|
|
2030
|
+
}
|
|
2017
2031
|
},
|
|
2018
2032
|
body: request,
|
|
2019
2033
|
headers: { Accept: "text/event-stream" },
|
|
@@ -2026,6 +2040,35 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
2026
2040
|
}
|
|
2027
2041
|
return result.data;
|
|
2028
2042
|
}
|
|
2043
|
+
/**
|
|
2044
|
+
* Send a message and receive the agent's response as a typed
|
|
2045
|
+
* `TurnStreamEvent` async iterable.
|
|
2046
|
+
*
|
|
2047
|
+
* The bytes-and-parser dance from `createTurnStream` is now hidden inside
|
|
2048
|
+
* the SDK — consumers iterate strongly typed events directly. Each yielded
|
|
2049
|
+
* value is a member of the `TurnStreamEvent` discriminated union (`token`,
|
|
2050
|
+
* `thinking`, `tool_call_started`, `tool_call_completed`, `message`,
|
|
2051
|
+
* `done`, `error`), validated as a record with a known `event`
|
|
2052
|
+
* discriminator. Unknown / malformed frames are dropped silently — this
|
|
2053
|
+
* matches the wire-format-drift behavior of the lower-level
|
|
2054
|
+
* `createTurnStream` while keeping the strict `TurnStreamEvent` static
|
|
2055
|
+
* contract intact for consumers.
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```ts
|
|
2059
|
+
* for await (const event of client.conversations.streamTurn(convId, { message: "Hello" })) {
|
|
2060
|
+
* if (event.event === "token") process.stdout.write(event.text);
|
|
2061
|
+
* else if (event.event === "done") break;
|
|
2062
|
+
* }
|
|
2063
|
+
* ```
|
|
2064
|
+
*/
|
|
2065
|
+
async *streamTurn(conversationId, request, options) {
|
|
2066
|
+
const byteStream = await this.createTurnStream(conversationId, request, options);
|
|
2067
|
+
for await (const frame of parseSSEFrames(byteStream)) {
|
|
2068
|
+
const event = parseTurnStreamFrame(frame.event, frame.data);
|
|
2069
|
+
if (event) yield event;
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2029
2072
|
/** Build the real-time text WebSocket URL for browser or custom clients. */
|
|
2030
2073
|
textStreamUrl(params) {
|
|
2031
2074
|
const url = buildTextStreamUrl({
|
|
@@ -2217,6 +2260,80 @@ function describeInvalidSubprotocolChars(token) {
|
|
|
2217
2260
|
}
|
|
2218
2261
|
return [...chars].map((char) => JSON.stringify(char)).join(", ");
|
|
2219
2262
|
}
|
|
2263
|
+
async function* parseSSEFrames(stream) {
|
|
2264
|
+
const reader = stream.getReader();
|
|
2265
|
+
const decoder = new TextDecoder();
|
|
2266
|
+
let buffer = "";
|
|
2267
|
+
function* drain(text) {
|
|
2268
|
+
buffer += text;
|
|
2269
|
+
while (true) {
|
|
2270
|
+
const idx = findFrameTerminator(buffer);
|
|
2271
|
+
if (idx === null) break;
|
|
2272
|
+
const block = buffer.slice(0, idx.terminatorStart);
|
|
2273
|
+
buffer = buffer.slice(idx.terminatorEnd);
|
|
2274
|
+
const frame = parseSSEBlock(block);
|
|
2275
|
+
if (frame) yield frame;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
try {
|
|
2279
|
+
while (true) {
|
|
2280
|
+
const { done, value } = await reader.read();
|
|
2281
|
+
if (done) break;
|
|
2282
|
+
yield* drain(decoder.decode(value, { stream: true }));
|
|
2283
|
+
}
|
|
2284
|
+
yield* drain(decoder.decode());
|
|
2285
|
+
if (buffer.trim().length > 0) {
|
|
2286
|
+
const frame = parseSSEBlock(buffer);
|
|
2287
|
+
if (frame) yield frame;
|
|
2288
|
+
buffer = "";
|
|
2289
|
+
}
|
|
2290
|
+
} finally {
|
|
2291
|
+
reader.releaseLock();
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
function findFrameTerminator(s) {
|
|
2295
|
+
const lf = s.indexOf("\n\n");
|
|
2296
|
+
const crlf = s.indexOf("\r\n\r\n");
|
|
2297
|
+
if (lf < 0 && crlf < 0) return null;
|
|
2298
|
+
if (lf < 0) return { terminatorStart: crlf, terminatorEnd: crlf + 4 };
|
|
2299
|
+
if (crlf < 0) return { terminatorStart: lf, terminatorEnd: lf + 2 };
|
|
2300
|
+
return lf < crlf ? { terminatorStart: lf, terminatorEnd: lf + 2 } : { terminatorStart: crlf, terminatorEnd: crlf + 4 };
|
|
2301
|
+
}
|
|
2302
|
+
function parseSSEBlock(block) {
|
|
2303
|
+
let event = "";
|
|
2304
|
+
const dataLines = [];
|
|
2305
|
+
for (const line of block.split(/\r?\n/)) {
|
|
2306
|
+
if (line === "" || line.startsWith(":")) continue;
|
|
2307
|
+
const colon = line.indexOf(":");
|
|
2308
|
+
const field = colon < 0 ? line : line.slice(0, colon);
|
|
2309
|
+
let value = colon < 0 ? "" : line.slice(colon + 1);
|
|
2310
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
2311
|
+
if (field === "event") event = value;
|
|
2312
|
+
else if (field === "data") dataLines.push(value);
|
|
2313
|
+
}
|
|
2314
|
+
if (!event || dataLines.length === 0) return null;
|
|
2315
|
+
return { event, data: dataLines.join("\n") };
|
|
2316
|
+
}
|
|
2317
|
+
var KNOWN_TURN_STREAM_EVENTS = /* @__PURE__ */ new Set([
|
|
2318
|
+
"token",
|
|
2319
|
+
"thinking",
|
|
2320
|
+
"tool_call_started",
|
|
2321
|
+
"tool_call_completed",
|
|
2322
|
+
"message",
|
|
2323
|
+
"done",
|
|
2324
|
+
"error"
|
|
2325
|
+
]);
|
|
2326
|
+
function parseTurnStreamFrame(eventName, dataJson) {
|
|
2327
|
+
if (!KNOWN_TURN_STREAM_EVENTS.has(eventName)) return null;
|
|
2328
|
+
let payload;
|
|
2329
|
+
try {
|
|
2330
|
+
payload = JSON.parse(dataJson);
|
|
2331
|
+
} catch {
|
|
2332
|
+
return null;
|
|
2333
|
+
}
|
|
2334
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) return null;
|
|
2335
|
+
return { ...payload, event: eventName };
|
|
2336
|
+
}
|
|
2220
2337
|
|
|
2221
2338
|
// src/resources/phone-numbers.ts
|
|
2222
2339
|
var PhoneNumbersResource = class extends WorkspaceScopedResource {
|