Add userPromptTransformed hook to all SDKs - #2254
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds the userPromptTransformed hook across all six SDKs, enabling inspection and replacement of model-facing prompts before persistence.
Changes:
- Adds typed hook APIs and dispatch.
- Adds shared E2E and serialization coverage.
- Adds cross-language hook documentation.
Show a summary per file
| File | Description |
|---|---|
test/snapshots/hooks_extended/should_invoke_userprompttransformed_hook_and_modify_transformed_prompt.yaml |
Adds shared replay fixture. |
rust/tests/e2e/hooks_extended.rs |
Adds Rust E2E coverage. |
rust/src/hooks.rs |
Implements the Rust hook API and dispatch. |
python/e2e/test_hooks_extended_e2e.py |
Adds Python E2E coverage. |
python/copilot/session.py |
Adds Python types and dispatch. |
python/copilot/__init__.py |
Exports Python hook types. |
nodejs/test/e2e/hooks_extended.e2e.test.ts |
Adds Node.js E2E coverage. |
nodejs/src/types.ts |
Defines Node.js hook types. |
nodejs/src/session.ts |
Dispatches the Node.js hook. |
nodejs/src/index.ts |
Exports Node.js hook types. |
java/src/test/java/com/github/copilot/SessionHandlerTest.java |
Tests Java dispatch. |
java/src/test/java/com/github/copilot/HooksTest.java |
Adds Java E2E coverage. |
java/src/main/java/com/github/copilot/rpc/UserPromptTransformedHookOutput.java |
Defines Java hook output. |
java/src/main/java/com/github/copilot/rpc/UserPromptTransformedHookInput.java |
Defines Java hook input. |
java/src/main/java/com/github/copilot/rpc/UserPromptTransformedHandler.java |
Defines Java handler API. |
java/src/main/java/com/github/copilot/rpc/SessionHooks.java |
Registers the Java handler. |
java/src/main/java/com/github/copilot/CopilotSession.java |
Dispatches the Java hook. |
go/types.go |
Defines Go hook types. |
go/types_test.go |
Tests empty replacement serialization. |
go/session.go |
Dispatches the Go hook. |
go/internal/e2e/hooks_extended_e2e_test.go |
Adds Go E2E coverage. |
go/client.go |
Registers Go hooks for create and resume. |
dotnet/test/E2E/HookLifecycleAndOutputE2ETests.cs |
Adds .NET E2E coverage. |
dotnet/src/Types.cs |
Defines .NET hook APIs. |
dotnet/src/Session.cs |
Dispatches and serializes the .NET hook. |
dotnet/src/Client.cs |
Registers .NET hooks for create and resume. |
docs/README.md |
Links the new hook guide. |
docs/hooks/user-prompt-transformed.md |
Documents the hook across languages. |
docs/hooks/README.md |
Adds the hook to the documentation index. |
docs/hooks/hooks-overview.md |
Adds the hook to the API overview. |
docs/features/hooks.md |
Updates lifecycle and reference documentation. |
Review details
Suppressed comments (4)
docs/hooks/user-prompt-transformed.md:39
- The docs validator extracts this Python block and type-checks it as a standalone file, where
clientandredactare undefined. Mark the conceptual snippet as skipped (or provide hidden validation scaffolding).
```python
docs/hooks/user-prompt-transformed.md:54
- This block is compiled standalone by docs validation, but it has no imports or declarations for
client,ctx, andredact, so validation fails. Mark the conceptual snippet as skipped (or provide hidden compilable scaffolding).
```go
docs/hooks/user-prompt-transformed.md:71
- Docs validation compiles this C# block independently;
clientandRedactare not declared, so the new article fails validation. Mark the conceptual snippet as skipped (or add hidden compilable scaffolding).
```csharp
docs/hooks/user-prompt-transformed.md:90
- The Java docs validator wraps and compiles this block, but no
redactmethod is defined. Mark the conceptual snippet as skipped (or add hidden compilable scaffolding) to keep docs validation passing.
```java
- Files reviewed: 31/31 changed files
- Comments generated: 7
- Review effort level: Balanced
…user-prompt-transformed-hook
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review details
Suppressed comments (2)
docs/hooks/user-prompt-transformed.md:108
- This tab defines
MyHooksbut never installs it on a session, so the documented callback will not run. Add session creation withwith_hooks(...)to cover the same registration flow shown by the other language tabs.
#[async_trait]
impl SessionHooks for MyHooks {
docs/hooks/user-prompt-transformed.md:98
- Unlike the other language tabs, this snippet only constructs a
SessionHooksvalue and never attaches it to a session, so copying it does not register the hook. Create the session with that hooks value so this tab demonstrates the same operation as the other examples.
This issue also appears on line 107 of the same file.
var hooks = new SessionHooks().setOnUserPromptTransformed((input, invocation) ->
CompletableFuture.completedFuture(
new UserPromptTransformedHookOutput(redact(input.transformedPrompt()))));
- Files reviewed: 32/32 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Review details
Suppressed comments (1)
go/internal/e2e/hooks_extended_e2e_test.go:84
- The hook callback is executed on a separate goroutine (
go/internal/jsonrpc2/jsonrpc2.go:450-472), but this new test appends to and later readsinputswithout synchronization. This can trigger a data race undergo test -race; protect both the callback write and the assertions with the mutex pattern used by the surrounding hook tests, or pass the input through a channel.
var inputs []copilot.UserPromptTransformedHookInput
session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
Hooks: &copilot.SessionHooks{
OnUserPromptTransformed: func(input copilot.UserPromptTransformedHookInput, invocation copilot.HookInvocation) (*copilot.UserPromptTransformedHookOutput, error) {
inputs = append(inputs, input)
- Files reviewed: 32/32 changed files
- Comments generated: 0 new
- Review effort level: Balanced
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency Review ✅This PR adds the
The API surface is consistent across all languages:
No cross-SDK consistency issues found. 🎉
|
* Add user prompt transformed hook to all SDKs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address user prompt hook review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Complete hook registration examples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Synchronize transformed hook test inputs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
userPromptTransformedhook APIs and dispatch across Node.js, Python, Go, .NET, Java, and RustImplements SDK support for github/copilot-agent-runtime#12791. Supersedes the older Node-only approach in #1774 with the shipped hook contract.