synapse-orch-ai 0.1.0
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.
- package/LICENSE +661 -0
- package/README.md +501 -0
- package/backend/core/__init__.py +0 -0
- package/backend/core/agent_logger.py +195 -0
- package/backend/core/builder_tools.py +1482 -0
- package/backend/core/compaction.py +188 -0
- package/backend/core/config.py +89 -0
- package/backend/core/json_store.py +50 -0
- package/backend/core/llm_providers.py +2088 -0
- package/backend/core/mcp_client.py +548 -0
- package/backend/core/mcp_oauth_state.py +37 -0
- package/backend/core/memory.py +714 -0
- package/backend/core/messaging/__init__.py +5 -0
- package/backend/core/messaging/adapters/__init__.py +1 -0
- package/backend/core/messaging/adapters/discord.py +112 -0
- package/backend/core/messaging/adapters/slack.py +123 -0
- package/backend/core/messaging/adapters/teams.py +102 -0
- package/backend/core/messaging/adapters/telegram.py +118 -0
- package/backend/core/messaging/adapters/whatsapp.py +216 -0
- package/backend/core/messaging/base.py +209 -0
- package/backend/core/messaging/manager.py +291 -0
- package/backend/core/messaging/markdown.py +171 -0
- package/backend/core/messaging/store.py +95 -0
- package/backend/core/models.py +154 -0
- package/backend/core/models_orchestration.py +123 -0
- package/backend/core/models_schedule.py +56 -0
- package/backend/core/native_builder/__init__.py +60 -0
- package/backend/core/native_builder/agents/agent_creator.json +20 -0
- package/backend/core/native_builder/agents/orchestrator_builder.json +15 -0
- package/backend/core/native_builder/agents/requirements_analyst.json +21 -0
- package/backend/core/native_builder/agents/saver_create.json +28 -0
- package/backend/core/native_builder/agents/saver_update.json +29 -0
- package/backend/core/native_builder/orchestration.json +515 -0
- package/backend/core/native_builder/seed.py +135 -0
- package/backend/core/orchestration/__init__.py +5 -0
- package/backend/core/orchestration/context.py +630 -0
- package/backend/core/orchestration/engine.py +489 -0
- package/backend/core/orchestration/logger.py +278 -0
- package/backend/core/orchestration/state.py +79 -0
- package/backend/core/orchestration/steps.py +1017 -0
- package/backend/core/orchestration/summarizer.py +106 -0
- package/backend/core/personal_details.py +60 -0
- package/backend/core/profiling.py +160 -0
- package/backend/core/react_engine.py +1017 -0
- package/backend/core/routes/__init__.py +4 -0
- package/backend/core/routes/agents.py +303 -0
- package/backend/core/routes/auth.py +38 -0
- package/backend/core/routes/builder.py +491 -0
- package/backend/core/routes/chat.py +151 -0
- package/backend/core/routes/data.py +800 -0
- package/backend/core/routes/db_configs.py +105 -0
- package/backend/core/routes/import_export.py +370 -0
- package/backend/core/routes/logs.py +93 -0
- package/backend/core/routes/messaging.py +204 -0
- package/backend/core/routes/n8n.py +95 -0
- package/backend/core/routes/orchestrations.py +364 -0
- package/backend/core/routes/profiling.py +83 -0
- package/backend/core/routes/repos.py +212 -0
- package/backend/core/routes/schedules.py +158 -0
- package/backend/core/routes/sessions.py +48 -0
- package/backend/core/routes/settings.py +362 -0
- package/backend/core/routes/tools.py +416 -0
- package/backend/core/routes/usage.py +63 -0
- package/backend/core/routes/vault.py +254 -0
- package/backend/core/schedule_logger.py +226 -0
- package/backend/core/scheduler.py +376 -0
- package/backend/core/server.py +658 -0
- package/backend/core/session.py +206 -0
- package/backend/core/tools.py +344 -0
- package/backend/core/usage_tracker.py +417 -0
- package/backend/core/vault.py +265 -0
- package/backend/main.py +26 -0
- package/backend/requirements.txt +24 -0
- package/backend/services/__init__.py +0 -0
- package/backend/services/code_indexer.py +488 -0
- package/backend/services/google.py +343 -0
- package/backend/services/synthetic_data.py +140 -0
- package/backend/tools/__init__.py +0 -0
- package/backend/tools/bash.py +244 -0
- package/backend/tools/code_indexer.py +110 -0
- package/backend/tools/code_search.py +537 -0
- package/backend/tools/collect_data.py +134 -0
- package/backend/tools/pdf_parser.py +103 -0
- package/backend/tools/personal_details.py +52 -0
- package/backend/tools/sandbox.Dockerfile +24 -0
- package/backend/tools/sandbox.py +586 -0
- package/backend/tools/sql_agent.py +221 -0
- package/backend/tools/time.py +283 -0
- package/backend/tools/web_scraper.py +765 -0
- package/backend/tools/xlsx_parser.py +79 -0
- package/bin/synapse +16 -0
- package/bin/synapse.bat +36 -0
- package/bin/synapse.js +247 -0
- package/frontend-build/.next/BUILD_ID +1 -0
- package/frontend-build/.next/app-path-routes-manifest.json +22 -0
- package/frontend-build/.next/build-manifest.json +21 -0
- package/frontend-build/.next/package.json +1 -0
- package/frontend-build/.next/prerender-manifest.json +114 -0
- package/frontend-build/.next/required-server-files.json +352 -0
- package/frontend-build/.next/routes-manifest.json +194 -0
- package/frontend-build/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/_global-error/page/build-manifest.json +17 -0
- package/frontend-build/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
- package/frontend-build/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
- package/frontend-build/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/_global-error/page.js +9 -0
- package/frontend-build/.next/server/app/_global-error/page.js.map +5 -0
- package/frontend-build/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/frontend-build/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/_global-error.html +1 -0
- package/frontend-build/.next/server/app/_global-error.meta +15 -0
- package/frontend-build/.next/server/app/_global-error.rsc +14 -0
- package/frontend-build/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
- package/frontend-build/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
- package/frontend-build/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/frontend-build/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
- package/frontend-build/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/frontend-build/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/_not-found/page/build-manifest.json +17 -0
- package/frontend-build/.next/server/app/_not-found/page/next-font-manifest.json +14 -0
- package/frontend-build/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
- package/frontend-build/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/_not-found/page.js +13 -0
- package/frontend-build/.next/server/app/_not-found/page.js.map +5 -0
- package/frontend-build/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/frontend-build/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/_not-found.html +1 -0
- package/frontend-build/.next/server/app/_not-found.meta +16 -0
- package/frontend-build/.next/server/app/_not-found.rsc +18 -0
- package/frontend-build/.next/server/app/_not-found.segments/_full.segment.rsc +18 -0
- package/frontend-build/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/frontend-build/.next/server/app/_not-found.segments/_index.segment.rsc +7 -0
- package/frontend-build/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
- package/frontend-build/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
- package/frontend-build/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -0
- package/frontend-build/.next/server/app/api/agent-types/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/agent-types/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/agent-types/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/agent-types/route.js +6 -0
- package/frontend-build/.next/server/app/api/agent-types/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/agent-types/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/agent-types/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route.js +6 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/agents/generate-prompt/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/builder/chat/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/builder/chat/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/builder/chat/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/builder/chat/route.js +6 -0
- package/frontend-build/.next/server/app/api/builder/chat/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/builder/chat/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/builder/chat/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/builder/resume/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/builder/resume/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/builder/resume/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/builder/resume/route.js +6 -0
- package/frontend-build/.next/server/app/api/builder/resume/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/builder/resume/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/builder/resume/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/chat/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/chat/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/chat/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/chat/route.js +6 -0
- package/frontend-build/.next/server/app/api/chat/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/chat/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/chat/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/chat/stream/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/chat/stream/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/chat/stream/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/chat/stream/route.js +6 -0
- package/frontend-build/.next/server/app/api/chat/stream/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/chat/stream/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/chat/stream/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route.js +6 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/logs/[type]/[run_id]/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route.js +6 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/logs/[type]/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/models/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/models/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/models/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/models/route.js +6 -0
- package/frontend-build/.next/server/app/api/models/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/models/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/models/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route.js +6 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/orchestrations/[orch_id]/run/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route.js +6 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/human-input/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route.js +6 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/orchestrations/runs/[run_id]/resume/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route.js +6 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route.js +6 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/schedules/[schedule_id]/run/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/api/schedules/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/api/schedules/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/api/schedules/route/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/api/schedules/route.js +6 -0
- package/frontend-build/.next/server/app/api/schedules/route.js.map +5 -0
- package/frontend-build/.next/server/app/api/schedules/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/api/schedules/route_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/icon.svg/route/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/icon.svg/route/build-manifest.json +9 -0
- package/frontend-build/.next/server/app/icon.svg/route.js +6 -0
- package/frontend-build/.next/server/app/icon.svg/route.js.map +5 -0
- package/frontend-build/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/frontend-build/.next/server/app/icon.svg.body +4 -0
- package/frontend-build/.next/server/app/icon.svg.meta +1 -0
- package/frontend-build/.next/server/app/index.html +1 -0
- package/frontend-build/.next/server/app/index.meta +14 -0
- package/frontend-build/.next/server/app/index.rsc +25 -0
- package/frontend-build/.next/server/app/index.segments/__PAGE__.segment.rsc +9 -0
- package/frontend-build/.next/server/app/index.segments/_full.segment.rsc +25 -0
- package/frontend-build/.next/server/app/index.segments/_head.segment.rsc +6 -0
- package/frontend-build/.next/server/app/index.segments/_index.segment.rsc +7 -0
- package/frontend-build/.next/server/app/index.segments/_tree.segment.rsc +8 -0
- package/frontend-build/.next/server/app/page/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/page/build-manifest.json +17 -0
- package/frontend-build/.next/server/app/page/next-font-manifest.json +14 -0
- package/frontend-build/.next/server/app/page/react-loadable-manifest.json +1 -0
- package/frontend-build/.next/server/app/page/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/page.js +14 -0
- package/frontend-build/.next/server/app/page.js.map +5 -0
- package/frontend-build/.next/server/app/page.js.nft.json +1 -0
- package/frontend-build/.next/server/app/page_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app/settings/[tab]/page/app-paths-manifest.json +3 -0
- package/frontend-build/.next/server/app/settings/[tab]/page/build-manifest.json +17 -0
- package/frontend-build/.next/server/app/settings/[tab]/page/next-font-manifest.json +14 -0
- package/frontend-build/.next/server/app/settings/[tab]/page/react-loadable-manifest.json +1 -0
- package/frontend-build/.next/server/app/settings/[tab]/page/server-reference-manifest.json +4 -0
- package/frontend-build/.next/server/app/settings/[tab]/page.js +16 -0
- package/frontend-build/.next/server/app/settings/[tab]/page.js.map +5 -0
- package/frontend-build/.next/server/app/settings/[tab]/page.js.nft.json +1 -0
- package/frontend-build/.next/server/app/settings/[tab]/page_client-reference-manifest.js +3 -0
- package/frontend-build/.next/server/app-paths-manifest.json +22 -0
- package/frontend-build/.next/server/chunks/0zjb_server_app_api_orchestrations_runs_[run_id]_human-input_route_actions_0oj9y8~.js +3 -0
- package/frontend-build/.next/server/chunks/0zjb_server_app_api_orchestrations_runs_[run_id]_resume_route_actions_0cdumha.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__00sljji._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__02je2si._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__03e7r3a._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__053~3b.._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0afb7iz._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0bc5iuk._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0bygctj._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0c7o1w_._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0cy6bl4._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0dmb8p1._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0gx4j6x._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0h2-vsq._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0j8-xkl._.js +13 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0kkdqe3._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0n1p1jk._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__0xccig4._.js +3 -0
- package/frontend-build/.next/server/chunks/[root-of-the-server]__13dxl3m._.js +3 -0
- package/frontend-build/.next/server/chunks/[turbopack]_runtime.js +903 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_agent-types_route_actions_11dsnho.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_agents_generate-prompt_route_actions_0sqc90~.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_builder_chat_route_actions_0mserwk.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_builder_resume_route_actions_10w~8ke.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_chat_route_actions_0tmcf6..js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_chat_stream_route_actions_0ef7us3.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_logs_[type]_[run_id]_route_actions_061uvw9.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_logs_[type]_route_actions_0jpmtla.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_models_route_actions_0vfccm4.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_orchestrations_[orch_id]_run_route_actions_019s..3.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_schedules_[schedule_id]_route_actions_0vtfp83.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_schedules_[schedule_id]_run_route_actions_04d41xi.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_api_schedules_route_actions_129kjsa.js +3 -0
- package/frontend-build/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_0-0ehc~.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__08gf6t7._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__09z7o2x._.js +19 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0fql_-o._.js +33 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0hfoz0-._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0p3x1m7._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0rj.gz.._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0ssmzpx._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__0uo38ip._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__10unlca._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js +33 -0
- package/frontend-build/.next/server/chunks/ssr/[root-of-the-server]__12b-xga._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/[turbopack]_runtime.js +903 -0
- package/frontend-build/.next/server/chunks/ssr/_0ayz11y._.js +4 -0
- package/frontend-build/.next/server/chunks/ssr/_0df15zg._.js +48 -0
- package/frontend-build/.next/server/chunks/ssr/_0yv_lu6._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0k77kol.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0eq97pa.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/_next-internal_server_app_page_actions_09-gtaw.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/_next-internal_server_app_settings_[tab]_page_actions_0ltd7re.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_09w7yel._.js +33 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_0_ce7g1._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_0y8evf1._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_0zhhlrq._.js +6 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_1041ur2._.js +6 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0ag5..o._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_loader-circle_0hcf_w-.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_0xdsm99._.js +6 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_client_components_0inhx6q._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0ghu-f7.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0lgvd_..js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_08ib7il.js +4 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0k.0n04.js +4 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0rc3ul_.js +4 -0
- package/frontend-build/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_13pf1l2.js +4 -0
- package/frontend-build/.next/server/chunks/ssr/src_app_page_tsx_0ss2.w7._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/src_app_settings_layout_tsx_0j6i0d.._.js +3 -0
- package/frontend-build/.next/server/chunks/ssr/src_app_settings_loading_tsx_0.wko.c._.js +3 -0
- package/frontend-build/.next/server/functions-config-manifest.json +29 -0
- package/frontend-build/.next/server/middleware-build-manifest.js +21 -0
- package/frontend-build/.next/server/middleware-manifest.json +6 -0
- package/frontend-build/.next/server/next-font-manifest.js +1 -0
- package/frontend-build/.next/server/next-font-manifest.json +28 -0
- package/frontend-build/.next/server/pages/404.html +1 -0
- package/frontend-build/.next/server/pages/500.html +1 -0
- package/frontend-build/.next/server/pages-manifest.json +4 -0
- package/frontend-build/.next/server/prefetch-hints.json +1 -0
- package/frontend-build/.next/server/server-reference-manifest.js +1 -0
- package/frontend-build/.next/server/server-reference-manifest.json +5 -0
- package/frontend-build/.next/static/2m6rYBnEW4xy8D-1wzwqJ/_buildManifest.js +18 -0
- package/frontend-build/.next/static/2m6rYBnEW4xy8D-1wzwqJ/_clientMiddlewareManifest.js +1 -0
- package/frontend-build/.next/static/2m6rYBnEW4xy8D-1wzwqJ/_ssgManifest.js +1 -0
- package/frontend-build/.next/static/chunks/02i7dfk78~t~2.js +4 -0
- package/frontend-build/.next/static/chunks/03~yq9q893hmn.js +1 -0
- package/frontend-build/.next/static/chunks/04v~lhs2c9fvw.js +1 -0
- package/frontend-build/.next/static/chunks/05dz57h.5fg3-.js +2 -0
- package/frontend-build/.next/static/chunks/078eei4f0ilb1.js +1 -0
- package/frontend-build/.next/static/chunks/0h4a4y-~puu.x.js +1 -0
- package/frontend-build/.next/static/chunks/0ipoy_nm8gvxg.js +1 -0
- package/frontend-build/.next/static/chunks/0j29xn-eqm8iz.css +5 -0
- package/frontend-build/.next/static/chunks/0js-43escs3uy.js +1 -0
- package/frontend-build/.next/static/chunks/0jvmviuftg5e2.css +1 -0
- package/frontend-build/.next/static/chunks/0mim5z5~_34t1.js +31 -0
- package/frontend-build/.next/static/chunks/0n_h7vo0a.b~e.js +46 -0
- package/frontend-build/.next/static/chunks/0obt-c9w~4_5f.js +1 -0
- package/frontend-build/.next/static/chunks/0uuygh822k98..css +1 -0
- package/frontend-build/.next/static/chunks/0v9xc_wrxht3o.js +1 -0
- package/frontend-build/.next/static/chunks/0vn.s1wic2p_8.js +1 -0
- package/frontend-build/.next/static/chunks/0x6cedgvid-.9.js +2 -0
- package/frontend-build/.next/static/chunks/11evimknhsnll.js +1 -0
- package/frontend-build/.next/static/chunks/127bqzm7d2i2u.js +1 -0
- package/frontend-build/.next/static/chunks/turbopack-1606efl0p3-k2.js +1 -0
- package/frontend-build/.next/static/media/03fc1b4a8d284b5e-s.p.09.f.n_ccld80.woff2 +0 -0
- package/frontend-build/.next/static/media/13bf9871fe164e7f-s.0s19wthhh_6~m.woff2 +0 -0
- package/frontend-build/.next/static/media/1bcd0e671759a44c-s.0vnh8.d8wxa2x.woff2 +0 -0
- package/frontend-build/.next/static/media/1bffadaabf893a1e-s.16ipb6fqu393i.woff2 +0 -0
- package/frontend-build/.next/static/media/2bbe8d2671613f1f-s.067x_6k0k23tk.woff2 +0 -0
- package/frontend-build/.next/static/media/2c55a0e60120577a-s.0bjc5tiuqdqro.woff2 +0 -0
- package/frontend-build/.next/static/media/3fe682a82f50d426-s.09q3q1i5159bl.woff2 +0 -0
- package/frontend-build/.next/static/media/4fa387ec64143e14-s.0q3udbd2bu5yp.woff2 +0 -0
- package/frontend-build/.next/static/media/5476f68d60460930-s.0wxq9webf.ew4.woff2 +0 -0
- package/frontend-build/.next/static/media/57215795b8570f5c-s.0vwgtotjdgnhr.woff2 +0 -0
- package/frontend-build/.next/static/media/70bc3e132a0a741e-s.p.1409xf.ylxg8g.woff2 +0 -0
- package/frontend-build/.next/static/media/7178b3e590c64307-s.11.cyxs5p-0z~.woff2 +0 -0
- package/frontend-build/.next/static/media/71b036adf157cdcf-s.03nf~dfjdkf~..woff2 +0 -0
- package/frontend-build/.next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2 +0 -0
- package/frontend-build/.next/static/media/7fea77d1d19108bf-s.0xyeb7czu1stb.woff2 +0 -0
- package/frontend-build/.next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2 +0 -0
- package/frontend-build/.next/static/media/89b21bb081cb7469-s.0gfhww.tctz1o.woff2 +0 -0
- package/frontend-build/.next/static/media/8a480f0b521d4e75-s.06d3mdzz5bre_.woff2 +0 -0
- package/frontend-build/.next/static/media/90c51ce8fb754fe8-s.00z~hoalba5dm.woff2 +0 -0
- package/frontend-build/.next/static/media/9c72aa0f40e4eef8-s.0m6w47a4e5dy9.woff2 +0 -0
- package/frontend-build/.next/static/media/ad66f9afd8947f86-s.11u06r12fd6v_.woff2 +0 -0
- package/frontend-build/.next/static/media/bbc41e54d2fcbd21-s.0gw~uztddq1df.woff2 +0 -0
- package/frontend-build/.next/static/media/caa3a2e1cccd8315-s.p.16t1db8_9y2o~.woff2 +0 -0
- package/frontend-build/.next/static/media/cc545e633e20c56d-s.0dza.stei.9v7.woff2 +0 -0
- package/frontend-build/.next/static/media/e15f58668ad64cb8-s.0~.8lt~vdqmc3.woff2 +0 -0
- package/frontend-build/.next/static/media/icon.08txep8y1sjlr.svg +4 -0
- package/frontend-build/node_modules/@img/colour/color.cjs +1594 -0
- package/frontend-build/node_modules/@img/colour/index.cjs +1 -0
- package/frontend-build/node_modules/@img/colour/package.json +45 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/README.md +46 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +221 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +1 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/package.json +42 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linux-x64/versions.json +30 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +46 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +221 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +1 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +42 -0
- package/frontend-build/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +30 -0
- package/frontend-build/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
- package/frontend-build/node_modules/@img/sharp-linux-x64/package.json +46 -0
- package/frontend-build/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
- package/frontend-build/node_modules/@img/sharp-linuxmusl-x64/package.json +46 -0
- package/frontend-build/node_modules/@next/env/dist/index.js +1 -0
- package/frontend-build/node_modules/@next/env/package.json +36 -0
- package/frontend-build/node_modules/@swc/helpers/cjs/_interop_require_default.cjs +6 -0
- package/frontend-build/node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs +38 -0
- package/frontend-build/node_modules/@swc/helpers/package.json +471 -0
- package/frontend-build/node_modules/client-only/index.js +0 -0
- package/frontend-build/node_modules/client-only/package.json +19 -0
- package/frontend-build/node_modules/detect-libc/lib/detect-libc.js +313 -0
- package/frontend-build/node_modules/detect-libc/lib/elf.js +39 -0
- package/frontend-build/node_modules/detect-libc/lib/filesystem.js +51 -0
- package/frontend-build/node_modules/detect-libc/lib/process.js +24 -0
- package/frontend-build/node_modules/detect-libc/package.json +44 -0
- package/frontend-build/node_modules/next/dist/build/adapter/setup-node-env.external.js +15 -0
- package/frontend-build/node_modules/next/dist/build/define-env.js +255 -0
- package/frontend-build/node_modules/next/dist/build/duration-to-string.js +99 -0
- package/frontend-build/node_modules/next/dist/build/get-supported-browsers.js +38 -0
- package/frontend-build/node_modules/next/dist/build/next-config-ts/require-hook.js +85 -0
- package/frontend-build/node_modules/next/dist/build/next-config-ts/transpile-config.js +251 -0
- package/frontend-build/node_modules/next/dist/build/output/format.js +84 -0
- package/frontend-build/node_modules/next/dist/build/output/log.js +135 -0
- package/frontend-build/node_modules/next/dist/build/segment-config/app/app-segment-config.js +162 -0
- package/frontend-build/node_modules/next/dist/build/segment-config/app/app-segments.js +137 -0
- package/frontend-build/node_modules/next/dist/build/segment-config/app/collect-root-param-keys.js +52 -0
- package/frontend-build/node_modules/next/dist/build/static-paths/app/extract-pathname-route-param-segments-from-loader-tree.js +137 -0
- package/frontend-build/node_modules/next/dist/build/static-paths/app.js +735 -0
- package/frontend-build/node_modules/next/dist/build/static-paths/pages.js +169 -0
- package/frontend-build/node_modules/next/dist/build/static-paths/utils.js +119 -0
- package/frontend-build/node_modules/next/dist/build/swc/helpers.js +15 -0
- package/frontend-build/node_modules/next/dist/build/swc/index.js +1348 -0
- package/frontend-build/node_modules/next/dist/build/swc/install-bindings.js +30 -0
- package/frontend-build/node_modules/next/dist/build/swc/jest-transformer.js +76 -0
- package/frontend-build/node_modules/next/dist/build/swc/loaderWorkerPool.js +40 -0
- package/frontend-build/node_modules/next/dist/build/swc/options.js +403 -0
- package/frontend-build/node_modules/next/dist/build/swc/types.js +6 -0
- package/frontend-build/node_modules/next/dist/build/utils.js +1215 -0
- package/frontend-build/node_modules/next/dist/cli/next-test.js +170 -0
- package/frontend-build/node_modules/next/dist/client/add-base-path.js +24 -0
- package/frontend-build/node_modules/next/dist/client/app-call-server.js +34 -0
- package/frontend-build/node_modules/next/dist/client/app-find-source-map-url.js +39 -0
- package/frontend-build/node_modules/next/dist/client/assign-location.js +29 -0
- package/frontend-build/node_modules/next/dist/client/components/app-router-announcer.js +78 -0
- package/frontend-build/node_modules/next/dist/client/components/app-router-headers.js +138 -0
- package/frontend-build/node_modules/next/dist/client/components/app-router-instance.js +397 -0
- package/frontend-build/node_modules/next/dist/client/components/app-router-utils.js +62 -0
- package/frontend-build/node_modules/next/dist/client/components/app-router.js +514 -0
- package/frontend-build/node_modules/next/dist/client/components/builtin/default.js +35 -0
- package/frontend-build/node_modules/next/dist/client/components/builtin/error-styles.js +165 -0
- package/frontend-build/node_modules/next/dist/client/components/builtin/global-error.js +100 -0
- package/frontend-build/node_modules/next/dist/client/components/dev-root-http-access-fallback-boundary.js +52 -0
- package/frontend-build/node_modules/next/dist/client/components/error-boundary.js +144 -0
- package/frontend-build/node_modules/next/dist/client/components/errors/graceful-degrade-boundary.js +86 -0
- package/frontend-build/node_modules/next/dist/client/components/errors/root-error-boundary.js +41 -0
- package/frontend-build/node_modules/next/dist/client/components/forbidden.js +48 -0
- package/frontend-build/node_modules/next/dist/client/components/handle-isr-error.js +30 -0
- package/frontend-build/node_modules/next/dist/client/components/hooks-server-context.js +42 -0
- package/frontend-build/node_modules/next/dist/client/components/http-access-fallback/error-boundary.js +125 -0
- package/frontend-build/node_modules/next/dist/client/components/http-access-fallback/http-access-fallback.js +72 -0
- package/frontend-build/node_modules/next/dist/client/components/is-next-router-error.js +23 -0
- package/frontend-build/node_modules/next/dist/client/components/links.js +299 -0
- package/frontend-build/node_modules/next/dist/client/components/match-segments.js +32 -0
- package/frontend-build/node_modules/next/dist/client/components/nav-failure-handler.js +61 -0
- package/frontend-build/node_modules/next/dist/client/components/navigation-devtools.js +126 -0
- package/frontend-build/node_modules/next/dist/client/components/navigation-untracked.js +67 -0
- package/frontend-build/node_modules/next/dist/client/components/navigation.js +225 -0
- package/frontend-build/node_modules/next/dist/client/components/navigation.react-server.js +75 -0
- package/frontend-build/node_modules/next/dist/client/components/not-found.js +42 -0
- package/frontend-build/node_modules/next/dist/client/components/readonly-url-search-params.js +41 -0
- package/frontend-build/node_modules/next/dist/client/components/redirect-boundary.js +107 -0
- package/frontend-build/node_modules/next/dist/client/components/redirect-error.js +43 -0
- package/frontend-build/node_modules/next/dist/client/components/redirect-status-code.js +24 -0
- package/frontend-build/node_modules/next/dist/client/components/redirect.js +91 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/compute-changed-path.js +201 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/create-href-from-url.js +21 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/create-initial-router-state.js +153 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/create-router-cache-key.js +32 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/fetch-server-response.js +457 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/is-navigating-to-new-root-layout.js +59 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/ppr-navigations.js +1341 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/committed-state.js +49 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/find-head-in-cache.js +63 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/has-interception-route-in-current-tree.js +38 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/hmr-refresh-reducer.js +23 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/navigate-reducer.js +56 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/refresh-reducer.js +83 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/restore-reducer.js +62 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/server-action-reducer.js +320 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/reducers/server-patch-reducer.js +58 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/router-reducer-types.js +70 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/router-reducer.js +66 -0
- package/frontend-build/node_modules/next/dist/client/components/router-reducer/set-cache-busting-search-param.js +60 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/bfcache.js +128 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/cache-key.js +28 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/cache-map.js +305 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/cache.js +1933 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/lru.js +152 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/navigation-testing-lock.js +194 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/navigation.js +597 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/optimistic-routes.js +543 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/prefetch.js +31 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/scheduler.js +1249 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/types.js +69 -0
- package/frontend-build/node_modules/next/dist/client/components/segment-cache/vary-path.js +278 -0
- package/frontend-build/node_modules/next/dist/client/components/static-generation-bailout.js +42 -0
- package/frontend-build/node_modules/next/dist/client/components/unauthorized.js +49 -0
- package/frontend-build/node_modules/next/dist/client/components/unrecognized-action-error.js +39 -0
- package/frontend-build/node_modules/next/dist/client/components/unresolved-thenable.js +23 -0
- package/frontend-build/node_modules/next/dist/client/components/unstable-rethrow.browser.js +28 -0
- package/frontend-build/node_modules/next/dist/client/components/unstable-rethrow.js +25 -0
- package/frontend-build/node_modules/next/dist/client/components/unstable-rethrow.server.js +32 -0
- package/frontend-build/node_modules/next/dist/client/components/use-action-queue.js +148 -0
- package/frontend-build/node_modules/next/dist/client/dev/debug-channel.js +72 -0
- package/frontend-build/node_modules/next/dist/client/flight-data-helpers.js +232 -0
- package/frontend-build/node_modules/next/dist/client/has-base-path.js +23 -0
- package/frontend-build/node_modules/next/dist/client/lib/console.js +177 -0
- package/frontend-build/node_modules/next/dist/client/lib/javascript-url.js +32 -0
- package/frontend-build/node_modules/next/dist/client/navigation-build-id.js +53 -0
- package/frontend-build/node_modules/next/dist/client/normalize-trailing-slash.js +36 -0
- package/frontend-build/node_modules/next/dist/client/remove-base-path.js +32 -0
- package/frontend-build/node_modules/next/dist/client/route-params.js +230 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/cookies/index.js +339 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/cookies/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/ponyfill/index.js +46 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/ponyfill/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/abort-controller.js.text.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/console.js.text.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/events.js.text.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/index.js +5 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/load.js +18713 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/stream.js +44 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/timers.js.text.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@edge-runtime/primitives/url.js.text.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@hapi/accept/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@hapi/accept/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@mswjs/interceptors/ClientRequest/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@mswjs/interceptors/ClientRequest/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@napi-rs/triples/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@napi-rs/triples/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@opentelemetry/api/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/@opentelemetry/api/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/async-retry/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/async-retry/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/async-sema/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/async-sema/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/busboy/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/busboy/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/bytes/index.js +8 -0
- package/frontend-build/node_modules/next/dist/compiled/bytes/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ci-info/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ci-info/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/commander/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/commander/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/comment-json/index.js +7 -0
- package/frontend-build/node_modules/next/dist/compiled/comment-json/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/compression/index.js +58 -0
- package/frontend-build/node_modules/next/dist/compiled/compression/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/conf/index.js +15 -0
- package/frontend-build/node_modules/next/dist/compiled/conf/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/content-disposition/index.js +6 -0
- package/frontend-build/node_modules/next/dist/compiled/content-disposition/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/cookie/index.js +7 -0
- package/frontend-build/node_modules/next/dist/compiled/cookie/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/cross-spawn/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/cross-spawn/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/debug/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/debug/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/edge-runtime/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/edge-runtime/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/find-up/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/find-up/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/fresh/index.js +8 -0
- package/frontend-build/node_modules/next/dist/compiled/fresh/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/http-proxy/index.js +34 -0
- package/frontend-build/node_modules/next/dist/compiled/http-proxy/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/image-detector/detector.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/image-size/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/image-size/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ipaddr.js/ipaddr.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ipaddr.js/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-animated/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-animated/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-docker/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-docker/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-wsl/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/is-wsl/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/jsonwebtoken/index.js +11 -0
- package/frontend-build/node_modules/next/dist/compiled/jsonwebtoken/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/nanoid/index.cjs +1 -0
- package/frontend-build/node_modules/next/dist/compiled/nanoid/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +54 -0
- package/frontend-build/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +54 -0
- package/frontend-build/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +6 -0
- package/frontend-build/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +20 -0
- package/frontend-build/node_modules/next/dist/compiled/p-limit/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/p-limit/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/p-queue/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/p-queue/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/path-browserify/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/path-browserify/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/path-to-regexp/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/path-to-regexp/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/picomatch/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/picomatch/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/react-is/cjs/react-is.development.js +133 -0
- package/frontend-build/node_modules/next/dist/compiled/react-is/cjs/react-is.production.js +130 -0
- package/frontend-build/node_modules/next/dist/compiled/react-is/index.js +7 -0
- package/frontend-build/node_modules/next/dist/compiled/react-is/package.json +26 -0
- package/frontend-build/node_modules/next/dist/compiled/regenerator-runtime/package.json +19 -0
- package/frontend-build/node_modules/next/dist/compiled/regenerator-runtime/runtime.js +729 -0
- package/frontend-build/node_modules/next/dist/compiled/semver/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/semver/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/send/index.js +70 -0
- package/frontend-build/node_modules/next/dist/compiled/send/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/source-map/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/source-map/source-map.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/stacktrace-parser/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/stacktrace-parser/stack-trace-parser.cjs.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/string-hash/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/string-hash/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/strip-ansi/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/strip-ansi/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/superstruct/index.cjs +1 -0
- package/frontend-build/node_modules/next/dist/compiled/superstruct/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/tar/index.min.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/tar/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/text-table/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/text-table/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/watchpack/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/watchpack/watchpack.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ws/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/ws/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/zod/index.cjs +1 -0
- package/frontend-build/node_modules/next/dist/compiled/zod/package.json +1 -0
- package/frontend-build/node_modules/next/dist/compiled/zod-validation-error/index.js +1 -0
- package/frontend-build/node_modules/next/dist/compiled/zod-validation-error/package.json +1 -0
- package/frontend-build/node_modules/next/dist/experimental/testmode/context.js +57 -0
- package/frontend-build/node_modules/next/dist/experimental/testmode/fetch.js +142 -0
- package/frontend-build/node_modules/next/dist/experimental/testmode/httpget.js +26 -0
- package/frontend-build/node_modules/next/dist/experimental/testmode/server-edge.js +32 -0
- package/frontend-build/node_modules/next/dist/experimental/testmode/server.js +62 -0
- package/frontend-build/node_modules/next/dist/export/helpers/create-incremental-cache.js +61 -0
- package/frontend-build/node_modules/next/dist/lib/batcher.js +65 -0
- package/frontend-build/node_modules/next/dist/lib/build-custom-route.js +46 -0
- package/frontend-build/node_modules/next/dist/lib/bundler.js +97 -0
- package/frontend-build/node_modules/next/dist/lib/client-and-server-references.js +54 -0
- package/frontend-build/node_modules/next/dist/lib/coalesced-function.js +39 -0
- package/frontend-build/node_modules/next/dist/lib/compile-error.js +14 -0
- package/frontend-build/node_modules/next/dist/lib/constants.js +420 -0
- package/frontend-build/node_modules/next/dist/lib/create-client-router-filter.js +67 -0
- package/frontend-build/node_modules/next/dist/lib/default-transpiled-packages.json +1 -0
- package/frontend-build/node_modules/next/dist/lib/detached-promise.js +32 -0
- package/frontend-build/node_modules/next/dist/lib/detect-typo.js +51 -0
- package/frontend-build/node_modules/next/dist/lib/download-swc.js +183 -0
- package/frontend-build/node_modules/next/dist/lib/error-telemetry-utils.js +42 -0
- package/frontend-build/node_modules/next/dist/lib/fallback.js +100 -0
- package/frontend-build/node_modules/next/dist/lib/fatal-error.js +14 -0
- package/frontend-build/node_modules/next/dist/lib/file-exists.js +53 -0
- package/frontend-build/node_modules/next/dist/lib/find-config.js +102 -0
- package/frontend-build/node_modules/next/dist/lib/find-pages-dir.js +65 -0
- package/frontend-build/node_modules/next/dist/lib/find-root.js +126 -0
- package/frontend-build/node_modules/next/dist/lib/format-cli-help-output.js +84 -0
- package/frontend-build/node_modules/next/dist/lib/format-dynamic-import-path.js +24 -0
- package/frontend-build/node_modules/next/dist/lib/format-server-error.js +75 -0
- package/frontend-build/node_modules/next/dist/lib/framework/boundary-components.js +62 -0
- package/frontend-build/node_modules/next/dist/lib/framework/boundary-constants.js +36 -0
- package/frontend-build/node_modules/next/dist/lib/fs/rename.js +87 -0
- package/frontend-build/node_modules/next/dist/lib/fs/write-atomic.js +28 -0
- package/frontend-build/node_modules/next/dist/lib/generate-interception-routes-rewrites.js +52 -0
- package/frontend-build/node_modules/next/dist/lib/get-files-in-dir.js +33 -0
- package/frontend-build/node_modules/next/dist/lib/get-network-host.js +44 -0
- package/frontend-build/node_modules/next/dist/lib/get-package-version.js +118 -0
- package/frontend-build/node_modules/next/dist/lib/get-project-dir.js +51 -0
- package/frontend-build/node_modules/next/dist/lib/has-necessary-dependencies.js +49 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-cache-directory.js +66 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-npx-command.js +29 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-online.js +50 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-pkg-manager.js +63 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-registry.js +45 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/get-reserved-port.js +116 -0
- package/frontend-build/node_modules/next/dist/lib/helpers/install.js +83 -0
- package/frontend-build/node_modules/next/dist/lib/import-next-warning.js +50 -0
- package/frontend-build/node_modules/next/dist/lib/inline-static-env.js +112 -0
- package/frontend-build/node_modules/next/dist/lib/install-dependencies.js +40 -0
- package/frontend-build/node_modules/next/dist/lib/interop-default.js +16 -0
- package/frontend-build/node_modules/next/dist/lib/is-api-route.js +15 -0
- package/frontend-build/node_modules/next/dist/lib/is-app-page-route.js +15 -0
- package/frontend-build/node_modules/next/dist/lib/is-app-route-route.js +15 -0
- package/frontend-build/node_modules/next/dist/lib/is-edge-runtime.js +16 -0
- package/frontend-build/node_modules/next/dist/lib/is-error.js +78 -0
- package/frontend-build/node_modules/next/dist/lib/is-interception-route-rewrite.js +18 -0
- package/frontend-build/node_modules/next/dist/lib/is-internal-component.js +36 -0
- package/frontend-build/node_modules/next/dist/lib/is-serializable-props.js +106 -0
- package/frontend-build/node_modules/next/dist/lib/known-edge-safe-packages.json +1 -0
- package/frontend-build/node_modules/next/dist/lib/load-custom-routes.js +594 -0
- package/frontend-build/node_modules/next/dist/lib/memory/gc-observer.js +53 -0
- package/frontend-build/node_modules/next/dist/lib/memory/shutdown.js +29 -0
- package/frontend-build/node_modules/next/dist/lib/memory/startup.js +47 -0
- package/frontend-build/node_modules/next/dist/lib/memory/trace.js +109 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/constants.js +40 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/default-metadata.js +82 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/generate/icon-mark.js +22 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/generate/utils.js +52 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/get-metadata-route.js +123 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/is-metadata-route.js +221 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/metadata-context.js +18 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/metadata.js +1686 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolve-metadata.js +884 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolvers/resolve-basics.js +232 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolvers/resolve-icons.js +56 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolvers/resolve-opengraph.js +199 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolvers/resolve-title.js +40 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/resolvers/resolve-url.js +135 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/alternative-urls-types.js +7 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/extra-types.js +9 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/icons.js +6 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/manifest-types.js +6 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/metadata-interface.js +18 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/metadata-types.js +10 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/opengraph-types.js +6 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/resolvers.js +6 -0
- package/frontend-build/node_modules/next/dist/lib/metadata/types/twitter-types.js +7 -0
- package/frontend-build/node_modules/next/dist/lib/mime-type.js +20 -0
- package/frontend-build/node_modules/next/dist/lib/mkcert.js +204 -0
- package/frontend-build/node_modules/next/dist/lib/multi-file-writer.js +75 -0
- package/frontend-build/node_modules/next/dist/lib/needs-experimental-react.js +16 -0
- package/frontend-build/node_modules/next/dist/lib/non-nullable.js +15 -0
- package/frontend-build/node_modules/next/dist/lib/normalize-path.js +21 -0
- package/frontend-build/node_modules/next/dist/lib/oxford-comma-list.js +15 -0
- package/frontend-build/node_modules/next/dist/lib/page-types.js +18 -0
- package/frontend-build/node_modules/next/dist/lib/patch-incorrect-lockfile.js +185 -0
- package/frontend-build/node_modules/next/dist/lib/pick.js +19 -0
- package/frontend-build/node_modules/next/dist/lib/picocolors.js +177 -0
- package/frontend-build/node_modules/next/dist/lib/pretty-bytes.js +74 -0
- package/frontend-build/node_modules/next/dist/lib/realpath.js +20 -0
- package/frontend-build/node_modules/next/dist/lib/recursive-copy.js +76 -0
- package/frontend-build/node_modules/next/dist/lib/recursive-delete.js +137 -0
- package/frontend-build/node_modules/next/dist/lib/recursive-readdir.js +124 -0
- package/frontend-build/node_modules/next/dist/lib/redirect-status.js +46 -0
- package/frontend-build/node_modules/next/dist/lib/require-instrumentation-client.js +26 -0
- package/frontend-build/node_modules/next/dist/lib/resolve-build-paths.js +154 -0
- package/frontend-build/node_modules/next/dist/lib/resolve-from.js +65 -0
- package/frontend-build/node_modules/next/dist/lib/route-pattern-normalizer.js +107 -0
- package/frontend-build/node_modules/next/dist/lib/scheduler.js +64 -0
- package/frontend-build/node_modules/next/dist/lib/semver-noop.js +18 -0
- package/frontend-build/node_modules/next/dist/lib/server-external-packages.jsonc +103 -0
- package/frontend-build/node_modules/next/dist/lib/setup-exception-listeners.js +11 -0
- package/frontend-build/node_modules/next/dist/lib/static-env.js +92 -0
- package/frontend-build/node_modules/next/dist/lib/try-to-parse-path.js +67 -0
- package/frontend-build/node_modules/next/dist/lib/turbopack-warning.js +185 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/diagnosticFormatter.js +243 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/getTypeScriptConfiguration.js +153 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/getTypeScriptIntent.js +52 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/missingDependencyError.js +27 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/runTypeCheck.js +149 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/type-paths.js +51 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/writeAppTypeDeclarations.js +75 -0
- package/frontend-build/node_modules/next/dist/lib/typescript/writeConfigurationDefaults.js +395 -0
- package/frontend-build/node_modules/next/dist/lib/url.js +75 -0
- package/frontend-build/node_modules/next/dist/lib/verify-partytown-setup.js +115 -0
- package/frontend-build/node_modules/next/dist/lib/verify-root-layout.js +165 -0
- package/frontend-build/node_modules/next/dist/lib/verify-typescript-setup.js +228 -0
- package/frontend-build/node_modules/next/dist/lib/wait.js +19 -0
- package/frontend-build/node_modules/next/dist/lib/with-promise-cache.js +24 -0
- package/frontend-build/node_modules/next/dist/lib/worker.js +234 -0
- package/frontend-build/node_modules/next/dist/server/ReactDOMServerPages.js +16 -0
- package/frontend-build/node_modules/next/dist/server/accept-header.js +132 -0
- package/frontend-build/node_modules/next/dist/server/after/after-context.js +140 -0
- package/frontend-build/node_modules/next/dist/server/after/after.js +26 -0
- package/frontend-build/node_modules/next/dist/server/after/awaiter.js +74 -0
- package/frontend-build/node_modules/next/dist/server/after/builtin-request-context.js +38 -0
- package/frontend-build/node_modules/next/dist/server/after/index.js +21 -0
- package/frontend-build/node_modules/next/dist/server/after/run-with-after.js +35 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/get-cookie-parser.js +22 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/index.js +201 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/node/api-resolver.js +395 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/node/parse-body.js +79 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/node/try-get-preview-data.js +86 -0
- package/frontend-build/node_modules/next/dist/server/api-utils/web.js +17 -0
- package/frontend-build/node_modules/next/dist/server/app-render/action-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/action-async-storage.external.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/action-handler.js +1020 -0
- package/frontend-build/node_modules/next/dist/server/app-render/after-task-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/after-task-async-storage.external.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/app-render-prerender-utils.js +167 -0
- package/frontend-build/node_modules/next/dist/server/app-render/app-render-render-utils.js +76 -0
- package/frontend-build/node_modules/next/dist/server/app-render/app-render-scheduling.js +188 -0
- package/frontend-build/node_modules/next/dist/server/app-render/app-render.js +4469 -0
- package/frontend-build/node_modules/next/dist/server/app-render/async-local-storage.js +76 -0
- package/frontend-build/node_modules/next/dist/server/app-render/cache-signal.js +181 -0
- package/frontend-build/node_modules/next/dist/server/app-render/collect-segment-data.js +600 -0
- package/frontend-build/node_modules/next/dist/server/app-render/console-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/console-async-storage.external.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/create-component-styles-and-scripts.js +33 -0
- package/frontend-build/node_modules/next/dist/server/app-render/create-component-tree.js +840 -0
- package/frontend-build/node_modules/next/dist/server/app-render/create-error-handler.js +189 -0
- package/frontend-build/node_modules/next/dist/server/app-render/create-flight-router-state-from-loader-tree.js +102 -0
- package/frontend-build/node_modules/next/dist/server/app-render/csrf-protection.js +86 -0
- package/frontend-build/node_modules/next/dist/server/app-render/debug-channel-server.js +30 -0
- package/frontend-build/node_modules/next/dist/server/app-render/debug-channel-server.web.js +71 -0
- package/frontend-build/node_modules/next/dist/server/app-render/dynamic-access-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/dynamic-access-async-storage.external.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/dynamic-rendering.js +1144 -0
- package/frontend-build/node_modules/next/dist/server/app-render/encryption-utils-server.js +114 -0
- package/frontend-build/node_modules/next/dist/server/app-render/encryption-utils.js +93 -0
- package/frontend-build/node_modules/next/dist/server/app-render/encryption.js +259 -0
- package/frontend-build/node_modules/next/dist/server/app-render/entry-base.js +256 -0
- package/frontend-build/node_modules/next/dist/server/app-render/flight-render-result.js +28 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-asset-query-string.js +29 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-css-inlined-link-tags.js +49 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-layer-assets.js +65 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-preloadable-fonts.js +39 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-script-nonce-from-header.js +44 -0
- package/frontend-build/node_modules/next/dist/server/app-render/get-short-dynamic-param-type.js +25 -0
- package/frontend-build/node_modules/next/dist/server/app-render/has-loading-component-in-tree.js +19 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/boundary-constants.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/boundary-impl.js +103 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/boundary-tracking.js +18 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/instant-config.js +181 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/instant-samples-client.js +128 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/instant-samples.js +432 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/instant-validation-error.js +33 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/instant-validation.js +713 -0
- package/frontend-build/node_modules/next/dist/server/app-render/instant-validation/stream-utils.js +96 -0
- package/frontend-build/node_modules/next/dist/server/app-render/interop-default.js +17 -0
- package/frontend-build/node_modules/next/dist/server/app-render/make-get-server-inserted-html.js +92 -0
- package/frontend-build/node_modules/next/dist/server/app-render/manifests-singleton.js +264 -0
- package/frontend-build/node_modules/next/dist/server/app-render/metadata-insertion/create-server-inserted-metadata.js +28 -0
- package/frontend-build/node_modules/next/dist/server/app-render/module-loading/track-dynamic-import.js +57 -0
- package/frontend-build/node_modules/next/dist/server/app-render/module-loading/track-module-loading.external.js +32 -0
- package/frontend-build/node_modules/next/dist/server/app-render/module-loading/track-module-loading.instance.js +66 -0
- package/frontend-build/node_modules/next/dist/server/app-render/parse-and-validate-flight-router-state.js +49 -0
- package/frontend-build/node_modules/next/dist/server/app-render/postponed-state.js +157 -0
- package/frontend-build/node_modules/next/dist/server/app-render/prospective-render-utils.js +74 -0
- package/frontend-build/node_modules/next/dist/server/app-render/react-large-shell-error.js +17 -0
- package/frontend-build/node_modules/next/dist/server/app-render/react-server.node.js +39 -0
- package/frontend-build/node_modules/next/dist/server/app-render/render-css-resource.js +52 -0
- package/frontend-build/node_modules/next/dist/server/app-render/required-scripts.js +76 -0
- package/frontend-build/node_modules/next/dist/server/app-render/rsc/postpone.js +18 -0
- package/frontend-build/node_modules/next/dist/server/app-render/rsc/preloads.js +74 -0
- package/frontend-build/node_modules/next/dist/server/app-render/rsc/taint.js +79 -0
- package/frontend-build/node_modules/next/dist/server/app-render/segment-explorer-path.js +128 -0
- package/frontend-build/node_modules/next/dist/server/app-render/server-inserted-html.js +77 -0
- package/frontend-build/node_modules/next/dist/server/app-render/staged-rendering.js +343 -0
- package/frontend-build/node_modules/next/dist/server/app-render/stale-time.js +111 -0
- package/frontend-build/node_modules/next/dist/server/app-render/stream-ops.js +106 -0
- package/frontend-build/node_modules/next/dist/server/app-render/stream-ops.web.js +163 -0
- package/frontend-build/node_modules/next/dist/server/app-render/strip-flight-headers.js +18 -0
- package/frontend-build/node_modules/next/dist/server/app-render/types.js +65 -0
- package/frontend-build/node_modules/next/dist/server/app-render/use-flight-response.js +214 -0
- package/frontend-build/node_modules/next/dist/server/app-render/vary-params.js +336 -0
- package/frontend-build/node_modules/next/dist/server/app-render/walk-tree-with-flight-router-state.js +232 -0
- package/frontend-build/node_modules/next/dist/server/app-render/work-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/work-async-storage.external.js +13 -0
- package/frontend-build/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.js +14 -0
- package/frontend-build/node_modules/next/dist/server/app-render/work-unit-async-storage.external.js +280 -0
- package/frontend-build/node_modules/next/dist/server/async-storage/draft-mode-provider.js +62 -0
- package/frontend-build/node_modules/next/dist/server/async-storage/request-store.js +144 -0
- package/frontend-build/node_modules/next/dist/server/async-storage/with-store.js +6 -0
- package/frontend-build/node_modules/next/dist/server/async-storage/work-store.js +91 -0
- package/frontend-build/node_modules/next/dist/server/base-http/helpers.js +36 -0
- package/frontend-build/node_modules/next/dist/server/base-http/index.js +54 -0
- package/frontend-build/node_modules/next/dist/server/base-http/node.js +147 -0
- package/frontend-build/node_modules/next/dist/server/base-http/web.js +124 -0
- package/frontend-build/node_modules/next/dist/server/base-server.js +1874 -0
- package/frontend-build/node_modules/next/dist/server/body-streams.js +114 -0
- package/frontend-build/node_modules/next/dist/server/cache-dir.js +26 -0
- package/frontend-build/node_modules/next/dist/server/capsize-font-metrics.json +181516 -0
- package/frontend-build/node_modules/next/dist/server/ci-info.js +41 -0
- package/frontend-build/node_modules/next/dist/server/client-component-renderer-logger.js +70 -0
- package/frontend-build/node_modules/next/dist/server/config-schema.js +718 -0
- package/frontend-build/node_modules/next/dist/server/config-shared.js +369 -0
- package/frontend-build/node_modules/next/dist/server/config-utils.js +185 -0
- package/frontend-build/node_modules/next/dist/server/config.js +1545 -0
- package/frontend-build/node_modules/next/dist/server/create-deduped-by-callsite-server-error-logger.js +96 -0
- package/frontend-build/node_modules/next/dist/server/crypto-utils.js +70 -0
- package/frontend-build/node_modules/next/dist/server/dev/browser-logs/file-logger.js +186 -0
- package/frontend-build/node_modules/next/dist/server/dev/browser-logs/receive-logs.js +558 -0
- package/frontend-build/node_modules/next/dist/server/dev/browser-logs/source-map.js +222 -0
- package/frontend-build/node_modules/next/dist/server/dev/debug-channel.js +87 -0
- package/frontend-build/node_modules/next/dist/server/dev/dev-indicator-server-state.js +15 -0
- package/frontend-build/node_modules/next/dist/server/dev/get-source-map-from-file.js +100 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-middleware.js +274 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-reloader-rspack.js +171 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-reloader-shared-utils.js +56 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +1480 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-reloader-types.js +58 -0
- package/frontend-build/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1386 -0
- package/frontend-build/node_modules/next/dist/server/dev/log-requests.js +149 -0
- package/frontend-build/node_modules/next/dist/server/dev/messages.js +74 -0
- package/frontend-build/node_modules/next/dist/server/dev/middleware-turbopack.js +403 -0
- package/frontend-build/node_modules/next/dist/server/dev/middleware-webpack.js +483 -0
- package/frontend-build/node_modules/next/dist/server/dev/node-stack-frames.js +72 -0
- package/frontend-build/node_modules/next/dist/server/dev/on-demand-entry-handler.js +773 -0
- package/frontend-build/node_modules/next/dist/server/dev/parse-version-info.js +108 -0
- package/frontend-build/node_modules/next/dist/server/dev/require-cache.js +79 -0
- package/frontend-build/node_modules/next/dist/server/dev/serialized-errors.js +67 -0
- package/frontend-build/node_modules/next/dist/server/dev/server-action-logger.js +37 -0
- package/frontend-build/node_modules/next/dist/server/dev/static-paths-worker.js +104 -0
- package/frontend-build/node_modules/next/dist/server/dev/turbopack-utils.js +687 -0
- package/frontend-build/node_modules/next/dist/server/dynamic-rendering-utils.js +108 -0
- package/frontend-build/node_modules/next/dist/server/font-utils.js +43 -0
- package/frontend-build/node_modules/next/dist/server/get-app-route-from-entrypoint.js +30 -0
- package/frontend-build/node_modules/next/dist/server/get-page-files.js +23 -0
- package/frontend-build/node_modules/next/dist/server/get-route-from-entrypoint.js +35 -0
- package/frontend-build/node_modules/next/dist/server/htmlescape.js +37 -0
- package/frontend-build/node_modules/next/dist/server/image-optimizer.js +1220 -0
- package/frontend-build/node_modules/next/dist/server/instrumentation/types.js +6 -0
- package/frontend-build/node_modules/next/dist/server/instrumentation/utils.js +21 -0
- package/frontend-build/node_modules/next/dist/server/internal-utils.js +39 -0
- package/frontend-build/node_modules/next/dist/server/is-private-ip.js +36 -0
- package/frontend-build/node_modules/next/dist/server/lib/app-dir-module.js +59 -0
- package/frontend-build/node_modules/next/dist/server/lib/app-info-log.js +132 -0
- package/frontend-build/node_modules/next/dist/server/lib/async-callback-set.js +29 -0
- package/frontend-build/node_modules/next/dist/server/lib/cache-control.js +22 -0
- package/frontend-build/node_modules/next/dist/server/lib/cache-handlers/default.external.js +18 -0
- package/frontend-build/node_modules/next/dist/server/lib/cache-handlers/default.js +160 -0
- package/frontend-build/node_modules/next/dist/server/lib/cache-handlers/types.js +8 -0
- package/frontend-build/node_modules/next/dist/server/lib/chrome-devtools-workspace.js +116 -0
- package/frontend-build/node_modules/next/dist/server/lib/clone-response.js +77 -0
- package/frontend-build/node_modules/next/dist/server/lib/cpu-profile.js +59 -0
- package/frontend-build/node_modules/next/dist/server/lib/decode-query-path-parameter.js +26 -0
- package/frontend-build/node_modules/next/dist/server/lib/dedupe-fetch.js +163 -0
- package/frontend-build/node_modules/next/dist/server/lib/dev-bundler-service.js +95 -0
- package/frontend-build/node_modules/next/dist/server/lib/disk-lru-cache.external.js +57 -0
- package/frontend-build/node_modules/next/dist/server/lib/etag.js +56 -0
- package/frontend-build/node_modules/next/dist/server/lib/experimental/create-env-definitions.js +48 -0
- package/frontend-build/node_modules/next/dist/server/lib/experimental/ppr.js +47 -0
- package/frontend-build/node_modules/next/dist/server/lib/find-page-file.js +147 -0
- package/frontend-build/node_modules/next/dist/server/lib/fix-mojibake.js +25 -0
- package/frontend-build/node_modules/next/dist/server/lib/format-hostname.js +16 -0
- package/frontend-build/node_modules/next/dist/server/lib/i18n-provider.js +129 -0
- package/frontend-build/node_modules/next/dist/server/lib/implicit-tags.js +77 -0
- package/frontend-build/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js +335 -0
- package/frontend-build/node_modules/next/dist/server/lib/incremental-cache/index.js +501 -0
- package/frontend-build/node_modules/next/dist/server/lib/incremental-cache/memory-cache.external.js +57 -0
- package/frontend-build/node_modules/next/dist/server/lib/incremental-cache/shared-cache-controls.external.js +73 -0
- package/frontend-build/node_modules/next/dist/server/lib/incremental-cache/tags-manifest.external.js +55 -0
- package/frontend-build/node_modules/next/dist/server/lib/install-code-frame.js +22 -0
- package/frontend-build/node_modules/next/dist/server/lib/is-ipv6.js +41 -0
- package/frontend-build/node_modules/next/dist/server/lib/lazy-result.js +46 -0
- package/frontend-build/node_modules/next/dist/server/lib/lru-cache.js +191 -0
- package/frontend-build/node_modules/next/dist/server/lib/match-next-data-pathname.js +18 -0
- package/frontend-build/node_modules/next/dist/server/lib/mock-request.js +416 -0
- package/frontend-build/node_modules/next/dist/server/lib/module-loader/module-loader.js +8 -0
- package/frontend-build/node_modules/next/dist/server/lib/module-loader/node-module-loader.js +25 -0
- package/frontend-build/node_modules/next/dist/server/lib/module-loader/route-module-loader.js +26 -0
- package/frontend-build/node_modules/next/dist/server/lib/node-fs-methods.js +28 -0
- package/frontend-build/node_modules/next/dist/server/lib/parse-stack.js +46 -0
- package/frontend-build/node_modules/next/dist/server/lib/patch-fetch.js +978 -0
- package/frontend-build/node_modules/next/dist/server/lib/patch-set-header.js +38 -0
- package/frontend-build/node_modules/next/dist/server/lib/postponed-request-body.js +64 -0
- package/frontend-build/node_modules/next/dist/server/lib/render-server.js +155 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-server.js +696 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/block-cross-site-dev.js +110 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/build-data-route.js +48 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.js +50 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/cache-life-type-utils.js +211 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/decode-path-params.js +42 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/filesystem.js +591 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js +89 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/instrumentation-node-extensions.js +96 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/is-postpone.js +16 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/proxy-request.js +118 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/resolve-routes.js +629 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/route-types-utils.js +286 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/router-server-context.js +26 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/typegen.js +858 -0
- package/frontend-build/node_modules/next/dist/server/lib/router-utils/types.js +6 -0
- package/frontend-build/node_modules/next/dist/server/lib/server-action-request-meta.js +53 -0
- package/frontend-build/node_modules/next/dist/server/lib/server-ipc/utils.js +81 -0
- package/frontend-build/node_modules/next/dist/server/lib/source-maps.js +196 -0
- package/frontend-build/node_modules/next/dist/server/lib/start-server.js +494 -0
- package/frontend-build/node_modules/next/dist/server/lib/streaming-metadata.js +38 -0
- package/frontend-build/node_modules/next/dist/server/lib/to-route.js +37 -0
- package/frontend-build/node_modules/next/dist/server/lib/trace/constants.js +203 -0
- package/frontend-build/node_modules/next/dist/server/lib/trace/tracer.js +280 -0
- package/frontend-build/node_modules/next/dist/server/lib/trace/utils.js +16 -0
- package/frontend-build/node_modules/next/dist/server/lib/types.js +6 -0
- package/frontend-build/node_modules/next/dist/server/lib/utils.js +278 -0
- package/frontend-build/node_modules/next/dist/server/lib/worker-utils.js +36 -0
- package/frontend-build/node_modules/next/dist/server/load-components.js +179 -0
- package/frontend-build/node_modules/next/dist/server/load-default-error-components.js +41 -0
- package/frontend-build/node_modules/next/dist/server/load-manifest.external.js +117 -0
- package/frontend-build/node_modules/next/dist/server/match-bundle.js +25 -0
- package/frontend-build/node_modules/next/dist/server/mcp/get-mcp-middleware.js +49 -0
- package/frontend-build/node_modules/next/dist/server/mcp/get-or-create-mcp-server.js +41 -0
- package/frontend-build/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.js +82 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-errors.js +114 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-logs.js +67 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-page-metadata.js +188 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-project-metadata.js +59 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-routes.js +136 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js +121 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/next-instance-error-state.js +31 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/utils/browser-communication.js +90 -0
- package/frontend-build/node_modules/next/dist/server/mcp/tools/utils/format-errors.js +137 -0
- package/frontend-build/node_modules/next/dist/server/next-server.js +1429 -0
- package/frontend-build/node_modules/next/dist/server/next-typescript.js +13 -0
- package/frontend-build/node_modules/next/dist/server/next.js +455 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-baseline.js +25 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/console-dim.external.js +301 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/console-exit.js +49 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/console-file.js +56 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/date.js +52 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/error-inspect.js +8 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/fast-set-immediate.external.js +577 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/global-behaviors.js +33 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/io-utils.js +195 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/node-crypto.js +103 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/process-error-handlers.js +91 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/random.js +28 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/unhandled-rejection.external.js +508 -0
- package/frontend-build/node_modules/next/dist/server/node-environment-extensions/web-crypto.js +45 -0
- package/frontend-build/node_modules/next/dist/server/node-environment.js +19 -0
- package/frontend-build/node_modules/next/dist/server/node-polyfill-crypto.js +21 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/absolute-filename-normalizer.js +33 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/app/app-bundle-path-normalizer.js +54 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/app/app-filename-normalizer.js +22 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/app/app-page-normalizer.js +40 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/app/app-pathname-normalizer.js +55 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/app/index.js +42 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/pages/index.js +44 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/pages/pages-bundle-path-normalizer.js +55 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/pages/pages-filename-normalizer.js +22 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/pages/pages-page-normalizer.js +19 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/built/pages/pages-pathname-normalizer.js +19 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/locale-route-normalizer.js +26 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/normalizer.js +6 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/normalizers.js +23 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/prefixing-normalizer.js +26 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/base-path.js +25 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/next-data.js +38 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/pathname-normalizer.js +6 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/prefix.js +39 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/rsc.js +19 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.js +33 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/request/suffix.js +27 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/underscore-normalizer.js +17 -0
- package/frontend-build/node_modules/next/dist/server/normalizers/wrap-normalizer-fn.js +17 -0
- package/frontend-build/node_modules/next/dist/server/og/image-response.js +53 -0
- package/frontend-build/node_modules/next/dist/server/patch-error-inspect.js +453 -0
- package/frontend-build/node_modules/next/dist/server/pipe-readable.js +140 -0
- package/frontend-build/node_modules/next/dist/server/post-process.js +39 -0
- package/frontend-build/node_modules/next/dist/server/render-result.js +204 -0
- package/frontend-build/node_modules/next/dist/server/render.js +1141 -0
- package/frontend-build/node_modules/next/dist/server/request/connection.js +133 -0
- package/frontend-build/node_modules/next/dist/server/request/cookies.js +235 -0
- package/frontend-build/node_modules/next/dist/server/request/draft-mode.js +230 -0
- package/frontend-build/node_modules/next/dist/server/request/fallback-params.js +69 -0
- package/frontend-build/node_modules/next/dist/server/request/headers.js +229 -0
- package/frontend-build/node_modules/next/dist/server/request/params.js +527 -0
- package/frontend-build/node_modules/next/dist/server/request/pathname.js +119 -0
- package/frontend-build/node_modules/next/dist/server/request/root-params.js +194 -0
- package/frontend-build/node_modules/next/dist/server/request/search-params.js +526 -0
- package/frontend-build/node_modules/next/dist/server/request/utils.js +51 -0
- package/frontend-build/node_modules/next/dist/server/request-meta.js +55 -0
- package/frontend-build/node_modules/next/dist/server/require-hook.js +82 -0
- package/frontend-build/node_modules/next/dist/server/require.js +109 -0
- package/frontend-build/node_modules/next/dist/server/response-cache/index.js +311 -0
- package/frontend-build/node_modules/next/dist/server/response-cache/types.js +41 -0
- package/frontend-build/node_modules/next/dist/server/response-cache/utils.js +104 -0
- package/frontend-build/node_modules/next/dist/server/response-cache/web.js +101 -0
- package/frontend-build/node_modules/next/dist/server/resume-data-cache/cache-store.js +96 -0
- package/frontend-build/node_modules/next/dist/server/resume-data-cache/resume-data-cache.js +124 -0
- package/frontend-build/node_modules/next/dist/server/revalidation-utils.js +157 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/app-page-route-definition.js +16 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/app-route-route-definition.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/locale-route-definition.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/pages-api-route-definition.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/pages-route-definition.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-definitions/route-definition.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-kind.js +32 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-managers/default-route-matcher-manager.js +239 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-managers/dev-route-matcher-manager.js +120 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/app-page-route-matcher-provider.js +55 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/app-route-route-matcher-provider.js +43 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/dev-app-page-route-matcher-provider.js +91 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/dev-app-route-route-matcher-provider.js +112 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/dev-pages-api-route-matcher-provider.js +77 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/dev-pages-route-matcher-provider.js +77 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/file-cache-route-matcher-provider.js +28 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/helpers/file-reader/batched-file-reader.js +106 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/helpers/file-reader/default-file-reader.js +42 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/dev/helpers/file-reader/file-reader.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/helpers/cached-route-matcher-provider.js +30 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/helpers/manifest-loaders/manifest-loader.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/helpers/manifest-loaders/node-manifest-loader.js +34 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/helpers/manifest-loaders/server-manifest-loader.js +20 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/manifest-route-matcher-provider.js +21 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/pages-api-route-matcher-provider.js +55 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/pages-route-matcher-provider.js +64 -0
- package/frontend-build/node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/app-page-route-matcher.js +18 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/app-route-route-matcher.js +15 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/locale-route-matcher.js +68 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/pages-api-route-matcher.js +30 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/pages-route-matcher.js +30 -0
- package/frontend-build/node_modules/next/dist/server/route-matchers/route-matcher.js +54 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/app-page-route-match.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/app-route-route-match.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/locale-route-match.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/pages-api-route-match.js +16 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/pages-route-match.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-matches/route-match.js +6 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/helpers/prerender-manifest-matcher.js +51 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/module.compiled.js +36 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/module.js +162 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/module.render.js +24 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/normalize-request-url.js +25 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/app-router-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.js +87 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/head-manager-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/hooks-client-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/image-config-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/router-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/server-inserted-html.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.js +140 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-dom.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-turbopack-server.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-turbopack-static.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-server.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-static.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.js +125 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-compiler-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-dom-server.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-dom.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-jsx-dev-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-jsx-runtime.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-server-dom-turbopack-client.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-server-dom-webpack-client.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/helpers/auto-implement-methods.js +85 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/helpers/clean-url.js +24 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/helpers/get-pathname-from-absolute-path.js +29 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/helpers/is-static-gen-enabled.js +15 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/helpers/parsed-url-query-to-params.js +20 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/module.compiled.js +36 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/module.js +914 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/app-route/shared-modules.js +56 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/checks.js +45 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/builtin/_error.js +100 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/module.compiled.js +20 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/module.js +92 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/module.render.js +24 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/pages-handler.js +545 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/app-router-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.js +102 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/head-manager-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/hooks-client-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/html-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/image-config-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/router-context.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages/vendored/contexts/server-inserted-html.js +4 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages-api/module.compiled.js +20 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/pages-api/module.js +58 -0
- package/frontend-build/node_modules/next/dist/server/route-modules/route-module.js +650 -0
- package/frontend-build/node_modules/next/dist/server/runtime-reacts.external.js +46 -0
- package/frontend-build/node_modules/next/dist/server/send-payload.js +88 -0
- package/frontend-build/node_modules/next/dist/server/send-response.js +70 -0
- package/frontend-build/node_modules/next/dist/server/serve-static.js +66 -0
- package/frontend-build/node_modules/next/dist/server/server-route-utils.js +30 -0
- package/frontend-build/node_modules/next/dist/server/server-utils.js +323 -0
- package/frontend-build/node_modules/next/dist/server/setup-http-agent-env.js +31 -0
- package/frontend-build/node_modules/next/dist/server/stream-utils/encoded-tags.js +122 -0
- package/frontend-build/node_modules/next/dist/server/stream-utils/node-web-streams-helper.js +918 -0
- package/frontend-build/node_modules/next/dist/server/stream-utils/uint8array-helpers.js +74 -0
- package/frontend-build/node_modules/next/dist/server/typescript/constant.js +98 -0
- package/frontend-build/node_modules/next/dist/server/typescript/index.js +199 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/client-boundary.js +97 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/config.js +512 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/entry.js +149 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/error.js +38 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/metadata.js +234 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/server-boundary.js +115 -0
- package/frontend-build/node_modules/next/dist/server/typescript/rules/server.js +79 -0
- package/frontend-build/node_modules/next/dist/server/typescript/utils.js +212 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/cache-life.js +163 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/cache-tag.js +52 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/constants.js +28 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/handlers.js +121 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/use-cache-errors.js +36 -0
- package/frontend-build/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1588 -0
- package/frontend-build/node_modules/next/dist/server/utils.js +73 -0
- package/frontend-build/node_modules/next/dist/server/web/adapter.js +392 -0
- package/frontend-build/node_modules/next/dist/server/web/edge-route-module-wrapper.js +123 -0
- package/frontend-build/node_modules/next/dist/server/web/error.js +54 -0
- package/frontend-build/node_modules/next/dist/server/web/exports/index.js +56 -0
- package/frontend-build/node_modules/next/dist/server/web/get-edge-preview-props.js +23 -0
- package/frontend-build/node_modules/next/dist/server/web/globals.js +128 -0
- package/frontend-build/node_modules/next/dist/server/web/http.js +39 -0
- package/frontend-build/node_modules/next/dist/server/web/internal-edge-wait-until.js +64 -0
- package/frontend-build/node_modules/next/dist/server/web/next-url.js +199 -0
- package/frontend-build/node_modules/next/dist/server/web/sandbox/context.js +462 -0
- package/frontend-build/node_modules/next/dist/server/web/sandbox/fetch-inline-assets.js +35 -0
- package/frontend-build/node_modules/next/dist/server/web/sandbox/index.js +28 -0
- package/frontend-build/node_modules/next/dist/server/web/sandbox/resource-managers.js +88 -0
- package/frontend-build/node_modules/next/dist/server/web/sandbox/sandbox.js +137 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/adapters/headers.js +192 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/adapters/next-request.js +142 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/adapters/reflect.js +30 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.js +211 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/cookies.js +29 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/fetch-event.js +98 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/image-response.js +22 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/request.js +99 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/response.js +136 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/revalidate.js +214 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/unstable-cache.js +289 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/unstable-no-store.js +51 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/url-pattern.js +14 -0
- package/frontend-build/node_modules/next/dist/server/web/spec-extension/user-agent.js +46 -0
- package/frontend-build/node_modules/next/dist/server/web/types.js +6 -0
- package/frontend-build/node_modules/next/dist/server/web/utils.js +151 -0
- package/frontend-build/node_modules/next/dist/server/web/web-on-close.js +87 -0
- package/frontend-build/node_modules/next/dist/shared/lib/action-revalidation-kind.js +31 -0
- package/frontend-build/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.js +50 -0
- package/frontend-build/node_modules/next/dist/shared/lib/app-router-types.js +46 -0
- package/frontend-build/node_modules/next/dist/shared/lib/constants.js +448 -0
- package/frontend-build/node_modules/next/dist/shared/lib/deep-freeze.js +30 -0
- package/frontend-build/node_modules/next/dist/shared/lib/deployment-id.js +63 -0
- package/frontend-build/node_modules/next/dist/shared/lib/dset.js +34 -0
- package/frontend-build/node_modules/next/dist/shared/lib/encode-uri-path.js +15 -0
- package/frontend-build/node_modules/next/dist/shared/lib/entry-constants.js +36 -0
- package/frontend-build/node_modules/next/dist/shared/lib/error-source.js +36 -0
- package/frontend-build/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +39 -0
- package/frontend-build/node_modules/next/dist/shared/lib/errors/code-frame.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/errors/constants.js +19 -0
- package/frontend-build/node_modules/next/dist/shared/lib/errors/empty-generate-static-params-error.js +24 -0
- package/frontend-build/node_modules/next/dist/shared/lib/errors/hard-deprecated-config-error.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/escape-regexp.js +22 -0
- package/frontend-build/node_modules/next/dist/shared/lib/get-hostname.js +23 -0
- package/frontend-build/node_modules/next/dist/shared/lib/hash.js +42 -0
- package/frontend-build/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/head.js +163 -0
- package/frontend-build/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.js +60 -0
- package/frontend-build/node_modules/next/dist/shared/lib/html-context.shared-runtime.js +40 -0
- package/frontend-build/node_modules/next/dist/shared/lib/i18n/detect-domain-locale.js +25 -0
- package/frontend-build/node_modules/next/dist/shared/lib/i18n/get-locale-redirect.js +59 -0
- package/frontend-build/node_modules/next/dist/shared/lib/i18n/normalize-locale-path.js +54 -0
- package/frontend-build/node_modules/next/dist/shared/lib/image-blur-svg.js +22 -0
- package/frontend-build/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.js +19 -0
- package/frontend-build/node_modules/next/dist/shared/lib/image-config.js +77 -0
- package/frontend-build/node_modules/next/dist/shared/lib/invariant-error.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/is-plain-object.js +42 -0
- package/frontend-build/node_modules/next/dist/shared/lib/is-thenable.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/isomorphic/path.js +14 -0
- package/frontend-build/node_modules/next/dist/shared/lib/lazy-dynamic/bailout-to-csr.js +37 -0
- package/frontend-build/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.js +19 -0
- package/frontend-build/node_modules/next/dist/shared/lib/loadable.shared-runtime.js +246 -0
- package/frontend-build/node_modules/next/dist/shared/lib/match-local-pattern.js +46 -0
- package/frontend-build/node_modules/next/dist/shared/lib/match-remote-pattern.js +63 -0
- package/frontend-build/node_modules/next/dist/shared/lib/modern-browserslist-target.js +15 -0
- package/frontend-build/node_modules/next/dist/shared/lib/no-fallback-error.external.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/normalized-asset-prefix.js +28 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/absolute-path-to-page.js +26 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/denormalize-page-path.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/ensure-leading-slash.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/get-page-paths.js +40 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/normalize-data-path.js +23 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/normalize-page-path.js +26 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/normalize-path-sep.js +19 -0
- package/frontend-build/node_modules/next/dist/shared/lib/page-path/remove-page-path-tail.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/promise-with-resolvers.js +26 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/adapters.js +136 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/routes/app.js +122 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/add-locale.js +28 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/add-path-prefix.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/add-path-suffix.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/app-paths.js +62 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/as-path-to-search-params.js +17 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/cache-busting-search-param.js +24 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/escape-path-delimiters.js +16 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/format-next-pathname-info.js +27 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/format-url.js +111 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/get-dynamic-param.js +174 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/get-next-pathname-info.js +52 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/get-route-from-asset-path.js +25 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/get-segment-param.js +90 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/html-bots.js +17 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/index.js +30 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/interception-prefix-from-param-type.js +33 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/interception-routes.js +108 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/is-bot.js +57 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/is-dynamic.js +26 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.js +31 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/parse-loader-tree.js +30 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/parse-path.js +33 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.js +43 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/parse-url.js +38 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/path-has-prefix.js +20 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/path-match.js +49 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/prepare-destination.js +292 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/querystring.js +79 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/relativize-url.js +40 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/remove-path-prefix.js +39 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/remove-trailing-slash.js +21 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/resolve-param-value.js +116 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/route-match-utils.js +113 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/route-matcher.js +45 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/route-regex.js +256 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router/utils/sorted-routes.js +244 -0
- package/frontend-build/node_modules/next/dist/shared/lib/router-context.shared-runtime.js +18 -0
- package/frontend-build/node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.js +99 -0
- package/frontend-build/node_modules/next/dist/shared/lib/segment-cache/vary-params-decoding.js +32 -0
- package/frontend-build/node_modules/next/dist/shared/lib/segment.js +102 -0
- package/frontend-build/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.js +35 -0
- package/frontend-build/node_modules/next/dist/shared/lib/server-reference-info.js +56 -0
- package/frontend-build/node_modules/next/dist/shared/lib/side-effect.js +63 -0
- package/frontend-build/node_modules/next/dist/shared/lib/size-limit.js +40 -0
- package/frontend-build/node_modules/next/dist/shared/lib/turbopack/internal-error.js +53 -0
- package/frontend-build/node_modules/next/dist/shared/lib/utils/reflect-utils.js +69 -0
- package/frontend-build/node_modules/next/dist/shared/lib/utils/warn-once.js +22 -0
- package/frontend-build/node_modules/next/dist/shared/lib/utils.js +207 -0
- package/frontend-build/node_modules/next/dist/shared/lib/zod.js +101 -0
- package/frontend-build/node_modules/next/dist/telemetry/anonymous-meta.js +89 -0
- package/frontend-build/node_modules/next/dist/telemetry/detached-flush.js +56 -0
- package/frontend-build/node_modules/next/dist/telemetry/events/build.js +174 -0
- package/frontend-build/node_modules/next/dist/telemetry/events/index.js +41 -0
- package/frontend-build/node_modules/next/dist/telemetry/events/plugins.js +51 -0
- package/frontend-build/node_modules/next/dist/telemetry/events/swc-load-failure.js +55 -0
- package/frontend-build/node_modules/next/dist/telemetry/events/version.js +66 -0
- package/frontend-build/node_modules/next/dist/telemetry/flush-telemetry.js +19 -0
- package/frontend-build/node_modules/next/dist/telemetry/post-telemetry-payload.js +48 -0
- package/frontend-build/node_modules/next/dist/telemetry/project-id.js +48 -0
- package/frontend-build/node_modules/next/dist/telemetry/storage.js +301 -0
- package/frontend-build/node_modules/next/dist/trace/index.js +58 -0
- package/frontend-build/node_modules/next/dist/trace/report/index.js +37 -0
- package/frontend-build/node_modules/next/dist/trace/report/to-json-build.js +40 -0
- package/frontend-build/node_modules/next/dist/trace/report/to-json.js +165 -0
- package/frontend-build/node_modules/next/dist/trace/report/to-telemetry.js +36 -0
- package/frontend-build/node_modules/next/dist/trace/shared.js +39 -0
- package/frontend-build/node_modules/next/dist/trace/trace.js +211 -0
- package/frontend-build/node_modules/next/package.json +378 -0
- package/frontend-build/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
- package/frontend-build/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
- package/frontend-build/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
- package/frontend-build/node_modules/react/cjs/react.development.js +1284 -0
- package/frontend-build/node_modules/react/cjs/react.production.js +542 -0
- package/frontend-build/node_modules/react/compiler-runtime.js +14 -0
- package/frontend-build/node_modules/react/index.js +7 -0
- package/frontend-build/node_modules/react/jsx-dev-runtime.js +7 -0
- package/frontend-build/node_modules/react/jsx-runtime.js +7 -0
- package/frontend-build/node_modules/react/package.json +51 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +6603 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +6692 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom-server.browser.production.js +7410 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom-server.edge.production.js +7512 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom-server.node.production.js +7707 -0
- package/frontend-build/node_modules/react-dom/cjs/react-dom.production.js +210 -0
- package/frontend-build/node_modules/react-dom/index.js +38 -0
- package/frontend-build/node_modules/react-dom/package.json +117 -0
- package/frontend-build/node_modules/react-dom/server.browser.js +16 -0
- package/frontend-build/node_modules/react-dom/server.edge.js +17 -0
- package/frontend-build/node_modules/react-dom/server.node.js +18 -0
- package/frontend-build/node_modules/react-dom/static.node.js +14 -0
- package/frontend-build/node_modules/sharp/lib/channel.js +177 -0
- package/frontend-build/node_modules/sharp/lib/colour.js +195 -0
- package/frontend-build/node_modules/sharp/lib/composite.js +212 -0
- package/frontend-build/node_modules/sharp/lib/constructor.js +499 -0
- package/frontend-build/node_modules/sharp/lib/index.js +16 -0
- package/frontend-build/node_modules/sharp/lib/input.js +809 -0
- package/frontend-build/node_modules/sharp/lib/is.js +143 -0
- package/frontend-build/node_modules/sharp/lib/libvips.js +207 -0
- package/frontend-build/node_modules/sharp/lib/operation.js +1016 -0
- package/frontend-build/node_modules/sharp/lib/output.js +1666 -0
- package/frontend-build/node_modules/sharp/lib/resize.js +595 -0
- package/frontend-build/node_modules/sharp/lib/sharp.js +121 -0
- package/frontend-build/node_modules/sharp/lib/utility.js +291 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/classes/comparator.js +143 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/classes/range.js +557 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/classes/semver.js +333 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/cmp.js +54 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/coerce.js +62 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/compare.js +7 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/eq.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/gt.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/gte.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/lt.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/lte.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/neq.js +5 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/parse.js +18 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/functions/satisfies.js +12 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/constants.js +37 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/debug.js +11 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/identifiers.js +29 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/lrucache.js +42 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/parse-options.js +17 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/internal/re.js +223 -0
- package/frontend-build/node_modules/sharp/node_modules/semver/package.json +78 -0
- package/frontend-build/node_modules/sharp/package.json +202 -0
- package/frontend-build/node_modules/styled-jsx/dist/index/index.js +499 -0
- package/frontend-build/node_modules/styled-jsx/index.js +1 -0
- package/frontend-build/node_modules/styled-jsx/package.json +132 -0
- package/frontend-build/node_modules/styled-jsx/style.js +1 -0
- package/frontend-build/package.json +43 -0
- package/frontend-build/public/aws-bedrock-icon.svg +1 -0
- package/frontend-build/public/chatgpt-icon.svg +1 -0
- package/frontend-build/public/claude-ai-icon.svg +1 -0
- package/frontend-build/public/deepseek-logo-icon.svg +1 -0
- package/frontend-build/public/discord-round-color-icon.svg +1 -0
- package/frontend-build/public/file.svg +1 -0
- package/frontend-build/public/globe.svg +1 -0
- package/frontend-build/public/google-gemini-icon.svg +1 -0
- package/frontend-build/public/grok-icon.svg +1 -0
- package/frontend-build/public/next.svg +1 -0
- package/frontend-build/public/ollama-icon.svg +1 -0
- package/frontend-build/public/slack-icon.svg +6 -0
- package/frontend-build/public/teams.svg +2 -0
- package/frontend-build/public/telegram-icon.svg +1 -0
- package/frontend-build/public/vercel.svg +1 -0
- package/frontend-build/public/whatsapp-color-icon.svg +1 -0
- package/frontend-build/public/window.svg +1 -0
- package/frontend-build/server.js +38 -0
- package/package.json +34 -0
|
@@ -0,0 +1,2088 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM provider API callers (OpenAI, Anthropic, Gemini, Bedrock, Ollama, Grok, DeepSeek, CLI).
|
|
3
|
+
Extracted from server.py to eliminate duplication between chat() and chat_stream().
|
|
4
|
+
|
|
5
|
+
All cloud providers follow the same failsafe pattern:
|
|
6
|
+
- 5 attempts max
|
|
7
|
+
- Exponential backoff: [5, 10, 20, 40, 80] seconds
|
|
8
|
+
- Raises LLMError on final failure (never returns error strings silently)
|
|
9
|
+
|
|
10
|
+
CLI providers (cli.claude, cli.gemini, cli.codex) use locally authenticated CLI sessions.
|
|
11
|
+
No API key needed — tool calling is emulated via system prompt injection + <tool_call> parsing.
|
|
12
|
+
"""
|
|
13
|
+
import os
|
|
14
|
+
import json
|
|
15
|
+
import tempfile
|
|
16
|
+
import asyncio
|
|
17
|
+
import base64
|
|
18
|
+
import threading
|
|
19
|
+
import httpx
|
|
20
|
+
import boto3
|
|
21
|
+
import botocore.exceptions
|
|
22
|
+
from botocore import UNSIGNED as _BEDROCK_UNSIGNED
|
|
23
|
+
from botocore.config import Config
|
|
24
|
+
|
|
25
|
+
# Lock to guard the process-level AWS_BEARER_TOKEN_BEDROCK env var.
|
|
26
|
+
# Multiple threads (via asyncio.to_thread) could otherwise race on set/clear.
|
|
27
|
+
_aws_env_lock = threading.Lock()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ─── Image helpers ──────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
def _parse_data_uri(data_uri: str) -> tuple[str, str]:
|
|
33
|
+
"""Parse a data URI into (mime_type, raw_base64).
|
|
34
|
+
|
|
35
|
+
Accepts:
|
|
36
|
+
- "data:image/png;base64,iVBOR..."
|
|
37
|
+
- plain base64 string (assumes image/png)
|
|
38
|
+
"""
|
|
39
|
+
if data_uri.startswith("data:"):
|
|
40
|
+
header, b64 = data_uri.split(",", 1)
|
|
41
|
+
mime = header.split(";")[0].replace("data:", "")
|
|
42
|
+
return mime, b64
|
|
43
|
+
return "image/png", data_uri
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _build_openai_image_content(text: str, images: list[str] | None) -> list[dict] | str:
|
|
47
|
+
"""Build OpenAI/Grok multimodal content blocks.
|
|
48
|
+
|
|
49
|
+
If images is empty, returns plain text string.
|
|
50
|
+
Otherwise returns a list of content parts (text + image_url blocks).
|
|
51
|
+
"""
|
|
52
|
+
if not images:
|
|
53
|
+
return text
|
|
54
|
+
parts: list[dict] = [{"type": "text", "text": text}]
|
|
55
|
+
for img in images[:5]:
|
|
56
|
+
mime, b64 = _parse_data_uri(img)
|
|
57
|
+
parts.append({
|
|
58
|
+
"type": "image_url",
|
|
59
|
+
"image_url": {"url": f"data:{mime};base64,{b64}"}
|
|
60
|
+
})
|
|
61
|
+
return parts
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _build_anthropic_image_content(text: str, images: list[str] | None) -> list[dict] | str:
|
|
65
|
+
"""Build Anthropic multimodal content blocks.
|
|
66
|
+
|
|
67
|
+
Returns list of content parts with image + text blocks.
|
|
68
|
+
"""
|
|
69
|
+
if not images:
|
|
70
|
+
return text
|
|
71
|
+
parts: list[dict] = []
|
|
72
|
+
for img in images[:5]:
|
|
73
|
+
mime, b64 = _parse_data_uri(img)
|
|
74
|
+
parts.append({
|
|
75
|
+
"type": "image",
|
|
76
|
+
"source": {"type": "base64", "media_type": mime, "data": b64}
|
|
77
|
+
})
|
|
78
|
+
parts.append({"type": "text", "text": text})
|
|
79
|
+
return parts
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class LLMError(Exception):
|
|
83
|
+
"""Raised when an LLM call fails after all retries.
|
|
84
|
+
|
|
85
|
+
This propagates through the orchestration engine so it can stop execution
|
|
86
|
+
instead of silently passing error strings to the next node.
|
|
87
|
+
"""
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# Configuration — read at call time so OLLAMA_BASE_URL set after import is respected
|
|
92
|
+
def _ollama_base_url() -> str:
|
|
93
|
+
return os.getenv("OLLAMA_BASE_URL", "http://127.0.0.1:11434")
|
|
94
|
+
|
|
95
|
+
OLLAMA_MODEL = "llama3"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def detect_mode_from_model(model_name: str) -> str:
|
|
99
|
+
"""Detect the provider mode from a model name prefix.
|
|
100
|
+
|
|
101
|
+
Returns 'cloud' for OpenAI/Anthropic/Gemini/Grok/DeepSeek models,
|
|
102
|
+
'bedrock' for Bedrock, 'cli' for local CLI session models (cli.*),
|
|
103
|
+
and 'local' for anything else (assumed to be Ollama).
|
|
104
|
+
"""
|
|
105
|
+
if not model_name:
|
|
106
|
+
return "local"
|
|
107
|
+
m = model_name.lower()
|
|
108
|
+
if m.startswith("cli."):
|
|
109
|
+
return "cli"
|
|
110
|
+
if m.startswith("gpt"):
|
|
111
|
+
return "cloud"
|
|
112
|
+
if m.startswith("claude"):
|
|
113
|
+
return "cloud"
|
|
114
|
+
if m.startswith("gemini") or m.startswith("gemma") or m.startswith("lyria"):
|
|
115
|
+
return "cloud"
|
|
116
|
+
if m.startswith("bedrock"):
|
|
117
|
+
return "bedrock"
|
|
118
|
+
if m.startswith("grok"):
|
|
119
|
+
return "cloud"
|
|
120
|
+
if m.startswith("deepseek"):
|
|
121
|
+
return "cloud"
|
|
122
|
+
if m.startswith("oaic."):
|
|
123
|
+
return "cloud"
|
|
124
|
+
if m.startswith("locv1."):
|
|
125
|
+
return "local"
|
|
126
|
+
if m.startswith("ollama."):
|
|
127
|
+
return "local"
|
|
128
|
+
return "local"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def detect_provider_from_model(model_name: str) -> str:
|
|
132
|
+
"""Detect the provider name from a model name prefix."""
|
|
133
|
+
if not model_name:
|
|
134
|
+
return "ollama"
|
|
135
|
+
m = model_name.lower()
|
|
136
|
+
# CLI session providers
|
|
137
|
+
if m.startswith("cli.claude"):
|
|
138
|
+
return "anthropic_cli"
|
|
139
|
+
if m.startswith("cli.gemini"):
|
|
140
|
+
return "gemini_cli"
|
|
141
|
+
if m.startswith("cli.codex"):
|
|
142
|
+
return "codex_cli"
|
|
143
|
+
if m.startswith("cli.copilot"):
|
|
144
|
+
return "github_copilot_cli"
|
|
145
|
+
if m.startswith("cli."):
|
|
146
|
+
return "cli"
|
|
147
|
+
if m.startswith("gpt"):
|
|
148
|
+
return "openai"
|
|
149
|
+
if m.startswith("claude"):
|
|
150
|
+
return "anthropic"
|
|
151
|
+
if m.startswith("gemini") or m.startswith("gemma") or m.startswith("lyria"):
|
|
152
|
+
return "gemini"
|
|
153
|
+
if m.startswith("bedrock"):
|
|
154
|
+
return "bedrock"
|
|
155
|
+
if m.startswith("grok"):
|
|
156
|
+
return "grok"
|
|
157
|
+
if m.startswith("deepseek"):
|
|
158
|
+
return "deepseek"
|
|
159
|
+
if m.startswith("oaic."):
|
|
160
|
+
return "openai_compatible"
|
|
161
|
+
if m.startswith("locv1."):
|
|
162
|
+
return "local_compatible"
|
|
163
|
+
if m.startswith("ollama."):
|
|
164
|
+
return "ollama"
|
|
165
|
+
return "ollama"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _normalize_bedrock_api_key(settings: dict) -> str:
|
|
170
|
+
"""Extract and normalize the Bedrock API key from settings.
|
|
171
|
+
|
|
172
|
+
Strips surrounding quotes and common header prefixes (Authorization: Bearer ...)
|
|
173
|
+
that users often paste. Both ABSK... and bedrock-api-key... formats are returned
|
|
174
|
+
as-is after stripping prefixes.
|
|
175
|
+
"""
|
|
176
|
+
api_key = (settings.get("bedrock_api_key") or "").strip()
|
|
177
|
+
if not api_key:
|
|
178
|
+
return ""
|
|
179
|
+
if (api_key.startswith('"') and api_key.endswith('"')) or (
|
|
180
|
+
api_key.startswith("'") and api_key.endswith("'")
|
|
181
|
+
):
|
|
182
|
+
api_key = api_key[1:-1].strip()
|
|
183
|
+
lower = api_key.lower()
|
|
184
|
+
if lower.startswith("authorization:"):
|
|
185
|
+
api_key = api_key.split(":", 1)[1].strip()
|
|
186
|
+
lower = api_key.lower()
|
|
187
|
+
if lower.startswith("bearer "):
|
|
188
|
+
api_key = api_key.split(" ", 1)[1].strip()
|
|
189
|
+
return api_key
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _make_aws_client(service_name: str, region: str, settings: dict):
|
|
193
|
+
"""Create a boto3 client.
|
|
194
|
+
|
|
195
|
+
If access/secret are not provided, boto3 will use its default credential chain
|
|
196
|
+
(env vars, AWS_PROFILE, SSO, instance role, etc.).
|
|
197
|
+
"""
|
|
198
|
+
# Amazon Bedrock API keys can be provided as a bearer token via this env var.
|
|
199
|
+
# See: https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys-use.html
|
|
200
|
+
bedrock_api_key = _normalize_bedrock_api_key(settings)
|
|
201
|
+
|
|
202
|
+
# If a Bedrock API key is provided, prefer it and avoid mixing auth mechanisms.
|
|
203
|
+
if bedrock_api_key:
|
|
204
|
+
access_key = ""
|
|
205
|
+
secret_key = ""
|
|
206
|
+
session_token = ""
|
|
207
|
+
else:
|
|
208
|
+
access_key = (settings.get("aws_access_key_id") or "").strip()
|
|
209
|
+
secret_key = (settings.get("aws_secret_access_key") or "").strip()
|
|
210
|
+
session_token = (settings.get("aws_session_token") or "").strip()
|
|
211
|
+
region_name = (region or settings.get("aws_region") or "us-east-1").strip()
|
|
212
|
+
|
|
213
|
+
kwargs = {
|
|
214
|
+
"service_name": service_name,
|
|
215
|
+
"region_name": region_name,
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if access_key and secret_key:
|
|
219
|
+
kwargs.update(
|
|
220
|
+
{
|
|
221
|
+
"aws_access_key_id": access_key,
|
|
222
|
+
"aws_secret_access_key": secret_key,
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
if session_token:
|
|
226
|
+
kwargs["aws_session_token"] = session_token
|
|
227
|
+
|
|
228
|
+
# -------------------------------------------------------------------------
|
|
229
|
+
# RETRY CONFIGURATION (Fix for ServiceUnavailableException / Throttling)
|
|
230
|
+
# -------------------------------------------------------------------------
|
|
231
|
+
# Standard retries are often insufficient for high-concurrency Bedrock usage.
|
|
232
|
+
# Adaptive mode allows standard retry logic to dynamically adjust for
|
|
233
|
+
# optimal request rates.
|
|
234
|
+
retry_config = Config(
|
|
235
|
+
retries={
|
|
236
|
+
'max_attempts': 10,
|
|
237
|
+
'mode': 'adaptive'
|
|
238
|
+
},
|
|
239
|
+
read_timeout=900,
|
|
240
|
+
connect_timeout=900,
|
|
241
|
+
)
|
|
242
|
+
kwargs["config"] = retry_config
|
|
243
|
+
|
|
244
|
+
# Guard the process-level env var with a lock so concurrent threads don't
|
|
245
|
+
# race on set/clear (AWS_BEARER_TOKEN_BEDROCK is read by botocore at client
|
|
246
|
+
# creation time for the bedrock-runtime bearer-token auth path).
|
|
247
|
+
with _aws_env_lock:
|
|
248
|
+
if bedrock_api_key:
|
|
249
|
+
os.environ["AWS_BEARER_TOKEN_BEDROCK"] = bedrock_api_key
|
|
250
|
+
else:
|
|
251
|
+
os.environ.pop("AWS_BEARER_TOKEN_BEDROCK", None)
|
|
252
|
+
return boto3.client(**kwargs)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# ─── CLI Session Providers ──────────────────────────────────────────────────────
|
|
256
|
+
|
|
257
|
+
# Maps cli.* model names to their CLI binary + flags
|
|
258
|
+
_CLI_COMMANDS: dict[str, list[str]] = {
|
|
259
|
+
"cli.claude": ["claude", "-p", "--allowedTools", ""],
|
|
260
|
+
"cli.gemini": ["gemini", "--prompt", ""],
|
|
261
|
+
"cli.codex": ["codex", "exec", "--dangerously-bypass-approvals-and-sandbox",
|
|
262
|
+
"-c", "instructions=", "-c", "features.shell_tool=false"],
|
|
263
|
+
"cli.copilot": ["copilot", "-p"],
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
# Seconds to wait for a CLI process before giving up
|
|
267
|
+
_CLI_TIMEOUT = 300.0
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _build_cli_prompt(
|
|
271
|
+
sys_prompt: str,
|
|
272
|
+
messages: list[dict],
|
|
273
|
+
tools: list[dict] | None = None,
|
|
274
|
+
) -> str:
|
|
275
|
+
"""Build a single flat text prompt for CLI providers.
|
|
276
|
+
|
|
277
|
+
Combines system prompt (with optional tool schema injection) + conversation
|
|
278
|
+
transcript into one string that can be piped into a CLI via stdin.
|
|
279
|
+
"""
|
|
280
|
+
parts: list[str] = []
|
|
281
|
+
|
|
282
|
+
# 1. System prompt
|
|
283
|
+
if sys_prompt and sys_prompt.strip():
|
|
284
|
+
parts.append(sys_prompt.strip())
|
|
285
|
+
|
|
286
|
+
# 2. Tool schema injection — emulates native tool calling
|
|
287
|
+
if tools:
|
|
288
|
+
import json as _json
|
|
289
|
+
tool_block = (
|
|
290
|
+
"\n\n===== AVAILABLE TOOLS =====\n"
|
|
291
|
+
"You have access to the following tools. "
|
|
292
|
+
"To call a tool, output EXACTLY the following XML block (nothing before or after it on that response):\n"
|
|
293
|
+
"<tool_call>{\"tool\": \"<tool_name>\", \"arguments\": {<args>}}</tool_call>\n\n"
|
|
294
|
+
"Tools:\n"
|
|
295
|
+
)
|
|
296
|
+
for t in tools:
|
|
297
|
+
func = t.get("function", {})
|
|
298
|
+
name = func.get("name", "")
|
|
299
|
+
if not name:
|
|
300
|
+
continue
|
|
301
|
+
desc = func.get("description", "")
|
|
302
|
+
params = func.get("parameters", {})
|
|
303
|
+
tool_block += f"- {name}: {desc}\n"
|
|
304
|
+
if params.get("properties"):
|
|
305
|
+
tool_block += f" Parameters: {_json.dumps(params['properties'])}\n"
|
|
306
|
+
tool_block += "===========================\n"
|
|
307
|
+
parts.append(tool_block)
|
|
308
|
+
|
|
309
|
+
# 3. Conversation history transcript
|
|
310
|
+
transcript = _messages_to_transcript(messages)
|
|
311
|
+
if transcript:
|
|
312
|
+
parts.append(transcript)
|
|
313
|
+
|
|
314
|
+
return "\n\n".join(parts)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
async def call_cli_provider(
|
|
318
|
+
cli_model: str,
|
|
319
|
+
full_prompt: str,
|
|
320
|
+
sys_prompt: str | None = None,
|
|
321
|
+
messages: list[dict] | None = None,
|
|
322
|
+
timeout: float = _CLI_TIMEOUT,
|
|
323
|
+
cli_session_id: str | None = None,
|
|
324
|
+
) -> tuple[str, int, int, str | None]:
|
|
325
|
+
"""Spawn a local CLI binary, feed it the full context, and return the response.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
cli_model: One of 'cli.claude', 'cli.gemini', 'cli.codex', 'cli.copilot'
|
|
329
|
+
full_prompt: Complete flat-text prompt (system + tools + transcript)
|
|
330
|
+
timeout: Seconds before we kill the process and raise LLMError
|
|
331
|
+
cli_session_id: Existing CLI session ID to resume (passed via --resume).
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
(response_text, estimated_input_tokens, estimated_output_tokens, new_session_id)
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
LLMError: on timeout, auth failure, binary not found, or empty output
|
|
338
|
+
"""
|
|
339
|
+
import re
|
|
340
|
+
from core import usage_tracker
|
|
341
|
+
|
|
342
|
+
ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
|
343
|
+
AUTH_PATTERNS = ["login", "authenticate", "auth", "expired", "sign in", "api key", "unauthorized"]
|
|
344
|
+
RATE_LIMIT_PATTERNS = ["429", "rate limit", "ratelimit", "quota", "too many requests", "capacity", "resource_exhausted", "ratelimitexceeded"]
|
|
345
|
+
|
|
346
|
+
parts = cli_model.lower().split(".")
|
|
347
|
+
if len(parts) >= 2:
|
|
348
|
+
base_cli = f"{parts[0]}.{parts[1]}"
|
|
349
|
+
else:
|
|
350
|
+
base_cli = cli_model.lower()
|
|
351
|
+
|
|
352
|
+
base_cmd = _CLI_COMMANDS.get(base_cli)
|
|
353
|
+
if not base_cmd:
|
|
354
|
+
raise LLMError(f"Unknown CLI base '{base_cli}'. Supported: {list(_CLI_COMMANDS.keys())}")
|
|
355
|
+
|
|
356
|
+
cmd = base_cmd.copy()
|
|
357
|
+
|
|
358
|
+
# ── Session Resume ──
|
|
359
|
+
# If a previous CLI session ID exists for this agent+session, continue it.
|
|
360
|
+
if cli_session_id:
|
|
361
|
+
cmd.extend(["--resume", cli_session_id])
|
|
362
|
+
|
|
363
|
+
# ── Dynamic Model & Options Parsing ──
|
|
364
|
+
if len(parts) > 2:
|
|
365
|
+
variant = parts[2]
|
|
366
|
+
if base_cli == "cli.claude":
|
|
367
|
+
# Extract base model by removing any thinking suffixes
|
|
368
|
+
clean_variant = variant.replace('-thinking', '').replace('-max', '').replace('-high', '')
|
|
369
|
+
cmd.extend(["--model", clean_variant])
|
|
370
|
+
|
|
371
|
+
# Thinking / Effort overrides
|
|
372
|
+
if "-thinking" in variant or "-max" in variant:
|
|
373
|
+
cmd.extend(["--effort", "medium"])
|
|
374
|
+
elif "-high" in variant:
|
|
375
|
+
cmd.extend(["--effort", "high"])
|
|
376
|
+
else:
|
|
377
|
+
cmd.extend(["--effort", "low"])
|
|
378
|
+
|
|
379
|
+
elif base_cli == "cli.gemini":
|
|
380
|
+
if "pro" in variant:
|
|
381
|
+
cmd.extend(["--model", "pro"])
|
|
382
|
+
elif "flash" in variant:
|
|
383
|
+
cmd.extend(["--model", "flash"])
|
|
384
|
+
|
|
385
|
+
elif base_cli == "cli.codex":
|
|
386
|
+
# Pass the variant directly as the model name (e.g. o3, o4-mini, gpt-4o)
|
|
387
|
+
cmd.extend(["-m", variant])
|
|
388
|
+
|
|
389
|
+
elif base_cli == "cli.copilot":
|
|
390
|
+
# Pass the variant directly as the model name (e.g. claude-sonnet-4-5, gpt-4o)
|
|
391
|
+
cmd.extend(["--model", variant])
|
|
392
|
+
|
|
393
|
+
# codex exec requires "-" as the positional PROMPT arg to signal stdin input.
|
|
394
|
+
# Append it after all option flags are resolved so it stays last.
|
|
395
|
+
if base_cli == "cli.codex":
|
|
396
|
+
cmd.append("-")
|
|
397
|
+
|
|
398
|
+
import shutil
|
|
399
|
+
executable = shutil.which(cmd[0])
|
|
400
|
+
if not executable:
|
|
401
|
+
raise LLMError(f"CLI binary '{cmd[0]}' exactly resolved by shutil.which not found. Check your PATH.")
|
|
402
|
+
|
|
403
|
+
env = os.environ.copy()
|
|
404
|
+
temp_sys_prompt_file = None
|
|
405
|
+
temp_input_file = None
|
|
406
|
+
temp_output_file = None
|
|
407
|
+
|
|
408
|
+
# Use backend/data/tmp for temp files — avoids cross-OS permission issues
|
|
409
|
+
# with the system temp dir and keeps all runtime files under the project root.
|
|
410
|
+
_tmp_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "tmp")
|
|
411
|
+
os.makedirs(_tmp_dir, exist_ok=True)
|
|
412
|
+
|
|
413
|
+
try:
|
|
414
|
+
if base_cli == "cli.copilot":
|
|
415
|
+
# copilot -p takes the full prompt inline as a CLI argument; stdin is not used.
|
|
416
|
+
# System prompt is already embedded in full_prompt by _build_cli_prompt().
|
|
417
|
+
cmd.append(full_prompt)
|
|
418
|
+
stdin_source = asyncio.subprocess.DEVNULL
|
|
419
|
+
else:
|
|
420
|
+
if base_cli == "cli.claude" and sys_prompt:
|
|
421
|
+
# Write sys_prompt to a temp file and pass via --system-prompt-file.
|
|
422
|
+
# --no-tools (added above) ensures Claude Code's native tools are stripped so
|
|
423
|
+
# only our XML emulation is active.
|
|
424
|
+
temp_sys_prompt_file = tempfile.NamedTemporaryFile(
|
|
425
|
+
mode="w", suffix=".md", prefix="claude_sys_prompt_", delete=False,
|
|
426
|
+
encoding="utf-8", dir=_tmp_dir
|
|
427
|
+
)
|
|
428
|
+
temp_sys_prompt_file.write(sys_prompt)
|
|
429
|
+
temp_sys_prompt_file.flush()
|
|
430
|
+
temp_sys_prompt_file.close()
|
|
431
|
+
cmd.extend(["--system-prompt-file", temp_sys_prompt_file.name])
|
|
432
|
+
|
|
433
|
+
# stdin carries only the content after the sys_prompt (tools + messages).
|
|
434
|
+
# full_prompt = sys_prompt.strip() + "\n\n" + rest, so strip the prefix.
|
|
435
|
+
prefix = sys_prompt.strip()
|
|
436
|
+
stdin_payload = full_prompt[len(prefix):].lstrip("\n") if full_prompt.startswith(prefix) else full_prompt
|
|
437
|
+
|
|
438
|
+
elif base_cli == "cli.gemini" and sys_prompt:
|
|
439
|
+
# Gemini CLI reads GEMINI_SYSTEM_MD env var as the path to a markdown file
|
|
440
|
+
# containing the system prompt, overriding its native default system prompt.
|
|
441
|
+
temp_sys_prompt_file = tempfile.NamedTemporaryFile(
|
|
442
|
+
mode="w", suffix=".md", prefix="gemini_sys_prompt_", delete=False,
|
|
443
|
+
encoding="utf-8", dir=_tmp_dir
|
|
444
|
+
)
|
|
445
|
+
temp_sys_prompt_file.write(sys_prompt)
|
|
446
|
+
temp_sys_prompt_file.flush()
|
|
447
|
+
temp_sys_prompt_file.close()
|
|
448
|
+
env["GEMINI_SYSTEM_MD"] = temp_sys_prompt_file.name
|
|
449
|
+
|
|
450
|
+
# stdin carries only the content after the sys_prompt (tools + messages).
|
|
451
|
+
prefix = sys_prompt.strip()
|
|
452
|
+
stdin_payload = full_prompt[len(prefix):].lstrip("\n") if full_prompt.startswith(prefix) else full_prompt
|
|
453
|
+
|
|
454
|
+
else:
|
|
455
|
+
stdin_payload = full_prompt
|
|
456
|
+
|
|
457
|
+
# Write stdin payload to a temp file and feed it as stdin (like `< file`),
|
|
458
|
+
# avoiding large string pipes and keeping content out of the process list.
|
|
459
|
+
temp_input_file = tempfile.NamedTemporaryFile(
|
|
460
|
+
mode="w", suffix=".txt", prefix="cli_input_", delete=False,
|
|
461
|
+
encoding="utf-8", dir=_tmp_dir
|
|
462
|
+
)
|
|
463
|
+
temp_input_file.write(stdin_payload)
|
|
464
|
+
temp_input_file.flush()
|
|
465
|
+
temp_input_file.close()
|
|
466
|
+
|
|
467
|
+
# codex exec: use -o to capture only the final agent message, avoiding TUI noise
|
|
468
|
+
if base_cli == "cli.codex":
|
|
469
|
+
temp_output_file = tempfile.NamedTemporaryFile(
|
|
470
|
+
mode="w", suffix=".txt", prefix="codex_output_", delete=False,
|
|
471
|
+
encoding="utf-8", dir=_tmp_dir
|
|
472
|
+
)
|
|
473
|
+
temp_output_file.close()
|
|
474
|
+
cmd.extend(["-o", temp_output_file.name])
|
|
475
|
+
|
|
476
|
+
stdin_source = open(temp_input_file.name, "rb")
|
|
477
|
+
|
|
478
|
+
print(f"DEBUG: 🖥️ CLI provider '{cli_model}' — spawning subprocess: {' '.join(str(a) for a in cmd)}", flush=True)
|
|
479
|
+
|
|
480
|
+
process = await asyncio.create_subprocess_exec(
|
|
481
|
+
executable,
|
|
482
|
+
*cmd[1:],
|
|
483
|
+
stdin=stdin_source,
|
|
484
|
+
stdout=asyncio.subprocess.PIPE,
|
|
485
|
+
stderr=asyncio.subprocess.PIPE,
|
|
486
|
+
env=env
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
if temp_input_file:
|
|
490
|
+
stdin_source.close()
|
|
491
|
+
|
|
492
|
+
try:
|
|
493
|
+
stdout_b, stderr_b = await asyncio.wait_for(
|
|
494
|
+
process.communicate(),
|
|
495
|
+
timeout=timeout,
|
|
496
|
+
)
|
|
497
|
+
except asyncio.TimeoutError:
|
|
498
|
+
try:
|
|
499
|
+
process.kill()
|
|
500
|
+
await process.wait()
|
|
501
|
+
except Exception:
|
|
502
|
+
pass
|
|
503
|
+
raise LLMError(
|
|
504
|
+
f"CLI provider '{cli_model}' timed out after {timeout}s. "
|
|
505
|
+
"Is the CLI authenticated and responsive?"
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
stderr_text = stderr_b.decode("utf-8", errors="replace").strip()
|
|
509
|
+
if stderr_text:
|
|
510
|
+
# Scan only the tail of stderr for error patterns — Codex (and some other CLIs)
|
|
511
|
+
# echo the stdin/banner to stderr, which can contain words like "capacity" that
|
|
512
|
+
# would falsely trigger rate-limit detection. Real API errors appear at the end.
|
|
513
|
+
lower_err = stderr_text[-600:].lower()
|
|
514
|
+
if any(p in lower_err for p in RATE_LIMIT_PATTERNS):
|
|
515
|
+
raise LLMError(
|
|
516
|
+
f"CLI provider '{cli_model}' rate limit / capacity error.\n"
|
|
517
|
+
f"Details: {stderr_text[:400]}"
|
|
518
|
+
)
|
|
519
|
+
if any(p in lower_err for p in AUTH_PATTERNS):
|
|
520
|
+
raise LLMError(
|
|
521
|
+
f"CLI provider '{cli_model}' authentication failure detected.\n"
|
|
522
|
+
f"Run the CLI in your terminal to re-authenticate.\n"
|
|
523
|
+
f"Details: {stderr_text[:400]}"
|
|
524
|
+
)
|
|
525
|
+
print(f"DEBUG: 🖥️ CLI stderr: {stderr_text[:300]}", flush=True)
|
|
526
|
+
|
|
527
|
+
# codex exec writes just the final agent message to the -o file; use that
|
|
528
|
+
# to avoid parsing the TUI header/footer noise from stdout.
|
|
529
|
+
if base_cli == "cli.codex" and temp_output_file:
|
|
530
|
+
try:
|
|
531
|
+
with open(temp_output_file.name, "r", encoding="utf-8", errors="replace") as f:
|
|
532
|
+
raw = f.read()
|
|
533
|
+
except Exception:
|
|
534
|
+
raw = stdout_b.decode("utf-8", errors="replace")
|
|
535
|
+
else:
|
|
536
|
+
raw = stdout_b.decode("utf-8", errors="replace")
|
|
537
|
+
clean = ANSI_ESCAPE.sub("", raw).strip()
|
|
538
|
+
|
|
539
|
+
# ── Session ID extraction & response unwrapping ──
|
|
540
|
+
new_session_id: str | None = None
|
|
541
|
+
if base_cli == "cli.claude":
|
|
542
|
+
# Claude CLI with --output-format json returns a structured object.
|
|
543
|
+
# Extract result text and session_id from it.
|
|
544
|
+
try:
|
|
545
|
+
import json as _json
|
|
546
|
+
obj = _json.loads(clean)
|
|
547
|
+
new_session_id = obj.get("session_id")
|
|
548
|
+
extracted = obj.get("result", "")
|
|
549
|
+
if isinstance(extracted, str) and extracted.strip():
|
|
550
|
+
clean = extracted.strip()
|
|
551
|
+
# Propagate JSON-level auth errors before the generic check below
|
|
552
|
+
if obj.get("is_error") and any(p in str(obj).lower() for p in AUTH_PATTERNS):
|
|
553
|
+
raise LLMError(
|
|
554
|
+
f"CLI provider '{cli_model}' authentication failure.\n"
|
|
555
|
+
f"Run 'claude' in your terminal to re-authenticate.\n"
|
|
556
|
+
f"Details: {str(obj)[:300]}"
|
|
557
|
+
)
|
|
558
|
+
except LLMError:
|
|
559
|
+
raise
|
|
560
|
+
except Exception:
|
|
561
|
+
pass # not JSON or parse error — treat clean as plain text
|
|
562
|
+
else:
|
|
563
|
+
# Best-effort session ID extraction for gemini, codex, copilot
|
|
564
|
+
sid_match = re.search(r"session[_\-]?id[:\s]+([a-zA-Z0-9_\-]{8,})", clean, re.IGNORECASE)
|
|
565
|
+
new_session_id = sid_match.group(1) if sid_match else None
|
|
566
|
+
|
|
567
|
+
# Auth failure check (also catches plain-text "Not logged in" from claude)
|
|
568
|
+
if any(p in clean.lower() for p in AUTH_PATTERNS):
|
|
569
|
+
raise LLMError(
|
|
570
|
+
f"CLI provider '{cli_model}' is not authenticated.\n"
|
|
571
|
+
f"Run the CLI in your terminal and complete the login flow, then retry.\n"
|
|
572
|
+
f"Details: {clean[:300]}"
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
if not clean:
|
|
576
|
+
raise LLMError(
|
|
577
|
+
f"CLI provider '{cli_model}' returned empty output. "
|
|
578
|
+
f"Return code: {process.returncode}. "
|
|
579
|
+
f"stderr: {stderr_text[:200]}"
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
print(f"DEBUG: ✅ CLI '{cli_model}' response ({len(clean)} chars)", flush=True)
|
|
583
|
+
|
|
584
|
+
input_est = usage_tracker.estimate_tokens_from_text(full_prompt)
|
|
585
|
+
output_est = usage_tracker.estimate_tokens_from_text(clean)
|
|
586
|
+
return clean, input_est, output_est, new_session_id
|
|
587
|
+
|
|
588
|
+
except LLMError:
|
|
589
|
+
raise
|
|
590
|
+
except FileNotFoundError:
|
|
591
|
+
raise LLMError(
|
|
592
|
+
f"CLI binary for '{cli_model}' not found in PATH. "
|
|
593
|
+
f"Install and authenticate the CLI first: {cmd[0]}"
|
|
594
|
+
)
|
|
595
|
+
except Exception as e:
|
|
596
|
+
raise LLMError(f"CLI provider '{cli_model}' unexpected error: {e}")
|
|
597
|
+
finally:
|
|
598
|
+
for f in [temp_sys_prompt_file, temp_input_file, temp_output_file]:
|
|
599
|
+
if f:
|
|
600
|
+
try:
|
|
601
|
+
os.unlink(f.name)
|
|
602
|
+
except Exception:
|
|
603
|
+
pass
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
# ────────────────────────────────────────────────────────────────────────────────
|
|
607
|
+
|
|
608
|
+
async def call_openai(model, messages, api_key, tools=None, images=None):
|
|
609
|
+
"""Call OpenAI with 5-attempt exponential backoff retry loop.
|
|
610
|
+
|
|
611
|
+
Args:
|
|
612
|
+
model: GPT model name (e.g. 'gpt-4o')
|
|
613
|
+
messages: List of {"role": ..., "content": ...} dicts
|
|
614
|
+
api_key: OpenAI API key
|
|
615
|
+
tools: Ollama-format tool list (forwarded as OpenAI function definitions)
|
|
616
|
+
images: List of base64 data-URI image strings to attach to the last user message
|
|
617
|
+
|
|
618
|
+
Returns:
|
|
619
|
+
(response_text, input_tokens, output_tokens)
|
|
620
|
+
"""
|
|
621
|
+
# Inject images into the last user message
|
|
622
|
+
if images:
|
|
623
|
+
for i in range(len(messages) - 1, -1, -1):
|
|
624
|
+
if messages[i].get("role") == "user":
|
|
625
|
+
messages[i] = dict(messages[i]) # shallow copy
|
|
626
|
+
messages[i]["content"] = _build_openai_image_content(
|
|
627
|
+
str(messages[i].get("content", "")), images
|
|
628
|
+
)
|
|
629
|
+
break
|
|
630
|
+
OPENAI_TIMEOUT = 180.0
|
|
631
|
+
MAX_RETRIES = 5
|
|
632
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80]
|
|
633
|
+
|
|
634
|
+
payload: dict = {"model": model, "messages": messages}
|
|
635
|
+
if tools:
|
|
636
|
+
# OpenAI uses the same format as our internal Ollama tool spec
|
|
637
|
+
payload["tools"] = tools
|
|
638
|
+
payload["tool_choice"] = "auto"
|
|
639
|
+
|
|
640
|
+
last_error = None
|
|
641
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
642
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
643
|
+
try:
|
|
644
|
+
print(f"DEBUG: 🔄 OpenAI call start (attempt {attempt}/{MAX_RETRIES})", flush=True)
|
|
645
|
+
async with httpx.AsyncClient(timeout=OPENAI_TIMEOUT) as client:
|
|
646
|
+
resp = await client.post(
|
|
647
|
+
"https://api.openai.com/v1/chat/completions",
|
|
648
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
649
|
+
json=payload,
|
|
650
|
+
)
|
|
651
|
+
if resp.status_code in (429, 499, 500, 502, 503, 529):
|
|
652
|
+
last_error = f"HTTP {resp.status_code}: {resp.text[:200]}"
|
|
653
|
+
print(f"DEBUG: ⏳ OpenAI {resp.status_code} on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
654
|
+
if attempt < MAX_RETRIES:
|
|
655
|
+
await asyncio.sleep(backoff)
|
|
656
|
+
continue
|
|
657
|
+
resp.raise_for_status()
|
|
658
|
+
data = resp.json()
|
|
659
|
+
# Extract actual token usage from the API response
|
|
660
|
+
usage = data.get("usage", {})
|
|
661
|
+
input_tokens = usage.get("prompt_tokens", 0)
|
|
662
|
+
output_tokens = usage.get("completion_tokens", 0)
|
|
663
|
+
# Handle tool_calls response
|
|
664
|
+
choice = data["choices"][0]
|
|
665
|
+
msg = choice.get("message", {})
|
|
666
|
+
if msg.get("tool_calls"):
|
|
667
|
+
tc = msg["tool_calls"][0]
|
|
668
|
+
text = json.dumps({
|
|
669
|
+
"tool": tc["function"]["name"],
|
|
670
|
+
"arguments": json.loads(tc["function"].get("arguments", "{}"))
|
|
671
|
+
})
|
|
672
|
+
return text, input_tokens, output_tokens
|
|
673
|
+
print(f"DEBUG: ✅ OpenAI call complete (attempt {attempt})", flush=True)
|
|
674
|
+
return msg.get("content", ""), input_tokens, output_tokens
|
|
675
|
+
except httpx.TimeoutException:
|
|
676
|
+
last_error = f"Request timed out ({OPENAI_TIMEOUT}s)"
|
|
677
|
+
print(f"DEBUG: ⏱️ OpenAI timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
678
|
+
if attempt < MAX_RETRIES:
|
|
679
|
+
await asyncio.sleep(backoff)
|
|
680
|
+
continue
|
|
681
|
+
except httpx.HTTPStatusError as e:
|
|
682
|
+
last_error = f"HTTP {e.response.status_code}: {str(e)[:200]}"
|
|
683
|
+
print(f"DEBUG: ❌ OpenAI HTTP error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
684
|
+
if attempt < MAX_RETRIES and e.response.status_code in (429, 499, 500, 502, 503, 529):
|
|
685
|
+
await asyncio.sleep(backoff)
|
|
686
|
+
continue
|
|
687
|
+
break
|
|
688
|
+
except Exception as e:
|
|
689
|
+
last_error = str(e)
|
|
690
|
+
print(f"DEBUG: ⚠️ OpenAI error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
691
|
+
if attempt < MAX_RETRIES:
|
|
692
|
+
await asyncio.sleep(backoff)
|
|
693
|
+
continue
|
|
694
|
+
|
|
695
|
+
error_msg = f"OpenAI LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
696
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
697
|
+
raise LLMError(error_msg)
|
|
698
|
+
|
|
699
|
+
def _convert_tools_for_anthropic(ollama_tools: list[dict] | None) -> list[dict] | None:
|
|
700
|
+
"""Convert Ollama-format tool list to Anthropic tool format.
|
|
701
|
+
|
|
702
|
+
Ollama format:
|
|
703
|
+
[{"type": "function", "function": {"name": ..., "description": ..., "parameters": ...}}]
|
|
704
|
+
Anthropic format:
|
|
705
|
+
[{"name": ..., "description": ..., "input_schema": ...}]
|
|
706
|
+
"""
|
|
707
|
+
if not ollama_tools:
|
|
708
|
+
return None
|
|
709
|
+
|
|
710
|
+
tools = []
|
|
711
|
+
for t in ollama_tools:
|
|
712
|
+
func = t.get("function", {})
|
|
713
|
+
name = func.get("name", "")
|
|
714
|
+
if not name:
|
|
715
|
+
continue
|
|
716
|
+
tool_def = {
|
|
717
|
+
"name": name,
|
|
718
|
+
"description": func.get("description", ""),
|
|
719
|
+
"input_schema": func.get("parameters", {"type": "object", "properties": {}}),
|
|
720
|
+
}
|
|
721
|
+
tools.append(tool_def)
|
|
722
|
+
|
|
723
|
+
return tools if tools else None
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def _extract_anthropic_response(response) -> str:
|
|
727
|
+
"""Extract text or tool call from an Anthropic SDK response.
|
|
728
|
+
|
|
729
|
+
Checks for tool_use content blocks first (native tool calling),
|
|
730
|
+
then falls back to text blocks.
|
|
731
|
+
"""
|
|
732
|
+
if not response.content:
|
|
733
|
+
return "Error: Empty Anthropic response."
|
|
734
|
+
|
|
735
|
+
# Check for tool_use blocks first (native tool calling)
|
|
736
|
+
for block in response.content:
|
|
737
|
+
if block.type == "tool_use":
|
|
738
|
+
return json.dumps({"tool": block.name, "arguments": block.input or {}})
|
|
739
|
+
|
|
740
|
+
# Collect text blocks
|
|
741
|
+
text_parts = [block.text for block in response.content if block.type == "text" and block.text]
|
|
742
|
+
if text_parts:
|
|
743
|
+
return "\n".join(text_parts)
|
|
744
|
+
|
|
745
|
+
return "Error: Anthropic returned no usable content."
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
async def call_anthropic(model, messages, system, api_key, tools=None, images=None):
|
|
749
|
+
"""Call Anthropic using the official SDK with native tool calling.
|
|
750
|
+
|
|
751
|
+
Args:
|
|
752
|
+
model: Claude model name (e.g. 'claude-sonnet-4-20250514')
|
|
753
|
+
messages: List of {"role": "user"/"assistant", "content": "..."} dicts
|
|
754
|
+
system: System instruction text
|
|
755
|
+
api_key: Anthropic API key
|
|
756
|
+
tools: Ollama-format tool list (converted to Anthropic tool definitions)
|
|
757
|
+
images: List of base64 data-URI image strings to attach to the last user message
|
|
758
|
+
|
|
759
|
+
Returns:
|
|
760
|
+
(response_text, input_tokens, output_tokens)
|
|
761
|
+
"""
|
|
762
|
+
# Inject images into the last user message
|
|
763
|
+
if images:
|
|
764
|
+
for i in range(len(messages) - 1, -1, -1):
|
|
765
|
+
if messages[i].get("role") == "user":
|
|
766
|
+
messages[i] = dict(messages[i]) # shallow copy
|
|
767
|
+
messages[i]["content"] = _build_anthropic_image_content(
|
|
768
|
+
str(messages[i].get("content", "")), images
|
|
769
|
+
)
|
|
770
|
+
break
|
|
771
|
+
import anthropic
|
|
772
|
+
|
|
773
|
+
ANTHROPIC_TIMEOUT = 180.0 # seconds per attempt (Claude can take >60s for complex prompts)
|
|
774
|
+
MAX_RETRIES = 5
|
|
775
|
+
|
|
776
|
+
# --- Input validation to prevent 400 errors ---
|
|
777
|
+
# 1. Filter out messages with empty content
|
|
778
|
+
clean_messages = [
|
|
779
|
+
m for m in (messages or [])
|
|
780
|
+
if m.get("content") and str(m["content"]).strip()
|
|
781
|
+
]
|
|
782
|
+
# 2. Ensure messages start with "user" role (Claude requirement)
|
|
783
|
+
while clean_messages and clean_messages[0].get("role") != "user":
|
|
784
|
+
clean_messages.pop(0)
|
|
785
|
+
# 3. If no valid messages remain, create a minimal one
|
|
786
|
+
if not clean_messages:
|
|
787
|
+
clean_messages = [{"role": "user", "content": "Hello"}]
|
|
788
|
+
|
|
789
|
+
# Convert tools
|
|
790
|
+
anthropic_tools = _convert_tools_for_anthropic(tools)
|
|
791
|
+
|
|
792
|
+
# Build kwargs
|
|
793
|
+
kwargs = {
|
|
794
|
+
"model": model,
|
|
795
|
+
"messages": clean_messages,
|
|
796
|
+
"max_tokens": 4096,
|
|
797
|
+
}
|
|
798
|
+
if system and str(system).strip():
|
|
799
|
+
kwargs["system"] = str(system).strip()
|
|
800
|
+
if anthropic_tools:
|
|
801
|
+
kwargs["tools"] = anthropic_tools
|
|
802
|
+
|
|
803
|
+
client = anthropic.AsyncAnthropic(
|
|
804
|
+
api_key=api_key,
|
|
805
|
+
timeout=ANTHROPIC_TIMEOUT,
|
|
806
|
+
max_retries=0, # Disable SDK internal retries — we handle retries ourselves
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80] # seconds between retries
|
|
810
|
+
last_error = None
|
|
811
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
812
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
813
|
+
try:
|
|
814
|
+
print(f"DEBUG: 🔄 Anthropic call start (attempt {attempt}/{MAX_RETRIES})", flush=True)
|
|
815
|
+
response = await client.messages.create(**kwargs)
|
|
816
|
+
print(f"DEBUG: ✅ Anthropic call complete (attempt {attempt})", flush=True)
|
|
817
|
+
# Extract actual token usage from the SDK response object
|
|
818
|
+
input_tokens = getattr(getattr(response, 'usage', None), 'input_tokens', 0) or 0
|
|
819
|
+
output_tokens = getattr(getattr(response, 'usage', None), 'output_tokens', 0) or 0
|
|
820
|
+
return _extract_anthropic_response(response), input_tokens, output_tokens
|
|
821
|
+
except anthropic.APITimeoutError:
|
|
822
|
+
last_error = f"Request timed out ({ANTHROPIC_TIMEOUT}s)"
|
|
823
|
+
print(f"DEBUG: ⏱️ Anthropic timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
824
|
+
if attempt < MAX_RETRIES:
|
|
825
|
+
await asyncio.sleep(backoff)
|
|
826
|
+
continue
|
|
827
|
+
except anthropic.APIStatusError as e:
|
|
828
|
+
last_error = f"API error {e.status_code}: {str(e)[:200]}"
|
|
829
|
+
print(f"DEBUG: ❌ Anthropic API error {e.status_code} on attempt {attempt}/{MAX_RETRIES}: {str(e)[:500]}", flush=True)
|
|
830
|
+
# Retry on transient/rate-limit errors (429 rate limit, 499 client disconnect, 5xx server errors, 529 overloaded)
|
|
831
|
+
if attempt < MAX_RETRIES and e.status_code in (429, 499, 500, 502, 503, 529):
|
|
832
|
+
print(f"DEBUG: ⏳ Retrying in {backoff}s...", flush=True)
|
|
833
|
+
await asyncio.sleep(backoff)
|
|
834
|
+
continue
|
|
835
|
+
# Non-retryable error (400, 401, 403, etc.) or last attempt
|
|
836
|
+
break
|
|
837
|
+
except Exception as e:
|
|
838
|
+
last_error = str(e)
|
|
839
|
+
print(f"DEBUG: ⚠️ Anthropic error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
840
|
+
if attempt < MAX_RETRIES:
|
|
841
|
+
await asyncio.sleep(backoff)
|
|
842
|
+
continue
|
|
843
|
+
|
|
844
|
+
error_msg = f"Claude LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
845
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
846
|
+
raise LLMError(error_msg)
|
|
847
|
+
|
|
848
|
+
def _convert_tools_for_gemini(ollama_tools: list[dict] | None):
|
|
849
|
+
"""Convert Ollama-format tool list to Gemini FunctionDeclaration list.
|
|
850
|
+
|
|
851
|
+
Ollama format:
|
|
852
|
+
[{"type": "function", "function": {"name": ..., "description": ..., "parameters": ...}}]
|
|
853
|
+
Gemini format:
|
|
854
|
+
types.Tool(function_declarations=[FunctionDeclaration(...)])
|
|
855
|
+
"""
|
|
856
|
+
from google.genai import types
|
|
857
|
+
|
|
858
|
+
if not ollama_tools:
|
|
859
|
+
return None
|
|
860
|
+
|
|
861
|
+
declarations = []
|
|
862
|
+
for t in ollama_tools:
|
|
863
|
+
func = t.get("function", {})
|
|
864
|
+
name = func.get("name", "")
|
|
865
|
+
if not name:
|
|
866
|
+
continue
|
|
867
|
+
# Clean up the parameters schema — Gemini doesn't accept 'default' in properties
|
|
868
|
+
params = func.get("parameters", {})
|
|
869
|
+
cleaned_params = _clean_schema_for_gemini(params) if params else None
|
|
870
|
+
declarations.append(types.FunctionDeclaration(
|
|
871
|
+
name=name,
|
|
872
|
+
description=func.get("description", ""),
|
|
873
|
+
parameters=cleaned_params,
|
|
874
|
+
))
|
|
875
|
+
|
|
876
|
+
if not declarations:
|
|
877
|
+
return None
|
|
878
|
+
return [types.Tool(function_declarations=declarations)]
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
def _clean_schema_for_gemini(schema: dict) -> dict:
|
|
882
|
+
"""Remove fields from JSON schema that Gemini doesn't support."""
|
|
883
|
+
UNSUPPORTED_KEYS = {"default", "$schema", "additionalProperties"}
|
|
884
|
+
if not isinstance(schema, dict):
|
|
885
|
+
return schema
|
|
886
|
+
cleaned = {}
|
|
887
|
+
for k, v in schema.items():
|
|
888
|
+
if k in UNSUPPORTED_KEYS:
|
|
889
|
+
continue
|
|
890
|
+
if isinstance(v, dict):
|
|
891
|
+
cleaned[k] = _clean_schema_for_gemini(v)
|
|
892
|
+
elif isinstance(v, list):
|
|
893
|
+
cleaned[k] = [_clean_schema_for_gemini(i) if isinstance(i, dict) else i for i in v]
|
|
894
|
+
else:
|
|
895
|
+
cleaned[k] = v
|
|
896
|
+
return cleaned
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
def _convert_messages_for_gemini(messages: list[dict], images: list[str] | None = None):
|
|
900
|
+
"""Convert OpenAI-style messages to Gemini Content objects.
|
|
901
|
+
|
|
902
|
+
Maps roles: 'user' → 'user', 'assistant' → 'model', 'system' → skip (handled separately).
|
|
903
|
+
If images are provided, they are attached to the last user message.
|
|
904
|
+
"""
|
|
905
|
+
from google.genai import types
|
|
906
|
+
|
|
907
|
+
contents = []
|
|
908
|
+
# Find the index of the last user message for image injection
|
|
909
|
+
last_user_idx = -1
|
|
910
|
+
filtered = [(msg, idx) for idx, msg in enumerate(messages) if msg.get("role") != "system" and msg.get("content")]
|
|
911
|
+
if images:
|
|
912
|
+
for i, (msg, _) in enumerate(filtered):
|
|
913
|
+
if msg.get("role") == "user":
|
|
914
|
+
last_user_idx = i
|
|
915
|
+
|
|
916
|
+
for i, (msg, _) in enumerate(filtered):
|
|
917
|
+
role = msg.get("role", "user")
|
|
918
|
+
text = msg.get("content", "")
|
|
919
|
+
gemini_role = "model" if role == "assistant" else "user"
|
|
920
|
+
parts = [types.Part.from_text(text=text)]
|
|
921
|
+
|
|
922
|
+
# Attach images to the last user message
|
|
923
|
+
if images and i == last_user_idx:
|
|
924
|
+
for img in images[:5]:
|
|
925
|
+
mime, b64 = _parse_data_uri(img)
|
|
926
|
+
parts.append(types.Part.from_bytes(
|
|
927
|
+
data=base64.b64decode(b64),
|
|
928
|
+
mime_type=mime,
|
|
929
|
+
))
|
|
930
|
+
|
|
931
|
+
contents.append(types.Content(role=gemini_role, parts=parts))
|
|
932
|
+
return contents
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
def _extract_gemini_response(response) -> str:
|
|
936
|
+
"""Extract text or function call from a Gemini response."""
|
|
937
|
+
if not response.candidates:
|
|
938
|
+
return "Error: No response candidates from Gemini."
|
|
939
|
+
|
|
940
|
+
candidate = response.candidates[0]
|
|
941
|
+
|
|
942
|
+
if candidate.finish_reason and candidate.finish_reason.name == "SAFETY":
|
|
943
|
+
return "Error: Response blocked by Gemini safety filters."
|
|
944
|
+
|
|
945
|
+
if not candidate.content or not candidate.content.parts:
|
|
946
|
+
reason = candidate.finish_reason.name if candidate.finish_reason else "UNKNOWN"
|
|
947
|
+
return f"Error: Empty Gemini response. Finish Reason: {reason}"
|
|
948
|
+
|
|
949
|
+
# Check for function calls first (native tool calling)
|
|
950
|
+
function_calls = []
|
|
951
|
+
for p in candidate.content.parts:
|
|
952
|
+
if p.function_call:
|
|
953
|
+
fc = p.function_call
|
|
954
|
+
args = dict(fc.args) if fc.args else {}
|
|
955
|
+
function_calls.append({"tool": fc.name, "arguments": args})
|
|
956
|
+
|
|
957
|
+
if function_calls:
|
|
958
|
+
# Return the first function call (ReAct loop processes one at a time)
|
|
959
|
+
if len(function_calls) > 1:
|
|
960
|
+
names = [fc["tool"] for fc in function_calls]
|
|
961
|
+
print(f"DEBUG: ⚠️ Gemini returned {len(function_calls)} function calls: {names}. Using first: {names[0]}")
|
|
962
|
+
return json.dumps(function_calls[0])
|
|
963
|
+
|
|
964
|
+
# Collect text parts
|
|
965
|
+
text_parts = [p.text for p in candidate.content.parts if p.text]
|
|
966
|
+
if text_parts:
|
|
967
|
+
return "\n".join(text_parts)
|
|
968
|
+
|
|
969
|
+
return "Error: Gemini returned no usable content."
|
|
970
|
+
|
|
971
|
+
# Global singleton Gemini client — reuses connection pool, prevents socket exhaustion
|
|
972
|
+
_gemini_client = None
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
async def call_gemini(model, messages, system, api_key, tools=None, images=None):
|
|
976
|
+
"""Call Gemini using the google-genai SDK with native function calling.
|
|
977
|
+
|
|
978
|
+
Args:
|
|
979
|
+
model: Gemini model name (e.g. 'gemini-2.0-flash')
|
|
980
|
+
messages: List of {"role": "user"/"assistant", "content": "..."} dicts
|
|
981
|
+
system: System instruction text
|
|
982
|
+
api_key: Gemini API key
|
|
983
|
+
tools: Ollama-format tool list (converted to Gemini FunctionDeclarations)
|
|
984
|
+
images: List of base64 data-URI image strings to attach to the last user message
|
|
985
|
+
|
|
986
|
+
Returns:
|
|
987
|
+
(response_text, input_tokens, output_tokens)
|
|
988
|
+
"""
|
|
989
|
+
global _gemini_client
|
|
990
|
+
from google import genai
|
|
991
|
+
from google.genai import types
|
|
992
|
+
|
|
993
|
+
GEMINI_TIMEOUT = 180.0 # seconds per attempt
|
|
994
|
+
MAX_RETRIES = 5
|
|
995
|
+
|
|
996
|
+
if _gemini_client is None:
|
|
997
|
+
_gemini_client = genai.Client(
|
|
998
|
+
api_key=api_key,
|
|
999
|
+
# HTTP timeout 5s above wait_for so wait_for fires first for clean handling
|
|
1000
|
+
http_options=types.HttpOptions(timeout=int((GEMINI_TIMEOUT+5) * 1000)), # seconds
|
|
1001
|
+
)
|
|
1002
|
+
|
|
1003
|
+
contents = _convert_messages_for_gemini(messages, images=images)
|
|
1004
|
+
gemini_tools = _convert_tools_for_gemini(tools)
|
|
1005
|
+
|
|
1006
|
+
config = types.GenerateContentConfig(
|
|
1007
|
+
system_instruction=system,
|
|
1008
|
+
)
|
|
1009
|
+
if gemini_tools:
|
|
1010
|
+
config.tools = gemini_tools
|
|
1011
|
+
|
|
1012
|
+
async def _call(cfg, attempt_label=""):
|
|
1013
|
+
print(f"DEBUG: 🔄 Gemini _call start ({attempt_label})", flush=True)
|
|
1014
|
+
result = await asyncio.to_thread(
|
|
1015
|
+
_gemini_client.models.generate_content,
|
|
1016
|
+
model=model,
|
|
1017
|
+
contents=contents,
|
|
1018
|
+
config=cfg,
|
|
1019
|
+
)
|
|
1020
|
+
print(f"DEBUG: ✅ Gemini _call complete ({attempt_label})", flush=True)
|
|
1021
|
+
return result
|
|
1022
|
+
|
|
1023
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80] # seconds between retries
|
|
1024
|
+
last_error = None
|
|
1025
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
1026
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
1027
|
+
try:
|
|
1028
|
+
response = await _call(config, f"attempt {attempt}")
|
|
1029
|
+
result = _extract_gemini_response(response)
|
|
1030
|
+
|
|
1031
|
+
# If MALFORMED_FUNCTION_CALL, retry once without tools (forces text response)
|
|
1032
|
+
if "MALFORMED_FUNCTION_CALL" in result and gemini_tools:
|
|
1033
|
+
print("DEBUG: Gemini MALFORMED_FUNCTION_CALL — retrying without tools")
|
|
1034
|
+
config_no_tools = types.GenerateContentConfig(
|
|
1035
|
+
system_instruction=system,
|
|
1036
|
+
)
|
|
1037
|
+
response = await _call(config_no_tools, "no-tools retry")
|
|
1038
|
+
result = _extract_gemini_response(response)
|
|
1039
|
+
|
|
1040
|
+
# Extract actual token usage from Gemini response metadata
|
|
1041
|
+
input_tokens = 0
|
|
1042
|
+
output_tokens = 0
|
|
1043
|
+
try:
|
|
1044
|
+
um = getattr(response, 'usage_metadata', None)
|
|
1045
|
+
if um:
|
|
1046
|
+
input_tokens = getattr(um, 'prompt_token_count', 0) or 0
|
|
1047
|
+
output_tokens = getattr(um, 'candidates_token_count', 0) or 0
|
|
1048
|
+
except Exception:
|
|
1049
|
+
pass
|
|
1050
|
+
return result, input_tokens, output_tokens
|
|
1051
|
+
|
|
1052
|
+
# except asyncio.TimeoutError:
|
|
1053
|
+
# last_error = f"Request timed out ({GEMINI_TIMEOUT}s)"
|
|
1054
|
+
# print(f"DEBUG: ⚠️ Gemini timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...")
|
|
1055
|
+
# if attempt < MAX_RETRIES:
|
|
1056
|
+
# await asyncio.sleep(backoff)
|
|
1057
|
+
# continue
|
|
1058
|
+
except Exception as e:
|
|
1059
|
+
last_error = str(e)
|
|
1060
|
+
print(f"DEBUG: ⚠️ Unexpected {type(e).__name__}: {vars(e) if hasattr(e, '__dict__') else e}", flush=True)
|
|
1061
|
+
print(f"DEBUG: ⚠️ Gemini error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1062
|
+
if attempt < MAX_RETRIES:
|
|
1063
|
+
print(f"DEBUG: ⏳ Retrying in {backoff}s...", flush=True)
|
|
1064
|
+
await asyncio.sleep(backoff)
|
|
1065
|
+
continue
|
|
1066
|
+
|
|
1067
|
+
error_msg = f"Gemini LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
1068
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
1069
|
+
raise LLMError(error_msg)
|
|
1070
|
+
|
|
1071
|
+
async def call_grok(model, messages, system, api_key, tools=None, images=None):
|
|
1072
|
+
"""Call xAI Grok via its OpenAI-compatible API with 5-attempt exponential backoff.
|
|
1073
|
+
|
|
1074
|
+
Args:
|
|
1075
|
+
model: Grok model name (e.g. 'grok-3', 'grok-3-mini')
|
|
1076
|
+
messages: List of {"role": ..., "content": ...} dicts
|
|
1077
|
+
system: System instruction text
|
|
1078
|
+
api_key: xAI API key (starts with 'xai-')
|
|
1079
|
+
tools: Ollama-format tool list (Grok is OpenAI-compatible for function calling)
|
|
1080
|
+
images: List of base64 data-URI image strings to attach to the last user message
|
|
1081
|
+
|
|
1082
|
+
Returns:
|
|
1083
|
+
(response_text, input_tokens, output_tokens)
|
|
1084
|
+
"""
|
|
1085
|
+
GROK_TIMEOUT = 180.0
|
|
1086
|
+
MAX_RETRIES = 5
|
|
1087
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80]
|
|
1088
|
+
|
|
1089
|
+
# Build full messages list with system prompt
|
|
1090
|
+
full_messages = []
|
|
1091
|
+
if system and str(system).strip():
|
|
1092
|
+
full_messages.append({"role": "system", "content": str(system).strip()})
|
|
1093
|
+
full_messages.extend(messages or [])
|
|
1094
|
+
|
|
1095
|
+
# Inject images into the last user message (Grok is OpenAI-compatible)
|
|
1096
|
+
if images:
|
|
1097
|
+
for i in range(len(full_messages) - 1, -1, -1):
|
|
1098
|
+
if full_messages[i].get("role") == "user":
|
|
1099
|
+
full_messages[i] = dict(full_messages[i])
|
|
1100
|
+
full_messages[i]["content"] = _build_openai_image_content(
|
|
1101
|
+
str(full_messages[i].get("content", "")), images
|
|
1102
|
+
)
|
|
1103
|
+
break
|
|
1104
|
+
|
|
1105
|
+
payload: dict = {"model": model, "messages": full_messages, "max_tokens": 4096}
|
|
1106
|
+
if tools:
|
|
1107
|
+
payload["tools"] = tools
|
|
1108
|
+
payload["tool_choice"] = "auto"
|
|
1109
|
+
|
|
1110
|
+
last_error = None
|
|
1111
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
1112
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
1113
|
+
try:
|
|
1114
|
+
print(f"DEBUG: 🔄 Grok call start (attempt {attempt}/{MAX_RETRIES})", flush=True)
|
|
1115
|
+
async with httpx.AsyncClient(timeout=GROK_TIMEOUT) as client:
|
|
1116
|
+
resp = await client.post(
|
|
1117
|
+
"https://api.x.ai/v1/chat/completions",
|
|
1118
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
1119
|
+
json=payload,
|
|
1120
|
+
)
|
|
1121
|
+
if resp.status_code in (429, 499, 500, 502, 503, 529):
|
|
1122
|
+
last_error = f"HTTP {resp.status_code}: {resp.text[:200]}"
|
|
1123
|
+
print(f"DEBUG: ⏳ Grok {resp.status_code} on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1124
|
+
if attempt < MAX_RETRIES:
|
|
1125
|
+
await asyncio.sleep(backoff)
|
|
1126
|
+
continue
|
|
1127
|
+
resp.raise_for_status()
|
|
1128
|
+
data = resp.json()
|
|
1129
|
+
usage = data.get("usage", {})
|
|
1130
|
+
input_tokens = usage.get("prompt_tokens", 0)
|
|
1131
|
+
output_tokens = usage.get("completion_tokens", 0)
|
|
1132
|
+
choice = data["choices"][0]
|
|
1133
|
+
msg = choice.get("message", {})
|
|
1134
|
+
if msg.get("tool_calls"):
|
|
1135
|
+
tc = msg["tool_calls"][0]
|
|
1136
|
+
text = json.dumps({
|
|
1137
|
+
"tool": tc["function"]["name"],
|
|
1138
|
+
"arguments": json.loads(tc["function"].get("arguments", "{}"))
|
|
1139
|
+
})
|
|
1140
|
+
return text, input_tokens, output_tokens
|
|
1141
|
+
print(f"DEBUG: ✅ Grok call complete (attempt {attempt})", flush=True)
|
|
1142
|
+
return msg.get("content", ""), input_tokens, output_tokens
|
|
1143
|
+
except httpx.TimeoutException:
|
|
1144
|
+
last_error = f"Request timed out ({GROK_TIMEOUT}s)"
|
|
1145
|
+
print(f"DEBUG: ⏱️ Grok timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1146
|
+
if attempt < MAX_RETRIES:
|
|
1147
|
+
await asyncio.sleep(backoff)
|
|
1148
|
+
continue
|
|
1149
|
+
except httpx.HTTPStatusError as e:
|
|
1150
|
+
last_error = f"HTTP {e.response.status_code}: {str(e)[:200]}"
|
|
1151
|
+
print(f"DEBUG: ❌ Grok HTTP error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1152
|
+
if attempt < MAX_RETRIES and e.response.status_code in (429, 499, 500, 502, 503, 529):
|
|
1153
|
+
await asyncio.sleep(backoff)
|
|
1154
|
+
continue
|
|
1155
|
+
break
|
|
1156
|
+
except Exception as e:
|
|
1157
|
+
last_error = str(e)
|
|
1158
|
+
print(f"DEBUG: ⚠️ Grok error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1159
|
+
if attempt < MAX_RETRIES:
|
|
1160
|
+
await asyncio.sleep(backoff)
|
|
1161
|
+
continue
|
|
1162
|
+
|
|
1163
|
+
error_msg = f"Grok LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
1164
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
1165
|
+
raise LLMError(error_msg)
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
async def call_deepseek(model, messages, system, api_key, tools=None, images=None):
|
|
1169
|
+
"""Call DeepSeek via its OpenAI-compatible API with 5-attempt exponential backoff.
|
|
1170
|
+
|
|
1171
|
+
Args:
|
|
1172
|
+
model: DeepSeek model name (e.g. 'deepseek-chat', 'deepseek-reasoner')
|
|
1173
|
+
messages: List of {"role": ..., "content": ...} dicts
|
|
1174
|
+
system: System instruction text
|
|
1175
|
+
api_key: DeepSeek API key
|
|
1176
|
+
tools: Ollama-format tool list (deepseek-chat supports function calling;
|
|
1177
|
+
deepseek-reasoner does NOT — tools are silently dropped for it)
|
|
1178
|
+
images: List of base64 data-URI image strings (NOT SUPPORTED — silently dropped)
|
|
1179
|
+
|
|
1180
|
+
Returns:
|
|
1181
|
+
(response_text, input_tokens, output_tokens)
|
|
1182
|
+
"""
|
|
1183
|
+
# DeepSeek does not support vision — drop images with a warning
|
|
1184
|
+
if images:
|
|
1185
|
+
print(f"DEBUG: ⚠️ DeepSeek does not support images. {len(images)} image(s) will be dropped.", flush=True)
|
|
1186
|
+
DEEPSEEK_TIMEOUT = 180.0
|
|
1187
|
+
MAX_RETRIES = 5
|
|
1188
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80]
|
|
1189
|
+
|
|
1190
|
+
# Build full messages list with system prompt
|
|
1191
|
+
full_messages = []
|
|
1192
|
+
if system and str(system).strip():
|
|
1193
|
+
full_messages.append({"role": "system", "content": str(system).strip()})
|
|
1194
|
+
full_messages.extend(messages or [])
|
|
1195
|
+
|
|
1196
|
+
payload: dict = {"model": model, "messages": full_messages, "max_tokens": 4096}
|
|
1197
|
+
# DeepSeek-Reasoner does not support function calling
|
|
1198
|
+
if tools and "reasoner" not in model.lower():
|
|
1199
|
+
payload["tools"] = tools
|
|
1200
|
+
payload["tool_choice"] = "auto"
|
|
1201
|
+
|
|
1202
|
+
last_error = None
|
|
1203
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
1204
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
1205
|
+
try:
|
|
1206
|
+
print(f"DEBUG: 🔄 DeepSeek call start (attempt {attempt}/{MAX_RETRIES})", flush=True)
|
|
1207
|
+
async with httpx.AsyncClient(timeout=DEEPSEEK_TIMEOUT) as client:
|
|
1208
|
+
resp = await client.post(
|
|
1209
|
+
"https://api.deepseek.com/v1/chat/completions",
|
|
1210
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
1211
|
+
json=payload,
|
|
1212
|
+
)
|
|
1213
|
+
if resp.status_code in (429, 499, 500, 502, 503, 529):
|
|
1214
|
+
last_error = f"HTTP {resp.status_code}: {resp.text[:200]}"
|
|
1215
|
+
print(f"DEBUG: ⏳ DeepSeek {resp.status_code} on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1216
|
+
if attempt < MAX_RETRIES:
|
|
1217
|
+
await asyncio.sleep(backoff)
|
|
1218
|
+
continue
|
|
1219
|
+
resp.raise_for_status()
|
|
1220
|
+
data = resp.json()
|
|
1221
|
+
usage = data.get("usage", {})
|
|
1222
|
+
input_tokens = usage.get("prompt_tokens", 0)
|
|
1223
|
+
output_tokens = usage.get("completion_tokens", 0)
|
|
1224
|
+
choice = data["choices"][0]
|
|
1225
|
+
msg = choice.get("message", {})
|
|
1226
|
+
if msg.get("tool_calls"):
|
|
1227
|
+
tc = msg["tool_calls"][0]
|
|
1228
|
+
text = json.dumps({
|
|
1229
|
+
"tool": tc["function"]["name"],
|
|
1230
|
+
"arguments": json.loads(tc["function"].get("arguments", "{}"))
|
|
1231
|
+
})
|
|
1232
|
+
return text, input_tokens, output_tokens
|
|
1233
|
+
print(f"DEBUG: ✅ DeepSeek call complete (attempt {attempt})", flush=True)
|
|
1234
|
+
return msg.get("content", ""), input_tokens, output_tokens
|
|
1235
|
+
except httpx.TimeoutException:
|
|
1236
|
+
last_error = f"Request timed out ({DEEPSEEK_TIMEOUT}s)"
|
|
1237
|
+
print(f"DEBUG: ⏱️ DeepSeek timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1238
|
+
if attempt < MAX_RETRIES:
|
|
1239
|
+
await asyncio.sleep(backoff)
|
|
1240
|
+
continue
|
|
1241
|
+
except httpx.HTTPStatusError as e:
|
|
1242
|
+
last_error = f"HTTP {e.response.status_code}: {str(e)[:200]}"
|
|
1243
|
+
print(f"DEBUG: ❌ DeepSeek HTTP error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1244
|
+
if attempt < MAX_RETRIES and e.response.status_code in (429, 499, 500, 502, 503, 529):
|
|
1245
|
+
await asyncio.sleep(backoff)
|
|
1246
|
+
continue
|
|
1247
|
+
break
|
|
1248
|
+
except Exception as e:
|
|
1249
|
+
last_error = str(e)
|
|
1250
|
+
print(f"DEBUG: ⚠️ DeepSeek error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1251
|
+
if attempt < MAX_RETRIES:
|
|
1252
|
+
await asyncio.sleep(backoff)
|
|
1253
|
+
continue
|
|
1254
|
+
|
|
1255
|
+
error_msg = f"DeepSeek LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
1256
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
1257
|
+
raise LLMError(error_msg)
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
def _normalize_v1_base_url(base_url: str) -> str:
|
|
1261
|
+
"""Normalize a v1-compatible base URL by stripping trailing /v1."""
|
|
1262
|
+
url = base_url.rstrip("/")
|
|
1263
|
+
if url.endswith("/v1"):
|
|
1264
|
+
url = url[:-3]
|
|
1265
|
+
return url
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
async def call_v1_compatible(model, messages, system, base_url, api_key, tools=None, images=None):
|
|
1269
|
+
"""Call any OpenAI v1-compatible endpoint with 5-attempt exponential backoff.
|
|
1270
|
+
|
|
1271
|
+
Used for both cloud OpenAI-compatible providers (OpenRouter, Together, etc.)
|
|
1272
|
+
and local v1-compatible servers (vLLM, LM Studio, etc.).
|
|
1273
|
+
|
|
1274
|
+
The model name is expected to have its prefix (oaic. or locv1.) already stripped
|
|
1275
|
+
before calling this function.
|
|
1276
|
+
|
|
1277
|
+
Args:
|
|
1278
|
+
model: Model name as known by the remote API (prefix already stripped)
|
|
1279
|
+
messages: List of {"role": ..., "content": ...} dicts
|
|
1280
|
+
system: System instruction text
|
|
1281
|
+
base_url: Base URL (e.g. https://openrouter.ai/api) — /v1/chat/completions appended
|
|
1282
|
+
api_key: API key (may be empty for local servers with no auth)
|
|
1283
|
+
tools: Ollama-format tool list (forwarded as OpenAI function definitions)
|
|
1284
|
+
images: List of base64 data-URI image strings to attach to the last user message
|
|
1285
|
+
|
|
1286
|
+
Returns:
|
|
1287
|
+
(response_text, input_tokens, output_tokens)
|
|
1288
|
+
"""
|
|
1289
|
+
if not base_url or not base_url.strip():
|
|
1290
|
+
raise LLMError("V1-compatible provider: base URL is not configured.")
|
|
1291
|
+
|
|
1292
|
+
V1_TIMEOUT = 180.0
|
|
1293
|
+
MAX_RETRIES = 5
|
|
1294
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80]
|
|
1295
|
+
|
|
1296
|
+
full_messages = []
|
|
1297
|
+
if system and str(system).strip():
|
|
1298
|
+
full_messages.append({"role": "system", "content": str(system).strip()})
|
|
1299
|
+
full_messages.extend(messages or [])
|
|
1300
|
+
|
|
1301
|
+
if images:
|
|
1302
|
+
for i in range(len(full_messages) - 1, -1, -1):
|
|
1303
|
+
if full_messages[i].get("role") == "user":
|
|
1304
|
+
full_messages[i] = dict(full_messages[i])
|
|
1305
|
+
full_messages[i]["content"] = _build_openai_image_content(
|
|
1306
|
+
str(full_messages[i].get("content", "")), images
|
|
1307
|
+
)
|
|
1308
|
+
break
|
|
1309
|
+
|
|
1310
|
+
payload: dict = {"model": model, "messages": full_messages}
|
|
1311
|
+
if tools:
|
|
1312
|
+
payload["tools"] = tools
|
|
1313
|
+
payload["tool_choice"] = "auto"
|
|
1314
|
+
|
|
1315
|
+
endpoint = f"{_normalize_v1_base_url(base_url)}/v1/chat/completions"
|
|
1316
|
+
headers = {}
|
|
1317
|
+
if api_key:
|
|
1318
|
+
headers["Authorization"] = f"Bearer {api_key}"
|
|
1319
|
+
|
|
1320
|
+
last_error = None
|
|
1321
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
1322
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
1323
|
+
try:
|
|
1324
|
+
async with httpx.AsyncClient(timeout=V1_TIMEOUT) as client:
|
|
1325
|
+
resp = await client.post(endpoint, headers=headers, json=payload)
|
|
1326
|
+
if resp.status_code in (429, 499, 500, 502, 503, 529):
|
|
1327
|
+
last_error = f"HTTP {resp.status_code}: {resp.text[:200]}"
|
|
1328
|
+
print(f"DEBUG: ⏳ V1-compatible {resp.status_code} on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1329
|
+
if attempt < MAX_RETRIES:
|
|
1330
|
+
await asyncio.sleep(backoff)
|
|
1331
|
+
continue
|
|
1332
|
+
resp.raise_for_status()
|
|
1333
|
+
data = resp.json()
|
|
1334
|
+
usage = data.get("usage", {})
|
|
1335
|
+
input_tokens = usage.get("prompt_tokens", 0)
|
|
1336
|
+
output_tokens = usage.get("completion_tokens", 0)
|
|
1337
|
+
choice = data["choices"][0]
|
|
1338
|
+
msg = choice.get("message", {})
|
|
1339
|
+
if msg.get("tool_calls"):
|
|
1340
|
+
tc = msg["tool_calls"][0]
|
|
1341
|
+
text = json.dumps({
|
|
1342
|
+
"tool": tc["function"]["name"],
|
|
1343
|
+
"arguments": json.loads(tc["function"].get("arguments", "{}"))
|
|
1344
|
+
})
|
|
1345
|
+
return text, input_tokens, output_tokens
|
|
1346
|
+
print(f"DEBUG: ✅ V1-compatible call complete (attempt {attempt})", flush=True)
|
|
1347
|
+
return msg.get("content", ""), input_tokens, output_tokens
|
|
1348
|
+
except httpx.TimeoutException:
|
|
1349
|
+
last_error = f"Request timed out ({V1_TIMEOUT}s)"
|
|
1350
|
+
print(f"DEBUG: ⏱️ V1-compatible timeout on attempt {attempt}/{MAX_RETRIES}. Retrying in {backoff}s...", flush=True)
|
|
1351
|
+
if attempt < MAX_RETRIES:
|
|
1352
|
+
await asyncio.sleep(backoff)
|
|
1353
|
+
continue
|
|
1354
|
+
except httpx.HTTPStatusError as e:
|
|
1355
|
+
last_error = f"HTTP {e.response.status_code}: {str(e)[:200]}"
|
|
1356
|
+
print(f"DEBUG: ❌ V1-compatible HTTP error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1357
|
+
if attempt < MAX_RETRIES and e.response.status_code in (429, 499, 500, 502, 503, 529):
|
|
1358
|
+
await asyncio.sleep(backoff)
|
|
1359
|
+
continue
|
|
1360
|
+
break
|
|
1361
|
+
except Exception as e:
|
|
1362
|
+
last_error = str(e)
|
|
1363
|
+
print(f"DEBUG: ⚠️ V1-compatible error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1364
|
+
if attempt < MAX_RETRIES:
|
|
1365
|
+
await asyncio.sleep(backoff)
|
|
1366
|
+
continue
|
|
1367
|
+
|
|
1368
|
+
error_msg = f"V1-compatible LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
1369
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
1370
|
+
raise LLMError(error_msg)
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
async def _bedrock_converse_direct(
|
|
1374
|
+
region: str, api_key: str, model_id: str,
|
|
1375
|
+
messages: list, system_blocks: list, max_tokens: int,
|
|
1376
|
+
) -> dict:
|
|
1377
|
+
"""Call Bedrock Converse via boto3 with UNSIGNED auth + before-send bearer injection.
|
|
1378
|
+
|
|
1379
|
+
Used for long-term ABSK keys. boto3's before-send event fires right before urllib3
|
|
1380
|
+
sends the HTTP request; we inject Authorization: Bearer {api_key} so botocore signing
|
|
1381
|
+
(disabled via UNSIGNED) cannot interfere.
|
|
1382
|
+
boto3 handles image-bytes serialisation natively; no manual base64 conversion needed.
|
|
1383
|
+
"""
|
|
1384
|
+
def _make_client():
|
|
1385
|
+
session = boto3.session.Session()
|
|
1386
|
+
|
|
1387
|
+
def _inject_auth(request, **kwargs): # noqa: ARG001
|
|
1388
|
+
request.headers['Authorization'] = f'Bearer {api_key}'
|
|
1389
|
+
|
|
1390
|
+
# Register on the session so it applies to this client only.
|
|
1391
|
+
# before-send fires with AWSPreparedRequest; returning None lets the
|
|
1392
|
+
# call proceed normally with the injected header.
|
|
1393
|
+
session.events.register(
|
|
1394
|
+
'before-send.bedrock-runtime.Converse',
|
|
1395
|
+
_inject_auth,
|
|
1396
|
+
)
|
|
1397
|
+
|
|
1398
|
+
return session.client(
|
|
1399
|
+
'bedrock-runtime',
|
|
1400
|
+
region_name=region,
|
|
1401
|
+
aws_access_key_id='unsigned',
|
|
1402
|
+
aws_secret_access_key='unsigned',
|
|
1403
|
+
config=Config(signature_version=_BEDROCK_UNSIGNED),
|
|
1404
|
+
)
|
|
1405
|
+
|
|
1406
|
+
def _run():
|
|
1407
|
+
client = _make_client()
|
|
1408
|
+
try:
|
|
1409
|
+
return client.converse(
|
|
1410
|
+
modelId=model_id,
|
|
1411
|
+
messages=messages,
|
|
1412
|
+
system=system_blocks,
|
|
1413
|
+
inferenceConfig={'maxTokens': max_tokens},
|
|
1414
|
+
)
|
|
1415
|
+
except botocore.exceptions.ClientError as e:
|
|
1416
|
+
status = e.response.get('ResponseMetadata', {}).get('HTTPStatusCode', 0)
|
|
1417
|
+
msg = e.response.get('Error', {}).get('Message', str(e))
|
|
1418
|
+
raise RuntimeError(f"HTTP {status}: {msg}") from e
|
|
1419
|
+
|
|
1420
|
+
return await asyncio.to_thread(_run)
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
async def call_bedrock(model_id, messages, system, region, settings, images=None):
|
|
1424
|
+
"""Call AWS Bedrock with 5-attempt exponential backoff retry loop.
|
|
1425
|
+
|
|
1426
|
+
Prefers the Converse API (standardized); falls back to InvokeModel for older models.
|
|
1427
|
+
Raises LLMError on final failure after all retries.
|
|
1428
|
+
"""
|
|
1429
|
+
MAX_RETRIES = 5
|
|
1430
|
+
BACKOFF_SCHEDULE = [5, 10, 20, 40, 80]
|
|
1431
|
+
|
|
1432
|
+
# Bedrock requires the exact model ID (e.g., anthropic.claude-3-5-sonnet-20240620-v1:0)
|
|
1433
|
+
# We strip the 'bedrock.' prefix if present
|
|
1434
|
+
real_model_id = model_id.replace("bedrock.", "")
|
|
1435
|
+
|
|
1436
|
+
# Some Bedrock models require an inference profile (no on-demand throughput).
|
|
1437
|
+
invocation_model_id = real_model_id
|
|
1438
|
+
inference_profile = (settings.get("bedrock_inference_profile") or "").strip()
|
|
1439
|
+
if inference_profile:
|
|
1440
|
+
if inference_profile.startswith("bedrock."):
|
|
1441
|
+
inference_profile = inference_profile.replace("bedrock.", "", 1)
|
|
1442
|
+
invocation_model_id = inference_profile
|
|
1443
|
+
|
|
1444
|
+
bedrock = _make_aws_client("bedrock-runtime", region, settings)
|
|
1445
|
+
bedrock_api_key = _normalize_bedrock_api_key(settings)
|
|
1446
|
+
effective_region = (region or settings.get("aws_region") or "us-east-1").strip()
|
|
1447
|
+
max_tokens = int(settings.get("bedrock_max_tokens") or 4096)
|
|
1448
|
+
|
|
1449
|
+
# Normalize messages to Bedrock Converse content-block format
|
|
1450
|
+
normalized_messages = []
|
|
1451
|
+
# Find the last user message index for image injection
|
|
1452
|
+
all_msgs = [m for m in (messages or []) if m.get("role") in ("user", "assistant")]
|
|
1453
|
+
last_user_idx = -1
|
|
1454
|
+
if images:
|
|
1455
|
+
for idx_m, m in enumerate(all_msgs):
|
|
1456
|
+
if m.get("role") == "user":
|
|
1457
|
+
last_user_idx = idx_m
|
|
1458
|
+
|
|
1459
|
+
for idx_m, m in enumerate(all_msgs):
|
|
1460
|
+
role = m.get("role")
|
|
1461
|
+
content = m.get("content")
|
|
1462
|
+
blocks = []
|
|
1463
|
+
if isinstance(content, str):
|
|
1464
|
+
blocks.append({"text": content})
|
|
1465
|
+
elif isinstance(content, list):
|
|
1466
|
+
for b in content:
|
|
1467
|
+
if isinstance(b, dict) and "text" in b:
|
|
1468
|
+
blocks.append({"text": str(b.get("text"))})
|
|
1469
|
+
elif isinstance(b, dict) and b.get("type") == "text" and "text" in b:
|
|
1470
|
+
blocks.append({"text": str(b.get("text"))})
|
|
1471
|
+
else:
|
|
1472
|
+
blocks.append({"text": str(b)})
|
|
1473
|
+
else:
|
|
1474
|
+
blocks.append({"text": str(content)})
|
|
1475
|
+
|
|
1476
|
+
# Inject images into the last user message
|
|
1477
|
+
if images and idx_m == last_user_idx:
|
|
1478
|
+
for img in images[:5]:
|
|
1479
|
+
mime, b64 = _parse_data_uri(img)
|
|
1480
|
+
# Map MIME to Bedrock format name
|
|
1481
|
+
fmt_map = {"image/png": "png", "image/jpeg": "jpeg", "image/gif": "gif", "image/webp": "webp"}
|
|
1482
|
+
fmt = fmt_map.get(mime, "png")
|
|
1483
|
+
blocks.append({"image": {"format": fmt, "source": {"bytes": base64.b64decode(b64)}}})
|
|
1484
|
+
|
|
1485
|
+
normalized_messages.append({"role": role, "content": blocks})
|
|
1486
|
+
|
|
1487
|
+
system_blocks = []
|
|
1488
|
+
if system and str(system).strip():
|
|
1489
|
+
system_blocks = [{"text": str(system)}]
|
|
1490
|
+
|
|
1491
|
+
async def _converse_call():
|
|
1492
|
+
def _run():
|
|
1493
|
+
return bedrock.converse(
|
|
1494
|
+
modelId=invocation_model_id,
|
|
1495
|
+
messages=normalized_messages,
|
|
1496
|
+
system=system_blocks,
|
|
1497
|
+
inferenceConfig={"maxTokens": max_tokens},
|
|
1498
|
+
)
|
|
1499
|
+
return await asyncio.to_thread(_run)
|
|
1500
|
+
|
|
1501
|
+
async def _invoke_model_call():
|
|
1502
|
+
anthropic_messages = []
|
|
1503
|
+
for m in normalized_messages:
|
|
1504
|
+
anthropic_messages.append({
|
|
1505
|
+
"role": m["role"],
|
|
1506
|
+
"content": [{"type": "text", "text": b.get("text", "")} for b in (m.get("content") or [])],
|
|
1507
|
+
})
|
|
1508
|
+
payload = {
|
|
1509
|
+
"anthropic_version": "bedrock-2023-05-31",
|
|
1510
|
+
"max_tokens": max_tokens,
|
|
1511
|
+
"system": str(system or ""),
|
|
1512
|
+
"messages": anthropic_messages,
|
|
1513
|
+
}
|
|
1514
|
+
def _run():
|
|
1515
|
+
return bedrock.invoke_model(
|
|
1516
|
+
body=json.dumps(payload).encode("utf-8"),
|
|
1517
|
+
modelId=invocation_model_id,
|
|
1518
|
+
accept="application/json",
|
|
1519
|
+
contentType="application/json",
|
|
1520
|
+
)
|
|
1521
|
+
return await asyncio.to_thread(_run)
|
|
1522
|
+
|
|
1523
|
+
last_error = None
|
|
1524
|
+
for attempt in range(1, MAX_RETRIES + 1):
|
|
1525
|
+
backoff = BACKOFF_SCHEDULE[attempt - 1]
|
|
1526
|
+
try:
|
|
1527
|
+
print(f"DEBUG: 🔄 Bedrock call start (attempt {attempt}/{MAX_RETRIES})", flush=True)
|
|
1528
|
+
if hasattr(bedrock, "converse") or bedrock_api_key:
|
|
1529
|
+
try:
|
|
1530
|
+
if bedrock_api_key:
|
|
1531
|
+
resp = await _bedrock_converse_direct(
|
|
1532
|
+
effective_region, bedrock_api_key, invocation_model_id,
|
|
1533
|
+
normalized_messages, system_blocks, max_tokens,
|
|
1534
|
+
)
|
|
1535
|
+
else:
|
|
1536
|
+
resp = await _converse_call()
|
|
1537
|
+
msg = (((resp or {}).get("output") or {}).get("message") or {})
|
|
1538
|
+
content = msg.get("content") or []
|
|
1539
|
+
if content and isinstance(content, list) and isinstance(content[0], dict):
|
|
1540
|
+
print(f"DEBUG: ✅ Bedrock (converse) complete (attempt {attempt})", flush=True)
|
|
1541
|
+
return content[0].get("text", "")
|
|
1542
|
+
return ""
|
|
1543
|
+
except Exception as converse_err:
|
|
1544
|
+
msg_str = str(converse_err)
|
|
1545
|
+
if "on-demand throughput" in msg_str:
|
|
1546
|
+
raise LLMError(
|
|
1547
|
+
"Bedrock model requires an inference profile (no on-demand throughput). "
|
|
1548
|
+
"Set Bedrock Inference Profile in settings, or pick a different model."
|
|
1549
|
+
)
|
|
1550
|
+
# Auth failures: raise immediately — InvokeModel also requires SigV4
|
|
1551
|
+
# and won't help when bearer token auth fails.
|
|
1552
|
+
if "AccessDeniedException" in msg_str or "HTTP 403" in msg_str or "Invalid API Key" in msg_str:
|
|
1553
|
+
raise LLMError(
|
|
1554
|
+
f"Bedrock authentication failed: {converse_err}. "
|
|
1555
|
+
"Check your API key or IAM credentials in Settings."
|
|
1556
|
+
)
|
|
1557
|
+
print(f"DEBUG: Bedrock converse failed (attempt {attempt}), falling back to invoke_model: {converse_err}")
|
|
1558
|
+
# Fall through to InvokeModel (for older models not on Converse API)
|
|
1559
|
+
resp = await _invoke_model_call()
|
|
1560
|
+
response_body = json.loads(resp.get("body").read()) if resp and resp.get("body") else {}
|
|
1561
|
+
content = response_body.get("content") or []
|
|
1562
|
+
if content and isinstance(content, list) and isinstance(content[0], dict):
|
|
1563
|
+
print(f"DEBUG: ✅ Bedrock (invoke_model) complete (attempt {attempt})", flush=True)
|
|
1564
|
+
return content[0].get("text", "")
|
|
1565
|
+
return ""
|
|
1566
|
+
else:
|
|
1567
|
+
resp = await _invoke_model_call()
|
|
1568
|
+
response_body = json.loads(resp.get("body").read()) if resp and resp.get("body") else {}
|
|
1569
|
+
content = response_body.get("content") or []
|
|
1570
|
+
if content and isinstance(content, list) and isinstance(content[0], dict):
|
|
1571
|
+
print(f"DEBUG: ✅ Bedrock (invoke_model) complete (attempt {attempt})", flush=True)
|
|
1572
|
+
return content[0].get("text", "")
|
|
1573
|
+
return ""
|
|
1574
|
+
except LLMError:
|
|
1575
|
+
raise # Non-retryable (config error)
|
|
1576
|
+
except Exception as e:
|
|
1577
|
+
last_error = str(e)
|
|
1578
|
+
print(f"DEBUG: ⚠️ Bedrock error on attempt {attempt}/{MAX_RETRIES}: {e}", flush=True)
|
|
1579
|
+
if attempt < MAX_RETRIES:
|
|
1580
|
+
print(f"DEBUG: ⏳ Retrying Bedrock in {backoff}s...", flush=True)
|
|
1581
|
+
await asyncio.sleep(backoff)
|
|
1582
|
+
continue
|
|
1583
|
+
|
|
1584
|
+
error_msg = f"Bedrock LLM Error: All {MAX_RETRIES} attempts failed. Last error: {last_error}"
|
|
1585
|
+
print(f"DEBUG: ❌ {error_msg}", flush=True)
|
|
1586
|
+
raise LLMError(error_msg)
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
def _messages_to_transcript(messages: list[dict] | None) -> str:
|
|
1590
|
+
"""Lossy conversion of role/content messages to plain text for providers that only accept a single prompt."""
|
|
1591
|
+
if not messages:
|
|
1592
|
+
return ""
|
|
1593
|
+
lines: list[str] = []
|
|
1594
|
+
for m in messages:
|
|
1595
|
+
if not isinstance(m, dict):
|
|
1596
|
+
continue
|
|
1597
|
+
role = (m.get("role") or "").strip().lower()
|
|
1598
|
+
content = m.get("content")
|
|
1599
|
+
if isinstance(content, list):
|
|
1600
|
+
# Best-effort concatenate any text blocks
|
|
1601
|
+
parts: list[str] = []
|
|
1602
|
+
for p in content:
|
|
1603
|
+
if isinstance(p, dict) and isinstance(p.get("text"), str):
|
|
1604
|
+
parts.append(p["text"])
|
|
1605
|
+
text = "\n".join(parts).strip()
|
|
1606
|
+
else:
|
|
1607
|
+
text = (content or "").strip() if isinstance(content, str) else ""
|
|
1608
|
+
|
|
1609
|
+
if not text:
|
|
1610
|
+
continue
|
|
1611
|
+
|
|
1612
|
+
if role == "user":
|
|
1613
|
+
label = "User"
|
|
1614
|
+
elif role == "assistant":
|
|
1615
|
+
label = "Assistant"
|
|
1616
|
+
elif role:
|
|
1617
|
+
label = role.title()
|
|
1618
|
+
else:
|
|
1619
|
+
label = "Message"
|
|
1620
|
+
lines.append(f"{label}: {text}")
|
|
1621
|
+
return "\n".join(lines)
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
async def generate_response(
|
|
1625
|
+
prompt_msg,
|
|
1626
|
+
sys_prompt,
|
|
1627
|
+
mode,
|
|
1628
|
+
current_model,
|
|
1629
|
+
current_settings,
|
|
1630
|
+
tools=None,
|
|
1631
|
+
history_messages=None,
|
|
1632
|
+
memory_context_text: str = "",
|
|
1633
|
+
# Usage tracking context — passed by react_engine & orchestration steps
|
|
1634
|
+
session_id: str | None = None,
|
|
1635
|
+
agent_id: str | None = None,
|
|
1636
|
+
source: str = "chat",
|
|
1637
|
+
run_id: str | None = None,
|
|
1638
|
+
tool_name: str | None = None,
|
|
1639
|
+
images: list[str] | None = None,
|
|
1640
|
+
):
|
|
1641
|
+
"""
|
|
1642
|
+
Unified LLM dispatch function. Routes to the appropriate provider
|
|
1643
|
+
based on mode and current_model. Logs token usage and cost after
|
|
1644
|
+
every successful call via usage_tracker.
|
|
1645
|
+
"""
|
|
1646
|
+
import time as _time
|
|
1647
|
+
from core import usage_tracker
|
|
1648
|
+
|
|
1649
|
+
augmented_system = (sys_prompt or "").strip()
|
|
1650
|
+
if memory_context_text and memory_context_text.strip():
|
|
1651
|
+
augmented_system = f"{augmented_system}\n\n{memory_context_text.strip()}".strip()
|
|
1652
|
+
|
|
1653
|
+
# Build the full context string for char-count tracking
|
|
1654
|
+
_all_msgs = []
|
|
1655
|
+
if history_messages:
|
|
1656
|
+
_all_msgs.extend(history_messages)
|
|
1657
|
+
_all_msgs.append({"role": "user", "content": prompt_msg})
|
|
1658
|
+
context_chars = sum(len(str(m.get("content", ""))) for m in _all_msgs) + len(augmented_system)
|
|
1659
|
+
|
|
1660
|
+
_t0 = _time.time()
|
|
1661
|
+
result_text = ""
|
|
1662
|
+
input_tokens = 0
|
|
1663
|
+
output_tokens = 0
|
|
1664
|
+
|
|
1665
|
+
if mode in ["cloud", "bedrock"]:
|
|
1666
|
+
try:
|
|
1667
|
+
# Construct messages list for cloud providers that support it
|
|
1668
|
+
messages = []
|
|
1669
|
+
if history_messages:
|
|
1670
|
+
messages.extend(history_messages)
|
|
1671
|
+
messages.append({"role": "user", "content": prompt_msg})
|
|
1672
|
+
|
|
1673
|
+
if current_model.startswith("gpt"):
|
|
1674
|
+
result_text, input_tokens, output_tokens = await call_openai(
|
|
1675
|
+
current_model,
|
|
1676
|
+
[{"role": "system", "content": augmented_system}] + messages,
|
|
1677
|
+
current_settings.get("openai_key"),
|
|
1678
|
+
tools=tools,
|
|
1679
|
+
images=images,
|
|
1680
|
+
)
|
|
1681
|
+
elif current_model.startswith("claude"):
|
|
1682
|
+
result_text, input_tokens, output_tokens = await call_anthropic(
|
|
1683
|
+
current_model,
|
|
1684
|
+
messages,
|
|
1685
|
+
augmented_system,
|
|
1686
|
+
current_settings.get("anthropic_key"),
|
|
1687
|
+
tools=tools,
|
|
1688
|
+
images=images,
|
|
1689
|
+
)
|
|
1690
|
+
elif current_model.startswith("gemini") or current_model.startswith("gemma") or current_model.startswith("lyria"):
|
|
1691
|
+
result_text, input_tokens, output_tokens = await call_gemini(
|
|
1692
|
+
current_model,
|
|
1693
|
+
messages,
|
|
1694
|
+
augmented_system,
|
|
1695
|
+
current_settings.get("gemini_key"),
|
|
1696
|
+
tools=tools,
|
|
1697
|
+
images=images,
|
|
1698
|
+
)
|
|
1699
|
+
elif current_model.startswith("bedrock"):
|
|
1700
|
+
result_text = await call_bedrock(
|
|
1701
|
+
current_model,
|
|
1702
|
+
messages,
|
|
1703
|
+
augmented_system,
|
|
1704
|
+
current_settings.get("aws_region"),
|
|
1705
|
+
current_settings,
|
|
1706
|
+
images=images,
|
|
1707
|
+
)
|
|
1708
|
+
# Bedrock does not surface token counts the same way — fall back to heuristic
|
|
1709
|
+
input_tokens = usage_tracker.estimate_tokens_from_text(
|
|
1710
|
+
augmented_system + " ".join(str(m.get("content", "")) for m in messages)
|
|
1711
|
+
)
|
|
1712
|
+
output_tokens = usage_tracker.estimate_tokens_from_text(result_text)
|
|
1713
|
+
elif current_model.startswith("grok"):
|
|
1714
|
+
result_text, input_tokens, output_tokens = await call_grok(
|
|
1715
|
+
current_model,
|
|
1716
|
+
messages,
|
|
1717
|
+
augmented_system,
|
|
1718
|
+
current_settings.get("grok_key"),
|
|
1719
|
+
tools=tools,
|
|
1720
|
+
images=images,
|
|
1721
|
+
)
|
|
1722
|
+
elif current_model.startswith("deepseek"):
|
|
1723
|
+
result_text, input_tokens, output_tokens = await call_deepseek(
|
|
1724
|
+
current_model,
|
|
1725
|
+
messages,
|
|
1726
|
+
augmented_system,
|
|
1727
|
+
current_settings.get("deepseek_key"),
|
|
1728
|
+
tools=tools,
|
|
1729
|
+
images=images,
|
|
1730
|
+
)
|
|
1731
|
+
elif current_model.startswith("oaic."):
|
|
1732
|
+
result_text, input_tokens, output_tokens = await call_v1_compatible(
|
|
1733
|
+
current_model[len("oaic."):],
|
|
1734
|
+
messages,
|
|
1735
|
+
augmented_system,
|
|
1736
|
+
current_settings.get("openai_compatible_base_url", ""),
|
|
1737
|
+
current_settings.get("openai_compatible_key", ""),
|
|
1738
|
+
tools=tools,
|
|
1739
|
+
images=images,
|
|
1740
|
+
)
|
|
1741
|
+
elif current_model.startswith("locv1."):
|
|
1742
|
+
result_text, input_tokens, output_tokens = await call_v1_compatible(
|
|
1743
|
+
current_model[len("locv1."):],
|
|
1744
|
+
messages,
|
|
1745
|
+
augmented_system,
|
|
1746
|
+
current_settings.get("local_compatible_base_url", ""),
|
|
1747
|
+
current_settings.get("local_compatible_key", ""),
|
|
1748
|
+
tools=tools,
|
|
1749
|
+
images=images,
|
|
1750
|
+
)
|
|
1751
|
+
else:
|
|
1752
|
+
return "Error: Unknown cloud model selected."
|
|
1753
|
+
except LLMError:
|
|
1754
|
+
# LLM errors must propagate — do NOT swallow them.
|
|
1755
|
+
# Orchestration engine will catch this and stop execution.
|
|
1756
|
+
raise
|
|
1757
|
+
except Exception as e:
|
|
1758
|
+
return f"Cloud API Error: {str(e)}"
|
|
1759
|
+
|
|
1760
|
+
elif mode == "cli":
|
|
1761
|
+
# CLI session providers: build a flat prompt and spawn the local binary.
|
|
1762
|
+
# No API key required — uses the user's existing CLI authentication.
|
|
1763
|
+
try:
|
|
1764
|
+
messages_for_cli = []
|
|
1765
|
+
if history_messages:
|
|
1766
|
+
messages_for_cli.extend(history_messages)
|
|
1767
|
+
messages_for_cli.append({"role": "user", "content": prompt_msg})
|
|
1768
|
+
|
|
1769
|
+
cli_full_prompt = _build_cli_prompt(
|
|
1770
|
+
sys_prompt=augmented_system,
|
|
1771
|
+
messages=messages_for_cli,
|
|
1772
|
+
tools=tools,
|
|
1773
|
+
)
|
|
1774
|
+
|
|
1775
|
+
# Load the existing CLI session ID for this agent+session (if any)
|
|
1776
|
+
from core.session import get_cli_session_id, save_cli_session_id
|
|
1777
|
+
_provider_key = detect_provider_from_model(current_model)
|
|
1778
|
+
_existing_cli_sid = get_cli_session_id(
|
|
1779
|
+
session_id or "default", agent_id, _provider_key
|
|
1780
|
+
) if session_id else None
|
|
1781
|
+
|
|
1782
|
+
result_text, input_tokens, output_tokens, new_cli_sid = await call_cli_provider(
|
|
1783
|
+
cli_model=current_model,
|
|
1784
|
+
full_prompt=cli_full_prompt,
|
|
1785
|
+
sys_prompt=augmented_system,
|
|
1786
|
+
messages=messages_for_cli,
|
|
1787
|
+
cli_session_id=_existing_cli_sid,
|
|
1788
|
+
)
|
|
1789
|
+
|
|
1790
|
+
# Persist the CLI session ID so the next turn resumes the same session
|
|
1791
|
+
if new_cli_sid and session_id:
|
|
1792
|
+
save_cli_session_id(session_id, agent_id, _provider_key, new_cli_sid)
|
|
1793
|
+
|
|
1794
|
+
except LLMError:
|
|
1795
|
+
raise
|
|
1796
|
+
except Exception as e:
|
|
1797
|
+
return f"CLI Provider Error: {str(e)}"
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
else:
|
|
1801
|
+
# Local Ollama
|
|
1802
|
+
# Strip the ollama. prefix — the Ollama API expects bare model names
|
|
1803
|
+
_ollama_model = current_model[len("ollama."):] if current_model.startswith("ollama.") else current_model
|
|
1804
|
+
async with httpx.AsyncClient() as client:
|
|
1805
|
+
try:
|
|
1806
|
+
# Try specific Ollama Tool Call format if tools are provided
|
|
1807
|
+
if tools:
|
|
1808
|
+
print(f"DEBUG: Calling Ollama /api/chat with tools...", flush=True)
|
|
1809
|
+
|
|
1810
|
+
# Construct full message history
|
|
1811
|
+
# 1. System Prompt
|
|
1812
|
+
messages = [{"role": "system", "content": augmented_system}]
|
|
1813
|
+
|
|
1814
|
+
# 2. History (if available)
|
|
1815
|
+
if history_messages:
|
|
1816
|
+
messages.extend(history_messages)
|
|
1817
|
+
|
|
1818
|
+
# 3. Current User Message
|
|
1819
|
+
user_msg: dict = {"role": "user", "content": prompt_msg}
|
|
1820
|
+
# Ollama supports images as base64 strings (no data URI prefix)
|
|
1821
|
+
if images:
|
|
1822
|
+
user_msg["images"] = [_parse_data_uri(img)[1] for img in images[:5]]
|
|
1823
|
+
messages.append(user_msg)
|
|
1824
|
+
|
|
1825
|
+
response = await client.post(
|
|
1826
|
+
f"{_ollama_base_url()}/api/chat",
|
|
1827
|
+
json={
|
|
1828
|
+
"model": _ollama_model,
|
|
1829
|
+
"messages": messages,
|
|
1830
|
+
"tools": tools,
|
|
1831
|
+
"stream": False
|
|
1832
|
+
},
|
|
1833
|
+
timeout=180.0
|
|
1834
|
+
)
|
|
1835
|
+
response.raise_for_status()
|
|
1836
|
+
data = response.json()
|
|
1837
|
+
msg = data.get("message", {})
|
|
1838
|
+
|
|
1839
|
+
# Check for native tool calls
|
|
1840
|
+
if "tool_calls" in msg and msg["tool_calls"]:
|
|
1841
|
+
# Convert Ollama native tool call to our internal JSON format
|
|
1842
|
+
tc = msg["tool_calls"][0]
|
|
1843
|
+
print(f"DEBUG: Native Tool Call received: {tc['function']['name']}", flush=True)
|
|
1844
|
+
result_text = json.dumps({
|
|
1845
|
+
"tool": tc["function"]["name"],
|
|
1846
|
+
"arguments": tc["function"]["arguments"]
|
|
1847
|
+
})
|
|
1848
|
+
else:
|
|
1849
|
+
result_text = msg.get("content", "")
|
|
1850
|
+
|
|
1851
|
+
# Ollama eval_count / prompt_eval_count (available when stream=False)
|
|
1852
|
+
input_tokens = data.get("prompt_eval_count", 0) or usage_tracker.estimate_tokens_from_text(prompt_msg)
|
|
1853
|
+
output_tokens = data.get("eval_count", 0) or usage_tracker.estimate_tokens_from_text(result_text)
|
|
1854
|
+
|
|
1855
|
+
else:
|
|
1856
|
+
# Fallback to generate if no tools or tools failed (Old behavior)
|
|
1857
|
+
print(f"DEBUG: Calling Ollama /api/generate (Legacy Mode)...", flush=True)
|
|
1858
|
+
|
|
1859
|
+
prompt_for_generate = prompt_msg
|
|
1860
|
+
if history_messages:
|
|
1861
|
+
prior = _messages_to_transcript(history_messages)
|
|
1862
|
+
if prior:
|
|
1863
|
+
prompt_for_generate = f"Conversation so far:\n{prior}\n\nUser: {prompt_msg}".strip()
|
|
1864
|
+
|
|
1865
|
+
response = await client.post(
|
|
1866
|
+
f"{_ollama_base_url()}/api/generate",
|
|
1867
|
+
json={
|
|
1868
|
+
"model": _ollama_model,
|
|
1869
|
+
"prompt": prompt_for_generate,
|
|
1870
|
+
"system": augmented_system,
|
|
1871
|
+
"stream": False
|
|
1872
|
+
},
|
|
1873
|
+
timeout=180.0
|
|
1874
|
+
)
|
|
1875
|
+
response.raise_for_status()
|
|
1876
|
+
data = response.json()
|
|
1877
|
+
result_text = data.get("response", "")
|
|
1878
|
+
input_tokens = data.get("prompt_eval_count", 0) or usage_tracker.estimate_tokens_from_text(prompt_for_generate)
|
|
1879
|
+
output_tokens = data.get("eval_count", 0) or usage_tracker.estimate_tokens_from_text(result_text)
|
|
1880
|
+
|
|
1881
|
+
except Exception as e:
|
|
1882
|
+
return f"Local Agent Error: {e}"
|
|
1883
|
+
|
|
1884
|
+
# ── Log usage (fire-and-forget, never raises) ────────────────────────────
|
|
1885
|
+
try:
|
|
1886
|
+
provider = detect_provider_from_model(current_model)
|
|
1887
|
+
usage_tracker.log_usage(
|
|
1888
|
+
model=current_model,
|
|
1889
|
+
provider=provider,
|
|
1890
|
+
input_tokens=input_tokens,
|
|
1891
|
+
output_tokens=output_tokens,
|
|
1892
|
+
context_chars=context_chars,
|
|
1893
|
+
session_id=session_id,
|
|
1894
|
+
agent_id=agent_id,
|
|
1895
|
+
source=source,
|
|
1896
|
+
run_id=run_id,
|
|
1897
|
+
tool_name=tool_name,
|
|
1898
|
+
latency_seconds=_time.time() - _t0,
|
|
1899
|
+
)
|
|
1900
|
+
except Exception as _track_err:
|
|
1901
|
+
print(f"DEBUG usage_tracker: log_usage failed (non-fatal): {_track_err}", flush=True)
|
|
1902
|
+
|
|
1903
|
+
return result_text
|
|
1904
|
+
|
|
1905
|
+
|
|
1906
|
+
# ─── Embedding Helpers ──────────────────────────────────────────────────────
|
|
1907
|
+
|
|
1908
|
+
async def embed_batch(texts: list[str], model: str, settings: dict) -> list[list[float]]:
|
|
1909
|
+
"""Unified embedding function that routes to the appropriate provider.
|
|
1910
|
+
|
|
1911
|
+
Optional settings key ``__embed_output_dim`` (int) is forwarded to
|
|
1912
|
+
providers that support dimensionality control (currently Gemini).
|
|
1913
|
+
"""
|
|
1914
|
+
provider = detect_provider_from_model(model)
|
|
1915
|
+
output_dim: int | None = settings.get("__embed_output_dim")
|
|
1916
|
+
|
|
1917
|
+
if provider == "openai":
|
|
1918
|
+
return await _embed_openai(texts, model, settings.get("openai_key", ""))
|
|
1919
|
+
elif provider == "openai_compatible":
|
|
1920
|
+
clean_model = model[len("oaic."):] if model.startswith("oaic.") else model
|
|
1921
|
+
return await _embed_v1_compatible(texts, clean_model, settings.get("openai_compatible_base_url", ""), settings.get("openai_compatible_key", ""))
|
|
1922
|
+
elif provider == "local_compatible":
|
|
1923
|
+
clean_model = model[len("locv1."):] if model.startswith("locv1.") else model
|
|
1924
|
+
return await _embed_v1_compatible(texts, clean_model, settings.get("local_compatible_base_url", ""), settings.get("local_compatible_key", ""))
|
|
1925
|
+
elif provider == "gemini":
|
|
1926
|
+
kwargs = {} if output_dim is None else {"output_dim": output_dim}
|
|
1927
|
+
return await _embed_gemini(texts, model, settings.get("gemini_key", ""), **kwargs)
|
|
1928
|
+
elif provider == "bedrock":
|
|
1929
|
+
return await _embed_bedrock(texts, model, settings)
|
|
1930
|
+
elif provider == "ollama":
|
|
1931
|
+
return await _embed_ollama(texts, model)
|
|
1932
|
+
else:
|
|
1933
|
+
print(f"DEBUG: Unknown provider '{provider}' for embedding model '{model}'")
|
|
1934
|
+
return [[0.0] * 768 for _ in range(len(texts))]
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
async def _embed_openai(texts: list[str], model: str, api_key: str) -> list[list[float]]:
|
|
1938
|
+
if not api_key:
|
|
1939
|
+
return [[0.0] * 1536 for _ in range(len(texts))]
|
|
1940
|
+
try:
|
|
1941
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
1942
|
+
resp = await client.post(
|
|
1943
|
+
"https://api.openai.com/v1/embeddings",
|
|
1944
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
1945
|
+
json={"model": model, "input": texts},
|
|
1946
|
+
)
|
|
1947
|
+
resp.raise_for_status()
|
|
1948
|
+
data = resp.json()
|
|
1949
|
+
# OpenAI returns embeddings in the same order as input
|
|
1950
|
+
return [item["embedding"] for item in data["data"]]
|
|
1951
|
+
except Exception as e:
|
|
1952
|
+
print(f"ERROR: OpenAI embedding failed: {e}")
|
|
1953
|
+
return [[0.0] * 1536 for _ in range(len(texts))]
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
async def _embed_v1_compatible(texts: list[str], model: str, base_url: str, api_key: str, output_dim: int = 768) -> list[list[float]]:
|
|
1957
|
+
"""Embed via an OpenAI v1-compatible /v1/embeddings endpoint."""
|
|
1958
|
+
if not base_url:
|
|
1959
|
+
raise LLMError("V1-compatible embedding — base URL not configured")
|
|
1960
|
+
headers = {}
|
|
1961
|
+
if api_key:
|
|
1962
|
+
headers["Authorization"] = f"Bearer {api_key}"
|
|
1963
|
+
endpoint = f"{_normalize_v1_base_url(base_url)}/v1/embeddings"
|
|
1964
|
+
try:
|
|
1965
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
1966
|
+
resp = await client.post(endpoint, headers=headers, json={"model": model, "input": texts})
|
|
1967
|
+
resp.raise_for_status()
|
|
1968
|
+
data = resp.json()
|
|
1969
|
+
return [item["embedding"] for item in data["data"]]
|
|
1970
|
+
except Exception as e:
|
|
1971
|
+
raise LLMError(f"V1-compatible embedding failed: {e}")
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
async def _embed_gemini(
|
|
1975
|
+
texts: list[str], model: str, api_key: str, output_dim: int = 768
|
|
1976
|
+
) -> list[list[float]]:
|
|
1977
|
+
if not api_key:
|
|
1978
|
+
return [[0.0] * output_dim for _ in range(len(texts))]
|
|
1979
|
+
|
|
1980
|
+
from google import genai
|
|
1981
|
+
from google.genai import types
|
|
1982
|
+
|
|
1983
|
+
global _gemini_client
|
|
1984
|
+
if _gemini_client is None:
|
|
1985
|
+
_gemini_client = genai.Client(api_key=api_key)
|
|
1986
|
+
|
|
1987
|
+
try:
|
|
1988
|
+
# Specify output_dimensionality so Gemini returns exactly `output_dim` dims
|
|
1989
|
+
# (uses Matryoshka truncation — the first N dims are the best N-dim representation).
|
|
1990
|
+
# Without this, the API returns the full 3072-dim vector which exceeds
|
|
1991
|
+
# pgvector's 2000-dim HNSW limit.
|
|
1992
|
+
result = await asyncio.to_thread(
|
|
1993
|
+
_gemini_client.models.embed_content,
|
|
1994
|
+
model=model,
|
|
1995
|
+
contents=texts,
|
|
1996
|
+
config=types.EmbedContentConfig(output_dimensionality=output_dim),
|
|
1997
|
+
)
|
|
1998
|
+
if not result.embeddings:
|
|
1999
|
+
return [[0.0] * output_dim for _ in range(len(texts))]
|
|
2000
|
+
return [list(em.values) for em in result.embeddings]
|
|
2001
|
+
except Exception as e:
|
|
2002
|
+
print(f"ERROR: Gemini embedding failed: {e}")
|
|
2003
|
+
return [[0.0] * output_dim for _ in range(len(texts))]
|
|
2004
|
+
|
|
2005
|
+
|
|
2006
|
+
async def _embed_bedrock(texts: list[str], model: str, settings: dict) -> list[list[float]]:
|
|
2007
|
+
region = settings.get("aws_region", "us-east-1")
|
|
2008
|
+
bedrock = _make_aws_client("bedrock-runtime", region, settings)
|
|
2009
|
+
# Strip the 'bedrock.' UI prefix to get the raw Bedrock model ID
|
|
2010
|
+
real_model_id = model.replace("bedrock.", "", 1)
|
|
2011
|
+
|
|
2012
|
+
embeddings = []
|
|
2013
|
+
for text in texts:
|
|
2014
|
+
try:
|
|
2015
|
+
if "titan" in real_model_id:
|
|
2016
|
+
# Titan Embed v1 and v2 both use inputText; v2 also supports
|
|
2017
|
+
# embeddingTypes but the default (float) is fine here.
|
|
2018
|
+
payload = json.dumps({"inputText": text})
|
|
2019
|
+
elif "cohere" in real_model_id:
|
|
2020
|
+
# Cohere Embed v3 via Bedrock expects a texts array + input_type
|
|
2021
|
+
payload = json.dumps({
|
|
2022
|
+
"texts": [text[:2048]],
|
|
2023
|
+
"input_type": "search_document",
|
|
2024
|
+
"truncate": "END",
|
|
2025
|
+
})
|
|
2026
|
+
else:
|
|
2027
|
+
# Generic fallback — try the Titan-style inputText payload
|
|
2028
|
+
payload = json.dumps({"inputText": text})
|
|
2029
|
+
|
|
2030
|
+
def _run(pid=real_model_id, body=payload):
|
|
2031
|
+
return bedrock.invoke_model(
|
|
2032
|
+
body=body,
|
|
2033
|
+
modelId=pid,
|
|
2034
|
+
accept="application/json",
|
|
2035
|
+
contentType="application/json",
|
|
2036
|
+
)
|
|
2037
|
+
|
|
2038
|
+
resp = await asyncio.to_thread(_run)
|
|
2039
|
+
body_parsed = json.loads(resp.get("body").read())
|
|
2040
|
+
|
|
2041
|
+
if "titan" in real_model_id:
|
|
2042
|
+
# Titan v2 may wrap embeddings under embeddingsByType; fall back to
|
|
2043
|
+
# top-level 'embedding' key used by v1.
|
|
2044
|
+
emb = body_parsed.get("embedding") or []
|
|
2045
|
+
embeddings.append(emb)
|
|
2046
|
+
elif "cohere" in real_model_id:
|
|
2047
|
+
# Cohere returns {"embeddings": [[...]]}
|
|
2048
|
+
embs = body_parsed.get("embeddings", [[]])
|
|
2049
|
+
embeddings.append(embs[0] if embs else [])
|
|
2050
|
+
else:
|
|
2051
|
+
embeddings.append(body_parsed.get("embedding", []))
|
|
2052
|
+
|
|
2053
|
+
except Exception as e:
|
|
2054
|
+
err_str = str(e)
|
|
2055
|
+
if "unknown model" in err_str.lower() or "resourcenotfound" in err_str.lower():
|
|
2056
|
+
print(
|
|
2057
|
+
f"ERROR: Bedrock embedding — model '{real_model_id}' not found in "
|
|
2058
|
+
f"region '{region}'. Ensure the model is enabled in the AWS console "
|
|
2059
|
+
f"and, if it requires on-demand throughput via an inference profile, "
|
|
2060
|
+
f"set 'Bedrock Inference Profile' in Settings.\nOriginal error: {e}"
|
|
2061
|
+
)
|
|
2062
|
+
else:
|
|
2063
|
+
print(f"ERROR: Bedrock embedding failed for '{real_model_id}': {e}")
|
|
2064
|
+
embeddings.append([])
|
|
2065
|
+
|
|
2066
|
+
return embeddings
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
async def _embed_ollama(texts: list[str], model: str) -> list[list[float]]:
|
|
2070
|
+
model = model[len("ollama."):] if model.startswith("ollama.") else model
|
|
2071
|
+
url = f"{_ollama_base_url()}/api/embed"
|
|
2072
|
+
try:
|
|
2073
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
2074
|
+
resp = await client.post(url, json={"model": model, "input": texts})
|
|
2075
|
+
if resp.status_code != 200:
|
|
2076
|
+
# Fallback for older Ollama versions
|
|
2077
|
+
url_legacy = f"{_ollama_base_url()}/api/embeddings"
|
|
2078
|
+
embeddings = []
|
|
2079
|
+
for t in texts:
|
|
2080
|
+
r = await client.post(url_legacy, json={"model": model, "prompt": t})
|
|
2081
|
+
embeddings.append(r.json().get("embedding", []))
|
|
2082
|
+
return embeddings
|
|
2083
|
+
|
|
2084
|
+
data = resp.json()
|
|
2085
|
+
return data.get("embeddings", [])
|
|
2086
|
+
except Exception as e:
|
|
2087
|
+
print(f"ERROR: Ollama embedding failed: {e}")
|
|
2088
|
+
return [[0.0] * 768 for _ in range(len(texts))]
|