Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Changelog

## 0.1.15 - 2026-08-02

### Added

- Added first-class DeepSeek V4 Flash and Pro support across Chat Completions,
beta prefix/strict tools, Responses, FIM, model listing, balance, and the
Anthropic-compatible Messages endpoint, with lazy streaming, normalized
reasoning/cache usage, current pricing, and live conformance coverage.

### Fixed

- Updated named Finch pool options for Req 0.7 so synchronous and streaming
requests no longer emit the deprecated `finch: name` warning.
- Updated the shared Ecto adapter to use `Repo.transact/1`, preserving its
existing result contract without invoking Ecto's deprecated transaction API.
- Synchronized shell timeout cleanup with stderr initialization so timed-out
host and session commands no longer emit missing-scratch-file warnings or
leave scratch directories and Port messages behind.
- Made record-manager key pagination deterministic when records share a
timestamp, matching the Postgres adapter's timestamp-and-ID ordering.
- Updated GPT-5.6 Terra and Luna pricing metadata to OpenAI's July 30 rates,
added current Batch/Flex/Fast multipliers, and documented Fast mode's
backward-compatible `priority` service-tier alias.

## 0.1.14 - 2026-07-20

### Added
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ prefixes when a model name is ambiguous.
| OpenAI | `openai:gpt-5.6-sol`, `openai:gpt-5.6-terra`, `openai:gpt-5.6-luna`, `openai:gpt-5.6`, `openai:gpt-5.5`, `openai:gpt-5.4`, `openai:gpt-5.4-mini`, `openai:gpt-4.1`, `openai:text-embedding-3-large`, `openai:text-embedding-3-small` |
| Anthropic | `anthropic:claude-opus-5`, `anthropic:claude-sonnet-5`, `anthropic:claude-opus-4-8`, `anthropic:claude-opus-4-7`, `anthropic:claude-opus-4-6`, `anthropic:claude-opus-4-5`, `anthropic:claude-sonnet-4-6`, `anthropic:claude-sonnet-4-5`, `anthropic:claude-haiku-4-5`, `anthropic:claude-fable-5`, `anthropic:claude-mythos-5` |
| Google Gemini | `google:gemini-3.6-flash`, `google:gemini-3.5-flash-lite`, `google:gemini-3.5-flash`, `google:gemini-3.1-pro-preview` |
| DeepSeek | `deepseek:deepseek-v4-flash`, `deepseek:deepseek-v4-pro` |
| Moonshot/Kimi | `moonshot:kimi-k3`, `moonshot:kimi-k2.7-code`, `moonshot:kimi-k2.7-code-highspeed`, `moonshot:kimi-k2.6`, `moonshot:kimi-k2.5` |
| xAI | `xai:grok-4.5`, `xai:grok-4.3`, `xai:grok-4.20-0309-reasoning`, `xai:grok-4.20-0309-non-reasoning`, `xai:grok-4.20-multi-agent-0309`, `xai:grok-build-0.1`, `xai:v1` embeddings |
| Z.ai | `zai:glm-5.2` |
Expand Down Expand Up @@ -154,6 +155,7 @@ config :beam_weaver,
openai: [api_key: System.fetch_env!("OPENAI_API_KEY")],
anthropic: [api_key: System.fetch_env!("ANTHROPIC_API_KEY")],
google: [api_key: System.fetch_env!("GOOGLE_API_KEY")],
deepseek: [api_key: System.fetch_env!("DEEPSEEK_API_KEY")],
xai: [api_key: System.fetch_env!("XAI_API_KEY")],
moonshot: [api_key: System.fetch_env!("MOONSHOT_API_KEY")],
zai: [api_key: System.fetch_env!("ZAI_API_KEY")]
Expand Down Expand Up @@ -287,6 +289,7 @@ Provider guides:
- [OpenAI](docs/partners/openai.md)
- [Anthropic](docs/partners/anthropic.md)
- [Google](docs/partners/google.md)
- [DeepSeek](docs/partners/deepseek.md)
- [Moonshot/Kimi](docs/partners/moonshot.md)
- [xAI](docs/partners/xai.md)
- [Z.ai](docs/partners/zai.md)
1 change: 1 addition & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Config
config :beam_weaver,
openai: [],
anthropic: [],
deepseek: [],
google: [],
xai: [],
zai: [],
Expand Down
18 changes: 16 additions & 2 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,27 @@ if config_env() != :test do
)
)

config :beam_weaver,
:deepseek,
Keyword.merge(
Application.get_env(:beam_weaver, :deepseek, []),
compact.(
api_key: non_blank.("DEEPSEEK_API_KEY"),
base_url: first_env.(["DEEPSEEK_BASE_URL", "DEEPSEEK_API_URL"]),
beta_base_url: first_env.(["DEEPSEEK_BETA_BASE_URL", "DEEPSEEK_BETA_API_URL"]),
anthropic_base_url: first_env.(["DEEPSEEK_ANTHROPIC_BASE_URL", "DEEPSEEK_ANTHROPIC_API_URL"])
)
)

provider_api_keys =
compact.(
openai: non_blank.("OPENAI_API_KEY"),
anthropic: non_blank.("ANTHROPIC_API_KEY"),
google: google_api_key,
xai: non_blank.("XAI_API_KEY"),
moonshot: non_blank.("MOONSHOT_API_KEY"),
zai: non_blank.("ZAI_API_KEY")
zai: non_blank.("ZAI_API_KEY"),
deepseek: non_blank.("DEEPSEEK_API_KEY")
)

sandbox_env = non_blank.("BEAM_WEAVER_DEEPAGENTS_SANDBOX")
Expand Down Expand Up @@ -143,5 +156,6 @@ config :beam_weaver, :examples,
"google" => examples_env.("GOOGLE_API_KEY") || examples_env.("GEMINI_API_KEY"),
"xai" => examples_env.("XAI_API_KEY"),
"moonshot" => examples_env.("MOONSHOT_API_KEY") || examples_env.("KIMI_API_KEY"),
"zai" => examples_env.("ZAI_API_KEY")
"zai" => examples_env.("ZAI_API_KEY"),
"deepseek" => examples_env.("DEEPSEEK_API_KEY")
}
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ history, and `stream_events/3`. Agents use the same graph runtime underneath.

| Capability | BeamWeaver surface |
| --- | --- |
| Standard model interface | `BeamWeaver.Core.ChatModel` plus provider adapters for OpenAI, Anthropic, Google, xAI, Z.ai, fake, and replay-backed tests. |
| Standard model interface | `BeamWeaver.Core.ChatModel` plus provider adapters for OpenAI, Anthropic, Google, DeepSeek, xAI, Z.ai, fake, and replay-backed tests. |
| Agent architecture | `use BeamWeaver.Agent` and `BeamWeaver.Agent.build/1` for graph-backed model/tool loops. |
| Low-level orchestration | `BeamWeaver.Graph` for deterministic, agentic, or hybrid workflows. |
| Durable execution | [Checkpoint-backed resumable graph execution](durable_execution.md). |
Expand Down Expand Up @@ -177,6 +177,7 @@ history, and `stream_events/3`. Agents use the same graph runtime underneath.
- [OpenAI](partners/openai.md)
- [Anthropic](partners/anthropic.md)
- [Google](partners/google.md)
- [DeepSeek](partners/deepseek.md)
- [Moonshot/Kimi](partners/moonshot.md)
- [xAI](partners/xai.md)
- [Z.ai](partners/zai.md)
Expand Down
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* [OpenAI](partners/openai.md)
* [Anthropic](partners/anthropic.md)
* [Google](partners/google.md)
* [DeepSeek](partners/deepseek.md)
* [Moonshot/Kimi](partners/moonshot.md)
* [xAI](partners/xai.md)
* [Z.ai](partners/zai.md)
Expand Down
9 changes: 6 additions & 3 deletions docs/event_streaming.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ also expose provider-specific `stream_events/3` lifecycle streams; use those
when you need the raw provider semantic lifecycle rather than the normalized
BeamWeaver event contract.

Standalone OpenAI, Anthropic, Google, xAI, and Z.ai model streams are lazy live
Standalone OpenAI, Anthropic, Google, DeepSeek, xAI, and Z.ai model streams are lazy live
enumerables when using the live transport. Provider chunks are parsed
incrementally as server-sent events arrive. In tests, fake or replay transports
can emit deterministic typed stream events from fixtures. If a lazy provider
stream fails before any model output is emitted, consumers see an
`%BeamWeaver.Stream.Events.Error{}` item when they enumerate the stream.
Raw provider lazy-stream helpers can also accept an `on_response` callback when
the caller needs transport status and headers without changing the lazy return
type.

{% hint style="info" %}
**Versionless Typed Events**
Expand Down Expand Up @@ -327,8 +330,8 @@ events in one pass for live UI updates, or reduce collected events into

## Reasoning Content

Reasoning output is provider-dependent. OpenAI, Anthropic, Google, xAI, and
Z.ai can surface reasoning as content blocks in `%Events.MessageChunk{}`
Reasoning output is provider-dependent. OpenAI, Anthropic, Google, DeepSeek,
xAI, and Z.ai can surface reasoning as content blocks in `%Events.MessageChunk{}`
events. Treat those chunk events as the live thinking stream; final assistant
messages and text projections should be considered answer/tool output, not the
primary place to read incremental reasoning.
Expand Down
31 changes: 26 additions & 5 deletions docs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ config :beam_weaver,
anthropic: [api_key: System.fetch_env!("ANTHROPIC_API_KEY")],
xai: [api_key: System.fetch_env!("XAI_API_KEY")],
google: [api_key: System.fetch_env!("GOOGLE_API_KEY")],
deepseek: [api_key: System.fetch_env!("DEEPSEEK_API_KEY")],
zai: [api_key: System.fetch_env!("ZAI_API_KEY")]
```

`BeamWeaver.Models.init_chat_model/2` accepts provider-prefixed identifiers.
Unprefixed `gpt-*` and `o*` names infer OpenAI. Unprefixed `claude-*` names infer
Anthropic. Unprefixed `grok-*` names infer xAI. Gemini and GLM models must use
the explicit `google:` and `zai:` prefixes.
Anthropic. Unprefixed `grok-*` names infer xAI. Gemini, DeepSeek, and GLM models
must use the explicit `google:`, `deepseek:`, and `zai:` prefixes.

```elixir
{:ok, model} =
Expand Down Expand Up @@ -68,6 +69,15 @@ Google:
)
```

DeepSeek:

```elixir
{:ok, model} =
BeamWeaver.Models.init_chat_model("deepseek:deepseek-v4-flash",
reasoning_effort: :low
)
```

Z.ai:

```elixir
Expand Down Expand Up @@ -113,6 +123,8 @@ Provider scope is intentionally narrow:
- `BeamWeaver.OpenAI.EmbeddingModel` for OpenAI embeddings
- `BeamWeaver.Anthropic.ChatModel` for Anthropic Messages API
- `BeamWeaver.Google.ChatModel` for Gemini Developer API
- `BeamWeaver.DeepSeek.ChatModel` for DeepSeek Chat Completions
- `BeamWeaver.DeepSeek.ResponsesModel` for DeepSeek Responses
- `BeamWeaver.Moonshot.ChatModel` for Moonshot/Kimi Chat Completions
- `BeamWeaver.XAI.ChatModel` for xAI Responses API
- `BeamWeaver.XAI.ChatCompletionsModel` for xAI Chat Completions
Expand All @@ -121,7 +133,9 @@ Provider scope is intentionally narrow:
- `BeamWeaver.Models.FakeChatModel` and `FakeEmbeddingModel` for tests

Checked-in model profiles cover common OpenAI, Anthropic, Google Gemini,
Moonshot/Kimi, xAI, and Z.ai families. Moonshot chat supports
DeepSeek, Moonshot/Kimi, xAI, and Z.ai families. DeepSeek requires explicit
`deepseek:deepseek-v4-flash` or `deepseek:deepseek-v4-pro`; Chat Completions is
the default and Responses is currently Flash-only. Moonshot chat supports
`moonshot:kimi-k3`, `moonshot:kimi-k2.7-code`,
`moonshot:kimi-k2.7-code-highspeed`, `moonshot:kimi-k2.6`, and
`moonshot:kimi-k2.5`. xAI chat defaults to
Expand Down Expand Up @@ -162,6 +176,7 @@ Recommended starting points:
| OpenAI GPT | `openai:gpt-5.6-sol`, `openai:gpt-5.6-terra`, `openai:gpt-5.6-luna`, `openai:gpt-5.4-mini` |
| Anthropic Claude | `anthropic:claude-opus-5`, `anthropic:claude-sonnet-5`, `anthropic:claude-sonnet-4-6`, `anthropic:claude-opus-*`, `anthropic:claude-haiku-*` |
| Google Gemini | `google:gemini-3.6-flash`, `google:gemini-3.5-flash-lite`, explicit `google:gemini-*` profiles |
| DeepSeek V4 | `deepseek:deepseek-v4-flash`, `deepseek:deepseek-v4-pro` |
| Moonshot/Kimi | `moonshot:kimi-k3`, `moonshot:kimi-k2.7-code`, `moonshot:kimi-k2.7-code-highspeed`, `moonshot:kimi-k2.6`, `moonshot:kimi-k2.5` |
| xAI Grok | `xai:grok-4.5`, `xai:grok-4.3`, `xai:grok-4.20-0309-reasoning` |
| Z.ai GLM | `zai:glm-5.2` |
Expand Down Expand Up @@ -680,6 +695,12 @@ BeamWeaver.Core.ChatModel.invoke(model, "Plan the migration.",
)
```

DeepSeek Chat uses the same `thinking` and `reasoning_effort` shapes. DeepSeek
Responses accepts `reasoning: %{effort: ...}` and is selected with
`api: :responses`. V4 thinking requests must omit Chat `tool_choice`; set
thinking to disabled before sending an explicit choice. Forced function/custom
choices in Responses require `reasoning: %{effort: "none"}`.

Reasoning output is surfaced as content blocks or stream events when the
underlying provider returns it.

Expand Down Expand Up @@ -707,7 +728,7 @@ Prompt caching is provider-specific:
controls for supported providers; Anthropic marks the static system prompt
with `cache_control`.
- Moonshot/Kimi supports `:prompt_cache_key`.
- Gemini and Z.ai cached-token usage is normalized when providers report it.
- Gemini, DeepSeek, and Z.ai cached-token usage is normalized when providers report it.
- Usage metadata preserves cache-read/cache-write/cache-creation token details when
providers return them.

Expand All @@ -717,7 +738,7 @@ See [Prompt Caching](prompt_caching.md) for provider-specific examples.
**Prompt Cache Scope**

Prompt caching is not portable across providers. OpenAI, xAI, Anthropic,
Gemini, Moonshot/Kimi, and Z.ai expose different request fields, cache markers,
Gemini, DeepSeek, Moonshot/Kimi, and Z.ai expose different request fields, cache markers,
and usage metadata. BeamWeaver keeps those controls at the provider boundary
instead of inventing a universal cache wrapper that would hide important
provider behavior.
Expand Down
2 changes: 2 additions & 0 deletions docs/partners.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ streaming.
| [OpenAI](partners/openai.md) | `BeamWeaver.OpenAI.*` | Yes | Yes | Yes | Yes | Function tools and Responses built-ins | JSON schema via Responses or Chat Completions | Text deltas, lifecycle events, reconstructed responses | Tokenizer/profile based |
| [Anthropic](partners/anthropic.md) | `BeamWeaver.Anthropic.*` | Yes | No | No | No | Custom tools and Anthropic server tools | Tool/schema strategy through model calls | Text deltas, typed events, reconstructed messages | Anthropic count-tokens endpoint |
| [Google](partners/google.md) | `BeamWeaver.Google.*` | Yes | No | No | No | Function declarations and Gemini built-ins | Gemini generation config schema | Text deltas, typed events, reconstructed messages | Gemini count-tokens endpoint |
| [DeepSeek](partners/deepseek.md) | `BeamWeaver.DeepSeek.*` | Yes | Yes | Flash only | No | Function tools, hosted web search, and Responses `apply_patch` | JSON object plus local validation in Chat; JSON Schema in Responses | Text/reasoning/tool deltas, named Responses events, reconstructed messages | Approximate fallback |
| [Moonshot/Kimi](partners/moonshot.md) | `BeamWeaver.Moonshot.*` | Yes | Yes | No | No | OpenAI-compatible functions, K3 required/dynamic tools, and legacy Kimi `$web_search` | JSON object/schema request options | Text/reasoning/tool-call deltas, choice- or response-level usage, typed events, reconstructed messages | Moonshot estimate-token endpoint |
| [xAI](partners/xai.md) | `BeamWeaver.XAI.*` | Yes | Yes | Yes | Yes | OpenAI-compatible function tools and xAI built-ins | JSON schema request options | Text deltas, typed events, reconstructed messages | Tokenizer/profile or approximate fallback |
| [Z.ai](partners/zai.md) | `BeamWeaver.ZAI.*` | Yes | Yes | No | No | OpenAI-compatible function tools | JSON object mode plus schema instructions and local validation | Text/reasoning/tool-call deltas, usage chunks, reconstructed messages | Approximate fallback |
Expand All @@ -35,6 +36,7 @@ output, stream useful events, and count enough tokens for context management.
| OpenAI GPT | `openai:gpt-5.6-sol`, `openai:gpt-5.6-terra`, `openai:gpt-5.6-luna`, `openai:gpt-5.4-mini`, explicit `BeamWeaver.OpenAI.*` structs | Strong default | Custom function tools, Responses built-ins, raw Responses tool-result turns | Provider-native Responses or Chat Completions schema; tool strategy fallback at agent layer | Text, reasoning, tool-call lifecycle, reconstructed streamed responses | Tokenizer/profile based with approximate fallback | GPT-5.6 adds 1.05M context, `max` effort, pro mode, and persisted reasoning; hosted multi-agent/programmatic tool calling are not yet wrapped. |
| Anthropic Claude | `anthropic:claude-opus-5`, `anthropic:claude-sonnet-5`, `anthropic:claude-fable-5`, `anthropic:claude-mythos-5`, `anthropic:claude-sonnet-4-6`, `anthropic:claude-opus-*`, `anthropic:claude-haiku-*` | Strong default | Custom tools plus Anthropic server tools through provider helpers | Anthropic output config plus BeamWeaver parsing/validation | Text, typed Anthropic stream envelopes, reconstructed messages | Anthropic count-tokens endpoint | Opus 5 defaults to adaptive thinking, supports the full effort ladder and server-side refusal fallback, and does not support web fetch; prompt caching and server tools are provider-specific. |
| Google Gemini | `google:gemini-3.6-flash`, `google:gemini-3.5-flash-lite`, other explicit `google:gemini-*` profiles | Supported | Function declarations and Gemini built-ins | Gemini generation config schema | Text, typed Gemini events, reconstructed messages | Gemini count-tokens endpoint | Gemini identifiers must use the `google:` prefix; 3.5 Flash Cyber is not a public Gemini API model. |
| DeepSeek V4 | `deepseek:deepseek-v4-flash`, `deepseek:deepseek-v4-pro` | Supported | Function tools; Flash Responses adds hosted web search and `apply_patch` | Chat JSON object plus local validation; Flash Responses JSON Schema | Text/reasoning/tool chunks, typed events, reconstructed messages | Approximate fallback | Explicit `deepseek:` prefix required. Responses is currently Flash-only; both models support Chat, beta prefix/FIM, and Anthropic compatibility. |
| Moonshot/Kimi | `moonshot:kimi-k3`, `moonshot:kimi-k2.7-code`, `moonshot:kimi-k2.7-code-highspeed`, `moonshot:kimi-k2.6`, `moonshot:kimi-k2.5` | Supported with Kimi constraints | OpenAI-compatible functions; K3 adds required choice and dynamic loading; legacy `$web_search` only where thinking can be disabled | JSON object/schema request options | Text, reasoning, tool-call chunks, usage chunks, reconstructed messages | Moonshot estimate-token endpoint | K3 has 1,048,576-token context/output limits, always reasons with `reasoning_effort: "max"`, and rejects K2 `thinking`; web search is currently being updated by Kimi. |
| xAI Grok | `xai:grok-4.5`, `xai:grok-4.3`, `xai:grok-4.20-0309-reasoning`, explicit `BeamWeaver.XAI.*` structs | Supported | OpenAI-compatible functions and xAI built-ins | JSON schema request options | Text, reasoning/citation metadata, typed events, reconstructed messages | Tokenizer/profile or approximate fallback | Useful for coding, agentic work, and Grok-specific reasoning/citation behavior; provider metadata is normalized. |
| Z.ai GLM | `zai:glm-5.2`, explicit `BeamWeaver.ZAI.ChatModel` structs | Supported | OpenAI-compatible functions with `tool_stream` for streamed arguments | JSON object mode plus BeamWeaver schema instructions and local validation | Text, reasoning, tool-call chunks, usage chunks, reconstructed messages | Approximate fallback | GLM identifiers must use `zai:`; only `glm-5.2` is enabled. Usage includes cached-input and reasoning-token details for cost metadata. |
Expand Down
Loading