Deliver File Sync prompt context to the first workflow task - #1287
Merged
Paul Lizer (paullizer) merged 1 commit intoAug 18, 2026
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1285
Problem
File Sync's prompt context — the block that tells a workflow what actually changed — never reached the model in any task-based workflow, which is every workflow the builder creates.
The failure was silent and actively misleading. The context was written into the conversation's user message, so the run transcript displayed the changed-document list as though the model had received it. In practice the model got only the raw task instructions and typically replied that it had no information about any documents.
What File Sync is supposed to do
Before a run, File Sync scans the configured sources and hands the workflow two separate things:
Scanned / Created / Updated / Unchanged / Skipped / Failed) plus a numbered list of each new or changed document (relative_path,action,document_id,source_name). This is what makes instructions like "summarize the documents that changed since the last run" work.Item 2 worked. Item 1 did not.
Root cause
_apply_file_sync_context_to_workflow()appended the context to the workflow-leveltask_prompt._build_workflow_task_execution_workflow()expected it on a different key, then overwrotetask_promptwith the task's own instructions:file_sync_prompt_contextwas read in exactly one place and written nowhere. The producer line was added in79148c84alongside the consumer and later lost in a merge on a long-lived branch (thefix/1031-tabular-row-orchestration-scale/ PR #1145 lineage). The consumer survived; the producer did not.Who was affected: Monitor File Sync Changes workflows — an entire trigger type whose purpose is reacting to what changed — unless they happened to use Analyze with Use changed documents. Also any workflow using
SearchorNo document action, and any workflow with Use changed documents disabled.Changes
1. Restored the producer
2. Gave the document search query a clean source
This was the blocking discovery, and the reason the fix is more than one line.
_prepare_workflow_search_context()usedworkflow['task_prompt']verbatim as the Azure AI Search query, and that singlequeryvalue feeds all four search call sites. Restoring the injection without this would have turned a Search task's query into 50 lines of file paths and sync counters.The prepared workflow now carries
task_search_query, captured from the task's instructions before any context blocks are appended:The fallback to
task_promptmeans every caller without the key behaves exactly as before.3. Made the first-task gate explicit
The injection was gated on
include_document_action, which used to mean "task 1". After #1284 that flag means "legacy record with no task-level document action", so it no longer expressed the intent. A dedicatedinclude_file_sync_contextparameter now carries it, passedtask_index == 0.Later tasks receive the information indirectly through task one's response, which is already chained forward as bounded context.
4. Bounded the context block
WORKFLOW_FILE_SYNC_CONTEXT_MAX_CHARS = 8000with head/tail truncation and a[File Sync context truncated]marker, mirroring the existing treatment of previous-task output. It is applied inside_format_workflow_file_sync_context()rather than at the injection site, so the conversation transcript and the prompt the model receives stay identical — that mismatch is exactly what made this bug invisible.Behavior change worth flagging
Scoping the search query to the task's own instructions also means a task-2-or-later Search action no longer uses the previous task's reply as query text. That only became reachable in #1284, and a full prior answer is far more likely to dilute retrieval than help it, so this is the intended behavior — but it is a change, not just a fix. Retrieved content and context still reach the model exactly as before; only the query is scoped.
Why no test caught the original bug
test_workflow_task_sequence.pyhand-injectedfile_sync_prompt_contextinto the workflow dict and asserted[Workflow input context]appeared in the dispatched prompt. It exercised the consumer with a value production never supplied, so it passed while the feature was broken. It now builds the context through_apply_file_sync_context_to_workflow()instead.Validation
functional_tests/test_workflow_file_sync_prompt_context.py— 8/8. Covers the producer, first-task-only injection, the legacy no-tasks path, search-query isolation for both paths, the truncation notice (including a realistic 50-document sync with deeply nested paths), the "nothing changed" wording, and that Use changed documents targeting is unaffected.test_workflow_task_sequence.py— 10/10.test_workflow_task_document_actions.py— 16/16.test_workflow*sweep against a cleangit archiveexport of the base commit: 21 pre-existing failures on both sides, identical file sets, and per-file output diffs contain only traceback path differences.functional_tests/route_tests/all pass. The personal and group document picker harnesses from Fix workflow document picker loading and make workspace documents per-task #1284 still pass.Version
0.250.225→0.250.226, with fix documentation, an index entry, and release notes.