fix: remove stale missing-capability fallbacks
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
- 任务恢复链会优先真实调用 `/v2/explore/jobs/{job_id}/retry`,只有接口真的不存在时才回退到手动恢复模板。
|
- 任务恢复链会优先真实调用 `/v2/explore/jobs/{job_id}/retry`,只有接口真的不存在时才回退到手动恢复模板。
|
||||||
- `找对标 / 跟踪账号` 里一批已经失效的 “当前平台待接入” 按钮禁用与入口分支已删除,当前 active 平台都直接走真实路由,失败时再给真实反馈。
|
- `找对标 / 跟踪账号` 里一批已经失效的 “当前平台待接入” 按钮禁用与入口分支已删除,当前 active 平台都直接走真实路由,失败时再给真实反馈。
|
||||||
- 工作台前端已经清掉浏览器 `alert` 弹窗,缺对象、权限不足、刷新失败和加载失败都会回到站内反馈,不再把用户从当前流程里打断出去。
|
- 工作台前端已经清掉浏览器 `alert` 弹窗,缺对象、权限不足、刷新失败和加载失败都会回到站内反馈,不再把用户从当前流程里打断出去。
|
||||||
|
- `OneLiner 会话 / 主 Agent 运行 / 动作执行器 / 跟踪同步 / 高分分析 / 平台技能验收` 这批真接口也已经去掉“当前实例未提供”的旧降级口径,统一按 live 结果说话。
|
||||||
|
|
||||||
### NAS 联调与回归
|
### NAS 联调与回归
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@
|
|||||||
- Web: `http://192.168.31.188:19192/`
|
- Web: `http://192.168.31.188:19192/`
|
||||||
- Collector: `http://192.168.31.188:19193/healthz`
|
- Collector: `http://192.168.31.188:19193/healthz`
|
||||||
- 当前基线通过:
|
- 当前基线通过:
|
||||||
- 前端测试 `61/61`
|
- 前端测试 `62/62`
|
||||||
- `bash scripts/check_repo_baseline.sh`
|
- `bash scripts/check_repo_baseline.sh`
|
||||||
- `bash scripts/smoke_fnos_storyforge_lan.sh`
|
- `bash scripts/smoke_fnos_storyforge_lan.sh`
|
||||||
|
|
||||||
|
|||||||
@@ -1845,11 +1845,6 @@ async function ensureOneLinerSession() {
|
|||||||
project_id: projectId,
|
project_id: projectId,
|
||||||
preferred_platform: getPreferredPlatform()
|
preferred_platform: getPreferredPlatform()
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
throw new Error("当前实例还没有开放 OneLiner 会话接口。");
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
});
|
||||||
appState.onelinerSessions = [session, ...safeArray(appState.onelinerSessions)];
|
appState.onelinerSessions = [session, ...safeArray(appState.onelinerSessions)];
|
||||||
appState.selectedOnelinerSessionId = session.id;
|
appState.selectedOnelinerSessionId = session.id;
|
||||||
@@ -1897,11 +1892,6 @@ async function createOneLinerRun(runRequest) {
|
|||||||
scheduling_mode: "queued",
|
scheduling_mode: "queued",
|
||||||
...runRequest
|
...runRequest
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
throw new Error("当前实例还没有开放主 Agent 运行层。");
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
});
|
||||||
await loadAgentControlSurfaces(projectId);
|
await loadAgentControlSurfaces(projectId);
|
||||||
appState.selectedOnelinerRunId = payload?.id || choosePreferredOneLinerRunId(appState.onelinerRuns, "");
|
appState.selectedOnelinerRunId = payload?.id || choosePreferredOneLinerRunId(appState.onelinerRuns, "");
|
||||||
@@ -2197,11 +2187,6 @@ async function executeOneLinerAction(executorKey, options = {}) {
|
|||||||
session_id: options.sessionId || session?.id || "",
|
session_id: options.sessionId || session?.id || "",
|
||||||
payload: options.payload || {}
|
payload: options.payload || {}
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
throw new Error("当前实例还没有开放 OneLiner 动作执行器。");
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
});
|
||||||
await loadAgentControlSurfaces(projectId);
|
await loadAgentControlSurfaces(projectId);
|
||||||
if (appState.selectedOnelinerSessionId) {
|
if (appState.selectedOnelinerSessionId) {
|
||||||
@@ -2590,19 +2575,10 @@ async function markTrackingDigestRead() {
|
|||||||
const platform = getCurrentPlatformValue();
|
const platform = getCurrentPlatformValue();
|
||||||
const trackingCursorPath = getWorkbenchRoute(platform, "trackingCursor");
|
const trackingCursorPath = getWorkbenchRoute(platform, "trackingCursor");
|
||||||
const nextSeenAt = new Date().toISOString();
|
const nextSeenAt = new Date().toISOString();
|
||||||
try {
|
await storyforgeFetch(trackingCursorPath, {
|
||||||
await storyforgeFetch(trackingCursorPath, {
|
method: "POST",
|
||||||
method: "POST",
|
body: { last_seen_at: nextSeenAt }
|
||||||
body: { last_seen_at: nextSeenAt }
|
});
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放跟踪已读游标接口。`, "orange");
|
|
||||||
renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
appState.trackingCursorMap = {
|
appState.trackingCursorMap = {
|
||||||
...(appState.trackingCursorMap || {}),
|
...(appState.trackingCursorMap || {}),
|
||||||
[platform]: nextSeenAt
|
[platform]: nextSeenAt
|
||||||
@@ -2624,19 +2600,9 @@ async function refreshTrackingAccountsAction() {
|
|||||||
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingRefresh");
|
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingRefresh");
|
||||||
setBusy(true, "正在同步跟踪账号...");
|
setBusy(true, "正在同步跟踪账号...");
|
||||||
try {
|
try {
|
||||||
let payload;
|
const payload = await storyforgeFetch(trackingRefreshPath, {
|
||||||
try {
|
method: "POST"
|
||||||
payload = await storyforgeFetch(trackingRefreshPath, {
|
});
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放批量跟踪同步。`, "orange");
|
|
||||||
renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "batch");
|
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "batch");
|
||||||
rememberTrackingRefreshNotice(refreshNotice);
|
rememberTrackingRefreshNotice(refreshNotice);
|
||||||
rememberAction(
|
rememberAction(
|
||||||
@@ -2660,19 +2626,9 @@ async function refreshTrackedAccountAction(trackedAccountId) {
|
|||||||
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingAccountRefresh", trackedAccountId);
|
const trackingRefreshPath = getWorkbenchRoute(platform, "trackingAccountRefresh", trackedAccountId);
|
||||||
setBusy(true, "正在同步该跟踪账号...");
|
setBusy(true, "正在同步该跟踪账号...");
|
||||||
try {
|
try {
|
||||||
let payload;
|
const payload = await storyforgeFetch(trackingRefreshPath, {
|
||||||
try {
|
method: "POST"
|
||||||
payload = await storyforgeFetch(trackingRefreshPath, {
|
});
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
rememberAction("当前实例未提供", `这套 ${platformLabel(platform)} collector 当前没有开放单账号跟踪同步。`, "orange");
|
|
||||||
renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "single");
|
const refreshNotice = summarizeTrackingRefreshPayload(payload, platform, "single");
|
||||||
rememberTrackingRefreshNotice(refreshNotice);
|
rememberTrackingRefreshNotice(refreshNotice);
|
||||||
const success = payload.success !== false;
|
const success = payload.success !== false;
|
||||||
@@ -9321,11 +9277,6 @@ function openPlatformSkillReviewAction(platform, skillId, accepted) {
|
|||||||
summary: values.summary || "",
|
summary: values.summary || "",
|
||||||
review_notes: values.reviewNotes || ""
|
review_notes: values.reviewNotes || ""
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
|
||||||
if (isMissingBackendCapability(error)) {
|
|
||||||
throw new Error("当前实例还没有开放平台技能验收接口。");
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
});
|
||||||
rememberAction(
|
rememberAction(
|
||||||
accepted ? "平台技能已通过" : "平台技能待优化",
|
accepted ? "平台技能已通过" : "平台技能待优化",
|
||||||
@@ -9590,15 +9541,7 @@ function openAnalyzeTopVideosAction() {
|
|||||||
min_score: Number(values.minScore || 45),
|
min_score: Number(values.minScore || 45),
|
||||||
temperature: 0.25
|
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 = {
|
||||||
...(appState.topVideoAnalysisResults || {}),
|
...(appState.topVideoAnalysisResults || {}),
|
||||||
[account.id]: {
|
[account.id]: {
|
||||||
@@ -10700,7 +10643,11 @@ document.addEventListener("click", async (event) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "refresh-tracking") {
|
if (name === "refresh-tracking") {
|
||||||
await refreshTrackingAccountsAction();
|
try {
|
||||||
|
await refreshTrackingAccountsAction();
|
||||||
|
} catch (error) {
|
||||||
|
presentActionFailure(error, "刷新跟踪账号失败");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "open-live-recorder") {
|
if (name === "open-live-recorder") {
|
||||||
@@ -10736,9 +10683,13 @@ document.addEventListener("click", async (event) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "mark-tracking-read") {
|
if (name === "mark-tracking-read") {
|
||||||
await markTrackingDigestRead();
|
try {
|
||||||
rememberAction("日报已标记", "当前跟踪摘要已更新为已读,下次会从新的时间点继续汇总。", "green");
|
await markTrackingDigestRead();
|
||||||
await bootstrap();
|
rememberAction("日报已标记", "当前跟踪摘要已更新为已读,下次会从新的时间点继续汇总。", "green");
|
||||||
|
await bootstrap();
|
||||||
|
} catch (error) {
|
||||||
|
presentActionFailure(error, "标记日报已读失败");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "logout-session") {
|
if (name === "logout-session") {
|
||||||
@@ -10824,7 +10775,11 @@ document.addEventListener("click", async (event) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "refresh-tracked-account") {
|
if (name === "refresh-tracked-account") {
|
||||||
await refreshTrackedAccountAction(action.dataset.trackedAccountId || "");
|
try {
|
||||||
|
await refreshTrackedAccountAction(action.dataset.trackedAccountId || "");
|
||||||
|
} catch (error) {
|
||||||
|
presentActionFailure(error, "同步跟踪账号失败");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === "open-import-video-link") {
|
if (name === "open-import-video-link") {
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ test("tracking refresh and top-video analysis flows expose async feedback inside
|
|||||||
assert.doesNotMatch(skillReview, /当前后端还没有接入平台技能验收接口/);
|
assert.doesNotMatch(skillReview, /当前后端还没有接入平台技能验收接口/);
|
||||||
assert.ok(!agentDetail.includes('backendSupports("/v2/platform-agents/{platform}/skills/{skill_id}/versions")'));
|
assert.ok(!agentDetail.includes('backendSupports("/v2/platform-agents/{platform}/skills/{skill_id}/versions")'));
|
||||||
assert.doesNotMatch(topVideoAction, /当前后端暂不支持.*高分作品批量分析/s);
|
assert.doesNotMatch(topVideoAction, /当前后端暂不支持.*高分作品批量分析/s);
|
||||||
assert.match(topVideoAction, /当前实例未提供/);
|
assert.doesNotMatch(topVideoAction, /当前实例未提供/);
|
||||||
assert.ok(!jobRecoverability.includes('backendSupports("/v2/explore/jobs/{job_id}/retry") && uploadedPath'));
|
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(!recoveryAction.includes('if (backendSupports("/v2/explore/jobs/{job_id}/retry"))'));
|
||||||
assert.ok(!clickActions.includes('else if (backendSupports("/v2/oneliner/sessions"))'));
|
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 === "show-disabled-reason"[\s\S]*rememberAction\("动作已拦截"/);
|
||||||
assert.match(clicks, /name === "auth-refresh" \|\| name === "refresh-data"[\s\S]*presentActionFailure\(error, "刷新数据失败"\)/);
|
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, /当前实例未提供/);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user