PraisonAI 3.0.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 (393) hide show
  1. praisonai/__init__.py +54 -0
  2. praisonai/__main__.py +15 -0
  3. praisonai/acp/__init__.py +54 -0
  4. praisonai/acp/config.py +159 -0
  5. praisonai/acp/server.py +587 -0
  6. praisonai/acp/session.py +219 -0
  7. praisonai/adapters/__init__.py +50 -0
  8. praisonai/adapters/readers.py +395 -0
  9. praisonai/adapters/rerankers.py +315 -0
  10. praisonai/adapters/retrievers.py +394 -0
  11. praisonai/adapters/vector_stores.py +409 -0
  12. praisonai/agent_scheduler.py +337 -0
  13. praisonai/agents_generator.py +903 -0
  14. praisonai/api/call.py +292 -0
  15. praisonai/auto.py +1197 -0
  16. praisonai/capabilities/__init__.py +275 -0
  17. praisonai/capabilities/a2a.py +140 -0
  18. praisonai/capabilities/assistants.py +283 -0
  19. praisonai/capabilities/audio.py +320 -0
  20. praisonai/capabilities/batches.py +469 -0
  21. praisonai/capabilities/completions.py +336 -0
  22. praisonai/capabilities/container_files.py +155 -0
  23. praisonai/capabilities/containers.py +93 -0
  24. praisonai/capabilities/embeddings.py +158 -0
  25. praisonai/capabilities/files.py +467 -0
  26. praisonai/capabilities/fine_tuning.py +293 -0
  27. praisonai/capabilities/guardrails.py +182 -0
  28. praisonai/capabilities/images.py +330 -0
  29. praisonai/capabilities/mcp.py +190 -0
  30. praisonai/capabilities/messages.py +270 -0
  31. praisonai/capabilities/moderations.py +154 -0
  32. praisonai/capabilities/ocr.py +217 -0
  33. praisonai/capabilities/passthrough.py +204 -0
  34. praisonai/capabilities/rag.py +207 -0
  35. praisonai/capabilities/realtime.py +160 -0
  36. praisonai/capabilities/rerank.py +165 -0
  37. praisonai/capabilities/responses.py +266 -0
  38. praisonai/capabilities/search.py +109 -0
  39. praisonai/capabilities/skills.py +133 -0
  40. praisonai/capabilities/vector_store_files.py +334 -0
  41. praisonai/capabilities/vector_stores.py +304 -0
  42. praisonai/capabilities/videos.py +141 -0
  43. praisonai/chainlit_ui.py +304 -0
  44. praisonai/chat/__init__.py +106 -0
  45. praisonai/chat/app.py +125 -0
  46. praisonai/cli/__init__.py +26 -0
  47. praisonai/cli/app.py +213 -0
  48. praisonai/cli/commands/__init__.py +75 -0
  49. praisonai/cli/commands/acp.py +70 -0
  50. praisonai/cli/commands/completion.py +333 -0
  51. praisonai/cli/commands/config.py +166 -0
  52. praisonai/cli/commands/debug.py +142 -0
  53. praisonai/cli/commands/diag.py +55 -0
  54. praisonai/cli/commands/doctor.py +166 -0
  55. praisonai/cli/commands/environment.py +179 -0
  56. praisonai/cli/commands/lsp.py +112 -0
  57. praisonai/cli/commands/mcp.py +210 -0
  58. praisonai/cli/commands/profile.py +457 -0
  59. praisonai/cli/commands/run.py +228 -0
  60. praisonai/cli/commands/schedule.py +150 -0
  61. praisonai/cli/commands/serve.py +97 -0
  62. praisonai/cli/commands/session.py +212 -0
  63. praisonai/cli/commands/traces.py +145 -0
  64. praisonai/cli/commands/version.py +101 -0
  65. praisonai/cli/configuration/__init__.py +18 -0
  66. praisonai/cli/configuration/loader.py +353 -0
  67. praisonai/cli/configuration/paths.py +114 -0
  68. praisonai/cli/configuration/schema.py +164 -0
  69. praisonai/cli/features/__init__.py +268 -0
  70. praisonai/cli/features/acp.py +236 -0
  71. praisonai/cli/features/action_orchestrator.py +546 -0
  72. praisonai/cli/features/agent_scheduler.py +773 -0
  73. praisonai/cli/features/agent_tools.py +474 -0
  74. praisonai/cli/features/agents.py +375 -0
  75. praisonai/cli/features/at_mentions.py +471 -0
  76. praisonai/cli/features/auto_memory.py +182 -0
  77. praisonai/cli/features/autonomy_mode.py +490 -0
  78. praisonai/cli/features/background.py +356 -0
  79. praisonai/cli/features/base.py +168 -0
  80. praisonai/cli/features/capabilities.py +1326 -0
  81. praisonai/cli/features/checkpoints.py +338 -0
  82. praisonai/cli/features/code_intelligence.py +652 -0
  83. praisonai/cli/features/compaction.py +294 -0
  84. praisonai/cli/features/compare.py +534 -0
  85. praisonai/cli/features/cost_tracker.py +514 -0
  86. praisonai/cli/features/debug.py +810 -0
  87. praisonai/cli/features/deploy.py +517 -0
  88. praisonai/cli/features/diag.py +289 -0
  89. praisonai/cli/features/doctor/__init__.py +63 -0
  90. praisonai/cli/features/doctor/checks/__init__.py +24 -0
  91. praisonai/cli/features/doctor/checks/acp_checks.py +240 -0
  92. praisonai/cli/features/doctor/checks/config_checks.py +366 -0
  93. praisonai/cli/features/doctor/checks/db_checks.py +366 -0
  94. praisonai/cli/features/doctor/checks/env_checks.py +543 -0
  95. praisonai/cli/features/doctor/checks/lsp_checks.py +199 -0
  96. praisonai/cli/features/doctor/checks/mcp_checks.py +349 -0
  97. praisonai/cli/features/doctor/checks/memory_checks.py +268 -0
  98. praisonai/cli/features/doctor/checks/network_checks.py +251 -0
  99. praisonai/cli/features/doctor/checks/obs_checks.py +328 -0
  100. praisonai/cli/features/doctor/checks/performance_checks.py +235 -0
  101. praisonai/cli/features/doctor/checks/permissions_checks.py +259 -0
  102. praisonai/cli/features/doctor/checks/selftest_checks.py +322 -0
  103. praisonai/cli/features/doctor/checks/serve_checks.py +426 -0
  104. praisonai/cli/features/doctor/checks/skills_checks.py +231 -0
  105. praisonai/cli/features/doctor/checks/tools_checks.py +371 -0
  106. praisonai/cli/features/doctor/engine.py +266 -0
  107. praisonai/cli/features/doctor/formatters.py +310 -0
  108. praisonai/cli/features/doctor/handler.py +397 -0
  109. praisonai/cli/features/doctor/models.py +264 -0
  110. praisonai/cli/features/doctor/registry.py +239 -0
  111. praisonai/cli/features/endpoints.py +1019 -0
  112. praisonai/cli/features/eval.py +560 -0
  113. praisonai/cli/features/external_agents.py +231 -0
  114. praisonai/cli/features/fast_context.py +410 -0
  115. praisonai/cli/features/flow_display.py +566 -0
  116. praisonai/cli/features/git_integration.py +651 -0
  117. praisonai/cli/features/guardrail.py +171 -0
  118. praisonai/cli/features/handoff.py +185 -0
  119. praisonai/cli/features/hooks.py +583 -0
  120. praisonai/cli/features/image.py +384 -0
  121. praisonai/cli/features/interactive_runtime.py +585 -0
  122. praisonai/cli/features/interactive_tools.py +380 -0
  123. praisonai/cli/features/interactive_tui.py +603 -0
  124. praisonai/cli/features/jobs.py +632 -0
  125. praisonai/cli/features/knowledge.py +531 -0
  126. praisonai/cli/features/lite.py +244 -0
  127. praisonai/cli/features/lsp_cli.py +225 -0
  128. praisonai/cli/features/mcp.py +169 -0
  129. praisonai/cli/features/message_queue.py +587 -0
  130. praisonai/cli/features/metrics.py +211 -0
  131. praisonai/cli/features/n8n.py +673 -0
  132. praisonai/cli/features/observability.py +293 -0
  133. praisonai/cli/features/ollama.py +361 -0
  134. praisonai/cli/features/output_style.py +273 -0
  135. praisonai/cli/features/package.py +631 -0
  136. praisonai/cli/features/performance.py +308 -0
  137. praisonai/cli/features/persistence.py +636 -0
  138. praisonai/cli/features/profile.py +226 -0
  139. praisonai/cli/features/profiler/__init__.py +81 -0
  140. praisonai/cli/features/profiler/core.py +558 -0
  141. praisonai/cli/features/profiler/optimizations.py +652 -0
  142. praisonai/cli/features/profiler/suite.py +386 -0
  143. praisonai/cli/features/profiling.py +350 -0
  144. praisonai/cli/features/queue/__init__.py +73 -0
  145. praisonai/cli/features/queue/manager.py +395 -0
  146. praisonai/cli/features/queue/models.py +286 -0
  147. praisonai/cli/features/queue/persistence.py +564 -0
  148. praisonai/cli/features/queue/scheduler.py +484 -0
  149. praisonai/cli/features/queue/worker.py +372 -0
  150. praisonai/cli/features/recipe.py +1723 -0
  151. praisonai/cli/features/recipes.py +449 -0
  152. praisonai/cli/features/registry.py +229 -0
  153. praisonai/cli/features/repo_map.py +860 -0
  154. praisonai/cli/features/router.py +466 -0
  155. praisonai/cli/features/sandbox_executor.py +515 -0
  156. praisonai/cli/features/serve.py +829 -0
  157. praisonai/cli/features/session.py +222 -0
  158. praisonai/cli/features/skills.py +856 -0
  159. praisonai/cli/features/slash_commands.py +650 -0
  160. praisonai/cli/features/telemetry.py +179 -0
  161. praisonai/cli/features/templates.py +1384 -0
  162. praisonai/cli/features/thinking.py +305 -0
  163. praisonai/cli/features/todo.py +334 -0
  164. praisonai/cli/features/tools.py +680 -0
  165. praisonai/cli/features/tui/__init__.py +83 -0
  166. praisonai/cli/features/tui/app.py +580 -0
  167. praisonai/cli/features/tui/cli.py +566 -0
  168. praisonai/cli/features/tui/debug.py +511 -0
  169. praisonai/cli/features/tui/events.py +99 -0
  170. praisonai/cli/features/tui/mock_provider.py +328 -0
  171. praisonai/cli/features/tui/orchestrator.py +652 -0
  172. praisonai/cli/features/tui/screens/__init__.py +50 -0
  173. praisonai/cli/features/tui/screens/main.py +245 -0
  174. praisonai/cli/features/tui/screens/queue.py +174 -0
  175. praisonai/cli/features/tui/screens/session.py +124 -0
  176. praisonai/cli/features/tui/screens/settings.py +148 -0
  177. praisonai/cli/features/tui/widgets/__init__.py +56 -0
  178. praisonai/cli/features/tui/widgets/chat.py +261 -0
  179. praisonai/cli/features/tui/widgets/composer.py +224 -0
  180. praisonai/cli/features/tui/widgets/queue_panel.py +200 -0
  181. praisonai/cli/features/tui/widgets/status.py +167 -0
  182. praisonai/cli/features/tui/widgets/tool_panel.py +248 -0
  183. praisonai/cli/features/workflow.py +720 -0
  184. praisonai/cli/legacy.py +236 -0
  185. praisonai/cli/main.py +5559 -0
  186. praisonai/cli/schedule_cli.py +54 -0
  187. praisonai/cli/state/__init__.py +31 -0
  188. praisonai/cli/state/identifiers.py +161 -0
  189. praisonai/cli/state/sessions.py +313 -0
  190. praisonai/code/__init__.py +93 -0
  191. praisonai/code/agent_tools.py +344 -0
  192. praisonai/code/diff/__init__.py +21 -0
  193. praisonai/code/diff/diff_strategy.py +432 -0
  194. praisonai/code/tools/__init__.py +27 -0
  195. praisonai/code/tools/apply_diff.py +221 -0
  196. praisonai/code/tools/execute_command.py +275 -0
  197. praisonai/code/tools/list_files.py +274 -0
  198. praisonai/code/tools/read_file.py +206 -0
  199. praisonai/code/tools/search_replace.py +248 -0
  200. praisonai/code/tools/write_file.py +217 -0
  201. praisonai/code/utils/__init__.py +46 -0
  202. praisonai/code/utils/file_utils.py +307 -0
  203. praisonai/code/utils/ignore_utils.py +308 -0
  204. praisonai/code/utils/text_utils.py +276 -0
  205. praisonai/db/__init__.py +64 -0
  206. praisonai/db/adapter.py +531 -0
  207. praisonai/deploy/__init__.py +62 -0
  208. praisonai/deploy/api.py +231 -0
  209. praisonai/deploy/docker.py +454 -0
  210. praisonai/deploy/doctor.py +367 -0
  211. praisonai/deploy/main.py +327 -0
  212. praisonai/deploy/models.py +179 -0
  213. praisonai/deploy/providers/__init__.py +33 -0
  214. praisonai/deploy/providers/aws.py +331 -0
  215. praisonai/deploy/providers/azure.py +358 -0
  216. praisonai/deploy/providers/base.py +101 -0
  217. praisonai/deploy/providers/gcp.py +314 -0
  218. praisonai/deploy/schema.py +208 -0
  219. praisonai/deploy.py +185 -0
  220. praisonai/endpoints/__init__.py +53 -0
  221. praisonai/endpoints/a2u_server.py +410 -0
  222. praisonai/endpoints/discovery.py +165 -0
  223. praisonai/endpoints/providers/__init__.py +28 -0
  224. praisonai/endpoints/providers/a2a.py +253 -0
  225. praisonai/endpoints/providers/a2u.py +208 -0
  226. praisonai/endpoints/providers/agents_api.py +171 -0
  227. praisonai/endpoints/providers/base.py +231 -0
  228. praisonai/endpoints/providers/mcp.py +263 -0
  229. praisonai/endpoints/providers/recipe.py +206 -0
  230. praisonai/endpoints/providers/tools_mcp.py +150 -0
  231. praisonai/endpoints/registry.py +131 -0
  232. praisonai/endpoints/server.py +161 -0
  233. praisonai/inbuilt_tools/__init__.py +24 -0
  234. praisonai/inbuilt_tools/autogen_tools.py +117 -0
  235. praisonai/inc/__init__.py +2 -0
  236. praisonai/inc/config.py +96 -0
  237. praisonai/inc/models.py +155 -0
  238. praisonai/integrations/__init__.py +56 -0
  239. praisonai/integrations/base.py +303 -0
  240. praisonai/integrations/claude_code.py +270 -0
  241. praisonai/integrations/codex_cli.py +255 -0
  242. praisonai/integrations/cursor_cli.py +195 -0
  243. praisonai/integrations/gemini_cli.py +222 -0
  244. praisonai/jobs/__init__.py +67 -0
  245. praisonai/jobs/executor.py +425 -0
  246. praisonai/jobs/models.py +230 -0
  247. praisonai/jobs/router.py +314 -0
  248. praisonai/jobs/server.py +186 -0
  249. praisonai/jobs/store.py +203 -0
  250. praisonai/llm/__init__.py +66 -0
  251. praisonai/llm/registry.py +382 -0
  252. praisonai/mcp_server/__init__.py +152 -0
  253. praisonai/mcp_server/adapters/__init__.py +74 -0
  254. praisonai/mcp_server/adapters/agents.py +128 -0
  255. praisonai/mcp_server/adapters/capabilities.py +168 -0
  256. praisonai/mcp_server/adapters/cli_tools.py +568 -0
  257. praisonai/mcp_server/adapters/extended_capabilities.py +462 -0
  258. praisonai/mcp_server/adapters/knowledge.py +93 -0
  259. praisonai/mcp_server/adapters/memory.py +104 -0
  260. praisonai/mcp_server/adapters/prompts.py +306 -0
  261. praisonai/mcp_server/adapters/resources.py +124 -0
  262. praisonai/mcp_server/adapters/tools_bridge.py +280 -0
  263. praisonai/mcp_server/auth/__init__.py +48 -0
  264. praisonai/mcp_server/auth/api_key.py +291 -0
  265. praisonai/mcp_server/auth/oauth.py +460 -0
  266. praisonai/mcp_server/auth/oidc.py +289 -0
  267. praisonai/mcp_server/auth/scopes.py +260 -0
  268. praisonai/mcp_server/cli.py +852 -0
  269. praisonai/mcp_server/elicitation.py +445 -0
  270. praisonai/mcp_server/icons.py +302 -0
  271. praisonai/mcp_server/recipe_adapter.py +573 -0
  272. praisonai/mcp_server/recipe_cli.py +824 -0
  273. praisonai/mcp_server/registry.py +703 -0
  274. praisonai/mcp_server/sampling.py +422 -0
  275. praisonai/mcp_server/server.py +490 -0
  276. praisonai/mcp_server/tasks.py +443 -0
  277. praisonai/mcp_server/transports/__init__.py +18 -0
  278. praisonai/mcp_server/transports/http_stream.py +376 -0
  279. praisonai/mcp_server/transports/stdio.py +132 -0
  280. praisonai/persistence/__init__.py +84 -0
  281. praisonai/persistence/config.py +238 -0
  282. praisonai/persistence/conversation/__init__.py +25 -0
  283. praisonai/persistence/conversation/async_mysql.py +427 -0
  284. praisonai/persistence/conversation/async_postgres.py +410 -0
  285. praisonai/persistence/conversation/async_sqlite.py +371 -0
  286. praisonai/persistence/conversation/base.py +151 -0
  287. praisonai/persistence/conversation/json_store.py +250 -0
  288. praisonai/persistence/conversation/mysql.py +387 -0
  289. praisonai/persistence/conversation/postgres.py +401 -0
  290. praisonai/persistence/conversation/singlestore.py +240 -0
  291. praisonai/persistence/conversation/sqlite.py +341 -0
  292. praisonai/persistence/conversation/supabase.py +203 -0
  293. praisonai/persistence/conversation/surrealdb.py +287 -0
  294. praisonai/persistence/factory.py +301 -0
  295. praisonai/persistence/hooks/__init__.py +18 -0
  296. praisonai/persistence/hooks/agent_hooks.py +297 -0
  297. praisonai/persistence/knowledge/__init__.py +26 -0
  298. praisonai/persistence/knowledge/base.py +144 -0
  299. praisonai/persistence/knowledge/cassandra.py +232 -0
  300. praisonai/persistence/knowledge/chroma.py +295 -0
  301. praisonai/persistence/knowledge/clickhouse.py +242 -0
  302. praisonai/persistence/knowledge/cosmosdb_vector.py +438 -0
  303. praisonai/persistence/knowledge/couchbase.py +286 -0
  304. praisonai/persistence/knowledge/lancedb.py +216 -0
  305. praisonai/persistence/knowledge/langchain_adapter.py +291 -0
  306. praisonai/persistence/knowledge/lightrag_adapter.py +212 -0
  307. praisonai/persistence/knowledge/llamaindex_adapter.py +256 -0
  308. praisonai/persistence/knowledge/milvus.py +277 -0
  309. praisonai/persistence/knowledge/mongodb_vector.py +306 -0
  310. praisonai/persistence/knowledge/pgvector.py +335 -0
  311. praisonai/persistence/knowledge/pinecone.py +253 -0
  312. praisonai/persistence/knowledge/qdrant.py +301 -0
  313. praisonai/persistence/knowledge/redis_vector.py +291 -0
  314. praisonai/persistence/knowledge/singlestore_vector.py +299 -0
  315. praisonai/persistence/knowledge/surrealdb_vector.py +309 -0
  316. praisonai/persistence/knowledge/upstash_vector.py +266 -0
  317. praisonai/persistence/knowledge/weaviate.py +223 -0
  318. praisonai/persistence/migrations/__init__.py +10 -0
  319. praisonai/persistence/migrations/manager.py +251 -0
  320. praisonai/persistence/orchestrator.py +406 -0
  321. praisonai/persistence/state/__init__.py +21 -0
  322. praisonai/persistence/state/async_mongodb.py +200 -0
  323. praisonai/persistence/state/base.py +107 -0
  324. praisonai/persistence/state/dynamodb.py +226 -0
  325. praisonai/persistence/state/firestore.py +175 -0
  326. praisonai/persistence/state/gcs.py +155 -0
  327. praisonai/persistence/state/memory.py +245 -0
  328. praisonai/persistence/state/mongodb.py +158 -0
  329. praisonai/persistence/state/redis.py +190 -0
  330. praisonai/persistence/state/upstash.py +144 -0
  331. praisonai/persistence/tests/__init__.py +3 -0
  332. praisonai/persistence/tests/test_all_backends.py +633 -0
  333. praisonai/profiler.py +1214 -0
  334. praisonai/recipe/__init__.py +134 -0
  335. praisonai/recipe/bridge.py +278 -0
  336. praisonai/recipe/core.py +893 -0
  337. praisonai/recipe/exceptions.py +54 -0
  338. praisonai/recipe/history.py +402 -0
  339. praisonai/recipe/models.py +266 -0
  340. praisonai/recipe/operations.py +440 -0
  341. praisonai/recipe/policy.py +422 -0
  342. praisonai/recipe/registry.py +849 -0
  343. praisonai/recipe/runtime.py +214 -0
  344. praisonai/recipe/security.py +711 -0
  345. praisonai/recipe/serve.py +859 -0
  346. praisonai/recipe/server.py +613 -0
  347. praisonai/scheduler/__init__.py +45 -0
  348. praisonai/scheduler/agent_scheduler.py +552 -0
  349. praisonai/scheduler/base.py +124 -0
  350. praisonai/scheduler/daemon_manager.py +225 -0
  351. praisonai/scheduler/state_manager.py +155 -0
  352. praisonai/scheduler/yaml_loader.py +193 -0
  353. praisonai/scheduler.py +194 -0
  354. praisonai/setup/__init__.py +1 -0
  355. praisonai/setup/build.py +21 -0
  356. praisonai/setup/post_install.py +23 -0
  357. praisonai/setup/setup_conda_env.py +25 -0
  358. praisonai/setup.py +16 -0
  359. praisonai/templates/__init__.py +116 -0
  360. praisonai/templates/cache.py +364 -0
  361. praisonai/templates/dependency_checker.py +358 -0
  362. praisonai/templates/discovery.py +391 -0
  363. praisonai/templates/loader.py +564 -0
  364. praisonai/templates/registry.py +511 -0
  365. praisonai/templates/resolver.py +206 -0
  366. praisonai/templates/security.py +327 -0
  367. praisonai/templates/tool_override.py +498 -0
  368. praisonai/templates/tools_doctor.py +256 -0
  369. praisonai/test.py +105 -0
  370. praisonai/train.py +562 -0
  371. praisonai/train_vision.py +306 -0
  372. praisonai/ui/agents.py +824 -0
  373. praisonai/ui/callbacks.py +57 -0
  374. praisonai/ui/chainlit_compat.py +246 -0
  375. praisonai/ui/chat.py +532 -0
  376. praisonai/ui/code.py +717 -0
  377. praisonai/ui/colab.py +474 -0
  378. praisonai/ui/colab_chainlit.py +81 -0
  379. praisonai/ui/components/aicoder.py +284 -0
  380. praisonai/ui/context.py +283 -0
  381. praisonai/ui/database_config.py +56 -0
  382. praisonai/ui/db.py +294 -0
  383. praisonai/ui/realtime.py +488 -0
  384. praisonai/ui/realtimeclient/__init__.py +756 -0
  385. praisonai/ui/realtimeclient/tools.py +242 -0
  386. praisonai/ui/sql_alchemy.py +710 -0
  387. praisonai/upload_vision.py +140 -0
  388. praisonai/version.py +1 -0
  389. praisonai-3.0.0.dist-info/METADATA +3493 -0
  390. praisonai-3.0.0.dist-info/RECORD +393 -0
  391. praisonai-3.0.0.dist-info/WHEEL +5 -0
  392. praisonai-3.0.0.dist-info/entry_points.txt +4 -0
  393. praisonai-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,134 @@
1
+ """
2
+ PraisonAI Recipe Module
3
+
4
+ Provides a minimal, client-friendly API for running Agent Recipes.
5
+ All imports are lazy to ensure zero performance impact on Core SDK.
6
+
7
+ Usage:
8
+ from praisonai import recipe
9
+ result = recipe.run("support-reply-drafter", input={"ticket": "T-123"})
10
+
11
+ # Or with streaming
12
+ for event in recipe.run_stream("transcript-generator", input="audio.mp3"):
13
+ print(event)
14
+ """
15
+
16
+ __all__ = [
17
+ # Core API
18
+ "run",
19
+ "run_stream",
20
+ "validate",
21
+ "list_recipes",
22
+ "describe",
23
+ # Runtime Bridge API
24
+ "resolve",
25
+ "run_background",
26
+ "submit_job",
27
+ "schedule",
28
+ # Data classes
29
+ "RecipeResult",
30
+ "RecipeEvent",
31
+ "RecipeConfig",
32
+ "ResolvedRecipe",
33
+ "RuntimeConfig",
34
+ # Exceptions
35
+ "RecipeError",
36
+ "RecipeNotFoundError",
37
+ "RecipeDependencyError",
38
+ "RecipePolicyError",
39
+ "RecipeValidationError",
40
+ # Exit codes
41
+ "ExitCode",
42
+ ]
43
+
44
+ # Lazy loading implementation
45
+ _module_cache = {}
46
+
47
+
48
+ def __getattr__(name):
49
+ """Lazy load recipe components."""
50
+ if name in _module_cache:
51
+ return _module_cache[name]
52
+
53
+ if name == "run":
54
+ from .core import run
55
+ _module_cache[name] = run
56
+ return run
57
+ elif name == "run_stream":
58
+ from .core import run_stream
59
+ _module_cache[name] = run_stream
60
+ return run_stream
61
+ elif name == "validate":
62
+ from .core import validate
63
+ _module_cache[name] = validate
64
+ return validate
65
+ elif name == "list_recipes":
66
+ from .core import list_recipes
67
+ _module_cache[name] = list_recipes
68
+ return list_recipes
69
+ elif name == "describe":
70
+ from .core import describe
71
+ _module_cache[name] = describe
72
+ return describe
73
+ elif name == "RecipeResult":
74
+ from .models import RecipeResult
75
+ _module_cache[name] = RecipeResult
76
+ return RecipeResult
77
+ elif name == "RecipeEvent":
78
+ from .models import RecipeEvent
79
+ _module_cache[name] = RecipeEvent
80
+ return RecipeEvent
81
+ elif name == "RecipeConfig":
82
+ from .models import RecipeConfig
83
+ _module_cache[name] = RecipeConfig
84
+ return RecipeConfig
85
+ elif name == "RecipeError":
86
+ from .exceptions import RecipeError
87
+ _module_cache[name] = RecipeError
88
+ return RecipeError
89
+ elif name == "RecipeNotFoundError":
90
+ from .exceptions import RecipeNotFoundError
91
+ _module_cache[name] = RecipeNotFoundError
92
+ return RecipeNotFoundError
93
+ elif name == "RecipeDependencyError":
94
+ from .exceptions import RecipeDependencyError
95
+ _module_cache[name] = RecipeDependencyError
96
+ return RecipeDependencyError
97
+ elif name == "RecipePolicyError":
98
+ from .exceptions import RecipePolicyError
99
+ _module_cache[name] = RecipePolicyError
100
+ return RecipePolicyError
101
+ elif name == "RecipeValidationError":
102
+ from .exceptions import RecipeValidationError
103
+ _module_cache[name] = RecipeValidationError
104
+ return RecipeValidationError
105
+ elif name == "ExitCode":
106
+ from .models import ExitCode
107
+ _module_cache[name] = ExitCode
108
+ return ExitCode
109
+ elif name == "resolve":
110
+ from .bridge import resolve
111
+ _module_cache[name] = resolve
112
+ return resolve
113
+ elif name == "run_background":
114
+ from .operations import run_background
115
+ _module_cache[name] = run_background
116
+ return run_background
117
+ elif name == "submit_job":
118
+ from .operations import submit_job
119
+ _module_cache[name] = submit_job
120
+ return submit_job
121
+ elif name == "schedule":
122
+ from .operations import schedule
123
+ _module_cache[name] = schedule
124
+ return schedule
125
+ elif name == "ResolvedRecipe":
126
+ from .bridge import ResolvedRecipe
127
+ _module_cache[name] = ResolvedRecipe
128
+ return ResolvedRecipe
129
+ elif name == "RuntimeConfig":
130
+ from .runtime import RuntimeConfig
131
+ _module_cache[name] = RuntimeConfig
132
+ return RuntimeConfig
133
+
134
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -0,0 +1,278 @@
1
+ """
2
+ Recipe Runtime Bridge.
3
+
4
+ Provides unified recipe resolution and execution for operational runtimes:
5
+ - Background tasks
6
+ - Async jobs
7
+ - Scheduled execution
8
+
9
+ This module bridges the gap between recipes and operational features,
10
+ keeping all glue code in the wrapper (praisonai) without modifying core SDK.
11
+ """
12
+
13
+ import uuid
14
+ import logging
15
+ from dataclasses import dataclass, field
16
+ from pathlib import Path
17
+ from typing import Any, Dict, Iterator, List, Optional
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ @dataclass
23
+ class ResolvedRecipe:
24
+ """
25
+ A fully resolved recipe ready for execution.
26
+
27
+ Contains all information needed to execute a recipe in any runtime mode.
28
+ """
29
+ name: str
30
+ version: str
31
+ description: str
32
+ path: Path
33
+
34
+ # Workflow/agents configuration
35
+ workflow_config: Dict[str, Any] = field(default_factory=dict)
36
+ agents_config: Dict[str, Any] = field(default_factory=dict)
37
+
38
+ # User-provided input and config
39
+ input_data: Any = None
40
+ config: Dict[str, Any] = field(default_factory=dict)
41
+
42
+ # Runtime configuration
43
+ runtime_config: Optional[Any] = None # RuntimeConfig
44
+
45
+ # Execution context
46
+ session_id: Optional[str] = None
47
+ run_id: str = field(default_factory=lambda: f"run_{uuid.uuid4().hex[:12]}")
48
+
49
+ # Options
50
+ options: Dict[str, Any] = field(default_factory=dict)
51
+
52
+ def get_timeout_sec(self, default: int = 300) -> int:
53
+ """Get timeout from runtime config or options."""
54
+ if self.options.get('timeout_sec'):
55
+ return self.options['timeout_sec']
56
+ if self.runtime_config and hasattr(self.runtime_config, 'schedule'):
57
+ return self.runtime_config.schedule.timeout_sec
58
+ return default
59
+
60
+ def get_max_cost_usd(self, default: float = 1.00) -> float:
61
+ """Get max cost from runtime config or options."""
62
+ if self.options.get('max_cost_usd'):
63
+ return self.options['max_cost_usd']
64
+ if self.runtime_config and hasattr(self.runtime_config, 'schedule'):
65
+ return self.runtime_config.schedule.max_cost_usd
66
+ return default
67
+
68
+
69
+ def resolve(
70
+ name: str,
71
+ input_data: Any = None,
72
+ config: Optional[Dict[str, Any]] = None,
73
+ session_id: Optional[str] = None,
74
+ options: Optional[Dict[str, Any]] = None,
75
+ ) -> ResolvedRecipe:
76
+ """
77
+ Resolve a recipe name into a fully executable ResolvedRecipe.
78
+
79
+ Args:
80
+ name: Recipe name or path
81
+ input_data: User input for the recipe
82
+ config: Configuration overrides
83
+ session_id: Session ID for conversation continuity
84
+ options: Execution options (timeout_sec, verbose, etc.)
85
+
86
+ Returns:
87
+ ResolvedRecipe ready for execution
88
+
89
+ Raises:
90
+ RecipeNotFoundError: If recipe cannot be found
91
+ RecipeValidationError: If recipe is invalid
92
+ """
93
+ from praisonai.templates import TemplateLoader
94
+ from praisonai.recipe.exceptions import RecipeNotFoundError
95
+
96
+ options = options or {}
97
+ config = config or {}
98
+
99
+ loader = TemplateLoader(offline=options.get('offline', False))
100
+
101
+ try:
102
+ # Load template configuration
103
+ template_config = loader.load(name, config=config, offline=options.get('offline', False))
104
+ except Exception as e:
105
+ # Try to find similar recipes for helpful error message
106
+ try:
107
+ from praisonai.recipe.core import list_recipes
108
+ available = list_recipes()
109
+ suggestions = _find_similar_recipes(name, [r.name for r in available])
110
+ if suggestions:
111
+ raise RecipeNotFoundError(
112
+ f"Recipe '{name}' not found. Did you mean: {', '.join(suggestions[:3])}?"
113
+ )
114
+ except Exception:
115
+ pass
116
+ raise RecipeNotFoundError(f"Recipe '{name}' not found: {e}")
117
+
118
+ # Load workflow and agents configs
119
+ try:
120
+ workflow_config = loader.load_workflow_config(template_config)
121
+ except Exception:
122
+ workflow_config = {}
123
+
124
+ try:
125
+ agents_config = loader.load_agents_config(template_config)
126
+ except Exception:
127
+ agents_config = {}
128
+
129
+ # Generate session_id if not provided
130
+ if not session_id:
131
+ session_id = f"session_{uuid.uuid4().hex[:8]}"
132
+
133
+ return ResolvedRecipe(
134
+ name=template_config.name,
135
+ version=template_config.version,
136
+ description=template_config.description,
137
+ path=template_config.path,
138
+ workflow_config=workflow_config,
139
+ agents_config=agents_config,
140
+ input_data=input_data,
141
+ config={**template_config.defaults, **config},
142
+ runtime_config=template_config.runtime,
143
+ session_id=session_id,
144
+ options=options,
145
+ )
146
+
147
+
148
+ def execute_resolved_recipe(
149
+ resolved: ResolvedRecipe,
150
+ progress_callback: Optional[callable] = None,
151
+ ) -> Any:
152
+ """
153
+ Execute a resolved recipe and return the result.
154
+
155
+ This is the canonical execution function used by all runtime modes.
156
+
157
+ Args:
158
+ resolved: Resolved recipe to execute
159
+ progress_callback: Optional callback for progress updates
160
+
161
+ Returns:
162
+ Recipe execution result
163
+ """
164
+ from praisonai.recipe.core import run
165
+
166
+ # Build options dict
167
+ options = {
168
+ 'timeout_sec': resolved.get_timeout_sec(),
169
+ 'verbose': resolved.options.get('verbose', False),
170
+ 'dry_run': resolved.options.get('dry_run', False),
171
+ **resolved.options,
172
+ }
173
+
174
+ # Execute using core recipe.run
175
+ result = run(
176
+ resolved.name,
177
+ input=resolved.input_data,
178
+ config=resolved.config,
179
+ session_id=resolved.session_id,
180
+ options=options,
181
+ )
182
+
183
+ return result
184
+
185
+
186
+ def execute_resolved_recipe_stream(
187
+ resolved: ResolvedRecipe,
188
+ progress_callback: Optional[callable] = None,
189
+ ) -> Iterator[Any]:
190
+ """
191
+ Execute a resolved recipe with streaming output.
192
+
193
+ Args:
194
+ resolved: Resolved recipe to execute
195
+ progress_callback: Optional callback for progress updates
196
+
197
+ Yields:
198
+ RecipeEvent objects during execution
199
+ """
200
+ from praisonai.recipe.core import run_stream
201
+
202
+ # Build options dict
203
+ options = {
204
+ 'timeout_sec': resolved.get_timeout_sec(),
205
+ 'verbose': resolved.options.get('verbose', False),
206
+ **resolved.options,
207
+ }
208
+
209
+ # Execute using core recipe.run_stream
210
+ for event in run_stream(
211
+ resolved.name,
212
+ input=resolved.input_data,
213
+ config=resolved.config,
214
+ session_id=resolved.session_id,
215
+ options=options,
216
+ ):
217
+ if progress_callback:
218
+ try:
219
+ progress_callback(event)
220
+ except Exception as e:
221
+ logger.warning(f"Progress callback error: {e}")
222
+ yield event
223
+
224
+
225
+ def _find_similar_recipes(name: str, available: List[str], max_results: int = 5) -> List[str]:
226
+ """Find recipes with similar names using simple string matching."""
227
+ name_lower = name.lower()
228
+
229
+ # Exact prefix match
230
+ prefix_matches = [r for r in available if r.lower().startswith(name_lower)]
231
+
232
+ # Contains match
233
+ contains_matches = [r for r in available if name_lower in r.lower() and r not in prefix_matches]
234
+
235
+ # Levenshtein-like similarity (simplified)
236
+ def similarity(a: str, b: str) -> float:
237
+ a, b = a.lower(), b.lower()
238
+ if a == b:
239
+ return 1.0
240
+ if a in b or b in a:
241
+ return 0.8
242
+ # Count common characters
243
+ common = sum(1 for c in a if c in b)
244
+ return common / max(len(a), len(b))
245
+
246
+ other_matches = sorted(
247
+ [r for r in available if r not in prefix_matches and r not in contains_matches],
248
+ key=lambda r: similarity(name, r),
249
+ reverse=True
250
+ )
251
+
252
+ results = prefix_matches + contains_matches + other_matches
253
+ return results[:max_results]
254
+
255
+
256
+ # Convenience functions for different runtime modes
257
+
258
+ def get_recipe_task_description(resolved: ResolvedRecipe) -> str:
259
+ """Get a task description suitable for scheduler/background."""
260
+ if resolved.input_data:
261
+ if isinstance(resolved.input_data, str):
262
+ return resolved.input_data
263
+ elif isinstance(resolved.input_data, dict):
264
+ return str(resolved.input_data.get('prompt', resolved.input_data.get('task', str(resolved.input_data))))
265
+ return f"Execute recipe: {resolved.name}"
266
+
267
+
268
+ def get_recipe_metadata(resolved: ResolvedRecipe) -> Dict[str, Any]:
269
+ """Get metadata dict for job/scheduler state persistence."""
270
+ return {
271
+ 'recipe_name': resolved.name,
272
+ 'recipe_version': resolved.version,
273
+ 'recipe_path': str(resolved.path) if resolved.path else None,
274
+ 'session_id': resolved.session_id,
275
+ 'run_id': resolved.run_id,
276
+ 'config': resolved.config,
277
+ 'options': resolved.options,
278
+ }