solace-agent-mesh 1.11.2__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 (624) hide show
  1. solace_agent_mesh/__init__.py +0 -0
  2. solace_agent_mesh/agent/__init__.py +0 -0
  3. solace_agent_mesh/agent/adk/__init__.py +0 -0
  4. solace_agent_mesh/agent/adk/adk_llm.txt +226 -0
  5. solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
  6. solace_agent_mesh/agent/adk/alembic/README +74 -0
  7. solace_agent_mesh/agent/adk/alembic/env.py +77 -0
  8. solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
  9. solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
  10. solace_agent_mesh/agent/adk/alembic.ini +112 -0
  11. solace_agent_mesh/agent/adk/app_llm_agent.py +52 -0
  12. solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
  13. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  14. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +545 -0
  15. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +609 -0
  16. solace_agent_mesh/agent/adk/callbacks.py +2318 -0
  17. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +406 -0
  18. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +415 -0
  19. solace_agent_mesh/agent/adk/mcp_content_processor.py +666 -0
  20. solace_agent_mesh/agent/adk/models/lite_llm.py +1026 -0
  21. solace_agent_mesh/agent/adk/models/models_llm.txt +189 -0
  22. solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +132 -0
  23. solace_agent_mesh/agent/adk/runner.py +390 -0
  24. solace_agent_mesh/agent/adk/schema_migration.py +88 -0
  25. solace_agent_mesh/agent/adk/services.py +468 -0
  26. solace_agent_mesh/agent/adk/setup.py +1325 -0
  27. solace_agent_mesh/agent/adk/stream_parser.py +415 -0
  28. solace_agent_mesh/agent/adk/tool_wrapper.py +165 -0
  29. solace_agent_mesh/agent/agent_llm.txt +369 -0
  30. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  31. solace_agent_mesh/agent/protocol/__init__.py +0 -0
  32. solace_agent_mesh/agent/protocol/event_handlers.py +2041 -0
  33. solace_agent_mesh/agent/protocol/protocol_llm.txt +81 -0
  34. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  35. solace_agent_mesh/agent/proxies/__init__.py +0 -0
  36. solace_agent_mesh/agent/proxies/a2a/__init__.py +3 -0
  37. solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
  38. solace_agent_mesh/agent/proxies/a2a/app.py +56 -0
  39. solace_agent_mesh/agent/proxies/a2a/component.py +1585 -0
  40. solace_agent_mesh/agent/proxies/a2a/config.py +216 -0
  41. solace_agent_mesh/agent/proxies/a2a/oauth_token_cache.py +104 -0
  42. solace_agent_mesh/agent/proxies/base/__init__.py +3 -0
  43. solace_agent_mesh/agent/proxies/base/app.py +100 -0
  44. solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
  45. solace_agent_mesh/agent/proxies/base/component.py +816 -0
  46. solace_agent_mesh/agent/proxies/base/config.py +85 -0
  47. solace_agent_mesh/agent/proxies/base/proxy_task_context.py +19 -0
  48. solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
  49. solace_agent_mesh/agent/sac/__init__.py +0 -0
  50. solace_agent_mesh/agent/sac/app.py +595 -0
  51. solace_agent_mesh/agent/sac/component.py +3668 -0
  52. solace_agent_mesh/agent/sac/patch_adk.py +103 -0
  53. solace_agent_mesh/agent/sac/sac_llm.txt +189 -0
  54. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  55. solace_agent_mesh/agent/sac/task_execution_context.py +415 -0
  56. solace_agent_mesh/agent/testing/__init__.py +3 -0
  57. solace_agent_mesh/agent/testing/debug_utils.py +135 -0
  58. solace_agent_mesh/agent/testing/testing_llm.txt +58 -0
  59. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  60. solace_agent_mesh/agent/tools/__init__.py +16 -0
  61. solace_agent_mesh/agent/tools/audio_tools.py +1740 -0
  62. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +2500 -0
  63. solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +244 -0
  64. solace_agent_mesh/agent/tools/dynamic_tool.py +396 -0
  65. solace_agent_mesh/agent/tools/general_agent_tools.py +572 -0
  66. solace_agent_mesh/agent/tools/image_tools.py +1185 -0
  67. solace_agent_mesh/agent/tools/peer_agent_tool.py +363 -0
  68. solace_agent_mesh/agent/tools/registry.py +38 -0
  69. solace_agent_mesh/agent/tools/test_tools.py +136 -0
  70. solace_agent_mesh/agent/tools/time_tools.py +126 -0
  71. solace_agent_mesh/agent/tools/tool_config_types.py +93 -0
  72. solace_agent_mesh/agent/tools/tool_definition.py +53 -0
  73. solace_agent_mesh/agent/tools/tools_llm.txt +276 -0
  74. solace_agent_mesh/agent/tools/tools_llm_detail.txt +275 -0
  75. solace_agent_mesh/agent/tools/web_tools.py +392 -0
  76. solace_agent_mesh/agent/utils/__init__.py +0 -0
  77. solace_agent_mesh/agent/utils/artifact_helpers.py +1353 -0
  78. solace_agent_mesh/agent/utils/config_parser.py +49 -0
  79. solace_agent_mesh/agent/utils/context_helpers.py +77 -0
  80. solace_agent_mesh/agent/utils/utils_llm.txt +152 -0
  81. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  82. solace_agent_mesh/assets/docs/404.html +16 -0
  83. solace_agent_mesh/assets/docs/assets/css/styles.8162edfb.css +1 -0
  84. solace_agent_mesh/assets/docs/assets/images/Solace_AI_Framework_With_Broker-85f0a306a9bcdd20b390b7a949f6d862.png +0 -0
  85. solace_agent_mesh/assets/docs/assets/images/sam-enterprise-credentials-b269f095349473118b2b33bdfcc40122.png +0 -0
  86. solace_agent_mesh/assets/docs/assets/js/032c2d61.f3d37824.js +1 -0
  87. solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
  88. solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
  89. solace_agent_mesh/assets/docs/assets/js/1001.0182a8bd.js +1 -0
  90. solace_agent_mesh/assets/docs/assets/js/1039.0bd46aa1.js +1 -0
  91. solace_agent_mesh/assets/docs/assets/js/149.b797a808.js +1 -0
  92. solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
  93. solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
  94. solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js +2 -0
  95. solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js.LICENSE.txt +9 -0
  96. solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
  97. solace_agent_mesh/assets/docs/assets/js/2130.ab9fd314.js +1 -0
  98. solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
  99. solace_agent_mesh/assets/docs/assets/js/2237.5e477fc6.js +1 -0
  100. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
  101. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js.LICENSE.txt +13 -0
  102. solace_agent_mesh/assets/docs/assets/js/2334.1cf50a20.js +1 -0
  103. solace_agent_mesh/assets/docs/assets/js/240a0364.9ad94d1b.js +1 -0
  104. solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
  105. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
  106. solace_agent_mesh/assets/docs/assets/js/3219.adc1d663.js +1 -0
  107. solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
  108. solace_agent_mesh/assets/docs/assets/js/3624.0eaa1fd0.js +1 -0
  109. solace_agent_mesh/assets/docs/assets/js/375.708d48db.js +1 -0
  110. solace_agent_mesh/assets/docs/assets/js/3834.b6cd790e.js +1 -0
  111. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
  112. solace_agent_mesh/assets/docs/assets/js/3ac1795d.28b7c67b.js +1 -0
  113. solace_agent_mesh/assets/docs/assets/js/3ff0015d.2ddc75c0.js +1 -0
  114. solace_agent_mesh/assets/docs/assets/js/41adc471.48b12a4e.js +1 -0
  115. solace_agent_mesh/assets/docs/assets/js/4250.95455b28.js +1 -0
  116. solace_agent_mesh/assets/docs/assets/js/4356.d169ab5b.js +1 -0
  117. solace_agent_mesh/assets/docs/assets/js/4458.518e66fa.js +1 -0
  118. solace_agent_mesh/assets/docs/assets/js/4488.c7cc3442.js +1 -0
  119. solace_agent_mesh/assets/docs/assets/js/4494.6ee23046.js +1 -0
  120. solace_agent_mesh/assets/docs/assets/js/4855.fc4444b6.js +1 -0
  121. solace_agent_mesh/assets/docs/assets/js/4866.22daefc0.js +1 -0
  122. solace_agent_mesh/assets/docs/assets/js/4950.ca4caeda.js +1 -0
  123. solace_agent_mesh/assets/docs/assets/js/509e993c.a1fbf45a.js +1 -0
  124. solace_agent_mesh/assets/docs/assets/js/5388.7a136447.js +1 -0
  125. solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
  126. solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
  127. solace_agent_mesh/assets/docs/assets/js/5607.081356f8.js +1 -0
  128. solace_agent_mesh/assets/docs/assets/js/5864.b0d0e9de.js +1 -0
  129. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.90a87880.js +1 -0
  130. solace_agent_mesh/assets/docs/assets/js/5e95c892.558d5167.js +1 -0
  131. solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
  132. solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
  133. solace_agent_mesh/assets/docs/assets/js/6143.0a1464c9.js +1 -0
  134. solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
  135. solace_agent_mesh/assets/docs/assets/js/6395.e9c73649.js +1 -0
  136. solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
  137. solace_agent_mesh/assets/docs/assets/js/66d4869e.b77431fc.js +1 -0
  138. solace_agent_mesh/assets/docs/assets/js/6796.51d2c9b7.js +1 -0
  139. solace_agent_mesh/assets/docs/assets/js/6976.379be23b.js +1 -0
  140. solace_agent_mesh/assets/docs/assets/js/6978.ee0b945c.js +1 -0
  141. solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
  142. solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
  143. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
  144. solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
  145. solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.js +1 -0
  146. solace_agent_mesh/assets/docs/assets/js/7040.cb436723.js +1 -0
  147. solace_agent_mesh/assets/docs/assets/js/7195.412f418a.js +1 -0
  148. solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
  149. solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
  150. solace_agent_mesh/assets/docs/assets/js/7280.3fb73bdb.js +1 -0
  151. solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
  152. solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.js +1 -0
  153. solace_agent_mesh/assets/docs/assets/js/7845.e33e7c4c.js +1 -0
  154. solace_agent_mesh/assets/docs/assets/js/7900.69516146.js +1 -0
  155. solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
  156. solace_agent_mesh/assets/docs/assets/js/81a99df0.2484b8d9.js +1 -0
  157. solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
  158. solace_agent_mesh/assets/docs/assets/js/8356.8a379c04.js +1 -0
  159. solace_agent_mesh/assets/docs/assets/js/8567.4732c6b7.js +1 -0
  160. solace_agent_mesh/assets/docs/assets/js/8573.cb04eda5.js +1 -0
  161. solace_agent_mesh/assets/docs/assets/js/8577.1d54e766.js +1 -0
  162. solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js +2 -0
  163. solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js.LICENSE.txt +61 -0
  164. solace_agent_mesh/assets/docs/assets/js/8709.7ecd4047.js +1 -0
  165. solace_agent_mesh/assets/docs/assets/js/8731.6c1dbf0c.js +1 -0
  166. solace_agent_mesh/assets/docs/assets/js/8908.f9d1b506.js +1 -0
  167. solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
  168. solace_agent_mesh/assets/docs/assets/js/9157.b4093d07.js +1 -0
  169. solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
  170. solace_agent_mesh/assets/docs/assets/js/9278.a4fd875d.js +1 -0
  171. solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
  172. solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
  173. solace_agent_mesh/assets/docs/assets/js/9616.b75c2f6d.js +1 -0
  174. solace_agent_mesh/assets/docs/assets/js/9793.c6d16376.js +1 -0
  175. solace_agent_mesh/assets/docs/assets/js/9bb13469.b2333011.js +1 -0
  176. solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
  177. solace_agent_mesh/assets/docs/assets/js/a7bd4aaa.2204d2f7.js +1 -0
  178. solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
  179. solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +1 -0
  180. solace_agent_mesh/assets/docs/assets/js/aba21aa0.c42a534c.js +1 -0
  181. solace_agent_mesh/assets/docs/assets/js/ad71b5ed.af3ecfd1.js +1 -0
  182. solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
  183. solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
  184. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
  185. solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
  186. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
  187. solace_agent_mesh/assets/docs/assets/js/ceb2a7a6.5d92d7d0.js +1 -0
  188. solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
  189. solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
  190. solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.js +1 -0
  191. solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
  192. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
  193. solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
  194. solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
  195. solace_agent_mesh/assets/docs/assets/js/e04b235d.52cb25ed.js +1 -0
  196. solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.b1068f9b.js +1 -0
  197. solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
  198. solace_agent_mesh/assets/docs/assets/js/e6f9706b.4488e34c.js +1 -0
  199. solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
  200. solace_agent_mesh/assets/docs/assets/js/f284c35a.250993bf.js +1 -0
  201. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
  202. solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js +2 -0
  203. solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js.LICENSE.txt +81 -0
  204. solace_agent_mesh/assets/docs/assets/js/runtime~main.9e0813a2.js +1 -0
  205. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +154 -0
  206. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +99 -0
  207. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +90 -0
  208. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +107 -0
  209. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +166 -0
  210. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +101 -0
  211. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +219 -0
  212. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +92 -0
  213. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
  214. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
  215. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
  216. solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
  217. solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
  218. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +345 -0
  219. solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
  220. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +83 -0
  221. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +84 -0
  222. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
  223. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
  224. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +85 -0
  225. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +60 -0
  226. solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
  227. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +144 -0
  228. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +191 -0
  229. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +128 -0
  230. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
  231. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
  232. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +34 -0
  233. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
  234. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +267 -0
  235. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +142 -0
  236. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +116 -0
  237. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +86 -0
  238. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +164 -0
  239. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +140 -0
  240. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +57 -0
  241. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
  242. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +102 -0
  243. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
  244. solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
  245. solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
  246. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +37 -0
  247. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +86 -0
  248. solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
  249. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +247 -0
  250. solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
  251. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +184 -0
  252. solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
  253. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
  254. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +54 -0
  255. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +85 -0
  256. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
  257. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
  258. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +78 -0
  259. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
  260. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +78 -0
  261. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +160 -0
  262. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
  263. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
  264. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
  265. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
  266. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +52 -0
  267. solace_agent_mesh/assets/docs/img/Solace_AI_Framework_With_Broker.png +0 -0
  268. solace_agent_mesh/assets/docs/img/logo.png +0 -0
  269. solace_agent_mesh/assets/docs/img/sac-flows.png +0 -0
  270. solace_agent_mesh/assets/docs/img/sac_parts_of_a_component.png +0 -0
  271. solace_agent_mesh/assets/docs/img/sam-enterprise-credentials.png +0 -0
  272. solace_agent_mesh/assets/docs/img/solace-logo-text.svg +18 -0
  273. solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
  274. solace_agent_mesh/assets/docs/lunr-index-1765810064709.json +1 -0
  275. solace_agent_mesh/assets/docs/lunr-index.json +1 -0
  276. solace_agent_mesh/assets/docs/search-doc-1765810064709.json +1 -0
  277. solace_agent_mesh/assets/docs/search-doc.json +1 -0
  278. solace_agent_mesh/assets/docs/sitemap.xml +1 -0
  279. solace_agent_mesh/cli/__init__.py +1 -0
  280. solace_agent_mesh/cli/commands/__init__.py +0 -0
  281. solace_agent_mesh/cli/commands/add_cmd/__init__.py +15 -0
  282. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +250 -0
  283. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +729 -0
  284. solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +322 -0
  285. solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +102 -0
  286. solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +114 -0
  287. solace_agent_mesh/cli/commands/docs_cmd.py +60 -0
  288. solace_agent_mesh/cli/commands/eval_cmd.py +46 -0
  289. solace_agent_mesh/cli/commands/init_cmd/__init__.py +439 -0
  290. solace_agent_mesh/cli/commands/init_cmd/broker_step.py +201 -0
  291. solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
  292. solace_agent_mesh/cli/commands/init_cmd/directory_step.py +28 -0
  293. solace_agent_mesh/cli/commands/init_cmd/env_step.py +238 -0
  294. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
  295. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +464 -0
  296. solace_agent_mesh/cli/commands/init_cmd/project_files_step.py +38 -0
  297. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +119 -0
  298. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +215 -0
  299. solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +20 -0
  300. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +137 -0
  301. solace_agent_mesh/cli/commands/plugin_cmd/build_cmd.py +86 -0
  302. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +144 -0
  303. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +306 -0
  304. solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +283 -0
  305. solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +175 -0
  306. solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +305 -0
  307. solace_agent_mesh/cli/commands/run_cmd.py +215 -0
  308. solace_agent_mesh/cli/main.py +52 -0
  309. solace_agent_mesh/cli/utils.py +262 -0
  310. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-Dj3JtK42.js +1 -0
  311. solace_agent_mesh/client/webui/frontend/static/assets/client-ZKk9kEJ5.js +25 -0
  312. solace_agent_mesh/client/webui/frontend/static/assets/favicon-BLgzUch9.ico +0 -0
  313. solace_agent_mesh/client/webui/frontend/static/assets/main-BcUaNZ-Q.css +1 -0
  314. solace_agent_mesh/client/webui/frontend/static/assets/main-vjch4RYc.js +435 -0
  315. solace_agent_mesh/client/webui/frontend/static/assets/vendor-BNV4kZN0.js +535 -0
  316. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +15 -0
  317. solace_agent_mesh/client/webui/frontend/static/index.html +16 -0
  318. solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
  319. solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
  320. solace_agent_mesh/common/__init__.py +1 -0
  321. solace_agent_mesh/common/a2a/__init__.py +241 -0
  322. solace_agent_mesh/common/a2a/a2a_llm.txt +175 -0
  323. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  324. solace_agent_mesh/common/a2a/artifact.py +368 -0
  325. solace_agent_mesh/common/a2a/events.py +213 -0
  326. solace_agent_mesh/common/a2a/message.py +375 -0
  327. solace_agent_mesh/common/a2a/protocol.py +689 -0
  328. solace_agent_mesh/common/a2a/task.py +127 -0
  329. solace_agent_mesh/common/a2a/translation.py +655 -0
  330. solace_agent_mesh/common/a2a/types.py +55 -0
  331. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  332. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +445 -0
  333. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  334. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  335. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +48 -0
  336. solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
  337. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +41 -0
  338. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +330 -0
  339. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  340. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +48 -0
  341. solace_agent_mesh/common/agent_registry.py +122 -0
  342. solace_agent_mesh/common/common_llm.txt +230 -0
  343. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  344. solace_agent_mesh/common/constants.py +6 -0
  345. solace_agent_mesh/common/data_parts.py +150 -0
  346. solace_agent_mesh/common/exceptions.py +49 -0
  347. solace_agent_mesh/common/middleware/__init__.py +12 -0
  348. solace_agent_mesh/common/middleware/config_resolver.py +132 -0
  349. solace_agent_mesh/common/middleware/middleware_llm.txt +174 -0
  350. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  351. solace_agent_mesh/common/middleware/registry.py +127 -0
  352. solace_agent_mesh/common/oauth/__init__.py +17 -0
  353. solace_agent_mesh/common/oauth/oauth_client.py +408 -0
  354. solace_agent_mesh/common/oauth/utils.py +50 -0
  355. solace_agent_mesh/common/sac/__init__.py +0 -0
  356. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  357. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  358. solace_agent_mesh/common/sac/sam_component_base.py +730 -0
  359. solace_agent_mesh/common/sam_events/__init__.py +9 -0
  360. solace_agent_mesh/common/sam_events/event_service.py +208 -0
  361. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  362. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  363. solace_agent_mesh/common/services/__init__.py +4 -0
  364. solace_agent_mesh/common/services/employee_service.py +164 -0
  365. solace_agent_mesh/common/services/identity_service.py +134 -0
  366. solace_agent_mesh/common/services/providers/__init__.py +4 -0
  367. solace_agent_mesh/common/services/providers/local_file_identity_service.py +151 -0
  368. solace_agent_mesh/common/services/providers/providers_llm.txt +81 -0
  369. solace_agent_mesh/common/services/services_llm.txt +368 -0
  370. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  371. solace_agent_mesh/common/utils/__init__.py +7 -0
  372. solace_agent_mesh/common/utils/artifact_utils.py +31 -0
  373. solace_agent_mesh/common/utils/asyncio_macos_fix.py +88 -0
  374. solace_agent_mesh/common/utils/embeds/__init__.py +33 -0
  375. solace_agent_mesh/common/utils/embeds/constants.py +56 -0
  376. solace_agent_mesh/common/utils/embeds/converter.py +447 -0
  377. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +220 -0
  378. solace_agent_mesh/common/utils/embeds/evaluators.py +395 -0
  379. solace_agent_mesh/common/utils/embeds/modifiers.py +793 -0
  380. solace_agent_mesh/common/utils/embeds/resolver.py +967 -0
  381. solace_agent_mesh/common/utils/embeds/types.py +23 -0
  382. solace_agent_mesh/common/utils/in_memory_cache.py +108 -0
  383. solace_agent_mesh/common/utils/initializer.py +52 -0
  384. solace_agent_mesh/common/utils/log_formatters.py +64 -0
  385. solace_agent_mesh/common/utils/message_utils.py +80 -0
  386. solace_agent_mesh/common/utils/mime_helpers.py +172 -0
  387. solace_agent_mesh/common/utils/push_notification_auth.py +135 -0
  388. solace_agent_mesh/common/utils/pydantic_utils.py +159 -0
  389. solace_agent_mesh/common/utils/rbac_utils.py +69 -0
  390. solace_agent_mesh/common/utils/templates/__init__.py +8 -0
  391. solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
  392. solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
  393. solace_agent_mesh/common/utils/type_utils.py +28 -0
  394. solace_agent_mesh/common/utils/utils_llm.txt +335 -0
  395. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  396. solace_agent_mesh/config_portal/__init__.py +0 -0
  397. solace_agent_mesh/config_portal/backend/__init__.py +0 -0
  398. solace_agent_mesh/config_portal/backend/common.py +77 -0
  399. solace_agent_mesh/config_portal/backend/plugin_catalog/__init__.py +0 -0
  400. solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +24 -0
  401. solace_agent_mesh/config_portal/backend/plugin_catalog/models.py +49 -0
  402. solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +166 -0
  403. solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +521 -0
  404. solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +217 -0
  405. solace_agent_mesh/config_portal/backend/server.py +644 -0
  406. solace_agent_mesh/config_portal/frontend/static/client/Solace_community_logo.png +0 -0
  407. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DiOiAjzL.js +103 -0
  408. solace_agent_mesh/config_portal/frontend/static/client/assets/components-Rk0n-9cK.js +140 -0
  409. solace_agent_mesh/config_portal/frontend/static/client/assets/entry.client-mvZjNKiz.js +19 -0
  410. solace_agent_mesh/config_portal/frontend/static/client/assets/index-DzNKzXrc.js +68 -0
  411. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-ba77705e.js +1 -0
  412. solace_agent_mesh/config_portal/frontend/static/client/assets/root-B17tZKK7.css +1 -0
  413. solace_agent_mesh/config_portal/frontend/static/client/assets/root-V2BeTIUc.js +10 -0
  414. solace_agent_mesh/config_portal/frontend/static/client/favicon.ico +0 -0
  415. solace_agent_mesh/config_portal/frontend/static/client/index.html +7 -0
  416. solace_agent_mesh/core_a2a/__init__.py +1 -0
  417. solace_agent_mesh/core_a2a/core_a2a_llm.txt +90 -0
  418. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  419. solace_agent_mesh/core_a2a/service.py +307 -0
  420. solace_agent_mesh/evaluation/__init__.py +0 -0
  421. solace_agent_mesh/evaluation/evaluator.py +691 -0
  422. solace_agent_mesh/evaluation/message_organizer.py +553 -0
  423. solace_agent_mesh/evaluation/report/benchmark_info.html +35 -0
  424. solace_agent_mesh/evaluation/report/chart_section.html +141 -0
  425. solace_agent_mesh/evaluation/report/detailed_breakdown.html +28 -0
  426. solace_agent_mesh/evaluation/report/modal.html +59 -0
  427. solace_agent_mesh/evaluation/report/modal_chart_functions.js +411 -0
  428. solace_agent_mesh/evaluation/report/modal_script.js +296 -0
  429. solace_agent_mesh/evaluation/report/modal_styles.css +340 -0
  430. solace_agent_mesh/evaluation/report/performance_metrics_styles.css +93 -0
  431. solace_agent_mesh/evaluation/report/templates/footer.html +2 -0
  432. solace_agent_mesh/evaluation/report/templates/header.html +340 -0
  433. solace_agent_mesh/evaluation/report_data_processor.py +970 -0
  434. solace_agent_mesh/evaluation/report_generator.py +607 -0
  435. solace_agent_mesh/evaluation/run.py +954 -0
  436. solace_agent_mesh/evaluation/shared/__init__.py +92 -0
  437. solace_agent_mesh/evaluation/shared/constants.py +47 -0
  438. solace_agent_mesh/evaluation/shared/exceptions.py +50 -0
  439. solace_agent_mesh/evaluation/shared/helpers.py +35 -0
  440. solace_agent_mesh/evaluation/shared/test_case_loader.py +167 -0
  441. solace_agent_mesh/evaluation/shared/test_suite_loader.py +280 -0
  442. solace_agent_mesh/evaluation/subscriber.py +776 -0
  443. solace_agent_mesh/evaluation/summary_builder.py +880 -0
  444. solace_agent_mesh/gateway/__init__.py +0 -0
  445. solace_agent_mesh/gateway/adapter/__init__.py +1 -0
  446. solace_agent_mesh/gateway/adapter/base.py +143 -0
  447. solace_agent_mesh/gateway/adapter/types.py +221 -0
  448. solace_agent_mesh/gateway/base/__init__.py +1 -0
  449. solace_agent_mesh/gateway/base/app.py +345 -0
  450. solace_agent_mesh/gateway/base/base_llm.txt +226 -0
  451. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  452. solace_agent_mesh/gateway/base/component.py +2030 -0
  453. solace_agent_mesh/gateway/base/task_context.py +75 -0
  454. solace_agent_mesh/gateway/gateway_llm.txt +369 -0
  455. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  456. solace_agent_mesh/gateway/generic/__init__.py +1 -0
  457. solace_agent_mesh/gateway/generic/app.py +50 -0
  458. solace_agent_mesh/gateway/generic/component.py +727 -0
  459. solace_agent_mesh/gateway/http_sse/__init__.py +0 -0
  460. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +345 -0
  461. solace_agent_mesh/gateway/http_sse/alembic/env.py +87 -0
  462. solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
  463. solace_agent_mesh/gateway/http_sse/alembic/versions/20250910_d5b3f8f2e9a0_create_initial_database.py +58 -0
  464. solace_agent_mesh/gateway/http_sse/alembic/versions/20250911_b1c2d3e4f5g6_add_database_indexes.py +83 -0
  465. solace_agent_mesh/gateway/http_sse/alembic/versions/20250916_f6e7d8c9b0a1_convert_timestamps_to_epoch_and_align_columns.py +412 -0
  466. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  467. solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
  468. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
  469. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
  470. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
  471. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
  472. solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
  473. solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
  474. solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
  475. solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
  476. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +161 -0
  477. solace_agent_mesh/gateway/http_sse/alembic.ini +109 -0
  478. solace_agent_mesh/gateway/http_sse/app.py +351 -0
  479. solace_agent_mesh/gateway/http_sse/component.py +2360 -0
  480. solace_agent_mesh/gateway/http_sse/components/__init__.py +7 -0
  481. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +105 -0
  482. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
  483. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +110 -0
  484. solace_agent_mesh/gateway/http_sse/dependencies.py +653 -0
  485. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +299 -0
  486. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  487. solace_agent_mesh/gateway/http_sse/main.py +789 -0
  488. solace_agent_mesh/gateway/http_sse/repository/__init__.py +46 -0
  489. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +102 -0
  490. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +11 -0
  491. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  492. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +221 -0
  493. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  494. solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
  495. solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
  496. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +66 -0
  497. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -0
  498. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +32 -0
  499. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  500. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +125 -0
  501. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +239 -0
  502. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +34 -0
  503. solace_agent_mesh/gateway/http_sse/repository/models/base.py +7 -0
  504. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  505. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  506. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +257 -0
  507. solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
  508. solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
  509. solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
  510. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +53 -0
  511. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  512. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +39 -0
  513. solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
  514. solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
  515. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +308 -0
  516. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +268 -0
  517. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +248 -0
  518. solace_agent_mesh/gateway/http_sse/routers/__init__.py +4 -0
  519. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +74 -0
  520. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1137 -0
  521. solace_agent_mesh/gateway/http_sse/routers/auth.py +311 -0
  522. solace_agent_mesh/gateway/http_sse/routers/config.py +371 -0
  523. solace_agent_mesh/gateway/http_sse/routers/dto/__init__.py +10 -0
  524. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +450 -0
  525. solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
  526. solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
  527. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +15 -0
  528. solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
  529. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +133 -0
  530. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +33 -0
  531. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  532. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +18 -0
  533. solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +42 -0
  534. solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
  535. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +123 -0
  536. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +33 -0
  537. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  538. solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
  539. solace_agent_mesh/gateway/http_sse/routers/feedback.py +168 -0
  540. solace_agent_mesh/gateway/http_sse/routers/people.py +38 -0
  541. solace_agent_mesh/gateway/http_sse/routers/projects.py +767 -0
  542. solace_agent_mesh/gateway/http_sse/routers/prompts.py +1415 -0
  543. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +312 -0
  544. solace_agent_mesh/gateway/http_sse/routers/sessions.py +634 -0
  545. solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
  546. solace_agent_mesh/gateway/http_sse/routers/sse.py +230 -0
  547. solace_agent_mesh/gateway/http_sse/routers/tasks.py +1089 -0
  548. solace_agent_mesh/gateway/http_sse/routers/users.py +83 -0
  549. solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
  550. solace_agent_mesh/gateway/http_sse/routers/visualization.py +1220 -0
  551. solace_agent_mesh/gateway/http_sse/services/__init__.py +4 -0
  552. solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +71 -0
  553. solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
  554. solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
  555. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +273 -0
  556. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +250 -0
  557. solace_agent_mesh/gateway/http_sse/services/people_service.py +78 -0
  558. solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
  559. solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
  560. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +303 -0
  561. solace_agent_mesh/gateway/http_sse/services/session_service.py +702 -0
  562. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +593 -0
  563. solace_agent_mesh/gateway/http_sse/services/task_service.py +119 -0
  564. solace_agent_mesh/gateway/http_sse/session_manager.py +219 -0
  565. solace_agent_mesh/gateway/http_sse/shared/__init__.py +146 -0
  566. solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
  567. solace_agent_mesh/gateway/http_sse/shared/base_repository.py +252 -0
  568. solace_agent_mesh/gateway/http_sse/shared/database_exceptions.py +274 -0
  569. solace_agent_mesh/gateway/http_sse/shared/database_helpers.py +43 -0
  570. solace_agent_mesh/gateway/http_sse/shared/enums.py +40 -0
  571. solace_agent_mesh/gateway/http_sse/shared/error_dto.py +107 -0
  572. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +217 -0
  573. solace_agent_mesh/gateway/http_sse/shared/exceptions.py +192 -0
  574. solace_agent_mesh/gateway/http_sse/shared/pagination.py +138 -0
  575. solace_agent_mesh/gateway/http_sse/shared/response_utils.py +134 -0
  576. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +319 -0
  577. solace_agent_mesh/gateway/http_sse/shared/timestamp_utils.py +97 -0
  578. solace_agent_mesh/gateway/http_sse/shared/types.py +50 -0
  579. solace_agent_mesh/gateway/http_sse/shared/utils.py +22 -0
  580. solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +88 -0
  581. solace_agent_mesh/gateway/http_sse/sse_manager.py +491 -0
  582. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  583. solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
  584. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +72 -0
  585. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  586. solace_agent_mesh/llm.txt +228 -0
  587. solace_agent_mesh/llm_detail.txt +2835 -0
  588. solace_agent_mesh/services/__init__.py +0 -0
  589. solace_agent_mesh/services/platform/__init__.py +18 -0
  590. solace_agent_mesh/services/platform/alembic/env.py +85 -0
  591. solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
  592. solace_agent_mesh/services/platform/alembic.ini +109 -0
  593. solace_agent_mesh/services/platform/api/__init__.py +3 -0
  594. solace_agent_mesh/services/platform/api/dependencies.py +147 -0
  595. solace_agent_mesh/services/platform/api/main.py +280 -0
  596. solace_agent_mesh/services/platform/api/middleware.py +51 -0
  597. solace_agent_mesh/services/platform/api/routers/__init__.py +24 -0
  598. solace_agent_mesh/services/platform/app.py +114 -0
  599. solace_agent_mesh/services/platform/component.py +235 -0
  600. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  601. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  602. solace_agent_mesh/templates/agent_template.yaml +53 -0
  603. solace_agent_mesh/templates/eval_backend_template.yaml +54 -0
  604. solace_agent_mesh/templates/gateway_app_template.py +75 -0
  605. solace_agent_mesh/templates/gateway_component_template.py +484 -0
  606. solace_agent_mesh/templates/gateway_config_template.yaml +38 -0
  607. solace_agent_mesh/templates/logging_config_template.yaml +48 -0
  608. solace_agent_mesh/templates/main_orchestrator.yaml +66 -0
  609. solace_agent_mesh/templates/plugin_agent_config_template.yaml +122 -0
  610. solace_agent_mesh/templates/plugin_custom_config_template.yaml +27 -0
  611. solace_agent_mesh/templates/plugin_custom_template.py +10 -0
  612. solace_agent_mesh/templates/plugin_gateway_config_template.yaml +60 -0
  613. solace_agent_mesh/templates/plugin_pyproject_template.toml +32 -0
  614. solace_agent_mesh/templates/plugin_readme_template.md +12 -0
  615. solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
  616. solace_agent_mesh/templates/plugin_tools_template.py +224 -0
  617. solace_agent_mesh/templates/shared_config.yaml +112 -0
  618. solace_agent_mesh/templates/templates_llm.txt +147 -0
  619. solace_agent_mesh/templates/webui.yaml +177 -0
  620. solace_agent_mesh-1.11.2.dist-info/METADATA +504 -0
  621. solace_agent_mesh-1.11.2.dist-info/RECORD +624 -0
  622. solace_agent_mesh-1.11.2.dist-info/WHEEL +4 -0
  623. solace_agent_mesh-1.11.2.dist-info/entry_points.txt +3 -0
  624. solace_agent_mesh-1.11.2.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,954 @@
1
+ """
2
+ Refactored evaluation runner with improved structure and readability.
3
+ This module orchestrates the evaluation of AI models against test cases.
4
+ """
5
+
6
+ import json
7
+ import logging
8
+ import mimetypes
9
+ import os
10
+ import shutil
11
+ import subprocess
12
+ import sys
13
+ import threading
14
+ import time
15
+ import uuid
16
+ from concurrent.futures import ThreadPoolExecutor, as_completed
17
+ from dataclasses import dataclass
18
+ from importlib import metadata
19
+ from pathlib import Path
20
+
21
+ import click
22
+ import requests
23
+ from dotenv import load_dotenv
24
+
25
+ from .evaluator import EvaluationOrchestrator
26
+ from .message_organizer import MessageOrganizer
27
+ from .report_generator import ReportGenerator
28
+ from .shared import (
29
+ DEFAULT_STARTUP_WAIT_TIME,
30
+ DEFAULT_TEST_TIMEOUT,
31
+ EVALUATION_DIR,
32
+ MAX_ARTIFACT_SIZE_MB,
33
+ EvaluationConfigLoader,
34
+ TestSuiteConfiguration,
35
+ get_local_base_url,
36
+ )
37
+ from .subscriber import Subscriber
38
+ from .summary_builder import SummaryBuilder
39
+
40
+ log = logging.getLogger(__name__)
41
+
42
+
43
+ def _error_exit(message: str):
44
+ """Logs an error message and exits."""
45
+ log.error(message)
46
+ sys.exit(1)
47
+
48
+
49
+ def _ensure_eval_backend_config_exists():
50
+ """Checks for eval_backend.yaml and creates it from a template if missing."""
51
+ project_root = Path.cwd()
52
+ configs_dir = project_root / "configs"
53
+ eval_backend_config_path = configs_dir / "eval_backend.yaml"
54
+
55
+ if eval_backend_config_path.exists():
56
+ return
57
+
58
+ click.echo(
59
+ f"'{eval_backend_config_path.relative_to(project_root)}' not found. Creating it..."
60
+ )
61
+
62
+ if not (configs_dir / "shared_config.yaml").exists():
63
+ _error_exit(
64
+ "Error: 'configs/shared_config.yaml' not found. Please run 'sam init' first."
65
+ )
66
+
67
+ try:
68
+ # This is a simplified way to get the template content.
69
+ # In a real CLI, you'd use a more robust method like `importlib.resources`.
70
+ template_path = Path(__file__).parent.parent / "templates" / "eval_backend_template.yaml"
71
+ with open(template_path, encoding="utf-8") as f:
72
+ template_content = f.read()
73
+
74
+ with open(eval_backend_config_path, "w", encoding="utf-8") as f:
75
+ f.write(template_content)
76
+ click.echo(
77
+ click.style(
78
+ f"Successfully created '{eval_backend_config_path.relative_to(project_root)}'.",
79
+ fg="green",
80
+ )
81
+ )
82
+ except Exception as e:
83
+ _error_exit(f"Failed to create eval_backend.yaml: {e}")
84
+
85
+
86
+ def _ensure_sam_rest_gateway_installed():
87
+ """Checks if the sam-rest-gateway package is installed for local evaluation."""
88
+ try:
89
+ metadata.distribution("sam-rest-gateway")
90
+ except metadata.PackageNotFoundError:
91
+ _error_exit(
92
+ "Error: 'sam-rest-gateway' is not installed. "
93
+ "Please install it using: "
94
+ 'pip install "sam-rest-gateway @ git+https://github.com/SolaceLabs/solace-agent-mesh-core-plugins#subdirectory=sam-rest-gateway"'
95
+ )
96
+
97
+
98
+ @dataclass
99
+ class TestRun:
100
+ """Represents a single test execution with all necessary parameters."""
101
+
102
+ agent: str
103
+ query: str
104
+ artifacts: list[str]
105
+ wait_time: int
106
+ test_case_file: str
107
+ run_num: int
108
+
109
+ @property
110
+ def test_case_id(self) -> str:
111
+ """Extract test case ID from filename."""
112
+ return Path(self.test_case_file).stem.replace(".test", "")
113
+
114
+
115
+ class ProcessManager:
116
+ """Manages subprocess lifecycle for the Solace AI Connector."""
117
+
118
+ def __init__(self, config: TestSuiteConfiguration, verbose: bool = False):
119
+ self.config = config
120
+ self.process: subprocess.Popen | None = None
121
+ self.namespace: str | None = None
122
+ self.verbose = verbose
123
+
124
+ def start_services(self) -> tuple[subprocess.Popen, str]:
125
+ """Start the Solace AI Connector and return process and namespace."""
126
+ load_dotenv()
127
+ self.namespace = f"eval-{uuid.uuid4()}"
128
+ os.environ["NAMESPACE"] = self.namespace
129
+
130
+ # Set broker environment variables from the required configuration
131
+ log.info("Setting broker configuration from test suite...")
132
+ for key, value in self.config.broker.dict().items():
133
+ if value is not None:
134
+ env_key = f"SOLACE_BROKER_{key.upper()}"
135
+ os.environ[env_key] = str(value)
136
+ log.info(f" - Set {env_key}")
137
+
138
+ agent_files = self.config.agent_configs
139
+
140
+ command = [sys.executable, "-m", "solace_ai_connector.main", *agent_files]
141
+
142
+ log.info("Starting Solace AI Connector as a subprocess...")
143
+ project_root = Path(EVALUATION_DIR).parent.resolve()
144
+
145
+ self.process = subprocess.Popen(
146
+ command, stdout=sys.stdout, stderr=sys.stderr, cwd=project_root
147
+ )
148
+
149
+ log.info("Waiting for server to become healthy...")
150
+ self._wait_for_server_ready(get_local_base_url())
151
+
152
+ return self.process, self.namespace
153
+
154
+ def _wait_for_server_ready(self, base_url: str):
155
+ """Poll the health endpoint until the server is ready."""
156
+ start_time = time.time()
157
+ health_url = f"{base_url}/health"
158
+
159
+ while time.time() - start_time < DEFAULT_STARTUP_WAIT_TIME:
160
+ try:
161
+ response = requests.get(health_url)
162
+ if response.status_code == 200:
163
+ log.info("Server is healthy.")
164
+ time.sleep(5)
165
+ return
166
+ except requests.ConnectionError:
167
+ # Server is not yet available, wait and retry
168
+ time.sleep(1)
169
+ except Exception as e:
170
+ log.error(f"An unexpected error occurred during health check: {e}")
171
+ time.sleep(1)
172
+
173
+ raise RuntimeError(
174
+ f"Server did not become healthy within {DEFAULT_STARTUP_WAIT_TIME} seconds."
175
+ )
176
+
177
+ def stop_services(self, subscriber: Subscriber | None = None):
178
+ """Clean up running processes."""
179
+ if subscriber:
180
+ log.info("Terminating subscriber")
181
+ subscriber.stop()
182
+ subscriber.join()
183
+ log.info("Subscriber terminated.")
184
+
185
+ if self.process:
186
+ log.info("Terminating subprocess")
187
+ self.process.terminate()
188
+ try:
189
+ self.process.wait(timeout=5)
190
+ log.info("Subprocess terminated.")
191
+ except subprocess.TimeoutExpired:
192
+ log.info("Subprocess did not terminate gracefully, killing.")
193
+ self.process.kill()
194
+
195
+ log.info("Process cleanup completed.")
196
+
197
+
198
+ class TaskService:
199
+ """Handles task submission and tracking."""
200
+
201
+ def __init__(self, config: TestSuiteConfiguration, verbose: bool = False):
202
+ self.verbose = verbose
203
+ self.config = config
204
+ if config.remote:
205
+ self.base_url = config.remote.environment.get("EVAL_REMOTE_URL")
206
+ else:
207
+ self.base_url = get_local_base_url()
208
+
209
+ def submit_task(
210
+ self, agent_name: str, message: str, artifact_paths: list[str] | None = None
211
+ ) -> str | None:
212
+ """Submit a test case to the agent and return the task ID."""
213
+ log.info("Sending test request")
214
+ url = f"{self.base_url}/api/v2/tasks"
215
+ data = {
216
+ "agent_name": agent_name,
217
+ "prompt": message,
218
+ }
219
+
220
+ headers = {}
221
+ if self.config.remote:
222
+ auth_token = self.config.remote.environment.get("EVAL_AUTH_TOKEN")
223
+ if auth_token:
224
+ headers["Authorization"] = f"Bearer {auth_token}"
225
+
226
+ files_to_upload = []
227
+ if artifact_paths:
228
+ files_to_upload = self._prepare_file_uploads(artifact_paths)
229
+
230
+ try:
231
+ with requests.Session() as session:
232
+ response = session.post(url, data=data, files=files_to_upload, headers=headers)
233
+
234
+ response.raise_for_status()
235
+ task_id = response.json()["taskId"]
236
+ log.info(f"Task submitted with ID: {task_id}")
237
+ return task_id
238
+
239
+ except requests.RequestException as e:
240
+ log.error(f"Failed to submit task: {e}")
241
+ return None
242
+ finally:
243
+ self._close_file_uploads(files_to_upload)
244
+
245
+ def _prepare_file_uploads(self, artifact_paths: list[str]) -> list[tuple]:
246
+ """Prepare file uploads for the request."""
247
+ files_to_upload = []
248
+ for path_str in artifact_paths:
249
+ path = Path(path_str)
250
+ # Check file size before reading
251
+ try:
252
+ file_size_mb = path.stat().st_size / (1024 * 1024)
253
+ if file_size_mb > MAX_ARTIFACT_SIZE_MB:
254
+ log.warning(
255
+ f"Artifact '{path.name}' is {file_size_mb:.2f} MB, "
256
+ f"which is larger than the recommended maximum of {MAX_ARTIFACT_SIZE_MB} MB. "
257
+ "This may cause memory issues."
258
+ )
259
+ except OSError as e:
260
+ log.error(f"Could not get size of artifact {path}: {e}")
261
+ continue
262
+
263
+ mimetype, _ = mimetypes.guess_type(path)
264
+ if mimetype is None:
265
+ mimetype = "text/plain"
266
+ # Read file content with context manager
267
+ with path.open("rb") as f:
268
+ file_content = f.read()
269
+ files_to_upload.append(("files", (path.name, file_content, mimetype)))
270
+ return files_to_upload
271
+
272
+ def _close_file_uploads(self, files_to_upload: list[tuple]):
273
+ """Close file handles after upload (no longer needed)."""
274
+ # No longer needed
275
+ pass
276
+
277
+
278
+ class FileService:
279
+ """Handles file operations and path management."""
280
+
281
+ @staticmethod
282
+ def ensure_directory(path: Path):
283
+ """Ensure directory exists, create if necessary."""
284
+ path.mkdir(parents=True, exist_ok=True)
285
+
286
+ @staticmethod
287
+ def remove_directory(path: Path):
288
+ """Remove directory and all contents."""
289
+ if path.exists():
290
+ shutil.rmtree(path)
291
+
292
+ @staticmethod
293
+ def save_json(data: any, filepath: Path):
294
+ """Save data as JSON to file."""
295
+ with filepath.open("w") as f:
296
+ json.dump(data, f, indent=4)
297
+
298
+ @staticmethod
299
+ def load_json(filepath: Path) -> any:
300
+ """Load JSON data from file."""
301
+ with filepath.open() as f:
302
+ return json.load(f)
303
+
304
+
305
+ class TestRunBuilder:
306
+ """Builds test run configurations from test cases."""
307
+
308
+ def __init__(self, config: TestSuiteConfiguration):
309
+ self.config = config
310
+
311
+ def build_test_runs(self) -> list[TestRun]:
312
+ """Build all test runs from configuration."""
313
+ test_runs = []
314
+
315
+ for test_case_path in self.config.test_case_files:
316
+ test_case = FileService.load_json(Path(test_case_path))
317
+
318
+ artifact_paths = self._get_artifact_paths(test_case, test_case_path)
319
+
320
+ for run_num in range(1, self.config.run_count + 1):
321
+ test_run = TestRun(
322
+ agent=test_case["target_agent"],
323
+ query=test_case["query"],
324
+ artifacts=artifact_paths,
325
+ wait_time=test_case.get("wait_time", DEFAULT_TEST_TIMEOUT),
326
+ test_case_file=test_case_path,
327
+ run_num=run_num,
328
+ )
329
+ test_runs.append(test_run)
330
+
331
+ return test_runs
332
+
333
+ def _get_artifact_paths(self, test_case: dict, test_case_path: str) -> list[str]:
334
+ """Extract artifact paths from test case."""
335
+ artifact_paths = []
336
+ if "artifacts" in test_case:
337
+ test_case_dir = Path(test_case_path).parent
338
+ for artifact in test_case["artifacts"]:
339
+ if artifact.get("type") == "file":
340
+ artifact_paths.append(str(test_case_dir / artifact["path"]))
341
+ return artifact_paths
342
+
343
+
344
+ class TestExecutor:
345
+ """Executes individual test runs."""
346
+
347
+ def __init__(self, task_service: TaskService, file_service: FileService, verbose: bool = False):
348
+ self.task_service = task_service
349
+ self.file_service = file_service
350
+ self.verbose = verbose
351
+
352
+ def execute_test(
353
+ self,
354
+ test_run: TestRun,
355
+ model_results_path: Path,
356
+ task_mappings: dict[str, str],
357
+ subscriber: Subscriber,
358
+ task_mappings_lock: threading.Lock,
359
+ ) -> bool:
360
+ """Execute a single test case and wait for completion."""
361
+ log.info(
362
+ f"Starting test: {test_run.test_case_file} (run {test_run.run_num})"
363
+ )
364
+
365
+ # Submit the task
366
+ task_id = self.task_service.submit_task(
367
+ test_run.agent, test_run.query, test_run.artifacts
368
+ )
369
+
370
+ if not task_id:
371
+ log.error(
372
+ f"Failed to start test case: {test_run.test_case_file} (run {test_run.run_num})"
373
+ )
374
+ return False
375
+
376
+ # Set up result directory
377
+ test_case_name = Path(test_run.test_case_file).stem.replace(".test", "")
378
+ run_dir = model_results_path / test_case_name / f"run_{test_run.run_num}"
379
+ self.file_service.ensure_directory(run_dir)
380
+
381
+ # Save test case path for summary builder
382
+ test_info = {"path": test_run.test_case_file}
383
+ self.file_service.save_json(test_info, run_dir / "test_case_info.json")
384
+
385
+ # Track the task
386
+ with task_mappings_lock:
387
+ task_mappings[task_id] = str(run_dir)
388
+ subscriber.active_tasks.add(task_id)
389
+
390
+ # Wait for completion
391
+ return self._wait_for_completion(task_id, test_run.wait_time, subscriber)
392
+
393
+ def _wait_for_completion(
394
+ self, task_id: str, wait_time: int, subscriber: Subscriber
395
+ ) -> bool:
396
+ """Wait for task completion with timeout."""
397
+ log.info(
398
+ f"Waiting for task {task_id} to complete (timeout: {wait_time} seconds)..."
399
+ )
400
+
401
+ start_time = time.time()
402
+ while task_id in subscriber.active_tasks:
403
+ if time.time() - start_time > wait_time:
404
+ log.warning(f"Task {task_id} timed out after {wait_time} seconds")
405
+ subscriber.active_tasks.discard(task_id)
406
+ return False
407
+ time.sleep(1)
408
+
409
+ log.info(f"Task {task_id} completed successfully")
410
+ return True
411
+
412
+
413
+ class ModelEvaluator:
414
+ """Handles the evaluation of a single model."""
415
+
416
+ def __init__(self, config: TestSuiteConfiguration, verbose: bool = False):
417
+ self.config = config
418
+ self.process_manager = ProcessManager(config, verbose=verbose)
419
+ self.task_service = TaskService(config, verbose=verbose)
420
+ self.file_service = FileService()
421
+ self.test_builder = TestRunBuilder(config)
422
+ self.test_executor = TestExecutor(self.task_service, self.file_service, verbose=verbose)
423
+ self.verbose = verbose
424
+ self._task_mappings_lock = threading.Lock()
425
+
426
+ def evaluate_model(
427
+ self, model_config: dict[str, any], base_results_path: Path
428
+ ) -> float:
429
+ """Evaluate a single model and return execution time."""
430
+ model_name = model_config.name
431
+ log.info(f"Starting evaluation for model: {model_name}")
432
+ start_time = time.time()
433
+
434
+ # Set environment variables for the model
435
+ self._set_model_environment(model_config)
436
+
437
+ # Set up paths
438
+ model_results_path = base_results_path / model_name
439
+ self.file_service.ensure_directory(model_results_path)
440
+
441
+ # Start services
442
+ app_process, namespace = self.process_manager.start_services()
443
+
444
+ # Set up subscriber
445
+ subscriber = self._setup_subscriber(namespace, model_results_path)
446
+
447
+ try:
448
+ # Execute tests
449
+ successful_tests = self._execute_all_tests(model_results_path, subscriber)
450
+ log.info(f"Completed {successful_tests} tests successfully")
451
+
452
+ except Exception as e:
453
+ log.error(f"Error during test case execution for model {model_name}: {e}")
454
+ finally:
455
+ # Cleanup
456
+ task_mappings = getattr(self, "_task_mappings", {})
457
+ self._cleanup_model_evaluation(
458
+ app_process, subscriber, model_results_path, task_mappings
459
+ )
460
+
461
+ end_time = time.time()
462
+ execution_time = end_time - start_time
463
+ log.info(
464
+ f"Evaluation for model: {model_name} complete in {execution_time:.2f} seconds"
465
+ )
466
+
467
+ return execution_time
468
+
469
+ def _set_model_environment(self, model_config: dict[str, any]):
470
+ """Set environment variables for the model."""
471
+ for key, value in model_config.environment.variables.items():
472
+ if value is not None:
473
+ os.environ[key] = value
474
+
475
+ def _setup_subscriber(self, namespace: str, model_results_path: Path) -> Subscriber:
476
+ """Set up and start the subscriber."""
477
+ subscription_ready_event = threading.Event()
478
+ subscriber = Subscriber(
479
+ self.config.broker,
480
+ namespace,
481
+ set(),
482
+ None,
483
+ subscription_ready_event,
484
+ model_results_path,
485
+ )
486
+ subscriber.start()
487
+
488
+ log.info("Waiting for subscriber to be ready...")
489
+ subscription_ready_event.wait()
490
+ log.info("Subscriber is ready.")
491
+
492
+ return subscriber
493
+
494
+ def _execute_all_tests(
495
+ self, model_results_path: Path, subscriber: Subscriber
496
+ ) -> int:
497
+ """Execute all test cases in parallel and return count of successful tests."""
498
+ test_runs = self.test_builder.build_test_runs()
499
+
500
+ self._task_mappings = {}
501
+ total_tests = len(test_runs)
502
+ successful_tests = 0
503
+
504
+ log.info(
505
+ f"Starting parallel execution of {total_tests} tests with {self.config.workers} workers."
506
+ )
507
+
508
+ with ThreadPoolExecutor(max_workers=self.config.workers) as executor:
509
+ # Create a dictionary to map futures to their test_run
510
+ future_to_run = {
511
+ executor.submit(
512
+ self.test_executor.execute_test,
513
+ test_run,
514
+ model_results_path,
515
+ self._task_mappings,
516
+ subscriber,
517
+ self._task_mappings_lock, # Pass the lock to the worker
518
+ ): test_run
519
+ for test_run in test_runs
520
+ }
521
+
522
+ # Process results as they complete
523
+ for i, future in enumerate(as_completed(future_to_run), 1):
524
+ test_run = future_to_run[future]
525
+ log.info(
526
+ f"Processing result for test {i}/{total_tests}: {test_run.test_case_id}"
527
+ )
528
+ try:
529
+ success = future.result()
530
+ if success:
531
+ successful_tests += 1
532
+ else:
533
+ log.warning(
534
+ f"Test {test_run.test_case_id} (run {test_run.run_num}) failed or timed out."
535
+ )
536
+ except Exception as e:
537
+ log.error(
538
+ f"Test {test_run.test_case_id} (run {test_run.run_num}) generated an exception: {e}",
539
+ exc_info=True,
540
+ )
541
+
542
+ return successful_tests
543
+
544
+ def _cleanup_model_evaluation(
545
+ self,
546
+ app_process: subprocess.Popen,
547
+ subscriber: Subscriber,
548
+ model_results_path: Path,
549
+ task_mappings: dict[str, str],
550
+ ):
551
+ """Clean up after model evaluation."""
552
+ self.process_manager.stop_services(subscriber)
553
+
554
+ # Save task mappings
555
+ mappings_file = model_results_path / "task_mappings.json"
556
+ self.file_service.save_json(task_mappings, mappings_file)
557
+ log.info(f"Task mappings saved to {mappings_file}")
558
+
559
+
560
+ class ResultsProcessor:
561
+ """Handles post-processing of evaluation results."""
562
+
563
+ def __init__(self, file_service: FileService, verbose: bool = False):
564
+ self.file_service = file_service
565
+ self.summary_builder: SummaryBuilder | None = None
566
+ self.verbose = verbose
567
+
568
+ def summarize_results(self, base_results_path: Path, config: TestSuiteConfiguration):
569
+ """Generate summaries for all test results."""
570
+ log.info("Summarizing results")
571
+
572
+ self.summary_builder = SummaryBuilder(config)
573
+
574
+ for model_path in base_results_path.iterdir():
575
+ if not model_path.is_dir():
576
+ continue
577
+ self._process_model_results(model_path)
578
+
579
+ def _process_model_results(self, model_path: Path):
580
+ """Process results for a single model."""
581
+ for test_case_path in model_path.iterdir():
582
+ if not test_case_path.is_dir():
583
+ continue
584
+ self._process_test_case_results(test_case_path)
585
+
586
+ def _process_test_case_results(self, test_case_path: Path):
587
+ """Process results for a single test case."""
588
+ for run_path in test_case_path.iterdir():
589
+ if not run_path.is_dir():
590
+ continue
591
+
592
+ messages_file = run_path / "messages.json"
593
+ if messages_file.exists():
594
+ summary_data = self.summary_builder.summarize_run(messages_file)
595
+ summary_file = run_path / "summary.json"
596
+ self.file_service.save_json(summary_data, summary_file)
597
+ log.info(f"Summary created for {run_path}")
598
+
599
+
600
+ class EvaluationRunner:
601
+ """Main orchestrator that coordinates the entire evaluation process."""
602
+
603
+ def __init__(self, verbose: bool = False):
604
+ self.config: TestSuiteConfiguration | None = None
605
+ self.file_service = FileService()
606
+ self.results_processor = ResultsProcessor(self.file_service, verbose=verbose)
607
+ self.report_generator: ReportGenerator | None = None
608
+ self.verbose = verbose
609
+
610
+ def run_evaluation(self, config_path: str):
611
+ """Main entry point for the evaluation process."""
612
+ start_time = time.time()
613
+
614
+ try:
615
+ # Load and validate configuration
616
+ self._load_configuration(config_path)
617
+
618
+ # Set up results directory in the current working directory
619
+ base_results_path = Path.cwd() / "results" / self.config.results_directory
620
+ self._setup_results_directory(base_results_path)
621
+
622
+ # Run model evaluations
623
+ if self.config.remote:
624
+ model_execution_times = self._run_remote_evaluation(base_results_path)
625
+ else:
626
+ model_execution_times = self._run_local_evaluation(base_results_path)
627
+
628
+ # Post-process results
629
+ self._post_process_results(
630
+ base_results_path, model_execution_times, config_path
631
+ )
632
+
633
+ # Save overall statistics
634
+ self._save_execution_stats(base_results_path, start_time)
635
+
636
+ # Generate reports
637
+ self._generate_reports(config_path, base_results_path)
638
+
639
+ # Display summary
640
+ self._display_summary(base_results_path)
641
+
642
+ except Exception as e:
643
+ log.error(f"Evaluation failed: {e}")
644
+ raise
645
+
646
+ def _load_configuration(self, config_path: str):
647
+ """Load and validate the evaluation configuration."""
648
+ config_loader = EvaluationConfigLoader(config_path)
649
+ self.config = config_loader.load_configuration()
650
+ self.report_generator = ReportGenerator(config_path)
651
+ log.info("Configuration loaded and validated successfully.")
652
+
653
+ def _setup_results_directory(self, base_results_path: Path):
654
+ """Set up the results directory."""
655
+ # Clean up existing results
656
+ self.file_service.remove_directory(base_results_path)
657
+ self.file_service.ensure_directory(base_results_path)
658
+
659
+ log.info(f"Results directory set up at: {base_results_path}")
660
+
661
+ def _run_local_evaluation(self, base_results_path: Path) -> dict[str, float]:
662
+ """Run the full local evaluation with service management."""
663
+ _ensure_eval_backend_config_exists()
664
+ _ensure_sam_rest_gateway_installed()
665
+ log.info("Starting local evaluation")
666
+ model_execution_times = {}
667
+
668
+ # This loop iterates through the models defined in the config
669
+ for model_config in self.config.model_configurations:
670
+ # ModelEvaluator manages the lifecycle of local services for each model
671
+ model_evaluator = ModelEvaluator(self.config, verbose=self.verbose)
672
+ execution_time = model_evaluator.evaluate_model(
673
+ model_config, base_results_path
674
+ )
675
+ model_execution_times[model_config.name] = execution_time
676
+
677
+ return model_execution_times
678
+
679
+ def _run_remote_evaluation(self, base_results_path: Path) -> dict[str, float]:
680
+ """Run evaluation against a remote endpoint in parallel."""
681
+ remote_url = self.config.remote.environment.get("EVAL_REMOTE_URL")
682
+ log.info(f"Starting remote evaluation against: {remote_url}")
683
+ start_time = time.time()
684
+
685
+ # Check if the remote server is healthy before proceeding
686
+ process_manager = ProcessManager(self.config, self.verbose)
687
+ process_manager._wait_for_server_ready(remote_url)
688
+
689
+ # Instantiate services with the remote configuration
690
+ task_service = TaskService(self.config, self.verbose)
691
+ test_builder = TestRunBuilder(self.config)
692
+ test_executor = TestExecutor(task_service, self.file_service, self.verbose)
693
+
694
+ # In remote mode, there's no model loop. We create a single "remote" results directory.
695
+ remote_results_path = base_results_path / "remote"
696
+ self.file_service.ensure_directory(remote_results_path)
697
+
698
+ # The subscriber needs to be configured for remote use.
699
+ subscriber = self._setup_remote_subscriber(str(remote_results_path))
700
+
701
+ task_mappings = {}
702
+ try:
703
+ test_runs = test_builder.build_test_runs()
704
+ successful_tests = 0
705
+ task_mappings_lock = threading.Lock()
706
+
707
+ log.info(
708
+ f"Starting parallel execution of {len(test_runs)} remote tests with {self.config.workers} workers."
709
+ )
710
+
711
+ with ThreadPoolExecutor(max_workers=self.config.workers) as executor:
712
+ future_to_run = {
713
+ executor.submit(
714
+ test_executor.execute_test,
715
+ test_run,
716
+ remote_results_path,
717
+ task_mappings,
718
+ subscriber,
719
+ task_mappings_lock,
720
+ ): test_run
721
+ for test_run in test_runs
722
+ }
723
+
724
+ for i, future in enumerate(as_completed(future_to_run), 1):
725
+ test_run = future_to_run[future]
726
+ log.info(
727
+ f"Processing result for remote test {i}/{len(test_runs)}: {test_run.test_case_id}"
728
+ )
729
+ try:
730
+ success = future.result()
731
+ if success:
732
+ successful_tests += 1
733
+ except Exception as e:
734
+ log.error(
735
+ f"Remote test {test_run.test_case_id} generated an exception: {e}",
736
+ exc_info=True,
737
+ )
738
+
739
+ log.info(f"Completed {successful_tests} remote tests successfully")
740
+
741
+ finally:
742
+ if subscriber:
743
+ subscriber.stop()
744
+ subscriber.join()
745
+
746
+ # Save task mappings for remote run
747
+ mappings_file = remote_results_path / "task_mappings.json"
748
+ self.file_service.save_json(task_mappings, mappings_file)
749
+
750
+ execution_time = time.time() - start_time
751
+ return {"remote": execution_time}
752
+
753
+ def _setup_remote_subscriber(self, results_path: str) -> Subscriber:
754
+ """Set up a subscriber for remote evaluation."""
755
+ subscription_ready_event = threading.Event()
756
+ namespace = self.config.remote.environment.get("EVAL_NAMESPACE")
757
+ subscriber = Subscriber(
758
+ self.config.broker,
759
+ namespace,
760
+ set(),
761
+ None,
762
+ subscription_ready_event,
763
+ results_path,
764
+ )
765
+ subscriber.start()
766
+ subscription_ready_event.wait()
767
+ log.info("Remote subscriber is ready.")
768
+ return subscriber
769
+
770
+ def _post_process_results(
771
+ self,
772
+ base_results_path: Path,
773
+ model_execution_times: dict[str, float],
774
+ config_path: str,
775
+ ):
776
+ """Post-process evaluation results."""
777
+ # Categorize messages using the refactored categorizer
778
+ log.info("Categorizing messages")
779
+ message_organizer = MessageOrganizer()
780
+ message_organizer.categorize_all_messages(base_results_path)
781
+ log.info("Message categorization finished")
782
+
783
+ # Generate summaries
784
+ self.results_processor.summarize_results(base_results_path, self.config)
785
+
786
+ # Run evaluation
787
+ log.info("Starting evaluation of results")
788
+ evaluation_orchestrator = EvaluationOrchestrator(config_path)
789
+ evaluation_orchestrator.run_evaluation(
790
+ base_results_path, model_execution_times
791
+ )
792
+ log.info("Evaluation of results finished")
793
+
794
+ def _generate_reports(self, config_path: str, base_results_path: Path):
795
+ """Generate evaluation reports."""
796
+ if self.report_generator:
797
+ self.report_generator.generate_report(base_results_path)
798
+
799
+ def _display_summary(self, base_results_path: Path):
800
+ """Display a summary of the evaluation results in the terminal."""
801
+
802
+ # Pre-process data to find column widths
803
+ summary_data = []
804
+ max_model_len = 0
805
+ max_test_case_len = 0
806
+
807
+ for model_dir in sorted(base_results_path.iterdir()):
808
+ if not model_dir.is_dir():
809
+ continue
810
+
811
+ results_file = model_dir / "results.json"
812
+ if not results_file.exists():
813
+ continue
814
+
815
+ try:
816
+ results_data = self.file_service.load_json(results_file)
817
+ model_name = results_data.get("model_name", model_dir.name)
818
+ max_model_len = max(max_model_len, len(model_name))
819
+
820
+ for test_case in results_data.get("test_cases", []):
821
+ test_case_id = test_case.get("test_case_id")
822
+ if not test_case_id:
823
+ continue
824
+
825
+ max_test_case_len = max(max_test_case_len, len(test_case_id))
826
+
827
+ scores = {}
828
+ tool_match = test_case.get("tool_match_scores", {}).get("average")
829
+ if tool_match is not None:
830
+ scores["Tool Match"] = f"{tool_match:.2f}"
831
+
832
+ response_match = test_case.get("response_match_scores", {}).get("average")
833
+ if response_match is not None:
834
+ scores["Response Match"] = f"{response_match:.2f}"
835
+
836
+ llm_eval = test_case.get("llm_eval_scores", {}).get("average")
837
+ if llm_eval is not None:
838
+ scores["LLM Eval"] = f"{llm_eval:.2f}"
839
+
840
+ if scores:
841
+ summary_data.append((model_name, test_case_id, scores))
842
+
843
+ except Exception as e:
844
+ log.error(f"Error processing results for {model_dir.name}: {e}")
845
+
846
+ if not summary_data:
847
+ log.warning("No summary data to display.")
848
+ return
849
+
850
+ # Define header line
851
+ header_line = (
852
+ f"{'Model':<{max_model_len}} | {'Test Case':<{max_test_case_len}} | "
853
+ f"{'Tool Match':<12} | {'Response Match':<16} | {'LLM Eval':<10}"
854
+ )
855
+ click.echo(click.style(header_line, fg="white", bold=True))
856
+ click.echo(click.style("-" * len(header_line), fg="white", bold=True))
857
+
858
+ for model_name, test_case_id, scores in summary_data:
859
+ tool_score = scores.get("Tool Match", "N/A")
860
+ response_score = scores.get("Response Match", "N/A")
861
+ llm_score = scores.get("LLM Eval", "N/A")
862
+
863
+ click.echo(
864
+ click.style(
865
+ f"{model_name:<{max_model_len}} | {test_case_id:<{max_test_case_len}} | "
866
+ f"{tool_score:<12} | {response_score:<16} | {llm_score:<10}",
867
+ fg="white",
868
+ )
869
+ )
870
+
871
+ def _get_model_stats(self, model_path: Path) -> dict[str, any]:
872
+ """Process results for a single model and return stats."""
873
+ model_stats = {}
874
+ results_file = model_path / "results.json"
875
+ if not results_file.exists():
876
+ return model_stats
877
+
878
+ results_data = self.file_service.load_json(results_file)
879
+ model_name = results_data.get("model_name", model_path.name)
880
+ model_stats[model_name] = {}
881
+
882
+ for test_case in results_data.get("test_cases", []):
883
+ test_case_id = test_case.get("test_case_id")
884
+ if not test_case_id:
885
+ continue
886
+
887
+ scores = {}
888
+ tool_match = test_case.get("tool_match_scores", {}).get("average")
889
+ if tool_match is not None:
890
+ scores["avg_tool_match"] = tool_match
891
+
892
+ response_match = test_case.get("response_match_scores", {}).get("average")
893
+ if response_match is not None:
894
+ scores["avg_response_match"] = response_match
895
+
896
+ llm_eval = test_case.get("llm_eval_scores", {}).get("average")
897
+ if llm_eval is not None:
898
+ scores["avg_llm_eval"] = llm_eval
899
+
900
+ if scores:
901
+ model_stats[model_name][test_case_id] = scores
902
+ return model_stats
903
+
904
+ def _save_execution_stats(self, base_results_path: Path, start_time: float):
905
+ """Save overall execution statistics."""
906
+ end_time = time.time()
907
+ total_execution_time = end_time - start_time
908
+ stats = {"total_execution_time": total_execution_time, "models": {}}
909
+
910
+ try:
911
+ for model_path in base_results_path.iterdir():
912
+ if not model_path.is_dir():
913
+ continue
914
+ model_stats = self._get_model_stats(model_path)
915
+ stats["models"].update(model_stats)
916
+
917
+ except Exception as e:
918
+ log.error(f"Error processing results for stats: {e}")
919
+
920
+ stats_path = base_results_path / "stats.json"
921
+ self.file_service.save_json(stats, stats_path)
922
+
923
+ log.info(f"Overall stats written to {stats_path}")
924
+ log.info(f"Total execution time: {total_execution_time:.2f} seconds")
925
+
926
+
927
+ def main(config_path: str, verbose: bool = False):
928
+ """Main entry point for the evaluation script."""
929
+ if verbose:
930
+ logging.basicConfig(level=logging.INFO)
931
+ log.info("Verbose logging enabled.")
932
+
933
+ orchestrator = EvaluationRunner(verbose=verbose)
934
+ orchestrator.run_evaluation(config_path)
935
+
936
+
937
+ if __name__ == "__main__":
938
+ # This allows the script to be run standalone with a config path argument
939
+ import argparse
940
+
941
+ parser = argparse.ArgumentParser(description="Run the SAM evaluation suite.")
942
+ parser.add_argument(
943
+ "test_suite_config_path",
944
+ type=str,
945
+ help="Path to the evaluation test_suite_config.json file.",
946
+ )
947
+ parser.add_argument(
948
+ "-v",
949
+ "--verbose",
950
+ action="store_true",
951
+ help="Enable verbose output.",
952
+ )
953
+ args = parser.parse_args()
954
+ main(args.test_suite_config_path, args.verbose)