From d4d03ab22b95136760469674f20b099ddfb34f53 Mon Sep 17 00:00:00 2001 From: Shubham Naik Date: Tue, 4 Nov 2025 10:54:27 -0800 Subject: [PATCH] chore: show agent url in commands (#60) Co-authored-by: Shubham Naik --- src/cli/App.tsx | 1 + src/cli/components/CommandPreview.tsx | 22 +++++++++++++++++++++- src/cli/components/InputAssist.tsx | 12 +++++++++++- src/cli/components/InputRich.tsx | 17 ++++++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index 91de6eb..bbb8a67 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -1406,6 +1406,7 @@ export default function App({ onExit={handleExit} onInterrupt={handleInterrupt} interruptRequested={interruptRequested} + agentId={agentId} /> {/* Model Selector - conditionally mounted as overlay */} diff --git a/src/cli/components/CommandPreview.tsx b/src/cli/components/CommandPreview.tsx index 6a4fc99..ab2fc9e 100644 --- a/src/cli/components/CommandPreview.tsx +++ b/src/cli/components/CommandPreview.tsx @@ -1,4 +1,5 @@ import { Box, Text } from "ink"; +import Link from "ink-link"; import { commands } from "../commands/registry"; import { colors } from "./colors"; @@ -8,11 +9,23 @@ const commandList = Object.entries(commands).map(([cmd, { desc }]) => ({ desc, })); -export function CommandPreview({ currentInput }: { currentInput: string }) { +export function CommandPreview({ + currentInput, + agentId, + serverUrl, +}: { + currentInput: string; + agentId?: string; + serverUrl?: string; +}) { if (!currentInput.startsWith("/")) { return null; } + // Show agent URL only for cloud users + const showAgentUrl = + agentId && agentId !== "loading" && serverUrl?.includes("api.letta.com"); + return ( {item.desc} ))} + {showAgentUrl && ( + + + View agent: + + + )} ); } diff --git a/src/cli/components/InputAssist.tsx b/src/cli/components/InputAssist.tsx index 980f5d5..1cea234 100644 --- a/src/cli/components/InputAssist.tsx +++ b/src/cli/components/InputAssist.tsx @@ -6,6 +6,8 @@ interface InputAssistProps { cursorPosition: number; onFileSelect: (path: string) => void; onAutocompleteActiveChange: (isActive: boolean) => void; + agentId?: string; + serverUrl?: string; } /** @@ -19,6 +21,8 @@ export function InputAssist({ cursorPosition, onFileSelect, onAutocompleteActiveChange, + agentId, + serverUrl, }: InputAssistProps) { // Show file autocomplete when @ is present if (currentInput.includes("@")) { @@ -34,7 +38,13 @@ export function InputAssist({ // Show command preview when input starts with / if (currentInput.startsWith("/")) { - return ; + return ( + + ); } // No assistance needed diff --git a/src/cli/components/InputRich.tsx b/src/cli/components/InputRich.tsx index 197fba7..834ad29 100644 --- a/src/cli/components/InputRich.tsx +++ b/src/cli/components/InputRich.tsx @@ -1,10 +1,12 @@ // Import useInput from vendored Ink for bracketed paste support import { Box, Text, useInput } from "ink"; +import Link from "ink-link"; import SpinnerLib from "ink-spinner"; import type { ComponentType } from "react"; import { useEffect, useRef, useState } from "react"; import type { PermissionMode } from "../../permissions/mode"; import { permissionMode } from "../../permissions/mode"; +import { settingsManager } from "../../settings-manager"; import { useTerminalWidth } from "../hooks/useTerminalWidth"; import { colors } from "./colors"; import { InputAssist } from "./InputAssist"; @@ -29,6 +31,7 @@ export function Input({ onExit, onInterrupt, interruptRequested = false, + agentId, }: { visible?: boolean; streaming: boolean; @@ -41,6 +44,7 @@ export function Input({ onExit?: () => void; onInterrupt?: () => void; interruptRequested?: boolean; + agentId?: string; }) { const [value, setValue] = useState(""); const [escapePressed, setEscapePressed] = useState(false); @@ -96,6 +100,13 @@ export function Input({ const columns = useTerminalWidth(); const contentWidth = Math.max(0, columns - 2); + // Get server URL (same logic as client.ts) + const settings = settingsManager.getSettings(); + const serverUrl = + process.env.LETTA_BASE_URL || + settings.env?.LETTA_BASE_URL || + "https://api.letta.com"; + // Handle escape key for interrupt (when streaming) or double-escape-to-clear (when not) useInput((_input, key) => { if (key.escape) { @@ -467,6 +478,8 @@ export function Input({ cursorPosition={currentCursorPosition} onFileSelect={handleFileSelect} onAutocompleteActiveChange={setIsAutocompleteActive} + agentId={agentId} + serverUrl={serverUrl} /> @@ -485,7 +498,9 @@ export function Input({ ) : ( Press / for commands or @ for files )} - https://discord.gg/letta + + Discord +