Skip to content

fix: human tool approval requests omit policy reasons - #19658

Merged
gr2m merged 5 commits into
mainfrom
bugfix-19654-20260826024353487723
Aug 26, 2026
Merged

fix: human tool approval requests omit policy reasons#19658
gr2m merged 5 commits into
mainfrom
bugfix-19654-20260826024353487723

Conversation

@ai-sdk-factory

@ai-sdk-factory ai-sdk-factory Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Background

OPA documentation promises that requires-approval reasons reach human approvers, but published generation and UI approval requests omitted them.

Root Cause

The OPA normalizer discarded requires-approval reasons, while user-approval status and request types could not carry them; the original reproduction confirmed both generateText and streamText lost the reason.

Summary

  • Preserved optional reasons through OPA normalization, approval status and request types, generateText and streamText outputs, response messages, UI serialization, processing, validation, and model-message conversion.
  • Kept the UI request reason as approval.requestReason, separate from the approver's response reason, so both survive approval state transitions and persisted-message round trips.
  • Documented the core result, UI message, stream protocol, and model-message conversion fields.
  • Added patch changesets for ai, @ai-sdk/policy-opa, and @ai-sdk/provider-utils.

Compatibility

Existing approval inputs and stored messages remain valid. Requests without a reason keep their previous runtime shape. The UI stream adds only an optional reason field, while UI messages add the optional approval.requestReason field and retain the existing response approval.reason semantics.

Testing

  • Focused AI UI tests: 270 passed in Node and 270 passed in Edge.
  • Focused policy-OPA tests: 22 passed in Node and 22 passed in Edge.
  • Affected package type checks and the full workspace type check passed.
  • Formatting and lint checks passed with no warnings or errors.
  • Documentation content sync, MDX generation, and docs TypeScript checking passed.

Regression coverage verifies OPA normalization and integration, generateText, streamText, response-message conversion, UI chunk conversion and processing, request/response reason lifecycle preservation, stored-message validation, public types, and model-message conversion.

End-to-end Validation

  • replay_original_reproduction: both generateText and streamText human approval requests contained the policy reason; classified no-longer-reproduces.

Related Issues

Fixes #19654

Closes #19655

ai-sdk-factory and others added 3 commits August 26, 2026 03:25
Co-authored-by: ladanjohari <13539962+ladanjohari@users.noreply.github.com>
Co-authored-by: ladanjohari <13539962+ladanjohari@users.noreply.github.com>
@ai-sdk-factory

Copy link
Copy Markdown
Contributor Author

Bugfix review

Outcome: approved

Reproduction replay

Status: no-longer-reproduces

The exact original reproduction completed successfully and the original bug signal did not appear.

Fixes issue

Status: fully-addresses

The OPA normalizer now preserves requires-approval reasons, and the reason propagates through generateText, streamText, response messages, UI chunks, UI state, validation, and model-message conversion.

Side effects

Risk: low

Existing approval behavior is unchanged when no reason is supplied; the only observable addition is the documented optional reason on human approval requests.

Performance

Risk: low

The change only carries and serializes one optional string per applicable approval request, with no new loops, retained collections, network operations, or expensive computation.

Backwards compatibility

Risk: low

Existing stored messages remain valid, while newly created pending approval messages may contain an additional optional reason field that validation and round-trip conversion now support without migration.

Breaking changes

Risk: none

Public types and accepted message schemas are broadened additively; no APIs, exports, accepted inputs, defaults, errors, or persisted formats are removed or narrowed.

Architecture

Risk: low

Ownership remains sound: policy-opa normalizes the policy decision, provider-utils owns the shared model-message request type, and ai owns generation and UI propagation. No cross-package src imports or dependency-direction violations were introduced.

Change scope

Status: minimal

Each production hunk participates in preserving, typing, validating, serializing, or testing the reason across an existing approval path, and the required patch changesets cover all affected published packages.

Security

Risk: low

The change exposes policy-provided text only through the already documented human-approval channel and does not alter execution authorization, signatures, URL handling, parsing, or trust decisions.

Testing

Status: appropriate

Regression tests cover OPA normalization, generateText, streamText, response and UI serialization, UI processing, stored-message validation, and model-message conversion in both Node and Edge configurations.

Verification

Inspected all 23 changed files against origin/main, public exports and surrounding approval flows, and package boundaries. The focused AI tests passed 943 tests in both Node and Edge configurations; policy-opa tests passed, affected package type checks passed, formatting and lint checks passed, and the diff had no whitespace errors.

Relevant Documentation

@ai-sdk-factory ai-sdk-factory Bot changed the title fix: surface policy reasons in human tool approval requests fix: human tool approval requests omit policy reasons Aug 26, 2026
@ai-sdk-factory

Copy link
Copy Markdown
Contributor Author

Addressed PR comment 5427242123.

Bugfix review

Outcome: approved

Reproduction replay

Status: no-longer-reproduces

... 64 more line(s) omitted

No change was made because the review approved the existing propagation, compatibility, architecture, and coverage. I reran the focused Node and Edge tests, affected and full type checks, formatting and lint checks, and the immutable reproduction; all passed and the replay remains no-longer-reproduces.

@ai-sdk-factory

Copy link
Copy Markdown
Contributor Author

Bugfix review

Outcome: approved

Reproduction replay

Status: no-longer-reproduces

The exact original reproduction completed successfully and the original bug signal did not appear.

Fixes issue

Status: fully-addresses

The OPA normalizer preserves requires-approval reasons, and the reason reaches core outputs, response messages, UI chunks, pending UI state, validation, and model-message round trips.

Side effects

Risk: low

Requests without a reason retain their existing shapes and behavior; only requests supplied with a reason gain the documented optional field.

Performance

Risk: low

The change carries one optional string through existing objects and serialization paths without adding loops, network operations, retained collections, or expensive computation.

Backwards compatibility

Risk: low

Existing stored messages remain valid without migration, while newly stored pending approvals may add an optional reason that the updated validators and converters accept.

Breaking changes

Risk: none

Public status, request, output, UI, and message types are widened additively; no exports, accepted inputs, defaults, errors, configuration, or existing persisted fields are removed or narrowed.

Architecture

Risk: low

Ownership remains consistent: policy-opa normalizes policy decisions, provider-utils owns the shared model-message request type, and ai owns generation and UI propagation. No cross-package src imports or dependency-direction violations were introduced.

Change scope

Status: minimal

All 23 changed files either propagate, type, validate, test, or release-note the optional reason across the existing approval pipeline.

Security

Risk: low

The change exposes policy-provided text only through the documented human-approval channel and does not alter authorization decisions, approval signatures, parsing, URL handling, or tool execution.

Testing

Status: appropriate

Regression tests cover normalization, generateText, streamText, response and UI serialization, UI processing, stored-message validation, and model-message conversion in Node and Edge runtimes.

Verification

Inspected the complete diff and surrounding public APIs and package boundaries. Focused Node and Edge runs each passed 943 AI tests; policy normalization passed 13 tests in each runtime. Affected package and workspace type checks, formatting, linting, and diff whitespace checks passed.

Relevant Documentation

@gr2m
gr2m merged commit 3e125ba into main Aug 26, 2026
52 checks passed
@gr2m
gr2m deleted the bugfix-19654-20260826024353487723 branch August 26, 2026 19:00
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Published in:

Package Version
ai 7.0.82 github npm
@ai-sdk/alibaba 2.0.37 github npm
@ai-sdk/amazon-bedrock 5.0.65 github npm
@ai-sdk/angular 3.0.82 github npm
@ai-sdk/anthropic 4.0.44 github npm
@ai-sdk/anthropic-aws 2.0.36 github npm
@ai-sdk/assemblyai 3.0.32 github npm
@ai-sdk/azure 4.0.51 github npm
@ai-sdk/baseten 2.1.17 github npm
@ai-sdk/black-forest-labs 2.0.33 github npm
@ai-sdk/bytedance 2.0.35 github npm
@ai-sdk/cartesia 3.0.27 github npm
@ai-sdk/cerebras 3.0.39 github npm
@ai-sdk/code-mode 1.0.39 github npm
@ai-sdk/cohere 4.0.32 github npm
@ai-sdk/deepgram 3.1.3 github npm
@ai-sdk/deepinfra 3.0.39 github npm
@ai-sdk/deepseek 3.0.34 github npm
@ai-sdk/elevenlabs 3.0.33 github npm
@ai-sdk/fal 3.0.33 github npm
@ai-sdk/fireworks 3.0.42 github npm
@ai-sdk/fish-audio 3.0.10 github npm
@ai-sdk/gateway 4.0.67 github npm
@ai-sdk/gladia 3.0.32 github npm
@ai-sdk/gmicloud 3.0.10 github npm
@ai-sdk/google 4.0.53 github npm
@ai-sdk/google-vertex 5.0.65 github npm
@ai-sdk/groq 4.0.33 github npm
@ai-sdk/harness 1.0.90 github npm
@ai-sdk/harness-acp 1.0.28 github npm
@ai-sdk/harness-claude-code 1.0.93 github npm
@ai-sdk/harness-cline 1.0.17 github npm
@ai-sdk/harness-codex 1.0.92 github npm
@ai-sdk/harness-cursor 1.0.3 github npm
@ai-sdk/harness-deepagents 1.0.90 github npm
@ai-sdk/harness-fx 1.0.3 github npm
@ai-sdk/harness-grok-build 1.0.27 github npm
@ai-sdk/harness-opencode 1.0.91 github npm
@ai-sdk/harness-pi 1.0.92 github npm
@ai-sdk/huggingface 2.0.39 github npm
@ai-sdk/hume 3.0.32 github npm
@ai-sdk/klingai 4.0.34 github npm
@ai-sdk/langchain 3.0.82 github npm
@ai-sdk/llamaindex 3.0.82 github npm
@ai-sdk/lmnt 3.0.32 github npm
@ai-sdk/luma 3.0.33 github npm
@ai-sdk/mcp 2.0.39 github npm
@ai-sdk/minimax 3.0.20 github npm
@ai-sdk/mistral 4.0.35 github npm
@ai-sdk/moonshotai 3.0.41 github npm
@ai-sdk/open-responses 2.0.34 github npm
@ai-sdk/openai 4.0.49 github npm
@ai-sdk/openai-compatible 3.0.39 github npm
@ai-sdk/otel 1.0.82 github npm
@ai-sdk/perplexity 4.0.34 github npm
@ai-sdk/policy-opa 1.0.82 github npm
@ai-sdk/prodia 2.0.33 github npm
@ai-sdk/provider-utils 5.0.32 github npm
@ai-sdk/quiverai 2.0.32 github npm
@ai-sdk/react 4.0.85 github npm
@ai-sdk/replicate 3.0.33 github npm
@ai-sdk/revai 3.0.32 github npm
@ai-sdk/rsc 3.0.82 github npm
@ai-sdk/sandbox-just-bash 1.0.90 github npm
@ai-sdk/sandbox-vercel 1.0.90 github npm
@ai-sdk/svelte 5.0.82 github npm
@ai-sdk/togetherai 3.0.40 github npm
@ai-sdk/tui 1.0.83 github npm
@ai-sdk/valibot 3.0.32 github npm
@ai-sdk/voyage 2.0.32 github npm
@ai-sdk/vue 4.0.82 github npm
@ai-sdk/workflow 2.0.12 github npm
@ai-sdk/workflow-harness 1.0.90 github npm
@ai-sdk/xai 4.0.47 github npm
@ai-sdk/zai 3.0.1 github npm

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

reason is documented as surfaced to human approvers, but user-approval cannot carry one

2 participants