botrun-flow-lang 5.12.263__py3-none-any.whl → 6.2.21__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 (89) hide show
  1. botrun_flow_lang/api/auth_api.py +39 -39
  2. botrun_flow_lang/api/auth_utils.py +183 -183
  3. botrun_flow_lang/api/botrun_back_api.py +65 -65
  4. botrun_flow_lang/api/flow_api.py +3 -3
  5. botrun_flow_lang/api/hatch_api.py +508 -508
  6. botrun_flow_lang/api/langgraph_api.py +816 -811
  7. botrun_flow_lang/api/langgraph_constants.py +11 -0
  8. botrun_flow_lang/api/line_bot_api.py +1484 -1484
  9. botrun_flow_lang/api/model_api.py +300 -300
  10. botrun_flow_lang/api/rate_limit_api.py +32 -32
  11. botrun_flow_lang/api/routes.py +79 -79
  12. botrun_flow_lang/api/search_api.py +53 -53
  13. botrun_flow_lang/api/storage_api.py +395 -395
  14. botrun_flow_lang/api/subsidy_api.py +290 -290
  15. botrun_flow_lang/api/subsidy_api_system_prompt.txt +109 -109
  16. botrun_flow_lang/api/user_setting_api.py +70 -70
  17. botrun_flow_lang/api/version_api.py +31 -31
  18. botrun_flow_lang/api/youtube_api.py +26 -26
  19. botrun_flow_lang/constants.py +13 -13
  20. botrun_flow_lang/langgraph_agents/agents/agent_runner.py +178 -178
  21. botrun_flow_lang/langgraph_agents/agents/agent_tools/step_planner.py +77 -77
  22. botrun_flow_lang/langgraph_agents/agents/checkpointer/firestore_checkpointer.py +666 -666
  23. botrun_flow_lang/langgraph_agents/agents/gov_researcher/GOV_RESEARCHER_PRD.md +192 -192
  24. botrun_flow_lang/langgraph_agents/agents/gov_researcher/gemini_subsidy_graph.py +460 -460
  25. botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_2_graph.py +1002 -1002
  26. botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_graph.py +822 -822
  27. botrun_flow_lang/langgraph_agents/agents/langgraph_react_agent.py +730 -723
  28. botrun_flow_lang/langgraph_agents/agents/search_agent_graph.py +864 -864
  29. botrun_flow_lang/langgraph_agents/agents/tools/__init__.py +4 -4
  30. botrun_flow_lang/langgraph_agents/agents/tools/gemini_code_execution.py +376 -376
  31. botrun_flow_lang/langgraph_agents/agents/util/gemini_grounding.py +66 -66
  32. botrun_flow_lang/langgraph_agents/agents/util/html_util.py +316 -316
  33. botrun_flow_lang/langgraph_agents/agents/util/img_util.py +336 -294
  34. botrun_flow_lang/langgraph_agents/agents/util/local_files.py +419 -419
  35. botrun_flow_lang/langgraph_agents/agents/util/mermaid_util.py +86 -86
  36. botrun_flow_lang/langgraph_agents/agents/util/model_utils.py +143 -143
  37. botrun_flow_lang/langgraph_agents/agents/util/pdf_analyzer.py +562 -486
  38. botrun_flow_lang/langgraph_agents/agents/util/pdf_cache.py +250 -250
  39. botrun_flow_lang/langgraph_agents/agents/util/pdf_processor.py +204 -204
  40. botrun_flow_lang/langgraph_agents/agents/util/perplexity_search.py +464 -464
  41. botrun_flow_lang/langgraph_agents/agents/util/plotly_util.py +59 -59
  42. botrun_flow_lang/langgraph_agents/agents/util/tavily_search.py +199 -199
  43. botrun_flow_lang/langgraph_agents/agents/util/usage_metadata.py +34 -0
  44. botrun_flow_lang/langgraph_agents/agents/util/youtube_util.py +90 -90
  45. botrun_flow_lang/langgraph_agents/cache/langgraph_botrun_cache.py +197 -197
  46. botrun_flow_lang/llm_agent/llm_agent.py +19 -19
  47. botrun_flow_lang/llm_agent/llm_agent_util.py +83 -83
  48. botrun_flow_lang/log/.gitignore +2 -2
  49. botrun_flow_lang/main.py +61 -61
  50. botrun_flow_lang/main_fast.py +51 -51
  51. botrun_flow_lang/mcp_server/__init__.py +10 -10
  52. botrun_flow_lang/mcp_server/default_mcp.py +854 -744
  53. botrun_flow_lang/models/nodes/utils.py +205 -205
  54. botrun_flow_lang/models/token_usage.py +34 -34
  55. botrun_flow_lang/requirements.txt +21 -21
  56. botrun_flow_lang/services/base/firestore_base.py +30 -30
  57. botrun_flow_lang/services/hatch/hatch_factory.py +11 -11
  58. botrun_flow_lang/services/hatch/hatch_fs_store.py +419 -419
  59. botrun_flow_lang/services/storage/storage_cs_store.py +206 -206
  60. botrun_flow_lang/services/storage/storage_factory.py +12 -12
  61. botrun_flow_lang/services/storage/storage_store.py +65 -65
  62. botrun_flow_lang/services/user_setting/user_setting_factory.py +9 -9
  63. botrun_flow_lang/services/user_setting/user_setting_fs_store.py +66 -66
  64. botrun_flow_lang/static/docs/tools/index.html +926 -926
  65. botrun_flow_lang/tests/api_functional_tests.py +1525 -1525
  66. botrun_flow_lang/tests/api_stress_test.py +357 -357
  67. botrun_flow_lang/tests/shared_hatch_tests.py +333 -333
  68. botrun_flow_lang/tests/test_botrun_app.py +46 -46
  69. botrun_flow_lang/tests/test_html_util.py +31 -31
  70. botrun_flow_lang/tests/test_img_analyzer.py +190 -190
  71. botrun_flow_lang/tests/test_img_util.py +39 -39
  72. botrun_flow_lang/tests/test_local_files.py +114 -114
  73. botrun_flow_lang/tests/test_mermaid_util.py +103 -103
  74. botrun_flow_lang/tests/test_pdf_analyzer.py +104 -104
  75. botrun_flow_lang/tests/test_plotly_util.py +151 -151
  76. botrun_flow_lang/tests/test_run_workflow_engine.py +65 -65
  77. botrun_flow_lang/tools/generate_docs.py +133 -133
  78. botrun_flow_lang/tools/templates/tools.html +153 -153
  79. botrun_flow_lang/utils/__init__.py +7 -7
  80. botrun_flow_lang/utils/botrun_logger.py +344 -344
  81. botrun_flow_lang/utils/clients/rate_limit_client.py +209 -209
  82. botrun_flow_lang/utils/clients/token_verify_client.py +153 -153
  83. botrun_flow_lang/utils/google_drive_utils.py +654 -654
  84. botrun_flow_lang/utils/langchain_utils.py +324 -324
  85. botrun_flow_lang/utils/yaml_utils.py +9 -9
  86. {botrun_flow_lang-5.12.263.dist-info → botrun_flow_lang-6.2.21.dist-info}/METADATA +6 -6
  87. botrun_flow_lang-6.2.21.dist-info/RECORD +104 -0
  88. botrun_flow_lang-5.12.263.dist-info/RECORD +0 -102
  89. {botrun_flow_lang-5.12.263.dist-info → botrun_flow_lang-6.2.21.dist-info}/WHEEL +0 -0
@@ -1,153 +1,153 @@
1
- import os
2
- import aiohttp
3
- from typing import Dict, Any, Optional
4
- import json
5
-
6
- # Import necessary libraries for IAP authentication
7
- from google.auth.transport.requests import Request
8
- from google.oauth2 import service_account
9
-
10
-
11
- class TokenVerifyClient:
12
- """Client for interacting with Botrun token verification API."""
13
-
14
- def __init__(self, api_base: Optional[str] = None):
15
- """
16
- Initialize the token verify client.
17
-
18
- Args:
19
- api_base: Base URL for the Botrun API. If None, will use BOTRUN_BACK_API_BASE env var.
20
- """
21
- if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
22
- return
23
- self.api_base = api_base or os.getenv("BOTRUN_BACK_API_BASE")
24
- if not self.api_base:
25
- raise ValueError("BOTRUN_BACK_API_BASE environment variable not set")
26
-
27
- # Get IAP configuration from environment variables
28
- self.iap_client_id = os.getenv("IAP_CLIENT_ID")
29
- self.iap_service_account_key_file = os.getenv("IAP_SERVICE_ACCOUNT_KEY_FILE")
30
-
31
- from botrun_flow_lang.utils.botrun_logger import get_default_botrun_logger
32
-
33
- self.logger = get_default_botrun_logger()
34
-
35
- def _get_iap_jwt(self) -> str:
36
- """
37
- Generate a JWT token for IAP authentication.
38
-
39
- Returns:
40
- JWT token as string
41
-
42
- Raises:
43
- ValueError: If the service account file can't be read or token generation fails
44
- """
45
- try:
46
- credentials = service_account.IDTokenCredentials.from_service_account_file(
47
- self.iap_service_account_key_file,
48
- target_audience=self.iap_client_id,
49
- )
50
- credentials.refresh(Request())
51
- return credentials.token
52
- except Exception as e:
53
- raise ValueError(f"Error generating IAP JWT token: {str(e)}")
54
-
55
- async def _make_iap_request(self, url: str, data: Dict[str, str]) -> Dict[Any, Any]:
56
- """
57
- Make an authenticated POST request to an IAP-protected endpoint.
58
-
59
- Args:
60
- url: The URL to request
61
- data: Form data to send in the request body
62
-
63
- Returns:
64
- JSON response as dictionary
65
-
66
- Raises:
67
- ValueError: If the request fails
68
- """
69
- try:
70
- token = self._get_iap_jwt()
71
- headers = {"Authorization": f"Bearer {token}"}
72
-
73
- async with aiohttp.ClientSession() as session:
74
- async with session.post(url, headers=headers, data=data) as response:
75
- response.raise_for_status()
76
- return await response.json()
77
- except aiohttp.ClientResponseError as e:
78
- raise ValueError(f"IAP API error: {e.status} - {e.message}")
79
- except Exception as e:
80
- raise ValueError(f"Error making IAP request: {str(e)}")
81
-
82
- async def verify_token(self, access_token: str) -> Dict[Any, Any]:
83
- """
84
- Verify access token via the Botrun backend API.
85
-
86
- Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
87
- environment variables are set, otherwise falls back to standard authentication.
88
-
89
- Args:
90
- access_token: The access token to verify
91
-
92
- Returns:
93
- Dictionary containing verification result:
94
- {
95
- "is_success": true,
96
- "username": "user@example.com"
97
- }
98
-
99
- Raises:
100
- ValueError: If the API call fails or token is invalid
101
- """
102
- self.logger.info(
103
- f"verify_token called with token length: {len(access_token) if access_token else 0}"
104
- )
105
-
106
- if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
107
- self.logger.info(
108
- "BOTRUN_BACK_API_BASE is not set, return default verification"
109
- )
110
- return {
111
- "is_success": False,
112
- "message": "Token verification service not configured",
113
- }
114
-
115
- url = f"{self.api_base}/botrun/token_verify"
116
- data = {"access_token": access_token}
117
- self.logger.info(f"Token verify URL: {url}")
118
-
119
- # Use IAP authentication if both required environment variables are set
120
- if self.iap_client_id and self.iap_service_account_key_file:
121
- self.logger.info("IAP authentication is used")
122
- return await self._make_iap_request(url, data)
123
-
124
- # Otherwise, use standard authentication
125
- async with aiohttp.ClientSession() as session:
126
- try:
127
- async with session.post(url, data=data) as response:
128
- response.raise_for_status()
129
- self.logger.info(
130
- f"Token verification response status: {response.status}"
131
- )
132
- text = await response.text()
133
- self.logger.info(f"Token verification response: {text}")
134
- return json.loads(text)
135
- except aiohttp.ClientResponseError as e:
136
- self.logger.error(
137
- f"API error: {e.status} - {e.message}",
138
- error=str(e),
139
- exc_info=True,
140
- )
141
- if e.status == 401:
142
- raise ValueError(f"Invalid access token")
143
- elif e.status == 400:
144
- raise ValueError(f"Bad request: missing or invalid token format")
145
- else:
146
- raise ValueError(f"API error: {e.status} - {e.message}")
147
- except Exception as e:
148
- self.logger.error(
149
- f"Error verifying token: {str(e)}",
150
- error=str(e),
151
- exc_info=True,
152
- )
153
- raise ValueError(f"Error verifying token: {str(e)}")
1
+ import os
2
+ import aiohttp
3
+ from typing import Dict, Any, Optional
4
+ import json
5
+
6
+ # Import necessary libraries for IAP authentication
7
+ from google.auth.transport.requests import Request
8
+ from google.oauth2 import service_account
9
+
10
+
11
+ class TokenVerifyClient:
12
+ """Client for interacting with Botrun token verification API."""
13
+
14
+ def __init__(self, api_base: Optional[str] = None):
15
+ """
16
+ Initialize the token verify client.
17
+
18
+ Args:
19
+ api_base: Base URL for the Botrun API. If None, will use BOTRUN_BACK_API_BASE env var.
20
+ """
21
+ if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
22
+ return
23
+ self.api_base = api_base or os.getenv("BOTRUN_BACK_API_BASE")
24
+ if not self.api_base:
25
+ raise ValueError("BOTRUN_BACK_API_BASE environment variable not set")
26
+
27
+ # Get IAP configuration from environment variables
28
+ self.iap_client_id = os.getenv("IAP_CLIENT_ID")
29
+ self.iap_service_account_key_file = os.getenv("IAP_SERVICE_ACCOUNT_KEY_FILE")
30
+
31
+ from botrun_flow_lang.utils.botrun_logger import get_default_botrun_logger
32
+
33
+ self.logger = get_default_botrun_logger()
34
+
35
+ def _get_iap_jwt(self) -> str:
36
+ """
37
+ Generate a JWT token for IAP authentication.
38
+
39
+ Returns:
40
+ JWT token as string
41
+
42
+ Raises:
43
+ ValueError: If the service account file can't be read or token generation fails
44
+ """
45
+ try:
46
+ credentials = service_account.IDTokenCredentials.from_service_account_file(
47
+ self.iap_service_account_key_file,
48
+ target_audience=self.iap_client_id,
49
+ )
50
+ credentials.refresh(Request())
51
+ return credentials.token
52
+ except Exception as e:
53
+ raise ValueError(f"Error generating IAP JWT token: {str(e)}")
54
+
55
+ async def _make_iap_request(self, url: str, data: Dict[str, str]) -> Dict[Any, Any]:
56
+ """
57
+ Make an authenticated POST request to an IAP-protected endpoint.
58
+
59
+ Args:
60
+ url: The URL to request
61
+ data: Form data to send in the request body
62
+
63
+ Returns:
64
+ JSON response as dictionary
65
+
66
+ Raises:
67
+ ValueError: If the request fails
68
+ """
69
+ try:
70
+ token = self._get_iap_jwt()
71
+ headers = {"Authorization": f"Bearer {token}"}
72
+
73
+ async with aiohttp.ClientSession() as session:
74
+ async with session.post(url, headers=headers, data=data) as response:
75
+ response.raise_for_status()
76
+ return await response.json()
77
+ except aiohttp.ClientResponseError as e:
78
+ raise ValueError(f"IAP API error: {e.status} - {e.message}")
79
+ except Exception as e:
80
+ raise ValueError(f"Error making IAP request: {str(e)}")
81
+
82
+ async def verify_token(self, access_token: str) -> Dict[Any, Any]:
83
+ """
84
+ Verify access token via the Botrun backend API.
85
+
86
+ Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
87
+ environment variables are set, otherwise falls back to standard authentication.
88
+
89
+ Args:
90
+ access_token: The access token to verify
91
+
92
+ Returns:
93
+ Dictionary containing verification result:
94
+ {
95
+ "is_success": true,
96
+ "username": "user@example.com"
97
+ }
98
+
99
+ Raises:
100
+ ValueError: If the API call fails or token is invalid
101
+ """
102
+ self.logger.info(
103
+ f"verify_token called with token length: {len(access_token) if access_token else 0}"
104
+ )
105
+
106
+ if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
107
+ self.logger.info(
108
+ "BOTRUN_BACK_API_BASE is not set, return default verification"
109
+ )
110
+ return {
111
+ "is_success": False,
112
+ "message": "Token verification service not configured",
113
+ }
114
+
115
+ url = f"{self.api_base}/botrun/token_verify"
116
+ data = {"access_token": access_token}
117
+ self.logger.info(f"Token verify URL: {url}")
118
+
119
+ # Use IAP authentication if both required environment variables are set
120
+ if self.iap_client_id and self.iap_service_account_key_file:
121
+ self.logger.info("IAP authentication is used")
122
+ return await self._make_iap_request(url, data)
123
+
124
+ # Otherwise, use standard authentication
125
+ async with aiohttp.ClientSession() as session:
126
+ try:
127
+ async with session.post(url, data=data) as response:
128
+ response.raise_for_status()
129
+ self.logger.info(
130
+ f"Token verification response status: {response.status}"
131
+ )
132
+ text = await response.text()
133
+ self.logger.info(f"Token verification response: {text}")
134
+ return json.loads(text)
135
+ except aiohttp.ClientResponseError as e:
136
+ self.logger.error(
137
+ f"API error: {e.status} - {e.message}",
138
+ error=str(e),
139
+ exc_info=True,
140
+ )
141
+ if e.status == 401:
142
+ raise ValueError(f"Invalid access token")
143
+ elif e.status == 400:
144
+ raise ValueError(f"Bad request: missing or invalid token format")
145
+ else:
146
+ raise ValueError(f"API error: {e.status} - {e.message}")
147
+ except Exception as e:
148
+ self.logger.error(
149
+ f"Error verifying token: {str(e)}",
150
+ error=str(e),
151
+ exc_info=True,
152
+ )
153
+ raise ValueError(f"Error verifying token: {str(e)}")