sis-tools 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +311 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,311 @@
1
+ # sis-tools (Node.js)
2
+
3
+ Semantic Integration System (SIS) is a tool-resolution layer that uses embeddings to select the most relevant tools for a query at runtime.
4
+
5
+ Instead of sending every tool schema to an LLM up front, you resolve the top-k tools for the user’s query and only inject the relevant schemas.
6
+
7
+ ## Why SIS?
8
+
9
+ - **Context savings**: Only send relevant tool schemas to the LLM
10
+ - **Scalability**: Register hundreds of tools without bloating context
11
+ - **Semantic matching**: Uses embeddings to find tools by intent, not keywords
12
+ - **Flexible**: Works with OpenAI, Anthropic, Google, Cohere, and custom providers
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install sis-tools
18
+ ```
19
+
20
+ SIS supports optional embedding providers. Install only what you use:
21
+
22
+ ```bash
23
+ npm install openai # OpenAI embeddings
24
+ npm install @google/generative-ai # Google embeddings
25
+ npm install cohere-ai # Cohere embeddings
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ ```ts
31
+ import { SIS } from "sis-tools";
32
+
33
+ const sis = new SIS({
34
+ embeddingProvider: "openai",
35
+ providerOptions: {
36
+ apiKey: process.env.OPENAI_API_KEY,
37
+ },
38
+ defaultTopK: 5,
39
+ defaultThreshold: 0.3,
40
+ });
41
+
42
+ sis.register({
43
+ name: "web_search",
44
+ description: "Search the web for current information",
45
+ parameters: { query: { type: "string" } },
46
+ semanticHints: ["google", "lookup", "find online"],
47
+ handler: async ({ query }) => {
48
+ // your implementation
49
+ return String(query);
50
+ },
51
+ });
52
+
53
+ await sis.initialize();
54
+
55
+ const tools = await sis.resolve("search for latest news");
56
+ // tools: [{ name, schema, score, handler? }, ...]
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ ### Constructor options
62
+
63
+ ```ts
64
+ interface SISOptions {
65
+ embeddingProvider?: "openai" | "cohere" | "google" | EmbeddingProvider;
66
+ providerOptions?: {
67
+ apiKey?: string;
68
+ model?: string;
69
+ dimensions?: number;
70
+ [key: string]: unknown;
71
+ };
72
+ defaultTopK?: number; // default: 5
73
+ defaultThreshold?: number; // default: 0.3
74
+ similarity?: SimilarityFunction;
75
+ scoring?: ScoringFunction;
76
+ validators?: ValidatorRegistry;
77
+ validateOnRegister?: boolean;
78
+ validateOnExecute?: boolean;
79
+ }
80
+ ```
81
+
82
+ ### Tool registration
83
+
84
+ ```ts
85
+ interface RegisterOptions {
86
+ name: string;
87
+ description: string;
88
+ parameters?: ToolParameters;
89
+ handler?: ToolHandler;
90
+ semanticHints?: string[];
91
+ examples?: ToolExample[];
92
+ metadata?: ToolMetadata;
93
+ }
94
+ ```
95
+
96
+ ## Resolve formats
97
+
98
+ ```ts
99
+ await sis.resolve("query", { format: "openai" });
100
+ await sis.resolve("query", { format: "anthropic" });
101
+ await sis.resolve("query", { format: "raw" });
102
+ ```
103
+
104
+ ## Examples
105
+
106
+ ### Use with OpenAI function calling
107
+
108
+ ```ts
109
+ import { OpenAI } from "openai";
110
+ import { SIS } from "sis-tools";
111
+
112
+ const openai = new OpenAI();
113
+ const sis = new SIS({ embeddingProvider: "openai" });
114
+
115
+ sis.register({
116
+ name: "web_search",
117
+ description: "Search the web",
118
+ parameters: { query: { type: "string" } },
119
+ handler: async ({ query }) => searchApi(query),
120
+ });
121
+
122
+ await sis.initialize();
123
+
124
+ async function runAgent(userMessage: string) {
125
+ const tools = await sis.resolve(userMessage, { format: "openai" });
126
+
127
+ const response = await openai.chat.completions.create({
128
+ model: "gpt-4.1",
129
+ messages: [{ role: "user", content: userMessage }],
130
+ tools,
131
+ });
132
+
133
+ const toolCall = response.choices[0]?.message?.tool_calls?.[0];
134
+ if (toolCall) {
135
+ const result = await sis.execute(
136
+ toolCall.function.name,
137
+ JSON.parse(toolCall.function.arguments)
138
+ );
139
+ return result;
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### Use with Anthropic tool use
145
+
146
+ ```ts
147
+ import Anthropic from "@anthropic-ai/sdk";
148
+ import { SIS } from "sis-tools";
149
+
150
+ const anthropic = new Anthropic();
151
+ const sis = new SIS({ embeddingProvider: "openai" });
152
+
153
+ await sis.initialize();
154
+
155
+ async function runAgent(userMessage: string) {
156
+ const tools = await sis.resolve(userMessage, { format: "anthropic" });
157
+
158
+ const response = await anthropic.messages.create({
159
+ model: "claude-3-5-sonnet-20241022",
160
+ max_tokens: 1024,
161
+ messages: [{ role: "user", content: userMessage }],
162
+ tools,
163
+ });
164
+
165
+ const toolUse = response.content.find((b) => b.type === "tool_use");
166
+ if (toolUse) {
167
+ const result = await sis.execute(toolUse.name, toolUse.input);
168
+ return result;
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### Bring your own embeddings
174
+
175
+ ```ts
176
+ import { SIS } from "sis-tools";
177
+ import type { EmbeddingProvider } from "sis-tools";
178
+
179
+ class MyEmbeddings implements EmbeddingProvider {
180
+ readonly dimensions = 768;
181
+
182
+ async embed(text: string): Promise<number[]> {
183
+ const res = await fetch("https://my-embedding-service/embed", {
184
+ method: "POST",
185
+ headers: { "Content-Type": "application/json" },
186
+ body: JSON.stringify({ text }),
187
+ });
188
+ const { embedding } = await res.json();
189
+ return embedding;
190
+ }
191
+
192
+ async embedBatch(texts: string[]): Promise<number[][]> {
193
+ const res = await fetch("https://my-embedding-service/embed-batch", {
194
+ method: "POST",
195
+ headers: { "Content-Type": "application/json" },
196
+ body: JSON.stringify({ texts }),
197
+ });
198
+ const { embeddings } = await res.json();
199
+ return embeddings;
200
+ }
201
+ }
202
+
203
+ const sis = new SIS({ embeddingProvider: new MyEmbeddings() });
204
+ ```
205
+
206
+ ### Custom scoring (priority boost)
207
+
208
+ ```ts
209
+ import { SIS, PriorityScoring } from "sis-tools";
210
+
211
+ const sis = new SIS({
212
+ embeddingProvider: "openai",
213
+ scoring: new PriorityScoring(1.0),
214
+ });
215
+
216
+ sis.register({
217
+ name: "important_tool",
218
+ description: "An important tool",
219
+ metadata: { priority: 2.0 },
220
+ });
221
+
222
+ await sis.initialize();
223
+ ```
224
+
225
+ ### Validation on register/execute
226
+
227
+ ```ts
228
+ import { SIS, createStrictValidator } from "sis-tools";
229
+
230
+ const sis = new SIS({
231
+ embeddingProvider: "openai",
232
+ validators: createStrictValidator(),
233
+ validateOnRegister: true,
234
+ validateOnExecute: true,
235
+ });
236
+
237
+ // Throws ValidationError if tool schema is invalid
238
+ sis.register({
239
+ name: "bad_tool",
240
+ description: "x", // too short
241
+ parameters: {},
242
+ });
243
+ ```
244
+
245
+ ## API
246
+
247
+ ### SIS
248
+
249
+ ```ts
250
+ class SIS {
251
+ constructor(options: SISOptions)
252
+
253
+ register(options: RegisterOptions): Tool
254
+ store(options: StoreOptions): void
255
+ async initialize(): Promise<void>
256
+
257
+ async resolve(query: string, options?: ResolveOptions): Promise<ResolvedTool[]>
258
+ async resolveOne(query: string, threshold?: number): Promise<ResolvedTool | null>
259
+
260
+ async execute(toolName: string, params: object): Promise<unknown>
261
+
262
+ getTool(name: string): Tool | undefined
263
+ listTools(): string[]
264
+ get toolCount(): number
265
+
266
+ // Customization
267
+ get hooks(): HookRegistry
268
+ get validators(): ValidatorRegistry | undefined
269
+ get similarity(): SimilarityFunction
270
+ set similarity(fn: SimilarityFunction)
271
+ get scoring(): ScoringFunction
272
+ set scoring(fn: ScoringFunction)
273
+ registerHook(hook: Hook): void
274
+ unregisterHook(hook: Hook): boolean
275
+ }
276
+ ```
277
+
278
+ ### ResolveOptions
279
+
280
+ ```ts
281
+ interface ResolveOptions {
282
+ topK?: number;
283
+ threshold?: number;
284
+ format?: "raw" | "openai" | "anthropic" | string | ToolFormatter;
285
+ }
286
+ ```
287
+
288
+ ## Troubleshooting
289
+
290
+ ### Provider not found
291
+
292
+ If you see an error like `requires the openai package`, install the peer dependency:
293
+
294
+ ```bash
295
+ npm install openai
296
+ ```
297
+
298
+ ### No tools returned
299
+
300
+ - Lower `defaultThreshold` (try `0.0` to see all matches)
301
+ - Increase `defaultTopK`
302
+ - Check tool descriptions and `semanticHints` for clarity
303
+
304
+ ### Slow initialization
305
+
306
+ - Use a faster embedding model (e.g., `text-embedding-3-small`)
307
+ - Consider caching embeddings or using a persistent vector store
308
+
309
+ ## License
310
+
311
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sis-tools",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Semantic Integration System - Intelligent tool resolution for LLMs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",