Skip to content

Replat azure-ai-agentserver-githubcopilot onto agentserver-core 2.0 + responses 1.0#46101

Open
jodeklotzms wants to merge 11 commits intomainfrom
feature/replat-core-2.0
Open

Replat azure-ai-agentserver-githubcopilot onto agentserver-core 2.0 + responses 1.0#46101
jodeklotzms wants to merge 11 commits intomainfrom
feature/replat-core-2.0

Conversation

@jodeklotzms
Copy link
Copy Markdown
Member

Summary

Re-platforms the azure-ai-agentserver-githubcopilot adapter onto the new agentserver packages:

  • azure-ai-agentserver-core 2.0 (AgentHost + Hypercorn)
  • azure-ai-agentserver-responses 1.0 (ResponseHandler + ResponseEventStream builders)

+282 lines, -1,484 lines (net -1,202 lines).

Why

  • Fixes SSE streaming truncation (ADO 5159118) — correct RAPI event ordering works natively on Hypercorn. The old workaround (emit completed before text_done) is removed.
  • Eliminates heartbeat hack — built-in sse_keep_alive_interval_seconds handles the thinking gap.
  • Eliminates 668 lines of manual event construction_copilot_response_converter.py and _copilot_request_converter.py deleted, replaced by ResponseEventStream builders.
  • FoundryCBAgent removed in core 2.0 — must migrate to AgentHost composition model.

What Changed

  • _copilot_adapter.py: Rewritten from class CopilotAdapter(FoundryCBAgent) to AgentHost + ResponseHandler + @responses.create_handler composition.
  • _copilot_response_converter.py: Deleted (355 lines) — replaced by ResponseEventStream builders.
  • _copilot_request_converter.py: Deleted (313 lines) — replaced by get_input_text() from responses package.
  • test_copilot_request_converter.py: Deleted — tests for deleted module.
  • pyproject.toml: Dependencies updated (core>=2.0.0a1, responses>=1.0.0a1, removed opentelemetry-exporter-otlp-proto-http).

What Stays the Same

  • Public API: GitHubCopilotAdapter.from_project(".").run() — unchanged.
  • All env vars: GITHUB_TOKEN, AZURE_AI_PROJECT_ENDPOINT, AZURE_AI_FOUNDRY_RESOURCE_URL, etc. — unchanged.
  • BYOK auth, model discovery, Tool ACL, skill/tool discovery, conversation history bootstrap — all preserved.
  • Standalone modules unchanged: _foundry_model_discovery.py, _model_cache.py, _tool_acl.py, _tool_discovery.py.

Test Plan

  • Deployed and tested on ADC as replat-pkg-v3 (NCUS)
  • Streaming works in Foundry Playground (correct RAPI event ordering, spinner stops)
  • Non-streaming works via fa invoke --remote
  • GitHub token auth validated
  • BYOK/Managed Identity auth (code path preserved, not tested on ADC)
  • Conversation history bootstrap on cold start
  • Multi-turn within same session

Dependencies

New base packages from Azure DevOps dev feed:

  • azure-ai-agentserver-core[tracing]==2.0.0a20260331006
  • azure-ai-agentserver-responses==1.0.0a20260331006

Feed: https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 3, 2026 05:08
@jodeklotzms jodeklotzms requested a review from code-vicar as a code owner April 3, 2026 05:08
@github-actions github-actions bot added the Hosted Agents sdk/agentserver/* label Apr 3, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Re-platforms azure-ai-agentserver-githubcopilot onto the new agentserver hosting + responses streaming model, removing the bespoke request/response converter layers in favor of ResponseEventStream builders and the new AgentHost/ResponseHandler composition approach.

Changes:

  • Rewrites _copilot_adapter.py to host via AgentHost + ResponseHandler and to stream via ResponseEventStream builders.
  • Removes the old _copilot_request_converter.py / _copilot_response_converter.py and their unit tests.
  • Updates packaging + integration test agent image to pull new prerelease dependencies and adjusts docs/changelog for the replat.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
sdk/agentserver/azure-ai-agentserver-githubcopilot/azure/ai/agentserver/githubcopilot/_copilot_adapter.py New hosting/streaming implementation using AgentHost + ResponseHandler + ResponseEventStream.
sdk/agentserver/azure-ai-agentserver-githubcopilot/azure/ai/agentserver/githubcopilot/init.py Docstring updated to reflect new composition model.
sdk/agentserver/azure-ai-agentserver-githubcopilot/azure/ai/agentserver/githubcopilot/_copilot_request_converter.py Deleted (request conversion/attachment materialization removed).
sdk/agentserver/azure-ai-agentserver-githubcopilot/azure/ai/agentserver/githubcopilot/_copilot_response_converter.py Deleted (manual RAPI event construction removed).
sdk/agentserver/azure-ai-agentserver-githubcopilot/tests/unit_tests/test_copilot_request_converter.py Deleted (unit tests for removed request converter).
sdk/agentserver/azure-ai-agentserver-githubcopilot/tests/integration/test_agent/Dockerfile Updated to install new prerelease agentserver deps from ADO feed and install package from local source.
sdk/agentserver/azure-ai-agentserver-githubcopilot/pyproject.toml Dependency set updated for new agentserver packages; removes explicit OTel exporter dependency.
sdk/agentserver/azure-ai-agentserver-githubcopilot/CHANGELOG.md Adds 1.0.0b2 (Unreleased) entry describing replat + behavior changes.
sdk/agentserver/azure-ai-agentserver-githubcopilot/.foundry-agent.json New file with environment-specific session/conversation IDs.

jodeklotzms added a commit that referenced this pull request Apr 3, 2026
- Fix duplicate kwargs bug: remove explicit skill_directories/tools from
  create_session() calls — already present in sdk_config via _session_config
- Bump version to 1.0.0b2 to match CHANGELOG
- Remove .foundry-agent.json (contained real session/conversation IDs)
- Close AsyncDefaultCredential in _load_conversation_history to prevent
  async transport/socket leak
- Restore attachment handling: _extract_input_with_attachments() extracts
  input_file and input_image items from RAPI requests and appends to prompt
- Observe cancellation_signal in event loop to stop early on client disconnect
- Drop [tracing] extra from test Dockerfile to match pyproject.toml deps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jodeklotzms and others added 8 commits April 3, 2026 14:29
Major architecture change: FoundryCBAgent (inheritance) → AgentHost +
ResponseHandler (composition). Hypercorn replaces uvicorn.

Fixes:
- SSE streaming truncation (correct RAPI event ordering works natively)
- Duplicate text in streaming (only emit ASSISTANT_MESSAGE_DELTA)
- Eliminates heartbeat hack (built-in SSE keepalive)

Deleted:
- _copilot_response_converter.py (355 lines) — replaced by ResponseEventStream builders
- _copilot_request_converter.py (313 lines) — replaced by get_input_text()
- Unit tests for deleted converter

Preserved:
- Public API: GitHubCopilotAdapter.from_project(".").run()
- All env vars unchanged
- BYOK auth, model discovery, Tool ACL, skill/tool discovery
- Conversation history bootstrap (now uses own AsyncOpenAI client)

Dependencies:
- azure-ai-agentserver-core>=2.0.0a1 (was >=1.0.0b14,<1.0.0b18)
- azure-ai-agentserver-responses>=1.0.0a1 (new)
- Removed opentelemetry-exporter-otlp-proto-http (tracing via core[tracing])

Validated on ADC as trove-replat-v4 with correct streaming.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ResponseHandler expects the create_handler to be an async generator
(with __anext__), not a coroutine. Fixed by using async for delegation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Azure DevOps feed is public — pip just needs --no-input to suppress
the interactive auth prompt in non-interactive builds (like ACR Tasks).
Removes wheel download/copy from deploy script and Dockerfile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Azure DevOps feed proxies github-copilot-sdk but requires auth for
upstream packages it hasn't cached. Fix: install base packages from
dev feed in a separate pip call, then install our package + deps from
PyPI only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix duplicate kwargs bug: remove explicit skill_directories/tools from
  create_session() calls — already present in sdk_config via _session_config
- Bump version to 1.0.0b2 to match CHANGELOG
- Remove .foundry-agent.json (contained real session/conversation IDs)
- Close AsyncDefaultCredential in _load_conversation_history to prevent
  async transport/socket leak
- Restore attachment handling: _extract_input_with_attachments() extracts
  input_file and input_image items from RAPI requests and appends to prompt
- Observe cancellation_signal in event loop to stop early on client disconnect
- Drop [tracing] extra from test Dockerfile to match pyproject.toml deps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…issing

The ResponseHandler context only populates conversation_id when the
request includes an explicit "conversation" field. Most callers (invoke
scripts, Playground) only send session_id. Without this fallback,
conversation_id is always None and the adapter creates a fresh Copilot
SDK session on every request, breaking multi-turn.

Also fixes Windows --no-logs in integration test deploy script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
conversation_id is only set when the request includes an explicit
"conversation" field. Most callers (invoke scripts, Playground) only
send session_id. The adapter now falls back to context.raw_body
["session_id"] and sets it on context.conversation_id so session
reuse and history bootstrap work transparently.

Also adds build tag canary for deployment verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ound

The Playground sends conversation identity via raw_body['conversation']['id']
(from Chat Completions API translation), not session_id. The fallback now
checks both session_id and conversation.id in the raw body.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jodeklotzms jodeklotzms force-pushed the feature/replat-core-2.0 branch from 9b73232 to 1b6103a Compare April 3, 2026 21:30
Covers input extraction with attachments, conversation_id fallback
(session_id and conversation.id from raw_body), session config
building, BYOK URL derivation, project endpoint resolution, and
skill directory discovery.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jodeklotzms and others added 2 commits April 3, 2026 15:09
@@ -1,16 +1,28 @@
FROM mcr.microsoft.com/mirror/docker/library/python:3.11-slim
FROM python:3.11-slim
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep this from the mcr registry? This will get flagged again for not being from an approved registry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Hosted Agents sdk/agentserver/*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants