Skip to content

feat: split TokenSpace into a dedicated channel type - #1040

Open
think-back wants to merge 3 commits into
mainfrom
feat/tokenspace-real-person-channel-type
Open

think-back wants to merge 3 commits into
mainfrom
feat/tokenspace-real-person-channel-type

Conversation

@think-back

Copy link
Copy Markdown
Collaborator

Summary

  • Introduce ChannelTypeTokenSpace (114) so TokenSpace no longer relies on the legacy DoubaoVideo channel type (54).
  • Reuse the existing async Seedance task adaptor while making real-person provider, asset binding, pinned-channel validation, endpoint support, and model-sync behavior type-aware.
  • Add TokenSpace channel metadata, defaults, icon/locale entries, and regression coverage for both default and classic consoles.

Compatibility and rollout

  • Existing DoubaoVideo channels with explicit tokenspace_material configuration remain supported.
  • This PR does not include a database schema migration and does not mutate production channel 106.
  • If channel 106 is migrated after deployment, change only its channel type from 54 to 114 after backing up/freezing traffic; preserve its keys, settings, models, groups, and channel ID, then refresh/restart channel caches.
  • Ordinary asset materialization for the new type still requires explicit tokenspace_material configuration.

Validation

  • go test -vet=off ./constant -count=1 -buildvcs=false -timeout=30s
  • Targeted compiled service tests for TokenSpace endpoint gating, real-person creation/provider selection, and legacy compatibility
  • bun test src/features/channels/constants.test.ts src/features/channels/lib/channel-form.test.ts (default console)
  • bun test src/components/table/channels/modals/modelapi-seedance-classic.test.js (classic console)
  • bun run build for both web/default and web/classic

The full go test ./service package suite was not used as the gate because unrelated Windows file-lock/process behavior prevents that package-wide run in this worktree; the focused service test binary and compile completed successfully.

Keep the existing channel records and explicit material provider path intact while giving new TokenSpace channels a stable type boundary.\n\nConstraint: Existing persisted channel types and 106 production configuration must remain compatible.\nRejected: Channel-ID special cases | They preserve the coupling this split is meant to remove.\nConfidence: high\nScope-risk: moderate\nDirective: Retain the legacy explicit tokenspace_material path until existing channels are migrated deliberately.\nTested: git diff --check and design self-review.\nNot-tested: Implementation behavior is pending.
Sequence the compatibility-preserving type registration, provider boundary, and console updates behind failing tests.\n\nConstraint: The existing DoubaoVideo and explicit tokenspace_material records must remain runnable without migration.\nRejected: One broad untested refactor | It obscures regressions across routing, provider selection, and two frontends.\nConfidence: high\nScope-risk: moderate\nDirective: Keep RED and GREEN checkpoints separate and do not deploy from this worktree.\nTested: git diff --check and plan self-review.\nNot-tested: Implementation tests are pending.
…nel type

Keep legacy DoubaoVideo records intact while giving new TokenSpace channels their own routing, provider, asset-binding, and console semantics.

Constraint: Preserve existing channel 106 records without database migration or production mutation.

Rejected: Copying a second Seedance adaptor or hardcoding channel IDs | the protocol and provider boundary are reusable by type.

Confidence: high

Scope-risk: moderate

Directive: Keep ordinary TokenSpace asset materialization explicit and retain the legacy Doubao provider path.

Tested: targeted Go tests for type, endpoint, provider, assets, pinned routing, polling keys, and Responses isolation; default/classic Bun tests and builds; default typecheck; locale JSON parse; git diff --check.

Not-tested: full service suite times out on existing Windows/SQLite parallel-test contention; classic i18n lint was unavailable because the required bunx dependency could not be resolved.
@KingCesc

KingCesc commented Sep 2, 2026

Copy link
Copy Markdown

🤖 OpenCodeReview · 评审 commit 6a4d6c25 · 共 2 条

service/asset_binding.go

  • L327-333: [严重] 这里直接短路到 rewriteMapForChannel(channel, nil) 会绕过原来按 bindingScope 选择绑定的逻辑。对于同一资产在同一 TokenSpace 渠道上存在多个 active binding 的迁移/回收场景,activeAssetReferenceBindingForChannel 可能返回任意一个绑定,进而把请求重写到错误的 upstream 资源,造成渲染结果错误。建议继续走下面的 scope-aware 分支,或至少在这里补充对 bindingScope/target 的一致性校验。
if independentTokenSpaceLegacyRealPersonReferencesReady(set, channel) {
	// 保持与下面一致的 scope-aware 绑定选择逻辑,避免选到错误的 active binding。
}

service/asset_reference.go

  • L840-842: [严重] 这里把 TokenSpace 的普通资产可用性直接交给了 channelCanConsumeAssetType,但该函数在 ChannelTypeTokenSpace 分支里始终返回 false。结果是:即使该 TokenSpace 渠道已经配置了 tokenspace_material 明确材质化能力,preparationReadinessForChannel / readinessForChannelScope / targetReadinessForChannel 也会在这里提前判定为不可用,导致新渠道类型无法通过普通图片/视频/音频资产的就绪判断。建议这里显式兼容 assetMaterializationConfigForChannel 的 TokenSpace material provider,或保留对已配置材质化能力的 asset type 放行逻辑。
func assetReferenceCanUseChannel(asset assetReferenceAsset, channel *model.Channel) bool {
	if channel == nil {
		return false
	}
	if channelCanConsumeAssetType(channel, asset.AssetType) {
		return true
	}
	config, explicit, err := assetMaterializationConfigForChannel(channel)
	if err == nil && explicit && config.Provider == assetMaterializationProviderTokenSpaceMaterial {
		return asset.AssetType == "Image" || asset.AssetType == "Video" || asset.AssetType == "Audio"
	}
	return legacyRealPersonAssetCanUseChannel(asset, channel)
}

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