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,206 @@
1
+ """
2
+ Recipe Provider
3
+
4
+ Provider adapter for recipe runner endpoints.
5
+ """
6
+
7
+ from typing import Any, Dict, Iterator, List, Optional
8
+
9
+ from .base import BaseProvider, InvokeResult, HealthResult
10
+ from ..discovery import EndpointInfo, ProviderInfo
11
+
12
+
13
+ class RecipeProvider(BaseProvider):
14
+ """
15
+ Provider adapter for recipe runner endpoints.
16
+
17
+ Connects to recipe runner server (Starlette-based) and provides
18
+ unified discovery and invocation interface.
19
+ """
20
+
21
+ provider_type = "recipe"
22
+
23
+ def get_provider_info(self) -> ProviderInfo:
24
+ """Get provider information."""
25
+ return ProviderInfo(
26
+ type=self.provider_type,
27
+ name="Recipe Runner",
28
+ description="Recipe execution endpoints",
29
+ capabilities=["list", "describe", "invoke", "stream", "validate"],
30
+ )
31
+
32
+ def list_endpoints(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
33
+ """List available recipe endpoints."""
34
+ path = "/v1/recipes"
35
+ if tags:
36
+ path += f"?tags={','.join(tags)}"
37
+
38
+ result = self._make_request("GET", path)
39
+
40
+ if result.get("error"):
41
+ return []
42
+
43
+ recipes = result.get("data", {}).get("recipes", [])
44
+ endpoints = []
45
+
46
+ for r in recipes:
47
+ endpoints.append(EndpointInfo(
48
+ name=r.get("name", ""),
49
+ description=r.get("description", ""),
50
+ provider_type=self.provider_type,
51
+ tags=r.get("tags", []),
52
+ version=r.get("version", "1.0.0"),
53
+ streaming=["none", "sse"],
54
+ auth_modes=["none", "api-key"],
55
+ ))
56
+
57
+ return endpoints
58
+
59
+ def describe_endpoint(self, name: str) -> Optional[EndpointInfo]:
60
+ """Get detailed information about a recipe endpoint."""
61
+ result = self._make_request("GET", f"/v1/recipes/{name}")
62
+
63
+ if result.get("status") == 404 or result.get("error"):
64
+ return None
65
+
66
+ data = result.get("data", {})
67
+
68
+ # Get schema
69
+ schema_result = self._make_request("GET", f"/v1/recipes/{name}/schema")
70
+ schema_data = schema_result.get("data", {}) if not schema_result.get("error") else {}
71
+
72
+ return EndpointInfo(
73
+ name=data.get("name", name),
74
+ description=data.get("description", ""),
75
+ provider_type=self.provider_type,
76
+ tags=data.get("tags", []),
77
+ version=data.get("version", "1.0.0"),
78
+ input_schema=schema_data.get("input_schema"),
79
+ output_schema=schema_data.get("output_schema"),
80
+ streaming=["none", "sse"],
81
+ auth_modes=["none", "api-key"],
82
+ metadata=data.get("metadata", {}),
83
+ )
84
+
85
+ def invoke(
86
+ self,
87
+ name: str,
88
+ input_data: Optional[Dict[str, Any]] = None,
89
+ config: Optional[Dict[str, Any]] = None,
90
+ stream: bool = False,
91
+ ) -> InvokeResult:
92
+ """Invoke a recipe endpoint."""
93
+ body = {
94
+ "recipe": name,
95
+ "input": input_data or {},
96
+ "config": config or {},
97
+ }
98
+
99
+ result = self._make_request("POST", "/v1/recipes/run", json_data=body)
100
+
101
+ if result.get("status") == 401:
102
+ return InvokeResult(
103
+ ok=False,
104
+ status="auth_error",
105
+ error="Authentication required",
106
+ )
107
+
108
+ if result.get("status") == 404:
109
+ return InvokeResult(
110
+ ok=False,
111
+ status="not_found",
112
+ error=f"Recipe not found: {name}",
113
+ )
114
+
115
+ if result.get("error"):
116
+ return InvokeResult(
117
+ ok=False,
118
+ status="error",
119
+ error=result["error"].get("message", str(result["error"])),
120
+ )
121
+
122
+ data = result.get("data", {})
123
+ return InvokeResult(
124
+ ok=data.get("ok", True),
125
+ status=data.get("status", "success"),
126
+ data=data.get("output"),
127
+ metadata={"run_id": data.get("run_id")},
128
+ )
129
+
130
+ def invoke_stream(
131
+ self,
132
+ name: str,
133
+ input_data: Optional[Dict[str, Any]] = None,
134
+ config: Optional[Dict[str, Any]] = None,
135
+ ) -> Iterator[Dict[str, Any]]:
136
+ """Invoke a recipe endpoint with streaming."""
137
+ import json
138
+ import urllib.request
139
+
140
+ body = {
141
+ "recipe": name,
142
+ "input": input_data or {},
143
+ "config": config or {},
144
+ }
145
+
146
+ full_url = f"{self.base_url}/v1/recipes/stream"
147
+
148
+ headers = {
149
+ "Content-Type": "application/json",
150
+ "Accept": "text/event-stream",
151
+ }
152
+ if self.api_key:
153
+ headers["X-API-Key"] = self.api_key
154
+
155
+ data = json.dumps(body).encode("utf-8")
156
+
157
+ try:
158
+ req = urllib.request.Request(full_url, data=data, headers=headers, method="POST")
159
+
160
+ with urllib.request.urlopen(req, timeout=300) as response:
161
+ buffer = ""
162
+ for line in response:
163
+ line = line.decode("utf-8")
164
+ buffer += line
165
+
166
+ if buffer.endswith("\n\n"):
167
+ event_type = "message"
168
+ event_data = ""
169
+
170
+ for part in buffer.strip().split("\n"):
171
+ if part.startswith("event:"):
172
+ event_type = part[6:].strip()
173
+ elif part.startswith("data:"):
174
+ event_data = part[5:].strip()
175
+
176
+ if event_data:
177
+ try:
178
+ yield {"event": event_type, "data": json.loads(event_data)}
179
+ except json.JSONDecodeError:
180
+ yield {"event": event_type, "data": event_data}
181
+
182
+ buffer = ""
183
+
184
+ except Exception as e:
185
+ yield {"event": "error", "data": {"error": str(e)}}
186
+
187
+ def health(self) -> HealthResult:
188
+ """Check recipe server health."""
189
+ result = self._make_request("GET", "/health")
190
+
191
+ if result.get("error"):
192
+ return HealthResult(
193
+ healthy=False,
194
+ status="unhealthy",
195
+ provider_type=self.provider_type,
196
+ metadata={"error": result["error"].get("message", str(result["error"]))},
197
+ )
198
+
199
+ data = result.get("data", {})
200
+ return HealthResult(
201
+ healthy=data.get("status") == "healthy",
202
+ status=data.get("status", "unknown"),
203
+ server_name=data.get("service"),
204
+ server_version=data.get("version"),
205
+ provider_type=self.provider_type,
206
+ )
@@ -0,0 +1,150 @@
1
+ """
2
+ Tools MCP Provider
3
+
4
+ Provider adapter for tools exposed as MCP server.
5
+ """
6
+
7
+ from typing import Any, Dict, Iterator, List, Optional
8
+
9
+ from .base import BaseProvider, InvokeResult, HealthResult
10
+ from ..discovery import EndpointInfo, ProviderInfo
11
+
12
+
13
+ class ToolsMCPProvider(BaseProvider):
14
+ """
15
+ Provider adapter for tools exposed as MCP server.
16
+
17
+ This provider connects to a ToolsMCPServer that exposes Python functions
18
+ as MCP tools.
19
+ """
20
+
21
+ provider_type = "tools-mcp"
22
+
23
+ def get_provider_info(self) -> ProviderInfo:
24
+ """Get provider information."""
25
+ return ProviderInfo(
26
+ type=self.provider_type,
27
+ name="Tools MCP Server",
28
+ description="Python tools exposed as MCP server",
29
+ capabilities=["list-tools", "call-tool"],
30
+ )
31
+
32
+ def list_endpoints(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
33
+ """List available tools as endpoints."""
34
+ # Try unified discovery first
35
+ result = self._make_request("GET", "/__praisonai__/discovery")
36
+
37
+ if not result.get("error") and result.get("data"):
38
+ data = result.get("data", {})
39
+ endpoints = []
40
+ for ep in data.get("endpoints", []):
41
+ if ep.get("provider_type") == self.provider_type:
42
+ endpoints.append(EndpointInfo(
43
+ name=ep.get("name", ""),
44
+ description=ep.get("description", ""),
45
+ provider_type=self.provider_type,
46
+ tags=ep.get("tags", []),
47
+ input_schema=ep.get("input_schema"),
48
+ streaming=ep.get("streaming", ["none"]),
49
+ auth_modes=ep.get("auth_modes", ["none"]),
50
+ ))
51
+ return endpoints
52
+
53
+ # Fallback: try tools endpoint
54
+ result = self._make_request("GET", "/tools")
55
+
56
+ if result.get("error"):
57
+ return []
58
+
59
+ tools = result.get("data", {}).get("tools", [])
60
+ endpoints = []
61
+
62
+ for tool in tools:
63
+ endpoints.append(EndpointInfo(
64
+ name=tool.get("name", ""),
65
+ description=tool.get("description", ""),
66
+ provider_type=self.provider_type,
67
+ input_schema=tool.get("input_schema"),
68
+ streaming=["none"],
69
+ auth_modes=["none"],
70
+ ))
71
+
72
+ return endpoints
73
+
74
+ def describe_endpoint(self, name: str) -> Optional[EndpointInfo]:
75
+ """Get detailed information about a tool."""
76
+ endpoints = self.list_endpoints()
77
+ for ep in endpoints:
78
+ if ep.name == name:
79
+ return ep
80
+ return None
81
+
82
+ def invoke(
83
+ self,
84
+ name: str,
85
+ input_data: Optional[Dict[str, Any]] = None,
86
+ config: Optional[Dict[str, Any]] = None,
87
+ stream: bool = False,
88
+ ) -> InvokeResult:
89
+ """Invoke a tool."""
90
+ body = {
91
+ "tool": name,
92
+ "arguments": input_data or {},
93
+ }
94
+
95
+ result = self._make_request("POST", "/tools/call", json_data=body)
96
+
97
+ if result.get("status") == 404:
98
+ return InvokeResult(
99
+ ok=False,
100
+ status="not_found",
101
+ error=f"Tool not found: {name}",
102
+ )
103
+
104
+ if result.get("error"):
105
+ return InvokeResult(
106
+ ok=False,
107
+ status="error",
108
+ error=result["error"].get("message", str(result["error"])),
109
+ )
110
+
111
+ data = result.get("data", {})
112
+ return InvokeResult(
113
+ ok=True,
114
+ status="success",
115
+ data=data.get("result", data),
116
+ )
117
+
118
+ def invoke_stream(
119
+ self,
120
+ name: str,
121
+ input_data: Optional[Dict[str, Any]] = None,
122
+ config: Optional[Dict[str, Any]] = None,
123
+ ) -> Iterator[Dict[str, Any]]:
124
+ """Invoke tool with streaming (wraps sync call)."""
125
+ result = self.invoke(name, input_data, config)
126
+ if result.ok:
127
+ yield {"event": "result", "data": result.data}
128
+ else:
129
+ yield {"event": "error", "data": {"error": result.error}}
130
+
131
+ def health(self) -> HealthResult:
132
+ """Check tools server health."""
133
+ result = self._make_request("GET", "/health")
134
+
135
+ if result.get("error"):
136
+ return HealthResult(
137
+ healthy=False,
138
+ status="unhealthy",
139
+ provider_type=self.provider_type,
140
+ metadata={"error": result["error"].get("message", str(result["error"]))},
141
+ )
142
+
143
+ data = result.get("data", {})
144
+ return HealthResult(
145
+ healthy=True,
146
+ status="healthy",
147
+ server_name=data.get("server_name", "Tools MCP Server"),
148
+ server_version=data.get("version"),
149
+ provider_type=self.provider_type,
150
+ )
@@ -0,0 +1,131 @@
1
+ """
2
+ Provider Registry
3
+
4
+ Central registry for provider adapters.
5
+ """
6
+
7
+ from typing import Dict, List, Optional, Type
8
+
9
+ from .providers.base import BaseProvider
10
+
11
+
12
+ # Global provider registry
13
+ _providers: Dict[str, Type[BaseProvider]] = {}
14
+
15
+
16
+ def register_provider(provider_type: str, provider_class: Type[BaseProvider]) -> None:
17
+ """
18
+ Register a provider class.
19
+
20
+ Args:
21
+ provider_type: Provider type identifier
22
+ provider_class: Provider class to register
23
+ """
24
+ _providers[provider_type] = provider_class
25
+
26
+
27
+ def get_provider(
28
+ provider_type: str,
29
+ base_url: str = "http://localhost:8765",
30
+ api_key: Optional[str] = None,
31
+ **kwargs,
32
+ ) -> Optional[BaseProvider]:
33
+ """
34
+ Get a provider instance by type.
35
+
36
+ Args:
37
+ provider_type: Provider type identifier
38
+ base_url: Base URL for the provider
39
+ api_key: Optional API key
40
+ **kwargs: Additional provider-specific arguments
41
+
42
+ Returns:
43
+ Provider instance or None if not found
44
+ """
45
+ # Lazy register built-in providers
46
+ _ensure_providers_registered()
47
+
48
+ if provider_type not in _providers:
49
+ return None
50
+
51
+ return _providers[provider_type](base_url=base_url, api_key=api_key, **kwargs)
52
+
53
+
54
+ def list_provider_types() -> List[str]:
55
+ """
56
+ List all registered provider types.
57
+
58
+ Returns:
59
+ List of provider type identifiers
60
+ """
61
+ _ensure_providers_registered()
62
+ return list(_providers.keys())
63
+
64
+
65
+ def get_provider_class(provider_type: str) -> Optional[Type[BaseProvider]]:
66
+ """
67
+ Get a provider class by type.
68
+
69
+ Args:
70
+ provider_type: Provider type identifier
71
+
72
+ Returns:
73
+ Provider class or None if not found
74
+ """
75
+ _ensure_providers_registered()
76
+ return _providers.get(provider_type)
77
+
78
+
79
+ def _ensure_providers_registered() -> None:
80
+ """Ensure built-in providers are registered."""
81
+ if _providers:
82
+ return
83
+
84
+ # Lazy import and register built-in providers
85
+ from .providers.recipe import RecipeProvider
86
+ from .providers.agents_api import AgentsAPIProvider
87
+ from .providers.mcp import MCPProvider
88
+ from .providers.tools_mcp import ToolsMCPProvider
89
+ from .providers.a2a import A2AProvider
90
+ from .providers.a2u import A2UProvider
91
+
92
+ register_provider("recipe", RecipeProvider)
93
+ register_provider("agents-api", AgentsAPIProvider)
94
+ register_provider("mcp", MCPProvider)
95
+ register_provider("tools-mcp", ToolsMCPProvider)
96
+ register_provider("a2a", A2AProvider)
97
+ register_provider("a2u", A2UProvider)
98
+
99
+
100
+ class ProviderRegistry:
101
+ """
102
+ Provider registry class for managing provider instances.
103
+
104
+ This class provides a more object-oriented interface to the provider registry.
105
+ """
106
+
107
+ def __init__(self):
108
+ """Initialize the registry."""
109
+ _ensure_providers_registered()
110
+
111
+ def get(
112
+ self,
113
+ provider_type: str,
114
+ base_url: str = "http://localhost:8765",
115
+ api_key: Optional[str] = None,
116
+ **kwargs,
117
+ ) -> Optional[BaseProvider]:
118
+ """Get a provider instance."""
119
+ return get_provider(provider_type, base_url, api_key, **kwargs)
120
+
121
+ def register(self, provider_type: str, provider_class: Type[BaseProvider]) -> None:
122
+ """Register a provider class."""
123
+ register_provider(provider_type, provider_class)
124
+
125
+ def list_types(self) -> List[str]:
126
+ """List all provider types."""
127
+ return list_provider_types()
128
+
129
+ def get_class(self, provider_type: str) -> Optional[Type[BaseProvider]]:
130
+ """Get a provider class."""
131
+ return get_provider_class(provider_type)
@@ -0,0 +1,161 @@
1
+ """
2
+ Unified Server Utilities
3
+
4
+ Provides utilities for adding discovery endpoints to any server.
5
+ """
6
+
7
+ from typing import Any, List, Optional
8
+
9
+ from .discovery import (
10
+ DiscoveryDocument,
11
+ EndpointInfo,
12
+ ProviderInfo,
13
+ SCHEMA_VERSION,
14
+ create_discovery_document,
15
+ )
16
+
17
+
18
+ def add_discovery_routes(
19
+ app: Any,
20
+ discovery: DiscoveryDocument,
21
+ path: str = "/__praisonai__/discovery",
22
+ ) -> None:
23
+ """
24
+ Add unified discovery routes to a Starlette/FastAPI application.
25
+
26
+ Args:
27
+ app: Starlette or FastAPI application
28
+ discovery: DiscoveryDocument to serve
29
+ path: Path for discovery endpoint
30
+ """
31
+ try:
32
+ from starlette.responses import JSONResponse
33
+ from starlette.routing import Route
34
+ except ImportError:
35
+ # Try FastAPI
36
+ try:
37
+ from fastapi.responses import JSONResponse
38
+ except ImportError:
39
+ raise ImportError("Starlette or FastAPI required for discovery routes")
40
+
41
+ async def discovery_handler(request):
42
+ """Return discovery document."""
43
+ return JSONResponse(discovery.to_dict())
44
+
45
+ async def health_handler(request):
46
+ """Return health status with discovery info."""
47
+ return JSONResponse({
48
+ "status": "healthy",
49
+ "schema_version": SCHEMA_VERSION,
50
+ "server_name": discovery.server_name,
51
+ "server_version": discovery.server_version,
52
+ "providers": [p.type for p in discovery.providers],
53
+ "endpoint_count": len(discovery.endpoints),
54
+ })
55
+
56
+ # Add routes based on app type
57
+ if hasattr(app, 'add_api_route'):
58
+ # FastAPI
59
+ app.add_api_route(path, discovery_handler, methods=["GET"])
60
+ if not _has_route(app, "/health"):
61
+ app.add_api_route("/health", health_handler, methods=["GET"])
62
+ elif hasattr(app, 'routes'):
63
+ # Starlette
64
+ app.routes.append(Route(path, discovery_handler, methods=["GET"]))
65
+ if not _has_route(app, "/health"):
66
+ app.routes.append(Route("/health", health_handler, methods=["GET"]))
67
+
68
+
69
+ def _has_route(app: Any, path: str) -> bool:
70
+ """Check if app already has a route at path."""
71
+ if hasattr(app, 'routes'):
72
+ for route in app.routes:
73
+ if hasattr(route, 'path') and route.path == path:
74
+ return True
75
+ return False
76
+
77
+
78
+ def create_unified_app(
79
+ providers: Optional[List[str]] = None,
80
+ server_name: str = "praisonai",
81
+ host: str = "127.0.0.1",
82
+ port: int = 8765,
83
+ cors_origins: Optional[List[str]] = None,
84
+ api_key: Optional[str] = None,
85
+ ) -> Any:
86
+ """
87
+ Create a unified server application with discovery support.
88
+
89
+ Args:
90
+ providers: List of provider types to enable
91
+ server_name: Server name for discovery
92
+ host: Server host
93
+ port: Server port
94
+ cors_origins: CORS allowed origins
95
+ api_key: Optional API key for authentication
96
+
97
+ Returns:
98
+ FastAPI application
99
+ """
100
+ try:
101
+ from fastapi import FastAPI
102
+ from fastapi.middleware.cors import CORSMiddleware
103
+ except ImportError:
104
+ raise ImportError("FastAPI required. Install with: pip install fastapi")
105
+
106
+ # Create discovery document
107
+ discovery = create_discovery_document(server_name=server_name)
108
+
109
+ # Create FastAPI app
110
+ app = FastAPI(
111
+ title=f"{server_name} Unified API",
112
+ description="Unified PraisonAI endpoints server",
113
+ version=discovery.server_version,
114
+ )
115
+
116
+ # Add CORS if configured
117
+ if cors_origins:
118
+ app.add_middleware(
119
+ CORSMiddleware,
120
+ allow_origins=cors_origins,
121
+ allow_methods=["*"],
122
+ allow_headers=["*"],
123
+ )
124
+
125
+ # Add discovery routes
126
+ add_discovery_routes(app, discovery)
127
+
128
+ # Store discovery document for later modification
129
+ app.state.discovery = discovery
130
+
131
+ return app
132
+
133
+
134
+ def register_endpoint_to_discovery(
135
+ app: Any,
136
+ endpoint: EndpointInfo,
137
+ ) -> None:
138
+ """
139
+ Register an endpoint to the app's discovery document.
140
+
141
+ Args:
142
+ app: FastAPI/Starlette app with discovery
143
+ endpoint: EndpointInfo to register
144
+ """
145
+ if hasattr(app, 'state') and hasattr(app.state, 'discovery'):
146
+ app.state.discovery.add_endpoint(endpoint)
147
+
148
+
149
+ def register_provider_to_discovery(
150
+ app: Any,
151
+ provider: ProviderInfo,
152
+ ) -> None:
153
+ """
154
+ Register a provider to the app's discovery document.
155
+
156
+ Args:
157
+ app: FastAPI/Starlette app with discovery
158
+ provider: ProviderInfo to register
159
+ """
160
+ if hasattr(app, 'state') and hasattr(app.state, 'discovery'):
161
+ app.state.discovery.add_provider(provider)
@@ -0,0 +1,24 @@
1
+ # Only try to import autogen_tools if either CrewAI or AG2 is available
2
+ CREWAI_AVAILABLE = False
3
+ AUTOGEN_AVAILABLE = False
4
+ PRAISONAI_TOOLS_AVAILABLE = False
5
+
6
+ try:
7
+ from crewai import Agent, Task, Crew
8
+ CREWAI_AVAILABLE = True
9
+ except ImportError:
10
+ pass
11
+
12
+ try:
13
+ import autogen
14
+ AUTOGEN_AVAILABLE = True
15
+ except ImportError:
16
+ pass
17
+
18
+ # Only try to import tools if a framework is available
19
+ if CREWAI_AVAILABLE or AUTOGEN_AVAILABLE:
20
+ try:
21
+ from .autogen_tools import *
22
+ PRAISONAI_TOOLS_AVAILABLE = True
23
+ except ImportError:
24
+ pass