@oomol-lab/open-connector 1.6.4 → 1.7.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.
Files changed (320) hide show
  1. package/assets/open-connector/catalog/apps/aisa.json +6394 -0
  2. package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
  3. package/assets/open-connector/catalog/apps/bilibili.json +2586 -0
  4. package/assets/open-connector/catalog/apps/bitwarden.json +1423 -0
  5. package/assets/open-connector/catalog/apps/cronfree.json +303 -0
  6. package/assets/open-connector/catalog/apps/cufinder.json +368 -0
  7. package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
  8. package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
  9. package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
  10. package/assets/open-connector/catalog/apps/framejet.json +273 -0
  11. package/assets/open-connector/catalog/apps/futunn.json +2967 -0
  12. package/assets/open-connector/catalog/apps/gmail.json +298 -0
  13. package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
  14. package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
  15. package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
  16. package/assets/open-connector/catalog/apps/googlecalendar.json +4 -1
  17. package/assets/open-connector/catalog/apps/googlechat.json +694 -7
  18. package/assets/open-connector/catalog/apps/googledocs.json +4 -1
  19. package/assets/open-connector/catalog/apps/googlesheets.json +4 -1
  20. package/assets/open-connector/catalog/apps/granola.json +23 -0
  21. package/assets/open-connector/catalog/apps/investoday_mcp.json +22228 -197
  22. package/assets/open-connector/catalog/apps/ixspy.json +2274 -0
  23. package/assets/open-connector/catalog/apps/keepa.json +3534 -987
  24. package/assets/open-connector/catalog/apps/linear.json +17 -0
  25. package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
  26. package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
  27. package/assets/open-connector/catalog/apps/notion.json +446 -1
  28. package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
  29. package/assets/open-connector/catalog/apps/odoo.json +619 -0
  30. package/assets/open-connector/catalog/apps/osv.json +663 -0
  31. package/assets/open-connector/catalog/apps/outlook.json +30 -8
  32. package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
  33. package/assets/open-connector/catalog/apps/pdf_vector.json +329 -0
  34. package/assets/open-connector/catalog/apps/postiz.json +334 -0
  35. package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
  36. package/assets/open-connector/catalog/apps/pulsetic.json +406 -0
  37. package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
  38. package/assets/open-connector/catalog/apps/shopee.json +1785 -0
  39. package/assets/open-connector/catalog/apps/slack.json +304 -0
  40. package/assets/open-connector/catalog/apps/slackbot.json +295 -0
  41. package/assets/open-connector/catalog/apps/speak_ai.json +360 -0
  42. package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
  43. package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
  44. package/assets/open-connector/catalog/apps/youtube.json +4 -1
  45. package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
  46. package/assets/open-connector/catalog/apps/zyhub.json +1585 -0
  47. package/assets/open-connector/catalog/apps-index.json +1 -1
  48. package/package.json +1 -1
  49. package/src/core/cast.d.ts +10 -0
  50. package/src/core/cast.js +14 -0
  51. package/src/core/guarded-fetch.d.ts +6 -3
  52. package/src/core/guarded-fetch.js +6 -3
  53. package/src/core/json-schema.d.ts +5 -1
  54. package/src/core/json-schema.js +14 -2
  55. package/src/core/provider-scenarios.js +67 -13
  56. package/src/core/request.js +4 -1
  57. package/src/core/types.d.ts +10 -1
  58. package/src/mcp.js +10 -7
  59. package/src/oauth/oauth-client-config-service.d.ts +16 -1
  60. package/src/oauth/oauth-client-config-service.js +59 -3
  61. package/src/oauth/oauth-credential-refresh-service.js +3 -1
  62. package/src/oauth/oauth-flow-service.d.ts +6 -0
  63. package/src/oauth/oauth-flow-service.js +21 -4
  64. package/src/oauth/oauth-token.d.ts +13 -0
  65. package/src/providers/17track/runtime.js +1 -1
  66. package/src/providers/action-contracts.generated.d.ts +32 -8
  67. package/src/providers/aifinmarket/runtime.js +1 -1
  68. package/src/providers/aisa/executors.d.ts +4 -0
  69. package/src/providers/aisa/executors.js +864 -0
  70. package/src/providers/aliyun_ack/runtime.js +1 -1
  71. package/src/providers/aliyun_sls/runtime.js +1 -1
  72. package/src/providers/app_store_server/runtime-helpers.js +1 -1
  73. package/src/providers/baizhi_mcp/actions.d.ts +2 -0
  74. package/src/providers/baizhi_mcp/actions.js +40 -0
  75. package/src/providers/baizhi_mcp/executors.d.ts +3 -0
  76. package/src/providers/baizhi_mcp/executors.js +102 -0
  77. package/src/providers/bazhuayu/runtime.js +2 -2
  78. package/src/providers/bilibili/articles.d.ts +3 -0
  79. package/src/providers/bilibili/articles.js +369 -0
  80. package/src/providers/bilibili/executors.d.ts +8 -0
  81. package/src/providers/bilibili/executors.js +262 -0
  82. package/src/providers/bilibili/runtime.d.ts +95 -0
  83. package/src/providers/bilibili/runtime.js +236 -0
  84. package/src/providers/bilibili/upload.d.ts +14 -0
  85. package/src/providers/bilibili/upload.js +107 -0
  86. package/src/providers/bitwarden/executors.d.ts +3 -0
  87. package/src/providers/bitwarden/executors.js +146 -0
  88. package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
  89. package/src/providers/cloudflare_dns/executors.js +1 -1
  90. package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
  91. package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
  92. package/src/providers/cloudflare_dns/runtime.js +1 -1
  93. package/src/providers/cloudflare_r2/executors.js +1 -1
  94. package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
  95. package/src/providers/cloudflare_r2/runtime.js +1 -1
  96. package/src/providers/cloudflare_worker/executors.js +1 -1
  97. package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
  98. package/src/providers/cloudflare_worker/runtime.js +1 -1
  99. package/src/providers/cronfree/executors.d.ts +4 -0
  100. package/src/providers/cronfree/executors.js +89 -0
  101. package/src/providers/cufinder/executors.d.ts +4 -0
  102. package/src/providers/cufinder/executors.js +105 -0
  103. package/src/providers/dingtalk_mcp/runtime.js +1 -1
  104. package/src/providers/discordbot/executors.d.ts +0 -9
  105. package/src/providers/discordbot/executors.js +9 -101
  106. package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
  107. package/src/providers/discordbot/runtime-guilds.js +464 -0
  108. package/src/providers/discordbot/runtime.d.ts +42 -0
  109. package/src/providers/discordbot/runtime.js +124 -0
  110. package/src/providers/drawio_mcp/executors.d.ts +3 -0
  111. package/src/providers/drawio_mcp/executors.js +19 -0
  112. package/src/providers/drawio_mcp/runtime.d.ts +8 -0
  113. package/src/providers/drawio_mcp/runtime.js +175 -0
  114. package/src/providers/elevenreader/runtime.js +6 -5
  115. package/src/providers/fastmoss_mcp/executors.js +2 -2
  116. package/src/providers/finchina/executors.js +1 -1
  117. package/src/providers/framejet/executors.d.ts +4 -0
  118. package/src/providers/framejet/executors.js +19 -0
  119. package/src/providers/framejet/runtime.d.ts +16 -0
  120. package/src/providers/framejet/runtime.js +148 -0
  121. package/src/providers/futunn/actions.d.ts +2 -0
  122. package/src/providers/futunn/actions.js +152 -0
  123. package/src/providers/futunn/actions.research.d.ts +2 -0
  124. package/src/providers/futunn/actions.research.js +423 -0
  125. package/src/providers/futunn/actions.trading.d.ts +2 -0
  126. package/src/providers/futunn/actions.trading.js +204 -0
  127. package/src/providers/futunn/executors.d.ts +3 -0
  128. package/src/providers/futunn/executors.js +24 -0
  129. package/src/providers/futunn/runtime-research.d.ts +3 -0
  130. package/src/providers/futunn/runtime-research.js +133 -0
  131. package/src/providers/futunn/runtime-trading.d.ts +3 -0
  132. package/src/providers/futunn/runtime-trading.js +39 -0
  133. package/src/providers/futunn/runtime.d.ts +2 -0
  134. package/src/providers/futunn/runtime.js +50 -0
  135. package/src/providers/futunn/transport.d.ts +11 -0
  136. package/src/providers/futunn/transport.js +76 -0
  137. package/src/providers/gildata/executors.js +1 -1
  138. package/src/providers/gmail/attachment-stream.d.ts +2 -0
  139. package/src/providers/gmail/attachment-stream.js +162 -0
  140. package/src/providers/gmail/executors.d.ts +3 -1
  141. package/src/providers/gmail/executors.js +54 -26
  142. package/src/providers/gmail/message.d.ts +6 -8
  143. package/src/providers/gmail/message.js +4 -0
  144. package/src/providers/gmail/scopes.d.ts +32 -0
  145. package/src/providers/gmail/scopes.js +37 -0
  146. package/src/providers/google_analytics/executors.js +2 -2
  147. package/src/providers/google_analytics/scopes.js +6 -1
  148. package/src/providers/google_bigquery/executors.js +2 -2
  149. package/src/providers/google_bigquery/scopes.js +2 -0
  150. package/src/providers/google_search_console/executors.js +2 -2
  151. package/src/providers/google_search_console/scopes.js +2 -0
  152. package/src/providers/googleads/executors.js +1 -1
  153. package/src/providers/googleads/scopes.d.ts +1 -3
  154. package/src/providers/googleads/scopes.js +2 -4
  155. package/src/providers/googlecalendar/executors.js +1 -1
  156. package/src/providers/googlecalendar/runtime-shared.js +2 -2
  157. package/src/providers/googlecalendar/scopes.js +2 -0
  158. package/src/providers/googlechat/executors.d.ts +1 -3
  159. package/src/providers/googlechat/executors.js +219 -28
  160. package/src/providers/googlechat/members.d.ts +55 -0
  161. package/src/providers/googlechat/members.js +293 -0
  162. package/src/providers/googlechat/runtime.d.ts +16 -0
  163. package/src/providers/googlechat/runtime.js +25 -0
  164. package/src/providers/googlechat/scopes.d.ts +22 -3
  165. package/src/providers/googlechat/scopes.js +30 -7
  166. package/src/providers/googledocs/executors.js +1 -1
  167. package/src/providers/googledrive/executors.js +2 -2
  168. package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
  169. package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
  170. package/src/providers/googledrive/runtime-collaboration.js +1 -1
  171. package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
  172. package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
  173. package/src/providers/googleforms/executors.js +2 -2
  174. package/src/providers/googleforms/scopes.d.ts +0 -3
  175. package/src/providers/googleforms/scopes.js +2 -6
  176. package/src/providers/googlemeet/executors.js +2 -2
  177. package/src/providers/googlemeet/scopes.d.ts +0 -3
  178. package/src/providers/googlemeet/scopes.js +2 -6
  179. package/src/providers/googlesheets/executors.js +1 -1
  180. package/src/providers/googlesheets/scopes.js +2 -0
  181. package/src/providers/googleslides/executors.js +2 -2
  182. package/src/providers/googleslides/scopes.d.ts +0 -3
  183. package/src/providers/googleslides/scopes.js +2 -6
  184. package/src/providers/googletasks/executors.js +2 -2
  185. package/src/providers/googletasks/scopes.d.ts +0 -3
  186. package/src/providers/googletasks/scopes.js +2 -6
  187. package/src/providers/granola/actions.js +2 -0
  188. package/src/providers/granola/runtime-mcp.js +2 -0
  189. package/src/providers/granola/runtime.js +2 -2
  190. package/src/providers/indiegogo/executors.js +1 -1
  191. package/src/providers/investoday_mcp/executors.js +2 -2
  192. package/src/providers/investoday_mcp/official-actions.js +19 -372
  193. package/src/providers/investoday_mcp/official-tool-types.d.ts +10 -0
  194. package/src/providers/investoday_mcp/official-tool-types.js +4 -0
  195. package/src/providers/investoday_mcp/official-tools/charts.d.ts +2 -0
  196. package/src/providers/investoday_mcp/official-tools/charts.js +32 -0
  197. package/src/providers/investoday_mcp/official-tools/fixed-income.d.ts +2 -0
  198. package/src/providers/investoday_mcp/official-tools/fixed-income.js +326 -0
  199. package/src/providers/investoday_mcp/official-tools/funds.d.ts +2 -0
  200. package/src/providers/investoday_mcp/official-tools/funds.js +1085 -0
  201. package/src/providers/investoday_mcp/official-tools/hong-kong.d.ts +2 -0
  202. package/src/providers/investoday_mcp/official-tools/hong-kong.js +275 -0
  203. package/src/providers/investoday_mcp/official-tools/indices-industries.d.ts +2 -0
  204. package/src/providers/investoday_mcp/official-tools/indices-industries.js +642 -0
  205. package/src/providers/investoday_mcp/official-tools/macro-calendar.d.ts +2 -0
  206. package/src/providers/investoday_mcp/official-tools/macro-calendar.js +398 -0
  207. package/src/providers/investoday_mcp/official-tools/other.d.ts +2 -0
  208. package/src/providers/investoday_mcp/official-tools/other.js +131 -0
  209. package/src/providers/investoday_mcp/official-tools/research-news.d.ts +2 -0
  210. package/src/providers/investoday_mcp/official-tools/research-news.js +302 -0
  211. package/src/providers/investoday_mcp/official-tools/stocks.d.ts +2 -0
  212. package/src/providers/investoday_mcp/official-tools/stocks.js +2829 -0
  213. package/src/providers/ixspy/executors.d.ts +3 -0
  214. package/src/providers/ixspy/executors.js +220 -0
  215. package/src/providers/iyunbiao/runtime.js +2 -2
  216. package/src/providers/keepa/actions.d.ts +1 -1
  217. package/src/providers/keepa/actions.js +371 -149
  218. package/src/providers/keepa/deal-attributes.d.ts +1 -0
  219. package/src/providers/keepa/deal-attributes.js +26 -0
  220. package/src/providers/keepa/runtime.js +212 -18
  221. package/src/providers/kingdee/executors.js +1 -1
  222. package/src/providers/kingdee/runtime.js +2 -2
  223. package/src/providers/kuaidi100/runtime.js +1 -1
  224. package/src/providers/linear/executors.js +12 -9
  225. package/src/providers/linear_mcp/actions.d.ts +47 -0
  226. package/src/providers/linear_mcp/actions.js +102 -0
  227. package/src/providers/linear_mcp/endpoints.d.ts +3 -0
  228. package/src/providers/linear_mcp/endpoints.js +3 -0
  229. package/src/providers/linear_mcp/executors.d.ts +3 -0
  230. package/src/providers/linear_mcp/executors.js +9 -0
  231. package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
  232. package/src/providers/linear_mcp/runtime-mcp.js +238 -0
  233. package/src/providers/lingxing_mcp/runtime.js +1 -1
  234. package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
  235. package/src/providers/metabase/mcp-runtime.js +1 -1
  236. package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
  237. package/src/providers/moneyforward_mcp/executors.js +11 -0
  238. package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
  239. package/src/providers/moneyforward_mcp/manifest.js +204 -0
  240. package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
  241. package/src/providers/moneyforward_mcp/runtime.js +296 -0
  242. package/src/providers/notion/executors.js +39 -3
  243. package/src/providers/notion_mcp/endpoints.d.ts +3 -0
  244. package/src/providers/notion_mcp/endpoints.js +3 -0
  245. package/src/providers/notion_mcp/executors.d.ts +3 -0
  246. package/src/providers/notion_mcp/executors.js +176 -0
  247. package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
  248. package/src/providers/notion_mcp/mcp-response.js +314 -0
  249. package/src/providers/odoo/executors.d.ts +3 -0
  250. package/src/providers/odoo/executors.js +32 -0
  251. package/src/providers/odoo/runtime.d.ts +16 -0
  252. package/src/providers/odoo/runtime.js +140 -0
  253. package/src/providers/osv/executors.d.ts +2 -0
  254. package/src/providers/osv/executors.js +11 -0
  255. package/src/providers/osv/runtime.d.ts +9 -0
  256. package/src/providers/osv/runtime.js +66 -0
  257. package/src/providers/outlook/executors.js +27 -6
  258. package/src/providers/outlook/microsoft-graph.js +17 -6
  259. package/src/providers/outlook_calendar/executors.js +24 -7
  260. package/src/providers/patsnap_mcp/executors.js +2 -2
  261. package/src/providers/pdf_vector/executors.d.ts +4 -0
  262. package/src/providers/pdf_vector/executors.js +108 -0
  263. package/src/providers/postiz/executors.d.ts +4 -0
  264. package/src/providers/postiz/executors.js +83 -0
  265. package/src/providers/provider-runtime.d.ts +18 -0
  266. package/src/providers/provider-runtime.js +60 -4
  267. package/src/providers/proworkflow/executors.d.ts +4 -0
  268. package/src/providers/proworkflow/executors.js +135 -0
  269. package/src/providers/pulsetic/executors.d.ts +4 -0
  270. package/src/providers/pulsetic/executors.js +126 -0
  271. package/src/providers/registry.generated.js +24 -0
  272. package/src/providers/scrape_creators/catalog.js +1 -1
  273. package/src/providers/scrape_creators/runtime.js +1 -1
  274. package/src/providers/sellersprite_mcp/executors.js +2 -2
  275. package/src/providers/sellersprite_mcp/official-actions.js +3 -2
  276. package/src/providers/sentry/runtime.js +6 -7
  277. package/src/providers/shopee/actions.d.ts +2 -0
  278. package/src/providers/shopee/actions.js +474 -0
  279. package/src/providers/shopee/executors.d.ts +3 -0
  280. package/src/providers/shopee/executors.js +85 -0
  281. package/src/providers/shopee/runtime.d.ts +79 -0
  282. package/src/providers/shopee/runtime.js +693 -0
  283. package/src/providers/slack/actions.js +69 -3
  284. package/src/providers/slack/runtime.js +116 -21
  285. package/src/providers/slickdeals/runtime.js +1 -1
  286. package/src/providers/sorftime_mcp/executors.js +2 -2
  287. package/src/providers/speak_ai/executors.d.ts +3 -0
  288. package/src/providers/speak_ai/executors.js +187 -0
  289. package/src/providers/tikhub/bounded-response.d.ts +1 -1
  290. package/src/providers/tikhub/bounded-response.js +8 -34
  291. package/src/providers/tikhub/endpoint-catalog.js +1 -1
  292. package/src/providers/tikhub/runtime.js +2 -2
  293. package/src/providers/tongdaxin/executors.js +79 -15
  294. package/src/providers/tushare/runtime.js +22 -9
  295. package/src/providers/uspto/executors.js +1 -1
  296. package/src/providers/waffo/executors.js +1 -1
  297. package/src/providers/waffo/runtime.js +1 -1
  298. package/src/providers/wecom_mcp/runtime.js +1 -1
  299. package/src/providers/wisburg/executors.d.ts +4 -0
  300. package/src/providers/wisburg/executors.js +13 -0
  301. package/src/providers/wisburg/runtime.d.ts +12 -0
  302. package/src/providers/wisburg/runtime.js +133 -0
  303. package/src/providers/xydc_mcp/executors.js +2 -2
  304. package/src/providers/youtube/executors.js +1 -1
  305. package/src/providers/youtube/runtime.js +1 -1
  306. package/src/providers/zerotier/executors.d.ts +9 -0
  307. package/src/providers/zerotier/executors.js +629 -0
  308. package/src/providers/zerotier/runtime.d.ts +54 -0
  309. package/src/providers/zerotier/runtime.js +207 -0
  310. package/src/providers/zyhub/executors.d.ts +3 -0
  311. package/src/providers/zyhub/executors.js +240 -0
  312. package/src/server/api/openapi.js +12 -2
  313. package/src/server/api/runtime-api.d.ts +8 -1
  314. package/src/server/api/runtime-api.js +19 -1
  315. package/src/server/connect-server.js +10 -2
  316. package/src/server/files/transit-files.d.ts +3 -2
  317. package/src/server/files/transit-files.js +31 -35
  318. package/src/providers/sentry/scopes.d.ts +0 -1
  319. package/src/providers/sentry/scopes.js +0 -7
  320. /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
@@ -1,44 +1,18 @@
1
+ import { readBoundedResponseBytes } from "../../core/request.js";
1
2
  import { TikHubRequestError } from "./errors.js";
2
3
  export class BoundedResponseTooLargeError extends TikHubRequestError {
3
4
  }
4
5
  export async function readBoundedResponseText(response, input) {
5
- const declaredLength = response.headers.get("content-length");
6
- if (declaredLength !== null) {
7
- const parsedLength = Number(declaredLength);
8
- if (Number.isFinite(parsedLength) && parsedLength > input.maxBytes) {
9
- await cancelResponseBody(response);
10
- throw responseTooLarge(input);
11
- }
12
- }
13
- if (!response.body) {
14
- return "";
15
- }
16
- const reader = response.body.getReader();
17
- const chunks = [];
18
- let totalBytes = 0;
19
- while (true) {
20
- const result = await reader.read();
21
- if (result.done) {
22
- break;
23
- }
24
- totalBytes += result.value.byteLength;
25
- if (totalBytes > input.maxBytes) {
26
- await reader.cancel();
27
- throw responseTooLarge(input);
28
- }
29
- chunks.push(result.value);
30
- }
31
- const bytes = new Uint8Array(totalBytes);
32
- let offset = 0;
33
- for (const chunk of chunks) {
34
- bytes.set(chunk, offset);
35
- offset += chunk.byteLength;
36
- }
6
+ const bytes = await readBoundedResponseBytes(response, {
7
+ maxBytes: input.maxBytes,
8
+ fieldName: input.label,
9
+ createError: () => responseTooLarge(input),
10
+ });
37
11
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
38
12
  }
39
- export async function cancelResponseBody(response) {
13
+ export function cancelResponseBody(response) {
40
14
  try {
41
- await response.body?.cancel();
15
+ void response.body?.cancel().catch(() => undefined);
42
16
  }
43
17
  catch {
44
18
  return;
@@ -105,7 +105,7 @@ async function fetchOpenApi(fetcher) {
105
105
  const response = await fetcher(tikhubOpenApiUrl, {
106
106
  method: "GET",
107
107
  headers: { accept: "application/json" },
108
- redirect: "error",
108
+ redirect: "manual",
109
109
  signal: timeout.signal,
110
110
  });
111
111
  if (!response.ok) {
@@ -166,7 +166,7 @@ async function invokeTikHubEndpoint(input, fetcher, apiKey) {
166
166
  "user-agent": providerUserAgent,
167
167
  },
168
168
  ...(serializedBody === undefined ? {} : { body: serializedBody }),
169
- redirect: "error",
169
+ redirect: "manual",
170
170
  signal: timeout.signal,
171
171
  });
172
172
  let responseBody;
@@ -454,7 +454,7 @@ async function requestTikHubUserJson(input) {
454
454
  authorization: `Bearer ${input.apiKey}`,
455
455
  "user-agent": providerUserAgent,
456
456
  },
457
- redirect: "error",
457
+ redirect: "manual",
458
458
  signal: timeout.signal,
459
459
  });
460
460
  const payload = await readTikHubResponseBody(response, tikhubDynamicResponseMaxBytes);
@@ -1,6 +1,7 @@
1
1
  import { ProtocolError, SdkHttpError, UnauthorizedError } from "@modelcontextprotocol/client";
2
2
  import { createHash } from "node:crypto";
3
- import { optionalRecord } from "../../core/cast.js";
3
+ import { optionalNumber, optionalRecord, optionalString } from "../../core/cast.js";
4
+ import { readBoundedResponseBytes } from "../../core/request.js";
4
5
  import { withMcpClient } from "../mcp-client.js";
5
6
  import { defineApiKeyProviderExecutors, providerUserAgent, ProviderRequestError, requiredInputString, } from "../provider-runtime.js";
6
7
  import { tongdaxinActions, tongdaxinReadOnlyToolNames } from "./actions.js";
@@ -9,10 +10,15 @@ import { isTongdaxinNamedActionName, resolveTongdaxinNamedToolCall } from "./nam
9
10
  const service = "tongdaxin";
10
11
  const endpoint = new URL("https://txmcp.tdx.com.cn:3001/txmcp");
11
12
  const requestTimeoutMs = 60_000;
13
+ const errorResponseMaxBytes = 64 * 1024;
14
+ const insufficientPointsToolError = "MCP error -32603: Your usage quota has been reached";
15
+ const insufficientPointsDescription = "TDX MCP quota is below 10. Please recharge before continuing.";
16
+ const rechargeOrigin = "https://vip.tdx.com.cn";
17
+ const rechargePath = "/site/app/pc-mall/main.html";
12
18
  const supportedToolNames = new Set(tongdaxinReadOnlyToolNames);
13
19
  const handlers = {
14
20
  async list_tools(_input, context) {
15
- return { tools: await discoverSupportedTools(context, "execute") };
21
+ return { tools: await discoverSupportedTools(context) };
16
22
  },
17
23
  async call_tool(input, context) {
18
24
  const toolName = requiredInputString(input.toolName, "toolName");
@@ -20,7 +26,8 @@ const handlers = {
20
26
  if (!argumentsValue)
21
27
  throw new ProviderRequestError(400, "arguments must be a JSON object");
22
28
  assertToolArgumentsSize(argumentsValue);
23
- const result = await withTongdaxinClient(context, "execute", false, (client) => client.callTool({ name: toolName, arguments: argumentsValue }, { timeout: requestTimeoutMs, signal: context.signal }));
29
+ const result = await withTongdaxinClient(context, false, (client) => client.callTool({ name: toolName, arguments: argumentsValue }, { timeout: requestTimeoutMs, signal: context.signal }));
30
+ assertSufficientTongdaxinCredit(result);
24
31
  if (!("toolResult" in result) && result.isError) {
25
32
  throw new ProviderRequestError(502, `Tongdaxin MCP tool ${toolName} returned an error`, result);
26
33
  }
@@ -37,7 +44,7 @@ for (const actionName of Object.keys(resolveNamedHandlers())) {
37
44
  throw new ProviderRequestError(400, `Unknown action: ${actionName}`);
38
45
  const toolCall = resolveTongdaxinNamedToolCall(actionName, input);
39
46
  assertToolArgumentsSize(toolCall.arguments);
40
- const tools = await discoverSupportedTools(context, "execute");
47
+ const tools = await discoverSupportedTools(context);
41
48
  const tool = tools.find((candidate) => candidate.name === toolCall.toolName);
42
49
  if (!tool && toolCall.toolName !== "wenda_macro_query") {
43
50
  throw new ProviderRequestError(409, `Tongdaxin action ${actionName} is unavailable because this connection does not expose ${toolCall.toolName}`);
@@ -48,7 +55,8 @@ for (const actionName of Object.keys(resolveNamedHandlers())) {
48
55
  tool.annotations.destructiveHint === true)) {
49
56
  throw new ProviderRequestError(403, `Tongdaxin MCP does not currently affirm ${tool.name} as a non-destructive read-only tool`);
50
57
  }
51
- const result = await withTongdaxinClient(context, "execute", true, (client) => client.callTool({ name: toolCall.toolName, arguments: toolCall.arguments }, { timeout: requestTimeoutMs, signal: context.signal }));
58
+ const result = await withTongdaxinClient(context, true, (client) => client.callTool({ name: toolCall.toolName, arguments: toolCall.arguments }, { timeout: requestTimeoutMs, signal: context.signal }));
59
+ assertSufficientTongdaxinCredit(result);
52
60
  if (!("toolResult" in result) && result.isError) {
53
61
  throw new ProviderRequestError(502, `Tongdaxin MCP tool ${toolCall.toolName} returned an error`, result);
54
62
  }
@@ -62,7 +70,7 @@ export const executors = defineApiKeyProviderExecutors(service, handlers, {
62
70
  export const credentialValidators = {
63
71
  async apiKey(input, { fetcher, signal }) {
64
72
  const context = { apiKey: input.apiKey, fetcher, signal };
65
- const tools = await discoverSupportedTools(context, "validate");
73
+ const tools = await discoverSupportedTools(context);
66
74
  if (tools.length === 0) {
67
75
  throw new ProviderRequestError(400, "Tongdaxin MCP did not expose any supported read-only tools");
68
76
  }
@@ -77,8 +85,8 @@ export const credentialValidators = {
77
85
  };
78
86
  },
79
87
  };
80
- async function discoverSupportedTools(context, phase) {
81
- const result = await withTongdaxinClient(context, phase, true, (client) => client.listTools({}, { timeout: requestTimeoutMs, signal: context.signal }));
88
+ async function discoverSupportedTools(context) {
89
+ const result = await withTongdaxinClient(context, true, (client) => client.listTools({}, { timeout: requestTimeoutMs, signal: context.signal }));
82
90
  return result.tools.map((tool) => ({
83
91
  name: tool.name,
84
92
  description: tool.description,
@@ -86,30 +94,30 @@ async function discoverSupportedTools(context, phase) {
86
94
  inputSchema: tool.inputSchema,
87
95
  }));
88
96
  }
89
- async function withTongdaxinClient(context, phase, retryOnSessionNotFound, run) {
97
+ async function withTongdaxinClient(context, retryOnSessionNotFound, run) {
90
98
  return withMcpClient({
91
99
  endpoint,
92
100
  transport: "streamable_http",
93
- fetcher: context.fetcher,
101
+ fetcher: createTongdaxinFetcher(context.fetcher),
94
102
  headers: {
95
103
  authorization: `Bearer ${context.apiKey}`,
96
104
  "user-agent": providerUserAgent,
97
105
  },
98
- redirect: "error",
106
+ redirect: "manual",
99
107
  signal: context.signal,
100
108
  retryOnSessionNotFound,
101
- mapError: (error) => mapTongdaxinError(error, phase),
109
+ mapError: mapTongdaxinError,
102
110
  }, run);
103
111
  }
104
- function mapTongdaxinError(error, phase) {
112
+ function mapTongdaxinError(error) {
105
113
  if (error instanceof ProviderRequestError)
106
114
  return error;
107
115
  if (error instanceof UnauthorizedError) {
108
- return new ProviderRequestError(phase === "validate" ? 400 : 401, "Tongdaxin API Key is invalid or expired");
116
+ return new ProviderRequestError(401, "Tongdaxin MCP denied this request");
109
117
  }
110
118
  if (error instanceof SdkHttpError) {
111
119
  if (error.status === 401) {
112
- return new ProviderRequestError(phase === "validate" ? 400 : 401, "Tongdaxin API Key is invalid or expired");
120
+ return new ProviderRequestError(401, "Tongdaxin MCP denied this request");
113
121
  }
114
122
  const status = 400 <= error.status && error.status < 500 ? error.status : 502;
115
123
  return new ProviderRequestError(status, `Tongdaxin MCP request failed: ${error.message}`, error);
@@ -119,6 +127,62 @@ function mapTongdaxinError(error, phase) {
119
127
  }
120
128
  return new ProviderRequestError(502, error instanceof Error ? `Tongdaxin MCP request failed: ${error.message}` : "Tongdaxin MCP request failed", error);
121
129
  }
130
+ function createTongdaxinFetcher(fetcher) {
131
+ return (async (...arguments_) => {
132
+ const response = await fetcher(...arguments_);
133
+ const details = await readInsufficientPoints(response);
134
+ if (details) {
135
+ void response.body?.cancel().catch(() => undefined);
136
+ throw insufficientCreditError(details);
137
+ }
138
+ return response;
139
+ });
140
+ }
141
+ async function readInsufficientPoints(response) {
142
+ if (response.status !== 401)
143
+ return undefined;
144
+ try {
145
+ const bytes = await readBoundedResponseBytes(response.clone(), {
146
+ maxBytes: errorResponseMaxBytes,
147
+ fieldName: "Tongdaxin MCP error response",
148
+ createError: (message) => new Error(message),
149
+ });
150
+ const payload = optionalRecord(JSON.parse(new TextDecoder().decode(bytes)));
151
+ const remainingCredit = optionalNumber(payload?.leftValue);
152
+ const rechargeUrl = optionalString(payload?.recharge_url);
153
+ if (payload?.error !== "unauthorized" ||
154
+ payload?.error_description !== insufficientPointsDescription ||
155
+ remainingCredit === undefined ||
156
+ !isOfficialRechargeUrl(rechargeUrl)) {
157
+ return undefined;
158
+ }
159
+ return { remainingCredit, rechargeUrl };
160
+ }
161
+ catch {
162
+ return undefined;
163
+ }
164
+ }
165
+ function isOfficialRechargeUrl(value) {
166
+ if (!value)
167
+ return false;
168
+ try {
169
+ const url = new URL(value);
170
+ return url.origin === rechargeOrigin && url.pathname === rechargePath;
171
+ }
172
+ catch {
173
+ return false;
174
+ }
175
+ }
176
+ function assertSufficientTongdaxinCredit(result) {
177
+ if (!("content" in result) || result.isError !== true)
178
+ return;
179
+ const exhausted = result.content.some((content) => content.type === "text" && content.text === insufficientPointsToolError);
180
+ if (exhausted)
181
+ throw insufficientCreditError();
182
+ }
183
+ function insufficientCreditError(details) {
184
+ return new ProviderRequestError(402, "Tongdaxin AI points are insufficient. Recharge the account before retrying.", details ?? { rechargeUrl: `${rechargeOrigin}${rechargePath}#/page_product_ai_jfb` }, "insufficient_credit");
185
+ }
122
186
  function resolveNamedHandlers() {
123
187
  return Object.fromEntries(tongdaxinActions
124
188
  .filter((action) => action.name !== "list_tools" && action.name !== "call_tool")
@@ -234,12 +234,18 @@ export const tushareActionHandlers = {
234
234
  },
235
235
  };
236
236
  export async function validateTushareCredential(apiKey, fetcher, signal) {
237
- const payload = await tushareRequest({
238
- apiName: "trade_cal",
239
- params: { exchange: "", start_date: "20180901", end_date: "20180902" },
240
- fields: "exchange,cal_date,is_open",
241
- }, { apiKey, fetcher, signal });
242
- normalizeTableData(payload.data);
237
+ try {
238
+ const payload = await tushareRequest({
239
+ apiName: "daily",
240
+ params: { ts_code: "000001.SZ", trade_date: "20180903" },
241
+ fields: "ts_code,trade_date",
242
+ }, { apiKey, fetcher, signal });
243
+ normalizeTableData(payload.data);
244
+ }
245
+ catch (error) {
246
+ if (!(error instanceof ProviderRequestError) || error.status !== 403)
247
+ throw error;
248
+ }
243
249
  return {
244
250
  profile: {
245
251
  accountId: "tushare-token",
@@ -248,7 +254,7 @@ export async function validateTushareCredential(apiKey, fetcher, signal) {
248
254
  grantedScopes: [],
249
255
  metadata: {
250
256
  apiBaseUrl: tushareApiBaseUrl,
251
- validationApiName: "trade_cal",
257
+ validationApiName: "daily",
252
258
  credentialHelpUrl: "https://tushare.pro/document/1?doc_id=39",
253
259
  },
254
260
  };
@@ -333,8 +339,10 @@ async function readJsonPayload(response) {
333
339
  }
334
340
  function createTushareHttpError(status, payload) {
335
341
  const message = extractErrorMessage(payload) ?? `Tushare request failed with ${status || 500}`;
336
- if (status === 401 || status === 403)
342
+ if (status === 401)
337
343
  return new ProviderRequestError(400, message, payload);
344
+ if (status === 403)
345
+ return new ProviderRequestError(403, message, payload);
338
346
  if (status === 429)
339
347
  return new ProviderRequestError(429, message, payload);
340
348
  return new ProviderRequestError(status || 502, message, payload);
@@ -343,12 +351,17 @@ function createTushareApiError(code, payload) {
343
351
  const message = `Tushare request failed: ${extractErrorMessage(payload) ?? `code ${code}`}`;
344
352
  if (code === 40101)
345
353
  return new ProviderRequestError(400, message, payload);
346
- if (code === 2002)
354
+ if (isTusharePermissionError(code, message))
347
355
  return new ProviderRequestError(403, message, payload);
348
356
  if (code === 2003 || code === 2004 || message.includes("频率超限"))
349
357
  return new ProviderRequestError(429, message, payload);
350
358
  return new ProviderRequestError(502, message, payload);
351
359
  }
360
+ function isTusharePermissionError(code, message) {
361
+ return (code === 2002 ||
362
+ message.includes("没有权限访问该接口") ||
363
+ (message.includes("没有接口(") && message.includes("访问权限")));
364
+ }
352
365
  function normalizeTableData(value) {
353
366
  const data = requiredResponseRecord(value, "data");
354
367
  return {
@@ -2,7 +2,7 @@ import { defineApiKeyProviderExecutors, defineProviderProxy, ProviderRequestErro
2
2
  async function get(path, accept, apiKey, fetcher, signal) {
3
3
  const response = await fetcher(new URL(path, "https://tsdrapi.uspto.gov"), {
4
4
  headers: { accept, "USPTO-API-KEY": apiKey, "user-agent": providerUserAgent },
5
- redirect: "error",
5
+ redirect: "manual",
6
6
  signal,
7
7
  });
8
8
  const text = await response.text();
@@ -37,7 +37,7 @@ export const proxy = async (input, context) => {
37
37
  method: input.method,
38
38
  headers,
39
39
  body: input.method === "GET" || input.body == null ? undefined : signingBody,
40
- redirect: "error",
40
+ redirect: "manual",
41
41
  signal: context.signal,
42
42
  });
43
43
  if (!response.ok) {
@@ -281,7 +281,7 @@ export async function requestWaffoJson(input) {
281
281
  method: "POST",
282
282
  headers,
283
283
  body,
284
- redirect: "error",
284
+ redirect: "manual",
285
285
  signal: timeout.signal,
286
286
  });
287
287
  const payload = await readProviderJsonBody(response, {
@@ -173,7 +173,7 @@ async function withWeComMcpClient(context, run) {
173
173
  transport: "streamable_http",
174
174
  fetcher: createWeComRateLimitedFetch(context.fetcher, hashWeComRateLimitKey(context)),
175
175
  headers,
176
- redirect: "error",
176
+ redirect: "manual",
177
177
  signal: context.signal,
178
178
  mapError: mapWeComMcpError,
179
179
  }, run);
@@ -0,0 +1,4 @@
1
+ import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
2
+ export declare const executors: ProviderExecutors;
3
+ export declare const proxy: ProviderProxyExecutor;
4
+ export declare const credentialValidators: CredentialValidators;
@@ -0,0 +1,13 @@
1
+ import { defineApiKeyProviderExecutors, defineProviderProxy } from "../provider-runtime.js";
2
+ import { validateWisburgCredential, wisburgActionHandlers, wisburgApiBaseUrl } from "./runtime.js";
3
+ const service = "wisburg";
4
+ export const executors = defineApiKeyProviderExecutors(service, wisburgActionHandlers, {
5
+ skipDnsValidation: true,
6
+ });
7
+ export const proxy = defineProviderProxy({
8
+ service,
9
+ baseUrl: wisburgApiBaseUrl,
10
+ auth: { type: "api_key_authorization", prefix: "Bearer " },
11
+ skipDnsValidation: true,
12
+ });
13
+ export const credentialValidators = { apiKey: validateWisburgCredential };
@@ -0,0 +1,12 @@
1
+ import type { CredentialValidationResult } from "../../core/types.ts";
2
+ import type { ApiKeyProviderContext, ProviderActionHandlers, ProviderRuntimeHandler } from "../provider-runtime.ts";
3
+ /** Output key a detail action nests its resource under. */
4
+ export type WisburgDetailKey = "report" | "article" | "log";
5
+ export declare const wisburgApiBaseUrl = "https://api-omen.wisburg.com";
6
+ export declare const wisburgActionHandlers: ProviderActionHandlers<"wisburg", ProviderRuntimeHandler<ApiKeyProviderContext>>;
7
+ export declare function validateWisburgCredential(input: {
8
+ apiKey: string;
9
+ }, { fetcher, signal }: {
10
+ fetcher: typeof fetch;
11
+ signal?: AbortSignal;
12
+ }): Promise<CredentialValidationResult>;
@@ -0,0 +1,133 @@
1
+ import { sha256Hex } from "../../core/aws-sigv4.js";
2
+ import { objectArray, optionalInteger, optionalNumber, optionalRecord, optionalString } from "../../core/cast.js";
3
+ import { ProviderRequestError, parseProviderJsonBodyText, providerResponseError, providerUserAgent, readProviderErrorTextBody, readProviderJsonBody, requiredInputNumber, requiredResponseRecord, runProviderRequest, setSearchParams, } from "../provider-runtime.js";
4
+ export const wisburgApiBaseUrl = "https://api-omen.wisburg.com";
5
+ export const wisburgActionHandlers = {
6
+ list_reports: (input, context) => listWisburgResource(input, context, "api/reports"),
7
+ get_report: (input, context) => getWisburgResource(input, context, "api/reports", "report"),
8
+ list_archives: (input, context) => listWisburgResource(input, context, "api/archives"),
9
+ get_archive: (input, context) => getWisburgResource(input, context, "api/archives", "report"),
10
+ list_company_reports: (input, context) => listWisburgResource(input, context, "api/company-reports"),
11
+ get_company_report: (input, context) => getWisburgResource(input, context, "api/company-reports", "report"),
12
+ list_earnings_calls: (input, context) => listWisburgResource(input, context, "api/earningscalls"),
13
+ get_earnings_call: (input, context) => getWisburgResource(input, context, "api/earningscalls", "report"),
14
+ list_articles: (input, context) => listWisburgResource(input, context, "api/articles"),
15
+ get_article: (input, context) => getWisburgResource(input, context, "api/articles", "article"),
16
+ list_market_daily: (input, context) => listWisburgResource(input, context, "api/market-daily"),
17
+ list_feed: (input, context) => listWisburgResource(input, context, "api/feed"),
18
+ list_images: (input, context) => listWisburgResource(input, context, "api/images"),
19
+ list_am_reports: (input, context) => listWisburgResource(input, context, "api/am-reports"),
20
+ get_am_report: (input, context) => getWisburgResource(input, context, "api/am-reports", "report"),
21
+ list_mikko_logs: (input, context) => listWisburgResource(input, context, "api/mikko-logs"),
22
+ get_mikko_log: (input, context) => getWisburgResource(input, context, "api/mikko-logs", "log"),
23
+ };
24
+ export async function validateWisburgCredential(input, { fetcher, signal }) {
25
+ try {
26
+ await wisburgRequest({ apiKey: input.apiKey, fetcher, signal }, { path: "api/feed", query: { first: "1" } });
27
+ }
28
+ catch (error) {
29
+ if (error instanceof ProviderRequestError && error.status === 401) {
30
+ throw new ProviderRequestError(400, error.message, error.details);
31
+ }
32
+ // A 403 proves the key was accepted; the feed is simply outside this key's subscription.
33
+ if (!(error instanceof ProviderRequestError) || error.status !== 403)
34
+ throw error;
35
+ }
36
+ return {
37
+ profile: {
38
+ accountId: `wisburg:${sha256Hex(input.apiKey).slice(0, 32)}`,
39
+ displayName: "Wisburg API Key",
40
+ },
41
+ grantedScopes: [],
42
+ metadata: {
43
+ apiBaseUrl: wisburgApiBaseUrl,
44
+ validationEndpoint: "/api/feed",
45
+ credentialHelpUrl: "https://open-docs.wisburg.com/docs/getting-started/first-call",
46
+ },
47
+ };
48
+ }
49
+ async function listWisburgResource(input, context, path) {
50
+ const envelope = await wisburgRequest(context, {
51
+ path,
52
+ query: {
53
+ first: optionalInteger(input.first)?.toString(),
54
+ after: optionalString(input.after),
55
+ query: optionalString(input.query),
56
+ startTime: optionalString(input.startTime),
57
+ endTime: optionalString(input.endTime),
58
+ },
59
+ });
60
+ const data = requiredResponseRecord(envelope.data, "Wisburg list data");
61
+ const pageInfo = requiredResponseRecord(data.page_info, "Wisburg list page_info");
62
+ const endCursor = pageInfo.end_cursor;
63
+ if (endCursor != null && typeof endCursor !== "string") {
64
+ throw providerResponseError("Wisburg list page_info.end_cursor must be a string");
65
+ }
66
+ return {
67
+ requestId: optionalString(envelope.request_id) ?? "",
68
+ items: objectArray(data.items, "Wisburg list data.items", providerResponseError),
69
+ pageInfo: { endCursor: optionalString(endCursor) },
70
+ };
71
+ }
72
+ async function getWisburgResource(input, context, path, key) {
73
+ const id = requiredInputNumber(input.id, "id");
74
+ const envelope = await wisburgRequest(context, { path: `${path}/${id}` });
75
+ return {
76
+ requestId: optionalString(envelope.request_id) ?? "",
77
+ [key]: requiredResponseRecord(envelope.data, "Wisburg detail data"),
78
+ };
79
+ }
80
+ async function wisburgRequest(context, input) {
81
+ return runProviderRequest({ signal: context.signal, label: "Wisburg" }, async (signal) => {
82
+ const url = new URL(input.path, `${wisburgApiBaseUrl}/`);
83
+ setSearchParams(url, input.query ?? {});
84
+ const response = await context.fetcher(url, {
85
+ headers: {
86
+ accept: "application/json",
87
+ authorization: `Bearer ${context.apiKey}`,
88
+ "user-agent": providerUserAgent,
89
+ },
90
+ signal,
91
+ });
92
+ if (!response.ok) {
93
+ throw await readWisburgHttpError(response);
94
+ }
95
+ const payload = await readProviderJsonBody(response, {
96
+ emptyBody: {},
97
+ invalidJsonMessage: "Wisburg returned invalid JSON",
98
+ });
99
+ const envelope = requiredResponseRecord(payload, "Wisburg response");
100
+ const code = optionalNumber(envelope.code);
101
+ if (code !== undefined && code !== 200) {
102
+ throw mapWisburgError(code, envelope);
103
+ }
104
+ // The envelope marks failure as status 1 even when the code field disagrees; fall back to the 1002 internal-error code when none is present.
105
+ if (optionalNumber(envelope.status) === 1) {
106
+ throw mapWisburgError(code ?? 1002, envelope);
107
+ }
108
+ return envelope;
109
+ });
110
+ }
111
+ // Keep the HTTP status for non-JSON gateway error pages; the JSON envelope, when present, only supplies the code and message.
112
+ async function readWisburgHttpError(response) {
113
+ const text = await readProviderErrorTextBody(response, "Wisburg error response");
114
+ const parsed = parseProviderJsonBodyText(text, {
115
+ emptyBody: {},
116
+ invalidJsonMessage: "Wisburg returned invalid JSON",
117
+ invalidJsonFallback: () => ({}),
118
+ });
119
+ const envelope = optionalRecord(parsed) ?? {};
120
+ return mapWisburgError(optionalNumber(envelope.code) ?? response.status, envelope);
121
+ }
122
+ function mapWisburgError(code, envelope) {
123
+ const message = optionalString(envelope.message) ?? `Wisburg request failed (${code})`;
124
+ // Besides the documented 401/403/404/429 codes, a bare gateway 4xx such as 414 stays a client error.
125
+ if (code >= 400 && code < 500) {
126
+ return new ProviderRequestError(code, message, envelope);
127
+ }
128
+ // 1001 marks invalid parameters and 1004 an out-of-range pagination cursor.
129
+ if (code === 1001 || code === 1004) {
130
+ return new ProviderRequestError(400, message, envelope);
131
+ }
132
+ return new ProviderRequestError(502, message, envelope);
133
+ }
@@ -38,7 +38,7 @@ export const proxy = defineProviderProxy({
38
38
  },
39
39
  timeoutMs: generationTimeoutMs,
40
40
  skipDnsValidation: true,
41
- redirect: "error",
41
+ redirect: "manual",
42
42
  customizeRequest({ headers }) {
43
43
  headers.set("accept", "application/json, text/event-stream");
44
44
  headers.set("content-type", "application/json");
@@ -61,7 +61,7 @@ async function withClient(context, run) {
61
61
  transport: "streamable_http",
62
62
  fetcher: context.fetcher,
63
63
  headers: { authorization: `Bearer ${context.apiKey}`, "user-agent": providerUserAgent },
64
- redirect: "error",
64
+ redirect: "manual",
65
65
  signal: context.signal,
66
66
  mapError,
67
67
  }, run);
@@ -1,4 +1,4 @@
1
- import { googleJsonRequest } from "../google-runtime.js";
1
+ import { googleJsonRequest } from "../googledrive/runtime-request.js";
2
2
  import { defineOAuthProviderExecutors, defineProviderProxy, providerProxyEndpointPrefixes, } from "../provider-runtime.js";
3
3
  import { youtubeActionHandlers } from "./runtime.js";
4
4
  const service = "youtube";
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { compactObject, optionalBoolean, optionalInteger, optionalString, rawStringOrNull } from "../../core/cast.js";
3
3
  import { assertPublicHttpUrl, readBoundedResponseBytes } from "../../core/request.js";
4
- import { googleJsonRequest, googleRequest } from "../google-runtime.js";
4
+ import { googleJsonRequest, googleRequest } from "../googledrive/runtime-request.js";
5
5
  import { providerUserAgent, ProviderRequestError } from "../provider-runtime.js";
6
6
  const youtubeApiBaseUrl = "https://www.googleapis.com/youtube/v3";
7
7
  const youtubeUploadApiBaseUrl = "https://www.googleapis.com/upload/youtube/v3";
@@ -0,0 +1,9 @@
1
+ import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
2
+ import type { ProviderActionHandlers, ProviderRuntimeHandler } from "../provider-runtime.ts";
3
+ import type { ZerotierActionContext } from "./runtime.ts";
4
+ type ZerotierHandler = ProviderRuntimeHandler<ZerotierActionContext>;
5
+ export declare const zerotierActionHandlers: ProviderActionHandlers<"zerotier", ZerotierHandler>;
6
+ export declare const executors: ProviderExecutors;
7
+ export declare const proxy: ProviderProxyExecutor;
8
+ export declare const credentialValidators: CredentialValidators;
9
+ export {};