New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@shiplightai/sdk

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shiplightai/sdk

Shiplight SDK with pluggable custom actions

latest
Source
npmnpm
Version
0.1.11
Version published
Maintainers
1
Created
Source

@shiplightai/sdk

A companion SDK for Playwright that makes your tests resilient to UI changes like dynamic IDs, layout rearrangements, and styling updates.

Installation

npm install @shiplightai/sdk playwright

Quick Start

import { chromium } from 'playwright';
import { createAgent, configureSdk } from '@shiplightai/sdk';

// Configure SDK with API key (call once at startup)
configureSdk({
  env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});

// Create an agent
const agent = createAgent({
  model: 'claude-haiku-4-5',
});

// Use with Playwright
const browser = await chromium.launch();
const page = await browser.newPage();

// Login using the Sauce Labs demo site (public test site)
await agent.login(page, {
  url: 'https://www.saucedemo.com/',
  username: 'standard_user',
  password: 'secret_sauce',
});

// Verify login succeeded
await agent.assert(page, 'Products page is visible');

// Extract data from the page
await agent.extract(page, 'the first product name', 'productName');
console.log('First product:', agent.getVariable('productName'));

await browser.close();

Custom Actions

Extend the agent with custom actions for your specific use case:

import { createAgent, z } from '@shiplightai/sdk';

const agent = createAgent({ model: 'claude-haiku-4-5' });

// Register a custom action
agent.registerAction({
  name: 'extract_email_code',
  description: 'Extract verification code from email inbox',
  schema: z.object({
    email_address: z.string().describe('The email address to check'),
    code_type: z.enum(['verification', 'reset']).describe('Type of code'),
  }),
  async execute(args, ctx) {
    // Your custom logic here
    const code = await myEmailService.getCode(args.email_address, args.code_type);

    // Store the result for later use
    ctx.variableStore.set('verification_code', code);

    return { success: true, message: `Found code: ${code}` };
  },
});

// The agent will automatically use your action when needed
await agent.act(page, 'Get the verification code from email');
await agent.act(page, 'Enter {{ verification_code }} in the input field');

API Reference

createAgent(options)

Create a new agent instance.

const agent = createAgent({
  // Required: LLM model to use
  model: 'claude-haiku-4-5',

  // Optional: Initial variables
  variables: { username: 'test@example.com' },

  // Optional: Keys to mark as sensitive (masked in logs)
  sensitiveKeys: ['password', 'apiKey'],

  // Optional: Directory for test data files
  testDataDir: './test-data',

  // Optional: Directory for downloads
  downloadDir: './downloads',
});

Supported Models

The SDK supports any model from the following providers. Pass the model name directly or use provider:model syntax for explicit routing.

ProviderModel patternExample modelsAPI key
Googlegemini-*gemini-2.5-pro, gemini-2.5-flashGOOGLE_API_KEY
Anthropicclaude-*claude-haiku-4-5, claude-sonnet-4-6, claude-opus-4-6ANTHROPIC_API_KEY
OpenAIgpt-*, o1*, o3*, o4*, chatgpt-*gpt-4o, o4-miniOPENAI_API_KEY

Explicit provider routing — use provider:model to bypass auto-detection:

// Route through specific provider
const agent = createAgent({ model: 'openai:gpt-4o' });
const agent = createAgent({ model: 'anthropic:claude-sonnet-4-6' });

// Useful for fine-tuned models or cloud-hosted variants
const agent = createAgent({ model: 'openai:ft:gpt-4o:my-org' });

agent.registerAction(action)

Register a custom action.

agent.registerAction({
  // Unique action name (snake_case recommended)
  name: 'my_action',

  // Description for the agent
  description: 'What this action does and when to use it',

  // Zod schema for parameters
  schema: z.object({
    param1: z.string().describe('Description of the parameter'),
    param2: z.number().optional(),
  }),

  // Execute function
  async execute(args, ctx) {
    // args: validated parameters
    // ctx.page: Playwright page
    // ctx.variableStore: access to variables

    return { success: true, message: 'Optional status message' };
  },
});

agent.act(page, instruction)

Perform a single action on the page.

await agent.act(page, 'Click the login button');
await agent.act(page, 'Fill the email field with test@example.com');
await agent.act(page, 'Select "Express" from shipping dropdown');

agent.run(page, instruction, options?)

Run a multi-step instruction until the goal is achieved.

await agent.run(page, 'Complete the checkout process');
await agent.run(page, 'Fill out the entire registration form');
await agent.run(page, 'Add 3 items to cart', { maxSteps: 10 });

agent.assert(page, statement)

Assert a condition (throws on failure).

await agent.assert(page, 'Login button is visible');
await agent.assert(page, 'Cart contains 3 items');

agent.evaluate(page, statement)

Evaluate a condition (returns boolean, doesn't throw).

const isLoggedIn = await agent.evaluate(page, 'User is logged in');
if (!isLoggedIn) {
  await agent.run(page, 'Click the login button');
}

agent.extract(page, description, variableName)

Extract data from the page and store in a variable.

await agent.extract(page, 'the order total', 'orderTotal');
await agent.run(page, 'Verify {{ orderTotal }} is displayed on receipt');

agent.step(page, action, description, options?)

Wrap Playwright code with self-healing. If action throws, the agent analyzes the page and attempts to accomplish the goal described in description.

// Single action with self-healing
await agent.step(
  page,
  async () => await page.click('#submit-btn'),
  'Click the submit button'
);

// Code block with multiple actions
await agent.step(
  page,
  async () => {
    await page.fill('#email', 'user@example.com');
    await page.fill('#password', 'secret');
    await page.click('#login');
  },
  'Fill login form and submit'
);

// Control recovery depth with maxSteps (default: 5)
await agent.step(
  page,
  async () => await page.click('.dynamic-button'),
  'Click the dynamic button that appears after loading',
  { maxSteps: 3 }
);

agent.setVariable(name, value, sensitive?)

Set a variable. Variables can be referenced in instructions using $variableName.

agent.setVariable('couponCode', 'SAVE20');
await agent.act(page, 'Enter $couponCode in the promo field');

// Sensitive values are masked in logs
agent.setVariable('apiKey', 'secret123', true);

agent.getVariable(name)

Get a variable value.

await agent.extract(page, 'the order total', 'orderTotal');
console.log('Order total:', agent.getVariable('orderTotal'));

agent.waitUntil(page, condition, timeoutSeconds?)

Wait until a condition becomes true.

await agent.waitUntil(page, 'Loading spinner is no longer visible');

const appeared = await agent.waitUntil(page, 'Table shows at least 5 rows', 30);
if (!appeared) {
  throw new Error('Data did not load in time');
}

Custom Action Context

The execute function receives a context object:

interface IActionExecutionContext {
  // Playwright page instance
  page: Page;

  // Variable store for reading/writing variables
  variableStore: VariableStore;
}

Using Variables

async execute(args, ctx) {
  // Read a variable
  const email = ctx.variableStore.get('email');

  // Set a variable
  ctx.variableStore.set('result', 'some value');

  // Set a sensitive variable (masked in logs)
  ctx.variableStore.set('token', secretToken, true);

  return { success: true };
}

SDK Configuration

Configure SDK-wide settings before creating agents:

import { configureSdk, getSdkConfig, LogLevel } from '@shiplightai/sdk';

configureSdk({
  // Log level: DEBUG, INFO, WARN, ERROR
  logLevel: LogLevel.INFO,

  // Enable detailed agent logging
  debugAgent: false,

  // Environment variables (API keys — provide the key for your chosen model's provider)
  env: {
    GOOGLE_API_KEY: 'your-google-api-key',       // for gemini-* models
    // ANTHROPIC_API_KEY: 'your-anthropic-key',   // for claude-* models
    // OPENAI_API_KEY: 'sk-...',                  // for gpt-*, o1*, o3*, o4* models
  },

  // Optional: paths for logs and results
  agentLogPath: './logs/agent.log',
  testResultsJsonPath: './results.json',
});

// Read current config
const config = getSdkConfig();

API Keys

API keys must be passed via configureSdk({ env }) — the SDK does not read process.env directly.

KeyRequiredDescription
GOOGLE_API_KEYYes*Google AI API key for gemini-* models
ANTHROPIC_API_KEYYes*Anthropic API key for claude-* models
OPENAI_API_KEYYes*OpenAI API key for gpt-*, o1*, o3*, o4* models

*Provide the key for the provider matching your chosen model.

License

MIT

Keywords

playwright

FAQs

Package last updated on 08 Sep 2026

Related posts