Add onboarding retry action to unset ANTHROPIC_API_KEY
This commit is contained in:
@@ -89,6 +89,9 @@ export function OnboardingWizard() {
|
|||||||
useState<AdapterEnvironmentTestResult | null>(null);
|
useState<AdapterEnvironmentTestResult | null>(null);
|
||||||
const [adapterEnvError, setAdapterEnvError] = useState<string | null>(null);
|
const [adapterEnvError, setAdapterEnvError] = useState<string | null>(null);
|
||||||
const [adapterEnvLoading, setAdapterEnvLoading] = useState(false);
|
const [adapterEnvLoading, setAdapterEnvLoading] = useState(false);
|
||||||
|
const [forceUnsetAnthropicApiKey, setForceUnsetAnthropicApiKey] =
|
||||||
|
useState(false);
|
||||||
|
const [unsetAnthropicLoading, setUnsetAnthropicLoading] = useState(false);
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
|
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
|
||||||
@@ -159,6 +162,15 @@ export function OnboardingWizard() {
|
|||||||
}, [step, adapterType, cwd, model, command, args, url]);
|
}, [step, adapterType, cwd, model, command, args, url]);
|
||||||
|
|
||||||
const selectedModel = (adapterModels ?? []).find((m) => m.id === model);
|
const selectedModel = (adapterModels ?? []).find((m) => m.id === model);
|
||||||
|
const hasAnthropicApiKeyOverrideCheck =
|
||||||
|
adapterEnvResult?.checks.some(
|
||||||
|
(check) =>
|
||||||
|
check.code === "claude_anthropic_api_key_overrides_subscription"
|
||||||
|
) ?? false;
|
||||||
|
const shouldSuggestUnsetAnthropicApiKey =
|
||||||
|
adapterType === "claude_local" &&
|
||||||
|
adapterEnvResult?.status === "fail" &&
|
||||||
|
hasAnthropicApiKeyOverrideCheck;
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
setStep(1);
|
setStep(1);
|
||||||
@@ -176,6 +188,8 @@ export function OnboardingWizard() {
|
|||||||
setAdapterEnvResult(null);
|
setAdapterEnvResult(null);
|
||||||
setAdapterEnvError(null);
|
setAdapterEnvError(null);
|
||||||
setAdapterEnvLoading(false);
|
setAdapterEnvLoading(false);
|
||||||
|
setForceUnsetAnthropicApiKey(false);
|
||||||
|
setUnsetAnthropicLoading(false);
|
||||||
setTaskTitle("Create your CEO HEARTBEAT.md");
|
setTaskTitle("Create your CEO HEARTBEAT.md");
|
||||||
setTaskDescription(DEFAULT_TASK_DESCRIPTION);
|
setTaskDescription(DEFAULT_TASK_DESCRIPTION);
|
||||||
setCreatedCompanyId(null);
|
setCreatedCompanyId(null);
|
||||||
@@ -191,7 +205,7 @@ export function OnboardingWizard() {
|
|||||||
|
|
||||||
function buildAdapterConfig(): Record<string, unknown> {
|
function buildAdapterConfig(): Record<string, unknown> {
|
||||||
const adapter = getUIAdapter(adapterType);
|
const adapter = getUIAdapter(adapterType);
|
||||||
return adapter.buildAdapterConfig({
|
const config = adapter.buildAdapterConfig({
|
||||||
...defaultCreateValues,
|
...defaultCreateValues,
|
||||||
adapterType,
|
adapterType,
|
||||||
cwd,
|
cwd,
|
||||||
@@ -208,9 +222,22 @@ export function OnboardingWizard() {
|
|||||||
? DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX
|
? DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX
|
||||||
: defaultCreateValues.dangerouslyBypassSandbox
|
: defaultCreateValues.dangerouslyBypassSandbox
|
||||||
});
|
});
|
||||||
|
if (adapterType === "claude_local" && forceUnsetAnthropicApiKey) {
|
||||||
|
const env =
|
||||||
|
typeof config.env === "object" &&
|
||||||
|
config.env !== null &&
|
||||||
|
!Array.isArray(config.env)
|
||||||
|
? { ...(config.env as Record<string, unknown>) }
|
||||||
|
: {};
|
||||||
|
env.ANTHROPIC_API_KEY = { type: "plain", value: "" };
|
||||||
|
config.env = env;
|
||||||
|
}
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runAdapterEnvironmentTest(): Promise<AdapterEnvironmentTestResult | null> {
|
async function runAdapterEnvironmentTest(
|
||||||
|
adapterConfigOverride?: Record<string, unknown>
|
||||||
|
): Promise<AdapterEnvironmentTestResult | null> {
|
||||||
if (!createdCompanyId) {
|
if (!createdCompanyId) {
|
||||||
setAdapterEnvError(
|
setAdapterEnvError(
|
||||||
"Create or select a company before testing adapter environment."
|
"Create or select a company before testing adapter environment."
|
||||||
@@ -224,7 +251,7 @@ export function OnboardingWizard() {
|
|||||||
createdCompanyId,
|
createdCompanyId,
|
||||||
adapterType,
|
adapterType,
|
||||||
{
|
{
|
||||||
adapterConfig: buildAdapterConfig()
|
adapterConfig: adapterConfigOverride ?? buildAdapterConfig()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
setAdapterEnvResult(result);
|
setAdapterEnvResult(result);
|
||||||
@@ -311,6 +338,55 @@ export function OnboardingWizard() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleUnsetAnthropicApiKey() {
|
||||||
|
if (!createdCompanyId || unsetAnthropicLoading) return;
|
||||||
|
setUnsetAnthropicLoading(true);
|
||||||
|
setError(null);
|
||||||
|
setAdapterEnvError(null);
|
||||||
|
setForceUnsetAnthropicApiKey(true);
|
||||||
|
|
||||||
|
const configWithUnset = (() => {
|
||||||
|
const config = buildAdapterConfig();
|
||||||
|
const env =
|
||||||
|
typeof config.env === "object" &&
|
||||||
|
config.env !== null &&
|
||||||
|
!Array.isArray(config.env)
|
||||||
|
? { ...(config.env as Record<string, unknown>) }
|
||||||
|
: {};
|
||||||
|
env.ANTHROPIC_API_KEY = { type: "plain", value: "" };
|
||||||
|
config.env = env;
|
||||||
|
return config;
|
||||||
|
})();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (createdAgentId) {
|
||||||
|
await agentsApi.update(
|
||||||
|
createdAgentId,
|
||||||
|
{ adapterConfig: configWithUnset },
|
||||||
|
createdCompanyId
|
||||||
|
);
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: queryKeys.agents.list(createdCompanyId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await runAdapterEnvironmentTest(configWithUnset);
|
||||||
|
if (result?.status === "fail") {
|
||||||
|
setError(
|
||||||
|
"Retried with ANTHROPIC_API_KEY unset in adapter config, but the environment test is still failing."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setError(
|
||||||
|
err instanceof Error
|
||||||
|
? err.message
|
||||||
|
: "Failed to unset ANTHROPIC_API_KEY and retry."
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setUnsetAnthropicLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleStep3Next() {
|
async function handleStep3Next() {
|
||||||
if (!createdCompanyId || !createdAgentId) return;
|
if (!createdCompanyId || !createdAgentId) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -673,6 +749,24 @@ export function OnboardingWizard() {
|
|||||||
<AdapterEnvironmentResult result={adapterEnvResult} />
|
<AdapterEnvironmentResult result={adapterEnvResult} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{shouldSuggestUnsetAnthropicApiKey && (
|
||||||
|
<div className="rounded-md border border-amber-300/60 bg-amber-50/40 px-2.5 py-2 space-y-2">
|
||||||
|
<p className="text-[11px] text-amber-900/90 leading-relaxed">
|
||||||
|
Claude failed while <span className="font-mono">ANTHROPIC_API_KEY</span> is set.
|
||||||
|
You can clear it in this CEO adapter config and retry the probe.
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
className="h-7 px-2.5 text-xs"
|
||||||
|
disabled={adapterEnvLoading || unsetAnthropicLoading}
|
||||||
|
onClick={() => void handleUnsetAnthropicApiKey()}
|
||||||
|
>
|
||||||
|
{unsetAnthropicLoading ? "Retrying..." : "Unset ANTHROPIC_API_KEY"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="rounded-md border border-border/70 bg-muted/20 px-2.5 py-2 text-[11px] space-y-1.5">
|
<div className="rounded-md border border-border/70 bg-muted/20 px-2.5 py-2 text-[11px] space-y-1.5">
|
||||||
<p className="font-medium">Manual debug</p>
|
<p className="font-medium">Manual debug</p>
|
||||||
<p className="text-muted-foreground font-mono break-all">
|
<p className="text-muted-foreground font-mono break-all">
|
||||||
|
|||||||
Reference in New Issue
Block a user