@thinkbase/sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/examples/basic.d.ts +1 -0
  2. package/dist/examples/basic.js +82 -0
  3. package/dist/examples/llm-context.d.ts +1 -0
  4. package/dist/examples/llm-context.js +107 -0
  5. package/dist/examples/postrgres.d.ts +1 -0
  6. package/dist/examples/postrgres.js +73 -0
  7. package/dist/src/client.d.ts +8 -0
  8. package/dist/src/client.js +16 -0
  9. package/dist/src/connectors/base.d.ts +9 -0
  10. package/dist/src/connectors/base.js +9 -0
  11. package/dist/src/connectors/factory.d.ts +5 -0
  12. package/dist/src/connectors/factory.js +29 -0
  13. package/dist/src/connectors/json.d.ts +7 -0
  14. package/dist/src/connectors/json.js +22 -0
  15. package/dist/src/connectors/mongodb.d.ts +9 -0
  16. package/dist/src/connectors/mongodb.js +39 -0
  17. package/dist/src/connectors/mysql.d.ts +8 -0
  18. package/dist/src/connectors/mysql.js +38 -0
  19. package/dist/src/connectors/postgres.d.ts +8 -0
  20. package/dist/src/connectors/postgres.js +35 -0
  21. package/dist/src/connectors/rest.d.ts +7 -0
  22. package/dist/src/connectors/rest.js +27 -0
  23. package/dist/src/context/builder.d.ts +11 -0
  24. package/dist/src/context/builder.js +40 -0
  25. package/dist/src/dataset.d.ts +21 -0
  26. package/dist/src/dataset.js +83 -0
  27. package/dist/src/embedding/chunker.d.ts +10 -0
  28. package/dist/src/embedding/chunker.js +41 -0
  29. package/dist/src/embedding/embedder.d.ts +9 -0
  30. package/dist/src/embedding/embedder.js +54 -0
  31. package/dist/src/embedding/pipeline.d.ts +8 -0
  32. package/dist/src/embedding/pipeline.js +24 -0
  33. package/dist/src/index.d.ts +3 -0
  34. package/dist/src/index.js +22 -0
  35. package/dist/src/query/natural-language.d.ts +9 -0
  36. package/dist/src/query/natural-language.js +44 -0
  37. package/dist/src/search/vector.d.ts +8 -0
  38. package/dist/src/search/vector.js +65 -0
  39. package/dist/src/types.d.ts +48 -0
  40. package/dist/src/types.js +2 -0
  41. package/package.json +6 -5
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const dotenv = __importStar(require("dotenv"));
37
+ const path = __importStar(require("path"));
38
+ const src_1 = require("../src");
39
+ dotenv.config({ path: path.join(__dirname, '..', '.env') });
40
+ async function basicExample() {
41
+ console.log('ThinkBase SDK - Basic Example\n');
42
+ const apiKey = process.env.OPENAI_API_KEY;
43
+ if (!apiKey || apiKey === 'your-openai-api-key-here') {
44
+ console.error('ERROR: OPENAI_API_KEY not found or using placeholder value');
45
+ console.error('Current working directory:', process.cwd());
46
+ console.error('Looking for .env at:', path.join(__dirname, '..', '.env'));
47
+ console.error('Make sure your .env file has: OPENAI_API_KEY=sk-your-actual-key');
48
+ process.exit(1);
49
+ }
50
+ console.log('✓ API key loaded:', apiKey.substring(0, 10) + '...\n');
51
+ const thinkbase = new src_1.ThinkBase();
52
+ const dataset = thinkbase.createDataset({
53
+ source: 'json',
54
+ data: [
55
+ { id: 1, title: 'Bitcoin reaches new highs', content: 'Bitcoin price surges past $50k' },
56
+ { id: 2, title: 'Ethereum updates', content: 'Ethereum 2.0 successfully deployed' },
57
+ { id: 3, title: 'New DeFi protocol', content: 'Revolutionary lending platform launches' },
58
+ { id: 4, title: 'NFT marketplace', content: 'New NFT platform sees record trading' },
59
+ { id: 5, title: 'Crypto regulation', content: 'New guidelines for crypto exchanges' }
60
+ ]
61
+ });
62
+ console.log('Syncing dataset with embeddings...');
63
+ await dataset.sync({
64
+ embedding: 'openai:text-embedding-3-small',
65
+ chunkSize: 500
66
+ });
67
+ console.log('Stats:', dataset.getStats());
68
+ console.log('\nSearching for: "bitcoin price"');
69
+ const results = await dataset.search('bitcoin price', { limit: 3 });
70
+ results.forEach((result, i) => {
71
+ console.log(`\n[${i + 1}] Score: ${result.score.toFixed(3)}`);
72
+ console.log(`Content: ${result.content}`);
73
+ });
74
+ console.log('\nBuilding context for LLM...');
75
+ const context = await dataset.context({
76
+ query: 'cryptocurrency news',
77
+ limit: 3
78
+ });
79
+ console.log('\nContext:');
80
+ console.log(context);
81
+ }
82
+ basicExample().catch(console.error);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const dotenv = __importStar(require("dotenv"));
40
+ const path = __importStar(require("path"));
41
+ const src_1 = require("../src");
42
+ const openai_1 = __importDefault(require("openai"));
43
+ dotenv.config({ path: path.join(__dirname, '..', '.env') });
44
+ async function llmContextExample() {
45
+ console.log('ThinkBase SDK - LLM Context Example\n');
46
+ const thinkbase = new src_1.ThinkBase();
47
+ const openai = new openai_1.default({ apiKey: process.env.OPENAI_API_KEY });
48
+ const dataset = thinkbase.createDataset({
49
+ source: 'json',
50
+ data: [
51
+ {
52
+ symbol: 'BTC',
53
+ name: 'Bitcoin',
54
+ price: 50000,
55
+ change24h: 5.2,
56
+ marketCap: 950000000000,
57
+ description: 'The first and largest cryptocurrency by market cap'
58
+ },
59
+ {
60
+ symbol: 'ETH',
61
+ name: 'Ethereum',
62
+ price: 3000,
63
+ change24h: 3.8,
64
+ marketCap: 360000000000,
65
+ description: 'Leading smart contract platform'
66
+ },
67
+ {
68
+ symbol: 'SOL',
69
+ name: 'Solana',
70
+ price: 100,
71
+ change24h: -2.1,
72
+ marketCap: 45000000000,
73
+ description: 'High-performance blockchain for DeFi and NFTs'
74
+ }
75
+ ]
76
+ });
77
+ console.log('Syncing dataset...');
78
+ await dataset.sync({
79
+ embedding: 'openai:text-embedding-3-small',
80
+ chunkSize: 500
81
+ });
82
+ console.log('Building context for LLM...');
83
+ const context = await dataset.context({
84
+ query: 'top performing cryptocurrencies',
85
+ limit: 3,
86
+ maxTokens: 2000
87
+ });
88
+ console.log('\nContext prepared for LLM:');
89
+ console.log(context);
90
+ console.log('\nSending to GPT-4...');
91
+ const response = await openai.chat.completions.create({
92
+ model: 'gpt-4',
93
+ messages: [
94
+ {
95
+ role: 'system',
96
+ content: `You are a crypto market analyst. Use this context:\n\n${context}`
97
+ },
98
+ {
99
+ role: 'user',
100
+ content: 'What are the key insights about these cryptocurrencies?'
101
+ }
102
+ ]
103
+ });
104
+ console.log('\nAI Response:');
105
+ console.log(response.choices[0].message.content);
106
+ }
107
+ llmContextExample().catch(console.error);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const dotenv = __importStar(require("dotenv"));
37
+ const path = __importStar(require("path"));
38
+ const src_1 = require("../src");
39
+ dotenv.config({ path: path.join(__dirname, '..', '.env') });
40
+ async function postgresExample() {
41
+ console.log('ThinkBase SDK - PostgreSQL Example\n');
42
+ const thinkbase = new src_1.ThinkBase();
43
+ const dataset = thinkbase.createDataset({
44
+ source: 'postgres',
45
+ connection: process.env.DATABASE_URL || 'postgresql://localhost:5432/mydb',
46
+ query: 'SELECT * FROM products WHERE active = true'
47
+ });
48
+ console.log('Connecting to PostgreSQL...');
49
+ await dataset.connect();
50
+ console.log('Syncing dataset...');
51
+ await dataset.sync({
52
+ embedding: 'openai:text-embedding-3-small',
53
+ chunkSize: 1000,
54
+ batchSize: 50
55
+ });
56
+ console.log('Dataset stats:', dataset.getStats());
57
+ console.log('\nSearching for: "best selling products"');
58
+ const searchResults = await dataset.search('best selling products', {
59
+ limit: 5,
60
+ threshold: 0.7
61
+ });
62
+ searchResults.forEach((result, i) => {
63
+ console.log(`\n[${i + 1}] ${result.score.toFixed(3)}`);
64
+ console.log(result.content);
65
+ });
66
+ console.log('\nAsking natural language query...');
67
+ const queryResult = await dataset.ask('What are the top 5 most expensive products?');
68
+ console.log('\nGenerated SQL:', queryResult.sql);
69
+ console.log('Results:', JSON.stringify(queryResult.data, null, 2));
70
+ await dataset.disconnect();
71
+ console.log('\nDisconnected from database');
72
+ }
73
+ postgresExample().catch(console.error);
@@ -0,0 +1,8 @@
1
+ import { Dataset } from './dataset';
2
+ import { ThinkBaseConfig, DataSourceConfig } from './types';
3
+ export declare class ThinkBase {
4
+ private config;
5
+ constructor(config?: ThinkBaseConfig);
6
+ createDataset(config: DataSourceConfig): Dataset;
7
+ getConfig(): ThinkBaseConfig;
8
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ThinkBase = void 0;
4
+ const dataset_1 = require("./dataset");
5
+ class ThinkBase {
6
+ constructor(config = {}) {
7
+ this.config = config;
8
+ }
9
+ createDataset(config) {
10
+ return new dataset_1.Dataset(config);
11
+ }
12
+ getConfig() {
13
+ return this.config;
14
+ }
15
+ }
16
+ exports.ThinkBase = ThinkBase;
@@ -0,0 +1,9 @@
1
+ import { DataSourceConfig } from '../types';
2
+ export declare abstract class DataConnector {
3
+ protected config: DataSourceConfig;
4
+ constructor(config: DataSourceConfig);
5
+ abstract connect(): Promise<void>;
6
+ abstract disconnect(): Promise<void>;
7
+ abstract fetchData(): Promise<any[]>;
8
+ abstract getName(): string;
9
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataConnector = void 0;
4
+ class DataConnector {
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ }
9
+ exports.DataConnector = DataConnector;
@@ -0,0 +1,5 @@
1
+ import { DataConnector } from './base';
2
+ import { DataSourceConfig } from '../types';
3
+ export declare class ConnectorFactory {
4
+ static create(config: DataSourceConfig): DataConnector;
5
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConnectorFactory = void 0;
4
+ const postgres_1 = require("./postgres");
5
+ const mysql_1 = require("./mysql");
6
+ const mongodb_1 = require("./mongodb");
7
+ const rest_1 = require("./rest");
8
+ const json_1 = require("./json");
9
+ class ConnectorFactory {
10
+ static create(config) {
11
+ switch (config.source) {
12
+ case 'postgres':
13
+ return new postgres_1.PostgresConnector(config);
14
+ case 'mysql':
15
+ return new mysql_1.MySQLConnector(config);
16
+ case 'mongodb':
17
+ return new mongodb_1.MongoDBConnector(config);
18
+ case 'rest':
19
+ case 'graphql':
20
+ return new rest_1.RESTConnector(config);
21
+ case 'json':
22
+ case 'csv':
23
+ return new json_1.JSONConnector(config);
24
+ default:
25
+ throw new Error(`Unsupported data source: ${config.source}`);
26
+ }
27
+ }
28
+ }
29
+ exports.ConnectorFactory = ConnectorFactory;
@@ -0,0 +1,7 @@
1
+ import { DataConnector } from './base';
2
+ export declare class JSONConnector extends DataConnector {
3
+ connect(): Promise<void>;
4
+ disconnect(): Promise<void>;
5
+ fetchData(): Promise<any[]>;
6
+ getName(): string;
7
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JSONConnector = void 0;
4
+ const base_1 = require("./base");
5
+ class JSONConnector extends base_1.DataConnector {
6
+ async connect() {
7
+ // No connection needed for in-memory data
8
+ }
9
+ async disconnect() {
10
+ // No connection to close
11
+ }
12
+ async fetchData() {
13
+ if (!this.config.data) {
14
+ throw new Error('JSON data is required');
15
+ }
16
+ return Array.isArray(this.config.data) ? this.config.data : [this.config.data];
17
+ }
18
+ getName() {
19
+ return 'JSON';
20
+ }
21
+ }
22
+ exports.JSONConnector = JSONConnector;
@@ -0,0 +1,9 @@
1
+ import { DataConnector } from './base';
2
+ export declare class MongoDBConnector extends DataConnector {
3
+ private client;
4
+ private db;
5
+ connect(): Promise<void>;
6
+ disconnect(): Promise<void>;
7
+ fetchData(): Promise<any[]>;
8
+ getName(): string;
9
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoDBConnector = void 0;
4
+ const mongodb_1 = require("mongodb");
5
+ const base_1 = require("./base");
6
+ class MongoDBConnector extends base_1.DataConnector {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.client = null;
10
+ this.db = null;
11
+ }
12
+ async connect() {
13
+ if (!this.config.connection) {
14
+ throw new Error('MongoDB connection string is required');
15
+ }
16
+ this.client = new mongodb_1.MongoClient(this.config.connection);
17
+ await this.client.connect();
18
+ this.db = this.client.db();
19
+ }
20
+ async disconnect() {
21
+ if (this.client) {
22
+ await this.client.close();
23
+ this.client = null;
24
+ this.db = null;
25
+ }
26
+ }
27
+ async fetchData() {
28
+ if (!this.db) {
29
+ throw new Error('Not connected to MongoDB');
30
+ }
31
+ const collection = this.config.collection || 'data';
32
+ const documents = await this.db.collection(collection).find({}).toArray();
33
+ return documents;
34
+ }
35
+ getName() {
36
+ return 'MongoDB';
37
+ }
38
+ }
39
+ exports.MongoDBConnector = MongoDBConnector;
@@ -0,0 +1,8 @@
1
+ import { DataConnector } from './base';
2
+ export declare class MySQLConnector extends DataConnector {
3
+ private connection;
4
+ connect(): Promise<void>;
5
+ disconnect(): Promise<void>;
6
+ fetchData(): Promise<any[]>;
7
+ getName(): string;
8
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MySQLConnector = void 0;
7
+ const promise_1 = __importDefault(require("mysql2/promise"));
8
+ const base_1 = require("./base");
9
+ class MySQLConnector extends base_1.DataConnector {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.connection = null;
13
+ }
14
+ async connect() {
15
+ if (!this.config.connection) {
16
+ throw new Error('MySQL connection string is required');
17
+ }
18
+ this.connection = await promise_1.default.createConnection(this.config.connection);
19
+ }
20
+ async disconnect() {
21
+ if (this.connection) {
22
+ await this.connection.end();
23
+ this.connection = null;
24
+ }
25
+ }
26
+ async fetchData() {
27
+ if (!this.connection) {
28
+ throw new Error('Not connected to MySQL');
29
+ }
30
+ const query = this.config.query || `SELECT * FROM ${this.config.table || 'data'}`;
31
+ const [rows] = await this.connection.execute(query);
32
+ return rows;
33
+ }
34
+ getName() {
35
+ return 'MySQL';
36
+ }
37
+ }
38
+ exports.MySQLConnector = MySQLConnector;
@@ -0,0 +1,8 @@
1
+ import { DataConnector } from './base';
2
+ export declare class PostgresConnector extends DataConnector {
3
+ private pool;
4
+ connect(): Promise<void>;
5
+ disconnect(): Promise<void>;
6
+ fetchData(): Promise<any[]>;
7
+ getName(): string;
8
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostgresConnector = void 0;
4
+ const pg_1 = require("pg");
5
+ const base_1 = require("./base");
6
+ class PostgresConnector extends base_1.DataConnector {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.pool = null;
10
+ }
11
+ async connect() {
12
+ if (!this.config.connection) {
13
+ throw new Error('PostgreSQL connection string is required');
14
+ }
15
+ this.pool = new pg_1.Pool({ connectionString: this.config.connection });
16
+ }
17
+ async disconnect() {
18
+ if (this.pool) {
19
+ await this.pool.end();
20
+ this.pool = null;
21
+ }
22
+ }
23
+ async fetchData() {
24
+ if (!this.pool) {
25
+ throw new Error('Not connected to PostgreSQL');
26
+ }
27
+ const query = this.config.query || `SELECT * FROM ${this.config.table || 'data'}`;
28
+ const result = await this.pool.query(query);
29
+ return result.rows;
30
+ }
31
+ getName() {
32
+ return 'PostgreSQL';
33
+ }
34
+ }
35
+ exports.PostgresConnector = PostgresConnector;
@@ -0,0 +1,7 @@
1
+ import { DataConnector } from './base';
2
+ export declare class RESTConnector extends DataConnector {
3
+ connect(): Promise<void>;
4
+ disconnect(): Promise<void>;
5
+ fetchData(): Promise<any[]>;
6
+ getName(): string;
7
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RESTConnector = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const base_1 = require("./base");
9
+ class RESTConnector extends base_1.DataConnector {
10
+ async connect() {
11
+ // No persistent connection needed for REST
12
+ }
13
+ async disconnect() {
14
+ // No persistent connection to close
15
+ }
16
+ async fetchData() {
17
+ if (!this.config.url) {
18
+ throw new Error('REST API URL is required');
19
+ }
20
+ const response = await axios_1.default.get(this.config.url);
21
+ return Array.isArray(response.data) ? response.data : [response.data];
22
+ }
23
+ getName() {
24
+ return 'REST API';
25
+ }
26
+ }
27
+ exports.RESTConnector = RESTConnector;
@@ -0,0 +1,11 @@
1
+ import { SearchResult, ContextOptions } from '../types';
2
+ import { DataChunk } from '../types';
3
+ export declare class ContextBuilder {
4
+ private search;
5
+ private embedder;
6
+ constructor(chunks: DataChunk[], embeddingModel: string);
7
+ build(options: ContextOptions): Promise<string>;
8
+ private formatContext;
9
+ private estimateTokens;
10
+ buildStructured(options: ContextOptions): Promise<SearchResult[]>;
11
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextBuilder = void 0;
4
+ const embedder_1 = require("../embedding/embedder");
5
+ const vector_1 = require("../search/vector");
6
+ class ContextBuilder {
7
+ constructor(chunks, embeddingModel) {
8
+ this.search = new vector_1.VectorSearch(chunks);
9
+ this.embedder = new embedder_1.Embedder(embeddingModel);
10
+ }
11
+ async build(options) {
12
+ const queryEmbedding = await this.embedder.embed(options.query);
13
+ const results = this.search.search(queryEmbedding, options.limit || 5, 0.5);
14
+ return this.formatContext(results, options);
15
+ }
16
+ formatContext(results, options) {
17
+ const maxTokens = options.maxTokens || 4000;
18
+ let context = `Relevant context for: "${options.query}"\n\n`;
19
+ let currentTokens = this.estimateTokens(context);
20
+ for (let i = 0; i < results.length; i++) {
21
+ const result = results[i];
22
+ const chunk = `[${i + 1}] (score: ${result.score.toFixed(3)})\n${result.content}\n\n`;
23
+ const chunkTokens = this.estimateTokens(chunk);
24
+ if (currentTokens + chunkTokens > maxTokens) {
25
+ break;
26
+ }
27
+ context += chunk;
28
+ currentTokens += chunkTokens;
29
+ }
30
+ return context.trim();
31
+ }
32
+ estimateTokens(text) {
33
+ return Math.ceil(text.length / 4);
34
+ }
35
+ async buildStructured(options) {
36
+ const queryEmbedding = await this.embedder.embed(options.query);
37
+ return this.search.search(queryEmbedding, options.limit || 5, 0.5);
38
+ }
39
+ }
40
+ exports.ContextBuilder = ContextBuilder;
@@ -0,0 +1,21 @@
1
+ import { DataSourceConfig, EmbeddingConfig, SearchOptions, ContextOptions, DataChunk, SearchResult, QueryResult } from './types';
2
+ export declare class Dataset {
3
+ private connector;
4
+ private chunks;
5
+ private embeddingConfig?;
6
+ private nlQuery?;
7
+ private contextBuilder?;
8
+ constructor(config: DataSourceConfig);
9
+ connect(): Promise<void>;
10
+ disconnect(): Promise<void>;
11
+ sync(config: EmbeddingConfig): Promise<void>;
12
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
13
+ ask(query: string): Promise<QueryResult>;
14
+ context(options: ContextOptions): Promise<string>;
15
+ contextStructured(options: ContextOptions): Promise<SearchResult[]>;
16
+ getChunks(): DataChunk[];
17
+ getStats(): {
18
+ totalChunks: number;
19
+ totalDocuments: number;
20
+ };
21
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Dataset = void 0;
4
+ const factory_1 = require("./connectors/factory");
5
+ const pipeline_1 = require("./embedding/pipeline");
6
+ const vector_1 = require("./search/vector");
7
+ const natural_language_1 = require("./query/natural-language");
8
+ const builder_1 = require("./context/builder");
9
+ const embedder_1 = require("./embedding/embedder");
10
+ class Dataset {
11
+ constructor(config) {
12
+ this.chunks = [];
13
+ this.connector = factory_1.ConnectorFactory.create(config);
14
+ }
15
+ async connect() {
16
+ await this.connector.connect();
17
+ }
18
+ async disconnect() {
19
+ await this.connector.disconnect();
20
+ }
21
+ async sync(config) {
22
+ this.embeddingConfig = config;
23
+ await this.connector.connect();
24
+ const data = await this.connector.fetchData();
25
+ await this.connector.disconnect();
26
+ const pipeline = new pipeline_1.EmbeddingPipeline(config);
27
+ this.chunks = await pipeline.process(data);
28
+ this.contextBuilder = new builder_1.ContextBuilder(this.chunks, config.embedding);
29
+ this.nlQuery = new natural_language_1.NaturalLanguageQuery();
30
+ }
31
+ async search(query, options = {}) {
32
+ if (!this.embeddingConfig) {
33
+ throw new Error('Dataset not synced. Call sync() first.');
34
+ }
35
+ const embedder = new embedder_1.Embedder(this.embeddingConfig.embedding);
36
+ const queryEmbedding = await embedder.embed(query);
37
+ const search = new vector_1.VectorSearch(this.chunks);
38
+ if (options.hybrid) {
39
+ const keywords = query.toLowerCase().split(' ');
40
+ return search.hybridSearch(queryEmbedding, keywords, options.limit || 10, 0.7);
41
+ }
42
+ return search.search(queryEmbedding, options.limit || 10, options.threshold || 0.7);
43
+ }
44
+ async ask(query) {
45
+ if (!this.nlQuery) {
46
+ this.nlQuery = new natural_language_1.NaturalLanguageQuery();
47
+ }
48
+ await this.connector.connect();
49
+ try {
50
+ const result = await this.nlQuery.executeQuery(query, async (sql) => {
51
+ return await this.connector.fetchData();
52
+ });
53
+ await this.connector.disconnect();
54
+ return result;
55
+ }
56
+ catch (error) {
57
+ await this.connector.disconnect();
58
+ throw error;
59
+ }
60
+ }
61
+ async context(options) {
62
+ if (!this.contextBuilder) {
63
+ throw new Error('Dataset not synced. Call sync() first.');
64
+ }
65
+ return this.contextBuilder.build(options);
66
+ }
67
+ async contextStructured(options) {
68
+ if (!this.contextBuilder) {
69
+ throw new Error('Dataset not synced. Call sync() first.');
70
+ }
71
+ return this.contextBuilder.buildStructured(options);
72
+ }
73
+ getChunks() {
74
+ return this.chunks;
75
+ }
76
+ getStats() {
77
+ return {
78
+ totalChunks: this.chunks.length,
79
+ totalDocuments: this.chunks.length
80
+ };
81
+ }
82
+ }
83
+ exports.Dataset = Dataset;
@@ -0,0 +1,10 @@
1
+ export declare class TextChunker {
2
+ private chunkSize;
3
+ private chunkOverlap;
4
+ constructor(chunkSize?: number, chunkOverlap?: number);
5
+ chunk(text: string): string[];
6
+ chunkDocuments(documents: any[]): Array<{
7
+ content: string;
8
+ metadata: any;
9
+ }>;
10
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TextChunker = void 0;
4
+ class TextChunker {
5
+ constructor(chunkSize = 1000, chunkOverlap = 200) {
6
+ this.chunkSize = chunkSize;
7
+ this.chunkOverlap = chunkOverlap;
8
+ }
9
+ chunk(text) {
10
+ const chunks = [];
11
+ let start = 0;
12
+ while (start < text.length) {
13
+ const end = Math.min(start + this.chunkSize, text.length);
14
+ let chunk = text.slice(start, end);
15
+ if (end < text.length) {
16
+ const lastSpace = chunk.lastIndexOf(' ');
17
+ if (lastSpace > 0) {
18
+ chunk = chunk.slice(0, lastSpace);
19
+ }
20
+ }
21
+ chunks.push(chunk.trim());
22
+ start += this.chunkSize - this.chunkOverlap;
23
+ }
24
+ return chunks.filter(c => c.length > 0);
25
+ }
26
+ chunkDocuments(documents) {
27
+ const chunkedDocs = [];
28
+ for (const doc of documents) {
29
+ const text = typeof doc === 'string' ? doc : JSON.stringify(doc);
30
+ const chunks = this.chunk(text);
31
+ for (const chunk of chunks) {
32
+ chunkedDocs.push({
33
+ content: chunk,
34
+ metadata: typeof doc === 'object' ? doc : {}
35
+ });
36
+ }
37
+ }
38
+ return chunkedDocs;
39
+ }
40
+ }
41
+ exports.TextChunker = TextChunker;
@@ -0,0 +1,9 @@
1
+ export declare class Embedder {
2
+ private model;
3
+ private client;
4
+ constructor(model: string);
5
+ private isOpenAIModel;
6
+ private getModelName;
7
+ embed(text: string): Promise<number[]>;
8
+ embedBatch(texts: string[], batchSize?: number): Promise<number[][]>;
9
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Embedder = void 0;
7
+ const openai_1 = __importDefault(require("openai"));
8
+ class Embedder {
9
+ constructor(model) {
10
+ this.client = null;
11
+ this.model = model;
12
+ if (this.isOpenAIModel()) {
13
+ const apiKey = process.env.OPENAI_API_KEY;
14
+ if (!apiKey) {
15
+ throw new Error('OPENAI_API_KEY is not set in environment variables. ' +
16
+ 'Please add it to your .env file: OPENAI_API_KEY=sk-your-key-here');
17
+ }
18
+ this.client = new openai_1.default({
19
+ apiKey: apiKey
20
+ });
21
+ }
22
+ }
23
+ isOpenAIModel() {
24
+ return this.model.startsWith('openai:');
25
+ }
26
+ getModelName() {
27
+ return this.model.replace('openai:', '');
28
+ }
29
+ async embed(text) {
30
+ if (this.isOpenAIModel() && this.client) {
31
+ const response = await this.client.embeddings.create({
32
+ model: this.getModelName(),
33
+ input: text
34
+ });
35
+ return response.data[0].embedding;
36
+ }
37
+ throw new Error(`Unsupported embedding model: ${this.model}`);
38
+ }
39
+ async embedBatch(texts, batchSize = 100) {
40
+ const embeddings = [];
41
+ for (let i = 0; i < texts.length; i += batchSize) {
42
+ const batch = texts.slice(i, i + batchSize);
43
+ if (this.isOpenAIModel() && this.client) {
44
+ const response = await this.client.embeddings.create({
45
+ model: this.getModelName(),
46
+ input: batch
47
+ });
48
+ embeddings.push(...response.data.map(d => d.embedding));
49
+ }
50
+ }
51
+ return embeddings;
52
+ }
53
+ }
54
+ exports.Embedder = Embedder;
@@ -0,0 +1,8 @@
1
+ import { DataChunk, EmbeddingConfig } from '../types';
2
+ export declare class EmbeddingPipeline {
3
+ private chunker;
4
+ private embedder;
5
+ private config;
6
+ constructor(config: EmbeddingConfig);
7
+ process(documents: any[]): Promise<DataChunk[]>;
8
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmbeddingPipeline = void 0;
4
+ const chunker_1 = require("./chunker");
5
+ const embedder_1 = require("./embedder");
6
+ class EmbeddingPipeline {
7
+ constructor(config) {
8
+ this.config = config;
9
+ this.chunker = new chunker_1.TextChunker(config.chunkSize || 1000, config.chunkOverlap || 200);
10
+ this.embedder = new embedder_1.Embedder(config.embedding);
11
+ }
12
+ async process(documents) {
13
+ const chunked = this.chunker.chunkDocuments(documents);
14
+ const texts = chunked.map(doc => doc.content);
15
+ const embeddings = await this.embedder.embedBatch(texts, this.config.batchSize || 100);
16
+ return chunked.map((doc, index) => ({
17
+ id: `chunk_${index}`,
18
+ content: doc.content,
19
+ embedding: embeddings[index],
20
+ metadata: doc.metadata
21
+ }));
22
+ }
23
+ }
24
+ exports.EmbeddingPipeline = EmbeddingPipeline;
@@ -0,0 +1,3 @@
1
+ export { ThinkBase } from './client';
2
+ export { Dataset } from './dataset';
3
+ export * from './types';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Dataset = exports.ThinkBase = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "ThinkBase", { enumerable: true, get: function () { return client_1.ThinkBase; } });
20
+ var dataset_1 = require("./dataset");
21
+ Object.defineProperty(exports, "Dataset", { enumerable: true, get: function () { return dataset_1.Dataset; } });
22
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,9 @@
1
+ import { QueryResult } from '../types';
2
+ export declare class NaturalLanguageQuery {
3
+ private client;
4
+ private schema;
5
+ constructor(schema?: any);
6
+ setSchema(schema: any): void;
7
+ translateToSQL(query: string, dialect?: string): Promise<string>;
8
+ executeQuery(query: string, executor: (sql: string) => Promise<any[]>): Promise<QueryResult>;
9
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NaturalLanguageQuery = void 0;
7
+ const openai_1 = __importDefault(require("openai"));
8
+ class NaturalLanguageQuery {
9
+ constructor(schema) {
10
+ this.client = new openai_1.default({
11
+ apiKey: process.env.OPENAI_API_KEY
12
+ });
13
+ this.schema = schema;
14
+ }
15
+ setSchema(schema) {
16
+ this.schema = schema;
17
+ }
18
+ async translateToSQL(query, dialect = 'postgres') {
19
+ const schemaContext = this.schema
20
+ ? `Database schema:\n${JSON.stringify(this.schema, null, 2)}\n\n`
21
+ : '';
22
+ const prompt = `${schemaContext}Convert this natural language query to ${dialect} SQL:
23
+ "${query}"
24
+
25
+ Return ONLY the SQL query, no explanations.`;
26
+ const response = await this.client.chat.completions.create({
27
+ model: 'gpt-4o-mini',
28
+ messages: [{ role: 'user', content: prompt }],
29
+ temperature: 0
30
+ });
31
+ return response.choices[0].message.content?.trim() || '';
32
+ }
33
+ async executeQuery(query, executor) {
34
+ const sql = await this.translateToSQL(query);
35
+ try {
36
+ const data = await executor(sql);
37
+ return { data, sql };
38
+ }
39
+ catch (error) {
40
+ throw new Error(`Query execution failed: ${error.message}`);
41
+ }
42
+ }
43
+ }
44
+ exports.NaturalLanguageQuery = NaturalLanguageQuery;
@@ -0,0 +1,8 @@
1
+ import { DataChunk, SearchResult } from '../types';
2
+ export declare class VectorSearch {
3
+ private chunks;
4
+ constructor(chunks: DataChunk[]);
5
+ cosineSimilarity(a: number[], b: number[]): number;
6
+ search(queryEmbedding: number[], limit?: number, threshold?: number): SearchResult[];
7
+ hybridSearch(queryEmbedding: number[], keywords: string[], limit?: number, vectorWeight?: number): SearchResult[];
8
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VectorSearch = void 0;
4
+ class VectorSearch {
5
+ constructor(chunks) {
6
+ this.chunks = chunks;
7
+ }
8
+ cosineSimilarity(a, b) {
9
+ if (a.length !== b.length) {
10
+ throw new Error('Vectors must have the same length');
11
+ }
12
+ let dotProduct = 0;
13
+ let normA = 0;
14
+ let normB = 0;
15
+ for (let i = 0; i < a.length; i++) {
16
+ dotProduct += a[i] * b[i];
17
+ normA += a[i] * a[i];
18
+ normB += b[i] * b[i];
19
+ }
20
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
21
+ }
22
+ search(queryEmbedding, limit = 5, threshold = 0.7) {
23
+ const results = [];
24
+ for (const chunk of this.chunks) {
25
+ if (!chunk.embedding)
26
+ continue;
27
+ const score = this.cosineSimilarity(queryEmbedding, chunk.embedding);
28
+ if (score >= threshold) {
29
+ results.push({
30
+ id: chunk.id,
31
+ content: chunk.content,
32
+ score,
33
+ metadata: chunk.metadata
34
+ });
35
+ }
36
+ }
37
+ return results
38
+ .sort((a, b) => b.score - a.score)
39
+ .slice(0, limit);
40
+ }
41
+ hybridSearch(queryEmbedding, keywords, limit = 5, vectorWeight = 0.7) {
42
+ const results = [];
43
+ const keywordWeight = 1 - vectorWeight;
44
+ for (const chunk of this.chunks) {
45
+ if (!chunk.embedding)
46
+ continue;
47
+ const vectorScore = this.cosineSimilarity(queryEmbedding, chunk.embedding);
48
+ const lowerContent = chunk.content.toLowerCase();
49
+ const keywordScore = keywords.reduce((score, keyword) => {
50
+ return score + (lowerContent.includes(keyword.toLowerCase()) ? 1 : 0);
51
+ }, 0) / keywords.length;
52
+ const combinedScore = (vectorScore * vectorWeight) + (keywordScore * keywordWeight);
53
+ results.push({
54
+ id: chunk.id,
55
+ content: chunk.content,
56
+ score: combinedScore,
57
+ metadata: chunk.metadata
58
+ });
59
+ }
60
+ return results
61
+ .sort((a, b) => b.score - a.score)
62
+ .slice(0, limit);
63
+ }
64
+ }
65
+ exports.VectorSearch = VectorSearch;
@@ -0,0 +1,48 @@
1
+ export interface ThinkBaseConfig {
2
+ apiKey?: string;
3
+ apiUrl?: string;
4
+ }
5
+ export type DataSourceType = 'postgres' | 'mysql' | 'mongodb' | 'rest' | 'graphql' | 'csv' | 'json' | 'webscrape';
6
+ export interface DataSourceConfig {
7
+ source: DataSourceType;
8
+ connection?: string;
9
+ url?: string;
10
+ data?: any;
11
+ query?: string;
12
+ collection?: string;
13
+ table?: string;
14
+ }
15
+ export interface EmbeddingConfig {
16
+ embedding: string;
17
+ chunkSize?: number;
18
+ chunkOverlap?: number;
19
+ batchSize?: number;
20
+ }
21
+ export interface SearchOptions {
22
+ limit?: number;
23
+ threshold?: number;
24
+ filter?: Record<string, any>;
25
+ hybrid?: boolean;
26
+ }
27
+ export interface ContextOptions {
28
+ query: string;
29
+ limit?: number;
30
+ maxTokens?: number;
31
+ }
32
+ export interface DataChunk {
33
+ id: string;
34
+ content: string;
35
+ embedding?: number[];
36
+ metadata?: Record<string, any>;
37
+ }
38
+ export interface SearchResult {
39
+ id: string;
40
+ content: string;
41
+ score: number;
42
+ metadata?: Record<string, any>;
43
+ }
44
+ export interface QueryResult {
45
+ data: any[];
46
+ sql?: string;
47
+ metadata?: Record<string, any>;
48
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkbase/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "ThinkBase SDK - Turn any data into structured, searchable, and AI-ready context with a single API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,11 +25,12 @@
25
25
  "author": "ThinkBase",
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "openai": "^4.68.4",
29
- "pg": "^8.13.1",
30
- "mysql2": "^3.11.5",
28
+ "axios": "^1.7.9",
29
+ "dotenv": "^17.3.1",
31
30
  "mongodb": "^6.10.0",
32
- "axios": "^1.7.9"
31
+ "mysql2": "^3.11.5",
32
+ "openai": "^4.68.4",
33
+ "pg": "^8.13.1"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/node": "^22.10.2",