Skip to content

Make serverless hooks work better - #84

Merged
msullivan merged 2 commits into
mainfrom
hook-investigate
May 10, 2026
Merged

Make serverless hooks work better#84
msullivan merged 2 commits into
mainfrom
hook-investigate

Conversation

@msullivan

Copy link
Copy Markdown
Contributor
  • Add a notion of an event being marked as replay, which can be
    fed to the agent loop to trigger tool calls, but won't get
    returned to the user.
  • When the last message when calling run is an assistant reply with
    tool results, we treat that as a runnable state and replay the ToolEnds
    into the agent loop
  • ai-sdk inbound strips internal hook messages and returns the list
    of approvals granted by hooks, instead of the existing behavior
    of it signalling the hooks itself.

For follow-up: the serverless-style loops are much nicer now, though
still don't match the stock loop's ToolRunner pattern. The current
issue, which I am going to think about some more, is that in the
interleaved streaming flow, if we immediately bail out of the loop
when a hook is requested, then that prevents a message from getting
emitted at all.

@msullivan
msullivan requested a review from anbuzin May 8, 2026 20:10
@vercel

vercel Bot commented May 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
py-ai Ready Ready Preview, Comment May 9, 2026 5:58pm

Request Review

Comment thread src/ai/models/core/api.py Outdated
self,
gen: AsyncGenerator[types.events.Event],
*,
message: types.messages.Message | None = None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably call it seed_message or something explicit like that

Comment thread src/ai/models/core/api.py Outdated
If the last message is an assistant turn with tool calls, replay
that turn as synthetic stream events instead of calling the model
— useful for resume-after-approval flows where the assistant turn
is already in history and re-asking would give a different answer.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can come up with a more explicit way to signal the intent to replay. Something like:

async with ai.replay(ai.stream(**args)) as stream:
    pass

wdyt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends if the goal is to make it work without changes to the event loop

msullivan added 2 commits May 9, 2026 10:51
 * Add a notion of an event being marked as `replay`, which can be
   fed to the agent loop to trigger tool calls, but won't get
   returned to the user.
 * When the last message when calling `run` is an assistant reply with
   tool results, we treat that as a runnable state and replay the ToolEnds
   into the agent loop
 * ai-sdk inbound strips internal hook messages and returns the list
   of approvals granted by hooks, instead of the existing behavior
   of it signalling the hooks itself.

For follow-up: the serverless-style loops are much nicer now, though
still don't match the stock loop's ToolRunner pattern. The current
issue, which I am going to think about some more, is that in the
interleaved streaming flow, if we immediately bail out of the loop
when a hook is requested, then that prevents a message from getting
emitted at all.
@msullivan
msullivan merged commit 1885775 into main May 10, 2026
6 checks passed
@msullivan
msullivan deleted the hook-investigate branch May 10, 2026 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants