fix(frontend): prefill host pattern in CoPilot credential setup modal

The SetupRequirementsCard passed inputValues={{}} to CredentialsGroupedView,
which meant the HostScopedCredentialsModal never received the target URL
from the backend's discriminator_values. The "Host Pattern" field was always
empty even though the CoPilot knew the exact host (e.g. api.openai.com).

Add buildSiblingInputsFromCredentials() to extract the discriminator value
(URL) from the missing_credentials setup_info and pass it as siblingInputs
so the modal can prefill the host pattern.
This commit is contained in:
Zamil Majdy
2026-04-02 12:40:45 +02:00
parent 9ab6082a23
commit a8bb6b5544
2 changed files with 45 additions and 1 deletions

View File

@@ -11,6 +11,7 @@ import { useCopilotChatActions } from "../../../../components/CopilotChatActions
import { ContentMessage } from "../../../../components/ToolAccordion/AccordionContent";
import {
buildExpectedInputsSchema,
buildSiblingInputsFromCredentials,
coerceCredentialFields,
coerceExpectedInputs,
} from "./helpers";
@@ -46,6 +47,10 @@ export function SetupRequirementsCard({
output.setup_info.user_readiness?.missing_credentials,
);
const siblingInputs = buildSiblingInputsFromCredentials(
output.setup_info.user_readiness?.missing_credentials,
);
const expectedInputs = coerceExpectedInputs(
(output.setup_info.requirements as Record<string, unknown>)?.inputs,
);
@@ -118,7 +123,7 @@ export function SetupRequirementsCard({
credentialFields={credentialFields}
requiredCredentials={requiredCredentials}
inputCredentials={inputCredentials}
inputValues={{}}
inputValues={siblingInputs}
onCredentialChange={handleCredentialChange}
/>
</div>

View File

@@ -71,6 +71,45 @@ export function coerceCredentialFields(rawMissingCredentials: unknown): {
return { credentialFields, requiredCredentials };
}
/**
* Build a sibling-inputs dict from the missing_credentials discriminator values.
*
* When the backend resolves credentials for host-scoped blocks (e.g.
* SendAuthenticatedWebRequestBlock), it adds the target URL to
* `discriminator_values`. The credential modal uses `siblingInputs`
* to extract the host and prefill the "Host Pattern" field.
*
* This function builds that mapping from the `discriminator` field name
* and the first `discriminator_values` entry for each credential.
*/
export function buildSiblingInputsFromCredentials(
rawMissingCredentials: unknown,
): Record<string, unknown> {
const result: Record<string, unknown> = {};
if (!rawMissingCredentials || typeof rawMissingCredentials !== "object")
return result;
const missing = rawMissingCredentials as Record<string, unknown>;
for (const value of Object.values(missing)) {
if (!value || typeof value !== "object") continue;
const cred = value as Record<string, unknown>;
const discriminator =
typeof cred.discriminator === "string" ? cred.discriminator : null;
const discriminatorValues = Array.isArray(cred.discriminator_values)
? cred.discriminator_values.filter(
(v): v is string => typeof v === "string",
)
: [];
if (discriminator && discriminatorValues.length > 0) {
result[discriminator] = discriminatorValues[0];
}
}
return result;
}
export function coerceExpectedInputs(rawInputs: unknown): Array<{
name: string;
title: string;