Skip to content

docs: add steering and queueing guide#714

Merged
patniko merged 3 commits intomainfrom
steering-and-queueing-guide
Mar 8, 2026
Merged

docs: add steering and queueing guide#714
patniko merged 3 commits intomainfrom
steering-and-queueing-guide

Conversation

@patniko
Copy link
Contributor

@patniko patniko commented Mar 8, 2026

Summary

Adds a new guide at docs/guides/steering-and-queueing.md documenting the two message delivery modes available through the SDK.

What's Covered

Steering (mode: "immediate")

  • Injects a message into the agent's current LLM turn for real-time course correction
  • Powered by the runtime's ImmediatePromptProcessor
  • Use case: redirecting the agent mid-turn ("actually, use JWT instead of sessions")

Queueing (mode: "enqueue")

  • Buffers messages for sequential processing after the current turn completes
  • FIFO ordering via the runtime's itemQueue
  • Use case: chaining follow-up tasks without disrupting current work

Guide Contents

  • Overview with a mermaid sequence diagram showing the interaction flow
  • Code examples for all four SDK languages (Node.js, Python, Go, .NET) using the existing collapsible <details> pattern
  • Internal behavior sections explaining how each mode works under the hood
  • Combined usage showing steering + queueing in the same session
  • Decision table for choosing between modes
  • UI building pattern for applications implementing both modes
  • API reference table with type signatures per language
  • Best practices for when to use each pattern

Style

Follows the established guide format used by custom-agents.md and skills.md:

  • Collapsible language tabs with Node.js open by default
  • Configuration reference tables
  • See Also cross-links to related guides

@patniko patniko requested a review from a team as a code owner March 8, 2026 06:00
Copilot AI review requested due to automatic review settings March 8, 2026 06:00
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>
@patniko patniko force-pushed the steering-and-queueing-guide branch from 49a1acd to 1e8ae0a Compare March 8, 2026 06:02
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

Cross-SDK Consistency Review

I've reviewed this PR for consistency across all four SDK implementations (Node.js, Python, Go, .NET).

✅ Code Changes: Fully Consistent

The setModel() / SetModel() / set_model() method updates are consistently implemented across all SDKs:

  • Node.js: options?: { reasoningEffort?: "low" | "medium" | "high" | "xhigh" }
  • Python: *, reasoning_effort: str | None = None
  • Go: opts *SetModelOptions with ReasoningEffort field
  • .NET: SessionModelSwitchToRequestReasoningEffort? reasoningEffort = null

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.

⚠️ Documentation: Minor Inconsistency

Finding: The "Combining Steering and Queueing" section (lines 324-380) only includes Node.js and Python examples, but is missing Go and .NET examples.

All other sections in the guide properly include all four languages:

  • ✅ Steering (Immediate Mode) - Node.js, Python, Go, .NET
  • ✅ Queueing (Enqueue Mode) - Node.js, Python, Go, .NET
  • ❌ Combining Steering and Queueing - Node.js, Python only

Recommendation: Add Go and .NET examples to the "Combining" section to maintain the established pattern. I've left an inline comment with suggested code.


Overall: This PR does an excellent job maintaining cross-SDK consistency in the code implementation. The only gap is in the documentation examples, which should be straightforward to address.

Generated by SDK Consistency Review Agent for issue #714 ·

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #714

})
```

</details>
Copy link
Contributor

Choose a reason for hiding this comment

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

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>

Copy link
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

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.md with usage guidance and examples across Node/Python/Go/.NET.
  • Extend setModel / set_model / SetModel / SetModelAsync to support an optional reasoningEffort parameter.
  • Add session.log RPC 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_request must accept (request, invocation) and return a PermissionRequestResult instance, not a dict. As written it will throw TypeError (wrong arity) or AttributeError when the SDK reads result.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 a PermissionRequestResult object (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"},
    })

Comment on lines +78 to +81
session = await client.create_session({
"model": "gpt-4.1",
"on_permission_request": lambda req: {"kind": "approved"},
})
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

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

Copilot uses AI. Check for mistakes.
patniko and others added 2 commits March 7, 2026 22:11
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>
@patniko patniko merged commit 890b1a7 into main Mar 8, 2026
14 checks passed
@patniko patniko deleted the steering-and-queueing-guide branch March 8, 2026 06:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants