Steps

step.run

Execute arbitrary async code as a typed step.

Quick Example

import { step } from '@noetic/core';

const transform = step.run({
  id: 'normalize-input',
  execute: async (input: string, ctx) => {
    return input.trim().toLowerCase();
  },
});

What It Does

step.run wraps any async function as a step. It is the escape hatch for custom logic -- API calls, database operations, file I/O, data transformations, or anything that is not a model call.

The execute function receives two arguments:

  1. input -- the typed input from the previous step (or the initial pipeline input).
  2. ctx -- the Noetic Context, giving access to memory, tokens, abort signals, and more.

The return value becomes the output of the step, passed to whatever comes next.

API Reference

Options

PropertyTypeRequiredDescription
idstringYesUnique step identifier
execute(input: I, ctx: Context) => Promise<O>YesThe async function to run
retryRetryPolicyNoRetry configuration on failure

RetryPolicy

PropertyTypeRequiredDefaultDescription
maxAttemptsnumberYes--Maximum number of attempts
backoff'fixed' | 'linear' | 'exponential'Yes--Backoff strategy between retries
initialDelaynumberYes--Delay in ms before first retry
maxDelaynumberNo--Cap on delay between retries

Retry Example

import { step } from '@noetic/core';

const fetchData = step.run({
  id: 'fetch-api',
  execute: async (url: string) => {
    const res = await fetch(url);
    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`);
    }
    return res.json();
  },
  retry: {
    maxAttempts: 3,
    backoff: 'exponential',
    initialDelay: 1e3,
    maxDelay: 1e4,
  },
});

Using Context

The Context object provides access to runtime state inside your execute function.

import { step } from '@noetic/core';

const contextAware = step.run({
  id: 'context-example',
  execute: async (input: string, ctx) => {
    // Check if the run has been cancelled
    if (ctx.aborted) {
      return 'Cancelled';
    }

    // Access token usage
    console.log('Tokens used so far:', ctx.tokens.total);

    return `Processed: ${input}`;
  },
});
  • step.llm -- for language model calls.
  • step.tool -- for direct tool invocation.
  • Loop & Until -- use step.run as a loop body for custom iteration logic.

On this page