SDK API
API reference for TrikHub TypeScript and Python packages.
TrikHub provides packages for both TypeScript and Python:
@trikhub/sdk— For building triks (trik authors)@trikhub/gateway— For loading and running triks (host app developers)
@trikhub/sdk (Building Triks)
The SDK provides utilities for wrapping LangGraph agents and tool handlers into the TrikAgent interface.
Installation
npm install @trikhub/sdkwrapAgent
Wrap a LangGraph agent (or factory) into a TrikAgent for conversational triks. Handles message history, tool call extraction, and transfer-back detection.
import { wrapAgent } from '@trikhub/sdk';
function wrapAgent(
agentOrFactory: InvokableAgent | AgentFactory,
options?: WrapAgentOptions
): TrikAgentPattern 1: Pre-built agent
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { wrapAgent, transferBackTool } from '@trikhub/sdk';
const agent = createReactAgent({
llm: model,
tools: [...myTools, transferBackTool],
});
export default wrapAgent(agent);Pattern 2: Factory (when you need config at runtime)
import { wrapAgent, transferBackTool } from '@trikhub/sdk';
export default wrapAgent(async (context) => {
const apiKey = context.config.get('ANTHROPIC_API_KEY');
const llm = new ChatAnthropic({ apiKey });
return createReactAgent({ llm, tools: [...myTools, transferBackTool] });
});wrapToolHandlers
Wrap a map of tool handler functions into a TrikAgent for tool-mode triks. Each handler receives validated input and returns structured output.
import { wrapToolHandlers } from '@trikhub/sdk';
function wrapToolHandlers(
handlers: Record<string, ToolHandler>
): TrikAgentExample:
import { wrapToolHandlers } from '@trikhub/sdk';
export default wrapToolHandlers({
getWeather: async (input, context) => {
const { city } = input as { city: string };
const apiKey = context.config.get('WEATHER_API_KEY');
// ... call weather API ...
return { temperature: 22, unit: 'celsius', condition: 'sunny' };
},
});ToolHandler type:
type ToolHandler = (
input: Record<string, unknown>,
context: TrikContext,
) => Promise<Record<string, unknown>> | Record<string, unknown>;transferBackTool
A LangChain tool that signals a transfer back to the main agent. Include this in your conversational agent’s tool set so the LLM can decide when to hand back control.
import { transferBackTool } from '@trikhub/sdk';
const agent = createReactAgent({
llm: model,
tools: [...myTools, transferBackTool],
});The tool accepts an optional reason parameter:
// The LLM calls this when the user's request is outside the trik's domain
transfer_back({ reason: "User is asking about weather, not articles" })Types
TrikAgent
The contract a trik must implement. Conversational triks use processMessage(), tool-mode triks use executeTool().
interface TrikAgent {
processMessage?(message: string, context: TrikContext): Promise<TrikResponse>;
executeTool?(toolName: string, input: Record<string, unknown>, context: TrikContext): Promise<ToolExecutionResult>;
}TrikContext
Context passed to a trik on each message or tool execution.
interface TrikContext {
sessionId: string;
config: TrikConfigContext;
storage: TrikStorageContext;
}TrikConfigContext
Access to user-configured values (API keys, tokens).
interface TrikConfigContext {
get(key: string): string | undefined;
has(key: string): boolean;
keys(): string[];
}TrikStorageContext
Persistent key-value storage scoped to the trik.
interface TrikStorageContext {
get(key: string): Promise<unknown | null>;
set(key: string, value: unknown, ttl?: number): Promise<void>;
delete(key: string): Promise<boolean>;
list(prefix?: string): Promise<string[]>;
getMany(keys: string[]): Promise<Map<string, unknown>>;
setMany(entries: Record<string, unknown>): Promise<void>;
}TrikResponse
Response from a conversational trik after processing a message.
interface TrikResponse {
message: string;
transferBack: boolean;
toolCalls?: ToolCallRecord[];
}ToolExecutionResult
Result from executing a tool-mode trik tool.
interface ToolExecutionResult {
output: Record<string, unknown>;
}ToolCallRecord
Record of a tool call made during message processing.
interface ToolCallRecord {
tool: string;
input: Record<string, unknown>;
output: Record<string, unknown>;
}InvokableAgent
Any agent with a LangGraph-compatible invoke method.
interface InvokableAgent {
invoke(
input: { messages: BaseMessage[] },
config?: unknown
): Promise<{ messages: BaseMessage[] }>;
}AgentFactory
Factory function that creates an agent from TrikContext. Use when your agent needs config values (API keys) at creation time.
type AgentFactory = (
context: TrikContext
) => InvokableAgent | Promise<InvokableAgent>;Type Re-exports
The SDK re-exports these types from @trikhub/manifest for convenience:
export type {
TrikAgent,
TrikContext,
TrikResponse,
TrikConfigContext,
TrikStorageContext,
ToolCallRecord,
ToolExecutionResult,
};@trikhub/gateway (Using Triks)
The gateway loads triks, routes messages, manages handoff sessions, and exposes tool-mode tools.
Installation
npm install @trikhub/gatewayTrikGateway
Main class for loading and running triks.
Constructor
import { TrikGateway } from '@trikhub/gateway';
const gateway = new TrikGateway(config?: TrikGatewayConfig);TrikGatewayConfig:
interface TrikGatewayConfig {
allowedTriks?: string[];
triksDirectory?: string;
configStore?: ConfigStore;
storageProvider?: StorageProvider;
sessionStorage?: SessionStorage;
validateConfig?: boolean;
pythonWorkerConfig?: PythonWorkerConfig;
maxTurnsPerHandoff?: number;
}| Field | Default | Description |
|---|---|---|
allowedTriks | undefined | Allowlist of trik IDs (all allowed if unset) |
triksDirectory | undefined | Directory for auto-discovery (~ supported) |
configStore | FileConfigStore | Config store for trik secrets |
storageProvider | SqliteStorageProvider | Storage provider for persistent data |
sessionStorage | InMemorySessionStorage | Session storage for handoff sessions |
validateConfig | true | Validate required config values on load |
maxTurnsPerHandoff | 20 | Max turns per handoff before auto-transfer-back |
initialize
Initialize the gateway by loading configuration. Must be called before loading triks.
await gateway.initialize();loadTriksFromConfig
Load triks from .trikhub/config.json.
async loadTriksFromConfig(options?: LoadFromConfigOptions): Promise<TrikManifest[]>Options:
interface LoadFromConfigOptions {
configPath?: string; // Default: '.trikhub/config.json' in cwd
baseDir?: string; // Default: directory of config file
}Example:
const gateway = new TrikGateway();
await gateway.initialize();
const manifests = await gateway.loadTriksFromConfig();
console.log(`Loaded ${manifests.length} triks`);loadTrik
Load a single trik from a directory path.
async loadTrik(path: string): Promise<TrikManifest>Example:
const manifest = await gateway.loadTrik('./my-trik');routeMessage
Route a user message through the gateway. This is the core routing method.
- If no active handoff: returns
RouteToMainwith handoff tool definitions - If active handoff and message is
/back: forces transfer-back - If active handoff: routes to the trik, handles transfer-back and max turns
async routeMessage(message: string, sessionId: string): Promise<RouteResult>Example:
const result = await gateway.routeMessage('Find me AI articles', 'session-1');
switch (result.target) {
case 'main':
// No active handoff — send to main agent with these handoff tools
console.log('Handoff tools:', result.handoffTools);
break;
case 'trik':
// Active handoff — trik responded
console.log('Trik response:', result.response.message);
break;
case 'transfer_back':
// Trik signaled transfer-back
console.log('Message:', result.message);
console.log('Summary:', result.summary);
break;
case 'force_back':
// User sent /back
console.log('Summary:', result.summary);
break;
}getHandoffTools
Get handoff tool definitions for conversational triks. One tool per loaded conversational trik, named talk_to_<trikId>.
getHandoffTools(): HandoffToolDefinition[]HandoffToolDefinition:
interface HandoffToolDefinition {
name: string; // e.g., "talk_to_article-curator"
description: string; // from agent.handoffDescription
inputSchema: JSONSchema;
}getExposedTools
Get exposed tool definitions from tool-mode triks. These appear as native tools on the main agent.
getExposedTools(): ExposedToolDefinition[]ExposedToolDefinition:
interface ExposedToolDefinition {
trikId: string;
toolName: string;
description: string;
inputSchema: JSONSchema;
outputSchema: JSONSchema;
outputTemplate: string;
}executeExposedTool
Execute an exposed tool from a tool-mode trik. Validates input and output against manifest schemas, strips undeclared properties, and fills the output template.
async executeExposedTool(
trikId: string,
toolName: string,
input: Record<string, unknown>
): Promise<string> // Returns the filled outputTemplate stringExample:
const result = await gateway.executeExposedTool(
'weather-tools',
'getWeather',
{ city: 'London' }
);
// result: "Current weather: 18 celsius, cloudy"getActiveHandoff
Get the current active handoff state, if any.
getActiveHandoff(): { trikId: string; sessionId: string; turnCount: number } | nullQuery Methods
// Get a loaded trik's manifest
getManifest(trikId: string): TrikManifest | undefined
// List all loaded trik IDs
getLoadedTriks(): string[]
// Check if a trik is loaded
isLoaded(trikId: string): boolean
// Unload a trik from memory
unloadTrik(trikId: string): boolean
// Shutdown Python worker if running
async shutdown(): Promise<void>Route Result Types
type RouteResult = RouteToMain | RouteToTrik | RouteTransferBack | RouteForceBack;RouteToMain
No active handoff. Caller should send the message to the main agent with these handoff tools.
interface RouteToMain {
target: 'main';
handoffTools: HandoffToolDefinition[];
}RouteToTrik
Active handoff. The gateway routed the message to the trik and got a response.
interface RouteToTrik {
target: 'trik';
trikId: string;
response: TrikResponse;
sessionId: string;
}RouteTransferBack
The trik signaled transfer-back. The message is shown to the user and the summary is injected into the main agent’s history.
interface RouteTransferBack {
target: 'transfer_back';
trikId: string;
message: string; // Trik's response, shown to user
summary: string; // Session log, injected into main history
sessionId: string;
}RouteForceBack
The user sent /back. Summary is injected into the main agent’s history.
interface RouteForceBack {
target: 'force_back';
trikId: string;
message: string; // Empty string
summary: string; // Session log, injected into main history
sessionId: string;
}Session Types
HandoffSession
A handoff session tracks a conversation with a trik agent.
interface HandoffSession {
sessionId: string;
trikId: string;
log: HandoffLogEntry[];
createdAt: number;
lastActivityAt: number;
}HandoffLogEntry
A single log entry in a handoff session.
interface HandoffLogEntry {
timestamp: number;
type: 'handoff_start' | 'tool_execution' | 'handoff_end';
summary: string;
}LangChain Adapter
Import from @trikhub/gateway/langchain. The adapter wraps a LangGraph agent with handoff routing to triks.
enhance
The primary integration point. Wraps a LangGraph agent with full handoff routing.
import { enhance } from '@trikhub/gateway/langchain';
async function enhance(
agent: InvokableAgent | null,
options?: EnhanceOptions
): Promise<EnhancedAgent>Pass null as the first argument when using createAgent (recommended). Pass a pre-built agent for manual tool binding.
EnhanceOptions:
interface EnhanceOptions {
createAgent?: (trikTools: DynamicStructuredTool[]) => InvokableAgent;
gateway?: TrikGatewayConfig;
config?: LoadFromConfigOptions;
gatewayInstance?: TrikGateway;
debug?: boolean;
verbose?: boolean;
}| Option | Description |
|---|---|
createAgent | Factory that builds the agent with trik tools. Agent is rebuilt automatically when triks are installed or uninstalled at runtime. (Recommended) |
EnhancedAgent:
interface EnhancedAgent {
processMessage(message: string, sessionId?: string): Promise<EnhancedResponse>;
gateway: TrikGateway;
getLoadedTriks(): string[];
}EnhancedResponse:
interface EnhancedResponse {
message: string;
source: string; // "main", a trik ID, or "system"
}Example (recommended — createAgent factory):
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { enhance } from '@trikhub/gateway/langchain';
const app = await enhance(null, {
createAgent: (trikTools) =>
createReactAgent({ model, tools: [...myTools, ...trikTools] }),
gateway: { triksDirectory: '~/.trikhub/triks' },
debug: true,
});
const response = await app.processMessage('find me AI articles');
console.log(response.message); // What to show the user
console.log(response.source); // "main" or trik IDgetHandoffToolsForAgent
Convert gateway handoff tool definitions into LangChain DynamicStructuredTool instances. Use this for manual tool binding when you need direct access to trik tools.
Note: When using
createAgent, these functions are called internally. You only need them for advanced manual setups.
import { getHandoffToolsForAgent } from '@trikhub/gateway/langchain';
function getHandoffToolsForAgent(gateway: TrikGateway): DynamicStructuredTool[]getExposedToolsForAgent
Convert exposed tool definitions from tool-mode triks into LangChain DynamicStructuredTool instances. These tools call gateway.executeExposedTool() under the hood.
import { getExposedToolsForAgent } from '@trikhub/gateway/langchain';
function getExposedToolsForAgent(gateway: TrikGateway): DynamicStructuredTool[]Type Exports
From @trikhub/gateway
export {
TrikGateway,
type TrikGatewayConfig,
type TrikHubConfig,
type LoadFromConfigOptions,
type RouteResult,
type RouteToMain,
type RouteToTrik,
type RouteTransferBack,
type RouteForceBack,
type HandoffToolDefinition,
type ExposedToolDefinition,
};From @trikhub/sdk
export {
wrapAgent,
wrapToolHandlers,
transferBackTool,
TRANSFER_BACK_TOOL_NAME,
extractToolInfo,
type InvokableAgent,
type AgentFactory,
type WrapAgentOptions,
type ToolHandler,
type ExtractedToolInfo,
type TrikAgent,
type TrikContext,
type TrikResponse,
type TrikConfigContext,
type TrikStorageContext,
type ToolCallRecord,
type ToolExecutionResult,
};From @trikhub/manifest
Re-exported by both packages for convenience:
export type {
TrikManifest,
TrikAgent,
TrikContext,
TrikResponse,
ToolCallRecord,
ToolExecutionResult,
JSONSchema,
SessionCapabilities,
StorageCapabilities,
ConfigRequirement,
TrikConfig,
TrikConfigContext,
TrikStorageContext,
HandoffLogEntry,
HandoffSession,
};