Sycophant.WireProtocol.CopilotChat (sycophant v0.4.2)

Copy Markdown

Wire protocol adapter for GitHub Copilot's chat surface.

Copilot's /chat/completions endpoint is OpenAI-Chat-Completions-shaped but diverges in two important ways:

  • Copilot exposes assistant reasoning via non-standard reasoning_text and reasoning_opaque fields on the message (sync) and on stream deltas. These map to Sycophant.Reasoning.content (a single Content.Thinking block carrying the text) and :encrypted_content (the opaque blob). During streaming, reasoning fragments are surfaced as :reasoning_delta chunks. Reasoning content captured from the response is never echoed back on subsequent turns - the chat surface has no input channel for it.

  • Copilot's stream packs the final text content together with finish_reason: "stop" in the same SSE frame, where vanilla OpenAI sends them in separate frames. decode_stream_chunk/2 emits any chunks generated in the final delta before signalling :done, using the 3-tuple {:done, response, chunks} return shape.

Summary

Types

t()

@type t() :: %{
  optional(:stop) => [binary()],
  optional(:seed) => integer(),
  optional(:temperature) => float(),
  optional(:top_p) => float(),
  optional(:top_k) => integer(),
  optional(:max_tokens) => integer(),
  optional(:frequency_penalty) => float(),
  optional(:presence_penalty) => float(),
  optional(:parallel_tool_calls) => boolean(),
  optional(:tool_choice) => any(),
  optional(:reasoning_budget) => integer(),
  optional(:reasoning_effort) =>
    :none | :minimal | :low | :medium | :high | :xhigh,
  optional(:reasoning_summary) => :auto | :concise | :detailed | :none,
  optional(:service_tier) => binary()
}

Functions

param_schema()

Options:

  • :stop (list of String.t/0) - Stop sequences

  • :seed (integer/0) - Random seed for reproducible outputs

  • :temperature (float/0) - Sampling temperature

  • :top_p (float/0) - Nucleus sampling threshold

  • :top_k (integer/0) - Top-K sampling

  • :max_tokens (integer/0) - Maximum number of tokens to generate

  • :frequency_penalty (float/0) - Penalize repeated tokens

  • :presence_penalty (float/0) - Penalize tokens already present

  • :parallel_tool_calls (boolean/0) - Allow parallel tool calls

  • :tool_choice (term/0) - Tool selection strategy

  • :reasoning_budget (integer/0) - Explicit reasoning token budget

  • :reasoning_effort (:none | :minimal | :low | :medium | :high | :xhigh) - Extended thinking effort level

  • :reasoning_summary (:auto | :concise | :detailed | :none) - How to summarize reasoning

  • :service_tier (String.t/0) - Service tier selection