Conversation
Add a comprehensive guide covering the two message delivery modes available through the SDK: - Steering (immediate mode): inject messages into the current agent turn for real-time course correction - Queueing (enqueue mode): buffer messages for sequential processing after the current turn completes Includes code examples for all four SDK languages (Node.js, Python, Go, .NET), a sequence diagram, API reference, UI building patterns, and best practices. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
49a1acd to
1e8ae0a
Compare
Cross-SDK Consistency ReviewI've reviewed this PR for consistency across all four SDK implementations (Node.js, Python, Go, .NET). ✅ Code Changes: Fully ConsistentThe
All implementations properly follow their respective language conventions (naming, optionality, type safety) and include updated documentation with examples. The generated RPC files are also updated consistently across all SDKs.
|
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for issue #714
| }) | ||
| ``` | ||
|
|
||
| </details> |
There was a problem hiding this comment.
Cross-SDK consistency: The "Combining Steering and Queueing" section is missing Go and .NET examples. All other sections in this guide include all four SDK languages (Node.js, Python, Go, .NET).
For consistency with the rest of the guide, consider adding Go and .NET examples here similar to the pattern used in the "Steering" and "Queueing" sections above.
Suggested addition (after the Python example):
</details>
<details>
<summary><strong>Go</strong></summary>
```go
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (copilot.PermissionRequestResult, error) {
return copilot.PermissionRequestResult{Kind: copilot.PermissionRequestResultKindApproved}, nil
},
})
// Start a task
session.Send(ctx, copilot.MessageOptions{
Prompt: "Refactor the database layer",
})
// Steer the current work
session.Send(ctx, copilot.MessageOptions{
Prompt: "Make sure to keep backwards compatibility with the v1 API",
Mode: "immediate",
})
// Queue a follow-up for after this turn
session.Send(ctx, copilot.MessageOptions{
Prompt: "Now add migration scripts for the schema changes",
Mode: "enqueue",
})
```
</details>
<details>
<summary><strong>.NET</strong></summary>
```csharp
var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
OnPermissionRequest = (req, inv) =>
Task.FromResult(new PermissionRequestResult { Kind = PermissionRequestResultKind.Approved }),
});
// Start a task
await session.SendAsync(new MessageOptions
{
Prompt = "Refactor the database layer"
});
// Steer the current work
await session.SendAsync(new MessageOptions
{
Prompt = "Make sure to keep backwards compatibility with the v1 API",
Mode = "immediate"
});
// Queue a follow-up for after this turn
await session.SendAsync(new MessageOptions
{
Prompt = "Now add migration scripts for the schema changes",
Mode = "enqueue"
});
```
</details>There was a problem hiding this comment.
Pull request overview
This PR adds a new documentation guide describing message delivery modes (“steering” via mode: "immediate" and “queueing” via mode: "enqueue"), but it also includes multi-language SDK API/runtime surface changes (reasoning-effort support for session.model.switchTo, plus new session.log RPC bindings).
Changes:
- Add
docs/guides/steering-and-queueing.mdwith usage guidance and examples across Node/Python/Go/.NET. - Extend
setModel/set_model/SetModel/SetModelAsyncto support an optionalreasoningEffortparameter. - Add
session.logRPC types/bindings in generated RPC clients (Node/Python/Go).
Reviewed changes
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| python/copilot/session.py | Adds reasoning_effort option to set_model() and forwards it to RPC. |
| python/copilot/generated/rpc.py | Generated updates: ReasoningEffort enum, session.log params/result, and reasoningEffort on SessionModelSwitchToParams. |
| nodejs/test/client.test.ts | Adds a unit test asserting reasoningEffort is sent on session.model.switchTo. |
| nodejs/src/session.ts | Extends setModel to accept an options object with reasoningEffort. |
| nodejs/src/generated/rpc.ts | Generated updates: reasoningEffort field + session.log RPC. |
| go/session.go | Changes SetModel signature to accept options and forwards reasoning effort when provided. |
| go/rpc/generated_rpc.go | Generated updates: ReasoningEffort, Level, and session.log RPC. |
| go/internal/e2e/rpc_test.go | Updates skipped E2E test callsite for new SetModel signature. |
| dotnet/test/RpcTests.cs | Updates callsite for updated SwitchToAsync signature. |
| dotnet/src/Session.cs | Adds reasoningEffort optional parameter + overload to keep the previous SetModelAsync call pattern working. |
| dotnet/src/Generated/Rpc.cs | Generated updates: reasoning-effort enum + required parameter on SwitchToAsync. |
| docs/guides/steering-and-queueing.md | New guide documenting steering vs queueing, plus examples and decision guidance. |
Comments suppressed due to low confidence (2)
docs/guides/steering-and-queueing.md:362
- Python example in this section has the same issue as earlier:
on_permission_requestmust accept(request, invocation)and return aPermissionRequestResultinstance, not a dict. As written it will throwTypeError(wrong arity) orAttributeErrorwhen the SDK readsresult.kind.
session = await client.create_session({
"model": "gpt-4.1",
"on_permission_request": lambda req: {"kind": "approved"},
})
docs/guides/steering-and-queueing.md:239
- Python queueing example also uses
on_permission_request: lambda req: {"kind": "approved"}. The SDK calls the handler with two args(request, invocation)and expects aPermissionRequestResultobject (not a dict), so this snippet will fail when a permission prompt occurs.
session = await client.create_session({
"model": "gpt-4.1",
"on_permission_request": lambda req: {"kind": "approved"},
})
| session = await client.create_session({ | ||
| "model": "gpt-4.1", | ||
| "on_permission_request": lambda req: {"kind": "approved"}, | ||
| }) |
There was a problem hiding this comment.
Python example: on_permission_request is invoked with two arguments (request, invocation) and must return a PermissionRequestResult object. A one-arg lambda returning a dict will raise at runtime (the session code accesses result.kind, result.rules, etc.). Update the example to accept both args and return PermissionRequestResult(kind="approved") (or use PermissionHandler.approve_all).
This issue also appears in the following locations of the same file:
- line 359
- line 236
Fix all 3 Python snippets to use the correct signature:
- 2-arg lambda (req, inv) matching PermissionHandlerFn typedef
- Return PermissionRequestResult dataclass instead of plain dict
- Add 'from copilot.types import PermissionRequestResult' import
The previous pattern (lambda req: {"kind": "approved"}) would fail
at runtime: TypeError from wrong arg count, and AttributeError from
dict lacking .kind attribute access.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ides Same fix as the steering guide — use correct 2-arg signature and PermissionRequestResult dataclass return type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Adds a new guide at
docs/guides/steering-and-queueing.mddocumenting the two message delivery modes available through the SDK.What's Covered
Steering (
mode: "immediate")ImmediatePromptProcessorQueueing (
mode: "enqueue")itemQueueGuide Contents
<details>patternStyle
Follows the established guide format used by
custom-agents.mdandskills.md: