fix: prevent SageMaker TGI from being marked configured when only Bedrock keys are set (#7284)
Signed-off-by: ibaaaaal rifaldi.51922721@mahasiswa.unikom.ac.id Co-authored-by: Lifei Zhou <lifei@squareup.com>
This commit is contained in:
@@ -323,7 +323,7 @@ impl ProviderDef for BedrockProvider {
|
||||
BEDROCK_DOC_LINK,
|
||||
vec![
|
||||
ConfigKey::new("AWS_PROFILE", false, false, Some("default"), true),
|
||||
ConfigKey::new("AWS_REGION", false, false, None, true),
|
||||
ConfigKey::new("AWS_REGION", true, false, Some("us-east-1"), true),
|
||||
ConfigKey::new("AWS_BEARER_TOKEN_BEDROCK", false, true, None, true),
|
||||
ConfigKey::new("BEDROCK_ENABLE_CACHING", false, false, Some("false"), false),
|
||||
],
|
||||
@@ -456,11 +456,18 @@ mod tests {
|
||||
.iter()
|
||||
.find(|k| k.name == "AWS_REGION")
|
||||
.expect("AWS_REGION config key should exist");
|
||||
assert!(!aws_region.required, "AWS_REGION should not be required");
|
||||
assert!(
|
||||
aws_region.required,
|
||||
"AWS_REGION is required for Bedrock to be marked as configured"
|
||||
);
|
||||
assert!(
|
||||
!aws_region.secret,
|
||||
"AWS_REGION should not be marked as secret"
|
||||
);
|
||||
assert!(
|
||||
aws_region.default.is_some(),
|
||||
"AWS_REGION should have a default value"
|
||||
);
|
||||
|
||||
let bearer_token = meta
|
||||
.config_keys
|
||||
|
||||
@@ -285,8 +285,8 @@ impl ProviderDef for SageMakerTgiProvider {
|
||||
SAGEMAKER_TGI_DOC_LINK,
|
||||
vec![
|
||||
ConfigKey::new("SAGEMAKER_ENDPOINT_NAME", true, false, None, true),
|
||||
ConfigKey::new("AWS_REGION", true, false, Some("us-east-1"), true),
|
||||
ConfigKey::new("AWS_PROFILE", true, false, Some("default"), true),
|
||||
ConfigKey::new("AWS_REGION", false, false, Some("us-east-1"), true),
|
||||
ConfigKey::new("AWS_PROFILE", false, false, Some("default"), true),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -145,11 +145,17 @@ export default function ChatInput({
|
||||
null
|
||||
) as React.RefObject<HTMLDivElement>;
|
||||
const { getProviders } = useConfig();
|
||||
const { getCurrentModelAndProvider, currentModel: configModel, currentProvider: configProvider } = useModelAndProvider();
|
||||
const {
|
||||
getCurrentModelAndProvider,
|
||||
currentModel: configModel,
|
||||
currentProvider: configProvider,
|
||||
} = useModelAndProvider();
|
||||
|
||||
// Local override for when the user changes the model in the modal,
|
||||
// before the session object is re-fetched from the backend.
|
||||
const [modelOverride, setModelOverride] = useState<{ model: string; provider: string } | null>(null);
|
||||
const [modelOverride, setModelOverride] = useState<{ model: string; provider: string } | null>(
|
||||
null
|
||||
);
|
||||
const effectiveModel = modelOverride?.model ?? sessionModel ?? configModel;
|
||||
const effectiveProvider = modelOverride?.provider ?? sessionProvider ?? configProvider;
|
||||
|
||||
@@ -157,8 +163,12 @@ export default function ChatInput({
|
||||
// active chats, config defaults for Hub / no-session contexts).
|
||||
useEffect(() => {
|
||||
if (!modelOverride) return;
|
||||
const sessionCaughtUp = sessionModel === modelOverride.model && sessionProvider === modelOverride.provider;
|
||||
const configCaughtUp = !sessionId && configModel === modelOverride.model && configProvider === modelOverride.provider;
|
||||
const sessionCaughtUp =
|
||||
sessionModel === modelOverride.model && sessionProvider === modelOverride.provider;
|
||||
const configCaughtUp =
|
||||
!sessionId &&
|
||||
configModel === modelOverride.model &&
|
||||
configProvider === modelOverride.provider;
|
||||
if (sessionCaughtUp || configCaughtUp) {
|
||||
setModelOverride(null);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,13 @@ interface CostTrackerProps {
|
||||
provider: string | null;
|
||||
}
|
||||
|
||||
export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts, model: currentModel, provider: currentProvider }: CostTrackerProps) {
|
||||
export function CostTracker({
|
||||
inputTokens = 0,
|
||||
outputTokens = 0,
|
||||
sessionCosts,
|
||||
model: currentModel,
|
||||
provider: currentProvider,
|
||||
}: CostTrackerProps) {
|
||||
const [costInfo, setCostInfo] = useState<ModelInfoData | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [showPricing, setShowPricing] = useState(true);
|
||||
|
||||
@@ -49,8 +49,12 @@ export const CreditsExhaustedNotification: React.FC<CreditsExhaustedNotification
|
||||
<div className="flex items-start gap-3">
|
||||
<AlertTriangle className="h-4 w-4 text-yellow-600 dark:text-yellow-400 mt-0.5 shrink-0" />
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-semibold text-yellow-800 dark:text-yellow-200">Insufficient Credits</div>
|
||||
<div className="text-sm text-yellow-800/80 dark:text-yellow-200/80 mt-1">{notification.msg}</div>
|
||||
<div className="text-sm font-semibold text-yellow-800 dark:text-yellow-200">
|
||||
Insufficient Credits
|
||||
</div>
|
||||
<div className="text-sm text-yellow-800/80 dark:text-yellow-200/80 mt-1">
|
||||
{notification.msg}
|
||||
</div>
|
||||
{topUpUrl && (
|
||||
<button
|
||||
onClick={handleTopUp}
|
||||
|
||||
@@ -206,10 +206,7 @@ export const DictationSettings = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<MicrophoneSelector
|
||||
selectedDeviceId={preferredMic}
|
||||
onDeviceChange={handleMicChange}
|
||||
/>
|
||||
<MicrophoneSelector selectedDeviceId={preferredMic} onDeviceChange={handleMicChange} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,10 @@ interface MicrophoneSelectorProps {
|
||||
|
||||
const TEST_DURATION_MS = 5000;
|
||||
|
||||
export const MicrophoneSelector = ({ selectedDeviceId, onDeviceChange }: MicrophoneSelectorProps) => {
|
||||
export const MicrophoneSelector = ({
|
||||
selectedDeviceId,
|
||||
onDeviceChange,
|
||||
}: MicrophoneSelectorProps) => {
|
||||
const [devices, setDevices] = useState<MediaDeviceInfo[]>([]);
|
||||
const [hasPermission, setHasPermission] = useState(false);
|
||||
const [isTesting, setIsTesting] = useState(false);
|
||||
@@ -163,9 +166,7 @@ export const MicrophoneSelector = ({ selectedDeviceId, onDeviceChange }: Microph
|
||||
value={selectedDeviceId ?? 'system_default'}
|
||||
onValueChange={(v) => onDeviceChange(v === 'system_default' ? null : v)}
|
||||
>
|
||||
<DropdownMenuRadioItem value="system_default">
|
||||
System Default
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="system_default">System Default</DropdownMenuRadioItem>
|
||||
{devices.map((device, i) => (
|
||||
<DropdownMenuRadioItem key={device.deviceId} value={device.deviceId}>
|
||||
<span className="truncate">{getDeviceLabel(device, i)}</span>
|
||||
|
||||
@@ -101,7 +101,11 @@ export const SwitchModelModal = ({
|
||||
sessionProvider,
|
||||
}: SwitchModelModalProps) => {
|
||||
const { getProviders, read, upsert } = useConfig();
|
||||
const { changeModel, currentModel: configModel, currentProvider: configProvider } = useModelAndProvider();
|
||||
const {
|
||||
changeModel,
|
||||
currentModel: configModel,
|
||||
currentProvider: configProvider,
|
||||
} = useModelAndProvider();
|
||||
// Use session-specific model/provider if available, otherwise fall back to config defaults
|
||||
const currentModel = sessionModel ?? configModel;
|
||||
const currentProvider = sessionProvider ?? configProvider;
|
||||
|
||||
Reference in New Issue
Block a user