{ "tool_id": "lumi_ai_web_search", "tool_namespace": "web_search", "name": "lumi_ai_web_search", "display_name": "Lumi AI Web Search", "version": "0.1.0", "description": "Self-contained, policy-controlled public web search and safe URL extraction for Lumi Assistant. The default provider requires no API key or external service setup.", "scope": { "label": "Assistant public web lookup", "required_role": "user" }, "permissions": { "required_role": "user", "permission": "lumi_ai_web_search.use" }, "capabilities": [ "No-key public web search through the tool-contained Lumi search broker", "Safe explicit URL fetch and readable-text extraction", "Condensed URL summarization", "Whitelist or blacklist URL policy with wildcard rules", "Context-aware output budgets, caching, rate limits, diagnostics, and audits" ], "registered_capabilities": [ { "tool_id": "web_search.search", "enabled_setting": "enable_search", "description": "Search the public web for current or external information." }, { "tool_id": "web_search.fetch_url", "enabled_setting": "enable_fetch_url", "description": "Fetch and extract readable information from an explicit public URL." }, { "tool_id": "web_search.summarize_url", "enabled_setting": "enable_summarize_url", "description": "Fetch an explicit public URL and return compact structured content for summarization." } ], "limitations": [ "Search sources may rate-limit, block automated requests, or change markup", "No JavaScript execution or browser automation is enabled by default", "Private, local, link-local, metadata, credential-bearing, and non-HTTP targets are always blocked", "Search quality and freshness depend on public source availability" ], "tool_type": "web_search", "owning_plugin": "lumi_ai_web_search", "default_enabled": true, "entrypoints": { "backend": "index.js" }, "frontend_assets": [ "public" ], "views": [ "views/settings-modal.ejs" ], "settings_ui": { "view": "views/settings-modal.ejs", "scripts": [ "settings-modal.js" ], "styles": [ "settings-modal.css" ] }, "settings_migrator": "backend/settings.js", "diagnostic_settings": [ "provider", "policy_mode", "allowed_origins", "enable_search", "enable_fetch_url", "enable_summarize_url" ], "status_file": "data/status.json", "dependencies": [], "minimum_lumi_version": "0.1.0", "minimum_lumi_ai_version": "0.8.1", "required_plugins": [ "core", "lumi_ai" ], "required_platforms": [], "risk_level": "low", "confirmation_required": false, "data_paths": [ "data/settings.json", "data/status.json", "data/audit.jsonl", "data/cache" ], "preserve_on_update": [ "data" ], "update_notes": "Adds a self-contained no-key search broker plus independent search, fetch URL, and summarize URL capabilities.", "author": "Lumi", "homepage": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi", "repository_path": "plugins/lumi_ai_web_search", "settings_schema": { "provider": { "type": "enum", "label": "Provider", "description": "The default Lumi search broker is contained in this plugin and requires no API key or separate service.", "options": [ "lumi_search_broker", "external_json" ], "default": "lumi_search_broker" }, "enable_search": { "type": "boolean", "label": "Enable web search", "default": true }, "enable_fetch_url": { "type": "boolean", "label": "Enable explicit URL fetch", "default": true }, "enable_summarize_url": { "type": "boolean", "label": "Enable URL summarization", "default": true }, "enable_headless_browser_fallback": { "type": "boolean", "label": "Headless browser fallback", "description": "Reserved for a future Lumi-managed restricted browser runtime. HTTP mode works without it.", "default": false }, "policy_mode": { "type": "enum", "label": "URL policy", "description": "Blacklist allows safe public URLs except matching rules. Whitelist permits only matching rules.", "options": [ "blacklist", "whitelist" ], "default": "blacklist" }, "url_rules": { "type": "string_list", "label": "URL policy rules", "description": "One domain, subdomain, URL, path prefix, or * wildcard pattern per line.", "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 }, "fetch_timeout_ms": { "type": "integer", "label": "Page fetch timeout (ms)", "default": 10000, "minimum": 1000, "maximum": 30000 }, "max_fetch_bytes": { "type": "integer", "label": "Maximum fetched bytes", "default": 1048576, "minimum": 65536, "maximum": 4194304 }, "max_extracted_chars": { "type": "integer", "label": "Maximum extracted characters", "default": 12000, "minimum": 1000, "maximum": 50000 }, "max_redirects": { "type": "integer", "label": "Maximum redirects", "default": 3, "minimum": 0, "maximum": 8 }, "cache_ttl_seconds": { "type": "integer", "label": "Cache TTL (seconds)", "default": 900, "minimum": 0, "maximum": 86400 }, "safe_search_level": { "type": "enum", "label": "Safe search", "options": [ "off", "moderate", "strict" ], "default": "moderate" }, "allowed_origins": { "type": "multi_select", "label": "Allowed origins", "options": [ "webui", "discord", "twitch", "youtube", "kick", "other" ], "default": [ "webui", "discord", "twitch" ] }, "show_source_links_webui": { "type": "boolean", "label": "Show source links in WebUI", "default": true }, "show_source_links_discord": { "type": "boolean", "label": "Show source links in Discord", "default": true }, "show_source_links_twitch": { "type": "boolean", "label": "Show source links in Twitch", "default": false }, "webui_output_chars": { "type": "integer", "label": "WebUI output budget", "default": 2500, "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": 450, "minimum": 120, "maximum": 1000 }, "youtube_output_chars": { "type": "integer", "label": "YouTube output budget", "default": 1200, "minimum": 120, "maximum": 3000 }, "kick_output_chars": { "type": "integer", "label": "Kick output budget", "default": 450, "minimum": 120, "maximum": 1000 }, "other_output_chars": { "type": "integer", "label": "Other output budget", "default": 700, "minimum": 120, "maximum": 3000 }, "per_user_per_minute": { "type": "integer", "label": "Requests per user/minute", "default": 6, "minimum": 1, "maximum": 60 }, "per_origin_per_minute": { "type": "integer", "label": "Requests per origin/minute", "default": 30, "minimum": 1, "maximum": 300 }, "per_server_per_minute": { "type": "integer", "label": "Requests per server/minute", "default": 20, "minimum": 1, "maximum": 300 }, "external_provider_adapter": { "type": "enum", "label": "Advanced external adapter", "options": [ "searxng_json", "generic_json" ], "default": "searxng_json" }, "external_provider_endpoint": { "type": "string", "label": "Advanced external endpoint", "description": "Optional. Not required by the default Lumi search broker.", "default": "" }, "external_provider_api_key": { "type": "string", "label": "Advanced external API key", "default": "", "secret": true }, "external_provider_api_key_header": { "type": "enum", "label": "External API key header", "options": [ "X-API-Key", "Authorization" ], "default": "X-API-Key" }, "external_provider_api_key_prefix": { "type": "string", "label": "External API key prefix", "default": "" }, "external_provider_query_parameter": { "type": "string", "label": "External query parameter", "default": "q" } } }