@runwayml/avatars-react 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RunwayML
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICES ADDED
@@ -0,0 +1,41 @@
1
+ This project includes the following third-party dependencies:
2
+
3
+ ================================================================================
4
+ livekit-client
5
+ https://github.com/livekit/client-sdk-js
6
+ --------------------------------------------------------------------------------
7
+ Licensed under the Apache License, Version 2.0
8
+
9
+ Copyright 2023 LiveKit, Inc.
10
+
11
+ Licensed under the Apache License, Version 2.0 (the "License");
12
+ you may not use this file except in compliance with the License.
13
+ You may obtain a copy of the License at
14
+
15
+ http://www.apache.org/licenses/LICENSE-2.0
16
+
17
+ Unless required by applicable law or agreed to in writing, software
18
+ distributed under the License is distributed on an "AS IS" BASIS,
19
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ See the License for the specific language governing permissions and
21
+ limitations under the License.
22
+
23
+ ================================================================================
24
+ @livekit/components-react
25
+ https://github.com/livekit/components-js
26
+ --------------------------------------------------------------------------------
27
+ Licensed under the Apache License, Version 2.0
28
+
29
+ Copyright 2023 LiveKit, Inc.
30
+
31
+ Licensed under the Apache License, Version 2.0 (the "License");
32
+ you may not use this file except in compliance with the License.
33
+ You may obtain a copy of the License at
34
+
35
+ http://www.apache.org/licenses/LICENSE-2.0
36
+
37
+ Unless required by applicable law or agreed to in writing, software
38
+ distributed under the License is distributed on an "AS IS" BASIS,
39
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40
+ See the License for the specific language governing permissions and
41
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,328 @@
1
+ # @runwayml/avatars-react
2
+
3
+ React SDK for real-time AI avatar interactions with GWM-1.
4
+
5
+ ## Requirements
6
+
7
+ - React 18+
8
+ - A Runway API secret ([get one here](https://dev.runwayml.com/))
9
+ - A server-side endpoint to create sessions (API secrets must not be exposed to the client)
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @runwayml/avatars-react
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ Add an avatar call to your app with just a few lines:
20
+
21
+ ```tsx
22
+ import { AvatarCall } from '@runwayml/avatars-react';
23
+
24
+ function App() {
25
+ return (
26
+ <AvatarCall
27
+ avatarId="game-host"
28
+ connectUrl="/api/avatar/connect"
29
+ />
30
+ );
31
+ }
32
+ ```
33
+
34
+ That's it! The component handles session creation, WebRTC connection, and renders a default UI with the avatar video and controls.
35
+
36
+ You can use preset avatars like `game-host`, `coding-teacher`, `language-tutor`, and more. See the [Runway Developer Portal](https://dev.runwayml.com/) for the full list and creating custom avatars.
37
+
38
+ ### Optional: Add Default Styles
39
+
40
+ Import the optional stylesheet for a polished look out of the box:
41
+
42
+ ```tsx
43
+ import '@runwayml/avatars-react/styles.css';
44
+ ```
45
+
46
+ The styles use CSS custom properties for easy customization:
47
+
48
+ ```css
49
+ :root {
50
+ --avatar-bg: #a78bfa; /* Video background color */
51
+ --avatar-radius: 16px; /* Container border radius */
52
+ --avatar-control-size: 48px; /* Control button size */
53
+ --avatar-end-call-bg: #ef4444; /* End call button color */
54
+ }
55
+ ```
56
+
57
+ See [`examples/`](./examples) for complete working examples:
58
+ - [`nextjs`](./examples/nextjs) - Next.js App Router
59
+ - [`react-router`](./examples/react-router) - React Router v7 framework mode
60
+ - [`express`](./examples/express) - Express + Vite
61
+
62
+ ## How It Works
63
+
64
+ 1. **Client** calls your server endpoint with the `avatarId`
65
+ 2. **Server** uses your Runway API secret to create a session via `@runwayml/sdk`
66
+ 3. **Server** returns connection credentials (token, URL) to the client
67
+ 4. **Client** establishes a WebRTC connection for real-time video/audio
68
+
69
+ This flow keeps your API secret secure on the server while enabling low-latency communication.
70
+
71
+ ## Server Setup
72
+
73
+ Your server endpoint receives the `avatarId` and returns session credentials. Use `@runwayml/sdk` to create the session:
74
+
75
+ ```ts
76
+ // /api/avatar/connect (Next.js App Router example)
77
+ import Runway from '@runwayml/sdk';
78
+
79
+ const runway = new Runway(); // Uses RUNWAYML_API_SECRET env var
80
+
81
+ export async function POST(req: Request) {
82
+ const { avatarId } = await req.json();
83
+
84
+ const session = await runway.realtime.sessions.create({
85
+ model: 'gwm1_avatars',
86
+ options: { avatar: avatarId },
87
+ });
88
+
89
+ return Response.json({
90
+ sessionId: session.id,
91
+ serverUrl: session.url,
92
+ token: session.token,
93
+ roomName: session.room_name,
94
+ });
95
+ }
96
+ ```
97
+
98
+ ## Customization
99
+
100
+ ### Custom Connect Function
101
+
102
+ For more control over the connection flow:
103
+
104
+ ```tsx
105
+ <AvatarCall
106
+ avatarId="game-host"
107
+ connect={async (avatarId) => {
108
+ const res = await fetch('/api/avatar/connect', {
109
+ method: 'POST',
110
+ headers: {
111
+ 'Authorization': `Bearer ${token}`,
112
+ 'Content-Type': 'application/json',
113
+ },
114
+ body: JSON.stringify({ avatarId }),
115
+ });
116
+ return res.json();
117
+ }}
118
+ />
119
+ ```
120
+
121
+ ### Custom UI with Child Components
122
+
123
+ Use the built-in components for custom layouts:
124
+
125
+ ```tsx
126
+ import { AvatarCall, AvatarVideo, ControlBar, UserVideo } from '@runwayml/avatars-react';
127
+
128
+ <AvatarCall avatarId="game-host" connectUrl="/api/avatar/connect">
129
+ <div className="call-layout">
130
+ <AvatarVideo className="avatar" />
131
+ <UserVideo className="self-view" />
132
+ <ControlBar className="controls" />
133
+ </div>
134
+ </AvatarCall>
135
+ ```
136
+
137
+ ### Render Props
138
+
139
+ All components support render props for complete control:
140
+
141
+ ```tsx
142
+ <AvatarVideo>
143
+ {({ hasVideo, isConnecting, isSpeaking, trackRef }) => (
144
+ <div className={isSpeaking ? 'speaking' : ''}>
145
+ {isConnecting && <Spinner />}
146
+ {hasVideo && <VideoTrack trackRef={trackRef} />}
147
+ </div>
148
+ )}
149
+ </AvatarVideo>
150
+ ```
151
+
152
+ ### CSS Styling with Data Attributes
153
+
154
+ Style connection states with CSS:
155
+
156
+ ```tsx
157
+ <AvatarCall avatarId="game-host" connectUrl="/api/avatar/connect" className="my-avatar" />
158
+ ```
159
+
160
+ ```css
161
+ .my-avatar[data-state="connecting"] {
162
+ opacity: 0.5;
163
+ }
164
+
165
+ .my-avatar[data-state="error"] {
166
+ border: 2px solid red;
167
+ }
168
+
169
+ .my-avatar[data-state="connected"] {
170
+ border: 2px solid green;
171
+ }
172
+ ```
173
+
174
+ ## Callbacks
175
+
176
+ ```tsx
177
+ <AvatarCall
178
+ avatarId="game-host"
179
+ connectUrl="/api/avatar/connect"
180
+ onEnd={() => console.log('Call ended')}
181
+ onError={(error) => console.error('Error:', error)}
182
+ />
183
+ ```
184
+
185
+ ## Hooks
186
+
187
+ Use hooks for custom components within an `AvatarCall` or `AvatarSession`:
188
+
189
+ ### useAvatarSession
190
+
191
+ Access session state and controls:
192
+
193
+ ```tsx
194
+ function MyComponent() {
195
+ const { state, sessionId, error, end } = useAvatarSession();
196
+
197
+ if (state === 'connecting') return <Loading />;
198
+ if (state === 'error') return <Error message={error.message} />;
199
+
200
+ return <button onClick={end}>End Call</button>;
201
+ }
202
+ ```
203
+
204
+ ### useAvatar
205
+
206
+ Access the remote avatar's video/audio:
207
+
208
+ ```tsx
209
+ function CustomAvatar() {
210
+ const { videoTrackRef, isSpeaking, hasVideo, hasAudio } = useAvatar();
211
+
212
+ return (
213
+ <div data-speaking={isSpeaking}>
214
+ {hasVideo && <VideoTrack trackRef={videoTrackRef} />}
215
+ </div>
216
+ );
217
+ }
218
+ ```
219
+
220
+ ### useLocalMedia
221
+
222
+ Control local camera and microphone:
223
+
224
+ ```tsx
225
+ function MediaControls() {
226
+ const {
227
+ isMicEnabled,
228
+ isCameraEnabled,
229
+ toggleMic,
230
+ toggleCamera,
231
+ toggleScreenShare,
232
+ } = useLocalMedia();
233
+
234
+ return (
235
+ <div>
236
+ <button onClick={toggleMic}>{isMicEnabled ? 'Mute' : 'Unmute'}</button>
237
+ <button onClick={toggleCamera}>{isCameraEnabled ? 'Hide' : 'Show'}</button>
238
+ </div>
239
+ );
240
+ }
241
+ ```
242
+
243
+ ## Advanced: AvatarSession
244
+
245
+ For full control over session management, use `AvatarSession` directly with pre-fetched credentials:
246
+
247
+ ```tsx
248
+ import { AvatarSession, AvatarVideo, ControlBar } from '@runwayml/avatars-react';
249
+
250
+ function AdvancedUsage({ credentials }) {
251
+ return (
252
+ <AvatarSession
253
+ credentials={credentials}
254
+ audio={true}
255
+ video={true}
256
+ onEnd={() => console.log('Ended')}
257
+ onError={(err) => console.error(err)}
258
+ >
259
+ <AvatarVideo />
260
+ <ControlBar />
261
+ </AvatarSession>
262
+ );
263
+ }
264
+ ```
265
+
266
+ ## Components Reference
267
+
268
+ | Component | Description |
269
+ |-----------|-------------|
270
+ | `AvatarCall` | High-level component that handles session creation |
271
+ | `AvatarSession` | Low-level wrapper that requires credentials |
272
+ | `AvatarVideo` | Renders the remote avatar video |
273
+ | `UserVideo` | Renders the local user's camera |
274
+ | `ControlBar` | Media control buttons (mic, camera, end call) |
275
+ | `ScreenShareVideo` | Renders screen share content |
276
+ | `AudioRenderer` | Handles avatar audio playback |
277
+
278
+ ## TypeScript
279
+
280
+ All components and hooks are fully typed:
281
+
282
+ ```tsx
283
+ import type {
284
+ AvatarCallProps,
285
+ SessionCredentials,
286
+ SessionState,
287
+ } from '@runwayml/avatars-react';
288
+ ```
289
+
290
+ ## Browser Support
291
+
292
+ This SDK uses WebRTC for real-time communication. Supported browsers:
293
+
294
+ - Chrome 74+
295
+ - Firefox 78+
296
+ - Safari 14.1+
297
+ - Edge 79+
298
+
299
+ Users must grant camera and microphone permissions when prompted.
300
+
301
+ ## Troubleshooting
302
+
303
+ **"Failed to connect" or timeout errors**
304
+ - Verify your server endpoint is returning the correct credential format
305
+ - Check that `RUNWAYML_API_SECRET` is set correctly on your server
306
+
307
+ **No video/audio**
308
+ - Ensure the user has granted camera/microphone permissions
309
+ - Check browser console for WebRTC errors
310
+ - Verify the device has a working camera/microphone
311
+
312
+ **CORS errors**
313
+ - Your server endpoint must accept requests from your client's origin
314
+ - For local development, ensure both client and server are on compatible origins
315
+
316
+ ## Agent Skill
317
+
318
+ This SDK includes an [Agent Skill](https://agentskills.io/) that teaches AI agents how to use the Runway Avatar SDK effectively. Install it with:
319
+
320
+ ```bash
321
+ npx skills add runwayml/avatars-sdk-react
322
+ ```
323
+
324
+ Once installed, AI coding assistants like Claude Code, Cursor, Cline, and others will have access to SDK documentation, patterns, and best practices when helping you build avatar-powered applications.
325
+
326
+ ## License
327
+
328
+ MIT
package/dist/api.cjs ADDED
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ // src/api/config.ts
4
+ var DEFAULT_BASE_URL = "https://api.dev.runwayml.com";
5
+ function getBaseUrl() {
6
+ try {
7
+ const envUrl = process.env.RUNWAYML_BASE_URL;
8
+ if (envUrl) return envUrl;
9
+ } catch {
10
+ }
11
+ return DEFAULT_BASE_URL;
12
+ }
13
+ var config = null;
14
+ function configure(options) {
15
+ config = { ...getConfig(), ...options };
16
+ }
17
+ function getConfig() {
18
+ if (!config) {
19
+ config = { baseUrl: getBaseUrl() };
20
+ }
21
+ return config;
22
+ }
23
+ function resetConfig() {
24
+ config = null;
25
+ }
26
+
27
+ // src/api/consume.ts
28
+ async function consumeSession(options) {
29
+ const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;
30
+ const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;
31
+ const response = await fetch(url, {
32
+ method: "POST",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ Authorization: `Bearer ${sessionKey}`
36
+ }
37
+ });
38
+ if (!response.ok) {
39
+ const errorText = await response.text();
40
+ throw new Error(
41
+ `Failed to consume session: ${response.status} ${errorText}`
42
+ );
43
+ }
44
+ return response.json();
45
+ }
46
+
47
+ exports.configure = configure;
48
+ exports.consumeSession = consumeSession;
49
+ exports.getConfig = getConfig;
50
+ exports.resetConfig = resetConfig;
51
+ //# sourceMappingURL=api.cjs.map
52
+ //# sourceMappingURL=api.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/config.ts","../src/api/consume.ts"],"names":[],"mappings":";;;AAIA,IAAM,gBAAA,GAAmB,8BAAA;AAEzB,SAAS,UAAA,GAAqB;AAC5B,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,QAAQ,GAAA,CAAI,iBAAA;AAC3B,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,gBAAA;AACT;AAEA,IAAI,MAAA,GAA2B,IAAA;AAExB,SAAS,UAAU,OAAA,EAAmC;AAC3D,EAAA,MAAA,GAAS,EAAE,GAAG,SAAA,EAAU,EAAG,GAAG,OAAA,EAAQ;AACxC;AAEO,SAAS,SAAA,GAAuB;AACrC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,GAAS,EAAE,OAAA,EAAS,UAAA,EAAW,EAAE;AAAA,EACnC;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,WAAA,GAAoB;AAClC,EAAA,MAAA,GAAS,IAAA;AACX;;;AC5BA,eAAsB,eACpB,OAAA,EACiC;AACjC,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,UAAU,SAAA,EAAU,CAAE,SAAQ,GAAI,OAAA;AAEjE,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,sBAAA,EAAyB,SAAS,CAAA,QAAA,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACP,cAAA,EAAgB,kBAAA;AAAA,MAChB,aAAA,EAAe,UAAU,UAAU,CAAA;AAAA;AACrC,GACD,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2BAAA,EAA8B,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,CAAA;AAAA,KAC5D;AAAA,EACF;AAEA,EAAA,OAAO,SAAS,IAAA,EAAK;AACvB","file":"api.cjs","sourcesContent":["export interface ApiConfig {\n baseUrl: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.dev.runwayml.com';\n\nfunction getBaseUrl(): string {\n try {\n const envUrl = process.env.RUNWAYML_BASE_URL;\n if (envUrl) return envUrl;\n } catch {\n // process not available in browser\n }\n return DEFAULT_BASE_URL;\n}\n\nlet config: ApiConfig | null = null;\n\nexport function configure(options: Partial<ApiConfig>): void {\n config = { ...getConfig(), ...options };\n}\n\nexport function getConfig(): ApiConfig {\n if (!config) {\n config = { baseUrl: getBaseUrl() };\n }\n return config;\n}\n\nexport function resetConfig(): void {\n config = null;\n}\n","import type { ConsumeSessionOptions, ConsumeSessionResponse } from '../types';\nimport { getConfig } from './config';\n\nexport async function consumeSession(\n options: ConsumeSessionOptions,\n): Promise<ConsumeSessionResponse> {\n const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;\n\n const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${sessionKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Failed to consume session: ${response.status} ${errorText}`,\n );\n }\n\n return response.json();\n}\n"]}
package/dist/api.d.cts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Connection credentials returned from the Runway API consume endpoint
3
+ */
4
+ interface ConsumeSessionResponse {
5
+ /** WebRTC server URL */
6
+ url: string;
7
+ /** Authentication token */
8
+ token: string;
9
+ /** Room name for the session */
10
+ roomName: string;
11
+ }
12
+ /**
13
+ * Options for consuming a session from the Runway API
14
+ */
15
+ interface ConsumeSessionOptions {
16
+ /** The session ID to consume */
17
+ sessionId: string;
18
+ /** The session key for authentication (from GET session response when READY) */
19
+ sessionKey: string;
20
+ /** Optional base URL for the Runway API (defaults to production) */
21
+ baseUrl?: string;
22
+ }
23
+
24
+ interface ApiConfig {
25
+ baseUrl: string;
26
+ }
27
+ declare function configure(options: Partial<ApiConfig>): void;
28
+ declare function getConfig(): ApiConfig;
29
+ declare function resetConfig(): void;
30
+
31
+ declare function consumeSession(options: ConsumeSessionOptions): Promise<ConsumeSessionResponse>;
32
+
33
+ export { type ApiConfig, type ConsumeSessionOptions, type ConsumeSessionResponse, configure, consumeSession, getConfig, resetConfig };
package/dist/api.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Connection credentials returned from the Runway API consume endpoint
3
+ */
4
+ interface ConsumeSessionResponse {
5
+ /** WebRTC server URL */
6
+ url: string;
7
+ /** Authentication token */
8
+ token: string;
9
+ /** Room name for the session */
10
+ roomName: string;
11
+ }
12
+ /**
13
+ * Options for consuming a session from the Runway API
14
+ */
15
+ interface ConsumeSessionOptions {
16
+ /** The session ID to consume */
17
+ sessionId: string;
18
+ /** The session key for authentication (from GET session response when READY) */
19
+ sessionKey: string;
20
+ /** Optional base URL for the Runway API (defaults to production) */
21
+ baseUrl?: string;
22
+ }
23
+
24
+ interface ApiConfig {
25
+ baseUrl: string;
26
+ }
27
+ declare function configure(options: Partial<ApiConfig>): void;
28
+ declare function getConfig(): ApiConfig;
29
+ declare function resetConfig(): void;
30
+
31
+ declare function consumeSession(options: ConsumeSessionOptions): Promise<ConsumeSessionResponse>;
32
+
33
+ export { type ApiConfig, type ConsumeSessionOptions, type ConsumeSessionResponse, configure, consumeSession, getConfig, resetConfig };
package/dist/api.js ADDED
@@ -0,0 +1,47 @@
1
+ // src/api/config.ts
2
+ var DEFAULT_BASE_URL = "https://api.dev.runwayml.com";
3
+ function getBaseUrl() {
4
+ try {
5
+ const envUrl = process.env.RUNWAYML_BASE_URL;
6
+ if (envUrl) return envUrl;
7
+ } catch {
8
+ }
9
+ return DEFAULT_BASE_URL;
10
+ }
11
+ var config = null;
12
+ function configure(options) {
13
+ config = { ...getConfig(), ...options };
14
+ }
15
+ function getConfig() {
16
+ if (!config) {
17
+ config = { baseUrl: getBaseUrl() };
18
+ }
19
+ return config;
20
+ }
21
+ function resetConfig() {
22
+ config = null;
23
+ }
24
+
25
+ // src/api/consume.ts
26
+ async function consumeSession(options) {
27
+ const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;
28
+ const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;
29
+ const response = await fetch(url, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ Authorization: `Bearer ${sessionKey}`
34
+ }
35
+ });
36
+ if (!response.ok) {
37
+ const errorText = await response.text();
38
+ throw new Error(
39
+ `Failed to consume session: ${response.status} ${errorText}`
40
+ );
41
+ }
42
+ return response.json();
43
+ }
44
+
45
+ export { configure, consumeSession, getConfig, resetConfig };
46
+ //# sourceMappingURL=api.js.map
47
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/config.ts","../src/api/consume.ts"],"names":[],"mappings":";AAIA,IAAM,gBAAA,GAAmB,8BAAA;AAEzB,SAAS,UAAA,GAAqB;AAC5B,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,QAAQ,GAAA,CAAI,iBAAA;AAC3B,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,gBAAA;AACT;AAEA,IAAI,MAAA,GAA2B,IAAA;AAExB,SAAS,UAAU,OAAA,EAAmC;AAC3D,EAAA,MAAA,GAAS,EAAE,GAAG,SAAA,EAAU,EAAG,GAAG,OAAA,EAAQ;AACxC;AAEO,SAAS,SAAA,GAAuB;AACrC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,GAAS,EAAE,OAAA,EAAS,UAAA,EAAW,EAAE;AAAA,EACnC;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,WAAA,GAAoB;AAClC,EAAA,MAAA,GAAS,IAAA;AACX;;;AC5BA,eAAsB,eACpB,OAAA,EACiC;AACjC,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,UAAU,SAAA,EAAU,CAAE,SAAQ,GAAI,OAAA;AAEjE,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,sBAAA,EAAyB,SAAS,CAAA,QAAA,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACP,cAAA,EAAgB,kBAAA;AAAA,MAChB,aAAA,EAAe,UAAU,UAAU,CAAA;AAAA;AACrC,GACD,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2BAAA,EAA8B,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,CAAA;AAAA,KAC5D;AAAA,EACF;AAEA,EAAA,OAAO,SAAS,IAAA,EAAK;AACvB","file":"api.js","sourcesContent":["export interface ApiConfig {\n baseUrl: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.dev.runwayml.com';\n\nfunction getBaseUrl(): string {\n try {\n const envUrl = process.env.RUNWAYML_BASE_URL;\n if (envUrl) return envUrl;\n } catch {\n // process not available in browser\n }\n return DEFAULT_BASE_URL;\n}\n\nlet config: ApiConfig | null = null;\n\nexport function configure(options: Partial<ApiConfig>): void {\n config = { ...getConfig(), ...options };\n}\n\nexport function getConfig(): ApiConfig {\n if (!config) {\n config = { baseUrl: getBaseUrl() };\n }\n return config;\n}\n\nexport function resetConfig(): void {\n config = null;\n}\n","import type { ConsumeSessionOptions, ConsumeSessionResponse } from '../types';\nimport { getConfig } from './config';\n\nexport async function consumeSession(\n options: ConsumeSessionOptions,\n): Promise<ConsumeSessionResponse> {\n const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;\n\n const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${sessionKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Failed to consume session: ${response.status} ${errorText}`,\n );\n }\n\n return response.json();\n}\n"]}