JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 9
  • Score
    100M100P100Q65729F
  • License Apache-2.0

Zero‑friction AI agent integration for JavaScript & TypeScript projects.

Package Exports

  • heylock
  • heylock/dist/index.min.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (heylock) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Heylock

Zero‑friction AI agent integration for JavaScript & TypeScript projects.

npm version npm downloads types included esm only license

Table of Contents

Overview

Integrate AI in 2 lines of code with Heylock.

  • Remembers what users do and say
  • Talks back to them, like a real support manager
  • Helps you sort stuff (literally anything) and fix words to sound better
  • Knows when to pop up and engage a prospect
  • And more

You just set up your agent on the website, then use this package to integrate AI. No hard work. No boring code. Just plug it in and look smart.

Why use Heylock?

  • You get all the cool features with almost no work
  • It saves you hours (maybe days!)
  • Your competitors will think you’re a genius for implementing those features

Features

  • 💬 Message (message) – Full chat capabilities.
  • 🔄 Streaming (messageStream) – Token‑by‑token replies for "instant" feel.
  • 👋 Greeting (greet) – Tailored first message so prospects are more likely to engage.
  • 🕵️ Engagement (shouldEngage) – Thinks “Should I pop up now?” with reasoning for debugging.
  • ✍️ Rewrite (rewrite) – Fix tone/grammar in one line.
  • 📊 Sort (sort) – AI ranks any list (products, leads, docs, literally anything).
  • 🧠 Context Store – Log user actions to enable personalized answers from AI.
  • 🗂️ Message History – Full chat transcript managed for you (modify / clear / stream updates).
  • 🚦 Balance (fetchBalanceRemaining) – Know remaining balance early.

Why you should care:

  • ⚡ Integrate core agent features in under 5 minutes.
  • 🛠️ Tailor your website’s experience for each user, so your site adapts to them in real time.

Developer Gains at a Glance

  • You don’t need to build: streaming parser, rate limiter, context store, chat log manager, AI sorter, rewrite tool. Just import and use.
  • Make a real chat + smart features in minutes instead of days.
  • Clear reasons (from sort & engage) help you tune and A/B test fast.
  • Safety built in: input checks, defensive copies = fewer weird bugs.

Registration & Prerequisites

  1. Create an account at https://heylock.dev
  2. Create an agent in the dashboard.
  3. Configure personality and knowledge.
  4. Generate the secret key.
  5. Start using AI agents!

Installation

Run this in your console.

npm install heylock

Runtime requirements:

  • Node: >= 18 (for native fetch + modern syntax: private fields, optional chaining, async generators, nullish coalescing). For Node 16/14 add a fetch polyfill (undici) and ensure ES2020 support.
  • Browser: Modern evergreen browsers (ES2020). LocalStorage features require a standard DOM environment.

Quick Start

import Heylock from 'heylock';

const agent = new Heylock(process.env.HEYLOCK_AGENT_KEY, {
    useStorage: false,          // Set to false when running server-side
    useMessageHistory: true,
    suppressWarnings: false
});

agent.onInitialized(async (success) => {
    const reply = await agent.message('Hello, Heylock!');
    
    console.log('Agent:', reply);
});

Streaming example (progressive UI):

for await (const chunk of agent.messageStream('Explain this feature briefly.')) {
    process.stdout.write(chunk); // append to UI / console
}

Concepts

Concept Summary
Agent Your AI agent, set up in dashboard, used by key
Context List of user actions for better replies
Message History Chat log of user and assistant messages
Streaming Get reply chunks as they arrive
Fallbacks Returns partial results or warnings if needed

Usage Guide

1. Initialization & Lifecycle

  • new Heylock(agentKey, options) — Starts the agent and checks your key.
  • Use onInitialized(callback) or check isInitialized to run code when ready.

2. Context Management

  • addContextEntry(content, timestamp?) — Add a new context fact. Timestamp is optional.
  • modifyContextEntry(index, content, timestamp?) — Change a context entry by its index.
  • removeContextEntry(index) — Remove a context entry by its index.
  • clearContext() — Remove all context entries.
  • getContextString() — Get a human-readable summary of context.
  • If useStorage is true in the browser, context is saved in localStorage.

3. Message History

  • addMessage(content, role?) — Add a message to the chat log. Role is 'user' or 'assistant' (default: 'user').
  • modifyMessage(index, content, role?) — Change a message by its index.
  • removeMessage(index) — Remove a message by its index.
  • setMessageHistory(messages) — Replace the whole chat log.
  • clearMessageHistory() — Remove all messages from the chat log.
  • onMessageHistoryChange(callback) — Run code when the chat log changes.

4. Sending Messages

  • message(content, useContext = true, saveToMessageHistory = true) — Send a message to your agent and get the assistant’s reply as a string. If saveToMessageHistory is true, both your message and the reply are saved in the chat log.
  • messageStream(content, useContext = true, saveToMessageHistory = true) — Stream the assistant’s reply in pieces (chunks) using an async generator. If saveToMessageHistory is true, the assistant’s message in the chat log is updated live as new chunks arrive.

5. Greeting

  • greet(instructions?, useContext = true, saveToMessageHistory = true) — Get a friendly first message from the agent. Use instructions to guide the greeting.

6. Engagement Decision

  • shouldEngage(instructions?) — Ask if the agent should pop up now. Returns { shouldEngage, reasoning, warning?, fallback }.

7. Rewrite

  • rewrite(content, instructions?, useContext = true) — Fix or change text using AI. Use instructions to guide the rewrite.

8. Sort

  • sort(array, instructions?, useContext = true) — AI sorts your array. Returns { array, indexes, reasoning?, warning?, fallback? }. If sorting fails, you get the original array and fallback: true.

9. Balance

  • fetchBalanceRemaining() — Check your balance.

Type Definitions

Interfaces:

  • AgentOptions (useStorage, useMessageHistory, suppressWarnings, agentId)
  • Message
  • ContextEntry
  • BalanceRemaining
  • ShouldEngageResult
  • SortResult

Core Class: Heylock

  • Constructor
  • Properties: isInitialized, balanceRemaining, messageHistory, context
  • Callbacks: onInitialized, onMessageHistoryChange, onContextChange
  • Context methods
  • Message history methods
  • Message / streaming / greet
  • Engagement / rewrite / sort / limits

Configuration & Options

Option Type Default Description
useStorage boolean auto (true in browser, false server) Persist context to localStorage (browser only).
useMessageHistory boolean true Maintain internal transcript.
suppressWarnings boolean false Hide non-fatal console warnings (e.g., throttling, environment).
agentId string 'default' Namespacing for multi-agent storage keys.

Environment Behavior:

  • Browser: If useStorage true, context persists (heylock:<agentId>:context).
  • Server (Node): Context is stored only in RAM.

Best Practices

Writing Good Context Entries

Why: Focused, consistent context reduces prompt size and improves response relevance without noise.

  • Use clear, short sentences that describe what the user did or what happened.
  • Focus on actions or events that help the agent give better answers.
  • Use past tense, and be specific.
  • The agent will see entries as in getContextString() – "User did X now", "User did X 5 minutes ago"

Examples:

  • "User clicked the X button"
  • "User opened brand tab"
  • "User hovers the cursor over technical details"
  • "User added item X to cart"
  • "User switched to dark mode"

Minimizing Sensitive Data Exposure

Why: Reduces risk of data leaks, simplifies compliance (GDPR/CCPA), and limits blast radius if logs are compromised.

  • Never add PII (emails, full names, addresses, secrets) to context or messages unless absolutely required.
  • Prefer ephemeral user/event IDs over raw identifiers.
  • Strip values before calling addContextEntry().

TypeScript example (sanitizing):

function safeContextEvent(raw: { email?: string; action: string }) {
    const anon = raw.email ? raw.email.split('@')[0] : 'user';

    agent.addContextEntry(`${anon} ${raw.action}`); // no full email stored
}

Streaming UI Pattern

Why: Early incremental feedback lowers perceived latency and increases user engagement.

  • Render partial chunks immediately for perceived speed.
  • Keep a mutable buffer; only commit to history at the end (SDK does this if saveToMessageHistory true).
  • Show a typing indicator while awaiting first chunk (set timeout >300ms to avoid flicker).

Example:

let buffer = '';
for await (const chunk of agent.messageStream(prompt)) {
    buffer += chunk;
    updateChatBubble(buffer);
}

Handling Fallbacks & Warnings

Why: Graceful degradation prevents hard failures and preserves UX while signaling issues for observability.

  • Always check fallback / warning for non-fatal degradations.
  • Log once; avoid noisy consoles in production by gating with NODE_ENV.
const result = await agent.sort(products, 'Rank by likelihood of purchase');

if (result.fallback) {
    // Use original order, maybe schedule retry with different arguments.
    console.warn('Sort fallback, using original array');
}

Engagement Throttling Recommendations

Why: Avoids spamming users and improves trust while still triggering help at high-intent moments.

  • Call shouldEngage() on meaningful user intent (time-on-page > N seconds, scroll depth, idle detection) not every minor event.
  • Respect { shouldEngage, reasoning }; log sampled reasoning for tuning.
const { shouldEngage, reasoning } = await agent.shouldEngage();

if (shouldEngage === true){ 
    openChat();
} else{ 
    debugSample(reasoning);
}

Retry & Backoff Strategy

Why: Mitigates transient network/service hiccups without amplifying load or causing duplicate side effects.

  • Network/transient errors: retry idempotent methods (message, rewrite, sort) with exponential backoff (e.g., 250ms * 2^n, max ~3 retries).
  • Do not retry shouldEngage() inside cooldown window.

Pseudo-code:

async function withRetry(op, attempts = 3) {
    let delay = 250;

    for (let i = 0; i < attempts; i++) {
        try { 
            return await op(); 
        } catch (e) {
            if (i === attempts - 1) throw e;

            await new Promise(resolve => setTimeout(resolve, delay));

            delay *= 2;
        }
    }
}

Efficient Context Lifecycle

Why: Prevents drift from outdated or duplicative events.

  • Cull stale entries (e.g., actions > 30m old) to keep prompt concise.
  • Avoid duplicate semantic events; coalesce rapid similar actions.
function pruneContext() {
    const now = Date.now();
    agent.context = agent.context.filter(entry => now - (entry.timestamp || now) < 30 * 60_000);
}

Server vs Browser Separation

Why: Protects the secret key and centralizes security, rate limiting, and auditing.

  • Prefer running SDK server-side with secret key; expose minimal HTTP endpoints for browser.
  • If using browser, proxy: browser -> your server -> Heylock.

Using rewrite Safely

Why: Ensures consistent tone while preserving original data for audits and rollback.

  • Use for style normalization (tone, grammar) before storage or indexing.
  • Keep original text if audit trail required.
const polished = await agent.rewrite(draft, 'Professional, concise, keep emojis if present');

Sorting for Personalization

Why: Clear objectives yield more reliable AI ranking and simplify post-result validation.

  • Provide explicit objective: "Sort by relevance to SEARCH_TERM for a first-time visitor".
const ranking = await agent.sort(items, 'Sort by highest estimated CTR for mobile users');

LocalStorage Hygiene (when useStorage true)

Why: Namespacing avoids key collisions across environments and eases user privacy controls.

  • Namespace via agentId per environment (e.g., myagent-dev, myagent-prod).
  • Provide a manual clear option in user settings.

Defensive UI States

Why: Immediate feedback and constraint-based disabling reduce accidental duplicate actions.

  • Disable send button while awaiting first chunk to avoid rapid duplicates.
  • Grey out chat input on balanceRemaining <= 0.

Graceful Degradation

Why: Users retain core functionality even when advanced AI features are unavailable.

  • If AI features fail, provide sensible defaults: original order list, unmodified text, chat disabled banner.
  • Communicate fallback politely to user only when necessary.

Internationalization

Why: Stable machine-readable context improves model consistency across locales.

  • Store stable event keys in context ("Added to cart") and localize only in UI layer; keep context language consistent for model reliability.

Cleaning / Resetting Sessions

Why: Resetting clears model bias from earlier context and supports multi-user demos/tests.

  • Expose a "Reset Conversation" button that calls clearMessageHistory() and optionally clearContext().

Multi-Agent Architecture

Why: Isolation between personas prevents context bleed and clarifies analytics attribution.

  • Use distinct agentIds per persona (e.g., support, recommender).

Troubleshooting / FAQ

Issue Likely Cause Action
isInitialized stays false Invalid key / network error Regenerate agent key; Check console warnings.
Throttling warning on shouldEngage Called again < 15s Debounce / gate UI triggers.
Streaming stops early Network interruption Retry with exponential backoff; inspect partial assistant message.
fallback: true in sort/rewrite Service fallback or rate limit Present basic result; optionally retry later.
Context not persisting useStorage false or server env Enable useStorage in browser; confirm not running server-side.

For questions or assistance, contact support@heylock.dev.

Security Notes

  • The agent secret key is sensitive—treat like any private API key.
  • Recommended: Keep key on the server; expose a minimal proxy endpoint for untrusted clients.
  • Avoid embedding the secret in public bundles. If you do client proofs-of-concept, rotate keys frequently.
  • Disable useStorage if you don't want context written to the user's browser.

License

Apache 2.0. See LICENSE.

Support