@sleep2agi/agent-network-dashboard 0.6.3-preview.1 → 0.6.3-preview.10
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_COMMIT +1 -1
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -0
- package/.next/build-manifest.json +3 -3
- package/.next/cache/.previewinfo +1 -0
- package/.next/cache/.rscinfo +1 -0
- package/.next/diagnostics/route-bundle-stats.json +56 -39
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +27 -3
- package/.next/routes-manifest.json +30 -0
- package/.next/server/app/_global-error.html +1 -1
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +13 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -8
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +15 -15
- package/.next/server/app/admin.segments/_full.segment.rsc +15 -15
- package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
- package/.next/server/app/admin.segments/_index.segment.rsc +8 -8
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
- package/.next/server/app/api/anet/host-supervisors/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/host-supervisors/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/host-supervisors/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/host-supervisors/route.js +7 -0
- package/.next/server/app/api/anet/host-supervisors/route.js.map +5 -0
- package/.next/server/app/api/anet/host-supervisors/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/host-supervisors/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/probe/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/probe/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/probe/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/probe/route.js +7 -0
- package/.next/server/app/api/anet/providers/probe/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/probe/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/probe/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/probe-results/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/probe-results/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/probe-results/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js +7 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/probe-results/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/route.js +8 -0
- package/.next/server/app/api/anet/providers/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +15 -15
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +8 -8
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +15 -15
- package/.next/server/app/login.segments/_full.segment.rsc +15 -15
- package/.next/server/app/login.segments/_head.segment.rsc +4 -4
- package/.next/server/app/login.segments/_index.segment.rsc +8 -8
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/login.segments/login.segment.rsc +3 -3
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +15 -15
- package/.next/server/app/logs.segments/_full.segment.rsc +15 -15
- package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/logs.segments/_index.segment.rsc +8 -8
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +15 -15
- package/.next/server/app/messages.segments/_full.segment.rsc +15 -15
- package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
- package/.next/server/app/messages.segments/_index.segment.rsc +8 -8
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +15 -15
- package/.next/server/app/node.segments/_full.segment.rsc +15 -15
- package/.next/server/app/node.segments/_head.segment.rsc +4 -4
- package/.next/server/app/node.segments/_index.segment.rsc +8 -8
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/node.segments/node.segment.rsc +3 -3
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +15 -15
- package/.next/server/app/nodes.segments/_full.segment.rsc +15 -15
- package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/_index.segment.rsc +8 -8
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers/page/app-paths-manifest.json +3 -0
- package/.next/server/app/providers/page/build-manifest.json +17 -0
- package/.next/server/app/providers/page/next-font-manifest.json +11 -0
- package/.next/server/app/providers/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/providers/page/server-reference-manifest.json +4 -0
- package/.next/server/app/providers/page.js +14 -0
- package/.next/server/app/providers/page.js.map +5 -0
- package/.next/server/app/providers/page.js.nft.json +1 -0
- package/.next/server/app/providers/page_client-reference-manifest.js +3 -0
- package/.next/server/app/providers.html +12 -0
- package/.next/server/app/providers.meta +15 -0
- package/.next/server/app/providers.rsc +27 -0
- package/.next/server/app/providers.segments/_full.segment.rsc +27 -0
- package/.next/server/app/providers.segments/_head.segment.rsc +6 -0
- package/.next/server/app/providers.segments/_index.segment.rsc +10 -0
- package/.next/server/app/providers.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/providers.segments/providers.segment.rsc +5 -0
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +15 -15
- package/.next/server/app/server-logs.segments/_full.segment.rsc +15 -15
- package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/_index.segment.rsc +8 -8
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
- package/.next/server/app/servers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/servers.html +2 -2
- package/.next/server/app/servers.rsc +15 -15
- package/.next/server/app/servers.segments/_full.segment.rsc +15 -15
- package/.next/server/app/servers.segments/_head.segment.rsc +4 -4
- package/.next/server/app/servers.segments/_index.segment.rsc +8 -8
- package/.next/server/app/servers.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/servers.segments/servers/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/servers.segments/servers.segment.rsc +3 -3
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +15 -15
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +15 -15
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +15 -15
- package/.next/server/app/settings.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +15 -15
- package/.next/server/app/tasks.segments/_full.segment.rsc +15 -15
- package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/_index.segment.rsc +8 -8
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
- package/.next/server/app-paths-manifest.json +5 -0
- package/.next/server/chunks/00jm_next_dist_esm_build_templates_app-route_0bobkt3.js +3 -0
- package/.next/server/chunks/00jm_next_dist_esm_build_templates_app-route_0bobkt3.js.map +1 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_anet_providers_probe-results_route_actions_07.d.5a.js +3 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_anet_providers_probe-results_route_actions_07.d.5a.js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_host-supervisors_route_actions_0g3hek2.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_host-supervisors_route_actions_0g3hek2.js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_probe_route_actions_05f000..js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_probe_route_actions_05f000..js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_route_actions_10htbhd.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_route_actions_10htbhd.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0-29ynz._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0-2le8-._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__02p2n3n._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__03nze3z._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__03nze3z._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__043tnx2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__04z62zk._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__07ztet2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0aqb4n5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0aqb4n5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0cphmer._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0cphmer._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0e3ucl1._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0e6yail._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0gx2_6a._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0hg3_8r._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0lhq4ha._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mkwzz7._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mkwzz7._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mzopco._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0o45a4q._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0w1w_w0._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0w1w_w0._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0xtp-et._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0yyo7k5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0yyo7k5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0~rwgo1._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0~rwgo1._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__10pvabe._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__10t11zq._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__12r~omy._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1389~cs._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__13n8t..._.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02lorbl.js +4 -0
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02lorbl.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__04mx~5g._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__04mx~5g._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__096ytyk._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0h5dae6._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0h5dae6._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard__next-internal_server_app_providers_page_actions_0ou6p43.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard__next-internal_server_app_providers_page_actions_0ou6p43.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0gd.4pc._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0gd.4pc._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0r7kb.o._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0r7kb.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_EmptyState_tsx_0aol-el._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_EmptyState_tsx_0aol-el._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_nodes_page_tsx_11haf_p._.js +2 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_nodes_page_tsx_11haf_p._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_providers_page_tsx_0hw2n0v._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_providers_page_tsx_0hw2n0v._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_tasks_page_tsx_0mwxy4z._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +4 -0
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{10kkhdde5ve~c.js → 0-z_kfck7-6_1.js} +3 -3
- package/.next/static/chunks/049vx3qljs1tt.js +1 -0
- package/.next/static/chunks/06.5euf239uvr.css +1 -0
- package/.next/static/chunks/{0vun~4ljcrj3p.js → 091hae.lhv9t1.js} +2 -2
- package/.next/static/chunks/0chpv7zsh-qrg.js +1 -0
- package/.next/static/chunks/0i-l67o_ae5hk.js +2 -0
- package/.next/static/chunks/{0vus9xpsz0s~i.js → 0l.gu-iqnmeja.js} +1 -1
- package/.next/static/chunks/{149a4l50_3vw-.js → 0mnmn-~ava1vy.js} +1 -1
- package/.next/static/chunks/0o-b62_a66.jr.js +1 -0
- package/.next/static/chunks/0pk6amtz5icbx.js +1 -0
- package/.next/static/chunks/0r4u1.sl.8p15.js +1 -0
- package/.next/static/chunks/0wz0122ym_gr3.js +1 -0
- package/.next/static/chunks/15aqdc5txzq9r.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +7 -2
- package/.next/types/validator.ts +45 -0
- package/app/admin/page.tsx +3 -1
- package/app/api/anet/host-supervisors/route.ts +102 -0
- package/app/api/anet/node-config/route.ts +26 -2
- package/app/api/anet/node-create/route.ts +14 -5
- package/app/api/anet/node-lifecycle/route.ts +54 -5
- package/app/api/anet/providers/probe/route.ts +79 -0
- package/app/api/anet/providers/probe-results/route.ts +60 -0
- package/app/api/anet/providers/route.ts +191 -0
- package/app/api/hub/auth/route.ts +0 -12
- package/app/api/hub/networks/route.ts +1 -1
- package/app/api/hub/nodes/route.ts +0 -14
- package/app/api/hub/upload/route.ts +0 -9
- package/app/components/CommandCenter.tsx +3 -6
- package/app/components/CommandPalette.tsx +0 -5
- package/app/components/CreateNodeWizard.tsx +140 -47
- package/app/components/HostSupervisorPicker.tsx +283 -0
- package/app/components/NodeLifecycleMenu.tsx +436 -0
- package/app/components/NodeSettingsPanel.tsx +80 -39
- package/app/components/ProviderFormModal.tsx +303 -0
- package/app/components/ReachabilityMatrix.tsx +196 -0
- package/app/components/Sidebar.tsx +1 -0
- package/app/components/TaskDrawer.tsx +1 -0
- package/app/components/TopoGraph.tsx +4 -8
- package/app/components/UserBar.tsx +37 -0
- package/app/components/types.ts +11 -0
- package/app/lib/chat-unread.ts +0 -6
- package/app/lib/dashboard-auth.ts +0 -12
- package/app/lib/hooks.ts +22 -4
- package/app/lib/hub.ts +4 -0
- package/app/lib/network-context.tsx +0 -6
- package/app/lib/rate-limit.ts +2 -16
- package/app/node/page.tsx +12 -1
- package/app/nodes/page.tsx +42 -2
- package/app/page.tsx +1 -0
- package/app/providers/page.tsx +182 -0
- package/app/settings/networks/page.tsx +1 -1
- package/app/settings/page.tsx +5 -0
- package/app/tasks/[id]/page.tsx +1 -0
- package/app/tasks/page.tsx +1 -0
- package/package.json +1 -1
- package/.next/static/chunks/0-t2rbg9~-oh5.js +0 -1
- package/.next/static/chunks/0iv.0p9_5b36e.js +0 -1
- package/.next/static/chunks/0l_hz3xrjwumg.js +0 -1
- package/.next/static/chunks/0lmdw~i5qjqsg.js +0 -1
- package/.next/static/chunks/0vruzstkdr99w.js +0 -1
- package/.next/static/chunks/0xssg9sin~2xw.js +0 -1
- package/.next/static/chunks/124dtwo1k24ao.css +0 -1
- package/bun.lock +0 -1663
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_buildManifest.js +0 -0
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_ssgManifest.js +0 -0
package/.next/server/chunks/ssr/agent-network-dashboard_app_providers_page_tsx_0hw2n0v._.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../agent-network-dashboard/app/providers/page.tsx","../../../../../agent-network-dashboard/app/components/ProviderFormModal.tsx","../../../../../agent-network-dashboard/app/components/ReachabilityMatrix.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { EmptyState } from '../components/EmptyState';\nimport { ProviderFormModal, type ProviderDraft } from '../components/ProviderFormModal';\nimport { ReachabilityMatrix } from '../components/ReachabilityMatrix';\n\n/**\n * Model providers (RFC-028 P1 — CRUD). Lists providers from\n * /api/anet/providers, with create/edit (ProviderFormModal), an enabled\n * toggle, soft-delete (enabled:0), and a per-row \"Test\" placeholder for the\n * P2 connectivity matrix. Keys are write-only — the list only shows a\n * key/no-key indicator, never a value.\n *\n * When the hub predates RFC-028 (#308 not merged / hub not upgraded) the API\n * returns `unconfirmed` — we surface an honest banner instead of faking data.\n * Set MOCK_PROVIDERS=1 on the dashboard server to preview the populated UI.\n */\n\ninterface Provider {\n provider_id?: string;\n name: string;\n type: string;\n base_url: string;\n models?: string[];\n enabled?: boolean;\n hasKey?: boolean;\n}\n\nfunction hostOf(url: string) {\n try { return new URL(url).host; } catch { return url; }\n}\n\n// Humanize the raw vendor enum for the row badge so it matches the create\n// modal's wording. A DeepSeek/MiniMax row tagged bare \"anthropic\" reads as\n// wrong — they're Anthropic-*compatible* endpoints, not Anthropic itself.\nconst TYPE_LABELS: Record<string, string> = {\n anthropic: 'Anthropic 兼容',\n 'openai-compatible': 'OpenAI 兼容',\n grok: 'Grok',\n custom: 'Custom',\n};\nconst typeLabel = (t: string) => TYPE_LABELS[t] || t;\n\nexport default function ProvidersPage() {\n const [providers, setProviders] = useState<Provider[]>([]);\n const [loading, setLoading] = useState(true);\n const [unconfirmed, setUnconfirmed] = useState<string | null>(null);\n const [mock, setMock] = useState(false);\n const [editing, setEditing] = useState<ProviderDraft | null>(null);\n const [showForm, setShowForm] = useState(false);\n const [expandedId, setExpandedId] = useState<string | null>(null);\n\n const fetchProviders = useCallback(async () => {\n try {\n const res = await fetch('/api/anet/providers', { cache: 'no-store' });\n const data = await res.json().catch(() => ({}));\n setProviders(Array.isArray(data?.providers) ? data.providers : []);\n setUnconfirmed(data?.unconfirmed ? (data?.error || 'backend not available') : null);\n setMock(!!data?.mock);\n } catch { setUnconfirmed('request failed'); } finally { setLoading(false); }\n }, []);\n\n useEffect(() => { fetchProviders(); }, [fetchProviders]);\n\n const openCreate = () => { setEditing(null); setShowForm(true); };\n // Edit / enable-disable wired to update_provider (#317). vendor + key are\n // immutable on the backend, so the edit form patches name/base_url/models\n // only (changing the key is a separate secret-first flow).\n const openEdit = (p: Provider) => {\n setEditing({ provider_id: p.provider_id, name: p.name, type: p.type, base_url: p.base_url, models: p.models || [], enabled: p.enabled ?? true, hasKey: p.hasKey });\n setShowForm(true);\n };\n const toggleEnabled = async (p: Provider) => {\n setProviders(prev => prev.map(x => (x.provider_id || x.name) === (p.provider_id || p.name) ? { ...x, enabled: !x.enabled } : x)); // optimistic\n await fetch('/api/anet/providers', {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ provider_id: p.provider_id, enabled: !p.enabled }),\n }).catch(() => {});\n fetchProviders();\n };\n\n return (\n <div className=\"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6\">\n <div className=\"flex items-center gap-4 mb-6\">\n <h1 className=\"text-2xl font-bold text-white lg:ml-0 ml-10\">Model Providers</h1>\n {mock && <span className=\"text-[10px] px-2 py-0.5 rounded-full border border-amber-500/30 bg-amber-500/5 text-amber-300\">preview fixture</span>}\n <button\n onClick={openCreate}\n className=\"ml-auto inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md bg-cyan-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-cyan-500\"\n >\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" aria-hidden><path d=\"M12 5v14M5 12h14\" /></svg>\n 新增供应商\n </button>\n </div>\n\n <div className=\"max-w-3xl space-y-4\">\n <p className=\"text-sm text-gray-500\">\n Configure model providers and per-server reachability. API keys are stored write-only in the secret vault and never displayed.\n </p>\n\n {unconfirmed && (\n <div className=\"rounded-xl border border-amber-500/30 bg-amber-500/5 px-4 py-3 text-xs text-amber-300\">\n 供应商后端(RFC-028)尚未在当前 hub 就绪:{unconfirmed}。UI 已就位;待 #308 合并 + hub 升级后接真后端。\n <span className=\"text-amber-400/70\">(开发预览可设 MOCK_PROVIDERS=1 看填充态。)</span>\n </div>\n )}\n\n <section className=\"bg-[#161618] border border-[#26262b] rounded-xl p-5\">\n {loading ? (\n <div className=\"animate-pulse space-y-2\">{[1, 2, 3].map(i => <div key={i} className=\"h-14 bg-gray-800/20 rounded\" />)}</div>\n ) : providers.length === 0 ? (\n <EmptyState\n variant=\"generic\"\n title=\"No model providers\"\n sub=\"Add a provider to register its models and test per-server reachability.\"\n cta={{ label: '新增供应商', onClick: openCreate }}\n />\n ) : (\n <div className=\"space-y-2\">\n {providers.map(p => {\n const rid = p.provider_id || p.name;\n const isOpen = expandedId === rid;\n return (\n <div key={rid} className={`rounded-lg border border-[#1c1c1f] bg-[#0e0e10] ${p.enabled ? '' : 'opacity-60'}`} data-provider={p.name}>\n <div className=\"flex flex-col gap-2 px-3 py-2.5 sm:flex-row sm:items-center sm:gap-3\">\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <span className={`inline-block h-2 w-2 shrink-0 rounded-full ${p.enabled ? 'bg-green-500' : 'bg-gray-600'}`} title={p.enabled ? 'enabled' : 'disabled'} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1\">\n <span className=\"text-sm font-semibold text-white truncate\">{p.name}</span>\n <span className=\"text-[10px] px-1.5 py-0.5 rounded border border-gray-600/30 text-gray-400 shrink-0\" title={p.type}>{typeLabel(p.type)}</span>\n {p.hasKey\n ? <span className=\"text-[10px] px-1.5 py-0.5 rounded border border-green-500/20 bg-green-500/5 text-green-400 shrink-0\">key set</span>\n : <span className=\"text-[10px] px-1.5 py-0.5 rounded border border-gray-600/20 text-gray-500 shrink-0\">no key</span>}\n </div>\n <div className=\"text-[11px] text-gray-500 truncate\">\n {hostOf(p.base_url)} · {(p.models?.length || 0)} model{(p.models?.length || 0) === 1 ? '' : 's'}\n </div>\n </div>\n </div>\n <div className=\"flex w-full shrink-0 items-center justify-end gap-1.5 border-t border-[#1c1c1f] pt-2 sm:w-auto sm:justify-normal sm:self-auto sm:border-t-0 sm:pt-0\">\n <button\n type=\"button\"\n onClick={() => setExpandedId(isOpen ? null : rid)}\n disabled={!p.enabled}\n title={p.enabled ? '连通性测试(模型 × 服务器 可达矩阵)' : '供应商已停用,启用后可测连通性'}\n className={`rounded border px-2 py-1 text-[11px] transition-colors ${!p.enabled ? 'border-[#26262b] text-gray-600 cursor-not-allowed' : isOpen ? 'border-cyan-500/40 bg-cyan-500/10 text-cyan-300' : 'border-[#26262b] text-gray-300 hover:border-cyan-500/30 hover:text-cyan-300'}`}\n >Test{isOpen ? ' ▾' : ''}</button>\n <button type=\"button\" onClick={() => openEdit(p)} title=\"编辑(名称 / base_url / 模型)\" className=\"rounded border border-[#26262b] px-2 py-1 text-[11px] text-gray-300 hover:border-cyan-500/30 hover:text-cyan-300\">Edit</button>\n <button type=\"button\" onClick={() => toggleEnabled(p)} title={p.enabled ? '停用(软删,可重新启用)' : '启用'} className=\"rounded border border-[#26262b] px-2 py-1 text-[11px] text-gray-400 hover:text-gray-200\">\n {p.enabled ? 'Disable' : 'Enable'}\n </button>\n </div>\n </div>\n {isOpen && (\n (p.models?.length || 0) > 0\n ? <ReachabilityMatrix providerId={p.provider_id} models={p.models || []} />\n : <div className=\"border-t border-[#1c1c1f] px-3 py-3 text-[11px] text-gray-500\">该供应商未配置模型——先 Edit 添加模型再测可达性。</div>\n )}\n </div>\n );\n })}\n </div>\n )}\n </section>\n\n <p className=\"text-[11px] text-gray-600\">\n 按 <span className=\"text-gray-400\">Test</span> 展开「模型 × 服务器」连通性矩阵(对每个模型实时探测可达性)。创建节点向导的模型下拉将从此处的 registry 拉取(即将支持)。\n </p>\n </div>\n\n {showForm && (\n <ProviderFormModal\n initial={editing}\n onClose={() => setShowForm(false)}\n onSaved={fetchProviders}\n />\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\n\n/**\n * Create/edit a model provider (RFC-028 P1 + #393 preset catalog). Single-step\n * modal mirroring the CreateNodeWizard shell (escape-to-close, SVG ✕, cyan\n * primary). The API key field is WRITE-ONLY: on edit of a provider that already\n * has a key it shows a \"•••• configured\" placeholder and an empty value means\n * \"keep existing key\"; the stored value is never fetched or displayed.\n *\n * #393 (Vincent UX): official providers (DeepSeek / MiniMax / GLM / Claude) are\n * offered as PRESETS — picking one auto-fills the Anthropic-compatible base_url\n * and turns the model field into a checkbox list of that provider's known\n * models, so the operator only supplies an API key. \"自定义\" falls back to the\n * manual base_url + comma-separated model entry for any other endpoint.\n */\n\nexport interface ProviderDraft {\n provider_id?: string;\n name: string;\n type: string;\n base_url: string;\n models: string[];\n enabled: boolean;\n hasKey?: boolean;\n}\n\n// Backend (#308) currently supports only the `anthropic` vendor — which means\n// any Anthropic-COMPATIBLE endpoint (Claude api.anthropic.com, DeepSeek\n// api.deepseek.com/anthropic, MiniMax api.minimax.chat/anthropic, …) via a\n// custom base_url, not just Anthropic the company. Native OpenAI/Grok vendors\n// aren't wired yet → shown disabled so users can't pick an erroring option.\nconst TYPES: { id: string; label: string; disabled?: boolean }[] = [\n { id: 'anthropic', label: 'Anthropic 兼容端点(Claude / DeepSeek / MiniMax 等)' },\n { id: 'openai-compatible', label: 'OpenAI-compatible(native,即将支持)', disabled: true },\n { id: 'grok', label: 'Grok(native,即将支持)', disabled: true },\n];\n\n// #393 preset catalog. Each base_url is an Anthropic-compatible endpoint\n// (verified 401-reachable). `models` are sensible defaults the operator can\n// tick on/off; extras can still be typed. Keep `custom` last as the escape\n// hatch to the manual URL/model flow.\ninterface ProviderPreset {\n id: string;\n label: string;\n type: string;\n base_url: string;\n models: string[];\n keyPlaceholder?: string;\n}\nconst PRESETS: ProviderPreset[] = [\n { id: 'deepseek', label: 'DeepSeek', type: 'anthropic', base_url: 'https://api.deepseek.com/anthropic', models: ['deepseek-v4-pro', 'deepseek-v4-flash'], keyPlaceholder: 'sk-…' },\n { id: 'minimax', label: 'MiniMax', type: 'anthropic', base_url: 'https://api.minimaxi.com/anthropic', models: ['MiniMax-M2.7'], keyPlaceholder: 'MiniMax API key' },\n { id: 'glm', label: '智谱 GLM', type: 'anthropic', base_url: 'https://open.bigmodel.cn/api/anthropic', models: ['glm-4.7', 'glm-5.2', 'glm-4.6'], keyPlaceholder: '{id}.{secret}' },\n { id: 'claude', label: 'Claude(Anthropic 官方)', type: 'anthropic', base_url: 'https://api.anthropic.com', models: ['claude-opus-4-8', 'claude-sonnet-5', 'claude-haiku-4-5'], keyPlaceholder: 'sk-ant-…' },\n { id: 'custom', label: '自定义(手动填 URL / 模型)', type: 'anthropic', base_url: '', models: [] },\n];\n\nfunction detectPreset(baseUrl?: string): string {\n if (!baseUrl) return 'custom';\n const hit = PRESETS.find(p => p.id !== 'custom' && p.base_url === baseUrl.trim());\n return hit ? hit.id : 'custom';\n}\n\ntype Phase = 'form' | 'saving' | 'done' | 'unconfirmed' | 'error';\n\nconst inputCls =\n 'w-full rounded-md border border-[#26262b] bg-[#0e0e10] px-3 py-2 text-sm text-gray-200 focus:border-cyan-600 focus:outline-none';\n\nfunction parseModels(text: string): string[] {\n return text.split(',').map(m => m.trim()).filter(Boolean);\n}\n\nexport function ProviderFormModal({\n initial,\n onClose,\n onSaved,\n}: {\n initial?: ProviderDraft | null;\n onClose: () => void;\n onSaved?: () => void;\n}) {\n const editing = !!initial?.provider_id;\n const [presetId, setPresetId] = useState(() => detectPreset(initial?.base_url));\n const [name, setName] = useState(initial?.name ?? '');\n const [type, setType] = useState(initial?.type ?? TYPES[0].id);\n const [baseUrl, setBaseUrl] = useState(initial?.base_url ?? '');\n // Checked preset models (only used while a non-custom preset is selected).\n const [checkedModels, setCheckedModels] = useState<string[]>(initial?.models ?? []);\n // Free-text models — for `custom` it's the whole list, for a preset it's extras.\n const [modelsText, setModelsText] = useState(() => {\n const p = detectPreset(initial?.base_url);\n if (p === 'custom') return (initial?.models ?? []).join(', ');\n // extras = initial models not in the preset's default list\n const preset = PRESETS.find(x => x.id === p);\n const extras = (initial?.models ?? []).filter(m => !preset?.models.includes(m));\n return extras.join(', ');\n });\n const [apiKey, setApiKey] = useState('');\n const [enabled, setEnabled] = useState(initial?.enabled ?? true);\n const [phase, setPhase] = useState<Phase>('form');\n const [msg, setMsg] = useState('');\n\n const preset = useMemo(() => PRESETS.find(p => p.id === presetId) ?? PRESETS[PRESETS.length - 1], [presetId]);\n const isCustom = presetId === 'custom';\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape' && phase !== 'saving') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose, phase]);\n\n function selectPreset(id: string) {\n setPresetId(id);\n const p = PRESETS.find(x => x.id === id);\n if (!p) return;\n if (id !== 'custom') {\n setType(p.type);\n setBaseUrl(p.base_url);\n // default-check all preset models; keep any prior extras in the text box\n setCheckedModels(p.models);\n if (!name.trim() || PRESETS.some(x => x.label === name.trim())) setName(p.label);\n } else {\n setBaseUrl('');\n setCheckedModels([]);\n }\n }\n\n function toggleModel(m: string) {\n setCheckedModels(prev => (prev.includes(m) ? prev.filter(x => x !== m) : [...prev, m]));\n }\n\n const finalModels = useMemo(() => {\n const extras = parseModels(modelsText);\n if (isCustom) return extras;\n return Array.from(new Set([...checkedModels, ...extras]));\n }, [isCustom, checkedModels, modelsText]);\n\n const nameValid = name.trim().length > 0;\n const urlValid = baseUrl.trim().length > 0;\n // Secret-first (RFC-028): a provider can't be created without a vault key,\n // so the API key is required on CREATE. On edit the key + vendor are\n // immutable (update_provider patches name/base_url/models only).\n const keyValid = editing || apiKey.trim().length > 0;\n const modelsValid = finalModels.length > 0;\n const canSave = nameValid && urlValid && keyValid && modelsValid && phase !== 'saving';\n\n async function handleSave() {\n setPhase('saving'); setMsg('');\n const payload = {\n ...(initial?.provider_id ? { provider_id: initial.provider_id } : {}),\n name: name.trim(), type, base_url: baseUrl.trim(), models: finalModels, enabled,\n ...(apiKey ? { apiKey } : {}),\n };\n try {\n const r = await fetch('/api/anet/providers', {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n const data = await r.json().catch(() => ({}));\n if (r.ok && data?.ok) {\n setPhase('done'); onSaved?.();\n // close shortly after success so the list refresh is visible\n setTimeout(onClose, 350);\n } else if (data?.unconfirmed) {\n setPhase('unconfirmed');\n setMsg(`后端 RFC-028 未就绪:${data?.error || '不可用'}(hub 需 #308 + 升级)`);\n } else {\n setPhase('error');\n setMsg(data?.error ? `保存失败:${data.error}` : '保存失败');\n }\n } catch (e) {\n setPhase('error');\n setMsg(`保存失败:${e instanceof Error ? e.message : '网络错误'}`);\n }\n }\n\n return (\n <>\n <div className=\"fixed inset-0 bg-black/50 z-40\" onClick={() => phase !== 'saving' && onClose()} aria-hidden />\n <div\n role=\"dialog\"\n aria-label={editing ? '编辑供应商' : '新增供应商'}\n className=\"fixed left-1/2 top-1/2 z-50 max-h-[92vh] w-[min(94vw,480px)] -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-xl border border-[#26262b] bg-[#161618] shadow-2xl\"\n >\n <div className=\"sticky top-0 flex items-center justify-between border-b border-[#26262b] bg-[#161618] px-4 py-3\">\n <div className=\"text-sm font-semibold text-white\">{editing ? '编辑供应商' : '新增供应商'}</div>\n <button onClick={onClose} aria-label=\"关闭\" className=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-gray-500 hover:bg-white/5 hover:text-white\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div className=\"space-y-3 px-4 py-4\">\n {phase === 'unconfirmed' || phase === 'error' ? (\n <div className={`rounded-md border px-3 py-2 text-xs ${phase === 'unconfirmed' ? 'border-amber-500/30 bg-amber-500/5 text-amber-300' : 'border-red-500/30 bg-red-500/5 text-red-300'}`}>\n {msg}\n </div>\n ) : null}\n\n {/* #393 preset provider picker (hidden while editing — base_url/vendor are immutable) */}\n {!editing && (\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">供应商 <span className=\"text-red-400/70\">*</span></span>\n <select value={presetId} onChange={e => selectPreset(e.target.value)} className={inputCls}>\n {PRESETS.map(p => <option key={p.id} value={p.id}>{p.label}</option>)}\n </select>\n {!isCustom && <span className=\"text-[11px] text-gray-600\">已选官方供应商:Base URL 自动填好,勾选模型 + 填 API Key 即可。</span>}\n </label>\n )}\n\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">名称 <span className=\"text-red-400/70\">*</span></span>\n <input autoFocus value={name} onChange={e => setName(e.target.value)} placeholder=\"例如 DeepSeek-V4-Pro\" className={inputCls} />\n </label>\n\n {/* 类型 only surfaces in custom / edit — presets imply anthropic. */}\n {(isCustom || editing) && (\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">类型{editing ? '(不可修改)' : ''}</span>\n <select value={type} onChange={e => setType(e.target.value)} disabled={editing} className={`${inputCls} ${editing ? 'opacity-60 cursor-not-allowed' : ''}`}>\n {TYPES.map(t => <option key={t.id} value={t.id} disabled={t.disabled}>{t.label}</option>)}\n </select>\n </label>\n )}\n\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">Base URL <span className=\"text-red-400/70\">*</span>{!isCustom && !editing && <span className=\"text-gray-600\">(已自动填充)</span>}</span>\n <input\n value={baseUrl}\n onChange={e => setBaseUrl(e.target.value)}\n placeholder=\"https://api.anthropic.com\"\n disabled={!isCustom && !editing}\n className={`${inputCls} ${(!isCustom && !editing) ? 'opacity-60 cursor-not-allowed' : ''}`}\n />\n {isCustom && !editing && <span className=\"text-[11px] text-gray-600\">Anthropic 兼容端点:Claude <span className=\"font-mono\">api.anthropic.com</span> · DeepSeek <span className=\"font-mono\">api.deepseek.com/anthropic</span> · MiniMax <span className=\"font-mono\">api.minimax.chat/anthropic</span>。</span>}\n </label>\n\n {/* Models: preset → checkbox list + extras; custom → comma text. */}\n {!isCustom && !editing ? (\n <div className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">模型 <span className=\"text-red-400/70\">*</span><span className=\"text-gray-600\">(勾选,可多选)</span></span>\n <div className=\"flex flex-wrap gap-2\">\n {preset.models.map(m => {\n const on = checkedModels.includes(m);\n return (\n <button\n type=\"button\"\n key={m}\n onClick={() => toggleModel(m)}\n className={`rounded-md border px-2.5 py-1 text-xs font-mono transition-colors ${on ? 'border-cyan-600 bg-cyan-600/15 text-cyan-300' : 'border-[#26262b] bg-[#0e0e10] text-gray-400 hover:border-gray-600'}`}\n >\n {on ? '✓ ' : ''}{m}\n </button>\n );\n })}\n </div>\n <input value={modelsText} onChange={e => setModelsText(e.target.value)} placeholder=\"其他模型(逗号分隔,可留空)\" className={`${inputCls} mt-1`} />\n </div>\n ) : (\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">模型(逗号分隔){editing ? '' : <span className=\"text-red-400/70\"> *</span>}</span>\n <input value={modelsText} onChange={e => setModelsText(e.target.value)} placeholder=\"claude-sonnet-4-6, deepseek-chat\" className={inputCls} />\n </label>\n )}\n\n <label className=\"block space-y-1\">\n <span className=\"text-xs text-gray-400\">API Key {editing ? <span className=\"text-gray-600\">(不可在此修改)</span> : <span className=\"text-red-400/70\">*</span>}</span>\n <input\n type=\"password\"\n value={apiKey}\n onChange={e => setApiKey(e.target.value)}\n placeholder={editing ? '•••• configured(密钥库已存)' : (preset.keyPlaceholder ?? 'sk-…')}\n className={`${inputCls} ${editing ? 'opacity-60 cursor-not-allowed' : ''}`}\n autoComplete=\"off\"\n disabled={editing}\n />\n <span className=\"text-[11px] text-gray-600\">{editing ? '密钥不可在此改;如需轮换 key 走单独的密钥库流程。' : '写入即存入密钥库,UI 不回显 key 值。'}</span>\n </label>\n\n <label className=\"flex items-center gap-2 pt-1\">\n <input type=\"checkbox\" checked={enabled} onChange={e => setEnabled(e.target.checked)} className=\"accent-cyan-500\" />\n <span className=\"text-xs text-gray-300\">启用</span>\n </label>\n </div>\n\n <div className=\"sticky bottom-0 flex items-center justify-end gap-2 border-t border-[#26262b] bg-[#161618] px-4 py-3\">\n <button type=\"button\" onClick={onClose} className=\"rounded-md px-3 py-1.5 text-sm text-gray-400 hover:text-gray-200\">取消</button>\n <button\n type=\"button\"\n disabled={!canSave}\n onClick={handleSave}\n className={`rounded-md px-4 py-1.5 text-sm font-medium ${canSave ? 'bg-cyan-600 text-white hover:bg-cyan-500' : 'bg-[#1c1c1f] text-gray-600 cursor-not-allowed'}`}\n >\n {phase === 'saving' ? '保存中…' : phase === 'done' ? '✓ 已保存' : editing ? '保存' : '新增'}\n </button>\n </div>\n </div>\n </>\n );\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n/**\n * Model × server reachability matrix (RFC-028 P2, aligned to real #308 schema).\n * probe_provider_model is ASYNC: we DISPATCH a probe per (model × server) with\n * bounded concurrency (~6), then POLL get_probe_results until every cell\n * resolves (or times out). Cells: ok (green ✓ + latency) · auth_fail (amber) ·\n * unreachable (red ✕) · incompatible (gray —) · pending (spinner).\n * Rendered as a real <table> for screen-reader columns.\n */\n\ninterface Server { daemon_node_id: string; hostname: string }\ntype CellStatus = 'pending' | 'ok' | 'auth_fail' | 'unreachable' | 'incompatible' | 'error';\ninterface Cell { status: CellStatus; latency_ms?: number; reason?: string }\n\n// `tag` is the short inline label shown in the cell (visible without hover, so\n// a screenshot/glance reads cleanly); `label` is the longer a11y/tooltip term.\nconst CELL_UI: Record<Exclude<CellStatus, 'pending'>, { glyph: string; cls: string; label: string; tag: string }> = {\n ok: { glyph: '✓', cls: 'text-green-400 border-green-500/30 bg-green-500/5', label: 'ok', tag: 'ok' },\n auth_fail: { glyph: '⚷', cls: 'text-amber-400 border-amber-500/30 bg-amber-500/5', label: 'auth', tag: '401' },\n unreachable: { glyph: '✕', cls: 'text-red-400 border-red-500/30 bg-red-500/5', label: 'unreachable', tag: 'down' },\n incompatible: { glyph: '—', cls: 'text-gray-500 border-gray-600/20', label: 'incompatible', tag: 'n/a' },\n error: { glyph: '!', cls: 'text-red-400 border-red-500/30 bg-red-500/5', label: 'error', tag: 'err' },\n};\n\n// Legend entries shown under the matrix so cell glyphs are self-explanatory.\nconst LEGEND: Array<Exclude<CellStatus, 'pending'>> = ['ok', 'auth_fail', 'unreachable', 'incompatible'];\n\nconst CONCURRENCY = 6;\nconst POLL_MS = 1500;\nconst POLL_TIMEOUT_MS = 24000;\n\nasync function pool<T>(items: T[], worker: (t: T) => Promise<void>) {\n let i = 0;\n await Promise.all(Array.from({ length: Math.min(CONCURRENCY, items.length) }, async () => {\n while (i < items.length) { const idx = i++; await worker(items[idx]); }\n }));\n}\n\nconst norm = (s: string): CellStatus => {\n if (s === 'ok' || s === 'auth_fail' || s === 'unreachable' || s === 'incompatible' || s === 'pending') return s;\n if (s === 'timeout' || s === 'dns_fail' || s === 'conn_fail') return 'unreachable';\n return 'error';\n};\n\nexport function ReachabilityMatrix({ providerId, models }: { providerId?: string; models: string[] }) {\n const [servers, setServers] = useState<Server[]>([]);\n const [cells, setCells] = useState<Record<string, Cell>>({});\n const [loading, setLoading] = useState(true);\n const [running, setRunning] = useState(false);\n const [unconfirmed, setUnconfirmed] = useState<string | null>(null);\n const aliveRef = useRef(true);\n useEffect(() => () => { aliveRef.current = false; }, []);\n\n const key = (m: string, s: string) => `${m}@@${s}`;\n\n const run = useCallback(async (srv: Server[]) => {\n if (!models.length || !srv.length || !providerId) return;\n setRunning(true); setUnconfirmed(null);\n const pairs = models.flatMap(m => srv.map(s => ({ m, s })));\n setCells(Object.fromEntries(pairs.map(({ m, s }) => [key(m, s.daemon_node_id), { status: 'pending' as CellStatus }])));\n\n // 1) dispatch all probes (async — backend mints pending rows + doorbells daemons)\n await pool(pairs, async ({ m, s }) => {\n try {\n const r = await fetch('/api/anet/providers/probe', {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ provider_id: providerId, model_name: m, daemon_node_id: s.daemon_node_id }),\n });\n const d = await r.json().catch(() => ({}));\n if (d?.unconfirmed && aliveRef.current) setUnconfirmed(d?.error || 'backend not available');\n } catch { /* dispatch best-effort; poll surfaces the outcome */ }\n });\n\n // 2) poll get_probe_results until every cell resolves or we time out\n const deadline = Date.now() + POLL_TIMEOUT_MS;\n const want = new Set(pairs.map(({ m, s }) => key(m, s.daemon_node_id)));\n while (aliveRef.current && Date.now() < deadline) {\n await new Promise(res => setTimeout(res, POLL_MS));\n if (!aliveRef.current) break;\n try {\n const r = await fetch(`/api/anet/providers/probe-results?provider_id=${encodeURIComponent(providerId)}`, { cache: 'no-store' });\n const d = await r.json().catch(() => ({}));\n if (d?.unconfirmed) { if (aliveRef.current) setUnconfirmed(d?.error || 'backend not available'); break; }\n const rows = Array.isArray(d?.results) ? d.results : [];\n // latest row per (model,daemon)\n const latest = new Map<string, { status: string; latency_ms?: number; error_label?: string; probed_at?: number }>();\n for (const row of rows) {\n const k = key(String(row.model_name), String(row.daemon_node_id));\n if (!want.has(k)) continue;\n const prev = latest.get(k);\n if (!prev || (row.probed_at || 0) >= (prev.probed_at || 0)) latest.set(k, row);\n }\n if (aliveRef.current) {\n setCells(prev => {\n const next = { ...prev };\n for (const [k, row] of latest) next[k] = { status: norm(String(row.status)), latency_ms: row.latency_ms, reason: row.error_label };\n return next;\n });\n }\n // done when no cell is still pending\n const allResolved = [...want].every(k => latest.get(k) && latest.get(k)!.status !== 'pending');\n if (allResolved) break;\n } catch { /* transient — keep polling */ }\n }\n if (aliveRef.current) setRunning(false);\n }, [models, providerId]);\n\n useEffect(() => {\n let alive = true;\n (async () => {\n try {\n const r = await fetch('/api/anet/providers/probe', { cache: 'no-store' });\n const d = await r.json().catch(() => ({}));\n const srv: Server[] = Array.isArray(d?.servers) ? d.servers : [];\n if (!alive) return;\n setServers(srv); setLoading(false);\n if (srv.length) run(srv);\n } catch { if (alive) setLoading(false); }\n })();\n return () => { alive = false; };\n }, [run]);\n\n const total = models.length * servers.length;\n const okCount = Object.values(cells).filter(c => c.status === 'ok').length;\n\n if (loading) return <div className=\"px-3 py-3 text-[11px] text-gray-500\">解析服务器集合…</div>;\n if (unconfirmed) {\n return <div className=\"mx-3 my-2 rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-[11px] text-amber-300\">\n 连通性 probe 后端尚未就绪:{unconfirmed}。矩阵 UI 已就位,待 hub 升级到含 RFC-028 接真 probe。\n </div>;\n }\n if (!servers.length) return <div className=\"px-3 py-3 text-[11px] text-gray-500\">未发现可达的 host_supervisor 服务器(probe 目标集为空)。</div>;\n\n return (\n <div className=\"border-t border-[#1c1c1f] px-3 py-3\" data-reachability-matrix>\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-[11px] text-gray-400\">\n 可达矩阵 · <span className=\"tabular-nums text-gray-300\">{okCount}/{total}</span> reachable\n {running && <span className=\"ml-2 text-gray-600\">probing…</span>}\n </span>\n <button type=\"button\" onClick={() => run(servers)} disabled={running}\n className=\"rounded border border-[#26262b] px-2 py-0.5 text-[11px] text-gray-400 hover:text-gray-200 disabled:opacity-50\">重新测试</button>\n </div>\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse text-[11px]\">\n <thead>\n <tr>\n <th className=\"px-2 py-1 text-left font-medium text-gray-500\">model \\\\ server</th>\n {servers.map(s => <th key={s.daemon_node_id} className=\"px-2 py-1 text-center font-mono font-normal text-gray-400\" title={s.daemon_node_id}>{s.hostname}</th>)}\n </tr>\n </thead>\n <tbody>\n {models.map(m => (\n <tr key={m}>\n <td className=\"px-2 py-1 font-mono text-gray-300 whitespace-nowrap\">{m}</td>\n {servers.map(s => {\n const c = cells[key(m, s.daemon_node_id)];\n if (!c || c.status === 'pending') return <td key={s.daemon_node_id} className=\"px-2 py-1 text-center\">\n <span className=\"inline-block h-3 w-3 animate-spin rounded-full border border-gray-600 border-t-transparent\" aria-label=\"probing\" />\n </td>;\n const ui = CELL_UI[c.status as Exclude<CellStatus, 'pending'>] || CELL_UI.error;\n return (\n <td key={s.daemon_node_id} className=\"px-2 py-1 text-center\">\n <span className={`inline-flex min-w-[2.75rem] items-center justify-center gap-1 rounded border px-1.5 py-0.5 ${ui.cls}`}\n title={c.reason ? `${ui.label}: ${c.reason}` : ui.label} data-cell-status={c.status}>\n <span aria-hidden>{ui.glyph}</span>\n {c.status === 'ok'\n ? (c.latency_ms != null && <span className=\"tabular-nums text-[10px] opacity-80\">{c.latency_ms}ms</span>)\n : <span className=\"text-[10px] opacity-80\">{ui.tag}</span>}\n </span>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-gray-500\">\n {LEGEND.map(s => {\n const ui = CELL_UI[s];\n return (\n <span key={s} className=\"inline-flex items-center gap-1\">\n <span className={`inline-flex h-3.5 w-3.5 items-center justify-center rounded border ${ui.cls}`} aria-hidden>{ui.glyph}</span>\n {ui.label}\n </span>\n );\n })}\n <span className=\"text-gray-600\">· 实时探测(模型→服务器真实请求往返)</span>\n </div>\n </div>\n );\n}\n"],"names":["TYPES","id","label","disabled","PRESETS","type","base_url","models","keyPlaceholder","detectPreset","baseUrl","hit","find","p","trim","inputCls","parseModels","text","split","map","m","filter","Boolean","ProviderFormModal","initial","onClose","onSaved","editing","provider_id","presetId","setPresetId","name","setName","setType","setBaseUrl","checkedModels","setCheckedModels","modelsText","setModelsText","join","preset","x","extras","includes","apiKey","setApiKey","enabled","setEnabled","phase","setPhase","msg","setMsg","length","isCustom","onKey","e","key","window","addEventListener","removeEventListener","selectPreset","some","toggleModel","prev","finalModels","Array","from","Set","nameValid","urlValid","keyValid","modelsValid","canSave","handleSave","payload","r","fetch","method","headers","body","JSON","stringify","data","json","catch","ok","setTimeout","unconfirmed","error","Error","message","className","onClick","role","width","height","viewBox","fill","stroke","strokeWidth","strokeLinecap","d","value","onChange","target","autoFocus","placeholder","t","on","autoComplete","checked"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../agent-network-dashboard/app/tasks/page.tsx","../../../../../agent-network-dashboard/app/components/TaskDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState, useCallback, Suspense } from 'react';\nimport { useSearchParams } from 'next/navigation';\nimport { useNetworkId } from '../lib/network-context';\nimport { TaskDrawer } from '../components/TaskDrawer';\nimport { EmptyState } from '../components/EmptyState';\nimport { AliasAvatar } from '../components/AliasAvatar';\nimport { previewContent } from '../components/utils';\nimport { TASK_STATUSES, STATUS_CHIP_CLASS, STATUS_DOT_HEX, STATUS_BAR_CLASS } from '../lib/status';\n\ninterface Task {\n task_id: string;\n from_name: string;\n to_name: string;\n status: string;\n priority: string;\n content: string;\n result: string;\n created_at: string;\n updated_at: string;\n delivered_at: string;\n started_at: string;\n completed_at: string;\n expires_at: string;\n}\n\nfunction statusBadge(status: string) {\n const color = STATUS_CHIP_CLASS[status] || 'bg-gray-500/10 text-gray-400 border-gray-500/20';\n return `text-xs px-2 py-0.5 rounded-md border ${color}`;\n}\n\nfunction priorityBadge(priority: string) {\n if (priority === 'high') return 'text-red-400';\n if (priority === 'low') return 'text-gray-600';\n return 'text-gray-400';\n}\n\nfunction timeAgo(dateStr: string): string {\n if (!dateStr) return '--';\n const diff = Date.now() - new Date(dateStr.replace(' ', 'T') + 'Z').getTime();\n const s = Math.floor(diff / 1000);\n if (s < 60) return `${s}s ago`;\n if (s < 3600) return `${Math.floor(s / 60)}m ago`;\n if (s < 86400) return `${Math.floor(s / 3600)}h ago`;\n return `${Math.floor(s / 86400)}d ago`;\n}\n\nfunction TasksContent() {\n const searchParams = useSearchParams();\n const { networkId } = useNetworkId();\n const [tasks, setTasks] = useState<Task[]>([]);\n const [count, setCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n\n const [filterStatus, setFilterStatus] = useState(searchParams.get('status') || '');\n const [filterFrom, setFilterFrom] = useState('');\n const [filterTo, setFilterTo] = useState('');\n const [drawerTaskId, setDrawerTaskId] = useState<string | null>(null);\n\n const toggleExpand = (taskId: string) => {\n setExpanded(prev => {\n const next = new Set(prev);\n if (next.has(taskId)) next.delete(taskId);\n else next.add(taskId);\n return next;\n });\n };\n\n const fetchTasks = useCallback(async () => {\n try {\n const params = new URLSearchParams();\n if (networkId) params.set('network_id', networkId);\n if (filterStatus) params.set('status', filterStatus);\n if (filterFrom) params.set('from_name', filterFrom);\n if (filterTo) params.set('to_name', filterTo);\n params.set('limit', '100');\n\n const res = await fetch(`/api/hub/tasks?${params.toString()}`);\n if (res.status === 401) {\n window.location.assign('/login');\n return;\n }\n const data = await res.json();\n setTasks(data.tasks || []);\n setCount(data.count ?? (data.tasks?.length || 0));\n setError('');\n } catch (e: unknown) {\n setError(e instanceof Error ? e.message : 'fetch failed');\n } finally {\n setLoading(false);\n }\n }, [filterStatus, filterFrom, filterTo, networkId]);\n\n useEffect(() => {\n setLoading(true);\n fetchTasks();\n const interval = setInterval(fetchTasks, 5000);\n return () => clearInterval(interval);\n }, [fetchTasks]);\n\n return (\n <div className=\"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6\">\n {/* Header.\n #209 R30 (mobile vertical rhythm — goal \"大幅提升移动端体验\",\n extending R28's Overview pattern to /tasks): this mb-6 + the\n From/To filter row mb-6 below both drop to mb-4 on phones,\n restoring mb-6 from sm: up. Saves ~16 px per spot = ~32 px of\n scroll reclaim on /tasks before the actual task rows. /tasks\n is the second-most-trafficked page after Overview. */}\n <div className=\"flex items-center gap-4 mb-4 sm:mb-6\">\n <h1 className=\"text-2xl font-bold text-white lg:ml-0 ml-10\">Tasks</h1>\n {/* Round 88 made this chip pagination-aware; #217 D6 hides it\n entirely in the common case — the All tab right below shows\n the same count. It only renders when it carries unique info\n (loaded < total ⇒ the list is a slice). */}\n {tasks.length < count && (\n <span\n className=\"text-xs bg-blue-900/30 text-blue-400 px-2 py-0.5 rounded-full border border-blue-800/30 tabular-nums\"\n title={`Showing ${tasks.length} of ${count} tasks`}\n >\n {tasks.length} / {count}\n </span>\n )}\n </div>\n\n {/* Round 75: hide the status tab strip + From/To filter row when\n there are no tasks at all. Each tab would show \"0\" and the\n filter inputs would have nothing to act on — pure noise above\n the empty-state CTA. When at least one task exists, the chrome\n comes back even if the current filter happens to hide\n everything (so users can clear filters). */}\n {tasks.length > 0 && <>\n {/* Status Tabs — color-coded dots per status family so users can\n scan the row at a glance. Active tab gets full chip styling\n (bg + border + text color), inactive tabs only carry the dot\n + neutral label so the active state remains the strong cue.\n On narrow viewports (<sm) the row scrolls horizontally with\n subtle gradient fade-edges (via .anet-tabstrip-wrap pseudo\n elements) hinting more content. */}\n <div className=\"anet-tabstrip-wrap mb-4\">\n <div className=\"anet-tabstrip flex sm:flex-wrap gap-1 bg-[#161618] rounded-lg border border-[#26262b] p-1 overflow-x-auto sm:overflow-x-visible scrollbar-thin\">\n {(() => {\n // Round 56: compute per-status counts so the tab strip doubles as a\n // status distribution dashboard. Matches Audit Log (r43) + Overview\n // agent filter (r34) chip-with-count pattern.\n const counts: Record<string, number> = {};\n tasks.forEach(t => { counts[t.status] = (counts[t.status] || 0) + 1; });\n return ['', ...TASK_STATUSES].map(s => {\n const count = s === '' ? tasks.length : counts[s] || 0;\n const isActive = filterStatus === s;\n return (\n <button\n key={s}\n onClick={() => setFilterStatus(s)}\n disabled={count === 0 && s !== '' && !isActive}\n className={`px-3 py-1.5 rounded-md text-xs transition-colors flex items-center gap-1.5 shrink-0 whitespace-nowrap disabled:opacity-30 disabled:cursor-not-allowed ${\n isActive\n ? `${STATUS_CHIP_CLASS[s] || 'bg-cyan-500/10 text-cyan-300 border-cyan-500/20'} border`\n : 'text-gray-500 hover:text-gray-300 hover:bg-[#1c1c1f]/40'\n }`}\n >\n {s && (\n <span\n aria-hidden\n className=\"inline-block w-1.5 h-1.5 rounded-full shrink-0\"\n style={{ backgroundColor: STATUS_DOT_HEX[s] || '#6b7280' }}\n />\n )}\n <span>{s || 'All'}</span>\n <span className={`text-[10px] tabular-nums ${isActive ? 'opacity-80' : 'text-gray-600'}`}>{count}</span>\n </button>\n );\n });\n })()}\n </div>\n </div>\n\n {/* From/To Filters — same visual block as the status tabs above.\n R30 (see header above): mb-6 → mb-4 sm:mb-6 mobile-tighten. */}\n <div className=\"flex flex-wrap items-center gap-2 mb-4 sm:mb-6\">\n <div className=\"flex items-center gap-1.5 rounded-lg border border-[#26262b] bg-[#161618] px-2.5 py-1.5 focus-within:border-blue-500/40\">\n <span className=\"text-[10px] uppercase tracking-wide text-gray-600\">From</span>\n <input\n type=\"text\"\n value={filterFrom}\n onChange={e => setFilterFrom(e.target.value)}\n placeholder=\"any node\"\n className=\"w-28 bg-transparent text-base sm:text-sm text-white placeholder-gray-700 focus:outline-none\"\n />\n </div>\n <div className=\"flex items-center gap-1.5 rounded-lg border border-[#26262b] bg-[#161618] px-2.5 py-1.5 focus-within:border-blue-500/40\">\n <span className=\"text-[10px] uppercase tracking-wide text-gray-600\">To</span>\n <input\n type=\"text\"\n value={filterTo}\n onChange={e => setFilterTo(e.target.value)}\n placeholder=\"any node\"\n className=\"w-28 bg-transparent text-base sm:text-sm text-white placeholder-gray-700 focus:outline-none\"\n />\n </div>\n {(filterStatus || filterFrom || filterTo) && (\n <button\n type=\"button\"\n onClick={() => { setFilterStatus(''); setFilterFrom(''); setFilterTo(''); }}\n className=\"rounded-lg border border-gray-700 px-2.5 py-1.5 text-[11px] text-gray-500 hover:text-gray-200 hover:border-gray-600\"\n >\n Clear filters\n </button>\n )}\n </div>\n </>}\n\n {/* Status distribution */}\n {tasks.length > 0 && !filterStatus && (() => {\n const stats: Record<string, number> = {};\n tasks.forEach(t => { stats[t.status] = (stats[t.status] || 0) + 1; });\n const total = tasks.length || 1;\n // Round 67: derive from shared TASK_STATUSES + STATUS_BAR_CLASS in\n // app/lib/status.ts. Adding a new lifecycle status updates badge,\n // tab dots, and bar in one edit.\n const bars = TASK_STATUSES\n .map(key => ({ key, color: STATUS_BAR_CLASS[key] }))\n .filter(b => stats[b.key]);\n if (!bars.length) return null;\n // Round 63: removed the per-status legend row beneath the bar —\n // it duplicated the counts already shown in the tab chip strip\n // since r56. The proportional bar stays because it adds a visual\n // \"shape of workload\" that the chip numbers don't convey.\n return (\n <div className=\"mb-6\">\n <div className=\"flex h-2 rounded-full overflow-hidden bg-gray-800\">\n {bars.map(b => <div key={b.key} className={b.color} style={{ width: `${(stats[b.key]/total)*100}%` }} title={`${b.key}: ${stats[b.key]}`} />)}\n </div>\n </div>\n );\n })()}\n\n {error && (\n <div className=\"bg-red-900/20 border border-red-800/40 text-red-300 px-4 py-2 rounded-lg mb-6 text-sm\">{error}</div>\n )}\n\n {loading ? (\n <div className=\"animate-pulse space-y-3\">\n {[1, 2, 3, 4, 5].map(i => (\n <div key={i} className=\"h-20 bg-gray-800/20 rounded-lg border border-gray-800/40\" />\n ))}\n </div>\n ) : tasks.length === 0 ? (\n <EmptyState\n variant=\"tasks\"\n sub={(filterStatus || filterFrom || filterTo)\n ? 'No tasks match the current filters. Try clearing them.'\n : 'Tasks will appear here when agents send them via CommHub.'}\n />\n ) : (\n <div className=\"space-y-1 sm:space-y-2\">\n {/* Table header */}\n <div className=\"hidden sm:grid sm:grid-cols-12 gap-2 px-4 py-2 text-xs text-gray-600 uppercase\">\n <div className=\"col-span-1\">Status</div>\n <div className=\"col-span-2\">From</div>\n <div className=\"col-span-2\">To</div>\n <div className=\"col-span-4\">Content</div>\n <div className=\"col-span-1\">Priority</div>\n <div className=\"col-span-2\">Time</div>\n </div>\n\n {tasks.map(t => {\n const isOpen = expanded.has(t.task_id);\n return (\n <div\n key={t.task_id}\n className={`anet-task-row group bg-[#161618] border rounded-lg px-3 py-2 sm:px-4 sm:py-3 transition-all duration-200 cursor-pointer ${\n isOpen\n ? 'border-[#3a3a41] shadow-lg shadow-black/20'\n : 'border-[#26262b] hover:border-[#3a3a41] hover:bg-[#15152e]'\n }`}\n onClick={() => toggleExpand(t.task_id)}\n role=\"button\"\n tabIndex={0}\n aria-expanded={isOpen}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggleExpand(t.task_id);\n }\n }}\n >\n {/* Desktop row */}\n <div className=\"hidden sm:grid sm:grid-cols-12 gap-2 items-center\">\n <div className=\"col-span-1\">\n <span className={statusBadge(t.status)}>{t.status}</span>\n </div>\n <div className=\"col-span-2 flex items-center gap-1.5 min-w-0\" title={t.from_name}>\n {t.from_name && <AliasAvatar alias={t.from_name} size={18} />}\n <span className=\"truncate text-sm text-gray-200\">{t.from_name || '--'}</span>\n </div>\n <div className=\"col-span-2 flex items-center gap-1.5 min-w-0\" title={t.to_name}>\n {t.to_name && <AliasAvatar alias={t.to_name} size={18} />}\n <span className=\"truncate text-sm text-gray-200\">{t.to_name || '--'}</span>\n </div>\n <div className=\"col-span-4 text-xs text-gray-400 truncate\" title={t.content}>\n {previewContent(t.content)}\n </div>\n <div className=\"col-span-1\">\n <span className={`text-xs ${priorityBadge(t.priority)}`}>{t.priority || 'normal'}</span>\n </div>\n <div className=\"col-span-2 text-xs text-gray-500 flex items-center justify-between gap-2\" title={t.created_at}>\n <span className=\"truncate\">{timeAgo(t.created_at)}</span>\n <svg\n aria-hidden\n className={`shrink-0 text-gray-600 group-hover:text-gray-400 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 9l6 6 6-6\" />\n </svg>\n </div>\n </div>\n\n {/* Mobile layout — R8 of #190 mobile polish: 4-row stack\n → 3-row by inlining timeAgo onto the same row as the\n from→to alias header (it's already 4 small atoms, has\n room), plus space-y-2 → space-y-1 to trim ~4px per\n row × 200 tasks. */}\n <div className=\"sm:hidden space-y-1\">\n <div className=\"flex items-center justify-between\">\n <span className={statusBadge(t.status)}>{t.status}</span>\n <div className=\"flex items-center gap-2\">\n <span className={`text-xs ${priorityBadge(t.priority)}`}>{t.priority || 'normal'}</span>\n <svg\n aria-hidden\n className={`text-gray-600 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 9l6 6 6-6\" />\n </svg>\n </div>\n </div>\n <div className=\"flex items-center gap-1.5 text-xs text-gray-300 min-w-0\">\n {t.from_name && <AliasAvatar alias={t.from_name} size={16} />}\n <span className=\"truncate max-w-[35%]\">{t.from_name || '--'}</span>\n <span className=\"text-gray-600\">→</span>\n {t.to_name && <AliasAvatar alias={t.to_name} size={16} />}\n <span className=\"truncate max-w-[35%]\">{t.to_name || '--'}</span>\n <span className=\"ml-auto shrink-0 text-[10px] text-gray-600\">{timeAgo(t.created_at)}</span>\n </div>\n <div className=\"text-xs text-gray-400 line-clamp-1\" title={t.content}>{previewContent(t.content)}</div>\n </div>\n\n {/* Expanded detail — always mounted; grid-rows 0fr↔1fr trick gives\n content-aware smooth max-height animation without measuring DOM. */}\n <div\n className={`grid transition-all duration-300 ease-out ${\n isOpen ? 'grid-rows-[1fr] opacity-100 mt-3' : 'grid-rows-[0fr] opacity-0'\n }`}\n aria-hidden={!isOpen}\n >\n <div className=\"overflow-hidden\">\n <div className=\"pt-3 border-t border-[#26262b] space-y-3\">\n {t.content && (\n <div>\n <div className=\"text-xs text-gray-600 mb-1\">Content</div>\n <div className=\"text-xs text-gray-300 whitespace-pre-wrap bg-[#0e0e10] rounded-lg px-3 py-2 border border-[#1c1c1f]\">{t.content}</div>\n </div>\n )}\n {t.result && (\n <div>\n <div className=\"text-xs text-gray-600 mb-1\">Result</div>\n <div className=\"text-xs text-gray-300 whitespace-pre-wrap bg-[#0e0e10] rounded-lg px-3 py-2 border border-[#1c1c1f] max-h-48 overflow-y-auto\">{t.result}</div>\n </div>\n )}\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs\">\n {[\n ['Created', t.created_at],\n ['Delivered', t.delivered_at],\n ['Started', t.started_at],\n ['Completed', t.completed_at],\n ].map(([label, val]) => (\n <div key={label as string}>\n <span className=\"text-gray-600\">{label}: </span>\n <span className=\"text-gray-400\">{val ? timeAgo(val as string) : '--'}</span>\n </div>\n ))}\n </div>\n {t.expires_at && (\n <div className=\"text-xs\">\n <span className=\"text-gray-600\">Expires: </span>\n <span className=\"text-orange-400\">{t.expires_at}</span>\n </div>\n )}\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-xs text-gray-600 truncate\" title={t.task_id}>\n ID: {t.task_id}\n </div>\n <div className=\"flex gap-2 shrink-0\">\n {(t.status === 'failed' || t.status === 'expired') && (\n <button\n onClick={async (e) => {\n e.stopPropagation();\n await fetch('/api/hub/send', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ alias: t.to_name, task: t.content, priority: t.priority }),\n });\n fetchTasks();\n }}\n className=\"text-xs text-orange-400 hover:text-orange-300 px-2 py-0.5 rounded border border-orange-500/20 hover:bg-orange-500/10\"\n >\n Retry\n </button>\n )}\n <button\n onClick={e => { e.stopPropagation(); setDrawerTaskId(t.task_id); }}\n className=\"text-xs text-cyan-400 hover:text-cyan-300\"\n >\n Detail →\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {drawerTaskId && <TaskDrawer taskId={drawerTaskId} onClose={() => setDrawerTaskId(null)} />}\n </div>\n );\n}\n\nexport default function TasksPage() {\n return (\n <Suspense fallback={\n // #209 R30 (playwright mobile-shot caught it): the bare Suspense\n // fallback rendered \"Loading tasks...\" at p-6 with no left-indent,\n // so the fixed top-3 left-3 mobile burger (56 px right-edge) sat\n // right on top of \"Loa\" — the screenshot read as a broken page.\n // Match the loaded layout: p-4 sm:p-6 page padding + ml-10 mobile\n // indent on the text, so the burger clears and the loading state\n // visually maps to the populated page.\n <div className=\"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6\">\n <div className=\"lg:ml-0 ml-10 text-gray-500 text-sm\">Loading tasks…</div>\n </div>\n }>\n <TasksContent />\n </Suspense>\n );\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport { timeAgo } from './utils';\nimport { AliasAvatar } from './AliasAvatar';\n\ninterface TaskDetail {\n task_id: string;\n from_name: string;\n to_name: string;\n status: string;\n priority: string;\n content: string;\n result: string;\n created_at: string;\n delivered_at: string;\n started_at: string;\n completed_at: string;\n expires_at: string;\n}\n\ninterface TaskEvent {\n id: number;\n event_type: string;\n from_status: string;\n to_status: string;\n detail: string;\n created_at: string;\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n created: 'text-gray-400', delivered: 'text-blue-400', running: 'text-green-400',\n replied: 'text-purple-400', failed: 'text-red-400', closed: 'text-gray-500',\n};\n\ninterface TaskDrawerProps {\n taskId: string;\n onClose: () => void;\n}\n\nexport function TaskDrawer({ taskId, onClose }: TaskDrawerProps) {\n const [task, setTask] = useState<TaskDetail | null>(null);\n const [events, setEvents] = useState<TaskEvent[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n (async () => {\n try {\n const [taskRes, eventsRes] = await Promise.all([\n fetch(`/api/hub/tasks?task_id=${encodeURIComponent(taskId)}`),\n fetch(`/api/hub/task-events?task_id=${encodeURIComponent(taskId)}&limit=50`),\n ]);\n const taskData = await taskRes.json();\n const eventsData = await eventsRes.json();\n if (taskData.tasks?.[0]) setTask(taskData.tasks[0]);\n setEvents(eventsData.events || []);\n } catch {} finally { setLoading(false); }\n })();\n }, [taskId]);\n\n /** Timeline steps — same 4 hops every task goes through. `time` is set\n * when the hop has happened; missing time means pending. Round 36 adds\n * `key` for the \"current step\" highlight + the `done` flag for layout. */\n const timeline = task ? [\n { key: 'created', label: 'Created', time: task.created_at, color: 'bg-gray-400' },\n { key: 'delivered', label: 'Delivered', time: task.delivered_at, color: 'bg-blue-400' },\n { key: 'started', label: 'Started', time: task.started_at, color: 'bg-green-400' },\n { key: 'completed', label: 'Completed', time: task.completed_at, color: 'bg-purple-400'},\n ].map(s => ({ ...s, done: !!s.time })) : [];\n\n /** Index of the highest-completed step. The step *after* this index is\n * the \"current\" one (in-progress). When all are done, currentIdx = -1. */\n const currentStepIdx = timeline.findIndex(s => !s.done);\n const isActive = task && task.status !== 'completed' && task.status !== 'failed' && task.status !== 'expired' && task.status !== 'cancelled';\n\n const duration = task?.started_at && task?.completed_at\n ? Math.round((new Date(task.completed_at).getTime() - new Date(task.started_at).getTime()) / 1000)\n : null;\n\n return (\n <>\n <div className=\"fixed inset-0 bg-black/30 z-40 anet-fade-in\" onClick={onClose} />\n <div className=\"fixed top-0 right-0 h-[100dvh] w-full lg:w-[500px] bg-[#0b0b0d] border-l border-[#26262b] z-50 flex flex-col shadow-2xl shadow-black/60 overflow-y-auto animate-slide-in\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-[#26262b] bg-[#111113] sticky top-0\">\n <div>\n <div className=\"text-sm font-semibold text-white\">Task Detail</div>\n <div className=\"text-[10px] text-gray-500 mt-0.5\">{taskId.slice(0, 16)}...</div>\n </div>\n {/* R16 of #190: same chat-panel close pattern — was ~32 px\n tap target; lift to a uniform 44 x 44 hit zone. */}\n <button onClick={onClose} aria-label=\"Close task drawer\" className=\"inline-flex min-h-[44px] min-w-[44px] items-center justify-center text-gray-500 hover:text-white rounded-lg hover:bg-[#1c1c1f]\">\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {loading ? (\n <div className=\"flex justify-center py-16\">\n <div className=\"w-6 h-6 border-2 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin\" />\n </div>\n ) : !task ? (\n <div className=\"text-center py-16 text-gray-500\">Task not found</div>\n ) : (\n <div className=\"px-5 py-5 space-y-5\">\n {/* Status + Priority */}\n <div className=\"flex items-center gap-3\">\n <span className={`text-lg font-bold ${STATUS_COLORS[task.status] || 'text-gray-400'}`}>{task.status}</span>\n {task.priority !== 'normal' && (\n <span className={`text-xs px-2 py-0.5 rounded border ${task.priority === 'high' ? 'text-red-300 border-red-500/20' : 'text-gray-400 border-gray-600/20'}`}>{task.priority}</span>\n )}\n {duration !== null && (\n <span className=\"text-xs text-gray-500\">⏱ {duration < 60 ? `${duration}s` : `${Math.floor(duration/60)}m ${duration%60}s`}</span>\n )}\n </div>\n\n {/* From → To — round 41: use AliasAvatar so from/to colours\n match the rest of the app instead of the legacy blue/cyan\n hardcode. */}\n <div className=\"flex items-center gap-2 text-sm flex-wrap\">\n {task.from_name && <AliasAvatar alias={task.from_name} size={18} />}\n <span className=\"text-gray-200 font-medium\">{task.from_name || '--'}</span>\n <span className=\"text-gray-600\">→</span>\n {task.to_name && <AliasAvatar alias={task.to_name} size={18} />}\n <span className=\"text-gray-200 font-medium\">{task.to_name || '--'}</span>\n </div>\n\n {/* Timeline — round 36 polish: relative timestamps, current-step\n pulse if task is still in flight, full ISO in title=. */}\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"text-xs text-gray-500 uppercase tracking-wide\">Timeline</div>\n {duration !== null && (\n <div className=\"text-[10px] text-gray-600\">\n {duration < 60 ? `${duration}s` : `${Math.floor(duration/60)}m ${duration%60}s`} runtime\n </div>\n )}\n </div>\n <div className=\"space-y-3\">\n {timeline.map((step, i) => {\n const isCurrent = isActive && i === currentStepIdx;\n const isNextDone = !!timeline[i+1]?.done;\n return (\n <div key={step.key} className=\"flex items-start gap-3\">\n <div className=\"flex flex-col items-center pt-0.5\">\n <span\n className={`relative w-3 h-3 rounded-full shrink-0 ${\n step.done ? step.color : 'bg-gray-700'\n }`}\n >\n {isCurrent && (\n <span\n aria-hidden\n className=\"absolute -inset-1 rounded-full border border-current opacity-60 anet-current-step-pulse\"\n style={{ borderColor: 'currentColor' }}\n />\n )}\n </span>\n {i < timeline.length - 1 && (\n <div className={`w-0.5 h-5 mt-1 ${\n step.done && isNextDone ? 'bg-gray-500' : step.done ? 'bg-gradient-to-b from-gray-500 to-gray-800' : 'bg-gray-800'\n }`} />\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className={`text-xs font-medium flex items-center gap-2 ${\n step.done ? 'text-gray-200' : isCurrent ? 'text-cyan-300' : 'text-gray-600'\n }`}>\n <span>{step.label}</span>\n {isCurrent && <span className=\"text-[9px] uppercase tracking-wide text-cyan-400\">in progress</span>}\n </div>\n <div className=\"text-[10px] text-gray-500\" title={step.time || undefined}>\n {step.time ? timeAgo(step.time) : isCurrent ? '—' : 'Pending'}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Input</div>\n <div className=\"text-sm text-gray-300 whitespace-pre-wrap\">{task.content || '--'}</div>\n </div>\n\n {/* Result */}\n {task.result && (\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Output</div>\n <div className=\"text-sm text-gray-300 whitespace-pre-wrap max-h-64 overflow-y-auto\">{task.result}</div>\n </div>\n )}\n\n {/* Events */}\n {events.length > 0 && (\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Events ({events.length})</div>\n <div className=\"space-y-1.5 max-h-40 overflow-y-auto\">\n {events.map(e => (\n <div key={e.id} className=\"flex items-center gap-2 text-[11px]\">\n <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${\n e.to_status === 'running' ? 'bg-green-400' : e.to_status === 'replied' ? 'bg-purple-400' : e.to_status === 'failed' ? 'bg-red-400' : 'bg-blue-400'\n }`} />\n <span className=\"text-gray-400\">{e.event_type}</span>\n {e.from_status && <span className=\"text-gray-600\">{e.from_status}→{e.to_status}</span>}\n <span className=\"text-gray-600 ml-auto\">{timeAgo(e.created_at)}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Metadata */}\n <div className=\"text-[10px] text-gray-600 space-y-1\">\n <div>Task ID: {task.task_id}</div>\n {task.expires_at && <div>Expires: {task.expires_at}</div>}\n </div>\n </div>\n )}\n </div>\n </>\n );\n}\n"],"names":["STATUS_COLORS","created","delivered","running","replied","failed","closed","TaskDrawer","taskId","onClose","task","setTask","events","setEvents","loading","setLoading","taskRes","eventsRes","Promise","all","fetch","encodeURIComponent","taskData","json","eventsData","tasks","timeline","key","label","time","created_at","color","delivered_at","started_at","completed_at","map","s","done","currentStepIdx","findIndex","isActive","status","duration","Math","round","Date","getTime","className","onClick","slice","fill","viewBox","stroke","strokeWidth","strokeLinecap","strokeLinejoin","d","priority","floor","from_name","alias","size","to_name","step","i","isCurrent","isNextDone","style","borderColor","length","title","undefined","content","result","e","to_status","event_type","from_status","id","task_id","expires_at"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../agent-network-dashboard/app/tasks/page.tsx","../../../../../agent-network-dashboard/app/components/TaskDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState, useCallback, Suspense } from 'react';\nimport { useSearchParams } from 'next/navigation';\nimport Link from 'next/link';\nimport { useNetworkId } from '../lib/network-context';\nimport { TaskDrawer } from '../components/TaskDrawer';\nimport { EmptyState } from '../components/EmptyState';\nimport { AliasAvatar } from '../components/AliasAvatar';\nimport { previewContent } from '../components/utils';\nimport { TASK_STATUSES, STATUS_CHIP_CLASS, STATUS_DOT_HEX, STATUS_BAR_CLASS } from '../lib/status';\n\ninterface Task {\n task_id: string;\n from_name: string;\n to_name: string;\n status: string;\n priority: string;\n content: string;\n result: string;\n created_at: string;\n updated_at: string;\n delivered_at: string;\n started_at: string;\n completed_at: string;\n expires_at: string;\n}\n\nfunction statusBadge(status: string) {\n const color = STATUS_CHIP_CLASS[status] || 'bg-gray-500/10 text-gray-400 border-gray-500/20';\n return `text-xs px-2 py-0.5 rounded-md border ${color}`;\n}\n\nfunction priorityBadge(priority: string) {\n if (priority === 'high') return 'text-red-400';\n if (priority === 'low') return 'text-gray-600';\n return 'text-gray-400';\n}\n\nfunction timeAgo(dateStr: string): string {\n if (!dateStr) return '--';\n const diff = Date.now() - new Date(dateStr.replace(' ', 'T') + 'Z').getTime();\n const s = Math.floor(diff / 1000);\n if (s < 60) return `${s}s ago`;\n if (s < 3600) return `${Math.floor(s / 60)}m ago`;\n if (s < 86400) return `${Math.floor(s / 3600)}h ago`;\n return `${Math.floor(s / 86400)}d ago`;\n}\n\nfunction TasksContent() {\n const searchParams = useSearchParams();\n const { networkId } = useNetworkId();\n const [tasks, setTasks] = useState<Task[]>([]);\n const [count, setCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n\n const [filterStatus, setFilterStatus] = useState(searchParams.get('status') || '');\n const [filterFrom, setFilterFrom] = useState('');\n const [filterTo, setFilterTo] = useState('');\n const [drawerTaskId, setDrawerTaskId] = useState<string | null>(null);\n\n const toggleExpand = (taskId: string) => {\n setExpanded(prev => {\n const next = new Set(prev);\n if (next.has(taskId)) next.delete(taskId);\n else next.add(taskId);\n return next;\n });\n };\n\n const fetchTasks = useCallback(async () => {\n try {\n const params = new URLSearchParams();\n if (networkId) params.set('network_id', networkId);\n if (filterStatus) params.set('status', filterStatus);\n if (filterFrom) params.set('from_name', filterFrom);\n if (filterTo) params.set('to_name', filterTo);\n params.set('limit', '100');\n\n const res = await fetch(`/api/hub/tasks?${params.toString()}`);\n if (res.status === 401) {\n window.location.assign('/login');\n return;\n }\n const data = await res.json();\n setTasks(data.tasks || []);\n setCount(data.count ?? (data.tasks?.length || 0));\n setError('');\n } catch (e: unknown) {\n setError(e instanceof Error ? e.message : 'fetch failed');\n } finally {\n setLoading(false);\n }\n }, [filterStatus, filterFrom, filterTo, networkId]);\n\n useEffect(() => {\n setLoading(true);\n fetchTasks();\n const interval = setInterval(fetchTasks, 5000);\n return () => clearInterval(interval);\n }, [fetchTasks]);\n\n return (\n <div className=\"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6\">\n {/* Header.\n #209 R30 (mobile vertical rhythm — goal \"大幅提升移动端体验\",\n extending R28's Overview pattern to /tasks): this mb-6 + the\n From/To filter row mb-6 below both drop to mb-4 on phones,\n restoring mb-6 from sm: up. Saves ~16 px per spot = ~32 px of\n scroll reclaim on /tasks before the actual task rows. /tasks\n is the second-most-trafficked page after Overview. */}\n <div className=\"flex items-center gap-4 mb-4 sm:mb-6\">\n <h1 className=\"text-2xl font-bold text-white lg:ml-0 ml-10\">Tasks</h1>\n {/* Round 88 made this chip pagination-aware; #217 D6 hides it\n entirely in the common case — the All tab right below shows\n the same count. It only renders when it carries unique info\n (loaded < total ⇒ the list is a slice). */}\n {tasks.length < count && (\n <span\n className=\"text-xs bg-blue-900/30 text-blue-400 px-2 py-0.5 rounded-full border border-blue-800/30 tabular-nums\"\n title={`Showing ${tasks.length} of ${count} tasks`}\n >\n {tasks.length} / {count}\n </span>\n )}\n </div>\n\n {/* Round 75: hide the status tab strip + From/To filter row when\n there are no tasks at all. Each tab would show \"0\" and the\n filter inputs would have nothing to act on — pure noise above\n the empty-state CTA. When at least one task exists, the chrome\n comes back even if the current filter happens to hide\n everything (so users can clear filters). */}\n {tasks.length > 0 && <>\n {/* Status Tabs — color-coded dots per status family so users can\n scan the row at a glance. Active tab gets full chip styling\n (bg + border + text color), inactive tabs only carry the dot\n + neutral label so the active state remains the strong cue.\n On narrow viewports (<sm) the row scrolls horizontally with\n subtle gradient fade-edges (via .anet-tabstrip-wrap pseudo\n elements) hinting more content. */}\n <div className=\"anet-tabstrip-wrap mb-4\">\n <div className=\"anet-tabstrip flex sm:flex-wrap gap-1 bg-[#161618] rounded-lg border border-[#26262b] p-1 overflow-x-auto sm:overflow-x-visible scrollbar-thin\">\n {(() => {\n // Round 56: compute per-status counts so the tab strip doubles as a\n // status distribution dashboard. Matches Audit Log (r43) + Overview\n // agent filter (r34) chip-with-count pattern.\n const counts: Record<string, number> = {};\n tasks.forEach(t => { counts[t.status] = (counts[t.status] || 0) + 1; });\n return ['', ...TASK_STATUSES].map(s => {\n const count = s === '' ? tasks.length : counts[s] || 0;\n const isActive = filterStatus === s;\n return (\n <button\n key={s}\n onClick={() => setFilterStatus(s)}\n disabled={count === 0 && s !== '' && !isActive}\n className={`px-3 py-1.5 rounded-md text-xs transition-colors flex items-center gap-1.5 shrink-0 whitespace-nowrap disabled:opacity-30 disabled:cursor-not-allowed ${\n isActive\n ? `${STATUS_CHIP_CLASS[s] || 'bg-cyan-500/10 text-cyan-300 border-cyan-500/20'} border`\n : 'text-gray-500 hover:text-gray-300 hover:bg-[#1c1c1f]/40'\n }`}\n >\n {s && (\n <span\n aria-hidden\n className=\"inline-block w-1.5 h-1.5 rounded-full shrink-0\"\n style={{ backgroundColor: STATUS_DOT_HEX[s] || '#6b7280' }}\n />\n )}\n <span>{s || 'All'}</span>\n <span className={`text-[10px] tabular-nums ${isActive ? 'opacity-80' : 'text-gray-600'}`}>{count}</span>\n </button>\n );\n });\n })()}\n </div>\n </div>\n\n {/* From/To Filters — same visual block as the status tabs above.\n R30 (see header above): mb-6 → mb-4 sm:mb-6 mobile-tighten. */}\n <div className=\"flex flex-wrap items-center gap-2 mb-4 sm:mb-6\">\n <div className=\"flex items-center gap-1.5 rounded-lg border border-[#26262b] bg-[#161618] px-2.5 py-1.5 focus-within:border-blue-500/40\">\n <span className=\"text-[10px] uppercase tracking-wide text-gray-600\">From</span>\n <input\n type=\"text\"\n value={filterFrom}\n onChange={e => setFilterFrom(e.target.value)}\n placeholder=\"any node\"\n className=\"w-28 bg-transparent text-base sm:text-sm text-white placeholder-gray-700 focus:outline-none\"\n />\n </div>\n <div className=\"flex items-center gap-1.5 rounded-lg border border-[#26262b] bg-[#161618] px-2.5 py-1.5 focus-within:border-blue-500/40\">\n <span className=\"text-[10px] uppercase tracking-wide text-gray-600\">To</span>\n <input\n type=\"text\"\n value={filterTo}\n onChange={e => setFilterTo(e.target.value)}\n placeholder=\"any node\"\n className=\"w-28 bg-transparent text-base sm:text-sm text-white placeholder-gray-700 focus:outline-none\"\n />\n </div>\n {(filterStatus || filterFrom || filterTo) && (\n <button\n type=\"button\"\n onClick={() => { setFilterStatus(''); setFilterFrom(''); setFilterTo(''); }}\n className=\"rounded-lg border border-gray-700 px-2.5 py-1.5 text-[11px] text-gray-500 hover:text-gray-200 hover:border-gray-600\"\n >\n Clear filters\n </button>\n )}\n </div>\n </>}\n\n {/* Status distribution */}\n {tasks.length > 0 && !filterStatus && (() => {\n const stats: Record<string, number> = {};\n tasks.forEach(t => { stats[t.status] = (stats[t.status] || 0) + 1; });\n const total = tasks.length || 1;\n // Round 67: derive from shared TASK_STATUSES + STATUS_BAR_CLASS in\n // app/lib/status.ts. Adding a new lifecycle status updates badge,\n // tab dots, and bar in one edit.\n const bars = TASK_STATUSES\n .map(key => ({ key, color: STATUS_BAR_CLASS[key] }))\n .filter(b => stats[b.key]);\n if (!bars.length) return null;\n // Round 63: removed the per-status legend row beneath the bar —\n // it duplicated the counts already shown in the tab chip strip\n // since r56. The proportional bar stays because it adds a visual\n // \"shape of workload\" that the chip numbers don't convey.\n return (\n <div className=\"mb-6\">\n <div className=\"flex h-2 rounded-full overflow-hidden bg-gray-800\">\n {bars.map(b => <div key={b.key} className={b.color} style={{ width: `${(stats[b.key]/total)*100}%` }} title={`${b.key}: ${stats[b.key]}`} />)}\n </div>\n </div>\n );\n })()}\n\n {error && (\n <div className=\"bg-red-900/20 border border-red-800/40 text-red-300 px-4 py-2 rounded-lg mb-6 text-sm\">{error}</div>\n )}\n\n {loading ? (\n <div className=\"animate-pulse space-y-3\">\n {[1, 2, 3, 4, 5].map(i => (\n <div key={i} className=\"h-20 bg-gray-800/20 rounded-lg border border-gray-800/40\" />\n ))}\n </div>\n ) : tasks.length === 0 ? (\n <EmptyState\n variant=\"tasks\"\n sub={(filterStatus || filterFrom || filterTo)\n ? 'No tasks match the current filters. Try clearing them.'\n : 'Tasks will appear here when agents send them via CommHub.'}\n />\n ) : (\n <div className=\"space-y-1 sm:space-y-2\">\n {/* Table header */}\n <div className=\"hidden sm:grid sm:grid-cols-12 gap-2 px-4 py-2 text-xs text-gray-600 uppercase\">\n <div className=\"col-span-1\">Status</div>\n <div className=\"col-span-2\">From</div>\n <div className=\"col-span-2\">To</div>\n <div className=\"col-span-4\">Content</div>\n <div className=\"col-span-1\">Priority</div>\n <div className=\"col-span-2\">Time</div>\n </div>\n\n {tasks.map(t => {\n const isOpen = expanded.has(t.task_id);\n return (\n <div\n key={t.task_id}\n className={`anet-task-row group bg-[#161618] border rounded-lg px-3 py-2 sm:px-4 sm:py-3 transition-all duration-200 cursor-pointer ${\n isOpen\n ? 'border-[#3a3a41] shadow-lg shadow-black/20'\n : 'border-[#26262b] hover:border-[#3a3a41] hover:bg-[#15152e]'\n }`}\n onClick={() => toggleExpand(t.task_id)}\n role=\"button\"\n tabIndex={0}\n aria-expanded={isOpen}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggleExpand(t.task_id);\n }\n }}\n >\n {/* Desktop row */}\n <div className=\"hidden sm:grid sm:grid-cols-12 gap-2 items-center\">\n <div className=\"col-span-1\">\n <span className={statusBadge(t.status)}>{t.status}</span>\n </div>\n <div className=\"col-span-2 flex items-center gap-1.5 min-w-0\" title={t.from_name}>\n {t.from_name && <AliasAvatar alias={t.from_name} size={18} />}\n <span className=\"truncate text-sm text-gray-200\">{t.from_name || '--'}</span>\n </div>\n <div className=\"col-span-2 flex items-center gap-1.5 min-w-0\" title={t.to_name}>\n {t.to_name && <AliasAvatar alias={t.to_name} size={18} />}\n <span className=\"truncate text-sm text-gray-200\">{t.to_name || '--'}</span>\n </div>\n <div className=\"col-span-4 text-xs text-gray-400 truncate\" title={t.content}>\n {previewContent(t.content)}\n </div>\n <div className=\"col-span-1\">\n <span className={`text-xs ${priorityBadge(t.priority)}`}>{t.priority || 'normal'}</span>\n </div>\n <div className=\"col-span-2 text-xs text-gray-500 flex items-center justify-between gap-2\" title={t.created_at}>\n <span className=\"truncate\">{timeAgo(t.created_at)}</span>\n <svg\n aria-hidden\n className={`shrink-0 text-gray-600 group-hover:text-gray-400 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 9l6 6 6-6\" />\n </svg>\n </div>\n </div>\n\n {/* Mobile layout — R8 of #190 mobile polish: 4-row stack\n → 3-row by inlining timeAgo onto the same row as the\n from→to alias header (it's already 4 small atoms, has\n room), plus space-y-2 → space-y-1 to trim ~4px per\n row × 200 tasks. */}\n <div className=\"sm:hidden space-y-1\">\n <div className=\"flex items-center justify-between\">\n <span className={statusBadge(t.status)}>{t.status}</span>\n <div className=\"flex items-center gap-2\">\n <span className={`text-xs ${priorityBadge(t.priority)}`}>{t.priority || 'normal'}</span>\n <svg\n aria-hidden\n className={`text-gray-600 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 9l6 6 6-6\" />\n </svg>\n </div>\n </div>\n <div className=\"flex items-center gap-1.5 text-xs text-gray-300 min-w-0\">\n {t.from_name && <AliasAvatar alias={t.from_name} size={16} />}\n <span className=\"truncate max-w-[35%]\">{t.from_name || '--'}</span>\n <span className=\"text-gray-600\">→</span>\n {t.to_name && <AliasAvatar alias={t.to_name} size={16} />}\n <span className=\"truncate max-w-[35%]\">{t.to_name || '--'}</span>\n <span className=\"ml-auto shrink-0 text-[10px] text-gray-600\">{timeAgo(t.created_at)}</span>\n </div>\n <div className=\"text-xs text-gray-400 line-clamp-1\" title={t.content}>{previewContent(t.content)}</div>\n </div>\n\n {/* Expanded detail — always mounted; grid-rows 0fr↔1fr trick gives\n content-aware smooth max-height animation without measuring DOM. */}\n <div\n className={`grid transition-all duration-300 ease-out ${\n isOpen ? 'grid-rows-[1fr] opacity-100 mt-3' : 'grid-rows-[0fr] opacity-0'\n }`}\n aria-hidden={!isOpen}\n >\n <div className=\"overflow-hidden\">\n <div className=\"pt-3 border-t border-[#26262b] space-y-3\">\n {t.content && (\n <div>\n <div className=\"text-xs text-gray-600 mb-1\">Content</div>\n <div className=\"text-xs text-gray-300 whitespace-pre-wrap bg-[#0e0e10] rounded-lg px-3 py-2 border border-[#1c1c1f]\">{t.content}</div>\n </div>\n )}\n {t.result && (\n <div>\n <div className=\"text-xs text-gray-600 mb-1\">Result</div>\n <div className=\"text-xs text-gray-300 whitespace-pre-wrap bg-[#0e0e10] rounded-lg px-3 py-2 border border-[#1c1c1f] max-h-48 overflow-y-auto\">{t.result}</div>\n </div>\n )}\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs\">\n {[\n ['Created', t.created_at],\n ['Delivered', t.delivered_at],\n ['Started', t.started_at],\n ['Completed', t.completed_at],\n ].map(([label, val]) => (\n <div key={label as string}>\n <span className=\"text-gray-600\">{label}: </span>\n <span className=\"text-gray-400\">{val ? timeAgo(val as string) : '--'}</span>\n </div>\n ))}\n </div>\n {t.expires_at && (\n <div className=\"text-xs\">\n <span className=\"text-gray-600\">Expires: </span>\n <span className=\"text-orange-400\">{t.expires_at}</span>\n </div>\n )}\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-xs text-gray-600 truncate\" title={t.task_id}>\n ID: {t.task_id}\n </div>\n <div className=\"flex gap-2 shrink-0\">\n {(t.status === 'failed' || t.status === 'expired') && (\n <button\n onClick={async (e) => {\n e.stopPropagation();\n await fetch('/api/hub/send', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ alias: t.to_name, task: t.content, priority: t.priority }),\n });\n fetchTasks();\n }}\n className=\"text-xs text-orange-400 hover:text-orange-300 px-2 py-0.5 rounded border border-orange-500/20 hover:bg-orange-500/10\"\n >\n Retry\n </button>\n )}\n <button\n onClick={e => { e.stopPropagation(); setDrawerTaskId(t.task_id); }}\n className=\"text-xs text-cyan-400 hover:text-cyan-300\"\n >\n Detail →\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {drawerTaskId && <TaskDrawer taskId={drawerTaskId} onClose={() => setDrawerTaskId(null)} />}\n </div>\n );\n}\n\nexport default function TasksPage() {\n return (\n <Suspense fallback={\n // #209 R30 (playwright mobile-shot caught it): the bare Suspense\n // fallback rendered \"Loading tasks...\" at p-6 with no left-indent,\n // so the fixed top-3 left-3 mobile burger (56 px right-edge) sat\n // right on top of \"Loa\" — the screenshot read as a broken page.\n // Match the loaded layout: p-4 sm:p-6 page padding + ml-10 mobile\n // indent on the text, so the burger clears and the loading state\n // visually maps to the populated page.\n <div className=\"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6\">\n <div className=\"lg:ml-0 ml-10 text-gray-500 text-sm\">Loading tasks…</div>\n </div>\n }>\n <TasksContent />\n </Suspense>\n );\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport { timeAgo } from './utils';\nimport Link from 'next/link';\nimport { AliasAvatar } from './AliasAvatar';\n\ninterface TaskDetail {\n task_id: string;\n from_name: string;\n to_name: string;\n status: string;\n priority: string;\n content: string;\n result: string;\n created_at: string;\n delivered_at: string;\n started_at: string;\n completed_at: string;\n expires_at: string;\n}\n\ninterface TaskEvent {\n id: number;\n event_type: string;\n from_status: string;\n to_status: string;\n detail: string;\n created_at: string;\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n created: 'text-gray-400', delivered: 'text-blue-400', running: 'text-green-400',\n replied: 'text-purple-400', failed: 'text-red-400', closed: 'text-gray-500',\n};\n\ninterface TaskDrawerProps {\n taskId: string;\n onClose: () => void;\n}\n\nexport function TaskDrawer({ taskId, onClose }: TaskDrawerProps) {\n const [task, setTask] = useState<TaskDetail | null>(null);\n const [events, setEvents] = useState<TaskEvent[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n (async () => {\n try {\n const [taskRes, eventsRes] = await Promise.all([\n fetch(`/api/hub/tasks?task_id=${encodeURIComponent(taskId)}`),\n fetch(`/api/hub/task-events?task_id=${encodeURIComponent(taskId)}&limit=50`),\n ]);\n const taskData = await taskRes.json();\n const eventsData = await eventsRes.json();\n if (taskData.tasks?.[0]) setTask(taskData.tasks[0]);\n setEvents(eventsData.events || []);\n } catch {} finally { setLoading(false); }\n })();\n }, [taskId]);\n\n /** Timeline steps — same 4 hops every task goes through. `time` is set\n * when the hop has happened; missing time means pending. Round 36 adds\n * `key` for the \"current step\" highlight + the `done` flag for layout. */\n const timeline = task ? [\n { key: 'created', label: 'Created', time: task.created_at, color: 'bg-gray-400' },\n { key: 'delivered', label: 'Delivered', time: task.delivered_at, color: 'bg-blue-400' },\n { key: 'started', label: 'Started', time: task.started_at, color: 'bg-green-400' },\n { key: 'completed', label: 'Completed', time: task.completed_at, color: 'bg-purple-400'},\n ].map(s => ({ ...s, done: !!s.time })) : [];\n\n /** Index of the highest-completed step. The step *after* this index is\n * the \"current\" one (in-progress). When all are done, currentIdx = -1. */\n const currentStepIdx = timeline.findIndex(s => !s.done);\n const isActive = task && task.status !== 'completed' && task.status !== 'failed' && task.status !== 'expired' && task.status !== 'cancelled';\n\n const duration = task?.started_at && task?.completed_at\n ? Math.round((new Date(task.completed_at).getTime() - new Date(task.started_at).getTime()) / 1000)\n : null;\n\n return (\n <>\n <div className=\"fixed inset-0 bg-black/30 z-40 anet-fade-in\" onClick={onClose} />\n <div className=\"fixed top-0 right-0 h-[100dvh] w-full lg:w-[500px] bg-[#0b0b0d] border-l border-[#26262b] z-50 flex flex-col shadow-2xl shadow-black/60 overflow-y-auto animate-slide-in\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-[#26262b] bg-[#111113] sticky top-0\">\n <div>\n <div className=\"text-sm font-semibold text-white\">Task Detail</div>\n <div className=\"text-[10px] text-gray-500 mt-0.5\">{taskId.slice(0, 16)}...</div>\n </div>\n {/* R16 of #190: same chat-panel close pattern — was ~32 px\n tap target; lift to a uniform 44 x 44 hit zone. */}\n <button onClick={onClose} aria-label=\"Close task drawer\" className=\"inline-flex min-h-[44px] min-w-[44px] items-center justify-center text-gray-500 hover:text-white rounded-lg hover:bg-[#1c1c1f]\">\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {loading ? (\n <div className=\"flex justify-center py-16\">\n <div className=\"w-6 h-6 border-2 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin\" />\n </div>\n ) : !task ? (\n <div className=\"text-center py-16 text-gray-500\">Task not found</div>\n ) : (\n <div className=\"px-5 py-5 space-y-5\">\n {/* Status + Priority */}\n <div className=\"flex items-center gap-3\">\n <span className={`text-lg font-bold ${STATUS_COLORS[task.status] || 'text-gray-400'}`}>{task.status}</span>\n {task.priority !== 'normal' && (\n <span className={`text-xs px-2 py-0.5 rounded border ${task.priority === 'high' ? 'text-red-300 border-red-500/20' : 'text-gray-400 border-gray-600/20'}`}>{task.priority}</span>\n )}\n {duration !== null && (\n <span className=\"text-xs text-gray-500\">⏱ {duration < 60 ? `${duration}s` : `${Math.floor(duration/60)}m ${duration%60}s`}</span>\n )}\n </div>\n\n {/* From → To — round 41: use AliasAvatar so from/to colours\n match the rest of the app instead of the legacy blue/cyan\n hardcode. */}\n <div className=\"flex items-center gap-2 text-sm flex-wrap\">\n {task.from_name && <AliasAvatar alias={task.from_name} size={18} />}\n <span className=\"text-gray-200 font-medium\">{task.from_name || '--'}</span>\n <span className=\"text-gray-600\">→</span>\n {task.to_name && <AliasAvatar alias={task.to_name} size={18} />}\n <span className=\"text-gray-200 font-medium\">{task.to_name || '--'}</span>\n </div>\n\n {/* Timeline — round 36 polish: relative timestamps, current-step\n pulse if task is still in flight, full ISO in title=. */}\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"text-xs text-gray-500 uppercase tracking-wide\">Timeline</div>\n {duration !== null && (\n <div className=\"text-[10px] text-gray-600\">\n {duration < 60 ? `${duration}s` : `${Math.floor(duration/60)}m ${duration%60}s`} runtime\n </div>\n )}\n </div>\n <div className=\"space-y-3\">\n {timeline.map((step, i) => {\n const isCurrent = isActive && i === currentStepIdx;\n const isNextDone = !!timeline[i+1]?.done;\n return (\n <div key={step.key} className=\"flex items-start gap-3\">\n <div className=\"flex flex-col items-center pt-0.5\">\n <span\n className={`relative w-3 h-3 rounded-full shrink-0 ${\n step.done ? step.color : 'bg-gray-700'\n }`}\n >\n {isCurrent && (\n <span\n aria-hidden\n className=\"absolute -inset-1 rounded-full border border-current opacity-60 anet-current-step-pulse\"\n style={{ borderColor: 'currentColor' }}\n />\n )}\n </span>\n {i < timeline.length - 1 && (\n <div className={`w-0.5 h-5 mt-1 ${\n step.done && isNextDone ? 'bg-gray-500' : step.done ? 'bg-gradient-to-b from-gray-500 to-gray-800' : 'bg-gray-800'\n }`} />\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className={`text-xs font-medium flex items-center gap-2 ${\n step.done ? 'text-gray-200' : isCurrent ? 'text-cyan-300' : 'text-gray-600'\n }`}>\n <span>{step.label}</span>\n {isCurrent && <span className=\"text-[9px] uppercase tracking-wide text-cyan-400\">in progress</span>}\n </div>\n <div className=\"text-[10px] text-gray-500\" title={step.time || undefined}>\n {step.time ? timeAgo(step.time) : isCurrent ? '—' : 'Pending'}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Input</div>\n <div className=\"text-sm text-gray-300 whitespace-pre-wrap\">{task.content || '--'}</div>\n </div>\n\n {/* Result */}\n {task.result && (\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Output</div>\n <div className=\"text-sm text-gray-300 whitespace-pre-wrap max-h-64 overflow-y-auto\">{task.result}</div>\n </div>\n )}\n\n {/* Events */}\n {events.length > 0 && (\n <div className=\"bg-[#161618] border border-[#26262b] rounded-xl p-4\">\n <div className=\"text-xs text-gray-500 uppercase mb-2\">Events ({events.length})</div>\n <div className=\"space-y-1.5 max-h-40 overflow-y-auto\">\n {events.map(e => (\n <div key={e.id} className=\"flex items-center gap-2 text-[11px]\">\n <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${\n e.to_status === 'running' ? 'bg-green-400' : e.to_status === 'replied' ? 'bg-purple-400' : e.to_status === 'failed' ? 'bg-red-400' : 'bg-blue-400'\n }`} />\n <span className=\"text-gray-400\">{e.event_type}</span>\n {e.from_status && <span className=\"text-gray-600\">{e.from_status}→{e.to_status}</span>}\n <span className=\"text-gray-600 ml-auto\">{timeAgo(e.created_at)}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Metadata */}\n <div className=\"text-[10px] text-gray-600 space-y-1\">\n <div>Task ID: {task.task_id}</div>\n {task.expires_at && <div>Expires: {task.expires_at}</div>}\n </div>\n </div>\n )}\n </div>\n </>\n );\n}\n"],"names":["STATUS_COLORS","created","delivered","running","replied","failed","closed","TaskDrawer","taskId","onClose","task","setTask","events","setEvents","loading","setLoading","taskRes","eventsRes","Promise","all","fetch","encodeURIComponent","taskData","json","eventsData","tasks","timeline","key","label","time","created_at","color","delivered_at","started_at","completed_at","map","s","done","currentStepIdx","findIndex","isActive","status","duration","Math","round","Date","getTime","className","onClick","slice","fill","viewBox","stroke","strokeWidth","strokeLinecap","strokeLinejoin","d","priority","floor","from_name","alias","size","to_name","step","i","isCurrent","isNextDone","style","borderColor","length","title","undefined","content","result","e","to_status","event_type","from_status","id","task_id","expires_at"],"mappings":"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"}
|
|
@@ -7,9 +7,9 @@ globalThis.__BUILD_MANIFEST = {
|
|
|
7
7
|
"static/chunks/03~yq9q893hmn.js"
|
|
8
8
|
],
|
|
9
9
|
"lowPriorityFiles": [
|
|
10
|
-
"static/
|
|
11
|
-
"static/
|
|
12
|
-
"static/
|
|
10
|
+
"static/tRPXkJdGLR6a0skqvMgQa/_buildManifest.js",
|
|
11
|
+
"static/tRPXkJdGLR6a0skqvMgQa/_ssgManifest.js",
|
|
12
|
+
"static/tRPXkJdGLR6a0skqvMgQa/_clientMiddlewareManifest.js"
|
|
13
13
|
],
|
|
14
14
|
"rootMainFiles": [
|
|
15
15
|
"static/chunks/05oi25hh7b81r.js",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/agent-network-dashboard/app/_not-found/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/admin/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/login/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/logs/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/messages/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/node/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/nodes/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/server-logs/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/servers/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/networks/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/tokens/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/tasks/[id]/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/tasks/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
|
|
1
|
+
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/agent-network-dashboard/app/_not-found/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/admin/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/login/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/logs/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/messages/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/node/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/nodes/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/providers/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/server-logs/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/servers/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/networks/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/settings/tokens/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/tasks/[id]/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ],\n \"[project]/agent-network-dashboard/app/tasks/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2\",\n \"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2",
|
|
33
33
|
"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2"
|
|
34
34
|
],
|
|
35
|
+
"[project]/agent-network-dashboard/app/providers/page": [
|
|
36
|
+
"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2",
|
|
37
|
+
"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2"
|
|
38
|
+
],
|
|
35
39
|
"[project]/agent-network-dashboard/app/server-logs/page": [
|
|
36
40
|
"static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2",
|
|
37
41
|
"static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2"
|