perf(plugins): keep public requests off the backend when possible

This commit is contained in:
tianma-if committed 2026-09-04 13:35:27 +08:00
1 parent 4176d26488
commit 12fca0db5f
30 files changed
+436 -136

No files matched your search

+4 -2
View File
@@ -485,7 +485,7 @@ const result = await context.ai.generate({
});
```
`system` is limited to 8,000 characters, `prompt` to 90,000, output to 5,000 tokens, and generation to 120 seconds. The backend requires an interactive user session, disables these capabilities in public demo mode, and redacts provider errors. Each workspace has up to four concurrent calls per AI/network group per app instance; this is not a distributed quota. Model charges follow the configured provider. Plugin deactivation aborts outstanding calls.
`system` is limited to 8,000 characters, `prompt` to 90,000, output to 5,000 tokens, and generation to 120 seconds. The backend requires an interactive user session, disables AI in public demo mode, and redacts provider errors. AI calls have a four-request per-workspace guard in each backend instance; this is not a distributed quota. Model charges follow the configured provider. Plugin deactivation aborts outstanding calls.
Existing `network.fetch(url, init)` remains browser fetch with CORS and omitted credentials. Add both `network` and `network:public`, declare `networkHosts`, and explicitly select `transport: "public"` to use the generic public Internet transport:
@@ -508,6 +508,8 @@ const feed = await response.text(); // Parse inside the plugin.
Public mode supports HTTPS GET/HEAD on port 443, no request body or credentials, a 20-second deadline, and at most 2,000,000 decoded response bytes. It always returns redirects without following them (`redirect: "error"` rejects them). Upstream 403/429 remain upstream status codes; this transport does not bypass platform restrictions. Allowed request headers: Accept, Accept-Language, If-None-Match, If-Modified-Since, Range. Only content/cache metadata, Location and Retry-After are returned; Set-Cookie is excluded. The response is buffered within the size limit, not an unlimited streaming proxy.
Web and desktop clients use the same authenticated backend transport. Cloudflare uses default workerd public-only Internet egress and no private-service bindings. Self-hosted Bun uses a TLS lookup callback which validates DNS answers and connects directly to those answers; private, special-use and mixed public/private answers are rejected. Synthetic VPN/fake-IP DNS answers in private or reserved ranges are also rejected; do not disable this check. Nonstandard workerd deployments must preserve public-only global egress.
The host selects the least expensive safe transport without changing the plugin API. Web first tries browser fetch; a readable CORS response stays entirely client-side, while a browser network/CORS `TypeError` falls back to the authenticated backend relay. Desktop uses its Electron main process and the user's own network, capped at four concurrent requests. It does not relay public content through the EdgeEver backend. Cancellation propagates to every transport.
All native/server drivers share one policy package. Desktop and self-hosted Bun validate every DNS answer and pass the validated address directly to TLS; private, special-use and mixed public/private answers are rejected. Cloudflare fallback uses workerd's default public-only Internet egress and no private-service bindings. Synthetic VPN/fake-IP DNS answers in reserved ranges are rejected; do not disable this check. Nonstandard workerd deployments must preserve public-only global egress. The Web fallback returns bounded binary bytes rather than Base64 JSON, avoiding Base64's transfer expansion.
Plugin permission/domain checks run in the trusted client host. Backend routes independently require user authentication and enforce public-only egress; they do not trust client-supplied plugin IDs or allowlists, and do not claim server-attested per-plugin isolation. The trusted-JavaScript limitation still applies. The backend never receives a source enum, search window, evidence schema or report workflow.