astonishing-waitress-60915
02/15/2026, 7:19 PMtall-airline-16756
02/15/2026, 7:19 PMtall-airline-16756
02/15/2026, 7:20 PMstart komutuyla başlatabilirsiniz, ancak Agents Playground ile doğrudan test etmek için start doğru seçenek değildir.
Kısa özet:
• start: Üretim (production) amaçlıdır ve Playground ile doğrudan etkileşime girmez.
• dev: Geliştirme ve test içindir; Agents Playground (https://agents-playground.livekit.io/) üzerinden test yapmak istiyorsanız ajanınızı bu modda çalıştırmanız gerekir.
Test adımları (özet):
1. Ajanı dev modunda başlatın:
uv run agent.py dev
1. Tarayıcıda https://agents-playground.livekit.io/ adresine gidin ve LiveKit Cloud projenizle oturum açın.
2. Ajanınız otomatik olarak odalara katılacak ve Playground üzerinden etkileşimli olarak test edebileceksiniz.
Eğer isterseniz, şu bilgileri paylaşırsanız yardımcı olacak daha spesifik adımlar veya hata giderme önerileri verebilirim:
• Hangi işletim sistemi / ortamda çalışıyorsunuz?
• Ajanı başlatırken aldığınız herhangi bir hata mesajı var mı?
• LiveKit Cloud projenizin ayarlarında özel bir yapılandırma var mı? Sources: Voice AI quickstart | LiveKit Documentationastonishing-waitress-60915
02/15/2026, 7:20 PMtall-airline-16756
02/15/2026, 7:21 PMdev modunda çalıştırıyorsun, Playground’da token ile bağlanıyorsun fakat agent odaya katılmıyor. Aşağıda kısa, uygulanabilir kontrol adımları ve hangi bilgileri paylaşırsan daha hızlı yardımcı olabileceğim yer alıyor.
Hemen kontrol etmen gerekenler
• Agent gerçekten dev modunda mı çalışıyor?
◦ Terminalde uv run agent.py dev (veya Node ise pnpm dev) komutunu çalıştırdığını doğrula.
◦ Terminalde hata veya “listening for jobs” gibi loglar görünüyor mu?
• agent_name kullanıyor musun?
◦ Eğer kodunda @server.rtc_session(agent_name="...") gibi bir kullanım varsa agent yalnızca açıkça dispatch edildiğinde odaya katılır. Bu durumda token ile otomatik katılmaz.
◦ Eğer agent_name yoksa (yani @server.rtc_session()), agent yeni odalara otomatik katılır.
• Token oluştururken agent dispatch ekledin mi?
◦ Sadece kullanıcı token’ı odaya sokar; agent’ı dispatch etmek için token’a RoomConfiguration içinde agents=[RoomAgentDispatch(...)] gibi bir yapı eklemelisin. Aksi halde agent dispatch edilmez.
• Ortam değişkenleri doğru mu?
◦ LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL değerlerinin doğru ve güncel olduğundan emin ol.
• Oda adını doğru mu kullandın?
◦ Oda isimlerinde küçük/büyük harf duyarlılığı veya boşluk/özel karakter farkı olabilir.
Hızlı test/çözüm önerileri
1. Geçici olarak agent_name parametresini kaldırıp agent’ı tüm odalara katılacak şekilde başlat:
◦ Böylece Playground’da oluşturduğun oda geldiğinde agent otomatik katılmalı.
1. Token üretirken agent dispatch ekle (Python örneği):
from livekit.api import AccessToken, RoomConfiguration, RoomAgentDispatch
token = (
AccessToken()
.with_identity("user123")
.with_grants(VideoGrants(room_join=True, room="your-room-name"))
.with_room_config(
RoomConfiguration(
agents=[RoomAgentDispatch(agent_name="test-agent", metadata='{"user":"123"}')]
)
)
.to_jwt()
)
1. CLI ile manuel dispatch (varsa):
◦ lk dispatch create --room your-room-name --agent-name test-agent
Ne paylaşırsan daha detaylı yardımcı olurum
• Agent kodundan ilgili kısım (rtc_session decorator ve agent_name kullanımı)
• Token üretme yönteminin kodu veya açıklaması
• Çalıştırdığın komut (tam olarak ne yazdın terminale)
• Terminal log çıktılarından ilgili satırlar
• Oda adı (gizli tutmak istiyorsan maskelenmiş versiyon)
Paylaşırsan adım adım birlikte inceleyip agent’ın odalara katılmasını sağlayalım.
Sources: Agent dispatch | LiveKit Documentation | Voice AI quickstart | LiveKit Documentationastonishing-waitress-60915
02/15/2026, 7:22 PM@server.rtc_session(agent_name="...") gibi bir kullanım varsa agent yalnızca açıkça dispatch edildiğinde odaya katılır. Bu durumda token ile otomatik katılmaz.
Evet var: test-agent agent'ın adı.
Sadece kullanıcı token’ı odaya sokar; agent’ı dispatch etmek için token’a RoomConfiguration içinde agents=[RoomAgentDispatch(...)] gibi bir yapı eklemelisin. Aksi halde agent dispatch edilmez.
Bunu nasıl yapacağım? Sadece lk token create ile token oluşturuyorumtall-airline-16756
02/15/2026, 7:22 PMtest-agent ve şu an tokenları lk token create ile üretiyorsun. Kısa ve net cevap:
• lk token create komutu agent dispatch eklemeyi desteklemez. Bu yüzden sadece bu CLI ile token oluştursan bile agent otomatik olarak odaya katılmaz.
• Agent adı belirtildiği için (@server.rtc_session(agent_name="test-agent")) agent’ın odaya katılması için açık bir dispatch yapılması gerekir.
Ne yapabilirsin (iki yol)
1) Programatik olarak token oluşturup agent dispatch eklemek (önerilen)
• SDK/HTTP API kullanarak token oluştururken RoomConfiguration içine agents=[RoomAgentDispatch(...)] eklemen gerekir. Bu token hem kullanıcıyı odaya sokar hem de `test-agent`i dispatch eder.
• Örnek (Python, kısa):
from livekit import api
from livekit.api import RoomAgentDispatch, RoomConfiguration
token = (
api.AccessToken(api_key="YOUR_KEY", api_secret="YOUR_SECRET", identity="user123")
.with_grants(api.VideoGrants(room_join=True, room="my-room"))
.with_room_config(
RoomConfiguration(
agents=[RoomAgentDispatch(agent_name="test-agent", metadata='{"user":"123"}')]
)
)
.to_jwt()
)
print(token)
• İstersen Node.js veya Go örneğini de gönderirim.
2) CLI ile ayrı bir dispatch işlemi yapmak (hızlı alternatif)
• Kullanıcı tokenını ayrı oluşturup odaya bağlandıktan sonra veya öncesinde, agent’ı manuel dispatch edebilirsin:
lk dispatch create --agent-name test-agent --room my-room --metadata '{"user_id":"12345"}'
• Bu komut agent’ı belirtilen odaya atar; kullanıcı token ile odaya bağlanınca agent da odada olur.
Eğer istersen birini adım adım yapalım
• Hangi dili kullanıyorsun (Python/Node/Go)? O dil için tam, kopyala-yapıştır çalışacak örnek vereyim.
• Veya CLI ile manuel dispatch denemek istersen oda adını söyle, gerekli lk komutunu tam şeklinde veririm.
• Ayrıca terminal loglarını paylaşırsan (agent dev modunda çalışırken) birlikte kontrol ederiz.
Hangi yolu tercih ediyorsun? Benimle dilini söyle, örneği hemen gönderirim.
Sources: Agent dispatch | LiveKit Documentationastonishing-waitress-60915
02/15/2026, 7:25 PMtall-airline-16756
02/15/2026, 7:25 PMdev veya connect modunda STT, TTS ve LLM çıktısını (ve özellikle TTFT/TTFB gibi metrikleri) göremiyorsun ve bu yüzden start ile denemek istemişsin. Kısa cevap ve kesin yol haritası aşağıda.
Özet (kısa)
• start modu üretim içindir; interaktif test çıktıları genelde görünmez. Bu yüzden start ile denemek problemi çözmez.
• STT, TTS ve LLM çıktıları ve TTFT/TTFB metrikleri en rahat şekilde console (lokal mock) veya dev modunda ve bir frontend (ör. Agents Playground) ile görülebilir.
• Eğer agent kodunda agent_name = "test-agent" varsa, agent sadece açıkça dispatch edildiğinde odaya katılır; bu da test akışını etkileyebilir.
Ne kontrol etmen gerekiyor (adım adım) 1) Hangi modda çalışıyorsun?
• Test için: önce console ile yerelde deneyip log/transkript çıktısını gör.
◦ Komut: uv run agent.py console
• Gerçek ortam testi için: uv run agent.py dev ve Agents Playground kullan.
2) Frontend kullanıyor musun?
• STT transkriptleri, TTS ses çıkışı ve LLM yanıtı genelde frontende (Agents Playground veya kendi frontend’in) görünür. Sadece agent terminaline bakmak bazen yeterli olmayabilir.
• Öneri: https://agents-playground.livekit.io/ adresine bağlan ve aynı LiveKit projesi ile oturum aç.
3) Agent konfigürasyonunda text_output etkin mi?
• Oturum başlatılırken RoomOptions(text_output=True) veya benzeri bir ayar olması gerekiyor ki transkript/LLM metin çıktıları toplanıp gönderilsin.
4) Agent gerçekten dispatch ediliyor mu?
• Eğer kodda @server.rtc_session(agent_name="test-agent") varsa agent otomatik katılmaz. Ya token ile RoomConfiguration içinde agent dispatch eklemelisin ya da CLI ile manuel dispatch yap:
◦ Manuel dispatch (CLI):
lk dispatch create --agent-name test-agent --room my-room --metadata '{"user_id":"12345"}'
5) Metrikleri görmek:
• TTFT/TTFB gibi metrikler, çalışır bir oturum ve gerçek LLM/TTS çağrıları olduğunda toplanır. dev modunda metrik olaylarını dinleyerek görebilirsin:
◦ Örneğin MetricsCollected olayını dinle ve logla.
Hızlı problemlere dayalı çözümler
• Hiçbir şey görünmüyorsa: büyük olasılıkla ya frontend yok ya da agent dispatch edilmemiş.
• Eğer dev modunda çalışıyor ama frontende hiçbir çıktı gelmiyorsa: .env değişkenlerini (LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL) ve agent loglarını kontrol et.
• Konsolda hızlı test istiyorsan: console modu ile transkripsiyon ve TTS çıktısını gör.
Bana söyleyince adım adım yardımcı olabilirim
• Hangi modu kullandın şu anda? (console, dev veya start)
• Agents Playground mu yoksa kendi frontend’in mi kullanılıyor?
• Agent kodundan şu kısımları paylaşırsan hızlıca bakarım: @server.rtc_session(...) dekoratörü satırı ve varsa `RoomOptions`/başlatma ayarları.
• dev çalıştırırken terminal logunda hangi mesajlar görünüyor? (özellikle hata veya “listening for jobs” vb.)
Tercih ettiğin yolu söyle: hızlı bir console testiyle mi ilerleyelim, yoksa dev + Playground’da agent dispatch akışını mı beraber kurup kontrol edelim?
Sources: Simple Call Answering Agent | LiveKit Documentation | Voice AI quickstart | LiveKit Documentation | Agents playground | LiveKit Documentation | Server options | LiveKit Documentation | Agents (Node.js) | livekit/livekit_composite | DeepWikiastonishing-waitress-60915
02/15/2026, 7:26 PMMetricsCollected
Bunları loglayacağım basit kodu yazar mısın?tall-airline-16756
02/15/2026, 7:26 PMsession senin AgentSession örneğin olmalı; dev veya console modunda çalışırken bu olaylar tetiklenir.
import asyncio
from datetime import datetime
# Örnek async handler: MetricsCollected olayını loglar
async def handle_metrics_collected(event):
m = event.metrics
now = datetime.utcnow().isoformat()
print(f"[MetricsCollected] {now}")
# Örnek alanlar; agent/session kitaplığına göre isimler küçük farklılık gösterebilir
print(f" Source: {getattr(event, 'source', 'unknown')}")
print(f" TTFT: {getattr(m, 'ttft', 'N/A')} s")
print(f" TTFB: {getattr(m, 'ttfb', 'N/A')} s")
print(f" Duration: {getattr(m, 'duration', 'N/A')} s")
print(f" Prompt tokens: {getattr(m, 'prompt_tokens', 'N/A')}")
print(f" Completion tokens: {getattr(m, 'completion_tokens', 'N/A')}")
print(f" Timestamp: {getattr(m, 'timestamp', 'N/A')}")
print("-" * 40)
# session: AgentSession örneği (kendi kodunda zaten oluşturulmuş olmalı)
# session.on ile event adını ve handler'ı kaydet
# Event adlandırması kullandığın SDK sürümüne göre değişebilir; örnek: "metrics_collected" veya AgentSessionEventTypes.MetricsCollected
def attach_metrics_logger(session):
try:
# Eğer SDK string event isimleri kullanıyorsa:
session.on("metrics_collected", handle_metrics_collected)
# Veya enum/const kullanılıyorsa (örnek kullanım, SDK'na uyarlayın):
# from livekit.agents import AgentSessionEventTypes
# session.on(AgentSessionEventTypes.MetricsCollected, handle_metrics_collected)
print("MetricsCollected handler eklendi.")
except Exception as e:
print("MetricsCollected handler eklenirken hata:", e)
Nasıl entegre edersin
• Agent oturumunu başlattıktan sonra (session oluşturulduktan hemen sonra) attach_metrics_logger(session) çağrısını yap.
• dev modunda gerçek çağrılar yapıldığında veya console modunda mock çağrılarla, terminalde metrik loglarını göreceksin.
İstersen ben:
• Kullandığın agent SDK sürümü/isimleri (ör. livekit.agents vs başka) ile örneği tam olarak uyarlayayım.
• Node.js örneğine de çevireyim (eğer Node kullanıyorsan).
Hangi dili/sürümü kullanıyorsun? Hemen uyarlayıp gönderirim.
Sources: LLM Metrics | LiveKit Documentation | TTS Metrics | LiveKit Documentation | STT Metrics | LiveKit Documentation | VAD Metrics | LiveKit Documentationastonishing-waitress-60915
02/15/2026, 7:27 PMtall-airline-16756
02/15/2026, 7:28 PMrecord=True ile başlatılmalı veya proje ayarından kaydı etkinleştirmelisin.
• Sonrasında LiveKit Cloud Dashboard → ilgili room → “Agent insights”/Observability bölümünde TTFT, TTFB, token sayıları, timeline ve senkronize logları görürsün.
Yapman gerekenler — adım adım 1) LiveKit Cloud’da proje ayarları
• Dashboard’a gir → Project Settings → Data and Privacy (veya Recording / Observability) bölümünü aç.
• “Record sessions” ve “Enable Agent Observability” seçeneklerini aktif hale getir.
2) Agent oturumunda kayıtı etkinleştir
• Agent kodunda AgentSession/başlatma kısmında record=True ayarla:
session = AgentSession(..., record=True)
• Eğer kodda record=False ise observability verisi toplanmaz.
3) Agent’ı deploy / çalıştır ve oturumu oluştur
• dev modunda test et: uv run agent.py dev
• Agent’in odaya katıldığını ve job’ların tetiklendiğini doğrula (terminal logları “listening for jobs” vb).
4) Dashboard’dan izle
• LiveKit Cloud’a gir, ilgili room’u aç.
• “Agent insights” veya “Observability” sekmesini seç.
• Timeline’da audio + transcript + turn bazlı trace, TTFT/TTFB, token sayıları ve eş zamanlı logları göreceksin.
Eğer self‑hosted kullanıyorsan
• Bu yerleşik Agent Observability şu an sadece LiveKit Cloud’da mevcut. Self‑hosted isen, aynı görselliği elde etmek için:
◦ MetricsCollected olaylarını dinleyip (kodda) bu metrikleri bir telemetry servisine (Prometheus/Grafana, Loki, Datadog vb.) gönderip dashboard oluşturman gerekir.
◦ İstersen sana örnek Grafana panosu veya Prometheus export kodu gösterebilirim.
Hızlı doğrulama / yardım için bana gönder
• Projeyi LiveKit Cloud’da mı kullanıyorsun yoksa self‑hosted mi?
• Agent kodundan ilgili kısım (AgentSession oluşturma / record ayarı) varsa paylaş — hızlıca kontrol edip düzeltilmesi gereken kısmı söyleyeyim.
• Dashboard’da ilgili room’u açtığında hangi sekmeleri görüyorsun? “Agent insights” görünmüyor mu yoksa boş mu?
İstersen şimdi:
• LiveKit Cloud kullanıyorsan seni adım adım yönlendirip hangi ayarı açacağımızı tam gösteririm.
• Self‑hosted isen hemen bir örnek ile MetricsCollected verilerini Prometheus/Grafana’a nasıl aktaracağına dair kod ve dashboard örneği verebilirim.
Hangi ortamdasın (Cloud mı self‑hosted?) söyle, hemen ilerleyelim.
Sources: Streamline troubleshooting with Agent Observability | Streamline troubleshooting with Agent Observability | Streamline troubleshooting with Agent Observability | examples/voice_agents | livekit/livekit_composite | DeepWiki | TTS Metrics | LiveKit Documentationastonishing-waitress-60915
02/15/2026, 7:28 PMtall-airline-16756
02/15/2026, 7:29 PMMetricsCollected olaylarını dinleyip bu metrikleri Prometheus/Grafana, OpenTelemetry, Loki vb. sistemlere göndererek benzer bir gösterge panosu oluşturabilirsin.
• Aşağıda önerilen akış: Agent içinde metrikleri yakala → uygun exporter ile telemetry sistemine gönder → Grafana/Loki ile görselleştir.
Önerilen seçenekler (tercihe göre)
• Hızlı & yaygın: Prometheus + Grafana (metrikler sayısal; TTFT, TTFB, token sayıları vs.)
• Log odaklı: Loki + Grafana (detaylı JSON log’lar, timeline aramaları)
• Tam izleme: OpenTelemetry → Jaeger/Tempo + Prometheus + Grafana (trace + metrics)
• Basit: Doğrudan JSON log dosyalarına yazıp `jq`/kibana/elk ile incele (geçici)
Adım adım uygulama (Prometheus + Grafana örneği) 1) MetricsCollected olaylarını yakala (örnek: Python)
• Agent oturumunu oluşturduğun yerde event handler ekle.
• Handler içinde metrikleri Prometheus client ile güncelle.
2) Prometheus exporter çalıştır:
• Agent ile aynı host veya sidecar olarak bir HTTP endpoint aç (ör. :8000/metrics).
• Prometheus bu endpoint’i scrape edecek.
3) Grafana’da dashboard oluştur:
• TTFT, TTFB, tokens per call, calls/sec, error rate gibi paneller kur.
Python örneği (Prometheus exporter) — doğrudan kopyala/yapıştır
# metrics_exporter.py
from prometheus_client import start_http_server, Gauge, Counter
import asyncio
import time
from datetime import datetime
# Prometheus metric tanımları
TTFT = Gauge('agent_ttft_seconds', 'Time to first token', ['agent_name', 'room_id', 'model'])
TTFB = Gauge('agent_ttfb_seconds', 'Time to first byte (TTS)', ['agent_name', 'room_id', 'model'])
DURATION = Gauge('agent_duration_seconds', 'Processing duration', ['agent_name', 'room_id', 'model'])
INPUT_TOKENS = Gauge('agent_input_tokens', 'Input tokens', ['agent_name', 'room_id', 'model'])
OUTPUT_TOKENS = Gauge('agent_output_tokens', 'Output tokens', ['agent_name', 'room_id', 'model'])
TOTAL_TOKENS = Gauge('agent_total_tokens', 'Total tokens', ['agent_name', 'room_id', 'model'])
REQUESTS = Counter('agent_requests_total', 'Total inference requests', ['agent_name', 'model', 'status'])
# Basit metrics logger / handler
async def handle_metrics_collected(event):
m = event.metrics
labels = {
'agent_name': getattr(event, 'agent_name', 'unknown'),
'room_id': getattr(event, 'room_id', 'unknown'),
'model': getattr(event, 'model_name', getattr(m, 'model_name', 'unknown'))
}
# Safely al (bazı alanlar eksik olabilir)
try:
if getattr(m, 'ttft', None) is not None and m.ttft >= 0:
TTFT.labels(**labels).set(m.ttft)
if getattr(m, 'ttfb', None) is not None and m.ttfb >= 0:
TTFB.labels(**labels).set(m.ttfb)
if getattr(m, 'duration', None) is not None:
DURATION.labels(**labels).set(m.duration)
if getattr(m, 'input_tokens', None) is not None:
INPUT_TOKENS.labels(**labels).set(m.input_tokens)
if getattr(m, 'output_tokens', None) is not None:
OUTPUT_TOKENS.labels(**labels).set(m.output_tokens)
if getattr(m, 'total_tokens', None) is not None:
TOTAL_TOKENS.labels(**labels).set(m.total_tokens)
# Basit request sayacı (hata durumu da varsa 'status' label'ı ver)
REQUESTS.labels(agent_name=labels['agent_name'], model=labels['model'], status='ok').inc()
except Exception as e:
# Hata sayacı
REQUESTS.labels(agent_name=labels['agent_name'], model=labels['model'], status='error').inc()
print("Metrics handler error:", e)
def attach_metrics_exporter(session, port=8000):
# Prometheus exporter'ı başlat
start_http_server(port)
print(f"Prometheus exporter started on :{port}")
# SDK event kaydı. SDK event ismi sürüme göre değişir: "metrics_collected" veya enum kullan
session.on("metrics_collected", lambda ev: asyncio.create_task(handle_metrics_collected(ev)))
print("MetricsCollected handler attached.")
Nasıl entegre edilir
1. Agent kodunda AgentSession oluşturduktan sonra attach_metrics_exporter(session, port=8000) çağr.
2. Prometheus konfigürene şu scrape job’u ekle:
scrape_configs:
- job_name: 'livekit_agents'
static_configs:
- targets: ['<agent-host>:8000']
1. Grafana’da Prometheus datasource ekle; örnek paneller oluştur:
◦ TTFT (avg/min/max): avg(agent_ttft_seconds) by (agent_name)
◦ Token kullanımı: sum(agent_total_tokens) by (agent_name)
Alternatif: Log bazlı (Loki) veya OpenTelemetry
• Eğer JSON log’ları zaten üretiyorsan, Loki’ye gönderip Grafana’da zaman çizelgesi + log detay paneli oluşturabilirsin.
• OpenTelemetry kullanıyorsan traces + metrics toplayıp Tempo/Jaeger + Prometheus ile daha zengin izleme kurabilirsin.
Ek notlar / pratik ipuçları
• Metrik isimlerini ve label’ları iyi seç; yüksek cardinality’den kaçının (ör. kullanıcı id’sini label yapma).
• TTFT bazen -1 veya None olabilir (henüz token gelmemiş). Filtrele veya grafikte ignore et.
• Eğer agent’ları container olarak çalıştırıyorsan exporter’ı sidecar container olarak da deploy edebilirsin.
• Logları da koru: timeline araması için log + metrics ikilisi en faydalısıdır.
Sonraki adım — nasıl yardım edeyim?
• Hangi dili kullanıyorsun: Python, Node.js veya Go? (Yukarı örnek Python.)
• Zaten Prometheus/Grafana kullanıyor musun yoksa sıfırdan mı kuracağız?
• Agent kodundan AgentSession başlatma kısmını paylaşırsan, sana tam çalışır halde bir entegrasyon snippet’i hazırlayıp verebilirim (sidecar veya aynı process, tercihine göre).
Hangisini istersin? Python örneğini Node/Go’ya çevireyim ya da Prometheus/Grafana konfigürasyon dosyalarını hazır çıkarayım.astonishing-waitress-60915
02/15/2026, 7:32 PMtall-airline-16756
02/15/2026, 7:32 PM.on(...) ile event aboneliği yaparken asenkron handler’ı doğrudan vermek hata veriyor çünkü .on senkron bir callable bekliyor. Çözüm: senkron bir wrapper içinden asyncio.create_task(...) ile asenkron handler’ı arka planda başlatmak.
Aşağıda doğrudan kopyala-yapıştır kullanabileceğin, eksiksiz ve basit bir Python örneği var. Bu örnek:
• MetricsCollected olayını dinliyor,
• asenkron handle_metrics fonksiyonunu asyncio.create_task ile çalıştırıyor,
• Prometheus exporter ekleme isteğine uygun olarak (isteğe bağlı) console’a log da yazıyor.
Kod (örnek, Python):
import asyncio
from datetime import datetime
# Bu örnekte event nesnesinin .metrics alanı olduğunu varsayıyoruz.
# SDK sürümüne göre event isimleri/alanlar değişebilir; gerekirse uyarlayalım.
async def handle_metrics(event):
"""Asenkron iş yapan gerçek handler"""
m = event.metrics
now = datetime.utcnow().isoformat()
# Güvenli erişim için getattr kullanıyoruz (bazı alanlar olmayabilir)
ttft = getattr(m, "ttft", None)
ttfb = getattr(m, "ttfb", None)
duration = getattr(m, "duration", None)
input_tokens = getattr(m, "input_tokens", None)
output_tokens = getattr(m, "output_tokens", None)
# Burada istediğin işlemi yap: DB'ye yaz, Prometheus'a gönder, dosyaya logla vb.
print(f"[Metrics] {now} room={getattr(event, 'room_id', 'unknown')} model={getattr(event, 'model_name', 'unknown')}")
if ttft is not None:
print(f" TTFT: {ttft}s")
if ttfb is not None:
print(f" TTFB: {ttfb}s")
if duration is not None:
print(f" Duration: {duration}s")
if input_tokens is not None or output_tokens is not None:
print(f" Tokens - in: {input_tokens} out: {output_tokens}")
# Örnek: bekleyip async I/O yapma
await asyncio.sleep(0) # placeholder, gerçek async iş burada olabilir
def metrics_wrapper(event):
""".on(...) için senkron wrapper — asenkron handler'ı arka planda çalıştırır."""
try:
asyncio.create_task(handle_metrics(event))
except RuntimeError:
# Eğer event loop yoksa (ör. module import sırasında), loop başlat veya logla
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(handle_metrics(event))
def attach_metrics_listener(session):
"""
session: SDK'daki AgentSession veya ilgili nesne.
.on event kayıt yöntemi SDK'ya göre farklı olabilir (string veya enum).
Örnek: session.on("metrics_collected", metrics_wrapper)
veya component bazında: session.llm.on("metrics_collected", metrics_wrapper)
"""
# Örnek: genel oturum event'i
try:
session.on("metrics_collected", metrics_wrapper)
print("MetricsCollected handler eklendi (wrapper ile).")
except Exception as e:
print("Handler eklenirken hata:", e)
Kullanım:
1. Agent oturumu oluşturduktan hemen sonra attach_metrics_listener(session) çağr.
2. dev veya console modunda test ederken event tetiklendiğinde arka planda handle_metrics çalışacak ve log/işlem yapılacaktır.
Notlar ve küçük ipuçları
• .on bazen component bazında olabilir (ör. session.llm.on(...), session.tts.on(...), session.stt.on(...)). Hangi component’in event verdiğini SDK dokümanına göre kontrol et.
• asyncio.create_task çağrısı, mevcut event loop içinde çalıştırır. Eğer wrapper bir thread içinde veya event loop yokken çağrılıyorsa RuntimeError alırsın; örnekte bunun için basit bir fallback ekledim.
• Eğer metrikleri Prometheus’a göndereceksek handle_metrics içinde Prometheus client güncellemesi yap; bu da asenkron olarak güvenli çalışır.
• TTFT bazen -1 veya None olabilir — bunu filtrele veya grafikte ignore et.
İstersen hemen:
• Kullandığın SDK sürümünü ve event aboneliğini nasıl yapmaya çalıştığını paylaş; kodu tam olarak senin ortamına göre uyarlayıp test edilebilir bir snippet atayım.
• Prometheus/Grafana entegrasyonu istersen, handle_metrics içinde örnek Prometheus güncellemesi ile tam entegrasyon kodu vereyim.
Hangi yolu istersin — doğrudan loglayalım mı yoksa Prometheus’a export eden tam örneği mi hazırlayayım?
Sources: LLM Metrics | LiveKit Documentation | STT Metrics | LiveKit Documentation | TTS Metrics | LiveKit Documentation | VAD Metrics | LiveKit Documentation | Agents (Node.js) | livekit/livekit_composite | DeepWikiastonishing-waitress-60915
02/15/2026, 7:33 PMattach_metrics_listener(session)tall-airline-16756
02/15/2026, 7:33 PMattach_metrics_listener(session) fonksiyonunu tam çalışan bir örnek içinde görmek istiyorsun; nerede çağrılacağını, session oluşturma ve eventlerin nasıl bağlanacağını gösteren eksiksiz bir Python örneği vereyim. Bu örnek self‑hosted ortamda çalışacak şekilde asyncio.create_task ile asenkron handler’ları arka planda çalıştırır ve konsola log basar. İstersen bu örneği Prometheus/Grafana exporter eklemesiyle de genişletebilirim.
Aşağıdaki tam örnek:
• Agent oturumunu oluşturur (örnek bir AgentSession/Session placeholder kullandım — kendi SDK kullanımına göre ufak isim uyarlamaları gerekebilir).
• attach_metrics_listener(session) çağrısını doğru yerde yapar.
• metrics_collected olayını senkron wrapper + asyncio.create_task ile işler.
Not: SDK sürümüne göre event isimleri metrics_collected veya enum/const olabilir; eğer session.llm, session.tts, session.stt gibi alt bileşenler varsa onlara bağlamak daha doğru olabilir. Gerekirse ben senin kullandığın SDK sürümüne göre uyarlayayım.
Kod (tam örnek):
import asyncio
from datetime import datetime
# --- Basit metrics handler'ları ---
async def handle_llm_metrics(event):
m = event.metrics
now = datetime.utcnow().isoformat()
print(f"[LLM Metrics] {now} room={getattr(event, 'room_id', 'unknown')} model={getattr(event, 'model_name', 'unknown')}")
print(f" TTFT: {getattr(m, 'ttft', 'N/A')}")
print(f" Duration: {getattr(m, 'duration', 'N/A')}")
print(f" Prompt tokens: {getattr(m, 'prompt_tokens', 'N/A')}")
print(f" Completion tokens: {getattr(m, 'completion_tokens', 'N/A')}")
print("-" * 40)
await asyncio.sleep(0) # placeholder for async I/O (DB, exporter, vb.)
async def handle_tts_metrics(event):
m = event.metrics
now = datetime.utcnow().isoformat()
print(f"[TTS Metrics] {now} room={getattr(event, 'room_id', 'unknown')}")
print(f" TTFB: {getattr(m, 'ttfb', 'N/A')}")
print(f" Duration: {getattr(m, 'duration', 'N/A')}")
print("-" * 40)
await asyncio.sleep(0)
async def handle_stt_metrics(event):
m = event.metrics
now = datetime.utcnow().isoformat()
print(f"[STT Metrics] {now} room={getattr(event, 'room_id', 'unknown')}")
print(f" Duration: {getattr(m, 'duration', 'N/A')}")
print("-" * 40)
await asyncio.sleep(0)
# --- Wrapper'lar: .on(...) sync callable beklediği için asyncio.create_task kullanıyoruz ---
def attach_metrics_listener(session):
"""
session: AgentSession nesnesi (kendi SDK'na göre isim farklı olabilir).
Bu fonksiyon session üzerinde metrics event'lerini dinler.
"""
# Eğer SDK component bazlı event veriyorsa session.llm/tts/stt kullan:
try:
# LLM metrics
session.llm.on("metrics_collected", lambda ev: asyncio.create_task(handle_llm_metrics(ev)))
except Exception:
# Eğer session.llm yoksa genel event üzerinden dinle
try:
session.on("llm_metrics_collected", lambda ev: asyncio.create_task(handle_llm_metrics(ev)))
except Exception:
pass
# TTS metrics
try:
session.tts.on("metrics_collected", lambda ev: asyncio.create_task(handle_tts_metrics(ev)))
except Exception:
try:
session.on("tts_metrics_collected", lambda ev: asyncio.create_task(handle_tts_metrics(ev)))
except Exception:
pass
# STT metrics
try:
session.stt.on("metrics_collected", lambda ev: asyncio.create_task(handle_stt_metrics(ev)))
except Exception:
try:
session.on("stt_metrics_collected", lambda ev: asyncio.create_task(handle_stt_metrics(ev)))
except Exception:
pass
print("attach_metrics_listener: handler'lar eklendi.")
# --- Tam bir örnek giriş noktası (entrypoint) ---
async def main():
"""
Burada session oluşturma yerini kendi agent koduna göre uyarla.
Örneğin:
- session = AgentSession(...)
- veya agent = MyAgent(...) ve agent.session
"""
# --- Placeholder: kendi SDK ile değiştir ---
# from livekit.agents import AgentSession
# session = AgentSession(...)
session = create_fake_session_for_example() # sadece örnek, kendi session'ını kullan
# Metrics listener'ı ekle
attach_metrics_listener(session)
# Start / connect agent session; kendi kodunda bu farklı olabilir
# Ör: await session.start(...) veya await agent.run(...)
try:
await session.start() # kendi SDK çağrınla değiştir
except AttributeError:
# Eğer örnek session fake ise, sadece bekle
print("Session.start() çağrısı örnek için atlandı.")
# Örnek: sonsuz bekle (gerçek agent çalışırken event'ler tetiklenecek)
while True:
await asyncio.sleep(60)
# --- Örnek placeholder session (sadece demo, gerçek kodunda kaldır) ---
class FakeEvent:
def __init__(self, metrics, room_id="RM_demo", model_name="demo-model"):
self.metrics = metrics
self.room_id = room_id
self.model_name = model_name
class FakeMetrics:
def __init__(self, ttft=None, ttfb=None, duration=None, prompt_tokens=None, completion_tokens=None):
self.ttft = ttft
self.ttfb = ttfb
self.duration = duration
self.prompt_tokens = prompt_tokens
self.completion_tokens = completion_tokens
class FakeComponent:
def __init__(self):
self._handlers = {}
def on(self, event_name, handler):
self._handlers.setdefault(event_name, []).append(handler)
# test için event tetikle
def emit(self, event_name, ev):
for h in self._handlers.get(event_name, []):
h(ev)
class FakeSession:
def __init__(self):
self.llm = FakeComponent()
self.tts = FakeComponent()
self.stt = FakeComponent()
async def start(self):
# örnek: çalıştıktan sonra periyodik test event'i gönder
await asyncio.sleep(1)
# test metrics
m1 = FakeMetrics(ttft=0.12, duration=1.3, prompt_tokens=120, completion_tokens=30)
self.llm.emit("metrics_collected", FakeEvent(m1))
await asyncio.sleep(1)
m2 = FakeMetrics(ttfb=0.25, duration=0.8)
self.tts.emit("metrics_collected", FakeEvent(m2))
await asyncio.sleep(1)
m3 = FakeMetrics(duration=0.6)
self.stt.emit("metrics_collected", FakeEvent(m3))
def create_fake_session_for_example():
return FakeSession()
# --- Çalıştır ---
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("Çıkış yapılıyor.")
Ne yapman gerektiği, özet:
• Kendi agent kodunda session nesnesini oluşturduktan hemen sonra attach_metrics_listener(session) çağır.
• Eğer SDK’da session.llm, session.tts, session.stt gibi alt bileşenler varsa onlara bağla; yoksa global session.on("metrics_collected", ...) şeklinde bağlan.
• Handler içinde async I/O (DB, Prometheus exporter, HTTP çağrısı) yapacaksan async def kullan ve wrapper ile asyncio.create_task(...) çağır.
İstersen ben:
• Bu örneği doğrudan kullandığın SDK sürümüne (tam import/isimlerle) göre uyarlayayım.
• handle_* fonksiyonları içine Prometheus client ekleyip tam exporter örneği verip prometheus_client.start_http_server(8000) ile scrape edilebilir hale getireyim.
Hangi SDK sürümünü / AgentSession oluşturma kodunu kullanıyorsun? Ona göre tam sürümü hemen hazırlarım.
Sources: TTS Metrics | LiveKit Documentation | STT Metrics | LiveKit Documentation | VAD Metrics | LiveKit Documentation | Agents (Node.js) | livekit/livekit_composite | DeepWikiastonishing-waitress-60915
02/15/2026, 7:34 PMtall-airline-16756
02/15/2026, 7:35 PMroom ve model hep "unknown" görünüyor. Bu genelde event nesnesinin beklediğimiz alanları taşımamasından veya doğru yerden okumamamamızdan kaynaklanır. Aşağıda nedenleri, nasıl kontrol edip düzelteceğin ve doğrudan kullanabileceğin güncellenmiş kod var.
Neden "unknown" görünüyor?
• Event nesnesi SDK sürümüne göre farklı yapıda olabilir; örneğin event.room_id yerine event.context.room_id veya event.job.room_id olabilir.
• Model bilgisi her metrics event’inde direkt gelmeyebilir; bazen event.model_name, bazen event.metrics.model_name, bazen metadata içinde bulunur.
• Event’i oluşturan component (LLM/TTS/STT) ile session/room ilişkisi ayrı tutuluyorsa, bağlam (context) ile birlikte taşınmalıdır. Eğer bağlam gönderilmiyorsa wrapper tarafında ek metadata sağlaman gerekir.
Ne yapacağız?
1. Event objesinin tüm alanlarını loglayıp yapıyı göreceğiz (inspect).
2. Bulduğumuz alanlara göre güvenli (fallback) okuma yapacağız: birkaç olası yer kontrol edilecek.
3. Güncellenmiş wrapper ile doğru room/model değerlerini alacağız.
Önce: Event yapısını görmek için hızlı inspect fonksiyonu Aşağıyı çalıştırıp bir metrics event tetiklediğinde terminalde hangi alanların geldiğini gönderir misin? (Tek seferlik; sonrasında kaldırabiliriz.)
def inspect_event(event):
print("=== EVENT INSPECT ===")
# En yaygın alanlar
for attr in ["room_id", "room", "model_name", "model", "agent_name", "context", "job", "metadata"]:
if hasattr(event, attr):
print(f"{attr}: {getattr(event, attr)}")
# Tüm __dict__ (varsa)
try:
print("__dict__:", event.__dict__)
except Exception:
pass
# metrics alt yapısı
try:
m = event.metrics
print("metrics.__dict__:", getattr(m, "__dict__", str(m)))
except Exception:
pass
print("=====================")
Güncellenmiş güvenli reader + attach fonksiyonu Bu versiyon birden fazla yerde arama yapar: event.room_id, event.context.room_id, event.job.room_id, event.metadata['room_id'], ve model için event.model_name, event.metrics.model_name, event.metadata['model_name'] gibi yerlere bakar.
import asyncio
from datetime import datetime
def _get_room_id_from_event(event):
# Olası yerleri sırayla kontrol et
candidates = []
if hasattr(event, "room_id"):
candidates.append(getattr(event, "room_id"))
if hasattr(event, "room"):
# bazen room objesi veya adı gelebilir
candidates.append(getattr(event, "room"))
# context veya job içinde olabilir
if hasattr(event, "context") and event.context:
try:
candidates.append(getattr(event.context, "room_id", None))
candidates.append(getattr(event.context, "room", None))
except Exception:
pass
if hasattr(event, "job") and event.job:
try:
candidates.append(getattr(event.job, "room_id", None))
except Exception:
pass
# metadata dict içinde olabilir
try:
meta = getattr(event, "metadata", None) or {}
if isinstance(meta, dict):
candidates.append(meta.get("room_id"))
candidates.append(meta.get("room"))
except Exception:
pass
# Döndürülebilir ilk dolu değer
for c in candidates:
if c not in (None, "", "unknown"):
return str(c)
return "unknown"
def _get_model_from_event(event):
candidates = []
if hasattr(event, "model_name"):
candidates.append(getattr(event, "model_name"))
if hasattr(event, "model"):
candidates.append(getattr(event, "model"))
# metrics içinde olabilir
try:
m = getattr(event, "metrics", None)
if m is not None:
candidates.append(getattr(m, "model_name", None))
candidates.append(getattr(m, "model", None))
except Exception:
pass
# metadata
try:
meta = getattr(event, "metadata", None) or {}
if isinstance(meta, dict):
candidates.append(meta.get("model_name"))
candidates.append(meta.get("model"))
except Exception:
pass
for c in candidates:
if c not in (None, "", "unknown"):
return str(c)
return "unknown"
async def handle_metrics(event):
m = getattr(event, "metrics", None)
room = _get_room_id_from_event(event)
model = _get_model_from_event(event)
now = datetime.utcnow().isoformat()
print(f"[Metrics] {now} room={room} model={model}")
if m is not None:
print(f" TTFT: {getattr(m, 'ttft', 'N/A')}")
print(f" TTFB: {getattr(m, 'ttfb', 'N/A')}")
print(f" Duration: {getattr(m, 'duration', 'N/A')}")
print(f" Input tokens: {getattr(m, 'input_tokens', 'N/A')}")
print(f" Output tokens: {getattr(m, 'output_tokens', 'N/A')}")
else:
print(" metrics: None")
print("-" * 40)
await asyncio.sleep(0)
def attach_metrics_listener(session):
# component bazlı bağlan (varsa)
try:
session.llm.on("metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
try:
session.on("llm_metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
pass
try:
session.tts.on("metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
try:
session.on("tts_metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
pass
try:
session.stt.on("metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
try:
session.on("stt_metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
pass
# fallback: genel metrics_collected
try:
session.on("metrics_collected", lambda ev: asyncio.create_task(handle_metrics(ev)))
except Exception:
pass
print("attach_metrics_listener: handlers attached.")
Sonraki adımlar (hangi bilgiyi paylaşmalısın)
• Lütfen bir metrics event üretip yukarıdaki inspect_event(event) fonksiyonunu çalıştırıp çıktısını paylaş (veya event.dict içeriğini). Böylece tam alan isimlerini görüp kodu kesinlikle uyarlayabilirim.
• SDK sürümünü söyle (ör. livekit-agents vX.Y veya package versiyon). Bu, event alan adlarını doğrulamak için önemli.
• Eğer event yapısı metadata ile geliyor ise, token/dispatch oluştururken metadata içine room_id veya model_name eklemek daha sağlam bir çözüm sağlar — istersen buna nasıl ekleyeceğini de gösteririm.
Hemen yardımcı olayım: önce inspect çıktısını paylaşır mısın? Ona göre _get_room_id_from_event ve _get_model_from_event fonksiyonlarını kesin doğru alanlarla güncelleyeyim.astonishing-waitress-60915
02/15/2026, 7:35 PMtall-airline-16756
02/15/2026, 7:35 PMstart (production) modunda çalışan agent’ı doğrudan LiveKit’in Playground gibi interaktif bir yerde test edebileceğin hazır bir ortam yok. start üretim amaçlı çalışır ve etkileşimli frontend/Playground ile otomatik olarak görünür olmayabilir. Ancak start modunda çalışan bir agent’ı test etmenin birkaç pratik yolu ve önerisi var — aşağıda kısa, uygulanabilir seçenekleri paylaşıyorum ve hangisini tercih ettiğini soruyorum.
Kısa özet
• start için özel, hazır bir “Playground” yok. dev ve console test amaçlı daha uygun.
• start modunda test etmek için production benzeri bir client/oda oluşturup agent’ı dispatch etmen veya doğrudan odaya katılmasını sağlaman gerekiyor.
• Aşağıda 3 pratik yöntem var: hızlı frontend ile test, CLI ile manuel dispatch, ya da test ortamı (staging) oluşturma.
Seçenekler ve adımlar
1) Hızlı HTML/JS client ile test (en hızlı ve kontrol edilmesi kolay)
• Basit bir web sayfası ile LiveKit’a bağlanıp room oluştur/katıl:
◦ Kullanıcı token’ı oluştur (dev için veya production key ile).
◦ Tarayıcıda mikrofonu aç ve odaya katıl.
• Agent`start` modunda kâtip/servis olarak çalışıyorsa, agent’ın odaya katılması için explicit dispatch gerekiyorsa token veya dispatch API ile agent’ı odaya gönder.
• Bu yöntemle gerçek ses/girdi ile start modundaki davranışı görebilirsin.
2) CLI ile manuel dispatch (doğrudan agent’ı odaya atmak)
• Eğer lk CLI yüklüyse:
◦ lk dispatch create --agent-name test-agent --room my-room --metadata '{"...": "..."}'
• Bu, production agent’ı hedef odaya dispatch eder. Sonrasında bir client ile odaya bağlanıp agent ile etkileşimi görebilirsin.
3) Staging ortamı: production’a çok yakın ama test için güvenli
• Production ile aynı konfigürasyona sahip bir “staging” LiveKit sunucusu/cluster’ı kur.
• Agent’ı start olarak burada deploy et ve gerçek world testlerini yap.
• Avantaj: gerçek koşullarda test, ama prod verilerine veya trafiğine karışmaz.
Göz önünde bulundurman gerekenler
• start modunda agent genelde container/process olarak çalışır; logs ve telemetri ile izleyebilirsin (metrics/loglar genelde tek kaynak).
• Eğer agent kodunda agent_name tanımlıysa, odaya katılması için explicit dispatch gerekir. Token yalnızca kullanıcıyı odaya sokar.
• start modunda interaktif debug zor olabilir; bu yüzden staging veya kısa süreli dev modunda çoğu testi yapmak daha pratiktir.
Hangi yardımı istersin?
• Hemen bir örnek HTML/JS client istersen, sana kopyala‑yapıştır çalışacak örnek token oluşturma + client kodu verebilirim.
• lk dispatch create komutu ile nasıl dispatch yapılacağını adım adım göstereyim mi?
• Yoksa staging ortamı kurma (docker/k8s örneği) ile ilgili rehber ister misin?
Tercihini söyle, hemen adım adım yardımcı olayım.