t-261015083454: мета-информация в событиях — trace_id+level+ts в каждом trace-событии (ToolCalled/ToolResult 68k были без связи с тиком), duration_ms/ok/exception в ToolResult, имя инструмента вместо '?', level+trace_id в TaskCompleted/TaskFailed; смоук + 5 тестов PASS
This commit is contained in:
parent
f667ab6d2c
commit
f3ab66e19e
3 changed files with 36 additions and 6 deletions
|
|
@ -447,7 +447,8 @@ def main():
|
||||||
memory=False,
|
memory=False,
|
||||||
skills=False,
|
skills=False,
|
||||||
)
|
)
|
||||||
agent = _wire_trace_hooks(agent, es, trace_id, model=payload.get("model"))
|
agent = _wire_trace_hooks(agent, es, trace_id, model=payload.get("model"),
|
||||||
|
level=level)
|
||||||
agent = _wire_budget_hooks(agent, level, trace_id, model=payload.get("model"))
|
agent = _wire_budget_hooks(agent, level, trace_id, model=payload.get("model"))
|
||||||
# хард-кап шагов (e-260930031800): cancel_tool + end_turn.
|
# хард-кап шагов (e-260930031800): cancel_tool + end_turn.
|
||||||
# ВАЖНО: НЕ используем limits={"turns": N} — нативный стоп SDK
|
# ВАЖНО: НЕ используем limits={"turns": N} — нативный стоп SDK
|
||||||
|
|
|
||||||
|
|
@ -77,12 +77,20 @@ def setup_provider():
|
||||||
os.environ["OPENAI_BASE_URL"] = _router_base_url()
|
os.environ["OPENAI_BASE_URL"] = _router_base_url()
|
||||||
|
|
||||||
|
|
||||||
def _wire_trace_hooks(agent, es, trace_id: str, model: str = None):
|
def _wire_trace_hooks(agent, es, trace_id: str, model: str = None, level: str = None):
|
||||||
"""Каждая стадия агентного цикла → событие агрегата trace.
|
"""Каждая стадия агентного цикла → событие агрегата trace.
|
||||||
|
|
||||||
model (e-260930062120): model_id уровня в InvocationStarted —
|
model (e-260930062120): model_id уровня в InvocationStarted —
|
||||||
видно, КАКАЯ модель запускалась на тике (запрошенная; "auto"
|
видно, КАКАЯ модель запускалась на тике (запрошенная; "auto"
|
||||||
резолвится роутером на его стороне).
|
резолвится роутером на его стороне).
|
||||||
|
|
||||||
|
t-261015083454 (аудит мета-информации в событиях): В КАЖДОМ
|
||||||
|
trace-событии теперь trace_id + ts + level (ToolCalled/ToolResult
|
||||||
|
раньше несли только tool/input — 68k событий без связи с тиком),
|
||||||
|
ToolResult дополнительно duration + ok/exception (из хука strands),
|
||||||
|
имя инструмента в ToolResult — из tool_use, а не заглушка "?".
|
||||||
|
Уровень недоступен (legacy-вызов) — поле не пишем, aggregate_id
|
||||||
|
по-прежнему "<level>-<seq>:<n>".
|
||||||
"""
|
"""
|
||||||
from strands import Agent
|
from strands import Agent
|
||||||
from strands.hooks import BeforeInvocationEvent, BeforeToolCallEvent, AfterToolCallEvent
|
from strands.hooks import BeforeInvocationEvent, BeforeToolCallEvent, AfterToolCallEvent
|
||||||
|
|
@ -93,25 +101,42 @@ def _wire_trace_hooks(agent, es, trace_id: str, model: str = None):
|
||||||
seq["n"] += 1
|
seq["n"] += 1
|
||||||
es.append_event("trace", f"{trace_id}:{seq['n']}", kind, payload)
|
es.append_event("trace", f"{trace_id}:{seq['n']}", kind, payload)
|
||||||
|
|
||||||
|
def _meta(extra: dict = None) -> dict:
|
||||||
|
base = {"trace_id": trace_id, "ts": _now()}
|
||||||
|
if level:
|
||||||
|
base["level"] = level
|
||||||
|
if extra:
|
||||||
|
base.update(extra)
|
||||||
|
return base
|
||||||
|
|
||||||
def on_before_invocation(event):
|
def on_before_invocation(event):
|
||||||
data = {"trace_id": trace_id, "ts": _now()}
|
data = _meta()
|
||||||
if model:
|
if model:
|
||||||
data["model"] = model
|
data["model"] = model
|
||||||
_trace("InvocationStarted", data)
|
_trace("InvocationStarted", data)
|
||||||
|
|
||||||
def on_before_tool(event):
|
def on_before_tool(event):
|
||||||
tool = getattr(event, "tool_use", None) or {}
|
tool = getattr(event, "tool_use", None) or {}
|
||||||
_trace("ToolCalled", {
|
_trace("ToolCalled", _meta({
|
||||||
"tool": tool.get("name", "?"),
|
"tool": tool.get("name", "?"),
|
||||||
"input": json.dumps(tool.get("input", {}), ensure_ascii=False, default=str)[:4000],
|
"input": json.dumps(tool.get("input", {}), ensure_ascii=False, default=str)[:4000],
|
||||||
})
|
}))
|
||||||
|
|
||||||
def on_after_tool(event):
|
def on_after_tool(event):
|
||||||
|
tool = getattr(event, "tool_use", None) or {}
|
||||||
try:
|
try:
|
||||||
res = str(getattr(event, "result", ""))[:4000]
|
res = str(getattr(event, "result", ""))[:4000]
|
||||||
except Exception:
|
except Exception:
|
||||||
res = "<unreadable>"
|
res = "<unreadable>"
|
||||||
_trace("ToolResult", {"tool": "?", "result": res})
|
extra = {"tool": tool.get("name", "?"), "result": res}
|
||||||
|
duration = getattr(event, "duration", None)
|
||||||
|
if duration is not None:
|
||||||
|
extra["duration_ms"] = round(float(duration) * 1000)
|
||||||
|
exc = getattr(event, "exception", None)
|
||||||
|
extra["ok"] = exc is None
|
||||||
|
if exc is not None:
|
||||||
|
extra["exception"] = str(exc)[:500]
|
||||||
|
_trace("ToolResult", _meta(extra))
|
||||||
|
|
||||||
agent.add_hook(on_before_invocation, BeforeInvocationEvent)
|
agent.add_hook(on_before_invocation, BeforeInvocationEvent)
|
||||||
agent.add_hook(on_before_tool, BeforeToolCallEvent)
|
agent.add_hook(on_before_tool, BeforeToolCallEvent)
|
||||||
|
|
|
||||||
|
|
@ -624,6 +624,8 @@ def run_level_tick(level_cfg, seq: int, model: dict):
|
||||||
if not _task_still_active(tid):
|
if not _task_still_active(tid):
|
||||||
continue
|
continue
|
||||||
es.append_event("task", tid, "TaskFailed", {
|
es.append_event("task", tid, "TaskFailed", {
|
||||||
|
# t-261015083454: мета — уровень/тик-воркер и его трасса
|
||||||
|
"level": level_cfg.name, "trace_id": trace_id,
|
||||||
"error": str(usage.get("error", "llm worker failed"))[:500],
|
"error": str(usage.get("error", "llm worker failed"))[:500],
|
||||||
})
|
})
|
||||||
raise RuntimeError(str(usage.get("error", "llm worker failed")))
|
raise RuntimeError(str(usage.get("error", "llm worker failed")))
|
||||||
|
|
@ -676,6 +678,8 @@ def run_level_tick(level_cfg, seq: int, model: dict):
|
||||||
_log("skip батч-догзакрытие задач, решённых воркером: " + ", ".join(_skipped))
|
_log("skip батч-догзакрытие задач, решённых воркером: " + ", ".join(_skipped))
|
||||||
for tid in _resolve:
|
for tid in _resolve:
|
||||||
es.append_event("task", tid, "TaskCompleted", {
|
es.append_event("task", tid, "TaskCompleted", {
|
||||||
|
# t-261015083454: мета-поля — какой тик/уровень закрыл задачу
|
||||||
|
"level": level_cfg.name, "trace_id": trace_id,
|
||||||
"result_ref": trace_id, "answer": (text or "")[:2000],
|
"result_ref": trace_id, "answer": (text or "")[:2000],
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue