@amigo-ai/platform-sdk 0.22.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/dist/index.mjs CHANGED
@@ -1930,7 +1930,10 @@ var ConversationsResource = class extends WorkspaceScopedResource {
1930
1930
  "/v1/{workspace_id}/conversations/{conversation_id}/turns",
1931
1931
  {
1932
1932
  params: {
1933
- 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
+ }
1934
1937
  },
1935
1938
  body: request,
1936
1939
  headers: { Accept: "text/event-stream" },
@@ -1943,6 +1946,35 @@ var ConversationsResource = class extends WorkspaceScopedResource {
1943
1946
  }
1944
1947
  return result.data;
1945
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
+ }
1946
1978
  /** Build the real-time text WebSocket URL for browser or custom clients. */
1947
1979
  textStreamUrl(params) {
1948
1980
  const url = buildTextStreamUrl({
@@ -2134,6 +2166,80 @@ function describeInvalidSubprotocolChars(token) {
2134
2166
  }
2135
2167
  return [...chars].map((char) => JSON.stringify(char)).join(", ");
2136
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
+ }
2137
2243
 
2138
2244
  // src/resources/phone-numbers.ts
2139
2245
  var PhoneNumbersResource = class extends WorkspaceScopedResource {