@dbx-tools/appkit-web-search 0.6.223 → 0.6.224

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/README.md CHANGED
@@ -32,7 +32,10 @@ has no equivalent for.
32
32
  whose URL matches a pattern, mapped onto Mastra's `requireApproval`.
33
33
  - Every outbound call runs through AppKit's `execute()` chain - per-user cache,
34
34
  retry with jittered backoff, timeout, telemetry - and unwinds on an
35
- `AbortSignal`.
35
+ `AbortSignal`. Each plugin instance owns its policy and executor, so multiple
36
+ apps in one process remain isolated.
37
+ - Page and fallback-result HTML use parser-backed text conversion and selectors,
38
+ including complete HTML entity decoding and malformed-markup recovery.
36
39
 
37
40
  ## Why Use This Over Native AppKit
38
41
 
@@ -43,21 +46,20 @@ controls which sites are reachable and which calls pause for a human. Crucially,
43
46
  the web-search tool resolves its own web-search-capable model, so an agent
44
47
  running on any chat model (including one without web search) can still search. It
45
48
  is a thin add-on in the same shape as [`@dbx-tools/email`](../email): a Mastra
46
- tool pair plus an AppKit plugin that primes their shared runtime.
49
+ tool pair plus an AppKit plugin.
47
50
 
48
51
  ## Register The AppKit Plugin
49
52
 
50
53
  ```ts
51
54
  import { createApp, lakebase, server } from "@databricks/appkit";
52
- import { plugin as webSearchPlugin, tool as webTool } from "@dbx-tools/appkit-web-search";
55
+ import { plugin as webSearchPlugin } from "@dbx-tools/appkit-web-search";
53
56
  import { agents, plugin as mastraPlugin } from "@dbx-tools/appkit-mastra";
54
57
 
55
58
  const researcher = agents.createAgent({
56
59
  instructions: "Research questions using web_search, then read sources with web_fetch.",
57
- tools: () => ({
58
- web_search: webTool.webSearchTool(),
59
- web_fetch: webTool.webFetchTool(),
60
- }),
60
+ async tools(plugins) {
61
+ return { ...(await plugins["web-search"].toolkit()) };
62
+ },
61
63
  });
62
64
 
63
65
  await createApp({
@@ -74,10 +76,10 @@ await createApp({
74
76
  ```
75
77
 
76
78
  `plugin.webSearch()` resolves config (over env), compiles the URL policy, and
77
- primes the shared runtime the tools reuse. `tool.webSearchTool()` /
78
- `tool.webFetchTool()` build the two Mastra tools. Approval, when enabled,
79
- requires Mastra storage, so register `lakebase()` or configure storage in the
80
- Mastra plugin.
79
+ owns the executor used by its tools. App-integrated Mastra agents should consume
80
+ the native plugin toolkit as shown above, which preserves that plugin's policy,
81
+ OBO scope, and AppKit execution chain. Approval, when enabled, requires Mastra
82
+ storage, so register `lakebase()` or configure storage in the Mastra plugin.
81
83
 
82
84
  The plugin is also an AppKit `ToolProvider`, so an AppKit agent can take the
83
85
  same two tools without Mastra in the picture:
@@ -159,11 +161,13 @@ plugin.webSearch({
159
161
  ## Search And Fetch Without An Agent
160
162
 
161
163
  ```ts
162
- import { search, fetch, runtime } from "@dbx-tools/appkit-web-search";
164
+ import { search, fetch, runtime, tool } from "@dbx-tools/appkit-web-search";
163
165
  import { getExecutionContext } from "@databricks/appkit";
164
166
 
165
- // Prime the shared runtime once (or let the plugin do it at setup):
166
- runtime.getWebSearchRuntime({ model: "gemini", allowedUrls: ["*.databricks.com"] });
167
+ const webRuntime = runtime.createWebSearchRuntime({
168
+ model: "gemini",
169
+ allowedUrls: ["*.databricks.com"],
170
+ });
167
171
 
168
172
  // web_search needs the OBO client + host from the active execution context:
169
173
  const ctx = getExecutionContext();
@@ -171,19 +175,33 @@ const host = (await ctx.client.config.getHost()).toString();
171
175
 
172
176
  const result = await search.runWebSearch(
173
177
  { query: "unity catalog lineage best practices" },
174
- runtime.getWebSearchRuntime().config,
178
+ webRuntime,
175
179
  { client: ctx.client, host },
176
180
  );
177
181
  // result.answer, result.citations, result.model
178
182
 
179
- const page = await fetch.runWebFetch(
180
- { url: result.citations[0]!.url, format: "text" },
181
- runtime.getWebSearchRuntime().config,
182
- );
183
+ const page = await fetch.runWebFetch({ url: result.citations[0]!.url, format: "text" }, webRuntime);
183
184
  ```
184
185
 
185
186
  Use direct calls for operational lookups, tests, or admin flows where a model is
186
- not involved. The same resolved runtime is used by the AppKit plugin and tools.
187
+ not involved. Standalone Mastra tool factories likewise accept `runtime` or
188
+ `config`; they never discover or attach to a process-global plugin:
189
+
190
+ ```ts
191
+ const webRuntime = runtime.createWebSearchRuntime({
192
+ allowedUrls: ["*.databricks.com"],
193
+ });
194
+
195
+ const tools = {
196
+ web_search: tool.webSearchTool({ runtime: webRuntime }),
197
+ web_fetch: tool.webFetchTool({ runtime: webRuntime }),
198
+ };
199
+ ```
200
+
201
+ `getWebSearchRuntime()` remains as a deprecated compatibility constructor and
202
+ returns a new isolated runtime on every call. Process-global
203
+ `setWebSearchExecutor(executor)` registration is no longer supported; pass the
204
+ runtime explicitly or provide the executor to `createWebSearchRuntime`.
187
205
 
188
206
  ## Restrict Which URLs Are Reachable
189
207
 
@@ -249,8 +267,11 @@ tool.webFetchTool({ approval: "*.internal.example.com" });
249
267
  // The same thing, with the mode named:
250
268
  tool.webFetchTool({ approval: { mode: "urls", patterns: ["*.internal.example.com"] } });
251
269
 
252
- // Plugin-wide default (tools inherit unless they set their own):
270
+ // Plugin toolkit default:
253
271
  plugin.webSearch({ approval: ["*.internal.example.com", "*.corp.example.com"] });
272
+
273
+ // Standalone tool config:
274
+ tool.webFetchTool({ config: { approval: ["*.internal.example.com"] } });
254
275
  ```
255
276
 
256
277
  Every spelling normalizes to one of three modes - `{ mode: "none" }`,
@@ -316,14 +337,14 @@ the [Databricks docs](https://docs.databricks.com/aws/en/machine-learning/model-
316
337
  with, and the reasoning behind each.
317
338
  - `search` - `runWebSearch()` over the Databricks native web-search tool.
318
339
  - `provider` - provider detection + the provider -> tool-spec map.
319
- - `scrape` - `runScrapeSearch()` DuckDuckGo fallback for workspaces with no
320
- native web-search model.
340
+ - `scrape` - `runScrapeSearch()` DuckDuckGo fallback plus parser-backed
341
+ `parseDdgHtml()` result extraction for workspaces with no native web-search model.
321
342
  - `fetch` - `runWebFetch()` over got-scraping.
322
343
  - `html-text` - `htmlToText()` / `htmlFragmentToText()` / `decodeHtmlEntities()`, shared by
323
344
  `fetch` and the DuckDuckGo scrape fallback.
324
- - `runtime` - shared runtime and the executor outbound calls run through:
325
- `getWebSearchRuntime()`, `setWebSearchExecutor()`, `executeRead()`,
326
- `resetWebSearchRuntime()`.
345
+ - `runtime` - isolated runtime construction and execution:
346
+ `createWebSearchRuntime()`, `createResolvedWebSearchRuntime()`,
347
+ `executeRead()`, plus deprecated global-era compatibility names.
327
348
  - `config` - config types, JSON schema, `resolveWebSearchConfig()`, URL policy
328
349
  and approval helpers.
329
350
  - `allowlist` - URL allow-list parsing/compiling on top of `@dbx-tools/path`.
package/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-web-search";
6
- export const PACKAGE_VERSION = "0.6.223";
6
+ export const PACKAGE_VERSION = "0.6.224";
7
7
  export * as allowlist from "./src/allowlist.ts";
8
8
  export * as config from "./src/config.ts";
9
9
  export * as defaults from "./src/defaults.ts";
@@ -24,7 +24,7 @@ export type { WebSearchExecuteConfig, WebSearchExecutionSettings } from "./src/d
24
24
  export { WebSearchPlugin, webSearch } from "./src/plugin.ts";
25
25
  export { WEB_SEARCH_PROVIDERS } from "./src/provider.ts";
26
26
  export type { WebSearchProvider, WebSearchProviderSpec } from "./src/provider.ts";
27
- export type { WebSearchExecutor, WebSearchRuntime } from "./src/runtime.ts";
27
+ export type { WebSearchExecutor, WebSearchRuntime, WebSearchRuntimeInput } from "./src/runtime.ts";
28
28
  export { WEB_SEARCH_TOOL_DESCRIPTION, WEB_FETCH_TOOL_DESCRIPTION, webSearchRequestSchema, webSearchCitationSchema, webSearchResultSchema, webFetchRequestSchema, webFetchResultSchema } from "./src/schema.ts";
29
29
  export type { WebSearchRequest, WebSearchCitation, WebSearchResult, WebFetchRequest, WebFetchResult } from "./src/schema.ts";
30
30
  export type { WebSearchContext } from "./src/search.ts";
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-web-search";
2
- export declare const PACKAGE_VERSION = "0.6.223";
2
+ export declare const PACKAGE_VERSION = "0.6.224";
3
3
  export * as allowlist from "./src/allowlist.ts";
4
4
  export * as config from "./src/config.ts";
5
5
  export * as defaults from "./src/defaults.ts";
@@ -20,7 +20,7 @@ export type { WebSearchExecuteConfig, WebSearchExecutionSettings } from "./src/d
20
20
  export { WebSearchPlugin, webSearch } from "./src/plugin.ts";
21
21
  export { WEB_SEARCH_PROVIDERS } from "./src/provider.ts";
22
22
  export type { WebSearchProvider, WebSearchProviderSpec } from "./src/provider.ts";
23
- export type { WebSearchExecutor, WebSearchRuntime } from "./src/runtime.ts";
23
+ export type { WebSearchExecutor, WebSearchRuntime, WebSearchRuntimeInput } from "./src/runtime.ts";
24
24
  export { WEB_SEARCH_TOOL_DESCRIPTION, WEB_FETCH_TOOL_DESCRIPTION, webSearchRequestSchema, webSearchCitationSchema, webSearchResultSchema, webFetchRequestSchema, webFetchResultSchema } from "./src/schema.ts";
25
25
  export type { WebSearchRequest, WebSearchCitation, WebSearchResult, WebFetchRequest, WebFetchResult } from "./src/schema.ts";
26
26
  export type { WebSearchContext } from "./src/search.ts";
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Regenerated from the exporting modules in ./src.
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
  export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-web-search";
5
- export const PACKAGE_VERSION = "0.6.223";
5
+ export const PACKAGE_VERSION = "0.6.224";
6
6
  export * as allowlist from "./src/allowlist.js";
7
7
  export * as config from "./src/config.js";
8
8
  export * as defaults from "./src/defaults.js";
@@ -20,4 +20,4 @@ export { SEARCH_CACHE_TTL_SECONDS, FETCH_CACHE_TTL_SECONDS, SERVING_RETRY_ATTEMP
20
20
  export { WebSearchPlugin, webSearch } from "./src/plugin.js";
21
21
  export { WEB_SEARCH_PROVIDERS } from "./src/provider.js";
22
22
  export { WEB_SEARCH_TOOL_DESCRIPTION, WEB_FETCH_TOOL_DESCRIPTION, webSearchRequestSchema, webSearchCitationSchema, webSearchResultSchema, webFetchRequestSchema, webFetchResultSchema } from "./src/schema.js";
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyw4QkFBOEIsQ0FBQztBQUNqRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLFFBQVEsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUV0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLG9CQUFvQixFQUFFLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLHdCQUF3QixFQUFFLGtCQUFrQixFQUFFLHdCQUF3QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFMUwsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHVCQUF1QixFQUFFLHNCQUFzQixFQUFFLGtCQUFrQixFQUFFLHdCQUF3QixFQUFFLHVCQUF1QixFQUFFLDJCQUEyQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFbE4sT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUd6RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsMEJBQTBCLEVBQUUsc0JBQXNCLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvYXBwa2l0LXdlYi1zZWFyY2hcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMjNcIjtcbmV4cG9ydCAqIGFzIGFsbG93bGlzdCBmcm9tIFwiLi9zcmMvYWxsb3dsaXN0LnRzXCI7XG5leHBvcnQgKiBhcyBjb25maWcgZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0ICogYXMgZGVmYXVsdHMgZnJvbSBcIi4vc3JjL2RlZmF1bHRzLnRzXCI7XG5leHBvcnQgKiBhcyBmZXRjaCBmcm9tIFwiLi9zcmMvZmV0Y2gudHNcIjtcbmV4cG9ydCAqIGFzIGh0bWxUZXh0IGZyb20gXCIuL3NyYy9odG1sLXRleHQudHNcIjtcbmV4cG9ydCAqIGFzIHBsdWdpbiBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgKiBhcyBwcm92aWRlciBmcm9tIFwiLi9zcmMvcHJvdmlkZXIudHNcIjtcbmV4cG9ydCAqIGFzIHJ1bnRpbWUgZnJvbSBcIi4vc3JjL3J1bnRpbWUudHNcIjtcbmV4cG9ydCAqIGFzIHNjaGVtYSBmcm9tIFwiLi9zcmMvc2NoZW1hLnRzXCI7XG5leHBvcnQgKiBhcyBzY3JhcGUgZnJvbSBcIi4vc3JjL3NjcmFwZS50c1wiO1xuZXhwb3J0ICogYXMgc2VhcmNoIGZyb20gXCIuL3NyYy9zZWFyY2gudHNcIjtcbmV4cG9ydCAqIGFzIHRvb2wgZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgVXJsQWxsb3dMaXN0IH0gZnJvbSBcIi4vc3JjL2FsbG93bGlzdC50c1wiO1xuZXhwb3J0IHsgTU9ERUxfRU5WLCBTRVJWSU5HX0VORFBPSU5UX0VOViwgREVGQVVMVF9NT0RFTF9GQUxMQkFDS1MsIERFRkFVTFRfTUFYX0NJVEFUSU9OUywgREVGQVVMVF9GRVRDSF9NQVhfTEVOR1RILCBERUZBVUxUX1RJTUVPVVRfTVMsIFdFQl9TRUFSQ0hfQ09ORklHX1NDSEVNQSB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB0eXBlIHsgQXBwcm92YWxHYXRlLCBBcHByb3ZhbFBvbGljeSwgVXJsUG9saWN5TW9kZSwgTW9kZWxTb3VyY2UsIFdlYlNlYXJjaFBsdWdpbkNvbmZpZywgUmVzb2x2ZWRXZWJTZWFyY2hDb25maWcgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgeyBTRUFSQ0hfQ0FDSEVfVFRMX1NFQ09ORFMsIEZFVENIX0NBQ0hFX1RUTF9TRUNPTkRTLCBTRVJWSU5HX1JFVFJZX0FUVEVNUFRTLCBXRUJfUkVUUllfQVRURU1QVFMsIHdlYlNlYXJjaEV4ZWN1dGVEZWZhdWx0cywgd2ViRmV0Y2hFeGVjdXRlRGVmYXVsdHMsIHNjcmFwZVNlYXJjaEV4ZWN1dGVEZWZhdWx0cyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBXZWJTZWFyY2hFeGVjdXRlQ29uZmlnLCBXZWJTZWFyY2hFeGVjdXRpb25TZXR0aW5ncyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHsgV2ViU2VhcmNoUGx1Z2luLCB3ZWJTZWFyY2ggfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBXRUJfU0VBUkNIX1BST1ZJREVSUyB9IGZyb20gXCIuL3NyYy9wcm92aWRlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBXZWJTZWFyY2hQcm92aWRlciwgV2ViU2VhcmNoUHJvdmlkZXJTcGVjIH0gZnJvbSBcIi4vc3JjL3Byb3ZpZGVyLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdlYlNlYXJjaEV4ZWN1dG9yLCBXZWJTZWFyY2hSdW50aW1lIH0gZnJvbSBcIi4vc3JjL3J1bnRpbWUudHNcIjtcbmV4cG9ydCB7IFdFQl9TRUFSQ0hfVE9PTF9ERVNDUklQVElPTiwgV0VCX0ZFVENIX1RPT0xfREVTQ1JJUFRJT04sIHdlYlNlYXJjaFJlcXVlc3RTY2hlbWEsIHdlYlNlYXJjaENpdGF0aW9uU2NoZW1hLCB3ZWJTZWFyY2hSZXN1bHRTY2hlbWEsIHdlYkZldGNoUmVxdWVzdFNjaGVtYSwgd2ViRmV0Y2hSZXN1bHRTY2hlbWEgfSBmcm9tIFwiLi9zcmMvc2NoZW1hLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdlYlNlYXJjaFJlcXVlc3QsIFdlYlNlYXJjaENpdGF0aW9uLCBXZWJTZWFyY2hSZXN1bHQsIFdlYkZldGNoUmVxdWVzdCwgV2ViRmV0Y2hSZXN1bHQgfSBmcm9tIFwiLi9zcmMvc2NoZW1hLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdlYlNlYXJjaENvbnRleHQgfSBmcm9tIFwiLi9zcmMvc2VhcmNoLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdlYlNlYXJjaFRvb2xPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbiJdfQ==
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyw4QkFBOEIsQ0FBQztBQUNqRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLFFBQVEsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUV0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLG9CQUFvQixFQUFFLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLHdCQUF3QixFQUFFLGtCQUFrQixFQUFFLHdCQUF3QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFMUwsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHVCQUF1QixFQUFFLHNCQUFzQixFQUFFLGtCQUFrQixFQUFFLHdCQUF3QixFQUFFLHVCQUF1QixFQUFFLDJCQUEyQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFbE4sT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUd6RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsMEJBQTBCLEVBQUUsc0JBQXNCLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvYXBwa2l0LXdlYi1zZWFyY2hcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMjRcIjtcbmV4cG9ydCAqIGFzIGFsbG93bGlzdCBmcm9tIFwiLi9zcmMvYWxsb3dsaXN0LnRzXCI7XG5leHBvcnQgKiBhcyBjb25maWcgZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0ICogYXMgZGVmYXVsdHMgZnJvbSBcIi4vc3JjL2RlZmF1bHRzLnRzXCI7XG5leHBvcnQgKiBhcyBmZXRjaCBmcm9tIFwiLi9zcmMvZmV0Y2gudHNcIjtcbmV4cG9ydCAqIGFzIGh0bWxUZXh0IGZyb20gXCIuL3NyYy9odG1sLXRleHQudHNcIjtcbmV4cG9ydCAqIGFzIHBsdWdpbiBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgKiBhcyBwcm92aWRlciBmcm9tIFwiLi9zcmMvcHJvdmlkZXIudHNcIjtcbmV4cG9ydCAqIGFzIHJ1bnRpbWUgZnJvbSBcIi4vc3JjL3J1bnRpbWUudHNcIjtcbmV4cG9ydCAqIGFzIHNjaGVtYSBmcm9tIFwiLi9zcmMvc2NoZW1hLnRzXCI7XG5leHBvcnQgKiBhcyBzY3JhcGUgZnJvbSBcIi4vc3JjL3NjcmFwZS50c1wiO1xuZXhwb3J0ICogYXMgc2VhcmNoIGZyb20gXCIuL3NyYy9zZWFyY2gudHNcIjtcbmV4cG9ydCAqIGFzIHRvb2wgZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgVXJsQWxsb3dMaXN0IH0gZnJvbSBcIi4vc3JjL2FsbG93bGlzdC50c1wiO1xuZXhwb3J0IHsgTU9ERUxfRU5WLCBTRVJWSU5HX0VORFBPSU5UX0VOViwgREVGQVVMVF9NT0RFTF9GQUxMQkFDS1MsIERFRkFVTFRfTUFYX0NJVEFUSU9OUywgREVGQVVMVF9GRVRDSF9NQVhfTEVOR1RILCBERUZBVUxUX1RJTUVPVVRfTVMsIFdFQl9TRUFSQ0hfQ09ORklHX1NDSEVNQSB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB0eXBlIHsgQXBwcm92YWxHYXRlLCBBcHByb3ZhbFBvbGljeSwgVXJsUG9saWN5TW9kZSwgTW9kZWxTb3VyY2UsIFdlYlNlYXJjaFBsdWdpbkNvbmZpZywgUmVzb2x2ZWRXZWJTZWFyY2hDb25maWcgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgeyBTRUFSQ0hfQ0FDSEVfVFRMX1NFQ09ORFMsIEZFVENIX0NBQ0hFX1RUTF9TRUNPTkRTLCBTRVJWSU5HX1JFVFJZX0FUVEVNUFRTLCBXRUJfUkVUUllfQVRURU1QVFMsIHdlYlNlYXJjaEV4ZWN1dGVEZWZhdWx0cywgd2ViRmV0Y2hFeGVjdXRlRGVmYXVsdHMsIHNjcmFwZVNlYXJjaEV4ZWN1dGVEZWZhdWx0cyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBXZWJTZWFyY2hFeGVjdXRlQ29uZmlnLCBXZWJTZWFyY2hFeGVjdXRpb25TZXR0aW5ncyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHsgV2ViU2VhcmNoUGx1Z2luLCB3ZWJTZWFyY2ggfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBXRUJfU0VBUkNIX1BST1ZJREVSUyB9IGZyb20gXCIuL3NyYy9wcm92aWRlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBXZWJTZWFyY2hQcm92aWRlciwgV2ViU2VhcmNoUHJvdmlkZXJTcGVjIH0gZnJvbSBcIi4vc3JjL3Byb3ZpZGVyLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdlYlNlYXJjaEV4ZWN1dG9yLCBXZWJTZWFyY2hSdW50aW1lLCBXZWJTZWFyY2hSdW50aW1lSW5wdXQgfSBmcm9tIFwiLi9zcmMvcnVudGltZS50c1wiO1xuZXhwb3J0IHsgV0VCX1NFQVJDSF9UT09MX0RFU0NSSVBUSU9OLCBXRUJfRkVUQ0hfVE9PTF9ERVNDUklQVElPTiwgd2ViU2VhcmNoUmVxdWVzdFNjaGVtYSwgd2ViU2VhcmNoQ2l0YXRpb25TY2hlbWEsIHdlYlNlYXJjaFJlc3VsdFNjaGVtYSwgd2ViRmV0Y2hSZXF1ZXN0U2NoZW1hLCB3ZWJGZXRjaFJlc3VsdFNjaGVtYSB9IGZyb20gXCIuL3NyYy9zY2hlbWEudHNcIjtcbmV4cG9ydCB0eXBlIHsgV2ViU2VhcmNoUmVxdWVzdCwgV2ViU2VhcmNoQ2l0YXRpb24sIFdlYlNlYXJjaFJlc3VsdCwgV2ViRmV0Y2hSZXF1ZXN0LCBXZWJGZXRjaFJlc3VsdCB9IGZyb20gXCIuL3NyYy9zY2hlbWEudHNcIjtcbmV4cG9ydCB0eXBlIHsgV2ViU2VhcmNoQ29udGV4dCB9IGZyb20gXCIuL3NyYy9zZWFyY2gudHNcIjtcbmV4cG9ydCB0eXBlIHsgV2ViU2VhcmNoVG9vbE9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvdG9vbC50c1wiO1xuIl19
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * @module
16
16
  */
17
- import type { ResolvedWebSearchConfig } from "./config.ts";
17
+ import { type WebSearchRuntimeInput } from "./runtime.ts";
18
18
  import type { WebFetchRequest, WebFetchResult } from "./schema.ts";
19
19
  /**
20
20
  * Fetch a single URL and return its content in the requested format.
@@ -24,4 +24,4 @@ import type { WebFetchRequest, WebFetchResult } from "./schema.ts";
24
24
  * `maxLength` narrows (never widens) the plugin's `fetchMaxLength` cap.
25
25
  * `signal` cancels the in-flight fetch.
26
26
  */
27
- export declare function runWebFetch(request: WebFetchRequest, config: ResolvedWebSearchConfig, signal?: AbortSignal): Promise<WebFetchResult>;
27
+ export declare function runWebFetch(request: WebFetchRequest, runtimeOrConfig: WebSearchRuntimeInput, signal?: AbortSignal): Promise<WebFetchResult>;
package/lib/src/fetch.js CHANGED
@@ -19,7 +19,7 @@ import { gotScraping } from "got-scraping";
19
19
  import { assertFetchUrlAllowed } from "./_fetch-url.js";
20
20
  import { toCallSettings, webFetchExecuteDefaults } from "./defaults.js";
21
21
  import { decodeHtmlEntities, htmlToText } from "./html-text.js";
22
- import { executeRead } from "./runtime.js";
22
+ import { executeRead, toWebSearchRuntime } from "./runtime.js";
23
23
  const logger = log.logger("web-search/fetch");
24
24
  /** Pull the <title> text out of an HTML document, when present. */
25
25
  function extractTitle(html) {
@@ -41,12 +41,14 @@ function truncate(text, max) {
41
41
  * `maxLength` narrows (never widens) the plugin's `fetchMaxLength` cap.
42
42
  * `signal` cancels the in-flight fetch.
43
43
  */
44
- export async function runWebFetch(request, config, signal) {
44
+ export async function runWebFetch(request, runtimeOrConfig, signal) {
45
+ const runtime = toWebSearchRuntime(runtimeOrConfig);
46
+ const { config } = runtime;
45
47
  await assertFetchUrlAllowed(request.url, config.allowList);
46
48
  const cap = Math.min(request.maxLength ?? config.fetchMaxLength, config.fetchMaxLength);
47
49
  // The response is cached before the format reduction, so the same page read
48
50
  // as text and as html shares one network round trip.
49
- const page = await executeRead("page-fetch", toCallSettings(webFetchExecuteDefaults, config.timeoutMs, [
51
+ const page = await executeRead(runtime, "page-fetch", toCallSettings(webFetchExecuteDefaults, config.timeoutMs, [
50
52
  "web-search",
51
53
  "fetch",
52
54
  request.url,
@@ -96,4 +98,4 @@ export async function runWebFetch(request, config, signal) {
96
98
  truncated,
97
99
  };
98
100
  }
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmV0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUczQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFVOUMsbUVBQW1FO0FBQ25FLFNBQVMsWUFBWSxDQUFDLElBQVk7SUFDaEMsTUFBTSxLQUFLLEdBQUcsa0NBQWtDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVELE1BQU0sS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3BFLE9BQU8sS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzlDLENBQUM7QUFFRCxvRUFBb0U7QUFDcEUsU0FBUyxRQUFRLENBQUMsSUFBWSxFQUFFLEdBQVc7SUFDekMsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLEdBQUc7UUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElB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LENBQUMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFFM0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7UUFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2IsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO1FBQ3ZCLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07UUFDdkIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1FBQ3hCLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDMUMsQ0FBQyxDQUFDO0lBRUgsT0FBTztRQUNMLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztRQUNiLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVTtRQUN2QixHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDOUQsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzNCLE9BQU87UUFDUCxTQUFTO0tBQ1YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhZ2UgZmV0Y2hpbmcgb3ZlciB7QGxpbmsgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvZ290LXNjcmFwaW5nIHwgZ290LXNjcmFwaW5nfVxuICogLSBhIGBnb3RgIHdyYXBwZXIgdGhhdCBnZW5lcmF0ZXMgYnJvd3Nlci1saWtlIFRMUyArIGhlYWRlciBmaW5nZXJwcmludHMsIHNvXG4gKiBmZXRjaGVzIHN1cnZpdmUgdGhlIGJvdCB3YWxscyBhIHBsYWluIGBmZXRjaGAgdHJpcHMuIHtAbGluayBydW5XZWJGZXRjaH1cbiAqIGVuZm9yY2VzIHRoZSBVUkwgYWxsb3ctbGlzdCAoYW4gZXhwbGljaXQgZmV0Y2ggb2YgYSBkaXNhbGxvd2VkIFVSTCBpc1xuICogcmVmdXNlZCwgbm90IHNpbGVudGx5IGVtcHRpZWQpLCBmZXRjaGVzIHdpdGggdGhlIHBsdWdpbidzIHRpbWVvdXQsIGFuZFxuICogcmV0dXJucyBlaXRoZXIgdGhlIHJhdyBIVE1MIG9yIGEgcmVhZGFibGUgcGxhaW4tdGV4dCByZWR1Y3Rpb24sIGNhcHBlZCBhdFxuICogdGhlIGNvbmZpZ3VyZWQgbGVuZ3RoLlxuICpcbiAqIFRoZSBIVE1MLXRvLXRleHQgcmVkdWN0aW9uIGlzIGRlbGliZXJhdGVseSBkZXBlbmRlbmN5LWZyZWUgKHN0cmlwXG4gKiBzY3JpcHQvc3R5bGUsIHVud3JhcCB0YWdzLCBkZWNvZGUgYSBoYW5kZnVsIG9mIGVudGl0aWVzLCBjb2xsYXBzZVxuICogd2hpdGVzcGFjZSk6IGdvb2QgZW5vdWdoIHRvIGZlZWQgYSBtb2RlbCwgYW5kIGl0IGtlZXBzIHRoZSBhZGQtb24nc1xuICogZGVwZW5kZW5jeSBzdXJmYWNlIHRvIHRoZSB0d28gbGlicmFyaWVzIHRoZSB0YXNrIGNhbGxlZCBmb3IuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBnb3RTY3JhcGluZyB9IGZyb20gXCJnb3Qtc2NyYXBpbmdcIjtcbmltcG9ydCB7IGFzc2VydEZldGNoVXJsQWxsb3dlZCB9IGZyb20gXCIuL19mZXRjaC11cmwudHNcIjtcbmltcG9ydCB0eXBlIHsgUmVzb2x2ZWRXZWJTZWFyY2hDb25maWcgfSBmcm9tIFwiLi9jb25maWcudHNcIjtcbmltcG9ydCB7IHRvQ2FsbFNldHRpbmdzLCB3ZWJGZXRjaEV4ZWN1dGVEZWZhdWx0cyB9IGZyb20gXCIuL2RlZmF1bHRzLnRzXCI7XG5pbXBvcnQgeyBkZWNvZGVIdG1sRW50aXRpZXMsIGh0bWxUb1RleHQgfSBmcm9tIFwiLi9odG1sLXRleHQudHNcIjtcbmltcG9ydCB7IGV4ZWN1dGVSZWFkIH0gZnJvbSBcIi4vcnVudGltZS50c1wiO1xuaW1wb3J0IHR5cGUgeyBXZWJGZXRjaFJlcXVlc3QsIFdlYkZldGNoUmVzdWx0IH0gZnJvbSBcIi4vc2NoZW1hLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ3ZWItc2VhcmNoL2ZldGNoXCIpO1xuXG4vKiogVGhlIHNsaWNlIG9mIGEgZ290LXNjcmFwaW5nIHJlc3BvbnNlIHRoaXMgbW9kdWxlIHJlYWRzLiAqL1xuaW50ZXJmYWNlIEZldGNoZWRQYWdlIHtcbiAgdXJsOiBzdHJpbmc7XG4gIHN0YXR1c0NvZGU6IG51bWJlcjtcbiAgY29udGVudFR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgYm9keTogc3RyaW5nO1xufVxuXG4vKiogUHVsbCB0aGUgPHRpdGxlPiB0ZXh0IG91dCBvZiBhbiBIVE1MIGRvY3VtZW50LCB3aGVuIHByZXNlbnQuICovXG5mdW5jdGlvbiBleHRyYWN0VGl0bGUoaHRtbDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWF0Y2ggPSAvPHRpdGxlW14+XSo+KFtcXHNcXFNdKj8pPFxcL3RpdGxlPi9pLmV4ZWMoaHRtbCk7XG4gIGNvbnN0IHRpdGxlID0gbWF0Y2g/LlsxXSA/IGRlY29kZUh0bWxFbnRpdGllcyhtYXRjaFsxXSkudHJpbSgpIDogXCJcIjtcbiAgcmV0dXJuIHRpdGxlLmxlbmd0aCA+IDAgPyB0aXRsZSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIFRydW5jYXRlIGB0ZXh0YCB0byBgbWF4YCBjaGFycywgcmVwb3J0aW5nIHdoZXRoZXIgaXQgd2FzIGN1dC4gKi9cbmZ1bmN0aW9uIHRydW5jYXRlKHRleHQ6IHN0cmluZywgbWF4OiBudW1iZXIpOiB7IGNvbnRlbnQ6IHN0cmluZzsgdHJ1bmNhdGVkOiBib29sZWFuIH0ge1xuICBpZiAodGV4dC5sZW5ndGggPD0gbWF4KSByZXR1cm4geyBjb250ZW50OiB0ZXh0LCB0cnVuY2F0ZWQ6IGZhbHNlIH07XG4gIHJldHVybiB7IGNvbnRlbnQ6IHRleHQuc2xpY2UoMCwgbWF4KSwgdHJ1bmNhdGVkOiB0cnVlIH07XG59XG5cbi8qKlxuICogRmV0Y2ggYSBzaW5nbGUgVVJMIGFuZCByZXR1cm4gaXRzIGNvbnRlbnQgaW4gdGhlIHJlcXVlc3RlZCBmb3JtYXQuXG4gKlxuICogVGhyb3dzIHdoZW4gdGhlIFVSTCBpcyBub3QgcGVybWl0dGVkIGJ5IHRoZSBhbGxvdy1saXN0ICh0aGUgdmlzaWJsZSxcbiAqIGNvcnJlY3RhYmxlIGZhaWx1cmUgdGhlIGRlc2lnbiBjYWxscyBmb3Igb24gdGhlIGZldGNoIHBhdGgpLiBUaGUgcmVxdWVzdCdzXG4gKiBgbWF4TGVuZ3RoYCBuYXJyb3dzIChuZXZlciB3aWRlbnMpIHRoZSBwbHVnaW4ncyBgZmV0Y2hNYXhMZW5ndGhgIGNhcC5cbiAqIGBzaWduYWxgIGNhbmNlbHMgdGhlIGluLWZsaWdodCBmZXRjaC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bldlYkZldGNoKFxuICByZXF1ZXN0OiBXZWJGZXRjaFJlcXVlc3QsXG4gIGNvbmZpZzogUmVzb2x2ZWRXZWJTZWFyY2hDb25maWcsXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuKTogUHJvbWlzZTxXZWJGZXRjaFJlc3VsdD4ge1xuICBhd2FpdCBhc3NlcnRGZXRjaFVybEFsbG93ZWQocmVxdWVzdC51cmwsIGNvbmZpZy5hbGxvd0xpc3QpO1xuICBjb25zdCBjYXAgPSBNYXRoLm1pbihyZXF1ZXN0Lm1heExlbmd0aCA/PyBjb25maWcuZmV0Y2hNYXhMZW5ndGgsIGNvbmZpZy5mZXRjaE1heExlbmd0aCk7XG5cbiAgLy8gVGhlIHJlc3BvbnNlIGlzIGNhY2hlZCBiZWZvcmUgdGhlIGZvcm1hdCByZWR1Y3Rpb24sIHNvIHRoZSBzYW1lIHBhZ2UgcmVhZFxuICAvLyBhcyB0ZXh0IGFuZCBhcyBodG1sIHNoYXJlcyBvbmUgbmV0d29yayByb3VuZCB0cmlwLlxuICBjb25zdCBwYWdlID0gYXdhaXQgZXhlY3V0ZVJlYWQoXG4gICAgXCJwYWdlLWZldGNoXCIsXG4gICAgdG9DYWxsU2V0dGluZ3Mod2ViRmV0Y2hFeGVjdXRlRGVmYXVsdHMsIGNvbmZpZy50aW1lb3V0TXMsIFtcbiAgICAgIFwid2ViLXNlYXJjaFwiLFxuICAgICAgXCJmZXRjaFwiLFxuICAgICAgcmVxdWVzdC51cmwsXG4gICAgICAuLi5jb25maWcuYWxsb3dMaXN0LnBhdHRlcm5zLFxuICAgIF0pLFxuICAgIGFzeW5jIChleGVjdXRlU2lnbmFsKTogUHJvbWlzZTxGZXRjaGVkUGFnZT4gPT4ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBnb3RTY3JhcGluZyh7XG4gICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgIC8vIGdvdCdzIG93biB0aW1lb3V0IGFib3J0cyB0aGUgc29ja2V0IGFuZCByZXBvcnRzIHdoaWNoIHBoYXNlIHRpbWVkXG4gICAgICAgIC8vIG91dDsgdGhlIGludGVyY2VwdG9yIHRpbWVvdXQgYm91bmRzIHRoZSB3aG9sZSBhdHRlbXB0IGFyb3VuZCBpdC5cbiAgICAgICAgdGltZW91dDogeyByZXF1ZXN0OiBjb25maWcudGltZW91dE1zIH0sXG4gICAgICAgIHRocm93SHR0cEVycm9yczogZmFsc2UsXG4gICAgICAgIGZvbGxvd1JlZGlyZWN0OiB0cnVlLFxuICAgICAgICBob29rczoge1xuICAgICAgICAgIGJlZm9yZVJlcXVlc3Q6IFtcbiAgICAgICAgICAgIGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAgIGF3YWl0IGFzc2VydEZldGNoVXJsQWxsb3dlZChTdHJpbmcob3B0aW9ucy51cmwpLCBjb25maWcuYWxsb3dMaXN0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4uKGV4ZWN1dGVTaWduYWwgPyB7IHNpZ25hbDogZXhlY3V0ZVNpZ25hbCB9IDoge30pLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1cmw6IHJlc3BvbnNlLnVybCA/PyByZXF1ZXN0LnVybCxcbiAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzQ29kZSxcbiAgICAgICAgY29udGVudFR5cGU6IHJlc3BvbnNlLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0sXG4gICAgICAgIGJvZHk6IHR5cGVvZiByZXNwb25zZS5ib2R5ID09PSBcInN0cmluZ1wiID8gcmVzcG9uc2UuYm9keSA6IFN0cmluZyhyZXNwb25zZS5ib2R5ID8/IFwiXCIpLFxuICAgICAgfTtcbiAgICB9LFxuICAgIHNpZ25hbCxcbiAgKTtcbiAgYXdhaXQgYXNzZXJ0RmV0Y2hVcmxBbGxvd2VkKHBhZ2UudXJsLCBjb25maWcuYWxsb3dMaXN0KTtcblxuICBjb25zdCBpc0h0bWwgPSAhcGFnZS5jb250ZW50VHlwZSB8fCAvaHRtbHx4bWwvaS50ZXN0KHBhZ2UuY29udGVudFR5cGUpO1xuICBjb25zdCByYXdDb250ZW50ID0gcmVxdWVzdC5mb3JtYXQgPT09IFwiaHRtbFwiIHx8ICFpc0h0bWwgPyBwYWdlLmJvZHkgOiBodG1sVG9UZXh0KHBhZ2UuYm9keSk7XG4gIGNvbnN0IHsgY29udGVudCwgdHJ1bmNhdGVkIH0gPSB0cnVuY2F0ZShyYXdDb250ZW50LCBjYXApO1xuICBjb25zdCB0aXRsZSA9IGlzSHRtbCA/IGV4dHJhY3RUaXRsZShwYWdlLmJvZHkpIDogdW5kZWZpbmVkO1xuXG4gIGxvZ2dlci5kZWJ1ZyhcImZldGNoZWRcIiwge1xuICAgIHVybDogcGFnZS51cmwsXG4gICAgc3RhdHVzOiBwYWdlLnN0YXR1c0NvZGUsXG4gICAgYnl0ZXM6IHBhZ2UuYm9keS5sZW5ndGgsXG4gICAgcmV0dXJuZWQ6IGNvbnRlbnQubGVuZ3RoLFxuICAgIC4uLih0cnVuY2F0ZWQgPyB7IHRydW5jYXRlZDogdHJ1ZSB9IDoge30pLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHVybDogcGFnZS51cmwsXG4gICAgc3RhdHVzOiBwYWdlLnN0YXR1c0NvZGUsXG4gICAgLi4uKHBhZ2UuY29udGVudFR5cGUgPyB7IGNvbnRlbnRUeXBlOiBwYWdlLmNvbnRlbnRUeXBlIH0gOiB7fSksXG4gICAgLi4uKHRpdGxlID8geyB0aXRsZSB9IDoge30pLFxuICAgIGNvbnRlbnQsXG4gICAgdHJ1bmNhdGVkLFxuICB9O1xufVxuIl19
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmV0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBOEIsTUFBTSxjQUFjLENBQUM7QUFHM0YsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBVTlDLG1FQUFtRTtBQUNuRSxTQUFTLFlBQVksQ0FBQyxJQUFZO0lBQ2hDLE1BQU0sS0FBSyxHQUFHLGtDQUFrQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1RCxNQUFNLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNwRSxPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLFNBQVMsUUFBUSxDQUFDLElBQVksRUFBRSxHQUFXO0lBQ3pDLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxHQUFHO1FBQUUsT0FBTyxFQUFF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LENBQUM7SUFDNUYsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxRQUFRLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRTNELE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO1FBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztRQUNiLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVTtRQUN2QixLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1FBQ3ZCLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTTtRQUN4QixHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQzFDLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7UUFDYixNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVU7UUFDdkIsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlELEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzQixPQUFPO1FBQ1AsU0FBUztLQUNWLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYWdlIGZldGNoaW5nIG92ZXIge0BsaW5rIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2dvdC1zY3JhcGluZyB8IGdvdC1zY3JhcGluZ31cbiAqIC0gYSBgZ290YCB3cmFwcGVyIHRoYXQgZ2VuZXJhdGVzIGJyb3dzZXItbGlrZSBUTFMgKyBoZWFkZXIgZmluZ2VycHJpbnRzLCBzb1xuICogZmV0Y2hlcyBzdXJ2aXZlIHRoZSBib3Qgd2FsbHMgYSBwbGFpbiBgZmV0Y2hgIHRyaXBzLiB7QGxpbmsgcnVuV2ViRmV0Y2h9XG4gKiBlbmZvcmNlcyB0aGUgVVJMIGFsbG93LWxpc3QgKGFuIGV4cGxpY2l0IGZldGNoIG9mIGEgZGlzYWxsb3dlZCBVUkwgaXNcbiAqIHJlZnVzZWQsIG5vdCBzaWxlbnRseSBlbXB0aWVkKSwgZmV0Y2hlcyB3aXRoIHRoZSBwbHVnaW4ncyB0aW1lb3V0LCBhbmRcbiAqIHJldHVybnMgZWl0aGVyIHRoZSByYXcgSFRNTCBvciBhIHJlYWRhYmxlIHBsYWluLXRleHQgcmVkdWN0aW9uLCBjYXBwZWQgYXRcbiAqIHRoZSBjb25maWd1cmVkIGxlbmd0aC5cbiAqXG4gKiBUaGUgSFRNTC10by10ZXh0IHJlZHVjdGlvbiBpcyBkZWxpYmVyYXRlbHkgZGVwZW5kZW5jeS1mcmVlIChzdHJpcFxuICogc2NyaXB0L3N0eWxlLCB1bndyYXAgdGFncywgZGVjb2RlIGEgaGFuZGZ1bCBvZiBlbnRpdGllcywgY29sbGFwc2VcbiAqIHdoaXRlc3BhY2UpOiBnb29kIGVub3VnaCB0byBmZWVkIGEgbW9kZWwsIGFuZCBpdCBrZWVwcyB0aGUgYWRkLW9uJ3NcbiAqIGRlcGVuZGVuY3kgc3VyZmFjZSB0byB0aGUgdHdvIGxpYnJhcmllcyB0aGUgdGFzayBjYWxsZWQgZm9yLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZ290U2NyYXBpbmcgfSBmcm9tIFwiZ290LXNjcmFwaW5nXCI7XG5pbXBvcnQgeyBhc3NlcnRGZXRjaFVybEFsbG93ZWQgfSBmcm9tIFwiLi9fZmV0Y2gtdXJsLnRzXCI7XG5pbXBvcnQgeyB0b0NhbGxTZXR0aW5ncywgd2ViRmV0Y2hFeGVjdXRlRGVmYXVsdHMgfSBmcm9tIFwiLi9kZWZhdWx0cy50c1wiO1xuaW1wb3J0IHsgZGVjb2RlSHRtbEVudGl0aWVzLCBodG1sVG9UZXh0IH0gZnJvbSBcIi4vaHRtbC10ZXh0LnRzXCI7XG5pbXBvcnQgeyBleGVjdXRlUmVhZCwgdG9XZWJTZWFyY2hSdW50aW1lLCB0eXBlIFdlYlNlYXJjaFJ1bnRpbWVJbnB1dCB9IGZyb20gXCIuL3J1bnRpbWUudHNcIjtcbmltcG9ydCB0eXBlIHsgV2ViRmV0Y2hSZXF1ZXN0LCBXZWJGZXRjaFJlc3VsdCB9IGZyb20gXCIuL3NjaGVtYS50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwid2ViLXNlYXJjaC9mZXRjaFwiKTtcblxuLyoqIFRoZSBzbGljZSBvZiBhIGdvdC1zY3JhcGluZyByZXNwb25zZSB0aGlzIG1vZHVsZSByZWFkcy4gKi9cbmludGVyZmFjZSBGZXRjaGVkUGFnZSB7XG4gIHVybDogc3RyaW5nO1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIGNvbnRlbnRUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGJvZHk6IHN0cmluZztcbn1cblxuLyoqIFB1bGwgdGhlIDx0aXRsZT4gdGV4dCBvdXQgb2YgYW4gSFRNTCBkb2N1bWVudCwgd2hlbiBwcmVzZW50LiAqL1xuZnVuY3Rpb24gZXh0cmFjdFRpdGxlKGh0bWw6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG1hdGNoID0gLzx0aXRsZVtePl0qPihbXFxzXFxTXSo/KTxcXC90aXRsZT4vaS5leGVjKGh0bWwpO1xuICBjb25zdCB0aXRsZSA9IG1hdGNoPy5bMV0gPyBkZWNvZGVIdG1sRW50aXRpZXMobWF0Y2hbMV0pLnRyaW0oKSA6IFwiXCI7XG4gIHJldHVybiB0aXRsZS5sZW5ndGggPiAwID8gdGl0bGUgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBUcnVuY2F0ZSBgdGV4dGAgdG8gYG1heGAgY2hhcnMsIHJlcG9ydGluZyB3aGV0aGVyIGl0IHdhcyBjdXQuICovXG5mdW5jdGlvbiB0cnVuY2F0ZSh0ZXh0OiBzdHJpbmcsIG1heDogbnVtYmVyKTogeyBjb250ZW50OiBzdHJpbmc7IHRydW5jYXRlZDogYm9vbGVhbiB9IHtcbiAgaWYgKHRleHQubGVuZ3RoIDw9IG1heCkgcmV0dXJuIHsgY29udGVudDogdGV4dCwgdHJ1bmNhdGVkOiBmYWxzZSB9O1xuICByZXR1cm4geyBjb250ZW50OiB0ZXh0LnNsaWNlKDAsIG1heCksIHRydW5jYXRlZDogdHJ1ZSB9O1xufVxuXG4vKipcbiAqIEZldGNoIGEgc2luZ2xlIFVSTCBhbmQgcmV0dXJuIGl0cyBjb250ZW50IGluIHRoZSByZXF1ZXN0ZWQgZm9ybWF0LlxuICpcbiAqIFRocm93cyB3aGVuIHRoZSBVUkwgaXMgbm90IHBlcm1pdHRlZCBieSB0aGUgYWxsb3ctbGlzdCAodGhlIHZpc2libGUsXG4gKiBjb3JyZWN0YWJsZSBmYWlsdXJlIHRoZSBkZXNpZ24gY2FsbHMgZm9yIG9uIHRoZSBmZXRjaCBwYXRoKS4gVGhlIHJlcXVlc3Qnc1xuICogYG1heExlbmd0aGAgbmFycm93cyAobmV2ZXIgd2lkZW5zKSB0aGUgcGx1Z2luJ3MgYGZldGNoTWF4TGVuZ3RoYCBjYXAuXG4gKiBgc2lnbmFsYCBjYW5jZWxzIHRoZSBpbi1mbGlnaHQgZmV0Y2guXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5XZWJGZXRjaChcbiAgcmVxdWVzdDogV2ViRmV0Y2hSZXF1ZXN0LFxuICBydW50aW1lT3JDb25maWc6IFdlYlNlYXJjaFJ1bnRpbWVJbnB1dCxcbiAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4pOiBQcm9taXNlPFdlYkZldGNoUmVzdWx0PiB7XG4gIGNvbnN0IHJ1bnRpbWUgPSB0b1dlYlNlYXJjaFJ1bnRpbWUocnVudGltZU9yQ29uZmlnKTtcbiAgY29uc3QgeyBjb25maWcgfSA9IHJ1bnRpbWU7XG4gIGF3YWl0IGFzc2VydEZldGNoVXJsQWxsb3dlZChyZXF1ZXN0LnVybCwgY29uZmlnLmFsbG93TGlzdCk7XG4gIGNvbnN0IGNhcCA9IE1hdGgubWluKHJlcXVlc3QubWF4TGVuZ3RoID8/IGNvbmZpZy5mZXRjaE1heExlbmd0aCwgY29uZmlnLmZldGNoTWF4TGVuZ3RoKTtcblxuICAvLyBUaGUgcmVzcG9uc2UgaXMgY2FjaGVkIGJlZm9yZSB0aGUgZm9ybWF0IHJlZHVjdGlvbiwgc28gdGhlIHNhbWUgcGFnZSByZWFkXG4gIC8vIGFzIHRleHQgYW5kIGFzIGh0bWwgc2hhcmVzIG9uZSBuZXR3b3JrIHJvdW5kIHRyaXAuXG4gIGNvbnN0IHBhZ2UgPSBhd2FpdCBleGVjdXRlUmVhZChcbiAgICBydW50aW1lLFxuICAgIFwicGFnZS1mZXRjaFwiLFxuICAgIHRvQ2FsbFNldHRpbmdzKHdlYkZldGNoRXhlY3V0ZURlZmF1bHRzLCBjb25maWcudGltZW91dE1zLCBbXG4gICAgICBcIndlYi1zZWFyY2hcIixcbiAgICAgIFwiZmV0Y2hcIixcbiAgICAgIHJlcXVlc3QudXJsLFxuICAgICAgLi4uY29uZmlnLmFsbG93TGlzdC5wYXR0ZXJucyxcbiAgICBdKSxcbiAgICBhc3luYyAoZXhlY3V0ZVNpZ25hbCk6IFByb21pc2U8RmV0Y2hlZFBhZ2U+ID0+IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZ290U2NyYXBpbmcoe1xuICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAvLyBnb3QncyBvd24gdGltZW91dCBhYm9ydHMgdGhlIHNvY2tldCBhbmQgcmVwb3J0cyB3aGljaCBwaGFzZSB0aW1lZFxuICAgICAgICAvLyBvdXQ7IHRoZSBpbnRlcmNlcHRvciB0aW1lb3V0IGJvdW5kcyB0aGUgd2hvbGUgYXR0ZW1wdCBhcm91bmQgaXQuXG4gICAgICAgIHRpbWVvdXQ6IHsgcmVxdWVzdDogY29uZmlnLnRpbWVvdXRNcyB9LFxuICAgICAgICB0aHJvd0h0dHBFcnJvcnM6IGZhbHNlLFxuICAgICAgICBmb2xsb3dSZWRpcmVjdDogdHJ1ZSxcbiAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICBiZWZvcmVSZXF1ZXN0OiBbXG4gICAgICAgICAgICBhc3luYyAob3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICBhd2FpdCBhc3NlcnRGZXRjaFVybEFsbG93ZWQoU3RyaW5nKG9wdGlvbnMudXJsKSwgY29uZmlnLmFsbG93TGlzdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIC4uLihleGVjdXRlU2lnbmFsID8geyBzaWduYWw6IGV4ZWN1dGVTaWduYWwgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdXJsOiByZXNwb25zZS51cmwgPz8gcmVxdWVzdC51cmwsXG4gICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1c0NvZGUsXG4gICAgICAgIGNvbnRlbnRUeXBlOiByZXNwb25zZS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdLFxuICAgICAgICBib2R5OiB0eXBlb2YgcmVzcG9uc2UuYm9keSA9PT0gXCJzdHJpbmdcIiA/IHJlc3BvbnNlLmJvZHkgOiBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyBcIlwiKSxcbiAgICAgIH07XG4gICAgfSxcbiAgICBzaWduYWwsXG4gICk7XG4gIGF3YWl0IGFzc2VydEZldGNoVXJsQWxsb3dlZChwYWdlLnVybCwgY29uZmlnLmFsbG93TGlzdCk7XG5cbiAgY29uc3QgaXNIdG1sID0gIXBhZ2UuY29udGVudFR5cGUgfHwgL2h0bWx8eG1sL2kudGVzdChwYWdlLmNvbnRlbnRUeXBlKTtcbiAgY29uc3QgcmF3Q29udGVudCA9IHJlcXVlc3QuZm9ybWF0ID09PSBcImh0bWxcIiB8fCAhaXNIdG1sID8gcGFnZS5ib2R5IDogaHRtbFRvVGV4dChwYWdlLmJvZHkpO1xuICBjb25zdCB7IGNvbnRlbnQsIHRydW5jYXRlZCB9ID0gdHJ1bmNhdGUocmF3Q29udGVudCwgY2FwKTtcbiAgY29uc3QgdGl0bGUgPSBpc0h0bWwgPyBleHRyYWN0VGl0bGUocGFnZS5ib2R5KSA6IHVuZGVmaW5lZDtcblxuICBsb2dnZXIuZGVidWcoXCJmZXRjaGVkXCIsIHtcbiAgICB1cmw6IHBhZ2UudXJsLFxuICAgIHN0YXR1czogcGFnZS5zdGF0dXNDb2RlLFxuICAgIGJ5dGVzOiBwYWdlLmJvZHkubGVuZ3RoLFxuICAgIHJldHVybmVkOiBjb250ZW50Lmxlbmd0aCxcbiAgICAuLi4odHJ1bmNhdGVkID8geyB0cnVuY2F0ZWQ6IHRydWUgfSA6IHt9KSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICB1cmw6IHBhZ2UudXJsLFxuICAgIHN0YXR1czogcGFnZS5zdGF0dXNDb2RlLFxuICAgIC4uLihwYWdlLmNvbnRlbnRUeXBlID8geyBjb250ZW50VHlwZTogcGFnZS5jb250ZW50VHlwZSB9IDoge30pLFxuICAgIC4uLih0aXRsZSA/IHsgdGl0bGUgfSA6IHt9KSxcbiAgICBjb250ZW50LFxuICAgIHRydW5jYXRlZCxcbiAgfTtcbn1cbiJdfQ==
@@ -2,17 +2,13 @@
2
2
  * Turning fetched HTML into the plain text a model can read.
3
3
  *
4
4
  * Both scraping paths need this: `runWebFetch`'s full-page read and
5
- * `runScrapeSearch`'s title/snippet extraction. The entity table is shared so
6
- * the two cannot drift apart.
7
- *
8
- * This is deliberately regex-based rather than a DOM parse. The inputs are
9
- * whole pages fetched for summarization, not documents to be queried, so the
10
- * cost of a real parser buys nothing - and a malformed page still degrades to
11
- * readable text instead of throwing.
5
+ * `runScrapeSearch`'s title/snippet extraction. Parser-backed conversion keeps
6
+ * malformed markup, quoted `>` characters, and the complete HTML entity table
7
+ * consistent across both paths.
12
8
  *
13
9
  * @module
14
10
  */
15
- /** Decode the HTML entities that survive tag-stripping. */
11
+ /** Decode named, decimal, and hexadecimal HTML entities without throwing. */
16
12
  export declare function decodeHtmlEntities(text: string): string;
17
13
  /**
18
14
  * Strip tags and decode entities from a short HTML fragment, collapsing all
@@ -2,39 +2,35 @@
2
2
  * Turning fetched HTML into the plain text a model can read.
3
3
  *
4
4
  * Both scraping paths need this: `runWebFetch`'s full-page read and
5
- * `runScrapeSearch`'s title/snippet extraction. The entity table is shared so
6
- * the two cannot drift apart.
7
- *
8
- * This is deliberately regex-based rather than a DOM parse. The inputs are
9
- * whole pages fetched for summarization, not documents to be queried, so the
10
- * cost of a real parser buys nothing - and a malformed page still degrades to
11
- * readable text instead of throwing.
5
+ * `runScrapeSearch`'s title/snippet extraction. Parser-backed conversion keeps
6
+ * malformed markup, quoted `>` characters, and the complete HTML entity table
7
+ * consistent across both paths.
12
8
  *
13
9
  * @module
14
10
  */
15
- /**
16
- * The named entities that survive tag-stripping in practice, plus numeric
17
- * escapes. Not a complete HTML entity table - anything rarer passes through
18
- * as-is, which reads acceptably in model input.
19
- */
20
- const NAMED_ENTITIES = {
21
- "&nbsp;": " ",
22
- "&amp;": "&",
23
- "&lt;": "<",
24
- "&gt;": ">",
25
- "&quot;": '"',
26
- "&#39;": "'",
27
- "&#x27;": "'",
28
- "&apos;": "'",
11
+ import { decodeHTML } from "entities";
12
+ import { compile } from "html-to-text";
13
+ const SHARED_OPTIONS = {
14
+ wordwrap: false,
15
+ selectors: [
16
+ { selector: "script", format: "skip" },
17
+ { selector: "style", format: "skip" },
18
+ { selector: "noscript", format: "skip" },
19
+ { selector: "a", options: { ignoreHref: true } },
20
+ { selector: "img", format: "skip" },
21
+ ],
29
22
  };
30
- const NAMED_ENTITY_REGEXP = new RegExp(Object.keys(NAMED_ENTITIES).join("|"), "g");
31
- const NUMERIC_ENTITY_REGEXP = /&#(\d+);/g;
32
- const TAG_REGEXP = /<[^>]+>/g;
33
- /** Decode the HTML entities that survive tag-stripping. */
23
+ const fragmentToText = compile({
24
+ ...SHARED_OPTIONS,
25
+ preserveNewlines: false,
26
+ });
27
+ const documentToText = compile({
28
+ ...SHARED_OPTIONS,
29
+ preserveNewlines: true,
30
+ });
31
+ /** Decode named, decimal, and hexadecimal HTML entities without throwing. */
34
32
  export function decodeHtmlEntities(text) {
35
- return text
36
- .replace(NAMED_ENTITY_REGEXP, (entity) => NAMED_ENTITIES[entity] ?? entity)
37
- .replace(NUMERIC_ENTITY_REGEXP, (_, code) => String.fromCodePoint(Number(code)));
33
+ return decodeHTML(text);
38
34
  }
39
35
  /**
40
36
  * Strip tags and decode entities from a short HTML fragment, collapsing all
@@ -42,7 +38,7 @@ export function decodeHtmlEntities(text) {
42
38
  * summary), where layout carries no meaning.
43
39
  */
44
40
  export function htmlFragmentToText(html) {
45
- return decodeHtmlEntities(html.replace(TAG_REGEXP, "")).replace(/\s+/g, " ").trim();
41
+ return fragmentToText(html).replace(/\s+/g, " ").trim();
46
42
  }
47
43
  /**
48
44
  * Reduce a full HTML document to readable plain text: drop `<script>` /
@@ -52,15 +48,10 @@ export function htmlFragmentToText(html) {
52
48
  * preserves line structure because paragraph breaks carry meaning in a page.
53
49
  */
54
50
  export function htmlToText(html) {
55
- return decodeHtmlEntities(html
56
- .replace(/<!--[\s\S]*?-->/g, "")
57
- .replace(/<(script|style|noscript)[^>]*>[\s\S]*?<\/\1>/gi, "")
58
- .replace(/<\/(p|div|section|article|li|tr|h[1-6]|header|footer|br)>/gi, "\n")
59
- .replace(/<br\s*\/?>/gi, "\n")
60
- .replace(TAG_REGEXP, ""))
51
+ return documentToText(html)
61
52
  .replace(/[ \t]+\n/g, "\n")
62
53
  .replace(/\n{3,}/g, "\n\n")
63
54
  .replace(/[ \t]{2,}/g, " ")
64
55
  .trim();
65
56
  }
66
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHRtbC10ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0bWwtdGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUg7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUEyQjtJQUM3QyxRQUFRLEVBQUUsR0FBRztJQUNiLE9BQU8sRUFBRSxHQUFHO0lBQ1osTUFBTSxFQUFFLEdBQUc7SUFDWCxNQUFNLEVBQUUsR0FBRztJQUNYLFFBQVEsRUFBRSxHQUFHO0lBQ2IsT0FBTyxFQUFFLEdBQUc7SUFDWixRQUFRLEVBQUUsR0FBRztJQUNiLFFBQVEsRUFBRSxHQUFHO0NBQ2QsQ0FBQztBQUVGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDbkYsTUFBTSxxQkFBcUIsR0FBRyxXQUFXLENBQUM7QUFDMUMsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDO0FBRTlCLDJEQUEyRDtBQUMzRCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsSUFBWTtJQUM3QyxPQUFPLElBQUk7U0FDUixPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUM7U0FDMUUsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JGLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLElBQVk7SUFDN0MsT0FBTyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDdEYsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsSUFBWTtJQUNyQyxPQUFPLGtCQUFrQixDQUN2QixJQUFJO1NBQ0QsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztTQUMvQixPQUFPLENBQUMsZ0RBQWdELEVBQUUsRUFBRSxDQUFDO1NBQzdELE9BQU8sQ0FBQyw2REFBNkQsRUFBRSxJQUFJLENBQUM7U0FDNUUsT0FBTyxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUM7U0FDN0IsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FDM0I7U0FDRSxPQUFPLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQztTQUMxQixPQUFPLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQztTQUMxQixPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQztTQUMxQixJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFR1cm5pbmcgZmV0Y2hlZCBIVE1MIGludG8gdGhlIHBsYWluIHRleHQgYSBtb2RlbCBjYW4gcmVhZC5cbiAqXG4gKiBCb3RoIHNjcmFwaW5nIHBhdGhzIG5lZWQgdGhpczogYHJ1bldlYkZldGNoYCdzIGZ1bGwtcGFnZSByZWFkIGFuZFxuICogYHJ1blNjcmFwZVNlYXJjaGAncyB0aXRsZS9zbmlwcGV0IGV4dHJhY3Rpb24uIFRoZSBlbnRpdHkgdGFibGUgaXMgc2hhcmVkIHNvXG4gKiB0aGUgdHdvIGNhbm5vdCBkcmlmdCBhcGFydC5cbiAqXG4gKiBUaGlzIGlzIGRlbGliZXJhdGVseSByZWdleC1iYXNlZCByYXRoZXIgdGhhbiBhIERPTSBwYXJzZS4gVGhlIGlucHV0cyBhcmVcbiAqIHdob2xlIHBhZ2VzIGZldGNoZWQgZm9yIHN1bW1hcml6YXRpb24sIG5vdCBkb2N1bWVudHMgdG8gYmUgcXVlcmllZCwgc28gdGhlXG4gKiBjb3N0IG9mIGEgcmVhbCBwYXJzZXIgYnV5cyBub3RoaW5nIC0gYW5kIGEgbWFsZm9ybWVkIHBhZ2Ugc3RpbGwgZGVncmFkZXMgdG9cbiAqIHJlYWRhYmxlIHRleHQgaW5zdGVhZCBvZiB0aHJvd2luZy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuLyoqXG4gKiBUaGUgbmFtZWQgZW50aXRpZXMgdGhhdCBzdXJ2aXZlIHRhZy1zdHJpcHBpbmcgaW4gcHJhY3RpY2UsIHBsdXMgbnVtZXJpY1xuICogZXNjYXBlcy4gTm90IGEgY29tcGxldGUgSFRNTCBlbnRpdHkgdGFibGUgLSBhbnl0aGluZyByYXJlciBwYXNzZXMgdGhyb3VnaFxuICogYXMtaXMsIHdoaWNoIHJlYWRzIGFjY2VwdGFibHkgaW4gbW9kZWwgaW5wdXQuXG4gKi9cbmNvbnN0IE5BTUVEX0VOVElUSUVTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBcIiZuYnNwO1wiOiBcIiBcIixcbiAgXCImYW1wO1wiOiBcIiZcIixcbiAgXCImbHQ7XCI6IFwiPFwiLFxuICBcIiZndDtcIjogXCI+XCIsXG4gIFwiJnF1b3Q7XCI6ICdcIicsXG4gIFwiJiMzOTtcIjogXCInXCIsXG4gIFwiJiN4Mjc7XCI6IFwiJ1wiLFxuICBcIiZhcG9zO1wiOiBcIidcIixcbn07XG5cbmNvbnN0IE5BTUVEX0VOVElUWV9SRUdFWFAgPSBuZXcgUmVnRXhwKE9iamVjdC5rZXlzKE5BTUVEX0VOVElUSUVTKS5qb2luKFwifFwiKSwgXCJnXCIpO1xuY29uc3QgTlVNRVJJQ19FTlRJVFlfUkVHRVhQID0gLyYjKFxcZCspOy9nO1xuY29uc3QgVEFHX1JFR0VYUCA9IC88W14+XSs+L2c7XG5cbi8qKiBEZWNvZGUgdGhlIEhUTUwgZW50aXRpZXMgdGhhdCBzdXJ2aXZlIHRhZy1zdHJpcHBpbmcuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlSHRtbEVudGl0aWVzKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoTkFNRURfRU5USVRZX1JFR0VYUCwgKGVudGl0eSkgPT4gTkFNRURfRU5USVRJRVNbZW50aXR5XSA/PyBlbnRpdHkpXG4gICAgLnJlcGxhY2UoTlVNRVJJQ19FTlRJVFlfUkVHRVhQLCAoXywgY29kZSkgPT4gU3RyaW5nLmZyb21Db2RlUG9pbnQoTnVtYmVyKGNvZGUpKSk7XG59XG5cbi8qKlxuICogU3RyaXAgdGFncyBhbmQgZGVjb2RlIGVudGl0aWVzIGZyb20gYSBzaG9ydCBIVE1MIGZyYWdtZW50LCBjb2xsYXBzaW5nIGFsbFxuICogd2hpdGVzcGFjZSB0byBzaW5nbGUgc3BhY2VzLiBGb3IgaW5saW5lIHNuaXBwZXRzIChhIHNlYXJjaCByZXN1bHQgdGl0bGUgb3JcbiAqIHN1bW1hcnkpLCB3aGVyZSBsYXlvdXQgY2FycmllcyBubyBtZWFuaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaHRtbEZyYWdtZW50VG9UZXh0KGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBkZWNvZGVIdG1sRW50aXRpZXMoaHRtbC5yZXBsYWNlKFRBR19SRUdFWFAsIFwiXCIpKS5yZXBsYWNlKC9cXHMrL2csIFwiIFwiKS50cmltKCk7XG59XG5cbi8qKlxuICogUmVkdWNlIGEgZnVsbCBIVE1MIGRvY3VtZW50IHRvIHJlYWRhYmxlIHBsYWluIHRleHQ6IGRyb3AgYDxzY3JpcHQ+YCAvXG4gKiBgPHN0eWxlPmAgLyBgPG5vc2NyaXB0PmAgYmxvY2tzIGFuZCBjb21tZW50cywgdHVybiBibG9jay1sZXZlbCB0YWdzIGludG9cbiAqIG5ld2xpbmVzLCBzdHJpcCB0aGUgcmVtYWluaW5nIHRhZ3MsIGRlY29kZSBlbnRpdGllcywgYW5kIGNvbGxhcHNlIHJ1bnMgb2ZcbiAqIGJsYW5rIGxpbmVzIC8gdHJhaWxpbmcgc3BhY2VzLiBVbmxpa2Uge0BsaW5rIGh0bWxGcmFnbWVudFRvVGV4dH0sIHRoaXNcbiAqIHByZXNlcnZlcyBsaW5lIHN0cnVjdHVyZSBiZWNhdXNlIHBhcmFncmFwaCBicmVha3MgY2FycnkgbWVhbmluZyBpbiBhIHBhZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBodG1sVG9UZXh0KGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBkZWNvZGVIdG1sRW50aXRpZXMoXG4gICAgaHRtbFxuICAgICAgLnJlcGxhY2UoLzwhLS1bXFxzXFxTXSo/LS0+L2csIFwiXCIpXG4gICAgICAucmVwbGFjZSgvPChzY3JpcHR8c3R5bGV8bm9zY3JpcHQpW14+XSo+W1xcc1xcU10qPzxcXC9cXDE+L2dpLCBcIlwiKVxuICAgICAgLnJlcGxhY2UoLzxcXC8ocHxkaXZ8c2VjdGlvbnxhcnRpY2xlfGxpfHRyfGhbMS02XXxoZWFkZXJ8Zm9vdGVyfGJyKT4vZ2ksIFwiXFxuXCIpXG4gICAgICAucmVwbGFjZSgvPGJyXFxzKlxcLz8+L2dpLCBcIlxcblwiKVxuICAgICAgLnJlcGxhY2UoVEFHX1JFR0VYUCwgXCJcIiksXG4gIClcbiAgICAucmVwbGFjZSgvWyBcXHRdK1xcbi9nLCBcIlxcblwiKVxuICAgIC5yZXBsYWNlKC9cXG57Myx9L2csIFwiXFxuXFxuXCIpXG4gICAgLnJlcGxhY2UoL1sgXFx0XXsyLH0vZywgXCIgXCIpXG4gICAgLnRyaW0oKTtcbn1cbiJdfQ==
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHRtbC10ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0bWwtdGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7O0dBU0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxPQUFPLEVBQTBCLE1BQU0sY0FBYyxDQUFDO0FBRS9ELE1BQU0sY0FBYyxHQUFzQjtJQUN4QyxRQUFRLEVBQUUsS0FBSztJQUNmLFNBQVMsRUFBRTtRQUNULEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO1FBQ3RDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO1FBQ3JDLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO1FBQ3hDLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDaEQsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7S0FDcEM7Q0FDRixDQUFDO0FBRUYsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDO0lBQzdCLEdBQUcsY0FBYztJQUNqQixnQkFBZ0IsRUFBRSxLQUFLO0NBQ3hCLENBQUMsQ0FBQztBQUVILE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQztJQUM3QixHQUFHLGNBQWM7SUFDakIsZ0JBQWdCLEVBQUUsSUFBSTtDQUN2QixDQUFDLENBQUM7QUFFSCw2RUFBNkU7QUFDN0UsTUFBTSxVQUFVLGtCQUFrQixDQUFDLElBQVk7SUFDN0MsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsSUFBWTtJQUM3QyxPQUFPLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQzFELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUFDLElBQVk7SUFDckMsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDO1NBQ3hCLE9BQU8sQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDO1NBQzFCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDO1NBQzFCLE9BQU8sQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDO1NBQzFCLElBQUksRUFBRSxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVHVybmluZyBmZXRjaGVkIEhUTUwgaW50byB0aGUgcGxhaW4gdGV4dCBhIG1vZGVsIGNhbiByZWFkLlxuICpcbiAqIEJvdGggc2NyYXBpbmcgcGF0aHMgbmVlZCB0aGlzOiBgcnVuV2ViRmV0Y2hgJ3MgZnVsbC1wYWdlIHJlYWQgYW5kXG4gKiBgcnVuU2NyYXBlU2VhcmNoYCdzIHRpdGxlL3NuaXBwZXQgZXh0cmFjdGlvbi4gUGFyc2VyLWJhY2tlZCBjb252ZXJzaW9uIGtlZXBzXG4gKiBtYWxmb3JtZWQgbWFya3VwLCBxdW90ZWQgYD5gIGNoYXJhY3RlcnMsIGFuZCB0aGUgY29tcGxldGUgSFRNTCBlbnRpdHkgdGFibGVcbiAqIGNvbnNpc3RlbnQgYWNyb3NzIGJvdGggcGF0aHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGRlY29kZUhUTUwgfSBmcm9tIFwiZW50aXRpZXNcIjtcbmltcG9ydCB7IGNvbXBpbGUsIHR5cGUgSHRtbFRvVGV4dE9wdGlvbnMgfSBmcm9tIFwiaHRtbC10by10ZXh0XCI7XG5cbmNvbnN0IFNIQVJFRF9PUFRJT05TOiBIdG1sVG9UZXh0T3B0aW9ucyA9IHtcbiAgd29yZHdyYXA6IGZhbHNlLFxuICBzZWxlY3RvcnM6IFtcbiAgICB7IHNlbGVjdG9yOiBcInNjcmlwdFwiLCBmb3JtYXQ6IFwic2tpcFwiIH0sXG4gICAgeyBzZWxlY3RvcjogXCJzdHlsZVwiLCBmb3JtYXQ6IFwic2tpcFwiIH0sXG4gICAgeyBzZWxlY3RvcjogXCJub3NjcmlwdFwiLCBmb3JtYXQ6IFwic2tpcFwiIH0sXG4gICAgeyBzZWxlY3RvcjogXCJhXCIsIG9wdGlvbnM6IHsgaWdub3JlSHJlZjogdHJ1ZSB9IH0sXG4gICAgeyBzZWxlY3RvcjogXCJpbWdcIiwgZm9ybWF0OiBcInNraXBcIiB9LFxuICBdLFxufTtcblxuY29uc3QgZnJhZ21lbnRUb1RleHQgPSBjb21waWxlKHtcbiAgLi4uU0hBUkVEX09QVElPTlMsXG4gIHByZXNlcnZlTmV3bGluZXM6IGZhbHNlLFxufSk7XG5cbmNvbnN0IGRvY3VtZW50VG9UZXh0ID0gY29tcGlsZSh7XG4gIC4uLlNIQVJFRF9PUFRJT05TLFxuICBwcmVzZXJ2ZU5ld2xpbmVzOiB0cnVlLFxufSk7XG5cbi8qKiBEZWNvZGUgbmFtZWQsIGRlY2ltYWwsIGFuZCBoZXhhZGVjaW1hbCBIVE1MIGVudGl0aWVzIHdpdGhvdXQgdGhyb3dpbmcuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlSHRtbEVudGl0aWVzKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBkZWNvZGVIVE1MKHRleHQpO1xufVxuXG4vKipcbiAqIFN0cmlwIHRhZ3MgYW5kIGRlY29kZSBlbnRpdGllcyBmcm9tIGEgc2hvcnQgSFRNTCBmcmFnbWVudCwgY29sbGFwc2luZyBhbGxcbiAqIHdoaXRlc3BhY2UgdG8gc2luZ2xlIHNwYWNlcy4gRm9yIGlubGluZSBzbmlwcGV0cyAoYSBzZWFyY2ggcmVzdWx0IHRpdGxlIG9yXG4gKiBzdW1tYXJ5KSwgd2hlcmUgbGF5b3V0IGNhcnJpZXMgbm8gbWVhbmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGh0bWxGcmFnbWVudFRvVGV4dChodG1sOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZnJhZ21lbnRUb1RleHQoaHRtbCkucmVwbGFjZSgvXFxzKy9nLCBcIiBcIikudHJpbSgpO1xufVxuXG4vKipcbiAqIFJlZHVjZSBhIGZ1bGwgSFRNTCBkb2N1bWVudCB0byByZWFkYWJsZSBwbGFpbiB0ZXh0OiBkcm9wIGA8c2NyaXB0PmAgL1xuICogYDxzdHlsZT5gIC8gYDxub3NjcmlwdD5gIGJsb2NrcyBhbmQgY29tbWVudHMsIHR1cm4gYmxvY2stbGV2ZWwgdGFncyBpbnRvXG4gKiBuZXdsaW5lcywgc3RyaXAgdGhlIHJlbWFpbmluZyB0YWdzLCBkZWNvZGUgZW50aXRpZXMsIGFuZCBjb2xsYXBzZSBydW5zIG9mXG4gKiBibGFuayBsaW5lcyAvIHRyYWlsaW5nIHNwYWNlcy4gVW5saWtlIHtAbGluayBodG1sRnJhZ21lbnRUb1RleHR9LCB0aGlzXG4gKiBwcmVzZXJ2ZXMgbGluZSBzdHJ1Y3R1cmUgYmVjYXVzZSBwYXJhZ3JhcGggYnJlYWtzIGNhcnJ5IG1lYW5pbmcgaW4gYSBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaHRtbFRvVGV4dChodG1sOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZG9jdW1lbnRUb1RleHQoaHRtbClcbiAgICAucmVwbGFjZSgvWyBcXHRdK1xcbi9nLCBcIlxcblwiKVxuICAgIC5yZXBsYWNlKC9cXG57Myx9L2csIFwiXFxuXFxuXCIpXG4gICAgLnJlcGxhY2UoL1sgXFx0XXsyLH0vZywgXCIgXCIpXG4gICAgLnRyaW0oKTtcbn1cbiJdfQ==
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * AppKit plugin (registered name: `web-search`) that owns the resolved
3
3
  * web-search runtime - the URL policy, result / length caps, timeout, and
4
- * default approval gate the {@link webSearchTool} / {@link webFetchTool}
5
- * read. Registering it resolves and logs the effective config (which URL
6
- * policy is in force, the caps) so a misconfiguration is visible in the boot
7
- * logs rather than on the first search, and installs the plugin's
8
- * `execute()` as the runtime's executor so every outbound call picks up
9
- * AppKit's cache / retry / timeout / telemetry chain.
4
+ * default approval gate its tools read. Registering it resolves and logs the
5
+ * effective config (which URL policy is in force, the caps) so a
6
+ * misconfiguration is visible in the boot logs rather than on the first
7
+ * search. The plugin's `execute()` is captured by its own runtime so every
8
+ * outbound call picks up AppKit's cache / retry / timeout / telemetry chain.
10
9
  *
11
10
  * The plugin also implements AppKit's `ToolProvider`, so an AppKit agent gets
12
- * `web_search` / `web_fetch` without going through Mastra; the Mastra tools in
13
- * `tool.ts` are the other half and share the same runtime.
11
+ * `web_search` / `web_fetch` without going through Mastra. App-integrated
12
+ * Mastra agents consume this provider through `plugins["web-search"].toolkit()`;
13
+ * standalone factories in `tool.ts` use their own explicit runtime or config.
14
14
  *
15
15
  * @module
16
16
  */
@@ -70,6 +70,8 @@ export declare class WebSearchPlugin extends Plugin<WebSearchPluginConfig> imple
70
70
  schema: import("json-schema").JSONSchema7;
71
71
  };
72
72
  };
73
+ /** Runtime owned exclusively by this plugin instance. */
74
+ private readonly runtime;
73
75
  /**
74
76
  * Promote the serving endpoint to a required resource once a deployment
75
77
  * pins one, through plugin config or either environment name. Left optional
@@ -93,24 +95,17 @@ export declare class WebSearchPlugin extends Plugin<WebSearchPluginConfig> imple
93
95
  */
94
96
  private readonly tools;
95
97
  /**
96
- * Prime the shared runtime from this plugin's config (over env), route the
97
- * tools' outbound calls through this plugin's interceptor chain, and log the
98
- * effective policy so an active allow-list / caps are obvious at boot.
98
+ * Log the effective policy so an active allow-list and caps are obvious at
99
+ * boot. Runtime construction already resolved config and captured this
100
+ * plugin's interceptor chain.
99
101
  */
100
102
  setup(): Promise<void>;
101
103
  /**
102
- * Drop the shared runtime so a restarted app re-resolves config and does not
103
- * keep calling through a torn-down plugin's `execute()`. Bounded and
104
- * idempotent: there is no connection to drain, only the memo to clear.
105
- */
106
- shutdown(): Promise<void>;
107
- /**
108
- * Abort in-flight work. AppKit's graceful shutdown only invokes this hook -
109
- * it never calls {@link shutdown} - so the runtime memo is dropped from here
110
- * to keep a restarted app from calling through a torn-down `execute()`. The
111
- * teardown is synchronous and idempotent, so the un-awaited call costs
112
- * nothing.
104
+ * No runtime resources require draining. The instance-owned config and
105
+ * executor become unreachable with this plugin.
113
106
  */
107
+ shutdown(): void;
108
+ /** Abort in-flight work owned by this plugin instance. */
114
109
  abortActiveOperations(): void;
115
110
  /** AppKit `ToolProvider`: the tool definitions offered to an agent. */
116
111
  getAgentTools(): AgentToolDefinition[];
@@ -123,13 +118,13 @@ export declare class WebSearchPlugin extends Plugin<WebSearchPluginConfig> imple
123
118
  exports(): {
124
119
  /**
125
120
  * Run a web search directly (bypassing the agent tool). Resolves the
126
- * OBO client from the active execution context and reads the shared
127
- * runtime config primed at setup.
121
+ * OBO client from the active execution context and reads this plugin's
122
+ * runtime config.
128
123
  */
129
124
  search: (request: WebSearchRequest, signal?: AbortSignal) => Promise<WebSearchResult>;
130
125
  /**
131
126
  * Fetch one URL directly (bypassing the agent tool). Enforces the
132
- * configured URL policy. Reads the shared runtime config.
127
+ * configured URL policy.
133
128
  */
134
129
  fetch: (request: WebFetchRequest, signal?: AbortSignal) => Promise<WebFetchResult>;
135
130
  };
@@ -142,12 +137,14 @@ export declare class WebSearchPlugin extends Plugin<WebSearchPluginConfig> imple
142
137
  * @example
143
138
  * ```ts
144
139
  * import { createApp, server } from "@databricks/appkit";
145
- * import { plugin as webSearchPlugin, tool as webTool } from "@dbx-tools/appkit-web-search";
140
+ * import { plugin as webSearchPlugin } from "@dbx-tools/appkit-web-search";
146
141
  * import { agents, plugin as mastraPlugin } from "@dbx-tools/appkit-mastra";
147
142
  *
148
143
  * const researcher = agents.createAgent({
149
144
  * instructions: "Research questions with web_search, then read sources with web_fetch.",
150
- * tools: () => ({ web_search: webTool.webSearchTool(), web_fetch: webTool.webFetchTool() }),
145
+ * async tools(plugins) {
146
+ * return { ...(await plugins["web-search"].toolkit()) };
147
+ * },
151
148
  * });
152
149
  *
153
150
  * await createApp({