soprano-sdk 0.1.99__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 (93) hide show
  1. soprano_sdk-0.1.99/.github/workflows/test_build_and_publish.yaml +63 -0
  2. soprano_sdk-0.1.99/.gitignore +11 -0
  3. soprano_sdk-0.1.99/.python-version +1 -0
  4. soprano_sdk-0.1.99/CLAUDE.md +51 -0
  5. soprano_sdk-0.1.99/LICENSE +21 -0
  6. soprano_sdk-0.1.99/PKG-INFO +420 -0
  7. soprano_sdk-0.1.99/README.md +381 -0
  8. soprano_sdk-0.1.99/examples/framework_example.yaml +48 -0
  9. soprano_sdk-0.1.99/examples/greeting_functions.py +14 -0
  10. soprano_sdk-0.1.99/examples/greeting_workflow.yaml +224 -0
  11. soprano_sdk-0.1.99/examples/main.py +32 -0
  12. soprano_sdk-0.1.99/examples/persistence/README.md +297 -0
  13. soprano_sdk-0.1.99/examples/persistence/conversation_based.py +135 -0
  14. soprano_sdk-0.1.99/examples/persistence/entity_based.py +83 -0
  15. soprano_sdk-0.1.99/examples/persistence/mongodb_demo.py +138 -0
  16. soprano_sdk-0.1.99/examples/return_functions.py +68 -0
  17. soprano_sdk-0.1.99/examples/return_workflow.yaml +129 -0
  18. soprano_sdk-0.1.99/examples/structured_output_example.yaml +67 -0
  19. soprano_sdk-0.1.99/examples/supervisors/README.md +265 -0
  20. soprano_sdk-0.1.99/examples/supervisors/crewai_supervisor_ui.py +170 -0
  21. soprano_sdk-0.1.99/examples/supervisors/langgraph_supervisor_ui.py +179 -0
  22. soprano_sdk-0.1.99/examples/supervisors/tools/__init__.py +1 -0
  23. soprano_sdk-0.1.99/examples/supervisors/tools/crewai_tools.py +100 -0
  24. soprano_sdk-0.1.99/examples/supervisors/tools/langgraph_tools.py +90 -0
  25. soprano_sdk-0.1.99/examples/supervisors/workflow_tools.py +75 -0
  26. soprano_sdk-0.1.99/examples/tools/__init__.py +0 -0
  27. soprano_sdk-0.1.99/examples/tools/address.py +34 -0
  28. soprano_sdk-0.1.99/examples/validator.py +36 -0
  29. soprano_sdk-0.1.99/legacy/langgraph_demo.py +92 -0
  30. soprano_sdk-0.1.99/legacy/langgraph_selfloop_demo.py +167 -0
  31. soprano_sdk-0.1.99/legacy/langgraph_v.py +319 -0
  32. soprano_sdk-0.1.99/legacy/main.py +240 -0
  33. soprano_sdk-0.1.99/legacy/return_fsm.excalidraw +1310 -0
  34. soprano_sdk-0.1.99/legacy/return_state_machine.png +0 -0
  35. soprano_sdk-0.1.99/legacy/ui.py +20 -0
  36. soprano_sdk-0.1.99/pyproject.toml +63 -0
  37. soprano_sdk-0.1.99/scripts/visualize_workflow.py +56 -0
  38. soprano_sdk-0.1.99/scripts/workflow_demo.py +125 -0
  39. soprano_sdk-0.1.99/scripts/workflow_demo_ui.py +112 -0
  40. soprano_sdk-0.1.99/soprano_sdk/__init__.py +10 -0
  41. soprano_sdk-0.1.99/soprano_sdk/agents/__init__.py +30 -0
  42. soprano_sdk-0.1.99/soprano_sdk/agents/adaptor.py +90 -0
  43. soprano_sdk-0.1.99/soprano_sdk/agents/factory.py +228 -0
  44. soprano_sdk-0.1.99/soprano_sdk/agents/structured_output.py +97 -0
  45. soprano_sdk-0.1.99/soprano_sdk/core/__init__.py +0 -0
  46. soprano_sdk-0.1.99/soprano_sdk/core/constants.py +59 -0
  47. soprano_sdk-0.1.99/soprano_sdk/core/engine.py +225 -0
  48. soprano_sdk-0.1.99/soprano_sdk/core/rollback_strategies.py +258 -0
  49. soprano_sdk-0.1.99/soprano_sdk/core/state.py +71 -0
  50. soprano_sdk-0.1.99/soprano_sdk/engine.py +381 -0
  51. soprano_sdk-0.1.99/soprano_sdk/nodes/__init__.py +0 -0
  52. soprano_sdk-0.1.99/soprano_sdk/nodes/base.py +56 -0
  53. soprano_sdk-0.1.99/soprano_sdk/nodes/call_function.py +112 -0
  54. soprano_sdk-0.1.99/soprano_sdk/nodes/collect_input.py +542 -0
  55. soprano_sdk-0.1.99/soprano_sdk/nodes/factory.py +46 -0
  56. soprano_sdk-0.1.99/soprano_sdk/routing/__init__.py +0 -0
  57. soprano_sdk-0.1.99/soprano_sdk/routing/router.py +97 -0
  58. soprano_sdk-0.1.99/soprano_sdk/tools.py +206 -0
  59. soprano_sdk-0.1.99/soprano_sdk/utils/__init__.py +0 -0
  60. soprano_sdk-0.1.99/soprano_sdk/utils/function.py +35 -0
  61. soprano_sdk-0.1.99/soprano_sdk/utils/logger.py +6 -0
  62. soprano_sdk-0.1.99/soprano_sdk/utils/template.py +27 -0
  63. soprano_sdk-0.1.99/soprano_sdk/utils/tool.py +60 -0
  64. soprano_sdk-0.1.99/soprano_sdk/utils/tracing.py +69 -0
  65. soprano_sdk-0.1.99/soprano_sdk/validation/__init__.py +13 -0
  66. soprano_sdk-0.1.99/soprano_sdk/validation/schema.py +297 -0
  67. soprano_sdk-0.1.99/soprano_sdk/validation/validator.py +173 -0
  68. soprano_sdk-0.1.99/tests/debug_jinja2.py +30 -0
  69. soprano_sdk-0.1.99/tests/test_agent_factory.py +151 -0
  70. soprano_sdk-0.1.99/tests/test_collect_input_refactor.py +27 -0
  71. soprano_sdk-0.1.99/tests/test_external_values.py +70 -0
  72. soprano_sdk-0.1.99/tests/test_inputs_validation.py +77 -0
  73. soprano_sdk-0.1.99/tests/test_jinja2_path.py +63 -0
  74. soprano_sdk-0.1.99/tests/test_jinja2_standalone.py +103 -0
  75. soprano_sdk-0.1.99/tests/test_persistence.py +160 -0
  76. soprano_sdk-0.1.99/tests/test_structured_output.py +165 -0
  77. soprano_sdk-0.1.99/tests/test_transition_routing.py +136 -0
  78. soprano_sdk-0.1.99/todo.md +24 -0
  79. soprano_sdk-0.1.99/uv.lock +5165 -0
  80. soprano_sdk-0.1.99/workflow-visualizer/.eslintrc.cjs +21 -0
  81. soprano_sdk-0.1.99/workflow-visualizer/.gitignore +24 -0
  82. soprano_sdk-0.1.99/workflow-visualizer/README.md +8 -0
  83. soprano_sdk-0.1.99/workflow-visualizer/index.html +13 -0
  84. soprano_sdk-0.1.99/workflow-visualizer/package-lock.json +5931 -0
  85. soprano_sdk-0.1.99/workflow-visualizer/package.json +33 -0
  86. soprano_sdk-0.1.99/workflow-visualizer/src/App.jsx +217 -0
  87. soprano_sdk-0.1.99/workflow-visualizer/src/CustomNode.jsx +124 -0
  88. soprano_sdk-0.1.99/workflow-visualizer/src/StepDetailsModal.jsx +267 -0
  89. soprano_sdk-0.1.99/workflow-visualizer/src/WorkflowGraph.jsx +286 -0
  90. soprano_sdk-0.1.99/workflow-visualizer/src/WorkflowInfoPanel.jsx +170 -0
  91. soprano_sdk-0.1.99/workflow-visualizer/src/assets/react.svg +1 -0
  92. soprano_sdk-0.1.99/workflow-visualizer/src/main.jsx +9 -0
  93. soprano_sdk-0.1.99/workflow-visualizer/vite.config.js +7 -0
@@ -0,0 +1,63 @@
1
+ name: Conversational SOP Framework CI/CD
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags: [ 'v*' ]
7
+ pull_request:
8
+ branches: [ main ]
9
+
10
+ jobs:
11
+ test:
12
+ name: Test and Lint
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Install uv
18
+ uses: astral-sh/setup-uv@v3
19
+ with:
20
+ version: "latest"
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version-file: ".python-version"
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --all-extras --dev
29
+
30
+ - name: Lint with ruff
31
+ run: uv run ruff check .
32
+
33
+ - name: Run tests
34
+ run: uv run pytest
35
+
36
+ release:
37
+ name: Build and Publish
38
+ needs: test
39
+ if: startsWith(github.ref, 'refs/tags/v')
40
+ runs-on: ubuntu-latest
41
+ permissions:
42
+ id-token: write
43
+ contents: read
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+
47
+ - name: Install uv
48
+ uses: astral-sh/setup-uv@v3
49
+ with:
50
+ version: "latest"
51
+
52
+ - name: Set up Python
53
+ uses: actions/setup-python@v5
54
+ with:
55
+ python-version-file: ".python-version"
56
+
57
+ - name: Build package
58
+ run: uv build
59
+
60
+ - name: Publish to PyPI
61
+ run: uv publish
62
+ env:
63
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
@@ -0,0 +1,11 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ .idea
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,51 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Development Commands
6
+
7
+ - **Install dependencies**: `uv sync` (uses uv.lock)
8
+ - **Run the application**: `python ui.py` (launches Gradio interface)
9
+ - **Run core logic directly**: `python main.py` (for testing state machine)
10
+
11
+ ## Project Architecture
12
+
13
+ This is a conversational SOP (Standard Operating Procedure) framework that implements a return processing workflow using finite state machines. The architecture consists of:
14
+
15
+ ### Core Components
16
+
17
+ 1. **State Machine (`main.py`)**:
18
+ - Uses `transitions` library to implement a finite state machine
19
+ - Defines `States` enum with 6 states: COLLECTING_ORDER_ID → CHECKING_RETURN_ELIGIBILITY → COLLECTING_RETURN_REASON → CHECKING_REASON_VALIDITY → PROCESSING_RETURN → COMPLETED
20
+ - `ReturnProcessor` class manages state transitions and business logic
21
+ - Integrates with `agno` AI agent framework using OpenAI GPT models
22
+
23
+ 2. **UI Layer (`ui.py`)**:
24
+ - Gradio-based chat interface that wraps the core state machine
25
+ - `run()` function serves as the main entry point for user interactions
26
+ - Passes conversation history and current date to the return processor
27
+
28
+ ### Key Dependencies
29
+
30
+ - **agno**: AI agent framework for conversational interactions
31
+ - **transitions**: State machine implementation
32
+ - **gradio**: Web-based chat interface
33
+ - **openai**: LLM integration (currently using gpt-5-mini)
34
+
35
+ ### State Flow
36
+
37
+ The return processing follows this workflow:
38
+ 1. Collect order ID from user
39
+ 2. Check if order is eligible for return
40
+ 3. Collect return reason from user
41
+ 4. Validate the return reason
42
+ 5. Process the return
43
+ 6. Complete the workflow
44
+
45
+ Each state has corresponding trigger methods that advance the workflow or terminate it based on business rules.
46
+
47
+ ### Development Notes
48
+
49
+ - The main logic is partially implemented with some placeholder/test code (random number generation)
50
+ - The AI agent in `collect_order_id()` currently has hardcoded instructions for "loan number" capture
51
+ - State machine callbacks are configured but not all are fully implemented
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Arvind Thangamani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,420 @@
1
+ Metadata-Version: 2.4
2
+ Name: soprano-sdk
3
+ Version: 0.1.99
4
+ Summary: YAML-driven workflow engine with AI agent integration for building conversational SOPs
5
+ Author: Arvind Thangamani
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: agent,ai,conversational,langgraph,sop,soprano,workflow
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Python: >=3.12
15
+ Requires-Dist: agno>=2.0.7
16
+ Requires-Dist: crewai>=0.186.1
17
+ Requires-Dist: jsonschema>=4.0.0
18
+ Requires-Dist: langchain-community>=0.4.1
19
+ Requires-Dist: langchain-core>=0.3.67
20
+ Requires-Dist: langchain-openai>=1.0.3
21
+ Requires-Dist: langchain>=1.0.7
22
+ Requires-Dist: langfuse>=3.10.1
23
+ Requires-Dist: langgraph==1.0.2
24
+ Requires-Dist: openai>=1.92.1
25
+ Requires-Dist: pydantic-ai>=1.22.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: pytest>=9.0.1
28
+ Requires-Dist: pyyaml>=6.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: gradio>=5.46.0; extra == 'dev'
31
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
32
+ Provides-Extra: persistence
33
+ Requires-Dist: langgraph-checkpoint-mongodb>=0.2.0; extra == 'persistence'
34
+ Requires-Dist: pymongo>=4.0.0; extra == 'persistence'
35
+ Provides-Extra: supervisors
36
+ Requires-Dist: crewai>=0.1.0; extra == 'supervisors'
37
+ Requires-Dist: langchain-openai>=0.3.34; extra == 'supervisors'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # Conversational SOP Framework
41
+
42
+ A YAML-driven workflow engine with AI agent integration for building conversational Standard Operating Procedures (SOPs).
43
+
44
+ ## Features
45
+
46
+ - **YAML Configuration**: Define workflows declaratively using YAML
47
+ - **AI Agent Integration**: Built-in support for conversational data collection using OpenAI models
48
+ - **State Management**: Powered by LangGraph for robust workflow execution
49
+ - **External Context Injection**: Support for pre-populated fields from external orchestrators
50
+ - **Pattern Matching**: Flexible transition logic based on patterns and conditions
51
+ - **Visualization**: Generate workflow graphs as images or Mermaid diagrams
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install conversational-sop-framework
57
+ ```
58
+
59
+ Or using uv:
60
+
61
+ ```bash
62
+ uv add conversational-sop-framework
63
+ ```
64
+
65
+ ## Quick Start
66
+
67
+ ### 1. Define a Workflow in YAML
68
+
69
+ ```yaml
70
+ name: "User Greeting Workflow"
71
+ description: "Collects user information and provides a personalized greeting"
72
+ version: "1.0"
73
+
74
+ data:
75
+ - name: name
76
+ type: text
77
+ description: "User's name"
78
+ - name: age
79
+ type: number
80
+ description: "User's age in years"
81
+
82
+ steps:
83
+ - id: get_name
84
+ action: collect_input_with_agent
85
+ field: name
86
+ max_attempts: 3
87
+ agent:
88
+ name: "NameCollector"
89
+ model: "gpt-4o-mini"
90
+ instructions: |
91
+ Your goal is to capture the user's name.
92
+ Start with a friendly greeting and ask for their name.
93
+ Once you have a clear name, respond with: 'NAME_CAPTURED: [name]'
94
+ transitions:
95
+ - pattern: "NAME_CAPTURED:"
96
+ next: get_age
97
+ - pattern: "NAME_FAILED:"
98
+ next: end_failed
99
+
100
+ - id: get_age
101
+ action: collect_input_with_agent
102
+ field: age
103
+ max_attempts: 3
104
+ agent:
105
+ name: "AgeCollector"
106
+ model: "gpt-4o-mini"
107
+ instructions: |
108
+ Ask for the user's age.
109
+ Once you have a valid age, respond with: 'AGE_CAPTURED: [age]'
110
+ transitions:
111
+ - pattern: "AGE_CAPTURED:"
112
+ next: end_success
113
+ - pattern: "AGE_FAILED:"
114
+ next: end_failed
115
+
116
+ outcomes:
117
+ - id: end_success
118
+ type: success
119
+ message: "Hello {name}! You are {age} years old."
120
+
121
+ - id: end_failed
122
+ type: failure
123
+ message: "Sorry, I couldn't complete the workflow."
124
+ ```
125
+
126
+ ### 2. Load and Execute the Workflow
127
+
128
+ ```python
129
+ from soprano_sdk import load_workflow
130
+ from langgraph.types import Command
131
+ import uuid
132
+
133
+ # Load workflow
134
+ graph, engine = load_workflow("greeting_workflow.yaml")
135
+
136
+ # Setup execution
137
+ thread_id = str(uuid.uuid4())
138
+ config = {"configurable": {"thread_id": thread_id}}
139
+
140
+ # Start workflow
141
+ result = graph.invoke({}, config=config)
142
+
143
+ # Interaction loop
144
+ while True:
145
+ if "__interrupt__" in result and result["__interrupt__"]:
146
+ # Get prompt from workflow
147
+ prompt = result["__interrupt__"][0].value
148
+ print(f"Bot: {prompt}")
149
+
150
+ # Get user input
151
+ user_input = input("You: ")
152
+
153
+ # Resume workflow with user input
154
+ result = graph.invoke(Command(resume=user_input), config=config)
155
+ else:
156
+ # Workflow completed
157
+ message = engine.get_outcome_message(result)
158
+ print(f"Bot: {message}")
159
+ break
160
+ ```
161
+
162
+ ### 3. External Context Injection
163
+
164
+ You can inject external context into workflows:
165
+
166
+ ```python
167
+ # Pre-populate fields from external orchestrator
168
+ result = graph.invoke({
169
+ "name": "Alice",
170
+ "age": 30
171
+ }, config=config)
172
+
173
+ # Workflow will automatically skip collection steps
174
+ # and proceed to validation/processing
175
+ ```
176
+
177
+ ### 4. Persistence
178
+
179
+ The library supports pluggable persistence through LangGraph's checkpointer system.
180
+
181
+ #### In-Memory (Default)
182
+
183
+ ```python
184
+ # No persistence - state lost when process ends
185
+ graph, engine = load_workflow("workflow.yaml")
186
+ ```
187
+
188
+ #### MongoDB Persistence
189
+
190
+ ```python
191
+ from soprano_sdk import load_workflow
192
+ from langgraph.checkpoint.mongodb import MongoDBSaver
193
+ from pymongo import MongoClient
194
+
195
+ # Setup MongoDB persistence (local)
196
+ client = MongoClient("mongodb://localhost:27017")
197
+ checkpointer = MongoDBSaver(client=client, db_name="workflows")
198
+
199
+ # Or MongoDB Atlas (cloud)
200
+ client = MongoClient("mongodb+srv://user:pass@cluster.mongodb.net")
201
+ checkpointer = MongoDBSaver(client=client, db_name="workflows")
202
+
203
+ # Load workflow with persistence
204
+ graph, engine = load_workflow("workflow.yaml", checkpointer=checkpointer)
205
+
206
+ # Execute with thread_id for state tracking
207
+ config = {"configurable": {"thread_id": "user-123-return"}}
208
+ result = graph.invoke({}, config=config)
209
+
210
+ # Later, resume using same thread_id
211
+ result = graph.invoke(Command(resume="continue"), config=config)
212
+ ```
213
+
214
+ #### Thread ID Strategies
215
+
216
+ Choose a thread_id strategy based on your use case:
217
+
218
+ | Strategy | Thread ID Pattern | Best For |
219
+ |----------|-------------------|----------|
220
+ | **Entity-Based** | `f"return_{order_id}"` | One workflow per business entity |
221
+ | **Conversation** | `str(uuid.uuid4())` | Multiple concurrent workflows |
222
+ | **User+Workflow** | `f"{user_id}_{workflow_type}"` | One workflow type per user |
223
+ | **Session-Based** | `session_id` | Web apps with sessions |
224
+
225
+ **Examples**: See `examples/persistence/` for detailed examples of each strategy.
226
+
227
+ ## Workflow Actions
228
+
229
+ ### collect_input_with_agent
230
+
231
+ Collects user input using an AI agent with conversation history.
232
+
233
+ ```yaml
234
+ - id: collect_field
235
+ action: collect_input_with_agent
236
+ field: field_name
237
+ max_attempts: 5
238
+ agent:
239
+ name: "CollectorAgent"
240
+ model: "gpt-4o-mini"
241
+ instructions: |
242
+ Instructions for the agent...
243
+ transitions:
244
+ - pattern: "SUCCESS:"
245
+ next: next_step
246
+ - pattern: "FAILED:"
247
+ next: failure_outcome
248
+ ```
249
+
250
+ ### call_function
251
+
252
+ Calls a Python function with workflow state.
253
+
254
+ ```yaml
255
+ - id: process_data
256
+ action: call_function
257
+ function: "my_module.my_function"
258
+ inputs:
259
+ field1: "{field_name}"
260
+ field2: "static_value"
261
+ output: result_field
262
+ transitions:
263
+ - condition: true
264
+ next: success_step
265
+ - condition: false
266
+ next: failure_step
267
+ ```
268
+
269
+ ## Examples
270
+
271
+ See the `examples/` directory for complete workflow examples:
272
+
273
+ - `greeting_workflow.yaml` - Simple user greeting workflow
274
+ - `return_workflow.yaml` - Customer return processing workflow
275
+ - Function modules with business logic (`greeting_functions.py`, `return_functions.py`)
276
+ - `persistence/` - Persistence strategy examples (entity-based, conversation-based, SQLite demo)
277
+
278
+ ## Running Workflows
279
+
280
+ ### CLI Demo
281
+
282
+ ```bash
283
+ # Basic usage (in-memory)
284
+ python scripts/workflow_demo.py examples/greeting_workflow.yaml
285
+
286
+ # With MongoDB persistence (local)
287
+ python scripts/workflow_demo.py examples/greeting_workflow.yaml --mongodb mongodb://localhost:27017
288
+
289
+ # Resume existing workflow
290
+ python scripts/workflow_demo.py examples/greeting_workflow.yaml --mongodb mongodb://localhost:27017 --thread-id abc-123
291
+
292
+ # With MongoDB Atlas
293
+ python scripts/workflow_demo.py examples/greeting_workflow.yaml --mongodb mongodb+srv://user:pass@cluster.mongodb.net
294
+ ```
295
+
296
+ ### Gradio UI
297
+
298
+ ```bash
299
+ # Basic usage (in-memory)
300
+ python scripts/workflow_demo_ui.py examples/greeting_workflow.yaml
301
+
302
+ # With MongoDB persistence
303
+ python scripts/workflow_demo_ui.py examples/greeting_workflow.yaml --mongodb mongodb://localhost:27017
304
+
305
+ # With MongoDB Atlas
306
+ python scripts/workflow_demo_ui.py examples/greeting_workflow.yaml --mongodb mongodb+srv://user:pass@cluster.mongodb.net
307
+ ```
308
+
309
+ ### Persistence Examples
310
+
311
+ ```bash
312
+ cd examples/persistence
313
+
314
+ # Entity-based (order ID as thread ID)
315
+ python entity_based.py ORDER-123
316
+
317
+ # Conversation-based (UUID with supervisor pattern)
318
+ python conversation_based.py ../return_workflow.yaml --order-id ORDER-456
319
+
320
+ # MongoDB demo with pause/resume
321
+ python mongodb_demo.py
322
+
323
+ # Use MongoDB Atlas
324
+ python mongodb_demo.py --mongodb mongodb+srv://user:pass@cluster.mongodb.net
325
+ ```
326
+
327
+ ### Visualize Workflow
328
+
329
+ ```bash
330
+ python scripts/visualize_workflow.py examples/greeting_workflow.yaml
331
+ ```
332
+
333
+ ## Development
334
+
335
+ ### Setup
336
+
337
+ ```bash
338
+ git clone https://github.com/dnivra26/soprano_sdk_framework.git
339
+ cd soprano_sdk_framework
340
+ uv sync --dev
341
+ ```
342
+
343
+ ### Run Tests
344
+
345
+ ```bash
346
+ python tests/test_external_values.py
347
+ ```
348
+
349
+ ## Architecture
350
+
351
+ - **soprano_sdk/**: Core library package
352
+ - `engine.py`: Workflow engine implementation
353
+ - `__init__.py`: Public API exports
354
+
355
+ - **examples/**: Example workflows and persistence patterns
356
+ - Workflow YAML definitions
357
+ - Function modules with business logic
358
+ - `persistence/`: Different persistence strategy examples
359
+
360
+ - **scripts/**: Utility tools for running and visualizing workflows
361
+ - `workflow_demo.py`: CLI runner with persistence support
362
+ - `workflow_demo_ui.py`: Gradio UI with thread management
363
+ - `visualize_workflow.py`: Workflow graph generator
364
+
365
+ - **tests/**: Test suite
366
+ - **legacy/**: Previous implementations (FSM, direct LangGraph)
367
+
368
+ ## Requirements
369
+
370
+ ### Core Dependencies
371
+
372
+ - Python >= 3.12
373
+ - agno >= 2.0.7
374
+ - langgraph >= 0.6.8
375
+ - openai >= 1.108.1
376
+ - pyyaml >= 6.0
377
+
378
+ ### Optional Dependencies
379
+
380
+ For MongoDB persistence:
381
+ ```bash
382
+ # Using pip
383
+ pip install langgraph-checkpoint-mongodb pymongo
384
+
385
+ # Using uv (recommended)
386
+ uv add langgraph-checkpoint-mongodb pymongo --optional persistence
387
+
388
+ # Or install library with persistence support
389
+ pip install conversational-sop-framework[persistence]
390
+ ```
391
+
392
+ For development (includes Gradio UI and tests):
393
+ ```bash
394
+ pip install conversational-sop-framework[dev]
395
+ # or
396
+ uv sync --dev
397
+ ```
398
+
399
+ ## License
400
+
401
+ MIT
402
+
403
+ ## Contributing
404
+
405
+ Contributions are welcome! Please open an issue or submit a pull request.
406
+
407
+ ## To Do
408
+
409
+ - ✅ Database persistence (SqliteSaver, PostgresSaver supported)
410
+ - ✅ Pluggable checkpointer system
411
+ - ✅ Thread ID strategies and examples
412
+ - Additional action types (webhook, conditional branching, parallel execution)
413
+ - More workflow examples (customer onboarding, support ticketing, approval flows)
414
+ - Workflow testing utilities
415
+ - Metrics and monitoring hooks
416
+
417
+ ## Links
418
+
419
+ - [GitHub Repository](https://github.com/dnivra26/soprano_sdk_framework)
420
+ - [Issues](https://github.com/dnivra26/soprano_sdk_framework/issues)