Spaces:
Sleeping
Sleeping
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> | |
| <meta name="color-scheme" content="light dark" /> | |
| <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" /> | |
| <meta name="theme-color" content="#0b0b0c" media="(prefers-color-scheme: dark)" /> | |
| <title>OpenStoryline</title> | |
| <link rel="icon" type="image/png" href="/static/logo.png"> | |
| <link rel="stylesheet" href="/static/style.css" /> | |
| <script defer src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | |
| <script defer src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script> | |
| </head> | |
| <body class="sidebar-collapsed devbar-collapsed"> | |
| <!-- 左侧可收起侧边栏 --> | |
| <aside id="sidebar" class="sidebar collapsed" aria-label="侧边栏"> | |
| <div class="sidebar-inner"> | |
| <!-- 顶部固定区:永远不被挤压 --> | |
| <div class="sidebar-top"> | |
| <button id="sidebarToggle" class="sidebar-icon-btn" title="收起/展开侧边栏" aria-label="收起/展开侧边栏"> | |
| <svg viewBox="0 0 24 24" aria-hidden="true"> | |
| <path d="M4 7h16"></path> | |
| <path d="M4 12h16"></path> | |
| <path d="M4 17h16"></path> | |
| </svg> | |
| </button> | |
| <button id="createDialogBtn" class="sidebar-action primary" title="创建新对话" aria-label="创建新对话"> | |
| <span class="sidebar-action-icon">+</span> | |
| <span class="sidebar-action-text">创建新对话</span> | |
| </button> | |
| </div> | |
| <!-- 中间滚动区:长内容放这里 --> | |
| <div class="sidebar-scroll" id="sidebarScroll" aria-label="侧边栏滚动区"> | |
| <div id="sidebarModel" class="sidebar-model" aria-label="对话模型选择"> | |
| <div class="sidebar-model-label">对话模型</div> | |
| <select id="modelSelect" class="sidebar-model-select" aria-label="选择对话模型" data-os-persist="sidebar.model"></select> | |
| </div> | |
| <!-- 自定义模型配置(仅当选择“使用自定义模型”时显示) --> | |
| <div id="customModelBox" class="sidebar-panel hidden" aria-label="自定义模型配置"> | |
| <div class="sidebar-panel-title">自定义模型</div> | |
| <div class="sidebar-subtitle">LLM(对话/文案)</div> | |
| <input id="customLlmModel" class="sidebar-input" | |
| data-os-persist="sidebar.custom.llm.model" | |
| placeholder="模型名称,例如 deepseek-chat / gpt-4o-mini" /> | |
| <input id="customLlmBaseUrl" class="sidebar-input" | |
| data-os-persist="sidebar.custom.llm.base_url" | |
| placeholder="Base URL,例如 https://api.xxx.com/v1" /> | |
| <input id="customLlmApiKey" class="sidebar-input" type="password" | |
| data-os-persist="sidebar.custom.llm.api_key" | |
| placeholder="API Key" autocomplete="off" /> | |
| <div class="sidebar-divider"></div> | |
| <div class="sidebar-subtitle">VLM(素材理解)</div> | |
| <input id="customVlmModel" class="sidebar-input" | |
| data-os-persist="sidebar.custom.vlm.model" | |
| placeholder="模型名称,例如 qwen-vl-plus / gpt-4o" /> | |
| <input id="customVlmBaseUrl" class="sidebar-input" | |
| data-os-persist="sidebar.custom.vlm.base_url" | |
| placeholder="Base URL,例如 https://api.xxx.com/v1" /> | |
| <input id="customVlmApiKey" class="sidebar-input" type="password" | |
| data-os-persist="sidebar.custom.vlm.api_key" | |
| placeholder="API Key" autocomplete="off" /> | |
| <div class="sidebar-hint"> | |
| 提示:API Key 仅用于本会话的服务端调用;页面与 Tool trace 会自动脱敏,不会显示明文。 | |
| </div> | |
| </div> | |
| <!-- TTS 配置 --> | |
| <div id="ttsBox" class="sidebar-panel" aria-label="TTS 服务配置"> | |
| <div class="sidebar-panel-title">TTS 配置</div> | |
| <select id="ttsVendorSelect" | |
| class="sidebar-model-select" | |
| aria-label="选择 TTS 服务厂家" | |
| data-os-persist="sidebar.tts.vendor"> | |
| <option value="">不配置</option> | |
| <option value="bytedance">字节跳动</option> | |
| </select> | |
| <div id="ttsBytedanceFields" class="sidebar-tts-fields hidden" aria-label="字节跳动 TTS 参数"> | |
| <input id="ttsBytedanceUid" class="sidebar-input" | |
| data-os-persist="sidebar.tts.bytedance.uid" | |
| placeholder="uid" /> | |
| <input id="ttsBytedanceAppId" class="sidebar-input" | |
| data-os-persist="sidebar.tts.bytedance.appid" | |
| placeholder="appid" /> | |
| <input id="ttsBytedanceAccessToken" class="sidebar-input" type="password" | |
| data-os-persist="sidebar.tts.bytedance.access_token" | |
| placeholder="access_token" autocomplete="off" /> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- 主内容区(用于给 sidebar 留出空间) --> | |
| <div class="main"> | |
| <!-- 保留原有 topbar 结构(不破坏 JS),但 CSS 默认隐藏 --> | |
| <header class="topbar"> | |
| <div class="brand">OpenStoryline <span class="ver">v1.0.0</span></div> | |
| </header> | |
| <!-- 对话区 --> | |
| <main id="chat" class="chat" aria-live="polite"></main> | |
| <!-- 空白页标题(ChatGPT 风格):仅在 #chat 为空时显示(纯 CSS 控制) --> | |
| <section id="hero" class="hero" aria-hidden="true"> | |
| <h1 class="hero-title">🎬 你好,创作者!</h1> | |
| </section> | |
| <!-- Toast --> | |
| <div id="toast" class="toast hidden" role="status" aria-live="polite"></div> | |
| <!-- Scroll to bottom --> | |
| <button id="scrollToBottomBtn" class="scroll-bottom hidden" aria-label="滚动到底部" title="滚动到底部"> | |
| <svg viewBox="0 0 24 24" aria-hidden="true"> | |
| <path d="M12 5v14"></path> | |
| <path d="M7 14l5 5 5-5"></path> | |
| </svg> | |
| </button> | |
| <!-- 输入区 --> | |
| <footer class="composer" role="region" aria-label="消息输入区"> | |
| <input id="fileInput" class="file-input" type="file" multiple /> | |
| <div id="pendingBar" class="pending hidden" aria-label="待发送素材"> | |
| <div class="asset-bar-title">待发送素材</div> | |
| <div id="pendingRow" class="asset-row"></div> | |
| </div> | |
| <div class="composer-top"> | |
| <textarea | |
| id="promptInput" | |
| class="prompt" | |
| placeholder="提出任何剪辑需求(Enter 发送,shift + Enter 换行)" | |
| ></textarea> | |
| </div> | |
| <div class="composer-actions"> | |
| <button id="uploadBtn" class="icon-btn" title="上传素材" aria-label="上传素材"> | |
| <svg viewBox="0 0 24 24" aria-hidden="true"> | |
| <path d="M12 5v14M5 12h14"></path> | |
| </svg> | |
| </button> | |
| <div class="composer-actions-spacer"></div> | |
| <button id="sendBtn" class="send-btn" aria-label="发送"> | |
| <svg viewBox="0 0 24 24" aria-hidden="true"> | |
| <path d="M12 19V6"></path> | |
| <path d="M7 11l5-5 5 5"></path> | |
| </svg> | |
| </button> | |
| </div> | |
| </footer> | |
| <!-- 预览 Modal --> | |
| <div id="modal" class="modal hidden" aria-hidden="true"> | |
| <div class="modal-backdrop" id="modalBackdrop"></div> | |
| <div class="modal-body" role="dialog" aria-modal="true"> | |
| <button class="modal-close" id="modalClose" aria-label="关闭">×</button> | |
| <div class="modal-content" id="modalContent"></div> | |
| </div> | |
| </div> | |
| <!-- Tool UI 配置:必须在 app.js 之前 --> | |
| <script> | |
| window.OPENSTORYLINE_TOOL_UI = { | |
| labels: { | |
| "assets_index": "读取素材", | |
| "split_shots": "镜头切分", | |
| "filter_clips": "筛选片段", | |
| "understand_clips": "理解素材", | |
| "group_clips": "片段分组", | |
| "generate_script": "生成文案", | |
| "generate_voiceover": "生成配音", | |
| "select_bgm": "推荐背景音乐", | |
| "plan_timeline": "组织时间线", | |
| "render_video": "渲染视频", | |
| "split_shots_pro": "镜头切分—pro", | |
| "filter_clips_pro": "筛选片段—pro", | |
| "understand_clips_pro": "理解素材—pro", | |
| "group_clips_pro": "片段分组—pro", | |
| "generate_script_pro": "生成文案—pro", | |
| "elementrec_texts_pro": "推荐花字—pro", | |
| "elementrec_title_pro": "推荐标题—pro", | |
| "elementrec_global_effects_pro": "推荐全局特效—pro", | |
| "elementrec_local_effects_pro": "推荐局部特效—pro", | |
| "elementrec_close_effects_pro": "推荐闭幕特效—pro", | |
| "elementrec_filter_pro": "推荐滤镜—pro", | |
| "elementrec_transition_pro": "推荐转场—pro", | |
| "elementrec_text_animation_pro": "推荐花字动画—pro", | |
| "elementrec_title_clip_pro": "推荐片头—pro", | |
| "elementrec_tts_pro": "推荐配音音色—pro", | |
| "tts_service_pro": "生成配音—pro", | |
| "music_rec_service_pro": "推荐背景音乐—pro", | |
| "timeline_pro": "组织时间线—pro", | |
| "render_template_pro": "渲染视频—pro", | |
| "read_node_history": "读取详细结果", | |
| }, | |
| estimates_ms: { | |
| "storyline.assets_index": 1000 | |
| }, | |
| default_estimate_ms: 5000, | |
| tick_ms: 120, | |
| cap_running_progress: 0.99, | |
| hide_raw_tool_name: true, | |
| show_raw_tool_name_in_dev: true | |
| }; | |
| </script> | |
| <script type="module" src="/static/app.js"></script> | |
| </div> | |
| <!-- 右侧开发者侧边栏(仅 developer_mode=true 时由 JS 显示) --> | |
| <aside id="devbar" class="devbar hidden collapsed" aria-label="开发者侧边栏"> | |
| <div class="devbar-inner"> | |
| <button id="devbarToggle" class="devbar-icon-btn" title="收起/展开开发者侧边栏" aria-label="收起/展开开发者侧边栏"> | |
| <svg viewBox="0 0 24 24" aria-hidden="true"> | |
| <path d="M15 6l-6 6 6 6"></path> | |
| </svg> | |
| </button> | |
| <div class="devbar-title">Tool summary trace</div> | |
| <div class="devbar-sid" id="sidebarSid"></div> | |
| <div id="devLog" class="devbar-log" aria-label="工具 summary 输出"> | |
| <!-- JS 追加 summary --> | |
| </div> | |
| </div> | |
| </aside> | |
| </body> | |
| </html> | |