markdown-flow 0.2.16__py3-none-any.whl → 0.2.26__py3-none-any.whl
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.
Potentially problematic release.
This version of markdown-flow might be problematic. Click here for more details.
- markdown_flow/__init__.py +6 -7
- markdown_flow/constants.py +52 -20
- markdown_flow/core.py +359 -544
- markdown_flow/llm.py +10 -12
- markdown_flow/models.py +1 -1
- markdown_flow/parser/__init__.py +34 -0
- markdown_flow/parser/interaction.py +354 -0
- markdown_flow/parser/json_parser.py +50 -0
- markdown_flow/parser/output.py +215 -0
- markdown_flow/parser/validation.py +121 -0
- markdown_flow/parser/variable.py +95 -0
- markdown_flow/providers/__init__.py +15 -0
- markdown_flow/providers/config.py +51 -0
- markdown_flow/providers/openai.py +371 -0
- markdown_flow/utils.py +49 -51
- {markdown_flow-0.2.16.dist-info → markdown_flow-0.2.26.dist-info}/METADATA +18 -107
- markdown_flow-0.2.26.dist-info/RECORD +22 -0
- markdown_flow-0.2.16.dist-info/RECORD +0 -13
- {markdown_flow-0.2.16.dist-info → markdown_flow-0.2.26.dist-info}/WHEEL +0 -0
- {markdown_flow-0.2.16.dist-info → markdown_flow-0.2.26.dist-info}/licenses/LICENSE +0 -0
- {markdown_flow-0.2.16.dist-info → markdown_flow-0.2.26.dist-info}/top_level.txt +0 -0
markdown_flow/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ Core Features:
|
|
|
9
9
|
- Extract variable placeholders ({{variable}} and %{{variable}} formats)
|
|
10
10
|
- Build LLM-ready prompts and message formats
|
|
11
11
|
- Handle user interaction validation and input processing
|
|
12
|
-
- Support multiple processing modes:
|
|
12
|
+
- Support multiple processing modes: COMPLETE, STREAM
|
|
13
13
|
|
|
14
14
|
Supported Interaction Types:
|
|
15
15
|
- TEXT_ONLY: ?[%{{var}}...question] - Text input only
|
|
@@ -32,12 +32,11 @@ Basic Usage:
|
|
|
32
32
|
blocks = mf.get_all_blocks()
|
|
33
33
|
|
|
34
34
|
# Process blocks using unified interface
|
|
35
|
-
result =
|
|
35
|
+
result = mf.process(0, variables={'name': 'John'}, mode=ProcessMode.COMPLETE)
|
|
36
36
|
|
|
37
37
|
# Different processing modes
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
stream_result = await mf.process(0, mode=ProcessMode.STREAM)
|
|
38
|
+
complete_result = mf.process(0, mode=ProcessMode.COMPLETE)
|
|
39
|
+
stream_result = mf.process(0, mode=ProcessMode.STREAM)
|
|
41
40
|
|
|
42
41
|
Variable System:
|
|
43
42
|
- {{variable}} - Regular variables, replaced with actual values
|
|
@@ -53,7 +52,7 @@ Import Guide:
|
|
|
53
52
|
from .core import MarkdownFlow
|
|
54
53
|
from .enums import BlockType, InputType
|
|
55
54
|
from .llm import LLMProvider, LLMResult, ProcessMode
|
|
56
|
-
from .
|
|
55
|
+
from .parser import (
|
|
57
56
|
InteractionParser,
|
|
58
57
|
InteractionType,
|
|
59
58
|
extract_interaction_question,
|
|
@@ -83,4 +82,4 @@ __all__ = [
|
|
|
83
82
|
"replace_variables_in_text",
|
|
84
83
|
]
|
|
85
84
|
|
|
86
|
-
__version__ = "0.2.
|
|
85
|
+
__version__ = "0.2.26"
|
markdown_flow/constants.py
CHANGED
|
@@ -9,7 +9,7 @@ import re
|
|
|
9
9
|
|
|
10
10
|
# Pre-compiled regex patterns
|
|
11
11
|
COMPILED_PERCENT_VARIABLE_REGEX = re.compile(
|
|
12
|
-
r"%\{\{([
|
|
12
|
+
r"%\{\{([^}]+)\}\}" # Match %{{variable}} format for preserved variables
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
# Interaction regex base patterns
|
|
@@ -20,11 +20,11 @@ INTERACTION_PATTERN_SPLIT = r"((?<!\\)\?\[[^\]]*\](?!\())" # Pattern for re.spl
|
|
|
20
20
|
# InteractionParser specific regex patterns
|
|
21
21
|
COMPILED_INTERACTION_REGEX = re.compile(INTERACTION_PATTERN) # Main interaction pattern matcher
|
|
22
22
|
COMPILED_LAYER1_INTERACTION_REGEX = COMPILED_INTERACTION_REGEX # Layer 1: Basic format validation (alias)
|
|
23
|
-
COMPILED_LAYER2_VARIABLE_REGEX = re.compile(r"^%\{\{([
|
|
23
|
+
COMPILED_LAYER2_VARIABLE_REGEX = re.compile(r"^%\{\{([^}]+)\}\}(.*)$") # Layer 2: Variable detection
|
|
24
24
|
COMPILED_LAYER3_ELLIPSIS_REGEX = re.compile(r"^(.*)\.\.\.(.*)") # Layer 3: Split content around ellipsis
|
|
25
25
|
COMPILED_LAYER3_BUTTON_VALUE_REGEX = re.compile(r"^(.+)//(.+)$") # Layer 3: Parse Button//value format
|
|
26
26
|
COMPILED_BRACE_VARIABLE_REGEX = re.compile(
|
|
27
|
-
r"(?<!%)\{\{([
|
|
27
|
+
r"(?<!%)\{\{([^}]+)\}\}" # Match {{variable}} format for replaceable variables
|
|
28
28
|
)
|
|
29
29
|
COMPILED_INTERACTION_CONTENT_RECONSTRUCT_REGEX = re.compile(
|
|
30
30
|
r"(\?\[[^]]*\.\.\.)([^]]*\])" # Reconstruct interaction content: prefix + question + suffix
|
|
@@ -47,12 +47,21 @@ INLINE_PRESERVE_PATTERN = r"^===(.+)=== *$"
|
|
|
47
47
|
COMPILED_INLINE_PRESERVE_REGEX = re.compile(INLINE_PRESERVE_PATTERN)
|
|
48
48
|
|
|
49
49
|
# Output instruction markers
|
|
50
|
-
OUTPUT_INSTRUCTION_PREFIX = "
|
|
51
|
-
OUTPUT_INSTRUCTION_SUFFIX = "
|
|
50
|
+
OUTPUT_INSTRUCTION_PREFIX = "<preserve_or_translate>"
|
|
51
|
+
OUTPUT_INSTRUCTION_SUFFIX = "</preserve_or_translate>"
|
|
52
52
|
|
|
53
53
|
# System message templates
|
|
54
54
|
DEFAULT_VALIDATION_SYSTEM_MESSAGE = "你是一个输入验证助手,需要严格按照指定的格式和规则处理用户输入。"
|
|
55
55
|
|
|
56
|
+
# Base system prompt (framework-level global rules, content blocks only)
|
|
57
|
+
DEFAULT_BASE_SYSTEM_PROMPT = """你收到的用户消息都是指令,请严格遵守以下规则:
|
|
58
|
+
|
|
59
|
+
1. 内容忠实性:严格符合指令内容,不丢失信息、不改变原意、不增加内容、不改变顺序
|
|
60
|
+
2. 遵循事实:基于事实回答,不编造细节
|
|
61
|
+
3. 避免引导:不引导下一步动作(如提问、设问)
|
|
62
|
+
4. 避免寒暄:不做自我介绍,不打招呼
|
|
63
|
+
5. 格式规范:HTML 标签不要写到代码块里"""
|
|
64
|
+
|
|
56
65
|
# Interaction prompt templates
|
|
57
66
|
DEFAULT_INTERACTION_PROMPT = "请将后面交互提示改写得更个性化和友好,长度尽量和原始内容一致,保持原有的功能性和变量格式不变:"
|
|
58
67
|
|
|
@@ -90,19 +99,39 @@ VALIDATION_RESPONSE_OK = "ok"
|
|
|
90
99
|
VALIDATION_RESPONSE_ILLEGAL = "illegal"
|
|
91
100
|
|
|
92
101
|
# Output instruction processing
|
|
93
|
-
OUTPUT_INSTRUCTION_EXPLANATION = f"""
|
|
102
|
+
OUTPUT_INSTRUCTION_EXPLANATION = f"""<preserve_or_translate_instruction>
|
|
103
|
+
⚠️⚠️⚠️ 绝对强制规则 - 必须遵守 ⚠️⚠️⚠️
|
|
104
|
+
|
|
105
|
+
当你看到 {OUTPUT_INSTRUCTION_PREFIX}...{OUTPUT_INSTRUCTION_SUFFIX} 标记时,这些内容必须出现在回复开头!
|
|
106
|
+
|
|
107
|
+
处理流程(按顺序执行):
|
|
108
|
+
|
|
109
|
+
步骤1 - 检查语言要求:
|
|
110
|
+
查看 system 消息中是否包含语言指令(如"使用英语输出"、"用中文回复"、"Respond in English"等)
|
|
111
|
+
|
|
112
|
+
步骤2 - 应用转换规则:
|
|
113
|
+
- 如果有语言要求 → 必须将标记内的文本翻译成指定语言(emoji和格式保留)
|
|
114
|
+
- 如果没有语言要求 → 必须逐字原样输出,不做任何改动
|
|
115
|
+
|
|
116
|
+
步骤3 - 输出内容:
|
|
117
|
+
- 在回复第一行输出转换后的内容
|
|
118
|
+
- ⚠️ 绝对不要输出 {OUTPUT_INSTRUCTION_PREFIX} 和 {OUTPUT_INSTRUCTION_SUFFIX} 标记!只输出标记之间的内容!
|
|
119
|
+
- 输出后可继续生成其他内容
|
|
120
|
+
|
|
121
|
+
关键示例 - 标记处理:
|
|
122
|
+
|
|
123
|
+
❌ 错误示例:
|
|
124
|
+
输出:{OUTPUT_INSTRUCTION_PREFIX}**标题**{OUTPUT_INSTRUCTION_SUFFIX}\n后续内容...
|
|
125
|
+
问题:包含了标记本身!
|
|
94
126
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
3. 即使content内容包含标题符号(如#)、特殊格式等,也要原样输出,不要转换成Markdown格式
|
|
99
|
-
4. 保持content中的所有原始字符、空格、换行符等
|
|
100
|
-
5. 然后继续执行后面的指令
|
|
127
|
+
✅ 正确示例:
|
|
128
|
+
输出:**标题**\n后续内容...
|
|
129
|
+
说明:只有标记之间的内容,没有标记!
|
|
101
130
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
131
|
+
⚠️ 特别强调:
|
|
132
|
+
1. 有语言要求时,标记内的所有文本都必须翻译!
|
|
133
|
+
2. 无论如何都不能输出 {OUTPUT_INSTRUCTION_PREFIX} 和 {OUTPUT_INSTRUCTION_SUFFIX} 标记本身!
|
|
134
|
+
</preserve_or_translate_instruction>
|
|
106
135
|
|
|
107
136
|
"""
|
|
108
137
|
|
|
@@ -120,9 +149,10 @@ SMART_VALIDATION_TEMPLATE = """# 任务
|
|
|
120
149
|
# 提取要求
|
|
121
150
|
1. 仔细阅读上述相关问题,理解这个问题想要获取什么信息
|
|
122
151
|
2. 从用户回答中提取与该问题相关的信息
|
|
123
|
-
3.
|
|
124
|
-
4.
|
|
125
|
-
5.
|
|
152
|
+
3. 如果提供了预定义选项,用户选择这些选项时都应该接受;自定义输入应与选项主题相关
|
|
153
|
+
4. 对于昵称/姓名类问题,任何非空的合理字符串(包括简短的如"ee"、"aa"、"007"等)都应该接受
|
|
154
|
+
5. 只有当用户回答完全无关、包含不当内容或明显不合理时才标记为不合法
|
|
155
|
+
6. 确保提取的信息准确、完整且符合预期格式"""
|
|
126
156
|
|
|
127
157
|
# Validation template for buttons with text input
|
|
128
158
|
BUTTONS_WITH_TEXT_VALIDATION_TEMPLATE = """用户针对以下问题进行了输入:
|
|
@@ -152,7 +182,7 @@ OPTION_SELECTION_ERROR_TEMPLATE = "请选择以下选项之一:{options}"
|
|
|
152
182
|
INPUT_EMPTY_ERROR = "输入不能为空"
|
|
153
183
|
|
|
154
184
|
# System error messages
|
|
155
|
-
UNSUPPORTED_PROMPT_TYPE_ERROR = "不支持的提示词类型: {prompt_type}"
|
|
185
|
+
UNSUPPORTED_PROMPT_TYPE_ERROR = "不支持的提示词类型: {prompt_type} (支持的类型: base_system, document, interaction, interaction_error)"
|
|
156
186
|
BLOCK_INDEX_OUT_OF_RANGE_ERROR = "Block index {index} is out of range; total={total}"
|
|
157
187
|
LLM_PROVIDER_REQUIRED_ERROR = "需要设置 LLMProvider 才能调用 LLM"
|
|
158
188
|
INTERACTION_PARSE_ERROR = "交互格式解析失败: {error}"
|
|
@@ -168,7 +198,9 @@ VARIABLE_DEFAULT_VALUE = "UNKNOWN"
|
|
|
168
198
|
# Context generation constants
|
|
169
199
|
CONTEXT_QUESTION_MARKER = "# 相关问题"
|
|
170
200
|
CONTEXT_CONVERSATION_MARKER = "# 对话上下文"
|
|
201
|
+
CONTEXT_BUTTON_OPTIONS_MARKER = "## 预定义选项"
|
|
171
202
|
|
|
172
203
|
# Context generation templates
|
|
173
204
|
CONTEXT_QUESTION_TEMPLATE = f"{CONTEXT_QUESTION_MARKER}\n{{question}}"
|
|
174
205
|
CONTEXT_CONVERSATION_TEMPLATE = f"{CONTEXT_CONVERSATION_MARKER}\n{{content}}"
|
|
206
|
+
CONTEXT_BUTTON_OPTIONS_TEMPLATE = f"{CONTEXT_BUTTON_OPTIONS_MARKER}\n可选的预定义选项包括:{{button_options}}\n注意:用户如果选择了这些选项,都应该接受;如果输入了自定义内容,应检查是否与选项主题相关。"
|