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

@steamory-agent-kit/gum

v0.2.0

Published

Node.js SDK for the Gum service.

Readme


Contents

Features

  • Fully typed TypeScript API.
  • ESM and CommonJS builds.
  • Works on Node.js 18+ with the built-in Fetch API.
  • Optional custom fetch implementation for tests, proxies, and custom runtimes.
  • Automatic Date serialization and undefined-value cleanup for request bodies.
  • Request timeout support with typed API errors, connection errors, and timeout errors.

Getting Started

Installation

# Install the SDK from npm.
npm install @steamory-agent-kit/gum

Quick Start

import { GumClient } from "@steamory-agent-kit/gum";

// Create a Gum client with your server-side API key.
const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

// Initialize a memory session for one user conversation.
const session = await gum.sessions.init({
  user_id: "user_id_xxxxx",
  session_id: "session_id_xxxxx",
});

// Add the conversation turns that Gum should use as memory.
await session.addMessages([
  {
    role: "user",
    content:
      "I'm setting up regular check-ins for our Europe team. Let's use Berlin as the city for that group.",
  },
  {
    role: "assistant",
    content:
      "Got it. I will use Berlin when you mention the Europe team.",
  },
  {
    role: "user",
    content:
      "For the Americas team, Toronto is usually the city I want to use.",
  },
]);

// Retrieve relevant memory before the next assistant response.
const memory = await session.getMemory({
  query: "which city should be used for Europe or Americas team scheduling",
});

console.log(memory.data);

Show Demo: Team Scheduling Assistant

This example shows a realistic turn lifecycle for an AI scheduling assistant: retrieve memory before calling your model, then write the new conversation back after the reply. The user does not need to repeat that Europe team scheduling usually uses Berlin, while Americas team scheduling usually uses Toronto.

import { GumClient } from "@steamory-agent-kit/gum";

const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

// Initialize this once for a new conversation, then store session.id.
const session = await gum.sessions.init({
  user_id: "user_id_xxxxxx",
  session_id: "session_id_xxxxxx",
  title: "Team scheduling session",
});

async function schedulingAssistantTurn(userContent: string) {
  // 1. SEARCH: retrieve relevant memory before calling your model.
  const memory = await session.getMemory({
    query: userContent,
    details: true,
  });

  // 2. PROMPT: inject the recalled memory into your model context.
  const systemPrompt = `
You are a team scheduling assistant.
Known user preferences:
${JSON.stringify(memory.data ?? {}, null, 2)}
Use these preferences naturally when answering.
`;

  // 3. LLM: replace this with OpenAI, Anthropic, Gemini, or your own model call.
  const assistantReply = await callYourLLM(systemPrompt, userContent);

  // 4. ADD: write the new turn back to Gum without blocking the response.
  void session.addMessages([
    { role: "user", content: userContent },
    { role: "assistant", content: assistantReply },
  ]).catch((error) => {
    console.error("Gum memory write failed", error);
  });

  return assistantReply;
}

Example flow:

await schedulingAssistantTurn(
  "For recurring team check-ins, use Berlin when I mention Europe and Toronto when I mention the Americas.",
);

await schedulingAssistantTurn(
  "Can you schedule the next sync for the region we discussed?",
);

Configuration

import { GumClient } from "@steamory-agent-kit/gum";

// Configure the client host and default timeout.
const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
  host: "gum.asix.inc",
  timeoutMs: 30_000,
});

| Option | Type | Default | Description | | --- | --- | --- | --- | | apiKey | string | Required | Gum API key. The SDK sends it as Authorization: Api-Key <apiKey>. Passing a value that already starts with Api-Key is also supported. | | host | string | gum.asix.inc | Gum service host override. Plain host values are normalized to HTTPS, so gum.asix.inc becomes https://gum.asix.inc. Explicit http:// or https:// URLs are preserved. | | timeoutMs | number | 30000 | Default request timeout in milliseconds. Set to 0 to disable the SDK timeout. | | fetch | FetchLike | globalThis.fetch | Custom Fetch-compatible implementation for tests, proxies, or custom runtimes. |


API Reference

Client

new GumClient(options)

Creates a client instance. The client exposes resource groups under gum.sessions and gum.userActions.

// Create a Gum client with the required API key.
const gum = new GumClient({
  apiKey: "gum_api_key",
});

gum.health(options?)

Checks the Gum service health endpoint.

// Check the Gum service health endpoint.
const health = await gum.health();

Sessions

gum.sessions.init(input, options?)

Initializes a Session and returns a Session object. Pass a creation request to create a new Session through the Gum API, or pass an existing Session id to rebuild the local object-style API without a network request. The object exposes the Session id and convenience methods that automatically use that id. input.user_id and input.session_id are required when creating a new Session.

// Create a new Session and inspect the returned helper.
const session = await gum.sessions.init({
  user_id: "user_123",
  session_id: "session_123",
  title: "Team scheduling session",
  metadata: {
    source: "assistant-api",
    channel: "web-chat",
  },
});

console.log(session.id);
console.log(session.rawResponse);

If Gum returns a successful response without data.session_id, the SDK throws Error: Gum API did not return data.session_id.

// Rebuild a Session helper from an existing Session id.
const session = await gum.sessions.init("session_123");

await session.addMessage({
  role: "user",
  content: "Continue where we left off. If I mention a region, use the city we picked for that team.",
});

const memory = await session.getMemory({
  query: "which city should be used for the user's team scheduling request",
});

session.addMessage(message, options?)

Adds one message to the created Session.

// Append one message to the Session.
await session.addMessage({
  role: "user",
  content:
    "For the Americas team, I usually coordinate from Toronto.",
});

session.addMessages(input, options?)

Adds messages to the created Session. input can be either a direct message array or an object with a messages property.

// Append messages with the array shorthand.
await session.addMessages([
  {
    role: "user",
    content:
      "For the Europe team check-in, keep Berlin as the city we are working from.",
  },
  {
    role: "assistant",
    content:
      "Understood. I will use Berlin for Europe team scheduling and Toronto for the Americas team.",
  },
]);

// Append messages with the object form.
await session.addMessages({
  messages: [
    {
      role: "user",
      content:
        "That works for me: Berlin when I mention Europe, and Toronto when I mention the Americas.",
      metadata: {
        channel: "chat",
      },
    },
  ],
});

session.getMemory(params?, options?)

Retrieves memory for the created Session. Pass query to focus the retrieval and details to include detailed memory data when the API supports it.

const memory = await session.getMemory({
  query: "which city should be used for Europe or Americas team scheduling",
  details: true,
});

Pass recall_config to override memory recall behavior. When recall_config is present, the SDK uses the POST context endpoint so the configuration can be sent as a JSON body.

const memory = await session.getMemory({
  query: "which city should be used for the user's team scheduling request",
  details: true,
  recall_config: {
    message_recent_limit: 20,
    message_semantic_top_k: 8,
    query_router: "single_hop_parallel",
    enable_long_term_recall: false,
  },
});

gum.sessions.addMessages(sessionId, input, options?)

Lower-level API for adding messages when you already have a Session id. input can be either a direct message array or an object with a messages property.

// Append messages by Session id with the array shorthand.
await gum.sessions.addMessages("session_123", [
  {
    role: "user",
    content:
      "Use the Europe city we discussed and draft the agenda for the next team check-in.",
  },
  {
    role: "assistant",
    content:
      "I will use Berlin for that check-in and keep the agenda focused on project updates.",
  },
]);

// Append messages by Session id with the object form.
await gum.sessions.addMessages("session_123", {
  messages: [
    {
      role: "user",
      content:
        "That works for me: Berlin when I mention Europe, and Toronto when I mention the Americas.",
      metadata: {
        channel: "chat",
      },
    },
  ],
});

gum.sessions.getMemory(sessionId, params?, options?)

Lower-level API for retrieving memory when you already have a Session id. Pass query to focus the retrieval and details to include detailed memory data when the API supports it.

const memory = await gum.sessions.getMemory("session_123", {
  query: "which city should be used for Europe or Americas team scheduling",
  details: true,
});

As with session.getMemory, this lower-level method automatically uses the POST context endpoint when recall_config is present.

User Actions

gum.userActions.create(input, options?)

Creates one user action log.

// Write a user action event with optional anchors and metadata.
await gum.userActions.create({
  user_id: "user_123",
  timestamp: new Date(),
  content: "User opened the Europe team scheduling page",
  session_id: "session_123",
  event_type: "page_view",
  page: "team_scheduling",
  anchors: {
    region: "Europe",
    city: "Berlin",
  },
  metadata: {
    source: "assistant-api",
  },
});

Runtime Contracts

Request Options

Every SDK method accepts optional request options as its last argument.

// Override timeout, abort signal, and headers for one request.
const controller = new AbortController();

await gum.sessions.getMemory(
  "session_123",
  { query: "which city should be used for the user's team scheduling request" },
  {
    timeoutMs: 5_000,
    signal: controller.signal,
    headers: {
      "X-Request-Id": "request_123",
    },
  },
);

| Option | Type | Description | | --- | --- | --- | | timeoutMs | number | Overrides the client timeout for one request. | | signal | AbortSignal | External abort signal. | | headers | HeadersInit | Additional request headers. |

Response Shape

Resource methods return the Gum response envelope:

// Resource methods return this generic Gum response envelope.
type GumEnvelope<T = unknown> = {
  data?: T;
  success?: boolean;
  message?: string;
  error?: unknown;
  [key: string]: unknown;
};

For example, gum.sessions.init() returns Promise<Session>. The Session id is available as session.id, and session.rawResponse preserves the original create response envelope for new Sessions. When initialized from an existing id, rawResponse is synthetic and shaped as { data: { session_id: sessionId } }. This is a breaking change from earlier 0.x versions where gum.sessions.create() and gum.sessions.fromId() were separate public methods.

Error Handling

import {
  GumApiError,
  GumConnectionError,
  GumTimeoutError,
} from "@steamory-agent-kit/gum";

// Handle SDK error types explicitly.
try {
  await gum.sessions.init({
    user_id: "user_123",
    session_id: "session_123",
    title: "Team scheduling session",
  });
} catch (error) {
  if (error instanceof GumApiError) {
    console.error(error.status, error.detail, error.body);
  } else if (error instanceof GumTimeoutError) {
    console.error(`Request timed out after ${error.timeoutMs}ms`);
  } else if (error instanceof GumConnectionError) {
    console.error("Network or fetch failure", error.cause);
  } else {
    throw error;
  }
}

| Error | When it is thrown | | --- | --- | | GumApiError | Gum returns a non-2xx response. Includes status, statusText, headers, body, and detail. | | GumConnectionError | The underlying fetch request fails before a response is received. | | GumTimeoutError | A request is aborted by timeout or an AbortSignal. Extends GumConnectionError. |

TypeScript

The package ships generated type declarations. Public types are exported from the package root:

// Import public SDK TypeScript types from the package root.
import type {
  ActionLogInput,
  GumClientOptions,
  Message,
  RecallConfig,
  Session,
  SessionMemory,
} from "@steamory-agent-kit/gum";

Session public types use the same naming as the gum.sessions resource group.


Project

Development

# Install dependencies, verify types, run tests, and build the package.
npm install
npm run typecheck
npm test
npm run test:coverage
npm run build

Publishing

The repository includes a .gitlab-ci.yml pipeline for verifying, building, and publishing this SDK to npm.

GitLab requirements:

  • Add a masked and protected CI/CD variable named NPM_TOKEN.
  • NPM_TOKEN must contain an npm granular access token with publish permission for @steamory-agent-kit/gum.
  • If the npm account or package requires 2FA for publishing, create the token with bypass 2FA enabled. Otherwise the publish job will fail with EOTP.
  • For a one-off manual publish with a non-bypass token, run the publish job manually and add a temporary NPM_OTP variable containing the current authenticator code.

Pipeline flow:

# Verify and publish the package from CI.
npm ci
npm run typecheck
npm test
npm run build
npm pack --dry-run
npm publish --access public --tag latest

The publish job runs automatically for Git tags and can be run manually from the default branch. Automatic tag publishing requires an NPM_TOKEN that can publish without an interactive OTP prompt. Before publishing, update the version in package.json. npm does not allow publishing the same package version twice.

Contributing

Issues and pull requests are welcome. For code changes, please run the local checks before opening a pull request:

# Run the core local checks before opening a pull request.
npm run typecheck
npm test
npm run build

License

MIT