Generate Your Own Nyno Workflow Extensions
Generate Your Own Nyno Workflow Extensions (Markdown Version)
Nyno Extension Rules (Simple)
1. Basic Rules
- Extensions are single workflow steps.
- Receive
args(simple array/list) andcontext(key-values). - Can read or modify any context variable.
- Default output is stored in
context[set_context], whereset_contextdefaults to"prev". - For API keys, use
context, for example VENDOR_NAME_API_KEY, never use api keys inargs.
2. Dynamic Output Key
-
To customize output, use the
set_contextkey incontext. -
If
set_contextis not provided, it defaults to"prev". -
Example:
const setName = context?.set_context ?? "prev"; context[setName] = result; -
This allows the workflow to store results under a custom context variable or reuse the previous step’s output.
3. Return Values
-
Must return an integer:
0= success- -1 = error
1/other number= for very rare cases with clear different branches
4. Context Usage
-
Extensions may store or overwrite data in context.
-
Context can pass global values (API keys, URLs, etc.) to other steps.
-
Errors can also be stored dynamically using the same
set_contextvalue:context[setName + "_error"] = { errorMessage };
5. Syntax
- Follow language-specific function signatures (JS (Use ES6 import/exports only, named function export, no module.exports), Python, PHP, Ruby).
- Only use
argsandcontext. - Always prefix the function with
nyno_if no other prefix is provided.
6. Language Choice Guideline
- Choose the language that best fits the task.
- Prefer the language with the strongest or most mature library support for what you need (e.g. APIs, SDKs, file formats, ML, scraping).
- Performance, ecosystem, and developer ergonomics are valid reasons to choose one language over another.
- If JS, always use ES6 with imports not requires.
7. Examples
Example Python extension
# extensions/hello-py/command.py
def hello_py(args, context):
name = args[0] if args else "World"
set_name = context.get("set_context", "prev")
context[set_name] = f"Hello, {name} from Python!"
return 0
Example PHP extension
<?php
// extensions/hello-php/command.php
function hello_php($args, &$context) { // & required to modify context
$name = $args[0] ?? "World";
$setName = $context["set_context"] ?? "prev";
$context[$setName] = "Hello, $name from PHP!";
return 0;
}
Example Ruby extension
# extensions/hello-rb/command.rb
def hello_rb(args, context)
name = args[0] || "World"
set_name = context["set_context"] || "prev"
context[set_name] = "Hello, #{name} from Ruby!"
return 0
end
JS Example using context to pass data between steps
export function some_extension(args, context) {
const result = args[0] || "default value";
const setName = context?.set_context ?? "prev";
// Save output in context for the next step
context[setName] = result;
return 0; // default path
}
8. Libraries
- In JS, never use Axios, use the build in fetch (we run the latest nodejs).
- Prefer direct HTTP requests/Linux commands over libraries/sdks unless explicitly asked.
9. Security
- Prevent RCE: If you need to use linux commands, always use the list input so variables are escaped, never use raw shell concatination.
- Prevent Path Traversal: If an argument is about a relative path with another directory as base, then alwas check if the path resolved to a path that starts with the base.
- Prevent SQL injection: always use prepared statements for args/user input variables.
- Overall just use the best security practices, especially when dealing with user input variables.
Making an Extension Appear in the GUI
For an extension to be detected and loaded in the GUI (search/loader), it must include a minimal set of correctly named files.
If any of these are missing or misnamed, the extension will not show up at all.
Required Files
template.yml (mandatory)
-
This file is what makes the extension discoverable by the GUI.
-
Must be named exactly:
template.yml- Use hyphens (
-), not underscores (_)
- Use hyphens (
Example:
- step: ai-mistral-embeddings
args:
- '${prev}'
label.txt (optional)
-
Defines the name shown in the GUI.
-
Must start with a colored circle emoji to indicate category:
- 🟢 Common / easy
- 🔵 More advanced
- 🟣 Rare / highly specific
Example:
🔵 Generate 1024-dimension vector from text for search
Icon (optional: pick one)
You must include one of:
icon.webp→ custom icon oremoji.txt→ contains exactly one emoji
Example Directory Structure
your-extension/
├── command.py
├── template.yml
├── label.txt
└── (icon.webp OR emoji.txt)