apps 0.0.1-beta.5 → 0.0.1-beta.55

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 (188) hide show
  1. package/README.md +68 -44
  2. package/framework-reference.json +1 -1
  3. package/js/chunk-47F7VXST.js +221 -0
  4. package/js/chunk-5FHWNLCI.js +88 -0
  5. package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
  6. package/js/chunk-7UUHJR2Q.js +49 -0
  7. package/js/{chunk-CYYBFC2K.js → chunk-AQU56EPI.js} +9 -5
  8. package/js/chunk-BTSIG4NQ.js +1885 -0
  9. package/js/chunk-CDXQDN7W.js +92 -0
  10. package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
  11. package/js/{chunk-27F7W2LG.js → chunk-H2CJWXA3.js} +2 -2
  12. package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
  13. package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
  14. package/js/{chunk-UDDE5KOR.js → chunk-JK5S2N2S.js} +148 -34
  15. package/js/{chunk-RJDDBDSN.js → chunk-JM7LOD2W.js} +628 -85
  16. package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
  17. package/js/{chunk-FWQC6I3C.js → chunk-KGCTYL2S.js} +523 -63
  18. package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
  19. package/js/chunk-L4K2K22P.js +42 -0
  20. package/js/chunk-LTDHQJ2Z.js +171 -0
  21. package/js/chunk-MWKHKOTL.js +240 -0
  22. package/js/chunk-OD3KFKZD.js +1617 -0
  23. package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
  24. package/js/chunk-PXXZ6ABC.js +266 -0
  25. package/js/chunk-QEBRH5AP.js +729 -0
  26. package/js/chunk-TLWLJ7PD.js +4342 -0
  27. package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
  28. package/js/{chunk-XHO2ZX6W.js → chunk-UM62MBJQ.js} +96 -41
  29. package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
  30. package/js/chunk-XCSG7FT7.js +340 -0
  31. package/js/client.js +142 -94
  32. package/js/contracts.js +123 -33
  33. package/js/effect.js +19 -21
  34. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  35. package/js/graphql.js +63 -60
  36. package/js/host.js +83 -60
  37. package/js/index.js +262 -222
  38. package/js/mcp/effect.js +23 -23
  39. package/js/mcp/stdio.js +48 -40
  40. package/js/mcp.js +109 -72
  41. package/js/openapi.js +4129 -1419
  42. package/js/react.js +2 -3
  43. package/js/skills/effect.js +6 -3
  44. package/js/skills.js +208 -82
  45. package/js/storage/facet.js +1 -540
  46. package/js/ui/auth/contracts.js +2 -2
  47. package/js/ui/auth.js +5 -5
  48. package/js/ui/contracts.js +5 -4
  49. package/js/ui/serving.js +8517 -214
  50. package/package.json +2 -3
  51. package/runtime.json +1 -1
  52. package/types/app-cache/src/index.d.ts +10 -1
  53. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  54. package/types/apps/src/contracts/app.d.ts +9 -8
  55. package/types/apps/src/contracts/cache.d.ts +20 -0
  56. package/types/apps/src/contracts/context.d.ts +19 -11
  57. package/types/apps/src/contracts/elicitation.d.ts +6 -6
  58. package/types/apps/src/contracts/events.d.ts +93 -0
  59. package/types/apps/src/contracts/failure.d.ts +30 -1
  60. package/types/apps/src/contracts/graphql.d.ts +2 -1
  61. package/types/apps/src/contracts/host.d.ts +57 -18
  62. package/types/apps/src/contracts/live.d.ts +2 -0
  63. package/types/apps/src/contracts/mcp.d.ts +96 -10
  64. package/types/apps/src/contracts/network.d.ts +84 -0
  65. package/types/apps/src/contracts/openapi-compile.d.ts +32 -3
  66. package/types/apps/src/contracts/openapi.d.ts +45 -9
  67. package/types/apps/src/contracts/operations.d.ts +8 -9
  68. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  69. package/types/apps/src/contracts/protocols/1.d.ts +733 -81
  70. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  71. package/types/apps/src/contracts/protocols/2.d.ts +69 -26
  72. package/types/apps/src/contracts/protocols/3.d.ts +133 -33
  73. package/types/apps/src/contracts/protocols/4.d.ts +1306 -0
  74. package/types/apps/src/contracts/protocols/5.d.ts +1200 -0
  75. package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
  76. package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
  77. package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
  78. package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
  79. package/types/apps/src/contracts/protocols/current.d.ts +2476 -0
  80. package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
  81. package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
  82. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  83. package/types/apps/src/contracts/provider.d.ts +115 -10
  84. package/types/apps/src/contracts/router.d.ts +59 -0
  85. package/types/apps/src/contracts/skills.d.ts +50 -13
  86. package/types/apps/src/contracts/sql.d.ts +58 -0
  87. package/types/apps/src/contracts/ui.d.ts +19 -1
  88. package/types/apps/src/contracts/workflows.d.ts +6 -0
  89. package/types/apps/src/facet.d.ts +4 -5
  90. package/types/apps/src/graphql.d.ts +1 -3
  91. package/types/apps/src/host.d.ts +5 -0
  92. package/types/apps/src/implementation/account-router.d.ts +13 -0
  93. package/types/apps/src/implementation/app.d.ts +5 -4
  94. package/types/apps/src/implementation/authoring.d.ts +25 -5
  95. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  96. package/types/apps/src/implementation/cache.d.ts +4 -0
  97. package/types/apps/src/implementation/catalog-cache.d.ts +43 -5
  98. package/types/apps/src/implementation/elicitation.d.ts +18 -15
  99. package/types/apps/src/implementation/events.d.ts +59 -0
  100. package/types/apps/src/implementation/failure-detail.d.ts +25 -3
  101. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  102. package/types/apps/src/implementation/graphql.d.ts +4 -3
  103. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  104. package/types/apps/src/implementation/invocation-timing.d.ts +16 -0
  105. package/types/apps/src/implementation/live.d.ts +2 -2
  106. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  107. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  108. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  109. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  110. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  111. package/types/apps/src/implementation/mcp.d.ts +52 -25
  112. package/types/apps/src/implementation/network.d.ts +16 -0
  113. package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
  114. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  115. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  116. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  117. package/types/apps/src/implementation/openapi-source.d.ts +8 -6
  118. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  119. package/types/apps/src/implementation/operations.d.ts +43 -5
  120. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  121. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  122. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  123. package/types/apps/src/implementation/provider.d.ts +19 -5
  124. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  125. package/types/apps/src/implementation/router-catalog.d.ts +223 -0
  126. package/types/apps/src/implementation/router.d.ts +70 -0
  127. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  128. package/types/apps/src/implementation/schema.d.ts +95 -11
  129. package/types/apps/src/implementation/skills.d.ts +18 -24
  130. package/types/apps/src/implementation/sql.d.ts +71 -0
  131. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  132. package/types/apps/src/implementation/ui-auth.d.ts +1 -1
  133. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  134. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  135. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  136. package/types/apps/src/implementation/ui-serving.d.ts +11 -5
  137. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  138. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  139. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  140. package/types/apps/src/implementation/workflow-context.d.ts +1 -1
  141. package/types/apps/src/implementation/workflows.d.ts +1 -1
  142. package/types/apps/src/index.d.ts +32 -13
  143. package/types/apps/src/mcp-stdio.d.ts +2 -5
  144. package/types/apps/src/mcp.d.ts +25 -5
  145. package/types/apps/src/openapi.d.ts +6 -6
  146. package/types/apps/src/react.d.ts +1 -1
  147. package/types/apps/src/skills.d.ts +10 -8
  148. package/types/telemetry/src/app-records.d.ts +42 -0
  149. package/types/telemetry/src/browser-operations.d.ts +7 -4
  150. package/types/telemetry/src/browser.d.ts +8 -3
  151. package/types/telemetry/src/config.d.ts +2 -2
  152. package/types/telemetry/src/index.d.ts +1 -0
  153. package/types/telemetry/src/layer.d.ts +2 -2
  154. package/types/telemetry/src/ownership.d.ts +56 -0
  155. package/types/telemetry/src/recorded-failure.d.ts +29 -0
  156. package/types/telemetry/src/relay.d.ts +2 -2
  157. package/types/telemetry/src/transport.d.ts +8 -1
  158. package/types/utils/src/api-error.d.ts +55 -0
  159. package/types/utils/src/connection-failure.d.ts +33 -0
  160. package/types/utils/src/recorded-message.d.ts +18 -0
  161. package/types/utils/src/user-facing-error.d.ts +83 -0
  162. package/js/chunk-3XKZDQLM.js +0 -93
  163. package/js/chunk-4M277YTM.js +0 -136
  164. package/js/chunk-67EVWIGJ.js +0 -224
  165. package/js/chunk-C3VAOK5B.js +0 -215
  166. package/js/chunk-DQAZTA4I.js +0 -2375
  167. package/js/chunk-G7T27IWB.js +0 -63
  168. package/js/chunk-LUVSFETN.js +0 -1347
  169. package/js/chunk-N7YDVXYJ.js +0 -186
  170. package/js/chunk-PJJ24GU7.js +0 -877
  171. package/js/chunk-PZB6T6KU.js +0 -19
  172. package/js/chunk-SB3V4YVR.js +0 -18
  173. package/js/chunk-TDNYXSIX.js +0 -29
  174. package/js/chunk-W4DMKWAB.js +0 -35
  175. package/js/chunk-YEPYT6SD.js +0 -85
  176. package/js/chunk-ZQINWV4W.js +0 -630
  177. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  178. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  179. package/types/app-data/src/implementation/promise.d.ts +0 -68
  180. package/types/app-data/src/implementation/range.d.ts +0 -8
  181. package/types/app-data/src/implementation/schema.d.ts +0 -18
  182. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  183. package/types/app-data/src/index.d.ts +0 -4
  184. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  185. package/types/apps/src/contracts/storage.d.ts +0 -68
  186. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  187. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
  188. package/types/apps/src/implementation/storage.d.ts +0 -15
@@ -1,26 +1,42 @@
1
+ import {
2
+ fromPromise,
3
+ method,
4
+ toPromise
5
+ } from "./chunk-LTDHQJ2Z.js";
1
6
  import {
2
7
  CacheError
3
- } from "./chunk-YEPYT6SD.js";
8
+ } from "./chunk-MWKHKOTL.js";
4
9
  import {
5
10
  wrap
6
- } from "./chunk-FWQC6I3C.js";
11
+ } from "./chunk-KGCTYL2S.js";
7
12
  import {
8
13
  JsonObject
9
- } from "./chunk-27F7W2LG.js";
14
+ } from "./chunk-H2CJWXA3.js";
10
15
  import {
16
+ Deferred_exports,
11
17
  Duration_exports,
12
18
  Effect_exports,
13
19
  Schema_exports
14
- } from "./chunk-CDL5PM2Q.js";
20
+ } from "./chunk-IFJU5SYQ.js";
15
21
 
16
22
  // src/implementation/catalog-cache.ts
23
+ var catalogScope = (options, credential, invalid) => {
24
+ const { account, cache } = options;
25
+ if (account === void 0)
26
+ return credential === void 0 ? Effect_exports.succeed(cache) : Effect_exports.fail(invalid("missing-account"));
27
+ if (cache === void 0) return Effect_exports.succeed(void 0);
28
+ return Effect_exports.try({
29
+ try: () => cache.forAccount(account),
30
+ catch: () => invalid("unselected-account")
31
+ });
32
+ };
17
33
  var schema = (decoder) => wrap(decoder, false);
18
34
  var Manifest = Schema_exports.Struct({
19
35
  revision: Schema_exports.String,
20
36
  pages: Schema_exports.Int,
21
- summaries: Schema_exports.Int
37
+ summaries: Schema_exports.Int,
38
+ header: Schema_exports.optionalKey(JsonObject)
22
39
  });
23
- var invoke = (work) => Effect_exports.tryPromise({ try: work, catch: (error) => error });
24
40
  var catalogCache = (options) => Effect_exports.gen(function* () {
25
41
  const cache = options.cache;
26
42
  const key = [...options.prefix, "current"];
@@ -34,11 +50,42 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
34
50
  const staleFor = options.staleFor ?? "1 day";
35
51
  const retention = Duration_exports.toMillis(Duration_exports.fromInputUnsafe(freshFor)) + Duration_exports.toMillis(Duration_exports.fromInputUnsafe(staleFor)) + 3e5;
36
52
  const local = yield* Effect_exports.cached(options.load());
37
- const refresh = (context) => Effect_exports.gen(function* () {
38
- const tools = yield* options.load(context);
39
- const digest = yield* invoke(
40
- () => crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify(tools)))
53
+ const pages = (cache2, revision, kind, count, decoder) => Effect_exports.gen(function* () {
54
+ const batches = yield* Effect_exports.forEach(
55
+ Array.from({ length: Math.ceil(count / 4) }, (_, batch) => batch * 4),
56
+ (offset) => fromPromise(method(cache2, "readMany"), "cache")(
57
+ Array.from(
58
+ { length: Math.min(4, count - offset) },
59
+ (_, index) => part(revision, kind, offset + index)
60
+ ),
61
+ schema(Schema_exports.Array(decoder))
62
+ ),
63
+ { concurrency: "unbounded" }
41
64
  );
65
+ const values = [];
66
+ for (const page of batches.flat()) {
67
+ if (page === void 0) return yield* new CacheError({ reason: "unavailable" });
68
+ values.push(...page);
69
+ }
70
+ return values;
71
+ });
72
+ const kept = (cache2) => fromPromise(method(cache2, "read"), "cache")(key, schema(Manifest)).pipe(
73
+ Effect_exports.map(
74
+ (manifest) => manifest === void 0 ? void 0 : {
75
+ header: manifest.header,
76
+ tools: pages(cache2, manifest.revision, "page", manifest.pages, options.schema)
77
+ }
78
+ )
79
+ );
80
+ const refresh = (context) => Effect_exports.gen(function* () {
81
+ const { tools, header } = yield* options.load(context, kept(context.cache));
82
+ const digest = yield* Effect_exports.tryPromise({
83
+ try: () => crypto.subtle.digest(
84
+ "SHA-256",
85
+ new TextEncoder().encode(JSON.stringify({ tools, header: header ?? null }))
86
+ ),
87
+ catch: (error) => error
88
+ });
42
89
  const revision = Array.from(
43
90
  new Uint8Array(digest),
44
91
  (byte) => byte.toString(16).padStart(2, "0")
@@ -58,7 +105,7 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
58
105
  batch = [];
59
106
  batchBytes = 0;
60
107
  if (!entries.length) return Effect_exports.void;
61
- return invoke(() => context.cache.write(entries, retention)).pipe(
108
+ return fromPromise(method(context.cache, "write"), "cache")(entries, retention).pipe(
62
109
  Effect_exports.withSpan("app.cache.flush", {
63
110
  attributes: {
64
111
  "cache.flush.index": flushes++,
@@ -104,50 +151,56 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
104
151
  yield* pageOut();
105
152
  yield* summaryOut();
106
153
  yield* flush();
107
- return { revision, pages: pages2, summaries };
154
+ return {
155
+ revision,
156
+ pages: pages2,
157
+ summaries,
158
+ ...header === void 0 ? {} : { header: yield* json(header) }
159
+ };
108
160
  });
109
161
  const getOptions = {
110
162
  key,
111
163
  schema: schema(Manifest),
112
164
  freshFor,
113
165
  staleFor,
114
- load: (context) => Effect_exports.runPromise(refresh(context), { signal: context.signal })
166
+ ...options.stale === void 0 ? {} : { stale: options.stale },
167
+ // A cache may call the loader as a Promise; its own signal cancels that load.
168
+ load: toPromise(refresh, (context) => context.signal)
115
169
  };
116
- const current = () => cache === void 0 ? Effect_exports.fail(new CacheError({ reason: "unavailable" })) : invoke(() => cache.get(getOptions));
170
+ let reading;
171
+ const current = () => Effect_exports.suspend(() => {
172
+ if (cache === void 0) return Effect_exports.fail(new CacheError({ reason: "unavailable" }));
173
+ const shared = reading;
174
+ if (shared !== void 0) return Deferred_exports.await(shared);
175
+ const deferred = Deferred_exports.makeUnsafe();
176
+ reading = deferred;
177
+ return fromPromise(
178
+ method(cache, "get"),
179
+ "cache"
180
+ )(getOptions).pipe(
181
+ Effect_exports.onExit(
182
+ (exit) => Effect_exports.sync(() => {
183
+ if (reading === deferred) reading = void 0;
184
+ }).pipe(Effect_exports.andThen(Deferred_exports.done(deferred, exit)))
185
+ )
186
+ );
187
+ });
117
188
  if (options.revalidate) {
118
189
  if (cache === void 0) yield* local;
119
- else yield* invoke(() => cache.revalidate(getOptions));
190
+ else yield* fromPromise(method(cache, "revalidate"), "cache")(getOptions);
120
191
  }
121
- const pages = (cache2, revision, kind, count, decoder) => Effect_exports.gen(function* () {
122
- const batches = yield* Effect_exports.forEach(
123
- Array.from({ length: Math.ceil(count / 4) }, (_, batch) => batch * 4),
124
- (offset) => invoke(
125
- () => cache2.readMany(
126
- Array.from(
127
- { length: Math.min(4, count - offset) },
128
- (_, index) => part(revision, kind, offset + index)
129
- ),
130
- schema(Schema_exports.Array(decoder))
131
- )
132
- ),
133
- { concurrency: "unbounded" }
134
- );
135
- const values = [];
136
- for (const page of batches.flat()) {
137
- if (page === void 0) return yield* new CacheError({ reason: "unavailable" });
138
- values.push(...page);
139
- }
140
- return values;
141
- });
142
192
  const metadata = () => Effect_exports.gen(function* () {
143
- if (cache === void 0) return yield* local;
193
+ if (cache === void 0) return (yield* local).tools;
144
194
  const manifest = yield* current();
145
195
  return yield* pages(cache, manifest.revision, "page", manifest.pages, options.schema);
146
196
  });
147
197
  return {
148
198
  list: metadata,
199
+ /** The record stored with the current revision, if the source supplied one. */
200
+ header: () => cache === void 0 ? local.pipe(Effect_exports.map(({ header }) => header)) : current().pipe(Effect_exports.map((manifest) => manifest.header)),
149
201
  summaries: () => Effect_exports.gen(function* () {
150
- if (cache === void 0) return (yield* local).map((tool) => options.summary.of(tool));
202
+ if (cache === void 0)
203
+ return (yield* local).tools.map((tool) => options.summary.of(tool));
151
204
  const manifest = yield* current();
152
205
  return yield* pages(
153
206
  cache,
@@ -157,10 +210,11 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
157
210
  options.summary.schema
158
211
  );
159
212
  }),
160
- resolve: (name) => cache === void 0 ? local.pipe(Effect_exports.map((tools) => tools.find((tool) => tool.name === name))) : current().pipe(
213
+ resolve: (name) => cache === void 0 ? local.pipe(Effect_exports.map(({ tools }) => tools.find((tool) => tool.name === name))) : current().pipe(
161
214
  Effect_exports.flatMap(
162
- (manifest) => invoke(
163
- () => cache.read(part(manifest.revision, "tool", name), schema(options.schema))
215
+ (manifest) => fromPromise(method(cache, "read"), "cache")(
216
+ part(manifest.revision, "tool", name),
217
+ schema(options.schema)
164
218
  )
165
219
  )
166
220
  )
@@ -168,5 +222,6 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
168
222
  });
169
223
 
170
224
  export {
225
+ catalogScope,
171
226
  catalogCache
172
227
  };
@@ -5,11 +5,11 @@ import {
5
5
  SkillDefinitionInvalid,
6
6
  SkillFile,
7
7
  SkillFilePath
8
- } from "./chunk-JU7VHODU.js";
8
+ } from "./chunk-H72MEDMN.js";
9
9
  import {
10
10
  Effect_exports,
11
11
  Schema_exports
12
- } from "./chunk-CDL5PM2Q.js";
12
+ } from "./chunk-IFJU5SYQ.js";
13
13
 
14
14
  // src/implementation/skill-files.ts
15
15
  var skillFromFiles = (input, source = {}) => Effect_exports.gen(function* () {
@@ -0,0 +1,340 @@
1
+ import {
2
+ adaptMcpTools,
3
+ answeredError,
4
+ mcpClient,
5
+ mcpJsonSchemaValidator
6
+ } from "./chunk-JK5S2N2S.js";
7
+ import {
8
+ failOnNetworkRefusal
9
+ } from "./chunk-7UUHJR2Q.js";
10
+ import {
11
+ accountProviderError,
12
+ bodyUpstreamError,
13
+ httpProviderError,
14
+ providerErrorDetail
15
+ } from "./chunk-LTDHQJ2Z.js";
16
+ import {
17
+ McpCredentialsUnverified,
18
+ McpError,
19
+ McpHealthInput,
20
+ McpToolsOptions,
21
+ defaultMcpClientLimits,
22
+ mcpHealthReserveMs
23
+ } from "./chunk-TLWLJ7PD.js";
24
+ import {
25
+ NetworkRefused,
26
+ ProviderError
27
+ } from "./chunk-MWKHKOTL.js";
28
+ import {
29
+ captureTelemetry,
30
+ owned
31
+ } from "./chunk-JM7LOD2W.js";
32
+ import {
33
+ FetchHttpClient_exports
34
+ } from "./chunk-PD6I2SDG.js";
35
+ import {
36
+ HttpClientRequest_exports,
37
+ HttpClient_exports
38
+ } from "./chunk-EOPQ727L.js";
39
+ import {
40
+ Clock_exports,
41
+ Deferred_exports,
42
+ Effect_exports,
43
+ Match_exports,
44
+ Option_exports,
45
+ Predicate_exports,
46
+ Redacted_exports,
47
+ Ref_exports,
48
+ Schema_exports,
49
+ Stream_exports
50
+ } from "./chunk-IFJU5SYQ.js";
51
+
52
+ // src/implementation/mcp.ts
53
+ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
54
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
55
+ import {
56
+ ErrorCode,
57
+ McpError as ProtocolError,
58
+ ToolListChangedNotificationSchema
59
+ } from "@modelcontextprotocol/sdk/types.js";
60
+ import { SSEClientTransport, SseError } from "@modelcontextprotocol/sdk/client/sse.js";
61
+ import {
62
+ StreamableHTTPClientTransport,
63
+ StreamableHTTPError
64
+ } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
65
+ var unreadable = (error) => error instanceof SyntaxError || error instanceof Error && Predicate_exports.hasProperty(error, "issues") && Array.isArray(error.issues);
66
+ var failure = (phase, error) => {
67
+ if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error) || Schema_exports.is(NetworkRefused)(error))
68
+ return error;
69
+ const code = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
70
+ if (code !== void 0 && code >= 300 && code <= 599)
71
+ return httpProviderError(code) ?? new McpError({ phase, reason: "request", status: code });
72
+ const upstream = answeredError(error);
73
+ return new McpError({
74
+ phase,
75
+ reason: code !== void 0 || unreadable(error) ? "invalid_response" : error instanceof ProtocolError && error.code === ErrorCode.RequestTimeout ? "timeout" : "request",
76
+ ...upstream === void 0 ? {} : { upstream }
77
+ });
78
+ };
79
+ var errorBodyLimits = { maxBytes: 65536, readTimeoutMs: 2e3 };
80
+ var errorBody = (response) => Effect_exports.gen(function* () {
81
+ const json = /^application\/(?:[\w.-]+\+)?json$/i.test(
82
+ response.headers["content-type"]?.split(";")[0]?.trim() ?? ""
83
+ );
84
+ const length = response.headers["content-length"];
85
+ if (!json || length !== void 0 && Number(length) > errorBodyLimits.maxBytes)
86
+ return { body: Stream_exports.toReadableStream(response.stream), upstream: void 0 };
87
+ const unreadable2 = new McpError({ phase: "transport", reason: "invalid_response" });
88
+ const read = yield* response.stream.pipe(
89
+ Stream_exports.mapError(() => unreadable2),
90
+ Stream_exports.limitBytes(errorBodyLimits.maxBytes, () => Stream_exports.fail(unreadable2)),
91
+ Stream_exports.decodeText,
92
+ Stream_exports.mkString,
93
+ Effect_exports.timeout(errorBodyLimits.readTimeoutMs),
94
+ Effect_exports.option
95
+ );
96
+ if (Option_exports.isNone(read)) return { body: null, upstream: void 0 };
97
+ const parsed = Schema_exports.decodeUnknownOption(Schema_exports.fromJsonString(Schema_exports.Json))(read.value);
98
+ return {
99
+ body: read.value,
100
+ upstream: Option_exports.isSome(parsed) ? bodyUpstreamError(parsed.value) : void 0
101
+ };
102
+ });
103
+ var transportFetch = (connection, telemetry, rejected, answered) => (url, init) => Effect_exports.runPromiseWith(telemetry.context)(
104
+ Effect_exports.gen(function* () {
105
+ const target = yield* Effect_exports.try({
106
+ try: () => new URL(url),
107
+ catch: () => new McpError({ phase: "transport", reason: "invalid_response" })
108
+ });
109
+ if (connection.url.username || connection.url.password)
110
+ return yield* new McpError({ phase: "transport", reason: "invalid_input" });
111
+ if (target.origin !== connection.url.origin || target.username || target.password)
112
+ return yield* new McpError({ phase: "transport", reason: "invalid_response" });
113
+ const request = yield* Effect_exports.try({
114
+ try: () => {
115
+ const headers = new Headers(Redacted_exports.value(connection.headers));
116
+ new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
117
+ return HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers }));
118
+ },
119
+ // The provider's headers cannot form an HTTP request, such as a name with a space.
120
+ catch: () => new McpError({ phase: "transport", reason: "invalid_input" })
121
+ });
122
+ const client = yield* HttpClient_exports.HttpClient;
123
+ const response = yield* client.execute(request);
124
+ yield* failOnNetworkRefusal(response).pipe(
125
+ Effect_exports.tapError((refused) => Deferred_exports.fail(rejected, refused))
126
+ );
127
+ if (response.status < 400)
128
+ return new Response(
129
+ [204, 205, 304].includes(response.status) ? null : Stream_exports.toReadableStream(response.stream),
130
+ {
131
+ status: response.status,
132
+ headers: response.headers
133
+ }
134
+ );
135
+ const { body, upstream } = yield* errorBody(response);
136
+ const provider = httpProviderError(response.status, response.headers);
137
+ if (provider !== void 0) {
138
+ const refused = providerErrorDetail(provider, { upstream });
139
+ yield* Deferred_exports.fail(rejected, refused);
140
+ return yield* refused;
141
+ }
142
+ const session = new Headers(init?.headers).has("mcp-session-id");
143
+ yield* Ref_exports.update(
144
+ answered,
145
+ (responses) => new Map(responses).set(response.status, { upstream, session })
146
+ );
147
+ return new Response(body, { status: response.status, headers: response.headers });
148
+ }).pipe(
149
+ Effect_exports.provide(FetchHttpClient_exports.layer),
150
+ Effect_exports.provideService(FetchHttpClient_exports.RequestInit, { redirect: "manual" }),
151
+ Effect_exports.provideService(
152
+ FetchHttpClient_exports.Fetch,
153
+ (url2, options) => globalThis.fetch(url2, {
154
+ ...options,
155
+ signal: AbortSignal.any([
156
+ ...options?.signal ? [options.signal] : [],
157
+ ...init?.signal ? [init.signal] : []
158
+ ])
159
+ })
160
+ ),
161
+ Effect_exports.mapError((error) => failure("transport", error))
162
+ ),
163
+ init?.signal ? { signal: init.signal } : {}
164
+ );
165
+ var explain = (error, phase, responses) => {
166
+ if (Schema_exports.is(ProviderError)(error)) return providerErrorDetail(error, { phase });
167
+ if (!Schema_exports.is(McpError)(error) || error.status === void 0) return error;
168
+ const response = responses.get(error.status);
169
+ if (response === void 0 || (error.upstream !== void 0 || response.upstream === void 0) && !response.session)
170
+ return error;
171
+ const upstream = error.upstream ?? response.upstream;
172
+ return new McpError({
173
+ phase: error.phase,
174
+ reason: error.reason,
175
+ status: error.status,
176
+ ...upstream === void 0 ? {} : { upstream },
177
+ ...response.session ? { session: true } : {}
178
+ });
179
+ };
180
+ var explained = (phase, answered) => (error) => Ref_exports.get(answered).pipe(
181
+ Effect_exports.flatMap((responses) => Effect_exports.fail(explain(error, phase, responses)))
182
+ );
183
+ function withClient(connection, mode, use, changed) {
184
+ const attempt = (kind) => Effect_exports.scoped(
185
+ Effect_exports.gen(function* () {
186
+ const telemetry = yield* captureTelemetry;
187
+ const rejected = yield* Deferred_exports.make();
188
+ const answered = yield* Ref_exports.make(/* @__PURE__ */ new Map());
189
+ const pending = /* @__PURE__ */ new Set();
190
+ const { client, transport } = yield* Effect_exports.acquireRelease(
191
+ Effect_exports.sync(() => {
192
+ const fetch = transportFetch(connection, telemetry, rejected, answered);
193
+ const client2 = new Client(
194
+ { name: "executor-apps", version: "0.1.0" },
195
+ {
196
+ jsonSchemaValidator: mcpJsonSchemaValidator,
197
+ capabilities: mode === "call" ? { elicitation: { form: {} } } : {}
198
+ }
199
+ );
200
+ if (changed !== void 0) {
201
+ client2.setNotificationHandler(ToolListChangedNotificationSchema, () => {
202
+ const task = Effect_exports.runPromiseWith(telemetry.context)(
203
+ changed.pipe(
204
+ Effect_exports.timeout("5 seconds"),
205
+ Effect_exports.catchCause(() => Effect_exports.logWarning("MCP catalog invalidation failed"))
206
+ )
207
+ );
208
+ pending.add(task);
209
+ return task.finally(() => pending.delete(task));
210
+ });
211
+ }
212
+ return {
213
+ client: client2,
214
+ transport: kind === "http" ? new StreamableHTTPClientTransport(connection.url, {
215
+ fetch,
216
+ reconnectionOptions: {
217
+ maxRetries: 0,
218
+ initialReconnectionDelay: 1e3,
219
+ maxReconnectionDelay: 1e3,
220
+ reconnectionDelayGrowFactor: 1
221
+ }
222
+ }) : new SSEClientTransport(connection.url, { fetch })
223
+ };
224
+ }),
225
+ ({ client: client2, transport: transport2 }) => Effect_exports.gen(function* () {
226
+ client2.removeNotificationHandler("notifications/tools/list_changed");
227
+ yield* Effect_exports.promise(async () => {
228
+ await Promise.allSettled(pending);
229
+ });
230
+ if (transport2 instanceof StreamableHTTPClientTransport && transport2.sessionId !== void 0) {
231
+ yield* Effect_exports.tryPromise(() => transport2.terminateSession()).pipe(
232
+ Effect_exports.timeout(defaultMcpClientLimits.cleanupTimeoutMs),
233
+ Effect_exports.ignore
234
+ );
235
+ }
236
+ yield* Effect_exports.tryPromise(() => client2.close()).pipe(
237
+ Effect_exports.timeout(defaultMcpClientLimits.cleanupTimeoutMs),
238
+ Effect_exports.ignore
239
+ );
240
+ }).pipe(owned("upstream", "provider.mcp.close"))
241
+ );
242
+ const wire = transport;
243
+ yield* Effect_exports.tryPromise({
244
+ try: (signal) => client.connect(wire, { signal, timeout: connection.timeoutMs }),
245
+ catch: (error) => failure("connect", error)
246
+ }).pipe(
247
+ Effect_exports.raceFirst(Deferred_exports.await(rejected)),
248
+ Effect_exports.catch(explained("connect", answered)),
249
+ Effect_exports.timeout(connection.timeoutMs),
250
+ owned("upstream", "provider.mcp.connect")
251
+ );
252
+ return yield* use(client).pipe(
253
+ Effect_exports.raceFirst(Deferred_exports.await(rejected)),
254
+ Effect_exports.catch(explained(mode, answered))
255
+ );
256
+ })
257
+ ).pipe(
258
+ owned("upstream", "provider.mcp.session", {
259
+ attributes: {
260
+ "mcp.transport": kind,
261
+ "mcp.operation": mode,
262
+ "server.address": connection.url.hostname
263
+ }
264
+ })
265
+ );
266
+ return attempt("http").pipe(
267
+ // Fallback is only for negotiation. Tool calls are never automatically replayed.
268
+ Effect_exports.catch(
269
+ (error) => Schema_exports.is(McpError)(error) && error.phase === "connect" && (error.status === 404 || error.status === 405) ? attempt("sse") : Effect_exports.fail(error)
270
+ ),
271
+ (operation) => mode === "discover" ? operation.pipe(Effect_exports.timeout(connection.timeoutMs)) : operation,
272
+ Effect_exports.catchTag(
273
+ "TimeoutError",
274
+ () => Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
275
+ )
276
+ );
277
+ }
278
+ var mcpClientEffect = (input, changed) => Effect_exports.gen(function* () {
279
+ const options = yield* Schema_exports.decodeUnknownEffect(McpToolsOptions)(input).pipe(
280
+ Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" }))
281
+ );
282
+ const url = new URL(options.url);
283
+ if (url.username || url.password || url.hash)
284
+ return yield* new McpError({ phase: "connect", reason: "invalid_input" });
285
+ const connection = {
286
+ url,
287
+ headers: Redacted_exports.make({ ...options.headers }),
288
+ timeoutMs: options.timeoutMs ?? defaultMcpClientLimits.timeoutMs
289
+ };
290
+ return mcpClient(
291
+ (mode, use) => withClient(connection, mode, use, changed).pipe(
292
+ Effect_exports.mapError(
293
+ (error) => options.accountId === void 0 ? error : accountProviderError(error, options.accountId)
294
+ )
295
+ ),
296
+ connection.timeoutMs,
297
+ failure
298
+ );
299
+ });
300
+ var refusesCredentials = (error) => Schema_exports.is(ProviderError)(error) && Match_exports.value(error.reason).pipe(
301
+ Match_exports.whenOr("unauthorized", "forbidden", "rejected", () => true),
302
+ Match_exports.whenOr("rate_limited", "unavailable", () => false),
303
+ Match_exports.exhaustive
304
+ );
305
+ var mcpHealthEffect = (check, options) => Effect_exports.gen(function* () {
306
+ const { deadline, timeoutMs, ...parsed } = yield* Schema_exports.decodeUnknownEffect(McpHealthInput)({
307
+ ...options,
308
+ accountId: check.account.id,
309
+ signal: check.signal,
310
+ deadline: check.deadline
311
+ }).pipe(Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" })));
312
+ const end = Math.min(
313
+ (yield* Clock_exports.currentTimeMillis) + (timeoutMs ?? defaultMcpClientLimits.timeoutMs),
314
+ deadline === void 0 ? Number.POSITIVE_INFINITY : deadline - mcpHealthReserveMs
315
+ );
316
+ const remaining = Effect_exports.flatMap(
317
+ Clock_exports.currentTimeMillis,
318
+ (now) => end - now >= 1 ? Effect_exports.succeed(Math.floor(end - now)) : Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
319
+ );
320
+ yield* (yield* mcpClientEffect({ ...parsed, timeoutMs: yield* remaining })).check;
321
+ return yield* remaining.pipe(
322
+ Effect_exports.flatMap(
323
+ (timeoutMs2) => mcpClientEffect({ url: parsed.url, signal: parsed.signal, timeoutMs: timeoutMs2 })
324
+ ),
325
+ Effect_exports.flatMap((anonymous) => anonymous.check),
326
+ Effect_exports.matchEffect({
327
+ onSuccess: () => Effect_exports.fail(new McpCredentialsUnverified({ anonymous: "answered" })),
328
+ // Executor's network refused the attempt, so the server never answered it.
329
+ onFailure: (error) => Schema_exports.is(NetworkRefused)(error) ? Effect_exports.fail(error) : refusesCredentials(error) ? Effect_exports.void : Effect_exports.fail(new McpCredentialsUnverified({ anonymous: error }))
330
+ }),
331
+ owned("upstream", "provider.mcp.anonymous")
332
+ );
333
+ }).pipe(owned("upstream", "provider.mcp.health"));
334
+ var mcpToolsEffect = (input) => mcpClientEffect(input).pipe(Effect_exports.flatMap(adaptMcpTools));
335
+
336
+ export {
337
+ mcpClientEffect,
338
+ mcpHealthEffect,
339
+ mcpToolsEffect
340
+ };