liminal 0.5.12 → 0.5.13

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 (179) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/Config.ts +13 -0
  3. package/Context.ts +23 -49
  4. package/Definition.ts +32 -0
  5. package/EventBase.ts +1 -1
  6. package/Handler.ts +3 -5
  7. package/L/L.ts +5 -2
  8. package/L/all.ts +35 -0
  9. package/L/assistant.ts +5 -6
  10. package/L/catch.ts +16 -13
  11. package/L/context.ts +12 -0
  12. package/L/continuation.ts +13 -0
  13. package/L/emit.ts +10 -8
  14. package/L/infer.ts +22 -25
  15. package/L/message.ts +5 -7
  16. package/L/model.ts +6 -6
  17. package/L/reflect.ts +12 -0
  18. package/L/run.ts +29 -0
  19. package/L/strand.ts +14 -71
  20. package/L/stream.ts +11 -24
  21. package/L/system.ts +13 -8
  22. package/L/user.ts +13 -8
  23. package/LEvent.ts +9 -17
  24. package/LiminalAssertionError.ts +19 -0
  25. package/Model.ts +5 -3
  26. package/ModelRegistry.ts +1 -7
  27. package/Rune.test.ts +5 -0
  28. package/Rune.ts +24 -12
  29. package/Schema.ts +185 -0
  30. package/Strand.ts +253 -0
  31. package/Tool.ts +8 -16
  32. package/TypeAdapter.ts +3 -0
  33. package/dist/Config.d.ts +12 -0
  34. package/dist/Config.js +2 -0
  35. package/dist/Config.js.map +1 -0
  36. package/dist/Context.d.ts +11 -12
  37. package/dist/Context.js +15 -42
  38. package/dist/Context.js.map +1 -1
  39. package/dist/Definition.d.ts +10 -0
  40. package/dist/Definition.js +18 -0
  41. package/dist/Definition.js.map +1 -0
  42. package/dist/EventBase.js +1 -1
  43. package/dist/EventBase.js.map +1 -1
  44. package/dist/Handler.d.ts +3 -4
  45. package/dist/Handler.js +1 -2
  46. package/dist/Handler.js.map +1 -1
  47. package/dist/L/L.d.ts +5 -2
  48. package/dist/L/L.js +5 -2
  49. package/dist/L/L.js.map +1 -1
  50. package/dist/L/all.d.ts +10 -0
  51. package/dist/L/all.js +20 -0
  52. package/dist/L/all.js.map +1 -0
  53. package/dist/L/assistant.d.ts +2 -2
  54. package/dist/L/assistant.js +4 -5
  55. package/dist/L/assistant.js.map +1 -1
  56. package/dist/L/catch.d.ts +3 -2
  57. package/dist/L/catch.js +12 -12
  58. package/dist/L/catch.js.map +1 -1
  59. package/dist/L/context.d.ts +2 -0
  60. package/dist/L/context.js +12 -0
  61. package/dist/L/context.js.map +1 -0
  62. package/dist/L/continuation.d.ts +3 -0
  63. package/dist/L/continuation.js +12 -0
  64. package/dist/L/continuation.js.map +1 -0
  65. package/dist/L/emit.d.ts +3 -5
  66. package/dist/L/emit.js +8 -3
  67. package/dist/L/emit.js.map +1 -1
  68. package/dist/L/infer.d.ts +2 -5
  69. package/dist/L/infer.js +21 -20
  70. package/dist/L/infer.js.map +1 -1
  71. package/dist/L/message.d.ts +2 -4
  72. package/dist/L/message.js +4 -4
  73. package/dist/L/message.js.map +1 -1
  74. package/dist/L/model.d.ts +2 -4
  75. package/dist/L/model.js +4 -3
  76. package/dist/L/model.js.map +1 -1
  77. package/dist/L/reflect.d.ts +4 -0
  78. package/dist/L/reflect.js +10 -0
  79. package/dist/L/reflect.js.map +1 -0
  80. package/dist/L/run.d.ts +15 -0
  81. package/dist/L/run.js +16 -0
  82. package/dist/L/run.js.map +1 -0
  83. package/dist/L/strand.d.ts +4 -15
  84. package/dist/L/strand.js +8 -53
  85. package/dist/L/strand.js.map +1 -1
  86. package/dist/L/stream.d.ts +2 -4
  87. package/dist/L/stream.js +8 -19
  88. package/dist/L/stream.js.map +1 -1
  89. package/dist/L/system.d.ts +2 -4
  90. package/dist/L/system.js +4 -3
  91. package/dist/L/system.js.map +1 -1
  92. package/dist/L/user.d.ts +2 -4
  93. package/dist/L/user.js +4 -3
  94. package/dist/L/user.js.map +1 -1
  95. package/dist/LEvent.d.ts +13 -41
  96. package/dist/LEvent.js +4 -15
  97. package/dist/LEvent.js.map +1 -1
  98. package/dist/LiminalAssertionError.d.ts +8 -0
  99. package/dist/LiminalAssertionError.js +20 -0
  100. package/dist/LiminalAssertionError.js.map +1 -0
  101. package/dist/Model.d.ts +4 -2
  102. package/dist/Model.js +1 -1
  103. package/dist/Model.js.map +1 -1
  104. package/dist/ModelRegistry.d.ts +0 -2
  105. package/dist/ModelRegistry.js +0 -2
  106. package/dist/ModelRegistry.js.map +1 -1
  107. package/dist/Rune.d.ts +19 -7
  108. package/dist/Rune.js +8 -4
  109. package/dist/Rune.js.map +1 -1
  110. package/dist/Rune.test.d.ts +1 -0
  111. package/dist/Rune.test.js +5 -0
  112. package/dist/Rune.test.js.map +1 -0
  113. package/dist/Schema.d.ts +46 -0
  114. package/dist/Schema.js +130 -0
  115. package/dist/Schema.js.map +1 -0
  116. package/dist/Strand.d.ts +57 -0
  117. package/dist/Strand.js +177 -0
  118. package/dist/Strand.js.map +1 -0
  119. package/dist/Tool.d.ts +6 -5
  120. package/dist/Tool.js +3 -4
  121. package/dist/Tool.js.map +1 -1
  122. package/dist/TypeAdapter.d.ts +1 -0
  123. package/dist/TypeAdapter.js +3 -0
  124. package/dist/TypeAdapter.js.map +1 -0
  125. package/dist/errors.d.ts +9 -0
  126. package/dist/errors.js +11 -0
  127. package/dist/errors.js.map +1 -0
  128. package/dist/index.d.ts +6 -5
  129. package/dist/index.js +6 -5
  130. package/dist/index.js.map +1 -1
  131. package/dist/tsconfig.tsbuildinfo +1 -1
  132. package/dist/util/EnsureNarrow.d.ts +1 -0
  133. package/dist/util/EnsureNarrow.js +2 -0
  134. package/dist/util/EnsureNarrow.js.map +1 -0
  135. package/dist/util/JSONValue.d.ts +8 -0
  136. package/dist/util/JSONValue.js +20 -0
  137. package/dist/util/JSONValue.js.map +1 -0
  138. package/dist/util/attachCustomInspect.d.ts +1 -0
  139. package/dist/util/attachCustomInspect.js +11 -0
  140. package/dist/util/attachCustomInspect.js.map +1 -0
  141. package/dist/util/isTemplateStringsArray.d.ts +1 -0
  142. package/dist/util/isTemplateStringsArray.js +4 -0
  143. package/dist/util/isTemplateStringsArray.js.map +1 -0
  144. package/errors.ts +12 -0
  145. package/index.ts +6 -5
  146. package/package.json +3 -10
  147. package/tsconfig.json +1 -5
  148. package/util/EnsureNarrow.ts +1 -0
  149. package/util/JSONValue.ts +20 -0
  150. package/util/attachCustomInspect.ts +14 -0
  151. package/util/isTemplateStringsArray.ts +3 -0
  152. package/Fiber.ts +0 -123
  153. package/L/_common.ts +0 -6
  154. package/L/rune.ts +0 -12
  155. package/MessageRegistry.ts +0 -22
  156. package/Runic.ts +0 -30
  157. package/StrandConfig.ts +0 -12
  158. package/ToolRegistry.ts +0 -10
  159. package/dist/Fiber.d.ts +0 -35
  160. package/dist/Fiber.js +0 -95
  161. package/dist/Fiber.js.map +0 -1
  162. package/dist/L/_common.d.ts +0 -4
  163. package/dist/L/_common.js +0 -7
  164. package/dist/L/_common.js.map +0 -1
  165. package/dist/L/rune.d.ts +0 -3
  166. package/dist/L/rune.js +0 -9
  167. package/dist/L/rune.js.map +0 -1
  168. package/dist/MessageRegistry.d.ts +0 -9
  169. package/dist/MessageRegistry.js +0 -15
  170. package/dist/MessageRegistry.js.map +0 -1
  171. package/dist/Runic.d.ts +0 -9
  172. package/dist/Runic.js +0 -18
  173. package/dist/Runic.js.map +0 -1
  174. package/dist/StrandConfig.d.ts +0 -11
  175. package/dist/StrandConfig.js +0 -2
  176. package/dist/StrandConfig.js.map +0 -1
  177. package/dist/ToolRegistry.d.ts +0 -6
  178. package/dist/ToolRegistry.js +0 -8
  179. package/dist/ToolRegistry.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # liminal
2
2
 
3
+ ## 0.5.13
4
+
5
+ ### Patch Changes
6
+
7
+ - bbd0e74: Liminal schema and util now exist within the liminal package itself. Runtime type compatibility changes.
8
+
3
9
  ## 0.5.12
4
10
 
5
11
  ### Patch Changes
package/Config.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { Message } from "./Message.ts"
2
+ import { ModelRegistry } from "./ModelRegistry.ts"
3
+ import type { Rune } from "./Rune.ts"
4
+ import type { Strand } from "./Strand.ts"
5
+ import type { Tool } from "./Tool.ts"
6
+
7
+ export interface Config<Y extends Rune<any> = Rune<any>, T = any> {
8
+ handler?: ((this: Strand<Y, T>, event: Rune.E<Y>) => void) | undefined
9
+ models?: ModelRegistry | undefined
10
+ messages?: Array<Message>
11
+ tools?: Set<Tool> | undefined
12
+ signal?: AbortSignal | undefined
13
+ }
package/Context.ts CHANGED
@@ -1,58 +1,32 @@
1
- import { assert } from "liminal-util"
2
- import { AsyncLocalStorage } from "node:async_hooks"
1
+ import type { Handler } from "./Handler.ts"
2
+ import type { Message } from "./Message.ts"
3
+ import { ModelRegistry } from "./ModelRegistry.ts"
4
+ import type { Tool } from "./Tool.ts"
3
5
 
4
- const storage = new AsyncLocalStorage<Context>()
6
+ export interface Context {
7
+ readonly handler: Handler | undefined
8
+ readonly models: ModelRegistry
9
+ readonly messages: Array<Message>
10
+ readonly tools: Set<Tool>
5
11
 
6
- export class Context extends Map<ContextPart, unknown> {
7
- static get(): Context | undefined {
8
- return storage.getStore()
9
- }
10
-
11
- static ensure(): Context {
12
- const current = Context.get()
13
- assert(current)
14
- return current
15
- }
16
-
17
- run<R>(f: () => R): R {
18
- return storage.run(this, f)
19
- }
20
-
21
- fork(): Context {
22
- const context = new Context()
23
- for (const [handle, value] of this.entries()) {
24
- if (!context.has(handle)) {
25
- context.set(handle, handle.fork(value))
26
- }
27
- }
28
- return context
29
- }
12
+ clone(): Context
30
13
  }
31
14
 
32
- export interface ContextPart<V = any> {
33
- fork(parent?: V): V
34
- get(): V | undefined
35
- getOrInit(): V
36
- debug?: string
37
- }
15
+ export function Context(context?: Omit<Context, "clone">): Context {
16
+ return {
17
+ handler: context?.handler,
18
+ models: context?.models.clone() ?? new ModelRegistry(),
19
+ messages: [],
20
+ tools: new Set(context?.tools),
38
21
 
39
- export function ContextPart<V>(fork: (parent?: V) => V, debug?: string): ContextPart<V> {
40
- const self: ContextPart<V> = {
41
- fork,
42
- get() {
43
- return Context.get()?.get(self) as never
44
- },
45
- getOrInit() {
46
- const context = Context.get()
47
- assert(context)
48
- let value = context.get(this)
49
- if (!value) {
50
- value = this.fork()
51
- context.set(this, value)
22
+ clone(): Context {
23
+ return {
24
+ handler: this.handler,
25
+ models: this.models.clone(),
26
+ messages: [...this.messages],
27
+ tools: new Set(this.tools),
28
+ clone: this.clone,
52
29
  }
53
- return value as never
54
30
  },
55
- ...debug && { debug },
56
31
  }
57
- return self
58
32
  }
package/Definition.ts ADDED
@@ -0,0 +1,32 @@
1
+ import type { Rune } from "./Rune.ts"
2
+
3
+ export type RuneIterator<Y extends Rune<any> = Rune<any>, T = any> = Iterator<Y, T> | AsyncIterator<Y, T>
4
+ export type RuneIterable<Y extends Rune<any> = Rune<any>, T = any> = Iterable<Y, T> | AsyncIterable<Y, T>
5
+ export type Definition<Y extends Rune<any> = Rune<any>, T = any> = RuneIterable<Y, T> | (() => RuneIterable<Y, T>)
6
+
7
+ export namespace Definition {
8
+ export type Y<X extends Definition> = X extends RuneIterable<infer Y> ? Y
9
+ : X extends () => RuneIterable<infer Y> ? Y
10
+ : X extends RuneIterator<infer Y> ? Y
11
+ : never
12
+
13
+ export type T<X extends Definition> = X extends RuneIterable<Rune<any>, infer T> ? T
14
+ : X extends () => RuneIterable<Rune<any>, infer T> ? T
15
+ : X extends RuneIterator<Rune<any>, infer T> ? T
16
+ : never
17
+
18
+ export type E<X extends Definition> = Rune.E<Y<X>>
19
+
20
+ export function unwrap<Y extends Rune<any>, T>(definition: Definition<Y, T>): RuneIterator<Y, T> {
21
+ if (Symbol.iterator in definition) {
22
+ return definition[Symbol.iterator]()
23
+ } else if (Symbol.asyncIterator in definition) {
24
+ return definition[Symbol.asyncIterator]()
25
+ }
26
+ const iterable = definition()
27
+ if (Symbol.iterator in iterable) {
28
+ return iterable[Symbol.iterator]()
29
+ }
30
+ return iterable[Symbol.asyncIterator]()
31
+ }
32
+ }
package/EventBase.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { attachCustomInspect } from "liminal-util"
1
+ import { attachCustomInspect } from "./util/attachCustomInspect.ts"
2
2
 
3
3
  export interface EventBase<B extends symbol = symbol, K extends string = string> {
4
4
  readonly brand: B
package/Handler.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { ContextPart as ContextPart } from "./Context.ts"
2
- import type { Fiber } from "./Fiber.ts"
1
+ import type { Rune } from "./Rune.ts"
2
+ import type { Strand } from "./Strand.ts"
3
3
 
4
- export type Handler<E = any> = [(this: Fiber, event: E) => void][0]
5
-
6
- export const HandlerContext: ContextPart<Handler | undefined> = ContextPart((parent) => parent, "handler")
4
+ export type Handler<Y extends Rune<any> = Rune<any>> = (this: Strand, event: Rune.E<Y>) => void
package/L/L.ts CHANGED
@@ -1,11 +1,14 @@
1
- export * from "liminal-schema/factories"
1
+ export * from "./all.ts"
2
2
  export * from "./assistant.ts"
3
3
  export * from "./catch.ts"
4
+ export * from "./context.ts"
5
+ export * from "./continuation.ts"
4
6
  export * from "./emit.ts"
5
7
  export * from "./infer.ts"
6
8
  export * from "./message.ts"
7
9
  export * from "./model.ts"
8
- export * from "./rune.ts"
10
+ export * from "./reflect.ts"
11
+ export * from "./run.ts"
9
12
  export * from "./strand.ts"
10
13
  export * from "./stream.ts"
11
14
  export * from "./system.ts"
package/L/all.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { Context } from "../Context.ts"
2
+ import { Definition } from "../Definition.ts"
3
+ import type { LEvent } from "../LEvent.ts"
4
+ import type { Rune } from "../Rune.ts"
5
+ import { Strand } from "../Strand.ts"
6
+ import { continuation } from "./continuation.ts"
7
+ import { reflect } from "./reflect.ts"
8
+
9
+ export function all<A extends Array<Definition>>(
10
+ definitions: A,
11
+ context?: Context,
12
+ ): Generator<Rune<LEvent> | Definition.Y<A[number]>, { [I in keyof A]: Definition.T<A[I]> }>
13
+ export function all<A extends Record<keyof any, Definition>>(
14
+ definitions: A,
15
+ context?: Context,
16
+ ): Generator<Rune<LEvent> | Definition.Y<A[keyof A]>, { [K in keyof A]: Definition.T<A[K]> }>
17
+ export function* all<A extends Array<Definition> | Record<keyof any, Definition>>(
18
+ definitions: A,
19
+ context?: Context,
20
+ ): Generator<Rune<any>, any> { // TODO: although it's somewhat irrelevant, type this
21
+ const parent = yield* reflect
22
+ const strands: Array<Strand> = []
23
+ for (const definition of Array.isArray(definitions) ? definitions : Object.values(definitions)) {
24
+ strands.push(
25
+ new Strand(definition, {
26
+ parent,
27
+ context: context?.clone() ?? parent.context.clone(),
28
+ }),
29
+ )
30
+ }
31
+ const results = yield* continuation("all", () => Promise.all(strands))
32
+ if (Array.isArray(strands)) return results
33
+ const keys = Object.keys(strands)
34
+ return Object.fromEntries(results.map((result, i) => [keys[i], result]))
35
+ }
package/L/assistant.ts CHANGED
@@ -1,21 +1,20 @@
1
- import { type LType, toJSONSchema, validate } from "liminal-schema"
2
1
  import type { LEvent } from "../LEvent.ts"
3
2
  import type { Rune } from "../Rune.ts"
3
+ import { Schema } from "../Schema.ts"
4
+ import { continuation } from "./continuation.ts"
4
5
  import { infer } from "./infer.ts"
5
6
  import { message } from "./message.ts"
6
- import { rune } from "./rune.ts"
7
7
 
8
8
  export interface assistant extends Iterable<Rune<LEvent>, string> {
9
- <T>(type: LType<T>): Generator<Rune<LEvent>, T>
9
+ <T>(schema: Schema<T>): Generator<Rune<LEvent>, T>
10
10
  }
11
11
 
12
12
  export const assistant: assistant = Object.assign(
13
- function*<T>(type: LType<T>): Generator<Rune<LEvent>, T> {
14
- const schema = toJSONSchema(type)
13
+ function* assistant<T>(schema: Schema<T>): Generator<Rune<LEvent>, T> {
15
14
  const inference = yield* infer(schema)
16
15
  yield* message("assistant", [{ part: inference }])
17
16
  const input = JSON.parse(inference)
18
- return yield* rune(() => validate(type, input), "validate_assistant_message")
17
+ return yield* continuation("validate_assistant_message", () => Schema.validateValue(schema, input))
19
18
  },
20
19
  {
21
20
  *[Symbol.iterator]() {
package/L/catch.ts CHANGED
@@ -1,24 +1,27 @@
1
- import { assert } from "liminal-util"
2
- import { Context } from "../Context.ts"
3
- import { Fiber } from "../Fiber.ts"
1
+ import type { Definition } from "../Definition.ts"
2
+ import type { LEvent } from "../LEvent.ts"
4
3
  import type { Rune } from "../Rune.ts"
5
- import type { Runic } from "../Runic.ts"
6
- import { rune } from "./rune.ts"
4
+ import { Strand } from "../Strand.ts"
5
+ import { continuation } from "./continuation.ts"
6
+ import { reflect } from "./reflect.ts"
7
7
 
8
8
  export { catch_ as catch }
9
9
 
10
- function* catch_<Y extends Rune, T>(runic: Runic<Y, T>): Generator<Rune<Y>, CatchResult<T>> {
11
- return yield* rune(async (parent) => {
10
+ function* catch_<Y extends Rune<any>, T>(
11
+ definition: Definition<Y, T>,
12
+ ): Generator<Rune<LEvent> | Rune<Y>, CatchResult<T>> {
13
+ const parent = yield* reflect
14
+ return yield* continuation("catch", async () => {
12
15
  try {
13
- const context = Context.get()
14
- assert(context)
15
- return {
16
- resolved: await context.fork().run(() => new Fiber(runic, { parent }).resolution()),
17
- }
16
+ const resolved = await new Strand(definition, {
17
+ parent,
18
+ context: parent.context.clone(),
19
+ }).then()
20
+ return { resolved }
18
21
  } catch (exception: unknown) {
19
22
  return { rejected: exception }
20
23
  }
21
- }, "catch")
24
+ })
22
25
  }
23
26
  Object.defineProperty(catch_, "name", { value: "catch" })
24
27
 
package/L/context.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Context } from "../Context.ts"
2
+ import { reflect } from "./reflect.ts"
3
+
4
+ export function* context(partial: Partial<Omit<Context, "clone">>) {
5
+ const { context } = yield* reflect
6
+ return Context({
7
+ handler: partial.handler ?? context.handler,
8
+ messages: partial.messages ?? context.messages,
9
+ models: partial.models ?? context.models,
10
+ tools: partial.tools ?? context.tools,
11
+ })
12
+ }
@@ -0,0 +1,13 @@
1
+ import type { LEvent } from "../LEvent.ts"
2
+ import { Rune, RuneKey } from "../Rune.ts"
3
+
4
+ export function* continuation<R>(debug: string, f: () => R): Generator<Rune<LEvent>, Awaited<R>> {
5
+ return yield {
6
+ [RuneKey]: true,
7
+ value: {
8
+ kind: "continuation",
9
+ debug,
10
+ f,
11
+ },
12
+ }
13
+ }
package/L/emit.ts CHANGED
@@ -1,10 +1,12 @@
1
- import type { EnsureNarrow } from "liminal-util"
2
- import { Fiber } from "../Fiber.ts"
3
- import type { Rune } from "../Rune.ts"
1
+ import { Rune, RuneKey } from "../Rune.ts"
2
+ import type { EnsureNarrow } from "../util/EnsureNarrow.ts"
4
3
 
5
- export interface emit<E> extends Generator<Rune<E>, void> {}
6
-
7
- export function* emit<const E>(event: EnsureNarrow<E>): emit<E> {
8
- const self = yield* Fiber
9
- self.handle(event)
4
+ export function* emit<E>(event: EnsureNarrow<E>): Generator<Rune<E>, void> {
5
+ return yield {
6
+ [RuneKey]: true,
7
+ value: {
8
+ kind: "event",
9
+ event,
10
+ },
11
+ }
10
12
  }
package/L/infer.ts CHANGED
@@ -1,33 +1,30 @@
1
- import type { SchemaObject } from "liminal-schema"
2
- import { assert } from "liminal-util"
3
1
  import { InferenceRequested, Inferred, type LEvent } from "../LEvent.ts"
4
- import { MessageRegistryContext } from "../MessageRegistry.ts"
5
- import { ModelRegistryContext } from "../ModelRegistry.ts"
2
+ import { LiminalAssertionError } from "../LiminalAssertionError.ts"
6
3
  import type { Rune } from "../Rune.ts"
7
- import { RequestCounter } from "./_common.ts"
4
+ import { Schema } from "../Schema.ts"
5
+ import { continuation } from "./continuation.ts"
8
6
  import { emit } from "./emit.ts"
9
- import { rune } from "./rune.ts"
7
+ import { reflect } from "./reflect.ts"
10
8
 
11
- export { infer_ as infer }
12
-
13
- interface infer_ extends Generator<Rune<LEvent>, string> {}
14
-
15
- function* infer_(schema?: SchemaObject): infer_ {
16
- const modelRegistry = ModelRegistryContext.getOrInit()
17
- const model = modelRegistry.peek()
18
- assert(model)
19
- const requestId = RequestCounter.next()
9
+ export function* infer(schema?: Schema): Generator<Rune<LEvent>, string> {
10
+ const { context: { models, messages }, signal } = yield* reflect
11
+ const model = models.peek()
12
+ LiminalAssertionError.assert(model)
13
+ const requestId = crypto.randomUUID()
20
14
  yield* emit(new InferenceRequested(requestId, schema))
21
- const messageRegistry = MessageRegistryContext.getOrInit()
22
- const inference = yield* rune((fiber) =>
23
- model
24
- .seal({
25
- messages: messageRegistry.messages,
26
- schema,
27
- signal: fiber.controller.signal,
28
- })
29
- .resolve(), "infer")
15
+ let inference = yield* continuation("infer", () =>
16
+ model.seal({
17
+ messages,
18
+ schema: schema
19
+ ? schema.type === "object"
20
+ ? schema
21
+ : Schema.wrap(schema)
22
+ : undefined,
23
+ signal,
24
+ }).resolve())
25
+ if (schema?.type && schema.type !== "object") {
26
+ inference = JSON.stringify(JSON.parse(inference).value)
27
+ }
30
28
  yield* emit(new Inferred(requestId, inference))
31
29
  return inference
32
30
  }
33
- Object.defineProperty(infer_, "name", { value: "infer" })
package/L/message.ts CHANGED
@@ -1,14 +1,12 @@
1
- import { type LEvent, MessageAppended } from "../LEvent.ts"
1
+ import { LEvent, MessageAppended } from "../LEvent.ts"
2
2
  import type { ContentPart, Message, MessageRole } from "../Message.ts"
3
- import { MessageRegistryContext } from "../MessageRegistry.ts"
4
3
  import type { Rune } from "../Rune.ts"
5
4
  import { emit } from "./emit.ts"
5
+ import { reflect } from "./reflect.ts"
6
6
 
7
- export interface message extends Generator<Rune<LEvent>, void> {}
8
-
9
- export function* message(role: MessageRole, content: Array<ContentPart>): message {
10
- const messageRegistry = MessageRegistryContext.getOrInit()
7
+ export function* message(role: MessageRole, content: Array<ContentPart>): Generator<Rune<LEvent>, void> {
8
+ const { context: { messages } } = yield* reflect
11
9
  const message: Message = { role, content }
12
10
  yield* emit(new MessageAppended(message))
13
- messageRegistry.append(message)
11
+ messages.push(message)
14
12
  }
package/L/model.ts CHANGED
@@ -1,13 +1,13 @@
1
+ import type { LEvent } from "../LEvent.ts"
1
2
  import { ModelRegistered } from "../LEvent.ts"
2
3
  import type { Model } from "../Model.ts"
3
- import { ModelRegistryContext } from "../ModelRegistry.ts"
4
4
  import type { Rune } from "../Rune.ts"
5
5
  import { emit } from "./emit.ts"
6
+ import { reflect } from "./reflect.ts"
6
7
 
7
- export interface model extends Generator<Rune<ModelRegistered>, void> {}
8
-
9
- export function* model(model: Model): model {
10
- const registry = ModelRegistryContext.getOrInit()
11
- registry.register(model)
8
+ export function* model(model: Model): Generator<Rune<LEvent>, Model> {
9
+ const { context: { models } } = yield* reflect
10
+ models.register(model)
12
11
  yield* emit(new ModelRegistered(model))
12
+ return model
13
13
  }
package/L/reflect.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { LEvent } from "../LEvent.ts"
2
+ import { Rune, RuneKey } from "../Rune.ts"
3
+ import type { Strand } from "../Strand.ts"
4
+
5
+ export const reflect: Iterable<Rune<LEvent>, Strand> = {
6
+ *[Symbol.iterator]() {
7
+ return yield {
8
+ [RuneKey]: true,
9
+ value: { kind: "reflect" },
10
+ }
11
+ },
12
+ }
package/L/run.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { Context } from "../Context.ts"
2
+ import type { Definition } from "../Definition.ts"
3
+ import type { Handler } from "../Handler.ts"
4
+ import type { Message } from "../Message.ts"
5
+ import { ModelRegistry } from "../ModelRegistry.ts"
6
+ import type { Rune } from "../Rune.ts"
7
+ import { Strand } from "../Strand.ts"
8
+ import type { Tool } from "../Tool.ts"
9
+
10
+ export interface RunConfig<Y extends Rune<any>> {
11
+ handler?: Handler<Y> | undefined
12
+ models?: ModelRegistry | undefined
13
+ messages?: Array<Message> | undefined
14
+ tools?: Set<Tool> | undefined
15
+ signal?: AbortSignal | undefined
16
+ }
17
+
18
+ export function run<Y extends Rune<any>, T>(definition: Definition<Y, T>, config?: RunConfig<Y>): Strand {
19
+ const context = Context({
20
+ handler: config?.handler,
21
+ models: config?.models ?? new ModelRegistry(),
22
+ messages: config?.messages ?? [],
23
+ tools: config?.tools ?? new Set(),
24
+ })
25
+ return new Strand(definition, {
26
+ signal: config?.signal,
27
+ ...config && { context },
28
+ })
29
+ }
package/L/strand.ts CHANGED
@@ -1,75 +1,18 @@
1
- import { assert, isIterableLike } from "liminal-util"
2
- import { Context } from "../Context.ts"
3
- import { Fiber } from "../Fiber.ts"
4
- import { HandlerContext } from "../Handler.ts"
5
- import { MessageRegistry, MessageRegistryContext } from "../MessageRegistry.ts"
6
- import { ModelRegistry, ModelRegistryContext } from "../ModelRegistry.ts"
7
- import { type Rune } from "../Rune.ts"
8
- import { Runic } from "../Runic.ts"
9
- import type { StrandConfig } from "../StrandConfig.ts"
10
- import { ToolRegistry, ToolRegistryContext } from "../ToolRegistry.ts"
11
- import { rune } from "./rune.ts"
1
+ import type { Context } from "../Context.ts"
2
+ import type { Definition } from "../Definition.ts"
3
+ import type { LEvent } from "../LEvent.ts"
4
+ import { type Rune, RuneKey } from "../Rune.ts"
12
5
 
13
- export interface strand<Y extends Rune, T> extends Iterable<Y, T>, PromiseLike<T> {}
14
-
15
- export function strand<X extends Runic>(
16
- runic: X,
17
- config?: StrandConfig<Runic.T<X>, Rune.E<Runic.Y<X>>>,
18
- ): strand<Runic.Y<X>, Runic.T<X>>
19
- export function strand<XA extends Array<Runic>>(
20
- runics: XA,
21
- config?: StrandConfig<{ [I in keyof XA]: Runic.T<XA[I]> }, Rune.E<Runic.Y<XA[number]>>>,
22
- ): strand<Runic.Y<XA[number]> | Rune<never>, { [I in keyof XA]: Runic.T<XA[I]> }>
23
- export function strand<XR extends Record<keyof any, Runic>>(
24
- runics: XR,
25
- config?: StrandConfig<{ [K in keyof XR]: Runic.T<XR[K]> }, Rune.E<Runic.Y<XR[keyof XR]>>>,
26
- ): strand<Runic.Y<XR[keyof XR]> | Rune<never>, { [K in keyof XR]: Runic.T<XR[K]> }>
27
- export function strand(
28
- value: Runic | Array<Runic> | Record<keyof any, Runic>,
29
- config?: StrandConfig,
30
- ): strand<Rune, any> {
31
- return {
32
- *[Symbol.iterator](): Generator<Rune, any> {
33
- const parent = yield* Fiber
34
- if (Array.isArray(value)) {
35
- const fibers = value.map((runic) => context().run(() => new Fiber(runic, { parent })))
36
- return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.resolution())), "strand")
37
- } else if (typeof value === "object" && !isIterableLike(value)) {
38
- const fibers = Object.values(value).map((runic) => context().run(() => new Fiber(runic, { parent })))
39
- return yield* rune(() => {
40
- const keys = Object.keys(value)
41
- return Promise
42
- .all(fibers.map((fiber) => fiber.resolution()))
43
- .then((resolved) => resolved.map((value, i) => [keys[i], value]))
44
- .then(Object.fromEntries)
45
- }, "strand")
46
- }
47
- const fiber = context().run(() => new Fiber(value, { parent }))
48
- return yield* rune(() => fiber.resolution(), "strand")
49
- },
50
- then(onfulfilled, onrejected) {
51
- return new Fiber(this).resolution().then(onfulfilled, onrejected)
6
+ export function* strand<Y extends Rune<any>, T>(
7
+ definition: Definition<Y, T>,
8
+ context?: Context,
9
+ ): Generator<Rune<LEvent>, T> {
10
+ return yield {
11
+ [RuneKey]: true,
12
+ value: {
13
+ kind: "child",
14
+ definition,
15
+ context,
52
16
  },
53
17
  }
54
-
55
- function context() {
56
- const current = Context.get()
57
- assert(current)
58
- const context = current.fork()
59
- if (config) {
60
- if ("handler" in config) {
61
- context.set(HandlerContext, config.handler)
62
- }
63
- if ("models" in config) {
64
- context.set(ModelRegistryContext, config.models?.clone() ?? new ModelRegistry())
65
- }
66
- if ("messages" in config) {
67
- context.set(MessageRegistryContext, config.messages?.clone() ?? new MessageRegistry())
68
- }
69
- if ("tools" in config) {
70
- context.set(ToolRegistryContext, config.tools?.clone() ?? new ToolRegistry())
71
- }
72
- }
73
- return context
74
- }
75
18
  }
package/L/stream.ts CHANGED
@@ -1,30 +1,17 @@
1
- import { assert } from "liminal-util"
2
1
  import { InferenceRequested, type LEvent } from "../LEvent.ts"
3
- import { MessageRegistryContext } from "../MessageRegistry.ts"
4
- import { ModelRegistryContext } from "../ModelRegistry.ts"
5
- import { type Rune } from "../Rune.ts"
6
- import { RequestCounter } from "./_common.ts"
2
+ import { LiminalAssertionError } from "../LiminalAssertionError.ts"
3
+ import type { Rune } from "../Rune.ts"
4
+ import { continuation } from "./continuation.ts"
7
5
  import { emit } from "./emit.ts"
8
- import { rune } from "./rune.ts"
6
+ import { reflect } from "./reflect.ts"
9
7
 
10
- export interface stream extends Iterable<Rune<LEvent>, ReadableStream<string>> {}
11
-
12
- export const stream: stream = {
13
- *[Symbol.iterator](): Generator<Rune<LEvent>, ReadableStream<string>> {
14
- const modelRegistry = ModelRegistryContext.get()
15
- assert(modelRegistry)
16
- const model = modelRegistry.peek()
17
- assert(model)
18
- const requestId = RequestCounter.next()
8
+ export const stream: Iterable<Rune<LEvent>, ReadableStream<string>> = {
9
+ *[Symbol.iterator]() {
10
+ const { context: { models, messages }, signal } = yield* reflect
11
+ const model = models.peek()
12
+ LiminalAssertionError.assert(model)
13
+ const requestId = crypto.randomUUID()
19
14
  yield* emit(new InferenceRequested(requestId))
20
- const messageRegistry = MessageRegistryContext.get()
21
- assert(messageRegistry)
22
- return yield* rune((fiber) =>
23
- model
24
- .seal({
25
- messages: messageRegistry.messages,
26
- signal: fiber.controller.signal,
27
- })
28
- .stream(), "stream")
15
+ return yield* continuation("stream", () => model.seal({ messages, signal }).stream())
29
16
  },
30
17
  }
package/L/system.ts CHANGED
@@ -1,13 +1,18 @@
1
- import { isTemplateStringsArray } from "liminal-util"
2
1
  import type { LEvent } from "../LEvent.ts"
3
2
  import type { Rune } from "../Rune.ts"
3
+ import { isTemplateStringsArray } from "../util/isTemplateStringsArray.ts"
4
4
  import { message } from "./message.ts"
5
5
 
6
- export interface system extends Generator<Rune<LEvent>, void> {}
7
-
8
- export function system(template: TemplateStringsArray, ...substitutions: Array<number | string>): system
9
- export function system(value: string): system
10
- export function system(e0: TemplateStringsArray | string, ...rest: Array<number | string>): system {
11
- const part = isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0
12
- return message("system", [{ part }])
6
+ export function system(
7
+ template: TemplateStringsArray,
8
+ ...substitutions: Array<number | string>
9
+ ): Generator<Rune<LEvent>, void>
10
+ export function system(value: string): Generator<Rune<LEvent>, void>
11
+ export function system(
12
+ e0: TemplateStringsArray | string,
13
+ ...rest: Array<number | string>
14
+ ): Generator<Rune<LEvent>, void> {
15
+ return message("system", [{
16
+ part: isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0,
17
+ }])
13
18
  }