Skip to content

feat(llm): Promote TwelveLabs video RAG components into xpacks core#256

Open
iapoorv01 wants to merge 3 commits into
pathwaycom:mainfrom
iapoorv01:feature/twelvelabs-video-rag
Open

feat(llm): Promote TwelveLabs video RAG components into xpacks core#256
iapoorv01 wants to merge 3 commits into
pathwaycom:mainfrom
iapoorv01:feature/twelvelabs-video-rag

Conversation

@iapoorv01

Copy link
Copy Markdown
Contributor

Introduction

This PR resolves #255 by officially promoting the TwelveLabsVideoParser and MarengoEmbedder out of the llm-app examples template and integrating them natively into the pathway.xpacks.llm core library.

This enables native, first-class Video RAG capabilities (parsing raw video bytes into Pegasus text descriptions and retrieving them using a shared multimodal embedding space) directly out of the box in Pathway.

Context

Currently, Pathway's core LLM xpack handles PDFs, DOCX, and slides exceptionally well, but has lacked native multimodal video handling. Previously introduced as an app template in PR #129, the TwelveLabs components proved stable and highly valuable. Promoting them to the core xpacks library eliminates the need for developers to maintain boilerplate API scaffolding when building multimodal search applications.

Design Decisions & Approach:

  • Modular Component Folding: Instead of creating a monolithic twelvelabs.py file, we strictly adhered to Pathway's architectural patterns by natively integrating MarengoEmbedder into embedders.py and TwelveLabsVideoParser into parsers.py.
  • Zero-Bloat Dependency Architecture: We opted for a strict lazy-import approach. The twelvelabs SDK is not a hard dependency. It sits securely in a new [twelvelabs] optional extra block in pyproject.toml. The components leverage a robust try/except ImportError guidance pattern to safely prompt users to run pip install pathway[twelvelabs] only if they attempt to instantiate the classes without the SDK.
  • Asynchronous Scalability & Resource Management: We preserved the crucial asyncio.gather pipeline for the Embedder to prevent thread-blocking under load. Furthermore, the Parser correctly utilizes a try/finally block to proactively delete TwelveLabs assets (delete_assets=True by default) so users do not accidentally flood their cloud workspace with zombie assets during repeated pipeline runs.

How has this been tested?

All tests have been ported from the template environment into the native test suite at python/pathway/xpacks/llm/tests/test_twelvelabs.py.

  • No-Network Unit Tests: Verified the __wrapped__ async concurrency behaviors, asset cleanup lifecycle, and fallback failure modes using the strict _FakeClient stubbing pattern.
  • Type-Checker Alignment: Refactored legacy IDE/Mypy workarounds from the template test suite (such as redundant sys.modules stubs) to align cleanly with the core [tests] environment runtime guarantees.
  • Live Smoke Testing: Maintained the live API dimension probe, successfully gating it behind @pytest.mark.skipif(not os.environ.get("TWELVELABS_API_KEY")) to guarantee zero disruptions to the standard CI pipeline.
  • All files have been successfully formatted against the strict isort and black hooks.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature or improvement (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Related issue(s):

  1. Resolves Promote TwelveLabsVideoParser and MarengoEmbedder from the Video RAG template into pathway.xpacks.llm #255

Checklist:

  • My code follows the code style of this project,
  • My change requires a change to the documentation,
  • I described the modification in the CHANGELOG.md file.

@iapoorv01 iapoorv01 force-pushed the feature/twelvelabs-video-rag branch from a526624 to f60073e Compare June 30, 2026 20:09
iapoorv01 and others added 3 commits July 1, 2026 01:41
This commit promotes the TwelveLabs integration from the template directory into the native pathway.xpacks.llm core library, as proposed in pathwaycom#255.

Key changes:
- pyproject.toml: Introduced a new [twelvelabs] optional dependency extra.
- embedders.py: Promoted MarengoEmbedder into pathway.xpacks.llm.embedders. It inherits from BaseEmbedder and leverages an async pathway (_aembed_one) via asyncio.gather for concurrent embedding generation, preventing thread blocking. It implements the lazy ImportError pattern.
- parsers.py: Promoted TwelveLabsVideoParser into pathway.xpacks.llm.parsers. Implemented proper resource cleanup logic using try/finally blocks to explicitly delete TwelveLabs assets (when delete_assets=True) preventing asset flooding on the API. Also implements the lazy ImportError pattern.
- test_twelvelabs.py: Ported the unit tests into python/pathway/xpacks/llm/tests/. Contains no-network test coverage via stubbed SDK mocks. The live smoke test is maintained but securely gated behind the TWELVELABS_API_KEY existence check.
- CHANGELOG.md: Added an entry under [Unreleased] -> Added documenting the promotion.

This effectively extends Pathway's live-sync multimodal indexing capabilities to handle full video ingestion over the TwelveLabs network natively.
Comment thread pyproject.toml
"Office365-REST-Python-Client >= 2.5.3",
]
twelvelabs = [
"twelvelabs >= 0.3.0",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This floor is too low and is a regression against the template: the original requirements.txt, module docstring, and ImportError message all require twelvelabs>=1.2.8. The code needs at least 1.2.x — AsyncTwelveLabs and twelvelabs.types.video_context don't exist in 0.3.x, and the assets client only appears in 1.2.0.

An environment that already has an older SDK installed satisfies >=0.3.0, so pip won't upgrade it, and the parser then fails at runtime with ModuleNotFoundError (and the embedder raises the misleading "package is required" hint even though the package is installed). Please change to twelvelabs >= 1.2.8.

)


def _resolve_twelvelabs_api_key(api_key: str | None) -> str:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two helpers (_resolve_twelvelabs_api_key, _build_twelvelabs_client) are verbatim copies of the ones added to embedders.py in this same PR — in the template they existed once. Since the split across two modules forces a shared home, please move them to python/pathway/xpacks/llm/_utils.py (both modules already import from it) and import them in both places.

While you're there, consider replacing the hand-rolled try/except ImportError with the xpack's standard with optional_imports("twelvelabs"): — it's what every other optional-SDK component in these files uses and produces the same pip install pathway[twelvelabs] guidance.

Returns:
A list of 512-dimensional ``numpy`` arrays, one per input string.
"""
import asyncio

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: in the template these were top-level imports; the port moved import asyncio (and import os/import time in the other helpers) inside the functions. embedders.py already imports asyncio at module level — please keep stdlib imports at the top; only the twelvelabs import needs to stay lazy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Promote TwelveLabsVideoParser and MarengoEmbedder from the Video RAG template into pathway.xpacks.llm

2 participants