@horribleprogram/sdk 0.1.2 → 0.1.4
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 +109 -97
- package/dist/chunk-4DZAWXQM.js +280 -0
- package/dist/index.cjs +261 -11
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/main.cjs +261 -11
- package/dist/main.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-EWLGKE65.js +0 -30
package/README.md
CHANGED
|
@@ -1,97 +1,109 @@
|
|
|
1
|
-
# @
|
|
2
|
-
|
|
3
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
|
|
6
|
-
Official JavaScript/TypeScript SDK for the **Botcierge Intent Classification API**.
|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
- **TypeScript Native**: Full type definitions for all API responses.
|
|
11
|
-
- **Lightweight**: Zero dependencies (uses native `fetch`).
|
|
12
|
-
- **Flexible**: Easy to use for both simple scripts and complex applications.
|
|
13
|
-
- **Cross-platform**: Works in Node.js, Browsers, and Edge environments.
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install @
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Quick Start
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
import { query_intent } from '@
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
1
|
+
# @horribleprogram/sdk
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@horribleprogram/sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Official JavaScript/TypeScript SDK for the **Botcierge Intent Classification API**.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **TypeScript Native**: Full type definitions for all API responses.
|
|
11
|
+
- **Lightweight**: Zero dependencies (uses native `fetch`).
|
|
12
|
+
- **Flexible**: Easy to use for both simple scripts and complex applications.
|
|
13
|
+
- **Cross-platform**: Works in Node.js, Browsers, and Edge environments.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @horribleprogram/sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { query_intent } from '@horribleprogram/sdk';
|
|
25
|
+
|
|
26
|
+
const result = await query_intent("I'd like to share some food");
|
|
27
|
+
|
|
28
|
+
console.log(result.domain); // FOODLINK
|
|
29
|
+
console.log(result.intent); // share_food
|
|
30
|
+
console.log(result.confidence); // high
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
No configuration needed — the SDK points to the hosted API at `https://horribleprogram-intentapi.hf.space` by default.
|
|
34
|
+
|
|
35
|
+
## Try it in Node
|
|
36
|
+
|
|
37
|
+
Create a file `demo.mjs` and run it with `node demo.mjs`:
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
import { Botcierge, query_intent } from '@horribleprogram/sdk'
|
|
41
|
+
|
|
42
|
+
// Zero-config — hits the hosted API by default
|
|
43
|
+
console.log(await query_intent("I'm hungry"))
|
|
44
|
+
console.log(await query_intent("I need help with a bill"))
|
|
45
|
+
|
|
46
|
+
// Or with an explicit client
|
|
47
|
+
const client = new Botcierge()
|
|
48
|
+
console.log(await client.query_intent("I want to add milk to my list"))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Example output:
|
|
52
|
+
```json
|
|
53
|
+
{ "domain": "FOODLINK", "intent": "request_food", "confidence": "high" }
|
|
54
|
+
{ "domain": "BILLBRIDGE", "intent": "request_bill_help", "confidence": "high" }
|
|
55
|
+
{ "domain": "SHOP_SAVVY", "intent": "add_item", "confidence": "high" }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## API Reference
|
|
59
|
+
|
|
60
|
+
### `query_intent(utterance: string): Promise<IntentResult>`
|
|
61
|
+
|
|
62
|
+
Classifies a string using the default client (hosted API).
|
|
63
|
+
|
|
64
|
+
### `class Botcierge`
|
|
65
|
+
|
|
66
|
+
#### `constructor(config?: BotciergeConfig)`
|
|
67
|
+
|
|
68
|
+
- `config.baseUrl`: Override the API base URL (default: `https://horribleprogram-intentapi.hf.space`).
|
|
69
|
+
|
|
70
|
+
#### `query_intent(utterance: string): Promise<IntentResult>`
|
|
71
|
+
|
|
72
|
+
Classifies a string into a specific domain and intent.
|
|
73
|
+
|
|
74
|
+
### Types
|
|
75
|
+
|
|
76
|
+
#### `IntentResult`
|
|
77
|
+
```typescript
|
|
78
|
+
interface IntentResult {
|
|
79
|
+
domain: string;
|
|
80
|
+
intent: string;
|
|
81
|
+
confidence: "high" | "medium" | "low";
|
|
82
|
+
scores?: Record<string, number>;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Error Handling
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { Botcierge } from '@horribleprogram/sdk';
|
|
90
|
+
|
|
91
|
+
const client = new Botcierge({ baseUrl: 'https://my-own-instance.com' });
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
await client.query_intent("hello");
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.log(e.message); // "Botcierge API error: ..."
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Development
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm test
|
|
104
|
+
npm run build
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT © [horribleprogram](https://npmjs.com/~horribleprogram)
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { pipeline } from "@xenova/transformers";
|
|
3
|
+
|
|
4
|
+
// src/intents.ts
|
|
5
|
+
var INTENTS_TAXONOMY = {
|
|
6
|
+
"GIFTMINDER": {
|
|
7
|
+
"view_events": [
|
|
8
|
+
"I want to see events coming up"
|
|
9
|
+
],
|
|
10
|
+
"view_wishlists": [
|
|
11
|
+
"I want to see wishlists"
|
|
12
|
+
],
|
|
13
|
+
"buy_gifts": [
|
|
14
|
+
"I want to buy gifts for my loved ones"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"REMEMBOT": {
|
|
18
|
+
"remember": [
|
|
19
|
+
"I want to remember something"
|
|
20
|
+
],
|
|
21
|
+
"recall": [
|
|
22
|
+
"I want to recall something"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"RESCUEBIDS": {
|
|
26
|
+
"avoid_fee": [
|
|
27
|
+
"I want to avoid a bank fee"
|
|
28
|
+
],
|
|
29
|
+
"request_loan": [
|
|
30
|
+
"I need a small loan"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"FOODLINK": {
|
|
34
|
+
"request_food": [
|
|
35
|
+
"I'm hungry",
|
|
36
|
+
"I am hungry"
|
|
37
|
+
],
|
|
38
|
+
"share_food": [
|
|
39
|
+
"I have food to share",
|
|
40
|
+
"I want to share some food"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"BILLBRIDGE": {
|
|
44
|
+
"request_bill_help": [
|
|
45
|
+
"I need help with a bill"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"BLOODSHARE": {
|
|
49
|
+
"request_blood": [
|
|
50
|
+
"I need blood"
|
|
51
|
+
],
|
|
52
|
+
"share_blood": [
|
|
53
|
+
"I have blood to share"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"MATH": {
|
|
57
|
+
"compute_expression": [
|
|
58
|
+
"compute xplusonesquared",
|
|
59
|
+
"compute xsquaredplusone",
|
|
60
|
+
"Compute x squared plus one",
|
|
61
|
+
"Compute x plus one squared"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"SHOP_SAVVY": {
|
|
65
|
+
"add_item": [
|
|
66
|
+
"Add an item to my shopping list",
|
|
67
|
+
"I want to add items to my shopping list"
|
|
68
|
+
],
|
|
69
|
+
"remove_item": [
|
|
70
|
+
"Remove an item from my shopping list"
|
|
71
|
+
],
|
|
72
|
+
"view_list": [
|
|
73
|
+
"What's on my shopping list",
|
|
74
|
+
"I want to see my shopping list"
|
|
75
|
+
],
|
|
76
|
+
"edit_list": [
|
|
77
|
+
"I want to change my shopping list"
|
|
78
|
+
],
|
|
79
|
+
"mark_purchased": [
|
|
80
|
+
"I've purchased some items on my shopping list",
|
|
81
|
+
"I have purchased some items on my shopping list"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"BOT_STORE": {
|
|
85
|
+
"add_package": [
|
|
86
|
+
"I want to buy a package",
|
|
87
|
+
"I want to add a package"
|
|
88
|
+
],
|
|
89
|
+
"remove_package": [
|
|
90
|
+
"I want to stop using a package",
|
|
91
|
+
"I want to remove a package"
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
"TASKMASTERAI": {
|
|
95
|
+
"add_task": [
|
|
96
|
+
"I want to add a to do list item to my list",
|
|
97
|
+
"Add a to do list item",
|
|
98
|
+
"I want to add a to do list item"
|
|
99
|
+
],
|
|
100
|
+
"view_tasks": [
|
|
101
|
+
"I want to see my to do list",
|
|
102
|
+
"Show to do list",
|
|
103
|
+
"Show my to do list"
|
|
104
|
+
],
|
|
105
|
+
"edit_tasks": [
|
|
106
|
+
"I want to change my to do list",
|
|
107
|
+
"I want to edit my to do list"
|
|
108
|
+
],
|
|
109
|
+
"remove_task": [
|
|
110
|
+
"I want to remove items from my to do list"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"FLOWPLANNER": {
|
|
114
|
+
"create_flow_plan": [
|
|
115
|
+
"Create a flow plan for tomorrow"
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"CGM": {
|
|
119
|
+
"find_company": [
|
|
120
|
+
"I need a company that...",
|
|
121
|
+
"I want a company that..."
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"TIFFANY": {
|
|
125
|
+
"process_dental_patient": [
|
|
126
|
+
"I want to process the patient visit for <patient-name>"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"CAREMEDIC": {
|
|
130
|
+
"process_medical_patient": [
|
|
131
|
+
"I want to process the patient visit for <patient-name>"
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"DISCRETION": {
|
|
135
|
+
"retrieval_augmented_generation": [
|
|
136
|
+
"I need to retrieve information from my documents"
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// src/index.ts
|
|
142
|
+
var extractorPromise = null;
|
|
143
|
+
function getExtractor() {
|
|
144
|
+
if (!extractorPromise) {
|
|
145
|
+
extractorPromise = (async () => {
|
|
146
|
+
console.log("Loading local embedding model 'Xenova/all-MiniLM-L12-v2'...");
|
|
147
|
+
console.log("Note: On first run, this will download the model files (approx. 120MB).");
|
|
148
|
+
const extractor = await pipeline("feature-extraction", "Xenova/all-MiniLM-L12-v2");
|
|
149
|
+
console.log("Local embedding model loaded successfully.");
|
|
150
|
+
return extractor;
|
|
151
|
+
})();
|
|
152
|
+
}
|
|
153
|
+
return extractorPromise;
|
|
154
|
+
}
|
|
155
|
+
var cachedTaxonomyEmbeddingsPromise = null;
|
|
156
|
+
async function getTaxonomyEmbeddings() {
|
|
157
|
+
if (cachedTaxonomyEmbeddingsPromise) {
|
|
158
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
159
|
+
}
|
|
160
|
+
cachedTaxonomyEmbeddingsPromise = (async () => {
|
|
161
|
+
const extractor = await getExtractor();
|
|
162
|
+
const items = [];
|
|
163
|
+
for (const [domain, intents] of Object.entries(INTENTS_TAXONOMY)) {
|
|
164
|
+
for (const [intent, utterances] of Object.entries(intents)) {
|
|
165
|
+
for (const utterance of utterances) {
|
|
166
|
+
if (utterance.trim()) {
|
|
167
|
+
items.push({ domain, intent, utterance });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const texts = items.map((item) => item.utterance);
|
|
173
|
+
const output = await extractor(texts, { pooling: "mean", normalize: true });
|
|
174
|
+
const dim = output.dims[1];
|
|
175
|
+
const data = output.data;
|
|
176
|
+
const embeddings = [];
|
|
177
|
+
for (let i = 0; i < items.length; i++) {
|
|
178
|
+
const startIndex = i * dim;
|
|
179
|
+
const vector = Array.from(data.subarray(startIndex, startIndex + dim));
|
|
180
|
+
embeddings.push({
|
|
181
|
+
...items[i],
|
|
182
|
+
vector
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return embeddings;
|
|
186
|
+
})();
|
|
187
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
188
|
+
}
|
|
189
|
+
function cosineSimilarity(v1, v2) {
|
|
190
|
+
let dotProduct = 0;
|
|
191
|
+
let norm1 = 0;
|
|
192
|
+
let norm2 = 0;
|
|
193
|
+
for (let i = 0; i < v1.length; i++) {
|
|
194
|
+
dotProduct += v1[i] * v2[i];
|
|
195
|
+
norm1 += v1[i] * v1[i];
|
|
196
|
+
norm2 += v2[i] * v2[i];
|
|
197
|
+
}
|
|
198
|
+
if (norm1 === 0 || norm2 === 0) return 0;
|
|
199
|
+
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
|
|
200
|
+
}
|
|
201
|
+
var Botcierge = class {
|
|
202
|
+
baseUrl;
|
|
203
|
+
apiKey;
|
|
204
|
+
constructor(config = {}) {
|
|
205
|
+
this.baseUrl = config.baseUrl || "https://horribleprogram-intentapi.hf.space";
|
|
206
|
+
this.apiKey = config.apiKey;
|
|
207
|
+
}
|
|
208
|
+
getApiKey() {
|
|
209
|
+
if (this.apiKey) return this.apiKey;
|
|
210
|
+
if (typeof process !== "undefined" && process.env) {
|
|
211
|
+
return process.env.BOTCIERGE_API_KEY || process.env.OPENAI_API_KEY;
|
|
212
|
+
}
|
|
213
|
+
return void 0;
|
|
214
|
+
}
|
|
215
|
+
async query_intent(utterance) {
|
|
216
|
+
const apiKey = this.getApiKey();
|
|
217
|
+
if (apiKey) {
|
|
218
|
+
const headers = {
|
|
219
|
+
"Content-Type": "application/json",
|
|
220
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
221
|
+
"X-API-Key": apiKey
|
|
222
|
+
};
|
|
223
|
+
const response = await fetch(`${this.baseUrl}/classify`, {
|
|
224
|
+
method: "POST",
|
|
225
|
+
headers,
|
|
226
|
+
body: JSON.stringify({ utterance })
|
|
227
|
+
});
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
230
|
+
throw new Error(`Botcierge API error: ${error.detail || response.statusText}`);
|
|
231
|
+
}
|
|
232
|
+
return await response.json();
|
|
233
|
+
} else {
|
|
234
|
+
const extractor = await getExtractor();
|
|
235
|
+
const output = await extractor(utterance, { pooling: "mean", normalize: true });
|
|
236
|
+
const queryVector = Array.from(output.data);
|
|
237
|
+
const taxEmbeddings = await getTaxonomyEmbeddings();
|
|
238
|
+
let bestSim = -1;
|
|
239
|
+
let bestItem = null;
|
|
240
|
+
for (const item of taxEmbeddings) {
|
|
241
|
+
const sim = cosineSimilarity(queryVector, item.vector);
|
|
242
|
+
if (sim > bestSim) {
|
|
243
|
+
bestSim = sim;
|
|
244
|
+
bestItem = item;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (!bestItem || bestSim < 0.35) {
|
|
248
|
+
return {
|
|
249
|
+
domain: "unknown",
|
|
250
|
+
intent: "unknown",
|
|
251
|
+
confidence: "low",
|
|
252
|
+
scores: {}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
let confidence = "low";
|
|
256
|
+
if (bestSim >= 0.7) {
|
|
257
|
+
confidence = "high";
|
|
258
|
+
} else if (bestSim >= 0.5) {
|
|
259
|
+
confidence = "medium";
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
domain: bestItem.domain,
|
|
263
|
+
intent: bestItem.intent,
|
|
264
|
+
confidence,
|
|
265
|
+
scores: {
|
|
266
|
+
[bestItem.intent]: bestSim
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var defaultClient = new Botcierge();
|
|
273
|
+
async function query_intent(utterance) {
|
|
274
|
+
return defaultClient.query_intent(utterance);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export {
|
|
278
|
+
Botcierge,
|
|
279
|
+
query_intent
|
|
280
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -24,24 +24,274 @@ __export(index_exports, {
|
|
|
24
24
|
query_intent: () => query_intent
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_transformers = require("@xenova/transformers");
|
|
28
|
+
|
|
29
|
+
// src/intents.ts
|
|
30
|
+
var INTENTS_TAXONOMY = {
|
|
31
|
+
"GIFTMINDER": {
|
|
32
|
+
"view_events": [
|
|
33
|
+
"I want to see events coming up"
|
|
34
|
+
],
|
|
35
|
+
"view_wishlists": [
|
|
36
|
+
"I want to see wishlists"
|
|
37
|
+
],
|
|
38
|
+
"buy_gifts": [
|
|
39
|
+
"I want to buy gifts for my loved ones"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"REMEMBOT": {
|
|
43
|
+
"remember": [
|
|
44
|
+
"I want to remember something"
|
|
45
|
+
],
|
|
46
|
+
"recall": [
|
|
47
|
+
"I want to recall something"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"RESCUEBIDS": {
|
|
51
|
+
"avoid_fee": [
|
|
52
|
+
"I want to avoid a bank fee"
|
|
53
|
+
],
|
|
54
|
+
"request_loan": [
|
|
55
|
+
"I need a small loan"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"FOODLINK": {
|
|
59
|
+
"request_food": [
|
|
60
|
+
"I'm hungry",
|
|
61
|
+
"I am hungry"
|
|
62
|
+
],
|
|
63
|
+
"share_food": [
|
|
64
|
+
"I have food to share",
|
|
65
|
+
"I want to share some food"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"BILLBRIDGE": {
|
|
69
|
+
"request_bill_help": [
|
|
70
|
+
"I need help with a bill"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"BLOODSHARE": {
|
|
74
|
+
"request_blood": [
|
|
75
|
+
"I need blood"
|
|
76
|
+
],
|
|
77
|
+
"share_blood": [
|
|
78
|
+
"I have blood to share"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"MATH": {
|
|
82
|
+
"compute_expression": [
|
|
83
|
+
"compute xplusonesquared",
|
|
84
|
+
"compute xsquaredplusone",
|
|
85
|
+
"Compute x squared plus one",
|
|
86
|
+
"Compute x plus one squared"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
"SHOP_SAVVY": {
|
|
90
|
+
"add_item": [
|
|
91
|
+
"Add an item to my shopping list",
|
|
92
|
+
"I want to add items to my shopping list"
|
|
93
|
+
],
|
|
94
|
+
"remove_item": [
|
|
95
|
+
"Remove an item from my shopping list"
|
|
96
|
+
],
|
|
97
|
+
"view_list": [
|
|
98
|
+
"What's on my shopping list",
|
|
99
|
+
"I want to see my shopping list"
|
|
100
|
+
],
|
|
101
|
+
"edit_list": [
|
|
102
|
+
"I want to change my shopping list"
|
|
103
|
+
],
|
|
104
|
+
"mark_purchased": [
|
|
105
|
+
"I've purchased some items on my shopping list",
|
|
106
|
+
"I have purchased some items on my shopping list"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"BOT_STORE": {
|
|
110
|
+
"add_package": [
|
|
111
|
+
"I want to buy a package",
|
|
112
|
+
"I want to add a package"
|
|
113
|
+
],
|
|
114
|
+
"remove_package": [
|
|
115
|
+
"I want to stop using a package",
|
|
116
|
+
"I want to remove a package"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"TASKMASTERAI": {
|
|
120
|
+
"add_task": [
|
|
121
|
+
"I want to add a to do list item to my list",
|
|
122
|
+
"Add a to do list item",
|
|
123
|
+
"I want to add a to do list item"
|
|
124
|
+
],
|
|
125
|
+
"view_tasks": [
|
|
126
|
+
"I want to see my to do list",
|
|
127
|
+
"Show to do list",
|
|
128
|
+
"Show my to do list"
|
|
129
|
+
],
|
|
130
|
+
"edit_tasks": [
|
|
131
|
+
"I want to change my to do list",
|
|
132
|
+
"I want to edit my to do list"
|
|
133
|
+
],
|
|
134
|
+
"remove_task": [
|
|
135
|
+
"I want to remove items from my to do list"
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
"FLOWPLANNER": {
|
|
139
|
+
"create_flow_plan": [
|
|
140
|
+
"Create a flow plan for tomorrow"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"CGM": {
|
|
144
|
+
"find_company": [
|
|
145
|
+
"I need a company that...",
|
|
146
|
+
"I want a company that..."
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"TIFFANY": {
|
|
150
|
+
"process_dental_patient": [
|
|
151
|
+
"I want to process the patient visit for <patient-name>"
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"CAREMEDIC": {
|
|
155
|
+
"process_medical_patient": [
|
|
156
|
+
"I want to process the patient visit for <patient-name>"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
"DISCRETION": {
|
|
160
|
+
"retrieval_augmented_generation": [
|
|
161
|
+
"I need to retrieve information from my documents"
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// src/index.ts
|
|
167
|
+
var extractorPromise = null;
|
|
168
|
+
function getExtractor() {
|
|
169
|
+
if (!extractorPromise) {
|
|
170
|
+
extractorPromise = (async () => {
|
|
171
|
+
console.log("Loading local embedding model 'Xenova/all-MiniLM-L12-v2'...");
|
|
172
|
+
console.log("Note: On first run, this will download the model files (approx. 120MB).");
|
|
173
|
+
const extractor = await (0, import_transformers.pipeline)("feature-extraction", "Xenova/all-MiniLM-L12-v2");
|
|
174
|
+
console.log("Local embedding model loaded successfully.");
|
|
175
|
+
return extractor;
|
|
176
|
+
})();
|
|
177
|
+
}
|
|
178
|
+
return extractorPromise;
|
|
179
|
+
}
|
|
180
|
+
var cachedTaxonomyEmbeddingsPromise = null;
|
|
181
|
+
async function getTaxonomyEmbeddings() {
|
|
182
|
+
if (cachedTaxonomyEmbeddingsPromise) {
|
|
183
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
184
|
+
}
|
|
185
|
+
cachedTaxonomyEmbeddingsPromise = (async () => {
|
|
186
|
+
const extractor = await getExtractor();
|
|
187
|
+
const items = [];
|
|
188
|
+
for (const [domain, intents] of Object.entries(INTENTS_TAXONOMY)) {
|
|
189
|
+
for (const [intent, utterances] of Object.entries(intents)) {
|
|
190
|
+
for (const utterance of utterances) {
|
|
191
|
+
if (utterance.trim()) {
|
|
192
|
+
items.push({ domain, intent, utterance });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const texts = items.map((item) => item.utterance);
|
|
198
|
+
const output = await extractor(texts, { pooling: "mean", normalize: true });
|
|
199
|
+
const dim = output.dims[1];
|
|
200
|
+
const data = output.data;
|
|
201
|
+
const embeddings = [];
|
|
202
|
+
for (let i = 0; i < items.length; i++) {
|
|
203
|
+
const startIndex = i * dim;
|
|
204
|
+
const vector = Array.from(data.subarray(startIndex, startIndex + dim));
|
|
205
|
+
embeddings.push({
|
|
206
|
+
...items[i],
|
|
207
|
+
vector
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return embeddings;
|
|
211
|
+
})();
|
|
212
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
213
|
+
}
|
|
214
|
+
function cosineSimilarity(v1, v2) {
|
|
215
|
+
let dotProduct = 0;
|
|
216
|
+
let norm1 = 0;
|
|
217
|
+
let norm2 = 0;
|
|
218
|
+
for (let i = 0; i < v1.length; i++) {
|
|
219
|
+
dotProduct += v1[i] * v2[i];
|
|
220
|
+
norm1 += v1[i] * v1[i];
|
|
221
|
+
norm2 += v2[i] * v2[i];
|
|
222
|
+
}
|
|
223
|
+
if (norm1 === 0 || norm2 === 0) return 0;
|
|
224
|
+
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
|
|
225
|
+
}
|
|
27
226
|
var Botcierge = class {
|
|
28
227
|
baseUrl;
|
|
228
|
+
apiKey;
|
|
29
229
|
constructor(config = {}) {
|
|
30
230
|
this.baseUrl = config.baseUrl || "https://horribleprogram-intentapi.hf.space";
|
|
231
|
+
this.apiKey = config.apiKey;
|
|
232
|
+
}
|
|
233
|
+
getApiKey() {
|
|
234
|
+
if (this.apiKey) return this.apiKey;
|
|
235
|
+
if (typeof process !== "undefined" && process.env) {
|
|
236
|
+
return process.env.BOTCIERGE_API_KEY || process.env.OPENAI_API_KEY;
|
|
237
|
+
}
|
|
238
|
+
return void 0;
|
|
31
239
|
}
|
|
32
240
|
async query_intent(utterance) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
headers
|
|
36
|
-
"Content-Type": "application/json"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
241
|
+
const apiKey = this.getApiKey();
|
|
242
|
+
if (apiKey) {
|
|
243
|
+
const headers = {
|
|
244
|
+
"Content-Type": "application/json",
|
|
245
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
246
|
+
"X-API-Key": apiKey
|
|
247
|
+
};
|
|
248
|
+
const response = await fetch(`${this.baseUrl}/classify`, {
|
|
249
|
+
method: "POST",
|
|
250
|
+
headers,
|
|
251
|
+
body: JSON.stringify({ utterance })
|
|
252
|
+
});
|
|
253
|
+
if (!response.ok) {
|
|
254
|
+
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
255
|
+
throw new Error(`Botcierge API error: ${error.detail || response.statusText}`);
|
|
256
|
+
}
|
|
257
|
+
return await response.json();
|
|
258
|
+
} else {
|
|
259
|
+
const extractor = await getExtractor();
|
|
260
|
+
const output = await extractor(utterance, { pooling: "mean", normalize: true });
|
|
261
|
+
const queryVector = Array.from(output.data);
|
|
262
|
+
const taxEmbeddings = await getTaxonomyEmbeddings();
|
|
263
|
+
let bestSim = -1;
|
|
264
|
+
let bestItem = null;
|
|
265
|
+
for (const item of taxEmbeddings) {
|
|
266
|
+
const sim = cosineSimilarity(queryVector, item.vector);
|
|
267
|
+
if (sim > bestSim) {
|
|
268
|
+
bestSim = sim;
|
|
269
|
+
bestItem = item;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (!bestItem || bestSim < 0.35) {
|
|
273
|
+
return {
|
|
274
|
+
domain: "unknown",
|
|
275
|
+
intent: "unknown",
|
|
276
|
+
confidence: "low",
|
|
277
|
+
scores: {}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
let confidence = "low";
|
|
281
|
+
if (bestSim >= 0.7) {
|
|
282
|
+
confidence = "high";
|
|
283
|
+
} else if (bestSim >= 0.5) {
|
|
284
|
+
confidence = "medium";
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
domain: bestItem.domain,
|
|
288
|
+
intent: bestItem.intent,
|
|
289
|
+
confidence,
|
|
290
|
+
scores: {
|
|
291
|
+
[bestItem.intent]: bestSim
|
|
292
|
+
}
|
|
293
|
+
};
|
|
43
294
|
}
|
|
44
|
-
return await response.json();
|
|
45
295
|
}
|
|
46
296
|
};
|
|
47
297
|
var defaultClient = new Botcierge();
|
package/dist/index.d.cts
CHANGED
|
@@ -6,15 +6,17 @@ interface IntentResult {
|
|
|
6
6
|
}
|
|
7
7
|
interface BotciergeConfig {
|
|
8
8
|
baseUrl?: string;
|
|
9
|
+
apiKey?: string;
|
|
9
10
|
}
|
|
10
11
|
declare class Botcierge {
|
|
11
12
|
private baseUrl;
|
|
13
|
+
private apiKey?;
|
|
12
14
|
constructor(config?: BotciergeConfig);
|
|
15
|
+
private getApiKey;
|
|
13
16
|
query_intent(utterance: string): Promise<IntentResult>;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Classifies an utterance into an intent.
|
|
17
|
-
* By default, connects to http://localhost:8000
|
|
18
20
|
*/
|
|
19
21
|
declare function query_intent(utterance: string): Promise<IntentResult>;
|
|
20
22
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,15 +6,17 @@ interface IntentResult {
|
|
|
6
6
|
}
|
|
7
7
|
interface BotciergeConfig {
|
|
8
8
|
baseUrl?: string;
|
|
9
|
+
apiKey?: string;
|
|
9
10
|
}
|
|
10
11
|
declare class Botcierge {
|
|
11
12
|
private baseUrl;
|
|
13
|
+
private apiKey?;
|
|
12
14
|
constructor(config?: BotciergeConfig);
|
|
15
|
+
private getApiKey;
|
|
13
16
|
query_intent(utterance: string): Promise<IntentResult>;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Classifies an utterance into an intent.
|
|
17
|
-
* By default, connects to http://localhost:8000
|
|
18
20
|
*/
|
|
19
21
|
declare function query_intent(utterance: string): Promise<IntentResult>;
|
|
20
22
|
|
package/dist/index.js
CHANGED
package/dist/main.cjs
CHANGED
|
@@ -26,24 +26,274 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
var readline = __toESM(require("readline"), 1);
|
|
27
27
|
|
|
28
28
|
// src/index.ts
|
|
29
|
+
var import_transformers = require("@xenova/transformers");
|
|
30
|
+
|
|
31
|
+
// src/intents.ts
|
|
32
|
+
var INTENTS_TAXONOMY = {
|
|
33
|
+
"GIFTMINDER": {
|
|
34
|
+
"view_events": [
|
|
35
|
+
"I want to see events coming up"
|
|
36
|
+
],
|
|
37
|
+
"view_wishlists": [
|
|
38
|
+
"I want to see wishlists"
|
|
39
|
+
],
|
|
40
|
+
"buy_gifts": [
|
|
41
|
+
"I want to buy gifts for my loved ones"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"REMEMBOT": {
|
|
45
|
+
"remember": [
|
|
46
|
+
"I want to remember something"
|
|
47
|
+
],
|
|
48
|
+
"recall": [
|
|
49
|
+
"I want to recall something"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"RESCUEBIDS": {
|
|
53
|
+
"avoid_fee": [
|
|
54
|
+
"I want to avoid a bank fee"
|
|
55
|
+
],
|
|
56
|
+
"request_loan": [
|
|
57
|
+
"I need a small loan"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"FOODLINK": {
|
|
61
|
+
"request_food": [
|
|
62
|
+
"I'm hungry",
|
|
63
|
+
"I am hungry"
|
|
64
|
+
],
|
|
65
|
+
"share_food": [
|
|
66
|
+
"I have food to share",
|
|
67
|
+
"I want to share some food"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"BILLBRIDGE": {
|
|
71
|
+
"request_bill_help": [
|
|
72
|
+
"I need help with a bill"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"BLOODSHARE": {
|
|
76
|
+
"request_blood": [
|
|
77
|
+
"I need blood"
|
|
78
|
+
],
|
|
79
|
+
"share_blood": [
|
|
80
|
+
"I have blood to share"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
"MATH": {
|
|
84
|
+
"compute_expression": [
|
|
85
|
+
"compute xplusonesquared",
|
|
86
|
+
"compute xsquaredplusone",
|
|
87
|
+
"Compute x squared plus one",
|
|
88
|
+
"Compute x plus one squared"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"SHOP_SAVVY": {
|
|
92
|
+
"add_item": [
|
|
93
|
+
"Add an item to my shopping list",
|
|
94
|
+
"I want to add items to my shopping list"
|
|
95
|
+
],
|
|
96
|
+
"remove_item": [
|
|
97
|
+
"Remove an item from my shopping list"
|
|
98
|
+
],
|
|
99
|
+
"view_list": [
|
|
100
|
+
"What's on my shopping list",
|
|
101
|
+
"I want to see my shopping list"
|
|
102
|
+
],
|
|
103
|
+
"edit_list": [
|
|
104
|
+
"I want to change my shopping list"
|
|
105
|
+
],
|
|
106
|
+
"mark_purchased": [
|
|
107
|
+
"I've purchased some items on my shopping list",
|
|
108
|
+
"I have purchased some items on my shopping list"
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
"BOT_STORE": {
|
|
112
|
+
"add_package": [
|
|
113
|
+
"I want to buy a package",
|
|
114
|
+
"I want to add a package"
|
|
115
|
+
],
|
|
116
|
+
"remove_package": [
|
|
117
|
+
"I want to stop using a package",
|
|
118
|
+
"I want to remove a package"
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"TASKMASTERAI": {
|
|
122
|
+
"add_task": [
|
|
123
|
+
"I want to add a to do list item to my list",
|
|
124
|
+
"Add a to do list item",
|
|
125
|
+
"I want to add a to do list item"
|
|
126
|
+
],
|
|
127
|
+
"view_tasks": [
|
|
128
|
+
"I want to see my to do list",
|
|
129
|
+
"Show to do list",
|
|
130
|
+
"Show my to do list"
|
|
131
|
+
],
|
|
132
|
+
"edit_tasks": [
|
|
133
|
+
"I want to change my to do list",
|
|
134
|
+
"I want to edit my to do list"
|
|
135
|
+
],
|
|
136
|
+
"remove_task": [
|
|
137
|
+
"I want to remove items from my to do list"
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
"FLOWPLANNER": {
|
|
141
|
+
"create_flow_plan": [
|
|
142
|
+
"Create a flow plan for tomorrow"
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
"CGM": {
|
|
146
|
+
"find_company": [
|
|
147
|
+
"I need a company that...",
|
|
148
|
+
"I want a company that..."
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
"TIFFANY": {
|
|
152
|
+
"process_dental_patient": [
|
|
153
|
+
"I want to process the patient visit for <patient-name>"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"CAREMEDIC": {
|
|
157
|
+
"process_medical_patient": [
|
|
158
|
+
"I want to process the patient visit for <patient-name>"
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
"DISCRETION": {
|
|
162
|
+
"retrieval_augmented_generation": [
|
|
163
|
+
"I need to retrieve information from my documents"
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// src/index.ts
|
|
169
|
+
var extractorPromise = null;
|
|
170
|
+
function getExtractor() {
|
|
171
|
+
if (!extractorPromise) {
|
|
172
|
+
extractorPromise = (async () => {
|
|
173
|
+
console.log("Loading local embedding model 'Xenova/all-MiniLM-L12-v2'...");
|
|
174
|
+
console.log("Note: On first run, this will download the model files (approx. 120MB).");
|
|
175
|
+
const extractor = await (0, import_transformers.pipeline)("feature-extraction", "Xenova/all-MiniLM-L12-v2");
|
|
176
|
+
console.log("Local embedding model loaded successfully.");
|
|
177
|
+
return extractor;
|
|
178
|
+
})();
|
|
179
|
+
}
|
|
180
|
+
return extractorPromise;
|
|
181
|
+
}
|
|
182
|
+
var cachedTaxonomyEmbeddingsPromise = null;
|
|
183
|
+
async function getTaxonomyEmbeddings() {
|
|
184
|
+
if (cachedTaxonomyEmbeddingsPromise) {
|
|
185
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
186
|
+
}
|
|
187
|
+
cachedTaxonomyEmbeddingsPromise = (async () => {
|
|
188
|
+
const extractor = await getExtractor();
|
|
189
|
+
const items = [];
|
|
190
|
+
for (const [domain, intents] of Object.entries(INTENTS_TAXONOMY)) {
|
|
191
|
+
for (const [intent, utterances] of Object.entries(intents)) {
|
|
192
|
+
for (const utterance of utterances) {
|
|
193
|
+
if (utterance.trim()) {
|
|
194
|
+
items.push({ domain, intent, utterance });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const texts = items.map((item) => item.utterance);
|
|
200
|
+
const output = await extractor(texts, { pooling: "mean", normalize: true });
|
|
201
|
+
const dim = output.dims[1];
|
|
202
|
+
const data = output.data;
|
|
203
|
+
const embeddings = [];
|
|
204
|
+
for (let i = 0; i < items.length; i++) {
|
|
205
|
+
const startIndex = i * dim;
|
|
206
|
+
const vector = Array.from(data.subarray(startIndex, startIndex + dim));
|
|
207
|
+
embeddings.push({
|
|
208
|
+
...items[i],
|
|
209
|
+
vector
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return embeddings;
|
|
213
|
+
})();
|
|
214
|
+
return cachedTaxonomyEmbeddingsPromise;
|
|
215
|
+
}
|
|
216
|
+
function cosineSimilarity(v1, v2) {
|
|
217
|
+
let dotProduct = 0;
|
|
218
|
+
let norm1 = 0;
|
|
219
|
+
let norm2 = 0;
|
|
220
|
+
for (let i = 0; i < v1.length; i++) {
|
|
221
|
+
dotProduct += v1[i] * v2[i];
|
|
222
|
+
norm1 += v1[i] * v1[i];
|
|
223
|
+
norm2 += v2[i] * v2[i];
|
|
224
|
+
}
|
|
225
|
+
if (norm1 === 0 || norm2 === 0) return 0;
|
|
226
|
+
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
|
|
227
|
+
}
|
|
29
228
|
var Botcierge = class {
|
|
30
229
|
baseUrl;
|
|
230
|
+
apiKey;
|
|
31
231
|
constructor(config = {}) {
|
|
32
232
|
this.baseUrl = config.baseUrl || "https://horribleprogram-intentapi.hf.space";
|
|
233
|
+
this.apiKey = config.apiKey;
|
|
234
|
+
}
|
|
235
|
+
getApiKey() {
|
|
236
|
+
if (this.apiKey) return this.apiKey;
|
|
237
|
+
if (typeof process !== "undefined" && process.env) {
|
|
238
|
+
return process.env.BOTCIERGE_API_KEY || process.env.OPENAI_API_KEY;
|
|
239
|
+
}
|
|
240
|
+
return void 0;
|
|
33
241
|
}
|
|
34
242
|
async query_intent(utterance) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
headers
|
|
38
|
-
"Content-Type": "application/json"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
243
|
+
const apiKey = this.getApiKey();
|
|
244
|
+
if (apiKey) {
|
|
245
|
+
const headers = {
|
|
246
|
+
"Content-Type": "application/json",
|
|
247
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
248
|
+
"X-API-Key": apiKey
|
|
249
|
+
};
|
|
250
|
+
const response = await fetch(`${this.baseUrl}/classify`, {
|
|
251
|
+
method: "POST",
|
|
252
|
+
headers,
|
|
253
|
+
body: JSON.stringify({ utterance })
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
257
|
+
throw new Error(`Botcierge API error: ${error.detail || response.statusText}`);
|
|
258
|
+
}
|
|
259
|
+
return await response.json();
|
|
260
|
+
} else {
|
|
261
|
+
const extractor = await getExtractor();
|
|
262
|
+
const output = await extractor(utterance, { pooling: "mean", normalize: true });
|
|
263
|
+
const queryVector = Array.from(output.data);
|
|
264
|
+
const taxEmbeddings = await getTaxonomyEmbeddings();
|
|
265
|
+
let bestSim = -1;
|
|
266
|
+
let bestItem = null;
|
|
267
|
+
for (const item of taxEmbeddings) {
|
|
268
|
+
const sim = cosineSimilarity(queryVector, item.vector);
|
|
269
|
+
if (sim > bestSim) {
|
|
270
|
+
bestSim = sim;
|
|
271
|
+
bestItem = item;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (!bestItem || bestSim < 0.35) {
|
|
275
|
+
return {
|
|
276
|
+
domain: "unknown",
|
|
277
|
+
intent: "unknown",
|
|
278
|
+
confidence: "low",
|
|
279
|
+
scores: {}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
let confidence = "low";
|
|
283
|
+
if (bestSim >= 0.7) {
|
|
284
|
+
confidence = "high";
|
|
285
|
+
} else if (bestSim >= 0.5) {
|
|
286
|
+
confidence = "medium";
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
domain: bestItem.domain,
|
|
290
|
+
intent: bestItem.intent,
|
|
291
|
+
confidence,
|
|
292
|
+
scores: {
|
|
293
|
+
[bestItem.intent]: bestSim
|
|
294
|
+
}
|
|
295
|
+
};
|
|
45
296
|
}
|
|
46
|
-
return await response.json();
|
|
47
297
|
}
|
|
48
298
|
};
|
|
49
299
|
var defaultClient = new Botcierge();
|
package/dist/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@horribleprogram/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "SDK for Botcierge Intent Classification",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,5 +32,7 @@
|
|
|
32
32
|
"typescript": "^5.0.0",
|
|
33
33
|
"vitest": "^4.1.6"
|
|
34
34
|
},
|
|
35
|
-
"dependencies": {
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@xenova/transformers": "^2.17.2"
|
|
37
|
+
}
|
|
36
38
|
}
|
package/dist/chunk-EWLGKE65.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
var Botcierge = class {
|
|
3
|
-
baseUrl;
|
|
4
|
-
constructor(config = {}) {
|
|
5
|
-
this.baseUrl = config.baseUrl || "https://horribleprogram-intentapi.hf.space";
|
|
6
|
-
}
|
|
7
|
-
async query_intent(utterance) {
|
|
8
|
-
const response = await fetch(`${this.baseUrl}/classify`, {
|
|
9
|
-
method: "POST",
|
|
10
|
-
headers: {
|
|
11
|
-
"Content-Type": "application/json"
|
|
12
|
-
},
|
|
13
|
-
body: JSON.stringify({ utterance })
|
|
14
|
-
});
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
17
|
-
throw new Error(`Botcierge API error: ${error.detail || response.statusText}`);
|
|
18
|
-
}
|
|
19
|
-
return await response.json();
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
var defaultClient = new Botcierge();
|
|
23
|
-
async function query_intent(utterance) {
|
|
24
|
-
return defaultClient.query_intent(utterance);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export {
|
|
28
|
-
Botcierge,
|
|
29
|
-
query_intent
|
|
30
|
-
};
|