@opencode/ai 0.0.0-dev-20206 → 0.0.0-dev-20208

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.
@@ -50,23 +50,25 @@ const fromRequest = Effect.fn("DeepgramSpeech.fromRequest")(function* (request)
50
50
  // ---------------------------------------------------------------------------
51
51
  // 6. Stream parsing
52
52
  // ---------------------------------------------------------------------------
53
+ /** Deepgram wraps raw encodings in WAV unless `container` is `none`, and defaults their sample rate per encoding. */
53
54
  const HEADERLESS_ENCODINGS = {
54
- linear16: "pcm_s16le",
55
- mulaw: "pcm_mulaw",
56
- alaw: "pcm_alaw",
55
+ linear16: { encoding: "pcm_s16le", sampleRate: 24000 },
56
+ mulaw: { encoding: "pcm_mulaw", sampleRate: 8000 },
57
+ alaw: { encoding: "pcm_alaw", sampleRate: 8000 },
57
58
  };
58
59
  const finish = (state, context) => {
59
60
  const headers = context.http.headers;
60
61
  const mediaType = headers["content-type"];
61
62
  const format = audioFormat(context.request);
62
- const encoding = HEADERLESS_ENCODINGS[format.encoding ?? ""];
63
+ const headerless = HEADERLESS_ENCODINGS[format.encoding ?? ""];
64
+ const container = format.container ?? (headerless === undefined ? undefined : "wav");
63
65
  const requestID = headers["dg-request-id"];
64
66
  const modelName = headers["dg-model-name"];
65
67
  return SpeechStream.finish(route, state, {
66
- ...(format.container === "none" && encoding !== undefined
67
- ? SpeechStream.pcm(encoding, SpeechStream.sampleRate(mediaType), mediaType)
68
+ ...(container === "none" && headerless !== undefined
69
+ ? SpeechStream.pcm(headerless.encoding, SpeechStream.sampleRate(mediaType) ?? context.request.providerOptions?.sampleRate ?? headerless.sampleRate, mediaType)
68
70
  : // Deepgram's default encoding is MP3; WAV is a container around any encoding.
69
- { mediaType, info: { format: format.container === "wav" ? "wav" : (format.encoding ?? "mp3") } }),
71
+ { mediaType, info: { format: container === "wav" ? "wav" : (format.encoding ?? "mp3") } }),
70
72
  usage: SpeechStream.headerUsage("characters", headers["dg-char-count"]),
71
73
  providerMetadata: requestID === undefined && modelName === undefined
72
74
  ? undefined
@@ -30,10 +30,13 @@ const decodeEvent = route.decodeFrame(SpeechStreamEvent);
30
30
  // ---------------------------------------------------------------------------
31
31
  // `sse` is not supported for `tts-1` or `tts-1-hd`; those models stream the raw audio body instead.
32
32
  const supportsSse = (model) => !/^tts-1(-hd)?(-|$)/.test(model);
33
+ const FORMATS = new Set(["mp3", "opus", "aac", "flac", "wav", "pcm"]);
33
34
  const fromRequest = Effect.fn("OpenAISpeech.fromRequest")(function* (request) {
34
35
  // Not in `unsupported`: that list would also reject `timestamps: false`, which asks for nothing.
35
36
  if (request.timestamps === true)
36
37
  return yield* route.unsupported("media.timestamps", `${route.name} does not return timestamps`);
38
+ if (request.format !== undefined && !FORMATS.has(request.format))
39
+ return yield* route.unsupported("media.format", `${route.name} supports the mp3, opus, aac, flac, wav, and pcm formats, not "${request.format}"`);
37
40
  return MediaProtocol.json(mergeJsonRecords({
38
41
  model: request.model.id,
39
42
  input: request.text,
@@ -73,7 +76,9 @@ const onEvent = Effect.fn("OpenAISpeech.onEvent")(function* (state, frame) {
73
76
  const finish = (state, context) => {
74
77
  if (isSse(context.body) && !state.done)
75
78
  return Effect.fail(route.incomplete());
76
- const format = context.request.format ?? "mp3";
79
+ // The sent body reflects `providerOptions` and `http.body` overrides of `format`.
80
+ const sent = context.body.type === "json" ? context.body.value.response_format : undefined;
81
+ const format = typeof sent === "string" ? sent : "mp3";
77
82
  return SpeechStream.finish(route, state, {
78
83
  ...(format === "pcm" ? SpeechStream.pcm("pcm_s16le", PCM_SAMPLE_RATE) : SpeechStream.container(format)),
79
84
  usage: state.usage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-dev-20206",
3
+ "version": "0.0.0-dev-20208",
4
4
  "name": "@opencode/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@clack/prompts": "1.0.0-alpha.1",
36
36
  "@effect/platform-node": "4.0.0-rc.112",
37
- "@opencode/http-recorder": "0.0.0-dev-20206",
37
+ "@opencode/http-recorder": "0.0.0-dev-20208",
38
38
  "@tsconfig/bun": "1.0.9",
39
39
  "@types/bun": "1.4.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -44,7 +44,7 @@
44
44
  "@aws-sdk/credential-providers": "3.1057.0",
45
45
  "@smithy/eventstream-codec": "4.2.14",
46
46
  "@smithy/util-utf8": "4.2.2",
47
- "@opencode/schema": "0.0.0-dev-20206",
47
+ "@opencode/schema": "0.0.0-dev-20208",
48
48
  "aws4fetch": "1.0.20",
49
49
  "effect": "4.0.0-rc.112",
50
50
  "google-auth-library": "10.5.0"