ai-agent-router 0.1.21 → 0.2.1
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +14 -0
- package/.next/build-manifest.json +2 -2
- package/.next/fallback-build-manifest.json +2 -2
- package/.next/routes-manifest.json +84 -0
- package/.next/server/app/_global-error/page.js +1 -1
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +2 -2
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/models/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/available-models/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/save/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/status/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/test/route.js +1 -1
- package/.next/server/app/api/ide/claude/test/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/openclaw/apply/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/apply/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/apply/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/apply/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/available-models/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/preview/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/preview/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/preview/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/preview/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/restore/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/restore/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/restore/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js +6 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/restore/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/save/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/save/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/save/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/save/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/save/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/save/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/save/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/status/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/status/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/status/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/status/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/status/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/status/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/status/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/test/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/test/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/test/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/test/route.js +6 -0
- package/.next/server/app/api/ide/openclaw/test/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/test/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/test/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/apply/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/apply/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/apply/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/apply/route.js +7 -0
- package/.next/server/app/api/ide/opencode/apply/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/apply/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/apply/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/available-models/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/available-models/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/available-models/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js +7 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/available-models/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/preview/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/preview/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/preview/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/preview/route.js +7 -0
- package/.next/server/app/api/ide/opencode/preview/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/preview/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/preview/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/restore/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/restore/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/restore/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/restore/route.js +6 -0
- package/.next/server/app/api/ide/opencode/restore/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/restore/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/restore/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/save/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/save/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/save/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/save/route.js +7 -0
- package/.next/server/app/api/ide/opencode/save/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/save/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/save/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/status/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/status/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/status/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/status/route.js +7 -0
- package/.next/server/app/api/ide/opencode/status/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/status/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/status/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/test/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/test/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/test/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/test/route.js +6 -0
- package/.next/server/app/api/ide/opencode/test/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/test/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/test/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/test/route.js.nft.json +1 -1
- package/.next/server/app/api/service/force-stop/route.js.nft.json +1 -1
- package/.next/server/app/api/service/start/route.js.nft.json +1 -1
- package/.next/server/app/api/service/status/route.js.nft.json +1 -1
- package/.next/server/app/api/service/stop/route.js.nft.json +1 -1
- package/.next/server/app/ide/page.js +1 -1
- package/.next/server/app/ide/page.js.nft.json +1 -1
- package/.next/server/app/ide/page_client-reference-manifest.js +1 -1
- package/.next/server/app/ide.html +1 -1
- package/.next/server/app/ide.rsc +3 -3
- package/.next/server/app/ide.segments/_full.segment.rsc +3 -3
- package/.next/server/app/ide.segments/_head.segment.rsc +1 -1
- package/.next/server/app/ide.segments/_index.segment.rsc +2 -2
- package/.next/server/app/ide.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/ide.segments/ide/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/ide.segments/ide.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs/page.js +1 -1
- package/.next/server/app/logs/page.js.nft.json +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +1 -1
- package/.next/server/app/logs.rsc +3 -3
- package/.next/server/app/logs.segments/_full.segment.rsc +3 -3
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/models/page.js +1 -1
- package/.next/server/app/models/page.js.nft.json +1 -1
- package/.next/server/app/models/page_client-reference-manifest.js +1 -1
- package/.next/server/app/models.html +1 -1
- package/.next/server/app/models.rsc +2 -2
- package/.next/server/app/models.segments/_full.segment.rsc +2 -2
- package/.next/server/app/models.segments/_head.segment.rsc +1 -1
- package/.next/server/app/models.segments/_index.segment.rsc +2 -2
- package/.next/server/app/models.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/models.segments/models/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/models.segments/models.segment.rsc +1 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers/page.js +1 -1
- package/.next/server/app/providers/page.js.nft.json +1 -1
- package/.next/server/app/providers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers.html +1 -1
- package/.next/server/app/providers.rsc +2 -2
- package/.next/server/app/providers.segments/_full.segment.rsc +2 -2
- package/.next/server/app/providers.segments/_head.segment.rsc +1 -1
- package/.next/server/app/providers.segments/_index.segment.rsc +2 -2
- package/.next/server/app/providers.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/providers.segments/providers.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +14 -0
- package/.next/server/chunks/[root-of-the-server]__001d5756._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__001d5756._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__05f8578b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__05f8578b._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1480f018._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1480f018._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1909f3aa._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1909f3aa._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1d4b7fc5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1d4b7fc5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__372ef2bf._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__372ef2bf._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__3aaf963c._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__3aaf963c._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__43810962._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__43810962._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__55cd88b8._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__55cd88b8._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__5e8276bc._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__5e8276bc._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__6ce199d2._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__6ce199d2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__760eaa16._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__760eaa16._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__772134c6._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__772134c6._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__7b77f523._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__7b77f523._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__7c298a19._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__7c298a19._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__85540228._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__85540228._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__94fe8d3c._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__94fe8d3c._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__97622908._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__97622908._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a02e6618._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a02e6618._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a32a20a7._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a32a20a7._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__af5b556a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__af5b556a._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js +18 -18
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__cafe113e._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__cafe113e._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__ccfc7f1d._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__ccfc7f1d._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__dc8b0bed._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__dc8b0bed._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__f8949f88._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__f8949f88._.js.map +1 -1
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_apply_route_actions_2cb9e4b4.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_apply_route_actions_2cb9e4b4.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_preview_route_actions_9814a8e4.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_preview_route_actions_9814a8e4.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_restore_route_actions_10ad8f9d.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_restore_route_actions_10ad8f9d.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_save_route_actions_044ad081.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_save_route_actions_044ad081.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_status_route_actions_ed9786d2.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_status_route_actions_ed9786d2.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_test_route_actions_ce2cb808.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_test_route_actions_ce2cb808.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_apply_route_actions_6c422244.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_apply_route_actions_6c422244.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_preview_route_actions_256c82e0.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_preview_route_actions_256c82e0.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_restore_route_actions_371993d3.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_restore_route_actions_371993d3.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_save_route_actions_6e4c9c41.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_save_route_actions_6e4c9c41.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_status_route_actions_498ad77b.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_status_route_actions_498ad77b.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_test_route_actions_c71be510.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_test_route_actions_c71be510.js.map +1 -0
- package/.next/server/chunks/ce889_server_app_api_ide_openclaw_available-models_route_actions_e568e70b.js +3 -0
- package/.next/server/chunks/ce889_server_app_api_ide_openclaw_available-models_route_actions_e568e70b.js.map +1 -0
- package/.next/server/chunks/ce889_server_app_api_ide_opencode_available-models_route_actions_95230db3.js +3 -0
- package/.next/server/chunks/ce889_server_app_api_ide_opencode_available-models_route_actions_95230db3.js.map +1 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__bec95712._.js → [root-of-the-server]__81937253._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__bec95712._.js.map → [root-of-the-server]__81937253._.js.map} +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__71c85955._.js → [root-of-the-server]__976ad963._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__71c85955._.js.map → [root-of-the-server]__976ad963._.js.map} +1 -1
- package/.next/server/chunks/ssr/src_app_ide_page_tsx_8962793b._.js +1 -1
- package/.next/server/chunks/ssr/src_app_ide_page_tsx_8962793b._.js.map +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js.map +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/static/chunks/0f120c117962200b.css +1 -0
- package/.next/static/chunks/64f547b3bcd3aef4.js +1 -0
- package/.next/static/chunks/{81c904164fe81379.js → 7c8b7cbb3339f139.js} +1 -1
- package/.next/static/chunks/8ed839b2e4948968.js +1 -0
- package/.next/types/routes.d.ts +15 -1
- package/.next/types/validator.ts +126 -0
- package/README.md +100 -111
- package/dist/.next/dev/types/validator.js +56 -0
- package/dist/.next/types/validator.js +56 -0
- package/dist/src/app/api/gateway/[...path]/route.js +1 -1
- package/dist/src/app/api/gateway/route.js +1 -1
- package/dist/src/app/api/ide/claude/apply/route.js +42 -31
- package/dist/src/app/api/ide/claude/status/route.js +6 -1
- package/dist/src/app/api/ide/openclaw/apply/route.js +92 -0
- package/dist/src/app/api/ide/openclaw/available-models/route.js +46 -0
- package/dist/src/app/api/ide/openclaw/build-config.js +101 -0
- package/dist/src/app/api/ide/openclaw/preview/route.js +49 -0
- package/dist/src/app/api/ide/openclaw/restore/route.js +24 -0
- package/dist/src/app/api/ide/openclaw/save/route.js +54 -0
- package/dist/src/app/api/ide/openclaw/status/route.js +139 -0
- package/dist/src/app/api/ide/openclaw/test/route.js +158 -0
- package/dist/src/app/api/ide/opencode/apply/route.js +89 -0
- package/dist/src/app/api/ide/opencode/available-models/route.js +46 -0
- package/dist/src/app/api/ide/opencode/build-config.js +54 -0
- package/dist/src/app/api/ide/opencode/preview/route.js +36 -0
- package/dist/src/app/api/ide/opencode/restore/route.js +40 -0
- package/dist/src/app/api/ide/opencode/save/route.js +123 -0
- package/dist/src/app/api/ide/opencode/status/route.js +106 -0
- package/dist/src/app/api/ide/opencode/test/route.js +136 -0
- package/dist/src/app/api/logs/route.js +2 -2
- package/dist/src/app/api/models/route.js +5 -5
- package/dist/src/app/api/providers/route.js +4 -4
- package/dist/src/app/api/providers/test/route.js +1 -1
- package/dist/src/app/api/service/start/route.js +1 -1
- package/dist/src/app/api/service/status/route.js +1 -1
- package/dist/src/app/api/service/stop/route.js +1 -1
- package/dist/src/app/ide/page.js +591 -81
- package/dist/src/app/logs/page.js +15 -1
- package/dist/src/cli/index.js +218 -20
- package/dist/src/db/database.js +56 -5
- package/dist/src/db/queries.js +6 -6
- package/dist/src/server/logger.js +22 -4
- package/package.json +2 -1
- package/src/app/api/gateway/[...path]/route.ts +1 -1
- package/src/app/api/gateway/route.ts +1 -1
- package/src/app/api/ide/claude/apply/route.ts +46 -31
- package/src/app/api/ide/claude/status/route.ts +12 -2
- package/src/app/api/ide/openclaw/apply/route.ts +103 -0
- package/src/app/api/ide/openclaw/available-models/route.ts +59 -0
- package/src/app/api/ide/openclaw/build-config.ts +152 -0
- package/src/app/api/ide/openclaw/preview/route.ts +57 -0
- package/src/app/api/ide/openclaw/restore/route.ts +27 -0
- package/src/app/api/ide/openclaw/save/route.ts +67 -0
- package/src/app/api/ide/openclaw/status/route.ts +178 -0
- package/src/app/api/ide/openclaw/test/route.ts +194 -0
- package/src/app/api/ide/opencode/apply/route.ts +92 -0
- package/src/app/api/ide/opencode/available-models/route.ts +59 -0
- package/src/app/api/ide/opencode/build-config.ts +69 -0
- package/src/app/api/ide/opencode/preview/route.ts +40 -0
- package/src/app/api/ide/opencode/restore/route.ts +52 -0
- package/src/app/api/ide/opencode/save/route.ts +131 -0
- package/src/app/api/ide/opencode/status/route.ts +128 -0
- package/src/app/api/ide/opencode/test/route.ts +145 -0
- package/src/app/api/logs/route.ts +2 -2
- package/src/app/api/models/route.ts +5 -5
- package/src/app/api/providers/route.ts +4 -4
- package/src/app/api/providers/test/route.ts +1 -1
- package/src/app/api/service/start/route.ts +1 -1
- package/src/app/api/service/status/route.ts +1 -1
- package/src/app/api/service/stop/route.ts +1 -1
- package/src/app/globals.css +17 -0
- package/src/app/ide/page.tsx +1535 -132
- package/src/app/logs/page.tsx +17 -5
- package/src/cli/index.ts +228 -25
- package/src/db/database.ts +60 -8
- package/src/db/queries.ts +6 -6
- package/src/server/logger.ts +19 -4
- package/.next/static/chunks/6418ca50028376b7.css +0 -1
- package/.next/static/chunks/9ec3b97741b6575e.js +0 -1
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → dYin74gcpdlg8TGoGv-_d}/_buildManifest.js +0 -0
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → dYin74gcpdlg8TGoGv-_d}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → dYin74gcpdlg8TGoGv-_d}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
|
|
7
|
+
const OPENCLAW_DIR = join(homedir(), '.openclaw');
|
|
8
|
+
const OPENCLAW_FILE = join(OPENCLAW_DIR, 'openclaw.json');
|
|
9
|
+
|
|
10
|
+
const RUN_TIMEOUT_MS = 30_000;
|
|
11
|
+
|
|
12
|
+
interface TestResult {
|
|
13
|
+
success: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
message?: string;
|
|
16
|
+
checks?: Record<string, boolean>;
|
|
17
|
+
configSummary?: {
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
apiKey?: string;
|
|
20
|
+
routerProvider?: string;
|
|
21
|
+
primaryModel?: string;
|
|
22
|
+
fallbackModels?: string[];
|
|
23
|
+
imageModel?: string;
|
|
24
|
+
fallbackImageModels?: string[];
|
|
25
|
+
};
|
|
26
|
+
probeResult?: {
|
|
27
|
+
success: boolean;
|
|
28
|
+
stdout: string;
|
|
29
|
+
stderr: string;
|
|
30
|
+
error?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function runCommand(args: string[]): Promise<{ success: boolean; stdout: string; stderr: string; error?: string; code?: number }> {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const child = spawn('openclaw', args, {
|
|
37
|
+
shell: process.platform === 'win32',
|
|
38
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
let stdout = '';
|
|
42
|
+
let stderr = '';
|
|
43
|
+
|
|
44
|
+
child.stdout?.on('data', (chunk: Buffer) => {
|
|
45
|
+
stdout += chunk.toString('utf-8');
|
|
46
|
+
});
|
|
47
|
+
child.stderr?.on('data', (chunk: Buffer) => {
|
|
48
|
+
stderr += chunk.toString('utf-8');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
child.on('error', (err) => {
|
|
52
|
+
resolve({ success: false, stdout, stderr, error: err.message });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
child.on('close', (code) => {
|
|
56
|
+
resolve({ success: code === 0, stdout, stderr, code: code ?? undefined });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
if (!child.killed) {
|
|
61
|
+
child.kill();
|
|
62
|
+
resolve({ success: false, stdout, stderr, error: 'Timeout' });
|
|
63
|
+
}
|
|
64
|
+
}, RUN_TIMEOUT_MS);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function maskApiKey(apiKey: string): string {
|
|
69
|
+
if (!apiKey || apiKey === 'your-gateway-api-key') return apiKey;
|
|
70
|
+
if (apiKey.length <= 8) return apiKey.slice(0, 2) + '***' + apiKey.slice(-2);
|
|
71
|
+
return apiKey.slice(0, 4) + '****' + apiKey.slice(-4);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function GET(request: NextRequest) {
|
|
75
|
+
try {
|
|
76
|
+
// Check config file exists
|
|
77
|
+
if (!existsSync(OPENCLAW_FILE)) {
|
|
78
|
+
return NextResponse.json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: 'Configuration file not found',
|
|
81
|
+
suggestion: 'Please apply configuration first',
|
|
82
|
+
} as TestResult);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const content = readFileSync(OPENCLAW_FILE, 'utf-8');
|
|
86
|
+
let config: any;
|
|
87
|
+
try {
|
|
88
|
+
config = JSON.parse(content);
|
|
89
|
+
} catch {
|
|
90
|
+
return NextResponse.json({
|
|
91
|
+
success: false,
|
|
92
|
+
error: 'Invalid configuration format',
|
|
93
|
+
} as TestResult);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Extract config summary
|
|
97
|
+
const modelsConfig = config.models || {};
|
|
98
|
+
const providers = modelsConfig.providers || {};
|
|
99
|
+
const aarProvider = providers['aar-gateway'];
|
|
100
|
+
|
|
101
|
+
const configSummary: TestResult['configSummary'] = {
|
|
102
|
+
baseUrl: aarProvider?.baseUrl,
|
|
103
|
+
apiKey: maskApiKey(aarProvider?.apiKey || ''),
|
|
104
|
+
routerProvider: aarProvider ? 'aar' : undefined,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const primaryModel = config.agents?.defaults?.model?.primary;
|
|
108
|
+
if (primaryModel) {
|
|
109
|
+
configSummary.primaryModel = primaryModel;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const fallbackModels = config.agents?.defaults?.model?.fallbacks;
|
|
113
|
+
if (Array.isArray(fallbackModels)) {
|
|
114
|
+
configSummary.fallbackModels = fallbackModels;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const imageModel = config.agents?.defaults?.imageModel?.primary;
|
|
118
|
+
if (imageModel) {
|
|
119
|
+
configSummary.imageModel = imageModel;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const fallbackImageModels = config.agents?.defaults?.imageModel?.fallbacks;
|
|
123
|
+
if (Array.isArray(fallbackImageModels)) {
|
|
124
|
+
configSummary.fallbackImageModels = fallbackImageModels;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Run probe command to test provider accessibility
|
|
128
|
+
const probeResult = await runCommand([
|
|
129
|
+
'models', 'status',
|
|
130
|
+
'--probe',
|
|
131
|
+
'--probe-provider', 'aar-gateway',
|
|
132
|
+
'--json'
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
let probeSuccess = false;
|
|
136
|
+
let probeMessage = 'Provider not found or not accessible';
|
|
137
|
+
|
|
138
|
+
if (probeResult.success) {
|
|
139
|
+
// Try to parse JSON output
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(probeResult.stdout);
|
|
142
|
+
// Check if probe was successful
|
|
143
|
+
probeSuccess = parsed?.success === true || parsed?.status === 'ok';
|
|
144
|
+
if (probeSuccess) {
|
|
145
|
+
probeMessage = 'Provider is accessible and responding';
|
|
146
|
+
} else {
|
|
147
|
+
probeMessage = parsed?.message || 'Probe returned unsuccessful status';
|
|
148
|
+
}
|
|
149
|
+
} catch {
|
|
150
|
+
// If not JSON, check for success indicators in text
|
|
151
|
+
probeSuccess = probeResult.stdout.toLowerCase().includes('ok') ||
|
|
152
|
+
probeResult.stdout.toLowerCase().includes('success') ||
|
|
153
|
+
probeResult.stdout.toLowerCase().includes('aar-gateway');
|
|
154
|
+
probeMessage = probeSuccess
|
|
155
|
+
? 'Provider is accessible'
|
|
156
|
+
: 'Could not verify provider status';
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
probeMessage = probeResult.error || `Command failed (code ${probeResult.code})`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const checks: Record<string, boolean> = {
|
|
163
|
+
hasBaseUrl: !!aarProvider?.baseUrl,
|
|
164
|
+
hasApiKey: !!aarProvider?.apiKey && aarProvider?.apiKey !== 'your-gateway-api-key',
|
|
165
|
+
hasModels: Array.isArray(aarProvider?.models) && aarProvider.models.length > 0,
|
|
166
|
+
hasPrimaryModel: !!primaryModel,
|
|
167
|
+
hasProvider: !!aarProvider,
|
|
168
|
+
probeSuccess,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const success = checks.hasBaseUrl && checks.hasApiKey && checks.hasProvider && probeSuccess;
|
|
172
|
+
|
|
173
|
+
const result: TestResult = {
|
|
174
|
+
success,
|
|
175
|
+
message: success ? 'Configuration verified successfully' : 'Configuration verification failed',
|
|
176
|
+
checks,
|
|
177
|
+
configSummary,
|
|
178
|
+
probeResult: {
|
|
179
|
+
success: probeSuccess,
|
|
180
|
+
stdout: probeResult.stdout.slice(-3000),
|
|
181
|
+
stderr: probeResult.stderr.slice(-500),
|
|
182
|
+
error: probeResult.error,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
return NextResponse.json(result);
|
|
187
|
+
} catch (error: any) {
|
|
188
|
+
console.error('OpenClaw Test API error:', error);
|
|
189
|
+
return NextResponse.json({
|
|
190
|
+
success: false,
|
|
191
|
+
error: error.message || 'Internal server error',
|
|
192
|
+
} as TestResult);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { buildMergedConfig } from '../build-config';
|
|
6
|
+
|
|
7
|
+
const OPENCODE_DIR =
|
|
8
|
+
process.platform === 'win32'
|
|
9
|
+
? join(process.env.APPDATA || homedir(), 'opencode')
|
|
10
|
+
: join(homedir(), '.config', 'opencode');
|
|
11
|
+
const OPENCODE_FILE = join(OPENCODE_DIR, 'opencode.json');
|
|
12
|
+
const BACKUP_FILE = join(OPENCODE_DIR, 'opencode.json.aar.bak');
|
|
13
|
+
|
|
14
|
+
function backupOriginalConfig(): { success: boolean; existed: boolean; isFromAar: boolean; error?: string } {
|
|
15
|
+
try {
|
|
16
|
+
const existing = existsSync(OPENCODE_FILE);
|
|
17
|
+
if (existing) {
|
|
18
|
+
const original = readFileSync(OPENCODE_FILE, 'utf-8');
|
|
19
|
+
let isFromAar = false;
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(original);
|
|
22
|
+
isFromAar = !!(parsed.provider && parsed.provider['aar-gateway']);
|
|
23
|
+
} catch {}
|
|
24
|
+
// 仅在当前配置不是 AAR 时写入备份,这样「还原」才能恢复到应用 AAR 前的状态;若已是 AAR 则保留原有备份不覆盖
|
|
25
|
+
if (!isFromAar) {
|
|
26
|
+
writeFileSync(BACKUP_FILE, original, 'utf-8');
|
|
27
|
+
}
|
|
28
|
+
return { success: true, existed: true, isFromAar };
|
|
29
|
+
}
|
|
30
|
+
return { success: true, existed: false, isFromAar: false };
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
return { success: false, existed: false, isFromAar: false, error: `Backup failed: ${error.message}` };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function POST(request: NextRequest) {
|
|
37
|
+
try {
|
|
38
|
+
const body = await request.json();
|
|
39
|
+
const { default_model: defaultModel, config: customConfigStr } = body;
|
|
40
|
+
|
|
41
|
+
let existing: Record<string, any> | null = null;
|
|
42
|
+
if (existsSync(OPENCODE_FILE)) {
|
|
43
|
+
try {
|
|
44
|
+
existing = JSON.parse(readFileSync(OPENCODE_FILE, 'utf-8'));
|
|
45
|
+
} catch {
|
|
46
|
+
existing = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let config: Record<string, any>;
|
|
51
|
+
if (typeof customConfigStr === 'string' && customConfigStr.trim()) {
|
|
52
|
+
try {
|
|
53
|
+
config = JSON.parse(customConfigStr);
|
|
54
|
+
if (!config || typeof config !== 'object') throw new Error('Invalid config object');
|
|
55
|
+
} catch (e: any) {
|
|
56
|
+
return NextResponse.json({ error: 'Invalid config JSON: ' + (e.message || 'parse error') }, { status: 400 });
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
if (defaultModel === undefined || defaultModel === '') {
|
|
60
|
+
return NextResponse.json({ error: 'Missing required field: default_model' }, { status: 400 });
|
|
61
|
+
}
|
|
62
|
+
config = await buildMergedConfig(defaultModel, existing);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const backupResult = backupOriginalConfig();
|
|
66
|
+
if (!backupResult.success) {
|
|
67
|
+
return NextResponse.json({ error: backupResult.error }, { status: 500 });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!existsSync(OPENCODE_DIR)) {
|
|
71
|
+
mkdirSync(OPENCODE_DIR, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const jsonString = JSON.stringify(config, null, 2);
|
|
75
|
+
writeFileSync(OPENCODE_FILE, jsonString, 'utf-8');
|
|
76
|
+
|
|
77
|
+
const alreadyHadAar = !!(existing?.provider?.['aar-gateway']);
|
|
78
|
+
return NextResponse.json({
|
|
79
|
+
success: true,
|
|
80
|
+
message: alreadyHadAar ? 'OpenCode 配置已更新为最新网关信息' : 'OpenCode configuration applied successfully',
|
|
81
|
+
config,
|
|
82
|
+
backup: backupResult.existed ? 'Created backup' : 'No existing config to backup',
|
|
83
|
+
previousWasFromAar: backupResult.existed && backupResult.isFromAar,
|
|
84
|
+
});
|
|
85
|
+
} catch (error: any) {
|
|
86
|
+
console.error('OpenCode Apply API error:', error);
|
|
87
|
+
return NextResponse.json(
|
|
88
|
+
{ error: error.message || 'Internal server error', stack: process.env.NODE_ENV === 'development' ? error.stack : undefined },
|
|
89
|
+
{ status: 500 }
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { getAllModels, getProviderById } from '@/db/queries';
|
|
3
|
+
|
|
4
|
+
type AvailableModel = {
|
|
5
|
+
id: number;
|
|
6
|
+
name: string;
|
|
7
|
+
model_id: string;
|
|
8
|
+
provider_id: number;
|
|
9
|
+
provider_name: string;
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type GroupedModels = { [providerName: string]: AvailableModel[] };
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 查询可用模型列表(与 Claude 共用网关,用于 OpenCode 配置)
|
|
17
|
+
*/
|
|
18
|
+
export async function GET(request: NextRequest) {
|
|
19
|
+
try {
|
|
20
|
+
const allModels = (await getAllModels()).filter((m: any) => m.enabled);
|
|
21
|
+
|
|
22
|
+
if (allModels.length === 0) {
|
|
23
|
+
return NextResponse.json({
|
|
24
|
+
models: {},
|
|
25
|
+
count: 0,
|
|
26
|
+
message: 'No enabled models found. Please enable some models first.',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const grouped = await allModels.reduce(async (acc: Promise<GroupedModels>, model: any) => {
|
|
31
|
+
const resolvedAcc = await acc;
|
|
32
|
+
const provider = await getProviderById(model.provider_id);
|
|
33
|
+
if (provider) {
|
|
34
|
+
if (!resolvedAcc[provider.name]) resolvedAcc[provider.name] = [];
|
|
35
|
+
resolvedAcc[provider.name].push({
|
|
36
|
+
id: model.id,
|
|
37
|
+
name: model.name,
|
|
38
|
+
model_id: model.model_id,
|
|
39
|
+
provider_id: model.provider_id,
|
|
40
|
+
provider_name: provider.name,
|
|
41
|
+
enabled: model.enabled,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return resolvedAcc;
|
|
45
|
+
}, Promise.resolve({} as GroupedModels));
|
|
46
|
+
|
|
47
|
+
return NextResponse.json({
|
|
48
|
+
models: grouped,
|
|
49
|
+
count: allModels.length,
|
|
50
|
+
providers: Object.keys(grouped),
|
|
51
|
+
});
|
|
52
|
+
} catch (error: any) {
|
|
53
|
+
console.error('OpenCode Available Models API error:', error);
|
|
54
|
+
return NextResponse.json(
|
|
55
|
+
{ error: error.message || 'Internal server error', stack: process.env.NODE_ENV === 'development' ? error.stack : undefined },
|
|
56
|
+
{ status: 500 }
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { getDatabase } from '@/db/database';
|
|
2
|
+
import { getConfig } from '@/db/queries';
|
|
3
|
+
import { getAllModels, getProviderById } from '@/db/queries';
|
|
4
|
+
|
|
5
|
+
export async function getGatewayAddress(): Promise<string> {
|
|
6
|
+
await getDatabase();
|
|
7
|
+
const portConfig = await getConfig('port');
|
|
8
|
+
const port = portConfig?.value || '1357';
|
|
9
|
+
return `http://localhost:${port}/v1`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function getGatewayApiKey(): Promise<string> {
|
|
13
|
+
await getDatabase();
|
|
14
|
+
const apiKeyConfig = await getConfig('api_key');
|
|
15
|
+
return apiKeyConfig?.value || 'your-gateway-api-key';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** OpenCode provider 下单个 provider 的结构(与官方 provider 文档一致) */
|
|
19
|
+
export type AarGatewayProviderEntry = {
|
|
20
|
+
npm: string;
|
|
21
|
+
name: string;
|
|
22
|
+
options: { baseURL: string; apiKey: string };
|
|
23
|
+
models: Record<string, { name: string; limit?: { context: number; output?: number } }>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export async function buildAarGatewayProvider(): Promise<AarGatewayProviderEntry> {
|
|
27
|
+
const gatewayAddress = await getGatewayAddress();
|
|
28
|
+
const gatewayApiKey = await getGatewayApiKey();
|
|
29
|
+
const allModels = (await getAllModels()).filter((m: any) => m.enabled);
|
|
30
|
+
const models: Record<string, { name: string; limit: { context: number; output: number } }> = {};
|
|
31
|
+
for (const m of allModels) {
|
|
32
|
+
await getProviderById(m.provider_id);
|
|
33
|
+
models[m.model_id] = { name: m.name, limit: { context: 128000, output: 65536 } };
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
npm: '@ai-sdk/openai-compatible',
|
|
37
|
+
name: 'AAR Model Router',
|
|
38
|
+
options: { baseURL: gatewayAddress, apiKey: gatewayApiKey },
|
|
39
|
+
models,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const AAR_PROVIDER_ID = 'aar-gateway';
|
|
44
|
+
|
|
45
|
+
/** 合并现有配置与 AAR 网关:写入 config.provider["aar-gateway"],并设置 config.model = "aar-gateway/{defaultModel}" */
|
|
46
|
+
export function mergeConfigWithAar(
|
|
47
|
+
existing: Record<string, any> | null,
|
|
48
|
+
defaultModel: string,
|
|
49
|
+
aarProvider: AarGatewayProviderEntry
|
|
50
|
+
): Record<string, any> {
|
|
51
|
+
const base = existing && typeof existing === 'object' ? { ...existing } : {};
|
|
52
|
+
const provider: Record<string, any> =
|
|
53
|
+
base.provider && typeof base.provider === 'object' ? { ...base.provider } : {};
|
|
54
|
+
provider[AAR_PROVIDER_ID] = aarProvider;
|
|
55
|
+
return {
|
|
56
|
+
...base,
|
|
57
|
+
provider,
|
|
58
|
+
model: `${AAR_PROVIDER_ID}/${defaultModel}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 生成合并后的配置(不写入磁盘),供预览或应用使用 */
|
|
63
|
+
export async function buildMergedConfig(
|
|
64
|
+
defaultModel: string,
|
|
65
|
+
existing: Record<string, any> | null
|
|
66
|
+
): Promise<Record<string, any>> {
|
|
67
|
+
const aarProvider = await buildAarGatewayProvider();
|
|
68
|
+
return mergeConfigWithAar(existing, defaultModel, aarProvider);
|
|
69
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { buildMergedConfig } from '../build-config';
|
|
6
|
+
|
|
7
|
+
const OPENCODE_FILE =
|
|
8
|
+
process.platform === 'win32'
|
|
9
|
+
? join(process.env.APPDATA || homedir(), 'opencode', 'opencode.json')
|
|
10
|
+
: join(homedir(), '.config', 'opencode', 'opencode.json');
|
|
11
|
+
|
|
12
|
+
/** GET ?default_model=xxx 返回配置预览:始终返回「现有配置 + AAR provider + 默认模型」的合并结果,即应用后将写入的内容 */
|
|
13
|
+
export async function GET(request: NextRequest) {
|
|
14
|
+
try {
|
|
15
|
+
const { searchParams } = new URL(request.url);
|
|
16
|
+
const defaultModel = searchParams.get('default_model') || '';
|
|
17
|
+
|
|
18
|
+
if (!defaultModel) {
|
|
19
|
+
return NextResponse.json({ error: 'Missing query: default_model' }, { status: 400 });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let existing: Record<string, any> | null = null;
|
|
23
|
+
if (existsSync(OPENCODE_FILE)) {
|
|
24
|
+
try {
|
|
25
|
+
existing = JSON.parse(readFileSync(OPENCODE_FILE, 'utf-8'));
|
|
26
|
+
} catch {
|
|
27
|
+
/* 文件损坏时 existing 保持 null */
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const config = await buildMergedConfig(defaultModel, existing);
|
|
32
|
+
return NextResponse.json({ config });
|
|
33
|
+
} catch (error: any) {
|
|
34
|
+
console.error('OpenCode Preview API error:', error);
|
|
35
|
+
return NextResponse.json(
|
|
36
|
+
{ error: error.message || 'Internal server error', stack: process.env.NODE_ENV === 'development' ? error.stack : undefined },
|
|
37
|
+
{ status: 500 }
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { existsSync, readFileSync, copyFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
|
|
6
|
+
const OPENCODE_DIR =
|
|
7
|
+
process.platform === 'win32'
|
|
8
|
+
? join(process.env.APPDATA || homedir(), 'opencode')
|
|
9
|
+
: join(homedir(), '.config', 'opencode');
|
|
10
|
+
const OPENCODE_FILE = join(OPENCODE_DIR, 'opencode.json');
|
|
11
|
+
const BACKUP_FILE = join(OPENCODE_DIR, 'opencode.json.aar.bak');
|
|
12
|
+
|
|
13
|
+
export async function POST(request: NextRequest) {
|
|
14
|
+
try {
|
|
15
|
+
if (!existsSync(BACKUP_FILE)) {
|
|
16
|
+
return NextResponse.json(
|
|
17
|
+
{ error: 'No backup file found. Please apply configuration first before restoring.' },
|
|
18
|
+
{ status: 404 }
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const backupContent = readFileSync(BACKUP_FILE, 'utf-8');
|
|
23
|
+
|
|
24
|
+
if (!existsSync(OPENCODE_DIR)) {
|
|
25
|
+
return NextResponse.json({ error: 'OpenCode config directory does not exist' }, { status: 500 });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
copyFileSync(BACKUP_FILE, OPENCODE_FILE);
|
|
29
|
+
|
|
30
|
+
let parsedBackup: any;
|
|
31
|
+
try {
|
|
32
|
+
parsedBackup = JSON.parse(backupContent);
|
|
33
|
+
} catch {
|
|
34
|
+
return NextResponse.json(
|
|
35
|
+
{ error: 'Backup file is corrupted or invalid JSON', backupContent },
|
|
36
|
+
{ status: 500 }
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return NextResponse.json({
|
|
41
|
+
success: true,
|
|
42
|
+
message: 'OpenCode configuration restored successfully',
|
|
43
|
+
config: parsedBackup,
|
|
44
|
+
});
|
|
45
|
+
} catch (error: any) {
|
|
46
|
+
console.error('OpenCode Restore API error:', error);
|
|
47
|
+
return NextResponse.json(
|
|
48
|
+
{ error: error.message || 'Internal server error', stack: process.env.NODE_ENV === 'development' ? error.stack : undefined },
|
|
49
|
+
{ status: 500 }
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { getDatabase } from '@/db/database';
|
|
6
|
+
import { getConfig } from '@/db/queries';
|
|
7
|
+
import { buildMergedConfig } from '../build-config';
|
|
8
|
+
|
|
9
|
+
const OPENCODE_DIR =
|
|
10
|
+
process.platform === 'win32'
|
|
11
|
+
? join(process.env.APPDATA || homedir(), 'opencode')
|
|
12
|
+
: join(homedir(), '.config', 'opencode');
|
|
13
|
+
const OPENCODE_FILE = join(OPENCODE_DIR, 'opencode.json');
|
|
14
|
+
const BACKUP_FILE = join(OPENCODE_DIR, 'opencode.json.aar.bak');
|
|
15
|
+
const AAR_DIR = join(homedir(), '.aar');
|
|
16
|
+
const TEMP_OPENCODE_FILE = join(AAR_DIR, 'opencode.tmp.json');
|
|
17
|
+
|
|
18
|
+
function backupIfExists(): { success: boolean; error?: string } {
|
|
19
|
+
try {
|
|
20
|
+
if (existsSync(OPENCODE_FILE)) {
|
|
21
|
+
const original = readFileSync(OPENCODE_FILE, 'utf-8');
|
|
22
|
+
writeFileSync(BACKUP_FILE, original, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
return { success: true };
|
|
25
|
+
} catch (error: any) {
|
|
26
|
+
return { success: false, error: `Backup failed: ${error.message}` };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function getGatewayAddress(): Promise<string> {
|
|
31
|
+
await getDatabase();
|
|
32
|
+
const portConfig = await getConfig('port');
|
|
33
|
+
return `http://localhost:${portConfig?.value || '1357'}/v1`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function getGatewayApiKey(): Promise<string> {
|
|
37
|
+
await getDatabase();
|
|
38
|
+
const apiKeyConfig = await getConfig('api_key');
|
|
39
|
+
return apiKeyConfig?.value || 'your-gateway-api-key';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function POST(request: NextRequest) {
|
|
43
|
+
try {
|
|
44
|
+
const body = await request.json();
|
|
45
|
+
const { default_model: defaultModel, config: customConfigStr } = body;
|
|
46
|
+
|
|
47
|
+
// 若前端传了编辑后的 config,直接写入 opencode.json(与「应用配置」一致)
|
|
48
|
+
if (typeof customConfigStr === 'string' && customConfigStr.trim()) {
|
|
49
|
+
let config: Record<string, any>;
|
|
50
|
+
try {
|
|
51
|
+
config = JSON.parse(customConfigStr);
|
|
52
|
+
if (!config || typeof config !== 'object') throw new Error('Invalid config object');
|
|
53
|
+
} catch (e: any) {
|
|
54
|
+
return NextResponse.json({ error: 'Invalid config JSON: ' + (e.message || 'parse error') }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
const backupResult = backupIfExists();
|
|
57
|
+
if (!backupResult.success) {
|
|
58
|
+
return NextResponse.json({ error: backupResult.error }, { status: 500 });
|
|
59
|
+
}
|
|
60
|
+
if (!existsSync(OPENCODE_DIR)) mkdirSync(OPENCODE_DIR, { recursive: true });
|
|
61
|
+
writeFileSync(OPENCODE_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
62
|
+
return NextResponse.json({
|
|
63
|
+
success: true,
|
|
64
|
+
message: '配置已更新到 OpenCode',
|
|
65
|
+
saveType: 'applied',
|
|
66
|
+
savePath: '~/.config/opencode/opencode.json',
|
|
67
|
+
config,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (defaultModel === undefined || defaultModel === '') {
|
|
72
|
+
return NextResponse.json({ error: 'No default model provided' }, { status: 400 });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const gatewayAddress = await getGatewayAddress();
|
|
76
|
+
const gatewayApiKey = await getGatewayApiKey();
|
|
77
|
+
|
|
78
|
+
const fileExists = existsSync(OPENCODE_FILE);
|
|
79
|
+
let current: Record<string, any> | null = null;
|
|
80
|
+
if (fileExists) {
|
|
81
|
+
try {
|
|
82
|
+
current = JSON.parse(readFileSync(OPENCODE_FILE, 'utf-8'));
|
|
83
|
+
} catch {
|
|
84
|
+
current = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const aar = current?.provider?.['aar-gateway'];
|
|
88
|
+
const isCurrentGatewayApplied =
|
|
89
|
+
!!aar &&
|
|
90
|
+
aar?.options?.baseURL === gatewayAddress &&
|
|
91
|
+
aar?.options?.apiKey === gatewayApiKey;
|
|
92
|
+
|
|
93
|
+
let savePath: string;
|
|
94
|
+
let saveType: string;
|
|
95
|
+
let mergedConfig: any;
|
|
96
|
+
|
|
97
|
+
if (fileExists && isCurrentGatewayApplied && current) {
|
|
98
|
+
mergedConfig = await buildMergedConfig(defaultModel, current);
|
|
99
|
+
savePath = OPENCODE_FILE;
|
|
100
|
+
saveType = 'applied';
|
|
101
|
+
} else {
|
|
102
|
+
savePath = TEMP_OPENCODE_FILE;
|
|
103
|
+
saveType = 'temp';
|
|
104
|
+
mergedConfig = {
|
|
105
|
+
defaultModel,
|
|
106
|
+
isTemp: true,
|
|
107
|
+
savedAt: new Date().toISOString(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const targetDir = savePath === OPENCODE_FILE ? OPENCODE_DIR : AAR_DIR;
|
|
112
|
+
if (!existsSync(targetDir)) {
|
|
113
|
+
mkdirSync(targetDir, { recursive: true });
|
|
114
|
+
}
|
|
115
|
+
writeFileSync(savePath, JSON.stringify(mergedConfig, null, 2), 'utf-8');
|
|
116
|
+
|
|
117
|
+
return NextResponse.json({
|
|
118
|
+
success: true,
|
|
119
|
+
message: saveType === 'applied' ? '配置已更新到 OpenCode' : '配置已保存(临时)',
|
|
120
|
+
saveType,
|
|
121
|
+
savePath: savePath === OPENCODE_FILE ? '~/.config/opencode/opencode.json' : '~/.aar/opencode.tmp.json',
|
|
122
|
+
config: mergedConfig,
|
|
123
|
+
});
|
|
124
|
+
} catch (error: any) {
|
|
125
|
+
console.error('OpenCode Save API error:', error);
|
|
126
|
+
return NextResponse.json(
|
|
127
|
+
{ error: error.message || 'Internal server error', stack: process.env.NODE_ENV === 'development' ? error.stack : undefined },
|
|
128
|
+
{ status: 500 }
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|