subconscious
v0.2.0
Published
Official Node.js SDK for the Subconscious API
Maintainers
Readme
Installation
pnpm add subconscious
# or
npm install subconscious
# or
yarn add subconsciousQuick Start
import { Subconscious } from 'subconscious';
const client = new Subconscious({
apiKey: process.env.SUBCONSCIOUS_API_KEY!,
});
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Search for the latest AI news and summarize the top 3 stories',
tools: [{ type: 'platform', id: 'parallel_search', options: {} }],
},
options: { awaitCompletion: true },
});
console.log(run.result?.answer);Get Your API Key
Create an API key in the Subconscious dashboard.
Usage
Run and Wait
The simplest way to use the SDK—create a run and wait for completion:
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Analyze the latest trends in renewable energy',
tools: [{ type: 'platform', id: 'parallel_search', options: {} }],
},
options: { awaitCompletion: true },
});
console.log(run.result?.answer);
console.log(run.result?.reasoning); // Structured reasoning nodesFire and Forget
Start a run without waiting, then check status later:
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Generate a comprehensive report',
tools: [],
},
});
console.log(`Run started: ${run.runId}`);
// Check status later
const status = await client.get(run.runId);
console.log(status.status); // 'queued' | 'running' | 'succeeded' | 'failed' | 'canceled' | 'timed_out'Poll with Custom Options
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Complex task',
tools: [{ type: 'platform', id: 'parallel_search' }],
},
});
// Wait with custom polling options
const result = await client.wait(run.runId, {
intervalMs: 2000, // Poll every 2 seconds
maxAttempts: 60, // Give up after 60 attempts
});Streaming (Text Deltas)
Stream text as it's generated:
const stream = client.stream({
engine: 'tim-gpt',
input: {
instructions: 'Write a short essay about space exploration',
tools: [{ type: 'platform', id: 'parallel_search' }],
},
});
for await (const event of stream) {
if (event.type === 'delta') {
process.stdout.write(event.content);
} else if (event.type === 'done') {
console.log('\n\nRun completed:', event.runId);
} else if (event.type === 'error') {
console.error('Error:', event.message);
}
}Note: Rich streaming events (reasoning steps, tool calls) are coming soon. Currently, the stream provides text deltas as they're generated.
Tools
// Platform tools (hosted by Subconscious)
const parallelSearch = {
type: 'platform',
id: 'parallel_search',
options: {},
};
// Function tools (your own functions)
const customFunction = {
type: 'function',
function: {
name: 'get_weather',
description: 'Get current weather for a location',
parameters: {
type: 'object',
properties: {
location: { type: 'string' },
},
required: ['location'],
},
url: 'https://api.example.com/weather',
method: 'GET',
timeout: 30,
},
};
// MCP tools
const mcpTool = {
type: 'mcp',
url: 'https://mcp.example.com',
allow: ['read', 'write'],
};Structured Output
Get structured responses using JSON Schema. We recommend using Zod to define your schema, then convert it with zodToJsonSchema():
import { z } from 'zod';
import { Subconscious, zodToJsonSchema } from 'subconscious';
const client = new Subconscious({ apiKey: process.env.SUBCONSCIOUS_API_KEY! });
// Define your output schema with Zod
const AnalysisSchema = z.object({
summary: z.string().describe('A brief summary of the findings'),
keyPoints: z.array(z.string()).describe('Main takeaways'),
sentiment: z.enum(['positive', 'neutral', 'negative']),
confidence: z.number().describe('Confidence score from 0 to 1'),
});
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Analyze the latest news about electric vehicles',
tools: [{ type: 'platform', id: 'parallel_search', options: {} }],
answerFormat: zodToJsonSchema(AnalysisSchema, 'Analysis'),
},
options: { awaitCompletion: true },
});
// Result is typed according to your schema
const result = run.result?.answer as z.infer<typeof AnalysisSchema>;
console.log(result.summary);
console.log(result.keyPoints);You can also define a reasoningFormat to structure the agent's reasoning:
const ReasoningSchema = z.object({
steps: z.array(z.object({
thought: z.string(),
action: z.string(),
})),
conclusion: z.string(),
});
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Research and explain quantum computing',
tools: [{ type: 'platform', id: 'parallel_search', options: {} }],
answerFormat: zodToJsonSchema(AnalysisSchema, 'Analysis'),
reasoningFormat: zodToJsonSchema(ReasoningSchema, 'Reasoning'),
},
options: { awaitCompletion: true },
});Manual JSON Schema
You can also provide the JSON Schema directly without Zod:
const run = await client.run({
engine: 'tim-gpt',
input: {
instructions: 'Analyze this topic',
tools: [],
answerFormat: {
title: 'Analysis',
type: 'object',
properties: {
summary: { type: 'string', description: 'Brief summary' },
score: { type: 'number', description: 'Score from 1-10' },
},
required: ['summary', 'score'],
},
},
options: { awaitCompletion: true },
});Error Handling
import { SubconsciousError, AuthenticationError, RateLimitError } from 'subconscious';
try {
const run = await client.run({ /* ... */ });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error('Rate limited, retry later');
} else if (error instanceof SubconsciousError) {
console.error(`API error: ${error.code} - ${error.message}`);
}
}Cancellation
// Cancel via AbortController
const controller = new AbortController();
const stream = client.stream(params, { signal: controller.signal });
setTimeout(() => controller.abort(), 30000);
// Or cancel a running run
await client.cancel(run.runId);API Reference
Subconscious
The main client class.
Constructor Options
| Option | Type | Required | Default |
| --------- | -------- | -------- | --------------------------------- |
| apiKey | string | Yes | - |
| baseUrl | string | No | https://api.subconscious.dev/v1 |
Methods
| Method | Description |
| -------------------------- | ------------------------ |
| run(params) | Create a new run |
| stream(params, options?) | Stream text deltas |
| get(runId) | Get run status |
| wait(runId, options?) | Poll until completion |
| cancel(runId) | Cancel a running run |
zodToJsonSchema(schema, title)
Convert a Zod schema to the JSON Schema format expected by answerFormat and reasoningFormat.
| Param | Type | Description |
| -------- | ------------ | ---------------------------------- |
| schema | Zod object | A Zod object schema (z.object()) |
| title | string | Title for the schema |
Returns an OutputSchema compatible with answerFormat and reasoningFormat.
Engines
| Engine | Description |
| --------------- | ---------------------------------------------------- |
| tim-edge | Fast, lightweight engine optimized for simple tasks |
| tim-gpt | Balanced reasoning engine powered by OpenAI |
| tim-gpt-heavy | Advanced reasoning engine for complex tasks |
Run Status
| Status | Description |
| ----------- | ---------------------- |
| queued | Waiting to start |
| running | Currently executing |
| succeeded | Completed successfully |
| failed | Encountered an error |
| canceled | Manually canceled |
| timed_out | Exceeded time limit |
Requirements
- Node.js ≥ 18
- ESM only
Contributing
Contributions are welcome! Please feel free to submit a pull request.
License
Apache-2.0
Support
For support and questions:
- Documentation: https://docs.subconscious.dev
- Email: {hongyin,jack}@subconscious.dev
License
Apache-2.0
