botrun-flow-lang 5.10.291__tar.gz → 5.11.11__tar.gz
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.
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/CHANGELOG.md +15 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/PKG-INFO +1 -1
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/storage_api.py +79 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/local_files.py +77 -3
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/mcp_server/default_mcp.py +37 -13
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/storage/storage_cs_store.py +1 -1
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/pyproject.toml +1 -1
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/.env_template +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/.gcloudignore +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/.gitignore +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/.vscode/launch.json +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/CLAUDE.md +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/Dockerfile.template +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/README.md +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/auth_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/auth_utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/botrun_back_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/flow_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/hatch_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/langgraph_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/line_bot_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/model_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/rate_limit_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/routes.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/search_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/subsidy_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/subsidy_api_system_prompt.txt +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/user_setting_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/version_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/youtube_api.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/constants.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/agent_runner.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/agent_tools/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/agent_tools/step_planner.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/checkpointer/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/checkpointer/firestore_checkpointer.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/gov_researcher/GOV_RESEARCHER_PRD.md +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/gov_researcher/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/gov_researcher/gemini_subsidy_graph.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_2_graph.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_graph.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/langgraph_react_agent.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/search_agent_graph.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/tools/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/tools/gemini_code_execution.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/gemini_grounding.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/html_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/img_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/mermaid_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/model_utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/pdf_analyzer.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/perplexity_search.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/plotly_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/tavily_search.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/agents/util/youtube_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/cache/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/cache/langgraph_botrun_cache.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/llm_agent.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/llm_agent_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/log/.gitignore +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/main.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/main_fast.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/mcp_server/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/models/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/models/nodes/utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/models/token_usage.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/requirements.txt +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/base/firestore_base.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/hatch/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/hatch/hatch_factory.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/hatch/hatch_fs_store.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/storage/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/storage/storage_factory.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/storage/storage_store.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/user_setting/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/user_setting/user_setting_factory.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/user_setting/user_setting_fs_store.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/static/docs/tools/index.html +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/api_functional_tests.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/api_stress_test.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/shared_hatch_tests.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_botrun_app.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/(/346/272/253/351/246/250/346/210/220/346/236/234 /350/241/214/346/224/277/350/253/213/347/244/272/345/214/257/347/270/275)20250210/345/220/221 /344/270/212/344/272/272/345/240/261/345/221/212/347/260/241/345/240/261 (1).pdf" +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/11206_10808/344/272/272/345/217/243/346/225/270(3/346/256/265/345/271/264/351/275/241/347/265/204+/346/257/224/347/216/207)/345/244/251/344/270/213/351/233/234/350/252/2141.pdf" +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/1120701A/346/265/267/345/273/243/351/233/242/345/262/270/351/242/250/345/212/233/347/231/274/351/233/273/350/250/210/347/225/253/347/222/260/345/242/203/345/275/261/351/237/277/350/252/252/346/230/216/346/233/270-C04.PDF" +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/ImportedPhoto.760363950.029251.jpeg +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/ImportedPhoto.760363950.030446.jpeg +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/ImportedPhoto.760363950.031127.jpeg +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/d5712343.jpg +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/spot_difference_1.png +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_files/spot_difference_2.png +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_html_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_img_analyzer.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_img_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_local_files.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_mermaid_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_pdf_analyzer.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_plotly_util.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_run_workflow_engine.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tools/generate_docs.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tools/templates/tools.html +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/botrun_logger.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/clients/__init__.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/clients/rate_limit_client.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/clients/token_verify_client.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/google_drive_utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/langchain_utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/yaml_utils.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/cloudbuild_template.yaml +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/convert_newlines.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/deploy.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/langgraph.json +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/poetry.lock +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/poetry.toml +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/requirements.txt +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/requirements_fast.txt +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_bigline.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_dev.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_evaldev.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_fast.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_modaline.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_prod.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/deploy_sebaline.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/firestore_checkpointer_delete_thread.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/generate_docs.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/llm_time_test.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/run_langgraph.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/run_langgraph_react.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/run_youtube_summary.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/scrape_pdf.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/seba_pypi.sh +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/subsidy_test.py +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/agent-architecture-upgrade.excalidraw +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/line_dev.excalidraw +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/subsidy_agent.excalidraw +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/subsidy_agent_dev.excalidraw +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/temp_txt.md +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/temp_txt2.md +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search//346/264/245/350/262/274line/345/276/205/350/250/216/350/253/226.excalidraw" +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/system_thinking.excalidraw +0 -0
- {botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/uv.lock +0 -0
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [5.11.11]
|
|
2
|
+
### Added
|
|
3
|
+
- DALL-E 圖片永久化儲存功能 [參考 specs/gen-img/design.md]
|
|
4
|
+
- Storage API 新增 `/api/img-files/{user_id}` endpoint,支援圖片永久儲存到 GCS
|
|
5
|
+
- 新增 `_upload_img_file_internal` 內部函數處理圖片上傳
|
|
6
|
+
- local_files.py 新增 `download_image_from_url` 函數從 URL 下載圖片到記憶體
|
|
7
|
+
- local_files.py 新增 `upload_image_and_get_public_url` 函數處理圖片下載與上傳流程
|
|
8
|
+
- MCP generate_image 工具現在會將 DALL-E 生成的圖片自動上傳到 GCS,回傳永久 URL
|
|
9
|
+
- 圖片儲存路徑:`img/{user_id}/dalle_{timestamp}_{random_id}.png`
|
|
10
|
+
- 支援 fallback 機制:上傳失敗時回傳臨時 URL(1小時有效)
|
|
11
|
+
|
|
12
|
+
### Updated
|
|
13
|
+
- GCS bucket lifecycle rules:將 tmp/ 目錄檔案的自動刪除期限從 7 天延長至 365 天(1年)
|
|
14
|
+
- local_files.py 重新命名 `_perform_upload` → `_perform_tmp_file_upload`,明確表示暫存檔案上傳
|
|
15
|
+
|
|
1
16
|
## [5.10.291]
|
|
2
17
|
### Updated
|
|
3
18
|
- line bot api ,呼叫 cbh 做的 api
|
|
@@ -202,6 +202,43 @@ async def _upload_html_file_internal(
|
|
|
202
202
|
return public_url
|
|
203
203
|
|
|
204
204
|
|
|
205
|
+
async def _upload_img_file_internal(
|
|
206
|
+
user_id: str, file_content: bytes, file_name: str, content_type: str = "image/png"
|
|
207
|
+
) -> str:
|
|
208
|
+
"""
|
|
209
|
+
Internal function to upload image file to GCS
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
user_id: User ID
|
|
213
|
+
file_content: File content as bytes
|
|
214
|
+
file_name: File name
|
|
215
|
+
content_type: MIME type of the file
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
str: Public URL of the uploaded file
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
Exception: If upload fails
|
|
222
|
+
"""
|
|
223
|
+
storage = storage_store_factory()
|
|
224
|
+
|
|
225
|
+
# Create file object from bytes
|
|
226
|
+
file_object = BytesIO(file_content)
|
|
227
|
+
|
|
228
|
+
# Build storage path - use img directory for permanent storage
|
|
229
|
+
storage_path = f"img/{user_id}/{file_name}"
|
|
230
|
+
|
|
231
|
+
# Store file with public access and content type
|
|
232
|
+
success, public_url = await storage.store_file(
|
|
233
|
+
storage_path, file_object, public=True, content_type=content_type
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if not success:
|
|
237
|
+
raise Exception("Failed to store image file")
|
|
238
|
+
|
|
239
|
+
return public_url
|
|
240
|
+
|
|
241
|
+
|
|
205
242
|
@router.post("/html-files/{user_id}")
|
|
206
243
|
async def upload_html_file(
|
|
207
244
|
user_id: str,
|
|
@@ -244,6 +281,48 @@ async def upload_html_file(
|
|
|
244
281
|
raise HTTPException(status_code=500, detail=str(e))
|
|
245
282
|
|
|
246
283
|
|
|
284
|
+
@router.post("/img-files/{user_id}")
|
|
285
|
+
async def upload_img_file(
|
|
286
|
+
user_id: str,
|
|
287
|
+
file: FastAPIUploadFile = File(...),
|
|
288
|
+
file_name: str = Form(...),
|
|
289
|
+
content_type: str = Form(None),
|
|
290
|
+
# current_user: CurrentUser = Depends(verify_jwt_token)
|
|
291
|
+
) -> dict:
|
|
292
|
+
"""
|
|
293
|
+
儲存圖片檔案到 GCS,檔案會是公開可存取且永久保存
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
user_id: 使用者 ID
|
|
297
|
+
file: 上傳的檔案
|
|
298
|
+
file_name: 檔案名稱
|
|
299
|
+
content_type: 檔案的 MIME type,如果沒有提供則使用檔案的 content_type
|
|
300
|
+
"""
|
|
301
|
+
# Verify user permission
|
|
302
|
+
# verify_user_permission(current_user, user_id)
|
|
303
|
+
|
|
304
|
+
try:
|
|
305
|
+
# 讀取上傳的檔案內容
|
|
306
|
+
contents = await file.read()
|
|
307
|
+
|
|
308
|
+
# 如果沒有提供 content_type,使用檔案的 content_type
|
|
309
|
+
if not content_type:
|
|
310
|
+
content_type = file.content_type
|
|
311
|
+
|
|
312
|
+
# Use internal function to upload file
|
|
313
|
+
public_url = await _upload_img_file_internal(
|
|
314
|
+
user_id, contents, file_name, content_type
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
"message": "Image file uploaded successfully",
|
|
319
|
+
"success": True,
|
|
320
|
+
"url": public_url,
|
|
321
|
+
}
|
|
322
|
+
except Exception as e:
|
|
323
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
324
|
+
|
|
325
|
+
|
|
247
326
|
@router.get("/directory-sizes")
|
|
248
327
|
async def get_directory_sizes(current_user: CurrentUser = Depends(verify_jwt_token)):
|
|
249
328
|
"""
|
|
@@ -52,7 +52,7 @@ def upload_and_get_tmp_public_url(
|
|
|
52
52
|
"""
|
|
53
53
|
# 外層 try-except: 處理第一次嘗試與重試邏輯
|
|
54
54
|
try:
|
|
55
|
-
return
|
|
55
|
+
return _perform_tmp_file_upload(file_path, botrun_flow_lang_url, user_id)
|
|
56
56
|
except Exception as e:
|
|
57
57
|
import traceback
|
|
58
58
|
|
|
@@ -68,7 +68,7 @@ def upload_and_get_tmp_public_url(
|
|
|
68
68
|
# 第二次嘗試
|
|
69
69
|
try:
|
|
70
70
|
print("Retry attempt...")
|
|
71
|
-
return
|
|
71
|
+
return _perform_tmp_file_upload(file_path, botrun_flow_lang_url, user_id)
|
|
72
72
|
except Exception as retry_e:
|
|
73
73
|
# 第二次嘗試也失敗,記錄錯誤並返回錯誤訊息
|
|
74
74
|
print(f"Retry attempt failed: {str(retry_e)}")
|
|
@@ -76,7 +76,7 @@ def upload_and_get_tmp_public_url(
|
|
|
76
76
|
return "Error uploading file"
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
def
|
|
79
|
+
def _perform_tmp_file_upload(
|
|
80
80
|
file_path: str, botrun_flow_lang_url: str = "", user_id: str = ""
|
|
81
81
|
) -> str:
|
|
82
82
|
"""執行實際的上傳操作
|
|
@@ -343,3 +343,77 @@ async def _perform_html_upload(
|
|
|
343
343
|
traceback.print_exc()
|
|
344
344
|
# 這裡把異常往上拋,讓外層的重試邏輯處理
|
|
345
345
|
raise e
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
async def download_image_from_url(image_url: str) -> tuple[BytesIO, str]:
|
|
349
|
+
"""
|
|
350
|
+
從 URL 下載圖片到記憶體
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
image_url: 圖片的 URL
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
tuple[BytesIO, str]: (圖片內容, content_type)
|
|
357
|
+
|
|
358
|
+
Raises:
|
|
359
|
+
Exception: 下載失敗時拋出例外
|
|
360
|
+
"""
|
|
361
|
+
try:
|
|
362
|
+
import httpx
|
|
363
|
+
|
|
364
|
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
365
|
+
response = await client.get(image_url, follow_redirects=True)
|
|
366
|
+
response.raise_for_status()
|
|
367
|
+
|
|
368
|
+
# 從 response headers 取得 content type
|
|
369
|
+
content_type = response.headers.get("content-type", "image/png")
|
|
370
|
+
|
|
371
|
+
# 將圖片內容存入 BytesIO
|
|
372
|
+
image_data = BytesIO(response.content)
|
|
373
|
+
|
|
374
|
+
return image_data, content_type
|
|
375
|
+
|
|
376
|
+
except Exception as e:
|
|
377
|
+
raise Exception(f"Failed to download image from URL: {str(e)}")
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
async def upload_image_and_get_public_url(
|
|
381
|
+
image_url: str, botrun_flow_lang_url: str = "", user_id: str = ""
|
|
382
|
+
) -> str:
|
|
383
|
+
"""
|
|
384
|
+
從 URL 下載圖片並上傳到 GCS /img 目錄,取得永久公開 URL
|
|
385
|
+
|
|
386
|
+
Args:
|
|
387
|
+
image_url: 圖片來源 URL(如 DALL-E 生成的臨時 URL)
|
|
388
|
+
botrun_flow_lang_url: botrun flow lang API 的 URL
|
|
389
|
+
user_id: 使用者 ID
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
str: 上傳後的永久公開存取 URL
|
|
393
|
+
"""
|
|
394
|
+
try:
|
|
395
|
+
# 1. 從 URL 下載圖片
|
|
396
|
+
image_data, content_type = await download_image_from_url(image_url)
|
|
397
|
+
|
|
398
|
+
# 2. 生成唯一檔案名稱
|
|
399
|
+
import uuid
|
|
400
|
+
from datetime import datetime
|
|
401
|
+
|
|
402
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
403
|
+
file_name = f"dalle_{timestamp}_{uuid.uuid4().hex[:8]}.png"
|
|
404
|
+
|
|
405
|
+
# 3. 使用內部函數上傳
|
|
406
|
+
from botrun_flow_lang.api.storage_api import _upload_img_file_internal
|
|
407
|
+
|
|
408
|
+
public_url = await _upload_img_file_internal(
|
|
409
|
+
user_id, image_data.getvalue(), file_name, content_type
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
return public_url
|
|
413
|
+
|
|
414
|
+
except Exception as e:
|
|
415
|
+
import traceback
|
|
416
|
+
|
|
417
|
+
print(f"Error uploading image: {str(e)}")
|
|
418
|
+
traceback.print_exc()
|
|
419
|
+
raise e
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/mcp_server/default_mcp.py
RENAMED
|
@@ -128,9 +128,11 @@ async def chat_with_imgs(
|
|
|
128
128
|
|
|
129
129
|
|
|
130
130
|
@mcp.tool()
|
|
131
|
-
async def generate_image(
|
|
131
|
+
async def generate_image(
|
|
132
|
+
user_input: str, user_id: str = "", botrun_flow_lang_url: str = ""
|
|
133
|
+
) -> str:
|
|
132
134
|
"""
|
|
133
|
-
Generate high-quality images using DALL-E 3.
|
|
135
|
+
Generate high-quality images using DALL-E 3 and store permanently in GCS.
|
|
134
136
|
|
|
135
137
|
When using generate_image tool, you must include the image URL in your response.
|
|
136
138
|
You MUST respond using this format (from @begin img to @end, including the image URL):
|
|
@@ -161,17 +163,22 @@ async def generate_image(user_input: str, user_id: str = "") -> str:
|
|
|
161
163
|
Args:
|
|
162
164
|
user_input: Detailed description of the image you want to generate.
|
|
163
165
|
Be specific about style, content, and composition.
|
|
164
|
-
user_id: REQUIRED - User ID for rate limit
|
|
166
|
+
user_id: REQUIRED - User ID for rate limit and file storage (LLM can get this from system prompt)
|
|
167
|
+
botrun_flow_lang_url: REQUIRED - URL for the botrun flow lang API (LLM can get this from system prompt)
|
|
165
168
|
|
|
166
169
|
Returns:
|
|
167
|
-
str: URL to the generated image, or error message if generation fails
|
|
170
|
+
str: Permanent URL to the generated image stored in GCS, or error message if generation fails
|
|
168
171
|
"""
|
|
169
172
|
try:
|
|
170
173
|
logger.info(f"generate_image user_input: {user_input}")
|
|
171
174
|
|
|
175
|
+
# 驗證必要參數
|
|
172
176
|
if not user_id:
|
|
173
|
-
logger.error("User ID not available
|
|
174
|
-
raise Exception("User ID not available
|
|
177
|
+
logger.error("User ID not available")
|
|
178
|
+
raise Exception("User ID not available")
|
|
179
|
+
if not botrun_flow_lang_url:
|
|
180
|
+
logger.error("botrun_flow_lang_url not available")
|
|
181
|
+
raise Exception("botrun_flow_lang_url not available")
|
|
175
182
|
|
|
176
183
|
# Check rate limit before generating image
|
|
177
184
|
rate_limit_client = RateLimitClient()
|
|
@@ -193,25 +200,42 @@ async def generate_image(user_input: str, user_id: str = "") -> str:
|
|
|
193
200
|
f"Current usage: {current_usage}. Please try again tomorrow."
|
|
194
201
|
)
|
|
195
202
|
|
|
196
|
-
#
|
|
203
|
+
# 2. 使用 DALL-E 生成圖片
|
|
197
204
|
dalle_wrapper = DallEAPIWrapper(
|
|
198
205
|
api_key=os.getenv("OPENAI_API_KEY"), model="dall-e-3"
|
|
199
206
|
)
|
|
200
207
|
|
|
201
208
|
# Generate image with token usage tracking
|
|
202
209
|
with get_openai_callback() as cb:
|
|
203
|
-
|
|
210
|
+
temp_image_url = dalle_wrapper.run(user_input)
|
|
204
211
|
logger.info(
|
|
205
|
-
f"
|
|
212
|
+
f"DALL-E generated temporary URL: {temp_image_url}, "
|
|
213
|
+
f"prompt tokens: {cb.prompt_tokens}, "
|
|
206
214
|
f"completion tokens: {cb.completion_tokens}"
|
|
207
215
|
)
|
|
208
216
|
|
|
209
|
-
|
|
217
|
+
# 3. 下載並上傳到 GCS,取得永久 URL
|
|
218
|
+
from botrun_flow_lang.langgraph_agents.agents.util.local_files import (
|
|
219
|
+
upload_image_and_get_public_url,
|
|
220
|
+
)
|
|
210
221
|
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
try:
|
|
223
|
+
permanent_url = await upload_image_and_get_public_url(
|
|
224
|
+
temp_image_url, botrun_flow_lang_url, user_id
|
|
225
|
+
)
|
|
226
|
+
logger.info(f"Image uploaded to GCS: {permanent_url}")
|
|
213
227
|
|
|
214
|
-
|
|
228
|
+
# 4. 更新使用計數
|
|
229
|
+
await rate_limit_client.update_drawing_usage(user_id)
|
|
230
|
+
|
|
231
|
+
return permanent_url
|
|
232
|
+
except Exception as upload_error:
|
|
233
|
+
logger.error(
|
|
234
|
+
f"Failed to upload to GCS, returning temporary URL: {upload_error}"
|
|
235
|
+
)
|
|
236
|
+
# Fallback: 回傳臨時 URL
|
|
237
|
+
await rate_limit_client.update_drawing_usage(user_id)
|
|
238
|
+
return temp_image_url
|
|
215
239
|
|
|
216
240
|
except Exception as e:
|
|
217
241
|
logger.error(f"generate_image error: {e}", error=str(e), exc_info=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/botrun_back_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/langgraph_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/rate_limit_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/api/user_setting_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/langgraph_agents/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/__init__.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/llm_agent.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/llm_agent/llm_agent_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/mcp_server/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/models/nodes/utils.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/models/token_usage.py
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/hatch/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/services/storage/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/static/docs/tools/index.html
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/api_stress_test.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/shared_hatch_tests.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_botrun_app.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_html_util.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_img_analyzer.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_img_util.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_local_files.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_mermaid_util.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_pdf_analyzer.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tests/test_plotly_util.py
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tools/generate_docs.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/tools/templates/tools.html
RENAMED
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/botrun_logger.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/clients/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/google_drive_utils.py
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/botrun_flow_lang/utils/langchain_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/sh/firestore_checkpointer_delete_thread.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/subsidy_agent.excalidraw
RENAMED
|
File without changes
|
{botrun_flow_lang-5.10.291 → botrun_flow_lang-5.11.11}/specs/gov-search/subsidy_agent_dev.excalidraw
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|