Skip to content

helpers

utility functions for common patterns

noToolsCalled

check if model called any tools

import { noToolsCalled } from "@threaded/ai";

scope(
  {
    tools: [calculator],
    until: noToolsCalled(),
  },
  model(),
);

runs model until no tools are called (agentic loop)

toolWasCalled

check if specific tool was called

import { toolWasCalled, when } from "@threaded/ai";

compose(
  model(),
  when(
    toolWasCalled("search_web"),
    tap((ctx) => console.log("model searched the web")),
  ),
);

returns true if this tool was called in the model's last response

everyNMessages

trigger step every n messages

import { everyNMessages, model } from "@threaded/ai";

compose(
  everyNMessages(
    10,
    model({ system: "summarize the last 10 messages" }),
    tap(({ lastResponse }) => console.log("model's summarization:", lastResponse.content))
  ),
  model(),
);

runs summarization every 10 messages

everyNTokens

trigger step based on token count

import { everyNTokens } from "@threaded/ai";

compose(
  everyNTokens(
    1_000_000,
    model({ system: "compress conversation history" }),
  ),
  model(),
);

estimates tokens as length / 4

appendToLastRequest

add content to last user message

import { appendToLastRequest } from "@threaded/ai";

compose(
  appendToLastRequest("\n\nplease remember to always be concise"),
  model(),
);

modifies last user message in history

toolNotUsedInNTurns

trigger when tool not used for n turns

import { toolNotUsedInNTurns, appendToLastRequest } from "@threaded/ai";

compose(
  toolNotUsedInNTurns(
    { toolName: "search_web", times: 5 },
    appendToLastRequest("\n\nconsider using the search_web tool if needed"),
  ),
  model(),
);

reminds model about available tools

combining helpers

import {
  compose,
  model,
  scope,
  when,
  tap,
  Inherit,
  noToolsCalled,
  everyNMessages,
  toolWasCalled,
} from "@threaded/ai";

const workflow = compose(
  everyNMessages(
    20,
    scope(
      {
        inherit: Inherit.Conversation,
        system: "create a brief summary of the conversation",
        silent: true,
      },
      model(),
    ),
  ),

  scope(
    {
      inherit: Inherit.All,
      tools: [search, calculator, weather],
      until: noToolsCalled(),
    },
    model(),
  ),

  when(
    toolWasCalled("search_web"),
    tap((ctx) => console.log("search was used")),
  ),
);

helpers compose together for complex behaviors