Skip to main content

LLM Provider

The LLM capability is injected workflow through the Unified provider Interface. The service workflow is not directly bound to OpenAI, Anthropic, or other SDKs. Currently, real calls are adapted to the Vercel AI SDK.

Workflow supports two sources of provider: the project's own LLM_* environment variables and the security proxy configuration activated on Workflow Server for the current logon account. The former is reserved for self-owned keys and compatible projects, while the latter is suitable for scenarios where Server manages upstream keys, subscriptions, and balance permissions in a unified manner.

Server AI Configuration

Use workflow.getServerLLMCredentials() to get optional configurations and models for the current account:

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

The returned object exposes the stable configuration ID, name, platform, Core provider type, model list, and per-model modelDetails. The real Sub2API Key exists only briefly in Workflow Server memory; the one-hour proxy credentials are saved and refreshed by the Core closure, not the field of the returned object. OpenAI groupings map to openai-responses and Anthropic groupings map to anthropic; unknown platforms are not optional.

The returned array is arranged by the preferences saved by the current account in Desktop or web AI Configuration. If no preference is configured, the group ID is kept in ascending order; the new open group is appended to the existing preference. Server skips out-of-service, subscription stale, no valid key, platform unsupported, or model unusable configurations when generating a catalog, so credentials[0] is always the first available item in the current preference. workflow can continue to use the find(...) ?? credentials[0] fallback after the explicitly selected configuration fails; model requests that have already started are not automatically switched provider or resent.

Sub2API The current model directory determines whether the model is available;Workflow Server's versioned model capabilities directory supplements the returned model with display name, visual, networking, inference, and tool invocation capabilities. workflow should read from the modelDetails corresponding to the current model ID and not infer by name itself. Use selected.createProvider({ model, webSearch: true }) only if capabilities.webSearch is true; both Core and the agent are validated by the selected model.

Ordinary LLM calls use createProvider(). Agent SDKs that must receive a HTTP base URL can use startLLMProxyBridge() to create a runtime loopback bridge that matches the current configuration protocol; OpenAI Responses uses /responses and Anthropic uses /messages. Compatible callers that only support the OpenAI Responses can continue to use startOpenAIProxyBridge(). The bridge must be shut down after running. the agent sub-process can only see the local address and placeholder key, and cannot read the real Sub2API key or Workflow Server short-term proxy credentials.

The local Desktop resolver uses the Server URL and API key for the current signed-in account. For Server Web, account API-key, and signed-in Embed runs, Server issues a capability valid only for the resolver or run subprocess lifetime. Anonymous Embed, Webhook, and administrator keys without a user identity cannot access account AI configuration.

Create provider ref

It is recommended to create provider ref in workflow:

const llmProvider = workflow.createLLMProviderRef("default", () => {
return workflow.createLLMProviderFromEnv();
});

When the node runs, it parses the provider to prevent the business code from reading the environment variables during the module loading phase.

LLM node

Non-streaming nodes:

const llmNode = workflow.createLLMNode<Input>({
name: "answer-llm",
provider: llmProvider,
mapInput(input) {
return {
system: "You are a concise assistant.",
prompt: input.message,
maxOutputTokens: 300,
};
},
});

Streaming node:

const llmStreamNode = workflow.createLLMStreamNode<Input>({
name: "answer-stream",
provider: llmProvider,
mapInput(input) {
return {
messages: [{ role: "user", content: input.message }],
temperature: 0.2,
};
},
});

Project environment variables

workflow.createLLMProviderFromEnv() will read:

  • LLM_TYPE
  • LLM_API_KEY
  • LLM_BASE_URL
  • LLM_MODEL

These values are obtained uniformly by workflow.getEnv, so local CLI, Desktop local environment variables, and server environment variables can all use the same name.

createLLMProviderFromEnv() continues to be used for its own provider and does not automatically read the server AI configuration. Explicitly use getServerLLMCredentials() when account configuration is required. The latter selects complete connection pairs in the order of WORKFLOW_LLM_SERVER_URL/TOKEN, WORKFLOW_SERVER_URL/ADMIN_KEY, workspace CLI login states, and does not mix URLs and tokens from different sources.

Provider Type

The types supported by the current provider factory are from LLM_PROVIDER_TYPES. When no model is configured, the default model is selected by provider type. You can use mock provider when testing.

Output and Error

A LLM provider call failure is wrapped as a workflow error and entered into an execution report. The user-visible output should be produced through the output node, rather than relying directly on the original return of the provider.

The AI SDK reports unsupported optional call settings as unsupported or compatibility warnings, for example when a reasoning model ignores temperature. These warnings do not interrupt the call: supported settings still apply, unsupported settings are downgraded by the provider, and details remain available in providerMetadata["workflow-code"].warnings. Invalid values, authentication failures, unavailable models, and upstream request failures remain real call errors and are not downgraded.