soprano-sdk 0.2.10__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.
@@ -0,0 +1,420 @@
1
+ Metadata-Version: 2.4
2
+ Name: soprano-sdk
3
+ Version: 0.2.10
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)
@@ -0,0 +1,35 @@
1
+ soprano_sdk/__init__.py,sha256=YZVl_SwQ0C-E_5_f1AwUe_hPcbgCt8k7k4_WAHM8vjE,243
2
+ soprano_sdk/engine.py,sha256=EFK91iTHjp72otLN6Kg-yeLye2J3CAKN0QH4FI2taL8,14838
3
+ soprano_sdk/tools.py,sha256=xsJbY1hZzhXbNRTAVj9M_2saU0oa7J8O9DaRGGuPf30,8832
4
+ soprano_sdk/agents/__init__.py,sha256=Yzbtv6iP_ABRgZo0IUjy9vDofEvLFbOjuABw758176A,636
5
+ soprano_sdk/agents/adaptor.py,sha256=Cm02YKFclrESu-Qq4CTknCgU7KaA7Z_2FspnQDkEVfU,3214
6
+ soprano_sdk/agents/factory.py,sha256=Aucfz4rZVKCXMAQtbGAqp1JR8aYwa66mokRmKkKGhYA,6699
7
+ soprano_sdk/agents/structured_output.py,sha256=7DSVzfMPsZAqBwI3v6XL15qG5Gh4jJ-qddcVPaa3gdc,3326
8
+ soprano_sdk/authenticators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ soprano_sdk/authenticators/mfa.py,sha256=Vew9Nb8pIRTw9hKbEZTH3YScY-fZ_TLq4ZuCzc-wbr8,7387
10
+ soprano_sdk/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ soprano_sdk/core/constants.py,sha256=UPXlRbF7gsOUNOV0Lm0jvgFfgZX7JrsV6n9I5csMfns,3508
12
+ soprano_sdk/core/engine.py,sha256=vM2-nAvDc6Oam-q_BegabBT4uKVMV8DVV10SyJJPgVw,11762
13
+ soprano_sdk/core/rollback_strategies.py,sha256=NjDTtBCZlqyDql5PSwI9SMDLK7_BNlTxbW_cq_5gV0g,7783
14
+ soprano_sdk/core/state.py,sha256=k8ojLfWgjES3p9XWMeGU5s4UK-Xa5T8mS4VtZzTrcDw,2961
15
+ soprano_sdk/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ soprano_sdk/nodes/async_function.py,sha256=v6WujLKm8NXX2iAkJ7Gz_QIVCtWFrpC6nnPyyfuCxXs,9354
17
+ soprano_sdk/nodes/base.py,sha256=idFyOGGPnjsASYnrOF_NIh7eFcSuJqw61EoVN_WCTaU,2360
18
+ soprano_sdk/nodes/call_function.py,sha256=afYBmj5Aditbkvb_7gD3CsXBEEUohcsC1_cdHfcOunE,5847
19
+ soprano_sdk/nodes/collect_input.py,sha256=nBTLCq6nxNSO6lCV2FIbCaX6SBCZhn6-SvWm82Gl83Y,24345
20
+ soprano_sdk/nodes/factory.py,sha256=IbBzT4FKBnYw5PuSo7uDONV3HSFtoyqjBQQtXtUY2IY,1756
21
+ soprano_sdk/routing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ soprano_sdk/routing/router.py,sha256=Z218r4BMbmlL9282ombutAoKsIs1WHZ2d5YHnbCeet8,3698
23
+ soprano_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ soprano_sdk/utils/function.py,sha256=yqkY4MlHOenv-Q3NciiovK1lamyrGQljpy6Q41wviy8,1216
25
+ soprano_sdk/utils/logger.py,sha256=hMYaNHt5syGOXRkglTUKzkgfSbWerix_pHQntcYyep8,157
26
+ soprano_sdk/utils/template.py,sha256=MG_B9TMx1ShpnSGo7s7TO-VfQzuFByuRNhJTvZ668kM,685
27
+ soprano_sdk/utils/tool.py,sha256=hWN826HIKmLdswLCTURLH8hWlb2WU0MB8nIUErbpB-8,1877
28
+ soprano_sdk/utils/tracing.py,sha256=gSHeBDLe-MbAZ9rkzpCoGFveeMdR9KLaA6tteB0IWjk,1991
29
+ soprano_sdk/validation/__init__.py,sha256=ImChmO86jYHU90xzTttto2-LmOUOmvY_ibOQaLRz5BA,262
30
+ soprano_sdk/validation/schema.py,sha256=SlC4sq-ueEg0p_8Uox_cgPj9S-0AEEiOOlA1Vsu0DsE,15443
31
+ soprano_sdk/validation/validator.py,sha256=GaCvHvjwVe88Z8yatQsueiPnqtq1oo5uN75gogzpQT0,8940
32
+ soprano_sdk-0.2.10.dist-info/METADATA,sha256=Oowx80YoqwZb11UYh8KSt4BCKrQz1qY5kwxSWIkolJ4,11298
33
+ soprano_sdk-0.2.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
34
+ soprano_sdk-0.2.10.dist-info/licenses/LICENSE,sha256=A1aBauSjPNtVehOXJe3WuvdU2xvM9H8XmigFMm6665s,1073
35
+ soprano_sdk-0.2.10.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -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.