liminal 0.5.12 → 0.5.14

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 (225) hide show
  1. package/CHANGELOG.md +12 -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 +15 -2
  8. package/L/all.ts +35 -0
  9. package/L/assistant.ts +4 -7
  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 +7 -9
  16. package/L/model.ts +6 -6
  17. package/L/reflect.ts +12 -0
  18. package/L/run.ts +29 -0
  19. package/L/schema/_schema_common.ts +29 -0
  20. package/L/schema/anyOf.ts +10 -0
  21. package/L/schema/array.ts +13 -0
  22. package/L/schema/boolean.ts +8 -0
  23. package/L/schema/const.ts +18 -0
  24. package/L/schema/enum.ts +18 -0
  25. package/L/schema/integer.ts +6 -0
  26. package/L/schema/null.ts +8 -0
  27. package/L/schema/number.ts +8 -0
  28. package/L/schema/object.ts +21 -0
  29. package/L/schema/string.ts +11 -0
  30. package/L/strand.ts +14 -71
  31. package/L/stream.ts +11 -24
  32. package/L/system.ts +13 -8
  33. package/L/user.ts +13 -8
  34. package/LEvent.ts +9 -17
  35. package/LiminalAssertionError.ts +19 -0
  36. package/Message.ts +3 -2
  37. package/Model.ts +5 -3
  38. package/ModelRegistry.ts +1 -7
  39. package/Rune.test.ts +5 -0
  40. package/Rune.ts +24 -12
  41. package/Schema.ts +185 -0
  42. package/Strand.ts +253 -0
  43. package/Tool.ts +8 -16
  44. package/TypeAdapter.ts +3 -0
  45. package/dist/Config.d.ts +12 -0
  46. package/dist/Config.js +2 -0
  47. package/dist/Config.js.map +1 -0
  48. package/dist/Context.d.ts +11 -12
  49. package/dist/Context.js +15 -42
  50. package/dist/Context.js.map +1 -1
  51. package/dist/Definition.d.ts +10 -0
  52. package/dist/Definition.js +18 -0
  53. package/dist/Definition.js.map +1 -0
  54. package/dist/EventBase.js +1 -1
  55. package/dist/EventBase.js.map +1 -1
  56. package/dist/Handler.d.ts +3 -4
  57. package/dist/Handler.js +1 -2
  58. package/dist/Handler.js.map +1 -1
  59. package/dist/L/L.d.ts +15 -2
  60. package/dist/L/L.js +15 -2
  61. package/dist/L/L.js.map +1 -1
  62. package/dist/L/all.d.ts +10 -0
  63. package/dist/L/all.js +20 -0
  64. package/dist/L/all.js.map +1 -0
  65. package/dist/L/assistant.d.ts +2 -2
  66. package/dist/L/assistant.js +3 -6
  67. package/dist/L/assistant.js.map +1 -1
  68. package/dist/L/catch.d.ts +3 -2
  69. package/dist/L/catch.js +12 -12
  70. package/dist/L/catch.js.map +1 -1
  71. package/dist/L/context.d.ts +2 -0
  72. package/dist/L/context.js +12 -0
  73. package/dist/L/context.js.map +1 -0
  74. package/dist/L/continuation.d.ts +3 -0
  75. package/dist/L/continuation.js +12 -0
  76. package/dist/L/continuation.js.map +1 -0
  77. package/dist/L/emit.d.ts +3 -5
  78. package/dist/L/emit.js +8 -3
  79. package/dist/L/emit.js.map +1 -1
  80. package/dist/L/infer.d.ts +2 -5
  81. package/dist/L/infer.js +21 -20
  82. package/dist/L/infer.js.map +1 -1
  83. package/dist/L/message.d.ts +3 -5
  84. package/dist/L/message.js +5 -5
  85. package/dist/L/message.js.map +1 -1
  86. package/dist/L/model.d.ts +2 -4
  87. package/dist/L/model.js +4 -3
  88. package/dist/L/model.js.map +1 -1
  89. package/dist/L/reflect.d.ts +4 -0
  90. package/dist/L/reflect.js +10 -0
  91. package/dist/L/reflect.js.map +1 -0
  92. package/dist/L/run.d.ts +15 -0
  93. package/dist/L/run.js +16 -0
  94. package/dist/L/run.js.map +1 -0
  95. package/dist/L/schema/_schema_common.d.ts +6 -0
  96. package/dist/L/schema/_schema_common.js +19 -0
  97. package/dist/L/schema/_schema_common.js.map +1 -0
  98. package/dist/L/schema/anyOf.d.ts +5 -0
  99. package/dist/L/schema/anyOf.js +5 -0
  100. package/dist/L/schema/anyOf.js.map +1 -0
  101. package/dist/L/schema/array.d.ts +5 -0
  102. package/dist/L/schema/array.js +8 -0
  103. package/dist/L/schema/array.js.map +1 -0
  104. package/dist/L/schema/boolean.d.ts +6 -0
  105. package/dist/L/schema/boolean.js +4 -0
  106. package/dist/L/schema/boolean.js.map +1 -0
  107. package/dist/L/schema/const.d.ts +8 -0
  108. package/dist/L/schema/const.js +10 -0
  109. package/dist/L/schema/const.js.map +1 -0
  110. package/dist/L/schema/enum.d.ts +8 -0
  111. package/dist/L/schema/enum.js +10 -0
  112. package/dist/L/schema/enum.js.map +1 -0
  113. package/dist/L/schema/integer.d.ts +5 -0
  114. package/dist/L/schema/integer.js +3 -0
  115. package/dist/L/schema/integer.js.map +1 -0
  116. package/dist/L/schema/null.d.ts +6 -0
  117. package/dist/L/schema/null.js +4 -0
  118. package/dist/L/schema/null.js.map +1 -0
  119. package/dist/L/schema/number.d.ts +6 -0
  120. package/dist/L/schema/number.js +4 -0
  121. package/dist/L/schema/number.js.map +1 -0
  122. package/dist/L/schema/object.d.ts +9 -0
  123. package/dist/L/schema/object.js +12 -0
  124. package/dist/L/schema/object.js.map +1 -0
  125. package/dist/L/schema/string.d.ts +8 -0
  126. package/dist/L/schema/string.js +4 -0
  127. package/dist/L/schema/string.js.map +1 -0
  128. package/dist/L/strand.d.ts +4 -15
  129. package/dist/L/strand.js +8 -53
  130. package/dist/L/strand.js.map +1 -1
  131. package/dist/L/stream.d.ts +2 -4
  132. package/dist/L/stream.js +8 -19
  133. package/dist/L/stream.js.map +1 -1
  134. package/dist/L/system.d.ts +2 -4
  135. package/dist/L/system.js +4 -3
  136. package/dist/L/system.js.map +1 -1
  137. package/dist/L/user.d.ts +2 -4
  138. package/dist/L/user.js +4 -3
  139. package/dist/L/user.js.map +1 -1
  140. package/dist/LEvent.d.ts +13 -41
  141. package/dist/LEvent.js +4 -15
  142. package/dist/LEvent.js.map +1 -1
  143. package/dist/LiminalAssertionError.d.ts +8 -0
  144. package/dist/LiminalAssertionError.js +20 -0
  145. package/dist/LiminalAssertionError.js.map +1 -0
  146. package/dist/Message.d.ts +3 -2
  147. package/dist/Model.d.ts +4 -2
  148. package/dist/Model.js +1 -1
  149. package/dist/Model.js.map +1 -1
  150. package/dist/ModelRegistry.d.ts +0 -2
  151. package/dist/ModelRegistry.js +0 -2
  152. package/dist/ModelRegistry.js.map +1 -1
  153. package/dist/Rune.d.ts +19 -7
  154. package/dist/Rune.js +8 -4
  155. package/dist/Rune.js.map +1 -1
  156. package/dist/Rune.test.d.ts +1 -0
  157. package/dist/Rune.test.js +5 -0
  158. package/dist/Rune.test.js.map +1 -0
  159. package/dist/Schema.d.ts +46 -0
  160. package/dist/Schema.js +130 -0
  161. package/dist/Schema.js.map +1 -0
  162. package/dist/Strand.d.ts +57 -0
  163. package/dist/Strand.js +177 -0
  164. package/dist/Strand.js.map +1 -0
  165. package/dist/Tool.d.ts +6 -5
  166. package/dist/Tool.js +3 -4
  167. package/dist/Tool.js.map +1 -1
  168. package/dist/TypeAdapter.d.ts +1 -0
  169. package/dist/TypeAdapter.js +3 -0
  170. package/dist/TypeAdapter.js.map +1 -0
  171. package/dist/errors.d.ts +9 -0
  172. package/dist/errors.js +11 -0
  173. package/dist/errors.js.map +1 -0
  174. package/dist/index.d.ts +6 -5
  175. package/dist/index.js +6 -5
  176. package/dist/index.js.map +1 -1
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/dist/util/EnsureNarrow.d.ts +1 -0
  179. package/dist/util/EnsureNarrow.js +2 -0
  180. package/dist/util/EnsureNarrow.js.map +1 -0
  181. package/dist/util/JSONValue.d.ts +8 -0
  182. package/dist/util/JSONValue.js +20 -0
  183. package/dist/util/JSONValue.js.map +1 -0
  184. package/dist/util/attachCustomInspect.d.ts +1 -0
  185. package/dist/util/attachCustomInspect.js +11 -0
  186. package/dist/util/attachCustomInspect.js.map +1 -0
  187. package/dist/util/isTemplateStringsArray.d.ts +1 -0
  188. package/dist/util/isTemplateStringsArray.js +4 -0
  189. package/dist/util/isTemplateStringsArray.js.map +1 -0
  190. package/errors.ts +12 -0
  191. package/index.ts +6 -5
  192. package/package.json +3 -10
  193. package/tsconfig.json +1 -5
  194. package/util/EnsureNarrow.ts +1 -0
  195. package/util/JSONValue.ts +20 -0
  196. package/util/attachCustomInspect.ts +14 -0
  197. package/util/isTemplateStringsArray.ts +3 -0
  198. package/Fiber.ts +0 -123
  199. package/L/_common.ts +0 -6
  200. package/L/rune.ts +0 -12
  201. package/MessageRegistry.ts +0 -22
  202. package/Runic.ts +0 -30
  203. package/StrandConfig.ts +0 -12
  204. package/ToolRegistry.ts +0 -10
  205. package/dist/Fiber.d.ts +0 -35
  206. package/dist/Fiber.js +0 -95
  207. package/dist/Fiber.js.map +0 -1
  208. package/dist/L/_common.d.ts +0 -4
  209. package/dist/L/_common.js +0 -7
  210. package/dist/L/_common.js.map +0 -1
  211. package/dist/L/rune.d.ts +0 -3
  212. package/dist/L/rune.js +0 -9
  213. package/dist/L/rune.js.map +0 -1
  214. package/dist/MessageRegistry.d.ts +0 -9
  215. package/dist/MessageRegistry.js +0 -15
  216. package/dist/MessageRegistry.js.map +0 -1
  217. package/dist/Runic.d.ts +0 -9
  218. package/dist/Runic.js +0 -18
  219. package/dist/Runic.js.map +0 -1
  220. package/dist/StrandConfig.d.ts +0 -11
  221. package/dist/StrandConfig.js +0 -2
  222. package/dist/StrandConfig.js.map +0 -1
  223. package/dist/ToolRegistry.d.ts +0 -6
  224. package/dist/ToolRegistry.js +0 -8
  225. package/dist/ToolRegistry.js.map +0 -1
@@ -0,0 +1,11 @@
1
+ import type { SchemaString } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ interface string_ extends SchemaString<string>, TypeBase {
5
+ enum?: never
6
+ const?: never
7
+ }
8
+
9
+ const string_: string_ = make({ type: "string" })
10
+
11
+ export { string_ as string }
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
  }
package/L/user.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 user extends Generator<Rune<LEvent>, void> {}
7
-
8
- export function user(template: TemplateStringsArray, ...substitutions: Array<number | string>): user
9
- export function user(value: string): user
10
- export function user(e0: TemplateStringsArray | string, ...rest: Array<number | string>): user {
11
- const part = isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0
12
- return message("user", [{ part }])
6
+ export function user(
7
+ template: TemplateStringsArray,
8
+ ...substitutions: Array<number | string>
9
+ ): Generator<Rune<LEvent>, void>
10
+ export function user(value: string): Generator<Rune<LEvent>, void>
11
+ export function user(
12
+ e0: TemplateStringsArray | string,
13
+ ...rest: Array<number | string>
14
+ ): Generator<Rune<LEvent>, void> {
15
+ return message("user", [{
16
+ part: isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0,
17
+ }])
13
18
  }
package/LEvent.ts CHANGED
@@ -1,12 +1,11 @@
1
- import type { SchemaObject } from "liminal-schema"
2
1
  import { EventBase } from "./EventBase.ts"
3
2
  import type { Message } from "./Message.ts"
4
3
  import type { Model } from "./Model.ts"
4
+ import type { Schema } from "./Schema.ts"
5
+ import type { StrandStatus } from "./Strand.ts"
5
6
 
6
7
  export type LEvent =
7
- | FiberCreated
8
- | FiberResolved
9
- | FiberStarted
8
+ | StrandStatusChanged
10
9
  | InferenceRequested
11
10
  | Inferred
12
11
  | MessageAppended
@@ -28,10 +27,10 @@ export class ModelRegistered extends EventBase(LEventTag, "model_registered") {
28
27
  }
29
28
 
30
29
  export class InferenceRequested extends EventBase(LEventTag, "inference_requested") {
31
- declare schema?: SchemaObject
30
+ declare schema?: Schema
32
31
  constructor(
33
- readonly requestId: number,
34
- schema?: SchemaObject | undefined,
32
+ readonly requestId: string,
33
+ schema?: Schema | undefined,
35
34
  ) {
36
35
  super()
37
36
  if (schema) {
@@ -42,7 +41,7 @@ export class InferenceRequested extends EventBase(LEventTag, "inference_requeste
42
41
 
43
42
  export class Inferred extends EventBase(LEventTag, "inferred") {
44
43
  constructor(
45
- readonly requestId: number,
44
+ readonly requestId: string,
46
45
  readonly inference: string,
47
46
  ) {
48
47
  super()
@@ -55,15 +54,8 @@ export class MessageAppended extends EventBase(LEventTag, "message_appended") {
55
54
  }
56
55
  }
57
56
 
58
- export class FiberCreated extends EventBase(LEventTag, "fiber_created") {}
59
- export class FiberStarted extends EventBase(LEventTag, "fiber_started") {}
60
- export class FiberResolved extends EventBase(LEventTag, "fiber_resolved") {
61
- constructor(readonly value: any) {
62
- super()
63
- }
64
- }
65
- export class FiberRejected extends EventBase(LEventTag, "fiber_rejected") {
66
- constructor(readonly reason: any) {
57
+ export class StrandStatusChanged extends EventBase(LEventTag, "strand_status_changed") {
58
+ constructor(readonly status: StrandStatus) {
67
59
  super()
68
60
  }
69
61
  }
@@ -0,0 +1,19 @@
1
+ export class LiminalAssertionError extends Error {
2
+ override readonly name = "LiminalAssertionError"
3
+ }
4
+
5
+ export namespace LiminalAssertionError {
6
+ export function assert(expr: unknown, msg = ""): asserts expr {
7
+ if (!expr) {
8
+ throw new LiminalAssertionError(msg)
9
+ }
10
+ }
11
+
12
+ export function unimplemented(): never {
13
+ throw new LiminalAssertionError()
14
+ }
15
+
16
+ export function unreachable(): never {
17
+ throw new LiminalAssertionError()
18
+ }
19
+ }
package/Message.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  export interface Message {
2
2
  readonly role: MessageRole
3
- readonly content: Array<ContentPart>
3
+ readonly parts: Array<Content>
4
4
  }
5
5
 
6
6
  export type MessageRole = "system" | "user" | "assistant"
7
7
 
8
- export type ContentPart = {
8
+ export type Content = {
9
9
  readonly part: string
10
10
  readonly alt?: never
11
+ readonly mime?: never
11
12
  } | {
12
13
  readonly part: URL
13
14
  readonly alt: string
package/Model.ts CHANGED
@@ -1,6 +1,7 @@
1
- import type { SchemaObject } from "liminal-schema"
2
- import { attachCustomInspect } from "liminal-util"
3
1
  import type { Message } from "./Message.ts"
2
+ import type { SchemaObject } from "./Schema.ts"
3
+ import type { Tool } from "./Tool.ts"
4
+ import { attachCustomInspect } from "./util/attachCustomInspect.ts"
4
5
 
5
6
  export class Model {
6
7
  constructor(
@@ -16,7 +17,8 @@ export class Model {
16
17
  export interface Envelope {
17
18
  messages: Array<Message>
18
19
  schema?: SchemaObject | undefined
19
- signal?: AbortSignal
20
+ signal: AbortSignal
21
+ tools?: Set<Tool> | undefined
20
22
  }
21
23
 
22
24
  export interface SealedEnvelope {
package/ModelRegistry.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { ContextPart } from "./Context.ts"
2
1
  import type { Model } from "./Model.ts"
3
2
 
4
3
  /** An intrusive list for storing `Model`s. */
@@ -40,7 +39,7 @@ export class ModelRegistry {
40
39
  node.prev = node.next = undefined
41
40
  }
42
41
 
43
- clone(): ModelRegistry {
42
+ clone() {
44
43
  const instance = new ModelRegistry()
45
44
  for (let node = this.head; node; node = node.next) {
46
45
  instance.register(node.model)
@@ -54,8 +53,3 @@ export interface ModelRegistryNode {
54
53
  model: Model
55
54
  next?: ModelRegistryNode | undefined
56
55
  }
57
-
58
- export const ModelRegistryContext: ContextPart<ModelRegistry> = ContextPart(
59
- (parent) => parent?.clone() ?? new ModelRegistry(),
60
- "model_registry",
61
- )
package/Rune.test.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ test("adds 1 + 2 to equal 3", () => {
4
+ expect(1 + 2).toBe(3)
5
+ })
package/Rune.ts CHANGED
@@ -1,19 +1,31 @@
1
- import type { Fiber } from "./Fiber.ts"
1
+ import type { Context } from "./Context.ts"
2
+ import type { Definition } from "./Definition.ts"
2
3
 
3
- export interface Rune<out E = any> {
4
- E: E
5
- (fiber: Fiber): any
4
+ export interface Rune<E> {
6
5
  [RuneKey]: true
7
- debug?: string
6
+ value: {
7
+ kind: "continuation"
8
+ debug: string
9
+ f: () => any
10
+ } | {
11
+ kind: "event"
12
+ event: E
13
+ } | {
14
+ kind: "reflect"
15
+ } | {
16
+ kind: "child"
17
+ definition: Definition
18
+ context?: Context | undefined
19
+ }
8
20
  }
9
21
 
10
- export declare namespace Rune {
11
- export type E<X extends Rune> = X["E"]
22
+ export namespace Rune {
23
+ export type E<X extends Rune<any>> = X extends Rune<infer E> ? E : never
24
+
25
+ export function is(value: unknown): value is Rune<any> {
26
+ return typeof value === "object" && value !== null && RuneKey in value
27
+ }
12
28
  }
13
29
 
14
- export const RuneKey: unique symbol = Symbol.for("liminal/Rune")
30
+ export const RuneKey: unique symbol = Symbol.for("liminal/RuneKey")
15
31
  export type RuneKey = typeof RuneKey
16
-
17
- export function isRune(value: unknown): value is Rune {
18
- return typeof value === "object" && value !== null && RuneKey in value
19
- }
package/Schema.ts ADDED
@@ -0,0 +1,185 @@
1
+ import { subtle } from "node:crypto"
2
+ import { LiminalAssertionError as LE } from "./LiminalAssertionError.ts"
3
+
4
+ export type Schema<T = any> = SchemaType<T> | SchemaAnyOf<T>
5
+
6
+ export type SchemaType<T = any> =
7
+ | SchemaNull<T>
8
+ | SchemaBoolean<T>
9
+ | SchemaInteger<T>
10
+ | SchemaNumber<T>
11
+ | SchemaString<T>
12
+ | SchemaArray<T>
13
+ | SchemaObject<T>
14
+
15
+ export interface SchemaNull<T = any> extends SchemaTypeBase<"null", T> {}
16
+
17
+ export interface SchemaBoolean<T = any> extends SchemaTypeBase<"boolean", T> {}
18
+
19
+ export interface SchemaInteger<T = any> extends SchemaTypeBase<"integer", T> {}
20
+
21
+ export interface SchemaNumber<T = any> extends SchemaTypeBase<"number", T> {}
22
+
23
+ export interface SchemaString<T = any> extends SchemaTypeBase<"string", T> {
24
+ enum?: Array<string>
25
+ const?: string
26
+ }
27
+
28
+ export interface SchemaArray<T = any> extends SchemaTypeBase<"array", T> {
29
+ items: Schema
30
+ }
31
+
32
+ export interface SchemaObject<T = any> extends SchemaTypeBase<"object", T> {
33
+ properties: Record<string, Schema>
34
+ required: Array<string>
35
+ additionalProperties: false
36
+ }
37
+
38
+ interface SchemaTypeBase<K extends SchemaTypeName, T> extends SchemaBase<T> {
39
+ type: K
40
+ anyOf?: never
41
+ }
42
+
43
+ export type SchemaTypeName = "null" | "boolean" | "integer" | "number" | "string" | "array" | "object"
44
+
45
+ export interface SchemaAnyOf<T = any> extends SchemaBase<T> {
46
+ type?: never
47
+ anyOf: Array<Schema>
48
+ }
49
+
50
+ export interface SchemaBase<T> {
51
+ T: T
52
+ description?: string
53
+ }
54
+
55
+ export namespace Schema {
56
+ const ids = new WeakMap<Schema, Record<string, string>>()
57
+ const schemas = new WeakMap<WeakKey, Schema>()
58
+ const validators = new WeakMap<Schema, (value: unknown) => unknown>()
59
+
60
+ export function compile<T>(key: WeakKey, {
61
+ schema: schema_,
62
+ validate,
63
+ }: {
64
+ schema(): unknown
65
+ validate(value: unknown): T
66
+ }) {
67
+ let schema = schemas.get(key)
68
+ if (!schema) {
69
+ schema = Schema.validate(schema_())
70
+ schemas.set(key, schema)
71
+ }
72
+ validators.set(schema, validate)
73
+ return schema
74
+ }
75
+
76
+ export function validateValue<T>(schema: Schema<T>, value: unknown): T {
77
+ const validator = validators.get(schema)
78
+ LE.assert(validator)
79
+ return validator(value) as never
80
+ }
81
+
82
+ export async function id(schema: Schema, description?: string): Promise<string> {
83
+ description = description ?? ""
84
+ if (!ids.has(schema)) {
85
+ ids.set(schema, {})
86
+ }
87
+ const schemaIds = ids.get(schema)!
88
+ let id = schemaIds[description]
89
+ if (!id) {
90
+ const content = `${description}_${JSON.stringify(schema)}`
91
+ const bytes = new Uint8Array(await subtle.digest("SHA-256", new TextEncoder().encode(content)))
92
+ let binary = ""
93
+ for (const b of bytes) binary += String.fromCharCode(b)
94
+ id = btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")
95
+ schemaIds[description] = id
96
+ }
97
+ return id
98
+ }
99
+
100
+ export function wrap(schema: Schema): SchemaObject {
101
+ return {
102
+ type: "object",
103
+ properties: { value: schema },
104
+ additionalProperties: false,
105
+ required: ["value"],
106
+ } satisfies Omit<SchemaObject, "T"> as never
107
+ }
108
+
109
+ export function validate(value: unknown): Schema {
110
+ LE.assert(typeof value === "object")
111
+ LE.assert(value !== null)
112
+ if ("anyOf" in value) {
113
+ LE.assert(Array.isArray(value.anyOf))
114
+ return {
115
+ anyOf: value.anyOf.map(validate),
116
+ } satisfies Omit<SchemaAnyOf, "T"> as never
117
+ } else {
118
+ if ("enum" in value) {
119
+ LE.assert(Array.isArray(value.enum))
120
+ LE.assert(!("const" in value))
121
+ value.enum.forEach((v) => LE.assert(typeof v === "string"))
122
+ return {
123
+ type: "string",
124
+ enum: value.enum,
125
+ } satisfies Omit<SchemaString, "T"> as never
126
+ } else if ("const" in value) {
127
+ LE.assert(typeof value.const === "string")
128
+ return {
129
+ type: "string",
130
+ const: value.const,
131
+ } satisfies Omit<SchemaString, "T"> as never
132
+ } else if ("type" in value) {
133
+ LE.assert("type" in value)
134
+ LE.assert(typeof value.type === "string")
135
+ LE.assert(SCHEMA_TYPE_NAMES[value.type])
136
+ switch (value.type) {
137
+ case "null":
138
+ case "boolean":
139
+ case "integer":
140
+ case "number": {
141
+ break
142
+ }
143
+ case "string": {
144
+ if ("const" in value) {
145
+ LE.assert(typeof value.const === "string")
146
+ }
147
+ break
148
+ }
149
+ case "array": {
150
+ LE.assert("items" in value)
151
+ return {
152
+ type: "array",
153
+ items: validate(value.items),
154
+ } satisfies Omit<SchemaArray, "T"> as never
155
+ }
156
+ case "object": {
157
+ LE.assert("properties" in value)
158
+ LE.assert(typeof value.properties === "object")
159
+ const { properties } = value
160
+ LE.assert(properties !== null)
161
+ return {
162
+ type: "object",
163
+ properties: Object.fromEntries(
164
+ Object.entries(properties).map(([key, value]) => [key, validate(value)]),
165
+ ),
166
+ required: Object.keys(properties),
167
+ additionalProperties: false,
168
+ } satisfies Omit<SchemaObject, "T"> as never
169
+ }
170
+ }
171
+ }
172
+ }
173
+ return value as Schema
174
+ }
175
+ }
176
+
177
+ const SCHEMA_TYPE_NAMES: Record<string, boolean> = {
178
+ null: true,
179
+ boolean: true,
180
+ integer: true,
181
+ number: true,
182
+ string: true,
183
+ array: true,
184
+ object: true,
185
+ } satisfies Record<SchemaTypeName, true>