@overshoot/sdk 0.1.0-alpha.1 → 0.1.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Overshoot SDK
2
2
 
3
- > **⚠️ Alpha Release**: This is an alpha version (0.1.0-alpha.0). The API may change in future versions.
3
+ > **⚠️ Alpha Release**: This is an alpha version (0.1.0-alpha.3). The API may change in future versions.
4
4
 
5
5
  TypeScript SDK for real-time AI vision analysis on live video streams.
6
6
 
@@ -13,7 +13,7 @@ npm install overshoot@alpha
13
13
  Or install a specific alpha version:
14
14
 
15
15
  ```bash
16
- npm install overshoot@0.1.0-alpha.0
16
+ npm install @overshoot/sdk@0.1.0-alpha.3
17
17
  ```
18
18
 
19
19
  ## Quick Start
@@ -24,7 +24,7 @@ npm install overshoot@0.1.0-alpha.0
24
24
  import { RealtimeVision } from "overshoot";
25
25
 
26
26
  const vision = new RealtimeVision({
27
- apiUrl: "https://api.overshoot.ai",
27
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
28
28
  apiKey: "your-api-key-here",
29
29
  prompt:
30
30
  "Read any visible text and return JSON: {text: string | null, confidence: number}",
@@ -41,7 +41,7 @@ await vision.start();
41
41
 
42
42
  ```typescript
43
43
  const vision = new RealtimeVision({
44
- apiUrl: "https://api.overshoot.ai",
44
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
45
45
  apiKey: "your-api-key-here",
46
46
  prompt: "Detect all objects in the video and count them",
47
47
  source: {
@@ -70,7 +70,7 @@ interface RealtimeVisionConfig {
70
70
 
71
71
  // Optional
72
72
  source?: StreamSource; // Video source (default: environment-facing camera)
73
- backend?: "overshoot" | "gemini"; // Model backend (default: "overshoot")
73
+ backend?: "overshoot"; // Model backend (default: "overshoot")
74
74
  model?: string; // Model name (default: "Qwen/Qwen3-VL-30B-A3B-Instruct")
75
75
  outputSchema?: Record<string, any>; // JSON schema for structured output
76
76
  onError?: (error: Error) => void;
@@ -117,7 +117,7 @@ vision.isActive(); // Check if stream is running
117
117
 
118
118
  ```typescript
119
119
  const vision = new RealtimeVision({
120
- apiUrl: "https://api.overshoot.ai",
120
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
121
121
  apiKey: "your-api-key",
122
122
  prompt: "Detect objects and return JSON: {objects: string[], count: number}",
123
123
  outputSchema: {
@@ -141,7 +141,7 @@ await vision.start();
141
141
 
142
142
  ```typescript
143
143
  const vision = new RealtimeVision({
144
- apiUrl: "https://api.overshoot.ai",
144
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
145
145
  apiKey: "your-api-key",
146
146
  prompt: "Read all visible text in the image",
147
147
  onResult: (result) => {
@@ -156,7 +156,7 @@ await vision.start();
156
156
 
157
157
  ```typescript
158
158
  const vision = new RealtimeVision({
159
- apiUrl: "https://api.overshoot.ai",
159
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
160
160
  apiKey: "your-api-key",
161
161
  prompt: "Describe what you see",
162
162
  onResult: (result) => console.log(result.result),
@@ -176,7 +176,7 @@ if (stream) {
176
176
 
177
177
  ```typescript
178
178
  const vision = new RealtimeVision({
179
- apiUrl: "https://api.overshoot.ai",
179
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
180
180
  apiKey: "your-api-key",
181
181
  prompt: "Count people",
182
182
  onResult: (result) => console.log(result.result),
@@ -192,7 +192,7 @@ await vision.updatePrompt("Detect vehicles instead");
192
192
 
193
193
  ```typescript
194
194
  const vision = new RealtimeVision({
195
- apiUrl: "https://api.overshoot.ai",
195
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
196
196
  apiKey: "your-api-key",
197
197
  prompt: "Detect objects",
198
198
  debug: true, // Enable detailed logging
@@ -207,7 +207,7 @@ await vision.start();
207
207
 
208
208
  ```typescript
209
209
  const vision = new RealtimeVision({
210
- apiUrl: "https://api.overshoot.ai",
210
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
211
211
  apiKey: "your-api-key",
212
212
  prompt: "Detect objects",
213
213
  onResult: (result) => {
@@ -243,7 +243,7 @@ The `onResult` callback receives a `StreamInferenceResult` object:
243
243
  interface StreamInferenceResult {
244
244
  id: string; // Result ID
245
245
  stream_id: string; // Stream ID
246
- model_backend: "gemini" | "overshoot";
246
+ model_backend: "overshoot";
247
247
  model_name: string; // Model used
248
248
  prompt: string; // Task that was run
249
249
  result: string; // Model output (text or JSON string)
package/dist/index.d.mts CHANGED
@@ -21,7 +21,7 @@ type StreamProcessingConfig = {
21
21
  };
22
22
  type StreamInferenceConfig = {
23
23
  prompt: string;
24
- backend: "gemini" | "overshoot";
24
+ backend: "overshoot";
25
25
  model: string;
26
26
  output_schema_json?: Record<string, any>;
27
27
  };
@@ -45,7 +45,7 @@ type StreamCreateResponse = {
45
45
  type StreamInferenceResult = {
46
46
  id: string;
47
47
  stream_id: string;
48
- model_backend: "gemini" | "overshoot";
48
+ model_backend: "overshoot";
49
49
  model_name: string;
50
50
  prompt: string;
51
51
  result: string;
@@ -58,7 +58,7 @@ type StreamConfigResponse = {
58
58
  id: string;
59
59
  stream_id: string;
60
60
  prompt: string;
61
- backend: "gemini" | "overshoot";
61
+ backend: "overshoot";
62
62
  model: string;
63
63
  output_schema_json?: Record<string, any>;
64
64
  created_at?: string;
@@ -143,7 +143,7 @@ interface RealtimeVisionConfig {
143
143
  /**
144
144
  * Model backend to use
145
145
  */
146
- backend?: "gemini" | "overshoot";
146
+ backend?: "overshoot";
147
147
  /**
148
148
  * Model name to use for inference
149
149
  */
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ type StreamProcessingConfig = {
21
21
  };
22
22
  type StreamInferenceConfig = {
23
23
  prompt: string;
24
- backend: "gemini" | "overshoot";
24
+ backend: "overshoot";
25
25
  model: string;
26
26
  output_schema_json?: Record<string, any>;
27
27
  };
@@ -45,7 +45,7 @@ type StreamCreateResponse = {
45
45
  type StreamInferenceResult = {
46
46
  id: string;
47
47
  stream_id: string;
48
- model_backend: "gemini" | "overshoot";
48
+ model_backend: "overshoot";
49
49
  model_name: string;
50
50
  prompt: string;
51
51
  result: string;
@@ -58,7 +58,7 @@ type StreamConfigResponse = {
58
58
  id: string;
59
59
  stream_id: string;
60
60
  prompt: string;
61
- backend: "gemini" | "overshoot";
61
+ backend: "overshoot";
62
62
  model: string;
63
63
  output_schema_json?: Record<string, any>;
64
64
  created_at?: string;
@@ -143,7 +143,7 @@ interface RealtimeVisionConfig {
143
143
  /**
144
144
  * Model backend to use
145
145
  */
146
- backend?: "gemini" | "overshoot";
146
+ backend?: "overshoot";
147
147
  /**
148
148
  * Model name to use for inference
149
149
  */
package/dist/index.js CHANGED
@@ -58,6 +58,7 @@ var StreamClient = class {
58
58
  const response = await fetch(url, {
59
59
  ...options,
60
60
  signal: controller.signal,
61
+ credentials: "include",
61
62
  headers: {
62
63
  "Content-Type": "application/json",
63
64
  Authorization: `Bearer ${this.apiKey}`,
@@ -152,7 +153,9 @@ var StreamClient = class {
152
153
  */
153
154
  async healthCheck() {
154
155
  const url = `${this.baseUrl}/healthz`;
155
- const response = await fetch(url);
156
+ const response = await fetch(url, {
157
+ credentials: "include"
158
+ });
156
159
  return response.text();
157
160
  }
158
161
  };
@@ -168,12 +171,28 @@ var DEFAULTS = {
168
171
  FALLBACK_FPS: 30,
169
172
  ICE_SERVERS: [
170
173
  {
171
- urls: "turn:34.63.114.235:3478",
174
+ urls: "turn:turn.overshoot.ai:3478?transport=udp",
175
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
176
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
177
+ },
178
+ {
179
+ urls: "turn:turn.overshoot.ai:3478?transport=tcp",
180
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
181
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
182
+ },
183
+ {
184
+ urls: "turns:turn.overshoot.ai:443?transport=udp",
185
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
186
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
187
+ },
188
+ {
189
+ urls: "turns:turn.overshoot.ai:443?transport=tcp",
172
190
  username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
173
191
  credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
174
192
  }
175
193
  ]
176
194
  };
195
+ console.log("defaults", DEFAULTS);
177
196
  var CONSTRAINTS = {
178
197
  SAMPLING_RATIO: { min: 0, max: 1 },
179
198
  FPS: { min: 1, max: 120 },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/errors.ts","../src/client/client.ts","../src/client/RealtimeVision.ts"],"names":["ValidationError"],"mappings":"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","file":"index.js","sourcesContent":["export class ApiError extends Error {\n readonly statusCode?: number;\n readonly requestId?: string;\n readonly details?: any;\n\n constructor(\n message: string,\n statusCode?: number,\n requestId?: string,\n details?: any,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.statusCode = statusCode;\n this.requestId = requestId;\n this.details = details;\n }\n}\n\nexport class UnauthorizedError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 401, requestId);\n this.name = \"UnauthorizedError\";\n }\n}\n\nexport class ValidationError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 422, requestId, details);\n this.name = \"ValidationError\";\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 404, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class NetworkError extends ApiError {\n readonly cause?: Error;\n\n constructor(message: string, cause?: Error) {\n super(message);\n this.name = \"NetworkError\";\n this.cause = cause;\n }\n}\n\nexport class ServerError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 500, requestId, details);\n this.name = \"ServerError\";\n }\n}\n","import type {\n StreamCreateRequest,\n StreamCreateResponse,\n KeepaliveResponse,\n StreamConfigResponse,\n FeedbackCreateRequest,\n FeedbackResponse,\n StatusResponse,\n ErrorResponse,\n} from \"./types\";\nimport {\n ApiError,\n ValidationError,\n NotFoundError,\n NetworkError,\n ServerError,\n UnauthorizedError,\n} from \"./errors\";\n\ntype ClientConfig = {\n baseUrl: string;\n apiKey: string;\n};\n\nexport class StreamClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new Error(\"apiKey is required and must be a string\");\n }\n\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const errorData: ErrorResponse = await response.json().catch(() => ({\n error: \"unknown_error\",\n message: response.statusText,\n }));\n\n const message = errorData.message || errorData.error;\n\n if (response.status === 401) {\n throw new UnauthorizedError(\n message || \"Invalid or revoked API key\",\n errorData.request_id,\n );\n }\n if (response.status === 422 || response.status === 400) {\n throw new ValidationError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n if (response.status === 404) {\n throw new NotFoundError(message, errorData.request_id);\n }\n if (response.status >= 500) {\n throw new ServerError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n\n throw new ApiError(\n message,\n response.status,\n errorData.request_id,\n errorData.details,\n );\n }\n\n return await response.json();\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof Error) {\n throw new NetworkError(`Network error: ${error.message}`, error);\n }\n\n throw new NetworkError(\"Unknown network error\");\n }\n }\n\n async createStream(\n request: StreamCreateRequest,\n ): Promise<StreamCreateResponse> {\n return this.request<StreamCreateResponse>(\"/streams\", {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n }\n\n async renewLease(streamId: string): Promise<KeepaliveResponse> {\n return this.request<KeepaliveResponse>(`/streams/${streamId}/keepalive`, {\n method: \"POST\",\n });\n }\n\n async updatePrompt(\n streamId: string,\n prompt: string,\n ): Promise<StreamConfigResponse> {\n return this.request<StreamConfigResponse>(\n `/streams/${streamId}/config/prompt`,\n {\n method: \"PATCH\",\n body: JSON.stringify({ prompt }),\n },\n );\n }\n\n async submitFeedback(\n streamId: string,\n feedback: FeedbackCreateRequest,\n ): Promise<StatusResponse> {\n return this.request<StatusResponse>(`/streams/${streamId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify(feedback),\n });\n }\n\n async getAllFeedback(): Promise<FeedbackResponse[]> {\n return this.request<FeedbackResponse[]>(\"/streams/feedback\", {\n method: \"GET\",\n });\n }\n\n connectWebSocket(streamId: string): WebSocket {\n const wsUrl = this.baseUrl\n .replace(\"http://\", \"ws://\")\n .replace(\"https://\", \"wss://\");\n return new WebSocket(`${wsUrl}/ws/streams/${streamId}`);\n }\n\n /**\n * Health check endpoint (for testing, uses internal port if available)\n * Note: This endpoint may not be available via the main API\n */\n async healthCheck(): Promise<string> {\n const url = `${this.baseUrl}/healthz`;\n const response = await fetch(url);\n return response.text();\n }\n}\n","import { StreamClient } from \"./client\";\n\nimport {\n type StreamInferenceResult,\n type StreamProcessingConfig,\n type StreamSource,\n} from \"./types\";\n\n/**\n * Default configuration values for RealtimeVision\n */\nconst DEFAULTS = {\n BACKEND: \"overshoot\" as const,\n MODEL: \"Qwen/Qwen3-VL-30B-A3B-Instruct\",\n SOURCE: { type: \"camera\", cameraFacing: \"environment\" } as const,\n SAMPLING_RATIO: 0.1,\n CLIP_LENGTH_SECONDS: 1.0,\n DELAY_SECONDS: 1.0,\n FALLBACK_FPS: 30,\n ICE_SERVERS: [\n {\n urls: \"turn:34.63.114.235:3478\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n ] as RTCIceServer[],\n} as const;\n\n/**\n * Validation constraints\n */\nconst CONSTRAINTS = {\n SAMPLING_RATIO: { min: 0, max: 1 },\n FPS: { min: 1, max: 120 },\n CLIP_LENGTH_SECONDS: { min: 0.1, max: 60 },\n DELAY_SECONDS: { min: 0, max: 60 },\n RATING: { min: 1, max: 5 },\n} as const;\n\n/**\n * Logger utility for controlled logging\n */\nclass Logger {\n private debugEnabled: boolean;\n\n constructor(debugEnabled: boolean = false) {\n this.debugEnabled = debugEnabled;\n }\n\n debug(...args: any[]): void {\n if (this.debugEnabled) {\n console.log(\"[RealtimeVision Debug]\", ...args);\n }\n }\n\n info(...args: any[]): void {\n console.log(\"[RealtimeVision]\", ...args);\n }\n\n warn(...args: any[]): void {\n console.warn(\"[RealtimeVision]\", ...args);\n }\n\n error(...args: any[]): void {\n console.error(\"[RealtimeVision]\", ...args);\n }\n}\n\nexport interface RealtimeVisionConfig {\n /**\n * Base URL for the API (e.g., \"https://api.example.com\")\n */\n apiUrl: string;\n\n /**\n * API key for authentication\n * Required for all API requests\n */\n apiKey: string;\n\n /**\n * The prompt/task to run on window segments of the stream.\n * This runs continuously (at a defined window interval).\n *\n * Examples:\n * - \"Read any visible text\"\n * - \"Detect objects and return as JSON array\"\n * - \"Describe facial expression\"\n */\n prompt: string;\n\n /**\n * Video source configuration\n * Defaults to camera with environment facing if not specified\n */\n source?: StreamSource;\n\n /**\n * Model backend to use\n */\n backend?: \"gemini\" | \"overshoot\";\n\n /**\n * Model name to use for inference\n */\n model?: string;\n\n /**\n * Optional JSON schema for structured output\n */\n outputSchema?: Record<string, any>;\n\n /**\n * Called when a new inference result arrives (~1 per second)\n */\n onResult: (result: StreamInferenceResult) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Custom processing configuration\n * All fields are optional and will use defaults if not provided\n */\n processing?: {\n /**\n * Sampling ratio (0-1). Controls what fraction of frames are processed.\n */\n sampling_ratio?: number;\n /**\n * Frames per second (1-120)\n */\n fps?: number;\n /**\n * Clip length in seconds (0.1-60)\n */\n clip_length_seconds?: number;\n /**\n * Delay in seconds (0-60)\n */\n delay_seconds?: number;\n };\n\n /**\n * ICE servers for WebRTC connection\n * If not provided, uses default TURN servers\n */\n iceServers?: RTCIceServer[];\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n}\n\nclass ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport class RealtimeVision {\n private config: RealtimeVisionConfig;\n private client: StreamClient;\n private logger: Logger;\n\n private mediaStream: MediaStream | null = null;\n private peerConnection: RTCPeerConnection | null = null;\n private webSocket: WebSocket | null = null;\n private streamId: string | null = null;\n private keepaliveInterval: number | null = null;\n private videoElement: HTMLVideoElement | null = null;\n\n private isRunning = false;\n\n constructor(config: RealtimeVisionConfig) {\n this.validateConfig(config);\n this.config = config;\n this.logger = new Logger(config.debug ?? false);\n this.client = new StreamClient({\n baseUrl: config.apiUrl,\n apiKey: config.apiKey,\n });\n }\n\n /**\n * Validate configuration values\n */\n private validateConfig(config: RealtimeVisionConfig): void {\n if (!config.apiUrl || typeof config.apiUrl !== \"string\") {\n throw new ValidationError(\"apiUrl is required and must be a string\");\n }\n\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new ValidationError(\"apiKey is required and must be a string\");\n }\n\n if (!config.prompt || typeof config.prompt !== \"string\") {\n throw new ValidationError(\"prompt is required and must be a string\");\n }\n\n if (config.source) {\n if (config.source.type === \"camera\") {\n if (\n config.source.cameraFacing !== \"user\" &&\n config.source.cameraFacing !== \"environment\"\n ) {\n throw new ValidationError(\n 'cameraFacing must be \"user\" or \"environment\"',\n );\n }\n } else if (config.source.type === \"video\") {\n if (!(config.source.file instanceof File)) {\n throw new ValidationError(\"video source must provide a File object\");\n }\n } else {\n throw new ValidationError('source.type must be \"camera\" or \"video\"');\n }\n }\n\n if (config.processing?.sampling_ratio !== undefined) {\n const ratio = config.processing.sampling_ratio;\n if (\n ratio < CONSTRAINTS.SAMPLING_RATIO.min ||\n ratio > CONSTRAINTS.SAMPLING_RATIO.max\n ) {\n throw new ValidationError(\n `sampling_ratio must be between ${CONSTRAINTS.SAMPLING_RATIO.min} and ${CONSTRAINTS.SAMPLING_RATIO.max}`,\n );\n }\n }\n\n if (config.processing?.fps !== undefined) {\n const fps = config.processing.fps;\n if (fps < CONSTRAINTS.FPS.min || fps > CONSTRAINTS.FPS.max) {\n throw new ValidationError(\n `fps must be between ${CONSTRAINTS.FPS.min} and ${CONSTRAINTS.FPS.max}`,\n );\n }\n }\n\n if (config.processing?.clip_length_seconds !== undefined) {\n const clip = config.processing.clip_length_seconds;\n if (\n clip < CONSTRAINTS.CLIP_LENGTH_SECONDS.min ||\n clip > CONSTRAINTS.CLIP_LENGTH_SECONDS.max\n ) {\n throw new ValidationError(\n `clip_length_seconds must be between ${CONSTRAINTS.CLIP_LENGTH_SECONDS.min} and ${CONSTRAINTS.CLIP_LENGTH_SECONDS.max}`,\n );\n }\n }\n\n if (config.processing?.delay_seconds !== undefined) {\n const delay = config.processing.delay_seconds;\n if (\n delay < CONSTRAINTS.DELAY_SECONDS.min ||\n delay > CONSTRAINTS.DELAY_SECONDS.max\n ) {\n throw new ValidationError(\n `delay_seconds must be between ${CONSTRAINTS.DELAY_SECONDS.min} and ${CONSTRAINTS.DELAY_SECONDS.max}`,\n );\n }\n }\n }\n\n /**\n * Create media stream from the configured source\n */\n private async createMediaStream(source: StreamSource): Promise<MediaStream> {\n this.logger.debug(\"Creating media stream from source:\", source.type);\n\n switch (source.type) {\n case \"camera\":\n return await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: source.cameraFacing } },\n audio: false,\n });\n\n case \"video\":\n const video = document.createElement(\"video\");\n video.src = URL.createObjectURL(source.file);\n video.muted = true;\n video.loop = true;\n video.playsInline = true;\n\n this.logger.debug(\"Loading video file:\", source.file.name);\n\n // Wait for video to be ready\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Video loading timeout after 10 seconds\"));\n }, 10000);\n\n video.onloadedmetadata = () => {\n clearTimeout(timeout);\n this.logger.debug(\"Video metadata loaded\");\n resolve();\n };\n\n video.onerror = (e) => {\n clearTimeout(timeout);\n this.logger.error(\"Video loading error:\", e);\n reject(new Error(\"Failed to load video file\"));\n };\n\n if (video.readyState >= 1) {\n clearTimeout(timeout);\n resolve();\n }\n });\n\n await video.play();\n this.logger.debug(\"Video playback started\");\n\n const stream = video.captureStream();\n if (!stream) {\n throw new Error(\"Failed to capture video stream\");\n }\n\n const videoTracks = stream.getVideoTracks();\n if (videoTracks.length === 0) {\n throw new Error(\"Video stream has no video tracks\");\n }\n\n this.videoElement = video;\n return stream;\n\n default:\n throw new Error(`Unknown source type: ${(source as any).type}`);\n }\n }\n\n /**\n * Get FPS from media stream\n */\n private async getStreamFps(\n stream: MediaStream | null,\n source: StreamSource,\n ): Promise<number> {\n if (!stream) {\n this.logger.warn(\"Stream is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTracks = stream.getVideoTracks();\n if (!videoTracks || videoTracks.length === 0) {\n this.logger.warn(\"No video tracks found, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTrack = videoTracks[0];\n if (!videoTrack) {\n this.logger.warn(\"First video track is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n // For camera sources, get FPS from track settings\n if (source.type === \"camera\") {\n const settings = videoTrack.getSettings();\n const fps = settings.frameRate ?? DEFAULTS.FALLBACK_FPS;\n this.logger.debug(\"Detected camera FPS:\", fps);\n return fps;\n }\n\n // For video file sources, try to get FPS from video element\n if (source.type === \"video\" && this.videoElement) {\n await new Promise<void>((resolve, reject) => {\n if (this.videoElement!.readyState >= 1) {\n resolve();\n } else {\n this.videoElement!.onloadedmetadata = () => resolve();\n this.videoElement!.onerror = () =>\n reject(new Error(\"Failed to load video metadata\"));\n }\n });\n\n // For video files, use fallback FPS or user-specified config\n this.logger.debug(\"Using fallback FPS for video file\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n return DEFAULTS.FALLBACK_FPS;\n }\n\n /**\n * Get processing configuration with defaults applied\n */\n private getProcessingConfig(detectedFps: number): StreamProcessingConfig {\n const userProcessing = this.config.processing || {};\n\n return {\n sampling_ratio: userProcessing.sampling_ratio ?? DEFAULTS.SAMPLING_RATIO,\n fps: userProcessing.fps ?? detectedFps,\n clip_length_seconds:\n userProcessing.clip_length_seconds ?? DEFAULTS.CLIP_LENGTH_SECONDS,\n delay_seconds: userProcessing.delay_seconds ?? DEFAULTS.DELAY_SECONDS,\n };\n }\n\n /**\n * Get the effective source configuration\n */\n private getSource(): StreamSource {\n return this.config.source ?? DEFAULTS.SOURCE;\n }\n\n /**\n * Start the vision stream\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Vision stream already running\");\n }\n\n try {\n const source = this.getSource();\n this.logger.debug(\"Starting stream with source type:\", source.type);\n\n if (source.type === \"video\") {\n this.logger.debug(\"Video file:\", {\n name: source.file.name,\n size: source.file.size,\n type: source.file.type,\n });\n\n if (!source.file || !(source.file instanceof File)) {\n throw new Error(\"Invalid video file\");\n }\n }\n\n // Create media stream\n this.mediaStream = await this.createMediaStream(source);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n if (!videoTrack) {\n throw new Error(\"No video track available\");\n }\n\n // Get FPS for the stream\n const detectedFps = await this.getStreamFps(this.mediaStream, source);\n\n // Set up WebRTC peer connection\n const iceServers = this.config.iceServers ?? DEFAULTS.ICE_SERVERS;\n this.logger.debug(\"Creating peer connection with ICE servers\");\n this.peerConnection = new RTCPeerConnection({ iceServers });\n\n // Set up ICE logging\n this.peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this.logger.debug(\"ICE candidate:\", {\n type: event.candidate.type,\n protocol: event.candidate.protocol,\n });\n } else {\n this.logger.debug(\"ICE gathering complete\");\n }\n };\n\n this.peerConnection.oniceconnectionstatechange = () => {\n this.logger.debug(\n \"ICE connection state:\",\n this.peerConnection?.iceConnectionState,\n );\n };\n\n this.peerConnection.addTrack(videoTrack, this.mediaStream);\n\n // Create and set local offer\n const offer = await this.peerConnection.createOffer();\n await this.peerConnection.setLocalDescription(offer);\n\n if (!this.peerConnection.localDescription) {\n throw new Error(\"Failed to create local description\");\n }\n\n // Create stream on server\n this.logger.debug(\"Creating stream on server\");\n const response = await this.client.createStream({\n webrtc: {\n type: \"offer\",\n sdp: this.peerConnection.localDescription.sdp,\n },\n processing: this.getProcessingConfig(detectedFps),\n inference: {\n prompt: this.config.prompt,\n backend: this.config.backend ?? DEFAULTS.BACKEND,\n model: this.config.model ?? DEFAULTS.MODEL,\n output_schema_json: this.config.outputSchema,\n },\n });\n\n this.logger.debug(\"Backend response received:\", {\n stream_id: response.stream_id,\n has_turn_servers: !!response.turn_servers,\n });\n\n // Set remote description\n await this.peerConnection.setRemoteDescription(response.webrtc);\n\n this.streamId = response.stream_id;\n this.logger.info(\"Stream started:\", this.streamId);\n\n // Set up keepalive\n this.setupKeepalive(response.lease?.ttl_seconds);\n\n // Connect WebSocket for results\n this.setupWebSocket(response.stream_id);\n\n this.isRunning = true;\n } catch (error) {\n await this.handleFatalError(error);\n throw error;\n }\n }\n\n /**\n * Set up keepalive interval with error handling\n */\n private setupKeepalive(ttlSeconds: number | undefined): void {\n if (!ttlSeconds) {\n return;\n }\n\n const intervalMs = (ttlSeconds / 2) * 1000;\n this.logger.debug(\"Setting up keepalive with interval:\", intervalMs, \"ms\");\n\n this.keepaliveInterval = window.setInterval(async () => {\n try {\n if (this.streamId) {\n await this.client.renewLease(this.streamId);\n this.logger.debug(\"Lease renewed\");\n }\n } catch (error) {\n this.logger.error(\"Keepalive failed:\", error);\n const keepaliveError = new Error(\n `Keepalive failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n await this.handleFatalError(keepaliveError);\n }\n }, intervalMs);\n }\n\n /**\n * Set up WebSocket connection with error handling\n */\n private setupWebSocket(streamId: string): void {\n this.logger.debug(\"Connecting WebSocket for stream:\", streamId);\n this.webSocket = this.client.connectWebSocket(streamId);\n\n this.webSocket.onopen = () => {\n this.logger.debug(\"WebSocket connected\");\n if (this.webSocket) {\n this.webSocket.send(JSON.stringify({ api_key: this.config.apiKey }));\n }\n };\n\n this.webSocket.onmessage = (event) => {\n try {\n const result: StreamInferenceResult = JSON.parse(event.data);\n this.config.onResult(result);\n } catch (error) {\n const parseError = new Error(\n `Failed to parse WebSocket message: ${error instanceof Error ? error.message : String(error)}`,\n );\n this.handleNonFatalError(parseError);\n }\n };\n\n this.webSocket.onerror = () => {\n this.logger.error(\"WebSocket error occurred\");\n const error = new Error(\"WebSocket error occurred\");\n this.handleFatalError(error);\n };\n\n this.webSocket.onclose = (event) => {\n if (this.isRunning) {\n if (event.code === 1008) {\n this.logger.error(\"WebSocket authentication failed\");\n const error = new Error(\n \"WebSocket authentication failed: Invalid or revoked API key\",\n );\n this.handleFatalError(error);\n } else {\n this.logger.warn(\"WebSocket closed unexpectedly:\", event.code);\n const error = new Error(\"WebSocket closed unexpectedly\");\n this.handleFatalError(error);\n }\n } else {\n this.logger.debug(\"WebSocket closed\");\n }\n };\n }\n\n /**\n * Handle non-fatal errors (report but don't stop stream)\n */\n private handleNonFatalError(error: Error): void {\n this.logger.warn(\"Non-fatal error:\", error.message);\n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Handle fatal errors (stop stream and report)\n */\n private async handleFatalError(error: unknown): Promise<void> {\n this.logger.error(\"Fatal error:\", error);\n await this.cleanup();\n this.isRunning = false;\n\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n\n if (this.config.onError) {\n this.config.onError(normalizedError);\n }\n }\n\n /**\n * Update the prompt/task while stream is running\n */\n async updatePrompt(prompt: string): Promise<void> {\n if (!this.isRunning || !this.streamId) {\n throw new Error(\"Vision stream not running\");\n }\n\n if (!prompt || typeof prompt !== \"string\") {\n throw new ValidationError(\"prompt must be a non-empty string\");\n }\n\n this.logger.debug(\"Updating prompt\");\n await this.client.updatePrompt(this.streamId, prompt);\n this.logger.info(\"Prompt updated\");\n }\n\n /**\n * Stop the vision stream and clean up resources\n */\n async stop(): Promise<void> {\n this.logger.info(\"Stopping stream\");\n await this.cleanup();\n this.isRunning = false;\n }\n\n /**\n * Submit feedback for the stream\n */\n async submitFeedback(feedback: {\n rating: number;\n category: string;\n feedback?: string;\n }): Promise<void> {\n if (!this.streamId) {\n throw new Error(\"No active stream\");\n }\n\n if (\n feedback.rating < CONSTRAINTS.RATING.min ||\n feedback.rating > CONSTRAINTS.RATING.max\n ) {\n throw new ValidationError(\n `rating must be between ${CONSTRAINTS.RATING.min} and ${CONSTRAINTS.RATING.max}`,\n );\n }\n\n if (!feedback.category || typeof feedback.category !== \"string\") {\n throw new ValidationError(\"category must be a non-empty string\");\n }\n\n this.logger.debug(\"Submitting feedback\");\n await this.client.submitFeedback(this.streamId, {\n rating: feedback.rating,\n category: feedback.category,\n feedback: feedback.feedback ?? \"\",\n });\n this.logger.info(\"Feedback submitted\");\n }\n\n /**\n * Get the current stream ID\n */\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /**\n * Get the media stream (for displaying video preview)\n */\n getMediaStream(): MediaStream | null {\n return this.mediaStream;\n }\n\n /**\n * Check if the stream is running\n */\n isActive(): boolean {\n return this.isRunning;\n }\n\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleaning up resources\");\n\n if (this.keepaliveInterval) {\n window.clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n\n if (this.webSocket) {\n this.webSocket.close();\n this.webSocket = null;\n }\n\n if (this.peerConnection) {\n this.peerConnection.close();\n this.peerConnection = null;\n }\n\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => track.stop());\n this.mediaStream = null;\n }\n\n if (this.videoElement) {\n this.videoElement.pause();\n URL.revokeObjectURL(this.videoElement.src);\n this.videoElement.remove();\n this.videoElement = null;\n }\n\n this.streamId = null;\n this.logger.debug(\"Cleanup complete\");\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/client/errors.ts","../src/client/client.ts","../src/client/RealtimeVision.ts"],"names":["ValidationError"],"mappings":"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","file":"index.js","sourcesContent":["export class ApiError extends Error {\n readonly statusCode?: number;\n readonly requestId?: string;\n readonly details?: any;\n\n constructor(\n message: string,\n statusCode?: number,\n requestId?: string,\n details?: any,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.statusCode = statusCode;\n this.requestId = requestId;\n this.details = details;\n }\n}\n\nexport class UnauthorizedError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 401, requestId);\n this.name = \"UnauthorizedError\";\n }\n}\n\nexport class ValidationError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 422, requestId, details);\n this.name = \"ValidationError\";\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 404, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class NetworkError extends ApiError {\n readonly cause?: Error;\n\n constructor(message: string, cause?: Error) {\n super(message);\n this.name = \"NetworkError\";\n this.cause = cause;\n }\n}\n\nexport class ServerError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 500, requestId, details);\n this.name = \"ServerError\";\n }\n}\n","import type {\n StreamCreateRequest,\n StreamCreateResponse,\n KeepaliveResponse,\n StreamConfigResponse,\n FeedbackCreateRequest,\n FeedbackResponse,\n StatusResponse,\n ErrorResponse,\n} from \"./types\";\nimport {\n ApiError,\n ValidationError,\n NotFoundError,\n NetworkError,\n ServerError,\n UnauthorizedError,\n} from \"./errors\";\n\ntype ClientConfig = {\n baseUrl: string;\n apiKey: string;\n};\n\nexport class StreamClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new Error(\"apiKey is required and must be a string\");\n }\n\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const errorData: ErrorResponse = await response.json().catch(() => ({\n error: \"unknown_error\",\n message: response.statusText,\n }));\n\n const message = errorData.message || errorData.error;\n\n if (response.status === 401) {\n throw new UnauthorizedError(\n message || \"Invalid or revoked API key\",\n errorData.request_id,\n );\n }\n if (response.status === 422 || response.status === 400) {\n throw new ValidationError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n if (response.status === 404) {\n throw new NotFoundError(message, errorData.request_id);\n }\n if (response.status >= 500) {\n throw new ServerError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n\n throw new ApiError(\n message,\n response.status,\n errorData.request_id,\n errorData.details,\n );\n }\n\n return await response.json();\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof Error) {\n throw new NetworkError(`Network error: ${error.message}`, error);\n }\n\n throw new NetworkError(\"Unknown network error\");\n }\n }\n async createStream(\n request: StreamCreateRequest,\n ): Promise<StreamCreateResponse> {\n return this.request<StreamCreateResponse>(\"/streams\", {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n }\n\n async renewLease(streamId: string): Promise<KeepaliveResponse> {\n return this.request<KeepaliveResponse>(`/streams/${streamId}/keepalive`, {\n method: \"POST\",\n });\n }\n\n async updatePrompt(\n streamId: string,\n prompt: string,\n ): Promise<StreamConfigResponse> {\n return this.request<StreamConfigResponse>(\n `/streams/${streamId}/config/prompt`,\n {\n method: \"PATCH\",\n body: JSON.stringify({ prompt }),\n },\n );\n }\n\n async submitFeedback(\n streamId: string,\n feedback: FeedbackCreateRequest,\n ): Promise<StatusResponse> {\n return this.request<StatusResponse>(`/streams/${streamId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify(feedback),\n });\n }\n\n async getAllFeedback(): Promise<FeedbackResponse[]> {\n return this.request<FeedbackResponse[]>(\"/streams/feedback\", {\n method: \"GET\",\n });\n }\n\n connectWebSocket(streamId: string): WebSocket {\n const wsUrl = this.baseUrl\n .replace(\"http://\", \"ws://\")\n .replace(\"https://\", \"wss://\");\n return new WebSocket(`${wsUrl}/ws/streams/${streamId}`);\n }\n\n /**\n * Health check endpoint (for testing, uses internal port if available)\n * Note: This endpoint may not be available via the main API\n */\n async healthCheck(): Promise<string> {\n const url = `${this.baseUrl}/healthz`;\n const response = await fetch(url, {\n credentials: \"include\",\n });\n return response.text();\n }\n}\n","import { StreamClient } from \"./client\";\n\nimport {\n type StreamInferenceResult,\n type StreamProcessingConfig,\n type StreamSource,\n} from \"./types\";\n\n/**\n * Default configuration values for RealtimeVision\n */\nconst DEFAULTS = {\n BACKEND: \"overshoot\" as const,\n MODEL: \"Qwen/Qwen3-VL-30B-A3B-Instruct\",\n SOURCE: { type: \"camera\", cameraFacing: \"environment\" } as const,\n SAMPLING_RATIO: 0.1,\n CLIP_LENGTH_SECONDS: 1.0,\n DELAY_SECONDS: 1.0,\n FALLBACK_FPS: 30,\n ICE_SERVERS: [\n {\n urls: \"turn:turn.overshoot.ai:3478?transport=udp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turn:turn.overshoot.ai:3478?transport=tcp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turns:turn.overshoot.ai:443?transport=udp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turns:turn.overshoot.ai:443?transport=tcp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n ] as RTCIceServer[],\n} as const;\n\nconsole.log(\"defaults\", DEFAULTS);\n\n/**\n * Validation constraints\n */\nconst CONSTRAINTS = {\n SAMPLING_RATIO: { min: 0, max: 1 },\n FPS: { min: 1, max: 120 },\n CLIP_LENGTH_SECONDS: { min: 0.1, max: 60 },\n DELAY_SECONDS: { min: 0, max: 60 },\n RATING: { min: 1, max: 5 },\n} as const;\n\n/**\n * Logger utility for controlled logging\n */\nclass Logger {\n private debugEnabled: boolean;\n\n constructor(debugEnabled: boolean = false) {\n this.debugEnabled = debugEnabled;\n }\n\n debug(...args: any[]): void {\n if (this.debugEnabled) {\n console.log(\"[RealtimeVision Debug]\", ...args);\n }\n }\n\n info(...args: any[]): void {\n console.log(\"[RealtimeVision]\", ...args);\n }\n\n warn(...args: any[]): void {\n console.warn(\"[RealtimeVision]\", ...args);\n }\n\n error(...args: any[]): void {\n console.error(\"[RealtimeVision]\", ...args);\n }\n}\n\nexport interface RealtimeVisionConfig {\n /**\n * Base URL for the API (e.g., \"https://api.example.com\")\n */\n apiUrl: string;\n\n /**\n * API key for authentication\n * Required for all API requests\n */\n apiKey: string;\n\n /**\n * The prompt/task to run on window segments of the stream.\n * This runs continuously (at a defined window interval).\n *\n * Examples:\n * - \"Read any visible text\"\n * - \"Detect objects and return as JSON array\"\n * - \"Describe facial expression\"\n */\n prompt: string;\n\n /**\n * Video source configuration\n * Defaults to camera with environment facing if not specified\n */\n source?: StreamSource;\n\n /**\n * Model backend to use\n */\n backend?: \"overshoot\";\n\n /**\n * Model name to use for inference\n */\n model?: string;\n\n /**\n * Optional JSON schema for structured output\n */\n outputSchema?: Record<string, any>;\n\n /**\n * Called when a new inference result arrives (~1 per second)\n */\n onResult: (result: StreamInferenceResult) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Custom processing configuration\n * All fields are optional and will use defaults if not provided\n */\n processing?: {\n /**\n * Sampling ratio (0-1). Controls what fraction of frames are processed.\n */\n sampling_ratio?: number;\n /**\n * Frames per second (1-120)\n */\n fps?: number;\n /**\n * Clip length in seconds (0.1-60)\n */\n clip_length_seconds?: number;\n /**\n * Delay in seconds (0-60)\n */\n delay_seconds?: number;\n };\n\n /**\n * ICE servers for WebRTC connection\n * If not provided, uses default TURN servers\n */\n iceServers?: RTCIceServer[];\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n}\n\nclass ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport class RealtimeVision {\n private config: RealtimeVisionConfig;\n private client: StreamClient;\n private logger: Logger;\n\n private mediaStream: MediaStream | null = null;\n private peerConnection: RTCPeerConnection | null = null;\n private webSocket: WebSocket | null = null;\n private streamId: string | null = null;\n private keepaliveInterval: number | null = null;\n private videoElement: HTMLVideoElement | null = null;\n\n private isRunning = false;\n\n constructor(config: RealtimeVisionConfig) {\n this.validateConfig(config);\n this.config = config;\n this.logger = new Logger(config.debug ?? false);\n this.client = new StreamClient({\n baseUrl: config.apiUrl,\n apiKey: config.apiKey,\n });\n }\n\n /**\n * Validate configuration values\n */\n private validateConfig(config: RealtimeVisionConfig): void {\n if (!config.apiUrl || typeof config.apiUrl !== \"string\") {\n throw new ValidationError(\"apiUrl is required and must be a string\");\n }\n\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new ValidationError(\"apiKey is required and must be a string\");\n }\n\n if (!config.prompt || typeof config.prompt !== \"string\") {\n throw new ValidationError(\"prompt is required and must be a string\");\n }\n\n if (config.source) {\n if (config.source.type === \"camera\") {\n if (\n config.source.cameraFacing !== \"user\" &&\n config.source.cameraFacing !== \"environment\"\n ) {\n throw new ValidationError(\n 'cameraFacing must be \"user\" or \"environment\"',\n );\n }\n } else if (config.source.type === \"video\") {\n if (!(config.source.file instanceof File)) {\n throw new ValidationError(\"video source must provide a File object\");\n }\n } else {\n throw new ValidationError('source.type must be \"camera\" or \"video\"');\n }\n }\n\n if (config.processing?.sampling_ratio !== undefined) {\n const ratio = config.processing.sampling_ratio;\n if (\n ratio < CONSTRAINTS.SAMPLING_RATIO.min ||\n ratio > CONSTRAINTS.SAMPLING_RATIO.max\n ) {\n throw new ValidationError(\n `sampling_ratio must be between ${CONSTRAINTS.SAMPLING_RATIO.min} and ${CONSTRAINTS.SAMPLING_RATIO.max}`,\n );\n }\n }\n\n if (config.processing?.fps !== undefined) {\n const fps = config.processing.fps;\n if (fps < CONSTRAINTS.FPS.min || fps > CONSTRAINTS.FPS.max) {\n throw new ValidationError(\n `fps must be between ${CONSTRAINTS.FPS.min} and ${CONSTRAINTS.FPS.max}`,\n );\n }\n }\n\n if (config.processing?.clip_length_seconds !== undefined) {\n const clip = config.processing.clip_length_seconds;\n if (\n clip < CONSTRAINTS.CLIP_LENGTH_SECONDS.min ||\n clip > CONSTRAINTS.CLIP_LENGTH_SECONDS.max\n ) {\n throw new ValidationError(\n `clip_length_seconds must be between ${CONSTRAINTS.CLIP_LENGTH_SECONDS.min} and ${CONSTRAINTS.CLIP_LENGTH_SECONDS.max}`,\n );\n }\n }\n\n if (config.processing?.delay_seconds !== undefined) {\n const delay = config.processing.delay_seconds;\n if (\n delay < CONSTRAINTS.DELAY_SECONDS.min ||\n delay > CONSTRAINTS.DELAY_SECONDS.max\n ) {\n throw new ValidationError(\n `delay_seconds must be between ${CONSTRAINTS.DELAY_SECONDS.min} and ${CONSTRAINTS.DELAY_SECONDS.max}`,\n );\n }\n }\n }\n\n /**\n * Create media stream from the configured source\n */\n private async createMediaStream(source: StreamSource): Promise<MediaStream> {\n this.logger.debug(\"Creating media stream from source:\", source.type);\n\n switch (source.type) {\n case \"camera\":\n return await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: source.cameraFacing } },\n audio: false,\n });\n\n case \"video\":\n const video = document.createElement(\"video\");\n video.src = URL.createObjectURL(source.file);\n video.muted = true;\n video.loop = true;\n video.playsInline = true;\n\n this.logger.debug(\"Loading video file:\", source.file.name);\n\n // Wait for video to be ready\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Video loading timeout after 10 seconds\"));\n }, 10000);\n\n video.onloadedmetadata = () => {\n clearTimeout(timeout);\n this.logger.debug(\"Video metadata loaded\");\n resolve();\n };\n\n video.onerror = (e) => {\n clearTimeout(timeout);\n this.logger.error(\"Video loading error:\", e);\n reject(new Error(\"Failed to load video file\"));\n };\n\n if (video.readyState >= 1) {\n clearTimeout(timeout);\n resolve();\n }\n });\n\n await video.play();\n this.logger.debug(\"Video playback started\");\n\n const stream = video.captureStream();\n if (!stream) {\n throw new Error(\"Failed to capture video stream\");\n }\n\n const videoTracks = stream.getVideoTracks();\n if (videoTracks.length === 0) {\n throw new Error(\"Video stream has no video tracks\");\n }\n\n this.videoElement = video;\n return stream;\n\n default:\n throw new Error(`Unknown source type: ${(source as any).type}`);\n }\n }\n\n /**\n * Get FPS from media stream\n */\n private async getStreamFps(\n stream: MediaStream | null,\n source: StreamSource,\n ): Promise<number> {\n if (!stream) {\n this.logger.warn(\"Stream is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTracks = stream.getVideoTracks();\n if (!videoTracks || videoTracks.length === 0) {\n this.logger.warn(\"No video tracks found, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTrack = videoTracks[0];\n if (!videoTrack) {\n this.logger.warn(\"First video track is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n // For camera sources, get FPS from track settings\n if (source.type === \"camera\") {\n const settings = videoTrack.getSettings();\n const fps = settings.frameRate ?? DEFAULTS.FALLBACK_FPS;\n this.logger.debug(\"Detected camera FPS:\", fps);\n return fps;\n }\n\n // For video file sources, try to get FPS from video element\n if (source.type === \"video\" && this.videoElement) {\n await new Promise<void>((resolve, reject) => {\n if (this.videoElement!.readyState >= 1) {\n resolve();\n } else {\n this.videoElement!.onloadedmetadata = () => resolve();\n this.videoElement!.onerror = () =>\n reject(new Error(\"Failed to load video metadata\"));\n }\n });\n\n // For video files, use fallback FPS or user-specified config\n this.logger.debug(\"Using fallback FPS for video file\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n return DEFAULTS.FALLBACK_FPS;\n }\n\n /**\n * Get processing configuration with defaults applied\n */\n private getProcessingConfig(detectedFps: number): StreamProcessingConfig {\n const userProcessing = this.config.processing || {};\n\n return {\n sampling_ratio: userProcessing.sampling_ratio ?? DEFAULTS.SAMPLING_RATIO,\n fps: userProcessing.fps ?? detectedFps,\n clip_length_seconds:\n userProcessing.clip_length_seconds ?? DEFAULTS.CLIP_LENGTH_SECONDS,\n delay_seconds: userProcessing.delay_seconds ?? DEFAULTS.DELAY_SECONDS,\n };\n }\n\n /**\n * Get the effective source configuration\n */\n private getSource(): StreamSource {\n return this.config.source ?? DEFAULTS.SOURCE;\n }\n\n /**\n * Start the vision stream\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Vision stream already running\");\n }\n\n try {\n const source = this.getSource();\n this.logger.debug(\"Starting stream with source type:\", source.type);\n\n if (source.type === \"video\") {\n this.logger.debug(\"Video file:\", {\n name: source.file.name,\n size: source.file.size,\n type: source.file.type,\n });\n\n if (!source.file || !(source.file instanceof File)) {\n throw new Error(\"Invalid video file\");\n }\n }\n\n // Create media stream\n this.mediaStream = await this.createMediaStream(source);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n if (!videoTrack) {\n throw new Error(\"No video track available\");\n }\n\n // Get FPS for the stream\n const detectedFps = await this.getStreamFps(this.mediaStream, source);\n\n // Set up WebRTC peer connection\n const iceServers = this.config.iceServers ?? DEFAULTS.ICE_SERVERS;\n this.logger.debug(\"Creating peer connection with ICE servers\");\n this.peerConnection = new RTCPeerConnection({ iceServers });\n\n // Set up ICE logging\n this.peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this.logger.debug(\"ICE candidate:\", {\n type: event.candidate.type,\n protocol: event.candidate.protocol,\n });\n } else {\n this.logger.debug(\"ICE gathering complete\");\n }\n };\n\n this.peerConnection.oniceconnectionstatechange = () => {\n this.logger.debug(\n \"ICE connection state:\",\n this.peerConnection?.iceConnectionState,\n );\n };\n\n this.peerConnection.addTrack(videoTrack, this.mediaStream);\n\n // Create and set local offer\n const offer = await this.peerConnection.createOffer();\n await this.peerConnection.setLocalDescription(offer);\n\n if (!this.peerConnection.localDescription) {\n throw new Error(\"Failed to create local description\");\n }\n\n // Create stream on server\n this.logger.debug(\"Creating stream on server\");\n const response = await this.client.createStream({\n webrtc: {\n type: \"offer\",\n sdp: this.peerConnection.localDescription.sdp,\n },\n processing: this.getProcessingConfig(detectedFps),\n inference: {\n prompt: this.config.prompt,\n backend: this.config.backend ?? DEFAULTS.BACKEND,\n model: this.config.model ?? DEFAULTS.MODEL,\n output_schema_json: this.config.outputSchema,\n },\n });\n\n this.logger.debug(\"Backend response received:\", {\n stream_id: response.stream_id,\n has_turn_servers: !!response.turn_servers,\n });\n\n // Set remote description\n await this.peerConnection.setRemoteDescription(response.webrtc);\n\n this.streamId = response.stream_id;\n this.logger.info(\"Stream started:\", this.streamId);\n\n // Set up keepalive\n this.setupKeepalive(response.lease?.ttl_seconds);\n\n // Connect WebSocket for results\n this.setupWebSocket(response.stream_id);\n\n this.isRunning = true;\n } catch (error) {\n await this.handleFatalError(error);\n throw error;\n }\n }\n\n /**\n * Set up keepalive interval with error handling\n */\n private setupKeepalive(ttlSeconds: number | undefined): void {\n if (!ttlSeconds) {\n return;\n }\n\n const intervalMs = (ttlSeconds / 2) * 1000;\n this.logger.debug(\"Setting up keepalive with interval:\", intervalMs, \"ms\");\n\n this.keepaliveInterval = window.setInterval(async () => {\n try {\n if (this.streamId) {\n await this.client.renewLease(this.streamId);\n this.logger.debug(\"Lease renewed\");\n }\n } catch (error) {\n this.logger.error(\"Keepalive failed:\", error);\n const keepaliveError = new Error(\n `Keepalive failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n await this.handleFatalError(keepaliveError);\n }\n }, intervalMs);\n }\n\n /**\n * Set up WebSocket connection with error handling\n */\n private setupWebSocket(streamId: string): void {\n this.logger.debug(\"Connecting WebSocket for stream:\", streamId);\n this.webSocket = this.client.connectWebSocket(streamId);\n\n this.webSocket.onopen = () => {\n this.logger.debug(\"WebSocket connected\");\n if (this.webSocket) {\n this.webSocket.send(JSON.stringify({ api_key: this.config.apiKey }));\n }\n };\n\n this.webSocket.onmessage = (event) => {\n try {\n const result: StreamInferenceResult = JSON.parse(event.data);\n this.config.onResult(result);\n } catch (error) {\n const parseError = new Error(\n `Failed to parse WebSocket message: ${error instanceof Error ? error.message : String(error)}`,\n );\n this.handleNonFatalError(parseError);\n }\n };\n\n this.webSocket.onerror = () => {\n this.logger.error(\"WebSocket error occurred\");\n const error = new Error(\"WebSocket error occurred\");\n this.handleFatalError(error);\n };\n\n this.webSocket.onclose = (event) => {\n if (this.isRunning) {\n if (event.code === 1008) {\n this.logger.error(\"WebSocket authentication failed\");\n const error = new Error(\n \"WebSocket authentication failed: Invalid or revoked API key\",\n );\n this.handleFatalError(error);\n } else {\n this.logger.warn(\"WebSocket closed unexpectedly:\", event.code);\n const error = new Error(\"WebSocket closed unexpectedly\");\n this.handleFatalError(error);\n }\n } else {\n this.logger.debug(\"WebSocket closed\");\n }\n };\n }\n\n /**\n * Handle non-fatal errors (report but don't stop stream)\n */\n private handleNonFatalError(error: Error): void {\n this.logger.warn(\"Non-fatal error:\", error.message);\n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Handle fatal errors (stop stream and report)\n */\n private async handleFatalError(error: unknown): Promise<void> {\n this.logger.error(\"Fatal error:\", error);\n await this.cleanup();\n this.isRunning = false;\n\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n\n if (this.config.onError) {\n this.config.onError(normalizedError);\n }\n }\n\n /**\n * Update the prompt/task while stream is running\n */\n async updatePrompt(prompt: string): Promise<void> {\n if (!this.isRunning || !this.streamId) {\n throw new Error(\"Vision stream not running\");\n }\n\n if (!prompt || typeof prompt !== \"string\") {\n throw new ValidationError(\"prompt must be a non-empty string\");\n }\n\n this.logger.debug(\"Updating prompt\");\n await this.client.updatePrompt(this.streamId, prompt);\n this.logger.info(\"Prompt updated\");\n }\n\n /**\n * Stop the vision stream and clean up resources\n */\n async stop(): Promise<void> {\n this.logger.info(\"Stopping stream\");\n await this.cleanup();\n this.isRunning = false;\n }\n\n /**\n * Submit feedback for the stream\n */\n async submitFeedback(feedback: {\n rating: number;\n category: string;\n feedback?: string;\n }): Promise<void> {\n if (!this.streamId) {\n throw new Error(\"No active stream\");\n }\n\n if (\n feedback.rating < CONSTRAINTS.RATING.min ||\n feedback.rating > CONSTRAINTS.RATING.max\n ) {\n throw new ValidationError(\n `rating must be between ${CONSTRAINTS.RATING.min} and ${CONSTRAINTS.RATING.max}`,\n );\n }\n\n if (!feedback.category || typeof feedback.category !== \"string\") {\n throw new ValidationError(\"category must be a non-empty string\");\n }\n\n this.logger.debug(\"Submitting feedback\");\n await this.client.submitFeedback(this.streamId, {\n rating: feedback.rating,\n category: feedback.category,\n feedback: feedback.feedback ?? \"\",\n });\n this.logger.info(\"Feedback submitted\");\n }\n\n /**\n * Get the current stream ID\n */\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /**\n * Get the media stream (for displaying video preview)\n */\n getMediaStream(): MediaStream | null {\n return this.mediaStream;\n }\n\n /**\n * Check if the stream is running\n */\n isActive(): boolean {\n return this.isRunning;\n }\n\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleaning up resources\");\n\n if (this.keepaliveInterval) {\n window.clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n\n if (this.webSocket) {\n this.webSocket.close();\n this.webSocket = null;\n }\n\n if (this.peerConnection) {\n this.peerConnection.close();\n this.peerConnection = null;\n }\n\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => track.stop());\n this.mediaStream = null;\n }\n\n if (this.videoElement) {\n this.videoElement.pause();\n URL.revokeObjectURL(this.videoElement.src);\n this.videoElement.remove();\n this.videoElement = null;\n }\n\n this.streamId = null;\n this.logger.debug(\"Cleanup complete\");\n }\n}\n"]}
package/dist/index.mjs CHANGED
@@ -56,6 +56,7 @@ var StreamClient = class {
56
56
  const response = await fetch(url, {
57
57
  ...options,
58
58
  signal: controller.signal,
59
+ credentials: "include",
59
60
  headers: {
60
61
  "Content-Type": "application/json",
61
62
  Authorization: `Bearer ${this.apiKey}`,
@@ -150,7 +151,9 @@ var StreamClient = class {
150
151
  */
151
152
  async healthCheck() {
152
153
  const url = `${this.baseUrl}/healthz`;
153
- const response = await fetch(url);
154
+ const response = await fetch(url, {
155
+ credentials: "include"
156
+ });
154
157
  return response.text();
155
158
  }
156
159
  };
@@ -166,12 +169,28 @@ var DEFAULTS = {
166
169
  FALLBACK_FPS: 30,
167
170
  ICE_SERVERS: [
168
171
  {
169
- urls: "turn:34.63.114.235:3478",
172
+ urls: "turn:turn.overshoot.ai:3478?transport=udp",
173
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
174
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
175
+ },
176
+ {
177
+ urls: "turn:turn.overshoot.ai:3478?transport=tcp",
178
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
179
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
180
+ },
181
+ {
182
+ urls: "turns:turn.overshoot.ai:443?transport=udp",
183
+ username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
184
+ credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
185
+ },
186
+ {
187
+ urls: "turns:turn.overshoot.ai:443?transport=tcp",
170
188
  username: "1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb",
171
189
  credential: "Fu9L4CwyYZvsOLc+23psVAo3i/Y="
172
190
  }
173
191
  ]
174
192
  };
193
+ console.log("defaults", DEFAULTS);
175
194
  var CONSTRAINTS = {
176
195
  SAMPLING_RATIO: { min: 0, max: 1 },
177
196
  FPS: { min: 1, max: 120 },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/errors.ts","../src/client/client.ts","../src/client/RealtimeVision.ts"],"names":["ValidationError"],"mappings":"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","file":"index.mjs","sourcesContent":["export class ApiError extends Error {\n readonly statusCode?: number;\n readonly requestId?: string;\n readonly details?: any;\n\n constructor(\n message: string,\n statusCode?: number,\n requestId?: string,\n details?: any,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.statusCode = statusCode;\n this.requestId = requestId;\n this.details = details;\n }\n}\n\nexport class UnauthorizedError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 401, requestId);\n this.name = \"UnauthorizedError\";\n }\n}\n\nexport class ValidationError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 422, requestId, details);\n this.name = \"ValidationError\";\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 404, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class NetworkError extends ApiError {\n readonly cause?: Error;\n\n constructor(message: string, cause?: Error) {\n super(message);\n this.name = \"NetworkError\";\n this.cause = cause;\n }\n}\n\nexport class ServerError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 500, requestId, details);\n this.name = \"ServerError\";\n }\n}\n","import type {\n StreamCreateRequest,\n StreamCreateResponse,\n KeepaliveResponse,\n StreamConfigResponse,\n FeedbackCreateRequest,\n FeedbackResponse,\n StatusResponse,\n ErrorResponse,\n} from \"./types\";\nimport {\n ApiError,\n ValidationError,\n NotFoundError,\n NetworkError,\n ServerError,\n UnauthorizedError,\n} from \"./errors\";\n\ntype ClientConfig = {\n baseUrl: string;\n apiKey: string;\n};\n\nexport class StreamClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new Error(\"apiKey is required and must be a string\");\n }\n\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const errorData: ErrorResponse = await response.json().catch(() => ({\n error: \"unknown_error\",\n message: response.statusText,\n }));\n\n const message = errorData.message || errorData.error;\n\n if (response.status === 401) {\n throw new UnauthorizedError(\n message || \"Invalid or revoked API key\",\n errorData.request_id,\n );\n }\n if (response.status === 422 || response.status === 400) {\n throw new ValidationError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n if (response.status === 404) {\n throw new NotFoundError(message, errorData.request_id);\n }\n if (response.status >= 500) {\n throw new ServerError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n\n throw new ApiError(\n message,\n response.status,\n errorData.request_id,\n errorData.details,\n );\n }\n\n return await response.json();\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof Error) {\n throw new NetworkError(`Network error: ${error.message}`, error);\n }\n\n throw new NetworkError(\"Unknown network error\");\n }\n }\n\n async createStream(\n request: StreamCreateRequest,\n ): Promise<StreamCreateResponse> {\n return this.request<StreamCreateResponse>(\"/streams\", {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n }\n\n async renewLease(streamId: string): Promise<KeepaliveResponse> {\n return this.request<KeepaliveResponse>(`/streams/${streamId}/keepalive`, {\n method: \"POST\",\n });\n }\n\n async updatePrompt(\n streamId: string,\n prompt: string,\n ): Promise<StreamConfigResponse> {\n return this.request<StreamConfigResponse>(\n `/streams/${streamId}/config/prompt`,\n {\n method: \"PATCH\",\n body: JSON.stringify({ prompt }),\n },\n );\n }\n\n async submitFeedback(\n streamId: string,\n feedback: FeedbackCreateRequest,\n ): Promise<StatusResponse> {\n return this.request<StatusResponse>(`/streams/${streamId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify(feedback),\n });\n }\n\n async getAllFeedback(): Promise<FeedbackResponse[]> {\n return this.request<FeedbackResponse[]>(\"/streams/feedback\", {\n method: \"GET\",\n });\n }\n\n connectWebSocket(streamId: string): WebSocket {\n const wsUrl = this.baseUrl\n .replace(\"http://\", \"ws://\")\n .replace(\"https://\", \"wss://\");\n return new WebSocket(`${wsUrl}/ws/streams/${streamId}`);\n }\n\n /**\n * Health check endpoint (for testing, uses internal port if available)\n * Note: This endpoint may not be available via the main API\n */\n async healthCheck(): Promise<string> {\n const url = `${this.baseUrl}/healthz`;\n const response = await fetch(url);\n return response.text();\n }\n}\n","import { StreamClient } from \"./client\";\n\nimport {\n type StreamInferenceResult,\n type StreamProcessingConfig,\n type StreamSource,\n} from \"./types\";\n\n/**\n * Default configuration values for RealtimeVision\n */\nconst DEFAULTS = {\n BACKEND: \"overshoot\" as const,\n MODEL: \"Qwen/Qwen3-VL-30B-A3B-Instruct\",\n SOURCE: { type: \"camera\", cameraFacing: \"environment\" } as const,\n SAMPLING_RATIO: 0.1,\n CLIP_LENGTH_SECONDS: 1.0,\n DELAY_SECONDS: 1.0,\n FALLBACK_FPS: 30,\n ICE_SERVERS: [\n {\n urls: \"turn:34.63.114.235:3478\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n ] as RTCIceServer[],\n} as const;\n\n/**\n * Validation constraints\n */\nconst CONSTRAINTS = {\n SAMPLING_RATIO: { min: 0, max: 1 },\n FPS: { min: 1, max: 120 },\n CLIP_LENGTH_SECONDS: { min: 0.1, max: 60 },\n DELAY_SECONDS: { min: 0, max: 60 },\n RATING: { min: 1, max: 5 },\n} as const;\n\n/**\n * Logger utility for controlled logging\n */\nclass Logger {\n private debugEnabled: boolean;\n\n constructor(debugEnabled: boolean = false) {\n this.debugEnabled = debugEnabled;\n }\n\n debug(...args: any[]): void {\n if (this.debugEnabled) {\n console.log(\"[RealtimeVision Debug]\", ...args);\n }\n }\n\n info(...args: any[]): void {\n console.log(\"[RealtimeVision]\", ...args);\n }\n\n warn(...args: any[]): void {\n console.warn(\"[RealtimeVision]\", ...args);\n }\n\n error(...args: any[]): void {\n console.error(\"[RealtimeVision]\", ...args);\n }\n}\n\nexport interface RealtimeVisionConfig {\n /**\n * Base URL for the API (e.g., \"https://api.example.com\")\n */\n apiUrl: string;\n\n /**\n * API key for authentication\n * Required for all API requests\n */\n apiKey: string;\n\n /**\n * The prompt/task to run on window segments of the stream.\n * This runs continuously (at a defined window interval).\n *\n * Examples:\n * - \"Read any visible text\"\n * - \"Detect objects and return as JSON array\"\n * - \"Describe facial expression\"\n */\n prompt: string;\n\n /**\n * Video source configuration\n * Defaults to camera with environment facing if not specified\n */\n source?: StreamSource;\n\n /**\n * Model backend to use\n */\n backend?: \"gemini\" | \"overshoot\";\n\n /**\n * Model name to use for inference\n */\n model?: string;\n\n /**\n * Optional JSON schema for structured output\n */\n outputSchema?: Record<string, any>;\n\n /**\n * Called when a new inference result arrives (~1 per second)\n */\n onResult: (result: StreamInferenceResult) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Custom processing configuration\n * All fields are optional and will use defaults if not provided\n */\n processing?: {\n /**\n * Sampling ratio (0-1). Controls what fraction of frames are processed.\n */\n sampling_ratio?: number;\n /**\n * Frames per second (1-120)\n */\n fps?: number;\n /**\n * Clip length in seconds (0.1-60)\n */\n clip_length_seconds?: number;\n /**\n * Delay in seconds (0-60)\n */\n delay_seconds?: number;\n };\n\n /**\n * ICE servers for WebRTC connection\n * If not provided, uses default TURN servers\n */\n iceServers?: RTCIceServer[];\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n}\n\nclass ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport class RealtimeVision {\n private config: RealtimeVisionConfig;\n private client: StreamClient;\n private logger: Logger;\n\n private mediaStream: MediaStream | null = null;\n private peerConnection: RTCPeerConnection | null = null;\n private webSocket: WebSocket | null = null;\n private streamId: string | null = null;\n private keepaliveInterval: number | null = null;\n private videoElement: HTMLVideoElement | null = null;\n\n private isRunning = false;\n\n constructor(config: RealtimeVisionConfig) {\n this.validateConfig(config);\n this.config = config;\n this.logger = new Logger(config.debug ?? false);\n this.client = new StreamClient({\n baseUrl: config.apiUrl,\n apiKey: config.apiKey,\n });\n }\n\n /**\n * Validate configuration values\n */\n private validateConfig(config: RealtimeVisionConfig): void {\n if (!config.apiUrl || typeof config.apiUrl !== \"string\") {\n throw new ValidationError(\"apiUrl is required and must be a string\");\n }\n\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new ValidationError(\"apiKey is required and must be a string\");\n }\n\n if (!config.prompt || typeof config.prompt !== \"string\") {\n throw new ValidationError(\"prompt is required and must be a string\");\n }\n\n if (config.source) {\n if (config.source.type === \"camera\") {\n if (\n config.source.cameraFacing !== \"user\" &&\n config.source.cameraFacing !== \"environment\"\n ) {\n throw new ValidationError(\n 'cameraFacing must be \"user\" or \"environment\"',\n );\n }\n } else if (config.source.type === \"video\") {\n if (!(config.source.file instanceof File)) {\n throw new ValidationError(\"video source must provide a File object\");\n }\n } else {\n throw new ValidationError('source.type must be \"camera\" or \"video\"');\n }\n }\n\n if (config.processing?.sampling_ratio !== undefined) {\n const ratio = config.processing.sampling_ratio;\n if (\n ratio < CONSTRAINTS.SAMPLING_RATIO.min ||\n ratio > CONSTRAINTS.SAMPLING_RATIO.max\n ) {\n throw new ValidationError(\n `sampling_ratio must be between ${CONSTRAINTS.SAMPLING_RATIO.min} and ${CONSTRAINTS.SAMPLING_RATIO.max}`,\n );\n }\n }\n\n if (config.processing?.fps !== undefined) {\n const fps = config.processing.fps;\n if (fps < CONSTRAINTS.FPS.min || fps > CONSTRAINTS.FPS.max) {\n throw new ValidationError(\n `fps must be between ${CONSTRAINTS.FPS.min} and ${CONSTRAINTS.FPS.max}`,\n );\n }\n }\n\n if (config.processing?.clip_length_seconds !== undefined) {\n const clip = config.processing.clip_length_seconds;\n if (\n clip < CONSTRAINTS.CLIP_LENGTH_SECONDS.min ||\n clip > CONSTRAINTS.CLIP_LENGTH_SECONDS.max\n ) {\n throw new ValidationError(\n `clip_length_seconds must be between ${CONSTRAINTS.CLIP_LENGTH_SECONDS.min} and ${CONSTRAINTS.CLIP_LENGTH_SECONDS.max}`,\n );\n }\n }\n\n if (config.processing?.delay_seconds !== undefined) {\n const delay = config.processing.delay_seconds;\n if (\n delay < CONSTRAINTS.DELAY_SECONDS.min ||\n delay > CONSTRAINTS.DELAY_SECONDS.max\n ) {\n throw new ValidationError(\n `delay_seconds must be between ${CONSTRAINTS.DELAY_SECONDS.min} and ${CONSTRAINTS.DELAY_SECONDS.max}`,\n );\n }\n }\n }\n\n /**\n * Create media stream from the configured source\n */\n private async createMediaStream(source: StreamSource): Promise<MediaStream> {\n this.logger.debug(\"Creating media stream from source:\", source.type);\n\n switch (source.type) {\n case \"camera\":\n return await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: source.cameraFacing } },\n audio: false,\n });\n\n case \"video\":\n const video = document.createElement(\"video\");\n video.src = URL.createObjectURL(source.file);\n video.muted = true;\n video.loop = true;\n video.playsInline = true;\n\n this.logger.debug(\"Loading video file:\", source.file.name);\n\n // Wait for video to be ready\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Video loading timeout after 10 seconds\"));\n }, 10000);\n\n video.onloadedmetadata = () => {\n clearTimeout(timeout);\n this.logger.debug(\"Video metadata loaded\");\n resolve();\n };\n\n video.onerror = (e) => {\n clearTimeout(timeout);\n this.logger.error(\"Video loading error:\", e);\n reject(new Error(\"Failed to load video file\"));\n };\n\n if (video.readyState >= 1) {\n clearTimeout(timeout);\n resolve();\n }\n });\n\n await video.play();\n this.logger.debug(\"Video playback started\");\n\n const stream = video.captureStream();\n if (!stream) {\n throw new Error(\"Failed to capture video stream\");\n }\n\n const videoTracks = stream.getVideoTracks();\n if (videoTracks.length === 0) {\n throw new Error(\"Video stream has no video tracks\");\n }\n\n this.videoElement = video;\n return stream;\n\n default:\n throw new Error(`Unknown source type: ${(source as any).type}`);\n }\n }\n\n /**\n * Get FPS from media stream\n */\n private async getStreamFps(\n stream: MediaStream | null,\n source: StreamSource,\n ): Promise<number> {\n if (!stream) {\n this.logger.warn(\"Stream is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTracks = stream.getVideoTracks();\n if (!videoTracks || videoTracks.length === 0) {\n this.logger.warn(\"No video tracks found, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTrack = videoTracks[0];\n if (!videoTrack) {\n this.logger.warn(\"First video track is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n // For camera sources, get FPS from track settings\n if (source.type === \"camera\") {\n const settings = videoTrack.getSettings();\n const fps = settings.frameRate ?? DEFAULTS.FALLBACK_FPS;\n this.logger.debug(\"Detected camera FPS:\", fps);\n return fps;\n }\n\n // For video file sources, try to get FPS from video element\n if (source.type === \"video\" && this.videoElement) {\n await new Promise<void>((resolve, reject) => {\n if (this.videoElement!.readyState >= 1) {\n resolve();\n } else {\n this.videoElement!.onloadedmetadata = () => resolve();\n this.videoElement!.onerror = () =>\n reject(new Error(\"Failed to load video metadata\"));\n }\n });\n\n // For video files, use fallback FPS or user-specified config\n this.logger.debug(\"Using fallback FPS for video file\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n return DEFAULTS.FALLBACK_FPS;\n }\n\n /**\n * Get processing configuration with defaults applied\n */\n private getProcessingConfig(detectedFps: number): StreamProcessingConfig {\n const userProcessing = this.config.processing || {};\n\n return {\n sampling_ratio: userProcessing.sampling_ratio ?? DEFAULTS.SAMPLING_RATIO,\n fps: userProcessing.fps ?? detectedFps,\n clip_length_seconds:\n userProcessing.clip_length_seconds ?? DEFAULTS.CLIP_LENGTH_SECONDS,\n delay_seconds: userProcessing.delay_seconds ?? DEFAULTS.DELAY_SECONDS,\n };\n }\n\n /**\n * Get the effective source configuration\n */\n private getSource(): StreamSource {\n return this.config.source ?? DEFAULTS.SOURCE;\n }\n\n /**\n * Start the vision stream\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Vision stream already running\");\n }\n\n try {\n const source = this.getSource();\n this.logger.debug(\"Starting stream with source type:\", source.type);\n\n if (source.type === \"video\") {\n this.logger.debug(\"Video file:\", {\n name: source.file.name,\n size: source.file.size,\n type: source.file.type,\n });\n\n if (!source.file || !(source.file instanceof File)) {\n throw new Error(\"Invalid video file\");\n }\n }\n\n // Create media stream\n this.mediaStream = await this.createMediaStream(source);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n if (!videoTrack) {\n throw new Error(\"No video track available\");\n }\n\n // Get FPS for the stream\n const detectedFps = await this.getStreamFps(this.mediaStream, source);\n\n // Set up WebRTC peer connection\n const iceServers = this.config.iceServers ?? DEFAULTS.ICE_SERVERS;\n this.logger.debug(\"Creating peer connection with ICE servers\");\n this.peerConnection = new RTCPeerConnection({ iceServers });\n\n // Set up ICE logging\n this.peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this.logger.debug(\"ICE candidate:\", {\n type: event.candidate.type,\n protocol: event.candidate.protocol,\n });\n } else {\n this.logger.debug(\"ICE gathering complete\");\n }\n };\n\n this.peerConnection.oniceconnectionstatechange = () => {\n this.logger.debug(\n \"ICE connection state:\",\n this.peerConnection?.iceConnectionState,\n );\n };\n\n this.peerConnection.addTrack(videoTrack, this.mediaStream);\n\n // Create and set local offer\n const offer = await this.peerConnection.createOffer();\n await this.peerConnection.setLocalDescription(offer);\n\n if (!this.peerConnection.localDescription) {\n throw new Error(\"Failed to create local description\");\n }\n\n // Create stream on server\n this.logger.debug(\"Creating stream on server\");\n const response = await this.client.createStream({\n webrtc: {\n type: \"offer\",\n sdp: this.peerConnection.localDescription.sdp,\n },\n processing: this.getProcessingConfig(detectedFps),\n inference: {\n prompt: this.config.prompt,\n backend: this.config.backend ?? DEFAULTS.BACKEND,\n model: this.config.model ?? DEFAULTS.MODEL,\n output_schema_json: this.config.outputSchema,\n },\n });\n\n this.logger.debug(\"Backend response received:\", {\n stream_id: response.stream_id,\n has_turn_servers: !!response.turn_servers,\n });\n\n // Set remote description\n await this.peerConnection.setRemoteDescription(response.webrtc);\n\n this.streamId = response.stream_id;\n this.logger.info(\"Stream started:\", this.streamId);\n\n // Set up keepalive\n this.setupKeepalive(response.lease?.ttl_seconds);\n\n // Connect WebSocket for results\n this.setupWebSocket(response.stream_id);\n\n this.isRunning = true;\n } catch (error) {\n await this.handleFatalError(error);\n throw error;\n }\n }\n\n /**\n * Set up keepalive interval with error handling\n */\n private setupKeepalive(ttlSeconds: number | undefined): void {\n if (!ttlSeconds) {\n return;\n }\n\n const intervalMs = (ttlSeconds / 2) * 1000;\n this.logger.debug(\"Setting up keepalive with interval:\", intervalMs, \"ms\");\n\n this.keepaliveInterval = window.setInterval(async () => {\n try {\n if (this.streamId) {\n await this.client.renewLease(this.streamId);\n this.logger.debug(\"Lease renewed\");\n }\n } catch (error) {\n this.logger.error(\"Keepalive failed:\", error);\n const keepaliveError = new Error(\n `Keepalive failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n await this.handleFatalError(keepaliveError);\n }\n }, intervalMs);\n }\n\n /**\n * Set up WebSocket connection with error handling\n */\n private setupWebSocket(streamId: string): void {\n this.logger.debug(\"Connecting WebSocket for stream:\", streamId);\n this.webSocket = this.client.connectWebSocket(streamId);\n\n this.webSocket.onopen = () => {\n this.logger.debug(\"WebSocket connected\");\n if (this.webSocket) {\n this.webSocket.send(JSON.stringify({ api_key: this.config.apiKey }));\n }\n };\n\n this.webSocket.onmessage = (event) => {\n try {\n const result: StreamInferenceResult = JSON.parse(event.data);\n this.config.onResult(result);\n } catch (error) {\n const parseError = new Error(\n `Failed to parse WebSocket message: ${error instanceof Error ? error.message : String(error)}`,\n );\n this.handleNonFatalError(parseError);\n }\n };\n\n this.webSocket.onerror = () => {\n this.logger.error(\"WebSocket error occurred\");\n const error = new Error(\"WebSocket error occurred\");\n this.handleFatalError(error);\n };\n\n this.webSocket.onclose = (event) => {\n if (this.isRunning) {\n if (event.code === 1008) {\n this.logger.error(\"WebSocket authentication failed\");\n const error = new Error(\n \"WebSocket authentication failed: Invalid or revoked API key\",\n );\n this.handleFatalError(error);\n } else {\n this.logger.warn(\"WebSocket closed unexpectedly:\", event.code);\n const error = new Error(\"WebSocket closed unexpectedly\");\n this.handleFatalError(error);\n }\n } else {\n this.logger.debug(\"WebSocket closed\");\n }\n };\n }\n\n /**\n * Handle non-fatal errors (report but don't stop stream)\n */\n private handleNonFatalError(error: Error): void {\n this.logger.warn(\"Non-fatal error:\", error.message);\n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Handle fatal errors (stop stream and report)\n */\n private async handleFatalError(error: unknown): Promise<void> {\n this.logger.error(\"Fatal error:\", error);\n await this.cleanup();\n this.isRunning = false;\n\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n\n if (this.config.onError) {\n this.config.onError(normalizedError);\n }\n }\n\n /**\n * Update the prompt/task while stream is running\n */\n async updatePrompt(prompt: string): Promise<void> {\n if (!this.isRunning || !this.streamId) {\n throw new Error(\"Vision stream not running\");\n }\n\n if (!prompt || typeof prompt !== \"string\") {\n throw new ValidationError(\"prompt must be a non-empty string\");\n }\n\n this.logger.debug(\"Updating prompt\");\n await this.client.updatePrompt(this.streamId, prompt);\n this.logger.info(\"Prompt updated\");\n }\n\n /**\n * Stop the vision stream and clean up resources\n */\n async stop(): Promise<void> {\n this.logger.info(\"Stopping stream\");\n await this.cleanup();\n this.isRunning = false;\n }\n\n /**\n * Submit feedback for the stream\n */\n async submitFeedback(feedback: {\n rating: number;\n category: string;\n feedback?: string;\n }): Promise<void> {\n if (!this.streamId) {\n throw new Error(\"No active stream\");\n }\n\n if (\n feedback.rating < CONSTRAINTS.RATING.min ||\n feedback.rating > CONSTRAINTS.RATING.max\n ) {\n throw new ValidationError(\n `rating must be between ${CONSTRAINTS.RATING.min} and ${CONSTRAINTS.RATING.max}`,\n );\n }\n\n if (!feedback.category || typeof feedback.category !== \"string\") {\n throw new ValidationError(\"category must be a non-empty string\");\n }\n\n this.logger.debug(\"Submitting feedback\");\n await this.client.submitFeedback(this.streamId, {\n rating: feedback.rating,\n category: feedback.category,\n feedback: feedback.feedback ?? \"\",\n });\n this.logger.info(\"Feedback submitted\");\n }\n\n /**\n * Get the current stream ID\n */\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /**\n * Get the media stream (for displaying video preview)\n */\n getMediaStream(): MediaStream | null {\n return this.mediaStream;\n }\n\n /**\n * Check if the stream is running\n */\n isActive(): boolean {\n return this.isRunning;\n }\n\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleaning up resources\");\n\n if (this.keepaliveInterval) {\n window.clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n\n if (this.webSocket) {\n this.webSocket.close();\n this.webSocket = null;\n }\n\n if (this.peerConnection) {\n this.peerConnection.close();\n this.peerConnection = null;\n }\n\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => track.stop());\n this.mediaStream = null;\n }\n\n if (this.videoElement) {\n this.videoElement.pause();\n URL.revokeObjectURL(this.videoElement.src);\n this.videoElement.remove();\n this.videoElement = null;\n }\n\n this.streamId = null;\n this.logger.debug(\"Cleanup complete\");\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/client/errors.ts","../src/client/client.ts","../src/client/RealtimeVision.ts"],"names":["ValidationError"],"mappings":"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","file":"index.mjs","sourcesContent":["export class ApiError extends Error {\n readonly statusCode?: number;\n readonly requestId?: string;\n readonly details?: any;\n\n constructor(\n message: string,\n statusCode?: number,\n requestId?: string,\n details?: any,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.statusCode = statusCode;\n this.requestId = requestId;\n this.details = details;\n }\n}\n\nexport class UnauthorizedError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 401, requestId);\n this.name = \"UnauthorizedError\";\n }\n}\n\nexport class ValidationError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 422, requestId, details);\n this.name = \"ValidationError\";\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, requestId?: string) {\n super(message, 404, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class NetworkError extends ApiError {\n readonly cause?: Error;\n\n constructor(message: string, cause?: Error) {\n super(message);\n this.name = \"NetworkError\";\n this.cause = cause;\n }\n}\n\nexport class ServerError extends ApiError {\n constructor(message: string, requestId?: string, details?: any) {\n super(message, 500, requestId, details);\n this.name = \"ServerError\";\n }\n}\n","import type {\n StreamCreateRequest,\n StreamCreateResponse,\n KeepaliveResponse,\n StreamConfigResponse,\n FeedbackCreateRequest,\n FeedbackResponse,\n StatusResponse,\n ErrorResponse,\n} from \"./types\";\nimport {\n ApiError,\n ValidationError,\n NotFoundError,\n NetworkError,\n ServerError,\n UnauthorizedError,\n} from \"./errors\";\n\ntype ClientConfig = {\n baseUrl: string;\n apiKey: string;\n};\n\nexport class StreamClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new Error(\"apiKey is required and must be a string\");\n }\n\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const errorData: ErrorResponse = await response.json().catch(() => ({\n error: \"unknown_error\",\n message: response.statusText,\n }));\n\n const message = errorData.message || errorData.error;\n\n if (response.status === 401) {\n throw new UnauthorizedError(\n message || \"Invalid or revoked API key\",\n errorData.request_id,\n );\n }\n if (response.status === 422 || response.status === 400) {\n throw new ValidationError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n if (response.status === 404) {\n throw new NotFoundError(message, errorData.request_id);\n }\n if (response.status >= 500) {\n throw new ServerError(\n message,\n errorData.request_id,\n errorData.details,\n );\n }\n\n throw new ApiError(\n message,\n response.status,\n errorData.request_id,\n errorData.details,\n );\n }\n\n return await response.json();\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof Error) {\n throw new NetworkError(`Network error: ${error.message}`, error);\n }\n\n throw new NetworkError(\"Unknown network error\");\n }\n }\n async createStream(\n request: StreamCreateRequest,\n ): Promise<StreamCreateResponse> {\n return this.request<StreamCreateResponse>(\"/streams\", {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n }\n\n async renewLease(streamId: string): Promise<KeepaliveResponse> {\n return this.request<KeepaliveResponse>(`/streams/${streamId}/keepalive`, {\n method: \"POST\",\n });\n }\n\n async updatePrompt(\n streamId: string,\n prompt: string,\n ): Promise<StreamConfigResponse> {\n return this.request<StreamConfigResponse>(\n `/streams/${streamId}/config/prompt`,\n {\n method: \"PATCH\",\n body: JSON.stringify({ prompt }),\n },\n );\n }\n\n async submitFeedback(\n streamId: string,\n feedback: FeedbackCreateRequest,\n ): Promise<StatusResponse> {\n return this.request<StatusResponse>(`/streams/${streamId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify(feedback),\n });\n }\n\n async getAllFeedback(): Promise<FeedbackResponse[]> {\n return this.request<FeedbackResponse[]>(\"/streams/feedback\", {\n method: \"GET\",\n });\n }\n\n connectWebSocket(streamId: string): WebSocket {\n const wsUrl = this.baseUrl\n .replace(\"http://\", \"ws://\")\n .replace(\"https://\", \"wss://\");\n return new WebSocket(`${wsUrl}/ws/streams/${streamId}`);\n }\n\n /**\n * Health check endpoint (for testing, uses internal port if available)\n * Note: This endpoint may not be available via the main API\n */\n async healthCheck(): Promise<string> {\n const url = `${this.baseUrl}/healthz`;\n const response = await fetch(url, {\n credentials: \"include\",\n });\n return response.text();\n }\n}\n","import { StreamClient } from \"./client\";\n\nimport {\n type StreamInferenceResult,\n type StreamProcessingConfig,\n type StreamSource,\n} from \"./types\";\n\n/**\n * Default configuration values for RealtimeVision\n */\nconst DEFAULTS = {\n BACKEND: \"overshoot\" as const,\n MODEL: \"Qwen/Qwen3-VL-30B-A3B-Instruct\",\n SOURCE: { type: \"camera\", cameraFacing: \"environment\" } as const,\n SAMPLING_RATIO: 0.1,\n CLIP_LENGTH_SECONDS: 1.0,\n DELAY_SECONDS: 1.0,\n FALLBACK_FPS: 30,\n ICE_SERVERS: [\n {\n urls: \"turn:turn.overshoot.ai:3478?transport=udp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turn:turn.overshoot.ai:3478?transport=tcp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turns:turn.overshoot.ai:443?transport=udp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n {\n urls: \"turns:turn.overshoot.ai:443?transport=tcp\",\n username: \"1769538895:c66a907c-61f4-4ec2-93a6-9d6b932776bb\",\n credential: \"Fu9L4CwyYZvsOLc+23psVAo3i/Y=\",\n },\n ] as RTCIceServer[],\n} as const;\n\nconsole.log(\"defaults\", DEFAULTS);\n\n/**\n * Validation constraints\n */\nconst CONSTRAINTS = {\n SAMPLING_RATIO: { min: 0, max: 1 },\n FPS: { min: 1, max: 120 },\n CLIP_LENGTH_SECONDS: { min: 0.1, max: 60 },\n DELAY_SECONDS: { min: 0, max: 60 },\n RATING: { min: 1, max: 5 },\n} as const;\n\n/**\n * Logger utility for controlled logging\n */\nclass Logger {\n private debugEnabled: boolean;\n\n constructor(debugEnabled: boolean = false) {\n this.debugEnabled = debugEnabled;\n }\n\n debug(...args: any[]): void {\n if (this.debugEnabled) {\n console.log(\"[RealtimeVision Debug]\", ...args);\n }\n }\n\n info(...args: any[]): void {\n console.log(\"[RealtimeVision]\", ...args);\n }\n\n warn(...args: any[]): void {\n console.warn(\"[RealtimeVision]\", ...args);\n }\n\n error(...args: any[]): void {\n console.error(\"[RealtimeVision]\", ...args);\n }\n}\n\nexport interface RealtimeVisionConfig {\n /**\n * Base URL for the API (e.g., \"https://api.example.com\")\n */\n apiUrl: string;\n\n /**\n * API key for authentication\n * Required for all API requests\n */\n apiKey: string;\n\n /**\n * The prompt/task to run on window segments of the stream.\n * This runs continuously (at a defined window interval).\n *\n * Examples:\n * - \"Read any visible text\"\n * - \"Detect objects and return as JSON array\"\n * - \"Describe facial expression\"\n */\n prompt: string;\n\n /**\n * Video source configuration\n * Defaults to camera with environment facing if not specified\n */\n source?: StreamSource;\n\n /**\n * Model backend to use\n */\n backend?: \"overshoot\";\n\n /**\n * Model name to use for inference\n */\n model?: string;\n\n /**\n * Optional JSON schema for structured output\n */\n outputSchema?: Record<string, any>;\n\n /**\n * Called when a new inference result arrives (~1 per second)\n */\n onResult: (result: StreamInferenceResult) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Custom processing configuration\n * All fields are optional and will use defaults if not provided\n */\n processing?: {\n /**\n * Sampling ratio (0-1). Controls what fraction of frames are processed.\n */\n sampling_ratio?: number;\n /**\n * Frames per second (1-120)\n */\n fps?: number;\n /**\n * Clip length in seconds (0.1-60)\n */\n clip_length_seconds?: number;\n /**\n * Delay in seconds (0-60)\n */\n delay_seconds?: number;\n };\n\n /**\n * ICE servers for WebRTC connection\n * If not provided, uses default TURN servers\n */\n iceServers?: RTCIceServer[];\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n}\n\nclass ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport class RealtimeVision {\n private config: RealtimeVisionConfig;\n private client: StreamClient;\n private logger: Logger;\n\n private mediaStream: MediaStream | null = null;\n private peerConnection: RTCPeerConnection | null = null;\n private webSocket: WebSocket | null = null;\n private streamId: string | null = null;\n private keepaliveInterval: number | null = null;\n private videoElement: HTMLVideoElement | null = null;\n\n private isRunning = false;\n\n constructor(config: RealtimeVisionConfig) {\n this.validateConfig(config);\n this.config = config;\n this.logger = new Logger(config.debug ?? false);\n this.client = new StreamClient({\n baseUrl: config.apiUrl,\n apiKey: config.apiKey,\n });\n }\n\n /**\n * Validate configuration values\n */\n private validateConfig(config: RealtimeVisionConfig): void {\n if (!config.apiUrl || typeof config.apiUrl !== \"string\") {\n throw new ValidationError(\"apiUrl is required and must be a string\");\n }\n\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new ValidationError(\"apiKey is required and must be a string\");\n }\n\n if (!config.prompt || typeof config.prompt !== \"string\") {\n throw new ValidationError(\"prompt is required and must be a string\");\n }\n\n if (config.source) {\n if (config.source.type === \"camera\") {\n if (\n config.source.cameraFacing !== \"user\" &&\n config.source.cameraFacing !== \"environment\"\n ) {\n throw new ValidationError(\n 'cameraFacing must be \"user\" or \"environment\"',\n );\n }\n } else if (config.source.type === \"video\") {\n if (!(config.source.file instanceof File)) {\n throw new ValidationError(\"video source must provide a File object\");\n }\n } else {\n throw new ValidationError('source.type must be \"camera\" or \"video\"');\n }\n }\n\n if (config.processing?.sampling_ratio !== undefined) {\n const ratio = config.processing.sampling_ratio;\n if (\n ratio < CONSTRAINTS.SAMPLING_RATIO.min ||\n ratio > CONSTRAINTS.SAMPLING_RATIO.max\n ) {\n throw new ValidationError(\n `sampling_ratio must be between ${CONSTRAINTS.SAMPLING_RATIO.min} and ${CONSTRAINTS.SAMPLING_RATIO.max}`,\n );\n }\n }\n\n if (config.processing?.fps !== undefined) {\n const fps = config.processing.fps;\n if (fps < CONSTRAINTS.FPS.min || fps > CONSTRAINTS.FPS.max) {\n throw new ValidationError(\n `fps must be between ${CONSTRAINTS.FPS.min} and ${CONSTRAINTS.FPS.max}`,\n );\n }\n }\n\n if (config.processing?.clip_length_seconds !== undefined) {\n const clip = config.processing.clip_length_seconds;\n if (\n clip < CONSTRAINTS.CLIP_LENGTH_SECONDS.min ||\n clip > CONSTRAINTS.CLIP_LENGTH_SECONDS.max\n ) {\n throw new ValidationError(\n `clip_length_seconds must be between ${CONSTRAINTS.CLIP_LENGTH_SECONDS.min} and ${CONSTRAINTS.CLIP_LENGTH_SECONDS.max}`,\n );\n }\n }\n\n if (config.processing?.delay_seconds !== undefined) {\n const delay = config.processing.delay_seconds;\n if (\n delay < CONSTRAINTS.DELAY_SECONDS.min ||\n delay > CONSTRAINTS.DELAY_SECONDS.max\n ) {\n throw new ValidationError(\n `delay_seconds must be between ${CONSTRAINTS.DELAY_SECONDS.min} and ${CONSTRAINTS.DELAY_SECONDS.max}`,\n );\n }\n }\n }\n\n /**\n * Create media stream from the configured source\n */\n private async createMediaStream(source: StreamSource): Promise<MediaStream> {\n this.logger.debug(\"Creating media stream from source:\", source.type);\n\n switch (source.type) {\n case \"camera\":\n return await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: source.cameraFacing } },\n audio: false,\n });\n\n case \"video\":\n const video = document.createElement(\"video\");\n video.src = URL.createObjectURL(source.file);\n video.muted = true;\n video.loop = true;\n video.playsInline = true;\n\n this.logger.debug(\"Loading video file:\", source.file.name);\n\n // Wait for video to be ready\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Video loading timeout after 10 seconds\"));\n }, 10000);\n\n video.onloadedmetadata = () => {\n clearTimeout(timeout);\n this.logger.debug(\"Video metadata loaded\");\n resolve();\n };\n\n video.onerror = (e) => {\n clearTimeout(timeout);\n this.logger.error(\"Video loading error:\", e);\n reject(new Error(\"Failed to load video file\"));\n };\n\n if (video.readyState >= 1) {\n clearTimeout(timeout);\n resolve();\n }\n });\n\n await video.play();\n this.logger.debug(\"Video playback started\");\n\n const stream = video.captureStream();\n if (!stream) {\n throw new Error(\"Failed to capture video stream\");\n }\n\n const videoTracks = stream.getVideoTracks();\n if (videoTracks.length === 0) {\n throw new Error(\"Video stream has no video tracks\");\n }\n\n this.videoElement = video;\n return stream;\n\n default:\n throw new Error(`Unknown source type: ${(source as any).type}`);\n }\n }\n\n /**\n * Get FPS from media stream\n */\n private async getStreamFps(\n stream: MediaStream | null,\n source: StreamSource,\n ): Promise<number> {\n if (!stream) {\n this.logger.warn(\"Stream is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTracks = stream.getVideoTracks();\n if (!videoTracks || videoTracks.length === 0) {\n this.logger.warn(\"No video tracks found, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n const videoTrack = videoTracks[0];\n if (!videoTrack) {\n this.logger.warn(\"First video track is null, using fallback FPS\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n // For camera sources, get FPS from track settings\n if (source.type === \"camera\") {\n const settings = videoTrack.getSettings();\n const fps = settings.frameRate ?? DEFAULTS.FALLBACK_FPS;\n this.logger.debug(\"Detected camera FPS:\", fps);\n return fps;\n }\n\n // For video file sources, try to get FPS from video element\n if (source.type === \"video\" && this.videoElement) {\n await new Promise<void>((resolve, reject) => {\n if (this.videoElement!.readyState >= 1) {\n resolve();\n } else {\n this.videoElement!.onloadedmetadata = () => resolve();\n this.videoElement!.onerror = () =>\n reject(new Error(\"Failed to load video metadata\"));\n }\n });\n\n // For video files, use fallback FPS or user-specified config\n this.logger.debug(\"Using fallback FPS for video file\");\n return DEFAULTS.FALLBACK_FPS;\n }\n\n return DEFAULTS.FALLBACK_FPS;\n }\n\n /**\n * Get processing configuration with defaults applied\n */\n private getProcessingConfig(detectedFps: number): StreamProcessingConfig {\n const userProcessing = this.config.processing || {};\n\n return {\n sampling_ratio: userProcessing.sampling_ratio ?? DEFAULTS.SAMPLING_RATIO,\n fps: userProcessing.fps ?? detectedFps,\n clip_length_seconds:\n userProcessing.clip_length_seconds ?? DEFAULTS.CLIP_LENGTH_SECONDS,\n delay_seconds: userProcessing.delay_seconds ?? DEFAULTS.DELAY_SECONDS,\n };\n }\n\n /**\n * Get the effective source configuration\n */\n private getSource(): StreamSource {\n return this.config.source ?? DEFAULTS.SOURCE;\n }\n\n /**\n * Start the vision stream\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Vision stream already running\");\n }\n\n try {\n const source = this.getSource();\n this.logger.debug(\"Starting stream with source type:\", source.type);\n\n if (source.type === \"video\") {\n this.logger.debug(\"Video file:\", {\n name: source.file.name,\n size: source.file.size,\n type: source.file.type,\n });\n\n if (!source.file || !(source.file instanceof File)) {\n throw new Error(\"Invalid video file\");\n }\n }\n\n // Create media stream\n this.mediaStream = await this.createMediaStream(source);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n if (!videoTrack) {\n throw new Error(\"No video track available\");\n }\n\n // Get FPS for the stream\n const detectedFps = await this.getStreamFps(this.mediaStream, source);\n\n // Set up WebRTC peer connection\n const iceServers = this.config.iceServers ?? DEFAULTS.ICE_SERVERS;\n this.logger.debug(\"Creating peer connection with ICE servers\");\n this.peerConnection = new RTCPeerConnection({ iceServers });\n\n // Set up ICE logging\n this.peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this.logger.debug(\"ICE candidate:\", {\n type: event.candidate.type,\n protocol: event.candidate.protocol,\n });\n } else {\n this.logger.debug(\"ICE gathering complete\");\n }\n };\n\n this.peerConnection.oniceconnectionstatechange = () => {\n this.logger.debug(\n \"ICE connection state:\",\n this.peerConnection?.iceConnectionState,\n );\n };\n\n this.peerConnection.addTrack(videoTrack, this.mediaStream);\n\n // Create and set local offer\n const offer = await this.peerConnection.createOffer();\n await this.peerConnection.setLocalDescription(offer);\n\n if (!this.peerConnection.localDescription) {\n throw new Error(\"Failed to create local description\");\n }\n\n // Create stream on server\n this.logger.debug(\"Creating stream on server\");\n const response = await this.client.createStream({\n webrtc: {\n type: \"offer\",\n sdp: this.peerConnection.localDescription.sdp,\n },\n processing: this.getProcessingConfig(detectedFps),\n inference: {\n prompt: this.config.prompt,\n backend: this.config.backend ?? DEFAULTS.BACKEND,\n model: this.config.model ?? DEFAULTS.MODEL,\n output_schema_json: this.config.outputSchema,\n },\n });\n\n this.logger.debug(\"Backend response received:\", {\n stream_id: response.stream_id,\n has_turn_servers: !!response.turn_servers,\n });\n\n // Set remote description\n await this.peerConnection.setRemoteDescription(response.webrtc);\n\n this.streamId = response.stream_id;\n this.logger.info(\"Stream started:\", this.streamId);\n\n // Set up keepalive\n this.setupKeepalive(response.lease?.ttl_seconds);\n\n // Connect WebSocket for results\n this.setupWebSocket(response.stream_id);\n\n this.isRunning = true;\n } catch (error) {\n await this.handleFatalError(error);\n throw error;\n }\n }\n\n /**\n * Set up keepalive interval with error handling\n */\n private setupKeepalive(ttlSeconds: number | undefined): void {\n if (!ttlSeconds) {\n return;\n }\n\n const intervalMs = (ttlSeconds / 2) * 1000;\n this.logger.debug(\"Setting up keepalive with interval:\", intervalMs, \"ms\");\n\n this.keepaliveInterval = window.setInterval(async () => {\n try {\n if (this.streamId) {\n await this.client.renewLease(this.streamId);\n this.logger.debug(\"Lease renewed\");\n }\n } catch (error) {\n this.logger.error(\"Keepalive failed:\", error);\n const keepaliveError = new Error(\n `Keepalive failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n await this.handleFatalError(keepaliveError);\n }\n }, intervalMs);\n }\n\n /**\n * Set up WebSocket connection with error handling\n */\n private setupWebSocket(streamId: string): void {\n this.logger.debug(\"Connecting WebSocket for stream:\", streamId);\n this.webSocket = this.client.connectWebSocket(streamId);\n\n this.webSocket.onopen = () => {\n this.logger.debug(\"WebSocket connected\");\n if (this.webSocket) {\n this.webSocket.send(JSON.stringify({ api_key: this.config.apiKey }));\n }\n };\n\n this.webSocket.onmessage = (event) => {\n try {\n const result: StreamInferenceResult = JSON.parse(event.data);\n this.config.onResult(result);\n } catch (error) {\n const parseError = new Error(\n `Failed to parse WebSocket message: ${error instanceof Error ? error.message : String(error)}`,\n );\n this.handleNonFatalError(parseError);\n }\n };\n\n this.webSocket.onerror = () => {\n this.logger.error(\"WebSocket error occurred\");\n const error = new Error(\"WebSocket error occurred\");\n this.handleFatalError(error);\n };\n\n this.webSocket.onclose = (event) => {\n if (this.isRunning) {\n if (event.code === 1008) {\n this.logger.error(\"WebSocket authentication failed\");\n const error = new Error(\n \"WebSocket authentication failed: Invalid or revoked API key\",\n );\n this.handleFatalError(error);\n } else {\n this.logger.warn(\"WebSocket closed unexpectedly:\", event.code);\n const error = new Error(\"WebSocket closed unexpectedly\");\n this.handleFatalError(error);\n }\n } else {\n this.logger.debug(\"WebSocket closed\");\n }\n };\n }\n\n /**\n * Handle non-fatal errors (report but don't stop stream)\n */\n private handleNonFatalError(error: Error): void {\n this.logger.warn(\"Non-fatal error:\", error.message);\n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Handle fatal errors (stop stream and report)\n */\n private async handleFatalError(error: unknown): Promise<void> {\n this.logger.error(\"Fatal error:\", error);\n await this.cleanup();\n this.isRunning = false;\n\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n\n if (this.config.onError) {\n this.config.onError(normalizedError);\n }\n }\n\n /**\n * Update the prompt/task while stream is running\n */\n async updatePrompt(prompt: string): Promise<void> {\n if (!this.isRunning || !this.streamId) {\n throw new Error(\"Vision stream not running\");\n }\n\n if (!prompt || typeof prompt !== \"string\") {\n throw new ValidationError(\"prompt must be a non-empty string\");\n }\n\n this.logger.debug(\"Updating prompt\");\n await this.client.updatePrompt(this.streamId, prompt);\n this.logger.info(\"Prompt updated\");\n }\n\n /**\n * Stop the vision stream and clean up resources\n */\n async stop(): Promise<void> {\n this.logger.info(\"Stopping stream\");\n await this.cleanup();\n this.isRunning = false;\n }\n\n /**\n * Submit feedback for the stream\n */\n async submitFeedback(feedback: {\n rating: number;\n category: string;\n feedback?: string;\n }): Promise<void> {\n if (!this.streamId) {\n throw new Error(\"No active stream\");\n }\n\n if (\n feedback.rating < CONSTRAINTS.RATING.min ||\n feedback.rating > CONSTRAINTS.RATING.max\n ) {\n throw new ValidationError(\n `rating must be between ${CONSTRAINTS.RATING.min} and ${CONSTRAINTS.RATING.max}`,\n );\n }\n\n if (!feedback.category || typeof feedback.category !== \"string\") {\n throw new ValidationError(\"category must be a non-empty string\");\n }\n\n this.logger.debug(\"Submitting feedback\");\n await this.client.submitFeedback(this.streamId, {\n rating: feedback.rating,\n category: feedback.category,\n feedback: feedback.feedback ?? \"\",\n });\n this.logger.info(\"Feedback submitted\");\n }\n\n /**\n * Get the current stream ID\n */\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /**\n * Get the media stream (for displaying video preview)\n */\n getMediaStream(): MediaStream | null {\n return this.mediaStream;\n }\n\n /**\n * Check if the stream is running\n */\n isActive(): boolean {\n return this.isRunning;\n }\n\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleaning up resources\");\n\n if (this.keepaliveInterval) {\n window.clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n\n if (this.webSocket) {\n this.webSocket.close();\n this.webSocket = null;\n }\n\n if (this.peerConnection) {\n this.peerConnection.close();\n this.peerConnection = null;\n }\n\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => track.stop());\n this.mediaStream = null;\n }\n\n if (this.videoElement) {\n this.videoElement.pause();\n URL.revokeObjectURL(this.videoElement.src);\n this.videoElement.remove();\n this.videoElement = null;\n }\n\n this.streamId = null;\n this.logger.debug(\"Cleanup complete\");\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overshoot/sdk",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -45,7 +45,7 @@
45
45
  "license": "MIT",
46
46
  "repository": {
47
47
  "type": "git",
48
- "url": "https://github.com/Overshoot-ai/overshoot-js-sdk.git"
48
+ "url": "git+https://github.com/Overshoot-ai/overshoot-js-sdk.git"
49
49
  },
50
50
  "bugs": {
51
51
  "url": "https://github.com/Overshoot-ai/overshoot-js-sdk/issues"
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Overshoot
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.