Skip to content

Decide Microsoft 365 approvals in the chat and tidy orchestration retries - #1715

Merged
Paul Lizer (paullizer) merged 7 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-m365-citations-approval-flow
Oct 8, 2026
Merged

Paul Lizer (paullizer) merged 7 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-m365-citations-approval-flow

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Summary

  • Microsoft 365 approvals in a plan are decided in the chat. A SharePoint or OneDrive plan step that needs more than a quick read (3 downloads, 25 MB or 12,000 tokens of file content) stops for the user's extended-analysis approval. Before, it only linked to Approvals. Now the stopped message explains why and offers Allow this time, Always allow for SharePoint/OneDrive or Quick read only. A choice is saved through the existing approvals API, and the plan continues. The failure now carries the approval id; only application-minted ids are kept.
  • No "Retry this failed step?" for Microsoft 365 stops. A Use an action step that stopped for Microsoft 365 sign-in, approval or policy can only have read data, so the server no longer requires external-effect confirmation for it (recovery_projection / prepare_retry). Agent steps and other failures still ask. A confirmation that is still needed now closes as soon as the retry is admitted, instead of staying open until the whole retry finishes.
  • A retry's answer replaces the stopped attempt. The stopped attempt's "The request could not be completed." message is hidden once a later attempt exists, including after reload. It is left out of model history (orchestration and normal chat) and exports, but stays stored. Successful retries no longer show "Saved execution attempt - Attempt 2"; Message details has View previous attempt / Review saved attempt.
  • Why the approval appeared at all: it was the extended-analysis guard with the default Ask preference, not access consent. That's documented in the fix doc, along with the existing per-source preference under Settings.

Linked issue

None; no issue was filed for this work. The companion change that cites Microsoft 365 files, emails and calendar events like workspace documents is developed separately on paullizer-m365-source-citations.

Release Notes & Latest Features

  • New Feature
  • Bug Fix
  • UI Enhancement
  • Breaking Change
  • Internal only

Is this visible to end users?

  • Yes
  • No

Is this admin-facing (Admin Settings, governance, deployment, config)?

  • Yes
  • No

Should this become a Latest Feature card?

  • Yes
  • No
  • Already added

Screenshot needed for the card?

  • Yes
  • No
  • Attached

Version bump

  • application/single_app/config.py VERSION third segment bumped, or not needed because this is docs-only (0.261.301 → 0.261.302)
  • deployers/version.txt bumped, or not needed because deployers/ was not changed

Testing / validation

Run with Python 3.12 in an isolated venv whose only difference from the shared interpreter is pyOpenSSL 26.4.0. The shared interpreter's pyOpenSSL 25.3.0 doesn't import with cryptography 50.

  • python -m pytest functional_tests/test_orchestration_m365_approval_retry_flow.py -q: 8 passed (new).
  • python -m pytest ui_tests/test_v2_orchestration_m365_inline_approval.py ui_tests/test_v2_orchestration_recovery.py ui_tests/test_v2_orchestration_m365_recovery.py ui_tests/test_v2_orchestration_outputs.py -q: 115 passed (7 new inline-approval tests).
  • python -m pytest ui_tests/test_v2_orchestration_recovery_backend.py -q (with PYTHONPATH=application/single_app;functional_tests): 18 passed. The reload test was updated: the stopped attempt is now hidden after a retry.
  • python -m pytest on test_analyze_backend_saved_integration, test_chat_stream_history_context_fix, test_image_chat_route_integration, test_workflow_result_chat_routes, test_saved_results_container_access_chat_orchestration, test_content_screening_history, test_workflow_chat_delivery_placement_and_masking, test_orchestration_conversation_context, test_orchestration_m365_actions and test_orchestration_recovery_safety: 172 passed, 9 failed. The same 9 fail identically on a clean checkout of the base commit (test_chat_stream_history_context_fix ×4, test_workflow_result_chat_routes ×1, test_workflow_chat_delivery_placement_and_masking ×4), so they are not caused by this PR. Three hand-built test namespaces gained the new history helper.
  • python -m pytest functional_tests/test_orchestration_*.py --continue-on-collection-errors (with PYTHONPATH): 6,916 passed, 69 failed. None of the 69 are caused by this PR:
    • 55 also fail on a clean checkout of the base commit fa3422dee. Rerunning their 6 files gives the identical 62-test failure set on both checkouts; 53 of those are ImportError: cannot import name 'enabled_required' from 'functions_settings' in a test stub.
    • The other 14 are test_orchestration_failure_telemetry cases that fail only in the combined run (test-order pollution). That file passes alone on both checkouts (18/18).
  • npm run typecheck and npm run build -- --outDir ../../ui_tests/artifacts/orchestration-plan-editor in application/v2_ui: passed.
  • python scripts/check_xss_sinks.py --base-sha fa3422dee --head-sha HEAD <changed files>: passed for 13 files.
  • python scripts/check_broken_access_control.py --base-sha fa3422dee --head-sha HEAD <changed files>: passed for 7 files.
  • python scripts/build_docs_inventory.py: no surface change. python functional_tests/test_docs_app_surface_coverage.py: 7/7. python functional_tests/test_docs_site_quality.py: 6/6.

Documentation

  • Release notes updated, or not needed (v0.261.302)
  • Feature documentation updated, or not needed (not needed)
  • Fix documentation updated, or not needed (docs/explanation/fixes/ORCHESTRATION_M365_APPROVAL_RETRY_FLOW_FIX.md; docs/admin/orchestration.md and docs/reference/chat-controls.md updated)

Security checklist

  • New Flask routes include @swagger_route(security=get_auth_security()) (no routes added)
  • Settings sent to non-admin frontends use sanitize_settings_for_user() (no settings sent)
  • Browser JavaScript is served from local SimpleChat static assets only; no CDN-hosted JS
  • No secrets, keys, connection strings, or local-only artifacts are included

…ries

A plan step that had to read more of a SharePoint or OneDrive file than a quick
read covers stopped for the user's extended-analysis approval and only linked to
Approvals. The stopped message now offers the decision inline (Allow this time,
Always allow, Quick read only) and continues the plan once it is saved.

- Carry the pending approval id on m365_approval_required failures, keeping only
  application-minted ids.
- Retry a Use an action step that stopped for Microsoft 365 without the external-
  effect confirmation; plan steps only read Microsoft 365 data, and the server
  enforces it. Agent steps and other failures still ask.
- Close a retry confirmation as soon as the retry is admitted.
- Hide an attempt that a later retry replaced, leave it out of model history and
  exports, and drop the attempt notice from successful retries; the attempt links
  move to Message details.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread ui_tests/test_v2_orchestration_m365_inline_approval.py Fixed
CodeQL flagged test_v2_orchestration_plan_editor as imported with both
'import' and 'import from'. Take RUN from the same from-import as the
shared fixtures instead of a second module alias.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) and others added 5 commits October 8, 2026 15:24
… flow branch

Brings in microsoft#1716 (Microsoft 365 sign-in session race fix, automatic workflow
encryption key, Microsoft 365 links that stay in V2).

Conflict and semantic resolutions:
- release_notes.md: both branches added entries under v0.261.302; kept both
  sets. The next commit moves this branch's entries to their own version.
- microsoft#1716 moved M365_APPROVALS_HREF from m365Connect.ts to m365Links.ts as an
  in-app router path (/approvals/m365) rendered with Link. The inline
  approval card now imports it from there and renders a Link, and its
  Settings link uses the new section deep link to the Microsoft 365 sharing
  card, where Extended analysis is set (M365_SHARING_PREFERENCES_HREF).
- The m365Links guardrail test pins every exported link the XSS checker
  trusts by name; it now pins the new sharing-preferences path.
- The inline approval UI test expects the new in-app link paths.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
microsoft#1716 shipped as 0.261.302, the version this branch used, and the open
Microsoft 365 citations PR (microsoft#1718) holds 0.261.303. Move this branch to
0.261.304: config.py, its own release-notes section above v0.261.302, and
the version headers and "Since" notes in its code, tests and docs.

The fix doc also lists the sharing-preferences link and guardrail pin added
when the base was merged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…files

Brings in microsoft#1720, which lists every file and agent document a conversation
produced in the V2 Documents drawer, for the replies the thread shows. The
merge had no textual conflicts.

Semantic resolution: this branch hides an orchestration attempt that a later
retry replaced. microsoft#1720's drawer filters only skipped replies replaced by a
workflow reply, so a hidden attempt's files and agent documents would still
be listed. collectConversationGeneratedFiles() and visibleGeneratedDocuments()
now skip replaced attempts too, with a regression case in the drawer logic
test, and this branch's docs and release notes say so.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…file sign-in fixes

Brings in microsoft#1721 (0.261.303): waiting orchestration runs survive settings
saves, failed files explain why, and a plan retry is offered for a file that
failed for good.

Conflict resolutions:
- config.py: keep 0.261.304, the next version after the base's 0.261.303.
- functions_orchestration_recovery.py: docstring only; Version 0.261.304 and
  both history notes, in version order. The code merged cleanly: the waiting
  step eligibility change and the Microsoft 365 confirmation exemption touch
  different lines.
- release_notes.md: v0.261.304 above the base's v0.261.303 and v0.261.302.
- chat-controls.md: the base's new Retry from failed step condition, this
  branch's Confirm retry wording, and its two new rows.

Semantic resolution: microsoft#1721 gates the plan retry on planRetryOffered instead of
"no file outputs". The inline Microsoft 365 approval card continues the plan,
so it now uses the same gate.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve approval retry details and source citation imports. Wire the new real citation helpers into the Analyze integration harness.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit e1657ef into microsoft:paullizer-react-v2-ui Oct 8, 2026
11 checks passed
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