-
Notifications
You must be signed in to change notification settings - Fork 91
feat: add optional You.com search integration #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
7d43387
6095ba7
668312b
81e7dbe
8c26ad1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,239 @@ | ||
| # You.com Provider Integration | ||
|
|
||
| The YouCom provider integrates You.com's web search into AgentOS, offering access to real-time web information and news search. | ||
|
|
||
| ## Overview | ||
|
|
||
| Unlike traditional LLM providers, YouCom specializes in: | ||
| - **Real-time web search** with source URLs, descriptions, and snippets | ||
| - **News search** with timestamps and publication metadata | ||
|
|
||
| The provider reads credentials from `YDC_API_KEY` or `YOUCOM_API_KEY`, and you can also pass an explicit `apiKey` during initialization. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```typescript | ||
| import { YouComProvider } from '@framers/agentos'; | ||
|
|
||
| const provider = new YouComProvider(); | ||
| await provider.initialize({ | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| }); | ||
|
|
||
| const results = await provider.search('What are the latest developments in AI agent frameworks?', { | ||
| count: 5, | ||
| }); | ||
|
|
||
| for (const item of results.web ?? []) { | ||
| console.log(item.title); | ||
| console.log(item.url); | ||
| console.log(item.description); | ||
| console.log(item.snippets[0]); | ||
| } | ||
| ``` | ||
|
|
||
| ## Authentication | ||
|
|
||
| ### Environment-Based Setup | ||
| The provider reads `YDC_API_KEY` first and falls back to `YOUCOM_API_KEY` for legacy setups. | ||
|
|
||
| ```bash | ||
| export YDC_API_KEY="your_api_key_here" | ||
| ``` | ||
|
|
||
| Get your API key at [you.com/platform/api-keys](https://you.com/platform/api-keys). | ||
|
|
||
| Alternative environment variable: | ||
| ```bash | ||
| export YOUCOM_API_KEY="your_api_key_here" | ||
| ``` | ||
|
|
||
| ### Custom Configuration | ||
|
|
||
| ```typescript | ||
| const provider = new YouComProvider(); | ||
| await provider.initialize({ | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| searchApiUrl: 'https://ydc-index.io/v1/search', | ||
| mcpServerUrl: 'https://api.you.com/mcp', | ||
| debug: true, | ||
| }); | ||
| ``` | ||
|
|
||
| ## Available Models | ||
|
|
||
| | Model ID | Description | Use Case | | ||
| |----------|-------------|----------| | ||
| | `youcom-search` | Web search with snippets | General web search queries | | ||
| | `youcom-news` | News-focused search | Recent news and current events | | ||
|
|
||
| ## Direct Search API | ||
|
|
||
| Access You.com search functionality directly: | ||
|
|
||
| ```typescript | ||
| const provider = new YouComProvider(); | ||
| await provider.initialize({ | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| }); | ||
|
|
||
| // Web search | ||
| const results = await provider.search('TypeScript frameworks', { | ||
| count: 5, | ||
| type: 'web' | ||
| }); | ||
|
|
||
| // News search | ||
| const news = await provider.search('AI developments', { | ||
| count: 3, | ||
| type: 'news' | ||
| }); | ||
| ``` | ||
|
|
||
| ## Response Format | ||
|
|
||
| ### Web Search Results | ||
| ```typescript | ||
| { | ||
| web: [ | ||
| { | ||
| title: "Page title", | ||
| url: "https://example.com", | ||
| description: "Relevant excerpt from the page...", | ||
| snippets: ["Relevant excerpt from the page..."] | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ### News Search Results | ||
| ```typescript | ||
| { | ||
| news: [ | ||
| { | ||
| title: "Article title", | ||
| url: "https://news.example.com/article", | ||
| description: "Article excerpt...", | ||
| snippets: ["Article excerpt..."], | ||
| published_at: "2026-07-26T10:00:00Z" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ## Error Handling | ||
|
|
||
| The provider handles common error scenarios gracefully: | ||
|
|
||
| - **Rate limiting (429)**: Returns helpful message about API key benefits | ||
| - **Network errors**: Fail-safe with informative error messages | ||
| - **Invalid queries**: Validation with suggestion prompts | ||
| - **Quota exceeded**: Clear indication of limits and upgrade paths | ||
|
|
||
| ```typescript | ||
| try { | ||
| const results = await provider.search('query'); | ||
| } catch (error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| if (message.includes('rate limit')) { | ||
| console.log('Consider using an API key for higher quotas'); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Health Monitoring | ||
|
|
||
| Check provider connectivity and configuration: | ||
|
|
||
| ```typescript | ||
| const health = await provider.checkHealth(); | ||
| console.log('Healthy:', health.isHealthy); | ||
| console.log('API Key configured:', health.details.apiKeyConfigured); | ||
| ``` | ||
|
|
||
| ## AgentOS Registry | ||
|
|
||
| YouCom is automatically registered in AgentOS's provider system: | ||
|
|
||
| ```typescript | ||
| import { AIModelProviderManager } from '@framers/agentos'; | ||
|
|
||
| const manager = new AIModelProviderManager(); | ||
| await manager.initialize({ | ||
| providers: [ | ||
| { | ||
| providerId: 'youcom', | ||
| enabled: true, | ||
| config: { | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| }, | ||
| }, | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| ## MCP Server Path | ||
|
|
||
| You.com's MCP surface also includes content and research tooling. This provider | ||
| keeps the search integration small and optional, but if you wire the MCP server | ||
| later the corresponding tool names are: | ||
| - `you-search` for web search | ||
| - `you-contents` for URL content extraction | ||
| - `you-research` for research synthesis | ||
|
|
||
| Those MCP tools are not enabled by this PR. | ||
|
|
||
| ## Limitations | ||
|
|
||
| - **No LLM generation**: YouCom focuses on search/tools, not text generation | ||
| - **No embeddings**: Use other providers for embedding models | ||
| - **No streaming**: Search results are returned as complete responses | ||
| - **Rate limits**: Keyless tier has daily quotas (overcome with API key) | ||
|
|
||
| ## Best Practices | ||
|
|
||
| 1. **Use for current information**: YouCom excels at real-time web data | ||
| 2. **Combine with LLM providers**: Use YouCom for search, other providers for generation | ||
| 3. **Cache results**: Avoid repeated identical searches | ||
| 4. **Respect rate limits**: Monitor quota usage in production | ||
| 5. **Cite sources**: Always include URLs in agent responses | ||
|
|
||
| ## Examples | ||
|
|
||
| See `examples/youcom-search-example.mjs` for a complete working example demonstrating: | ||
| - Direct search and news search with YouComProvider | ||
| - Multiple query types | ||
| - Direct API access | ||
| - Error handling patterns | ||
| - Configuration examples | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### "Provider not initialized" | ||
| - Ensure `initialize()` is called before use | ||
| - Check network connectivity | ||
|
|
||
| ### "Rate limit exceeded" | ||
| - Set `YDC_API_KEY` environment variable | ||
| - Implement request throttling | ||
| - Consider caching search results | ||
|
|
||
| ### "Search API connectivity test failed" | ||
| - Check internet connection | ||
| - Verify You.com API endpoint accessibility | ||
| - Review firewall/proxy settings | ||
|
|
||
| ### Integration Issues | ||
| - Confirm YouCom is registered in `AIModelProviderManager` | ||
| - Check provider configuration in AgentOS config | ||
| - Enable debug logging: `debug: true` | ||
|
|
||
| ## Contributing | ||
|
|
||
| YouCom provider follows AgentOS provider standards: | ||
| - Implements full `IProvider` interface | ||
| - Comprehensive error handling | ||
| - Unit test coverage | ||
| - Documentation and examples | ||
|
|
||
| See [Provider Integration Guide](../contributing/new-provider.md) for details. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| #!/usr/bin/env node | ||
| /** | ||
| * @fileoverview YouCom Provider Example - Demonstrates You.com integration with AgentOS | ||
| * | ||
| * This example shows how to use the YouCom provider for web search and news search. | ||
| * | ||
| * Usage: | ||
| * node examples/youcom-search-example.mjs | ||
| * | ||
| * Environment variables: | ||
| * YDC_API_KEY - You.com API key | ||
| * YOUCOM_API_KEY - Legacy fallback env var | ||
| */ | ||
|
|
||
| import { YouComProvider } from '@framers/agentos'; | ||
|
|
||
| function printConfigurationExamples() { | ||
| console.log('\n📚 Configuration Examples:\n'); | ||
|
|
||
| console.log('1. Environment-based setup:'); | ||
| console.log(' export YDC_API_KEY="your-api-key-here"'); | ||
| console.log(' # or export YOUCOM_API_KEY="your-api-key-here"\n'); | ||
|
|
||
| console.log('2. Explicit initialization:'); | ||
| console.log(` const provider = new YouComProvider(); | ||
| await provider.initialize({ | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| });\n`); | ||
| } | ||
|
|
||
| async function runYouComExample() { | ||
| console.log('🔍 YouCom Provider Example - Search with AgentOS\n'); | ||
|
|
||
| const provider = new YouComProvider(); | ||
| await provider.initialize({ | ||
| apiKey: process.env.YDC_API_KEY ?? process.env.YOUCOM_API_KEY, | ||
| debug: true, | ||
| }); | ||
|
|
||
| const webQuery = 'What are the latest developments in AI agent frameworks?'; | ||
| console.log(`\n📋 Web query: ${webQuery}`); | ||
| const webResults = await provider.search(webQuery, { count: 5, type: 'web' }); | ||
|
|
||
| for (const [index, result] of (webResults.web ?? []).entries()) { | ||
| console.log(`${index + 1}. ${result.title}`); | ||
| console.log(` ${result.url}`); | ||
| console.log(` ${result.description}`); | ||
| if (result.snippets[0]) { | ||
| console.log(` ${result.snippets[0]}`); | ||
| } | ||
| } | ||
|
|
||
| const newsQuery = 'TypeScript 5.7 release'; | ||
| console.log(`\n📰 News query: ${newsQuery}`); | ||
| const newsResults = await provider.search(newsQuery, { | ||
| count: 3, | ||
| type: 'news', | ||
| freshness: 'week', | ||
| }); | ||
|
|
||
| for (const [index, result] of (newsResults.news ?? []).entries()) { | ||
| console.log(`${index + 1}. ${result.title}`); | ||
| console.log(` ${result.url}`); | ||
| console.log(` ${result.description}`); | ||
| if (result.published_at) { | ||
| console.log(` published: ${result.published_at}`); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (import.meta.url === `file://${process.argv[1]}`) { | ||
| printConfigurationExamples(); | ||
| runYouComExample().catch((error) => { | ||
| console.error('❌ YouCom example failed:', error instanceof Error ? error.message : String(error)); | ||
| process.exitCode = 1; | ||
| }); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| allowBuilds: | ||
| '@matrix-org/matrix-sdk-crypto-nodejs': true | ||
| '@whiskeysockets/baileys': true | ||
| bcrypt: true | ||
| better-sqlite3: true | ||
| esbuild: true | ||
| ffi-napi: true | ||
| hnswlib-node: true | ||
| onnxruntime-node: true | ||
| protobufjs: true | ||
| ref-napi: true | ||
| sharp: true | ||
| tesseract.js: true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,6 +131,8 @@ const AUTO_DETECT_ORDER: AutoDetectProbe[] = [ | |
| { envKey: 'TOGETHER_API_KEY', provider: 'together' }, | ||
| { envKey: 'MISTRAL_API_KEY', provider: 'mistral' }, | ||
| { envKey: 'XAI_API_KEY', provider: 'xai' }, | ||
| { envKey: 'YDC_API_KEY', provider: 'youcom' }, | ||
| { envKey: 'YOUCOM_API_KEY', provider: 'youcom' }, // Fallback for legacy env var | ||
|
Comment on lines
+134
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎.
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
coderabbitai[bot] marked this conversation as resolved.
|
||
| { binaryName: 'claude', provider: 'claude-code-cli' }, | ||
| { binaryName: 'gemini', provider: 'gemini-cli' }, | ||
| { envKey: 'OLLAMA_BASE_URL', provider: 'ollama' }, | ||
|
|
@@ -148,11 +150,15 @@ function isBinaryOnPath(binaryName: string): boolean { | |
| } | ||
|
|
||
| // Provider-id → probe lookup so a custom priority list (just provider | ||
| // ids) can be resolved back to its env-var or CLI-binary probe. Stays | ||
| // ids) can be resolved back to its env-var or CLI-binary probes. Stays | ||
| // in sync automatically with `AUTO_DETECT_ORDER`. | ||
| const PROBE_BY_PROVIDER: Record<string, AutoDetectProbe> = Object.fromEntries( | ||
| AUTO_DETECT_ORDER.map((probe) => [probe.provider, probe]) | ||
| ); | ||
| const PROBES_BY_PROVIDER: Record<string, AutoDetectProbe[]> = {}; | ||
| for (const probe of AUTO_DETECT_ORDER) { | ||
| if (!PROBES_BY_PROVIDER[probe.provider]) { | ||
| PROBES_BY_PROVIDER[probe.provider] = []; | ||
| } | ||
| PROBES_BY_PROVIDER[probe.provider].push(probe); | ||
| } | ||
|
|
||
| /** | ||
| * Auto-detects the active provider by scanning well-known environment variables | ||
|
|
@@ -171,9 +177,7 @@ const PROBE_BY_PROVIDER: Record<string, AutoDetectProbe> = Object.fromEntries( | |
| export function autoDetectProvider(task?: ProviderDefaultTask): string | undefined { | ||
| const customOrder = getProviderPriority(); | ||
| const order: AutoDetectProbe[] = customOrder | ||
| ? customOrder | ||
| .map((p) => PROBE_BY_PROVIDER[p]) | ||
| .filter((probe): probe is AutoDetectProbe => Boolean(probe)) | ||
| ? customOrder.flatMap((p) => PROBES_BY_PROVIDER[p] ?? []) | ||
| : AUTO_DETECT_ORDER; | ||
|
|
||
| for (const probe of order) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.