Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e255e22
improved tabular analysis
paullizer Jul 22, 2026
aea82a4
Add authorized mixed-source manifest contracts
paullizer Jul 22, 2026
28d4700
Merge pull request #1064 from microsoft/feature/1056-authorized-sourc…
paullizer Jul 22, 2026
778c10f
Add mixed-source chat search and migration recovery
paullizer Jul 22, 2026
81933f4
Merge pull request #1065 from paullizer/feature/1057-chat-search-mixe…
paullizer Jul 22, 2026
26508c0
Fix CSV artifacts for non-tabular documents
paullizer Jul 22, 2026
fc6d971
Merge pull request #1067 from paullizer/fix/1066-non-tabular-document…
paullizer Jul 22, 2026
ebd7394
Add mixed-source combined Analyze
paullizer Jul 22, 2026
f34c1e6
Merge pull request #1068 from microsoft/feature/1059-mixed-source-ana…
paullizer Jul 22, 2026
1f93bc5
Add cross-format compare orchestration
paullizer Jul 23, 2026
b504f3b
Merge pull request #1069 from paullizer/feature/1059-phase-4-cross-fo…
paullizer Jul 23, 2026
9178649
Add mixed-source conversation continuity
paullizer Jul 23, 2026
d7e04ec
Merge pull request #1070 from microsoft/feature/1060-conversation-con…
paullizer Jul 23, 2026
95df035
Harden mixed-source orchestration and CSV exports
paullizer Jul 23, 2026
ee85a13
Merge pull request #1074 from microsoft/feature/1061-mixed-source-har…
paullizer Jul 23, 2026
a483491
Add universal CSV generation and mixed-source Analyze
paullizer Jul 23, 2026
dbab53e
Merge pull request #1075 from paullizer/fix/1071-universal-csv-genera…
paullizer Jul 23, 2026
e2133e9
Add generic generated file export framework
paullizer Jul 23, 2026
c4653ab
Expand authorized search retrieval capacity
paullizer Jul 23, 2026
2b196f5
Merge pull request #1076 from paullizer/fix/1071-universal-csv-genera…
paullizer Jul 23, 2026
d199d15
Merge origin/Development into tabular orchestration branch
paullizer Jul 31, 2026
722d491
Merge latest Development into tabular orchestration branch
paullizer Jul 31, 2026
066eed7
Restore conversation fork operation API
paullizer Jul 31, 2026
9ad46d7
Preserve mixed source manifest storage locators
paullizer Aug 3, 2026
1d7c651
Merge remote-tracking branch 'origin/Development' into fix/1031-tabul…
paullizer Aug 3, 2026
c7b0dbb
Fix duplicate data management restore review route
paullizer Aug 3, 2026
b3a7612
Remove generated migration state artifacts
paullizer Aug 4, 2026
2f59d8b
Fix SharePoint URL detection CodeQL alerts
paullizer Aug 4, 2026
2ae3f34
Fix CodeQL markdown fence parsing alerts
paullizer Aug 4, 2026
1befaf7
Fix chat exception disclosure alerts
paullizer Aug 4, 2026
a6b5e10
Fix Foundry citation thought CodeQL alert
paullizer Aug 4, 2026
562988d
Fix token usage fixture duplicate keys
paullizer Aug 4, 2026
68b25a4
Fix chat route unreachable CodeQL alert
paullizer Aug 4, 2026
cef2679
Fix tabular lifecycle no-effect CodeQL alert
paullizer Aug 4, 2026
fbec452
Fix Semantic Kernel return CodeQL alert
paullizer Aug 4, 2026
77afb69
Fix duplicate chat stream json import
paullizer Aug 4, 2026
0bbcf59
Merge Development into PR 1145 branch
paullizer Aug 4, 2026
88f4043
Fix CodeQL import cycle alerts
paullizer Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions application/single_app/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# app.py
import builtins
import bleach
import logging
import pickle
import json
Expand Down Expand Up @@ -1047,8 +1048,36 @@

# Add target="_blank" to all <a> links
html = re.sub(r'(<a\s+href=["\'](https?://.*?)["\'])', r'\1 target="_blank" rel="noopener noreferrer"', html)
allowed_tags = set(bleach.sanitizer.ALLOWED_TAGS).union({
'p',
'pre',
'span',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'br',
'table',
'thead',
'tbody',
'tr',
'th',
'td',
})
allowed_attributes = dict(bleach.sanitizer.ALLOWED_ATTRIBUTES)
allowed_attributes['a'] = ['href', 'title', 'target', 'rel']
allowed_attributes['*'] = ['class']
html = bleach.clean(
html,
tags=allowed_tags,
attributes=allowed_attributes,
protocols={'http', 'https', 'mailto'},
strip=True,
)

return Markup(html)
return Markup(html) # xss-check: ignore - sanitized with bleach.clean before Markup.

# Add the filter to the Jinja environment
app.jinja_env.filters['markdown'] = markdown_filter
Expand All @@ -1058,8 +1087,8 @@
"""Escape HTML then convert newline characters to <br> tags."""
from markupsafe import escape, Markup
if not value:
return Markup('')
return Markup(str(escape(value)).replace('\n', '<br>\n'))
return Markup('') # xss-check: ignore - static empty safe markup.

Check warning on line 1090 in application/single_app/app.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains dynamic execution, persistence, or system access marker. Recommendation%3A Do not execute changed lifecycle scripts or installers while this finding is unresolved.
return Markup(str(escape(value)).replace('\n', '<br>\n')) # xss-check: ignore - value is escaped before adding static br tags.

app.jinja_env.filters['nl2br'] = nl2br_filter

Expand Down
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.250.114"
VERSION = "0.250.120"
IS_DEVELOPMENT = is_development_env_enabled()

SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax')
Expand Down
75 changes: 74 additions & 1 deletion application/single_app/foundry_agent_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@
FOUNDRY_INTERNAL_METADATA_KEYS = {
"active_group_ids",
"active_public_workspace_ids",
"document_context_requested",
"document_scope",
"group_id",
"selection_mode",
"selected_document_id",
"selected_document_ids",
"user_id",
}
FOUNDRY_FILE_SEARCHABLE_CONTEXT_MAX_CHARS = 6000
FOUNDRY_FILE_SEARCHABLE_CONTEXT_HEADER = "Attached file searchable summary"
Expand Down Expand Up @@ -391,6 +397,14 @@
) -> FoundryAgentInvocationResult:
"""Invoke a Foundry agent using Semantic Kernel's AzureAIAgent abstraction."""

message_history = _filter_foundry_document_context_messages(
message_history,
include_document_context=_coerce_bool(
foundry_settings.get("include_document_context"),
True,
),
)

agent_id = (foundry_settings.get("agent_id") or "").strip()
if not agent_id:
raise FoundryAgentInvocationError(
Expand Down Expand Up @@ -491,6 +505,14 @@
) -> FoundryAgentInvocationResult:
"""Invoke the new Foundry application runtime through its Responses protocol endpoint."""

message_history = _filter_foundry_document_context_messages(
message_history,
include_document_context=_coerce_bool(
foundry_settings.get("include_document_context"),
True,
),
)

application_name = _resolve_new_foundry_application_name(foundry_settings)
endpoint = _resolve_endpoint(foundry_settings, global_settings)
responses_api_version = (
Expand Down Expand Up @@ -573,6 +595,14 @@
) -> AsyncIterator[FoundryAgentStreamMessage]:
"""Stream a new Foundry application response through the Responses API."""

message_history = _filter_foundry_document_context_messages(
message_history,
include_document_context=_coerce_bool(
foundry_settings.get("include_document_context"),
True,
),
)

application_name = _resolve_new_foundry_application_name(foundry_settings)
endpoint = _resolve_endpoint(foundry_settings, global_settings)
responses_api_version = (
Expand Down Expand Up @@ -1222,10 +1252,45 @@
"chat-uploaded file",
"selected document",
"tabular analysis",
"mixed-source evidence handoff",
"evidence_envelopes",
"[workflow document search context]",

Check warning on line 1257 in application/single_app/foundry_agent_runtime.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
)
return any(marker in normalized for marker in markers)


def _filter_foundry_document_context_messages(
message_history: List[ChatMessageContent],
include_document_context: bool = True,
) -> List[ChatMessageContent]:
"""Remove document/evidence messages before Foundry transport when opted out."""
if include_document_context:
return list(message_history or [])

filtered_messages: List[ChatMessageContent] = []
workflow_task_marker = "[workflow task]"
for message in list(message_history or []):
text = _extract_message_text(message).strip()
if not text:
continue
if not _looks_like_document_context_message(text):
filtered_messages.append(message)
continue

marker_index = text.lower().rfind(workflow_task_marker)
if marker_index < 0:
continue
workflow_task = text[marker_index + len(workflow_task_marker):].strip()
if not workflow_task:
continue
filtered_messages.append(ChatMessageContent(
role=getattr(message, "role", "user"),

Check warning on line 1287 in application/single_app/foundry_agent_runtime.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

Check warning on line 1287 in application/single_app/foundry_agent_runtime.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
content=workflow_task,
metadata=getattr(message, "metadata", {}) or {},

Check warning on line 1289 in application/single_app/foundry_agent_runtime.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
))
return filtered_messages


def _build_foundry_workflow_input_text(
message_history: List[ChatMessageContent],
max_context_chars: Optional[int] = None,
Expand All @@ -1237,7 +1302,13 @@
if not text:
continue
if not include_document_context and _looks_like_document_context_message(text):
continue
workflow_task_marker = "[Workflow task]"
workflow_task_index = text.rfind(workflow_task_marker)
if workflow_task_index < 0:
continue
text = text[workflow_task_index + len(workflow_task_marker):].strip()
if not text:
continue
role_value = getattr(message, "role", "user")
role = str(role_value).strip().lower() or "user"
if role.startswith("authorrole."):
Expand Down Expand Up @@ -1800,6 +1871,8 @@
foundry_settings: Dict[str, Any],
metadata: Dict[str, Any],
) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
if not _coerce_bool(foundry_settings.get("include_document_context"), True):
return [], []
if not _coerce_bool(foundry_settings.get("include_file_inputs"), True):
return [], []

Expand Down
Loading
Loading