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.
Table of Contents
- Overview
- Features
- Registration & Prerequisites
- Installation
- Quick Start
- Concepts
- Usage Guide
- Configuration & Options
- Best Practices
- Writing Good Context Entries
- Minimizing Sensitive Data Exposure
- Streaming UI Pattern
- Handling Fallbacks & Warnings
- Engagement Throttling Recommendations
- Retry & Backoff Strategy
- Efficient Context Lifecycle
- Server vs Browser Separation
- Using
rewrite
Safely - Sorting for Personalization
- LocalStorage Hygiene (when
useStorage
true) - Defensive UI States
- Graceful Degradation
- Internationalization
- Cleaning / Resetting Sessions
- Multi-Agent Architecture
- Troubleshooting / FAQ
- Security Notes
- License
- Support
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
- Create an account at https://heylock.dev
- Create an agent in the dashboard.
- Configure personality and knowledge.
- Generate the secret key.
- 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 checkisInitialized
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. IfsaveToMessageHistory
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. IfsaveToMessageHistory
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. Useinstructions
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. Useinstructions
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 andfallback: 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 optionallyclearContext()
.
Multi-Agent Architecture
Why: Isolation between personas prevents context bleed and clarifies analytics attribution.
- Use distinct
agentId
s 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
- Email: support@heylock.dev