فهرست منبع

refactor: move interactive menu to agent/cli

Talegorithm 3 روز پیش
والد
کامیت
f44bf24485
100فایلهای تغییر یافته به همراه348 افزوده شده و 20 حذف شده
  1. 11 0
      agent/cli/__init__.py
  2. 290 0
      agent/cli/interactive.py
  3. 2 2
      agent/core/prompts/knowledge.py
  4. 8 0
      agent/core/runner.py
  5. 3 0
      agent/docs/knowledge.md
  6. 13 13
      agent/llm/openrouter.py
  7. 8 1
      agent/tools/schema.py
  8. 13 4
      agent/trace/models.py
  9. 0 0
      examples/archive/analyze_story/README.md
  10. 0 0
      examples/archive/analyze_story/analysis_results.json
  11. 0 0
      examples/archive/analyze_story/analyze_samples.py
  12. 0 0
      examples/archive/analyze_story/generate_report.py
  13. 0 0
      examples/archive/analyze_story/input/中国合伙人.pdf
  14. 0 0
      examples/archive/analyze_story/input/大奉打更人.txt
  15. 0 0
      examples/archive/analyze_story/input/搜神记.txt
  16. 0 0
      examples/archive/analyze_story/input/无双.docx
  17. 0 0
      examples/archive/analyze_story/input/雪中悍刀行.txt
  18. 0 0
      examples/archive/analyze_story/input/魔道祖师.txt
  19. 0 0
      examples/archive/analyze_story/knowledge/01_Scene_Sequel_Structure.md
  20. 0 0
      examples/archive/analyze_story/knowledge/01_save_the_cat_beat_sheet.md
  21. 0 0
      examples/archive/analyze_story/knowledge/01_scene_sequel_theory.md
  22. 0 0
      examples/archive/analyze_story/knowledge/01_叙事理论综述.md
  23. 0 0
      examples/archive/analyze_story/knowledge/02_MICE_Quotient.md
  24. 0 0
      examples/archive/analyze_story/knowledge/02_MICE_quotient_theory.md
  25. 0 0
      examples/archive/analyze_story/knowledge/03_Save_the_Cat_Beats.md
  26. 0 0
      examples/archive/analyze_story/knowledge/03_web_novel_techniques.md
  27. 0 0
      examples/archive/analyze_story/knowledge/04_Web_Novel_Theory.md
  28. 0 0
      examples/archive/analyze_story/knowledge/04_save_the_cat_beats.md
  29. 0 0
      examples/archive/analyze_story/knowledge/05_AI_narrative_generation.md
  30. 0 0
      examples/archive/analyze_story/knowledge/05_Integrated_Methodology.md
  31. 0 0
      examples/archive/analyze_story/knowledge/07_Methodology_Analysis.md
  32. 0 0
      examples/archive/analyze_story/knowledge/1_scene_sequel_theory.md
  33. 0 0
      examples/archive/analyze_story/knowledge/samples_overview.md
  34. 0 0
      examples/archive/analyze_story/methodology/README.md
  35. 0 0
      examples/archive/analyze_story/methodology/v2_improved_methodology.md
  36. 0 0
      examples/archive/analyze_story/read_all_files.py
  37. 0 0
      examples/archive/analyze_story/read_samples.py
  38. 0 0
      examples/archive/analyze_story/read_txt_files.py
  39. 0 0
      examples/archive/analyze_story/run.py
  40. 0 0
      examples/archive/analyze_story/runs/搜神记/analysis/w0.error.txt
  41. 0 0
      examples/archive/analyze_story/runs/搜神记/analysis/w0.json
  42. 0 0
      examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/stats.json
  43. 0 0
      examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task1_structure_planning.jsonl
  44. 0 0
      examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task2_scene_continuation.jsonl
  45. 0 0
      examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task3_shuang_injection.jsonl
  46. 0 0
      examples/archive/analyze_story/samples_data.json
  47. 0 0
      examples/archive/analyze_story/sft/README.md
  48. 0 0
      examples/archive/analyze_story/sft/run_pipeline.py
  49. 0 0
      examples/archive/analyze_story/sft/step1_analyze.py
  50. 0 0
      examples/archive/analyze_story/sft/step2_build_sft.py
  51. 0 0
      examples/archive/analyze_story/test.prompt
  52. 0 0
      examples/archive/analyze_story/一周执行计划.md
  53. 0 0
      examples/archive/analyze_story/拆解示例_大奉打更人第1-2章.md
  54. 0 0
      examples/archive/deep_research/input/1.jpeg
  55. 0 0
      examples/archive/deep_research/input/1_invariant_features.json
  56. 0 0
      examples/archive/deep_research/input/3.jpeg
  57. 0 0
      examples/archive/deep_research/input/3_invariant_features.json
  58. 0 0
      examples/archive/deep_research/input/7.jpeg
  59. 0 0
      examples/archive/deep_research/input/7_invariant_features.json
  60. 0 0
      examples/archive/deep_research/input/《秋日际遇》写生油画.json
  61. 0 0
      examples/archive/deep_research/production.prompt
  62. 0 0
      examples/archive/deep_research/run.py
  63. 0 0
      examples/archive/feature_extract/input_1/feature.md
  64. 0 0
      examples/archive/feature_extract/input_1/image.png
  65. 0 0
      examples/archive/feature_extract/run.py
  66. 0 0
      examples/archive/feature_extract/test.prompt
  67. 0 0
      examples/archive/how/README.md
  68. 0 0
      examples/archive/how/analyze_images.py
  69. 0 0
      examples/archive/how/encode_images.py
  70. 0 0
      examples/archive/how/features/images_b64.json
  71. 0 0
      examples/archive/how/features/img1_b64.txt
  72. 0 0
      examples/archive/how/features/img2_b64.txt
  73. 0 0
      examples/archive/how/features/img3_b64.txt
  74. 0 0
      examples/archive/how/features/img4_b64.txt
  75. 0 0
      examples/archive/how/features/img5_b64.txt
  76. 0 0
      examples/archive/how/features/img6_b64.txt
  77. 0 0
      examples/archive/how/features/img7_b64.txt
  78. 0 0
      examples/archive/how/features/img8_b64.txt
  79. 0 0
      examples/archive/how/features/img9_b64.txt
  80. 0 0
      examples/archive/how/features/thumb_1.jpg
  81. 0 0
      examples/archive/how/features/thumb_2.jpg
  82. 0 0
      examples/archive/how/features/thumb_3.jpg
  83. 0 0
      examples/archive/how/features/thumb_4.jpg
  84. 0 0
      examples/archive/how/features/thumb_5.jpg
  85. 0 0
      examples/archive/how/features/thumb_6.jpg
  86. 0 0
      examples/archive/how/features/thumb_7.jpg
  87. 0 0
      examples/archive/how/features/thumb_8.jpg
  88. 0 0
      examples/archive/how/features/thumb_9.jpg
  89. 0 0
      examples/archive/how/input/1.jpeg
  90. 0 0
      examples/archive/how/input/1_invariant_features.json
  91. 0 0
      examples/archive/how/input/3.jpeg
  92. 0 0
      examples/archive/how/input/3_invariant_features.json
  93. 0 0
      examples/archive/how/input/7.jpeg
  94. 0 0
      examples/archive/how/input/7_invariant_features.json
  95. 0 0
      examples/archive/how/input/set_invariant_features.json
  96. 0 0
      examples/archive/how/input/《秋日际遇》写生油画.json
  97. 0 0
      examples/archive/how/load_imgs.py
  98. 0 0
      examples/archive/how/presets.json
  99. 0 0
      examples/archive/how/production.prompt
  100. 0 0
      examples/archive/how/resource/input_cloud_archive/《秋日际遇》写生油画.json

+ 11 - 0
agent/cli/__init__.py

@@ -0,0 +1,11 @@
+"""
+CLI 工具模块
+
+提供交互式控制等 CLI 相关功能。
+"""
+
+from .interactive import InteractiveController
+
+__all__ = [
+    "InteractiveController",
+]

+ 290 - 0
agent/cli/interactive.py

@@ -0,0 +1,290 @@
+"""
+交互式控制器
+
+提供暂停/继续、交互式菜单、经验总结等功能。
+"""
+
+import sys
+import asyncio
+from typing import Optional, Dict, Any
+from pathlib import Path
+
+from agent.core.runner import AgentRunner
+from agent.trace import TraceStore
+
+
+# ===== 非阻塞 stdin 检测 =====
+
+if sys.platform == 'win32':
+    import msvcrt
+
+
+def check_stdin() -> Optional[str]:
+    """
+    跨平台非阻塞检查 stdin 输入。
+
+    Windows: 使用 msvcrt.kbhit()
+    macOS/Linux: 使用 select.select()
+
+    Returns:
+        'pause' | 'quit' | None
+    """
+    if sys.platform == 'win32':
+        # Windows: 检查是否有按键按下
+        if msvcrt.kbhit():
+            ch = msvcrt.getwch().lower()
+            if ch == 'p':
+                return 'pause'
+            if ch == 'q':
+                return 'quit'
+        return None
+    else:
+        # Unix/Mac: 使用 select
+        import select
+        ready, _, _ = select.select([sys.stdin], [], [], 0)
+        if ready:
+            line = sys.stdin.readline().strip().lower()
+            if line in ('p', 'pause'):
+                return 'pause'
+            if line in ('q', 'quit'):
+                return 'quit'
+        return None
+
+
+def read_multiline() -> str:
+    """
+    读取多行输入,以连续两次回车(空行)结束。
+
+    Returns:
+        用户输入的多行文本
+    """
+    print("\n请输入干预消息(连续输入两次回车结束):")
+    lines = []
+    blank_count = 0
+
+    while True:
+        line = input()
+        if line == "":
+            blank_count += 1
+            if blank_count >= 2:
+                break
+            lines.append("")  # 保留单个空行
+        else:
+            blank_count = 0
+            lines.append(line)
+
+    # 去掉尾部多余空行
+    while lines and lines[-1] == "":
+        lines.pop()
+
+    return "\n".join(lines)
+
+
+# ===== 交互式控制器 =====
+
+class InteractiveController:
+    """
+    交互式控制器
+
+    管理暂停/继续、交互式菜单、经验总结等交互功能。
+    """
+
+    def __init__(
+        self,
+        runner: AgentRunner,
+        store: TraceStore,
+        enable_stdin_check: bool = True
+    ):
+        """
+        初始化交互式控制器
+
+        Args:
+            runner: Agent Runner 实例
+            store: Trace Store 实例
+            enable_stdin_check: 是否启用 stdin 检查
+        """
+        self.runner = runner
+        self.store = store
+        self.enable_stdin_check = enable_stdin_check
+
+    def check_stdin(self) -> Optional[str]:
+        """
+        检查 stdin 输入
+
+        Returns:
+            'pause' | 'quit' | None
+        """
+        if not self.enable_stdin_check:
+            return None
+        return check_stdin()
+
+    async def show_menu(
+        self,
+        trace_id: str,
+        current_sequence: int
+    ) -> Dict[str, Any]:
+        """
+        显示交互式菜单
+
+        Args:
+            trace_id: Trace ID
+            current_sequence: 当前消息序号
+
+        Returns:
+            用户选择的操作
+        """
+        print("\n" + "=" * 60)
+        print("  执行已暂停")
+        print("=" * 60)
+        print("请选择操作:")
+        print("  1. 插入干预消息并继续")
+        print("  2. 触发经验总结(reflect)")
+        print("  3. 查看当前 GoalTree")
+        print("  4. 手动压缩上下文(compact)")
+        print("  5. 继续执行")
+        print("  6. 停止执行")
+        print("=" * 60)
+
+        while True:
+            choice = input("请输入选项 (1-6): ").strip()
+
+            if choice == "1":
+                # 插入干预消息
+                text = read_multiline()
+                if not text:
+                    print("未输入任何内容,取消操作")
+                    continue
+
+                print(f"\n将插入干预消息并继续执行...")
+                # 从 store 读取实际的 last_sequence
+                live_trace = await self.store.get_trace(trace_id)
+                actual_sequence = live_trace.last_sequence if live_trace and live_trace.last_sequence else current_sequence
+
+                return {
+                    "action": "continue",
+                    "messages": [{"role": "user", "content": text}],
+                    "after_sequence": actual_sequence,
+                }
+
+            elif choice == "2":
+                # 触发经验总结
+                print("\n触发经验总结...")
+                focus = input("请输入反思重点(可选,直接回车跳过): ").strip()
+                await self.perform_reflection(trace_id, focus=focus)
+                continue
+
+            elif choice == "3":
+                # 查看 GoalTree
+                goal_tree = await self.store.get_goal_tree(trace_id)
+                if goal_tree and goal_tree.goals:
+                    print("\n当前 GoalTree:")
+                    print(goal_tree.to_prompt())
+                else:
+                    print("\n当前没有 Goal")
+                continue
+
+            elif choice == "4":
+                # 手动压缩上下文
+                await self.manual_compact(trace_id)
+                continue
+
+            elif choice == "5":
+                # 继续执行
+                print("\n继续执行...")
+                return {"action": "continue"}
+
+            elif choice == "6":
+                # 停止执行
+                print("\n停止执行...")
+                return {"action": "stop"}
+
+            else:
+                print("无效选项,请重新输入")
+
+    async def perform_reflection(
+        self,
+        trace_id: str,
+        focus: str = ""
+    ):
+        """
+        执行经验总结
+
+        Args:
+            trace_id: Trace ID
+            focus: 反思重点(可选)
+        """
+        from agent.core.prompts.knowledge import build_reflect_prompt
+        from agent.core.runner import RunConfig
+
+        trace = await self.store.get_trace(trace_id)
+        if not trace:
+            print("未找到 Trace")
+            return
+
+        saved_head = trace.head_sequence
+
+        # 构建反思 prompt
+        prompt = build_reflect_prompt()
+        if focus:
+            prompt += f"\n\n请特别关注:{focus}"
+
+        print("正在生成反思...")
+        reflect_cfg = RunConfig(trace_id=trace_id, max_iterations=1, tools=[])
+
+        try:
+            result = await self.runner.run_result(
+                messages=[{"role": "user", "content": prompt}],
+                config=reflect_cfg,
+            )
+            reflection_text = result.get("summary", "")
+
+            if reflection_text:
+                print("\n--- 反思内容 ---")
+                print(reflection_text)
+                print("--- 结束 ---\n")
+            else:
+                print("未生成反思内容")
+
+        finally:
+            # 恢复 head_sequence(反思消息成为侧枝,不污染主对话)
+            await self.store.update_trace(trace_id, head_sequence=saved_head)
+
+    async def manual_compact(self, trace_id: str):
+        """
+        手动压缩上下文
+
+        Args:
+            trace_id: Trace ID
+        """
+        from agent.core.runner import RunConfig
+
+        print("\n正在执行上下文压缩(compact)...")
+
+        try:
+            goal_tree = await self.store.get_goal_tree(trace_id)
+            trace = await self.store.get_trace(trace_id)
+
+            if not trace:
+                print("未找到 Trace,无法压缩")
+                return
+
+            # 重建当前 history
+            main_path = await self.store.get_main_path_messages(trace_id, trace.head_sequence)
+            history = [msg.to_llm_dict() for msg in main_path]
+            head_seq = main_path[-1].sequence if main_path else 0
+            next_seq = head_seq + 1
+
+            compact_config = RunConfig(trace_id=trace_id)
+            new_history, new_head, new_seq = await self.runner._compress_history(
+                trace_id=trace_id,
+                history=history,
+                goal_tree=goal_tree,
+                config=compact_config,
+                sequence=next_seq,
+                head_seq=head_seq,
+            )
+
+            print(f"\n✅ 压缩完成: {len(history)} 条消息 → {len(new_history)} 条")
+
+        except Exception as e:
+            print(f"\n❌ 压缩失败: {e}")

+ 2 - 2
agent/core/prompts/knowledge.py

@@ -47,7 +47,7 @@ REFLECT_PROMPT = """请回顾以上执行过程,将值得沉淀的经验直接
    - 一个知识可以关联多个资源,如:`resource_ids=["code/selenium/login", "credentials/website_a"]`
 
 **注意**:
-- 只保存最有价值的经验,宁少勿滥;一次就成功或比较简单的经验就不要记录了,记录反复尝试或被用户指导后才成功的经验。
+- 只保存最有价值的经验,宁少勿滥;一次就成功或比较简单的经验就不要记录了,记录反复尝试或被用户指导后才成功的经验、或者是调研之后的收获
 - 不需要输出任何文字,直接调用工具即可
 - 如果没有值得保存的经验,不调用任何工具
 """
@@ -88,7 +88,7 @@ COMPLETION_REFLECT_PROMPT = """请对整个任务进行复盘,将值得沉淀
    - 然后在 `knowledge_save` 中通过 `secure_resource_id` 关联
 
 **注意**:
-- 只保存最有价值的经验,宁少勿滥;一次就成功或比较简单的经验就不要记录了,记录反复尝试或被用户指导后才成功的经验。
+- 只保存最有价值的经验,宁少勿滥;一次就成功或比较简单的经验就不要记录了,记录反复尝试或被用户指导后才成功的经验、或者是调研之后的收获
 - 不需要输出任何文字,直接调用工具即可
 - 如果没有值得保存的经验,不调用任何工具
 """

+ 8 - 0
agent/core/runner.py

@@ -890,6 +890,7 @@ class AgentRunner:
                     tc.get("function", {}).get("name") == "goal"
                     for tc in tool_calls
                 )
+                logger.debug(f"[Auto Root Goal] goal_tree.goals={len(goal_tree.goals)}, has_goal_call={has_goal_call}, tool_calls={[tc.get('function', {}).get('name') for tc in tool_calls]}")
                 if not has_goal_call:
                     mission = goal_tree.mission
                     root_desc = mission[:200] if len(mission) > 200 else mission
@@ -903,6 +904,8 @@ class AgentRunner:
                         await self.trace_store.add_goal(trace_id, goal_tree.goals[0])
                         await self.trace_store.update_goal_tree(trace_id, goal_tree)
                     logger.info(f"自动创建 root goal: {goal_tree.goals[0].id}")
+                else:
+                    logger.debug(f"[Auto Root Goal] 检测到 goal 工具调用,跳过自动创建")
 
             # 获取当前 goal_id
             current_goal_id = goal_tree.current_id if (goal_tree and goal_tree.current_id) else None
@@ -996,6 +999,11 @@ class AgentRunner:
                         if config.knowledge.default_search_owner and "owner" not in tool_args:
                             tool_args["owner"] = config.knowledge.default_search_owner
 
+                    # 记录工具调用(INFO 级别,显示参数)
+                    args_str = json.dumps(tool_args, ensure_ascii=False)
+                    args_display = args_str[:100] + "..." if len(args_str) > 100 else args_str
+                    logger.info(f"[Tool Call] {tool_name}({args_display})")
+
                     tool_result = await self.tools.execute(
                         tool_name,
                         tool_args,

+ 3 - 0
agent/docs/knowledge.md

@@ -1,3 +1,5 @@
+- 产生知识时区分:人、场景(例如飞书群,可以对应到tags)、业务(还有子业务)
+
 **知识结构**(单条知识)
     id: 知识唯一标识
     task: 任务描述,什么场景、在做什么
@@ -14,6 +16,7 @@
         category: 子类别(如 preference, background, habit, constraint)
         domain: 领域(如 coding_style, architecture)
         其他自定义标签
+        scenario
 
     scopes: 可见范围(可有多个,格式:{entity_type}:{entity_id})
         user:{user_id}:用户级(个人可见)

+ 13 - 13
agent/llm/openrouter.py

@@ -480,7 +480,7 @@ async def _openrouter_anthropic_call(
 
     # Resolve model name for OpenRouter (e.g. "claude-sonnet-4.5" → "anthropic/claude-sonnet-4-5-20250929")
     resolved_model = _resolve_openrouter_model(model)
-    logger.info("[OpenRouter/Anthropic] model: %s → %s", model, resolved_model)
+    logger.debug("[OpenRouter/Anthropic] model: %s → %s", model, resolved_model)
 
     # 跨 Provider 续跑时,重写不兼容的 tool_call_id 为 toolu_ 前缀
     messages = _normalize_tool_call_ids(messages, "toolu")
@@ -512,20 +512,20 @@ async def _openrouter_anthropic_call(
         payload["temperature"] = kwargs["temperature"]
 
     # Debug: 检查 cache_control 是否存在
-    cache_control_count = 0
-    if isinstance(system_prompt, list):
-        for block in system_prompt:
-            if isinstance(block, dict) and "cache_control" in block:
-                cache_control_count += 1
-    for msg in anthropic_messages:
-        content = msg.get("content", "")
-        if isinstance(content, list):
-            for block in content:
+    if logger.isEnabledFor(logging.DEBUG):
+        cache_control_count = 0
+        if isinstance(system_prompt, list):
+            for block in system_prompt:
                 if isinstance(block, dict) and "cache_control" in block:
                     cache_control_count += 1
-    if cache_control_count > 0:
-        print(f"[OpenRouter/Anthropic] 发现 {cache_control_count} 个 cache_control 标记")
-        logger.info(f"[OpenRouter/Anthropic] 发现 {cache_control_count} 个 cache_control 标记")
+        for msg in anthropic_messages:
+            content = msg.get("content", "")
+            if isinstance(content, list):
+                for block in content:
+                    if isinstance(block, dict) and "cache_control" in block:
+                        cache_control_count += 1
+        if cache_control_count > 0:
+            logger.debug(f"[OpenRouter/Anthropic] 发现 {cache_control_count} 个 cache_control 标记")
 
     headers = {
         "Authorization": f"Bearer {api_key}",

+ 8 - 1
agent/tools/schema.py

@@ -187,6 +187,13 @@ class SchemaGenerator:
         if python_type in cls.TYPE_MAP:
             return {"type": cls.TYPE_MAP[python_type]}
 
+        # 检查是否是 Protocol(如 ToolContext)
+        # Protocol 类型用于依赖注入,不应出现在 schema 中
+        type_name = getattr(python_type, "__name__", str(python_type))
+        if "Protocol" in str(type(python_type)) or type_name in ("ToolContext",):
+            logger.debug(f"Skipping Protocol type {python_type} (used for dependency injection)")
+            return {}
+
         # 默认为 string
-        logger.warning(f"Unknown type {python_type}, defaulting to string")
+        logger.debug(f"Unknown type {python_type}, defaulting to string")
         return {"type": "string"}

+ 13 - 4
agent/trace/models.py

@@ -356,12 +356,21 @@ class Message:
                 if content.get("tool_calls"):
                     tool_calls = content["tool_calls"]
                     if isinstance(tool_calls, list):
-                        tool_names = []
+                        tool_descriptions = []
                         for tc in tool_calls:
                             if isinstance(tc, dict) and tc.get("function", {}).get("name"):
-                                tool_names.append(tc["function"]["name"])
-                        if tool_names:
-                            return f"tool call: {', '.join(tool_names)}"
+                                tool_name = tc["function"]["name"]
+                                # 提取参数并截断到 100 字符
+                                tool_args = tc["function"].get("arguments", "{}")
+                                if isinstance(tool_args, str):
+                                    args_str = tool_args
+                                else:
+                                    import json
+                                    args_str = json.dumps(tool_args, ensure_ascii=False)
+                                args_display = args_str[:100] + "..." if len(args_str) > 100 else args_str
+                                tool_descriptions.append(f"{tool_name}({args_display})")
+                        if tool_descriptions:
+                            return "tool call: " + ", ".join(tool_descriptions)
 
             # 如果 content 是字符串
             if isinstance(content, str):

+ 0 - 0
examples/analyze_story/README.md → examples/archive/analyze_story/README.md


+ 0 - 0
examples/analyze_story/analysis_results.json → examples/archive/analyze_story/analysis_results.json


+ 0 - 0
examples/analyze_story/analyze_samples.py → examples/archive/analyze_story/analyze_samples.py


+ 0 - 0
examples/analyze_story/generate_report.py → examples/archive/analyze_story/generate_report.py


+ 0 - 0
examples/analyze_story/input/中国合伙人.pdf → examples/archive/analyze_story/input/中国合伙人.pdf


+ 0 - 0
examples/analyze_story/input/大奉打更人.txt → examples/archive/analyze_story/input/大奉打更人.txt


+ 0 - 0
examples/analyze_story/input/搜神记.txt → examples/archive/analyze_story/input/搜神记.txt


+ 0 - 0
examples/analyze_story/input/无双.docx → examples/archive/analyze_story/input/无双.docx


+ 0 - 0
examples/analyze_story/input/雪中悍刀行.txt → examples/archive/analyze_story/input/雪中悍刀行.txt


+ 0 - 0
examples/analyze_story/input/魔道祖师.txt → examples/archive/analyze_story/input/魔道祖师.txt


+ 0 - 0
examples/analyze_story/knowledge/01_Scene_Sequel_Structure.md → examples/archive/analyze_story/knowledge/01_Scene_Sequel_Structure.md


+ 0 - 0
examples/analyze_story/knowledge/01_save_the_cat_beat_sheet.md → examples/archive/analyze_story/knowledge/01_save_the_cat_beat_sheet.md


+ 0 - 0
examples/analyze_story/knowledge/01_scene_sequel_theory.md → examples/archive/analyze_story/knowledge/01_scene_sequel_theory.md


+ 0 - 0
examples/analyze_story/knowledge/01_叙事理论综述.md → examples/archive/analyze_story/knowledge/01_叙事理论综述.md


+ 0 - 0
examples/analyze_story/knowledge/02_MICE_Quotient.md → examples/archive/analyze_story/knowledge/02_MICE_Quotient.md


+ 0 - 0
examples/analyze_story/knowledge/02_MICE_quotient_theory.md → examples/archive/analyze_story/knowledge/02_MICE_quotient_theory.md


+ 0 - 0
examples/analyze_story/knowledge/03_Save_the_Cat_Beats.md → examples/archive/analyze_story/knowledge/03_Save_the_Cat_Beats.md


+ 0 - 0
examples/analyze_story/knowledge/03_web_novel_techniques.md → examples/archive/analyze_story/knowledge/03_web_novel_techniques.md


+ 0 - 0
examples/analyze_story/knowledge/04_Web_Novel_Theory.md → examples/archive/analyze_story/knowledge/04_Web_Novel_Theory.md


+ 0 - 0
examples/analyze_story/knowledge/04_save_the_cat_beats.md → examples/archive/analyze_story/knowledge/04_save_the_cat_beats.md


+ 0 - 0
examples/analyze_story/knowledge/05_AI_narrative_generation.md → examples/archive/analyze_story/knowledge/05_AI_narrative_generation.md


+ 0 - 0
examples/analyze_story/knowledge/05_Integrated_Methodology.md → examples/archive/analyze_story/knowledge/05_Integrated_Methodology.md


+ 0 - 0
examples/analyze_story/knowledge/07_Methodology_Analysis.md → examples/archive/analyze_story/knowledge/07_Methodology_Analysis.md


+ 0 - 0
examples/analyze_story/knowledge/1_scene_sequel_theory.md → examples/archive/analyze_story/knowledge/1_scene_sequel_theory.md


+ 0 - 0
examples/analyze_story/knowledge/samples_overview.md → examples/archive/analyze_story/knowledge/samples_overview.md


+ 0 - 0
examples/analyze_story/methodology/README.md → examples/archive/analyze_story/methodology/README.md


+ 0 - 0
examples/analyze_story/methodology/v2_improved_methodology.md → examples/archive/analyze_story/methodology/v2_improved_methodology.md


+ 0 - 0
examples/analyze_story/read_all_files.py → examples/archive/analyze_story/read_all_files.py


+ 0 - 0
examples/analyze_story/read_samples.py → examples/archive/analyze_story/read_samples.py


+ 0 - 0
examples/analyze_story/read_txt_files.py → examples/archive/analyze_story/read_txt_files.py


+ 0 - 0
examples/analyze_story/run.py → examples/archive/analyze_story/run.py


+ 0 - 0
examples/analyze_story/runs/搜神记/analysis/w0.error.txt → examples/archive/analyze_story/runs/搜神记/analysis/w0.error.txt


+ 0 - 0
examples/analyze_story/runs/搜神记/analysis/w0.json → examples/archive/analyze_story/runs/搜神记/analysis/w0.json


+ 0 - 0
examples/analyze_story/runs/搜神记/sft_raw/w0_demo/stats.json → examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/stats.json


+ 0 - 0
examples/analyze_story/runs/搜神记/sft_raw/w0_demo/task1_structure_planning.jsonl → examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task1_structure_planning.jsonl


+ 0 - 0
examples/analyze_story/runs/搜神记/sft_raw/w0_demo/task2_scene_continuation.jsonl → examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task2_scene_continuation.jsonl


+ 0 - 0
examples/analyze_story/runs/搜神记/sft_raw/w0_demo/task3_shuang_injection.jsonl → examples/archive/analyze_story/runs/搜神记/sft_raw/w0_demo/task3_shuang_injection.jsonl


+ 0 - 0
examples/analyze_story/samples_data.json → examples/archive/analyze_story/samples_data.json


+ 0 - 0
examples/analyze_story/sft/README.md → examples/archive/analyze_story/sft/README.md


+ 0 - 0
examples/analyze_story/sft/run_pipeline.py → examples/archive/analyze_story/sft/run_pipeline.py


+ 0 - 0
examples/analyze_story/sft/step1_analyze.py → examples/archive/analyze_story/sft/step1_analyze.py


+ 0 - 0
examples/analyze_story/sft/step2_build_sft.py → examples/archive/analyze_story/sft/step2_build_sft.py


+ 0 - 0
examples/analyze_story/test.prompt → examples/archive/analyze_story/test.prompt


+ 0 - 0
examples/analyze_story/一周执行计划.md → examples/archive/analyze_story/一周执行计划.md


+ 0 - 0
examples/analyze_story/拆解示例_大奉打更人第1-2章.md → examples/archive/analyze_story/拆解示例_大奉打更人第1-2章.md


+ 0 - 0
examples/deep_research/input/1.jpeg → examples/archive/deep_research/input/1.jpeg


+ 0 - 0
examples/deep_research/input/1_invariant_features.json → examples/archive/deep_research/input/1_invariant_features.json


+ 0 - 0
examples/deep_research/input/3.jpeg → examples/archive/deep_research/input/3.jpeg


+ 0 - 0
examples/deep_research/input/3_invariant_features.json → examples/archive/deep_research/input/3_invariant_features.json


+ 0 - 0
examples/deep_research/input/7.jpeg → examples/archive/deep_research/input/7.jpeg


+ 0 - 0
examples/deep_research/input/7_invariant_features.json → examples/archive/deep_research/input/7_invariant_features.json


+ 0 - 0
examples/deep_research/input/《秋日际遇》写生油画.json → examples/archive/deep_research/input/《秋日际遇》写生油画.json


+ 0 - 0
examples/deep_research/production.prompt → examples/archive/deep_research/production.prompt


+ 0 - 0
examples/deep_research/run.py → examples/archive/deep_research/run.py


+ 0 - 0
examples/feature_extract/input_1/feature.md → examples/archive/feature_extract/input_1/feature.md


+ 0 - 0
examples/feature_extract/input_1/image.png → examples/archive/feature_extract/input_1/image.png


+ 0 - 0
examples/feature_extract/run.py → examples/archive/feature_extract/run.py


+ 0 - 0
examples/feature_extract/test.prompt → examples/archive/feature_extract/test.prompt


+ 0 - 0
examples/how/README.md → examples/archive/how/README.md


+ 0 - 0
examples/how/analyze_images.py → examples/archive/how/analyze_images.py


+ 0 - 0
examples/how/encode_images.py → examples/archive/how/encode_images.py


+ 0 - 0
examples/how/features/images_b64.json → examples/archive/how/features/images_b64.json


+ 0 - 0
examples/how/features/img1_b64.txt → examples/archive/how/features/img1_b64.txt


+ 0 - 0
examples/how/features/img2_b64.txt → examples/archive/how/features/img2_b64.txt


+ 0 - 0
examples/how/features/img3_b64.txt → examples/archive/how/features/img3_b64.txt


+ 0 - 0
examples/how/features/img4_b64.txt → examples/archive/how/features/img4_b64.txt


+ 0 - 0
examples/how/features/img5_b64.txt → examples/archive/how/features/img5_b64.txt


+ 0 - 0
examples/how/features/img6_b64.txt → examples/archive/how/features/img6_b64.txt


+ 0 - 0
examples/how/features/img7_b64.txt → examples/archive/how/features/img7_b64.txt


+ 0 - 0
examples/how/features/img8_b64.txt → examples/archive/how/features/img8_b64.txt


+ 0 - 0
examples/how/features/img9_b64.txt → examples/archive/how/features/img9_b64.txt


+ 0 - 0
examples/how/features/thumb_1.jpg → examples/archive/how/features/thumb_1.jpg


+ 0 - 0
examples/how/features/thumb_2.jpg → examples/archive/how/features/thumb_2.jpg


+ 0 - 0
examples/how/features/thumb_3.jpg → examples/archive/how/features/thumb_3.jpg


+ 0 - 0
examples/how/features/thumb_4.jpg → examples/archive/how/features/thumb_4.jpg


+ 0 - 0
examples/how/features/thumb_5.jpg → examples/archive/how/features/thumb_5.jpg


+ 0 - 0
examples/how/features/thumb_6.jpg → examples/archive/how/features/thumb_6.jpg


+ 0 - 0
examples/how/features/thumb_7.jpg → examples/archive/how/features/thumb_7.jpg


+ 0 - 0
examples/how/features/thumb_8.jpg → examples/archive/how/features/thumb_8.jpg


+ 0 - 0
examples/how/features/thumb_9.jpg → examples/archive/how/features/thumb_9.jpg


+ 0 - 0
examples/how/input/1.jpeg → examples/archive/how/input/1.jpeg


+ 0 - 0
examples/how/input/1_invariant_features.json → examples/archive/how/input/1_invariant_features.json


+ 0 - 0
examples/how/input/3.jpeg → examples/archive/how/input/3.jpeg


+ 0 - 0
examples/how/input/3_invariant_features.json → examples/archive/how/input/3_invariant_features.json


+ 0 - 0
examples/how/input/7.jpeg → examples/archive/how/input/7.jpeg


+ 0 - 0
examples/how/input/7_invariant_features.json → examples/archive/how/input/7_invariant_features.json


+ 0 - 0
examples/how/input/set_invariant_features.json → examples/archive/how/input/set_invariant_features.json


+ 0 - 0
examples/how/input/《秋日际遇》写生油画.json → examples/archive/how/input/《秋日际遇》写生油画.json


+ 0 - 0
examples/how/load_imgs.py → examples/archive/how/load_imgs.py


+ 0 - 0
examples/how/presets.json → examples/archive/how/presets.json


+ 0 - 0
examples/how/production.prompt → examples/archive/how/production.prompt


+ 0 - 0
examples/how/resource/input_cloud_archive/《秋日际遇》写生油画.json → examples/archive/how/resource/input_cloud_archive/《秋日际遇》写生油画.json


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است