@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/dist/index.mjs
CHANGED
|
@@ -1885,11 +1885,22 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
1885
1885
|
}
|
|
1886
1886
|
});
|
|
1887
1887
|
}
|
|
1888
|
-
|
|
1888
|
+
/**
|
|
1889
|
+
* Send a user message and receive the agent's synchronous JSON response.
|
|
1890
|
+
*
|
|
1891
|
+
* Pass `options.includeToolCalls: true` to request tool-call metadata
|
|
1892
|
+
* alongside the response turns. Server-side default is `false` — without
|
|
1893
|
+
* this opt-in the `tool_calls` array on the `TurnResponse` will be empty
|
|
1894
|
+
* even when the agent invoked tools during the turn.
|
|
1895
|
+
*/
|
|
1896
|
+
async createTurn(conversationId, request, options) {
|
|
1889
1897
|
return extractData(
|
|
1890
1898
|
await this.client.POST("/v1/{workspace_id}/conversations/{conversation_id}/turns", {
|
|
1891
1899
|
params: {
|
|
1892
|
-
path: { workspace_id: this.workspaceId, conversation_id: conversationId }
|
|
1900
|
+
path: { workspace_id: this.workspaceId, conversation_id: conversationId },
|
|
1901
|
+
...options?.includeToolCalls !== void 0 && {
|
|
1902
|
+
query: { include_tool_calls: options.includeToolCalls }
|
|
1903
|
+
}
|
|
1893
1904
|
},
|
|
1894
1905
|
body: request,
|
|
1895
1906
|
headers: { Accept: "application/json" }
|
|
@@ -1919,7 +1930,10 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
1919
1930
|
"/v1/{workspace_id}/conversations/{conversation_id}/turns",
|
|
1920
1931
|
{
|
|
1921
1932
|
params: {
|
|
1922
|
-
path: { workspace_id: this.workspaceId, conversation_id: conversationId }
|
|
1933
|
+
path: { workspace_id: this.workspaceId, conversation_id: conversationId },
|
|
1934
|
+
...options?.includeToolCalls !== void 0 && {
|
|
1935
|
+
query: { include_tool_calls: options.includeToolCalls }
|
|
1936
|
+
}
|
|
1923
1937
|
},
|
|
1924
1938
|
body: request,
|
|
1925
1939
|
headers: { Accept: "text/event-stream" },
|
|
@@ -1932,6 +1946,35 @@ var ConversationsResource = class extends WorkspaceScopedResource {
|
|
|
1932
1946
|
}
|
|
1933
1947
|
return result.data;
|
|
1934
1948
|
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Send a message and receive the agent's response as a typed
|
|
1951
|
+
* `TurnStreamEvent` async iterable.
|
|
1952
|
+
*
|
|
1953
|
+
* The bytes-and-parser dance from `createTurnStream` is now hidden inside
|
|
1954
|
+
* the SDK — consumers iterate strongly typed events directly. Each yielded
|
|
1955
|
+
* value is a member of the `TurnStreamEvent` discriminated union (`token`,
|
|
1956
|
+
* `thinking`, `tool_call_started`, `tool_call_completed`, `message`,
|
|
1957
|
+
* `done`, `error`), validated as a record with a known `event`
|
|
1958
|
+
* discriminator. Unknown / malformed frames are dropped silently — this
|
|
1959
|
+
* matches the wire-format-drift behavior of the lower-level
|
|
1960
|
+
* `createTurnStream` while keeping the strict `TurnStreamEvent` static
|
|
1961
|
+
* contract intact for consumers.
|
|
1962
|
+
*
|
|
1963
|
+
* @example
|
|
1964
|
+
* ```ts
|
|
1965
|
+
* for await (const event of client.conversations.streamTurn(convId, { message: "Hello" })) {
|
|
1966
|
+
* if (event.event === "token") process.stdout.write(event.text);
|
|
1967
|
+
* else if (event.event === "done") break;
|
|
1968
|
+
* }
|
|
1969
|
+
* ```
|
|
1970
|
+
*/
|
|
1971
|
+
async *streamTurn(conversationId, request, options) {
|
|
1972
|
+
const byteStream = await this.createTurnStream(conversationId, request, options);
|
|
1973
|
+
for await (const frame of parseSSEFrames(byteStream)) {
|
|
1974
|
+
const event = parseTurnStreamFrame(frame.event, frame.data);
|
|
1975
|
+
if (event) yield event;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1935
1978
|
/** Build the real-time text WebSocket URL for browser or custom clients. */
|
|
1936
1979
|
textStreamUrl(params) {
|
|
1937
1980
|
const url = buildTextStreamUrl({
|
|
@@ -2123,6 +2166,80 @@ function describeInvalidSubprotocolChars(token) {
|
|
|
2123
2166
|
}
|
|
2124
2167
|
return [...chars].map((char) => JSON.stringify(char)).join(", ");
|
|
2125
2168
|
}
|
|
2169
|
+
async function* parseSSEFrames(stream) {
|
|
2170
|
+
const reader = stream.getReader();
|
|
2171
|
+
const decoder = new TextDecoder();
|
|
2172
|
+
let buffer = "";
|
|
2173
|
+
function* drain(text) {
|
|
2174
|
+
buffer += text;
|
|
2175
|
+
while (true) {
|
|
2176
|
+
const idx = findFrameTerminator(buffer);
|
|
2177
|
+
if (idx === null) break;
|
|
2178
|
+
const block = buffer.slice(0, idx.terminatorStart);
|
|
2179
|
+
buffer = buffer.slice(idx.terminatorEnd);
|
|
2180
|
+
const frame = parseSSEBlock(block);
|
|
2181
|
+
if (frame) yield frame;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
try {
|
|
2185
|
+
while (true) {
|
|
2186
|
+
const { done, value } = await reader.read();
|
|
2187
|
+
if (done) break;
|
|
2188
|
+
yield* drain(decoder.decode(value, { stream: true }));
|
|
2189
|
+
}
|
|
2190
|
+
yield* drain(decoder.decode());
|
|
2191
|
+
if (buffer.trim().length > 0) {
|
|
2192
|
+
const frame = parseSSEBlock(buffer);
|
|
2193
|
+
if (frame) yield frame;
|
|
2194
|
+
buffer = "";
|
|
2195
|
+
}
|
|
2196
|
+
} finally {
|
|
2197
|
+
reader.releaseLock();
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
function findFrameTerminator(s) {
|
|
2201
|
+
const lf = s.indexOf("\n\n");
|
|
2202
|
+
const crlf = s.indexOf("\r\n\r\n");
|
|
2203
|
+
if (lf < 0 && crlf < 0) return null;
|
|
2204
|
+
if (lf < 0) return { terminatorStart: crlf, terminatorEnd: crlf + 4 };
|
|
2205
|
+
if (crlf < 0) return { terminatorStart: lf, terminatorEnd: lf + 2 };
|
|
2206
|
+
return lf < crlf ? { terminatorStart: lf, terminatorEnd: lf + 2 } : { terminatorStart: crlf, terminatorEnd: crlf + 4 };
|
|
2207
|
+
}
|
|
2208
|
+
function parseSSEBlock(block) {
|
|
2209
|
+
let event = "";
|
|
2210
|
+
const dataLines = [];
|
|
2211
|
+
for (const line of block.split(/\r?\n/)) {
|
|
2212
|
+
if (line === "" || line.startsWith(":")) continue;
|
|
2213
|
+
const colon = line.indexOf(":");
|
|
2214
|
+
const field = colon < 0 ? line : line.slice(0, colon);
|
|
2215
|
+
let value = colon < 0 ? "" : line.slice(colon + 1);
|
|
2216
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
2217
|
+
if (field === "event") event = value;
|
|
2218
|
+
else if (field === "data") dataLines.push(value);
|
|
2219
|
+
}
|
|
2220
|
+
if (!event || dataLines.length === 0) return null;
|
|
2221
|
+
return { event, data: dataLines.join("\n") };
|
|
2222
|
+
}
|
|
2223
|
+
var KNOWN_TURN_STREAM_EVENTS = /* @__PURE__ */ new Set([
|
|
2224
|
+
"token",
|
|
2225
|
+
"thinking",
|
|
2226
|
+
"tool_call_started",
|
|
2227
|
+
"tool_call_completed",
|
|
2228
|
+
"message",
|
|
2229
|
+
"done",
|
|
2230
|
+
"error"
|
|
2231
|
+
]);
|
|
2232
|
+
function parseTurnStreamFrame(eventName, dataJson) {
|
|
2233
|
+
if (!KNOWN_TURN_STREAM_EVENTS.has(eventName)) return null;
|
|
2234
|
+
let payload;
|
|
2235
|
+
try {
|
|
2236
|
+
payload = JSON.parse(dataJson);
|
|
2237
|
+
} catch {
|
|
2238
|
+
return null;
|
|
2239
|
+
}
|
|
2240
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) return null;
|
|
2241
|
+
return { ...payload, event: eventName };
|
|
2242
|
+
}
|
|
2126
2243
|
|
|
2127
2244
|
// src/resources/phone-numbers.ts
|
|
2128
2245
|
var PhoneNumbersResource = class extends WorkspaceScopedResource {
|