Complete API reference for the Plugin SDK (@sperax/plugin-sdk) from nirholas/plugin.delivery.
- Installation
- Client SDK (speraxOS)
- React Hooks
- Schema Validation
- Error Types
- Server Utilities
- Communication Channels
# Install the SDK from nirholas/plugin.delivery
pnpm add @sperax/plugin-sdk
# Or with npm/yarn/bun
npm install @sperax/plugin-sdk
yarn add @sperax/plugin-sdk
bun add @sperax/plugin-sdkThe speraxOS object provides methods for plugin-to-host communication from the nirholas/plugin.delivery SDK. Import from the client subpath:
import { speraxOS } from '@sperax/plugin-sdk/client';Get the Function Call initialization payload including arguments, name, settings, and state.
interface PluginPayload<T = any> {
arguments?: T;
name: string;
settings?: Record<string, any>;
state?: Record<string, any>;
}
const payload = await speraxOS.getPluginPayload<MyArgs>();
console.log(payload.name); // API name that was called
console.log(payload.arguments); // Arguments passed to the function
console.log(payload.settings); // Plugin settings from user configRetrieve the current plugin message content (the content field deserialized as JSON).
const message = await speraxOS.getPluginMessage<MyMessageType>();
console.log(message);Update the plugin message content. This serializes the content and triggers conversation flow.
await speraxOS.setPluginMessage({
title: 'Result',
data: myData
});Manage runtime state stored in the message.
// Get state
const counter = await speraxOS.getPluginState<number>('counter');
// Set state
await speraxOS.setPluginState('counter', counter + 1);Manage plugin configuration stored in the host application.
// Get all settings
const settings = await speraxOS.getPluginSettings<MySettings>();
// Update settings (partial update)
await speraxOS.setPluginSettings({ theme: 'dark' });Trigger the AI to generate a response (for standalone plugins).
await speraxOS.triggerAIMessage(messageId);Create a new assistant message programmatically (for standalone plugins).
await speraxOS.createAssistantMessage('Here is the analysis...');This is a React Hook encapsulating the Chat Plugin SDK, used to listen for plugin messages sent from SperaxOS.
Syntax:
const { data, loading } = useWatchPluginMessage<T>();Return Value:
| Property | Type | Description |
|---|---|---|
data |
T |
Data of the message sent by the plugin |
loading |
boolean |
Indicates whether the data is currently being loaded |
Example:
import { useWatchPluginMessage } from '@sperax/plugin-sdk/client';
const MyPlugin = () => {
const { data, loading } = useWatchPluginMessage<MyDataType>();
if (loading) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Plugin Message Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default MyPlugin;Notes:
- Please ensure that
useWatchPluginMessageis used within a React functional component. - The hook automatically handles postMessage communication with the host.
- Use with
swrorreact-queryfor data caching and automatic updates.
Used to listen for the initialization of standalone type plugins. This hook is only executed once when the component is mounted.
Syntax:
useOnStandalonePluginInit<T>(callback: (payload: PluginPayload<T>) => void): void;Parameters:
| Parameter | Type | Description |
|---|---|---|
callback |
(payload: PluginPayload<T>) => void |
Callback function invoked when the plugin initialization event is triggered |
Payload Type:
interface PluginPayload<T = any> {
arguments?: T; // Plugin initialization parameters
name: string; // Plugin initialization function name
settings?: Record<string, any>;
state?: Record<string, any>;
}Example:
import { useOnStandalonePluginInit } from '@sperax/plugin-sdk/client';
const StandalonePlugin = () => {
useOnStandalonePluginInit((payload) => {
console.log('Plugin initialization triggered');
console.log('Function name:', payload.name);
console.log('Arguments:', payload.arguments);
console.log('Settings:', payload.settings);
});
return <div>Listening for plugin initialization</div>;
};
export default StandalonePlugin;Notes:
- Please ensure it is used within a React functional component.
- Will only be executed once when the component is mounted.
- In the callback function, you can process the payload, such as obtaining initialization parameters or calling initialization functions.
Used to retrieve and update the running state of the plugin. The state is persisted across re-renders.
Syntax:
const [value, updateValue] = usePluginState<T>(key: string, initialValue: T);Parameters:
| Parameter | Type | Description |
|---|---|---|
key |
string |
Unique identifier for the state |
initialValue |
T |
Initial value of the state |
Return Value:
| Property | Type | Description |
|---|---|---|
value |
T |
Current value of the state |
updateValue |
(value: T) => void |
Function to update the state |
Example:
import { usePluginState } from '@sperax/plugin-sdk/client';
const Counter = () => {
const [count, setCount] = usePluginState('count', 0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<h1>Current Count: {count}</h1>
<button onClick={increment}>Increment</button>
</div>
);
};
export default Counter;Notes:
- Ensure usage within a React function component.
- The
keyparameter must be a string used to uniquely identify the plugin state. - The
initialValueparameter is the initial value of the state. - State is automatically synchronized with SperaxOS.
Used to retrieve and update plugin settings with automatic synchronization.
Syntax:
const [value, updateValue] = usePluginSettings<T>(initialValue: T);Parameters:
| Parameter | Type | Description |
|---|---|---|
initialValue |
T |
Initial value of plugin settings |
Return Value:
Returns an array containing two elements: the current plugin settings value and the function to update plugin settings.
Example:
import { usePluginSettings } from '@sperax/plugin-sdk/client';
const SettingsPanel = () => {
const [settings, updateSettings] = usePluginSettings({
theme: 'light',
fontSize: 14
});
const handleThemeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
updateSettings({ theme: e.target.value });
};
return (
<div>
<h1>Plugin Settings:</h1>
<select value={settings.theme} onChange={handleThemeChange}>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
);
};
export default SettingsPanel;Notes:
- Please ensure to use
usePluginSettingsinside a React function component. - Initial value
initialValuecan be of any type. - When updating plugin settings, the SDK automatically sends update messages to SperaxOS via
postMessage.
A utility function for fetching plugin message data. Useful in useEffect or non-hook contexts.
Syntax:
const data = await fetchPluginMessage<T>();Example:
import { fetchPluginMessage } from '@sperax/plugin-sdk/client';
import { memo, useEffect, useState } from 'react';
interface ResponseData {
items: string[];
timestamp: number;
}
const PluginDisplay = memo(() => {
const [data, setData] = useState<ResponseData>();
useEffect(() => {
// Get the current message of the plugin from SperaxOS
fetchPluginMessage<ResponseData>().then((response) => {
setData(response);
});
}, []);
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>Plugin Data</h1>
<ul>
{data.items.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
</div>
);
});
export default PluginDisplay;Notes:
- The
fetchPluginMessagemethod is a regular asynchronous request method. - Can be used with
swrorreact-queryto implement data caching and automatic updates for a better user experience.
The SDK provides Zod schemas for validating plugin configurations.
Validate plugin manifest files.
import { pluginManifestSchema } from '@sperax/plugin-sdk';
const manifest = {
identifier: 'my-plugin',
api: [{
url: 'https://api.example.com/endpoint',
name: 'myFunction',
description: 'Does something useful',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' }
},
required: ['query']
}
}],
ui: {
url: 'https://plugin.example.com',
height: 400
}
};
const result = pluginManifestSchema.parse(manifest);Validate plugin metadata for the index.
import { pluginMetaSchema } from '@sperax/plugin-sdk';
const meta = {
author: 'MyCompany',
createdAt: '2024-01-01',
homepage: 'https://example.com',
identifier: 'my-plugin',
manifest: 'https://plugin.example.com/manifest.json',
meta: {
avatar: '🔌',
tags: ['utility', 'search'],
title: 'My Plugin',
description: 'A useful plugin'
}
};
const result = pluginMetaSchema.parse(meta);Validate individual API definitions.
import { pluginApiSchema } from '@sperax/plugin-sdk';
const api = {
url: 'https://api.example.com/search',
name: 'search',
description: 'Search for items',
parameters: {
type: 'object',
properties: {
query: { type: 'string' }
}
}
};
const result = pluginApiSchema.parse(api);Use PluginErrorType for standardized error responses.
import { PluginErrorType, createErrorResponse } from '@sperax/plugin-sdk';
export default async (req: Request) => {
// Method validation
if (req.method !== 'POST') {
return createErrorResponse(PluginErrorType.MethodNotAllowed);
}
// Settings validation
const settings = getPluginSettingsFromRequest(req);
if (!settings?.apiKey) {
return createErrorResponse(PluginErrorType.PluginSettingsInvalid, {
message: 'API key is required'
});
}
// Your logic here...
};| Error Type | Description |
|---|---|
PluginMarketIndexNotFound |
Plugin market index parse failed |
PluginMarketIndexInvalid |
Invalid plugin market index |
PluginMetaNotFound |
No plugin metadata found |
PluginMetaInvalid |
Invalid plugin metadata |
PluginManifestNotFound |
Plugin manifest file does not exist |
PluginManifestInvalid |
Invalid plugin manifest format |
PluginSettingsInvalid |
Invalid plugin settings |
PluginApiNotFound |
Plugin API does not exist |
PluginApiParamsError |
Plugin API parameter error |
PluginServerError |
Plugin server error |
| Error Type | HTTP Status | Description |
|---|---|---|
BadRequest |
400 | Bad request |
Unauthorized |
401 | Unauthorized |
Forbidden |
403 | Forbidden |
ContentNotFound |
404 | Not found |
MethodNotAllowed |
405 | Method not allowed |
TooManyRequests |
429 | Too many requests |
| Error Type | HTTP Status | Description |
|---|---|---|
InternalServerError |
500 | Internal server error |
BadGateway |
502 | Bad gateway |
ServiceUnavailable |
503 | Service unavailable |
GatewayTimeout |
504 | Gateway timeout |
Extract plugin settings from the request headers.
import { getPluginSettingsFromRequest } from '@sperax/plugin-sdk';
interface MySettings {
apiKey: string;
endpoint?: string;
}
export default async (req: Request) => {
const settings = getPluginSettingsFromRequest<MySettings>(req);
if (!settings?.apiKey) {
return createErrorResponse(PluginErrorType.PluginSettingsInvalid);
}
// Use settings.apiKey for API calls
};Create headers with plugin settings (useful for testing).
import { createHeadersWithPluginSettings } from '@sperax/plugin-sdk';
const headers = createHeadersWithPluginSettings({ apiKey: 'test-key' });
const req = new Request('https://api.example.com', { headers });For advanced use cases, you can use the low-level PluginChannel constants.
import { PluginChannel } from '@sperax/plugin-sdk';| Channel | Literal | Description |
|---|---|---|
pluginReadyForRender |
speraxos:plugin-ready-for-render |
Plugin is ready for rendering |
initStandalonePlugin |
speraxos:init-standalone-plugin |
Initialize standalone plugin |
| Channel | Literal | Description |
|---|---|---|
fetchPluginMessage |
speraxos:fetch-plugin-message |
Request message content |
renderPlugin |
speraxos:render-plugin |
Render plugin instruction |
fillStandalonePluginContent |
speraxos:fill-plugin-content |
Fill standalone plugin content |
| Channel | Literal | Description |
|---|---|---|
fetchPluginState |
speraxos:fetch-plugin-state |
Request plugin state |
renderPluginState |
speraxos:render-plugin-state |
Render plugin state |
updatePluginState |
speraxos:update-plugin-state |
Update plugin state |
| Channel | Literal | Description |
|---|---|---|
fetchPluginSettings |
speraxos:fetch-plugin-settings |
Request plugin settings |
renderPluginSettings |
speraxos:render-plugin-settings |
Render plugin settings |
updatePluginSettings |
speraxos:update-plugin-settings |
Update plugin settings |
The SDK is fully typed. Import types as needed:
import type {
PluginManifest,
PluginMeta,
PluginApi,
PluginPayload,
PluginErrorType,
} from '@sperax/plugin-sdk';- Plugin Manifest Reference - Complete manifest schema
- Plugin Types Guide - Choose the right plugin type
- Quick Start - Build your first plugin