Skip to main content

TypeScript SDK user guide

The Crusoe AI Platform TypeScript/Node.js SDK provides strongly typed, async/await interfaces for building frontend and backend applications on Node.js and modern JavaScript runtimes.


Installation

Install the package into your TypeScript or Node.js project:

# Install from local SDK directory
npm install ./sdk/typescript

# Or install from npm registry
npm install @crusoe-ai/sdk

Requirements

  • Node.js 18.0.0 or higher — the examples below call the built-in global fetch, so there is no HTTP client to install
  • TypeScript 4.5+ (if using TypeScript)

Authentication & Configuration

The SDK reads CAI_API_KEY and CAI_PROJECT from process.env, or you can pass configuration explicitly:

import { Configuration } from '@crusoe-ai/secrets';

const config = new Configuration({
basePath: process.env.CAI_API || 'https://api.codyhill.dev',
headers: {
Authorization: `Bearer ${process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef'}`
}
});

Code examples by service

1. Agents

Invoke agents asynchronously, handle streamed server-sent events, list user sessions, and memorize agent interactions.

const apiBase = process.env.CAI_API || 'https://api.codyhill.dev';
const apiKey = process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef';
const projectId = process.env.CAI_PROJECT || '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};

// 1. Synchronous agent invocation
async function invokeAgent(agentName: string, prompt: string, sessionId = 'sess_ts_001') {
const url = `${apiBase}/v1/agents/${agentName}/invoke?project=${projectId}`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ prompt, session_id: sessionId, user_id: 'user_node' })
});

const data = await response.json();
console.log('Agent Response:', data.response);
return data;
}

// 2. Streaming agent invocation (NDJSON)
async function invokeAgentStream(agentName: string, prompt: string, sessionId = 'sess_ts_001') {
const url = `${apiBase}/v1/agents/${agentName}/invoke/stream?project=${projectId}`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ prompt, session_id: sessionId })
});

if (!response.body) return;

for await (const chunk of response.body) {
const lines = chunk.toString().split('\n').filter(Boolean);
for (const line of lines) {
const parsed = JSON.parse(line);
if (parsed.text) {
process.stdout.write(parsed.text);
}
}
}
console.log();
}

// 3. Memorize session transcript
async function memorizeSession(agentName: string, sessionId: string) {
const url = `${apiBase}/v1/agents/${agentName}/sessions/${sessionId}/memorize?project=${projectId}`;
const response = await fetch(url, { method: 'POST', headers });
console.log('Memorize Status:', response.status);
}

// Example Execution
(async () => {
await invokeAgent('research-assistant', 'Explain vector database indexes.');
await memorizeSession('research-assistant', 'sess_ts_001');
})();

2. VectorDB

Create vector indexes, upsert vector embeddings, query similar points, and scroll point collections.

const vectorBase = process.env.CAI_VECTORDB_API || 'https://api.codyhill.dev';
const apiKey = process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef';
const projectId = process.env.CAI_PROJECT || '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};

interface VectorPoint {
id: string;
vector: number[];
payload?: Record<string, any>;
}

// 1. Create a VectorDB index
async function createIndex(indexName: string, dimension = 1536) {
const url = `${vectorBase}/v1/projects/${projectId}/indexes`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ name: indexName, dimension, metric: 'cosine' })
});
console.log('Index created with status:', response.status);
}

// 2. Upsert vector points
async function upsertPoints(indexName: string, points: VectorPoint[]) {
const url = `${vectorBase}/v1/projects/${projectId}/indexes/${indexName}:upsert`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ points })
});
const data = await response.json();
console.log('Upsert result:', data);
}

// 3. Query vector similarity
async function queryVector(indexName: string, vector: number[], topK = 5) {
const url = `${vectorBase}/v1/projects/${projectId}/indexes/${indexName}:query`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ vector, top_k: topK, include_payload: true })
});
const data = await response.json();
console.log('Found matches:', data.matches?.length || 0);
return data;
}

// Example Execution
(async () => {
const samplePoints: VectorPoint[] = [
{
id: 'doc_101',
vector: new Array(1536).fill(0.02),
payload: { source: 'docs', topic: 'typescript-sdk' }
}
];
await upsertPoints('kb-ts-index', samplePoints);
await queryVector('kb-ts-index', new Array(1536).fill(0.02));
})();

3. Functions

Trigger serverless functions, read output values, and tail function logs.

const apiBase = process.env.CAI_API || 'https://api.codyhill.dev';
const apiKey = process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef';
const projectId = process.env.CAI_PROJECT || '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};

// 1. Execute function
async function executeFunction(functionName: string, payload: Record<string, any>) {
const url = `${apiBase}/v1/agents/${functionName}/invoke?project=${projectId}`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(payload)
});
const result = await response.json();
console.log('Function Execution Output:', result);
return result;
}

// 2. Fetch logs
async function getLogs(functionName: string) {
const url = `${apiBase}/v1/agents/${functionName}/logs?project=${projectId}`;
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const logs = await response.text();
console.log('Function Logs:\n', logs);
}

// Example execution
(async () => {
await executeFunction('image-resizer', { width: 800, height: 600, image_url: 'https://example.com/img.png' });
await getLogs('image-resizer');
})();

4. Secrets

Manage secrets using @crusoe-ai/secrets TypeScript API bindings.

import {
Configuration,
SecretsApi,
BindingsApi,
CreateSecretRequest,
PutBindingRequest
} from '@crusoe-ai/secrets';

const config = new Configuration({
basePath: process.env.CAI_API || 'https://api.codyhill.dev',
headers: {
Authorization: `Bearer ${process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef'}`
}
});

const projectId = '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

async function manageSecrets() {
const secretsApi = new SecretsApi(config);
const bindingsApi = new BindingsApi(config);

// 1. Create a secret
const createReq: CreateSecretRequest = {
name: 'github-token',
value: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz'
};
const secret = await secretsApi.createProjectSecret({ projectID: projectId, createSecretRequest: createReq });
console.log(`Created secret ${secret.name}, version: ${secret.version}`);

// 2. Bind secret to an agent
const bindReq: PutBindingRequest = {
secretName: 'github-token'
};
await bindingsApi.putAgentSecretBinding({
projectID: projectId,
agent: 'ci-bot',
envName: 'GITHUB_TOKEN',
putBindingRequest: bindReq
});
console.log('Bound secret to ci-bot');

// 3. Apply secret bindings
const applyResult = await bindingsApi.applyAgentSecretBindings({
projectID: projectId,
agent: 'ci-bot'
});
console.log('Applied bindings result:', applyResult);

// 4. Reveal secret value (Admin only, audited)
const revealed = await secretsApi.revealSecret({
projectID: projectId,
name: 'github-token'
});
console.log('Revealed secret:', revealed.value);
}

manageSecrets().catch(console.error);

5. MemoryStore

Manage Redis-compatible instances, check live server metrics, and rotate instance keys.

const memBase = process.env.CAI_MEMORYSTORE_API || 'https://api.codyhill.dev';
const apiKey = process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef';
const projectId = process.env.CAI_PROJECT || '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};

// 1. Create instance
async function createStore(instanceName: string) {
const url = `${memBase}/v1/projects/${projectId}/memorystores`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ name: instanceName, max_memory_mb: 256 })
});
const data = await response.json();
console.log('MemoryStore Endpoint:', data.endpoint);
return data;
}

// 2. Fetch stats
async function getStoreStats(instanceName: string) {
const url = `${memBase}/v1/projects/${projectId}/memorystores/${instanceName}/stats`;
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const stats = await response.json();
console.log('MemoryStore connected clients:', stats.connected_clients);
}

(async () => {
await createStore('session-cache');
await getStoreStats('session-cache');
})();

6. PubSub

Publish message objects, pull unacknowledged messages, and acknowledge processed IDs.

const pubsubBase = process.env.CAI_PUBSUB_API || 'https://api.codyhill.dev';
const apiKey = process.env.CAI_API_KEY || 'cai_pk_live_1234567890abcdef';
const projectId = process.env.CAI_PROJECT || '0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f';

const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};

// 1. Publish message
async function publishMessage(topic: string, dataObj: Record<string, any>) {
const url = `${pubsubBase}/v1/projects/${projectId}/topics/${topic}:publish`;
const encoded = Buffer.from(JSON.stringify(dataObj)).toString('base64');

const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({
messages: [{ data: encoded, attributes: { env: 'production' } }]
})
});
const res = await response.json();
console.log('Published message IDs:', res.message_ids);
}

// 2. Pull messages
async function pullMessages(topic: string, subscription: string) {
const url = `${pubsubBase}/v1/projects/${projectId}/topics/${topic}/subscriptions/${subscription}:pull`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ max_messages: 10 })
});
const data = await response.json();
const ackIds: string[] = [];

for (const msg of data.received_messages || []) {
const raw = Buffer.from(msg.message.data, 'base64').toString('utf-8');
console.log('Received Message Payload:', JSON.parse(raw));
ackIds.push(msg.ack_id);
}
return ackIds;
}

// 3. Acknowledge messages
async function acknowledgeMessages(topic: string, subscription: string, ackIds: string[]) {
if (ackIds.length === 0) return;
const url = `${pubsubBase}/v1/projects/${projectId}/topics/${topic}/subscriptions/${subscription}:acknowledge`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ ack_ids: ackIds })
});
console.log('Ack Response Status:', response.status);
}

// Example execution
(async () => {
await publishMessage('order-events', { order_id: 'ord_123', total: 49.99 });
const acks = await pullMessages('order-events', 'order-processor');
await acknowledgeMessages('order-events', 'order-processor', acks);
})();

Error handling

Errors are returned as standard JavaScript Error objects or HTTP status codes:

try {
// Call SDK endpoint
} catch (error: any) {
console.error('API Error Message:', error.message);
if (error.response) {
console.error('HTTP Status:', error.response.status);
console.error('Request ID:', error.response.headers.get('x-request-id'));
}
}