diff --git a/.changeset/shiny-emus-change.md b/.changeset/shiny-emus-change.md new file mode 100644 index 000000000..8e2423c2e --- /dev/null +++ b/.changeset/shiny-emus-change.md @@ -0,0 +1,5 @@ +--- +"livekit-plugins-llama-index": patch +--- + +Publish llama-index plugin diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 129e794bf..5be08fc1d 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -12,13 +12,13 @@ on: workflow_dispatch: inputs: package: - description: 'Name of the package to build' + description: "Name of the package to build" required: true - default: 'livekit-plugins-browser' + default: "livekit-plugins-browser" artifact_name: - description: 'Artifact name for the distribution package' + description: "Artifact name for the distribution package" required: true - default: 'build-artifact' + default: "build-artifact" jobs: build_plugins: @@ -35,7 +35,8 @@ jobs: inputs.package == 'livekit-plugins-openai' || inputs.package == 'livekit-plugins-rag' || inputs.package == 'livekit-plugins-silero' || - inputs.package == 'livekit-plugins-anthropic' + inputs.package == 'livekit-plugins-anthropic' || + inputs.package == 'livekit-plugins-llama-index' defaults: run: @@ -98,4 +99,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: ${{ inputs.artifact_name }} - path: livekit-plugins/livekit-plugins-browser/dist/ \ No newline at end of file + path: livekit-plugins/livekit-plugins-browser/dist/ diff --git a/.github/workflows/check-types.yml b/.github/workflows/check-types.yml index 927c9e2eb..9bc413831 100644 --- a/.github/workflows/check-types.yml +++ b/.github/workflows/check-types.yml @@ -20,7 +20,6 @@ jobs: with: submodules: recursive - - uses: actions/setup-python@v5 with: python-version: "3.9" @@ -41,7 +40,8 @@ jobs: ./livekit-plugins/livekit-plugins-cartesia \ ./livekit-plugins/livekit-plugins-rag \ ./livekit-plugins/livekit-plugins-azure \ - ./livekit-plugins/livekit-plugins-anthropic + ./livekit-plugins/livekit-plugins-anthropic \ + ./livekit-plugins/livekit-plugins-llama-index - name: Install stub packages run: | diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 8c5f924bd..d6ced9dc8 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -3,7 +3,7 @@ name: Publish docs on: workflow_dispatch: workflow_call: - secrets: + secrets: DOCS_DEPLOY_AWS_ACCESS_KEY: {} DOCS_DEPLOY_AWS_API_SECRET: {} @@ -19,7 +19,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.12' # Specify the Python version you want to use + python-version: "3.12" # Specify the Python version you want to use - name: Create and activate virtual environment run: | @@ -42,7 +42,10 @@ jobs: ./livekit-plugins/livekit-plugins-elevenlabs \ ./livekit-plugins/livekit-plugins-google \ ./livekit-plugins/livekit-plugins-nltk \ - ./livekit-plugins/livekit-plugins-openai + ./livekit-plugins/livekit-plugins-openai \ + ./livekit-plugins/livekit-plugins-rag \ + ./livekit-plugins/livekit-plugins-silero \ + ./livekit-plugins/livekit-plugins-llama-index - name: Build Docs run: | @@ -56,4 +59,4 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.DOCS_DEPLOY_AWS_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DOCS_DEPLOY_AWS_API_SECRET }} - AWS_DEFAULT_REGION: "us-east-1" \ No newline at end of file + AWS_DEFAULT_REGION: "us-east-1" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9d6f73da0..7febfaed6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,11 +13,8 @@ on: jobs: tests: - if: > # don't run tests for PRs on forks - ${{ - !github.event.pull_request || - github.event.pull_request.head.repo.full_name == github.repository - }} + # don't run tests for PRs on forks + if: github.repository == 'livekit/agents' strategy: fail-fast: false matrix: @@ -41,10 +38,23 @@ jobs: submodules: true lfs: true + - name: Cache packages + uses: actions/cache@v4 + with: + path: | + /var/cache/apt/archives + ~/Library/Caches/Homebrew + C:\ProgramData\chocolatey\lib\ffmpeg + key: ${{ runner.os }}-cache + restore-keys: | + ${{ runner.os }}-cache + - uses: actions/setup-python@v5 + # on mac, ffmpeg installs python + if: ${{ matrix.os != 'macos' }} with: - python-version: '3.9' - cache: 'pip' + python-version: "3.9" + cache: "pip" - name: Install ffmpeg (Linux) if: ${{ matrix.platform == 'linux' }} diff --git a/livekit-agents/livekit/agents/pipeline/human_input.py b/livekit-agents/livekit/agents/pipeline/human_input.py index 10342662b..b54ba6f28 100644 --- a/livekit-agents/livekit/agents/pipeline/human_input.py +++ b/livekit-agents/livekit/agents/pipeline/human_input.py @@ -80,18 +80,14 @@ def _subscribe_to_microphone(self, *args, **kwargs) -> None: if not publication.subscribed: publication.set_subscribed(True) - if ( - publication.track is not None - and publication.track != self._subscribed_track - ): - self._subscribed_track = publication.track # type: ignore + track: rtc.RemoteAudioTrack | None = publication.track # type: ignore + if track is not None and track != self._subscribed_track: + self._subscribed_track = track if self._recognize_atask is not None: self._recognize_atask.cancel() self._recognize_atask = asyncio.create_task( - self._recognize_task( - rtc.AudioStream(self._subscribed_track, sample_rate=16000) - ) # type: ignore + self._recognize_task(rtc.AudioStream(track, sample_rate=16000)) ) break diff --git a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py index b3ae6b9ee..d5357b604 100644 --- a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py +++ b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py @@ -172,7 +172,7 @@ def _on_speech_end(self, evt: speechsdk.SpeechRecognitionEventArgs): def _on_session_stopped(self, evt: speechsdk.SpeechRecognitionEventArgs): self._loop.call_soon_threadsafe(self._done_event.set) - def _threadsafe_send(self, evt: stt.SpeechEvent | None): + def _threadsafe_send(self, evt: stt.SpeechEvent): self._loop.call_soon_threadsafe(self._event_ch.send_nowait, evt) diff --git a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py index 5d0183d60..99c6b5d94 100644 --- a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py +++ b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py @@ -206,4 +206,4 @@ def _gender_from_str(gender: str) -> SsmlVoiceGender: elif gender == "female": ssml_gender = SsmlVoiceGender.FEMALE - return ssml_gender + return ssml_gender # type: ignore diff --git a/livekit-plugins/livekit-plugins-llama-index/README.md b/livekit-plugins/livekit-plugins-llama-index/README.md index 006906528..1c2b3add1 100644 --- a/livekit-plugins/livekit-plugins-llama-index/README.md +++ b/livekit-plugins/livekit-plugins-llama-index/README.md @@ -1,14 +1,36 @@ -# LiveKit Plugins Minimal +# LiveKit Plugins Llama Index -This is a minimal example of a LiveKit plugin for Agents. +Agent Framework plugin for using Llama Index. Currently supports [Query Engine](https://docs.llamaindex.ai/en/stable/module_guides/deploying/query_engine/) and [Chat Engine](https://docs.llamaindex.ai/en/stable/module_guides/deploying/chat_engines/). -### Developer note +## Install -When copying this directory over to create a new `livekit-plugins` package, make sure it's nested within the `livekit-plugins` folder and that the `"name"` field in `package.json` follows the proper naming convention for CI: +```bash +pip install livekit-plugins-llama-index +``` + +## Query Engine + +Query Engine is primarily used for RAG. See [example voice agent](https://github.com/livekit/agents/blob/main/examples/voice-pipeline-agent/llamaindex-rag/query_engine.py) + +## Chat Engine -```json -{ - "name": "livekit-plugins-", - "private": true -} +Chat Engine can be used as an LLM within the framework. + +```python +# load the existing index +storage_context = StorageContext.from_defaults(persist_dir=) +index = load_index_from_storage(storage_context) + +async def entrypoint(ctx: JobContext): + ... + chat_engine = index.as_chat_engine(chat_mode=ChatMode.CONTEXT) + assistant = VoicePipelineAgent( + vad=silero.VAD.load(), + stt=deepgram.STT(), + llm=llama_index.LLM(chat_engine=chat_engine), + tts=openai.TTS(), + chat_ctx=initial_ctx, + ) ``` + +full example [here](https://github.com/livekit/agents/blob/main/examples/voice-pipeline-agent/llamaindex-rag/chat_engine.py)