pyfect-dev 0.1.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 (1265) hide show
  1. pyfect/__init__.py +729 -0
  2. pyfect/_all.py +242 -0
  3. pyfect/_background.py +28 -0
  4. pyfect/_binary_codecs.py +124 -0
  5. pyfect/_cached.py +165 -0
  6. pyfect/_catch.py +128 -0
  7. pyfect/_catch_reason.py +574 -0
  8. pyfect/_concurrency.py +291 -0
  9. pyfect/_context_effects.py +163 -0
  10. pyfect/_context_managers.py +76 -0
  11. pyfect/_core.py +368 -0
  12. pyfect/_digits.py +71 -0
  13. pyfect/_effect_args.py +46 -0
  14. pyfect/_effect_base.py +71 -0
  15. pyfect/_effect_concurrency.py +133 -0
  16. pyfect/_effect_eager.py +103 -0
  17. pyfect/_effect_errors.py +344 -0
  18. pyfect/_effect_folding.py +110 -0
  19. pyfect/_effect_hash.py +140 -0
  20. pyfect/_effect_logging.py +57 -0
  21. pyfect/_effect_metrics.py +102 -0
  22. pyfect/_effect_resources.py +179 -0
  23. pyfect/_effect_services.py +25 -0
  24. pyfect/_effect_timing.py +199 -0
  25. pyfect/_effect_tracing.py +99 -0
  26. pyfect/_equal.py +195 -0
  27. pyfect/_extras.py +43 -0
  28. pyfect/_fiber.py +969 -0
  29. pyfect/_fiber_all.py +134 -0
  30. pyfect/_fiber_collections.py +106 -0
  31. pyfect/_fn.py +706 -0
  32. pyfect/_hamt.py +174 -0
  33. pyfect/_interrupt_reason.py +33 -0
  34. pyfect/_isaac.py +149 -0
  35. pyfect/_iterables.py +231 -0
  36. pyfect/_js.py +263 -0
  37. pyfect/_js_date.py +87 -0
  38. pyfect/_json_text.py +286 -0
  39. pyfect/_json_value.py +9 -0
  40. pyfect/_layer_core.py +403 -0
  41. pyfect/_layer_for_life.py +33 -0
  42. pyfect/_layer_tracing.py +70 -0
  43. pyfect/_locked_ref.py +147 -0
  44. pyfect/_loop_thread.py +152 -0
  45. pyfect/_metric_ref.py +29 -0
  46. pyfect/_one_or_many.py +14 -0
  47. pyfect/_os_wait.py +118 -0
  48. pyfect/_path_posix.py +129 -0
  49. pyfect/_primitives.py +434 -0
  50. pyfect/_public.py +36 -0
  51. pyfect/_reasons.py +64 -0
  52. pyfect/_released.py +67 -0
  53. pyfect/_root.py +87 -0
  54. pyfect/_round_robin.py +73 -0
  55. pyfect/_some.py +17 -0
  56. pyfect/_stack.py +52 -0
  57. pyfect/_stack_frame.py +114 -0
  58. pyfect/_string_hash.py +35 -0
  59. pyfect/_subscriber_queue.py +47 -0
  60. pyfect/_tags.py +14 -0
  61. pyfect/_tracer_ref.py +21 -0
  62. pyfect/_tx_ops.py +77 -0
  63. pyfect/_unsubscripted.py +23 -0
  64. pyfect/_url.py +54 -0
  65. pyfect/_waiters.py +127 -0
  66. pyfect/_wake_tracking.py +98 -0
  67. pyfect/_wire_codec.py +123 -0
  68. pyfect/ai/__init__.py +73 -0
  69. pyfect/ai/_approvals.py +249 -0
  70. pyfect/ai/_decision_answers.py +185 -0
  71. pyfect/ai/_generated_client.py +298 -0
  72. pyfect/ai/_generated_support.py +84 -0
  73. pyfect/ai/_mcp/__init__.py +1 -0
  74. pyfect/ai/_mcp/batch.py +68 -0
  75. pyfect/ai/_mcp/client_transport.py +412 -0
  76. pyfect/ai/_mcp/client_wire.py +284 -0
  77. pyfect/ai/_mcp/core.py +490 -0
  78. pyfect/ai/_mcp/dispatch.py +1048 -0
  79. pyfect/ai/_mcp/http.py +462 -0
  80. pyfect/ai/_mcp/http_admission.py +269 -0
  81. pyfect/ai/_mcp/http_status.py +27 -0
  82. pyfect/ai/_mcp/input_wire.py +226 -0
  83. pyfect/ai/_mcp/log_levels.py +55 -0
  84. pyfect/ai/_mcp/param_headers.py +63 -0
  85. pyfect/ai/_mcp/projection.py +248 -0
  86. pyfect/ai/_mcp/register.py +683 -0
  87. pyfect/ai/_mcp/reverse_policy.py +155 -0
  88. pyfect/ai/_mcp/routing_header.py +24 -0
  89. pyfect/ai/_mcp/sessions.py +114 -0
  90. pyfect/ai/_mcp/stdio.py +110 -0
  91. pyfect/ai/_mcp/subscriptions.py +134 -0
  92. pyfect/ai/_mcp/tool_schema.py +35 -0
  93. pyfect/ai/_noul_answers.py +64 -0
  94. pyfect/ai/_openai_all_of.py +137 -0
  95. pyfect/ai/_openai_errors.py +233 -0
  96. pyfect/ai/_provider.py +439 -0
  97. pyfect/ai/_provider_tools.py +129 -0
  98. pyfect/ai/_stream_resolution.py +231 -0
  99. pyfect/ai/_structured_output_checks.py +138 -0
  100. pyfect/ai/_structured_output_codec.py +229 -0
  101. pyfect/ai/_structured_output_json.py +109 -0
  102. pyfect/ai/_tool_call_ids.py +80 -0
  103. pyfect/ai/ai_error.py +785 -0
  104. pyfect/ai/anthropic/__init__.py +28 -0
  105. pyfect/ai/anthropic/_errors.py +164 -0
  106. pyfect/ai/anthropic/_prompt.py +375 -0
  107. pyfect/ai/anthropic/_response.py +443 -0
  108. pyfect/ai/anthropic/_schema.py +206 -0
  109. pyfect/ai/anthropic/_stream.py +377 -0
  110. pyfect/ai/anthropic/_tools.py +248 -0
  111. pyfect/ai/anthropic/client.py +289 -0
  112. pyfect/ai/anthropic/config.py +32 -0
  113. pyfect/ai/anthropic/error.py +27 -0
  114. pyfect/ai/anthropic/language_model.py +366 -0
  115. pyfect/ai/anthropic/telemetry.py +51 -0
  116. pyfect/ai/anthropic/tool.py +570 -0
  117. pyfect/ai/anthropic_structured_output.py +138 -0
  118. pyfect/ai/chat.py +548 -0
  119. pyfect/ai/cloudflare/__init__.py +15 -0
  120. pyfect/ai/cloudflare/_errors.py +108 -0
  121. pyfect/ai/cloudflare/client.py +174 -0
  122. pyfect/ai/cloudflare/decision_model.py +117 -0
  123. pyfect/ai/cloudflare/schema.py +144 -0
  124. pyfect/ai/decision.py +290 -0
  125. pyfect/ai/decision_model.py +283 -0
  126. pyfect/ai/embedding_model.py +177 -0
  127. pyfect/ai/id_generator.py +79 -0
  128. pyfect/ai/language_model.py +1077 -0
  129. pyfect/ai/mcp_client.py +682 -0
  130. pyfect/ai/mcp_client_error.py +223 -0
  131. pyfect/ai/mcp_protocol.py +205 -0
  132. pyfect/ai/mcp_schema.py +1300 -0
  133. pyfect/ai/mcp_server.py +404 -0
  134. pyfect/ai/model.py +56 -0
  135. pyfect/ai/openai/__init__.py +49 -0
  136. pyfect/ai/openai/_errors.py +89 -0
  137. pyfect/ai/openai/_prompt.py +527 -0
  138. pyfect/ai/openai/_requests.py +34 -0
  139. pyfect/ai/openai/_response.py +569 -0
  140. pyfect/ai/openai/_schema.py +769 -0
  141. pyfect/ai/openai/_stream.py +771 -0
  142. pyfect/ai/openai/_tools.py +128 -0
  143. pyfect/ai/openai/_web_socket.py +295 -0
  144. pyfect/ai/openai/client.py +296 -0
  145. pyfect/ai/openai/client_generated.py +123 -0
  146. pyfect/ai/openai/config.py +34 -0
  147. pyfect/ai/openai/decision_model.py +177 -0
  148. pyfect/ai/openai/embedding_model.py +116 -0
  149. pyfect/ai/openai/error.py +8 -0
  150. pyfect/ai/openai/generated/__init__.py +7213 -0
  151. pyfect/ai/openai/generated/_recursive.py +18 -0
  152. pyfect/ai/openai/generated/_schemas_0.py +1015 -0
  153. pyfect/ai/openai/generated/_schemas_1.py +1016 -0
  154. pyfect/ai/openai/generated/_schemas_2.py +1017 -0
  155. pyfect/ai/openai/generated/_schemas_3.py +615 -0
  156. pyfect/ai/openai/generated/client.py +5298 -0
  157. pyfect/ai/openai/generated/types.py +8123 -0
  158. pyfect/ai/openai/language_model.py +304 -0
  159. pyfect/ai/openai/telemetry.py +19 -0
  160. pyfect/ai/openai/tool.py +391 -0
  161. pyfect/ai/openai_compat/__init__.py +25 -0
  162. pyfect/ai/openai_compat/_prompt.py +191 -0
  163. pyfect/ai/openai_compat/_request.py +153 -0
  164. pyfect/ai/openai_compat/_response.py +407 -0
  165. pyfect/ai/openai_compat/_schema.py +97 -0
  166. pyfect/ai/openai_compat/client.py +234 -0
  167. pyfect/ai/openai_compat/config.py +32 -0
  168. pyfect/ai/openai_compat/embedding_model.py +139 -0
  169. pyfect/ai/openai_compat/error.py +7 -0
  170. pyfect/ai/openai_compat/language_model.py +245 -0
  171. pyfect/ai/openai_compat/telemetry.py +51 -0
  172. pyfect/ai/openai_structured_output.py +118 -0
  173. pyfect/ai/openrouter/__init__.py +36 -0
  174. pyfect/ai/openrouter/_errors.py +186 -0
  175. pyfect/ai/openrouter/_prompt.py +272 -0
  176. pyfect/ai/openrouter/_response.py +226 -0
  177. pyfect/ai/openrouter/_stream.py +320 -0
  178. pyfect/ai/openrouter/client.py +283 -0
  179. pyfect/ai/openrouter/config.py +36 -0
  180. pyfect/ai/openrouter/decision_model.py +161 -0
  181. pyfect/ai/openrouter/error.py +23 -0
  182. pyfect/ai/openrouter/generated/__init__.py +3029 -0
  183. pyfect/ai/openrouter/generated/_recursive.py +15 -0
  184. pyfect/ai/openrouter/generated/_schemas_0.py +1015 -0
  185. pyfect/ai/openrouter/generated/_schemas_1.py +522 -0
  186. pyfect/ai/openrouter/generated/client.py +1445 -0
  187. pyfect/ai/openrouter/generated/types.py +4769 -0
  188. pyfect/ai/openrouter/language_model.py +345 -0
  189. pyfect/ai/openrouter/schema.py +165 -0
  190. pyfect/ai/prompt.py +664 -0
  191. pyfect/ai/response.py +768 -0
  192. pyfect/ai/response_id_tracker.py +82 -0
  193. pyfect/ai/telemetry.py +126 -0
  194. pyfect/ai/tokenizer.py +61 -0
  195. pyfect/ai/tool.py +536 -0
  196. pyfect/ai/toolkit.py +490 -0
  197. pyfect/ai/typesafe/__init__.py +17 -0
  198. pyfect/ai/typesafe/_errors.py +120 -0
  199. pyfect/ai/typesafe/client.py +146 -0
  200. pyfect/ai/typesafe/config.py +34 -0
  201. pyfect/ai/typesafe/decision_model.py +90 -0
  202. pyfect/ai/typesafe/schema.py +140 -0
  203. pyfect/batching/__init__.py +58 -0
  204. pyfect/batching/_api.py +71 -0
  205. pyfect/batching/_engine.py +229 -0
  206. pyfect/batching/_from_effect.py +76 -0
  207. pyfect/batching/_persisted.py +98 -0
  208. pyfect/batching/_request.py +133 -0
  209. pyfect/batching/_resolver.py +477 -0
  210. pyfect/batching/_with_cache.py +90 -0
  211. pyfect/big_decimal.py +500 -0
  212. pyfect/brand.py +114 -0
  213. pyfect/byte_size.py +354 -0
  214. pyfect/cache/__init__.py +29 -0
  215. pyfect/cache/_cache.py +426 -0
  216. pyfect/cache/_expiry.py +69 -0
  217. pyfect/cache/_scoped_cache.py +546 -0
  218. pyfect/case.py +174 -0
  219. pyfect/cause.py +462 -0
  220. pyfect/channel/__init__.py +155 -0
  221. pyfect/channel/_base.py +92 -0
  222. pyfect/channel/_catch.py +158 -0
  223. pyfect/channel/_catch_reason.py +572 -0
  224. pyfect/channel/_channel.py +158 -0
  225. pyfect/channel/_combinators.py +220 -0
  226. pyfect/channel/_concurrency_methods.py +217 -0
  227. pyfect/channel/_concurrent_map.py +118 -0
  228. pyfect/channel/_constructors.py +349 -0
  229. pyfect/channel/_context.py +232 -0
  230. pyfect/channel/_error_methods.py +336 -0
  231. pyfect/channel/_errors.py +180 -0
  232. pyfect/channel/_filters.py +225 -0
  233. pyfect/channel/_lifecycle.py +71 -0
  234. pyfect/channel/_lifecycle_methods.py +206 -0
  235. pyfect/channel/_loop.py +100 -0
  236. pyfect/channel/_merge.py +246 -0
  237. pyfect/channel/_repeat.py +154 -0
  238. pyfect/channel/_run.py +149 -0
  239. pyfect/channel/_run_methods.py +341 -0
  240. pyfect/channel/_sinks.py +88 -0
  241. pyfect/channel/_sources.py +238 -0
  242. pyfect/channel/_text.py +176 -0
  243. pyfect/channel/_transform_methods.py +415 -0
  244. pyfect/channel/_upstream.py +67 -0
  245. pyfect/channel_schema.py +131 -0
  246. pyfect/cli/__init__.py +79 -0
  247. pyfect/cli/_ansi.py +82 -0
  248. pyfect/cli/_command.py +469 -0
  249. pyfect/cli/_config.py +164 -0
  250. pyfect/cli/_environment.py +10 -0
  251. pyfect/cli/_help.py +195 -0
  252. pyfect/cli/_lexer.py +81 -0
  253. pyfect/cli/_parser.py +465 -0
  254. pyfect/cli/_settings.py +85 -0
  255. pyfect/cli/_suggest.py +33 -0
  256. pyfect/cli/_width.py +134 -0
  257. pyfect/cli/_wizard.py +317 -0
  258. pyfect/cli/argument.py +212 -0
  259. pyfect/cli/cli_config.py +40 -0
  260. pyfect/cli/cli_error.py +242 -0
  261. pyfect/cli/cli_output.py +305 -0
  262. pyfect/cli/command.py +440 -0
  263. pyfect/cli/completions/__init__.py +50 -0
  264. pyfect/cli/completions/_completer.ps1 +190 -0
  265. pyfect/cli/completions/_descriptor.py +182 -0
  266. pyfect/cli/completions/bash.py +300 -0
  267. pyfect/cli/completions/fish.py +164 -0
  268. pyfect/cli/completions/powershell.py +156 -0
  269. pyfect/cli/completions/zsh.py +189 -0
  270. pyfect/cli/flag.py +246 -0
  271. pyfect/cli/global_flag.py +99 -0
  272. pyfect/cli/help_doc.py +63 -0
  273. pyfect/cli/param.py +789 -0
  274. pyfect/cli/primitive.py +308 -0
  275. pyfect/cli/prompt/__init__.py +75 -0
  276. pyfect/cli/prompt/_auto_complete.py +205 -0
  277. pyfect/cli/prompt/_choices.py +104 -0
  278. pyfect/cli/prompt/_confirm.py +195 -0
  279. pyfect/cli/prompt/_core.py +512 -0
  280. pyfect/cli/prompt/_date.py +173 -0
  281. pyfect/cli/prompt/_date_parts.py +387 -0
  282. pyfect/cli/prompt/_file.py +372 -0
  283. pyfect/cli/prompt/_multi_select.py +204 -0
  284. pyfect/cli/prompt/_number.py +257 -0
  285. pyfect/cli/prompt/_select.py +117 -0
  286. pyfect/cli/prompt/_text.py +239 -0
  287. pyfect/cli/terminal_capabilities.py +118 -0
  288. pyfect/clock.py +150 -0
  289. pyfect/cluster/__init__.py +155 -0
  290. pyfect/cluster/_cluster_abandon.py +36 -0
  291. pyfect/cluster/_cluster_layer.py +122 -0
  292. pyfect/cluster/_entity_activation.py +16 -0
  293. pyfect/cluster/_entity_manager/__init__.py +22 -0
  294. pyfect/cluster/_entity_manager/_activation.py +540 -0
  295. pyfect/cluster/_entity_manager/_core.py +186 -0
  296. pyfect/cluster/_entity_manager/_decode.py +60 -0
  297. pyfect/cluster/_entity_manager/_manager.py +423 -0
  298. pyfect/cluster/_entity_manager/_state.py +113 -0
  299. pyfect/cluster/_entity_reaper.py +94 -0
  300. pyfect/cluster/_hash.py +13 -0
  301. pyfect/cluster/_interruptors.py +88 -0
  302. pyfect/cluster/_resource_map.py +179 -0
  303. pyfect/cluster/_resource_ref.py +266 -0
  304. pyfect/cluster/_shard_lock.py +14 -0
  305. pyfect/cluster/cluster_cron.py +230 -0
  306. pyfect/cluster/cluster_error.py +81 -0
  307. pyfect/cluster/cluster_http.py +210 -0
  308. pyfect/cluster/cluster_metrics.py +54 -0
  309. pyfect/cluster/cluster_schema.py +137 -0
  310. pyfect/cluster/cluster_socket.py +197 -0
  311. pyfect/cluster/cluster_workflow_engine/__init__.py +24 -0
  312. pyfect/cluster/cluster_workflow_engine/_engine.py +1099 -0
  313. pyfect/cluster/cluster_workflow_engine/_entities.py +298 -0
  314. pyfect/cluster/deliver_at.py +31 -0
  315. pyfect/cluster/entity/__init__.py +39 -0
  316. pyfect/cluster/entity/_entity.py +332 -0
  317. pyfect/cluster/entity/_handlers.py +168 -0
  318. pyfect/cluster/entity/_keep_alive.py +74 -0
  319. pyfect/cluster/entity/_queue.py +103 -0
  320. pyfect/cluster/entity/_request.py +34 -0
  321. pyfect/cluster/entity/_services.py +23 -0
  322. pyfect/cluster/entity/_test_client.py +237 -0
  323. pyfect/cluster/entity_address.py +25 -0
  324. pyfect/cluster/entity_id.py +20 -0
  325. pyfect/cluster/entity_proxy.py +161 -0
  326. pyfect/cluster/entity_proxy_server.py +103 -0
  327. pyfect/cluster/entity_resource.py +122 -0
  328. pyfect/cluster/entity_type.py +20 -0
  329. pyfect/cluster/envelope.py +307 -0
  330. pyfect/cluster/http_runner.py +254 -0
  331. pyfect/cluster/k8s_http_client.py +281 -0
  332. pyfect/cluster/k8s_types.py +1394 -0
  333. pyfect/cluster/machine_id.py +21 -0
  334. pyfect/cluster/message.py +219 -0
  335. pyfect/cluster/message_storage/__init__.py +67 -0
  336. pyfect/cluster/message_storage/_encoded.py +393 -0
  337. pyfect/cluster/message_storage/_memory.py +386 -0
  338. pyfect/cluster/message_storage/_noop.py +109 -0
  339. pyfect/cluster/message_storage/_service.py +388 -0
  340. pyfect/cluster/reply.py +236 -0
  341. pyfect/cluster/runner.py +32 -0
  342. pyfect/cluster/runner_address.py +23 -0
  343. pyfect/cluster/runner_health.py +93 -0
  344. pyfect/cluster/runner_server.py +286 -0
  345. pyfect/cluster/runner_storage.py +212 -0
  346. pyfect/cluster/runners/__init__.py +55 -0
  347. pyfect/cluster/runners/_local.py +460 -0
  348. pyfect/cluster/runners/_noop.py +57 -0
  349. pyfect/cluster/runners/_rpc.py +290 -0
  350. pyfect/cluster/runners/_service.py +113 -0
  351. pyfect/cluster/shard_id.py +39 -0
  352. pyfect/cluster/sharding/__init__.py +12 -0
  353. pyfect/cluster/sharding/_acquisition.py +490 -0
  354. pyfect/cluster/sharding/_clients.py +271 -0
  355. pyfect/cluster/sharding/_make.py +388 -0
  356. pyfect/cluster/sharding/_routing.py +296 -0
  357. pyfect/cluster/sharding/_runners_sync.py +198 -0
  358. pyfect/cluster/sharding/_service.py +91 -0
  359. pyfect/cluster/sharding/_singletons.py +183 -0
  360. pyfect/cluster/sharding/_state.py +296 -0
  361. pyfect/cluster/sharding/_storage_loop.py +421 -0
  362. pyfect/cluster/sharding_config.py +230 -0
  363. pyfect/cluster/sharding_registration_event.py +28 -0
  364. pyfect/cluster/single_runner.py +49 -0
  365. pyfect/cluster/singleton.py +36 -0
  366. pyfect/cluster/singleton_address.py +20 -0
  367. pyfect/cluster/snowflake.py +133 -0
  368. pyfect/cluster/socket_runner.py +67 -0
  369. pyfect/cluster/sql_message_storage.py +1001 -0
  370. pyfect/cluster/sql_runner_storage.py +841 -0
  371. pyfect/cluster/test_runner.py +23 -0
  372. pyfect/config/__init__.py +93 -0
  373. pyfect/config/_all.py +96 -0
  374. pyfect/config/_collections.py +291 -0
  375. pyfect/config/_config.py +261 -0
  376. pyfect/config/_constructors.py +106 -0
  377. pyfect/config/_error.py +27 -0
  378. pyfect/config/_leaf.py +92 -0
  379. pyfect/config/_scalars.py +193 -0
  380. pyfect/config/_schema.py +340 -0
  381. pyfect/config_provider/__init__.py +60 -0
  382. pyfect/config_provider/_dir.py +84 -0
  383. pyfect/config_provider/_dotenv.py +127 -0
  384. pyfect/config_provider/_env.py +79 -0
  385. pyfect/config_provider/_layers.py +80 -0
  386. pyfect/config_provider/_node.py +90 -0
  387. pyfect/config_provider/_provider.py +118 -0
  388. pyfect/config_provider/_unknown.py +62 -0
  389. pyfect/console/__init__.py +63 -0
  390. pyfect/console/_effects.py +134 -0
  391. pyfect/console/_live.py +156 -0
  392. pyfect/console/_service.py +49 -0
  393. pyfect/console/_table.py +90 -0
  394. pyfect/context.py +414 -0
  395. pyfect/cron/__init__.py +30 -0
  396. pyfect/cron/_model.py +183 -0
  397. pyfect/cron/_search.py +268 -0
  398. pyfect/cron/_text.py +202 -0
  399. pyfect/cron/_wall.py +42 -0
  400. pyfect/crypto.py +257 -0
  401. pyfect/date_time/__init__.py +77 -0
  402. pyfect/date_time/_calendar.py +209 -0
  403. pyfect/date_time/_current.py +118 -0
  404. pyfect/date_time/_epoch.py +22 -0
  405. pyfect/date_time/_iso.py +80 -0
  406. pyfect/date_time/_zones.py +135 -0
  407. pyfect/date_time/intl.py +144 -0
  408. pyfect/deferred.py +145 -0
  409. pyfect/devtools/__init__.py +24 -0
  410. pyfect/devtools/client.py +323 -0
  411. pyfect/devtools/layers.py +32 -0
  412. pyfect/devtools/schema.py +301 -0
  413. pyfect/devtools/server.py +72 -0
  414. pyfect/duration.py +295 -0
  415. pyfect/effect.py +565 -0
  416. pyfect/effectable.py +37 -0
  417. pyfect/encoding/__init__.py +62 -0
  418. pyfect/encoding/_archive.py +197 -0
  419. pyfect/encoding/_json_array_scanner.py +477 -0
  420. pyfect/encoding/base64.py +23 -0
  421. pyfect/encoding/base64_url.py +19 -0
  422. pyfect/encoding/encoding_error.py +17 -0
  423. pyfect/encoding/hex.py +28 -0
  424. pyfect/encoding/ini.py +188 -0
  425. pyfect/encoding/json_array.py +246 -0
  426. pyfect/encoding/ndjson.py +461 -0
  427. pyfect/encoding/schema_binary/__init__.py +257 -0
  428. pyfect/encoding/schema_binary/_channels.py +173 -0
  429. pyfect/encoding/schema_binary/_compile.py +584 -0
  430. pyfect/encoding/schema_binary/_decode.py +848 -0
  431. pyfect/encoding/schema_binary/_dictionary.py +90 -0
  432. pyfect/encoding/schema_binary/_encode.py +838 -0
  433. pyfect/encoding/schema_binary/_fingerprint.py +168 -0
  434. pyfect/encoding/schema_binary/_layout.py +350 -0
  435. pyfect/encoding/schema_binary/_literals.py +47 -0
  436. pyfect/encoding/schema_binary/_parser.py +163 -0
  437. pyfect/encoding/schema_binary/_reader.py +148 -0
  438. pyfect/encoding/schema_binary/_target.py +310 -0
  439. pyfect/encoding/schema_binary/_values.py +133 -0
  440. pyfect/encoding/schema_binary/_wire.py +253 -0
  441. pyfect/encoding/sse.py +476 -0
  442. pyfect/encoding/tar/__init__.py +396 -0
  443. pyfect/encoding/tar/_decoder.py +220 -0
  444. pyfect/encoding/tar/_encoder.py +83 -0
  445. pyfect/encoding/tar/_header.py +494 -0
  446. pyfect/encoding/tar/_model.py +82 -0
  447. pyfect/encoding/toml.py +375 -0
  448. pyfect/encoding/xml/__init__.py +222 -0
  449. pyfect/encoding/xml/_chars.py +119 -0
  450. pyfect/encoding/xml/_collector.py +106 -0
  451. pyfect/encoding/xml/_inputs.py +126 -0
  452. pyfect/encoding/xml/_model.py +114 -0
  453. pyfect/encoding/xml/_parser.py +694 -0
  454. pyfect/encoding/xml/_scanner.py +180 -0
  455. pyfect/encoding/xml/_writer.py +238 -0
  456. pyfect/encoding/yaml.py +739 -0
  457. pyfect/encoding/zip/__init__.py +392 -0
  458. pyfect/encoding/zip/_decoder.py +378 -0
  459. pyfect/encoding/zip/_format.py +122 -0
  460. pyfect/encoding/zip/_inflate.py +65 -0
  461. pyfect/encoding/zip/_model.py +86 -0
  462. pyfect/encoding/zip/_writer.py +311 -0
  463. pyfect/error_reporter.py +240 -0
  464. pyfect/errors.py +321 -0
  465. pyfect/eventlog/__init__.py +77 -0
  466. pyfect/eventlog/_conflicts.py +94 -0
  467. pyfect/eventlog/_crypto.py +64 -0
  468. pyfect/eventlog/_identity.py +26 -0
  469. pyfect/eventlog/_identity_derivation.py +79 -0
  470. pyfect/eventlog/_transferable_bytes.py +55 -0
  471. pyfect/eventlog/_uuid.py +33 -0
  472. pyfect/eventlog/event.py +115 -0
  473. pyfect/eventlog/event_group.py +55 -0
  474. pyfect/eventlog/event_journal.py +630 -0
  475. pyfect/eventlog/event_log.py +1039 -0
  476. pyfect/eventlog/event_log_encryption.py +219 -0
  477. pyfect/eventlog/event_log_message.py +357 -0
  478. pyfect/eventlog/event_log_remote.py +465 -0
  479. pyfect/eventlog/event_log_server.py +442 -0
  480. pyfect/eventlog/event_log_server_encrypted.py +322 -0
  481. pyfect/eventlog/event_log_server_unencrypted.py +814 -0
  482. pyfect/eventlog/event_log_session_auth.py +250 -0
  483. pyfect/eventlog/event_row.py +423 -0
  484. pyfect/eventlog/sql_event_journal.py +692 -0
  485. pyfect/eventlog/sql_event_log_server_encrypted.py +440 -0
  486. pyfect/eventlog/sql_event_log_server_unencrypted.py +568 -0
  487. pyfect/execution_plan/__init__.py +42 -0
  488. pyfect/execution_plan/_events.py +128 -0
  489. pyfect/execution_plan/_model.py +108 -0
  490. pyfect/execution_plan/_run.py +176 -0
  491. pyfect/exit.py +205 -0
  492. pyfect/fiber_handle.py +305 -0
  493. pyfect/fiber_map.py +350 -0
  494. pyfect/fiber_set.py +232 -0
  495. pyfect/file_system/__init__.py +69 -0
  496. pyfect/file_system/_copy.py +116 -0
  497. pyfect/file_system/_errors.py +32 -0
  498. pyfect/file_system/_file.py +177 -0
  499. pyfect/file_system/_live.py +351 -0
  500. pyfect/file_system/_model.py +72 -0
  501. pyfect/file_system/_noop.py +189 -0
  502. pyfect/file_system/_service.py +336 -0
  503. pyfect/file_system/_stat.py +69 -0
  504. pyfect/file_system/_watch.py +107 -0
  505. pyfect/filters.py +245 -0
  506. pyfect/graph/__init__.py +101 -0
  507. pyfect/graph/_all_pairs.py +150 -0
  508. pyfect/graph/_combine.py +259 -0
  509. pyfect/graph/_compact.py +143 -0
  510. pyfect/graph/_components.py +200 -0
  511. pyfect/graph/_cycles.py +144 -0
  512. pyfect/graph/_enumerate.py +168 -0
  513. pyfect/graph/_errors.py +51 -0
  514. pyfect/graph/_flow.py +164 -0
  515. pyfect/graph/_forest.py +109 -0
  516. pyfect/graph/_graph.py +269 -0
  517. pyfect/graph/_lowlink.py +98 -0
  518. pyfect/graph/_matching.py +101 -0
  519. pyfect/graph/_mutate.py +211 -0
  520. pyfect/graph/_query.py +138 -0
  521. pyfect/graph/_records.py +119 -0
  522. pyfect/graph/_render.py +109 -0
  523. pyfect/graph/_shortest.py +274 -0
  524. pyfect/graph/_snapshot.py +50 -0
  525. pyfect/graph/_store.py +136 -0
  526. pyfect/graph/_traverse.py +289 -0
  527. pyfect/graph/_view.py +384 -0
  528. pyfect/graph/_walker.py +70 -0
  529. pyfect/graphql/__init__.py +87 -0
  530. pyfect/graphql/_codec.py +117 -0
  531. pyfect/graphql/_http.py +309 -0
  532. pyfect/graphql/_schemas.py +39 -0
  533. pyfect/graphql/_slices.py +110 -0
  534. pyfect/graphql/_template.py +111 -0
  535. pyfect/graphql/_types.py +115 -0
  536. pyfect/graphql/_ws.py +395 -0
  537. pyfect/graphql/_ws_messages.py +120 -0
  538. pyfect/graphql/client.py +428 -0
  539. pyfect/graphql/client_error.py +285 -0
  540. pyfect/graphql/group.py +142 -0
  541. pyfect/graphql/middleware.py +98 -0
  542. pyfect/graphql/operation.py +409 -0
  543. pyfect/graphql/protocol.py +119 -0
  544. pyfect/graphql/resolver.py +574 -0
  545. pyfect/graphql/template.py +61 -0
  546. pyfect/hash_map.py +317 -0
  547. pyfect/hash_ring.py +206 -0
  548. pyfect/hash_set.py +163 -0
  549. pyfect/http/__init__.py +125 -0
  550. pyfect/http/_asgi_listener.py +272 -0
  551. pyfect/http/_authority.py +63 -0
  552. pyfect/http/_brotli.py +27 -0
  553. pyfect/http/_compression.py +52 -0
  554. pyfect/http/_field.py +18 -0
  555. pyfect/http/_foreign_path.py +27 -0
  556. pyfect/http/_form_data.py +34 -0
  557. pyfect/http/_httpx_options.py +120 -0
  558. pyfect/http/_in_memory.py +76 -0
  559. pyfect/http/_request_state.py +59 -0
  560. pyfect/http/_vary.py +14 -0
  561. pyfect/http/abort.py +65 -0
  562. pyfect/http/asgi/__init__.py +59 -0
  563. pyfect/http/asgi/_app.py +155 -0
  564. pyfect/http/asgi/_http.py +201 -0
  565. pyfect/http/asgi/_mount.py +263 -0
  566. pyfect/http/asgi/_scope.py +86 -0
  567. pyfect/http/asgi/_serve.py +72 -0
  568. pyfect/http/asgi/_types.py +13 -0
  569. pyfect/http/asgi/_web_socket.py +325 -0
  570. pyfect/http/body.py +437 -0
  571. pyfect/http/client/__init__.py +111 -0
  572. pyfect/http/client/_circuit_breaker.py +113 -0
  573. pyfect/http/client/_cookie_jar.py +120 -0
  574. pyfect/http/client/_make.py +252 -0
  575. pyfect/http/client/_rate_limit.py +423 -0
  576. pyfect/http/client/_redirects.py +93 -0
  577. pyfect/http/client/_retry.py +115 -0
  578. pyfect/http/client/_service.py +497 -0
  579. pyfect/http/cookies.py +444 -0
  580. pyfect/http/error.py +188 -0
  581. pyfect/http/etag.py +96 -0
  582. pyfect/http/file_like.py +49 -0
  583. pyfect/http/find_my_way/__init__.py +10 -0
  584. pyfect/http/find_my_way/_nodes.py +186 -0
  585. pyfect/http/find_my_way/_paths.py +43 -0
  586. pyfect/http/find_my_way/_query_string.py +67 -0
  587. pyfect/http/find_my_way/_router.py +401 -0
  588. pyfect/http/headers.py +343 -0
  589. pyfect/http/http_effect.py +198 -0
  590. pyfect/http/httpx_client.py +291 -0
  591. pyfect/http/hypercorn_server.py +122 -0
  592. pyfect/http/incoming_message.py +140 -0
  593. pyfect/http/live_server/__init__.py +191 -0
  594. pyfect/http/live_server/_body.py +164 -0
  595. pyfect/http/live_server/_exchange.py +321 -0
  596. pyfect/http/live_server/_head.py +194 -0
  597. pyfect/http/live_server/_inbound.py +156 -0
  598. pyfect/http/live_server/_listener.py +211 -0
  599. pyfect/http/live_server/_serve.py +225 -0
  600. pyfect/http/live_server/_timers.py +20 -0
  601. pyfect/http/live_server/_upgrade.py +108 -0
  602. pyfect/http/live_server/_websocket.py +286 -0
  603. pyfect/http/live_server/_ws_frames.py +242 -0
  604. pyfect/http/method.py +30 -0
  605. pyfect/http/middleware/__init__.py +61 -0
  606. pyfect/http/middleware/_compression.py +156 -0
  607. pyfect/http/middleware/_cors.py +129 -0
  608. pyfect/http/middleware/_decompression.py +274 -0
  609. pyfect/http/middleware/_forwarded.py +113 -0
  610. pyfect/http/middleware/_logger.py +73 -0
  611. pyfect/http/middleware/_search_params.py +34 -0
  612. pyfect/http/middleware/_tracer.py +153 -0
  613. pyfect/http/middleware/_types.py +16 -0
  614. pyfect/http/mime/__init__.py +69 -0
  615. pyfect/http/mime/_types.py +361 -0
  616. pyfect/http/multipart.py +613 -0
  617. pyfect/http/multipart_parser/__init__.py +348 -0
  618. pyfect/http/multipart_parser/_content_type.py +109 -0
  619. pyfect/http/multipart_parser/_headers.py +206 -0
  620. pyfect/http/multipart_parser/_search.py +85 -0
  621. pyfect/http/origin.py +146 -0
  622. pyfect/http/platform.py +593 -0
  623. pyfect/http/prometheus.py +34 -0
  624. pyfect/http/request.py +384 -0
  625. pyfect/http/response.py +474 -0
  626. pyfect/http/router/__init__.py +82 -0
  627. pyfect/http/router/_api.py +462 -0
  628. pyfect/http/router/_in_memory.py +76 -0
  629. pyfect/http/router/_markers.py +47 -0
  630. pyfect/http/router/_middleware.py +181 -0
  631. pyfect/http/router/_middleware_stack.py +51 -0
  632. pyfect/http/router/_provided.py +31 -0
  633. pyfect/http/router/_route.py +114 -0
  634. pyfect/http/router/_router.py +308 -0
  635. pyfect/http/schema.py +276 -0
  636. pyfect/http/server.py +199 -0
  637. pyfect/http/server_error.py +261 -0
  638. pyfect/http/server_request.py +729 -0
  639. pyfect/http/server_respondable.py +77 -0
  640. pyfect/http/server_response.py +569 -0
  641. pyfect/http/static_server/__init__.py +257 -0
  642. pyfect/http/static_server/_conditional.py +72 -0
  643. pyfect/http/static_server/_mime.py +55 -0
  644. pyfect/http/static_server/_range.py +53 -0
  645. pyfect/http/status.py +51 -0
  646. pyfect/http/template.py +161 -0
  647. pyfect/http/trace_context.py +91 -0
  648. pyfect/http/url.py +442 -0
  649. pyfect/http/url_params.py +304 -0
  650. pyfect/http/uvicorn_server.py +119 -0
  651. pyfect/http/web.py +171 -0
  652. pyfect/http/web_handler.py +463 -0
  653. pyfect/http/wire.py +209 -0
  654. pyfect/http_api/__init__.py +83 -0
  655. pyfect/http_api/_assets/scalar.js +8 -0
  656. pyfect/http_api/_assets/swagger-ui.css +3 -0
  657. pyfect/http_api/_assets/swagger-ui.js +4 -0
  658. pyfect/http_api/_client_method.py +220 -0
  659. pyfect/http_api/_client_payload.py +144 -0
  660. pyfect/http_api/_client_response.py +377 -0
  661. pyfect/http_api/_handlers.py +282 -0
  662. pyfect/http_api/_html.py +38 -0
  663. pyfect/http_api/_media_type.py +6 -0
  664. pyfect/http_api/_openapi_responses.py +164 -0
  665. pyfect/http_api/_openapi_schemas.py +163 -0
  666. pyfect/http_api/_path.py +102 -0
  667. pyfect/http_api/_payload.py +260 -0
  668. pyfect/http_api/_response.py +363 -0
  669. pyfect/http_api/_security.py +174 -0
  670. pyfect/http_api/api.py +265 -0
  671. pyfect/http_api/builder.py +447 -0
  672. pyfect/http_api/client.py +474 -0
  673. pyfect/http_api/endpoint.py +969 -0
  674. pyfect/http_api/error.py +280 -0
  675. pyfect/http_api/group.py +215 -0
  676. pyfect/http_api/middleware.py +232 -0
  677. pyfect/http_api/openapi.py +396 -0
  678. pyfect/http_api/scalar.py +143 -0
  679. pyfect/http_api/schema.py +713 -0
  680. pyfect/http_api/security.py +91 -0
  681. pyfect/http_api/swagger.py +69 -0
  682. pyfect/http_api/test.py +105 -0
  683. pyfect/json_patch.py +255 -0
  684. pyfect/json_pointer.py +100 -0
  685. pyfect/json_schema/__init__.py +66 -0
  686. pyfect/json_schema/_api.py +96 -0
  687. pyfect/json_schema/_converter.py +258 -0
  688. pyfect/json_schema/_draft04.py +198 -0
  689. pyfect/json_schema/_draft07.py +203 -0
  690. pyfect/json_schema/_keywords.py +202 -0
  691. pyfect/json_schema/_model.py +201 -0
  692. pyfect/json_schema/_openapi.py +208 -0
  693. pyfect/latch.py +127 -0
  694. pyfect/layer.py +479 -0
  695. pyfect/layer_map.py +279 -0
  696. pyfect/layer_ref.py +208 -0
  697. pyfect/logger/__init__.py +91 -0
  698. pyfect/logger/_batched.py +49 -0
  699. pyfect/logger/_console.py +116 -0
  700. pyfect/logger/_file.py +31 -0
  701. pyfect/logger/_formats.py +104 -0
  702. pyfect/logger/_layer.py +50 -0
  703. pyfect/logger/_level.py +53 -0
  704. pyfect/logger/_log.py +142 -0
  705. pyfect/logger/_model.py +163 -0
  706. pyfect/logger/_refs.py +78 -0
  707. pyfect/logger/_stdlib.py +54 -0
  708. pyfect/logger/_text.py +263 -0
  709. pyfect/logger/_tracer.py +35 -0
  710. pyfect/managed_runtime.py +393 -0
  711. pyfect/metric/__init__.py +119 -0
  712. pyfect/metric/_boundaries.py +27 -0
  713. pyfect/metric/_kinds.py +417 -0
  714. pyfect/metric/_metric.py +302 -0
  715. pyfect/metric/_prometheus.py +150 -0
  716. pyfect/metric/_refs.py +78 -0
  717. pyfect/metric/_runtime.py +75 -0
  718. pyfect/metric/_snapshot.py +97 -0
  719. pyfect/metric/_state.py +74 -0
  720. pyfect/msgspec.py +98 -0
  721. pyfect/mutable_hash_map.py +140 -0
  722. pyfect/mutable_hash_set.py +95 -0
  723. pyfect/net/__init__.py +18 -0
  724. pyfect/net/_errors.py +29 -0
  725. pyfect/net/address_resolver.py +179 -0
  726. pyfect/net/dns/__init__.py +92 -0
  727. pyfect/net/dns/_error.py +43 -0
  728. pyfect/net/dns/_records.py +335 -0
  729. pyfect/net/dns/_service.py +287 -0
  730. pyfect/net/dns/_system.py +89 -0
  731. pyfect/net/host.py +311 -0
  732. pyfect/net/ip_interface.py +202 -0
  733. pyfect/net/ip_network.py +250 -0
  734. pyfect/net/net_address/__init__.py +245 -0
  735. pyfect/net/net_address/_inet.py +412 -0
  736. pyfect/net/net_address/_ip.py +348 -0
  737. pyfect/net/net_address/_mac.py +119 -0
  738. pyfect/optic/__init__.py +50 -0
  739. pyfect/optic/_builtins.py +90 -0
  740. pyfect/optic/_data.py +97 -0
  741. pyfect/optic/_optic.py +422 -0
  742. pyfect/optic/_steps.py +151 -0
  743. pyfect/option.py +362 -0
  744. pyfect/otel/__init__.py +22 -0
  745. pyfect/otel/_attributes.py +67 -0
  746. pyfect/otel/_producer.py +322 -0
  747. pyfect/otel/_shutdown.py +26 -0
  748. pyfect/otel/_span.py +292 -0
  749. pyfect/otel/_wrapper.py +92 -0
  750. pyfect/otel/logger.py +154 -0
  751. pyfect/otel/metrics.py +126 -0
  752. pyfect/otel/resource.py +111 -0
  753. pyfect/otel/sdk.py +195 -0
  754. pyfect/otel/tracer.py +157 -0
  755. pyfect/partitioned_semaphore.py +211 -0
  756. pyfect/path.py +304 -0
  757. pyfect/persistence/__init__.py +77 -0
  758. pyfect/persistence/_columns.py +32 -0
  759. pyfect/persistence/_error.py +14 -0
  760. pyfect/persistence/_seconds.py +68 -0
  761. pyfect/persistence/_sql_keys.py +47 -0
  762. pyfect/persistence/circuit_breaker/__init__.py +120 -0
  763. pyfect/persistence/circuit_breaker/_breaker.py +317 -0
  764. pyfect/persistence/circuit_breaker/_errors.py +67 -0
  765. pyfect/persistence/circuit_breaker/_memory.py +243 -0
  766. pyfect/persistence/circuit_breaker/_redis.py +509 -0
  767. pyfect/persistence/circuit_breaker/_store.py +60 -0
  768. pyfect/persistence/circuit_breaker/_types.py +191 -0
  769. pyfect/persistence/key_value_store/__init__.py +51 -0
  770. pyfect/persistence/key_value_store/_layers.py +216 -0
  771. pyfect/persistence/key_value_store/_schema_store.py +91 -0
  772. pyfect/persistence/key_value_store/_sql.py +197 -0
  773. pyfect/persistence/key_value_store/_store.py +212 -0
  774. pyfect/persistence/persistable.py +164 -0
  775. pyfect/persistence/persisted_cache.py +159 -0
  776. pyfect/persistence/persisted_queue/__init__.py +75 -0
  777. pyfect/persistence/persisted_queue/_error.py +42 -0
  778. pyfect/persistence/persisted_queue/_mailbox.py +101 -0
  779. pyfect/persistence/persisted_queue/_memory.py +182 -0
  780. pyfect/persistence/persisted_queue/_queue.py +272 -0
  781. pyfect/persistence/persisted_queue/_redis.py +455 -0
  782. pyfect/persistence/persisted_queue/_redis_scripts.py +395 -0
  783. pyfect/persistence/persisted_queue/_sql.py +334 -0
  784. pyfect/persistence/persisted_queue/_sql_migrations.py +319 -0
  785. pyfect/persistence/persisted_queue/_sql_statements.py +441 -0
  786. pyfect/persistence/persisted_queue/_store.py +147 -0
  787. pyfect/persistence/persistence/__init__.py +84 -0
  788. pyfect/persistence/persistence/_kvs.py +135 -0
  789. pyfect/persistence/persistence/_memory.py +62 -0
  790. pyfect/persistence/persistence/_redis.py +162 -0
  791. pyfect/persistence/persistence/_service.py +276 -0
  792. pyfect/persistence/persistence/_sql.py +499 -0
  793. pyfect/persistence/rate_limiter/__init__.py +82 -0
  794. pyfect/persistence/rate_limiter/_errors.py +59 -0
  795. pyfect/persistence/rate_limiter/_limiter.py +325 -0
  796. pyfect/persistence/rate_limiter/_memory.py +217 -0
  797. pyfect/persistence/rate_limiter/_redis.py +485 -0
  798. pyfect/persistence/rate_limiter/_store.py +89 -0
  799. pyfect/persistence/redis/__init__.py +52 -0
  800. pyfect/persistence/redis/_error.py +12 -0
  801. pyfect/persistence/redis/_make.py +234 -0
  802. pyfect/persistence/redis/_script.py +78 -0
  803. pyfect/persistence/redis/_service.py +104 -0
  804. pyfect/persistence/redis_py.py +303 -0
  805. pyfect/persistence/user_directories.py +195 -0
  806. pyfect/platform.py +26 -0
  807. pyfect/platform_error.py +256 -0
  808. pyfect/pool/__init__.py +36 -0
  809. pyfect/pool/_pool.py +707 -0
  810. pyfect/pool/_state.py +161 -0
  811. pyfect/pool/_ttl.py +105 -0
  812. pyfect/pool/_waiters.py +116 -0
  813. pyfect/primary_key.py +35 -0
  814. pyfect/process/__init__.py +82 -0
  815. pyfect/process/_child.py +213 -0
  816. pyfect/process/_command.py +358 -0
  817. pyfect/process/_handle.py +77 -0
  818. pyfect/process/_live.py +455 -0
  819. pyfect/process/_os.py +78 -0
  820. pyfect/process/_pipes.py +291 -0
  821. pyfect/process/_spawner.py +75 -0
  822. pyfect/pubsub/__init__.py +33 -0
  823. pyfect/pubsub/_atomic.py +181 -0
  824. pyfect/pubsub/_hub.py +214 -0
  825. pyfect/pubsub/_pubsub.py +214 -0
  826. pyfect/pubsub/_replay.py +107 -0
  827. pyfect/pubsub/_subscription.py +226 -0
  828. pyfect/pull.py +132 -0
  829. pyfect/py.typed +0 -0
  830. pyfect/pydantic.py +188 -0
  831. pyfect/queue/__init__.py +33 -0
  832. pyfect/queue/_queue.py +525 -0
  833. pyfect/queue/_state.py +111 -0
  834. pyfect/queue/_views.py +55 -0
  835. pyfect/random.py +146 -0
  836. pyfect/rc_map.py +363 -0
  837. pyfect/rc_ref.py +271 -0
  838. pyfect/reactivity/__init__.py +53 -0
  839. pyfect/reactivity/_async_result_schema.py +227 -0
  840. pyfect/reactivity/_hydration.py +18 -0
  841. pyfect/reactivity/_live.py +21 -0
  842. pyfect/reactivity/_reactivity.py +256 -0
  843. pyfect/reactivity/_result_effect.py +17 -0
  844. pyfect/reactivity/_time.py +11 -0
  845. pyfect/reactivity/async_result.py +679 -0
  846. pyfect/reactivity/atom/__init__.py +143 -0
  847. pyfect/reactivity/atom/_combinators.py +223 -0
  848. pyfect/reactivity/atom/_constructors.py +80 -0
  849. pyfect/reactivity/atom/_conversions.py +79 -0
  850. pyfect/reactivity/atom/_effect.py +252 -0
  851. pyfect/reactivity/atom/_fn.py +341 -0
  852. pyfect/reactivity/atom/_kvs.py +101 -0
  853. pyfect/reactivity/atom/_optimistic.py +162 -0
  854. pyfect/reactivity/atom/_runtime.py +323 -0
  855. pyfect/reactivity/atom/_serializable.py +65 -0
  856. pyfect/reactivity/atom/_subscription_ref.py +102 -0
  857. pyfect/reactivity/atom/_swr.py +69 -0
  858. pyfect/reactivity/atom/_types.py +435 -0
  859. pyfect/reactivity/atom_http_api.py +667 -0
  860. pyfect/reactivity/atom_ref.py +260 -0
  861. pyfect/reactivity/atom_registry/__init__.py +219 -0
  862. pyfect/reactivity/atom_registry/_batch.py +96 -0
  863. pyfect/reactivity/atom_registry/_dispatcher.py +60 -0
  864. pyfect/reactivity/atom_registry/_lifetime.py +202 -0
  865. pyfect/reactivity/atom_registry/_node.py +423 -0
  866. pyfect/reactivity/atom_registry/_registry.py +380 -0
  867. pyfect/reactivity/atom_rpc.py +283 -0
  868. pyfect/reactivity/hydration.py +200 -0
  869. pyfect/redacted.py +83 -0
  870. pyfect/ref.py +129 -0
  871. pyfect/resource.py +98 -0
  872. pyfect/result.py +306 -0
  873. pyfect/rpc/__init__.py +64 -0
  874. pyfect/rpc/_encoded_schema.py +86 -0
  875. pyfect/rpc/_json_rpc.py +246 -0
  876. pyfect/rpc/_methods.py +177 -0
  877. pyfect/rpc/_rpc.py +498 -0
  878. pyfect/rpc/client/__init__.py +100 -0
  879. pyfect/rpc/client/_core.py +449 -0
  880. pyfect/rpc/client/_http.py +257 -0
  881. pyfect/rpc/client/_protocol.py +171 -0
  882. pyfect/rpc/client/_serialized.py +321 -0
  883. pyfect/rpc/client/_transports.py +328 -0
  884. pyfect/rpc/client/_worker.py +283 -0
  885. pyfect/rpc/client_error.py +35 -0
  886. pyfect/rpc/group.py +296 -0
  887. pyfect/rpc/message.py +299 -0
  888. pyfect/rpc/middleware.py +182 -0
  889. pyfect/rpc/schema.py +89 -0
  890. pyfect/rpc/serialization.py +366 -0
  891. pyfect/rpc/server/__init__.py +181 -0
  892. pyfect/rpc/server/_core.py +549 -0
  893. pyfect/rpc/server/_protocol.py +123 -0
  894. pyfect/rpc/server/_serialized.py +363 -0
  895. pyfect/rpc/server/_stdio.py +101 -0
  896. pyfect/rpc/server/_transports.py +427 -0
  897. pyfect/rpc/server/_worker.py +108 -0
  898. pyfect/rpc/test.py +74 -0
  899. pyfect/rpc/worker.py +92 -0
  900. pyfect/run.py +393 -0
  901. pyfect/schedule/__init__.py +91 -0
  902. pyfect/schedule/_combinators.py +168 -0
  903. pyfect/schedule/_constructors.py +223 -0
  904. pyfect/schedule/_cron.py +49 -0
  905. pyfect/schedule/_drive.py +191 -0
  906. pyfect/schedule/_model.py +405 -0
  907. pyfect/scheduler.py +575 -0
  908. pyfect/schema/__init__.py +866 -0
  909. pyfect/schema/_adapters.py +39 -0
  910. pyfect/schema/_arbitrary_constraint.py +242 -0
  911. pyfect/schema/_arbitrary_graph.py +325 -0
  912. pyfect/schema/_arbitrary_links.py +179 -0
  913. pyfect/schema/_arbitrary_number.py +112 -0
  914. pyfect/schema/_arrays.py +287 -0
  915. pyfect/schema/_assignable.py +118 -0
  916. pyfect/schema/_boolean_literals.py +31 -0
  917. pyfect/schema/_checks_number.py +216 -0
  918. pyfect/schema/_checks_order.py +140 -0
  919. pyfect/schema/_checks_size.py +277 -0
  920. pyfect/schema/_checks_string.py +241 -0
  921. pyfect/schema/_class.py +569 -0
  922. pyfect/schema/_codec_derivation.py +227 -0
  923. pyfect/schema/_codec_links.py +221 -0
  924. pyfect/schema/_codecs.py +316 -0
  925. pyfect/schema/_collections.py +172 -0
  926. pyfect/schema/_constructor_default.py +89 -0
  927. pyfect/schema/_data.py +440 -0
  928. pyfect/schema/_data_codecs.py +145 -0
  929. pyfect/schema/_decimal_regexp.py +243 -0
  930. pyfect/schema/_declare.py +68 -0
  931. pyfect/schema/_derive.py +292 -0
  932. pyfect/schema/_duration_codecs.py +27 -0
  933. pyfect/schema/_ecma_pattern.py +416 -0
  934. pyfect/schema/_error.py +26 -0
  935. pyfect/schema/_error_instance.py +222 -0
  936. pyfect/schema/_graph.py +271 -0
  937. pyfect/schema/_instances.py +240 -0
  938. pyfect/schema/_jsonschema/__init__.py +90 -0
  939. pyfect/schema/_jsonschema/_annotations.py +114 -0
  940. pyfect/schema/_jsonschema/_checks.py +253 -0
  941. pyfect/schema/_jsonschema/_compile.py +346 -0
  942. pyfect/schema/_jsonschema/_exact.py +19 -0
  943. pyfect/schema/_jsonschema/_merge.py +211 -0
  944. pyfect/schema/_jsonschema/_objects.py +231 -0
  945. pyfect/schema/_jsonschema/_references.py +221 -0
  946. pyfect/schema/_jsonschema/_template.py +69 -0
  947. pyfect/schema/_literals.py +147 -0
  948. pyfect/schema/_middleware.py +209 -0
  949. pyfect/schema/_net.py +522 -0
  950. pyfect/schema/_options.py +49 -0
  951. pyfect/schema/_parse.py +351 -0
  952. pyfect/schema/_parsed_text.py +37 -0
  953. pyfect/schema/_primitives.py +48 -0
  954. pyfect/schema/_record.py +41 -0
  955. pyfect/schema/_refine.py +81 -0
  956. pyfect/schema/_schema.py +158 -0
  957. pyfect/schema/_semver.py +144 -0
  958. pyfect/schema/_strategy/__init__.py +258 -0
  959. pyfect/schema/_strategy/_big_decimal.py +203 -0
  960. pyfect/schema/_strategy/_composites.py +119 -0
  961. pyfect/schema/_strategy/_leaves.py +94 -0
  962. pyfect/schema/_strategy/_net.py +133 -0
  963. pyfect/schema/_struct.py +87 -0
  964. pyfect/schema/_struct_keys.py +128 -0
  965. pyfect/schema/_tagged.py +254 -0
  966. pyfect/schema/_template_literal.py +172 -0
  967. pyfect/schema/_to_codec_array_from_single.py +115 -0
  968. pyfect/schema/_to_codec_go_json.py +174 -0
  969. pyfect/schema/_to_codec_json.py +73 -0
  970. pyfect/schema/_to_codec_string_tree.py +115 -0
  971. pyfect/schema/_to_differ_json_patch.py +44 -0
  972. pyfect/schema/_to_encoder_xml.py +119 -0
  973. pyfect/schema/_to_equivalence.py +186 -0
  974. pyfect/schema/_to_formatter.py +180 -0
  975. pyfect/schema/_to_iso.py +73 -0
  976. pyfect/schema/_to_strategy.py +31 -0
  977. pyfect/schema/_transform.py +210 -0
  978. pyfect/schema/_tree.py +27 -0
  979. pyfect/schema/_type_walk.py +53 -0
  980. pyfect/schema/_undefined.py +58 -0
  981. pyfect/schema/_value_codecs.py +84 -0
  982. pyfect/schema/_values.py +123 -0
  983. pyfect/schema/_void.py +86 -0
  984. pyfect/schema/ast/__init__.py +227 -0
  985. pyfect/schema/ast/_annotations.py +43 -0
  986. pyfect/schema/ast/_arrays.py +210 -0
  987. pyfect/schema/ast/_base.py +295 -0
  988. pyfect/schema/ast/_candidates.py +309 -0
  989. pyfect/schema/ast/_check.py +181 -0
  990. pyfect/schema/ast/_class.py +159 -0
  991. pyfect/schema/ast/_constructors.py +65 -0
  992. pyfect/schema/ast/_declaration.py +97 -0
  993. pyfect/schema/ast/_encoding.py +111 -0
  994. pyfect/schema/ast/_json.py +129 -0
  995. pyfect/schema/ast/_keywords.py +125 -0
  996. pyfect/schema/ast/_literal.py +157 -0
  997. pyfect/schema/ast/_objects.py +356 -0
  998. pyfect/schema/ast/_record.py +36 -0
  999. pyfect/schema/ast/_result.py +116 -0
  1000. pyfect/schema/ast/_steps.py +209 -0
  1001. pyfect/schema/ast/_suspend.py +65 -0
  1002. pyfect/schema/ast/_template_literal.py +256 -0
  1003. pyfect/schema/ast/_union.py +172 -0
  1004. pyfect/schema/getter/__init__.py +136 -0
  1005. pyfect/schema/getter/_binary.py +104 -0
  1006. pyfect/schema/getter/_coerce.py +196 -0
  1007. pyfect/schema/getter/_getter.py +243 -0
  1008. pyfect/schema/getter/_make.py +151 -0
  1009. pyfect/schema/getter/_text.py +141 -0
  1010. pyfect/schema/getter/_tree_record.py +170 -0
  1011. pyfect/schema/issue.py +420 -0
  1012. pyfect/schema/model/__init__.py +120 -0
  1013. pyfect/schema/model/_class.py +245 -0
  1014. pyfect/schema/model/_dates.py +103 -0
  1015. pyfect/schema/model/_fields.py +77 -0
  1016. pyfect/schema/model/_toolkit.py +114 -0
  1017. pyfect/schema/model/_uuid.py +69 -0
  1018. pyfect/schema/representation/__init__.py +424 -0
  1019. pyfect/schema/representation/_builtin_revivers.py +331 -0
  1020. pyfect/schema/representation/_code.py +106 -0
  1021. pyfect/schema/representation/_code_builtins.py +281 -0
  1022. pyfect/schema/representation/_code_document.py +563 -0
  1023. pyfect/schema/representation/_code_sort.py +111 -0
  1024. pyfect/schema/representation/_from.py +278 -0
  1025. pyfect/schema/representation/_import/__init__.py +78 -0
  1026. pyfect/schema/representation/_import/_finalize.py +121 -0
  1027. pyfect/schema/representation/_import/_intersect.py +467 -0
  1028. pyfect/schema/representation/_import/_js_order.py +66 -0
  1029. pyfect/schema/representation/_import/_keywords.py +224 -0
  1030. pyfect/schema/representation/_import/_nodes.py +199 -0
  1031. pyfect/schema/representation/_import/_translate.py +455 -0
  1032. pyfect/schema/representation/_json.py +520 -0
  1033. pyfect/schema/representation/_json_schema.py +178 -0
  1034. pyfect/schema/representation/_model.py +284 -0
  1035. pyfect/schema/representation/_revivers.py +89 -0
  1036. pyfect/schema/representation/_to.py +249 -0
  1037. pyfect/schema/transformation/__init__.py +99 -0
  1038. pyfect/schema/transformation/_builtins.py +314 -0
  1039. pyfect/schema/transformation/_durations.py +150 -0
  1040. pyfect/schema/transformation/_transformation.py +177 -0
  1041. pyfect/schema/variant_schema/__init__.py +69 -0
  1042. pyfect/schema/variant_schema/_class.py +188 -0
  1043. pyfect/schema/variant_schema/_defaults.py +30 -0
  1044. pyfect/schema/variant_schema/_field.py +32 -0
  1045. pyfect/schema/variant_schema/_struct.py +130 -0
  1046. pyfect/schema/variant_schema/_toolkit.py +160 -0
  1047. pyfect/scope.py +374 -0
  1048. pyfect/scoped_ref.py +124 -0
  1049. pyfect/semaphore.py +276 -0
  1050. pyfect/semver.py +403 -0
  1051. pyfect/semver_range.py +420 -0
  1052. pyfect/sink/__init__.py +131 -0
  1053. pyfect/sink/_combinators.py +151 -0
  1054. pyfect/sink/_constructors.py +187 -0
  1055. pyfect/sink/_context.py +87 -0
  1056. pyfect/sink/_folds.py +336 -0
  1057. pyfect/sink/_for_each.py +87 -0
  1058. pyfect/sink/_sink.py +265 -0
  1059. pyfect/sink/_steps.py +34 -0
  1060. pyfect/sink/_taking.py +183 -0
  1061. pyfect/socket/__init__.py +146 -0
  1062. pyfect/socket/_accepted.py +65 -0
  1063. pyfect/socket/_connection.py +384 -0
  1064. pyfect/socket/_errors.py +135 -0
  1065. pyfect/socket/_loop.py +66 -0
  1066. pyfect/socket/_net.py +281 -0
  1067. pyfect/socket/_socket.py +245 -0
  1068. pyfect/socket/_tls.py +88 -0
  1069. pyfect/socket/_tls_session.py +117 -0
  1070. pyfect/socket/_web_socket.py +555 -0
  1071. pyfect/socket/datagram/__init__.py +110 -0
  1072. pyfect/socket/datagram/_core.py +460 -0
  1073. pyfect/socket/datagram/_errors.py +102 -0
  1074. pyfect/socket/datagram/_live.py +675 -0
  1075. pyfect/socket/datagram/_model.py +217 -0
  1076. pyfect/socket/server.py +258 -0
  1077. pyfect/socket/ws.py +484 -0
  1078. pyfect/sql/__init__.py +60 -0
  1079. pyfect/sql/_loop.py +134 -0
  1080. pyfect/sql/clickhouse/__init__.py +74 -0
  1081. pyfect/sql/clickhouse/_connection.py +237 -0
  1082. pyfect/sql/clickhouse/_rows.py +87 -0
  1083. pyfect/sql/clickhouse/client.py +322 -0
  1084. pyfect/sql/clickhouse/config.py +241 -0
  1085. pyfect/sql/clickhouse/driver.py +434 -0
  1086. pyfect/sql/clickhouse/error.py +106 -0
  1087. pyfect/sql/clickhouse/migrator.py +47 -0
  1088. pyfect/sql/clickhouse/params.py +168 -0
  1089. pyfect/sql/client/__init__.py +35 -0
  1090. pyfect/sql/client/_client.py +309 -0
  1091. pyfect/sql/client/_sqlite_acquirers.py +130 -0
  1092. pyfect/sql/client/_transaction.py +410 -0
  1093. pyfect/sql/connection.py +87 -0
  1094. pyfect/sql/d1/__init__.py +48 -0
  1095. pyfect/sql/d1/api.py +270 -0
  1096. pyfect/sql/d1/client.py +344 -0
  1097. pyfect/sql/d1/config.py +55 -0
  1098. pyfect/sql/error.py +311 -0
  1099. pyfect/sql/libsql/__init__.py +58 -0
  1100. pyfect/sql/libsql/_connection.py +110 -0
  1101. pyfect/sql/libsql/_hrana.py +258 -0
  1102. pyfect/sql/libsql/_local.py +251 -0
  1103. pyfect/sql/libsql/_targets.py +28 -0
  1104. pyfect/sql/libsql/_values.py +46 -0
  1105. pyfect/sql/libsql/client.py +225 -0
  1106. pyfect/sql/libsql/config.py +170 -0
  1107. pyfect/sql/libsql/migrator.py +43 -0
  1108. pyfect/sql/libsql/sdk.py +123 -0
  1109. pyfect/sql/migrator.py +434 -0
  1110. pyfect/sql/model.py +324 -0
  1111. pyfect/sql/mssql/__init__.py +79 -0
  1112. pyfect/sql/mssql/_connection.py +169 -0
  1113. pyfect/sql/mssql/_driver.py +103 -0
  1114. pyfect/sql/mssql/_names.py +9 -0
  1115. pyfect/sql/mssql/_pool.py +125 -0
  1116. pyfect/sql/mssql/_tds.py +447 -0
  1117. pyfect/sql/mssql/_tds_params.py +155 -0
  1118. pyfect/sql/mssql/_worker.py +155 -0
  1119. pyfect/sql/mssql/client.py +344 -0
  1120. pyfect/sql/mssql/config.py +118 -0
  1121. pyfect/sql/mssql/error.py +111 -0
  1122. pyfect/sql/mssql/migrator.py +43 -0
  1123. pyfect/sql/mssql/parameter.py +44 -0
  1124. pyfect/sql/mssql/procedure.py +119 -0
  1125. pyfect/sql/mssql/types.py +137 -0
  1126. pyfect/sql/mysql/__init__.py +60 -0
  1127. pyfect/sql/mysql/_asyncmy.py +168 -0
  1128. pyfect/sql/mysql/_bind.py +76 -0
  1129. pyfect/sql/mysql/_connection.py +156 -0
  1130. pyfect/sql/mysql/_pool.py +63 -0
  1131. pyfect/sql/mysql/_session.py +262 -0
  1132. pyfect/sql/mysql/client.py +244 -0
  1133. pyfect/sql/mysql/config.py +108 -0
  1134. pyfect/sql/mysql/error.py +104 -0
  1135. pyfect/sql/mysql/migrator.py +44 -0
  1136. pyfect/sql/pg/__init__.py +82 -0
  1137. pyfect/sql/pg/_resolve.py +284 -0
  1138. pyfect/sql/pg/_session.py +380 -0
  1139. pyfect/sql/pg/client.py +398 -0
  1140. pyfect/sql/pg/config.py +142 -0
  1141. pyfect/sql/pg/connection.py +585 -0
  1142. pyfect/sql/pg/error.py +131 -0
  1143. pyfect/sql/pg/migrator.py +139 -0
  1144. pyfect/sql/pg/pool.py +265 -0
  1145. pyfect/sql/resolver.py +294 -0
  1146. pyfect/sql/result.py +24 -0
  1147. pyfect/sql/schema.py +116 -0
  1148. pyfect/sql/sqlite/__init__.py +26 -0
  1149. pyfect/sql/sqlite/_connection.py +230 -0
  1150. pyfect/sql/sqlite/_worker.py +71 -0
  1151. pyfect/sql/sqlite/client.py +248 -0
  1152. pyfect/sql/sqlite/migrator.py +43 -0
  1153. pyfect/sql/statement/__init__.py +144 -0
  1154. pyfect/sql/statement/_compiler.py +384 -0
  1155. pyfect/sql/statement/_segments.py +487 -0
  1156. pyfect/sql/statement/_statement.py +526 -0
  1157. pyfect/sql/statement/_transforms.py +93 -0
  1158. pyfect/sql/stream.py +88 -0
  1159. pyfect/stdio.py +206 -0
  1160. pyfect/stream/__init__.py +151 -0
  1161. pyfect/stream/_async_iterable.py +129 -0
  1162. pyfect/stream/_base.py +69 -0
  1163. pyfect/stream/_bridge_methods.py +139 -0
  1164. pyfect/stream/_catch.py +135 -0
  1165. pyfect/stream/_catch_reason.py +558 -0
  1166. pyfect/stream/_channel_methods.py +61 -0
  1167. pyfect/stream/_chunk_methods.py +169 -0
  1168. pyfect/stream/_chunking.py +310 -0
  1169. pyfect/stream/_concat.py +65 -0
  1170. pyfect/stream/_constructors.py +341 -0
  1171. pyfect/stream/_context.py +147 -0
  1172. pyfect/stream/_error_methods.py +254 -0
  1173. pyfect/stream/_execution_plan.py +199 -0
  1174. pyfect/stream/_fanout.py +154 -0
  1175. pyfect/stream/_fanout_methods.py +183 -0
  1176. pyfect/stream/_filter_methods.py +203 -0
  1177. pyfect/stream/_grouping.py +168 -0
  1178. pyfect/stream/_many.py +65 -0
  1179. pyfect/stream/_map_methods.py +233 -0
  1180. pyfect/stream/_mapping.py +126 -0
  1181. pyfect/stream/_run.py +114 -0
  1182. pyfect/stream/_run_methods.py +114 -0
  1183. pyfect/stream/_service_methods.py +36 -0
  1184. pyfect/stream/_sink_methods.py +151 -0
  1185. pyfect/stream/_sinking.py +277 -0
  1186. pyfect/stream/_sources.py +124 -0
  1187. pyfect/stream/_stream.py +162 -0
  1188. pyfect/stream/_taking.py +330 -0
  1189. pyfect/stream/_text.py +43 -0
  1190. pyfect/stream/_timing.py +294 -0
  1191. pyfect/stream/_timing_methods.py +252 -0
  1192. pyfect/stream/_zip_methods.py +279 -0
  1193. pyfect/stream/_zipping.py +213 -0
  1194. pyfect/subscription_ref.py +66 -0
  1195. pyfect/synchronized_ref.py +38 -0
  1196. pyfect/take.py +36 -0
  1197. pyfect/terminal/__init__.py +41 -0
  1198. pyfect/terminal/_keys.py +113 -0
  1199. pyfect/terminal/_live.py +223 -0
  1200. pyfect/terminal/_service.py +73 -0
  1201. pyfect/testing/__init__.py +122 -0
  1202. pyfect/testing/_assertions.py +92 -0
  1203. pyfect/testing/_clock.py +309 -0
  1204. pyfect/testing/_console.py +164 -0
  1205. pyfect/testing/_crypto.py +44 -0
  1206. pyfect/testing/_decorators.py +211 -0
  1207. pyfect/testing/_flaky.py +34 -0
  1208. pyfect/testing/_layers.py +153 -0
  1209. pyfect/testing/_prop.py +255 -0
  1210. pyfect/testing/_runners.py +84 -0
  1211. pyfect/testing/_runtime.py +174 -0
  1212. pyfect/testing/_schema.py +238 -0
  1213. pyfect/testing/plugin.py +59 -0
  1214. pyfect/tracer/__init__.py +107 -0
  1215. pyfect/tracer/_model.py +176 -0
  1216. pyfect/tracer/_native.py +172 -0
  1217. pyfect/tracer/_refs.py +87 -0
  1218. pyfect/tracer/_spans.py +269 -0
  1219. pyfect/transaction.py +340 -0
  1220. pyfect/trie.py +317 -0
  1221. pyfect/tx_chunk.py +127 -0
  1222. pyfect/tx_deferred.py +75 -0
  1223. pyfect/tx_hash_map.py +265 -0
  1224. pyfect/tx_hash_set.py +151 -0
  1225. pyfect/tx_priority_queue.py +224 -0
  1226. pyfect/tx_pubsub.py +194 -0
  1227. pyfect/tx_queue/__init__.py +27 -0
  1228. pyfect/tx_queue/_queue.py +359 -0
  1229. pyfect/tx_queue/_views.py +60 -0
  1230. pyfect/tx_reentrant_lock.py +201 -0
  1231. pyfect/tx_ref.py +79 -0
  1232. pyfect/tx_semaphore.py +136 -0
  1233. pyfect/tx_subscription_ref.py +118 -0
  1234. pyfect/workers/__init__.py +62 -0
  1235. pyfect/workers/_frames.py +82 -0
  1236. pyfect/workers/_mailbox.py +51 -0
  1237. pyfect/workers/_port.py +106 -0
  1238. pyfect/workers/_process.py +155 -0
  1239. pyfect/workers/_thread.py +100 -0
  1240. pyfect/workers/python_worker.py +133 -0
  1241. pyfect/workers/python_worker_runner.py +112 -0
  1242. pyfect/workers/transferable.py +103 -0
  1243. pyfect/workers/worker.py +273 -0
  1244. pyfect/workers/worker_error.py +86 -0
  1245. pyfect/workers/worker_runner.py +85 -0
  1246. pyfect/workflow/__init__.py +78 -0
  1247. pyfect/workflow/_crypto.py +23 -0
  1248. pyfect/workflow/_encoded.py +381 -0
  1249. pyfect/workflow/_memory.py +424 -0
  1250. pyfect/workflow/_result.py +43 -0
  1251. pyfect/workflow/_services.py +241 -0
  1252. pyfect/workflow/_suspension.py +153 -0
  1253. pyfect/workflow/activity.py +427 -0
  1254. pyfect/workflow/durable_clock.py +72 -0
  1255. pyfect/workflow/durable_deferred.py +403 -0
  1256. pyfect/workflow/durable_queue.py +259 -0
  1257. pyfect/workflow/workflow.py +509 -0
  1258. pyfect/workflow/workflow_engine.py +42 -0
  1259. pyfect/workflow/workflow_proxy.py +161 -0
  1260. pyfect/workflow/workflow_proxy_server.py +146 -0
  1261. pyfect_dev-0.1.0.dist-info/METADATA +296 -0
  1262. pyfect_dev-0.1.0.dist-info/RECORD +1265 -0
  1263. pyfect_dev-0.1.0.dist-info/WHEEL +4 -0
  1264. pyfect_dev-0.1.0.dist-info/entry_points.txt +3 -0
  1265. pyfect_dev-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1048 @@
1
+ """One client's side of an MCP server: its session and the handling of
2
+ each JSON-RPC message it sends.
3
+
4
+ A ``Connection`` is a stdio process's client or an HTTP session.
5
+ ``dispatch`` takes one parsed message and writes what it causes through
6
+ ``out``: a request is served on its own fiber (so the client can answer
7
+ the server's requests meanwhile, or cancel it) and its response written
8
+ when done; a response to a server request completes the waiting call.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import itertools
14
+ from collections.abc import Callable, Mapping
15
+ from dataclasses import dataclass, field
16
+ from typing import Any, Literal, Never, cast
17
+
18
+ from pyfect import _json_text
19
+ from pyfect import schema as S
20
+ from pyfect._core import Effect
21
+ from pyfect._fiber import Fiber
22
+ from pyfect.ai._mcp import log_levels, param_headers, projection, reverse_policy, subscriptions
23
+ from pyfect.ai._mcp.core import McpServerService, RequestOutbound, RequestServices
24
+ from pyfect.ai._mcp.http_status import fail_with_http_status
25
+ from pyfect.ai._mcp.input_wire import CONTINUATION_PARAMS, INPUT_REQUESTS, ContinuationParams
26
+ from pyfect.ai.mcp_protocol import AnyProtocolAdapter, Registry
27
+ from pyfect.ai.mcp_schema import (
28
+ CALL_TOOL_PARAMS,
29
+ COMPLETE_PARAMS,
30
+ CREATE_MESSAGE_RESULT,
31
+ ELICIT_RESULT,
32
+ GET_PROMPT,
33
+ HEADER_MISMATCH_ERROR_CODE,
34
+ IMPLEMENTATION,
35
+ INITIALIZE_PARAMS,
36
+ LIST_ROOTS_RESULT,
37
+ LIST_TOOLS,
38
+ METHOD_NOT_FOUND_ERROR_CODE,
39
+ MISSING_REQUIRED_CLIENT_CAPABILITY_ERROR_CODE,
40
+ READ_RESOURCE,
41
+ SET_LEVEL,
42
+ SUBSCRIBE,
43
+ SUBSCRIPTIONS_LISTEN,
44
+ UNSUPPORTED_PROTOCOL_VERSION_ERROR_CODE,
45
+ CallToolParams,
46
+ CallToolResult,
47
+ ClientCapabilities,
48
+ CreateMessageParams,
49
+ CreateMessageResult,
50
+ ElicitRequestParams,
51
+ ElicitResult,
52
+ GetPromptResult,
53
+ Icon,
54
+ Implementation,
55
+ InputRequired,
56
+ InternalError,
57
+ InvalidParams,
58
+ InvalidRequest,
59
+ JsonObject,
60
+ ListRootsResult,
61
+ LoggingLevel,
62
+ McpError,
63
+ McpInputResponse,
64
+ McpRequestContext,
65
+ McpReverseOperationError,
66
+ McpReverseOperationUnsupported,
67
+ McpServerClient,
68
+ ProtocolError,
69
+ RequestContext,
70
+ RequestId,
71
+ ReverseClient,
72
+ ReverseError,
73
+ ReverseOperation,
74
+ ServerCapabilities,
75
+ ServerClient,
76
+ parse_request_id,
77
+ )
78
+ from pyfect.cause import Cause, Fail
79
+ from pyfect.deferred import Deferred
80
+ from pyfect.effect import (
81
+ fail,
82
+ fail_cause,
83
+ gen,
84
+ interrupt,
85
+ provide_service,
86
+ service_option,
87
+ succeed,
88
+ suspend,
89
+ sync,
90
+ )
91
+ from pyfect.exit import Success
92
+ from pyfect.http.server_request import HttpServerRequest, ServerRequest
93
+ from pyfect.logger import CurrentLogLevel, Severity
94
+ from pyfect.option import Option
95
+ from pyfect.scope import scoped
96
+
97
+ type Wire = dict[str, Any]
98
+ """A result as written."""
99
+
100
+ type Send = Callable[[JsonObject], Effect[None]]
101
+ """Writes a message to the client."""
102
+
103
+ PROTOCOL_VERSION_META = "io.modelcontextprotocol/protocolVersion"
104
+ CLIENT_INFO_META = "io.modelcontextprotocol/clientInfo"
105
+ CLIENT_CAPABILITIES_META = "io.modelcontextprotocol/clientCapabilities"
106
+ SERVER_INFO_META = "io.modelcontextprotocol/serverInfo"
107
+
108
+ _FEATURE_HANDLER_FAILED = "MCP feature handler failed"
109
+
110
+ _VOID: Effect[None] = succeed(None)
111
+
112
+
113
+ @dataclass(frozen=True, slots=True, kw_only=True)
114
+ class ServerInfo:
115
+ """How the server describes itself."""
116
+
117
+ name: str
118
+ version: str
119
+ title: str | None = None
120
+ description: str | None = None
121
+ website_url: str | None = None
122
+ icons: tuple[Icon, ...] = ()
123
+ instructions: str | None = None
124
+ extensions: Mapping[str, Any] | None = None
125
+
126
+ def implementation(self) -> Implementation:
127
+ info: Implementation = {"name": self.name, "version": self.version}
128
+ if self.title is not None:
129
+ info["title"] = self.title
130
+ if self.description is not None:
131
+ info["description"] = self.description
132
+ if self.website_url is not None:
133
+ info["websiteUrl"] = self.website_url
134
+ if self.icons:
135
+ info["icons"] = list(self.icons)
136
+ return info
137
+
138
+
139
+ def response(id: RequestId | None, result: Mapping[str, Any]) -> JsonObject:
140
+ return {"jsonrpc": "2.0", "id": id, "result": dict(result)}
141
+
142
+
143
+ def error_response(id: RequestId | None, error: McpError) -> JsonObject:
144
+ return {"jsonrpc": "2.0", "id": id, "error": cast("Any", error.to_wire())}
145
+
146
+
147
+ def _encodable_response(id: RequestId, result: Wire) -> JsonObject:
148
+ """The response carrying ``result``, or an internal error when it is not
149
+ JSON (a NaN, a value with no JSON form)."""
150
+ reply = response(id, result)
151
+ try:
152
+ _json_text.stringify(reply)
153
+ except (TypeError, ValueError):
154
+ return error_response(id, InternalError("Failed to encode the result"))
155
+ return reply
156
+
157
+
158
+ def invalid_params_response(id: RequestId | None) -> JsonObject:
159
+ """The answer to a request whose params are not an object."""
160
+ return error_response(id, InvalidParams("Invalid params"))
161
+
162
+
163
+ def notification(method: str, params: JsonObject) -> JsonObject:
164
+ return {"jsonrpc": "2.0", "method": method, "params": params}
165
+
166
+
167
+ type Kind = Literal["request", "notification", "response", "invalid", "invalid_params", "ignored"]
168
+ """``invalid_params``: a request whose params are not an object; ``ignored``:
169
+ a notification whose params are not (answered by nothing)."""
170
+
171
+
172
+ @dataclass(frozen=True, slots=True)
173
+ class Request:
174
+ """A request to serve: its id was parsed, so it is one."""
175
+
176
+ id: RequestId
177
+ method: str
178
+ params: JsonObject
179
+
180
+
181
+ @dataclass(frozen=True, slots=True)
182
+ class Classified:
183
+ """What a parsed JSON value is, with the id to answer it with (and the
184
+ request, when it is one)."""
185
+
186
+ kind: Kind
187
+ id: RequestId | None = None
188
+ method: str = ""
189
+ params: JsonObject = field(default_factory=dict[str, Any])
190
+ body: JsonObject = field(default_factory=dict[str, Any])
191
+ request: Request | None = None
192
+
193
+
194
+ def classify(message: object) -> Classified: # noqa: PLR0911
195
+ if not isinstance(message, dict):
196
+ return Classified("invalid")
197
+ body = cast("JsonObject", message)
198
+ id = parse_request_id(body.get("id"))
199
+ if body.get("jsonrpc") != "2.0":
200
+ return Classified("invalid", id)
201
+ method = body.get("method")
202
+ params = body.get("params", {})
203
+ if isinstance(method, str):
204
+ if params is not None and not isinstance(params, dict):
205
+ if "id" not in body:
206
+ return Classified("ignored", None, method)
207
+ return (
208
+ Classified("invalid_params", id, method)
209
+ if id is not None
210
+ else Classified("invalid", None, method)
211
+ )
212
+ params_object: JsonObject = params or {}
213
+ if "id" not in body:
214
+ return Classified("notification", None, method, params_object)
215
+ if id is None:
216
+ return Classified("invalid", None, method)
217
+ return Classified(
218
+ "request", id, method, params_object, request=Request(id, method, params_object)
219
+ )
220
+ if "method" not in body and ("result" in body or "error" in body):
221
+ return Classified("response", id, body=body)
222
+ return Classified("invalid", id)
223
+
224
+
225
+ def requested_protocol_version(params: Mapping[str, Any]) -> str | None:
226
+ """The version a stateless request names in its ``_meta``."""
227
+ meta = params.get("_meta")
228
+ if not isinstance(meta, dict):
229
+ return None
230
+ version = cast("JsonObject", meta).get(PROTOCOL_VERSION_META)
231
+ return version if isinstance(version, str) else None
232
+
233
+
234
+ def _decode(schema: S.Top, params: object) -> Effect[Any, InvalidParams]:
235
+ decode = cast("Callable[[object], Effect[Any, S.SchemaError]]", S.decode_unknown_effect(schema))
236
+ return decode(params).map_error(lambda error: InvalidParams(error.message))
237
+
238
+
239
+ def _method_not_found_bare() -> McpError:
240
+ return ProtocolError("Method not found", error_code=METHOD_NOT_FOUND_ERROR_CODE)
241
+
242
+
243
+ def _method_not_found(method: str) -> McpError:
244
+ return ProtocolError(f"Method not found: {method}", error_code=METHOD_NOT_FOUND_ERROR_CODE)
245
+
246
+
247
+ def _as_mcp_error(cause: Cause[object]) -> Effect[Wire, McpError]:
248
+ """A request's failure as the error to answer with: its own MCP error,
249
+ else an internal error. Interruption stays interruption."""
250
+ if cause.has_interrupts_only:
251
+ return fail_cause(cast("Cause[Never]", cause))
252
+ found = cause.find_recoverable_error()
253
+ if isinstance(found, Fail) and isinstance(found.error, McpError):
254
+ return fail(found.error)
255
+ return fail(InternalError("Internal error"))
256
+
257
+
258
+ @dataclass(frozen=True, slots=True)
259
+ class Identity:
260
+ """Who sent a request: a session's client, fixed by ``initialize``, or
261
+ a stateless request's own ``_meta``. Passed to each request rather
262
+ than read from the connection, so one request cannot change another's."""
263
+
264
+ capabilities: ClientCapabilities = field(default_factory=ClientCapabilities)
265
+ info: Implementation | None = None
266
+
267
+
268
+ @dataclass(eq=False)
269
+ class Connection:
270
+ """One client: a stdio process's or an HTTP session's."""
271
+
272
+ server: McpServerService
273
+ info: ServerInfo
274
+ registry: Registry
275
+ client_id: int
276
+ transport: Literal["stdio", "http"]
277
+ broadcast: Send
278
+ default_log_level: Severity
279
+ """The session's threshold until it sets one: the ``CurrentLogLevel``
280
+ the server was built with (Effect's ``defaultLogLevel``)."""
281
+ protocol: AnyProtocolAdapter | None = None
282
+ identity: Identity = field(default_factory=Identity)
283
+ initialize_payload: JsonObject = field(default_factory=dict[str, Any])
284
+ initialized: bool = False
285
+ closed: bool = False
286
+ """Whether the session ended (closed by the client, idle or evicted)."""
287
+ streams: list[Send] = field(default_factory=list[Send])
288
+ """An HTTP session's event streams of the requests in flight, where its
289
+ ``broadcast`` writes (a stdio client has the one output)."""
290
+ log_level: LoggingLevel | None = None
291
+ """The level the client set with ``logging/setLevel``."""
292
+ subscriptions: set[str] = field(default_factory=set[str])
293
+ supports_subscriptions: bool = True
294
+ """Whether 2026-07-28 clients may ``subscriptions/listen``."""
295
+ _listening: set[RequestId] = field(default_factory=set[RequestId])
296
+ """The requests that are subscriptions: they end only when cancelled."""
297
+ _pending: dict[RequestId, Deferred[JsonObject]] = field(
298
+ default_factory=dict[RequestId, "Deferred[JsonObject]"]
299
+ )
300
+ _inflight: dict[RequestId, Fiber[Any, Any]] = field(
301
+ default_factory=dict[RequestId, "Fiber[Any, Any]"]
302
+ )
303
+ _reverse_ids: itertools.count[int] = field(default_factory=lambda: itertools.count(1))
304
+
305
+ # --- messages ----------------------------------------------------------------------
306
+
307
+ def dispatch(self, message: object, out: Send) -> Effect[None]:
308
+ """Handle one message; a request is answered through ``out`` from
309
+ its own fiber."""
310
+ classified = classify(message)
311
+ request = classified.request
312
+ if request is not None:
313
+ if request.method == "initialize":
314
+ # Answered before the next message, which may rely on it.
315
+ return self.answer(request.id, request.method, request.params, out).flat_map(
316
+ lambda reply: _VOID if reply is None else out(reply)
317
+ )
318
+ return self.start(request, out).as_void()
319
+ return self._not_a_request(classified, out)
320
+
321
+ def _not_a_request(self, classified: Classified, out: Send) -> Effect[None]:
322
+ match classified.kind:
323
+ case "notification":
324
+ return self._notified(classified.method, classified.params)
325
+ case "response":
326
+ return self._answered(classified.body)
327
+ case "ignored":
328
+ return _VOID
329
+ case "invalid_params":
330
+ return out(invalid_params_response(classified.id))
331
+ case _:
332
+ return out(error_response(classified.id, InvalidRequest("Invalid Request")))
333
+
334
+ @property
335
+ def busy(self) -> bool:
336
+ """Whether a request is still being served."""
337
+ return bool(self._inflight)
338
+
339
+ def close(self) -> Effect[None]:
340
+ """End the connection: interrupt the requests still being served."""
341
+
342
+ @gen
343
+ def run():
344
+ self.closed = True
345
+ for fiber in list(self._inflight.values()):
346
+ yield from fiber.interrupt()
347
+
348
+ return run
349
+
350
+ def drain(self) -> Effect[None]:
351
+ """Wait for the requests still being served, ending the subscriptions
352
+ among them: nobody is left to cancel those."""
353
+
354
+ @gen
355
+ def run():
356
+ # Taken at once: awaiting one, another may end by itself (overflow).
357
+ for fiber in [self._inflight[id] for id in self._listening]:
358
+ yield from fiber.interrupt()
359
+ while self._inflight:
360
+ yield from next(iter(self._inflight.values())).await_exit()
361
+
362
+ return run
363
+
364
+ def start(self, request: Request, out: Send) -> Effect[Fiber[None, Never]]:
365
+ """Serve ``request`` on its own fiber, which ends once its response
366
+ is written or it is cancelled (writing nothing)."""
367
+ id = request.id
368
+
369
+ def done() -> None:
370
+ self._inflight.pop(id, None)
371
+ self._listening.discard(id)
372
+
373
+ served = (
374
+ self.answer(id, request.method, request.params, out)
375
+ .flat_map(lambda reply: _VOID if reply is None else out(reply))
376
+ .ensuring(sync(done))
377
+ )
378
+
379
+ def track(fiber: Fiber[None, Never]) -> Fiber[None, Never]:
380
+ self._inflight[id] = fiber
381
+ if request.method == SUBSCRIPTIONS_LISTEN.name:
382
+ self._listening.add(id)
383
+ return fiber
384
+
385
+ return served.fork_daemon().map(track)
386
+
387
+ def answer(
388
+ self, id: RequestId, method: str, params: JsonObject, out: Send
389
+ ) -> Effect[JsonObject | None]:
390
+ """The response to a request (``None`` when it was cancelled)."""
391
+ version = requested_protocol_version(params)
392
+ stateless = self.registry.find(version) if version is not None else None
393
+ if stateless is not None and stateless.is_stateless:
394
+ answered = self._stateless(stateless, id, method, params, out)
395
+ elif version is not None and stateless is None and _offers_stateless(self.registry):
396
+ answered = fail(_unsupported_version(version, self.registry))
397
+ else:
398
+ answered = self._stateful(method, params, out)
399
+ # Effect's McpServer is an RpcServer with spanPrefix "McpServer".
400
+ traced = answered.with_span(
401
+ f"McpServer.{method}",
402
+ kind="server",
403
+ capture_stack_trace=False,
404
+ attributes={"rpc.system.name": "effect_rpc", "rpc.method": method},
405
+ )
406
+ # Effect's RpcServer reports the cause of every failed request.
407
+ replied: Effect[JsonObject] = (
408
+ traced.with_error_reporting()
409
+ .catch_cause(_as_mcp_error)
410
+ .match(
411
+ on_failure=lambda error: error_response(id, error),
412
+ on_success=lambda result: _encodable_response(id, result),
413
+ )
414
+ )
415
+ return replied.exit().map(lambda exit: exit.value if isinstance(exit, Success) else None)
416
+
417
+ def _notified(self, method: str, params: JsonObject) -> Effect[None]:
418
+ if method == "notifications/initialized" and self.protocol is not None:
419
+ return sync(lambda: setattr(self, "initialized", True))
420
+ if method == "notifications/cancelled":
421
+ request_id = parse_request_id(params.get("requestId"))
422
+ fiber = None if request_id is None else self._inflight.get(request_id)
423
+ if fiber is not None:
424
+ return sync(lambda: fiber.interrupt_as_unsafe(None))
425
+ return _VOID
426
+
427
+ def _answered(self, body: JsonObject) -> Effect[None]:
428
+ id = parse_request_id(body.get("id"))
429
+ deferred = None if id is None else self._pending.get(id)
430
+ return _VOID if deferred is None else deferred.succeed(body).as_void()
431
+
432
+ # --- notifications -----------------------------------------------------------------
433
+
434
+ def wants(self, method: str, params: Mapping[str, Any]) -> bool:
435
+ if method == "notifications/message":
436
+ threshold = self.default_log_level if self.log_level is None else self.log_level
437
+ return log_levels.session_delivers(params.get("level"), threshold)
438
+ if method == "notifications/resources/updated":
439
+ return params.get("uri") in self.subscriptions
440
+ if method == "notifications/elicitation/complete":
441
+ return self.protocol is not None and self.protocol.supports_icons
442
+ return True
443
+
444
+ def deliver(self, method: str, params: JsonObject) -> Effect[None]:
445
+ """A broadcast notification, sent once the client is initialized
446
+ and if it wants it (``Peer``)."""
447
+ protocol = self.protocol
448
+ if protocol is None or not self.initialized or not self.wants(method, params):
449
+ return _VOID
450
+ return self.broadcast(
451
+ notification(method, projection.notification(protocol, method, params))
452
+ )
453
+
454
+ def _request_outbound(
455
+ self, out: Send, protocol: AnyProtocolAdapter, metadata: JsonObject
456
+ ) -> Callable[[str, JsonObject], Effect[None]]:
457
+ """Where a request's own notifications go. A 2026-07-28 request gets
458
+ the logs its ``_meta`` asks for and the progress of its own token."""
459
+
460
+ def stateless_wants(method: str, params: JsonObject) -> bool:
461
+ if method == "notifications/message":
462
+ minimum = log_levels.request_log_level(metadata)
463
+ level = params.get("level")
464
+ return (
465
+ log_levels.is_logging_level(minimum)
466
+ and log_levels.is_logging_level(level)
467
+ and log_levels.at_least(level, minimum)
468
+ )
469
+ if method == "notifications/progress":
470
+ return params.get("progressToken") == metadata.get("progressToken")
471
+ return self.wants(method, params)
472
+
473
+ wants = stateless_wants if protocol.is_stateless else self.wants
474
+
475
+ def deliver(method: str, params: JsonObject) -> Effect[None]:
476
+ if not wants(method, params):
477
+ return _VOID
478
+ return out(notification(method, projection.notification(protocol, method, params)))
479
+
480
+ return deliver
481
+
482
+ def _handler_log_level(self, protocol: AnyProtocolAdapter, metadata: JsonObject) -> Severity:
483
+ """The ``CurrentLogLevel`` a handler runs at: its request's level on
484
+ 2026-07-28, else the session's."""
485
+ if protocol.is_stateless:
486
+ requested = log_levels.request_log_level(metadata)
487
+ if log_levels.is_logging_level(requested):
488
+ return log_levels.effect_level(requested)
489
+ return self.default_log_level
490
+ if self.log_level is None:
491
+ return self.default_log_level
492
+ return log_levels.effect_level(self.log_level)
493
+
494
+ # --- requests to the client --------------------------------------------------------
495
+
496
+ def _reverse_request(
497
+ self, operation: ReverseOperation, params: Mapping[str, Any], out: Send
498
+ ) -> Effect[JsonObject, ReverseError]:
499
+ id = f"server-{self.client_id}-{next(self._reverse_ids)}"
500
+ deferred = Deferred[JsonObject]()
501
+ message: JsonObject = {
502
+ "jsonrpc": "2.0",
503
+ "id": id,
504
+ "method": operation,
505
+ "params": dict(params),
506
+ }
507
+
508
+ def answer(reply: JsonObject) -> Effect[JsonObject, ReverseError]:
509
+ error = reply.get("error")
510
+ if isinstance(error, dict):
511
+ return fail(McpReverseOperationError(operation, error))
512
+ result = reply.get("result")
513
+ return succeed(result if isinstance(result, dict) else {})
514
+
515
+ return (
516
+ sync(lambda: self._pending.__setitem__(id, deferred))
517
+ .and_then(out(message))
518
+ .and_then(
519
+ # A cancelled request may never be answered: tell the client.
520
+ deferred.wait().on_interrupt(
521
+ out(notification("notifications/cancelled", {"requestId": id}))
522
+ )
523
+ )
524
+ .flat_map(answer)
525
+ .ensuring(sync(lambda: self._pending.pop(id, None)))
526
+ )
527
+
528
+ def _reverse_client(
529
+ self, protocol: AnyProtocolAdapter, identity: Identity, out: Send
530
+ ) -> ReverseClient:
531
+ version = protocol.protocol_version
532
+
533
+ def refused(
534
+ operation: ReverseOperation, capability: Literal["roots", "sampling", "elicitation"]
535
+ ) -> McpReverseOperationUnsupported | None:
536
+ def unsupported(reason: str) -> McpReverseOperationUnsupported:
537
+ return McpReverseOperationUnsupported(operation, version, reason)
538
+
539
+ if capability == "elicitation" and not protocol.supports_structured_content:
540
+ return unsupported(f"MCP {version} has no elicitation")
541
+ if identity.capabilities.get(capability) is None:
542
+ return unsupported(f"Client did not advertise the {capability} capability")
543
+ return None
544
+
545
+ def request[A](
546
+ operation: ReverseOperation,
547
+ capability: Literal["roots", "sampling", "elicitation"],
548
+ params: Mapping[str, Any],
549
+ result: S.Codec[A, Any],
550
+ ) -> Effect[A, ReverseError]:
551
+ """The client's answer, decoded with ``result`` (a malformed one
552
+ is an ``McpReverseOperationError``, never taken as is)."""
553
+ error = refused(operation, capability)
554
+ if error is not None:
555
+ return fail(error)
556
+ decode = cast(
557
+ "Callable[[object], Effect[A, S.SchemaError]]", S.decode_unknown_effect(result)
558
+ )
559
+ return self._reverse_request(operation, params, out).flat_map(
560
+ lambda reply: decode(reply).map_error(
561
+ lambda invalid: McpReverseOperationError(operation, invalid)
562
+ )
563
+ )
564
+
565
+ def list_roots() -> Effect[ListRootsResult, ReverseError]:
566
+ return request("roots/list", "roots", {}, LIST_ROOTS_RESULT)
567
+
568
+ def create_message(
569
+ params: CreateMessageParams,
570
+ ) -> Effect[CreateMessageResult, ReverseError]:
571
+ operation: ReverseOperation = "sampling/createMessage"
572
+ refusal = refused(operation, "sampling")
573
+ reason = reverse_policy.sampling_refusal(protocol, identity.capabilities, params)
574
+ if refusal is None and reason is not None:
575
+ return fail(McpReverseOperationUnsupported(operation, version, reason))
576
+
577
+ def checked(result: CreateMessageResult) -> Effect[CreateMessageResult, ReverseError]:
578
+ reason = reverse_policy.sampling_result_refusal(
579
+ protocol, identity.capabilities, result
580
+ )
581
+ if reason is None:
582
+ return succeed(result)
583
+ return fail(McpReverseOperationUnsupported(operation, version, reason))
584
+
585
+ return request(operation, "sampling", params, CREATE_MESSAGE_RESULT).flat_map(checked)
586
+
587
+ def elicit(params: ElicitRequestParams) -> Effect[ElicitResult, ReverseError]:
588
+ if refused("elicitation/create", "elicitation") is None:
589
+ projected = reverse_policy.project_elicitation(
590
+ protocol, identity.capabilities, params
591
+ )
592
+ if isinstance(projected, str):
593
+ return fail(
594
+ McpReverseOperationUnsupported("elicitation/create", version, projected)
595
+ )
596
+ params = projected
597
+ return request("elicitation/create", "elicitation", params, ELICIT_RESULT)
598
+
599
+ return ReverseClient(list_roots, create_message, elicit)
600
+
601
+ # --- serving -----------------------------------------------------------------------
602
+
603
+ def _serve(
604
+ self,
605
+ protocol: AnyProtocolAdapter,
606
+ identity: Identity,
607
+ params: JsonObject,
608
+ out: Send,
609
+ handler: Callable[[RequestContext], Effect[Wire, McpError, RequestServices]],
610
+ *,
611
+ continuation: ContinuationParams | None = None,
612
+ ) -> Effect[Wire, McpError]:
613
+ """``handler`` given the request's services."""
614
+ meta = params.get("_meta")
615
+ metadata: JsonObject = meta if isinstance(meta, dict) else {}
616
+ version = protocol.protocol_version
617
+ responses: Mapping[str, McpInputResponse] | None = None
618
+ state: str | None = None
619
+ if continuation is not None:
620
+ responses = continuation.get("inputResponses")
621
+ state = continuation.get("requestState")
622
+ context = RequestContext(
623
+ self.client_id,
624
+ version,
625
+ identity.capabilities,
626
+ identity.info,
627
+ metadata,
628
+ responses,
629
+ state,
630
+ )
631
+ client = ServerClient(
632
+ self.client_id,
633
+ version,
634
+ identity.capabilities,
635
+ identity.info,
636
+ self.initialize_payload,
637
+ succeed(self._reverse_client(protocol, identity, out)),
638
+ metadata,
639
+ )
640
+ # A stateless request belongs to no session, so it has no client of one.
641
+ with_client: Effect[Wire, McpError, Any] = suspend(lambda: handler(context))
642
+ if not protocol.is_stateless:
643
+ with_client = with_client.pipe(provide_service(McpServerClient, client))
644
+ return (
645
+ with_client.pipe(provide_service(McpRequestContext, context))
646
+ .pipe(provide_service(CurrentLogLevel, self._handler_log_level(protocol, metadata)))
647
+ .pipe(provide_service(RequestOutbound, self._request_outbound(out, protocol, metadata)))
648
+ )
649
+
650
+ def _stateful(self, method: str, params: JsonObject, out: Send) -> Effect[Wire, McpError]:
651
+ if method == "ping":
652
+ return succeed({})
653
+ if method == "initialize":
654
+ return self._initialize(params)
655
+ protocol = self.protocol
656
+ if protocol is None:
657
+ return fail(InvalidRequest("Server not initialized"))
658
+ return self._feature(protocol, self.identity, method, params, out)
659
+
660
+ def _initialize(self, params: JsonObject) -> Effect[Wire, McpError]:
661
+ offered = params.get("protocolVersion")
662
+ protocol = self.registry.select_stateful(offered if isinstance(offered, str) else None)
663
+ if protocol is None:
664
+ return fail(_method_not_found("initialize"))
665
+
666
+ def start(payload: Any) -> Wire:
667
+ self.protocol = protocol
668
+ capabilities = projection.client_capabilities(protocol, payload["capabilities"])
669
+ self.identity = Identity(capabilities, payload["clientInfo"])
670
+ self.initialize_payload = dict(params)
671
+ result: Wire = {
672
+ "protocolVersion": protocol.protocol_version,
673
+ "capabilities": cast("Any", self.capabilities_for(protocol)),
674
+ "serverInfo": projection.implementation(protocol, self.info.implementation()),
675
+ }
676
+ if self.info.instructions is not None:
677
+ result["instructions"] = self.info.instructions
678
+ return result
679
+
680
+ return _decode(INITIALIZE_PARAMS, params).map(start)
681
+
682
+ def capabilities_for(self, protocol: AnyProtocolAdapter) -> ServerCapabilities:
683
+ presence = self.server.has_registrations
684
+ # A session's client always gets list changes; only 2026-07-28 opts out.
685
+ list_changed = self.supports_subscriptions if protocol.is_stateless else True
686
+ subscribe = list_changed if protocol.is_stateless else self.transport == "stdio"
687
+ capabilities: ServerCapabilities = {"logging": {}}
688
+ if protocol.supports_audio:
689
+ capabilities["completions"] = {}
690
+ extensions = _extensions(protocol, self.info.extensions)
691
+ if extensions:
692
+ capabilities["extensions"] = extensions
693
+ if presence.prompts:
694
+ capabilities["prompts"] = {"listChanged": list_changed}
695
+ if presence.resources:
696
+ capabilities["resources"] = {"listChanged": list_changed, "subscribe": subscribe}
697
+ if presence.tools:
698
+ capabilities["tools"] = {"listChanged": list_changed}
699
+ return capabilities
700
+
701
+ def _feature( # noqa: PLR0911
702
+ self,
703
+ protocol: AnyProtocolAdapter,
704
+ identity: Identity,
705
+ method: str,
706
+ params: JsonObject,
707
+ out: Send,
708
+ ) -> Effect[Wire, McpError]:
709
+ server = self.server
710
+
711
+ def serve(
712
+ handler: Callable[[RequestContext], Effect[Wire, McpError, RequestServices]],
713
+ ) -> Effect[Wire, McpError]:
714
+ return self._serve(protocol, identity, params, out, handler)
715
+
716
+ def serve_continued(
717
+ handler: Callable[[RequestContext], Effect[Wire, McpError, RequestServices]],
718
+ ) -> Effect[Wire, McpError]:
719
+ """``serve`` for a request 2026-07-28 may retry with client input."""
720
+ if not protocol.is_stateless:
721
+ return serve(handler)
722
+ return _decode(CONTINUATION_PARAMS, params).flat_map(
723
+ lambda continuation: self._serve(
724
+ protocol, identity, params, out, handler, continuation=continuation
725
+ )
726
+ )
727
+
728
+ def listed(
729
+ key: str, items: Callable[[RequestContext], list[Any]]
730
+ ) -> Effect[Wire, McpError]:
731
+ return serve(lambda c: succeed({key: items(c)}))
732
+
733
+ match method:
734
+ case "logging/setLevel":
735
+ return _decode(SET_LEVEL.payload_schema, params).map(self._set_level)
736
+ case "resources/subscribe" | "resources/unsubscribe" if self.transport == "stdio":
737
+ subscribe = method == "resources/subscribe"
738
+ return _decode(SUBSCRIBE.payload_schema, params).map(
739
+ lambda decoded: self._subscribe(decoded["uri"], subscribe)
740
+ )
741
+ case "tools/list":
742
+ return _decode(LIST_TOOLS.payload_schema, params).and_then(
743
+ listed(
744
+ "tools",
745
+ lambda c: [projection.tool(protocol, t) for t in server.list_tools(c)],
746
+ )
747
+ )
748
+ case "tools/call":
749
+ return _decode(CALL_TOOL_PARAMS, params).flat_map(
750
+ lambda call: serve_continued(lambda c: _call_tool(server, protocol, call, c))
751
+ )
752
+ case "resources/list":
753
+ return listed(
754
+ "resources",
755
+ lambda c: [projection.resource(protocol, r) for r in server.list_resources(c)],
756
+ )
757
+ case "resources/templates/list":
758
+ return listed(
759
+ "resourceTemplates",
760
+ lambda c: [
761
+ projection.resource_template(protocol, t)
762
+ for t in server.list_resource_templates(c)
763
+ ],
764
+ )
765
+ case "resources/read":
766
+ return _decode(READ_RESOURCE.payload_schema, params).flat_map(
767
+ lambda decoded: serve_continued(
768
+ lambda c: self._read(protocol, decoded["uri"], c)
769
+ )
770
+ )
771
+ case "prompts/list":
772
+ return listed(
773
+ "prompts",
774
+ lambda c: [projection.prompt(protocol, p) for p in server.list_prompts(c)],
775
+ )
776
+ case "prompts/get":
777
+ return _decode(GET_PROMPT.payload_schema, params).flat_map(
778
+ lambda decoded: serve_continued(
779
+ lambda c: server.get_prompt_for(
780
+ decoded["name"], decoded.get("arguments") or {}, c
781
+ ).flat_map(lambda outcome: _prompt_on_wire(protocol, identity, outcome))
782
+ )
783
+ )
784
+ case "completion/complete":
785
+ return _decode(COMPLETE_PARAMS, params).flat_map(
786
+ lambda decoded: serve(lambda _: server.complete_for(decoded).map(_wire))
787
+ )
788
+ case _:
789
+ return fail(_method_not_found(method))
790
+
791
+ def _set_level(self, decoded: Any) -> JsonObject:
792
+ self.log_level = decoded["level"]
793
+ return {}
794
+
795
+ def _subscribe(self, uri: str, subscribe: bool) -> JsonObject:
796
+ if subscribe:
797
+ self.subscriptions.add(uri)
798
+ else:
799
+ self.subscriptions.discard(uri)
800
+ return {}
801
+
802
+ def _read(
803
+ self, protocol: AnyProtocolAdapter, uri: str, context: RequestContext
804
+ ) -> Effect[Wire, McpError, RequestServices]:
805
+ found = self.server.read_resource_for(uri, context)
806
+ if found is None:
807
+ return fail(
808
+ ProtocolError(
809
+ f"Resource '{uri}' not found",
810
+ {"uri": uri},
811
+ error_code=protocol.resource_not_found_code,
812
+ )
813
+ )
814
+ return found.map(_wire)
815
+
816
+ # --- 2026-07-28 ----------------------------------------------------------------------
817
+
818
+ def _listen(self, id: RequestId, params: JsonObject, out: Send) -> Effect[Wire, McpError]:
819
+ """A ``subscriptions/listen`` stream, on ``out``. It has no result: it
820
+ ends when cancelled, or by itself when its backlog overflows."""
821
+
822
+ def send(method: str, body: JsonObject) -> Effect[None]:
823
+ return out(notification(method, body))
824
+
825
+ def terminate(request_id: RequestId, reason: str) -> Effect[None]:
826
+ # Over HTTP the stream's end says it; stdio's has no end of its own.
827
+ if self.transport == "http":
828
+ return _VOID
829
+ return send("notifications/cancelled", {"requestId": request_id, "reason": reason})
830
+
831
+ def listening(decoded: Any) -> Effect[Wire, McpError]:
832
+ if not self.supports_subscriptions:
833
+ return fail(_method_not_found(SUBSCRIPTIONS_LISTEN.name))
834
+ listened = subscriptions.listen(
835
+ decoded["notifications"],
836
+ id,
837
+ presence=self.server.has_registrations,
838
+ list_change_revision=self.server.list_change_revision,
839
+ subscribe=self.server.subscribe_events,
840
+ send=send,
841
+ terminate=terminate,
842
+ )
843
+ return scoped(listened).and_then(interrupt())
844
+
845
+ return _decode(SUBSCRIPTIONS_LISTEN.payload_schema, params).flat_map(listening)
846
+
847
+ def _stateless( # noqa: PLR0911
848
+ self,
849
+ protocol: AnyProtocolAdapter,
850
+ id: RequestId,
851
+ method: str,
852
+ params: JsonObject,
853
+ out: Send,
854
+ ) -> Effect[Wire, McpError]:
855
+ meta = cast("JsonObject", params.get("_meta") or {})
856
+ capabilities = meta.get(CLIENT_CAPABILITIES_META)
857
+ info = meta.get(CLIENT_INFO_META)
858
+ if info is not None and not _is_implementation(info):
859
+ return fail(InvalidParams(f"Invalid {CLIENT_INFO_META}"))
860
+ identity = Identity(
861
+ cast("ClientCapabilities", capabilities if isinstance(capabilities, dict) else {}),
862
+ cast("Implementation", info) if isinstance(info, dict) else None,
863
+ )
864
+ server_info = projection.implementation(protocol, self.info.implementation())
865
+
866
+ def complete(result: JsonObject, cacheable: bool) -> JsonObject:
867
+ own = result.get("_meta")
868
+ merged: JsonObject = {**(own if isinstance(own, dict) else {})}
869
+ merged[SERVER_INFO_META] = cast("Any", server_info)
870
+ result_type = "input_required" if isinstance(result, _InputRequired) else "complete"
871
+ completed: JsonObject = {**result, "_meta": merged, "resultType": result_type}
872
+ if cacheable:
873
+ completed["ttlMs"] = 0
874
+ completed["cacheScope"] = "private"
875
+ return completed
876
+
877
+ if method == "server/discover":
878
+ discovery: JsonObject = {
879
+ "supportedVersions": list(self.registry.versions),
880
+ "capabilities": cast("Any", self.capabilities_for(protocol)),
881
+ }
882
+ if self.info.instructions is not None:
883
+ discovery["instructions"] = self.info.instructions
884
+ return succeed(complete(discovery, True))
885
+ if method in _NOT_ON_2026_07_28:
886
+ return fail(_method_not_found(method))
887
+ requested_level = log_levels.request_log_level(meta)
888
+ if requested_level is not None and not log_levels.is_logging_level(requested_level):
889
+ return fail(InvalidParams(f"Invalid request log level {requested_level!r}"))
890
+ if method == SUBSCRIPTIONS_LISTEN.name:
891
+ return self._listen(id, params, out)
892
+ if method == "prompts/list" and not self.server.has_registrations.prompts:
893
+ # An unadvertised capability's method (Effect's 2026-07-28 prompts/list).
894
+ return fail_with_http_status(404, _method_not_found_bare())
895
+ cacheable = method in _CACHEABLE
896
+ return self._feature(protocol, identity, method, params, out).map(
897
+ lambda result: complete(result, cacheable)
898
+ )
899
+
900
+
901
+ class _InputRequired(dict[str, Any]):
902
+ """A result that is an ``input_required`` one."""
903
+
904
+
905
+ _NOT_ON_2026_07_28 = frozenset(
906
+ {"ping", "initialize", "logging/setLevel", "resources/subscribe", "resources/unsubscribe"}
907
+ )
908
+ """Session methods ``_feature`` serves for the revisions that have sessions."""
909
+
910
+ _CACHEABLE = frozenset(
911
+ {"tools/list", "prompts/list", "resources/list", "resources/templates/list", "resources/read"}
912
+ )
913
+ """The 2026-07-28 results carrying ``ttlMs`` and ``cacheScope`` (with
914
+ ``server/discover``)."""
915
+
916
+
917
+ def _call_tool(
918
+ server: McpServerService,
919
+ protocol: AnyProtocolAdapter,
920
+ call: CallToolParams,
921
+ context: RequestContext,
922
+ ) -> Effect[Wire, McpError, RequestServices]:
923
+ """A tool's outcome on ``protocol`` 's wire. An unknown tool is always a
924
+ protocol error; the tool's own failures are ``isError`` results when the
925
+ revision reports them so (Effect's per-revision ``tools/call``), but a
926
+ retry the tool refuses (a tampered state) stays a protocol error."""
927
+ name = call["name"]
928
+ found = server.find_tool(name, context)
929
+ if found is None:
930
+ return fail(InvalidParams(f"Tool '{name}' not found"))
931
+ called = server.call_tool_for(call, context)
932
+ continued = context.input_responses is not None or context.request_state is not None
933
+ if protocol.reports_tool_errors_as_results:
934
+
935
+ def reported(
936
+ error: InvalidParams | InternalError,
937
+ ) -> Effect[CallToolResult, InvalidParams]:
938
+ if continued and isinstance(error, InvalidParams):
939
+ return fail(error)
940
+ return succeed(
941
+ cast(
942
+ "CallToolResult",
943
+ {"isError": True, "content": [{"type": "text", "text": str(error)}]},
944
+ )
945
+ )
946
+
947
+ called = called.catch_all(reported)
948
+
949
+ def on_wire(outcome: CallToolResult | InputRequired) -> Effect[Wire, McpError]:
950
+ if isinstance(outcome, InputRequired):
951
+ if not protocol.is_stateless:
952
+ version = protocol.protocol_version
953
+ return fail(InvalidParams(f"Client input is not supported by MCP {version}"))
954
+ return _input_required(outcome, context.client_capabilities)
955
+ reason = projection.unsupported_content(protocol, outcome["content"])
956
+ if reason is not None:
957
+ return fail(InvalidParams(reason))
958
+ return succeed(projection.call_tool_result(protocol, outcome))
959
+
960
+ def checked(request: Option[ServerRequest]) -> Effect[Wire, McpError, RequestServices]:
961
+ if protocol.is_stateless and request is not None:
962
+ mismatch = param_headers.mismatch(
963
+ found.tool["inputSchema"], call.get("arguments"), request.value.headers
964
+ )
965
+ if mismatch is not None:
966
+ return fail_with_http_status(
967
+ 400, ProtocolError(mismatch, error_code=HEADER_MISMATCH_ERROR_CODE)
968
+ )
969
+ return called.flat_map(on_wire)
970
+
971
+ return service_option(HttpServerRequest).flat_map(checked)
972
+
973
+
974
+ def _input_required(
975
+ outcome: InputRequired, capabilities: ClientCapabilities
976
+ ) -> Effect[Wire, McpError]:
977
+ """``outcome`` on the 2026-07-28 wire, once the client can answer it."""
978
+
979
+ @gen
980
+ def run():
981
+ wire = _InputRequired()
982
+ requests = outcome.input_requests
983
+ required = reverse_policy.required_input_capabilities(requests, capabilities)
984
+ if required:
985
+ return (
986
+ yield from fail_with_http_status(
987
+ 400,
988
+ ProtocolError(
989
+ "The request requires client capabilities that were not declared",
990
+ {"requiredCapabilities": required},
991
+ error_code=MISSING_REQUIRED_CLIENT_CAPABILITY_ERROR_CODE,
992
+ ),
993
+ )
994
+ )
995
+ if requests is not None:
996
+ wire["inputRequests"] = yield from _decode_input_requests(requests).map_error(
997
+ lambda _: InternalError(_FEATURE_HANDLER_FAILED)
998
+ )
999
+ if outcome.request_state is not None:
1000
+ wire["requestState"] = outcome.request_state
1001
+ return wire
1002
+
1003
+ return run
1004
+
1005
+
1006
+ def _wire(value: Mapping[str, Any]) -> Wire:
1007
+ return dict(value)
1008
+
1009
+
1010
+ def _prompt_on_wire(
1011
+ protocol: AnyProtocolAdapter, identity: Identity, result: GetPromptResult | InputRequired
1012
+ ) -> Effect[Wire, McpError]:
1013
+ if isinstance(result, InputRequired):
1014
+ if not protocol.is_stateless:
1015
+ return fail(InternalError(_FEATURE_HANDLER_FAILED))
1016
+ return _input_required(result, identity.capabilities)
1017
+ reason = projection.unsupported_content(protocol, [m["content"] for m in result["messages"]])
1018
+ if reason is not None:
1019
+ return fail(InvalidParams(reason))
1020
+ return succeed(projection.get_prompt_result(protocol, result))
1021
+
1022
+
1023
+ _is_implementation = S.is_(IMPLEMENTATION)
1024
+ _decode_input_requests = S.decode_unknown_effect(INPUT_REQUESTS)
1025
+
1026
+
1027
+ def _extensions(
1028
+ protocol: AnyProtocolAdapter, extensions: Mapping[str, Any] | None
1029
+ ) -> dict[str, Any]:
1030
+ """The extension settings ``protocol`` can advertise: on 2026-07-28 only
1031
+ JSON objects, so a legacy scalar setting cannot break discovery."""
1032
+ if extensions is None:
1033
+ return {}
1034
+ if not protocol.is_stateless:
1035
+ return dict(extensions)
1036
+ return {name: value for name, value in extensions.items() if isinstance(value, dict)}
1037
+
1038
+
1039
+ def _offers_stateless(registry: Registry) -> bool:
1040
+ return any(p.is_stateless for p in registry.protocols)
1041
+
1042
+
1043
+ def _unsupported_version(requested: str, registry: Registry) -> McpError:
1044
+ return ProtocolError(
1045
+ "Unsupported protocol version",
1046
+ {"requested": requested, "supported": list(registry.versions)},
1047
+ error_code=UNSUPPORTED_PROTOCOL_VERSION_ERROR_CODE,
1048
+ )