@@ -21,7 +21,7 @@ async def notify_mothership(message: str) -> str:
2121```
2222
2323When the model calls the tool, the agent emits a hook event. Resolve it with
24- ` ai.resolve_hook ` :
24+ the ` resolve() ` method :
2525
2626``` python
2727async with agent.run(model, messages) as stream:
@@ -31,25 +31,23 @@ async with agent.run(model, messages) as stream:
3131 and event.hook.status == " pending"
3232 ):
3333 print (event.hook.hook_id, event.hook.metadata)
34- ai.resolve_hook(
35- event.hook,
34+ event.hook.resolve(
3635 ai.tools.ToolApproval(granted = True , reason = " approved" ),
3736 )
3837```
3938
4039Return a denial by resolving the hook with ` granted=False ` :
4140
4241``` python
43- ai.resolve_hook(
44- " approve_tool_call_id_here" ,
42+ event.hook.resolve(
4543 ai.tools.ToolApproval(granted = False , reason = " not allowed" ),
4644)
4745```
4846
4947Cancel a live hook when the waiting workflow should stop:
5048
5149``` python
52- await ai.cancel_hook( " approve_tool_call_id_here " , reason = " client disconnected" )
50+ await event.hook.cancel( reason = " client disconnected" )
5351```
5452
5553Hook operations target the current ` HookRegistry ` , which is set inside the
@@ -106,13 +104,10 @@ approval = await ai.hook(
106104)
107105```
108106
109- Resolve the hook from another part of your application :
107+ Resolve the hook from your event handler :
110108
111109``` python
112- ai.resolve_hook(
113- " some_hook" ,
114- {" foo" : 999 },
115- )
110+ event.hook.resolve({" foo" : 999 })
116111```
117112
118113## Resume in serverless flows
@@ -127,34 +122,29 @@ Using the serverless flow only requires you to update the `agent.run` callsite
127122``` python
128123# start (or replay pre-hook part of) a run
129124async with agent.run(model, messages) as stream:
130- # pre-register tool approvals before iterating the stream
131- for approval in approvals:
132- ai.resolve_hook(
133- approval.hook_id,
134- ai.tools.ToolApproval.model_validate(approval.data)
135- )
125+ # apply approvals from the resumed request before iterating the stream
126+ ai.agents.ui.ai_sdk.apply_approvals(approvals)
136127
137128 async for event in stream:
138129 if (
139130 isinstance (event, ai.events.HookEvent)
140131 and event.hook.status == " pending"
141132 ):
142133 # interrupt the loop
143- ai.defer_hook( event.hook)
134+ event.hook.defer( )
144135
145136```
146137
147- When handling the hook event, call ` defer_hook ` to interrupt the loop
138+ When handling the hook event, call ` event.hook.defer() ` to interrupt the loop
148139and surface your tool approvals (or custom hook-related work) to the client.
149140
150141The ` ToolRunner ` will handle multiple concurrent aborts by waiting for all
151142scheduled tasks to complete or get aborted. That way you can run approval-gated
152143tools on serverless concurrently.
153144
154145Once the client has gathered payloads for all hooks, it will re-enter via the
155- same endpoint, which will then pre-register hook resolutions inside the
156- ` agent.run ` block, before iterating the stream. The loop will replay results
157- of LLM calls and tool results
158- from the first run without redoing non-deterministic and duplicating side-effects.
159- When it hits the hook for which it has a pre-registered resolution, it will
160- continue through without suspending.
146+ same endpoint, which will then apply the approvals inside the ` agent.run `
147+ block, before iterating the stream. The loop will replay results of LLM calls
148+ and tool results from the first run without redoing non-deterministic and
149+ duplicating side-effects. When it hits the hook for which it has a
150+ pre-registered resolution, it will continue through without suspending.
0 commit comments