SDK reference
@lex/sdk 0.1.2. The SDK holds no keys and does no privileged work: every call is a message to the host, which forwards it to the API for authorization.
createLex(options?)
import { createLex } from '@lex/sdk';
const lex = createLex();| Option | Default | |
|---|---|---|
timeoutMs | 15000 | Timeout per request |
streamIdleTimeoutMs | 120000 | Idle timeout for requestAgent |
connectTimeoutMs | 10000 | How long to wait for the host to connect |
port | the host's port | A custom transport, for tests |
getContext()
const { user, miniProgram, locale } = await lex.getContext();
// user: { id, displayName? }, miniProgram: { id, version }, locale?: stringnotify(input) · ui.notifications
await lex.notify({ title: 'Saved', message: 'Your board is up to date', level: 'success' });level is info (default), success, warning or error.
storage · storage.scoped
Private to this workspace, this user and this Mini Program.
await lex.storage.set('tasks', [{ id: 1, title: 'Plan sprint' }]);
const tasks = await lex.storage.get<Task[]>('tasks'); // null if missing
await lex.storage.remove('tasks');
const keys = await lex.storage.keys();Keys up to 128 characters, values up to 64 KB of JSON, up to 200 keys.
requestAgent(input) · agent.request
Streams an assistant's answer. Break out of the loop to cancel.
let answer = '';
for await (const event of lex.requestAgent({ prompt: 'Plan these tasks for this week: …' })) {
if (event.type === 'delta') answer += event.text;
if (event.type === 'completed') answer = event.output;
if (event.type === 'failed') throw new Error(event.message);
}Pass botId to ask a specific bot. The assistant gets no tools when called from a Mini Program.
ai.text(input) · ai.text
Text from Lexcetha's language model. Pass a single prompt, or a conversation in messages.
const { text, credits } = await lex.ai.text({
system: 'You write short, friendly product descriptions.',
prompt: 'A reusable bamboo lunch box',
maxTokens: 300,
});messages is [{ role: 'user' | 'assistant', content }] (up to 50). maxTokens is the longest answer, default 1024, at most 2048. credits is what the call cost you.
ai.transcribe(audio, options?) · ai.transcribe
Speech to text. audio is a Blob of up to 10 MB, for example from media.recordAudio().
const { text } = await lex.ai.transcribe(audio, { language: 'id' });language is optional (an ISO code such as en or id); without it the model detects the language.
ai.speak(text, options?) · ai.speak
Text to speech, up to 4096 characters. Returns an MP3 Blob.
const mp3 = await lex.ai.speak('Your meeting summary is ready.');
new Audio(URL.createObjectURL(mp3)).play();ai.image(prompt, options?) · ai.image
const png = await lex.ai.image('A flat illustration of a lighthouse at dawn', { quality: 'high' });
img.src = URL.createObjectURL(png);quality is standard (default) or high, which costs more.
ai.video · ai.video
Videos take minutes. create starts one, follows it and returns the video Blob:
const video = await lex.ai.video.create('A 3D logo spinning on a white background', {
onProgress: (p) => (bar.value = p), // 0-100
});
player.src = URL.createObjectURL(video);Options: intervalMs (how often to check, default 3000) and timeoutMs (default 20 minutes; then it rejects with TIMEOUT). To manage it yourself, use start(prompt) → { jobId }, status(jobId) → { status: 'queued' | 'running' | 'succeeded' | 'failed', progress, error? } and result(jobId) → Blob. Keep the jobId (for example in storage) if the person might close the Mini Program while it runs.
media.recordAudio(options?) · media.microphone
Records from the microphone and returns the audio Blob. Your iframe never touches the microphone: Lex asks the person, shows its own recorder with Stop and Cancel, and hands you the result.
const audio = await lex.media.recordAudio({ maxSeconds: 1800 });It stops when the person presses Stop or at maxSeconds (default 600, at most 3600). It rejects with CANCELLED if they cancel and PERMISSION_DENIED if the browser blocks the microphone.
All ai.* calls are paid from your AI credits and count toward the person's daily limit; see AI models & credits.
Errors
Every failure rejects with a LexError whose code is stable:
| Code | Meaning |
|---|---|
PERMISSION_DENIED | The capability isn't in your approved manifest |
INVALID_REQUEST | Bad input (e.g. a value too large for storage) |
RATE_LIMITED | Too many calls (a session allows 2,000), the workspace budget is used up, or the person reached today's AI limit in your Mini Program |
TIMEOUT | No answer in time |
CANCELLED | You stopped it |
BRIDGE_UNAVAILABLE | Not running inside a Lex host, or the host didn't connect |
UNSUPPORTED_PROTOCOL | SDK and host speak different protocol versions |
SESSION_ENDED | The runtime session ended (closed, expired after an hour, or the version was disabled) |
INSUFFICIENT_CREDITS | Your AI credits ran out (ai.* only) |
UNAVAILABLE | That AI model isn't set up on this Lexcetha instance |
INTERNAL | Something went wrong on the platform |
import { LexError } from '@lex/sdk';
try {
await lex.storage.set('big', hugeValue);
} catch (e) {
if (e instanceof LexError && e.code === 'INVALID_REQUEST') showTooBig();
}Bridge protocol
@lex/sdk/protocol exports the version 1 message types for anyone implementing a host. Messages carry lex: 1; requests and responses are matched by id, and streams end with stream_end.
