@humain/terminal 0.2.2 → 0.3.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/CHANGELOG.md +4 -0
- package/dist/bundle/chunks/{chunk-NMPIM7MN.js → chunk-CBTAWCW5.js} +1 -1
- package/dist/bundle/chunks/{chunk-D6HHRSB5.js → chunk-S43N4JYF.js} +14 -29
- package/dist/bundle/chunks/{chunk-ADQYVZ6A.js → chunk-WKLAQTQ4.js} +104 -128
- package/dist/bundle/chunks/{compat-CN7WN6DA.js → compat-L5WILLPV.js} +1 -1
- package/dist/bundle/chunks/{extract-CTIFQZDJ.js → extract-2YP6VMY4.js} +3 -3
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/tools/subagent.d.ts +2 -0
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +46 -16
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/anysearch.js +4 -14
- package/dist/humain/web-access/vendor/anysearch.js.map +1 -1
- package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/bocha.js +3 -24
- package/dist/humain/web-access/vendor/bocha.js.map +1 -1
- package/dist/humain/web-access/vendor/brave.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/brave.js +3 -24
- package/dist/humain/web-access/vendor/brave.js.map +1 -1
- package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/brightdata.js +5 -34
- package/dist/humain/web-access/vendor/brightdata.js.map +1 -1
- package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/content-find.js +186 -51
- package/dist/humain/web-access/vendor/content-find.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.js +4 -1
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-run.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-run.js +3 -1
- package/dist/humain/web-access/vendor/curator-run.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.js +2 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
- package/dist/humain/web-access/vendor/domain-filter-normalization.d.ts +2 -0
- package/dist/humain/web-access/vendor/domain-filter-normalization.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/domain-filter-normalization.js +19 -0
- package/dist/humain/web-access/vendor/domain-filter-normalization.js.map +1 -0
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js +3 -24
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/extract.js +3 -1
- package/dist/humain/web-access/vendor/extract.js.map +1 -1
- package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/firecrawl.js +5 -32
- package/dist/humain/web-access/vendor/firecrawl.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.d.ts +5 -2
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.js +85 -37
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
- package/dist/humain/web-access/vendor/index.d.ts +3 -3
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/index.js +135 -157
- package/dist/humain/web-access/vendor/index.js.map +1 -1
- package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/jina-search.js +4 -14
- package/dist/humain/web-access/vendor/jina-search.js.map +1 -1
- package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/kagi.js +4 -12
- package/dist/humain/web-access/vendor/kagi.js.map +1 -1
- package/dist/humain/web-access/vendor/kimi-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/kimi-search.js +5 -32
- package/dist/humain/web-access/vendor/kimi-search.js.map +1 -1
- package/dist/humain/web-access/vendor/mistral-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/mistral-search.js +1 -18
- package/dist/humain/web-access/vendor/mistral-search.js.map +1 -1
- package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/ollama.js +2 -6
- package/dist/humain/web-access/vendor/ollama.js.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.d.ts +3 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.js +181 -38
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/opencode-session-headers.d.ts +10 -0
- package/dist/humain/web-access/vendor/opencode-session-headers.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/opencode-session-headers.js +23 -0
- package/dist/humain/web-access/vendor/opencode-session-headers.js.map +1 -0
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/page-query.js +10 -2
- package/dist/humain/web-access/vendor/page-query.js.map +1 -1
- package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/parallel.js +1 -18
- package/dist/humain/web-access/vendor/parallel.js.map +1 -1
- package/dist/humain/web-access/vendor/pdf-extract.d.ts +2 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/pdf-extract.js +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/querit.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/querit.js +5 -32
- package/dist/humain/web-access/vendor/querit.js.map +1 -1
- package/dist/humain/web-access/vendor/search-answer-formatting.d.ts +8 -0
- package/dist/humain/web-access/vendor/search-answer-formatting.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/search-answer-formatting.js +6 -0
- package/dist/humain/web-access/vendor/search-answer-formatting.js.map +1 -0
- package/dist/humain/web-access/vendor/search-result-count-normalization.d.ts +2 -0
- package/dist/humain/web-access/vendor/search-result-count-normalization.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/search-result-count-normalization.js +6 -0
- package/dist/humain/web-access/vendor/search-result-count-normalization.js.map +1 -0
- package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/search1api.js +5 -32
- package/dist/humain/web-access/vendor/search1api.js.map +1 -1
- package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/searchinfinity.js +5 -32
- package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -1
- package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/searxng.js +3 -24
- package/dist/humain/web-access/vendor/searxng.js.map +1 -1
- package/dist/humain/web-access/vendor/serpapi.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serpapi.js +5 -30
- package/dist/humain/web-access/vendor/serpapi.js.map +1 -1
- package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serpbase.js +3 -24
- package/dist/humain/web-access/vendor/serpbase.js.map +1 -1
- package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serpdive.js +3 -24
- package/dist/humain/web-access/vendor/serpdive.js.map +1 -1
- package/dist/humain/web-access/vendor/serper.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serper.js +5 -30
- package/dist/humain/web-access/vendor/serper.js.map +1 -1
- package/dist/humain/web-access/vendor/serply.d.ts +4 -0
- package/dist/humain/web-access/vendor/serply.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serply.js +191 -0
- package/dist/humain/web-access/vendor/serply.js.map +1 -0
- package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/source-check.js +11 -47
- package/dist/humain/web-access/vendor/source-check.js.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.js +6 -2
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
- package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/tavily.js +3 -24
- package/dist/humain/web-access/vendor/tavily.js.map +1 -1
- package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/tinyfish.js +5 -32
- package/dist/humain/web-access/vendor/tinyfish.js.map +1 -1
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/utils.js +2 -0
- package/dist/humain/web-access/vendor/utils.js.map +1 -1
- package/dist/humain/web-access/vendor/valyu.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/valyu.js +5 -30
- package/dist/humain/web-access/vendor/valyu.js.map +1 -1
- package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/xai-search.js +1 -18
- package/dist/humain/web-access/vendor/xai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/xcrawl.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/xcrawl.js +5 -34
- package/dist/humain/web-access/vendor/xcrawl.js.map +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
- package/src/humain/web-access/UPSTREAM.md +33 -1
- package/src/humain/web-access/upstream.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mistral-search.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/mistral-search.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { SearchOptions, SearchResponse, SearchResult } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst MISTRAL_CONVERSATIONS_URL = \"https://api.mistral.ai/v1/conversations\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst DEFAULT_SEARCH_MODEL = \"mistral-small-latest\";\nconst DEFAULT_SEARCH_TOOL = \"web_search\";\nconst MAX_RESULTS = 20;\n\ntype MistralSearchTool = \"web_search\" | \"web_search_premium\";\n\ninterface WebSearchConfig {\n\tmistralApiKey?: unknown;\n\tmistralSearchModel?: unknown;\n\tmistralSearchTool?: unknown;\n}\n\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nfunction resolveSearchModel(value: unknown): string {\n\tif (value === undefined) return DEFAULT_SEARCH_MODEL;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new Error(`mistralSearchModel in ${CONFIG_PATH} must be a non-empty string`);\n\t}\n\treturn value.trim();\n}\n\nfunction resolveSearchTool(value: unknown): MistralSearchTool {\n\tif (value === undefined) return DEFAULT_SEARCH_TOOL;\n\tif (value !== \"web_search\" && value !== \"web_search_premium\") {\n\t\tthrow new Error(`mistralSearchTool in ${CONFIG_PATH} must be either web_search or web_search_premium`);\n\t}\n\treturn value;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), MAX_RESULTS));\n}\n\nfunction normalizeDomain(value: string): string | null {\n\tlet input = value.trim().toLowerCase();\n\tif (!input) return null;\n\tif (input.startsWith(\"-\")) input = input.slice(1).trim();\n\tif (!input) return null;\n\ttry {\n\t\tconst parsed = input.includes(\"://\") ? new URL(input) : new URL(`https://${input}`);\n\t\tinput = parsed.hostname;\n\t} catch {\n\t\tinput = input.split(\"/\")[0]?.split(\":\")[0] ?? \"\";\n\t}\n\tinput = input.replace(/^\\.+|\\.+$/g, \"\");\n\treturn /^[a-z0-9][a-z0-9.-]*\\.[a-z]{2,}$/i.test(input) ? input : null;\n}\n\nfunction parseDomainFilters(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? filters.exclude : filters.include;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction passesDomainFilters(url: string, filters: DomainFilters): boolean {\n\tif (filters.include.length === 0 && filters.exclude.length === 0) return true;\n\tconst hostname = new URL(url).hostname.toLowerCase();\n\tconst matches = (domain: string) => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.exclude.some(matches)) return false;\n\treturn filters.include.length === 0 || filters.include.some(matches);\n}\n\nfunction normalizeResultUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst url = value.trim();\n\tif (!url) return null;\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return null;\n\t} catch {\n\t\treturn null;\n\t}\n\treturn url;\n}\n\nfunction buildSearchPrompt(query: string, options: SearchOptions, numResults: number): string {\n\tconst lines: string[] = [];\n\tif (options.recencyFilter) {\n\t\tconst labels: Record<string, string> = {\n\t\t\tday: \"past 24 hours\",\n\t\t\tweek: \"past week\",\n\t\t\tmonth: \"past month\",\n\t\t\tyear: \"past year\",\n\t\t};\n\t\tlines.push(`Prefer sources from the ${labels[options.recencyFilter] ?? options.recencyFilter}.`);\n\t}\n\tif (typeof options.numResults === \"number\" && Number.isFinite(options.numResults) && options.numResults > 0) {\n\t\tlines.push(`Prefer up to ${numResults} distinct sources.`);\n\t}\n\n\tconst filters = parseDomainFilters(options.domainFilter);\n\tif (filters.include.length > 0) lines.push(`Only use sources from: ${filters.include.slice(0, 100).join(\", \")}.`);\n\tif (filters.exclude.length > 0) lines.push(`Do not use sources from: ${filters.exclude.slice(0, 100).join(\", \")}.`);\n\treturn lines.length > 0 ? `${lines.join(\" \")}\\n\\n${query}` : query;\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`Mistral API returned invalid response: ${message}`);\n}\n\nfunction parseConversationResponse(value: unknown, options: SearchOptions, numResults: number): SearchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow invalidResponse(\"expected an object envelope\");\n\t}\n\tconst outputs = (value as Record<string, unknown>).outputs;\n\tif (!Array.isArray(outputs)) throw invalidResponse(\"outputs must be an array\");\n\n\tconst answerParts: string[] = [];\n\tconst results: SearchResult[] = [];\n\tconst seenUrls = new Set<string>();\n\tconst domainFilters = parseDomainFilters(options.domainFilter);\n\n\tfor (const output of outputs) {\n\t\tif (!output || typeof output !== \"object\" || Array.isArray(output)) continue;\n\t\tconst entry = output as Record<string, unknown>;\n\t\tif (entry.type !== \"message.output\") continue;\n\t\tconst content = entry.content;\n\t\tif (typeof content === \"string\") {\n\t\t\tif (content.trim()) answerParts.push(content.trim());\n\t\t\tcontinue;\n\t\t}\n\t\tif (!Array.isArray(content)) continue;\n\n\t\tfor (const chunk of content) {\n\t\t\tif (!chunk || typeof chunk !== \"object\" || Array.isArray(chunk)) continue;\n\t\t\tconst part = chunk as Record<string, unknown>;\n\t\t\tif (part.type === \"text\") {\n\t\t\t\tif (typeof part.text === \"string\" && part.text.trim()) answerParts.push(part.text.trim());\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (part.type !== \"tool_reference\" || results.length >= numResults) continue;\n\n\t\t\tconst url = normalizeResultUrl(part.url);\n\t\t\tif (!url || !passesDomainFilters(url, domainFilters) || seenUrls.has(url)) continue;\n\t\t\tseenUrls.add(url);\n\t\t\tconst title = typeof part.title === \"string\" && part.title.trim() ? part.title.trim() : url;\n\t\t\tconst snippet = typeof part.description === \"string\" ? part.description : \"\";\n\t\t\tresults.push({ title, url, snippet });\n\t\t}\n\t}\n\n\tconst answer = answerParts.join(\"\\n\").trim();\n\tif (!answer && results.length === 0) throw invalidResponse(\"no answer or sources\");\n\treturn { answer, results };\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await resolveCredential({\n\t\tprovider: \"Mistral\",\n\t\tconfiguredValue: loadConfig().mistralApiKey,\n\t\tenvironmentValue: process.env.MISTRAL_API_KEY,\n\t\tsignal,\n\t});\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Mistral API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"mistralApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set MISTRAL_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://console.mistral.ai/api-keys\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nexport function isMistralAvailable(): boolean {\n\ttry {\n\t\tconst config = loadConfig();\n\t\tresolveSearchModel(config.mistralSearchModel);\n\t\tresolveSearchTool(config.mistralSearchTool);\n\t\treturn hasCredentialSource({\n\t\t\tprovider: \"Mistral\",\n\t\t\tconfiguredValue: config.mistralApiKey,\n\t\t\tenvironmentValue: process.env.MISTRAL_API_KEY,\n\t\t});\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function searchWithMistral(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst config = loadConfig();\n\tconst model = resolveSearchModel(config.mistralSearchModel);\n\tconst tool = resolveSearchTool(config.mistralSearchTool);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst apiKey = await getApiKey(options.signal);\n\tconst requestSignal = options.signal\n\t\t? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal])\n\t\t: AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\n\ttry {\n\t\tconst response = await fetch(MISTRAL_CONVERSATIONS_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tinputs: [{ role: \"user\", content: buildSearchPrompt(query, options, numResults) }],\n\t\t\t\tstream: false,\n\t\t\t\tmodel,\n\t\t\t\ttools: [{ type: tool }],\n\t\t\t}),\n\t\t\tsignal: requestSignal,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\t\tthrow new Error(`Mistral API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t\t}\n\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = await response.json();\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Mistral API returned invalid JSON: ${errorMessage(err)}`);\n\t\t}\n\t\tconst result = parseConversationResponse(parsed, options, numResults);\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\treturn result;\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, redactedMessage);\n\t\t}\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mistral-search.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/mistral-search.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { normalizeDomain } from \"./domain-filter-normalization.ts\";\nimport type { SearchOptions, SearchResponse, SearchResult } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst MISTRAL_CONVERSATIONS_URL = \"https://api.mistral.ai/v1/conversations\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst DEFAULT_SEARCH_MODEL = \"mistral-small-latest\";\nconst DEFAULT_SEARCH_TOOL = \"web_search\";\nconst MAX_RESULTS = 20;\n\ntype MistralSearchTool = \"web_search\" | \"web_search_premium\";\n\ninterface WebSearchConfig {\n\tmistralApiKey?: unknown;\n\tmistralSearchModel?: unknown;\n\tmistralSearchTool?: unknown;\n}\n\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nfunction resolveSearchModel(value: unknown): string {\n\tif (value === undefined) return DEFAULT_SEARCH_MODEL;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new Error(`mistralSearchModel in ${CONFIG_PATH} must be a non-empty string`);\n\t}\n\treturn value.trim();\n}\n\nfunction resolveSearchTool(value: unknown): MistralSearchTool {\n\tif (value === undefined) return DEFAULT_SEARCH_TOOL;\n\tif (value !== \"web_search\" && value !== \"web_search_premium\") {\n\t\tthrow new Error(`mistralSearchTool in ${CONFIG_PATH} must be either web_search or web_search_premium`);\n\t}\n\treturn value;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), MAX_RESULTS));\n}\n\nfunction parseDomainFilters(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? filters.exclude : filters.include;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction passesDomainFilters(url: string, filters: DomainFilters): boolean {\n\tif (filters.include.length === 0 && filters.exclude.length === 0) return true;\n\tconst hostname = new URL(url).hostname.toLowerCase();\n\tconst matches = (domain: string) => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.exclude.some(matches)) return false;\n\treturn filters.include.length === 0 || filters.include.some(matches);\n}\n\nfunction normalizeResultUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst url = value.trim();\n\tif (!url) return null;\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return null;\n\t} catch {\n\t\treturn null;\n\t}\n\treturn url;\n}\n\nfunction buildSearchPrompt(query: string, options: SearchOptions, numResults: number): string {\n\tconst lines: string[] = [];\n\tif (options.recencyFilter) {\n\t\tconst labels: Record<string, string> = {\n\t\t\tday: \"past 24 hours\",\n\t\t\tweek: \"past week\",\n\t\t\tmonth: \"past month\",\n\t\t\tyear: \"past year\",\n\t\t};\n\t\tlines.push(`Prefer sources from the ${labels[options.recencyFilter] ?? options.recencyFilter}.`);\n\t}\n\tif (typeof options.numResults === \"number\" && Number.isFinite(options.numResults) && options.numResults > 0) {\n\t\tlines.push(`Prefer up to ${numResults} distinct sources.`);\n\t}\n\n\tconst filters = parseDomainFilters(options.domainFilter);\n\tif (filters.include.length > 0) lines.push(`Only use sources from: ${filters.include.slice(0, 100).join(\", \")}.`);\n\tif (filters.exclude.length > 0) lines.push(`Do not use sources from: ${filters.exclude.slice(0, 100).join(\", \")}.`);\n\treturn lines.length > 0 ? `${lines.join(\" \")}\\n\\n${query}` : query;\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`Mistral API returned invalid response: ${message}`);\n}\n\nfunction parseConversationResponse(value: unknown, options: SearchOptions, numResults: number): SearchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow invalidResponse(\"expected an object envelope\");\n\t}\n\tconst outputs = (value as Record<string, unknown>).outputs;\n\tif (!Array.isArray(outputs)) throw invalidResponse(\"outputs must be an array\");\n\n\tconst answerParts: string[] = [];\n\tconst results: SearchResult[] = [];\n\tconst seenUrls = new Set<string>();\n\tconst domainFilters = parseDomainFilters(options.domainFilter);\n\n\tfor (const output of outputs) {\n\t\tif (!output || typeof output !== \"object\" || Array.isArray(output)) continue;\n\t\tconst entry = output as Record<string, unknown>;\n\t\tif (entry.type !== \"message.output\") continue;\n\t\tconst content = entry.content;\n\t\tif (typeof content === \"string\") {\n\t\t\tif (content.trim()) answerParts.push(content.trim());\n\t\t\tcontinue;\n\t\t}\n\t\tif (!Array.isArray(content)) continue;\n\n\t\tfor (const chunk of content) {\n\t\t\tif (!chunk || typeof chunk !== \"object\" || Array.isArray(chunk)) continue;\n\t\t\tconst part = chunk as Record<string, unknown>;\n\t\t\tif (part.type === \"text\") {\n\t\t\t\tif (typeof part.text === \"string\" && part.text.trim()) answerParts.push(part.text.trim());\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (part.type !== \"tool_reference\" || results.length >= numResults) continue;\n\n\t\t\tconst url = normalizeResultUrl(part.url);\n\t\t\tif (!url || !passesDomainFilters(url, domainFilters) || seenUrls.has(url)) continue;\n\t\t\tseenUrls.add(url);\n\t\t\tconst title = typeof part.title === \"string\" && part.title.trim() ? part.title.trim() : url;\n\t\t\tconst snippet = typeof part.description === \"string\" ? part.description : \"\";\n\t\t\tresults.push({ title, url, snippet });\n\t\t}\n\t}\n\n\tconst answer = answerParts.join(\"\\n\").trim();\n\tif (!answer && results.length === 0) throw invalidResponse(\"no answer or sources\");\n\treturn { answer, results };\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await resolveCredential({\n\t\tprovider: \"Mistral\",\n\t\tconfiguredValue: loadConfig().mistralApiKey,\n\t\tenvironmentValue: process.env.MISTRAL_API_KEY,\n\t\tsignal,\n\t});\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Mistral API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"mistralApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set MISTRAL_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://console.mistral.ai/api-keys\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nexport function isMistralAvailable(): boolean {\n\ttry {\n\t\tconst config = loadConfig();\n\t\tresolveSearchModel(config.mistralSearchModel);\n\t\tresolveSearchTool(config.mistralSearchTool);\n\t\treturn hasCredentialSource({\n\t\t\tprovider: \"Mistral\",\n\t\t\tconfiguredValue: config.mistralApiKey,\n\t\t\tenvironmentValue: process.env.MISTRAL_API_KEY,\n\t\t});\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function searchWithMistral(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst config = loadConfig();\n\tconst model = resolveSearchModel(config.mistralSearchModel);\n\tconst tool = resolveSearchTool(config.mistralSearchTool);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst apiKey = await getApiKey(options.signal);\n\tconst requestSignal = options.signal\n\t\t? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal])\n\t\t: AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\n\ttry {\n\t\tconst response = await fetch(MISTRAL_CONVERSATIONS_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tinputs: [{ role: \"user\", content: buildSearchPrompt(query, options, numResults) }],\n\t\t\t\tstream: false,\n\t\t\t\tmodel,\n\t\t\t\ttools: [{ type: tool }],\n\t\t\t}),\n\t\t\tsignal: requestSignal,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\t\tthrow new Error(`Mistral API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t\t}\n\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = await response.json();\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Mistral API returned invalid JSON: ${errorMessage(err)}`);\n\t\t}\n\t\tconst result = parseConversationResponse(parsed, options, numResults);\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\treturn result;\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, redactedMessage);\n\t\t}\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ollama.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ollama.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAgG,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA4BrJ,UAAU,mBAAoB,SAAQ,aAAa;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,QAAQ,CAAC;IACzF,IAAI,CAAC,EAAE,UAAU,CAAC;CAClB;AAqFD,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAgDhH;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAoD/I"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { activityMonitor } from "./activity.js";
|
|
3
|
+
import { formatSearchResultsAsAnswer } from "./search-answer-formatting.js";
|
|
3
4
|
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
5
|
import { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig, validateRemoteUrl } from "./ssrf-protection.js";
|
|
5
6
|
import { getWebSearchConfigPath } from "./utils.js";
|
|
@@ -90,11 +91,6 @@ function parseFetchResponse(value) {
|
|
|
90
91
|
throw invalidResponse("expected content string");
|
|
91
92
|
return { title: envelope.title, content: envelope.content, links: envelope.links };
|
|
92
93
|
}
|
|
93
|
-
function buildAnswer(results) {
|
|
94
|
-
return results.map((result) => result.snippet
|
|
95
|
-
? `${result.snippet}\nSource: ${result.title} (${result.url})`
|
|
96
|
-
: `Source: ${result.title} (${result.url})`).join("\n\n");
|
|
97
|
-
}
|
|
98
94
|
export function isOllamaAvailable() {
|
|
99
95
|
return hasCredentialSource({ provider: "Ollama", configuredValue: loadConfig().ollamaApiKey, environmentValue: process.env.OLLAMA_API_KEY });
|
|
100
96
|
}
|
|
@@ -141,7 +137,7 @@ export async function searchWithOllama(query, options = {}) {
|
|
|
141
137
|
const data = parseSearchResponse(rawData);
|
|
142
138
|
activityMonitor.logComplete(activityId, response.status);
|
|
143
139
|
const results = data.results.slice(0, numResults).map((result) => ({ title: result.title, url: result.url, snippet: result.content }));
|
|
144
|
-
const mapped = { answer:
|
|
140
|
+
const mapped = { answer: formatSearchResultsAsAnswer(results), results };
|
|
145
141
|
if (options.includeContent) {
|
|
146
142
|
const inlineContent = data.results.slice(0, numResults)
|
|
147
143
|
.filter(result => result.content.trim().length > 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ollama.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig, validateRemoteUrl, type Lookup, type SsrfConfig } from \"./ssrf-protection.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst OLLAMA_SEARCH_URL = \"https://ollama.com/api/web_search\";\nconst OLLAMA_FETCH_URL = \"https://ollama.com/api/web_fetch\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tollamaApiKey?: unknown;\n}\n\ninterface OllamaSearchResult {\n\ttitle: string;\n\turl: string;\n\tcontent: string;\n}\n\ninterface OllamaSearchResponse {\n\tresults: OllamaSearchResult[];\n}\n\ninterface OllamaFetchResponse {\n\ttitle: string;\n\tcontent: string;\n\tlinks?: unknown;\n}\n\ninterface OllamaSearchOptions extends SearchOptions {\n\tincludeContent?: boolean;\n}\n\nexport interface OllamaExtractOptions extends Pick<ExtractOptions, \"timeoutMs\" | \"lookup\"> {\n\tssrf?: SsrfConfig;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Ollama\",\n\t\tconfiguredValue: loadConfig().ollamaApiKey,\n\t\tenvironmentValue: process.env.OLLAMA_API_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Ollama API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"ollamaApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set OLLAMA_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://ollama.com/settings/keys\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 10));\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`Ollama API returned invalid response: ${message}`);\n}\n\nfunction parseSearchResponse(value: unknown): OllamaSearchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst envelope = value as Record<string, unknown>;\n\tif (!Array.isArray(envelope.results)) throw invalidResponse(\"expected results array\");\n\tconst results: OllamaSearchResult[] = [];\n\tfor (const [index, value] of envelope.results.entries()) {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(`expected results[${index}] object`);\n\t\tconst item = value as Record<string, unknown>;\n\t\tif (typeof item.title !== \"string\") throw invalidResponse(`expected results[${index}].title string`);\n\t\tif (typeof item.url !== \"string\" || !item.url) throw invalidResponse(`expected results[${index}].url non-empty string`);\n\t\tif (typeof item.content !== \"string\") throw invalidResponse(`expected results[${index}].content string`);\n\t\tresults.push({ title: item.title, url: item.url, content: item.content });\n\t}\n\treturn { results };\n}\n\nfunction parseFetchResponse(value: unknown): OllamaFetchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected fetch object envelope\");\n\tconst envelope = value as Record<string, unknown>;\n\tif (typeof envelope.title !== \"string\") throw invalidResponse(\"expected title string\");\n\tif (typeof envelope.content !== \"string\") throw invalidResponse(\"expected content string\");\n\treturn { title: envelope.title, content: envelope.content, links: envelope.links };\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => result.snippet\n\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t: `Source: ${result.title} (${result.url})`).join(\"\\n\\n\");\n}\n\nexport function isOllamaAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"Ollama\", configuredValue: loadConfig().ollamaApiKey, environmentValue: process.env.OLLAMA_API_KEY });\n}\n\nexport async function searchWithOllama(query: string, options: OllamaSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(OLLAMA_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ query, max_results: numResults }),\n\t\t\tsignal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Ollama API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Ollama API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\n\tconst data = parseSearchResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results = data.results.slice(0, numResults).map((result) => ({ title: result.title, url: result.url, snippet: result.content }));\n\tconst mapped: SearchResponse = { answer: buildAnswer(results), results };\n\tif (options.includeContent) {\n\t\tconst inlineContent: ExtractedContent[] = data.results.slice(0, numResults)\n\t\t\t.filter(result => result.content.trim().length > 0)\n\t\t\t.map(result => ({ url: result.url, title: result.title, content: result.content, error: null }));\n\t\tif (inlineContent.length > 0) mapped.inlineContent = inlineContent;\n\t}\n\treturn mapped;\n}\n\nexport function isOllamaFetchAvailable(): boolean {\n\treturn isOllamaAvailable();\n}\n\nexport async function extractWithOllama(url: string, signal?: AbortSignal, options: OllamaExtractOptions = {}): Promise<ExtractedContent | null> {\n\tconst ssrf = options.ssrf ?? loadSsrfConfig();\n\tconst domainPolicy = loadFetchContentDomainPolicy();\n\tawait validateRemoteUrl(url, {\n\t\tallowRanges: ssrf.allowRanges,\n\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\tdomainPolicy,\n\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t});\n\tconst apiKey = await requireApiKey(signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query: `ollama fetch: ${url}` });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchRemoteUrl(OLLAMA_FETCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ url }),\n\t\t\tsignal: signal ? AbortSignal.any([AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS), signal]) : AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS),\n\t\t}, {\n\t\t\tallowRanges: ssrf.allowRanges,\n\t\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\t\tonRedirect: ({ from, to, init }) => to.origin === from.origin ? init : { ...init, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Ollama Web Fetch error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Ollama Web Fetch returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst data = parseFetchResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst content = data.content.trim();\n\tif (!content) return null;\n\treturn { url, title: data.title, content, error: null };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ollama.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { formatSearchResultsAsAnswer } from \"./search-answer-formatting.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig, validateRemoteUrl, type Lookup, type SsrfConfig } from \"./ssrf-protection.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst OLLAMA_SEARCH_URL = \"https://ollama.com/api/web_search\";\nconst OLLAMA_FETCH_URL = \"https://ollama.com/api/web_fetch\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tollamaApiKey?: unknown;\n}\n\ninterface OllamaSearchResult {\n\ttitle: string;\n\turl: string;\n\tcontent: string;\n}\n\ninterface OllamaSearchResponse {\n\tresults: OllamaSearchResult[];\n}\n\ninterface OllamaFetchResponse {\n\ttitle: string;\n\tcontent: string;\n\tlinks?: unknown;\n}\n\ninterface OllamaSearchOptions extends SearchOptions {\n\tincludeContent?: boolean;\n}\n\nexport interface OllamaExtractOptions extends Pick<ExtractOptions, \"timeoutMs\" | \"lookup\"> {\n\tssrf?: SsrfConfig;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Ollama\",\n\t\tconfiguredValue: loadConfig().ollamaApiKey,\n\t\tenvironmentValue: process.env.OLLAMA_API_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Ollama API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"ollamaApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set OLLAMA_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://ollama.com/settings/keys\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 10));\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`Ollama API returned invalid response: ${message}`);\n}\n\nfunction parseSearchResponse(value: unknown): OllamaSearchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst envelope = value as Record<string, unknown>;\n\tif (!Array.isArray(envelope.results)) throw invalidResponse(\"expected results array\");\n\tconst results: OllamaSearchResult[] = [];\n\tfor (const [index, value] of envelope.results.entries()) {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(`expected results[${index}] object`);\n\t\tconst item = value as Record<string, unknown>;\n\t\tif (typeof item.title !== \"string\") throw invalidResponse(`expected results[${index}].title string`);\n\t\tif (typeof item.url !== \"string\" || !item.url) throw invalidResponse(`expected results[${index}].url non-empty string`);\n\t\tif (typeof item.content !== \"string\") throw invalidResponse(`expected results[${index}].content string`);\n\t\tresults.push({ title: item.title, url: item.url, content: item.content });\n\t}\n\treturn { results };\n}\n\nfunction parseFetchResponse(value: unknown): OllamaFetchResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected fetch object envelope\");\n\tconst envelope = value as Record<string, unknown>;\n\tif (typeof envelope.title !== \"string\") throw invalidResponse(\"expected title string\");\n\tif (typeof envelope.content !== \"string\") throw invalidResponse(\"expected content string\");\n\treturn { title: envelope.title, content: envelope.content, links: envelope.links };\n}\n\nexport function isOllamaAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"Ollama\", configuredValue: loadConfig().ollamaApiKey, environmentValue: process.env.OLLAMA_API_KEY });\n}\n\nexport async function searchWithOllama(query: string, options: OllamaSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(OLLAMA_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ query, max_results: numResults }),\n\t\t\tsignal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Ollama API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Ollama API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\n\tconst data = parseSearchResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results = data.results.slice(0, numResults).map((result) => ({ title: result.title, url: result.url, snippet: result.content }));\n\tconst mapped: SearchResponse = { answer: formatSearchResultsAsAnswer(results), results };\n\tif (options.includeContent) {\n\t\tconst inlineContent: ExtractedContent[] = data.results.slice(0, numResults)\n\t\t\t.filter(result => result.content.trim().length > 0)\n\t\t\t.map(result => ({ url: result.url, title: result.title, content: result.content, error: null }));\n\t\tif (inlineContent.length > 0) mapped.inlineContent = inlineContent;\n\t}\n\treturn mapped;\n}\n\nexport function isOllamaFetchAvailable(): boolean {\n\treturn isOllamaAvailable();\n}\n\nexport async function extractWithOllama(url: string, signal?: AbortSignal, options: OllamaExtractOptions = {}): Promise<ExtractedContent | null> {\n\tconst ssrf = options.ssrf ?? loadSsrfConfig();\n\tconst domainPolicy = loadFetchContentDomainPolicy();\n\tawait validateRemoteUrl(url, {\n\t\tallowRanges: ssrf.allowRanges,\n\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\tdomainPolicy,\n\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t});\n\tconst apiKey = await requireApiKey(signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query: `ollama fetch: ${url}` });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchRemoteUrl(OLLAMA_FETCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ url }),\n\t\t\tsignal: signal ? AbortSignal.any([AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS), signal]) : AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS),\n\t\t}, {\n\t\t\tallowRanges: ssrf.allowRanges,\n\t\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\t\tonRedirect: ({ from, to, init }) => to.origin === from.origin ? init : { ...init, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Ollama Web Fetch error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Ollama Web Fetch returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst data = parseFetchResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst content = data.content.trim();\n\tif (!content) return null;\n\treturn { url, title: data.title, content, error: null };\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ExtensionContext } from "../host.ts";
|
|
2
2
|
import type { SearchOptions, SearchResponse } from "./perplexity.ts";
|
|
3
3
|
type ProviderHeaders = Record<string, string | null>;
|
|
4
|
+
export declare class OpenAIAlphaSearchUnsupportedError extends Error {
|
|
5
|
+
}
|
|
4
6
|
interface OpenAIAuth {
|
|
5
7
|
provider: string;
|
|
6
8
|
apiKey: string;
|
|
@@ -8,6 +10,7 @@ interface OpenAIAuth {
|
|
|
8
10
|
headers: ProviderHeaders;
|
|
9
11
|
responsesUrl: string;
|
|
10
12
|
useCodexEndpoint?: boolean;
|
|
13
|
+
useProviderBaseUrl?: boolean;
|
|
11
14
|
}
|
|
12
15
|
export declare function isCurrentModelHostedSearchEligible(ctx?: Pick<ExtensionContext, "model">): boolean;
|
|
13
16
|
export declare function resolveOpenAIAuth(ctx?: ExtensionContext, signal?: AbortSignal): Promise<OpenAIAuth | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-search.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/openai-search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-search.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/openai-search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAwCnF,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAIrD,qBAAa,iCAAkC,SAAQ,KAAK;CAAG;AAE/D,UAAU,UAAU;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B;AA+BD,wBAAgB,kCAAkC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG,OAAO,CASjG;AAqMD,wBAAsB,iBAAiB,CAAC,GAAG,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA6BrH;AAED,wBAAsB,uBAAuB,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBtF;AA8XD,wBAAsB,gBAAgB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,EAC3B,GAAG,CAAC,EAAE,gBAAgB,GACpB,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,wBAAsB,4BAA4B,CACjD,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,EAC3B,GAAG,CAAC,EAAE,gBAAgB,GACpB,OAAO,CAAC,cAAc,CAAC,CAIzB"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
3
|
import { activityMonitor } from "./activity.js";
|
|
4
|
+
import { normalizeDomain } from "./domain-filter-normalization.js";
|
|
3
5
|
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
6
|
import { getWebSearchConfigPath } from "./utils.js";
|
|
5
7
|
const OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses";
|
|
@@ -29,6 +31,8 @@ function pickSearchModel(models) {
|
|
|
29
31
|
}
|
|
30
32
|
class CustomOpenAIBaseUrlError extends Error {
|
|
31
33
|
}
|
|
34
|
+
export class OpenAIAlphaSearchUnsupportedError extends Error {
|
|
35
|
+
}
|
|
32
36
|
function resolveCurrentModelSearchTarget(model) {
|
|
33
37
|
const url = new URL(model.baseUrl);
|
|
34
38
|
if (url.protocol !== "https:")
|
|
@@ -76,24 +80,6 @@ function loadConfig() {
|
|
|
76
80
|
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
|
-
function normalizeDomain(value) {
|
|
80
|
-
let input = value.trim().toLowerCase();
|
|
81
|
-
if (!input)
|
|
82
|
-
return null;
|
|
83
|
-
if (input.startsWith("-"))
|
|
84
|
-
input = input.slice(1).trim();
|
|
85
|
-
if (!input)
|
|
86
|
-
return null;
|
|
87
|
-
try {
|
|
88
|
-
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
89
|
-
input = parsed.hostname;
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
93
|
-
}
|
|
94
|
-
input = input.replace(/^\.+|\.+$/g, "");
|
|
95
|
-
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
96
|
-
}
|
|
97
83
|
function normalizeDomainFilters(domainFilter) {
|
|
98
84
|
if (!domainFilter?.length)
|
|
99
85
|
return null;
|
|
@@ -157,6 +143,41 @@ function resolveConfiguredResponsesUrl(value) {
|
|
|
157
143
|
}
|
|
158
144
|
return url.toString();
|
|
159
145
|
}
|
|
146
|
+
function resolveUseProviderBaseUrl(config) {
|
|
147
|
+
if (config.openaiResponsesUrl !== undefined)
|
|
148
|
+
return false;
|
|
149
|
+
const value = config.openaiUseProviderBaseUrl;
|
|
150
|
+
if (value === undefined)
|
|
151
|
+
return false;
|
|
152
|
+
if (typeof value !== "boolean") {
|
|
153
|
+
throw new Error(`openaiUseProviderBaseUrl in ${CONFIG_PATH} must be a boolean`);
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
function resolveProviderResponsesUrl(baseUrl, useCodexEndpoint) {
|
|
158
|
+
let url;
|
|
159
|
+
try {
|
|
160
|
+
if (typeof baseUrl !== "string" || !baseUrl.trim())
|
|
161
|
+
throw new Error();
|
|
162
|
+
url = new URL(baseUrl.trim());
|
|
163
|
+
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
164
|
+
throw new Error();
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
throw new CustomOpenAIBaseUrlError("OpenAI search configuration: openaiUseProviderBaseUrl requires an absolute http(s) provider baseUrl");
|
|
168
|
+
}
|
|
169
|
+
const path = url.pathname.replace(/\/+$/u, "");
|
|
170
|
+
if (path.endsWith("/responses")) {
|
|
171
|
+
url.pathname = path;
|
|
172
|
+
}
|
|
173
|
+
else if (useCodexEndpoint && url.hostname.toLowerCase() === "chatgpt.com" && path === "/backend-api") {
|
|
174
|
+
url.pathname = "/backend-api/codex/responses";
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
url.pathname = `${path || "/v1"}/responses`;
|
|
178
|
+
}
|
|
179
|
+
return url.toString();
|
|
180
|
+
}
|
|
160
181
|
function resolveConfiguredSearchProviders(value) {
|
|
161
182
|
if (value === undefined)
|
|
162
183
|
return DEFAULT_SEARCH_PROVIDERS;
|
|
@@ -181,8 +202,9 @@ function toRequestHeaders(headers) {
|
|
|
181
202
|
}
|
|
182
203
|
return requestHeaders;
|
|
183
204
|
}
|
|
184
|
-
async function resolvePiAuth(ctx, responsesUrl, providers, modelOverride, hasExplicitResponsesUrl = false) {
|
|
205
|
+
async function resolvePiAuth(ctx, responsesUrl, providers, modelOverride, hasExplicitResponsesUrl = false, useProviderBaseUrl = false) {
|
|
185
206
|
let models;
|
|
207
|
+
let invalidProviderUrlError;
|
|
186
208
|
try {
|
|
187
209
|
models = ctx.modelRegistry.getAll();
|
|
188
210
|
}
|
|
@@ -206,7 +228,7 @@ async function resolvePiAuth(ctx, responsesUrl, providers, modelOverride, hasExp
|
|
|
206
228
|
// support from a gateway URL, or pair its credential with the official API.
|
|
207
229
|
const baseUrl = resolved.baseUrl ?? preferred.baseUrl;
|
|
208
230
|
const useCodexEndpoint = provider === "openai-codex" || isCodexJwt(resolved.apiKey);
|
|
209
|
-
if (!hasExplicitResponsesUrl && !useCodexEndpoint && baseUrl !== undefined) {
|
|
231
|
+
if (!hasExplicitResponsesUrl && !useProviderBaseUrl && !useCodexEndpoint && baseUrl !== undefined) {
|
|
210
232
|
let isOfficial = false;
|
|
211
233
|
try {
|
|
212
234
|
isOfficial = new URL(baseUrl).toString().replace(/\/+$/u, "") === "https://api.openai.com/v1";
|
|
@@ -217,26 +239,45 @@ async function resolvePiAuth(ctx, responsesUrl, providers, modelOverride, hasExp
|
|
|
217
239
|
throw new CustomOpenAIBaseUrlError(`OpenAI web search cannot reuse Pi credentials with a custom baseUrl by default. Set openaiResponsesUrl in ${CONFIG_PATH} to the full Responses endpoint for this credential.`);
|
|
218
240
|
}
|
|
219
241
|
}
|
|
242
|
+
let providerResponsesUrl = responsesUrl;
|
|
243
|
+
if (useProviderBaseUrl) {
|
|
244
|
+
try {
|
|
245
|
+
providerResponsesUrl = resolveProviderResponsesUrl(baseUrl, useCodexEndpoint);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
if (!(err instanceof CustomOpenAIBaseUrlError))
|
|
249
|
+
throw err;
|
|
250
|
+
invalidProviderUrlError ??= err;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
220
254
|
return {
|
|
221
255
|
provider,
|
|
222
256
|
apiKey: resolved.apiKey,
|
|
223
257
|
model: modelOverride ?? preferred.id,
|
|
224
258
|
headers: resolved.headers ?? {},
|
|
225
|
-
responsesUrl,
|
|
259
|
+
responsesUrl: providerResponsesUrl,
|
|
260
|
+
...(useProviderBaseUrl ? { useProviderBaseUrl: true } : {}),
|
|
226
261
|
};
|
|
227
262
|
}
|
|
263
|
+
if (invalidProviderUrlError)
|
|
264
|
+
throw invalidProviderUrlError;
|
|
228
265
|
return undefined;
|
|
229
266
|
}
|
|
230
267
|
export async function resolveOpenAIAuth(ctx, signal) {
|
|
231
268
|
const config = loadConfig();
|
|
232
269
|
const responsesUrl = resolveConfiguredResponsesUrl(config.openaiResponsesUrl);
|
|
270
|
+
const useProviderBaseUrl = resolveUseProviderBaseUrl(config);
|
|
233
271
|
const modelOverride = resolveConfiguredSearchModel(config.openaiSearchModel);
|
|
234
272
|
const providers = resolveConfiguredSearchProviders(config.openaiSearchProviders);
|
|
235
273
|
if (ctx) {
|
|
236
|
-
const auth = await resolvePiAuth(ctx, responsesUrl, providers, modelOverride, config.openaiResponsesUrl !== undefined);
|
|
274
|
+
const auth = await resolvePiAuth(ctx, responsesUrl, providers, modelOverride, config.openaiResponsesUrl !== undefined, useProviderBaseUrl);
|
|
237
275
|
if (auth)
|
|
238
276
|
return auth;
|
|
239
277
|
}
|
|
278
|
+
if (useProviderBaseUrl) {
|
|
279
|
+
throw new CustomOpenAIBaseUrlError("OpenAI search configuration: openaiUseProviderBaseUrl requires selected Pi provider credentials and a baseUrl; set openaiResponsesUrl for standalone API keys");
|
|
280
|
+
}
|
|
240
281
|
const hasSource = hasCredentialSource({
|
|
241
282
|
provider: "OpenAI",
|
|
242
283
|
configuredValue: config.openaiApiKey,
|
|
@@ -257,9 +298,10 @@ export async function resolveOpenAIAuth(ctx, signal) {
|
|
|
257
298
|
export async function isOpenAISearchAvailable(ctx) {
|
|
258
299
|
const config = loadConfig();
|
|
259
300
|
const responsesUrl = resolveConfiguredResponsesUrl(config.openaiResponsesUrl);
|
|
301
|
+
const useProviderBaseUrl = resolveUseProviderBaseUrl(config);
|
|
260
302
|
const providers = resolveConfiguredSearchProviders(config.openaiSearchProviders);
|
|
261
303
|
try {
|
|
262
|
-
if (ctx && await resolvePiAuth(ctx, responsesUrl, providers, undefined, config.openaiResponsesUrl !== undefined))
|
|
304
|
+
if (ctx && await resolvePiAuth(ctx, responsesUrl, providers, undefined, config.openaiResponsesUrl !== undefined, useProviderBaseUrl))
|
|
263
305
|
return true;
|
|
264
306
|
}
|
|
265
307
|
catch (err) {
|
|
@@ -267,6 +309,8 @@ export async function isOpenAISearchAvailable(ctx) {
|
|
|
267
309
|
return false;
|
|
268
310
|
throw err;
|
|
269
311
|
}
|
|
312
|
+
if (useProviderBaseUrl)
|
|
313
|
+
return false;
|
|
270
314
|
return hasCredentialSource({
|
|
271
315
|
provider: "OpenAI",
|
|
272
316
|
configuredValue: config.openaiApiKey,
|
|
@@ -480,7 +524,110 @@ function extractAnswer(output) {
|
|
|
480
524
|
}
|
|
481
525
|
return parts.join("\n").trim();
|
|
482
526
|
}
|
|
527
|
+
function isAlphaSearchEnabled() {
|
|
528
|
+
const value = loadConfig().openaiUseAlphaSearch;
|
|
529
|
+
if (value === undefined)
|
|
530
|
+
return false;
|
|
531
|
+
if (typeof value !== "boolean") {
|
|
532
|
+
throw new Error(`openaiUseAlphaSearch in ${CONFIG_PATH} must be a boolean`);
|
|
533
|
+
}
|
|
534
|
+
return value;
|
|
535
|
+
}
|
|
536
|
+
function resolveAlphaSearchUrl(responsesUrl) {
|
|
537
|
+
const url = new URL(responsesUrl);
|
|
538
|
+
const pathname = url.pathname.replace(/\/+$/u, "");
|
|
539
|
+
if (!pathname.endsWith("/responses")) {
|
|
540
|
+
throw new Error("OpenAI alpha/search configuration: endpoint path must end with /responses");
|
|
541
|
+
}
|
|
542
|
+
url.pathname = `${pathname.slice(0, -"/responses".length)}/alpha/search`;
|
|
543
|
+
return url.toString();
|
|
544
|
+
}
|
|
545
|
+
function buildAlphaSearchBody(query, options, model) {
|
|
546
|
+
const filters = normalizeDomainFilters(options.domainFilter);
|
|
547
|
+
if (filters?.blockedDomains?.length) {
|
|
548
|
+
throw new OpenAIAlphaSearchUnsupportedError("OpenAI alpha/search: unsupported excluded domains; use another search provider or disable openaiUseAlphaSearch");
|
|
549
|
+
}
|
|
550
|
+
const recencyDays = { day: 1, week: 7, month: 30, year: 365 };
|
|
551
|
+
return {
|
|
552
|
+
id: randomUUID(),
|
|
553
|
+
model,
|
|
554
|
+
commands: {
|
|
555
|
+
search_query: [{
|
|
556
|
+
q: query,
|
|
557
|
+
...(options.recencyFilter ? { recency: recencyDays[options.recencyFilter] } : {}),
|
|
558
|
+
...(filters?.allowedDomains ? { domains: filters.allowedDomains } : {}),
|
|
559
|
+
}],
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
function buildAlphaSearchHeaders(headers, apiKey) {
|
|
564
|
+
const result = new Headers(headers);
|
|
565
|
+
for (const name of ["OpenAI-Beta", "Session_ID", "Conversation_ID", "X-Codex-Beta-Features", "X-Codex-Turn-State", "x-openai-internal-codex-responses-lite"]) {
|
|
566
|
+
result.delete(name);
|
|
567
|
+
}
|
|
568
|
+
result.set("Authorization", `Bearer ${apiKey}`);
|
|
569
|
+
result.set("Content-Type", "application/json");
|
|
570
|
+
result.set("Accept", "application/json");
|
|
571
|
+
result.set("Originator", "codex_cli_rs");
|
|
572
|
+
return result;
|
|
573
|
+
}
|
|
574
|
+
async function parseAlphaSearchResponse(response, numResults = 5) {
|
|
575
|
+
const text = await response.text();
|
|
576
|
+
let payload;
|
|
577
|
+
try {
|
|
578
|
+
payload = JSON.parse(text);
|
|
579
|
+
}
|
|
580
|
+
catch {
|
|
581
|
+
throw new Error("OpenAI alpha/search returned invalid JSON");
|
|
582
|
+
}
|
|
583
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
584
|
+
throw new Error("OpenAI alpha/search returned an invalid response");
|
|
585
|
+
}
|
|
586
|
+
const record = payload;
|
|
587
|
+
const answer = typeof record.output === "string" ? record.output.trim() : "";
|
|
588
|
+
const results = [];
|
|
589
|
+
const seen = new Set();
|
|
590
|
+
for (const item of Array.isArray(record.results) ? record.results : []) {
|
|
591
|
+
if (!item || typeof item !== "object" || item.type !== "text_result" || typeof item.url !== "string")
|
|
592
|
+
continue;
|
|
593
|
+
try {
|
|
594
|
+
const url = new URL(item.url);
|
|
595
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
catch {
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
addResult(results, seen, item.url, item.title, typeof item.snippet === "string" ? item.snippet : "");
|
|
602
|
+
}
|
|
603
|
+
if (!answer && results.length === 0) {
|
|
604
|
+
throw new Error("OpenAI alpha/search returned no parseable results or plaintext output");
|
|
605
|
+
}
|
|
606
|
+
return {
|
|
607
|
+
answer,
|
|
608
|
+
results: typeof numResults === "number" && Number.isFinite(numResults) && numResults > 0
|
|
609
|
+
? results.slice(0, Math.min(Math.floor(numResults), 20))
|
|
610
|
+
: results,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
483
613
|
async function runOpenAISearch(query, options, auth) {
|
|
614
|
+
const useAlphaSearch = isAlphaSearchEnabled();
|
|
615
|
+
if (useAlphaSearch)
|
|
616
|
+
options.signal?.throwIfAborted();
|
|
617
|
+
const useCodexEndpoint = auth.useCodexEndpoint ?? (auth.provider === "openai-codex" || isCodexJwt(auth.apiKey));
|
|
618
|
+
const responsesUrl = useCodexEndpoint && !auth.useProviderBaseUrl ? CODEX_RESPONSES_URL : auth.responsesUrl;
|
|
619
|
+
const requestUrl = useAlphaSearch ? resolveAlphaSearchUrl(responsesUrl) : responsesUrl;
|
|
620
|
+
const body = useAlphaSearch ? buildAlphaSearchBody(query, options, auth.model) : {
|
|
621
|
+
model: auth.model,
|
|
622
|
+
instructions: buildInstructions(options),
|
|
623
|
+
input: [{ role: "user", content: [{ type: "input_text", text: query }] }],
|
|
624
|
+
tools: [buildWebSearchTool(options)],
|
|
625
|
+
include: ["web_search_call.action.sources"],
|
|
626
|
+
store: false,
|
|
627
|
+
stream: true,
|
|
628
|
+
tool_choice: "required",
|
|
629
|
+
parallel_tool_calls: true,
|
|
630
|
+
};
|
|
484
631
|
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
485
632
|
const headers = {
|
|
486
633
|
...toRequestHeaders(auth.headers),
|
|
@@ -488,28 +635,16 @@ async function runOpenAISearch(query, options, auth) {
|
|
|
488
635
|
"Content-Type": "application/json",
|
|
489
636
|
"OpenAI-Beta": "responses=experimental",
|
|
490
637
|
};
|
|
491
|
-
const useCodexEndpoint = auth.useCodexEndpoint ?? (auth.provider === "openai-codex" || isCodexJwt(auth.apiKey));
|
|
492
638
|
if (useCodexEndpoint) {
|
|
493
639
|
const accountId = extractAccountId(auth.apiKey);
|
|
494
640
|
if (accountId)
|
|
495
641
|
headers["chatgpt-account-id"] = accountId;
|
|
496
642
|
headers.originator = "pi";
|
|
497
643
|
}
|
|
498
|
-
const body = {
|
|
499
|
-
model: auth.model,
|
|
500
|
-
instructions: buildInstructions(options),
|
|
501
|
-
input: [{ role: "user", content: [{ type: "input_text", text: query }] }],
|
|
502
|
-
tools: [buildWebSearchTool(options)],
|
|
503
|
-
include: ["web_search_call.action.sources"],
|
|
504
|
-
store: false,
|
|
505
|
-
stream: true,
|
|
506
|
-
tool_choice: "required",
|
|
507
|
-
parallel_tool_calls: true,
|
|
508
|
-
};
|
|
509
644
|
try {
|
|
510
|
-
const response = await fetch(
|
|
645
|
+
const response = await fetch(requestUrl, {
|
|
511
646
|
method: "POST",
|
|
512
|
-
headers,
|
|
647
|
+
headers: useAlphaSearch ? buildAlphaSearchHeaders(headers, auth.apiKey) : headers,
|
|
513
648
|
body: JSON.stringify(body),
|
|
514
649
|
signal: options.signal
|
|
515
650
|
? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal])
|
|
@@ -518,7 +653,15 @@ async function runOpenAISearch(query, options, auth) {
|
|
|
518
653
|
if (!response.ok) {
|
|
519
654
|
activityMonitor.logError(activityId, `HTTP ${response.status}`);
|
|
520
655
|
const errorText = redactCredential(await response.text(), auth.apiKey);
|
|
521
|
-
|
|
656
|
+
const ErrorType = useAlphaSearch && [404, 405, 501].includes(response.status)
|
|
657
|
+
? OpenAIAlphaSearchUnsupportedError
|
|
658
|
+
: Error;
|
|
659
|
+
throw new ErrorType(`OpenAI ${useAlphaSearch ? "alpha/search " : ""}API error ${response.status}: ${errorText.slice(0, 300)}`);
|
|
660
|
+
}
|
|
661
|
+
if (useAlphaSearch) {
|
|
662
|
+
const result = await parseAlphaSearchResponse(response, options.numResults);
|
|
663
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
664
|
+
return result;
|
|
522
665
|
}
|
|
523
666
|
const parsed = await parseOpenAIResponse(response);
|
|
524
667
|
const output = Array.isArray(parsed.payload.output) ? parsed.payload.output : [];
|