update
This commit is contained in:
@@ -159,7 +159,10 @@ async def run_agent(key: str, prompt: str, timeout: int, *, provider: str,
|
||||
_active[key] = time.time()
|
||||
try:
|
||||
if use_api:
|
||||
await _api_slot(key)
|
||||
await _api_slot(key) # belegt _api_inflight — bei Abbruch freigeben
|
||||
if _ist_abgebrochen(key):
|
||||
_api_inflight -= 1
|
||||
return AgentErgebnis(1, "", "abgebrochen")
|
||||
wait_s = time.time() - warte_start
|
||||
try:
|
||||
res = await _text_api(key, prompt, timeout, model, role)
|
||||
@@ -171,6 +174,8 @@ async def run_agent(key: str, prompt: str, timeout: int, *, provider: str,
|
||||
res.model = model
|
||||
return res
|
||||
await _drossel_warten(key)
|
||||
if _ist_abgebrochen(key): # Nachzügler nach dem Cooldown nicht mehr feuern
|
||||
return AgentErgebnis(1, "", "abgebrochen")
|
||||
wait_s = time.time() - warte_start
|
||||
if PROVIDERS[provider]["cli"] == "opencode":
|
||||
res = await _opencode(key, prompt, timeout, model, capabilities)
|
||||
@@ -255,11 +260,13 @@ async def _spawn(key: str, cmd: list[str], stdin_data: bytes | None, timeout: in
|
||||
try:
|
||||
try:
|
||||
stdout, stderr = await asyncio.wait_for(process.communicate(input=stdin_data), timeout=timeout)
|
||||
except asyncio.TimeoutError:
|
||||
except (asyncio.TimeoutError, asyncio.CancelledError):
|
||||
# Timeout ODER Cancel (Hedge-Verlierer, LaufPause) → Prozess killen,
|
||||
# sonst rechnet ein verwaister CLI-Prozess unsichtbar weiter
|
||||
_kill(process)
|
||||
try:
|
||||
await asyncio.wait_for(process.wait(), timeout=5)
|
||||
except asyncio.TimeoutError:
|
||||
except (asyncio.TimeoutError, asyncio.CancelledError):
|
||||
pass
|
||||
raise
|
||||
log.info("agent %s: exit %s nach %.1fs", key, process.returncode, time.monotonic() - start)
|
||||
@@ -308,7 +315,14 @@ async def _opencode(key: str, prompt: str, timeout: int, model: str, capabilitie
|
||||
"-m", model, "--agent", _OPENCODE_AGENTS.get(capabilities, "text"),
|
||||
"--dangerously-skip-permissions", "--title", key, "-f", str(pfad)]
|
||||
try:
|
||||
res = await _spawn(key, cmd, None, timeout)
|
||||
try:
|
||||
res = await _spawn(key, cmd, None, timeout)
|
||||
except asyncio.TimeoutError:
|
||||
# Timeout heißt nicht 0 Tokens — die Session hat oft schon zigtausend
|
||||
# erzeugt. Als infra (err="timeout") mit echten Tokens zurückgeben,
|
||||
# damit Budget/Ledger stimmen. CancelledError NICHT fangen (Hedge).
|
||||
tokens = await asyncio.to_thread(_opencode_tokens, key)
|
||||
return AgentErgebnis(1, "", "timeout", tokens or {})
|
||||
res.text = _clean_opencode(res.text)
|
||||
res.tokens = await asyncio.to_thread(_opencode_tokens, key) or {}
|
||||
return res
|
||||
|
||||
Reference in New Issue
Block a user