feat(identity): web metadata enrichment for titles missing on TMDB (META-1)
- metadata.enrich (propose, low, replay safe): normalized-title cache (kv_cache
region enrich, 7 days) -> daily budget -> web.search (title + 短剧 / 电视剧 平台,
second query limited to whitelist via site:) -> web.fetch of up to 3 relevant
whitelisted pages (registered site domains never read, redirects out of the
whitelist dropped) -> upstream model extraction with rule fallback -> server-side
evidence check (rule_confirmed / multi_evidence / needs_review). Suggestion only.
- POST /identity-pool/{id}/enrich (suggest) and /enrich/apply (console session):
provisional entity or same-title merge, season/episode units, field-level
metadata with source web/agent + evidence, aliases, release assignment.
Poster proxy GET /img/enrich/{id} (og:image from whitelisted pages only).
- Auto-enrich once per pool entry when subscription/rule lookups find nothing on
TMDB (identity.autoEnrich, off by default); identity.enrichDailyBudget,
identity.enrichDomains settings; web.fetch now returns og:image.
- Pool sheet "元数据补全" section; entity detail shows evidence links.
- Migration 0049_enrichment (metadata_enrichment, metadata_field.evidence, source
web). Requires image rebuild / api + worker restart to take effect.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
18a5cf1de7
commit
f4666a4671
36 files changed
+2514
-25
No files matched your search
@@ -390,10 +390,45 @@ export type SearchSettings = z.infer<typeof SearchSettings>;
|
||||
* (识别缓存命中则 0 次);一个每小时 100 条的 RSS 约为每天 2400–7200 次 TMDB 请求,多数是站点独有的短剧 / 综艺,查不到。
|
||||
* 关闭(缺省)时只在命中订阅 / 本地作品别名、已发布的新作品收录规则前置条件通过、用户手动识别或搜索时查询。
|
||||
*/
|
||||
/** 元数据补全缺省白名单:视频平台、短剧平台、百科 / 影视资料站(不含任何 PT 站) */
|
||||
export const DEFAULT_ENRICH_DOMAINS: string[] = [
|
||||
"baike.baidu.com",
|
||||
"douban.com",
|
||||
"hongguoduanju.com",
|
||||
"wikipedia.org",
|
||||
"iqiyi.com",
|
||||
"v.qq.com",
|
||||
"youku.com",
|
||||
"mgtv.com",
|
||||
"bilibili.com",
|
||||
"douyin.com",
|
||||
"kuaishou.com",
|
||||
"ixigua.com",
|
||||
"baike.sogou.com",
|
||||
"mydramalist.com",
|
||||
];
|
||||
|
||||
export const IdentitySettings = z.object({
|
||||
eagerTmdbLookup: z.boolean(),
|
||||
/** 待识别池里 unmatched 条目多少天没有新证据就归档(仍可按状态筛出、可手动指定) */
|
||||
poolArchiveDays: z.number().int().min(1).max(3650),
|
||||
/**
|
||||
* META-1:订阅别名 / 新作品收录规则命中、TMDB 却查不到时自动尝试一次元数据补全(只出建议,不建作品)。
|
||||
* 每次约 1–2 次网页搜索 + 最多 3 次读取网页 + 1 次模型调用。
|
||||
*/
|
||||
autoEnrich: z.boolean(),
|
||||
/** 元数据补全每日上限(手动 + 自动;命中 7 天标题缓存不计);0 = 停用补全 */
|
||||
enrichDailyBudget: z.number().int().min(0).max(500),
|
||||
/** 元数据补全只读取这些域名(含子域名)的网页:平台站点、百科类;已登记站点的域名一律不读 */
|
||||
enrichDomains: z
|
||||
.array(
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.regex(/^[a-z0-9.-]+\.[a-z]{2,}$/),
|
||||
)
|
||||
.max(100),
|
||||
});
|
||||
export type IdentitySettings = z.infer<typeof IdentitySettings>;
|
||||
|
||||
@@ -483,7 +518,13 @@ export const DEFAULT_SETTINGS: GlobalSettings = {
|
||||
defaultDetailCacheSec: 86400,
|
||||
},
|
||||
naming: { ...DEFAULT_NAMING_TEMPLATES, lockFileNameForBound: false },
|
||||
identity: { eagerTmdbLookup: false, poolArchiveDays: 30 },
|
||||
identity: {
|
||||
eagerTmdbLookup: false,
|
||||
poolArchiveDays: 30,
|
||||
autoEnrich: false,
|
||||
enrichDailyBudget: 20,
|
||||
enrichDomains: DEFAULT_ENRICH_DOMAINS,
|
||||
},
|
||||
search: { defaultSiteMode: "default", siteIds: [] },
|
||||
};
|
||||
|
||||
@@ -738,6 +779,9 @@ export const SETTINGS_SECTIONS: readonly SettingsSectionDef[] = [
|
||||
"cache.emptyResultTtlSec",
|
||||
"identity.eagerTmdbLookup",
|
||||
"identity.poolArchiveDays",
|
||||
"identity.autoEnrich",
|
||||
"identity.enrichDailyBudget",
|
||||
"identity.enrichDomains",
|
||||
"cache.globalImageCache",
|
||||
"cache.globalImageCacheDays",
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user