liminal 0.16.0 → 0.17.1

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 (275) hide show
  1. package/Accumulator.ts +97 -0
  2. package/Actor.ts +118 -0
  3. package/Audition.ts +105 -0
  4. package/CHANGELOG.md +2 -206
  5. package/Client.ts +560 -0
  6. package/ClientHandle.ts +39 -0
  7. package/F.ts +18 -0
  8. package/Method.ts +39 -0
  9. package/Protocol.ts +142 -0
  10. package/Send.ts +8 -0
  11. package/_constants.ts +1 -0
  12. package/_types.ts +27 -0
  13. package/_util/Mutex.ts +13 -0
  14. package/_util/phantom.ts +1 -0
  15. package/dist/Accumulator.d.ts +22 -0
  16. package/dist/Accumulator.js +33 -0
  17. package/dist/Accumulator.js.map +1 -0
  18. package/dist/Actor.d.ts +30 -0
  19. package/dist/Actor.js +31 -0
  20. package/dist/Actor.js.map +1 -0
  21. package/dist/Audition.d.ts +18 -0
  22. package/dist/Audition.js +27 -0
  23. package/dist/Audition.js.map +1 -0
  24. package/dist/Client.d.ts +65 -0
  25. package/dist/Client.js +248 -0
  26. package/dist/Client.js.map +1 -0
  27. package/dist/ClientHandle.d.ts +18 -0
  28. package/dist/ClientHandle.js +10 -0
  29. package/dist/ClientHandle.js.map +1 -0
  30. package/dist/F.d.ts +13 -0
  31. package/dist/F.js +4 -0
  32. package/dist/F.js.map +1 -0
  33. package/dist/Method.d.ts +23 -0
  34. package/dist/Method.js +4 -0
  35. package/dist/Method.js.map +1 -0
  36. package/dist/Protocol.d.ts +96 -0
  37. package/dist/Protocol.js +13 -0
  38. package/dist/Protocol.js.map +1 -0
  39. package/dist/Send.d.ts +3 -0
  40. package/dist/Send.js +2 -0
  41. package/dist/Send.js.map +1 -0
  42. package/dist/_constants.d.ts +1 -0
  43. package/dist/_constants.js +2 -0
  44. package/dist/_constants.js.map +1 -0
  45. package/dist/_types.d.ts +22 -0
  46. package/dist/_types.js +2 -0
  47. package/dist/_types.js.map +1 -0
  48. package/dist/_util/Mutex.d.ts +7 -0
  49. package/dist/_util/Mutex.js +9 -0
  50. package/dist/_util/Mutex.js.map +1 -0
  51. package/dist/_util/phantom.d.ts +3 -0
  52. package/dist/_util/phantom.js +2 -0
  53. package/dist/_util/phantom.js.map +1 -0
  54. package/dist/errors.d.ts +20 -0
  55. package/dist/errors.js +13 -0
  56. package/dist/errors.js.map +1 -0
  57. package/dist/experimental/BranchLive.d.ts +3 -0
  58. package/dist/experimental/BranchLive.js +5 -0
  59. package/dist/experimental/BranchLive.js.map +1 -0
  60. package/dist/experimental/L/L.d.ts +11 -0
  61. package/dist/experimental/L/L.js +12 -0
  62. package/dist/experimental/L/L.js.map +1 -0
  63. package/dist/experimental/L/append.d.ts +3 -0
  64. package/dist/experimental/L/append.js +4 -0
  65. package/dist/experimental/L/append.js.map +1 -0
  66. package/dist/experimental/L/assistant.d.ts +3 -0
  67. package/dist/experimental/L/assistant.js +13 -0
  68. package/dist/experimental/L/assistant.js.map +1 -0
  69. package/dist/experimental/L/assistantSchema.d.ts +3 -0
  70. package/dist/experimental/L/assistantSchema.js +13 -0
  71. package/dist/experimental/L/assistantSchema.js.map +1 -0
  72. package/dist/experimental/L/assistantStream.d.ts +3 -0
  73. package/dist/experimental/L/assistantStream.js +5 -0
  74. package/dist/experimental/L/assistantStream.js.map +1 -0
  75. package/dist/experimental/L/branch.d.ts +2 -0
  76. package/dist/experimental/L/branch.js +4 -0
  77. package/dist/experimental/L/branch.js.map +1 -0
  78. package/dist/experimental/L/clear.d.ts +3 -0
  79. package/dist/experimental/L/clear.js +7 -0
  80. package/dist/experimental/L/clear.js.map +1 -0
  81. package/dist/experimental/L/history.d.ts +3 -0
  82. package/dist/experimental/L/history.js +4 -0
  83. package/dist/experimental/L/history.js.map +1 -0
  84. package/dist/experimental/L/init.d.ts +3 -0
  85. package/dist/experimental/L/init.js +4 -0
  86. package/dist/experimental/L/init.js.map +1 -0
  87. package/dist/experimental/L/matrix.d.ts +10 -0
  88. package/dist/experimental/L/matrix.js +6 -0
  89. package/dist/experimental/L/matrix.js.map +1 -0
  90. package/dist/experimental/L/system.d.ts +1 -0
  91. package/dist/experimental/L/system.js +4 -0
  92. package/dist/experimental/L/system.js.map +1 -0
  93. package/dist/experimental/L/user.d.ts +1 -0
  94. package/dist/experimental/L/user.js +6 -0
  95. package/dist/experimental/L/user.js.map +1 -0
  96. package/dist/experimental/Loader.d.ts +16 -0
  97. package/dist/experimental/Loader.js +20 -0
  98. package/dist/experimental/Loader.js.map +1 -0
  99. package/dist/experimental/TaggedTemplateFunction.d.ts +11 -0
  100. package/dist/experimental/TaggedTemplateFunction.js +14 -0
  101. package/dist/experimental/TaggedTemplateFunction.js.map +1 -0
  102. package/dist/experimental/Template.d.ts +32 -0
  103. package/dist/experimental/Template.js +58 -0
  104. package/dist/experimental/Template.js.map +1 -0
  105. package/dist/experimental/index.d.ts +4 -0
  106. package/dist/experimental/index.js +5 -0
  107. package/dist/experimental/index.js.map +1 -0
  108. package/dist/index.d.ts +9 -5
  109. package/dist/index.js +9 -5
  110. package/dist/index.js.map +1 -1
  111. package/dist/tsconfig.tsbuildinfo +1 -1
  112. package/errors.ts +14 -0
  113. package/experimental/BranchLive.ts +6 -0
  114. package/experimental/L/L.ts +11 -0
  115. package/experimental/L/append.ts +12 -0
  116. package/experimental/L/assistant.ts +16 -0
  117. package/experimental/L/assistantSchema.ts +18 -0
  118. package/experimental/L/assistantStream.ts +9 -0
  119. package/experimental/L/branch.ts +5 -0
  120. package/experimental/L/clear.ts +7 -0
  121. package/experimental/L/history.ts +4 -0
  122. package/experimental/L/init.ts +4 -0
  123. package/experimental/L/matrix.ts +26 -0
  124. package/experimental/L/system.ts +5 -0
  125. package/experimental/L/user.ts +10 -0
  126. package/experimental/Loader.ts +35 -0
  127. package/experimental/TaggedTemplateFunction.ts +44 -0
  128. package/experimental/Template.ts +93 -0
  129. package/experimental/index.ts +4 -0
  130. package/index.ts +9 -5
  131. package/package.json +26 -23
  132. package/tsconfig.json +9 -0
  133. package/Envelope.ts +0 -48
  134. package/L/L.ts +0 -21
  135. package/L/Self.ts +0 -5
  136. package/L/append.ts +0 -14
  137. package/L/assistant.ts +0 -30
  138. package/L/assistantSchema.ts +0 -61
  139. package/L/assistantStream.ts +0 -22
  140. package/L/branch.ts +0 -33
  141. package/L/clear.ts +0 -14
  142. package/L/disable.ts +0 -13
  143. package/L/enable.ts +0 -24
  144. package/L/events.ts +0 -11
  145. package/L/fqn.ts +0 -9
  146. package/L/handle.ts +0 -26
  147. package/L/messages.ts +0 -10
  148. package/L/raw.ts +0 -30
  149. package/L/sequence.ts +0 -9
  150. package/L/system.ts +0 -14
  151. package/L/thread.ts +0 -28
  152. package/L/to.ts +0 -4
  153. package/L/toolkit.ts +0 -14
  154. package/L/user.test.ts +0 -30
  155. package/L/user.ts +0 -22
  156. package/L/userJson.ts +0 -14
  157. package/LEvent.ts +0 -23
  158. package/LPretty.ts +0 -41
  159. package/Thread.ts +0 -69
  160. package/dist/Envelope.d.ts +0 -15
  161. package/dist/Envelope.js +0 -30
  162. package/dist/Envelope.js.map +0 -1
  163. package/dist/L/L.d.ts +0 -21
  164. package/dist/L/L.js +0 -22
  165. package/dist/L/L.js.map +0 -1
  166. package/dist/L/Self.d.ts +0 -3
  167. package/dist/L/Self.js +0 -4
  168. package/dist/L/Self.js.map +0 -1
  169. package/dist/L/append.d.ts +0 -5
  170. package/dist/L/append.js +0 -10
  171. package/dist/L/append.js.map +0 -1
  172. package/dist/L/assistant.d.ts +0 -6
  173. package/dist/L/assistant.js +0 -26
  174. package/dist/L/assistant.js.map +0 -1
  175. package/dist/L/assistantSchema.d.ts +0 -13
  176. package/dist/L/assistantSchema.js +0 -44
  177. package/dist/L/assistantSchema.js.map +0 -1
  178. package/dist/L/assistantStream.d.ts +0 -7
  179. package/dist/L/assistantStream.js +0 -17
  180. package/dist/L/assistantStream.js.map +0 -1
  181. package/dist/L/branch.d.ts +0 -6
  182. package/dist/L/branch.js +0 -22
  183. package/dist/L/branch.js.map +0 -1
  184. package/dist/L/clear.d.ts +0 -5
  185. package/dist/L/clear.js +0 -12
  186. package/dist/L/clear.js.map +0 -1
  187. package/dist/L/disable.d.ts +0 -4
  188. package/dist/L/disable.js +0 -10
  189. package/dist/L/disable.js.map +0 -1
  190. package/dist/L/enable.d.ts +0 -5
  191. package/dist/L/enable.js +0 -13
  192. package/dist/L/enable.js.map +0 -1
  193. package/dist/L/events.d.ts +0 -5
  194. package/dist/L/events.js +0 -6
  195. package/dist/L/events.js.map +0 -1
  196. package/dist/L/fqn.d.ts +0 -3
  197. package/dist/L/fqn.js +0 -8
  198. package/dist/L/fqn.js.map +0 -1
  199. package/dist/L/handle.d.ts +0 -7
  200. package/dist/L/handle.js +0 -14
  201. package/dist/L/handle.js.map +0 -1
  202. package/dist/L/messages.d.ts +0 -5
  203. package/dist/L/messages.js +0 -5
  204. package/dist/L/messages.js.map +0 -1
  205. package/dist/L/raw.d.ts +0 -3
  206. package/dist/L/raw.js +0 -18
  207. package/dist/L/raw.js.map +0 -1
  208. package/dist/L/sequence.d.ts +0 -2
  209. package/dist/L/sequence.js +0 -5
  210. package/dist/L/sequence.js.map +0 -1
  211. package/dist/L/system.d.ts +0 -5
  212. package/dist/L/system.js +0 -12
  213. package/dist/L/system.js.map +0 -1
  214. package/dist/L/thread.d.ts +0 -6
  215. package/dist/L/thread.js +0 -17
  216. package/dist/L/thread.js.map +0 -1
  217. package/dist/L/to.d.ts +0 -3
  218. package/dist/L/to.js +0 -3
  219. package/dist/L/to.js.map +0 -1
  220. package/dist/L/toolkit.d.ts +0 -4
  221. package/dist/L/toolkit.js +0 -9
  222. package/dist/L/toolkit.js.map +0 -1
  223. package/dist/L/user.d.ts +0 -4
  224. package/dist/L/user.js +0 -13
  225. package/dist/L/user.js.map +0 -1
  226. package/dist/L/user.test.d.ts +0 -1
  227. package/dist/L/user.test.js.map +0 -1
  228. package/dist/L/userJson.d.ts +0 -6
  229. package/dist/L/userJson.js +0 -9
  230. package/dist/L/userJson.js.map +0 -1
  231. package/dist/LEvent.d.ts +0 -26
  232. package/dist/LEvent.js +0 -16
  233. package/dist/LEvent.js.map +0 -1
  234. package/dist/LPretty.d.ts +0 -4
  235. package/dist/LPretty.js +0 -37
  236. package/dist/LPretty.js.map +0 -1
  237. package/dist/Thread.d.ts +0 -55
  238. package/dist/Thread.js +0 -38
  239. package/dist/Thread.js.map +0 -1
  240. package/dist/patterns/Debate.d.ts +0 -1
  241. package/dist/patterns/Debate.js +0 -3
  242. package/dist/patterns/Debate.js.map +0 -1
  243. package/dist/patterns/Model.d.ts +0 -6
  244. package/dist/patterns/Model.js +0 -14
  245. package/dist/patterns/Model.js.map +0 -1
  246. package/dist/patterns/Route.d.ts +0 -3
  247. package/dist/patterns/Route.js +0 -14
  248. package/dist/patterns/Route.js.map +0 -1
  249. package/dist/util/JsonValue.d.ts +0 -8
  250. package/dist/util/JsonValue.js +0 -109
  251. package/dist/util/JsonValue.js.map +0 -1
  252. package/dist/util/NeverTool.d.ts +0 -3
  253. package/dist/util/NeverTool.js +0 -3
  254. package/dist/util/NeverTool.js.map +0 -1
  255. package/dist/util/Sequencer.d.ts +0 -4
  256. package/dist/util/Sequencer.js +0 -2
  257. package/dist/util/Sequencer.js.map +0 -1
  258. package/dist/util/Taggable.d.ts +0 -5
  259. package/dist/util/Taggable.js +0 -2
  260. package/dist/util/Taggable.js.map +0 -1
  261. package/dist/util/normalizeRaw.d.ts +0 -4
  262. package/dist/util/normalizeRaw.js +0 -75
  263. package/dist/util/normalizeRaw.js.map +0 -1
  264. package/dist/util/prefix.d.ts +0 -1
  265. package/dist/util/prefix.js +0 -2
  266. package/dist/util/prefix.js.map +0 -1
  267. package/patterns/Debate.ts +0 -2
  268. package/patterns/Model.ts +0 -29
  269. package/patterns/Route.ts +0 -21
  270. package/util/JsonValue.ts +0 -144
  271. package/util/NeverTool.ts +0 -10
  272. package/util/Sequencer.ts +0 -13
  273. package/util/Taggable.ts +0 -14
  274. package/util/normalizeRaw.ts +0 -93
  275. package/util/prefix.ts +0 -1
package/errors.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { Schema as S } from "effect"
2
+
3
+ export class AuditionError extends S.TaggedError<AuditionError>()("AuditionError", {
4
+ value: S.Struct({
5
+ actual: S.String,
6
+ expected: S.String,
7
+ }).pipe(S.optional),
8
+ }) {}
9
+
10
+ export class ConnectionError extends S.TaggedError<ConnectionError>()("ConnectionError", {
11
+ cause: S.Unknown,
12
+ }) {}
13
+
14
+ export type ClientError = AuditionError | ConnectionError
@@ -0,0 +1,6 @@
1
+ import { Chat } from "@effect/ai"
2
+ import { Effect, Layer } from "effect"
3
+
4
+ import { history } from "./L/history.ts"
5
+
6
+ export const BranchLive = Layer.effect(Chat.Chat, history.pipe(Effect.flatMap(Chat.fromPrompt)))
@@ -0,0 +1,11 @@
1
+ export * from "./append.ts"
2
+ export * from "./assistant.ts"
3
+ export * from "./assistantSchema.ts"
4
+ export * from "./assistantStream.ts"
5
+ export * from "./branch.ts"
6
+ export * from "./clear.ts"
7
+ export * from "./history.ts"
8
+ export * from "./init.ts"
9
+ export * from "./matrix.ts"
10
+ export * from "./system.ts"
11
+ export * from "./user.ts"
@@ -0,0 +1,12 @@
1
+ import { Prompt, Chat } from "@effect/ai"
2
+ import { Effect, flow, Ref } from "effect"
3
+
4
+ export const append = (message: Prompt.Message) =>
5
+ Chat.Chat.pipe(
6
+ Effect.flatMap(
7
+ flow(
8
+ ({ history }) => history,
9
+ Ref.update(({ content }) => Prompt.fromMessages([...content, message])),
10
+ ),
11
+ ),
12
+ )
@@ -0,0 +1,16 @@
1
+ import { Prompt, LanguageModel } from "@effect/ai"
2
+ import { Effect } from "effect"
3
+
4
+ import { append } from "./append.ts"
5
+ import { history } from "./history.ts"
6
+
7
+ export const assistant = Effect.gen(function* () {
8
+ const prompt = yield* history
9
+ const { text } = yield* LanguageModel.generateText({ prompt })
10
+ yield* append(
11
+ Prompt.assistantMessage({
12
+ content: [Prompt.textPart({ text })],
13
+ }),
14
+ )
15
+ return text
16
+ })
@@ -0,0 +1,18 @@
1
+ import { Prompt, LanguageModel } from "@effect/ai"
2
+ import { Effect, Schema as S } from "effect"
3
+
4
+ import { append } from "./append.ts"
5
+ import { history } from "./history.ts"
6
+
7
+ export const assistantSchema = Effect.fnUntraced(function* <A, I extends Record<string, unknown>, R>(
8
+ schema: S.Schema<A, I, R>,
9
+ ) {
10
+ const prompt = yield* history
11
+ const { text, value } = yield* LanguageModel.generateObject({ prompt, schema })
12
+ yield* append(
13
+ Prompt.assistantMessage({
14
+ content: [Prompt.textPart({ text })],
15
+ }),
16
+ )
17
+ return value
18
+ })
@@ -0,0 +1,9 @@
1
+ import { LanguageModel } from "@effect/ai"
2
+ import { Effect, Stream } from "effect"
3
+
4
+ import { history } from "./history.ts"
5
+
6
+ export const assistantStream = history.pipe(
7
+ Effect.map((prompt) => LanguageModel.streamText({ prompt })),
8
+ Stream.unwrap,
9
+ )
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect"
2
+
3
+ import { BranchLive } from "../BranchLive.ts"
4
+
5
+ export const branch = Effect.provide(BranchLive)
@@ -0,0 +1,7 @@
1
+ import { Chat, Prompt } from "@effect/ai"
2
+ import { Ref, Effect } from "effect"
3
+
4
+ export const clear = Effect.gen(function* () {
5
+ const { history } = yield* Chat.Chat
6
+ yield* Ref.update(history, () => Prompt.empty)
7
+ })
@@ -0,0 +1,4 @@
1
+ import { Chat } from "@effect/ai"
2
+ import { flow, Effect, Ref } from "effect"
3
+
4
+ export const history = Chat.Chat.pipe(Effect.flatMap(flow(({ history }) => history, Ref.get)))
@@ -0,0 +1,4 @@
1
+ import { Chat } from "@effect/ai"
2
+ import { Effect } from "effect"
3
+
4
+ export const init = Effect.provideServiceEffect(Chat.Chat, Chat.empty)
@@ -0,0 +1,26 @@
1
+ import { Effect, Function, Layer } from "effect"
2
+
3
+ import { branch } from "./branch.ts"
4
+
5
+ type LayerRecord = Record<string, Layer.Layer.Any>
6
+
7
+ export type MatrixEffect<A, E, R, Layers extends LayerRecord> = Effect.Effect<
8
+ {
9
+ readonly [K in keyof Layers]: A
10
+ },
11
+ E | Layer.Layer.Error<Layers[keyof Layers]>,
12
+ R | Layer.Layer.Context<Layers[keyof Layers]>
13
+ >
14
+
15
+ export const matrix: {
16
+ <Layers extends LayerRecord>(
17
+ layers: Layers,
18
+ ): <A, E, R>(effect: Effect.Effect<A, E, R>) => MatrixEffect<A, E, R, Layers>
19
+ <Layers extends LayerRecord, A, E, R>(effect: Effect.Effect<A, E, R>, layers: Layers): MatrixEffect<A, E, R, Layers>
20
+ } = Function.dual(2, <Layers extends LayerRecord, A, E, R>(effect: Effect.Effect<A, E, R>, layers: Layers) => {
21
+ return Effect.all(
22
+ Object.fromEntries(
23
+ Object.entries(layers).map(([key, Live]) => [key, effect.pipe(branch, Effect.provide(Live as never))]),
24
+ ),
25
+ )
26
+ })
@@ -0,0 +1,5 @@
1
+ import { Prompt } from "@effect/ai"
2
+
3
+ import { append } from "./append.ts"
4
+
5
+ export const system = (text: string) => append(Prompt.systemMessage({ content: text }))
@@ -0,0 +1,10 @@
1
+ import { Prompt } from "@effect/ai"
2
+
3
+ import { append } from "./append.ts"
4
+
5
+ export const user = (text: string) =>
6
+ append(
7
+ Prompt.userMessage({
8
+ content: [Prompt.textPart({ text })],
9
+ }),
10
+ )
@@ -0,0 +1,35 @@
1
+ import { Path, FileSystem } from "@effect/platform"
2
+ import { Option, Layer, Effect, Data, Context } from "effect"
3
+
4
+ export class LoaderError extends Data.TaggedError("LoaderError")<{
5
+ readonly url: string
6
+ }> {}
7
+
8
+ export class Loader extends Context.Tag("liminal/Loader")<
9
+ Loader,
10
+ {
11
+ readonly load: (key: string) => Effect.Effect<Option.Option<string>, LoaderError>
12
+ }
13
+ >() {}
14
+
15
+ export const layerFs = Layer.effect(
16
+ Loader,
17
+ Effect.gen(function* () {
18
+ const path = yield* Path.Path
19
+ const fs = yield* FileSystem.FileSystem
20
+
21
+ const load = Effect.fnUntraced(function* (url: string) {
22
+ const { dir, name } = path.parse(new URL(url).pathname)
23
+ const templatePathname = path.join(dir, `${name}.md`)
24
+ if (yield* fs.exists(templatePathname).pipe(Effect.mapError(() => new LoaderError({ url })))) {
25
+ return yield* fs.readFileString(templatePathname).pipe(
26
+ Effect.map(Option.some),
27
+ Effect.mapError(() => new LoaderError({ url })),
28
+ )
29
+ }
30
+ return Option.none()
31
+ })
32
+
33
+ return { load }
34
+ }),
35
+ )
@@ -0,0 +1,44 @@
1
+ import { Effect } from "effect"
2
+
3
+ export type TemplateStringsArrayLike = {
4
+ raw: ReadonlyArray<string> | ArrayLike<string>
5
+ }
6
+
7
+ type ExtractE<T> = [Extract<T, Effect.Effect<any, any, any>>] extends [never]
8
+ ? never
9
+ : Effect.Effect.Error<Extract<T, Effect.Effect<any, any, any>>>
10
+
11
+ type ExtractR<T> = [Extract<T, Effect.Effect<any, any, any>>] extends [never]
12
+ ? never
13
+ : Effect.Effect.Context<Extract<T, Effect.Effect<any, any, any>>>
14
+
15
+ export const raw = Effect.fnUntraced(function* <Substitutions extends Array<unknown>>(
16
+ template: TemplateStringsArrayLike,
17
+ ...substitutions: Substitutions
18
+ ): Effect.fn.Return<string, ExtractE<Substitutions[number]>, ExtractR<Substitutions[number]>> {
19
+ return String.raw(
20
+ template,
21
+ ...(yield* Effect.all(substitutions.map((v) => (Effect.isEffect(v) ? v : Effect.succeed(v)))) as Effect.Effect<
22
+ Array<string>,
23
+ ExtractE<Substitutions[number]>,
24
+ ExtractR<Substitutions[number]>
25
+ >),
26
+ )
27
+ })
28
+
29
+ export type TaggableHead = TemplateStringsArrayLike | string | Effect.Effect<string, any, any>
30
+
31
+ export type TaggableRest<H extends TaggableHead> = H extends TemplateStringsArrayLike ? Array<unknown> : []
32
+
33
+ export const normalize = Effect.fnUntraced(function* <H extends TaggableHead, ARest extends TaggableRest<H>>(
34
+ a0: H,
35
+ ...aRest: ARest
36
+ ): Effect.fn.Return<string, ExtractE<H | ARest[number]>, ExtractR<H | ARest[number]>> {
37
+ if (Effect.isEffect(a0)) {
38
+ return yield* a0
39
+ }
40
+ if (typeof a0 === "string") {
41
+ return a0
42
+ }
43
+ return yield* raw(a0, ...aRest)
44
+ })
@@ -0,0 +1,93 @@
1
+ import { Option, Types, Layer, pipe, String, Effect, Schema as S, Data, SchemaAST, Context } from "effect"
2
+
3
+ import * as Loader from "./Loader.ts"
4
+
5
+ export type Template<A> = (...[value]: A extends undefined ? [] : [value: A]) => string
6
+
7
+ export class TemplateMisalignedError extends Data.TaggedError("TemplateMisalignedError")<{
8
+ readonly url: string
9
+ readonly keys: ReadonlyArray<string>
10
+ }> {}
11
+
12
+ export class NoSuchTemplateError extends Data.TaggedError("NoSuchTemplateError")<{ url: string }> {}
13
+
14
+ export interface TemplateClass<Self, Id extends string, A> extends Context.Tag<Self, Template<A>> {
15
+ new (_: never): Context.TagClassShape<Id, Template<A>>
16
+
17
+ readonly layer: Layer.Layer<Self, NoSuchTemplateError | TemplateMisalignedError | Loader.LoaderError, Loader.Loader>
18
+
19
+ readonly synthesize: (...[value]: A extends undefined ? [] : [value: A]) => Effect.Effect<string, never, Self>
20
+ }
21
+
22
+ export type Payload = Record<string, S.Schema<any, string> | S.optional<S.Schema<any, string>>>
23
+
24
+ export declare namespace Payload {
25
+ export type FromDefinition<P extends Payload | undefined> = P extends infer Q extends Payload
26
+ ? S.Struct<Q>["Type"]
27
+ : {}
28
+ }
29
+
30
+ export const Service =
31
+ <Self>() =>
32
+ <const Id extends string, const P extends Payload | undefined>(
33
+ id: Id,
34
+ {
35
+ url,
36
+ payload,
37
+ }: {
38
+ readonly url: string
39
+ readonly payload?: P | undefined
40
+ },
41
+ ): TemplateClass<Self, Id, Payload.FromDefinition<P>> => {
42
+ type Make_ = Template<Payload.FromDefinition<P>>
43
+ type Self_ = TemplateClass<Self, Id, Payload.FromDefinition<P>>
44
+ const self = Context.Tag(`liminal/Template/${id}`)<Self, Make_>() as never as Types.Mutable<Self_>
45
+ self.layer = Effect.gen(function* () {
46
+ const loader = yield* Loader.Loader
47
+ const template = yield* loader.load(url).pipe(Effect.map(Option.getOrUndefined))
48
+ if (!template) {
49
+ return yield* new NoSuchTemplateError({ url })
50
+ }
51
+ const [head, ...rest] = pipe(template, String.trim, String.split("{{"))
52
+ if ((!payload || !Object.keys(payload).length) && !rest.length) {
53
+ return () => template
54
+ }
55
+ const segments = rest.flatMap((part) => {
56
+ const i = part.indexOf("}}")
57
+ if (i === -1) {
58
+ return []
59
+ }
60
+ return {
61
+ key: part.slice(0, i).trim(),
62
+ tail: part.slice(i + 2),
63
+ }
64
+ })
65
+ const keys = segments.map(({ key }) => key)
66
+ if (payload) {
67
+ const keys_ = new Set(keys)
68
+ const dne = new Set<string>()
69
+ const schema = S.Struct(payload)
70
+ const fields = SchemaAST.getPropertySignatures(SchemaAST.encodedBoundAST(schema.ast))
71
+ for (const field of fields) {
72
+ if (!field.isOptional && !keys_.has(field.name.toString())) {
73
+ dne.add(field.name.toString())
74
+ }
75
+ }
76
+ if (dne.size) {
77
+ return yield* new TemplateMisalignedError({
78
+ url,
79
+ keys: [...dne.values()],
80
+ })
81
+ }
82
+ } else if (segments.length) {
83
+ return yield* new TemplateMisalignedError({ url, keys })
84
+ }
85
+ const make: Make_ = (value?) =>
86
+ value
87
+ ? head + segments.map(({ key, tail }) => `${(value as Record<typeof key, string>)[key]}${tail}`).join("")
88
+ : template
89
+ return make
90
+ }).pipe(Layer.effect(self))
91
+ self.synthesize = (...args) => self.pipe(Effect.map((make) => make(...args)))
92
+ return self as Self_
93
+ }
@@ -0,0 +1,4 @@
1
+ export * as L from "./L/L.ts"
2
+ export * as Loader from "./Loader.ts"
3
+ export * as Template from "./Template.ts"
4
+ export * from "./BranchLive.ts"
package/index.ts CHANGED
@@ -1,5 +1,9 @@
1
- export * from "./Envelope.ts"
2
- export * as default from "./L/L.ts"
3
- export * from "./LEvent.ts"
4
- export * as LPretty from "./LPretty.ts"
5
- export * from "./Thread.ts"
1
+ export * as Accumulator from "./Accumulator.ts"
2
+ export * as Actor from "./Actor.ts"
3
+ export * as Audition from "./Audition.ts"
4
+ export * as Client from "./Client.ts"
5
+ export * as ClientHandle from "./ClientHandle.ts"
6
+ export * as Method from "./Method.ts"
7
+ export * as Protocol from "./Protocol.ts"
8
+ export * from "./F.ts"
9
+ export * from "./errors.ts"
package/package.json CHANGED
@@ -1,31 +1,34 @@
1
1
  {
2
2
  "name": "liminal",
3
- "version": "0.16.0",
3
+ "version": "0.17.1",
4
+ "description": "Actors x Effects",
5
+ "bugs": {
6
+ "url": "https://github.com/crosshatch/liminal/issues"
7
+ },
8
+ "license": "Apache-2.0",
4
9
  "repository": {
5
10
  "type": "git",
6
- "url": "https://github.com/harrysolovay/liminal.git",
11
+ "url": "https://github.com/crosshatch/liminal.git",
7
12
  "directory": "liminal"
8
13
  },
9
- "peerDependencies": {
10
- "@effect/ai": "^0.25.2",
11
- "effect": "^3.17.7"
12
- },
14
+ "type": "module",
15
+ "sideEffects": false,
13
16
  "exports": {
14
- ".": "./index.ts",
15
- "./package.json": "./package.json",
16
- "./patterns/Route": "./patterns/Route.ts",
17
- "./patterns/Model": "./patterns/Model.ts",
18
- "./patterns/Debate": "./patterns/Debate.ts"
17
+ ".": {
18
+ "types": "./index.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./*": {
22
+ "types": "./*.ts",
23
+ "default": "./dist/*.js"
24
+ },
25
+ "./package.json": "./package.json"
19
26
  },
20
- "description": "An Effect AI toolkit for conversation state management.",
21
- "homepage": "https://liminal.land",
22
- "license": "Apache-2.0",
23
- "llms": "https://liminal.land/llms.txt",
24
- "llmsFull": "https://liminal.land/llmsFull.txt",
25
- "publishConfig": {
26
- "access": "public",
27
- "provenance": true
28
- },
29
- "sideEffects": false,
30
- "type": "module"
31
- }
27
+ "peerDependencies": {
28
+ "@effect-atom/atom": "^0.5.2",
29
+ "@effect/ai": "^0.33.2",
30
+ "@effect/experimental": "^0.58.0",
31
+ "@effect/platform": "^0.94.5",
32
+ "effect": "^3.19.17"
33
+ }
34
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../tsconfig.base",
3
+ "compilerOptions": {
4
+ "noEmit": false,
5
+ "outDir": "dist"
6
+ },
7
+ "include": ["."],
8
+ "exclude": ["dist"]
9
+ }
package/Envelope.ts DELETED
@@ -1,48 +0,0 @@
1
- import * as AiInput from "@effect/ai/AiInput"
2
- import * as Effect from "effect/Effect"
3
- import * as Option from "effect/Option"
4
- import { append } from "./L/append.ts"
5
- import { raw } from "./L/raw.ts"
6
- import { Self } from "./L/Self.ts"
7
- import type { Thread } from "./Thread.ts"
8
- import { type Taggable } from "./util/Taggable.ts"
9
-
10
- export interface MessageHeaders {
11
- readonly to: Array<Thread>
12
- readonly cc?: Array<Thread> | undefined
13
- readonly bcc?: Array<Thread> | undefined
14
- }
15
-
16
- export interface EnvelopeMembers {
17
- readonly headers: MessageHeaders
18
- readonly cc: (...cc: Array<Thread>) => Envelope
19
- readonly bcc: (...bcc: Array<Thread>) => Envelope
20
- }
21
-
22
- export interface Envelope extends Taggable<void, never, Thread>, EnvelopeMembers {}
23
-
24
- // TODO: cc, bcc
25
- export const Envelope = (headers: MessageHeaders): Envelope =>
26
- Object.assign(
27
- Effect.fnUntraced(function*(a0, ...aRest) {
28
- const { state: { fqn } } = yield* Self
29
- const name = Option.getOrElse(fqn, () => "anonymous-entity")
30
- const text = yield* raw(a0, ...aRest)
31
- if (!text) return
32
- const { to, cc: _cc, bcc: _bcc } = headers
33
- for (const recipient of to) {
34
- yield* append(AiInput.UserMessage.make({
35
- parts: [
36
- AiInput.TextPart.make({
37
- text: `[FROM: ${name}]\n${text}`,
38
- }),
39
- ],
40
- })).pipe(Effect.provideService(Self, recipient))
41
- }
42
- }) satisfies Taggable<void, never, Thread>,
43
- {
44
- headers,
45
- cc: (...cc) => Envelope({ ...headers, cc }),
46
- bcc: (...bcc) => Envelope({ ...headers, bcc }),
47
- } satisfies EnvelopeMembers,
48
- )
package/L/L.ts DELETED
@@ -1,21 +0,0 @@
1
- export * from "./append.ts"
2
- export * from "./assistant.ts"
3
- export * from "./assistantSchema.ts"
4
- export * from "./assistantStream.ts"
5
- export * from "./branch.ts"
6
- export * from "./clear.ts"
7
- export * from "./disable.ts"
8
- export * from "./enable.ts"
9
- export * from "./events.ts"
10
- export * from "./fqn.ts"
11
- export * from "./handle.ts"
12
- export * from "./messages.ts"
13
- export * from "./raw.ts"
14
- export * from "./Self.ts"
15
- export * from "./sequence.ts"
16
- export * from "./system.ts"
17
- export * from "./thread.ts"
18
- export * from "./to.ts"
19
- export * from "./toolkit.ts"
20
- export * from "./user.ts"
21
- export * from "./userJson.ts"
package/L/Self.ts DELETED
@@ -1,5 +0,0 @@
1
- import * as Context from "effect/Context"
2
- import type { Thread } from "../Thread.ts"
3
- import { prefix } from "../util/prefix.ts"
4
-
5
- export const Self: Context.Tag<Thread, Thread> = Context.GenericTag<Thread>(prefix("Self"))
package/L/append.ts DELETED
@@ -1,14 +0,0 @@
1
- import type { Message } from "@effect/ai/AiInput"
2
- import * as Effect from "effect/Effect"
3
- import { MessagesAppended } from "../LEvent.ts"
4
- import type { Thread } from "../Thread.ts"
5
- import { Self } from "./Self.ts"
6
-
7
- /** Append messages to the thread. */
8
- export const append: (
9
- ...messages: Array<Message>
10
- ) => Effect.Effect<void, never, Thread> = Effect.fnUntraced(function*(...messages) {
11
- const { state, events } = yield* Self
12
- state.messages.push(...messages)
13
- yield* events.publish(MessagesAppended.make({ messages }))
14
- })
package/L/assistant.ts DELETED
@@ -1,30 +0,0 @@
1
- import type { AiError } from "@effect/ai/AiError"
2
- import { AssistantMessage, TextPart } from "@effect/ai/AiInput"
3
- import { AiLanguageModel } from "@effect/ai/AiLanguageModel"
4
- import * as Effect from "effect/Effect"
5
- import * as Option from "effect/Option"
6
- import type { Thread } from "../Thread.ts"
7
- import { append } from "./append.ts"
8
- import { Self } from "./Self.ts"
9
- import { toolkit } from "./toolkit.ts"
10
-
11
- /** Infer an assistant message and append it to the thread. */
12
- export const assistant: Effect.Effect<string, AiError, AiLanguageModel | Thread> = Effect.gen(function*() {
13
- const model = yield* AiLanguageModel
14
- const { state: { system, messages: prompt } } = yield* Self
15
- let { text, results } = yield* model.generateText({
16
- system: Option.getOrUndefined(system),
17
- prompt,
18
- toolkit,
19
- })
20
- // TODO: this shouldn't be necessary. Bug in Effect AI?
21
- if (!text.trim()) {
22
- text = results.values().next().value?.result as never as string
23
- }
24
- yield* append(
25
- AssistantMessage.make({
26
- parts: [TextPart.make({ text })],
27
- }),
28
- )
29
- return text
30
- })
@@ -1,61 +0,0 @@
1
- import type { AiError } from "@effect/ai/AiError"
2
- import { AssistantMessage, TextPart } from "@effect/ai/AiInput"
3
- import { AiLanguageModel } from "@effect/ai/AiLanguageModel"
4
- import * as Effect from "effect/Effect"
5
- import * as Option from "effect/Option"
6
- import * as Schema from "effect/Schema"
7
- import * as SchemaAST from "effect/SchemaAST"
8
- import type { Thread } from "../Thread.ts"
9
- import { encodeJsonc, type JsonValue } from "../util/JsonValue.ts"
10
- import { append } from "./append.ts"
11
- import { Self } from "./Self.ts"
12
-
13
- /** Infer a structured assistant message and append its JSON representation to the conversation. */
14
- export const assistantSchema: {
15
- <F extends Record<string, Schema.Schema.AnyNoContext>>(
16
- fields: F,
17
- ): Effect.Effect<{ [K in keyof F]: Schema.Schema.Type<F[K]> }, AiError, AiLanguageModel | Thread>
18
- <O, I extends JsonValue>(
19
- schema: Schema.Schema<O, I, never>,
20
- ): Effect.Effect<O, AiError, AiLanguageModel | Thread>
21
- } = Effect.fnUntraced(function*(schema) {
22
- const model = yield* AiLanguageModel
23
- const { state: { system, messages } } = yield* Self
24
-
25
- const isSchema = Schema.isSchema(schema)
26
- const schema_ = isSchema ? schema : Schema.Struct(schema) as Schema.Schema.AnyNoContext
27
- const isObject = !isSchema || isObjectSchema(SchemaAST.encodedAST(schema.ast))
28
- const wrapped = isObject ? schema_ : Schema.Struct({ inner: schema_ })
29
-
30
- const value = yield* model.generateObject({
31
- system: Option.getOrUndefined(system),
32
- schema: wrapped,
33
- prompt: messages,
34
- }).pipe(
35
- Effect.map(({ value }) => isObject ? value : value["inner"]),
36
- )
37
-
38
- yield* append(
39
- AssistantMessage.make({
40
- parts: [
41
- TextPart.make({
42
- text: yield* encodeJsonc(schema_)(value),
43
- }),
44
- ],
45
- }),
46
- )
47
- return value
48
- })
49
-
50
- const isObjectSchema = (ast: SchemaAST.AST): boolean => {
51
- switch (ast._tag) {
52
- case "TypeLiteral": {
53
- return true
54
- }
55
- case "Refinement":
56
- case "Transformation": {
57
- return isObjectSchema(ast.from)
58
- }
59
- }
60
- return false
61
- }
@@ -1,22 +0,0 @@
1
- import type { AiError } from "@effect/ai/AiError"
2
- import { AiLanguageModel } from "@effect/ai/AiLanguageModel"
3
- import type { AiResponse } from "@effect/ai/AiResponse"
4
- import * as Effect from "effect/Effect"
5
- import * as Option from "effect/Option"
6
- import * as Stream from "effect/Stream"
7
- import type { Thread } from "../Thread.ts"
8
- import { Self } from "./Self.ts"
9
- import { toolkit } from "./toolkit.ts"
10
-
11
- /** Get a stream of an assistant message (does not append the message to the thread). */
12
- export const assistantStream: Stream.Stream<AiResponse, AiError, AiLanguageModel | Thread> = Stream.unwrap(
13
- Effect.gen(function*() {
14
- const model = yield* AiLanguageModel
15
- const { state: { system, messages: prompt } } = yield* Self
16
- return model.streamText({
17
- system: Option.getOrUndefined(system),
18
- prompt,
19
- toolkit,
20
- })
21
- }),
22
- )