-
Notifications
You must be signed in to change notification settings - Fork 1
LLM Streaming
Edge adaptation of the upstream model streaming and provider abstraction layer.
Upstream reference: LLM Streaming
The LLM subsystem (ctx.llm) provides the complete model interaction stack:
-
LlmRuntime — provider registration, model catalog, call preparation, retry policy, and the
llm/streamwaterfall that dispatches every request. -
Adapter contract — each provider implements
stream(), emitting a closed union ofStreamChunktypes (text-delta, reasoning-delta, tool-call-delta, usage, finish). Strict ordering: usage before finish, no chunks after termination. -
BlockAssembler — incrementally assembles raw chunks into complete
ContentBlockobjects and a frozen assistantMessage. - Model selection — three-level resolution: per-session log → deployment default → adapter default. Catalog is advisory — adapters accept unlisted model ids.
- Token accounting — disjoint counts: input, output, cache-read, cache-write, reasoning (informational only).
LlmRuntime is installed as-is. Streaming protocol, block assembly, retry policy, model discovery, and the llm/stream waterfall are entirely upstream code.
The upstream dsh-llm-deepseek adapter is installed as-is. It registers the deepseek-official provider, implements the streaming contract over the DeepSeek API, handles context-window overflow mapping, and provides model catalog and reasoning effort metadata. No Edge-specific adapter code.
Edge configures the adapter through Worker environment variables instead of upstream's CLI flags or config files:
| Environment Variable | Default | Purpose|
DEEPSEEK_API_KEY |
— | Provider authentication (BYOK) |
|---|---|---|
DEEPSEEK_BASE_URL |
https://api.deepseek.com |
API endpoint (custom deployments) |
| --- | --- | --- |
DEEPSEEK_MODEL |
deepseek-v4-flash |
Default model for new sessions |
| --- | --- | --- |
DEEPSEEK_MAX_OUTPUT_TOKENS |
256000 |
Output token cap per request |
| --- | --- | --- |
DEEPSEEK_REASONING_EFFORT |
high |
Thinking depth (off/low/high/max) |
| --- | --- | --- |
DEEPSEEK_STREAM_IDLE_TIMEOUT_MS |
120000 |
Max silence before stream abort |
All variables are validated at DO initialization (deepseek.ts). Invalid values throw immediately — no silent fallbacks.
EdgeModelSelectionBridge persists per-session model selections to DO KV (dsh-edge:session-model:{id}). Upstream stores selections in the local filesystem. The bridge provides an in-memory cache with async KV fallback, matching upstream's three-level resolution: session log → saved selection → deployment default.
DurableObjectUploadIndex + DeepSeekFileStore track image attachments uploaded to the DeepSeek API. Upstream uses a local filesystem index; Edge uses DO KV (dsh-edge:file-upload-index).
Edge supports two image upload backends, selected at first use based on whether an R2 binding is configured:
| Plan | Backend | Storage | Limit|
| Free (no R2) | temporary-do |
DO SQL table | 64 MB per workspace |
|---|---|---|---|
| Paid (R2 binding) | private-r2 |
Cloudflare R2 | Unlimited |
Both tiers accept the same image formats and sizes at upload. The difference is durability and capacity — DO storage is tied to the Durable Object's lifecycle, while R2 provides independent object storage.
- Streaming protocol (StreamChunk union, ordering invariants)
- Adapter contract (10 invariants, single-attempt-per-call)
- Block assembly and message freezing
- Retry policy (default: 5 retries, exponential backoff)
- Token accounting and billing calculation
- Model catalog and reasoning effort resolution
-
llm/streamwaterfall interception
The streaming path is: browser → Worker → DO → DeepSeek API → SSE chunks back through the same chain. Edge adds one network hop (Worker → DO) vs upstream's direct connection, but this is within Cloudflare's internal network (sub-millisecond). The dominant latency is the DeepSeek API's time-to-first-token (typically 500ms–2s depending on model and reasoning effort).
The stream idle timeout (DEEPSEEK_STREAM_IDLE_TIMEOUT_MS, default 120s) aborts the request if no chunks arrive within the window. This protects against hung API connections. The value is clamped to MAX_TIMER_DELAY_MS (2,147,483,647ms) — a V8 timer limit.
Edge uses a Bring Your Own Key model — the user provides their DeepSeek API key via DEEPSEEK_API_KEY env var or the credentials UI. No Edge-side token metering or billing. API costs are between the user and DeepSeek directly.
| Component | Category | Edge Code|
| LlmRuntime | One ctx.plugin() call |
|
|---|---|---|
| DeepSeek adapter | One ctx.plugin() call + config |
|
| --- | --- | --- |
| Env var configuration |
deepseek.ts (~80 lines) |
|
| --- | --- | --- |
| Model selection bridge |
model-selection-bridge.ts (~60 lines) |
|
| --- | --- | --- |
| Upload index |
do-upload-index.ts (~40 lines) |
Key observation: The LLM subsystem is the most critical upstream capability and requires zero business-logic adaptation. All Edge-owned code is configuration mapping (env vars → plugin config) and storage delegation (filesystem → DO KV). The streaming protocol, adapter, assembly, and retry logic are 100% upstream.
上游模型流式传输和提供者抽象层在 Edge 中的适配。
上游参考:LLM Streaming
LLM 子系统(ctx.llm)提供完整的模型交互栈:
-
LlmRuntime — 提供者注册、模型目录、调用准备、重试策略和分发每个请求的
llm/stream瀑布。 -
Adapter 契约 — 每个提供者实现
stream(),发出封闭联合的StreamChunk类型(text-delta、reasoning-delta、tool-call-delta、usage、finish)。严格排序:usage 在 finish 之前,终止后无 chunk。 -
BlockAssembler — 增量式将原始 chunk 组装为完整的
ContentBlock和冻结的 assistantMessage。 - 模型选择 — 三级解析:session 日志 → 部署默认 → 适配器默认。目录是建议性的——适配器接受未列出的模型 id。
- Token 计量 — 不重叠计数:input、output、cache-read、cache-write、reasoning(仅信息性)。
LlmRuntime 原封安装。流式协议、块组装、重试策略、模型发现和 llm/stream 瀑布完全是上游代码。
上游 dsh-llm-deepseek 适配器原封安装。注册 deepseek-official 提供者,基于 DeepSeek API 实现流式契约,处理上下文窗口溢出映射,提供模型目录和推理强度元数据。无 Edge 专属适配器代码。
Edge 通过 Worker 环境变量配置适配器,替代上游的 CLI 参数或配置文件:
| 环境变量 | 默认值 | 用途|
DEEPSEEK_API_KEY |
— | 提供者认证(BYOK) |
|---|---|---|
DEEPSEEK_BASE_URL |
https://api.deepseek.com |
API 端点(自定义部署) |
| --- | --- | --- |
DEEPSEEK_MODEL |
deepseek-v4-flash |
新 session 的默认模型 |
| --- | --- | --- |
DEEPSEEK_MAX_OUTPUT_TOKENS |
256000 |
每请求输出 token 上限 |
| --- | --- | --- |
DEEPSEEK_REASONING_EFFORT |
high |
思考深度(off/low/high/max) |
| --- | --- | --- |
DEEPSEEK_STREAM_IDLE_TIMEOUT_MS |
120000 |
流无数据时的最大等待 |
所有变量在 DO 初始化时验证(deepseek.ts)。无效值立即抛错——无静默降级。
EdgeModelSelectionBridge 将每 session 的模型选择持久化到 DO KV(dsh-edge:session-model:{id})。上游存在本地文件系统。该桥提供内存缓存 + 异步 KV 降级,匹配上游的三级解析:session 日志 → 保存的选择 → 部署默认。
DurableObjectUploadIndex + DeepSeekFileStore 追踪上传到 DeepSeek API 的图片附件。上游用本地文件系统索引;Edge 用 DO KV(dsh-edge:file-upload-index)。
Edge 支持两种图片上传后端,在首次使用时根据是否配置了 R2 binding 自动选择:
| 方案 | 后端 | 存储 | 限制|
| 免费(无 R2) | temporary-do |
DO SQL 表 | 每 workspace 64 MB |
|---|---|---|---|
| 付费(R2 binding) | private-r2 |
Cloudflare R2 | 无限制 |
两种方案在上传时接受相同的图片格式和大小。差异在于持久性和容量——DO 存储绑定于 Durable Object 的生命周期,R2 提供独立的对象存储。
- 流式协议(StreamChunk 联合、排序不变量)
- Adapter 契约(10 条不变量、单次尝试)
- 块组装和消息冻结
- 重试策略(默认:5 次重试、指数退避)
- Token 计量和计费计算
- 模型目录和推理强度解析
-
llm/stream瀑布拦截
流式路径:浏览器 → Worker → DO → DeepSeek API → SSE chunk 原路返回。Edge 比上游多一跳(Worker → DO),但在 Cloudflare 内部网络中(亚毫秒)。主导延迟是 DeepSeek API 的首 token 时间(通常 500ms–2s,取决于模型和推理强度)。
流空闲超时(DEEPSEEK_STREAM_IDLE_TIMEOUT_MS,默认 120s)在窗口内无 chunk 时中止请求。防御挂起的 API 连接。值上限为 MAX_TIMER_DELAY_MS(2,147,483,647ms)——V8 定时器限制。
Edge 使用自带密钥模式——用户通过 DEEPSEEK_API_KEY 环境变量或凭据 UI 提供 DeepSeek API 密钥。Edge 侧无 token 计量或计费。API 费用由用户直接与 DeepSeek 结算。
| 组件 | 分类 | Edge 代码|
| LlmRuntime | 一行 ctx.plugin() 调用 |
|
|---|---|---|
| DeepSeek 适配器 | 一行 ctx.plugin() 调用 + 配置 |
|
| --- | --- | --- |
| 环境变量配置 |
deepseek.ts(约 80 行) |
|
| --- | --- | --- |
| 模型选择桥 |
model-selection-bridge.ts(约 60 行) |
|
| --- | --- | --- |
| 上传索引 |
do-upload-index.ts(约 40 行) |
关键观察:LLM 子系统是最关键的上游能力,需要零业务逻辑适配。所有 Edge 代码都是配置映射(环境变量 → 插件配置)和存储委托(文件系统 → DO KV)。流式协议、适配器、组装和重试逻辑 100% 上游。
- Home
- Architecture
- Core & Scope
- Session & Persistence
- Model & Context
-
Execution & Tools
- Tools
- Bash
- Subprocess 🚫
- PTY Session 🚫
- Background Jobs 🚫
- Filesystem
- LSP Navigation 🚫
- Code Runtime 🚫
-
Web Access
⚠️ -
Skills
⚠️ - Workflow 🚫
- Subagent 🚫
-
Policy & Interaction
- Goal
- Approval 🚫
- Permission Presets 🚫
-
Sandbox
⚠️ - Plan Mode 🚫
- User Interaction 🚫
- Commands 🚫
- Schedule 🚫
- Message Feedback 🚫
- Platform & Access
- Development
- 首页
- 架构
- 核心与作用域
- 会话与持久化
- 模型与上下文
- 执行与工具
- 策略与交互
- 平台与接入
- 开发