feat(real-person): susciyuan virtual_character 真人渠道对接 + 自动分组路由 (Phase A) - #1175
Open
think-back wants to merge 11 commits into
Open
think-back wants to merge 11 commits into
think-back wants to merge 11 commits into
Conversation
Phase A (this deliverable): verification+routing+8-method provider, keyed by management id, verifiable via unit tests + live pre-verification path. Phase B (deferred): asset://<provider_asset_id> wire bridge via two-field scoped AssetBinding — its payoff needs a live human H5 flow (excluded from agreed acceptance) and bridging BytePlus-table real-person assets to the generalized pipeline is a separate design.
…date only Confirmed against origin/main: staging native BytePlus requires a callback base, so auto-routing already passes the gate and can select susciyuan once it is an automatic candidate — no callback relaxation needed (and a naive pre-selection probe would double-draw, Rule 11). Provider errors reuse existing AssetMaterializeFailure classes -> existing real_person.* keys, so no new i18n string; a task verifies this.
…ck + error mapping
… multipart upload
…roviderForChannel
…te set realPersonChannelIsAutomaticCandidate now delegates to realPersonProviderForChannel for non-native channels, so tokenspace_material and virtual_character (susciyuan) channels enter group-based random routing alongside native BytePlus. Prior rule excluded all explicit providers from the automatic pool. Pre-existing service-package failures (ResolveBytePlusAssetReferences*, DingTalk*, Recall*, AssetBinding*, Solana, Cache — 20 total) are present unchanged at the code-identical origin/main baseline (4ef3cd8f7) and lie outside this call graph.
…re gate realPersonAssetMultipartStore fell back to the GCS temp store only for tokenSpaceRealPersonProvider when a channel carries no explicit StorageCredentials. susciyuan (virtual_character) has the same shape, so portrait upload failed closed with a 503 before reaching the upstream. Admit both explicit providers via a type switch. Test appended to the existing byteplus_real_person_asset_test.go suite.
…explicit providers The three ChannelTypeBytePlus gates in lockBytePlusAssetPinnedChannel / validateBytePlusAssetPinnedLock reject any non-native channel that carries a pinned-asset lock. They are dormant on the production video-submit path (which routes through ResolveLegacyBytePlusAssetBindingReferences and never sets ContextKeyBytePlusAssetPinnedChannelID), but widen them anyway to accept DoubaoVideo real-person channels, mirroring selectBytePlusPinnedAssetChannel in middleware/distributor.go. Not on the hot path; additive, native behaviour unchanged.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目标
为 susciyuan(涑元智算,渠道 272,
asset_materialization.provider=virtual_character)接入真人素材(volc_real_person)对接,并让这类渠道进入自动分组随机路由,与原生 BytePlus、tokenspace_material 并存。对接方案参考 flatkey 既有真人 provider 抽象(native BytePlus / TokenSpace),新增第三个显式 provider。Phase A(本 PR 范围,已实现 + 已验证)
realPersonProvider实现virtualCharacterRealPersonProvider(service/virtual_character_real_person.go):CreateVisualValidateSession(POST 拿launch_urlH5 链接)/GetVisualValidateResult(轮询 succeeded/pending/failed → 复用既有AssetMaterializeFailure重试语义)。CreateAsset(io.Pipe 流式 multipart 上传本人肖像)/GetAsset/DeleteAsset/ListAssets,character_id作为UpstreamGroupId单键。LimitReader限流、HTTP 状态 → 错误分类(429→Throttled / 408→Timeout / 5xx→Upstream5xx / 4xx→Definitive)。{success,data,message,error:{code}},source_type校验为volc_real_person。realPersonChannelIsAutomaticCandidate改为对非原生渠道委托realPersonProviderForChannel,使 virtual_character / tokenspace_material 与 native BytePlus 一同进入随机池(此前显式 provider 被排除在自动池外)。realPersonProviderForChannel用switch派发virtual_character,保留"恰好一个启用 key"约束。realPersonAssetMultipartStore允许 virtual_character 走 GCS 回退(否则肖像上传在到达上游前就 503 fail-closed)。controller/relay.go三处ChannelTypeBytePluspinned-lock 闸门放宽接受 DoubaoVideo 真人渠道,镜像middleware/distributor.go的selectBytePlusPinnedAssetChannel(该路径在生产 video-submit 上休眠——走ResolveLegacyBytePlusAssetBindingReferences,从不设 pinned key;additive,原生行为不变)。AssetMaterializeFailure/error,用户可见文案沿用既有real_person.*key。测试:单测严格 TDD(provider 静态契约、状态映射、重定向阻断、HTTP 错误映射、会话创建/轮询、错误不泄漏 API Key、GetAsset/DeleteAsset、肖像 multipart 上传、显式 provider 进自动池、multipart 闸门放行 virtual_character)。全部新测试通过。
Phase B(不在本 PR)
asset://<provider_asset_id>线缆桥接(把生成请求里的asset://引用改写到上游真人素材 id)。它需要真人在 H5 完成人脸核验 + 上传肖像才能拿到provider_asset_id,无法在无真人参与下验证,故排除在本 PR 验收之外。生产真人「出片」在 Phase B 落地前不算完成。数据面(仅 staging)
渠道 272 的配置(
provider=virtual_character、单个启用 key、ability 行、enable status)只在 staging 应用,不动生产。验证情况
go vet ./service/... ./controller/...干净。main包因//go:embed web/classic/dist需先构建前端而失败,此为预存在、与本改动无关(baseline 同样失败)。./service/... ./middleware/... ./controller/...:本分支 62 失败 == 代码同一的 origin/main baseline(486d10394)62 失败,两集合逐字节相同,零新增回归。这些预存在失败均为环境依赖(本机缺完整 DB/env),不在本改动调用图内。🤖 Generated with Claude Code