npm package: @odin-ai/sdk
Description: TypeScript SDK for Odin AI - Chat, Workflows, Smart Tables, and Voice
Author: Odin AI
Latest version: 1.0.0

# Odin AI SDK

A TypeScript SDK for interacting with the Odin AI platform, including Chat, Smart Tables, Voice, and **Workflows**.

## Installation

```bash
npm install @odin-ai/sdk
```

## Available SDKs

| SDK | Description |
|-----|-------------|
| `ChatSDK` | Chat conversations with AI agents |
| `SmartTablesSDK` | Structured data tables with AI enrichment |
| `VoiceSDK` | Voice conversations with AI |
| **`WorkflowSDK`** | Execute and monitor workflows with real-time updates |

## Authentication

All SDKs support two authentication methods:

### 1. Access Token Authentication (Web App)

For web applications that already have user sessions:

```typescript
import { ChatSDK } from '@odin-ai/sdk';

const chatSDK = new ChatSDK({
  baseUrl: 'https://api.example.com/',
  projectId: 'your-project-id',
  accessToken: 'your-access-token', // From user session
});
```

### 2. API Key Authentication (External SDK)

For external applications and server-to-server communication:

```typescript
import { ChatSDK } from '@odin-ai/sdk';

const chatSDK = new ChatSDK({
  baseUrl: 'https://api.example.com/',
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret',
});
```

## Usage Examples

### Creating a Chat

```typescript
const chat = await chatSDK.createChat('My Chat', ['document-key-1']);
console.log('Created chat:', chat.chat_id);
```

### Sending a Message

```typescript
const response = await chatSDK.sendMessage('Hello!', {
  chatId: 'chat-id',
  agentType: 'chat_agent',
});
console.log('Response:', response);
```

### Streaming Messages

```typescript
await chatSDK.sendMessageStream('Tell me about...', {
  chatId: 'chat-id',
  onChunk: (chunk) => console.log('Chunk:', chunk),
  onComplete: (message) => console.log('Complete:', message),
  onError: (error) => console.error('Error:', error),
});
```

### Listing Chats

```typescript
const chats = await chatSDK.listChats();
console.log('Chats:', chats.chats);
```

### Deleting a Chat

```typescript
await chatSDK.deleteChat('chat-id');
console.log('Chat deleted');
```

## Error Handling

The SDK throws errors for failed requests. Always wrap SDK calls in try-catch blocks:

```typescript
try {
  const chat = await chatSDK.createChat('My Chat');
  // Handle success
} catch (error) {
  console.error('Failed to create chat:', error.message);
  // Handle error
}
```

## TypeScript Support

The SDK is written in TypeScript and includes full type definitions for all methods and responses.

## Features

- ✅ **Authentication**: X-API-KEY and X-API-SECRET headers
- ✅ **Chat Management**: Create, list, get, delete, rename chats
- ✅ **Message Sending**: Both simple and streaming responses
- ✅ **File Support**: Image and document uploads
- ✅ **Pagination**: Cursor-based pagination for chat listing
- ✅ **TypeScript**: Full type safety and IntelliSense support
- ✅ **Error Handling**: Comprehensive error handling
- ✅ **Real-time**: Streaming message responses
- ✅ **Feedback**: User feedback on AI responses

## API Reference

### Configuration

```typescript
interface ChatSDKConfig {
  apiKey: string;        // X-API-KEY header
  apiSecret: string;     // X-API-SECRET header  
  baseUrl: string;       // API base URL
  projectId: string;     // Project ID for all operations
}
```

### Chat Management

#### `createChat(name?, documentKeys?)`
Creates a new chat in the project.

```typescript
const chat = await chatSDK.createChat('My Chat', ['doc1', 'doc2']);
```

#### `listChats(cursor?, limit?)`
Lists chats with pagination support.

```typescript
const { chats, has_more, next_cursor } = await chatSDK.listChats();
```

#### `getChatHistory(chatId)`
Gets a specific chat with its message history.

```typescript
const chatHistory = await chatSDK.getChatHistory('chat-id');
```

#### `deleteChat(chatId)`
Deletes a chat and all its messages.

```typescript
await chatSDK.deleteChat('chat-id');
```

#### `updateChatName(chatId, newName)`
Updates the name of an existing chat.

```typescript
await chatSDK.updateChatName('chat-id', 'New Chat Name');
```

### Message Operations

#### `sendMessage(message, options?)`
Sends a message and returns the response.

```typescript
const response = await chatSDK.sendMessage('Hello!', {
  chatId: 'chat-id',
  agentType: 'chat_agent',
  documentKeys: ['doc1'],
});
```

#### `sendMessageStream(message, options?)`
Sends a message with streaming response support.

```typescript
await chatSDK.sendMessageStream('Tell me about AI', {
  chatId: 'chat-id',
  onChunk: (chunk) => {
    // Handle streaming text chunks
    console.log('Chunk:', chunk);
  },
  onMessageObject: (obj) => {
    // Handle structured message objects
    console.log('Message object:', obj);
  },
  onComplete: (message) => {
    // Handle completion
    console.log('Complete:', message);
  },
  onError: (error) => {
    // Handle errors
    console.error('Error:', error);
  },
});
```

### Feedback

#### `sendFeedback(messageId, chatId, feedback)`
Sends user feedback (thumbs up/down) for a message.

```typescript
await chatSDK.sendFeedback('message-id', 'chat-id', true); // thumbs up
await chatSDK.sendFeedback('message-id', 'chat-id', false); // thumbs down
```

## Advanced Usage

### File Uploads

```typescript
const fileInput = document.getElementById('file') as HTMLInputElement;
const files = Array.from(fileInput.files || []);

await chatSDK.sendMessageStream('Analyze this image', {
  chatId: 'chat-id',
  images: files,
  onChunk: (chunk) => console.log(chunk),
});
```

### Custom Agents

```typescript
await chatSDK.sendMessage('Help me write code', {
  chatId: 'chat-id',
  agentType: 'chat_agent',
  agentId: 'custom-agent-id',
  modelName: 'gpt-4o',
});
```

### Knowledge Base Integration

```typescript
await chatSDK.sendMessage('What does our documentation say about X?', {
  chatId: 'chat-id',
  documentKeys: ['doc1', 'doc2', 'doc3'],
  useKnowledgebase: true,
});
```

### Metadata

```typescript
await chatSDK.sendMessage('Hello', {
  chatId: 'chat-id',
  metadata: {
    userId: 'user-123',
    sessionId: 'session-456',
    customField: 'value',
  },
});
```

## Examples

See the `/examples` directory for complete working examples:

- `basic-chat.ts` - Simple chat implementation
- `streaming-chat.ts` - Real-time streaming chat
- `file-upload.ts` - Chat with file uploads
- `react-integration.tsx` - React component integration
- `workflow-basic.ts` - Basic workflow listing and execution
- `workflow-streaming.ts` - Real-time streaming workflow execution
- `workflow-react-embed.tsx` - React component for embedding workflows

---

## WorkflowSDK

Execute and monitor workflows from external applications with real-time streaming updates.

### Quick Start

```typescript
import { WorkflowSDK } from '@odin-ai/sdk';

const sdk = new WorkflowSDK({
  baseUrl: 'https://ecs-api.getodin.ai/',
  projectId: 'your-project-id',
  accessToken: 'your-access-token', // From Firebase, Supabase, or your auth
});

// List workflows
const { tools: workflows } = await sdk.listWorkflows();

// Execute with streaming updates
const session = await sdk.executeWorkflowStream('workflow-id', {
  inputs: { name: 'John' },
  onNodeStarted: (event) => console.log(`Starting ${event.node_id}`),
  onNodeCompleted: (event) => console.log(`Completed ${event.node_id}`),
  onExecutionCompleted: (event) => console.log('Done!', event.result),
});
```

### Key Features

- **List & retrieve workflows** - Get available workflows in your project
- **Execute workflows** - Run workflows with custom input values
- **Real-time streaming** - SSE-based updates for node-by-node progress
- **Execution history** - Track past executions and results
- **File upload support** - Execute workflows with file inputs
- **Full TypeScript support** - Complete type definitions

See [WorkflowSDK Documentation](./docs/WorkflowSDK.md) for full API reference.

---

## Workflow Embed

Embed workflow visualization directly in your web application with a lightweight bundle (335 KB / 106 KB gzipped).

### Installation

Include the embed script and CSS:

```html
<link rel="stylesheet" href="https://cdn.getodin.ai/embed/odin-workflow.css">
<script src="https://cdn.getodin.ai/embed/odin-workflow.js"></script>
```

Or build from source:

```bash
cd ai-content-creator
npx vite build --config vite.embed.config.ts
# Output: dist/embed/odin-workflow.js, dist/embed/odin-workflow.css
```

### Usage

#### Method 1: JavaScript API

```javascript
OdinWorkflow.mount(document.getElementById('workflow-container'), {
  apiUrl: 'https://ecs-api.getodin.ai/',
  projectId: 'your-project-id',
  workflowId: 'your-workflow-id',
  accessToken: 'your-access-token',
  theme: 'odin', // 'odin' | 'aai' | 'leah' | 'emerald' | 'sunset'
  onExecutionStart: (executionId) => console.log('Started:', executionId),
  onExecutionComplete: (result) => console.log('Complete:', result),
  onError: (error) => console.error('Error:', error),
});
```

#### Method 2: Web Component

```html
<odin-workflow
  api-url="https://ecs-api.getodin.ai/"
  project-id="your-project-id"
  workflow-id="your-workflow-id"
  access-token="your-access-token"
  theme="odin"
></odin-workflow>

<script>
  document.querySelector('odin-workflow').addEventListener('execution-complete', (e) => {
    console.log('Workflow completed:', e.detail.result);
  });
</script>
```

### Authentication Examples

#### With Firebase Auth

```javascript
import { initializeApp } from 'firebase/app';
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';

const app = initializeApp({ apiKey: '...', authDomain: '...' });
const auth = getAuth(app);

const userCredential = await signInWithEmailAndPassword(auth, email, password);
const accessToken = await userCredential.user.getIdToken();

OdinWorkflow.mount(container, {
  apiUrl: 'https://ecs-api.getodin.ai/',
  projectId: 'your-project-id',
  workflowId: 'your-workflow-id',
  accessToken: accessToken,
});
```

#### With Supabase Auth

```javascript
import { createClient } from '@supabase/supabase-js';

const supabase = createClient('https://your-project.supabase.co', 'your-anon-key');

const { data: { session } } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password',
});

OdinWorkflow.mount(container, {
  apiUrl: 'https://ecs-api.getodin.ai/',
  projectId: 'your-project-id',
  workflowId: 'your-workflow-id',
  accessToken: session.access_token,
});
```

### Available Themes

| Theme | Primary Color |
|-------|---------------|
| `odin` | Blue (#4485FF) |
| `aai` | Orange (#FF5A10) |
| `leah` | Purple (#A855F7) |
| `emerald` | Green (#10B981) |
| `sunset` | Amber (#F59E0B) |

### Props Reference

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `apiUrl` | string | ✅ | API base URL |
| `projectId` | string | ✅ | Your project ID |
| `workflowId` | string | ✅ | Workflow to display |
| `accessToken` | string | ✅ | Auth token |
| `theme` | string | ❌ | Theme name (default: 'odin') |
| `height` | string/number | ❌ | Container height |
| `width` | string/number | ❌ | Container width |
| `darkMode` | boolean | ❌ | Enable dark mode |
| `hideHeader` | boolean | ❌ | Hide workflow header |
| `hideInputs` | boolean | ❌ | Hide input fields |
| `showControls` | boolean | ❌ | Show zoom controls |
| `initialInputs` | object | ❌ | Pre-fill input values |
| `onExecutionStart` | function | ❌ | Callback when execution starts |
| `onExecutionComplete` | function | ❌ | Callback when execution completes |
| `onError` | function | ❌ | Callback on error |

See [examples/workflow-embed-supabase.html](./examples/workflow-embed-supabase.html) for a complete Supabase example.

---

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.