Skip to content

feat(api_server): add POST /v1/runs/{run_id}/stop (salvage of #15656) - #15842

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-8eaea4cc
Apr 26, 2026
Merged

feat(api_server): add POST /v1/runs/{run_id}/stop (salvage of #15656)#15842
teknium1 merged 3 commits into
mainfrom
hermes/hermes-8eaea4cc

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvages PR #15656 by @EKKOLearnAI onto current main with a bounded-wait fix.

Summary

Adds POST /v1/runs/{run_id}/stop to interrupt agents started via POST /v1/runs. Calls agent.interrupt(), cancels the asyncio task, and cleans up refs — but caps the await at 5s so the handler can't hang when the agent is slow to respond to the interrupt.

Changes

  • gateway/platforms/api_server.py: contributor's stop endpoint + agent/task ref dicts + cleanup wiring (unchanged from feat(api_server): add POST /v1/runs/{run_id}/stop endpoint #15656)
  • gateway/platforms/api_server.py: follow-up — wrap await task in asyncio.wait_for(shield(task), 5.0) with TimeoutError warning, so an unresponsive agent.interrupt() can't block the handler indefinitely. run_conversation() runs in the default executor which task.cancel() cannot preempt.
  • tests/gateway/test_api_server_runs.py: 15 new tests (start/events/stop, auth, 404, interrupt, cleanup, exception paths) — unchanged from feat(api_server): add POST /v1/runs/{run_id}/stop endpoint #15656
  • scripts/release.py: AUTHOR_MAP entry for fqsy1416@gmail.com → EKKOLearnAI

Validation

scripts/run_tests.sh tests/gateway/test_api_server_runs.py — 15/15 pass.

Closes #15656 (with credit preserved via cherry-pick authorship).

EKKOLearnAI and others added 3 commits April 25, 2026 18:32
Add ability to interrupt a running agent via the runs API. Previously
/v1/runs could start a run and subscribe to events, but there was no
way to cancel it. The new endpoint stores agent and task references
during execution, calls agent.interrupt() to stop LLM calls, then
cancels the asyncio task.

Includes 15 tests covering start, events, and stop scenarios.
task.cancel() can't preempt the run_in_executor thread running
run_conversation(), so we rely on agent.interrupt() to wake the loop.
Without a timeout, a slow/unresponsive interrupt blocks the HTTP
response indefinitely. Wrap the await in wait_for(shield(task), 5.0)
and log a warning on timeout.

Also tidy one extra space in the module docstring's /stop entry.
@teknium1
teknium1 merged commit 4c591c2 into main Apr 26, 2026
11 of 12 checks passed
@teknium1
teknium1 deleted the hermes/hermes-8eaea4cc branch April 26, 2026 01:40
@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery labels Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants