Host fibey agent in Foundry; load skills via toolbox MCP#2
Open
lindazqli wants to merge 1 commit into
Open
Conversation
- Add MCPSkillsSource adapter that loads skills published by the Foundry
Toolbox (SEP-2640 skills extension) as InlineSkill instances usable by
the existing SkillsProvider, no framework changes required.
- agent.py: prefer MCP-published skills when TOOLBOX_MCP_URL is set, with
graceful fallback to FileSkillsSource via SKILLS_SOURCE env var.
- hosted.py: rewrite to follow the foundry-samples 04-foundry-toolbox
pattern. Resolves the toolbox MCP URL from FOUNDRY_PROJECT_ENDPOINT +
TOOLBOX_NAME, pre-loads skills synchronously at startup, sets
default_options={store: False}, and enables OpenTelemetry instrumentation
so traces flow to the project Application Insights.
- _ResilientResponsesHostServer: override the correct parent method
(_handle_inner, not _handle_inner_agent) so the get_history fallback
actually runs.
- agent.yaml: switch from TOOLBOX_MCP_URL to TOOLBOX_NAME.
- Dockerfile.agent / azure.yaml: run hosted entrypoint as a module
(python -m fibey.agent.hosted) and set PYTHONPATH so package-relative
imports resolve.
- requirements.txt: require agent-framework[foundry] extras; without
them FoundryChatClient is unimportable and the container fails its
readiness probe.
- Gateway _run_hosted: fix [DONE] handling so the outer aiter_text loop
actually terminates (previously only the inner buffer loop broke,
leaving the upstream connection open after [DONE]).
- Add scripts/smoke_mcp_skills.py and scripts/probe_toolbox_resources.py
for local validation of the toolbox MCP skills path.
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.
Summary
This PR makes the fibey agent deployable as a Foundry hosted agent in the same project and consolidates the agent's skills behind the Foundry Toolbox so they are served via MCP resources (SEP-2640 skills extension) instead of being bundled into each deployable.
It also fixes a real streaming-termination bug in the gateway's hosted proxy.
Changes
Hosted agent (Foundry-hosted entrypoint)
src/fibey/agent/hosted.pyrewritten to follow the foundry-samples 04-foundry-toolbox pattern.FOUNDRY_PROJECT_ENDPOINT+TOOLBOX_NAME(no hard-coded URL).MCPSkillsSource, so they are ready before the first request.default_options={"store": False}per the sample._ResilientResponsesHostServernow overrides the correct parent method (_handle_inner, not_handle_inner_agent); the previous override was dead code and thecontext.get_historyfallback never ran.configure_otel_providers(enable_sensitive_data=True)so traces flow to the project's Application Insights and show in the portal's Tracing tab.Dockerfile.agent: run as module (python -m fibey.agent.hosted) and setPYTHONPATH=/app/user_agent/srcso package-relative imports resolve.azure.yaml: matchingstartupCommand: python -m fibey.agent.hosted.agent.yaml: replaceTOOLBOX_MCP_URLwithTOOLBOX_NAME(URL is now resolved from the auto-injected project endpoint).requirements.txt: pinagent-framework[foundry]>=1.4.0. Without the[foundry]extra,from agent_framework.foundry import FoundryChatClientfails at import and the container never passes its readiness probe.MCP-published skills
src/fibey/agent/mcp_skills_source.pyimplementsSkillsSourceagainst any MCP server publishingskill://*/SKILL.mdresources. Tolerant of the toolbox's double-frontmatter quirk; works with bearer or API-key auth; sends theFoundry-Features: Toolboxes=V1Previewheader.src/fibey/agent/agent.py:_build_skills_provider: prefer MCP skills whenTOOLBOX_MCP_URLis set; fall back toFileSkillsSourceotherwise.SKILLS_SOURCE=mcp|file|autoto force.create_agentis nowasync(needed for MCP skill loading);run_agentawaits it.Gateway streaming fix
src/fibey/gateway/api_server.py_run_hosted: when the upstream Responses SSE stream emitsdata: [DONE], the previous code onlybreaked the inner buffer loop and kept awaiting more bytes on the outeraiter_text()loop — so the gateway never reached its ownyield _sse("done", "[DONE]")and the UI spinner hung. Added astream_doneflag that propagates the termination to the outer loop.logging.basicConfig(level=logging.INFO)so gateway INFO logs are visible during local dev.Tooling
scripts/smoke_mcp_skills.py— exercisesMCPSkillsSourceagainst the live toolbox.scripts/probe_toolbox_resources.py— lists raw MCP resources for debugging.Validation
AGENT_MODE=local): UI streams correctly; gateway logs show 5 skills loaded from the toolbox;load_skill→tool_search→call_toolchain completes and rendered output matches expectations (e.g. WO-007 briefing, OTDR stock lookup).fibey-project-westus2(version 3) viaazd deploy;azd ai agent invoke "Do we have OTDR test equipment in stock?"returns a fully formatted markdown response. App Insights confirmsInbound POST /responses completed with status 200for streaming requests.Notes for reviewers
403 insufficient_scopefor theAgent365.Observability.OtelWriteapp role — this is a workspace-level RBAC config (not in this PR's scope) and only affects whether GenAI spans show in the portal Tracing tab.