Make tool callbacks optional across SDKs#1308
Conversation
|
@SteveSandersonMS I'd appreciate your eyes on this one. |
There was a problem hiding this comment.
Pull request overview
Makes permission handlers and external-tool handlers optional across all five SDKs (Node, Python, Go, .NET, Rust). Previously, omitting these handlers caused errors; now requests are surfaced as events and left pending for the consumer to resolve via the new pending permission/tool RPCs. Adds an end-to-end "manual tool resume" sample for each SDK and updates docs/tests accordingly.
Changes:
- Drops "required" validation on
OnPermissionRequest/onPermissionRequest/on_permission_requestand makes the handler argument nullable; tool definitions also accept a missing handler so tools can be declaration-only. - Adds a new Rust
NoopHandler(replacingDenyAllHandleras the default), introducesHandlerResponse::NoResult, and routes external-tool requests/notifications without handlers to leave them pending. - Adds
samples/manual_tool_resume.*for all SDKs and converts the .NET samples todotnet run --filestyle (removingChat.csprojfrom the solution).
Show a summary per file
| File | Description |
|---|---|
| rust/src/types.rs | Doc updates and switch from DenyAllHandler to NoopHandler as the default in builder paths. |
| rust/src/session.rs | Default handler swapped to NoopHandler; new notification_tool_payload/direct_tool_result helpers handle NoResult for external tool calls. |
| rust/src/handler.rs | Adds HandlerResponse::NoResult and the new NoopHandler implementation with tests. |
| rust/README.md | Reformats tables and documents NoopHandler as the default. |
| rust/examples/manual_tool_resume.rs | New end-to-end example for manual permission/tool resume. |
| python/copilot/{client,session,tools,init}.py | Permission handler optional in create/resume; declaration-only tool support; Tool/ToolResult re-exported. |
| python/test_client.py, python/test_tools.py | Tests updated for optional handlers and declaration-only tools. |
| python/samples/manual_tool_resume.py, python/README.md | New sample and updated docs. |
| nodejs/src/{client,session,types}.ts | Removes required-handler checks, makes Tool.handler optional, only registers tools that have handlers. |
| nodejs/test/client.test.ts | Tests updated to use offline client/session for the new optional behavior. |
| nodejs/samples/manual-tool-resume.ts, nodejs/README.md | New sample and updated docs. |
| go/{client,session,types}.go | Removes required-handler validation; Tool.Handler documented as optional. |
| go/client_test.go | Renames/repurposes tests for optional handler behavior. |
| go/samples/manual_tool_resume/main.go, go/README.md | New sample and updated docs. |
| dotnet/src/{Client,Session,Types}.cs | Removes required-handler validation; Tools switched to ICollection<AIFunctionDeclaration>; only declarations exposing an AIFunction get auto-invoked. |
| dotnet/test/E2E/ClientE2ETests.cs | Tests updated to assert successful create/resume without permission handler. |
| dotnet/samples/{Chat.cs,ManualToolResume.cs}, Chat.csproj, GitHub.Copilot.SDK.slnx, dotnet/README.md | Switch samples to dotnet run --file; new manual-resume sample; remove Chat.csproj. |
Copilot's findings
- Files reviewed: 34/34 changed files
- Comments generated: 0
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Allow SDK consumers to provide declaration-only tools and manually resolve permission and tool requests when callbacks are omitted. Preserve automatic SDK handling when callbacks are supplied, and add manual resume samples across languages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use explicit pass bodies for define_tool overload declarations so code-quality checks do not flag no-op ellipsis statements. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assert create and resume sessions work without permission callbacks now that those callbacks are optional. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
309b7b9 to
79d9c47
Compare
Cross-SDK Consistency Review ✅This PR implements the optional permission handler and declaration-only tool features consistently across all five SDK implementations (Node.js/TypeScript, Python, Go, .NET, and Rust). Here's a summary of what was verified: Feature parity confirmed
Implementation consistencyOptional permission handler: All SDKs removed the validation that threw when Declaration-only tools: Each SDK made the
One behavioral note worth being aware ofThe Rust default handler change from Overall, the cross-SDK implementation is thorough and well-aligned. No additional changes needed for consistency.
|
Tools previously assumed SDK-managed callbacks were always available, which made it difficult for consumers to pause/resume work and manually resolve permission or external tool requests from events. This PR makes callback-backed execution optional while preserving the existing automatic behavior whenever a callback or handler is supplied.
Summary
Notes
The .NET samples are file-based apps using
dotnet run --file, so the existing chat sample and new manual resume sample can live side by side without project glob conflicts.Validation
dotnet build dotnet\GitHub.Copilot.SDK.slnx --nologodotnet build dotnet\samples\Chat.cs --nologodotnet build dotnet\samples\ManualToolResume.cs --nologocd nodejs && npm run typecheck -- --pretty falsecd python && python -m py_compile samples\manual_tool_resume.pycd go\samples && go test ./...cd rust && cargo check --all-features --example manual_tool_resume