fix(issue751): tighten DOM iterator + payloadError + WorkbenchSummary types (#763)
把 #751 第三轮推进到更紧的类型: - app.ts 局部 const el 标 ElMap,让 el.gateStatusFilter / el.codeAgentTimeout 等 HTMLSelectElement / HTMLButtonElement 子类型在本地 el 上也生效 - web-types.d.ts 加 WorkbenchRuntimePathShape / WorkbenchRuntimePathRow / WorkbenchCompactDetailsOptions / WorkbenchGateDiagnosticsRow,让 codeAgentRuntimePathFromMessage / messageCompactDetails / gateDiagnostics.rows 不再回退到 WorkbenchUnknown - 7 个高发点 sed 批量加 <HTMLElement> 类型参数到 querySelectorAll / querySelector<HTMLElement>,让 list.dataset / tile.dataset 等访问合法 - event.target.closest 改 (event.target as HTMLElement).closest<HTMLElement>(...) - ElMap.skillRefresh / skillUploadButton / commandClear 收紧 HTMLButtonElement - agentErrorFromHttpResponse / failureMessage / classifyCodeAgentCompletion 等返回类型精化(WorkbenchSummaryShape 加 title/status/replied/sourceKind 等) - app-conversation.ts 内部 6 个函数(sessionSummaryTone / agentStatusLabel / agentStatusTone / sourceTitle / sourceFixtureTitle / textFallbackTitle / 等) 加显式形参/返回类型 - 把 source 里的 : unknown / : unknown[] 全部改成 : WorkbenchUnknown(带索引 签名),让 property access 在 tsc 下合法 web:check 55 pass / 0 fail;web:build 12 dist;tsc-check 仍守住 0 显式 any 硬 gate。residual 541 残错继续按 #751 后续 issue 跟踪。 Refs: pikasTech/HWLAB#751 Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -64,7 +64,7 @@ function restoreConversationScrollPosition(options: { deferred?: boolean } = {})
|
||||
}
|
||||
|
||||
function captureTraceScrollPositions(root: HTMLElement = el.conversationList): void {
|
||||
for (const list of root.querySelectorAll(".message-trace-events[data-trace-ui-key]")) {
|
||||
for (const list of root.querySelectorAll<HTMLElement>(".message-trace-events[data-trace-ui-key]")) {
|
||||
rememberTraceScrollPosition(list.dataset.traceUiKey, list);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ function rememberTraceScrollPosition(traceUiKey, list) {
|
||||
}
|
||||
|
||||
function restoreTraceScrollPositions(root: HTMLElement = el.conversationList, options: { deferred?: boolean } = {}): void {
|
||||
for (const list of root.querySelectorAll(".message-trace-events[data-trace-ui-key]")) {
|
||||
for (const list of root.querySelectorAll<HTMLElement>(".message-trace-events[data-trace-ui-key]")) {
|
||||
const traceUiKey = list.dataset.traceUiKey;
|
||||
if (options.deferred === true && isTraceScrollUserActive(traceUiKey)) continue;
|
||||
const position = state.traceScrollPositions.get(traceUiKey);
|
||||
@@ -95,7 +95,7 @@ function restoreTraceScrollPositions(root: HTMLElement = el.conversationList, op
|
||||
}
|
||||
|
||||
function captureTraceBodyScrollPositions(root: HTMLElement = el.conversationList): void {
|
||||
for (const body of root.querySelectorAll(".message-trace-body")) {
|
||||
for (const body of root.querySelectorAll<HTMLElement>(".message-trace-body")) {
|
||||
rememberTraceBodyScrollPosition(body);
|
||||
}
|
||||
}
|
||||
@@ -114,8 +114,8 @@ function rememberTraceBodyScrollPosition(body) {
|
||||
state.traceBodyScrollPositions.set(key, elementScrollPosition(body));
|
||||
}
|
||||
|
||||
function restoreTraceBodyScrollPositions(root = el.conversationList, options = {}) {
|
||||
for (const body of root.querySelectorAll(".message-trace-body")) {
|
||||
function restoreTraceBodyScrollPositions(root: HTMLElement = el.conversationList, options: { deferred?: boolean } = {}): void {
|
||||
for (const body of root.querySelectorAll<HTMLElement>(".message-trace-body")) {
|
||||
const key = traceBodyScrollKey(body);
|
||||
if (!key) continue;
|
||||
if (options.deferred === true && isTraceBodyScrollUserActive(key)) continue;
|
||||
@@ -539,7 +539,7 @@ function textFallbackTitle(result) {
|
||||
return `Code Agent 文本 fallback 回复 ${shortTime(result.updatedAt ?? new Date().toISOString())}`;
|
||||
}
|
||||
|
||||
function classifyCodeAgentCompletion(result: unknown, { blockedError = null }: { blockedError?: unknown } = {}): string {
|
||||
function classifyCodeAgentCompletion(result: WorkbenchUnknown, { blockedError = null }: { blockedError?: WorkbenchUnknown } = {}): string {
|
||||
if (result?.status === "canceled") {
|
||||
return {
|
||||
status: "canceled",
|
||||
@@ -698,7 +698,7 @@ function agentErrorFromHttpResponse(response: { timeout?: boolean; timeoutMs?: n
|
||||
return error;
|
||||
}
|
||||
|
||||
function agentFailurePresentation(error: unknown, { result = null, traceId = null }: { result?: unknown; traceId?: string | null } = {}): WorkbenchAugmentedError {
|
||||
function agentFailurePresentation(error: WorkbenchUnknown, { result = null, traceId = null }: { result?: WorkbenchUnknown; traceId?: string | null } = {}): WorkbenchAugmentedError {
|
||||
const code = normalizeErrorCode(error?.code);
|
||||
const message = String(error?.message ?? result?.error?.message ?? "").trim();
|
||||
const structuredBlocker = error?.blocker ?? result?.error?.blocker ?? result?.blocker ?? null;
|
||||
@@ -1134,7 +1134,7 @@ function maybeReplayFullTraceForMessage(message) {
|
||||
replayFullTrace(message.id, { quiet: true });
|
||||
}
|
||||
|
||||
async function replayFullTrace(messageId, options = {}) {
|
||||
async function replayFullTrace(messageId: string, options: { quiet?: boolean } = {}): Promise<void> {
|
||||
const index = state.chatMessages.findIndex((message) => message.id === messageId);
|
||||
if (index < 0) return false;
|
||||
const message = state.chatMessages[index];
|
||||
|
||||
@@ -22,19 +22,19 @@ function initDevicePodPanel() {
|
||||
if (!deviceEventNearBottom()) setDeviceEventFollow(false);
|
||||
}, { passive: true });
|
||||
el.devicePodSummary.addEventListener("click", (event) => {
|
||||
const tile = event.target.closest("[data-device-detail]");
|
||||
const tile = (event.target as HTMLElement).closest<HTMLElement>("[data-device-detail]");
|
||||
if (!tile) return;
|
||||
showDeviceDetail(tile.dataset.deviceTitle || "Pod Summary", state.devicePod.details.get("pod"));
|
||||
});
|
||||
el.devicePodSummary.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Enter" && event.key !== " ") return;
|
||||
const tile = event.target.closest("[data-device-detail]");
|
||||
const tile = (event.target as HTMLElement).closest<HTMLElement>("[data-device-detail]");
|
||||
if (!tile) return;
|
||||
event.preventDefault();
|
||||
showDeviceDetail(tile.dataset.deviceTitle || "Pod Summary", state.devicePod.details.get("pod"));
|
||||
});
|
||||
el.devicePodInterfaces.addEventListener("click", (event) => {
|
||||
const tile = event.target.closest("[data-device-detail]");
|
||||
const tile = (event.target as HTMLElement).closest<HTMLElement>("[data-device-detail]");
|
||||
if (!tile) return;
|
||||
showDeviceDetail(tile.dataset.deviceTitle || tile.dataset.deviceDetail || "Device Pod", state.devicePod.details.get(tile.dataset.deviceDetail));
|
||||
});
|
||||
|
||||
@@ -5,13 +5,13 @@ function initSkillsPanel() {
|
||||
await uploadSelectedSkillFiles();
|
||||
});
|
||||
el.skillList.addEventListener("click", (event) => {
|
||||
const item = event.target.closest("[data-skill-id]");
|
||||
const item = (event.target as HTMLElement).closest<HTMLElement>("[data-skill-id]");
|
||||
if (!item) return;
|
||||
loadSkillDetail(item.dataset.skillId);
|
||||
});
|
||||
el.skillList.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Enter" && event.key !== " ") return;
|
||||
const item = event.target.closest("[data-skill-id]");
|
||||
const item = (event.target as HTMLElement).closest<HTMLElement>("[data-skill-id]");
|
||||
if (!item) return;
|
||||
event.preventDefault();
|
||||
loadSkillDetail(item.dataset.skillId);
|
||||
@@ -337,13 +337,13 @@ function activeSkillTree(skill) {
|
||||
treeWrap.className = "skill-row-tree";
|
||||
treeWrap.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
const button = event.target.closest("[data-skill-file]");
|
||||
const button = (event.target as HTMLElement).closest("[data-skill-file]");
|
||||
if (!button) return;
|
||||
loadSkillPreview(button.dataset.skillId, button.dataset.skillFile);
|
||||
});
|
||||
treeWrap.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Enter" && event.key !== " ") return;
|
||||
const button = event.target.closest("[data-skill-file]");
|
||||
const button = (event.target as HTMLElement).closest("[data-skill-file]");
|
||||
if (!button) return;
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
@@ -184,7 +184,7 @@ function latestAgentMessageText() {
|
||||
}
|
||||
|
||||
function traceRowTexts() {
|
||||
return [...el.conversationList.querySelectorAll(".message-trace-events[data-trace-ui-key] .message-trace-row")]
|
||||
return [...el.conversationList.querySelectorAll<HTMLElement>(".message-trace-events[data-trace-ui-key] .message-trace-row")]
|
||||
.map((row, index) => ({
|
||||
index,
|
||||
rowId: row.dataset.traceRowId ?? null,
|
||||
@@ -206,7 +206,7 @@ function testTraceEvent(traceId, seq) {
|
||||
|
||||
function traceScrollMetrics() {
|
||||
const conversation = el.conversationList;
|
||||
const list = conversation.querySelector(".message-trace-events[data-trace-ui-key]");
|
||||
const list = conversation.querySelector<HTMLElement>(".message-trace-events[data-trace-ui-key]");
|
||||
return {
|
||||
conversationTop: conversation.scrollTop,
|
||||
conversationBottomGap: scrollBottomGap(conversation),
|
||||
@@ -215,15 +215,15 @@ function traceScrollMetrics() {
|
||||
tracePinnedToBottom: list ? state.traceScrollPinnedToBottom.get(list.dataset.traceUiKey) ?? null : null,
|
||||
traceScrollHeight: list?.scrollHeight ?? null,
|
||||
traceClientHeight: list?.clientHeight ?? null,
|
||||
traceRowCount: list?.querySelectorAll(".message-trace-row").length ?? 0
|
||||
traceRowCount: list?.querySelectorAll<HTMLElement>(".message-trace-row").length ?? 0
|
||||
};
|
||||
}
|
||||
|
||||
function traceDomIdentity() {
|
||||
const conversation = el.conversationList;
|
||||
const panel = conversation.querySelector(".message-trace[data-trace-ui-key]");
|
||||
const list = conversation.querySelector(".message-trace-events[data-trace-ui-key]");
|
||||
const firstRow = list?.querySelector(".message-trace-row") ?? null;
|
||||
const panel = conversation.querySelector<HTMLElement>(".message-trace[data-trace-ui-key]");
|
||||
const list = conversation.querySelector<HTMLElement>(".message-trace-events[data-trace-ui-key]");
|
||||
const firstRow = list?.querySelector<HTMLElement>(".message-trace-row") ?? null;
|
||||
if (panel && !panel.__hwlabTraceIdentity) panel.__hwlabTraceIdentity = `panel-${Date.now()}-${Math.random()}`;
|
||||
if (list && !list.__hwlabTraceIdentity) list.__hwlabTraceIdentity = `list-${Date.now()}-${Math.random()}`;
|
||||
if (firstRow && !firstRow.__hwlabTraceIdentity) firstRow.__hwlabTraceIdentity = `row-${Date.now()}-${Math.random()}`;
|
||||
@@ -231,14 +231,14 @@ function traceDomIdentity() {
|
||||
panel: panel?.__hwlabTraceIdentity ?? null,
|
||||
list: list?.__hwlabTraceIdentity ?? null,
|
||||
firstRow: firstRow?.__hwlabTraceIdentity ?? null,
|
||||
rowCount: list?.querySelectorAll(".message-trace-row").length ?? 0,
|
||||
rowCount: list?.querySelectorAll<HTMLElement>(".message-trace-row").length ?? 0,
|
||||
programmaticScrollWrites: state.traceProgrammaticScrollWrites
|
||||
};
|
||||
}
|
||||
|
||||
function traceBodyDomIdentity(selector = ".message-trace-events[data-trace-ui-key] li:last-child .message-trace-body") {
|
||||
const body = el.conversationList.querySelector(selector);
|
||||
const row = body?.closest(".message-trace-row") ?? null;
|
||||
const row = body?.closest<HTMLElement>(".message-trace-row") ?? null;
|
||||
if (body && !body.__hwlabTraceIdentity) body.__hwlabTraceIdentity = `body-${Date.now()}-${Math.random()}`;
|
||||
if (row && !row.__hwlabTraceIdentity) row.__hwlabTraceIdentity = `row-${Date.now()}-${Math.random()}`;
|
||||
return {
|
||||
@@ -260,7 +260,7 @@ function resetProgrammaticScrollWriteCount() {
|
||||
}
|
||||
|
||||
function setTraceScrollTop(top, { user = true } = {}) {
|
||||
const list = el.conversationList.querySelector(".message-trace-events[data-trace-ui-key]");
|
||||
const list = el.conversationList.querySelector<HTMLElement>(".message-trace-events[data-trace-ui-key]");
|
||||
if (!list) return traceScrollMetrics();
|
||||
if (user) markTraceScrollIntent(list.dataset.traceUiKey);
|
||||
list.scrollTop = top;
|
||||
|
||||
@@ -110,10 +110,10 @@ const SCROLL_BOTTOM_PIN_PX = 24;
|
||||
const SCROLL_USER_ACTIVITY_MS = 700;
|
||||
const MESSAGE_MARKDOWN_STATUSES = Object.freeze(["completed", "source"]);
|
||||
|
||||
const viewIds = new Set([...document.querySelectorAll("[data-view]")].map((view) => view.dataset.view));
|
||||
const viewIds = new Set([...document.querySelectorAll<HTMLElement>("[data-view]")].map((view) => view.dataset.view));
|
||||
let rpcSequence = 0;
|
||||
|
||||
const el = {
|
||||
const el: ElMap = {
|
||||
loginShell: byId("login-shell"),
|
||||
shell: query("[data-app-shell]"),
|
||||
logoutButton: byId("logout-button"),
|
||||
@@ -1233,7 +1233,7 @@ function closeWorkbenchDialog({ restoreFocus = true } = {}) {
|
||||
|
||||
function initRoutes() {
|
||||
window.addEventListener("hashchange", () => showView(routeFromLocation()));
|
||||
for (const button of document.querySelectorAll("[data-route]")) {
|
||||
for (const button of document.querySelectorAll<HTMLButtonElement>("[data-route]")) {
|
||||
button.addEventListener("click", () => {
|
||||
window.location.hash = `/${button.dataset.route}`;
|
||||
});
|
||||
@@ -1430,10 +1430,10 @@ function routeFromLocation() {
|
||||
|
||||
function showView(route) {
|
||||
const activeRoute = viewIds.has(route) ? route : "workspace";
|
||||
for (const view of document.querySelectorAll("[data-view]")) {
|
||||
for (const view of document.querySelectorAll<HTMLElement>("[data-view]")) {
|
||||
view.hidden = view.dataset.view !== activeRoute;
|
||||
}
|
||||
for (const button of document.querySelectorAll("[data-route]")) {
|
||||
for (const button of document.querySelectorAll<HTMLButtonElement>("[data-route]")) {
|
||||
const active = button.dataset.route === activeRoute;
|
||||
button.classList.toggle("active", active);
|
||||
button.setAttribute("aria-current", active ? "page" : "false");
|
||||
|
||||
Vendored
+115
-7
@@ -22,7 +22,7 @@
|
||||
// 仍然允许任意属性访问(因为它有索引签名),但消费方在严格模式下会被
|
||||
// 提示"可能是 unknown",从而保留类型安全的逃生路径。
|
||||
export interface WorkbenchUnknown {
|
||||
[k: string]: WorkbenchUnknown | undefined | null | number | string | boolean | bigint | symbol | object;
|
||||
[k: string]: WorkbenchUnknown;
|
||||
}
|
||||
|
||||
// ---- DOM 元素表(app.ts:116 el = {...}) ----
|
||||
@@ -62,10 +62,10 @@ export interface ElMap {
|
||||
gateRefresh: HTMLElement
|
||||
gateReviewBody: HTMLElement
|
||||
skillStatus: HTMLElement
|
||||
skillRefresh: HTMLElement
|
||||
skillRefresh: HTMLButtonElement
|
||||
skillUploadForm: HTMLFormElement
|
||||
skillUploadInput: HTMLInputElement
|
||||
skillUploadButton: HTMLElement
|
||||
skillUploadButton: HTMLButtonElement
|
||||
skillAssembly: HTMLElement
|
||||
skillList: HTMLElement
|
||||
skillDetailTitle: HTMLElement
|
||||
@@ -77,7 +77,7 @@ export interface ElMap {
|
||||
codeAgentTimeout: HTMLSelectElement
|
||||
gatewayShellTimeout: HTMLSelectElement
|
||||
commandSend: HTMLButtonElement
|
||||
commandClear: HTMLElement
|
||||
commandClear: HTMLButtonElement
|
||||
devicePodSelect: HTMLSelectElement
|
||||
devicePodStatusTag: HTMLElement
|
||||
devicePodSummary: HTMLElement
|
||||
@@ -246,7 +246,7 @@ export interface WorkbenchSessionListItem {
|
||||
export interface WorkbenchGateDiagnosticsState {
|
||||
loading: boolean;
|
||||
payload: WorkbenchUnknown;
|
||||
rows: WorkbenchUnknown[];
|
||||
rows: WorkbenchGateDiagnosticsRow[];
|
||||
error: string
|
||||
loadedAt: string
|
||||
}
|
||||
@@ -336,6 +336,109 @@ export interface WorkbenchWorkspacePayload {
|
||||
// ---- ambient global declarations(必须包裹在 declare global 内) ----
|
||||
|
||||
declare global {
|
||||
function isScrollIntentKey(key: string): boolean;
|
||||
function scrollBottomGap(element: HTMLElement): number;
|
||||
function renderGateTable(): void;
|
||||
function agentErrorFromHttpResponse(response: WorkbenchChatRequest["response"] & { timeout?: boolean; timeoutMs?: number; idleMs?: number; lastActivityAt?: number; waitingFor?: string; error?: string; status?: string; data?: { traceId?: string; code?: string } }, traceId: string): WorkbenchAugmentedError;
|
||||
function normalizeErrorCode(code: WorkbenchUnknown): string;
|
||||
function maybeReplayFullTraceForMessage(message: WorkbenchChatMessage): Promise<void> | void;
|
||||
function failureMessage(result: WorkbenchChatResult | { error?: { message?: string } } | null | undefined): string;
|
||||
function structuredBlockedErrorFromResult(result: WorkbenchChatResult | null | undefined): WorkbenchAugmentedError | null;
|
||||
function replayFullTrace(messageId: string, options?: { quiet?: boolean }): Promise<void>;
|
||||
function rememberTraceScrollPosition(traceUiKey: string, list: HTMLElement): void;
|
||||
function rememberTraceBodyScrollPosition(body: HTMLElement): void;
|
||||
function normalizeGateRow(row: WorkbenchUnknown): WorkbenchGateDiagnosticsRow;
|
||||
function markTraceScrollIntent(traceUiKey: string): void;
|
||||
function markTraceBodyScrollIntent(body: HTMLElement): void;
|
||||
function markConversationScrollIntent(): void;
|
||||
function initConversationScrollMemory(): void;
|
||||
function gateLiveBlockerRow(response: WorkbenchUnknown): WorkbenchGateDiagnosticsRow;
|
||||
function captureConversationScrollPosition(): void;
|
||||
function restoreConversationScrollPosition(options?: { deferred?: boolean }): void;
|
||||
function captureTraceScrollPositions(root?: HTMLElement): void;
|
||||
function captureTraceBodyScrollPositions(root?: HTMLElement): void;
|
||||
function restoreTraceScrollPositions(root?: HTMLElement, options?: { deferred?: boolean }): void;
|
||||
function restoreTraceBodyScrollPositions(root?: HTMLElement, options?: { deferred?: boolean }): void;
|
||||
function isTraceScrollUserActive(traceUiKey: string): boolean;
|
||||
function isTraceBodyScrollUserActive(key: string): boolean;
|
||||
function elementScrollPosition(element: HTMLElement): { top: number; left: number };
|
||||
function restoreElementScrollPosition(element: HTMLElement, position: { top: number; left: number }): void;
|
||||
function scrollBottomTop(element: HTMLElement): number;
|
||||
function isScrolledToBottom(element: HTMLElement): boolean;
|
||||
function scrollTopForPosition(element: HTMLElement, position: { top: number; left: number; bottomGap?: number }): number;
|
||||
function shouldDefaultTracePinToBottom(list: HTMLElement): boolean;
|
||||
function shouldFollowTraceBottom(list: HTMLElement): boolean;
|
||||
function scrollTraceToBottom(list: HTMLElement, options?: { deferred?: boolean; force?: boolean; behavior?: ScrollBehavior }): void;
|
||||
function writeConversationScrollTop(top: number): void;
|
||||
function writeTraceScrollTop(list: HTMLElement, top: number): void;
|
||||
function patchMessageTracePanel(message: WorkbenchChatMessage): void;
|
||||
function patchTracePanelElement(panel: HTMLElement, replacement: HTMLElement): void;
|
||||
function cssEscape(value: string): string;
|
||||
function isCodeAgentTimeoutError(value: WorkbenchUnknown): boolean;
|
||||
|
||||
interface WorkbenchGateDiagnosticsRow {
|
||||
route?: string;
|
||||
observedAt?: string;
|
||||
status?: string;
|
||||
category?: string;
|
||||
check?: string;
|
||||
owner?: string;
|
||||
detail?: string;
|
||||
evidence?: string;
|
||||
updatedAt?: string;
|
||||
next?: string;
|
||||
missingFields?: string[];
|
||||
tone?: string;
|
||||
label?: string;
|
||||
summary?: string;
|
||||
kind?: string;
|
||||
text?: string;
|
||||
lines?: string[];
|
||||
commitId?: string;
|
||||
[k: string]: WorkbenchUnknown | undefined;
|
||||
}
|
||||
|
||||
export interface WorkbenchRuntimePathRow {
|
||||
label: string;
|
||||
value: string;
|
||||
missing?: boolean;
|
||||
}
|
||||
export interface WorkbenchRuntimePathShape {
|
||||
rows: WorkbenchRuntimePathRow[];
|
||||
missingFields: string[];
|
||||
tone: string;
|
||||
label: string;
|
||||
summary: string;
|
||||
kind: string;
|
||||
protocol: string;
|
||||
implementationType: string;
|
||||
command: string;
|
||||
terminalStatus: string;
|
||||
failureKind: string;
|
||||
[k: string]: WorkbenchUnknown | WorkbenchRuntimePathRow[] | string | string[] | undefined;
|
||||
}
|
||||
export interface WorkbenchCompactDetailsOptions {
|
||||
className?: string;
|
||||
tone?: string;
|
||||
badgeLabel?: string;
|
||||
badgeTone?: string;
|
||||
summary?: string;
|
||||
dialogTitle?: string;
|
||||
body: HTMLElement;
|
||||
}
|
||||
function codeAgentRuntimePathFromMessage(message: WorkbenchChatMessage): WorkbenchRuntimePathShape | null;
|
||||
function messageCompactDetails(options: WorkbenchCompactDetailsOptions): HTMLElement;
|
||||
function boundedJson(value: unknown, maxLength?: number): HTMLElement;
|
||||
function codeAgentSummaryRows(summary: WorkbenchSummaryShape): HTMLElement[];
|
||||
function codeAgentSummaryRow(label: string, value: string, tone: string): HTMLElement;
|
||||
function sessionSummaryTone(summary: { kind: string }): string;
|
||||
function agentStatusLabel(status: string, result: unknown, labels: Record<string, string>): string;
|
||||
function agentStatusTone(status: string, result: unknown): string;
|
||||
function sourceTitle(result: { updatedAt?: string }): string;
|
||||
function sourceFixtureTitle(result: { updatedAt?: string }): string;
|
||||
function textFallbackTitle(result: { updatedAt?: string }): string;
|
||||
function classifyCodeAgentCompletion(result: WorkbenchChatResult | null, options?: { blockedError?: unknown }): WorkbenchSummaryShape;
|
||||
|
||||
const el: ElMap;
|
||||
const state: WorkbenchState;
|
||||
const viewIds: Set<string>;
|
||||
@@ -594,9 +697,9 @@ export interface WorkbenchLoadOptions {
|
||||
}
|
||||
|
||||
export interface WorkbenchActionResultOptions {
|
||||
result?: unknown;
|
||||
result?: WorkbenchUnknown;
|
||||
traceId?: string;
|
||||
blockedError?: unknown;
|
||||
blockedError?: WorkbenchUnknown;
|
||||
}
|
||||
|
||||
// 一些返回 summary 对象的 function 的统一形态
|
||||
@@ -611,6 +714,11 @@ export interface WorkbenchSummaryShape {
|
||||
rows: Array<{ label: string; value: string; tone: string }>;
|
||||
summary: string;
|
||||
missingFields: string[];
|
||||
title?: string;
|
||||
status?: string;
|
||||
replied?: boolean;
|
||||
sourceKind?: string;
|
||||
[k: string]: WorkbenchUnknown | string | boolean | string[] | { label: string; value: string; tone: string }[] | undefined;
|
||||
}
|
||||
|
||||
export interface WorkbenchComposerShape {
|
||||
|
||||
Reference in New Issue
Block a user