@overshoot/sdk 0.1.0-alpha.2 → 0.1.0-alpha.4

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,19 +1,19 @@
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
+ > **Warning: 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
 
7
7
  ## Installation
8
8
 
9
9
  ```bash
10
- npm install overshoot@alpha
10
+ npm install @overshoot/sdk@alpha
11
11
  ```
12
12
 
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
@@ -21,10 +21,10 @@ npm install overshoot@0.1.0-alpha.0
21
21
  ### Camera Source
22
22
 
23
23
  ```typescript
24
- import { RealtimeVision } from "overshoot";
24
+ import { RealtimeVision } from "@overshoot/sdk";
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: {
@@ -56,6 +56,8 @@ const vision = new RealtimeVision({
56
56
  await vision.start();
57
57
  ```
58
58
 
59
+ > **Note:** Video files automatically loop continuously until you call `stop()`.
60
+
59
61
  ## Configuration
60
62
 
61
63
  ### RealtimeVisionConfig
@@ -70,20 +72,20 @@ interface RealtimeVisionConfig {
70
72
 
71
73
  // Optional
72
74
  source?: StreamSource; // Video source (default: environment-facing camera)
73
- backend?: "overshoot" | "gemini"; // Model backend (default: "overshoot")
74
- model?: string; // Model name (default: "Qwen/Qwen3-VL-30B-A3B-Instruct")
75
+ backend?: "overshoot"; // Model backend (default: "overshoot")
76
+ model?: string; // Model name (see Available Models below)
75
77
  outputSchema?: Record<string, any>; // JSON schema for structured output
76
78
  onError?: (error: Error) => void;
77
79
  debug?: boolean; // Enable debug logging (default: false)
78
80
 
79
81
  processing?: {
80
- fps?: number; // Actual source frames per second (1-120)
82
+ fps?: number; // Source frames per second (1-120, auto-detected for cameras)
81
83
  sampling_ratio?: number; // Fraction of frames to process (0-1, default: 0.1)
82
- clip_length_seconds?: number; // Size of each clip that the VLM infers on (0.1-60, default: 1.0)
83
- delay_seconds?: number; // Shift between clips (0-60, default: 1.0)
84
+ clip_length_seconds?: number; // Duration of each clip sent to the model (0.1-60, default: 1.0)
85
+ delay_seconds?: number; // Interval between inference runs (0-60, default: 1.0)
84
86
  };
85
87
 
86
- iceServers?: RTCIceServer[]; // Custom WebRTC ICE servers
88
+ iceServers?: RTCIceServer[]; // Custom WebRTC ICE servers (uses Overshoot TURN servers by default, see RealtimeVision.ts)
87
89
  }
88
90
  ```
89
91
 
@@ -95,6 +97,84 @@ type StreamSource =
95
97
  | { type: "video"; file: File };
96
98
  ```
97
99
 
100
+ ### Available Models
101
+
102
+ | Model | Description |
103
+ | -------------------------------- | ------------------------------------------------------------------------------------ |
104
+ | `Qwen/Qwen3-VL-30B-A3B-Instruct` | Default. Very fast and performant general-purpose vision-language model. |
105
+ | `Qwen/Qwen3-VL-8B-Instruct` | Similar latency to 30B. Particularly good at OCR and text extraction tasks. |
106
+ | `OpenGVLab/InternVL3_5-30B-A3B` | Excels at capturing visual detail. More verbose output, higher latency. |
107
+
108
+ ### Processing Parameters Explained
109
+
110
+ The processing parameters control how video frames are sampled and sent to the model:
111
+
112
+ - **`fps`**: The frame rate of your video source. Auto-detected for camera streams; defaults to 30 for video files.
113
+ - **`sampling_ratio`**: What fraction of frames to include in each clip (0.1 = 10% of frames).
114
+ - **`clip_length_seconds`**: Duration of video captured for each inference (e.g., 1.0 = 1 second of video).
115
+ - **`delay_seconds`**: How often inference runs (e.g., 1.0 = one inference per second).
116
+
117
+ **Example:** With `fps=30`, `clip_length_seconds=1.0`, `sampling_ratio=0.1`:
118
+
119
+ - Each clip captures 1 second of video (30 frames at 30fps)
120
+ - 10% of frames are sampled = 3 frames sent to the model
121
+ - If `delay_seconds=1.0`, you get ~1 inference result per second
122
+
123
+ #### Configuration by Use Case
124
+
125
+ Different applications need different processing configurations:
126
+
127
+ **Real-time tracking** (low latency, frequent updates):
128
+
129
+ ```typescript
130
+ processing: {
131
+ sampling_ratio: 0.7,
132
+ clip_length_seconds: 0.5,
133
+ delay_seconds: 0.3,
134
+ }
135
+ ```
136
+
137
+ **Event detection** (monitoring for specific occurrences):
138
+
139
+ ```typescript
140
+ processing: {
141
+ sampling_ratio: 0.2,
142
+ clip_length_seconds: 5.0,
143
+ delay_seconds: 5.0,
144
+ }
145
+ ```
146
+
147
+ ### Structured Output (JSON Schema)
148
+
149
+ Use `outputSchema` to constrain the model's output to a specific JSON structure. The schema follows [JSON Schema](https://json-schema.org/) specification.
150
+
151
+ ```typescript
152
+ const vision = new RealtimeVision({
153
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
154
+ apiKey: "your-api-key",
155
+ prompt: "Detect objects and return structured data",
156
+ outputSchema: {
157
+ type: "object",
158
+ properties: {
159
+ objects: {
160
+ type: "array",
161
+ items: { type: "string" },
162
+ },
163
+ count: { type: "integer" },
164
+ },
165
+ required: ["objects", "count"],
166
+ },
167
+ onResult: (result) => {
168
+ const data = JSON.parse(result.result);
169
+ console.log(`Found ${data.count} objects:`, data.objects);
170
+ },
171
+ });
172
+ ```
173
+
174
+ The model will return valid JSON matching your schema. If the model cannot produce valid output, `result.ok` will be `false` and `result.error` will contain details.
175
+
176
+ > **Note:** `result.result` is always a string. When using `outputSchema`, you must parse it with `JSON.parse()`.
177
+
98
178
  ## API Methods
99
179
 
100
180
  ```typescript
@@ -106,18 +186,203 @@ await vision.stop(); // Stop and cleanup resources
106
186
  await vision.updatePrompt(newPrompt); // Update task while running
107
187
 
108
188
  // State access
109
- vision.getMediaStream(); // Get MediaStream for video preview
110
- vision.getStreamId(); // Get current stream ID
189
+ vision.getMediaStream(); // Get MediaStream for video preview (null if not started)
190
+ vision.getStreamId(); // Get current stream ID (null if not started)
111
191
  vision.isActive(); // Check if stream is running
112
192
  ```
113
193
 
194
+ ## Stream Lifecycle
195
+
196
+ ### Keepalive
197
+
198
+ Streams have a server-side lease (typically 300 seconds). The SDK automatically sends keepalive requests to maintain the connection. If the keepalive fails (e.g., network issues), the stream will stop and `onError` will be called.
199
+
200
+ You don't need to manage keepalives manually - just call `start()` and the SDK handles the rest.
201
+
202
+ ### State and Memory
203
+
204
+ The SDK does not maintain memory or state between inference calls - each frame clip is processed independently. If your application needs to track state over time (e.g., counting repetitions, detecting transitions), implement this in your `onResult` callback:
205
+
206
+ ```typescript
207
+ let lastPosition = "up";
208
+ let repCount = 0;
209
+
210
+ const vision = new RealtimeVision({
211
+ // ...config
212
+ onResult: (result) => {
213
+ const data = JSON.parse(result.result);
214
+
215
+ // Track state transitions externally
216
+ if (lastPosition === "down" && data.position === "up") {
217
+ repCount++;
218
+ }
219
+ lastPosition = data.position;
220
+ },
221
+ });
222
+ ```
223
+
224
+ For result deduplication (e.g., avoiding repeated announcements), track previous results and implement cooldown logic in your application code.
225
+
226
+ ## Prompt Engineering
227
+
228
+ Prompt quality significantly affects results. Here are some tips:
229
+
230
+ **Be specific about output format:**
231
+
232
+ ```typescript
233
+ prompt: "Count the people visible. Return only a number.";
234
+ ```
235
+
236
+ **Include examples for complex tasks:**
237
+
238
+ ```typescript
239
+ prompt: `Describe the primary action happening. Examples:
240
+ - "Person walking left"
241
+ - "Car turning right"
242
+ - "Dog sitting still"`;
243
+ ```
244
+
245
+ **Request minimal output for lower latency:**
246
+
247
+ ```typescript
248
+ prompt: "Is there a person in frame? Answer only 'yes' or 'no'.";
249
+ ```
250
+
251
+ **Provide context when needed:**
252
+
253
+ ```typescript
254
+ prompt: `You are monitoring a ${locationName}. Alert if you see: ${alertConditions.join(", ")}.`;
255
+ ```
256
+
257
+ **Use JSON schema for structured data:**
258
+
259
+ ```typescript
260
+ prompt: "Analyze the scene",
261
+ outputSchema: {
262
+ type: "object",
263
+ properties: {
264
+ description: { type: "string" },
265
+ alert: { type: "boolean" }
266
+ },
267
+ required: ["description", "alert"]
268
+ }
269
+ ```
270
+
271
+ > **Note:** Prompt effectiveness varies by model. Test different approaches to find what works best for your use case.
272
+
273
+ ## React Integration
274
+
275
+ When using the SDK in React applications, ensure proper cleanup:
276
+
277
+ ```typescript
278
+ import { useEffect, useRef, useState } from "react";
279
+ import { RealtimeVision } from "@overshoot/sdk";
280
+
281
+ function VisionComponent() {
282
+ const visionRef = useRef<RealtimeVision | null>(null);
283
+ const videoRef = useRef<HTMLVideoElement>(null);
284
+ const [isRunning, setIsRunning] = useState(false);
285
+
286
+ const startVision = async () => {
287
+ const vision = new RealtimeVision({
288
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
289
+ apiKey: "your-api-key",
290
+ prompt: "Describe what you see",
291
+ onResult: (result) => {
292
+ console.log(result.result);
293
+ },
294
+ onError: (error) => {
295
+ console.error("Vision error:", error);
296
+ setIsRunning(false);
297
+ },
298
+ });
299
+
300
+ await vision.start();
301
+ visionRef.current = vision;
302
+ setIsRunning(true);
303
+
304
+ // Attach stream to video element for preview
305
+ const stream = vision.getMediaStream();
306
+ if (stream && videoRef.current) {
307
+ videoRef.current.srcObject = stream;
308
+ videoRef.current.play().catch(console.error);
309
+ }
310
+ };
311
+
312
+ // Cleanup on unmount
313
+ useEffect(() => {
314
+ return () => {
315
+ visionRef.current?.stop();
316
+ };
317
+ }, []);
318
+
319
+ return (
320
+ <div>
321
+ <video ref={videoRef} autoPlay playsInline muted />
322
+ <button onClick={startVision} disabled={isRunning}>
323
+ Start
324
+ </button>
325
+ <button onClick={() => visionRef.current?.stop()} disabled={!isRunning}>
326
+ Stop
327
+ </button>
328
+ </div>
329
+ );
330
+ }
331
+ ```
332
+
333
+ ## Advanced: Custom Video Sources with StreamClient
334
+
335
+ For advanced use cases like streaming from a canvas, screen capture, or other custom sources, use `StreamClient` directly:
336
+
337
+ ```typescript
338
+ import { StreamClient } from "@overshoot/sdk";
339
+
340
+ const client = new StreamClient({
341
+ baseUrl: "https://cluster1.overshoot.ai/api/v0.2",
342
+ apiKey: "your-api-key",
343
+ });
344
+
345
+ // Get stream from any source (canvas, screen capture, etc.)
346
+ const canvas = document.querySelector("canvas");
347
+ const stream = canvas.captureStream(30);
348
+ const videoTrack = stream.getVideoTracks()[0];
349
+
350
+ // Set up WebRTC connection
351
+ const peerConnection = new RTCPeerConnection({ iceServers: [...] }); // See default ice servers in RealtimeVison.ts file
352
+ peerConnection.addTrack(videoTrack, stream);
353
+
354
+ const offer = await peerConnection.createOffer();
355
+ await peerConnection.setLocalDescription(offer);
356
+
357
+ // Create stream on server
358
+ const response = await client.createStream({
359
+ webrtc: { type: "offer", sdp: peerConnection.localDescription.sdp },
360
+ processing: { sampling_ratio: 0.5, fps: 30, clip_length_seconds: 1.0, delay_seconds: 1.0 },
361
+ inference: {
362
+ prompt: "Analyze the content",
363
+ backend: "overshoot",
364
+ model: "Qwen/Qwen3-VL-30B-A3B-Instruct",
365
+ },
366
+ });
367
+
368
+ await peerConnection.setRemoteDescription(response.webrtc);
369
+
370
+ // Connect WebSocket for results
371
+ const ws = client.connectWebSocket(response.stream_id);
372
+ ws.onopen = () => ws.send(JSON.stringify({ api_key: "your-api-key" }));
373
+ ws.onmessage = (event) => {
374
+ const result = JSON.parse(event.data);
375
+ console.log("Result:", result);
376
+ };
377
+ ```
378
+
114
379
  ## Examples
115
380
 
116
381
  ### Object Detection with Structured Output
117
382
 
118
383
  ```typescript
119
384
  const vision = new RealtimeVision({
120
- apiUrl: "https://api.overshoot.ai",
385
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
121
386
  apiKey: "your-api-key",
122
387
  prompt: "Detect objects and return JSON: {objects: string[], count: number}",
123
388
  outputSchema: {
@@ -141,7 +406,7 @@ await vision.start();
141
406
 
142
407
  ```typescript
143
408
  const vision = new RealtimeVision({
144
- apiUrl: "https://api.overshoot.ai",
409
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
145
410
  apiKey: "your-api-key",
146
411
  prompt: "Read all visible text in the image",
147
412
  onResult: (result) => {
@@ -152,31 +417,11 @@ const vision = new RealtimeVision({
152
417
  await vision.start();
153
418
  ```
154
419
 
155
- ### Video Preview Display
156
-
157
- ```typescript
158
- const vision = new RealtimeVision({
159
- apiUrl: "https://api.overshoot.ai",
160
- apiKey: "your-api-key",
161
- prompt: "Describe what you see",
162
- onResult: (result) => console.log(result.result),
163
- });
164
-
165
- await vision.start();
166
-
167
- // Attach to video element for preview
168
- const videoElement = document.querySelector("video");
169
- const stream = vision.getMediaStream();
170
- if (stream) {
171
- videoElement.srcObject = stream;
172
- }
173
- ```
174
-
175
420
  ### Dynamic Prompt Updates
176
421
 
177
422
  ```typescript
178
423
  const vision = new RealtimeVision({
179
- apiUrl: "https://api.overshoot.ai",
424
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
180
425
  apiKey: "your-api-key",
181
426
  prompt: "Count people",
182
427
  onResult: (result) => console.log(result.result),
@@ -192,7 +437,7 @@ await vision.updatePrompt("Detect vehicles instead");
192
437
 
193
438
  ```typescript
194
439
  const vision = new RealtimeVision({
195
- apiUrl: "https://api.overshoot.ai",
440
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
196
441
  apiKey: "your-api-key",
197
442
  prompt: "Detect objects",
198
443
  debug: true, // Enable detailed logging
@@ -207,7 +452,7 @@ await vision.start();
207
452
 
208
453
  ```typescript
209
454
  const vision = new RealtimeVision({
210
- apiUrl: "https://api.overshoot.ai",
455
+ apiUrl: "https://cluster1.overshoot.ai/api/v0.2",
211
456
  apiKey: "your-api-key",
212
457
  prompt: "Detect objects",
213
458
  onResult: (result) => {
@@ -243,10 +488,10 @@ The `onResult` callback receives a `StreamInferenceResult` object:
243
488
  interface StreamInferenceResult {
244
489
  id: string; // Result ID
245
490
  stream_id: string; // Stream ID
246
- model_backend: "gemini" | "overshoot";
491
+ model_backend: "overshoot";
247
492
  model_name: string; // Model used
248
493
  prompt: string; // Task that was run
249
- result: string; // Model output (text or JSON string)
494
+ result: string; // Model output (always a string - parse JSON if using outputSchema)
250
495
  inference_latency_ms: number; // Model inference time
251
496
  total_latency_ms: number; // End-to-end latency
252
497
  ok: boolean; // Success status
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,26 +58,12 @@ 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;
65
65
  updated_at?: string;
66
66
  };
67
- type FeedbackCreateRequest = {
68
- rating: number;
69
- category: string;
70
- feedback?: string;
71
- };
72
- type FeedbackResponse = {
73
- id: string;
74
- stream_id: string;
75
- rating: number;
76
- category: string;
77
- feedback: string;
78
- created_at?: string;
79
- updated_at?: string;
80
- };
81
67
  type KeepaliveResponse = {
82
68
  status: "ok";
83
69
  stream_id: string;
@@ -105,8 +91,6 @@ declare class StreamClient {
105
91
  createStream(request: StreamCreateRequest): Promise<StreamCreateResponse>;
106
92
  renewLease(streamId: string): Promise<KeepaliveResponse>;
107
93
  updatePrompt(streamId: string, prompt: string): Promise<StreamConfigResponse>;
108
- submitFeedback(streamId: string, feedback: FeedbackCreateRequest): Promise<StatusResponse>;
109
- getAllFeedback(): Promise<FeedbackResponse[]>;
110
94
  connectWebSocket(streamId: string): WebSocket;
111
95
  /**
112
96
  * Health check endpoint (for testing, uses internal port if available)
@@ -143,7 +127,7 @@ interface RealtimeVisionConfig {
143
127
  /**
144
128
  * Model backend to use
145
129
  */
146
- backend?: "gemini" | "overshoot";
130
+ backend?: "overshoot";
147
131
  /**
148
132
  * Model name to use for inference
149
133
  */
@@ -203,6 +187,8 @@ declare class RealtimeVision {
203
187
  private streamId;
204
188
  private keepaliveInterval;
205
189
  private videoElement;
190
+ private canvasElement;
191
+ private canvasAnimationFrameId;
206
192
  private isRunning;
207
193
  constructor(config: RealtimeVisionConfig);
208
194
  /**
@@ -253,14 +239,6 @@ declare class RealtimeVision {
253
239
  * Stop the vision stream and clean up resources
254
240
  */
255
241
  stop(): Promise<void>;
256
- /**
257
- * Submit feedback for the stream
258
- */
259
- submitFeedback(feedback: {
260
- rating: number;
261
- category: string;
262
- feedback?: string;
263
- }): Promise<void>;
264
242
  /**
265
243
  * Get the current stream ID
266
244
  */
@@ -299,4 +277,4 @@ declare class ServerError extends ApiError {
299
277
  constructor(message: string, requestId?: string, details?: any);
300
278
  }
301
279
 
302
- export { ApiError, type ErrorResponse, type FeedbackCreateRequest, type FeedbackResponse, type KeepaliveResponse, NetworkError, NotFoundError, RealtimeVision, type RealtimeVisionConfig, ServerError, type StatusResponse, StreamClient, type StreamClientMeta, type StreamConfigResponse, type StreamCreateRequest, type StreamCreateResponse, type StreamInferenceConfig, type StreamInferenceResult, type StreamProcessingConfig, type StreamSource, UnauthorizedError, ValidationError, type WebRtcAnswer, type WebRtcOffer };
280
+ export { ApiError, type ErrorResponse, type KeepaliveResponse, NetworkError, NotFoundError, RealtimeVision, type RealtimeVisionConfig, ServerError, type StatusResponse, StreamClient, type StreamClientMeta, type StreamConfigResponse, type StreamCreateRequest, type StreamCreateResponse, type StreamInferenceConfig, type StreamInferenceResult, type StreamProcessingConfig, type StreamSource, UnauthorizedError, ValidationError, type WebRtcAnswer, type WebRtcOffer };
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,26 +58,12 @@ 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;
65
65
  updated_at?: string;
66
66
  };
67
- type FeedbackCreateRequest = {
68
- rating: number;
69
- category: string;
70
- feedback?: string;
71
- };
72
- type FeedbackResponse = {
73
- id: string;
74
- stream_id: string;
75
- rating: number;
76
- category: string;
77
- feedback: string;
78
- created_at?: string;
79
- updated_at?: string;
80
- };
81
67
  type KeepaliveResponse = {
82
68
  status: "ok";
83
69
  stream_id: string;
@@ -105,8 +91,6 @@ declare class StreamClient {
105
91
  createStream(request: StreamCreateRequest): Promise<StreamCreateResponse>;
106
92
  renewLease(streamId: string): Promise<KeepaliveResponse>;
107
93
  updatePrompt(streamId: string, prompt: string): Promise<StreamConfigResponse>;
108
- submitFeedback(streamId: string, feedback: FeedbackCreateRequest): Promise<StatusResponse>;
109
- getAllFeedback(): Promise<FeedbackResponse[]>;
110
94
  connectWebSocket(streamId: string): WebSocket;
111
95
  /**
112
96
  * Health check endpoint (for testing, uses internal port if available)
@@ -143,7 +127,7 @@ interface RealtimeVisionConfig {
143
127
  /**
144
128
  * Model backend to use
145
129
  */
146
- backend?: "gemini" | "overshoot";
130
+ backend?: "overshoot";
147
131
  /**
148
132
  * Model name to use for inference
149
133
  */
@@ -203,6 +187,8 @@ declare class RealtimeVision {
203
187
  private streamId;
204
188
  private keepaliveInterval;
205
189
  private videoElement;
190
+ private canvasElement;
191
+ private canvasAnimationFrameId;
206
192
  private isRunning;
207
193
  constructor(config: RealtimeVisionConfig);
208
194
  /**
@@ -253,14 +239,6 @@ declare class RealtimeVision {
253
239
  * Stop the vision stream and clean up resources
254
240
  */
255
241
  stop(): Promise<void>;
256
- /**
257
- * Submit feedback for the stream
258
- */
259
- submitFeedback(feedback: {
260
- rating: number;
261
- category: string;
262
- feedback?: string;
263
- }): Promise<void>;
264
242
  /**
265
243
  * Get the current stream ID
266
244
  */
@@ -299,4 +277,4 @@ declare class ServerError extends ApiError {
299
277
  constructor(message: string, requestId?: string, details?: any);
300
278
  }
301
279
 
302
- export { ApiError, type ErrorResponse, type FeedbackCreateRequest, type FeedbackResponse, type KeepaliveResponse, NetworkError, NotFoundError, RealtimeVision, type RealtimeVisionConfig, ServerError, type StatusResponse, StreamClient, type StreamClientMeta, type StreamConfigResponse, type StreamCreateRequest, type StreamCreateResponse, type StreamInferenceConfig, type StreamInferenceResult, type StreamProcessingConfig, type StreamSource, UnauthorizedError, ValidationError, type WebRtcAnswer, type WebRtcOffer };
280
+ export { ApiError, type ErrorResponse, type KeepaliveResponse, NetworkError, NotFoundError, RealtimeVision, type RealtimeVisionConfig, ServerError, type StatusResponse, StreamClient, type StreamClientMeta, type StreamConfigResponse, type StreamCreateRequest, type StreamCreateResponse, type StreamInferenceConfig, type StreamInferenceResult, type StreamProcessingConfig, type StreamSource, UnauthorizedError, ValidationError, type WebRtcAnswer, type WebRtcOffer };