@agent-native/core 0.68.3 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +54 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/changelog/parse.ts +245 -0
- package/corpus/core/src/cli/changelog.ts +199 -0
- package/corpus/core/src/cli/index.ts +19 -0
- package/corpus/core/src/cli/recap.ts +24 -1
- package/corpus/core/src/cli/skills.ts +72 -45
- package/corpus/core/src/client/CommandMenu.tsx +183 -75
- package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
- package/corpus/core/src/client/analytics.ts +181 -0
- package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
- package/corpus/core/src/client/index.ts +11 -0
- package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
- package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
- package/corpus/core/src/extensions/web-search-tool.ts +45 -4
- package/corpus/core/src/mcp/build-server.ts +1 -1
- package/corpus/core/src/mcp/embed-app.ts +112 -6
- package/corpus/core/src/secrets/register-framework-secrets.ts +7 -0
- package/corpus/core/src/server/attribution.ts +211 -0
- package/corpus/core/src/server/auth.ts +6 -0
- package/corpus/core/src/server/better-auth-instance.ts +49 -5
- package/corpus/core/src/server/builder-browser.ts +27 -1
- package/corpus/core/src/server/core-routes-plugin.ts +58 -0
- package/corpus/core/src/server/google-oauth.ts +19 -6
- package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
- package/corpus/core/src/styles/agent-conversation.css +21 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/corpus/templates/analytics/CHANGELOG.md +10 -0
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +2 -2
- package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/update-dashboard.ts +5 -3
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
- package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -2
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -213
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -3
- package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
- package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
- package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
- package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
- package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
- package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
- package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
- package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
- package/corpus/templates/analytics/server/db/index.ts +1 -1
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
- package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
- package/corpus/templates/assets/CHANGELOG.md +10 -0
- package/corpus/templates/assets/app/root.tsx +7 -1
- package/corpus/templates/assets/app/routes/settings.tsx +6 -0
- package/corpus/templates/brain/CHANGELOG.md +10 -0
- package/corpus/templates/brain/app/root.tsx +7 -1
- package/corpus/templates/brain/app/routes/settings.tsx +8 -1
- package/corpus/templates/calendar/CHANGELOG.md +10 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
- package/corpus/templates/calendar/app/root.tsx +7 -1
- package/corpus/templates/chat/CHANGELOG.md +10 -0
- package/corpus/templates/chat/app/root.tsx +7 -1
- package/corpus/templates/clips/CHANGELOG.md +10 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
- package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +72 -20
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +69 -2
- package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
- package/corpus/templates/clips/app/lib/recorder-preferences.ts +67 -0
- package/corpus/templates/clips/app/root.tsx +7 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
- package/corpus/templates/clips/app/routes/_app.trash.tsx +21 -0
- package/corpus/templates/clips/app/routes/record.tsx +92 -8
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
- package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
- package/corpus/templates/clips/desktop/src/main.tsx +3 -0
- package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
- package/corpus/templates/clips/desktop/src/styles.css +49 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +67 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +51 -1
- package/corpus/templates/clips/shared/share-attribution.ts +79 -0
- package/corpus/templates/content/CHANGELOG.md +10 -0
- package/corpus/templates/content/app/root.tsx +7 -1
- package/corpus/templates/content/vitest.config.ts +3 -0
- package/corpus/templates/design/CHANGELOG.md +10 -0
- package/corpus/templates/design/actions/generate-design.ts +4 -0
- package/corpus/templates/design/app/root.tsx +7 -1
- package/corpus/templates/design/app/routes/settings.tsx +10 -2
- package/corpus/templates/dispatch/CHANGELOG.md +10 -0
- package/corpus/templates/dispatch/app/root.tsx +7 -1
- package/corpus/templates/forms/CHANGELOG.md +10 -0
- package/corpus/templates/forms/app/root.tsx +7 -1
- package/corpus/templates/macros/CHANGELOG.md +10 -0
- package/corpus/templates/macros/app/root.tsx +7 -1
- package/corpus/templates/mail/CHANGELOG.md +10 -0
- package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
- package/corpus/templates/plan/AGENTS.md +4 -0
- package/corpus/templates/plan/CHANGELOG.md +10 -0
- package/corpus/templates/plan/actions/view-screen.ts +5 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
- package/corpus/templates/plan/app/root.tsx +7 -1
- package/corpus/templates/plan/shared/share-attribution.ts +72 -0
- package/corpus/templates/slides/CHANGELOG.md +10 -0
- package/corpus/templates/slides/app/root.tsx +7 -1
- package/corpus/templates/videos/CHANGELOG.md +4 -151
- package/corpus/templates/videos/app/root.tsx +7 -1
- package/dist/changelog/parse.d.ts +70 -0
- package/dist/changelog/parse.d.ts.map +1 -0
- package/dist/changelog/parse.js +200 -0
- package/dist/changelog/parse.js.map +1 -0
- package/dist/cli/changelog.d.ts +4 -0
- package/dist/cli/changelog.d.ts.map +1 -0
- package/dist/cli/changelog.js +166 -0
- package/dist/cli/changelog.js.map +1 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +22 -1
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +72 -45
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/CommandMenu.d.ts +17 -1
- package/dist/client/CommandMenu.d.ts.map +1 -1
- package/dist/client/CommandMenu.js +49 -13
- package/dist/client/CommandMenu.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +43 -6
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts +18 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +177 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/changelog/Changelog.d.ts +47 -0
- package/dist/client/changelog/Changelog.d.ts.map +1 -0
- package/dist/client/changelog/Changelog.js +138 -0
- package/dist/client/changelog/Changelog.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
- package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
- package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +58 -10
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/extensions/web-search-tool.d.ts +5 -3
- package/dist/extensions/web-search-tool.d.ts.map +1 -1
- package/dist/extensions/web-search-tool.js +36 -4
- package/dist/extensions/web-search-tool.js.map +1 -1
- package/dist/mcp/build-server.js +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.d.ts.map +1 -1
- package/dist/mcp/embed-app.js +112 -6
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +6 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/attribution.d.ts +83 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +178 -0
- package/dist/server/attribution.js.map +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +7 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +9 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +32 -2
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +20 -1
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +25 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +38 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +16 -2
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/shared/mcp-embed-headers.js +1 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-conversation.css +21 -0
- package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
* 1. Brave Search API (BRAVE_SEARCH_API_KEY)
|
|
8
8
|
* 2. Tavily (TAVILY_API_KEY)
|
|
9
9
|
* 3. Exa (EXA_API_KEY)
|
|
10
|
-
* 4.
|
|
10
|
+
* 4. Firecrawl (FIRECRAWL_API_KEY)
|
|
11
|
+
* 5. Builder.io (connected Builder credentials)
|
|
11
12
|
*
|
|
12
13
|
* The first configured backend wins. If none is configured, the tool
|
|
13
14
|
* returns a helpful message telling the user which keys to add.
|
|
14
15
|
*
|
|
15
|
-
* Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY,
|
|
16
|
-
* EXA_API_KEY via app secrets settings or environment
|
|
16
|
+
* Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY,
|
|
17
|
+
* EXA_API_KEY, or FIRECRAWL_API_KEY via app secrets settings or environment
|
|
18
|
+
* variables.
|
|
17
19
|
*/
|
|
18
20
|
import type { ActionEntry } from "../agent/production-agent.js";
|
|
19
21
|
import type { CredentialContext } from "../credentials/index.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search-tool.d.ts","sourceRoot":"","sources":["../../src/extensions/web-search-tool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"web-search-tool.d.ts","sourceRoot":"","sources":["../../src/extensions/web-search-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,KACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,iBAAiB,GAAG,IAAI,CAAC;IACtD;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACvE;;OAEG;IACH,0BAA0B,CAAC,EAAE,MAAM,MAAM,CAAC;IAC1C;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzD;AAKD,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAwPD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,oBAAyB,GAC9B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAoH7B"}
|
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
* 1. Brave Search API (BRAVE_SEARCH_API_KEY)
|
|
8
8
|
* 2. Tavily (TAVILY_API_KEY)
|
|
9
9
|
* 3. Exa (EXA_API_KEY)
|
|
10
|
-
* 4.
|
|
10
|
+
* 4. Firecrawl (FIRECRAWL_API_KEY)
|
|
11
|
+
* 5. Builder.io (connected Builder credentials)
|
|
11
12
|
*
|
|
12
13
|
* The first configured backend wins. If none is configured, the tool
|
|
13
14
|
* returns a helpful message telling the user which keys to add.
|
|
14
15
|
*
|
|
15
|
-
* Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY,
|
|
16
|
-
* EXA_API_KEY via app secrets settings or environment
|
|
16
|
+
* Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY,
|
|
17
|
+
* EXA_API_KEY, or FIRECRAWL_API_KEY via app secrets settings or environment
|
|
18
|
+
* variables.
|
|
17
19
|
*/
|
|
18
20
|
const DEFAULT_COUNT = 5;
|
|
19
21
|
const MAX_COUNT = 10;
|
|
@@ -136,6 +138,30 @@ async function searchExa(query, count, apiKey) {
|
|
|
136
138
|
snippet: r.text ?? "",
|
|
137
139
|
}));
|
|
138
140
|
}
|
|
141
|
+
async function searchFirecrawl(query, count, apiKey) {
|
|
142
|
+
const res = await fetch("https://api.firecrawl.dev/v2/search", {
|
|
143
|
+
method: "POST",
|
|
144
|
+
headers: {
|
|
145
|
+
"Content-Type": "application/json",
|
|
146
|
+
Authorization: `Bearer ${apiKey}`,
|
|
147
|
+
},
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
query,
|
|
150
|
+
limit: count,
|
|
151
|
+
}),
|
|
152
|
+
signal: AbortSignal.timeout(15_000),
|
|
153
|
+
});
|
|
154
|
+
if (!res.ok) {
|
|
155
|
+
throw new Error(`Firecrawl error ${res.status}: ${await res.text()}`);
|
|
156
|
+
}
|
|
157
|
+
const data = (await res.json());
|
|
158
|
+
const results = Array.isArray(data.data) ? data.data : (data.data?.web ?? []);
|
|
159
|
+
return results.map((r) => ({
|
|
160
|
+
title: r.title ?? "",
|
|
161
|
+
url: r.url ?? "",
|
|
162
|
+
snippet: r.description ?? "",
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
139
165
|
async function searchBuilderManaged(query, count, credentials, opts) {
|
|
140
166
|
const baseUrl = opts.getBuilderWebSearchBaseUrl?.() ??
|
|
141
167
|
process.env.BUILDER_WEB_SEARCH_BASE_URL ??
|
|
@@ -183,7 +209,7 @@ export function createWebSearchToolEntry(opts = {}) {
|
|
|
183
209
|
return {
|
|
184
210
|
"web-search": {
|
|
185
211
|
tool: {
|
|
186
|
-
description: "Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs using responseMode:'markdown' or responseMode:'matches' to fetch clean text, links, or compact snippets from promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, or
|
|
212
|
+
description: "Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs using responseMode:'markdown' or responseMode:'matches' to fetch clean text, links, or compact snippets from promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, EXA_API_KEY, or FIRECRAWL_API_KEY.",
|
|
187
213
|
parameters: {
|
|
188
214
|
type: "object",
|
|
189
215
|
properties: {
|
|
@@ -211,6 +237,7 @@ export function createWebSearchToolEntry(opts = {}) {
|
|
|
211
237
|
const braveKey = await resolveSearchKey("BRAVE_SEARCH_API_KEY", opts);
|
|
212
238
|
const tavilyKey = await resolveSearchKey("TAVILY_API_KEY", opts);
|
|
213
239
|
const exaKey = await resolveSearchKey("EXA_API_KEY", opts);
|
|
240
|
+
const firecrawlKey = await resolveSearchKey("FIRECRAWL_API_KEY", opts);
|
|
214
241
|
const builderCredentials = await resolveBuilderSearchCredentials(opts);
|
|
215
242
|
let results;
|
|
216
243
|
let backend;
|
|
@@ -228,6 +255,10 @@ export function createWebSearchToolEntry(opts = {}) {
|
|
|
228
255
|
results = await searchExa(query, count, exaKey);
|
|
229
256
|
backend = "Exa";
|
|
230
257
|
}
|
|
258
|
+
else if (firecrawlKey) {
|
|
259
|
+
results = await searchFirecrawl(query, count, firecrawlKey);
|
|
260
|
+
backend = "Firecrawl";
|
|
261
|
+
}
|
|
231
262
|
else if (builderCredentials) {
|
|
232
263
|
managedText = await searchBuilderManaged(query, count, builderCredentials, opts);
|
|
233
264
|
results = [];
|
|
@@ -240,6 +271,7 @@ export function createWebSearchToolEntry(opts = {}) {
|
|
|
240
271
|
" • BRAVE_SEARCH_API_KEY — https://brave.com/search/api/",
|
|
241
272
|
" • TAVILY_API_KEY — https://tavily.com/",
|
|
242
273
|
" • EXA_API_KEY — https://exa.ai/",
|
|
274
|
+
" • FIRECRAWL_API_KEY — https://firecrawl.dev/",
|
|
243
275
|
].join("\n");
|
|
244
276
|
}
|
|
245
277
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search-tool.js","sourceRoot":"","sources":["../../src/extensions/web-search-tool.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Web-search tool — agent tool for searching the public web.\n *\n * Pluggable backends resolved at call time based on which API key is\n * configured (env var or secrets/credentials store):\n *\n * 1. Brave Search API (BRAVE_SEARCH_API_KEY)\n * 2. Tavily (TAVILY_API_KEY)\n * 3. Exa (EXA_API_KEY)\n * 4. Builder.io (connected Builder credentials)\n *\n * The first configured backend wins. If none is configured, the tool\n * returns a helpful message telling the user which keys to add.\n *\n * Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, or\n * EXA_API_KEY via app secrets settings or environment variables.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { CredentialContext } from \"../credentials/index.js\";\n\nexport interface WebSearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nexport interface WebSearchToolOptions {\n /**\n * Resolve a request-scoped secret by key. When not provided the tool falls\n * back to env-var lookup only.\n */\n resolveSecret?: (key: string) => Promise<string | null>;\n /**\n * Legacy credential resolver retained for older callers.\n */\n resolveCredential?: (\n key: string,\n ctx: CredentialContext,\n ) => Promise<string | undefined>;\n /**\n * Legacy credential context callback retained for older callers.\n */\n getCredentialContext?: () => CredentialContext | null;\n /**\n * Resolve connected Builder credentials for managed web search.\n */\n resolveBuilderCredentials?: () => Promise<BuilderWebSearchCredentials>;\n /**\n * Base URL for Builder-managed web search.\n */\n getBuilderWebSearchBaseUrl?: () => string;\n /**\n * Stable attribution headers for Builder-managed API calls.\n */\n getBuilderRequestHeaders?: () => Record<string, string>;\n}\n\nconst DEFAULT_COUNT = 5;\nconst MAX_COUNT = 10;\n\ninterface BuilderWebSearchCredentials {\n privateKey: string | null;\n publicKey: string | null;\n userId?: string | null;\n}\n\nasync function resolveSearchKey(\n key: string,\n opts: WebSearchToolOptions,\n): Promise<string | undefined> {\n let usedRequestScopedResolver = false;\n // 1. Try request-scoped app secrets (user/org/workspace stored key).\n if (opts.resolveSecret) {\n usedRequestScopedResolver = true;\n try {\n const value = await opts.resolveSecret(key);\n if (value) return value;\n } catch {\n // Secret lookup failures are non-fatal; fall through to legacy/env.\n }\n }\n\n // 2. Try legacy per-request credential context.\n if (opts.resolveCredential && opts.getCredentialContext) {\n const ctx = opts.getCredentialContext();\n if (ctx) {\n try {\n const value = await opts.resolveCredential(key, ctx);\n if (value) return value;\n } catch {\n // Credential lookup failures are non-fatal; fall through to env.\n }\n }\n }\n\n if (usedRequestScopedResolver) return undefined;\n\n // 3. Fall back to env var.\n return process.env[key] || undefined;\n}\n\nasync function resolveBuilderSearchCredentials(\n opts: WebSearchToolOptions,\n): Promise<BuilderWebSearchCredentials | null> {\n if (!opts.resolveBuilderCredentials) return null;\n try {\n const creds = await opts.resolveBuilderCredentials();\n if (creds.privateKey && creds.publicKey) return creds;\n } catch {\n // Builder credential lookup failures are non-fatal; BYOK backends or the\n // setup hint below can still handle the tool call.\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Backend implementations\n// ---------------------------------------------------------------------------\n\nasync function searchBrave(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`;\n const res = await fetch(url, {\n headers: {\n Accept: \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n \"X-Subscription-Token\": apiKey,\n },\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Brave Search error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n web?: {\n results?: Array<{\n title?: string;\n url?: string;\n description?: string;\n }>;\n };\n };\n return (data.web?.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.description ?? \"\",\n }));\n}\n\nasync function searchTavily(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const res = await fetch(\"https://api.tavily.com/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: count,\n search_depth: \"basic\",\n }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Tavily error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n results?: Array<{\n title?: string;\n url?: string;\n content?: string;\n }>;\n };\n return (data.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.content ?? \"\",\n }));\n}\n\nasync function searchExa(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const res = await fetch(\"https://api.exa.ai/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n },\n body: JSON.stringify({\n query,\n numResults: count,\n type: \"auto\",\n contents: { text: { maxCharacters: 400 } },\n }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Exa error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n results?: Array<{\n title?: string;\n url?: string;\n text?: string;\n }>;\n };\n return (data.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.text ?? \"\",\n }));\n}\n\nasync function searchBuilderManaged(\n query: string,\n count: number,\n credentials: BuilderWebSearchCredentials,\n opts: WebSearchToolOptions,\n): Promise<string> {\n const baseUrl =\n opts.getBuilderWebSearchBaseUrl?.() ??\n process.env.BUILDER_WEB_SEARCH_BASE_URL ??\n \"https://api.builder.io/agent-native/web-search/v1\";\n const url = new URL(\n \"search\",\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`,\n );\n const res = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${credentials.privateKey}`,\n \"x-builder-api-key\": credentials.publicKey ?? \"\",\n ...(credentials.userId\n ? { \"x-builder-user-id\": credentials.userId }\n : {}),\n ...(opts.getBuilderRequestHeaders?.() ?? {}),\n },\n body: JSON.stringify({\n query,\n count,\n source: {\n appId: \"agent-native\",\n feature: \"web-search-tool\",\n },\n }),\n signal: AbortSignal.timeout(45_000),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(\n `Builder web search error ${res.status}${text ? `: ${text.slice(0, 300)}` : \"\"}`,\n );\n }\n const data = (await res.json()) as {\n text?: string;\n };\n const text = data.text?.trim();\n if (!text) {\n throw new Error(\"Builder web search returned no text.\");\n }\n return text;\n}\n\n// ---------------------------------------------------------------------------\n// Tool entry factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create the web-search tool entry for the agent tool registry.\n */\nexport function createWebSearchToolEntry(\n opts: WebSearchToolOptions = {},\n): Record<string, ActionEntry> {\n return {\n \"web-search\": {\n tool: {\n description:\n \"Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs using responseMode:'markdown' or responseMode:'matches' to fetch clean text, links, or compact snippets from promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, or EXA_API_KEY.\",\n parameters: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Search query. Be specific — include API name, version, and what you need (e.g. 'Stripe API list subscriptions endpoint').\",\n },\n count: {\n type: \"number\",\n description: `Number of results to return. Default ${DEFAULT_COUNT}, max ${MAX_COUNT}.`,\n },\n },\n required: [\"query\"],\n },\n },\n run: async (args: Record<string, string>) => {\n const query = (args.query ?? \"\").trim();\n if (!query) return \"query is required.\";\n\n const rawCount = Number(args.count);\n const count =\n Number.isFinite(rawCount) && rawCount > 0\n ? Math.min(Math.floor(rawCount), MAX_COUNT)\n : DEFAULT_COUNT;\n\n // Backend selection — first configured wins.\n const braveKey = await resolveSearchKey(\"BRAVE_SEARCH_API_KEY\", opts);\n const tavilyKey = await resolveSearchKey(\"TAVILY_API_KEY\", opts);\n const exaKey = await resolveSearchKey(\"EXA_API_KEY\", opts);\n const builderCredentials = await resolveBuilderSearchCredentials(opts);\n\n let results: WebSearchResult[];\n let backend: string;\n let managedText: string | null = null;\n\n try {\n if (braveKey) {\n results = await searchBrave(query, count, braveKey);\n backend = \"Brave Search\";\n } else if (tavilyKey) {\n results = await searchTavily(query, count, tavilyKey);\n backend = \"Tavily\";\n } else if (exaKey) {\n results = await searchExa(query, count, exaKey);\n backend = \"Exa\";\n } else if (builderCredentials) {\n managedText = await searchBuilderManaged(\n query,\n count,\n builderCredentials,\n opts,\n );\n results = [];\n backend = \"Builder.io\";\n } else {\n return [\n \"No web-search backend configured.\",\n \"Connect Builder.io in Settings, or add one of the following keys via app settings or environment variables:\",\n \" • BRAVE_SEARCH_API_KEY — https://brave.com/search/api/\",\n \" • TAVILY_API_KEY — https://tavily.com/\",\n \" • EXA_API_KEY — https://exa.ai/\",\n ].join(\"\\n\");\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Web search failed (${msg}). Try web-request to fetch a specific URL directly.`;\n }\n\n if (managedText) {\n return [\n `Web search results for \"${query}\" (backend: ${backend}):`,\n \"\",\n managedText,\n \"\",\n \"Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.\",\n ].join(\"\\n\");\n }\n\n if (results.length === 0) {\n return `No results found for \"${query}\" (backend: ${backend}).`;\n }\n\n const lines: string[] = [\n `Web search results for \"${query}\" (backend: ${backend}):`,\n \"\",\n ];\n for (let i = 0; i < results.length; i++) {\n const r = results[i];\n lines.push(`${i + 1}. ${r.title}`);\n lines.push(` URL: ${r.url}`);\n if (r.snippet) {\n const snippet = r.snippet.slice(0, 300).replace(/\\n+/g, \" \");\n lines.push(` ${snippet}`);\n }\n lines.push(\"\");\n }\n lines.push(\n \"Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.\",\n );\n return lines.join(\"\\n\");\n },\n readOnly: true,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web-search-tool.js","sourceRoot":"","sources":["../../src/extensions/web-search-tool.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Web-search tool — agent tool for searching the public web.\n *\n * Pluggable backends resolved at call time based on which API key is\n * configured (env var or secrets/credentials store):\n *\n * 1. Brave Search API (BRAVE_SEARCH_API_KEY)\n * 2. Tavily (TAVILY_API_KEY)\n * 3. Exa (EXA_API_KEY)\n * 4. Firecrawl (FIRECRAWL_API_KEY)\n * 5. Builder.io (connected Builder credentials)\n *\n * The first configured backend wins. If none is configured, the tool\n * returns a helpful message telling the user which keys to add.\n *\n * Connect Builder.io or register BRAVE_SEARCH_API_KEY, TAVILY_API_KEY,\n * EXA_API_KEY, or FIRECRAWL_API_KEY via app secrets settings or environment\n * variables.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { CredentialContext } from \"../credentials/index.js\";\n\nexport interface WebSearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nexport interface WebSearchToolOptions {\n /**\n * Resolve a request-scoped secret by key. When not provided the tool falls\n * back to env-var lookup only.\n */\n resolveSecret?: (key: string) => Promise<string | null>;\n /**\n * Legacy credential resolver retained for older callers.\n */\n resolveCredential?: (\n key: string,\n ctx: CredentialContext,\n ) => Promise<string | undefined>;\n /**\n * Legacy credential context callback retained for older callers.\n */\n getCredentialContext?: () => CredentialContext | null;\n /**\n * Resolve connected Builder credentials for managed web search.\n */\n resolveBuilderCredentials?: () => Promise<BuilderWebSearchCredentials>;\n /**\n * Base URL for Builder-managed web search.\n */\n getBuilderWebSearchBaseUrl?: () => string;\n /**\n * Stable attribution headers for Builder-managed API calls.\n */\n getBuilderRequestHeaders?: () => Record<string, string>;\n}\n\nconst DEFAULT_COUNT = 5;\nconst MAX_COUNT = 10;\n\ninterface BuilderWebSearchCredentials {\n privateKey: string | null;\n publicKey: string | null;\n userId?: string | null;\n}\n\nasync function resolveSearchKey(\n key: string,\n opts: WebSearchToolOptions,\n): Promise<string | undefined> {\n let usedRequestScopedResolver = false;\n // 1. Try request-scoped app secrets (user/org/workspace stored key).\n if (opts.resolveSecret) {\n usedRequestScopedResolver = true;\n try {\n const value = await opts.resolveSecret(key);\n if (value) return value;\n } catch {\n // Secret lookup failures are non-fatal; fall through to legacy/env.\n }\n }\n\n // 2. Try legacy per-request credential context.\n if (opts.resolveCredential && opts.getCredentialContext) {\n const ctx = opts.getCredentialContext();\n if (ctx) {\n try {\n const value = await opts.resolveCredential(key, ctx);\n if (value) return value;\n } catch {\n // Credential lookup failures are non-fatal; fall through to env.\n }\n }\n }\n\n if (usedRequestScopedResolver) return undefined;\n\n // 3. Fall back to env var.\n return process.env[key] || undefined;\n}\n\nasync function resolveBuilderSearchCredentials(\n opts: WebSearchToolOptions,\n): Promise<BuilderWebSearchCredentials | null> {\n if (!opts.resolveBuilderCredentials) return null;\n try {\n const creds = await opts.resolveBuilderCredentials();\n if (creds.privateKey && creds.publicKey) return creds;\n } catch {\n // Builder credential lookup failures are non-fatal; BYOK backends or the\n // setup hint below can still handle the tool call.\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Backend implementations\n// ---------------------------------------------------------------------------\n\nasync function searchBrave(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`;\n const res = await fetch(url, {\n headers: {\n Accept: \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n \"X-Subscription-Token\": apiKey,\n },\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Brave Search error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n web?: {\n results?: Array<{\n title?: string;\n url?: string;\n description?: string;\n }>;\n };\n };\n return (data.web?.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.description ?? \"\",\n }));\n}\n\nasync function searchTavily(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const res = await fetch(\"https://api.tavily.com/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: count,\n search_depth: \"basic\",\n }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Tavily error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n results?: Array<{\n title?: string;\n url?: string;\n content?: string;\n }>;\n };\n return (data.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.content ?? \"\",\n }));\n}\n\nasync function searchExa(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const res = await fetch(\"https://api.exa.ai/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n },\n body: JSON.stringify({\n query,\n numResults: count,\n type: \"auto\",\n contents: { text: { maxCharacters: 400 } },\n }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Exa error ${res.status}: ${await res.text()}`);\n }\n const data = (await res.json()) as {\n results?: Array<{\n title?: string;\n url?: string;\n text?: string;\n }>;\n };\n return (data.results ?? []).map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.text ?? \"\",\n }));\n}\n\nasync function searchFirecrawl(\n query: string,\n count: number,\n apiKey: string,\n): Promise<WebSearchResult[]> {\n const res = await fetch(\"https://api.firecrawl.dev/v2/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n query,\n limit: count,\n }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) {\n throw new Error(`Firecrawl error ${res.status}: ${await res.text()}`);\n }\n // v2 groups results by source ({ data: { web: [...] } }); older shapes\n // return a flat array ({ data: [...] }). Accept both defensively.\n type FirecrawlResult = { title?: string; url?: string; description?: string };\n const data = (await res.json()) as {\n data?: FirecrawlResult[] | { web?: FirecrawlResult[] };\n };\n const results = Array.isArray(data.data) ? data.data : (data.data?.web ?? []);\n return results.map((r) => ({\n title: r.title ?? \"\",\n url: r.url ?? \"\",\n snippet: r.description ?? \"\",\n }));\n}\n\nasync function searchBuilderManaged(\n query: string,\n count: number,\n credentials: BuilderWebSearchCredentials,\n opts: WebSearchToolOptions,\n): Promise<string> {\n const baseUrl =\n opts.getBuilderWebSearchBaseUrl?.() ??\n process.env.BUILDER_WEB_SEARCH_BASE_URL ??\n \"https://api.builder.io/agent-native/web-search/v1\";\n const url = new URL(\n \"search\",\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`,\n );\n const res = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${credentials.privateKey}`,\n \"x-builder-api-key\": credentials.publicKey ?? \"\",\n ...(credentials.userId\n ? { \"x-builder-user-id\": credentials.userId }\n : {}),\n ...(opts.getBuilderRequestHeaders?.() ?? {}),\n },\n body: JSON.stringify({\n query,\n count,\n source: {\n appId: \"agent-native\",\n feature: \"web-search-tool\",\n },\n }),\n signal: AbortSignal.timeout(45_000),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(\n `Builder web search error ${res.status}${text ? `: ${text.slice(0, 300)}` : \"\"}`,\n );\n }\n const data = (await res.json()) as {\n text?: string;\n };\n const text = data.text?.trim();\n if (!text) {\n throw new Error(\"Builder web search returned no text.\");\n }\n return text;\n}\n\n// ---------------------------------------------------------------------------\n// Tool entry factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create the web-search tool entry for the agent tool registry.\n */\nexport function createWebSearchToolEntry(\n opts: WebSearchToolOptions = {},\n): Record<string, ActionEntry> {\n return {\n \"web-search\": {\n tool: {\n description:\n \"Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs using responseMode:'markdown' or responseMode:'matches' to fetch clean text, links, or compact snippets from promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, EXA_API_KEY, or FIRECRAWL_API_KEY.\",\n parameters: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Search query. Be specific — include API name, version, and what you need (e.g. 'Stripe API list subscriptions endpoint').\",\n },\n count: {\n type: \"number\",\n description: `Number of results to return. Default ${DEFAULT_COUNT}, max ${MAX_COUNT}.`,\n },\n },\n required: [\"query\"],\n },\n },\n run: async (args: Record<string, string>) => {\n const query = (args.query ?? \"\").trim();\n if (!query) return \"query is required.\";\n\n const rawCount = Number(args.count);\n const count =\n Number.isFinite(rawCount) && rawCount > 0\n ? Math.min(Math.floor(rawCount), MAX_COUNT)\n : DEFAULT_COUNT;\n\n // Backend selection — first configured wins.\n const braveKey = await resolveSearchKey(\"BRAVE_SEARCH_API_KEY\", opts);\n const tavilyKey = await resolveSearchKey(\"TAVILY_API_KEY\", opts);\n const exaKey = await resolveSearchKey(\"EXA_API_KEY\", opts);\n const firecrawlKey = await resolveSearchKey(\"FIRECRAWL_API_KEY\", opts);\n const builderCredentials = await resolveBuilderSearchCredentials(opts);\n\n let results: WebSearchResult[];\n let backend: string;\n let managedText: string | null = null;\n\n try {\n if (braveKey) {\n results = await searchBrave(query, count, braveKey);\n backend = \"Brave Search\";\n } else if (tavilyKey) {\n results = await searchTavily(query, count, tavilyKey);\n backend = \"Tavily\";\n } else if (exaKey) {\n results = await searchExa(query, count, exaKey);\n backend = \"Exa\";\n } else if (firecrawlKey) {\n results = await searchFirecrawl(query, count, firecrawlKey);\n backend = \"Firecrawl\";\n } else if (builderCredentials) {\n managedText = await searchBuilderManaged(\n query,\n count,\n builderCredentials,\n opts,\n );\n results = [];\n backend = \"Builder.io\";\n } else {\n return [\n \"No web-search backend configured.\",\n \"Connect Builder.io in Settings, or add one of the following keys via app settings or environment variables:\",\n \" • BRAVE_SEARCH_API_KEY — https://brave.com/search/api/\",\n \" • TAVILY_API_KEY — https://tavily.com/\",\n \" • EXA_API_KEY — https://exa.ai/\",\n \" • FIRECRAWL_API_KEY — https://firecrawl.dev/\",\n ].join(\"\\n\");\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Web search failed (${msg}). Try web-request to fetch a specific URL directly.`;\n }\n\n if (managedText) {\n return [\n `Web search results for \"${query}\" (backend: ${backend}):`,\n \"\",\n managedText,\n \"\",\n \"Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.\",\n ].join(\"\\n\");\n }\n\n if (results.length === 0) {\n return `No results found for \"${query}\" (backend: ${backend}).`;\n }\n\n const lines: string[] = [\n `Web search results for \"${query}\" (backend: ${backend}):`,\n \"\",\n ];\n for (let i = 0; i < results.length; i++) {\n const r = results[i];\n lines.push(`${i + 1}. ${r.title}`);\n lines.push(` URL: ${r.url}`);\n if (r.snippet) {\n const snippet = r.snippet.slice(0, 300).replace(/\\n+/g, \" \");\n lines.push(` ${snippet}`);\n }\n lines.push(\"\");\n }\n lines.push(\n \"Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.\",\n );\n return lines.join(\"\\n\");\n },\n readOnly: true,\n },\n };\n}\n"]}
|
package/dist/mcp/build-server.js
CHANGED
|
@@ -467,7 +467,7 @@ function safeUiSegment(value, fallback) {
|
|
|
467
467
|
}
|
|
468
468
|
// ChatGPT and Claude cache MCP App resource HTML by `ui://` URI. Bump this
|
|
469
469
|
// when the shared shell changes in a way that must invalidate host caches.
|
|
470
|
-
const MCP_APP_RESOURCE_SHELL_VERSION = "shell-
|
|
470
|
+
const MCP_APP_RESOURCE_SHELL_VERSION = "shell-v45";
|
|
471
471
|
function legacyDefaultMcpAppUri(config, actionName) {
|
|
472
472
|
const app = safeUiSegment(config.appId ?? config.name, "agent-native");
|
|
473
473
|
const action = safeUiSegment(actionName, "tool");
|