tavus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +32 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +90 -0
- data/LICENSE.txt +21 -0
- data/README.md +736 -0
- data/Rakefile +153 -0
- data/examples/advanced_persona.rb +148 -0
- data/examples/basic_usage.rb +107 -0
- data/examples/complete_workflow.rb +200 -0
- data/lib/tavus/client.rb +150 -0
- data/lib/tavus/configuration.rb +26 -0
- data/lib/tavus/errors.rb +13 -0
- data/lib/tavus/resources/conversations.rb +66 -0
- data/lib/tavus/resources/documents.rb +61 -0
- data/lib/tavus/resources/guardrails.rb +88 -0
- data/lib/tavus/resources/objectives.rb +87 -0
- data/lib/tavus/resources/personas.rb +97 -0
- data/lib/tavus/resources/replicas.rb +64 -0
- data/lib/tavus/resources/videos.rb +90 -0
- data/lib/tavus/version.rb +5 -0
- data/lib/tavus.rb +31 -0
- metadata +168 -0
data/README.md
ADDED
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
# Tavus Ruby Client
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/tavus)
|
|
4
|
+
|
|
5
|
+
A Ruby gem for interacting with the [Tavus API](https://tavusapi.com), providing a simple and intuitive interface for managing Conversational Video Interfaces (CVI).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Conversations Management**: Create, retrieve, list, end, and delete real-time video conversations
|
|
10
|
+
- **Personas Management**: Create, retrieve, list, update, and delete AI personas with customizable behavior
|
|
11
|
+
- **Replicas Management**: Create, train, retrieve, list, rename, and delete AI replicas
|
|
12
|
+
- **Objectives Management**: Create, retrieve, list, update, and delete conversation objectives
|
|
13
|
+
- **Guardrails Management**: Create, retrieve, list, update, and delete behavioral guardrails
|
|
14
|
+
- **Knowledge Base (Documents)**: Upload, retrieve, list, update, and delete documents for personas
|
|
15
|
+
- **Video Generation**: Generate videos from text or audio, retrieve, list, rename, and delete videos
|
|
16
|
+
- **Full API Coverage**: Support for all Tavus API v2 endpoints
|
|
17
|
+
- **Easy Configuration**: Simple API key configuration
|
|
18
|
+
- **Comprehensive Error Handling**: Detailed error classes for different API responses
|
|
19
|
+
- **JSON Patch Support**: Update personas, objectives, and guardrails using JSON Patch operations (RFC 6902)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Add this line to your application's Gemfile:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
gem 'tavus'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
And then execute:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
$ bundle install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or install it yourself as:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
$ gem install tavus
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
### Global Configuration
|
|
44
|
+
|
|
45
|
+
Configure the client globally (recommended for Rails applications):
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
# config/initializers/tavus.rb
|
|
49
|
+
Tavus.configure do |config|
|
|
50
|
+
config.api_key = ENV['TAVUS_API_KEY']
|
|
51
|
+
config.base_url = 'https://tavusapi.com' # Optional, defaults to this
|
|
52
|
+
config.timeout = 30 # Optional, defaults to 30 seconds
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Per-Instance Configuration
|
|
57
|
+
|
|
58
|
+
You can also configure individual client instances:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
client = Tavus::Client.new(
|
|
62
|
+
api_key: 'your-api-key',
|
|
63
|
+
base_url: 'https://tavusapi.com',
|
|
64
|
+
timeout: 30
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### Conversations
|
|
71
|
+
|
|
72
|
+
#### Create a Conversation
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
client = Tavus::Client.new(api_key: 'your-api-key')
|
|
76
|
+
|
|
77
|
+
# Create a conversation with required parameters
|
|
78
|
+
conversation = client.conversations.create(
|
|
79
|
+
replica_id: 'rfe12d8b9597',
|
|
80
|
+
persona_id: 'pdced222244b'
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Create a conversation with optional parameters
|
|
84
|
+
conversation = client.conversations.create(
|
|
85
|
+
replica_id: 'rfe12d8b9597',
|
|
86
|
+
persona_id: 'pdced222244b',
|
|
87
|
+
conversation_name: 'Interview User',
|
|
88
|
+
callback_url: 'https://yourwebsite.com/webhook',
|
|
89
|
+
audio_only: false,
|
|
90
|
+
conversational_context: 'I want to improve my sales techniques.',
|
|
91
|
+
custom_greeting: 'Hey there!',
|
|
92
|
+
memory_stores: ['anna'],
|
|
93
|
+
document_ids: ['doc_1234567890'],
|
|
94
|
+
document_retrieval_strategy: 'balanced',
|
|
95
|
+
document_tags: ['sales', 'marketing'],
|
|
96
|
+
test_mode: false
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Response includes:
|
|
100
|
+
# {
|
|
101
|
+
# "conversation_id" => "c123456",
|
|
102
|
+
# "conversation_name" => "Interview User",
|
|
103
|
+
# "status" => "active",
|
|
104
|
+
# "conversation_url" => "https://tavus.daily.co/c123456",
|
|
105
|
+
# "replica_id" => "r79e1c033f",
|
|
106
|
+
# "persona_id" => "p5317866",
|
|
107
|
+
# "created_at" => "2025-10-04T12:00:00Z"
|
|
108
|
+
# }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Get a Conversation
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
conversation = client.conversations.get('c123456')
|
|
115
|
+
|
|
116
|
+
# Response includes conversation details with status, URLs, etc.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### List Conversations
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
# List all conversations
|
|
123
|
+
conversations = client.conversations.list
|
|
124
|
+
|
|
125
|
+
# List with pagination and filters
|
|
126
|
+
conversations = client.conversations.list(
|
|
127
|
+
limit: 20,
|
|
128
|
+
page: 1,
|
|
129
|
+
status: 'active' # or 'ended'
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Response includes:
|
|
133
|
+
# {
|
|
134
|
+
# "data" => [...],
|
|
135
|
+
# "total_count" => 123
|
|
136
|
+
# }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### End a Conversation
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
result = client.conversations.end('c123456')
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Delete a Conversation
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
result = client.conversations.delete('c123456')
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Personas
|
|
152
|
+
|
|
153
|
+
#### Create a Persona
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
# Create a basic persona
|
|
157
|
+
persona = client.personas.create(
|
|
158
|
+
system_prompt: 'As a Life Coach, you are a dedicated professional...',
|
|
159
|
+
persona_name: 'Life Coach',
|
|
160
|
+
pipeline_mode: 'full'
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Create a persona with advanced configuration
|
|
164
|
+
persona = client.personas.create(
|
|
165
|
+
system_prompt: 'As a Life Coach...',
|
|
166
|
+
persona_name: 'Life Coach',
|
|
167
|
+
pipeline_mode: 'full',
|
|
168
|
+
context: 'Here are a few times that you have helped...',
|
|
169
|
+
default_replica_id: 'rfe12d8b9597',
|
|
170
|
+
document_ids: ['d1234567890', 'd2468101214'],
|
|
171
|
+
document_tags: ['product_info', 'company_policies'],
|
|
172
|
+
layers: {
|
|
173
|
+
llm: {
|
|
174
|
+
model: 'tavus-gpt-4o',
|
|
175
|
+
base_url: 'your-base-url',
|
|
176
|
+
api_key: 'your-api-key',
|
|
177
|
+
tools: [
|
|
178
|
+
{
|
|
179
|
+
type: 'function',
|
|
180
|
+
function: {
|
|
181
|
+
name: 'get_current_weather',
|
|
182
|
+
description: 'Get the current weather in a given location',
|
|
183
|
+
parameters: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
location: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'The city and state, e.g. San Francisco, CA'
|
|
189
|
+
},
|
|
190
|
+
unit: {
|
|
191
|
+
type: 'string',
|
|
192
|
+
enum: ['celsius', 'fahrenheit']
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
required: ['location']
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
tts: {
|
|
202
|
+
tts_engine: 'cartesia',
|
|
203
|
+
external_voice_id: 'external-voice-id',
|
|
204
|
+
voice_settings: {
|
|
205
|
+
speed: 0.5,
|
|
206
|
+
emotion: ['positivity:high', 'curiosity']
|
|
207
|
+
},
|
|
208
|
+
tts_emotion_control: 'false',
|
|
209
|
+
tts_model_name: 'sonic'
|
|
210
|
+
},
|
|
211
|
+
perception: {
|
|
212
|
+
perception_model: 'raven-0',
|
|
213
|
+
ambient_awareness_queries: [
|
|
214
|
+
'Is the user showing an ID card?',
|
|
215
|
+
'Does the user appear distressed or uncomfortable?'
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
stt: {
|
|
219
|
+
stt_engine: 'tavus-turbo',
|
|
220
|
+
participant_pause_sensitivity: 'low',
|
|
221
|
+
participant_interrupt_sensitivity: 'low',
|
|
222
|
+
hotwords: 'This is a hotword example',
|
|
223
|
+
smart_turn_detection: true
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# Response includes:
|
|
229
|
+
# {
|
|
230
|
+
# "persona_id" => "p5317866",
|
|
231
|
+
# "persona_name" => "Life Coach",
|
|
232
|
+
# "created_at" => "2025-10-04T12:00:00Z"
|
|
233
|
+
# }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Get a Persona
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
persona = client.personas.get('p5317866')
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### List Personas
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
# List all personas
|
|
246
|
+
personas = client.personas.list
|
|
247
|
+
|
|
248
|
+
# List with pagination and filters
|
|
249
|
+
personas = client.personas.list(
|
|
250
|
+
limit: 20,
|
|
251
|
+
page: 1,
|
|
252
|
+
persona_type: 'user' # or 'system'
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
# Response includes:
|
|
256
|
+
# {
|
|
257
|
+
# "data" => [...],
|
|
258
|
+
# "total_count" => 123
|
|
259
|
+
# }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Update a Persona (JSON Patch)
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
# Update multiple fields using patch operations
|
|
266
|
+
operations = [
|
|
267
|
+
{ op: 'replace', path: '/persona_name', value: 'Wellness Advisor' },
|
|
268
|
+
{ op: 'replace', path: '/default_replica_id', value: 'r79e1c033f' },
|
|
269
|
+
{ op: 'replace', path: '/context', value: 'Updated context...' },
|
|
270
|
+
{ op: 'replace', path: '/layers/llm/model', value: 'tavus-gpt-4o' },
|
|
271
|
+
{ op: 'add', path: '/layers/tts/tts_emotion_control', value: 'true' },
|
|
272
|
+
{ op: 'remove', path: '/layers/stt/hotwords' }
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
result = client.personas.patch('p5317866', operations)
|
|
276
|
+
|
|
277
|
+
# Helper method to build patch operations
|
|
278
|
+
operation = client.personas.build_patch_operation(
|
|
279
|
+
'/persona_name',
|
|
280
|
+
'New Name',
|
|
281
|
+
operation: 'replace'
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# Convenient method to update a single field
|
|
285
|
+
result = client.personas.update_field(
|
|
286
|
+
'p5317866',
|
|
287
|
+
'/persona_name',
|
|
288
|
+
'New Name'
|
|
289
|
+
)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### Delete a Persona
|
|
293
|
+
|
|
294
|
+
```ruby
|
|
295
|
+
result = client.personas.delete('p5317866')
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Replicas
|
|
299
|
+
|
|
300
|
+
#### Create a Replica
|
|
301
|
+
|
|
302
|
+
```ruby
|
|
303
|
+
# Create a replica for conversational video
|
|
304
|
+
replica = client.replicas.create(
|
|
305
|
+
train_video_url: 'https://my-bucket.s3.amazonaws.com/training-video.mp4',
|
|
306
|
+
replica_name: 'My Replica',
|
|
307
|
+
model_name: 'phoenix-3', # Optional, defaults to phoenix-3
|
|
308
|
+
consent_video_url: 'https://my-bucket.s3.amazonaws.com/consent-video.mp4', # Optional
|
|
309
|
+
callback_url: 'https://yourwebsite.com/webhook'
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# Response includes:
|
|
313
|
+
# {
|
|
314
|
+
# "replica_id" => "r783537ef5",
|
|
315
|
+
# "status" => "started"
|
|
316
|
+
# }
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Get a Replica
|
|
320
|
+
|
|
321
|
+
```ruby
|
|
322
|
+
# Get basic replica info
|
|
323
|
+
replica = client.replicas.get('r783537ef5')
|
|
324
|
+
|
|
325
|
+
# Get detailed replica info with verbose flag
|
|
326
|
+
replica = client.replicas.get('r783537ef5', verbose: true)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### List Replicas
|
|
330
|
+
|
|
331
|
+
```ruby
|
|
332
|
+
# List all replicas
|
|
333
|
+
replicas = client.replicas.list
|
|
334
|
+
|
|
335
|
+
# List with filters
|
|
336
|
+
replicas = client.replicas.list(
|
|
337
|
+
limit: 20,
|
|
338
|
+
page: 1,
|
|
339
|
+
replica_type: 'user', # or 'system'
|
|
340
|
+
replica_ids: 're1074c227,r243eed46c',
|
|
341
|
+
verbose: true
|
|
342
|
+
)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Rename a Replica
|
|
346
|
+
|
|
347
|
+
```ruby
|
|
348
|
+
client.replicas.rename('r783537ef5', 'Updated Replica Name')
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### Delete a Replica
|
|
352
|
+
|
|
353
|
+
```ruby
|
|
354
|
+
# Soft delete
|
|
355
|
+
client.replicas.delete('r783537ef5')
|
|
356
|
+
|
|
357
|
+
# Hard delete (irreversible - deletes all assets)
|
|
358
|
+
client.replicas.delete('r783537ef5', hard: true)
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Objectives
|
|
362
|
+
|
|
363
|
+
#### Create Objectives
|
|
364
|
+
|
|
365
|
+
```ruby
|
|
366
|
+
objectives = client.objectives.create(
|
|
367
|
+
data: [
|
|
368
|
+
{
|
|
369
|
+
objective_name: 'Gather User Feedback',
|
|
370
|
+
objective_prompt: 'Ask the user about their experience with the product',
|
|
371
|
+
confirmation_mode: 'automatic',
|
|
372
|
+
modality: 'verbal'
|
|
373
|
+
}
|
|
374
|
+
]
|
|
375
|
+
)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Get an Objective
|
|
379
|
+
|
|
380
|
+
```ruby
|
|
381
|
+
objective = client.objectives.get('o12345')
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
#### List Objectives
|
|
385
|
+
|
|
386
|
+
```ruby
|
|
387
|
+
objectives = client.objectives.list(limit: 20, page: 1)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Update an Objective
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
operations = [
|
|
394
|
+
{ op: 'replace', path: '/data/0/objective_name', value: 'Updated Objective' },
|
|
395
|
+
{ op: 'replace', path: '/data/0/confirmation_mode', value: 'manual' }
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
client.objectives.patch('o12345', operations)
|
|
399
|
+
|
|
400
|
+
# Or update a single field
|
|
401
|
+
client.objectives.update_field('o12345', '/data/0/objective_name', 'New Name')
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### Delete an Objective
|
|
405
|
+
|
|
406
|
+
```ruby
|
|
407
|
+
client.objectives.delete('o12345')
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Guardrails
|
|
411
|
+
|
|
412
|
+
#### Create Guardrails
|
|
413
|
+
|
|
414
|
+
```ruby
|
|
415
|
+
guardrails = client.guardrails.create(
|
|
416
|
+
name: 'Healthcare Compliance Guardrails',
|
|
417
|
+
data: [
|
|
418
|
+
{
|
|
419
|
+
guardrails_prompt: 'Never discuss competitor products or share sensitive medical information',
|
|
420
|
+
modality: 'verbal',
|
|
421
|
+
callback_url: 'https://your-server.com/webhook'
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
)
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
#### Get Guardrails
|
|
428
|
+
|
|
429
|
+
```ruby
|
|
430
|
+
guardrails = client.guardrails.get('g12345')
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### List Guardrails
|
|
434
|
+
|
|
435
|
+
```ruby
|
|
436
|
+
guardrails = client.guardrails.list(limit: 20, page: 1)
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### Update Guardrails
|
|
440
|
+
|
|
441
|
+
```ruby
|
|
442
|
+
operations = [
|
|
443
|
+
{ op: 'replace', path: '/data/0/guardrails_prompt', value: 'Updated guardrails prompt' },
|
|
444
|
+
{ op: 'add', path: '/data/0/callback_url', value: 'https://new-server.com/webhook' }
|
|
445
|
+
]
|
|
446
|
+
|
|
447
|
+
client.guardrails.patch('g12345', operations)
|
|
448
|
+
|
|
449
|
+
# Or update a single field
|
|
450
|
+
client.guardrails.update_field('g12345', '/data/0/guardrails_prompt', 'New prompt')
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
#### Delete Guardrails
|
|
454
|
+
|
|
455
|
+
```ruby
|
|
456
|
+
client.guardrails.delete('g12345')
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Documents (Knowledge Base)
|
|
460
|
+
|
|
461
|
+
#### Create a Document
|
|
462
|
+
|
|
463
|
+
```ruby
|
|
464
|
+
# Upload from URL
|
|
465
|
+
document = client.documents.create(
|
|
466
|
+
document_url: 'https://example.com/document.pdf',
|
|
467
|
+
document_name: 'Product Documentation',
|
|
468
|
+
callback_url: 'https://your-server.com/webhook',
|
|
469
|
+
tags: ['product', 'documentation'],
|
|
470
|
+
properties: { department: 'sales', priority: 'high' }
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
# Supported formats: .pdf, .txt, .docx, .doc, .png, .jpg, .pptx, .csv, .xlsx
|
|
474
|
+
# Also supports website URLs for snapshots
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### Get a Document
|
|
478
|
+
|
|
479
|
+
```ruby
|
|
480
|
+
document = client.documents.get('d290f1ee-6c54-4b01-90e6-d701748f0851')
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### List Documents
|
|
484
|
+
|
|
485
|
+
```ruby
|
|
486
|
+
# List all documents
|
|
487
|
+
documents = client.documents.list
|
|
488
|
+
|
|
489
|
+
# List with filters
|
|
490
|
+
documents = client.documents.list(
|
|
491
|
+
limit: 20,
|
|
492
|
+
page: 0,
|
|
493
|
+
sort: 'descending',
|
|
494
|
+
status: 'ready',
|
|
495
|
+
tags: 'product,documentation'
|
|
496
|
+
)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
#### Update a Document
|
|
500
|
+
|
|
501
|
+
```ruby
|
|
502
|
+
client.documents.update(
|
|
503
|
+
'd290f1ee-6c54-4b01-90e6-d701748f0851',
|
|
504
|
+
document_name: 'Updated Document Name',
|
|
505
|
+
tags: ['updated', 'important']
|
|
506
|
+
)
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
#### Delete a Document
|
|
510
|
+
|
|
511
|
+
```ruby
|
|
512
|
+
client.documents.delete('d290f1ee-6c54-4b01-90e6-d701748f0851')
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Videos
|
|
516
|
+
|
|
517
|
+
#### Generate a Video
|
|
518
|
+
|
|
519
|
+
```ruby
|
|
520
|
+
# Generate video from text script
|
|
521
|
+
video = client.videos.create(
|
|
522
|
+
replica_id: 'r783537ef5',
|
|
523
|
+
script: 'Hello from Tavus! Enjoy your new replica',
|
|
524
|
+
video_name: 'My First Video',
|
|
525
|
+
background_url: 'https://yourwebsite.com/',
|
|
526
|
+
callback_url: 'https://yourwebsite.com/webhook'
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
# Or use the convenient method
|
|
530
|
+
video = client.videos.generate_from_text(
|
|
531
|
+
replica_id: 'r783537ef5',
|
|
532
|
+
script: 'Hello from Tavus!',
|
|
533
|
+
video_name: 'My Video'
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
# Generate video from audio file
|
|
537
|
+
video = client.videos.generate_from_audio(
|
|
538
|
+
replica_id: 'r783537ef5',
|
|
539
|
+
audio_url: 'https://my-bucket.s3.amazonaws.com/audio.mp3',
|
|
540
|
+
video_name: 'Audio Video'
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
# Advanced options
|
|
544
|
+
video = client.videos.create(
|
|
545
|
+
replica_id: 'r783537ef5',
|
|
546
|
+
script: 'Hello!',
|
|
547
|
+
fast: true, # Use fast rendering
|
|
548
|
+
transparent_background: true, # Requires fast: true
|
|
549
|
+
watermark_image_url: 'https://s3.amazonaws.com/watermark.png',
|
|
550
|
+
background_source_url: 'https://my-bucket.s3.amazonaws.com/background.mp4'
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
# Response includes:
|
|
554
|
+
# {
|
|
555
|
+
# "video_id" => "abcd123",
|
|
556
|
+
# "status" => "queued",
|
|
557
|
+
# "hosted_url" => "https://tavus.video/abcd123"
|
|
558
|
+
# }
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
#### Get a Video
|
|
562
|
+
|
|
563
|
+
```ruby
|
|
564
|
+
# Get basic video info
|
|
565
|
+
video = client.videos.get('abcd123')
|
|
566
|
+
|
|
567
|
+
# Get detailed info with thumbnails
|
|
568
|
+
video = client.videos.get('abcd123', verbose: true)
|
|
569
|
+
|
|
570
|
+
# Response includes download_url, stream_url, hosted_url when ready
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
#### List Videos
|
|
574
|
+
|
|
575
|
+
```ruby
|
|
576
|
+
videos = client.videos.list(limit: 20, page: 1)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### Rename a Video
|
|
580
|
+
|
|
581
|
+
```ruby
|
|
582
|
+
client.videos.rename('abcd123', 'New Video Name')
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
#### Delete a Video
|
|
586
|
+
|
|
587
|
+
```ruby
|
|
588
|
+
# Soft delete
|
|
589
|
+
client.videos.delete('abcd123')
|
|
590
|
+
|
|
591
|
+
# Hard delete (irreversible - deletes all assets)
|
|
592
|
+
client.videos.delete('abcd123', hard: true)
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
## Error Handling
|
|
596
|
+
|
|
597
|
+
The gem provides specific error classes for different API responses:
|
|
598
|
+
|
|
599
|
+
```ruby
|
|
600
|
+
begin
|
|
601
|
+
conversation = client.conversations.create(replica_id: 'invalid')
|
|
602
|
+
rescue Tavus::AuthenticationError => e
|
|
603
|
+
# Handle authentication errors (401)
|
|
604
|
+
puts "Authentication failed: #{e.message}"
|
|
605
|
+
rescue Tavus::BadRequestError => e
|
|
606
|
+
# Handle bad request errors (400)
|
|
607
|
+
puts "Bad request: #{e.message}"
|
|
608
|
+
rescue Tavus::NotFoundError => e
|
|
609
|
+
# Handle not found errors (404)
|
|
610
|
+
puts "Resource not found: #{e.message}"
|
|
611
|
+
rescue Tavus::ValidationError => e
|
|
612
|
+
# Handle validation errors (422)
|
|
613
|
+
puts "Validation failed: #{e.message}"
|
|
614
|
+
rescue Tavus::RateLimitError => e
|
|
615
|
+
# Handle rate limit errors (429)
|
|
616
|
+
puts "Rate limit exceeded: #{e.message}"
|
|
617
|
+
rescue Tavus::ServerError => e
|
|
618
|
+
# Handle server errors (5xx)
|
|
619
|
+
puts "Server error: #{e.message}"
|
|
620
|
+
rescue Tavus::ApiError => e
|
|
621
|
+
# Handle any other API errors
|
|
622
|
+
puts "API error: #{e.message}"
|
|
623
|
+
rescue Tavus::ConfigurationError => e
|
|
624
|
+
# Handle configuration errors
|
|
625
|
+
puts "Configuration error: #{e.message}"
|
|
626
|
+
end
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
## API Reference
|
|
630
|
+
|
|
631
|
+
### Conversations
|
|
632
|
+
|
|
633
|
+
| Method | Description |
|
|
634
|
+
|--------|-------------|
|
|
635
|
+
| `create(replica_id:, persona_id:, **options)` | Create a new conversation |
|
|
636
|
+
| `get(conversation_id)` | Get a conversation by ID |
|
|
637
|
+
| `list(**options)` | List all conversations |
|
|
638
|
+
| `end(conversation_id)` | End a conversation |
|
|
639
|
+
| `delete(conversation_id)` | Delete a conversation |
|
|
640
|
+
|
|
641
|
+
### Personas
|
|
642
|
+
|
|
643
|
+
| Method | Description |
|
|
644
|
+
|--------|-------------|
|
|
645
|
+
| `create(system_prompt:, **options)` | Create a new persona |
|
|
646
|
+
| `get(persona_id)` | Get a persona by ID |
|
|
647
|
+
| `list(**options)` | List all personas |
|
|
648
|
+
| `patch(persona_id, operations)` | Update a persona using JSON Patch |
|
|
649
|
+
| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |
|
|
650
|
+
| `update_field(persona_id, field, value)` | Update a single field |
|
|
651
|
+
| `delete(persona_id)` | Delete a persona |
|
|
652
|
+
|
|
653
|
+
### Replicas
|
|
654
|
+
|
|
655
|
+
| Method | Description |
|
|
656
|
+
|--------|-------------|
|
|
657
|
+
| `create(train_video_url:, **options)` | Create a new replica |
|
|
658
|
+
| `get(replica_id, verbose: false)` | Get a replica by ID |
|
|
659
|
+
| `list(**options)` | List all replicas |
|
|
660
|
+
| `rename(replica_id, replica_name)` | Rename a replica |
|
|
661
|
+
| `delete(replica_id, hard: false)` | Delete a replica |
|
|
662
|
+
|
|
663
|
+
### Objectives
|
|
664
|
+
|
|
665
|
+
| Method | Description |
|
|
666
|
+
|--------|-------------|
|
|
667
|
+
| `create(data:)` | Create new objectives |
|
|
668
|
+
| `get(objectives_id)` | Get an objective by ID |
|
|
669
|
+
| `list(**options)` | List all objectives |
|
|
670
|
+
| `patch(objectives_id, operations)` | Update an objective using JSON Patch |
|
|
671
|
+
| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |
|
|
672
|
+
| `update_field(objectives_id, field, value)` | Update a single field |
|
|
673
|
+
| `delete(objectives_id)` | Delete an objective |
|
|
674
|
+
|
|
675
|
+
### Guardrails
|
|
676
|
+
|
|
677
|
+
| Method | Description |
|
|
678
|
+
|--------|-------------|
|
|
679
|
+
| `create(name:, data:)` | Create new guardrails |
|
|
680
|
+
| `get(guardrails_id)` | Get guardrails by ID |
|
|
681
|
+
| `list(**options)` | List all guardrails |
|
|
682
|
+
| `patch(guardrails_id, operations)` | Update guardrails using JSON Patch |
|
|
683
|
+
| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |
|
|
684
|
+
| `update_field(guardrails_id, field, value)` | Update a single field |
|
|
685
|
+
| `delete(guardrails_id)` | Delete guardrails |
|
|
686
|
+
|
|
687
|
+
### Documents (Knowledge Base)
|
|
688
|
+
|
|
689
|
+
| Method | Description |
|
|
690
|
+
|--------|-------------|
|
|
691
|
+
| `create(document_url:, **options)` | Upload a new document |
|
|
692
|
+
| `get(document_id)` | Get a document by ID |
|
|
693
|
+
| `list(**options)` | List all documents |
|
|
694
|
+
| `update(document_id, **options)` | Update document metadata |
|
|
695
|
+
| `delete(document_id)` | Delete a document |
|
|
696
|
+
|
|
697
|
+
### Videos
|
|
698
|
+
|
|
699
|
+
| Method | Description |
|
|
700
|
+
|--------|-------------|
|
|
701
|
+
| `create(replica_id:, **options)` | Generate a new video |
|
|
702
|
+
| `generate_from_text(replica_id:, script:, **options)` | Generate video from text |
|
|
703
|
+
| `generate_from_audio(replica_id:, audio_url:, **options)` | Generate video from audio |
|
|
704
|
+
| `get(video_id, verbose: false)` | Get a video by ID |
|
|
705
|
+
| `list(**options)` | List all videos |
|
|
706
|
+
| `rename(video_id, video_name)` | Rename a video |
|
|
707
|
+
| `delete(video_id, hard: false)` | Delete a video |
|
|
708
|
+
|
|
709
|
+
## Development
|
|
710
|
+
|
|
711
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
712
|
+
|
|
713
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
714
|
+
|
|
715
|
+
## CI/CD
|
|
716
|
+
|
|
717
|
+
This project uses GitHub Actions for continuous integration:
|
|
718
|
+
|
|
719
|
+
- **Tests**: Runs on Ruby 2.7, 3.0, 3.1, 3.2, and 3.3
|
|
720
|
+
- **Linting**: RuboCop style checking
|
|
721
|
+
- **Security**: Bundle audit for dependency vulnerabilities
|
|
722
|
+
|
|
723
|
+
[](https://github.com/upriser/tavus/actions/workflows/ci.yml)
|
|
724
|
+
|
|
725
|
+
## Contributing
|
|
726
|
+
|
|
727
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/upriser/tavus.
|
|
728
|
+
|
|
729
|
+
## License
|
|
730
|
+
|
|
731
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
732
|
+
|
|
733
|
+
## Resources
|
|
734
|
+
|
|
735
|
+
- [Tavus API Documentation](https://docs.tavus.io)
|
|
736
|
+
- [Tavus Developer Portal](https://platform.tavus.io)
|