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

@hasura/promptql

v2.0.0-alpha.15

Published

A Typescript SDK allows you to interact with PromptQL API

Readme

PromptQL TypeScript SDK

The PromptQL TypeScript SDK is a general-purpose SDK that interacts with the PromptQL API by Hasura. PromptQL enables natural language querying of your data through an AI-powered interface.

[!NOTE] This SDK supports PromptQL v2. Please install @hasura/[email protected] if you wants to integrate PromptQL v1.

Features

  • Type-safe API Client: Fully typed TypeScript SDK with auto-generated types from GraphQL schema
  • Thread Management: Create, list, and manage conversation threads
  • Real-time Streaming: Subscribe to thread events with GraphQL subscriptions using RxJS observables
  • Authentication: Built-in authentication handling with service account tokens
  • Query Planning: Access to AI agent query plans and execution steps
  • Artifact Support: Handle modified artifacts from AI responses
  • CLI Tool: Command-line interface for quick interactions
  • Flexible Configuration: Support for custom base URLs, headers, and fetch implementations

Requirements

  • Node.js >= 24
  • TypeScript >= 5.9.2

Installation

npm install @hasura/promptql@latest

Or with your preferred package manager:

# Yarn
yarn add @hasura/promptql@latest

# pnpm
pnpm add @hasura/promptql@latest

# Bun
bun add @hasura/promptql@latest

Quick Start

Getting Service Account Token

  1. Visit your Hasura project console
  2. Navigate to Project Settings
  3. Go to Service Accounts section
  4. Create a new service account token with Read Only permission. Avoid using the Admin role. Hackers can modify your project metadata if the service account token is leaked.
  5. Copy the token and use it in your SDK configuration

For more details, check the Hasura documentation.

Basic Usage

Start a PromptQL thread

import { PromptQLSdk } from '@hasura/promptql';

// Initialize the SDK
const sdk = new PromptQLSdk({
  projectId: 'your-project-id',
  serviceAccountToken: 'your-service-account-token',
});

// Start a new thread
const thread = await sdk.thread.start({
  message: 'What are the top 10 customers by revenue?',
});

console.log('Thread ID:', thread.thread_id);

// Stream events from the thread
sdk.thread.streamEvents(thread.thread_id).subscribe({
  next: (events) => {
    events.forEach(event => {
      console.log('Event:', event);
    });
  },
  error: (err) => console.error('Error:', err),
  complete: () => console.log('Interaction complete'),
});

Continue a Conversation

// Send a follow-up message to an existing thread
const result = await sdk.thread.sendMessage({
  threadId: 'existing-thread-id',
  message: 'Now show me their average order value',
});

// Stream the response
sdk.streamEvents(result.thread_id, result.thread_event_id)
  .subscribe({
    next: (events) => console.log('New events:', events),
  });

Wait until the final response only

Use the lastValueFrom function to wrap the subscription.

import { PromptQLSdk } from '@hasura/promptql';
import { lastValueFrom } from "rxjs";

// Initialize the SDK
const sdk = new PromptQLSdk({
  projectId: 'your-project-id',
  serviceAccountToken: 'your-service-account-token',
});

// Start a new thread
const thread = await sdk.thread.start({
  message: 'What are the top 10 customers by revenue?',
});

console.log('Thread ID:', thread.thread_id);

const events = await lastValueFrom(
  sdk.thread.streamEvents(
     result.thread_id,
  ),
);

events.forEach(event => {
  console.log('Event:', event);
});

Print new events only

import { PromptQLSdk, diffThreadEvents } from '@hasura/promptql';
import { pairwise, map } from 'rxjs';

// Initialize the SDK
const sdk = new PromptQLSdk({
  projectId: 'your-project-id',
  serviceAccountToken: 'your-service-account-token',
});

// Start a new thread
const thread = await sdk.thread.start({
  message: 'What are the top 10 customers by revenue?',
});

console.log('Thread ID:', thread.thread_id);

// Stream events from the thread
sdk.streamEvents(thread.thread_id)
  .pipe(
    pairwise(),
    map(([prev, curr]) => diffThreadEvents(prev, curr)),
  )
  .subscribe({
  next: (events) => {
    events.forEach(event => {
      console.log('Event:', event);
    });
  },
  error: (err) => console.error('Error:', err),
  complete: () => console.log('Interaction complete'),
});

Listing Threads

const threads = await sdk.thread.list({
  limit: 20,
  offset: 0,
  order_by: [{ created_at: 'desc' }],
  where: {
    // Optional filters
  },
});

threads.forEach(thread => {
  console.log(`Thread ${thread.id}:`, thread.title);
});

Get a Specific Thread

const thread = await sdk.thread.get('thread-id');
console.log('Thread:', thread);

Event Handling

Basics

The data structure of event data is the union of many event type. Each event type contains a different payload. You can go to the definition of ThreadEventData type to view the full data structure details.

The SDK also provides utility functions to parse different event types, for example, the following example catches and prints the query plan event and the final generated response:

import {
  getAgentPlanGenerationStartedEvent,
  getAgentPlanStepGeneratedEvent,
  getAgentGeneratedResponse,
  getUserMessageEvent,
} from '@hasura/promptql';

sdk.thread.streamEvents(threadId).subscribe({
  next: (events) => {
    events.forEach(event => {
      // Check for plan generation start
      const planStart = getAgentPlanGenerationStartedEvent(event.event_data);
      if (planStart) {
        console.log('Query Plan:\n');
        return;
      }

      // Check for plan steps
      const planStep = getAgentPlanStepGeneratedEvent(event.event_data);
      if (planStep) {
        console.log(`  - Step ${planStep.step_index}: ${planStep.step_title}\n`);
        return;
      }

      // Check for final response
      const response = getAgentGeneratedResponse(event.event_data);
      if (response) {
        const xmlRegex = /<\w+.*\/>/gm;
        console.log('Response:', source.replaceAll(xmlRegex, response.response.message));
        if (response.response.modified_artifacts) {
          console.log('Artifacts:', response.response.modified_artifacts);
        }
        return;
      }
    });
  },
});

Handle XML tags in generated response message

The generated message may contains XML tags. They represents custom UI elements that the markdown text doesn't support. You should parse or remove them if they aren't required.

Common XML tags are:

  • <artifact type="table" identifier="last_5_products" />: the identifier of the artifact block.
  • <user_mention id="user_id" />: mentioned user in the chat message.
  • <user_group_mention id="group_id" />: mentioned group in the chat message.
  • <promptql_mention />: represents a @promptql tag in the chat message.

You can remove them using regular expressions or parse the message to XML elements for advanced format.

const xmlRegex = /<\w+.*\/>/gm;
console.log(source.replaceAll(xmlRegex, ""));

Configuration Options

interface PromptQLSdkOptions {
  // Required: Project ID from PromptQL console
  projectId: string;

  // Required: Service account token for authentication
  serviceAccountToken: string;

  // Optional: Base URL of PromptQL data plane
  // Default: 'https://promptql.ddn.hasura.app'
  promptqlBaseUrl?: string;

  // Optional: Custom authentication host (for self-hosted control plane)
  authHost?: string;

  // Optional: Custom fetch implementation
  fetch?: typeof fetch;

  // Optional: Additional headers for all requests
  headers?: Record<string, string>;

  // Optional: IANA timezone for time-based queries
  // Default: Client's timezone
  timezone?: string;

  // Optional: DDN build ID
  // Default: Applied build
  buildId?: string;
}

License

Apache License 2.0 - see LICENSE file for details.

Links

Support

For support, please:

  1. Check the documentation
  2. Join the Hasura Discord community