neuralex 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +269 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +188 -0
- package/dist/index.mjs +147 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NeuraLex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# NeuraLex JavaScript/TypeScript Client
|
|
2
|
+
|
|
3
|
+
Official TypeScript/JavaScript client library for the [NeuraLex](https://neuralex.ca) API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install neuralex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add neuralex
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { NeuraLexClient } from 'neuralex';
|
|
21
|
+
|
|
22
|
+
// Initialize client with your API key
|
|
23
|
+
const client = new NeuraLexClient({ apiKey: 'nlx_your_api_key' });
|
|
24
|
+
|
|
25
|
+
// Generate embeddings
|
|
26
|
+
const response = await client.embed('Hello, world!');
|
|
27
|
+
|
|
28
|
+
// Access the embedding vector
|
|
29
|
+
const embedding = response.payload[0].embedding;
|
|
30
|
+
console.log(`Dimensions: ${embedding.length}`);
|
|
31
|
+
console.log(`First 5 values: ${embedding.slice(0, 5)}`);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- ✅ TypeScript support with full type definitions
|
|
37
|
+
- ✅ Promise-based async API
|
|
38
|
+
- ✅ Automatic error handling
|
|
39
|
+
- ✅ Configurable semantic/term-based balance
|
|
40
|
+
- ✅ Batch embedding support (up to 100 inputs)
|
|
41
|
+
- ✅ Tree-shakeable ESM and CommonJS builds
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
### Basic Usage
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { NeuraLexClient } from 'neuralex';
|
|
49
|
+
|
|
50
|
+
const client = new NeuraLexClient({ apiKey: 'nlx_your_api_key' });
|
|
51
|
+
|
|
52
|
+
// Single text
|
|
53
|
+
const response = await client.embed('Machine learning is fascinating');
|
|
54
|
+
const embedding = response.payload[0].embedding;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Batch Embeddings
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Multiple texts
|
|
61
|
+
const texts = [
|
|
62
|
+
'First document',
|
|
63
|
+
'Second document',
|
|
64
|
+
'Third document'
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const response = await client.embed(texts);
|
|
68
|
+
|
|
69
|
+
response.payload.forEach((item) => {
|
|
70
|
+
console.log(`Text: ${item.text}`);
|
|
71
|
+
console.log(`Embedding dimensions: ${item.embedding.length}`);
|
|
72
|
+
console.log(`Tokens used: ${item.usage.totalTokens}`);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Adjusting Semantic Weight
|
|
77
|
+
|
|
78
|
+
The `semanticWeight` parameter controls the balance between term-based and semantic embeddings:
|
|
79
|
+
- `0.0` = Pure term-based (exact keyword matching)
|
|
80
|
+
- `1.0` = Pure semantic (meaning-based)
|
|
81
|
+
- `0.5` = Balanced (default)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// More term-focused (better for keyword search)
|
|
85
|
+
const response = await client.embed('Python programming', {
|
|
86
|
+
semanticWeight: 0.3
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// More semantic-focused (better for meaning-based search)
|
|
90
|
+
const response = await client.embed('Python programming', {
|
|
91
|
+
semanticWeight: 0.8
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Error Handling
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import {
|
|
99
|
+
NeuraLexClient,
|
|
100
|
+
AuthenticationError,
|
|
101
|
+
RateLimitError,
|
|
102
|
+
APIError
|
|
103
|
+
} from 'neuralex';
|
|
104
|
+
|
|
105
|
+
const client = new NeuraLexClient({ apiKey: 'nlx_your_api_key' });
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const response = await client.embed('Hello, world!');
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (error instanceof AuthenticationError) {
|
|
111
|
+
console.error('Invalid API key');
|
|
112
|
+
} else if (error instanceof RateLimitError) {
|
|
113
|
+
console.error('Rate limit exceeded, please wait');
|
|
114
|
+
} else if (error instanceof APIError) {
|
|
115
|
+
console.error(`API error: ${error.message} (status: ${error.statusCode})`);
|
|
116
|
+
} else {
|
|
117
|
+
console.error(`Unexpected error: ${error}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Using with JavaScript (CommonJS)
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
const { NeuraLexClient } = require('neuralex');
|
|
126
|
+
|
|
127
|
+
const client = new NeuraLexClient({ apiKey: 'nlx_your_api_key' });
|
|
128
|
+
|
|
129
|
+
async function main() {
|
|
130
|
+
const response = await client.embed('Hello, world!');
|
|
131
|
+
console.log(response.payload[0].embedding.slice(0, 5));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
main();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API Reference
|
|
138
|
+
|
|
139
|
+
### `NeuraLexClient`
|
|
140
|
+
|
|
141
|
+
Main client class for API interactions.
|
|
142
|
+
|
|
143
|
+
**Constructor:**
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
new NeuraLexClient(config: NeuraLexClientConfig)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Config Options:**
|
|
150
|
+
|
|
151
|
+
- `apiKey` (string, required): Your NeuraLex API key
|
|
152
|
+
- `baseUrl` (string, optional): Base URL for the API (default: "https://api.neuralex.ca")
|
|
153
|
+
- `timeout` (number, optional): Request timeout in milliseconds (default: 30000)
|
|
154
|
+
|
|
155
|
+
**Methods:**
|
|
156
|
+
|
|
157
|
+
#### `embed(inputs, options?)`
|
|
158
|
+
|
|
159
|
+
Generate embeddings for text input(s).
|
|
160
|
+
|
|
161
|
+
**Parameters:**
|
|
162
|
+
|
|
163
|
+
- `inputs` (string | string[]): Text or array of texts to embed (max 100)
|
|
164
|
+
- `options` (object, optional):
|
|
165
|
+
- `model` (string): Model name (default: "public")
|
|
166
|
+
- `language` (string): Language for lexeme extraction (default: "english")
|
|
167
|
+
- `semanticWeight` (number): Balance between term (0.0) and semantic (1.0) (default: 0.5)
|
|
168
|
+
|
|
169
|
+
**Returns:** `Promise<EmbeddingResponse>`
|
|
170
|
+
|
|
171
|
+
### Types
|
|
172
|
+
|
|
173
|
+
#### `EmbeddingResponse`
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
interface EmbeddingResponse {
|
|
177
|
+
payload: EmbeddingData[];
|
|
178
|
+
model: string;
|
|
179
|
+
totalUsage: Usage;
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### `EmbeddingData`
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
interface EmbeddingData {
|
|
187
|
+
text: string;
|
|
188
|
+
embedding: number[];
|
|
189
|
+
usage: Usage;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### `Usage`
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
interface Usage {
|
|
197
|
+
totalTokens: number;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Error Classes
|
|
202
|
+
|
|
203
|
+
- `NeuraLexError` - Base error class
|
|
204
|
+
- `AuthenticationError` - Invalid or missing API key
|
|
205
|
+
- `RateLimitError` - Rate limit exceeded
|
|
206
|
+
- `APIError` - API error response (includes `statusCode` and `responseData`)
|
|
207
|
+
|
|
208
|
+
## Getting an API Key
|
|
209
|
+
|
|
210
|
+
1. Sign up at [app.neuralex.ca](https://app.neuralex.ca)
|
|
211
|
+
2. Generate a new API key
|
|
212
|
+
3. Keep your API key secure and never commit it to version control
|
|
213
|
+
|
|
214
|
+
## Examples
|
|
215
|
+
|
|
216
|
+
### Semantic Search
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { NeuraLexClient } from 'neuralex';
|
|
220
|
+
|
|
221
|
+
const client = new NeuraLexClient({ apiKey: process.env.NEURALEX_API_KEY });
|
|
222
|
+
|
|
223
|
+
// Embed documents
|
|
224
|
+
const documents = [
|
|
225
|
+
'The quick brown fox jumps over the lazy dog',
|
|
226
|
+
'Machine learning is a subset of artificial intelligence',
|
|
227
|
+
'Python is a popular programming language'
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
const docResponse = await client.embed(documents);
|
|
231
|
+
const docEmbeddings = docResponse.payload.map(d => d.embedding);
|
|
232
|
+
|
|
233
|
+
// Embed query
|
|
234
|
+
const queryResponse = await client.embed('Tell me about AI');
|
|
235
|
+
const queryEmbedding = queryResponse.payload[0].embedding;
|
|
236
|
+
|
|
237
|
+
// Compute cosine similarity (you'll need to implement this)
|
|
238
|
+
const similarities = docEmbeddings.map(docEmb =>
|
|
239
|
+
cosineSimilarity(queryEmbedding, docEmb)
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
console.log('Most similar document:', documents[similarities.indexOf(Math.max(...similarities))]);
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Integration with Vector Databases
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { NeuraLexClient } from 'neuralex';
|
|
249
|
+
// import your vector database client
|
|
250
|
+
|
|
251
|
+
const nlxClient = new NeuraLexClient({ apiKey: 'nlx_your_api_key' });
|
|
252
|
+
|
|
253
|
+
async function indexDocuments(documents: string[]) {
|
|
254
|
+
const response = await nlxClient.embed(documents);
|
|
255
|
+
|
|
256
|
+
// Store in your vector database
|
|
257
|
+
for (let i = 0; i < response.payload.length; i++) {
|
|
258
|
+
await vectorDB.insert({
|
|
259
|
+
id: i,
|
|
260
|
+
text: response.payload[i].text,
|
|
261
|
+
embedding: response.payload[i].embedding
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
MIT License - see LICENSE file for details
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
interface EmbeddingRequest {
|
|
2
|
+
inputs: string[];
|
|
3
|
+
model?: string;
|
|
4
|
+
language?: string;
|
|
5
|
+
semanticWeight?: number;
|
|
6
|
+
}
|
|
7
|
+
interface Usage {
|
|
8
|
+
totalTokens: number;
|
|
9
|
+
}
|
|
10
|
+
interface EmbeddingData {
|
|
11
|
+
text: string;
|
|
12
|
+
embedding: number[];
|
|
13
|
+
usage: Usage;
|
|
14
|
+
}
|
|
15
|
+
interface EmbeddingResponse {
|
|
16
|
+
payload: EmbeddingData[];
|
|
17
|
+
model: string;
|
|
18
|
+
totalUsage: Usage;
|
|
19
|
+
}
|
|
20
|
+
interface NeuraLexClientConfig {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
timeout?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class NeuraLexClient {
|
|
27
|
+
private client;
|
|
28
|
+
private apiKey;
|
|
29
|
+
constructor(config: NeuraLexClientConfig);
|
|
30
|
+
embed(inputs: string | string[], options?: {
|
|
31
|
+
model?: string;
|
|
32
|
+
language?: string;
|
|
33
|
+
semanticWeight?: number;
|
|
34
|
+
}): Promise<EmbeddingResponse>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare class NeuraLexError extends Error {
|
|
38
|
+
constructor(message: string);
|
|
39
|
+
}
|
|
40
|
+
declare class AuthenticationError extends NeuraLexError {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
|
43
|
+
declare class RateLimitError extends NeuraLexError {
|
|
44
|
+
constructor(message?: string);
|
|
45
|
+
}
|
|
46
|
+
declare class APIError extends NeuraLexError {
|
|
47
|
+
statusCode: number;
|
|
48
|
+
responseData: any;
|
|
49
|
+
constructor(message: string, statusCode: number, responseData?: any);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { APIError, AuthenticationError, type EmbeddingData, type EmbeddingRequest, type EmbeddingResponse, NeuraLexClient, type NeuraLexClientConfig, NeuraLexError, RateLimitError, type Usage };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
interface EmbeddingRequest {
|
|
2
|
+
inputs: string[];
|
|
3
|
+
model?: string;
|
|
4
|
+
language?: string;
|
|
5
|
+
semanticWeight?: number;
|
|
6
|
+
}
|
|
7
|
+
interface Usage {
|
|
8
|
+
totalTokens: number;
|
|
9
|
+
}
|
|
10
|
+
interface EmbeddingData {
|
|
11
|
+
text: string;
|
|
12
|
+
embedding: number[];
|
|
13
|
+
usage: Usage;
|
|
14
|
+
}
|
|
15
|
+
interface EmbeddingResponse {
|
|
16
|
+
payload: EmbeddingData[];
|
|
17
|
+
model: string;
|
|
18
|
+
totalUsage: Usage;
|
|
19
|
+
}
|
|
20
|
+
interface NeuraLexClientConfig {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
timeout?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class NeuraLexClient {
|
|
27
|
+
private client;
|
|
28
|
+
private apiKey;
|
|
29
|
+
constructor(config: NeuraLexClientConfig);
|
|
30
|
+
embed(inputs: string | string[], options?: {
|
|
31
|
+
model?: string;
|
|
32
|
+
language?: string;
|
|
33
|
+
semanticWeight?: number;
|
|
34
|
+
}): Promise<EmbeddingResponse>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare class NeuraLexError extends Error {
|
|
38
|
+
constructor(message: string);
|
|
39
|
+
}
|
|
40
|
+
declare class AuthenticationError extends NeuraLexError {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
|
43
|
+
declare class RateLimitError extends NeuraLexError {
|
|
44
|
+
constructor(message?: string);
|
|
45
|
+
}
|
|
46
|
+
declare class APIError extends NeuraLexError {
|
|
47
|
+
statusCode: number;
|
|
48
|
+
responseData: any;
|
|
49
|
+
constructor(message: string, statusCode: number, responseData?: any);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { APIError, AuthenticationError, type EmbeddingData, type EmbeddingRequest, type EmbeddingResponse, NeuraLexClient, type NeuraLexClientConfig, NeuraLexError, RateLimitError, type Usage };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
APIError: () => APIError,
|
|
34
|
+
AuthenticationError: () => AuthenticationError,
|
|
35
|
+
NeuraLexClient: () => NeuraLexClient,
|
|
36
|
+
NeuraLexError: () => NeuraLexError,
|
|
37
|
+
RateLimitError: () => RateLimitError
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
|
|
41
|
+
// src/client.ts
|
|
42
|
+
var import_axios = __toESM(require("axios"));
|
|
43
|
+
|
|
44
|
+
// src/errors.ts
|
|
45
|
+
var NeuraLexError = class _NeuraLexError extends Error {
|
|
46
|
+
constructor(message) {
|
|
47
|
+
super(message);
|
|
48
|
+
this.name = "NeuraLexError";
|
|
49
|
+
Object.setPrototypeOf(this, _NeuraLexError.prototype);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var AuthenticationError = class _AuthenticationError extends NeuraLexError {
|
|
53
|
+
constructor(message = "Authentication failed") {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = "AuthenticationError";
|
|
56
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var RateLimitError = class _RateLimitError extends NeuraLexError {
|
|
60
|
+
constructor(message = "Rate limit exceeded") {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = "RateLimitError";
|
|
63
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var APIError = class _APIError extends NeuraLexError {
|
|
67
|
+
constructor(message, statusCode, responseData = {}) {
|
|
68
|
+
super(message);
|
|
69
|
+
this.name = "APIError";
|
|
70
|
+
this.statusCode = statusCode;
|
|
71
|
+
this.responseData = responseData;
|
|
72
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/client.ts
|
|
77
|
+
var NeuraLexClient = class {
|
|
78
|
+
/**
|
|
79
|
+
* Create a new NeuraLex client
|
|
80
|
+
*
|
|
81
|
+
* @param config - Client configuration
|
|
82
|
+
* @param config.apiKey - Your NeuraLex API key (starts with 'nlx_')
|
|
83
|
+
* @param config.baseUrl - Base URL for the API (default: https://api.neuralex.ca)
|
|
84
|
+
* @param config.timeout - Request timeout in milliseconds (default: 30000)
|
|
85
|
+
*/
|
|
86
|
+
constructor(config) {
|
|
87
|
+
const { apiKey, baseUrl = "https://api.neuralex.ca", timeout = 3e4 } = config;
|
|
88
|
+
if (!apiKey) {
|
|
89
|
+
throw new AuthenticationError("API key is required");
|
|
90
|
+
}
|
|
91
|
+
if (!apiKey.startsWith("nlx_")) {
|
|
92
|
+
throw new AuthenticationError("Invalid API key format (should start with 'nlx_')");
|
|
93
|
+
}
|
|
94
|
+
this.apiKey = apiKey;
|
|
95
|
+
this.client = import_axios.default.create({
|
|
96
|
+
baseURL: baseUrl,
|
|
97
|
+
timeout,
|
|
98
|
+
headers: {
|
|
99
|
+
"X-API-Key": apiKey,
|
|
100
|
+
"Content-Type": "application/json"
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate embeddings for the provided input text(s)
|
|
106
|
+
*
|
|
107
|
+
* @param inputs - Text string or array of text strings to embed (max 100)
|
|
108
|
+
* @param options - Optional parameters
|
|
109
|
+
* @param options.model - Model name (default: "public")
|
|
110
|
+
* @param options.language - Language for lexeme extraction (default: "english")
|
|
111
|
+
* @param options.semanticWeight - Balance between term-based (0.0) and semantic (1.0) (default: 0.5)
|
|
112
|
+
* @returns Promise<EmbeddingResponse> - Embeddings and usage information
|
|
113
|
+
*
|
|
114
|
+
* @throws {AuthenticationError} Invalid or missing API key
|
|
115
|
+
* @throws {RateLimitError} Rate limit exceeded
|
|
116
|
+
* @throws {APIError} API returned an error response
|
|
117
|
+
* @throws {NeuraLexError} Other errors
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* // Single text
|
|
122
|
+
* const response = await client.embed('Hello, world!');
|
|
123
|
+
*
|
|
124
|
+
* // Multiple texts
|
|
125
|
+
* const response = await client.embed(['Text 1', 'Text 2', 'Text 3']);
|
|
126
|
+
*
|
|
127
|
+
* // With options
|
|
128
|
+
* const response = await client.embed('Python programming', {
|
|
129
|
+
* semanticWeight: 0.8,
|
|
130
|
+
* model: 'public'
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
async embed(inputs, options = {}) {
|
|
135
|
+
const inputArray = Array.isArray(inputs) ? inputs : [inputs];
|
|
136
|
+
if (inputArray.length === 0) {
|
|
137
|
+
throw new Error("At least one input is required");
|
|
138
|
+
}
|
|
139
|
+
if (inputArray.length > 100) {
|
|
140
|
+
throw new Error("Maximum 100 inputs allowed per request");
|
|
141
|
+
}
|
|
142
|
+
const request = {
|
|
143
|
+
inputs: inputArray,
|
|
144
|
+
model: options.model ?? "public",
|
|
145
|
+
language: options.language ?? "english",
|
|
146
|
+
semanticWeight: options.semanticWeight ?? 0.5
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
const response = await this.client.post(
|
|
150
|
+
"/api/v1/embed",
|
|
151
|
+
request
|
|
152
|
+
);
|
|
153
|
+
return response.data;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (import_axios.default.isAxiosError(error)) {
|
|
156
|
+
const axiosError = error;
|
|
157
|
+
if (axiosError.response?.status === 401) {
|
|
158
|
+
throw new AuthenticationError("Invalid API key");
|
|
159
|
+
} else if (axiosError.response?.status === 429) {
|
|
160
|
+
throw new RateLimitError("Rate limit exceeded");
|
|
161
|
+
} else if (axiosError.response?.status && axiosError.response.status >= 400) {
|
|
162
|
+
const errorData = axiosError.response.data;
|
|
163
|
+
throw new APIError(
|
|
164
|
+
errorData?.message || "API request failed",
|
|
165
|
+
axiosError.response.status,
|
|
166
|
+
errorData
|
|
167
|
+
);
|
|
168
|
+
} else if (error.code === "ECONNABORTED") {
|
|
169
|
+
throw new NeuraLexError("Request timeout");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (error instanceof NeuraLexError) {
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
throw new NeuraLexError(
|
|
176
|
+
error instanceof Error ? error.message : "Unknown error occurred"
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
182
|
+
0 && (module.exports = {
|
|
183
|
+
APIError,
|
|
184
|
+
AuthenticationError,
|
|
185
|
+
NeuraLexClient,
|
|
186
|
+
NeuraLexError,
|
|
187
|
+
RateLimitError
|
|
188
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
var NeuraLexError = class _NeuraLexError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "NeuraLexError";
|
|
9
|
+
Object.setPrototypeOf(this, _NeuraLexError.prototype);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var AuthenticationError = class _AuthenticationError extends NeuraLexError {
|
|
13
|
+
constructor(message = "Authentication failed") {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "AuthenticationError";
|
|
16
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var RateLimitError = class _RateLimitError extends NeuraLexError {
|
|
20
|
+
constructor(message = "Rate limit exceeded") {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "RateLimitError";
|
|
23
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var APIError = class _APIError extends NeuraLexError {
|
|
27
|
+
constructor(message, statusCode, responseData = {}) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "APIError";
|
|
30
|
+
this.statusCode = statusCode;
|
|
31
|
+
this.responseData = responseData;
|
|
32
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/client.ts
|
|
37
|
+
var NeuraLexClient = class {
|
|
38
|
+
/**
|
|
39
|
+
* Create a new NeuraLex client
|
|
40
|
+
*
|
|
41
|
+
* @param config - Client configuration
|
|
42
|
+
* @param config.apiKey - Your NeuraLex API key (starts with 'nlx_')
|
|
43
|
+
* @param config.baseUrl - Base URL for the API (default: https://api.neuralex.ca)
|
|
44
|
+
* @param config.timeout - Request timeout in milliseconds (default: 30000)
|
|
45
|
+
*/
|
|
46
|
+
constructor(config) {
|
|
47
|
+
const { apiKey, baseUrl = "https://api.neuralex.ca", timeout = 3e4 } = config;
|
|
48
|
+
if (!apiKey) {
|
|
49
|
+
throw new AuthenticationError("API key is required");
|
|
50
|
+
}
|
|
51
|
+
if (!apiKey.startsWith("nlx_")) {
|
|
52
|
+
throw new AuthenticationError("Invalid API key format (should start with 'nlx_')");
|
|
53
|
+
}
|
|
54
|
+
this.apiKey = apiKey;
|
|
55
|
+
this.client = axios.create({
|
|
56
|
+
baseURL: baseUrl,
|
|
57
|
+
timeout,
|
|
58
|
+
headers: {
|
|
59
|
+
"X-API-Key": apiKey,
|
|
60
|
+
"Content-Type": "application/json"
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate embeddings for the provided input text(s)
|
|
66
|
+
*
|
|
67
|
+
* @param inputs - Text string or array of text strings to embed (max 100)
|
|
68
|
+
* @param options - Optional parameters
|
|
69
|
+
* @param options.model - Model name (default: "public")
|
|
70
|
+
* @param options.language - Language for lexeme extraction (default: "english")
|
|
71
|
+
* @param options.semanticWeight - Balance between term-based (0.0) and semantic (1.0) (default: 0.5)
|
|
72
|
+
* @returns Promise<EmbeddingResponse> - Embeddings and usage information
|
|
73
|
+
*
|
|
74
|
+
* @throws {AuthenticationError} Invalid or missing API key
|
|
75
|
+
* @throws {RateLimitError} Rate limit exceeded
|
|
76
|
+
* @throws {APIError} API returned an error response
|
|
77
|
+
* @throws {NeuraLexError} Other errors
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Single text
|
|
82
|
+
* const response = await client.embed('Hello, world!');
|
|
83
|
+
*
|
|
84
|
+
* // Multiple texts
|
|
85
|
+
* const response = await client.embed(['Text 1', 'Text 2', 'Text 3']);
|
|
86
|
+
*
|
|
87
|
+
* // With options
|
|
88
|
+
* const response = await client.embed('Python programming', {
|
|
89
|
+
* semanticWeight: 0.8,
|
|
90
|
+
* model: 'public'
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
async embed(inputs, options = {}) {
|
|
95
|
+
const inputArray = Array.isArray(inputs) ? inputs : [inputs];
|
|
96
|
+
if (inputArray.length === 0) {
|
|
97
|
+
throw new Error("At least one input is required");
|
|
98
|
+
}
|
|
99
|
+
if (inputArray.length > 100) {
|
|
100
|
+
throw new Error("Maximum 100 inputs allowed per request");
|
|
101
|
+
}
|
|
102
|
+
const request = {
|
|
103
|
+
inputs: inputArray,
|
|
104
|
+
model: options.model ?? "public",
|
|
105
|
+
language: options.language ?? "english",
|
|
106
|
+
semanticWeight: options.semanticWeight ?? 0.5
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
const response = await this.client.post(
|
|
110
|
+
"/api/v1/embed",
|
|
111
|
+
request
|
|
112
|
+
);
|
|
113
|
+
return response.data;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (axios.isAxiosError(error)) {
|
|
116
|
+
const axiosError = error;
|
|
117
|
+
if (axiosError.response?.status === 401) {
|
|
118
|
+
throw new AuthenticationError("Invalid API key");
|
|
119
|
+
} else if (axiosError.response?.status === 429) {
|
|
120
|
+
throw new RateLimitError("Rate limit exceeded");
|
|
121
|
+
} else if (axiosError.response?.status && axiosError.response.status >= 400) {
|
|
122
|
+
const errorData = axiosError.response.data;
|
|
123
|
+
throw new APIError(
|
|
124
|
+
errorData?.message || "API request failed",
|
|
125
|
+
axiosError.response.status,
|
|
126
|
+
errorData
|
|
127
|
+
);
|
|
128
|
+
} else if (error.code === "ECONNABORTED") {
|
|
129
|
+
throw new NeuraLexError("Request timeout");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (error instanceof NeuraLexError) {
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
throw new NeuraLexError(
|
|
136
|
+
error instanceof Error ? error.message : "Unknown error occurred"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
export {
|
|
142
|
+
APIError,
|
|
143
|
+
AuthenticationError,
|
|
144
|
+
NeuraLexClient,
|
|
145
|
+
NeuraLexError,
|
|
146
|
+
RateLimitError
|
|
147
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "neuralex",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official TS/JS client library for NeuraLex API",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
10
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"lint": "eslint src --ext .ts",
|
|
13
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"embeddings",
|
|
18
|
+
"vector",
|
|
19
|
+
"search",
|
|
20
|
+
"ai",
|
|
21
|
+
"ml",
|
|
22
|
+
"neuralex",
|
|
23
|
+
"typescript",
|
|
24
|
+
"semantic-search",
|
|
25
|
+
"hybrid-search",
|
|
26
|
+
"similarity-search",
|
|
27
|
+
"rag",
|
|
28
|
+
"retrieval",
|
|
29
|
+
"pgvector",
|
|
30
|
+
"pinecone",
|
|
31
|
+
"qdrant",
|
|
32
|
+
"weaviate",
|
|
33
|
+
"milvus",
|
|
34
|
+
"chroma",
|
|
35
|
+
"dense-retrieval",
|
|
36
|
+
"transformers",
|
|
37
|
+
"nlp"
|
|
38
|
+
],
|
|
39
|
+
"author": "NeuraLex <support@neuralex.ca>",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git@github.com:pavel604/neuralex-lib.git"
|
|
44
|
+
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/pavel604/neuralex-lib/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://neuralex.ca",
|
|
49
|
+
"files": [
|
|
50
|
+
"dist"
|
|
51
|
+
],
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"axios": "^1.6.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/jest": "^29.5.0",
|
|
57
|
+
"@types/node": "^20.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
59
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
60
|
+
"eslint": "^8.50.0",
|
|
61
|
+
"jest": "^29.7.0",
|
|
62
|
+
"prettier": "^3.0.0",
|
|
63
|
+
"ts-jest": "^29.1.0",
|
|
64
|
+
"tsup": "^8.0.0",
|
|
65
|
+
"typescript": "^5.3.0"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=14.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|