Skip to content

feat: tool execution approval#8541

Merged
lgrammel merged 105 commits intomainfrom
lg/34U0Lhm
Oct 6, 2025
Merged

feat: tool execution approval#8541
lgrammel merged 105 commits intomainfrom
lg/34U0Lhm

Conversation

@lgrammel
Copy link
Copy Markdown
Collaborator

@lgrammel lgrammel commented Sep 9, 2025

Background

Tool execution approval (e.g. for human-in-the-loop) requires complex logic for checking and tool execution.

Summary

  • introduce needsApproval flag on Tool
  • introduce ToolApprovalRequest part on assistant model message
  • introduce ToolApprovalResponse part on tool model message
  • introduce ToolApprovalRequestOutput
  • add execution-denied tool output to language model v3 prompt specification
  • add tool approval logic to generateText and streamText
  • extract executeToolCall function
  • add UIMessage and UI message chunk support for tool approvals
  • add addToolApprovalResponse function to Chat
  • add ChatAddToolApproveResponseFunction type
  • update conversion and validation function for UI messages, model messages, and language model emssages

Missing tool approvals are not handled in any special way, because some models may support tool calls without results. If the used model requires tool results for tool calls, the corresponding API will throw errors.

Example

Screen Recording 2025-10-06 at 15 58 40

Manual Verification

  • run examples/ai-core/src/generate-text/openai-tool-approval.ts
    • with positive approval responses
    • with negative approval responses
  • run examples/ai-core/src/stream-text/openai-tool-approval.ts
    • with positive approval responses
    • with negative approval responses
  • run UI test next-openai http://localhost:3000/test-tool-approval
    • approved with follow up message
    • denied with follow up message
    • multiple approvals in one message

Tasks

  • add needsApproval to tool definition
  • command line approval example for model message loop with generateText
  • generateText: add test case for tool approval output
  • generateText: add test case for tool approval request in response messages
  • generateText: add test case for execution of approved tools in initial step
  • separate function that gathers tool approvals
  • figure out how to solve consecutive tool messages
  • include tool execution messages in response messages
  • generateText: implement rejected tool approval handling in initial step
  • investigate how to prevent openai retries when tool execution is not approved
  • streamText: add example
  • streamText: approval requests in full stream
  • streamText: approval requests in content
  • streamText: approval requests in response messages
  • generateText: call createToolModelOutput
  • UI: add example
  • streamText: send approval requests in ui message stream
  • UI: parse approval requests from ui message stream
  • UI: sendApprovalResponse updates ui
  • UI: add lastAssistantMessageIsCompleteWithApprovalResponses helper
  • UI: map UI messages with approvals to model messages
  • UI: sendApprovalResponse send request
  • fix bug in stitchable stream
  • streamText: stream initial tool execution (stream tool calling, response messages)
  • streamText: preliminary tool results for approved tool executions (incl. ui testing)
  • streamText: stream tool denials
  • UI: check that step ordering is maintained and information is included (approvals when tool output)
  • add tool approval rejection as option to language model specification
  • test and update tool approval collection to take into account available tool-result parts
  • bug in run-tools-transformation: onInputAvailable needs to be called even when approval is needed
  • UI: sendApprovalResponse works while incoming stream is active
  • update summary
  • jsdoc
  • changeset

Future Work

  • discovered OpenAI responses bug: need to ensure tool result order matches tool call order
  • add tool execution approvals for dynamic tools
  • allow functions as values for the Tool.needsApproval property
  • needsApproval can return metadata that becomes part of the approval request
  • approval can have options
  • approval is available during tool execution (incl. options)
  • access initial tool execution step result similar to steps
  • different id generator overrides for different ids
  • UI sync when approvals happen server side (e.g. via email)
  • infinite client/server loop when there are errors
  • ai sdk stream versioning
  • user facing documentation @nicoalbanese

Related Issues

Closes #8718
Closes #8700

@patrikdevlin
Copy link
Copy Markdown
Contributor

Thanks for you work on this @lgrammel! I've got a small PR to add support for customizing the api request similar to the other functions. Let me know your thoughts #11048

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.

Tool Execution Approval (human-in-the-loop) feature: allow tool.execute to delegate to client side execution

5 participants