@neuledge/graph 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,381 @@
1
+ <div align="center">
2
+
3
+ # @neuledge/graph
4
+
5
+
6
+ **Give LLMs real knowledge — structured, live, and reliable — so they reason with facts, not guesses.**
7
+
8
+ [![npm version](https://img.shields.io/npm/v/@neuledge/graph.svg)](https://www.npmjs.com/package/@neuledge/graph)
9
+ [![License](https://img.shields.io/npm/l/@neuledge/graph.svg)](https://github.com/neuledge/graph/blob/main/LICENSE)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
11
+
12
+ [How it works](#-how-it-works) • [Examples](#-examples) • [Installation](#-installation) • [API Reference](#-api-reference)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## Overview
19
+
20
+ `@neuledge/graph` connects your AI to live, structured data sources so your models can answer with certainty. Stop hallucinations before they happen by grounding your LLM in real-time, verified data.
21
+
22
+ ### Why @neuledge/graph?
23
+
24
+ Your AI agent gets asked: *"What's the weather in Tokyo?"*
25
+
26
+ **Your options:**
27
+ 1. 🤷 **Let the LLM guess** → "Tokyo is typically mild this time of year..." (Wrong)
28
+ 2. 🐌 **Web search tool** → 3-5 seconds, parse HTML, unstructured results
29
+ 3. 🔧 **Build custom integration** → Sign up for API, handle auth, write parsers
30
+ 4. ⚡ **Use @neuledge/graph** → `lookup({ query: "cities.tokyo.weather" })` → Done in <100ms
31
+
32
+ **One tool. Live data. Zero setup.**
33
+
34
+ - ✅ **Instant** - Pre-fetched & cached data returns in <100ms
35
+ - ✅ **Structured** - Clean JSON your LLM can reason about
36
+ - ✅ **Trusted** - Real sources, not scraped web pages
37
+ - ✅ **Universal** - Same tool for weather, stocks, FX, and more
38
+
39
+ <br>
40
+
41
+ ## ⚡ How it works
42
+
43
+ ```typescript
44
+ // 1. Create a knowledge graph instance
45
+ const graph = new NeuledgeGraph();
46
+
47
+ // 2. Pass the lookup tool to your AI agent
48
+ const agent = new Agent({
49
+ model: 'claude-sonnet-4-5',
50
+ tools: { lookup: tool(graph.lookup) },
51
+ });
52
+
53
+ // 3. Ask questions - the agent will fetch live data automatically
54
+ const { text } = await agent.generate({
55
+ prompt: 'What is the weather in San Francisco?',
56
+ });
57
+
58
+ // => "San Francisco is sunny, about 68°F."
59
+ ```
60
+
61
+ 👉 See full working examples with [Vercel AI SDK](#with-vercel-ai-sdk), [OpenAI Agents SDK](#with-openai-agents-sdk), and [LangChain](#with-langchain).
62
+
63
+ <br>
64
+
65
+ ## 🚀 Use Cases
66
+
67
+ | Prompt | Example Output |
68
+ | -------------------------------------------- | ------------------------------------------------ |
69
+ | `What is the weather in San Francisco?` | `San Francisco is sunny, about 68°F.` |
70
+ | `What time is it in Tokyo?` | `It's 3:42 PM JST.` |
71
+ | `When is the next Monday?` | `The next Monday is on February 10, 2025.` |
72
+ | `When is Thanksgiving next year?` | `Thanksgiving in 2026 falls on November 26.` |
73
+ | `How much is $250 in euros?` | `$250 equals €215.` |
74
+ | `Price of Apple stock?` | `Apple (AAPL) is trading at $175.20` |
75
+ | `Latest headlines about AI` | *Coming soon…* |
76
+ | `Who won the Lakers game last night?` | *Coming soon…* |
77
+ | `What's the current Bitcoin price?` | *Coming soon…* |
78
+
79
+ <br>
80
+
81
+ ## 🥇 Key Features
82
+
83
+ - **Answers in <100ms** – Pre-cached data means your AI responds instantly, not after slow web searches
84
+ - **One tool, unlimited sources** – Weather, stocks, currency, and more through a single `lookup()` call
85
+ - **LLM-optimized responses** – Structured JSON designed for reasoning, not messy HTML to parse
86
+ - **Works everywhere** – Drop into Vercel AI SDK, OpenAI Agents, LangChain, or any framework
87
+ - **Zero configuration** – No API keys to juggle, no rate limits to manage, no parsers to write
88
+ - **Type-safe & predictable** – Full TypeScript support with discriminated unions for response types
89
+ - **Bring your own data** – Connect your databases and APIs for instant, grounded responses *(coming soon)*
90
+
91
+ <br>
92
+
93
+ ## 💿 Installation
94
+
95
+ ```bash
96
+ pnpm add @neuledge/graph zod
97
+ ```
98
+
99
+ ```bash
100
+ npm install @neuledge/graph zod
101
+ ```
102
+
103
+ ```bash
104
+ yarn add @neuledge/graph zod
105
+ ```
106
+
107
+ <br>
108
+
109
+ ## 📚 Examples
110
+
111
+ ### With Vercel AI SDK
112
+
113
+ ```typescript
114
+ import { anthropic } from "@ai-sdk/anthropic";
115
+ import { NeuledgeGraph } from "@neuledge/graph";
116
+ import { Experimental_Agent as Agent, stepCountIs, tool } from "ai";
117
+
118
+ const graph = new NeuledgeGraph();
119
+
120
+ const agent = new Agent({
121
+ model: anthropic("claude-sonnet-4-5"),
122
+ tools: {
123
+ lookup: tool(graph.lookup),
124
+ },
125
+ stopWhen: stepCountIs(20),
126
+ });
127
+
128
+ const { textStream } = agent.stream({
129
+ prompt: "Compare Apple and Microsoft stock prices",
130
+ });
131
+
132
+ for await (const textPart of textStream) {
133
+ process.stdout.write(textPart);
134
+ }
135
+ process.stdout.write("\n");
136
+ ```
137
+
138
+ ### With OpenAI Agents SDK
139
+
140
+ ```typescript
141
+ import { NeuledgeGraph } from "@neuledge/graph";
142
+ import { Agent, run, tool } from "@openai/agents";
143
+
144
+ const graph = new NeuledgeGraph();
145
+
146
+ const agent = new Agent({
147
+ name: "Data Assistant",
148
+ model: "gpt-4.1",
149
+ tools: [tool(graph.lookup)],
150
+ });
151
+
152
+ const result = await run(agent, "What is the current price of Apple stock?");
153
+ console.log(result);
154
+ ```
155
+
156
+ ### With LangChain
157
+
158
+ ```typescript
159
+ // make sure to install all the following packages:
160
+ // $ npm install @neuledge/graph langchain @langchain/openai @langchain/core zod zod-to-json-schema
161
+
162
+ import { NeuledgeGraph } from "@neuledge/graph";
163
+ import { createAgent, tool } from "langchain";
164
+
165
+ // Create the tool from the graph lookup function
166
+ const graph = new NeuledgeGraph();
167
+
168
+ const lookup = tool(graph.lookup, graph.lookup);
169
+
170
+ // Create the agent with an OpenAI LLM
171
+ const agent = createAgent({
172
+ model: "openai:gpt-4.1",
173
+ tools: [lookup],
174
+ });
175
+
176
+ // Invoke the agent
177
+ const result = await agent.invoke({
178
+ messages: [
179
+ { role: "user", content: "What is the exchange rate from USD to EUR?" },
180
+ ],
181
+ });
182
+ console.log(result);
183
+ ```
184
+
185
+ <br>
186
+
187
+ ## 🔐 Authentication & Rate Limits
188
+
189
+ By default, `@neuledge/graph` is free to use without authentication.
190
+ To increase your request limit, generate a **free API key**.
191
+
192
+ | Access Type | Requests Limit | Per-Minute Limit |
193
+ |--------------|-------------------|------------------|
194
+ | Anonymous | 100 / day | 5 requests/min |
195
+ | Free API Key | 10,000 / month | 60 requests/min |
196
+ | Pro Plan | *Coming soon* | *Coming soon* |
197
+
198
+ ### Getting a Free API Key
199
+
200
+ Run the following command:
201
+
202
+ ```bash
203
+ npx @neuledge/graph sign-up your-email@example.com
204
+ ```
205
+
206
+ You'll receive an API key via email:
207
+
208
+ ```bash
209
+ NEULEDGE_API_KEY='sk_xxxxxxxxx'
210
+ ```
211
+
212
+ ### Using Your API Key
213
+
214
+ Pass the key when initializing the graph:
215
+
216
+ ```typescript
217
+ import "dotenv/config";
218
+ import { NeuledgeGraph } from '@neuledge/graph';
219
+
220
+ const graph = new NeuledgeGraph({
221
+ apiKey: process.env.NEULEDGE_API_KEY
222
+ });
223
+ ```
224
+
225
+ **Best Practice:** Store your API key in environment variables and never commit it to version control.
226
+
227
+ ### Building a Custom Server
228
+
229
+ For advanced use cases, you can build your own knowledge graph server using the router and registry packages:
230
+
231
+ ```typescript
232
+ // Install: npm install @neuledge/graph-router @neuledge/graph-memory-registry fastify
233
+ import { NeuledgeGraphRouter } from "@neuledge/graph-router";
234
+ import { NeuledgeGraphMemoryRegistry } from "@neuledge/graph-memory-registry";
235
+ import { openai } from "ai";
236
+ import Fastify from "fastify";
237
+
238
+ // Create registry with embedding model
239
+ const registry = new NeuledgeGraphMemoryRegistry({
240
+ model: openai.embedding("text-embedding-3-small"),
241
+ });
242
+
243
+ // Register your data sources
244
+ await registry.register({
245
+ template: "cities.{city}.weather",
246
+ resolver: async (match) => {
247
+ const city = match.params.city;
248
+ const response = await fetch(`https://api.weather.com/current?city=${city}`);
249
+ return response.json();
250
+ },
251
+ });
252
+
253
+ // Create router
254
+ const router = new NeuledgeGraphRouter({ registry });
255
+
256
+ // Set up HTTP server
257
+ const app = Fastify();
258
+
259
+ app.post("/lookup", async (request, reply) => {
260
+ const result = await router.lookup(request.body);
261
+ return reply.send(result);
262
+ });
263
+
264
+ app.listen({ port: 3000 });
265
+ ```
266
+
267
+ See [graph-router](https://github.com/neuledge/graph/tree/main/packages/graph-router) and [graph-memory-registry](https://github.com/neuledge/graph/tree/main/packages/graph-memory-registry) packages for detailed documentation.
268
+
269
+ ### Connecting to a Custom Server
270
+
271
+ Once you have a custom server running, connect to it using the `baseUrl` option:
272
+
273
+ ```typescript
274
+ import { NeuledgeGraph } from "@neuledge/graph";
275
+
276
+ // Connect to your custom server
277
+ const graph = new NeuledgeGraph({
278
+ baseUrl: "http://localhost:3000",
279
+ });
280
+
281
+ // Use it the same way as with the default server
282
+ const result = await graph.lookup({ query: "cities.tokyo.weather" });
283
+ console.log(result); // => { status: "matched", match: {...}, value: {...} }
284
+ ```
285
+
286
+ You can now use this graph instance with any AI framework, and it will query your custom knowledge graph server instead of the default Neuledge service.
287
+
288
+ <br>
289
+
290
+ ## 🛠 API Reference
291
+
292
+ ### `NeuledgeGraph`
293
+
294
+ The main class for interacting with the knowledge graph.
295
+
296
+ #### Constructor Options
297
+
298
+ ```typescript
299
+ interface NeuledgeGraphOptions {
300
+ apiKey?: string; // Your API key (optional for free tier)
301
+ baseUrl?: string; // Custom API endpoint (optional)
302
+ timeout?: number; // Request timeout in ms (default: 10000)
303
+ }
304
+ ```
305
+
306
+ #### Example
307
+
308
+ ```typescript
309
+ const graph = new NeuledgeGraph({
310
+ apiKey: process.env.NEULEDGE_API_KEY,
311
+ timeout: 5000,
312
+ });
313
+ ```
314
+
315
+ ### `graph.lookup` Tool
316
+
317
+ The `lookup` tool is designed to be a **first-class tool** in any AI framework that supports function calling.
318
+
319
+ #### Properties
320
+
321
+ - **`lookup`** (`function`) – The function that fetches live data
322
+ - **`lookup.name`** (`string`) - The name of the tool (`"lookup"`)
323
+ - **`lookup.description`** (`string`) – Instructions for the LLM on how to use the tool
324
+ - **`lookup.parameters`** (`object`) – JSON Schema defining expected inputs
325
+ - **`lookup.execute`** (`function`) – same as calling `lookup` directly
326
+
327
+
328
+ <br>
329
+
330
+ ## 🎯 Supported Data Sources
331
+
332
+ Currently available:
333
+ - ☀️ **Weather** - Current weather and forecasts for any location
334
+ - 💱 **Currency Exchange** - Live FX rates for 150+ currencies
335
+ - 📈 **Stock Market** - Current stock prices and market data
336
+
337
+ Coming soon:
338
+ - 📰 News & headlines
339
+ - ⚽ Sports scores & schedules
340
+ - 🪙 Cryptocurrency prices
341
+ - 🗺️ Geographic data
342
+ - 📊 Economic indicators
343
+
344
+ Want to request a data source? [Open an issue](https://github.com/neuledge/graph/issues/new)!
345
+
346
+ <br>
347
+
348
+ ## Development Setup
349
+
350
+ ```bash
351
+ # Clone the repository
352
+ git clone https://github.com/neuledge/graph.git
353
+ cd graph
354
+
355
+ # Install dependencies
356
+ npm install
357
+
358
+ # Run tests
359
+ npm test
360
+
361
+ # Build the project
362
+ npm run build
363
+ ```
364
+
365
+ <br>
366
+
367
+ ## 📄 License
368
+
369
+ Apache-2.0 © Neuledge
370
+
371
+ See [LICENSE](LICENSE) for more information.
372
+
373
+ <br>
374
+
375
+ ---
376
+
377
+ <div align="center">
378
+
379
+ **Built with ❤️ by Neuledge**
380
+
381
+ </div>
package/bin/cli.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+
3
+ const [, , command, ...args] = process.argv;
4
+
5
+ const NEULEDGE_API_BASE_URL = "https://api.graph.neuledge.com/v1";
6
+
7
+ (async () => {
8
+ try {
9
+ switch (command) {
10
+ case "sign-up": {
11
+ const email = args[0];
12
+ if (!email) {
13
+ console.error("Usage: sign-up <email>");
14
+ process.exit(1);
15
+ }
16
+
17
+ console.log("Signing up…");
18
+
19
+ const result = await signUp(email);
20
+
21
+ console.log("✅ Signed up successfully");
22
+ if (result?.message) {
23
+ console.log(result.message);
24
+ }
25
+
26
+ break;
27
+ }
28
+
29
+ case undefined:
30
+ case "help":
31
+ printHelp();
32
+ break;
33
+
34
+ default:
35
+ console.error(`Unknown command: ${command}`);
36
+ process.exit(1);
37
+ }
38
+ } catch (err) {
39
+ console.error("❌", err.message);
40
+ process.exit(1);
41
+ }
42
+ })();
43
+
44
+ function printHelp() {
45
+ console.log(`
46
+ Usage:
47
+ graph sign-up <email>
48
+
49
+ Commands:
50
+ sign-up Register an email
51
+ help Showing this message
52
+
53
+ Examples:
54
+ graph sign-up your@email.com
55
+ `);
56
+ }
57
+
58
+ async function signUp(email) {
59
+ if (!email.includes("@")) {
60
+ throw new TypeError("Invalid email address");
61
+ }
62
+
63
+ const controller = new AbortController();
64
+ setTimeout(() => controller.abort(), 10_000);
65
+
66
+ const res = await fetch(`${NEULEDGE_API_BASE_URL}/cli/sign-up`, {
67
+ method: "POST",
68
+ headers: {
69
+ "Content-Type": "application/json",
70
+ },
71
+ body: JSON.stringify({ email }),
72
+ abort: controller.signal,
73
+ }).catch(() => {
74
+ throw new Error("Error while accessing the server");
75
+ });
76
+
77
+ if (!res.ok) {
78
+ const text = await res
79
+ .json()
80
+ .then((body) => {
81
+ const message = body?.error?.message;
82
+ if (!message) {
83
+ throw new Error("Invalid error format");
84
+ }
85
+
86
+ return message;
87
+ })
88
+ .catch(() => res.text());
89
+ throw new Error(`Sign-up failed (${res.status}): ${text}`);
90
+ }
91
+
92
+ return res.json();
93
+ }
@@ -0,0 +1,11 @@
1
+ import { NeuledgeError } from "./error.js";
2
+ import type { NeuledgeGraph } from "./index.js";
3
+ export interface ApiFetchParams {
4
+ method?: "GET" | "POST" | "PUT" | "DELETE";
5
+ url: string;
6
+ body?: object;
7
+ }
8
+ export interface NeuledgeApiErrorResponse {
9
+ error: NeuledgeError;
10
+ }
11
+ export declare function apiFetch<T>(graph: NeuledgeGraph, params: ApiFetchParams): Promise<T>;
@@ -0,0 +1,31 @@
1
+ import { NeuledgeError } from "./error.js";
2
+ export async function apiFetch(graph, params) {
3
+ const url = `${graph.baseUrl}${params.url}`;
4
+ const headers = {
5
+ "Content-Type": "application/json",
6
+ };
7
+ if (graph.apiKey)
8
+ headers.Authorization = `Bearer ${graph.apiKey}`;
9
+ const res = await fetch(url, {
10
+ method: "POST",
11
+ headers,
12
+ body: params.body ? JSON.stringify(params.body) : undefined,
13
+ });
14
+ if (!res.ok) {
15
+ return res
16
+ .json()
17
+ .then((data) => {
18
+ const typed = data;
19
+ if (typeof typed?.error?.message !== "string") {
20
+ throw new Error(`Unknown error response`);
21
+ }
22
+ throw new NeuledgeError(typed.error.message);
23
+ })
24
+ .catch(() => {
25
+ throw new NeuledgeError(`NeuledgeGraph: Request failed with ${res.statusText}`);
26
+ });
27
+ }
28
+ const data = await res.json();
29
+ return data;
30
+ }
31
+ //# sourceMappingURL=api-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-fetch.js","sourceRoot":"","sources":["../src/api-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAa3C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAoB,EACpB,MAAsB;IAEtB,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IAC5C,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,CAAC,MAAM,EAAE,CAAC;IAEnE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC5D,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,GAAG;aACP,IAAI,EAAE;aACN,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,MAAM,KAAK,GAAG,IAAyC,CAAC;YACxD,IAAI,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,MAAM,IAAI,aAAa,CACrB,sCAAsC,GAAG,CAAC,UAAU,EAAE,CACvD,CAAC;QACJ,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,OAAO,IAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface NeuledgeError {
2
+ message: string;
3
+ }
4
+ declare class NeuledgeErrorImpl extends Error implements NeuledgeError {
5
+ constructor(message: string);
6
+ static from(error: NeuledgeError | unknown): NeuledgeError;
7
+ }
8
+ export declare const NeuledgeError: typeof NeuledgeErrorImpl;
9
+ export {};
package/dist/error.js ADDED
@@ -0,0 +1,22 @@
1
+ class NeuledgeErrorImpl extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "NeuledgeError";
5
+ // Maintain proper prototype chain for instanceof checks
6
+ Object.setPrototypeOf(this, NeuledgeError.prototype);
7
+ }
8
+ static from(error) {
9
+ if (error instanceof NeuledgeError) {
10
+ return error;
11
+ }
12
+ const message = String(error?.message || error);
13
+ const neuledgeError = new NeuledgeError(message);
14
+ // Preserve the original stack trace if available
15
+ const stack = error?.stack;
16
+ if (stack)
17
+ neuledgeError.stack = stack;
18
+ return neuledgeError;
19
+ }
20
+ }
21
+ export const NeuledgeError = NeuledgeErrorImpl;
22
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAIA,MAAM,iBAAkB,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAE5B,wDAAwD;QACxD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAA8B;QACxC,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAE,KAAuB,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;QACnE,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;QAEjD,iDAAiD;QACjD,MAAM,KAAK,GAAI,KAAe,EAAE,KAAK,CAAC;QACtC,IAAI,KAAK;YAAE,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC;QAEvC,OAAO,aAAa,CAAC;IACvB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { lookup } from "./lookup.js";
2
+ export interface NeuledgeGraphOptions {
3
+ apiKey?: string;
4
+ baseUrl?: string;
5
+ timeout?: number;
6
+ }
7
+ export declare class NeuledgeGraph {
8
+ apiKey?: string;
9
+ baseUrl: string;
10
+ timeout: number;
11
+ constructor(options?: NeuledgeGraphOptions);
12
+ lookup: typeof lookup;
13
+ }
package/dist/graph.js ADDED
@@ -0,0 +1,13 @@
1
+ import { lookup } from "./lookup.js";
2
+ export class NeuledgeGraph {
3
+ apiKey;
4
+ baseUrl;
5
+ timeout;
6
+ constructor(options = {}) {
7
+ this.apiKey = options.apiKey;
8
+ this.baseUrl = options.baseUrl || "https://api.graph.neuledge.com/v1";
9
+ this.timeout = options.timeout || 10000;
10
+ }
11
+ }
12
+ NeuledgeGraph.prototype.lookup = lookup;
13
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,MAAM,OAAO,aAAa;IACxB,MAAM,CAAU;IAChB,OAAO,CAAS;IAChB,OAAO,CAAS;IAEhB,YAAY,UAAgC,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,mCAAmC,CAAC;QACtE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IAC1C,CAAC;CAIF;AAED,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type { NeuledgeApiErrorResponse } from "./api-fetch.js";
2
+ export { NeuledgeError } from "./error.js";
3
+ export { NeuledgeGraph, type NeuledgeGraphOptions } from "./graph.js";
4
+ export { type NeuledgeGraphLookup, type NeuledgeGraphLookupAmbiguousResponse, type NeuledgeGraphLookupErrorResponse, type NeuledgeGraphLookupMatchedResponse, NeuledgeGraphLookupParams, type NeuledgeGraphLookupResponse, type NeuledgeGraphLookupResponseTemplate, } from "./lookup.js";
5
+ export type { NeuledgeGraphMatch, NeuledgeGraphTemplateParams, } from "./match.js";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { NeuledgeError } from "./error.js";
2
+ export { NeuledgeGraph } from "./graph.js";
3
+ export { NeuledgeGraphLookupParams, } from "./lookup.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAA6B,MAAM,YAAY,CAAC;AACtE,OAAO,EAKL,yBAAyB,GAG1B,MAAM,aAAa,CAAC"}
@@ -0,0 +1,36 @@
1
+ import * as z from "zod";
2
+ import { NeuledgeError } from "./error.js";
3
+ import type { NeuledgeGraph } from "./index.js";
4
+ export interface NeuledgeGraphLookup {
5
+ (this: NeuledgeGraph, params: NeuledgeGraphLookupParams): Promise<NeuledgeGraphLookupResponse | NeuledgeGraphLookupErrorResponse>;
6
+ name: string;
7
+ description: string;
8
+ parameters: typeof NeuledgeGraphLookupParams;
9
+ schema: typeof NeuledgeGraphLookupParams;
10
+ inputSchema: typeof NeuledgeGraphLookupParams;
11
+ execute: NeuledgeGraphLookup;
12
+ }
13
+ export type NeuledgeGraphLookupParams = z.infer<typeof NeuledgeGraphLookupParams>;
14
+ export declare const NeuledgeGraphLookupParams: z.ZodObject<{
15
+ query: z.ZodString;
16
+ }, z.core.$strip>;
17
+ export type NeuledgeGraphLookupResponse = NeuledgeGraphLookupMatchedResponse | NeuledgeGraphLookupAmbiguousResponse;
18
+ export interface NeuledgeGraphLookupMatchedResponse<T = unknown> {
19
+ status: "matched";
20
+ match: NeuledgeGraphLookupResponseTemplate;
21
+ value: T;
22
+ }
23
+ export interface NeuledgeGraphLookupAmbiguousResponse {
24
+ status: "ambiguous";
25
+ reasonCode: "UNKNOWN_PATH" | "INVALID_IDENTIFIER" | (string & {});
26
+ reasonHint: string;
27
+ suggestions: NeuledgeGraphLookupResponseTemplate[];
28
+ }
29
+ export interface NeuledgeGraphLookupResponseTemplate {
30
+ template: string;
31
+ }
32
+ export interface NeuledgeGraphLookupErrorResponse {
33
+ status: "error";
34
+ error: NeuledgeError;
35
+ }
36
+ export declare const lookup: NeuledgeGraphLookup;
package/dist/lookup.js ADDED
@@ -0,0 +1,111 @@
1
+ import * as z from "zod";
2
+ import { apiFetch } from "./api-fetch.js";
3
+ import { NeuledgeError } from "./error.js";
4
+ const description = `This tool provides access to **live, structured data** across a wide range of domains.
5
+
6
+ It ensures answers are **accurate and up-to-date**, preventing the model from relying on outdated information or hallucinating (e.g., old stock prices, past weather, or obsolete events).
7
+
8
+ Queries should use **\`snake_case\`** with dots between segments (\`lowercase.with_underscores\`).
9
+
10
+ The system tries to match your query to a **built-in template** and fill the \`{placeholders}\`.
11
+
12
+ * If a close template exists, you receive the structured data.
13
+ * If no exact match, the system returns **suggested templates** you can refine your query against.
14
+
15
+ **This tool supports many domains including (but not limited to):**
16
+ - Weather, time, and location data
17
+ - Financial data (stocks, currencies, markets)
18
+ - Calendar operations and holidays
19
+ - And many other live data sources
20
+
21
+ **The most popular templates used:**
22
+ * \`cities.{city}.weather\`
23
+ * \`cities.{city}.time\`
24
+ * \`stocks.{stock}.quote\`
25
+ * \`currencies.{from}.rate.{to}\`
26
+ * \`calendar.next.{weekday}\`
27
+ * \`calendar.in.{integer}.{unit}\`
28
+ * \`holidays.{holiday}.next\`
29
+
30
+ **Key principle:** Even if your query doesn't exactly match a template, the tool will **suggest the closest available templates**, allowing you to refine and retrieve the live data. When in doubt, try a query - the tool will guide you to the right template.`;
31
+ export const NeuledgeGraphLookupParams = z.object({
32
+ query: z
33
+ .string()
34
+ .describe(`A search query using snake_case and dots between segments (lowercase.with_underscores).`),
35
+ // context: z
36
+ // .object({
37
+ // units: z
38
+ // .enum(["auto", "metric", "imperial"])
39
+ // .default("auto")
40
+ // .describe(
41
+ // "Measurement system for applicable data (temperature, distance, etc.). 'auto' uses location-appropriate defaults.",
42
+ // )
43
+ // .optional(),
44
+ //
45
+ // date: z
46
+ // .string()
47
+ // .regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD format")
48
+ // .describe(
49
+ // "Reference date for time-sensitive queries. Defaults to current date if not specified.",
50
+ // )
51
+ // .optional(),
52
+ //
53
+ // amount: z
54
+ // .number()
55
+ // .positive()
56
+ // .describe(
57
+ // "Quantity for conversion queries (e.g., currency amounts). Defaults to 1 if not specified.",
58
+ // )
59
+ // .optional(),
60
+ //
61
+ // timezone: z
62
+ // .string()
63
+ // .regex(
64
+ // /^([A-Z]{2,5}|[A-Za-z]+\/[A-Za-z_]+)$/,
65
+ // "Must be a valid timezone (e.g., 'EST', 'America/New_York')",
66
+ // )
67
+ // .describe(
68
+ // "TTimezone for date/time queries (e.g., 'America/New_York', 'EST')",
69
+ // )
70
+ // .optional(),
71
+ //
72
+ // locale: z
73
+ // .string()
74
+ // .regex(
75
+ // /^[a-z]{2}(-[A-Z]{2})?$/,
76
+ // "Must be language code or language-country (e.g., 'en', 'en-US')",
77
+ // )
78
+ // .describe(
79
+ // "Locale for formatting numbers, dates, and currency. Affects output presentation.",
80
+ // )
81
+ // .optional(),
82
+ // })
83
+ // .describe(
84
+ // "Optional parameters that modify how data is retrieved or formatted.",
85
+ // )
86
+ // .optional(),
87
+ });
88
+ export const lookup = Object.assign(async function lookup(params) {
89
+ return await apiFetch(this, {
90
+ url: "/lookup",
91
+ method: "POST",
92
+ body: {
93
+ query: params.query,
94
+ // context: params.context,
95
+ },
96
+ }).catch((error) => ({
97
+ status: "error",
98
+ error: NeuledgeError.from(error),
99
+ }));
100
+ }, {
101
+ description,
102
+ parameters: NeuledgeGraphLookupParams,
103
+ schema: NeuledgeGraphLookupParams,
104
+ inputSchema: NeuledgeGraphLookupParams,
105
+ execute: null,
106
+ });
107
+ // force `name` property to be enumerable (fix LangChain bug)
108
+ Object.defineProperty(lookup, "name", { value: "lookup", enumerable: true });
109
+ // self assign `execute`
110
+ lookup.execute = lookup;
111
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../src/lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiB3C,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;kQA0B8O,CAAC;AAKnQ,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,CACP,yFAAyF,CAC1F;IAEH,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,gDAAgD;IAChD,2BAA2B;IAC3B,qBAAqB;IACrB,gIAAgI;IAChI,YAAY;IACZ,uBAAuB;IACvB,EAAE;IACF,gBAAgB;IAChB,oBAAoB;IACpB,qEAAqE;IACrE,qBAAqB;IACrB,qGAAqG;IACrG,YAAY;IACZ,uBAAuB;IACvB,EAAE;IACF,kBAAkB;IAClB,oBAAoB;IACpB,sBAAsB;IACtB,qBAAqB;IACrB,yGAAyG;IACzG,YAAY;IACZ,uBAAuB;IACvB,EAAE;IACF,oBAAoB;IACpB,oBAAoB;IACpB,kBAAkB;IAClB,oDAAoD;IACpD,0EAA0E;IAC1E,YAAY;IACZ,qBAAqB;IACrB,iFAAiF;IACjF,YAAY;IACZ,uBAAuB;IACvB,EAAE;IACF,kBAAkB;IAClB,oBAAoB;IACpB,kBAAkB;IAClB,sCAAsC;IACtC,+EAA+E;IAC/E,YAAY;IACZ,qBAAqB;IACrB,gGAAgG;IAChG,YAAY;IACZ,uBAAuB;IACvB,SAAS;IACT,iBAAiB;IACjB,+EAA+E;IAC/E,QAAQ;IACR,mBAAmB;CACpB,CAAC,CAAC;AA4BH,MAAM,CAAC,MAAM,MAAM,GAAwB,MAAM,CAAC,MAAM,CACtD,KAAK,UAAU,MAAM,CAEnB,MAAiC;IAEjC,OAAO,MAAM,QAAQ,CAA8B,IAAI,EAAE;QACvD,GAAG,EAAE,SAAS;QACd,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,2BAA2B;SACQ;KACtC,CAAC,CAAC,KAAK,CACN,CAAC,KAAK,EAAoC,EAAE,CAAC,CAAC;QAC5C,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;KACjC,CAAC,CACH,CAAC;AACJ,CAAC,EACD;IACE,WAAW;IACX,UAAU,EAAE,yBAAyB;IACrC,MAAM,EAAE,yBAAyB;IACjC,WAAW,EAAE,yBAAyB;IACtC,OAAO,EAAE,IAAa;CACvB,CACF,CAAC;AAEF,6DAA6D;AAC7D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AAE7E,wBAAwB;AACxB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface NeuledgeGraphMatch<Template extends string = string> {
2
+ template: Template;
3
+ params: NeuledgeGraphTemplateParams<Template>;
4
+ }
5
+ export type NeuledgeGraphTemplateParams<Template extends string = string> = Record<NeuledgeGraphTemplateParamsNames<Template>, string>;
6
+ type NeuledgeGraphTemplateParamsNames<T extends string> = T extends `${string}{${infer Param}}${infer Rest}` ? Param | NeuledgeGraphTemplateParamsNames<Rest> : never;
7
+ export {};
package/dist/match.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.js","sourceRoot":"","sources":["../src/match.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@neuledge/graph",
3
+ "version": "0.1.0",
4
+ "description": "Give LLMs real knowledge — structured, live, and reliable — so they reason with facts, not guesses.",
5
+ "keywords": [
6
+ "ai",
7
+ "llm",
8
+ "agents",
9
+ "openai",
10
+ "anthropic",
11
+ "langchain",
12
+ "vercel-ai",
13
+ "ai-sdk",
14
+ "tool",
15
+ "function-calling",
16
+ "structured-data",
17
+ "live-data",
18
+ "knowledge-graph",
19
+ "real-time-data",
20
+ "data-fetching",
21
+ "ai-integration",
22
+ "ai-tools",
23
+ "lookup",
24
+ "grounding",
25
+ "no-rag",
26
+ "no-indexes",
27
+ "json-api",
28
+ "data-layer",
29
+ "ai-infrastructure",
30
+ "neuledge",
31
+ "weather",
32
+ "stocks",
33
+ "price",
34
+ "fx",
35
+ "rates"
36
+ ],
37
+ "main": "dist/index.js",
38
+ "types": "dist/index.d.ts",
39
+ "type": "module",
40
+ "exports": {
41
+ ".": "./dist/index.js"
42
+ },
43
+ "files": [
44
+ "dist/",
45
+ "bin/",
46
+ "package.json",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "bin": "./bin/cli.js",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "author": "Neuledge",
55
+ "license": "Apache-2.0",
56
+ "devDependencies": {
57
+ "@ai-sdk/anthropic": "^2.0.50",
58
+ "@ai-sdk/openai": "^2.0.74",
59
+ "@langchain/core": "^1.0.1",
60
+ "@langchain/openai": "^1.0.0",
61
+ "@openai/agents": "^0.2.1",
62
+ "@total-typescript/tsconfig": "^1.0.4",
63
+ "@types/js-yaml": "^4.0.9",
64
+ "@types/node": "^24.9.1",
65
+ "ai": "^5.0.104",
66
+ "dotenv": "^17.2.3",
67
+ "js-yaml": "^4.1.1",
68
+ "langchain": "^1.0.1",
69
+ "rimraf": "^6.0.1",
70
+ "tsconfig-paths": "^4.2.0",
71
+ "tsx": "^4.20.6",
72
+ "typescript": "^5.9.3",
73
+ "vite-tsconfig-paths": "^5.1.4",
74
+ "vitest": "^4.0.3",
75
+ "zod": "^4.2.1",
76
+ "zod-to-json-schema": "^3.24.6"
77
+ },
78
+ "peerDependencies": {
79
+ "zod": ">=3"
80
+ },
81
+ "tsx": {
82
+ "require": [
83
+ "tsconfig-paths/register"
84
+ ]
85
+ },
86
+ "scripts": {
87
+ "build": "rimraf --glob dist/** && tsc -p tsconfig.build.json",
88
+ "test": "vitest run",
89
+ "test:watch": "vitest",
90
+ "evals": "vitest run --config vitest.config.evals.ts",
91
+ "lint": "npx biome ci --error-on-warnings",
92
+ "fix": "npx biome check --write"
93
+ }
94
+ }