@dbx-tools/appkit-web-search 0.9.69 → 0.9.71
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 +30 -33
- package/index.ts +5 -5
- package/lib/index.d.ts +5 -5
- package/lib/index.js +4 -4
- package/lib/src/config.d.ts +10 -15
- package/lib/src/config.js +8 -15
- package/lib/src/fetch.js +4 -1
- package/lib/src/plugin.d.ts +3 -0
- package/lib/src/plugin.js +16 -6
- package/lib/src/provider.d.ts +18 -20
- package/lib/src/provider.js +38 -29
- package/lib/src/runtime.d.ts +3 -0
- package/lib/src/runtime.js +3 -3
- package/lib/src/schema.d.ts +6 -0
- package/lib/src/schema.js +8 -7
- package/lib/src/search.d.ts +10 -2
- package/lib/src/search.js +216 -66
- package/lib/src/tool.d.ts +0 -1
- package/lib/src/tool.js +4 -4
- package/package.json +7 -7
- package/src/config.ts +13 -23
- package/src/fetch.ts +3 -0
- package/src/plugin.ts +35 -5
- package/src/provider.ts +44 -36
- package/src/runtime.ts +5 -2
- package/src/schema.ts +11 -6
- package/src/search.ts +252 -68
- package/src/tool.ts +3 -3
package/lib/src/tool.js
CHANGED
|
@@ -26,7 +26,7 @@ import { createTool } from "@mastra/core/tools";
|
|
|
26
26
|
import { approvalMatches, toApprovalPolicy, } from "./config.js";
|
|
27
27
|
import { runWebFetch } from "./fetch.js";
|
|
28
28
|
import { createWebSearchRuntime } from "./runtime.js";
|
|
29
|
-
import { webFetchRequestSchema, webFetchResultSchema,
|
|
29
|
+
import { webFetchRequestSchema, webFetchResultSchema, webSearchToolRequestSchema, webSearchResultSchema, WEB_FETCH_TOOL_DESCRIPTION, WEB_SEARCH_TOOL_DESCRIPTION, } from "./schema.js";
|
|
30
30
|
import { resolveWebSearchContext, runWebSearch } from "./search.js";
|
|
31
31
|
/**
|
|
32
32
|
* Validate a tool call's arguments at the runtime boundary. Mastra checks the
|
|
@@ -73,13 +73,13 @@ export function webSearchTool(opts = {}) {
|
|
|
73
73
|
return createTool({
|
|
74
74
|
id: opts.id ?? "web_search",
|
|
75
75
|
description: WEB_SEARCH_TOOL_DESCRIPTION,
|
|
76
|
-
inputSchema:
|
|
76
|
+
inputSchema: webSearchToolRequestSchema,
|
|
77
77
|
outputSchema: webSearchResultSchema,
|
|
78
78
|
// A search's result URLs aren't known before the call, so a pattern gate
|
|
79
79
|
// is treated as "always gate".
|
|
80
80
|
...(gate.mode === "none" ? {} : { requireApproval: () => true }),
|
|
81
81
|
execute: async (input) => {
|
|
82
|
-
const request = parseToolInput(
|
|
82
|
+
const request = parseToolInput(webSearchToolRequestSchema, input);
|
|
83
83
|
return runWebSearch(request, runtime, await resolveWebSearchContext());
|
|
84
84
|
},
|
|
85
85
|
});
|
|
@@ -116,4 +116,4 @@ export function webFetchTool(opts = {}) {
|
|
|
116
116
|
},
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVoRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLGdCQUFnQixHQUlqQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxzQkFBc0IsRUFBeUIsTUFBTSxjQUFjLENBQUM7QUFDN0UsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixvQkFBb0IsRUFDcEIsc0JBQXNCLEVBQ3RCLHFCQUFxQixFQUNyQiwwQkFBMEIsRUFDMUIsMkJBQTJCLEdBQzVCLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFcEU7Ozs7O0dBS0c7QUFDSCxTQUFTLGNBQWMsQ0FBc0IsTUFBUyxFQUFFLEtBQWM7SUFDcEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLE1BQU0sZUFBZSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLHNDQUFzQyxDQUFDLENBQUM7SUFDN0YsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQztBQUNyQixDQUFDO0FBa0JELDRFQUE0RTtBQUM1RSxTQUFTLFdBQVcsQ0FBQyxJQUEwQjtJQUM3QyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hDLE1BQU0sSUFBSSxTQUFTLENBQUMsbUVBQW1FLENBQUMsQ0FBQztJQUMzRixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxJQUFJLHNCQUFzQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQsa0ZBQWtGO0FBQ2xGLFNBQVMsYUFBYSxDQUFDLElBQTBCLEVBQUUsT0FBeUI7SUFDMUUsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNqRyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE9BQTZCLEVBQUU7SUFDM0QsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsT0FBTyxVQUFVLENBQUM7UUFDaEIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksWUFBWTtRQUMzQixXQUFXLEVBQUUsMkJBQTJCO1FBQ3hDLFdBQVcsRUFBRSxzQkFBc0I7UUFDbkMsWUFBWSxFQUFFLHFCQUFxQjtRQUNuQyx5RUFBeUU7UUFDekUsK0JBQStCO1FBQy9CLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxzQkFBc0IsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM5RCxPQUFPLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sdUJBQXVCLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsT0FBNkIsRUFBRTtJQUMxRCxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxQyxPQUFPLFVBQVUsQ0FBQztRQUNoQixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxXQUFXO1FBQzFCLFdBQVcsRUFBRSwwQkFBMEI7UUFDdkMsV0FBVyxFQUFFLHFCQUFxQjtRQUNsQyxZQUFZLEVBQUUsb0JBQW9CO1FBQ2xDLHNFQUFzRTtRQUN0RSx3QkFBd0I7UUFDeEIsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTTtZQUN0QixDQUFDLENBQUMsRUFBRTtZQUNKLENBQUMsQ0FBQztnQkFDRSxlQUFlLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUNsQyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVE7b0JBQ3RCLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxjQUFjLENBQUMscUJBQXFCLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDNUUsQ0FBQztRQUNOLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDdkIsT0FBTyxXQUFXLENBQUMsY0FBYyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVFLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgYHdlYl9zZWFyY2hgIGFuZCBgd2ViX2ZldGNoYCBNYXN0cmEgdG9vbHMuXG4gKlxuICogYHdlYl9zZWFyY2hgIGlzIGJhY2tlZCBieSB0aGUgRGF0YWJyaWNrcyBNb2RlbCBTZXJ2aW5nIG5hdGl2ZSB3ZWItc2VhcmNoXG4gKiB0b29sOiBpdCByZXNvbHZlcyBpdHMgb3duIHdlYi1zZWFyY2gtY2FwYWJsZSBtb2RlbCAoc2VlIGBzZWFyY2gudHNgKSBhbmRcbiAqIGNhbGxzIHRoZSB3b3Jrc3BhY2Ugc2VydmluZyBlbmRwb2ludCB1bmRlciB0aGUgY2FsbGVyJ3MgT0JPIHNjb3BlLCBzbyB0aGVcbiAqIHNlYXJjaCBydW5zIGFzIHRoZSByZXF1ZXN0aW5nIHVzZXIgYW5kIGluZGVwZW5kZW50bHkgb2YgdGhlIGFnZW50J3MgY2hhdFxuICogbW9kZWwuIGB3ZWJfZmV0Y2hgIHJlYWRzIGEgcGFnZSB2aWEgZ290LXNjcmFwaW5nLlxuICpcbiAqIEJvdGggYXJlIHJlYWQtb25seSBhbmQgcnVuIHdpdGhvdXQgYXBwcm92YWwgYnkgZGVmYXVsdDsgZWFjaCBhY2NlcHRzIGFuXG4gKiBvcHRpb25hbCB7QGxpbmsgQXBwcm92YWxHYXRlfSAoYGFwcHJvdmFsYCkgdGhhdCBtYXBzIG9udG8gTWFzdHJhJ3NcbiAqIGByZXF1aXJlQXBwcm92YWxgLiBgdHJ1ZWAgZ2F0ZXMgZXZlcnkgY2FsbDsgYSBVUkwtcGF0dGVybiAob3Ige0BsaW5rIE9uZU9yTWFueX1cbiAqIGxpc3QpIGdhdGVzIG9ubHkgY2FsbHMgd2hvc2UgVVJMIG1hdGNoZXMgLSBmb3IgYHdlYl9mZXRjaGAgdGhhdCBpcyBldmFsdWF0ZWRcbiAqIGFnYWluc3QgdGhlIHRhcmdldCBVUkwsIHdoaWxlIGB3ZWJfc2VhcmNoYCAod2hvc2UgcmVzdWx0IFVSTHMgYXJlbid0IGtub3duXG4gKiBiZWZvcmUgdGhlIGNhbGwpIHRyZWF0cyBhIHBhdHRlcm4gZ2F0ZSBhcyBcImFsd2F5cyBnYXRlXCIuIGBhcHByb3ZhbGAgZmFsbHNcbiAqIGJhY2sgdG8gdGhlIHN0YW5kYWxvbmUgcnVudGltZSdzIGBhcHByb3ZhbGAgY29uZmlnIHdoZW4gYSB0b29sIG9taXRzIGl0cyBvd24uXG4gKlxuICogQXBwLWludGVncmF0ZWQgYWdlbnRzIHNob3VsZCBjb25zdW1lIHRoZSBwbHVnaW4ncyBuYXRpdmUgdG9vbGtpdCBzbyBjYWxsc1xuICogcmV0YWluIHRoYXQgcGx1Z2luJ3MgcG9saWN5IGFuZCBleGVjdXRvci4gVGhlc2UgZmFjdG9yaWVzIGFyZSB0aGUgc3RhbmRhbG9uZVxuICogTWFzdHJhIHN1cmZhY2UgYW5kIGNhcHR1cmUgYW4gZXhwbGljaXQgcnVudGltZSBvciBpc29sYXRlZCBjb25maWcuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGNyZWF0ZVRvb2wgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3Rvb2xzXCI7XG5pbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQge1xuICBhcHByb3ZhbE1hdGNoZXMsXG4gIHRvQXBwcm92YWxQb2xpY3ksXG4gIHR5cGUgQXBwcm92YWxHYXRlLFxuICB0eXBlIEFwcHJvdmFsUG9saWN5LFxuICB0eXBlIFdlYlNlYXJjaFBsdWdpbkNvbmZpZyxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBydW5XZWJGZXRjaCB9IGZyb20gXCIuL2ZldGNoLnRzXCI7XG5pbXBvcnQgeyBjcmVhdGVXZWJTZWFyY2hSdW50aW1lLCB0eXBlIFdlYlNlYXJjaFJ1bnRpbWUgfSBmcm9tIFwiLi9ydW50aW1lLnRzXCI7XG5pbXBvcnQge1xuICB3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsXG4gIHdlYkZldGNoUmVzdWx0U2NoZW1hLFxuICB3ZWJTZWFyY2hSZXF1ZXN0U2NoZW1hLFxuICB3ZWJTZWFyY2hSZXN1bHRTY2hlbWEsXG4gIFdFQl9GRVRDSF9UT09MX0RFU0NSSVBUSU9OLFxuICBXRUJfU0VBUkNIX1RPT0xfREVTQ1JJUFRJT04sXG59IGZyb20gXCIuL3NjaGVtYS50c1wiO1xuaW1wb3J0IHsgcmVzb2x2ZVdlYlNlYXJjaENvbnRleHQsIHJ1bldlYlNlYXJjaCB9IGZyb20gXCIuL3NlYXJjaC50c1wiO1xuXG4vKipcbiAqIFZhbGlkYXRlIGEgdG9vbCBjYWxsJ3MgYXJndW1lbnRzIGF0IHRoZSBydW50aW1lIGJvdW5kYXJ5LiBNYXN0cmEgY2hlY2tzIHRoZVxuICogaW5wdXQgc2NoZW1hIGJlZm9yZSBkaXNwYXRjaCwgYnV0IHRoZSBhcmd1bWVudCBzdGlsbCBhcnJpdmVzIHR5cGVkIGFzXG4gKiBgdW5rbm93bmAgYW5kIHRoZSBtb2RlbCBpcyB0aGUgb25lIGZpbGxpbmcgaXQgaW4uIFRoZSByZWplY3RlZCB2YWx1ZSBpcyBub3RcbiAqIGVjaG9lZCBiYWNrLlxuICovXG5mdW5jdGlvbiBwYXJzZVRvb2xJbnB1dDxTIGV4dGVuZHMgei5ab2RUeXBlPihzY2hlbWE6IFMsIGlucHV0OiB1bmtub3duKTogei5pbmZlcjxTPiB7XG4gIGNvbnN0IHBhcnNlZCA9IHNjaGVtYS5zYWZlUGFyc2UoaW5wdXQpO1xuICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLmludmFsaWRWYWx1ZShcImlucHV0XCIsIGlucHV0LCBcImFyZ3VtZW50cyBtYXRjaGluZyB0aGUgdG9vbCdzIHNjaGVtYVwiKTtcbiAgfVxuICByZXR1cm4gcGFyc2VkLmRhdGE7XG59XG5cbi8qKiBPcHRpb25zIHNoYXJlZCBieSBib3RoIHdlYiB0b29scy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2ViU2VhcmNoVG9vbE9wdGlvbnMge1xuICAvKiogT3ZlcnJpZGUgdGhlIHRvb2wgaWQuICovXG4gIGlkPzogc3RyaW5nO1xuICAvKiogSXNvbGF0ZWQgcnVudGltZSB1c2VkIGJ5IHRoaXMgc3RhbmRhbG9uZSB0b29sLiBNdXR1YWxseSBleGNsdXNpdmUgd2l0aCBgY29uZmlnYC4gKi9cbiAgcnVudGltZT86IFdlYlNlYXJjaFJ1bnRpbWU7XG4gIC8qKiBDb25maWcgdXNlZCB0byBjcmVhdGUgYW4gaXNvbGF0ZWQgZGlyZWN0LWV4ZWN1dGlvbiBydW50aW1lLiAqL1xuICBjb25maWc/OiBXZWJTZWFyY2hQbHVnaW5Db25maWc7XG4gIC8qKlxuICAgKiBBcHByb3ZhbCBnYXRlIGZvciB0aGlzIHRvb2wsIG92ZXJyaWRpbmcgdGhlIHJ1bnRpbWUncyBgYXBwcm92YWxgLiBgdHJ1ZWBcbiAgICogZ2F0ZXMgZXZlcnkgY2FsbDsgYSBVUkwtcGF0dGVybiAob3IgbGlzdCkgZ2F0ZXMgb25seSBtYXRjaGluZyBjYWxscztcbiAgICogb21pdCAvIGBmYWxzZWAgZm9yIG5vIGFwcHJvdmFsLiBTZWUge0BsaW5rIEFwcHJvdmFsR2F0ZX0uXG4gICAqL1xuICBhcHByb3ZhbD86IEFwcHJvdmFsR2F0ZSB8IEFwcHJvdmFsUG9saWN5O1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgaXNvbGF0ZWQgcnVudGltZSBjYXB0dXJlZCBieSBvbmUgc3RhbmRhbG9uZSB0b29sIGZhY3RvcnkuICovXG5mdW5jdGlvbiB0b29sUnVudGltZShvcHRzOiBXZWJTZWFyY2hUb29sT3B0aW9ucyk6IFdlYlNlYXJjaFJ1bnRpbWUge1xuICBpZiAob3B0cy5ydW50aW1lICYmIG9wdHMuY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIndlYi1zZWFyY2ggdG9vbCBvcHRpb25zIGFjY2VwdCBlaXRoZXIgcnVudGltZSBvciBjb25maWcsIG5vdCBib3RoXCIpO1xuICB9XG4gIHJldHVybiBvcHRzLnJ1bnRpbWUgPz8gY3JlYXRlV2ViU2VhcmNoUnVudGltZShvcHRzLmNvbmZpZyk7XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBlZmZlY3RpdmUgZ2F0ZTogZXhwbGljaXQgdG9vbCBvcHRpb24sIGVsc2UgdGhlIHJ1bnRpbWUgZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIGVmZmVjdGl2ZUdhdGUob3B0czogV2ViU2VhcmNoVG9vbE9wdGlvbnMsIHJ1bnRpbWU6IFdlYlNlYXJjaFJ1bnRpbWUpOiBBcHByb3ZhbFBvbGljeSB7XG4gIHJldHVybiBvcHRzLmFwcHJvdmFsID09PSB1bmRlZmluZWQgPyBydW50aW1lLmNvbmZpZy5hcHByb3ZhbCA6IHRvQXBwcm92YWxQb2xpY3kob3B0cy5hcHByb3ZhbCk7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGB3ZWJfc2VhcmNoYCB0b29sLiBTcHJlYWQgaXQgaW50byB0aGUgYWdlbnRzIHRoYXQgc2hvdWxkIGJlIGFibGVcbiAqIHRvIHNlYXJjaCB0aGUgd2ViLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgd2ViU2VhcmNoVG9vbCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC13ZWItc2VhcmNoXCI7XG4gKiBpbXBvcnQgeyBjcmVhdGVBZ2VudCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC1tYXN0cmFcIjtcbiAqXG4gKiBjb25zdCByZXNlYXJjaGVyID0gY3JlYXRlQWdlbnQoe1xuICogICBpbnN0cnVjdGlvbnM6IFwiLi4uXCIsXG4gKiAgIHRvb2xzOiAoKSA9PiAoeyB3ZWJfc2VhcmNoOiB3ZWJTZWFyY2hUb29sKCkgfSksXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gd2ViU2VhcmNoVG9vbChvcHRzOiBXZWJTZWFyY2hUb29sT3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHJ1bnRpbWUgPSB0b29sUnVudGltZShvcHRzKTtcbiAgY29uc3QgZ2F0ZSA9IGVmZmVjdGl2ZUdhdGUob3B0cywgcnVudGltZSk7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0cy5pZCA/PyBcIndlYl9zZWFyY2hcIixcbiAgICBkZXNjcmlwdGlvbjogV0VCX1NFQVJDSF9UT09MX0RFU0NSSVBUSU9OLFxuICAgIGlucHV0U2NoZW1hOiB3ZWJTZWFyY2hSZXF1ZXN0U2NoZW1hLFxuICAgIG91dHB1dFNjaGVtYTogd2ViU2VhcmNoUmVzdWx0U2NoZW1hLFxuICAgIC8vIEEgc2VhcmNoJ3MgcmVzdWx0IFVSTHMgYXJlbid0IGtub3duIGJlZm9yZSB0aGUgY2FsbCwgc28gYSBwYXR0ZXJuIGdhdGVcbiAgICAvLyBpcyB0cmVhdGVkIGFzIFwiYWx3YXlzIGdhdGVcIi5cbiAgICAuLi4oZ2F0ZS5tb2RlID09PSBcIm5vbmVcIiA/IHt9IDogeyByZXF1aXJlQXBwcm92YWw6ICgpID0+IHRydWUgfSksXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gcGFyc2VUb29sSW5wdXQod2ViU2VhcmNoUmVxdWVzdFNjaGVtYSwgaW5wdXQpO1xuICAgICAgcmV0dXJuIHJ1bldlYlNlYXJjaChyZXF1ZXN0LCBydW50aW1lLCBhd2FpdCByZXNvbHZlV2ViU2VhcmNoQ29udGV4dCgpKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgYHdlYl9mZXRjaGAgdG9vbC4gU3ByZWFkIGl0IGludG8gdGhlIGFnZW50cyB0aGF0IHNob3VsZCBiZSBhYmxlXG4gKiB0byByZWFkIGEgcGFnZSdzIGNvbnRlbnRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgd2ViRmV0Y2hUb29sIH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0LXdlYi1zZWFyY2hcIjtcbiAqXG4gKiB0b29sczogKCkgPT4gKHsgd2ViX2ZldGNoOiB3ZWJGZXRjaFRvb2woeyBhcHByb3ZhbDogXCIqLmludGVybmFsLmV4YW1wbGUuY29tXCIgfSkgfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gd2ViRmV0Y2hUb29sKG9wdHM6IFdlYlNlYXJjaFRvb2xPcHRpb25zID0ge30pIHtcbiAgY29uc3QgcnVudGltZSA9IHRvb2xSdW50aW1lKG9wdHMpO1xuICBjb25zdCBnYXRlID0gZWZmZWN0aXZlR2F0ZShvcHRzLCBydW50aW1lKTtcbiAgcmV0dXJuIGNyZWF0ZVRvb2woe1xuICAgIGlkOiBvcHRzLmlkID8/IFwid2ViX2ZldGNoXCIsXG4gICAgZGVzY3JpcHRpb246IFdFQl9GRVRDSF9UT09MX0RFU0NSSVBUSU9OLFxuICAgIGlucHV0U2NoZW1hOiB3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsXG4gICAgb3V0cHV0U2NoZW1hOiB3ZWJGZXRjaFJlc3VsdFNjaGVtYSxcbiAgICAvLyBBIGZldGNoIGtub3dzIGl0cyBzaW5nbGUgdGFyZ2V0IFVSTCwgc28gYSBwYXR0ZXJuIGdhdGUgaXMgZXZhbHVhdGVkXG4gICAgLy8gcHJlY2lzZWx5IGFnYWluc3QgaXQuXG4gICAgLi4uKGdhdGUubW9kZSA9PT0gXCJub25lXCJcbiAgICAgID8ge31cbiAgICAgIDoge1xuICAgICAgICAgIHJlcXVpcmVBcHByb3ZhbDogKGlucHV0OiB1bmtub3duKSA9PlxuICAgICAgICAgICAgZ2F0ZS5tb2RlID09PSBcImFsd2F5c1wiIHx8XG4gICAgICAgICAgICBhcHByb3ZhbE1hdGNoZXMoZ2F0ZSwgW3BhcnNlVG9vbElucHV0KHdlYkZldGNoUmVxdWVzdFNjaGVtYSwgaW5wdXQpLnVybF0pLFxuICAgICAgICB9KSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgIHJldHVybiBydW5XZWJGZXRjaChwYXJzZVRvb2xJbnB1dCh3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsIGlucHV0KSwgcnVudGltZSk7XG4gICAgfSxcbiAgfSk7XG59XG4iXX0=
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVoRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLGdCQUFnQixHQUlqQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxzQkFBc0IsRUFBeUIsTUFBTSxjQUFjLENBQUM7QUFDN0UsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixvQkFBb0IsRUFDcEIsMEJBQTBCLEVBQzFCLHFCQUFxQixFQUNyQiwwQkFBMEIsRUFDMUIsMkJBQTJCLEdBQzVCLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFcEU7Ozs7O0dBS0c7QUFDSCxTQUFTLGNBQWMsQ0FBc0IsTUFBUyxFQUFFLEtBQWM7SUFDcEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLE1BQU0sZUFBZSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLHNDQUFzQyxDQUFDLENBQUM7SUFDN0YsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQztBQUNyQixDQUFDO0FBa0JELDRFQUE0RTtBQUM1RSxTQUFTLFdBQVcsQ0FBQyxJQUEwQjtJQUM3QyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hDLE1BQU0sSUFBSSxTQUFTLENBQUMsbUVBQW1FLENBQUMsQ0FBQztJQUMzRixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxJQUFJLHNCQUFzQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQsa0ZBQWtGO0FBQ2xGLFNBQVMsYUFBYSxDQUFDLElBQTBCLEVBQUUsT0FBeUI7SUFDMUUsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNqRyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE9BQTZCLEVBQUU7SUFDM0QsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsT0FBTyxVQUFVLENBQUM7UUFDaEIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksWUFBWTtRQUMzQixXQUFXLEVBQUUsMkJBQTJCO1FBQ3hDLFdBQVcsRUFBRSwwQkFBMEI7UUFDdkMsWUFBWSxFQUFFLHFCQUFxQjtRQUNuQyx5RUFBeUU7UUFDekUsK0JBQStCO1FBQy9CLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQywwQkFBMEIsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsRSxPQUFPLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sdUJBQXVCLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsT0FBNkIsRUFBRTtJQUMxRCxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxQyxPQUFPLFVBQVUsQ0FBQztRQUNoQixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxXQUFXO1FBQzFCLFdBQVcsRUFBRSwwQkFBMEI7UUFDdkMsV0FBVyxFQUFFLHFCQUFxQjtRQUNsQyxZQUFZLEVBQUUsb0JBQW9CO1FBQ2xDLHNFQUFzRTtRQUN0RSx3QkFBd0I7UUFDeEIsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTTtZQUN0QixDQUFDLENBQUMsRUFBRTtZQUNKLENBQUMsQ0FBQztnQkFDRSxlQUFlLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUNsQyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVE7b0JBQ3RCLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxjQUFjLENBQUMscUJBQXFCLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDNUUsQ0FBQztRQUNOLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDdkIsT0FBTyxXQUFXLENBQUMsY0FBYyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVFLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgYHdlYl9zZWFyY2hgIGFuZCBgd2ViX2ZldGNoYCBNYXN0cmEgdG9vbHMuXG4gKlxuICogYHdlYl9zZWFyY2hgIGlzIGJhY2tlZCBieSB0aGUgRGF0YWJyaWNrcyBNb2RlbCBTZXJ2aW5nIG5hdGl2ZSB3ZWItc2VhcmNoXG4gKiB0b29sOiBpdCByZXNvbHZlcyBpdHMgb3duIHdlYi1zZWFyY2gtY2FwYWJsZSBtb2RlbCAoc2VlIGBzZWFyY2gudHNgKSBhbmRcbiAqIGNhbGxzIHRoZSB3b3Jrc3BhY2Ugc2VydmluZyBlbmRwb2ludCB1bmRlciB0aGUgY2FsbGVyJ3MgT0JPIHNjb3BlLCBzbyB0aGVcbiAqIHNlYXJjaCBydW5zIGFzIHRoZSByZXF1ZXN0aW5nIHVzZXIgYW5kIGluZGVwZW5kZW50bHkgb2YgdGhlIGFnZW50J3MgY2hhdFxuICogbW9kZWwuIGB3ZWJfZmV0Y2hgIHJlYWRzIGEgcGFnZSB2aWEgZ290LXNjcmFwaW5nLlxuICpcbiAqIEJvdGggYXJlIHJlYWQtb25seSBhbmQgcnVuIHdpdGhvdXQgYXBwcm92YWwgYnkgZGVmYXVsdDsgZWFjaCBhY2NlcHRzIGFuXG4gKiBvcHRpb25hbCB7QGxpbmsgQXBwcm92YWxHYXRlfSAoYGFwcHJvdmFsYCkgdGhhdCBtYXBzIG9udG8gTWFzdHJhJ3NcbiAqIGByZXF1aXJlQXBwcm92YWxgLiBgdHJ1ZWAgZ2F0ZXMgZXZlcnkgY2FsbDsgYSBVUkwtcGF0dGVybiAob3Ige0BsaW5rIE9uZU9yTWFueX1cbiAqIGxpc3QpIGdhdGVzIG9ubHkgY2FsbHMgd2hvc2UgVVJMIG1hdGNoZXMgLSBmb3IgYHdlYl9mZXRjaGAgdGhhdCBpcyBldmFsdWF0ZWRcbiAqIGFnYWluc3QgdGhlIHRhcmdldCBVUkwsIHdoaWxlIGB3ZWJfc2VhcmNoYCAod2hvc2UgcmVzdWx0IFVSTHMgYXJlbid0IGtub3duXG4gKiBiZWZvcmUgdGhlIGNhbGwpIHRyZWF0cyBhIHBhdHRlcm4gZ2F0ZSBhcyBcImFsd2F5cyBnYXRlXCIuIGBhcHByb3ZhbGAgZmFsbHNcbiAqIGJhY2sgdG8gdGhlIHN0YW5kYWxvbmUgcnVudGltZSdzIGBhcHByb3ZhbGAgY29uZmlnIHdoZW4gYSB0b29sIG9taXRzIGl0cyBvd24uXG4gKlxuICogQXBwLWludGVncmF0ZWQgYWdlbnRzIHNob3VsZCBjb25zdW1lIHRoZSBwbHVnaW4ncyBuYXRpdmUgdG9vbGtpdCBzbyBjYWxsc1xuICogcmV0YWluIHRoYXQgcGx1Z2luJ3MgcG9saWN5IGFuZCBleGVjdXRvci4gVGhlc2UgZmFjdG9yaWVzIGFyZSB0aGUgc3RhbmRhbG9uZVxuICogTWFzdHJhIHN1cmZhY2UgYW5kIGNhcHR1cmUgYW4gZXhwbGljaXQgcnVudGltZSBvciBpc29sYXRlZCBjb25maWcuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGNyZWF0ZVRvb2wgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3Rvb2xzXCI7XG5pbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQge1xuICBhcHByb3ZhbE1hdGNoZXMsXG4gIHRvQXBwcm92YWxQb2xpY3ksXG4gIHR5cGUgQXBwcm92YWxHYXRlLFxuICB0eXBlIEFwcHJvdmFsUG9saWN5LFxuICB0eXBlIFdlYlNlYXJjaFBsdWdpbkNvbmZpZyxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBydW5XZWJGZXRjaCB9IGZyb20gXCIuL2ZldGNoLnRzXCI7XG5pbXBvcnQgeyBjcmVhdGVXZWJTZWFyY2hSdW50aW1lLCB0eXBlIFdlYlNlYXJjaFJ1bnRpbWUgfSBmcm9tIFwiLi9ydW50aW1lLnRzXCI7XG5pbXBvcnQge1xuICB3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsXG4gIHdlYkZldGNoUmVzdWx0U2NoZW1hLFxuICB3ZWJTZWFyY2hUb29sUmVxdWVzdFNjaGVtYSxcbiAgd2ViU2VhcmNoUmVzdWx0U2NoZW1hLFxuICBXRUJfRkVUQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgV0VCX1NFQVJDSF9UT09MX0RFU0NSSVBUSU9OLFxufSBmcm9tIFwiLi9zY2hlbWEudHNcIjtcbmltcG9ydCB7IHJlc29sdmVXZWJTZWFyY2hDb250ZXh0LCBydW5XZWJTZWFyY2ggfSBmcm9tIFwiLi9zZWFyY2gudHNcIjtcblxuLyoqXG4gKiBWYWxpZGF0ZSBhIHRvb2wgY2FsbCdzIGFyZ3VtZW50cyBhdCB0aGUgcnVudGltZSBib3VuZGFyeS4gTWFzdHJhIGNoZWNrcyB0aGVcbiAqIGlucHV0IHNjaGVtYSBiZWZvcmUgZGlzcGF0Y2gsIGJ1dCB0aGUgYXJndW1lbnQgc3RpbGwgYXJyaXZlcyB0eXBlZCBhc1xuICogYHVua25vd25gIGFuZCB0aGUgbW9kZWwgaXMgdGhlIG9uZSBmaWxsaW5nIGl0IGluLiBUaGUgcmVqZWN0ZWQgdmFsdWUgaXMgbm90XG4gKiBlY2hvZWQgYmFjay5cbiAqL1xuZnVuY3Rpb24gcGFyc2VUb29sSW5wdXQ8UyBleHRlbmRzIHouWm9kVHlwZT4oc2NoZW1hOiBTLCBpbnB1dDogdW5rbm93bik6IHouaW5mZXI8Uz4ge1xuICBjb25zdCBwYXJzZWQgPSBzY2hlbWEuc2FmZVBhcnNlKGlucHV0KTtcbiAgaWYgKCFwYXJzZWQuc3VjY2Vzcykge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5pbnZhbGlkVmFsdWUoXCJpbnB1dFwiLCBpbnB1dCwgXCJhcmd1bWVudHMgbWF0Y2hpbmcgdGhlIHRvb2wncyBzY2hlbWFcIik7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZC5kYXRhO1xufVxuXG4vKiogT3B0aW9ucyBzaGFyZWQgYnkgYm90aCB3ZWIgdG9vbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFdlYlNlYXJjaFRvb2xPcHRpb25zIHtcbiAgLyoqIE92ZXJyaWRlIHRoZSB0b29sIGlkLiAqL1xuICBpZD86IHN0cmluZztcbiAgLyoqIElzb2xhdGVkIHJ1bnRpbWUgdXNlZCBieSB0aGlzIHN0YW5kYWxvbmUgdG9vbC4gTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggYGNvbmZpZ2AuICovXG4gIHJ1bnRpbWU/OiBXZWJTZWFyY2hSdW50aW1lO1xuICAvKiogQ29uZmlnIHVzZWQgdG8gY3JlYXRlIGFuIGlzb2xhdGVkIGRpcmVjdC1leGVjdXRpb24gcnVudGltZS4gKi9cbiAgY29uZmlnPzogV2ViU2VhcmNoUGx1Z2luQ29uZmlnO1xuICAvKipcbiAgICogQXBwcm92YWwgZ2F0ZSBmb3IgdGhpcyB0b29sLCBvdmVycmlkaW5nIHRoZSBydW50aW1lJ3MgYGFwcHJvdmFsYC4gYHRydWVgXG4gICAqIGdhdGVzIGV2ZXJ5IGNhbGw7IGEgVVJMLXBhdHRlcm4gKG9yIGxpc3QpIGdhdGVzIG9ubHkgbWF0Y2hpbmcgY2FsbHM7XG4gICAqIG9taXQgLyBgZmFsc2VgIGZvciBubyBhcHByb3ZhbC4gU2VlIHtAbGluayBBcHByb3ZhbEdhdGV9LlxuICAgKi9cbiAgYXBwcm92YWw/OiBBcHByb3ZhbEdhdGUgfCBBcHByb3ZhbFBvbGljeTtcbn1cblxuLyoqIFJlc29sdmUgdGhlIGlzb2xhdGVkIHJ1bnRpbWUgY2FwdHVyZWQgYnkgb25lIHN0YW5kYWxvbmUgdG9vbCBmYWN0b3J5LiAqL1xuZnVuY3Rpb24gdG9vbFJ1bnRpbWUob3B0czogV2ViU2VhcmNoVG9vbE9wdGlvbnMpOiBXZWJTZWFyY2hSdW50aW1lIHtcbiAgaWYgKG9wdHMucnVudGltZSAmJiBvcHRzLmNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ3ZWItc2VhcmNoIHRvb2wgb3B0aW9ucyBhY2NlcHQgZWl0aGVyIHJ1bnRpbWUgb3IgY29uZmlnLCBub3QgYm90aFwiKTtcbiAgfVxuICByZXR1cm4gb3B0cy5ydW50aW1lID8/IGNyZWF0ZVdlYlNlYXJjaFJ1bnRpbWUob3B0cy5jb25maWcpO1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIGdhdGU6IGV4cGxpY2l0IHRvb2wgb3B0aW9uLCBlbHNlIHRoZSBydW50aW1lIGRlZmF1bHQuICovXG5mdW5jdGlvbiBlZmZlY3RpdmVHYXRlKG9wdHM6IFdlYlNlYXJjaFRvb2xPcHRpb25zLCBydW50aW1lOiBXZWJTZWFyY2hSdW50aW1lKTogQXBwcm92YWxQb2xpY3kge1xuICByZXR1cm4gb3B0cy5hcHByb3ZhbCA9PT0gdW5kZWZpbmVkID8gcnVudGltZS5jb25maWcuYXBwcm92YWwgOiB0b0FwcHJvdmFsUG9saWN5KG9wdHMuYXBwcm92YWwpO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBgd2ViX3NlYXJjaGAgdG9vbC4gU3ByZWFkIGl0IGludG8gdGhlIGFnZW50cyB0aGF0IHNob3VsZCBiZSBhYmxlXG4gKiB0byBzZWFyY2ggdGhlIHdlYi5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IHdlYlNlYXJjaFRvb2wgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQtd2ViLXNlYXJjaFwiO1xuICogaW1wb3J0IHsgY3JlYXRlQWdlbnQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhXCI7XG4gKlxuICogY29uc3QgcmVzZWFyY2hlciA9IGNyZWF0ZUFnZW50KHtcbiAqICAgaW5zdHJ1Y3Rpb25zOiBcIi4uLlwiLFxuICogICB0b29sczogKCkgPT4gKHsgd2ViX3NlYXJjaDogd2ViU2VhcmNoVG9vbCgpIH0pLFxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdlYlNlYXJjaFRvb2wob3B0czogV2ViU2VhcmNoVG9vbE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBydW50aW1lID0gdG9vbFJ1bnRpbWUob3B0cyk7XG4gIGNvbnN0IGdhdGUgPSBlZmZlY3RpdmVHYXRlKG9wdHMsIHJ1bnRpbWUpO1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdHMuaWQgPz8gXCJ3ZWJfc2VhcmNoXCIsXG4gICAgZGVzY3JpcHRpb246IFdFQl9TRUFSQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogd2ViU2VhcmNoVG9vbFJlcXVlc3RTY2hlbWEsXG4gICAgb3V0cHV0U2NoZW1hOiB3ZWJTZWFyY2hSZXN1bHRTY2hlbWEsXG4gICAgLy8gQSBzZWFyY2gncyByZXN1bHQgVVJMcyBhcmVuJ3Qga25vd24gYmVmb3JlIHRoZSBjYWxsLCBzbyBhIHBhdHRlcm4gZ2F0ZVxuICAgIC8vIGlzIHRyZWF0ZWQgYXMgXCJhbHdheXMgZ2F0ZVwiLlxuICAgIC4uLihnYXRlLm1vZGUgPT09IFwibm9uZVwiID8ge30gOiB7IHJlcXVpcmVBcHByb3ZhbDogKCkgPT4gdHJ1ZSB9KSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBwYXJzZVRvb2xJbnB1dCh3ZWJTZWFyY2hUb29sUmVxdWVzdFNjaGVtYSwgaW5wdXQpO1xuICAgICAgcmV0dXJuIHJ1bldlYlNlYXJjaChyZXF1ZXN0LCBydW50aW1lLCBhd2FpdCByZXNvbHZlV2ViU2VhcmNoQ29udGV4dCgpKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgYHdlYl9mZXRjaGAgdG9vbC4gU3ByZWFkIGl0IGludG8gdGhlIGFnZW50cyB0aGF0IHNob3VsZCBiZSBhYmxlXG4gKiB0byByZWFkIGEgcGFnZSdzIGNvbnRlbnRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgd2ViRmV0Y2hUb29sIH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0LXdlYi1zZWFyY2hcIjtcbiAqXG4gKiB0b29sczogKCkgPT4gKHsgd2ViX2ZldGNoOiB3ZWJGZXRjaFRvb2woeyBhcHByb3ZhbDogXCIqLmludGVybmFsLmV4YW1wbGUuY29tXCIgfSkgfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gd2ViRmV0Y2hUb29sKG9wdHM6IFdlYlNlYXJjaFRvb2xPcHRpb25zID0ge30pIHtcbiAgY29uc3QgcnVudGltZSA9IHRvb2xSdW50aW1lKG9wdHMpO1xuICBjb25zdCBnYXRlID0gZWZmZWN0aXZlR2F0ZShvcHRzLCBydW50aW1lKTtcbiAgcmV0dXJuIGNyZWF0ZVRvb2woe1xuICAgIGlkOiBvcHRzLmlkID8/IFwid2ViX2ZldGNoXCIsXG4gICAgZGVzY3JpcHRpb246IFdFQl9GRVRDSF9UT09MX0RFU0NSSVBUSU9OLFxuICAgIGlucHV0U2NoZW1hOiB3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsXG4gICAgb3V0cHV0U2NoZW1hOiB3ZWJGZXRjaFJlc3VsdFNjaGVtYSxcbiAgICAvLyBBIGZldGNoIGtub3dzIGl0cyBzaW5nbGUgdGFyZ2V0IFVSTCwgc28gYSBwYXR0ZXJuIGdhdGUgaXMgZXZhbHVhdGVkXG4gICAgLy8gcHJlY2lzZWx5IGFnYWluc3QgaXQuXG4gICAgLi4uKGdhdGUubW9kZSA9PT0gXCJub25lXCJcbiAgICAgID8ge31cbiAgICAgIDoge1xuICAgICAgICAgIHJlcXVpcmVBcHByb3ZhbDogKGlucHV0OiB1bmtub3duKSA9PlxuICAgICAgICAgICAgZ2F0ZS5tb2RlID09PSBcImFsd2F5c1wiIHx8XG4gICAgICAgICAgICBhcHByb3ZhbE1hdGNoZXMoZ2F0ZSwgW3BhcnNlVG9vbElucHV0KHdlYkZldGNoUmVxdWVzdFNjaGVtYSwgaW5wdXQpLnVybF0pLFxuICAgICAgICB9KSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgIHJldHVybiBydW5XZWJGZXRjaChwYXJzZVRvb2xJbnB1dCh3ZWJGZXRjaFJlcXVlc3RTY2hlbWEsIGlucHV0KSwgcnVudGltZSk7XG4gICAgfSxcbiAgfSk7XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@databricks/appkit": "0.81.0",
|
|
30
|
-
"@dbx-tools/appkit": "^0.9.
|
|
31
|
-
"@dbx-tools/core": "^0.9.
|
|
32
|
-
"@dbx-tools/model": "^0.9.
|
|
33
|
-
"@dbx-tools/path": "^0.9.
|
|
34
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
35
|
-
"@dbx-tools/shared-model": "^0.9.
|
|
30
|
+
"@dbx-tools/appkit": "^0.9.71",
|
|
31
|
+
"@dbx-tools/core": "^0.9.71",
|
|
32
|
+
"@dbx-tools/model": "^0.9.71",
|
|
33
|
+
"@dbx-tools/path": "^0.9.71",
|
|
34
|
+
"@dbx-tools/shared-core": "^0.9.71",
|
|
35
|
+
"@dbx-tools/shared-model": "^0.9.71",
|
|
36
36
|
"@mastra/core": "1.71.0",
|
|
37
37
|
"cheerio": "^1.2.0",
|
|
38
38
|
"entities": "^4.5.0",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"./package.json": "./package.json"
|
|
103
103
|
}
|
|
104
104
|
},
|
|
105
|
-
"version": "0.9.
|
|
105
|
+
"version": "0.9.71",
|
|
106
106
|
"types": "./lib/index.d.ts",
|
|
107
107
|
"dbxToolsConfig": {
|
|
108
108
|
"tags": [
|
package/src/config.ts
CHANGED
|
@@ -88,18 +88,11 @@ export const SERVING_ENDPOINT_ENV = "DATABRICKS_SERVING_ENDPOINT_NAME";
|
|
|
88
88
|
export type ModelSource = "config" | typeof MODEL_ENV | typeof SERVING_ENDPOINT_ENV | "none";
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
* Default web-search
|
|
92
|
-
* pinned.
|
|
93
|
-
*
|
|
94
|
-
* live catalogue, so a close variant (e.g. `databricks-gemini-3-1-pro`) is
|
|
95
|
-
* picked when the exact id isn't present.
|
|
91
|
+
* Default web-search family preference, tried in order when no model is
|
|
92
|
+
* pinned. Each query selects the highest-ranked deployed model in that family
|
|
93
|
+
* after model-owned web-search capability filtering.
|
|
96
94
|
*/
|
|
97
|
-
export const DEFAULT_MODEL_FALLBACKS: readonly string[] = [
|
|
98
|
-
"databricks-gemini-3-pro",
|
|
99
|
-
"databricks-gemini-2-5-pro",
|
|
100
|
-
"databricks-gpt-5",
|
|
101
|
-
"databricks-gpt-5-mini",
|
|
102
|
-
];
|
|
95
|
+
export const DEFAULT_MODEL_FALLBACKS: readonly string[] = ["gemini", "gpt"];
|
|
103
96
|
|
|
104
97
|
/** Default cap on the number of citations returned from a single search. */
|
|
105
98
|
export const DEFAULT_MAX_CITATIONS = 10;
|
|
@@ -108,17 +101,14 @@ export const DEFAULT_MAX_CITATIONS = 10;
|
|
|
108
101
|
export const DEFAULT_FETCH_MAX_LENGTH = 50_000;
|
|
109
102
|
|
|
110
103
|
/** Default per-request network timeout (ms) for search + fetch. */
|
|
111
|
-
export const DEFAULT_TIMEOUT_MS =
|
|
104
|
+
export const DEFAULT_TIMEOUT_MS = 60_000;
|
|
112
105
|
|
|
113
106
|
/** AppKit config accepted by the web-search plugin. */
|
|
114
107
|
export interface WebSearchPluginConfig extends BasePluginConfig {
|
|
115
108
|
/**
|
|
116
|
-
*
|
|
117
|
-
* name
|
|
118
|
-
*
|
|
119
|
-
* back to `WEB_SEARCH_MODEL`, then `DATABRICKS_SERVING_ENDPOINT_NAME`, then
|
|
120
|
-
* the {@link modelFallbacks} order. Chosen independently of the calling
|
|
121
|
-
* agent's chat model.
|
|
109
|
+
* GPT preference used when no capable Gemini is available. Accepts a
|
|
110
|
+
* Databricks serving endpoint name or loose family search and falls back to
|
|
111
|
+
* `WEB_SEARCH_MODEL`, then `DATABRICKS_SERVING_ENDPOINT_NAME`.
|
|
122
112
|
*/
|
|
123
113
|
model?: string;
|
|
124
114
|
/**
|
|
@@ -129,9 +119,9 @@ export interface WebSearchPluginConfig extends BasePluginConfig {
|
|
|
129
119
|
*/
|
|
130
120
|
modelFallbacks?: string | string[];
|
|
131
121
|
/**
|
|
132
|
-
* Provider ->
|
|
122
|
+
* Provider -> request-fragment override map, merged over the built-in
|
|
133
123
|
* {@link WEB_SEARCH_PROVIDERS} defaults. Keyed by provider family
|
|
134
|
-
* (`"openai"`, `"gemini"`); each value may override the `
|
|
124
|
+
* (`"openai"`, `"gemini"`); each value may override the `request` fragment
|
|
135
125
|
* and/or the `api` surface. Use to change the tool shape as the platform
|
|
136
126
|
* evolves without a code change. Falls back to `WEB_SEARCH_TOOLS` parsed as
|
|
137
127
|
* JSON. This is the `WEB_SEARCH_TOOLS` setting.
|
|
@@ -203,7 +193,7 @@ export interface ResolvedWebSearchConfig {
|
|
|
203
193
|
modelSource: ModelSource;
|
|
204
194
|
/** Ordered fallback model candidates (Gemini, then GPT, then a floor). */
|
|
205
195
|
modelFallbacks: readonly string[];
|
|
206
|
-
/** Provider ->
|
|
196
|
+
/** Provider -> request-fragment override map, merged over the built-in defaults. */
|
|
207
197
|
webSearchTools: Record<string, unknown>;
|
|
208
198
|
/** Whether to fuzzy-match loose model names. */
|
|
209
199
|
fuzzy: boolean;
|
|
@@ -240,7 +230,7 @@ export const WEB_SEARCH_CONFIG_SCHEMA: JSONSchema7 = {
|
|
|
240
230
|
webSearchTools: {
|
|
241
231
|
type: "object",
|
|
242
232
|
description:
|
|
243
|
-
'Provider ->
|
|
233
|
+
'Provider -> request-fragment override map merged over the built-in defaults (openai -> {"tools":[{"type":"web_search"}]}, gemini -> {"google_search":{}}). Env: WEB_SEARCH_TOOLS (JSON).',
|
|
244
234
|
},
|
|
245
235
|
modelFuzzyMatch: {
|
|
246
236
|
type: "boolean",
|
|
@@ -312,7 +302,7 @@ function parseToolsEnv(): Record<string, unknown> {
|
|
|
312
302
|
const parsed = json.parseRecord(raw);
|
|
313
303
|
if (!parsed) {
|
|
314
304
|
throw new ConfigurationError(
|
|
315
|
-
"WEB_SEARCH_TOOLS must be a JSON object mapping a provider family to its
|
|
305
|
+
"WEB_SEARCH_TOOLS must be a JSON object mapping a provider family to its request fragment",
|
|
316
306
|
{ context: { envVar: "WEB_SEARCH_TOOLS" } },
|
|
317
307
|
);
|
|
318
308
|
}
|
package/src/fetch.ts
CHANGED
|
@@ -78,6 +78,9 @@ export async function runWebFetch(
|
|
|
78
78
|
async (executeSignal): Promise<FetchedPage> => {
|
|
79
79
|
const response = await gotScraping({
|
|
80
80
|
url: request.url,
|
|
81
|
+
// Bun's node:http2 reports default-port origins with :443 while
|
|
82
|
+
// http2-wrapper compares them against URL-normalized origins.
|
|
83
|
+
http2: false,
|
|
81
84
|
// got's own timeout aborts the socket and reports which phase timed
|
|
82
85
|
// out; the interceptor timeout bounds the whole attempt around it.
|
|
83
86
|
timeout: { request: config.timeoutMs },
|
package/src/plugin.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from "@databricks/appkit";
|
|
24
24
|
import { defineTool, type ToolRegistry } from "@databricks/appkit/beta";
|
|
25
25
|
import { ToolRegistryPlugin } from "@dbx-tools/appkit";
|
|
26
|
+
import type { AgentToolExecutionContext } from "@dbx-tools/appkit/tool-provider";
|
|
26
27
|
import { log, stringUtils } from "@dbx-tools/shared-core";
|
|
27
28
|
import {
|
|
28
29
|
MODEL_ENV,
|
|
@@ -34,7 +35,7 @@ import { runWebFetch } from "./fetch.ts";
|
|
|
34
35
|
import { createWebSearchRuntime, type WebSearchRuntime } from "./runtime.ts";
|
|
35
36
|
import {
|
|
36
37
|
webFetchRequestSchema,
|
|
37
|
-
|
|
38
|
+
webSearchToolRequestSchema,
|
|
38
39
|
WEB_FETCH_TOOL_DESCRIPTION,
|
|
39
40
|
WEB_SEARCH_TOOL_DESCRIPTION,
|
|
40
41
|
} from "./schema.ts";
|
|
@@ -149,10 +150,10 @@ export class WebSearchPlugin extends ToolRegistryPlugin<WebSearchPluginConfig> {
|
|
|
149
150
|
protected readonly toolRegistry: ToolRegistry = {
|
|
150
151
|
web_search: defineTool({
|
|
151
152
|
description: WEB_SEARCH_TOOL_DESCRIPTION,
|
|
152
|
-
schema:
|
|
153
|
+
schema: webSearchToolRequestSchema,
|
|
153
154
|
annotations: { effect: "read", requiresUserContext: true },
|
|
154
155
|
autoInheritable: false,
|
|
155
|
-
execute: async (args, signal) => this.search(
|
|
156
|
+
execute: async (args, signal) => this.search(webSearchToolRequestSchema.parse(args), signal),
|
|
156
157
|
}),
|
|
157
158
|
web_fetch: defineTool({
|
|
158
159
|
description: WEB_FETCH_TOOL_DESCRIPTION,
|
|
@@ -163,6 +164,25 @@ export class WebSearchPlugin extends ToolRegistryPlugin<WebSearchPluginConfig> {
|
|
|
163
164
|
}),
|
|
164
165
|
};
|
|
165
166
|
|
|
167
|
+
/** Dispatch with the actual calling model and optional host progress sink. */
|
|
168
|
+
override executeAgentTool(
|
|
169
|
+
name: string,
|
|
170
|
+
args: unknown,
|
|
171
|
+
signal?: AbortSignal,
|
|
172
|
+
context?: AgentToolExecutionContext,
|
|
173
|
+
): Promise<unknown> {
|
|
174
|
+
if (name !== "web_search") return super.executeAgentTool(name, args, signal, context);
|
|
175
|
+
const request = webSearchToolRequestSchema.parse(args);
|
|
176
|
+
return this.search(
|
|
177
|
+
{
|
|
178
|
+
...request,
|
|
179
|
+
...(context?.model ? { model: context.model } : {}),
|
|
180
|
+
},
|
|
181
|
+
signal,
|
|
182
|
+
context?.writeProgress,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
166
186
|
/**
|
|
167
187
|
* Log the effective policy so an active allow-list and caps are obvious at
|
|
168
188
|
* boot. Runtime construction already resolved config and captured this
|
|
@@ -213,8 +233,18 @@ export class WebSearchPlugin extends ToolRegistryPlugin<WebSearchPluginConfig> {
|
|
|
213
233
|
};
|
|
214
234
|
}
|
|
215
235
|
|
|
216
|
-
private async search(
|
|
217
|
-
|
|
236
|
+
private async search(
|
|
237
|
+
request: WebSearchRequest,
|
|
238
|
+
signal?: AbortSignal,
|
|
239
|
+
writeProgress?: AgentToolExecutionContext["writeProgress"],
|
|
240
|
+
): Promise<WebSearchResult> {
|
|
241
|
+
return runWebSearch(
|
|
242
|
+
request,
|
|
243
|
+
this.runtime,
|
|
244
|
+
await resolveWebSearchContext(),
|
|
245
|
+
signal,
|
|
246
|
+
writeProgress,
|
|
247
|
+
);
|
|
218
248
|
}
|
|
219
249
|
|
|
220
250
|
private async fetch(request: WebFetchRequest, signal?: AbortSignal): Promise<WebFetchResult> {
|
package/src/provider.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - OpenAI GPT models, via the Responses API (`/serving-endpoints/responses`):
|
|
11
11
|
* `tools: [{ "type": "web_search" }]`
|
|
12
12
|
* - Google Gemini models, via Chat Completions
|
|
13
|
-
* (`/serving-endpoints/chat/completions`): `
|
|
13
|
+
* (`/serving-endpoints/chat/completions`): top-level `"google_search": {}`
|
|
14
14
|
*
|
|
15
15
|
* (Anthropic exposes it over MCP, which needs a different call shape; only
|
|
16
16
|
* GPT + Gemini are wired here, matching what the platform supports today.)
|
|
@@ -24,22 +24,28 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { ValidationError } from "@databricks/appkit";
|
|
27
|
+
import { metadata, policy } from "@dbx-tools/model";
|
|
28
|
+
import type { ServingEndpointSummary } from "@dbx-tools/shared-model";
|
|
27
29
|
import { z } from "zod";
|
|
28
30
|
|
|
29
31
|
/** A web-search-capable model provider family. */
|
|
30
32
|
export type WebSearchProvider = "openai" | "gemini";
|
|
31
33
|
|
|
34
|
+
/** Serialized provider request fragment for native web search. */
|
|
35
|
+
export const WebSearchProviderSpecSchema = z
|
|
36
|
+
.object({
|
|
37
|
+
api: z
|
|
38
|
+
.enum(["responses", "chat"])
|
|
39
|
+
.describe("Databricks serving API that accepts the provider request."),
|
|
40
|
+
request: z
|
|
41
|
+
.record(z.string(), z.unknown())
|
|
42
|
+
.describe("Provider-specific fields merged into the serving request body."),
|
|
43
|
+
})
|
|
44
|
+
.strict()
|
|
45
|
+
.describe("Native web-search request contract for one provider family.");
|
|
46
|
+
|
|
32
47
|
/** How a provider's native web-search call is shaped. */
|
|
33
|
-
export
|
|
34
|
-
/**
|
|
35
|
-
* Which serving REST surface to call. `"responses"` posts to
|
|
36
|
-
* `/serving-endpoints/responses` (OpenAI Responses API); `"chat"` posts to
|
|
37
|
-
* `/serving-endpoints/chat/completions`.
|
|
38
|
-
*/
|
|
39
|
-
api: "responses" | "chat";
|
|
40
|
-
/** The tool entry appended to the request's `tools` array. */
|
|
41
|
-
tool: Record<string, unknown>;
|
|
42
|
-
}
|
|
48
|
+
export type WebSearchProviderSpec = z.infer<typeof WebSearchProviderSpecSchema>;
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* Built-in provider -> tool-spec map. Operators can override or extend this
|
|
@@ -47,30 +53,33 @@ export interface WebSearchProviderSpec {
|
|
|
47
53
|
* `WEB_SEARCH_TOOLS`), which is merged over these defaults.
|
|
48
54
|
*/
|
|
49
55
|
export const WEB_SEARCH_PROVIDERS: Readonly<Record<WebSearchProvider, WebSearchProviderSpec>> = {
|
|
50
|
-
openai: { api: "responses",
|
|
51
|
-
gemini: { api: "chat",
|
|
56
|
+
openai: { api: "responses", request: { tools: [{ type: "web_search" }] } },
|
|
57
|
+
gemini: { api: "chat", request: { google_search: {} } },
|
|
52
58
|
};
|
|
53
59
|
|
|
54
60
|
/**
|
|
55
|
-
*
|
|
56
|
-
* the model is not one of the web-search-capable families. Anthropic
|
|
57
|
-
* (`opus`/`sonnet`/`haiku`) is intentionally excluded - it needs an MCP call
|
|
58
|
-
* shape this module doesn't implement - so a Claude endpoint returns `null`
|
|
59
|
-
* and is treated as unsupported.
|
|
61
|
+
* Map a model-owned family value to its native web-search provider contract.
|
|
60
62
|
*/
|
|
61
|
-
export function
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
export function webSearchProviderForFamily(
|
|
64
|
+
family: policy.ModelFamily | undefined,
|
|
65
|
+
): WebSearchProvider | null {
|
|
66
|
+
switch (family) {
|
|
67
|
+
case policy.ModelFamily.Gpt:
|
|
68
|
+
return "openai";
|
|
69
|
+
case policy.ModelFamily.Gemini:
|
|
70
|
+
return "gemini";
|
|
71
|
+
default:
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
/** Whether
|
|
72
|
-
export function supportsWebSearch(
|
|
73
|
-
|
|
76
|
+
/** Whether a model has both native capability and a supported provider contract. */
|
|
77
|
+
export function supportsWebSearch(model: string | ServingEndpointSummary): boolean {
|
|
78
|
+
const identity = typeof model === "string" ? model : (model.modelServiceName ?? model.name);
|
|
79
|
+
return (
|
|
80
|
+
webSearchProviderForFamily(policy.modelFamily(identity)) !== null &&
|
|
81
|
+
metadata.modelCapabilitiesFor(model).webSearch
|
|
82
|
+
);
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
/**
|
|
@@ -78,16 +87,15 @@ export function supportsWebSearch(modelId: string): boolean {
|
|
|
78
87
|
* parsed JSON (config or `WEB_SEARCH_TOOLS`), so it is validated rather than
|
|
79
88
|
* asserted.
|
|
80
89
|
*/
|
|
81
|
-
const providerOverrideSchema =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
90
|
+
const providerOverrideSchema = WebSearchProviderSpecSchema.partial()
|
|
91
|
+
.strict()
|
|
92
|
+
.describe("Partial native web-search provider override.");
|
|
85
93
|
|
|
86
94
|
/**
|
|
87
95
|
* Resolve the effective {@link WebSearchProviderSpec} for a provider: the
|
|
88
96
|
* built-in default, with any operator override (the `webSearchTools` map,
|
|
89
97
|
* keyed by provider) shallow-merged over it. An override may replace just the
|
|
90
|
-
* `
|
|
98
|
+
* `request` fragment or also the `api`. An override
|
|
91
99
|
* that is not one of those two fields is a deployment mistake that would
|
|
92
100
|
* otherwise be silently dropped, so it throws.
|
|
93
101
|
*/
|
|
@@ -103,11 +111,11 @@ export function webSearchToolSpec(
|
|
|
103
111
|
throw ValidationError.invalidValue(
|
|
104
112
|
`webSearchTools.${provider}`,
|
|
105
113
|
raw,
|
|
106
|
-
'an object with an optional "api" ("responses" | "chat") and an optional "
|
|
114
|
+
'an object with an optional "api" ("responses" | "chat") and an optional "request" object',
|
|
107
115
|
);
|
|
108
116
|
}
|
|
109
117
|
return {
|
|
110
118
|
api: parsed.data.api ?? base.api,
|
|
111
|
-
|
|
119
|
+
request: parsed.data.request ?? base.request,
|
|
112
120
|
};
|
|
113
121
|
}
|
package/src/runtime.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import type { ExecutionResult } from "@databricks/appkit";
|
|
12
12
|
import { pluginExecution } from "@dbx-tools/appkit";
|
|
13
|
+
import { policy } from "@dbx-tools/model";
|
|
13
14
|
import { execution, log } from "@dbx-tools/shared-core";
|
|
14
15
|
import {
|
|
15
16
|
resolveWebSearchConfig,
|
|
@@ -34,6 +35,8 @@ export type WebSearchExecutor = <T>(
|
|
|
34
35
|
export interface WebSearchRuntime {
|
|
35
36
|
config: ResolvedWebSearchConfig;
|
|
36
37
|
execute: WebSearchExecutor;
|
|
38
|
+
/** Provider-family cooldown deadlines learned from workspace failures. */
|
|
39
|
+
familyCooldowns: Map<policy.ModelFamily, number>;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
/** Runtime-aware operation input, retaining resolved-config compatibility. */
|
|
@@ -51,7 +54,7 @@ export function createWebSearchRuntime(
|
|
|
51
54
|
overrides?: WebSearchPluginConfig,
|
|
52
55
|
execute: WebSearchExecutor = directExecute,
|
|
53
56
|
): WebSearchRuntime {
|
|
54
|
-
return { config: resolveWebSearchConfig(overrides), execute };
|
|
57
|
+
return { config: resolveWebSearchConfig(overrides), execute, familyCooldowns: new Map() };
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
/** Build an isolated runtime from config that has already been resolved. */
|
|
@@ -59,7 +62,7 @@ export function createResolvedWebSearchRuntime(
|
|
|
59
62
|
config: ResolvedWebSearchConfig,
|
|
60
63
|
execute: WebSearchExecutor = directExecute,
|
|
61
64
|
): WebSearchRuntime {
|
|
62
|
-
return { config, execute };
|
|
65
|
+
return { config, execute, familyCooldowns: new Map() };
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
/** Normalize an explicit runtime or legacy resolved config for one operation. */
|
package/src/schema.ts
CHANGED
|
@@ -54,12 +54,9 @@ export const webSearchRequestSchema = z.object({
|
|
|
54
54
|
.optional()
|
|
55
55
|
.describe(
|
|
56
56
|
stringUtils.toDescription(`
|
|
57
|
-
Optional
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
configured web-search model. The web-search tool resolves its own
|
|
61
|
-
model independently of the calling agent's chat model, since not
|
|
62
|
-
every chat model supports web search.
|
|
57
|
+
Optional calling-model preference. The tool always tries the highest
|
|
58
|
+
web-search-capable Gemini first. When Gemini is unavailable, a matching
|
|
59
|
+
GPT endpoint wins before the highest-ranked GPT fallback.
|
|
63
60
|
`),
|
|
64
61
|
),
|
|
65
62
|
});
|
|
@@ -67,6 +64,14 @@ export const webSearchRequestSchema = z.object({
|
|
|
67
64
|
/** A validated `web_search` request. */
|
|
68
65
|
export type WebSearchRequest = z.infer<typeof webSearchRequestSchema>;
|
|
69
66
|
|
|
67
|
+
/** Model-facing `web_search` input; the host owns model selection. */
|
|
68
|
+
export const webSearchToolRequestSchema = webSearchRequestSchema
|
|
69
|
+
.omit({ model: true })
|
|
70
|
+
.describe("Model-facing web-search input with host-owned model selection.");
|
|
71
|
+
|
|
72
|
+
/** Model-facing `web_search` request. */
|
|
73
|
+
export type WebSearchToolRequest = z.infer<typeof webSearchToolRequestSchema>;
|
|
74
|
+
|
|
70
75
|
/** Schema for a single source the model cited while answering. */
|
|
71
76
|
export const webSearchCitationSchema = z.object({
|
|
72
77
|
url: z.string().describe("The source URL the answer drew on."),
|