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

@loopstack/hitl-example-module

v0.24.0

Published

Comprehensive Human-in-the-Loop examples — custom document with widget, AskUserWorkflow / ConfirmUserWorkflow sub-workflow shortcuts, and LLM agent loops with AskClarificationTool / AskForApprovalTool

Readme


title: HITL Examples Module description: Comprehensive examples of Human-in-the-Loop patterns in Loopstack — custom Document with a form widget, AskUserWorkflow / ConfirmUserWorkflow sub-workflow shortcuts, and LLM agent loops with the ask_clarification / ask_for_approval tools. Demonstrates when to design a form vs delegate to a generic prompt vs let an agent decide to ask.

@loopstack/hitl-example-module

Side-by-side examples of every way to pause a Loopstack workflow for the user.

The point of this package is to answer one question: when do I design a custom document with a widget, vs. when do I delegate to a HITL sub-workflow, vs. when do I let an LLM agent ask the user?

Decision matrix

| You are building... | Use | Workflow in this package | | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A predefined workflow with known user-input steps — form fields, structured data, a record the user edits | Custom document with a widget — your workflow owns the document and the wait: true transition | InlineFormWorkflow, PromptInputChatWorkflow | | An LLM agent loop where the LLM dynamically decides to ask the user something or request approval | Agent tools ask_clarification / ask_for_approval from @loopstack/hitl | AgentAskClarificationWorkflow, AgentAskForApprovalWorkflow | | A predefined workflow that just needs a quick generic ask — one free-text field, yes/no, pick-one — and you don't want to design a form | Sub-workflow shortcutAskUserWorkflow / ConfirmUserWorkflow from @loopstack/hitl | AskUserTextWorkflow, AskUserOptionsWorkflow, AskUserConfirmWorkflow, ConfirmContentWorkflow |

Why custom document is the default for predefined workflows

The HITL sub-workflows (AskUserWorkflow, ConfirmUserWorkflow) were designed primarily for agent loops, where the LLM doesn't know in advance what it will need to ask — at runtime it picks a question and a presentation mode and the agent tool wraps a generic sub-workflow around it.

In your own predefined workflow you already know what you need from the user. Owning the document means the form is the structured data: the same record holds the prompt, the user's edits, and the final answer. The wait-transition payload schema is also your document schema, so types line up end-to-end with no wrapping or unpacking.

The sub-workflow shortcut is still useful — when the ask is small and generic, designing a form is overkill. Treat it as exactly that: a shortcut, not the primary pattern.

What each workflow shows

Predefined workflow owns the UI (custom document)

  • InlineFormWorkflow — defines a FeedbackFormDocument with a widget: form YAML config. The form's Submit button triggers a submitFeedback wait-transition; the transition payload conforms to the document schema. The same document is saved twice — once as the empty prompt, once with the submitted values.
  • PromptInputChatWorkflow — workflow-level widget: prompt-input YAML with enabledWhen: [waiting_for_user]. Loops on user messages without any LLM, demonstrating the chat-style entry pattern that the LLM examples build on.

LLM agent prompts the user

  • AgentAskClarificationWorkflow — launches AgentWorkflow with tools: ['ask_clarification'] and a system prompt that tells the LLM to ask the user when information is missing. The agent pauses its loop on each call and resumes once the user answers.
  • AgentAskForApprovalWorkflow — same shape, with tools: ['ask_for_approval']. The LLM drafts content, then hands it to the user for explicit confirm/deny before finalizing.

Sub-workflow shortcut (predefined workflow, generic ask)

  • AskUserTextWorkflowAskUserWorkflow.run({ question }) for a one-shot free-text answer.
  • AskUserOptionsWorkflowmode: 'options' with allowCustomAnswer: true for a pick-one list with a custom-text fallback.
  • AskUserConfirmWorkflowmode: 'confirm' for a quick yes/no decision; the answer is the literal string 'yes' or 'no'.
  • ConfirmContentWorkflowConfirmUserWorkflow.run({ markdown }) to show a pre-rendered markdown blob for review; the callback receives { confirmed: boolean, markdown: string }.

Installation

npm install @loopstack/hitl-example-module

Register the module. Use forFeature to provide an LLM configuration for the two agent workflows:

import { Module } from '@nestjs/common';
import { HitlExampleModule } from '@loopstack/hitl-example-module';

@Module({
  imports: [
    HitlExampleModule.forFeature({
      llm: {
        providers: [
          /* claude or openai provider config */
        ],
      },
    }),
  ],
})
export class MyModule {}

The four non-agent workflows (InlineFormWorkflow, PromptInputChatWorkflow, AskUser*Workflow, ConfirmContentWorkflow) work without any LLM provider configuration.

Public API

  • Module: HitlExampleModule
  • Workflows: InlineFormWorkflow, PromptInputChatWorkflow, AskUserTextWorkflow, AskUserOptionsWorkflow, AskUserConfirmWorkflow, ConfirmContentWorkflow, AgentAskClarificationWorkflow, AgentAskForApprovalWorkflow
  • Documents: FeedbackFormDocument (used by InlineFormWorkflow)

Dependencies

  • @loopstack/common, @loopstack/hitl — HITL sub-workflows and agent tools
  • @loopstack/agent, @loopstack/llm-provider-module — for the two agent examples

Related

About

Author: Jakob Klippel

License: MIT