JavaScript SDK for driftos-core - conversation routing and context management for AI applications.
npm install @driftos/clientimport { createDriftClient } from '@driftos/client';
const drift = createDriftClient('http://localhost:3000');
// Route a message
const result = await drift.route('conv-123', 'I want to plan a trip to Paris');
console.log(result.branchTopic); // "Paris trip planning"
// Get context for LLM
const { system, messages } = await drift.buildPrompt(result.branchId);
// Use with OpenAI
const response = await openai.chat.completions.create({
model: 'gpt-5',
messages: [
{ role: 'system', content: system },
...messages,
{ role: 'user', content: 'What hotels do you recommend?' }
]
});import { DriftClient } from '@driftos/client';
// Bare host is fine — the SDK auto-composes /api/v1/<engine>/... for you.
const drift = new DriftClient({
baseUrl: 'https://api.driftos.dev',
apiKey: 'your-api-key',
// engine: 'llm' (default) | 'embed'
});
const result = await drift.route('conv-123', 'I want to plan a trip to Paris');Or pin to a specific engine by giving the full URL yourself — the SDK sees the engine segment and leaves it alone:
const drift = new DriftClient({
baseUrl: 'https://api.driftos.dev/api/v1/embed',
apiKey: 'your-api-key',
});new DriftClient({
baseUrl: string; // Required: Base URL of your driftos instance
apiKey?: string; // Optional: API key for authentication
timeout?: number; // Optional: Request timeout in ms (default: 10000)
engine?: 'llm' | 'embed'; // Optional: hosted engine (default: 'llm')
hosted?: boolean; // Optional: force hosted-gateway mode on/off
})Hosted mode (gateway at api.driftos.dev):
- Auto-detected when
baseUrlcontainsapi.driftos.dev. - If
baseUrldoesn't include an engine segment (/api/v1/llmor/api/v1/embed), the SDK appends/api/v1/<engine>automatically. Default engine isllm. - If you already include the engine segment in
baseUrl, it's left untouched.
Self-hosted mode (direct connection to driftos-core or driftos-embed):
- Set
hosted: false(or use any URL that doesn't containapi.driftos.dev). - Paths are composed as
<baseUrl>/api/v1/...with no engine prefix.
Route a message to the appropriate branch.
List all branches for a conversation.
Get messages and facts for a branch.
Extract facts from branch messages.
Get existing facts for a branch.
Build a ready-to-use prompt with context for LLM calls.
Options:
systemPrompt?: string- Base system prompt (default: 'You are a helpful assistant.')includeOtherTopics?: boolean- Mention other discussed topics (default: true)includeFacts?: boolean- Include extracted facts (default: true)factsFromAllBranches?: boolean- Include facts from all branches (default: false)template?: (ctx) => string- Custom template function for system prompt generation
Legacy: Also accepts a plain string for systemPrompt (backwards compatible)
Delete a conversation and every branch, message, and fact belonging to it. Use this to implement client "Clear chat history" flows. Throws on 404.
const { deletedBranches, deletedMessages, deletedFacts } =
await drift.deleteConversation('conv-123');Returns: { deletedBranches: number; deletedMessages: number; deletedFacts: number }
Delete a branch and every descendant branch (cascading), including their messages and facts. No re-parenting is performed. Throws on 404.
const { deletedMessages, deletedFacts } = await drift.deleteBranch('branch_abc123');Returns: { deletedMessages: number; deletedFacts: number }
By default, route() lets the server decide which branch a message belongs to.
If your UI lets the user manually select a branch, pass branchMode: 'PINNED'
with targetBranchId to force the write onto that branch instead.
await drift.route('conv-123', 'reply text', {
branchMode: 'PINNED',
targetBranchId: 'branch_abc123',
});
// result.pinned === trueMIT