last
CI / ruff (push) Has been cancelled
CI / mypy (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / package (push) Has been cancelled
CI / Install smoke (${{ matrix.label }}) (linux, ubuntu-latest) (push) Has been cancelled
CI / Install smoke (${{ matrix.label }}) (macos-arm64, macos-14) (push) Has been cancelled
CI / ruff (push) Has been cancelled
CI / mypy (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / package (push) Has been cancelled
CI / Install smoke (${{ matrix.label }}) (linux, ubuntu-latest) (push) Has been cancelled
CI / Install smoke (${{ matrix.label }}) (macos-arm64, macos-14) (push) Has been cancelled
This commit is contained in:
@@ -44,6 +44,8 @@ se exponen en el mismo servidor HTTP mediante una API REST de 11 endpoints.
|
||||
| **Detección automática de idioma** | A través de `lingua-language-detector` para el idioma de la respuesta del asistente. |
|
||||
| **Transcripción parcial en vivo** | Parakeet-TDT emite transcripciones parciales cada 500 ms para que los clientes muestren el texto "el usuario está hablando…". |
|
||||
| **Soporte completo de tool-calling** | Con el backend `responses-api`: entrega en streaming de argumentos de función, tool calls paralelos, voces personalizadas sobre TTS — todo conforme a la superficie de la Responses API de OpenAI. |
|
||||
| **Llamadas a herramientas dinámicas siempre frescas** | Regla de sistema de máxima prioridad doble (canales voz y texto) garantiza que cualquier herramienta de información dinámica/en vivo como `get_user_briefing`, el tiempo, calendario, estado, búsquedas y consultas a bases de datos se **vuelva a invocar en cada petición del usuario** — nunca se contesta desde el historial. La regla se inyecta dos veces (inicio + final del prompt) usando bloques 🔴 OBLIGATORIO para maximizar la adhesión de los LLMs modernos con fine-tuning de instrucciones. |
|
||||
| **Guardia anti-marcadores internos en la ruta TTS** | Filtro de dos capas (en `LMOutputProcessor` + por cada handler TTS) que suprime automáticamente las frases que contienen marcadores de control internos como `<<<APIPILOT_CALL:...>>>`, de modo que el asistente nunca habla literalmente las directivas de invocación de herramientas mientras las sigue enrutando por el canal de texto. |
|
||||
| **Inyección RAG opcional en el servidor** | Hook transparente de recuperación en cada turno del LLM. Embeddings con Sentence-Transformers, persistencia del índice NPZ, top-k / umbral coseno configurables, inyección como mensaje del sistema o del usuario. Multilingüe por defecto (español / italiano / inglés listos para usar). |
|
||||
| **API REST para base de conocimientos dinámica** | 11 endpoints para listar, buscar, hacer upsert, actualizar, eliminar y recargar contenidos de la KB en tiempo real — con persistencia entre reinicios mediante `kb/_dynamic.jsonl`. |
|
||||
| **Configuración estructurada CLI / JSON** | Cada parámetro es un argumento `@dataclass` de HfArgumentParser con valores predeterminados razonables, o un fichero JSON de configuración completo que puedes pasar como único argumento. |
|
||||
@@ -95,6 +97,7 @@ Invariantes clave:
|
||||
- **La etapa LLM nunca ve audio crudo**. La pipeline solo envía buffers de texto al manejador del LLM, por lo que cambiar de proveedor o de modelo sigue siendo transparente.
|
||||
- **La etapa RAG es un efecto lateral puro sobre el búfer de texto**: lee el texto más reciente del usuario, ejecuta un embedding + top-k por coseno + filtro por umbral, y antepone el conocimiento relevante como un mensaje adicional del sistema (o del usuario) — con una línea de registro clara para ver siempre exactamente qué se inyectó.
|
||||
- **TTS en streaming** (todos los backends modernos): los deltas de audio se emiten a medida que se sintetizan, por lo que el primer byte de una respuesta llega al altavoz mucho antes de que el LLM termine de generar el texto.
|
||||
- **Los marcadores internos nunca llegan al altavoz**: `LMOutputProcessor` (handover LLM→TTS) **y** cada handler TTS individual ejecutan `contains_internal_markers()` de [`utils.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/utils/utils.py#L60-L86) y cortan anticipadamente cualquier fragmento que contenga directivas de herramienta como `APIPILOT_CALL:...`. Los marcadores siguen fluyendo por el canal lateral de texto para que los clientes puedan reaccionar a las invocaciones.
|
||||
|
||||
---
|
||||
|
||||
@@ -146,6 +149,8 @@ Configurables mediante [ModuleArguments.mode](file:///home/azurian/speech-to-spe
|
||||
|
||||
Todos los backends de TTS se acceden a través de una interfaz de streaming común, por lo que el resto de la pipeline es agnóstica al backend.
|
||||
|
||||
Cada handler TTS, junto con el [`lm_output_processor.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/LLM/lm_output_processor.py) de etapa previa, hace cumplir la **invariante de marcadores internos**: cualquier frase que contenga directivas de invocación de herramientas como `<<<APIPILOT_CALL:NAME=...,ARGUMENTS=...>>>` se filtra **antes** de que comience la síntesis de audio. Los patrones de marcadores viven en un único lugar: [`utils/utils.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/utils/utils.py#L60-L86) (véase `contains_internal_markers`).
|
||||
|
||||
---
|
||||
|
||||
## 6. RAG del lado servidor (complemento opcional)
|
||||
@@ -274,6 +279,7 @@ speech-to-speech/
|
||||
│ ├── s2s_pipeline.py ← punto de entrada (main), constructor de pipeline, pool realtime
|
||||
│ ├── baseHandler.py
|
||||
│ ├── chat.py
|
||||
│ ├── utils/utils.py ← helpers compartidos: `response_wants_audio`, `contains_internal_markers` (filtro anti-APIPILOT)
|
||||
│ ├── pipeline/ ← tipos de cola, CancelScope, tipos de handler
|
||||
│ │
|
||||
│ ├── arguments_classes/ ← args HfArgumentParser @dataclass (uno por handler)
|
||||
|
||||
@@ -42,6 +42,8 @@ Dynamic knowledge base updates are exposed over the same HTTP server via a 11-en
|
||||
| **Automatic language detection** | Via `lingua-language-detector` for the assistant reply language. |
|
||||
| **Live partial transcription** | Parakeet-TDT emits live partial transcriptions every 500 ms so clients can display "user is speaking …" text. |
|
||||
| **Full tool-calling support** | With `responses-api` backend: streamed function argument delivery, parallel tool calls, custom voices over TTS — everything compliant with the OpenAI Responses API surface. |
|
||||
| **Always-fresh dynamic tool calls** | Dual highest-priority system prompt rule (voice & text channels) guarantees that any dynamic/live information tool such as `get_user_briefing`, weather, calendar, status, search, and database lookups is **re-invoked on every user request** — never answered from chat history. The rule is injected twice (prompt head + prompt tail) using 🔴 MANDATORY blocks to maximise compliance with modern instruction-tuned LLMs. |
|
||||
| **Internal-marker guard on TTS path** | Two-layer filter (in `LMOutputProcessor` + per-TTS handler) automatically suppresses utterances that contain internal control markers such as `<<<APIPILOT_CALL:...>>>`, so the assistant never literally speaks tool-call directives while still routing them over the text channel. |
|
||||
| **Optional RAG server-side injection** | Transparent retrieval hook on every LLM turn. Sentence-Transformers embeddings, NPZ-index persistence, configurable top-k / cosine threshold, system or user-message injection. Multilingual by default (Spanish / Italian / English out of the box). |
|
||||
| **Dynamic Knowledge Base REST API** | 11 endpoints to list, search, upsert, update, remove, and reload KB contents at runtime — including cross-restart persistence through `kb/_dynamic.jsonl`. |
|
||||
| **Structured CLI / JSON configuration** | Every parameter is a `@dataclass` HfArgumentParser argument with sane defaults, or a full JSON config file you can pass in as single argument. |
|
||||
@@ -93,6 +95,7 @@ Key invariants:
|
||||
- **The LLM stage never sees raw audio**. The pipeline only forwards text buffers to the LLM handler, so model vendors and backend switches remain transparent.
|
||||
- **The RAG stage is a pure side-effect on the text buffer**: it reads the most recent user text, runs an embedding + cosine top-k + threshold filter, and prepends matching knowledge as an extra system (or user) message — with a clear log line so you can always see exactly what was injected.
|
||||
- **TTS streams** (all modern backends): audio deltas are emitted as they are synthesised, so the first byte of a reply reaches the speaker well before the LLM has finished generating text.
|
||||
- **Internal markers never reach the speaker**: `LMOutputProcessor` (LLM→TTS handover) **and** each individual TTS handler run `contains_internal_markers()` from [`utils.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/utils/utils.py#L60-L86) and short-circuit any chunk that contains tool-call payloads such as `APIPILOT_CALL:...`. Markers still flow through the text side-channel so clients can react to tool invocations.
|
||||
|
||||
---
|
||||
|
||||
@@ -144,6 +147,8 @@ Configurable via [ModuleArguments.mode](file:///home/azurian/speech-to-speech/sr
|
||||
|
||||
All TTS backends are reachable through a common streaming interface so the rest of the pipeline is backend-agnostic.
|
||||
|
||||
Every TTS handler, together with the upstream [`lm_output_processor.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/LLM/lm_output_processor.py), enforces the **internal-marker invariant**: any utterance containing tool-call control payloads such as `<<<APIPILOT_CALL:NAME=...,ARGUMENTS=...>>>` is filtered out **before** audio synthesis begins. The marker patterns live in a single place: [`utils/utils.py`](file:///home/azurian/speech-to-speech/src/speech_to_speech/utils/utils.py#L60-L86) (see `contains_internal_markers`).
|
||||
|
||||
---
|
||||
|
||||
## 6. RAG Server-Side (optional add-on)
|
||||
@@ -272,6 +277,7 @@ speech-to-speech/
|
||||
│ ├── s2s_pipeline.py ← entry point (main), pipeline builder, realtime pool
|
||||
│ ├── baseHandler.py
|
||||
│ ├── chat.py
|
||||
│ ├── utils/utils.py ← shared helpers: `response_wants_audio`, `contains_internal_markers` (anti-APIPILOT filter)
|
||||
│ ├── pipeline/ ← queue types, CancelScope, handler types
|
||||
│ │
|
||||
│ ├── arguments_classes/ ← @dataclass HfArgumentParser args (one per handler)
|
||||
|
||||
Reference in New Issue
Block a user