Merge pull request 'hermes/visual-novel-genarrative' (#18) from hermes/visual-novel-genarrative into master
Reviewed-on: #18
This commit was merged in pull request #18.
This commit is contained in:
@@ -224,11 +224,23 @@ pub(crate) fn build_visual_novel_creation_user_prompt(
|
||||
"currentDraft": params.current_draft,
|
||||
"recentMessages": params.recent_messages,
|
||||
"nowIso": params.now_iso,
|
||||
"oneLineGenerationFlow": [
|
||||
"提取一句话核心创意、故事类型、玩家身份和视觉画风",
|
||||
"扩展世界观、故事前提、文学风格和默认叙事语气",
|
||||
"设计 3 到 6 个角色,并为每个角色写出可生成立绘的 appearance",
|
||||
"设计 3 到 8 个场景,并为 opening 场景写出可生成背景图的 description",
|
||||
"组织 3 到 6 个剧情阶段,第一阶段必须能从 opening 进入",
|
||||
"生成 opening.narration、可选 firstDialogue 和 2 到 4 个 initialChoices",
|
||||
"图片、音乐可先为 null,但文字草稿必须可进入结果页编辑、保存并试玩"
|
||||
],
|
||||
"draftRequirements": {
|
||||
"mainCharacters": "3 到 6 个,至少 1 个非玩家主要角色",
|
||||
"scenes": "3 到 8 个,至少 1 个 opening 场景",
|
||||
"storyPhases": "3 到 6 个,第一阶段可从 opening 进入",
|
||||
"initialChoices": "2 到 4 个",
|
||||
"initialChoices": "2 到 4 个 initialChoices",
|
||||
"openingScene": "opening.sceneId 必须指向存在且 availability 为 opening 的 scene",
|
||||
"firstPhase": "storyPhases[0] 必须包含 opening scene 和主要角色",
|
||||
"assetFallback": "图片、音乐可先为 null,但 appearance 和 scene description 必须足够后续生成资产",
|
||||
"runtimeConfigDefaults": "沿用契约默认值,attributePanelMode 默认为 off"
|
||||
},
|
||||
"outputContract": VISUAL_NOVEL_CREATION_OUTPUT_CONTRACT
|
||||
@@ -616,6 +628,29 @@ mod tests {
|
||||
assert!(repair_prompt.contains("scene_change"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_prompt_guides_one_line_flow_into_playable_draft() {
|
||||
let asset_ids = source_asset_ids();
|
||||
let prompt = build_visual_novel_creation_user_prompt(VisualNovelCreationPromptParams {
|
||||
source_mode: "idea",
|
||||
seed_text: Some(
|
||||
"雨夜旧图书馆里,失忆高中生发现一本会回应心声的日记。\n视觉画风:映画动画\n画风要求:电影感动画视觉小说画风。",
|
||||
),
|
||||
source_asset_ids: asset_ids.as_slice(),
|
||||
document_summary: None,
|
||||
current_draft: None,
|
||||
recent_messages: &[],
|
||||
now_iso: "2026-05-13T12:00:00Z",
|
||||
});
|
||||
|
||||
assert!(prompt.contains("oneLineGenerationFlow"));
|
||||
assert!(prompt.contains("提取一句话核心创意"));
|
||||
assert!(prompt.contains("视觉画风"));
|
||||
assert!(prompt.contains("opening.sceneId"));
|
||||
assert!(prompt.contains("2 到 4 个 initialChoices"));
|
||||
assert!(prompt.contains("图片、音乐可先为 null"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn llm_requests_use_responses_template_model() {
|
||||
let asset_ids = source_asset_ids();
|
||||
|
||||
@@ -1409,6 +1409,12 @@ fn build_public_work_like_id(source_type: &str, profile_id: &str, user_id: &str)
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn duplicate_tracking_event_ids_are_treated_as_idempotent_replays() {
|
||||
assert!(should_skip_existing_tracking_event_id(true));
|
||||
assert!(!should_skip_existing_tracking_event_id(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recent_public_work_play_counts_group_requested_profiles_in_window() {
|
||||
let now_micros = PUBLIC_WORK_PLAY_DAY_MICROS * 10;
|
||||
@@ -3223,6 +3229,10 @@ fn record_daily_login_tracking_event(ctx: &ReducerContext, user_id: &str) -> Res
|
||||
)
|
||||
}
|
||||
|
||||
fn should_skip_existing_tracking_event_id(event_exists: bool) -> bool {
|
||||
event_exists
|
||||
}
|
||||
|
||||
fn record_tracking_event(
|
||||
ctx: &ReducerContext,
|
||||
input: RuntimeTrackingEventInput,
|
||||
@@ -3242,6 +3252,15 @@ fn record_tracking_event(
|
||||
.map_err(|error| error.to_string())?;
|
||||
let occurred_at = Timestamp::from_micros_since_unix_epoch(validated_input.occurred_at_micros);
|
||||
let day_key = runtime_profile_beijing_day_key(validated_input.occurred_at_micros);
|
||||
if should_skip_existing_tracking_event_id(
|
||||
ctx.db
|
||||
.tracking_event()
|
||||
.event_id()
|
||||
.find(&validated_input.event_id)
|
||||
.is_some(),
|
||||
) {
|
||||
return Ok(());
|
||||
}
|
||||
// 中文注释:埋点事实与日期维表使用同一北京时间业务日桶,先幂等补齐维表,避免后续周/月/季/年聚合缺少 bucket 映射。
|
||||
ensure_analytics_date_dimension_row(ctx, day_key)?;
|
||||
ctx.db.tracking_event().insert(TrackingEvent {
|
||||
|
||||
Reference in New Issue
Block a user