trustgraph/docs/tech-specs/python-api-refactor.pt.md
Alex Jenkins 8954fa3ad7 Feat: TrustGraph i18n & Documentation Translation Updates (#781)
Native CLI i18n: The TrustGraph CLI has built-in translation support
that dynamically loads language strings. You can test and use
different languages by simply passing the --lang flag (e.g., --lang
es for Spanish, --lang ru for Russian) or by configuring your
environment's LANG variable.

Automated Docs Translations: This PR introduces autonomously
translated Markdown documentation into several target languages,
including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew,
Arabic, Simplified Chinese, and Russian.
2026-04-14 12:08:32 +01:00

53 KiB

layout title parent
default Python API Refactor Technical Specification Portuguese (Beta)

Python API Refactor Technical Specification

Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.

Overview

Esta especificação descreve uma refatoração abrangente da biblioteca de cliente da API Python TrustGraph para alcançar a paridade de recursos com o API Gateway e adicionar suporte para padrões de comunicação em tempo real modernos.

A refatoração aborda quatro casos de uso primários:

  1. Interações de LLM em Streaming: Habilitar o streaming em tempo real de respostas de LLM (agente, RAG de grafo, RAG de documento, conclusão de texto, prompts) com uma latência ~60 vezes menor (500ms vs 30s para o primeiro token).
  2. Operações em Lote: Suportar a importação/exportação eficiente em lote de triplas, incorporações de grafos e incorporações de documentos para gerenciamento de grafos de conhecimento em grande escala.
  3. Paridade de Recursos: Garantir que cada endpoint do API Gateway tenha um método de API Python correspondente, incluindo a consulta de incorporações de grafos.
  4. Conexões Persistentes: Habilitar a comunicação baseada em WebSocket para solicitações multiplexadas e redução da sobrecarga de conexão.

Objetivos

Paridade de Recursos: Cada serviço do Gateway API tem um método de API Python correspondente. Suporte para Streaming: Todos os serviços capazes de streaming (agente, RAG, conclusão de texto, prompt) suportam streaming na API Python. Transporte WebSocket: Adicionar uma camada de transporte WebSocket opcional para conexões persistentes e multiplexação. Operações em Lote: Adicionar importação/exportação eficiente em lote para triplas, incorporações de grafos e incorporações de documentos. Suporte Completo Async: Implementação completa de async/await para todas as interfaces (REST, WebSocket, operações em lote, métricas). Compatibilidade com Versões Anteriores: O código existente continua a funcionar sem modificação. Segurança de Tipos: Manter interfaces com segurança de tipos com dataclasses e dicas de tipo. Aprimoramento Progressivo: Streaming e async são opcionais por meio da seleção explícita da interface. Desempenho: Alcançar uma melhoria de latência de 60 vezes para operações de streaming. Python Moderno: Suporte para paradigmas sync e async para máxima flexibilidade.

Contexto

Estado Atual

A API Python (trustgraph-base/trustgraph/api/) é uma biblioteca de cliente REST somente com os seguintes módulos:

flow.py: Gerenciamento de fluxo e serviços com escopo de fluxo (50 métodos). library.py: Operações da biblioteca de documentos (9 métodos). knowledge.py: Gerenciamento central do KG (4 métodos). collection.py: Metadados da coleção (3 métodos). config.py: Gerenciamento de configuração (6 métodos). types.py: Definições de tipo de dados (5 dataclasses).

Operações Totais: 50/59 (85% de cobertura).

Limitações Atuais

Operações Ausentes: Consulta de incorporações de grafos (busca semântica sobre entidades de grafos). Importação/exportação em lote para triplas, incorporações de grafos, incorporações de documentos, contextos de entidades, objetos. Endpoint de métricas.

Capacidades Ausentes: Suporte para streaming para serviços de LLM. Transporte WebSocket. Solicitações concorrentes multiplexadas. Conexões persistentes.

Problemas de Desempenho: Alta latência para interações de LLM (~30s para o primeiro token). Transferência de dados em lote ineficiente (requisição REST por item). Sobrecarga de conexão para várias operações sequenciais.

Problemas de Experiência do Usuário: Sem feedback em tempo real durante a geração de LLM. Não é possível cancelar operações de LLM em execução prolongada. Má escalabilidade para operações em lote.

Impacto

O aprimoramento de streaming do API Gateway em novembro de 2024 proporcionou uma melhoria de latência de 60 vezes (500ms vs 30s para o primeiro token) para interações de LLM, mas os usuários da API Python não podem aproveitar essa capacidade. Isso cria uma lacuna significativa de experiência entre usuários de Python e não usuários de Python.

Design Técnico

Arquitetura

A API Python refatorada usa uma abordagem de interface modular com objetos separados para diferentes padrões de comunicação. Todas as interfaces estão disponíveis tanto em variantes síncronas quanto assíncronas:

  1. Interface REST (existente, aprimorada). Sync: api.flow(), api.library(), api.knowledge(), api.collection(), api.config(). Async: api.async_flow(). Requisição/resposta síncrona/assíncrona. Modelo de conexão simples. Padrão para compatibilidade com versões anteriores.

  2. Interface WebSocket (nova). Sync: api.socket(). Async: api.async_socket(). Conexão persistente. Solicitações multiplexadas. Suporte para streaming. Mesmas assinaturas de método do REST onde a funcionalidade se sobrepõe.

  3. Interface de Operações em Lote (nova). Sync: api.bulk(). Async: api.async_bulk(). Baseado em WebSocket para eficiência. Importação/exportação baseada em iterador/AsyncIterator. Lida com grandes conjuntos de dados.

  4. Interface de Métricas (nova). Sync: api.metrics(). Async: api.async_metrics(). Acesso a métricas Prometheus.

import asyncio

# Synchronous interfaces
api = Api(url="http://localhost:8088/")

# REST (existing, unchanged)
flow = api.flow().id("default")
response = flow.agent(question="...", user="...")

# WebSocket (new)
socket_flow = api.socket().flow("default")
response = socket_flow.agent(question="...", user="...")
for chunk in socket_flow.agent(question="...", user="...", streaming=True):
    print(chunk)

# Bulk operations (new)
bulk = api.bulk()
bulk.import_triples(flow="default", triples=triple_generator())

# Asynchronous interfaces
async def main():
    api = Api(url="http://localhost:8088/")

    # Async REST (new)
    flow = api.async_flow().id("default")
    response = await flow.agent(question="...", user="...")

    # Async WebSocket (new)
    socket_flow = api.async_socket().flow("default")
    async for chunk in socket_flow.agent(question="...", streaming=True):
        print(chunk)

    # Async bulk operations (new)
    bulk = api.async_bulk()
    await bulk.import_triples(flow="default", triples=async_triple_generator())

asyncio.run(main())

Princípios de Design Chave: Mesmo URL para todas as interfaces: Api(url="http://localhost:8088/") funciona para todas. Simetria Síncrona/Assíncrona: Cada interface possui variantes síncronas e assíncronas com assinaturas de método idênticas. Assinaturas Idênticas: Onde a funcionalidade se sobrepõe, as assinaturas dos métodos são idênticas entre REST e WebSocket, síncronas e assíncronas. Melhoria Progressiva: Escolha a interface com base nas necessidades (REST para tarefas simples, WebSocket para streaming, Bulk para grandes conjuntos de dados, assíncrono para frameworks modernos). Intenção Explícita: api.socket() sinaliza WebSocket, api.async_socket() sinaliza WebSocket assíncrono. Compatível com versões anteriores: Código existente permanece inalterado.

Componentes

1. Classe de API Principal (Modificada)

Módulo: trustgraph-base/trustgraph/api/api.py

Classe de API Aprimorada:

class Api:
    def __init__(self, url: str, timeout: int = 60, token: Optional[str] = None):
        self.url = url
        self.timeout = timeout
        self.token = token  # Optional bearer token for REST, query param for WebSocket
        self._socket_client = None
        self._bulk_client = None
        self._async_flow = None
        self._async_socket_client = None
        self._async_bulk_client = None

    # Existing synchronous methods (unchanged)
    def flow(self) -> Flow:
        """Synchronous REST-based flow interface"""
        pass

    def library(self) -> Library:
        """Synchronous REST-based library interface"""
        pass

    def knowledge(self) -> Knowledge:
        """Synchronous REST-based knowledge interface"""
        pass

    def collection(self) -> Collection:
        """Synchronous REST-based collection interface"""
        pass

    def config(self) -> Config:
        """Synchronous REST-based config interface"""
        pass

    # New synchronous methods
    def socket(self) -> SocketClient:
        """Synchronous WebSocket-based interface for streaming operations"""
        if self._socket_client is None:
            self._socket_client = SocketClient(self.url, self.timeout, self.token)
        return self._socket_client

    def bulk(self) -> BulkClient:
        """Synchronous bulk operations interface for import/export"""
        if self._bulk_client is None:
            self._bulk_client = BulkClient(self.url, self.timeout, self.token)
        return self._bulk_client

    def metrics(self) -> Metrics:
        """Synchronous metrics interface"""
        return Metrics(self.url, self.timeout, self.token)

    # New asynchronous methods
    def async_flow(self) -> AsyncFlow:
        """Asynchronous REST-based flow interface"""
        if self._async_flow is None:
            self._async_flow = AsyncFlow(self.url, self.timeout, self.token)
        return self._async_flow

    def async_socket(self) -> AsyncSocketClient:
        """Asynchronous WebSocket-based interface for streaming operations"""
        if self._async_socket_client is None:
            self._async_socket_client = AsyncSocketClient(self.url, self.timeout, self.token)
        return self._async_socket_client

    def async_bulk(self) -> AsyncBulkClient:
        """Asynchronous bulk operations interface for import/export"""
        if self._async_bulk_client is None:
            self._async_bulk_client = AsyncBulkClient(self.url, self.timeout, self.token)
        return self._async_bulk_client

    def async_metrics(self) -> AsyncMetrics:
        """Asynchronous metrics interface"""
        return AsyncMetrics(self.url, self.timeout, self.token)

    # Resource management
    def close(self) -> None:
        """Close all synchronous connections"""
        if self._socket_client:
            self._socket_client.close()
        if self._bulk_client:
            self._bulk_client.close()

    async def aclose(self) -> None:
        """Close all asynchronous connections"""
        if self._async_socket_client:
            await self._async_socket_client.aclose()
        if self._async_bulk_client:
            await self._async_bulk_client.aclose()
        if self._async_flow:
            await self._async_flow.aclose()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    async def __aenter__(self):
        return self

    async def __aexit__(self, *args):
        await self.aclose()

2. Cliente WebSocket Síncrono

Módulo: trustgraph-base/trustgraph/api/socket_client.py (novo)

Classe SocketClient:

class SocketClient:
    """Synchronous WebSocket client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token
        self._connection = None
        self._request_counter = 0

    def flow(self, flow_id: str) -> SocketFlowInstance:
        """Get flow instance for WebSocket operations"""
        return SocketFlowInstance(self, flow_id)

    def _connect(self) -> WebSocket:
        """Establish WebSocket connection (lazy)"""
        # Uses asyncio.run() internally to wrap async websockets library
        pass

    def _send_request(
        self,
        service: str,
        flow: Optional[str],
        request: Dict[str, Any],
        streaming: bool = False
    ) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
        """Send request and handle response/streaming"""
        # Synchronous wrapper around async WebSocket calls
        pass

    def close(self) -> None:
        """Close WebSocket connection"""
        pass

class SocketFlowInstance:
    """Synchronous WebSocket flow instance with same interface as REST FlowInstance"""
    def __init__(self, client: SocketClient, flow_id: str):
        self.client = client
        self.flow_id = flow_id

    # Same method signatures as FlowInstance
    def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        streaming: bool = False,
        **kwargs
    ) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
        """Agent with optional streaming"""
        pass

    def text_completion(
        self,
        system: str,
        prompt: str,
        streaming: bool = False,
        **kwargs
    ) -> Union[str, Iterator[str]]:
        """Text completion with optional streaming"""
        pass

    # ... similar for graph_rag, document_rag, prompt, etc.

Principais Características: Conexão preguiçosa (conecta apenas quando o primeiro pedido é enviado) Multiplexação de requisições (até 15 simultâneas) Reconexão automática em caso de desconexão Análise de resposta em streaming Operação thread-safe Wrapper síncrono em torno da biblioteca assíncrona de WebSockets

3. Cliente WebSocket Assíncrono

Módulo: trustgraph-base/trustgraph/api/async_socket_client.py (novo)

Classe AsyncSocketClient:

class AsyncSocketClient:
    """Asynchronous WebSocket client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token
        self._connection = None
        self._request_counter = 0

    def flow(self, flow_id: str) -> AsyncSocketFlowInstance:
        """Get async flow instance for WebSocket operations"""
        return AsyncSocketFlowInstance(self, flow_id)

    async def _connect(self) -> WebSocket:
        """Establish WebSocket connection (lazy)"""
        # Native async websockets library
        pass

    async def _send_request(
        self,
        service: str,
        flow: Optional[str],
        request: Dict[str, Any],
        streaming: bool = False
    ) -> Union[Dict[str, Any], AsyncIterator[Dict[str, Any]]]:
        """Send request and handle response/streaming"""
        pass

    async def aclose(self) -> None:
        """Close WebSocket connection"""
        pass

class AsyncSocketFlowInstance:
    """Asynchronous WebSocket flow instance"""
    def __init__(self, client: AsyncSocketClient, flow_id: str):
        self.client = client
        self.flow_id = flow_id

    # Same method signatures as FlowInstance (but async)
    async def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        streaming: bool = False,
        **kwargs
    ) -> Union[Dict[str, Any], AsyncIterator[Dict[str, Any]]]:
        """Agent with optional streaming"""
        pass

    async def text_completion(
        self,
        system: str,
        prompt: str,
        streaming: bool = False,
        **kwargs
    ) -> Union[str, AsyncIterator[str]]:
        """Text completion with optional streaming"""
        pass

    # ... similar for graph_rag, document_rag, prompt, etc.

Principais Características: Suporte nativo para async/await Eficiente para aplicações assíncronas (FastAPI, aiohttp) Sem bloqueio de threads Mesma interface da versão síncrona AsyncIterator para streaming

4. Cliente de Operações em Lote Síncronas

Módulo: trustgraph-base/trustgraph/api/bulk_client.py (novo)

Classe BulkClient:

class BulkClient:
    """Synchronous bulk operations client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token

    def import_triples(
        self,
        flow: str,
        triples: Iterator[Triple],
        **kwargs
    ) -> None:
        """Bulk import triples via WebSocket"""
        pass

    def export_triples(
        self,
        flow: str,
        **kwargs
    ) -> Iterator[Triple]:
        """Bulk export triples via WebSocket"""
        pass

    def import_graph_embeddings(
        self,
        flow: str,
        embeddings: Iterator[Dict[str, Any]],
        **kwargs
    ) -> None:
        """Bulk import graph embeddings via WebSocket"""
        pass

    def export_graph_embeddings(
        self,
        flow: str,
        **kwargs
    ) -> Iterator[Dict[str, Any]]:
        """Bulk export graph embeddings via WebSocket"""
        pass

    # ... similar for document embeddings, entity contexts, objects

    def close(self) -> None:
        """Close connections"""
        pass

Principais Características: Baseado em iteradores para uso constante de memória. Conexões WebSocket dedicadas por operação. Rastreamento de progresso (callback opcional). Tratamento de erros com relatórios de sucesso parcial.

5. Cliente de Operações em Massa Assíncronas

Módulo: trustgraph-base/trustgraph/api/async_bulk_client.py (novo)

Classe AsyncBulkClient:

class AsyncBulkClient:
    """Asynchronous bulk operations client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token

    async def import_triples(
        self,
        flow: str,
        triples: AsyncIterator[Triple],
        **kwargs
    ) -> None:
        """Bulk import triples via WebSocket"""
        pass

    async def export_triples(
        self,
        flow: str,
        **kwargs
    ) -> AsyncIterator[Triple]:
        """Bulk export triples via WebSocket"""
        pass

    async def import_graph_embeddings(
        self,
        flow: str,
        embeddings: AsyncIterator[Dict[str, Any]],
        **kwargs
    ) -> None:
        """Bulk import graph embeddings via WebSocket"""
        pass

    async def export_graph_embeddings(
        self,
        flow: str,
        **kwargs
    ) -> AsyncIterator[Dict[str, Any]]:
        """Bulk export graph embeddings via WebSocket"""
        pass

    # ... similar for document embeddings, entity contexts, objects

    async def aclose(self) -> None:
        """Close connections"""
        pass

Principais Características: Baseado em AsyncIterator para uso constante de memória Eficiente para aplicações assíncronas Suporte nativo para async/await Mesma interface da versão síncrona

6. API REST Flow (Síncrona - Inalterada)

Módulo: trustgraph-base/trustgraph/api/flow.py

A API REST Flow permanece completamente inalterada para compatibilidade com versões anteriores. Todos os métodos existentes continuam a funcionar:

Flow.list(), Flow.start(), Flow.stop(), etc. FlowInstance.agent(), FlowInstance.text_completion(), FlowInstance.graph_rag(), etc. Todas as assinaturas e tipos de retorno existentes preservados

Novo: Adicione graph_embeddings_query() a REST FlowInstance para paridade de recursos:

class FlowInstance:
    # All existing methods unchanged...

    # New: Graph embeddings query (REST)
    def graph_embeddings_query(
        self,
        text: str,
        user: str,
        collection: str,
        limit: int = 10,
        **kwargs
    ) -> List[Dict[str, Any]]:
        """Query graph embeddings for semantic search"""
        # Calls POST /api/v1/flow/{flow}/service/graph-embeddings
        pass

7. API de Fluxo REST Assíncrono

Módulo: trustgraph-base/trustgraph/api/async_flow.py (novo)

Classes AsyncFlow e AsyncFlowInstance:

class AsyncFlow:
    """Asynchronous REST-based flow interface"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    async def list(self) -> List[Dict[str, Any]]:
        """List all flows"""
        pass

    async def get(self, id: str) -> Dict[str, Any]:
        """Get flow definition"""
        pass

    async def start(self, class_name: str, id: str, description: str, parameters: Dict) -> None:
        """Start a flow"""
        pass

    async def stop(self, id: str) -> None:
        """Stop a flow"""
        pass

    def id(self, flow_id: str) -> AsyncFlowInstance:
        """Get async flow instance"""
        return AsyncFlowInstance(self.url, self.timeout, self.token, flow_id)

    async def aclose(self) -> None:
        """Close connection"""
        pass

class AsyncFlowInstance:
    """Asynchronous REST flow instance"""

    async def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        **kwargs
    ) -> Dict[str, Any]:
        """Async agent execution"""
        pass

    async def text_completion(
        self,
        system: str,
        prompt: str,
        **kwargs
    ) -> str:
        """Async text completion"""
        pass

    async def graph_rag(
        self,
        question: str,
        user: str,
        collection: str,
        **kwargs
    ) -> str:
        """Async graph RAG"""
        pass

    # ... all other FlowInstance methods as async versions

Principais Características: HTTP assíncrono nativo usando aiohttp ou httpx Mesmas assinaturas de método da API REST síncrona Sem streaming (use async_socket() para streaming) Eficiente para aplicações assíncronas

8. API de Métricas

Módulo: trustgraph-base/trustgraph/api/metrics.py (novo)

Métricas Síncronas:

class Metrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

Métricas Assíncronas:

class AsyncMetrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    async def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

9. Tipos Aprimorados

Módulo: trustgraph-base/trustgraph/api/types.py (modificado)

Novos Tipos:

from typing import Iterator, Union, Dict, Any
import dataclasses

@dataclasses.dataclass
class StreamingChunk:
    """Base class for streaming chunks"""
    content: str
    end_of_message: bool = False

@dataclasses.dataclass
class AgentThought(StreamingChunk):
    """Agent reasoning chunk"""
    chunk_type: str = "thought"

@dataclasses.dataclass
class AgentObservation(StreamingChunk):
    """Agent tool observation chunk"""
    chunk_type: str = "observation"

@dataclasses.dataclass
class AgentAnswer(StreamingChunk):
    """Agent final answer chunk"""
    chunk_type: str = "final-answer"
    end_of_dialog: bool = False

@dataclasses.dataclass
class RAGChunk(StreamingChunk):
    """RAG streaming chunk"""
    end_of_stream: bool = False
    error: Optional[Dict[str, str]] = None

# Type aliases for clarity
AgentStream = Iterator[Union[AgentThought, AgentObservation, AgentAnswer]]
RAGStream = Iterator[RAGChunk]
CompletionStream = Iterator[str]

6. API de Métricas

Módulo: trustgraph-base/trustgraph/api/metrics.py (novo)

class Metrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

Abordagem de Implementação

Fase 1: Aprimoramento da API Central (Semana 1)

  1. Adicionar métodos socket(), bulk() e metrics() à classe Api
  2. Implementar inicialização preguiçosa para clientes WebSocket e em lote
  3. Adicionar suporte a gerenciador de contexto (__enter__, __exit__)
  4. Adicionar método close() para limpeza
  5. Adicionar testes unitários para aprimoramentos da classe da API
  6. Verificar compatibilidade com versões anteriores

Compatibilidade com versões anteriores: Nenhuma alteração disruptiva. Apenas novos métodos.

Fase 2: Cliente WebSocket (Semana 2-3)

  1. Implementar classe SocketClient com gerenciamento de conexão
  2. Implementar SocketFlowInstance com as mesmas assinaturas de método de FlowInstance
  3. Adicionar suporte para multiplexação de solicitações (até 15 simultâneas)
  4. Adicionar análise de resposta em streaming para diferentes tipos de fragmentos
  5. Adicionar lógica de reconexão automática
  6. Adicionar testes unitários e de integração
  7. Documentar padrões de uso do WebSocket

Compatibilidade com versões anteriores: Nova interface apenas. Sem impacto no código existente.

Fase 3: Suporte a Streaming (Semana 3-4)

  1. Adicionar classes de tipo de fragmento de streaming (AgentThought, AgentObservation, AgentAnswer, RAGChunk)
  2. Implementar análise de resposta em streaming em SocketClient
  3. Adicionar parâmetro de streaming a todos os métodos LLM em SocketFlowInstance
  4. Lidar com casos de erro durante o streaming
  5. Adicionar testes unitários e de integração para streaming
  6. Adicionar exemplos de streaming à documentação

Compatibilidade com versões anteriores: Nova interface apenas. API REST existente inalterada.

Fase 4: Operações em Lote (Semana 4-5)

  1. Implementar classe BulkClient
  2. Adicionar métodos de importação/exportação em lote para triplas, incorporações, contextos, objetos
  3. Implementar processamento baseado em iterador para uso de memória constante
  4. Adicionar rastreamento de progresso (callback opcional)
  5. Adicionar tratamento de erros com relatório de sucesso parcial
  6. Adicionar testes unitários e de integração
  7. Adicionar exemplos de operações em lote

Compatibilidade com versões anteriores: Nova interface apenas. Sem impacto no código existente.

Fase 5: Paridade de Recursos e Refinamento (Semana 5)

  1. Adicionar graph_embeddings_query() ao REST FlowInstance
  2. Implementar classe Metrics
  3. Adicionar testes de integração abrangentes
  4. Teste de desempenho
  5. Atualizar toda a documentação
  6. Criar guia de migração

Compatibilidade com versões anteriores: Novos métodos apenas. Sem impacto no código existente.

Modelos de Dados

Seleção de Interface

# Single API instance, same URL for all interfaces
api = Api(url="http://localhost:8088/")

# Synchronous interfaces
rest_flow = api.flow().id("default")           # Sync REST
socket_flow = api.socket().flow("default")     # Sync WebSocket
bulk = api.bulk()                               # Sync bulk operations
metrics = api.metrics()                         # Sync metrics

# Asynchronous interfaces
async_rest_flow = api.async_flow().id("default")      # Async REST
async_socket_flow = api.async_socket().flow("default") # Async WebSocket
async_bulk = api.async_bulk()                          # Async bulk operations
async_metrics = api.async_metrics()                    # Async metrics

Tipos de Resposta de Streaming

Streaming do Agente:

api = Api(url="http://localhost:8088/")

# REST interface - non-streaming (existing)
rest_flow = api.flow().id("default")
response = rest_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# WebSocket interface - non-streaming (same signature)
socket_flow = api.socket().flow("default")
response = socket_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# WebSocket interface - streaming (new)
for chunk in socket_flow.agent(question="What is ML?", user="user123", streaming=True):
    if isinstance(chunk, AgentThought):
        print(f"Thinking: {chunk.content}")
    elif isinstance(chunk, AgentObservation):
        print(f"Observed: {chunk.content}")
    elif isinstance(chunk, AgentAnswer):
        print(f"Answer: {chunk.content}")
        if chunk.end_of_dialog:
            break

Streaming RAG:

api = Api(url="http://localhost:8088/")

# REST interface - non-streaming (existing)
rest_flow = api.flow().id("default")
response = rest_flow.graph_rag(question="What is Python?", user="user123", collection="default")
print(response)

# WebSocket interface - streaming (new)
socket_flow = api.socket().flow("default")
for chunk in socket_flow.graph_rag(
    question="What is Python?",
    user="user123",
    collection="default",
    streaming=True
):
    print(chunk.content, end="", flush=True)
    if chunk.end_of_stream:
        break

Operações em Lote (Síncronas):

api = Api(url="http://localhost:8088/")

# Bulk import triples
def triple_generator():
    yield Triple(s="http://ex.com/alice", p="http://ex.com/type", o="Person")
    yield Triple(s="http://ex.com/alice", p="http://ex.com/name", o="Alice")
    yield Triple(s="http://ex.com/bob", p="http://ex.com/type", o="Person")

bulk = api.bulk()
bulk.import_triples(flow="default", triples=triple_generator())

# Bulk export triples
for triple in bulk.export_triples(flow="default"):
    print(f"{triple.s} -> {triple.p} -> {triple.o}")

Operações em Lote (Assíncronas):

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async bulk import triples
    async def async_triple_generator():
        yield Triple(s="http://ex.com/alice", p="http://ex.com/type", o="Person")
        yield Triple(s="http://ex.com/alice", p="http://ex.com/name", o="Alice")
        yield Triple(s="http://ex.com/bob", p="http://ex.com/type", o="Person")

    bulk = api.async_bulk()
    await bulk.import_triples(flow="default", triples=async_triple_generator())

    # Async bulk export triples
    async for triple in bulk.export_triples(flow="default"):
        print(f"{triple.s} -> {triple.p} -> {triple.o}")

asyncio.run(main())

Exemplo de REST Assíncrono:

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async REST flow operations
    flow = api.async_flow().id("default")
    response = await flow.agent(question="What is ML?", user="user123")
    print(response["response"])

asyncio.run(main())

Exemplo de Streaming WebSocket Assíncrono:

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async WebSocket streaming
    socket = api.async_socket()
    flow = socket.flow("default")

    async for chunk in flow.agent(question="What is ML?", user="user123", streaming=True):
        if isinstance(chunk, AgentAnswer):
            print(chunk.content, end="", flush=True)
            if chunk.end_of_dialog:
                break

asyncio.run(main())

APIs

New APIs

  1. Classe de API Core: Síncrono: Api.socket() - Obter cliente WebSocket síncrono Api.bulk() - Obter cliente de operações em lote síncrono Api.metrics() - Obter cliente de métricas síncrono Api.close() - Fechar todas as conexões síncronas Suporte a gerenciador de contexto (__enter__, __exit__) Assíncrono: Api.async_flow() - Obter cliente de fluxo REST assíncrono Api.async_socket() - Obter cliente WebSocket assíncrono Api.async_bulk() - Obter cliente de operações em lote assíncrono Api.async_metrics() - Obter cliente de métricas assíncrono Api.aclose() - Fechar todas as conexões assíncronas Suporte a gerenciador de contexto assíncrono (__aenter__, __aexit__)

  2. Cliente WebSocket Síncrono: SocketClient.flow(flow_id) - Obter instância de fluxo WebSocket SocketFlowInstance.agent(..., streaming: bool = False) - Agente com streaming opcional SocketFlowInstance.text_completion(..., streaming: bool = False) - Conclusão de texto com streaming opcional SocketFlowInstance.graph_rag(..., streaming: bool = False) - Graph RAG com streaming opcional SocketFlowInstance.document_rag(..., streaming: bool = False) - Document RAG com streaming opcional SocketFlowInstance.prompt(..., streaming: bool = False) - Prompt com streaming opcional SocketFlowInstance.graph_embeddings_query() - Consulta de embeddings de grafo Todos os outros métodos FlowInstance com assinaturas idênticas

  3. Cliente WebSocket Assíncrono: AsyncSocketClient.flow(flow_id) - Obter instância de fluxo WebSocket assíncrono AsyncSocketFlowInstance.agent(..., streaming: bool = False) - Agente assíncrono com streaming opcional AsyncSocketFlowInstance.text_completion(..., streaming: bool = False) - Conclusão de texto assíncrona com streaming opcional AsyncSocketFlowInstance.graph_rag(..., streaming: bool = False) - Graph RAG assíncrono com streaming opcional AsyncSocketFlowInstance.document_rag(..., streaming: bool = False) - Document RAG assíncrono com streaming opcional AsyncSocketFlowInstance.prompt(..., streaming: bool = False) - Prompt assíncrono com streaming opcional AsyncSocketFlowInstance.graph_embeddings_query() - Consulta de embeddings de grafo assíncrona Todos os outros métodos FlowInstance como versões assíncronas

  4. Cliente de Operações em Lote Síncrono: BulkClient.import_triples(flow, triples) - Importação em lote de triplas BulkClient.export_triples(flow) - Exportação em lote de triplas BulkClient.import_graph_embeddings(flow, embeddings) - Importação em lote de embeddings de grafo BulkClient.export_graph_embeddings(flow) - Exportação em lote de embeddings de grafo BulkClient.import_document_embeddings(flow, embeddings) - Importação em lote de embeddings de documentos BulkClient.export_document_embeddings(flow) - Exportação em lote de embeddings de documentos BulkClient.import_entity_contexts(flow, contexts) - Importação em lote de contextos de entidades BulkClient.export_entity_contexts(flow) - Exportação em lote de contextos de entidades BulkClient.import_objects(flow, objects) - Importação em lote de objetos

  5. Cliente de Operações em Lote Assíncrono: AsyncBulkClient.import_triples(flow, triples) - Importação assíncrona em lote de triplas AsyncBulkClient.export_triples(flow) - Exportação assíncrona em lote de triplas AsyncBulkClient.import_graph_embeddings(flow, embeddings) - Importação assíncrona em lote de embeddings de grafo AsyncBulkClient.export_graph_embeddings(flow) - Exportação assíncrona em lote de embeddings de grafo AsyncBulkClient.import_document_embeddings(flow, embeddings) - Importação assíncrona em lote de embeddings de documentos AsyncBulkClient.export_document_embeddings(flow) - Exportação assíncrona em lote de embeddings de documentos AsyncBulkClient.import_entity_contexts(flow, contexts) - Importação assíncrona em lote de contextos de entidades AsyncBulkClient.export_entity_contexts(flow) - Exportação assíncrona em lote de contextos de entidades AsyncBulkClient.import_objects(flow, objects) - Importação assíncrona em lote de objetos

  6. Cliente de Fluxo REST Assíncrono: AsyncFlow.list() - Listar todos os fluxos de forma assíncrona AsyncFlow.get(id) - Obter definição de fluxo de forma assíncrona AsyncFlow.start(...) - Iniciar fluxo de forma assíncrona AsyncFlow.stop(id) - Parar fluxo de forma assíncrona AsyncFlow.id(flow_id) - Obter instância de fluxo de forma assíncrona AsyncFlowInstance.agent(...) - Execução de agente assíncrona AsyncFlowInstance.text_completion(...) - Conclusão de texto assíncrona AsyncFlowInstance.graph_rag(...) - Graph RAG assíncrono Todos os outros métodos FlowInstance como versões assíncronas

  7. Clientes de Métricas: Metrics.get() - Métricas Prometheus síncronas AsyncMetrics.get() - Métricas Prometheus assíncronas

  8. Aprimoramento da API de Fluxo REST: FlowInstance.graph_embeddings_query() - Consulta de embeddings de grafo (paridade de recursos síncrona) AsyncFlowInstance.graph_embeddings_query() - Consulta de embeddings de grafo (paridade de recursos assíncrona)

APIs Modificadas

  1. Construtor (melhoria menor):

    Api(url: str, timeout: int = 60, token: Optional[str] = None)
    

    Adicionado parâmetro token (opcional, para autenticação) Se None (padrão): Nenhuma autenticação utilizada Se especificado: Usado como token bearer para REST (Authorization: Bearer <token>), parâmetro de consulta para WebSocket (?token=<token>) Nenhuma outra alteração - totalmente compatível com versões anteriores

  2. Nenhuma Alteração Significativa: Todos os métodos da API REST existentes permanecem inalterados Todas as assinaturas existentes são preservadas Todos os tipos de retorno existentes são preservados

Detalhes da Implementação

Tratamento de Erros

Erros de Conexão WebSocket:

try:
    api = Api(url="http://localhost:8088/")
    socket = api.socket()
    socket_flow = socket.flow("default")
    response = socket_flow.agent(question="...", user="user123")
except ConnectionError as e:
    print(f"WebSocket connection failed: {e}")
    print("Hint: Ensure Gateway is running and WebSocket endpoint is accessible")

Fallback Elegante:

api = Api(url="http://localhost:8088/")

try:
    # Try WebSocket streaming first
    socket_flow = api.socket().flow("default")
    for chunk in socket_flow.agent(question="...", user="...", streaming=True):
        print(chunk.content)
except ConnectionError:
    # Fall back to REST non-streaming
    print("WebSocket unavailable, falling back to REST")
    rest_flow = api.flow().id("default")
    response = rest_flow.agent(question="...", user="...")
    print(response["response"])

Erros de Streaming Parcial:

api = Api(url="http://localhost:8088/")
socket_flow = api.socket().flow("default")

accumulated = []
try:
    for chunk in socket_flow.graph_rag(question="...", streaming=True):
        accumulated.append(chunk.content)
        if chunk.error:
            print(f"Error occurred: {chunk.error}")
            print(f"Partial response: {''.join(accumulated)}")
            break
except Exception as e:
    print(f"Streaming error: {e}")
    print(f"Partial response: {''.join(accumulated)}")

Gerenciamento de Recursos

Suporte a Gerenciadores de Contexto:

# Automatic cleanup
with Api(url="http://localhost:8088/") as api:
    socket_flow = api.socket().flow("default")
    response = socket_flow.agent(question="...", user="user123")
# All connections automatically closed

# Manual cleanup
api = Api(url="http://localhost:8088/")
try:
    socket_flow = api.socket().flow("default")
    response = socket_flow.agent(question="...", user="user123")
finally:
    api.close()  # Explicitly close all connections (WebSocket, bulk, etc.)

Threads e Concorrência

Segurança de Threads: Cada instância de Api mantém sua própria conexão. O transporte WebSocket usa bloqueios para multiplexação de solicitações com segurança de thread. Múltiplas threads podem compartilhar uma instância de Api com segurança. Iteradores de streaming não são seguros para threads (consumir de uma única thread).

Suporte Assíncrono (consideração futura):

# Phase 2 enhancement (not in initial scope)
import asyncio

async def main():
    api = await AsyncApi(url="ws://localhost:8088/")
    flow = api.flow().id("default")

    async for chunk in flow.agent(question="...", streaming=True):
        print(chunk.content)

    await api.close()

asyncio.run(main())

Considerações de Segurança

Autenticação

Parâmetro de Token:

# No authentication (default)
api = Api(url="http://localhost:8088/")

# With authentication
api = Api(url="http://localhost:8088/", token="mytoken")

Transporte REST: Token do transportador via cabeçalho Authorization Aplicado automaticamente a todas as requisições REST Formato: Authorization: Bearer <token>

Transporte WebSocket: Token via parâmetro de consulta anexado à URL do WebSocket Aplicado automaticamente durante o estabelecimento da conexão Formato: ws://localhost:8088/api/v1/socket?token=<token>

Implementação:

class SocketClient:
    def _connect(self) -> WebSocket:
        # Construct WebSocket URL with optional token
        ws_url = f"{self.url}/api/v1/socket"
        if self.token:
            ws_url = f"{ws_url}?token={self.token}"
        # Connect to WebSocket
        return websocket.connect(ws_url)

Exemplo:

# REST with auth
api = Api(url="http://localhost:8088/", token="mytoken")
flow = api.flow().id("default")
# All REST calls include: Authorization: Bearer mytoken

# WebSocket with auth
socket = api.socket()
# Connects to: ws://localhost:8088/api/v1/socket?token=mytoken

Comunicação Segura

Suporta os esquemas WS (WebSocket) e WSS (WebSocket Secure). Validação de certificado TLS para conexões WSS. Verificação de certificado opcional para desenvolvimento (com aviso).

Validação de Entrada

Valida esquemas de URL (http, https, ws, wss). Valida valores de parâmetros de transporte. Valida combinações de parâmetros de streaming. Valida tipos de dados para importação em lote.

Considerações de Desempenho

Melhorias de Latência

Operações LLM em Streaming: Tempo para o primeiro token: ~500ms (vs ~30s sem streaming) Melhoria: 60 vezes mais rápido em termos de desempenho percebido. Aplicável a: Agente, Graph RAG, Document RAG, Geração de Texto, Prompt.

Conexões Persistentes: Sobrecarga de conexão: Eliminada para solicitações subsequentes. Handshake WebSocket: Custo único (~100ms). Aplicável a: Todas as operações ao usar o transporte WebSocket.

Melhorias de Throughput

Operações em Lote: Importação de triplas: ~10.000 triplas/segundo (vs ~100/segundo com REST por item). Importação de embeddings: ~5.000 embeddings/segundo (vs ~50/segundo com REST por item). Melhoria: 100 vezes mais rápido para operações em lote.

Multiplexação de Requisições: Requisições concorrentes: Até 15 requisições simultâneas sobre uma única conexão. Reutilização de conexão: Sem sobrecarga de conexão para operações concorrentes.

Considerações de Memória

Respostas em Streaming: Uso constante de memória (processa os chunks à medida que chegam). Sem bufferização da resposta completa. Adequado para saídas muito longas (>1MB).

Operações em Lote: Processamento baseado em iterador (uso constante de memória). Sem carregamento do conjunto de dados inteiro na memória. Adequado para conjuntos de dados com milhões de itens.

Benchmarks (Esperados)

Operação REST (existente) WebSocket (streaming) Melhoria
Agente (tempo para o primeiro token) 30s 0.5s 60x
Graph RAG (tempo para o primeiro token) 25s 0.5s 50x
Importação de 10K triplas 100s 1s 100x
Importação de 1M triplas 10.000s (2.7h) 100s (1.6m) 100x
10 requisições pequenas concorrentes 5s (sequencial) 0.5s (paralelo) 10x

Estratégia de Testes

Testes Unitários

Camada de Transporte (test_transport.py): Testar requisição/resposta de transporte REST Testar conexão de transporte WebSocket Testar reconexão de transporte WebSocket Testar multiplexação de requisições Testar análise de resposta em streaming Simular um servidor WebSocket para testes determinísticos

Métodos da API (test_flow.py, test_library.py, etc.): Testar novos métodos com transporte simulado Testar tratamento de parâmetros em streaming Testar iteradores de operações em lote Testar tratamento de erros

Tipos (test_types.py): Testar novos tipos de fragmentos em streaming Testar serialização/desserialização de tipos

Testes de Integração

REST de Ponta a Ponta (test_integration_rest.py): Testar todas as operações contra o Gateway real (modo REST) Verificar compatibilidade com versões anteriores Testar condições de erro

WebSocket de Ponta a Ponta (test_integration_websocket.py): Testar todas as operações contra o Gateway real (modo WebSocket) Testar operações de streaming Testar operações em lote Testar requisições concorrentes Testar recuperação de conexão

Serviços de Streaming (test_streaming_integration.py): Testar streaming de agentes (pensamentos, observações, respostas) Testar streaming RAG (fragmentos incrementais) Testar streaming de conclusão de texto (token por token) Testar streaming de prompts Testar tratamento de erros durante o streaming

Operações em Lote (test_bulk_integration.py): Testar importação/exportação em lote de triplas (1K, 10K, 100K itens) Testar importação/exportação em lote de embeddings Testar o uso de memória durante operações em lote Testar o rastreamento de progresso

Testes de Desempenho

Benchmarks de Latência (test_performance_latency.py): Medir o tempo para o primeiro token (streaming vs não streaming) Medir a sobrecarga de conexão (REST vs WebSocket) Comparar com benchmarks esperados

Benchmarks de Throughput (test_performance_throughput.py): Medir o throughput de importação em lote Medir a eficiência da multiplexação de requisições Comparar com benchmarks esperados

Testes de Compatibilidade

Compatibilidade com Versões Anteriores (test_backward_compatibility.py): Executar o conjunto de testes existente contra a API refatorada Verificar a ausência de alterações que quebrem a compatibilidade Testar o caminho de migração para padrões comuns

Plano de Migração

Fase 1: Migração Transparente (Padrão)

Não são necessárias alterações no código. O código existente continua a funcionar:

# Existing code works unchanged
api = Api(url="http://localhost:8088/")
flow = api.flow().id("default")
response = flow.agent(question="What is ML?", user="user123")

Fase 2: Streaming Opcional (Simples)

Use a interface api.socket() para habilitar o streaming:

# Before: Non-streaming REST
api = Api(url="http://localhost:8088/")
rest_flow = api.flow().id("default")
response = rest_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# After: Streaming WebSocket (same parameters!)
api = Api(url="http://localhost:8088/")  # Same URL
socket_flow = api.socket().flow("default")

for chunk in socket_flow.agent(question="What is ML?", user="user123", streaming=True):
    if isinstance(chunk, AgentAnswer):
        print(chunk.content, end="", flush=True)

Pontos-chave: Mesma URL para REST e WebSocket Mesmas assinaturas de método (fácil migração) Basta adicionar .socket() e streaming=True

Fase 3: Operações em Lote (Nova Funcionalidade)

Use a interface api.bulk() para grandes conjuntos de dados:

# Before: Inefficient per-item operations
api = Api(url="http://localhost:8088/")
flow = api.flow().id("default")

for triple in my_large_triple_list:
    # Slow per-item operations
    # (no direct bulk insert in REST API)
    pass

# After: Efficient bulk loading
api = Api(url="http://localhost:8088/")  # Same URL
bulk = api.bulk()

# This is fast (10,000 triples/second)
bulk.import_triples(flow="default", triples=iter(my_large_triple_list))

Atualizações na Documentação

  1. README.md: Adicionar exemplos de streaming e WebSocket
  2. Referência da API: Documentar todos os novos métodos e parâmetros
  3. Guia de Migração: Guia passo a passo para habilitar o streaming
  4. Exemplos: Adicionar scripts de exemplo para padrões comuns
  5. Guia de Desempenho: Documentar as melhorias de desempenho esperadas

Política de Descontinuação

Nenhuma descontinuação. Todas as APIs existentes permanecem suportadas. Esta é uma melhoria pura.

Cronograma

Semana 1: Fundação

Camada de abstração de transporte Refatorar o código REST existente Testes unitários para a camada de transporte Verificação de compatibilidade com versões anteriores

Semana 2: Transporte WebSocket

Implementação do transporte WebSocket Gerenciamento de conexão e reconexão Multiplexação de requisições Testes unitários e de integração

Semana 3: Suporte a Streaming

Adicionar parâmetro de streaming aos métodos LLM Implementar análise de resposta de streaming Adicionar tipos de fragmentos de streaming Testes de integração de streaming

Semana 4: Operações em Lote

Adicionar métodos de importação/exportação em lote Implementar operações baseadas em iteradores Testes de desempenho Testes de integração de operações em lote

Semana 5: Paridade de Recursos e Documentação

Adicionar consulta de incorporações de grafos Adicionar API de métricas Documentação abrangente Guia de migração Versão candidata

Semana 6: Lançamento

Testes de integração finais Benchmarking de desempenho Documentação de lançamento Anúncio para a comunidade

Duração Total: 6 semanas

Perguntas Abertas

Perguntas de Design da API

  1. Suporte Assíncrono: RESOLVIDO - Suporte assíncrono completo incluído no lançamento inicial Todas as interfaces possuem variantes assíncronas: async_flow(), async_socket(), async_bulk(), async_metrics() Fornece total simetria entre as APIs síncronas e assíncronas Essencial para frameworks assíncronos modernos (FastAPI, aiohttp)

  2. Rastreamento de Progresso: As operações em lote devem suportar callbacks de progresso?

    def progress_callback(processed: int, total: Optional[int]):
        print(f"Processed {processed} items")
    
    bulk.import_triples(flow="default", triples=triples, on_progress=progress_callback)
    

    Recomendação: Adicionar na Fase 2. Não é crítico para a versão inicial.

  3. Tempo Limite de Streaming: Como devemos tratar os tempos limite para operações de streaming? Recomendação: Usar o mesmo tempo limite que as operações não-streaming, mas resetar a cada bloco recebido.

  4. Bufferização de Blocos: Devemos bufferizar os blocos ou retornar imediatamente? Recomendação: Retornar imediatamente para a menor latência.

  5. Serviços Globais via WebSocket: api.socket() deve suportar serviços globais (biblioteca, conhecimento, coleção, configuração) ou apenas serviços específicos do fluxo? Recomendação: Começar apenas com serviços específicos do fluxo (onde o streaming é importante). Adicionar serviços globais, se necessário, na Fase 2.

Perguntas de Implementação

  1. Biblioteca WebSocket: Devemos usar websockets, websocket-client ou aiohttp? Recomendação: websockets (assíncrono, maduro, bem mantido). Envolver em uma interface síncrona usando asyncio.run().

  2. Pool de Conexões: Devemos suportar múltiplas instâncias concorrentes de Api compartilhando um pool de conexões? Recomendação: Adiar para a Fase 2. Cada instância de Api terá suas próprias conexões inicialmente.

  3. Reutilização de Conexões: SocketClient e BulkClient devem compartilhar a mesma conexão WebSocket, ou usar conexões separadas? Recomendação: Conexões separadas. Implementação mais simples, separação mais clara de responsabilidades.

  4. Conexão Preguiçosa vs. Ansiosa: A conexão WebSocket deve ser estabelecida em api.socket() ou na primeira requisição? Recomendação: Preguiçosa (na primeira requisição). Evita a sobrecarga da conexão se o usuário usar apenas métodos REST.

Perguntas de Teste

  1. Gateway Mock: Devemos criar um Gateway mock leve para testes, ou testar contra o Gateway real? Recomendação: Ambos. Usar mocks para testes unitários, Gateway real para testes de integração.

  2. Testes de Regressão de Desempenho: Devemos adicionar testes de regressão de desempenho automatizados ao CI? Recomendação: Sim, mas com limites generosos para levar em conta a variabilidade do ambiente do CI.

Referências

Especificações Técnicas Relacionadas

docs/tech-specs/streaming-llm-responses.md - Implementação de streaming no Gateway docs/tech-specs/rag-streaming-support.md - Suporte de streaming RAG

Arquivos de Implementação

trustgraph-base/trustgraph/api/ - Código fonte da API Python trustgraph-flow/trustgraph/gateway/ - Código fonte do Gateway trustgraph-flow/trustgraph/gateway/dispatch/mux.py - Implementação de referência de multiplexador WebSocket

Documentação

docs/apiSpecification.md - Referência completa da API docs/api-status-summary.md - Resumo do status da API README.websocket - Documentação do protocolo WebSocket STREAMING-IMPLEMENTATION-NOTES.txt - Notas sobre a implementação de streaming

Bibliotecas Externas

websockets - Biblioteca WebSocket Python (https://websockets.readthedocs.io/) requests - Biblioteca HTTP Python (existente)