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,171 @@
1
+ """
2
+ Agents API Provider
3
+
4
+ Provider adapter for agents-as-API endpoints (single agent or multi-agent router).
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional
8
+
9
+ from .base import BaseProvider, InvokeResult, HealthResult
10
+ from ..discovery import EndpointInfo, ProviderInfo
11
+
12
+
13
+ class AgentsAPIProvider(BaseProvider):
14
+ """
15
+ Provider adapter for agents-as-API endpoints.
16
+
17
+ Connects to FastAPI-based agent servers launched via Agent.launch() or Agents.launch()
18
+ and provides unified discovery and invocation interface.
19
+ """
20
+
21
+ provider_type = "agents-api"
22
+
23
+ def get_provider_info(self) -> ProviderInfo:
24
+ """Get provider information."""
25
+ return ProviderInfo(
26
+ type=self.provider_type,
27
+ name="Agents API",
28
+ description="Agent HTTP API endpoints",
29
+ capabilities=["list", "describe", "invoke", "health"],
30
+ )
31
+
32
+ def list_endpoints(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
33
+ """List available agent 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
+ version=ep.get("version", "1.0.0"),
48
+ streaming=ep.get("streaming", ["none"]),
49
+ auth_modes=ep.get("auth_modes", ["none"]),
50
+ ))
51
+ return endpoints
52
+
53
+ # Fallback: try root endpoint for endpoint list
54
+ result = self._make_request("GET", "/")
55
+
56
+ if result.get("error"):
57
+ return []
58
+
59
+ data = result.get("data", {})
60
+ endpoint_paths = data.get("endpoints", [])
61
+
62
+ endpoints = []
63
+ for path in endpoint_paths:
64
+ endpoints.append(EndpointInfo(
65
+ name=path.lstrip("/"),
66
+ description=f"Agent endpoint at {path}",
67
+ provider_type=self.provider_type,
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 an agent endpoint."""
76
+ # Try unified discovery first
77
+ result = self._make_request("GET", "/__praisonai__/discovery")
78
+
79
+ if not result.get("error") and result.get("data"):
80
+ data = result.get("data", {})
81
+ for ep in data.get("endpoints", []):
82
+ if ep.get("name") == name:
83
+ return EndpointInfo(
84
+ name=ep.get("name", name),
85
+ description=ep.get("description", ""),
86
+ provider_type=self.provider_type,
87
+ tags=ep.get("tags", []),
88
+ version=ep.get("version", "1.0.0"),
89
+ input_schema=ep.get("input_schema"),
90
+ output_schema=ep.get("output_schema"),
91
+ streaming=ep.get("streaming", ["none"]),
92
+ auth_modes=ep.get("auth_modes", ["none"]),
93
+ metadata=ep.get("metadata", {}),
94
+ )
95
+
96
+ # Fallback: return basic info
97
+ return EndpointInfo(
98
+ name=name,
99
+ description=f"Agent endpoint: {name}",
100
+ provider_type=self.provider_type,
101
+ input_schema={"type": "object", "properties": {"query": {"type": "string"}}},
102
+ streaming=["none"],
103
+ auth_modes=["none"],
104
+ )
105
+
106
+ def invoke(
107
+ self,
108
+ name: str,
109
+ input_data: Optional[Dict[str, Any]] = None,
110
+ config: Optional[Dict[str, Any]] = None,
111
+ stream: bool = False,
112
+ ) -> InvokeResult:
113
+ """Invoke an agent endpoint."""
114
+ # Normalize endpoint path
115
+ path = name if name.startswith("/") else f"/{name}"
116
+
117
+ # Build request body
118
+ body = input_data or {}
119
+ if "query" not in body and config and "query" in config:
120
+ body["query"] = config["query"]
121
+
122
+ result = self._make_request("POST", path, json_data=body)
123
+
124
+ if result.get("status") == 401:
125
+ return InvokeResult(
126
+ ok=False,
127
+ status="auth_error",
128
+ error="Authentication required",
129
+ )
130
+
131
+ if result.get("status") == 404:
132
+ return InvokeResult(
133
+ ok=False,
134
+ status="not_found",
135
+ error=f"Endpoint not found: {name}",
136
+ )
137
+
138
+ if result.get("error"):
139
+ return InvokeResult(
140
+ ok=False,
141
+ status="error",
142
+ error=result["error"].get("message", str(result["error"])),
143
+ )
144
+
145
+ data = result.get("data", {})
146
+ return InvokeResult(
147
+ ok=True,
148
+ status="success",
149
+ data=data.get("response", data),
150
+ )
151
+
152
+ def health(self) -> HealthResult:
153
+ """Check agent server health."""
154
+ result = self._make_request("GET", "/health")
155
+
156
+ if result.get("error"):
157
+ return HealthResult(
158
+ healthy=False,
159
+ status="unhealthy",
160
+ provider_type=self.provider_type,
161
+ metadata={"error": result["error"].get("message", str(result["error"]))},
162
+ )
163
+
164
+ data = result.get("data", {})
165
+ return HealthResult(
166
+ healthy=data.get("status") == "ok",
167
+ status=data.get("status", "unknown"),
168
+ server_name="PraisonAI Agents API",
169
+ provider_type=self.provider_type,
170
+ metadata={"endpoints": data.get("endpoints", [])},
171
+ )
@@ -0,0 +1,231 @@
1
+ """
2
+ Base Provider Interface
3
+
4
+ Abstract base class for all provider adapters.
5
+ Each provider implements discovery, invocation, and health check methods.
6
+ """
7
+
8
+ from abc import ABC, abstractmethod
9
+ from dataclasses import dataclass
10
+ from typing import Any, Dict, Iterator, List, Optional
11
+
12
+ from ..discovery import EndpointInfo, ProviderInfo
13
+
14
+
15
+ @dataclass
16
+ class InvokeResult:
17
+ """Result from invoking an endpoint."""
18
+ ok: bool
19
+ status: str = "success"
20
+ data: Optional[Any] = None
21
+ error: Optional[str] = None
22
+ metadata: Optional[Dict[str, Any]] = None
23
+
24
+ def to_dict(self) -> Dict[str, Any]:
25
+ """Convert to dictionary."""
26
+ return {
27
+ "ok": self.ok,
28
+ "status": self.status,
29
+ "data": self.data,
30
+ "error": self.error,
31
+ "metadata": self.metadata,
32
+ }
33
+
34
+
35
+ @dataclass
36
+ class HealthResult:
37
+ """Result from health check."""
38
+ healthy: bool
39
+ status: str = "healthy"
40
+ server_name: Optional[str] = None
41
+ server_version: Optional[str] = None
42
+ provider_type: Optional[str] = None
43
+ metadata: Optional[Dict[str, Any]] = None
44
+
45
+ def to_dict(self) -> Dict[str, Any]:
46
+ """Convert to dictionary."""
47
+ return {
48
+ "healthy": self.healthy,
49
+ "status": self.status,
50
+ "server_name": self.server_name,
51
+ "server_version": self.server_version,
52
+ "provider_type": self.provider_type,
53
+ "metadata": self.metadata,
54
+ }
55
+
56
+
57
+ class BaseProvider(ABC):
58
+ """
59
+ Abstract base class for provider adapters.
60
+
61
+ Each provider type (recipe, agents-api, mcp, etc.) implements this interface
62
+ to provide consistent discovery and invocation behavior.
63
+ """
64
+
65
+ # Provider type identifier
66
+ provider_type: str = "base"
67
+
68
+ def __init__(
69
+ self,
70
+ base_url: str = "http://localhost:8765",
71
+ api_key: Optional[str] = None,
72
+ timeout: float = 30.0,
73
+ ):
74
+ """
75
+ Initialize the provider.
76
+
77
+ Args:
78
+ base_url: Base URL of the server
79
+ api_key: Optional API key for authentication
80
+ timeout: Request timeout in seconds
81
+ """
82
+ self.base_url = base_url.rstrip("/")
83
+ self.api_key = api_key
84
+ self.timeout = timeout
85
+
86
+ @abstractmethod
87
+ def get_provider_info(self) -> ProviderInfo:
88
+ """
89
+ Get provider information.
90
+
91
+ Returns:
92
+ ProviderInfo with provider details
93
+ """
94
+ pass
95
+
96
+ @abstractmethod
97
+ def list_endpoints(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
98
+ """
99
+ List available endpoints.
100
+
101
+ Args:
102
+ tags: Optional list of tags to filter by
103
+
104
+ Returns:
105
+ List of EndpointInfo objects
106
+ """
107
+ pass
108
+
109
+ @abstractmethod
110
+ def describe_endpoint(self, name: str) -> Optional[EndpointInfo]:
111
+ """
112
+ Get detailed information about an endpoint.
113
+
114
+ Args:
115
+ name: Endpoint name
116
+
117
+ Returns:
118
+ EndpointInfo or None if not found
119
+ """
120
+ pass
121
+
122
+ @abstractmethod
123
+ def invoke(
124
+ self,
125
+ name: str,
126
+ input_data: Optional[Dict[str, Any]] = None,
127
+ config: Optional[Dict[str, Any]] = None,
128
+ stream: bool = False,
129
+ ) -> InvokeResult:
130
+ """
131
+ Invoke an endpoint.
132
+
133
+ Args:
134
+ name: Endpoint name
135
+ input_data: Input data for the endpoint
136
+ config: Optional configuration overrides
137
+ stream: Whether to stream the response
138
+
139
+ Returns:
140
+ InvokeResult with response data
141
+ """
142
+ pass
143
+
144
+ def invoke_stream(
145
+ self,
146
+ name: str,
147
+ input_data: Optional[Dict[str, Any]] = None,
148
+ config: Optional[Dict[str, Any]] = None,
149
+ ) -> Iterator[Dict[str, Any]]:
150
+ """
151
+ Invoke an endpoint with streaming.
152
+
153
+ Args:
154
+ name: Endpoint name
155
+ input_data: Input data for the endpoint
156
+ config: Optional configuration overrides
157
+
158
+ Yields:
159
+ Stream events as dictionaries
160
+ """
161
+ # Default implementation - subclasses can override
162
+ result = self.invoke(name, input_data, config, stream=True)
163
+ if result.ok:
164
+ yield {"event": "complete", "data": result.data}
165
+ else:
166
+ yield {"event": "error", "data": {"error": result.error}}
167
+
168
+ @abstractmethod
169
+ def health(self) -> HealthResult:
170
+ """
171
+ Check server health.
172
+
173
+ Returns:
174
+ HealthResult with health status
175
+ """
176
+ pass
177
+
178
+ def _make_request(
179
+ self,
180
+ method: str,
181
+ path: str,
182
+ json_data: Optional[Dict] = None,
183
+ ) -> Dict[str, Any]:
184
+ """
185
+ Make HTTP request to server.
186
+
187
+ Args:
188
+ method: HTTP method
189
+ path: URL path
190
+ json_data: Optional JSON body
191
+
192
+ Returns:
193
+ Response data dictionary
194
+ """
195
+ import json
196
+ import urllib.request
197
+ import urllib.error
198
+
199
+ full_url = f"{self.base_url}{path}"
200
+
201
+ headers = {"Content-Type": "application/json"}
202
+ if self.api_key:
203
+ headers["X-API-Key"] = self.api_key
204
+
205
+ data = None
206
+ if json_data:
207
+ data = json.dumps(json_data).encode("utf-8")
208
+
209
+ try:
210
+ req = urllib.request.Request(
211
+ full_url,
212
+ data=data,
213
+ headers=headers,
214
+ method=method,
215
+ )
216
+
217
+ with urllib.request.urlopen(req, timeout=self.timeout) as response:
218
+ body = response.read().decode("utf-8")
219
+ return {"status": response.status, "data": json.loads(body) if body else {}}
220
+
221
+ except urllib.error.HTTPError as e:
222
+ body = e.read().decode("utf-8") if e.fp else ""
223
+ try:
224
+ error_data = json.loads(body) if body else {}
225
+ except json.JSONDecodeError:
226
+ error_data = {"message": body}
227
+ return {"status": e.code, "error": error_data}
228
+ except urllib.error.URLError as e:
229
+ return {"status": 0, "error": {"message": f"Connection error: {e.reason}"}}
230
+ except Exception as e:
231
+ return {"status": 0, "error": {"message": str(e)}}
@@ -0,0 +1,263 @@
1
+ """
2
+ MCP Provider
3
+
4
+ Provider adapter for MCP server endpoints (stdio, http, sse).
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 MCPProvider(BaseProvider):
14
+ """
15
+ Provider adapter for MCP server endpoints.
16
+
17
+ Supports multiple MCP transport types:
18
+ - stdio: Standard input/output (requires subprocess)
19
+ - http: HTTP-based MCP server
20
+ - sse: Server-Sent Events MCP gateway
21
+ """
22
+
23
+ provider_type = "mcp"
24
+
25
+ def __init__(
26
+ self,
27
+ base_url: str = "http://localhost:8765",
28
+ api_key: Optional[str] = None,
29
+ timeout: float = 30.0,
30
+ transport: str = "http",
31
+ command: Optional[str] = None,
32
+ args: Optional[List[str]] = None,
33
+ env: Optional[Dict[str, str]] = None,
34
+ ):
35
+ """
36
+ Initialize MCP provider.
37
+
38
+ Args:
39
+ base_url: Base URL for HTTP/SSE transport
40
+ api_key: Optional API key
41
+ timeout: Request timeout
42
+ transport: Transport type (stdio, http, sse)
43
+ command: Command for stdio transport
44
+ args: Command arguments for stdio transport
45
+ env: Environment variables for stdio transport
46
+ """
47
+ super().__init__(base_url, api_key, timeout)
48
+ self.transport = transport
49
+ self.command = command
50
+ self.args = args or []
51
+ self.env = env or {}
52
+
53
+ def get_provider_info(self) -> ProviderInfo:
54
+ """Get provider information."""
55
+ return ProviderInfo(
56
+ type=self.provider_type,
57
+ name="MCP Server",
58
+ description=f"MCP server ({self.transport} transport)",
59
+ capabilities=["list-tools", "call-tool", "list-resources"],
60
+ )
61
+
62
+ def list_endpoints(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
63
+ """List available MCP tools as endpoints."""
64
+ if self.transport == "stdio":
65
+ return self._list_stdio_tools(tags)
66
+ else:
67
+ return self._list_http_tools(tags)
68
+
69
+ def _list_stdio_tools(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
70
+ """List tools from stdio MCP server."""
71
+ try:
72
+ from praisonaiagents.mcp import MCP
73
+
74
+ mcp = MCP(command=self.command, args=self.args, env=self.env)
75
+ tools = mcp.get_tools()
76
+
77
+ endpoints = []
78
+ for tool in tools:
79
+ tool_name = getattr(tool, 'name', str(tool))
80
+ tool_desc = getattr(tool, 'description', '')
81
+
82
+ endpoints.append(EndpointInfo(
83
+ name=tool_name,
84
+ description=tool_desc,
85
+ provider_type=self.provider_type,
86
+ streaming=["mcp-stream"],
87
+ auth_modes=["none"],
88
+ metadata={"transport": "stdio"},
89
+ ))
90
+
91
+ return endpoints
92
+ except Exception:
93
+ return []
94
+
95
+ def _list_http_tools(self, tags: Optional[List[str]] = None) -> List[EndpointInfo]:
96
+ """List tools from HTTP MCP server."""
97
+ # Try unified discovery first
98
+ result = self._make_request("GET", "/__praisonai__/discovery")
99
+
100
+ if not result.get("error") and result.get("data"):
101
+ data = result.get("data", {})
102
+ endpoints = []
103
+ for ep in data.get("endpoints", []):
104
+ if ep.get("provider_type") == self.provider_type:
105
+ endpoints.append(EndpointInfo(
106
+ name=ep.get("name", ""),
107
+ description=ep.get("description", ""),
108
+ provider_type=self.provider_type,
109
+ tags=ep.get("tags", []),
110
+ streaming=ep.get("streaming", ["mcp-stream"]),
111
+ auth_modes=ep.get("auth_modes", ["none"]),
112
+ ))
113
+ return endpoints
114
+
115
+ # Fallback: try MCP tools endpoint
116
+ result = self._make_request("GET", "/mcp/tools")
117
+
118
+ if result.get("error"):
119
+ return []
120
+
121
+ tools = result.get("data", {}).get("tools", [])
122
+ endpoints = []
123
+
124
+ for tool in tools:
125
+ endpoints.append(EndpointInfo(
126
+ name=tool.get("name", ""),
127
+ description=tool.get("description", ""),
128
+ provider_type=self.provider_type,
129
+ input_schema=tool.get("inputSchema"),
130
+ streaming=["mcp-stream"],
131
+ auth_modes=["none"],
132
+ ))
133
+
134
+ return endpoints
135
+
136
+ def describe_endpoint(self, name: str) -> Optional[EndpointInfo]:
137
+ """Get detailed information about an MCP tool."""
138
+ endpoints = self.list_endpoints()
139
+ for ep in endpoints:
140
+ if ep.name == name:
141
+ return ep
142
+ return None
143
+
144
+ def invoke(
145
+ self,
146
+ name: str,
147
+ input_data: Optional[Dict[str, Any]] = None,
148
+ config: Optional[Dict[str, Any]] = None,
149
+ stream: bool = False,
150
+ ) -> InvokeResult:
151
+ """Invoke an MCP tool."""
152
+ if self.transport == "stdio":
153
+ return self._invoke_stdio(name, input_data)
154
+ else:
155
+ return self._invoke_http(name, input_data)
156
+
157
+ def _invoke_stdio(self, name: str, input_data: Optional[Dict[str, Any]] = None) -> InvokeResult:
158
+ """Invoke tool via stdio MCP."""
159
+ try:
160
+ from praisonaiagents.mcp import MCP
161
+
162
+ mcp = MCP(command=self.command, args=self.args, env=self.env)
163
+ tools = mcp.get_tools()
164
+
165
+ for tool in tools:
166
+ tool_name = getattr(tool, 'name', str(tool))
167
+ if tool_name == name:
168
+ if callable(tool):
169
+ result = tool(**(input_data or {}))
170
+ return InvokeResult(
171
+ ok=True,
172
+ status="success",
173
+ data=result,
174
+ )
175
+
176
+ return InvokeResult(
177
+ ok=False,
178
+ status="not_found",
179
+ error=f"Tool not found: {name}",
180
+ )
181
+ except Exception as e:
182
+ return InvokeResult(
183
+ ok=False,
184
+ status="error",
185
+ error=str(e),
186
+ )
187
+
188
+ def _invoke_http(self, name: str, input_data: Optional[Dict[str, Any]] = None) -> InvokeResult:
189
+ """Invoke tool via HTTP MCP."""
190
+ body = {
191
+ "tool": name,
192
+ "arguments": input_data or {},
193
+ }
194
+
195
+ result = self._make_request("POST", "/mcp/tools/call", json_data=body)
196
+
197
+ if result.get("error"):
198
+ return InvokeResult(
199
+ ok=False,
200
+ status="error",
201
+ error=result["error"].get("message", str(result["error"])),
202
+ )
203
+
204
+ data = result.get("data", {})
205
+ return InvokeResult(
206
+ ok=True,
207
+ status="success",
208
+ data=data.get("result", data),
209
+ )
210
+
211
+ def invoke_stream(
212
+ self,
213
+ name: str,
214
+ input_data: Optional[Dict[str, Any]] = None,
215
+ config: Optional[Dict[str, Any]] = None,
216
+ ) -> Iterator[Dict[str, Any]]:
217
+ """Invoke MCP tool with streaming."""
218
+ # MCP streaming is tool-specific; for now, wrap sync call
219
+ result = self.invoke(name, input_data, config)
220
+ if result.ok:
221
+ yield {"event": "result", "data": result.data}
222
+ else:
223
+ yield {"event": "error", "data": {"error": result.error}}
224
+
225
+ def health(self) -> HealthResult:
226
+ """Check MCP server health."""
227
+ if self.transport == "stdio":
228
+ # For stdio, check if command exists
229
+ import shutil
230
+ if self.command and shutil.which(self.command):
231
+ return HealthResult(
232
+ healthy=True,
233
+ status="available",
234
+ server_name=self.command,
235
+ provider_type=self.provider_type,
236
+ metadata={"transport": "stdio"},
237
+ )
238
+ return HealthResult(
239
+ healthy=False,
240
+ status="unavailable",
241
+ provider_type=self.provider_type,
242
+ metadata={"error": f"Command not found: {self.command}"},
243
+ )
244
+
245
+ # HTTP health check
246
+ result = self._make_request("GET", "/health")
247
+
248
+ if result.get("error"):
249
+ return HealthResult(
250
+ healthy=False,
251
+ status="unhealthy",
252
+ provider_type=self.provider_type,
253
+ metadata={"error": result["error"].get("message", str(result["error"]))},
254
+ )
255
+
256
+ data = result.get("data", {})
257
+ return HealthResult(
258
+ healthy=True,
259
+ status="healthy",
260
+ server_name=data.get("server_name", "MCP Server"),
261
+ server_version=data.get("version"),
262
+ provider_type=self.provider_type,
263
+ )