Skip to content

feat(flow): AI node — in-flow LLM completion (Claude/OpenAI/Kimi)#18

Merged
hacka0wi merged 2 commits into
mainfrom
feat/ai-node
Jun 17, 2026
Merged

feat(flow): AI node — in-flow LLM completion (Claude/OpenAI/Kimi)#18
hacka0wi merged 2 commits into
mainfrom
feat/ai-node

Conversation

@hacka0wi

@hacka0wi hacka0wi commented Jun 9, 2026

Copy link
Copy Markdown
Member

What

Adds a 25th flow node — AI — that calls an LLM (Claude / OpenAI / Kimi) from inside a DAG. The engine-side twin of the existing in-app assistant: same provider set, same secret names, same default models.

Why

RunLoop already has a deep node palette but no way to use an LLM inside a flow — only the side-panel assistant. An AI node turns common one-liners (summarize, classify, extract, rewrite, structure-to-JSON) into a single drag-drop node, and slots into the existing variable/retry/DLQ machinery.

Engine

  • internal/llm — provider-agnostic client (Anthropic Messages API + OpenAI-compatible chat completions for OpenAI/Kimi). Standard-library only, no vendor SDK — we don't want a third-party retry/transport stack underneath the engine's own retry + circuit-breaker. Endpoints are package vars so tests target httptest.
  • executeAINode + case models.JobTypeAI in flow_executor.go. Provider/key/model resolution mirrors src/app/api/ai/chat/route.ts (config.providerCLAUDE_DEFAULT_PROVIDER → first configured key; key from <PROVIDER>_API_KEY; model from config.model<PROVIDER>_DEFAULT_MODEL → built-in default). Prompts are ${{...}}-substituted before dispatch. Optional JSON-object mode parses output to ${{nodeId.json.field}}. Output carries response, model, provider, stopReason, usage. Goes through the existing retry + circuit-breaker path.
  • 5 new tests: request shaping per provider, JSON mode, max_tokens cap, upstream error, input validation.

UI

  • AINode + AINodeProperties, registered in the node/properties indexes.
  • New "AI" palette category (Sparkles icon, #8B5CF6); icon/color added to BaseNode.
  • Node type 'ai' follows the existing nodeType.toUpperCase() === JobType convention → serializes to "AI" with no mapping-table changes.

Config / Output

Config Output
provider (auto/claude/openai/kimi) ${{node.response}}
model, systemPrompt, prompt (req) ${{node.json.*}} (json mode)
temperature, maxTokens (cap 4096) ${{node.usage.totalTokens}}
responseFormat (text/json), timeout model · provider · stopReason

Out of scope (phase 2)

Single-shot completion only. The agent/tool loop (tools: [http, database]) is designed-for — llm.Request already takes a Messages[] slice — but deferred: it needs a tool-schema + execution loop, a meaningfully bigger change.

Tests

  • Engine: go build ./... ✅, go vet ✅, go test ./... ✅ (incl. new internal/llm)
  • Web: tsc --noEmit ✅, vitest 36/36 ✅

🤖 Generated with Claude Code

hacka0wi and others added 2 commits June 9, 2026 17:29
Adds a 25th flow node that calls an LLM from inside a DAG. Provider, API
keys, and default models resolve from the project secret vault exactly like
the in-app assistant (CLAUDE_API_KEY / OPENAI_API_KEY / KIMI_API_KEY,
*_DEFAULT_MODEL, CLAUDE_DEFAULT_PROVIDER), or per-node overrides.

Engine:
- new internal/llm package — provider-agnostic client (Anthropic Messages
  API + OpenAI-compatible chat completions), standard-library only, no
  vendor SDK. Endpoints are vars so tests can target httptest.
- executeAINode + dispatch case models.JobTypeAI in flow_executor.go.
  Prompts are already ${{...}}-substituted by the time dispatch runs;
  optional JSON-object mode parses output to ${{nodeId.json.field}}.
  Output carries response/model/provider/stopReason/usage. Runs through
  the existing retry + circuit-breaker path.
- 5 new tests (provider request shaping, JSON mode, token cap, upstream
  error, validation).

UI:
- AINode + AINodeProperties, registered in nodes/properties indexes.
- new "AI" palette category (Sparkles icon, #8B5CF6), icon/color in BaseNode.
- node type 'ai' follows the existing nodeType.toUpperCase() === JobType
  convention, so it serializes to "AI" with no mapping changes.

Docs: README features (24→25 + AI bullet), CHANGELOG [Unreleased],
CLAUDE.md, in-app API docs node list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reposition the AI node for adoption: lead the hero tagline + paragraph with
AI/LLM nodes, add an "AI / LLM node in a step" row to the comparison table
(built-in vs none of Cronicle/Dkron/DolphinScheduler; Airflow only via a
provider pkg + code), rewrite the feature bullet as benefit-driven with a
concrete webhook→classify→route example, and add an "AI triage" use case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hacka0wi hacka0wi merged commit c9a3a50 into main Jun 17, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant