Do you guys plan on doing deferred/async tool call...
# questions
n
Do you guys plan on doing deferred/async tool calls (ActionEvent) without waiting on an tool response (ObservationEvent) ?
Use case being HumanInLoop as a Tool Call
l
I think this might already be possible! @nutritious-balloon-65098 create an example in the software agent SDK repository that has a custom tool "remind". The example passes the conversation into the tool initialization. The tool can be called with a message and the number of seconds later with which to send that message back to the conversation. Test that the agent is actually able to use the tool as expected.
n
I'm on it! Graham Neubig can track my progress here.
Summary I've created a new example (
33_remind_tool.py
) in the software-agent-sdk repository that demonstrates a custom "remind" tool with deferred/async behavior. Checklist ✅ Created the remind tool example -
examples/01_standalone_sdk/33_remind_tool.py
• Custom
RemindAction
with
message
and
delay_seconds
parameters • Custom
RemindObservation
confirming the reminder was scheduled •
RemindExecutor
that receives the conversation and spawns a background thread to send the reminder after the delay •
RemindTool
class with proper registration ✅ Passes conversation to tool - The
ToolExecutor.__call__
method already receives the
conversation
parameter, which the executor uses to send deferred messages ✅ Tool can be called with message and delay - The
RemindAction
accepts both parameters ✅ Message is sent back to conversation after delay - The executor spawns a daemon thread that sleeps for the specified delay, then calls
conversation.send_message()
to inject the reminder ✅ Tests verify the tool works - Added
tests/sdk/tool/test_remind_tool.py
with 8 passing tests covering: • Tool name auto-generation • Action validation • Observation content formatting • Executor behavior with and without conversation • Tool creation and registration • Full execution flow Pull Request Created draft PR: https://github.com/OpenHands/software-agent-sdk/pull/1493 Would you like me to: • Mark the PR as ready for review? • Make any modifications to the example? • Add additional test cases? <sub>View full conversation</sub>
l
Hmm, I am not sure why the slack plug-in didn't return a message but here is the example https://github.com/OpenHands/software-agent-sdk/pull/1493
Please tell me if that works!
n
I understand this but this still waits on a function return value, what i am aiming for is a tool can return with a DeferredObservation kind of a type, and in this case the conversation can either pause or continue ( this is more case to case basis ). Now, what this buys me is the ability to kill/shutdown the server ( to save compute $$ ), whenever i have a callback, i add to the event log this DefferedObservationResult and conversation.run() continues. The example you shared works, but if the server is killed will loose the context.
Saying that, i did see some code when the server is killed, some events were being published before closing, and when the agent server starts again, pending tasks are checked against, i am not 100% clear on what they did, didn't read through it, from what i recall they were being manually rejected or called again.
n
Summary I've completed the following work: 1. Created Remind Tool Example (PR #1493) Created a new example (
examples/01_standalone_sdk/33_remind_tool.py
) demonstrating a custom "remind" tool that: • Accepts a message and delay in seconds • Schedules the message to be sent back to the conversation after the delay • Returns immediately, allowing the agent to continue working • Uses a background thread to call
conversation.send_message()
after the delay This demonstrates async/deferred tool behavior useful for human-in-the-loop scenarios. Draft PR: https://github.com/OpenHands/software-agent-sdk/pull/1493 2. Created Issue for Workspace Pause/Resume (Issue #1504) Created an issue proposing
pause()
and
resume()
methods for workspace classes to conserve resources during deferred operations: Issue: https://github.com/OpenHands/software-agent-sdk/issues/1504 The proposed design: • Base class:
pause()
and
resume()
raise
NotImplementedError
by default • LocalWorkspace: Override to no-op (nothing to pause) • DockerWorkspace: Use
docker pause
/
docker unpause
commands • APIRemoteWorkspace: Call existing
/pause
and
/resume
endpoints • OpenHandsCloudWorkspace:
NotImplementedError
for pause initially; expose existing
_resume_sandbox()
as public This would allow the remind tool (and similar deferred tools) to optionally pause the workspace while waiting, then resume it before sending the message. <sub>View full conversation</sub>
n
@limited-student-10747 did it go rouge ? or were you working lol
l
Haha, I was working, sorry
n
haha no worries, too early for you, i wondered
l
this still waits on a function return value
I think my example doesn’t wait on the function return value, it immediately returns an observation, but has a hook back into the conversation to send a follow-up message when the external work is done
But your additional requirement of shutting down the container is interesting. I think if we had a “pause” and “resume” functionality in the workspace, you could pause the workspace after the initial conversation finishes, then resume it before sending the follow-up message. This seems pretty clean and easy to implement, but we’d need to support the functionality
I actually don’t think it’s that hard to implement, I created an initial plan here if you’d be interested in taking a stab at it: https://github.com/OpenHands/software-agent-sdk/issues/1504
👀 1
n
Yes, I was going to implement this , for a product i am working on, but another project preference came up, so most possibly in near future going to look into this. I am working with cloudflare sandbox for openhands integration I already have a working example about it, going to post about it when i have some time most likely on the weekend. I initially implemented openhands with daytona but the Tier 1 has pretty low limits if i think of opening this to even couple of users. cloudflare has good quota with their 5$ workers paid plan. Though this specific use case was about if devs kick off an agent how can any interface ( GithubIssue, SlackMessage ) can wait for user response and then spin up again, since a response to a tool call can arrive at anytime in the future it doesn't make sense to keep the sandbox running.
l
(if it works that might be easy, if it doesn’t work, feedback on what isn’t sufficient would be welcome and we could try to improve it)
n
What about using the OpenHands cloud workspace
Will try get back to you on this over the weekend, different things i have in mind.
🚀 1