Dsxir. LM. Sycophant
(dsxir v0.1.0)
Copy Markdown
Sycophant-backed implementation of the Dsxir.LM behaviour.
Config shape:
[model: "openai:gpt-4o-mini", api_key: nil | binary,
base_url: nil | binary, temperature: float, max_tokens: integer,
top_p: float, num_retries: integer]Unknown config keys pass through to Sycophant; Sycophant validates them against the resolved wire protocol's param schema.
Per-call opts override per-config opts via Keyword.merge/2. api_key and
base_url are lifted into credentials: %{...} for Sycophant. The :headers
config key is reserved for future use and intentionally ignored.
Streaming
The :stream opt is forwarded to Sycophant.generate_text/3 unchanged.
Sycophant invokes the 1-arity callback with %Sycophant.StreamChunk{} values
(:text_delta, :tool_call_delta, :reasoning_delta, :usage, :failed,
:incomplete, :cancelled, :done) as the response streams in; the final
assembled {:ok, text, usage} tuple is still returned by this callback so
Dsxir.Predictor.Predict can build its %Dsxir.Prediction{} normally.
Usage extraction
On a successful response, the %Sycophant.Usage{} struct is flattened into
the Dsxir.LM usage map. When Sycophant reports nil usage, the empty
usage map (tokens_in: nil, tokens_out: nil, cost: nil) is returned so
downstream telemetry can rely on the keys always being present.
Dsxir.LM usage key | Sycophant.Usage field |
|---|---|
:tokens_in | :input_tokens |
:tokens_out | :output_tokens |
:cost | :total_cost |
Error translation
Provider errors are translated into typed Dsxir.Errors.LM.* structs. A
%Sycophant.Error.Provider.BadRequest{status: 400} is classified against a
small set of regexes (case-insensitive) on its :body to detect upstream
context-window-exceeded responses:
~r/context length/i~r/maximum context/i~r/prompt is too long/i~r/too many tokens/i~r/exceeds.*token/i~r/request is too large/i
When any of those match the body, the error becomes a
Dsxir.Errors.LM.ContextWindow (with prompt_tokens/limit extracted when
the body carries them). All other BadRequest bodies stay as
Dsxir.Errors.LM.RequestFailed with status: 400.