@tool-bridge/server 0.3.0 → 0.5.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 (108) hide show
  1. package/dist/{airtable-V6446SVY.js → airtable-7TFNLFIF.js} +6 -4
  2. package/dist/{alt_text_generator_ai-HV7JZPDT.js → alt_text_generator_ai-VJSAHBJM.js} +6 -4
  3. package/dist/{amap-TTTVB6WS.js → amap-KZMUDGK6.js} +6 -4
  4. package/dist/{anthropic-JH3RA363.js → anthropic-C6FCUSY7.js} +6 -4
  5. package/dist/{apify-ETNN7ITU.js → apify-MUCWNIWU.js} +6 -4
  6. package/dist/{brave_search-3DDR2MMB.js → brave_search-NRVZ4ZNY.js} +6 -4
  7. package/dist/{chunk-KGYJEEBI.js → chunk-3C3J36GT.js} +106 -61
  8. package/dist/{chunk-CSJEZHQO.js → chunk-7GP7DRES.js} +13 -82
  9. package/dist/{chunk-JLTYA2B3.js → chunk-7PM4FD5K.js} +100 -71
  10. package/dist/{chunk-K7FVSFUX.js → chunk-B4ZA7EGO.js} +47 -3
  11. package/dist/chunk-FHYFPPBZ.js +90 -0
  12. package/dist/{circleci-MX3TX3HC.js → circleci-QY36SZIM.js} +6 -4
  13. package/dist/{clerk-MRPORVF4.js → clerk-ECH23XL5.js} +6 -4
  14. package/dist/{cloudflare_dns-OWP7DD7L.js → cloudflare_dns-F6DN2F3X.js} +6 -4
  15. package/dist/{cohere-GPECP66S.js → cohere-HD4XZOPJ.js} +6 -4
  16. package/dist/{confluence-BN7LZ6BC.js → confluence-J4AZ2KYL.js} +6 -4
  17. package/dist/{convertapi-SBEOFOFQ.js → convertapi-BXBII5Z6.js} +7 -5
  18. package/dist/{currencyapi-P2YY7Y7P.js → currencyapi-HEEQ7EQJ.js} +6 -4
  19. package/dist/{deepseek-MWB3NYIN.js → deepseek-RKRGIFPM.js} +6 -4
  20. package/dist/{docker_hub-3JSCIGQ3.js → docker_hub-YFSTEZVP.js} +6 -4
  21. package/dist/{dropbox-RFIBDAXO.js → dropbox-VGK634PO.js} +6 -4
  22. package/dist/{dub-YVP57ELQ.js → dub-GEXD3XK6.js} +6 -4
  23. package/dist/{e2b-NFSUHTZR.js → e2b-LPTZQEDV.js} +6 -4
  24. package/dist/{exa-KTDY6IV3.js → exa-VJENLTKN.js} +6 -4
  25. package/dist/{fal_ai-OCUENLNQ.js → fal_ai-75O63LLP.js} +6 -4
  26. package/dist/{feishu-5CWBQ7E5.js → feishu-FATBHGEJ.js} +12 -4
  27. package/dist/{feishu_custom_bot-ZJR22OK6.js → feishu_custom_bot-QFSYPOLI.js} +6 -4
  28. package/dist/{figma-YULGANSA.js → figma-JED3Q56H.js} +6 -4
  29. package/dist/{firehydrant-2V6YSYAP.js → firehydrant-7JDKFJTB.js} +6 -4
  30. package/dist/{fixer-LTCDB3CJ.js → fixer-ZI2JS5GU.js} +6 -4
  31. package/dist/{fly-IXPKMAML.js → fly-3RA7ETFP.js} +6 -4
  32. package/dist/{front-KRFB4M5X.js → front-X2CJXBYS.js} +6 -4
  33. package/dist/{geocodio-VVURKYHQ.js → geocodio-C6NHG5UJ.js} +6 -4
  34. package/dist/{ghost-6J2RIOUB.js → ghost-ZBFOMWQF.js} +7 -5
  35. package/dist/{github-5Z6KQRYH.js → github-6QM2NIP4.js} +6 -4
  36. package/dist/{gmail-KU4NZ7VA.js → gmail-ST3MS32S.js} +6 -4
  37. package/dist/{googlecalendar-X44DFFXG.js → googlecalendar-SAUTUJ3Q.js} +6 -4
  38. package/dist/{googledocs-WSGLPKSF.js → googledocs-2SJKS2SC.js} +6 -4
  39. package/dist/{grafana-4PKSSDXY.js → grafana-RP7DOS3A.js} +13 -5
  40. package/dist/{graphhopper-DF65ZNGK.js → graphhopper-XSDTLJTE.js} +6 -4
  41. package/dist/index.d.ts +43 -10
  42. package/dist/index.js +2 -2
  43. package/dist/{ip2proxy-UCAQ5P2J.js → ip2proxy-IKV5IWUI.js} +6 -4
  44. package/dist/{ipgeolocation_io-UX6FCA2S.js → ipgeolocation_io-NSUWUF5X.js} +6 -4
  45. package/dist/{ipqualityscore-MKTRXIZJ.js → ipqualityscore-ZQKL3WLC.js} +6 -4
  46. package/dist/{jina_ai-MRHPCSV5.js → jina_ai-F4Y7V5AS.js} +6 -4
  47. package/dist/{jira-EG7ZPOIW.js → jira-CYDY44ZO.js} +7 -5
  48. package/dist/{langsmith-FNO3RCOZ.js → langsmith-74JSSJNY.js} +19 -4
  49. package/dist/{lemlist-SN6BJHSG.js → lemlist-C3LKIPVN.js} +6 -4
  50. package/dist/{linear-H3VU4PSD.js → linear-YYGRHKJC.js} +6 -4
  51. package/dist/{logsnag-OY2JJT2H.js → logsnag-YBMDJ6DO.js} +6 -4
  52. package/dist/main.js +184 -184
  53. package/dist/{mattermost-C5SQ7PGD.js → mattermost-NDID4TAL.js} +7 -5
  54. package/dist/{mem0-LMLE5BFC.js → mem0-ASBAEBWR.js} +6 -4
  55. package/dist/{memos-UWFAMBZC.js → memos-76I27HCW.js} +13 -5
  56. package/dist/{metabase-SRYDSDJ6.js → metabase-LCPIP2DL.js} +13 -5
  57. package/dist/{mistral_ai-YNIJ7VDM.js → mistral_ai-YVBQ6QKO.js} +7 -5
  58. package/dist/{mother_duck-CPGOFEXE.js → mother_duck-J2MPBIFO.js} +6 -4
  59. package/dist/{ngrok-CDJFBSOM.js → ngrok-UJC2ORDH.js} +6 -4
  60. package/dist/{notes-DIVFH3P3.js → notes-6VWWD6RW.js} +10 -3
  61. package/dist/{notion-HGDKS4HK.js → notion-6LBO2KHR.js} +6 -4
  62. package/dist/{open_exchange_rates-COHHYJDD.js → open_exchange_rates-OGDH4ZBX.js} +6 -4
  63. package/dist/{openai-4TRT66GW.js → openai-IKGD5M66.js} +7 -5
  64. package/dist/{opengraph_io-YKVW4PXI.js → opengraph_io-CIILQ7VK.js} +7 -5
  65. package/dist/{openrouter-6CV7B7V5.js → openrouter-IYG5CPG5.js} +6 -4
  66. package/dist/{outline-YWDUK5F7.js → outline-R2UMBY4M.js} +13 -5
  67. package/dist/{paddle-MEU7HWDZ.js → paddle-IYWA7DOV.js} +6 -4
  68. package/dist/{perplexity-MRQUDBIC.js → perplexity-3TGYQWHT.js} +6 -4
  69. package/dist/{pinecone-JI7X2TAF.js → pinecone-TEBOW4LJ.js} +6 -4
  70. package/dist/{pipedrive-6JQPAW23.js → pipedrive-ZXDY753U.js} +6 -4
  71. package/dist/{polar-7BF56CMC.js → polar-BVZV5A4O.js} +6 -4
  72. package/dist/{posthog-YPU5ADEN.js → posthog-DXKAS4PJ.js} +20 -5
  73. package/dist/{postmark-BEU5OFKU.js → postmark-6RWFC3TD.js} +6 -4
  74. package/dist/{prerender-UT5GOOZH.js → prerender-YIXOTM3K.js} +6 -4
  75. package/dist/{pubmed-3SGOE24Q.js → pubmed-2RHSZB4E.js} +6 -4
  76. package/dist/{railway-CEK4GLRQ.js → railway-IF64BUE2.js} +12 -4
  77. package/dist/{readwise-DXQUQU67.js → readwise-5XKQZNOM.js} +6 -4
  78. package/dist/{render-7TGAU5AW.js → render-Q2Z66LTA.js} +6 -4
  79. package/dist/{replicate-VICFSQ5A.js → replicate-SOI65IJO.js} +6 -4
  80. package/dist/{resend-3E76WK3O.js → resend-O2BGONOO.js} +6 -4
  81. package/dist/{rootly-36GY46BY.js → rootly-WPQKTVU3.js} +6 -4
  82. package/dist/{scrapfly-VDVUYAHX.js → scrapfly-GLMBVNPG.js} +6 -4
  83. package/dist/{scrapingbee-3KTPMAVY.js → scrapingbee-TUER54CY.js} +6 -4
  84. package/dist/{screenshot_fyi-LKG62C3J.js → screenshot_fyi-4J4W5EKY.js} +6 -4
  85. package/dist/{semantic_scholar-4WREECYO.js → semantic_scholar-4PITOANV.js} +6 -4
  86. package/dist/{sentry-HUQTGXOV.js → sentry-4WURPLIE.js} +6 -4
  87. package/dist/{shodan-SGRKU4KS.js → shodan-G3M3LFEW.js} +6 -4
  88. package/dist/{shopify-YCZ4L5HT.js → shopify-72AIELMS.js} +6 -4
  89. package/dist/{stripe-OEBKMELB.js → stripe-7C7XVPMU.js} +6 -4
  90. package/dist/{supabase-I3DBY7L4.js → supabase-N4Y3YC23.js} +6 -4
  91. package/dist/{tavily-B2YHCNRD.js → tavily-GGLSWERP.js} +6 -4
  92. package/dist/{telegram-2VYJELZX.js → telegram-4RH36WYP.js} +7 -5
  93. package/dist/{telnyx-HHXD3CXL.js → telnyx-I2KUITFV.js} +6 -4
  94. package/dist/{todoist-PHFDEEIS.js → todoist-A3NX6X2Y.js} +6 -4
  95. package/dist/{trello-WUSAK6YN.js → trello-2GJYN7GR.js} +6 -4
  96. package/dist/{turso-FW56U2B3.js → turso-WKUXMTZ5.js} +6 -4
  97. package/dist/{twilio-M5JI7XHA.js → twilio-SSXDBOK4.js} +6 -4
  98. package/dist/{umami-HAYODRC4.js → umami-SBDB4GXK.js} +6 -4
  99. package/dist/{unsplash-EDPTNEHJ.js → unsplash-4AVC4ZGP.js} +6 -4
  100. package/dist/{upstash_redis-GC2CLIWD.js → upstash_redis-7XY3UHBO.js} +6 -4
  101. package/dist/{uptimerobot-XMSNYLIT.js → uptimerobot-QVQP3QYG.js} +6 -4
  102. package/dist/{v2ex-KU4ECD65.js → v2ex-ASVTIKO7.js} +6 -4
  103. package/dist/{vercel-THPCEFHW.js → vercel-ZQXZCGWY.js} +6 -4
  104. package/dist/{wolfram_alpha_api-WHHTH4GU.js → wolfram_alpha_api-RVBWQSEF.js} +6 -4
  105. package/dist/{wordpress-O6TQEQNF.js → wordpress-SOWKVNCX.js} +7 -5
  106. package/dist/{workos-A3VHHWI3.js → workos-F45INANB.js} +6 -4
  107. package/dist/{zhihu-BJAI64YJ.js → zhihu-5VODAGAP.js} +6 -4
  108. package/package.json +5 -5
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/airtable/api.ts
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/alt_text_generator_ai/schema.ts
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/amap/api.ts
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/anthropic/api.ts
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/apify/api.ts
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  createProviderPlugin,
3
- guardedFetch,
4
3
  requireApiKey,
5
4
  upstreamError
6
- } from "./chunk-CSJEZHQO.js";
7
- import "./chunk-K7FVSFUX.js";
5
+ } from "./chunk-FHYFPPBZ.js";
6
+ import {
7
+ guardedFetch
8
+ } from "./chunk-7GP7DRES.js";
9
+ import "./chunk-B4ZA7EGO.js";
8
10
  import {
9
11
  TBError,
10
12
  external_exports
11
- } from "./chunk-JLTYA2B3.js";
13
+ } from "./chunk-7PM4FD5K.js";
12
14
  import "./chunk-MLKGABMK.js";
13
15
 
14
16
  // ../plugins/src/brave_search/api.ts
@@ -130,7 +130,7 @@ import {
130
130
  url,
131
131
  validatePath,
132
132
  virtualizeTools
133
- } from "./chunk-JLTYA2B3.js";
133
+ } from "./chunk-7PM4FD5K.js";
134
134
 
135
135
  // src/config.ts
136
136
  var DEFAULT_PORT = 8787;
@@ -442,7 +442,7 @@ async function doBootstrap(store, adminSk, requireAdminSk) {
442
442
  if (!bootstrapped) await store.put(KEY_BOOTSTRAPPED, true);
443
443
  }
444
444
  function runBootstrap(store, opts) {
445
- return doBootstrap(store, opts?.adminSk, opts?.requireAdminSk ?? false);
445
+ return doBootstrap(store, opts?.adminSk, opts?.requireAdminSk ?? true);
446
446
  }
447
447
  function buildDeps(opts) {
448
448
  return {
@@ -457,8 +457,7 @@ function buildDeps(opts) {
457
457
  store: opts.store,
458
458
  probe: (manifest) => probePlugin(manifest, opts.pluginBindings),
459
459
  fetchContract: (manifest) => fetchPluginContract(manifest, opts.pluginBindings),
460
- allowInsecureHttp: opts.allowInsecureHttp,
461
- ...opts.pluginBindings !== void 0 ? { bindings: () => [...(opts.pluginBindings ?? /* @__PURE__ */ new Map()).keys()] } : {}
460
+ allowInsecureHttp: opts.allowInsecureHttp
462
461
  },
463
462
  // federation 模块:remote host 白名单运行时存储 + env 基线。
464
463
  federation: { store: new RemoteAllowlistStore(opts.store), base: opts.remoteAllowlistBase },
@@ -650,53 +649,6 @@ function createS3ObjectStore(cfg, opts) {
650
649
  };
651
650
  }
652
651
 
653
- // ../app/src/deviceNodes.ts
654
- function tbErrorFromBody(body) {
655
- return new TBError(body.code, body.message, { retryable: body.retryable });
656
- }
657
- function requireDevice(deps) {
658
- if (deps.device === void 0) {
659
- throw TBError.unimplemented("device capability disabled: no device transport");
660
- }
661
- return deps.device;
662
- }
663
- async function invokeDevice(deps, deviceId, req) {
664
- const id = crypto.randomUUID();
665
- const body = await requireDevice(deps).invoke(deviceId, { id, ...req });
666
- if (!body || !("ok" in body)) {
667
- throw new TBError("unavailable", "device session returned invalid result");
668
- }
669
- if (body.ok) return body.value;
670
- throw tbErrorFromBody(body.error);
671
- }
672
- function deviceMarkerOf(pc) {
673
- if (pc === void 0 || typeof pc.deviceId !== "string" || typeof pc.mountPath !== "string") {
674
- return null;
675
- }
676
- return {
677
- deviceId: pc.deviceId,
678
- mountPath: pc.mountPath,
679
- ...Array.isArray(pc.cmds) ? { cmds: pc.cmds } : {}
680
- };
681
- }
682
- function deviceToolMarker(node) {
683
- if (node.kind !== "tool" || node.config?.kind !== "tool") return null;
684
- return deviceMarkerOf(node.config.providerConfig);
685
- }
686
- function relativeDevicePath(nodePath, mountPath) {
687
- if (nodePath.startsWith(`${mountPath}/`)) return nodePath.slice(mountPath.length + 1);
688
- throw new TBError("invalid_argument", `device \u8282\u70B9 '${nodePath}' \u4E0D\u5728\u6302\u8F7D '${mountPath}' \u4E0B`);
689
- }
690
- function assertNoDeviceMarker(config) {
691
- const pc = config.providerConfig;
692
- if (pc !== null && typeof pc === "object" && deviceMarkerOf(pc) !== null) {
693
- throw new TBError(
694
- "invalid_argument",
695
- "providerConfig \u7684 device \u8F6C\u53D1\u6807\u8BB0\u7531\u7F51\u5173\u4EE3\u5199,\u4E0D\u5F97\u7ECF\u6CE8\u518C\u9762\u643A\u5E26"
696
- );
697
- }
698
- }
699
-
700
652
  // ../app/src/providers/toolCache.ts
701
653
  var KEY_PREFIX = "toolcache:";
702
654
  function toolCacheKey(path) {
@@ -992,6 +944,53 @@ var SearchSynchronizer = class {
992
944
  // ../app/src/deps.ts
993
945
  var TOOL_CACHE_TTL_DEFAULT = 300;
994
946
 
947
+ // ../app/src/deviceNodes.ts
948
+ function tbErrorFromBody(body) {
949
+ return new TBError(body.code, body.message, { retryable: body.retryable });
950
+ }
951
+ function requireDevice(deps) {
952
+ if (deps.device === void 0) {
953
+ throw TBError.unimplemented("device capability disabled: no device transport");
954
+ }
955
+ return deps.device;
956
+ }
957
+ async function invokeDevice(deps, deviceId, req) {
958
+ const id = crypto.randomUUID();
959
+ const body = await requireDevice(deps).invoke(deviceId, { id, ...req });
960
+ if (!body || !("ok" in body)) {
961
+ throw new TBError("unavailable", "device session returned invalid result");
962
+ }
963
+ if (body.ok) return body.value;
964
+ throw tbErrorFromBody(body.error);
965
+ }
966
+ function deviceMarkerOf(pc) {
967
+ if (pc === void 0 || typeof pc.deviceId !== "string" || typeof pc.mountPath !== "string") {
968
+ return null;
969
+ }
970
+ return {
971
+ deviceId: pc.deviceId,
972
+ mountPath: pc.mountPath,
973
+ ...Array.isArray(pc.cmds) ? { cmds: pc.cmds } : {}
974
+ };
975
+ }
976
+ function deviceToolMarker(node) {
977
+ if (node.kind !== "tool" || node.config?.kind !== "tool") return null;
978
+ return deviceMarkerOf(node.config.providerConfig);
979
+ }
980
+ function relativeDevicePath(nodePath, mountPath) {
981
+ if (nodePath.startsWith(`${mountPath}/`)) return nodePath.slice(mountPath.length + 1);
982
+ throw new TBError("invalid_argument", `device \u8282\u70B9 '${nodePath}' \u4E0D\u5728\u6302\u8F7D '${mountPath}' \u4E0B`);
983
+ }
984
+ function assertNoDeviceMarker(config) {
985
+ const pc = config.providerConfig;
986
+ if (pc !== null && typeof pc === "object" && deviceMarkerOf(pc) !== null) {
987
+ throw new TBError(
988
+ "invalid_argument",
989
+ "providerConfig \u7684 device \u8F6C\u53D1\u6807\u8BB0\u7531\u7F51\u5173\u4EE3\u5199,\u4E0D\u5F97\u7ECF\u6CE8\u518C\u9762\u643A\u5E26"
990
+ );
991
+ }
992
+ }
993
+
995
994
  // ../app/src/providers/http.ts
996
995
  function toSpec(t) {
997
996
  const spec = { name: t.name, description: t.description, effect: effectFor(t) };
@@ -19265,6 +19264,47 @@ function mountCallContext(ctx, mountPath, providerConfig, exportId) {
19265
19264
  ...exportId !== void 0 ? { exportId } : {}
19266
19265
  };
19267
19266
  }
19267
+ async function assertPluginMountContract(exported, config, deps) {
19268
+ const providerConfig = config.providerConfig ?? {};
19269
+ const missingConfig = (exported.mountConfigFields ?? []).filter((field) => {
19270
+ if (field.required !== true) return false;
19271
+ const value = providerConfig[field.key];
19272
+ return value === void 0 || value === null || typeof value === "string" && value.trim() === "";
19273
+ }).map((field) => field.key);
19274
+ if (missingConfig.length > 0) {
19275
+ throw new TBError(
19276
+ "invalid_argument",
19277
+ `plugin export '${exported.id}' \u7F3A\u5C11\u5FC5\u586B providerConfig:${missingConfig.join(", ")}`
19278
+ );
19279
+ }
19280
+ const authRef = typeof config.authRef === "string" && config.authRef.trim() !== "" ? config.authRef.trim() : void 0;
19281
+ if (exported.auth?.kind === "none") {
19282
+ if (authRef !== void 0) {
19283
+ throw new TBError(
19284
+ "invalid_argument",
19285
+ `plugin export '${exported.id}' \u58F0\u660E auth:none,\u4E0D\u5F97\u7ED1\u5B9A authRef`
19286
+ );
19287
+ }
19288
+ return;
19289
+ }
19290
+ const requiresAuth = exported.oauth !== void 0 || exported.credentialFields !== void 0 || exported.auth?.kind === "single" && exported.auth.required === true;
19291
+ if (requiresAuth && authRef === void 0) {
19292
+ throw new TBError(
19293
+ "invalid_argument",
19294
+ `plugin export '${exported.id}' \u9700\u8981 authRef`
19295
+ );
19296
+ }
19297
+ if (authRef === void 0) return;
19298
+ const raw = await deps.secrets.resolve(authRef);
19299
+ if (raw === void 0) {
19300
+ throw new TBError("invalid_argument", `secret '${authRef}' \u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u89E3\u5BC6`);
19301
+ }
19302
+ if (exported.credentialFields !== void 0) {
19303
+ parseCredentialValues(raw, exported.credentialFields);
19304
+ } else if (exported.oauth !== void 0) {
19305
+ parseCredentialValues(raw, [...OAUTH_CLIENT_FIELDS]);
19306
+ }
19307
+ }
19268
19308
  async function providerAccessTokenFor(opts) {
19269
19309
  const encryptionKey = opts.deps.encryptionKey;
19270
19310
  if (encryptionKey === void 0) {
@@ -19290,7 +19330,7 @@ async function providerFor(node, ctx, deps) {
19290
19330
  if (node.kind === "mcp" && node.config?.kind === "mcp") {
19291
19331
  return createMcpProvider(node.config, deps.secrets, {
19292
19332
  allowInsecure: insecure,
19293
- // 会话复用凭证存 StateStore(mcpsession:<path>);调用结果不缓存(providers/mcp.ts)。
19333
+ // era 判定存 StateStore(mcpera:<path>);调用结果不缓存(providers/mcp.ts)。
19294
19334
  session: { store: deps.state, nodePath: node.path },
19295
19335
  // auth:'oauth' 节点的托管凭证存取面(mcpoauth:*);密钥缺省 → provider 内报 unavailable。
19296
19336
  ...deps.encryptionKey !== void 0 ? { oauth: { store: deps.state, encryptionKey: deps.encryptionKey } } : {}
@@ -19452,13 +19492,11 @@ async function assertToolConfig(config, deps, ctx, mountPath) {
19452
19492
  typeof exportId === "string" ? exportId : void 0
19453
19493
  );
19454
19494
  const authRef = config.authRef;
19455
- if (exported.credentialFields !== void 0 && typeof authRef === "string") {
19456
- const raw = await deps.secrets.resolve(authRef);
19457
- if (raw === void 0) {
19458
- throw new TBError("invalid_argument", `secret '${authRef}' \u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u89E3\u5BC6`);
19459
- }
19460
- parseCredentialValues(raw, exported.credentialFields);
19461
- }
19495
+ await assertPluginMountContract(
19496
+ exported,
19497
+ config,
19498
+ deps
19499
+ );
19462
19500
  if (exported.credentialProbe === void 0 || typeof authRef !== "string" || ctx === void 0 || mountPath === void 0 || exported.oauth !== void 0) {
19463
19501
  return;
19464
19502
  }
@@ -19713,7 +19751,14 @@ async function assertContextConfig(config, deps) {
19713
19751
  assertNoDeviceMarker(config);
19714
19752
  const cfg = config;
19715
19753
  if (cfg.provider !== "r2" && cfg.provider !== "s3") {
19716
- await requirePluginExport(deps, cfg.provider, "context", "context", cfg.export);
19754
+ const { export: exported } = await requirePluginExport(
19755
+ deps,
19756
+ cfg.provider,
19757
+ "context",
19758
+ "context",
19759
+ cfg.export
19760
+ );
19761
+ await assertPluginMountContract(exported, cfg, deps);
19717
19762
  return;
19718
19763
  }
19719
19764
  if (cfg.provider === "s3") {
@@ -38291,7 +38336,7 @@ import { join as join4 } from "path";
38291
38336
  // package.json
38292
38337
  var package_default = {
38293
38338
  name: "@tool-bridge/server",
38294
- version: "0.3.0",
38339
+ version: "0.5.0",
38295
38340
  description: "tool-bridge self-hosted server: run the HTBP gateway on Node with SQLite persistence, filesystem object storage and WebSocket device channel \u2014 single container via docker run",
38296
38341
  type: "module",
38297
38342
  license: "MIT",
@@ -1,80 +1,6 @@
1
- import {
2
- createPlugin
3
- } from "./chunk-K7FVSFUX.js";
4
1
  import {
5
2
  TBError
6
- } from "./chunk-JLTYA2B3.js";
7
-
8
- // ../plugins/src/_runtime/plugin.ts
9
- function requireApiKey(ctx, service) {
10
- const key = ctx.upstreamAuth;
11
- if (key === void 0 || key === "") {
12
- throw new TBError(
13
- "unavailable",
14
- `${service} \u9700\u8981 API key:\u7ED9\u6302\u8F7D\u8282\u70B9\u914D config.authRef \u6307\u5411\u5DF2\u5B58\u5165 system/secret \u7684\u51ED\u8BC1`
15
- );
16
- }
17
- return key;
18
- }
19
- function requireCredential(ctx, service, field) {
20
- const values = ctx.credentials;
21
- if (values === void 0) {
22
- throw new TBError(
23
- "unavailable",
24
- `${service} \u9700\u8981\u591A\u5B57\u6BB5\u51ED\u8BC1:\u7ED9\u6302\u8F7D\u8282\u70B9\u914D config.authRef \u6307\u5411\u5DF2\u5B58\u5165 system/secret \u7684\u51ED\u8BC1(\u7528 \`tb secret set <name> --field ...\` \u5199\u5165)`
25
- );
26
- }
27
- const value = values[field];
28
- if (value === void 0 || value === "") {
29
- throw new TBError("internal", `${service} \u7684\u51ED\u8BC1\u5B57\u6BB5 '${field}' \u672A\u5728 credentialFields \u91CC\u58F0\u660E`);
30
- }
31
- return value;
32
- }
33
- function createProviderPlugin(input) {
34
- const names = Object.keys(input.actions);
35
- const handlerNames = Object.keys(input.handlers);
36
- const missing = names.filter((name) => !handlerNames.includes(name));
37
- const extra = handlerNames.filter((name) => !names.includes(name));
38
- if (missing.length > 0 || extra.length > 0) {
39
- throw new Error(
40
- `action \u8868\u4E0E handler \u8868\u4E0D\u543B\u5408:\u7F3A handler [${missing.join(", ")}];\u591A\u4F59 handler [${extra.join(", ")}]`
41
- );
42
- }
43
- const plugin = createPlugin({ token: (env) => env.PLUGIN_TOKEN });
44
- const tools = plugin.tools(input.exportId ?? "actions", { description: input.description });
45
- if (input.oauth !== void 0) tools.oauth(input.oauth);
46
- if (input.credentialFields !== void 0) tools.credentials(input.credentialFields);
47
- for (const name of names) {
48
- tools.register(name, input.actions[name], (args, ctx) => input.handlers[name](args, {
49
- upstreamAuth: ctx.upstreamAuth,
50
- credentials: ctx.credentials,
51
- config: ctx.mountConfig
52
- }));
53
- }
54
- if (input.credentialProbe !== void 0) {
55
- const effect = input.actions[input.credentialProbe]?.effect;
56
- if (effect !== "read") {
57
- throw new Error(
58
- `credentialProbe '${input.credentialProbe}' \u7684 effect \u662F '${effect ?? "\u672A\u58F0\u660E"}', \u63A2\u9488\u5FC5\u987B\u662F read \u2014\u2014 \u6302\u8F7D\u65F6\u4F1A\u771F\u5B9E\u8C03\u7528\u5B83`
59
- );
60
- }
61
- tools.probeCredentialWith(input.credentialProbe);
62
- }
63
- return plugin;
64
- }
65
-
66
- // ../plugins/src/_runtime/upstreamError.ts
67
- function upstreamError(status, message) {
68
- if (status === 401) {
69
- return new TBError("permission_denied", message, { httpStatus: 401 });
70
- }
71
- if (status === 403) return new TBError("permission_denied", message);
72
- if (status === 404) return new TBError("not_found", message);
73
- if (status === 409) return new TBError("conflict", message);
74
- if (status === 429) return new TBError("rate_limited", message, { retryable: true });
75
- if (status >= 500) return new TBError("unavailable", message, { retryable: true });
76
- return new TBError("invalid_argument", message);
77
- }
3
+ } from "./chunk-7PM4FD5K.js";
78
4
 
79
5
  // ../plugins/src/_runtime/ipPolicy.ts
80
6
  function parseIpv4(value) {
@@ -186,10 +112,10 @@ var CROSS_ORIGIN_STRIPPED_HEADERS = [
186
112
  function looksLikeCredentialHeader(name) {
187
113
  return /(?:^|-)(?:api[-_]?key|key|token|secret|auth)(?:$|-)/i.test(name);
188
114
  }
189
- function stripCredentials(headers) {
115
+ function stripCredentials(headers, sensitiveHeaders) {
190
116
  const next = new Headers(headers);
191
117
  for (const [name] of headers) {
192
- if (CROSS_ORIGIN_STRIPPED_HEADERS.includes(name.toLowerCase()) || looksLikeCredentialHeader(name)) {
118
+ if (CROSS_ORIGIN_STRIPPED_HEADERS.includes(name.toLowerCase()) || looksLikeCredentialHeader(name) || sensitiveHeaders.has(name.toLowerCase())) {
193
119
  next.delete(name);
194
120
  }
195
121
  }
@@ -219,7 +145,11 @@ function assertPublicHttpUrl(value) {
219
145
  return url;
220
146
  }
221
147
  function createGuardedFetch(options = {}) {
148
+ const crossOriginRedirect = options.crossOriginRedirect ?? "follow";
222
149
  const maxRedirects = options.maxRedirects ?? MAX_REDIRECTS;
150
+ const sensitiveHeaders = new Set(
151
+ (options.sensitiveHeaders ?? []).map((name) => name.toLowerCase())
152
+ );
223
153
  return async function guardedFetch2(input, init) {
224
154
  const transport = options.fetch ?? globalThis.fetch;
225
155
  const initial = input instanceof Request ? input.url : String(input);
@@ -234,7 +164,11 @@ function createGuardedFetch(options = {}) {
234
164
  }
235
165
  const previousOrigin = new URL(request.url).origin;
236
166
  url = assertPublicHttpUrl(new URL(location, url));
237
- const headers = url.origin === previousOrigin ? request.headers : stripCredentials(request.headers);
167
+ const crossesOrigin = url.origin !== previousOrigin;
168
+ if (crossesOrigin && crossOriginRedirect === "error") {
169
+ throw new EgressBlockedError("\u643A\u5E26\u654F\u611F\u4FE1\u606F\u7684\u51FA\u7AD9\u8BF7\u6C42\u4E0D\u5141\u8BB8\u8DE8\u6E90\u91CD\u5B9A\u5411");
170
+ }
171
+ const headers = !crossesOrigin ? request.headers : stripCredentials(request.headers, sensitiveHeaders);
238
172
  const downgrade = response.status === 303 || (response.status === 301 || response.status === 302) && request.method !== "GET";
239
173
  request = downgrade ? new Request(url, { method: "GET", headers, redirect: "manual" }) : new Request(url, { ...request, headers, redirect: "manual" });
240
174
  }
@@ -243,10 +177,7 @@ function createGuardedFetch(options = {}) {
243
177
  var guardedFetch = createGuardedFetch();
244
178
 
245
179
  export {
246
- requireApiKey,
247
- requireCredential,
248
- createProviderPlugin,
249
- upstreamError,
250
180
  assertPublicHttpUrl,
181
+ createGuardedFetch,
251
182
  guardedFetch
252
183
  };