apps 0.0.1-beta.3 → 0.0.1-beta.30

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 (139) hide show
  1. package/README.md +68 -44
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-G7ZIRKMK.js → chunk-2D2PKLGQ.js} +118 -197
  4. package/js/chunk-3SPRHIEE.js +42 -0
  5. package/js/{chunk-FDNTX5QJ.js → chunk-4N26L465.js} +2 -2
  6. package/js/chunk-5ZHHO4OM.js +92 -0
  7. package/js/{chunk-EVJUVWN2.js → chunk-65SZ23BK.js} +2 -2
  8. package/js/{chunk-M6ZRRIBI.js → chunk-6JBTHTI5.js} +1 -1
  9. package/js/{chunk-J7O55ZV7.js → chunk-6NK26ONC.js} +332 -187
  10. package/js/chunk-6VWYEQ4X.js +254 -0
  11. package/js/{chunk-RN2MXB4R.js → chunk-AE4FWJQU.js} +128 -24
  12. package/js/{chunk-HDJH3RPR.js → chunk-BBTELEAN.js} +2 -2
  13. package/js/{chunk-LGIYBDWA.js → chunk-BRGF7VFN.js} +65 -1
  14. package/js/{chunk-MYYEW3RA.js → chunk-BSRU52RU.js} +984 -61
  15. package/js/{chunk-FZJOYIZO.js → chunk-BTJMXW4I.js} +1 -1
  16. package/js/{chunk-HDTGZWP2.js → chunk-IMCEF6KE.js} +139 -32
  17. package/js/chunk-KQCMHI3K.js +118 -0
  18. package/js/{chunk-BMOIAIVR.js → chunk-M2KEEOIQ.js} +49 -1
  19. package/js/{chunk-YEJOQEII.js → chunk-MYCVMDWI.js} +45 -7
  20. package/js/{chunk-FW5HBOIK.js → chunk-NXTXZ635.js} +1841 -1701
  21. package/js/chunk-OD3KFKZD.js +1617 -0
  22. package/js/{chunk-JN55AYQH.js → chunk-OI5CKSBU.js} +61 -32
  23. package/js/{chunk-NQ3OMCA5.js → chunk-P46HIAX6.js} +2 -2
  24. package/js/chunk-PUC24GZP.js +801 -0
  25. package/js/{chunk-SATWJKN6.js → chunk-PWF2DRJ3.js} +1 -1
  26. package/js/{chunk-D47C7KG5.js → chunk-VUVBMNKC.js} +2 -2
  27. package/js/{chunk-ZCAMUXSG.js → chunk-WGBI5MVX.js} +3 -4
  28. package/js/{chunk-T2LAZCAD.js → chunk-WQ5MVBTP.js} +1 -1
  29. package/js/{chunk-PLCMJREA.js → chunk-XBQTJP76.js} +60 -20
  30. package/js/{chunk-QKHR7BMF.js → chunk-XGN5IFOZ.js} +3 -3
  31. package/js/{chunk-WFSQXYUT.js → chunk-YML53Z7H.js} +42 -5
  32. package/js/{chunk-5MQZEB6Y.js → chunk-ZZOCEUTB.js} +37 -12
  33. package/js/client.js +120 -84
  34. package/js/contracts.js +110 -16
  35. package/js/effect.js +20 -20
  36. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  37. package/js/graphql.js +58 -54
  38. package/js/host.js +20 -20
  39. package/js/index.js +247 -204
  40. package/js/mcp/effect.js +24 -22
  41. package/js/mcp/stdio.js +35 -30
  42. package/js/mcp.js +105 -68
  43. package/js/openapi.js +4087 -1503
  44. package/js/react.js +3 -3
  45. package/js/skills/effect.js +5 -3
  46. package/js/skills.js +15 -15
  47. package/js/storage/facet.js +4 -4
  48. package/js/ui/auth/contracts.js +2 -2
  49. package/js/ui/auth.js +5 -5
  50. package/js/ui/contracts.js +5 -4
  51. package/js/ui/serving.js +8516 -214
  52. package/package.json +1 -1
  53. package/runtime.json +1 -1
  54. package/types/app-data/src/contracts/database.d.ts +33 -6
  55. package/types/app-data/src/implementation/schema.d.ts +2 -17
  56. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  57. package/types/apps/src/contracts/app.d.ts +7 -6
  58. package/types/apps/src/contracts/failure.d.ts +54 -0
  59. package/types/apps/src/contracts/graphql.d.ts +2 -1
  60. package/types/apps/src/contracts/host.d.ts +34 -11
  61. package/types/apps/src/contracts/mcp.d.ts +91 -10
  62. package/types/apps/src/contracts/network.d.ts +84 -0
  63. package/types/apps/src/contracts/openapi-compile.d.ts +31 -3
  64. package/types/apps/src/contracts/openapi.d.ts +45 -9
  65. package/types/apps/src/contracts/operations.d.ts +5 -6
  66. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  67. package/types/apps/src/contracts/protocols/1.d.ts +251 -69
  68. package/types/apps/src/contracts/protocols/2.d.ts +710 -0
  69. package/types/apps/src/contracts/protocols/3.d.ts +716 -0
  70. package/types/apps/src/contracts/protocols/4.d.ts +1298 -0
  71. package/types/apps/src/contracts/protocols/5.d.ts +1174 -0
  72. package/types/apps/src/contracts/protocols/6.d.ts +1620 -0
  73. package/types/apps/src/contracts/protocols/7.d.ts +1784 -0
  74. package/types/apps/src/contracts/protocols/8.d.ts +1119 -0
  75. package/types/apps/src/contracts/protocols/oauth.d.ts +89 -0
  76. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  77. package/types/apps/src/contracts/provider.d.ts +115 -10
  78. package/types/apps/src/contracts/router.d.ts +59 -0
  79. package/types/apps/src/contracts/skills.d.ts +18 -5
  80. package/types/apps/src/contracts/storage.d.ts +3 -3
  81. package/types/apps/src/contracts/ui.d.ts +18 -0
  82. package/types/apps/src/contracts/workflows.d.ts +34 -3
  83. package/types/apps/src/graphql.d.ts +1 -3
  84. package/types/apps/src/implementation/account-router.d.ts +12 -0
  85. package/types/apps/src/implementation/app.d.ts +5 -4
  86. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  87. package/types/apps/src/implementation/catalog-cache.d.ts +34 -4
  88. package/types/apps/src/implementation/elicitation.d.ts +9 -9
  89. package/types/apps/src/implementation/failure-detail.d.ts +46 -0
  90. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  91. package/types/apps/src/implementation/graphql.d.ts +4 -3
  92. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  93. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  94. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  95. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  96. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  97. package/types/apps/src/implementation/mcp.d.ts +52 -25
  98. package/types/apps/src/implementation/network.d.ts +16 -0
  99. package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
  100. package/types/apps/src/implementation/openapi-document.d.ts +35 -8
  101. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  102. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  103. package/types/apps/src/implementation/openapi-source.d.ts +8 -6
  104. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  105. package/types/apps/src/implementation/operations.d.ts +36 -3
  106. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  107. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  108. package/types/apps/src/implementation/provider.d.ts +19 -5
  109. package/types/apps/src/implementation/router-catalog.d.ts +224 -0
  110. package/types/apps/src/implementation/router.d.ts +68 -0
  111. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  112. package/types/apps/src/implementation/schema.d.ts +52 -1
  113. package/types/apps/src/implementation/skills.d.ts +2 -2
  114. package/types/apps/src/implementation/storage.d.ts +5 -3
  115. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  116. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  117. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  118. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  119. package/types/apps/src/implementation/ui-serving.d.ts +10 -4
  120. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  121. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  122. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  123. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  124. package/types/apps/src/index.d.ts +29 -11
  125. package/types/apps/src/mcp-stdio.d.ts +2 -5
  126. package/types/apps/src/mcp.d.ts +25 -5
  127. package/types/apps/src/openapi.d.ts +6 -6
  128. package/types/apps/src/skills.d.ts +4 -4
  129. package/types/telemetry/src/browser-operations.d.ts +5 -2
  130. package/types/telemetry/src/config.d.ts +2 -2
  131. package/types/utils/src/api-error.d.ts +48 -0
  132. package/js/chunk-PYUYJRSK.js +0 -93
  133. package/js/chunk-SWPD52J7.js +0 -35
  134. package/js/chunk-W7D7WVSY.js +0 -18
  135. package/js/chunk-Z5NMEGJN.js +0 -29
  136. package/js/chunk-ZJWDMTE3.js +0 -63
  137. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  138. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  139. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
@@ -1,24 +1,44 @@
1
1
  import {
2
2
  makeCache
3
- } from "./chunk-D47C7KG5.js";
3
+ } from "./chunk-VUVBMNKC.js";
4
+ import {
5
+ accountSecrets,
6
+ appInvocationFetch,
7
+ boundFailureMessage,
8
+ describeFailure,
9
+ failureDetail,
10
+ leavingProviderError,
11
+ parseMcpError,
12
+ readCatalog,
13
+ routerSkills
14
+ } from "./chunk-PUC24GZP.js";
4
15
  import {
5
16
  folderSkillsEffect
6
- } from "./chunk-FDNTX5QJ.js";
17
+ } from "./chunk-4N26L465.js";
7
18
  import {
19
+ ResponseStatusError,
8
20
  authorDatabase,
9
21
  isApp,
10
22
  toEffectApp,
11
23
  unavailableStorage
12
- } from "./chunk-JN55AYQH.js";
24
+ } from "./chunk-OI5CKSBU.js";
25
+ import {
26
+ parseDatabaseSchema
27
+ } from "./chunk-XBQTJP76.js";
13
28
  import {
29
+ declaredOperations,
14
30
  fromPromise,
31
+ locate,
15
32
  nativeOperation,
16
33
  toPromise
17
- } from "./chunk-PYUYJRSK.js";
34
+ } from "./chunk-6VWYEQ4X.js";
18
35
  import {
36
+ accountProviderError,
37
+ httpProviderError,
19
38
  parseProviderError
20
- } from "./chunk-ZJWDMTE3.js";
39
+ } from "./chunk-KQCMHI3K.js";
21
40
  import {
41
+ AccountCheckResult,
22
42
  DeclaredProvider,
23
43
  DeclaredRequirements,
24
44
  ElicitationFailed,
@@ -29,6 +49,7 @@ import {
29
49
  HostError,
30
50
  HostEvaluationFailed,
31
51
  HostInputInvalid,
52
+ HostKindMismatch,
32
53
  HostOperationFailed,
33
54
  HostOperationNotFound,
34
55
  HostOutputInvalid,
@@ -38,6 +59,7 @@ import {
38
59
  HostToolBlocked,
39
60
  HostToolNotFound,
40
61
  HostToolPolicyFailed,
62
+ HostedRouter,
41
63
  HostedTool,
42
64
  HostedToolSummary,
43
65
  HostedWebhook,
@@ -45,9 +67,8 @@ import {
45
67
  InvocationDeadline,
46
68
  ManualWebhookSetup,
47
69
  ManyAccounts,
48
- McpError,
49
70
  NonRetryableError,
50
- OperationToolPrefixes,
71
+ OpenapiResponseError,
51
72
  ResolvedAccounts,
52
73
  ToolResultObservation,
53
74
  TrustedToolApproval,
@@ -62,31 +83,28 @@ import {
62
83
  defaultWebhookTransportLimits,
63
84
  maxInputProblems,
64
85
  workflowDurationMillis
65
- } from "./chunk-MYYEW3RA.js";
86
+ } from "./chunk-BSRU52RU.js";
66
87
  import {
67
88
  CacheError
68
- } from "./chunk-LGIYBDWA.js";
89
+ } from "./chunk-BRGF7VFN.js";
69
90
  import {
70
91
  AppSkills,
71
92
  SkillFile,
72
93
  SkillLoadFailed
73
- } from "./chunk-YEJOQEII.js";
74
- import {
75
- OpenapiResponseError
76
- } from "./chunk-SWPD52J7.js";
94
+ } from "./chunk-MYCVMDWI.js";
77
95
  import {
78
- captureTelemetry,
79
- invocationFetch
80
- } from "./chunk-ZCAMUXSG.js";
96
+ captureTelemetry
97
+ } from "./chunk-WGBI5MVX.js";
81
98
  import {
82
99
  decoderOf,
83
100
  importedJsonSchema,
84
- jsonSchemaDecoder
85
- } from "./chunk-WFSQXYUT.js";
101
+ jsonSchemaDecoder,
102
+ jsonSchemaDocument
103
+ } from "./chunk-YML53Z7H.js";
86
104
  import {
87
105
  JsonObject,
88
106
  JsonValue
89
- } from "./chunk-SATWJKN6.js";
107
+ } from "./chunk-PWF2DRJ3.js";
90
108
  import {
91
109
  Cause_exports,
92
110
  Clock_exports,
@@ -98,7 +116,7 @@ import {
98
116
  SchemaIssue_exports,
99
117
  Schema_exports,
100
118
  Stream_exports
101
- } from "./chunk-FW5HBOIK.js";
119
+ } from "./chunk-NXTXZ635.js";
102
120
 
103
121
  // src/implementation/elicitation.ts
104
122
  var prepareElicitation = (input) => Effect_exports.gen(function* () {
@@ -139,19 +157,29 @@ var makeElicit = (handler, signal) => toPromise(
139
157
  var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
140
158
 
141
159
  // src/implementation/workflow-context.ts
142
- var workflowSafe = (work) => work.pipe(
160
+ var workflowSafe = (work, secrets) => work.pipe(
143
161
  Effect_exports.catchCause((cause) => {
144
162
  if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
145
163
  const error = Cause_exports.squash(cause);
146
164
  if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
165
+ const { errorName, message } = failureDetail(error, secrets);
147
166
  return Effect_exports.fail(
148
167
  new WorkflowFailure({
149
168
  reason: "execution",
150
- retryable: !(error instanceof NonRetryableError)
169
+ retryable: !(error instanceof NonRetryableError),
170
+ ...errorName === void 0 ? {} : { errorName },
171
+ ...message === void 0 ? {} : { message }
151
172
  })
152
173
  );
153
174
  })
154
175
  );
176
+ var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
177
+ reason: failure.reason,
178
+ retryable: failure.retryable,
179
+ step: step.slice(0, 200),
180
+ ...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
181
+ ...failure.message.length === 0 ? {} : { message: failure.message }
182
+ }) : failure;
155
183
  var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
156
184
  const services = yield* Effect_exports.context();
157
185
  const counts = /* @__PURE__ */ new Map();
@@ -206,25 +234,33 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
206
234
  Effect_exports.sync(() => new AbortController()),
207
235
  (controller2) => Effect_exports.sync(() => controller2.abort())
208
236
  );
209
- const ctx = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
237
+ const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
210
238
  const result = yield* workflowSafe(
211
- Effect_exports.tryPromise({ try: () => callback(ctx), catch: (error) => error })
239
+ Effect_exports.tryPromise({
240
+ try: () => callback(step2.context),
241
+ catch: (error) => error
242
+ }),
243
+ step2.secrets
212
244
  );
213
245
  return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
214
246
  Effect_exports.mapError(
215
- () => new WorkflowFailure({ reason: "output", retryable: false })
247
+ () => new WorkflowFailure({
248
+ reason: "output",
249
+ retryable: false,
250
+ message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
251
+ })
216
252
  )
217
253
  );
218
254
  })
219
255
  ).pipe(Effect_exports.provideContext(services))
220
256
  )
221
- );
257
+ ).pipe(Effect_exports.mapError(inStep(name)));
222
258
  });
223
259
  const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
224
260
  const target = nativeOperation(operation);
225
- const catalog = kind === "query" ? definition.queries : definition.mutations;
226
- const match = Object.entries(catalog ?? {}).find(
227
- ([, value]) => value === target && value.kind === kind
261
+ const root = definition.tools?.kind === "router" ? definition.tools : void 0;
262
+ const match = declaredOperations(root).find(
263
+ (entry) => entry.operation === target && entry.operation.kind === kind
228
264
  );
229
265
  if (target === void 0 || match === void 0)
230
266
  return yield* new WorkflowFailure({ reason: "operation", retryable: false });
@@ -243,9 +279,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
243
279
  parsed,
244
280
  () => attempt(
245
281
  parsed,
246
- execution.invoke({ kind, name: match[0], input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
282
+ execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
247
283
  )
248
- );
284
+ ).pipe(Effect_exports.mapError(inStep(name)));
249
285
  });
250
286
  const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
251
287
  const step = {
@@ -469,7 +505,7 @@ var authorCache = (host, accounts, signal, deadline) => {
469
505
  ...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
470
506
  load: Effect_exports.acquireUseRelease(
471
507
  Effect_exports.sync(() => new AbortController()),
472
- (controller) => invocationFetch(controller.signal).pipe(
508
+ (controller) => appInvocationFetch(controller.signal).pipe(
473
509
  Effect_exports.flatMap(
474
510
  (fetch) => fromPromise(options.load)({
475
511
  fetch,
@@ -523,6 +559,10 @@ var authorCache = (host, accounts, signal, deadline) => {
523
559
  };
524
560
 
525
561
  // src/implementation/host.ts
562
+ var WireCatalog = Schema_exports.Struct({
563
+ tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
564
+ routers: Schema_exports.Array(HostedRouter)
565
+ });
526
566
  function safe2(work, failure) {
527
567
  return Effect_exports.suspend(work).pipe(
528
568
  Effect_exports.catchCause(
@@ -530,30 +570,39 @@ function safe2(work, failure) {
530
570
  )
531
571
  );
532
572
  }
533
- var evaluationSafe = (work) => work.pipe(
573
+ var evaluationSafe = (work, secrets) => work.pipe(
534
574
  Effect_exports.catchCause((cause) => {
535
575
  if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
536
576
  const error = Cause_exports.squash(cause);
537
577
  const provider = parseProviderError(error);
538
578
  const skills = parseSkillLoadFailed(error);
539
- const mcp = parseMcpError(error);
579
+ const mcp = parseMcpError(error, secrets);
540
580
  return Effect_exports.fail(
541
- Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed()
581
+ Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "discover") : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
542
582
  );
543
583
  })
544
584
  );
545
- function jsonSchema(decoder) {
546
- const imported = importedJsonSchema(decoder);
547
- if (imported !== void 0) return Schema_exports.decodeUnknownEffect(JsonObject)(imported);
548
- const document = Schema_exports.toJsonSchemaDocument(decoder);
549
- return Schema_exports.decodeUnknownEffect(JsonObject)({
550
- ...document.schema,
551
- $defs: document.definitions,
552
- $schema: "https://json-schema.org/draft/2020-12/schema"
553
- });
585
+ var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
586
+ source: "app",
587
+ errorName: "HostDeclarationInvalid",
588
+ message: boundFailureMessage(
589
+ cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
590
+ secrets
591
+ )
592
+ });
593
+ var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
594
+ Effect_exports.catchCause(
595
+ (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
596
+ )
597
+ );
598
+ function declaredExposure(exposure) {
599
+ const named = (kind) => Object.entries(exposure ?? {}).filter(([, value]) => value === kind).map(([field]) => field).sort();
600
+ const plain = named("plain");
601
+ const raw = named("raw");
602
+ return { ...plain.length === 0 ? {} : { plain }, ...raw.length === 0 ? {} : { raw } };
554
603
  }
555
604
  function providerDeclaration(provider) {
556
- return safe2(
605
+ return declarationSafe(
557
606
  () => Effect_exports.gen(function* () {
558
607
  const auth = /* @__PURE__ */ new Map();
559
608
  for (const [name, method] of Object.entries(provider.auth)) {
@@ -562,42 +611,50 @@ function providerDeclaration(provider) {
562
611
  auth.set(name, {
563
612
  type: "secrets",
564
613
  label: method.label,
565
- fields: yield* jsonSchema(method.fields)
614
+ fields: yield* jsonSchemaDocument(method.fields),
615
+ ...declaredExposure(method.exposure)
566
616
  });
567
617
  break;
568
618
  case "oauth2":
569
619
  auth.set(name, {
570
620
  type: "oauth2",
571
621
  ...method.config,
572
- response: yield* jsonSchema(method.response)
622
+ response: yield* jsonSchemaDocument(method.response),
623
+ ...declaredExposure(method.exposure)
573
624
  });
574
625
  break;
575
626
  }
576
627
  }
577
628
  return yield* Schema_exports.decodeUnknownEffect(DeclaredProvider)({
578
629
  name: provider.name,
579
- auth: Object.fromEntries(auth)
630
+ auth: Object.fromEntries(auth),
631
+ // Order and repetition carry no meaning, so neither changes the provider's identity.
632
+ ...provider.hosts === void 0 ? {} : { hosts: [...new Set(provider.hosts)].sort() }
580
633
  });
581
634
  }),
582
- new HostDeclarationInvalid()
635
+ `Account provider "${provider.name}" has an invalid declaration`
583
636
  );
584
637
  }
585
638
  function requirements(slots, database) {
586
639
  return Effect_exports.gen(function* () {
587
640
  const accounts = /* @__PURE__ */ new Map();
588
641
  for (const [slot, selection] of Object.entries(slots)) {
642
+ const provider = selection instanceof ManyAccounts ? selection.provider : selection;
589
643
  accounts.set(slot, {
590
644
  cardinality: selection instanceof ManyAccounts ? "many" : "one",
591
- definition: yield* providerDeclaration(
592
- selection instanceof ManyAccounts ? selection.provider : selection
593
- )
645
+ definition: yield* providerDeclaration(provider),
646
+ ...provider.health === void 0 ? {} : { health: true }
594
647
  });
595
648
  }
596
649
  return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
597
650
  accounts: Object.fromEntries(accounts),
598
651
  capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
599
652
  ...database === void 0 ? {} : { database }
600
- }).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
653
+ }).pipe(
654
+ Effect_exports.mapError(
655
+ (cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
656
+ )
657
+ );
601
658
  });
602
659
  }
603
660
  function canonical(value) {
@@ -607,6 +664,9 @@ function canonical(value) {
607
664
  }
608
665
  return JSON.stringify(value);
609
666
  }
667
+ function withoutHosts({ hosts: _hosts, ...provider }) {
668
+ return provider;
669
+ }
610
670
  function bindAccounts(slots, declarations, context) {
611
671
  return safe2(
612
672
  () => Effect_exports.gen(function* () {
@@ -632,7 +692,7 @@ function bindAccounts(slots, declarations, context) {
632
692
  for (const account of accounts) {
633
693
  if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
634
694
  ids.add(account.id);
635
- if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
695
+ if (canonical(withoutHosts(account.provider)) !== canonical(withoutHosts(requirement.definition)) || !Object.hasOwn(provider.auth, account.method))
636
696
  return yield* Effect_exports.fail(new HostAccountsInvalid());
637
697
  const method = provider.auth[account.method];
638
698
  if (method === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
@@ -653,17 +713,67 @@ function bindAccounts(slots, declarations, context) {
653
713
  new HostAccountsInvalid()
654
714
  );
655
715
  }
716
+ var fetchLifetime = (signal, background) => Effect_exports.acquireRelease(
717
+ Effect_exports.sync(() => {
718
+ const controller = new AbortController();
719
+ let refreshes = 0;
720
+ let ended = false;
721
+ const settle = () => {
722
+ if (ended && refreshes === 0) controller.abort();
723
+ };
724
+ const end = () => {
725
+ ended = true;
726
+ settle();
727
+ };
728
+ signal.addEventListener("abort", end, { once: true });
729
+ if (signal.aborted) end();
730
+ const settled = Effect_exports.sync(() => {
731
+ refreshes -= 1;
732
+ settle();
733
+ });
734
+ return {
735
+ signal: controller.signal,
736
+ close: () => {
737
+ signal.removeEventListener("abort", end);
738
+ end();
739
+ },
740
+ /** Counted from the hand-off, so a refresh that has not started yet keeps the fetch. */
741
+ background: (task) => Effect_exports.suspend(() => {
742
+ refreshes += 1;
743
+ return background(task.pipe(Effect_exports.ensuring(settled))).pipe(
744
+ Effect_exports.onError(() => settled)
745
+ );
746
+ })
747
+ };
748
+ }),
749
+ (lifetime) => Effect_exports.sync(lifetime.close)
750
+ );
656
751
  function dispatch(app, request, context, signal) {
657
752
  return Effect_exports.scoped(
658
753
  Effect_exports.gen(function* () {
659
- if (!isApp(app)) return yield* Effect_exports.fail(new HostDeclarationInvalid());
754
+ if (!isApp(app))
755
+ return yield* Effect_exports.fail(
756
+ declarationInvalid("The app module's default export is not an app created by defineApp")
757
+ );
660
758
  const native = toEffectApp(app);
759
+ const secrets = accountSecrets(context.accounts);
760
+ const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
661
761
  const declared = yield* requirements(native.accounts, native.database?.schema);
662
- if (request.operation === "requirements")
762
+ if (request.operation === "requirements") {
763
+ if (native.database !== void 0)
764
+ yield* parseDatabaseSchema(native.database.schema).pipe(
765
+ Effect_exports.catchTag(
766
+ "AppDatabaseError",
767
+ (cause) => Effect_exports.fail(
768
+ declarationInvalid("The app's account or database declarations are invalid", cause)
769
+ )
770
+ )
771
+ );
663
772
  return yield* safe2(
664
773
  () => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
665
774
  new HostDeclarationInvalid()
666
775
  );
776
+ }
667
777
  const lifetime = yield* Effect_exports.acquireRelease(
668
778
  Effect_exports.sync(() => new AbortController()),
669
779
  (controller) => Effect_exports.sync(() => controller.abort())
@@ -689,6 +799,15 @@ function dispatch(app, request, context, signal) {
689
799
  return yield* new WorkflowFailure({ reason: "engine", retryable: true });
690
800
  return result;
691
801
  });
802
+ if (request.operation === "account-check")
803
+ return yield* checkAccount(
804
+ native.accounts,
805
+ declared,
806
+ request.requirement,
807
+ context,
808
+ invocationSignal,
809
+ deadline
810
+ ).pipe(withinDeadline);
692
811
  let running;
693
812
  let transactionOpen = false;
694
813
  const delivery = (request2, signal2) => Effect_exports.suspend(
@@ -723,9 +842,19 @@ function dispatch(app, request, context, signal) {
723
842
  const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
724
843
  context.files ?? []
725
844
  ).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
845
+ let cacheCommands = 0;
846
+ const hostCache = context.cache ?? unavailableCache;
847
+ const fetching = yield* fetchLifetime(signal, hostCache.background);
726
848
  const bound = {
727
849
  cache: authorCache(
728
- context.cache ?? unavailableCache,
850
+ {
851
+ ...hostCache,
852
+ transport: (command) => {
853
+ cacheCommands += 1;
854
+ return hostCache.transport(command);
855
+ },
856
+ background: fetching.background
857
+ },
729
858
  Redacted_exports.value(context.accounts),
730
859
  invocationSignal,
731
860
  deadline
@@ -736,35 +865,43 @@ function dispatch(app, request, context, signal) {
736
865
  ),
737
866
  workflows: workflowReads,
738
867
  signal: invocationSignal,
739
- fetch: yield* invocationFetch(invocationSignal),
868
+ fetch: yield* appInvocationFetch(fetching.signal),
740
869
  elicit: makeElicit(delivery, invocationSignal)
741
870
  };
742
- const definition = yield* evaluationSafe(native.evaluate(bound)).pipe(
871
+ const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
743
872
  Effect_exports.withSpan("app.evaluate")
744
873
  );
745
874
  if (request.operation === "skills") {
746
875
  const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
747
876
  Effect_exports.mapError(() => new HostDeclarationInvalid())
748
877
  ));
749
- const source2 = definition.dynamicSkills;
750
- const dynamic = source2 === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source2.list)).pipe(
878
+ const source = definition.dynamicSkills;
879
+ const before = cacheCommands;
880
+ const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
751
881
  Effect_exports.withSpan("app.skills.load")
752
882
  );
753
- const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([...declared2, ...dynamic]).pipe(
754
- Effect_exports.mapError(() => new HostDeclarationInvalid())
755
- );
756
- return request.sources === true ? { skills, dynamic: source2 !== void 0 } : skills;
883
+ const cached = source !== void 0 && cacheCommands > before;
884
+ const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
885
+ const routed = (yield* routerSkills(definition.tools).pipe(
886
+ Effect_exports.withSpan("app.skills.routers")
887
+ )).filter((skill) => !authored.has(skill.name));
888
+ const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
889
+ ...declared2,
890
+ ...dynamic,
891
+ ...routed
892
+ ]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
893
+ return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
757
894
  }
758
895
  if (request.operation === "workflows") {
759
896
  return yield* Effect_exports.forEach(
760
897
  Object.entries(definition.workflows ?? {}),
761
- ([name2, entry]) => safe2(
898
+ ([name, entry]) => safe2(
762
899
  () => Effect_exports.gen(function* () {
763
900
  return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
764
- name: name2,
901
+ name,
765
902
  ...entry.description === void 0 ? {} : { description: entry.description },
766
- inputSchema: yield* jsonSchema(entry.input),
767
- ...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchema(entry.output) }
903
+ inputSchema: yield* jsonSchemaDocument(entry.input),
904
+ ...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
768
905
  });
769
906
  }),
770
907
  new HostDeclarationInvalid()
@@ -797,108 +934,60 @@ function dispatch(app, request, context, signal) {
797
934
  new WorkflowFailure({ reason: "credentials", retryable: false })
798
935
  );
799
936
  return {
800
- ...accounts,
801
- cache: authorCache(
802
- context.cache ?? unavailableCache,
803
- Redacted_exports.value(current.accounts),
804
- signal2
805
- ),
806
- files,
807
- fetch: yield* invocationFetch(signal2),
808
- signal: signal2,
809
- runId: execution.runId,
810
- stepId,
811
- idempotencyKey: stepId
937
+ context: {
938
+ ...accounts,
939
+ cache: authorCache(
940
+ context.cache ?? unavailableCache,
941
+ Redacted_exports.value(current.accounts),
942
+ signal2
943
+ ),
944
+ files,
945
+ fetch: yield* appInvocationFetch(signal2),
946
+ signal: signal2,
947
+ runId: execution.runId,
948
+ stepId,
949
+ idempotencyKey: stepId
950
+ },
951
+ // The resolved values, not the app's decoded fields, which may be `Redacted`.
952
+ secrets: accountSecrets(current.accounts)
812
953
  };
813
954
  }),
814
955
  invocationSignal
815
956
  );
816
- const output = yield* workflowSafe(entry.run(workflowContext, input2));
957
+ const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
817
958
  const outputSchema = entry.output;
818
959
  const decoded = outputSchema === void 0 ? output : yield* safe2(
819
960
  () => Schema_exports.decodeUnknownEffect(outputSchema)(output),
820
- new WorkflowFailure({ reason: "output", retryable: false })
961
+ new WorkflowFailure({
962
+ reason: "output",
963
+ retryable: false,
964
+ message: "The workflow's result does not match its declared output schema."
965
+ })
821
966
  );
822
967
  return yield* safe2(
823
968
  () => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
824
- new WorkflowFailure({ reason: "output", retryable: false })
969
+ new WorkflowFailure({
970
+ reason: "output",
971
+ retryable: false,
972
+ message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
973
+ })
825
974
  );
826
975
  }
827
976
  if (request.operation === "inspect") {
828
977
  const summary = request.detail === "summary";
829
- const wanted = request.tools === void 0 ? void 0 : new Set(request.tools);
830
- const metadata = [];
831
- for (const [prefix, readOnly, catalog2] of [
832
- [OperationToolPrefixes.query, true, definition.queries],
833
- [OperationToolPrefixes.mutate, false, definition.mutations]
834
- ]) {
835
- for (const [name2, operation] of Object.entries(catalog2 ?? {})) {
836
- if (wanted !== void 0 && !wanted.has(`${prefix}${name2}`)) continue;
837
- const schedules = Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === `${prefix}${name2}`).map(([name3, { tool: _tool, ...schedule }]) => ({ name: name3, ...schedule }));
838
- if (request.scheduled === true && schedules.length === 0) continue;
839
- metadata.push(
840
- yield* safe2(
841
- () => Effect_exports.gen(function* () {
842
- const fields = {
843
- name: `${prefix}${name2}`,
844
- schedules,
845
- description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
846
- ...operation.title === void 0 ? {} : { title: operation.title },
847
- readOnly,
848
- annotations: { ...operation.annotations, readOnlyHint: readOnly }
849
- };
850
- if (summary)
851
- return yield* Schema_exports.decodeUnknownEffect(HostedToolSummary)(fields);
852
- return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
853
- ...fields,
854
- inputSchema: yield* jsonSchema(operation.input),
855
- ...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
856
- ...operation._meta === void 0 ? {} : { _meta: operation._meta }
857
- });
858
- }),
859
- new HostDeclarationInvalid()
860
- )
861
- );
862
- }
863
- }
864
- const dynamic = request.scheduled === true ? void 0 : definition.dynamicTools;
865
- if (dynamic !== void 0 && (wanted === void 0 || metadata.length < wanted.size)) {
866
- const declared2 = new Set(metadata.map((tool2) => tool2.name));
867
- const discover = () => {
868
- if (summary && dynamic.summaries !== void 0) return dynamic.summaries();
869
- if (wanted !== void 0 && dynamic.describe !== void 0) {
870
- const describe = dynamic.describe;
871
- return Effect_exports.forEach(
872
- [...wanted].filter((name2) => !declared2.has(name2)),
873
- (name2) => describe(name2),
874
- { concurrency: "unbounded" }
875
- ).pipe(Effect_exports.map((tools) => tools.filter((tool2) => tool2 !== void 0)));
876
- }
877
- return dynamic.list();
878
- };
879
- const discovered = yield* evaluationSafe(discover()).pipe(
880
- Effect_exports.flatMap(
881
- (value) => safe2(
882
- () => summary ? Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedToolSummary))(value) : Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool))(value),
883
- new HostDeclarationInvalid()
884
- )
885
- )
886
- );
887
- const names = new Set(declared2);
888
- for (const tool2 of discovered) {
889
- const readOnly = tool2.name.startsWith(OperationToolPrefixes.query);
890
- if (!readOnly && !tool2.name.startsWith(OperationToolPrefixes.mutate) || tool2.name === OperationToolPrefixes.query || tool2.name === OperationToolPrefixes.mutate || names.has(tool2.name))
891
- return yield* new HostDeclarationInvalid();
892
- names.add(tool2.name);
893
- if (wanted !== void 0 && !wanted.has(tool2.name)) continue;
894
- metadata.push({
895
- ...tool2,
896
- readOnly,
897
- annotations: { ...tool2.annotations, readOnlyHint: readOnly }
898
- });
899
- }
900
- }
901
- return metadata;
978
+ const catalog = yield* readCatalog(definition.tools, {
979
+ summary,
980
+ secrets,
981
+ ...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
982
+ ...request.scheduled === true ? { scheduled: true } : {},
983
+ schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
984
+ }).pipe(Effect_exports.withSpan("app.catalog.read"));
985
+ return yield* safe2(
986
+ () => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
987
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
988
+ ),
989
+ new HostDeclarationInvalid()
990
+ );
902
991
  }
903
992
  if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
904
993
  const executeWebhook = (db) => dispatchWebhook(
@@ -922,25 +1011,22 @@ function dispatch(app, request, context, signal) {
922
1011
  const storage2 = context.storage ?? unavailableStorage;
923
1012
  return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
924
1013
  Effect_exports.catchTags({
925
- AppDatabaseError: () => Effect_exports.fail(new HostOperationFailed()),
926
- AppStorageUnavailable: () => Effect_exports.fail(new HostOperationFailed()),
927
- AppStorageError: () => Effect_exports.fail(new HostOperationFailed())
1014
+ AppDatabaseError: storageFailure,
1015
+ DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
1016
+ AppStorageUnavailable: storageFailure,
1017
+ AppStorageError: storageFailure
928
1018
  })
929
1019
  );
930
1020
  }
931
- const kind = request.operation === "call" ? request.tool.startsWith(OperationToolPrefixes.query) ? "query" : request.tool.startsWith(OperationToolPrefixes.mutate) ? "mutate" : void 0 : request.operation;
932
- if (kind === void 0) return yield* new HostToolNotFound();
933
- const name = request.operation === "call" ? request.tool.slice(OperationToolPrefixes[kind].length) : request.name;
934
- const toolName = `${OperationToolPrefixes[kind]}${name}`;
935
- const catalog = kind === "query" ? definition.queries : definition.mutations;
936
- const declaredTool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
937
- const source = definition.dynamicTools;
938
- const resolvedTool = source === void 0 || declaredTool !== void 0 ? void 0 : yield* evaluationSafe(source.resolve(toolName));
939
- const tool = declaredTool ?? resolvedTool;
940
- if (tool !== void 0 && tool.kind !== (kind === "query" ? "query" : "mutation"))
941
- return yield* new HostDeclarationInvalid();
1021
+ const toolName = request.operation === "call" ? request.tool : request.name;
1022
+ const location = locate(definition.tools, toolName);
1023
+ const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
942
1024
  if (tool === void 0)
943
1025
  return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
1026
+ const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
1027
+ if (requested !== void 0 && tool.kind !== requested)
1028
+ return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
1029
+ const kind = tool.kind === "query" ? "query" : "mutate";
944
1030
  const input = yield* Effect_exports.suspend(
945
1031
  () => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
946
1032
  ).pipe(
@@ -994,7 +1080,7 @@ function dispatch(app, request, context, signal) {
994
1080
  transactionOpen = db !== void 0;
995
1081
  const output = yield* Effect_exports.gen(function* () {
996
1082
  running = yield* captureTelemetry;
997
- const fetch = yield* invocationFetch(invocationSignal);
1083
+ const fetch = yield* appInvocationFetch(fetching.signal);
998
1084
  return yield* tool.run(
999
1085
  {
1000
1086
  ...bound,
@@ -1022,14 +1108,15 @@ function dispatch(app, request, context, signal) {
1022
1108
  const error = Cause_exports.squash(cause);
1023
1109
  const provider = parseProviderError(error);
1024
1110
  const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
1111
+ const mcp = parseMcpError(error, secrets);
1025
1112
  const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
1026
1113
  return Effect_exports.fail(
1027
- Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
1114
+ Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "call") : Option_exports.isSome(response) ? new OpenapiResponseError({
1028
1115
  code: response.value.code,
1029
1116
  status: response.value.status,
1030
1117
  message: response.value.message,
1031
1118
  ...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
1032
- }) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
1119
+ }) : Option_exports.isSome(mcp) ? mcp.value : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
1033
1120
  );
1034
1121
  }),
1035
1122
  Effect_exports.withSpan("app.operation.execute", {
@@ -1060,14 +1147,61 @@ function dispatch(app, request, context, signal) {
1060
1147
  )
1061
1148
  ).pipe(
1062
1149
  Effect_exports.catchTags({
1063
- AppDatabaseError: () => Effect_exports.fail(new HostOperationFailed()),
1064
- AppStorageUnavailable: () => Effect_exports.fail(new HostOperationFailed()),
1065
- AppStorageError: () => Effect_exports.fail(new HostOperationFailed())
1150
+ AppDatabaseError: storageFailure,
1151
+ DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
1152
+ AppStorageUnavailable: storageFailure,
1153
+ AppStorageError: storageFailure
1066
1154
  })
1067
1155
  );
1068
1156
  })
1069
1157
  );
1070
1158
  }
1159
+ function checkAccount(slots, declared, requirement, context, signal, deadline) {
1160
+ return Effect_exports.gen(function* () {
1161
+ const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
1162
+ const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
1163
+ if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
1164
+ const provider = selection instanceof ManyAccounts ? selection.provider : selection;
1165
+ const health = provider.health;
1166
+ if (health === void 0) return yield* new HostOperationNotFound();
1167
+ const { accounts } = yield* bindAccounts(
1168
+ { [requirement]: provider },
1169
+ { accounts: { [requirement]: { ...slot, cardinality: "one" } } },
1170
+ context
1171
+ ).pipe(Effect_exports.withSpan("app.accounts.bind"));
1172
+ const account = accounts[requirement];
1173
+ if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
1174
+ const result = yield* Effect_exports.suspend(
1175
+ () => Effect_exports.gen(function* () {
1176
+ return yield* health.run({
1177
+ account,
1178
+ fetch: yield* appInvocationFetch(signal),
1179
+ signal,
1180
+ ...deadline === void 0 ? {} : { deadline }
1181
+ });
1182
+ })
1183
+ ).pipe(
1184
+ Effect_exports.catchCause((cause) => {
1185
+ if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
1186
+ const error = Cause_exports.squash(cause);
1187
+ const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
1188
+ const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
1189
+ const secrets = accountSecrets(context.accounts);
1190
+ return Effect_exports.fail(
1191
+ Option_exports.isSome(classified) ? leavingProviderError(accountProviderError(classified.value, account.id), secrets) : new HostOperationFailed(failureDetail(error, secrets))
1192
+ );
1193
+ }),
1194
+ Effect_exports.withSpan("app.account.check")
1195
+ );
1196
+ return yield* safe2(
1197
+ () => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
1198
+ Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
1199
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
1200
+ ),
1201
+ new HostOutputInvalid()
1202
+ );
1203
+ });
1204
+ }
1071
1205
  var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
1072
1206
  Option_exports.map(
1073
1207
  ({ reason, message, status }) => new SkillLoadFailed({
@@ -1077,11 +1211,6 @@ var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLo
1077
1211
  })
1078
1212
  )
1079
1213
  );
1080
- var parseMcpError = (error) => Schema_exports.decodeUnknownOption(McpError)(error).pipe(
1081
- Option_exports.map(
1082
- ({ phase, reason, status }) => new McpError({ phase, reason, ...status === void 0 ? {} : { status } })
1083
- )
1084
- );
1085
1214
  var errorStatus = Match_exports.type().pipe(
1086
1215
  Match_exports.tagsExhaustive({
1087
1216
  ProviderError: () => 502,
@@ -1093,11 +1222,14 @@ var errorStatus = Match_exports.type().pipe(
1093
1222
  HostAccountsInvalid: () => 422,
1094
1223
  HostInputInvalid: () => 422,
1095
1224
  HostOperationNotFound: () => 404,
1225
+ HostKindMismatch: () => 409,
1096
1226
  HostToolNotFound: () => 404,
1097
1227
  HostToolBlocked: () => 403,
1098
1228
  HostToolApprovalRequired: () => 409,
1099
1229
  HostToolPolicyFailed: () => 500,
1100
1230
  HostOperationFailed: () => 500,
1231
+ DatabaseLimitExceeded: () => 422,
1232
+ DatabaseFieldReserved: () => 422,
1101
1233
  HostDeclarationInvalid: () => 500,
1102
1234
  HostEvaluationFailed: () => 500,
1103
1235
  HostOutputInvalid: () => 500,
@@ -1124,6 +1256,14 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
1124
1256
  toolError = true;
1125
1257
  }
1126
1258
  }),
1259
+ // Name what failed on the span; the bounded message stays in the reply only.
1260
+ Effect_exports.tapError(
1261
+ (error) => (error._tag === "HostEvaluationFailed" || error._tag === "HostOperationFailed" || error._tag === "HostDeclarationInvalid") && error.errorName !== void 0 ? Effect_exports.annotateCurrentSpan({
1262
+ "error.type": error.errorName,
1263
+ ...error.source === void 0 ? {} : { "executor.failure.source": error.source },
1264
+ ...error.code === void 0 ? {} : { "executor.failure.code": error.code }
1265
+ }) : Effect_exports.void
1266
+ ),
1127
1267
  Effect_exports.withSpan(`app.${command.operation}`)
1128
1268
  );
1129
1269
  if (toolError)
@@ -1143,12 +1283,17 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
1143
1283
  ),
1144
1284
  Effect_exports.catchCause(
1145
1285
  (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
1146
- Effect_exports.as(
1147
- Response.json(
1148
- { ok: false, error: { _tag: "HostDeclarationInvalid" } },
1149
- { status: 500 }
1286
+ Effect_exports.andThen(
1287
+ Schema_exports.encodeEffect(HostError)(
1288
+ declarationInvalid(
1289
+ "The app failed while it was loaded",
1290
+ Cause_exports.squash(cause),
1291
+ accountSecrets(context.accounts)
1292
+ )
1150
1293
  )
1151
- )
1294
+ ),
1295
+ Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
1296
+ Effect_exports.orDie
1152
1297
  )
1153
1298
  )
1154
1299
  );