{ "tool_id": "lumi_ai_web_search", "name": "lumi_ai_web_search", "display_name": "Lumi AI Web Search", "version": "1.0.0", "description": "Controlled current-information search for Lumi Assistant with URL policy, origin budgets, and source normalization.", "scope": { "label": "Assistant web lookup", "required_role": "user" }, "permissions": { "required_role": "user", "permission": "lumi_ai_web_search.search" }, "capabilities": [ "Current web search through an administrator-configured JSON search provider", "Whitelist or blacklist URL policy with wildcard rules", "Optional bounded page excerpt fetching", "Context-aware condensed results for WebUI and chat platforms" ], "limitations": [ "Requires an administrator-configured search provider endpoint", "Does not provide browser automation or execute page scripts", "Private, local, link-local, metadata, and non-HTTP targets are always blocked", "Search quality and freshness depend on the configured provider" ], "tool_type": "web_search", "owning_plugin": "lumi_ai", "entrypoints": { "backend": "index.js" }, "frontend_assets": [ "public" ], "views": [ "views/settings-modal.ejs" ], "dependencies": [], "minimum_lumi_version": "0.1.0", "minimum_lumi_ai_version": "0.7.1", "required_plugins": [ "core", "lumi_ai" ], "required_platforms": [], "risk_level": "low", "confirmation_required": false, "data_paths": [ "data/settings.json", "data/audit.jsonl" ], "preserve_on_update": [ "data" ], "update_notes": "Initial controlled web-search provider with policy enforcement and per-origin output budgets.", "author": "Lumi", "homepage": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi", "repository_path": "plugins/lumi_ai_web_search", "settings_schema": { "enabled": { "type": "boolean", "label": "Web search enabled", "description": "The tool remains unavailable to Lumi Assistant until this and the parent Tools enable state are both on.", "default": false }, "policy_mode": { "type": "enum", "label": "Search policy", "description": "Whitelist permits only matching result/page URLs. Blacklist permits URLs except matching rules.", "options": [ "whitelist", "blacklist" ], "default": "whitelist" }, "url_rules": { "type": "string_list", "label": "URL policy rules", "description": "One domain, URL, path prefix, or * wildcard pattern per line. Example: docs.example.com or *.example.com/docs/*.", "default": [], "rows": 6 }, "max_results": { "type": "integer", "label": "Maximum results", "default": 5, "minimum": 1, "maximum": 10 }, "search_timeout_ms": { "type": "integer", "label": "Search timeout (ms)", "default": 8000, "minimum": 1000, "maximum": 30000 }, "cache_ttl_seconds": { "type": "integer", "label": "Result cache TTL (seconds)", "default": 300, "minimum": 0, "maximum": 3600 }, "safe_search": { "type": "enum", "label": "Safe search", "options": [ "off", "moderate", "strict" ], "default": "strict" }, "allowed_origins": { "type": "multi_select", "label": "Allowed origins", "options": [ "webui", "discord", "twitch", "youtube", "kick", "other" ], "default": [ "webui" ] }, "webui_output_chars": { "type": "integer", "label": "WebUI output budget", "default": 4000, "minimum": 300, "maximum": 12000 }, "discord_output_chars": { "type": "integer", "label": "Discord output budget", "default": 1200, "minimum": 200, "maximum": 4000 }, "twitch_output_chars": { "type": "integer", "label": "Twitch output budget", "default": 350, "minimum": 120, "maximum": 1000 }, "youtube_output_chars": { "type": "integer", "label": "YouTube output budget", "default": 500, "minimum": 120, "maximum": 1500 }, "kick_output_chars": { "type": "integer", "label": "Kick output budget", "default": 350, "minimum": 120, "maximum": 1000 }, "other_output_chars": { "type": "integer", "label": "Other output budget", "default": 500, "minimum": 120, "maximum": 2000 }, "provider_adapter": { "type": "enum", "label": "Provider adapter", "options": [ "searxng_json", "generic_json" ], "default": "searxng_json" }, "provider_endpoint": { "type": "string", "label": "Provider endpoint", "description": "HTTPS is recommended. The endpoint must be publicly routable and return JSON.", "default": "" }, "provider_api_key": { "type": "string", "label": "Provider API key", "description": "Stored in the plugin data directory and never returned by the settings API.", "default": "", "secret": true }, "provider_api_key_header": { "type": "enum", "label": "API key header", "options": [ "X-API-Key", "Authorization" ], "default": "X-API-Key" }, "provider_api_key_prefix": { "type": "string", "label": "API key prefix", "description": "For example: Bearer", "default": "" }, "provider_query_parameter": { "type": "string", "label": "Query parameter", "default": "q" }, "show_source_links": { "type": "boolean", "label": "Show source links", "default": true }, "allow_full_page_fetch": { "type": "boolean", "label": "Allow page excerpts", "description": "Allows bounded text extraction after search discovery. URL policy and redirect checks still apply.", "default": false }, "requests_per_minute": { "type": "integer", "label": "Requests per actor/minute", "default": 6, "minimum": 1, "maximum": 60 } } }