apps 0.0.1-beta.9 → 0.0.1-beta.91

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 (191) hide show
  1. package/README.md +56 -38
  2. package/framework-reference.json +1 -1
  3. package/js/chunk-3LEVTFD4.js +712 -0
  4. package/js/chunk-5FHWNLCI.js +88 -0
  5. package/js/{chunk-FL2QR3XW.js → chunk-5MDA7MKL.js} +338 -73
  6. package/js/chunk-6XQLA5NC.js +5047 -0
  7. package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
  8. package/js/chunk-7PHHWYV4.js +335 -0
  9. package/js/chunk-DADXWWRZ.js +449 -0
  10. package/js/{chunk-27F7W2LG.js → chunk-DDHBUKXX.js} +18 -2
  11. package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
  12. package/js/{chunk-5T57N25Q.js → chunk-GQ33QSNB.js} +583 -69
  13. package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
  14. package/js/chunk-I5C7FD5Z.js +171 -0
  15. package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
  16. package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
  17. package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
  18. package/js/{chunk-RFVIONFX.js → chunk-KUCCHNVY.js} +123 -44
  19. package/js/chunk-OD3KFKZD.js +1617 -0
  20. package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
  21. package/js/{chunk-72JNVHPK.js → chunk-PYQLOLOC.js} +4 -3
  22. package/js/{chunk-ODEIDRGW.js → chunk-QWQM3CLH.js} +795 -176
  23. package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
  24. package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
  25. package/js/chunk-XPRZTLHD.js +1915 -0
  26. package/js/chunk-YNJ5CZMJ.js +93 -0
  27. package/js/chunk-YRGL4QEF.js +49 -0
  28. package/js/{chunk-Z5M2LQOZ.js → chunk-YWFUWTUJ.js} +113 -58
  29. package/js/client.js +142 -78
  30. package/js/contracts.js +142 -21
  31. package/js/effect.js +18 -19
  32. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  33. package/js/graphql.js +49 -40
  34. package/js/host.js +85 -62
  35. package/js/index.js +165 -70
  36. package/js/mcp/effect.js +21 -21
  37. package/js/mcp.js +76 -56
  38. package/js/openapi.js +4189 -1411
  39. package/js/react.js +2 -3
  40. package/js/skills/effect.js +6 -3
  41. package/js/skills.js +208 -81
  42. package/js/storage/facet.js +1 -540
  43. package/js/ui/auth/contracts.js +2 -2
  44. package/js/ui/auth.js +5 -5
  45. package/js/ui/contracts.js +5 -4
  46. package/js/ui/serving.js +8605 -225
  47. package/package.json +3 -8
  48. package/runtime.json +1 -1
  49. package/types/app-cache/src/contracts/cache.d.ts +18 -0
  50. package/types/app-cache/src/index.d.ts +34 -2
  51. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  52. package/types/apps/src/contracts/app.d.ts +60 -11
  53. package/types/apps/src/contracts/cache.d.ts +20 -0
  54. package/types/apps/src/contracts/context.d.ts +60 -17
  55. package/types/apps/src/contracts/elicitation.d.ts +23 -7
  56. package/types/apps/src/contracts/events.d.ts +94 -0
  57. package/types/apps/src/contracts/failure.d.ts +30 -1
  58. package/types/apps/src/contracts/graphql.d.ts +2 -1
  59. package/types/apps/src/contracts/host.d.ts +1446 -17
  60. package/types/apps/src/contracts/icons.d.ts +28 -0
  61. package/types/apps/src/contracts/live.d.ts +2 -0
  62. package/types/apps/src/contracts/mcp.d.ts +81 -20
  63. package/types/apps/src/contracts/network.d.ts +120 -0
  64. package/types/apps/src/contracts/openapi-compile.d.ts +82 -3
  65. package/types/apps/src/contracts/openapi.d.ts +41 -9
  66. package/types/apps/src/contracts/operations.d.ts +14 -7
  67. package/types/apps/src/contracts/placement.d.ts +102 -0
  68. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  69. package/types/apps/src/contracts/protocols/1.d.ts +733 -81
  70. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  71. package/types/apps/src/contracts/protocols/11.d.ts +1149 -0
  72. package/types/apps/src/contracts/protocols/12.d.ts +3310 -0
  73. package/types/apps/src/contracts/protocols/2.d.ts +69 -26
  74. package/types/apps/src/contracts/protocols/3.d.ts +133 -33
  75. package/types/apps/src/contracts/protocols/4.d.ts +122 -45
  76. package/types/apps/src/contracts/protocols/5.d.ts +157 -47
  77. package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
  78. package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
  79. package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
  80. package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
  81. package/types/apps/src/contracts/protocols/current.d.ts +6669 -0
  82. package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
  83. package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
  84. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  85. package/types/apps/src/contracts/provider.d.ts +90 -6
  86. package/types/apps/src/contracts/schedules.d.ts +7 -1
  87. package/types/apps/src/contracts/schema.d.ts +21 -0
  88. package/types/apps/src/contracts/skills.d.ts +50 -13
  89. package/types/apps/src/contracts/sql.d.ts +63 -0
  90. package/types/apps/src/contracts/ui.d.ts +44 -14
  91. package/types/apps/src/contracts/webhooks.d.ts +24 -7
  92. package/types/apps/src/contracts/workflows.d.ts +19 -17
  93. package/types/apps/src/facet.d.ts +4 -5
  94. package/types/apps/src/host.d.ts +5 -0
  95. package/types/apps/src/implementation/account-router.d.ts +4 -3
  96. package/types/apps/src/implementation/app.d.ts +41 -14
  97. package/types/apps/src/implementation/authoring.d.ts +25 -5
  98. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  99. package/types/apps/src/implementation/cache.d.ts +29 -2
  100. package/types/apps/src/implementation/catalog-cache.d.ts +35 -4
  101. package/types/apps/src/implementation/elicitation.d.ts +18 -15
  102. package/types/apps/src/implementation/events.d.ts +64 -0
  103. package/types/apps/src/implementation/failure-detail.d.ts +28 -5
  104. package/types/apps/src/implementation/graphql-catalog.d.ts +3 -3
  105. package/types/apps/src/implementation/graphql.d.ts +4 -3
  106. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  107. package/types/apps/src/implementation/invocation-timing.d.ts +18 -0
  108. package/types/apps/src/implementation/live.d.ts +2 -2
  109. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  110. package/types/apps/src/implementation/mcp-catalog.d.ts +6 -4
  111. package/types/apps/src/implementation/mcp-client.d.ts +17 -9
  112. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  113. package/types/apps/src/implementation/mcp.d.ts +20 -9
  114. package/types/apps/src/implementation/network.d.ts +16 -0
  115. package/types/apps/src/implementation/openapi-compile.d.ts +28 -7
  116. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  117. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  118. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  119. package/types/apps/src/implementation/openapi-source.d.ts +23 -1
  120. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  121. package/types/apps/src/implementation/operations.d.ts +57 -7
  122. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  123. package/types/apps/src/implementation/placement.d.ts +60 -0
  124. package/types/apps/src/implementation/protocol-operations.d.ts +3 -0
  125. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  126. package/types/apps/src/implementation/provider.d.ts +19 -4
  127. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  128. package/types/apps/src/implementation/router-catalog.d.ts +20 -18
  129. package/types/apps/src/implementation/router.d.ts +24 -5
  130. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  131. package/types/apps/src/implementation/schedules.d.ts +39 -8
  132. package/types/apps/src/implementation/schema.d.ts +98 -11
  133. package/types/apps/src/implementation/skills.d.ts +18 -24
  134. package/types/apps/src/implementation/sql.d.ts +71 -0
  135. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  136. package/types/apps/src/implementation/ui-auth.d.ts +1 -1
  137. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  138. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  139. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  140. package/types/apps/src/implementation/ui-serving.d.ts +26 -9
  141. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  142. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  143. package/types/apps/src/implementation/webhooks.d.ts +15 -6
  144. package/types/apps/src/implementation/workflow-context.d.ts +6 -2
  145. package/types/apps/src/implementation/workflows.d.ts +11 -4
  146. package/types/apps/src/index.d.ts +68 -19
  147. package/types/apps/src/mcp.d.ts +20 -1
  148. package/types/apps/src/openapi.d.ts +6 -1
  149. package/types/apps/src/react.d.ts +1 -1
  150. package/types/apps/src/skills.d.ts +10 -8
  151. package/types/apps/src/ui-serving.d.ts +1 -1
  152. package/types/telemetry/src/app-records.d.ts +42 -0
  153. package/types/telemetry/src/browser-operations.d.ts +2 -2
  154. package/types/telemetry/src/browser.d.ts +8 -3
  155. package/types/telemetry/src/config.d.ts +2 -2
  156. package/types/telemetry/src/index.d.ts +2 -1
  157. package/types/telemetry/src/layer.d.ts +10 -4
  158. package/types/telemetry/src/measurements.d.ts +1 -1
  159. package/types/telemetry/src/ownership.d.ts +60 -0
  160. package/types/telemetry/src/recorded-failure.d.ts +29 -0
  161. package/types/telemetry/src/relay.d.ts +16 -6
  162. package/types/telemetry/src/span-attributes.d.ts +17 -1
  163. package/types/telemetry/src/transport.d.ts +8 -1
  164. package/types/utils/src/api-error.d.ts +55 -0
  165. package/types/utils/src/connection-failure.d.ts +33 -0
  166. package/types/utils/src/recorded-message.d.ts +18 -0
  167. package/types/utils/src/user-facing-error.d.ts +83 -0
  168. package/js/chunk-7EK2JDX4.js +0 -299
  169. package/js/chunk-IKS2C5MQ.js +0 -224
  170. package/js/chunk-MKWZPDR6.js +0 -63
  171. package/js/chunk-N7YDVXYJ.js +0 -186
  172. package/js/chunk-NKLWZJLE.js +0 -172
  173. package/js/chunk-PJJ24GU7.js +0 -877
  174. package/js/chunk-PZB6T6KU.js +0 -19
  175. package/js/chunk-R3EV5FTO.js +0 -97
  176. package/js/chunk-SJFZCGXG.js +0 -1243
  177. package/js/chunk-WLE7WX2U.js +0 -2645
  178. package/js/chunk-YXQHV65J.js +0 -242
  179. package/js/chunk-ZQINWV4W.js +0 -630
  180. package/js/mcp/stdio.js +0 -128
  181. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  182. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  183. package/types/app-data/src/implementation/promise.d.ts +0 -68
  184. package/types/app-data/src/implementation/range.d.ts +0 -8
  185. package/types/app-data/src/implementation/schema.d.ts +0 -18
  186. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  187. package/types/app-data/src/index.d.ts +0 -4
  188. package/types/apps/src/contracts/storage.d.ts +0 -68
  189. package/types/apps/src/implementation/mcp-stdio.d.ts +0 -4
  190. package/types/apps/src/implementation/storage.d.ts +0 -15
  191. package/types/apps/src/mcp-stdio.d.ts +0 -5
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Failures as Executor's telemetry records them. Traces and error reports keep an error's text only
3
+ * when Executor wrote it: a tagged error is recorded by its tag and the fixed sentence it declares
4
+ * (see `RecordedMessage`), or by its tag alone when it declares none. Its fields, message, stack and
5
+ * cause are not recorded, so a value an error carries for its caller, an app's text or a service's
6
+ * reply cannot reach telemetry by an error forgetting to declare. The error itself, and what its
7
+ * caller receives, are unchanged.
8
+ */
9
+ import { Cause } from "effect";
10
+ /**
11
+ * The error a trace or error report records in place of `error`.
12
+ *
13
+ * - A tagged error is named by its tag: a field called `name`, such as a requested skill's or an
14
+ * app's, replaces the error's own name. Its message is the sentence it declares, or empty. Its
15
+ * stack is generated here and names no frames: the error's own stack begins with its message,
16
+ * which can span lines that look like frames. Traces still show where it failed through the
17
+ * operation's own spans, which Effect appends to a recorded stack.
18
+ * - Any other value that is not an `Error`, such as a plain object Effect would print as JSON, is
19
+ * recorded as `UnrecognizedFailure` with no text.
20
+ * - An untagged `Error` is a defect or a platform's error: its message and stack come from the
21
+ * JavaScript engine or a library and are kept, as they are the only diagnosis of an Executor bug.
22
+ * Its cause is recorded by these same rules.
23
+ */
24
+ export declare const recordedError: (error: unknown) => unknown;
25
+ /**
26
+ * A failure's cause as traces record it: each failure and defect by `recordedError`. Interruptions
27
+ * are unchanged, and each reason keeps its annotations, which locate it.
28
+ */
29
+ export declare const recordedCause: <E>(cause: Cause.Cause<E>) => Cause.Cause<unknown>;
@@ -2,11 +2,13 @@
2
2
  import { Effect, Schema } from "effect";
3
3
  /**
4
4
  * Forward app telemetry in the host scope without delaying an app result.
5
- * One export runs at a time, with at most sixteen pending batches. Overload and
6
- * shutdown loss are reported through the normal safe export-failure signal.
7
- * Scope release drains for the same three-second budget as the other exporters.
5
+ * Batches wait in one queue and a single sender exports everything waiting as one request per
6
+ * signal, so a burst of finished runs costs a few exports instead of one each. The queue holds at
7
+ * most eight MiB of payload and one export carries at most four. Overload and shutdown loss are
8
+ * reported through the normal safe export-failure signal. Scope release drains for the same
9
+ * three-second budget as the other exporters.
8
10
  */
9
- export declare const makeTelemetryForwarder: Effect.Effect<(batch: TelemetryBatch, traceId: string, build?: string) => Effect.Effect<void, never, never>, never, import("effect/Scope").Scope>;
11
+ export declare const makeTelemetryForwarder: Effect.Effect<(batch: TelemetryBatch, traceId: string, source: TelemetrySource) => Effect.Effect<void, never, never>, never, import("effect/Scope").Scope>;
10
12
  /** Untrusted isolate batches are bounded before decoding; no endpoint or credential crosses back. */
11
13
  export declare const TelemetryBatch: Schema.Struct<{
12
14
  readonly traces: Schema.$Array<Schema.String>;
@@ -23,6 +25,14 @@ export declare const collectTelemetry: <A, E, R>(effect: Effect.Effect<A, E, R>)
23
25
  logs: string[];
24
26
  dropped: number;
25
27
  };
26
- }, E, Exclude<Exclude<R, import("effect/unstable/observability/OtlpExporter").Flusher>, never>>;
28
+ }, E, Exclude<Exclude<R, import("effect/observability/OtlpExporter").Flusher>, never>>;
29
+ /**
30
+ * What the host knows about the records' source, from its own invocation rather than the records:
31
+ * the build that ran and, for an app isolate, the app's opaque ID. Both become resource attributes.
32
+ */
33
+ export interface TelemetrySource {
34
+ readonly build?: string | undefined;
35
+ readonly app?: string | undefined;
36
+ }
27
37
  /** Validate isolated records and export only this call's trace, using parent-owned credentials/identity. */
28
- export declare const forwardTelemetry: (batch: TelemetryBatch, traceId: string | undefined, build: string | undefined, service?: "executor-app" | "executor-web") => Effect.Effect<void, Schema.SchemaError | import("effect/unstable/http/HttpClientError").HttpClientError | import("effect/Cause").TimeoutError, never>;
38
+ export declare const forwardTelemetry: (batch: TelemetryBatch, traceId: string | undefined, source: TelemetrySource, service?: "executor-app" | "executor-web") => Effect.Effect<void, Schema.SchemaError | import("effect/http/HttpClientError").HttpClientError | import("effect/Cause").TimeoutError, never>;
@@ -18,11 +18,27 @@
18
18
  *
19
19
  * Attributes outside these namespaces are the product's own and pass through.
20
20
  */
21
- import { Layer } from "effect";
21
+ import { Effect, Layer } from "effect";
22
22
  /** Every HTTP attribute an exported span may carry. */
23
23
  export declare const httpSpanAttributeAllowlist: ReadonlySet<string>;
24
24
  /** Record this attribute? HTTP names must be allowlisted; product names pass through. */
25
25
  export declare const spanAttributeAllowed: (key: string) => boolean;
26
+ /**
27
+ * Record the template of a route whose path an app or its caller chose, in place of the router's
28
+ * wildcard: an app's own page or asset, or an app's outbound request. Its last parameter stands
29
+ * for the rest of the path. It annotates the current span, so call it from the request's handler.
30
+ */
31
+ export declare const recordRoute: (template: `/${string}`) => Effect.Effect<void, never, never>;
32
+ /**
33
+ * A fixed set of endpoint templates served under one wildcard route, such as Better Auth's
34
+ * endpoints under `/api/auth/*`. `:name` stands for one segment. `record` names the request's
35
+ * endpoint by its template and leaves the wildcard for any path the set does not hold, so a span
36
+ * keeps which endpoint ran without any segment the caller chose.
37
+ */
38
+ export declare const routeTemplates: (templates: Iterable<`/${string}`>) => {
39
+ match: (path: string) => `/${string}` | undefined;
40
+ record: (path: string) => Effect.Effect<void, never, never>;
41
+ };
26
42
  /** Wrap whichever tracer is already in scope; provide this above the exporter. */
27
43
  export declare const spanAttributes: (clock?: "system" | "cloudflare-io", recordAll?: boolean) => Layer.Layer<never>;
28
44
  /** Header and URL filtering without making an unsupported claim about the runtime clock. */
@@ -1,6 +1,13 @@
1
1
  import { Context, Layer } from "effect";
2
- import { HttpClient } from "effect/unstable/http";
2
+ import { HttpClient, HttpClientError } from "effect/http";
3
3
  /** Local collector discovery can resolve its destination when an export runs. */
4
4
  export declare const CurrentTelemetryClient: Context.Reference<HttpClient.HttpClient | undefined>;
5
5
  /** Telemetry consumers inspect status and headers; release response I/O inside each export scope. */
6
6
  export declare const telemetryHttpClient: Layer.Layer<HttpClient.HttpClient, never, never>;
7
+ /**
8
+ * Resend an export the collector refused for now, as OTLP requires and Effect's own
9
+ * exporters do: lost connections, 429 and 5xx overload, at most three more times. A
10
+ * collector shedding load answers 429 or 503 with Retry-After, which sets the wait. A
11
+ * wait longer than the caller's budget ends with the budget, without sending again.
12
+ */
13
+ export declare const retryTelemetryExport: (client: HttpClient.HttpClient) => HttpClient.HttpClient.With<HttpClientError.HttpClientError, never>;
@@ -0,0 +1,55 @@
1
+ import { Schema, type Cause } from "effect";
2
+ import "effect/http-api";
3
+ /**
4
+ * Encode the class's `message` getter as a required wire string. Decoding validates the field,
5
+ * then omits it, so the class derives its own message from the parsed payload and a supplied
6
+ * value never replaces it.
7
+ */
8
+ export declare const MessageField: Schema.decodeTo<Schema.optionalKey<Schema.String>, Schema.String, never, never>;
9
+ /** An expected API error whose response states its cause in a `message` derived from its fields. */
10
+ export interface ApiError extends Cause.YieldableError {
11
+ readonly _tag: string;
12
+ }
13
+ type Header<Tag extends string> = {
14
+ readonly tag: Tag;
15
+ readonly status: number;
16
+ };
17
+ type Definition<Tag extends string, Fields extends Schema.Struct.Fields> = Header<Tag> & {
18
+ readonly fields: Fields & {
19
+ readonly [Key in "_tag" | "message"]?: never;
20
+ };
21
+ /**
22
+ * The cause, stated for API and agent callers. It is also the error's `message`, which traces
23
+ * record, so it never includes credentials, upstream response text or submitted values.
24
+ */
25
+ readonly message: string | ((fields: Schema.Struct.Type<Fields>) => string);
26
+ /**
27
+ * What traces and error reports record beside the tag. A fixed `message` is recorded as is; a
28
+ * message derived from fields is recorded only through this, from fixed text and closed fields,
29
+ * never a value the caller chose, an app's text or a service's reply. Without it the error is
30
+ * recorded by its tag alone.
31
+ */
32
+ readonly recorded?: (fields: Schema.Struct.Type<Fields>) => string;
33
+ };
34
+ type ErrorFields<Tag extends string, Fields extends Schema.Struct.Fields> = Omit<Schema.TaggedStruct<Tag, Fields & {
35
+ readonly message: typeof MessageField;
36
+ }>, "~type.make.in"> & {
37
+ readonly "~type.make.in": Schema.TaggedStruct<Tag, Fields>["~type.make.in"];
38
+ };
39
+ type ErrorClass<Tag extends string, Fields extends Schema.Struct.Fields> = Schema.Class<Schema.Struct.Type<Fields> & ApiError & {
40
+ readonly _tag: Tag;
41
+ }, ErrorFields<Tag, Fields>, ApiError>;
42
+ /** Define an error with no payload and a fixed message. Its tag is its public error code. */
43
+ declare function define<const Tag extends string>(definition: Header<Tag> & {
44
+ readonly message: string;
45
+ }): ErrorClass<Tag, {}>;
46
+ /** Define an error whose message can depend on its parsed fields. */
47
+ declare function define<const Tag extends string, const Fields extends Schema.Struct.Fields>(definition: Definition<Tag, Fields>): ErrorClass<Tag, Fields>;
48
+ /**
49
+ * Define the schema, constructor and API message of an expected error together. Errors that need
50
+ * a user-facing title and recovery use `UserFacingError`, which carries the same message field.
51
+ */
52
+ export declare const ApiError: {
53
+ define: typeof define;
54
+ };
55
+ export {};
@@ -0,0 +1,33 @@
1
+ /** Requests the browser could not complete because no response reached it. */
2
+ import { Cause } from "effect";
3
+ import { HttpClientError } from "effect/http";
4
+ import { UserFacingError } from "./user-facing-error.js";
5
+ /**
6
+ * Fetch rejects with a `TypeError` when no response arrives: the device is offline, the page
7
+ * navigated away first, the connection was reset before a response, or the browser blocked the
8
+ * request. The server may still have completed the request and records its own outcome. Failures Executor constructs itself, such as a batch reply
9
+ * that ended without an answer, carry no such cause and stay unexpected.
10
+ */
11
+ export declare const isConnectionFailure: (error: unknown) => error is HttpClientError.HttpClientError;
12
+ /** Typed API clients may surface a lost connection as a failure or, after narrowing, a defect. */
13
+ export declare const hasConnectionFailure: (cause: Cause.Cause<unknown>) => boolean;
14
+ /** The browser could not reach Executor. Nothing on the server needs fixing. */
15
+ export declare const ConnectionFailed: import("effect/Schema").Class<{} & UserFacingError & {
16
+ readonly _tag: "ConnectionFailed";
17
+ }, Omit<import("effect/Schema").TaggedStruct<"ConnectionFailed", {
18
+ readonly message: typeof import("./api-error.js").MessageField;
19
+ readonly recovery: import("effect/Schema").decodeTo<import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
20
+ readonly action: import("effect/Schema").String;
21
+ readonly instructions: import("effect/Schema").String;
22
+ }>>, import("effect/Schema").Struct<{
23
+ readonly action: import("effect/Schema").String;
24
+ readonly instructions: import("effect/Schema").String;
25
+ }>, never, never>;
26
+ }>, "~type.make.in"> & {
27
+ readonly "~type.make.in": {
28
+ readonly _tag?: "ConnectionFailed";
29
+ };
30
+ }, UserFacingError>;
31
+ export type ConnectionFailed = typeof ConnectionFailed.Type;
32
+ /** What to show for a failure no contract declares: a lost connection, or an unexpected error. */
33
+ export declare const undeclaredError: (cause: Cause.Cause<unknown>) => UserFacingError;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The fixed sentence traces and error reports record for a tagged error, beside its tag. Telemetry
3
+ * records no other text from a tagged error: one that declares no sentence is recorded by its tag
4
+ * alone (`@executor-js/telemetry/recorded-failure`). Declare one from fixed text and closed fields
5
+ * only, never from a value the caller supplied (a slug, a name, a tool name, an argument's key),
6
+ * an app's own text or a service's reply. That text still reaches the caller the error is for.
7
+ * `ApiError` and `UserFacingError` declare a fixed message for you; a message derived from fields
8
+ * declares `recorded`.
9
+ */
10
+ export declare const RecordedMessage: unique symbol;
11
+ /** The fixed sentence an error declares for telemetry, if it declares one. */
12
+ export declare const recordedMessage: (error: unknown) => string | undefined;
13
+ /**
14
+ * Declare a recorded message on one error that Executor did not define the text of, such as an
15
+ * error decoded from an app's reply. An error class's own declaration is kept. The error's fields
16
+ * and wire encoding are unchanged.
17
+ */
18
+ export declare const recordAs: <E>(error: E, message: string) => E;
@@ -0,0 +1,83 @@
1
+ import { Schema, type Cause } from "effect";
2
+ import "effect/http-api";
3
+ import { MessageField } from "./api-error.js";
4
+ /** Curated explanation and recovery. Never include raw diagnostics, credentials, or form values. */
5
+ export interface ErrorPresentation {
6
+ readonly title: string;
7
+ readonly description: string;
8
+ readonly recovery: {
9
+ readonly action: string;
10
+ readonly instructions: string;
11
+ };
12
+ /** Repeating the failed operation can help. Configuration changes are not retries. */
13
+ readonly retryable?: boolean;
14
+ /** False when the user's agent cannot act on the fix prompt, so hosts do not offer it. */
15
+ readonly agentFixable?: boolean;
16
+ /** One safe value the user needs for recovery, such as a URL to send to the service. */
17
+ readonly detail?: {
18
+ readonly label: string;
19
+ readonly value: string;
20
+ };
21
+ /**
22
+ * Present only when the Executor team must fix the problem. Safe evidence for a public
23
+ * report: fixed codes and statuses, never user data, URLs, or upstream text.
24
+ */
25
+ readonly report?: string;
26
+ }
27
+ type PresentationProperties = Required<Omit<ErrorPresentation, "detail" | "report">> & {
28
+ readonly detail: ErrorPresentation["detail"];
29
+ readonly report: ErrorPresentation["report"];
30
+ readonly code: string;
31
+ readonly fixPrompt: string;
32
+ };
33
+ /** A yieldable error that owns its safe user explanation and agent recovery task. */
34
+ export interface UserFacingError extends Cause.YieldableError, PresentationProperties {
35
+ readonly _tag: string;
36
+ }
37
+ type Header<Tag extends string> = {
38
+ readonly tag: Tag;
39
+ readonly status: number;
40
+ };
41
+ type Definition<Tag extends string, Fields extends Schema.Struct.Fields> = Header<Tag> & {
42
+ readonly fields: Fields & {
43
+ readonly [Key in keyof PresentationProperties | "_tag" | "message"]?: never;
44
+ };
45
+ /**
46
+ * What traces and error reports record beside the tag. A fixed description is recorded as is; a
47
+ * presentation derived from fields is recorded only through this, from fixed text and closed
48
+ * fields, never a value the caller chose, an app's text or a service's reply. Without it the
49
+ * error is recorded by its tag alone.
50
+ */
51
+ readonly recorded?: (fields: Schema.Struct.Type<Fields>) => string;
52
+ } & (ErrorPresentation | {
53
+ readonly presentation: (fields: Schema.Struct.Type<Fields>) => ErrorPresentation;
54
+ });
55
+ declare const RecoveryField: Schema.decodeTo<Schema.optionalKey<Schema.Struct<{
56
+ readonly action: Schema.String;
57
+ readonly instructions: Schema.String;
58
+ }>>, Schema.Struct<{
59
+ readonly action: Schema.String;
60
+ readonly instructions: Schema.String;
61
+ }>, never, never>;
62
+ type DerivedFields = {
63
+ readonly message: typeof MessageField;
64
+ readonly recovery: typeof RecoveryField;
65
+ };
66
+ type ErrorFields<Tag extends string, Fields extends Schema.Struct.Fields> = Omit<Schema.TaggedStruct<Tag, Fields & DerivedFields>, "~type.make.in"> & {
67
+ readonly "~type.make.in": Schema.TaggedStruct<Tag, Fields>["~type.make.in"];
68
+ };
69
+ type ErrorClass<Tag extends string, Fields extends Schema.Struct.Fields> = Schema.Class<Schema.Struct.Type<Fields> & UserFacingError & {
70
+ readonly _tag: Tag;
71
+ }, ErrorFields<Tag, Fields>, UserFacingError>;
72
+ /** Define a schema-backed error with no payload. Its tag becomes its public error code. */
73
+ declare function define<const Tag extends string>(definition: Header<Tag> & ErrorPresentation): ErrorClass<Tag, {}>;
74
+ /** Define a schema-backed error whose safe presentation can depend on its parsed fields. */
75
+ declare function define<const Tag extends string, const Fields extends Schema.Struct.Fields>(definition: Definition<Tag, Fields>): ErrorClass<Tag, Fields>;
76
+ /** Define the schema, error constructor, user copy, and agent recovery together. */
77
+ export declare const UserFacingError: {
78
+ define: typeof define;
79
+ is: (value: unknown) => value is UserFacingError;
80
+ };
81
+ /** Defects get a safe explanation without exposing an arbitrary cause. */
82
+ export declare const UnexpectedError: ErrorClass<"UnexpectedError", {}>;
83
+ export {};
@@ -1,299 +0,0 @@
1
- import {
2
- prepareElicitation
3
- } from "./chunk-SJFZCGXG.js";
4
- import {
5
- fromPromise
6
- } from "./chunk-Z5M2LQOZ.js";
7
- import {
8
- ElicitationFailed,
9
- McpError,
10
- McpServerHeader,
11
- McpToolMetadata,
12
- McpToolResult,
13
- RouterIcon,
14
- ToolResultObservation,
15
- defaultElicitationLimits,
16
- defaultMcpClientLimits,
17
- mcpSdkTimerCeilingMs
18
- } from "./chunk-WLE7WX2U.js";
19
- import {
20
- compileJsonSchemaDecoder,
21
- jsonSchemaDecoder
22
- } from "./chunk-5T57N25Q.js";
23
- import {
24
- JsonObject
25
- } from "./chunk-27F7W2LG.js";
26
- import {
27
- Clock_exports,
28
- Deferred_exports,
29
- Effect_exports,
30
- Exit_exports,
31
- Option_exports,
32
- Queue_exports,
33
- Schema_exports
34
- } from "./chunk-CDL5PM2Q.js";
35
-
36
- // src/implementation/mcp-tools.ts
37
- var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
38
- const decoder = yield* jsonSchemaDecoder(tool.inputSchema).pipe(
39
- Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
40
- );
41
- const output = tool.outputSchema === void 0 ? void 0 : yield* Effect_exports.cached(
42
- compileJsonSchemaDecoder(tool.outputSchema).pipe(
43
- Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
44
- )
45
- );
46
- const adapted = {
47
- ...tool,
48
- description: tool.description ?? tool.title ?? tool.name,
49
- input: decoder,
50
- ...tool.annotations?.readOnlyHint === void 0 ? {} : { readOnly: tool.annotations.readOnlyHint },
51
- run: (context, input) => Effect_exports.gen(function* () {
52
- const arguments_ = yield* Schema_exports.decodeUnknownEffect(decoder)(input).pipe(
53
- Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonObject)),
54
- Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_input" }))
55
- );
56
- const outputDecoder = output === void 0 ? void 0 : yield* output;
57
- const result = yield* client.call(tool.name, arguments_, context);
58
- if (result.isError === true) {
59
- (yield* ToolResultObservation).failed();
60
- yield* Effect_exports.annotateCurrentSpan({
61
- "executor.outcome": "failed",
62
- "error.type": "McpToolError"
63
- });
64
- }
65
- if (outputDecoder !== void 0 && !result.isError)
66
- yield* Schema_exports.decodeUnknownEffect(outputDecoder)(result.structuredContent).pipe(
67
- Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_response" }))
68
- );
69
- return result;
70
- })
71
- };
72
- return adapted;
73
- });
74
- var adaptMcpTools = (client) => Effect_exports.gen(function* () {
75
- const { tools: metadata } = yield* client.list;
76
- const entries = yield* Effect_exports.forEach(
77
- metadata,
78
- (tool) => adaptMcpTool(client, tool).pipe(Effect_exports.map((adapted) => [tool.name, adapted]))
79
- );
80
- return Object.fromEntries(entries);
81
- });
82
-
83
- // src/implementation/mcp-client.ts
84
- import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
85
-
86
- // src/implementation/mcp-call.ts
87
- import {
88
- ElicitRequestSchema,
89
- ElicitResultSchema,
90
- ErrorCode,
91
- McpError as ProtocolError
92
- } from "@modelcontextprotocol/sdk/types.js";
93
- function callBudget(timeoutMs) {
94
- return Effect_exports.gen(function* () {
95
- const clock = yield* Clock_exports.Clock;
96
- const changes = yield* Queue_exports.unbounded();
97
- let remaining = timeoutMs, updated = clock.currentTimeMillisUnsafe(), waiting = 0;
98
- const account = () => {
99
- const now = clock.currentTimeMillisUnsafe();
100
- if (waiting === 0) remaining -= Math.max(0, now - updated);
101
- updated = now;
102
- return remaining;
103
- };
104
- return {
105
- waitForInput: (input) => Effect_exports.acquireUseRelease(
106
- Effect_exports.sync(() => {
107
- account();
108
- waiting++;
109
- }).pipe(Effect_exports.andThen(Queue_exports.offer(changes, void 0))),
110
- () => input,
111
- () => Effect_exports.sync(() => {
112
- account();
113
- waiting--;
114
- }).pipe(Effect_exports.andThen(Queue_exports.offer(changes, void 0)))
115
- ),
116
- expired: Effect_exports.gen(function* () {
117
- while (true) {
118
- const left = account();
119
- if (waiting === 0 && left <= 0)
120
- return yield* new McpError({ phase: "call", reason: "timeout" });
121
- if (waiting > 0) yield* Queue_exports.take(changes);
122
- else yield* Queue_exports.take(changes).pipe(Effect_exports.raceFirst(Effect_exports.sleep(Math.max(1, left))));
123
- }
124
- })
125
- };
126
- });
127
- }
128
- var mcpCall = (client, name, input, context, timeoutMs, failure) => Effect_exports.scoped(
129
- Effect_exports.gen(function* () {
130
- const budget = yield* callBudget(timeoutMs);
131
- const failed = yield* Deferred_exports.make();
132
- const runtime = yield* Effect_exports.context();
133
- const callbacks = /* @__PURE__ */ new Set();
134
- const lifetime = yield* Effect_exports.acquireRelease(
135
- Effect_exports.sync(() => new AbortController()),
136
- (controller) => Effect_exports.promise(async () => {
137
- controller.abort();
138
- client.removeRequestHandler("elicitation/create");
139
- await Promise.allSettled(callbacks);
140
- })
141
- );
142
- client.setRequestHandler(ElicitRequestSchema, (request, extra) => {
143
- const signal = AbortSignal.any([lifetime.signal, extra.signal]);
144
- const interaction = Effect_exports.gen(function* () {
145
- const form = yield* prepareElicitation({
146
- ...request.params,
147
- mode: request.params.mode ?? "form"
148
- });
149
- const deliver = context.elicit;
150
- if (deliver === void 0) return yield* new ElicitationFailed({ reason: "unavailable" });
151
- const answer = yield* budget.waitForInput(
152
- fromPromise(deliver)(form.request).pipe(
153
- Effect_exports.mapError(
154
- (error) => Option_exports.getOrElse(
155
- Schema_exports.decodeUnknownOption(ElicitationFailed)(error),
156
- () => new ElicitationFailed({ reason: "transport" })
157
- )
158
- ),
159
- Effect_exports.timeoutOrElse({
160
- duration: defaultElicitationLimits.timeoutMs,
161
- orElse: () => Effect_exports.fail(new ElicitationFailed({ reason: "expired" }))
162
- })
163
- )
164
- ).pipe(Effect_exports.withSpan("provider.mcp.elicitation"));
165
- return yield* form.respond(answer).pipe(
166
- Effect_exports.flatMap(
167
- (response) => Effect_exports.try({
168
- try: () => ElicitResultSchema.parse(response),
169
- catch: () => new ElicitationFailed({ reason: "invalid-response" })
170
- })
171
- )
172
- );
173
- }).pipe(Effect_exports.tapError((error) => Deferred_exports.fail(failed, error)));
174
- const callback = Effect_exports.runPromiseWith(runtime)(interaction, { signal }).catch(() => {
175
- if (!lifetime.signal.aborted)
176
- Effect_exports.runSync(Deferred_exports.fail(failed, new ElicitationFailed({ reason: "transport" })));
177
- throw new ProtocolError(ErrorCode.InternalError, "User input could not be delivered");
178
- });
179
- callbacks.add(callback);
180
- return callback.finally(() => callbacks.delete(callback));
181
- });
182
- return yield* Effect_exports.tryPromise({
183
- try: (signal) => client.callTool({ name, arguments: input }, void 0, {
184
- signal: AbortSignal.any([signal, lifetime.signal]),
185
- timeout: mcpSdkTimerCeilingMs
186
- }),
187
- catch: (error) => failure("call", error)
188
- }).pipe(
189
- Effect_exports.raceFirst(Deferred_exports.await(failed)),
190
- Effect_exports.raceFirst(budget.expired),
191
- Effect_exports.flatMap(
192
- (result) => Schema_exports.decodeUnknownEffect(McpToolResult)(result).pipe(
193
- Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_response" }))
194
- )
195
- ),
196
- Effect_exports.tap(
197
- (result) => Effect_exports.annotateCurrentSpan("mcp.tool.is_error", result.isError === true)
198
- )
199
- );
200
- })
201
- ).pipe(
202
- Effect_exports.withSpan("provider.mcp.request", {
203
- kind: "client",
204
- attributes: {
205
- "rpc.system.name": "jsonrpc",
206
- "rpc.method": "tools/call",
207
- "mcp.tool.name": name
208
- }
209
- })
210
- );
211
-
212
- // src/implementation/mcp-client.ts
213
- var mcpJsonSchemaValidator = {
214
- getValidator(document) {
215
- const decoder = Effect_exports.runSync(jsonSchemaDecoder(document));
216
- return (input) => {
217
- const result = Effect_exports.runSyncExit(Schema_exports.decodeUnknownEffect(decoder)(input));
218
- if (Exit_exports.isFailure(result))
219
- return {
220
- valid: false,
221
- data: void 0,
222
- errorMessage: "Value does not match the supported JSON Schema"
223
- };
224
- return { valid: true, data: result.value, errorMessage: void 0 };
225
- };
226
- }
227
- };
228
- function mcpClient(withClient, timeoutMs, failure) {
229
- const list = withClient(
230
- "discover",
231
- (client) => Effect_exports.gen(function* () {
232
- const tools = /* @__PURE__ */ new Map();
233
- const cursors = /* @__PURE__ */ new Set();
234
- let cursor;
235
- do {
236
- const page = yield* Effect_exports.tryPromise({
237
- // This session only reads metadata. listTools() also eagerly compiles
238
- // every output validator; mcpRouter validates the selected tool on call.
239
- try: (signal) => client.request(
240
- { method: "tools/list", params: cursor === void 0 ? {} : { cursor } },
241
- ListToolsResultSchema,
242
- { signal, timeout: timeoutMs }
243
- ),
244
- catch: (error) => failure("discover", error)
245
- }).pipe(
246
- Effect_exports.withSpan("provider.mcp.request", {
247
- kind: "client",
248
- attributes: { "rpc.system.name": "jsonrpc", "rpc.method": "tools/list" }
249
- })
250
- );
251
- const metadata = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(McpToolMetadata))(
252
- page.tools
253
- ).pipe(
254
- Effect_exports.mapError(() => new McpError({ phase: "discover", reason: "invalid_response" }))
255
- );
256
- for (const tool of metadata) {
257
- if (!tool.name || tools.has(tool.name) || tools.size >= defaultMcpClientLimits.maxTools)
258
- return yield* new McpError({ phase: "discover", reason: "invalid_response" });
259
- tools.set(tool.name, tool);
260
- }
261
- cursor = page.nextCursor;
262
- if (cursor !== void 0) {
263
- if (cursors.has(cursor) || cursors.size >= defaultMcpClientLimits.maxPaginationCursors)
264
- return yield* new McpError({ phase: "discover", reason: "invalid_response" });
265
- cursors.add(cursor);
266
- }
267
- } while (cursor !== void 0);
268
- const info = client.getServerVersion();
269
- const instructions = client.getInstructions();
270
- const icons = info?.icons?.flatMap(
271
- (icon) => Option_exports.toArray(Schema_exports.decodeUnknownOption(RouterIcon)(icon))
272
- );
273
- const server = Schema_exports.decodeUnknownOption(McpServerHeader)({
274
- ...info?.name === void 0 ? {} : { name: info.name },
275
- ...info?.title === void 0 ? {} : { title: info.title },
276
- ...info?.version === void 0 ? {} : { version: info.version },
277
- ...info?.description === void 0 ? {} : { description: info.description },
278
- ...info?.websiteUrl === void 0 ? {} : { websiteUrl: info.websiteUrl },
279
- ...icons === void 0 ? {} : { icons },
280
- ...instructions === void 0 ? {} : { instructions }
281
- });
282
- return {
283
- tools: [...tools.values()],
284
- server: Option_exports.getOrElse(server, () => ({}))
285
- };
286
- })
287
- ).pipe(Effect_exports.withSpan("provider.mcp.discover"));
288
- const call = (name, input, context) => withClient("call", (client) => mcpCall(client, name, input, context, timeoutMs, failure)).pipe(
289
- Effect_exports.withSpan("provider.mcp.call", { attributes: { "mcp.tool.name": name } })
290
- );
291
- return { list, call };
292
- }
293
-
294
- export {
295
- adaptMcpTool,
296
- adaptMcpTools,
297
- mcpJsonSchemaValidator,
298
- mcpClient
299
- };