@acosmi/sdk-ts 2.19.2 → 2.19.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.19.3
2
+
3
+ - Surface gateway stream failures on the OpenAI line instead of crashing on them. The gateway emits its structured error frame with `event: failed`, but the OpenAI branch of `chatMessagesStream` captured the SSE event name and never read it, so the error frame reached the OpenAI chunk converter and died on `chunk.choices.length` - replacing the real upstream cause with an unrelated TypeError. That branch now routes `failed` and `error` frames through the existing `parseStreamError`, exactly as `chatStreamWithUsage` already did.
4
+ - Guard the OpenAI stream converter against data frames that carry no `choices` (gateway error frames, usage-only tail frames from some compatible implementations), and mark `OpenAIStreamChunk.choices` optional - the type declared it required while the wire genuinely omits it, which is where the TypeError came from.
5
+ - No behavior change on the Anthropic line, and no change to request building.
6
+
1
7
  ## 2.19.2
2
8
 
3
9
  - Preserve catalog-supported low, medium, xhigh, and max thinking levels through both chat adapters.
@@ -1084,7 +1084,7 @@ var init_openai = __esm({
1084
1084
  throw new Error(`parse openai stream chunk: ${e instanceof Error ? e.message : String(e)}`);
1085
1085
  }
1086
1086
  const events = [];
1087
- if (chunk.choices.length === 0) {
1087
+ if (!Array.isArray(chunk.choices) || chunk.choices.length === 0) {
1088
1088
  return { events, done: false };
1089
1089
  }
1090
1090
  const choice = chunk.choices[0];
@@ -4355,13 +4355,17 @@ var Client = class _Client {
4355
4355
  }
4356
4356
  if (adapter.format() === 1 /* OpenAI */) {
4357
4357
  const converter = newOpenAIStreamConverter();
4358
+ let currentEvent = "";
4358
4359
  for await (const line of iterSSELines(resp.body)) {
4359
4360
  notifyUpstreamActivity(onUpstreamActivity);
4360
4361
  if (isSSECommentLine(line)) continue;
4361
4362
  if (line.startsWith("event:")) {
4362
- line.slice("event:".length).trim();
4363
+ currentEvent = line.slice("event:".length).trim();
4363
4364
  } else if (line.startsWith("data:")) {
4364
4365
  const data = line.slice("data:".length).trim();
4366
+ if (currentEvent === "failed" || currentEvent === "error") {
4367
+ throw parseStreamError(data);
4368
+ }
4365
4369
  const { events, done } = converter.convert(data);
4366
4370
  for (const ev of events) yield ev;
4367
4371
  if (done) return;