@youdotcom-oss/ai-sdk-plugin 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/README.md +372 -0
- package/dist/main.d.ts +146 -0
- package/dist/main.js +4748 -0
- package/package.json +80 -0
- package/templates/generate-text.ts +78 -0
- package/templates/streaming-text.ts +123 -0
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@youdotcom-oss/ai-sdk-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vercel AI SDK plugin for You.com web search, AI agents, and content extraction via MCP",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18",
|
|
8
|
+
"bun": ">= 1.2.21"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/youdotcom-oss/dx-toolkit.git",
|
|
13
|
+
"directory": "packages/ai-sdk-plugin"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/youdotcom-oss/dx-toolkit/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/youdotcom-oss/dx-toolkit/tree/main/packages/ai-sdk-plugin#readme",
|
|
19
|
+
"author": "You.com (https://you.com)",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"ai",
|
|
22
|
+
"sdk",
|
|
23
|
+
"plugin",
|
|
24
|
+
"you",
|
|
25
|
+
"search",
|
|
26
|
+
"mcp",
|
|
27
|
+
"vercel",
|
|
28
|
+
"model-context-protocol",
|
|
29
|
+
"ai-agents",
|
|
30
|
+
"web-search"
|
|
31
|
+
],
|
|
32
|
+
"type": "module",
|
|
33
|
+
"main": "./dist/main.js",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/main.d.ts",
|
|
37
|
+
"default": "./dist/main.js"
|
|
38
|
+
},
|
|
39
|
+
"./templates/generate-text": "./templates/generate-text.ts",
|
|
40
|
+
"./templates/streaming-text": "./templates/streaming-text.ts"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"templates"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "bun run build:bundle && bun run build:types",
|
|
51
|
+
"build:bundle": "bun build src/main.ts --outdir dist --target node --external ai",
|
|
52
|
+
"build:types": "tsc --project tsconfig.build.json --declaration --emitDeclarationOnly --noEmit false",
|
|
53
|
+
"check": "bun run check:biome && bun run check:types && bun run check:package",
|
|
54
|
+
"check:biome": "biome check",
|
|
55
|
+
"check:package": "format-package --check",
|
|
56
|
+
"check:types": "tsc --noEmit",
|
|
57
|
+
"check:write": "bun run format && bun run lint:fix && bun run format:package",
|
|
58
|
+
"example": "bun scripts/run-example.ts",
|
|
59
|
+
"format": "biome format --write",
|
|
60
|
+
"format:check": "biome format",
|
|
61
|
+
"format:package": "format-package --write",
|
|
62
|
+
"lint": "biome lint",
|
|
63
|
+
"lint:fix": "biome lint --write",
|
|
64
|
+
"prepublishOnly": "bun run build",
|
|
65
|
+
"test": "bun test",
|
|
66
|
+
"test:coverage": "bun test --coverage",
|
|
67
|
+
"test:coverage:watch": "bun test --coverage --watch",
|
|
68
|
+
"test:watch": "bun test --watch"
|
|
69
|
+
},
|
|
70
|
+
"types": "./dist/main.d.ts",
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@youdotcom-oss/mcp": "1.3.9"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"ai": "^5.0.0"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@ai-sdk/anthropic": "^2.0.56"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI SDK Integration Template - generateText()
|
|
3
|
+
*
|
|
4
|
+
* Shows how to integrate You.com tools with Vercel AI SDK's generateText().
|
|
5
|
+
*
|
|
6
|
+
* Key Integration Points:
|
|
7
|
+
* 1. Import tools: youSearch(), youExpress(), youContents()
|
|
8
|
+
* 2. Add to tools object
|
|
9
|
+
* 3. API key: Use env variable or pass directly to each tool
|
|
10
|
+
* 4. Model handles everything - you just get result.text
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
14
|
+
import { youContents, youExpress, youSearch } from '@youdotcom-oss/ai-sdk-plugin';
|
|
15
|
+
import { generateText } from 'ai';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// INTEGRATION STEP 1: Environment Variables
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Option A: Use environment variables (recommended)
|
|
21
|
+
// Set YDC_API_KEY in your .env file - tools read it automatically
|
|
22
|
+
|
|
23
|
+
if (!process.env.YDC_API_KEY) {
|
|
24
|
+
throw new Error('YDC_API_KEY environment variable is required');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Your AI provider key (Anthropic, OpenAI, etc.)
|
|
28
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
29
|
+
throw new Error('ANTHROPIC_API_KEY environment variable is required');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// INTEGRATION STEP 2: Add Tools to generateText
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
const anthropic = createAnthropic();
|
|
37
|
+
|
|
38
|
+
// Single tool example
|
|
39
|
+
const result = await generateText({
|
|
40
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
41
|
+
tools: {
|
|
42
|
+
search: youSearch(), // Reads YDC_API_KEY from environment
|
|
43
|
+
},
|
|
44
|
+
prompt: 'Your dynamic prompt here', // Replace with your actual prompt
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
console.log(result.text); // Model-formatted response with search results
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Multiple Tools (model chooses which to use)
|
|
51
|
+
// ============================================================================
|
|
52
|
+
|
|
53
|
+
const multiToolResult = await generateText({
|
|
54
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
55
|
+
tools: {
|
|
56
|
+
search: youSearch(),
|
|
57
|
+
agent: youExpress(),
|
|
58
|
+
extract: youContents(),
|
|
59
|
+
},
|
|
60
|
+
prompt: 'Your prompt here',
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log(multiToolResult.text);
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// INTEGRATION OPTION B: Pass API Key Directly
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Override environment variable per tool if needed
|
|
69
|
+
|
|
70
|
+
const customKeyResult = await generateText({
|
|
71
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
72
|
+
tools: {
|
|
73
|
+
search: youSearch({ apiKey: 'your-key-here' }),
|
|
74
|
+
},
|
|
75
|
+
prompt: 'Your prompt here',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
console.log(customKeyResult.text);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI SDK Integration Template - streamText()
|
|
3
|
+
*
|
|
4
|
+
* Shows how to integrate You.com tools with Vercel AI SDK's streamText().
|
|
5
|
+
*
|
|
6
|
+
* Key Integration Points:
|
|
7
|
+
* 1. Import tools: youSearch(), youExpress(), youContents()
|
|
8
|
+
* 2. Add to tools object
|
|
9
|
+
* 3. IMPORTANT: Use stopWhen with stepCountIs(2 + number_of_tools) minimum
|
|
10
|
+
* 4. Consume textStream for real-time UI updates
|
|
11
|
+
* 5. Model handles formatting - you just render the stream
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
15
|
+
import { youContents, youExpress, youSearch } from '@youdotcom-oss/ai-sdk-plugin';
|
|
16
|
+
import { stepCountIs, streamText } from 'ai';
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// INTEGRATION STEP 1: Environment Variables
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
if (!process.env.YDC_API_KEY) {
|
|
23
|
+
throw new Error('YDC_API_KEY environment variable is required');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
27
|
+
throw new Error('ANTHROPIC_API_KEY environment variable is required');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// INTEGRATION STEP 2: Add Tools + Configure stopWhen
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Use stopWhen: stepCountIs(3) - works for any number of tools with Anthropic
|
|
34
|
+
|
|
35
|
+
const anthropic = createAnthropic();
|
|
36
|
+
|
|
37
|
+
const result = streamText({
|
|
38
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
39
|
+
tools: {
|
|
40
|
+
search: youSearch(),
|
|
41
|
+
},
|
|
42
|
+
stopWhen: stepCountIs(3), // 3 steps works regardless of tool count (Anthropic)
|
|
43
|
+
prompt: 'Your dynamic prompt here', // Replace with actual prompt
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// INTEGRATION STEP 3: Consume the Stream
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Stream text to your UI in real-time
|
|
50
|
+
|
|
51
|
+
for await (const chunk of result.textStream) {
|
|
52
|
+
process.stdout.write(chunk); // Or update your UI component
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Multiple Tools Example
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// stepCountIs(3) works with any number of tools when using Anthropic
|
|
59
|
+
|
|
60
|
+
const multiToolStream = streamText({
|
|
61
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
62
|
+
tools: {
|
|
63
|
+
search: youSearch(),
|
|
64
|
+
agent: youExpress(),
|
|
65
|
+
extract: youContents(),
|
|
66
|
+
},
|
|
67
|
+
stopWhen: stepCountIs(3), // 3 steps works for 1, 2, or 3+ tools (Anthropic)
|
|
68
|
+
prompt: 'Your prompt here',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
for await (const chunk of multiToolStream.textStream) {
|
|
72
|
+
process.stdout.write(chunk);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Web Framework Integration Examples
|
|
77
|
+
// ============================================================================
|
|
78
|
+
|
|
79
|
+
// Next.js App Router (Route Handler)
|
|
80
|
+
// export async function POST(req: Request) {
|
|
81
|
+
// const { messages } = await req.json();
|
|
82
|
+
//
|
|
83
|
+
// const result = streamText({
|
|
84
|
+
// model: anthropic('claude-sonnet-4-5-20250929'),
|
|
85
|
+
// tools: { search: youSearch() },
|
|
86
|
+
// stopWhen: stepCountIs(3),
|
|
87
|
+
// messages,
|
|
88
|
+
// });
|
|
89
|
+
//
|
|
90
|
+
// return result.toDataStreamResponse();
|
|
91
|
+
// }
|
|
92
|
+
|
|
93
|
+
// Express.js
|
|
94
|
+
// app.post('/api/chat', async (req, res) => {
|
|
95
|
+
// const { prompt } = req.body;
|
|
96
|
+
//
|
|
97
|
+
// const result = streamText({
|
|
98
|
+
// model: anthropic('claude-sonnet-4-5-20250929'),
|
|
99
|
+
// tools: { search: youSearch() },
|
|
100
|
+
// stopWhen: stepCountIs(3),
|
|
101
|
+
// prompt,
|
|
102
|
+
// });
|
|
103
|
+
//
|
|
104
|
+
// result.pipeDataStreamToResponse(res);
|
|
105
|
+
// });
|
|
106
|
+
|
|
107
|
+
// React Component (using useChat hook)
|
|
108
|
+
// import { useChat } from 'ai/react';
|
|
109
|
+
//
|
|
110
|
+
// function ChatComponent() {
|
|
111
|
+
// const { messages, input, handleInputChange, handleSubmit } = useChat({
|
|
112
|
+
// api: '/api/chat', // Your endpoint with You.com tools
|
|
113
|
+
// });
|
|
114
|
+
//
|
|
115
|
+
// return (
|
|
116
|
+
// <div>
|
|
117
|
+
// {messages.map(m => <div key={m.id}>{m.content}</div>)}
|
|
118
|
+
// <form onSubmit={handleSubmit}>
|
|
119
|
+
// <input value={input} onChange={handleInputChange} />
|
|
120
|
+
// </form>
|
|
121
|
+
// </div>
|
|
122
|
+
// );
|
|
123
|
+
// }
|