Skip to content

feat: implement OpenAI-compatible video generation features and settings#1637

Merged
zerob13 merged 4 commits into
devfrom
gen-video
May 18, 2026
Merged

feat: implement OpenAI-compatible video generation features and settings#1637
zerob13 merged 4 commits into
devfrom
gen-video

Conversation

@zhangmo8
Copy link
Copy Markdown
Collaborator

@zhangmo8 zhangmo8 commented May 18, 2026

link #1237

7cec2776174d6242bb05686942e75531

Summary by CodeRabbit

  • New Features

    • Added OpenAI-compatible video generation support, enabling users to generate videos from text prompts with configurable options (size, duration, ratio, resolution, watermark, audio generation).
    • Implemented video message display component with video player controls.
    • Added automatic video duration inference from prompt text hints (e.g., "5s").
    • Extended UI with dedicated video generation settings panel.
  • Localization

    • Added multi-language support across 15+ languages for video generation features.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64497284-8d95-4b65-9fb8-740c652468b9

📥 Commits

Reviewing files that changed from the base of the PR and between 4e163c1 and cf4e262.

📒 Files selected for processing (4)
  • docs/issues/merge-dev-into-gen-video/plan.md
  • docs/issues/merge-dev-into-gen-video/spec.md
  • docs/issues/merge-dev-into-gen-video/tasks.md
  • src/main/presenter/agentRuntimePresenter/index.ts
✅ Files skipped from review due to trivial changes (3)
  • docs/issues/merge-dev-into-gen-video/tasks.md
  • docs/issues/merge-dev-into-gen-video/spec.md
  • docs/issues/merge-dev-into-gen-video/plan.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/presenter/agentRuntimePresenter/index.ts

📝 Walkthrough

Walkthrough

This PR implements first-class OpenAI-compatible video generation as a new model capability in DeepChat. It extends the existing image-generation and TTS frameworks to support Seedance and other video-capable providers through /v1/videos endpoints, adding model-type detection, session persistence, runtime execution with prompt-driven duration parsing, and comprehensive renderer UI with settings fields and video playback across 14 localized interfaces.

Changes

OpenAI-Compatible Video Generation

Layer / File(s) Summary
Feature specification and planning documents
docs/features/openai-compatible-video-generation/*, docs/issues/openai-compatible-video-prompt-duration-fallback/*, docs/issues/merge-dev-into-gen-video/*
Feature plan, spec, and task checklists defining scope, acceptance criteria, and validation steps for video generation and prompt duration fallback. Merge documentation for branch integration.
Shared contracts and video generation settings module
src/shared/contracts/common.ts, src/shared/contracts/domainSchemas.ts, src/shared/videoGenerationSettings.ts
VideoGenerationOptionsSchema with Zod validation; SessionGenerationSettings and ModelConfigSchema extended with videoGeneration field; comprehensive settings module with modelId-based detection, OpenAI-compatible provider support checks, and request-body shape resolution.
Model type inference and endpoint routing
src/main/presenter/configPresenter/*, src/shared/model.ts, src/shared/types/model-db.ts
Video-generation-compatible type detection via modelId patterns; ModelType enum and NEW_API_ENDPOINT_TYPES extended; routing resolvers handle video-generation models; model-db parser recognizes videoGeneration variants.
Session settings persistence and SQLite schema migration
src/main/presenter/sqlitePresenter/tables/deepchatSessions.ts
Schema version bump to 28 with video_generation_options_json column; recovery ALTER TABLE logic and migration path; serialization helpers; session operations persist and retrieve videoGeneration settings.
Agent runtime context budget and generation settings handling
src/main/presenter/agentRuntimePresenter/index.ts
Context-budget bypass includes VideoGeneration model-type checks; videoGeneration normalized into default session settings; included in per-request modelConfig; sanitization/patching during settings updates.
OpenAI-compatible video generation runtime execution
src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
Prompt duration parsing (English/Chinese patterns, model constraints); request normalization (base URL, reference URLs); flat-top-level and extra-body request builders; polling-based task execution with abort awareness; binary download and image_data event streaming.
Provider routing and standalone video generation API
src/main/presenter/llmProviderPresenter/index.ts, src/main/presenter/llmProviderPresenter/providers/aiSdkProvider.ts
Video-generation route decision and model config patching; shouldUseVideoGeneration runtime hook; model discovery classifies video-type models; generateVideoStandalone method with rate limiting, streaming collection, and result normalization.
Renderer model detection, type tracking, and draft store management
src/renderer/src/composables/useModelTypeDetection.ts, src/renderer/src/stores/modelStore.ts, src/renderer/src/stores/ui/draft.ts
isVideoGenerationModel computed flag; model type resolved via resolveRendererModelType; draft store adds videoGeneration state with normalization and wiring into generation settings flows.
Chat UI and dialog components for video generation settings
src/renderer/src/components/chat/ChatStatusBar.vue, src/renderer/src/components/ChatConfig.vue, src/renderer/src/components/settings/ModelConfigDialog.vue
OpenAIVideoGenerationSettingsFields panel with media-gated visibility; advanced settings switch to combined media-generation gating; video generation config persisted in model config dialog; system-prompt clearing extended for videoGeneration.
Video settings fields component and message rendering
src/renderer/src/components/settings/OpenAIVideoGenerationSettingsFields.vue, src/renderer/src/components/message/MessageBlockVideo.vue, src/renderer/src/components/message/MessageItemAssistant.vue
Settings fields component renders video parameters with normalization; MessageBlockVideo displays video with controls and error handling; MessageItemAssistant adds video block detection and VIDEO_EXTENSIONS constant.
Model filtering UI and draft defaults cleanup
src/renderer/settings/components/ProviderModelList.vue, src/renderer/src/pages/NewThreadPage.vue
TYPE_ORDER and TYPE_ICONS extended for VideoGeneration filter; videoGeneration cleared in draft defaults on agent switch.
Internationalization across 14 locales
src/renderer/src/i18n/{da-DK,en-US,fa-IR,fr-FR,he-IL,ja-JP,ko-KR,pt-BR,ru-RU,zh-CN,zh-HK,zh-TW}/{model,settings}.json
videoGeneration added to type filter options, model type selectors, API endpoint labels, endpoint type labels, and complete settings block labels/placeholders across all 14 languages.
Unit and integration tests
test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts, test/main/presenter/llmProviderPresenter/aihubmixProvider.test.ts, test/renderer/components/message/MessageItemAssistant.test.ts
Prompt duration parsing tests (unsupported/supported); Seedance model routing verification; video block detection and classification tests.
Type declarations and public presenter API exports
src/shared/types/presenters/*, src/shared/types/agent-interface.d.ts
StandaloneVideoGenerationResult exported; ILlmProviderPresenter extended with generateVideoStandalone; videoGeneration added to ModelConfig and SessionGenerationSettings.
Standalone video generation entry point adapter
src/main/presenter/index.ts
agentToolRuntime adapter exposes generateVideoStandalone alongside generateImageStandalone.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1591: Parallel image generation implementation extending the same OpenAI-compatible generation-settings pipeline and AI SDK streaming runtime layer.
  • ThinkInAIXYZ/deepchat#1365: Modifies ChatStatusBar.vue advanced settings gating and capability-driven normalization logic that this PR extends to include media-generation gating.
  • ThinkInAIXYZ/deepchat#1443: Adds NewAPI endpoint-type mapping foundation in src/shared/model.ts that this PR extends with video-generation handling.

Suggested reviewers

  • zerob13

🎥 A Rabbit's Video Tale
From pixels frozen, life now flows—
The burrow streams, the carrot glows,
Generation speaks in frames so swift,
In /v1/videos, a speedy gift,
Where hops and hues in seconds gleam,
Hop along the video dream! 🐰✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gen-video

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/presenter/agentRuntimePresenter/index.ts (1)

3327-3350: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

videoGeneration is missing from persistence methods, causing settings to not be saved.

Both buildPersistedGenerationSettingsPatch and buildPersistedGenerationSettingsReplacement include imageGeneration but omit videoGeneration. This means video generation settings will be normalized and applied in-memory but never persisted to the database when updating or replacing session settings.

🐛 Proposed fix to add videoGeneration to persistence
   if (Object.prototype.hasOwnProperty.call(requestedPatch, 'imageGeneration')) {
     patch.imageGeneration = sanitized.imageGeneration
   }
+  if (Object.prototype.hasOwnProperty.call(requestedPatch, 'videoGeneration')) {
+    patch.videoGeneration = sanitized.videoGeneration
+  }

   return patch
 }

 private buildPersistedGenerationSettingsReplacement(
   settings: SessionGenerationSettings
 ): Partial<SessionGenerationSettings> {
   return {
     systemPrompt: settings.systemPrompt,
     temperature: settings.temperature,
     contextLength: settings.contextLength,
     maxTokens: settings.maxTokens,
     timeout: settings.timeout,
     thinkingBudget: settings.thinkingBudget,
     reasoningEffort: settings.reasoningEffort,
     reasoningVisibility: settings.reasoningVisibility,
     verbosity: settings.verbosity,
     forceInterleavedThinkingCompat: settings.forceInterleavedThinkingCompat,
-    imageGeneration: settings.imageGeneration
+    imageGeneration: settings.imageGeneration,
+    videoGeneration: settings.videoGeneration
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/agentRuntimePresenter/index.ts` around lines 3327 - 3350,
The replacement and patch builders omit videoGeneration so those settings never
persist; update both buildPersistedGenerationSettingsReplacement and
buildPersistedGenerationSettingsPatch to include the videoGeneration property in
their returned Partial<SessionGenerationSettings> objects (mirror how
imageGeneration is handled) so normalized videoGeneration is written to the
database on update/replace.
🧹 Nitpick comments (2)
src/shared/contracts/common.ts (1)

64-69: ⚖️ Poor tradeoff

Consider adding format validation for video parameter strings.

The seconds, size, ratio, and resolution fields accept arbitrary strings without format constraints. Depending on provider API requirements, you might want to add validation patterns or enums for expected formats (e.g., ratio: z.enum(['16:9', '9:16', '4:3']) or regex patterns for resolution like /^\d+x\d+$/).

This would catch configuration errors earlier and provide better type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/contracts/common.ts` around lines 64 - 69, The string fields
seconds, size, ratio and resolution currently accept any string; update their
Zod schemas to enforce expected formats (e.g., use z.enum for known ratios like
ratio: z.enum(['16:9','9:16','4:3']) or z.string().regex(/^\d+x\d+$/) for
resolution, and appropriate regexes for seconds and size such as numeric or
unit-suffixed patterns) so invalid formats are rejected early; modify the schema
definitions where seconds, size, ratio and resolution are declared to replace
z.string().optional() with the stricter z.enum(...) or
z.string().regex(...).optional() variants and keep duration and watermark
validation unchanged.
src/shared/videoGenerationSettings.ts (1)

284-285: ⚡ Quick win

Avoid duplicating model ID prefix checks.

The hardcoded check modelId.startsWith('doubao-seedance-') duplicates the prefix already defined in VIDEO_GENERATION_MODEL_ID_PREFIXES (line 64). This creates a maintenance burden where changes to the prefix list must be synchronized in two places.

Consider checking if the modelId matches any prefix in FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS or create a separate constant for flat-top-level model ID patterns to keep the logic DRY.

♻️ Suggested refactor
+const FLAT_TOP_LEVEL_VIDEO_MODEL_ID_PREFIXES = ['doubao-seedance-'] as const
+
 const FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS = ['aihubmix'] as const

Then update the check:

   if (
     FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS.some(
       (hint) =>
         providerId.includes(hint) ||
         providerApiType.includes(hint) ||
         providerKind.includes(hint) ||
         providerOptionsKey.includes(hint) ||
         baseUrl.includes(hint)
-    )
+    ) ||
+    FLAT_TOP_LEVEL_VIDEO_MODEL_ID_PREFIXES.some((prefix) => modelId.startsWith(prefix))
   ) {
     return 'flat-top-level'
   }
-
-  if (modelId.startsWith('doubao-seedance-')) {
-    return 'flat-top-level'
-  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/videoGenerationSettings.ts` around lines 284 - 285, The code
currently uses a hardcoded startsWith('doubao-seedance-') check; replace that
duplication by checking the modelId against the existing prefix collection
instead. Update the condition in the function that references modelId to test
whether any prefix in FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS (or, if more
appropriate, a new constant e.g. FLAT_TOP_LEVEL_MODEL_ID_PREFIXES) is a prefix
of modelId rather than the literal string; use Array.prototype.some(...) over
the prefix list or keys to decide the branch so maintenance relies on a single
source of truth (referencing VIDEO_GENERATION_MODEL_ID_PREFIXES /
FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS and modelId).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts`:
- Around line 1023-1032: The fetchBinary function is leaking provider
credentials by always adding Authorization and defaultHeaders to requests for
arbitrary task.url; change fetchBinary (and the similar block at the other
location around lines ~1076-1080) to only attach Authorization
(provider.oauthToken || provider.apiKey) and provider-specific defaultHeaders
when the download URL is on the provider’s origin/host (compare new
URL(task.url).host or origin against provider.baseUrl/provider.origin/host),
otherwise send a minimal fetch with no Authorization and only necessary CORS
headers; keep using controller.signal and dispatcher as before (symbols:
fetchBinary, task.url, defaultHeaders, provider.oauthToken, provider.apiKey,
controller.signal, dispatcher).
- Around line 997-1001: The polling helper creates a local AbortController
(controller/timeoutId) but never composes it with a caller-provided AbortSignal,
so caller cancellation doesn't stop the background polling; modify the helper
(the function that builds controller/timeoutId and uses proxyUrl/dispatcher) to
accept an optional caller AbortSignal parameter, wire the caller signal into the
local controller by adding a listener that calls controller.abort() (and remove
the listener during cleanup), ensure the local timeout still aborts as before,
pass controller.signal to all fetch/stream calls, clear the timeoutId and remove
the listener when finished, and apply the same change to the analogous block
around lines 1066-1073.

In `@src/main/presenter/llmProviderPresenter/providers/aiSdkProvider.ts`:
- Around line 1714-1718: The branch that classifies models as
ModelType.VideoGeneration (the normalizedRawType checks around
ModelType.VideoGeneration) is not mirrored in the provider config sync in
fetchNewApiModels(), which still maps non-image/TTS models to
ApiEndpointType.Chat; update fetchNewApiModels() (the provider-managed config
sync) to detect video-generation models using the same
normalizedRawType/supportedEndpointTypes logic and set apiEndpoint to
'video-generation' (or the corresponding ApiEndpointType) when assigning model
metadata so persisted models have matching type, endpointType, and apiEndpoint.

In `@src/renderer/src/components/message/MessageBlockVideo.vue`:
- Around line 17-18: videoError in MessageBlockVideo.vue remains true after a
single failure and isn't cleared when the video source changes; add logic to
reset it whenever a new source is set or successfully loads. In
MessageBlockVideo.vue, reset the data property videoError to false when the
bound src prop changes (add a watcher for the prop used for :src) and/or clear
videoError on a successful load event (e.g., handle `@loadedmetadata` or `@canplay`
to set videoError = false); ensure the existing `@error` listener still sets
videoError = true. Update any methods that swap sources to also set videoError =
false before switching so stale error UI can't appear after a successful source
change.
- Around line 42-58: The hardcoded English fallbacks in keyMap cause user-facing
strings to bypass i18n; remove those literal values and make the code return the
i18n keys when no translation exists. Specifically, remove or change keyMap
entries ('keyMap') so they do not contain "Video" or "Request failed", ensure
the i18n fallback in the immediately-invoked function that returns useI18n().t
(symbol: i18n) returns the input key (identity) on error, and update
translate(key) to return the key when translated === key (instead of
keyMap[key]) so rendering remains fully key-based and driven by vue-i18n
(symbols: translate, i18n, useI18n).
- Around line 28-30: The current v-else branch in MessageBlockVideo.vue always
renders a loading spinner (Icon "lucide:loader-2") when no media data exists,
causing an endless loader for failed/cancelled blocks; update the render logic
to check the block/message terminal state (e.g., a status prop like "failed" or
"cancelled" or message.status) before showing the spinner and render a terminal
view instead—use a failure icon/text and optional retry/cancel UI when status is
failed/cancelled, otherwise keep the spinner for in-progress states; locate the
conditional around the loader (the v-else that renders Icon) and replace it with
an explicit status check that chooses between loading, failed/cancelled, and
empty states.

In `@src/renderer/src/components/message/MessageItemAssistant.vue`:
- Around line 246-258: isVideoBlock currently only looks at block.image_data and
uses includes() on URLs which can false-positive; update isVideoBlock (operating
on DisplayAssistantMessageBlock / MessageBlockVideo) to also check legacy
payloads like block.content for mimeType, data, or url, and when inspecting URL
paths convert to lowercase and check the pathname or filename (not the whole
URL) for video extensions using VIDEO_EXTENSIONS with a strict endsWith or exact
extension match rather than includes; also preserve the existing mimeType/data
checks (data:video/ and video/*) and ensure null-safe access to both image_data
and content fields.

In `@src/renderer/src/i18n/da-DK/settings.json`:
- Around line 466-467: Several newly added strings in the Danish locale remain
in English; update the JSON values for the keys such as "video",
"videoGeneration" and the API-related option labels ("apiEndpoint", "apiType" or
equivalent keys used for endpoint/type options) plus the other recently added
entries so they are translated to Danish, keeping the original JSON keys intact
and matching the style/phrasing used elsewhere in the da-DK file to ensure a
consistent Danish UI.

In `@src/renderer/src/i18n/fa-IR/settings.json`:
- Line 533: The Persian locale file contains new English strings for the
video-generation UI (e.g., the "video" key currently set to "Video Generation"
and other keys added around the same area at lines noted), so replace those
English values with their Persian translations for the corresponding keys
(update the "video" key and all newly added video-generation keys between the
same block — the group around lines 547 and 615–644) so the settings UI is fully
localized; locate the keys in src/renderer/src/i18n/fa-IR/settings.json (search
for "video" and the surrounding new keys) and provide proper Persian
translations for each user-facing string.

In `@src/renderer/src/i18n/fr-FR/settings.json`:
- Line 533: The French locale file still contains English values for the
video-generation UI labels — replace the English strings with French
translations for the JSON keys in that section (e.g., "video": "Video
Generation" and the other keys in the same block around lines 533, 547 and
615-644); do not change the property names (keys), only update their values to
idiomatic French (e.g., "Video Generation" → "Génération de vidéo" and similarly
translate placeholders/descriptions for the related keys) and keep JSON syntax
intact.

In `@src/renderer/src/i18n/he-IL/settings.json`:
- Line 533: The Hebrew locale file src/renderer/src/i18n/he-IL/settings.json
contains new English strings (e.g., the "video" key with value "Video
Generation" and other user-facing strings added around the same region) and must
be replaced with proper Hebrew translations; locate the affected keys ("video"
and the contiguous keys introduced at the same block around lines 547 and
615-644) and substitute each English value with an accurate Hebrew translation,
preserving any placeholders, punctuation, and JSON quoting/escaping exactly as
in the originals so keys like "video" and the related setting labels/tooltips
remain intact and properly localized.

In `@src/renderer/src/i18n/ja-JP/settings.json`:
- Line 533: The ja-JP settings file contains English text in the Video
Generation section (the "video" key and its neighboring video-generation keys);
replace those English values with appropriate Japanese translations so the
settings panel is fully localized (update the "video" value and all adjacent
video-generation string values that mirror the en-US keys), keeping the JSON
keys identical to the source language and preserving encoding/escaping.

In `@src/renderer/src/i18n/ko-KR/settings.json`:
- Line 533: The ko-KR settings JSON contains English labels that must be
localized: replace the value for the "video" key (currently "Video Generation")
and any other English strings found in the same file ranges (around the keys
present at the blocks near lines 547 and 615–644) with their proper Korean
translations, preserving the JSON keys and punctuation; update only the string
values so the UI no longer mixes English and Korean.

In `@src/renderer/src/i18n/pt-BR/settings.json`:
- Line 533: The pt-BR locale still contains English strings in the
video-generation block: replace the value for the "video" key ("Video
Generation") and all other English strings in the same block (the
video-generation section around the subsequent entries) with correct Portuguese
(pt-BR) translations, keeping the JSON keys unchanged and preserving
punctuation/formatting; locate the block by the "video" key and the surrounding
video-generation entries and update their values to proper pt-BR text.

In `@src/renderer/src/i18n/ru-RU/settings.json`:
- Line 533: The ru-RU locale file contains English text for the new
video-generation entries (e.g., the "video" key currently set to "Video
Generation" and other recently added keys around that block); update the string
values for those keys to their correct Russian translations while leaving the
JSON keys intact, preserving any placeholders/formatting (quotes, interpolation
tokens) and punctuation; locate the same block of keys near "video" and the
adjacent entries that were added (the other strings mentioned in the review) and
replace their English values with Russian equivalents, validate the JSON syntax
after edits.

In `@test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts`:
- Around line 561-663: The tests in aiSdkRuntime.test.ts are waiting real time
between mocked poll responses because the runAiSdkCoreStream poll loop uses
VIDEO_GENERATION_POLL_INTERVAL_MS; replace the real wait by installing fake
timers (e.g., vi.useFakeTimers()/jest.useFakeTimers()) or stubbing the internal
delay used by runAiSdkCoreStream so the submitted->completed transition is
advanced deterministically (advance timers or resolve the stubbed delay) before
collecting events; locate the test block using runAiSdkCoreStream and references
to VIDEO_GENERATION_POLL_INTERVAL_MS and ensure timers are restored/cleared
after the test to avoid cross-test pollution.

---

Outside diff comments:
In `@src/main/presenter/agentRuntimePresenter/index.ts`:
- Around line 3327-3350: The replacement and patch builders omit videoGeneration
so those settings never persist; update both
buildPersistedGenerationSettingsReplacement and
buildPersistedGenerationSettingsPatch to include the videoGeneration property in
their returned Partial<SessionGenerationSettings> objects (mirror how
imageGeneration is handled) so normalized videoGeneration is written to the
database on update/replace.

---

Nitpick comments:
In `@src/shared/contracts/common.ts`:
- Around line 64-69: The string fields seconds, size, ratio and resolution
currently accept any string; update their Zod schemas to enforce expected
formats (e.g., use z.enum for known ratios like ratio:
z.enum(['16:9','9:16','4:3']) or z.string().regex(/^\d+x\d+$/) for resolution,
and appropriate regexes for seconds and size such as numeric or unit-suffixed
patterns) so invalid formats are rejected early; modify the schema definitions
where seconds, size, ratio and resolution are declared to replace
z.string().optional() with the stricter z.enum(...) or
z.string().regex(...).optional() variants and keep duration and watermark
validation unchanged.

In `@src/shared/videoGenerationSettings.ts`:
- Around line 284-285: The code currently uses a hardcoded
startsWith('doubao-seedance-') check; replace that duplication by checking the
modelId against the existing prefix collection instead. Update the condition in
the function that references modelId to test whether any prefix in
FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS (or, if more appropriate, a new constant
e.g. FLAT_TOP_LEVEL_MODEL_ID_PREFIXES) is a prefix of modelId rather than the
literal string; use Array.prototype.some(...) over the prefix list or keys to
decide the branch so maintenance relies on a single source of truth (referencing
VIDEO_GENERATION_MODEL_ID_PREFIXES / FLAT_TOP_LEVEL_VIDEO_PROVIDER_HINTS and
modelId).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 16793bd6-fa59-4351-81ea-33a8e9de5876

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8816d and 60099cd.

📒 Files selected for processing (62)
  • docs/features/openai-compatible-video-generation/plan.md
  • docs/features/openai-compatible-video-generation/spec.md
  • docs/features/openai-compatible-video-generation/tasks.md
  • docs/issues/openai-compatible-video-prompt-duration-fallback/plan.md
  • docs/issues/openai-compatible-video-prompt-duration-fallback/spec.md
  • docs/issues/openai-compatible-video-prompt-duration-fallback/tasks.md
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/configPresenter/modelConfig.ts
  • src/main/presenter/configPresenter/providerModelHelper.ts
  • src/main/presenter/index.ts
  • src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/providers/aiSdkProvider.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatSessions.ts
  • src/renderer/settings/components/ProviderModelList.vue
  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/chat/messageListItems.ts
  • src/renderer/src/components/message/MessageBlockVideo.vue
  • src/renderer/src/components/message/MessageItemAssistant.vue
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/renderer/src/components/settings/OpenAIVideoGenerationSettingsFields.vue
  • src/renderer/src/composables/useModelTypeDetection.ts
  • src/renderer/src/i18n/da-DK/model.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/en-US/model.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/fa-IR/model.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/model.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/model.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/ja-JP/model.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/model.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/pt-BR/model.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/model.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/zh-CN/model.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/model.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/model.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/pages/NewThreadPage.vue
  • src/renderer/src/stores/modelStore.ts
  • src/renderer/src/stores/ui/draft.ts
  • src/shared/contracts/common.ts
  • src/shared/contracts/domainSchemas.ts
  • src/shared/model.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/types/model-db.ts
  • src/shared/types/presenters/index.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/shared/videoGenerationSettings.ts
  • test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts
  • test/main/presenter/llmProviderPresenter/aihubmixProvider.test.ts

Comment thread src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
Comment thread src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
Comment thread src/main/presenter/llmProviderPresenter/providers/aiSdkProvider.ts
Comment thread src/renderer/src/components/message/MessageBlockVideo.vue
Comment thread src/renderer/src/components/message/MessageBlockVideo.vue
Comment thread src/renderer/src/i18n/ja-JP/settings.json
Comment thread src/renderer/src/i18n/ko-KR/settings.json
Comment thread src/renderer/src/i18n/pt-BR/settings.json
Comment thread src/renderer/src/i18n/ru-RU/settings.json
Comment thread test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts
zhangmo8 and others added 3 commits May 18, 2026 17:56
* fix(agent): bypass chat budget for image routes (#1636)

* Initial plan

* merge(gen-video): resolve agent runtime conflict

Agent-Logs-Url: https://github.com/ThinkInAIXYZ/deepchat/sessions/7c9b17d6-272d-44a2-ab2d-57a554c773ab

Co-authored-by: zhangmo8 <43628500+zhangmo8@users.noreply.github.com>

---------

Co-authored-by: duskzhen <zerob13@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
@zerob13 zerob13 merged commit 4da79f8 into dev May 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants