Skip to content

feat(hooks): add resume flag to AfterInvocationEvent#1767

Draft
mkmeral wants to merge 4 commits intostrands-agents:mainfrom
mkmeral:agent-resume
Draft

feat(hooks): add resume flag to AfterInvocationEvent#1767
mkmeral wants to merge 4 commits intostrands-agents:mainfrom
mkmeral:agent-resume

Conversation

@mkmeral
Copy link
Contributor

@mkmeral mkmeral commented Feb 25, 2026

Description

Motivation

Hooks that run after an agent invocation sometimes need to trigger a follow-up invocation automatically. For example, a coding agent hook could run tests and linting after each response, and if checks fail, resume the agent with the error output so it can fix the issues autonomously. Similarly, a validation hook could inspect the agent's output against acceptance criteria and loop until the result passes. Today there's no way to do this from a hook; callers have to build the retry loop externally, which duplicates lifecycle logic and bypasses the hook system entirely.

This PR adds a resume field to AfterInvocationEvent. When a hook sets resume to any valid AgentInput, the agent re-invokes itself with that input, firing a full new invocation cycle (including BeforeInvocationEvent). When resume is None (the default), behavior is unchanged.

Public API Changes

AfterInvocationEvent gains a writable resume attribute:

from strands import Agent
from strands.hooks.events import AfterInvocationEvent
import subprocess

async def validate_code(event: AfterInvocationEvent):
    result = subprocess.run(["hatch", "run", "prepare"], capture_output=True, text=True)
    if result.returncode != 0:
        event.resume = f"Tests/linting failed. Fix these errors:\n{result.stdout}\n{result.stderr}"

agent = Agent()
agent.add_hook(validate_code)
agent("implement a fibonacci function in utils.py")

Each resume triggers a complete invocation cycle: BeforeInvocationEvent → event loop → AfterInvocationEvent, so all existing hooks participate in every iteration. The resume input is converted to messages via the same _convert_prompt_to_messages path as normal agent calls.

Use Cases

  • Code quality loops: A hook runs tests and static analysis after each agent response, resuming with failure output until all checks pass
  • Output validation: Inspect the agent's result against acceptance criteria or schema constraints and loop until the output is correct
  • Multi-step workflows: Chain invocations where each step's output determines the next step's input, all within the hook lifecycle

Related Issues

Resolves: #1181

Documentation PR

TBD

Type of Change

New feature

Testing

  • 4 unit tests covering resume triggering, no-resume default, BeforeInvocationEvent firing on resume, and multi-step chaining

  • 3 unit tests for the resume field on AfterInvocationEvent (default value, writability, input type acceptance)

  • Manually tested with a Jupyter notebook demo

…-invocation

Add a writable 'resume' field (AgentInput | None) to AfterInvocationEvent.
When a hook sets resume to a non-None value, the agent automatically
re-invokes with that input, triggering a full new invocation cycle
including BeforeInvocationEvent.
@mkmeral mkmeral marked this pull request as draft February 25, 2026 20:09
@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 96.42857% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/strands/agent/agent.py 95.83% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add support for skills

1 participant