Files
tutti/packages/agent/gui/agent-gui/agentGuiNode/model/agentGuiConversationActivityMessage.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

65 lines
1.9 KiB
TypeScript

import type { AgentActivityMessage } from "@tutti-os/agent-activity-core";
export function resolveAgentGUIConversationActivityMessage(
messages: readonly AgentActivityMessage[]
): string | null {
const candidates = messages
.filter((message) => {
const role = message.role.trim().toLowerCase();
return (
(role === "assistant" || role === "agent") &&
message.semantics?.userVisibleAssistantResponse !== false
);
})
.map((message) => ({
message,
text: activityMessageText(message)
}))
.filter((candidate) => candidate.text.length > 0)
.sort(
(left, right) =>
right.message.occurredAtUnixMs - left.message.occurredAtUnixMs ||
(right.message.sequence ?? 0) - (left.message.sequence ?? 0) ||
right.message.messageId.localeCompare(left.message.messageId)
);
return candidates[0]?.text ?? null;
}
function activityMessageText(message: AgentActivityMessage): string {
if (message.kind.trim().toLowerCase() === "tool_call") return "";
const payload = message.payload;
for (const value of [
payload.text,
payload.content,
payload.message,
payload.body,
payload.title
]) {
const text = activityMessageValueText(value);
if (text) return text;
}
return "";
}
function activityMessageValueText(value: unknown): string {
if (typeof value === "string") return compactActivityMessageText(value);
if (!Array.isArray(value)) return "";
return compactActivityMessageText(
value
.flatMap((block) => {
if (!block || typeof block !== "object" || Array.isArray(block)) {
return [];
}
const record = block as Record<string, unknown>;
return record.type === "text" && typeof record.text === "string"
? [record.text]
: [];
})
.join(" ")
);
}
function compactActivityMessageText(value: string): string {
return value.replace(/\s+/g, " ").trim();
}