Files
tutti/packages/agent/gui/shared/workspaceAgentActivitySummary.ts
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

110 lines
3.1 KiB
TypeScript

import type {
AgentActivityMessage,
AgentActivitySession
} from "@tutti-os/agent-activity-core";
import { translate } from "../i18n/index";
import { normalizeAgentTitleText } from "./utils/agentTitleText";
import { fallbackSummary } from "./workspaceAgentLatestActivitySummary";
import { isWorkspaceAgentSyntheticControlMessage } from "./workspaceAgentSyntheticMessages";
import type { WorkspaceAgentActivityStatus } from "./workspaceAgentActivityListTypes";
export function resolveWorkspaceAgentActivityTitle(
session: AgentActivitySession
): string {
return session.title.trim() || workspaceAgentUntitledConversationLabel();
}
export function resolveLatestActivity(
messages: readonly AgentActivityMessage[],
status: WorkspaceAgentActivityStatus,
actors: { agentName: string; userName: string }
): { actorName: string; summary: string } {
const latestMessage = latestDisplayableMessage(messages);
if (latestMessage) {
return {
actorName:
messageRole(latestMessage.message) === "user"
? actors.userName
: actors.agentName,
summary: latestMessage.text
};
}
return {
actorName: actors.agentName,
summary: fallbackSummary(status)
};
}
function latestDisplayableMessage(messages: readonly AgentActivityMessage[]): {
message: AgentActivityMessage;
text: string;
time?: number;
} | null {
return (
messages
.map((message) => ({
message,
text: messageDisplayText(message),
time: messageTime(message)
}))
.filter(
(item) =>
item.text.length > 0 &&
normalizeToken(item.message.kind) !== "tool_call"
)
.sort((left, right) => {
const timeDiff = (right.time ?? 0) - (left.time ?? 0);
if (timeDiff !== 0) {
return timeDiff;
}
return right.message.messageId.localeCompare(left.message.messageId);
})[0] ?? null
);
}
function messageDisplayText(message: AgentActivityMessage): string {
const payload = message.payload ?? {};
const text = normalizeAgentTitleText(
compactText(
stringValue(payload.displayPrompt) ||
stringValue(payload.text) ||
stringValue(payload.content) ||
stringValue(payload.message) ||
stringValue(payload.body) ||
stringValue(payload.title) ||
""
)
);
return isWorkspaceAgentSyntheticControlMessage(text) ? "" : text;
}
function messageRole(message: AgentActivityMessage): string {
return normalizeToken(message.role);
}
function messageTime(message: AgentActivityMessage): number | undefined {
return (
message.occurredAtUnixMs ??
message.completedAtUnixMs ??
message.startedAtUnixMs
);
}
function normalizeToken(value: string | undefined): string {
return value?.trim().toLowerCase() ?? "";
}
function compactText(value: string): string {
return value.replace(/\s+/g, " ").trim();
}
function workspaceAgentUntitledConversationLabel(): string {
return normalizeAgentTitleText(
translate("agentHost.workspaceAgentsUntitledConversation")
);
}
function stringValue(value: unknown): string | null {
return typeof value === "string" && value.trim() ? value.trim() : null;
}