@opencode/ai 0.0.0-dev-20138 → 0.0.0-dev-20141

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.
Files changed (44) hide show
  1. package/dist/image-client.d.ts +54 -21
  2. package/dist/image-client.js +14 -39
  3. package/dist/image.d.ts +13 -25
  4. package/dist/image.js +2 -13
  5. package/dist/media-client.d.ts +30 -0
  6. package/dist/media-client.js +51 -0
  7. package/dist/media-model.d.ts +9 -8
  8. package/dist/media-model.js +10 -10
  9. package/dist/promise.d.ts +26 -10
  10. package/dist/promise.js +15 -20
  11. package/dist/protocols/anthropic-messages.js +3 -6
  12. package/dist/protocols/bedrock-converse.js +5 -6
  13. package/dist/protocols/cartesia-speech.d.ts +16 -0
  14. package/dist/protocols/deepgram-speech.d.ts +16 -0
  15. package/dist/protocols/elevenlabs-speech.d.ts +16 -0
  16. package/dist/protocols/gemini.js +6 -6
  17. package/dist/protocols/google-speech.d.ts +16 -0
  18. package/dist/protocols/meta-responses.js +1 -2
  19. package/dist/protocols/mistral-chat.js +3 -6
  20. package/dist/protocols/open-responses.d.ts +1 -3
  21. package/dist/protocols/open-responses.js +3 -4
  22. package/dist/protocols/openai-chat.js +3 -4
  23. package/dist/protocols/openai-responses.js +7 -10
  24. package/dist/protocols/openai-speech.d.ts +16 -0
  25. package/dist/protocols/utils/tool-schema.d.ts +2 -2
  26. package/dist/protocols/utils/tool-schema.js +10 -3
  27. package/dist/route/client.d.ts +2 -1
  28. package/dist/route/client.js +3 -1
  29. package/dist/route/media.d.ts +4 -14
  30. package/dist/route/media.js +1 -36
  31. package/dist/route/protocol.d.ts +3 -1
  32. package/dist/speech-client.d.ts +57 -14
  33. package/dist/speech-client.js +15 -20
  34. package/dist/speech.d.ts +176 -19
  35. package/dist/speech.js +11 -6
  36. package/dist/transcription-client.d.ts +73 -21
  37. package/dist/transcription-client.js +7 -39
  38. package/dist/transcription.d.ts +13 -25
  39. package/dist/transcription.js +2 -8
  40. package/dist/video-client.d.ts +50 -21
  41. package/dist/video-client.js +14 -35
  42. package/dist/video.d.ts +14 -22
  43. package/dist/video.js +13 -14
  44. package/package.json +3 -3
@@ -5,7 +5,7 @@ import { Endpoint } from "./endpoint.js";
5
5
  import { RequestExecutorService } from "./executor-service.js";
6
6
  import { RequestExecutor } from "./executor.js";
7
7
  import { MediaProtocol } from "./media-protocol.js";
8
- import { Generation, resultEvents } from "../generation.js";
8
+ import { Generation } from "../generation.js";
9
9
  import { AIError, AIErrorReason, HttpOptions, InvalidRequestError, ProviderID, UnsupportedOperationError, mergeHttpOptions, } from "../schema/index.js";
10
10
  import { encodeJson } from "../utils/json.js";
11
11
  import { sanitizeSurrogates } from "../utils/sanitize.js";
@@ -112,41 +112,6 @@ export const stream = (input) => {
112
112
  generate: (request, execute) => events(request, execute, "generate").pipe(Stream.runCollect, Effect.flatMap(input.collect)),
113
113
  };
114
114
  };
115
- export const dispatch = (input) => {
116
- const notQueued = (route, operation) => new AIError({
117
- reason: new UnsupportedOperationError({
118
- operation: `${input.modality}.${operation}`,
119
- provider: route.provider,
120
- route: route.id,
121
- message: `${route.provider}/${route.id} is not a queued route; use generate or stream`,
122
- }),
123
- });
124
- const start = (route, request) => {
125
- if (route.kind !== "queued")
126
- return Effect.fail(notQueued(route, "start"));
127
- return route.start(request, input.execute);
128
- };
129
- return {
130
- start,
131
- resume: (route, model, token) => {
132
- if (route.kind !== "queued")
133
- return Effect.fail(notQueued(route, "resume"));
134
- return route.resume(model, token, input.execute);
135
- },
136
- generate: (route, request, options) => {
137
- if (route.kind !== "queued")
138
- return route.generate(request, input.execute);
139
- return start(route, request).pipe(Effect.flatMap((generation) => generation.await(options)));
140
- },
141
- stream: (route, request, options) => {
142
- if (route.kind === "stream")
143
- return route.stream(request, input.execute);
144
- if (route.kind === "queued")
145
- return Stream.unwrap(start(route, request).pipe(Effect.map((generation) => resultEvents(generation, input.responseEvents, options))));
146
- return Stream.fromIterableEffect(Effect.map(route.generate(request, input.execute), input.responseEvents));
147
- },
148
- };
149
- };
150
115
  // ---------------------------------------------------------------------------
151
116
  // Transport plumbing shared by every kind
152
117
  // ---------------------------------------------------------------------------
@@ -1,5 +1,5 @@
1
1
  import { Schema, type Effect } from "effect";
2
- import type { AIError, LLMEvent, LLMRequest, ProtocolID } from "../schema/index.js";
2
+ import type { AIError, LanguageModelSanitizerCompatibility, LLMEvent, LLMRequest, ProtocolID } from "../schema/index.js";
3
3
  /**
4
4
  * The semantic API contract of one model server family.
5
5
  *
@@ -42,6 +42,8 @@ export interface Protocol<Body, Frame, Event, State> {
42
42
  readonly stream: ProtocolStream<Frame, Event, State>;
43
43
  /** Whether `body.from` lowers `Message.effort(...)` markers; wrappers around another `body.from` must forward it. */
44
44
  readonly supportsEffortUpdates?: (request: LLMRequest) => boolean;
45
+ /** Tool schema sanitizer for every model on this protocol unless the model's compatibility sets one; wrappers around another `body.from` must forward it. */
46
+ readonly sanitizer?: LanguageModelSanitizerCompatibility;
45
47
  }
46
48
  export interface ProtocolBody<Body> {
47
49
  /** Schema for the validated provider-native body sent as the JSON request. */
@@ -1,23 +1,66 @@
1
- import { Context, Effect, Layer, Stream } from "effect";
2
- import { RequestExecutor } from "./route/executor.js";
3
- import type { AIError } from "./schema/index.js";
4
- import type { SpeechEvent, SpeechOptions, SpeechRequestFor, SpeechResponse } from "./speech.js";
5
- export interface Interface {
6
- readonly generate: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Effect.Effect<SpeechResponse, AIError>;
7
- readonly stream: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Stream.Stream<SpeechEvent, AIError>;
8
- }
1
+ import { Context } from "effect";
2
+ import { MediaClient } from "./media-client.js";
3
+ import { type SpeechEvent, type SpeechRequestFor, type SpeechResponse } from "./speech.js";
4
+ export type Interface = MediaClient.Interface<SpeechRequestFor, SpeechEvent, SpeechResponse>;
9
5
  declare const SpeechClientService_base: Context.ServiceClass<SpeechClientService, "@opencode/SpeechClient", Interface>;
10
6
  export declare class SpeechClientService extends SpeechClientService_base {
11
7
  }
12
8
  export declare const Service: typeof SpeechClientService;
13
9
  export type Service = SpeechClientService;
14
- export declare const generate: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Effect.Effect<SpeechResponse, AIError, Service>;
15
- export declare const stream: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Stream.Stream<SpeechEvent, AIError, Service>;
16
- export declare const layer: Layer.Layer<Service, never, RequestExecutor.Service>;
17
10
  export declare const SpeechClient: {
11
+ readonly layer: import("effect/Layer").Layer<SpeechClientService, never, import("./route/executor-service.js").RequestExecutorService>;
12
+ readonly generate: (request: SpeechRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<SpeechResponse, import("./index.js").AIError, SpeechClientService>;
13
+ readonly stream: (request: SpeechRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Stream").Stream<import("./generation.js").Observation | {
14
+ readonly type: "audio-delta";
15
+ readonly chunk: Uint8Array<ArrayBufferLike>;
16
+ } | {
17
+ readonly type: "timestamps";
18
+ readonly items: readonly {
19
+ readonly text: string;
20
+ readonly startSeconds: number;
21
+ readonly endSeconds: number;
22
+ }[];
23
+ } | {
24
+ readonly type: "finish";
25
+ readonly audio: import("./media.js").Asset;
26
+ readonly providerMetadata?: {
27
+ readonly [x: string]: {
28
+ readonly [x: string]: unknown;
29
+ };
30
+ } | undefined;
31
+ readonly usage?: {
32
+ readonly type: "tokens";
33
+ readonly input?: number | undefined;
34
+ readonly output?: number | undefined;
35
+ readonly total?: number | undefined;
36
+ readonly details?: {
37
+ readonly [x: string]: unknown;
38
+ } | undefined;
39
+ } | {
40
+ readonly type: "seconds";
41
+ readonly seconds: number;
42
+ } | {
43
+ readonly type: "characters";
44
+ readonly characters: number;
45
+ } | {
46
+ readonly type: "credits";
47
+ readonly credits: number;
48
+ } | {
49
+ readonly type: "compute";
50
+ readonly seconds: number;
51
+ } | undefined;
52
+ readonly notices?: readonly {
53
+ readonly type: "other" | "moderated" | "filtered";
54
+ readonly message: string;
55
+ readonly providerMetadata?: {
56
+ readonly [x: string]: {
57
+ readonly [x: string]: unknown;
58
+ };
59
+ } | undefined;
60
+ }[] | undefined;
61
+ }, import("./index.js").AIError, SpeechClientService>;
62
+ readonly start: (request: SpeechRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./index.js").AIError, SpeechClientService>;
63
+ readonly resume: (model: import("./speech.js").SpeechModel<import("./media-model.js").MediaModel.Options>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./index.js").AIError, SpeechClientService>;
18
64
  readonly Service: typeof SpeechClientService;
19
- readonly layer: Layer.Layer<SpeechClientService, never, import("./route/executor-service.js").RequestExecutorService>;
20
- readonly generate: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Effect.Effect<SpeechResponse, AIError, Service>;
21
- readonly stream: <Options extends SpeechOptions>(request: SpeechRequestFor<Options>) => Stream.Stream<SpeechEvent, AIError, Service>;
22
65
  };
23
66
  export {};
@@ -1,26 +1,21 @@
1
- import { Context, Effect, Layer, Stream } from "effect";
2
- import { RequestExecutor } from "./route/executor.js";
1
+ import { Context } from "effect";
2
+ import { MediaClient } from "./media-client.js";
3
+ import { SpeechTimestampsEvent, SpeechFinishEvent, } from "./speech.js";
3
4
  export class SpeechClientService extends Context.Service()("@opencode/SpeechClient") {
4
5
  }
5
6
  export const Service = SpeechClientService;
6
- export const generate = (request) => Effect.gen(function* () {
7
- const client = yield* Service;
8
- return yield* client.generate(request);
9
- });
10
- export const stream = (request) => Stream.unwrap(Effect.gen(function* () {
11
- const client = yield* Service;
12
- return client.stream(request);
13
- }));
14
- export const layer = Layer.effect(Service, Effect.gen(function* () {
15
- const executor = yield* RequestExecutor.Service;
16
- return Service.of({
17
- generate: (request) => request.model.route.generate(request, executor.execute),
18
- stream: (request) => request.model.route.stream(request, executor.execute),
19
- });
20
- }));
21
7
  export const SpeechClient = {
22
8
  Service,
23
- layer,
24
- generate,
25
- stream,
9
+ ...MediaClient.make(Service, {
10
+ modality: "speech",
11
+ responseEvents: (response) => [
12
+ ...(response.timestamps === undefined ? [] : [SpeechTimestampsEvent.make({ items: response.timestamps })]),
13
+ SpeechFinishEvent.make({
14
+ audio: response.audio,
15
+ usage: response.usage,
16
+ notices: response.notices,
17
+ providerMetadata: response.providerMetadata,
18
+ }),
19
+ ],
20
+ }),
26
21
  };
package/dist/speech.d.ts CHANGED
@@ -2,21 +2,18 @@ import { Effect, Schema, Stream } from "effect";
2
2
  import { Media } from "./media.js";
3
3
  import { MediaModel } from "./media-model.js";
4
4
  import { MediaRoute } from "./route/media.js";
5
- import type { MediaProtocol } from "./route/media-protocol.js";
6
5
  import { AIError, HttpOptions, type OpenString } from "./schema/index.js";
7
6
  import { Service } from "./speech-client.js";
8
- export type SpeechOptions = Record<string, unknown>;
9
- export type SpeechRoute<Options extends SpeechOptions = SpeechOptions> = MediaRoute.StreamRoute<SpeechRequestFor<Options>, SpeechEvent, SpeechResponse>;
10
- export declare class SpeechModel<Options extends SpeechOptions = SpeechOptions> extends MediaModel<SpeechRoute<Options>, Options> {
7
+ export type SpeechOptions = MediaModel.Options;
8
+ export type SpeechRoute = MediaRoute.AnyRoute<SpeechRequestFor, SpeechEvent, SpeechResponse>;
9
+ export declare class SpeechModel<Options extends SpeechOptions = SpeechOptions> extends MediaModel<SpeechRoute, Options> {
11
10
  protected readonly _SpeechModel: void;
12
- static make<Options extends SpeechOptions = SpeechOptions>(input: MediaModel.Input<SpeechRoute<Options>>): SpeechModel<Options>;
13
- /** Compose a streaming speech protocol with its canonical path into a model for one deployment. */
14
- static fromRoute<Options extends SpeechOptions = SpeechOptions, Frame = unknown, State = unknown>(route: SpeechModel.RouteInput<Options, Frame, State>, input: MediaRoute.ModelInput): SpeechModel<Options>;
11
+ /** The number of type arguments selects the kind: `<Options>`, `<Options, Frame, State>`, or `<Options, Token>`. */
12
+ static fromRoute<Options extends SpeechOptions>(route: MediaModel.InlineRouteInput<SpeechRequestFor<Options>, SpeechResponse>, input: MediaRoute.ModelInput): SpeechModel<Options>;
13
+ static fromRoute<Options extends SpeechOptions, Frame, State>(route: MediaModel.StreamRouteInput<SpeechRequestFor<Options>, SpeechEvent, Frame, State>, input: MediaRoute.ModelInput): SpeechModel<Options>;
14
+ static fromRoute<Options extends SpeechOptions, Token>(route: MediaModel.QueuedRouteInput<SpeechRequestFor<Options>, SpeechResponse, Token>, input: MediaRoute.ModelInput): SpeechModel<Options>;
15
15
  }
16
- export declare namespace SpeechModel {
17
- type RouteInput<Options extends SpeechOptions = SpeechOptions, Frame = unknown, State = unknown> = MediaModel.RouteInput<MediaProtocol.Addressed<SpeechRequestFor<Options>>, MediaProtocol.Streamed<SpeechRequestFor<Options>, SpeechEvent, Frame, State>>;
18
- }
19
- export declare const SpeechModelSchema: Schema.declare<SpeechModel<SpeechOptions>, SpeechModel<SpeechOptions>>;
16
+ export declare const SpeechModelSchema: Schema.declare<SpeechModel<MediaModel.Options>, SpeechModel<MediaModel.Options>>;
20
17
  /** Provider-native: a name on OpenAI and Gemini, a voice id on ElevenLabs and Cartesia; `{ id }` is an OpenAI custom voice. */
21
18
  export declare const SpeechVoice: Schema.Union<readonly [Schema.String, Schema.Struct<{
22
19
  readonly id: Schema.String;
@@ -31,7 +28,7 @@ export declare const SpeechTimestamp: Schema.Struct<{
31
28
  }>;
32
29
  export type SpeechTimestamp = Schema.Schema.Type<typeof SpeechTimestamp>;
33
30
  declare const SpeechRequest_base: Schema.Class<SpeechRequest, Schema.Struct<{
34
- readonly model: Schema.declare<SpeechModel<SpeechOptions>, SpeechModel<SpeechOptions>>;
31
+ readonly model: Schema.declare<SpeechModel<MediaModel.Options>, SpeechModel<MediaModel.Options>>;
35
32
  readonly text: Schema.String;
36
33
  readonly voice: Schema.optional<Schema.Union<readonly [Schema.String, Schema.Struct<{
37
34
  readonly id: Schema.String;
@@ -197,6 +194,14 @@ export declare const SpeechFinishEvent: Schema.Struct<{
197
194
  readonly providerMetadata: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>;
198
195
  }>;
199
196
  declare const speechEventTagged: Schema.toTaggedUnion<"type", readonly [Schema.Struct<{
197
+ readonly type: Schema.tag<"generation-queued">;
198
+ readonly id: Schema.String;
199
+ readonly position: Schema.optional<Schema.Number>;
200
+ }>, Schema.Struct<{
201
+ readonly type: Schema.tag<"generation-progress">;
202
+ readonly id: Schema.String;
203
+ readonly progress: Schema.optional<Schema.Number>;
204
+ }>, Schema.Struct<{
200
205
  readonly type: Schema.tag<"audio-delta">;
201
206
  readonly chunk: Schema.Uint8Array;
202
207
  }>, Schema.Struct<{
@@ -266,6 +271,14 @@ declare const speechEventTagged: Schema.toTaggedUnion<"type", readonly [Schema.S
266
271
  readonly providerMetadata: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>;
267
272
  }>]>;
268
273
  export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
274
+ readonly type: Schema.tag<"generation-queued">;
275
+ readonly id: Schema.String;
276
+ readonly position: Schema.optional<Schema.Number>;
277
+ }>, Schema.Struct<{
278
+ readonly type: Schema.tag<"generation-progress">;
279
+ readonly id: Schema.String;
280
+ readonly progress: Schema.optional<Schema.Number>;
281
+ }>, Schema.Struct<{
269
282
  readonly type: Schema.tag<"audio-delta">;
270
283
  readonly chunk: Schema.Uint8Array;
271
284
  }>, Schema.Struct<{
@@ -334,8 +347,18 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
334
347
  }>>>;
335
348
  readonly providerMetadata: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>;
336
349
  }>]> & {
337
- readonly discriminants: readonly ["audio-delta", "timestamps", "finish"];
350
+ readonly discriminants: readonly ["generation-queued", "generation-progress", "audio-delta", "timestamps", "finish"];
338
351
  readonly cases: {
352
+ "generation-queued": Schema.Struct<{
353
+ readonly type: Schema.tag<"generation-queued">;
354
+ readonly id: Schema.String;
355
+ readonly position: Schema.optional<Schema.Number>;
356
+ }>;
357
+ "generation-progress": Schema.Struct<{
358
+ readonly type: Schema.tag<"generation-progress">;
359
+ readonly id: Schema.String;
360
+ readonly progress: Schema.optional<Schema.Number>;
361
+ }>;
339
362
  "audio-delta": Schema.Struct<{
340
363
  readonly type: Schema.tag<"audio-delta">;
341
364
  readonly chunk: Schema.Uint8Array;
@@ -409,6 +432,14 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
409
432
  }>;
410
433
  };
411
434
  readonly isAnyOf: <const Keys>(keys: readonly Keys[]) => (value: {
435
+ readonly id: string;
436
+ readonly type: "generation-queued";
437
+ readonly position?: number | undefined;
438
+ } | {
439
+ readonly id: string;
440
+ readonly type: "generation-progress";
441
+ readonly progress?: number | undefined;
442
+ } | {
412
443
  readonly type: "audio-delta";
413
444
  readonly chunk: Uint8Array<ArrayBufferLike>;
414
445
  } | {
@@ -457,6 +488,18 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
457
488
  } | undefined;
458
489
  }[] | undefined;
459
490
  }) => value is Extract<{
491
+ readonly id: string;
492
+ readonly type: "generation-queued";
493
+ readonly position?: number | undefined;
494
+ }, {
495
+ readonly type: Keys;
496
+ }> | Extract<{
497
+ readonly id: string;
498
+ readonly type: "generation-progress";
499
+ readonly progress?: number | undefined;
500
+ }, {
501
+ readonly type: Keys;
502
+ }> | Extract<{
460
503
  readonly type: "audio-delta";
461
504
  readonly chunk: Uint8Array<ArrayBufferLike>;
462
505
  }, {
@@ -512,6 +555,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
512
555
  readonly type: Keys;
513
556
  }>;
514
557
  readonly guards: {
558
+ "generation-queued": (u: unknown) => u is {
559
+ readonly id: string;
560
+ readonly type: "generation-queued";
561
+ readonly position?: number | undefined;
562
+ };
563
+ "generation-progress": (u: unknown) => u is {
564
+ readonly id: string;
565
+ readonly type: "generation-progress";
566
+ readonly progress?: number | undefined;
567
+ };
515
568
  "audio-delta": (u: unknown) => u is {
516
569
  readonly type: "audio-delta";
517
570
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -566,6 +619,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
566
619
  };
567
620
  readonly match: {
568
621
  <Cases extends {
622
+ "generation-queued": (value: {
623
+ readonly id: string;
624
+ readonly type: "generation-queued";
625
+ readonly position?: number | undefined;
626
+ }) => any;
627
+ "generation-progress": (value: {
628
+ readonly id: string;
629
+ readonly type: "generation-progress";
630
+ readonly progress?: number | undefined;
631
+ }) => any;
569
632
  "audio-delta": (value: {
570
633
  readonly type: "audio-delta";
571
634
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -618,6 +681,14 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
618
681
  }[] | undefined;
619
682
  }) => any;
620
683
  }>(value: {
684
+ readonly id: string;
685
+ readonly type: "generation-queued";
686
+ readonly position?: number | undefined;
687
+ } | {
688
+ readonly id: string;
689
+ readonly type: "generation-progress";
690
+ readonly progress?: number | undefined;
691
+ } | {
621
692
  readonly type: "audio-delta";
622
693
  readonly chunk: Uint8Array<ArrayBufferLike>;
623
694
  } | {
@@ -667,6 +738,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
667
738
  }[] | undefined;
668
739
  }, cases: Cases): Cases[keyof Cases] extends (value: any) => infer R ? import("effect/Unify").Unify<R> : never;
669
740
  <Cases extends {
741
+ "generation-queued": (value: {
742
+ readonly id: string;
743
+ readonly type: "generation-queued";
744
+ readonly position?: number | undefined;
745
+ }) => any;
746
+ "generation-progress": (value: {
747
+ readonly id: string;
748
+ readonly type: "generation-progress";
749
+ readonly progress?: number | undefined;
750
+ }) => any;
670
751
  "audio-delta": (value: {
671
752
  readonly type: "audio-delta";
672
753
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -719,6 +800,14 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
719
800
  }[] | undefined;
720
801
  }) => any;
721
802
  }>(cases: Cases): (value: {
803
+ readonly id: string;
804
+ readonly type: "generation-queued";
805
+ readonly position?: number | undefined;
806
+ } | {
807
+ readonly id: string;
808
+ readonly type: "generation-progress";
809
+ readonly progress?: number | undefined;
810
+ } | {
722
811
  readonly type: "audio-delta";
723
812
  readonly chunk: Uint8Array<ArrayBufferLike>;
724
813
  } | {
@@ -770,6 +859,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
770
859
  };
771
860
  readonly matchOrElse: {
772
861
  <Cases extends {
862
+ "generation-queued"?: ((value: {
863
+ readonly id: string;
864
+ readonly type: "generation-queued";
865
+ readonly position?: number | undefined;
866
+ }) => any) | undefined;
867
+ "generation-progress"?: ((value: {
868
+ readonly id: string;
869
+ readonly type: "generation-progress";
870
+ readonly progress?: number | undefined;
871
+ }) => any) | undefined;
773
872
  "audio-delta"?: ((value: {
774
873
  readonly type: "audio-delta";
775
874
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -821,7 +920,19 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
821
920
  } | undefined;
822
921
  }[] | undefined;
823
922
  }) => any) | undefined;
824
- } & { [K in Exclude<keyof Cases, "finish" | "timestamps" | "audio-delta">]: never; }, OrElse extends (value: Exclude<{
923
+ } & { [K in Exclude<keyof Cases, "finish" | "generation-queued" | "generation-progress" | "timestamps" | "audio-delta">]: never; }, OrElse extends (value: Exclude<{
924
+ readonly id: string;
925
+ readonly type: "generation-queued";
926
+ readonly position?: number | undefined;
927
+ }, {
928
+ readonly type: keyof Cases;
929
+ }> | Exclude<{
930
+ readonly id: string;
931
+ readonly type: "generation-progress";
932
+ readonly progress?: number | undefined;
933
+ }, {
934
+ readonly type: keyof Cases;
935
+ }> | Exclude<{
825
936
  readonly type: "audio-delta";
826
937
  readonly chunk: Uint8Array<ArrayBufferLike>;
827
938
  }, {
@@ -876,6 +987,14 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
876
987
  }, {
877
988
  readonly type: keyof Cases;
878
989
  }>) => any>(value: {
990
+ readonly id: string;
991
+ readonly type: "generation-queued";
992
+ readonly position?: number | undefined;
993
+ } | {
994
+ readonly id: string;
995
+ readonly type: "generation-progress";
996
+ readonly progress?: number | undefined;
997
+ } | {
879
998
  readonly type: "audio-delta";
880
999
  readonly chunk: Uint8Array<ArrayBufferLike>;
881
1000
  } | {
@@ -925,6 +1044,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
925
1044
  }[] | undefined;
926
1045
  }, cases: Cases, orElse: OrElse): import("effect/Unify").Unify<{ [K_1 in keyof Cases]-?: NonNullable<Cases[K_1]> extends (...args: Array<any>) => infer R ? R : never; }[keyof Cases] | ReturnType<OrElse>>;
927
1046
  <Cases extends {
1047
+ "generation-queued"?: ((value: {
1048
+ readonly id: string;
1049
+ readonly type: "generation-queued";
1050
+ readonly position?: number | undefined;
1051
+ }) => any) | undefined;
1052
+ "generation-progress"?: ((value: {
1053
+ readonly id: string;
1054
+ readonly type: "generation-progress";
1055
+ readonly progress?: number | undefined;
1056
+ }) => any) | undefined;
928
1057
  "audio-delta"?: ((value: {
929
1058
  readonly type: "audio-delta";
930
1059
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -976,7 +1105,19 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
976
1105
  } | undefined;
977
1106
  }[] | undefined;
978
1107
  }) => any) | undefined;
979
- } & { [K in Exclude<keyof Cases, "finish" | "timestamps" | "audio-delta">]: never; }, OrElse extends (value: Exclude<{
1108
+ } & { [K in Exclude<keyof Cases, "finish" | "generation-queued" | "generation-progress" | "timestamps" | "audio-delta">]: never; }, OrElse extends (value: Exclude<{
1109
+ readonly id: string;
1110
+ readonly type: "generation-queued";
1111
+ readonly position?: number | undefined;
1112
+ }, {
1113
+ readonly type: keyof Cases;
1114
+ }> | Exclude<{
1115
+ readonly id: string;
1116
+ readonly type: "generation-progress";
1117
+ readonly progress?: number | undefined;
1118
+ }, {
1119
+ readonly type: keyof Cases;
1120
+ }> | Exclude<{
980
1121
  readonly type: "audio-delta";
981
1122
  readonly chunk: Uint8Array<ArrayBufferLike>;
982
1123
  }, {
@@ -1031,6 +1172,14 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
1031
1172
  }, {
1032
1173
  readonly type: keyof Cases;
1033
1174
  }>) => any>(cases: Cases, orElse: OrElse): (value: {
1175
+ readonly id: string;
1176
+ readonly type: "generation-queued";
1177
+ readonly position?: number | undefined;
1178
+ } | {
1179
+ readonly id: string;
1180
+ readonly type: "generation-progress";
1181
+ readonly progress?: number | undefined;
1182
+ } | {
1034
1183
  readonly type: "audio-delta";
1035
1184
  readonly chunk: Uint8Array<ArrayBufferLike>;
1036
1185
  } | {
@@ -1082,6 +1231,16 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
1082
1231
  };
1083
1232
  } & {
1084
1233
  is: {
1234
+ generationQueued: (u: unknown) => u is {
1235
+ readonly id: string;
1236
+ readonly type: "generation-queued";
1237
+ readonly position?: number | undefined;
1238
+ };
1239
+ generationProgress: (u: unknown) => u is {
1240
+ readonly id: string;
1241
+ readonly type: "generation-progress";
1242
+ readonly progress?: number | undefined;
1243
+ };
1085
1244
  audioDelta: (u: unknown) => u is {
1086
1245
  readonly type: "audio-delta";
1087
1246
  readonly chunk: Uint8Array<ArrayBufferLike>;
@@ -1138,10 +1297,8 @@ export declare const SpeechEvent: Schema.Union<readonly [Schema.Struct<{
1138
1297
  export type SpeechEvent = Schema.Schema.Type<typeof speechEventTagged>;
1139
1298
  export declare function request<const Model extends SpeechModel>(input: SpeechRequestInput<Model>): SpeechRequestFor<SpeechModelOptions<Model>>;
1140
1299
  export declare function request(input: SpeechRequest): SpeechRequest;
1141
- export declare function generate<const Model extends SpeechModel>(input: SpeechRequestInput<Model>): Effect.Effect<SpeechResponse, AIError, Service>;
1142
- export declare function generate(input: SpeechRequest): Effect.Effect<SpeechResponse, AIError, Service>;
1143
- export declare function stream<const Model extends SpeechModel>(input: SpeechRequestInput<Model>): Stream.Stream<SpeechEvent, AIError, Service>;
1144
- export declare function stream(input: SpeechRequest): Stream.Stream<SpeechEvent, AIError, Service>;
1300
+ export declare function generate<const Model extends SpeechModel>(input: SpeechRequest | SpeechRequestInput<Model>): Effect.Effect<SpeechResponse, AIError, Service>;
1301
+ export declare function stream<const Model extends SpeechModel>(input: SpeechRequest | SpeechRequestInput<Model>): Stream.Stream<SpeechEvent, AIError, Service>;
1145
1302
  export declare const Speech: {
1146
1303
  readonly request: typeof request;
1147
1304
  readonly generate: typeof generate;
package/dist/speech.js CHANGED
@@ -1,20 +1,17 @@
1
1
  import { Effect, Schema, Stream } from "effect";
2
+ import { ProgressEvent, QueuedEvent } from "./generation.js";
2
3
  import { Media } from "./media.js";
3
4
  import { MediaModel, composeRoute, tryRequest } from "./media-model.js";
4
5
  import { MediaRoute } from "./route/media.js";
5
6
  import { AIError, HttpOptions, MediaUsage, ProviderMetadata } from "./schema/index.js";
6
7
  import { SpeechClient, Service } from "./speech-client.js";
7
8
  export class SpeechModel extends MediaModel {
8
- static make(input) {
9
- return new SpeechModel(input);
10
- }
11
- /** Compose a streaming speech protocol with its canonical path into a model for one deployment. */
12
9
  static fromRoute(route, input) {
13
10
  return new SpeechModel({
14
11
  id: input.id,
15
12
  provider: route.protocol.provider,
16
13
  http: input.http,
17
- route: composeRoute((composition) => MediaRoute.stream({ ...composition, collect: collectResponse }), route, input),
14
+ route: composeRoute(route, input, collectResponse),
18
15
  });
19
16
  }
20
17
  }
@@ -75,9 +72,17 @@ export const SpeechFinishEvent = Schema.Struct({
75
72
  notices: Schema.optional(Schema.Array(Media.Notice)),
76
73
  providerMetadata: Schema.optional(ProviderMetadata),
77
74
  }).annotate({ identifier: "Speech.Event.Finish" });
78
- const speechEventTagged = Schema.Union([SpeechAudioDeltaEvent, SpeechTimestampsEvent, SpeechFinishEvent]).pipe(Schema.toTaggedUnion("type"));
75
+ const speechEventTagged = Schema.Union([
76
+ QueuedEvent,
77
+ ProgressEvent,
78
+ SpeechAudioDeltaEvent,
79
+ SpeechTimestampsEvent,
80
+ SpeechFinishEvent,
81
+ ]).pipe(Schema.toTaggedUnion("type"));
79
82
  export const SpeechEvent = Object.assign(speechEventTagged, {
80
83
  is: {
84
+ generationQueued: speechEventTagged.guards["generation-queued"],
85
+ generationProgress: speechEventTagged.guards["generation-progress"],
81
86
  audioDelta: speechEventTagged.guards["audio-delta"],
82
87
  timestamps: speechEventTagged.guards.timestamps,
83
88
  finish: speechEventTagged.guards.finish,