ai.chat.complete ​
OpenAI-compatible chat completion (any provider), with optional provider web search and citations
Send a chat completion request to any OpenAI-compatible API.
Works with OpenAI, Anthropic (via openai-compat endpoint), AWS Bedrock proxy, Ollama, Together AI, Groq, and any provider that implements the /chat/completions endpoint.
Inputs:
- messages: List of {role, content} objects (required). Roles: user, assistant, system.
- model: Model ID override (optional, default: plugin.default_model).
- system_prompt: System instruction prepended as a system message (optional).
- temperature: Sampling temperature 0.0–2.0 (optional).
- max_tokens: Maximum tokens to generate (optional, default: 1024).
- attachment_uuids: List of StorageObject UUIDs to include as multimodal image content in the last user message (optional). Only image/* content types are supported in this version; non-image attachments are silently dropped when text is also present, or cause a WorkflowNotRetryableError when there is no accompanying text.
- web_search: Optional object. When {"enabled": true}, the answer is produced WITH the provider's own web search and normalized citations are returned. Absent (or enabled not true) = the unchanged Chat Completions behavior. Keys: enabled (bool), force (bool: require a search where the provider documents it), max_uses (int), user_location ({country, region, city, timezone}), allowed_domains / blocked_domains (lists; not both). The provider comes from the connection's API host: api.openai.com -> Responses API POST /v1/responses (web_search tool) api.anthropic.com -> Messages API POST /v1/messages (web_search_20250305) api.perplexity.ai -> Agent API POST /v1/agent (web_search tool) api.x.ai -> Responses API POST /v1/responses (web_search tool) *.openai.azure.com, *.services.ai.azure.com, *.cognitiveservices.azure.com -> Azure OpenAI v1 Responses API POST <base_url>/responses (web_search tool; base_url must be the /openai/v1 surface; api-key header, or Bearer when the stored credential is an Entra JWT) Any other host (Gemini/Google, OpenRouter, MiniMax, gateways) fails with web_search_unsupported_provider rather than answering without search. Options a provider cannot honor are listed in web_search_notes (e.g. xAI rejects user_location, so it is never sent). Cannot be combined with stream_to_workflow_id, tools, tool_choice, parallel_tool_calls, response_format or attachment_uuids.
Outputs (terminal state_data):
- content: str — assistant reply text
- role: str — always "assistant"
- finish_reason: str — stop | length | tool_calls | etc.
- model: str — model ID used
- input_tokens: int — prompt token count
- output_tokens: int — completion token count Only when web_search is enabled:
- citations: list of {url, title, domain, start_index, end_index, cited_text}; indices are character offsets into content, null when the provider gives no span
- web_search_performed: bool — read from the provider response, never assumed
- web_search_queries: list[str] — queries the provider reports it ran
- web_search_count: int — searches the provider reports (billed search calls)
- web_search_notes: list[str] — options not applied, search errors, citation provenance
- web_search_provider: str — openai | anthropic | perplexity | xai | azure_openai
Failure reasons added by web_search (failure_reason starts with one of): web_search_invalid_input, web_search_incompatible_input, web_search_streaming_unsupported, web_search_unsupported_provider, web_search_upstream_auth_failed, web_search_upstream_error, web_search_invalid_response
Plugin required: context.get_plugin("ai") must expose:
- .api_url — base URL, e.g. https://api.openai.com/v1
- .api_key — bearer token
- .default_model — fallback model ID
Overview ​
| Property | Value |
|---|---|
| Workflow type | Atomic |
| Library | App-ai |
| Version | 1.0 |
Input Schema ​
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
messages | json | Yes | — | List of {role, content} message objects |
model | string | No | — | Model ID (default: plugin.default_model) |
system_prompt | string | No | — | System instruction (prepended as system message) |
temperature | json | No | — | Sampling temperature 0.0–2.0 |
max_tokens | integer | No | — | Max tokens to generate (default: 1024) |
attachment_uuids | json | No | — | List of StorageObject UUIDs for multimodal image content |
tools | json | No | — | OpenAI-compatible tool definitions |
tool_choice | json | No | — | OpenAI-compatible tool_choice |
parallel_tool_calls | boolean | No | — | Whether the provider may return multiple tool calls |
response_format | json | No | — | OpenAI-compatible response_format |
timeout_seconds | integer | No | — | Provider HTTP timeout in seconds |
connection_uuid | uuid | No | — | Explicit AI CloudConnection UUID — resolved + decrypted directly (org-context-free, highest precedence). Mirrors ai.chat; lets async-DAG/consumer callers pass the org's connection without org context in context.metadata. |
ai_provider_config_uuid | uuid | No | — | Explicit AIProviderConfig UUID — resolved to its connection (second precedence, after connection_uuid). |
stream_to_workflow_id | string | No | — | When set, stream this completion (provider stream=True) and publish each content delta as a token frame to Redis channel dgi:tokens:<id>, so a live SSE consumer (GET /api/workflows/<id>/stream) can render tokens as they generate. The full message (content + tool_calls) is still reconstructed and returned unchanged, so the agent loop is unaffected. Absent = the existing synchronous behavior (zero change for every non-streaming caller). |
organization_uuid | uuid | No | — | Ignored when present — the organization is resolved from the authenticated context. Accepted so callers that inject it unconditionally (the agents tool runtime injects it into every workflow-skill call) do not fail input validation. |
web_search | json | No | — | Optional {enabled, force, max_uses, user_location: {country, region, city, timezone}, allowed_domains, blocked_domains}. When enabled is true the provider answers with its own web search (OpenAI, Anthropic, Perplexity, xAI, Azure OpenAI; chosen by the connection's API host) and citations are returned. Any other provider fails with web_search_unsupported_provider. Absent = unchanged Chat Completions behavior. |
Output Schema ​
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | No | — | — |
role | string | No | — | — |
message | json | No | — | — |
tool_calls | json | No | — | — |
finish_reason | string | No | — | — |
model | string | No | — | — |
provider_response_id | string | No | — | — |
input_tokens | integer | No | — | — |
output_tokens | integer | No | — | — |
total_tokens | integer | No | — | — |
usage | json | No | — | — |
citations | json | No | — | List of |
web_search_performed | boolean | No | — | Whether the provider reports it searched (read from the response) |
web_search_queries | json | No | — | Search queries the provider reports it ran |
web_search_count | integer | No | — | Number of searches the provider reports |
web_search_notes | json | No | — | Options the provider could not honor, search errors, citation provenance |
web_search_provider | string | No | — | openai |
failure_reason | string | No | — | — |
failure_type | string | No | — | — |
failed_action | string | No | — | — |
failed_at_state | string | No | — | — |
error | string | No | — | — |
error_type | string | No | — | — |
failed_step | string | No | — | — |
failed_layer | json | No | — | — |
failed_at | string | No | — | — |
States ​
| State | Initial | Terminal | Success | Auto-advance | Description |
|---|---|---|---|---|---|
pending | Yes | No | — | execute | — |
completed | No | Yes | Yes | — | — |
failed | No | Yes | No | — | — |
State Diagram ​
Transitions ​
| From | Action | To | Description |
|---|---|---|---|
pending | execute | completed | — |
* (any state) | fail | failed | — |
API Usage ​
bash
POST /api/workflows/start
Content-Type: application/json
{
"workflow_type": "ai.chat.complete",
"initial_data": {
"messages": "value"
}
}