Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/976250947_-riddle-theater.json
T

1 line
5.4 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "976250947/-riddle-theater", "files": {"src/config/llm-runtime.js": {"41966c53f6322ca1e3f93ca53212ccbb633c235a": {"t": 1785746670.4109046, "n": 3594, "h": "787c5c4bb018da7f", "c": "/**\n * Runtime LLM configuration used by the narrative engine.\n *\n * The frontend talks to an OpenAI-compatible chat-completions API, so DeepSeek\n * can be used by changing only the base URL, model and API key.\n */\n\nconst ENV = import.meta.env ?? {};\n\nfunction readBoolEnv(name, fallback = false) {\n const value = ENV[name];\n if (value === undefined || value === null || value === \"\") return fallback;\n return [\"1\", \"true\", \"yes\", \"on\"].includes(String(value).toLowerCase());\n}\n\nfunction readNumberEnv(name, fallback) {\n const value = Number(ENV[name]);\n return Number.isFinite(value) ? value : fallback;\n}\n\nconst envApiKey = String(ENV.VITE_LLM_API_KEY || ENV.VITE_DEEPSEEK_API_KEY || \"\").trim();\n\nexport const LLM_CONFIG = {\n enabled: readBoolEnv(\"VITE_LLM_ENABLED\", false),\n baseURL: String(ENV.VITE_LLM_BASE_URL || ENV.VITE_DEEPSEEK_BASE_URL || \"https://api.deepseek.com\").trim(),\n apiKey: envApiKey,\n model: String(ENV.VITE_LLM_MODEL || ENV.VITE_DEEPSEEK_MODEL || \"deepseek-chat\").trim(),\n timeout: readNumberEnv(\"VITE_LLM_TIMEOUT\", 30000),\n temperature: readNumberEnv(\"VITE_LLM_TEMPERATURE\", 0.85),\n maxTokens: readNumberEnv(\"VITE_LLM_MAX_TOKENS\", 800),\n stream: readBoolEnv(\"VITE_LLM_STREAM\", false)\n};\n\nexport const SYSTEM_PROMPT = `你是「谜语剧场(璋滆鍓у満)」的 AI 叙事引擎,负责为互动剧情游戏生成沉浸式中文文本。\n\n## 核心规则\n1. 只输出可直接展示给玩家的正文,不要输出 JSON、代码、系统说明或分析过程。\n2. 严格遵守 worldState,不要编造超出当前场景、人物关系和已知线索范围的新设定。\n3. 如果存在 sceneCard,它就是硬约束。地点、时间、氛围、关系阶段与剧情目标都不能越界。\n4. 玩家自由输入只能被吸收为当前场景内的自然反馈,不能直接跳章、跳场景或越过剧情节点。\n5. 只有 presentCharacters 中的角色可以在场发言或互动,offstageCharacters 只能被提及。\n6. 不要直接泄露 forbiddenReveals,也不要提前直白揭露 hiddenTruths。\n7. 角色语气、态度和情绪必须和当前好感、信任、警觉等关系状态一致。\n8. 全程使用简体中文,风格偏细腻、克制、电影化的第二人称叙事。\n9. 不要生成色情、仇恨或露骨暴力内容。\n\n## 输出长度\n- narrate: 2-4 段,约 150-300 字\n- explore: 1-2 段,约 80-150 字\n- dialogue: 1-2 段,约 80-200 字\n- recap: 3-5 段,约 200-400 字`;\n\nexport function buildExplorePrompt(worldState, actionText) {\n return `## 任务:explore\n玩家正在场景「${worldState.stageId}」中进行自由探索。\n\n### 玩家行动\n「${actionText}」\n\n### 世界状态\n${JSON.stringify(worldState, null, 2)}\n\n### 要求\n1. 描写玩家当下的探索反馈与感官发现。\n2. 可以暗示线索,但不能直接泄露 forbiddenReveals。\n3. 如存在 sceneCard,反馈必须停留在当前 scene 内。\n4. 保持当前场景氛围、角色关系与剧情节奏一致。`;\n}\n\nexport function buildDialoguePrompt(worldState, characterId, characterState, messageText) {\n return `## 任务:dialogue\n玩家正在场景「${worldState.stageId}」中与「${characterState.name}」对话。\n\n### 玩家说的话\n「${messageText}」\n\n### 对话角色状态\n- 角色 ID:${characterId}\n- 名称:${characterState.name}\n- 身份:${characterState.role}\n- 情绪:${characterState.mood}\n- 态度:${characterState.attitude || \"未标注\"}\n- 好感:${characterState.affinity}\n- 信任:${characterState.trust}\n- 警觉:${characterState.alertness}\n- 关系阶段:${characterState.relationshipStage}\n\n### 世界状态\n${JSON.stringify(worldState, null, 2)}\n\n### 要求\n1. 只输出 ${characterState.name} 的自然回应,不要附加解释。\n2. 语气必须符合当前关系值与情绪状态。\n3. 高警觉时更克制、更试探;高信任时可以更坦诚,但仍不能越过 forbiddenReveals。\n4. 如果存在 sceneCard,回答必须停留在该 scene 的边界内。\n5. 不允许让不在场角色突然发言,也不要直接推进到下一个 scene。`;\n}\n\nexport function buildNarratePrompt(worldState, context) {\n return `## 任务:narrate\n请在场景「${worldState.stageId}」中生成一段过渡叙事。\n\n### 上下文\n${context}\n\n### 世界状态\n${JSON.stringify(worldState, null, 2)}\n\n### 要求\n1. 使用第二人称、电影感叙事。\n2. 融合当前场景氛围、已知线索与角色状态。\n3. 如存在 sceneCard,叙事不得越界。\n4. 不要替玩家做决定,只负责铺陈与推进气氛。`;\n}\n\nexport function buildRecapPrompt(worldState, endingData, journeyFlags) {\n return `## 任务:recap\n请为玩家生成本局故事的结局回顾。\n\n### 结局信息\n- 结局 ID:${endingData.id}\n- 结局标题:${endingData.title}\n- 结局描述:${endingData.description}\n\n### 玩家旅程关键标记\n${JSON.stringify(journeyFlags, null, 2)}\n\n### 世界状态\n${JSON.stringify(worldState, null, 2)}\n\n### 要求\n1. 回顾玩家一路上的关键选择、关系变化与结果。\n2. 使用第二人称总结,保留一点余韵感。\n3. 可以对其他路线留下轻微暗示,但不要脱离当前世界状态。`;\n}\n"}}}}