Merge pull request #24 from Askhz/fix/model-login-sync
feat(logo): show "Not logged in" state and provider display name in logo
This commit is contained in:
commit
cb6108610d
|
|
@ -7,7 +7,7 @@ import { useAppState } from '../../state/AppState.js';
|
|||
import { getEffortSuffix } from '../../utils/effort.js';
|
||||
import { truncate } from '../../utils/format.js';
|
||||
import { isFullscreenEnvEnabled } from '../../utils/fullscreen.js';
|
||||
import { formatModelAndBilling, getLogoDisplayData, truncatePath } from '../../utils/logoV2Utils.js';
|
||||
import { formatModelAndBilling, getLogoDisplayData, isNotLoggedIn, truncatePath } from '../../utils/logoV2Utils.js';
|
||||
import { renderModelSetting } from '../../utils/model/model.js';
|
||||
import { OffscreenFreeze } from '../OffscreenFreeze.js';
|
||||
import { AnimatedClawd } from './AnimatedClawd.js';
|
||||
|
|
@ -23,7 +23,10 @@ export function CondensedLogo(): ReactNode {
|
|||
const { columns } = useTerminalSize();
|
||||
const agent = useAppState(s => s.agent);
|
||||
const effortValue = useAppState(s => s.effortValue);
|
||||
// Subscribe to authVersion to re-render after login/logout
|
||||
useAppState(s => s.authVersion);
|
||||
const model = useMainLoopModel();
|
||||
const notLoggedIn = isNotLoggedIn();
|
||||
const modelDisplayName = renderModelSetting(model);
|
||||
const { version, cwd, billingType, agentName: agentNameFromSettings } = getLogoDisplayData();
|
||||
|
||||
|
|
@ -92,7 +95,9 @@ export function CondensedLogo(): ReactNode {
|
|||
</Text>{' '}
|
||||
<Text dimColor>v{truncatedVersion}</Text>
|
||||
</Text>
|
||||
{shouldSplit ? (
|
||||
{notLoggedIn ? (
|
||||
<Text dimColor>Not logged in</Text>
|
||||
) : shouldSplit ? (
|
||||
<>
|
||||
<Text dimColor>{truncatedModel}</Text>
|
||||
<Text dimColor>{truncatedBilling}</Text>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
getRecentActivitySync,
|
||||
getRecentReleaseNotesSync,
|
||||
getLogoDisplayData,
|
||||
isNotLoggedIn,
|
||||
} from '../../utils/logoV2Utils.js';
|
||||
import { truncate } from '../../utils/format.js';
|
||||
import { getDisplayPath } from '../../utils/file.js';
|
||||
|
|
@ -82,6 +83,8 @@ export function LogoV2(): React.ReactNode {
|
|||
const showOverageCreditUpsell = useShowOverageCreditUpsell();
|
||||
const agent = useAppState(s => s.agent);
|
||||
const effortValue = useAppState(s => s.effortValue);
|
||||
// Subscribe to authVersion to re-render after login/logout
|
||||
useAppState(s => s.authVersion);
|
||||
|
||||
const config = getGlobalConfig();
|
||||
|
||||
|
|
@ -136,6 +139,7 @@ export function LogoV2(): React.ReactNode {
|
|||
}, [showOverageCreditUpsell, showOnboarding, showGuestPassesUpsell, isCondensedMode]);
|
||||
|
||||
const model = useMainLoopModel();
|
||||
const notLoggedIn = isNotLoggedIn();
|
||||
const fullModelDisplayName = renderModelSetting(model);
|
||||
const { version, cwd, billingType, agentName: agentNameFromSettings } = getLogoDisplayData();
|
||||
// Prefer AppState.agent (set from --agent CLI flag) over settings
|
||||
|
|
@ -247,8 +251,8 @@ export function LogoV2(): React.ReactNode {
|
|||
<Box marginY={1}>
|
||||
<Clawd />
|
||||
</Box>
|
||||
<Text dimColor>{modelDisplayName}</Text>
|
||||
<Text dimColor>{billingType}</Text>
|
||||
<Text dimColor>{notLoggedIn ? 'Not logged in' : modelDisplayName}</Text>
|
||||
{!notLoggedIn && <Text dimColor>{billingType}</Text>}
|
||||
<Text dimColor>{agentName ? `@${agentName} · ${truncatedCwd}` : truncatedCwd}</Text>
|
||||
</Box>
|
||||
</OffscreenFreeze>
|
||||
|
|
@ -269,8 +273,9 @@ export function LogoV2(): React.ReactNode {
|
|||
}
|
||||
|
||||
const welcomeMessage = formatWelcomeMessage(username);
|
||||
const modelLine =
|
||||
!process.env.IS_DEMO && config.oauthAccount?.organizationName
|
||||
const modelLine = notLoggedIn
|
||||
? 'Not logged in'
|
||||
: !process.env.IS_DEMO && config.oauthAccount?.organizationName
|
||||
? `${modelDisplayName} · ${billingType} · ${config.oauthAccount.organizationName}`
|
||||
: `${modelDisplayName} · ${billingType}`;
|
||||
// Calculate cwd width accounting for agent name if present
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { getDirectConnectServerUrl, getSessionId } from '../bootstrap/state.js'
|
||||
import { stringWidth } from '@anthropic/ink'
|
||||
import type { LogOption } from '../types/logs.js'
|
||||
import { getSubscriptionName, isClaudeAISubscriber } from './auth.js'
|
||||
import { getAnthropicApiKey } from './auth.js'
|
||||
import { hasCoStrictCredentialsSync } from '../costrict/provider/credentials.js'
|
||||
import { getCwd } from './cwd.js'
|
||||
import { getDisplayPath } from './file.js'
|
||||
import {
|
||||
|
|
@ -9,6 +10,7 @@ import {
|
|||
truncateToWidth,
|
||||
truncateToWidthNoEllipsis,
|
||||
} from './format.js'
|
||||
import { getAPIProvider, getProviderDisplayName } from './model/providers.js'
|
||||
import { getStoredChangelogFromMemory, parseChangelog } from './releaseNotes.js'
|
||||
import { gt } from './semver.js'
|
||||
import { loadMessageLogs } from './sessionStorage.js'
|
||||
|
|
@ -237,12 +239,33 @@ export function formatReleaseNoteForDisplay(
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the common logo display data used by both LogoV2 and CondensedLogo
|
||||
* Check if user is not logged in
|
||||
* User is considered logged in if they have CoStrict credentials or API key
|
||||
*/
|
||||
export function isNotLoggedIn(): boolean {
|
||||
// 1. CoStrict login (credentials file exists)
|
||||
if (hasCoStrictCredentialsSync()) return false
|
||||
|
||||
const settings = getInitialSettings()
|
||||
|
||||
// 2. Any provider configured via modelType (包括 anthropic/openai/bedrock 等)
|
||||
// 用户通过 /login 选择 provider 后会设置 modelType
|
||||
if (settings.modelType) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 3. Anthropic API Key configured (legacy way without modelType)
|
||||
if (getAnthropicApiKey() !== null) return false
|
||||
|
||||
// None of the above - not logged in
|
||||
return true
|
||||
}
|
||||
|
||||
export function getLogoDisplayData(): {
|
||||
version: string
|
||||
cwd: string
|
||||
billingType: string
|
||||
isLoggedIn: boolean
|
||||
agentName: string | undefined
|
||||
} {
|
||||
const version = process.env.DEMO_VERSION ?? MACRO.VERSION
|
||||
|
|
@ -253,15 +276,18 @@ export function getLogoDisplayData(): {
|
|||
const cwd = serverUrl
|
||||
? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, '')}`
|
||||
: displayPath
|
||||
const billingType = isClaudeAISubscriber()
|
||||
? getSubscriptionName()
|
||||
: 'API Usage Billing'
|
||||
|
||||
const loggedIn = !isNotLoggedIn()
|
||||
const provider = getAPIProvider()
|
||||
const providerName = getProviderDisplayName(provider)
|
||||
const billingType = loggedIn ? providerName : 'Not logged in'
|
||||
const agentName = getInitialSettings().agent
|
||||
|
||||
return {
|
||||
version,
|
||||
cwd,
|
||||
billingType,
|
||||
isLoggedIn: loggedIn,
|
||||
agentName,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,32 @@ export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS
|
|||
return getAPIProvider() as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a human-readable display name for the current API provider
|
||||
*/
|
||||
export function getProviderDisplayName(provider: APIProvider): string {
|
||||
switch (provider) {
|
||||
case 'firstParty':
|
||||
return 'Anthropic'
|
||||
case 'bedrock':
|
||||
return 'AWS Bedrock'
|
||||
case 'vertex':
|
||||
return 'Google Vertex'
|
||||
case 'foundry':
|
||||
return 'Foundry'
|
||||
case 'openai':
|
||||
return 'OpenAI'
|
||||
case 'gemini':
|
||||
return 'Google Gemini'
|
||||
case 'grok':
|
||||
return 'xAI Grok'
|
||||
case 'costrict':
|
||||
return 'CoStrict'
|
||||
default:
|
||||
return provider
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if ANTHROPIC_BASE_URL is a first-party Anthropic API URL.
|
||||
* Returns true if not set (default API) or points to api.anthropic.com
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user