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/sdk

wrapAgent

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 ): TrikAgent

Pattern 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> ): TrikAgent

Example:

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/gateway

TrikGateway

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; }
FieldDefaultDescription
allowedTriksundefinedAllowlist of trik IDs (all allowed if unset)
triksDirectoryundefinedDirectory for auto-discovery (~ supported)
configStoreFileConfigStoreConfig store for trik secrets
storageProviderSqliteStorageProviderStorage provider for persistent data
sessionStorageInMemorySessionStorageSession storage for handoff sessions
validateConfigtrueValidate required config values on load
maxTurnsPerHandoff20Max 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 RouteToMain with 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 string

Example:

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 } | null

Query 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; }
OptionDescription
createAgentFactory 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 ID

getHandoffToolsForAgent

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, };