{"id":31779586,"url":"https://github.com/vbrazo/tavus","last_synced_at":"2026-01-20T17:33:33.303Z","repository":{"id":318012413,"uuid":"1069739336","full_name":"vbrazo/tavus","owner":"vbrazo","description":"A Ruby library that leverages Tavus tools and guides to give your AI Agent real-time human-like perception and presence, bringing the human layer to AI","archived":false,"fork":false,"pushed_at":"2025-10-04T15:03:32.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-04T15:03:45.136Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vbrazo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-04T14:26:36.000Z","updated_at":"2025-10-04T15:03:34.000Z","dependencies_parsed_at":"2025-10-04T15:03:48.827Z","dependency_job_id":"3f5c9c36-516b-4ccd-9175-22c50c52f8e7","html_url":"https://github.com/vbrazo/tavus","commit_stats":null,"previous_names":["vbrazo/tavus"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/vbrazo/tavus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbrazo%2Ftavus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbrazo%2Ftavus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbrazo%2Ftavus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbrazo%2Ftavus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vbrazo","download_url":"https://codeload.github.com/vbrazo/tavus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbrazo%2Ftavus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002341,"owners_count":26083340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-10T07:52:02.232Z","updated_at":"2025-10-10T07:52:11.545Z","avatar_url":"https://github.com/vbrazo.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tavus Ruby Client\n\n[![Gem Version](https://badge.fury.io/rb/tavus.svg)](https://badge.fury.io/rb/tavus)\n\nA Ruby gem for interacting with the [Tavus API](https://tavusapi.com), providing a simple and intuitive interface for managing Conversational Video Interfaces (CVI).\n\n## Features\n\n- **Conversations Management**: Create, retrieve, list, end, and delete real-time video conversations\n- **Personas Management**: Create, retrieve, list, update, and delete AI personas with customizable behavior\n- **Replicas Management**: Create, train, retrieve, list, rename, and delete AI replicas\n- **Objectives Management**: Create, retrieve, list, update, and delete conversation objectives\n- **Guardrails Management**: Create, retrieve, list, update, and delete behavioral guardrails\n- **Knowledge Base (Documents)**: Upload, retrieve, list, update, and delete documents for personas\n- **Video Generation**: Generate videos from text or audio, retrieve, list, rename, and delete videos\n- **Full API Coverage**: Support for all Tavus API v2 endpoints\n- **Easy Configuration**: Simple API key configuration\n- **Comprehensive Error Handling**: Detailed error classes for different API responses\n- **JSON Patch Support**: Update personas, objectives, and guardrails using JSON Patch operations (RFC 6902)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'tavus'\n```\n\nAnd then execute:\n\n```bash\n$ bundle install\n```\n\nOr install it yourself as:\n\n```bash\n$ gem install tavus\n```\n\n## Configuration\n\n### Global Configuration\n\nConfigure the client globally (recommended for Rails applications):\n\n```ruby\n# config/initializers/tavus.rb\nTavus.configure do |config|\n  config.api_key = ENV['TAVUS_API_KEY']\n  config.base_url = 'https://tavusapi.com' # Optional, defaults to this\n  config.timeout = 30 # Optional, defaults to 30 seconds\nend\n```\n\n### Per-Instance Configuration\n\nYou can also configure individual client instances:\n\n```ruby\nclient = Tavus::Client.new(\n  api_key: 'your-api-key',\n  base_url: 'https://tavusapi.com',\n  timeout: 30\n)\n```\n\n## Usage\n\nFor more comprehensive examples, check the [examples/](examples/) directory:\n- [basic_usage.rb](examples/basic_usage.rb) - Basic operations with personas and conversations\n- [advanced_persona.rb](examples/advanced_persona.rb) - Advanced persona configuration with custom layers\n- [complete_workflow.rb](examples/complete_workflow.rb) - End-to-end workflow including replicas, documents, objectives, guardrails, and videos\n\n### Conversations\n\n#### Create a Conversation\n\n```ruby\nclient = Tavus::Client.new(api_key: 'your-api-key')\n\n# Create a conversation with required parameters\nconversation = client.conversations.create(\n  replica_id: 'rfe12d8b9597',\n  persona_id: 'pdced222244b'\n)\n\n# Create a conversation with optional parameters\nconversation = client.conversations.create(\n  replica_id: 'rfe12d8b9597',\n  persona_id: 'pdced222244b',\n  conversation_name: 'Interview User',\n  callback_url: 'https://yourwebsite.com/webhook',\n  audio_only: false,\n  conversational_context: 'I want to improve my sales techniques.',\n  custom_greeting: 'Hey there!',\n  memory_stores: ['anna'],\n  document_ids: ['doc_1234567890'],\n  document_retrieval_strategy: 'balanced',\n  document_tags: ['sales', 'marketing'],\n  test_mode: false\n)\n\n# Response includes:\n# {\n#   \"conversation_id\" =\u003e \"c123456\",\n#   \"conversation_name\" =\u003e \"Interview User\",\n#   \"status\" =\u003e \"active\",\n#   \"conversation_url\" =\u003e \"https://tavus.daily.co/c123456\",\n#   \"replica_id\" =\u003e \"rfe12d8b9597\",\n#   \"persona_id\" =\u003e \"pdced222244b\",\n#   \"created_at\" =\u003e \"2025-10-04T12:00:00Z\"\n# }\n```\n\n#### Get a Conversation\n\n```ruby\nconversation = client.conversations.get('c123456')\n\n# Response includes conversation details with status, URLs, etc.\n```\n\n#### List Conversations\n\n```ruby\n# List all conversations\nconversations = client.conversations.list\n\n# List with pagination and filters\nconversations = client.conversations.list(\n  limit: 20,\n  page: 1,\n  status: 'active' # or 'ended'\n)\n\n# Response includes:\n# {\n#   \"data\" =\u003e [...],\n#   \"total_count\" =\u003e 123\n# }\n```\n\n#### End a Conversation\n\n```ruby\nresult = client.conversations.end('c123456')\n```\n\n#### Delete a Conversation\n\n```ruby\nresult = client.conversations.delete('c123456')\n```\n\n### Personas\n\n#### Create a Persona\n\n```ruby\n# Create a basic persona\npersona = client.personas.create(\n  system_prompt: 'As a Life Coach, you are a dedicated professional...',\n  persona_name: 'Life Coach',\n  pipeline_mode: 'full'\n)\n\n# Create a persona with advanced configuration\npersona = client.personas.create(\n  system_prompt: 'As a Life Coach...',\n  persona_name: 'Life Coach',\n  pipeline_mode: 'full',\n  context: 'Here are a few times that you have helped...',\n  default_replica_id: 'rfe12d8b9597',\n  document_ids: ['d1234567890', 'd2468101214'],\n  document_tags: ['product_info', 'company_policies'],\n  layers: {\n    llm: {\n      model: 'tavus-gpt-4o',\n      base_url: 'your-base-url',\n      api_key: 'your-api-key',\n      tools: [\n        {\n          type: 'function',\n          function: {\n            name: 'get_current_weather',\n            description: 'Get the current weather in a given location',\n            parameters: {\n              type: 'object',\n              properties: {\n                location: {\n                  type: 'string',\n                  description: 'The city and state, e.g. San Francisco, CA'\n                },\n                unit: {\n                  type: 'string',\n                  enum: ['celsius', 'fahrenheit']\n                }\n              },\n              required: ['location']\n            }\n          }\n        }\n      ]\n    },\n    tts: {\n      tts_engine: 'cartesia',\n      external_voice_id: 'external-voice-id',\n      voice_settings: {\n        speed: 0.5,\n        emotion: ['positivity:high', 'curiosity']\n      },\n      tts_emotion_control: 'false',\n      tts_model_name: 'sonic'\n    },\n    perception: {\n      perception_model: 'raven-0',\n      ambient_awareness_queries: [\n        'Is the user showing an ID card?',\n        'Does the user appear distressed or uncomfortable?'\n      ]\n    },\n    stt: {\n      stt_engine: 'tavus-turbo',\n      participant_pause_sensitivity: 'low',\n      participant_interrupt_sensitivity: 'low',\n      hotwords: 'This is a hotword example',\n      smart_turn_detection: true\n    }\n  }\n)\n\n# Response includes:\n# {\n#   \"persona_id\" =\u003e \"p5317866\",\n#   \"persona_name\" =\u003e \"Life Coach\",\n#   \"created_at\" =\u003e \"2025-10-04T12:00:00Z\"\n# }\n```\n\n#### Get a Persona\n\n```ruby\npersona = client.personas.get('p5317866')\n```\n\n#### List Personas\n\n```ruby\n# List all personas\npersonas = client.personas.list\n\n# List with pagination and filters\npersonas = client.personas.list(\n  limit: 20,\n  page: 1,\n  persona_type: 'user' # or 'system'\n)\n\n# Response includes:\n# {\n#   \"data\" =\u003e [...],\n#   \"total_count\" =\u003e 123\n# }\n```\n\n#### Update a Persona (JSON Patch)\n\n```ruby\n# Update multiple fields using patch operations\noperations = [\n  { op: 'replace', path: '/persona_name', value: 'Wellness Advisor' },\n  { op: 'replace', path: '/default_replica_id', value: 'r79e1c033f' },\n  { op: 'replace', path: '/context', value: 'Updated context...' },\n  { op: 'replace', path: '/layers/llm/model', value: 'tavus-gpt-4o' },\n  { op: 'add', path: '/layers/tts/tts_emotion_control', value: 'true' },\n  { op: 'remove', path: '/layers/stt/hotwords' }\n]\n\nresult = client.personas.patch('p5317866', operations)\n\n# Helper method to build patch operations\noperation = client.personas.build_patch_operation(\n  '/persona_name',\n  'New Name',\n  operation: 'replace'\n)\n\n# Convenient method to update a single field\nresult = client.personas.update_field(\n  'p5317866',\n  '/persona_name',\n  'New Name'\n)\n```\n\n#### Delete a Persona\n\n```ruby\nresult = client.personas.delete('p5317866')\n```\n\n### Replicas\n\n#### Create a Replica\n\n```ruby\n# Create a replica for conversational video\nreplica = client.replicas.create(\n  train_video_url: 'https://my-bucket.s3.amazonaws.com/training-video.mp4',\n  replica_name: 'My Replica',\n  model_name: 'phoenix-3', # Optional, defaults to phoenix-3\n  consent_video_url: 'https://my-bucket.s3.amazonaws.com/consent-video.mp4', # Optional\n  callback_url: 'https://yourwebsite.com/webhook'\n)\n\n# Response includes:\n# {\n#   \"replica_id\" =\u003e \"r783537ef5\",\n#   \"status\" =\u003e \"started\"\n# }\n```\n\n#### Get a Replica\n\n```ruby\n# Get basic replica info\nreplica = client.replicas.get('r783537ef5')\n\n# Get detailed replica info with verbose flag\nreplica = client.replicas.get('r783537ef5', verbose: true)\n```\n\n#### List Replicas\n\n```ruby\n# List all replicas\nreplicas = client.replicas.list\n\n# List with filters\nreplicas = client.replicas.list(\n  limit: 20,\n  page: 1,\n  replica_type: 'user', # or 'system'\n  replica_ids: 're1074c227,r243eed46c',\n  verbose: true\n)\n```\n\n#### Rename a Replica\n\n```ruby\nclient.replicas.rename('r783537ef5', 'Updated Replica Name')\n```\n\n#### Delete a Replica\n\n```ruby\n# Soft delete\nclient.replicas.delete('r783537ef5')\n\n# Hard delete (irreversible - deletes all assets)\nclient.replicas.delete('r783537ef5', hard: true)\n```\n\n### Objectives\n\n#### Create Objectives\n\n```ruby\nobjectives = client.objectives.create(\n  data: [\n    {\n      objective_name: 'Gather User Feedback',\n      objective_prompt: 'Ask the user about their experience with the product',\n      confirmation_mode: 'automatic',\n      modality: 'verbal'\n    }\n  ]\n)\n```\n\n#### Get an Objective\n\n```ruby\nobjective = client.objectives.get('o12345')\n```\n\n#### List Objectives\n\n```ruby\nobjectives = client.objectives.list(limit: 20, page: 1)\n```\n\n#### Update an Objective\n\n```ruby\noperations = [\n  { op: 'replace', path: '/data/0/objective_name', value: 'Updated Objective' },\n  { op: 'replace', path: '/data/0/confirmation_mode', value: 'manual' }\n]\n\nclient.objectives.patch('o12345', operations)\n\n# Or update a single field\nclient.objectives.update_field('o12345', '/data/0/objective_name', 'New Name')\n```\n\n#### Delete an Objective\n\n```ruby\nclient.objectives.delete('o12345')\n```\n\n### Guardrails\n\n#### Create Guardrails\n\n```ruby\nguardrails = client.guardrails.create(\n  name: 'Healthcare Compliance Guardrails',\n  data: [\n    {\n      guardrails_prompt: 'Never discuss competitor products or share sensitive medical information',\n      modality: 'verbal',\n      callback_url: 'https://your-server.com/webhook'\n    }\n  ]\n)\n```\n\n#### Get Guardrails\n\n```ruby\nguardrails = client.guardrails.get('g12345')\n```\n\n#### List Guardrails\n\n```ruby\nguardrails = client.guardrails.list(limit: 20, page: 1)\n```\n\n#### Update Guardrails\n\n```ruby\noperations = [\n  { op: 'replace', path: '/data/0/guardrails_prompt', value: 'Updated guardrails prompt' },\n  { op: 'add', path: '/data/0/callback_url', value: 'https://new-server.com/webhook' }\n]\n\nclient.guardrails.patch('g12345', operations)\n\n# Or update a single field\nclient.guardrails.update_field('g12345', '/data/0/guardrails_prompt', 'New prompt')\n```\n\n#### Delete Guardrails\n\n```ruby\nclient.guardrails.delete('g12345')\n```\n\n### Documents (Knowledge Base)\n\n#### Create a Document\n\n```ruby\n# Upload from URL\ndocument = client.documents.create(\n  document_url: 'https://example.com/document.pdf',\n  document_name: 'Product Documentation',\n  callback_url: 'https://your-server.com/webhook',\n  tags: ['product', 'documentation'],\n  properties: { department: 'sales', priority: 'high' }\n)\n\n# Supported formats: .pdf, .txt, .docx, .doc, .png, .jpg, .pptx, .csv, .xlsx\n# Also supports website URLs for snapshots\n```\n\n#### Get a Document\n\n```ruby\ndocument = client.documents.get('d290f1ee-6c54-4b01-90e6-d701748f0851')\n```\n\n#### List Documents\n\n```ruby\n# List all documents\ndocuments = client.documents.list\n\n# List with filters\ndocuments = client.documents.list(\n  limit: 20,\n  page: 0,\n  sort: 'descending',\n  status: 'ready',\n  tags: 'product,documentation'\n)\n```\n\n#### Update a Document\n\n```ruby\nclient.documents.update(\n  'd290f1ee-6c54-4b01-90e6-d701748f0851',\n  document_name: 'Updated Document Name',\n  tags: ['updated', 'important']\n)\n```\n\n#### Delete a Document\n\n```ruby\nclient.documents.delete('d290f1ee-6c54-4b01-90e6-d701748f0851')\n```\n\n### Videos\n\n#### Generate a Video\n\n```ruby\n# Generate video from text script\nvideo = client.videos.create(\n  replica_id: 'r783537ef5',\n  script: 'Hello from Tavus! Enjoy your new replica',\n  video_name: 'My First Video',\n  background_url: 'https://yourwebsite.com/',\n  callback_url: 'https://yourwebsite.com/webhook'\n)\n\n# Or use the convenient method\nvideo = client.videos.generate_from_text(\n  replica_id: 'r783537ef5',\n  script: 'Hello from Tavus!',\n  video_name: 'My Video'\n)\n\n# Generate video from audio file\nvideo = client.videos.generate_from_audio(\n  replica_id: 'r783537ef5',\n  audio_url: 'https://my-bucket.s3.amazonaws.com/audio.mp3',\n  video_name: 'Audio Video'\n)\n\n# Advanced options\nvideo = client.videos.create(\n  replica_id: 'r783537ef5',\n  script: 'Hello!',\n  fast: true, # Use fast rendering\n  transparent_background: true, # Requires fast: true\n  watermark_image_url: 'https://s3.amazonaws.com/watermark.png',\n  background_source_url: 'https://my-bucket.s3.amazonaws.com/background.mp4'\n)\n\n# Response includes:\n# {\n#   \"video_id\" =\u003e \"abcd123\",\n#   \"status\" =\u003e \"queued\",\n#   \"hosted_url\" =\u003e \"https://tavus.video/abcd123\"\n# }\n```\n\n#### Get a Video\n\n```ruby\n# Get basic video info\nvideo = client.videos.get('abcd123')\n\n# Get detailed info with thumbnails\nvideo = client.videos.get('abcd123', verbose: true)\n\n# Response includes download_url, stream_url, hosted_url when ready\n```\n\n#### List Videos\n\n```ruby\nvideos = client.videos.list(limit: 20, page: 1)\n```\n\n#### Rename a Video\n\n```ruby\nclient.videos.rename('abcd123', 'New Video Name')\n```\n\n#### Delete a Video\n\n```ruby\n# Soft delete\nclient.videos.delete('abcd123')\n\n# Hard delete (irreversible - deletes all assets)\nclient.videos.delete('abcd123', hard: true)\n```\n\n## Error Handling\n\nThe gem provides specific error classes for different API responses:\n\n```ruby\nbegin\n  conversation = client.conversations.create(replica_id: 'invalid')\nrescue Tavus::AuthenticationError =\u003e e\n  # Handle authentication errors (401)\n  puts \"Authentication failed: #{e.message}\"\nrescue Tavus::BadRequestError =\u003e e\n  # Handle bad request errors (400)\n  puts \"Bad request: #{e.message}\"\nrescue Tavus::NotFoundError =\u003e e\n  # Handle not found errors (404)\n  puts \"Resource not found: #{e.message}\"\nrescue Tavus::ValidationError =\u003e e\n  # Handle validation errors (422)\n  puts \"Validation failed: #{e.message}\"\nrescue Tavus::RateLimitError =\u003e e\n  # Handle rate limit errors (429)\n  puts \"Rate limit exceeded: #{e.message}\"\nrescue Tavus::ServerError =\u003e e\n  # Handle server errors (5xx)\n  puts \"Server error: #{e.message}\"\nrescue Tavus::ApiError =\u003e e\n  # Handle any other API errors\n  puts \"API error: #{e.message}\"\nrescue Tavus::ConfigurationError =\u003e e\n  # Handle configuration errors\n  puts \"Configuration error: #{e.message}\"\nend\n```\n\n## API Reference\n\n### Conversations\n\n| Method | Description |\n|--------|-------------|\n| `create(replica_id:, persona_id:, **options)` | Create a new conversation |\n| `get(conversation_id)` | Get a conversation by ID |\n| `list(**options)` | List all conversations |\n| `end(conversation_id)` | End a conversation |\n| `delete(conversation_id)` | Delete a conversation |\n\n### Personas\n\n| Method | Description |\n|--------|-------------|\n| `create(system_prompt:, **options)` | Create a new persona |\n| `get(persona_id)` | Get a persona by ID |\n| `list(**options)` | List all personas |\n| `patch(persona_id, operations)` | Update a persona using JSON Patch |\n| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |\n| `update_field(persona_id, field, value)` | Update a single field |\n| `delete(persona_id)` | Delete a persona |\n\n### Replicas\n\n| Method | Description |\n|--------|-------------|\n| `create(train_video_url:, **options)` | Create a new replica |\n| `get(replica_id, verbose: false)` | Get a replica by ID |\n| `list(**options)` | List all replicas |\n| `rename(replica_id, replica_name)` | Rename a replica |\n| `delete(replica_id, hard: false)` | Delete a replica |\n\n### Objectives\n\n| Method | Description |\n|--------|-------------|\n| `create(data:)` | Create new objectives |\n| `get(objectives_id)` | Get an objective by ID |\n| `list(**options)` | List all objectives |\n| `patch(objectives_id, operations)` | Update an objective using JSON Patch |\n| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |\n| `update_field(objectives_id, field, value)` | Update a single field |\n| `delete(objectives_id)` | Delete an objective |\n\n### Guardrails\n\n| Method | Description |\n|--------|-------------|\n| `create(name:, data:)` | Create new guardrails |\n| `get(guardrails_id)` | Get guardrails by ID |\n| `list(**options)` | List all guardrails |\n| `patch(guardrails_id, operations)` | Update guardrails using JSON Patch |\n| `build_patch_operation(field, value, operation:)` | Build a JSON Patch operation |\n| `update_field(guardrails_id, field, value)` | Update a single field |\n| `delete(guardrails_id)` | Delete guardrails |\n\n### Documents (Knowledge Base)\n\n| Method | Description |\n|--------|-------------|\n| `create(document_url:, **options)` | Upload a new document |\n| `get(document_id)` | Get a document by ID |\n| `list(**options)` | List all documents |\n| `update(document_id, **options)` | Update document metadata |\n| `delete(document_id)` | Delete a document |\n\n### Videos\n\n| Method | Description |\n|--------|-------------|\n| `create(replica_id:, **options)` | Generate a new video |\n| `generate_from_text(replica_id:, script:, **options)` | Generate video from text |\n| `generate_from_audio(replica_id:, audio_url:, **options)` | Generate video from audio |\n| `get(video_id, verbose: false)` | Get a video by ID |\n| `list(**options)` | List all videos |\n| `rename(video_id, video_name)` | Rename a video |\n| `delete(video_id, hard: false)` | Delete a video |\n\n## JSON Patch Operations\n\nSeveral resources (Personas, Objectives, and Guardrails) support updates via JSON Patch operations following [RFC 6902](https://tools.ietf.org/html/rfc6902). This allows for precise, atomic updates to specific fields.\n\n### Supported Operations\n\n- `add`: Add a new field or array element\n- `remove`: Remove a field or array element\n- `replace`: Replace an existing field value\n- `copy`: Copy a value from one location to another\n- `move`: Move a value from one location to another\n- `test`: Test that a value at a location equals a specified value\n\n### Examples\n\n```ruby\n# Replace a single field\noperations = [\n  { op: 'replace', path: '/persona_name', value: 'New Name' }\n]\n\n# Multiple operations in one request\noperations = [\n  { op: 'replace', path: '/persona_name', value: 'Updated Name' },\n  { op: 'add', path: '/layers/tts/tts_emotion_control', value: 'true' },\n  { op: 'remove', path: '/layers/stt/hotwords' }\n]\n\n# Update nested fields\noperations = [\n  { op: 'replace', path: '/layers/llm/model', value: 'tavus-gpt-4o' }\n]\n```\n\n## Development\n\nAfter 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.\n\nTo install this gem onto your local machine, run `bundle exec rake install`.\n\n## CI/CD\n\nThis project uses GitHub Actions for continuous integration:\n\n- **Tests**: Runs on Ruby 2.7, 3.0, 3.1, 3.2, and 3.3\n- **Linting**: RuboCop style checking\n- **Security**: Bundle audit for dependency vulnerabilities\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/vbrazo/tavus.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Resources\n\n- [Tavus API Documentation](https://docs.tavus.io)\n- [Tavus Developer Portal](https://platform.tavus.io)\n- [GitHub Repository](https://github.com/vbrazo/tavus)\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes and version history.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbrazo%2Ftavus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvbrazo%2Ftavus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbrazo%2Ftavus/lists"}