planar 0.10.0__py3-none-any.whl → 0.12.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.
- planar/app.py +26 -6
- planar/cli.py +26 -0
- planar/data/__init__.py +1 -0
- planar/data/config.py +12 -1
- planar/data/connection.py +89 -4
- planar/data/dataset.py +13 -7
- planar/data/utils.py +145 -25
- planar/db/alembic/env.py +68 -57
- planar/db/alembic.ini +1 -1
- planar/files/storage/config.py +7 -1
- planar/routers/dataset_router.py +5 -1
- planar/routers/info.py +79 -36
- planar/scaffold_templates/pyproject.toml.j2 +1 -1
- planar/testing/fixtures.py +7 -4
- planar/testing/planar_test_client.py +8 -0
- planar/version.py +27 -0
- planar-0.12.0.dist-info/METADATA +202 -0
- {planar-0.10.0.dist-info → planar-0.12.0.dist-info}/RECORD +20 -71
- planar/ai/test_agent_serialization.py +0 -229
- planar/ai/test_agent_tool_step_display.py +0 -78
- planar/data/test_dataset.py +0 -358
- planar/files/storage/test_azure_blob.py +0 -435
- planar/files/storage/test_local_directory.py +0 -162
- planar/files/storage/test_s3.py +0 -299
- planar/files/test_files.py +0 -282
- planar/human/test_human.py +0 -385
- planar/logging/test_formatter.py +0 -327
- planar/modeling/mixins/test_auditable.py +0 -97
- planar/modeling/mixins/test_timestamp.py +0 -134
- planar/modeling/mixins/test_uuid_primary_key.py +0 -52
- planar/routers/test_agents_router.py +0 -174
- planar/routers/test_dataset_router.py +0 -429
- planar/routers/test_files_router.py +0 -49
- planar/routers/test_object_config_router.py +0 -367
- planar/routers/test_routes_security.py +0 -168
- planar/routers/test_rule_router.py +0 -470
- planar/routers/test_workflow_router.py +0 -564
- planar/rules/test_data/account_dormancy_management.json +0 -223
- planar/rules/test_data/airline_loyalty_points_calculator.json +0 -262
- planar/rules/test_data/applicant_risk_assessment.json +0 -435
- planar/rules/test_data/booking_fraud_detection.json +0 -407
- planar/rules/test_data/cellular_data_rollover_system.json +0 -258
- planar/rules/test_data/clinical_trial_eligibility_screener.json +0 -437
- planar/rules/test_data/customer_lifetime_value.json +0 -143
- planar/rules/test_data/import_duties_calculator.json +0 -289
- planar/rules/test_data/insurance_prior_authorization.json +0 -443
- planar/rules/test_data/online_check_in_eligibility_system.json +0 -254
- planar/rules/test_data/order_consolidation_system.json +0 -375
- planar/rules/test_data/portfolio_risk_monitor.json +0 -471
- planar/rules/test_data/supply_chain_risk.json +0 -253
- planar/rules/test_data/warehouse_cross_docking.json +0 -237
- planar/rules/test_rules.py +0 -1494
- planar/security/tests/test_auth_middleware.py +0 -162
- planar/security/tests/test_authorization_context.py +0 -78
- planar/security/tests/test_cedar_basics.py +0 -41
- planar/security/tests/test_cedar_policies.py +0 -158
- planar/security/tests/test_jwt_principal_context.py +0 -179
- planar/test_app.py +0 -142
- planar/test_cli.py +0 -394
- planar/test_config.py +0 -515
- planar/test_object_config.py +0 -527
- planar/test_object_registry.py +0 -14
- planar/test_sqlalchemy.py +0 -193
- planar/test_utils.py +0 -105
- planar/testing/test_memory_storage.py +0 -143
- planar/workflows/test_concurrency_detection.py +0 -120
- planar/workflows/test_lock_timeout.py +0 -140
- planar/workflows/test_serialization.py +0 -1203
- planar/workflows/test_suspend_deserialization.py +0 -231
- planar/workflows/test_workflow.py +0 -2005
- planar-0.10.0.dist-info/METADATA +0 -323
- {planar-0.10.0.dist-info → planar-0.12.0.dist-info}/WHEEL +0 -0
- {planar-0.10.0.dist-info → planar-0.12.0.dist-info}/entry_points.txt +0 -0
@@ -6,58 +6,46 @@ planar/ai/agent_utils.py,sha256=MYNerdAm2TPVbDSKAmBCUlGmR56NAc8seZmDAFOWvUA,4199
|
|
6
6
|
planar/ai/models.py,sha256=bZd4MoBBJMqzXJqsmsbMdZtOaRrNeX438CHAqOvmpfw,4598
|
7
7
|
planar/ai/pydantic_ai.py,sha256=FpD0pE7wWNYwmEUZ90D7_J8gbAoqKmWtrLr2fhAd7rg,23503
|
8
8
|
planar/ai/state.py,sha256=6vQ8VMLxJYB75QXkm8AVPkdXHUMwwjKxBWH-hGIK9p0,278
|
9
|
-
planar/ai/test_agent_serialization.py,sha256=zYLIxhYdFhOZzBrEBoQNyYLyNcNxWwaMTkjt_ARTkZk,8073
|
10
|
-
planar/ai/test_agent_tool_step_display.py,sha256=7OeKLnimItAkAFcArufDfiL3rXnQ1GwEtrE58_557hM,2588
|
11
9
|
planar/ai/utils.py,sha256=WVBW0TGaoKytC4bNd_a9lXrBf5QsDRut4GBcA53U2Ww,3116
|
12
|
-
planar/app.py,sha256=
|
13
|
-
planar/cli.py,sha256=
|
10
|
+
planar/app.py,sha256=2ijbrORCfjKReDieLbwgey_9poJJwEfWkvCNKcVYcdk,19484
|
11
|
+
planar/cli.py,sha256=9LINDDiAUBDmzWQY9BuCYTssM7eb-ypa5bL9HAY3Ld8,10500
|
14
12
|
planar/config.py,sha256=6J42G9rEVUiOyCAY3EwUTU3PPmWthGTnrHMzST9TMcc,17809
|
15
|
-
planar/data/__init__.py,sha256=
|
16
|
-
planar/data/config.py,sha256=
|
17
|
-
planar/data/connection.py,sha256=
|
18
|
-
planar/data/dataset.py,sha256=
|
13
|
+
planar/data/__init__.py,sha256=eqSREzJ58HM05DXpR_00M6RDFxtHSIh-OEuqXBPVsVc,362
|
14
|
+
planar/data/config.py,sha256=oaLiwN3OUt3i85MS0zxpdMNG5VjaM5xB6VtPc1f4MFU,1484
|
15
|
+
planar/data/connection.py,sha256=OQL-EEBtfEOtN5PYZA5TswCTD8Cebt9-pP_w5Qifs24,6705
|
16
|
+
planar/data/dataset.py,sha256=f-x9cOuGyQQldC98mCwpFVOXMiDNN6LQDQ9vtljXVRo,6095
|
19
17
|
planar/data/exceptions.py,sha256=AlhGQ_TReyEzfPSlqoXCjoZ1206Ut7dS4lrukVfGHaw,358
|
20
|
-
planar/data/
|
21
|
-
planar/data/utils.py,sha256=hhHKpYBvzLdzjNy_OElpAqIU-3XuHqUkFCiF5YWsShs,2556
|
18
|
+
planar/data/utils.py,sha256=NhxJFSxPLNX1ddSANS3-bVhMr1Q_-25qDRRXxGug4Vc,6312
|
22
19
|
planar/db/__init__.py,sha256=SNgB6unQ1f1E9dB9O-KrsPsYM17KLsgOW1u0ajqs57I,318
|
23
|
-
planar/db/alembic/env.py,sha256=
|
20
|
+
planar/db/alembic/env.py,sha256=gOKwdugTO1tyUl8BAlpYJ7AweOXqgX1Arg88lle1944,6180
|
24
21
|
planar/db/alembic/script.py.mako,sha256=BgXfi4ClINnJU-PaaWqh1-Sjqu4brkWpbVd-0rEPzLU,665
|
25
22
|
planar/db/alembic/versions/3476068c153c_initial_system_tables_migration.py,sha256=1FbzJyfapjegM-Mxd3HMMVA-8zVU6AnrnzEgIoc6eoQ,13204
|
26
23
|
planar/db/alembic/versions/8855a78a408f_message_step_type.py,sha256=iH13r8swy79lw8icGNKW1lqN09TX93MvR1zi-qvWNlU,869
|
27
|
-
planar/db/alembic.ini,sha256=
|
24
|
+
planar/db/alembic.ini,sha256=KtC8QRYmJoWV04tYZ94FDvE4xrYm-vhTTdCRfryPdes,4303
|
28
25
|
planar/db/db.py,sha256=VNpHH1R62tdWVLIV1I2ULmw3B8M6-RsM2ALG3VAVjSg,12790
|
29
26
|
planar/dependencies.py,sha256=PH78fGk3bQfGnz-AphxH49307Y0XVgl3EY0LdGJnoik,1008
|
30
27
|
planar/files/__init__.py,sha256=uXqwnoIaJAuDYXFA-9gqcSq1R4mZLNyfem1zZyGI5Ek,206
|
31
28
|
planar/files/models.py,sha256=zbZvMkoqoSnn7yOo26SRtEgtlHJbFIvwSht75APHQXk,6145
|
32
29
|
planar/files/storage/azure_blob.py,sha256=QM-j9NHZmbwGv7H04yNpakJ54BJMseWEjehSekL3yr8,12316
|
33
30
|
planar/files/storage/base.py,sha256=KO7jyKwjKg5fNSLvhxJWE-lsypv6LXXf7bgA34aflwY,2495
|
34
|
-
planar/files/storage/config.py,sha256=
|
31
|
+
planar/files/storage/config.py,sha256=lzODgufhZliwQDikqMQCX3KKiap0CL6Cc9qbIdeUMCU,3617
|
35
32
|
planar/files/storage/context.py,sha256=Qadlz4T-FQ1A0TdGsOfuNmM679ohayU7oaexUpT8AY0,361
|
36
33
|
planar/files/storage/local_directory.py,sha256=1SsEfr0Ud9TvSQJneDl_M-D7AFYixLE9t-bVIiY3aSI,7395
|
37
34
|
planar/files/storage/s3.py,sha256=1861rSw3kplXtugUWD7mdSD_EnPSHME1mGc82V69r5g,8234
|
38
|
-
planar/files/storage/test_azure_blob.py,sha256=OFYpns6JyeCCBHCoLz56uUHR6tWWeSZldUant5llczI,14200
|
39
|
-
planar/files/storage/test_local_directory.py,sha256=KtzRfjtZUew1U-KETtD2mb6ywwX6HmjzaaeixOP0Ebg,5751
|
40
|
-
planar/files/storage/test_s3.py,sha256=QG-CH7fiaRmQRwffnqG2mLRrw9LIlR2-xRyHs6Wuspo,10565
|
41
|
-
planar/files/test_files.py,sha256=nclsbLnbijCWQ-Aj8Yvo06hs72PygL1Wps7uk7716sc,8957
|
42
35
|
planar/human/__init__.py,sha256=FwpV-FFssKKlvKSjWoI4gJB1XTMaNb1UNCSBxjAtIBw,147
|
43
36
|
planar/human/human.py,sha256=-oRtN_8bCtSV7Sxku7yG4rof7T5pr4j18Cfm3u4Z3PM,14925
|
44
37
|
planar/human/models.py,sha256=Cec1Y9NGGtuAl1ZhqNc9PWIq__BbiWVTh7IYKR4yl3w,2317
|
45
|
-
planar/human/test_human.py,sha256=GlbTjCNeAAfcwVIPq1TRiH0ojSgAU0i3oMc2yQe0xVo,13226
|
46
38
|
planar/logging/__init__.py,sha256=BW101gskQS3C2agKSDiJEy4L-j5z6BP1AwEfd2JMXHM,254
|
47
39
|
planar/logging/attributes.py,sha256=SB-lC-Osa55zXkX2UAWm56vKXvHgbF7TmhGnSiBWejk,1529
|
48
40
|
planar/logging/context.py,sha256=mGVpL-276VWpRUIGlkGwbn9gkATqFS7lcFn1aM0v-eQ,384
|
49
41
|
planar/logging/formatter.py,sha256=NMDhpo7ezsfGO7cPwOWbClqODviEgSjqHCoqrCCIu2c,3560
|
50
42
|
planar/logging/logger.py,sha256=vj3-z2ea0J1ppgDpJBsrueA3jg5kjk9ceIo-4tWarXk,2650
|
51
43
|
planar/logging/otel.py,sha256=bD1wgKTon1ooq3JIWc_i0_d_ejxw8_a5YPFuizRa5ic,1734
|
52
|
-
planar/logging/test_formatter.py,sha256=nzlZFUC1JD4Imcy1H7VaFhwjrHzRc_oQLXWZXiN7iGA,11695
|
53
44
|
planar/modeling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
45
|
planar/modeling/field_helpers.py,sha256=9SOHTWPzjlaiq7RF88wjug3NvAywFurcHn651YL_SNY,1903
|
55
46
|
planar/modeling/json_schema_generator.py,sha256=NDqPkWQA_I7ywQXCEQfj5ub9u5KAFEcSQpXVkrCluV4,2864
|
56
47
|
planar/modeling/mixins/__init__.py,sha256=Lwg5eL4VFfv61FRBvH5OZqIyfrSogxQlYLUDnWnSorg,320
|
57
48
|
planar/modeling/mixins/auditable.py,sha256=WP7aDWVn1j22ZffKzYRpu23JQJ4vvHCU1qxcbgChwhc,1619
|
58
|
-
planar/modeling/mixins/test_auditable.py,sha256=RSYesWWBysFEWTD39-yDhww3wCe1OPN9Yt3ywGmx4d8,2912
|
59
|
-
planar/modeling/mixins/test_timestamp.py,sha256=oLKPvr8oUdjJPJRif81nn4YV_uwbxql_ojjXdKI7j7E,4366
|
60
|
-
planar/modeling/mixins/test_uuid_primary_key.py,sha256=t9ZoB0dS4jjJVrHic7EeEh_g3eZeYV3mr0ylv3Kr1Io,1575
|
61
49
|
planar/modeling/mixins/timestamp.py,sha256=-eHndCWztDiOxfCI2UknmphGeoHMJVDJG1Lz4KtkQUA,1641
|
62
50
|
planar/modeling/mixins/uuid_primary_key.py,sha256=O1BtuXk5GdsfpwTS6nGZm1GNi0pdXKQ6Kt2f5ZjiuMc,453
|
63
51
|
planar/modeling/orm/__init__.py,sha256=QwPgToKEf_gCdjAjKKmgh0xLTHGsboK1kH1a1a0tSy0,339
|
@@ -72,60 +60,33 @@ planar/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
72
60
|
planar/registry_items.py,sha256=slRQWmrK39wn5BQ3ohHmbiwvkEq1yr1nB8jSc7QG2CE,2132
|
73
61
|
planar/routers/__init__.py,sha256=B_ZEbBuosX4ahPfvWZsyMIPmQm0rt6ail4nJA6NLfOk,379
|
74
62
|
planar/routers/agents_router.py,sha256=trb1JPYVlaV7O2uoYvKIrLuTNGP_PmQSLZmXYFWrHkg,8251
|
75
|
-
planar/routers/dataset_router.py,sha256=
|
63
|
+
planar/routers/dataset_router.py,sha256=V712DNeqycejP1daoEIDShoH3pW4wJ3U0fF3F3Wxv_0,7585
|
76
64
|
planar/routers/entity_router.py,sha256=7Y1LDSqI_ovoOGr9DGylGM8BmRxF-WSPQSwITJHc6NE,4841
|
77
65
|
planar/routers/event.py,sha256=yvzzMQaKRoS2A0KSjQTyWcfmBzpt8xPNDfVW50XUSCw,2961
|
78
66
|
planar/routers/files.py,sha256=udu6PeZ9AuOpNyJete21rWAVQyE0qnC7tnSyJ97AH4Y,5644
|
79
67
|
planar/routers/human.py,sha256=m_CbH97_QGmzriui_xopLOq-2D1kR0WgvO92fMaFeBQ,5010
|
80
|
-
planar/routers/info.py,sha256=
|
68
|
+
planar/routers/info.py,sha256=XaDTuqZl4jaF5i4po4j2M2Alhq6HcOC4GI1Fq9QVN30,5418
|
81
69
|
planar/routers/models.py,sha256=zknkVs9-B4UJlMe9fl2EpXx7sdzfjQfwAbNoL1a0wmI,4694
|
82
70
|
planar/routers/object_config_router.py,sha256=zA8-gGBQp1-Gm3uCC4WJ6nLicFwt4CsCqCYLFp1lRN8,4802
|
83
71
|
planar/routers/rule.py,sha256=d6giUwYRKzxQFPeoWbe8Ylp2Cxd71_uK8yoS9NrOOBg,3563
|
84
|
-
planar/routers/test_agents_router.py,sha256=jzRCLB21YcEfhaFUos_gfRp9WDdP38_cozTQkHbi9b4,6099
|
85
|
-
planar/routers/test_dataset_router.py,sha256=8Dm6ZFlIXQgwWLG3y00mz5cMsZvmIw7yM2-w-Qe_sCQ,13058
|
86
|
-
planar/routers/test_files_router.py,sha256=HfZF1zeJ9BD2jhE6s698Jo7sDpO55RJF5g1Ksup4jtM,1576
|
87
|
-
planar/routers/test_object_config_router.py,sha256=JpzoNlNONgljmGJYtrXnhtGhKjUT3YQMhP89fnt7dn4,11406
|
88
|
-
planar/routers/test_routes_security.py,sha256=lXHeYg_th4UaDWeANM-dzONF8p2bEtwXJYYUlftE9R8,5556
|
89
|
-
planar/routers/test_rule_router.py,sha256=08fa4sc7RaXvQzPCQQ4LaftfXuQwoPEDzcS4lesPG2Q,17220
|
90
|
-
planar/routers/test_workflow_router.py,sha256=h2XTJrlO3vAshd45abtMaE0kigWTNxXjfJiuGcjcA7s,17463
|
91
72
|
planar/routers/workflow.py,sha256=I9wJLqcFf52eEREhwqMsYICBEVD7I07g7ILWzxR5x9Y,18151
|
92
73
|
planar/rules/__init__.py,sha256=lF3F8Rdf2ottjiJu0IeBdqhg1bckLhOqZFI2t-8KItM,474
|
93
74
|
planar/rules/decorator.py,sha256=nxT17n9uwfXMOlk5lliw_cRS7Y83gMI6CQdrf_pB5yk,6666
|
94
75
|
planar/rules/models.py,sha256=vC38JLeGzmU87L8BX4AyVJLJHmRYjWRmoHQ6S6ZlhPg,10186
|
95
76
|
planar/rules/rule_configuration.py,sha256=B2G6mPnfxA277nF-Gr-B_Uely-ZOhz2jAhiwQMZuY-k,6508
|
96
77
|
planar/rules/runner.py,sha256=KIPrt_ri50qotvDLOY9xly40bNTWRh8GVT2kEJFFtFo,1714
|
97
|
-
planar/rules/test_data/account_dormancy_management.json,sha256=9aMMELZrF5DTBluMKUXJptxwULEcva4GHEyaapIeerY,4776
|
98
|
-
planar/rules/test_data/airline_loyalty_points_calculator.json,sha256=7S1koMe60yR3h2VQys34oLy5ynhsEQ5wadMLPHCRQZA,5689
|
99
|
-
planar/rules/test_data/applicant_risk_assessment.json,sha256=rj-Q13NczdNt00x5wrvGLalw5IfdT1j-_RvpwCZa7Fc,9994
|
100
|
-
planar/rules/test_data/booking_fraud_detection.json,sha256=HCAsUIIlaPL8Ph3jtUFVi2vTZxZW53-XggjDWEoXmi4,10027
|
101
|
-
planar/rules/test_data/cellular_data_rollover_system.json,sha256=8GjkKqqzK7usSa5KAvUwkD2CzW5JtLGECjlD5gH-vHk,6317
|
102
|
-
planar/rules/test_data/clinical_trial_eligibility_screener.json,sha256=VV0RzWdThBNlIffuyklqAcKtRq-aOLHpcXX28IR9qOU,11152
|
103
|
-
planar/rules/test_data/customer_lifetime_value.json,sha256=ZYeISNOsgT7zLcddeNrrrHlrocDlDBmSfOlQqhu3PTE,3562
|
104
|
-
planar/rules/test_data/import_duties_calculator.json,sha256=JsXuvkiGQF6MxrgrIhFC1UxDCtO9nQpxtKKXwOQ1VYs,9062
|
105
|
-
planar/rules/test_data/insurance_prior_authorization.json,sha256=27_jET4mmpuzLeOzVF5xi7c9IexX1UJTKsIoQGQ0n8c,12145
|
106
|
-
planar/rules/test_data/online_check_in_eligibility_system.json,sha256=c6zCGojFN6c-CnuvG93zqlCZIrMccnOGAPMZVoMfirg,6114
|
107
|
-
planar/rules/test_data/order_consolidation_system.json,sha256=kWJuVHAfAqsDW2xVdxHbtJTlfolQ_SM6_GISgnxsYB8,9803
|
108
|
-
planar/rules/test_data/portfolio_risk_monitor.json,sha256=tTvQOJJLhakGxG4CnA9fdBIECstJnp0B8ogFADkdy8s,15168
|
109
|
-
planar/rules/test_data/supply_chain_risk.json,sha256=fO0wV5ZnsZQpOP19Zp2troTMADaX0-KMpCxG_uHG198,7263
|
110
|
-
planar/rules/test_data/warehouse_cross_docking.json,sha256=IPfcgNkY2sds301BeW6CjgFtK_zRyr27gI3UcqCB2Uo,5549
|
111
|
-
planar/rules/test_rules.py,sha256=6M7CSg1bwn7O7DOoNi38vyVG4UmPQfRFxEO9qGE6rz0,52011
|
112
78
|
planar/scaffold_templates/app/__init__.py.j2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
113
79
|
planar/scaffold_templates/app/db/entities.py.j2,sha256=wg9O3JtRaRMKlDtoWHHodyNRL0s1UILvsr9fCQ_O2-4,279
|
114
80
|
planar/scaffold_templates/app/flows/process_invoice.py.j2,sha256=R3EII_O2DHV1kvffW_AApZyaS6rR9eikcpxI08XH9dI,1691
|
115
81
|
planar/scaffold_templates/main.py.j2,sha256=zrqsuv3Fp4lcknvB37RrRHy11msdFB1yDguYmTLLPhw,398
|
116
82
|
planar/scaffold_templates/planar.dev.yaml.j2,sha256=I5-IqX7GJm6qA91WtUMw43L4hKACqgnER_H2racim4c,998
|
117
83
|
planar/scaffold_templates/planar.prod.yaml.j2,sha256=FahJ2atDtvVH7IUCatGq6h9hmyF8meeiWC8RLfWphOQ,867
|
118
|
-
planar/scaffold_templates/pyproject.toml.j2,sha256=
|
84
|
+
planar/scaffold_templates/pyproject.toml.j2,sha256=HpBc3cuTr-VeVN3BQ8y1Vr2eOtkL7TLH5mNz_T-akpA,190
|
119
85
|
planar/security/auth_context.py,sha256=i63JkHQ3oXNlTis7GIKRkZJbkcvZhD2jVDuO7blgbSc,5068
|
120
86
|
planar/security/auth_middleware.py,sha256=Grrm0i2bstWZ83ukrNZsHvFbNzffN0rvbbCcb2OxRY0,5746
|
121
87
|
planar/security/authorization.py,sha256=zTh5rLmVJZnGDq540_1WYljJ7Hws-BY_P6VqUCONqLE,12760
|
122
88
|
planar/security/default_policies.cedar,sha256=j7stjEfmgzthsDCjw1NwlE3_SxXQmLOGNRONM_2htoE,1492
|
123
89
|
planar/security/security_context.py,sha256=vzfwiDJRzq8snaENrJddG5Ei-UUq_a5hkInMEOZf0mM,496
|
124
|
-
planar/security/tests/test_auth_middleware.py,sha256=GjAyJYAR6jF_zGG85ZKY-E_e_aoqjK8qiHSalv2T2rk,6206
|
125
|
-
planar/security/tests/test_authorization_context.py,sha256=cnsC3V13NBJwzyIwZaM9wu_vergcnmVhwB3khVH7G-o,2364
|
126
|
-
planar/security/tests/test_cedar_basics.py,sha256=i1jLPjlJT1n_97onbeDYVpnwAzU2PmHvIPvaJSH1J2U,1026
|
127
|
-
planar/security/tests/test_cedar_policies.py,sha256=-Vn_CQgCUAVg7YhdUd34FsOjNL1EmY_o92r-fzmknP8,4848
|
128
|
-
planar/security/tests/test_jwt_principal_context.py,sha256=nGElTLtXbabkAxd3kXVpSFdH7kvSzHzSkp89g5Vu5Hc,4691
|
129
90
|
planar/session.py,sha256=xLS9WPvaiy9nr2Olju1-C-7_sU5VXK8RuNdjuKndul4,1020
|
130
91
|
planar/sse/constants.py,sha256=jE3SooTEWPuuL_Bi6DisJYMR9pKOiHVfboU2h5QTJRg,22
|
131
92
|
planar/sse/example.html,sha256=SgTJbdJ3B1F1DxLC2YWuX2F1XVwKcTjX34CbJCXoCTM,4144
|
@@ -133,21 +94,14 @@ planar/sse/hub.py,sha256=5jhfk7zdCivau3TT1MxU2qtvETSskhqEiXzt-t0sRpE,6859
|
|
133
94
|
planar/sse/model.py,sha256=fU_Fx9LS2ouS6-Dj1TIF-PLGul9YratKWafoWfZR1gc,123
|
134
95
|
planar/sse/proxy.py,sha256=aJGo_-JIeQ0xSmE4HJdulZxIgCVRsBMMXqqSqtPvTvo,9177
|
135
96
|
planar/task_local.py,sha256=pyvT0bdzAn15HL2yQUs9YrU5MVXh9njQt9MH51AGljs,1102
|
136
|
-
planar/test_app.py,sha256=5dYhOW6lRbAx2X270DfqktkJ5IfuqfowX6bwxM1WQAM,4865
|
137
|
-
planar/test_cli.py,sha256=faR6CSuooHHyyB5Yt-p8CIr7mGtKrrU2TLQbc4Oe9bA,13834
|
138
|
-
planar/test_config.py,sha256=HcmDu1nwKZZhzHQLGVyP9oxje-_g_XubEsvzRj28QPg,14328
|
139
|
-
planar/test_object_config.py,sha256=izn4s2HmSDWpGtgpOTDmKeUYN2-63WDR1QtVQrT-x00,20135
|
140
|
-
planar/test_object_registry.py,sha256=R7IwbB2GACm2HUuVZTeVY4V12XB9_JgSSeppPxiCdfs,480
|
141
|
-
planar/test_sqlalchemy.py,sha256=QTloaipWiFmlLTBGH6YCRkwi1R27gmQZnwprO7lPLfU,7058
|
142
|
-
planar/test_utils.py,sha256=gKenXotj36SN_bb3bQpYPfD8t06IjnGBQqEgWpujHcA,3086
|
143
97
|
planar/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
144
|
-
planar/testing/fixtures.py,sha256=
|
98
|
+
planar/testing/fixtures.py,sha256=z0VkKTqAg9z_1L_ojB0pTzKSaLPcDeNxRq_RB36rUU8,9740
|
145
99
|
planar/testing/memory_storage.py,sha256=apcuFisC3hW9KiU3kO8zwHQ6oK9Lu20NSX5fJ0LSZUY,2824
|
146
|
-
planar/testing/planar_test_client.py,sha256=
|
100
|
+
planar/testing/planar_test_client.py,sha256=yMEmEUxlnoO4OeErx0DO_Fch0XrKyJBcsKCq-qrZrZA,2220
|
147
101
|
planar/testing/synchronizable_tracer.py,sha256=SWeta1CgwGsN5duC0FR8NyXOQ1b1L8nDpvGdjZVJ9Bg,4938
|
148
|
-
planar/testing/test_memory_storage.py,sha256=So32XL0gbLDFMTl-WJN445x9jL6O8Qsqw8IRaiZnsPs,4797
|
149
102
|
planar/testing/workflow_observer.py,sha256=0Q2xsYuZzNGXHZVwvXBqL9KXPsdIXuSZGBJAxHopzJw,2976
|
150
103
|
planar/utils.py,sha256=YP37-ODS8nYOIfHPo11CwCpQRsg8oc57lQ0wkXwqCyo,3607
|
104
|
+
planar/version.py,sha256=FvzlKrPfP1lqDNc-m3AIyd0wijm3VtvpUS5VKdUHq3Y,699
|
151
105
|
planar/workflows/__init__.py,sha256=yFrrtKYUCx4jBPpHdEWDfKQgZXzGyr9voj5lFe9C-_w,826
|
152
106
|
planar/workflows/context.py,sha256=93kPSmYniqjX_lv6--eUUPnzZEKZJi6IPaAjrT-hFRY,1271
|
153
107
|
planar/workflows/contrib.py,sha256=tUqMZ42Jh8KMy1JP1VFJOD4rsiYxzMTd5pJfe2t3yzk,6650
|
@@ -166,14 +120,9 @@ planar/workflows/step_core.py,sha256=e-O-SP_1ufr3EYwuvu3O4I06aoqMxu_tpvHAUO-pMWg
|
|
166
120
|
planar/workflows/step_metadata.py,sha256=7hwcIm6ot8m-iUXSYCbPmkg6bWegF6_RJ1stInvaFII,10903
|
167
121
|
planar/workflows/step_testing_utils.py,sha256=WiTwxB4mM2y6dW7CJ3PlIR1BkBodSxQV7-S25pQ3Ycs,2361
|
168
122
|
planar/workflows/sub_workflow_runner.py,sha256=EpS7DhhXRbC6ABm-Sho6Uyxh2TqCjcTPDYvcTQN4FjY,8313
|
169
|
-
planar/workflows/test_concurrency_detection.py,sha256=yfgvLOMkPaK7EiW4ihm1KQx82Y-s9pB6uJhBfDi7PwQ,4528
|
170
|
-
planar/workflows/test_lock_timeout.py,sha256=H78N090wJtiEg6SaJosfRWijpX6HwnyWyNNb7WaGPe0,5746
|
171
|
-
planar/workflows/test_serialization.py,sha256=JfaveBRQTNMkucqkTorIMGcvi8S0j6uRtboFaWpCmes,39586
|
172
|
-
planar/workflows/test_suspend_deserialization.py,sha256=ddw2jToSJ-ebQ0RfT7KWTRMCOs1nis1lprQiGIGuaJ0,7751
|
173
|
-
planar/workflows/test_workflow.py,sha256=hBLPQYqUsWEQ_SopKgi69ckRC5OpmQEBlsPcftGMu_Q,65266
|
174
123
|
planar/workflows/tracing.py,sha256=E7E_kj2VBQisDqrllviIshbvOmB9QcEeRwMapunqio4,2732
|
175
124
|
planar/workflows/wrappers.py,sha256=dY_3NqkzGMG4jgX2lkAqvHTYFA1lBzhkQCw7N5CyaQM,1174
|
176
|
-
planar-0.
|
177
|
-
planar-0.
|
178
|
-
planar-0.
|
179
|
-
planar-0.
|
125
|
+
planar-0.12.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
|
126
|
+
planar-0.12.0.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
|
127
|
+
planar-0.12.0.dist-info/METADATA,sha256=QzYhhuXw0VLyymqS31qadZ_DeIYbG7v93MZAe5t2Esw,7285
|
128
|
+
planar-0.12.0.dist-info/RECORD,,
|
@@ -1,229 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Tests for agent serialization functionality.
|
3
|
-
|
4
|
-
This module tests the serialization of agents including configuration
|
5
|
-
management and schema validation warnings.
|
6
|
-
"""
|
7
|
-
|
8
|
-
import pytest
|
9
|
-
from pydantic import BaseModel
|
10
|
-
from sqlmodel.ext.asyncio.session import AsyncSession
|
11
|
-
|
12
|
-
from planar.ai.agent import Agent
|
13
|
-
from planar.ai.agent_utils import AgentConfig, agent_configuration
|
14
|
-
from planar.ai.models import AgentSerializeable
|
15
|
-
from planar.ai.utils import serialize_agent
|
16
|
-
from planar.object_config.object_config import ObjectConfigurationBase
|
17
|
-
|
18
|
-
|
19
|
-
class InputModelForTest(BaseModel):
|
20
|
-
"""Test input model for agents."""
|
21
|
-
|
22
|
-
text: str
|
23
|
-
value: int
|
24
|
-
|
25
|
-
|
26
|
-
class OutputModelForTest(BaseModel):
|
27
|
-
"""Test output model for agents."""
|
28
|
-
|
29
|
-
result: str
|
30
|
-
score: float
|
31
|
-
|
32
|
-
|
33
|
-
@pytest.fixture
|
34
|
-
def test_agent():
|
35
|
-
"""Create a test agent with various configurations."""
|
36
|
-
return Agent(
|
37
|
-
name="test_serialization_agent",
|
38
|
-
system_prompt="Test system prompt",
|
39
|
-
user_prompt="Test user prompt: {input}",
|
40
|
-
model="openai:gpt-4o",
|
41
|
-
max_turns=3,
|
42
|
-
input_type=InputModelForTest,
|
43
|
-
output_type=OutputModelForTest,
|
44
|
-
)
|
45
|
-
|
46
|
-
|
47
|
-
@pytest.fixture
|
48
|
-
def test_agent_with_tools():
|
49
|
-
"""Create a test agent with tools."""
|
50
|
-
|
51
|
-
async def test_tool(param: str) -> str:
|
52
|
-
"""A test tool."""
|
53
|
-
return f"Processed: {param}"
|
54
|
-
|
55
|
-
return Agent(
|
56
|
-
name="test_agent_with_tools",
|
57
|
-
system_prompt="System with tools",
|
58
|
-
user_prompt="User: {input}",
|
59
|
-
model="anthropic:claude-3-5-sonnet-latest",
|
60
|
-
max_turns=5,
|
61
|
-
tools=[test_tool],
|
62
|
-
)
|
63
|
-
|
64
|
-
|
65
|
-
async def test_serialize_agent_basic(session: AsyncSession, test_agent):
|
66
|
-
"""Test basic agent serialization without any configurations."""
|
67
|
-
|
68
|
-
# Serialize the agent
|
69
|
-
serialized = await serialize_agent(test_agent)
|
70
|
-
|
71
|
-
# Verify basic fields
|
72
|
-
assert isinstance(serialized, AgentSerializeable)
|
73
|
-
assert serialized.name == "test_serialization_agent"
|
74
|
-
assert serialized.input_schema is not None
|
75
|
-
assert serialized.output_schema is not None
|
76
|
-
assert serialized.tool_definitions == []
|
77
|
-
|
78
|
-
# Verify configs field exists and contains the default config (at least one config always present)
|
79
|
-
assert hasattr(serialized, "configs")
|
80
|
-
assert len(serialized.configs) == 1
|
81
|
-
|
82
|
-
# Verify the default config is present and correct
|
83
|
-
default_config = serialized.configs[-1]
|
84
|
-
assert isinstance(default_config, ObjectConfigurationBase)
|
85
|
-
assert default_config.version == 0
|
86
|
-
assert default_config.data.system_prompt == test_agent.system_prompt
|
87
|
-
assert default_config.data.user_prompt == test_agent.user_prompt
|
88
|
-
assert default_config.data.model == str(test_agent.model)
|
89
|
-
assert default_config.data.max_turns == test_agent.max_turns
|
90
|
-
assert default_config.data.model_parameters == test_agent.model_parameters
|
91
|
-
|
92
|
-
# Verify overwrites field is removed
|
93
|
-
assert not hasattr(serialized, "overwrites")
|
94
|
-
|
95
|
-
|
96
|
-
async def test_serialize_agent_with_configs(session: AsyncSession, test_agent):
|
97
|
-
"""Test agent serialization with multiple configurations."""
|
98
|
-
|
99
|
-
# Create multiple configurations
|
100
|
-
config1 = AgentConfig(
|
101
|
-
system_prompt="Override system 1",
|
102
|
-
user_prompt="Override user 1: {input}",
|
103
|
-
model="openai:gpt-4o",
|
104
|
-
max_turns=2,
|
105
|
-
model_parameters={"temperature": 0.7},
|
106
|
-
)
|
107
|
-
|
108
|
-
config2 = AgentConfig(
|
109
|
-
system_prompt="Override system 2",
|
110
|
-
user_prompt="Override user 2: {input}",
|
111
|
-
model="anthropic:claude-3-opus",
|
112
|
-
max_turns=4,
|
113
|
-
model_parameters={"temperature": 0.9},
|
114
|
-
)
|
115
|
-
|
116
|
-
# Write configurations
|
117
|
-
await agent_configuration.write_config(test_agent.name, config1)
|
118
|
-
await agent_configuration.write_config(test_agent.name, config2)
|
119
|
-
|
120
|
-
# Serialize the agent
|
121
|
-
serialized = await serialize_agent(test_agent)
|
122
|
-
|
123
|
-
# Verify configs are included
|
124
|
-
assert len(serialized.configs) == 3
|
125
|
-
|
126
|
-
# Verify default config is included
|
127
|
-
default_config = serialized.configs[-1]
|
128
|
-
assert isinstance(default_config, ObjectConfigurationBase)
|
129
|
-
assert default_config.version == 0
|
130
|
-
assert default_config.data.system_prompt == test_agent.system_prompt
|
131
|
-
assert default_config.data.user_prompt == test_agent.user_prompt
|
132
|
-
assert default_config.data.model == str(test_agent.model)
|
133
|
-
assert default_config.data.max_turns == test_agent.max_turns
|
134
|
-
assert default_config.data.model_parameters == test_agent.model_parameters
|
135
|
-
|
136
|
-
# Verify configs are ordered by version (descending)
|
137
|
-
assert all(
|
138
|
-
isinstance(config, ObjectConfigurationBase) for config in serialized.configs
|
139
|
-
)
|
140
|
-
assert serialized.configs[0].version == 2 # Latest version first
|
141
|
-
assert serialized.configs[1].version == 1
|
142
|
-
|
143
|
-
# Verify config data
|
144
|
-
latest_config = serialized.configs[0]
|
145
|
-
assert latest_config.data.system_prompt == "Override system 2"
|
146
|
-
assert latest_config.data.user_prompt == "Override user 2: {input}"
|
147
|
-
assert latest_config.data.model == "anthropic:claude-3-opus"
|
148
|
-
assert latest_config.data.max_turns == 4
|
149
|
-
|
150
|
-
older_config = serialized.configs[1]
|
151
|
-
assert older_config.data.system_prompt == "Override system 1"
|
152
|
-
assert older_config.data.user_prompt == "Override user 1: {input}"
|
153
|
-
|
154
|
-
|
155
|
-
async def test_serialize_agent_with_tools(session: AsyncSession, test_agent_with_tools):
|
156
|
-
"""Test serialization of agent with tools."""
|
157
|
-
|
158
|
-
# Serialize the agent
|
159
|
-
serialized = await serialize_agent(test_agent_with_tools)
|
160
|
-
|
161
|
-
# Verify tool definitions are included
|
162
|
-
assert len(serialized.tool_definitions) == 1
|
163
|
-
tool_def = serialized.tool_definitions[0]
|
164
|
-
assert tool_def["name"] == "test_tool"
|
165
|
-
assert tool_def["description"] == "A test tool."
|
166
|
-
assert "parameters" in tool_def
|
167
|
-
|
168
|
-
|
169
|
-
async def test_serialize_agent_no_duplicate_fields(session: AsyncSession, test_agent):
|
170
|
-
"""Test that AgentSerializeable doesn't duplicate fields from AgentConfig."""
|
171
|
-
|
172
|
-
# Create a configuration
|
173
|
-
config = AgentConfig(
|
174
|
-
system_prompt="Config system",
|
175
|
-
user_prompt="Config user: {input}",
|
176
|
-
model="openai:gpt-3.5-turbo",
|
177
|
-
max_turns=1,
|
178
|
-
model_parameters={},
|
179
|
-
)
|
180
|
-
|
181
|
-
await agent_configuration.write_config(test_agent.name, config)
|
182
|
-
|
183
|
-
# Serialize the agent
|
184
|
-
serialized = await serialize_agent(test_agent)
|
185
|
-
|
186
|
-
# Verify that system_prompt, user_prompt, model, max_turns are NOT in the serialized object
|
187
|
-
# They should only be in the configs
|
188
|
-
assert not hasattr(serialized, "system_prompt")
|
189
|
-
assert not hasattr(serialized, "user_prompt")
|
190
|
-
assert not hasattr(serialized, "model")
|
191
|
-
assert not hasattr(serialized, "max_turns")
|
192
|
-
|
193
|
-
# These fields should only be accessible through configs
|
194
|
-
assert serialized.configs[0].data.system_prompt == "Config system"
|
195
|
-
assert serialized.configs[0].data.user_prompt == "Config user: {input}"
|
196
|
-
assert serialized.configs[0].data.model == "openai:gpt-3.5-turbo"
|
197
|
-
assert serialized.configs[0].data.max_turns == 1
|
198
|
-
|
199
|
-
|
200
|
-
async def test_agent_serializable_structure():
|
201
|
-
"""Test the structure of AgentSerializeable model."""
|
202
|
-
# Verify the model has the expected fields
|
203
|
-
fields = AgentSerializeable.model_fields.keys()
|
204
|
-
|
205
|
-
# Should have these fields
|
206
|
-
assert "name" in fields
|
207
|
-
assert "input_schema" in fields
|
208
|
-
assert "output_schema" in fields
|
209
|
-
assert "tool_definitions" in fields
|
210
|
-
assert "configs" in fields
|
211
|
-
assert "built_in_vars" in fields
|
212
|
-
|
213
|
-
# Should NOT have these fields (moved to configs)
|
214
|
-
assert "system_prompt" not in fields
|
215
|
-
assert "user_prompt" not in fields
|
216
|
-
assert "model" not in fields
|
217
|
-
assert "max_turns" not in fields
|
218
|
-
assert "overwrites" not in fields
|
219
|
-
|
220
|
-
|
221
|
-
async def test_configs_field_type():
|
222
|
-
"""Test that configs field has the correct type annotation."""
|
223
|
-
# Get the type annotation for configs field
|
224
|
-
configs_field = AgentSerializeable.model_fields["configs"]
|
225
|
-
|
226
|
-
# The annotation should be list[ObjectConfigurationBase[AgentConfig]]
|
227
|
-
# This is a complex type, so we'll check the string representation
|
228
|
-
assert "ObjectConfigurationBase" in str(configs_field.annotation)
|
229
|
-
assert "AgentConfig" in str(configs_field.annotation)
|
@@ -1,78 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from unittest.mock import patch
|
3
|
-
|
4
|
-
from sqlmodel import col, select
|
5
|
-
|
6
|
-
from planar.ai import models as m
|
7
|
-
from planar.ai.agent import Agent
|
8
|
-
from planar.ai.pydantic_ai import ModelRunResponse
|
9
|
-
from planar.workflows.decorators import workflow
|
10
|
-
from planar.workflows.execution import execute
|
11
|
-
from planar.workflows.models import StepType, WorkflowStep
|
12
|
-
|
13
|
-
|
14
|
-
async def test_agent_tool_step_has_display_name(session):
|
15
|
-
async def add(a: int, b: int) -> int:
|
16
|
-
return a + b
|
17
|
-
|
18
|
-
# Prepare mocked model responses: first triggers a tool call, then returns final content
|
19
|
-
first = ModelRunResponse[str](
|
20
|
-
response=m.CompletionResponse[str](
|
21
|
-
content=None,
|
22
|
-
tool_calls=[
|
23
|
-
m.ToolCall(id="call_1", name="add", arguments={"a": 2, "b": 3})
|
24
|
-
],
|
25
|
-
text_content="",
|
26
|
-
reasoning_content=None,
|
27
|
-
),
|
28
|
-
extra_turns_used=0,
|
29
|
-
)
|
30
|
-
second = ModelRunResponse[str](
|
31
|
-
response=m.CompletionResponse[str](
|
32
|
-
content="5",
|
33
|
-
tool_calls=[],
|
34
|
-
text_content="5",
|
35
|
-
reasoning_content=None,
|
36
|
-
),
|
37
|
-
extra_turns_used=0,
|
38
|
-
)
|
39
|
-
|
40
|
-
responses = [first, second]
|
41
|
-
|
42
|
-
async def fake_model_run(*args, **kwargs):
|
43
|
-
assert responses, "No more fake responses configured"
|
44
|
-
return responses.pop(0)
|
45
|
-
|
46
|
-
# Patch the model run to avoid any network/model dependency
|
47
|
-
# Use unittest.mock.patch context managers to ensure cleanup
|
48
|
-
with (
|
49
|
-
patch.dict(os.environ, {"OPENAI_API_KEY": "test-key"}, clear=False),
|
50
|
-
patch("planar.ai.agent.model_run", side_effect=fake_model_run),
|
51
|
-
):
|
52
|
-
agent = Agent[str, str, None](
|
53
|
-
name="test_agent",
|
54
|
-
system_prompt="",
|
55
|
-
user_prompt="",
|
56
|
-
model="openai:gpt-4o-mini",
|
57
|
-
tools=[add],
|
58
|
-
max_turns=3,
|
59
|
-
)
|
60
|
-
|
61
|
-
@workflow()
|
62
|
-
async def run_agent():
|
63
|
-
result = await agent("please add")
|
64
|
-
return result.output
|
65
|
-
|
66
|
-
wf = await run_agent.start()
|
67
|
-
result = await execute(wf)
|
68
|
-
assert result == "5"
|
69
|
-
|
70
|
-
steps = (
|
71
|
-
await session.exec(select(WorkflowStep).order_by(col(WorkflowStep.step_id)))
|
72
|
-
).all()
|
73
|
-
# Ensure there is a tool call step with the display name set to the tool name
|
74
|
-
tool_steps = [s for s in steps if s.step_type == StepType.TOOL_CALL]
|
75
|
-
assert tool_steps, "Expected at least one TOOL_CALL step recorded"
|
76
|
-
assert any(s.display_name == "add" for s in tool_steps), (
|
77
|
-
f"Expected a TOOL_CALL step with display_name 'add', got {[s.display_name for s in tool_steps]}"
|
78
|
-
)
|