Skip to content

Host-managed next-prompt suggestions for CLI extensions #2565

Description

@anujb-msft

Summary

Propose an opt-in, host-managed API that lets a CLI extension supply ranked
next-prompt suggestions while the CLI retains ownership of the input buffer,
ghost-text rendering, and Tab acceptance.

This is a request for API/design alignment before implementation, following the
contribution guidance.
The names below are illustrative, not methods available in the current SDK.

Use case and existing prototype

github/copilot-cli#4746 contains a
working, separately installed next-action extension prototype. It uses the
existing foreground session and a no-tools session.rpc.ui.ephemeralQuery to infer
follow-up prompts. It supports an interactive review flow and a non-modal autopilot
list/preview/run flow, but cannot offer native prompt-input suggestions.

The existing session.rpc.completions.getTriggerCharacters() and
session.rpc.completions.request({ text, offset }) APIs consume host-driven completions; they
do not expose registration of a local extension suggestion source. A batch API
would let this use case work without exposing every draft edit or keystroke to an
extension.

UX reference: Claude Code

Claude Code documents a similar built-in capability in its official
Prompt suggestions reference.
After a response, it can suggest a follow-up prompt based on the conversation.
Tab or Right Arrow places the suggestion in the input for editing; Enter submits
the accepted prompt, and typing dismisses the suggestion. The documentation also
describes background generation that reuses the conversation's prompt cache.

That is the reference interaction here: native suggestions that accelerate the
next user-directed step, not automatic execution. This proposal does not assume
the same inference implementation, provider, or billing behavior.

Proposed minimal SDK surface

const source = await session.ui.registerPromptSuggestionSource({
  id: "next-action",
  title: "Next action",
});

await source.setSuggestions({
  contextRevision: batch.contextRevision,
  items: [
    {
      id: "review",
      label: "Review the changes",
      prompt: "Review the current diff for correctness.",
    },
  ],
});

// At the corresponding lifecycle boundaries:
await source.clear();
await source.dispose();
  • Registration is owned by the extension connection and scoped to its session.
    It follows user and enterprise opt-in and exposes enabled-state changes so
    providers can avoid unnecessary background generation.
  • A capability such as session.capabilities.ui.promptSuggestions distinguishes
    an unsupported host from a supported but disabled source.
  • setSuggestions atomically replaces the source's bounded batch. It returns an
    explicit accepted, stale-context, or disabled outcome; acceptance of a batch
    does not mean it is currently visible.
  • clear, disposal, or disconnection removes that source's suggestions.
  • A host-owned contextRevision is exposed on session snapshots and transient
    query results, identifying the context actually used for inference. Publishing
    a batch for an obsolete revision is rejected.
  • Publishing suggestions does not invoke a model, modify a draft, submit a
    prompt, or grant tool permissions.

Native host contract

The CLI, rather than the extension, would:

  1. Validate and bound the candidate prompts, initially up to three ranked items.
  2. Select an exact-prefix match locally, including the highest-ranked candidate
    for eligible empty input. No model request or extension callback is needed
    for each keystroke.
  3. Show only the remaining suffix when the cursor is at the end, with no
    selection, active work, or conflicting modal/completion UI.
  4. Revalidate the context and input revisions on Tab, then append the suffix.
    Enter remains a separate action through the ordinary submission pipeline.
  5. Preserve command/path/mention completion priority and existing Tab behavior
    when no next-prompt suggestion is eligible.
  6. Invalidate obsolete suggestions when conversation, repository, model, policy,
    or relevant goal state changes. Draft contents remain in the host and are not
    included in feature telemetry.

This intentionally avoids arbitrary key interception or a general input-buffer
setter. A more general input-sensitive completion-provider API could be a
separate capability.

Implementation and usage boundaries

This requires both native CLI work and a negotiated SDK/wire contract; SDK method
declarations alone would not make Tab suggestions usable. The contract should be
consistent across supported SDK languages and capability-gated for other hosts.

The UI API can consume the prototype's existing cached inference results. Before
enabling automatic prefetch, individual query cancellation, output bounds, and
usage-limit enforcement also need explicit guarantees. A suggestion request must
never cancel the main agent turn or silently switch its model or permissions.

Related work and requested feedback

  • SDK #1219 requests completion
    and ghost text for extension command arguments. This proposal instead covers
    whole next-prompt suggestions and deliberately keeps matching inside the host.
  • CLI prototype PR #4746 supplies
    a concrete producer and review/acceptance flow, without claiming native Tab
    integration.

Feedback is requested on whether this narrow batch surface is the right
abstraction, the context-revision and enablement contract, and ownership/location
of the native CLI portion before implementation PRs are prepared.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions