JavaScript SDK
The official Cortex JavaScript SDK for Node.js and browser environments. Provides TypeScript support and modern async/await patterns.
๐ฆ Installationโ
Node.jsโ
npm install @cortex/sdk
# or
yarn add @cortex/sdk
# or
pnpm add @cortex/sdk
Browser (CDN)โ
<script src="https://cdn.jsdelivr.net/npm/@cortex/sdk@latest/dist/cortex.min.js"></script>
Browser (ES Modules)โ
import Cortex from 'https://cdn.skypack.dev/@cortex/sdk';
๐ Quick Startโ
Node.jsโ
import Cortex from '@cortex/sdk';
// or const Cortex = require('@cortex/sdk');
// Initialize client
const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here'
});
// Search the web
const result = await cortex.search('latest AI developments');
console.log(result.summary);
// Extract content
const content = await cortex.extract('https://example.com/article');
console.log(content.text);
// Validate claim
const validation = await cortex.validate('The iPhone 15 supports USB-C');
console.log(`Validation: ${validation.result}`);
Browserโ
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@cortex/sdk@latest/dist/cortex.min.js"></script>
</head>
<body>
<script>
const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here'
});
async function searchExample() {
try {
const result = await cortex.search('quantum computing news');
document.getElementById('results').innerHTML = result.summary;
} catch (error) {
console.error('Search failed:', error);
}
}
</script>
</body>
</html>
๐ง Configurationโ
Environment Variablesโ
// .env file
CORTEX_API_KEY=cortex_sk_your_api_key_here
CORTEX_BASE_URL=https://api.usecortex.co/v1
// Client automatically reads environment variables
const cortex = new Cortex();
Configuration Objectโ
const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here',
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000,
maxRetries: 3,
retryDelay: 1000,
userAgent: 'MyApp/1.0',
defaultHeaders: {
'X-Custom-Header': 'value'
}
});
Configuration Fileโ
// cortex.config.js
export default {
apiKey: process.env.CORTEX_API_KEY,
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000,
maxRetries: 3
};
// Usage
import config from './cortex.config.js';
const cortex = new Cortex(config);
๐ Search APIโ
Basic Searchโ
// Simple search
const result = await cortex.search('quantum computing breakthrough');
console.log(result.summary);
console.log(`Found ${result.sources.length} sources`);
Advanced Searchโ
const result = await cortex.search({
query: 'Tesla stock analysis',
maxResults: 10,
language: 'en',
country: 'us',
recency: 'week',
includeSources: true,
domainFilter: {
include: ['reuters.com', 'bloomberg.com'],
exclude: ['reddit.com']
}
});
// Access results
console.log(`Summary: ${result.summary}`);
console.log(`Confidence: ${result.confidenceScore}`);
console.log(`Processing time: ${result.metadata.processingTime}s`);
// Iterate through sources
result.sources.forEach(source => {
console.log(`- ${source.title} (${source.confidence.toFixed(2)})`);
console.log(` ${source.url}`);
console.log(` ${source.snippet}`);
});
Search with Optionsโ
const result = await cortex.search({
query: 'machine learning model performance',
context: {
domain: 'technology',
intent: 'research',
complexity: 'technical'
},
options: {
deepSearch: true,
enableCache: true,
timeout: 20000
}
});
Streaming Searchโ
// Stream search results
const stream = cortex.searchStream('breaking news AI');
stream.on('progress', (event) => {
if (event.type === 'source') {
console.log(`Found: ${event.data.title}`);
} else if (event.type === 'summary') {
console.log(`Summary progress: ${event.data.progress}%`);
}
});
stream.on('complete', (result) => {
console.log('Search complete:', result.summary);
});
stream.on('error', (error) => {
console.error('Search failed:', error);
});
Promise-based Streamingโ
const result = await cortex.search({
query: 'breaking news AI',
stream: true,
onProgress: (event) => {
console.log(`Progress: ${event.type}`, event.data);
}
});
console.log('Final result:', result.summary);
๐ Extract APIโ
URL Extractionโ
// Extract content from URL
const content = await cortex.extract('https://example.com/article');
console.log(`Title: ${content.metadata.title}`);
console.log(`Author: ${content.metadata.author}`);
console.log(`Word count: ${content.metadata.wordCount}`);
console.log(`Content: ${content.text}`);
Advanced Extractionโ
const content = await cortex.extract({
url: 'https://example.com/article',
format: 'markdown',
includeMetadata: true,
extractImages: true,
extractLinks: true,
cleanHtml: true
});
// Access structured content
console.log(`Title: ${content.metadata.title}`);
console.log(`Reading time: ${content.metadata.readingTime}`);
console.log(`Quality score: ${content.qualityScore}`);
// Access images
content.images.forEach(image => {
console.log(`Image: ${image.url} - ${image.alt}`);
});
// Access links
console.log(`Internal links: ${content.links.internal.length}`);
console.log(`External links: ${content.links.external.length}`);
Batch Extractionโ
const urls = [
'https://example1.com/article',
'https://example2.com/article',
'https://example3.com/article'
];
// Extract multiple URLs concurrently
const results = await cortex.extractBatch(urls, { maxConcurrency: 5 });
for (const [url, content] of Object.entries(results)) {
if (content.success) {
console.log(`${url}: ${content.metadata.wordCount} words`);
} else {
console.log(`${url}: Failed - ${content.error}`);
}
}
PDF Extractionโ
// Extract from PDF
const content = await cortex.extract({
url: 'https://example.com/document.pdf',
options: {
extractPages: [1, 2, 3],
preserveLayout: false,
ocrEnabled: true
}
});
console.log(content.text);
โ Validate APIโ
Basic Validationโ
// Validate a factual claim
const result = await cortex.validate('The Earth is round');
console.log(`Result: ${result.validationResult}`); // VERIFIED
console.log(`Confidence: ${result.confidenceScore}`);
console.log(`Consensus: ${result.consensusLevel}`);
Advanced Validationโ
const result = await cortex.validate({
claim: 'Tesla delivered over 1.8 million vehicles in 2023',
sources: [
'https://ir.tesla.com/press-release/tesla-q4-2023',
'reuters.com',
'bloomberg.com'
],
context: {
domain: 'automotive',
claimType: 'statistical',
timeSensitive: true
},
options: {
confidenceThreshold: 0.8,
requirePrimarySources: true,
maxSources: 10
}
});
// Analyze evidence
console.log(`Validation: ${result.validationResult}`);
console.log(`Supporting sources: ${result.evidence.supporting.length}`);
console.log(`Contradicting sources: ${result.evidence.contradicting.length}`);
// Review evidence
result.evidence.supporting.forEach(evidence => {
console.log(`+ ${evidence.source}`);
console.log(` Confidence: ${evidence.confidence.toFixed(2)}`);
console.log(` Authority: ${evidence.authorityScore.toFixed(2)}`);
console.log(` Snippet: ${evidence.snippet}`);
});
Batch Validationโ
const claims = [
{ id: 'claim1', claim: 'Python is open source' },
{ id: 'claim2', claim: 'The moon is made of cheese' },
{ id: 'claim3', claim: 'Bitcoin was created in 2009' }
];
const results = await cortex.validateBatch(claims);
results.forEach(result => {
console.log(`${result.id}: ${result.validationResult}`);
});
๐ Cache APIโ
Query Cacheโ
// Check if result is cached
const cached = await cortex.cache.query('AI developments today');
if (cached.cacheHit) {
console.log('Using cached result');
console.log(`TTL remaining: ${cached.ttlRemaining}s`);
return cached.results;
} else {
// Perform new search
const result = await cortex.search('AI developments today');
// Store in cache
await cortex.cache.store({
query: 'AI developments today',
content: result,
ttl: 3600, // 1 hour
trustLevel: 'high'
});
return result;
}
Cache Managementโ
// Get cache statistics
const stats = await cortex.cache.stats();
console.log(`Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
console.log(`Storage used: ${stats.storageUsed}`);
// Clear cache by tags
await cortex.cache.clear({ tags: ['outdated', 'temporary'] });
// Clear old entries
const cutoff = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); // 7 days ago
await cortex.cache.clear({ olderThan: cutoff });
๐ Monitoringโ
Usage Statisticsโ
// Get usage stats
const usage = await cortex.monitoring.usage({ period: 'month' });
console.log(`Requests used: ${usage.requestsUsed}/${usage.requestsLimit}`);
console.log(`Success rate: ${(usage.performanceMetrics.successRate * 100).toFixed(1)}%`);
console.log(`Avg response time: ${usage.performanceMetrics.avgResponseTime.toFixed(2)}s`);
console.log(`Cache hit rate: ${(usage.performanceMetrics.cacheHitRate * 100).toFixed(1)}%`);
Health Monitoringโ
// Check system health
const health = await cortex.monitoring.health();
if (health.status === 'healthy') {
console.log('All systems operational');
} else {
console.log('System issues detected:');
Object.entries(health.services).forEach(([service, status]) => {
if (status.status !== 'healthy') {
console.log(` ${service}: ${status.status}`);
}
});
}
Audit Logsโ
// Get recent audit logs
const logs = await cortex.monitoring.audit({ limit: 100 });
logs.entries.forEach(entry => {
console.log(`${entry.timestamp}: ${entry.endpoint} - ${entry.status}`);
if (entry.status !== 200) {
console.log(` Error: ${entry.error}`);
}
});
๐จ Error Handlingโ
Error Typesโ
import Cortex, {
CortexError, // Base error
AuthenticationError, // 401 errors
RateLimitError, // 429 errors
ValidationError, // 400 errors
ServerError // 5xx errors
} from '@cortex/sdk';
try {
const result = await cortex.search('test query');
} catch (error) {
if (error instanceof AuthenticationError) {
console.log(`Auth error: ${error.message}`);
// Handle invalid API key
} else if (error instanceof RateLimitError) {
console.log(`Rate limited: ${error.retryAfter}s`);
// Implement backoff
} else if (error instanceof ValidationError) {
console.log(`Invalid request: ${error.message}`);
// Fix request parameters
} else if (error instanceof ServerError) {
console.log(`Server error: ${error.message}`);
// Retry or report issue
} else if (error instanceof CortexError) {
console.log(`General error: ${error.code} - ${error.message}`);
}
}
Retry Logicโ
async function searchWithRetry(cortex, query, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await cortex.search(query);
} catch (error) {
if (error instanceof RateLimitError) {
if (attempt < maxRetries - 1) {
const delay = error.retryAfter * 1000 || Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
} else if (error instanceof ServerError) {
if (attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
// Usage
const result = await searchWithRetry(cortex, 'AI developments');
๐ง Advanced Featuresโ
Request Interceptorsโ
// Add request interceptor
cortex.interceptors.request.use(
(config) => {
console.log(`Making request to ${config.url}`);
config.headers['X-Request-ID'] = Math.random().toString(36);
return config;
},
(error) => {
console.error('Request error:', error);
return Promise.reject(error);
}
);
// Add response interceptor
cortex.interceptors.response.use(
(response) => {
console.log(`Response: ${response.status} in ${response.duration}ms`);
return response;
},
(error) => {
console.error('Response error:', error);
return Promise.reject(error);
}
);
AbortController Supportโ
// Abort long-running requests
const controller = new AbortController();
// Set timeout to abort after 10 seconds
setTimeout(() => controller.abort(), 10000);
try {
const result = await cortex.search({
query: 'complex search query',
signal: controller.signal
});
console.log(result.summary);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request was aborted');
} else {
console.error('Search failed:', error);
}
}
Custom Fetch Implementationโ
// Use custom fetch (e.g., for Deno, Bun, or custom proxy)
import customFetch from './my-fetch-implementation.js';
const cortex = new Cortex({
apiKey: 'your_key',
fetch: customFetch
});
Middlewareโ
// Add custom middleware
cortex.use((req, next) => {
console.log(`Request: ${req.method} ${req.url}`);
const start = Date.now();
return next(req).then(response => {
console.log(`Response: ${response.status} in ${Date.now() - start}ms`);
return response;
});
});
๐งช Testingโ
Mock Clientโ
import { MockCortex } from '@cortex/sdk/testing';
// Create mock client
const mockCortex = new MockCortex();
// Add mock responses
mockCortex.addSearchResponse({
query: 'test query',
response: {
summary: 'Test summary',
sources: [],
confidenceScore: 0.9
}
});
// Use in tests
const result = await mockCortex.search('test query');
expect(result.summary).toBe('Test summary');
Jest Integrationโ
// __mocks__/@cortex/sdk.js
export default class MockCortex {
async search(query) {
return {
summary: 'Mocked summary',
sources: [],
confidenceScore: 0.9
};
}
async extract(url) {
return {
text: 'Mocked content',
metadata: { title: 'Mocked title' }
};
}
}
// test.js
import Cortex from '@cortex/sdk';
jest.mock('@cortex/sdk');
test('search returns results', async () => {
const cortex = new Cortex({ apiKey: 'test' });
const result = await cortex.search('test query');
expect(result.summary).toBe('Mocked summary');
});
Vitest Integrationโ
// vitest.config.js
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'node',
setupFiles: ['./test/setup.js']
}
});
// test/setup.js
import { vi } from 'vitest';
vi.mock('@cortex/sdk', () => ({
default: vi.fn().mockImplementation(() => ({
search: vi.fn().mockResolvedValue({
summary: 'Mocked summary',
sources: []
})
}))
}));
๐ Framework Integrationโ
React Hookโ
// hooks/useCortex.js
import { useState, useEffect } from 'react';
import Cortex from '@cortex/sdk';
const cortex = new Cortex({
apiKey: process.env.REACT_APP_CORTEX_API_KEY
});
export function useCortexSearch(query) {
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!query) return;
let cancelled = false;
const performSearch = async () => {
setLoading(true);
setError(null);
try {
const searchResult = await cortex.search(query);
if (!cancelled) {
setResult(searchResult);
}
} catch (err) {
if (!cancelled) {
setError(err);
}
} finally {
if (!cancelled) {
setLoading(false);
}
}
};
performSearch();
return () => {
cancelled = true;
};
}, [query]);
return { result, loading, error };
}
// Component usage
import { useCortexSearch } from './hooks/useCortex';
function SearchComponent() {
const [query, setQuery] = useState('');
const { result, loading, error } = useCortexSearch(query);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
{loading && <div>Searching...</div>}
{error && <div>Error: {error.message}</div>}
{result && (
<div>
<h3>Summary:</h3>
<p>{result.summary}</p>
</div>
)}
</div>
);
}
Next.js API Routeโ
// pages/api/search.js
import Cortex from '@cortex/sdk';
const cortex = new Cortex({
apiKey: process.env.CORTEX_API_KEY
});
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { query } = req.body;
if (!query) {
return res.status(400).json({ error: 'Query is required' });
}
try {
const result = await cortex.search(query);
res.status(200).json(result);
} catch (error) {
console.error('Search error:', error);
res.status(500).json({ error: 'Search failed' });
}
}
Express.js Middlewareโ
// middleware/cortex.js
import Cortex from '@cortex/sdk';
const cortex = new Cortex({
apiKey: process.env.CORTEX_API_KEY
});
export function addCortexToRequest(req, res, next) {
req.cortex = cortex;
next();
}
// routes/search.js
import express from 'express';
const router = express.Router();
router.post('/search', async (req, res) => {
try {
const result = await req.cortex.search(req.body.query);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
export default router;
Vue.js Pluginโ
// plugins/cortex.js
import Cortex from '@cortex/sdk';
export default {
install(app, options) {
const cortex = new Cortex(options);
app.config.globalProperties.$cortex = cortex;
app.provide('cortex', cortex);
}
};
// main.js
import { createApp } from 'vue';
import CortexPlugin from './plugins/cortex';
const app = createApp(App);
app.use(CortexPlugin, {
apiKey: process.env.VUE_APP_CORTEX_API_KEY
});
// Component usage
<template>
<div>
<input v-model="query" @input="search" />
<div v-if="loading">Searching...</div>
<div v-else-if="result">{{ result.summary }}</div>
</div>
</template>
<script>
import { inject, ref } from 'vue';
export default {
setup() {
const cortex = inject('cortex');
const query = ref('');
const result = ref(null);
const loading = ref(false);
const search = async () => {
if (!query.value) return;
loading.value = true;
try {
result.value = await cortex.search(query.value);
} catch (error) {
console.error('Search failed:', error);
} finally {
loading.value = false;
}
};
return { query, result, loading, search };
}
};
</script>
๐ TypeScript Supportโ
Type Definitionsโ
// Import with types
import Cortex, {
SearchResult,
ExtractionResult,
ValidationResult,
CortexConfig,
SearchOptions,
ExtractOptions,
ValidateOptions
} from '@cortex/sdk';
// Configure with types
const config: CortexConfig = {
apiKey: 'cortex_sk_your_api_key_here',
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000
};
const cortex = new Cortex(config);
// Typed search
const searchOptions: SearchOptions = {
query: 'AI developments',
maxResults: 10,
language: 'en',
includeSources: true
};
const result: SearchResult = await cortex.search(searchOptions);
// Type guards
if (result.success) {
console.log(result.summary); // TypeScript knows this exists
result.sources.forEach(source => {
console.log(source.title); // Fully typed
});
}
Generic Typesโ
// Custom result processing
async function processSearchResult<T>(
cortex: Cortex,
query: string,
processor: (result: SearchResult) => T
): Promise<T> {
const result = await cortex.search({ query });
return processor(result);
}
// Usage
const summary = await processSearchResult(
cortex,
'AI news',
(result) => result.summary
);
Next: REST API โ - Direct HTTP API usage without SDK