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
|
@@ -10,6 +10,20 @@ const react_1 = require("react");
|
|
|
10
10
|
const Nav_1 = __importDefault(require("../components/Nav"));
|
|
11
11
|
const ToastProvider_1 = require("../components/ToastProvider");
|
|
12
12
|
const ConfirmDialog_1 = __importDefault(require("../components/ConfirmDialog"));
|
|
13
|
+
/** 将服务端返回的 created_at 格式化为本地显示。数据库存储的是本地时间,无需追加 Z 后缀。 */
|
|
14
|
+
function formatCreatedAt(createdAt) {
|
|
15
|
+
if (!createdAt || typeof createdAt !== 'string')
|
|
16
|
+
return '';
|
|
17
|
+
const s = createdAt.trim();
|
|
18
|
+
if (!s)
|
|
19
|
+
return '';
|
|
20
|
+
// 数据库使用 datetime('now','localtime') 存储的已经是本地时间,
|
|
21
|
+
// 不带时区后缀时直接按本地时间解析,不要追加 'Z'(否则会多偏移 8 小时)
|
|
22
|
+
const hasTz = /[Z+-]\d{2}:?\d{2}$/.test(s);
|
|
23
|
+
const iso = hasTz ? s : s.replace(' ', 'T');
|
|
24
|
+
const date = new Date(iso);
|
|
25
|
+
return Number.isNaN(date.getTime()) ? s : date.toLocaleString('zh-CN');
|
|
26
|
+
}
|
|
13
27
|
function LogsPage() {
|
|
14
28
|
const [logs, setLogs] = (0, react_1.useState)([]);
|
|
15
29
|
const [selectedLog, setSelectedLog] = (0, react_1.useState)(null);
|
|
@@ -244,7 +258,7 @@ function LogsPage() {
|
|
|
244
258
|
}, className: "mt-2 text-xs text-emerald-600 hover:text-emerald-700", children: "\u6E05\u9664\u641C\u7D22" }))] }) }) })) : (logs.map((log) => {
|
|
245
259
|
const parsedModel = parseModelFromRequest(log.request_query, log.request_body);
|
|
246
260
|
const displayModel = parsedModel || log.model_name || 'Gateway';
|
|
247
|
-
return ((0, jsx_runtime_1.jsxs)("tr", { className: "hover:bg-emerald-50/20 transition-colors duration-300", children: [(0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: selectedIds.includes(log.id), onChange: (e) => handleSelectLog(log.id, e.target.checked), className: "w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500", onClick: (e) => e.stopPropagation() }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3 whitespace-nowrap", children: (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-slate-600", children:
|
|
261
|
+
return ((0, jsx_runtime_1.jsxs)("tr", { className: "hover:bg-emerald-50/20 transition-colors duration-300", children: [(0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: selectedIds.includes(log.id), onChange: (e) => handleSelectLog(log.id, e.target.checked), className: "w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500", onClick: (e) => e.stopPropagation() }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3 whitespace-nowrap", children: (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-slate-600", children: formatCreatedAt(log.created_at) }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3 whitespace-nowrap", children: (0, jsx_runtime_1.jsxs)("div", { className: "text-xs", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-medium text-slate-800", children: displayModel }), log.provider_name && ((0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-slate-500", children: log.provider_name }))] }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3 whitespace-nowrap", children: (0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-lg border ${log.request_method === 'GET' ? 'bg-sky-50 text-sky-700 border-sky-200/50' :
|
|
248
262
|
log.request_method === 'POST' ? 'bg-emerald-50 text-emerald-700 border-emerald-200/50' :
|
|
249
263
|
'bg-slate-50 text-slate-600 border-slate-200/50'}`, children: log.request_method }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-slate-600 font-mono max-w-xs truncate", children: log.request_path }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3 whitespace-nowrap", children: (0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-full border ${log.response_status >= 200 && log.response_status < 300 ? 'bg-emerald-100/80 text-emerald-700 border-emerald-200/50' :
|
|
250
264
|
log.response_status >= 400 && log.response_status < 500 ? 'bg-amber-100/80 text-amber-700 border-amber-200/50' :
|
package/dist/src/cli/index.js
CHANGED
|
@@ -7,51 +7,249 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const child_process_1 = require("child_process");
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const http_1 = __importDefault(require("http"));
|
|
10
13
|
const database_1 = require("../db/database");
|
|
11
14
|
const queries_1 = require("../db/queries");
|
|
12
15
|
const program = new commander_1.Command();
|
|
13
16
|
const packageJsonPath = require.resolve('../../../package.json');
|
|
14
17
|
const packageJson = require(packageJsonPath);
|
|
18
|
+
const AAR_DIR = path_1.default.join(os_1.default.homedir(), '.aar');
|
|
19
|
+
const UI_PID_FILE = path_1.default.join(AAR_DIR, 'ui.pid');
|
|
20
|
+
const GATEWAY_PID_FILE = path_1.default.join(AAR_DIR, 'gateway.pid');
|
|
21
|
+
const GATEWAY_PORT_FILE = path_1.default.join(AAR_DIR, 'gateway.port');
|
|
22
|
+
function ensureAarDir() {
|
|
23
|
+
if (!fs_1.default.existsSync(AAR_DIR)) {
|
|
24
|
+
fs_1.default.mkdirSync(AAR_DIR, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function getPackageRoot() {
|
|
28
|
+
return path_1.default.dirname(path_1.default.dirname(path_1.default.dirname(__dirname)));
|
|
29
|
+
}
|
|
30
|
+
/** Wait for HTTP server to respond (e.g. UI or gateway ready) */
|
|
31
|
+
function waitForReady(baseUrl, maxWaitMs = 30000) {
|
|
32
|
+
const url = new URL(baseUrl);
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
const start = Date.now();
|
|
35
|
+
const tryOnce = () => {
|
|
36
|
+
const req = http_1.default.request({
|
|
37
|
+
hostname: url.hostname,
|
|
38
|
+
port: url.port || '80',
|
|
39
|
+
path: url.pathname || '/',
|
|
40
|
+
method: 'GET',
|
|
41
|
+
timeout: 2000,
|
|
42
|
+
}, (res) => {
|
|
43
|
+
resolve(res.statusCode !== undefined && res.statusCode < 500);
|
|
44
|
+
});
|
|
45
|
+
req.on('error', () => {
|
|
46
|
+
if (Date.now() - start >= maxWaitMs) {
|
|
47
|
+
resolve(false);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
setTimeout(tryOnce, 800);
|
|
51
|
+
});
|
|
52
|
+
req.on('timeout', () => {
|
|
53
|
+
req.destroy();
|
|
54
|
+
if (Date.now() - start >= maxWaitMs)
|
|
55
|
+
resolve(false);
|
|
56
|
+
else
|
|
57
|
+
setTimeout(tryOnce, 800);
|
|
58
|
+
});
|
|
59
|
+
req.end();
|
|
60
|
+
};
|
|
61
|
+
tryOnce();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function printStatus(uiPort, gatewayPort, gatewayRunning, background) {
|
|
65
|
+
const uiUrl = `http://localhost:${uiPort}`;
|
|
66
|
+
const gatewayUrl = `http://localhost:${gatewayPort}`;
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log('-------------------------------------------');
|
|
69
|
+
console.log(' AI Agent Router');
|
|
70
|
+
console.log('-------------------------------------------');
|
|
71
|
+
console.log(` 前台 UI: ${uiUrl}`);
|
|
72
|
+
console.log(` 网关地址: ${gatewayUrl}`);
|
|
73
|
+
console.log(` 网关状态: ${gatewayRunning ? '运行中' : '未启动'}`);
|
|
74
|
+
if (background) {
|
|
75
|
+
console.log(' 运行模式: 后台运行(关闭终端不影响)');
|
|
76
|
+
console.log(' 停止服务: aar stop');
|
|
77
|
+
}
|
|
78
|
+
console.log('-------------------------------------------');
|
|
79
|
+
console.log('');
|
|
80
|
+
}
|
|
15
81
|
program
|
|
16
82
|
.name('aar')
|
|
17
83
|
.description('AI Agent Router - Web UI for managing the API gateway')
|
|
18
84
|
.version(packageJson.version);
|
|
19
85
|
program
|
|
20
86
|
.command('start')
|
|
21
|
-
.description('Start the Web UI
|
|
87
|
+
.description('Start the Web UI and gateway (default: both; use --no-gateway for UI only)')
|
|
22
88
|
.option('-p, --port <port>', 'Port for Web UI', '9527')
|
|
89
|
+
.option('-g, --gateway-port <port>', 'Port for gateway (default: from config or 1357)')
|
|
90
|
+
.option('--no-gateway', 'Only start Web UI, do not start gateway')
|
|
91
|
+
.option('--no-background', 'Run in foreground (attach to terminal)')
|
|
23
92
|
.action(async (options) => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
93
|
+
const uiPort = parseInt(options.port || '9527', 10);
|
|
94
|
+
const startGateway = options.gateway !== false;
|
|
95
|
+
const background = options.background !== false;
|
|
96
|
+
const packageRoot = getPackageRoot();
|
|
97
|
+
let gatewayPort = 1357;
|
|
98
|
+
if (startGateway) {
|
|
99
|
+
try {
|
|
100
|
+
await (0, database_1.getDatabase)();
|
|
101
|
+
const portConfig = await (0, queries_1.getConfig)('port');
|
|
102
|
+
gatewayPort = options.gatewayPort
|
|
103
|
+
? parseInt(options.gatewayPort, 10)
|
|
104
|
+
: parseInt(portConfig?.value || '1357', 10);
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
gatewayPort = options.gatewayPort ? parseInt(options.gatewayPort, 10) : 1357;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
33
110
|
const serverPath = path_1.default.join(packageRoot, 'node_modules', 'next', 'dist', 'bin', 'next');
|
|
34
|
-
const
|
|
111
|
+
const gatewayScriptPath = path_1.default.join(packageRoot, 'dist', 'src', 'cli', 'gateway-server.js');
|
|
112
|
+
if (background) {
|
|
113
|
+
ensureAarDir();
|
|
114
|
+
const envBase = { ...process.env, NODE_ENV: 'production' };
|
|
115
|
+
const uiProc = (0, child_process_1.spawn)(process.execPath, [serverPath, 'start', '-p', uiPort.toString()], {
|
|
116
|
+
cwd: packageRoot,
|
|
117
|
+
env: { ...envBase, PORT: uiPort.toString() },
|
|
118
|
+
detached: true,
|
|
119
|
+
stdio: 'ignore',
|
|
120
|
+
});
|
|
121
|
+
uiProc.unref();
|
|
122
|
+
if (uiProc.pid) {
|
|
123
|
+
fs_1.default.writeFileSync(UI_PID_FILE, String(uiProc.pid));
|
|
124
|
+
}
|
|
125
|
+
let gatewayRunning = false;
|
|
126
|
+
if (startGateway && fs_1.default.existsSync(gatewayScriptPath)) {
|
|
127
|
+
const gwProc = (0, child_process_1.spawn)(process.execPath, [gatewayScriptPath, '--port', String(gatewayPort)], {
|
|
128
|
+
cwd: packageRoot,
|
|
129
|
+
env: envBase,
|
|
130
|
+
detached: true,
|
|
131
|
+
stdio: 'ignore',
|
|
132
|
+
});
|
|
133
|
+
gwProc.unref();
|
|
134
|
+
if (gwProc.pid) {
|
|
135
|
+
fs_1.default.writeFileSync(GATEWAY_PID_FILE, String(gwProc.pid));
|
|
136
|
+
fs_1.default.writeFileSync(GATEWAY_PORT_FILE, String(gatewayPort));
|
|
137
|
+
gatewayRunning = true;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
await (0, database_1.getDatabase)();
|
|
141
|
+
await (0, queries_1.setServiceStatus)({
|
|
142
|
+
status: 'running',
|
|
143
|
+
port: gatewayPort,
|
|
144
|
+
pid: gwProc.pid ?? null,
|
|
145
|
+
started_at: new Date().toISOString(),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// ignore db errors
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
printStatus(uiPort, gatewayPort, gatewayRunning, true);
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
// Foreground: start UI first
|
|
156
|
+
console.log('Starting AI Agent Router...');
|
|
157
|
+
const uiProcess = (0, child_process_1.spawn)(process.execPath, [serverPath, 'start', '-p', uiPort.toString()], {
|
|
35
158
|
cwd: packageRoot,
|
|
36
159
|
stdio: ['ignore', 'inherit', 'inherit'],
|
|
37
|
-
env: { ...process.env, PORT:
|
|
38
|
-
});
|
|
39
|
-
// Handle UI process exit
|
|
40
|
-
uiProcess.on('exit', (code) => {
|
|
41
|
-
console.log(`Web UI process exited with code ${code}`);
|
|
42
|
-
process.exit(code || 0);
|
|
160
|
+
env: { ...process.env, PORT: uiPort.toString(), NODE_ENV: 'production' },
|
|
43
161
|
});
|
|
44
162
|
uiProcess.on('error', (error) => {
|
|
45
163
|
console.error(`Failed to start Web UI: ${error.message}`);
|
|
46
164
|
process.exit(1);
|
|
47
165
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
166
|
+
const gatewayProcess = startGateway && fs_1.default.existsSync(gatewayScriptPath)
|
|
167
|
+
? (0, child_process_1.spawn)(process.execPath, [gatewayScriptPath, '--port', String(gatewayPort)], {
|
|
168
|
+
cwd: packageRoot,
|
|
169
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
170
|
+
env: { ...process.env, NODE_ENV: 'production' },
|
|
171
|
+
})
|
|
172
|
+
: null;
|
|
173
|
+
if (gatewayProcess?.stdout) {
|
|
174
|
+
gatewayProcess.stdout.on('data', (d) => process.stdout.write(d));
|
|
175
|
+
}
|
|
176
|
+
if (gatewayProcess?.stderr) {
|
|
177
|
+
gatewayProcess.stderr.on('data', (d) => process.stderr.write(d));
|
|
178
|
+
}
|
|
179
|
+
const ready = await waitForReady(`http://localhost:${uiPort}`);
|
|
180
|
+
if (ready) {
|
|
181
|
+
printStatus(uiPort, gatewayPort, !!gatewayProcess, false);
|
|
182
|
+
}
|
|
183
|
+
const shutdown = (signal) => {
|
|
184
|
+
console.log(`\nShutting down (${signal})...`);
|
|
185
|
+
if (gatewayProcess?.pid) {
|
|
186
|
+
try {
|
|
187
|
+
process.kill(gatewayProcess.pid, 'SIGTERM');
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// ignore
|
|
191
|
+
}
|
|
192
|
+
}
|
|
51
193
|
uiProcess.kill('SIGTERM');
|
|
52
194
|
process.exit(0);
|
|
195
|
+
};
|
|
196
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
197
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
198
|
+
uiProcess.on('exit', (code) => {
|
|
199
|
+
if (gatewayProcess?.pid) {
|
|
200
|
+
try {
|
|
201
|
+
process.kill(gatewayProcess.pid, 'SIGTERM');
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// ignore
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
process.exit(code ?? 0);
|
|
53
208
|
});
|
|
54
209
|
});
|
|
210
|
+
program
|
|
211
|
+
.command('stop')
|
|
212
|
+
.description('Stop AI Agent Router when running in background')
|
|
213
|
+
.action(async () => {
|
|
214
|
+
ensureAarDir();
|
|
215
|
+
let stopped = 0;
|
|
216
|
+
const killPidFile = (file, name) => {
|
|
217
|
+
if (!fs_1.default.existsSync(file))
|
|
218
|
+
return;
|
|
219
|
+
try {
|
|
220
|
+
const pid = parseInt(fs_1.default.readFileSync(file, 'utf8').trim(), 10);
|
|
221
|
+
if (!isNaN(pid)) {
|
|
222
|
+
try {
|
|
223
|
+
process.kill(pid, 'SIGTERM');
|
|
224
|
+
console.log(`Stopped ${name} (PID ${pid})`);
|
|
225
|
+
stopped++;
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
if (e?.code !== 'ESRCH')
|
|
229
|
+
console.warn(`${name} (PID ${pid}): ${e.message}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
fs_1.default.unlinkSync(file);
|
|
233
|
+
}
|
|
234
|
+
catch (e) {
|
|
235
|
+
// ignore
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
killPidFile(GATEWAY_PID_FILE, 'gateway');
|
|
239
|
+
killPidFile(UI_PID_FILE, 'Web UI');
|
|
240
|
+
if (fs_1.default.existsSync(GATEWAY_PORT_FILE))
|
|
241
|
+
fs_1.default.unlinkSync(GATEWAY_PORT_FILE);
|
|
242
|
+
try {
|
|
243
|
+
await (0, database_1.getDatabase)();
|
|
244
|
+
await (0, queries_1.updateServiceStatus)({ status: 'stopped', pid: null });
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// ignore
|
|
248
|
+
}
|
|
249
|
+
if (stopped === 0) {
|
|
250
|
+
console.log('No background processes found (or already stopped).');
|
|
251
|
+
}
|
|
252
|
+
});
|
|
55
253
|
program
|
|
56
254
|
.command('config')
|
|
57
255
|
.description('Manage gateway configuration')
|
package/dist/src/db/database.js
CHANGED
|
@@ -15,14 +15,55 @@ const path_1 = __importDefault(require("path"));
|
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const os_1 = __importDefault(require("os"));
|
|
17
17
|
const DB_PATH = process.env.DB_PATH || path_1.default.join(os_1.default.homedir(), '.aar', 'gateway.db');
|
|
18
|
+
// Use hardcoded path for the built/distributed WASM file
|
|
19
|
+
// Next.js copies sql-wasm.wasm to its chunks directory
|
|
20
|
+
function findSqlJsWasmPath() {
|
|
21
|
+
// Try Next.js chunks directory first (works in dev and production)
|
|
22
|
+
const nextChunksPath = path_1.default.join(process.cwd(), '.next', 'dev', 'server', 'chunks', 'sql-wasm.wasm');
|
|
23
|
+
if (fs_1.default.existsSync(nextChunksPath)) {
|
|
24
|
+
return nextChunksPath;
|
|
25
|
+
}
|
|
26
|
+
// Try production .next directory
|
|
27
|
+
const prodChunksPath = path_1.default.join(process.cwd(), '.next', 'server', 'chunks', 'sql-wasm.wasm');
|
|
28
|
+
if (fs_1.default.existsSync(prodChunksPath)) {
|
|
29
|
+
return prodChunksPath;
|
|
30
|
+
}
|
|
31
|
+
// Try node_modules as fallback
|
|
32
|
+
const nodeModulesPath = path_1.default.join(process.cwd(), 'node_modules', 'sql.js', 'dist', 'sql-wasm.wasm');
|
|
33
|
+
if (fs_1.default.existsSync(nodeModulesPath)) {
|
|
34
|
+
return nodeModulesPath;
|
|
35
|
+
}
|
|
36
|
+
// Use the most likely location as default
|
|
37
|
+
return nodeModulesPath;
|
|
38
|
+
}
|
|
39
|
+
const SQLJS_WASM_PATH = findSqlJsWasmPath();
|
|
18
40
|
let dbInstance = null;
|
|
19
41
|
let sqlJsInstance = null;
|
|
42
|
+
let lastLoadMtimeMs = 0;
|
|
43
|
+
function reloadFromFileIfNewer() {
|
|
44
|
+
if (!dbInstance || !fs_1.default.existsSync(DB_PATH))
|
|
45
|
+
return;
|
|
46
|
+
const mtime = fs_1.default.statSync(DB_PATH).mtimeMs;
|
|
47
|
+
if (mtime <= lastLoadMtimeMs)
|
|
48
|
+
return;
|
|
49
|
+
try {
|
|
50
|
+
const fresh = loadDatabase();
|
|
51
|
+
if (fresh) {
|
|
52
|
+
dbInstance.close();
|
|
53
|
+
dbInstance = fresh;
|
|
54
|
+
lastLoadMtimeMs = fs_1.default.statSync(DB_PATH).mtimeMs;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
console.warn('[Database] Reload from file failed:', e.message);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
20
61
|
async function initSqlJsEngine() {
|
|
21
62
|
if (!sqlJsInstance) {
|
|
22
63
|
sqlJsInstance = await (0, sql_js_1.default)({
|
|
23
64
|
locateFile: (file) => {
|
|
24
65
|
if (file.endsWith('.wasm')) {
|
|
25
|
-
return
|
|
66
|
+
return SQLJS_WASM_PATH;
|
|
26
67
|
}
|
|
27
68
|
return `https://sql.js.org/dist/${file}`;
|
|
28
69
|
}
|
|
@@ -39,6 +80,9 @@ function saveDatabase(db) {
|
|
|
39
80
|
fs_1.default.mkdirSync(dbDir, { recursive: true });
|
|
40
81
|
}
|
|
41
82
|
fs_1.default.writeFileSync(DB_PATH, buffer);
|
|
83
|
+
if (fs_1.default.existsSync(DB_PATH)) {
|
|
84
|
+
lastLoadMtimeMs = fs_1.default.statSync(DB_PATH).mtimeMs;
|
|
85
|
+
}
|
|
42
86
|
}
|
|
43
87
|
catch (error) {
|
|
44
88
|
console.error('Failed to save database:', error);
|
|
@@ -59,7 +103,16 @@ function loadDatabase() {
|
|
|
59
103
|
async function getDatabase() {
|
|
60
104
|
if (!dbInstance) {
|
|
61
105
|
const engine = await initSqlJsEngine();
|
|
62
|
-
|
|
106
|
+
const loaded = loadDatabase();
|
|
107
|
+
if (loaded) {
|
|
108
|
+
dbInstance = loaded;
|
|
109
|
+
if (fs_1.default.existsSync(DB_PATH))
|
|
110
|
+
lastLoadMtimeMs = fs_1.default.statSync(DB_PATH).mtimeMs;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
dbInstance = new engine.Database();
|
|
114
|
+
lastLoadMtimeMs = 0;
|
|
115
|
+
}
|
|
63
116
|
try {
|
|
64
117
|
dbInstance.run(schema_1.CREATE_TABLES_SQL);
|
|
65
118
|
// Migration: Allow NULL model_id in request_logs table
|
|
@@ -113,6 +166,7 @@ async function getDatabase() {
|
|
|
113
166
|
}
|
|
114
167
|
}
|
|
115
168
|
}
|
|
169
|
+
reloadFromFileIfNewer();
|
|
116
170
|
return dbInstance;
|
|
117
171
|
}
|
|
118
172
|
async function closeDatabase() {
|
|
@@ -125,7 +179,6 @@ async function closeDatabase() {
|
|
|
125
179
|
function getDbPath() {
|
|
126
180
|
return DB_PATH;
|
|
127
181
|
}
|
|
128
|
-
// Helper to run a query and get single result
|
|
129
182
|
async function queryOne(sql, params = []) {
|
|
130
183
|
const db = await getDatabase();
|
|
131
184
|
const stmt = db.prepare(sql);
|
|
@@ -138,7 +191,6 @@ async function queryOne(sql, params = []) {
|
|
|
138
191
|
stmt.free();
|
|
139
192
|
return null;
|
|
140
193
|
}
|
|
141
|
-
// Helper to run a query and get all results
|
|
142
194
|
async function queryAll(sql, params = []) {
|
|
143
195
|
const db = await getDatabase();
|
|
144
196
|
const results = [];
|
|
@@ -150,7 +202,6 @@ async function queryAll(sql, params = []) {
|
|
|
150
202
|
stmt.free();
|
|
151
203
|
return results;
|
|
152
204
|
}
|
|
153
|
-
// Helper to run INSERT/UPDATE/DELETE
|
|
154
205
|
async function run(sql, params = []) {
|
|
155
206
|
const db = await getDatabase();
|
|
156
207
|
db.run(sql, params);
|
package/dist/src/db/queries.js
CHANGED
|
@@ -155,9 +155,9 @@ async function createRequestLog(log) {
|
|
|
155
155
|
try {
|
|
156
156
|
const result = await (0, database_1.run)(`INSERT INTO request_logs (
|
|
157
157
|
model_id, request_method, request_path, request_headers,
|
|
158
|
-
request_query, request_body, response_status, response_body, response_time_ms
|
|
159
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
|
|
160
|
-
log.model_id
|
|
158
|
+
request_query, request_body, response_status, response_body, response_time_ms, created_at
|
|
159
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'))`, [
|
|
160
|
+
log.model_id === undefined ? null : log.model_id,
|
|
161
161
|
log.request_method,
|
|
162
162
|
log.request_path,
|
|
163
163
|
log.request_headers,
|
|
@@ -178,9 +178,9 @@ async function createRequestLog(log) {
|
|
|
178
178
|
console.warn(`[RequestLog] Foreign key constraint failed for model_id ${log.model_id}, retrying with NULL`);
|
|
179
179
|
const result = await (0, database_1.run)(`INSERT INTO request_logs (
|
|
180
180
|
model_id, request_method, request_path, request_headers,
|
|
181
|
-
request_query, request_body, response_status, response_body, response_time_ms
|
|
182
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
|
|
183
|
-
null,
|
|
181
|
+
request_query, request_body, response_status, response_body, response_time_ms, created_at
|
|
182
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'))`, [
|
|
183
|
+
log.model_id === undefined ? null : log.model_id,
|
|
184
184
|
log.request_method,
|
|
185
185
|
log.request_path,
|
|
186
186
|
log.request_headers,
|
|
@@ -3,6 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.logRequest = logRequest;
|
|
4
4
|
const queries_1 = require("../db/queries");
|
|
5
5
|
const crypto_1 = require("./crypto");
|
|
6
|
+
/** Safe JSON.stringify that never throws; use for logging arbitrary response/request bodies. */
|
|
7
|
+
function safeStringify(value) {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
return '';
|
|
10
|
+
if (value === null)
|
|
11
|
+
return 'null';
|
|
12
|
+
try {
|
|
13
|
+
return JSON.stringify(value);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
try {
|
|
17
|
+
return String(value);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return '[Non-serializable]';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
6
24
|
async function logRequest(request, response) {
|
|
7
25
|
try {
|
|
8
26
|
// Mask sensitive information
|
|
@@ -12,11 +30,11 @@ async function logRequest(request, response) {
|
|
|
12
30
|
model_id: request.modelId,
|
|
13
31
|
request_method: request.method,
|
|
14
32
|
request_path: request.path,
|
|
15
|
-
request_headers:
|
|
16
|
-
request_query:
|
|
17
|
-
request_body:
|
|
33
|
+
request_headers: safeStringify(maskedHeaders),
|
|
34
|
+
request_query: safeStringify(request.query),
|
|
35
|
+
request_body: safeStringify(maskedBody),
|
|
18
36
|
response_status: response.status,
|
|
19
|
-
response_body:
|
|
37
|
+
response_body: safeStringify(response.body),
|
|
20
38
|
response_time_ms: response.responseTimeMs,
|
|
21
39
|
});
|
|
22
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-agent-router",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A unified API gateway for managing multiple AI model providers (Anthropic, OpenAI, Gemini, etc.)",
|
|
5
5
|
"main": "dist/src/cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"dev": "next dev -p 9527",
|
|
11
11
|
"build": "next build && tsc",
|
|
12
12
|
"start": "node dist/src/cli/index.js start",
|
|
13
|
+
"stop": "node dist/src/cli/index.js stop",
|
|
13
14
|
"lint": "eslint .",
|
|
14
15
|
"pub": "npm run build && npm publish",
|
|
15
16
|
"type-check": "tsc --noEmit"
|
|
@@ -19,7 +19,7 @@ async function handleGatewayRequestDirect(
|
|
|
19
19
|
method: string
|
|
20
20
|
) {
|
|
21
21
|
try {
|
|
22
|
-
getDatabase();
|
|
22
|
+
await getDatabase();
|
|
23
23
|
const searchParams = request.nextUrl.searchParams;
|
|
24
24
|
let modelId = searchParams.get('model') || searchParams.get('model_id');
|
|
25
25
|
const providerName = searchParams.get('provider');
|
|
@@ -38,11 +38,9 @@ export async function POST(request: NextRequest) {
|
|
|
38
38
|
const gatewayAddress = await getGatewayAddress();
|
|
39
39
|
const gatewayApiKey = await getGatewayApiKey();
|
|
40
40
|
|
|
41
|
-
// 生成配置对象
|
|
42
41
|
const modelMapping = { haiku, sonnet, opus, default: defaultModel, reasoning: reasoningModel };
|
|
43
|
-
const
|
|
42
|
+
const aarEnv = buildAarEnv(gatewayAddress, gatewayApiKey, modelMapping);
|
|
44
43
|
|
|
45
|
-
// 备份原有配置
|
|
46
44
|
const backupResult = backupOriginalConfig();
|
|
47
45
|
if (!backupResult.success) {
|
|
48
46
|
return NextResponse.json(
|
|
@@ -51,13 +49,27 @@ export async function POST(request: NextRequest) {
|
|
|
51
49
|
);
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
// 确保目录存在
|
|
55
52
|
if (!existsSync(CLAUDE_DIR)) {
|
|
56
53
|
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
let configToWrite: any;
|
|
57
|
+
if (existsSync(SETTINGS_FILE)) {
|
|
58
|
+
try {
|
|
59
|
+
const existing = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
60
|
+
configToWrite = {
|
|
61
|
+
...existing,
|
|
62
|
+
env: { ...(existing.env || {}), ...aarEnv },
|
|
63
|
+
router_provider: 'aar',
|
|
64
|
+
};
|
|
65
|
+
} catch {
|
|
66
|
+
configToWrite = generateClaudeConfig(gatewayAddress, gatewayApiKey, modelMapping);
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
configToWrite = generateClaudeConfig(gatewayAddress, gatewayApiKey, modelMapping);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const validationResult = validateAndWriteConfig(configToWrite);
|
|
61
73
|
if (!validationResult.success) {
|
|
62
74
|
return NextResponse.json(
|
|
63
75
|
{ error: validationResult.error },
|
|
@@ -68,7 +80,7 @@ export async function POST(request: NextRequest) {
|
|
|
68
80
|
return NextResponse.json({
|
|
69
81
|
success: true,
|
|
70
82
|
message: 'Configuration applied successfully',
|
|
71
|
-
config,
|
|
83
|
+
config: configToWrite,
|
|
72
84
|
backup: backupResult.existed ? 'Created backup' : 'No existing config to backup',
|
|
73
85
|
previousWasFromAar: backupResult.existed && backupResult.isFromAar,
|
|
74
86
|
});
|
|
@@ -101,57 +113,60 @@ async function getGatewayApiKey(): Promise<string> {
|
|
|
101
113
|
return apiKeyConfig?.value || 'your-gateway-api-key';
|
|
102
114
|
}
|
|
103
115
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
/** 仅生成 AAR 相关的 env 字段,用于合并到现有配置 */
|
|
117
|
+
function buildAarEnv(
|
|
118
|
+
gatewayAddress: string,
|
|
119
|
+
gatewayApiKey: string,
|
|
120
|
+
modelMapping: { haiku: string; sonnet: string; opus: string; default: string; reasoning: string }
|
|
121
|
+
): Record<string, unknown> {
|
|
122
|
+
return {
|
|
123
|
+
ANTHROPIC_AUTH_TOKEN: gatewayApiKey,
|
|
124
|
+
ANTHROPIC_BASE_URL: gatewayAddress,
|
|
125
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: modelMapping.haiku,
|
|
126
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: modelMapping.opus,
|
|
127
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: modelMapping.sonnet,
|
|
128
|
+
ANTHROPIC_MODEL: modelMapping.default,
|
|
129
|
+
ANTHROPIC_REASONING_MODEL: modelMapping.reasoning,
|
|
130
|
+
API_TIMEOUT_MS: '3000000',
|
|
131
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
|
|
132
|
+
hasCompletedOnboarding: true,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** 生成完整 Claude 配置(仅在无现有文件时使用) */
|
|
107
137
|
function generateClaudeConfig(
|
|
108
138
|
gatewayAddress: string,
|
|
109
139
|
gatewayApiKey: string,
|
|
110
140
|
modelMapping: { haiku: string; sonnet: string; opus: string; default: string; reasoning: string }
|
|
111
141
|
): any {
|
|
112
142
|
return {
|
|
113
|
-
// 路由提供者标识,标识配置来自当前工具 aar
|
|
114
143
|
router_provider: 'aar',
|
|
115
|
-
env:
|
|
116
|
-
ANTHROPIC_AUTH_TOKEN: gatewayApiKey,
|
|
117
|
-
ANTHROPIC_BASE_URL: gatewayAddress,
|
|
118
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: modelMapping.haiku,
|
|
119
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: modelMapping.opus,
|
|
120
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: modelMapping.sonnet,
|
|
121
|
-
ANTHROPIC_MODEL: modelMapping.default,
|
|
122
|
-
ANTHROPIC_REASONING_MODEL: modelMapping.reasoning,
|
|
123
|
-
API_TIMEOUT_MS: '3000000',
|
|
124
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
|
|
125
|
-
hasCompletedOnboarding: true,
|
|
126
|
-
},
|
|
144
|
+
env: buildAarEnv(gatewayAddress, gatewayApiKey, modelMapping),
|
|
127
145
|
};
|
|
128
146
|
}
|
|
129
147
|
|
|
130
148
|
/**
|
|
131
149
|
* 备份原有配置
|
|
132
|
-
*
|
|
150
|
+
* 仅在当前配置不是 AAR 时写入备份,这样「还原」才能恢复到应用 AAR 前的状态
|
|
133
151
|
*/
|
|
134
152
|
function backupOriginalConfig(): { success: boolean; existed: boolean; isFromAar: boolean; error?: string } {
|
|
135
153
|
try {
|
|
136
|
-
// 检查原有配置是否存在
|
|
137
154
|
const existing = existsSync(SETTINGS_FILE);
|
|
138
155
|
|
|
139
156
|
if (existing) {
|
|
140
|
-
// 读取原有配置
|
|
141
157
|
const originalConfig = readFileSync(SETTINGS_FILE, 'utf-8');
|
|
142
158
|
|
|
143
|
-
// 解析配置检查 router_provider
|
|
144
159
|
let isFromAar = false;
|
|
145
160
|
try {
|
|
146
161
|
const parsedConfig = JSON.parse(originalConfig);
|
|
147
162
|
isFromAar = parsedConfig.router_provider === 'aar';
|
|
148
|
-
} catch
|
|
149
|
-
// 解析失败,不影响备份操作
|
|
163
|
+
} catch {
|
|
150
164
|
isFromAar = false;
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
|
|
154
|
-
|
|
167
|
+
if (!isFromAar) {
|
|
168
|
+
writeFileSync(BACKUP_FILE, originalConfig, 'utf-8');
|
|
169
|
+
}
|
|
155
170
|
|
|
156
171
|
return { success: true, existed: true, isFromAar };
|
|
157
172
|
}
|