fix(commandcode): preserve images and reasoning_effort on /alpha/generate
Command Code dropped vision and ignored client effort through the router:
image blocks became "[image omitted]", HTTP image URLs were never inlined,
and reasoning_effort landed on the envelope wrapper instead of params (so the
DeepSeek family mapping remapped low -> high). The catalog also treated
deepseek/deepseek-v4.1-flash as text-only, so the vision adapter stole those
requests to another provider.
- Map OpenAI image_url / Claude image blocks (base64 or data-URI) to the
native {type:"image", image:"data:...;base64,...", mimeType} generate block.
- Add FORMATS.COMMANDCODE to TARGETS_NEED_BASE64 so remote http(s) images are
inlined by the existing SSRF-safe fetcher before translation.
- Write reasoning_effort inside params for targetFormat commandcode and pass
low|medium|high|xhigh|max through unmapped; allow it in thinkingLevels.
- Provider-scoped capabilities for commandcode/cmc: vision except the CLI
text-only denylist, thinkingFormat commandcode, so family patterns
(deepseek-v4 -> thinkingFormat deepseek, vision false) no longer win.
- Quota Tracker: whoami + billing credits/subscriptions (credits vs plan cap,
5h and weekly windows), labels from AI_PROVIDERS[].name.
This commit is contained in:
@@ -40,7 +40,7 @@ import {
|
||||
} from "./utils";
|
||||
import Card from "@/shared/components/Card";
|
||||
import { ConfirmModal, EditConnectionModal } from "@/shared/components";
|
||||
import { USAGE_SUPPORTED_PROVIDERS } from "@/shared/constants/providers";
|
||||
import { USAGE_SUPPORTED_PROVIDERS, AI_PROVIDERS } from "@/shared/constants/providers";
|
||||
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
|
||||
|
||||
// Maps the stored providerSpecificData.authMethod to a human label for Kiro.
|
||||
@@ -100,6 +100,10 @@ function getCodexResetCreditCount(quota) {
|
||||
return Number.isFinite(count) ? Math.max(0, count) : 0;
|
||||
}
|
||||
|
||||
function providerLabel(providerId) {
|
||||
return AI_PROVIDERS[providerId]?.name || providerId;
|
||||
}
|
||||
|
||||
function formatCreditDate(value) {
|
||||
if (!value) return "N/A";
|
||||
const date = new Date(value);
|
||||
@@ -767,7 +771,7 @@ export default function ProviderLimits() {
|
||||
};
|
||||
|
||||
const selectedProviderLabel =
|
||||
providerFilter === "all" ? "All providers" : providerFilter;
|
||||
providerFilter === "all" ? "All providers" : providerLabel(providerFilter);
|
||||
const hasEligibleConnections = totals.eligibleConnections > 0;
|
||||
const hasVisibleConnections = sortedConnections.length > 0;
|
||||
const emptyState = getConnectionsEmptyMessage(
|
||||
@@ -844,7 +848,7 @@ export default function ProviderLimits() {
|
||||
fallbackText={providerFilter.slice(0, 2).toUpperCase()}
|
||||
/>
|
||||
)}
|
||||
<span className="truncate capitalize hidden lg:inline">
|
||||
<span className="truncate hidden lg:inline">
|
||||
{selectedProviderLabel}
|
||||
</span>
|
||||
</span>
|
||||
@@ -905,8 +909,8 @@ export default function ProviderLimits() {
|
||||
className="size-6 rounded-md object-contain"
|
||||
fallbackText={provider.slice(0, 2).toUpperCase()}
|
||||
/>
|
||||
<span className="font-medium capitalize">
|
||||
{provider}
|
||||
<span className="font-medium">
|
||||
{providerLabel(provider)}
|
||||
</span>
|
||||
{providerFilter === provider && (
|
||||
<span className="material-symbols-outlined ml-auto text-[20px]">
|
||||
@@ -1079,8 +1083,8 @@ export default function ProviderLimits() {
|
||||
/>
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<h3 className="text-sm font-semibold text-text-primary capitalize truncate">
|
||||
{conn.provider}
|
||||
<h3 className="text-sm font-semibold text-text-primary truncate">
|
||||
{providerLabel(conn.provider)}
|
||||
</h3>
|
||||
{getConnectionLabel(conn) ? (
|
||||
<p className="text-xs text-text-muted truncate">
|
||||
|
||||
Reference in New Issue
Block a user