Skip to content
Back to skills

2044 Workflow Nodes 81a3fb81

ASecurity

This document provides an exhaustive reference for all available non-memory-related nodes within the WilmerAI workflow system. It is designed to be a complete guide for an LLM to understand the purpose, configuration, and proper usage of each node.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentjavascriptpythongojavanodeexpressdebuggingapidatabasebackend

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2044-workflow_nodes_81a3fb81 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2044 Workflow Nodes 81a3fb81?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2044 Workflow Nodes 81a3fb81
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2044-workflow-nodes-81a3fb81/badge)](https://www.skillsdirectory.com/skills/tools-only-2044-workflow-nodes-81a3fb81)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
## A Comprehensive Guide to WilmerAI Workflow Nodes

This document provides an exhaustive reference for all available non-memory-related nodes within the WilmerAI workflow
system. It is designed to be a complete guide for an LLM to understand the purpose, configuration, and proper usage of
each node.

-----

### **Core LLM Interaction: The `Standard` Node**

The **`Standard` Node** (also referred to as `Conversational`) is the fundamental building block for all direct
interactions with a Large Language Model (LLM). Its primary purpose is to assemble a prompt from various sources of
context (conversation history, previous node outputs, static text), send it to a specified LLM backend, and process the
response.

#### **Properties**

| Property                                    | Type    | Required | Default    | Description                                                                                                                           |
|:--------------------------------------------|:--------|:---------|:-----------|:--------------------------------------------------------------------------------------------------------------------------------------|
| **`type`**                                  | String  | Yes      | `Standard` | The node type. Best practice is to always include it for clarity.                                                                     |
| **`title`**                                 | String  | No       | `""`       | A descriptive name for the node, used for logging and debugging.                                                                      |
| **`endpointName`**                          | String  | Yes      | N/A        | The name of the LLM endpoint configuration. **Supports LIMITED variables: only `{agent#Input}` and static workflow variables, NOT `{agent#Output}`.**  |
| **`preset`**                                | String  | Yes      | N/A        | The name of the generation preset to use. If omitted, the endpoint's default is used. **Supports LIMITED variables like endpointName.** |
| **`returnToUser`**                          | Boolean | No       | `false`    | If `true`, this node's output is sent to the user. Only one node per workflow can be a responder.                                     |
| **`systemPrompt`**                          | String  | Yes      | N/A        | The system prompt or initial instruction set for the LLM. Supports variable substitution.                                             |
| **`prompt`**                                | String  | Yes      | N/A        | The main user-facing prompt. If this is empty, the node will use `lastMessagesToSendInsteadOfPrompt`. Supports variable substitution. |
| **`lastMessagesToSendInsteadOfPrompt`**     | Integer | No       | `5`        | If `prompt` is empty, this specifies how many recent conversational turns to use as the prompt.                                       |
| **`maxResponseSizeInTokens`**               | Integer/String | No       | `400`      | Overrides the maximum number of tokens the LLM can generate for this node. **Supports LIMITED variables like endpointName.**         |
| **`maxContextTokenSize`**                   | Integer | No       | `4096`     | Overrides the maximum context window size (in tokens) for this node.                                                                  |
| **`nMessagesToIncludeInVariable`**           | Integer | No       | `5`        | Controls how many messages are included in the `{chat_user_prompt_n_messages}` and `{templated_user_prompt_n_messages}` variables.    |
| **`estimatedTokensToIncludeInVariable`**    | Integer | No       | `2048`     | Controls the estimated token budget for the `{chat_user_prompt_estimated_token_limit}` and `{templated_user_prompt_estimated_token_limit}` variables. Messages are included from most recent backwards until the budget is reached. At least one message is always included. |
| **`minMessagesInVariable`**                 | Integer | No       | `5`        | Used with `maxEstimatedTokensInVariable`. Sets the minimum message count for the `{chat_user_prompt_min_n_max_tokens}` and `{templated_user_prompt_min_n_max_tokens}` variables. These messages are always included regardless of the token budget. |
| **`maxEstimatedTokensInVariable`**          | Integer | No       | `2048`     | Used with `minMessagesInVariable`. Sets the token budget for expansion beyond the minimum message count. After the minimum messages are included, older messages are added until this budget would be exceeded. |
| **`jinja2`**                                | Boolean | No       | `false`    | If `true`, enables Jinja2 templating for the `systemPrompt` and `prompt` fields.                                                      |
| **`addDiscussionIdTimestampsForLLM`**       | Boolean | No       | `false`    | If `true`, automatically injects timestamps into the `messages` payload sent to the LLM.                                              |
| **`useRelativeTimestamps`**                 | Boolean | No       | `false`    | If `addDiscussionIdTimestampsForLLM` is `true`, this uses relative timestamps (e.g., "5 minutes ago").                                |
| **`useGroupChatTimestampLogic`**            | Boolean | No       | `false`    | Activates special timestamping logic for group chat-style generation prompts.                                                         |
| **`addUserTurnTemplate`**                   | Boolean | No       | `false`    | Manually wraps the final prompt content in the user turn template defined by the endpoint.                                            |
| **`addOpenEndedAssistantTurnTemplate`**     | Boolean | No       | `false`    | Appends the start of an assistant turn template to the end of the final prompt.                                                       |
| **`forceGenerationPromptIfEndpointAllows`** | Boolean | No       | `false`    | Forces the addition of a generation prompt even if other settings would normally suppress it.                                         |
| **`blockGenerationPrompt`**                 | Boolean | No       | `false`    | Explicitly blocks the addition of any automatic generation prompt.                                                                    |

#### **Limitations and Key Usage Notes**

* **Variable Support:** Full variables are supported in the `systemPrompt` and `prompt` fields. The `endpointName`,
  `preset`, and `maxResponseSizeInTokens` fields support LIMITED variables (only `{agent#Input}` from parent workflows
  and static variables defined in the workflow JSON, NOT `{agent#Output}` which doesn't exist yet). For
  `maxResponseSizeInTokens`, the variable must resolve to a valid integer string (e.g., `"5000"`).
* **Responder Node:** Only one node in a workflow can have `returnToUser` set to `true`. If no node is designated, the
  last node in the workflow automatically becomes the responder.
* **Prompt Fallback:** The node prioritizes the `prompt` field. If it's empty, it will fall back to using the
  conversation history as defined by `lastMessagesToSendInsteadOfPrompt`.

#### **Full Syntax Example**

This example shows a non-responder "thinking" node that synthesizes information from previous nodes and the conversation
history.

```json
{
  "title": "LLM Thinking Over to User Request",
  "type": "Standard",
  "systemPrompt": "System Information: Today is {todays_date_pretty}. The user is {human_persona_name}.\n\n<your_profile>\n{agent3Output}\n</your_profile>\n\n<user_profile>\n{agent2Output}\n</user_profile>",
  "prompt": "Please consider the most recent twenty messages of your online conversation with {human_persona_name}:\n\n<recent_conversation>\n{chat_user_prompt_last_twenty}\n</recent_conversation>\n\nPlease think carefully about all of this by answering the following questions:\n- A) How long has it been since the last message?\n- B) What did {human_persona_name} mean in their last message to you?\n- C) Carefully consider what the best way to respond might be.",
  "endpointName": "Thinker-Endpoint",
  "preset": "Thinker-Preset",
  "maxResponseSizeInTokens": 8000,
  "addUserTurnTemplate": true,
  "returnToUser": false,
  "addDiscussionIdTimestampsForLLM": true,
  "useRelativeTimestamps": true
}
```

#### **Variable Substitution for Child Workflows**

When calling a child workflow via `CustomWorkflow`, you can pass dynamic values for `endpointName`, `preset`, and
`maxResponseSizeInTokens` using `scoped_variables`. This allows the parent workflow to control which endpoint, preset,
and response size the child uses.

**Parent Workflow (calls the child with dynamic config):**

```json
{
  "title": "Run Analysis with Custom Settings",
  "type": "CustomWorkflow",
  "workflowName": "General_Workflow_Replaceable_Endpoint",
  "workflowUserFolderOverride": "_common",
  "scoped_variables": [
    "MyDynamicEndpoint",
    "MyDynamicPreset",
    "6000"
  ]
}
```

**Child Workflow (receives the values as `{agent#Input}`):**

```json
{
  "title": "Responding Agent",
  "type": "Standard",
  "endpointName": "{agent1Input}",
  "preset": "{agent2Input}",
  "maxResponseSizeInTokens": "{agent3Input}",
  "systemPrompt": "...",
  "prompt": ""
}
```

In this example, the child workflow will use endpoint `MyDynamicEndpoint`, preset `MyDynamicPreset`, and generate up to
`6000` tokens.

-----

### **Logic & Control Flow: The `Conditional` Node**

The **`Conditional`** node is a control flow utility that evaluates a complex logical expression and returns the string
`"TRUE"` or `"FALSE"`. Its output is designed to be used by a `ConditionalCustomWorkflow` node to make branching
decisions. It supports comparisons, logical operators (`AND`, `OR`), and parentheses `()` for grouping.

#### **Properties**

| Property           | Type    | Required | Default | Description                                                                                                     |
|:-------------------|:--------|:---------|:--------|:----------------------------------------------------------------------------------------------------------------|
| **`type`**         | String  | Yes      | N/A     | Must be `"Conditional"`.                                                                                        |
| **`title`**        | String  | No       | `""`    | A descriptive name for the node, used for logging and debugging.                                                |
| **`condition`**    | String  | Yes      | N/A     | The logical expression to evaluate (e.g., `({val} >= 100 AND '{status}' != 'ERROR') OR {is_override} == TRUE`). |
| **`returnToUser`** | Boolean | No       | `false` | This node is designed for internal logic; its output is not intended for the end-user.                          |

#### **Limitations and Key Usage Notes**

* **Variable Support:** The `condition` property supports all available workflow variables.
* **Type Inference:** The node intelligently infers types. Values in quotes (e.g., `'complete'`) are strings. Unquoted
  `TRUE` or `FALSE` are booleans. Other unquoted values are treated as numbers if possible, otherwise as strings.
* **IMPORTANT:** Be careful when doing comparisons. The node distinguishes between a boolean and a string. The output of
  a `Conditional` node is a boolean `TRUE` or `FALSE`. If `agent3Output` comes from a `Conditional` node and is `TRUE`,
  the comparison `"{agent3Output} == 'TRUE'"` will be **FALSE** because `(boolean) TRUE` is not equal to
  `(string) 'TRUE'`. The correct comparison is `"{agent3Output} == TRUE"`.

#### **Full Syntax Example**

This example demonstrates complex logic with `OR` and parentheses, checking for multiple valid states or an override
condition.

```json
{
  "title": "Check for valid state or admin override",
  "type": "Conditional",
  "condition": "({agent1Output} == 'Admin') OR ({agent2Output} == 'Approved' AND {agent3Output} == TRUE)"
}
```

-----

### **In-Workflow Routing: The `ConditionalCustomWorkflow` Node**

The **`ConditionalCustomWorkflow` Node** provides powerful branching logic. It dynamically selects and executes a
sub-workflow based on the value of a conditional variable (e.g., the output from a `Conditional` node). It also supports
a default content fallback, preventing the need for an extra workflow file for a simple default response.

#### **Properties**

| Property                                 | Type             | Required | Default | Description                                                                                                                          |
|:-----------------------------------------|:-----------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------|
| **`type`**                               | String           | Yes      | N/A     | Must be set to `"ConditionalCustomWorkflow"`.                                                                                        |
| **`title`**                              | String           | No       | `""`    | A descriptive title for the node shown in logs.                                                                                      |
| **`is_responder`**                       | Boolean          | No       | `false` | Determines if the output provides the final user-facing response. Renamed from `returnToUser` for clarity.                           |
| **`conditionalKey`**                     | String           | Yes      | N/A     | A variable placeholder (e.g., `{agent1Output}`) whose resolved value determines which workflow to execute.                           |
| **`conditionalWorkflows`**               | Object           | Yes      | N/A     | A dictionary mapping possible values of `conditionalKey` to workflow filenames. A special `"Default"` key can be used as a fallback. |
| **`UseDefaultContentInsteadOfWorkflow`** | String           | No       | `null`  | A string (supports variables) to return as output if no condition is met. This takes precedence over the `"Default"` workflow.       |
| **`scoped_variables`**                   | Array of Strings | No       | `[]`    | A list of values to pass into whichever child workflow is chosen.                                                                    |
| **`routeOverrides`**                     | Object           | No       | `{}`    | A dictionary specifying prompt overrides for each potential route. Keys should correspond to keys in `conditionalWorkflows`.         |
| **`workflowUserFolderOverride`**         | String           | No       | `null`  | Specifies a user folder from which to load the selected workflow. Use `_common` for shared workflows.                                |

#### **Limitations and Key Usage Notes**

* **IMPORTANT:** Only `scoped_variables`, `UseDefaultContentInsteadOfWorkflow`, and `conditionalKey` support workflow
  variables.
* **You cannot set a variable as a workflow name.** Configuration keys like workflow names inside `conditionalWorkflows`
  and `routeOverrides` must be static, hardcoded strings.
* **Matching Logic:** The match for `conditionalWorkflows` is **case-insensitive**. However, the match for
  `routeOverrides` keys is **case-sensitive** and expects the key to be **Capitalized**.

#### **Full Syntax Example**

This node routes to a specialized coding workflow based on the language detected in a previous step.

```json
{
  "title": "Route to a Specific Coding Model",
  "type": "ConditionalCustomWorkflow",
  "is_responder": true,
  "conditionalKey": "{agent1Output}",
  "workflowUserFolderOverride": "_common",
  "conditionalWorkflows": {
    "Python": "PythonCodingWorkflow",
    "JavaScript": "JavaScriptCodingWorkflow",
    "Default": "GeneralCodingWorkflow"
  },
  "UseDefaultContentInsteadOfWorkflow": "I'm sorry, I can only assist with Python and JavaScript at the moment.",
  "scoped_variables": [
    "{agent2Output}"
  ],
  "routeOverrides": {
    "Python": {
      "systemPromptOverride": "You are an expert Python programmer. The user's request is: {agent1Input}"
    },
    "JavaScript": {
      "systemPromptOverride": "You are a master JavaScript developer. The user's request is: {agent1Input}"
    }
  }
}
```

> Values sent in as scoped_variables are accessible within the child workflow that is called as agentXInputs. So
> the first scoped_variable is agent1Input, second scoped_variable is agent2Input, etc.

-----

### **Modular Logic: The `CustomWorkflow` Node**

The **`CustomWorkflow` Node** allows you to execute a separate workflow from within the current one. This is essential
for encapsulating reusable logic and breaking down complex processes. Child workflows run in an isolated context; data
must be passed in explicitly via `scoped_variables`.

#### **Properties**

| Property                            | Type             | Required | Default | Description                                                                                                         |
|:------------------------------------|:-----------------|:---------|:--------|:--------------------------------------------------------------------------------------------------------------------|
| **`type`**                          | String           | Yes      | N/A     | Must be set to `"CustomWorkflow"`.                                                                                  |
| **`title`**                         | String           | No       | `""`    | A descriptive title for the node shown in logs.                                                                     |
| **`workflowName`**                  | String           | Yes      | N/A     | The filename of the child workflow to execute (without the `.json`).                                                |
| **`is_responder`**                  | Boolean          | No       | `false` | Determines if this node provides the final user-facing response. Renamed from `returnToUser`.                       |
| **`scoped_variables`**              | Array of Strings | No       | `[]`    | A list of values to pass from the parent to the child workflow. These become `{agent1Input}`, `{agent2Input}`, etc. |
| **`workflowUserFolderOverride`**    | String           | No       | `null`  | Specifies a user folder to load the workflow from. Use `_common` for shared workflows.                              |
| **`firstNodeSystemPromptOverride`** | String           | No       | `null`  | **(Legacy)** Overrides the `systemPrompt` for the first node in the child workflow. Use `scoped_variables` instead. |
| **`firstNodePromptOverride`**       | String           | No       | `null`  | **(Legacy)** Overrides the `prompt` for the first node in the child workflow. Use `scoped_variables` instead.       |

#### **Limitations and Key Usage Notes**

* **Variable Support:** Variable substitution is supported within the `scoped_variables` array and the legacy prompt
  override fields.
* **Static Configuration:** The `workflowName` and `workflowUserFolderOverride` fields **do not** support variables and
  must be static strings.

#### **Full Syntax Example**

This example calls a reusable child workflow to perform a search and summarize the findings.

```json
{
  "title": "Custom Wiki Search: Initial Search",
  "type": "CustomWorkflow",
  "workflowName": "Util_Workflow_Wiki_Search_And_Summarize",
  "workflowUserFolderOverride": "_common",
  "is_responder": false,
  "scoped_variables": [
    "{agent1Output}",
    "{agent3Output}"
  ]
}
```

> Values sent in as scoped_variables are accessible within the child workflow that is called as agentXInputs. So
> the first scoped_variable is agent1Input, second scoped_variable is agent2Input, etc.

-----

### **Data Manipulation: The `ArithmeticProcessor` Node**

The **`ArithmeticProcessor`** node performs a basic mathematical calculation. It takes a string expression containing
two numbers and one operator (`+`, `-`, `*`, `/`), resolves any variables, computes the result, and returns it as a
string. If the expression is invalid, it returns `"-1"`.

#### **Properties**

| Property           | Type    | Required | Default | Description                                                              |
|:-------------------|:--------|:---------|:--------|:-------------------------------------------------------------------------|
| **`type`**         | String  | Yes      | N/A     | Must be `"ArithmeticProcessor"`.                                         |
| **`title`**        | String  | No       | `""`    | A descriptive name for the node.                                         |
| **`expression`**   | String  | Yes      | N/A     | The mathematical expression to evaluate (e.g., `{agent1Output} * 1.07`). |
| **`returnToUser`** | Boolean | No       | `false` | Unlikely to be used, as this node is for internal data processing.       |

#### **Limitations and Key Usage Notes**

* **Variable Support:** The `expression` property supports all available workflow variables. These variables are
  expected to resolve to numeric values.

#### **Full Syntax Example**

This node calculates a final price by adding a 7% tax to a subtotal from a previous node.

```json
{
  "title": "Calculate Final Price with Tax",
  "type": "ArithmeticProcessor",
  "expression": "{agent1Output} * 1.07",
  "returnToUser": false
}
```

-----

### **Data Manipulation: The `StringConcatenator` Node**

The **`StringConcatenator`** is a utility for combining multiple strings into one. It takes a list of strings, resolves
any variables, and joins them with a specified delimiter. It can also act as a streaming responder.

#### **Properties**

| Property           | Type            | Required | Default | Description                                                                       |
|:-------------------|:----------------|:---------|:--------|:----------------------------------------------------------------------------------|
| **`type`**         | String          | Yes      | N/A     | Must be `"StringConcatenator"`.                                                   |
| **`title`**        | String          | No       | `""`    | A descriptive name for the node.                                                  |
| **`strings`**      | List of Strings | Yes      | N/A     | A JSON array of strings to be joined. Each string supports variable substitution. |
| **`delimiter`**    | String          | No       | `""`    | The character(s) to insert between each string. `"\n"` is common for new lines.   |
| **`returnToUser`** | Boolean         | No       | `false` | If `true`, this node's output is sent to the user, with support for streaming.    |

#### **Limitations and Key Usage Notes**

* **Variable Support:** Every string within the `strings` list supports full variable substitution.

#### **Full Syntax Example**

This example assembles a multi-line user profile from various data sources.

```json
{
  "title": "Assemble User Profile Block",
  "type": "StringConcatenator",
  "strings": [
    "--- User Profile ---",
    "Name: {user_name}",
    "Key Trait: {agent1Output}",
    "Report Generated: {todays_date_pretty}"
  ],
  "delimiter": "\n",
  "returnToUser": false
}
```

-----

### **Data Extraction: The `JsonExtractor` Node**

The **`JsonExtractor`** node extracts a specific field from a JSON string. It parses a JSON object (optionally wrapped
in markdown code blocks), resolves workflow variables, and returns the value of the specified field as a string. This
is useful for parsing structured LLM outputs.

#### **Properties**

| Property                | Type   | Required | Default | Description                                                                                          |
|:------------------------|:-------|:---------|:--------|:-----------------------------------------------------------------------------------------------------|
| **`type`**              | String | Yes      | N/A     | Must be `"JsonExtractor"`.                                                                           |
| **`title`**             | String | No       | `""`    | A descriptive name for the node.                                                                     |
| **`jsonToExtractFrom`** | String | Yes      | N/A     | The JSON string to extract from. Supports variables. Handles markdown code blocks automatically.     |
| **`fieldToExtract`**    | String | Yes      | N/A     | The name of the field to extract. Supports variables.                                                |

#### **Limitations and Key Usage Notes**

* **Variable Support:** Both `jsonToExtractFrom` and `fieldToExtract` support full variable substitution.
* **Markdown Handling:** The node automatically strips ` ```json ` and ` ``` ` code block wrappers before parsing.
* **Return Types:** Strings are returned as-is; numbers/booleans become strings; nested objects/arrays become JSON
  strings; `null` returns an empty string.

#### **Full Syntax Example**

This node extracts the "name" field from a JSON object returned by a previous LLM node.

```json
{
  "title": "Extract Character Name from LLM Response",
  "type": "JsonExtractor",
  "jsonToExtractFrom": "{agent1Output}",
  "fieldToExtract": "name"
}
```

**Example Input (from `agent1Output`):**
```json
{"name": "Socg", "file": "Socg.txt"}
```

**Example Output:** `Socg`

-----

### **Data Extraction: The `TagTextExtractor` Node**

The **`TagTextExtractor`** node extracts content from XML/HTML-style tags within a text string. It searches for a
specified tag (e.g., `<answer>...</answer>`) and returns the content between the opening and closing tags. This is
useful for parsing structured LLM outputs where the model wraps content in custom tags.

#### **Properties**

| Property              | Type   | Required | Default | Description                                                                    |
|:----------------------|:-------|:---------|:--------|:-------------------------------------------------------------------------------|
| **`type`**            | String | Yes      | N/A     | Must be `"TagTextExtractor"`.                                                  |
| **`title`**           | String | No       | `""`    | A descriptive name for the node.                                               |
| **`tagToExtractFrom`** | String | Yes      | N/A     | The text string to search within. Supports variables.                          |
| **`fieldToExtract`**    | String | Yes      | N/A     | The name of the tag to search for (without angle brackets). Supports variables.|

#### **Limitations and Key Usage Notes**

* **Variable Support:** Both `tagToExtractFrom` and `fieldToExtract` support full variable substitution.
* **Case Sensitivity:** Tag matching is case-sensitive (`<Answer>` and `<answer>` are different).
* **First Match:** If multiple instances of the tag exist, only the first match is extracted.
* **Whitespace:** Leading/trailing whitespace is stripped from the extracted content.

#### **Full Syntax Example**

This node extracts the content within `<answer>` tags from an LLM response.

```json
{
  "title": "Extract Answer from LLM Response",
  "type": "TagTextExtractor",
  "tagToExtractFrom": "{agent1Output}",
  "fieldToExtract": "answer"
}
```

**Example Input (from `agent1Output`):**
```
I've analyzed your question. Here is my response:

<answer>
The capital of France is Paris.
</answer>

I hope this helps.
```

**Example Output:** `The capital of France is Paris.`

-----

### **Utility: The `GetCustomFile` Node**

The **`GetCustomFile`** node loads the content of a local text file into the workflow as a string. This allows you to
inject large blocks of static text (like instructions or lore) without cluttering the workflow JSON.

#### **Properties**

| Property                    | Type   | Required | Default | Description                                                                                           |
|:----------------------------|:-------|:---------|:--------|:------------------------------------------------------------------------------------------------------|
| **`type`**                  | String | Yes      | N/A     | Must be `"GetCustomFile"`.                                                                            |
| **`title`**                 | String | No       | `""`    | An optional, human-readable name for the node.                                                        |
| **`filepath`**              | String | Yes      | N/A     | The full path to the text file to load. Supports variables including `{Discussion_Id}` and `{YYYY_MM_DD}`. |
| **`delimiter`**             | String | No       | `\n`    | An optional string to search for and replace within the file's content.                               |
| **`customReturnDelimiter`** | String | No       | `\n`    | An optional string that will replace every instance of the `delimiter`.                               |

#### **Limitations and Key Usage Notes**

* **Variable Support:** The `filepath` field supports full variable substitution, including `{Discussion_Id}` for
  per-conversation files and `{YYYY_MM_DD}` for date-based files.
* **File Not Found:** If the file doesn't exist, the node returns `"Custom instruction file did not exist"`.
* **IMPORTANT:** Do not set a delimiter or custom delimiter if you want the file to be pulled as it was originally
  written.

#### **Full Syntax Example**

This node loads a character sheet and replaces a simple `---` separator with a more decorative one.

```json
{
  "title": "Load Character Sheet",
  "type": "GetCustomFile",
  "filepath": "C:\\Users\\User\\Desktop\\character_sheet.txt",
  "delimiter": "---",
  "customReturnDelimiter": "\n**********\n"
}
```

#### **Dynamic Filepath Example**

This node loads session-specific notes using the conversation's unique identifier.

```json
{
  "title": "Load Session Notes",
  "type": "GetCustomFile",
  "filepath": "/data/sessions/{Discussion_Id}_notes.txt"
}
```

-----

### **Utility: The `SaveCustomFile` Node**

The **`SaveCustomFile`** node writes string content to a local text file. This is useful for saving data generated
during a workflow, such as an LLM's analysis, a conversation summary, or a report.

#### **Properties**

| Property       | Type   | Required | Default | Description                                                                                             |
|:---------------|:-------|:---------|:--------|:--------------------------------------------------------------------------------------------------------|
| **`type`**     | String | Yes      | N/A     | Must be `"SaveCustomFile"`.                                                                             |
| **`title`**    | String | No       | `""`    | An optional, human-readable name for the node.                                                          |
| **`filepath`** | String | Yes      | N/A     | The full path where the file will be saved. Supports variables including `{Discussion_Id}` and `{YYYY_MM_DD}`. |
| **`content`**  | String | Yes      | N/A     | The string content to be written to the file. Supports variables.                                       |

#### **Limitations and Key Usage Notes**

* **Variable Support:** Both `filepath` and `content` fields support full variable substitution, including
  `{Discussion_Id}` for per-conversation files and `{YYYY_MM_DD}` for date-based files.
* **Error Handling:** The node returns a status message indicating success or failure (e.g., due to permissions).
* **Directory Creation:** If parent directories don't exist, the node will attempt to create them.

#### **Full Syntax Example**

This node saves a character bio generated by a previous node to a file.

```json
{
  "title": "Save Character Bio to File",
  "type": "SaveCustomFile",
  "filepath": "D:\\WilmerAI\\Characters\\jax_the_pirate.txt",
  "content": "CHARACTER PROFILE\n-----------------\nName: Jax\nBio: {agent1Output}"
}
```

#### **Dynamic Filepath Example**

This node saves a daily report using the date variable.

```json
{
  "title": "Save Daily Report",
  "type": "SaveCustomFile",
  "filepath": "/data/reports/{YYYY_MM_DD}_report.txt",
  "content": "Report for {todays_date_pretty}:\n\n{agent1Output}"
}
```

-----

### **Utility: The `StaticResponse` Node**

The **`StaticResponse`** node returns a hardcoded string. It's versatile for debugging, providing static instructions,
or delivering canned responses without an LLM call. When designated as a responder, it can simulate a streaming
response.

#### **Properties**

| Property           | Type    | Required | Default | Description                                                           |
|:-------------------|:--------|:---------|:--------|:----------------------------------------------------------------------|
| **`type`**         | String  | Yes      | N/A     | Must be `"StaticResponse"`.                                           |
| **`title`**        | String  | No       | `""`    | An optional, human-readable name for the node.                        |
| **`content`**      | String  | Yes      | N/A     | The static text content that the node will output.                    |
| **`returnToUser`** | Boolean | No       | `false` | If `true`, the `content` is sent to the user, with streaming support. |

#### **Limitations and Key Usage Notes**

* **Variable Support:** The `content` field does not support variable substitution; it is treated as a literal string.
* **Streaming:** If `returnToUser` is `true` and the request is for streaming, the content is delivered word-by-word.

#### **Full Syntax Example**

This node sends a pre-written message directly to the user as a final, streaming response.

```json
{
  "title": "Return System Status Message",
  "type": "StaticResponse",
  "content": "Affirmative. All systems are operating within nominal parameters. This is a pre-recorded message.",
  "returnToUser": true
}
```

-----

### **Vision: The `ImageProcessor` Node**

The **`ImageProcessor`** node is the bridge between user-provided images and text-based nodes. It calls a vision-capable
LLM to generate text descriptions of images in the user's latest message. These descriptions are then made available to
subsequent nodes.

#### **Properties**

| Property               | Type    | Required | Default | Description                                                                                                       |
|:-----------------------|:--------|:---------|:--------|:------------------------------------------------------------------------------------------------------------------|
| **`type`**             | String  | Yes      | N/A     | Must be `"ImageProcessor"`.                                                                                       |
| **`endpointName`**     | String  | Yes      | N/A     | The name of the vision-capable LLM endpoint. **Supports LIMITED variables: only `{agent#Input}` and static workflow variables, NOT `{agent#Output}`.**  |
| **`systemPrompt`**     | String  | Yes      | N/A     | The system prompt for the vision LLM, instructing it on how to describe the image. Supports variables.            |
| **`prompt`**           | String  | Yes      | N/A     | The user prompt for the vision LLM, guiding what to focus on. Supports variables.                                 |
| **`preset`**           | String  | Yes      | N/A     | The generation preset for the vision LLM. **Supports LIMITED variables like endpointName.**                       |
| **`addAsUserMessage`** | Boolean | No       | `false` | If `true`, injects the aggregated image description into the conversation history as a new user message.          |
| **`message`**          | String  | No       | N/A     | A template string for the injected message. **Must contain the `[IMAGE_BLOCK]` placeholder.** Supports variables. |

#### **Limitations and Key Usage Notes**

* **Limited Variable Support:** `endpointName` and `preset` support LIMITED variables (only `{agent#Input}` from parent
  workflows and static variables, NOT `{agent#Output}` which doesn't exist yet).
* **Sequential Processing:** The node processes images one by one and aggregates their descriptions into a single string
  output, separated by `\n-------------\n`.
* **`[IMAGE_BLOCK]` Placeholder:** This special keyword is **only valid** inside the `message` property of this node. It
  marks where the aggregated descriptions will be inserted.

#### **Full Syntax Example**

This node analyzes all user images and injects the description into the chat history for a subsequent text-only node to
use.

```json
{
  "title": "Analyze and Describe All User Images",
  "type": "ImageProcessor",
  "endpointName": "Vision-Endpoint",
  "preset": "Vision-Preset",
  "addAsUserMessage": true,
  "message": "[SYSTEM: An image analysis module has processed the user's recent image(s). The detailed description is below:\n\n[IMAGE_BLOCK]\n\nThis is now part of our conversation.]",
  "systemPrompt": "You are a world-class visual analysis AI. Describe the image in meticulous detail for a text-only assistant.",
  "prompt": "Based on our recent conversation:\n{chat_user_prompt_last_five}\n\nDescribe the image's contents in extreme detail. Transcribe any text you see."
}
```

-----

### **External Tools: The `PythonModule` Node**

The **`PythonModule`** node executes a custom Python script, allowing you to extend workflow capabilities with custom
logic, API calls, or file access. The script must contain an `Invoke(*args, **kwargs)` function that returns a single
string value.

#### **Properties**

| Property          | Type   | Required | Default | Description                                                                                   |
|:------------------|:-------|:---------|:--------|:----------------------------------------------------------------------------------------------|
| **`type`**        | String | Yes      | N/A     | Must be `"PythonModule"`.                                                                     |
| **`title`**       | String | No       | `""`    | A descriptive name for the node.                                                              |
| **`module_path`** | String | Yes      | N/A     | The full, absolute file path to the Python (`.py`) script.                                    |
| **`args`**        | Array  | No       | `[]`    | A list of positional arguments to pass to the `Invoke` function. Values support variables.    |
| **`kwargs`**      | Object | No       | `{}`    | A dictionary of keyword arguments to pass to the `Invoke` function. Values support variables. |

#### **Limitations and Key Usage Notes**

* **Variable Support:** All values within the `args` array and `kwargs` object support variable substitution.
* **Script Requirement:** The target Python file must define a function `Invoke(*args, **kwargs)` that returns a single
  value, which will be converted to a string.
* **Output Variable:** The string returned by the `Invoke` function becomes the node's output.

#### **Full Syntax Example**

This node executes a script to process data, passing arguments from workflow variables.

```json
{
  "title": "My Custom Python Tool",
  "type": "PythonModule",
  "module_path": "C:/WilmerAI/Public/Scripts/process_data.py",
  "args": [
    "A static string argument",
    "{agent1Output}"
  ],
  "kwargs": {
    "api_key": "your-secret-key",
    "user_id": "{userName}"
  }
}
```

-----

### **External Tools: The Offline Wikipedia Nodes**

The **Offline Wikipedia** nodes query a local `OfflineWikipediaTextApi` service to retrieve factual information from a
Wikipedia database. This is used for Retrieval-Augmented Generation (RAG) by providing context to an LLM. The
`promptToSearch` field supports variables.

#### **`OfflineWikiApiBestFullArticle`**

Performs a broad search and returns only the single best-matching full article.

##### **Full Syntax Example**

```json
{
  "title": "Get Best Article on Alan Turing",
  "type": "OfflineWikiApiBestFullArticle",
  "promptToSearch": "Who was Alan Turing?"
}
```

#### **`OfflineWikiApiFullArticle`**

Retrieves the first full article returned by the search query.

##### **Full Syntax Example**

```json
{
  "title": "Get First-Result Article",
  "type": "OfflineWikiApiFullArticle",
  "promptToSearch": "The geography of Antarctica"
}
```

#### **`OfflineWikiApiPartialArticle`**

Retrieves one or more article summaries (typically the first paragraph).

##### **Properties**

| Property             | Type    | Required | Default | Description                                                         |
|:---------------------|:--------|:---------|:--------|:--------------------------------------------------------------------|
| **`type`**           | String  | Yes      | N/A     | `"OfflineWikiApiPartialArticle"`.                                   |
| **`title`**          | String  | No       | `""`    | A descriptive name.                                                 |
| **`promptToSearch`** | String  | Yes      | N/A     | The search query.                                                   |
| **`percentile`**     | Float   | No       | `0.5`   | Minimum relevance score (0.0 to 1.0) for an article to be included. |
| **`num_results`**    | Integer | No       | `1`     | The number of article summaries to retrieve.                        |

##### **Full Syntax Example**

```json
{
  "title": "Get Photosynthesis Summaries",
  "type": "OfflineWikiApiPartialArticle",
  "promptToSearch": "What is photosynthesis?",
  "num_results": 2
}
```

#### **`OfflineWikiApiTopNFullArticles`**

Returns a specified number of the most relevant full articles.

##### **Properties**

| Property             | Type    | Required | Default | Description                                                                  |
|:---------------------|:--------|:---------|:--------|:-----------------------------------------------------------------------------|
| **`type`**           | String  | Yes      | N/A     | `"OfflineWikiApiTopNFullArticles"`.                                          |
| **`title`**          | String  | No       | `""`    | A descriptive name.                                                          |
| **`promptToSearch`** | String  | Yes      | N/A     | The search query.                                                            |
| **`percentile`**     | Float   | No       | `0.5`   | Minimum relevance score for the initial candidate pool.                      |
| **`num_results`**    | Integer | No       | `10`    | The size of the initial candidate pool.                                      |
| **`top_n_articles`** | Integer | No       | `3`     | The final number of articles to return. A negative value reverses the order. |

##### **Full Syntax Example**

```json
{
  "title": "Get top 3 articles on Roman History",
  "type": "OfflineWikiApiTopNFullArticles",
  "promptToSearch": "The fall of the Roman Republic",
  "top_n_articles": 3
}
```

-----

### **Concurrency Control: The `WorkflowLock` Node**

The **`WorkflowLock`** node prevents race conditions during long-running, asynchronous operations. It creates a
temporary lock that halts subsequent workflow executions at that point, ensuring a resource-intensive task (like memory
generation) isn't triggered multiple times concurrently. If a lock is active, the workflow terminates immediately.

#### **Properties**

| Property             | Type   | Required | Default | Description                                                                           |
|:---------------------|:-------|:---------|:--------|:--------------------------------------------------------------------------------------|
| **`type`**           | String | Yes      | N/A     | Must be `"WorkflowLock"`.                                                             |
| **`title`**          | String | No       | `""`    | A descriptive name for the node.                                                      |
| **`workflowLockId`** | String | Yes      | N/A     | The unique identifier for the lock. Nodes with the same ID contend for the same lock. |

#### **Limitations and Key Usage Notes**

* **Placement:** The lock should be placed immediately after the responder node and before the long-running task.
* **Automatic Release:** Locks are released upon workflow completion or after a 10-minute safety timeout. They are also
  cleared on application restart.
* **Scope:** Locks are scoped per-user.

#### **Full Syntax Example**

This node acquires a lock before a subsequent node begins a long memory generation process.

```json
{
  "title": "Acquire Lock for Memory Generation",
  "type": "WorkflowLock",
  "workflowLockId": "FullCustomChatSummaryLock"
}
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.