@opencode/ai 2.0.15 → 2.0.17
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/README.md +441 -99
- package/dist/ai-client.d.ts +8 -0
- package/dist/ai-client.js +12 -0
- package/dist/experimental/evaluation-client.d.ts +3 -3
- package/dist/experimental/evaluation-client.js +1 -1
- package/dist/experimental/evaluation.js +1 -1
- package/dist/generation.d.ts +39 -29
- package/dist/generation.js +62 -36
- package/dist/image-client.d.ts +59 -17
- package/dist/image-client.js +16 -24
- package/dist/image.d.ts +394 -55
- package/dist/image.js +48 -57
- package/dist/index.d.ts +15 -2
- package/dist/index.js +10 -0
- package/dist/llm.d.ts +7 -5
- package/dist/llm.js +10 -4
- package/dist/media-client.d.ts +30 -0
- package/dist/media-client.js +51 -0
- package/dist/media-model.d.ts +43 -0
- package/dist/media-model.js +47 -0
- package/dist/media.d.ts +10 -9
- package/dist/media.js +11 -12
- package/dist/promise.d.ts +473 -15
- package/dist/promise.js +71 -13
- package/dist/protocols/alibaba-chat.d.ts +12 -0
- package/dist/protocols/alibaba-chat.js +4 -1
- package/dist/protocols/alibaba-messages.d.ts +1 -1
- package/dist/protocols/alibaba-messages.js +6 -4
- package/dist/protocols/alibaba-responses.d.ts +2 -2
- package/dist/protocols/anthropic-messages.d.ts +34 -34
- package/dist/protocols/anthropic-messages.js +14 -9
- package/dist/protocols/assemblyai-transcription.d.ts +41 -0
- package/dist/protocols/assemblyai-transcription.js +136 -0
- package/dist/protocols/bedrock-converse.d.ts +7 -0
- package/dist/protocols/bedrock-converse.js +39 -19
- package/dist/protocols/bfl-images.d.ts +38 -0
- package/dist/protocols/bfl-images.js +153 -0
- package/dist/protocols/cartesia-speech.d.ts +143 -0
- package/dist/protocols/cartesia-speech.js +120 -0
- package/dist/protocols/deepgram-speech.d.ts +135 -0
- package/dist/protocols/deepgram-speech.js +91 -0
- package/dist/protocols/deepgram-transcription.d.ts +26 -0
- package/dist/protocols/deepgram-transcription.js +125 -0
- package/dist/protocols/elevenlabs-speech.d.ts +138 -0
- package/dist/protocols/elevenlabs-speech.js +111 -0
- package/dist/protocols/fal-images.d.ts +25 -0
- package/dist/protocols/fal-images.js +104 -0
- package/dist/protocols/fal-video.d.ts +29 -0
- package/dist/protocols/fal-video.js +73 -0
- package/dist/protocols/gemini.d.ts +22 -22
- package/dist/protocols/gemini.js +19 -36
- package/dist/protocols/google-images.d.ts +3 -3
- package/dist/protocols/google-images.js +12 -34
- package/dist/protocols/google-speech.d.ts +146 -0
- package/dist/protocols/google-speech.js +88 -0
- package/dist/protocols/google-transcription.d.ts +174 -0
- package/dist/protocols/google-transcription.js +126 -0
- package/dist/protocols/google-video.d.ts +26 -0
- package/dist/protocols/google-video.js +142 -0
- package/dist/protocols/meta-images.d.ts +3 -4
- package/dist/protocols/meta-images.js +13 -29
- package/dist/protocols/meta-messages.d.ts +5 -5
- package/dist/protocols/meta-responses.d.ts +4 -4
- package/dist/protocols/meta-responses.js +6 -4
- package/dist/protocols/open-responses.d.ts +10 -9
- package/dist/protocols/open-responses.js +4 -9
- package/dist/protocols/openai-chat.d.ts +84 -0
- package/dist/protocols/openai-chat.js +28 -17
- package/dist/protocols/openai-compatible-chat.d.ts +12 -0
- package/dist/protocols/openai-compatible-responses.d.ts +2 -2
- package/dist/protocols/openai-images.d.ts +130 -7
- package/dist/protocols/openai-images.js +143 -91
- package/dist/protocols/openai-responses.d.ts +20 -20
- package/dist/protocols/openai-responses.js +31 -31
- package/dist/protocols/openai-speech.d.ts +136 -0
- package/dist/protocols/openai-speech.js +97 -0
- package/dist/protocols/openai-transcription.d.ts +211 -0
- package/dist/protocols/openai-transcription.js +202 -0
- package/dist/protocols/replicate-images.d.ts +28 -0
- package/dist/protocols/replicate-images.js +127 -0
- package/dist/protocols/runway-video.d.ts +38 -0
- package/dist/protocols/runway-video.js +140 -0
- package/dist/protocols/shared.d.ts +21 -17
- package/dist/protocols/shared.js +27 -36
- package/dist/protocols/stability-images.d.ts +39 -0
- package/dist/protocols/stability-images.js +136 -0
- package/dist/protocols/utils/fal-queue.d.ts +26 -0
- package/dist/protocols/utils/fal-queue.js +67 -0
- package/dist/protocols/utils/gemini-generate-content.d.ts +65 -0
- package/dist/protocols/utils/gemini-generate-content.js +65 -0
- package/dist/protocols/utils/gemini-json-schema.d.ts +3 -0
- package/dist/protocols/utils/gemini-json-schema.js +76 -0
- package/dist/protocols/utils/media-input.d.ts +23 -1
- package/dist/protocols/utils/media-input.js +40 -0
- package/dist/protocols/utils/responses-checkpoint.js +3 -7
- package/dist/protocols/utils/responses-compaction.d.ts +3 -1
- package/dist/protocols/utils/responses-compaction.js +16 -3
- package/dist/protocols/utils/speech-stream.d.ts +49 -0
- package/dist/protocols/utils/speech-stream.js +64 -0
- package/dist/protocols/utils/tool-schema.d.ts +2 -2
- package/dist/protocols/utils/tool-schema.js +62 -19
- package/dist/protocols/xai-images.d.ts +4 -4
- package/dist/protocols/xai-images.js +14 -40
- package/dist/protocols/xai-responses.d.ts +2 -2
- package/dist/protocols/xai-responses.js +1 -1
- package/dist/protocols/xai-video.d.ts +34 -0
- package/dist/protocols/xai-video.js +141 -0
- package/dist/protocols/zai-chat.d.ts +13 -1
- package/dist/protocols/zai-images.d.ts +2 -2
- package/dist/protocols/zai-images.js +11 -14
- package/dist/protocols/zai-messages.d.ts +1 -1
- package/dist/provider-error.js +10 -1
- package/dist/providers/alibaba.d.ts +15 -3
- package/dist/providers/amazon-bedrock-mantle.d.ts +14 -2
- package/dist/providers/amazon-bedrock.d.ts +2 -0
- package/dist/providers/amazon-bedrock.js +1 -0
- package/dist/providers/anthropic-compatible.d.ts +5 -5
- package/dist/providers/anthropic.d.ts +5 -5
- package/dist/providers/assemblyai.d.ts +25 -0
- package/dist/providers/assemblyai.js +24 -0
- package/dist/providers/azure.d.ts +20 -8
- package/dist/providers/azure.js +2 -2
- package/dist/providers/baseten.d.ts +24 -0
- package/dist/providers/black-forest-labs.d.ts +25 -0
- package/dist/providers/black-forest-labs.js +23 -0
- package/dist/providers/cartesia.d.ts +24 -0
- package/dist/providers/cartesia.js +17 -0
- package/dist/providers/cerebras.d.ts +24 -0
- package/dist/providers/cloudflare-ai-gateway.d.ts +42 -18
- package/dist/providers/cloudflare-workers-ai.d.ts +24 -0
- package/dist/providers/deepgram.d.ts +29 -0
- package/dist/providers/deepgram.js +25 -0
- package/dist/providers/deepinfra.d.ts +24 -0
- package/dist/providers/deepseek.d.ts +24 -0
- package/dist/providers/elevenlabs.d.ts +24 -0
- package/dist/providers/elevenlabs.js +23 -0
- package/dist/providers/fal.d.ts +29 -0
- package/dist/providers/fal.js +26 -0
- package/dist/providers/fireworks.d.ts +24 -0
- package/dist/providers/google-vertex-chat.d.ts +12 -0
- package/dist/providers/google-vertex-messages.d.ts +5 -5
- package/dist/providers/google-vertex-responses.d.ts +2 -2
- package/dist/providers/google-vertex.d.ts +6 -6
- package/dist/providers/google.d.ts +21 -6
- package/dist/providers/google.js +13 -9
- package/dist/providers/groq.d.ts +24 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +9 -0
- package/dist/providers/meta.d.ts +22 -10
- package/dist/providers/meta.js +4 -8
- package/dist/providers/minimax.d.ts +19 -7
- package/dist/providers/moonshot.d.ts +19 -7
- package/dist/providers/moonshot.js +3 -3
- package/dist/providers/openai-compatible-responses.d.ts +2 -2
- package/dist/providers/openai-compatible.d.ts +12 -0
- package/dist/providers/openai-options.d.ts +3 -9
- package/dist/providers/openai-options.js +4 -7
- package/dist/providers/openai.d.ts +33 -12
- package/dist/providers/openai.js +17 -9
- package/dist/providers/opencode-zen.js +1 -1
- package/dist/providers/openrouter.d.ts +54 -7
- package/dist/providers/openrouter.js +10 -5
- package/dist/providers/replicate.d.ts +25 -0
- package/dist/providers/replicate.js +17 -0
- package/dist/providers/runway.d.ts +24 -0
- package/dist/providers/runway.js +17 -0
- package/dist/providers/stability.d.ts +28 -0
- package/dist/providers/stability.js +18 -0
- package/dist/providers/togetherai.d.ts +24 -0
- package/dist/providers/typesafe-ai.js +1 -1
- package/dist/providers/vercel-ai-gateway.js +1 -1
- package/dist/providers/xai.d.ts +17 -0
- package/dist/providers/xai.js +7 -9
- package/dist/providers/zai-coding-plan.d.ts +16 -4
- package/dist/providers/zai.d.ts +13 -1
- package/dist/providers/zai.js +4 -8
- package/dist/route/auth.d.ts +5 -2
- package/dist/route/auth.js +20 -13
- package/dist/route/client.d.ts +9 -7
- package/dist/route/client.js +6 -8
- package/dist/route/endpoint.d.ts +1 -0
- package/dist/route/endpoint.js +2 -2
- package/dist/route/executor-service.d.ts +4 -2
- package/dist/route/executor-service.js +2 -1
- package/dist/route/executor.d.ts +3 -1
- package/dist/route/executor.js +7 -0
- package/dist/route/framing.d.ts +15 -2
- package/dist/route/framing.js +53 -4
- package/dist/route/index.d.ts +1 -1
- package/dist/route/media-protocol.d.ts +145 -18
- package/dist/route/media-protocol.js +96 -28
- package/dist/route/media.d.ts +54 -9
- package/dist/route/media.js +194 -38
- package/dist/route/protocol.d.ts +3 -1
- package/dist/schema/events.d.ts +0 -6
- package/dist/schema/messages.d.ts +0 -3
- package/dist/schema/options.d.ts +10 -6
- package/dist/schema/options.js +10 -5
- package/dist/speech-client.d.ts +66 -0
- package/dist/speech-client.js +21 -0
- package/dist/speech.d.ts +1307 -0
- package/dist/speech.js +124 -0
- package/dist/testing.d.ts +2 -2
- package/dist/transcription-client.d.ts +82 -0
- package/dist/transcription-client.js +13 -0
- package/dist/transcription.d.ts +1492 -0
- package/dist/transcription.js +127 -0
- package/dist/utils/bytes.d.ts +1 -0
- package/dist/utils/bytes.js +10 -0
- package/dist/utils/json.d.ts +4 -0
- package/dist/utils/json.js +4 -0
- package/dist/utils/media-type.d.ts +3 -1
- package/dist/utils/media-type.js +25 -2
- package/dist/video-client.d.ts +59 -0
- package/dist/video-client.js +20 -0
- package/dist/video.d.ts +1351 -0
- package/dist/video.js +118 -0
- package/package.json +3 -3
- package/dist/protocols/utils/gemini-tool-schema.d.ts +0 -2
- package/dist/protocols/utils/gemini-tool-schema.js +0 -103
- package/dist/protocols/utils/meta-image.d.ts +0 -2
- package/dist/protocols/utils/meta-image.js +0 -13
- package/dist/protocols/utils/openai-image.d.ts +0 -5
- package/dist/protocols/utils/openai-image.js +0 -18
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
3
|
+
import { MediaRoute } from "../route/media.js";
|
|
4
|
+
import { TranscriptionModel, type TranscriptionRequestFor, type TranscriptionSegment } from "../transcription.js";
|
|
5
|
+
export declare const DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
6
|
+
export declare const PATH = "/audio/transcriptions";
|
|
7
|
+
export type OpenAITranscriptionOptions = {
|
|
8
|
+
readonly chunking_strategy?: "auto" | {
|
|
9
|
+
readonly type: "server_vad";
|
|
10
|
+
readonly prefix_padding_ms?: number;
|
|
11
|
+
readonly silence_duration_ms?: number;
|
|
12
|
+
readonly threshold?: number;
|
|
13
|
+
};
|
|
14
|
+
readonly include?: ReadonlyArray<"logprobs">;
|
|
15
|
+
readonly keywords?: ReadonlyArray<string>;
|
|
16
|
+
readonly known_speaker_names?: ReadonlyArray<string>;
|
|
17
|
+
readonly known_speaker_references?: ReadonlyArray<string>;
|
|
18
|
+
readonly temperature?: number;
|
|
19
|
+
} & Record<string, unknown>;
|
|
20
|
+
export type Request = TranscriptionRequestFor<OpenAITranscriptionOptions>;
|
|
21
|
+
declare const Transcript: Schema.Struct<{
|
|
22
|
+
text: Schema.String;
|
|
23
|
+
language: Schema.optional<Schema.String>;
|
|
24
|
+
languages: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
25
|
+
readonly code: Schema.String;
|
|
26
|
+
}>>>;
|
|
27
|
+
duration: Schema.optional<Schema.Number>;
|
|
28
|
+
segments: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
29
|
+
readonly text: Schema.String;
|
|
30
|
+
readonly start: Schema.Number;
|
|
31
|
+
readonly end: Schema.Number;
|
|
32
|
+
readonly speaker: Schema.optional<Schema.String>;
|
|
33
|
+
}>>>;
|
|
34
|
+
words: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
35
|
+
readonly word: Schema.String;
|
|
36
|
+
readonly start: Schema.Number;
|
|
37
|
+
readonly end: Schema.Number;
|
|
38
|
+
}>>>;
|
|
39
|
+
usage: Schema.optional<Schema.Union<readonly [Schema.Struct<{
|
|
40
|
+
readonly type: Schema.Literal<"tokens">;
|
|
41
|
+
readonly input_tokens: Schema.optional<Schema.Number>;
|
|
42
|
+
readonly output_tokens: Schema.optional<Schema.Number>;
|
|
43
|
+
readonly total_tokens: Schema.optional<Schema.Number>;
|
|
44
|
+
readonly input_token_details: Schema.optional<Schema.Struct<{
|
|
45
|
+
readonly audio_tokens: Schema.optional<Schema.Number>;
|
|
46
|
+
readonly text_tokens: Schema.optional<Schema.Number>;
|
|
47
|
+
}>>;
|
|
48
|
+
}>, Schema.Struct<{
|
|
49
|
+
readonly type: Schema.Literal<"duration">;
|
|
50
|
+
readonly seconds: Schema.Number;
|
|
51
|
+
}>]>>;
|
|
52
|
+
}>;
|
|
53
|
+
type Transcript = Schema.Schema.Type<typeof Transcript>;
|
|
54
|
+
type Frame = string | {
|
|
55
|
+
readonly document: string;
|
|
56
|
+
};
|
|
57
|
+
interface State {
|
|
58
|
+
readonly segments: Array<TranscriptionSegment>;
|
|
59
|
+
readonly transcript?: Transcript;
|
|
60
|
+
}
|
|
61
|
+
export declare const protocol: MediaProtocol.Streamed<Request, {
|
|
62
|
+
readonly id: string;
|
|
63
|
+
readonly type: "generation-queued";
|
|
64
|
+
readonly position?: number | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
readonly id: string;
|
|
67
|
+
readonly type: "generation-progress";
|
|
68
|
+
readonly progress?: number | undefined;
|
|
69
|
+
} | {
|
|
70
|
+
readonly type: "text-delta";
|
|
71
|
+
readonly delta: string;
|
|
72
|
+
} | {
|
|
73
|
+
readonly type: "segment";
|
|
74
|
+
readonly segment: {
|
|
75
|
+
readonly text: string;
|
|
76
|
+
readonly startSeconds: number;
|
|
77
|
+
readonly endSeconds: number;
|
|
78
|
+
readonly speaker?: string | undefined;
|
|
79
|
+
};
|
|
80
|
+
} | {
|
|
81
|
+
readonly type: "finish";
|
|
82
|
+
readonly text: string;
|
|
83
|
+
readonly durationSeconds?: number | undefined;
|
|
84
|
+
readonly providerMetadata?: {
|
|
85
|
+
readonly [x: string]: {
|
|
86
|
+
readonly [x: string]: unknown;
|
|
87
|
+
};
|
|
88
|
+
} | undefined;
|
|
89
|
+
readonly usage?: {
|
|
90
|
+
readonly type: "tokens";
|
|
91
|
+
readonly input?: number | undefined;
|
|
92
|
+
readonly output?: number | undefined;
|
|
93
|
+
readonly total?: number | undefined;
|
|
94
|
+
readonly details?: {
|
|
95
|
+
readonly [x: string]: unknown;
|
|
96
|
+
} | undefined;
|
|
97
|
+
} | {
|
|
98
|
+
readonly type: "seconds";
|
|
99
|
+
readonly seconds: number;
|
|
100
|
+
} | {
|
|
101
|
+
readonly type: "characters";
|
|
102
|
+
readonly characters: number;
|
|
103
|
+
} | {
|
|
104
|
+
readonly type: "credits";
|
|
105
|
+
readonly credits: number;
|
|
106
|
+
} | {
|
|
107
|
+
readonly type: "compute";
|
|
108
|
+
readonly seconds: number;
|
|
109
|
+
} | undefined;
|
|
110
|
+
readonly notices?: readonly {
|
|
111
|
+
readonly type: "other" | "moderated" | "filtered";
|
|
112
|
+
readonly message: string;
|
|
113
|
+
readonly providerMetadata?: {
|
|
114
|
+
readonly [x: string]: {
|
|
115
|
+
readonly [x: string]: unknown;
|
|
116
|
+
};
|
|
117
|
+
} | undefined;
|
|
118
|
+
}[] | undefined;
|
|
119
|
+
readonly language?: string | undefined;
|
|
120
|
+
readonly segments?: readonly {
|
|
121
|
+
readonly text: string;
|
|
122
|
+
readonly startSeconds: number;
|
|
123
|
+
readonly endSeconds: number;
|
|
124
|
+
readonly speaker?: string | undefined;
|
|
125
|
+
}[] | undefined;
|
|
126
|
+
readonly words?: readonly {
|
|
127
|
+
readonly text: string;
|
|
128
|
+
readonly startSeconds: number;
|
|
129
|
+
readonly endSeconds: number;
|
|
130
|
+
readonly speaker?: string | undefined;
|
|
131
|
+
readonly confidence?: number | undefined;
|
|
132
|
+
}[] | undefined;
|
|
133
|
+
}, Frame, State>;
|
|
134
|
+
export declare const model: (input: MediaRoute.ModelInput) => TranscriptionModel<OpenAITranscriptionOptions>;
|
|
135
|
+
export declare const OpenAITranscription: {
|
|
136
|
+
readonly protocol: MediaProtocol.Streamed<Request, {
|
|
137
|
+
readonly id: string;
|
|
138
|
+
readonly type: "generation-queued";
|
|
139
|
+
readonly position?: number | undefined;
|
|
140
|
+
} | {
|
|
141
|
+
readonly id: string;
|
|
142
|
+
readonly type: "generation-progress";
|
|
143
|
+
readonly progress?: number | undefined;
|
|
144
|
+
} | {
|
|
145
|
+
readonly type: "text-delta";
|
|
146
|
+
readonly delta: string;
|
|
147
|
+
} | {
|
|
148
|
+
readonly type: "segment";
|
|
149
|
+
readonly segment: {
|
|
150
|
+
readonly text: string;
|
|
151
|
+
readonly startSeconds: number;
|
|
152
|
+
readonly endSeconds: number;
|
|
153
|
+
readonly speaker?: string | undefined;
|
|
154
|
+
};
|
|
155
|
+
} | {
|
|
156
|
+
readonly type: "finish";
|
|
157
|
+
readonly text: string;
|
|
158
|
+
readonly durationSeconds?: number | undefined;
|
|
159
|
+
readonly providerMetadata?: {
|
|
160
|
+
readonly [x: string]: {
|
|
161
|
+
readonly [x: string]: unknown;
|
|
162
|
+
};
|
|
163
|
+
} | undefined;
|
|
164
|
+
readonly usage?: {
|
|
165
|
+
readonly type: "tokens";
|
|
166
|
+
readonly input?: number | undefined;
|
|
167
|
+
readonly output?: number | undefined;
|
|
168
|
+
readonly total?: number | undefined;
|
|
169
|
+
readonly details?: {
|
|
170
|
+
readonly [x: string]: unknown;
|
|
171
|
+
} | undefined;
|
|
172
|
+
} | {
|
|
173
|
+
readonly type: "seconds";
|
|
174
|
+
readonly seconds: number;
|
|
175
|
+
} | {
|
|
176
|
+
readonly type: "characters";
|
|
177
|
+
readonly characters: number;
|
|
178
|
+
} | {
|
|
179
|
+
readonly type: "credits";
|
|
180
|
+
readonly credits: number;
|
|
181
|
+
} | {
|
|
182
|
+
readonly type: "compute";
|
|
183
|
+
readonly seconds: number;
|
|
184
|
+
} | undefined;
|
|
185
|
+
readonly notices?: readonly {
|
|
186
|
+
readonly type: "other" | "moderated" | "filtered";
|
|
187
|
+
readonly message: string;
|
|
188
|
+
readonly providerMetadata?: {
|
|
189
|
+
readonly [x: string]: {
|
|
190
|
+
readonly [x: string]: unknown;
|
|
191
|
+
};
|
|
192
|
+
} | undefined;
|
|
193
|
+
}[] | undefined;
|
|
194
|
+
readonly language?: string | undefined;
|
|
195
|
+
readonly segments?: readonly {
|
|
196
|
+
readonly text: string;
|
|
197
|
+
readonly startSeconds: number;
|
|
198
|
+
readonly endSeconds: number;
|
|
199
|
+
readonly speaker?: string | undefined;
|
|
200
|
+
}[] | undefined;
|
|
201
|
+
readonly words?: readonly {
|
|
202
|
+
readonly text: string;
|
|
203
|
+
readonly startSeconds: number;
|
|
204
|
+
readonly endSeconds: number;
|
|
205
|
+
readonly speaker?: string | undefined;
|
|
206
|
+
readonly confidence?: number | undefined;
|
|
207
|
+
}[] | undefined;
|
|
208
|
+
}, Frame, State>;
|
|
209
|
+
readonly model: (input: MediaRoute.ModelInput) => TranscriptionModel<OpenAITranscriptionOptions>;
|
|
210
|
+
};
|
|
211
|
+
export {};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Effect, Schema, Stream } from "effect";
|
|
2
|
+
import { classifyProviderFailure } from "../provider-error.js";
|
|
3
|
+
import { Framing } from "../route/framing.js";
|
|
4
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
5
|
+
import { MediaRoute } from "../route/media.js";
|
|
6
|
+
import { AIError, mergeJsonRecords } from "../schema/index.js";
|
|
7
|
+
import { TranscriptionFinishEvent, TranscriptionModel, TranscriptionSegmentEvent, TranscriptionTextDeltaEvent, } from "../transcription.js";
|
|
8
|
+
import { mediaTypeExtension } from "../utils/media-type.js";
|
|
9
|
+
import { ProviderShared } from "./shared.js";
|
|
10
|
+
import { MediaInput } from "./utils/media-input.js";
|
|
11
|
+
const route = MediaProtocol.identity({ id: "openai-transcription", name: "OpenAI Transcription", provider: "openai" });
|
|
12
|
+
export const DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
13
|
+
export const PATH = "/audio/transcriptions";
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// 3. Streaming event schema
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const Segment = Schema.Struct({
|
|
18
|
+
text: Schema.String,
|
|
19
|
+
start: Schema.Number,
|
|
20
|
+
end: Schema.Number,
|
|
21
|
+
speaker: Schema.optional(Schema.String),
|
|
22
|
+
});
|
|
23
|
+
const Usage = Schema.Union([
|
|
24
|
+
Schema.Struct({
|
|
25
|
+
type: Schema.Literal("tokens"),
|
|
26
|
+
input_tokens: Schema.optional(Schema.Number),
|
|
27
|
+
output_tokens: Schema.optional(Schema.Number),
|
|
28
|
+
total_tokens: Schema.optional(Schema.Number),
|
|
29
|
+
input_token_details: Schema.optional(Schema.Struct({ audio_tokens: Schema.optional(Schema.Number), text_tokens: Schema.optional(Schema.Number) })),
|
|
30
|
+
}),
|
|
31
|
+
Schema.Struct({ type: Schema.Literal("duration"), seconds: Schema.Number }),
|
|
32
|
+
]);
|
|
33
|
+
const transcriptFields = {
|
|
34
|
+
text: Schema.String,
|
|
35
|
+
language: Schema.optional(Schema.String),
|
|
36
|
+
languages: Schema.optional(Schema.Array(Schema.Struct({ code: Schema.String }))),
|
|
37
|
+
duration: Schema.optional(Schema.Number),
|
|
38
|
+
segments: Schema.optional(Schema.Array(Segment)),
|
|
39
|
+
words: Schema.optional(Schema.Array(Schema.Struct({ word: Schema.String, start: Schema.Number, end: Schema.Number }))),
|
|
40
|
+
usage: Schema.optional(Usage),
|
|
41
|
+
};
|
|
42
|
+
/** OpenAI may add stream event types; frames outside `EVENT_TYPES` are ignored. */
|
|
43
|
+
const EventType = Schema.Struct({ type: Schema.String });
|
|
44
|
+
const Event = Schema.Union([
|
|
45
|
+
Schema.Struct({ type: Schema.Literal("transcript.text.delta"), delta: Schema.String }),
|
|
46
|
+
Schema.Struct({ type: Schema.Literal("transcript.text.segment"), ...Segment.fields }),
|
|
47
|
+
Schema.Struct({ type: Schema.Literal("transcript.text.done"), ...transcriptFields }),
|
|
48
|
+
Schema.Struct({
|
|
49
|
+
type: Schema.Literal("error"),
|
|
50
|
+
message: Schema.optional(Schema.String),
|
|
51
|
+
error: Schema.optional(Schema.Struct({ message: Schema.optional(Schema.String) })),
|
|
52
|
+
}),
|
|
53
|
+
]);
|
|
54
|
+
const EVENT_TYPES = new Set(["transcript.text.delta", "transcript.text.segment", "transcript.text.done", "error"]);
|
|
55
|
+
const Transcript = Schema.Struct(transcriptFields);
|
|
56
|
+
const decodeEventType = route.decodeFrame(EventType);
|
|
57
|
+
const decodeEvent = route.decodeFrame(Event);
|
|
58
|
+
const decodeTranscript = route.decodeFrame(Transcript);
|
|
59
|
+
const TRANSCRIBE = { stream: true, timestamps: [], diarize: false, languageField: "language" };
|
|
60
|
+
const capabilities = (model) => {
|
|
61
|
+
if (model.startsWith("whisper"))
|
|
62
|
+
return { ...TRANSCRIBE, stream: false, timestamps: ["segment", "word"] };
|
|
63
|
+
if (model.includes("diarize"))
|
|
64
|
+
return { ...TRANSCRIBE, timestamps: ["segment"], diarize: true };
|
|
65
|
+
// `gpt-transcribe` replaces `language` with `languages[]` and rejects both together.
|
|
66
|
+
if (model.startsWith("gpt-transcribe"))
|
|
67
|
+
return { ...TRANSCRIBE, languageField: "languages" };
|
|
68
|
+
return TRANSCRIBE;
|
|
69
|
+
};
|
|
70
|
+
/** whisper-1 ignores `stream`, so its `stream` mode sends a plain request and emits only `finish`. */
|
|
71
|
+
const streamsEvents = (request) => request.mode === "stream" && capabilities(request.model.id).stream;
|
|
72
|
+
const validate = (request, model) => {
|
|
73
|
+
const id = request.model.id;
|
|
74
|
+
if (request.diarize === true && !model.diarize)
|
|
75
|
+
return Effect.fail(route.unsupported("media.diarize", `${id} does not diarize; use gpt-4o-transcribe-diarize`));
|
|
76
|
+
if (request.prompt !== undefined && model.diarize)
|
|
77
|
+
return Effect.fail(route.unsupported("media.prompt", `${id} does not accept a prompt`));
|
|
78
|
+
if (request.timestamps === undefined ||
|
|
79
|
+
request.timestamps === "none" ||
|
|
80
|
+
model.timestamps.includes(request.timestamps))
|
|
81
|
+
return Effect.void;
|
|
82
|
+
return Effect.fail(route.unsupported("media.timestamps", `${id} does not return ${request.timestamps} timestamps`));
|
|
83
|
+
};
|
|
84
|
+
const RESERVED_FORM_FIELDS = new Set([
|
|
85
|
+
"file",
|
|
86
|
+
"model",
|
|
87
|
+
"prompt",
|
|
88
|
+
"language",
|
|
89
|
+
"response_format",
|
|
90
|
+
"timestamp_granularities",
|
|
91
|
+
"stream",
|
|
92
|
+
]);
|
|
93
|
+
const fromRequest = Effect.fn("OpenAITranscription.fromRequest")(function* (request) {
|
|
94
|
+
const model = capabilities(request.model.id);
|
|
95
|
+
yield* validate(request, model);
|
|
96
|
+
// The API detects the audio format from the upload's filename extension.
|
|
97
|
+
const extension = mediaTypeExtension(request.audio.mediaType);
|
|
98
|
+
if (extension === undefined)
|
|
99
|
+
return yield* ProviderShared.invalidRequest(`${route.name} cannot name a ${request.audio.mediaType} upload; send mp3, mp4, m4a, wav, webm, ogg, or flac audio`);
|
|
100
|
+
const audio = yield* MediaInput.inlineBytes(route.id, request.audio);
|
|
101
|
+
const responseFormat = model.diarize
|
|
102
|
+
? "diarized_json"
|
|
103
|
+
: request.timestamps === undefined || request.timestamps === "none"
|
|
104
|
+
? undefined
|
|
105
|
+
: "verbose_json";
|
|
106
|
+
const form = new FormData();
|
|
107
|
+
form.append("file", MediaInput.blob(audio, request.audio.mediaType), `audio.${extension}`);
|
|
108
|
+
MediaInput.appendFields(form, {
|
|
109
|
+
model: request.model.id,
|
|
110
|
+
language: model.languageField === "language" ? request.language : undefined,
|
|
111
|
+
languages: model.languageField === "languages" && request.language !== undefined ? [request.language] : undefined,
|
|
112
|
+
prompt: request.prompt,
|
|
113
|
+
response_format: responseFormat,
|
|
114
|
+
timestamp_granularities: responseFormat === "verbose_json" ? [request.timestamps] : undefined,
|
|
115
|
+
// Diarizing audio longer than 30 seconds requires a chunking strategy.
|
|
116
|
+
chunking_strategy: model.diarize ? "auto" : undefined,
|
|
117
|
+
stream: streamsEvents(request) ? true : undefined,
|
|
118
|
+
}, {
|
|
119
|
+
overlay: mergeJsonRecords(request.providerOptions, request.http?.body),
|
|
120
|
+
reserved: RESERVED_FORM_FIELDS,
|
|
121
|
+
repeatArrays: true,
|
|
122
|
+
});
|
|
123
|
+
return MediaProtocol.multipart(form);
|
|
124
|
+
});
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// 6. Stream parsing
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
const segment = (value) => ({
|
|
129
|
+
text: value.text.trim(),
|
|
130
|
+
startSeconds: value.start,
|
|
131
|
+
endSeconds: value.end,
|
|
132
|
+
speaker: value.speaker,
|
|
133
|
+
});
|
|
134
|
+
const onEvent = Effect.fn("OpenAITranscription.onEvent")(function* (state, frame) {
|
|
135
|
+
if (!EVENT_TYPES.has((yield* decodeEventType(frame)).type))
|
|
136
|
+
return [state, []];
|
|
137
|
+
const event = yield* decodeEvent(frame);
|
|
138
|
+
if (event.type === "error")
|
|
139
|
+
return yield* new AIError({
|
|
140
|
+
reason: classifyProviderFailure({
|
|
141
|
+
message: `${route.name} stream failed: ${event.message ?? event.error?.message ?? "unknown error"}`,
|
|
142
|
+
rawBody: frame,
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
if (event.type === "transcript.text.done")
|
|
146
|
+
return [{ ...state, transcript: event }, []];
|
|
147
|
+
if (event.type === "transcript.text.delta")
|
|
148
|
+
return [state, event.delta.length === 0 ? [] : [TranscriptionTextDeltaEvent.make({ delta: event.delta })]];
|
|
149
|
+
const next = segment(event);
|
|
150
|
+
state.segments.push(next);
|
|
151
|
+
return [state, [TranscriptionSegmentEvent.make({ segment: next })]];
|
|
152
|
+
});
|
|
153
|
+
const step = (state, frame) => typeof frame === "string"
|
|
154
|
+
? onEvent(state, frame)
|
|
155
|
+
: decodeTranscript(frame.document).pipe(Effect.map((transcript) => [{ ...state, transcript }, []]));
|
|
156
|
+
const usage = (value) => {
|
|
157
|
+
if (value === undefined)
|
|
158
|
+
return undefined;
|
|
159
|
+
if (value.type === "duration")
|
|
160
|
+
return { type: "seconds", seconds: value.seconds };
|
|
161
|
+
return {
|
|
162
|
+
type: "tokens",
|
|
163
|
+
input: value.input_tokens,
|
|
164
|
+
output: value.output_tokens,
|
|
165
|
+
total: value.total_tokens,
|
|
166
|
+
details: { openai: value },
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
const finish = (state) => {
|
|
170
|
+
const transcript = state.transcript;
|
|
171
|
+
if (transcript === undefined)
|
|
172
|
+
return Effect.fail(route.incomplete());
|
|
173
|
+
const segments = transcript.segments?.map(segment) ?? state.segments;
|
|
174
|
+
return Effect.succeed([
|
|
175
|
+
TranscriptionFinishEvent.make({
|
|
176
|
+
text: transcript.text,
|
|
177
|
+
segments: segments.length === 0 ? undefined : segments,
|
|
178
|
+
words: transcript.words?.map((word) => ({ text: word.word, startSeconds: word.start, endSeconds: word.end })),
|
|
179
|
+
language: (transcript.language ?? transcript.languages?.[0]?.code)?.toLowerCase(),
|
|
180
|
+
durationSeconds: transcript.duration,
|
|
181
|
+
usage: usage(transcript.usage),
|
|
182
|
+
}),
|
|
183
|
+
]);
|
|
184
|
+
};
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// 7. Protocol and route
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
export const protocol = MediaProtocol.stream(route, {
|
|
189
|
+
unsupported: ["speakers"],
|
|
190
|
+
body: { from: fromRequest },
|
|
191
|
+
frames: (bytes, context) => streamsEvents(context.request)
|
|
192
|
+
? Framing.sse.frame(bytes)
|
|
193
|
+
: Framing.document.frame(bytes).pipe(Stream.map((document) => ({ document }))),
|
|
194
|
+
initial: () => ({ segments: [] }),
|
|
195
|
+
step,
|
|
196
|
+
finish,
|
|
197
|
+
});
|
|
198
|
+
export const model = (input) => TranscriptionModel.fromRoute({ protocol, baseURL: DEFAULT_BASE_URL, path: PATH }, input);
|
|
199
|
+
export const OpenAITranscription = {
|
|
200
|
+
protocol,
|
|
201
|
+
model,
|
|
202
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js";
|
|
3
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
4
|
+
import { MediaRoute } from "../route/media.js";
|
|
5
|
+
export declare const DEFAULT_BASE_URL = "https://api.replicate.com";
|
|
6
|
+
/** Model-defined `input` fields under the model's own names; `Media.Asset` values lower to URLs or data URLs. */
|
|
7
|
+
export type ReplicateImageOptions = Record<string, unknown>;
|
|
8
|
+
export type Request = ImageRequestFor<ReplicateImageOptions>;
|
|
9
|
+
export declare const Token: Schema.Struct<{
|
|
10
|
+
readonly id: Schema.String;
|
|
11
|
+
readonly getURL: Schema.String;
|
|
12
|
+
readonly cancelURL: Schema.String;
|
|
13
|
+
}>;
|
|
14
|
+
export type Token = Schema.Schema.Type<typeof Token>;
|
|
15
|
+
export declare const protocol: MediaProtocol.Queued<Request, ImageResponse, {
|
|
16
|
+
readonly id: string;
|
|
17
|
+
readonly getURL: string;
|
|
18
|
+
readonly cancelURL: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const model: (input: MediaRoute.ModelInput) => ImageModel<ReplicateImageOptions>;
|
|
21
|
+
export declare const ReplicateImages: {
|
|
22
|
+
readonly protocol: MediaProtocol.Queued<Request, ImageResponse, {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly getURL: string;
|
|
25
|
+
readonly cancelURL: string;
|
|
26
|
+
}>;
|
|
27
|
+
readonly model: (input: MediaRoute.ModelInput) => ImageModel<ReplicateImageOptions>;
|
|
28
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Duration, Effect, Schema } from "effect";
|
|
2
|
+
import { ImageModel, ImageResponse } from "../image.js";
|
|
3
|
+
import { Media } from "../media.js";
|
|
4
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
5
|
+
import { MediaRoute } from "../route/media.js";
|
|
6
|
+
import { mergeJsonRecords } from "../schema/index.js";
|
|
7
|
+
import { ProviderShared, optionalNull } from "./shared.js";
|
|
8
|
+
const route = MediaProtocol.identity({ id: "replicate-images", name: "Replicate", provider: "replicate" });
|
|
9
|
+
export const DEFAULT_BASE_URL = "https://api.replicate.com";
|
|
10
|
+
const OUTPUT_RETENTION = Duration.hours(1);
|
|
11
|
+
const MAX_DATA_URL_BYTES = 256 * 1024;
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// 2. Token and response schemas
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
export const Token = Schema.Struct({ id: Schema.String, getURL: Schema.String, cancelURL: Schema.String });
|
|
16
|
+
const Prediction = Schema.Struct({
|
|
17
|
+
id: Schema.String,
|
|
18
|
+
status: Schema.String,
|
|
19
|
+
output: optionalNull(Schema.Unknown),
|
|
20
|
+
error: optionalNull(Schema.Unknown),
|
|
21
|
+
data_removed: optionalNull(Schema.Boolean),
|
|
22
|
+
completed_at: optionalNull(Schema.String),
|
|
23
|
+
metrics: optionalNull(Schema.Struct({ predict_time: optionalNull(Schema.Number) })),
|
|
24
|
+
urls: Schema.Struct({ get: Schema.String, cancel: Schema.String }),
|
|
25
|
+
});
|
|
26
|
+
const Output = Schema.Union([Schema.String, Schema.Array(Schema.String)]);
|
|
27
|
+
const isOutput = Schema.is(Output);
|
|
28
|
+
const STATUS = {
|
|
29
|
+
starting: "queued",
|
|
30
|
+
processing: "running",
|
|
31
|
+
succeeded: "completed",
|
|
32
|
+
failed: "failed",
|
|
33
|
+
canceled: "cancelled",
|
|
34
|
+
// The prediction hit its `Cancel-After` deadline before it started running.
|
|
35
|
+
aborted: "expired",
|
|
36
|
+
};
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// 5. Request body construction
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Official models run by `owner/name`; anything else (`owner/name:version` or a bare version id) is a pinned version.
|
|
41
|
+
const isOfficial = (model) => /^[^/:]+\/[^/:]+$/.test(model);
|
|
42
|
+
const inlineSize = (source) => {
|
|
43
|
+
if (source.type === "bytes")
|
|
44
|
+
return source.data.byteLength;
|
|
45
|
+
if (source.type === "base64")
|
|
46
|
+
return source.data.length * 0.75;
|
|
47
|
+
return 0;
|
|
48
|
+
};
|
|
49
|
+
const fileInput = (asset) => {
|
|
50
|
+
if (inlineSize(asset.source) > MAX_DATA_URL_BYTES)
|
|
51
|
+
return Effect.fail(ProviderShared.invalidRequest(`${route.name} data URL inputs are limited to 256 KB; pass a larger file by https URL`));
|
|
52
|
+
return ProviderShared.mediaReference(asset, undefined, route.name).pipe(Effect.map((reference) => reference.value));
|
|
53
|
+
};
|
|
54
|
+
const inputValue = (value) => {
|
|
55
|
+
if (value instanceof Media.Asset)
|
|
56
|
+
return fileInput(value);
|
|
57
|
+
if (Array.isArray(value) && value.some((item) => item instanceof Media.Asset))
|
|
58
|
+
return Effect.forEach(value, (item) => (item instanceof Media.Asset ? fileInput(item) : Effect.succeed(item)));
|
|
59
|
+
return Effect.succeed(value);
|
|
60
|
+
};
|
|
61
|
+
const fromRequest = Effect.fn("ReplicateImages.fromRequest")(function* (request) {
|
|
62
|
+
const native = yield* Effect.forEach(Object.entries(request.providerOptions ?? {}), ([key, value]) => inputValue(value).pipe(Effect.map((lowered) => [key, lowered])));
|
|
63
|
+
const input = mergeJsonRecords({ prompt: request.prompt }, Object.fromEntries(native));
|
|
64
|
+
const model = request.model.id;
|
|
65
|
+
return MediaProtocol.json(mergeJsonRecords(isOfficial(model) ? { input } : { version: model, input }, request.http?.body) ?? {});
|
|
66
|
+
});
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// 6. Response decoding
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
const decodePrediction = route.decodeJson(Prediction);
|
|
71
|
+
const decodeStart = Effect.fn("ReplicateImages.decodeStart")(function* (response) {
|
|
72
|
+
const output = yield* decodePrediction(response);
|
|
73
|
+
const prediction = output.value;
|
|
74
|
+
return {
|
|
75
|
+
token: { id: prediction.id, getURL: prediction.urls.get, cancelURL: prediction.urls.cancel },
|
|
76
|
+
// `Prefer: wait` can return an already-finished prediction, so `await` skips straight to the result.
|
|
77
|
+
snapshot: { id: prediction.id, status: yield* MediaProtocol.status(STATUS, prediction.status, output) },
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
const decodeStatus = Effect.fn("ReplicateImages.decodeStatus")(function* (response, context) {
|
|
81
|
+
const output = yield* decodePrediction(response);
|
|
82
|
+
return { id: context.token.id, status: yield* MediaProtocol.status(STATUS, output.value.status, output) };
|
|
83
|
+
});
|
|
84
|
+
const decodeResult = Effect.fn("ReplicateImages.decodeResult")(function* (response, context) {
|
|
85
|
+
const output = yield* decodePrediction(response);
|
|
86
|
+
const prediction = output.value;
|
|
87
|
+
const status = yield* MediaProtocol.status(STATUS, prediction.status, output);
|
|
88
|
+
if (status === "failed" || status === "cancelled" || status === "expired")
|
|
89
|
+
return yield* output.ended(status, `${route.name} prediction ${context.token.id} ${prediction.status}${typeof prediction.error === "string" ? `: ${prediction.error}` : ""}`);
|
|
90
|
+
if (status !== "completed")
|
|
91
|
+
return yield* output.pending(context.token.id);
|
|
92
|
+
if (prediction.data_removed === true)
|
|
93
|
+
return yield* output.ended("expired", `${route.name} removed the output of prediction ${context.token.id}`);
|
|
94
|
+
if (!isOutput(prediction.output))
|
|
95
|
+
return yield* output.invalid(`${route.name} prediction ${context.token.id} returned output that is not image URLs`);
|
|
96
|
+
const urls = typeof prediction.output === "string" ? [prediction.output] : prediction.output;
|
|
97
|
+
if (urls.length === 0)
|
|
98
|
+
return yield* output.invalid(`${route.name} prediction ${context.token.id} returned no images`);
|
|
99
|
+
const predictTime = prediction.metrics?.predict_time ?? undefined;
|
|
100
|
+
const completedAt = prediction.completed_at ?? undefined;
|
|
101
|
+
const expiresAt = completedAt === undefined ? undefined : Date.parse(completedAt) + Duration.toMillis(OUTPUT_RETENTION);
|
|
102
|
+
return new ImageResponse({
|
|
103
|
+
images: urls.map((url) => Media.url(url, { expiresAt })),
|
|
104
|
+
usage: predictTime === undefined ? undefined : { type: "compute", seconds: predictTime },
|
|
105
|
+
providerMetadata: { replicate: { predictionId: prediction.id } },
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// 7. Protocol and route
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
export const protocol = MediaProtocol.queued(route, {
|
|
112
|
+
token: Token,
|
|
113
|
+
unsupported: ["images", "mask", "n", "size", "aspectRatio", "seed", "format"],
|
|
114
|
+
start: { body: { from: fromRequest }, decode: decodeStart },
|
|
115
|
+
status: { path: (token) => token.getURL, decode: decodeStatus },
|
|
116
|
+
result: { path: (token) => token.getURL, decode: decodeResult },
|
|
117
|
+
cancel: { method: "POST", path: (token) => token.cancelURL },
|
|
118
|
+
});
|
|
119
|
+
export const model = (input) => ImageModel.fromRoute({
|
|
120
|
+
protocol,
|
|
121
|
+
baseURL: DEFAULT_BASE_URL,
|
|
122
|
+
path: ({ request }) => isOfficial(request.model.id) ? `/v1/models/${request.model.id}/predictions` : "/v1/predictions",
|
|
123
|
+
}, input);
|
|
124
|
+
export const ReplicateImages = {
|
|
125
|
+
protocol,
|
|
126
|
+
model,
|
|
127
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
3
|
+
import { MediaRoute } from "../route/media.js";
|
|
4
|
+
import { type OpenString } from "../schema/index.js";
|
|
5
|
+
import { VideoModel, VideoResponse, type VideoRequestFor } from "../video.js";
|
|
6
|
+
export declare const DEFAULT_BASE_URL = "https://api.dev.runwayml.com/v1";
|
|
7
|
+
/** Every Runway request must pin the API version. */
|
|
8
|
+
export declare const API_VERSION = "2024-11-06";
|
|
9
|
+
export declare const TEXT_TO_VIDEO_PATH = "/text_to_video";
|
|
10
|
+
export declare const IMAGE_TO_VIDEO_PATH = "/image_to_video";
|
|
11
|
+
export declare const VIDEO_TO_VIDEO_PATH = "/video_to_video";
|
|
12
|
+
export declare const TASKS_PATH = "/tasks";
|
|
13
|
+
/**
|
|
14
|
+
* Provider-native options. Common fields lower to Runway's names: `aspectRatio` → `ratio` (Runway expects pixel
|
|
15
|
+
* ratios such as `1280:720` for most models), `durationSeconds` → `duration`, `audio`, `negativePrompt`,
|
|
16
|
+
* `resolution`, `references`, and `frames` → `promptImage`.
|
|
17
|
+
*/
|
|
18
|
+
export type RunwayVideoOptions = {
|
|
19
|
+
readonly contentModeration?: {
|
|
20
|
+
readonly publicFigureThreshold?: OpenString<"auto" | "low">;
|
|
21
|
+
};
|
|
22
|
+
readonly outputFormat?: OpenString<"mp4" | "prores" | "png_sequence">;
|
|
23
|
+
} & Record<string, unknown>;
|
|
24
|
+
export type Request = VideoRequestFor<RunwayVideoOptions>;
|
|
25
|
+
export declare const Token: Schema.Struct<{
|
|
26
|
+
readonly taskID: Schema.String;
|
|
27
|
+
}>;
|
|
28
|
+
export type Token = Schema.Schema.Type<typeof Token>;
|
|
29
|
+
export declare const protocol: MediaProtocol.Queued<Request, VideoResponse, {
|
|
30
|
+
readonly taskID: string;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const model: (input: MediaRoute.ModelInput) => VideoModel<RunwayVideoOptions>;
|
|
33
|
+
export declare const RunwayVideo: {
|
|
34
|
+
readonly protocol: MediaProtocol.Queued<Request, VideoResponse, {
|
|
35
|
+
readonly taskID: string;
|
|
36
|
+
}>;
|
|
37
|
+
readonly model: (input: MediaRoute.ModelInput) => VideoModel<RunwayVideoOptions>;
|
|
38
|
+
};
|