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,287 @@
1
+ """
2
+ SurrealDB implementation of ConversationStore.
3
+
4
+ Requires: surrealdb
5
+ Install: pip install surrealdb
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ from typing import List, Optional
11
+
12
+ from .base import ConversationStore, ConversationSession, ConversationMessage
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class SurrealDBConversationStore(ConversationStore):
18
+ """
19
+ SurrealDB-based conversation store.
20
+
21
+ SurrealDB is a multi-model database supporting SQL-like queries.
22
+
23
+ Example:
24
+ store = SurrealDBConversationStore(
25
+ url="ws://localhost:8000/rpc",
26
+ namespace="praisonai",
27
+ database="conversations"
28
+ )
29
+ """
30
+
31
+ SCHEMA_VERSION = "1.0.0"
32
+
33
+ def __init__(
34
+ self,
35
+ url: str = "ws://localhost:8000/rpc",
36
+ namespace: str = "praisonai",
37
+ database: str = "conversations",
38
+ username: Optional[str] = None,
39
+ password: Optional[str] = None,
40
+ table_prefix: str = "praison_",
41
+ auto_create_tables: bool = True,
42
+ ):
43
+ try:
44
+ from surrealdb import Surreal
45
+ except ImportError:
46
+ raise ImportError(
47
+ "surrealdb is required for SurrealDB support. "
48
+ "Install with: pip install surrealdb"
49
+ )
50
+
51
+ self._Surreal = Surreal
52
+ self.url = url
53
+ self.namespace = namespace
54
+ self.database = database
55
+ self.username = username
56
+ self.password = password
57
+ self.table_prefix = table_prefix
58
+ self.sessions_table = f"{table_prefix}sessions"
59
+ self.messages_table = f"{table_prefix}messages"
60
+ self._client = None
61
+
62
+ # Note: SurrealDB Python client is async, we'll use sync wrapper
63
+ self._init_sync()
64
+
65
+ def _init_sync(self):
66
+ """Initialize synchronously using asyncio."""
67
+ import asyncio
68
+
69
+ async def _init():
70
+ self._client = self._Surreal(self.url)
71
+ await self._client.connect()
72
+ if self.username and self.password:
73
+ await self._client.signin({"user": self.username, "pass": self.password})
74
+ await self._client.use(self.namespace, self.database)
75
+
76
+ try:
77
+ loop = asyncio.get_event_loop()
78
+ except RuntimeError:
79
+ loop = asyncio.new_event_loop()
80
+ asyncio.set_event_loop(loop)
81
+
82
+ loop.run_until_complete(_init())
83
+
84
+ def _run_sync(self, coro):
85
+ """Run async coroutine synchronously."""
86
+ import asyncio
87
+ try:
88
+ loop = asyncio.get_event_loop()
89
+ except RuntimeError:
90
+ loop = asyncio.new_event_loop()
91
+ asyncio.set_event_loop(loop)
92
+ return loop.run_until_complete(coro)
93
+
94
+ def create_session(self, session: ConversationSession) -> ConversationSession:
95
+ data = {
96
+ "session_id": session.session_id,
97
+ "user_id": session.user_id,
98
+ "agent_id": session.agent_id,
99
+ "name": session.name,
100
+ "state": session.state,
101
+ "metadata": session.metadata,
102
+ "created_at": session.created_at,
103
+ "updated_at": session.updated_at,
104
+ }
105
+ self._run_sync(self._client.create(self.sessions_table, data))
106
+ return session
107
+
108
+ def get_session(self, session_id: str) -> Optional[ConversationSession]:
109
+ result = self._run_sync(
110
+ self._client.query(
111
+ f"SELECT * FROM {self.sessions_table} WHERE session_id = $sid",
112
+ {"sid": session_id}
113
+ )
114
+ )
115
+ if not result or not result[0].get("result"):
116
+ return None
117
+ row = result[0]["result"][0]
118
+ return ConversationSession(
119
+ session_id=row["session_id"],
120
+ user_id=row.get("user_id"),
121
+ agent_id=row.get("agent_id"),
122
+ name=row.get("name"),
123
+ state=row.get("state"),
124
+ metadata=row.get("metadata"),
125
+ created_at=row.get("created_at"),
126
+ updated_at=row.get("updated_at"),
127
+ )
128
+
129
+ def update_session(self, session: ConversationSession) -> ConversationSession:
130
+ self._run_sync(
131
+ self._client.query(
132
+ f"""UPDATE {self.sessions_table} SET
133
+ user_id = $user_id, agent_id = $agent_id, name = $name,
134
+ state = $state, metadata = $metadata, updated_at = $updated_at
135
+ WHERE session_id = $session_id""",
136
+ {
137
+ "session_id": session.session_id,
138
+ "user_id": session.user_id,
139
+ "agent_id": session.agent_id,
140
+ "name": session.name,
141
+ "state": session.state,
142
+ "metadata": session.metadata,
143
+ "updated_at": session.updated_at,
144
+ }
145
+ )
146
+ )
147
+ return session
148
+
149
+ def delete_session(self, session_id: str) -> bool:
150
+ self._run_sync(
151
+ self._client.query(
152
+ f"DELETE FROM {self.messages_table} WHERE session_id = $sid",
153
+ {"sid": session_id}
154
+ )
155
+ )
156
+ result = self._run_sync(
157
+ self._client.query(
158
+ f"DELETE FROM {self.sessions_table} WHERE session_id = $sid",
159
+ {"sid": session_id}
160
+ )
161
+ )
162
+ return True
163
+
164
+ def list_sessions(
165
+ self,
166
+ user_id: Optional[str] = None,
167
+ agent_id: Optional[str] = None,
168
+ limit: int = 100,
169
+ offset: int = 0
170
+ ) -> List[ConversationSession]:
171
+ conditions = []
172
+ params = {"limit": limit, "offset": offset}
173
+
174
+ if user_id:
175
+ conditions.append("user_id = $user_id")
176
+ params["user_id"] = user_id
177
+ if agent_id:
178
+ conditions.append("agent_id = $agent_id")
179
+ params["agent_id"] = agent_id
180
+
181
+ where = "WHERE " + " AND ".join(conditions) if conditions else ""
182
+
183
+ result = self._run_sync(
184
+ self._client.query(
185
+ f"SELECT * FROM {self.sessions_table} {where} ORDER BY updated_at DESC LIMIT $limit START $offset",
186
+ params
187
+ )
188
+ )
189
+
190
+ if not result or not result[0].get("result"):
191
+ return []
192
+
193
+ return [
194
+ ConversationSession(
195
+ session_id=row["session_id"],
196
+ user_id=row.get("user_id"),
197
+ agent_id=row.get("agent_id"),
198
+ name=row.get("name"),
199
+ state=row.get("state"),
200
+ metadata=row.get("metadata"),
201
+ created_at=row.get("created_at"),
202
+ updated_at=row.get("updated_at"),
203
+ )
204
+ for row in result[0]["result"]
205
+ ]
206
+
207
+ def add_message(self, session_id: str, message: ConversationMessage) -> ConversationMessage:
208
+ message.session_id = session_id
209
+ data = {
210
+ "id": message.id,
211
+ "session_id": session_id,
212
+ "role": message.role,
213
+ "content": message.content,
214
+ "tool_calls": message.tool_calls,
215
+ "tool_call_id": message.tool_call_id,
216
+ "metadata": message.metadata,
217
+ "created_at": message.created_at,
218
+ }
219
+ self._run_sync(self._client.create(self.messages_table, data))
220
+ return message
221
+
222
+ def get_messages(
223
+ self,
224
+ session_id: str,
225
+ limit: Optional[int] = None,
226
+ before: Optional[float] = None,
227
+ after: Optional[float] = None
228
+ ) -> List[ConversationMessage]:
229
+ conditions = ["session_id = $session_id"]
230
+ params = {"session_id": session_id}
231
+
232
+ if before:
233
+ conditions.append("created_at < $before")
234
+ params["before"] = before
235
+ if after:
236
+ conditions.append("created_at > $after")
237
+ params["after"] = after
238
+
239
+ where = "WHERE " + " AND ".join(conditions)
240
+ limit_clause = f"LIMIT {limit}" if limit else ""
241
+
242
+ result = self._run_sync(
243
+ self._client.query(
244
+ f"SELECT * FROM {self.messages_table} {where} ORDER BY created_at ASC {limit_clause}",
245
+ params
246
+ )
247
+ )
248
+
249
+ if not result or not result[0].get("result"):
250
+ return []
251
+
252
+ return [
253
+ ConversationMessage(
254
+ id=row["id"],
255
+ session_id=row["session_id"],
256
+ role=row["role"],
257
+ content=row.get("content", ""),
258
+ tool_calls=row.get("tool_calls"),
259
+ tool_call_id=row.get("tool_call_id"),
260
+ metadata=row.get("metadata"),
261
+ created_at=row.get("created_at"),
262
+ )
263
+ for row in result[0]["result"]
264
+ ]
265
+
266
+ def delete_messages(self, session_id: str, message_ids: Optional[List[str]] = None) -> int:
267
+ if message_ids:
268
+ self._run_sync(
269
+ self._client.query(
270
+ f"DELETE FROM {self.messages_table} WHERE session_id = $sid AND id IN $ids",
271
+ {"sid": session_id, "ids": message_ids}
272
+ )
273
+ )
274
+ return len(message_ids)
275
+ else:
276
+ self._run_sync(
277
+ self._client.query(
278
+ f"DELETE FROM {self.messages_table} WHERE session_id = $sid",
279
+ {"sid": session_id}
280
+ )
281
+ )
282
+ return -1
283
+
284
+ def close(self) -> None:
285
+ if self._client:
286
+ self._run_sync(self._client.close())
287
+ self._client = None
@@ -0,0 +1,301 @@
1
+ """
2
+ Factory functions for creating store instances.
3
+
4
+ Provides lazy loading of backend implementations to avoid importing
5
+ unused dependencies.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Dict, Optional
10
+
11
+ from .config import PersistenceConfig
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def create_conversation_store(
17
+ backend: str,
18
+ url: Optional[str] = None,
19
+ **options: Any
20
+ ):
21
+ """
22
+ Create a ConversationStore instance.
23
+
24
+ Args:
25
+ backend: Backend type (postgres, mysql, sqlite, singlestore, supabase, surrealdb)
26
+ url: Connection URL
27
+ **options: Backend-specific options
28
+
29
+ Returns:
30
+ ConversationStore instance
31
+
32
+ Example:
33
+ store = create_conversation_store(
34
+ "postgres",
35
+ url="postgresql://localhost:5432/praisonai"
36
+ )
37
+ """
38
+ backend = backend.lower()
39
+
40
+ if backend == "postgres":
41
+ from .conversation.postgres import PostgresConversationStore
42
+ return PostgresConversationStore(url=url, **options)
43
+
44
+ elif backend == "mysql":
45
+ from .conversation.mysql import MySQLConversationStore
46
+ return MySQLConversationStore(url=url, **options)
47
+
48
+ elif backend == "sqlite":
49
+ from .conversation.sqlite import SQLiteConversationStore
50
+ path = url or options.pop("path", None)
51
+ return SQLiteConversationStore(path=path, **options)
52
+
53
+ elif backend == "singlestore":
54
+ from .conversation.singlestore import SingleStoreConversationStore
55
+ return SingleStoreConversationStore(url=url, **options)
56
+
57
+ elif backend == "supabase":
58
+ from .conversation.supabase import SupabaseConversationStore
59
+ return SupabaseConversationStore(url=url, **options)
60
+
61
+ elif backend == "surrealdb":
62
+ from .conversation.surrealdb import SurrealDBConversationStore
63
+ return SurrealDBConversationStore(url=url, **options)
64
+
65
+ elif backend == "json":
66
+ from .conversation.json_store import JSONConversationStore
67
+ path = url or options.pop("path", None) or "./praisonai_conversations"
68
+ return JSONConversationStore(path=path, **options)
69
+
70
+ elif backend in ("async_postgres", "asyncpg", "postgres_async"):
71
+ from .conversation.async_postgres import AsyncPostgresConversationStore
72
+ return AsyncPostgresConversationStore(url=url, **options)
73
+
74
+ elif backend in ("async_sqlite", "aiosqlite", "sqlite_async"):
75
+ from .conversation.async_sqlite import AsyncSQLiteConversationStore
76
+ path = url or options.pop("path", None)
77
+ return AsyncSQLiteConversationStore(path=path, **options)
78
+
79
+ elif backend in ("async_mysql", "aiomysql", "mysql_async"):
80
+ from .conversation.async_mysql import AsyncMySQLConversationStore
81
+ return AsyncMySQLConversationStore(url=url, **options)
82
+
83
+ else:
84
+ raise ValueError(
85
+ f"Unknown conversation store backend: {backend}. "
86
+ f"Supported: postgres, mysql, sqlite, json, singlestore, supabase, surrealdb, "
87
+ f"async_postgres, async_sqlite, async_mysql"
88
+ )
89
+
90
+
91
+ def create_knowledge_store(
92
+ backend: str,
93
+ url: Optional[str] = None,
94
+ **options: Any
95
+ ):
96
+ """
97
+ Create a KnowledgeStore instance.
98
+
99
+ Args:
100
+ backend: Backend type (qdrant, pinecone, chroma, weaviate, lancedb, milvus, pgvector, redis, cassandra, clickhouse)
101
+ url: Connection URL
102
+ **options: Backend-specific options
103
+
104
+ Returns:
105
+ KnowledgeStore instance
106
+
107
+ Example:
108
+ store = create_knowledge_store(
109
+ "qdrant",
110
+ url="http://localhost:6333"
111
+ )
112
+ """
113
+ backend = backend.lower()
114
+
115
+ if backend == "qdrant":
116
+ from .knowledge.qdrant import QdrantKnowledgeStore
117
+ return QdrantKnowledgeStore(url=url, **options)
118
+
119
+ elif backend == "pinecone":
120
+ from .knowledge.pinecone import PineconeKnowledgeStore
121
+ return PineconeKnowledgeStore(**options)
122
+
123
+ elif backend == "chroma":
124
+ from .knowledge.chroma import ChromaKnowledgeStore
125
+ path = url or options.pop("path", None)
126
+ return ChromaKnowledgeStore(path=path, **options)
127
+
128
+ elif backend == "weaviate":
129
+ from .knowledge.weaviate import WeaviateKnowledgeStore
130
+ return WeaviateKnowledgeStore(url=url, **options)
131
+
132
+ elif backend == "lancedb":
133
+ from .knowledge.lancedb import LanceDBKnowledgeStore
134
+ path = url or options.pop("path", None)
135
+ return LanceDBKnowledgeStore(path=path, **options)
136
+
137
+ elif backend == "milvus":
138
+ from .knowledge.milvus import MilvusKnowledgeStore
139
+ return MilvusKnowledgeStore(url=url, **options)
140
+
141
+ elif backend == "pgvector":
142
+ from .knowledge.pgvector import PGVectorKnowledgeStore
143
+ return PGVectorKnowledgeStore(url=url, **options)
144
+
145
+ elif backend == "redis":
146
+ from .knowledge.redis_vector import RedisVectorKnowledgeStore
147
+ return RedisVectorKnowledgeStore(url=url, **options)
148
+
149
+ elif backend == "cassandra":
150
+ from .knowledge.cassandra import CassandraKnowledgeStore
151
+ return CassandraKnowledgeStore(**options)
152
+
153
+ elif backend == "clickhouse":
154
+ from .knowledge.clickhouse import ClickHouseKnowledgeStore
155
+ return ClickHouseKnowledgeStore(**options)
156
+
157
+ elif backend == "couchbase":
158
+ from .knowledge.couchbase import CouchbaseKnowledgeStore
159
+ return CouchbaseKnowledgeStore(**options)
160
+
161
+ elif backend in ("mongodb_vector", "mongodb_atlas", "mongo_vector"):
162
+ from .knowledge.mongodb_vector import MongoDBVectorKnowledgeStore
163
+ return MongoDBVectorKnowledgeStore(url=url, **options)
164
+
165
+ elif backend in ("singlestore_vector", "singlestore_v"):
166
+ from .knowledge.singlestore_vector import SingleStoreVectorKnowledgeStore
167
+ return SingleStoreVectorKnowledgeStore(url=url, **options)
168
+
169
+ elif backend in ("surrealdb_vector", "surrealdb_v"):
170
+ from .knowledge.surrealdb_vector import SurrealDBVectorKnowledgeStore
171
+ return SurrealDBVectorKnowledgeStore(url=url, **options)
172
+
173
+ elif backend in ("upstash_vector", "upstash_v"):
174
+ from .knowledge.upstash_vector import UpstashVectorKnowledgeStore
175
+ return UpstashVectorKnowledgeStore(url=url, **options)
176
+
177
+ elif backend == "lightrag":
178
+ from .knowledge.lightrag_adapter import LightRAGKnowledgeStore
179
+ return LightRAGKnowledgeStore(**options)
180
+
181
+ elif backend in ("langchain", "langchain_adapter"):
182
+ from .knowledge.langchain_adapter import LangChainKnowledgeStore
183
+ return LangChainKnowledgeStore(**options)
184
+
185
+ elif backend in ("llamaindex", "llama_index", "llamaindex_adapter"):
186
+ from .knowledge.llamaindex_adapter import LlamaIndexKnowledgeStore
187
+ return LlamaIndexKnowledgeStore(**options)
188
+
189
+ elif backend in ("cosmosdb", "cosmos", "azure_cosmos", "cosmosdb_vector"):
190
+ from .knowledge.cosmosdb_vector import CosmosDBVectorKnowledgeStore
191
+ return CosmosDBVectorKnowledgeStore(**options)
192
+
193
+ else:
194
+ raise ValueError(
195
+ f"Unknown knowledge store backend: {backend}. "
196
+ f"Supported: qdrant, pinecone, chroma, weaviate, lancedb, milvus, pgvector, redis, cassandra, clickhouse, "
197
+ f"couchbase, mongodb_vector, singlestore_vector, surrealdb_vector, upstash_vector, lightrag, langchain, llamaindex, cosmosdb"
198
+ )
199
+
200
+
201
+ def create_state_store(
202
+ backend: str,
203
+ url: Optional[str] = None,
204
+ **options: Any
205
+ ):
206
+ """
207
+ Create a StateStore instance.
208
+
209
+ Args:
210
+ backend: Backend type (redis, dynamodb, firestore, mongodb, upstash, memory)
211
+ url: Connection URL
212
+ **options: Backend-specific options
213
+
214
+ Returns:
215
+ StateStore instance
216
+
217
+ Example:
218
+ store = create_state_store(
219
+ "redis",
220
+ url="redis://localhost:6379"
221
+ )
222
+ """
223
+ backend = backend.lower()
224
+
225
+ if backend == "redis":
226
+ from .state.redis import RedisStateStore
227
+ return RedisStateStore(url=url, **options)
228
+
229
+ elif backend == "dynamodb":
230
+ from .state.dynamodb import DynamoDBStateStore
231
+ return DynamoDBStateStore(**options)
232
+
233
+ elif backend == "firestore":
234
+ from .state.firestore import FirestoreStateStore
235
+ return FirestoreStateStore(**options)
236
+
237
+ elif backend == "mongodb":
238
+ from .state.mongodb import MongoDBStateStore
239
+ return MongoDBStateStore(url=url, **options)
240
+
241
+ elif backend == "upstash":
242
+ from .state.upstash import UpstashStateStore
243
+ return UpstashStateStore(url=url, **options)
244
+
245
+ elif backend == "memory":
246
+ from .state.memory import MemoryStateStore
247
+ return MemoryStateStore(**options)
248
+
249
+ elif backend == "gcs":
250
+ from .state.gcs import GCSStateStore
251
+ bucket = options.pop("bucket_name", None) or options.pop("bucket", None)
252
+ if not bucket:
253
+ raise ValueError("GCS state store requires 'bucket_name' option")
254
+ return GCSStateStore(bucket_name=bucket, **options)
255
+
256
+ elif backend in ("async_mongodb", "motor", "mongodb_async"):
257
+ from .state.async_mongodb import AsyncMongoDBStateStore
258
+ return AsyncMongoDBStateStore(url=url, **options)
259
+
260
+ else:
261
+ raise ValueError(
262
+ f"Unknown state store backend: {backend}. "
263
+ f"Supported: redis, dynamodb, firestore, mongodb, upstash, memory, gcs, async_mongodb"
264
+ )
265
+
266
+
267
+ def create_stores_from_config(config: PersistenceConfig) -> Dict[str, Any]:
268
+ """
269
+ Create all configured stores from a PersistenceConfig.
270
+
271
+ Returns:
272
+ Dict with keys: conversation, knowledge, state (values may be None)
273
+ """
274
+ stores = {
275
+ "conversation": None,
276
+ "knowledge": None,
277
+ "state": None,
278
+ }
279
+
280
+ if config.conversation_store:
281
+ stores["conversation"] = create_conversation_store(
282
+ config.conversation_store,
283
+ url=config.conversation_url,
284
+ **config.conversation_options
285
+ )
286
+
287
+ if config.knowledge_store:
288
+ stores["knowledge"] = create_knowledge_store(
289
+ config.knowledge_store,
290
+ url=config.knowledge_url,
291
+ **config.knowledge_options
292
+ )
293
+
294
+ if config.state_store:
295
+ stores["state"] = create_state_store(
296
+ config.state_store,
297
+ url=config.state_url,
298
+ **config.state_options
299
+ )
300
+
301
+ return stores
@@ -0,0 +1,18 @@
1
+ """
2
+ Agent hooks for automatic persistence integration.
3
+
4
+ Provides wrapper functions to add persistence capabilities to PraisonAI agents
5
+ without modifying the core SDK.
6
+ """
7
+
8
+ from .agent_hooks import (
9
+ wrap_agent_with_persistence,
10
+ PersistentAgent,
11
+ create_persistent_session,
12
+ )
13
+
14
+ __all__ = [
15
+ "wrap_agent_with_persistence",
16
+ "PersistentAgent",
17
+ "create_persistent_session",
18
+ ]