fix: remove stale missing-capability fallbacks
Some checks failed
StoryForge CI / Baseline checks (push) Has been cancelled
StoryForge CI / Backend tests (push) Has been cancelled
StoryForge CI / Web tests (push) Has been cancelled

This commit is contained in:
kris
2026-03-30 22:06:05 +08:00
parent 9317d4c0a5
commit 3f3c8de949
3 changed files with 38 additions and 74 deletions

View File

@@ -32,6 +32,7 @@
- 任务恢复链会优先真实调用 `/v2/explore/jobs/{job_id}/retry`,只有接口真的不存在时才回退到手动恢复模板。
- `找对标 / 跟踪账号` 里一批已经失效的 “当前平台待接入” 按钮禁用与入口分支已删除,当前 active 平台都直接走真实路由,失败时再给真实反馈。
- 工作台前端已经清掉浏览器 `alert` 弹窗,缺对象、权限不足、刷新失败和加载失败都会回到站内反馈,不再把用户从当前流程里打断出去。
- `OneLiner 会话 / 主 Agent 运行 / 动作执行器 / 跟踪同步 / 高分分析 / 平台技能验收` 这批真接口也已经去掉“当前实例未提供”的旧降级口径,统一按 live 结果说话。
### NAS 联调与回归
@@ -39,7 +40,7 @@
- Web: `http://192.168.31.188:19192/`
- Collector: `http://192.168.31.188:19193/healthz`
- 当前基线通过:
- 前端测试 `61/61`
- 前端测试 `62/62`
- `bash scripts/check_repo_baseline.sh`
- `bash scripts/smoke_fnos_storyforge_lan.sh`

View File

@@ -1845,11 +1845,6 @@ async function ensureOneLinerSession() {
project_id: projectId,
preferred_platform: getPreferredPlatform()
}
}).catch((error) => {
if (isMissingBackendCapability(error)) {
throw new Error("当前实例还没有开放 OneLiner 会话接口。");
}
throw error;
});
appState.onelinerSessions = [session, ...safeArray(appState.onelinerSessions)];
appState.selectedOnelinerSessionId = session.id;
@@ -1897,11 +1892,6 @@ async function createOneLinerRun(runRequest) {
scheduling_mode: "queued",
...runRequest
}
}).catch((error) => {
if (isMissingBackendCapability(error)) {
throw new Error("当前实例还没有开放主 Agent 运行层。");
}
throw error;
});
await loadAgentControlSurfaces(projectId);
appState.selectedOnelinerRunId = payload?.id || choosePreferredOneLinerRunId(appState.onelinerRuns, "");
@@ -2197,11 +2187,6 @@ async function executeOneLinerAction(executorKey, options = {}) {
session_id: options.sessionId || session?.id || "",
payload: options.payload || {}
}
}).catch((error) => {
if (isMissingBackendCapability(error)) {
throw new Error("当前实例还没有开放 OneLiner 动作执行器。");
}
throw error;
});
await loadAgentControlSurfaces(projectId);
if (appState.selectedOnelinerSessionId) {
@@ -2590,19 +2575,10 @@ async function markTrackingDigestRead() {
const platform = getCurrentPlatformValue();
const trackingCursorPath = getWorkbenchRoute(platform, "trackingCursor");
const nextSeenAt = new Date().toISOString();
try {
await storyforgeFetch(trackingCursorPath, {
method: "POST",
body: { last_seen_at: nextSeenAt }
});
} catch (error) {
if (isMissingBackendCapability(error)) {
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放跟踪已读游标接口。`, "orange");
renderAll();
return;
}
throw error;
}
await storyforgeFetch(trackingCursorPath, {
method: "POST",
body: { last_seen_at: nextSeenAt }
});
appState.trackingCursorMap = {
...(appState.trackingCursorMap || {}),
[platform]: nextSeenAt
@@ -2624,19 +2600,9 @@ async function refreshTrackingAccountsAction() {
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingRefresh");
setBusy(true, "正在同步跟踪账号...");
try {
let payload;
try {
payload = await storyforgeFetch(trackingRefreshPath, {
method: "POST"
});
} catch (error) {
if (isMissingBackendCapability(error)) {
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放批量跟踪同步。`, "orange");
renderAll();
return;
}
throw error;
}
const payload = await storyforgeFetch(trackingRefreshPath, {
method: "POST"
});
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "batch");
rememberTrackingRefreshNotice(refreshNotice);
rememberAction(
@@ -2660,19 +2626,9 @@ async function refreshTrackedAccountAction(trackedAccountId) {
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingAccountRefresh", trackedAccountId);
setBusy(true, "正在同步该跟踪账号...");
try {
let payload;
try {
payload = await storyforgeFetch(trackingRefreshPath, {
method: "POST"
});
} catch (error) {
if (isMissingBackendCapability(error)) {
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放单账号跟踪同步。`, "orange");
renderAll();
return;
}
throw error;
}
const payload = await storyforgeFetch(trackingRefreshPath, {
method: "POST"
});
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "single");
rememberTrackingRefreshNotice(refreshNotice);
const success = payload.success !== false;
@@ -9321,11 +9277,6 @@ function openPlatformSkillReviewAction(platform, skillId, accepted) {
summary: values.summary || "",
review_notes: values.reviewNotes || ""
}
}).catch((error) => {
if (isMissingBackendCapability(error)) {
throw new Error("当前实例还没有开放平台技能验收接口。");
}
throw error;
});
rememberAction(
accepted ? "平台技能已通过" : "平台技能待优化",
@@ -9590,15 +9541,7 @@ function openAnalyzeTopVideosAction() {
min_score: Number(values.minScore || 45),
temperature: 0.25
}
}).catch((error) => {
if (isMissingBackendCapability(error)) {
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放高分作品批量分析。`, "orange");
renderAll();
return null;
}
throw error;
});
if (!result) return;
appState.topVideoAnalysisResults = {
...(appState.topVideoAnalysisResults || {}),
[account.id]: {
@@ -10700,7 +10643,11 @@ document.addEventListener("click", async (event) => {
return;
}
if (name === "refresh-tracking") {
await refreshTrackingAccountsAction();
try {
await refreshTrackingAccountsAction();
} catch (error) {
presentActionFailure(error, "刷新跟踪账号失败");
}
return;
}
if (name === "open-live-recorder") {
@@ -10736,9 +10683,13 @@ document.addEventListener("click", async (event) => {
return;
}
if (name === "mark-tracking-read") {
await markTrackingDigestRead();
rememberAction("日报已标记", "当前跟踪摘要已更新为已读,下次会从新的时间点继续汇总。", "green");
await bootstrap();
try {
await markTrackingDigestRead();
rememberAction("日报已标记", "当前跟踪摘要已更新为已读,下次会从新的时间点继续汇总。", "green");
await bootstrap();
} catch (error) {
presentActionFailure(error, "标记日报已读失败");
}
return;
}
if (name === "logout-session") {
@@ -10824,7 +10775,11 @@ document.addEventListener("click", async (event) => {
return;
}
if (name === "refresh-tracked-account") {
await refreshTrackedAccountAction(action.dataset.trackedAccountId || "");
try {
await refreshTrackedAccountAction(action.dataset.trackedAccountId || "");
} catch (error) {
presentActionFailure(error, "同步跟踪账号失败");
}
return;
}
if (name === "open-import-video-link") {

View File

@@ -332,7 +332,7 @@ test("tracking refresh and top-video analysis flows expose async feedback inside
assert.doesNotMatch(skillReview, /当前后端还没有接入平台技能验收接口/);
assert.ok(!agentDetail.includes('backendSupports("/v2/platform-agents/{platform}/skills/{skill_id}/versions")'));
assert.doesNotMatch(topVideoAction, /.*/s);
assert.match(topVideoAction, /当前实例未提供/);
assert.doesNotMatch(topVideoAction, /当前实例未提供/);
assert.ok(!jobRecoverability.includes('backendSupports("/v2/explore/jobs/{job_id}/retry") && uploadedPath'));
assert.ok(!recoveryAction.includes('if (backendSupports("/v2/explore/jobs/{job_id}/retry"))'));
assert.ok(!clickActions.includes('else if (backendSupports("/v2/oneliner/sessions"))'));
@@ -789,3 +789,11 @@ test("workbench interaction flow avoids browser alerts and keeps failures inside
assert.match(clicks, /name === "show-disabled-reason"[\s\S]*rememberAction\("动作已拦截"/);
assert.match(clicks, /name === "auth-refresh" \|\| name === "refresh-data"[\s\S]*presentActionFailure\(error, "刷新数据失败"\)/);
});
test("live-first workbench flows no longer advertise stale missing-capability placeholders for active routes", () => {
assert.doesNotMatch(APP, /当前实例还没有开放 OneLiner 会话接口/);
assert.doesNotMatch(APP, /当前实例还没有开放主 Agent 运行层/);
assert.doesNotMatch(APP, /当前实例还没有开放 OneLiner 动作执行器/);
assert.doesNotMatch(APP, /当前实例还没有开放平台技能验收接口/);
assert.doesNotMatch(APP, /当前实例未提供/);
});