aip-agents-binary 0.6.4__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.
- aip_agents/__init__.py +65 -0
- aip_agents/__init__.pyi +19 -0
- aip_agents/a2a/__init__.py +19 -0
- aip_agents/a2a/__init__.pyi +3 -0
- aip_agents/a2a/server/__init__.py +10 -0
- aip_agents/a2a/server/__init__.pyi +4 -0
- aip_agents/a2a/server/base_executor.py +1086 -0
- aip_agents/a2a/server/base_executor.pyi +73 -0
- aip_agents/a2a/server/google_adk_executor.py +198 -0
- aip_agents/a2a/server/google_adk_executor.pyi +51 -0
- aip_agents/a2a/server/langflow_executor.py +180 -0
- aip_agents/a2a/server/langflow_executor.pyi +43 -0
- aip_agents/a2a/server/langgraph_executor.py +270 -0
- aip_agents/a2a/server/langgraph_executor.pyi +47 -0
- aip_agents/a2a/types.py +232 -0
- aip_agents/a2a/types.pyi +132 -0
- aip_agents/agent/__init__.py +27 -0
- aip_agents/agent/__init__.pyi +9 -0
- aip_agents/agent/base_agent.py +970 -0
- aip_agents/agent/base_agent.pyi +221 -0
- aip_agents/agent/base_langgraph_agent.py +3037 -0
- aip_agents/agent/base_langgraph_agent.pyi +233 -0
- aip_agents/agent/google_adk_agent.py +926 -0
- aip_agents/agent/google_adk_agent.pyi +141 -0
- aip_agents/agent/google_adk_constants.py +6 -0
- aip_agents/agent/google_adk_constants.pyi +3 -0
- aip_agents/agent/hitl/__init__.py +24 -0
- aip_agents/agent/hitl/__init__.pyi +6 -0
- aip_agents/agent/hitl/config.py +28 -0
- aip_agents/agent/hitl/config.pyi +15 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.pyi +42 -0
- aip_agents/agent/hitl/manager.py +532 -0
- aip_agents/agent/hitl/manager.pyi +200 -0
- aip_agents/agent/hitl/models.py +18 -0
- aip_agents/agent/hitl/models.pyi +3 -0
- aip_agents/agent/hitl/prompt/__init__.py +9 -0
- aip_agents/agent/hitl/prompt/__init__.pyi +4 -0
- aip_agents/agent/hitl/prompt/base.py +42 -0
- aip_agents/agent/hitl/prompt/base.pyi +24 -0
- aip_agents/agent/hitl/prompt/deferred.py +73 -0
- aip_agents/agent/hitl/prompt/deferred.pyi +30 -0
- aip_agents/agent/hitl/registry.py +149 -0
- aip_agents/agent/hitl/registry.pyi +101 -0
- aip_agents/agent/interface.py +138 -0
- aip_agents/agent/interface.pyi +81 -0
- aip_agents/agent/interfaces.py +65 -0
- aip_agents/agent/interfaces.pyi +44 -0
- aip_agents/agent/langflow_agent.py +464 -0
- aip_agents/agent/langflow_agent.pyi +133 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.py +767 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +50 -0
- aip_agents/agent/langgraph_react_agent.py +2856 -0
- aip_agents/agent/langgraph_react_agent.pyi +170 -0
- aip_agents/agent/system_instruction_context.py +34 -0
- aip_agents/agent/system_instruction_context.pyi +13 -0
- aip_agents/clients/__init__.py +10 -0
- aip_agents/clients/__init__.pyi +4 -0
- aip_agents/clients/langflow/__init__.py +10 -0
- aip_agents/clients/langflow/__init__.pyi +4 -0
- aip_agents/clients/langflow/client.py +477 -0
- aip_agents/clients/langflow/client.pyi +140 -0
- aip_agents/clients/langflow/types.py +18 -0
- aip_agents/clients/langflow/types.pyi +7 -0
- aip_agents/constants.py +23 -0
- aip_agents/constants.pyi +7 -0
- aip_agents/credentials/manager.py +132 -0
- aip_agents/examples/__init__.py +5 -0
- aip_agents/examples/__init__.pyi +0 -0
- aip_agents/examples/compare_streaming_client.py +783 -0
- aip_agents/examples/compare_streaming_client.pyi +48 -0
- aip_agents/examples/compare_streaming_server.py +142 -0
- aip_agents/examples/compare_streaming_server.pyi +18 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
- aip_agents/examples/hello_world_a2a_langchain_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
- aip_agents/examples/hello_world_a2a_langflow_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
- aip_agents/examples/hello_world_a2a_langflow_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +16 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +15 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +45 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_google_adk.py +41 -0
- aip_agents/examples/hello_world_google_adk.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_stream.py +44 -0
- aip_agents/examples/hello_world_google_adk_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain.py +28 -0
- aip_agents/examples/hello_world_langchain.pyi +5 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.pyi +16 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.pyi +18 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream.py +36 -0
- aip_agents/examples/hello_world_langchain_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_langflow_agent.py +163 -0
- aip_agents/examples/hello_world_langflow_agent.pyi +35 -0
- aip_agents/examples/hello_world_langgraph.py +39 -0
- aip_agents/examples/hello_world_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream.py +43 -0
- aip_agents/examples/hello_world_langgraph_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_model_switch_cli.py +210 -0
- aip_agents/examples/hello_world_model_switch_cli.pyi +30 -0
- aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
- aip_agents/examples/hello_world_multi_agent_adk.pyi +6 -0
- aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
- aip_agents/examples/hello_world_multi_agent_langchain.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_pii_logger.py +21 -0
- aip_agents/examples/hello_world_pii_logger.pyi +5 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_sentry.py +133 -0
- aip_agents/examples/hello_world_sentry.pyi +21 -0
- aip_agents/examples/hello_world_step_limits.py +273 -0
- aip_agents/examples/hello_world_step_limits.pyi +17 -0
- aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
- aip_agents/examples/hello_world_stock_a2a_server.pyi +17 -0
- aip_agents/examples/hello_world_tool_output_client.py +55 -0
- aip_agents/examples/hello_world_tool_output_client.pyi +5 -0
- aip_agents/examples/hello_world_tool_output_server.py +114 -0
- aip_agents/examples/hello_world_tool_output_server.pyi +19 -0
- aip_agents/examples/hitl_demo.py +724 -0
- aip_agents/examples/hitl_demo.pyi +67 -0
- aip_agents/examples/mcp_configs/configs.py +63 -0
- aip_agents/examples/mcp_servers/common.py +76 -0
- aip_agents/examples/mcp_servers/mcp_name.py +29 -0
- aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
- aip_agents/examples/mcp_servers/mcp_time.py +10 -0
- aip_agents/examples/pii_demo_langgraph_client.py +69 -0
- aip_agents/examples/pii_demo_langgraph_client.pyi +5 -0
- aip_agents/examples/pii_demo_langgraph_server.py +126 -0
- aip_agents/examples/pii_demo_langgraph_server.pyi +20 -0
- aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
- aip_agents/examples/pii_demo_multi_agent_client.pyi +5 -0
- aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
- aip_agents/examples/pii_demo_multi_agent_server.pyi +40 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.pyi +19 -0
- aip_agents/examples/tools/__init__.py +27 -0
- aip_agents/examples/tools/__init__.pyi +9 -0
- aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
- aip_agents/examples/tools/adk_arithmetic_tools.pyi +24 -0
- aip_agents/examples/tools/adk_weather_tool.py +60 -0
- aip_agents/examples/tools/adk_weather_tool.pyi +18 -0
- aip_agents/examples/tools/data_generator_tool.py +103 -0
- aip_agents/examples/tools/data_generator_tool.pyi +15 -0
- aip_agents/examples/tools/data_visualization_tool.py +312 -0
- aip_agents/examples/tools/data_visualization_tool.pyi +19 -0
- aip_agents/examples/tools/image_artifact_tool.py +136 -0
- aip_agents/examples/tools/image_artifact_tool.pyi +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.pyi +17 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +20 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +25 -0
- aip_agents/examples/tools/langchain_weather_tool.py +48 -0
- aip_agents/examples/tools/langchain_weather_tool.pyi +19 -0
- aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
- aip_agents/examples/tools/langgraph_streaming_tool.pyi +43 -0
- aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
- aip_agents/examples/tools/mock_retrieval_tool.pyi +13 -0
- aip_agents/examples/tools/pii_demo_tools.py +189 -0
- aip_agents/examples/tools/pii_demo_tools.pyi +54 -0
- aip_agents/examples/tools/random_chart_tool.py +142 -0
- aip_agents/examples/tools/random_chart_tool.pyi +20 -0
- aip_agents/examples/tools/serper_tool.py +202 -0
- aip_agents/examples/tools/serper_tool.pyi +16 -0
- aip_agents/examples/tools/stock_tools.py +82 -0
- aip_agents/examples/tools/stock_tools.pyi +36 -0
- aip_agents/examples/tools/table_generator_tool.py +167 -0
- aip_agents/examples/tools/table_generator_tool.pyi +22 -0
- aip_agents/examples/tools/time_tool.py +82 -0
- aip_agents/examples/tools/time_tool.pyi +15 -0
- aip_agents/examples/tools/weather_forecast_tool.py +38 -0
- aip_agents/examples/tools/weather_forecast_tool.pyi +14 -0
- aip_agents/executor/agent_executor.py +473 -0
- aip_agents/executor/base.py +48 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/__init__.pyi +6 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/__init__.pyi +4 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/base.pyi +61 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/nemo.pyi +46 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/exceptions.pyi +23 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/manager.pyi +42 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/middleware.pyi +87 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/schemas.pyi +43 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/guardrails/utils.pyi +19 -0
- aip_agents/mcp/__init__.py +1 -0
- aip_agents/mcp/__init__.pyi +0 -0
- aip_agents/mcp/client/__init__.py +14 -0
- aip_agents/mcp/client/__init__.pyi +5 -0
- aip_agents/mcp/client/base_mcp_client.py +369 -0
- aip_agents/mcp/client/base_mcp_client.pyi +148 -0
- aip_agents/mcp/client/connection_manager.py +228 -0
- aip_agents/mcp/client/connection_manager.pyi +51 -0
- aip_agents/mcp/client/google_adk/__init__.py +11 -0
- aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
- aip_agents/mcp/client/google_adk/client.py +381 -0
- aip_agents/mcp/client/google_adk/client.pyi +75 -0
- aip_agents/mcp/client/langchain/__init__.py +11 -0
- aip_agents/mcp/client/langchain/__init__.pyi +3 -0
- aip_agents/mcp/client/langchain/client.py +265 -0
- aip_agents/mcp/client/langchain/client.pyi +48 -0
- aip_agents/mcp/client/persistent_session.py +612 -0
- aip_agents/mcp/client/persistent_session.pyi +122 -0
- aip_agents/mcp/client/session_pool.py +351 -0
- aip_agents/mcp/client/session_pool.pyi +101 -0
- aip_agents/mcp/client/transports.py +263 -0
- aip_agents/mcp/client/transports.pyi +132 -0
- aip_agents/mcp/utils/__init__.py +7 -0
- aip_agents/mcp/utils/__init__.pyi +0 -0
- aip_agents/mcp/utils/config_validator.py +139 -0
- aip_agents/mcp/utils/config_validator.pyi +82 -0
- aip_agents/memory/__init__.py +14 -0
- aip_agents/memory/__init__.pyi +5 -0
- aip_agents/memory/adapters/__init__.py +10 -0
- aip_agents/memory/adapters/__init__.pyi +4 -0
- aip_agents/memory/adapters/base_adapter.py +811 -0
- aip_agents/memory/adapters/base_adapter.pyi +176 -0
- aip_agents/memory/adapters/mem0.py +84 -0
- aip_agents/memory/adapters/mem0.pyi +22 -0
- aip_agents/memory/base.py +84 -0
- aip_agents/memory/base.pyi +60 -0
- aip_agents/memory/constants.py +49 -0
- aip_agents/memory/constants.pyi +25 -0
- aip_agents/memory/factory.py +86 -0
- aip_agents/memory/factory.pyi +24 -0
- aip_agents/memory/guidance.py +20 -0
- aip_agents/memory/guidance.pyi +3 -0
- aip_agents/memory/simple_memory.py +47 -0
- aip_agents/memory/simple_memory.pyi +23 -0
- aip_agents/middleware/__init__.py +17 -0
- aip_agents/middleware/__init__.pyi +5 -0
- aip_agents/middleware/base.py +96 -0
- aip_agents/middleware/base.pyi +75 -0
- aip_agents/middleware/manager.py +150 -0
- aip_agents/middleware/manager.pyi +84 -0
- aip_agents/middleware/todolist.py +274 -0
- aip_agents/middleware/todolist.pyi +125 -0
- aip_agents/ptc/__init__.py +48 -0
- aip_agents/ptc/__init__.pyi +10 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +39 -0
- aip_agents/ptc/exceptions.pyi +22 -0
- aip_agents/ptc/executor.py +143 -0
- aip_agents/ptc/executor.pyi +73 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/__init__.pyi +7 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +668 -0
- aip_agents/ptc/mcp/sandbox_bridge.pyi +47 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/__init__.pyi +0 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +239 -0
- aip_agents/ptc/naming.py +184 -0
- aip_agents/ptc/naming.pyi +76 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +571 -0
- aip_agents/ptc/prompt_builder.pyi +55 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +58 -0
- aip_agents/ptc/sandbox_bridge.pyi +25 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/template_utils.pyi +13 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/__init__.pyi +0 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +9 -0
- aip_agents/sandbox/defaults.pyi +2 -0
- aip_agents/sandbox/e2b_runtime.py +267 -0
- aip_agents/sandbox/e2b_runtime.pyi +51 -0
- aip_agents/sandbox/template_builder.py +131 -0
- aip_agents/sandbox/template_builder.pyi +36 -0
- aip_agents/sandbox/types.py +24 -0
- aip_agents/sandbox/types.pyi +14 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/sandbox/validation.pyi +20 -0
- aip_agents/schema/__init__.py +69 -0
- aip_agents/schema/__init__.pyi +9 -0
- aip_agents/schema/a2a.py +56 -0
- aip_agents/schema/a2a.pyi +40 -0
- aip_agents/schema/agent.py +111 -0
- aip_agents/schema/agent.pyi +65 -0
- aip_agents/schema/hitl.py +157 -0
- aip_agents/schema/hitl.pyi +89 -0
- aip_agents/schema/langgraph.py +37 -0
- aip_agents/schema/langgraph.pyi +28 -0
- aip_agents/schema/model_id.py +97 -0
- aip_agents/schema/model_id.pyi +54 -0
- aip_agents/schema/step_limit.py +108 -0
- aip_agents/schema/step_limit.pyi +63 -0
- aip_agents/schema/storage.py +40 -0
- aip_agents/schema/storage.pyi +21 -0
- aip_agents/sentry/__init__.py +11 -0
- aip_agents/sentry/__init__.pyi +3 -0
- aip_agents/sentry/sentry.py +151 -0
- aip_agents/sentry/sentry.pyi +48 -0
- aip_agents/storage/__init__.py +41 -0
- aip_agents/storage/__init__.pyi +8 -0
- aip_agents/storage/base.py +85 -0
- aip_agents/storage/base.pyi +58 -0
- aip_agents/storage/clients/__init__.py +12 -0
- aip_agents/storage/clients/__init__.pyi +3 -0
- aip_agents/storage/clients/minio_client.py +318 -0
- aip_agents/storage/clients/minio_client.pyi +137 -0
- aip_agents/storage/config.py +62 -0
- aip_agents/storage/config.pyi +29 -0
- aip_agents/storage/providers/__init__.py +15 -0
- aip_agents/storage/providers/__init__.pyi +5 -0
- aip_agents/storage/providers/base.py +106 -0
- aip_agents/storage/providers/base.pyi +88 -0
- aip_agents/storage/providers/memory.py +114 -0
- aip_agents/storage/providers/memory.pyi +79 -0
- aip_agents/storage/providers/object_storage.py +214 -0
- aip_agents/storage/providers/object_storage.pyi +98 -0
- aip_agents/tools/__init__.py +64 -0
- aip_agents/tools/__init__.pyi +11 -0
- aip_agents/tools/browser_use/__init__.py +82 -0
- aip_agents/tools/browser_use/__init__.pyi +14 -0
- aip_agents/tools/browser_use/action_parser.py +103 -0
- aip_agents/tools/browser_use/action_parser.pyi +18 -0
- aip_agents/tools/browser_use/browser_use_tool.py +1120 -0
- aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
- aip_agents/tools/browser_use/llm_config.py +120 -0
- aip_agents/tools/browser_use/llm_config.pyi +52 -0
- aip_agents/tools/browser_use/minio_storage.py +198 -0
- aip_agents/tools/browser_use/minio_storage.pyi +109 -0
- aip_agents/tools/browser_use/schemas.py +119 -0
- aip_agents/tools/browser_use/schemas.pyi +32 -0
- aip_agents/tools/browser_use/session.py +76 -0
- aip_agents/tools/browser_use/session.pyi +4 -0
- aip_agents/tools/browser_use/session_errors.py +132 -0
- aip_agents/tools/browser_use/session_errors.pyi +53 -0
- aip_agents/tools/browser_use/steel_session_recording.py +317 -0
- aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
- aip_agents/tools/browser_use/streaming.py +815 -0
- aip_agents/tools/browser_use/streaming.pyi +81 -0
- aip_agents/tools/browser_use/structured_data_parser.py +257 -0
- aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
- aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
- aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
- aip_agents/tools/browser_use/types.py +78 -0
- aip_agents/tools/browser_use/types.pyi +45 -0
- aip_agents/tools/code_sandbox/__init__.py +26 -0
- aip_agents/tools/code_sandbox/__init__.pyi +3 -0
- aip_agents/tools/code_sandbox/constant.py +13 -0
- aip_agents/tools/code_sandbox/constant.pyi +4 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +306 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +102 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
- aip_agents/tools/constants.py +177 -0
- aip_agents/tools/constants.pyi +138 -0
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/date_range_tool.pyi +21 -0
- aip_agents/tools/document_loader/__init__.py +44 -0
- aip_agents/tools/document_loader/__init__.pyi +7 -0
- aip_agents/tools/document_loader/base_reader.py +302 -0
- aip_agents/tools/document_loader/base_reader.pyi +75 -0
- aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
- aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
- aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
- aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
- aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
- aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
- aip_agents/tools/document_loader/pdf_splitter.py +169 -0
- aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
- aip_agents/tools/execute_ptc_code.py +308 -0
- aip_agents/tools/execute_ptc_code.pyi +90 -0
- aip_agents/tools/gl_connector/__init__.py +5 -0
- aip_agents/tools/gl_connector/__init__.pyi +3 -0
- aip_agents/tools/gl_connector/tool.py +383 -0
- aip_agents/tools/gl_connector/tool.pyi +74 -0
- aip_agents/tools/gl_connector_tools.py +119 -0
- aip_agents/tools/gl_connector_tools.pyi +39 -0
- aip_agents/tools/memory_search/__init__.py +29 -0
- aip_agents/tools/memory_search/__init__.pyi +5 -0
- aip_agents/tools/memory_search/base.py +200 -0
- aip_agents/tools/memory_search/base.pyi +69 -0
- aip_agents/tools/memory_search/mem0.py +365 -0
- aip_agents/tools/memory_search/mem0.pyi +29 -0
- aip_agents/tools/memory_search/schema.py +81 -0
- aip_agents/tools/memory_search/schema.pyi +25 -0
- aip_agents/tools/memory_search_tool.py +34 -0
- aip_agents/tools/memory_search_tool.pyi +3 -0
- aip_agents/tools/time_tool.py +117 -0
- aip_agents/tools/time_tool.pyi +16 -0
- aip_agents/tools/tool_config_injector.py +300 -0
- aip_agents/tools/tool_config_injector.pyi +26 -0
- aip_agents/tools/web_search/__init__.py +15 -0
- aip_agents/tools/web_search/__init__.pyi +3 -0
- aip_agents/tools/web_search/serper_tool.py +187 -0
- aip_agents/tools/web_search/serper_tool.pyi +19 -0
- aip_agents/types/__init__.py +70 -0
- aip_agents/types/__init__.pyi +36 -0
- aip_agents/types/a2a_events.py +13 -0
- aip_agents/types/a2a_events.pyi +3 -0
- aip_agents/utils/__init__.py +79 -0
- aip_agents/utils/__init__.pyi +11 -0
- aip_agents/utils/a2a_connector.py +1757 -0
- aip_agents/utils/a2a_connector.pyi +146 -0
- aip_agents/utils/artifact_helpers.py +502 -0
- aip_agents/utils/artifact_helpers.pyi +203 -0
- aip_agents/utils/constants.py +22 -0
- aip_agents/utils/constants.pyi +10 -0
- aip_agents/utils/datetime/__init__.py +34 -0
- aip_agents/utils/datetime/__init__.pyi +4 -0
- aip_agents/utils/datetime/normalization.py +231 -0
- aip_agents/utils/datetime/normalization.pyi +95 -0
- aip_agents/utils/datetime/timezone.py +206 -0
- aip_agents/utils/datetime/timezone.pyi +48 -0
- aip_agents/utils/env_loader.py +27 -0
- aip_agents/utils/env_loader.pyi +10 -0
- aip_agents/utils/event_handler_registry.py +58 -0
- aip_agents/utils/event_handler_registry.pyi +23 -0
- aip_agents/utils/file_prompt_utils.py +176 -0
- aip_agents/utils/file_prompt_utils.pyi +21 -0
- aip_agents/utils/final_response_builder.py +211 -0
- aip_agents/utils/final_response_builder.pyi +34 -0
- aip_agents/utils/formatter_llm_client.py +231 -0
- aip_agents/utils/formatter_llm_client.pyi +71 -0
- aip_agents/utils/langgraph/__init__.py +19 -0
- aip_agents/utils/langgraph/__init__.pyi +3 -0
- aip_agents/utils/langgraph/converter.py +128 -0
- aip_agents/utils/langgraph/converter.pyi +49 -0
- aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
- aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1096 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
- aip_agents/utils/langgraph/tool_output_management.py +1047 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +329 -0
- aip_agents/utils/logger.py +195 -0
- aip_agents/utils/logger.pyi +60 -0
- aip_agents/utils/metadata/__init__.py +27 -0
- aip_agents/utils/metadata/__init__.pyi +5 -0
- aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
- aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
- aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
- aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
- aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
- aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
- aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
- aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
- aip_agents/utils/metadata/activity_narrative/context.py +49 -0
- aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
- aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
- aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
- aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
- aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
- aip_agents/utils/metadata/schemas/__init__.py +16 -0
- aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
- aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
- aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
- aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
- aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
- aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
- aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
- aip_agents/utils/metadata_helper.py +358 -0
- aip_agents/utils/metadata_helper.pyi +117 -0
- aip_agents/utils/name_preprocessor/__init__.py +17 -0
- aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
- aip_agents/utils/pii/__init__.py +25 -0
- aip_agents/utils/pii/__init__.pyi +5 -0
- aip_agents/utils/pii/pii_handler.py +397 -0
- aip_agents/utils/pii/pii_handler.pyi +96 -0
- aip_agents/utils/pii/pii_helper.py +207 -0
- aip_agents/utils/pii/pii_helper.pyi +78 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
- aip_agents/utils/reference_helper.py +273 -0
- aip_agents/utils/reference_helper.pyi +81 -0
- aip_agents/utils/sse_chunk_transformer.py +831 -0
- aip_agents/utils/sse_chunk_transformer.pyi +166 -0
- aip_agents/utils/step_limit_manager.py +265 -0
- aip_agents/utils/step_limit_manager.pyi +112 -0
- aip_agents/utils/token_usage_helper.py +156 -0
- aip_agents/utils/token_usage_helper.pyi +60 -0
- aip_agents_binary-0.6.4.dist-info/METADATA +673 -0
- aip_agents_binary-0.6.4.dist-info/RECORD +612 -0
- aip_agents_binary-0.6.4.dist-info/WHEEL +5 -0
- aip_agents_binary-0.6.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from aip_agents.a2a.types import Artifact as Artifact, ArtifactType as ArtifactType, MimeType as MimeType, get_mime_type_from_filename as get_mime_type_from_filename
|
|
2
|
+
from langgraph.types import Command
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
class ArtifactHandler:
|
|
6
|
+
"""Handler class for creating and managing artifacts in agent tools.
|
|
7
|
+
|
|
8
|
+
This class provides a clean, object-oriented interface for artifact creation
|
|
9
|
+
with built-in validation, deduplication, and standardized formatting.
|
|
10
|
+
"""
|
|
11
|
+
def __init__(self) -> None:
|
|
12
|
+
"""Initialize the ArtifactHandler."""
|
|
13
|
+
def create_file_artifact(self, result: str, artifact_data: bytes | str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None, enable_deduplication: bool = True) -> dict[str, Any]:
|
|
14
|
+
'''Deprecated. Use create_artifact instead.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
result (str): The message/result to show to the agent.
|
|
18
|
+
artifact_data (bytes | str): The binary data for the artifact.
|
|
19
|
+
artifact_name (str): The name for the artifact file.
|
|
20
|
+
artifact_description (str, optional): Description of the artifact. Defaults to "".
|
|
21
|
+
mime_type (str | None, optional): MIME type of the artifact. If None, will be auto-detected.
|
|
22
|
+
enable_deduplication (bool, optional): Whether to deduplicate by content hash. Defaults to True.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
dict[str, Any]: Dictionary with \'result\' and \'artifact\' keys.
|
|
26
|
+
'''
|
|
27
|
+
def create_text_artifact(self, result: str, artifact_text: str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None, enable_deduplication: bool = True) -> dict[str, Any]:
|
|
28
|
+
'''Deprecated. Use create_artifact instead.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
result (str): The message/result to show to the agent.
|
|
32
|
+
artifact_text (str): The text content for the artifact.
|
|
33
|
+
artifact_name (str): The name for the artifact file.
|
|
34
|
+
artifact_description (str, optional): Description of the artifact. Defaults to "".
|
|
35
|
+
mime_type (str | None, optional): MIME type of the artifact. If None, will be auto-detected.
|
|
36
|
+
enable_deduplication (bool, optional): Whether to deduplicate by content hash. Defaults to True.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
dict[str, Any]: Dictionary with \'result\' and \'artifact\' keys.
|
|
40
|
+
'''
|
|
41
|
+
def create_artifact(self, result: str, data: bytes | str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None, enable_deduplication: bool = True) -> dict[str, Any]:
|
|
42
|
+
"""Create an artifact with automatic text/binary handling.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
result: The message/result to show to the agent.
|
|
46
|
+
data: The data for the artifact. Bytes for binary; str for text or base64.
|
|
47
|
+
artifact_name: The filename to present to users.
|
|
48
|
+
artifact_description: Description of the artifact.
|
|
49
|
+
mime_type: Optional MIME type. If None, inferred from filename.
|
|
50
|
+
enable_deduplication: Whether to deduplicate by content hash.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Dictionary with 'result' and 'artifact' keys.
|
|
54
|
+
"""
|
|
55
|
+
def create_error_response(self, error_message: str) -> str:
|
|
56
|
+
"""Create a standardized error response for tools.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
error_message: The error message to return.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
String with error information.
|
|
63
|
+
"""
|
|
64
|
+
def clear_cache(self) -> None:
|
|
65
|
+
"""Clear the artifact cache."""
|
|
66
|
+
def get_cache_size(self) -> int:
|
|
67
|
+
"""Get the number of cached artifacts.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Number of artifacts in cache.
|
|
71
|
+
"""
|
|
72
|
+
@staticmethod
|
|
73
|
+
def generate_artifact_hash(artifact_data: str, name: str, mime_type: str) -> str:
|
|
74
|
+
"""Generate a hash for artifact deduplication.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
artifact_data: Base64 encoded artifact data.
|
|
78
|
+
name: Artifact name.
|
|
79
|
+
mime_type: MIME type.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Hash string for deduplication.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def create_artifact_response(result: str, artifact_data: bytes | str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None) -> dict[str, Any]:
|
|
86
|
+
'''Create a standardized artifact response for tools.
|
|
87
|
+
|
|
88
|
+
This function creates a response that separates the agent-facing result
|
|
89
|
+
from the user-facing artifact, following the established pattern for
|
|
90
|
+
artifact generation in the agent system.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
result: The message/result to show to the agent (clean, no file data).
|
|
94
|
+
artifact_data: The binary data or base64 string for the artifact.
|
|
95
|
+
artifact_name: The name for the artifact file.
|
|
96
|
+
artifact_description: Description of the artifact. Defaults to "".
|
|
97
|
+
mime_type: MIME type of the artifact. If None, will be auto-detected from filename.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Dictionary with \'result\' and \'artifacts\' keys (artifacts is always a list).
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
>>> import io
|
|
104
|
+
>>> csv_data = "Name,Age\\\\nAlice,30\\\\nBob,25"
|
|
105
|
+
>>> response = create_artifact_response(
|
|
106
|
+
... result="Generated a 2-row CSV table",
|
|
107
|
+
... artifact_data=csv_data.encode(\'utf-8\'),
|
|
108
|
+
... artifact_name="data.csv",
|
|
109
|
+
... artifact_description="Sample data table",
|
|
110
|
+
... mime_type="text/csv"
|
|
111
|
+
... )
|
|
112
|
+
>>> assert "result" in response
|
|
113
|
+
>>> assert "artifacts" in response
|
|
114
|
+
>>> assert isinstance(response["artifacts"], list)
|
|
115
|
+
'''
|
|
116
|
+
def create_text_artifact_response(result: str, artifact_text: str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None) -> dict[str, Any]:
|
|
117
|
+
"""Create a standardized artifact response for tools.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
result: The message/result to show to the agent.
|
|
121
|
+
artifact_text: The text content for the artifact.
|
|
122
|
+
artifact_name: The name for the artifact file.
|
|
123
|
+
artifact_description: Description of the artifact.
|
|
124
|
+
mime_type: MIME type of the artifact. If None, will be auto-detected from filename.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Dictionary with 'result' and 'artifacts' keys (artifacts is always a list).
|
|
128
|
+
"""
|
|
129
|
+
def create_multiple_artifacts_response(result: str, artifacts: list[dict[str, Any]]) -> dict[str, Any]:
|
|
130
|
+
"""Create a standardized response for multiple artifacts.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
result: The message/result to show to the agent.
|
|
134
|
+
artifacts: List of artifact dictionaries.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Dictionary with 'result' and 'artifacts' keys.
|
|
138
|
+
"""
|
|
139
|
+
def create_artifact_command(result: str, artifact_data: bytes | str, artifact_name: str, artifact_description: str = '', mime_type: str | None = None, metadata_update: dict[str, Any] | None = None) -> Command:
|
|
140
|
+
"""Create a Command that updates artifacts (and optional metadata).
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
result: Message/result to show to the agent (for ToolMessage content).
|
|
144
|
+
artifact_data: The binary data or base64 string for the artifact.
|
|
145
|
+
artifact_name: The name for the artifact file.
|
|
146
|
+
artifact_description: Description of the artifact.
|
|
147
|
+
mime_type: MIME type of the artifact. If None, auto-detected from filename.
|
|
148
|
+
metadata_update: Optional metadata delta to merge into state metadata.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Command: A LangGraph Command with update containing 'result', 'artifacts', and optional 'metadata'.
|
|
152
|
+
"""
|
|
153
|
+
def create_multiple_artifacts_command(result: str, artifacts: list[Artifact | dict[str, Any]] | None = None, metadata_update: dict[str, Any] | None = None) -> Command:
|
|
154
|
+
"""Create a Command that updates multiple artifacts (and optional metadata).
|
|
155
|
+
|
|
156
|
+
The 'artifacts' list accepts mixed item types:
|
|
157
|
+
- Artifact: a typed artifact model (preferred). Will be converted via model_dump().
|
|
158
|
+
- dict: a prebuilt artifact dict ready for A2A.
|
|
159
|
+
- DataSpec dict: raw spec to build an artifact with keys:
|
|
160
|
+
{'data': bytes|str, 'artifact_name': str, 'artifact_description'?: str, 'mime_type'?: str}
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
result: Message/result to show to the agent.
|
|
164
|
+
artifacts: List of items (Artifact | dict) to attach or build.
|
|
165
|
+
metadata_update: Optional metadata delta to merge into state metadata.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Command: A LangGraph Command with update containing 'result', 'artifacts', and optional 'metadata'.
|
|
169
|
+
"""
|
|
170
|
+
def create_error_response(error_message: str) -> str:
|
|
171
|
+
"""Create a standardized error response for tools.
|
|
172
|
+
|
|
173
|
+
For error cases, we return a simple string that will be passed directly
|
|
174
|
+
to the agent without any artifact processing.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
error_message: The error message to return.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
String with error information.
|
|
181
|
+
"""
|
|
182
|
+
def extract_artifacts_from_agent_response(result: Any) -> tuple[str, list[dict[str, Any]]]:
|
|
183
|
+
"""Extract artifacts from agent response for delegation tools.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
result: The result returned by the delegated agent.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Tuple of (text_response, artifacts_list) where:
|
|
190
|
+
- text_response: The text content for the agent
|
|
191
|
+
- artifacts_list: List of artifacts to be passed through
|
|
192
|
+
"""
|
|
193
|
+
def create_delegation_response_with_artifacts(result: str, artifacts: list[dict[str, Any]], agent_name: str = '') -> Command:
|
|
194
|
+
"""Create a delegation response that includes artifacts only when needed.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
result: The text result from the delegated agent.
|
|
198
|
+
artifacts: List of artifacts from the delegated agent (always a list).
|
|
199
|
+
agent_name: Name of the agent for prefixing the result.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Command containing 'result' and optional 'artifacts'.
|
|
203
|
+
"""
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Shared constants for AIP Agents.
|
|
2
|
+
|
|
3
|
+
This module defines commonly used constants across the agents library
|
|
4
|
+
to avoid duplication and maintain consistency.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
from uuid import UUID
|
|
12
|
+
|
|
13
|
+
__all__ = ["DefaultTimezone", "DEFAULT_PII_TAG_NAMESPACE"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DefaultTimezone(StrEnum):
|
|
17
|
+
"""Default timezone constants used across the application."""
|
|
18
|
+
|
|
19
|
+
JAKARTA = "Asia/Jakarta"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
DEFAULT_PII_TAG_NAMESPACE: UUID = UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
|
|
4
|
+
__all__ = ['DefaultTimezone', 'DEFAULT_PII_TAG_NAMESPACE']
|
|
5
|
+
|
|
6
|
+
class DefaultTimezone(StrEnum):
|
|
7
|
+
"""Default timezone constants used across the application."""
|
|
8
|
+
JAKARTA: str
|
|
9
|
+
|
|
10
|
+
DEFAULT_PII_TAG_NAMESPACE: UUID
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Datetime-related helper utilities.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for working with dates, times, and timezones
|
|
4
|
+
in a robust and consistent manner. It includes functions for normalizing
|
|
5
|
+
timestamp formats, validating date strings, and working with timezone-aware
|
|
6
|
+
datetimes.
|
|
7
|
+
|
|
8
|
+
The module is organized into the following submodules:
|
|
9
|
+
- normalization: Functions for normalizing and validating timestamp formats
|
|
10
|
+
- timezone: Functions for working with timezone-aware datetimes
|
|
11
|
+
|
|
12
|
+
All functions in this module are designed to be robust and handle edge cases
|
|
13
|
+
gracefully, making them suitable for production use.
|
|
14
|
+
|
|
15
|
+
Authors:
|
|
16
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from aip_agents.utils.datetime.normalization import (
|
|
20
|
+
format_created_updated_label,
|
|
21
|
+
is_valid_date_string,
|
|
22
|
+
next_day_iso,
|
|
23
|
+
normalize_timestamp_to_date,
|
|
24
|
+
)
|
|
25
|
+
from aip_agents.utils.datetime.timezone import ensure_utc_datetime, get_timezone_aware_now
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"normalize_timestamp_to_date",
|
|
29
|
+
"format_created_updated_label",
|
|
30
|
+
"is_valid_date_string",
|
|
31
|
+
"next_day_iso",
|
|
32
|
+
"ensure_utc_datetime",
|
|
33
|
+
"get_timezone_aware_now",
|
|
34
|
+
]
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
from aip_agents.utils.datetime.normalization import format_created_updated_label as format_created_updated_label, is_valid_date_string as is_valid_date_string, next_day_iso as next_day_iso, normalize_timestamp_to_date as normalize_timestamp_to_date
|
|
2
|
+
from aip_agents.utils.datetime.timezone import ensure_utc_datetime as ensure_utc_datetime, get_timezone_aware_now as get_timezone_aware_now
|
|
3
|
+
|
|
4
|
+
__all__ = ['normalize_timestamp_to_date', 'format_created_updated_label', 'is_valid_date_string', 'next_day_iso', 'ensure_utc_datetime', 'get_timezone_aware_now']
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""Timestamp normalization helpers.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
from typing import Any, Final
|
|
11
|
+
|
|
12
|
+
from aip_agents.utils.logger import get_logger
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"normalize_timestamp_to_date",
|
|
16
|
+
"format_created_updated_label",
|
|
17
|
+
"is_valid_date_string",
|
|
18
|
+
"next_day_iso",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
logger: Final = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
DEFAULT_DATE_FORMAT: Final[str] = "%Y-%m-%d"
|
|
25
|
+
DATETIME_FORMAT: Final[str] = "%Y-%m-%d %H:%M:%S"
|
|
26
|
+
ISO_FORMATS: Final[list[str | None]] = [
|
|
27
|
+
None, # ISO format
|
|
28
|
+
"%Y-%m-%d %H:%M:%S",
|
|
29
|
+
"%Y-%m-%d",
|
|
30
|
+
"%Y-%m-%dT%H:%M:%S",
|
|
31
|
+
"%Y-%m-%dT%H:%M:%S%z",
|
|
32
|
+
"%Y-%m-%dT%H:%M:%S.%f",
|
|
33
|
+
"%Y-%m-%dT%H:%M:%S.%f%z",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def normalize_timestamp_to_date(value: Any) -> str | None:
|
|
38
|
+
"""Normalize various timestamp representations into a YYYY-MM-DD string.
|
|
39
|
+
|
|
40
|
+
This function handles multiple input types and formats, converting them to
|
|
41
|
+
a standardized ISO date string. It gracefully handles invalid inputs by
|
|
42
|
+
returning None or the string representation.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
value: The timestamp value to normalize. Can be:
|
|
46
|
+
- None or empty string: Returns None
|
|
47
|
+
- int/float: Unix timestamp (seconds since epoch)
|
|
48
|
+
- str: ISO format, datetime string, or other string representation
|
|
49
|
+
- Other types: Converted to string representation
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
str | None: A YYYY-MM-DD formatted date string, or None if the input
|
|
53
|
+
cannot be parsed as a valid date.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If the timestamp value is invalid (e.g., negative timestamp).
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
>>> normalize_timestamp_to_date(1640995200) # Unix timestamp
|
|
60
|
+
'2022-01-01'
|
|
61
|
+
>>> normalize_timestamp_to_date("2022-01-01T12:00:00")
|
|
62
|
+
'2022-01-01'
|
|
63
|
+
>>> normalize_timestamp_to_date("invalid")
|
|
64
|
+
'invalid'
|
|
65
|
+
>>> normalize_timestamp_to_date(None)
|
|
66
|
+
None
|
|
67
|
+
"""
|
|
68
|
+
# Handle None and empty values
|
|
69
|
+
if value in (None, ""):
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
if isinstance(value, int | float):
|
|
73
|
+
return _normalize_numeric_timestamp(value)
|
|
74
|
+
elif isinstance(value, str):
|
|
75
|
+
return _normalize_string_timestamp(value)
|
|
76
|
+
else:
|
|
77
|
+
# For any other type, convert to string
|
|
78
|
+
return str(value)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _normalize_numeric_timestamp(value: int | float) -> str | None:
|
|
82
|
+
"""Normalize numeric timestamp to ISO date string.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
value: Numeric timestamp (seconds since epoch).
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
ISO date string or None if invalid.
|
|
89
|
+
|
|
90
|
+
Raises:
|
|
91
|
+
ValueError: If timestamp is negative.
|
|
92
|
+
"""
|
|
93
|
+
try:
|
|
94
|
+
if value < 0:
|
|
95
|
+
raise ValueError(f"Negative timestamp value: {value}")
|
|
96
|
+
return datetime.fromtimestamp(value).date().isoformat()
|
|
97
|
+
except (OSError, OverflowError, ValueError):
|
|
98
|
+
logger.warning(f"Invalid timestamp value: {value}")
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _normalize_string_timestamp(ts: str) -> str | None:
|
|
103
|
+
"""Normalize string timestamp to ISO date string.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
ts: String timestamp in various formats.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
ISO date string, original string if unparseable, or None if empty.
|
|
110
|
+
"""
|
|
111
|
+
ts = ts.strip()
|
|
112
|
+
if not ts:
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
# Handle ISO format with timezone
|
|
116
|
+
iso_candidate = ts.replace("Z", "+00:00") if ts.endswith("Z") else ts
|
|
117
|
+
|
|
118
|
+
# Try different parsing strategies
|
|
119
|
+
for fmt in ISO_FORMATS:
|
|
120
|
+
try:
|
|
121
|
+
if fmt is None:
|
|
122
|
+
dt = datetime.fromisoformat(iso_candidate)
|
|
123
|
+
else:
|
|
124
|
+
dt = datetime.strptime(ts, fmt)
|
|
125
|
+
return dt.date().isoformat()
|
|
126
|
+
except ValueError:
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
# If no format worked, return the original string
|
|
130
|
+
# This preserves the original behavior for unparseable strings
|
|
131
|
+
return ts
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def format_created_updated_label(created_at: Any | None, updated_at: Any | None) -> str | None:
|
|
135
|
+
"""Build a compact label combining created/updated timestamps when available.
|
|
136
|
+
|
|
137
|
+
Creates a human-readable label that shows creation and update timestamps
|
|
138
|
+
in a compact format. If both dates are the same, only shows one date.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
created_at: The creation timestamp (any format supported by normalize_timestamp_to_date).
|
|
142
|
+
updated_at: The update timestamp (any format supported by normalize_timestamp_to_date).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
str | None: A formatted label string, or None if both inputs are invalid/empty.
|
|
146
|
+
Examples: "2022-01-01", "2022-01-01 (updated 2022-01-02)", "updated 2022-01-01"
|
|
147
|
+
|
|
148
|
+
Examples:
|
|
149
|
+
>>> format_created_updated_label("2022-01-01", "2022-01-02")
|
|
150
|
+
'2022-01-01 (updated 2022-01-02)'
|
|
151
|
+
>>> format_created_updated_label("2022-01-01", "2022-01-01")
|
|
152
|
+
'2022-01-01'
|
|
153
|
+
>>> format_created_updated_label(None, "2022-01-01")
|
|
154
|
+
'updated 2022-01-01'
|
|
155
|
+
>>> format_created_updated_label("2022-01-01", None)
|
|
156
|
+
'2022-01-01'
|
|
157
|
+
"""
|
|
158
|
+
created = normalize_timestamp_to_date(created_at)
|
|
159
|
+
updated = normalize_timestamp_to_date(updated_at)
|
|
160
|
+
|
|
161
|
+
if created and updated:
|
|
162
|
+
if created == updated:
|
|
163
|
+
return created
|
|
164
|
+
return f"{created} (updated {updated})"
|
|
165
|
+
if created:
|
|
166
|
+
return created
|
|
167
|
+
if updated:
|
|
168
|
+
return f"updated {updated}"
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def is_valid_date_string(date_str: str, fmt: str = DEFAULT_DATE_FORMAT) -> bool:
|
|
173
|
+
"""Validate that a date string matches the provided strftime format.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
date_str: The date string to validate. Must be a non-empty string.
|
|
177
|
+
fmt: The strftime format pattern to validate against.
|
|
178
|
+
Defaults to YYYY-MM-DD format.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
bool: True if the date string matches the format, False otherwise.
|
|
182
|
+
|
|
183
|
+
Raises:
|
|
184
|
+
ValueError: If the format string is empty or invalid, or if date_str is not a string.
|
|
185
|
+
|
|
186
|
+
Examples:
|
|
187
|
+
>>> is_valid_date_string("2022-01-01")
|
|
188
|
+
True
|
|
189
|
+
>>> is_valid_date_string("2022-13-01")
|
|
190
|
+
False
|
|
191
|
+
>>> is_valid_date_string("01-01-2022", "%m-%d-%Y")
|
|
192
|
+
True
|
|
193
|
+
>>> is_valid_date_string("", "%Y-%m-%d")
|
|
194
|
+
False
|
|
195
|
+
"""
|
|
196
|
+
if not isinstance(date_str, str):
|
|
197
|
+
raise ValueError(f"date_str must be a string, got {type(date_str).__name__}")
|
|
198
|
+
|
|
199
|
+
if not fmt or not fmt.strip():
|
|
200
|
+
raise ValueError("Format string cannot be empty")
|
|
201
|
+
|
|
202
|
+
if not date_str or not date_str.strip():
|
|
203
|
+
return False
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
datetime.strptime(date_str.strip(), fmt)
|
|
207
|
+
return True
|
|
208
|
+
except (ValueError, TypeError) as e:
|
|
209
|
+
logger.debug(f"Date string '{date_str}' does not match format '{fmt}': {e}")
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def next_day_iso(date_str: str) -> str:
|
|
214
|
+
"""Return the ISO date string for the day after the given ``YYYY-MM-DD`` date.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
date_str: A date string in ``YYYY-MM-DD`` format.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
str: The next day's date in ``YYYY-MM-DD`` format.
|
|
221
|
+
|
|
222
|
+
Raises:
|
|
223
|
+
ValueError: If ``date_str`` is not a valid ``YYYY-MM-DD`` date string.
|
|
224
|
+
"""
|
|
225
|
+
try:
|
|
226
|
+
pivot = datetime.strptime(date_str.strip(), "%Y-%m-%d")
|
|
227
|
+
except ValueError as exc:
|
|
228
|
+
raise ValueError(f"Invalid date string '{date_str}'. Expected YYYY-MM-DD.") from exc
|
|
229
|
+
|
|
230
|
+
next_day = pivot + timedelta(days=1)
|
|
231
|
+
return next_day.date().isoformat()
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
__all__ = ['normalize_timestamp_to_date', 'format_created_updated_label', 'is_valid_date_string', 'next_day_iso']
|
|
4
|
+
|
|
5
|
+
def normalize_timestamp_to_date(value: Any) -> str | None:
|
|
6
|
+
'''Normalize various timestamp representations into a YYYY-MM-DD string.
|
|
7
|
+
|
|
8
|
+
This function handles multiple input types and formats, converting them to
|
|
9
|
+
a standardized ISO date string. It gracefully handles invalid inputs by
|
|
10
|
+
returning None or the string representation.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
value: The timestamp value to normalize. Can be:
|
|
14
|
+
- None or empty string: Returns None
|
|
15
|
+
- int/float: Unix timestamp (seconds since epoch)
|
|
16
|
+
- str: ISO format, datetime string, or other string representation
|
|
17
|
+
- Other types: Converted to string representation
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
str | None: A YYYY-MM-DD formatted date string, or None if the input
|
|
21
|
+
cannot be parsed as a valid date.
|
|
22
|
+
|
|
23
|
+
Raises:
|
|
24
|
+
ValueError: If the timestamp value is invalid (e.g., negative timestamp).
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
>>> normalize_timestamp_to_date(1640995200) # Unix timestamp
|
|
28
|
+
\'2022-01-01\'
|
|
29
|
+
>>> normalize_timestamp_to_date("2022-01-01T12:00:00")
|
|
30
|
+
\'2022-01-01\'
|
|
31
|
+
>>> normalize_timestamp_to_date("invalid")
|
|
32
|
+
\'invalid\'
|
|
33
|
+
>>> normalize_timestamp_to_date(None)
|
|
34
|
+
None
|
|
35
|
+
'''
|
|
36
|
+
def format_created_updated_label(created_at: Any | None, updated_at: Any | None) -> str | None:
|
|
37
|
+
'''Build a compact label combining created/updated timestamps when available.
|
|
38
|
+
|
|
39
|
+
Creates a human-readable label that shows creation and update timestamps
|
|
40
|
+
in a compact format. If both dates are the same, only shows one date.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
created_at: The creation timestamp (any format supported by normalize_timestamp_to_date).
|
|
44
|
+
updated_at: The update timestamp (any format supported by normalize_timestamp_to_date).
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
str | None: A formatted label string, or None if both inputs are invalid/empty.
|
|
48
|
+
Examples: "2022-01-01", "2022-01-01 (updated 2022-01-02)", "updated 2022-01-01"
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
>>> format_created_updated_label("2022-01-01", "2022-01-02")
|
|
52
|
+
\'2022-01-01 (updated 2022-01-02)\'
|
|
53
|
+
>>> format_created_updated_label("2022-01-01", "2022-01-01")
|
|
54
|
+
\'2022-01-01\'
|
|
55
|
+
>>> format_created_updated_label(None, "2022-01-01")
|
|
56
|
+
\'updated 2022-01-01\'
|
|
57
|
+
>>> format_created_updated_label("2022-01-01", None)
|
|
58
|
+
\'2022-01-01\'
|
|
59
|
+
'''
|
|
60
|
+
def is_valid_date_string(date_str: str, fmt: str = ...) -> bool:
|
|
61
|
+
'''Validate that a date string matches the provided strftime format.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
date_str: The date string to validate. Must be a non-empty string.
|
|
65
|
+
fmt: The strftime format pattern to validate against.
|
|
66
|
+
Defaults to YYYY-MM-DD format.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
bool: True if the date string matches the format, False otherwise.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
ValueError: If the format string is empty or invalid, or if date_str is not a string.
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
>>> is_valid_date_string("2022-01-01")
|
|
76
|
+
True
|
|
77
|
+
>>> is_valid_date_string("2022-13-01")
|
|
78
|
+
False
|
|
79
|
+
>>> is_valid_date_string("01-01-2022", "%m-%d-%Y")
|
|
80
|
+
True
|
|
81
|
+
>>> is_valid_date_string("", "%Y-%m-%d")
|
|
82
|
+
False
|
|
83
|
+
'''
|
|
84
|
+
def next_day_iso(date_str: str) -> str:
|
|
85
|
+
"""Return the ISO date string for the day after the given ``YYYY-MM-DD`` date.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
date_str: A date string in ``YYYY-MM-DD`` format.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
str: The next day's date in ``YYYY-MM-DD`` format.
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
ValueError: If ``date_str`` is not a valid ``YYYY-MM-DD`` date string.
|
|
95
|
+
"""
|