npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

langchain-task-steering

v0.1.8

Published

Implicit state machine middleware for LangChain.js agents. Ordered task pipelines with per-task tool scoping, prompt injection, and composable validation.

Readme

langchain-task-steering

Implicit state-machine middleware for LangChain.js agents. Define ordered task pipelines with per-task tool scoping, dynamic prompt injection, and composable validation.

Also available for Python.

PENDING ──> IN_PROGRESS ──> COMPLETE

The model drives its own transitions by calling update_task_status. The middleware enforces ordering, scopes tools, injects the active task's instruction into the system prompt, and gates completion via pluggable validators.

Install

npm i langchain-task-steering

Zero runtime dependencies. Works with any LangChain.js model provider (@langchain/anthropic, @langchain/aws, @langchain/openai, etc.).

Quick start

import { TaskSteeringMiddleware, type Task, type ToolLike } from 'langchain-task-steering'

const addItems: ToolLike = {
  name: 'add_items',
  description: 'Add items to the inventory.',
}

const categorize: ToolLike = {
  name: 'categorize',
  description: 'Assign items to categories.',
}

const pipeline = new TaskSteeringMiddleware({
  tasks: [
    {
      name: 'collect',
      instruction: "Collect all relevant items from the user's input.",
      tools: [addItems],
    },
    {
      name: 'categorize',
      instruction: 'Organize the collected items into categories.',
      tools: [categorize],
    },
  ],
})

The middleware exposes hooks you integrate into your agent loop:

pipeline.tools // all tools to register with the agent
pipeline.beforeAgent() // call on first invocation to init state
pipeline.wrapModelCall() // wrap model calls for prompt injection + tool scoping
pipeline.wrapToolCall() // wrap tool calls for validation + delegation
pipeline.afterAgent() // call after agent to check required tasks

See examples/simple-agent.ts for a full end-to-end example with Bedrock.

Agent integration

The middleware provides hooks — you wire them into your agent loop:

import { ChatBedrockConverse } from '@langchain/aws'

const model = new ChatBedrockConverse({
  model: 'us.anthropic.claude-sonnet-4-6',
  region: 'us-east-1',
})

// 1. Init state
const state = { messages: [] }
Object.assign(state, pipeline.beforeAgent(state))

// 2. Before each model call — get scoped tools + injected prompt
pipeline.wrapModelCall(request, (req) => {
  // req has filtered tools + injected system prompt
  return model.bindTools(req.tools).invoke(req.messages)
})

// 3. For update_task_status calls — route through middleware
const result = pipeline.wrapToolCall(toolCallReq, (r) =>
  pipeline.executeTransition(r.toolCall.args, r.state, r.toolCall.id)
)

// 4. When agent stops — check required tasks
const nudge = pipeline.afterAgent(state)
if (nudge) {
  /* add nudge message, continue loop */
}

Documentation

Detailed documentation is shared across both Python and TypeScript packages. The concepts and behavior are identical — only the API surface differs by language.

| Topic | Description | | -------------------------------------------------------- | --------------------------------------------------------------------- | | Task Mode | Task lifecycle, hooks, tool scoping, required tasks, configuration | | Workflow Mode | Dynamic workflow activation, catalog, human-in-the-loop, deactivation | | Task Middleware | TaskMiddleware hooks, validation, composition, persistent state | | Summarization | Post-completion message compression (replace and summarize modes) | | Skills | Task-scoped skills from SKILL.md files | | Backend Passthrough | Whitelisting backend tools through the filter |

Note: Code examples in the docs are primarily in Python. The TypeScript API mirrors the same design with camelCase naming (enforceOrder, globalTools, validateCompletion, etc.).

Configuration

const pipeline = new TaskSteeringMiddleware({
  tasks: [...],                    // required — ordered Task list
  globalTools: [],                 // tools available in every task
  enforceOrder: true,              // require tasks in definition order
  requiredTasks: ['*'],            // ['*'] = all, null = none, or list of names
  maxNudges: 3,                    // max nudge attempts before allowing exit
  globalSkills: [],                // skill names available in all tasks
  backendToolsPassthrough: false,  // whitelist known backend tools
  backendTools: null,              // override DEFAULT_BACKEND_TOOLS
  model: chatModel,                // default model for TaskSummarization
})

Task fields

| Field | Required | Description | | ------------- | -------- | ------------------------------------------------------------------------------------------ | | name | yes | Unique identifier (used in prompts and state). | | instruction | yes | Injected into system prompt when this task is active. | | tools | yes | Tools visible when this task is IN_PROGRESS. | | middleware | no | Scoped middleware — a TaskMiddleware, agent middleware object (auto-wrapped), or a list. | | skills | no | Skill names available when this task is IN_PROGRESS. | | summarize | no | Post-completion summarization config. See Summarization. |

Development

cd packages/typescript
npm install
npm test              # vitest run
npm run test:watch    # vitest in watch mode
npm run build         # tsup (CJS + ESM + .d.ts)
npm run lint          # tsc --noEmit
npm run format        # prettier --write

License

MIT — see LICENSE.