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

137 lines
4.3 KiB
TypeScript

import {
isPendingActivationViable,
selectLatestActivationForSession,
selectSessionMessages,
selectWorkspaceAgentConsumerSession,
type AgentActivityMessage,
type AgentPromptContentBlock,
type AgentSessionEngineState
} from "@tutti-os/agent-activity-core";
import { resolveAgentGuiSessionProviderIconUrl } from "../agentGuiSessionProviderIconUrls.ts";
import {
resolveAgentGUIConversationBrowserFreeTitle,
resolveAgentGUIConversationTitleDisplayPrompt
} from "../shared/agentConversationTitleProjection.ts";
import type { AgentGUIAgent } from "../types.ts";
import { isAgentGuiWorkbenchProvider } from "./providerCatalog.ts";
import {
resolveAgentGuiWorkbenchHeaderTitle,
resolveAgentGuiWorkbenchSessionTitle
} from "./sessionTitle.ts";
import type {
AgentGuiWorkbenchProvider,
AgentGuiWorkbenchState
} from "./types.ts";
export interface AgentGuiWorkbenchConversationIdentity {
agentTargetId?: string | null;
agentTitle?: string | null;
iconUrl?: string | null;
title: string | null;
titleDisplayPrompt?: string | null;
}
export function resolveAgentGuiWorkbenchConversationIdentity(input: {
agents: readonly AgentGUIAgent[];
dockIconUrls?: Partial<Record<AgentGuiWorkbenchProvider, string>>;
engineState: AgentSessionEngineState;
workbenchState: AgentGuiWorkbenchState | null;
}): AgentGuiWorkbenchConversationIdentity | null {
const agentSessionId =
input.workbenchState?.lastActiveAgentSessionId?.trim() ?? "";
if (!agentSessionId) {
return null;
}
const session = selectWorkspaceAgentConsumerSession(
input.engineState,
agentSessionId
)?.session;
const activation = selectLatestActivationForSession(
input.engineState,
agentSessionId
);
const optimisticTitle =
activation?.mode === "new" && isPendingActivationViable(activation)
? activation.optimisticTitle
: null;
const agentTargetId =
session?.agentTargetId ?? input.workbenchState?.agentTargetId ?? null;
const agent = agentTargetId
? (input.agents.find(
(candidate) => candidate.agentTargetId === agentTargetId
) ?? null)
: null;
const provider = session?.provider ?? agent?.provider ?? null;
const resolvedTitle = resolveAgentGuiWorkbenchSessionTitle({
agentSessionId,
fallbackTitle: null,
optimisticTitle,
session
});
const canonicalTitle = resolvedTitle.title;
const messages = selectSessionMessages(input.engineState, agentSessionId);
const titleDisplayPrompt = resolveAgentGuiWorkbenchTitleDisplayPrompt({
activation,
allowEmptyTitle: resolvedTitle.source === "optimistic",
messages,
title: canonicalTitle
});
// Keep browser context canonical in the message while omitting its tag from the visible header title.
const title = resolveAgentGUIConversationBrowserFreeTitle({
activation,
allowEmptyTitle: resolvedTitle.source === "optimistic",
messages,
title: canonicalTitle
});
const agentTitle = resolveAgentGuiWorkbenchHeaderTitle({
agentName: agent?.name,
conversationTitle: title,
provider
});
const iconUrl =
agent?.iconUrl ??
resolveAgentGuiSessionProviderIconUrl(provider ?? undefined) ??
(isAgentGuiWorkbenchProvider(provider)
? (input.dockIconUrls?.[provider] ?? null)
: null);
return {
agentTargetId,
agentTitle,
iconUrl,
title,
titleDisplayPrompt
};
}
export function resolveAgentGuiWorkbenchTitleDisplayPrompt(input: {
activation?: {
content: readonly AgentPromptContentBlock[];
displayPrompt?: string;
mode: "existing" | "new";
status: import("@tutti-os/agent-activity-core").PendingActivationStatus;
} | null;
allowEmptyTitle?: boolean;
messages: readonly AgentActivityMessage[];
title: string | null;
}): string | null {
return resolveAgentGUIConversationTitleDisplayPrompt(input);
}
export function agentGuiWorkbenchConversationIdentitiesEqual(
left: AgentGuiWorkbenchConversationIdentity | null,
right: AgentGuiWorkbenchConversationIdentity | null
): boolean {
return (
left === right ||
(left !== null &&
right !== null &&
left.agentTargetId === right.agentTargetId &&
left.agentTitle === right.agentTitle &&
left.iconUrl === right.iconUrl &&
left.title === right.title &&
left.titleDisplayPrompt === right.titleDisplayPrompt)
);
}