Files
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

86 lines
2.7 KiB
TypeScript

// Agent GUI controller — session control state, message, and timeline helpers.
import type { AgentActivityMessageUpdate } from "../../../shared/agentSessionTypes";
import type { AgentActivityMessage } from "@tutti-os/agent-activity-core";
import { normalizeOptionalWorkspaceAgentStatus } from "../../../shared/workspaceAgentStatusNormalizer";
import type { WorkspaceAgentActivityTimelineItem } from "../../../shared/workspaceAgentTimelineTypes";
export function normalizeTimelineStatus(
value: string | null | undefined
): "working" | "waiting" | null {
const normalized = normalizeOptionalWorkspaceAgentStatus({
status: value ?? undefined
});
if (normalized?.kind === "working" || normalized?.kind === "waiting") {
return normalized.kind;
}
switch (value?.trim().toLowerCase()) {
case "active":
case "in_progress":
return "working";
case "pending":
return "waiting";
default:
return null;
}
}
export function messageFromMessageUpdate(
update: AgentActivityMessageUpdate
): AgentActivityMessage {
const payload = update.payload ?? {};
const normalizedKind = update.kind.trim().toLowerCase();
const normalizedRole = update.role.trim().toLowerCase();
const id =
normalizedPositiveNumber(update.seq) ??
normalizedPositiveNumber(update.occurredAtUnixMs) ??
0;
const isToolCall = normalizedKind === "tool_call";
const kind = isToolCall
? "tool_call"
: normalizedKind === "reasoning"
? "reasoning"
: "text";
const role = normalizedRole === "user" ? "user" : "assistant";
return {
workspaceId: update.workspaceId?.trim() || "",
agentSessionId: update.agentSessionId,
messageId: update.messageId.trim() || `message:${id}`,
version: id,
turnId: update.turnId?.trim() || null,
role,
kind,
status: update.status,
payload: {
...payload,
...(isToolCall && update.callId?.trim()
? { callId: update.callId.trim() }
: {}),
...(isToolCall && update.title?.trim()
? { title: update.title.trim() }
: {})
},
occurredAtUnixMs: update.occurredAtUnixMs,
...(update.startedAtUnixMs !== undefined
? { startedAtUnixMs: update.startedAtUnixMs }
: {}),
...(update.completedAtUnixMs !== undefined
? { completedAtUnixMs: update.completedAtUnixMs }
: {})
};
}
export function normalizedPositiveNumber(
value: number | undefined
): number | null {
return typeof value === "number" && Number.isFinite(value) && value > 0
? Math.trunc(value)
: null;
}
export function timelineItemTime(
item: WorkspaceAgentActivityTimelineItem
): number {
return item.occurredAtUnixMs ?? item.createdAtUnixMs ?? 0;
}