UNPKG

@optimizely-opal/opal-tools-sdk

Version:

SDK for creating Opal-compatible tools services

273 lines (219 loc) 7.37 kB
# Opal Tools SDK for TypeScript This SDK simplifies the creation of tools services compatible with the Opal Tools Management Service. ## Features - Easy definition of tool functions with decorators - Automatic generation of discovery endpoints - Parameter validation and type checking - Authentication helpers - Express integration - Island components for interactive UI responses ## Installation ```bash npm install @optimizely-opal/opal-tools-sdk ``` ## Usage ```typescript import { ToolsService, tool, IslandResponse, IslandConfig } from '@optimizely-opal/opal-tools-sdk'; import express from 'express'; const app = express(); const toolsService = new ToolsService(app); interface WeatherParameters { location: string; units: string; } @tool({ name: 'get_weather', description: 'Gets current weather for a location' }) async function getWeather(parameters: WeatherParameters) { // Implementation... return { temperature: 22, condition: 'sunny' }; } // Discovery endpoint is automatically created at /discovery ``` ## Authentication The SDK provides two ways to require authentication for your tools: ### 1. Using the `@requiresAuth` decorator ```typescript import { ToolsService, tool } from '@optimizely-opal/opal-tools-sdk'; import { requiresAuth } from '@optimizely-opal/opal-tools-sdk/auth'; import express from 'express'; const app = express(); const toolsService = new ToolsService(app); interface CalendarParameters { date: string; timezone?: string; } // Single authentication requirement @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true }) @tool({ name: 'get_calendar_events', description: 'Gets calendar events for a date' }) async function getCalendarEvents(parameters: CalendarParameters, authData?: any) { // The authData parameter contains authentication information const token = authData?.credentials?.token || ''; // Use the token to make authenticated requests // ... return { events: ['Meeting at 10:00', 'Lunch at 12:00'] }; } // Multiple authentication requirements (tool can work with either provider) @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true }) @requiresAuth({ provider: 'microsoft', scopeBundle: 'outlook', required: true }) @tool({ name: 'get_calendar_availability', description: 'Check calendar availability' }) async function getCalendarAvailability(parameters: CalendarParameters, authData?: any) { const provider = authData?.provider || ''; const token = authData?.credentials?.token || ''; if (provider === 'google') { // Use Google Calendar API } else if (provider === 'microsoft') { // Use Microsoft Outlook API } return { available: true, provider_used: provider }; } ``` ### 2. Specifying auth requirements in the `@tool` decorator ```typescript interface EmailParameters { limit?: number; folder?: string; } @tool({ name: 'get_email', description: 'Gets emails from the user\'s inbox', authRequirements: { provider: 'google', scopeBundle: 'gmail', required: true } }) async function getEmail(parameters: EmailParameters, authData?: any) { // Implementation... return { emails: ['Email 1', 'Email 2'] }; } ``` ## Authentication The SDK provides authentication support for tools that require user credentials: ```typescript import { ToolsService, tool, requiresAuth, AuthData } from '@optimizely-opal/opal-tools-sdk'; import express from 'express'; interface CalendarParameters { date: string; timezone?: string; } const app = express(); const toolsService = new ToolsService(app); @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true }) @tool({ name: 'get_calendar_events', description: 'Gets calendar events for a date' }) async function getCalendarEvents(parameters: CalendarParameters, authData?: AuthData) { // The authData parameter contains authentication information if (authData) { const token = authData.credentials.access_token; // Use the token to make authenticated requests } return { events: ['Meeting at 10:00', 'Lunch at 12:00'] }; } ``` ## Island Components The SDK includes Island components for creating interactive UI responses: ```typescript import { ToolsService, tool, IslandResponse, IslandConfig } from '@optimizely-opal/opal-tools-sdk'; import express from 'express'; interface WeatherParameters { location: string; units?: string; } const app = express(); const toolsService = new ToolsService(app); @tool({ name: 'get_weather', description: 'Gets current weather for a location' }) async function getWeather(parameters: WeatherParameters) { // Get weather data (implementation details omitted) const weatherData = { temperature: 22, condition: 'sunny', humidity: 65 }; // Create an interactive island for weather settings const island = new IslandConfig( [ new IslandConfig.Field( 'location', 'Location', 'string', parameters.location ), new IslandConfig.Field( 'units', 'Temperature Units', 'string', parameters.units || 'metric', false, ['metric', 'imperial', 'kelvin'] ), new IslandConfig.Field( 'current_temp', 'Current Temperature', 'string', `${weatherData.temperature}°${parameters.units === 'metric' ? 'C' : 'F'}` ) ], [ new IslandConfig.Action( 'refresh_weather', 'Refresh Weather', 'button', '/tools/get_weather', 'update' ) ] ); return IslandResponse.create([island]); } ``` ### Island Components #### IslandConfig.Field Fields represent data inputs in the UI: - `name`: Programmatic field identifier - `label`: Human-readable label - `type`: Field type (`'string'`, `'boolean'`, `'json'`) - `value`: Current field value (optional) - `hidden`: Whether to hide from user (optional, default: false) - `options`: Available options for selection (optional) #### IslandConfig.Action Actions represent buttons or operations: - `name`: Programmatic action identifier - `label`: Human-readable button label - `type`: UI element type (typically `'button'`) - `endpoint`: API endpoint to call - `operation`: Operation type (default: `'create'`) #### IslandConfig Contains the complete island configuration: - `fields`: Array of IslandConfig.Field objects - `actions`: Array of IslandConfig.Action objects #### IslandResponse The response wrapper for islands: - Use `IslandResponse.create([islands])` to create responses - Supports multiple islands per response ## Type Definitions The SDK provides comprehensive TypeScript type definitions: ### Authentication Types - `AuthData`: Interface containing provider and credentials information - `Credentials`: Interface with access_token, org_sso_id, customer_id, instance_id, and product_sku - `Environment`: Interface specifying execution mode (`'headless'` or `'interactive'`) ### Parameter Types - `ParameterType`: Enum for supported parameter types - `Parameter`: Class for tool parameter definitions - `Function`: Class for complete tool function definitions These types provide full IDE support and compile-time type checking for better development experience. ## Documentation See full documentation for more examples and configuration options.