feat(examples): GitHub Copilot CLI agent (github-copilot-sdk==0.2.2)#492
Draft
elefthei wants to merge 3 commits intoAgent-Field:mainfrom
Draft
feat(examples): GitHub Copilot CLI agent (github-copilot-sdk==0.2.2)#492elefthei wants to merge 3 commits intoAgent-Field:mainfrom
elefthei wants to merge 3 commits intoAgent-Field:mainfrom
Conversation
Track A of copilot-cli-support plan.
New example at examples/python_agent_nodes/copilot_agent/ that exposes
GitHub Copilot CLI as a first-class AgentField node via the official
github-copilot-sdk (Public Preview). Four reasoners:
- ask — one-shot Q&A, no tools
- plan — step-by-step plan without executing, no tools
- review — inline diff (no tools) or file list (read-only allow-list)
- run_task — full agent mode, requires allow_tools=True opt-in;
allow_list beats deny_list
Structured output is a stable dict (af_session_id, copilot_session_id,
answer, transcript, tool_calls, usage, finished_reason, error) that
insulates callers from SDK preview churn.
Key design choices (post rubber-duck critique):
- Default config_dir=None: reuses the user's real ~/.copilot so that
skills placed by the new skillkit target, stored auth, and session
resume are all visible. Opt-in isolation via isolate=True or
AGENTFIELD_COPILOT_ISOLATE=1 uses a per-NODE (not per-run) sandbox,
keeping concurrent reasoner calls on the same node coherent.
- AF session id ↔ Copilot session id map kept in session-scoped memory
under 'copilot_session_id', never reused directly.
- Deny-by-default permission handler for every reasoner except run_task
when the caller explicitly opts in.
- Event discrimination via SessionEventType enum, never via isinstance
on event.data — the Data dataclass is a union in v0.2.2 and subclass
names are not exported.
- Auth forwarded from COPILOT_GITHUB_TOKEN / GH_TOKEN / GITHUB_TOKEN into
SubprocessConfig(github_token=...).
21 unit tests (mocked CopilotClient, no Copilot subscription required in
CI) plus a tests/test_sdk_compat.py smoke test that fails loudly if the
preview SDK drifts.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Lef Ioannidis seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
Tidies six small warts surfaced during self-review. No behaviour change; all 21 unit tests still pass. - pyproject.toml: drop unused pydantic>=2.0 dependency - copilot_session.py: rename _deny_all_handler -> deny_all_handler so it can be imported without crossing the leading-underscore boundary; lift the nonlocal error_msg declaration out of the SESSION_ERROR branch to the top of _on_event and drop the incorrect noqa: PLW0603 (PLW0603 is the code for global-statement, not nonlocal); default final_event = None before the try block so the post-session read is well-typed even on an early error path - reasoners.py: update import + call sites for the public handler name - tests/test_copilot_session.py: drop unused monkeypatch fixture in test_ask_happy_path; follow handler rename - README.md: rewrite See-also to reference PR Agent-Field#491 rather than paths that only exist on the skillkit branch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5 tasks
Co-authored-by: Copilot <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.
Summary
Ships GitHub Copilot CLI as a first-class AgentField reasoner node, backed by the official
github-copilot-sdk==0.2.2(Public Preview). Other agents on the field can call Copilot the same way they call any other AgentField reasoner — no subprocess parsing, no bespoke protocol, full access to Copilot's event model and permission hooks.Track A of the two-PR Copilot integration (Track B is #491, the skillkit target + doctor probes — independent of this PR).
Lives entirely under
examples/python_agent_nodes/copilot_agent/:copilot_session.py— thin wrapper that returns a stableCopilotRunResultdict from a single Copilot turn. Event discrimination viaSessionEventType(stable enum), neverisinstanceonevent.data— subclass names likeAssistantMessageDatadon't exist in the PyPI build even though the repo samples reference them.reasoners.py— four reasoners,ask/plan/review/run_task. Deny-by-default permission posture;run_taskrequiresallow_tools=Trueand takes precedence-orderedallow_list/deny_list. Permission handler rejects withPermissionRequestResult(kind="denied", ...).copilot_session_idkey). Different AF sessions always get independent Copilot sessions;continue_session=Truereuses the mapping.COPILOT_GITHUB_TOKEN→GH_TOKEN→GITHUB_TOKEN→ falls back tocopilot --loginuser. Token never leaves the process env.~/.copilot/so skills installed byaf skill installand auth fromcopilot --loginare visible.AGENTFIELD_COPILOT_ISOLATE=1(orisolate=True) switches to a per-node sandbox under$AGENTFIELD_HOME/copilot-home/<node_id>.tests/test_sdk_compat.pyimports every SDK symbol the example uses and fails loudly if the preview SDK drifts.No changes outside
examples/python_agent_nodes/copilot_agent/andCHANGELOG.md; no new core deps.Testing
./scripts/test-all.sh— N/A (no change tocontrol-plane/,sdk/go/, orsdk/python/; the script does not traverseexamples/).pytest tests/in the example — 21 passed (0 skipped, 0 xfail) against the stubbedCopilotClientinconftest.py. No live Copilot subscription required.tests/test_sdk_compat.pyassertsCopilotClient.create_sessionsignature,CopilotSession.send_and_waitshape,PermissionHandler.approve_all, and everySessionEventTypeenum value we rely on.python -m py_compileclean oncopilot_session.py,reasoners.py,main.py.ghp_*PATs are rejected by the backend).Checklist
README.mdcovers quickstart, auth, isolation, cross-agent calls, and links to feat(skillkit,doctor): GitHub Copilot CLI target + doctor probes #491 for the skillkit half.)tests/.)CHANGELOG.md— new[Unreleased]entry under### Added.Screenshots (if UI-related)
Not UI-related.
Related issues
Pairs with #491 (Copilot skillkit + doctor probes, independent — merge in either order). Installing #491 makes
af skill installflow into~/.copilot/skills/, visible to the session created by this example out of the box.