源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
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
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
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user