Functions are the building blocks of Inferable. They get invoked by the agent as tools.

When productionizing your Inferable application, it’s good to consider timeouts and retry strategies to ensure reliable execution. This guide covers best practices for implementing resilient functions.

Timeouts

Functions in Inferable have a default timeout of 30 seconds. It’s recommended to keep timeouts short to enable faster failure detection.

In Node.js, you can configure the timeout using the timeoutSeconds option:

service.register({
  name: "longRunningOperation",
  description: "Performs a long running operation",
  config: {
    timeoutSeconds: 60 * 60 * 24, // Extend timeout to 24 hours
  },
  func: async (input) => {
    // Your function logic
  },
});

Since Inferable uses HTTP long polling and an event-driven architecture, there’s no theoretical limit to the timeout.

Retry Behavior

By default, Inferable will not retry failed function executions. This is because not all functions are idempotent (safe to retry). However, you can enable retries for functions that are safe to retry multiple times, such as read operations.

This is an example of configuring retries using retryCountOnStall in Node.js:

service.register({
  name: "fetchUserData",
  description: "Fetches user data from database",
  config: {
    retryCountOnStall: 3, // Will retry up to 3 times if the function stalls
  },
  func: async (input) => {
    // Safe to retry as this is a read operation
    return await db.users.findById(input.userId);
  },
});

Example of a resilient function

This is an example of a function that might stall first, but will automatically recover.

let count = 0;

service.register({
  name: "resilientOperation",
  description: "Example of a resilient function implementation",
  config: {
    timeoutSeconds: 30,
    retryCountOnStall: 2,
  },
  func: async (input) => {
    if (count === 0) {
      await new Promise((resolve) => setTimeout(resolve, 31_000));
      count++;
    } else {
      return `Success after ${count} retries!`;
    }
  },
});

Function States

Once a function is invoked, it will go through a series of states.

Pending - The function call is pending to be picked up by a worker machine.

Running - The function call is running on a worker machine.

Success - The function call returned a result (either a value or a serialized error).

Stalled - The function call did not return a result within the timeout.

Failure - The function call did not return a result within the timeout and the retry count was reached.