@tool-bridge/server 0.21.1 → 0.23.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/dist/admin.js +170 -0
- package/dist/airtable-VMQVXLHK.js +790 -0
- package/dist/{alt_text_generator_ai-W7O34SNG.js → alt_text_generator_ai-FTWY4RU4.js} +12 -11
- package/dist/{amap-VOX4T2AW.js → amap-OK5VBHYC.js} +221 -220
- package/dist/anthropic-S67AZFZ3.js +203 -0
- package/dist/apify-ZE6MYQI3.js +248 -0
- package/dist/brave_search-TG2M2KOD.js +302 -0
- package/dist/chunk-2JNAI4OC.js +161 -0
- package/dist/{chunk-KMTT3I6D.js → chunk-4XJPN3DY.js} +19392 -26136
- package/dist/chunk-5ICRY3VU.js +8432 -0
- package/dist/chunk-7CTWGTDU.js +302 -0
- package/dist/chunk-BADVCN6K.js +378 -0
- package/dist/{chunk-XYBU3WZH.js → chunk-TDAWLMDE.js} +3 -3
- package/dist/chunk-U7PTOA3U.js +7320 -0
- package/dist/{chunk-E6JCVKW6.js → chunk-VWRUGUSU.js} +3 -3
- package/dist/{chunk-ATK45BXV.js → chunk-WJHG6OK7.js} +4 -2
- package/dist/circleci-3L3WJVSK.js +389 -0
- package/dist/clerk-EZPF2V7T.js +1019 -0
- package/dist/cohere-U27DPO64.js +185 -0
- package/dist/{confluence-B3EWPZVE.js → confluence-G2KL6ERH.js} +105 -104
- package/dist/{convertapi-EUWSQYPF.js → convertapi-L4CLJ2M3.js} +32 -31
- package/dist/{currencyapi-KVTIK3GL.js → currencyapi-YPYXG7YY.js} +71 -71
- package/dist/deepseek-6HT6WF3M.js +210 -0
- package/dist/docker_hub-LPE3PCVB.js +933 -0
- package/dist/dropbox-V56ABHTA.js +1305 -0
- package/dist/dub-6OKQ7MHT.js +680 -0
- package/dist/e2b-JS2U2QFU.js +278 -0
- package/dist/exa-DPWVYXSP.js +332 -0
- package/dist/{fal_ai-23E7JPNT.js → fal_ai-DK6Y27ZF.js} +81 -80
- package/dist/{feishu-7QRIDUV6.js → feishu-K7EGSRF3.js} +528 -572
- package/dist/{feishu_custom_bot-TJ4K7QNJ.js → feishu_custom_bot-2JUGFYNG.js} +57 -53
- package/dist/figma-FT5I7ITD.js +777 -0
- package/dist/firehydrant-EIKLKHX2.js +563 -0
- package/dist/{fixer-BWON27UO.js → fixer-U5QXIAKD.js} +34 -33
- package/dist/fly-T3JYFZ2M.js +469 -0
- package/dist/{front-QCGXYEDJ.js → front-D72MGVOR.js} +104 -104
- package/dist/geocodio-BOTD5TI5.js +213 -0
- package/dist/ghost-KYP7SZGB.js +338 -0
- package/dist/github-AGMZT3VY.js +5421 -0
- package/dist/gmail-BLJNJOBG.js +1887 -0
- package/dist/googlecalendar-GTHWNCF6.js +2524 -0
- package/dist/{googledocs-BUHL4J2H.js → googledocs-6EEDMEBQ.js} +341 -340
- package/dist/{grafana-GLU2DWF2.js → grafana-GMW6EKSQ.js} +221 -220
- package/dist/graphhopper-6OLGBDGB.js +325 -0
- package/dist/index.d.ts +1132 -332
- package/dist/index.js +31 -14
- package/dist/{ip2proxy-EZ64Y4ZH.js → ip2proxy-4QN42E6T.js} +28 -27
- package/dist/ipgeolocation_io-SK4XKDA2.js +315 -0
- package/dist/ipqualityscore-6ANBPXKT.js +279 -0
- package/dist/{jina_ai-EFBHTBXL.js → jina_ai-IHPSVRM5.js} +23 -23
- package/dist/{jira-HQSHAA5K.js → jira-46KKM4LC.js} +118 -117
- package/dist/langsmith-JZA345I5.js +593 -0
- package/dist/lemlist-43IV7DK6.js +289 -0
- package/dist/{linear-K7RYFYAD.js → linear-5LFH7XNL.js} +327 -326
- package/dist/logsnag-5RMYAHIL.js +150 -0
- package/dist/main.js +57 -280
- package/dist/{mattermost-S2BRCWLQ.js → mattermost-XFL6SHGG.js} +59 -58
- package/dist/mem0-NYO4DTP6.js +544 -0
- package/dist/memos-37MPQOLV.js +744 -0
- package/dist/{metabase-MMSEPCOF.js → metabase-KYBKZFMG.js} +90 -89
- package/dist/mistral_ai-6PL3K4PM.js +1196 -0
- package/dist/{mother_duck-H7PCQNZ2.js → mother_duck-2NH7W5M5.js} +94 -93
- package/dist/ngrok-UO6CDYCA.js +356 -0
- package/dist/{notes-PFMKRO33.js → notes-I3P32WP4.js} +11 -9
- package/dist/notion-BEAJFUOE.js +940 -0
- package/dist/open_exchange_rates-CMF62JB4.js +215 -0
- package/dist/openai-IHOMKVND.js +800 -0
- package/dist/opengraph_io-ZQ2FGLHX.js +362 -0
- package/dist/openrouter-HXLW3NR5.js +441 -0
- package/dist/outline-ELCP4NEU.js +599 -0
- package/dist/paddle-O77LALVN.js +454 -0
- package/dist/perplexity-JCU654QV.js +220 -0
- package/dist/pinecone-W5W4LRKL.js +571 -0
- package/dist/{pipedrive-Y2O7QGFF.js → pipedrive-ITMJLLPZ.js} +99 -98
- package/dist/polar-R33XU4L3.js +395 -0
- package/dist/posthog-JVNTOLTV.js +3464 -0
- package/dist/postmark-6SBG7HWV.js +427 -0
- package/dist/{prerender-MENYM2TY.js → prerender-GPNKTNFC.js} +31 -30
- package/dist/{pubmed-GOXUVVH5.js → pubmed-UP6ZEEIH.js} +239 -238
- package/dist/{railway-V2SID4WV.js → railway-KWEWXHTY.js} +118 -117
- package/dist/readwise-BLATSMC3.js +470 -0
- package/dist/render-QYRVIXII.js +461 -0
- package/dist/{replicate-756MXPYX.js → replicate-JYTWH4NF.js} +81 -80
- package/dist/{resend-ZKH3BTBI.js → resend-L5N75SZM.js} +20 -16
- package/dist/rootly-MHCPEQ26.js +336 -0
- package/dist/{scrapfly-NSRHFDIQ.js → scrapfly-PTPGYSJM.js} +62 -61
- package/dist/{scrapingbee-OQHLAVEY.js → scrapingbee-JN6UH5PY.js} +56 -56
- package/dist/{screenshot_fyi-DVWG3AXC.js → screenshot_fyi-4QRVSV55.js} +16 -16
- package/dist/semantic_scholar-LRSWA2GE.js +611 -0
- package/dist/{sentry-546MNDJG.js → sentry-2G6PF5W6.js} +208 -207
- package/dist/{shodan-C3OON3Z3.js → shodan-WKKPP5C6.js} +62 -61
- package/dist/shopify-64YDK5T2.js +610 -0
- package/dist/stripe-QAIGGOTF.js +585 -0
- package/dist/{supabase-U2SL4D63.js → supabase-WHTGR6ND.js} +245 -244
- package/dist/tavily-QIXCDDWO.js +326 -0
- package/dist/telegram-E6G7CWI6.js +1767 -0
- package/dist/{telnyx-CXQ4EZUX.js → telnyx-ZDVVS7PK.js} +57 -56
- package/dist/todoist-DMYF3G7J.js +664 -0
- package/dist/trello-HY2RYIRP.js +1080 -0
- package/dist/turso-HAQWMGRP.js +416 -0
- package/dist/{twilio-4PDBJKWX.js → twilio-MLXYPHJE.js} +70 -69
- package/dist/umami-DZHBLPVG.js +389 -0
- package/dist/unsplash-GS2OPXKE.js +351 -0
- package/dist/{upstash_redis-G4LQBYHA.js → upstash_redis-XMXWTNAJ.js} +51 -50
- package/dist/uptimerobot-TF5WRZ4G.js +483 -0
- package/dist/v2ex-2BVXAPDF.js +667 -0
- package/dist/vercel-YMJGQYJE.js +1076 -0
- package/dist/{wolfram_alpha_api-3G4PUJWB.js → wolfram_alpha_api-I56SXWFZ.js} +36 -35
- package/dist/wordpress-R7TDFZ2P.js +812 -0
- package/dist/workos-HDNHWVMS.js +664 -0
- package/dist/zhihu-LX6AGGDS.js +254 -0
- package/package.json +18 -9
- package/dist/airtable-LLZDFN7M.js +0 -789
- package/dist/anthropic-G23NN3X5.js +0 -202
- package/dist/apify-Y3SS734K.js +0 -247
- package/dist/brave_search-ZC7OAPSZ.js +0 -301
- package/dist/chunk-R6P4XAE5.js +0 -248
- package/dist/chunk-U7B6DS2O.js +0 -977
- package/dist/chunk-UZM2RXZH.js +0 -23436
- package/dist/circleci-3BAX5FCG.js +0 -388
- package/dist/clerk-6LEM6TNU.js +0 -1019
- package/dist/cloudflare_dns-KINYTJUD.js +0 -588
- package/dist/cohere-XCJ5AJ6B.js +0 -185
- package/dist/deepseek-PC5YGNC5.js +0 -209
- package/dist/docker_hub-C3MA5FU6.js +0 -932
- package/dist/dropbox-XBV7Z2IR.js +0 -1304
- package/dist/dub-LDOFG3HC.js +0 -679
- package/dist/e2b-JMCPSVBW.js +0 -277
- package/dist/exa-RAK7O7RD.js +0 -331
- package/dist/figma-E6IX5DTH.js +0 -773
- package/dist/firehydrant-ZBLPQREE.js +0 -562
- package/dist/fly-ZH3HFCZJ.js +0 -468
- package/dist/geocodio-YGNI7DA4.js +0 -212
- package/dist/ghost-EVSGKH2Q.js +0 -337
- package/dist/github-MA2BGRCJ.js +0 -5420
- package/dist/gmail-E5E6AADE.js +0 -1886
- package/dist/googlecalendar-BTLFPXTD.js +0 -2523
- package/dist/graphhopper-WSMB3TCD.js +0 -324
- package/dist/ipgeolocation_io-AA7HAS22.js +0 -315
- package/dist/ipqualityscore-BHJXVTJT.js +0 -277
- package/dist/langsmith-5W6SCT6F.js +0 -592
- package/dist/lemlist-HJWH6UMK.js +0 -288
- package/dist/logsnag-4KFOHL37.js +0 -150
- package/dist/mem0-CAW43CIC.js +0 -543
- package/dist/memos-TWEGPKFM.js +0 -740
- package/dist/mistral_ai-64BGZQHP.js +0 -1195
- package/dist/ngrok-GQCUGZKJ.js +0 -356
- package/dist/notion-DQWZWP4N.js +0 -936
- package/dist/open_exchange_rates-QMMD735E.js +0 -214
- package/dist/openai-W6PX32NZ.js +0 -799
- package/dist/opengraph_io-HNDBXYNW.js +0 -361
- package/dist/openrouter-JJYMEAUL.js +0 -437
- package/dist/outline-MCBNQZYY.js +0 -595
- package/dist/paddle-D2SKLUDN.js +0 -453
- package/dist/perplexity-XIFMKUAE.js +0 -219
- package/dist/pinecone-HUFTALV2.js +0 -570
- package/dist/polar-TYTOMOSR.js +0 -394
- package/dist/posthog-43JAR3VW.js +0 -3463
- package/dist/postmark-KL2QJYSG.js +0 -426
- package/dist/readwise-CI4GIMMJ.js +0 -469
- package/dist/render-SUBJ6YRZ.js +0 -460
- package/dist/rootly-CD2LJHPI.js +0 -336
- package/dist/semantic_scholar-T4A252KW.js +0 -610
- package/dist/shopify-Y2HN2MCQ.js +0 -609
- package/dist/stripe-VE3CD3AY.js +0 -584
- package/dist/tavily-KCZHK6HE.js +0 -326
- package/dist/telegram-3URFBCMY.js +0 -1766
- package/dist/todoist-HNPWNYTD.js +0 -663
- package/dist/trello-3W2MIXRP.js +0 -1079
- package/dist/turso-2EQF7C2Z.js +0 -415
- package/dist/umami-5REN7TGP.js +0 -388
- package/dist/unsplash-EIXL424F.js +0 -350
- package/dist/uptimerobot-KNJ3EYLY.js +0 -482
- package/dist/v2ex-RHJ234PZ.js +0 -666
- package/dist/vercel-AS6NCIC7.js +0 -1075
- package/dist/wordpress-KNDAAUV7.js +0 -811
- package/dist/workos-R6UITSJ7.js +0 -663
- package/dist/zhihu-AGK4HILK.js +0 -253
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAuthedClient
|
|
3
|
+
} from "./chunk-TDAWLMDE.js";
|
|
4
|
+
import "./chunk-VWRUGUSU.js";
|
|
5
|
+
import {
|
|
6
|
+
asJsonObject,
|
|
7
|
+
compactDefined,
|
|
8
|
+
trimmedText
|
|
9
|
+
} from "./chunk-JXHMDBAY.js";
|
|
10
|
+
import {
|
|
11
|
+
createProviderPlugin,
|
|
12
|
+
upstreamError
|
|
13
|
+
} from "./chunk-WJHG6OK7.js";
|
|
14
|
+
import "./chunk-2JNAI4OC.js";
|
|
15
|
+
import "./chunk-BADVCN6K.js";
|
|
16
|
+
import {
|
|
17
|
+
TBError
|
|
18
|
+
} from "./chunk-5ICRY3VU.js";
|
|
19
|
+
import "./chunk-U67V476Y.js";
|
|
20
|
+
|
|
21
|
+
// ../plugins/src/brave_search/api.ts
|
|
22
|
+
var SERVICE = "brave_search";
|
|
23
|
+
var API_BASE = "https://api.search.brave.com";
|
|
24
|
+
var RATE_LIMIT_CODES = /* @__PURE__ */ new Set(["QUOTA_LIMITED", "RATE_LIMITED", "USAGE_LIMIT_EXCEEDED"]);
|
|
25
|
+
var AUTH_CODES = /* @__PURE__ */ new Set(["SUBSCRIPTION_TOKEN_INVALID", "SUBSCRIPTION_NOT_FOUND"]);
|
|
26
|
+
var INVALID_CODES = /* @__PURE__ */ new Set(["RESOURCE_NOT_ALLOWED", "OPTION_NOT_IN_PLAN", "INVALID_URL"]);
|
|
27
|
+
function nullableRecord(value) {
|
|
28
|
+
return value === null ? null : asJsonObject(value);
|
|
29
|
+
}
|
|
30
|
+
function requireRecord(value, label) {
|
|
31
|
+
const result = asJsonObject(value);
|
|
32
|
+
if (result === void 0) {
|
|
33
|
+
throw new TBError("unavailable", `${label}\u4E0D\u662F\u5BF9\u8C61`, { retryable: true });
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function objectArray(value) {
|
|
38
|
+
if (!Array.isArray(value)) return void 0;
|
|
39
|
+
return value.map((item) => requireRecord(item, "Brave Search \u7ED3\u679C\u9879"));
|
|
40
|
+
}
|
|
41
|
+
function searchTerm(value) {
|
|
42
|
+
const term = trimmedText(value);
|
|
43
|
+
if (term === void 0) throw new TBError("invalid_argument", "q \u4E0D\u80FD\u662F\u7A7A\u767D");
|
|
44
|
+
return term;
|
|
45
|
+
}
|
|
46
|
+
function goggles(value) {
|
|
47
|
+
if (value === void 0 || typeof value === "string") return trimmedText(value);
|
|
48
|
+
const items = value.map((item) => trimmedText(item)).filter((item) => item !== void 0);
|
|
49
|
+
return items.length > 0 ? items : void 0;
|
|
50
|
+
}
|
|
51
|
+
function braveSearchError(status, payload) {
|
|
52
|
+
const error = asJsonObject(asJsonObject(payload)?.error);
|
|
53
|
+
const message = trimmedText(error?.detail) ?? trimmedText(error?.code) ?? `Brave Search \u8FD4\u56DE HTTP ${status}`;
|
|
54
|
+
const code = trimmedText(error?.code);
|
|
55
|
+
if (code !== void 0) {
|
|
56
|
+
if (RATE_LIMIT_CODES.has(code)) return upstreamError(429, message);
|
|
57
|
+
if (AUTH_CODES.has(code)) return upstreamError(401, message);
|
|
58
|
+
if (INVALID_CODES.has(code)) return upstreamError(400, message);
|
|
59
|
+
}
|
|
60
|
+
return upstreamError(status, message);
|
|
61
|
+
}
|
|
62
|
+
var http = createAuthedClient({
|
|
63
|
+
baseUrl: `${API_BASE}/`,
|
|
64
|
+
service: SERVICE,
|
|
65
|
+
auth: { kind: "header", name: "x-subscription-token" },
|
|
66
|
+
headers: { accept: "application/json" },
|
|
67
|
+
// 稳定错误码码表比 HTTP 状态准,整段覆写而不用标准键序提取。
|
|
68
|
+
mapError: ({ data: payload, status }) => braveSearchError(status, payload)
|
|
69
|
+
});
|
|
70
|
+
async function request(ctx, path, query) {
|
|
71
|
+
const { data } = await http.request(ctx, {
|
|
72
|
+
path,
|
|
73
|
+
method: "GET",
|
|
74
|
+
query: Object.entries(query),
|
|
75
|
+
invalidJsonMessage: "Brave Search \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94"
|
|
76
|
+
});
|
|
77
|
+
return data ?? null;
|
|
78
|
+
}
|
|
79
|
+
function normalizeWebSearch(payload) {
|
|
80
|
+
const result = requireRecord(payload, "Brave Search \u54CD\u5E94");
|
|
81
|
+
return compactDefined({
|
|
82
|
+
type: trimmedText(result.type) ?? "search",
|
|
83
|
+
query: nullableRecord(result.query),
|
|
84
|
+
web: nullableRecord(result.web),
|
|
85
|
+
news: nullableRecord(result.news),
|
|
86
|
+
videos: nullableRecord(result.videos),
|
|
87
|
+
locations: nullableRecord(result.locations),
|
|
88
|
+
discussions: nullableRecord(result.discussions),
|
|
89
|
+
faq: nullableRecord(result.faq),
|
|
90
|
+
infobox: nullableRecord(result.infobox),
|
|
91
|
+
mixed: nullableRecord(result.mixed),
|
|
92
|
+
summarizer: nullableRecord(result.summarizer),
|
|
93
|
+
rich: nullableRecord(result.rich)
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function normalizeCollection(payload, withExtra) {
|
|
97
|
+
const result = requireRecord(payload, "Brave Search \u54CD\u5E94");
|
|
98
|
+
return compactDefined({
|
|
99
|
+
type: trimmedText(result.type) ?? "search",
|
|
100
|
+
query: nullableRecord(result.query),
|
|
101
|
+
results: objectArray(result.results),
|
|
102
|
+
extra: withExtra ? nullableRecord(result.extra) : void 0
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function webSearch(input, ctx) {
|
|
106
|
+
return normalizeWebSearch(await request(ctx, "/res/v1/web/search", {
|
|
107
|
+
q: searchTerm(input.q),
|
|
108
|
+
search_lang: trimmedText(input.search_lang),
|
|
109
|
+
ui_lang: trimmedText(input.ui_lang),
|
|
110
|
+
country: trimmedText(input.country),
|
|
111
|
+
safesearch: trimmedText(input.safesearch),
|
|
112
|
+
count: input.count,
|
|
113
|
+
offset: input.offset,
|
|
114
|
+
spellcheck: input.spellcheck,
|
|
115
|
+
freshness: trimmedText(input.freshness),
|
|
116
|
+
result_filter: trimmedText(input.result_filter),
|
|
117
|
+
extra_snippets: input.extra_snippets,
|
|
118
|
+
goggles: goggles(input.goggles),
|
|
119
|
+
text_decorations: input.text_decorations,
|
|
120
|
+
units: trimmedText(input.units),
|
|
121
|
+
operators: input.operators,
|
|
122
|
+
include_fetch_metadata: input.include_fetch_metadata
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
async function newsSearch(input, ctx) {
|
|
126
|
+
const payload = await request(ctx, "/res/v1/news/search", {
|
|
127
|
+
q: searchTerm(input.q),
|
|
128
|
+
search_lang: trimmedText(input.search_lang),
|
|
129
|
+
ui_lang: trimmedText(input.ui_lang),
|
|
130
|
+
country: trimmedText(input.country),
|
|
131
|
+
safesearch: trimmedText(input.safesearch),
|
|
132
|
+
count: input.count,
|
|
133
|
+
offset: input.offset,
|
|
134
|
+
spellcheck: input.spellcheck,
|
|
135
|
+
freshness: trimmedText(input.freshness),
|
|
136
|
+
extra_snippets: input.extra_snippets,
|
|
137
|
+
goggles: goggles(input.goggles),
|
|
138
|
+
operators: input.operators,
|
|
139
|
+
include_fetch_metadata: input.include_fetch_metadata
|
|
140
|
+
});
|
|
141
|
+
return normalizeCollection(payload, false);
|
|
142
|
+
}
|
|
143
|
+
async function videoSearch(input, ctx) {
|
|
144
|
+
const payload = await request(ctx, "/res/v1/videos/search", {
|
|
145
|
+
q: searchTerm(input.q),
|
|
146
|
+
search_lang: trimmedText(input.search_lang),
|
|
147
|
+
ui_lang: trimmedText(input.ui_lang),
|
|
148
|
+
country: trimmedText(input.country),
|
|
149
|
+
safesearch: trimmedText(input.safesearch),
|
|
150
|
+
count: input.count,
|
|
151
|
+
offset: input.offset,
|
|
152
|
+
spellcheck: input.spellcheck,
|
|
153
|
+
freshness: trimmedText(input.freshness),
|
|
154
|
+
operators: input.operators,
|
|
155
|
+
include_fetch_metadata: input.include_fetch_metadata
|
|
156
|
+
});
|
|
157
|
+
return normalizeCollection(payload, true);
|
|
158
|
+
}
|
|
159
|
+
async function imageSearch(input, ctx) {
|
|
160
|
+
const payload = await request(ctx, "/res/v1/images/search", {
|
|
161
|
+
q: searchTerm(input.q),
|
|
162
|
+
search_lang: trimmedText(input.search_lang),
|
|
163
|
+
country: trimmedText(input.country),
|
|
164
|
+
safesearch: trimmedText(input.safesearch),
|
|
165
|
+
count: input.count,
|
|
166
|
+
spellcheck: input.spellcheck
|
|
167
|
+
});
|
|
168
|
+
return normalizeCollection(payload, true);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ../plugins/src/brave_search/schema.ts
|
|
172
|
+
import { z } from "zod/v4";
|
|
173
|
+
var webSearchInput = z.strictObject({
|
|
174
|
+
q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
|
|
175
|
+
search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
|
|
176
|
+
ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
|
|
177
|
+
country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
|
|
178
|
+
safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from web results.").optional(),
|
|
179
|
+
count: z.int().min(1).max(20).describe("The maximum number of web results to return.").optional(),
|
|
180
|
+
offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
|
|
181
|
+
spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
|
|
182
|
+
freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters web results by page age.").optional(),
|
|
183
|
+
result_filter: z.string().min(1).describe("A comma-delimited list of result types to include, such as web,news,videos,locations,discussions,faq,infobox,mixed,summarizer or rich.").optional(),
|
|
184
|
+
extra_snippets: z.boolean().describe("Whether Brave Search should return extra alternate snippets.").optional(),
|
|
185
|
+
goggles: z.union([z.string().min(1).describe("One goggle URL or inline definition."), z.array(z.string().min(1).describe("One goggle URL or inline definition.")).min(1).describe("Multiple goggles to apply to the search request.")]).describe("One or more Brave Search goggles used to rerank results.").optional(),
|
|
186
|
+
text_decorations: z.boolean().describe("Whether display strings should include decoration markers such as highlights.").optional(),
|
|
187
|
+
units: z.enum(["metric", "imperial"]).describe("The measurement units used for localized results.").optional(),
|
|
188
|
+
operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
|
|
189
|
+
include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
|
|
190
|
+
}).describe("Input parameters for a Brave Search web search request.");
|
|
191
|
+
var webSearchOutput = z.strictObject({
|
|
192
|
+
type: z.string().describe("The Brave Search response type."),
|
|
193
|
+
query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
|
|
194
|
+
web: z.looseObject({}).describe("Web result payload returned by Brave Search.").nullable().optional(),
|
|
195
|
+
news: z.looseObject({}).describe("News result payload returned by Brave Search.").nullable().optional(),
|
|
196
|
+
videos: z.looseObject({}).describe("Video result payload returned by Brave Search.").nullable().optional(),
|
|
197
|
+
locations: z.looseObject({}).describe("Location result payload returned by Brave Search.").nullable().optional(),
|
|
198
|
+
discussions: z.looseObject({}).describe("Discussion clusters returned by Brave Search.").nullable().optional(),
|
|
199
|
+
faq: z.looseObject({}).describe("Frequently asked questions returned by Brave Search.").nullable().optional(),
|
|
200
|
+
infobox: z.looseObject({}).describe("Infobox payload returned by Brave Search.").nullable().optional(),
|
|
201
|
+
mixed: z.looseObject({}).describe("Mixed ranking payload returned by Brave Search.").nullable().optional(),
|
|
202
|
+
summarizer: z.looseObject({}).describe("Summary metadata returned by Brave Search.").nullable().optional(),
|
|
203
|
+
rich: z.looseObject({}).describe("Rich result callback payload returned by Brave Search.").nullable().optional()
|
|
204
|
+
}).describe("A normalized Brave Search web search response.");
|
|
205
|
+
var newsSearchInput = z.strictObject({
|
|
206
|
+
q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
|
|
207
|
+
search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
|
|
208
|
+
ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
|
|
209
|
+
country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
|
|
210
|
+
safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from news results.").optional(),
|
|
211
|
+
count: z.int().min(1).max(50).describe("The maximum number of results to return.").optional(),
|
|
212
|
+
offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
|
|
213
|
+
spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
|
|
214
|
+
freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters news results by page age.").optional(),
|
|
215
|
+
extra_snippets: z.boolean().describe("Whether Brave Search should return extra alternate snippets.").optional(),
|
|
216
|
+
goggles: z.union([z.string().min(1).describe("One goggle URL or inline definition."), z.array(z.string().min(1).describe("One goggle URL or inline definition.")).min(1).describe("Multiple goggles to apply to the search request.")]).describe("One or more Brave Search goggles used to rerank results.").optional(),
|
|
217
|
+
operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
|
|
218
|
+
include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
|
|
219
|
+
}).describe("Input parameters for a Brave Search news request.");
|
|
220
|
+
var newsSearchOutput = z.strictObject({
|
|
221
|
+
type: z.string().describe("The Brave Search response type."),
|
|
222
|
+
query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
|
|
223
|
+
results: z.array(z.looseObject({}).describe("One news result item returned by Brave Search.")).describe("The list of news results returned by Brave Search.").optional()
|
|
224
|
+
}).describe("A normalized Brave Search news response.");
|
|
225
|
+
var videoSearchInput = z.strictObject({
|
|
226
|
+
q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
|
|
227
|
+
search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
|
|
228
|
+
ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
|
|
229
|
+
country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
|
|
230
|
+
safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from video results.").optional(),
|
|
231
|
+
count: z.int().min(1).max(50).describe("The maximum number of results to return.").optional(),
|
|
232
|
+
offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
|
|
233
|
+
spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
|
|
234
|
+
freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters video results by page age.").optional(),
|
|
235
|
+
operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
|
|
236
|
+
include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
|
|
237
|
+
}).describe("Input parameters for a Brave Search video request.");
|
|
238
|
+
var videoSearchOutput = z.strictObject({
|
|
239
|
+
type: z.string().describe("The Brave Search response type."),
|
|
240
|
+
query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
|
|
241
|
+
results: z.array(z.looseObject({}).describe("One video result item returned by Brave Search.")).describe("The list of video results returned by Brave Search.").optional(),
|
|
242
|
+
extra: z.looseObject({}).describe("Additional metadata returned with the video results.").nullable().optional()
|
|
243
|
+
}).describe("A normalized Brave Search video response.");
|
|
244
|
+
var imageSearchInput = z.strictObject({
|
|
245
|
+
q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
|
|
246
|
+
search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
|
|
247
|
+
country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
|
|
248
|
+
safesearch: z.enum(["off", "strict"]).describe("Filters adult content from image results.").optional(),
|
|
249
|
+
count: z.int().min(1).max(200).describe("The maximum number of image results to return.").optional(),
|
|
250
|
+
spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional()
|
|
251
|
+
}).describe("Input parameters for a Brave Search image request.");
|
|
252
|
+
var imageSearchOutput = z.strictObject({
|
|
253
|
+
type: z.string().describe("The Brave Search response type."),
|
|
254
|
+
query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
|
|
255
|
+
results: z.array(z.looseObject({}).describe("One image result item returned by Brave Search.")).describe("The list of image results returned by Brave Search.").optional(),
|
|
256
|
+
extra: z.looseObject({}).describe("Additional metadata returned with the image results.").nullable().optional()
|
|
257
|
+
}).describe("A normalized Brave Search image response.");
|
|
258
|
+
var braveSearchActions = {
|
|
259
|
+
web_search: {
|
|
260
|
+
description: "Search the Brave Search web index and return the selected result families.",
|
|
261
|
+
effect: "write",
|
|
262
|
+
inputSchema: webSearchInput,
|
|
263
|
+
outputSchema: z.toJSONSchema(webSearchOutput, { io: "output", unrepresentable: "any" })
|
|
264
|
+
},
|
|
265
|
+
news_search: {
|
|
266
|
+
description: "Search Brave's news index for recent articles related to a query.",
|
|
267
|
+
effect: "write",
|
|
268
|
+
inputSchema: newsSearchInput,
|
|
269
|
+
outputSchema: z.toJSONSchema(newsSearchOutput, { io: "output", unrepresentable: "any" })
|
|
270
|
+
},
|
|
271
|
+
video_search: {
|
|
272
|
+
description: "Search Brave's video index for videos related to a query.",
|
|
273
|
+
effect: "write",
|
|
274
|
+
inputSchema: videoSearchInput,
|
|
275
|
+
outputSchema: z.toJSONSchema(videoSearchOutput, { io: "output", unrepresentable: "any" })
|
|
276
|
+
},
|
|
277
|
+
image_search: {
|
|
278
|
+
description: "Search Brave's image index for images related to a query.",
|
|
279
|
+
effect: "write",
|
|
280
|
+
inputSchema: imageSearchInput,
|
|
281
|
+
outputSchema: z.toJSONSchema(imageSearchOutput, { io: "output", unrepresentable: "any" })
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
// ../plugins/src/brave_search/index.ts
|
|
286
|
+
function createBraveSearchPlugin() {
|
|
287
|
+
return createProviderPlugin({
|
|
288
|
+
description: "Brave Search",
|
|
289
|
+
actions: braveSearchActions,
|
|
290
|
+
handlers: {
|
|
291
|
+
web_search: webSearch,
|
|
292
|
+
news_search: newsSearch,
|
|
293
|
+
video_search: videoSearch,
|
|
294
|
+
image_search: imageSearch
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
var brave_search_default = createBraveSearchPlugin();
|
|
299
|
+
export {
|
|
300
|
+
createBraveSearchPlugin,
|
|
301
|
+
brave_search_default as default
|
|
302
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TBError
|
|
3
|
+
} from "./chunk-5ICRY3VU.js";
|
|
4
|
+
|
|
5
|
+
// ../plugins/src/_runtime/ipPolicy.ts
|
|
6
|
+
import ipaddr from "ipaddr.js";
|
|
7
|
+
function isStrictIpv4(value) {
|
|
8
|
+
return ipaddr.IPv4.isValidFourPartDecimal(value) && value.split(".").every((part) => part === "0" || !part.startsWith("0"));
|
|
9
|
+
}
|
|
10
|
+
function parseAddress(value) {
|
|
11
|
+
let text = value;
|
|
12
|
+
if (text.startsWith("[") && text.endsWith("]")) text = text.slice(1, -1);
|
|
13
|
+
const embeddedIpv4 = text.includes(".") ? text.slice(text.lastIndexOf(":") + 1) : void 0;
|
|
14
|
+
if (embeddedIpv4 !== void 0 && !isStrictIpv4(embeddedIpv4)) return void 0;
|
|
15
|
+
try {
|
|
16
|
+
if (isStrictIpv4(text)) return ipaddr.IPv4.parse(text);
|
|
17
|
+
if (ipaddr.IPv6.isValid(text)) return ipaddr.IPv6.parse(text);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
function classifyIpv4(octets) {
|
|
23
|
+
const a = octets[0];
|
|
24
|
+
const b = octets[1];
|
|
25
|
+
const c = octets[2];
|
|
26
|
+
if (a === 0) return "blocked";
|
|
27
|
+
if (a === 10) return "blocked";
|
|
28
|
+
if (a === 127) return "blocked";
|
|
29
|
+
if (a === 169 && b === 254) return "blocked";
|
|
30
|
+
if (a === 172 && b >= 16 && b <= 31) return "blocked";
|
|
31
|
+
if (a === 192 && b === 0 && c === 0) return "blocked";
|
|
32
|
+
if (a === 192 && b === 0 && c === 2) return "blocked";
|
|
33
|
+
if (a === 192 && b === 168) return "blocked";
|
|
34
|
+
if (a === 198 && (b === 18 || b === 19)) return "blocked";
|
|
35
|
+
if (a === 198 && b === 51 && c === 100) return "blocked";
|
|
36
|
+
if (a === 203 && b === 0 && c === 113) return "blocked";
|
|
37
|
+
if (a === 100 && b >= 64 && b <= 127) return "blocked";
|
|
38
|
+
if (a >= 224) return "blocked";
|
|
39
|
+
return "public";
|
|
40
|
+
}
|
|
41
|
+
function classifyIpv6(bytes) {
|
|
42
|
+
const isZero = bytes.every((byte) => byte === 0);
|
|
43
|
+
if (isZero) return "blocked";
|
|
44
|
+
if (bytes.slice(0, 15).every((byte) => byte === 0) && bytes[15] === 1) return "blocked";
|
|
45
|
+
const v4Mapped = bytes.slice(0, 10).every((byte) => byte === 0) && (bytes[10] === 255 && bytes[11] === 255 || bytes[10] === 0 && bytes[11] === 0);
|
|
46
|
+
if (v4Mapped) {
|
|
47
|
+
return classifyIpv4([bytes[12], bytes[13], bytes[14], bytes[15]]);
|
|
48
|
+
}
|
|
49
|
+
const first = bytes[0];
|
|
50
|
+
if ((first & 254) === 252) return "blocked";
|
|
51
|
+
if (first === 254 && (bytes[1] & 192) === 128) return "blocked";
|
|
52
|
+
if (first === 255) return "blocked";
|
|
53
|
+
if (first === 32 && bytes[1] === 1 && bytes[2] === 13 && bytes[3] === 184) return "blocked";
|
|
54
|
+
return "public";
|
|
55
|
+
}
|
|
56
|
+
function isIpAddress(value) {
|
|
57
|
+
return parseAddress(value) !== void 0;
|
|
58
|
+
}
|
|
59
|
+
function classifyIpAddress(address) {
|
|
60
|
+
const parsed = parseAddress(address);
|
|
61
|
+
if (parsed === void 0) return "blocked";
|
|
62
|
+
if (parsed instanceof ipaddr.IPv4) return classifyIpv4(parsed.octets);
|
|
63
|
+
const bytes = new Uint8Array(parsed.toByteArray());
|
|
64
|
+
if (parsed.isIPv4MappedAddress()) return classifyIpv4(parsed.toIPv4Address().octets);
|
|
65
|
+
return classifyIpv6(bytes);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ../plugins/src/_runtime/guardedFetch.ts
|
|
69
|
+
var MAX_REDIRECTS = 5;
|
|
70
|
+
var CROSS_ORIGIN_STRIPPED_HEADERS = [
|
|
71
|
+
"authorization",
|
|
72
|
+
"cookie",
|
|
73
|
+
"proxy-authorization"
|
|
74
|
+
// 各家自定义的密钥头没有统一命名,凡是名字里带 key/token/secret 的一律剥掉:
|
|
75
|
+
// 宁可让跨源跳转少带一个无关头,也不能漏带走一个凭证。
|
|
76
|
+
];
|
|
77
|
+
var REQUEST_BODY_HEADERS = [
|
|
78
|
+
"content-encoding",
|
|
79
|
+
"content-language",
|
|
80
|
+
"content-location",
|
|
81
|
+
"content-type"
|
|
82
|
+
];
|
|
83
|
+
function looksLikeCredentialHeader(name) {
|
|
84
|
+
return /(?:^|-)(?:api[-_]?key|key|token|secret|auth)(?:$|-)/i.test(name);
|
|
85
|
+
}
|
|
86
|
+
function stripCredentials(headers, sensitiveHeaders) {
|
|
87
|
+
const next = new Headers(headers);
|
|
88
|
+
for (const [name] of headers) {
|
|
89
|
+
if (CROSS_ORIGIN_STRIPPED_HEADERS.includes(name.toLowerCase()) || looksLikeCredentialHeader(name) || sensitiveHeaders.has(name.toLowerCase())) {
|
|
90
|
+
next.delete(name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return next;
|
|
94
|
+
}
|
|
95
|
+
var EgressBlockedError = class extends TBError {
|
|
96
|
+
constructor(message) {
|
|
97
|
+
super("invalid_argument", message);
|
|
98
|
+
this.name = "EgressBlockedError";
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
function assertPublicHttpUrl(value) {
|
|
102
|
+
let url;
|
|
103
|
+
try {
|
|
104
|
+
url = value instanceof URL ? value : new URL(value);
|
|
105
|
+
} catch {
|
|
106
|
+
throw new EgressBlockedError(`\u51FA\u7AD9\u76EE\u6807\u4E0D\u662F\u5408\u6CD5 URL: ${String(value)}`);
|
|
107
|
+
}
|
|
108
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
109
|
+
throw new EgressBlockedError(`\u51FA\u7AD9\u76EE\u6807\u534F\u8BAE\u4E0D\u88AB\u5141\u8BB8: ${url.protocol}`);
|
|
110
|
+
}
|
|
111
|
+
const hostname = url.hostname.startsWith("[") && url.hostname.endsWith("]") ? url.hostname.slice(1, -1) : url.hostname;
|
|
112
|
+
if (hostname === "") throw new EgressBlockedError("\u51FA\u7AD9\u76EE\u6807\u7F3A\u5C11\u4E3B\u673A\u540D");
|
|
113
|
+
if (isIpAddress(hostname) && classifyIpAddress(hostname) === "blocked") {
|
|
114
|
+
throw new EgressBlockedError("\u51FA\u7AD9\u76EE\u6807\u6307\u5411\u79C1\u6709\u6216\u4FDD\u7559\u5730\u5740");
|
|
115
|
+
}
|
|
116
|
+
return url;
|
|
117
|
+
}
|
|
118
|
+
function createGuardedFetch(options = {}) {
|
|
119
|
+
const crossOriginRedirect = options.crossOriginRedirect ?? "error";
|
|
120
|
+
const maxRedirects = options.maxRedirects ?? MAX_REDIRECTS;
|
|
121
|
+
const sensitiveHeaders = new Set(
|
|
122
|
+
(options.sensitiveHeaders ?? []).map((name) => name.toLowerCase())
|
|
123
|
+
);
|
|
124
|
+
return async function guardedFetch2(input, init) {
|
|
125
|
+
const transport = options.fetch ?? globalThis.fetch;
|
|
126
|
+
const initial = input instanceof Request ? input.url : String(input);
|
|
127
|
+
let url = assertPublicHttpUrl(initial);
|
|
128
|
+
let request = input instanceof Request ? new Request(url, new Request(input, init)) : new Request(url, { ...init, redirect: "manual" });
|
|
129
|
+
for (let hop = 0; ; hop += 1) {
|
|
130
|
+
const response = await transport(new Request(request.clone(), { redirect: "manual" }));
|
|
131
|
+
const location = response.headers.get("location");
|
|
132
|
+
if (response.status < 300 || response.status > 399 || location === null) return response;
|
|
133
|
+
if (hop >= maxRedirects) {
|
|
134
|
+
throw new EgressBlockedError(`\u51FA\u7AD9\u91CD\u5B9A\u5411\u8D85\u8FC7 ${maxRedirects} \u8DF3`);
|
|
135
|
+
}
|
|
136
|
+
const previousOrigin = new URL(request.url).origin;
|
|
137
|
+
url = assertPublicHttpUrl(new URL(location, url));
|
|
138
|
+
const crossesOrigin = url.origin !== previousOrigin;
|
|
139
|
+
if (crossesOrigin && crossOriginRedirect === "error") {
|
|
140
|
+
throw new EgressBlockedError("\u643A\u5E26\u654F\u611F\u4FE1\u606F\u7684\u51FA\u7AD9\u8BF7\u6C42\u4E0D\u5141\u8BB8\u8DE8\u6E90\u91CD\u5B9A\u5411");
|
|
141
|
+
}
|
|
142
|
+
const headers = !crossesOrigin ? request.headers : stripCredentials(request.headers, sensitiveHeaders);
|
|
143
|
+
const downgrade = (response.status === 301 || response.status === 302) && request.method === "POST" || response.status === 303 && request.method !== "GET" && request.method !== "HEAD";
|
|
144
|
+
if (downgrade) {
|
|
145
|
+
const redirectedHeaders = new Headers(headers);
|
|
146
|
+
for (const name of REQUEST_BODY_HEADERS) redirectedHeaders.delete(name);
|
|
147
|
+
request = new Request(url, { method: "GET", headers: redirectedHeaders, redirect: "manual" });
|
|
148
|
+
} else {
|
|
149
|
+
const redirected = new Request(url, request);
|
|
150
|
+
request = crossesOrigin ? new Request(redirected, { headers, redirect: "manual" }) : redirected;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
var guardedFetch = createGuardedFetch();
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
assertPublicHttpUrl,
|
|
159
|
+
createGuardedFetch,
|
|
160
|
+
guardedFetch
|
|
161
|
+
};
|