markdown-flow 0.2.12__tar.gz → 0.2.28__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.
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/PKG-INFO +18 -107
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/README.md +17 -106
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/__init__.py +7 -7
- markdown_flow-0.2.28/markdown_flow/constants.py +359 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/core.py +588 -540
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/llm.py +10 -12
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/models.py +1 -1
- markdown_flow-0.2.28/markdown_flow/parser/__init__.py +38 -0
- markdown_flow-0.2.28/markdown_flow/parser/code_fence_utils.py +190 -0
- markdown_flow-0.2.28/markdown_flow/parser/interaction.py +354 -0
- markdown_flow-0.2.28/markdown_flow/parser/json_parser.py +50 -0
- markdown_flow-0.2.28/markdown_flow/parser/output.py +215 -0
- markdown_flow-0.2.28/markdown_flow/parser/preprocessor.py +151 -0
- markdown_flow-0.2.28/markdown_flow/parser/validation.py +121 -0
- markdown_flow-0.2.28/markdown_flow/parser/variable.py +95 -0
- markdown_flow-0.2.28/markdown_flow/providers/__init__.py +16 -0
- markdown_flow-0.2.28/markdown_flow/providers/config.py +48 -0
- markdown_flow-0.2.28/markdown_flow/providers/openai.py +369 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/utils.py +49 -51
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow.egg-info/PKG-INFO +18 -107
- markdown_flow-0.2.28/markdown_flow.egg-info/SOURCES.txt +32 -0
- markdown_flow-0.2.28/tests/test_markdownflow_basic.py +232 -0
- markdown_flow-0.2.28/tests/test_parser_interaction.py +124 -0
- markdown_flow-0.2.28/tests/test_parser_variable.py +111 -0
- markdown_flow-0.2.28/tests/test_preprocessor.py +288 -0
- markdown_flow-0.2.28/tests/test_preserved_simple.py +262 -0
- markdown_flow-0.2.12/markdown_flow/constants.py +0 -174
- markdown_flow-0.2.12/markdown_flow.egg-info/SOURCES.txt +0 -16
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/LICENSE +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/enums.py +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow/exceptions.py +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow.egg-info/dependency_links.txt +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/markdown_flow.egg-info/top_level.txt +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/pyproject.toml +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/setup.cfg +0 -0
- {markdown_flow-0.2.12 → markdown_flow-0.2.28}/tests/test_dynamic_interaction.py +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.28
|
|
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":
|
|
@@ -74,36 +74,6 @@ for chunk in mf.process(
|
|
|
74
74
|
print(chunk.content, end='')
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### Dynamic Interaction Generation ✨
|
|
78
|
-
|
|
79
|
-
Transform natural language content into interactive elements automatically:
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
from markdown_flow import MarkdownFlow, ProcessMode
|
|
83
|
-
|
|
84
|
-
# Dynamic interaction generation works automatically
|
|
85
|
-
mf = MarkdownFlow(
|
|
86
|
-
document="询问用户的菜品偏好,并记录到变量{{菜品选择}}",
|
|
87
|
-
llm_provider=llm_provider,
|
|
88
|
-
document_prompt="你是中餐厅服务员,提供川菜、粤菜、鲁菜等选项"
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Process with Function Calling
|
|
92
|
-
result = mf.process(0, ProcessMode.COMPLETE)
|
|
93
|
-
|
|
94
|
-
if result.transformed_to_interaction:
|
|
95
|
-
print(f"Generated interaction: {result.content}")
|
|
96
|
-
# Output: ?[%{{菜品选择}} 宫保鸡丁||麻婆豆腐||水煮鱼||...其他菜品]
|
|
97
|
-
|
|
98
|
-
# Continue with user input
|
|
99
|
-
user_result = mf.process(
|
|
100
|
-
block_index=0,
|
|
101
|
-
mode=ProcessMode.COMPLETE,
|
|
102
|
-
user_input={"菜品选择": ["宫保鸡丁", "麻婆豆腐"]},
|
|
103
|
-
dynamic_interaction_format=result.content
|
|
104
|
-
)
|
|
105
|
-
```
|
|
106
|
-
|
|
107
77
|
### Interactive Elements
|
|
108
78
|
|
|
109
79
|
```python
|
|
@@ -141,59 +111,6 @@ result = mf.process(
|
|
|
141
111
|
)
|
|
142
112
|
```
|
|
143
113
|
|
|
144
|
-
## ✨ Key Features
|
|
145
|
-
|
|
146
|
-
### 🏗️ Three-Layer Architecture
|
|
147
|
-
|
|
148
|
-
- **Document Level**: Parse `---` separators and `?[]` interaction patterns
|
|
149
|
-
- **Block Level**: Categorize as CONTENT, INTERACTION, or PRESERVED_CONTENT
|
|
150
|
-
- **Interaction Level**: Handle 6 different interaction types with smart validation
|
|
151
|
-
|
|
152
|
-
### 🔄 Dynamic Interaction Generation
|
|
153
|
-
|
|
154
|
-
- **Natural Language Input**: Write content in plain language
|
|
155
|
-
- **AI-Powered Conversion**: LLM automatically detects interaction needs using Function Calling
|
|
156
|
-
- **Structured Data Generation**: LLM returns structured data, core builds MarkdownFlow format
|
|
157
|
-
- **Language Agnostic**: Support for any language with proper document prompts
|
|
158
|
-
- **Context Awareness**: Both original and resolved variable contexts provided to LLM
|
|
159
|
-
|
|
160
|
-
### 🤖 Unified LLM Integration
|
|
161
|
-
|
|
162
|
-
- **Single Interface**: One `complete()` method for both regular and Function Calling modes
|
|
163
|
-
- **Automatic Detection**: Tools parameter determines processing mode automatically
|
|
164
|
-
- **Consistent Returns**: Always returns `LLMResult` with structured metadata
|
|
165
|
-
- **Error Handling**: Automatic fallback from Function Calling to regular completion
|
|
166
|
-
- **Provider Agnostic**: Abstract interface supports any LLM service
|
|
167
|
-
|
|
168
|
-
### 📝 Variable System
|
|
169
|
-
|
|
170
|
-
- **Replaceable Variables**: `{{variable}}` for content personalization
|
|
171
|
-
- **Preserved Variables**: `%{{variable}}` for LLM understanding in interactions
|
|
172
|
-
- **Multi-Value Support**: Handle both single values and arrays
|
|
173
|
-
- **Smart Extraction**: Automatic detection from document content
|
|
174
|
-
|
|
175
|
-
### 🎯 Interaction Types
|
|
176
|
-
|
|
177
|
-
- **Text Input**: `?[%{{var}}...question]` - Free text entry
|
|
178
|
-
- **Single Select**: `?[%{{var}} A|B|C]` - Choose one option
|
|
179
|
-
- **Multi Select**: `?[%{{var}} A||B||C]` - Choose multiple options
|
|
180
|
-
- **Mixed Mode**: `?[%{{var}} A||B||...custom]` - Predefined + custom input
|
|
181
|
-
- **Display Buttons**: `?[Continue|Cancel]` - Action buttons without assignment
|
|
182
|
-
- **Value Separation**: `?[%{{var}} Display//value|...]` - Different display/stored values
|
|
183
|
-
|
|
184
|
-
### 🔒 Content Preservation
|
|
185
|
-
|
|
186
|
-
- **Multiline Format**: `!===content!===` blocks output exactly as written
|
|
187
|
-
- **Inline Format**: `===content===` for single-line preserved content
|
|
188
|
-
- **Variable Support**: Preserved content can contain variables for substitution
|
|
189
|
-
|
|
190
|
-
### ⚡ Performance Optimized
|
|
191
|
-
|
|
192
|
-
- **Pre-compiled Regex**: All patterns compiled once for maximum performance
|
|
193
|
-
- **Synchronous Interface**: Clean synchronous operations with optional streaming
|
|
194
|
-
- **Stream Processing**: Real-time streaming responses supported
|
|
195
|
-
- **Memory Efficient**: Lazy evaluation and generator patterns
|
|
196
|
-
|
|
197
114
|
## 📖 API Reference
|
|
198
115
|
|
|
199
116
|
### Core Classes
|
|
@@ -219,7 +136,7 @@ class MarkdownFlow:
|
|
|
219
136
|
mode: ProcessMode = ProcessMode.COMPLETE,
|
|
220
137
|
variables: Optional[Dict[str, str]] = None,
|
|
221
138
|
user_input: Optional[str] = None
|
|
222
|
-
) -> LLMResult: ...
|
|
139
|
+
) -> LLMResult | Generator[LLMResult, None, None]: ...
|
|
223
140
|
```
|
|
224
141
|
|
|
225
142
|
**Methods:**
|
|
@@ -249,18 +166,13 @@ Processing mode enumeration for different use cases.
|
|
|
249
166
|
|
|
250
167
|
```python
|
|
251
168
|
class ProcessMode(Enum):
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
STREAM = "stream" # Streaming LLM responses
|
|
169
|
+
COMPLETE = "complete" # Non-streaming LLM processing
|
|
170
|
+
STREAM = "stream" # Streaming LLM responses
|
|
255
171
|
```
|
|
256
172
|
|
|
257
173
|
**Usage:**
|
|
258
174
|
|
|
259
175
|
```python
|
|
260
|
-
# Generate prompt only
|
|
261
|
-
prompt_result = mf.process(0, ProcessMode.PROMPT_ONLY)
|
|
262
|
-
print(prompt_result.content) # Raw prompt text
|
|
263
|
-
|
|
264
176
|
# Complete response
|
|
265
177
|
complete_result = mf.process(0, ProcessMode.COMPLETE)
|
|
266
178
|
print(complete_result.content) # Full LLM response
|
|
@@ -280,10 +192,10 @@ from typing import Generator
|
|
|
280
192
|
|
|
281
193
|
class LLMProvider(ABC):
|
|
282
194
|
@abstractmethod
|
|
283
|
-
def complete(self,
|
|
195
|
+
def complete(self, messages: list[dict[str, str]]) -> str: ...
|
|
284
196
|
|
|
285
197
|
@abstractmethod
|
|
286
|
-
def stream(self,
|
|
198
|
+
def stream(self, messages: list[dict[str, str]]) -> Generator[str, None, None]: ...
|
|
287
199
|
```
|
|
288
200
|
|
|
289
201
|
**Custom Implementation:**
|
|
@@ -293,23 +205,22 @@ class OpenAIProvider(LLMProvider):
|
|
|
293
205
|
def __init__(self, api_key: str):
|
|
294
206
|
self.client = openai.OpenAI(api_key=api_key)
|
|
295
207
|
|
|
296
|
-
def complete(self,
|
|
297
|
-
response = self.client.completions.create(
|
|
208
|
+
def complete(self, messages: list[dict[str, str]]) -> str:
|
|
209
|
+
response = self.client.chat.completions.create(
|
|
298
210
|
model="gpt-3.5-turbo",
|
|
299
|
-
|
|
300
|
-
max_tokens=500
|
|
211
|
+
messages=messages
|
|
301
212
|
)
|
|
302
|
-
return
|
|
213
|
+
return response.choices[0].message.content
|
|
303
214
|
|
|
304
|
-
def stream(self,
|
|
305
|
-
stream = self.client.completions.create(
|
|
215
|
+
def stream(self, messages: list[dict[str, str]]):
|
|
216
|
+
stream = self.client.chat.completions.create(
|
|
306
217
|
model="gpt-3.5-turbo",
|
|
307
|
-
|
|
218
|
+
messages=messages,
|
|
308
219
|
stream=True
|
|
309
220
|
)
|
|
310
221
|
for chunk in stream:
|
|
311
|
-
if chunk.choices[0].
|
|
312
|
-
yield chunk.choices[0].
|
|
222
|
+
if chunk.choices[0].delta.content:
|
|
223
|
+
yield chunk.choices[0].delta.content
|
|
313
224
|
```
|
|
314
225
|
|
|
315
226
|
### Block Types
|
|
@@ -629,7 +540,7 @@ Include code samples, explanations, and practice exercises.
|
|
|
629
540
|
mode=ProcessMode.STREAM,
|
|
630
541
|
variables={
|
|
631
542
|
'user_name': 'developer',
|
|
632
|
-
'topic': '
|
|
543
|
+
'topic': 'synchronous programming'
|
|
633
544
|
}
|
|
634
545
|
):
|
|
635
546
|
content += chunk.content
|
|
@@ -683,9 +594,9 @@ class InteractiveDocumentBuilder:
|
|
|
683
594
|
self.user_responses.update(response)
|
|
684
595
|
|
|
685
596
|
def handle_interaction(self, interaction_content: str):
|
|
686
|
-
from markdown_flow.
|
|
597
|
+
from markdown_flow.parser import InteractionParser
|
|
687
598
|
|
|
688
|
-
interaction = InteractionParser.parse(interaction_content)
|
|
599
|
+
interaction = InteractionParser().parse(interaction_content)
|
|
689
600
|
print(f"\n{interaction_content}")
|
|
690
601
|
|
|
691
602
|
if interaction.name == "BUTTONS_ONLY":
|
|
@@ -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,5 @@ __all__ = [
|
|
|
83
82
|
"replace_variables_in_text",
|
|
84
83
|
]
|
|
85
84
|
|
|
86
|
-
__version__ = "0.2.
|
|
85
|
+
__version__ = "0.2.28"
|
|
86
|
+
# __version__ = "0.2.27-alpha-8"
|