122 lines
3.7 KiB
TypeScript
122 lines
3.7 KiB
TypeScript
import { Box } from "ink";
|
|
import Link from "ink-link";
|
|
import { memo, useMemo } from "react";
|
|
import { DEFAULT_AGENT_NAME } from "../../constants";
|
|
import { settingsManager } from "../../settings-manager";
|
|
import { getVersion } from "../../version";
|
|
import { colors } from "./colors";
|
|
import { Text } from "./Text";
|
|
|
|
interface AgentInfoBarProps {
|
|
agentId?: string;
|
|
agentName?: string | null;
|
|
serverUrl?: string;
|
|
conversationId?: string;
|
|
}
|
|
|
|
/**
|
|
* Shows agent info bar with current agent details and useful links.
|
|
*/
|
|
export const AgentInfoBar = memo(function AgentInfoBar({
|
|
agentId,
|
|
agentName,
|
|
serverUrl,
|
|
conversationId,
|
|
}: AgentInfoBarProps) {
|
|
const isTmux = Boolean(process.env.TMUX);
|
|
// Check if current agent is pinned
|
|
const isPinned = useMemo(() => {
|
|
if (!agentId) return false;
|
|
const localPinned = settingsManager.getLocalPinnedAgents();
|
|
const globalPinned = settingsManager.getGlobalPinnedAgents();
|
|
return localPinned.includes(agentId) || globalPinned.includes(agentId);
|
|
}, [agentId]);
|
|
|
|
const isCloudUser = serverUrl?.includes("api.letta.com");
|
|
const adeUrl =
|
|
agentId && agentId !== "loading"
|
|
? `https://app.letta.com/agents/${agentId}${conversationId && conversationId !== "default" ? `?conversation=${conversationId}` : ""}`
|
|
: "";
|
|
const showBottomBar = agentId && agentId !== "loading";
|
|
|
|
if (!showBottomBar) {
|
|
return null;
|
|
}
|
|
|
|
// Alien ASCII art lines (4 lines tall, with 2-char indent + extra space before text)
|
|
const alienLines = [" ▗▖▗▖ ", " ▙█▜▛█▟ ", " ▝▜▛▜▛▘ ", " "];
|
|
|
|
return (
|
|
<Box flexDirection="column">
|
|
{/* Blank line after commands */}
|
|
<Box height={1} />
|
|
|
|
{/* Version and Discord/feedback info */}
|
|
<Box>
|
|
<Text>
|
|
{" "}Letta Code v{getVersion()} · Report bugs with /feedback or{" "}
|
|
<Link url="https://discord.gg/letta">
|
|
<Text>on Discord ↗</Text>
|
|
</Link>
|
|
</Text>
|
|
</Box>
|
|
|
|
{/* Blank line before agent info */}
|
|
<Box height={1} />
|
|
|
|
{/* Alien + Agent name */}
|
|
<Box>
|
|
<Text color={colors.footer.agentName}>{alienLines[0]}</Text>
|
|
<Text bold color={colors.footer.agentName}>
|
|
{agentName || "Unnamed"}
|
|
</Text>
|
|
{isPinned ? (
|
|
<Text color="green"> (pinned ✓)</Text>
|
|
) : agentName === DEFAULT_AGENT_NAME || !agentName ? (
|
|
<Text color="gray"> (type /pin to give your agent a real name!)</Text>
|
|
) : (
|
|
<Text color="gray"> (type /pin to pin agent)</Text>
|
|
)}
|
|
</Box>
|
|
|
|
{/* Alien + Links */}
|
|
<Box>
|
|
<Text color={colors.footer.agentName}>{alienLines[1]}</Text>
|
|
{isCloudUser && adeUrl && !isTmux && (
|
|
<>
|
|
<Link url={adeUrl}>
|
|
<Text>Open in ADE ↗</Text>
|
|
</Link>
|
|
<Text dimColor>· </Text>
|
|
</>
|
|
)}
|
|
{isCloudUser && adeUrl && isTmux && (
|
|
<Text dimColor>Open in ADE: {adeUrl} · </Text>
|
|
)}
|
|
{isCloudUser && (
|
|
<Link url="https://app.letta.com/settings/organization/usage">
|
|
<Text>View usage ↗</Text>
|
|
</Link>
|
|
)}
|
|
{!isCloudUser && <Text dimColor>{serverUrl}</Text>}
|
|
</Box>
|
|
|
|
{/* Alien + Agent ID */}
|
|
<Box>
|
|
<Text color={colors.footer.agentName}>{alienLines[2]}</Text>
|
|
<Text dimColor>{agentId}</Text>
|
|
</Box>
|
|
|
|
{/* Phantom alien row + Conversation ID */}
|
|
<Box>
|
|
<Text>{alienLines[3]}</Text>
|
|
{conversationId && conversationId !== "default" ? (
|
|
<Text dimColor>{conversationId}</Text>
|
|
) : (
|
|
<Text dimColor>default conversation</Text>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
);
|
|
});
|