planar 0.5.0__py3-none-any.whl → 0.8.0__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.
Files changed (211) hide show
  1. planar/_version.py +1 -1
  2. planar/ai/agent.py +155 -283
  3. planar/ai/agent_base.py +170 -0
  4. planar/ai/agent_utils.py +7 -0
  5. planar/ai/pydantic_ai.py +638 -0
  6. planar/ai/test_agent_serialization.py +1 -1
  7. planar/app.py +64 -20
  8. planar/cli.py +39 -27
  9. planar/config.py +45 -36
  10. planar/db/db.py +2 -1
  11. planar/files/storage/azure_blob.py +343 -0
  12. planar/files/storage/base.py +7 -0
  13. planar/files/storage/config.py +70 -7
  14. planar/files/storage/s3.py +6 -6
  15. planar/files/storage/test_azure_blob.py +435 -0
  16. planar/logging/formatter.py +17 -4
  17. planar/logging/test_formatter.py +327 -0
  18. planar/registry_items.py +2 -1
  19. planar/routers/agents_router.py +3 -1
  20. planar/routers/files.py +11 -2
  21. planar/routers/models.py +14 -1
  22. planar/routers/test_agents_router.py +1 -1
  23. planar/routers/test_files_router.py +49 -0
  24. planar/routers/test_routes_security.py +5 -7
  25. planar/routers/test_workflow_router.py +270 -3
  26. planar/routers/workflow.py +95 -36
  27. planar/rules/models.py +36 -39
  28. planar/rules/test_data/account_dormancy_management.json +223 -0
  29. planar/rules/test_data/airline_loyalty_points_calculator.json +262 -0
  30. planar/rules/test_data/applicant_risk_assessment.json +435 -0
  31. planar/rules/test_data/booking_fraud_detection.json +407 -0
  32. planar/rules/test_data/cellular_data_rollover_system.json +258 -0
  33. planar/rules/test_data/clinical_trial_eligibility_screener.json +437 -0
  34. planar/rules/test_data/customer_lifetime_value.json +143 -0
  35. planar/rules/test_data/import_duties_calculator.json +289 -0
  36. planar/rules/test_data/insurance_prior_authorization.json +443 -0
  37. planar/rules/test_data/online_check_in_eligibility_system.json +254 -0
  38. planar/rules/test_data/order_consolidation_system.json +375 -0
  39. planar/rules/test_data/portfolio_risk_monitor.json +471 -0
  40. planar/rules/test_data/supply_chain_risk.json +253 -0
  41. planar/rules/test_data/warehouse_cross_docking.json +237 -0
  42. planar/rules/test_rules.py +750 -6
  43. planar/scaffold_templates/planar.dev.yaml.j2 +6 -6
  44. planar/scaffold_templates/planar.prod.yaml.j2 +9 -5
  45. planar/scaffold_templates/pyproject.toml.j2 +1 -1
  46. planar/security/auth_context.py +21 -0
  47. planar/security/{jwt_middleware.py → auth_middleware.py} +70 -17
  48. planar/security/authorization.py +9 -15
  49. planar/security/tests/test_auth_middleware.py +162 -0
  50. planar/sse/proxy.py +4 -9
  51. planar/test_app.py +92 -1
  52. planar/test_cli.py +81 -59
  53. planar/test_config.py +17 -14
  54. planar/testing/fixtures.py +325 -0
  55. planar/testing/planar_test_client.py +5 -2
  56. planar/utils.py +41 -1
  57. planar/workflows/execution.py +1 -1
  58. planar/workflows/orchestrator.py +5 -0
  59. planar/workflows/serialization.py +12 -6
  60. planar/workflows/step_core.py +3 -1
  61. planar/workflows/test_serialization.py +9 -1
  62. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/METADATA +30 -5
  63. planar-0.8.0.dist-info/RECORD +166 -0
  64. planar/.__init__.py.un~ +0 -0
  65. planar/._version.py.un~ +0 -0
  66. planar/.app.py.un~ +0 -0
  67. planar/.cli.py.un~ +0 -0
  68. planar/.config.py.un~ +0 -0
  69. planar/.context.py.un~ +0 -0
  70. planar/.db.py.un~ +0 -0
  71. planar/.di.py.un~ +0 -0
  72. planar/.engine.py.un~ +0 -0
  73. planar/.files.py.un~ +0 -0
  74. planar/.log_context.py.un~ +0 -0
  75. planar/.log_metadata.py.un~ +0 -0
  76. planar/.logging.py.un~ +0 -0
  77. planar/.object_registry.py.un~ +0 -0
  78. planar/.otel.py.un~ +0 -0
  79. planar/.server.py.un~ +0 -0
  80. planar/.session.py.un~ +0 -0
  81. planar/.sqlalchemy.py.un~ +0 -0
  82. planar/.task_local.py.un~ +0 -0
  83. planar/.test_app.py.un~ +0 -0
  84. planar/.test_config.py.un~ +0 -0
  85. planar/.test_object_config.py.un~ +0 -0
  86. planar/.test_sqlalchemy.py.un~ +0 -0
  87. planar/.test_utils.py.un~ +0 -0
  88. planar/.util.py.un~ +0 -0
  89. planar/.utils.py.un~ +0 -0
  90. planar/ai/.__init__.py.un~ +0 -0
  91. planar/ai/._models.py.un~ +0 -0
  92. planar/ai/.agent.py.un~ +0 -0
  93. planar/ai/.agent_utils.py.un~ +0 -0
  94. planar/ai/.events.py.un~ +0 -0
  95. planar/ai/.files.py.un~ +0 -0
  96. planar/ai/.models.py.un~ +0 -0
  97. planar/ai/.providers.py.un~ +0 -0
  98. planar/ai/.pydantic_ai.py.un~ +0 -0
  99. planar/ai/.pydantic_ai_agent.py.un~ +0 -0
  100. planar/ai/.pydantic_ai_provider.py.un~ +0 -0
  101. planar/ai/.step.py.un~ +0 -0
  102. planar/ai/.test_agent.py.un~ +0 -0
  103. planar/ai/.test_agent_serialization.py.un~ +0 -0
  104. planar/ai/.test_providers.py.un~ +0 -0
  105. planar/ai/.utils.py.un~ +0 -0
  106. planar/ai/providers.py +0 -1088
  107. planar/ai/test_agent.py +0 -1298
  108. planar/ai/test_providers.py +0 -463
  109. planar/db/.db.py.un~ +0 -0
  110. planar/files/.config.py.un~ +0 -0
  111. planar/files/.local.py.un~ +0 -0
  112. planar/files/.local_filesystem.py.un~ +0 -0
  113. planar/files/.model.py.un~ +0 -0
  114. planar/files/.models.py.un~ +0 -0
  115. planar/files/.s3.py.un~ +0 -0
  116. planar/files/.storage.py.un~ +0 -0
  117. planar/files/.test_files.py.un~ +0 -0
  118. planar/files/storage/.__init__.py.un~ +0 -0
  119. planar/files/storage/.base.py.un~ +0 -0
  120. planar/files/storage/.config.py.un~ +0 -0
  121. planar/files/storage/.context.py.un~ +0 -0
  122. planar/files/storage/.local_directory.py.un~ +0 -0
  123. planar/files/storage/.test_local_directory.py.un~ +0 -0
  124. planar/files/storage/.test_s3.py.un~ +0 -0
  125. planar/human/.human.py.un~ +0 -0
  126. planar/human/.test_human.py.un~ +0 -0
  127. planar/logging/.__init__.py.un~ +0 -0
  128. planar/logging/.attributes.py.un~ +0 -0
  129. planar/logging/.formatter.py.un~ +0 -0
  130. planar/logging/.logger.py.un~ +0 -0
  131. planar/logging/.otel.py.un~ +0 -0
  132. planar/logging/.tracer.py.un~ +0 -0
  133. planar/modeling/.mixin.py.un~ +0 -0
  134. planar/modeling/.storage.py.un~ +0 -0
  135. planar/modeling/orm/.planar_base_model.py.un~ +0 -0
  136. planar/object_config/.object_config.py.un~ +0 -0
  137. planar/routers/.__init__.py.un~ +0 -0
  138. planar/routers/.agents_router.py.un~ +0 -0
  139. planar/routers/.crud.py.un~ +0 -0
  140. planar/routers/.decision.py.un~ +0 -0
  141. planar/routers/.event.py.un~ +0 -0
  142. planar/routers/.file_attachment.py.un~ +0 -0
  143. planar/routers/.files.py.un~ +0 -0
  144. planar/routers/.files_router.py.un~ +0 -0
  145. planar/routers/.human.py.un~ +0 -0
  146. planar/routers/.info.py.un~ +0 -0
  147. planar/routers/.models.py.un~ +0 -0
  148. planar/routers/.object_config_router.py.un~ +0 -0
  149. planar/routers/.rule.py.un~ +0 -0
  150. planar/routers/.test_object_config_router.py.un~ +0 -0
  151. planar/routers/.test_workflow_router.py.un~ +0 -0
  152. planar/routers/.workflow.py.un~ +0 -0
  153. planar/rules/.decorator.py.un~ +0 -0
  154. planar/rules/.runner.py.un~ +0 -0
  155. planar/rules/.test_rules.py.un~ +0 -0
  156. planar/security/.jwt_middleware.py.un~ +0 -0
  157. planar/sse/.constants.py.un~ +0 -0
  158. planar/sse/.example.html.un~ +0 -0
  159. planar/sse/.hub.py.un~ +0 -0
  160. planar/sse/.model.py.un~ +0 -0
  161. planar/sse/.proxy.py.un~ +0 -0
  162. planar/testing/.client.py.un~ +0 -0
  163. planar/testing/.memory_storage.py.un~ +0 -0
  164. planar/testing/.planar_test_client.py.un~ +0 -0
  165. planar/testing/.predictable_tracer.py.un~ +0 -0
  166. planar/testing/.synchronizable_tracer.py.un~ +0 -0
  167. planar/testing/.test_memory_storage.py.un~ +0 -0
  168. planar/testing/.workflow_observer.py.un~ +0 -0
  169. planar/workflows/.__init__.py.un~ +0 -0
  170. planar/workflows/.builtin_steps.py.un~ +0 -0
  171. planar/workflows/.concurrency_tracing.py.un~ +0 -0
  172. planar/workflows/.context.py.un~ +0 -0
  173. planar/workflows/.contrib.py.un~ +0 -0
  174. planar/workflows/.decorators.py.un~ +0 -0
  175. planar/workflows/.durable_test.py.un~ +0 -0
  176. planar/workflows/.errors.py.un~ +0 -0
  177. planar/workflows/.events.py.un~ +0 -0
  178. planar/workflows/.exceptions.py.un~ +0 -0
  179. planar/workflows/.execution.py.un~ +0 -0
  180. planar/workflows/.human.py.un~ +0 -0
  181. planar/workflows/.lock.py.un~ +0 -0
  182. planar/workflows/.misc.py.un~ +0 -0
  183. planar/workflows/.model.py.un~ +0 -0
  184. planar/workflows/.models.py.un~ +0 -0
  185. planar/workflows/.notifications.py.un~ +0 -0
  186. planar/workflows/.orchestrator.py.un~ +0 -0
  187. planar/workflows/.runtime.py.un~ +0 -0
  188. planar/workflows/.serialization.py.un~ +0 -0
  189. planar/workflows/.step.py.un~ +0 -0
  190. planar/workflows/.step_core.py.un~ +0 -0
  191. planar/workflows/.sub_workflow_runner.py.un~ +0 -0
  192. planar/workflows/.sub_workflow_scheduler.py.un~ +0 -0
  193. planar/workflows/.test_concurrency.py.un~ +0 -0
  194. planar/workflows/.test_concurrency_detection.py.un~ +0 -0
  195. planar/workflows/.test_human.py.un~ +0 -0
  196. planar/workflows/.test_lock_timeout.py.un~ +0 -0
  197. planar/workflows/.test_orchestrator.py.un~ +0 -0
  198. planar/workflows/.test_race_conditions.py.un~ +0 -0
  199. planar/workflows/.test_serialization.py.un~ +0 -0
  200. planar/workflows/.test_suspend_deserialization.py.un~ +0 -0
  201. planar/workflows/.test_workflow.py.un~ +0 -0
  202. planar/workflows/.tracing.py.un~ +0 -0
  203. planar/workflows/.types.py.un~ +0 -0
  204. planar/workflows/.util.py.un~ +0 -0
  205. planar/workflows/.utils.py.un~ +0 -0
  206. planar/workflows/.workflow.py.un~ +0 -0
  207. planar/workflows/.workflow_wrapper.py.un~ +0 -0
  208. planar/workflows/.wrappers.py.un~ +0 -0
  209. planar-0.5.0.dist-info/RECORD +0 -289
  210. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/WHEEL +0 -0
  211. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,435 @@
1
+ {
2
+ "nodes": [
3
+ {
4
+ "type": "inputNode",
5
+ "content": {
6
+ "schema": ""
7
+ },
8
+ "id": "input",
9
+ "name": "request",
10
+ "position": {
11
+ "x": 110,
12
+ "y": 163.5
13
+ }
14
+ },
15
+ {
16
+ "type": "decisionTableNode",
17
+ "content": {
18
+ "hitPolicy": "first",
19
+ "rules": [
20
+ {
21
+ "_id": "r1-1",
22
+ "i1-1": "> 750",
23
+ "i1-2": "< 2",
24
+ "i1-3": "> 60",
25
+ "o1-1": "30"
26
+ },
27
+ {
28
+ "_id": "r1-2",
29
+ "i1-1": "[650..750]",
30
+ "i1-2": "< 4",
31
+ "i1-3": "> 36",
32
+ "o1-1": "20"
33
+ },
34
+ {
35
+ "_id": "r1-3",
36
+ "i1-1": "[600..650)",
37
+ "i1-2": "< 6",
38
+ "i1-3": "> 24",
39
+ "o1-1": "10"
40
+ },
41
+ {
42
+ "_id": "r1-4",
43
+ "i1-1": "",
44
+ "i1-2": "",
45
+ "i1-3": "",
46
+ "o1-1": "0"
47
+ }
48
+ ],
49
+ "inputs": [
50
+ {
51
+ "id": "i1-1",
52
+ "name": "creditScore",
53
+ "field": "applicant.creditScore"
54
+ },
55
+ {
56
+ "id": "i1-2",
57
+ "name": "latePayments",
58
+ "field": "applicant.latePayments"
59
+ },
60
+ {
61
+ "id": "i1-3",
62
+ "name": "creditHistoryLength",
63
+ "field": "applicant.creditHistoryMonths"
64
+ }
65
+ ],
66
+ "outputs": [
67
+ {
68
+ "id": "o1-1",
69
+ "name": "creditHistoryScore",
70
+ "field": "scores.creditHistory"
71
+ }
72
+ ],
73
+ "passThrough": true,
74
+ "inputField": null,
75
+ "outputPath": null,
76
+ "executionMode": "single",
77
+ "passThorough": false
78
+ },
79
+ "id": "scoreCreditHistory",
80
+ "name": "scoreCreditHistory",
81
+ "position": {
82
+ "x": 430,
83
+ "y": 163.5
84
+ }
85
+ },
86
+ {
87
+ "type": "decisionTableNode",
88
+ "content": {
89
+ "hitPolicy": "first",
90
+ "rules": [
91
+ {
92
+ "_id": "r2-1",
93
+ "i2-1": "> 60",
94
+ "i2-2": "'complete'",
95
+ "i2-3": "'good'",
96
+ "o2-1": "25"
97
+ },
98
+ {
99
+ "_id": "r2-2",
100
+ "i2-1": "> 24",
101
+ "i2-2": "'complete'",
102
+ "i2-3": "'good'",
103
+ "o2-1": "20"
104
+ },
105
+ {
106
+ "_id": "r2-3",
107
+ "i2-1": "> 12",
108
+ "i2-2": "'partial'",
109
+ "i2-3": "'fair'",
110
+ "o2-1": "15"
111
+ },
112
+ {
113
+ "_id": "r2-4",
114
+ "i2-1": "> 6",
115
+ "i2-2": "",
116
+ "i2-3": "",
117
+ "o2-1": "5"
118
+ },
119
+ {
120
+ "_id": "r2-5",
121
+ "i2-1": "",
122
+ "i2-2": "",
123
+ "i2-3": "",
124
+ "o2-1": "0"
125
+ }
126
+ ],
127
+ "inputs": [
128
+ {
129
+ "id": "i2-1",
130
+ "name": "employmentLength",
131
+ "field": "applicant.employmentMonths"
132
+ },
133
+ {
134
+ "id": "i2-2",
135
+ "name": "incomeVerification",
136
+ "field": "applicant.incomeVerification"
137
+ },
138
+ {
139
+ "id": "i2-3",
140
+ "name": "bankAccountStanding",
141
+ "field": "applicant.bankAccountStanding"
142
+ }
143
+ ],
144
+ "outputs": [
145
+ {
146
+ "id": "o2-1",
147
+ "name": "incomeStabilityScore",
148
+ "field": "scores.incomeStability"
149
+ }
150
+ ],
151
+ "passThrough": true,
152
+ "inputField": null,
153
+ "outputPath": null,
154
+ "executionMode": "single"
155
+ },
156
+ "id": "scoreIncomeStability",
157
+ "name": "scoreIncomeStability",
158
+ "position": {
159
+ "x": 750,
160
+ "y": 163.5
161
+ }
162
+ },
163
+ {
164
+ "type": "decisionTableNode",
165
+ "content": {
166
+ "hitPolicy": "first",
167
+ "rules": [
168
+ {
169
+ "_id": "r3-1",
170
+ "i3-1": "< 0.2",
171
+ "i3-2": "< 2",
172
+ "o3-1": "25"
173
+ },
174
+ {
175
+ "_id": "r3-2",
176
+ "i3-1": "< 0.4",
177
+ "i3-2": "< 3",
178
+ "o3-1": "15"
179
+ },
180
+ {
181
+ "_id": "r3-3",
182
+ "i3-1": "< 0.6",
183
+ "i3-2": "< 5",
184
+ "o3-1": "5"
185
+ },
186
+ {
187
+ "_id": "r3-4",
188
+ "i3-1": "",
189
+ "i3-2": "",
190
+ "o3-1": "0"
191
+ }
192
+ ],
193
+ "inputs": [
194
+ {
195
+ "id": "i3-1",
196
+ "name": "debtToIncomeRatio",
197
+ "field": "applicant.debtToIncomeRatio"
198
+ },
199
+ {
200
+ "id": "i3-2",
201
+ "name": "outstandingLoans",
202
+ "field": "applicant.outstandingLoans"
203
+ }
204
+ ],
205
+ "outputs": [
206
+ {
207
+ "id": "o3-1",
208
+ "name": "debtToIncomeScore",
209
+ "field": "scores.debtToIncome"
210
+ }
211
+ ],
212
+ "passThrough": true,
213
+ "inputField": null,
214
+ "outputPath": null,
215
+ "executionMode": "single"
216
+ },
217
+ "id": "scoreDebtToIncome",
218
+ "name": "scoreDebtToIncome",
219
+ "position": {
220
+ "x": 1070,
221
+ "y": 163.5
222
+ }
223
+ },
224
+ {
225
+ "type": "expressionNode",
226
+ "content": {
227
+ "expressions": [
228
+ {
229
+ "id": "e4-1",
230
+ "key": "totalRiskScore",
231
+ "value": "scores.creditHistory + scores.incomeStability + scores.debtToIncome"
232
+ },
233
+ {
234
+ "id": "e4-2",
235
+ "key": "negativeFactors",
236
+ "value": "filter([scores.creditHistory == 0, scores.incomeStability == 0, scores.debtToIncome == 0], # == true)"
237
+ },
238
+ {
239
+ "id": "e4-3",
240
+ "key": "negativeFactorsCount",
241
+ "value": "len($.negativeFactors)"
242
+ }
243
+ ],
244
+ "passThrough": true,
245
+ "inputField": null,
246
+ "outputPath": null,
247
+ "executionMode": "single"
248
+ },
249
+ "id": "calculateRiskScore",
250
+ "name": "calculateRiskScore",
251
+ "position": {
252
+ "x": 1390,
253
+ "y": 163.5
254
+ }
255
+ },
256
+ {
257
+ "type": "switchNode",
258
+ "content": {
259
+ "hitPolicy": "first",
260
+ "statements": [
261
+ {
262
+ "id": "s1",
263
+ "condition": "totalRiskScore >= 60 and negativeFactorsCount == 0",
264
+ "isDefault": false
265
+ },
266
+ {
267
+ "id": "s2",
268
+ "condition": "totalRiskScore >= 30 or (totalRiskScore >= 20 and negativeFactorsCount < 2)",
269
+ "isDefault": false
270
+ },
271
+ {
272
+ "id": "s3",
273
+ "condition": "",
274
+ "isDefault": true
275
+ }
276
+ ]
277
+ },
278
+ "id": "classifyRisk",
279
+ "name": "classifyRisk",
280
+ "position": {
281
+ "x": 1710,
282
+ "y": 163.5
283
+ }
284
+ },
285
+ {
286
+ "type": "expressionNode",
287
+ "content": {
288
+ "expressions": [
289
+ {
290
+ "id": "e6-1",
291
+ "key": "riskCategory",
292
+ "value": "'low'"
293
+ },
294
+ {
295
+ "id": "e6-2",
296
+ "key": "approvalStatus",
297
+ "value": "'auto-approved'"
298
+ },
299
+ {
300
+ "id": "e6-3",
301
+ "key": "interestRateModifier",
302
+ "value": "-0.5"
303
+ }
304
+ ],
305
+ "passThrough": true,
306
+ "inputField": null,
307
+ "outputPath": null,
308
+ "executionMode": "single"
309
+ },
310
+ "id": "lowRiskAction",
311
+ "name": "lowRiskAction",
312
+ "position": {
313
+ "x": 2030,
314
+ "y": 65.5
315
+ }
316
+ },
317
+ {
318
+ "type": "expressionNode",
319
+ "content": {
320
+ "expressions": [
321
+ {
322
+ "id": "e7-1",
323
+ "key": "riskCategory",
324
+ "value": "'medium'"
325
+ },
326
+ {
327
+ "id": "e7-2",
328
+ "key": "approvalStatus",
329
+ "value": "'manual-review'"
330
+ },
331
+ {
332
+ "id": "e7-3",
333
+ "key": "interestRateModifier",
334
+ "value": "0"
335
+ }
336
+ ],
337
+ "passThrough": true,
338
+ "inputField": null,
339
+ "outputPath": null,
340
+ "executionMode": "single"
341
+ },
342
+ "id": "mediumRiskAction",
343
+ "name": "mediumRiskAction",
344
+ "position": {
345
+ "x": 2030,
346
+ "y": 163.5
347
+ }
348
+ },
349
+ {
350
+ "type": "expressionNode",
351
+ "content": {
352
+ "expressions": [
353
+ {
354
+ "id": "e8-1",
355
+ "key": "riskCategory",
356
+ "value": "'high'"
357
+ },
358
+ {
359
+ "id": "e8-2",
360
+ "key": "approvalStatus",
361
+ "value": "'additional-verification'"
362
+ },
363
+ {
364
+ "id": "e8-3",
365
+ "key": "interestRateModifier",
366
+ "value": "1.5"
367
+ }
368
+ ],
369
+ "passThrough": true,
370
+ "inputField": null,
371
+ "outputPath": null,
372
+ "executionMode": "single"
373
+ },
374
+ "id": "highRiskAction",
375
+ "name": "highRiskAction",
376
+ "position": {
377
+ "x": 2030,
378
+ "y": 261.5
379
+ }
380
+ }
381
+ ],
382
+ "edges": [
383
+ {
384
+ "id": "e1",
385
+ "sourceId": "input",
386
+ "targetId": "scoreCreditHistory",
387
+ "type": "edge"
388
+ },
389
+ {
390
+ "id": "e2",
391
+ "sourceId": "scoreCreditHistory",
392
+ "targetId": "scoreIncomeStability",
393
+ "type": "edge"
394
+ },
395
+ {
396
+ "id": "e3",
397
+ "sourceId": "scoreIncomeStability",
398
+ "targetId": "scoreDebtToIncome",
399
+ "type": "edge"
400
+ },
401
+ {
402
+ "id": "e4",
403
+ "sourceId": "scoreDebtToIncome",
404
+ "targetId": "calculateRiskScore",
405
+ "type": "edge"
406
+ },
407
+ {
408
+ "id": "e5",
409
+ "sourceId": "calculateRiskScore",
410
+ "targetId": "classifyRisk",
411
+ "type": "edge"
412
+ },
413
+ {
414
+ "id": "e6",
415
+ "sourceId": "classifyRisk",
416
+ "targetId": "lowRiskAction",
417
+ "sourceHandle": "s1",
418
+ "type": "edge"
419
+ },
420
+ {
421
+ "id": "e7",
422
+ "sourceId": "classifyRisk",
423
+ "targetId": "mediumRiskAction",
424
+ "sourceHandle": "s2",
425
+ "type": "edge"
426
+ },
427
+ {
428
+ "id": "e8",
429
+ "sourceId": "classifyRisk",
430
+ "targetId": "highRiskAction",
431
+ "sourceHandle": "s3",
432
+ "type": "edge"
433
+ }
434
+ ]
435
+ }