"""Воркер одного LLM-тика (запускается сабпроцессом из isolated_runner). Читает payload из stdin, гоняет create_harness() один раз и умирает — каждый тик получает чистый asyncio-рантайм Strands. Трасса пишется напрямую в event store (es доступен). Результат — в JSON-файл (path в payload['result_path']); stdout — только лог. """ import json import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def _emit(payload, obj): rp = payload.get("result_path") if rp: try: with open(rp, "w") as f: json.dump(obj, f, ensure_ascii=False) except OSError: pass def main(): payload = json.loads(sys.stdin.read()) from harness import es from harness.runtime import setup_provider, _wire_trace_hooks setup_provider() from strands_harness import create_harness trace_id = payload.get("trace_prefix") or "tick" try: agent = create_harness( model=f"openai/{payload['model']}", effort=payload.get("effort", "auto"), instructions=payload.get("instructions", ""), session=None, builtin_tools=("read", "write", "edit", "shell") if payload.get("can_shell") else [], memory=False, skills=False, ) agent = _wire_trace_hooks(agent, es, trace_id) result = agent(payload.get("prompt", "")) usage = {} try: msgs = getattr(agent, "messages", None) or [] for m in reversed(msgs): u = (m or {}).get("message", {}).get("usage") if u: usage = { "prompt_tokens": u.get("inputTokens") or u.get("prompt_tokens"), "completion_tokens": u.get("outputTokens") or u.get("completion_tokens"), } break except Exception: pass _emit(payload, {"ok": True, "text": str(result), "usage": usage, "trace_id": trace_id}) except Exception as e: import traceback _emit(payload, {"ok": False, "error": f"{e}\n{traceback.format_exc()[-800:]}"}) # орфан-воркер после убийства родителя может умереть на печати — не критично if __name__ == "__main__": main()