feat: TealTiger governance node for n8n - #424
Conversation
There was a problem hiding this comment.
Pull request overview
Introduces a new n8n-nodes-tealtiger community node package intended to add a “TealTiger Governance” node to n8n workflows, using the TealTiger (TealOpenAI) SDK for policy enforcement and evidence output.
Changes:
- Added an n8n node (
TealTiger Governance) that calls TealOpenAI and routes results to different outputs. - Added an n8n credential type for storing the TealTiger API key.
- Added initial package scaffolding (package.json + tsconfig) and an SVG icon asset.
Reviewed changes
Copilot reviewed 4 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/n8n-nodes-tealtiger/tsconfig.json | TypeScript build configuration for emitting compiled node code to dist/. |
| packages/n8n-nodes-tealtiger/src/nodes/TealTiger/tealtiger.svg | Icon asset referenced by the n8n node. |
| packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts | Implements the TealTiger Governance node (parameters, execution, output routing). |
| packages/n8n-nodes-tealtiger/src/credentials/TealTigerApi.credentials.ts | Defines the n8n credential for storing the API key. |
| packages/n8n-nodes-tealtiger/package.json | Defines the community node package metadata and build scripts. |
Suppressed comments (4)
packages/n8n-nodes-tealtiger/package.json:16
- The build only runs
tsc, which will not copysrc/nodes/TealTiger/tealtiger.svgintodist/…. Since the node icon is referenced asfile:tealtiger.svg, the published package will be missing the icon at runtime unless the SVG is copied intodist/nodes/TealTiger/tealtiger.svg. Also, the currenttestscript always exits 1, which makesnpm testfail even when nothing is wrong.
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:97
- Avoid suppressing type-checking here (
as any+// @ts-ignore). The TealTiger README examples show this call working without ignores, and keeping types enabled will prevent runtime-breaking API drift (especially important in an n8n node).
}
} as any);
// @ts-ignore
const res = await client.chat.completions.create({
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:108
- This node replaces the entire incoming item with a new
{ decision, content, securityInfo }payload. That discards upstream fields that downstream nodes may rely on (and the issue description calls out evaluating/routing existing workflow data). Prefer preserving the original item JSON and nesting TealTiger output under a dedicated key.
const newItem = {
json: {
decision,
content: res.choices[0]?.message?.content,
securityInfo: res.security
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:120
- When
continueOnFail()is enabled, the error path drops the original item context entirely. This makes it hard to correlate failures with the input data and can break downstream expectations. Preserve the original item JSON alongside the error.
if (this.continueOnFail()) {
blockedData.push({ json: { error: error.message }});
continue;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (11)
packages/n8n-nodes-tealtiger/package.json:11
mainpoints toindex.js, but this package doesn't include anindex.jsfile (andfilesonly publishesdist). This will make the published package entrypoint invalid for consumers/tools that rely onmain.
"main": "index.js",
packages/n8n-nodes-tealtiger/package.json:33
- Using "*" for
n8n-core/n8n-workflowmakes builds non-reproducible and can silently break when n8n publishes a new major. Pin these to a supported semver range for the n8n major(s) you intend to support.
"n8n-core": "*",
"n8n-workflow": "*",
packages/n8n-nodes-tealtiger/package.json:37
- Depending on
tealtigeras "latest" makes installs non-deterministic and can introduce breaking changes without a package.json diff. Pin to a semver range instead.
"tealtiger": "latest"
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:25
- Issue #326 requires three routes (approved / blocked / needs-review), but the node declares only two outputs and merges blocked + needs-review into one label. This prevents workflows from branching correctly on “needs review”.
outputs: ['main', 'main'], // output 0: approved, output 1: blocked
outputNames: ['Approved', 'Blocked/Needs Review'],
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:74
- To support the required third “needs-review” output, the execute function needs a third output array.
const approvedData: INodeExecutionData[] = [];
const blockedData: INodeExecutionData[] = [];
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:131
- The node currently returns only two outputs; after adding a third route, it must return three arrays to match the declared outputs.
return [approvedData, blockedData];
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:116
- Routing currently treats any non-ALLOW decision as “blocked”, which collapses “needs-review” into the blocked path. To match the required 3-way routing, split DENY/BLOCK from everything else.
if (decision === 'ALLOW') {
approvedData.push(newItem);
} else {
blockedData.push(newItem);
}
packages/n8n-nodes-tealtiger/package.json:13
- The build script uses
mkdir -pandcp, which will fail on Windows runners/environments. Prefer a cross-platform Node-based copy.
"build": "tsc && mkdir -p dist/nodes/TealTiger && cp src/nodes/TealTiger/tealtiger.svg dist/nodes/TealTiger/",
packages/n8n-nodes-tealtiger/tsconfig.json:5
- This package is a server-side n8n node, but the TS config includes the
domlib. That can introduce conflicting global types (e.g.,Request,fetch) and is not used by Node-only code.
"lib": ["es2019", "dom"],
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:93
- The PII / prompt injection / content moderation parameters are currently read but never used, and the TealOpenAI config uses
enableGuardrails/enableCostTrackingkeys that don’t match the documentedguardrailsconfiguration. As written, the UI toggles won’t affect behavior.
const piiDetection = this.getNodeParameter('piiDetection', itemIndex) as boolean;
const promptInjection = this.getNodeParameter('promptInjection', itemIndex) as boolean;
const contentModeration = this.getNodeParameter('contentModeration', itemIndex) as boolean;
const config: any = {
apiKey: credentials.apiKey as string,
enableGuardrails: true,
enableCostTracking: true
};
const client: any = new TealOpenAI(config);
packages/n8n-nodes-tealtiger/src/nodes/TealTiger/TealTiger.node.ts:97
- Per Issue #326 the governance node is expected to evaluate existing workflow data (e.g., an LLM response/tool args) and route it. This implementation instead makes a new
chat.completions.createLLM call, changing the workflow semantics (it behaves like a guarded LLM node rather than a governance/evaluation node).
const res = await client.chat.completions.create({
model,
messages: [{ role: 'user', content }]
});
|
Thanks @lleonardo-franco! A few questions before merge: Are there any tests included (or planned for a follow-up)? |
Closes #326. This PR introduces the n8n community node package for TealTiger. It includes a TealTiger Governance node which connects to the TealOpenAI SDK to enforce security policies and track costs within n8n workflows.