Actions

Define workflow and agent actions with createAction.

An action is a single operation users (or agents) can invoke as a workflow step or tool call. Define actions with createAction from @lunnoa/toolkit.

These examples assume you already understand the toolkit overview.

createAction fields

FieldPurpose
idUnique id: <app-id>_action_<action-name>
name / descriptionLabels shown in the workflow and agent UIs
inputConfigUI fields for configuring the action (see Input config)
aiSchemaZod object that mirrors inputConfig field ids; used by agents and validation
runExecutes the action; receives configValue, connection, and platform services
mockRunReturns representative output for workflow mapping and testing
needsConnectionSet false when this action does not need the app's connection
needsApprovalWhen true, agent tool execution requires user approval before running
availableForAgentSet false to hide the action from the agent tool list
iconUrlOptional; falls back to the app logoUrl
uiOptional declarative chat UI for execution and output
systemPromptFragmentOptional per-action policy text injected when the tool is enabled

Example

send-request.ts
import { createAction, createTextInputField } from '@lunnoa/toolkit';import { z } from 'zod/v3';export const sendRequest = createAction({  id: 'http_action_send-request',  name: 'Send request',  description: 'Call an HTTP endpoint with the given URL.',  inputConfig: [    createTextInputField({      id: 'url',      label: 'URL',      required: {        missingMessage: 'URL is required',        missingStatus: 'warning',      },    }),  ],  aiSchema: z.object({    url: z.string().url().describe('HTTP URL to call'),  }),  needsConnection: false,  async run({ configValue }) {    const res = await fetch(configValue.url);    return { status: res.status, body: await res.text() };  },  async mockRun() {    return { status: 200, body: '{"ok":true}' };  },});

aiSchema must match inputConfig

If inputConfig has a field with id: 'name', then aiSchema must include a name property. Agents and validation rely on that 1:1 mapping. Keep descriptions on Zod fields short and concrete so tool calling stays reliable.

run vs mockRun

  • run is the real execution path in workflows and agent tools. Prefer configValue and connection from the handler args.
  • mockRun should return data shaped like run so users can map outputs to downstream steps. If the output is always different, hide save-and-test with viewOptions.hideSaveAndTestButton: true.

Handlers run inside the Lunnoa server. Do not assume your package's private node_modules beyond the toolkit peer dependency and what the host injects.

Next