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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: markdown-flow
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.26
|
|
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
|
|
@@ -92,36 +92,6 @@ for chunk in mf.process(
|
|
|
92
92
|
print(chunk.content, end='')
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
### Dynamic Interaction Generation ✨
|
|
96
|
-
|
|
97
|
-
Transform natural language content into interactive elements automatically:
|
|
98
|
-
|
|
99
|
-
```python
|
|
100
|
-
from markdown_flow import MarkdownFlow, ProcessMode
|
|
101
|
-
|
|
102
|
-
# Dynamic interaction generation works automatically
|
|
103
|
-
mf = MarkdownFlow(
|
|
104
|
-
document="询问用户的菜品偏好,并记录到变量{{菜品选择}}",
|
|
105
|
-
llm_provider=llm_provider,
|
|
106
|
-
document_prompt="你是中餐厅服务员,提供川菜、粤菜、鲁菜等选项"
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
# Process with Function Calling
|
|
110
|
-
result = mf.process(0, ProcessMode.COMPLETE)
|
|
111
|
-
|
|
112
|
-
if result.transformed_to_interaction:
|
|
113
|
-
print(f"Generated interaction: {result.content}")
|
|
114
|
-
# Output: ?[%{{菜品选择}} 宫保鸡丁||麻婆豆腐||水煮鱼||...其他菜品]
|
|
115
|
-
|
|
116
|
-
# Continue with user input
|
|
117
|
-
user_result = mf.process(
|
|
118
|
-
block_index=0,
|
|
119
|
-
mode=ProcessMode.COMPLETE,
|
|
120
|
-
user_input={"菜品选择": ["宫保鸡丁", "麻婆豆腐"]},
|
|
121
|
-
dynamic_interaction_format=result.content
|
|
122
|
-
)
|
|
123
|
-
```
|
|
124
|
-
|
|
125
95
|
### Interactive Elements
|
|
126
96
|
|
|
127
97
|
```python
|
|
@@ -159,59 +129,6 @@ result = mf.process(
|
|
|
159
129
|
)
|
|
160
130
|
```
|
|
161
131
|
|
|
162
|
-
## ✨ Key Features
|
|
163
|
-
|
|
164
|
-
### 🏗️ Three-Layer Architecture
|
|
165
|
-
|
|
166
|
-
- **Document Level**: Parse `---` separators and `?[]` interaction patterns
|
|
167
|
-
- **Block Level**: Categorize as CONTENT, INTERACTION, or PRESERVED_CONTENT
|
|
168
|
-
- **Interaction Level**: Handle 6 different interaction types with smart validation
|
|
169
|
-
|
|
170
|
-
### 🔄 Dynamic Interaction Generation
|
|
171
|
-
|
|
172
|
-
- **Natural Language Input**: Write content in plain language
|
|
173
|
-
- **AI-Powered Conversion**: LLM automatically detects interaction needs using Function Calling
|
|
174
|
-
- **Structured Data Generation**: LLM returns structured data, core builds MarkdownFlow format
|
|
175
|
-
- **Language Agnostic**: Support for any language with proper document prompts
|
|
176
|
-
- **Context Awareness**: Both original and resolved variable contexts provided to LLM
|
|
177
|
-
|
|
178
|
-
### 🤖 Unified LLM Integration
|
|
179
|
-
|
|
180
|
-
- **Single Interface**: One `complete()` method for both regular and Function Calling modes
|
|
181
|
-
- **Automatic Detection**: Tools parameter determines processing mode automatically
|
|
182
|
-
- **Consistent Returns**: Always returns `LLMResult` with structured metadata
|
|
183
|
-
- **Error Handling**: Automatic fallback from Function Calling to regular completion
|
|
184
|
-
- **Provider Agnostic**: Abstract interface supports any LLM service
|
|
185
|
-
|
|
186
|
-
### 📝 Variable System
|
|
187
|
-
|
|
188
|
-
- **Replaceable Variables**: `{{variable}}` for content personalization
|
|
189
|
-
- **Preserved Variables**: `%{{variable}}` for LLM understanding in interactions
|
|
190
|
-
- **Multi-Value Support**: Handle both single values and arrays
|
|
191
|
-
- **Smart Extraction**: Automatic detection from document content
|
|
192
|
-
|
|
193
|
-
### 🎯 Interaction Types
|
|
194
|
-
|
|
195
|
-
- **Text Input**: `?[%{{var}}...question]` - Free text entry
|
|
196
|
-
- **Single Select**: `?[%{{var}} A|B|C]` - Choose one option
|
|
197
|
-
- **Multi Select**: `?[%{{var}} A||B||C]` - Choose multiple options
|
|
198
|
-
- **Mixed Mode**: `?[%{{var}} A||B||...custom]` - Predefined + custom input
|
|
199
|
-
- **Display Buttons**: `?[Continue|Cancel]` - Action buttons without assignment
|
|
200
|
-
- **Value Separation**: `?[%{{var}} Display//value|...]` - Different display/stored values
|
|
201
|
-
|
|
202
|
-
### 🔒 Content Preservation
|
|
203
|
-
|
|
204
|
-
- **Multiline Format**: `!===content!===` blocks output exactly as written
|
|
205
|
-
- **Inline Format**: `===content===` for single-line preserved content
|
|
206
|
-
- **Variable Support**: Preserved content can contain variables for substitution
|
|
207
|
-
|
|
208
|
-
### ⚡ Performance Optimized
|
|
209
|
-
|
|
210
|
-
- **Pre-compiled Regex**: All patterns compiled once for maximum performance
|
|
211
|
-
- **Synchronous Interface**: Clean synchronous operations with optional streaming
|
|
212
|
-
- **Stream Processing**: Real-time streaming responses supported
|
|
213
|
-
- **Memory Efficient**: Lazy evaluation and generator patterns
|
|
214
|
-
|
|
215
132
|
## 📖 API Reference
|
|
216
133
|
|
|
217
134
|
### Core Classes
|
|
@@ -237,7 +154,7 @@ class MarkdownFlow:
|
|
|
237
154
|
mode: ProcessMode = ProcessMode.COMPLETE,
|
|
238
155
|
variables: Optional[Dict[str, str]] = None,
|
|
239
156
|
user_input: Optional[str] = None
|
|
240
|
-
) -> LLMResult: ...
|
|
157
|
+
) -> LLMResult | Generator[LLMResult, None, None]: ...
|
|
241
158
|
```
|
|
242
159
|
|
|
243
160
|
**Methods:**
|
|
@@ -267,18 +184,13 @@ Processing mode enumeration for different use cases.
|
|
|
267
184
|
|
|
268
185
|
```python
|
|
269
186
|
class ProcessMode(Enum):
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
STREAM = "stream" # Streaming LLM responses
|
|
187
|
+
COMPLETE = "complete" # Non-streaming LLM processing
|
|
188
|
+
STREAM = "stream" # Streaming LLM responses
|
|
273
189
|
```
|
|
274
190
|
|
|
275
191
|
**Usage:**
|
|
276
192
|
|
|
277
193
|
```python
|
|
278
|
-
# Generate prompt only
|
|
279
|
-
prompt_result = mf.process(0, ProcessMode.PROMPT_ONLY)
|
|
280
|
-
print(prompt_result.content) # Raw prompt text
|
|
281
|
-
|
|
282
194
|
# Complete response
|
|
283
195
|
complete_result = mf.process(0, ProcessMode.COMPLETE)
|
|
284
196
|
print(complete_result.content) # Full LLM response
|
|
@@ -298,10 +210,10 @@ from typing import Generator
|
|
|
298
210
|
|
|
299
211
|
class LLMProvider(ABC):
|
|
300
212
|
@abstractmethod
|
|
301
|
-
def complete(self,
|
|
213
|
+
def complete(self, messages: list[dict[str, str]]) -> str: ...
|
|
302
214
|
|
|
303
215
|
@abstractmethod
|
|
304
|
-
def stream(self,
|
|
216
|
+
def stream(self, messages: list[dict[str, str]]) -> Generator[str, None, None]: ...
|
|
305
217
|
```
|
|
306
218
|
|
|
307
219
|
**Custom Implementation:**
|
|
@@ -311,23 +223,22 @@ class OpenAIProvider(LLMProvider):
|
|
|
311
223
|
def __init__(self, api_key: str):
|
|
312
224
|
self.client = openai.OpenAI(api_key=api_key)
|
|
313
225
|
|
|
314
|
-
def complete(self,
|
|
315
|
-
response = self.client.completions.create(
|
|
226
|
+
def complete(self, messages: list[dict[str, str]]) -> str:
|
|
227
|
+
response = self.client.chat.completions.create(
|
|
316
228
|
model="gpt-3.5-turbo",
|
|
317
|
-
|
|
318
|
-
max_tokens=500
|
|
229
|
+
messages=messages
|
|
319
230
|
)
|
|
320
|
-
return
|
|
231
|
+
return response.choices[0].message.content
|
|
321
232
|
|
|
322
|
-
def stream(self,
|
|
323
|
-
stream = self.client.completions.create(
|
|
233
|
+
def stream(self, messages: list[dict[str, str]]):
|
|
234
|
+
stream = self.client.chat.completions.create(
|
|
324
235
|
model="gpt-3.5-turbo",
|
|
325
|
-
|
|
236
|
+
messages=messages,
|
|
326
237
|
stream=True
|
|
327
238
|
)
|
|
328
239
|
for chunk in stream:
|
|
329
|
-
if chunk.choices[0].
|
|
330
|
-
yield chunk.choices[0].
|
|
240
|
+
if chunk.choices[0].delta.content:
|
|
241
|
+
yield chunk.choices[0].delta.content
|
|
331
242
|
```
|
|
332
243
|
|
|
333
244
|
### Block Types
|
|
@@ -647,7 +558,7 @@ Include code samples, explanations, and practice exercises.
|
|
|
647
558
|
mode=ProcessMode.STREAM,
|
|
648
559
|
variables={
|
|
649
560
|
'user_name': 'developer',
|
|
650
|
-
'topic': '
|
|
561
|
+
'topic': 'synchronous programming'
|
|
651
562
|
}
|
|
652
563
|
):
|
|
653
564
|
content += chunk.content
|
|
@@ -701,9 +612,9 @@ class InteractiveDocumentBuilder:
|
|
|
701
612
|
self.user_responses.update(response)
|
|
702
613
|
|
|
703
614
|
def handle_interaction(self, interaction_content: str):
|
|
704
|
-
from markdown_flow.
|
|
615
|
+
from markdown_flow.parser import InteractionParser
|
|
705
616
|
|
|
706
|
-
interaction = InteractionParser.parse(interaction_content)
|
|
617
|
+
interaction = InteractionParser().parse(interaction_content)
|
|
707
618
|
print(f"\n{interaction_content}")
|
|
708
619
|
|
|
709
620
|
if interaction.name == "BUTTONS_ONLY":
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
markdown_flow/__init__.py,sha256=wBE8Q9hyL-5sA6OWPuucQDbJAhKZ2XNlPl9xu-71v4k,2775
|
|
2
|
+
markdown_flow/constants.py,sha256=zHXE8E7E4Axf75xZdCdjkLRPfzXDZ8s9D9PxizncrVA,9653
|
|
3
|
+
markdown_flow/core.py,sha256=g2-KbKnD1kPywgNLe1BR81dgZBn1wYJuDxk2WSuhO9Y,42476
|
|
4
|
+
markdown_flow/enums.py,sha256=Wr41zt0Ce5b3fyLtOTE2erEVp1n92g9OVaBF_BZg_l8,820
|
|
5
|
+
markdown_flow/exceptions.py,sha256=9sUZ-Jd3CPLdSRqG8Pw7eMm7cv_S3VZM6jmjUU8OhIc,976
|
|
6
|
+
markdown_flow/llm.py,sha256=MJRbXKj35AjLCAhWpFhS07s-m3YU2qO1HOFff05HG2I,2239
|
|
7
|
+
markdown_flow/models.py,sha256=8uG4mmyTd53UPZNIoBLy03iwcPPrikuXLY4CKuR_oCM,2894
|
|
8
|
+
markdown_flow/utils.py,sha256=TlQan3rNIcbIzgOa-kpphFKpw9IXblFKhIesac_lu3Y,28769
|
|
9
|
+
markdown_flow/parser/__init__.py,sha256=_mua4f2utEvoB6aGk2ZYhbKCJQIEv4_Nnf7Zkyrx8aM,1035
|
|
10
|
+
markdown_flow/parser/interaction.py,sha256=T4W7iO-iyNJnpM7SmvOH_DRlLuWSDcFyIrN2fH6cv7w,12653
|
|
11
|
+
markdown_flow/parser/json_parser.py,sha256=78GhyyOjlg0l4UmKKNc4zrg-4pSHzrJEt7VKqbz3uyE,1305
|
|
12
|
+
markdown_flow/parser/output.py,sha256=LgxvH6-RINM50p58miQtw_fHER1JEWDGucHk5-sZ-gk,8087
|
|
13
|
+
markdown_flow/parser/validation.py,sha256=dkk8MopUdj1Yj6YIcRqRzcgXxUeM679hBAY2pnOC2DU,4417
|
|
14
|
+
markdown_flow/parser/variable.py,sha256=eJLbVOyZT8uYM5eJNv5kHLqdRoNz5iNlxHhhi2oDW94,2986
|
|
15
|
+
markdown_flow/providers/__init__.py,sha256=3dJWYdzb2W8nwOeQIJ-RWO79JOlHaAB9B0dXn1aP4eQ,318
|
|
16
|
+
markdown_flow/providers/config.py,sha256=KJu7uChBcEUZAOjo1GsXB2Cq9DDIaltbiVCOyAw4BDQ,2120
|
|
17
|
+
markdown_flow/providers/openai.py,sha256=NySSSCHloYmkKXwppk3eeBOTh9dVeHu9z9Ne3VaUU0A,12425
|
|
18
|
+
markdown_flow-0.2.26.dist-info/licenses/LICENSE,sha256=qz3BziejhHPd1xa5eVtYEU5Qp6L2pn4otuj194uGxmc,1069
|
|
19
|
+
markdown_flow-0.2.26.dist-info/METADATA,sha256=AxVoOBt1d32QUf-DHbUkjMHDqpYkTg0LqOfec1_9Ea0,20686
|
|
20
|
+
markdown_flow-0.2.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
21
|
+
markdown_flow-0.2.26.dist-info/top_level.txt,sha256=DpigGvQuIt2L0TTLnDU5sylhiTGiZS7MmAMa2hi-AJs,14
|
|
22
|
+
markdown_flow-0.2.26.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
markdown_flow/__init__.py,sha256=IOL89FC4C8kH6qU5bjNsmuumPk3YDEHKHEjnJFFzQRU,2875
|
|
2
|
-
markdown_flow/constants.py,sha256=Wq10-gvskBT6CpI3WiNfZpDIfl-lnAMaHVvjGvYpGG0,8006
|
|
3
|
-
markdown_flow/core.py,sha256=INQ5vIJOFOCYHkBszqCbgn0BGVQ0WXMONtQ6AJmRXkM,51237
|
|
4
|
-
markdown_flow/enums.py,sha256=Wr41zt0Ce5b3fyLtOTE2erEVp1n92g9OVaBF_BZg_l8,820
|
|
5
|
-
markdown_flow/exceptions.py,sha256=9sUZ-Jd3CPLdSRqG8Pw7eMm7cv_S3VZM6jmjUU8OhIc,976
|
|
6
|
-
markdown_flow/llm.py,sha256=MhllCwqzrN_RtIG-whfdkNk6e0WQ2H6RJVCRv3lNM_0,2531
|
|
7
|
-
markdown_flow/models.py,sha256=ENcvXMVXwpFN-RzbeVHhXTjBN0bbmRpJ96K-XS2rizI,2893
|
|
8
|
-
markdown_flow/utils.py,sha256=cVi0zDRK_rCMAr3EDhgITmx6Po5fSvYjqrprYaitYE0,28450
|
|
9
|
-
markdown_flow-0.2.16.dist-info/licenses/LICENSE,sha256=qz3BziejhHPd1xa5eVtYEU5Qp6L2pn4otuj194uGxmc,1069
|
|
10
|
-
markdown_flow-0.2.16.dist-info/METADATA,sha256=0uwa1wYOmt5MjukW6x2MTlUxYO-zn9Q4hkKu_NSiKOc,24287
|
|
11
|
-
markdown_flow-0.2.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
markdown_flow-0.2.16.dist-info/top_level.txt,sha256=DpigGvQuIt2L0TTLnDU5sylhiTGiZS7MmAMa2hi-AJs,14
|
|
13
|
-
markdown_flow-0.2.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|