feat: add Keenable as a configurable internet search backend - #2072
feat: add Keenable as a configurable internet search backend#2072ilya-bogin-keenable wants to merge 5 commits into
Conversation
Add Keenable alongside the existing bocha / tavily / google / bing / xinyu internet retrievers, following the Tavily backend pattern. - retrieve/keenablesearch.py: InternetKeenableRetriever. Keyless by default (no SDK, a thin requests call): with no key it hits /v1/search/public (rate-limited); a key switches to /v1/search with an X-API-Key header. Attribution via X-Keenable-Title. Results map into TextualMemoryItem exactly like the Tavily retriever. - configs/internet_retriever.py: KeenableSearchConfig (api_key optional) and registration in InternetRetrieverConfigFactory. - retrieve/internet_retriever_factory.py: register "keenable" + constructor. - api/config.py: INTERNET_SEARCH_BACKEND=keenable branch (KEENABLE_API_KEY optional, keyless by default). py_compile and ruff pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Hey @bittergreen could you please take a look? Thanks! |
🤖 Open Code ReviewTarget: PR #2072 🔍 OpenCodeReview found 5 issue(s) in this PR. 1.
|
✅ Automated Test Results: PASSEDAll tests passed (5/5 executed). memos_python_core/changed-python-source: 5/5. Duration: 4s [advisory, non-gating] AI-generated tests on branch test/auto-gen-33586be3c2b3f89c-20260801031509: 107/107 passed — these do NOT affect the PR verdict; review the branch manually. Branch: |
Summary
Adds Keenable as a new internet search backend alongside the existing Bocha / Tavily / Google / Bing / Xinyu retrievers, following the Tavily backend pattern (#1357). Additive and opt-in via
INTERNET_SEARCH_BACKEND=keenable; existing backends are untouched.Keenable is a web search API built for AI agents. Unlike the key-required backends it is keyless by default: with no key it calls the public endpoint (rate-limited), and an optional
KEENABLE_API_KEYonly lifts the cap.Files changed
src/memos/memories/textual/tree_text_memory/retrieve/keenablesearch.py(new):InternetKeenableRetriever. No SDK dependency, a thinrequestscall. Keyless requests hit/v1/search/public; a configured key switches to/v1/searchwith anX-API-Keyheader. Attribution viaX-Keenable-Title. Results map intoTextualMemoryItemthe same way the Tavily retriever does.src/memos/configs/internet_retriever.py:KeenableSearchConfig(API key optional) + registration inInternetRetrieverConfigFactory.src/memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py: registerkeenable+ constructor branch.src/memos/api/config.py:INTERNET_SEARCH_BACKEND=keenablebranch (KEENABLE_API_KEYoptional).Testing
python -m py_compileon all changed files: passes.ruff checkon all changed files: passes.