aip-agents-binary 0.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 (447) hide show
  1. aip_agents/__init__.py +66 -0
  2. aip_agents/a2a/__init__.py +19 -0
  3. aip_agents/a2a/server/__init__.py +10 -0
  4. aip_agents/a2a/server/base_executor.py +1125 -0
  5. aip_agents/a2a/server/google_adk_executor.py +198 -0
  6. aip_agents/a2a/server/langflow_executor.py +180 -0
  7. aip_agents/a2a/server/langgraph_executor.py +270 -0
  8. aip_agents/a2a/types.py +232 -0
  9. aip_agents/a2ui/__init__.py +26 -0
  10. aip_agents/a2ui/catalog_provider.py +109 -0
  11. aip_agents/a2ui/examples/0.8/booking_form.json +1 -0
  12. aip_agents/a2ui/examples/0.8/confirmation.json +1 -0
  13. aip_agents/a2ui/examples/0.8/single_column_list.json +1 -0
  14. aip_agents/a2ui/examples/0.9/booking_form.json +1 -0
  15. aip_agents/a2ui/examples/0.9/confirmation.json +1 -0
  16. aip_agents/a2ui/examples/0.9/single_column_list.json +1 -0
  17. aip_agents/a2ui/middleware.py +754 -0
  18. aip_agents/a2ui/models.py +153 -0
  19. aip_agents/a2ui/public_url.py +138 -0
  20. aip_agents/a2ui/stream_filter.py +67 -0
  21. aip_agents/agent/__init__.py +72 -0
  22. aip_agents/agent/base_agent.py +1437 -0
  23. aip_agents/agent/base_langgraph_agent.py +4048 -0
  24. aip_agents/agent/google_adk_agent.py +932 -0
  25. aip_agents/agent/google_adk_constants.py +11 -0
  26. aip_agents/agent/graph_runtime.py +185 -0
  27. aip_agents/agent/hitl/__init__.py +24 -0
  28. aip_agents/agent/hitl/config.py +28 -0
  29. aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
  30. aip_agents/agent/hitl/manager.py +532 -0
  31. aip_agents/agent/hitl/models.py +18 -0
  32. aip_agents/agent/hitl/prompt/__init__.py +9 -0
  33. aip_agents/agent/hitl/prompt/base.py +42 -0
  34. aip_agents/agent/hitl/prompt/deferred.py +73 -0
  35. aip_agents/agent/hitl/registry.py +149 -0
  36. aip_agents/agent/interface.py +138 -0
  37. aip_agents/agent/interfaces.py +65 -0
  38. aip_agents/agent/langflow_agent.py +464 -0
  39. aip_agents/agent/langgraph_react_agent.py +3741 -0
  40. aip_agents/agent/model_invocation_adapter.py +346 -0
  41. aip_agents/agent/system_instruction_context.py +34 -0
  42. aip_agents/agent/tool_execution_engine.py +587 -0
  43. aip_agents/audio_interface/__init__.py +30 -0
  44. aip_agents/audio_interface/audio_agent_adapter.py +254 -0
  45. aip_agents/audio_interface/config.py +146 -0
  46. aip_agents/audio_interface/errors.py +15 -0
  47. aip_agents/audio_interface/livekit_audio_session.py +504 -0
  48. aip_agents/audio_interface/livekit_realtime_audio_session.py +142 -0
  49. aip_agents/audio_interface/session_factory.py +40 -0
  50. aip_agents/clients/__init__.py +10 -0
  51. aip_agents/clients/langflow/__init__.py +10 -0
  52. aip_agents/clients/langflow/client.py +477 -0
  53. aip_agents/clients/langflow/types.py +18 -0
  54. aip_agents/common/__init__.py +5 -0
  55. aip_agents/common/callable_introspection.py +17 -0
  56. aip_agents/constants.py +23 -0
  57. aip_agents/context/__init__.py +5 -0
  58. aip_agents/context/budget.py +237 -0
  59. aip_agents/context/compaction.py +339 -0
  60. aip_agents/context/metadata.py +169 -0
  61. aip_agents/context/offload.py +449 -0
  62. aip_agents/context/preparation.py +196 -0
  63. aip_agents/context/prompt.py +61 -0
  64. aip_agents/context/runtime.py +149 -0
  65. aip_agents/context/session_recall.py +69 -0
  66. aip_agents/context/state.py +48 -0
  67. aip_agents/context/utils.py +44 -0
  68. aip_agents/credentials/manager.py +132 -0
  69. aip_agents/examples/__init__.py +5 -0
  70. aip_agents/examples/audio_livekit_session.py +116 -0
  71. aip_agents/examples/compare_streaming_client.py +783 -0
  72. aip_agents/examples/compare_streaming_server.py +141 -0
  73. aip_agents/examples/gl_connectors_smoke.py +148 -0
  74. aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
  75. aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
  76. aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
  77. aip_agents/examples/hello_world_a2a_google_adk_server.py +78 -0
  78. aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
  79. aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
  80. aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
  81. aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
  82. aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
  83. aip_agents/examples/hello_world_a2a_langchain_reference_server.py +104 -0
  84. aip_agents/examples/hello_world_a2a_langchain_server.py +78 -0
  85. aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +77 -0
  86. aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
  87. aip_agents/examples/hello_world_a2a_langflow_server.py +80 -0
  88. aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
  89. aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
  90. aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +91 -0
  91. aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
  92. aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
  93. aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
  94. aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
  95. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
  96. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
  97. aip_agents/examples/hello_world_a2a_langgraph_server.py +83 -0
  98. aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +78 -0
  99. aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +131 -0
  100. aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
  101. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
  102. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +250 -0
  103. aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
  104. aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +79 -0
  105. aip_agents/examples/hello_world_filesystem.py +162 -0
  106. aip_agents/examples/hello_world_google_adk.py +41 -0
  107. aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
  108. aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
  109. aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
  110. aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
  111. aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
  112. aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
  113. aip_agents/examples/hello_world_google_adk_stream.py +44 -0
  114. aip_agents/examples/hello_world_langchain.py +28 -0
  115. aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
  116. aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
  117. aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
  118. aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
  119. aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
  120. aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
  121. aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
  122. aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
  123. aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
  124. aip_agents/examples/hello_world_langchain_stream.py +36 -0
  125. aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
  126. aip_agents/examples/hello_world_langflow_agent.py +163 -0
  127. aip_agents/examples/hello_world_langgraph.py +39 -0
  128. aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
  129. aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
  130. aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
  131. aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
  132. aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
  133. aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
  134. aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
  135. aip_agents/examples/hello_world_langgraph_skills.py +62 -0
  136. aip_agents/examples/hello_world_langgraph_stream.py +43 -0
  137. aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
  138. aip_agents/examples/hello_world_model_switch_cli.py +210 -0
  139. aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
  140. aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
  141. aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
  142. aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
  143. aip_agents/examples/hello_world_multi_agent_tool_output_client.py +57 -0
  144. aip_agents/examples/hello_world_multi_agent_tool_output_server.py +131 -0
  145. aip_agents/examples/hello_world_pii_logger.py +21 -0
  146. aip_agents/examples/hello_world_ptc.py +49 -0
  147. aip_agents/examples/hello_world_ptc_custom_tools.py +83 -0
  148. aip_agents/examples/hello_world_sentry.py +133 -0
  149. aip_agents/examples/hello_world_step_limits.py +273 -0
  150. aip_agents/examples/hello_world_stock_a2a_server.py +100 -0
  151. aip_agents/examples/hello_world_tool_output_client.py +55 -0
  152. aip_agents/examples/hello_world_tool_output_server.py +113 -0
  153. aip_agents/examples/hitl_demo.py +724 -0
  154. aip_agents/examples/mcp_configs/configs.py +63 -0
  155. aip_agents/examples/mcp_servers/common.py +76 -0
  156. aip_agents/examples/mcp_servers/mcp_name.py +29 -0
  157. aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
  158. aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
  159. aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
  160. aip_agents/examples/mcp_servers/mcp_time.py +10 -0
  161. aip_agents/examples/pii_demo_langgraph_client.py +69 -0
  162. aip_agents/examples/pii_demo_langgraph_server.py +125 -0
  163. aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
  164. aip_agents/examples/pii_demo_multi_agent_server.py +246 -0
  165. aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
  166. aip_agents/examples/todolist_planning_a2a_langgraph_server.py +87 -0
  167. aip_agents/examples/tools/__init__.py +27 -0
  168. aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
  169. aip_agents/examples/tools/adk_weather_tool.py +60 -0
  170. aip_agents/examples/tools/data_generator_tool.py +103 -0
  171. aip_agents/examples/tools/data_visualization_tool.py +312 -0
  172. aip_agents/examples/tools/image_artifact_tool.py +136 -0
  173. aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
  174. aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
  175. aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
  176. aip_agents/examples/tools/langchain_weather_tool.py +48 -0
  177. aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
  178. aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
  179. aip_agents/examples/tools/multiply_tool.py +43 -0
  180. aip_agents/examples/tools/pii_demo_tools.py +189 -0
  181. aip_agents/examples/tools/random_chart_tool.py +142 -0
  182. aip_agents/examples/tools/serper_tool.py +202 -0
  183. aip_agents/examples/tools/stock_tools.py +82 -0
  184. aip_agents/examples/tools/table_generator_tool.py +167 -0
  185. aip_agents/examples/tools/time_tool.py +82 -0
  186. aip_agents/examples/tools/weather_forecast_tool.py +38 -0
  187. aip_agents/guardrails/__init__.py +83 -0
  188. aip_agents/guardrails/engines/__init__.py +69 -0
  189. aip_agents/guardrails/engines/base.py +90 -0
  190. aip_agents/guardrails/engines/nemo.py +101 -0
  191. aip_agents/guardrails/engines/phrase_matcher.py +113 -0
  192. aip_agents/guardrails/exceptions.py +39 -0
  193. aip_agents/guardrails/manager.py +163 -0
  194. aip_agents/guardrails/middleware.py +199 -0
  195. aip_agents/guardrails/schemas.py +63 -0
  196. aip_agents/guardrails/utils.py +45 -0
  197. aip_agents/integration/__init__.py +43 -0
  198. aip_agents/integration/agent.py +58 -0
  199. aip_agents/integration/guardrails.py +52 -0
  200. aip_agents/integration/hitl.py +71 -0
  201. aip_agents/integration/ptc.py +95 -0
  202. aip_agents/integration/skills.py +37 -0
  203. aip_agents/integration/storage.py +81 -0
  204. aip_agents/integration/version.py +103 -0
  205. aip_agents/mcp/__init__.py +1 -0
  206. aip_agents/mcp/client/__init__.py +60 -0
  207. aip_agents/mcp/client/base_mcp_client.py +377 -0
  208. aip_agents/mcp/client/connection_manager.py +231 -0
  209. aip_agents/mcp/client/errors.py +119 -0
  210. aip_agents/mcp/client/google_adk/__init__.py +45 -0
  211. aip_agents/mcp/client/google_adk/client.py +383 -0
  212. aip_agents/mcp/client/langchain/__init__.py +11 -0
  213. aip_agents/mcp/client/langchain/client.py +265 -0
  214. aip_agents/mcp/client/persistent_session.py +704 -0
  215. aip_agents/mcp/client/session_pool.py +358 -0
  216. aip_agents/mcp/client/transports.py +288 -0
  217. aip_agents/mcp/utils/__init__.py +7 -0
  218. aip_agents/mcp/utils/config_validator.py +139 -0
  219. aip_agents/memory/__init__.py +14 -0
  220. aip_agents/memory/adapters/__init__.py +10 -0
  221. aip_agents/memory/adapters/base_adapter.py +815 -0
  222. aip_agents/memory/adapters/mem0.py +286 -0
  223. aip_agents/memory/base.py +84 -0
  224. aip_agents/memory/constants.py +49 -0
  225. aip_agents/memory/factory.py +86 -0
  226. aip_agents/memory/guidance.py +20 -0
  227. aip_agents/memory/simple_memory.py +47 -0
  228. aip_agents/middleware/__init__.py +65 -0
  229. aip_agents/middleware/backends/__init__.py +72 -0
  230. aip_agents/middleware/backends/in_memory.py +578 -0
  231. aip_agents/middleware/backends/local_disk.py +1203 -0
  232. aip_agents/middleware/backends/protocol.py +353 -0
  233. aip_agents/middleware/backends/sandbox.py +1431 -0
  234. aip_agents/middleware/backends/sandbox_files.py +113 -0
  235. aip_agents/middleware/backends/utils.py +293 -0
  236. aip_agents/middleware/base.py +239 -0
  237. aip_agents/middleware/filesystem.py +690 -0
  238. aip_agents/middleware/manager.py +291 -0
  239. aip_agents/middleware/memory.py +532 -0
  240. aip_agents/middleware/pii_middleware.py +192 -0
  241. aip_agents/middleware/schema.py +19 -0
  242. aip_agents/middleware/skills.py +872 -0
  243. aip_agents/middleware/task_delegation.py +1656 -0
  244. aip_agents/middleware/todolist.py +276 -0
  245. aip_agents/middleware/tools/__init__.py +23 -0
  246. aip_agents/middleware/tools/edit_file.py +70 -0
  247. aip_agents/middleware/tools/execute.py +428 -0
  248. aip_agents/middleware/tools/grep_file.py +79 -0
  249. aip_agents/middleware/tools/ls.py +71 -0
  250. aip_agents/middleware/tools/read_file.py +239 -0
  251. aip_agents/middleware/tools/skill_load.py +193 -0
  252. aip_agents/middleware/tools/skill_resource.py +338 -0
  253. aip_agents/middleware/tools/write_file.py +114 -0
  254. aip_agents/middleware/vision.py +322 -0
  255. aip_agents/ptc/__init__.py +87 -0
  256. aip_agents/ptc/custom_tools.py +511 -0
  257. aip_agents/ptc/custom_tools_payload.py +499 -0
  258. aip_agents/ptc/custom_tools_templates/__init__.py +1 -0
  259. aip_agents/ptc/custom_tools_templates/custom_build_function.py.template +24 -0
  260. aip_agents/ptc/custom_tools_templates/custom_init.py.template +26 -0
  261. aip_agents/ptc/custom_tools_templates/custom_invoke.py.template +149 -0
  262. aip_agents/ptc/custom_tools_templates/custom_registry.py.template +112 -0
  263. aip_agents/ptc/custom_tools_templates/custom_sources_init.py.template +7 -0
  264. aip_agents/ptc/custom_tools_templates/custom_wrapper.py.template +87 -0
  265. aip_agents/ptc/doc_gen.py +122 -0
  266. aip_agents/ptc/exceptions.py +57 -0
  267. aip_agents/ptc/executor.py +627 -0
  268. aip_agents/ptc/mcp/__init__.py +45 -0
  269. aip_agents/ptc/mcp/sandbox_bridge.py +679 -0
  270. aip_agents/ptc/mcp/templates/__init__.py +1 -0
  271. aip_agents/ptc/mcp/templates/mcp_client.py.template +240 -0
  272. aip_agents/ptc/naming.py +430 -0
  273. aip_agents/ptc/payload.py +26 -0
  274. aip_agents/ptc/prompt_builder.py +674 -0
  275. aip_agents/ptc/ptc_helper.py +16 -0
  276. aip_agents/ptc/sandbox_bridge.py +297 -0
  277. aip_agents/ptc/template_utils.py +33 -0
  278. aip_agents/ptc/templates/__init__.py +1 -0
  279. aip_agents/ptc/templates/ptc_helper.py.template +134 -0
  280. aip_agents/ptc/tool_def_helpers.py +101 -0
  281. aip_agents/ptc/tool_enrichment.py +163 -0
  282. aip_agents/resilience/__init__.py +10 -0
  283. aip_agents/resilience/base.py +46 -0
  284. aip_agents/resilience/tool.py +1661 -0
  285. aip_agents/sandbox/__init__.py +62 -0
  286. aip_agents/sandbox/defaults.py +220 -0
  287. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-1-datasaur.Dockerfile +120 -0
  288. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-1.Dockerfile +100 -0
  289. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-2-datasaur.Dockerfile +143 -0
  290. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-2.Dockerfile +119 -0
  291. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-3-datasaur.Dockerfile +173 -0
  292. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-3.Dockerfile +130 -0
  293. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.Dockerfile +164 -0
  294. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.patch_js_context.py +41 -0
  295. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.requirements.txt +29 -0
  296. aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2.Dockerfile +87 -0
  297. aip_agents/sandbox/e2b_runtime.py +27 -0
  298. aip_agents/sandbox/image_registry.py +98 -0
  299. aip_agents/sandbox/providers/__init__.py +76 -0
  300. aip_agents/sandbox/providers/base.py +392 -0
  301. aip_agents/sandbox/providers/bedrock.py +28 -0
  302. aip_agents/sandbox/providers/e2b.py +230 -0
  303. aip_agents/sandbox/providers/opensandbox.py +163 -0
  304. aip_agents/sandbox/sandbox_runtime.py +967 -0
  305. aip_agents/sandbox/template_builder.py +240 -0
  306. aip_agents/sandbox/types.py +141 -0
  307. aip_agents/sandbox/validation.py +50 -0
  308. aip_agents/schema/__init__.py +106 -0
  309. aip_agents/schema/a2a.py +58 -0
  310. aip_agents/schema/agent.py +117 -0
  311. aip_agents/schema/artifacts.py +75 -0
  312. aip_agents/schema/attachments.py +425 -0
  313. aip_agents/schema/hitl.py +157 -0
  314. aip_agents/schema/langgraph.py +47 -0
  315. aip_agents/schema/model_id.py +103 -0
  316. aip_agents/schema/model_usage.py +50 -0
  317. aip_agents/schema/runtime_metadata.py +78 -0
  318. aip_agents/schema/step_limit.py +108 -0
  319. aip_agents/schema/storage.py +40 -0
  320. aip_agents/schema/tool_payloads.py +68 -0
  321. aip_agents/sentry/__init__.py +11 -0
  322. aip_agents/sentry/sentry.py +267 -0
  323. aip_agents/skills/__init__.py +30 -0
  324. aip_agents/skills/errors.py +110 -0
  325. aip_agents/skills/installer.py +479 -0
  326. aip_agents/skills/models.py +769 -0
  327. aip_agents/skills/stager.py +224 -0
  328. aip_agents/skills/validation.py +53 -0
  329. aip_agents/storage/__init__.py +41 -0
  330. aip_agents/storage/base.py +85 -0
  331. aip_agents/storage/clients/__init__.py +12 -0
  332. aip_agents/storage/clients/minio_client.py +318 -0
  333. aip_agents/storage/config.py +62 -0
  334. aip_agents/storage/providers/__init__.py +15 -0
  335. aip_agents/storage/providers/base.py +106 -0
  336. aip_agents/storage/providers/memory.py +114 -0
  337. aip_agents/storage/providers/object_storage.py +214 -0
  338. aip_agents/tools/__init__.py +65 -0
  339. aip_agents/tools/agent_schedule_tool.py +392 -0
  340. aip_agents/tools/browser_use/__init__.py +83 -0
  341. aip_agents/tools/browser_use/action_parser.py +104 -0
  342. aip_agents/tools/browser_use/browser_use_tool.py +1118 -0
  343. aip_agents/tools/browser_use/llm_config.py +120 -0
  344. aip_agents/tools/browser_use/minio_storage.py +203 -0
  345. aip_agents/tools/browser_use/schemas.py +121 -0
  346. aip_agents/tools/browser_use/session.py +13 -0
  347. aip_agents/tools/browser_use/session_errors.py +132 -0
  348. aip_agents/tools/browser_use/steel_session_recording.py +321 -0
  349. aip_agents/tools/browser_use/streaming.py +263 -0
  350. aip_agents/tools/browser_use/structured_data_parser.py +257 -0
  351. aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
  352. aip_agents/tools/browser_use/types.py +37 -0
  353. aip_agents/tools/code_sandbox/__init__.py +48 -0
  354. aip_agents/tools/code_sandbox/code_sandbox_tool.py +350 -0
  355. aip_agents/tools/code_sandbox/constant.py +13 -0
  356. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +346 -0
  357. aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +65 -0
  358. aip_agents/tools/computer_use/__init__.py +75 -0
  359. aip_agents/tools/computer_use/computer_use_tool.py +910 -0
  360. aip_agents/tools/computer_use/schemas.py +78 -0
  361. aip_agents/tools/computer_use/streaming.py +198 -0
  362. aip_agents/tools/computer_use/types.py +32 -0
  363. aip_agents/tools/constants.py +177 -0
  364. aip_agents/tools/date_range_tool.py +554 -0
  365. aip_agents/tools/document_loader/__init__.py +44 -0
  366. aip_agents/tools/document_loader/base_reader.py +302 -0
  367. aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
  368. aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
  369. aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
  370. aip_agents/tools/document_loader/pdf_splitter.py +169 -0
  371. aip_agents/tools/execute_ptc_code.py +582 -0
  372. aip_agents/tools/gl_connector/__init__.py +5 -0
  373. aip_agents/tools/gl_connector/tool.py +518 -0
  374. aip_agents/tools/gl_connector_tools.py +170 -0
  375. aip_agents/tools/memory_search/__init__.py +29 -0
  376. aip_agents/tools/memory_search/base.py +213 -0
  377. aip_agents/tools/memory_search/mem0.py +424 -0
  378. aip_agents/tools/memory_search/schema.py +81 -0
  379. aip_agents/tools/memory_search_tool.py +34 -0
  380. aip_agents/tools/streaming_common.py +577 -0
  381. aip_agents/tools/time_tool.py +117 -0
  382. aip_agents/tools/tool_config_injector.py +300 -0
  383. aip_agents/tools/web_search/__init__.py +15 -0
  384. aip_agents/tools/web_search/serper_tool.py +187 -0
  385. aip_agents/types/__init__.py +73 -0
  386. aip_agents/types/a2a_events.py +13 -0
  387. aip_agents/utils/__init__.py +91 -0
  388. aip_agents/utils/a2a_connector.py +1758 -0
  389. aip_agents/utils/artifact_helpers.py +542 -0
  390. aip_agents/utils/artifacts/__init__.py +20 -0
  391. aip_agents/utils/artifacts/tracker.py +367 -0
  392. aip_agents/utils/attachment_helpers.py +178 -0
  393. aip_agents/utils/constants.py +22 -0
  394. aip_agents/utils/datetime/__init__.py +34 -0
  395. aip_agents/utils/datetime/normalization.py +231 -0
  396. aip_agents/utils/datetime/timezone.py +206 -0
  397. aip_agents/utils/env_loader.py +27 -0
  398. aip_agents/utils/event_handler_registry.py +58 -0
  399. aip_agents/utils/file_prompt_utils.py +276 -0
  400. aip_agents/utils/file_watchers/__init__.py +33 -0
  401. aip_agents/utils/file_watchers/base.py +46 -0
  402. aip_agents/utils/file_watchers/e2b.py +128 -0
  403. aip_agents/utils/file_watchers/factory.py +39 -0
  404. aip_agents/utils/file_watchers/ls_diff.py +88 -0
  405. aip_agents/utils/file_watchers/sandbox.py +66 -0
  406. aip_agents/utils/file_watchers/watchdog.py +97 -0
  407. aip_agents/utils/final_response_builder.py +211 -0
  408. aip_agents/utils/formatter_llm_client.py +258 -0
  409. aip_agents/utils/langgraph/__init__.py +19 -0
  410. aip_agents/utils/langgraph/converter.py +399 -0
  411. aip_agents/utils/langgraph/delegation_context.py +22 -0
  412. aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
  413. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
  414. aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
  415. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1329 -0
  416. aip_agents/utils/langgraph/tool_output_management.py +1047 -0
  417. aip_agents/utils/logger.py +195 -0
  418. aip_agents/utils/metadata/__init__.py +27 -0
  419. aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
  420. aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
  421. aip_agents/utils/metadata/activity_narrative/builder.py +822 -0
  422. aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
  423. aip_agents/utils/metadata/activity_narrative/context.py +49 -0
  424. aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
  425. aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
  426. aip_agents/utils/metadata/schemas/__init__.py +16 -0
  427. aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
  428. aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
  429. aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
  430. aip_agents/utils/metadata_helper.py +363 -0
  431. aip_agents/utils/name_preprocessor/__init__.py +17 -0
  432. aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
  433. aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
  434. aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
  435. aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
  436. aip_agents/utils/pii/__init__.py +29 -0
  437. aip_agents/utils/pii/pii_handler.py +555 -0
  438. aip_agents/utils/pii/pii_helper.py +225 -0
  439. aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
  440. aip_agents/utils/reference_helper.py +273 -0
  441. aip_agents/utils/sse_chunk_transformer.py +836 -0
  442. aip_agents/utils/step_limit_manager.py +265 -0
  443. aip_agents/utils/token_usage_helper.py +531 -0
  444. aip_agents_binary-0.0.0.dist-info/METADATA +825 -0
  445. aip_agents_binary-0.0.0.dist-info/RECORD +447 -0
  446. aip_agents_binary-0.0.0.dist-info/WHEEL +5 -0
  447. aip_agents_binary-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,254 @@
1
+ """Adapter that routes transcripts into an AIP agent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import inspect
6
+ import json
7
+ import os
8
+ import uuid
9
+ from collections.abc import Awaitable, Callable
10
+ from typing import Any, cast
11
+
12
+ from aip_agents.schema.a2a import A2AStreamEventType
13
+
14
+
15
+ class AIPAudioAgentAdapter:
16
+ """Adapter that turns transcript text into agent replies.
17
+
18
+ This wrapper:
19
+ - calls the agent's `arun(...)` method
20
+ - injects a stable thread id via `configurable` for conversation persistence
21
+ - optionally prints internal LangGraph step events when `AIP_AUDIO_DEBUG=1`
22
+ """
23
+
24
+ def __init__(self, agent: Any) -> None:
25
+ """Create an adapter around an async-capable agent."""
26
+ self._agent = agent
27
+ self._thread_id = str(uuid.uuid4())
28
+ self._debug = os.environ.get("AIP_AUDIO_DEBUG") == "1"
29
+
30
+ async def generate_reply(
31
+ self,
32
+ text: str,
33
+ *,
34
+ on_a2a_event: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
35
+ prefer_a2a_stream: bool = False,
36
+ **kwargs: Any,
37
+ ) -> str:
38
+ """Generate an agent reply for a single user transcript.
39
+
40
+ Args:
41
+ text: Final transcript text.
42
+ on_a2a_event: Optional async callback invoked for each A2A stream event.
43
+ prefer_a2a_stream: When True, uses `arun_a2a_stream(...)` if available even
44
+ when debug mode is disabled.
45
+ **kwargs: Passed through to the underlying agent call.
46
+ """
47
+ self._ensure_thread_id(kwargs)
48
+
49
+ arun_a2a_stream = getattr(self._agent, "arun_a2a_stream", None)
50
+ if callable(arun_a2a_stream) and (prefer_a2a_stream or self._debug):
51
+ return await self._arun_via_a2a_stream(
52
+ text,
53
+ arun_a2a_stream=arun_a2a_stream,
54
+ on_a2a_event=on_a2a_event,
55
+ debug=self._debug,
56
+ **kwargs,
57
+ )
58
+
59
+ if not self._debug:
60
+ return await self._arun_basic(text, **kwargs)
61
+
62
+ # Debug fallback for agents without A2A streaming support.
63
+ if not hasattr(self._agent, "_compiled_graph"):
64
+ return await self._arun_basic(text, **kwargs)
65
+
66
+ create_cfg = getattr(self._agent, "_create_graph_config", None)
67
+ get_tid = getattr(self._agent, "_get_thread_id_from_config", None)
68
+ prep_input = getattr(self._agent, "_prepare_graph_input", None)
69
+ fmt_output = getattr(self._agent, "_format_graph_output", None)
70
+ if not (callable(create_cfg) and callable(get_tid) and callable(prep_input) and callable(fmt_output)):
71
+ return await self._arun_basic(text, **kwargs)
72
+
73
+ return await self._arun_with_compiled_graph_steps(text, **kwargs)
74
+
75
+ def _ensure_thread_id(self, kwargs: dict[str, Any]) -> None:
76
+ """Ensure a stable thread_id is injected into kwargs for persistence."""
77
+ configurable = kwargs.get("configurable")
78
+ if not isinstance(configurable, dict):
79
+ configurable = {}
80
+ kwargs["configurable"] = configurable
81
+
82
+ thread_id_key = getattr(self._agent, "thread_id_key", "thread_id") or "thread_id"
83
+ configurable.setdefault(thread_id_key, self._thread_id)
84
+
85
+ async def _arun_basic(self, text: str, **kwargs: Any) -> str:
86
+ arun = getattr(self._agent, "arun", None)
87
+ if not callable(arun):
88
+ raise TypeError(f"Agent does not support arun(): {type(self._agent).__name__}")
89
+
90
+ maybe = arun(text, **kwargs)
91
+ if inspect.isawaitable(maybe):
92
+ result = await cast(Awaitable[Any], maybe)
93
+ else:
94
+ result = maybe
95
+
96
+ if isinstance(result, dict) and isinstance(result.get("output"), str):
97
+ return result["output"]
98
+ return str(result)
99
+
100
+ async def _arun_with_steps(self, text: str, **kwargs: Any) -> str:
101
+ """Backwards-compatible alias for debug mode."""
102
+ return await self.generate_reply(text, prefer_a2a_stream=True, **kwargs)
103
+
104
+ async def _arun_with_compiled_graph_steps(self, text: str, **kwargs: Any) -> str:
105
+ """Fallback debug streaming for agents without A2A streaming support."""
106
+ # Create config and get thread_id using agent's internal logic.
107
+ config = self._agent._create_graph_config(**kwargs)
108
+ thread_id = self._agent._get_thread_id_from_config(config)
109
+ graph_input = self._agent._prepare_graph_input(text, thread_id=thread_id, **kwargs)
110
+
111
+ final_state: Any | None = None
112
+ async for event in self._agent._compiled_graph.astream_events(graph_input, config=config, version="v2"):
113
+ final_state = self._process_compiled_graph_event(event, final_state)
114
+
115
+ if final_state is None:
116
+ return await self._arun_basic(text, **kwargs)
117
+
118
+ # We must use the agent's internal formatter to preserve consistent output formatting.
119
+ return self._agent._format_graph_output(final_state)
120
+
121
+ def _process_compiled_graph_event(self, event: dict[str, Any], final_state: Any | None) -> Any | None:
122
+ """Print step events and return updated final state when it becomes available."""
123
+ kind = event.get("event")
124
+ name = event.get("name")
125
+ data = event.get("data", {}) or {}
126
+
127
+ if kind == "on_chat_model_start":
128
+ print("[aip-step] agent: Thinking...")
129
+ return final_state
130
+
131
+ if kind == "on_tool_start":
132
+ inputs = data.get("input", {})
133
+ try:
134
+ inputs_str = json.dumps(inputs)
135
+ except (TypeError, ValueError):
136
+ inputs_str = str(inputs)
137
+ print(f"[aip-step] tool: Using '{name}' with inputs: {inputs_str}")
138
+ return final_state
139
+
140
+ if kind == "on_tool_end":
141
+ print(f"[aip-step] tool: '{name}' finished")
142
+ return final_state
143
+
144
+ if kind == "on_chain_end" and not event.get("parent_id"):
145
+ return data.get("output")
146
+
147
+ return final_state
148
+
149
+ async def _arun_via_a2a_stream(
150
+ self,
151
+ text: str,
152
+ *,
153
+ arun_a2a_stream: Any,
154
+ on_a2a_event: Callable[[dict[str, Any]], Awaitable[None]] | None,
155
+ debug: bool,
156
+ **kwargs: Any,
157
+ ) -> str:
158
+ """Run the agent using the public A2A event stream.
159
+
160
+ This method intentionally drains the full stream (even after FINAL_RESPONSE)
161
+ so LangGraph checkpointing can complete.
162
+ """
163
+ output_chunks: list[str] = []
164
+ final_reply: str | None = None
165
+
166
+ handlers = self._build_a2a_handlers(output_chunks) if debug else {}
167
+
168
+ async for event in arun_a2a_stream(text, **kwargs):
169
+ if on_a2a_event is not None and isinstance(event, dict):
170
+ await on_a2a_event(event)
171
+
172
+ self._check_stream_error(event)
173
+ self._handle_stream_event(event, output_chunks, handlers)
174
+
175
+ # Capture final response but continue draining
176
+ if self._is_final_response(event):
177
+ content = str(event.get("content") or "")
178
+ final_reply = content if content else "".join(output_chunks)
179
+
180
+ if final_reply is not None:
181
+ return final_reply
182
+
183
+ return await self._arun_basic(text, **kwargs)
184
+
185
+ def _check_stream_error(self, event: dict[str, Any]) -> None:
186
+ """Raise RuntimeError if the event indicates an error."""
187
+ raw_type = event.get("event_type")
188
+ event_type = raw_type.value if hasattr(raw_type, "value") else str(raw_type)
189
+ if event_type in (A2AStreamEventType.ERROR.value, A2AStreamEventType.STEP_LIMIT_EXCEEDED.value):
190
+ content = str(event.get("content") or "")
191
+ raise RuntimeError(content or "Streaming failed")
192
+
193
+ def _is_final_response(self, event: dict[str, Any]) -> bool:
194
+ """Check if event is a final response."""
195
+ raw_type = event.get("event_type")
196
+ event_type = raw_type.value if hasattr(raw_type, "value") else str(raw_type)
197
+ return event_type == A2AStreamEventType.FINAL_RESPONSE.value
198
+
199
+ def _handle_stream_event(
200
+ self,
201
+ event: dict[str, Any],
202
+ output_chunks: list[str],
203
+ handlers: dict[str, Callable[[str, dict[str, Any]], None]],
204
+ ) -> None:
205
+ """Process a single stream event: update chunks and invoke debug handlers."""
206
+ raw_type = event.get("event_type")
207
+ event_type = raw_type.value if hasattr(raw_type, "value") else str(raw_type)
208
+ content = str(event.get("content") or "")
209
+ tool_info = event.get("tool_info")
210
+ tool_info_dict = tool_info if isinstance(tool_info, dict) else {}
211
+
212
+ if event_type == A2AStreamEventType.CONTENT_CHUNK.value and content:
213
+ output_chunks.append(content)
214
+
215
+ handler = handlers.get(event_type)
216
+ if handler is not None:
217
+ handler(content, tool_info_dict)
218
+
219
+ def _build_a2a_handlers(self, _output_chunks: list[str]) -> dict[str, Callable[[str, dict[str, Any]], None]]:
220
+ """Return event handlers for debug A2A streaming."""
221
+
222
+ def _status_update(content: str, _tool_info: dict[str, Any]) -> None:
223
+ msg = content.strip()
224
+ if msg:
225
+ print(f"[aip-step] agent: {msg}")
226
+ return None
227
+
228
+ def _tool_call(_content: str, tool_info: dict[str, Any]) -> None:
229
+ calls = tool_info.get("tool_calls")
230
+ if not isinstance(calls, list):
231
+ return None
232
+ for call in calls:
233
+ if not isinstance(call, dict):
234
+ continue
235
+ name = call.get("name")
236
+ args = call.get("args")
237
+ args_dict = args if isinstance(args, dict) else {}
238
+ try:
239
+ inputs_str = json.dumps(args_dict)
240
+ except (TypeError, ValueError):
241
+ inputs_str = str(args_dict)
242
+ print(f"[aip-step] tool: Using '{name}' with inputs: {inputs_str}")
243
+ return None
244
+
245
+ def _tool_result(_content: str, tool_info: dict[str, Any]) -> None:
246
+ name = tool_info.get("name")
247
+ print(f"[aip-step] tool: '{name}' finished")
248
+ return None
249
+
250
+ return {
251
+ A2AStreamEventType.STATUS_UPDATE.value: _status_update,
252
+ A2AStreamEventType.TOOL_CALL.value: _tool_call,
253
+ A2AStreamEventType.TOOL_RESULT.value: _tool_result,
254
+ }
@@ -0,0 +1,146 @@
1
+ """Typed config objects for audio sessions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import re
7
+ from dataclasses import dataclass
8
+ from typing import Any
9
+
10
+ from aip_agents.audio_interface.errors import AudioConfigError
11
+
12
+ _ENV_REF_RE = re.compile(r"^\$\{([A-Z0-9_]+)\}$")
13
+
14
+
15
+ def _resolve_env_ref(value: str | None) -> str | None:
16
+ if value is None:
17
+ return None
18
+ m = _ENV_REF_RE.match(value.strip())
19
+ if not m:
20
+ return value
21
+ return os.environ.get(m.group(1))
22
+
23
+
24
+ @dataclass(frozen=True, slots=True)
25
+ class AudioIOConfig:
26
+ """I/O toggles and device hints for an audio session."""
27
+
28
+ input_enabled: bool = True
29
+ output_enabled: bool = True
30
+ input_device: str | None = None
31
+ output_device: str | None = None
32
+
33
+
34
+ @dataclass(frozen=True, slots=True)
35
+ class AudioModelConfig:
36
+ """Model selection for provider-specific audio components.
37
+
38
+ For OpenAI STT/TTS wiring in the LiveKit provider:
39
+ provider="openai", voice="echo"
40
+ """
41
+
42
+ provider: str | None = None
43
+ model: str | None = None
44
+ voice: str | None = None
45
+ credentials: str | None = None
46
+
47
+
48
+ @dataclass(frozen=True, slots=True)
49
+ class LiveKitConfig:
50
+ """Connection and provider configuration for LiveKit audio sessions."""
51
+
52
+ url: str
53
+ api_key: str | None = None
54
+ api_secret: str | None = None
55
+ room_name: str | None = None
56
+ identity: str | None = None
57
+
58
+ # Optional: OpenAI STT/TTS via livekit-plugins-openai
59
+ openai_stt_model: str | None = None
60
+ openai_tts_model: str | None = None
61
+ openai_voice: str | None = None
62
+ openai_use_realtime_stt: bool = True
63
+ openai_api_key: str | None = None
64
+ openai_base_url: str | None = None
65
+
66
+ def resolve_api_key(self) -> str:
67
+ """Resolve the LiveKit API key from config/env."""
68
+ val = _resolve_env_ref(self.api_key) or os.environ.get("LIVEKIT_API_KEY")
69
+ if not val:
70
+ raise AudioConfigError("LIVEKIT_API_KEY missing")
71
+ return val
72
+
73
+ def resolve_api_secret(self) -> str:
74
+ """Resolve the LiveKit API secret from config/env."""
75
+ val = _resolve_env_ref(self.api_secret) or os.environ.get("LIVEKIT_API_SECRET")
76
+ if not val:
77
+ raise AudioConfigError("LIVEKIT_API_SECRET missing")
78
+ return val
79
+
80
+ def resolve_openai_api_key(self) -> str:
81
+ """Resolve OpenAI API key used by livekit-plugins-openai."""
82
+ val = _resolve_env_ref(self.openai_api_key) or os.environ.get("OPENAI_API_KEY")
83
+ if not val:
84
+ raise AudioConfigError("OPENAI_API_KEY missing (required for OpenAI STT/TTS)")
85
+ return val
86
+
87
+
88
+ @dataclass(frozen=True, slots=True)
89
+ class AudioSessionConfig:
90
+ """Top-level audio session config as used by the audio interface."""
91
+
92
+ provider: str = "livekit"
93
+ io: AudioIOConfig = AudioIOConfig()
94
+ model: AudioModelConfig | None = None
95
+ provider_config: LiveKitConfig | dict[str, Any] | None = None
96
+
97
+ @staticmethod
98
+ def from_agent_config_audio(raw: dict[str, Any]) -> AudioSessionConfig:
99
+ """Parse the `agent_config.audio` section into a typed config."""
100
+ if not isinstance(raw, dict):
101
+ raise AudioConfigError("agent_config.audio must be a dict")
102
+
103
+ provider = raw.get("provider") or "livekit"
104
+ io_raw = raw.get("io") or {}
105
+ io = AudioIOConfig(
106
+ input_enabled=bool(io_raw.get("input_enabled", True)),
107
+ output_enabled=bool(io_raw.get("output_enabled", True)),
108
+ input_device=io_raw.get("input_device"),
109
+ output_device=io_raw.get("output_device"),
110
+ )
111
+
112
+ model_raw = raw.get("model")
113
+ model: AudioModelConfig | None = None
114
+ if isinstance(model_raw, dict):
115
+ model = AudioModelConfig(
116
+ provider=model_raw.get("provider"),
117
+ model=model_raw.get("model"),
118
+ voice=model_raw.get("voice"),
119
+ credentials=model_raw.get("credentials"),
120
+ )
121
+
122
+ provider_cfg: LiveKitConfig | dict[str, Any] | None = None
123
+ if provider in {"livekit", "livekit_realtime"}:
124
+ lk = raw.get(provider) or raw.get("livekit")
125
+ if not isinstance(lk, dict):
126
+ raise AudioConfigError(f"{provider}.url is required")
127
+ url = lk.get("url")
128
+ if not url:
129
+ raise AudioConfigError(f"{provider}.url is required")
130
+ provider_cfg = LiveKitConfig(
131
+ url=str(url),
132
+ api_key=lk.get("api_key"),
133
+ api_secret=lk.get("api_secret"),
134
+ room_name=lk.get("room_name"),
135
+ identity=lk.get("identity"),
136
+ openai_stt_model=lk.get("openai_stt_model"),
137
+ openai_tts_model=lk.get("openai_tts_model"),
138
+ openai_voice=lk.get("openai_voice"),
139
+ openai_use_realtime_stt=bool(lk.get("openai_use_realtime_stt", True)),
140
+ openai_api_key=lk.get("openai_api_key"),
141
+ openai_base_url=lk.get("openai_base_url"),
142
+ )
143
+ elif isinstance(raw.get(provider), dict):
144
+ provider_cfg = dict(raw[provider])
145
+
146
+ return AudioSessionConfig(provider=provider, io=io, model=model, provider_config=provider_cfg)
@@ -0,0 +1,15 @@
1
+ """Audio interface errors (local-only, optional deps)."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class AudioInterfaceError(RuntimeError):
7
+ """Base error for audio interface."""
8
+
9
+
10
+ class AudioSessionUnavailableError(AudioInterfaceError):
11
+ """Provider deps are missing or incompatible."""
12
+
13
+
14
+ class AudioConfigError(AudioInterfaceError, ValueError):
15
+ """Audio config is missing or invalid."""