# Time to First Token (TTFT)
# Requires `--features openai-responses` (experimental and off by default).
#
# Measures the elapsed time from request receipt to the first non-empty
# SSE body chunk and records a praxis_ai_ttft_seconds Prometheus
# histogram labeled by model.
#
# Usage:
#   cargo run -p praxis-ai-proxy -- -c examples/configs/time-to-first-token.yaml
#   curl http://localhost:8080/v1/responses -d '{"model":"gpt-4o","input":"hi","stream":true}'
#
# The time_to_first_token filter activates only for successful text/event-stream
# responses. Non-streaming and non-success responses pass through
# without measurement.
#
# A request fact filter (openai_responses_request, openai_chat_completions_request,
# anthropic_messages_request, or anthropic_messages_to_chat_completions) must run
# upstream to set model metadata in the request path. Without one, all TTFT
# samples are labeled "unknown".
#
# This example publishes model facts for Responses and native Chat Completions:
# ai_operation publishes the typed operation head, openai_responses_request reads
# the model from Responses create bodies, and openai_chat_completions_request reads
# it from native POST /v1/chat/completions bodies. Anthropic and translated-to-Chat
# traffic are labeled by their own classifiers.

listeners:
  - name: default
    address: "127.0.0.1:8080"
    filter_chains:
      - main

filter_chains:
  - name: main
    filters:
      # Publishes the typed operation head consumed by the request filters below.
      - filter: ai_operation

      # Labels Responses create traffic with the model from the request body.
      - filter: openai_responses_request
        initialize_state: false

      # Labels native POST /v1/chat/completions traffic with its request model.
      - filter: openai_chat_completions_request

      - filter: router
        routes:
          - path_prefix: "/"
            cluster: backend

      - filter: time_to_first_token

      - filter: load_balancer
        clusters:
          - name: backend
            endpoints:
              - "127.0.0.1:3000"

insecure_options:
  allow_private_endpoints: true # example proxies to local backends
