feat(agi): stream fix, persistence defaults, infra specialist, Aria wiring#462
Conversation
…iring - Materialize SSE generator bodies for azure-functions 1.x compatibility - Default AGI JSONL persistence and expose /api/agi/persistence without 404 - Add infrastructure-specialist agent and domain routing - Wire Aria command parser to accept agi/agi-reasoning provider aliases - Expand AGI smoke CI with stream and LM Studio routing coverage Co-authored-by: Bryan
|
@Bryan-Roe Thanks for sending me some feedback. Unfortunately, I hit an error while trying to use the custom Copilot setup steps configured for this repository. The error I am seeing is: Once you or someone with the necessary access fixes the problem, please let me know in a comment and I'll try again. Thanks! |
Reviewer's GuideAdds a shared SSE response helper compatible with azure-functions 1.x, introduces default JSONL persistence behavior and richer metadata for the AGI persistence endpoint, wires a new infrastructure-specialist agent and infrastructure domain routing, extends Aria to recognize AGI provider aliases and expose AGI support in health checks, and hardens CI/tests for AGI streaming and LM Studio routing. Flow diagram for shared SSE response helperflowchart LR
Client[[SSE_client]] --> Endpoint
subgraph FunctionApp
Endpoint["SSE endpoint
(e.g. agi_stream)"] --> SSEGen["_sse_iterable
/ blocked_sse
/ sse_iterable
/ _unavail
/ _sse_generator"]
SSEGen --> MakeResp["_make_sse_response"]
MakeResp --> Materialize["_materialize_sse_body"]
Materialize --> HttpResp["func.HttpResponse
body: bytes"]
end
HttpResp --> AzureRuntime[[azure_functions_1x]]
Flow diagram for infrastructure domain routing to infrastructure-specialist agentflowchart LR
UserQuery[[user_query]] --> Analyze
Analyze["AgiProvider._analyze_query"] --> DomainCheck
subgraph DomainDetection
DomainCheck -->|contains deploy/kubernetes/docker/...| InfraDomain["domain = infrastructure"]
DomainCheck -->|other keywords| OtherDomain["domain = quantum/aria/ai/technical/general"]
end
InfraDomain --> SelectAgent["select infrastructure-specialist agent config"]
SelectAgent --> ProviderAgi["provider = agi"]
Flow diagram for Aria AGI provider alias normalization and health payloadflowchart LR
CmdReq[[aria_command_request]] --> AliasInput
AliasInput["provider param
(e.g. agi-reasoning)"] --> Normalize
Normalize["_normalize_provider_alias"] --> ProviderAgi["normalized provider = agi"]
HealthReq[[health_check_request]] --> BuildHealth
BuildHealth["build_health_payload"] --> Fields
subgraph HealthPayload
Fields --> LlmAvailable["llm_available"]
Fields --> AgiSupported["agi_provider_supported"]
Fields --> SupportedProviders["supported_providers
includes agi"]
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
| "DEFAULT_AI_PROVIDER": "auto", | ||
| "# Aria web UI LLM provider (ollama|lmstudio|auto|local|azure) - set azure to match Azure OpenAI; falls back to DEFAULT_AI_PROVIDER": "", | ||
| "ARIA_LLM_PROVIDER": "" | ||
| "# Aria web UI LLM provider (ollama|lmstudio|auto|local|azure|agi) - set azure to match Azure OpenAI; falls back to DEFAULT_AI_PROVIDER": "", |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-generic-ai-oai.
You can view more details about this finding in the Semgrep AppSec Platform.
| "ollama", | ||
| "lmstudio", | ||
| "azure", | ||
| "openai", |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-generic-ai-oai.
You can view more details about this finding in the Semgrep AppSec Platform.
🟡 Coverage —
|
| Metric | Value |
|---|---|
| Total coverage | 65.4% |
▲ vs main |
+0.1% |
| Minimum threshold | 60% |
Updated on every push · 2026-06-21
There was a problem hiding this comment.
Pull request overview
This PR implements a batch of AGI follow-up items: it centralizes Server-Sent Events (SSE) response handling in function_app.py to work around azure-functions 1.x not accepting generator bodies, makes AGI JSONL persistence enabled-by-default with a stable path (and returns JSONL metadata instead of a 404 when unconfigured), adds an infrastructure-specialist agent with an infrastructure domain to the AGI router, and wires the agi/agi-reasoning provider aliases plus a supported_providers health field into the Aria server. It fits into the Functions integration layer and the AGI provider that powers /api/agi/* and Aria command parsing.
Changes:
- Add
_materialize_sse_body()/_make_sse_response()helpers and route all SSE endpoints through them; default AGI persistence todata_out/agi_reasoning.jsonland enable it by default. - Register
infrastructure-specialistagent and addinfrastructuredomain keyword detection in_analyze_query. - Expose
agiin the Aria health payload'ssupported_providersand acceptagi/agi-reasoningaliases; extend tests and theagi-smokeCI workflow.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
function_app.py |
Adds SSE materialization helpers, routes all stream endpoints through them, and reworks the persistence endpoint to default to JSONL metadata. |
ai-projects/chat-cli/src/agi_provider.py |
Adds infrastructure-specialist agent, infrastructure domain detection, and defaults QAI_AGI_PERSIST to enabled. |
apps/aria/server.py |
Adds agi_provider_supported/supported_providers to the health payload and agi/agi-reasoning alias mapping. |
local.settings.json.example |
Documents agi provider option and new QAI_AGI_PERSIST* defaults. |
.github/workflows/agi-smoke.yml |
Runs LM Studio routing and AGI stream sentinel tests in CI. |
tests/test_function_app_endpoints.py |
Simplifies the stream test to read the materialized response body directly. |
tests/test_agi_smoke.py |
Adds a test for _materialize_sse_body joining generator chunks. |
tests/test_agi_provider.py |
Adds infrastructure domain detection and infrastructure-specialist routing tests. |
tests/test_agi_persistence_endpoint.py |
Adds a default-JSONL-path persistence test. |
tests/test_lmstudio_agi_integration.py |
Adds an LM Studio specialist routing test. |
tests/test_aria_server.py |
Adds AGI alias parsing and health-payload AGI-support tests. |
| path = jsonl_path or default_jsonl_path | ||
| if jsonl_path or jsonl_enabled or os.path.exists(path) or not sqlite_path: |
| }, | ||
| "infrastructure-specialist": { | ||
| "domains": ["infrastructure"], | ||
| "intents": ["explanation", "question", "coding", "creation", "debugging"], |
| "agi_provider_supported": bool(llm), | ||
| "supported_providers": [ | ||
| "auto", | ||
| "local", | ||
| "ollama", | ||
| "lmstudio", | ||
| "azure", | ||
| "openai", | ||
| "quantum", | ||
| "agi", | ||
| ], |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7fab62b8-ca50-4756-b1ad-dfa7c690aeb1) |
…dies Update TestPostValidation chat_stream tests to read SSE via resp.get_body() after _make_sse_response materializes generators. Fix yamllint bracket and comment spacing in agi-smoke.yml. Co-authored-by: Bryan <bryan@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_17a94df7-df51-435c-ba27-436da9d91ce6) |
- Add AGI mode toggle and SSE streaming in chat.js and index.html - Serve agi_stream_utils.js via /api/chat-web/static/agi_stream_utils.js - Add agi_analyze and agi_reason MCP tools with import-safe server boot - Fix devcontainer LM Studio URL test isolation and add MCP/endpoint tests Co-authored-by: Bryan <bryan@users.noreply.github.com>
| payload = run_agi_reason(query="hello agi") | ||
|
|
||
| assert payload["success"] is True | ||
| assert payload["response"] == "Reasoned AGI response" |
🔐 CodeQL — Open Alerts on this PR
Copilot Autofix suggestions (if enabled) appear as inline review comments on the affected lines. |
| max_tokens: int = DEFAULT_MAX_TOKENS, | ||
| timeout: float = 30.0, | ||
| ): | ||
| if httpx is None: |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
Found identical comparison using is. Ensure this is what you intended.
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by identical-is-comparison.
You can view more details about this finding in the Semgrep AppSec Platform.
|
|
||
| if (outputText) { | ||
| try { | ||
| contentDiv.innerHTML = (reasoningHtml ? reasoningHtml : '') + marked.parse(outputText); |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
User controlled data in a contentDiv.innerHTML is an anti-pattern that can lead to XSS vulnerabilities
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by insecure-innerhtml.
You can view more details about this finding in the Semgrep AppSec Platform.
| reasoningHtml += renderAgiDeltaHtml(delta); | ||
| } | ||
|
|
||
| contentDiv.innerHTML = reasoningHtml + '<div class="agi-final-output">' + outputText.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') + '</div>'; |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
User controlled data in a contentDiv.innerHTML is an anti-pattern that can lead to XSS vulnerabilities
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by insecure-innerhtml.
You can view more details about this finding in the Semgrep AppSec Platform.
|
|
||
| if (outputText) { | ||
| try { | ||
| contentDiv.innerHTML = (reasoningHtml ? reasoningHtml : '') + marked.parse(outputText); |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
User controlled data in methods like innerHTML, outerHTML or document.write is an anti-pattern that can lead to XSS vulnerabilities
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by insecure-document-method.
You can view more details about this finding in the Semgrep AppSec Platform.
| reasoningHtml += renderAgiDeltaHtml(delta); | ||
| } | ||
|
|
||
| contentDiv.innerHTML = reasoningHtml + '<div class="agi-final-output">' + outputText.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') + '</div>'; |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
User controlled data in methods like innerHTML, outerHTML or document.write is an anti-pattern that can lead to XSS vulnerabilities
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by insecure-document-method.
You can view more details about this finding in the Semgrep AppSec Platform.
|
Semgrep found 1
Detected the use of an inner/outerHTML assignment. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. If you have to use a dangerous web API, consider using a sanitization library such as DOMPurify to sanitize the HTML before it is assigned. |
- Set ARIA_EMBEDDED=true and null-safe optional controls in chat.js - Add agi_stream_utils route to http_chat_web and expand ai/routes lists - Extend integration_smoke AGI probes, static asset check, and schema tests - Broaden agi-smoke.yml coverage with MCP tools and 30s timeout Co-authored-by: Bryan <bryan@users.noreply.github.com>
Keep branch total_steps schema fix and main results key check. Co-authored-by: Bryan <bryan@users.noreply.github.com>
Co-authored-by: Bryan <bryan@users.noreply.github.com>
| @@ -66,7 +67,7 @@ jobs: | |||
| exit 1 | |||
| fi | |||
| } | |||
|
|
|||
| validate_threshold "${{ inputs.fitness_threshold }}" "fitness_threshold" | |||
| validate_threshold "${{ inputs.stability_threshold }}" "stability_threshold" | |||
| echo "✓ All inputs validated successfully" | |||
There was a problem hiding this comment.
Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. github context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with env: to store the data and use the environment variable in the run: script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".
🎈 Fixed in commit d62288e 🎈
There was a problem hiding this comment.
Stale comment
Not approving: Cursor Bugbot is still pending after the 8-minute polling window and no Bugbot review comment (
<!-- BUGBOT_REVIEW -->) was posted, so the required automated review signal is missing. Human review is needed before merge; no reviewers were assigned because Bryan-Roe is the sole code owner and PR author.Sent by Cursor Approval Agent: Pull Request Approver
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_23e26b73-bca2-402b-be1a-cd07a6ce27ec) |
…icts Take main's local_dev_adapter CI path and _sse_response helpers while keeping PR AGI persistence defaults and strict-mode endpoint gating. Co-authored-by: Bryan <bryan@users.noreply.github.com>
There was a problem hiding this comment.
Not approving: Cursor Bugbot is still pending after the 8-minute polling window and no Bugbot review comment (<!-- BUGBOT_REVIEW -->) was posted for the current head, so the required automated review signal is missing. Human review is needed before merge; no reviewers were assigned because Bryan-Roe is the sole code owner and PR author.
Sent by Cursor Approval Agent: Pull Request Approver
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_f7a6b6a6-d8c8-4afb-a8d1-543b74953360) |
- Add _materialize_sse_body alias for _sse_body_bytes - Use resp.get_body() in SSE stream endpoint tests - Pin LMSTUDIO_MODEL in provider detection test - Use hmac.compare_digest for AGI persistence token check - Fix MD060 compact table formatting in docs Co-authored-by: Bryan <bryan@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_d495a275-1693-4828-9c2d-3cbe301b295d) |
- Use libasound2t64 on Ubuntu 24.04 for Pyppeteer Chromium deps - Bind Aria server to 0.0.0.0 and point remote Chrome at host.docker.internal - Grant workflows: write to CodeQL autofix job for workflow YAML pushes Co-authored-by: Bryan <bryan@users.noreply.github.com>
- Keep set -e-safe retry increment in contract gate loop - Keep resp.get_body() SSE assertions from PR branch (drop unused capture helper) - Align quantum integration test job name with main (smoke) Co-authored-by: Bryan <bryan@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_49faea2e-5389-4ee0-b343-9a6ab346b83a) |
Signed-off-by: Bryan <74067792+Bryan-Roe@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_27a154f4-e9f7-44f5-a937-2928cc297d5a) |


Summary
Implements all six AGI follow-up items from the orientation plan: SSE stream compatibility, persistence defaults, LM Studio routing verification, a new infrastructure specialist agent, CI hardening, and Aria provider wiring.
Changes
_materialize_sse_body()/_make_sse_response()infunction_app.pyso/api/agi/stream(and other SSE routes) work with azure-functions 1.x, which only acceptsstr/bytesbodies.data_out/agi_reasoning.jsonl; enable writes whenQAI_AGI_PERSISTdefaults totrue;/api/agi/persistencereturns JSONL metadata instead of 404 when unconfigured.tests/test_lmstudio_agi_integration.py.infrastructure-specialistwith domain detection for deploy/CI/CD/DevOps queries.agi-smoke.ymlwith stream materialization and LM Studio routing tests.agi/agi-reasoningprovider aliases in/api/aria/command; exposeagiin health payloadsupported_providers.Verification
pytest tests/test_agi_smoke.py tests/test_agi_provider.py tests/test_agi_persistence_endpoint.py tests/test_agi_persistence_auth.py tests/test_lmstudio_agi_integration.py tests/test_function_app_endpoints.py::TestAgiEndpoints tests/test_aria_server.py::test_parse_accepts_agi_provider_alias tests/test_aria_server.py::test_health_payload_includes_agi_provider_support -q→ 122 passedPOST /api/agi/streamreturns SSEevent: meta+data: {"delta": ...}+[DONE]GET /api/agi/persistence?limit=3returnsbackend: jsonlwith entriesSummary by Sourcery
Ensure AGI streaming, persistence, routing, and Aria integration behave consistently across environments and providers.
New Features:
Enhancements:
CI:
Tests: