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
110 lines
3.1 KiB
TypeScript
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;
|
|
}
|