soprano-sdk 0.2.6__py3-none-any.whl → 0.2.7__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.
@@ -154,25 +154,47 @@ class MFANodeConfig:
154
154
  model=model_name,
155
155
  initial_message="{{_mfa.message}}",
156
156
  instructions="""
157
- You are an authentication value extractor. Your job is to identify and extract MFA codes from user input.
157
+ You are an authentication value extractor. Your job is to identify and extract MFA codes from user input, or detect if the user wants to cancel the authentication flow.
158
158
 
159
159
  **Task:**
160
- - Read the user's message
161
- - Extract ONLY the OTP code value
162
- - Output in the exact format shown below
163
-
164
- Examples:
165
- * User says: "1234" → `MFA_CAPTURED:1223`
166
- * User says: "2345e" `MFA_CAPTURED:1223e
160
+ - Read the user's message carefully
161
+ - First, check if the user wants to cancel, stop, or exit the authentication process
162
+ - If they want to cancel, output: MFA_CANCELLED:
163
+ - Otherwise, extract ONLY the OTP/MFA code value and output in the format shown below
164
+
165
+ **Cancellation Detection:**
166
+ If the user expresses any intent to cancel, stop, exit, abort, or quit the authentication process, respond with: MFA_CANCELLED
167
+
168
+ Examples of cancellation phrases:
169
+ * "cancel" → MFA_CANCELLED:
170
+ * "I want to stop" → MFA_CANCELLED:
171
+ * "exit" → MFA_CANCELLED:
172
+ * "nevermind" → MFA_CANCELLED:
173
+ * "I don't want to continue" → MFA_CANCELLED:
174
+ * "stop this" → MFA_CANCELLED:
175
+ * "forget it" → MFA_CANCELLED:
176
+ * "abort" → MFA_CANCELLED:
177
+ * "quit" → MFA_CANCELLED:
178
+
179
+ **OTP Capture Examples:**
180
+ * "1234" → MFA_CAPTURED:1234
181
+ * "2345e" → MFA_CAPTURED:2345e
182
+ * "the code is 567890" → MFA_CAPTURED:567890
183
+ * "my otp is 123456" → MFA_CAPTURED:123456
167
184
 
168
185
  **Output Format:**
169
- MFA_CAPTURED:<input_field_name>
186
+ - For OTP/MFA codes: MFA_CAPTURED:<otp_value>
187
+ - For cancellation: MFA_CANCELLED:
170
188
 
171
189
  """),
172
190
  transitions=[
173
191
  dict(
174
192
  pattern="MFA_CAPTURED:",
175
193
  next=next_node
194
+ ),
195
+ dict(
196
+ pattern="MFA_CANCELLED:",
197
+ next="mfa_cancelled"
176
198
  )
177
199
  ]
178
200
  )
@@ -114,6 +114,10 @@ class MFAConfig(BaseSettings):
114
114
  default=30,
115
115
  description="API request timeout in seconds"
116
116
  )
117
+ mfa_cancelled_message: str = Field(
118
+ default="Authentication has been cancelled.",
119
+ description="Message to display when user cancels MFA authentication"
120
+ )
117
121
 
118
122
  model_config = SettingsConfigDict(
119
123
  case_sensitive=False,
@@ -39,8 +39,7 @@ class WorkflowEngine:
39
39
  self.step_map = {step['id']: step for step in self.steps}
40
40
  self.mfa_config = (mfa_config or MFAConfig()) if self.mfa_validator_steps else None
41
41
  self.data_fields = self.load_data()
42
-
43
- self.outcomes = self.config['outcomes']
42
+ self.outcomes = self.load_outcomes()
44
43
  self.metadata = self.config.get('metadata', {})
45
44
 
46
45
  self.StateType = create_state_model(self.data_fields)
@@ -260,6 +259,20 @@ class WorkflowEngine:
260
259
  )
261
260
  return data
262
261
 
262
+ def load_outcomes(self):
263
+ outcomes: list = self.config['outcomes']
264
+
265
+ if self.mfa_config:
266
+ mfa_cancelled_outcome = {
267
+ 'id': 'mfa_cancelled',
268
+ 'type': 'failure',
269
+ 'message': self.mfa_config.mfa_cancelled_message
270
+ }
271
+ outcomes.append(mfa_cancelled_outcome)
272
+ logger.info(f"Auto-generated 'mfa_cancelled' outcome with message: {self.mfa_config.mfa_cancelled_message}")
273
+
274
+ return outcomes
275
+
263
276
 
264
277
  def load_workflow(yaml_path: str, checkpointer=None, config=None, mfa_config: Optional[MFAConfig] = None) -> Tuple[CompiledStateGraph, WorkflowEngine]:
265
278
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soprano-sdk
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: YAML-driven workflow engine with AI agent integration for building conversational SOPs
5
5
  Author: Arvind Thangamani
6
6
  License: MIT
@@ -6,10 +6,10 @@ soprano_sdk/agents/adaptor.py,sha256=Cm02YKFclrESu-Qq4CTknCgU7KaA7Z_2FspnQDkEVfU
6
6
  soprano_sdk/agents/factory.py,sha256=Aucfz4rZVKCXMAQtbGAqp1JR8aYwa66mokRmKkKGhYA,6699
7
7
  soprano_sdk/agents/structured_output.py,sha256=7DSVzfMPsZAqBwI3v6XL15qG5Gh4jJ-qddcVPaa3gdc,3326
8
8
  soprano_sdk/authenticators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- soprano_sdk/authenticators/mfa.py,sha256=Zl1dcwCmuwsAbruFMqguJ4lY0PPnC6v2EZ-xTPULX04,6098
9
+ soprano_sdk/authenticators/mfa.py,sha256=Vew9Nb8pIRTw9hKbEZTH3YScY-fZ_TLq4ZuCzc-wbr8,7387
10
10
  soprano_sdk/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- soprano_sdk/core/constants.py,sha256=21ful8skHgDeDJJMdB_oJDw7Xq3lkbO6KWOhHuuLIa0,3330
12
- soprano_sdk/core/engine.py,sha256=UTFJimrgUzfdDZgc4rW5nvkOKevAEGW8C5Zr1D0tgcs,11270
11
+ soprano_sdk/core/constants.py,sha256=UPXlRbF7gsOUNOV0Lm0jvgFfgZX7JrsV6n9I5csMfns,3508
12
+ soprano_sdk/core/engine.py,sha256=vM2-nAvDc6Oam-q_BegabBT4uKVMV8DVV10SyJJPgVw,11762
13
13
  soprano_sdk/core/rollback_strategies.py,sha256=NjDTtBCZlqyDql5PSwI9SMDLK7_BNlTxbW_cq_5gV0g,7783
14
14
  soprano_sdk/core/state.py,sha256=k8ojLfWgjES3p9XWMeGU5s4UK-Xa5T8mS4VtZzTrcDw,2961
15
15
  soprano_sdk/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -29,7 +29,7 @@ soprano_sdk/utils/tracing.py,sha256=gSHeBDLe-MbAZ9rkzpCoGFveeMdR9KLaA6tteB0IWjk,
29
29
  soprano_sdk/validation/__init__.py,sha256=ImChmO86jYHU90xzTttto2-LmOUOmvY_ibOQaLRz5BA,262
30
30
  soprano_sdk/validation/schema.py,sha256=SlC4sq-ueEg0p_8Uox_cgPj9S-0AEEiOOlA1Vsu0DsE,15443
31
31
  soprano_sdk/validation/validator.py,sha256=GaCvHvjwVe88Z8yatQsueiPnqtq1oo5uN75gogzpQT0,8940
32
- soprano_sdk-0.2.6.dist-info/METADATA,sha256=Ykmgc9OD9Q5nBvGSD-z67oPU7Cy4jynpvhjZkwdPxzQ,11297
33
- soprano_sdk-0.2.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
34
- soprano_sdk-0.2.6.dist-info/licenses/LICENSE,sha256=A1aBauSjPNtVehOXJe3WuvdU2xvM9H8XmigFMm6665s,1073
35
- soprano_sdk-0.2.6.dist-info/RECORD,,
32
+ soprano_sdk-0.2.7.dist-info/METADATA,sha256=L9wKEDqgskIRsFIIhtYJq8gfUZ2TJuwXUqrtb-4qNEI,11297
33
+ soprano_sdk-0.2.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
34
+ soprano_sdk-0.2.7.dist-info/licenses/LICENSE,sha256=A1aBauSjPNtVehOXJe3WuvdU2xvM9H8XmigFMm6665s,1073
35
+ soprano_sdk-0.2.7.dist-info/RECORD,,