apps 0.0.1-beta.0 → 0.0.1-beta.10

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 (141) hide show
  1. package/README.md +145 -30
  2. package/framework-reference.json +1 -1
  3. package/js/browser-XIPJGLH2.js +65 -0
  4. package/js/{chunk-36DNRFZQ.js → chunk-27F7W2LG.js} +1 -1
  5. package/js/{chunk-VFUZI3NY.js → chunk-57RKNWL2.js} +4 -4
  6. package/js/{chunk-BPEFS4YF.js → chunk-5T57N25Q.js} +122 -18
  7. package/js/chunk-72JNVHPK.js +41 -0
  8. package/js/{chunk-2OTCEKL2.js → chunk-CDL5PM2Q.js} +2643 -1646
  9. package/js/{chunk-KWTCHVLT.js → chunk-CRDWFA74.js} +69 -54
  10. package/js/chunk-CZ7CSFO4.js +39 -0
  11. package/js/{chunk-WIDTG42X.js → chunk-EPT3ZP52.js} +79 -26
  12. package/js/chunk-FL2QR3XW.js +507 -0
  13. package/js/{chunk-3ANFZFCV.js → chunk-IJX4CYZO.js} +15 -18
  14. package/js/chunk-IPI4MFSN.js +78 -0
  15. package/js/chunk-JU7VHODU.js +104 -0
  16. package/js/chunk-KUMBKVJD.js +39 -0
  17. package/js/{chunk-YDR4CPJA.js → chunk-M3B3DE4K.js} +8 -8
  18. package/js/chunk-MKWZPDR6.js +63 -0
  19. package/js/{chunk-7JXHF5IF.js → chunk-N7YDVXYJ.js} +49 -1
  20. package/js/chunk-NKLWZJLE.js +172 -0
  21. package/js/{chunk-OWD2YICM.js → chunk-ODEIDRGW.js} +116 -88
  22. package/js/{chunk-D6BKYP2L.js → chunk-PJJ24GU7.js} +4 -4
  23. package/js/{chunk-EP6AEUZO.js → chunk-PZB6T6KU.js} +1 -1
  24. package/js/chunk-R3EV5FTO.js +97 -0
  25. package/js/chunk-RFVIONFX.js +189 -0
  26. package/js/{chunk-W7Q5EOTS.js → chunk-UK573G7W.js} +32 -32
  27. package/js/chunk-UVL56Z6E.js +6641 -0
  28. package/js/{chunk-Q2FD5IBM.js → chunk-V5KNQVCT.js} +505 -124
  29. package/js/{chunk-SBKHUC5L.js → chunk-VFZKSM3T.js} +5 -25
  30. package/js/{chunk-HP7E42X6.js → chunk-WLE7WX2U.js} +1158 -232
  31. package/js/{chunk-X3YBZCJW.js → chunk-YXQHV65J.js} +58 -62
  32. package/js/chunk-Z5M2LQOZ.js +209 -0
  33. package/js/{chunk-R6JMJSVT.js → chunk-ZQINWV4W.js} +60 -20
  34. package/js/client.js +11 -27
  35. package/js/contracts.js +138 -27
  36. package/js/effect.js +20 -15
  37. package/js/es-APDZKREY.js +40968 -0
  38. package/js/graphql.js +220 -123
  39. package/js/host.js +75 -19
  40. package/js/index.js +261 -117
  41. package/js/mcp/effect.js +24 -17
  42. package/js/mcp/stdio.js +26 -21
  43. package/js/mcp.js +127 -26
  44. package/js/openapi.js +3048 -150
  45. package/js/operations/approval.js +1 -1
  46. package/js/react.js +4 -4
  47. package/js/skills/effect.js +11 -0
  48. package/js/skills.js +893 -0
  49. package/js/storage/facet.js +7 -7
  50. package/js/ui/auth/contracts.js +9 -10
  51. package/js/ui/auth.js +17 -15
  52. package/js/ui/contracts.js +5 -5
  53. package/js/ui/serving.js +14 -13
  54. package/package.json +9 -1
  55. package/runtime.json +1 -1
  56. package/types/app-cache/src/contracts/cache.d.ts +119 -0
  57. package/types/app-cache/src/index.d.ts +93 -0
  58. package/types/app-data/src/contracts/database.d.ts +33 -6
  59. package/types/app-data/src/implementation/schema.d.ts +2 -17
  60. package/types/apps/src/contracts/api-response-error.d.ts +43 -0
  61. package/types/apps/src/contracts/app.d.ts +16 -4
  62. package/types/apps/src/contracts/cache.d.ts +44 -0
  63. package/types/apps/src/contracts/dynamic-skills.d.ts +10 -0
  64. package/types/apps/src/contracts/failure.d.ts +25 -0
  65. package/types/apps/src/contracts/graphql.d.ts +18 -1
  66. package/types/apps/src/contracts/host.d.ts +76 -528
  67. package/types/apps/src/contracts/mcp.d.ts +19 -1
  68. package/types/apps/src/contracts/openapi-compile.d.ts +11 -0
  69. package/types/apps/src/contracts/openapi-document.d.ts +53 -0
  70. package/types/apps/src/contracts/openapi.d.ts +160 -30
  71. package/types/apps/src/contracts/operations.d.ts +0 -5
  72. package/types/apps/src/contracts/protocol-version.d.ts +6 -0
  73. package/types/apps/src/contracts/protocols/1.d.ts +1589 -0
  74. package/types/apps/src/contracts/protocols/2.d.ts +668 -0
  75. package/types/apps/src/contracts/protocols/3.d.ts +676 -0
  76. package/types/apps/src/contracts/protocols/4.d.ts +1229 -0
  77. package/types/apps/src/contracts/protocols/5.d.ts +1090 -0
  78. package/types/apps/src/contracts/provider-error.d.ts +15 -0
  79. package/types/apps/src/contracts/provider.d.ts +69 -6
  80. package/types/apps/src/contracts/router.d.ts +59 -0
  81. package/types/apps/src/contracts/skills.d.ts +122 -0
  82. package/types/apps/src/contracts/storage.d.ts +3 -3
  83. package/types/apps/src/contracts/swagger-client.d.ts +29 -0
  84. package/types/apps/src/contracts/ui-auth.d.ts +6 -14
  85. package/types/apps/src/contracts/workflows.d.ts +34 -3
  86. package/types/apps/src/graphql.d.ts +5 -7
  87. package/types/apps/src/host.d.ts +1 -0
  88. package/types/apps/src/implementation/account-router.d.ts +12 -0
  89. package/types/apps/src/implementation/app.d.ts +5 -4
  90. package/types/apps/src/implementation/cache-session.d.ts +7 -0
  91. package/types/apps/src/implementation/cache.d.ts +8 -0
  92. package/types/apps/src/implementation/catalog-cache.d.ts +36 -0
  93. package/types/apps/src/implementation/dynamic-skills.d.ts +7 -0
  94. package/types/apps/src/implementation/elicitation.d.ts +13 -13
  95. package/types/apps/src/implementation/failure-detail.d.ts +25 -0
  96. package/types/apps/src/implementation/git.d.ts +25 -0
  97. package/types/apps/src/implementation/graphql-catalog.d.ts +7 -0
  98. package/types/apps/src/implementation/graphql.d.ts +81 -3
  99. package/types/apps/src/implementation/inflate.d.ts +16 -0
  100. package/types/apps/src/implementation/input-problems.d.ts +3 -0
  101. package/types/apps/src/implementation/mcp-call.d.ts +3 -2
  102. package/types/apps/src/implementation/mcp-catalog.d.ts +9 -0
  103. package/types/apps/src/implementation/mcp-client.d.ts +39 -22
  104. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  105. package/types/apps/src/implementation/mcp-tools.d.ts +6 -3
  106. package/types/apps/src/implementation/mcp.d.ts +55 -2
  107. package/types/apps/src/implementation/openapi-compile.d.ts +120 -0
  108. package/types/apps/src/implementation/openapi-document.d.ts +51 -0
  109. package/types/apps/src/implementation/openapi-names.d.ts +18 -0
  110. package/types/apps/src/implementation/openapi-request.d.ts +10 -4
  111. package/types/apps/src/implementation/openapi-source.d.ts +36 -0
  112. package/types/apps/src/implementation/openapi.d.ts +39 -3
  113. package/types/apps/src/implementation/operations.d.ts +26 -3
  114. package/types/apps/src/implementation/protocol-operations.d.ts +3 -4
  115. package/types/apps/src/implementation/provider-error.d.ts +10 -0
  116. package/types/apps/src/implementation/provider.d.ts +9 -4
  117. package/types/apps/src/implementation/router-catalog.d.ts +225 -0
  118. package/types/apps/src/implementation/router.d.ts +59 -0
  119. package/types/apps/src/implementation/schema.d.ts +11 -6
  120. package/types/apps/src/implementation/skill-files.d.ts +10 -0
  121. package/types/apps/src/implementation/skills.d.ts +43 -0
  122. package/types/apps/src/implementation/storage.d.ts +5 -3
  123. package/types/apps/src/implementation/swagger-client.d.ts +28 -0
  124. package/types/apps/src/implementation/ui-auth.d.ts +11 -5
  125. package/types/apps/src/implementation/ui-serving.d.ts +4 -2
  126. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  127. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  128. package/types/apps/src/index.d.ts +11 -3
  129. package/types/apps/src/mcp-stdio.d.ts +2 -5
  130. package/types/apps/src/mcp.d.ts +8 -7
  131. package/types/apps/src/openapi.d.ts +8 -6
  132. package/types/apps/src/skills.d.ts +75 -0
  133. package/types/apps/src/ui-auth.d.ts +2 -2
  134. package/types/telemetry/src/browser-operations.d.ts +5 -2
  135. package/types/telemetry/src/config.d.ts +2 -0
  136. package/js/chunk-22WRQZT7.js +0 -389
  137. package/js/chunk-BKVL7XAJ.js +0 -47
  138. package/js/chunk-C24KEZXR.js +0 -59
  139. package/js/chunk-LOKGDT6B.js +0 -28
  140. package/js/chunk-MLKGABMK.js +0 -9
  141. package/types/apps/src/implementation/account-operations.d.ts +0 -32
@@ -1,21 +1,52 @@
1
1
  import {
2
+ makeCache
3
+ } from "./chunk-NKLWZJLE.js";
4
+ import {
5
+ accountSecrets,
6
+ boundFailureMessage,
7
+ describeFailure,
8
+ failureDetail,
9
+ readCatalog,
10
+ routerSkills
11
+ } from "./chunk-FL2QR3XW.js";
12
+ import {
13
+ folderSkillsEffect
14
+ } from "./chunk-IPI4MFSN.js";
15
+ import {
16
+ ResponseStatusError,
2
17
  authorDatabase,
3
18
  isApp,
4
19
  toEffectApp,
5
- toPromise,
6
20
  unavailableStorage
7
- } from "./chunk-X3YBZCJW.js";
21
+ } from "./chunk-YXQHV65J.js";
22
+ import {
23
+ parseDatabaseSchema
24
+ } from "./chunk-ZQINWV4W.js";
25
+ import {
26
+ declaredOperations,
27
+ fromPromise,
28
+ locate,
29
+ nativeOperation,
30
+ toPromise
31
+ } from "./chunk-Z5M2LQOZ.js";
8
32
  import {
9
- nativeOperation
10
- } from "./chunk-C24KEZXR.js";
33
+ accountProviderError,
34
+ httpProviderError,
35
+ parseProviderError
36
+ } from "./chunk-MKWZPDR6.js";
11
37
  import {
38
+ AccountCheckResult,
12
39
  DeclaredProvider,
13
40
  DeclaredRequirements,
41
+ ElicitationFailed,
42
+ ElicitationResponse,
43
+ FormElicitation,
14
44
  HostAccountsInvalid,
15
45
  HostDeclarationInvalid,
16
46
  HostError,
17
47
  HostEvaluationFailed,
18
48
  HostInputInvalid,
49
+ HostKindMismatch,
19
50
  HostOperationFailed,
20
51
  HostOperationNotFound,
21
52
  HostOutputInvalid,
@@ -25,23 +56,21 @@ import {
25
56
  HostToolBlocked,
26
57
  HostToolNotFound,
27
58
  HostToolPolicyFailed,
59
+ HostedRouter,
28
60
  HostedTool,
61
+ HostedToolSummary,
29
62
  HostedWebhook,
63
+ HostedWorkflow,
64
+ InvocationDeadline,
30
65
  ManualWebhookSetup,
31
- OperationToolPrefixes,
66
+ ManyAccounts,
67
+ McpError,
68
+ NonRetryableError,
69
+ OpenapiResponseError,
32
70
  ResolvedAccounts,
33
71
  ToolResultObservation,
34
72
  TrustedToolApproval,
35
73
  WebhookResponseData,
36
- defaultWebhookTransportLimits
37
- } from "./chunk-22WRQZT7.js";
38
- import {
39
- ElicitationFailed,
40
- ElicitationResponse,
41
- FormElicitation,
42
- HostedWorkflow,
43
- ManyAccounts,
44
- NonRetryableError,
45
74
  WorkflowDuration,
46
75
  WorkflowFailure,
47
76
  WorkflowName,
@@ -49,30 +78,44 @@ import {
49
78
  WorkflowStepOptions,
50
79
  WorkflowValue,
51
80
  approvalElicitation,
81
+ defaultWebhookTransportLimits,
82
+ maxInputProblems,
52
83
  workflowDurationMillis
53
- } from "./chunk-HP7E42X6.js";
84
+ } from "./chunk-WLE7WX2U.js";
85
+ import {
86
+ CacheError
87
+ } from "./chunk-R3EV5FTO.js";
88
+ import {
89
+ AppSkills,
90
+ SkillFile,
91
+ SkillLoadFailed
92
+ } from "./chunk-JU7VHODU.js";
54
93
  import {
55
94
  captureTelemetry,
56
95
  invocationFetch
57
- } from "./chunk-OWD2YICM.js";
96
+ } from "./chunk-ODEIDRGW.js";
58
97
  import {
98
+ decoderOf,
59
99
  importedJsonSchema,
60
- jsonSchemaDecoder
61
- } from "./chunk-BPEFS4YF.js";
100
+ jsonSchemaDecoder,
101
+ jsonSchemaDocument
102
+ } from "./chunk-5T57N25Q.js";
62
103
  import {
63
104
  JsonObject,
64
105
  JsonValue
65
- } from "./chunk-36DNRFZQ.js";
106
+ } from "./chunk-27F7W2LG.js";
66
107
  import {
67
108
  Cause_exports,
109
+ Clock_exports,
68
110
  Effect_exports,
69
111
  Encoding_exports,
70
112
  Match_exports,
71
113
  Option_exports,
72
114
  Redacted_exports,
115
+ SchemaIssue_exports,
73
116
  Schema_exports,
74
117
  Stream_exports
75
- } from "./chunk-2OTCEKL2.js";
118
+ } from "./chunk-CDL5PM2Q.js";
76
119
 
77
120
  // src/implementation/elicitation.ts
78
121
  var prepareElicitation = (input) => Effect_exports.gen(function* () {
@@ -113,19 +156,29 @@ var makeElicit = (handler, signal) => toPromise(
113
156
  var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
114
157
 
115
158
  // src/implementation/workflow-context.ts
116
- var workflowSafe = (work) => work.pipe(
159
+ var workflowSafe = (work, secrets) => work.pipe(
117
160
  Effect_exports.catchCause((cause) => {
118
161
  if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
119
162
  const error = Cause_exports.squash(cause);
120
163
  if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
164
+ const { errorName, message } = failureDetail(error, secrets);
121
165
  return Effect_exports.fail(
122
166
  new WorkflowFailure({
123
167
  reason: "execution",
124
- retryable: !(error instanceof NonRetryableError)
168
+ retryable: !(error instanceof NonRetryableError),
169
+ ...errorName === void 0 ? {} : { errorName },
170
+ ...message === void 0 ? {} : { message }
125
171
  })
126
172
  );
127
173
  })
128
174
  );
175
+ var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
176
+ reason: failure.reason,
177
+ retryable: failure.retryable,
178
+ step: step.slice(0, 200),
179
+ ...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
180
+ ...failure.message.length === 0 ? {} : { message: failure.message }
181
+ }) : failure;
129
182
  var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
130
183
  const services = yield* Effect_exports.context();
131
184
  const counts = /* @__PURE__ */ new Map();
@@ -156,7 +209,11 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
156
209
  Effect_exports.timeout(timeout),
157
210
  Effect_exports.catchTag(
158
211
  "TimeoutError",
159
- () => Effect_exports.fail(new WorkflowFailure({ reason: "execution", retryable: true }))
212
+ () => (
213
+ // Both the capability deadline and the native engine deadline describe
214
+ // the same cancellation, regardless of which timer fires first.
215
+ Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
216
+ )
160
217
  )
161
218
  );
162
219
  };
@@ -176,25 +233,33 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
176
233
  Effect_exports.sync(() => new AbortController()),
177
234
  (controller2) => Effect_exports.sync(() => controller2.abort())
178
235
  );
179
- const ctx = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
236
+ const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
180
237
  const result = yield* workflowSafe(
181
- Effect_exports.tryPromise({ try: () => callback(ctx), catch: (error) => error })
238
+ Effect_exports.tryPromise({
239
+ try: () => callback(step2.context),
240
+ catch: (error) => error
241
+ }),
242
+ step2.secrets
182
243
  );
183
244
  return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
184
245
  Effect_exports.mapError(
185
- () => new WorkflowFailure({ reason: "output", retryable: false })
246
+ () => new WorkflowFailure({
247
+ reason: "output",
248
+ retryable: false,
249
+ message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
250
+ })
186
251
  )
187
252
  );
188
253
  })
189
254
  ).pipe(Effect_exports.provideContext(services))
190
255
  )
191
- );
256
+ ).pipe(Effect_exports.mapError(inStep(name)));
192
257
  });
193
258
  const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
194
259
  const target = nativeOperation(operation);
195
- const catalog = kind === "query" ? definition.queries : definition.mutations;
196
- const match = Object.entries(catalog ?? {}).find(
197
- ([, value]) => value === target && value.kind === kind
260
+ const root = definition.tools?.kind === "router" ? definition.tools : void 0;
261
+ const match = declaredOperations(root).find(
262
+ (entry) => entry.operation === target && entry.operation.kind === kind
198
263
  );
199
264
  if (target === void 0 || match === void 0)
200
265
  return yield* new WorkflowFailure({ reason: "operation", retryable: false });
@@ -213,9 +278,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
213
278
  parsed,
214
279
  () => attempt(
215
280
  parsed,
216
- execution.invoke({ kind, name: match[0], input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
281
+ execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
217
282
  )
218
- );
283
+ ).pipe(Effect_exports.mapError(inStep(name)));
219
284
  });
220
285
  const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
221
286
  const step = {
@@ -253,6 +318,23 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
253
318
  return { runId: execution.runId, step };
254
319
  });
255
320
 
321
+ // src/implementation/input-problems.ts
322
+ var leafHook = (issue) => SchemaIssue_exports.hasInput(issue) ? "Invalid value" : SchemaIssue_exports.defaultLeafHook(issue);
323
+ var checkHook = (issue) => SchemaIssue_exports.hasInput(issue) || SchemaIssue_exports.hasInput(issue.issue) ? SchemaIssue_exports.defaultCheckHook(issue) ?? "Invalid value" : SchemaIssue_exports.defaultCheckHook(issue);
324
+ var format = SchemaIssue_exports.makeFormatterStandardSchemaV1({ leafHook, checkHook });
325
+ var segment = (key) => typeof key === "number" ? `[${key}]` : typeof key === "string" && /^[A-Za-z_$][\w$-]{0,63}$/.test(key) ? `.${key}` : "[key]";
326
+ var inputInvalid = (error) => {
327
+ if (!Schema_exports.isSchemaError(error)) return new HostInputInvalid();
328
+ const problems = format(error.issue).issues.slice(0, maxInputProblems).map(({ path, message }) => {
329
+ const location = (path ?? []).map((key) => segment(typeof key === "object" ? key.key : key));
330
+ return `${location.length === 0 ? "input" : `input${location.join("")}`}: ${message}`.slice(
331
+ 0,
332
+ 512
333
+ );
334
+ });
335
+ return new HostInputInvalid({ problems });
336
+ };
337
+
256
338
  // src/implementation/webhooks.ts
257
339
  var safe = (work, error) => Effect_exports.suspend(work).pipe(
258
340
  Effect_exports.catchCause(
@@ -407,7 +489,79 @@ var dispatchWebhook = (definition, command, context, accounts) => Effect_exports
407
489
  );
408
490
  });
409
491
 
492
+ // src/implementation/cache.ts
493
+ var unavailableCache = {
494
+ transport: () => Effect_exports.fail(new CacheError({ reason: "unavailable" })),
495
+ background: () => Effect_exports.die(new Error("Cache background runner is unavailable"))
496
+ };
497
+ var authorCache = (host, accounts, signal, deadline) => {
498
+ const scoped = (scope, callerSignal = signal) => {
499
+ const cache = makeCache(host.transport, host.background, scope, deadline);
500
+ const load = (method, options) => cache[method]({
501
+ key: options.key,
502
+ schema: decoderOf(options.schema),
503
+ freshFor: options.freshFor,
504
+ ...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
505
+ load: Effect_exports.acquireUseRelease(
506
+ Effect_exports.sync(() => new AbortController()),
507
+ (controller) => invocationFetch(controller.signal).pipe(
508
+ Effect_exports.flatMap(
509
+ (fetch) => fromPromise(options.load)({
510
+ fetch,
511
+ signal: controller.signal,
512
+ cache: scoped(scope, controller.signal)
513
+ })
514
+ )
515
+ ),
516
+ (controller) => Effect_exports.sync(() => controller.abort())
517
+ )
518
+ });
519
+ return {
520
+ get: toPromise((options) => load("get", options), callerSignal),
521
+ revalidate: toPromise(
522
+ (options) => load("revalidate", options),
523
+ callerSignal
524
+ ),
525
+ read: toPromise(
526
+ (key, schema) => cache.read([key]).pipe(
527
+ Effect_exports.flatMap((entries) => {
528
+ const entry = entries[0];
529
+ return entry === void 0 || entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value);
530
+ })
531
+ ),
532
+ callerSignal
533
+ ),
534
+ readMany: toPromise(
535
+ (keys, schema) => cache.read(keys).pipe(
536
+ Effect_exports.flatMap(
537
+ (entries) => Effect_exports.forEach(
538
+ entries,
539
+ (entry) => entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value)
540
+ )
541
+ )
542
+ ),
543
+ callerSignal
544
+ ),
545
+ write: toPromise(cache.write, callerSignal),
546
+ invalidate: toPromise(cache.invalidate, callerSignal),
547
+ forAccount: (account) => {
548
+ const bound = Object.values(accounts).flatMap((value) => Array.isArray(value) ? value : [value]).find((value) => value.id === account.id);
549
+ if (bound === void 0) throw new CacheError({ reason: "invalid" });
550
+ return scoped(
551
+ { account: bound.id, method: bound.method, generation: bound.generation },
552
+ callerSignal
553
+ );
554
+ }
555
+ };
556
+ };
557
+ return scoped("shared");
558
+ };
559
+
410
560
  // src/implementation/host.ts
561
+ var WireCatalog = Schema_exports.Struct({
562
+ tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
563
+ routers: Schema_exports.Array(HostedRouter)
564
+ });
411
565
  function safe2(work, failure) {
412
566
  return Effect_exports.suspend(work).pipe(
413
567
  Effect_exports.catchCause(
@@ -415,18 +569,33 @@ function safe2(work, failure) {
415
569
  )
416
570
  );
417
571
  }
418
- function jsonSchema(decoder) {
419
- const imported = importedJsonSchema(decoder);
420
- if (imported !== void 0) return Schema_exports.decodeUnknownEffect(JsonObject)(imported);
421
- const document = Schema_exports.toJsonSchemaDocument(decoder);
422
- return Schema_exports.decodeUnknownEffect(JsonObject)({
423
- ...document.schema,
424
- $defs: document.definitions,
425
- $schema: "https://json-schema.org/draft/2020-12/schema"
426
- });
427
- }
572
+ var evaluationSafe = (work, secrets) => work.pipe(
573
+ Effect_exports.catchCause((cause) => {
574
+ if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
575
+ const error = Cause_exports.squash(cause);
576
+ const provider = parseProviderError(error);
577
+ const skills = parseSkillLoadFailed(error);
578
+ const mcp = parseMcpError(error);
579
+ return Effect_exports.fail(
580
+ Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
581
+ );
582
+ })
583
+ );
584
+ var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
585
+ source: "app",
586
+ errorName: "HostDeclarationInvalid",
587
+ message: boundFailureMessage(
588
+ cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
589
+ secrets
590
+ )
591
+ });
592
+ var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
593
+ Effect_exports.catchCause(
594
+ (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
595
+ )
596
+ );
428
597
  function providerDeclaration(provider) {
429
- return safe2(
598
+ return declarationSafe(
430
599
  () => Effect_exports.gen(function* () {
431
600
  const auth = /* @__PURE__ */ new Map();
432
601
  for (const [name, method] of Object.entries(provider.auth)) {
@@ -435,14 +604,14 @@ function providerDeclaration(provider) {
435
604
  auth.set(name, {
436
605
  type: "secrets",
437
606
  label: method.label,
438
- fields: yield* jsonSchema(method.fields)
607
+ fields: yield* jsonSchemaDocument(method.fields)
439
608
  });
440
609
  break;
441
610
  case "oauth2":
442
611
  auth.set(name, {
443
612
  type: "oauth2",
444
613
  ...method.config,
445
- response: yield* jsonSchema(method.response)
614
+ response: yield* jsonSchemaDocument(method.response)
446
615
  });
447
616
  break;
448
617
  }
@@ -452,24 +621,29 @@ function providerDeclaration(provider) {
452
621
  auth: Object.fromEntries(auth)
453
622
  });
454
623
  }),
455
- new HostDeclarationInvalid()
624
+ `Account provider "${provider.name}" has an invalid declaration`
456
625
  );
457
626
  }
458
627
  function requirements(slots, database) {
459
628
  return Effect_exports.gen(function* () {
460
629
  const accounts = /* @__PURE__ */ new Map();
461
630
  for (const [slot, selection] of Object.entries(slots)) {
631
+ const provider = selection instanceof ManyAccounts ? selection.provider : selection;
462
632
  accounts.set(slot, {
463
633
  cardinality: selection instanceof ManyAccounts ? "many" : "one",
464
- definition: yield* providerDeclaration(
465
- selection instanceof ManyAccounts ? selection.provider : selection
466
- )
634
+ definition: yield* providerDeclaration(provider),
635
+ ...provider.health === void 0 ? {} : { health: true }
467
636
  });
468
637
  }
469
638
  return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
470
639
  accounts: Object.fromEntries(accounts),
640
+ capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
471
641
  ...database === void 0 ? {} : { database }
472
- }).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
642
+ }).pipe(
643
+ Effect_exports.mapError(
644
+ (cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
645
+ )
646
+ );
473
647
  });
474
648
  }
475
649
  function canonical(value) {
@@ -525,22 +699,100 @@ function bindAccounts(slots, declarations, context) {
525
699
  new HostAccountsInvalid()
526
700
  );
527
701
  }
702
+ var fetchLifetime = (signal, background) => Effect_exports.acquireRelease(
703
+ Effect_exports.sync(() => {
704
+ const controller = new AbortController();
705
+ let refreshes = 0;
706
+ let ended = false;
707
+ const settle = () => {
708
+ if (ended && refreshes === 0) controller.abort();
709
+ };
710
+ const end = () => {
711
+ ended = true;
712
+ settle();
713
+ };
714
+ signal.addEventListener("abort", end, { once: true });
715
+ if (signal.aborted) end();
716
+ const settled = Effect_exports.sync(() => {
717
+ refreshes -= 1;
718
+ settle();
719
+ });
720
+ return {
721
+ signal: controller.signal,
722
+ close: () => {
723
+ signal.removeEventListener("abort", end);
724
+ end();
725
+ },
726
+ /** Counted from the hand-off, so a refresh that has not started yet keeps the fetch. */
727
+ background: (task) => Effect_exports.suspend(() => {
728
+ refreshes += 1;
729
+ return background(task.pipe(Effect_exports.ensuring(settled))).pipe(
730
+ Effect_exports.onError(() => settled)
731
+ );
732
+ })
733
+ };
734
+ }),
735
+ (lifetime) => Effect_exports.sync(lifetime.close)
736
+ );
528
737
  function dispatch(app, request, context, signal) {
529
738
  return Effect_exports.scoped(
530
739
  Effect_exports.gen(function* () {
531
- if (!isApp(app)) return yield* Effect_exports.fail(new HostDeclarationInvalid());
740
+ if (!isApp(app))
741
+ return yield* Effect_exports.fail(
742
+ declarationInvalid("The app module's default export is not an app created by defineApp")
743
+ );
532
744
  const native = toEffectApp(app);
745
+ const secrets = accountSecrets(context.accounts);
746
+ const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
533
747
  const declared = yield* requirements(native.accounts, native.database?.schema);
534
- if (request.operation === "requirements")
748
+ if (request.operation === "requirements") {
749
+ if (native.database !== void 0)
750
+ yield* parseDatabaseSchema(native.database.schema).pipe(
751
+ Effect_exports.catchTag(
752
+ "AppDatabaseError",
753
+ (cause) => Effect_exports.fail(
754
+ declarationInvalid("The app's account or database declarations are invalid", cause)
755
+ )
756
+ )
757
+ );
535
758
  return yield* safe2(
536
759
  () => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
537
760
  new HostDeclarationInvalid()
538
761
  );
762
+ }
539
763
  const lifetime = yield* Effect_exports.acquireRelease(
540
764
  Effect_exports.sync(() => new AbortController()),
541
765
  (controller) => Effect_exports.sync(() => controller.abort())
542
766
  );
543
767
  const invocationSignal = AbortSignal.any([signal, lifetime.signal]);
768
+ const deadline = context.deadline === void 0 ? void 0 : yield* safe2(
769
+ () => Schema_exports.decodeUnknownEffect(InvocationDeadline)(context.deadline),
770
+ new HostInputInvalid()
771
+ );
772
+ const withinDeadline = (work) => Effect_exports.gen(function* () {
773
+ if (deadline === void 0) return yield* work;
774
+ const remaining = deadline - (yield* Clock_exports.currentTimeMillis);
775
+ if (remaining <= 0)
776
+ return yield* new WorkflowFailure({ reason: "engine", retryable: true });
777
+ const result = yield* work.pipe(
778
+ Effect_exports.timeout(remaining),
779
+ Effect_exports.catchTag(
780
+ "TimeoutError",
781
+ () => Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
782
+ )
783
+ );
784
+ if ((yield* Clock_exports.currentTimeMillis) >= deadline)
785
+ return yield* new WorkflowFailure({ reason: "engine", retryable: true });
786
+ return result;
787
+ });
788
+ if (request.operation === "account-check")
789
+ return yield* checkAccount(
790
+ native.accounts,
791
+ declared,
792
+ request.requirement,
793
+ context,
794
+ invocationSignal
795
+ ).pipe(withinDeadline);
544
796
  let running;
545
797
  let transactionOpen = false;
546
798
  const delivery = (request2, signal2) => Effect_exports.suspend(
@@ -572,29 +824,69 @@ function dispatch(app, request, context, signal) {
572
824
  get: workflowControls.get,
573
825
  list: workflowControls.list
574
826
  };
827
+ const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
828
+ context.files ?? []
829
+ ).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
830
+ let cacheCommands = 0;
831
+ const hostCache = context.cache ?? unavailableCache;
832
+ const fetching = yield* fetchLifetime(signal, hostCache.background);
575
833
  const bound = {
834
+ cache: authorCache(
835
+ {
836
+ ...hostCache,
837
+ transport: (command) => {
838
+ cacheCommands += 1;
839
+ return hostCache.transport(command);
840
+ },
841
+ background: fetching.background
842
+ },
843
+ Redacted_exports.value(context.accounts),
844
+ invocationSignal,
845
+ deadline
846
+ ),
847
+ files,
576
848
  ...yield* bindAccounts(native.accounts, declared, context).pipe(
577
849
  Effect_exports.withSpan("app.accounts.bind")
578
850
  ),
579
851
  workflows: workflowReads,
580
852
  signal: invocationSignal,
581
- fetch: yield* invocationFetch(invocationSignal),
853
+ fetch: yield* invocationFetch(fetching.signal),
582
854
  elicit: makeElicit(delivery, invocationSignal)
583
855
  };
584
- const definition = yield* safe2(
585
- () => native.evaluate(bound).pipe(Effect_exports.withSpan("app.evaluate")),
586
- new HostEvaluationFailed()
856
+ const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
857
+ Effect_exports.withSpan("app.evaluate")
587
858
  );
859
+ if (request.operation === "skills") {
860
+ const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
861
+ Effect_exports.mapError(() => new HostDeclarationInvalid())
862
+ ));
863
+ const source = definition.dynamicSkills;
864
+ const before = cacheCommands;
865
+ const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
866
+ Effect_exports.withSpan("app.skills.load")
867
+ );
868
+ const cached = source !== void 0 && cacheCommands > before;
869
+ const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
870
+ const routed = (yield* routerSkills(definition.tools).pipe(
871
+ Effect_exports.withSpan("app.skills.routers")
872
+ )).filter((skill) => !authored.has(skill.name));
873
+ const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
874
+ ...declared2,
875
+ ...dynamic,
876
+ ...routed
877
+ ]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
878
+ return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
879
+ }
588
880
  if (request.operation === "workflows") {
589
881
  return yield* Effect_exports.forEach(
590
882
  Object.entries(definition.workflows ?? {}),
591
- ([name2, entry]) => safe2(
883
+ ([name, entry]) => safe2(
592
884
  () => Effect_exports.gen(function* () {
593
885
  return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
594
- name: name2,
886
+ name,
595
887
  ...entry.description === void 0 ? {} : { description: entry.description },
596
- inputSchema: yield* jsonSchema(entry.input),
597
- ...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchema(entry.output) }
888
+ inputSchema: yield* jsonSchemaDocument(entry.input),
889
+ ...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
598
890
  });
599
891
  }),
600
892
  new HostDeclarationInvalid()
@@ -627,61 +919,68 @@ function dispatch(app, request, context, signal) {
627
919
  new WorkflowFailure({ reason: "credentials", retryable: false })
628
920
  );
629
921
  return {
630
- ...accounts,
631
- fetch: yield* invocationFetch(signal2),
632
- signal: signal2,
633
- runId: execution.runId,
634
- stepId,
635
- idempotencyKey: stepId
922
+ context: {
923
+ ...accounts,
924
+ cache: authorCache(
925
+ context.cache ?? unavailableCache,
926
+ Redacted_exports.value(current.accounts),
927
+ signal2
928
+ ),
929
+ files,
930
+ fetch: yield* invocationFetch(signal2),
931
+ signal: signal2,
932
+ runId: execution.runId,
933
+ stepId,
934
+ idempotencyKey: stepId
935
+ },
936
+ // The resolved values, not the app's decoded fields, which may be `Redacted`.
937
+ secrets: accountSecrets(current.accounts)
636
938
  };
637
939
  }),
638
940
  invocationSignal
639
941
  );
640
- const output = yield* workflowSafe(entry.run(workflowContext, input2));
942
+ const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
641
943
  const outputSchema = entry.output;
642
944
  const decoded = outputSchema === void 0 ? output : yield* safe2(
643
945
  () => Schema_exports.decodeUnknownEffect(outputSchema)(output),
644
- new WorkflowFailure({ reason: "output", retryable: false })
946
+ new WorkflowFailure({
947
+ reason: "output",
948
+ retryable: false,
949
+ message: "The workflow's result does not match its declared output schema."
950
+ })
645
951
  );
646
952
  return yield* safe2(
647
953
  () => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
648
- new WorkflowFailure({ reason: "output", retryable: false })
954
+ new WorkflowFailure({
955
+ reason: "output",
956
+ retryable: false,
957
+ message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
958
+ })
649
959
  );
650
960
  }
651
961
  if (request.operation === "inspect") {
652
- const metadata = [];
653
- for (const [prefix, readOnly, catalog2] of [
654
- [OperationToolPrefixes.query, true, definition.queries],
655
- [OperationToolPrefixes.mutate, false, definition.mutations]
656
- ]) {
657
- for (const [name2, operation] of Object.entries(catalog2 ?? {})) {
658
- metadata.push(
659
- yield* safe2(
660
- () => Effect_exports.gen(function* () {
661
- return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
662
- name: `${prefix}${name2}`,
663
- schedules: Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === `${prefix}${name2}`).map(([name3, { tool: _tool, ...schedule }]) => ({ name: name3, ...schedule })),
664
- description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
665
- ...operation.title === void 0 ? {} : { title: operation.title },
666
- inputSchema: yield* jsonSchema(operation.input),
667
- ...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
668
- readOnly,
669
- annotations: { ...operation.annotations, readOnlyHint: readOnly },
670
- ...operation._meta === void 0 ? {} : { _meta: operation._meta }
671
- });
672
- }),
673
- new HostDeclarationInvalid()
674
- )
675
- );
676
- }
677
- }
678
- return metadata;
962
+ const summary = request.detail === "summary";
963
+ const catalog = yield* readCatalog(definition.tools, {
964
+ summary,
965
+ secrets,
966
+ ...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
967
+ ...request.scheduled === true ? { scheduled: true } : {},
968
+ schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
969
+ }).pipe(Effect_exports.withSpan("app.catalog.read"));
970
+ return yield* safe2(
971
+ () => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
972
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
973
+ ),
974
+ new HostDeclarationInvalid()
975
+ );
679
976
  }
680
977
  if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
681
978
  const executeWebhook = (db) => dispatchWebhook(
682
979
  definition,
683
980
  request,
684
981
  {
982
+ files,
983
+ cache: bound.cache,
685
984
  accounts: bound.accounts,
686
985
  workflows: workflowControls,
687
986
  signal: bound.signal,
@@ -697,23 +996,28 @@ function dispatch(app, request, context, signal) {
697
996
  const storage2 = context.storage ?? unavailableStorage;
698
997
  return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
699
998
  Effect_exports.catchTags({
700
- AppDatabaseError: () => Effect_exports.fail(new HostOperationFailed()),
701
- AppStorageUnavailable: () => Effect_exports.fail(new HostOperationFailed()),
702
- AppStorageError: () => Effect_exports.fail(new HostOperationFailed())
999
+ AppDatabaseError: storageFailure,
1000
+ DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
1001
+ AppStorageUnavailable: storageFailure,
1002
+ AppStorageError: storageFailure
703
1003
  })
704
1004
  );
705
1005
  }
706
- const kind = request.operation === "call" ? request.tool.startsWith(OperationToolPrefixes.query) ? "query" : request.tool.startsWith(OperationToolPrefixes.mutate) ? "mutate" : void 0 : request.operation;
707
- if (kind === void 0) return yield* new HostToolNotFound();
708
- const name = request.operation === "call" ? request.tool.slice(OperationToolPrefixes[kind].length) : request.name;
709
- const toolName = `${OperationToolPrefixes[kind]}${name}`;
710
- const catalog = kind === "query" ? definition.queries : definition.mutations;
711
- const tool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
1006
+ const toolName = request.operation === "call" ? request.tool : request.name;
1007
+ const location = locate(definition.tools, toolName);
1008
+ const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
712
1009
  if (tool === void 0)
713
1010
  return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
714
- const input = yield* safe2(
715
- () => Schema_exports.decodeUnknownEffect(tool.input)(request.input),
716
- new HostInputInvalid()
1011
+ const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
1012
+ if (requested !== void 0 && tool.kind !== requested)
1013
+ return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
1014
+ const kind = tool.kind === "query" ? "query" : "mutate";
1015
+ const input = yield* Effect_exports.suspend(
1016
+ () => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
1017
+ ).pipe(
1018
+ Effect_exports.catchCause(
1019
+ (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(inputInvalid(Cause_exports.squash(cause)))
1020
+ )
717
1021
  );
718
1022
  if (context.approval !== void 0) {
719
1023
  const approved = yield* safe2(
@@ -761,7 +1065,7 @@ function dispatch(app, request, context, signal) {
761
1065
  transactionOpen = db !== void 0;
762
1066
  const output = yield* Effect_exports.gen(function* () {
763
1067
  running = yield* captureTelemetry;
764
- const fetch = yield* invocationFetch(invocationSignal);
1068
+ const fetch = yield* invocationFetch(fetching.signal);
765
1069
  return yield* tool.run(
766
1070
  {
767
1071
  ...bound,
@@ -779,9 +1083,6 @@ function dispatch(app, request, context, signal) {
779
1083
  input
780
1084
  );
781
1085
  }).pipe(
782
- Effect_exports.withSpan("app.operation.execute", {
783
- attributes: { "executor.tool.name": toolName, "executor.operation": kind }
784
- }),
785
1086
  Effect_exports.ensuring(
786
1087
  Effect_exports.sync(() => {
787
1088
  running = void 0;
@@ -789,10 +1090,21 @@ function dispatch(app, request, context, signal) {
789
1090
  ),
790
1091
  Effect_exports.catchCause((cause) => {
791
1092
  if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
792
- const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(Cause_exports.squash(cause));
1093
+ const error = Cause_exports.squash(cause);
1094
+ const provider = parseProviderError(error);
1095
+ const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
1096
+ const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
793
1097
  return Effect_exports.fail(
794
- Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
1098
+ Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
1099
+ code: response.value.code,
1100
+ status: response.value.status,
1101
+ message: response.value.message,
1102
+ ...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
1103
+ }) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
795
1104
  );
1105
+ }),
1106
+ Effect_exports.withSpan("app.operation.execute", {
1107
+ attributes: { "executor.tool.name": toolName, "executor.operation": kind }
796
1108
  })
797
1109
  );
798
1110
  const outputSchema = tool.output;
@@ -810,33 +1122,97 @@ function dispatch(app, request, context, signal) {
810
1122
  new HostInputInvalid()
811
1123
  );
812
1124
  if (replay !== void 0 && kind !== "mutate") return yield* new HostInputInvalid();
813
- if (native.database === void 0) return yield* execute();
1125
+ if (native.database === void 0) return yield* withinDeadline(execute());
814
1126
  const storage = context.storage ?? unavailableStorage;
815
1127
  return yield* storage[kind === "query" ? "read" : "mutate"](
816
1128
  native.database.schema,
817
- (db) => replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
1129
+ (db) => withinDeadline(
1130
+ replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
1131
+ )
818
1132
  ).pipe(
819
1133
  Effect_exports.catchTags({
820
- AppDatabaseError: () => Effect_exports.fail(new HostOperationFailed()),
821
- AppStorageUnavailable: () => Effect_exports.fail(new HostOperationFailed()),
822
- AppStorageError: () => Effect_exports.fail(new HostOperationFailed())
1134
+ AppDatabaseError: storageFailure,
1135
+ DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
1136
+ AppStorageUnavailable: storageFailure,
1137
+ AppStorageError: storageFailure
823
1138
  })
824
1139
  );
825
1140
  })
826
1141
  );
827
1142
  }
1143
+ function checkAccount(slots, declared, requirement, context, signal) {
1144
+ return Effect_exports.gen(function* () {
1145
+ const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
1146
+ const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
1147
+ if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
1148
+ const provider = selection instanceof ManyAccounts ? selection.provider : selection;
1149
+ const health = provider.health;
1150
+ if (health === void 0) return yield* new HostOperationNotFound();
1151
+ const { accounts } = yield* bindAccounts(
1152
+ { [requirement]: provider },
1153
+ { accounts: { [requirement]: { ...slot, cardinality: "one" } } },
1154
+ context
1155
+ ).pipe(Effect_exports.withSpan("app.accounts.bind"));
1156
+ const account = accounts[requirement];
1157
+ if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
1158
+ const result = yield* Effect_exports.suspend(
1159
+ () => Effect_exports.gen(function* () {
1160
+ return yield* health.run({ account, fetch: yield* invocationFetch(signal), signal });
1161
+ })
1162
+ ).pipe(
1163
+ Effect_exports.catchCause((cause) => {
1164
+ if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
1165
+ const error = Cause_exports.squash(cause);
1166
+ const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
1167
+ const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
1168
+ return Effect_exports.fail(
1169
+ Option_exports.isSome(classified) ? accountProviderError(classified.value, account.id) : new HostOperationFailed()
1170
+ );
1171
+ }),
1172
+ Effect_exports.withSpan("app.account.check")
1173
+ );
1174
+ return yield* safe2(
1175
+ () => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
1176
+ Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
1177
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
1178
+ ),
1179
+ new HostOutputInvalid()
1180
+ );
1181
+ });
1182
+ }
1183
+ var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
1184
+ Option_exports.map(
1185
+ ({ reason, message, status }) => new SkillLoadFailed({
1186
+ reason,
1187
+ ...message ? { message } : {},
1188
+ ...status === void 0 ? {} : { status }
1189
+ })
1190
+ )
1191
+ );
1192
+ var parseMcpError = (error) => Schema_exports.decodeUnknownOption(McpError)(error).pipe(
1193
+ Option_exports.map(
1194
+ ({ phase, reason, status }) => new McpError({ phase, reason, ...status === void 0 ? {} : { status } })
1195
+ )
1196
+ );
828
1197
  var errorStatus = Match_exports.type().pipe(
829
1198
  Match_exports.tagsExhaustive({
1199
+ ProviderError: () => 502,
1200
+ McpError: () => 502,
1201
+ SkillLoadFailed: () => 502,
1202
+ OpenapiResponseError: () => 502,
830
1203
  WorkflowFailure: () => 422,
831
1204
  HostRequestInvalid: () => 400,
832
1205
  HostAccountsInvalid: () => 422,
833
1206
  HostInputInvalid: () => 422,
834
1207
  HostOperationNotFound: () => 404,
1208
+ HostKindMismatch: () => 409,
835
1209
  HostToolNotFound: () => 404,
836
1210
  HostToolBlocked: () => 403,
837
1211
  HostToolApprovalRequired: () => 409,
838
1212
  HostToolPolicyFailed: () => 500,
839
1213
  HostOperationFailed: () => 500,
1214
+ DatabaseLimitExceeded: () => 422,
1215
+ DatabaseFieldReserved: () => 422,
840
1216
  HostDeclarationInvalid: () => 500,
841
1217
  HostEvaluationFailed: () => 500,
842
1218
  HostOutputInvalid: () => 500,
@@ -882,12 +1258,17 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
882
1258
  ),
883
1259
  Effect_exports.catchCause(
884
1260
  (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
885
- Effect_exports.as(
886
- Response.json(
887
- { ok: false, error: { _tag: "HostDeclarationInvalid" } },
888
- { status: 500 }
1261
+ Effect_exports.andThen(
1262
+ Schema_exports.encodeEffect(HostError)(
1263
+ declarationInvalid(
1264
+ "The app failed while it was loaded",
1265
+ Cause_exports.squash(cause),
1266
+ accountSecrets(context.accounts)
1267
+ )
889
1268
  )
890
- )
1269
+ ),
1270
+ Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
1271
+ Effect_exports.orDie
891
1272
  )
892
1273
  )
893
1274
  );