apps 0.0.1-beta.26 → 0.0.1-beta.28

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 (72) hide show
  1. package/README.md +6 -6
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-AAAMPT6F.js → chunk-65SZ23BK.js} +2 -2
  4. package/js/{chunk-XBG3M64K.js → chunk-6JBTHTI5.js} +1 -1
  5. package/js/{chunk-OBXHLFGQ.js → chunk-B5YJQU45.js} +1 -1
  6. package/js/{chunk-T7WRQJUF.js → chunk-BRGF7VFN.js} +2 -2
  7. package/js/{chunk-HQKIPKM5.js → chunk-BTJMXW4I.js} +1 -1
  8. package/js/{chunk-BTRBOOTD.js → chunk-GLIAMV2R.js} +29 -23
  9. package/js/{chunk-WPKXOTKM.js → chunk-GQ7GCZ4J.js} +3 -3
  10. package/js/{chunk-EXDR4HVM.js → chunk-JN3PEGMW.js} +109 -12
  11. package/js/{chunk-DAIW2WM3.js → chunk-KQCMHI3K.js} +3 -3
  12. package/js/{chunk-HIYRKEWP.js → chunk-L76NWXM5.js} +74 -22
  13. package/js/{chunk-GH6PY5BQ.js → chunk-M2KEEOIQ.js} +1 -1
  14. package/js/{chunk-OI7OI2U3.js → chunk-MWCLJQRI.js} +2 -2
  15. package/js/{chunk-TACLXEAE.js → chunk-NSBRV4FJ.js} +1 -1
  16. package/js/{chunk-DM5U7G7V.js → chunk-NXTXZ635.js} +1842 -1840
  17. package/js/{chunk-3YN4UDPB.js → chunk-PTUZSCEV.js} +2 -2
  18. package/js/{chunk-KKGRSXUK.js → chunk-PWF2DRJ3.js} +1 -1
  19. package/js/{chunk-2TP7C25K.js → chunk-SDLIDQXG.js} +3 -3
  20. package/js/{chunk-VGEPL4BV.js → chunk-TE2HPDZG.js} +110 -5
  21. package/js/{chunk-PC5RHPUP.js → chunk-TSLG2WPA.js} +2 -2
  22. package/js/{chunk-KNJAOYV4.js → chunk-V2I3MMPM.js} +2 -2
  23. package/js/{chunk-NXO2GN2T.js → chunk-VF3X26ZO.js} +8 -8
  24. package/js/{chunk-4CMJD7AB.js → chunk-VIQQ52V7.js} +24 -8
  25. package/js/{chunk-ZVMZWXVF.js → chunk-VUVBMNKC.js} +2 -2
  26. package/js/{chunk-SUY33XAY.js → chunk-WQ5MVBTP.js} +1 -1
  27. package/js/{chunk-LPN4ONWW.js → chunk-XBQTJP76.js} +2 -2
  28. package/js/{chunk-IE6W5RNN.js → chunk-YML53Z7H.js} +2 -2
  29. package/js/{chunk-DUEZ2XCO.js → chunk-YXKXKGN6.js} +3 -3
  30. package/js/{chunk-XIRAIB3P.js → chunk-ZZOCEUTB.js} +4 -4
  31. package/js/client.js +10 -10
  32. package/js/contracts.js +19 -7
  33. package/js/effect.js +19 -19
  34. package/js/graphql.js +28 -23
  35. package/js/host.js +19 -19
  36. package/js/index.js +16 -12
  37. package/js/mcp/effect.js +23 -21
  38. package/js/mcp/stdio.js +21 -21
  39. package/js/mcp.js +29 -24
  40. package/js/openapi.js +20 -16
  41. package/js/react.js +3 -3
  42. package/js/skills/effect.js +3 -3
  43. package/js/skills.js +11 -11
  44. package/js/storage/facet.js +4 -4
  45. package/js/ui/auth/contracts.js +2 -2
  46. package/js/ui/auth.js +5 -5
  47. package/js/ui/contracts.js +4 -4
  48. package/js/ui/serving.js +8 -8
  49. package/package.json +1 -1
  50. package/runtime.json +1 -1
  51. package/types/apps/src/contracts/graphql.d.ts +2 -1
  52. package/types/apps/src/contracts/host.d.ts +1 -0
  53. package/types/apps/src/contracts/mcp.d.ts +51 -4
  54. package/types/apps/src/contracts/network.d.ts +84 -0
  55. package/types/apps/src/contracts/openapi.d.ts +2 -1
  56. package/types/apps/src/contracts/provider.d.ts +6 -0
  57. package/types/apps/src/implementation/elicitation.d.ts +8 -8
  58. package/types/apps/src/implementation/failure-detail.d.ts +3 -2
  59. package/types/apps/src/implementation/graphql.d.ts +4 -3
  60. package/types/apps/src/implementation/mcp-call.d.ts +3 -2
  61. package/types/apps/src/implementation/mcp-client.d.ts +7 -5
  62. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  63. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  64. package/types/apps/src/implementation/mcp.d.ts +16 -5
  65. package/types/apps/src/implementation/network.d.ts +16 -0
  66. package/types/apps/src/implementation/openapi-compile.d.ts +1 -1
  67. package/types/apps/src/implementation/openapi-request.d.ts +2 -1
  68. package/types/apps/src/implementation/router-catalog.d.ts +6 -6
  69. package/types/apps/src/implementation/skills.d.ts +2 -2
  70. package/types/apps/src/index.d.ts +1 -0
  71. package/types/apps/src/mcp.d.ts +20 -1
  72. package/types/apps/src/skills.d.ts +4 -4
@@ -3,7 +3,7 @@ import {
3
3
  invalidate,
4
4
  layer,
5
5
  mutation
6
- } from "./chunk-XBG3M64K.js";
6
+ } from "./chunk-6JBTHTI5.js";
7
7
  import {
8
8
  Boolean,
9
9
  Cause,
@@ -158,7 +158,7 @@ import {
158
158
  void_2,
159
159
  whileLoop,
160
160
  zipRight
161
- } from "./chunk-DM5U7G7V.js";
161
+ } from "./chunk-NXTXZ635.js";
162
162
  import {
163
163
  __export
164
164
  } from "./chunk-CZ7CSFO4.js";
@@ -58,7 +58,7 @@ import {
58
58
  useSpan,
59
59
  void_2 as void_,
60
60
  withFiber
61
- } from "./chunk-DM5U7G7V.js";
61
+ } from "./chunk-NXTXZ635.js";
62
62
 
63
63
  // ../../node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect+effect@c7d1ffff31a3e2ae0b0b+a654a55b752bdb24/node_modules/effect/dist/unstable/reactivity/Reactivity.js
64
64
  var TypeId = "~effect/reactivity/Reactivity";
@@ -211,7 +211,7 @@ import {
211
211
  withFiber,
212
212
  withParentSpan,
213
213
  zero2 as zero
214
- } from "./chunk-DM5U7G7V.js";
214
+ } from "./chunk-NXTXZ635.js";
215
215
  import {
216
216
  __export
217
217
  } from "./chunk-CZ7CSFO4.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  AccountId
3
- } from "./chunk-KKGRSXUK.js";
3
+ } from "./chunk-PWF2DRJ3.js";
4
4
  import {
5
5
  Schema_exports
6
- } from "./chunk-DM5U7G7V.js";
6
+ } from "./chunk-NXTXZ635.js";
7
7
 
8
8
  // src/contracts/failure.ts
9
9
  var maxFailureMessageLength = 2048;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Schema_exports
3
- } from "./chunk-DM5U7G7V.js";
3
+ } from "./chunk-NXTXZ635.js";
4
4
 
5
5
  // src/contracts/storage.ts
6
6
  var StorageName = Schema_exports.NonEmptyString.check(Schema_exports.isMaxLength(200));
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  makeCache
3
- } from "./chunk-ZVMZWXVF.js";
3
+ } from "./chunk-VUVBMNKC.js";
4
4
  import {
5
5
  accountSecrets,
6
+ appInvocationFetch,
6
7
  boundFailureMessage,
7
8
  describeFailure,
8
9
  failureDetail,
@@ -10,32 +11,32 @@ import {
10
11
  parseMcpError,
11
12
  readCatalog,
12
13
  routerSkills
13
- } from "./chunk-EXDR4HVM.js";
14
+ } from "./chunk-JN3PEGMW.js";
14
15
  import {
15
16
  folderSkillsEffect
16
- } from "./chunk-PC5RHPUP.js";
17
+ } from "./chunk-TSLG2WPA.js";
17
18
  import {
18
19
  ResponseStatusError,
19
20
  authorDatabase,
20
21
  isApp,
21
22
  toEffectApp,
22
23
  unavailableStorage
23
- } from "./chunk-NXO2GN2T.js";
24
+ } from "./chunk-VF3X26ZO.js";
24
25
  import {
25
26
  parseDatabaseSchema
26
- } from "./chunk-LPN4ONWW.js";
27
+ } from "./chunk-XBQTJP76.js";
27
28
  import {
28
29
  declaredOperations,
29
30
  fromPromise,
30
31
  locate,
31
32
  nativeOperation,
32
33
  toPromise
33
- } from "./chunk-WPKXOTKM.js";
34
+ } from "./chunk-GQ7GCZ4J.js";
34
35
  import {
35
36
  accountProviderError,
36
37
  httpProviderError,
37
38
  parseProviderError
38
- } from "./chunk-DAIW2WM3.js";
39
+ } from "./chunk-KQCMHI3K.js";
39
40
  import {
40
41
  AccountCheckResult,
41
42
  DeclaredProvider,
@@ -82,29 +83,28 @@ import {
82
83
  defaultWebhookTransportLimits,
83
84
  maxInputProblems,
84
85
  workflowDurationMillis
85
- } from "./chunk-VGEPL4BV.js";
86
+ } from "./chunk-TE2HPDZG.js";
86
87
  import {
87
88
  CacheError
88
- } from "./chunk-T7WRQJUF.js";
89
+ } from "./chunk-BRGF7VFN.js";
89
90
  import {
90
91
  AppSkills,
91
92
  SkillFile,
92
93
  SkillLoadFailed
93
- } from "./chunk-TACLXEAE.js";
94
+ } from "./chunk-NSBRV4FJ.js";
94
95
  import {
95
- captureTelemetry,
96
- invocationFetch
97
- } from "./chunk-DUEZ2XCO.js";
96
+ captureTelemetry
97
+ } from "./chunk-YXKXKGN6.js";
98
98
  import {
99
99
  decoderOf,
100
100
  importedJsonSchema,
101
101
  jsonSchemaDecoder,
102
102
  jsonSchemaDocument
103
- } from "./chunk-IE6W5RNN.js";
103
+ } from "./chunk-YML53Z7H.js";
104
104
  import {
105
105
  JsonObject,
106
106
  JsonValue
107
- } from "./chunk-KKGRSXUK.js";
107
+ } from "./chunk-PWF2DRJ3.js";
108
108
  import {
109
109
  Cause_exports,
110
110
  Clock_exports,
@@ -116,7 +116,7 @@ import {
116
116
  SchemaIssue_exports,
117
117
  Schema_exports,
118
118
  Stream_exports
119
- } from "./chunk-DM5U7G7V.js";
119
+ } from "./chunk-NXTXZ635.js";
120
120
 
121
121
  // src/implementation/elicitation.ts
122
122
  var prepareElicitation = (input) => Effect_exports.gen(function* () {
@@ -505,7 +505,7 @@ var authorCache = (host, accounts, signal, deadline) => {
505
505
  ...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
506
506
  load: Effect_exports.acquireUseRelease(
507
507
  Effect_exports.sync(() => new AbortController()),
508
- (controller) => invocationFetch(controller.signal).pipe(
508
+ (controller) => appInvocationFetch(controller.signal).pipe(
509
509
  Effect_exports.flatMap(
510
510
  (fetch) => fromPromise(options.load)({
511
511
  fetch,
@@ -805,7 +805,8 @@ function dispatch(app, request, context, signal) {
805
805
  declared,
806
806
  request.requirement,
807
807
  context,
808
- invocationSignal
808
+ invocationSignal,
809
+ deadline
809
810
  ).pipe(withinDeadline);
810
811
  let running;
811
812
  let transactionOpen = false;
@@ -864,7 +865,7 @@ function dispatch(app, request, context, signal) {
864
865
  ),
865
866
  workflows: workflowReads,
866
867
  signal: invocationSignal,
867
- fetch: yield* invocationFetch(fetching.signal),
868
+ fetch: yield* appInvocationFetch(fetching.signal),
868
869
  elicit: makeElicit(delivery, invocationSignal)
869
870
  };
870
871
  const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
@@ -941,7 +942,7 @@ function dispatch(app, request, context, signal) {
941
942
  signal2
942
943
  ),
943
944
  files,
944
- fetch: yield* invocationFetch(signal2),
945
+ fetch: yield* appInvocationFetch(signal2),
945
946
  signal: signal2,
946
947
  runId: execution.runId,
947
948
  stepId,
@@ -1079,7 +1080,7 @@ function dispatch(app, request, context, signal) {
1079
1080
  transactionOpen = db !== void 0;
1080
1081
  const output = yield* Effect_exports.gen(function* () {
1081
1082
  running = yield* captureTelemetry;
1082
- const fetch = yield* invocationFetch(fetching.signal);
1083
+ const fetch = yield* appInvocationFetch(fetching.signal);
1083
1084
  return yield* tool.run(
1084
1085
  {
1085
1086
  ...bound,
@@ -1155,7 +1156,7 @@ function dispatch(app, request, context, signal) {
1155
1156
  })
1156
1157
  );
1157
1158
  }
1158
- function checkAccount(slots, declared, requirement, context, signal) {
1159
+ function checkAccount(slots, declared, requirement, context, signal, deadline) {
1159
1160
  return Effect_exports.gen(function* () {
1160
1161
  const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
1161
1162
  const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
@@ -1172,7 +1173,12 @@ function checkAccount(slots, declared, requirement, context, signal) {
1172
1173
  if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
1173
1174
  const result = yield* Effect_exports.suspend(
1174
1175
  () => Effect_exports.gen(function* () {
1175
- return yield* health.run({ account, fetch: yield* invocationFetch(signal), signal });
1176
+ return yield* health.run({
1177
+ account,
1178
+ fetch: yield* appInvocationFetch(signal),
1179
+ signal,
1180
+ ...deadline === void 0 ? {} : { deadline }
1181
+ });
1176
1182
  })
1177
1183
  ).pipe(
1178
1184
  Effect_exports.catchCause((cause) => {
@@ -3,14 +3,14 @@ import {
3
3
  RouterKey,
4
4
  RouterMeta,
5
5
  reservedRouterKeys
6
- } from "./chunk-VGEPL4BV.js";
6
+ } from "./chunk-TE2HPDZG.js";
7
7
  import {
8
8
  decoderOf
9
- } from "./chunk-IE6W5RNN.js";
9
+ } from "./chunk-YML53Z7H.js";
10
10
  import {
11
11
  Effect_exports,
12
12
  Schema_exports
13
- } from "./chunk-DM5U7G7V.js";
13
+ } from "./chunk-NXTXZ635.js";
14
14
 
15
15
  // src/implementation/authoring.ts
16
16
  var NativeCallback = /* @__PURE__ */ Symbol("apps.NativeCallback");
@@ -1,27 +1,35 @@
1
1
  import {
2
2
  skillFromFiles
3
- } from "./chunk-PC5RHPUP.js";
3
+ } from "./chunk-TSLG2WPA.js";
4
4
  import {
5
5
  joinPath,
6
6
  mergeMeta
7
- } from "./chunk-WPKXOTKM.js";
7
+ } from "./chunk-GQ7GCZ4J.js";
8
8
  import {
9
9
  isShortenedUpstream,
10
10
  parseProviderError,
11
11
  providerError
12
- } from "./chunk-DAIW2WM3.js";
12
+ } from "./chunk-KQCMHI3K.js";
13
13
  import {
14
14
  ApiErrorResponse,
15
+ FetchOptionUnsupported,
15
16
  HostDeclarationInvalid,
16
17
  HostEvaluationFailed,
17
18
  HostedRouter,
18
19
  HostedTool,
19
20
  HostedToolSummary,
20
- McpError
21
- } from "./chunk-VGEPL4BV.js";
21
+ McpCredentialsUnverified,
22
+ McpError,
23
+ NetworkRefused,
24
+ NetworkRefusedHeader,
25
+ RestrictedFetchOption,
26
+ networkRefusalHeader,
27
+ networkRefusalStatus,
28
+ supportedFetchOptions
29
+ } from "./chunk-TE2HPDZG.js";
22
30
  import {
23
31
  AppDatabaseError
24
- } from "./chunk-GH6PY5BQ.js";
32
+ } from "./chunk-M2KEEOIQ.js";
25
33
  import {
26
34
  CacheError,
27
35
  FailureCode,
@@ -30,32 +38,36 @@ import {
30
38
  maxFailureFields,
31
39
  maxFailureMessageLength,
32
40
  maxUpstreamMessageLength
33
- } from "./chunk-T7WRQJUF.js";
41
+ } from "./chunk-BRGF7VFN.js";
34
42
  import {
35
43
  SkillLoadFailed,
36
44
  skillFormatLimits
37
- } from "./chunk-TACLXEAE.js";
45
+ } from "./chunk-NSBRV4FJ.js";
46
+ import {
47
+ invocationFetch
48
+ } from "./chunk-YXKXKGN6.js";
38
49
  import {
39
50
  jsonSchemaDocument
40
- } from "./chunk-IE6W5RNN.js";
51
+ } from "./chunk-YML53Z7H.js";
41
52
  import {
42
53
  AppStorageError,
43
54
  AppStorageUnavailable
44
- } from "./chunk-HQKIPKM5.js";
55
+ } from "./chunk-BTJMXW4I.js";
45
56
  import {
46
57
  AccountId,
47
58
  HttpUrl,
48
59
  JsonObject
49
- } from "./chunk-KKGRSXUK.js";
60
+ } from "./chunk-PWF2DRJ3.js";
50
61
  import {
51
62
  Cause_exports,
52
63
  Effect_exports,
64
+ Match_exports,
53
65
  Option_exports,
54
66
  Predicate_exports,
55
67
  Redacted_exports,
56
68
  Result_exports,
57
69
  Schema_exports
58
- } from "./chunk-DM5U7G7V.js";
70
+ } from "./chunk-NXTXZ635.js";
59
71
 
60
72
  // src/contracts/openapi.ts
61
73
  var OpenapiErrorResponse = Schema_exports.Struct({
@@ -250,6 +262,35 @@ var OpenapiCompileError = class extends Schema_exports.TaggedError()(
250
262
  }
251
263
  };
252
264
 
265
+ // src/implementation/network.ts
266
+ var refusalHeader = (status, header) => status === networkRefusalStatus && header !== null && header !== void 0 ? header : void 0;
267
+ var failOnNetworkRefusal = (response) => {
268
+ const header = refusalHeader(response.status, response.headers[networkRefusalHeader]);
269
+ return header === void 0 ? Effect_exports.void : Schema_exports.decodeUnknownEffect(NetworkRefusedHeader)(header).pipe(
270
+ Effect_exports.orDie,
271
+ Effect_exports.flatMap(Effect_exports.fail)
272
+ );
273
+ };
274
+ var unsupportedOption = (init) => {
275
+ for (const option of RestrictedFetchOption.literals) {
276
+ const value = init?.[option];
277
+ const supported = supportedFetchOptions[option];
278
+ if (value !== void 0 && !supported.includes(value))
279
+ return new FetchOptionUnsupported({ option, value: String(value), supported });
280
+ }
281
+ return void 0;
282
+ };
283
+ var appFetch = (fetch) => async (input, init) => {
284
+ const unsupported = unsupportedOption(init);
285
+ if (unsupported !== void 0) throw unsupported;
286
+ const response = await fetch(input, init);
287
+ const header = refusalHeader(response.status, response.headers.get(networkRefusalHeader));
288
+ if (header === void 0) return response;
289
+ await response.body?.cancel();
290
+ throw Schema_exports.decodeUnknownSync(NetworkRefusedHeader)(header);
291
+ };
292
+ var appInvocationFetch = (signal) => invocationFetch(signal).pipe(Effect_exports.map(appFetch));
293
+
253
294
  // src/implementation/failure-detail.ts
254
295
  var storageMessages = {
255
296
  schema: "The app's database schema is invalid.",
@@ -272,6 +313,32 @@ var cacheMessages = {
272
313
  storage: "The app cache failed to complete the operation.",
273
314
  timeout: "The app cache did not respond in time."
274
315
  };
316
+ var mcpStages = {
317
+ connect: "connecting",
318
+ transport: "connecting",
319
+ discover: "listing its tools",
320
+ schema: "reading a tool's schema",
321
+ call: "calling a tool"
322
+ };
323
+ var mcpMessage = ({ phase, reason, status }) => {
324
+ const stage = mcpStages[phase];
325
+ return Match_exports.value(reason).pipe(
326
+ Match_exports.when("timeout", () => `The MCP server did not respond in time while ${stage}.`),
327
+ Match_exports.when("unauthorized", () => `The MCP server rejected the credentials while ${stage}.`),
328
+ Match_exports.when(
329
+ "invalid_response",
330
+ () => `The MCP server returned a response Executor could not use while ${stage}, such as an unreadable message or an address on another origin.`
331
+ ),
332
+ Match_exports.when("invalid_input", () => "The MCP server URL or connection settings are invalid."),
333
+ // Only a transport failure has no answer from the server; a JSON-RPC error is an answer.
334
+ Match_exports.when(
335
+ "request",
336
+ () => status !== void 0 ? `The MCP server answered HTTP ${status} while ${stage}.` : phase === "transport" ? `Executor could not reach the MCP server while ${stage}.` : `The request to the MCP server failed while ${stage}.`
337
+ ),
338
+ Match_exports.exhaustive
339
+ );
340
+ };
341
+ var unverifiedMessage = ({ anonymous }) => anonymous === "answered" ? "This MCP server answers without credentials, so Executor can't check this account. A refused key will show up when a tool is called." : `The MCP server accepted the credentials, but the same check without them failed, so Executor can't tell whether it requires them. ${Schema_exports.is(McpError)(anonymous) ? mcpMessage(anonymous) : anonymous.status === void 0 ? "The MCP server could not answer the request." : `The MCP server answered HTTP ${anonymous.status}.`}`;
275
342
  var minimumSecretLength = 6;
276
343
  var secretValues = (value, found) => {
277
344
  if (typeof value === "string") {
@@ -388,6 +455,20 @@ var failureDetail = (error, secrets) => {
388
455
  code: error.reason,
389
456
  message: error.reason === "request" ? error.status === void 0 ? "The API request failed before a response arrived." : `The API responded with HTTP ${error.status}, which its OpenAPI document does not declare as an error with a message.` : error.reason === "invalid_input" ? "The input could not be encoded as a request for this API operation." : "The API's OpenAPI definition for this operation is invalid."
390
457
  };
458
+ if (Schema_exports.is(McpError)(error))
459
+ return {
460
+ source: "service",
461
+ errorName: "McpError",
462
+ code: error.reason,
463
+ message: mcpMessage(error)
464
+ };
465
+ if (Schema_exports.is(McpCredentialsUnverified)(error))
466
+ return {
467
+ source: "service",
468
+ errorName: "McpCredentialsUnverified",
469
+ code: error.anonymous === "answered" ? "anonymous_access" : error.anonymous.reason,
470
+ message: unverifiedMessage(error)
471
+ };
391
472
  if (Schema_exports.is(OpenapiCompileError)(error))
392
473
  return {
393
474
  source: "app",
@@ -395,6 +476,20 @@ var failureDetail = (error, secrets) => {
395
476
  code: error.code,
396
477
  message: boundFailureMessage(error.message, secrets)
397
478
  };
479
+ if (Schema_exports.is(NetworkRefused)(error))
480
+ return {
481
+ source: "app",
482
+ errorName: "NetworkRefused",
483
+ code: error.refusal.reason,
484
+ message: boundFailureMessage(error.message, secrets)
485
+ };
486
+ if (Schema_exports.is(FetchOptionUnsupported)(error))
487
+ return {
488
+ source: "app",
489
+ errorName: "FetchOptionUnsupported",
490
+ code: error.option,
491
+ message: boundFailureMessage(error.message, secrets)
492
+ };
398
493
  if (error instanceof Error) {
399
494
  const code = ownCode(error, secrets);
400
495
  const fields = ownFields(error, code, secrets);
@@ -672,6 +767,8 @@ export {
672
767
  parseMcpError,
673
768
  describeFailure,
674
769
  failureDetail,
770
+ failOnNetworkRefusal,
771
+ appInvocationFetch,
675
772
  operationDescription,
676
773
  fixedRouter,
677
774
  readCatalog,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  ProviderError,
3
3
  maxUpstreamMessageLength
4
- } from "./chunk-T7WRQJUF.js";
4
+ } from "./chunk-BRGF7VFN.js";
5
5
  import {
6
6
  AccountId
7
- } from "./chunk-KKGRSXUK.js";
7
+ } from "./chunk-PWF2DRJ3.js";
8
8
  import {
9
9
  Option_exports,
10
10
  Schema_exports
11
- } from "./chunk-DM5U7G7V.js";
11
+ } from "./chunk-NXTXZ635.js";
12
12
 
13
13
  // src/implementation/upstream-error.ts
14
14
  var ErrorToken = Schema_exports.String.check(Schema_exports.isPattern(/^[A-Za-z0-9._-]{1,128}$/));
@@ -3,40 +3,50 @@ import {
3
3
  answeredError,
4
4
  mcpClient,
5
5
  mcpJsonSchemaValidator
6
- } from "./chunk-4CMJD7AB.js";
6
+ } from "./chunk-VIQQ52V7.js";
7
+ import {
8
+ failOnNetworkRefusal
9
+ } from "./chunk-JN3PEGMW.js";
7
10
  import {
8
11
  accountProviderError,
9
12
  bodyUpstreamError,
10
13
  httpProviderError,
11
14
  providerErrorDetail
12
- } from "./chunk-DAIW2WM3.js";
15
+ } from "./chunk-KQCMHI3K.js";
13
16
  import {
17
+ McpCredentialsUnverified,
14
18
  McpError,
19
+ McpHealthInput,
15
20
  McpToolsOptions,
16
- defaultMcpClientLimits
17
- } from "./chunk-VGEPL4BV.js";
21
+ NetworkRefused,
22
+ defaultMcpClientLimits,
23
+ mcpHealthReserveMs
24
+ } from "./chunk-TE2HPDZG.js";
18
25
  import {
19
26
  ProviderError
20
- } from "./chunk-T7WRQJUF.js";
27
+ } from "./chunk-BRGF7VFN.js";
21
28
  import {
22
29
  captureTelemetry
23
- } from "./chunk-DUEZ2XCO.js";
30
+ } from "./chunk-YXKXKGN6.js";
24
31
  import {
25
32
  FetchHttpClient_exports
26
- } from "./chunk-KNJAOYV4.js";
33
+ } from "./chunk-V2I3MMPM.js";
27
34
  import {
28
35
  HttpClientRequest_exports,
29
36
  HttpClient_exports
30
- } from "./chunk-OBXHLFGQ.js";
37
+ } from "./chunk-B5YJQU45.js";
31
38
  import {
39
+ Clock_exports,
32
40
  Deferred_exports,
33
41
  Effect_exports,
42
+ Match_exports,
34
43
  Option_exports,
44
+ Predicate_exports,
35
45
  Redacted_exports,
36
46
  Ref_exports,
37
47
  Schema_exports,
38
48
  Stream_exports
39
- } from "./chunk-DM5U7G7V.js";
49
+ } from "./chunk-NXTXZ635.js";
40
50
 
41
51
  // src/implementation/mcp.ts
42
52
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
@@ -51,16 +61,17 @@ import {
51
61
  StreamableHTTPClientTransport,
52
62
  StreamableHTTPError
53
63
  } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
64
+ var unreadable = (error) => error instanceof SyntaxError || error instanceof Error && Predicate_exports.hasProperty(error, "issues") && Array.isArray(error.issues);
54
65
  var failure = (phase, error) => {
55
- if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error)) return error;
56
- const status = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
57
- const provider = status === void 0 ? void 0 : httpProviderError(status);
58
- if (provider !== void 0) return provider;
66
+ if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error) || Schema_exports.is(NetworkRefused)(error))
67
+ return error;
68
+ const code = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
69
+ if (code !== void 0 && code >= 300 && code <= 599)
70
+ return httpProviderError(code) ?? new McpError({ phase, reason: "request", status: code });
59
71
  const upstream = answeredError(error);
60
72
  return new McpError({
61
73
  phase,
62
- reason: error instanceof ProtocolError && error.code === ErrorCode.RequestTimeout ? "timeout" : "request",
63
- ...status === void 0 ? {} : { status },
74
+ reason: code !== void 0 || unreadable(error) ? "invalid_response" : error instanceof ProtocolError && error.code === ErrorCode.RequestTimeout ? "timeout" : "request",
64
75
  ...upstream === void 0 ? {} : { upstream }
65
76
  });
66
77
  };
@@ -72,10 +83,10 @@ var errorBody = (response) => Effect_exports.gen(function* () {
72
83
  const length = response.headers["content-length"];
73
84
  if (!json || length !== void 0 && Number(length) > errorBodyLimits.maxBytes)
74
85
  return { body: Stream_exports.toReadableStream(response.stream), upstream: void 0 };
75
- const unreadable = new McpError({ phase: "transport", reason: "invalid_response" });
86
+ const unreadable2 = new McpError({ phase: "transport", reason: "invalid_response" });
76
87
  const read = yield* response.stream.pipe(
77
- Stream_exports.mapError(() => unreadable),
78
- Stream_exports.limitBytes(errorBodyLimits.maxBytes, () => Stream_exports.fail(unreadable)),
88
+ Stream_exports.mapError(() => unreadable2),
89
+ Stream_exports.limitBytes(errorBodyLimits.maxBytes, () => Stream_exports.fail(unreadable2)),
79
90
  Stream_exports.decodeText,
80
91
  Stream_exports.mkString,
81
92
  Effect_exports.timeout(errorBodyLimits.readTimeoutMs),
@@ -98,14 +109,20 @@ var transportFetch = (connection, telemetry, rejected, answered) => (url, init)
98
109
  return yield* new McpError({ phase: "transport", reason: "invalid_input" });
99
110
  if (target.origin !== connection.url.origin || target.username || target.password)
100
111
  return yield* new McpError({ phase: "transport", reason: "invalid_response" });
101
- const headers = new Headers(Redacted_exports.value(connection.headers));
102
- new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
103
112
  const request = yield* Effect_exports.try({
104
- try: () => HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers })),
105
- catch: () => failure("transport", void 0)
113
+ try: () => {
114
+ const headers = new Headers(Redacted_exports.value(connection.headers));
115
+ new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
116
+ return HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers }));
117
+ },
118
+ // The provider's headers cannot form an HTTP request, such as a name with a space.
119
+ catch: () => new McpError({ phase: "transport", reason: "invalid_input" })
106
120
  });
107
121
  const client = yield* HttpClient_exports.HttpClient;
108
122
  const response = yield* client.execute(request);
123
+ yield* failOnNetworkRefusal(response).pipe(
124
+ Effect_exports.tapError((refused) => Deferred_exports.fail(rejected, refused))
125
+ );
109
126
  if (response.status < 400)
110
127
  return new Response(
111
128
  [204, 205, 304].includes(response.status) ? null : Stream_exports.toReadableStream(response.stream),
@@ -271,9 +288,44 @@ var mcpClientEffect = (input, changed) => Effect_exports.gen(function* () {
271
288
  failure
272
289
  );
273
290
  });
291
+ var refusesCredentials = (error) => Schema_exports.is(ProviderError)(error) && Match_exports.value(error.reason).pipe(
292
+ Match_exports.whenOr("unauthorized", "forbidden", "rejected", () => true),
293
+ Match_exports.whenOr("rate_limited", "unavailable", () => false),
294
+ Match_exports.exhaustive
295
+ );
296
+ var mcpHealthEffect = (check, options) => Effect_exports.gen(function* () {
297
+ const { deadline, timeoutMs, ...parsed } = yield* Schema_exports.decodeUnknownEffect(McpHealthInput)({
298
+ ...options,
299
+ accountId: check.account.id,
300
+ signal: check.signal,
301
+ deadline: check.deadline
302
+ }).pipe(Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" })));
303
+ const end = Math.min(
304
+ (yield* Clock_exports.currentTimeMillis) + (timeoutMs ?? defaultMcpClientLimits.timeoutMs),
305
+ deadline === void 0 ? Number.POSITIVE_INFINITY : deadline - mcpHealthReserveMs
306
+ );
307
+ const remaining = Effect_exports.flatMap(
308
+ Clock_exports.currentTimeMillis,
309
+ (now) => end - now >= 1 ? Effect_exports.succeed(Math.floor(end - now)) : Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
310
+ );
311
+ yield* (yield* mcpClientEffect({ ...parsed, timeoutMs: yield* remaining })).check;
312
+ return yield* remaining.pipe(
313
+ Effect_exports.flatMap(
314
+ (timeoutMs2) => mcpClientEffect({ url: parsed.url, signal: parsed.signal, timeoutMs: timeoutMs2 })
315
+ ),
316
+ Effect_exports.flatMap((anonymous) => anonymous.check),
317
+ Effect_exports.matchEffect({
318
+ onSuccess: () => Effect_exports.fail(new McpCredentialsUnverified({ anonymous: "answered" })),
319
+ // Executor's network refused the attempt, so the server never answered it.
320
+ onFailure: (error) => Schema_exports.is(NetworkRefused)(error) ? Effect_exports.fail(error) : refusesCredentials(error) ? Effect_exports.void : Effect_exports.fail(new McpCredentialsUnverified({ anonymous: error }))
321
+ }),
322
+ Effect_exports.withSpan("provider.mcp.anonymous")
323
+ );
324
+ }).pipe(Effect_exports.withSpan("provider.mcp.health"));
274
325
  var mcpToolsEffect = (input) => mcpClientEffect(input).pipe(Effect_exports.flatMap(adaptMcpTools));
275
326
 
276
327
  export {
277
328
  mcpClientEffect,
329
+ mcpHealthEffect,
278
330
  mcpToolsEffect
279
331
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Schema_exports
3
- } from "./chunk-DM5U7G7V.js";
3
+ } from "./chunk-NXTXZ635.js";
4
4
 
5
5
  // ../app-data/src/contracts/database.ts
6
6
  var DataName = Schema_exports.String.check(
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  fixedRouter
3
- } from "./chunk-EXDR4HVM.js";
3
+ } from "./chunk-JN3PEGMW.js";
4
4
  import {
5
5
  nativeOperation,
6
6
  operationDeclaration,
7
7
  routerDeclaration
8
- } from "./chunk-WPKXOTKM.js";
8
+ } from "./chunk-GQ7GCZ4J.js";
9
9
 
10
10
  // src/implementation/protocol-operations.ts
11
11
  var protocolOperations = (operations, kinds = {}) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Schema_exports
3
- } from "./chunk-DM5U7G7V.js";
3
+ } from "./chunk-NXTXZ635.js";
4
4
 
5
5
  // src/contracts/skills.ts
6
6
  var SkillFilePath = Schema_exports.NonEmptyString.check(