Skip to content

feat(v2): AI tool support, native binding fallback, and Execute SQL expression toggle - #26

Merged
DangerBlack merged 3 commits into
masterfrom
feature/usable-as-tool
Jun 27, 2026
Merged

feat(v2): AI tool support, native binding fallback, and Execute SQL expression toggle#26
DangerBlack merged 3 commits into
masterfrom
feature/usable-as-tool

Conversation

@DangerBlack

@DangerBlack DangerBlack commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Exposes the node as an AI agent tool (usableAsTool: true) so all 6 operations can be wired directly into an n8n AI Agent node, closing [Feature Req] Make Available as a Tool Call #17
  • Fixes the native binding loader to use try/catch instead of fs.existsSync, allowing graceful fallback to system bindings on non-musl and non-x64 hosts (ARM64, glibc Linux, macOS), closing Bug: "unsupported relocation type 7" on ARM64 (aarch64) due to hardcoded x64 binary #24
  • Adds an Allow Expressions in Query (Unsafe) toggle to the Execute SQL operation, off by default to preserve the existing safe behavior
  • Fixes a shallow merge bug in updateDisplayOptions that was silently dropping field-level displayOptions conditions (affected dataMode-dependent fields in Insert, Update, and Upsert)
  • Updates README with screenshots and a dedicated AI Agent Tool section

Details

AI tool support (#17)

Adding usableAsTool: true to the node description makes all 6 operations available in the n8n AI Agent tool picker. Execute SQL is the most flexible option for agents. The structured operations (Select, Insert, Update, Delete, Upsert) are useful when limiting the scope of what the agent can do.

Native binding fallback (fixes #24)

The previous code used fs.existsSync to decide whether to load the bundled musl x64 binary. This caused a fatal crash on ARM64 because the file exists on disk but cannot be loaded. The fix wraps the load attempt in try/catch and falls back to better-sqlite3's own binding resolution, which handles architecture detection correctly.

Allow Expressions in Query (Unsafe)

Expressions in the SQL query field were blocked by noDataExpression: true as a safeguard against expression-based injection. The new toggle keeps that safeguard on by default and lets users opt in explicitly when they need dynamic query construction.

Test plan

  • Verify node appears in AI Agent tool picker
  • Verify Execute SQL works with expressions enabled
  • Verify Execute SQL blocks expressions when toggle is off
  • Verify node loads correctly on non-musl host (no binding crash)
  • Run test suite: npm test

- Add usableAsTool: true so the node is available as an AI agent tool
- Fix native binding loader to try/catch instead of existsSync, allowing
  graceful fallback to system bindings on non-musl hosts
- Add Allow Expressions in Query (Unsafe) toggle to Execute SQL, off by
  default to preserve existing safe behavior
- Fix updateDisplayOptions shallow merge so field-level displayOptions
  conditions are preserved alongside operation-level conditions
@DangerBlack DangerBlack self-assigned this Jun 7, 2026
@DangerBlack DangerBlack added bug Something isn't working enhancement New feature or request labels Jun 7, 2026
@DangerBlack
DangerBlack requested a review from Copilot June 27, 2026 14:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the v2 SQLite node to better integrate with n8n AI Agent tooling, improve cross-platform native binding loading, and add an opt-in path for evaluating expressions inside Execute SQL queries.

Changes:

  • Mark the node as AI-agent tool compatible (usableAsTool: true) so operations can be wired into AI Agent nodes.
  • Make native binding loading resilient by trying the bundled musl x64 binding and falling back gracefully when it can’t be loaded.
  • Add an Allow Expressions in Query (Unsafe) toggle for Execute SQL (default off) and fix updateDisplayOptions to preserve field-level display conditions.

Reviewed changes

Copilot reviewed 7 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Updates docs with screenshots and new sections for Execute SQL, unsafe expressions, and AI tool usage.
package.json Bumps package version to 1.1.0.
nodes/SqliteNode/v2/transport/index.ts Changes native binding load to try/catch fallback behavior.
nodes/SqliteNode/v2/helpers/utils.ts Fixes shallow-merge bug by deep-merging displayOptions.show/hide.
nodes/SqliteNode/v2/actions/versionDescription.ts Marks v2 node description as usableAsTool.
nodes/SqliteNode/v2/actions/database/executeQuery.operation.ts Adds unsafe-expression toggle and a separate expression-enabled query field.
nodes/SqliteNode/SqliteNode.node.ts Marks the versioned node’s base description as usableAsTool.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to +42
if (fs.existsSync(nativeBinding)) {
try {
return new Database(dbPath, { nativeBinding });
} catch {}
}
return new Database(dbPath);
Comment on lines +17 to +24
{
displayName: 'Allow Expressions in Query (Unsafe)',
name: 'allowExpressions',
type: 'boolean',
default: false,
noDataExpression: true,
description: 'Whether to allow n8n expressions inside the SQL query. When enabled, expressions like {{ $JSON.value }} are evaluated before the query is sent to SQLite. Only enable this with trusted data, passing unsanitized user input into the query string can lead to SQL injection.',
},
Comment on lines 68 to +72
for (let i = 0; i < items.length; i++) {
const rawQuery = this.getNodeParameter('query', i) as string;
const allowExpressions = this.getNodeParameter('allowExpressions', i, false) as boolean;
const rawQuery = allowExpressions
? (this.getNodeParameter('queryExpression', i) as string)
: (this.getNodeParameter('query', i) as string);
Comment on lines 12 to 16
export function updateDisplayOptions(
displayOptions: { show?: Record<string, unknown[]>; hide?: Record<string, unknown[]> },
properties: INodeProperties[],
): INodeProperties[] {
return properties.map((p) => ({
@DangerBlack
DangerBlack merged commit 4907200 into master Jun 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: "unsupported relocation type 7" on ARM64 (aarch64) due to hardcoded x64 binary

2 participants