Skip to main content

getServerLLMCredentials

workflow.getServerLLMCredentials() obtains the AI configuration that the user has enabled from the currently connected Workflow Server. The real Sub2API Key is always read by Server and injected into the upstream request, and does not enter the workflow process, Desktop, browser response, or return object.

Returns an array sorted by the provider usage preferences saved by the current account. Server skips configurations that are not currently available, and subsequent valid items remain in relative order; an explicit provider has failed to fall back to credentials[0]. This behavior occurs only during the catalog selection phase and does not replay streaming requests, tool calls, or normal model requests that have already started.

Signature

workflow.getServerLLMCredentials(options?: {
signal?: AbortSignal;
}): Promise<WorkflowServerLLMCredential[]>

interface WorkflowServerLLMCredential {
readonly id: string;
readonly name: string;
readonly platform: string;
readonly providerType: LLMProviderType;
readonly models: readonly string[];
readonly modelDetails: readonly {
readonly id: string;
readonly name: string;
readonly capabilities: {
readonly vision: boolean;
readonly webSearch: boolean;
readonly reasoning: boolean;
readonly toolCalling: boolean;
};
}[];
createProvider(options: {
model: string;
system?: string;
defaults?: LLMCallSettings;
webSearch?: boolean;
}): LLMProvider;
startOpenAIProxyBridge(options?: {
signal?: AbortSignal;
}): Promise<{
baseUrl: string;
apiKey: string;
close(): Promise<void>;
}>;
startLLMProxyBridge(options?: {
signal?: AbortSignal;
}): Promise<{
baseUrl: string;
apiKey: string;
close(): Promise<void>;
}>;
}

Connection Source

Core Select the complete URL/token pair in the following order, without mixing different sources:

  1. WORKFLOW_LLM_SERVER_URL and WORKFLOW_LLM_SERVER_TOKEN
  2. WORKFLOW_SERVER_URL and WORKFLOW_SERVER_ADMIN_KEY
  3. workspace CLI saved login status

An error is reported directly when only half of the explicit environment variables are configured. Server runner injects process lifecycle capability for resolver and runs with user identities; anonymous Embed, Webhook, and administrator keys without user identities cannot obtain user AI configuration.

Example

const credentials = await workflow.getServerLLMCredentials({
signal: abortSignal,
});
const selected = credentials.find((item) => item.id === providerId) ?? credentials[0];

if (!selected || !selected.models.includes(model)) {
throw new workflow.WorkflowError({
type: "input_validation",
message: "The selected AI configuration or model is unavailable.",
});
}

const provider = selected.createProvider({ model });

models is still determined by the Sub2API current grouping real-time model list, and modelDetails is supplemented by Workflow Server's versioned model capabilities directory with display names and visual, networking, inference, and tool invocation capabilities. Models that are not recognized by the catalog will not be moved out models, but the 4 item capabilities are all false and will not be temporarily guessed by name.

webSearch: true can only be passed in if the modelDetails[].capabilities.webSearch of the selected model is true. Core injects a web_search provider tool for OpenAI Responses and a versioned Web Search tool for Anthropic Messages; if the capability is not declared, it will be rejected before the request is made. The agent also reads the model from the request body and checks it again, and cannot be bypassed with old parameters or by calling the agent directly.

When you need to hand over the system AI configuration to the agent SDK that only accepts the HTTP base URL, you can start a temporary local bridge that matches the configuration protocol:

const bridge = await selected.startLLMProxyBridge({ signal: abortSignal });
try {
const client = new AgentSdk({ baseUrl: bridge.baseUrl, apiKey: bridge.apiKey });
await client.run({ model });
} finally {
await bridge.close();
}

The local bridge binds only random 127.0.0.1 ports and paths. OpenAI Responses configuration only open /responses and Anthropic configuration only open /messages; both limit the request body to 50 MiB and support JSON, SSE streaming response and cancellation. apiKey is only a local placeholder value, not a Sub2API Key, a Workflow Server login credential, or a one-hour proxy credential. The caller must close the bridge on success, failure, and cancellation paths.

startOpenAIProxyBridge() is reserved for existing callers that only support OpenAI Responses. It rejects Anthropic configuration; new agent integrations use startLLMProxyBridge() first.

Credential Refresh

The one-hour proxy credentials issued by Server are saved in the Core closure and are not exposed as object fields. The validity period is checked before each provider or local bridge request. If the refresh is triggered after 60 seconds, concurrent refreshes on the same object will be merged. If the refresh fails but the old credentials are still valid, the old credentials continue to be used, and an explicit provider error is returned after expiration. An established streaming request only validates the credentials at the beginning and is not interrupted by the expiration of the transmission period.

Error

SceneTypeBehavior
No complete Server connectioninput_validationRequire login or pair configuration URL/token.
No configuration is available for the current accountinput_validationRequires subscription activation or balance billing configuration.
Invalid directory protocol, refresh failed, or configuration failureprovider_callThe proxy token, real key, or upstream error body is not returned.