npm package: @preclinical/sdk
Description: TypeScript SDK for the Preclinical healthcare AI safety testing platform
Author: Preclinical AI
Latest version: 0.2.2

# Preclinical TypeScript SDK

TypeScript SDK for the [Preclinical](https://preclinical.co) healthcare AI safety testing platform.

## Installation

```bash
npm install @preclinical/sdk
```

## Quick Start

```typescript
import { Preclinical } from '@preclinical/sdk';

const client = new Preclinical({ apiKey: 'sk_live_...' });

// Start a test and wait for completion
const test = await client.tests.runAndWait({
  agent_id: 'your-agent-id',
  test_mode: 'demo',
});

console.log(`Status: ${test.status}`);
console.log(`Pass rate: ${test.pass_rate}%`);

// Get detailed results
const results = await client.tests.results(test.id);
for (const r of results.data) {
  const status = r.passed ? 'PASS' : 'FAIL';
  console.log(`[${status}] ${r.scenario_name}`);
}
```

## Usage

### Initialize the Client

```typescript
import { Preclinical } from '@preclinical/sdk';

const client = new Preclinical({
  apiKey: 'sk_live_...',
  baseUrl: 'https://app.preclinical.dev', // optional, defaults to production
});
```

### Agents

```typescript
// List all agents
const agents = await client.agents.list();

// Create an agent
const agent = await client.agents.create({
  name: 'My Agent',
  provider: 'openai',
  config: {
    api_key: 'sk-...',
    base_url: 'https://api.openai.com/v1',
    target_model: 'gpt-4o',
  },
});

// Get an agent
const fetched = await client.agents.get(agent.id);

// Update an agent
const updated = await client.agents.update(agent.id, { name: 'Renamed Agent' });

// Validate agent configuration
const validation = await client.agents.validate(agent.id);

// Delete an agent
await client.agents.delete(agent.id);
```

### Tests

```typescript
// Create a test
const created = await client.tests.create({
  agent_id: agent.id,
  test_mode: 'demo', // 'demo' or 'full'
  max_turns: 6,
});

// Get test status
const test = await client.tests.get(created.id);

// List tests with pagination
const tests = await client.tests.list({ limit: 10, offset: 0, status: 'completed' });

// Get test results (scenario-level summaries)
const results = await client.tests.results(test.id);

// Cancel a running test
await client.tests.cancel(test.id);

// Run and wait for completion with progress callback
const completed = await client.tests.runAndWait(
  { agent_id: agent.id, test_mode: 'demo' },
  {
    intervalMs: 10_000,
    timeoutMs: 30 * 60 * 1000,
    onProgress: (t) => console.log(`Status: ${t.status}`),
  }
);
```

### Scenario Runs

Access individual scenario run details including full conversation transcripts.

```typescript
// List scenario runs for a test
const runs = await client.scenarioRuns.list(test.id, { limit: 10 });

// Get a single scenario run with transcript
const run = await client.scenarioRuns.get(runs.data[0].id);
console.log(`Passed: ${run.passed}`);
console.log(`Grade: ${run.grade_summary}`);

// Print the conversation transcript
for (const entry of run.transcript) {
  console.log(`[${entry.role}]: ${entry.content}`);
}
```

### Scenarios

```typescript
// List available scenarios
const scenarios = await client.scenarios.list({ limit: 50 });

// Get a specific scenario
const scenario = await client.scenarios.get(scenarios.data[0].id);
```

### Webhooks

```typescript
// List webhooks
const webhooks = await client.webhooks.list();

// Create a webhook
const webhook = await client.webhooks.create({
  url: 'https://example.com/webhook',
  description: 'Test completion notifications',
  secret: 'whsec_...',
});

// Get a webhook
const fetched = await client.webhooks.get(webhook.id);

// Update a webhook
await client.webhooks.update(webhook.id, { is_enabled: false });

// Test a webhook
const testResult = await client.webhooks.test(webhook.id);

// Get delivery history
const deliveries = await client.webhooks.deliveries(webhook.id);

// Delete a webhook
await client.webhooks.delete(webhook.id);
```

## Error Handling

```typescript
import { Preclinical, PreclinicalError } from '@preclinical/sdk';

const client = new Preclinical({ apiKey: 'sk_live_...' });

try {
  const test = await client.tests.get('nonexistent-id');
} catch (err) {
  if (err instanceof PreclinicalError) {
    console.error(`API error: ${err.message} (status: ${err.status}, code: ${err.code})`);
  }
}
```

## Types

All types are exported from the package:

```typescript
import type {
  Agent,
  CreateAgentParams,
  UpdateAgentParams,
  ValidationResult,
  TestRun,
  TestRunCreated,
  CreateTestParams,
  ScenarioResult,
  ScenarioRun,
  Scenario,
  Webhook,
  CreateWebhookParams,
  UpdateWebhookParams,
  WebhookTestResult,
  WebhookDelivery,
  ListParams,
  PaginatedResponse,
  PollOptions,
  PreclinicalConfig,
} from '@preclinical/sdk';
```

## Documentation

Full API docs at [docs.preclinical.co](https://docs.preclinical.co)