effect-assistant 0.0.0-stage → 0.1.0

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 (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -2
  3. package/dist/AppEvent.d.ts +111 -0
  4. package/dist/AppEvent.d.ts.map +1 -0
  5. package/dist/AppEvent.js +71 -0
  6. package/dist/AppEvent.js.map +1 -0
  7. package/dist/Assistant.d.ts +403 -0
  8. package/dist/Assistant.d.ts.map +1 -0
  9. package/dist/Assistant.js +126 -0
  10. package/dist/Assistant.js.map +1 -0
  11. package/dist/AssistantActivity.d.ts +85 -0
  12. package/dist/AssistantActivity.d.ts.map +1 -0
  13. package/dist/AssistantActivity.js +105 -0
  14. package/dist/AssistantActivity.js.map +1 -0
  15. package/dist/AssistantEngine.d.ts +116 -0
  16. package/dist/AssistantEngine.d.ts.map +1 -0
  17. package/dist/AssistantEngine.js +255 -0
  18. package/dist/AssistantEngine.js.map +1 -0
  19. package/dist/AssistantEvent.d.ts +614 -0
  20. package/dist/AssistantEvent.d.ts.map +1 -0
  21. package/dist/AssistantEvent.js +523 -0
  22. package/dist/AssistantEvent.js.map +1 -0
  23. package/dist/AssistantLoop.d.ts +171 -0
  24. package/dist/AssistantLoop.d.ts.map +1 -0
  25. package/dist/AssistantLoop.js +108 -0
  26. package/dist/AssistantLoop.js.map +1 -0
  27. package/dist/AssistantToolCall.d.ts +32 -0
  28. package/dist/AssistantToolCall.d.ts.map +1 -0
  29. package/dist/AssistantToolCall.js +37 -0
  30. package/dist/AssistantToolCall.js.map +1 -0
  31. package/dist/Block.d.ts +69 -0
  32. package/dist/Block.d.ts.map +1 -0
  33. package/dist/Block.js +39 -0
  34. package/dist/Block.js.map +1 -0
  35. package/dist/BlockKit.d.ts +184 -0
  36. package/dist/BlockKit.d.ts.map +1 -0
  37. package/dist/BlockKit.js +151 -0
  38. package/dist/BlockKit.js.map +1 -0
  39. package/dist/ChatId.d.ts +31 -0
  40. package/dist/ChatId.d.ts.map +1 -0
  41. package/dist/ChatId.js +36 -0
  42. package/dist/ChatId.js.map +1 -0
  43. package/dist/ChatLog.d.ts +109 -0
  44. package/dist/ChatLog.d.ts.map +1 -0
  45. package/dist/ChatLog.js +177 -0
  46. package/dist/ChatLog.js.map +1 -0
  47. package/dist/ChatView.d.ts +459 -0
  48. package/dist/ChatView.d.ts.map +1 -0
  49. package/dist/ChatView.js +496 -0
  50. package/dist/ChatView.js.map +1 -0
  51. package/dist/Chats.d.ts +110 -0
  52. package/dist/Chats.d.ts.map +1 -0
  53. package/dist/Chats.js +98 -0
  54. package/dist/Chats.js.map +1 -0
  55. package/dist/Compaction.d.ts +105 -0
  56. package/dist/Compaction.d.ts.map +1 -0
  57. package/dist/Compaction.js +133 -0
  58. package/dist/Compaction.js.map +1 -0
  59. package/dist/CurrentChat.d.ts +40 -0
  60. package/dist/CurrentChat.d.ts.map +1 -0
  61. package/dist/CurrentChat.js +33 -0
  62. package/dist/CurrentChat.js.map +1 -0
  63. package/dist/Decision.d.ts +145 -0
  64. package/dist/Decision.d.ts.map +1 -0
  65. package/dist/Decision.js +178 -0
  66. package/dist/Decision.js.map +1 -0
  67. package/dist/DecisionId.d.ts +37 -0
  68. package/dist/DecisionId.d.ts.map +1 -0
  69. package/dist/DecisionId.js +44 -0
  70. package/dist/DecisionId.js.map +1 -0
  71. package/dist/InputId.d.ts +38 -0
  72. package/dist/InputId.d.ts.map +1 -0
  73. package/dist/InputId.js +43 -0
  74. package/dist/InputId.js.map +1 -0
  75. package/dist/Instructions.d.ts +56 -0
  76. package/dist/Instructions.d.ts.map +1 -0
  77. package/dist/Instructions.js +50 -0
  78. package/dist/Instructions.js.map +1 -0
  79. package/dist/Memory.d.ts +190 -0
  80. package/dist/Memory.d.ts.map +1 -0
  81. package/dist/Memory.js +216 -0
  82. package/dist/Memory.js.map +1 -0
  83. package/dist/RunId.d.ts +41 -0
  84. package/dist/RunId.d.ts.map +1 -0
  85. package/dist/RunId.js +46 -0
  86. package/dist/RunId.js.map +1 -0
  87. package/dist/Skill.d.ts +72 -0
  88. package/dist/Skill.d.ts.map +1 -0
  89. package/dist/Skill.js +58 -0
  90. package/dist/Skill.js.map +1 -0
  91. package/dist/Specialist.d.ts +267 -0
  92. package/dist/Specialist.d.ts.map +1 -0
  93. package/dist/Specialist.js +119 -0
  94. package/dist/Specialist.js.map +1 -0
  95. package/dist/ToolDiscovery.d.ts +108 -0
  96. package/dist/ToolDiscovery.d.ts.map +1 -0
  97. package/dist/ToolDiscovery.js +139 -0
  98. package/dist/ToolDiscovery.js.map +1 -0
  99. package/dist/ToolFailure.d.ts +66 -0
  100. package/dist/ToolFailure.d.ts.map +1 -0
  101. package/dist/ToolFailure.js +79 -0
  102. package/dist/ToolFailure.js.map +1 -0
  103. package/dist/_virtual/_rolldown/runtime.js +13 -0
  104. package/dist/index.d.ts +26 -0
  105. package/dist/index.js +26 -0
  106. package/dist/internal/chat.js +202 -0
  107. package/dist/internal/chat.js.map +1 -0
  108. package/dist/internal/decisions.js +66 -0
  109. package/dist/internal/decisions.js.map +1 -0
  110. package/dist/internal/events.d.ts +46 -0
  111. package/dist/internal/events.d.ts.map +1 -0
  112. package/dist/internal/events.js +65 -0
  113. package/dist/internal/events.js.map +1 -0
  114. package/dist/internal/history.js +185 -0
  115. package/dist/internal/history.js.map +1 -0
  116. package/dist/internal/instructions.js +11 -0
  117. package/dist/internal/instructions.js.map +1 -0
  118. package/dist/internal/loop.d.ts +73 -0
  119. package/dist/internal/loop.d.ts.map +1 -0
  120. package/dist/internal/loop.js +166 -0
  121. package/dist/internal/loop.js.map +1 -0
  122. package/dist/internal/schema.js +14 -0
  123. package/dist/internal/schema.js.map +1 -0
  124. package/dist/internal/skills.js +28 -0
  125. package/dist/internal/skills.js.map +1 -0
  126. package/dist/internal/specialists.js +273 -0
  127. package/dist/internal/specialists.js.map +1 -0
  128. package/dist/internal/telemetry.js +85 -0
  129. package/dist/internal/telemetry.js.map +1 -0
  130. package/dist/internal/toolkit.d.ts +76 -0
  131. package/dist/internal/toolkit.d.ts.map +1 -0
  132. package/dist/internal/toolkit.js +129 -0
  133. package/dist/internal/toolkit.js.map +1 -0
  134. package/dist/internal/tools.js +132 -0
  135. package/dist/internal/tools.js.map +1 -0
  136. package/dist/internal/turns.d.ts +64 -0
  137. package/dist/internal/turns.d.ts.map +1 -0
  138. package/dist/internal/turns.js +221 -0
  139. package/dist/internal/turns.js.map +1 -0
  140. package/dist/internal/uuid.js +45 -0
  141. package/dist/internal/uuid.js.map +1 -0
  142. package/dist/internal/writer.d.ts +12 -0
  143. package/dist/internal/writer.d.ts.map +1 -0
  144. package/package.json +51 -3
  145. package/src/AppEvent.ts +134 -0
  146. package/src/Assistant.ts +589 -0
  147. package/src/AssistantActivity.ts +150 -0
  148. package/src/AssistantEngine.ts +343 -0
  149. package/src/AssistantEvent.ts +635 -0
  150. package/src/AssistantLoop.ts +207 -0
  151. package/src/AssistantToolCall.ts +40 -0
  152. package/src/Block.ts +84 -0
  153. package/src/BlockKit.ts +311 -0
  154. package/src/ChatId.ts +36 -0
  155. package/src/ChatLog.ts +247 -0
  156. package/src/ChatView.ts +658 -0
  157. package/src/Chats.ts +122 -0
  158. package/src/Compaction.ts +224 -0
  159. package/src/CurrentChat.ts +47 -0
  160. package/src/Decision.ts +241 -0
  161. package/src/DecisionId.ts +46 -0
  162. package/src/InputId.ts +43 -0
  163. package/src/Instructions.ts +72 -0
  164. package/src/Memory.ts +276 -0
  165. package/src/RunId.ts +46 -0
  166. package/src/Skill.ts +91 -0
  167. package/src/Specialist.ts +355 -0
  168. package/src/ToolDiscovery.ts +187 -0
  169. package/src/ToolFailure.ts +74 -0
  170. package/src/index.ts +130 -0
  171. package/src/internal/chat.ts +372 -0
  172. package/src/internal/decisions.ts +131 -0
  173. package/src/internal/events.ts +100 -0
  174. package/src/internal/history.ts +366 -0
  175. package/src/internal/instructions.ts +9 -0
  176. package/src/internal/loop.ts +344 -0
  177. package/src/internal/schema.ts +25 -0
  178. package/src/internal/skills.ts +37 -0
  179. package/src/internal/specialists.ts +414 -0
  180. package/src/internal/telemetry.ts +125 -0
  181. package/src/internal/toolkit.ts +231 -0
  182. package/src/internal/tools.ts +210 -0
  183. package/src/internal/turns.ts +429 -0
  184. package/src/internal/uuid.ts +50 -0
  185. package/src/internal/writer.ts +12 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 David
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,23 @@
1
- # Temporary Holding Version
1
+ # effect-assistant
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A chat assistant on [Effect](https://effect.website) that behaves like a
4
+ colleague. It keeps an append-only event log per chat, runs an
5
+ interruptible agent loop over it, and talks to the user only through a
6
+ `send_user_message` tool. It also supports specialists, skills, UI blocks,
7
+ decisions, memory, and compaction. It runs in memory or as one Effect
8
+ Cluster entity per chat.
9
+
10
+ ```bash
11
+ pnpm add effect-assistant effect@^4.0.0 @effect/ai-anthropic@^4.0.0
12
+ ```
13
+
14
+ The [README on GitHub](https://github.com/dbrxnds/effect-assistant#readme)
15
+ has the simplest setup and the more extensive ones. The
16
+ [docs](https://github.com/dbrxnds/effect-assistant/tree/main/apps/docs) have
17
+ a guide per topic and the API reference.
18
+
19
+ ```bash
20
+ pnpm --filter effect-assistant test # the mechanics, on a scripted model
21
+ pnpm --filter effect-assistant test:contract # against a real model (ANTHROPIC_API_KEY in .env.local)
22
+ pnpm --filter effect-assistant build # dist, with declarations and source maps
23
+ ```
@@ -0,0 +1,111 @@
1
+ import * as SchemaAST from "effect/SchemaAST";
2
+ import * as Schema from "effect/Schema";
3
+ declare namespace AppEvent_d_exports {
4
+ export { Any, AppEvent, EventSchema, Render, Type, make };
5
+ }
6
+ /**
7
+ * Schema for one of the application's own events.
8
+ *
9
+ * It is a tagged struct or class (`Schema.TaggedStruct`, `Schema.TaggedClass`) that needs no
10
+ * services.
11
+ *
12
+ * @category models
13
+ * @since 0.1.0
14
+ */
15
+ export type EventSchema = Schema.Codec<{
16
+ readonly _tag: string;
17
+ }, {
18
+ readonly _tag: string;
19
+ }> & {
20
+ readonly fields: {
21
+ readonly _tag: {
22
+ readonly ast: SchemaAST.AST;
23
+ };
24
+ };
25
+ };
26
+ /**
27
+ * Describes how the model reads an event.
28
+ *
29
+ * `"json"` shows the event's tag and fields as JSON. A function shows the text it returns for the
30
+ * event.
31
+ *
32
+ * @category models
33
+ * @since 0.1.0
34
+ */
35
+ export type Render<A> = "json" | ((event: A) => string);
36
+ /**
37
+ * Represents one of the application's events, registered with an assistant.
38
+ *
39
+ * It holds the event's schema and tag, whether storing it wakes a turn, and how the model reads
40
+ * it. A `render` of `undefined` means the model doesn't read it.
41
+ *
42
+ * @category models
43
+ * @since 0.1.0
44
+ */
45
+ export interface AppEvent<S extends EventSchema = EventSchema> {
46
+ readonly schema: S;
47
+ readonly tag: string;
48
+ readonly wakes: boolean;
49
+ readonly render: Render<S["Type"]> | undefined;
50
+ }
51
+ /**
52
+ * Represents any registered event, for generic constraints.
53
+ *
54
+ * @category utility types
55
+ * @since 0.1.0
56
+ */
57
+ export type Any = AppEvent<any>;
58
+ /**
59
+ * Extracts the type of a registered event's values.
60
+ *
61
+ * @category utility types
62
+ * @since 0.1.0
63
+ */
64
+ export type Type<E extends Any> = E["schema"]["Type"];
65
+ /**
66
+ * Registers one of the application's events with an assistant.
67
+ *
68
+ * **Details**
69
+ *
70
+ * Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`
71
+ * defaults to `"json"` for an event that wakes a turn. An event that doesn't wake a turn and has
72
+ * no `render` isn't read by the model.
73
+ *
74
+ * The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws
75
+ * otherwise.
76
+ *
77
+ * **Example** (Registering an event that wakes a turn)
78
+ *
79
+ * ```ts
80
+ * import { AppEvent, Assistant, InputId } from "effect-assistant"
81
+ * import * as Schema from "effect/Schema"
82
+ *
83
+ * class OrderShipped extends Schema.TaggedClass<OrderShipped>()("OrderShipped", {
84
+ * id: InputId.InputId,
85
+ * orderId: Schema.String,
86
+ * carrier: Schema.String
87
+ * }) {}
88
+ *
89
+ * export const MyAssistant = Assistant.make("my-assistant", {
90
+ * events: [
91
+ * AppEvent.make(OrderShipped, {
92
+ * wakes: true,
93
+ * render: (shipped) =>
94
+ * `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`
95
+ * })
96
+ * ]
97
+ * })
98
+ * ```
99
+ *
100
+ * @category constructors
101
+ * @since 0.1.0
102
+ */
103
+ export declare const make: <S extends EventSchema>(schema: S, options?: {
104
+ /** Whether storing it starts a turn, like a user's message. Default false. */
105
+ readonly wakes?: boolean | undefined;
106
+ /** How the model reads it in its history. */
107
+ readonly render?: Render<S["Type"]> | undefined;
108
+ }) => AppEvent<S>;
109
+ //#endregion
110
+ export { AppEvent_d_exports };
111
+ //# sourceMappingURL=AppEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppEvent.d.ts","names":[],"sources":["../src/AppEvent.ts"],"mappings":";;;;;;;;;;;;;;YAuBY,cAAc,OAAO;WAAiB;;WAA2B;;WAClE;aAAmB;eAAiB,KAAK,UAAU;;;;;;;;;;;;;YAYlD,OAAO,gBAAgB,OAAO;;;;;;;;;;iBAWzB,SAAS,UAAU,cAAc;WACvC,QAAQ;WACR;WACA;WACA,QAAQ,OAAO;;;;;;;;YASd,MAAM;;;;;;;YAQN,KAAK,UAAU,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgDrB,OAAQ,UAAU,aAAW,QAChC,GAAC;;WAGE;;WAEA,SAAS,OAAO;MAE1B,SAAS"}
@@ -0,0 +1,71 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import * as Predicate from "effect/Predicate";
3
+ import * as SchemaAST from "effect/SchemaAST";
4
+ //#region src/AppEvent.ts
5
+ /**
6
+ * Registers an application's own events with an assistant.
7
+ *
8
+ * An app event is a tagged schema for something the application reports into a chat, such as a
9
+ * workflow's progress, a webhook, a summary for compaction, or the draft the user opened.
10
+ * {@link make} registers one with two choices: whether storing it wakes a turn (`wakes`), and
11
+ * how the model reads it (`render`).
12
+ *
13
+ * @since 0.1.0
14
+ */
15
+ var AppEvent_exports = /* @__PURE__ */ __exportAll({ make: () => make });
16
+ const tagOf = (schema) => {
17
+ const ast = schema.fields._tag.ast;
18
+ if (SchemaAST.isLiteral(ast) && Predicate.isString(ast.literal)) return ast.literal;
19
+ throw new Error("An app event is a tagged struct or class.");
20
+ };
21
+ /**
22
+ * Registers one of the application's events with an assistant.
23
+ *
24
+ * **Details**
25
+ *
26
+ * Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`
27
+ * defaults to `"json"` for an event that wakes a turn. An event that doesn't wake a turn and has
28
+ * no `render` isn't read by the model.
29
+ *
30
+ * The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws
31
+ * otherwise.
32
+ *
33
+ * **Example** (Registering an event that wakes a turn)
34
+ *
35
+ * ```ts
36
+ * import { AppEvent, Assistant, InputId } from "effect-assistant"
37
+ * import * as Schema from "effect/Schema"
38
+ *
39
+ * class OrderShipped extends Schema.TaggedClass<OrderShipped>()("OrderShipped", {
40
+ * id: InputId.InputId,
41
+ * orderId: Schema.String,
42
+ * carrier: Schema.String
43
+ * }) {}
44
+ *
45
+ * export const MyAssistant = Assistant.make("my-assistant", {
46
+ * events: [
47
+ * AppEvent.make(OrderShipped, {
48
+ * wakes: true,
49
+ * render: (shipped) =>
50
+ * `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`
51
+ * })
52
+ * ]
53
+ * })
54
+ * ```
55
+ *
56
+ * @category constructors
57
+ * @since 0.1.0
58
+ */
59
+ const make = (schema, options) => {
60
+ const wakes = options?.wakes ?? false;
61
+ return {
62
+ schema,
63
+ tag: tagOf(schema),
64
+ wakes,
65
+ render: options?.render ?? (wakes ? "json" : void 0)
66
+ };
67
+ };
68
+ //#endregion
69
+ export { AppEvent_exports, make };
70
+
71
+ //# sourceMappingURL=AppEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppEvent.js","names":[],"sources":["../src/AppEvent.ts"],"sourcesContent":["/**\n * Registers an application's own events with an assistant.\n *\n * An app event is a tagged schema for something the application reports into a chat, such as a\n * workflow's progress, a webhook, a summary for compaction, or the draft the user opened.\n * {@link make} registers one with two choices: whether storing it wakes a turn (`wakes`), and\n * how the model reads it (`render`).\n *\n * @since 0.1.0\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Schema from \"effect/Schema\"\nimport * as SchemaAST from \"effect/SchemaAST\"\n\n/**\n * Schema for one of the application's own events.\n *\n * It is a tagged struct or class (`Schema.TaggedStruct`, `Schema.TaggedClass`) that needs no\n * services.\n *\n * @category models\n * @since 0.1.0\n */\nexport type EventSchema = Schema.Codec<{ readonly _tag: string }, { readonly _tag: string }> & {\n readonly fields: { readonly _tag: { readonly ast: SchemaAST.AST } }\n}\n\n/**\n * Describes how the model reads an event.\n *\n * `\"json\"` shows the event's tag and fields as JSON. A function shows the text it returns for the\n * event.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Render<A> = \"json\" | ((event: A) => string)\n\n/**\n * Represents one of the application's events, registered with an assistant.\n *\n * It holds the event's schema and tag, whether storing it wakes a turn, and how the model reads\n * it. A `render` of `undefined` means the model doesn't read it.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface AppEvent<S extends EventSchema = EventSchema> {\n readonly schema: S\n readonly tag: string\n readonly wakes: boolean\n readonly render: Render<S[\"Type\"]> | undefined\n}\n\n/**\n * Represents any registered event, for generic constraints.\n *\n * @category utility types\n * @since 0.1.0\n */\nexport type Any = AppEvent<any>\n\n/**\n * Extracts the type of a registered event's values.\n *\n * @category utility types\n * @since 0.1.0\n */\nexport type Type<E extends Any> = E[\"schema\"][\"Type\"]\n\nconst tagOf = (schema: EventSchema): string => {\n const ast = schema.fields._tag.ast\n\n if (SchemaAST.isLiteral(ast) && Predicate.isString(ast.literal)) return ast.literal\n\n throw new Error(\"An app event is a tagged struct or class.\")\n}\n\n/**\n * Registers one of the application's events with an assistant.\n *\n * **Details**\n *\n * Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`\n * defaults to `\"json\"` for an event that wakes a turn. An event that doesn't wake a turn and has\n * no `render` isn't read by the model.\n *\n * The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws\n * otherwise.\n *\n * **Example** (Registering an event that wakes a turn)\n *\n * ```ts\n * import { AppEvent, Assistant, InputId } from \"effect-assistant\"\n * import * as Schema from \"effect/Schema\"\n *\n * class OrderShipped extends Schema.TaggedClass<OrderShipped>()(\"OrderShipped\", {\n * id: InputId.InputId,\n * orderId: Schema.String,\n * carrier: Schema.String\n * }) {}\n *\n * export const MyAssistant = Assistant.make(\"my-assistant\", {\n * events: [\n * AppEvent.make(OrderShipped, {\n * wakes: true,\n * render: (shipped) =>\n * `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`\n * })\n * ]\n * })\n * ```\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = <S extends EventSchema>(\n schema: S,\n options?: {\n /** Whether storing it starts a turn, like a user's message. Default false. */\n readonly wakes?: boolean | undefined\n /** How the model reads it in its history. */\n readonly render?: Render<S[\"Type\"]> | undefined\n }\n): AppEvent<S> => {\n const wakes = options?.wakes ?? false\n\n return {\n schema,\n tag: tagOf(schema),\n wakes,\n render: options?.render ?? (wakes ? \"json\" : undefined)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsEA,MAAM,SAAS,WAAgC;CAC7C,MAAM,MAAM,OAAO,OAAO,KAAK;CAE/B,IAAI,UAAU,UAAU,GAAG,KAAK,UAAU,SAAS,IAAI,OAAO,GAAG,OAAO,IAAI;CAE5E,MAAM,IAAI,MAAM,2CAA2C;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,QACX,QACA,YAMgB;CAChB,MAAM,QAAQ,SAAS,SAAS;CAEhC,OAAO;EACL;EACA,KAAK,MAAM,MAAM;EACjB;EACA,QAAQ,SAAS,WAAW,QAAQ,SAAS,KAAA;CAC/C;AACF"}
@@ -0,0 +1,403 @@
1
+ import { Any as Any$1, AppEvent_d_exports, Type } from "./AppEvent.js";
2
+ import { ChatId } from "./ChatId.js";
3
+ import { AssistantEvent, AssistantEvent_d_exports, Input } from "./AssistantEvent.js";
4
+ import { Instructions_d_exports, Resolved } from "./Instructions.js";
5
+ import { AssistantLoop_d_exports, ChatHistory, Event, ToolkitServices } from "./AssistantLoop.js";
6
+ import { CurrentChat } from "./CurrentChat.js";
7
+ import { BlockKit, BlockKit_d_exports } from "./BlockKit.js";
8
+ import { Skill } from "./Skill.js";
9
+ import { Any as Any$2, CheckServices, HandlerOf, Runner, Specialist_d_exports, ToolHandlers } from "./Specialist.js";
10
+ import { AssistantEngine } from "./AssistantEngine.js";
11
+ import { Chats_d_exports, GetChatError } from "./Chats.js";
12
+ import * as Context from "effect/Context";
13
+ import * as Effect from "effect/Effect";
14
+ import * as Layer from "effect/Layer";
15
+ import * as Schema from "effect/Schema";
16
+ import * as Stream from "effect/Stream";
17
+ import * as Scope from "effect/Scope";
18
+ import * as Prompt from "effect/ai/Prompt";
19
+ import * as Tool from "effect/ai/Tool";
20
+ import * as Toolkit from "effect/ai/Toolkit";
21
+ import * as LanguageModel from "effect/ai/LanguageModel";
22
+ import * as AiError from "effect/ai/AiError";
23
+ declare namespace Assistant_d_exports {
24
+ export { Any, Assistant, Chat, ChatIdentifier, Entry, Handler, HandlerServices, HistoryView, Identifier, LoopOptions, ReplyOptions, Service, Turn, TurnServices, isAssistant, make };
25
+ }
26
+ declare const TypeId: "~effect-assistant/Assistant";
27
+ /**
28
+ * Represents the services that a turn provides to its tools, its loop, and its specialists. These
29
+ * are the turn's chat (`CurrentChat`) and the chat's specialist runner (`Specialist.Runner`).
30
+ *
31
+ * @category utility types
32
+ * @since 0.1.0
33
+ */
34
+ export type TurnServices = CurrentChat | Runner;
35
+ /**
36
+ * Represents the options accepted by `turn.loop`.
37
+ *
38
+ * @category models
39
+ * @since 0.1.0
40
+ */
41
+ export interface LoopOptions<T extends Record<string, Tool.Any> = Record<never, never>, RS = never, Events = never> {
42
+ /** The assistant's role and rules. The loop places `Instructions.protocol` before them. */
43
+ readonly instructions: string | Resolved;
44
+ /**
45
+ * Tools the model can use in addition to the assistant's own. This is an `effect/ai` toolkit,
46
+ * and its handlers come from the layer. Combine several toolkits with `Toolkit.merge`, for
47
+ * example `Memory.Tools` or a `ToolDiscovery.make(...)` toolkit together with your own.
48
+ */
49
+ readonly toolkit?: Toolkit.Toolkit<T> | undefined;
50
+ /**
51
+ * Playbooks the model can follow. The prompt lists them as a catalog, and the model loads one
52
+ * with `load_skill` when a task matches it.
53
+ */
54
+ readonly skills?: ReadonlyArray<Skill<RS>> | undefined;
55
+ /** The maximum number of model calls per turn. Defaults to 16. */
56
+ readonly maxSteps?: number | undefined;
57
+ /** The message the reply pass gives the model when the turn would end without a reply. */
58
+ readonly replyNudge?: string | undefined;
59
+ /**
60
+ * Selects which of the chat's entries the model reads, for example only those since the last
61
+ * summary. Defaults to all entries.
62
+ */
63
+ readonly history?: HistoryView<Events> | undefined;
64
+ }
65
+ /**
66
+ * Represents a function that selects which of a chat's entries the model reads, and what else it
67
+ * reads with them.
68
+ *
69
+ * **Details**
70
+ *
71
+ * The function receives the chat's entries and returns, in order, a mix of entries and
72
+ * `Prompt.Message`s. The model reads the returned entries the same way it reads the full history,
73
+ * and reads each prompt message unchanged.
74
+ *
75
+ * @category models
76
+ * @since 0.1.0
77
+ */
78
+ export type HistoryView<Events = never> = (entries: ReadonlyArray<Entry<Events>>) => ReadonlyArray<Entry<Events> | Prompt.Message>;
79
+ /**
80
+ * Represents an entry in a chat's log, with the assistant's own events decoded to their types.
81
+ *
82
+ * @category models
83
+ * @since 0.1.0
84
+ */
85
+ export interface Entry<Events = never> {
86
+ readonly chatId: ChatId;
87
+ readonly seq: number;
88
+ readonly at: number;
89
+ readonly event: AssistantEvent | Events;
90
+ }
91
+ /**
92
+ * Represents the options accepted by `turn.replyIfOwed`.
93
+ *
94
+ * @category models
95
+ * @since 0.1.0
96
+ */
97
+ export interface ReplyOptions {
98
+ /** The assistant's instructions, as passed to `turn.loop`. `Instructions.protocol` is added. */
99
+ readonly instructions: string | Resolved;
100
+ /**
101
+ * The message given to the model after the history. Defaults to a message saying that it
102
+ * hasn't replied yet and should reply now.
103
+ */
104
+ readonly nudge?: string | undefined;
105
+ }
106
+ /**
107
+ * Represents one turn, as the assistant's handler receives it.
108
+ *
109
+ * `Events` is the type of the app's own events that the assistant registered with its `events`
110
+ * option.
111
+ *
112
+ * @category models
113
+ * @since 0.1.0
114
+ */
115
+ export interface Turn<Events = never> {
116
+ readonly chatId: ChatId;
117
+ /**
118
+ * Returns the model's history, built from the chat's entries (all of them, or those a view
119
+ * keeps), together with how far into the chat it reaches.
120
+ *
121
+ * Read it before every model call, as the loop does. Each step records how far its model call
122
+ * read, and the turn ends once it has handled what the model saw. An input that arrived after
123
+ * that is handled by the next turn.
124
+ */
125
+ readonly history: (view?: HistoryView<Events>) => Effect.Effect<ChatHistory>;
126
+ /**
127
+ * Returns the full system prompt for the given instructions. It contains
128
+ * `Instructions.protocol`, the instructions, and the specialist runs that are working now.
129
+ */
130
+ readonly instructions: (instructions: string | Resolved) => Resolved;
131
+ /**
132
+ * Runs the agent loop over the chat. The loop uses `Instructions.protocol`, the assistant's own
133
+ * tools, and the instructions, tools, and skills in `options`. Every step is a tool call, and
134
+ * the loop ends with `replyIfOwed`.
135
+ */
136
+ readonly loop: <T extends Record<string, Tool.Any> = Record<never, never>, RS = never>(options: LoopOptions<T, RS, Events>) => Stream.Stream<Event, AiError.AiError, LanguageModel.LanguageModel | TurnServices | ToolkitServices<T> | RS>;
137
+ /**
138
+ * Runs one more pass when the turn would otherwise end without a reply to the user's latest
139
+ * message. In this pass the model can only reply.
140
+ *
141
+ * The stream is empty when no reply is owed, or when an input arrived that the next turn will
142
+ * read. `loop` runs this pass with its own prompt and tools, so the pass reuses the cached
143
+ * prompt.
144
+ */
145
+ readonly replyIfOwed: (options: ReplyOptions) => Stream.Stream<Event, AiError.AiError, LanguageModel.LanguageModel | TurnServices>;
146
+ }
147
+ /**
148
+ * Represents an assistant's handler, which runs a turn and returns it as a stream of the loop's
149
+ * events.
150
+ *
151
+ * The handler may return the stream directly or from an Effect. `R` is the services the stream
152
+ * requires, and `RE` is the services the Effect requires.
153
+ *
154
+ * @category models
155
+ * @since 0.1.0
156
+ */
157
+ export type Handler<R = never, RE = R, Events = never> = (turn: Turn<Events>) => Stream.Stream<Event, unknown, R> | Effect.Effect<Stream.Stream<Event, unknown, R>, unknown, RE>;
158
+ /**
159
+ * Computes the services an assistant's handler needs beyond those its turns provide (the turn
160
+ * services and `LanguageModel`) and its tools' handlers (which its layer requires). These are the
161
+ * services that its build Effect must require.
162
+ *
163
+ * @category utility types
164
+ * @since 0.1.0
165
+ */
166
+ export type HandlerServices<R> = Exclude<R, TurnServices | LanguageModel.LanguageModel | Tool.Handler<string>>;
167
+ /**
168
+ * Identifies an assistant's service in a context. Each assistant has its own identifier, keyed by
169
+ * its name.
170
+ *
171
+ * @category models
172
+ * @since 0.1.0
173
+ */
174
+ export interface Identifier<Name extends string> {
175
+ readonly "~effect-assistant/Assistant": Name;
176
+ }
177
+ /**
178
+ * Identifies, in a context, the chat that an assistant's turns run in.
179
+ *
180
+ * @category models
181
+ * @since 0.1.0
182
+ */
183
+ export interface ChatIdentifier<Name extends string> {
184
+ readonly "~effect-assistant/Assistant/Chat": Name;
185
+ }
186
+ /**
187
+ * Represents the chat that a turn of this assistant runs in, typed with the assistant's events.
188
+ *
189
+ * Use `yield* MyAssistant.Chat` in the handler, in the handler's build, or in a tool that its
190
+ * turns run. Code that doesn't know the assistant uses `CurrentChat` instead.
191
+ *
192
+ * @see {@link CurrentChat} for the same chat without the assistant's event types
193
+ *
194
+ * @category models
195
+ * @since 0.1.0
196
+ */
197
+ export interface Chat<Events = never> {
198
+ readonly chatId: ChatId;
199
+ /**
200
+ * The chat's entries so far, in order. They include the library's events and the assistant's
201
+ * own events, typed.
202
+ */
203
+ readonly entries: Effect.Effect<ReadonlyArray<Entry<Events>>>;
204
+ /**
205
+ * Appends events after the chat's last entry and sends them to the chat's subscribers. The
206
+ * events can be the library's or the assistant's own, such as a summary. An event that wakes a
207
+ * turn is handled by the next turn.
208
+ */
209
+ append(...events: ReadonlyArray<AssistantEvent | Events>): Effect.Effect<void>;
210
+ }
211
+ /**
212
+ * Represents the service that `yield* MyAssistant` returns. It gives code outside a chat, such as
213
+ * a server or a workflow, access to the assistant's chats. Code that runs inside a chat uses
214
+ * `CurrentChat` instead.
215
+ *
216
+ * @category models
217
+ * @since 0.1.0
218
+ */
219
+ export interface Service<Events = never> {
220
+ /**
221
+ * Stores an input or one of the assistant's own events, then returns. Examples are a user's
222
+ * message or block answer, a workflow's progress, or the draft the user opened. The assistant
223
+ * works on events that wake a turn in the background.
224
+ *
225
+ * Fails with `GetChatError` when the app's `Chats` service reports that the chat can't be used,
226
+ * because the app doesn't know the chat or has deleted it.
227
+ */
228
+ submit(chatId: ChatId, input: Input | Events): Effect.Effect<void, GetChatError>;
229
+ /**
230
+ * Streams the chat's stored entries, then live ones, with the assistant's own events decoded.
231
+ * A reader that already has the earlier entries passes `after` and receives only the entries
232
+ * after that `seq`.
233
+ *
234
+ * For a chat client, pipe the whole log into `ChatView.updates(MyAssistant, { after })`, which
235
+ * streams the chat as its user sees it. Its `after` goes there, not here: the view of a message
236
+ * depends on earlier entries.
237
+ */
238
+ readonly subscribe: (chatId: ChatId, options?: {
239
+ readonly after?: number | undefined;
240
+ }) => Stream.Stream<Entry<Events>>;
241
+ /**
242
+ * Deletes a chat by storing a `ChatDeleted` event and stopping everything that works in it.
243
+ *
244
+ * **Details**
245
+ *
246
+ * A turn or specialist run working in the chat stops, and subscribers' streams end with the
247
+ * `ChatDeleted` event. After that the chat stores nothing more: a later input, a run's report,
248
+ * or a workflow's event for it is dropped without an error. The log is kept, and removing it is
249
+ * up to the app. Deleting a chat a second time does nothing.
250
+ *
251
+ * When the app's `Chats` service reports a chat as deleted, the assistant deletes it in the same
252
+ * way the next time it checks. It checks before an input is stored and before each model call.
253
+ */
254
+ readonly delete: (chatId: ChatId) => Effect.Effect<void>;
255
+ }
256
+ /**
257
+ * Represents an assistant's definition.
258
+ *
259
+ * The definition holds what callers and the UI need to know about the assistant, builds its
260
+ * handler's layer, and is the key of its service (`yield* MyAssistant`). `Events` is the type of
261
+ * the app's own events that the assistant registered.
262
+ *
263
+ * @category models
264
+ * @since 0.1.0
265
+ */
266
+ export interface Assistant<Name extends string = string, Specs extends Any$2 = never, Events = never> extends Context.Service<Identifier<Name>, Service<Events>> {
267
+ readonly [TypeId]: typeof TypeId;
268
+ readonly name: Name;
269
+ readonly blocks: BlockKit | undefined;
270
+ /** The specialists the assistant can hand work to. */
271
+ readonly specialists: ReadonlyArray<Specs>;
272
+ /** The app's own events the assistant registered. */
273
+ readonly events: ReadonlyArray<Any$1>;
274
+ /**
275
+ * Creates a layer that registers the assistant's handler with the engine and provides the
276
+ * assistant's service.
277
+ *
278
+ * **Details**
279
+ *
280
+ * `build` is the handler, or an Effect that returns it. The handler may use the turn services,
281
+ * `LanguageModel`, its tools' handlers (which the layer then requires), and services that its
282
+ * build Effect required (see `Specialist.CheckServices`). The layer requires the
283
+ * `AssistantEngine`, the `LanguageModel`, and each specialist's handler
284
+ * (`Research.toLayer(...)`).
285
+ *
286
+ * **Example** (Providing an assistant's handler)
287
+ *
288
+ * ```ts
289
+ * import { Assistant, AssistantEngine, ChatLog } from "effect-assistant"
290
+ * import type * as LanguageModel from "effect/ai/LanguageModel"
291
+ * import * as Layer from "effect/Layer"
292
+ *
293
+ * declare const ModelLive: Layer.Layer<LanguageModel.LanguageModel>
294
+ *
295
+ * export const MyAssistant = Assistant.make("my-assistant")
296
+ *
297
+ * const MyAssistantLive = MyAssistant.toLayer((turn) =>
298
+ * turn.loop({ instructions: "You help a small team. Be brief." })
299
+ * )
300
+ *
301
+ * const AppLive = MyAssistantLive.pipe(
302
+ * Layer.provide(ModelLive),
303
+ * Layer.provideMerge(AssistantEngine.layerMemory),
304
+ * Layer.provideMerge(ChatLog.layerMemory)
305
+ * )
306
+ * ```
307
+ */
308
+ readonly toLayer: <R = never, RE = never, E = never, RX = never>(build: (Handler<R, RE, Events> | Effect.Effect<Handler<R, RE, Events>, E, RX>) & CheckServices<Exclude<HandlerServices<R | RE>, RX | ChatIdentifier<Name>>>) => Layer.Layer<Identifier<Name>, never, AssistantEngine | LanguageModel.LanguageModel | HandlerOf<Specs> | Exclude<RX, Scope.Scope | CurrentChat | ChatIdentifier<Name>> | ToolHandlers<R | RE>>;
309
+ /**
310
+ * A layer that provides the assistant's service without its handler.
311
+ *
312
+ * **When to use**
313
+ *
314
+ * Use it in a process that submits to chats that another process runs, such as a web server in
315
+ * front of a cluster.
316
+ *
317
+ * **Example** (Serving clients in front of a cluster)
318
+ *
319
+ * ```ts
320
+ * import { Assistant, AssistantEngine } from "effect-assistant"
321
+ * import * as Layer from "effect/Layer"
322
+ *
323
+ * export const MyAssistant = Assistant.make("my-assistant")
324
+ *
325
+ * // Requires `ChatLog` and `Sharding`. The cluster's runners run the chats.
326
+ * const MyAssistantClient = MyAssistant.layerClient.pipe(
327
+ * Layer.provide(AssistantEngine.layerCluster)
328
+ * )
329
+ * ```
330
+ */
331
+ readonly layerClient: Layer.Layer<Identifier<Name>, never, AssistantEngine>;
332
+ /**
333
+ * The key of the chat that the assistant's turns run in, typed with its events. See
334
+ * {@link Chat}.
335
+ */
336
+ readonly Chat: Context.Service<ChatIdentifier<Name>, Chat<Events>>;
337
+ /** A schema that encodes the chat's entries to JSON, including the assistant's own events. */
338
+ readonly Entry: Schema.Codec<Entry<Events>, Schema.Json>;
339
+ }
340
+ /**
341
+ * Represents any assistant, for use in generic constraints.
342
+ *
343
+ * @category utility types
344
+ * @since 0.1.0
345
+ */
346
+ export type Any = Assistant<any, any, any>;
347
+ /**
348
+ * Returns `true` when the value is an assistant's definition, created with {@link make}.
349
+ *
350
+ * @category guards
351
+ * @since 0.1.0
352
+ */
353
+ export declare const isAssistant: (u: unknown) => u is Any;
354
+ /**
355
+ * Creates an assistant definition from its name, its UI blocks, its specialists, and the app's own
356
+ * events it stores (see `AppEvent`).
357
+ *
358
+ * **Details**
359
+ *
360
+ * The definition holds no code that runs turns. Provide a handler with its `toLayer`, then yield
361
+ * the definition to get the assistant's {@link Service}.
362
+ *
363
+ * **Example** (Defining an assistant and submitting a message)
364
+ *
365
+ * ```ts
366
+ * import { Assistant, AssistantEvent, ChatId } from "effect-assistant"
367
+ * import * as Effect from "effect/Effect"
368
+ *
369
+ * export const MyAssistant = Assistant.make("my-assistant")
370
+ *
371
+ * const program = Effect.gen(function* () {
372
+ * const assistant = yield* MyAssistant
373
+ * const chatId = yield* ChatId.make()
374
+ *
375
+ * yield* assistant.submit(chatId, AssistantEvent.UserMessage.make({ text: "Weather in Oslo?" }))
376
+ * })
377
+ * ```
378
+ *
379
+ * @see {@link Assistant} for the definition's members
380
+ * @see {@link Service} for what `yield* MyAssistant` returns
381
+ *
382
+ * @category constructors
383
+ * @since 0.1.0
384
+ */
385
+ export declare const make: <const Name extends string, const Specs extends ReadonlyArray<Any$2> = readonly [], const Events extends ReadonlyArray<Any$1> = readonly []>(name: Name, options?: {
386
+ /** UI blocks the assistant can add to its messages. */
387
+ readonly blocks?: BlockKit | undefined;
388
+ /**
389
+ * The specialists the assistant can hand work to. Each specialist's `toLayer` must be
390
+ * provided to the assistant's layer.
391
+ */
392
+ readonly specialists?: Specs | undefined;
393
+ /**
394
+ * The app's own events, each created with `AppEvent.make(schema, { wakes, render })`.
395
+ * `submit` and the chat's `append` store them, and the chat's `entries` read them back,
396
+ * decoded. Events that wake a turn are inputs, and the model reads each event that has a
397
+ * `render`.
398
+ */
399
+ readonly events?: Events | undefined;
400
+ }) => Assistant<Name, Specs[number], Type<Events[number]>>;
401
+ //#endregion
402
+ export { Assistant_d_exports };
403
+ //# sourceMappingURL=Assistant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Assistant.d.ts","names":[],"sources":["../src/Assistant.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;cAwCM;;;;;;;;YASM,eAAe,cAAc;;;;;;;iBAQxB,YAAY,UAAU,eAAe,KAAK,OAAO,sBAAsB,YAAY;;WAEzF,uBAAuB;;;;;;WAMvB,UAAU,QAAQ,QAAQ;;;;;WAK1B,SAAS,cAAc,MAAM;;WAE7B;;WAEA;;;;;WAKA,UAAU,YAAY;;;;;;;;;;;;;;;YAgBrB,YAAY,mBACtB,SAAS,cAAc,MAAM,aAC1B,cAAc,MAAM,UAAU,OAAO;;;;;;;iBAQzB,MAAM;WACZ,QAAQ;WACR;WACA;WACA,OAAO,iBAAgC;;;;;;;;iBASjC;;WAEN,uBAAuB;;;;;WAKvB;;;;;;;;;;;iBAYM,KAAK;WACX,QAAQ;;;;;;;;;WASR,UAAU,OAAO,YAAY,YAAY,OAAO,OAAO;;;;;WAKvD,eAAe,uBAAuB,aAA0B;;;;;;WAMhE,OAAO,UAAU,eAAe,KAAK,OAAO,sBAAsB,YACzE,SAAS,YAAY,GAAG,IAAI,YACzB,OAAO,OACV,OACA,QAAQ,SACR,cAAc,gBAAgB,eAAe,gBAA8B,KAAK;;;;;;;;;WAUzE,cACP,SAAS,iBACN,OAAO,OAAO,OAAqB,QAAQ,SAAS,cAAc,gBAAgB;;;;;;;;;;;;YAa7E,QAAQ,WAAW,KAAK,GAAG,mBACrC,MAAM,KAAK,YAET,OAAO,OAAO,gBAA8B,KAC5C,OAAO,OAAO,OAAO,OAAO,gBAA8B,aAAa;;;;;;;;;YAU/D,gBAAgB,KAAK,QAAQ,GAAG,eAAe,cAAc,gBAAgB,KAAK;;;;;;;;iBAe7E,WAAW;WACjB,+BAA+B;;;;;;;;iBASzB,eAAe;WACrB,oCAAoC;;;;;;;;;;;;;iBAc9B,KAAK;WACX,QAAQ;;;;;WAKR,SAAS,OAAO,OAAO,cAAc,MAAM;;;;;;EAMpD,UAAU,QAAQ,cAAc,iBAAgC,UAAU,OAAO;;;;;;;;;;iBAWlE,QAAQ;;;;;;;;;EAUvB,OAAO,QAAQ,QAAQ,OAAO,QAAuB,SAAS,OAAO,aAAa;;;;;;;;;;WAUzE,YACP,QAAQ,QACR;aAAqB;QAClB,OAAO,OAAO,MAAM;;;;;;;;;;;;;;WAchB,SAAS,QAAQ,WAAW,OAAO;;;;;;;;;;;;iBAa7B,UACf,8BACA,cAAc,eACd,wBACQ,QAAQ,QAAQ,WAAW,OAAO,QAAQ;YACxC,gBAAgB;WACjB,MAAM;WACN,QAAQ;;WAER,aAAa,cAAc;;WAE3B,QAAQ,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCtB,UAAU,WAAW,YAAY,WAAW,YACnD,QAAQ,QAAQ,GAAG,IAAI,UAAU,OAAO,OAAO,QAAQ,GAAG,IAAI,SAAS,GAAG,OACxE,cAAyB,QAAQ,gBAAgB,IAAI,KAAK,KAAK,eAAe,YAC7E,MAAM,MACT,WAAW,cAET,kBACA,cAAc,gBACd,UAAqB,SACrB,QAAQ,IAAI,MAAM,QAAQ,cAAc,eAAe,SACvD,aAAwB,IAAI;;;;;;;;;;;;;;;;;;;;;;;WAwBvB,aAAa,MAAM,MAAM,WAAW,cAAc;;;;;WAKlD,MAAM,QAAQ,QAAQ,eAAe,OAAO,KAAK;;WAEjD,OAAO,OAAO,MAAM,MAAM,SAAS,OAAO;;;;;;;;YASzC,MAAM;;;;;;;qBAQL,cAAW,eAAiB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8CjC,aACL,2BACA,cAAc,cAAc,4BAC5B,eAAe,cAAc,sBAA2B,MAExD,MAAI;;WAGC,SAAS;;;;;WAKT,cAAc;;;;;;;WAOd,SAAS;MAEnB,UAAU,MAAM,eAAe,KAAc"}