dg-dataagent 0.1.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 (310) hide show
  1. dataagent/__init__.py +37 -0
  2. dataagent/__main__.py +16 -0
  3. dataagent/a2a_server/__init__.py +25 -0
  4. dataagent/a2a_server/agent_card.py +85 -0
  5. dataagent/a2a_server/agent_executor.py +310 -0
  6. dataagent/a2a_server/server.py +169 -0
  7. dataagent/a2a_server/task_store.py +29 -0
  8. dataagent/actions/__init__.py +12 -0
  9. dataagent/actions/environment/__init__.py +21 -0
  10. dataagent/actions/environment/compound_env.py +89 -0
  11. dataagent/actions/environment/env.py +52 -0
  12. dataagent/actions/environment/env_config.py +101 -0
  13. dataagent/actions/gym/__init__.py +32 -0
  14. dataagent/actions/gym/arithmetic/arithmetic.py +124 -0
  15. dataagent/actions/gym/changping/changping_env.py +480 -0
  16. dataagent/actions/gym/icbc/icbc_env.py +800 -0
  17. dataagent/actions/gym/manufacturing/manufacturing_env.py +534 -0
  18. dataagent/actions/gym/nl2sql/base_env.py +444 -0
  19. dataagent/actions/gym/nl2sql/sqlite_env.py +79 -0
  20. dataagent/actions/gym/ontology_env.py +1310 -0
  21. dataagent/actions/perceptor/perceptor_atomic.py +671 -0
  22. dataagent/actions/perceptor/perceptor_utils.py +31 -0
  23. dataagent/actions/skills/__init__.py +12 -0
  24. dataagent/actions/skills/data_analysis_report/SKILL.md +95 -0
  25. dataagent/actions/skills/ontology_service/SKILL.md +65 -0
  26. dataagent/actions/skills/ontology_service/__init__.py +12 -0
  27. dataagent/actions/skills/ontology_service/references/commands.md +204 -0
  28. dataagent/actions/skills/ontology_service/references/public-api.md +66 -0
  29. dataagent/actions/skills/ontology_service/scripts/__init__.py +12 -0
  30. dataagent/actions/skills/ontology_service/scripts/cli_utils.py +75 -0
  31. dataagent/actions/skills/ontology_service/scripts/describe_ontology.py +39 -0
  32. dataagent/actions/skills/ontology_service/scripts/entity_lookup.py +77 -0
  33. dataagent/actions/skills/ontology_service/scripts/ontology_cli.py +1067 -0
  34. dataagent/actions/skills/ontology_service/scripts/ontology_client.py +533 -0
  35. dataagent/actions/tools/__init__.py +36 -0
  36. dataagent/actions/tools/a2a.py +472 -0
  37. dataagent/actions/tools/backfill.py +126 -0
  38. dataagent/actions/tools/concurrency.py +114 -0
  39. dataagent/actions/tools/context.py +49 -0
  40. dataagent/actions/tools/hooks/__init__.py +34 -0
  41. dataagent/actions/tools/hooks/base.py +123 -0
  42. dataagent/actions/tools/hooks/config.py +73 -0
  43. dataagent/actions/tools/hooks/examples/__init__.py +17 -0
  44. dataagent/actions/tools/hooks/examples/example_hooks.py +95 -0
  45. dataagent/actions/tools/local.py +172 -0
  46. dataagent/actions/tools/local_tool/agent_status_handler.py +221 -0
  47. dataagent/actions/tools/local_tool/document_recall.py +300 -0
  48. dataagent/actions/tools/local_tool/plan.py +166 -0
  49. dataagent/actions/tools/local_tool/sandbox.py +655 -0
  50. dataagent/actions/tools/local_tool/sql_reader.py +36 -0
  51. dataagent/actions/tools/local_tool/sub_agent_entry.py +255 -0
  52. dataagent/actions/tools/local_tool/tools.py +2756 -0
  53. dataagent/actions/tools/mcp.py +486 -0
  54. dataagent/actions/tools/mcp_examples.py +231 -0
  55. dataagent/actions/tools/mcp_tool/nl2sql.py +62 -0
  56. dataagent/actions/tools/schema_validator.py +438 -0
  57. dataagent/actions/tools/semantic_tool/get_join_relations.py +108 -0
  58. dataagent/actions/tools/semantic_tool/get_table_desc.py +35 -0
  59. dataagent/actions/tools/semantic_tool/search_metric_instance.py +991 -0
  60. dataagent/actions/tools/semantic_tool/search_tables_with_schema.py +588 -0
  61. dataagent/actions/tools/semantic_tool/search_udf_functions.py +641 -0
  62. dataagent/actions/tools/utils.py +65 -0
  63. dataagent/agents/document_recall/document_recall_agent.yaml +109 -0
  64. dataagent/agents/document_recall/tools.py +141 -0
  65. dataagent/agents/galatea/__init__.py +13 -0
  66. dataagent/agents/galatea/actions/__init__.py +38 -0
  67. dataagent/agents/galatea/actions/bash.py +59 -0
  68. dataagent/agents/galatea/actions/create_subagent.py +70 -0
  69. dataagent/agents/galatea/actions/edit.py +90 -0
  70. dataagent/agents/galatea/actions/inspect.py +73 -0
  71. dataagent/agents/galatea/actions/read.py +66 -0
  72. dataagent/agents/galatea/actions/search_online.py +80 -0
  73. dataagent/agents/galatea/actions/write.py +45 -0
  74. dataagent/agents/galatea/agent.py +194 -0
  75. dataagent/agents/galatea/core/__init__.py +19 -0
  76. dataagent/agents/galatea/graph/__init__.py +12 -0
  77. dataagent/agents/galatea/graph/executor.py +122 -0
  78. dataagent/agents/galatea/graph/planner.py +125 -0
  79. dataagent/agents/galatea/graph/router.py +139 -0
  80. dataagent/agents/galatea/graph/rule.py +35 -0
  81. dataagent/agents/galatea/hooks/__init__.py +12 -0
  82. dataagent/agents/galatea/hooks/metadata_tracker.py +210 -0
  83. dataagent/agents/galatea/hooks/portraiter.py +150 -0
  84. dataagent/agents/galatea/hooks/pruner.py +84 -0
  85. dataagent/agents/galatea/hooks/streamer.py +141 -0
  86. dataagent/agents/galatea/prompts/planner/system.md +42 -0
  87. dataagent/agents/galatea/prompts/planner/user.md +7 -0
  88. dataagent/agents/galatea/state/__init__.py +12 -0
  89. dataagent/agents/galatea/state/state.py +22 -0
  90. dataagent/agents/galatea/utils/__init__.py +12 -0
  91. dataagent/agents/galatea/utils/history_utils.py +173 -0
  92. dataagent/agents/galatea/utils/json_store.py +40 -0
  93. dataagent/agents/galatea/utils/metadata_utils.py +148 -0
  94. dataagent/agents/galatea/utils/portraiter_utils.py +114 -0
  95. dataagent/agents/galatea/utils/workspace_utils.py +67 -0
  96. dataagent/agents/nl2sql/__init__.py +3 -0
  97. dataagent/agents/nl2sql/agent.py +178 -0
  98. dataagent/agents/nl2sql/errors.py +98 -0
  99. dataagent/agents/nl2sql/nl2sql_agent.yaml +41 -0
  100. dataagent/agents/nl2sql/nodes/__init__.py +31 -0
  101. dataagent/agents/nl2sql/nodes/base_nl2sql_node.py +70 -0
  102. dataagent/agents/nl2sql/nodes/coordinator.py +34 -0
  103. dataagent/agents/nl2sql/nodes/executor.py +54 -0
  104. dataagent/agents/nl2sql/nodes/generator.py +94 -0
  105. dataagent/agents/nl2sql/nodes/perceptor.py +199 -0
  106. dataagent/agents/nl2sql/nodes/reflector.py +59 -0
  107. dataagent/agents/nl2sql/nodes/selector.py +74 -0
  108. dataagent/agents/nl2sql/nodes/validator.py +172 -0
  109. dataagent/agents/nl2sql/prompts/coordinator/system.md +30 -0
  110. dataagent/agents/nl2sql/prompts/coordinator/user.md +7 -0
  111. dataagent/agents/nl2sql/prompts/generator/dc_system.md +44 -0
  112. dataagent/agents/nl2sql/prompts/generator/dc_user.md +12 -0
  113. dataagent/agents/nl2sql/prompts/generator/icl_system.md +33 -0
  114. dataagent/agents/nl2sql/prompts/generator/icl_user.md +18 -0
  115. dataagent/agents/nl2sql/prompts/generator/prompt_system.md +17 -0
  116. dataagent/agents/nl2sql/prompts/generator/prompt_user.md +15 -0
  117. dataagent/agents/nl2sql/prompts/generator/skeleton_system.md +46 -0
  118. dataagent/agents/nl2sql/prompts/generator/skeleton_user.md +10 -0
  119. dataagent/agents/nl2sql/prompts/perceptor/filter_udn_table_system.md +32 -0
  120. dataagent/agents/nl2sql/prompts/perceptor/filter_udn_table_user.md +8 -0
  121. dataagent/agents/nl2sql/prompts/reflector/system.md +29 -0
  122. dataagent/agents/nl2sql/prompts/reflector/user.md +7 -0
  123. dataagent/agents/nl2sql/prompts/selector/system.md +30 -0
  124. dataagent/agents/nl2sql/prompts/selector/user.md +13 -0
  125. dataagent/agents/nl2sql/prompts/user/sql_rules_bird.md +6 -0
  126. dataagent/agents/nl2sql/prompts/user/sql_rules_udn.md +71 -0
  127. dataagent/agents/nl2sql/prompts/user/sql_rules_zdy.md +3 -0
  128. dataagent/agents/nl2sql/prompts/validator/extract_columns_system.md +30 -0
  129. dataagent/agents/nl2sql/prompts/validator/extract_columns_user.md +3 -0
  130. dataagent/agents/nl2sql/prompts/validator/validate_semantic_system.md +30 -0
  131. dataagent/agents/nl2sql/prompts/validator/validate_semantic_user.md +18 -0
  132. dataagent/agents/nl2sql/udn.yaml +33 -0
  133. dataagent/agents/nl2sql/utils/metavisor_client.py +123 -0
  134. dataagent/agents/nl2sql/utils/nl2sql_utils.py +232 -0
  135. dataagent/agents/nl2sql/utils/sql_service.py +310 -0
  136. dataagent/agents/nl2sql/workflow/router.py +63 -0
  137. dataagent/agents/nl2sql/workflow/state.py +104 -0
  138. dataagent/common_utils/knowledge_base/knowledge_base.py +405 -0
  139. dataagent/common_utils/knowledge_base/memory.py +1338 -0
  140. dataagent/common_utils/knowledge_base/metadata_management.py +1129 -0
  141. dataagent/common_utils/knowledge_base/tool_management.py +331 -0
  142. dataagent/common_utils/knowledge_base/utils_common.py +869 -0
  143. dataagent/common_utils/knowledge_base/utils_inference.py +80 -0
  144. dataagent/common_utils/knowledge_base/utils_knowledgebase.py +119 -0
  145. dataagent/common_utils/knowledge_base/utils_memory.py +322 -0
  146. dataagent/common_utils/knowledge_base/utils_metadata.py +267 -0
  147. dataagent/common_utils/storer_utils.py +113 -0
  148. dataagent/config/__init__.py +35 -0
  149. dataagent/config/config_manager.py +343 -0
  150. dataagent/core/__init__.py +30 -0
  151. dataagent/core/cbb/__init__.py +17 -0
  152. dataagent/core/cbb/agent_env.py +63 -0
  153. dataagent/core/cbb/base_agent.py +142 -0
  154. dataagent/core/cbb/base_hook.py +36 -0
  155. dataagent/core/cbb/base_node.py +148 -0
  156. dataagent/core/cbb/base_router.py +81 -0
  157. dataagent/core/cbb/base_state.py +19 -0
  158. dataagent/core/cbb/galatea_base_agent.py +114 -0
  159. dataagent/core/cbb/module.py +27 -0
  160. dataagent/core/cbb/runtime.py +327 -0
  161. dataagent/core/cbb/runtime_env.py +577 -0
  162. dataagent/core/context/contextIR.py +617 -0
  163. dataagent/core/context/context_trajectory.py +1129 -0
  164. dataagent/core/context/flex_context_formatting.py +179 -0
  165. dataagent/core/context/message_history.py +207 -0
  166. dataagent/core/context/todolist_manager.py +202 -0
  167. dataagent/core/context/util.py +113 -0
  168. dataagent/core/context/utils_context_storage.py +320 -0
  169. dataagent/core/context/utils_context_trajectory.py +323 -0
  170. dataagent/core/flex/agent.py +982 -0
  171. dataagent/core/flex/examples/arithmetic.yaml +29 -0
  172. dataagent/core/flex/examples/changping.yaml +87 -0
  173. dataagent/core/flex/examples/deep_analyze.yaml +7 -0
  174. dataagent/core/flex/examples/ecommerce_agent.yaml +55 -0
  175. dataagent/core/flex/examples/example.yaml +292 -0
  176. dataagent/core/flex/examples/icbc.yaml +69 -0
  177. dataagent/core/flex/examples/manufacturing.yaml +92 -0
  178. dataagent/core/flex/examples/nl2sql_flex_e2e_subagent.yaml +44 -0
  179. dataagent/core/flex/examples/ontology_sub_agent.yaml +42 -0
  180. dataagent/core/flex/examples/quickstart.yaml +15 -0
  181. dataagent/core/flex/examples/test_custom_prompt.yaml +65 -0
  182. dataagent/core/flex/examples/test_skills.yaml +36 -0
  183. dataagent/core/flex/examples/test_subagent_tool.yaml +40 -0
  184. dataagent/core/flex/examples/ueg.yaml +35 -0
  185. dataagent/core/flex/examples/yunhe.yaml +21 -0
  186. dataagent/core/flex/flex_default_configs.yaml +60 -0
  187. dataagent/core/flex/flex_runtime_from_config.py +330 -0
  188. dataagent/core/flex/hooks/__init__.py +15 -0
  189. dataagent/core/flex/hooks/agent_turn.py +54 -0
  190. dataagent/core/flex/hooks/cross_session_recall.py +200 -0
  191. dataagent/core/flex/hooks/history_writer.py +54 -0
  192. dataagent/core/flex/hooks/memory_indexer.py +128 -0
  193. dataagent/core/flex/hooks/metadata_tracker.py +263 -0
  194. dataagent/core/flex/hooks/organize_workspace.py +49 -0
  195. dataagent/core/flex/hooks/portraiter.py +346 -0
  196. dataagent/core/flex/hooks/pruner.py +84 -0
  197. dataagent/core/flex/hooks/registry.py +45 -0
  198. dataagent/core/flex/nodes/executor.py +1242 -0
  199. dataagent/core/flex/nodes/human_feedback.py +405 -0
  200. dataagent/core/flex/nodes/planner.py +435 -0
  201. dataagent/core/flex/utils/__init__.py +13 -0
  202. dataagent/core/flex/utils/context_from_state.py +68 -0
  203. dataagent/core/flex/utils/planner_prompt_builder.py +848 -0
  204. dataagent/core/flex/workflow/router.py +212 -0
  205. dataagent/core/flex/workflow/state.py +44 -0
  206. dataagent/core/framework_adapters/checkpoints/__init__.py +9 -0
  207. dataagent/core/framework_adapters/checkpoints/postgres_store.py +110 -0
  208. dataagent/core/framework_adapters/checkpoints/sqlite_store.py +124 -0
  209. dataagent/core/framework_adapters/checkpoints/types.py +24 -0
  210. dataagent/core/framework_adapters/runtime/__init__.py +38 -0
  211. dataagent/core/framework_adapters/runtime/context.py +373 -0
  212. dataagent/core/framework_adapters/runtime/workflow.py +176 -0
  213. dataagent/core/framework_adapters/runtime/workflow_backend.py +208 -0
  214. dataagent/core/framework_adapters/runtime/workflow_backend_factory.py +53 -0
  215. dataagent/core/framework_adapters/runtime/workflow_openjiuwen.py +707 -0
  216. dataagent/core/interface.py +101 -0
  217. dataagent/core/managers/action_manager/__init__.py +35 -0
  218. dataagent/core/managers/action_manager/base.py +220 -0
  219. dataagent/core/managers/action_manager/manager.py +1071 -0
  220. dataagent/core/managers/action_manager/registry.py +81 -0
  221. dataagent/core/managers/action_manager/schemas.py +322 -0
  222. dataagent/core/managers/galatea_action_manager.py +251 -0
  223. dataagent/core/managers/llm_manager/__init__.py +50 -0
  224. dataagent/core/managers/llm_manager/adapters.py +610 -0
  225. dataagent/core/managers/llm_manager/galatea_llm.py +46 -0
  226. dataagent/core/managers/llm_manager/llm_client.py +889 -0
  227. dataagent/core/managers/llm_manager/llm_config.py +82 -0
  228. dataagent/core/managers/llm_manager/llm_manager.py +115 -0
  229. dataagent/core/managers/prompt_manager/__init__.py +31 -0
  230. dataagent/core/managers/prompt_manager/template.py +120 -0
  231. dataagent/core/managers/prompt_manager/templates/__init__.py +12 -0
  232. dataagent/core/managers/prompt_manager/templates/context/fold_messages.md +80 -0
  233. dataagent/core/managers/prompt_manager/templates/human_feedback/system.md +13 -0
  234. dataagent/core/managers/prompt_manager/templates/human_feedback/user.md +7 -0
  235. dataagent/core/managers/prompt_manager/templates/irmanager/system.md +1 -0
  236. dataagent/core/managers/prompt_manager/templates/irmanager/system_update_state.md +8 -0
  237. dataagent/core/managers/prompt_manager/templates/irmanager/user.md +21 -0
  238. dataagent/core/managers/prompt_manager/templates/irmanager/user_update_state.md +11 -0
  239. dataagent/core/managers/prompt_manager/templates/knowledge_base/community_parent_report.md +39 -0
  240. dataagent/core/managers/prompt_manager/templates/knowledge_base/community_report.md +39 -0
  241. dataagent/core/managers/prompt_manager/templates/knowledge_base/extract_column_relationships.md +15 -0
  242. dataagent/core/managers/prompt_manager/templates/knowledge_base/extract_columns.md +14 -0
  243. dataagent/core/managers/prompt_manager/templates/knowledge_base/extract_tool_relationships.md +20 -0
  244. dataagent/core/managers/prompt_manager/templates/knowledge_base/extract_virtual_columns.md +18 -0
  245. dataagent/core/managers/prompt_manager/templates/knowledge_base/infer_data_type.md +24 -0
  246. dataagent/core/managers/prompt_manager/templates/knowledge_base/infer_file_description.md +22 -0
  247. dataagent/core/managers/prompt_manager/templates/knowledge_base/infer_schema_description.md +18 -0
  248. dataagent/core/managers/prompt_manager/templates/knowledge_base/update_column_description.md +28 -0
  249. dataagent/core/managers/prompt_manager/templates/knowledge_base/user_guide_kb.md +11 -0
  250. dataagent/core/managers/prompt_manager/templates/nl2sql_react/system.md +17 -0
  251. dataagent/core/managers/prompt_manager/templates/nl2sql_react/user.md +1 -0
  252. dataagent/core/managers/prompt_manager/templates/perceptor/keyword_extract_system.md +34 -0
  253. dataagent/core/managers/prompt_manager/templates/perceptor/keyword_extract_user.md +7 -0
  254. dataagent/core/managers/prompt_manager/templates/planner/system.md +128 -0
  255. dataagent/core/managers/prompt_manager/templates/planner/todo.md +38 -0
  256. dataagent/core/managers/prompt_manager/templates/planner/user.md +44 -0
  257. dataagent/core/managers/prompt_manager/templates/skill_selector/system.md +118 -0
  258. dataagent/core/managers/prompt_manager/templates/skill_selector/user.md +15 -0
  259. dataagent/core/swarm/__init__.py +15 -0
  260. dataagent/core/swarm/swarm_config.py +65 -0
  261. dataagent/core/swarm/worker_io.py +27 -0
  262. dataagent/core/swarm/worker_lock.py +105 -0
  263. dataagent/core/swarm/worker_memory.py +133 -0
  264. dataagent/core/swarm/worker_metadata.py +247 -0
  265. dataagent/core/swarm/worker_result.py +255 -0
  266. dataagent/core/utils/__init__.py +13 -0
  267. dataagent/core/utils/performance.py +597 -0
  268. dataagent/interface/cli/__init__.py +17 -0
  269. dataagent/interface/cli/main.py +640 -0
  270. dataagent/interface/rest_api/__init__.py +22 -0
  271. dataagent/interface/rest_api/app.py +110 -0
  272. dataagent/interface/rest_api/service.py +242 -0
  273. dataagent/interface/rest_api/start_service.py +52 -0
  274. dataagent/interface/sdk/__init__.py +24 -0
  275. dataagent/interface/sdk/agent.py +309 -0
  276. dataagent/interface/sdk/base_data_agent.py +425 -0
  277. dataagent/interface/sdk/builder.py +410 -0
  278. dataagent/interface/sdk/loader.py +34 -0
  279. dataagent/utils/__init__.py +12 -0
  280. dataagent/utils/builder_utils.py +368 -0
  281. dataagent/utils/cli/rich_renderer.py +889 -0
  282. dataagent/utils/cli/terminal_input.py +132 -0
  283. dataagent/utils/compression_utils.py +237 -0
  284. dataagent/utils/constants.py +472 -0
  285. dataagent/utils/converter/__init__.py +21 -0
  286. dataagent/utils/converter/graph_summary.py +230 -0
  287. dataagent/utils/converter/ir_converter_constants.py +188 -0
  288. dataagent/utils/converter/ir_message_consumer.py +220 -0
  289. dataagent/utils/converter/result_ir_converter.py +747 -0
  290. dataagent/utils/dag_utils.py +145 -0
  291. dataagent/utils/env_file_loader.py +255 -0
  292. dataagent/utils/env_utils.py +35 -0
  293. dataagent/utils/fix_md_image_path.py +300 -0
  294. dataagent/utils/formatting_utils.py +525 -0
  295. dataagent/utils/import_utils.py +154 -0
  296. dataagent/utils/info_utils.py +31 -0
  297. dataagent/utils/log/__init__.py +62 -0
  298. dataagent/utils/log/config.py +54 -0
  299. dataagent/utils/log/configs/default.yaml +49 -0
  300. dataagent/utils/log/configs/dev.yaml +18 -0
  301. dataagent/utils/log/configs/prod.yaml +19 -0
  302. dataagent/utils/log/dataagent_logger.py +311 -0
  303. dataagent/utils/messages_utils.py +390 -0
  304. dataagent/utils/parsing_utils.py +403 -0
  305. dataagent/utils/runtime_paths.py +167 -0
  306. dg_dataagent-0.1.0.dist-info/METADATA +273 -0
  307. dg_dataagent-0.1.0.dist-info/RECORD +310 -0
  308. dg_dataagent-0.1.0.dist-info/WHEEL +5 -0
  309. dg_dataagent-0.1.0.dist-info/licenses/LICENSE +201 -0
  310. dg_dataagent-0.1.0.dist-info/top_level.txt +1 -0
dataagent/__init__.py ADDED
@@ -0,0 +1,37 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ """dataagent 包入口。
14
+
15
+ 注意:这里保持轻量,避免在 import dataagent 时就触发大量依赖初始化/循环导入。
16
+ 需要 DataAgent 等对象时,通过属性懒加载获取。
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ __version__ = "0.1.0"
22
+ __author__ = "DataAgent Team"
23
+
24
+ from typing import Any
25
+
26
+
27
+ def __getattr__(name: str) -> Any:
28
+ if name in ("DataAgent", "AgentBuilder", "load_agent_from_config", "BaseDataAgent"):
29
+ from dataagent.interface.sdk import AgentBuilder, BaseDataAgent, DataAgent, load_agent_from_config
30
+
31
+ return {
32
+ "DataAgent": DataAgent,
33
+ "AgentBuilder": AgentBuilder,
34
+ "BaseDataAgent": BaseDataAgent,
35
+ "load_agent_from_config": load_agent_from_config,
36
+ }[name]
37
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
dataagent/__main__.py ADDED
@@ -0,0 +1,16 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ from dataagent.interface.cli.main import main
14
+
15
+ if __name__ == "__main__":
16
+ main()
@@ -0,0 +1,25 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+
14
+ """DataAgent A2A 1.0 Server — exposes DataAgent agents as A2A-compliant services."""
15
+
16
+ from dataagent.a2a_server.agent_card import build_agent_card
17
+ from dataagent.a2a_server.agent_executor import DataAgentExecutor
18
+ from dataagent.a2a_server.server import create_a2a_server, run_a2a_server
19
+
20
+ __all__ = [
21
+ "DataAgentExecutor",
22
+ "build_agent_card",
23
+ "create_a2a_server",
24
+ "run_a2a_server",
25
+ ]
@@ -0,0 +1,85 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ """Build A2A 1.0 AgentCard from a DataAgent."""
14
+
15
+ from a2a.types.a2a_pb2 import (
16
+ AgentCapabilities,
17
+ AgentCard,
18
+ AgentInterface,
19
+ AgentSkill,
20
+ )
21
+
22
+ from dataagent.interface.sdk.agent import DataAgent
23
+
24
+
25
+ def build_agent_card(
26
+ agent: DataAgent,
27
+ host: str = "0.0.0.0",
28
+ port: int = 9999,
29
+ jsonrpc_path: str = "/a2a/jsonrpc",
30
+ rest_path: str = "/a2a/rest",
31
+ ) -> AgentCard:
32
+ """Create an A2A 1.0 AgentCard for the given DataAgent.
33
+
34
+ Args:
35
+ agent: The DataAgent instance to expose.
36
+ host: Server host for the interface URLs.
37
+ port: Server port for the interface URLs.
38
+ jsonrpc_path: JSON-RPC route path.
39
+ rest_path: REST route path.
40
+
41
+ Returns:
42
+ A2A 1.0 AgentCard with supported_interfaces.
43
+ """
44
+ agent_name = agent.name() or "DataAgent"
45
+ agent_desc = agent.description() or "DataAgent data analysis agent"
46
+ agent_ver = agent.version() or "0.1.0"
47
+
48
+ # AgentCard URL should use 127.0.0.1 for local access (host may be 0.0.0.0 for binding)
49
+ card_host = "127.0.0.1" if host in ("0.0.0.0", "::") else host
50
+ base_url = f"http://{card_host}:{port}"
51
+
52
+ # Build skills from agent info and known capabilities
53
+ skills = [
54
+ AgentSkill(
55
+ id="chat",
56
+ name="Chat",
57
+ description="Interactive conversational data analysis",
58
+ tags=["data-analysis", "chat"],
59
+ input_modes=["text/plain"],
60
+ output_modes=["text/plain"],
61
+ ),
62
+ ]
63
+
64
+ card = AgentCard(
65
+ name=agent_name,
66
+ description=agent_desc,
67
+ version=agent_ver,
68
+ default_input_modes=["text/plain"],
69
+ default_output_modes=["text/plain"],
70
+ capabilities=AgentCapabilities(streaming=True),
71
+ skills=skills,
72
+ supported_interfaces=[
73
+ AgentInterface(
74
+ protocol_binding="JSONRPC",
75
+ url=f"{base_url}{jsonrpc_path}",
76
+ protocol_version="1.0",
77
+ ),
78
+ AgentInterface(
79
+ protocol_binding="HTTP+JSON",
80
+ url=f"{base_url}{rest_path}",
81
+ protocol_version="1.0",
82
+ ),
83
+ ],
84
+ )
85
+ return card
@@ -0,0 +1,310 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ """DataAgentExecutor — bridges A2A 1.0 requests to DataAgent."""
14
+
15
+ import asyncio
16
+ import uuid
17
+ from typing import Any
18
+
19
+ from a2a.helpers import (
20
+ new_task,
21
+ new_text_artifact,
22
+ new_text_message,
23
+ new_text_status_update_event,
24
+ )
25
+ from a2a.server.agent_execution import AgentExecutor, RequestContext
26
+ from a2a.server.events import EventQueue
27
+ from a2a.types.a2a_pb2 import (
28
+ Role,
29
+ TaskArtifactUpdateEvent,
30
+ TaskState,
31
+ TaskStatus,
32
+ TaskStatusUpdateEvent,
33
+ )
34
+ from loguru import logger
35
+
36
+ from dataagent.interface.sdk.agent import DataAgent
37
+
38
+
39
+ class DataAgentExecutor(AgentExecutor):
40
+ """Bridges A2A 1.0 protocol requests to DataAgent execution."""
41
+
42
+ def __init__(self, agent: DataAgent):
43
+ self._agent = agent
44
+ self._cancellation_events: dict[str, asyncio.Event] = {}
45
+ self._run_counters: dict[str, int] = {}
46
+ self._run_lock = asyncio.Lock()
47
+ self._session_locks: dict[str, asyncio.Lock] = {}
48
+ self._session_locks_guard = asyncio.Lock()
49
+
50
+ async def execute(
51
+ self,
52
+ context: RequestContext,
53
+ event_queue: EventQueue,
54
+ ) -> None:
55
+ """Handle an A2A request by invoking the DataAgent.
56
+
57
+ Publishes task status updates and artifacts to the event queue,
58
+ supporting both sync and streaming (SSE) responses.
59
+ """
60
+ task = context.current_task or new_task(
61
+ task_id=context.task_id,
62
+ context_id=context.context_id,
63
+ state=TaskState.TASK_STATE_SUBMITTED,
64
+ )
65
+ await event_queue.enqueue_event(task)
66
+
67
+ user_text = _extract_text_from_context(context)
68
+ if not user_text:
69
+ await self._fail_with_message(event_queue, context, "No user message provided.")
70
+ return
71
+
72
+ cancel_event = asyncio.Event()
73
+ self._cancellation_events[context.task_id] = cancel_event
74
+
75
+ session_id = context.context_id or context.task_id or f"a2a-{uuid.uuid4().hex[:12]}"
76
+ session_lock = await self._get_session_lock(session_id)
77
+
78
+ try:
79
+ async with session_lock:
80
+ await event_queue.enqueue_event(
81
+ new_text_status_update_event(
82
+ task_id=context.task_id,
83
+ context_id=context.context_id,
84
+ state=TaskState.TASK_STATE_WORKING,
85
+ text="Processing request...",
86
+ )
87
+ )
88
+
89
+ response = await self._execute_agent_chat(user_text, session_id, context.task_id)
90
+
91
+ if cancel_event.is_set():
92
+ await event_queue.enqueue_event(
93
+ new_text_status_update_event(
94
+ task_id=context.task_id,
95
+ context_id=context.context_id,
96
+ state=TaskState.TASK_STATE_CANCELED,
97
+ text="Task was canceled.",
98
+ )
99
+ )
100
+ return
101
+
102
+ result_text = _extract_final_answer(response)
103
+
104
+ has_error = self._has_error_response(response)
105
+ if has_error:
106
+ error_msg = self._extract_error_message(response)
107
+ logger.error(f"Agent execution failed: {error_msg}")
108
+ await event_queue.enqueue_event(
109
+ new_text_status_update_event(
110
+ task_id=context.task_id,
111
+ context_id=context.context_id,
112
+ state=TaskState.TASK_STATE_FAILED,
113
+ text=str(error_msg) if error_msg else "Agent execution failed",
114
+ )
115
+ )
116
+ return
117
+
118
+ logger.info("Agent execution completed successfully")
119
+
120
+ await event_queue.enqueue_event(
121
+ TaskArtifactUpdateEvent(
122
+ task_id=context.task_id,
123
+ context_id=context.context_id,
124
+ artifact=new_text_artifact(name="dataagent_result", text=result_text),
125
+ )
126
+ )
127
+ await event_queue.enqueue_event(
128
+ new_text_status_update_event(
129
+ task_id=context.task_id,
130
+ context_id=context.context_id,
131
+ state=TaskState.TASK_STATE_COMPLETED,
132
+ text=result_text,
133
+ )
134
+ )
135
+
136
+ except asyncio.CancelledError:
137
+ await event_queue.enqueue_event(
138
+ new_text_status_update_event(
139
+ task_id=context.task_id,
140
+ context_id=context.context_id,
141
+ state=TaskState.TASK_STATE_CANCELED,
142
+ text="Task was canceled.",
143
+ )
144
+ )
145
+ except Exception as e:
146
+ logger.error(f"DataAgent execution failed: {e}")
147
+ await event_queue.enqueue_event(
148
+ new_text_status_update_event(
149
+ task_id=context.task_id,
150
+ context_id=context.context_id,
151
+ state=TaskState.TASK_STATE_FAILED,
152
+ text=f"Error: {str(e)}",
153
+ )
154
+ )
155
+ finally:
156
+ self._cancellation_events.pop(context.task_id, None)
157
+
158
+ async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
159
+ """Request cancellation of an ongoing task."""
160
+ cancel_event = self._cancellation_events.get(context.task_id)
161
+ if cancel_event:
162
+ cancel_event.set()
163
+ await event_queue.enqueue_event(
164
+ new_text_status_update_event(
165
+ task_id=context.task_id,
166
+ context_id=context.context_id,
167
+ state=TaskState.TASK_STATE_CANCELED,
168
+ text="Task was canceled.",
169
+ )
170
+ )
171
+
172
+ async def _fail_with_message(
173
+ self,
174
+ event_queue: EventQueue,
175
+ context: RequestContext,
176
+ message: str,
177
+ ) -> None:
178
+ """Publish a failed status event with the given message."""
179
+ await event_queue.enqueue_event(
180
+ TaskStatusUpdateEvent(
181
+ task_id=context.task_id,
182
+ context_id=context.context_id,
183
+ status=TaskStatus(
184
+ state=TaskState.TASK_STATE_FAILED,
185
+ message=new_text_message(
186
+ text=message,
187
+ role=Role.ROLE_AGENT,
188
+ task_id=context.task_id,
189
+ context_id=context.context_id,
190
+ ),
191
+ ),
192
+ )
193
+ )
194
+
195
+ async def _execute_agent_chat(
196
+ self,
197
+ user_text: str,
198
+ session_id: str,
199
+ task_id: str,
200
+ ) -> Any:
201
+ """Acquire session lock, increment run counter, and execute agent chat."""
202
+ async with self._run_lock:
203
+ run_id = self._run_counters.get(session_id, 0)
204
+ self._run_counters[session_id] = run_id + 1
205
+ initial_state = {"session_id": session_id, "run_id": run_id}
206
+
207
+ response = await self._agent.chat(user_query=user_text, session_id=session_id, initial_state=initial_state)
208
+
209
+ logger.info(f"[DEBUG] _agent.chat() returned type: {type(response)}")
210
+ if isinstance(response, dict):
211
+ logger.info(f"[DEBUG] _agent.chat() response keys: {list(response.keys())}")
212
+ logger.info(f"[DEBUG] _agent.chat() response: {response}")
213
+
214
+ return response
215
+
216
+ def _has_error_response(self, response: Any) -> bool:
217
+ """Check if the response contains an error.
218
+
219
+ Errors can be in two places:
220
+ 1. Top-level: response.get("error") - from DataAgent.chat() exception handling
221
+ 2. Nested: response["messages"][-1].additional_kwargs.get("error") - from FlexAgent planner
222
+ """
223
+ if not isinstance(response, dict):
224
+ return False
225
+
226
+ if "error" in response:
227
+ return True
228
+
229
+ if response.get("messages"):
230
+ last_msg = response["messages"][-1]
231
+ if isinstance(last_msg, dict):
232
+ return bool(last_msg.get("additional_kwargs", {}).get("error"))
233
+ return bool(getattr(last_msg, "additional_kwargs", {}).get("error"))
234
+
235
+ return False
236
+
237
+ def _extract_error_message(self, response: Any) -> str:
238
+ """Extract the error message from a response."""
239
+ if not isinstance(response, dict):
240
+ return str(response)
241
+
242
+ if "error" in response:
243
+ return str(response.get("error"))
244
+
245
+ if response.get("messages"):
246
+ last_msg = response["messages"][-1]
247
+ if isinstance(last_msg, dict):
248
+ return str(last_msg.get("content", str(response)))
249
+ return str(getattr(last_msg, "content", str(response)))
250
+
251
+ return str(response)
252
+
253
+ async def _get_session_lock(self, session_id: str) -> asyncio.Lock:
254
+ """Get or create a per-session Lock for FIFO task serialization."""
255
+ async with self._session_locks_guard:
256
+ lock = self._session_locks.get(session_id)
257
+ if lock is None:
258
+ lock = asyncio.Lock()
259
+ self._session_locks[session_id] = lock
260
+ return lock
261
+
262
+
263
+ def _extract_text_from_context(context: RequestContext) -> str:
264
+ """Extract text content from the request context message."""
265
+ # RequestContext.get_user_input() already handles text extraction
266
+ user_text = context.get_user_input()
267
+ if user_text:
268
+ return user_text
269
+
270
+ # Fallback: extract from context.message directly
271
+ message = context.message
272
+ if message is None:
273
+ return ""
274
+
275
+ parts_text = []
276
+ for part in message.parts:
277
+ if part.text:
278
+ parts_text.append(part.text)
279
+ elif part.data:
280
+ try:
281
+ import json
282
+
283
+ from google.protobuf.json_format import MessageToDict
284
+
285
+ data_dict = MessageToDict(part.data)
286
+ parts_text.append(json.dumps(data_dict, ensure_ascii=False))
287
+ except Exception:
288
+ parts_text.append(str(part.data))
289
+
290
+ return "".join(parts_text).strip()
291
+
292
+
293
+ def _extract_final_answer(response: Any) -> str:
294
+ """Extract the final answer text from a DataAgent response."""
295
+ if isinstance(response, dict):
296
+ for key in ("final_answer", "answer", "result", "response"):
297
+ if key in response:
298
+ val = response[key]
299
+ if isinstance(val, str):
300
+ return val
301
+ return str(val)
302
+
303
+ messages = response.get("messages", [])
304
+ if messages:
305
+ last_msg = messages[-1]
306
+ content = getattr(last_msg, "content", str(last_msg))
307
+ return str(content)
308
+
309
+ return str(response)
310
+ return str(response)
@@ -0,0 +1,169 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ """Assemble and run an A2A 1.0 server for a DataAgent."""
14
+
15
+ from a2a.server.agent_execution import AgentExecutor
16
+ from a2a.server.request_handlers import DefaultRequestHandler
17
+ from a2a.server.request_handlers.response_helpers import agent_card_to_dict
18
+ from a2a.server.routes import (
19
+ create_jsonrpc_routes,
20
+ create_rest_routes,
21
+ )
22
+ from a2a.server.tasks import InMemoryTaskStore
23
+ from a2a.types.a2a_pb2 import AgentCard
24
+ from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
25
+ from starlette.applications import Starlette
26
+ from starlette.middleware import Middleware
27
+ from starlette.requests import Request
28
+ from starlette.responses import JSONResponse
29
+ from starlette.routing import Route
30
+
31
+
32
+ def _make_bearer_middleware(token: str, exclude_paths: tuple[str, ...]):
33
+ """Create a Bearer token authentication middleware."""
34
+ from starlette.middleware.base import BaseHTTPMiddleware
35
+
36
+ class BearerAuthMiddleware(BaseHTTPMiddleware):
37
+ """Validate Bearer token on every request, skipping excluded paths."""
38
+
39
+ async def dispatch(self, request: Request, call_next):
40
+ """Check Authorization header against the expected token.
41
+
42
+ Returns 401 if the token is missing or invalid, otherwise
43
+ forwards the request to the next middleware/route handler.
44
+ """
45
+ if request.url.path in exclude_paths:
46
+ return await call_next(request)
47
+
48
+ auth = request.headers.get("Authorization", "")
49
+ if not auth.startswith("Bearer ") or auth[7:] != token:
50
+ return JSONResponse(
51
+ status_code=401,
52
+ content={"detail": "Unauthorized: invalid or missing Bearer token"},
53
+ )
54
+ return await call_next(request)
55
+
56
+ return Middleware(BearerAuthMiddleware)
57
+
58
+
59
+ def _create_dynamic_agent_card_routes(
60
+ agent_card: AgentCard,
61
+ jsonrpc_path: str,
62
+ rest_path: str,
63
+ ) -> list:
64
+ """Create agent card routes that use the requestʼs Host header for interface URLs.
65
+
66
+ Clients from any network can discover the correct URLs instead of always
67
+ receiving 127.0.0.1.
68
+ """
69
+
70
+ async def _get_agent_card(request: Request) -> JSONResponse:
71
+ base_card = agent_card_to_dict(agent_card)
72
+ host = request.headers.get("Host", "127.0.0.1:9999")
73
+ scheme = request.headers.get("X-Forwarded-Proto", request.url.scheme or "http")
74
+ base_url = f"{scheme}://{host}"
75
+
76
+ for iface in base_card.get("supportedInterfaces", []):
77
+ protocol = iface.get("protocolBinding", "")
78
+ if protocol == "JSONRPC":
79
+ iface["url"] = f"{base_url}{jsonrpc_path}"
80
+ elif protocol == "HTTP+JSON":
81
+ iface["url"] = f"{base_url}{rest_path}"
82
+
83
+ return JSONResponse(base_card)
84
+
85
+ return [
86
+ Route(path=AGENT_CARD_WELL_KNOWN_PATH, endpoint=_get_agent_card, methods=["GET"]),
87
+ ]
88
+
89
+
90
+ def create_a2a_server(
91
+ agent_card: AgentCard,
92
+ executor: AgentExecutor,
93
+ jsonrpc_path: str = "/a2a/jsonrpc",
94
+ rest_path: str = "/a2a/rest",
95
+ enable_v0_3_compat: bool = False,
96
+ auth_token: str | None = None,
97
+ auth_exclude_paths: tuple[str, ...] = ("/.well-known/agent-card.json",),
98
+ ) -> Starlette:
99
+ """Create a Starlette application with A2A 1.0 routes.
100
+
101
+ Args:
102
+ agent_card: The A2A AgentCard for this server.
103
+ executor: The AgentExecutor that handles requests.
104
+ jsonrpc_path: JSON-RPC route path (default: /a2a/jsonrpc).
105
+ rest_path: REST route path (default: /a2a/rest).
106
+ enable_v0_3_compat: Enable backward compatibility with A2A v0.3 clients.
107
+ auth_token: Bearer token for authentication. If None, no auth is required.
108
+ auth_exclude_paths: Paths to exclude from auth checks (default: AgentCard discovery).
109
+
110
+ Returns:
111
+ A configured Starlette application.
112
+ """
113
+ task_store = InMemoryTaskStore()
114
+
115
+ request_handler = DefaultRequestHandler(
116
+ agent_executor=executor,
117
+ task_store=task_store,
118
+ agent_card=agent_card,
119
+ )
120
+
121
+ routes: list = []
122
+ routes.extend(_create_dynamic_agent_card_routes(agent_card, jsonrpc_path, rest_path))
123
+ routes.extend(create_jsonrpc_routes(request_handler, rpc_url=jsonrpc_path, enable_v0_3_compat=enable_v0_3_compat))
124
+ routes.extend(create_rest_routes(request_handler, path_prefix=rest_path, enable_v0_3_compat=enable_v0_3_compat))
125
+
126
+ middleware: list = []
127
+ if auth_token:
128
+ middleware.append(_make_bearer_middleware(auth_token, exclude_paths=auth_exclude_paths))
129
+
130
+ app = Starlette(routes=routes, middleware=middleware)
131
+ return app
132
+
133
+
134
+ def run_a2a_server(
135
+ agent_card: AgentCard,
136
+ executor: AgentExecutor,
137
+ host: str = "",
138
+ port: int = 9999,
139
+ jsonrpc_path: str = "/a2a/jsonrpc",
140
+ rest_path: str = "/a2a/rest",
141
+ auth_token: str | None = None,
142
+ auth_exclude_paths: tuple[str, ...] = ("/.well-known/agent-card.json",),
143
+ ) -> None:
144
+ """Run the A2A server using uvicorn.
145
+
146
+ Args:
147
+ agent_card: The A2A AgentCard.
148
+ executor: The AgentExecutor.
149
+ host: Server host.
150
+ port: Server port.
151
+ jsonrpc_path: JSON-RPC route path.
152
+ rest_path: REST route path.
153
+ auth_token: Bearer token for authentication. If None, no auth is required.
154
+ auth_exclude_paths: Paths excluded from auth checks.
155
+ """
156
+ import uvicorn
157
+
158
+ if not host:
159
+ raise ValueError("Host must be specified")
160
+ app = create_a2a_server(
161
+ agent_card=agent_card,
162
+ executor=executor,
163
+ jsonrpc_path=jsonrpc_path,
164
+ rest_path=rest_path,
165
+ auth_token=auth_token,
166
+ auth_exclude_paths=auth_exclude_paths,
167
+ )
168
+
169
+ uvicorn.run(app, host=host, port=port, log_level="info")
@@ -0,0 +1,29 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================
13
+ """Task store utilities for the A2A server.
14
+
15
+ For MVP we use the in-memory store from a2a-sdk.
16
+ For production, a PostgreSQL-backed store can be implemented here
17
+ using a2a-sdk[sql] extras.
18
+ """
19
+
20
+ from a2a.server.tasks import InMemoryTaskStore
21
+
22
+
23
+ def create_task_store() -> InMemoryTaskStore:
24
+ """Create an in-memory task store (MVP).
25
+
26
+ Returns:
27
+ An InMemoryTaskStore instance.
28
+ """
29
+ return InMemoryTaskStore()
@@ -0,0 +1,12 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ # ============================================================================