mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-27 02:45:24 +08:00
feat(telemetry): attach called platform APIs to their step node on execution traces
Every host step now opens a stage scope, so observations recorded inside it (including cross-task plugin/RPC calls resolved through the execution registry) carry the owning step as parent; the pipeline lane records its own pipeline/run node so acks and replies issued outside the runner still hang off a node.
This commit is contained in:
@@ -11,6 +11,21 @@ from .execution import record
|
||||
processing_mode: ContextVar[str] = ContextVar('telemetry_processing_mode', default='none')
|
||||
|
||||
|
||||
def result_failure_detail(result) -> str:
|
||||
"""Pull a bounded human-readable reason out of a failed platform API result."""
|
||||
raw = getattr(result, 'raw', result)
|
||||
if isinstance(raw, dict):
|
||||
for key in ('error', 'message', 'msg', 'detail', 'reason'):
|
||||
value = raw.get(key)
|
||||
if isinstance(value, str) and value.strip():
|
||||
return value
|
||||
if isinstance(value, dict):
|
||||
for inner in ('message', 'msg', 'detail'):
|
||||
if isinstance(value.get(inner), str) and value[inner].strip():
|
||||
return value[inner]
|
||||
return ''
|
||||
|
||||
|
||||
def result_outcome(result):
|
||||
# Empty returns do not prove a remote operation succeeded.
|
||||
if result is None:
|
||||
@@ -69,18 +84,24 @@ def observe_adapter(ap, context, adapter):
|
||||
if action in declared:
|
||||
observed_operation = action
|
||||
outcome = 'unknown'
|
||||
error_detail = ''
|
||||
try:
|
||||
result = await method(*args, **kwargs)
|
||||
outcome = result_outcome(result)
|
||||
if outcome != 'success':
|
||||
error_detail = result_failure_detail(result)
|
||||
return result
|
||||
except asyncio.CancelledError:
|
||||
outcome = 'cancelled'
|
||||
error_detail = 'cancelled'
|
||||
raise
|
||||
except TimeoutError:
|
||||
except TimeoutError as exc:
|
||||
outcome = 'timeout'
|
||||
error_detail = str(exc) or 'timeout'
|
||||
raise
|
||||
except Exception:
|
||||
except Exception as exc:
|
||||
outcome = 'failed'
|
||||
error_detail = str(exc)
|
||||
raise
|
||||
finally:
|
||||
record(
|
||||
@@ -91,6 +112,7 @@ def observe_adapter(ap, context, adapter):
|
||||
adapter=adapter.__class__.__name__,
|
||||
mode=processing_mode.get(),
|
||||
outcome=outcome,
|
||||
error=error_detail,
|
||||
)
|
||||
|
||||
return wrapped
|
||||
|
||||
Reference in New Issue
Block a user