@van1s1mys/ai-router 1.0.1 → 1.2.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/README.md +37 -3
- package/dist/index.cjs +71 -3
- package/dist/index.d.cts +70 -3
- package/dist/index.d.ts +70 -3
- package/dist/index.js +71 -3
- package/package.json +45 -45
package/dist/index.d.cts
CHANGED
|
@@ -40,11 +40,29 @@ interface RouteOptions {
|
|
|
40
40
|
/** Array of routes to index for semantic search. */
|
|
41
41
|
routes: RouteConfig[];
|
|
42
42
|
/**
|
|
43
|
-
* HuggingFace model ID for generating embeddings.
|
|
43
|
+
* HuggingFace model ID (or an ordered array of IDs) for generating embeddings.
|
|
44
44
|
* Must produce 384-dimensional vectors.
|
|
45
|
+
*
|
|
46
|
+
* When an array is provided, the first model is loaded and used immediately.
|
|
47
|
+
* Heavier models are downloaded in the background; once ready, the router
|
|
48
|
+
* hot-swaps to the next model and re-indexes all routes automatically.
|
|
49
|
+
*
|
|
45
50
|
* @default "Xenova/all-MiniLM-L6-v2"
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Start fast with a light model, upgrade to a better one in the background
|
|
55
|
+
* model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small']
|
|
56
|
+
* ```
|
|
46
57
|
*/
|
|
47
|
-
model?: string;
|
|
58
|
+
model?: string | string[];
|
|
59
|
+
/**
|
|
60
|
+
* Called each time the router upgrades to the next model in the chain.
|
|
61
|
+
* Only relevant when {@link model} is an array with more than one entry.
|
|
62
|
+
*
|
|
63
|
+
* @param modelId - The HuggingFace model ID that just became active.
|
|
64
|
+
*/
|
|
65
|
+
onModelUpgrade?: (modelId: string) => void;
|
|
48
66
|
/**
|
|
49
67
|
* Minimum similarity score (0–1) for a result to be returned.
|
|
50
68
|
* Results below this threshold are discarded.
|
|
@@ -83,10 +101,13 @@ interface SearchResult {
|
|
|
83
101
|
* { path: '/pricing', title: 'Pricing', description: 'cost, plans, subscription' },
|
|
84
102
|
* { path: '/contact', title: 'Contact', description: 'support, phone, address' },
|
|
85
103
|
* ],
|
|
104
|
+
* // Start with a fast lightweight model, then upgrade to a better one in the background
|
|
105
|
+
* model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'],
|
|
86
106
|
* threshold: 0.5,
|
|
107
|
+
* onModelUpgrade: (modelId) => console.log(`Upgraded to ${modelId}`),
|
|
87
108
|
* });
|
|
88
109
|
*
|
|
89
|
-
* // Wait for the model to load
|
|
110
|
+
* // Wait for the first (lightest) model to load — ready to search immediately
|
|
90
111
|
* await router.ready;
|
|
91
112
|
*
|
|
92
113
|
* // Search by meaning — typos and synonyms work too
|
|
@@ -98,6 +119,7 @@ interface SearchResult {
|
|
|
98
119
|
* ```
|
|
99
120
|
*/
|
|
100
121
|
declare class SmartRouter {
|
|
122
|
+
private static cache;
|
|
101
123
|
private worker;
|
|
102
124
|
private readyPromise;
|
|
103
125
|
private resolveReady;
|
|
@@ -105,6 +127,51 @@ declare class SmartRouter {
|
|
|
105
127
|
private pendingSearches;
|
|
106
128
|
private destroyed;
|
|
107
129
|
private readonly ssr;
|
|
130
|
+
private onModelUpgrade?;
|
|
131
|
+
private _cacheKey;
|
|
132
|
+
/**
|
|
133
|
+
* Returns a cached SmartRouter instance for the given options.
|
|
134
|
+
* If an instance with the same model configuration already exists and
|
|
135
|
+
* hasn't been destroyed, it is returned immediately — no new worker
|
|
136
|
+
* is spawned and no model is re-downloaded.
|
|
137
|
+
*
|
|
138
|
+
* Use this instead of `new SmartRouter()` when the router may be
|
|
139
|
+
* created multiple times (e.g. React component mounts/unmounts).
|
|
140
|
+
*
|
|
141
|
+
* @param options - Routes to index, model ID, and similarity threshold.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* // Safe to call on every mount — returns the same instance
|
|
146
|
+
* const router = SmartRouter.create({ routes, model: 'Xenova/all-MiniLM-L6-v2' });
|
|
147
|
+
* await router.ready;
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
static create(options: RouteOptions): SmartRouter;
|
|
151
|
+
/**
|
|
152
|
+
* Pre-downloads the model(s) and indexes routes in the background
|
|
153
|
+
* so that a later {@link create} call returns an already-ready instance.
|
|
154
|
+
*
|
|
155
|
+
* Safe to call at page load — runs in a Web Worker and does not
|
|
156
|
+
* block the main thread. No-op on the server (SSR).
|
|
157
|
+
* Calling it multiple times with the same options is a no-op.
|
|
158
|
+
*
|
|
159
|
+
* @param options - Routes to index, model ID, and similarity threshold.
|
|
160
|
+
* @returns The pre-warming SmartRouter instance (await `.ready` if needed).
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* // At page load — start downloading the model immediately
|
|
165
|
+
* SmartRouter.preload({ routes, model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'] });
|
|
166
|
+
*
|
|
167
|
+
* // Later, when the user opens search — instant, model is already loaded
|
|
168
|
+
* const router = SmartRouter.create({ routes, model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'] });
|
|
169
|
+
* await router.ready; // resolves immediately if preload finished
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
static preload(options: RouteOptions): SmartRouter;
|
|
173
|
+
/** @internal Generates a stable cache key from options. */
|
|
174
|
+
private static cacheKey;
|
|
108
175
|
/**
|
|
109
176
|
* Creates a new SmartRouter instance.
|
|
110
177
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -40,11 +40,29 @@ interface RouteOptions {
|
|
|
40
40
|
/** Array of routes to index for semantic search. */
|
|
41
41
|
routes: RouteConfig[];
|
|
42
42
|
/**
|
|
43
|
-
* HuggingFace model ID for generating embeddings.
|
|
43
|
+
* HuggingFace model ID (or an ordered array of IDs) for generating embeddings.
|
|
44
44
|
* Must produce 384-dimensional vectors.
|
|
45
|
+
*
|
|
46
|
+
* When an array is provided, the first model is loaded and used immediately.
|
|
47
|
+
* Heavier models are downloaded in the background; once ready, the router
|
|
48
|
+
* hot-swaps to the next model and re-indexes all routes automatically.
|
|
49
|
+
*
|
|
45
50
|
* @default "Xenova/all-MiniLM-L6-v2"
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Start fast with a light model, upgrade to a better one in the background
|
|
55
|
+
* model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small']
|
|
56
|
+
* ```
|
|
46
57
|
*/
|
|
47
|
-
model?: string;
|
|
58
|
+
model?: string | string[];
|
|
59
|
+
/**
|
|
60
|
+
* Called each time the router upgrades to the next model in the chain.
|
|
61
|
+
* Only relevant when {@link model} is an array with more than one entry.
|
|
62
|
+
*
|
|
63
|
+
* @param modelId - The HuggingFace model ID that just became active.
|
|
64
|
+
*/
|
|
65
|
+
onModelUpgrade?: (modelId: string) => void;
|
|
48
66
|
/**
|
|
49
67
|
* Minimum similarity score (0–1) for a result to be returned.
|
|
50
68
|
* Results below this threshold are discarded.
|
|
@@ -83,10 +101,13 @@ interface SearchResult {
|
|
|
83
101
|
* { path: '/pricing', title: 'Pricing', description: 'cost, plans, subscription' },
|
|
84
102
|
* { path: '/contact', title: 'Contact', description: 'support, phone, address' },
|
|
85
103
|
* ],
|
|
104
|
+
* // Start with a fast lightweight model, then upgrade to a better one in the background
|
|
105
|
+
* model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'],
|
|
86
106
|
* threshold: 0.5,
|
|
107
|
+
* onModelUpgrade: (modelId) => console.log(`Upgraded to ${modelId}`),
|
|
87
108
|
* });
|
|
88
109
|
*
|
|
89
|
-
* // Wait for the model to load
|
|
110
|
+
* // Wait for the first (lightest) model to load — ready to search immediately
|
|
90
111
|
* await router.ready;
|
|
91
112
|
*
|
|
92
113
|
* // Search by meaning — typos and synonyms work too
|
|
@@ -98,6 +119,7 @@ interface SearchResult {
|
|
|
98
119
|
* ```
|
|
99
120
|
*/
|
|
100
121
|
declare class SmartRouter {
|
|
122
|
+
private static cache;
|
|
101
123
|
private worker;
|
|
102
124
|
private readyPromise;
|
|
103
125
|
private resolveReady;
|
|
@@ -105,6 +127,51 @@ declare class SmartRouter {
|
|
|
105
127
|
private pendingSearches;
|
|
106
128
|
private destroyed;
|
|
107
129
|
private readonly ssr;
|
|
130
|
+
private onModelUpgrade?;
|
|
131
|
+
private _cacheKey;
|
|
132
|
+
/**
|
|
133
|
+
* Returns a cached SmartRouter instance for the given options.
|
|
134
|
+
* If an instance with the same model configuration already exists and
|
|
135
|
+
* hasn't been destroyed, it is returned immediately — no new worker
|
|
136
|
+
* is spawned and no model is re-downloaded.
|
|
137
|
+
*
|
|
138
|
+
* Use this instead of `new SmartRouter()` when the router may be
|
|
139
|
+
* created multiple times (e.g. React component mounts/unmounts).
|
|
140
|
+
*
|
|
141
|
+
* @param options - Routes to index, model ID, and similarity threshold.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* // Safe to call on every mount — returns the same instance
|
|
146
|
+
* const router = SmartRouter.create({ routes, model: 'Xenova/all-MiniLM-L6-v2' });
|
|
147
|
+
* await router.ready;
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
static create(options: RouteOptions): SmartRouter;
|
|
151
|
+
/**
|
|
152
|
+
* Pre-downloads the model(s) and indexes routes in the background
|
|
153
|
+
* so that a later {@link create} call returns an already-ready instance.
|
|
154
|
+
*
|
|
155
|
+
* Safe to call at page load — runs in a Web Worker and does not
|
|
156
|
+
* block the main thread. No-op on the server (SSR).
|
|
157
|
+
* Calling it multiple times with the same options is a no-op.
|
|
158
|
+
*
|
|
159
|
+
* @param options - Routes to index, model ID, and similarity threshold.
|
|
160
|
+
* @returns The pre-warming SmartRouter instance (await `.ready` if needed).
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* // At page load — start downloading the model immediately
|
|
165
|
+
* SmartRouter.preload({ routes, model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'] });
|
|
166
|
+
*
|
|
167
|
+
* // Later, when the user opens search — instant, model is already loaded
|
|
168
|
+
* const router = SmartRouter.create({ routes, model: ['Xenova/all-MiniLM-L6-v2', 'Xenova/multilingual-e5-small'] });
|
|
169
|
+
* await router.ready; // resolves immediately if preload finished
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
static preload(options: RouteOptions): SmartRouter;
|
|
173
|
+
/** @internal Generates a stable cache key from options. */
|
|
174
|
+
private static cacheKey;
|
|
108
175
|
/**
|
|
109
176
|
* Creates a new SmartRouter instance.
|
|
110
177
|
*
|