Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/rl/agent-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Agentic RL 的性能问题常表现为 GPU 空转,根因却可能在 Sandbox
Web UI:Rollout / Train / Spans / Perfetto / Inference
```

框架在关键边界打 Span 并传递 `rollout_id`、`sample_id`、`phase` 等**通用属性**;Web UI 只读这些契约字段,不依赖框架私有 span 名称(契约定义见 `web/src/rl_contract.rs`)。因此同一套 UI 可对接多种 RL 栈。
框架在关键边界打 Span 并传递 `rollout_id`、`sample_id`、`phase` 等**通用属性**;Web UI 只读这些契约字段,不依赖框架私有 span 名称(查询与转换见 `web/src/api/rl.rs`,页面消费见 `web/src/next/pages/rl.rs`)。因此同一套 UI 可对接多种 RL 栈。

---

Expand Down
7 changes: 2 additions & 5 deletions docs/rl/inference-engine-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,10 @@ SGLang 指标端点(/metrics 或 /engine_metrics)
在仓库根目录执行(需已安装 [Dioxus CLI](https://dioxuslabs.com/learn/0.6/getting_started/) `dx`):

```bash
cd web
dx build --release
mkdir -p dist
cp -r target/dx/web/release/web/public/* dist/
make frontend
```

完成后存在 `web/dist/index.html`,后续将 `PROBING_ASSETS_ROOT` 设为 `web/dist`。
完成后 `web/dist` 会链接到嵌入式 Web 产物目录;如需显式磁盘覆盖,可将 `PROBING_ASSETS_ROOT` 设为 `web/dist`。

### 步骤 1:启动 SGLang 推理服务

Expand Down
2 changes: 1 addition & 1 deletion docs/src/design/modularity.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ Use this table to decide **where a change belongs**:
| Auth, request limits | probing-server | middleware |
| Inject, query CLI | probing-cli | HTTP to server |
| Diagnostic skills | skills/ | steps.yaml |
| Training step matrix UI | web/pages/training | GET `/apis/training/step_matrix` |
| Training step matrix UI | web/src/next/pages/training.rs | GET `/apis/training/step_matrix` |
| Agent routing | web/agent + skills catalog | skill metadata |

---
Expand Down
2 changes: 1 addition & 1 deletion docs/src/design/modularity.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ sequenceDiagram
| 认证、限流 | probing-server | middleware |
| inject、query CLI | probing-cli | HTTP → server |
| 诊断 skill | skills/ | steps.yaml |
| Training step 矩阵 UI | web/pages/training | `GET /apis/training/step_matrix` |
| Training step 矩阵 UI | web/src/next/pages/training.rs | `GET /apis/training/step_matrix` |
| Agent 路由 | web/agent + skills catalog | skill 元数据 |

---
Expand Down
2 changes: 0 additions & 2 deletions web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ dioxus-web = "0.7.9"
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"

# HTTP client
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
urlencoding = "2.1"

# Error handling
anyhow = "1.0"
thiserror = "1.0"

# Logging
Expand Down
31 changes: 15 additions & 16 deletions web/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ web/src/next/
| 证据 | `/spans`、`/stacks/*`、`/profiles`、`/profiling/:view` |
| 工具 | `/analytics`、`/python`、`/pulsing`、`/cluster`、`/system` |

Shell 挂载 ⌘K Command Panel、全局快捷键、Investigation URL 同步、页面 evidence snapshot、后台任务与 Torch overhead monitor,以及可浮动的 Investigate 面板。主内容区不设固定顶栏。未知 URL 由 `ClassicFallback`(历史命名)落到能力目录引导页,不再切回旧 UI
Shell 挂载 ⌘K Command Panel、全局快捷键、Investigation URL 同步、页面 evidence snapshot、后台任务与 Torch overhead monitor,以及可浮动的 Investigate 面板。主内容区不设固定顶栏。未知 URL 由 `NotFound` 路由落到能力目录引导页

**新页面**放在 `web/src/next/pages/`,在 `routes.rs` 注册,并在 `page_registry.rs` 声明 page spec。

Expand Down Expand Up @@ -66,11 +66,10 @@ Probing Web 是 **训练/推理现场的 live 诊断工作台**,不是 experim
| `AppOverlays` | 侧栏 Monitors 点击 / `file:line` | 根级 viewport overlay(任务队列、Torch overhead、源码预览) |
| `GlobalCommandPanel` | 侧栏搜索 / ⌘K | SQL / eval REPL;不常驻输入条 |
| `AgentPanel` | ⌘J(`/agent` 全页时禁用浮层) | 右侧浮层 Investigate |
| (已移除)InvestigationContextHint | — | 调查上下文由 Next 页内固定条承载 |
| `SidebarMonitors` | — | 侧栏底部紧凑摘要(Tasks + Torch overhead);点击打开对应 overlay |
| Monitor rail actions | 侧栏底部 Tasks / Overhead | 展示任务摘要并打开对应 overlay |
| `LlmSettingsOverlay` | Agent ⚙ | LLM API 配置(localStorage) |
| `ShortcutsHelpOverlay` | `?` | 快捷键帮助 |
| `PageContextSync` | | 已由 `NextShell` + `page_snapshot` 取代 |
| `page_snapshot` | 路由或调查坐标变化 | `NextShell` 向 Agent 发布当前页面证据 |
| `InvestigationUrlSync` | — | 上下文 ↔ URL query 双向同步 |
| `UiTaskRuntime` | — | 全局任务计时 tick |

Expand Down Expand Up @@ -133,14 +132,14 @@ APP_OVERLAY: None | SourceViewer(path, line) | Monitor(Tasks | Overhead)

### 2.3 页面与状态组件

**经典页面模式**(Dashboard、Cluster、Analytics 等):
**统一页面模式**(Dashboard、Cluster、Analytics 等):

- `PageContainer` + `PageTitle` + 若干 `Card` / `StatCard`
- 异步数据:`AsyncBoundary` + `use_app_resource`;poll 页配合 `use_poll_tick_gated` + `PollStatusBar`。
- `next/components.rs` 的 `WorkspacePage` + `NextPageHeader` + 若干 `SectionCard` / evidence panel
- 异步数据:页面按资源状态使用 `LoadingPanel` / `UnavailablePanel`;需要 Suspense 时使用 `AsyncBoundary`,轮询配合 `use_poll_tick_gated` + `PollStatusBar`。

**Workspace 模式**(Agent、部分新面板):
**可分栏工作区**(Agent、时间线等):

- `workspace/panel_shell.rs`、`surface.rs`、`split.rs` — 统一 Agent 与浮层视觉
- `components/workspace/surface.rs`、`split.rs` — 统一可调整分栏和 surface 视觉

**反馈状态**(`components/common.rs`):

Expand Down Expand Up @@ -192,7 +191,7 @@ Tasks / Overhead 紧凑状态行
|------|------|------|
| 状态 | `state/investigation.rs` | `INVESTIGATION_CONTEXT`(step、rank、host、trace_id、span、pid/tid) |
| URL | `state/investigation_url.rs` | query 参数读写、与 localStorage 同步 |
| 提示 | `components/investigation_context_hint.rs` | 页内空状态 / 上下文引导 |
| 固定条 | `next/components.rs` | `InvestigationBar` 展示当前坐标及页面支持状态 |

固定上下文以紧凑的 blue-50 调查条显示,字段写入 URL 和 localStorage;调查条、侧栏轨道和侧栏子视图都使用包含完整坐标的 durable link,普通跳转、复制链接和新标签页不得丢失上下文。Hover 只做预览,Click/键盘选择才固定上下文。

Expand All @@ -219,9 +218,9 @@ Cluster Nodes 在 registry 表格上提供 Rank、Host、GPU、endpoint、role
| `ui_agent_busy()` | Agent 输入禁用、chip disabled |
| `UI_TASK_TICK` | 500ms tick,驱动侧栏 Monitors elapsed 显示 |

**任务种类**(`UiTaskKind`):`Agent` · `Snapshot` · `Skill` · `Query`(Query 预留,Command Panel 待接入)
**任务种类**(`UiTaskKind`):`Agent` · `Snapshot` · `Skill`。

**UI 入口**:侧栏 `SidebarMonitors` 摘要 → `AppOverlays::TasksMonitorOverlay` 全屏列表(可 Cancel all / Clear finished)。
**UI 入口**:侧栏 Tasks rail action → `AppOverlays::TasksMonitorOverlay` 全屏列表(可 Cancel all / Clear finished)。

---

Expand All @@ -235,7 +234,7 @@ Cluster Nodes 在 registry 表格上提供 Rank、Host、GPU、endpoint、role
| SQL | `overhead/sql.rs` | 固定窗口 SQL(`WINDOW_STEPS=80` 等常量) |
| API | `api/overhead.rs` | `fetch_overhead_summary`、NCCL counters 可选 |
| UI | `components/overhead/panel.rs` | `TorchOverheadPanel` 表格与脚注 |
| 侧栏 | `components/sidebar/monitors.rs` | 轮询摘要 + 打开 `OverheadMonitorOverlay` |
| 入口 | `next/sidebar.rs` + `components/app_overlays.rs` | 侧栏触发并渲染 `OverheadMonitorOverlay` |

轮询间隔:`OVERHEAD_POLL_MS`(2000ms),页面不可见时 `use_poll_tick_gated` 暂停。

Expand Down Expand Up @@ -343,7 +342,7 @@ web/src/

## 九、构建与部署

- 开发 / 构建:`dx serve` / `dx build --release`;仓库根 `make frontend` 复制产物到 `web/dist/`。
- 开发 / 构建:`dx serve` / `dx bundle --release`;仓库根 `make frontend` 将产物嵌入 `probing/server/web-assets/`,并把 `web/dist/` 链接到该目录
- UI 静态资源由 `make frontend` 生成到被 Git 忽略的 `probing/server/web-assets/`,build script 将其复制到 `$OUT_DIR` 后通过 `include_dir` 编译进 `probing._core`;没有前端产物的普通 Rust 构建使用轻量 fallback,`PROBING_ASSETS_ROOT` 仅作为开发期显式磁盘覆盖。

---
Expand All @@ -352,9 +351,9 @@ web/src/

以下为当前实现与理想状态之间的差距,供迭代参考(非阻塞发布):

**已修复(历史 P0)**:Classic `pages/stack.rs` 侧栏帧计数改为 `use_effect`;删除 `chrome_tracing_iframe`;Playbook 体系迁移为 Skills + `probing-skills`。
**已完成的架构收敛**:Classic 页面与 iframe tracing 已删除;Playbook 体系已迁移为 Skills + `probing-skills`。

**重构后已落地**:`SidebarMonitors` + `AppOverlays`;`overhead/` 领域模块;runtime skill 加载;`OverlayShell` 统一 modal。
**重构后已落地**:Next sidebar + `AppOverlays`;`overhead/` 领域模块;runtime skill 加载;`OverlayShell` 统一 modal。

1. **全局 Esc 与 monitor overlay** — `keyboard_shortcuts.rs` 未调用 `close_app_overlay()`;Tasks/Overhead 仅依赖 `OverlayShell` 局部 Esc。
2. **`/traces` 与 `/spans` 重复** — 侧栏仅推广 `/spans`;`/traces` 保留兼容 redirect。
Expand Down
20 changes: 0 additions & 20 deletions web/src/agent/skill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use serde_json::Value;
pub struct RoutingPayload {
pub catalog: CatalogPayload,
pub intents: IntentCatalogFile,
pub pages: PageCatalogFile,
}

#[derive(Debug, Clone, Deserialize)]
Expand Down Expand Up @@ -50,31 +49,13 @@ pub struct IntentEntry {
pub skills: Vec<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct PageCatalogFile {
#[serde(default)]
pub pages: HashMap<String, PageEntry>,
}

#[derive(Debug, Clone, Deserialize)]
#[allow(dead_code)] // Deserialized from routing API; not read after Classic page catalog removal.
pub struct PageEntry {
pub title: String,
pub path: String,
#[serde(default)]
pub description: String,
#[serde(default)]
pub skills: Vec<String>,
}

pub type SkillPayload = Value;

#[derive(Debug, Default)]
struct SkillStore {
skills: HashMap<String, Skill>,
catalog: Vec<CatalogEntry>,
intents: HashMap<String, IntentEntry>,
pages: HashMap<String, PageEntry>,
loaded: bool,
}

Expand All @@ -99,7 +80,6 @@ pub fn populate_skill_store(routing: RoutingPayload, payloads: Vec<SkillPayload>
if let Ok(mut guard) = store().write() {
guard.catalog = routing.catalog.skills;
guard.intents = routing.intents.intents;
guard.pages = routing.pages.pages;
guard.skills = skills;
guard.loaded = true;
}
Expand Down
41 changes: 9 additions & 32 deletions web/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,35 +268,12 @@ mod trace;
mod traces;
mod training;

#[allow(unused_imports)]
pub use analytics::*;
#[allow(unused_imports)]
pub use cluster::*;
#[allow(unused_imports)]
pub use cpu::*;
#[allow(unused_imports)]
pub use dashboard::*;
#[allow(unused_imports)]
pub use gpu::*;
#[allow(unused_imports)]
pub use overhead::*;
#[allow(unused_imports)]
pub use profiling::*;
#[allow(unused_imports)]
pub use pulsing::*;
#[allow(unused_imports)]
pub use pytorch::*;
#[allow(unused_imports)]
pub use repl::*;
#[allow(unused_imports)]
pub use rl::*;
#[allow(unused_imports)]
pub use skills::*;
#[allow(unused_imports)]
pub use stack::*;
#[allow(unused_imports)]
pub use trace::*;
#[allow(unused_imports)]
pub use traces::*;
#[allow(unused_imports)]
pub use training::*;
pub use cpu::{format_cpu_ms, CpuHistorySample, CpuSnapshot, CpuThreadRow};
pub use gpu::{GpuHistorySample, GpuSnapshot};
pub use overhead::{empty_dataframe, is_nccl_counters_missing, OVERHEAD_POLL_MS};
pub use pytorch::{ProfileResponse, RuntimeDebugResponse, TcpStoreSnapshot, WaitCounterSnapshot};
pub use repl::{MagicGroup, MagicItem};
pub use rl::EngineInfo;
pub use trace::{TraceableItem, VariableRecord};
pub use traces::SpanInfo;
pub use training::{StepDurationSample, StepMatrixResponse};
61 changes: 0 additions & 61 deletions web/src/components/colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,15 @@
// - Main content area: Light gray/indigo background (clear, readable)
// - Accent color: blue (consistent with sidebar, maintains visual unity)

#[allow(dead_code)]
#[allow(clippy::module_inception)]
pub mod colors {
pub const PRIMARY: &str = "blue-600";
pub const PRIMARY_HOVER: &str = "blue-700";
pub const PRIMARY_BG: &str = "blue-600/30";
pub const PRIMARY_TEXT: &str = "blue-100";
pub const PRIMARY_TEXT_DARK: &str = "blue-400";
pub const PRIMARY_BORDER: &str = "blue-500";

/// Secondary button (inactive outline)
pub const BTN_SECONDARY_BG: &str = "gray-100";
pub const BTN_SECONDARY_HOVER: &str = "gray-200";

pub const SIDEBAR_BG: &str = "slate-900";
pub const SIDEBAR_BG_VIA: &str = "slate-800";
pub const SIDEBAR_BORDER: &str = "slate-700/30";
pub const SIDEBAR_TEXT_PRIMARY: &str = "slate-100";
pub const SIDEBAR_TEXT_SECONDARY: &str = "slate-300";
pub const SIDEBAR_TEXT_MUTED: &str = "slate-400";
pub const SIDEBAR_HOVER_BG: &str = "slate-800/50";
pub const SIDEBAR_ACTIVE_BG: &str = "slate-700";
pub const SIDEBAR_INPUT_BG: &str = "slate-800";
pub const SIDEBAR_INPUT_BORDER: &str = "slate-600";

pub const CONTENT_BG: &str = "gray-50";
pub const CONTENT_BG_ACCENT: &str = "indigo-50/30";
pub const CONTENT_CARD_BG: &str = "white";
pub const CONTENT_BORDER: &str = "gray-200";
pub const CONTENT_TEXT_PRIMARY: &str = "gray-900";
pub const CONTENT_TEXT_SECONDARY: &str = "gray-600";
pub const CONTENT_TEXT_MUTED: &str = "gray-500";

pub const SUCCESS: &str = "green-600";
pub const SUCCESS_HOVER: &str = "green-700";
pub const SUCCESS_LIGHT: &str = "green-50";
pub const SUCCESS_TEXT: &str = "green-800";
pub const SUCCESS_BORDER: &str = "green-200";

pub const ERROR: &str = "red-600";
pub const ERROR_HOVER: &str = "red-700";
pub const ERROR_LIGHT: &str = "red-50";
pub const ERROR_TEXT: &str = "red-800";
pub const ERROR_BORDER: &str = "red-200";
Expand All @@ -55,33 +23,4 @@ pub mod colors {
pub const CONTENT_ACCENT_BG: &str = "blue-50";
pub const CONTENT_ACCENT_TEXT: &str = "blue-700";
pub const CONTENT_ACCENT_BORDER: &str = "blue-200";

pub const WARNING: &str = "yellow-600";
pub const WARNING_LIGHT: &str = "yellow-50";
pub const WARNING_TEXT: &str = "yellow-800";

// Composite Tailwind class strings (must be literals for the CSS build to include them).
pub const SIDEBAR_ASIDE: &str = "bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 border-r border-slate-700/30 h-screen flex flex-col flex-shrink-0 shadow-xl";
pub const SIDEBAR_LOGO_BORDER: &str = "px-4 py-3 border-b border-slate-700/30";
pub const SIDEBAR_BRAND: &str = "text-base font-semibold text-slate-100";
pub const SIDEBAR_FOOTER: &str = "px-4 py-3 border-t border-slate-700/30";
pub const SIDEBAR_FOOTER_LINK: &str =
"flex items-center gap-2 text-xs text-slate-400 hover:text-blue-400 transition-colors";
pub const SIDEBAR_HIDE_BTN: &str = "absolute top-4 -right-3 w-6 h-6 bg-slate-700 border border-slate-700 rounded-full shadow-lg flex items-center justify-center hover:bg-slate-600 z-30 transition-colors";

pub const SIDEBAR_ITEM_ACTIVE: &str = "flex items-center gap-2 px-2 py-1.5 text-sm font-medium rounded-md bg-blue-600/30 text-blue-100 border-l-2 border-blue-500";
pub const SIDEBAR_ITEM_INACTIVE: &str = "flex items-center gap-2 px-2 py-1.5 text-sm font-medium rounded-md text-slate-300 hover:bg-slate-800/50 hover:text-blue-100 transition-colors";

pub const SIDEBAR_PANEL_BORDER: &str = "mt-4 pt-4 border-t border-slate-700/30";

pub const SIDEBAR_CONTROL_TITLE: &str = "text-xs font-semibold text-slate-300";
pub const SIDEBAR_CONTROL_VALUE: &str = "text-xs text-slate-400";
pub const SIDEBAR_TOGGLE_ON: &str =
"relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors bg-blue-600";
pub const SIDEBAR_TOGGLE_OFF: &str =
"relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors bg-slate-700";
pub const SIDEBAR_TOGGLE_LABEL: &str = "text-xs text-slate-300";
pub const SIDEBAR_INPUT: &str = "w-full px-2 py-1 border border-slate-600 bg-slate-800 text-slate-300 rounded text-xs focus:border-blue-500 focus:outline-none";
pub const SIDEBAR_RESIZE_HOVER: &str = "hover:bg-blue-600/50";
pub const SIDEBAR_RESIZE_ACTIVE: &str = "bg-blue-600";
}
2 changes: 1 addition & 1 deletion web/src/next/page_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ impl NextRoute {
"Toolbox",
DeepTools
),
Self::Explore {} | Self::ClassicFallback { .. } => page!(
Self::Explore {} | Self::NotFound { .. } => page!(
"explore",
"Capability Catalog",
"/explore",
Expand Down
4 changes: 2 additions & 2 deletions web/src/next/page_snapshot.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Native Next-page evidence snapshots consumed by the Investigate panel.
//!
//! This module deliberately speaks in Next routes and evidence requests. It
//! must not translate through Classic routes: page UI and Agent context should
//! must not translate through removed legacy routes: page UI and Agent context should
//! use the same scope and investigation coordinates.

use dioxus::prelude::ReadableExt;
Expand Down Expand Up @@ -485,7 +485,7 @@ mod tests {
use super::*;

#[test]
fn next_snapshot_routes_do_not_require_classic_route_identity() {
fn snapshot_ids_follow_canonical_routes() {
assert_eq!(NextRoute::Memory {}.snapshot_id(), "memory");
assert_eq!(NextRoute::Training {}.snapshot_id(), "training");
assert_eq!(NextRoute::Cluster {}.snapshot_id(), "cluster-nodes");
Expand Down
4 changes: 2 additions & 2 deletions web/src/next/pages/explore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn canonical_capability_routes() -> Vec<NextRoute> {
}

#[component]
pub fn ClassicFallbackPage(segments: Vec<String>) -> Element {
pub fn NotFoundPage(segments: Vec<String>) -> Element {
let path = format!("/{}", segments.join("/"));
let explore_href = evidence_href(
&NextRoute::Explore {},
Expand Down Expand Up @@ -163,7 +163,7 @@ mod tests {
let routes = canonical_capability_routes();
assert!(routes.iter().all(|route| {
route.page_spec().canonical_path != "/explore"
&& !matches!(route, NextRoute::ClassicFallback { .. })
&& !matches!(route, NextRoute::NotFound { .. })
}));
}
}
12 changes: 1 addition & 11 deletions web/src/next/pages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use analytics::AnalyticsPage;
pub use cluster::ClusterPage;
pub use dashboard::DashboardPage;
pub use distributed::{DistributedPage, DistributedStatusPage};
pub use explore::{ClassicFallbackPage, ExplorePage};
pub use explore::{ExplorePage, NotFoundPage};
pub use inference::InferencePage;
pub use investigate::InvestigatePage;
pub(crate) use investigate::InvestigateSession;
Expand Down Expand Up @@ -56,16 +56,6 @@ mod architecture_tests {
("investigate", include_str!("investigate.rs")),
];

#[test]
fn workspace_pages_do_not_import_classic_pages() {
for (name, source) in WORKSPACE_PAGES {
assert!(
!source.contains("crate::pages::"),
"{name} must not mount a Classic page"
);
}
}

#[test]
fn product_pages_share_the_next_workspace_frame() {
for (name, source) in WORKSPACE_PAGES
Expand Down
Loading
Loading