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

@stackfactor/agent-utils

v1.2.7

Published

Shared utilities for StackFactor AI agent services — LangChain helpers, structured logging, error handling, and constants.

Downloads

4,213

Readme

@stackfactor/agent-utils

Shared utilities for StackFactor AI agent services — LangChain helpers, structured logging, error handling, and constants.

Installation

npm install @stackfactor/agent-utils

Modules

The package exports four modules:

import {
  langChain,
  logger,
  errorHandling,
  constants,
} from "@stackfactor/agent-utils";

langChain

Unified interface for running LLM prompts, managing LangChain agents, and generating images across OpenAI, Anthropic, Google, DeepSeek, Kimi (Moonshot), and GLM (Zhipu) providers.

langChain.runPromptWithModel(modelName, config, prompt, onProgressReport?, minPercent?, maxPercent?, expectsJsonResponse?, schema?, agentName?, tools?, usageTracker?)

Sends a prompt to an LLM and returns the response. Supports three execution modes:

  • Agentic (config.agentic === true) — creates and runs a LangChain agent with tools.
  • Streaming (onProgressReport provided) — streams the response with progress callbacks. Uses native response_format for OpenAI+schema, or NDJSON for other providers.
  • Non-streaming — direct invocation with JSON extraction.

When expectsJsonResponse is true (the default), JSON escape instructions are injected and the response is parsed. If a Zod schema is provided, the parsed result is validated.

| Parameter | Type | Default | Description | | --------------------- | -------------------- | --------------- | -------------------------------------------------------------------------------------------------------- | | modelName | string | — | Model identifier: "gpt-4o", "claude-3-5-sonnet", "gemini-1.5-pro", "deepseek-chat", "kimi-k2-0905-preview", "glm-4.6", etc. | | config | object | — | API keys (openAIAPIKey, anthropicAPIKey, googleAPIKey, deepSeekAPIKey, kimiAPIKey, glmAPIKey), temperature, agentic, recursionLimit | | prompt | string \| object[] | — | Plain string or array of { role, content } message objects | | onProgressReport | function \| null | null | Async callback receiving { message, progress } updates | | minPercent | number | 0 | Lower bound for progress percentage | | maxPercent | number | 100 | Upper bound for progress percentage | | expectsJsonResponse | boolean | true | Parse response as JSON | | schema | ZodSchema \| null | null | Zod schema for response validation | | agentName | string | "StackFactor" | Display name for the agent (agentic mode) | | tools | any[] | [] | LangChain tools available to the agent (agentic mode) | | usageTracker | UsageTracker \| null | null | Optional accumulator updated on every successful LLM call with cost (USD) and per-model token counts. |

Returns: JSON string (when expectsJsonResponse is true) or raw content string.

const usageTracker = {};
const result = await langChain.runPromptWithModel(
  "gpt-4o",
  { openAIAPIKey: "sk-..." },
  "Generate a summary of this document.",
  null,
  0,
  100,
  true,
  null,
  "StackFactor",
  [],
  usageTracker,
);
// usageTracker is now:
// {
//   cost: 0.00123,
//   tokens: {
//     "gpt-4o_inputTokens": 412,
//     "gpt-4o_outputTokens": 87,
//   }
// }

langChain.createAIAgent(name, modelName, systemPrompt, tools?, responseFormat?, config, onReportProgress?, minPercent?, maxPercent?)

Constructs a LangChain agent with a model, system prompt, and tools. When onReportProgress is provided, a report_progress tool is automatically added.

| Parameter | Type | Default | Description | | ------------------ | ------------------ | ------- | ---------------------------------------- | | name | string | — | Display name for the agent | | modelName | string | — | LLM identifier | | systemPrompt | string | — | System prompt describing agent behaviour | | tools | any[] | [] | LangChain tool instances | | responseFormat | any | — | Structured response format descriptor | | config | object | — | API keys, temperature, etc. | | onReportProgress | Function \| null | null | Progress callback | | minPercent | number | 0 | Minimum reportable progress | | maxPercent | number | 100 | Maximum reportable progress |

Returns: A configured LangChain agent instance.


langChain.runAIAgent(agent, prompt, config, onProgress?)

Executes a LangChain agent with a user prompt. Registers callbacks for tool_start, tool_end, agent_action, and error events when onProgress is provided. Logs execution time on completion.

| Parameter | Type | Default | Description | | ------------ | ------------------ | ------- | -------------------------------- | | agent | any | — | Agent created by createAIAgent | | prompt | string | — | User message to send | | config | object | — | recursionLimit (default: 25) | | onProgress | Function \| null | null | Progress event callback |

Returns: Raw response from the agent's invoke method.

const agent = langChain.createAIAgent(
  "Summarizer",
  "gpt-4o",
  "You summarize documents concisely.",
  [],
  null,
  { openAIAPIKey: "sk-..." },
);

const response = await langChain.runAIAgent(
  agent,
  "Summarize this text...",
  {},
);

langChain.runPromptWithModelForImageGeneration(modelName, config, prompt, options?)

Generates an image using OpenAI or Google AI models.

| Parameter | Type | Default | Description | | ----------- | -------- | ------- | --------------------------------------------------------------------------------------------------------- | | modelName | string | — | Image model: "dall-e-3", "gpt-image-1.5", "imagen-4.0-generate-001", "gemini-3.0-pro-image", etc. | | config | object | — | openAIAPIKey or googleAPIKey | | prompt | string | — | Text prompt describing the image | | options | object | {} | Provider-specific options (see below) |

OpenAI options: size ("1024x1024", "1792x1024", etc.), style ("vivid" or "natural"), responseFormat ("url" or "b64_json"), n (number of images).

Google options: aspectRatio ("1:1", "3:4", "4:3", "9:16", "16:9"), numberOfImages, negativePrompt.

Returns: { url?, b64_json?, revisedPrompt? } for single images, or { images: [...] } for multiple.

const image = await langChain.runPromptWithModelForImageGeneration(
  "dall-e-3",
  { openAIAPIKey: "sk-..." },
  "A futuristic city skyline at sunset",
  { size: "1792x1024" },
);

langChain.throwErrorIfNotSuccessful(response)

Guards that a response is a non-empty string. Throws an INTERNAL_SERVER_ERROR if not.

| Parameter | Type | Description | | ---------- | ----- | ----------------- | | response | any | Value to validate |

Returns: The response string if valid.


logger

GCP-compatible structured logging via Winston with OpenTelemetry trace enrichment.

logger.log(request, level, message, options?)

Writes a structured log entry. Automatically enriches with OpenTelemetry traceId and spanId when an active span exists. Prepends the user's email from the request object when available.

| Parameter | Type | Default | Description | | --------- | ---------- | ------- | -------------------------------------------------------------------------- | | request | any | — | HTTP request object (reads request.user.email), or null | | level | LogLevel | — | "error", "warn", "info", "http", "verbose", "debug", "silly" | | message | string | — | Log message | | options | object | {} | Additional structured fields (service, requestId, etc.) |

logger.log(req, logger.levels.info, "User signed in", { service: "auth" });
logger.log(null, logger.levels.error, "Connection failed");

logger.levels

Enum-like object mapping level names to their string values:

logger.levels.error; // "error"
logger.levels.warn; // "warn"
logger.levels.info; // "info"
logger.levels.http; // "http"
logger.levels.verbose; // "verbose"
logger.levels.debug; // "debug"
logger.levels.silly; // "silly"

errorHandling

Factory for consistently shaped error payloads.

errorHandling.create(errorCode, errorMessage, details?)

Creates a structured error object with a stack trace.

| Parameter | Type | Default | Description | | -------------- | -------- | ------- | ------------------------------------------ | | errorCode | number | — | HTTP status code or application error code | | errorMessage | string | — | Human-readable error description | | details | any | null | Optional supplementary information |

Returns: { code, message, details, stack }

throw errorHandling.create(404, "User not found");
throw errorHandling.create(400, "Validation failed", { field: "email" });

constants

Shared constants used across the package.

constants.HTTP_CODES

| Constant | Value | | ----------------------- | ----- | | BAD_REQUEST | 400 | | UNPROCESSABLE_ENTITY | 422 | | INTERNAL_SERVER_ERROR | 500 | | BAD_GATEWAY | 502 |

constants.ERROR

| Constant | Value | | ---------------------------- | ---------------------------------------- | | UNABLE_TO_GENERATE_CONTENT | "Unable to generate content" | | UNEXPECTED_ERROR | "An unexpected error occured..." | | UNSUPPORTED_MODEL | "The specified model is not supported" |


Supported Models

Text / Chat

| Provider | Model Prefix | Example | | ----------------- | ---------------------- | ------------------------------------ | | OpenAI | gpt- | gpt-4o, gpt-4o-mini | | Anthropic | claude- | claude-3-5-sonnet, claude-3-opus | | Google | gemini- | gemini-1.5-pro, gemini-2.0-flash | | DeepSeek | deepseek- | deepseek-chat, deepseek-reasoner | | Kimi (Moonshot) | kimi-, moonshot- | kimi-k2-0905-preview, moonshot-v1-8k | | GLM (Zhipu) | glm- | glm-4.6, glm-4.5 |

DeepSeek, Kimi, and GLM are routed through their OpenAI-compatible endpoints. Native structured output via response_format with JSON schema is only applied to gpt-* models; all other providers (including these three) use prompt-based JSON instructions.

Image Generation

| Provider | Model Prefix | Example | | -------- | ----------------------- | ------------------------------------------------- | | OpenAI | dall-e-, gpt-image- | dall-e-3, gpt-image-1.5 | | Google | imagen-, gemini- | imagen-4.0-generate-001, gemini-3.0-pro-image |


Config Object

The config object accepted by LangChain methods supports the following keys:

| Key | Type | Description | | ----------------- | --------- | ------------------------------------------- | | openAIAPIKey | string | OpenAI API key | | anthropicAPIKey | string | Anthropic API key | | googleAPIKey | string | Google AI API key | | deepSeekAPIKey | string | DeepSeek API key | | kimiAPIKey | string | Kimi (Moonshot) API key | | glmAPIKey | string | GLM (Zhipu) API key | | temperature | number | Sampling temperature | | maxTokens | number | Maximum output tokens (default: 16384 for Claude, 200000 for other providers). For Claude, values above 21333 automatically enable LangChain streaming to bypass the Anthropic SDK's 10-minute non-streaming guard. | | agentic | boolean | Enable agentic mode in runPromptWithModel | | recursionLimit | number | Max agent steps (default: 25) |


License

Not licensed — proprietary software of StackFactor Inc.