sis-tools 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/dist/index.js ADDED
@@ -0,0 +1,1476 @@
1
+ // src/types.ts
2
+ function toSchema(tool) {
3
+ const required = Object.entries(tool.parameters).filter(([, v]) => v.required !== false).map(([k]) => k);
4
+ return {
5
+ name: tool.name,
6
+ description: tool.description,
7
+ parameters: {
8
+ type: "object",
9
+ properties: tool.parameters,
10
+ required
11
+ }
12
+ };
13
+ }
14
+ function toOpenAISchema(tool) {
15
+ return {
16
+ type: "function",
17
+ function: toSchema(tool)
18
+ };
19
+ }
20
+ function toAnthropicSchema(tool) {
21
+ const schema = toSchema(tool);
22
+ return {
23
+ name: schema.name,
24
+ description: schema.description,
25
+ input_schema: schema.parameters
26
+ };
27
+ }
28
+
29
+ // src/embeddings/base.ts
30
+ function buildToolText(name, description, semanticHints, examples) {
31
+ const parts = [`${name}: ${description}`];
32
+ if (semanticHints?.length) {
33
+ parts.push(`Related: ${semanticHints.join(", ")}`);
34
+ }
35
+ if (examples?.length) {
36
+ const queries = examples.map((ex) => ex.query).filter(Boolean);
37
+ if (queries.length) {
38
+ parts.push(`Examples: ${queries.join("; ")}`);
39
+ }
40
+ }
41
+ return parts.join(" | ");
42
+ }
43
+
44
+ // src/embeddings/openai.ts
45
+ var DEFAULT_DIMENSIONS = {
46
+ "text-embedding-3-small": 1536,
47
+ "text-embedding-3-large": 3072,
48
+ "text-embedding-ada-002": 1536
49
+ };
50
+ var OpenAIEmbeddings = class {
51
+ client = null;
52
+ model;
53
+ apiKey;
54
+ dimensions;
55
+ constructor(options = {}) {
56
+ const { model = "text-embedding-3-small", apiKey, dimensions } = options;
57
+ this.model = model;
58
+ this.apiKey = apiKey;
59
+ this.dimensions = dimensions ?? DEFAULT_DIMENSIONS[model] ?? 1536;
60
+ }
61
+ async ensureClient() {
62
+ if (this.client) {
63
+ return this.client;
64
+ }
65
+ try {
66
+ const mod = await import('openai');
67
+ const OpenAI = mod?.OpenAI ?? mod?.default?.OpenAI ?? mod?.default;
68
+ if (!OpenAI) {
69
+ throw new Error("OpenAI export not found");
70
+ }
71
+ this.client = new OpenAI({ apiKey: this.apiKey });
72
+ return this.client;
73
+ } catch {
74
+ throw new Error(
75
+ "OpenAI provider requires the openai package. Install with: npm install openai"
76
+ );
77
+ }
78
+ }
79
+ async embed(text) {
80
+ const client = await this.ensureClient();
81
+ const params = {
82
+ model: this.model,
83
+ input: text
84
+ };
85
+ if (this.model.includes("text-embedding-3")) {
86
+ params.dimensions = this.dimensions;
87
+ }
88
+ const response = await client.embeddings.create(params);
89
+ return response.data[0].embedding;
90
+ }
91
+ async embedBatch(texts) {
92
+ const client = await this.ensureClient();
93
+ const params = {
94
+ model: this.model,
95
+ input: texts
96
+ };
97
+ if (this.model.includes("text-embedding-3")) {
98
+ params.dimensions = this.dimensions;
99
+ }
100
+ const response = await client.embeddings.create(params);
101
+ const sorted = [...response.data].sort(
102
+ (a, b) => a.index - b.index
103
+ );
104
+ return sorted.map((item) => item.embedding);
105
+ }
106
+ };
107
+
108
+ // src/embeddings/cohere.ts
109
+ var DEFAULT_DIMENSIONS2 = {
110
+ "embed-english-v3.0": 1024,
111
+ "embed-multilingual-v3.0": 1024,
112
+ "embed-english-light-v3.0": 384,
113
+ "embed-multilingual-light-v3.0": 384
114
+ };
115
+ var CohereEmbeddings = class {
116
+ client = null;
117
+ model;
118
+ inputType;
119
+ apiKey;
120
+ dimensions;
121
+ constructor(options = {}) {
122
+ const {
123
+ model = "embed-english-v3.0",
124
+ apiKey,
125
+ inputType = "search_query"
126
+ } = options;
127
+ this.model = model;
128
+ this.inputType = inputType;
129
+ this.apiKey = apiKey;
130
+ this.dimensions = DEFAULT_DIMENSIONS2[model] ?? 1024;
131
+ }
132
+ async ensureClient() {
133
+ if (this.client) {
134
+ return this.client;
135
+ }
136
+ try {
137
+ const mod = await import('cohere-ai');
138
+ const CohereClient = mod?.CohereClient ?? mod?.default?.CohereClient ?? mod?.default;
139
+ if (!CohereClient) {
140
+ throw new Error("CohereClient export not found");
141
+ }
142
+ this.client = new CohereClient({ token: this.apiKey });
143
+ return this.client;
144
+ } catch {
145
+ throw new Error(
146
+ "Cohere provider requires the cohere-ai package. Install with: npm install cohere-ai"
147
+ );
148
+ }
149
+ }
150
+ async embed(text) {
151
+ const client = await this.ensureClient();
152
+ const response = await client.embed({
153
+ texts: [text],
154
+ model: this.model,
155
+ inputType: this.inputType
156
+ });
157
+ return response.embeddings[0];
158
+ }
159
+ async embedBatch(texts) {
160
+ const client = await this.ensureClient();
161
+ const response = await client.embed({
162
+ texts,
163
+ model: this.model,
164
+ inputType: this.inputType
165
+ });
166
+ return response.embeddings;
167
+ }
168
+ };
169
+
170
+ // src/embeddings/google.ts
171
+ var DEFAULT_DIMENSIONS3 = {
172
+ "text-embedding-004": 768,
173
+ "text-embedding-preview-0815": 768
174
+ };
175
+ var GoogleEmbeddings = class {
176
+ client = null;
177
+ model;
178
+ apiKey;
179
+ dimensions;
180
+ constructor(options = {}) {
181
+ const { model = "text-embedding-004", apiKey } = options;
182
+ this.model = model;
183
+ this.apiKey = apiKey;
184
+ this.dimensions = DEFAULT_DIMENSIONS3[model] ?? 768;
185
+ }
186
+ async ensureClient() {
187
+ if (this.client) {
188
+ return this.client;
189
+ }
190
+ try {
191
+ const mod = await import('@google/generative-ai');
192
+ const GoogleGenerativeAI = mod?.GoogleGenerativeAI ?? mod?.default?.GoogleGenerativeAI ?? mod?.default;
193
+ if (!GoogleGenerativeAI) {
194
+ throw new Error("GoogleGenerativeAI export not found");
195
+ }
196
+ this.client = new GoogleGenerativeAI(this.apiKey || process.env.GOOGLE_API_KEY);
197
+ return this.client;
198
+ } catch {
199
+ throw new Error(
200
+ "Google provider requires @google/generative-ai. Install with: npm install @google/generative-ai"
201
+ );
202
+ }
203
+ }
204
+ async embed(text) {
205
+ const client = await this.ensureClient();
206
+ const model = client.getGenerativeModel({ model: this.model });
207
+ const result = await model.embedContent(text);
208
+ return result.embedding.values;
209
+ }
210
+ async embedBatch(texts) {
211
+ const client = await this.ensureClient();
212
+ const model = client.getGenerativeModel({ model: this.model });
213
+ const results = await Promise.all(
214
+ texts.map((text) => model.embedContent(text))
215
+ );
216
+ return results.map((r) => r.embedding.values);
217
+ }
218
+ };
219
+
220
+ // src/embeddings/index.ts
221
+ function getProvider(name, options = {}) {
222
+ switch (name) {
223
+ case "openai":
224
+ return new OpenAIEmbeddings(options);
225
+ case "cohere":
226
+ return new CohereEmbeddings(options);
227
+ case "google":
228
+ return new GoogleEmbeddings(options);
229
+ default:
230
+ throw new Error(
231
+ `Unknown provider: ${name}. Available: openai, cohere, google`
232
+ );
233
+ }
234
+ }
235
+
236
+ // src/scoring.ts
237
+ var CosineSimilarity = class {
238
+ compute(a, b) {
239
+ if (a.length !== b.length) {
240
+ throw new Error(`Vector dimensions must match: ${a.length} !== ${b.length}`);
241
+ }
242
+ let dotProduct = 0;
243
+ let normA = 0;
244
+ let normB = 0;
245
+ for (let i = 0; i < a.length; i++) {
246
+ dotProduct += a[i] * b[i];
247
+ normA += a[i] * a[i];
248
+ normB += b[i] * b[i];
249
+ }
250
+ normA = Math.sqrt(normA);
251
+ normB = Math.sqrt(normB);
252
+ if (normA === 0 || normB === 0) {
253
+ return 0;
254
+ }
255
+ return dotProduct / (normA * normB);
256
+ }
257
+ };
258
+ var EuclideanSimilarity = class {
259
+ compute(a, b) {
260
+ if (a.length !== b.length) {
261
+ throw new Error(`Vector dimensions must match: ${a.length} !== ${b.length}`);
262
+ }
263
+ let sumSquares = 0;
264
+ for (let i = 0; i < a.length; i++) {
265
+ const diff = a[i] - b[i];
266
+ sumSquares += diff * diff;
267
+ }
268
+ const distance = Math.sqrt(sumSquares);
269
+ return 1 / (1 + distance);
270
+ }
271
+ };
272
+ var DotProductSimilarity = class {
273
+ compute(a, b) {
274
+ if (a.length !== b.length) {
275
+ throw new Error(`Vector dimensions must match: ${a.length} !== ${b.length}`);
276
+ }
277
+ let dotProduct = 0;
278
+ for (let i = 0; i < a.length; i++) {
279
+ dotProduct += a[i] * b[i];
280
+ }
281
+ return dotProduct;
282
+ }
283
+ };
284
+ var PriorityScoring = class {
285
+ maxScore;
286
+ constructor(maxScore = 1) {
287
+ this.maxScore = maxScore;
288
+ }
289
+ score(similarity, tool) {
290
+ const priority = tool.metadata.priority ?? 1;
291
+ const boosted = similarity * priority;
292
+ return Math.min(boosted, this.maxScore);
293
+ }
294
+ };
295
+ var WeightedScoring = class {
296
+ similarityWeight;
297
+ priorityWeight;
298
+ maxScore;
299
+ constructor(similarityWeight = 0.8, priorityWeight = 0.2, maxScore = 1) {
300
+ this.similarityWeight = similarityWeight;
301
+ this.priorityWeight = priorityWeight;
302
+ this.maxScore = maxScore;
303
+ }
304
+ score(similarity, tool) {
305
+ const priority = tool.metadata.priority ?? 1;
306
+ const normalizedPriority = Math.min(priority / 2, 1);
307
+ const weighted = this.similarityWeight * similarity + this.priorityWeight * normalizedPriority;
308
+ return Math.min(weighted, this.maxScore);
309
+ }
310
+ };
311
+ var TagBoostScoring = class {
312
+ boostTags;
313
+ boostFactor;
314
+ maxScore;
315
+ constructor(boostTags = [], boostFactor = 1.5, maxScore = 1) {
316
+ this.boostTags = new Set(boostTags);
317
+ this.boostFactor = boostFactor;
318
+ this.maxScore = maxScore;
319
+ }
320
+ score(similarity, tool) {
321
+ const toolTags = new Set(tool.metadata.tags ?? []);
322
+ const hasMatchingTag = [...toolTags].some((tag) => this.boostTags.has(tag));
323
+ const boosted = hasMatchingTag ? similarity * this.boostFactor : similarity;
324
+ return Math.min(boosted, this.maxScore);
325
+ }
326
+ };
327
+ var CompositeScoring = class {
328
+ scorers;
329
+ constructor(scorers) {
330
+ this.scorers = scorers;
331
+ }
332
+ score(similarity, tool) {
333
+ let currentScore = similarity;
334
+ for (const scorer of this.scorers) {
335
+ currentScore = scorer.score(currentScore, tool);
336
+ }
337
+ return currentScore;
338
+ }
339
+ };
340
+ var DEFAULT_SIMILARITY = new CosineSimilarity();
341
+ var DEFAULT_SCORING = new PriorityScoring();
342
+
343
+ // src/store.ts
344
+ var VectorStore = class {
345
+ tools = [];
346
+ embeddings = [];
347
+ /**
348
+ * Add a tool with its embedding to the store
349
+ */
350
+ add(tool, embedding) {
351
+ tool.embedding = embedding;
352
+ this.tools.push(tool);
353
+ this.embeddings.push(embedding);
354
+ }
355
+ /**
356
+ * Add multiple tools with embeddings
357
+ */
358
+ addBatch(tools, embeddings) {
359
+ for (let i = 0; i < tools.length; i++) {
360
+ this.add(tools[i], embeddings[i]);
361
+ }
362
+ }
363
+ /**
364
+ * Search for similar tools
365
+ *
366
+ * @param queryEmbedding - The query embedding vector
367
+ * @param topK - Maximum number of results
368
+ * @param threshold - Minimum score to include
369
+ * @param similarityFn - Custom similarity function (defaults to cosine)
370
+ * @param scoringFn - Custom scoring function (defaults to priority scoring)
371
+ */
372
+ search(queryEmbedding, topK = 5, threshold = 0, similarityFn, scoringFn) {
373
+ if (this.tools.length === 0) {
374
+ return [];
375
+ }
376
+ const simFn = similarityFn ?? DEFAULT_SIMILARITY;
377
+ const scoreFn = scoringFn ?? DEFAULT_SCORING;
378
+ const matches = [];
379
+ for (let i = 0; i < this.tools.length; i++) {
380
+ const tool = this.tools[i];
381
+ const embedding = this.embeddings[i];
382
+ const similarity = simFn.compute(queryEmbedding, embedding);
383
+ const finalScore = scoreFn.score(similarity, tool);
384
+ if (finalScore >= threshold) {
385
+ matches.push({ tool, score: finalScore });
386
+ }
387
+ }
388
+ matches.sort((a, b) => b.score - a.score);
389
+ return matches.slice(0, topK);
390
+ }
391
+ /**
392
+ * Remove a tool by name
393
+ */
394
+ remove(toolName) {
395
+ const index = this.tools.findIndex((t) => t.name === toolName);
396
+ if (index !== -1) {
397
+ this.tools.splice(index, 1);
398
+ this.embeddings.splice(index, 1);
399
+ return true;
400
+ }
401
+ return false;
402
+ }
403
+ /**
404
+ * Remove all tools from the store
405
+ */
406
+ clear() {
407
+ this.tools = [];
408
+ this.embeddings = [];
409
+ }
410
+ /**
411
+ * Get a tool by name
412
+ */
413
+ get(toolName) {
414
+ return this.tools.find((t) => t.name === toolName);
415
+ }
416
+ /**
417
+ * Number of tools in the store
418
+ */
419
+ get size() {
420
+ return this.tools.length;
421
+ }
422
+ /**
423
+ * Check if a tool exists by name
424
+ */
425
+ has(toolName) {
426
+ return this.tools.some((t) => t.name === toolName);
427
+ }
428
+ /**
429
+ * Get all tools
430
+ */
431
+ getAll() {
432
+ return [...this.tools];
433
+ }
434
+ };
435
+
436
+ // src/formatters.ts
437
+ var RawFormatter = class {
438
+ name = "raw";
439
+ format(tool) {
440
+ return tool.schema;
441
+ }
442
+ };
443
+ var OpenAIFormatter = class {
444
+ name = "openai";
445
+ format(tool) {
446
+ return {
447
+ type: "function",
448
+ function: tool.schema
449
+ };
450
+ }
451
+ };
452
+ var AnthropicFormatter = class {
453
+ name = "anthropic";
454
+ format(tool) {
455
+ return {
456
+ name: tool.schema.name,
457
+ description: tool.schema.description,
458
+ input_schema: tool.schema.parameters
459
+ };
460
+ }
461
+ };
462
+ var GeminiFormatter = class {
463
+ name = "gemini";
464
+ format(tool) {
465
+ return {
466
+ name: tool.schema.name,
467
+ description: tool.schema.description,
468
+ parameters: tool.schema.parameters
469
+ };
470
+ }
471
+ };
472
+ var MistralFormatter = class {
473
+ name = "mistral";
474
+ format(tool) {
475
+ return {
476
+ type: "function",
477
+ function: {
478
+ name: tool.schema.name,
479
+ description: tool.schema.description,
480
+ parameters: tool.schema.parameters
481
+ }
482
+ };
483
+ }
484
+ };
485
+ var LlamaFormatter = class {
486
+ name = "llama";
487
+ format(tool) {
488
+ return {
489
+ type: "function",
490
+ function: {
491
+ name: tool.schema.name,
492
+ description: tool.schema.description,
493
+ parameters: tool.schema.parameters
494
+ }
495
+ };
496
+ }
497
+ };
498
+ var CohereFormatter = class {
499
+ name = "cohere";
500
+ format(tool) {
501
+ const params = tool.schema.parameters;
502
+ const properties = params.properties;
503
+ const required = new Set(params.required);
504
+ const parameterDefinitions = {};
505
+ for (const [name, prop] of Object.entries(properties)) {
506
+ parameterDefinitions[name] = {
507
+ type: prop.type ?? "string",
508
+ description: prop.description ?? "",
509
+ required: required.has(name)
510
+ };
511
+ }
512
+ return {
513
+ name: tool.schema.name,
514
+ description: tool.schema.description,
515
+ parameter_definitions: parameterDefinitions
516
+ };
517
+ }
518
+ };
519
+ var MinimalFormatter = class {
520
+ name = "minimal";
521
+ format(tool) {
522
+ return {
523
+ name: tool.schema.name,
524
+ description: tool.schema.description
525
+ };
526
+ }
527
+ };
528
+ var VerboseFormatter = class {
529
+ name = "verbose";
530
+ format(tool) {
531
+ return {
532
+ name: tool.name,
533
+ schema: tool.schema,
534
+ score: tool.score,
535
+ hasHandler: tool.handler !== void 0
536
+ };
537
+ }
538
+ };
539
+ var formatters = /* @__PURE__ */ new Map();
540
+ function registerFormatter(formatter) {
541
+ formatters.set(formatter.name, formatter);
542
+ }
543
+ function unregisterFormatter(name) {
544
+ return formatters.delete(name);
545
+ }
546
+ function getFormatter(name) {
547
+ const formatter = formatters.get(name);
548
+ if (!formatter) {
549
+ const available = Array.from(formatters.keys()).join(", ");
550
+ throw new Error(`Unknown formatter '${name}'. Available: ${available}`);
551
+ }
552
+ return formatter;
553
+ }
554
+ function listFormatters() {
555
+ return Array.from(formatters.keys());
556
+ }
557
+ function hasFormatter(name) {
558
+ return formatters.has(name);
559
+ }
560
+ function formatTools(tools, formatter) {
561
+ const fmt = typeof formatter === "string" ? getFormatter(formatter) : formatter;
562
+ if (fmt.formatBatch) {
563
+ return fmt.formatBatch(tools);
564
+ }
565
+ return tools.map((tool) => fmt.format(tool));
566
+ }
567
+ function registerDefaults() {
568
+ const defaults = [
569
+ new RawFormatter(),
570
+ new OpenAIFormatter(),
571
+ new AnthropicFormatter(),
572
+ new GeminiFormatter(),
573
+ new MistralFormatter(),
574
+ new LlamaFormatter(),
575
+ new CohereFormatter(),
576
+ new MinimalFormatter(),
577
+ new VerboseFormatter()
578
+ ];
579
+ for (const formatter of defaults) {
580
+ registerFormatter(formatter);
581
+ }
582
+ }
583
+ registerDefaults();
584
+
585
+ // src/hooks.ts
586
+ var HookType = /* @__PURE__ */ ((HookType2) => {
587
+ HookType2["PRE_REGISTER"] = "pre_register";
588
+ HookType2["POST_REGISTER"] = "post_register";
589
+ HookType2["PRE_EMBED"] = "pre_embed";
590
+ HookType2["POST_EMBED"] = "post_embed";
591
+ HookType2["PRE_RESOLVE"] = "pre_resolve";
592
+ HookType2["POST_RESOLVE"] = "post_resolve";
593
+ HookType2["PRE_SEARCH"] = "pre_search";
594
+ HookType2["POST_SEARCH"] = "post_search";
595
+ HookType2["PRE_EXECUTE"] = "pre_execute";
596
+ HookType2["POST_EXECUTE"] = "post_execute";
597
+ return HookType2;
598
+ })(HookType || {});
599
+ function createContext(hookType, data = {}) {
600
+ return {
601
+ hookType,
602
+ data,
603
+ cancelled: false,
604
+ error: null
605
+ };
606
+ }
607
+ function cancelContext(context, reason) {
608
+ context.cancelled = true;
609
+ if (reason) {
610
+ context.data.cancelReason = reason;
611
+ }
612
+ }
613
+ function setContextError(context, error) {
614
+ context.error = error;
615
+ context.cancelled = true;
616
+ }
617
+ function createHook(hookType, fn, priority = 0) {
618
+ return {
619
+ hookType,
620
+ priority,
621
+ execute: fn
622
+ };
623
+ }
624
+ var HookRegistry = class {
625
+ hooks = /* @__PURE__ */ new Map();
626
+ constructor() {
627
+ for (const type of Object.values(HookType)) {
628
+ this.hooks.set(type, []);
629
+ }
630
+ }
631
+ /**
632
+ * Register a hook
633
+ */
634
+ register(hook) {
635
+ const hooks = this.hooks.get(hook.hookType) ?? [];
636
+ hooks.push(hook);
637
+ hooks.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
638
+ this.hooks.set(hook.hookType, hooks);
639
+ }
640
+ /**
641
+ * Register a function as a hook
642
+ */
643
+ on(hookType, fn, priority = 0) {
644
+ const hook = createHook(hookType, fn, priority);
645
+ this.register(hook);
646
+ return hook;
647
+ }
648
+ /**
649
+ * Unregister a hook
650
+ */
651
+ unregister(hook) {
652
+ const hooks = this.hooks.get(hook.hookType) ?? [];
653
+ const index = hooks.indexOf(hook);
654
+ if (index !== -1) {
655
+ hooks.splice(index, 1);
656
+ return true;
657
+ }
658
+ return false;
659
+ }
660
+ /**
661
+ * Clear hooks
662
+ */
663
+ clear(hookType) {
664
+ if (hookType) {
665
+ this.hooks.set(hookType, []);
666
+ } else {
667
+ for (const type of Object.values(HookType)) {
668
+ this.hooks.set(type, []);
669
+ }
670
+ }
671
+ }
672
+ /**
673
+ * Get all hooks for a type
674
+ */
675
+ getHooks(hookType) {
676
+ return [...this.hooks.get(hookType) ?? []];
677
+ }
678
+ /**
679
+ * Check if any hooks are registered for a type
680
+ */
681
+ hasHooks(hookType) {
682
+ return (this.hooks.get(hookType) ?? []).length > 0;
683
+ }
684
+ /**
685
+ * Run all hooks of a given type
686
+ */
687
+ async run(hookType, context) {
688
+ const hooks = this.hooks.get(hookType) ?? [];
689
+ for (const hook of hooks) {
690
+ if (context.cancelled) {
691
+ break;
692
+ }
693
+ try {
694
+ const result = hook.execute(context);
695
+ if (result instanceof Promise) {
696
+ context = await result;
697
+ } else {
698
+ context = result;
699
+ }
700
+ } catch (error) {
701
+ setContextError(context, error);
702
+ break;
703
+ }
704
+ }
705
+ return context;
706
+ }
707
+ };
708
+ var LoggingHook = class {
709
+ hookType;
710
+ priority = 0;
711
+ logger;
712
+ constructor(hookType, logger) {
713
+ this.hookType = hookType;
714
+ this.logger = logger ?? console.log;
715
+ }
716
+ execute(context) {
717
+ this.logger(`[${this.hookType}] data=${JSON.stringify(context.data)}`);
718
+ return context;
719
+ }
720
+ };
721
+ var TimingHook = class {
722
+ hookType;
723
+ priority = 0;
724
+ preHook;
725
+ postHook;
726
+ timingKey;
727
+ constructor(preHook, postHook, timingKey = "timing") {
728
+ this.preHook = preHook;
729
+ this.postHook = postHook;
730
+ this.hookType = preHook;
731
+ this.timingKey = timingKey;
732
+ }
733
+ execute(context) {
734
+ if (context.hookType === this.preHook) {
735
+ context.data[`${this.timingKey}Start`] = performance.now();
736
+ } else if (context.hookType === this.postHook) {
737
+ const start = context.data[`${this.timingKey}Start`];
738
+ if (start) {
739
+ const duration = performance.now() - start;
740
+ context.data[`${this.timingKey}Ms`] = duration;
741
+ }
742
+ }
743
+ return context;
744
+ }
745
+ };
746
+ var MetricsHook = class {
747
+ hookType;
748
+ priority = 0;
749
+ count = 0;
750
+ errors = 0;
751
+ constructor(hookType) {
752
+ this.hookType = hookType;
753
+ }
754
+ execute(context) {
755
+ this.count++;
756
+ if (context.error) {
757
+ this.errors++;
758
+ }
759
+ return context;
760
+ }
761
+ reset() {
762
+ this.count = 0;
763
+ this.errors = 0;
764
+ }
765
+ };
766
+ var CachingHook = class {
767
+ hookType = "pre_resolve" /* PRE_RESOLVE */;
768
+ priority = 100;
769
+ // Run early to check cache
770
+ cache = /* @__PURE__ */ new Map();
771
+ maxSize;
772
+ constructor(maxSize = 100) {
773
+ this.maxSize = maxSize;
774
+ }
775
+ execute(context) {
776
+ if (context.hookType === "pre_resolve" /* PRE_RESOLVE */) {
777
+ const query = context.data.query;
778
+ if (query && this.cache.has(query)) {
779
+ context.data.cachedResults = this.cache.get(query);
780
+ context.data.cacheHit = true;
781
+ }
782
+ } else if (context.hookType === "post_resolve" /* POST_RESOLVE */) {
783
+ const query = context.data.query;
784
+ const results = context.data.results;
785
+ if (query && results && !this.cache.has(query)) {
786
+ if (this.cache.size >= this.maxSize) {
787
+ const firstKey = this.cache.keys().next().value;
788
+ if (firstKey) {
789
+ this.cache.delete(firstKey);
790
+ }
791
+ }
792
+ this.cache.set(query, results);
793
+ }
794
+ }
795
+ return context;
796
+ }
797
+ clearCache() {
798
+ this.cache.clear();
799
+ }
800
+ get cacheSize() {
801
+ return this.cache.size;
802
+ }
803
+ };
804
+
805
+ // src/validators.ts
806
+ function createValidationResult(valid, errors = [], warnings = []) {
807
+ return { valid, errors, warnings };
808
+ }
809
+ function mergeValidationResults(a, b) {
810
+ return {
811
+ valid: a.valid && b.valid,
812
+ errors: [...a.errors, ...b.errors],
813
+ warnings: [...a.warnings, ...b.warnings]
814
+ };
815
+ }
816
+ var ValidationError = class extends Error {
817
+ result;
818
+ constructor(result) {
819
+ super(`Validation failed: ${result.errors.join(", ")}`);
820
+ this.name = "ValidationError";
821
+ this.result = result;
822
+ }
823
+ };
824
+ var ALLOWED_TYPES = /* @__PURE__ */ new Set([
825
+ "string",
826
+ "integer",
827
+ "number",
828
+ "boolean",
829
+ "array",
830
+ "object",
831
+ "null"
832
+ ]);
833
+ var ToolSchemaValidator = class {
834
+ options;
835
+ constructor(options = {}) {
836
+ this.options = {
837
+ requireDescription: options.requireDescription ?? true,
838
+ requireParameters: options.requireParameters ?? false,
839
+ minDescriptionLength: options.minDescriptionLength ?? 0,
840
+ maxDescriptionLength: options.maxDescriptionLength ?? 1e3
841
+ };
842
+ }
843
+ validate(tool) {
844
+ const errors = [];
845
+ const warnings = [];
846
+ if (!tool.name) {
847
+ errors.push("Tool name is required");
848
+ } else if (!/^[\w-]+$/.test(tool.name)) {
849
+ warnings.push(`Tool name '${tool.name}' contains special characters`);
850
+ }
851
+ if (this.options.requireDescription && !tool.description) {
852
+ errors.push("Tool description is required");
853
+ } else if (tool.description) {
854
+ if (tool.description.length < this.options.minDescriptionLength) {
855
+ errors.push(
856
+ `Description must be at least ${this.options.minDescriptionLength} characters`
857
+ );
858
+ }
859
+ if (tool.description.length > this.options.maxDescriptionLength) {
860
+ errors.push(
861
+ `Description must be at most ${this.options.maxDescriptionLength} characters`
862
+ );
863
+ }
864
+ }
865
+ if (this.options.requireParameters && Object.keys(tool.parameters).length === 0) {
866
+ errors.push("Tool parameters are required");
867
+ }
868
+ for (const [name, param] of Object.entries(tool.parameters)) {
869
+ if (param.type && !ALLOWED_TYPES.has(param.type)) {
870
+ errors.push(`Parameter '${name}' has invalid type '${param.type}'`);
871
+ }
872
+ }
873
+ return createValidationResult(errors.length === 0, errors, warnings);
874
+ }
875
+ };
876
+ var ParameterValidator = class {
877
+ options;
878
+ constructor(options = {}) {
879
+ this.options = {
880
+ strict: options.strict ?? false,
881
+ allowExtra: options.allowExtra ?? true
882
+ };
883
+ }
884
+ validate(data) {
885
+ const { tool, params } = data;
886
+ const errors = [];
887
+ const warnings = [];
888
+ if (!tool) {
889
+ errors.push("Tool is required for parameter validation");
890
+ return createValidationResult(false, errors, warnings);
891
+ }
892
+ const properties = tool.parameters;
893
+ if (this.options.strict) {
894
+ for (const [name, param] of Object.entries(properties)) {
895
+ if (param.required !== false && !(name in params)) {
896
+ errors.push(`Missing required parameter: ${name}`);
897
+ }
898
+ }
899
+ }
900
+ for (const [name, value] of Object.entries(params)) {
901
+ if (!(name in properties)) {
902
+ if (!this.options.allowExtra) {
903
+ errors.push(`Unknown parameter: ${name}`);
904
+ } else {
905
+ warnings.push(`Extra parameter provided: ${name}`);
906
+ }
907
+ continue;
908
+ }
909
+ const param = properties[name];
910
+ const typeError = this.checkType(name, value, param.type);
911
+ if (typeError) {
912
+ errors.push(typeError);
913
+ }
914
+ }
915
+ return createValidationResult(errors.length === 0, errors, warnings);
916
+ }
917
+ checkType(name, value, expectedType) {
918
+ if (!expectedType) return null;
919
+ const typeMap = {
920
+ string: (v) => typeof v === "string",
921
+ integer: (v) => Number.isInteger(v),
922
+ number: (v) => typeof v === "number",
923
+ boolean: (v) => typeof v === "boolean",
924
+ array: (v) => Array.isArray(v),
925
+ object: (v) => typeof v === "object" && v !== null && !Array.isArray(v),
926
+ null: (v) => v === null
927
+ };
928
+ const checker = typeMap[expectedType];
929
+ if (checker && !checker(value)) {
930
+ return `Parameter '${name}' expected ${expectedType}, got ${typeof value}`;
931
+ }
932
+ return null;
933
+ }
934
+ };
935
+ var ResultValidator = class {
936
+ options;
937
+ constructor(options = {}) {
938
+ this.options = {
939
+ strict: options.strict ?? false
940
+ };
941
+ }
942
+ validate(data) {
943
+ const { tool, result } = data;
944
+ const errors = [];
945
+ const warnings = [];
946
+ if (!tool) {
947
+ errors.push("Tool is required for result validation");
948
+ return createValidationResult(false, errors, warnings);
949
+ }
950
+ if (tool.returns) {
951
+ const expectedType = tool.returns.type;
952
+ const typeError = this.checkReturnType(result, expectedType);
953
+ if (typeError) {
954
+ if (this.options.strict) {
955
+ errors.push(typeError);
956
+ } else {
957
+ warnings.push(typeError);
958
+ }
959
+ }
960
+ }
961
+ return createValidationResult(errors.length === 0, errors, warnings);
962
+ }
963
+ checkReturnType(value, expectedType) {
964
+ if (!expectedType) return null;
965
+ const typeMap = {
966
+ string: (v) => typeof v === "string",
967
+ integer: (v) => Number.isInteger(v),
968
+ number: (v) => typeof v === "number",
969
+ boolean: (v) => typeof v === "boolean",
970
+ array: (v) => Array.isArray(v),
971
+ object: (v) => typeof v === "object" && v !== null && !Array.isArray(v),
972
+ null: (v) => v === null
973
+ };
974
+ const checker = typeMap[expectedType];
975
+ if (checker && !checker(value)) {
976
+ return `Result expected ${expectedType}, got ${typeof value}`;
977
+ }
978
+ return null;
979
+ }
980
+ };
981
+ var EmbeddingValidator = class {
982
+ options;
983
+ constructor(options = {}) {
984
+ this.options = options;
985
+ }
986
+ validate(embedding) {
987
+ const errors = [];
988
+ const warnings = [];
989
+ if (!Array.isArray(embedding)) {
990
+ errors.push("Embedding must be an array");
991
+ return createValidationResult(false, errors, warnings);
992
+ }
993
+ if (embedding.length === 0) {
994
+ errors.push("Embedding cannot be empty");
995
+ return createValidationResult(false, errors, warnings);
996
+ }
997
+ if (this.options.expectedDimensions !== void 0 && embedding.length !== this.options.expectedDimensions) {
998
+ errors.push(
999
+ `Embedding dimensions mismatch: expected ${this.options.expectedDimensions}, got ${embedding.length}`
1000
+ );
1001
+ }
1002
+ for (let i = 0; i < embedding.length; i++) {
1003
+ if (typeof embedding[i] !== "number") {
1004
+ errors.push(`Embedding value at index ${i} is not numeric`);
1005
+ break;
1006
+ }
1007
+ }
1008
+ if (this.options.checkNormalization && errors.length === 0) {
1009
+ let sumSquares = 0;
1010
+ for (const val of embedding) {
1011
+ sumSquares += val * val;
1012
+ }
1013
+ const norm = Math.sqrt(sumSquares);
1014
+ if (Math.abs(norm - 1) > 0.01) {
1015
+ warnings.push(`Embedding is not normalized (norm=${norm.toFixed(4)})`);
1016
+ }
1017
+ }
1018
+ return createValidationResult(errors.length === 0, errors, warnings);
1019
+ }
1020
+ };
1021
+ var CompositeValidator = class {
1022
+ validators;
1023
+ constructor(validators) {
1024
+ this.validators = validators;
1025
+ }
1026
+ validate(data) {
1027
+ let result = createValidationResult(true);
1028
+ for (const validator of this.validators) {
1029
+ const subResult = validator.validate(data);
1030
+ result = mergeValidationResults(result, subResult);
1031
+ }
1032
+ return result;
1033
+ }
1034
+ };
1035
+ var ValidatorRegistry = class {
1036
+ schemaValidators = [];
1037
+ parameterValidators = [];
1038
+ resultValidators = [];
1039
+ embeddingValidators = [];
1040
+ addSchemaValidator(validator) {
1041
+ this.schemaValidators.push(validator);
1042
+ }
1043
+ addParameterValidator(validator) {
1044
+ this.parameterValidators.push(validator);
1045
+ }
1046
+ addResultValidator(validator) {
1047
+ this.resultValidators.push(validator);
1048
+ }
1049
+ addEmbeddingValidator(validator) {
1050
+ this.embeddingValidators.push(validator);
1051
+ }
1052
+ validateTool(tool) {
1053
+ let result = createValidationResult(true);
1054
+ for (const validator of this.schemaValidators) {
1055
+ const subResult = validator.validate(tool);
1056
+ result = mergeValidationResults(result, subResult);
1057
+ }
1058
+ return result;
1059
+ }
1060
+ validateParams(tool, params) {
1061
+ let result = createValidationResult(true);
1062
+ for (const validator of this.parameterValidators) {
1063
+ const subResult = validator.validate({ tool, params });
1064
+ result = mergeValidationResults(result, subResult);
1065
+ }
1066
+ return result;
1067
+ }
1068
+ validateResult(tool, resultValue) {
1069
+ let result = createValidationResult(true);
1070
+ for (const validator of this.resultValidators) {
1071
+ const subResult = validator.validate({ tool, result: resultValue });
1072
+ result = mergeValidationResults(result, subResult);
1073
+ }
1074
+ return result;
1075
+ }
1076
+ validateEmbedding(embedding) {
1077
+ let result = createValidationResult(true);
1078
+ for (const validator of this.embeddingValidators) {
1079
+ const subResult = validator.validate(embedding);
1080
+ result = mergeValidationResults(result, subResult);
1081
+ }
1082
+ return result;
1083
+ }
1084
+ clear() {
1085
+ this.schemaValidators = [];
1086
+ this.parameterValidators = [];
1087
+ this.resultValidators = [];
1088
+ this.embeddingValidators = [];
1089
+ }
1090
+ };
1091
+ function createStrictValidator() {
1092
+ const registry = new ValidatorRegistry();
1093
+ registry.addSchemaValidator(
1094
+ new ToolSchemaValidator({
1095
+ requireDescription: true,
1096
+ minDescriptionLength: 10
1097
+ })
1098
+ );
1099
+ registry.addParameterValidator(new ParameterValidator({ strict: true }));
1100
+ registry.addResultValidator(new ResultValidator({ strict: true }));
1101
+ return registry;
1102
+ }
1103
+ function createLenientValidator() {
1104
+ const registry = new ValidatorRegistry();
1105
+ registry.addSchemaValidator(
1106
+ new ToolSchemaValidator({
1107
+ requireDescription: false,
1108
+ minDescriptionLength: 0
1109
+ })
1110
+ );
1111
+ registry.addParameterValidator(
1112
+ new ParameterValidator({
1113
+ strict: false,
1114
+ allowExtra: true
1115
+ })
1116
+ );
1117
+ registry.addResultValidator(new ResultValidator({ strict: false }));
1118
+ return registry;
1119
+ }
1120
+
1121
+ // src/sis.ts
1122
+ var SIS = class {
1123
+ _embeddings;
1124
+ _vectorStore;
1125
+ _pendingTools;
1126
+ _defaultTopK;
1127
+ _defaultThreshold;
1128
+ _initialized;
1129
+ _remoteUrl;
1130
+ _projectId;
1131
+ // Customization systems
1132
+ _similarity;
1133
+ _scoring;
1134
+ _hooks;
1135
+ _validators;
1136
+ _validateOnRegister;
1137
+ _validateOnExecute;
1138
+ constructor(options = {}) {
1139
+ const {
1140
+ embeddingProvider = "openai",
1141
+ defaultTopK = 5,
1142
+ defaultThreshold = 0.3,
1143
+ providerOptions = {},
1144
+ similarity,
1145
+ scoring,
1146
+ validators,
1147
+ validateOnRegister = false,
1148
+ validateOnExecute = false
1149
+ } = options;
1150
+ if (typeof embeddingProvider === "string") {
1151
+ this._embeddings = getProvider(embeddingProvider, providerOptions);
1152
+ } else {
1153
+ this._embeddings = embeddingProvider;
1154
+ }
1155
+ this._vectorStore = new VectorStore();
1156
+ this._pendingTools = [];
1157
+ this._defaultTopK = defaultTopK;
1158
+ this._defaultThreshold = defaultThreshold;
1159
+ this._initialized = false;
1160
+ this._remoteUrl = options.remoteUrl;
1161
+ this._projectId = options.projectId;
1162
+ this._similarity = similarity ?? DEFAULT_SIMILARITY;
1163
+ this._scoring = scoring ?? DEFAULT_SCORING;
1164
+ this._hooks = new HookRegistry();
1165
+ this._validators = validators;
1166
+ this._validateOnRegister = validateOnRegister;
1167
+ this._validateOnExecute = validateOnExecute;
1168
+ }
1169
+ // Properties for accessing customization systems
1170
+ /** Get the hook registry for registering middleware */
1171
+ get hooks() {
1172
+ return this._hooks;
1173
+ }
1174
+ /** Get the validator registry */
1175
+ get validators() {
1176
+ return this._validators;
1177
+ }
1178
+ /** Get the current similarity function */
1179
+ get similarity() {
1180
+ return this._similarity;
1181
+ }
1182
+ /** Set a new similarity function */
1183
+ set similarity(fn) {
1184
+ this._similarity = fn;
1185
+ }
1186
+ /** Get the current scoring function */
1187
+ get scoring() {
1188
+ return this._scoring;
1189
+ }
1190
+ /** Set a new scoring function */
1191
+ set scoring(fn) {
1192
+ this._scoring = fn;
1193
+ }
1194
+ /** Register a hook */
1195
+ registerHook(hook) {
1196
+ this._hooks.register(hook);
1197
+ }
1198
+ /** Unregister a hook */
1199
+ unregisterHook(hook) {
1200
+ return this._hooks.unregister(hook);
1201
+ }
1202
+ /**
1203
+ * Register a tool programmatically
1204
+ */
1205
+ register(options) {
1206
+ const tool = {
1207
+ name: options.name,
1208
+ description: options.description,
1209
+ parameters: options.parameters ?? {},
1210
+ semanticHints: options.semanticHints ?? [],
1211
+ examples: options.examples ?? [],
1212
+ handler: options.handler,
1213
+ metadata: options.metadata ?? {}
1214
+ };
1215
+ if (this._validateOnRegister && this._validators) {
1216
+ const result = this._validators.validateTool(tool);
1217
+ if (!result.valid) {
1218
+ throw new ValidationError(result);
1219
+ }
1220
+ }
1221
+ this._pendingTools.push(tool);
1222
+ return tool;
1223
+ }
1224
+ /**
1225
+ * Store (upsert) a tool with a precomputed embedding.
1226
+ *
1227
+ * This bypasses the embedding provider, allowing custom embedding workflows.
1228
+ */
1229
+ store(options) {
1230
+ const tool = {
1231
+ name: options.name,
1232
+ description: options.description,
1233
+ parameters: options.parameters ?? {},
1234
+ semanticHints: options.semanticHints ?? [],
1235
+ examples: options.examples ?? [],
1236
+ handler: options.handler,
1237
+ metadata: options.metadata ?? {}
1238
+ };
1239
+ if (this._validateOnRegister && this._validators) {
1240
+ const result = this._validators.validateTool(tool);
1241
+ if (!result.valid) {
1242
+ throw new ValidationError(result);
1243
+ }
1244
+ }
1245
+ if (this._validators) {
1246
+ const embeddingResult = this._validators.validateEmbedding(options.embedding);
1247
+ if (!embeddingResult.valid) {
1248
+ throw new ValidationError(embeddingResult);
1249
+ }
1250
+ }
1251
+ if (options.embedding.length !== this._embeddings.dimensions) {
1252
+ throw new Error(
1253
+ `Embedding dimensions must match provider: ${options.embedding.length} !== ${this._embeddings.dimensions}`
1254
+ );
1255
+ }
1256
+ if (this._vectorStore.has(tool.name)) {
1257
+ this._vectorStore.remove(tool.name);
1258
+ }
1259
+ this._vectorStore.add(tool, options.embedding);
1260
+ return tool;
1261
+ }
1262
+ /**
1263
+ * Initialize embeddings for all pending tools
1264
+ */
1265
+ async initialize() {
1266
+ if (this._pendingTools.length === 0) {
1267
+ this._initialized = true;
1268
+ return;
1269
+ }
1270
+ let ctx = createContext("pre_embed" /* PRE_EMBED */, { tools: this._pendingTools });
1271
+ ctx = await this._hooks.run("pre_embed" /* PRE_EMBED */, ctx);
1272
+ if (ctx.cancelled) {
1273
+ return;
1274
+ }
1275
+ const texts = this._pendingTools.map(
1276
+ (tool) => buildToolText(
1277
+ tool.name,
1278
+ tool.description,
1279
+ tool.semanticHints,
1280
+ tool.examples
1281
+ )
1282
+ );
1283
+ const embeddings = await this._embeddings.embedBatch(texts);
1284
+ this._vectorStore.addBatch(this._pendingTools, embeddings);
1285
+ ctx = createContext("post_embed" /* POST_EMBED */, {
1286
+ tools: this._pendingTools,
1287
+ embeddings
1288
+ });
1289
+ await this._hooks.run("post_embed" /* POST_EMBED */, ctx);
1290
+ this._pendingTools = [];
1291
+ this._initialized = true;
1292
+ }
1293
+ /**
1294
+ * Resolve tools for a query
1295
+ */
1296
+ async resolve(query, options = {}) {
1297
+ if (!this._initialized) {
1298
+ await this.initialize();
1299
+ }
1300
+ const topK = options.topK ?? this._defaultTopK;
1301
+ const threshold = options.threshold ?? this._defaultThreshold;
1302
+ const format = options.format ?? "raw";
1303
+ let ctx = createContext("pre_resolve" /* PRE_RESOLVE */, {
1304
+ query,
1305
+ topK,
1306
+ threshold,
1307
+ format
1308
+ });
1309
+ ctx = await this._hooks.run("pre_resolve" /* PRE_RESOLVE */, ctx);
1310
+ if (ctx.cancelled) {
1311
+ if (ctx.data.cachedResults) {
1312
+ return ctx.data.cachedResults;
1313
+ }
1314
+ return [];
1315
+ }
1316
+ const finalQuery = ctx.data.query ?? query;
1317
+ const finalTopK = ctx.data.topK ?? topK;
1318
+ const finalThreshold = ctx.data.threshold ?? threshold;
1319
+ if (this._remoteUrl && this._projectId) {
1320
+ const response = await fetch(
1321
+ `${this._remoteUrl}/v1/projects/${this._projectId}/resolve`,
1322
+ {
1323
+ method: "POST",
1324
+ headers: { "Content-Type": "application/json" },
1325
+ body: JSON.stringify({ query: finalQuery, top_k: finalTopK, threshold: finalThreshold })
1326
+ }
1327
+ );
1328
+ if (!response.ok) {
1329
+ throw new Error(`Remote resolution failed: ${response.statusText}`);
1330
+ }
1331
+ const data = await response.json();
1332
+ const results2 = data.results;
1333
+ return this.formatResults(results2, format);
1334
+ }
1335
+ const queryEmbedding = await this._embeddings.embed(finalQuery);
1336
+ let searchCtx = createContext("pre_search" /* PRE_SEARCH */, {
1337
+ query: finalQuery,
1338
+ queryEmbedding,
1339
+ topK: finalTopK,
1340
+ threshold: finalThreshold
1341
+ });
1342
+ searchCtx = await this._hooks.run("pre_search" /* PRE_SEARCH */, searchCtx);
1343
+ const matches = this._vectorStore.search(
1344
+ queryEmbedding,
1345
+ finalTopK,
1346
+ finalThreshold,
1347
+ this._similarity,
1348
+ this._scoring
1349
+ );
1350
+ let postSearchCtx = createContext("post_search" /* POST_SEARCH */, {
1351
+ query: finalQuery,
1352
+ matches
1353
+ });
1354
+ postSearchCtx = await this._hooks.run("post_search" /* POST_SEARCH */, postSearchCtx);
1355
+ const finalMatches = postSearchCtx.data.matches ?? matches;
1356
+ const resolved = finalMatches.map((match) => ({
1357
+ name: match.tool.name,
1358
+ schema: toSchema(match.tool),
1359
+ score: match.score,
1360
+ handler: match.tool.handler
1361
+ }));
1362
+ const results = this.formatResults(resolved, format);
1363
+ let postCtx = createContext("post_resolve" /* POST_RESOLVE */, {
1364
+ query: finalQuery,
1365
+ results,
1366
+ resolved
1367
+ });
1368
+ postCtx = await this._hooks.run("post_resolve" /* POST_RESOLVE */, postCtx);
1369
+ return postCtx.data.results ?? results;
1370
+ }
1371
+ /**
1372
+ * Format results based on format option
1373
+ */
1374
+ formatResults(resolved, format) {
1375
+ if (format === "raw") {
1376
+ return resolved;
1377
+ }
1378
+ if (typeof format === "object" && "format" in format) {
1379
+ return formatTools(resolved, format);
1380
+ }
1381
+ if (typeof format === "string") {
1382
+ if (hasFormatter(format)) {
1383
+ return formatTools(resolved, format);
1384
+ }
1385
+ if (format === "openai") {
1386
+ return resolved.map((r) => ({
1387
+ type: "function",
1388
+ function: r.schema
1389
+ }));
1390
+ }
1391
+ if (format === "anthropic") {
1392
+ return resolved.map((r) => ({
1393
+ name: r.schema.name,
1394
+ description: r.schema.description,
1395
+ input_schema: r.schema.parameters
1396
+ }));
1397
+ }
1398
+ throw new Error(`Unknown format: ${format}`);
1399
+ }
1400
+ return resolved;
1401
+ }
1402
+ /**
1403
+ * Resolve the single best matching tool
1404
+ */
1405
+ async resolveOne(query, threshold) {
1406
+ const results = await this.resolve(query, { topK: 1, threshold });
1407
+ return results.length > 0 ? results[0] : null;
1408
+ }
1409
+ /**
1410
+ * Get a registered tool by name
1411
+ */
1412
+ getTool(name) {
1413
+ return this._vectorStore.get(name);
1414
+ }
1415
+ /**
1416
+ * List all registered tool names
1417
+ */
1418
+ listTools() {
1419
+ return this._vectorStore.getAll().map((t) => t.name);
1420
+ }
1421
+ /**
1422
+ * Number of registered tools
1423
+ */
1424
+ get toolCount() {
1425
+ return this._vectorStore.size + this._pendingTools.length;
1426
+ }
1427
+ /**
1428
+ * Execute a tool by name
1429
+ */
1430
+ async execute(toolName, params) {
1431
+ const tool = this._vectorStore.get(toolName);
1432
+ if (!tool) {
1433
+ throw new Error(`Tool not found: ${toolName}`);
1434
+ }
1435
+ if (!tool.handler) {
1436
+ throw new Error(`Tool has no handler: ${toolName}`);
1437
+ }
1438
+ let ctx = createContext("pre_execute" /* PRE_EXECUTE */, {
1439
+ tool,
1440
+ toolName,
1441
+ params
1442
+ });
1443
+ ctx = await this._hooks.run("pre_execute" /* PRE_EXECUTE */, ctx);
1444
+ if (ctx.cancelled) {
1445
+ if (ctx.error) {
1446
+ throw ctx.error;
1447
+ }
1448
+ return null;
1449
+ }
1450
+ if (this._validateOnExecute && this._validators) {
1451
+ const paramsResult = this._validators.validateParams(tool, params);
1452
+ if (!paramsResult.valid) {
1453
+ throw new ValidationError(paramsResult);
1454
+ }
1455
+ }
1456
+ const result = await tool.handler(params);
1457
+ if (this._validateOnExecute && this._validators) {
1458
+ const resultValidation = this._validators.validateResult(tool, result);
1459
+ if (!resultValidation.valid) {
1460
+ throw new ValidationError(resultValidation);
1461
+ }
1462
+ }
1463
+ let postCtx = createContext("post_execute" /* POST_EXECUTE */, {
1464
+ tool,
1465
+ toolName,
1466
+ params,
1467
+ result
1468
+ });
1469
+ postCtx = await this._hooks.run("post_execute" /* POST_EXECUTE */, postCtx);
1470
+ return postCtx.data.result ?? result;
1471
+ }
1472
+ };
1473
+
1474
+ export { AnthropicFormatter, CachingHook, CohereEmbeddings, CohereFormatter, CompositeScoring, CompositeValidator, CosineSimilarity, DEFAULT_SCORING, DEFAULT_SIMILARITY, DotProductSimilarity, EmbeddingValidator, EuclideanSimilarity, GeminiFormatter, GoogleEmbeddings, HookRegistry, HookType, LlamaFormatter, LoggingHook, MetricsHook, MinimalFormatter, MistralFormatter, OpenAIEmbeddings, OpenAIFormatter, ParameterValidator, PriorityScoring, RawFormatter, ResultValidator, SIS, TagBoostScoring, TimingHook, ToolSchemaValidator, ValidationError, ValidatorRegistry, VectorStore, VerboseFormatter, WeightedScoring, cancelContext, createContext, createHook, createLenientValidator, createStrictValidator, createValidationResult, formatTools, getFormatter, getProvider, hasFormatter, listFormatters, mergeValidationResults, registerFormatter, setContextError, toAnthropicSchema, toOpenAISchema, toSchema, unregisterFormatter };
1475
+ //# sourceMappingURL=index.js.map
1476
+ //# sourceMappingURL=index.js.map