mirror of
https://github.com/hoshikawa2/first_contas.git
synced 2026-07-09 10:14:20 +00:00
85 lines
3.1 KiB
Python
85 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
"""Observer adapter that emits IC/NOC/GRL through framework Telemetry only.
|
|
|
|
This avoids a second Langfuse root trace created by AgentObserver ->
|
|
AnalyticsPublisher while preserving the events inside the active request span.
|
|
"""
|
|
|
|
from datetime import datetime, timezone
|
|
from typing import Any
|
|
|
|
|
|
def _normalize_ic_code(code: str) -> str:
|
|
code = str(code or "UNKNOWN").strip()
|
|
return code if code.startswith(("IC.", "AGA.", "NOC.", "GRL.")) else f"IC.{code}"
|
|
|
|
|
|
def _normalize_noc_code(code: str) -> str:
|
|
code = str(code or "UNKNOWN").strip()
|
|
return code if code.startswith("NOC.") else f"NOC.{code}"
|
|
|
|
|
|
def _normalize_grl_code(code: str) -> str:
|
|
code = str(code or "UNKNOWN").strip()
|
|
return code if code.startswith("GRL.") else f"GRL.{code}"
|
|
|
|
|
|
def _kind_for(event_type: str) -> str:
|
|
if event_type.startswith(("IC.", "AGA.")):
|
|
return "ic"
|
|
if event_type.startswith("NOC."):
|
|
return "noc"
|
|
if event_type.startswith("GRL."):
|
|
return "grl"
|
|
return "event"
|
|
|
|
|
|
class TelemetryBackedAgentObserver:
|
|
"""Drop-in subset of AgentObserver backed by Telemetry.event.
|
|
|
|
Do not publish through AnalyticsPublisher here. Analytics publishing may be
|
|
configured with a Langfuse provider, and that path creates an extra root
|
|
trace for business events such as IC.AGENT_COMPLETED/NOC.006. Telemetry.event
|
|
uses the active span/trace context, so these events appear inside the single
|
|
request trace.
|
|
"""
|
|
|
|
def __init__(self, telemetry: Any, *, source: str = "agent_framework") -> None:
|
|
self.telemetry = telemetry
|
|
self.source = source
|
|
|
|
async def emit(
|
|
self,
|
|
event_type: str,
|
|
payload: dict[str, Any] | None = None,
|
|
*,
|
|
metadata: dict[str, Any] | None = None,
|
|
source: str | None = None,
|
|
) -> dict[str, Any]:
|
|
body = dict(payload or {})
|
|
meta = dict(metadata or {})
|
|
body.setdefault("tag", event_type)
|
|
event = {
|
|
"eventType": event_type,
|
|
"source": source or self.source,
|
|
"eventDate": datetime.now(timezone.utc).isoformat(),
|
|
"body": body,
|
|
"metadata": meta,
|
|
}
|
|
try:
|
|
await self.telemetry.event(event_type, event, kind=_kind_for(event_type))
|
|
except TypeError:
|
|
# Compatibility with older Telemetry.event signatures.
|
|
await self.telemetry.event(event_type, event)
|
|
return event
|
|
|
|
async def emit_ic(self, code: str, payload: dict[str, Any] | None = None, **metadata: Any) -> dict[str, Any]:
|
|
return await self.emit(_normalize_ic_code(code), payload, metadata={**metadata, "ic": True})
|
|
|
|
async def emit_noc(self, code: str, payload: dict[str, Any] | None = None, **metadata: Any) -> dict[str, Any]:
|
|
return await self.emit(_normalize_noc_code(code), payload, metadata={**metadata, "noc": True})
|
|
|
|
async def emit_grl(self, code: str, payload: dict[str, Any] | None = None, **metadata: Any) -> dict[str, Any]:
|
|
return await self.emit(_normalize_grl_code(code), payload, metadata={**metadata, "grl": True})
|