npm package: @ofuma/sdk
Description: TypeScript SDK for Ofuma API - Manage prompts, versions, and AI interactions
Author: Ofuma Engineering
Latest version: 0.1.4

# @ofuma/sdk

TypeScript SDK for the Ofuma API with full type safety and IntelliSense support.

## Code Structure

```
sdk/
├── src/
│   ├── resources/           # API resource implementations
│   │   ├── prompts/         # Prompts API resource
│   │   │   ├── index.ts     # PromptsResource class implementation
│   │   │   └── types.ts     # Prompt-related type definitions and re-exports
│   │   └── chains/          # Chains API resource
│   │       ├── index.ts     # ChainsResource class implementation
│   │       └── types.ts     # Chain-related type definitions and re-exports
│   ├── client.ts            # BaseClient with HTTP handling and validation
│   ├── env.ts               # Environment variable validation (Zod-based)
│   ├── types.ts             # SDK configuration types and validation schemas
│   └── index.ts             # Main SDK export and public API
├── dist/                    # Built output (generated)
├── .eslintrc.js             # ESLint configuration
├── package.json             # Package configuration and dependencies
├── tsconfig.json            # TypeScript configuration
├── tsup.config.ts           # Build configuration
├── README.md                # User documentation
├── example.js               # Usage examples
└── CLAUDE.md               # Development guidance
```

### Recent Changes

- **Endpoint Constants**: All API endpoints now use shared constants from `@ofuma/shared`
  - Backend routes use `PROMPT_ROUTES` and `ROUTE_BASE_PATHS` constants
  - SDK uses `API_ENDPOINTS` constants for consistent URL management
  - Eliminates hardcoded URLs and ensures consistency across backend and SDK

### Architecture

The SDK is organized into distinct layers:

- **Main SDK Class**: `OfumaSDK` - Entry point that initializes all resources
- **Resource Classes**: Organized by API domain (e.g., `PromptsResource`)
- **Type Definitions**: Co-located with resources, re-exported from shared package
- **Base Client**: Handles HTTP communication, validation, and error handling
- **Validation Layer**: Type-safe environment and configuration validation
- **Endpoint Constants**: Shared constants from `@ofuma/shared` ensure URL consistency

## Installation

```bash
npm install @ofuma/sdk
# or
pnpm add @ofuma/sdk
# or
yarn add @ofuma/sdk
```

## Usage

### Setup

```typescript
import { OfumaSDK } from '@ofuma/sdk'

// Production environment (default)
const ofuma = new OfumaSDK({
  apiKey: 'your-api-key', // Required: API key for authentication
  organizationId: 'your-org-id' // Optional: Organization ID for scoped requests
})

// Staging environment
const ofumaStaging = new OfumaSDK({
  apiKey: 'your-api-key',
  env: 'staging' // or 'stg' - connects to staging
})

// Local development
const ofumaLocal = new OfumaSDK({
  apiKey: 'your-api-key',
  env: 'localhost' // or 'local' - connects to http://localhost:3004
})

// Custom URL (overrides all other settings)
const ofumaCustom = new OfumaSDK({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.custom-domain.com'
})
```

### Environment Configuration

The SDK determines the API base URL using the following priority order:

1. **Custom `baseUrl`** - If provided, overrides all other settings
2. **`env` parameter** - Specifies which environment to connect to
3. **Environment variable** - `OFUMA_API_URL` as fallback
4. **Default** - Production URL


### Environment Variables (Optional)

For backward compatibility, you can still use environment variables:

```bash
# Optional: Override the default URL
OFUMA_API_URL=https://api.ofuma.example.com
```

**Note**: Environment variables are now optional. The SDK will use the `env` parameter or default to production if not specified.

### Configuration Options

```typescript
interface SDKConfig {
  apiKey: string           // Required: API key for authentication
  organizationId?: string  // Optional: Organization ID for scoped requests
  env?: 'production' | 'prod' | 'staging' | 'stg' | 'localhost' | 'local'  // Optional: Environment (default: 'production')
  baseUrl?: string         // Optional: Custom API URL (overrides env)
  fetch?: typeof fetch     // Optional: Custom fetch implementation
}
```

## Prompts API

The SDK provides comprehensive support for all prompt operations:

### List Prompts

```typescript
const prompts = await ofuma.prompts.list()
console.log('Available prompts:', prompts)
```

### Create a Prompt

```typescript
const newPrompt = await ofuma.prompts.create({
  name: 'my-awesome-prompt',
  description: 'A prompt for generating awesome content'
})
```

### Get a Specific Prompt

```typescript
// Get latest version
const prompt = await ofuma.prompts.getById('prompt-id')

// Get specific version
const promptVersion = await ofuma.prompts.getById('prompt-id', {
  versionId: 5
})
```

### Update a Prompt

```typescript
const updatedPrompt = await ofuma.prompts.update('prompt-id', {
  content: 'Updated prompt content',
  environment: 'development',
  type: 'text',
  commitMessage: 'Updated prompt for better responses',
  model: 'gpt-4',
  provider: 'openai'
})
```

### Interpolate a Prompt

```typescript
const interpolated = await ofuma.prompts.interpolate('prompt-id', {
  version: 1,
  variables: {
    userName: 'John Doe',
    context: 'customer support'
  }
})

console.log('Interpolated prompt:', interpolated.interpolatedPrompt)
```

### Version Management

```typescript
// Set version environment
await ofuma.prompts.setVersionEnvironment({
  versionId: 'version-uuid',
  promptId: 'prompt-uuid',
  teamId: 'team-id',
  environment: 'production'
})

// Delete a version
await ofuma.prompts.deleteVersion({
  versionId: 'version-uuid',
  promptId: 'prompt-uuid'
})
```

### Label Management

```typescript
// Add labels to a version
await ofuma.prompts.addLabel('prompt-id', {
  label: ['feature', 'customer-facing'],
  versionId: 'version-uuid'
})

// Remove labels
await ofuma.prompts.removeLabel('prompt-id', {
  label: 'deprecated',
  versionId: 'version-uuid'
})
```

### Delete a Prompt

```typescript
await ofuma.prompts.delete({
  promptId: 'prompt-id'
})
```

## Chains API

The SDK provides support for chain operations:

### Get a Chain

```typescript
// Get a chain by ID
const chain = await ofuma.chains.get('chain-id')

console.log('Chain:', chain.name)
console.log('Nodes:', chain.nodes)
console.log('Dependencies:', chain.dependencies)
```

### Execute a Chain

```typescript
// Execute a chain with input data
const execution = await ofuma.chains.execute('chain-id', {
  input: {
    userName: 'John Doe',
    context: 'customer support'
  },
  metadata: {
    source: 'api',
    requestId: 'req-123'
  }
})

console.log('Execution ID:', execution.id)
console.log('Status:', execution.status)
console.log('Output:', execution.output)
```

## Error Handling

The SDK includes comprehensive error handling and validation:

### Initialization Errors

The SDK validates configuration at initialization:

```typescript
import { OfumaSDK } from '@ofuma/sdk'

try {
  const ofuma = new OfumaSDK({
    apiKey: '', // ❌ This will throw: "API key is required and cannot be empty"
  })
} catch (error) {
  console.error('SDK Initialization failed:', error.message)
}

// Invalid environment will also throw:
try {
  const ofuma = new OfumaSDK({
    apiKey: 'valid-key',
    env: 'invalid-env' // ❌ This will throw: validation error
  })
} catch (error) {
  console.error('Invalid environment:', error.message)
}
```

### API Errors

The SDK includes typed error responses for API calls:

```typescript
import { SDKError } from '@ofuma/sdk'

try {
  const prompt = await ofuma.prompts.getById('non-existent-id')
} catch (error) {
  if (error instanceof SDKError) {
    console.error(`API Error (${error.status}):`, error.message)
    console.error('Response:', error.response)
  } else {
    console.error('Unexpected error:', error)
  }
}
```

## Request Options

All methods accept optional request options for advanced usage:

```typescript
const prompts = await ofuma.prompts.list({
  signal: abortController.signal, // For request cancellation
  headers: {
    'Custom-Header': 'value'
  }
})
```

## TypeScript Support

The SDK is built with TypeScript and provides full type safety:

```typescript
import type {
  CreatePromptRequest,
  PromptResponse,
  InterpolatePromptRequest,
  InterpolatedPromptResponse,
  ChainResponse,
  ExecuteChainRequest,
  ChainExecutionResponse
} from '@ofuma/sdk'

// All request and response types are exported for your use
const createData: CreatePromptRequest = {
  name: 'typed-prompt',
  description: 'Fully typed prompt creation'
}

const prompt: PromptResponse = await ofuma.prompts.create(createData)

// Chain types
const chain: ChainResponse = await ofuma.chains.get('chain-id')

const executeData: ExecuteChainRequest = {
  chainId: 'chain-id',
  input: { key: 'value' }
}

const execution: ChainExecutionResponse = await ofuma.chains.execute('chain-id', executeData)
```

## Browser Support

The SDK works in both Node.js and browser environments. In browsers, it uses the native `fetch` API.

## Contributing

This SDK is part of the Ofuma monorepo. For development and contributions, see the main project documentation.

## License

MIT License - see the main project for details.