open-design/apps/web/tests
mzl163 210b94069a
feat(senseaudio): BYOK chat with image + video generation tools (#2065)
* feat(senseaudio): BYOK chat with image + video generation tools

Adds SenseAudio as a first-class BYOK chat protocol and wires the daemon's
chat proxy with a tool loop so BYOK users can generate images and videos
without dropping to a CLI agent.

- BYOK protocol: new senseaudio tab + /api/proxy/senseaudio/stream route +
  connection-test + provider-models discovery (OpenAI-compatible wire)
- Tool loop: generate_image (synchronous /v1/image/sync) and generate_video
  (async /v1/video/create + 5s polling /v1/video/status, 10-min ceiling,
  periodic progress log every 30s)
- Settings dropdown + chat-composer dropdown for the BYOK image model
  default; generate_image's model enum lets the LLM override per call
- Seed-on-success: a successful BYOK chat call idempotently mirrors the
  key into media-config (preserves env-resolved + already-stored keys)
- Generated artifacts land in <projectsRoot>/<projectId>/ so FileViewer,
  DesignFilesPanel, and project export pick them up automatically;
  legacy /api/byok-image/:id route kept for old conversation links
- Markdown renderer learns ![alt](url) image syntax with a scheme
  allowlist (http(s) / data:image/ / blob: / relative paths)
- i18n key settings.byokImageModel across all 19 locales
- 3 SenseAudio image models registered (2.0, 1.0, doubao-seedream-5.0);
  1 video model (doubao-seedance-2.0)
- Tests: byok-tools (29), media-senseaudio-image (8), media-config seed
  (7), proxy-routes (47), markdown image rendering (8)

* fix(senseaudio): unblock image gen + design file preview switching

- SenseAudio /v1/image/sync rejected the previous size mapping with
  `参数错误:size` (1664x936, 936x1664, 1280x960, 960x1280 are not in
  the gateway's accepted set). Switched to standard HD / SD sizes that
  every aspect bucket can hit: 1024×1024, 1280×720, 720×1280,
  1024×768, 768×1024. Kept the byok-tools and media.ts tables in sync
  so the BYOK chat tool and the CLI agent path both stop failing on
  non-square aspects.

- DesignFilesPanel's <DfPreview> was missing a key prop, so React
  reused the same iframe DOM node when the user picked a different
  file — the src prop changed but the iframe never navigated. Added
  key={previewFile.name} so the previous preview unmounts cleanly.

- Updated byok-tools + media-senseaudio-image tests for the new size
  expectations.

* docs(senseaudio): clear stale provider hint + update README

- Settings → Media → SenseAudio: clear the auto-promoted
  "Image · TTS · 70+ voices · clone" hint; the provider label alone is
  enough now that the BYOK chat surface covers image + video tooling.
- README: list the new senseaudio (and missing ollama) proxy routes so
  the BYOK section reflects what the daemon actually serves, and
  mention the generate_image / generate_video chat tools that ship
  with the SenseAudio path.

* fix(senseaudio): address PR #2065 review feedback

Three non-blocking review notes from @PerishCode on PR #2065:

1. Drop the dead /api/byok-image/:id route. The PR description claimed
   it was "legacy fallback for old chat history" but that storage
   layout never existed on main, so the route can only ever 400 or
   404 — never 200. Removed the handler, the isSafeByokImageId
   export, the unused createReadStream / stat / path / Request /
   Response imports, and the two byok-image regression tests.

2. Add rejectProxyPluginContext guard to the senseaudio proxy
   handler so it matches the invariant the other five proxy paths
   already enforce (plugin runs must go through /api/runs for
   snapshot pinning). Extended the existing "API fallback rejects
   plugin runs" describe to also cover /api/proxy/senseaudio/stream
   with the 409 PLUGIN_REQUIRES_DAEMON expectation.

3. Wrap the secondary image / video downloads (the URLs the
   SenseAudio gateway hands back in /v1/image/sync .url and
   /v1/video/status .video_url) in validateBaseUrlResolved so a
   malicious gateway can't point us at 169.254.169.254 (AWS / Azure
   metadata) or RFC1918 hosts via the response payload. Also passed
   `redirect: 'error'` on both fetches to match the SSRF posture
   the primary proxy fetch already uses. The new
   assertExternalAssetUrl helper lives next to executeGenerateImage
   so future tool downloads can reuse it.

Tests: 120/120 daemon tests pass; guard + typecheck green.

* fix(senseaudio): mirror SSRF guard onto renderSenseAudioImage CLI path

Follow-up to 01b1260a — the chat-tool fix in byok-tools.ts wasn't
mirrored onto the parallel renderSenseAudioImage path in media.ts.
Same attacker-controllable shape (gateway-returned `data.url`),
same one-line fix.

- Hoist assertExternalAssetUrl from byok-tools.ts into
  connectionTest.ts next to validateBaseUrlResolved so both call
  sites (the BYOK chat tool loop AND the CLI agent media dispatcher)
  share one helper. Made the error strings provider-agnostic so a
  future caller doesn't get a misleading "senseaudio" attribution
  for a Volcengine / Grok / etc. download.
- renderSenseAudioImage now runs the response url through
  assertExternalAssetUrl before fetching bytes, and passes
  redirect: 'error' to block a 3xx hop into private space.

Scope intentionally limited to the senseaudio path PerishCode
flagged; the other unguarded fetch(entry.url) call sites in
media.ts (OpenAI / Volcengine / Grok / Nano-Banana) are pre-existing
patterns and belong in a separate follow-up if the daemon wants
defense-in-depth across every provider.

Tests: 127/127 daemon tests pass; guard + typecheck green.

---------

Co-authored-by: unknown <mazeliang@sensetime.com>
2026-05-19 23:14:56 +08:00
..
artifacts Fix pointer HTML artifact previews (#2075) 2026-05-18 18:28:28 +08:00
components [codex] Add global onboarding flow without AMR (#2272) 2026-05-19 22:00:40 +08:00
edit-mode Implement manual edit inspector (#1448) 2026-05-13 13:25:58 +08:00
hooks Fix finalize provider routing for Gemini BYOK (#1964) 2026-05-18 18:03:44 +08:00
i18n [codex] Add global onboarding flow without AMR (#2272) 2026-05-19 22:00:40 +08:00
lib Add desktop updater UI flow (#2270) 2026-05-19 21:36:51 +08:00
providers Add connector memory extraction flow (#2265) 2026-05-19 21:27:41 +08:00
runtime feat(senseaudio): BYOK chat with image + video generation tools (#2065) 2026-05-19 23:14:56 +08:00
state fix: support CODEX_API_KEY for Codex CLI (#1880) 2026-05-18 14:29:23 +08:00
styles fix(web): keep filter pill hover labels readable (#1828) 2026-05-15 23:07:43 +08:00
utils [codex] Add pet task center and desktop pet (#1833) 2026-05-19 15:38:39 +08:00
analytics-identity.test.ts feat(analytics): PostHog product analytics (P0 events, consent-gated, packaged) (#1428) 2026-05-12 22:32:42 +08:00
analytics-scrub.test.ts feat(analytics): PostHog product analytics (P0 events, consent-gated, packaged) (#1428) 2026-05-12 22:32:42 +08:00
api-attachment-context.test.ts Inline attached file context for BYOK chats (#1730) 2026-05-15 15:52:15 +08:00
App.test.ts fix(web): suppress autosave indicator for draft-only Connector key edits (#1232) 2026-05-11 20:52:45 +08:00
comments.test.ts [codex] Add visual draw annotation context (#1547) 2026-05-13 20:02:19 +08:00
host-boundary.test.ts refactor desktop host bridge (#2246) 2026-05-19 18:27:05 +08:00
quickSwitcherRecents.test.ts feat(web): add Cmd/Ctrl+P quick file switcher (#556) 2026-05-06 10:31:50 +08:00
router-marketplace.test.ts [codex] Add global onboarding flow without AMR (#2272) 2026-05-19 22:00:40 +08:00
router.test.ts Garnet hemisphere (#1702) 2026-05-14 21:12:50 +08:00
sidecar-proxy.test.ts Enable LAN web dev access (#1947) 2026-05-19 17:50:50 +08:00