dsh-edge 0.2.0 → 0.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +13 -10
- package/README.zh.md +13 -10
- package/THIRD_PARTY_NOTICES.md +447 -348
- package/dist/assets/{index-BNMwCG9c.css → index-C6eRlFa6.css} +1 -1
- package/dist/assets/{index-CA9Bpko5.js → index-ClqxG24t.js} +35 -35
- package/dist/index.html +3 -3
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +84 -55
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +10 -6
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +15 -6
- package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +782 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +188 -72
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +46 -13
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +1 -1
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +287 -128
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +46 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +26 -0
- package/package.json +25 -22
- package/scripts/cli.mjs +56 -1
- package/scripts/install.d.mts +31 -0
- package/scripts/install.mjs +304 -16
- package/scripts/legal-files.mjs +5 -1
- package/scripts/wrangler-config-core.mjs +28 -0
- package/scripts/wrangler-config.d.mts +1 -0
- package/worker/direct/index.js +1021 -991
- package/worker/isolated/index.js +677 -647
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# last confirmed-consistent state. Both languages carry equal authority.
|
|
3
3
|
# After editing either side, update both and re-record every pair with:
|
|
4
4
|
# pnpm run doc-pairs -- --write
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 50dc27b1d0be05e08f3ffce591a7e33257e1ac1c
|
|
6
|
+
README.zh.md: 698b8511580befa735b51f41a20cf3a51b35cf77
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ The checked-in Wrangler configuration exposes two deployment targets from the sa
|
|
|
10
10
|
|
|
11
11
|
The runtime runs persistent conversations through the upstream Cordis-composed `ReactLoopAgent`, `AgentRegistry`, `LlmRuntime`, `ToolRuntime`, `SystemPrompt`, `SessionStore`, and `SessionPersistence`. Edge code only binds a request-scoped DeepSeek adapter and maps one native DSH `bash` tool definition onto Cloudflare Computer. Durable Object SQLite implements the upstream persistence backend contract; `PersistenceCoordinator` still owns write-behind, revisions, resume preparation, and crash recovery. Model history is projected from canonical events rather than persisted separately.
|
|
12
12
|
|
|
13
|
-
The browser is the upstream Web shell and upstream client-plugin bundles. A build-time assembler derives the browser roster from the upstream base and Web bundle configs, injects the standard `window.__DSH_BOOT__` graph, and publishes the result as Cloudflare static assets. The Durable Object implements the supported upstream `ApiProxy` methods through the standard HTTP carrier and supplies the two upstream downlinks as hibernatable WebSockets. Edge excludes client plugins whose host domains are absent instead of forking their UI code; this includes session-log export until its server endpoint exists. A small Edge-owned login shell protects the upstream UI and protocol without changing either one. Optional local-host plugins remain unavailable.
|
|
13
|
+
The browser is the upstream Web shell and upstream client-plugin bundles. A build-time assembler derives the browser roster from the upstream base and Web bundle configs, injects the standard `window.__DSH_BOOT__` graph, and publishes the result as Cloudflare static assets. The Durable Object implements the supported upstream `ApiProxy` methods through the standard HTTP carrier and supplies the two upstream downlinks as hibernatable WebSockets. The upstream image composer, gallery, lightbox, attachment wire contract, and DeepSeek serializer are reused unchanged; the storage seam selects private R2 for new permanent deployments, bounded Durable Object storage for temporary deployments, and a one-time owner choice for pre-0.3 Workers. Edge excludes client plugins whose host domains are absent instead of forking their UI code; this includes session-log export until its server endpoint exists. A small Edge-owned login shell protects the upstream UI and protocol without changing either one. Optional local-host plugins remain unavailable.
|
|
14
14
|
|
|
15
15
|
## Run locally
|
|
16
16
|
|
|
@@ -93,13 +93,13 @@ This reference separates code that runs natively in Workers, code adapted at an
|
|
|
93
93
|
| Bash tool | Node subprocess, sandbox, terminal, and job services | Adapted at the native tool seam | Register an upstream `ToolDefinition`, but execute its body through the configured Computer workspace backend and just-bash. The default direct backend runs inside the owner Durable Object with hardened interpreter limits and no network command; adding a `LOADER` binding selects Computer's isolated Worker Shell backend. Native tool cancellation sends `SIGINT` through the Computer execution handle. Deployment configuration supplies an explicit default timeout and caller-selectable ceiling, while `timedOut` reports the deadline independently from exit and cancellation status. Native binaries, background processes, PTYs, and arbitrary Linux behavior are unavailable. |
|
|
94
94
|
| Workspace filesystem | Local filesystem services and host paths | Adapted | Store `/workspace` in the owner's SQLite-backed Durable Object VFS. |
|
|
95
95
|
| Session persistence | `SessionPersistence` service, `PersistenceCoordinator`, and local JSONL/SQLite backends | Native backend adaptation | Reuse the upstream service and coordinator ownership. Implement storage primitives over Durable Object SQL with the upstream header/event mapping. One Edge-only table retains empty session headers across transparent hibernation and is removed when canonical rows materialize; no Edge turn or message schema exists. Internal coordinator helpers validate the bounded replay loader and abandon a failed unmaterialized creation before disposal. |
|
|
96
|
-
| Settings and credentials | File-backed settings, launch environment, and credential services | Read-only edge projection | Resolve the Worker secret per operation; never persist or return the literal key. Blank secrets are unconfigured, while surrounding whitespace is removed before use. `credentials.describe` reports only whether `DEEPSEEK_API_KEY` is configured and that its read-only source is `worker-secret`. The built-in `dsh-edge` preset projects its effective release, shell/VFS, model, limits, credential state, prompt, and tools through the upstream read-only composition viewer. Writable settings and authenticated per-user secret storage remain open. |
|
|
96
|
+
| Settings and credentials | File-backed settings, launch environment, and credential services | Read-only edge projection | Resolve the Worker secret per operation; never persist or return the literal key. Blank secrets are unconfigured, while surrounding whitespace is removed before use. `credentials.describe` reports only whether `DEEPSEEK_API_KEY` is configured and that its read-only source is `worker-secret`. The built-in `dsh-edge` preset projects its effective release, shell/VFS, deployment-default model, runtime-derived upstream model catalog, per-session selection scope, limits, credential state, prompt, and tools through the upstream read-only composition viewer. Writable settings and authenticated per-user secret storage remain open. |
|
|
97
97
|
| Host boot and plugins | Node command line, Cordis profile loading, package resolution, and HMR | Explicit Edge composition | Keep the local boot profile out of Workerd. Build immutable client bundles ahead of deployment; exclude HMR and host domains that the Edge `ApiProxy` does not expose. |
|
|
98
98
|
| DSH transport | Typed HTTP RPC plus mux and host WebSocket downlinks | Reused with an Edge server implementation | Use the upstream fetch carrier for unary methods and preserve its envelopes, schemas, projections, lazy blank-session behavior, bounded content search, prompt and queue mutations, workspace mutations, queue snapshots, and event frames. Durable Object WebSocket hibernation owns both downlinks; mux reconnects replay pending live inbox state, while REST/SSE routes remain a diagnostic compatibility path. |
|
|
99
99
|
| Workspace registry | Storage-domain global state plus `WorkspaceRecord` rows | Native backend adaptation | Keep the upstream global and record value shapes, including manual session order and archive membership, but map their physical keys and atomic writes to Durable Object storage. Edge constrains the registry to the one native `/workspace` VFS; rename, delete, recreation, and session reordering retain the upstream RPC and Host-frame semantics. |
|
|
100
100
|
| Existing Web UI | Runtime-loaded shell and `dsh.client` plugin graph | Reused with generic composition fallbacks | Assemble the upstream shell and supported upstream client bundles as Worker assets. Shared slot-occupancy rules hide actions whose provider is absent; Cloudflare serves ordinary assets directly, while `/`, `/login`, and `/api/*` enter the Worker for owner access control. The assembled asset policy prevents every direct or SPA-fallback shell alias from being framed. |
|
|
101
101
|
| Other tools | Web Search, filesystem editor tools, MCP, skills, workflows, jobs, and subagents | Search ported; others not ported | Reuse upstream DeepSeek Web Search with its 30-second tool-call timeout. Add the remaining tools individually against Worker-compatible capabilities; do not advertise unavailable host behavior. |
|
|
102
|
-
| Attachments | Local attachment storage
|
|
102
|
+
| Attachments | Local attachment storage, upstream image references, composer, gallery, lightbox, and provider conversion | Adapted at the native storage seam | Reuse upstream `AttachmentStore`, admission, protocol, authorization, UI, and DeepSeek conversion unchanged. Store immutable PNG/JPEG bytes under their SHA-256 identities in private R2 for new permanent deployments or in a 64 MiB, 512 KiB-chunked DO backend for temporary deployments and owners who select it while upgrading a pre-attachment Worker; session events retain only upstream refs. The first backend is pinned per owner instance so claiming or upgrading cannot strand existing references. |
|
|
103
103
|
| Authentication and tenancy | Local trusted-user boundary | Single-owner adaptation | Require one high-entropy Worker secret, exchange it for a signed 30-day HttpOnly `SameSite=Strict` cookie, and route every accepted request to one fixed owner object. This intentionally provides no registration, user database, roles, or multi-tenant routing. |
|
|
104
104
|
|
|
105
105
|
The browser request path is:
|
|
@@ -109,12 +109,15 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
|
|
|
109
109
|
-> POST /api/session.create through the upstream HTTP carrier
|
|
110
110
|
-> host/workspace-changed + session/subscribed over Durable Object WebSockets
|
|
111
111
|
-> POST /api/session.prompt with the client rpcId
|
|
112
|
+
-> upstream image admission validates and stores immutable bytes in the selected R2 or DO backend
|
|
113
|
+
-> canonical session events retain upstream sha256 attachment refs only
|
|
112
114
|
-> AgentRegistry live lookup or resume
|
|
113
115
|
-> sessionPersistence.prepare through PersistenceCoordinator on cold resume
|
|
114
116
|
-> ReactLoopAgent.followup(queue) or ReactLoopAgent.steer(steer)
|
|
115
117
|
-> pre-step admission gate waits for the sessions.flush durability barrier
|
|
116
118
|
-> session/queue snapshots publish live and replay on mux reconnect
|
|
117
119
|
-> turn-scoped DeepSeekAdapter configuration selected by sessionId
|
|
120
|
+
-> upstream attachment resolver reads and verifies authorized backend bytes
|
|
118
121
|
-> upstream LlmRuntime + ReactLoopAgent stream/event pipeline
|
|
119
122
|
-> upstream ToolRuntime native bash or web_search call
|
|
120
123
|
-> upstream WebRuntime + DeepSeek native search provider for web_search
|
|
@@ -128,11 +131,11 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
|
|
|
128
131
|
-> upstream Web runtime reconciles and renders the canonical events
|
|
129
132
|
```
|
|
130
133
|
|
|
131
|
-
The local integration check uses an SSE stand-in and the real Wrangler, Durable Object SQLite, the default direct Computer workspace backend, static asset service, HTTP carrier, and WebSockets. It verifies owner login, API and WebSocket cookie enforcement, rejection of legacy instance selectors, disabled direct-shell networking, the upstream session create/list/history/search/prompt/rename/fork flow; queue edit, removal, and promotion to steering; workspace create/list/rename/delete/session reorder/archive; the corresponding live and reconnect baselines and Host frames; real browser boot and UI-issued workspace rename, turn, content search, branch, and archive actions; automatic return to login when the browser session expires; conversation continuity, event replay, two-step bash and Web Search tool exchanges, and restoration after a Wrangler restart. A focused failure test proves that a post-enqueue durability failure blocks model use without reporting the already-woken prompt as rejected. Committed model-visible and ARIA goldens pin the tool transcripts and the assembled upstream Web client through the Edge HTTP/WebSocket protocol. A live DeepSeek call requires the developer's own key and is intentionally not part of the repository test suite.
|
|
134
|
+
The local integration check uses an SSE stand-in and the real Wrangler, Durable Object SQLite, local R2, the default direct Computer workspace backend, static asset service, HTTP carrier, and WebSockets. Direct mode exercises the temporary DO attachment backend while Isolated mode exercises private R2. It verifies owner login, API and WebSocket cookie enforcement, rejection of legacy instance selectors, disabled direct-shell networking, the upstream session create/list/history/search/prompt/rename/fork flow; an image prompt through the upstream composer/protocol/provider path; authorized attachment reads, cross-session rejection, fork reuse, and attachment persistence after restart; queue edit, removal, and promotion to steering; workspace create/list/rename/delete/session reorder/archive; the corresponding live and reconnect baselines and Host frames; real browser boot and UI-issued workspace rename, image turn, content search, branch, and archive actions; automatic return to login when the browser session expires; conversation continuity, event replay, two-step bash and Web Search tool exchanges, and restoration after a Wrangler restart. A focused failure test proves that a post-enqueue durability failure blocks model use without reporting the already-woken prompt as rejected. Committed model-visible and ARIA goldens pin the tool transcripts and the assembled upstream Web client through the Edge HTTP/WebSocket protocol. A live DeepSeek call requires the developer's own key and is intentionally not part of the repository test suite.
|
|
132
135
|
|
|
133
136
|
## API-key boundary
|
|
134
137
|
|
|
135
|
-
`DEEPSEEK_API_KEY` from `.dev.vars` is the local credential source. A read-only Edge provider exposes that Worker secret through the upstream `ctx.credentials` service for each chat or search operation without writing it to Durable Object storage, the VFS, session events, or responses. It removes surrounding whitespace and treats a blank value as unconfigured. `DEEPSEEK_BASE_URL` controls chat and must be an HTTP(S) URL without URL userinfo; its read-only browser projection omits query and fragment components that may carry gateway credentials. `DEEPSEEK_SEARCH_BASE_URL` independently controls the Anthropic-compatible Messages endpoint used by DeepSeek native search, defaults to `https://api.deepseek.com/anthropic/v1`, and must be an HTTP(S) URL without userinfo, query, or fragment. Edge mounts the upstream `web_search` tool, its 30-second tool-call timeout policy, and structured Web result presentation; `web_fetch` remains disabled because the runtime has no arbitrary-URL network policy. Search requests do not follow redirects. `DEEPSEEK_MODEL` selects
|
|
138
|
+
`DEEPSEEK_API_KEY` from `.dev.vars` is the local credential source. A read-only Edge provider exposes that Worker secret through the upstream `ctx.credentials` service for each chat or search operation without writing it to Durable Object storage, the VFS, session events, or responses. It removes surrounding whitespace and treats a blank value as unconfigured. `DEEPSEEK_BASE_URL` controls chat and must be an HTTP(S) URL without URL userinfo; its read-only browser projection omits query and fragment components that may carry gateway credentials. `DEEPSEEK_SEARCH_BASE_URL` independently controls the Anthropic-compatible Messages endpoint used by DeepSeek native search, defaults to `https://api.deepseek.com/anthropic/v1`, and must be an HTTP(S) URL without userinfo, query, or fragment. Edge mounts the upstream `web_search` tool, its 30-second tool-call timeout policy, and structured Web result presentation; `web_fetch` remains disabled because the runtime has no arbitrary-URL network policy. Search requests do not follow redirects. `DEEPSEEK_MODEL` selects the validated deployment default and defaults to `deepseek-v4-flash`; each session can choose another entry from the upstream provider catalog. `DEEPSEEK_REASONING_EFFORT` accepts `off`, `low`, `high`, or `max` and defaults to `off`. `DEEPSEEK_MAX_OUTPUT_TOKENS` optionally overrides the 8,192-token chat default and must be a positive safe integer. `DEEPSEEK_STREAM_IDLE_TIMEOUT_MS` optionally overrides the 120,000 ms chat default and must be a positive integer no greater than 2,147,483,647. Invalid deployment configuration fails before session lookup or the SSE response opens.
|
|
136
139
|
|
|
137
140
|
`DSH_EDGE_DEFAULT_COMMAND_TIMEOUT_MS` applies to every Computer command that omits a caller timeout, and `DSH_EDGE_MAX_COMMAND_TIMEOUT_MS` limits caller-selected values. Both default to 120,000 ms, must be positive integers no greater than 2,147,483,647, and the default cannot exceed the maximum.
|
|
138
141
|
|
|
@@ -152,7 +155,7 @@ Run the stable installer without cloning this repository:
|
|
|
152
155
|
npx dsh-edge install
|
|
153
156
|
```
|
|
154
157
|
|
|
155
|
-
This resolves through npm's `latest` channel. Use `npx dsh-edge@next install`
|
|
158
|
+
This resolves through npm's `latest` channel. Use `npx dsh-edge@next install` to test the current 0.3 prerelease with upstream model selection and image prompts.
|
|
156
159
|
|
|
157
160
|
Upgrade an existing named Worker with the same runtime choice. The deployment keeps its Durable Object data; because Cloudflare secrets are write-only, the upgrade asks for the owner access key and DeepSeek API key again and replaces their active values:
|
|
158
161
|
|
|
@@ -164,7 +167,7 @@ npx dsh-edge upgrade
|
|
|
164
167
|
|
|
165
168
|
If the installed version is a 0.2 alpha, promote it to the stable channel once with `npx dsh-edge@latest upgrade`; prerelease deployments otherwise remain on `next`. The Edge settings page derives the channel from the installed version and copies the matching command.
|
|
166
169
|
|
|
167
|
-
The installer asks for the runtime before the account. The recommended `Free — Direct Shell` mode works on Workers Free and can use a detected Cloudflare account, open Cloudflare sign-in or registration, or create a temporary account without login. `Isolated — Dynamic Worker` requires Workers Paid and therefore offers only a detected or newly authenticated account. Cloudflare does not expose a reliable local entitlement check for Worker Loader, so an isolated install lets Cloudflare authorize the upload and turns a rejection into a choice between enabling Workers Paid and using direct mode.
|
|
170
|
+
The installer asks for the runtime before the account. The recommended `Free — Direct Shell` mode works on Workers Free and can use a detected Cloudflare account, open Cloudflare sign-in or registration, or create a temporary account without login. `Isolated — Dynamic Worker` requires Workers Paid and therefore offers only a detected or newly authenticated account. Cloudflare does not expose a reliable local entitlement check for Worker Loader, so an isolated install lets Cloudflare authorize the upload and turns a rejection into a choice between enabling Workers Paid and using direct mode. For a new permanent account installation, the installer creates or reuses a private `<worker-name>-attachments` R2 bucket and writes only its binding to the generated private Wrangler config. It never deletes the bucket on deployment failure. R2 Standard has an included monthly free tier, but Cloudflare requires the selected account to enable its separate usage-based R2 subscription through the Dashboard checkout. The installer checks R2 before collecting Worker secrets. Cloudflare error `10042` opens an account-specific recovery choice: retry after activation, cancel, or safely switch an unmarked pre-attachment Worker to DO storage. A new or already R2-pinned deployment cannot switch backends because doing so could violate the documented storage decision or strand references. Temporary accounts use a 64 MiB Durable Object attachment backend and support the same upstream image UI. Claiming preserves that backend and its existing image history; automatic migration to R2 is not implemented. Each new deployment records an explicit attachment-storage marker. Before updating an existing Worker, the installer inspects every active version and preserves a marked or bound R2-or-DO choice. A Worker from before image support has neither marker nor attachment binding and cannot contain image references, so its first 0.3 upgrade asks once between no-setup 64 MiB DO storage and private R2. The chosen backend is then pinned. Mixed active rollouts are refused rather than guessed.
|
|
168
171
|
|
|
169
172
|
The remaining prompts select a Worker name, generate or accept the owner access key, collect the DeepSeek API key through hidden input, and show a final cost summary. A temporary-account install also asks the user to accept Cloudflare's Terms of Service and Privacy Policy explicitly. An existing Worker is never overwritten without confirmation. The installer passes both credentials through a mode-`0600` temporary secrets file and gives Wrangler only an allowlisted runtime environment plus the Cloudflare authentication selected for that command; unrelated ambient keys, tokens, passwords, secrets, and Node injection options do not reach the child. It removes the secret file after the command and discovers the resulting URL from Wrangler's structured output. Deployment output is hidden behind one progress indicator by default; add `--verbose` to either command to inspect Wrangler diagnostics.
|
|
170
173
|
|
|
@@ -184,7 +187,7 @@ pnpm --filter dsh-edge example:install
|
|
|
184
187
|
- `GET /login` renders the Edge-owned owner form; `POST /api/auth/login` exchanges the configured access key for a signed cookie, `GET /api/auth/session` reports cookie validity, and `POST /api/auth/logout` clears it.
|
|
185
188
|
- `GET /api/events.mux` and `GET /api/events.host` upgrade to the upstream downlink WebSockets. The Durable Object serializes each socket's channel and verified owner-session expiry as its hibernation attachment, closes it at that expiry through an alarm, and reconstructs canonical sessions plus retained blank headers from Durable Object SQL. The mux stream publishes a complete `session/queue` snapshot after each committed inbox splice and sends pending live inbox baselines when a client reconnects.
|
|
186
189
|
- `POST /api/commands/list` implements the upstream generated-Remote envelope with an empty catalog because the Edge preset registers no human commands.
|
|
187
|
-
- `GET /api/health` returns the public package-and-mode release identifier and validates owner authentication, the deployment-scoped DeepSeek credential, model and transport choices, and the command-timeout policy before reporting the runtime components as ready. It does not call the provider, Durable Object, VFS, or shell.
|
|
190
|
+
- `GET /api/health` returns the public package-and-mode release identifier and configured attachment default (`private-r2` or `temporary-do`), and validates owner authentication, the deployment-scoped DeepSeek credential, model and transport choices, and the command-timeout policy before reporting the runtime components as ready. It does not call the provider, Durable Object, R2, VFS, or shell. The authenticated agent-preset projection reports the actual backend pinned by the owner Durable Object, the temporary storage cap, the deployment-default model, and the runtime-derived upstream model catalog with session selection scope.
|
|
188
191
|
- `PUT /api/workspace/file?path=/workspace/...` writes a UTF-8 file.
|
|
189
192
|
- `GET /api/workspace/file?path=/workspace/...` reads a UTF-8 file.
|
|
190
193
|
- `DELETE /api/workspace/file?path=/workspace/...` removes a file.
|
|
@@ -195,6 +198,6 @@ pnpm --filter dsh-edge example:install
|
|
|
195
198
|
- `GET /api/sessions/:sessionId/events?after=...&limit=...` replays a bounded event page and returns continuation headers.
|
|
196
199
|
- `POST /api/sessions/:sessionId/cancel` aborts the active turn owned by the current Durable Object process.
|
|
197
200
|
|
|
198
|
-
Upstream session creation and fork return `workspace-attach-failed` with the published session and Workspace ids when publication succeeds but Workspace attachment fails; the diagnostic creation route returns the same code plus its complete created session. Prompt and queue-edit text share the same 64 KiB semantic limit
|
|
201
|
+
Upstream session creation and fork return `workspace-attach-failed` with the published session and Workspace ids when publication succeeds but Workspace attachment fails; the diagnostic creation route returns the same code plus its complete created session. Prompt and queue-edit text share the same 64 KiB semantic limit. Their RPC carrier accepts up to 10 MiB so a projected 7 MiB raw-image batch still fits after base64 and envelope overhead. Because the Edge composition has no directory-flow provider, the upstream browser hides Delete on its sole Workspace and exposes it again whenever restoration remains possible.
|
|
199
202
|
|
|
200
|
-
The API limits text files to 1 MiB, commands to 16 KiB, user messages to 64 KiB, and retained shell stdout plus stderr to 64 KiB; these are UTF-8 byte limits. Request bodies are consumed incrementally before parsing or forwarding: session creation accepts at most 8 KiB of JSON, workspace execution 128 KiB, and message-bearing turn or queue-update RPCs
|
|
203
|
+
The API limits text files to 1 MiB, commands to 16 KiB, user messages to 64 KiB, and retained shell stdout plus stderr to 64 KiB; these are UTF-8 byte limits. Both attachment backends accept PNG and JPEG only, at most 4 images per message, 3.5 MiB per image, 7 MiB total, 40 million pixels, and 2,000 pixels per side; admission fully decodes the declared raster format before writing. Request bodies are consumed incrementally before parsing or forwarding: session creation accepts at most 8 KiB of JSON, workspace execution 128 KiB, and message-bearing turn or queue-update RPCs 10 MiB, while file uploads enforce their 1 MiB bound during consumption and reject malformed UTF-8. Once a body exceeds its route limit, later chunks are drained without being retained and the route returns 413. File reads first check VFS metadata, then collect the opened raw byte stream through the same 1 MiB cap, closing the growth race between `stat()` and `readFile()` without retaining an unbounded value. The runtime requests interruption when combined shell output crosses the retention bound and does not accumulate later output. Command status reports cancellation only when the adapter requested interruption, independently of the shell exit code; `timedOut` separately records deadline expiry. Failed initial session persistence discards the retained unmaterialized batch before disposing the newly published upstream agent handle, so teardown cannot later commit a session whose create request returned an error. A lazy blank session retains only its upstream header until the first canonical event; that materialization removes the retained header in the same SQL transaction. Each turn owns one upstream handle and disposes it after the stream completes, so previously accessed conversations do not remain resident for the Durable Object lifetime. Deployment settings resolve before the process-local owner claim. An upstream protocol prompt returns accepted and publishes running state only after its inbox event crosses `SessionStore.flush()`; later streamed events cross the same barrier before WebSocket or SSE delivery. Queue edits, removals, and steering promotion use the synchronous live-inbox mutation as their acceptance point; `PersistenceCoordinator` owns subsequent write-behind or retirement retry, so a later storage attempt cannot turn an accepted mutation into a rejected response. Session rename follows the same upstream metadata contract: the synchronous title append is its acceptance point for both active and cold sessions. Workspace global state and records use the upstream logical schemas under Edge-specific physical keys; DO transactions atomically pair record and registry-order changes, while a process-local chain serializes workspace mutations. Committed rename, delete, recreation, session reorder, attachment, and archive changes publish the matching upstream Host frames, and `workspace.list` restores their complete baseline after restart. A process-local owner rejects a concurrent turn, and cancel calls the native agent cancellation path. On the next cold resume, upstream interrupted-turn repair closes an open persisted tail and canonical `session/end-seed` markers preserve lifecycle boundaries. Replay checks session absence separately so persistence corruption or SQL failures are not collapsed into 404, reads only one bounded SQL page rather than the full suffix, and caps the encoded response. `PersistenceCoordinator.readValidatedPage()` performs identity, format, legacy-shape, and event-vocabulary validation on every page without adding Edge pagination to the public persistence service. If legacy normalization needs earlier messages, it rereads only one prefix through the same byte-bounded loader and refuses the page when that required prefix does not fit. Cold browser history selects its message boundary in SQL and loads only the resulting contiguous range under fixed event and stored-byte ceilings. Session listing queries one bounded canonical header/title summary page; detail reads its durable canonical point summary or retained blank header, while turn existence checks use point queries instead of listing headers or projecting a complete log. Effective model, system prompt, adapter defaults, and tools are recorded in standard `request/header` events. The request-scoped adapter uses the validated deployment reasoning and output policies. Workspace paths must stay below `/workspace/`.
|
package/README.zh.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
该运行时通过上游 Cordis 组合的 `ReactLoopAgent`、`AgentRegistry`、`LlmRuntime`、`ToolRuntime`、`SystemPrompt`、`SessionStore` 和 `SessionPersistence` 运行持久对话。Edge 代码只绑定请求作用域的 DeepSeek 适配器,并把一个原生 DSH `bash` 工具定义映射到 Cloudflare Computer。Durable Object SQLite 实现上游持久化后端约定,write-behind、revision、恢复准备和崩溃恢复仍由 `PersistenceCoordinator` 负责。模型历史从 canonical 事件投影,不再单独持久化。
|
|
12
12
|
|
|
13
|
-
浏览器直接使用上游 Web shell 和上游客户端插件包。构建期 assembler 根据上游 base 与 Web 组合包配置推导浏览器 roster,注入标准 `window.__DSH_BOOT__` graph,并把结果发布为 Cloudflare 静态资源。Durable Object 通过标准 HTTP carrier 实现受支持的上游 `ApiProxy` 方法,并以支持休眠的 WebSocket 提供两条上游 downlink
|
|
13
|
+
浏览器直接使用上游 Web shell 和上游客户端插件包。构建期 assembler 根据上游 base 与 Web 组合包配置推导浏览器 roster,注入标准 `window.__DSH_BOOT__` graph,并把结果发布为 Cloudflare 静态资源。Durable Object 通过标准 HTTP carrier 实现受支持的上游 `ApiProxy` 方法,并以支持休眠的 WebSocket 提供两条上游 downlink。上游图片 composer、gallery、lightbox、attachment wire contract 与 DeepSeek serializer 保持原样复用;storage seam 会为新的永久部署选择私有 R2,为临时部署选择有界 Durable Object storage,并让 0.3 之前的 Worker 在升级时由 owner 做一次选择。Edge 会排除缺少对应 host domain 的客户端插件,而不会 fork 其 UI 代码;在服务端 endpoint 可用前,session log export 也属于排除项。一个很小的 Edge 登录外壳会保护上游 UI 与协议,不修改两者本身。可选的本地 host 插件仍不可用。
|
|
14
14
|
|
|
15
15
|
## 本地运行
|
|
16
16
|
|
|
@@ -93,13 +93,13 @@ Session listing 同样有界:`GET /api/sessions?after=SESSION_ID&limit=COUNT`
|
|
|
93
93
|
| Bash tool | Node subprocess、sandbox、terminal 和 job services | 在原生 tool seam 上适配 | 注册上游 `ToolDefinition`,但通过配置的 Computer workspace backend 和 just-bash 执行其 body。默认 direct backend 在 owner Durable Object 内运行,启用 hardened interpreter limits 且不提供网络命令;添加 `LOADER` binding 后会选择 Computer 的 isolated Worker Shell backend。原生 tool cancellation 会通过 Computer execution handle 发送 `SIGINT`。部署配置提供明确的默认 timeout 与调用方可选值上限,`timedOut` 则独立于 exit 与 cancellation status 报告 deadline。不支持原生二进制、后台进程、PTY 和任意 Linux 行为。 |
|
|
94
94
|
| Workspace filesystem | 本地 filesystem services 和 host paths | 适配 | 在 owner 基于 SQLite 的 Durable Object VFS 中保存 `/workspace`。 |
|
|
95
95
|
| Session persistence | `SessionPersistence` service、`PersistenceCoordinator` 及本地 JSONL/SQLite backends | 原生 backend 适配 | 复用上游 service 及 coordinator 的职责划分,在 Durable Object SQL 上实现存储原语,并使用上游 header/event 映射。一个 Edge 独有表会在透明休眠期间保留 empty session header,并在 canonical rows 物化时删除;Edge 不定义 turn 或 message schema。内部 coordinator helper 负责校验有界 replay loader,并在 disposal 前放弃失败且尚未物化的创建。 |
|
|
96
|
-
| Settings and credentials | 基于文件的 settings、launch environment 和 credential services | Edge 只读投影 | 为每次操作解析 Worker secret,绝不持久化或返回 literal key。空白 secret 会被视为未配置,使用前会移除首尾空白。`credentials.describe` 只报告 `DEEPSEEK_API_KEY` 是否已配置,以及其只读来源为 `worker-secret`。内置 `dsh-edge` preset 会通过上游只读 composition viewer 投影实际 release、shell/VFS
|
|
96
|
+
| Settings and credentials | 基于文件的 settings、launch environment 和 credential services | Edge 只读投影 | 为每次操作解析 Worker secret,绝不持久化或返回 literal key。空白 secret 会被视为未配置,使用前会移除首尾空白。`credentials.describe` 只报告 `DEEPSEEK_API_KEY` 是否已配置,以及其只读来源为 `worker-secret`。内置 `dsh-edge` preset 会通过上游只读 composition viewer 投影实际 release、shell/VFS、部署默认模型、runtime 实际读取的上游 model catalog、per-session 选择范围、limits、credential state、prompt 与 tools。可写 settings 和经过身份认证的用户级 secret storage 尚未实现。 |
|
|
97
97
|
| Host boot and plugins | Node 命令行、Cordis profile loading、package resolution 和 HMR | 显式 Edge composition | 不在 Workerd 中运行本地 boot profile。部署前构建 immutable 客户端包,并排除 HMR 及 Edge `ApiProxy` 未暴露的 host domain。 |
|
|
98
98
|
| DSH transport | Typed HTTP RPC 加 mux/host WebSocket downlink | 复用并提供 Edge 服务端实现 | 对 unary method 使用上游 fetch carrier,并保留其 envelope、schema、projection、lazy blank-session 行为、有界内容搜索、prompt 与 queue mutation、workspace mutation、queue snapshot 和 event frame。两条 downlink 都由 Durable Object WebSocket 休眠机制持有;mux 重连会重放 live inbox 的待处理状态,REST/SSE 路由则保留为诊断兼容路径。 |
|
|
99
99
|
| Workspace registry | Storage-domain global state 加 `WorkspaceRecord` rows | 原生 backend 适配 | 保持上游 global 和 record value shape,包括手动 session 顺序与 archive membership;仅把物理 key 和原子写入映射到 Durable Object storage。Edge 把 registry 限制为一个原生 `/workspace` VFS;rename、delete、recreate 与 session reorder 保持上游 RPC 和 Host-frame 语义。 |
|
|
100
100
|
| Existing Web UI | 运行时加载的 shell 和 `dsh.client` 插件 graph | 复用并采用通用 composition fallback | 把上游 shell 和受支持的上游客户端包组装成 Worker 静态资源;共享的 slot occupancy 规则会隐藏缺少 provider 的 action。Cloudflare 直接提供普通资源,`/`、`/login` 与 `/api/*` 则进入 Worker 执行 owner access control。组装后的 asset policy 会阻止所有直接或 SPA-fallback shell alias 被嵌入 frame。 |
|
|
101
101
|
| Other tools | Web Search、filesystem editor tools、MCP、skills、workflows、jobs 和 subagents | Search 已移植;其他未移植 | 复用上游 DeepSeek Web Search 及其 30 秒 tool-call timeout。逐个针对 Worker-compatible capabilities 增加其余工具,不宣称不可用的 host 行为。 |
|
|
102
|
-
| Attachments | 本地 attachment storage
|
|
102
|
+
| Attachments | 本地 attachment storage、上游 image reference、composer、gallery、lightbox 与 provider conversion | 在原生 storage seam 上适配 | 原样复用上游 `AttachmentStore`、admission、协议、授权、UI 与 DeepSeek conversion。PNG/JPEG 不可变字节按 SHA-256 identity 存入新永久部署的私有 R2,或存入临时部署以及升级旧版 Worker 时由 owner 选择的 64 MiB、按 512 KiB 分块的 DO backend;session event 只保留上游 ref。每个 owner instance 首次选择的 backend 会被固定,认领或升级不会让既有引用失联。 |
|
|
103
103
|
| Authentication and tenancy | 本地 trusted-user boundary | 单 owner 适配 | 要求一个高熵 Worker secret,把它交换为带签名、有效期 30 天的 HttpOnly `SameSite=Strict` cookie,并把所有已接纳请求路由到一个固定 owner object。这里刻意不提供注册、用户数据库、角色或多租户路由。 |
|
|
104
104
|
|
|
105
105
|
浏览器请求路径是:
|
|
@@ -109,12 +109,15 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
|
|
|
109
109
|
-> POST /api/session.create through the upstream HTTP carrier
|
|
110
110
|
-> host/workspace-changed + session/subscribed over Durable Object WebSockets
|
|
111
111
|
-> POST /api/session.prompt with the client rpcId
|
|
112
|
+
-> 上游图片 admission 校验图片,并把不可变字节存入所选 R2 或 DO backend
|
|
113
|
+
-> canonical session event 只保留上游 sha256 attachment ref
|
|
112
114
|
-> AgentRegistry live lookup or resume
|
|
113
115
|
-> sessionPersistence.prepare through PersistenceCoordinator on cold resume
|
|
114
116
|
-> ReactLoopAgent.followup(queue) or ReactLoopAgent.steer(steer)
|
|
115
117
|
-> pre-step admission gate waits for the sessions.flush durability barrier
|
|
116
118
|
-> session/queue snapshots publish live and replay on mux reconnect
|
|
117
119
|
-> turn-scoped DeepSeekAdapter configuration selected by sessionId
|
|
120
|
+
-> 上游 attachment resolver 读取并校验已授权的 backend 字节
|
|
118
121
|
-> upstream LlmRuntime + ReactLoopAgent stream/event pipeline
|
|
119
122
|
-> upstream ToolRuntime native bash or web_search call
|
|
120
123
|
-> upstream WebRuntime + DeepSeek native search provider for web_search
|
|
@@ -128,11 +131,11 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
|
|
|
128
131
|
-> upstream Web runtime reconciles and renders the canonical events
|
|
129
132
|
```
|
|
130
133
|
|
|
131
|
-
本地集成检查使用 SSE stand-in 以及真实的 Wrangler、Durable Object SQLite、默认 direct Computer workspace backend、静态资源服务、HTTP carrier 和 WebSocket。它验证 owner 登录、API 与 WebSocket cookie enforcement、拒绝旧 instance selector、direct shell 网络被禁用、上游 session create/list/history/search/prompt/rename/fork
|
|
134
|
+
本地集成检查使用 SSE stand-in 以及真实的 Wrangler、Durable Object SQLite、本地 R2、默认 direct Computer workspace backend、静态资源服务、HTTP carrier 和 WebSocket。Direct 模式会覆盖临时 DO attachment backend,Isolated 模式则覆盖私有 R2。它验证 owner 登录、API 与 WebSocket cookie enforcement、拒绝旧 instance selector、direct shell 网络被禁用、上游 session create/list/history/search/prompt/rename/fork;经上游 composer/协议/provider 路径完成图片 prompt;已授权附件读取、跨 session 拒绝、fork 复用,以及重启后的附件持久性;queue edit、remove 与提升为 steering;workspace create/list/rename/delete/session reorder/archive;对应的实时与重连 baseline 和 Host frame;真实浏览器启动及由 UI 发起的 workspace rename、图片 turn、内容搜索、branch 与 archive 操作;浏览器 session 过期后自动返回登录页;跨 turn 对话连续性、event 重放、两步 bash 与 Web Search tool 交互,以及 Wrangler 重启后的恢复。一项聚焦的故障测试证明,入队后的持久化失败会阻止模型调用,同时不会把已经唤醒 Agent 的 prompt 报告为拒绝。提交到仓库的 model-visible 与 ARIA golden 会固定 tool transcript 以及组装后的上游 Web client 通过 Edge HTTP/WebSocket 协议呈现的结果。真实 DeepSeek 调用需要开发者自己的 key,因此不会纳入仓库测试套件。
|
|
132
135
|
|
|
133
136
|
## API key 边界
|
|
134
137
|
|
|
135
|
-
`.dev.vars` 中的 `DEEPSEEK_API_KEY` 是本地 credential source。只读 Edge provider 会通过上游 `ctx.credentials` service 为每次 chat 或 search 操作提供该 Worker secret,但不会将它写入 Durable Object storage、VFS、session event 或 response。Provider 会移除首尾空白,并把空白值视为未配置。`DEEPSEEK_BASE_URL` 控制 chat,必须是不含 URL userinfo 的 HTTP(S) URL;它的只读 browser 投影会省略可能携带 gateway credential 的 query 与 fragment。`DEEPSEEK_SEARCH_BASE_URL` 独立控制 DeepSeek native search 使用的 Anthropic-compatible Messages endpoint,默认为 `https://api.deepseek.com/anthropic/v1`,且必须是不含 userinfo、query 与 fragment 的 HTTP(S) URL。Edge 会挂载上游 `web_search` tool、它的 30 秒 tool-call timeout policy 与结构化 Web result presentation;由于 runtime 尚无 arbitrary-URL network policy,`web_fetch` 保持禁用。Search request 不会跟随 redirect。`DEEPSEEK_MODEL`
|
|
138
|
+
`.dev.vars` 中的 `DEEPSEEK_API_KEY` 是本地 credential source。只读 Edge provider 会通过上游 `ctx.credentials` service 为每次 chat 或 search 操作提供该 Worker secret,但不会将它写入 Durable Object storage、VFS、session event 或 response。Provider 会移除首尾空白,并把空白值视为未配置。`DEEPSEEK_BASE_URL` 控制 chat,必须是不含 URL userinfo 的 HTTP(S) URL;它的只读 browser 投影会省略可能携带 gateway credential 的 query 与 fragment。`DEEPSEEK_SEARCH_BASE_URL` 独立控制 DeepSeek native search 使用的 Anthropic-compatible Messages endpoint,默认为 `https://api.deepseek.com/anthropic/v1`,且必须是不含 userinfo、query 与 fragment 的 HTTP(S) URL。Edge 会挂载上游 `web_search` tool、它的 30 秒 tool-call timeout policy 与结构化 Web result presentation;由于 runtime 尚无 arbitrary-URL network policy,`web_fetch` 保持禁用。Search request 不会跟随 redirect。`DEEPSEEK_MODEL` 选择经过校验的部署默认模型,默认为 `deepseek-v4-flash`;每个 session 可以从上游 provider catalog 选择其他条目。`DEEPSEEK_REASONING_EFFORT` 接受 `off`、`low`、`high` 或 `max`,默认为 `off`。`DEEPSEEK_MAX_OUTPUT_TOKENS` 可以覆盖默认的 8,192-token chat 上限,且必须是正安全整数。`DEEPSEEK_STREAM_IDLE_TIMEOUT_MS` 可以覆盖默认的 120,000 ms chat 超时,且必须是小于等于 2,147,483,647 的正整数。部署配置无效时,会在查询 session 或打开 SSE response 前失败。
|
|
136
139
|
|
|
137
140
|
`DSH_EDGE_DEFAULT_COMMAND_TIMEOUT_MS` 会应用到每个未指定调用方 timeout 的 Computer 命令,`DSH_EDGE_MAX_COMMAND_TIMEOUT_MS` 则限制调用方选择的值。两者都默认为 120,000 ms,必须是小于等于 2,147,483,647 的正整数,且默认值不能超过最大值。
|
|
138
141
|
|
|
@@ -152,7 +155,7 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
|
|
|
152
155
|
npx dsh-edge install
|
|
153
156
|
```
|
|
154
157
|
|
|
155
|
-
该命令通过 npm `latest`
|
|
158
|
+
该命令通过 npm `latest` 渠道解析。使用 `npx dsh-edge@next install` 可以测试当前包含上游模型选择与图片 prompt 的 0.3 预发布版本。
|
|
156
159
|
|
|
157
160
|
选择相同 runtime 并输入现有 Worker 名称即可升级。部署会保留 Durable Object 数据;由于 Cloudflare secret 只能写入而不能读取,升级会再次要求 owner access key 与 DeepSeek API key,并用输入值替换当前生效值:
|
|
158
161
|
|
|
@@ -164,7 +167,7 @@ npx dsh-edge upgrade
|
|
|
164
167
|
|
|
165
168
|
如果当前安装的是 0.2 alpha,需要执行一次 `npx dsh-edge@latest upgrade` 晋级到稳定渠道;其他预发布部署仍跟随 `next`。Edge 设置页会根据已安装版本推导渠道,并复制匹配的命令。
|
|
166
169
|
|
|
167
|
-
安装器会先询问运行时,再询问账户。推荐的 `Free — Direct Shell` 模式可在 Workers Free 上运行,并可使用检测到的 Cloudflare 账户、打开 Cloudflare 登录或注册,也可在不登录的情况下创建临时账户。`Isolated — Dynamic Worker` 需要 Workers Paid,因此只提供已检测到或新认证的账户。Cloudflare 没有提供可靠的本地 Worker Loader entitlement 检查;isolated 安装会由 Cloudflare 对上传进行授权,并在被拒绝时提示启用 Workers Paid 或改用 direct
|
|
170
|
+
安装器会先询问运行时,再询问账户。推荐的 `Free — Direct Shell` 模式可在 Workers Free 上运行,并可使用检测到的 Cloudflare 账户、打开 Cloudflare 登录或注册,也可在不登录的情况下创建临时账户。`Isolated — Dynamic Worker` 需要 Workers Paid,因此只提供已检测到或新认证的账户。Cloudflare 没有提供可靠的本地 Worker Loader entitlement 检查;isolated 安装会由 Cloudflare 对上传进行授权,并在被拒绝时提示启用 Workers Paid 或改用 direct 模式。对于新的永久账户安装,安装器会创建或复用私有 `<worker-name>-attachments` R2 bucket,并只把 binding 写入生成的私有 Wrangler 配置;部署失败时绝不会删除 bucket。R2 Standard 提供月度免费额度,但 Cloudflare 要求所选账户先在 Dashboard checkout 中启用独立的按量 R2 subscription。安装器会在收集 Worker secret 前检查 R2;Cloudflare 返回 `10042` 时,会提供当前账户专属的恢复选择:启用后重试、取消,或者把无 marker 的 pre-attachment Worker 安全切换到 DO storage。新的部署或已固定为 R2 的部署不能切换 backend,因为这会违背已确认的 storage 决策或导致引用失联。临时账户使用 64 MiB Durable Object attachment backend,并支持相同的上游图片 UI。认领会保留这个 backend 与已有图片历史;自动迁移到 R2 尚未实现。每个新部署都会记录明确的 attachment-storage marker。在更新已有 Worker 前,安装器会检查所有 active version,并保留 marker 或 binding 指定的 R2/DO 选择。图片功能出现前创建的 Worker 既没有 marker、也没有 attachment binding,不可能包含图片引用,因此首次升级到 0.3 时会询问一次:选择无需额外开通的 64 MiB DO storage,或选择私有 R2。此后固定所选 backend。若 active rollout 混用两种 backend,则会拒绝猜测并要求先完成 rollout。
|
|
168
171
|
|
|
169
172
|
后续提示会选择 Worker 名称、生成或接收 owner access key、通过隐藏输入收集 DeepSeek API key,并显示最终费用摘要。临时账户安装还会要求用户明确接受 Cloudflare 服务条款与隐私政策。安装器绝不会在未经确认时覆盖现有 Worker。两项 credential 会通过权限模式为 `0600` 的临时 secret 文件传给 Wrangler;Wrangler 子进程只会收到 allowlist 内的运行时环境变量和当前命令选中的 Cloudflare authentication,其他 ambient key、token、password、secret 与 Node 注入选项不会进入子进程。命令结束后临时 secret 文件会被删除,安装器从 Wrangler 结构化输出中取得最终 URL。默认情况下,部署输出会收敛到一个进度提示;在任一命令后添加 `--verbose` 可以查看 Wrangler 诊断。
|
|
170
173
|
|
|
@@ -184,7 +187,7 @@ pnpm --filter dsh-edge example:install
|
|
|
184
187
|
- `GET /login` 渲染 Edge 持有的 owner form;`POST /api/auth/login` 用已配置的 access key 换取 signed cookie,`GET /api/auth/session` 报告 cookie 是否有效,`POST /api/auth/logout` 清除 cookie。
|
|
185
188
|
- `GET /api/events.mux` 和 `GET /api/events.host` 会升级为上游 downlink WebSocket。Durable Object 会把每个 socket 的 channel 与已验证 owner session 过期时间序列化为 hibernation attachment,通过 alarm 在该时间关闭连接,并从 Durable Object SQL 重建 canonical session 与 retained blank header。每次 inbox splice 提交后,mux stream 都会发布完整的 `session/queue` snapshot;客户端重连时还会发送 live inbox 的待处理 baseline。
|
|
186
189
|
- `POST /api/commands/list` 使用上游 generated-Remote envelope 返回空 catalog,因为 Edge preset 没有注册 human command。
|
|
187
|
-
- `GET /api/health` 会返回公开的 package-and-mode release identifier
|
|
190
|
+
- `GET /api/health` 会返回公开的 package-and-mode release identifier 与配置的附件默认值(`private-r2` 或 `temporary-do`),并先验证 owner authentication、部署级 DeepSeek 凭据、模型与传输配置,以及命令超时策略,再报告运行时组件已就绪。它不会调用提供方、Durable Object、R2、VFS 或 shell。认证后的 agent-preset projection 会报告 owner Durable Object 实际固定的 backend、临时存储上限、部署默认模型,以及 runtime 实际读取的上游 model catalog 与 session 选择范围。
|
|
188
191
|
- `PUT /api/workspace/file?path=/workspace/...` 写入 UTF-8 文件。
|
|
189
192
|
- `GET /api/workspace/file?path=/workspace/...` 读取 UTF-8 文件。
|
|
190
193
|
- `DELETE /api/workspace/file?path=/workspace/...` 删除文件。
|
|
@@ -195,6 +198,6 @@ pnpm --filter dsh-edge example:install
|
|
|
195
198
|
- `GET /api/sessions/:sessionId/events?after=...&limit=...` 重放一个有界 event page,并返回 continuation headers。
|
|
196
199
|
- `POST /api/sessions/:sessionId/cancel` 终止当前 Durable Object 进程持有的 active turn。
|
|
197
200
|
|
|
198
|
-
上游 Session 创建与 fork 在发布成功但 Workspace attachment 失败时返回 `workspace-attach-failed`,并携带已发布的 session 与 Workspace id;诊断创建路由会返回相同 code 及完整的已创建 session。Prompt 和 queue-edit 文本共用 64 KiB
|
|
201
|
+
上游 Session 创建与 fork 在发布成功但 Workspace attachment 失败时返回 `workspace-attach-failed`,并携带已发布的 session 与 Workspace id;诊断创建路由会返回相同 code 及完整的已创建 session。Prompt 和 queue-edit 文本共用 64 KiB 语义上限。其 RPC 载体最多接受 10 MiB,从而让 7 MiB 原始图片批次在 base64 与 envelope 膨胀后仍可装入。Edge 组合没有目录流 provider,因此上游浏览器会在仅剩一个 Workspace 时隐藏 Delete,并在仍有恢复路径时重新显示。
|
|
199
202
|
|
|
200
|
-
API 将文本文件限制为 1 MiB、命令限制为 16 KiB、用户消息限制为 64 KiB,并将保留的 shell stdout 与 stderr 总量限制为 64 KiB;这些均为 UTF-8
|
|
203
|
+
API 将文本文件限制为 1 MiB、命令限制为 16 KiB、用户消息限制为 64 KiB,并将保留的 shell stdout 与 stderr 总量限制为 64 KiB;这些均为 UTF-8 字节限制。两种 attachment backend 都只接受 PNG 与 JPEG:每条消息最多 4 张、每张最多 3.5 MiB、合计最多 7 MiB、最多 4,000 万像素,且单边不超过 2,000 像素;写入前会完整解码声明的 raster 格式。Request body 会在解析或转发前增量消费:创建 session 的 JSON 上限为 8 KiB、workspace execution 为 128 KiB、承载消息的 turn 或 queue-update RPC 为 10 MiB,文件上传也会在消费过程中执行其 1 MiB 上限,并拒绝非法 UTF-8。Body 一旦越过路由上限,后续 chunk 只会排空而不会继续保留,路由最终返回 413。读取文件时会先检查 VFS metadata,再通过相同的 1 MiB 上限收集实际打开的原始 byte stream,从而关闭 `stat()` 与 `readFile()` 之间的增长竞态,且不会保留无界值。组合输出越界时,runtime 会请求中断 shell execution,并停止累积后续输出。只有 adapter 实际请求过中断时,命令状态才会报告 cancellation;这一状态与 shell exit code 独立,`timedOut` 则单独记录 deadline expiry。首次 session 持久化失败时,会先丢弃保留但尚未物化的 batch,再 dispose 新发布的上游 agent handle,因此 teardown 无法在创建请求返回错误后又提交该 session。Lazy blank session 在首个 canonical event 前只保留其上游 header;物化该 event 的同一个 SQL transaction 会删除 retained header。每个 turn 持有一个上游 handle,并在 stream 完成后 dispose,避免曾访问的对话在 Durable Object 整个生命周期内常驻内存。部署 settings 会在声明进程内 owner 前解析。上游 protocol prompt 只有在其 inbox event 跨过 `SessionStore.flush()` 后才返回 accepted 并发布 running state;后续 streamed event 也会先跨过同一个 barrier,再通过 WebSocket 或 SSE 发送。Queue edit、remove 与 steering promotion 以同步 live-inbox mutation 作为接纳点;后续 write-behind 或 retirement retry 由 `PersistenceCoordinator` 负责,因此后续存储尝试不能把已接纳的 mutation 变成被拒绝的响应。Session rename 遵循相同的上游 metadata contract:对于 active 与 cold session,同步追加 title 即为接纳点。Workspace global state 与 record 在 Edge-specific physical key 下使用上游逻辑 schema;DO transaction 原子组合 record 与 registry order 变更,进程内 chain 则串行化 workspace mutation。已提交的 rename、delete、recreate、session reorder、attachment 和 archive 变更会发布对应的上游 Host frame,`workspace.list` 会在重启后恢复完整 baseline。进程内 owner 会拒绝并发 turn,cancel 调用原生 agent cancellation path。下次冷恢复时,上游 interrupted-turn repair 会关闭开放的持久 event tail,canonical `session/end-seed` marker 会保留生命周期边界。Replay 会独立确认 session 是否不存在,因此 persistence corruption 或 SQL failure 不会被折叠成 404;它只读取一个有界 SQL page,而不是完整 suffix,并限制编码后的 response。`PersistenceCoordinator.readValidatedPage()` 会对每个 page 执行 identity、format、legacy-shape 和 event-vocabulary 校验,而不把 Edge pagination 加入公共 persistence service。如果 legacy normalization 需要更早的 message,它只会通过同一个受字节约束的 loader 重读一个 prefix;必要 prefix 无法装入预算时会拒绝该 page。冷浏览器 history 会在 SQL 中选择消息边界,并仅在固定事件数与存储字节上限内加载所得连续区间。Session listing 查询一个有界的 canonical header/title summary page;detail 读取持久化的 canonical point summary 或 retained blank header,turn existence check 则使用 point query,不会列出全部 headers 或投影完整 log。实际 model、system prompt、adapter defaults 和 tools 写入标准 `request/header` 事件。Request-scoped adapter 使用已校验的部署级 reasoning 与输出策略。workspace 路径必须位于 `/workspace/` 下。
|