@synoppy/ai-sdk 1.0.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 +21 -0
- package/README.md +70 -0
- package/dist/index.d.ts +137 -0
- package/dist/index.js +149 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Saanora
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @synoppy/ai-sdk
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@synoppy/ai-sdk) [](./LICENSE)
|
|
4
|
+
|
|
5
|
+
**Give your AI SDK agent the whole web.** [Synoppy](https://synoppy.com) tools for the [Vercel AI SDK](https://ai-sdk.dev) — drop them into `generateText` / `streamText` and your agent can read, search, crawl, map, extract, classify, enrich, screenshot, and pull images from the live web, all on one key.
|
|
6
|
+
|
|
7
|
+
[**Get a free key →**](https://synoppy.com/dashboard) · [Docs](https://synoppy.com/docs) · [synoppy.com](https://synoppy.com)
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @synoppy/ai-sdk ai zod
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`ai` (v5+) and `zod` are peer dependencies — you almost certainly already have `ai`.
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { generateText } from "ai";
|
|
21
|
+
import { openai } from "@ai-sdk/openai";
|
|
22
|
+
import { synoppyTools } from "@synoppy/ai-sdk";
|
|
23
|
+
|
|
24
|
+
const { text } = await generateText({
|
|
25
|
+
model: openai("gpt-4o"),
|
|
26
|
+
tools: synoppyTools({ apiKey: process.env.SYNOPPY_API_KEY! }),
|
|
27
|
+
maxSteps: 5,
|
|
28
|
+
prompt: "Find the top HN story right now, read it, and summarize it in 3 bullets.",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
console.log(text);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`synoppyTools()` returns an object keyed by tool name, so you can spread it straight into `tools`. Want just a few? Destructure them:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const { synoppy_read, synoppy_search } = synoppyTools({ apiKey });
|
|
38
|
+
const tools = { synoppy_read, synoppy_search };
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Tools
|
|
42
|
+
|
|
43
|
+
| Tool | Endpoint | What it does |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `synoppy_read` | `/api/scrape` | URL → clean markdown (nav/ads stripped) |
|
|
46
|
+
| `synoppy_search` | `/api/search` | Ranked live-web results, optionally read to markdown |
|
|
47
|
+
| `synoppy_crawl` | `/api/crawl` | Crawl a site → markdown per page (RAG ingest) |
|
|
48
|
+
| `synoppy_map` | `/api/map` | Every URL on a domain |
|
|
49
|
+
| `synoppy_extract` | `/api/extract` | Page → structured JSON from a prompt |
|
|
50
|
+
| `synoppy_classify` | `/api/classify` | NAICS/SIC industry codes, or custom labels |
|
|
51
|
+
| `synoppy_enrich` | `/api/brand` | Domain / email → brand profile (logo, colors, fonts, socials) |
|
|
52
|
+
| `synoppy_images` | `/api/images` | Every image on a page + alt text |
|
|
53
|
+
| `synoppy_screenshot` | `/api/screenshot` | URL → PNG (base64 data URL) for vision models |
|
|
54
|
+
|
|
55
|
+
Each tool returns a lean, agent-friendly result plus `creditsUsed`. Failures come back as `{ error, code }` so the model can read them and recover instead of throwing.
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
`synoppyTools(options)` takes the same options as the [`@synoppy/sdk`](https://www.npmjs.com/package/@synoppy/sdk) client:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
synoppyTools({
|
|
63
|
+
apiKey: process.env.SYNOPPY_API_KEY!, // required
|
|
64
|
+
baseUrl: "https://synoppy.com", // optional override
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Need typed extraction (a JSON Schema), custom timeouts, or the raw responses? Use [`@synoppy/sdk`](https://www.npmjs.com/package/@synoppy/sdk) directly — it's re-exported here as `Synoppy`.
|
|
69
|
+
|
|
70
|
+
MIT licensed · built by [Saanora](https://synoppy.com)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @synoppy/ai-sdk — Synoppy tools for the Vercel AI SDK.
|
|
3
|
+
*
|
|
4
|
+
* `synoppyTools({ apiKey })` returns the nine Synoppy endpoints as AI SDK tools,
|
|
5
|
+
* ready to spread into `generateText` / `streamText`. Each tool wraps the
|
|
6
|
+
* official `@synoppy/sdk` client and returns a lean, agent-friendly result;
|
|
7
|
+
* failures come back as `{ error, code }` so the model can read them and recover.
|
|
8
|
+
*/
|
|
9
|
+
import { type SynoppyOptions } from "@synoppy/sdk";
|
|
10
|
+
export type SynoppyToolsOptions = SynoppyOptions;
|
|
11
|
+
/**
|
|
12
|
+
* Build the full set of Synoppy AI SDK tools.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { generateText } from "ai";
|
|
17
|
+
* import { openai } from "@ai-sdk/openai";
|
|
18
|
+
* import { synoppyTools } from "@synoppy/ai-sdk";
|
|
19
|
+
*
|
|
20
|
+
* const { text } = await generateText({
|
|
21
|
+
* model: openai("gpt-4o"),
|
|
22
|
+
* tools: synoppyTools({ apiKey: process.env.SYNOPPY_API_KEY! }),
|
|
23
|
+
* maxSteps: 5,
|
|
24
|
+
* prompt: "Summarize the latest post on https://stripe.com/blog",
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function synoppyTools(options: SynoppyToolsOptions): {
|
|
29
|
+
synoppy_read: import("ai").Tool<{
|
|
30
|
+
url: string;
|
|
31
|
+
onlyMainContent?: boolean | undefined;
|
|
32
|
+
render?: boolean | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
error: string;
|
|
35
|
+
code: string;
|
|
36
|
+
} | {
|
|
37
|
+
markdown: string | undefined;
|
|
38
|
+
metadata: import("@synoppy/sdk").ScrapeMetadata;
|
|
39
|
+
creditsUsed: number;
|
|
40
|
+
}>;
|
|
41
|
+
synoppy_search: import("ai").Tool<{
|
|
42
|
+
query: string;
|
|
43
|
+
markdown?: boolean | undefined;
|
|
44
|
+
maxResults?: number | undefined;
|
|
45
|
+
includeDomains?: string[] | undefined;
|
|
46
|
+
excludeDomains?: string[] | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
error: string;
|
|
49
|
+
code: string;
|
|
50
|
+
} | {
|
|
51
|
+
results: import("@synoppy/sdk").SearchResult[];
|
|
52
|
+
creditsUsed: number;
|
|
53
|
+
}>;
|
|
54
|
+
synoppy_crawl: import("ai").Tool<{
|
|
55
|
+
url: string;
|
|
56
|
+
limit?: number | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
error: string;
|
|
59
|
+
code: string;
|
|
60
|
+
} | {
|
|
61
|
+
domain: string;
|
|
62
|
+
discovered: number;
|
|
63
|
+
count: number;
|
|
64
|
+
pages: import("@synoppy/sdk").CrawlPage[];
|
|
65
|
+
creditsUsed: number;
|
|
66
|
+
}>;
|
|
67
|
+
synoppy_map: import("ai").Tool<{
|
|
68
|
+
url: string;
|
|
69
|
+
}, {
|
|
70
|
+
error: string;
|
|
71
|
+
code: string;
|
|
72
|
+
} | {
|
|
73
|
+
domain: string;
|
|
74
|
+
urls: string[];
|
|
75
|
+
count: number;
|
|
76
|
+
creditsUsed: number;
|
|
77
|
+
}>;
|
|
78
|
+
synoppy_extract: import("ai").Tool<{
|
|
79
|
+
url: string;
|
|
80
|
+
prompt?: string | undefined;
|
|
81
|
+
}, {
|
|
82
|
+
error: string;
|
|
83
|
+
code: string;
|
|
84
|
+
} | {
|
|
85
|
+
data: Record<string, unknown>;
|
|
86
|
+
creditsUsed: number;
|
|
87
|
+
}>;
|
|
88
|
+
synoppy_classify: import("ai").Tool<{
|
|
89
|
+
url: string;
|
|
90
|
+
labels?: string[] | undefined;
|
|
91
|
+
}, {
|
|
92
|
+
error: string;
|
|
93
|
+
code: string;
|
|
94
|
+
} | {
|
|
95
|
+
data: import("@synoppy/sdk").ClassifyIndustryData | import("@synoppy/sdk").ClassifyLabelData;
|
|
96
|
+
creditsUsed: number;
|
|
97
|
+
}>;
|
|
98
|
+
synoppy_enrich: import("ai").Tool<{
|
|
99
|
+
input: string;
|
|
100
|
+
}, {
|
|
101
|
+
error: string;
|
|
102
|
+
code: string;
|
|
103
|
+
} | {
|
|
104
|
+
name: string;
|
|
105
|
+
domain: string;
|
|
106
|
+
description: string | null;
|
|
107
|
+
logo: string | null;
|
|
108
|
+
colors: string[];
|
|
109
|
+
fonts: string[];
|
|
110
|
+
socials: import("@synoppy/sdk").Social[];
|
|
111
|
+
creditsUsed: number;
|
|
112
|
+
}>;
|
|
113
|
+
synoppy_images: import("ai").Tool<{
|
|
114
|
+
url: string;
|
|
115
|
+
}, {
|
|
116
|
+
error: string;
|
|
117
|
+
code: string;
|
|
118
|
+
} | {
|
|
119
|
+
images: import("@synoppy/sdk").ImageItem[];
|
|
120
|
+
count: number;
|
|
121
|
+
creditsUsed: number;
|
|
122
|
+
}>;
|
|
123
|
+
synoppy_screenshot: import("ai").Tool<{
|
|
124
|
+
url: string;
|
|
125
|
+
fullPage?: boolean | undefined;
|
|
126
|
+
}, {
|
|
127
|
+
error: string;
|
|
128
|
+
code: string;
|
|
129
|
+
} | {
|
|
130
|
+
screenshot: string;
|
|
131
|
+
sourceUrl: string;
|
|
132
|
+
creditsUsed: number;
|
|
133
|
+
}>;
|
|
134
|
+
};
|
|
135
|
+
export default synoppyTools;
|
|
136
|
+
export { Synoppy, SynoppyError } from "@synoppy/sdk";
|
|
137
|
+
export type { SynoppyOptions } from "@synoppy/sdk";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @synoppy/ai-sdk — Synoppy tools for the Vercel AI SDK.
|
|
3
|
+
*
|
|
4
|
+
* `synoppyTools({ apiKey })` returns the nine Synoppy endpoints as AI SDK tools,
|
|
5
|
+
* ready to spread into `generateText` / `streamText`. Each tool wraps the
|
|
6
|
+
* official `@synoppy/sdk` client and returns a lean, agent-friendly result;
|
|
7
|
+
* failures come back as `{ error, code }` so the model can read them and recover.
|
|
8
|
+
*/
|
|
9
|
+
import { tool } from "ai";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { Synoppy, SynoppyError } from "@synoppy/sdk";
|
|
12
|
+
/** Run an SDK call, returning an agent-readable error object instead of throwing. */
|
|
13
|
+
async function guard(fn) {
|
|
14
|
+
try {
|
|
15
|
+
return await fn();
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
if (e instanceof SynoppyError)
|
|
19
|
+
return { error: e.message, code: e.code };
|
|
20
|
+
return { error: e instanceof Error ? e.message : "Unknown error", code: "ERROR" };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the full set of Synoppy AI SDK tools.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { generateText } from "ai";
|
|
29
|
+
* import { openai } from "@ai-sdk/openai";
|
|
30
|
+
* import { synoppyTools } from "@synoppy/ai-sdk";
|
|
31
|
+
*
|
|
32
|
+
* const { text } = await generateText({
|
|
33
|
+
* model: openai("gpt-4o"),
|
|
34
|
+
* tools: synoppyTools({ apiKey: process.env.SYNOPPY_API_KEY! }),
|
|
35
|
+
* maxSteps: 5,
|
|
36
|
+
* prompt: "Summarize the latest post on https://stripe.com/blog",
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function synoppyTools(options) {
|
|
41
|
+
const client = new Synoppy(options);
|
|
42
|
+
return {
|
|
43
|
+
synoppy_read: tool({
|
|
44
|
+
description: "Read any URL and return it as clean, LLM-ready markdown (navigation, ads, and boilerplate stripped). Use to fetch the content of a specific web page.",
|
|
45
|
+
inputSchema: z.object({
|
|
46
|
+
url: z.string().describe("The absolute URL to read, e.g. https://example.com/blog/post"),
|
|
47
|
+
onlyMainContent: z.boolean().optional().describe("Strip navigation, headers, footers, and ads (default true)."),
|
|
48
|
+
render: z.boolean().optional().describe("Render JS-heavy / single-page apps in a real browser before reading (default false)."),
|
|
49
|
+
}),
|
|
50
|
+
execute: ({ url, onlyMainContent, render }) => guard(async () => {
|
|
51
|
+
const r = await client.read(url, { onlyMainContent, render });
|
|
52
|
+
return { markdown: r.markdown, metadata: r.metadata, creditsUsed: r.creditsUsed };
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
synoppy_search: tool({
|
|
56
|
+
description: "Search the live web and get back ranked results with clean source URLs. Use for current information, research, or to find pages before reading them. Set markdown to also read each result into clean markdown in the same call.",
|
|
57
|
+
inputSchema: z.object({
|
|
58
|
+
query: z.string().describe("The search query."),
|
|
59
|
+
maxResults: z.number().int().min(1).max(15).optional().describe("How many results to return (default 5)."),
|
|
60
|
+
markdown: z.boolean().optional().describe("Also read each result into clean markdown."),
|
|
61
|
+
includeDomains: z.array(z.string()).optional().describe("Only return results from these domains."),
|
|
62
|
+
excludeDomains: z.array(z.string()).optional().describe("Never return results from these domains."),
|
|
63
|
+
}),
|
|
64
|
+
execute: ({ query, ...opts }) => guard(async () => {
|
|
65
|
+
const r = await client.search(query, opts);
|
|
66
|
+
return { results: r.results, creditsUsed: r.creditsUsed };
|
|
67
|
+
}),
|
|
68
|
+
}),
|
|
69
|
+
synoppy_crawl: tool({
|
|
70
|
+
description: "Crawl a website from a starting URL and return clean markdown for every page found. Use to ingest a whole site or docs section (e.g. to build a RAG corpus).",
|
|
71
|
+
inputSchema: z.object({
|
|
72
|
+
url: z.string().describe("The starting URL."),
|
|
73
|
+
limit: z.number().int().min(1).max(25).optional().describe("Maximum pages to crawl (default 10)."),
|
|
74
|
+
}),
|
|
75
|
+
execute: ({ url, limit }) => guard(async () => {
|
|
76
|
+
const r = await client.crawl(url, { limit });
|
|
77
|
+
return { domain: r.domain, discovered: r.discovered, count: r.count, pages: r.pages, creditsUsed: r.creditsUsed };
|
|
78
|
+
}),
|
|
79
|
+
}),
|
|
80
|
+
synoppy_map: tool({
|
|
81
|
+
description: "Discover every URL on a domain in one call (from sitemaps and links). Use to understand a site's structure before crawling or reading specific pages.",
|
|
82
|
+
inputSchema: z.object({ url: z.string().describe("The domain or URL to map, e.g. https://stripe.com") }),
|
|
83
|
+
execute: ({ url }) => guard(async () => {
|
|
84
|
+
const r = await client.map(url);
|
|
85
|
+
return { domain: r.domain, urls: r.urls, count: r.count, creditsUsed: r.creditsUsed };
|
|
86
|
+
}),
|
|
87
|
+
}),
|
|
88
|
+
synoppy_extract: tool({
|
|
89
|
+
description: "Extract structured JSON from a page using AI. Describe the fields you want in a natural-language prompt and get back typed data (pricing tables, product specs, job listings, etc.).",
|
|
90
|
+
inputSchema: z.object({
|
|
91
|
+
url: z.string().describe("The page to extract from."),
|
|
92
|
+
prompt: z.string().optional().describe("Describe the JSON you want, e.g. 'the pricing tiers as a list of name + price'."),
|
|
93
|
+
}),
|
|
94
|
+
execute: ({ url, prompt }) => guard(async () => {
|
|
95
|
+
const r = await client.extract(url, { prompt });
|
|
96
|
+
return { data: r.data, creditsUsed: r.creditsUsed };
|
|
97
|
+
}),
|
|
98
|
+
}),
|
|
99
|
+
synoppy_classify: tool({
|
|
100
|
+
description: "Classify a company by its website — NAICS/SIC industry codes by default, or scored against your own custom labels.",
|
|
101
|
+
inputSchema: z.object({
|
|
102
|
+
url: z.string().describe("The company website."),
|
|
103
|
+
labels: z.array(z.string()).optional().describe("Custom labels to score against instead of industry codes."),
|
|
104
|
+
}),
|
|
105
|
+
execute: ({ url, labels }) => guard(async () => {
|
|
106
|
+
const r = await client.classify(url, { labels });
|
|
107
|
+
return { data: r.data, creditsUsed: r.creditsUsed };
|
|
108
|
+
}),
|
|
109
|
+
}),
|
|
110
|
+
synoppy_enrich: tool({
|
|
111
|
+
description: "Resolve a domain, URL, or work email into a live brand profile: name, logo, colors, fonts, socials, and description — read straight from the site.",
|
|
112
|
+
inputSchema: z.object({ input: z.string().describe("A domain, URL, or work email, e.g. stripe.com or jane@stripe.com") }),
|
|
113
|
+
execute: ({ input }) => guard(async () => {
|
|
114
|
+
const r = await client.enrich(input);
|
|
115
|
+
return {
|
|
116
|
+
name: r.name,
|
|
117
|
+
domain: r.domain,
|
|
118
|
+
description: r.description,
|
|
119
|
+
logo: r.logo,
|
|
120
|
+
colors: r.colors,
|
|
121
|
+
fonts: r.fonts,
|
|
122
|
+
socials: r.socials,
|
|
123
|
+
creditsUsed: r.creditsUsed,
|
|
124
|
+
};
|
|
125
|
+
}),
|
|
126
|
+
}),
|
|
127
|
+
synoppy_images: tool({
|
|
128
|
+
description: "Collect every image on a page with its alt text and dimensions.",
|
|
129
|
+
inputSchema: z.object({ url: z.string().describe("The page to collect images from.") }),
|
|
130
|
+
execute: ({ url }) => guard(async () => {
|
|
131
|
+
const r = await client.images(url);
|
|
132
|
+
return { images: r.images, count: r.count, creditsUsed: r.creditsUsed };
|
|
133
|
+
}),
|
|
134
|
+
}),
|
|
135
|
+
synoppy_screenshot: tool({
|
|
136
|
+
description: "Capture a URL as a PNG screenshot, returned as a base64 data URL — so a vision model can see the page, or to snapshot a layout. Note: the returned image is large.",
|
|
137
|
+
inputSchema: z.object({
|
|
138
|
+
url: z.string().describe("The page to capture."),
|
|
139
|
+
fullPage: z.boolean().optional().describe("Capture the entire scrollable page instead of just the viewport (default false)."),
|
|
140
|
+
}),
|
|
141
|
+
execute: ({ url, fullPage }) => guard(async () => {
|
|
142
|
+
const r = await client.screenshot(url, { fullPage });
|
|
143
|
+
return { screenshot: r.screenshot, sourceUrl: r.sourceUrl, creditsUsed: r.creditsUsed };
|
|
144
|
+
}),
|
|
145
|
+
}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export default synoppyTools;
|
|
149
|
+
export { Synoppy, SynoppyError } from "@synoppy/sdk";
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@synoppy/ai-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Vercel AI SDK tools for Synoppy — give your agent the whole web: read, search, crawl, map, extract, classify, enrich, images, and screenshot on one key.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
17
|
+
"publishConfig": { "access": "public" },
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": ["synoppy", "ai-sdk", "vercel-ai", "tools", "agents", "web-scraping", "web-search", "rag", "llm", "markdown"],
|
|
23
|
+
"author": "Saanora <support@synoppy.com>",
|
|
24
|
+
"homepage": "https://synoppy.com/docs",
|
|
25
|
+
"repository": { "type": "git", "url": "git+https://github.com/Synoppy/synoppy-ai-sdk.git" },
|
|
26
|
+
"bugs": { "url": "https://github.com/Synoppy/synoppy-ai-sdk/issues" },
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@synoppy/sdk": "^1.1.1"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"ai": ">=5.0.0",
|
|
32
|
+
"zod": ">=3.23.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"ai": "^5.0.0",
|
|
36
|
+
"typescript": "^5.5.0",
|
|
37
|
+
"zod": "^3.23.8"
|
|
38
|
+
}
|
|
39
|
+
}
|