markdown-flow 0.2.77__tar.gz → 0.2.79__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/PKG-INFO +1 -1
  2. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/__init__.py +1 -1
  3. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/constants.py +19 -23
  4. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/core.py +23 -16
  5. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/system_prompt.md +7 -0
  6. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow.egg-info/PKG-INFO +1 -1
  7. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/LICENSE +0 -0
  8. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/README.md +0 -0
  9. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/constants_system_prompt.py +0 -0
  10. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/enums.py +0 -0
  11. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/exceptions.py +0 -0
  12. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/__init__.py +0 -0
  13. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/classifier.py +0 -0
  14. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/format.py +0 -0
  15. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/patterns.py +0 -0
  16. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/stream.py +0 -0
  17. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/formatter/types.py +0 -0
  18. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/llm.py +0 -0
  19. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/models.py +0 -0
  20. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/__init__.py +0 -0
  21. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/code_fence_utils.py +0 -0
  22. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/html_comment_utils.py +0 -0
  23. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/interaction.py +0 -0
  24. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/json_parser.py +0 -0
  25. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/output.py +0 -0
  26. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/preprocessor.py +0 -0
  27. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/validation.py +0 -0
  28. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/parser/variable.py +0 -0
  29. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/providers/__init__.py +0 -0
  30. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/providers/config.py +0 -0
  31. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/providers/openai.py +0 -0
  32. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/tag_filter.py +0 -0
  33. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow/utils.py +0 -0
  34. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow.egg-info/SOURCES.txt +0 -0
  35. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow.egg-info/dependency_links.txt +0 -0
  36. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/markdown_flow.egg-info/top_level.txt +0 -0
  37. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/pyproject.toml +0 -0
  38. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/setup.cfg +0 -0
  39. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_dynamic_interaction.py +0 -0
  40. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_formatter.py +0 -0
  41. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_formatter_stream.py +0 -0
  42. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_html_comment_utils.py +0 -0
  43. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_markdownflow_basic.py +0 -0
  44. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_parser_interaction.py +0 -0
  45. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_parser_output.py +0 -0
  46. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_parser_variable.py +0 -0
  47. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_preprocessor.py +0 -0
  48. {markdown_flow-0.2.77 → markdown_flow-0.2.79}/tests/test_preserved_simple.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-flow
3
- Version: 0.2.77
3
+ Version: 0.2.79
4
4
  Summary: An agent library designed to parse and process MarkdownFlow documents
5
5
  Project-URL: Homepage, https://github.com/ai-shifu/markdown-flow-agent-py
6
6
  Project-URL: Bug Tracker, https://github.com/ai-shifu/markdown-flow-agent-py/issues
@@ -88,5 +88,5 @@ __all__ = [
88
88
  "replace_variables_in_text",
89
89
  ]
90
90
 
91
- __version__ = "0.2.77"
91
+ __version__ = "0.2.79"
92
92
  # __version__ = "0.2.45-alpha-1"
@@ -86,24 +86,21 @@ OUTPUT_LANGUAGE_INSTRUCTION_BOTTOM = """<output_language_final_check>
86
86
  </output_language_final_check>"""
87
87
 
88
88
  # Interaction prompt templates (Modular design)
89
- INTERACTION_PROMPT_BASE = """<interaction_processing_rules>
90
- ⚠️⚠️⚠️ JSON 处理任务 ⚠️⚠️⚠️
89
+ INTERACTION_PROMPT_BASE = """# JSON 交互翻译任务
91
90
 
92
- ## 任务说明
93
-
94
- 你将收到一个包含交互元素的 JSON 对象(buttons 和/或 question 字段)。
91
+ 你将收到一个包含交互元素的 JSON 对象(`buttons` 和/或 `question` 字段),需要把其中的文本翻译为目标语言。
95
92
 
96
93
  ## 输出格式要求
97
94
 
98
- - **必须返回纯 JSON**,不要添加任何解释或 markdown 代码块
99
- - **格式必须与输入完全一致**,包括空格、标点、引号
100
- - 不要添加或删除任何字段
101
- - 不要修改 JSON 的结构"""
95
+ - 必须返回纯 JSON,不要添加任何解释或 markdown 代码块
96
+ - JSON 结构必须与输入完全一致:不增删字段、不修改键名、不调整顺序
97
+ - 保留原有的空格、标点和引号"""
102
98
 
103
99
  INTERACTION_PROMPT_NO_TRANSLATION = """
104
100
  ## 处理规则
105
101
 
106
- **逐字符原样返回输入的 JSON**
102
+ 逐字符原样返回输入的 JSON
103
+
107
104
  - 不翻译任何文本
108
105
  - 不修改任何格式
109
106
  - 不添加任何内容(如 display//value 分离)
@@ -112,23 +109,22 @@ INTERACTION_PROMPT_NO_TRANSLATION = """
112
109
 
113
110
  ## 示例
114
111
 
115
- 输入:{"buttons": ["产品经理", "开发者"], "question": "其他身份"}
116
-
117
- ✅ 输出:{"buttons": ["产品经理", "开发者"], "question": "其他身份"}
118
- </interaction_processing_rules>"""
112
+ - 输入 `{"buttons": ["产品经理", "开发者"], "question": "其他身份"}`
113
+ - 输出 `{"buttons": ["产品经理", "开发者"], "question": "其他身份"}`"""
119
114
 
120
115
  INTERACTION_PROMPT_WITH_TRANSLATION = """
121
- ## 处理规则
116
+ ## 翻译规则
117
+
118
+ - 将 `buttons` 和 `question` 中的文本翻译为目标语言
119
+ - 仅翻译显示文本(Display 部分),不改变 JSON 结构
120
+ - 如果存在 `display//value` 分离(如 `Yes//1`),只翻译 `//` 前的 Display 部分,保留 value 不变
121
+ - 100% 使用目标语言,不允许混排;先把所有非目标语言的词翻译完再输出
122
+ - 若某段文本的原文语言已与目标语言一致,则原样返回该文本(例如目标语言为中文、原文也是中文时不做任何改写)
122
123
 
123
- **将 buttons 和 question 文本翻译到指定语言**
124
- - 保持 JSON 格式完全不变
125
- - 仅翻译显示文本(Display 部分),不改变结构
126
- - 如果存在 display//value 分离,只翻译 display 部分,保留 value 不变
127
- - 100% 纯目标语言,ZERO 混排
128
- - 先翻译所有非目标语言的词,再输出
124
+ ## 示例
129
125
 
130
- 示例:{"buttons": ["Yes//1", "No//0"]} → 西班牙语 → {"buttons": ["Sí//1", "No//0"]}
131
- </interaction_processing_rules>"""
126
+ - 输入 `{"buttons": ["Yes//1", "No//0"]}`,目标语言西班牙语`{"buttons": ["Sí//1", "No//0"]}`
127
+ - 输入 `{"buttons": ["初级", "高级"], "question": "其他"}`,目标语言英语 → `{"buttons": ["Beginner", "Advanced"], "question": "Other"}`"""
132
128
 
133
129
  # Default: use no translation version (backward compatible)
134
130
  DEFAULT_INTERACTION_PROMPT = INTERACTION_PROMPT_BASE + "\n" + INTERACTION_PROMPT_NO_TRANSLATION
@@ -690,6 +690,20 @@ class MarkdownFlow:
690
690
  },
691
691
  )
692
692
 
693
+ # If no output language is configured, skip translation entirely:
694
+ # return the interaction content as-is without any LLM call.
695
+ if not self._output_language:
696
+ return LLMResult(
697
+ content=processed_block.content,
698
+ type=ElementType.INTERACTION,
699
+ number=block_index,
700
+ metadata={
701
+ "block_type": "interaction",
702
+ "block_index": block_index,
703
+ "translation_skipped": True,
704
+ },
705
+ )
706
+
693
707
  # Build translation messages
694
708
  messages = self._build_translation_messages(translatable_json)
695
709
 
@@ -1315,26 +1329,19 @@ class MarkdownFlow:
1315
1329
  """
1316
1330
  messages = []
1317
1331
 
1318
- # Build system message: choose template based on whether outputLanguage exists
1332
+ # Build system message. This method is only reached when an output
1333
+ # language is configured (callers short-circuit otherwise), so the
1334
+ # prompt always performs translation.
1319
1335
  system_parts = []
1320
1336
 
1321
- # Determine if translation is needed
1322
- need_translation = self._output_language is not None and self._output_language != ""
1337
+ # 1. Output language anchoring (top)
1338
+ system_parts.append(OUTPUT_LANGUAGE_INSTRUCTION_TOP.format(self._output_language))
1323
1339
 
1324
- if need_translation:
1325
- # Translation scenario: language anchoring + translation rules
1326
- # 1. Output language anchoring (top)
1327
- system_parts.append(OUTPUT_LANGUAGE_INSTRUCTION_TOP.format(self._output_language))
1340
+ # 2. Interaction processing base + translation rules
1341
+ system_parts.append(INTERACTION_PROMPT_BASE + "\n" + INTERACTION_PROMPT_WITH_TRANSLATION)
1328
1342
 
1329
- # 2. Interaction processing base + translation rules
1330
- system_parts.append(INTERACTION_PROMPT_BASE + "\n" + INTERACTION_PROMPT_WITH_TRANSLATION)
1331
-
1332
- # 3. Output language anchoring (bottom)
1333
- system_parts.append(OUTPUT_LANGUAGE_INSTRUCTION_BOTTOM.format(self._output_language))
1334
- else:
1335
- # No translation scenario: use default no-translation prompt
1336
- # Use default prompt (includes Base + NoTranslation)
1337
- system_parts.append(self._interaction_prompt)
1343
+ # 3. Output language anchoring (bottom)
1344
+ system_parts.append(OUTPUT_LANGUAGE_INSTRUCTION_BOTTOM.format(self._output_language))
1338
1345
 
1339
1346
  # Combine all parts
1340
1347
  system_content = "\n\n".join(system_parts)
@@ -33,6 +33,7 @@
33
33
  ```
34
34
 
35
35
  每屏 HTML 后必须紧跟:
36
+
36
37
  ```
37
38
  <style>
38
39
  *,*::before,*::after{box-sizing:border-box;overflow-wrap:break-word;word-wrap:break-word}
@@ -60,6 +61,7 @@
60
61
 
61
62
  **方式 B:浮动层 DOM 节点**
62
63
  若必须使用独立元素,必须同时满足:
64
+
63
65
  - `position:absolute`(父级须为 `position:relative`,外层容器已默认满足)
64
66
  - `pointer-events:none`(不拦截交互)
65
67
  - `z-index:0` 或负值(置于主内容之下)
@@ -81,6 +83,7 @@
81
83
  - **禁止使用 DaisyUI 的 steps 组件**(`.steps` / `.step`):该组件仅承载"一行短标签"的进度指示,不支持图标+标题+描述多层内容,塞入多个 `<span>` 或 `<div>` 都会让 grid 布局崩坏(圆点错位、文字被挤成窄列竖排换行等);凡是"步骤"需求全部走 timeline
82
84
 
83
85
  **timeline 组件正确用法**
86
+
84
87
  - 容器:`<ul class="timeline timeline-vertical">`(横向用 `timeline-horizontal`,紧凑用 `timeline-compact`),直接子元素必须是 `<li>`
85
88
  - 每个 `<li>` 按需组合以下槽位(块级元素只能是这些 class,不能放无 class 的裸 `<div>`):
86
89
  - `<div class="timeline-start timeline-box">起始侧内容</div>`:左/上侧内容,加 `timeline-box` 会渲染为卡片
@@ -95,12 +98,15 @@
95
98
  ## 3. 操作模式
96
99
 
97
100
  ### 3.1 创建新屏
101
+
98
102
  输出 HTML 块级元素 → 清空容器,创建新一屏。
99
103
 
100
104
  ### 3.2 追加脚本/样式
105
+
101
106
  输出 `<script>` 或 `<style>` → 追加到当前屏,不翻页。
102
107
 
103
108
  ### 3.3 修改已有屏(Diff)
109
+
104
110
  仅当用户明确要求修改时使用。格式:
105
111
 
106
112
  !+++
@@ -129,5 +135,6 @@
129
135
  11. 禁止在布局流中出现纯装饰性的块级/行内元素,装饰必须遵循 2.2 节的 CSS 背景或浮动层方式
130
136
  12. 视图中禁止生成body 之外的元素基本已div 为主 禁止生成`<head>` `<!DOCTYPE html>`
131
137
  13. 以纯文本形式输出HTML,**禁止**使用```html或任何代码块标记。比如:
138
+
132
139
  ```html
133
140
  <div style="width:100%; min-height:100vh; overflow-x:hidden; overflow-y:auto; display:flex; flex-direction:column; align-items:center; padding:1em; font-size:clamp(12px,calc(100vw/48),3vh)">
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-flow
3
- Version: 0.2.77
3
+ Version: 0.2.79
4
4
  Summary: An agent library designed to parse and process MarkdownFlow documents
5
5
  Project-URL: Homepage, https://github.com/ai-shifu/markdown-flow-agent-py
6
6
  Project-URL: Bug Tracker, https://github.com/ai-shifu/markdown-flow-agent-py/issues
File without changes
File without changes
File without changes