botrun-flow-lang 5.10.32__py3-none-any.whl → 5.10.83__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.
@@ -155,8 +155,8 @@ DEFAULT_SUPPORTED_MODELS = [
155
155
  provider="gemini",
156
156
  ),
157
157
  ModelInfo(
158
- display_name="claude-sonnet-4-20250514",
159
- model_name="claude-sonnet-4-20250514",
158
+ display_name="claude-sonnet-4-5-20250929",
159
+ model_name="claude-sonnet-4-5-20250929",
160
160
  provider="anthropic",
161
161
  ),
162
162
  ModelInfo(
@@ -251,7 +251,7 @@ DEFAULT_SUPPORTED_MODELS = [
251
251
 
252
252
  # 定義支援 agent 的 LLM models
253
253
  DEFAULT_AGENT_MODELS = [
254
- "claude-sonnet-4-20250514",
254
+ "claude-sonnet-4-5-20250929",
255
255
  "gemini-2.5-pro",
256
256
  "gemini-2.5-flash",
257
257
  ]
@@ -83,6 +83,11 @@ from langchain_anthropic import ChatAnthropic
83
83
  from langchain.tools import StructuredTool # 或 langchain_core.tools
84
84
  from langchain_mcp_adapters.client import MultiServerMCPClient
85
85
 
86
+ # ========
87
+ # for Vertex AI
88
+ from google.oauth2 import service_account
89
+ from langchain_google_vertexai.model_garden import ChatAnthropicVertex
90
+
86
91
  load_dotenv()
87
92
 
88
93
  # logger = default_logger
@@ -129,7 +134,7 @@ logger = get_default_botrun_logger()
129
134
  def get_react_agent_model_name(model_name: str = ""):
130
135
  final_model_name = model_name
131
136
  if final_model_name == "":
132
- final_model_name = "claude-sonnet-4-20250514"
137
+ final_model_name = "claude-sonnet-4-5-20250929"
133
138
  logger.info(f"final_model_name: {final_model_name}")
134
139
  return final_model_name
135
140
 
@@ -140,56 +145,94 @@ ANTHROPIC_MAX_TOKENS = 64000
140
145
  def get_react_agent_model(model_name: str = ""):
141
146
  final_model_name = get_react_agent_model_name(model_name)
142
147
  if final_model_name.startswith("gemini-"):
143
-
144
148
  model = ChatGoogleGenerativeAI(model=final_model_name, temperature=0)
145
149
  logger.info(f"model ChatGoogleGenerativeAI {final_model_name}")
146
150
  elif final_model_name.startswith("claude-"):
147
- anthropic_api_keys_str = os.getenv("ANTHROPIC_API_KEYS", "")
148
- anthropic_api_keys = [
149
- key.strip() for key in anthropic_api_keys_str.split(",") if key.strip()
150
- ]
151
- if anthropic_api_keys:
152
-
153
- model = RotatingChatAnthropic(
154
- model_name=final_model_name,
155
- keys=anthropic_api_keys,
156
- temperature=0,
157
- max_tokens=ANTHROPIC_MAX_TOKENS,
158
- )
159
- logger.info(f"model RotatingChatAnthropic {final_model_name}")
160
- elif os.getenv("OPENROUTER_API_KEY") and os.getenv("OPENROUTER_BASE_URL"):
161
-
162
- openrouter_model_name = "anthropic/claude-sonnet-4.5"
163
- # openrouter_model_name = "openai/o4-mini-high"
164
- # openrouter_model_name = "openai/gpt-4.1"
165
- model = ChatOpenAI(
166
- openai_api_key=os.getenv("OPENROUTER_API_KEY"),
167
- openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
168
- model_name=openrouter_model_name,
169
- temperature=0,
170
- max_tokens=ANTHROPIC_MAX_TOKENS,
171
- model_kwargs={
172
- # "headers": {
173
- # "HTTP-Referer": getenv("YOUR_SITE_URL"),
174
- # "X-Title": getenv("YOUR_SITE_NAME"),
175
- # }
176
- },
151
+ use_vertex_ai = os.getenv("USE_VERTEX_AI", "false").lower() in ("true", "1", "yes")
152
+
153
+ if use_vertex_ai:
154
+ # 從環境變數讀取設定
155
+ vertex_location = os.getenv("VERTEX_AI_LANGCHAIN_LOCATION", "europe-west1")
156
+ vertex_model = os.getenv("VERTEX_AI_LANGCHAIN_MODEL", final_model_name)
157
+ vertex_sa_path = os.getenv("VERTEX_AI_LANGCHAIN_GOOGLE_APPLICATION_CREDENTIALS")
158
+
159
+ # 驗證 service account
160
+ credentials = None
161
+ if vertex_sa_path and os.path.exists(vertex_sa_path):
162
+ # 加入 Vertex AI 需要的 scopes
163
+ SCOPES = [
164
+ 'https://www.googleapis.com/auth/cloud-platform',
165
+ 'https://www.googleapis.com/auth/cloudplatformprojects.readonly',
166
+ ]
167
+ credentials = service_account.Credentials.from_service_account_file(
168
+ vertex_sa_path,
169
+ scopes=SCOPES
170
+ )
171
+ logger.info(f"Using Vertex AI service account from {vertex_sa_path}")
172
+ else:
173
+ logger.warning(
174
+ "VERTEX_AI_GOOGLE_APPLICATION_CREDENTIALS not set or file not found. Using ADC if available.")
175
+
176
+ # 初始化 ChatAnthropicVertex
177
+ model = ChatAnthropicVertex(
178
+ model=vertex_model,
179
+ location=vertex_location,
180
+ credentials=credentials,
181
+ temperature=0
177
182
  )
178
- logger.info(f"model OpenRouter {openrouter_model_name}")
183
+ logger.info(f"model ChatAnthropicVertex {vertex_model} @ {vertex_location}")
184
+
179
185
  else:
186
+ anthropic_api_keys_str = os.getenv("ANTHROPIC_API_KEYS", "")
187
+ anthropic_api_keys = [
188
+ key.strip() for key in anthropic_api_keys_str.split(",") if key.strip()
189
+ ]
190
+ if anthropic_api_keys:
191
+
192
+ model = RotatingChatAnthropic(
193
+ model_name=final_model_name,
194
+ keys=anthropic_api_keys,
195
+ temperature=0,
196
+ max_tokens=ANTHROPIC_MAX_TOKENS,
197
+ )
198
+ logger.info(f"model RotatingChatAnthropic {final_model_name}")
199
+ elif os.getenv("OPENROUTER_API_KEY") and os.getenv("OPENROUTER_BASE_URL"):
200
+
201
+ openrouter_model_name = "anthropic/claude-sonnet-4.5"
202
+ # openrouter_model_name = "openai/o4-mini-high"
203
+ # openrouter_model_name = "openai/gpt-4.1"
204
+ model = ChatOpenAI(
205
+ openai_api_key=os.getenv("OPENROUTER_API_KEY"),
206
+ openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
207
+ model_name=openrouter_model_name,
208
+ temperature=0,
209
+ max_tokens=ANTHROPIC_MAX_TOKENS,
210
+ model_kwargs={
211
+ # "headers": {
212
+ # "HTTP-Referer": getenv("YOUR_SITE_URL"),
213
+ # "X-Title": getenv("YOUR_SITE_NAME"),
214
+ # }
215
+ },
216
+ )
217
+ logger.info(f"model OpenRouter {openrouter_model_name}")
218
+ else:
219
+
220
+ model = ChatAnthropic(
221
+ model=final_model_name,
222
+ temperature=0,
223
+ max_tokens=ANTHROPIC_MAX_TOKENS,
224
+ # model_kwargs={
225
+ # "extra_headers": {
226
+ # "anthropic-beta": "token-efficient-tools-2025-02-19",
227
+ # "anthropic-beta": "output-128k-2025-02-19",
228
+ # }
229
+ # },
230
+ )
231
+ logger.info(f"model ChatAnthropic {final_model_name}")
232
+
233
+ else:
234
+ raise ValueError(f"Unknown model name prefix: {final_model_name}")
180
235
 
181
- model = ChatAnthropic(
182
- model=final_model_name,
183
- temperature=0,
184
- max_tokens=ANTHROPIC_MAX_TOKENS,
185
- # model_kwargs={
186
- # "extra_headers": {
187
- # "anthropic-beta": "token-efficient-tools-2025-02-19",
188
- # "anthropic-beta": "output-128k-2025-02-19",
189
- # }
190
- # },
191
- )
192
- logger.info(f"model ChatAnthropic {final_model_name}")
193
236
  return model
194
237
 
195
238
 
@@ -419,7 +462,7 @@ async def create_react_agent_graph(
419
462
  system_prompt: The system prompt to use for the agent (used directly, no concatenation)
420
463
  botrun_flow_lang_url: URL for botrun flow lang service (reserved for future use)
421
464
  user_id: User identifier (reserved for future use)
422
- model_name: AI model name to use (defaults to claude-sonnet-4-20250514)
465
+ model_name: AI model name to use (defaults to claude-sonnet-4-5-20250929)
423
466
  lang: Language code affecting language-specific tools (e.g., "en", "zh-TW")
424
467
  mcp_config: MCP servers configuration dict providing tools like scrape, chat_with_pdf, etc.
425
468
 
@@ -49,7 +49,7 @@ def get_img_content_type(file_path: str | Path) -> str:
49
49
 
50
50
 
51
51
  def analyze_imgs_with_claude(
52
- img_urls: list[str], user_input: str, model_name: str = "claude-sonnet-4-20250514"
52
+ img_urls: list[str], user_input: str, model_name: str = "claude-sonnet-4-5-20250929"
53
53
  ) -> str:
54
54
  """
55
55
  Analyze multiple images using Claude Vision API
@@ -9,15 +9,17 @@ from langchain_openai import ChatOpenAI
9
9
  from langchain_google_genai import ChatGoogleGenerativeAI
10
10
 
11
11
 
12
- def get_model_instance(model_name: str, temperature: float = 0, enable_code_execution: bool = False):
12
+ def get_model_instance(
13
+ model_name: str, temperature: float = 0, enable_code_execution: bool = False
14
+ ):
13
15
  """
14
16
  統一的模型實例獲取函數
15
-
17
+
16
18
  Args:
17
19
  model_name: 模型名稱
18
20
  temperature: 溫度參數
19
21
  enable_code_execution: 是否啟用代碼執行(僅 Gemini 2.5 支援)
20
-
22
+
21
23
  Returns:
22
24
  對應的模型實例
23
25
  """
@@ -25,20 +27,18 @@ def get_model_instance(model_name: str, temperature: float = 0, enable_code_exec
25
27
  model_kwargs = {}
26
28
  if enable_code_execution and "2.5" in model_name:
27
29
  model_kwargs["enable_code_execution"] = True
28
-
30
+
29
31
  return ChatGoogleGenerativeAI(
30
- model=model_name,
31
- temperature=temperature,
32
- **model_kwargs
32
+ model=model_name, temperature=temperature, **model_kwargs
33
33
  )
34
-
34
+
35
35
  elif model_name.startswith("claude-"):
36
36
  # 檢查是否有多個 Anthropic API keys
37
37
  anthropic_api_keys_str = os.getenv("ANTHROPIC_API_KEYS", "")
38
38
  anthropic_api_keys = [
39
39
  key.strip() for key in anthropic_api_keys_str.split(",") if key.strip()
40
40
  ]
41
-
41
+
42
42
  if anthropic_api_keys:
43
43
  return RotatingChatAnthropic(
44
44
  model_name=model_name,
@@ -47,7 +47,7 @@ def get_model_instance(model_name: str, temperature: float = 0, enable_code_exec
47
47
  max_tokens=64000,
48
48
  )
49
49
  elif os.getenv("OPENROUTER_API_KEY") and os.getenv("OPENROUTER_BASE_URL"):
50
- openrouter_model_name = "anthropic/claude-sonnet-4"
50
+ openrouter_model_name = "anthropic/claude-sonnet-4.5"
51
51
  return ChatOpenAI(
52
52
  openai_api_key=os.getenv("OPENROUTER_API_KEY"),
53
53
  openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
@@ -61,7 +61,7 @@ def get_model_instance(model_name: str, temperature: float = 0, enable_code_exec
61
61
  temperature=temperature,
62
62
  max_tokens=64000,
63
63
  )
64
-
64
+
65
65
  elif model_name.startswith("gpt-"):
66
66
  if os.getenv("OPENROUTER_API_KEY") and os.getenv("OPENROUTER_BASE_URL"):
67
67
  return ChatOpenAI(
@@ -77,7 +77,7 @@ def get_model_instance(model_name: str, temperature: float = 0, enable_code_exec
77
77
  temperature=temperature,
78
78
  max_tokens=8192,
79
79
  )
80
-
80
+
81
81
  else:
82
82
  # 預設使用 Gemini
83
83
  return ChatGoogleGenerativeAI(
@@ -11,7 +11,7 @@ load_dotenv()
11
11
 
12
12
 
13
13
  def analyze_pdf_with_claude(
14
- pdf_data: str, user_input: str, model_name: str = "claude-sonnet-4-20250514"
14
+ pdf_data: str, user_input: str, model_name: str = "claude-sonnet-4-5-20250929"
15
15
  ):
16
16
  """
17
17
  Analyze a PDF file using Claude API
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: botrun-flow-lang
3
- Version: 5.10.32
3
+ Version: 5.10.83
4
4
  Summary: A flow language for botrun
5
5
  Author-email: sebastian-hsu <sebastian.hsu@gmail.com>
6
6
  License: MIT
@@ -13,7 +13,7 @@ Requires-Python: <3.13,>=3.11
13
13
  Requires-Dist: aiohttp>=3.10.8
14
14
  Requires-Dist: anthropic>=0.61.0
15
15
  Requires-Dist: boto3>=1.40.3
16
- Requires-Dist: botrun-hatch>=5.6.101
16
+ Requires-Dist: botrun-hatch>=5.10.82
17
17
  Requires-Dist: botrun-log>=0.3.0
18
18
  Requires-Dist: cachetools>=5.5.2
19
19
  Requires-Dist: chardet>=5.2.0
@@ -23,7 +23,7 @@ Requires-Dist: google-auth>=2.40.3
23
23
  Requires-Dist: google-cloud-discoveryengine>=0.13.3
24
24
  Requires-Dist: google-cloud-firestore>=2.21.0
25
25
  Requires-Dist: google-cloud-logging>=3.11.4
26
- Requires-Dist: google-cloud-storage>=3.2.0
26
+ Requires-Dist: google-cloud-storage<3,>=2.18
27
27
  Requires-Dist: google-genai>=1.28.0
28
28
  Requires-Dist: jinja2>=3.1.6
29
29
  Requires-Dist: langchain-anthropic>=0.3.10
@@ -32,6 +32,7 @@ Requires-Dist: langchain-community>=0.3.27
32
32
  Requires-Dist: langchain-core>=0.3.72
33
33
  Requires-Dist: langchain-google-community>=2.0.3
34
34
  Requires-Dist: langchain-google-genai>=2.0.9
35
+ Requires-Dist: langchain-google-vertexai<3.0.0,>=2.1.2
35
36
  Requires-Dist: langchain-mcp-adapters>=0.1.7
36
37
  Requires-Dist: langchain-openai>=0.3.28
37
38
  Requires-Dist: langchain>=0.3.27
@@ -11,7 +11,7 @@ botrun_flow_lang/api/flow_api.py,sha256=I6ZMohJOpuVcs8q2euUjdydz0xYvavRei7f3LQFm
11
11
  botrun_flow_lang/api/hatch_api.py,sha256=SOKCmCUeeXQbkTZagpc4zpaHPYwu-x99W0tzfEZsKfo,16394
12
12
  botrun_flow_lang/api/langgraph_api.py,sha256=So3sov5GMMiW71Da7KoHM9U3FAGX2tjxgkVspcAawqM,29424
13
13
  botrun_flow_lang/api/line_bot_api.py,sha256=mg1mjgzWDVEno7VpXXO6h9GTdQ02v1pPrEBhei5-QA0,53178
14
- botrun_flow_lang/api/model_api.py,sha256=ADg5Rap_EPN3iIyYxxHGwSKx_hpmaoXPK2DrustSKIE,9777
14
+ botrun_flow_lang/api/model_api.py,sha256=vkzVvzxxsAhqbiMcVAeqiQoheJVbPLAXBqwoU5PgWMw,9783
15
15
  botrun_flow_lang/api/rate_limit_api.py,sha256=zrQ9wFILNqYMiLDM8NqdfcDg87BdyzbBC2Kns89WIGo,980
16
16
  botrun_flow_lang/api/routes.py,sha256=nV6h-MtpGUjK7DdVEf22ddi62KA2ovdgKyOy75cpOZA,1649
17
17
  botrun_flow_lang/api/search_api.py,sha256=dztKS8sb3YYLVn6NVj8r0N92xkgJr_g13RpdXPLPZP0,1437
@@ -24,7 +24,7 @@ botrun_flow_lang/api/youtube_api.py,sha256=9eGr--gR2OoM9JZ6Nf9KqPiE-FeXEx8R-QeJv
24
24
  botrun_flow_lang/langgraph_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  botrun_flow_lang/langgraph_agents/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  botrun_flow_lang/langgraph_agents/agents/agent_runner.py,sha256=eozsyG5Qywd-h4_oHYzPk8c8W9cC1uN2S-11AoQfwOA,6415
27
- botrun_flow_lang/langgraph_agents/agents/langgraph_react_agent.py,sha256=Aavc1GJ_6LNyFrT_tR5l_KW3-DGxgPvMzWgFdhtdI0E,23270
27
+ botrun_flow_lang/langgraph_agents/agents/langgraph_react_agent.py,sha256=y58ia0wT3AW0Xe04YHaOUcedycd_u4nUoosByfKXfjM,25307
28
28
  botrun_flow_lang/langgraph_agents/agents/search_agent_graph.py,sha256=hWDPt0U09Gj-3-NNWhsn9xaakYbOcHExIXqcL8TeZxw,32046
29
29
  botrun_flow_lang/langgraph_agents/agents/agent_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  botrun_flow_lang/langgraph_agents/agents/agent_tools/step_planner.py,sha256=S4TYt0ZhgdAZ-2ndH8hJoEaIyDKdNJdWHjEZ49Lg_NQ,2427
@@ -39,11 +39,11 @@ botrun_flow_lang/langgraph_agents/agents/tools/gemini_code_execution.py,sha256=E
39
39
  botrun_flow_lang/langgraph_agents/agents/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  botrun_flow_lang/langgraph_agents/agents/util/gemini_grounding.py,sha256=JTfH9WJNDlpvMvfzXyZy3bHeCN58MTnEOiamQGMsqh0,2884
41
41
  botrun_flow_lang/langgraph_agents/agents/util/html_util.py,sha256=g5yJO0qTqRq_kb-xhSnWX3WAbHDIjNQYl7ErRBPQwHs,13230
42
- botrun_flow_lang/langgraph_agents/agents/util/img_util.py,sha256=I7TW_SBuJJRxnaJZngZRdD84LMlIiKdkSbqycOwtexQ,10403
42
+ botrun_flow_lang/langgraph_agents/agents/util/img_util.py,sha256=px_ymI5U8WkFujqF-nbxZZNFOKPxJyj5HYV2IQdpYl4,10405
43
43
  botrun_flow_lang/langgraph_agents/agents/util/local_files.py,sha256=ag9axxHdXwFikemjOZDky2G_CB_bPunq1oHIZM6y2jU,11315
44
44
  botrun_flow_lang/langgraph_agents/agents/util/mermaid_util.py,sha256=o65I979wA7jzzB_Zp-t2CxBjNdXyFtdTkdofi4bJlb0,2642
45
- botrun_flow_lang/langgraph_agents/agents/util/model_utils.py,sha256=ZhSPmHs9PTbGs_3PAdS9V_Vs6jeovxYwTETRiXzfI2I,5010
46
- botrun_flow_lang/langgraph_agents/agents/util/pdf_analyzer.py,sha256=QxuJaJhpuohb0aJpxVchl2MIA-f5zjYLYHAn94Y2qAQ,5249
45
+ botrun_flow_lang/langgraph_agents/agents/util/model_utils.py,sha256=oeYEwiEtlrNGomKZ98M3F_OvXYjAIoCV9IJCY9eMuug,4954
46
+ botrun_flow_lang/langgraph_agents/agents/util/pdf_analyzer.py,sha256=WG3SFecIRb2-2gEQLILPduP6Aih9A-TC_JVNnLK1x4M,5251
47
47
  botrun_flow_lang/langgraph_agents/agents/util/perplexity_search.py,sha256=dZmb4tSECEXWOSZkqdMhFrmnGwMhdHSUJvLT7IAVu_s,19537
48
48
  botrun_flow_lang/langgraph_agents/agents/util/plotly_util.py,sha256=WwAPcmMDnQnrsxH_92377G0yRWf-dF-g8uOG9KnkcCk,1972
49
49
  botrun_flow_lang/langgraph_agents/agents/util/tavily_search.py,sha256=jjuA8dko9YRSs_LcvMduAsSGDaix3UEzw4cIllVVFh0,6822
@@ -94,6 +94,6 @@ botrun_flow_lang/utils/yaml_utils.py,sha256=dPlabIol-Clhnwc7N5nuffCaLSq8dyvmvjRw
94
94
  botrun_flow_lang/utils/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
95
  botrun_flow_lang/utils/clients/rate_limit_client.py,sha256=96NNCHB9I5C5bpVFF6sfPhmh4oAx3UdOLb-Z4PAXLdg,8558
96
96
  botrun_flow_lang/utils/clients/token_verify_client.py,sha256=-AnYApJ9CvxVn-RhCCZZ2LCrf065fgskhwLKAm-aiN0,5893
97
- botrun_flow_lang-5.10.32.dist-info/METADATA,sha256=lGn8iUQnoxBXVL_FPw-KaF-fb54m3Up1X7NQ25wkBgk,6362
98
- botrun_flow_lang-5.10.32.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- botrun_flow_lang-5.10.32.dist-info/RECORD,,
97
+ botrun_flow_lang-5.10.83.dist-info/METADATA,sha256=ol2rAztn49Me0-g-Ftbe3lKw_0BuQAMyz1HHtNrOa14,6419
98
+ botrun_flow_lang-5.10.83.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ botrun_flow_lang-5.10.83.dist-info/RECORD,,