liminal 0.5.13 → 0.5.15

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 (134) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/Context.ts +21 -4
  3. package/Definition.ts +16 -0
  4. package/L/L.ts +10 -1
  5. package/L/all.ts +4 -0
  6. package/L/assistant.ts +5 -3
  7. package/L/catch.ts +4 -0
  8. package/L/continuation.ts +3 -2
  9. package/L/emit.ts +6 -2
  10. package/L/infer.ts +16 -10
  11. package/L/message.ts +7 -3
  12. package/L/model.ts +4 -0
  13. package/L/reflect.ts +2 -1
  14. package/L/run.ts +2 -1
  15. package/L/schema/_schema_common.ts +29 -0
  16. package/L/schema/anyOf.ts +10 -0
  17. package/L/schema/array.ts +13 -0
  18. package/L/schema/boolean.ts +8 -0
  19. package/L/schema/const.ts +18 -0
  20. package/L/schema/enum.ts +18 -0
  21. package/L/schema/integer.ts +6 -0
  22. package/L/schema/null.ts +8 -0
  23. package/L/schema/number.ts +8 -0
  24. package/L/schema/object.ts +21 -0
  25. package/L/schema/string.ts +11 -0
  26. package/L/strand.ts +6 -2
  27. package/L/stream.ts +2 -1
  28. package/Message.ts +3 -2
  29. package/Model.ts +4 -4
  30. package/ModelRegistry.ts +16 -3
  31. package/Rune.ts +36 -7
  32. package/Schema.ts +4 -4
  33. package/Strand.ts +37 -6
  34. package/dist/Context.d.ts +19 -0
  35. package/dist/Context.js +7 -2
  36. package/dist/Context.js.map +1 -1
  37. package/dist/Definition.d.ts +14 -0
  38. package/dist/Definition.js +11 -0
  39. package/dist/Definition.js.map +1 -1
  40. package/dist/L/L.d.ts +10 -1
  41. package/dist/L/L.js +10 -1
  42. package/dist/L/L.js.map +1 -1
  43. package/dist/L/all.d.ts +4 -0
  44. package/dist/L/all.js.map +1 -1
  45. package/dist/L/assistant.d.ts +4 -0
  46. package/dist/L/assistant.js +1 -3
  47. package/dist/L/assistant.js.map +1 -1
  48. package/dist/L/catch.d.ts +4 -0
  49. package/dist/L/catch.js +4 -0
  50. package/dist/L/catch.js.map +1 -1
  51. package/dist/L/continuation.d.ts +1 -0
  52. package/dist/L/continuation.js +3 -2
  53. package/dist/L/continuation.js.map +1 -1
  54. package/dist/L/emit.d.ts +4 -0
  55. package/dist/L/emit.js +6 -2
  56. package/dist/L/emit.js.map +1 -1
  57. package/dist/L/infer.d.ts +4 -0
  58. package/dist/L/infer.js +11 -7
  59. package/dist/L/infer.js.map +1 -1
  60. package/dist/L/message.d.ts +6 -2
  61. package/dist/L/message.js +5 -1
  62. package/dist/L/message.js.map +1 -1
  63. package/dist/L/model.d.ts +4 -0
  64. package/dist/L/model.js +4 -0
  65. package/dist/L/model.js.map +1 -1
  66. package/dist/L/reflect.d.ts +1 -0
  67. package/dist/L/reflect.js +2 -1
  68. package/dist/L/reflect.js.map +1 -1
  69. package/dist/L/run.d.ts +2 -1
  70. package/dist/L/run.js.map +1 -1
  71. package/dist/L/schema/_schema_common.d.ts +6 -0
  72. package/dist/L/schema/_schema_common.js +19 -0
  73. package/dist/L/schema/_schema_common.js.map +1 -0
  74. package/dist/L/schema/anyOf.d.ts +5 -0
  75. package/dist/L/schema/anyOf.js +5 -0
  76. package/dist/L/schema/anyOf.js.map +1 -0
  77. package/dist/L/schema/array.d.ts +5 -0
  78. package/dist/L/schema/array.js +8 -0
  79. package/dist/L/schema/array.js.map +1 -0
  80. package/dist/L/schema/boolean.d.ts +6 -0
  81. package/dist/L/schema/boolean.js +4 -0
  82. package/dist/L/schema/boolean.js.map +1 -0
  83. package/dist/L/schema/const.d.ts +8 -0
  84. package/dist/L/schema/const.js +10 -0
  85. package/dist/L/schema/const.js.map +1 -0
  86. package/dist/L/schema/enum.d.ts +8 -0
  87. package/dist/L/schema/enum.js +10 -0
  88. package/dist/L/schema/enum.js.map +1 -0
  89. package/dist/L/schema/integer.d.ts +5 -0
  90. package/dist/L/schema/integer.js +3 -0
  91. package/dist/L/schema/integer.js.map +1 -0
  92. package/dist/L/schema/null.d.ts +6 -0
  93. package/dist/L/schema/null.js +4 -0
  94. package/dist/L/schema/null.js.map +1 -0
  95. package/dist/L/schema/number.d.ts +6 -0
  96. package/dist/L/schema/number.js +4 -0
  97. package/dist/L/schema/number.js.map +1 -0
  98. package/dist/L/schema/object.d.ts +9 -0
  99. package/dist/L/schema/object.js +12 -0
  100. package/dist/L/schema/object.js.map +1 -0
  101. package/dist/L/schema/string.d.ts +8 -0
  102. package/dist/L/schema/string.js +4 -0
  103. package/dist/L/schema/string.js.map +1 -0
  104. package/dist/L/strand.d.ts +4 -0
  105. package/dist/L/strand.js +6 -2
  106. package/dist/L/strand.js.map +1 -1
  107. package/dist/L/stream.d.ts +1 -0
  108. package/dist/L/stream.js +2 -1
  109. package/dist/L/stream.js.map +1 -1
  110. package/dist/Message.d.ts +3 -2
  111. package/dist/Model.d.ts +4 -4
  112. package/dist/Model.js +4 -4
  113. package/dist/ModelRegistry.d.ts +11 -1
  114. package/dist/ModelRegistry.js +16 -3
  115. package/dist/ModelRegistry.js.map +1 -1
  116. package/dist/Rune.d.ts +29 -8
  117. package/dist/Rune.js +2 -0
  118. package/dist/Rune.js.map +1 -1
  119. package/dist/Schema.d.ts +2 -2
  120. package/dist/Schema.js +2 -2
  121. package/dist/Schema.js.map +1 -1
  122. package/dist/Strand.d.ts +24 -0
  123. package/dist/Strand.js +27 -4
  124. package/dist/Strand.js.map +1 -1
  125. package/dist/tsconfig.tsbuildinfo +1 -1
  126. package/dist/util/JSONValue.d.ts +1 -1
  127. package/dist/util/JSONValue.js +21 -9
  128. package/dist/util/JSONValue.js.map +1 -1
  129. package/package.json +1 -1
  130. package/util/JSONValue.ts +23 -8
  131. package/L/context.ts +0 -12
  132. package/dist/L/context.d.ts +0 -2
  133. package/dist/L/context.js +0 -12
  134. package/dist/L/context.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # liminal
2
2
 
3
+ ## 0.5.15
4
+
5
+ ### Patch Changes
6
+
7
+ - 9c276c3: Fix message list cloning, add streaming to ollama adapter.
8
+
9
+ ## 0.5.14
10
+
11
+ ### Patch Changes
12
+
13
+ - d12049c: Fix L.run return type. Add L.<type> for JSON-schema building.
14
+
3
15
  ## 0.5.13
4
16
 
5
17
  ### Patch Changes
package/Context.ts CHANGED
@@ -3,22 +3,39 @@ import type { Message } from "./Message.ts"
3
3
  import { ModelRegistry } from "./ModelRegistry.ts"
4
4
  import type { Tool } from "./Tool.ts"
5
5
 
6
+ /**
7
+ * Context represents the execution environment for a Strand.
8
+ *
9
+ * It holds all the stateful components needed during strand execution:
10
+ * - Message history.
11
+ * - Event handler for processing events.
12
+ * - Model registry for tracking available language models.
13
+ * - Available tools for model-driven function calling.
14
+ */
6
15
  export interface Context {
16
+ /** Event handler for processing events during strand execution. */
7
17
  readonly handler: Handler | undefined
18
+ /** Registry of available models for inference. */
8
19
  readonly models: ModelRegistry
20
+ /** Accumulated message history. */
9
21
  readonly messages: Array<Message>
22
+ /** Set of tools available to the models. */
10
23
  readonly tools: Set<Tool>
11
-
24
+ /** Creates a copy of the current `Context` for child strands. */
12
25
  clone(): Context
13
26
  }
14
27
 
28
+ /**
29
+ * Factory function to create a new Context.
30
+ * @param context Optional base context from which to initialize.
31
+ * @returns A newly created Context.
32
+ */
15
33
  export function Context(context?: Omit<Context, "clone">): Context {
16
34
  return {
17
35
  handler: context?.handler,
18
- models: context?.models.clone() ?? new ModelRegistry(),
19
- messages: [],
36
+ models: context?.models?.clone() ?? new ModelRegistry(),
37
+ messages: [...(context?.messages ?? [])],
20
38
  tools: new Set(context?.tools),
21
-
22
39
  clone(): Context {
23
40
  return {
24
41
  handler: this.handler,
package/Definition.ts CHANGED
@@ -1,22 +1,38 @@
1
1
  import type { Rune } from "./Rune.ts"
2
2
 
3
3
  export type RuneIterator<Y extends Rune<any> = Rune<any>, T = any> = Iterator<Y, T> | AsyncIterator<Y, T>
4
+
4
5
  export type RuneIterable<Y extends Rune<any> = Rune<any>, T = any> = Iterable<Y, T> | AsyncIterable<Y, T>
6
+
5
7
  export type Definition<Y extends Rune<any> = Rune<any>, T = any> = RuneIterable<Y, T> | (() => RuneIterable<Y, T>)
6
8
 
7
9
  export namespace Definition {
10
+ /** Extracts the Rune type from a Definition. */
8
11
  export type Y<X extends Definition> = X extends RuneIterable<infer Y> ? Y
9
12
  : X extends () => RuneIterable<infer Y> ? Y
10
13
  : X extends RuneIterator<infer Y> ? Y
11
14
  : never
12
15
 
16
+ /** Extracts the result type from a Definition. */
13
17
  export type T<X extends Definition> = X extends RuneIterable<Rune<any>, infer T> ? T
14
18
  : X extends () => RuneIterable<Rune<any>, infer T> ? T
15
19
  : X extends RuneIterator<Rune<any>, infer T> ? T
16
20
  : never
17
21
 
22
+ /** Extracts the event type from a Definition. */
18
23
  export type E<X extends Definition> = Rune.E<Y<X>>
19
24
 
25
+ /**
26
+ * Converts a Definition into a RuneIterator.
27
+ *
28
+ * This function handles all the different forms a Definition can take:
29
+ * - Synchronous iterables
30
+ * - Asynchronous iterables
31
+ * - Factory functions returning iterables
32
+ *
33
+ * @param definition The definition to unwrap.
34
+ * @returns A RuneIterator ready for consumption.
35
+ */
20
36
  export function unwrap<Y extends Rune<any>, T>(definition: Definition<Y, T>): RuneIterator<Y, T> {
21
37
  if (Symbol.iterator in definition) {
22
38
  return definition[Symbol.iterator]()
package/L/L.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from "./all.ts"
2
2
  export * from "./assistant.ts"
3
3
  export * from "./catch.ts"
4
- export * from "./context.ts"
5
4
  export * from "./continuation.ts"
6
5
  export * from "./emit.ts"
7
6
  export * from "./infer.ts"
@@ -9,6 +8,16 @@ export * from "./message.ts"
9
8
  export * from "./model.ts"
10
9
  export * from "./reflect.ts"
11
10
  export * from "./run.ts"
11
+ export * from "./schema/anyOf.ts"
12
+ export * from "./schema/array.ts"
13
+ export * from "./schema/boolean.ts"
14
+ export * from "./schema/const.ts"
15
+ export * from "./schema/enum.ts"
16
+ export * from "./schema/integer.ts"
17
+ export * from "./schema/null.ts"
18
+ export * from "./schema/number"
19
+ export * from "./schema/object.ts"
20
+ export * from "./schema/string.ts"
12
21
  export * from "./strand.ts"
13
22
  export * from "./stream.ts"
14
23
  export * from "./system.ts"
package/L/all.ts CHANGED
@@ -6,6 +6,10 @@ import { Strand } from "../Strand.ts"
6
6
  import { continuation } from "./continuation.ts"
7
7
  import { reflect } from "./reflect.ts"
8
8
 
9
+ /**
10
+ * Runs multiple definitions in parallel and collects their results.
11
+ * Can be used with an array or object of definitions.
12
+ */
9
13
  export function all<A extends Array<Definition>>(
10
14
  definitions: A,
11
15
  context?: Context,
package/L/assistant.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import type { LEvent } from "../LEvent.ts"
2
2
  import type { Rune } from "../Rune.ts"
3
3
  import { Schema } from "../Schema.ts"
4
- import { continuation } from "./continuation.ts"
5
4
  import { infer } from "./infer.ts"
6
5
  import { message } from "./message.ts"
7
6
 
7
+ /**
8
+ * Produces an assistant message when yielded. Can be called with a schema
9
+ * for structured output. Otherwise produces a string.
10
+ */
8
11
  export interface assistant extends Iterable<Rune<LEvent>, string> {
9
12
  <T>(schema: Schema<T>): Generator<Rune<LEvent>, T>
10
13
  }
@@ -13,8 +16,7 @@ export const assistant: assistant = Object.assign(
13
16
  function* assistant<T>(schema: Schema<T>): Generator<Rune<LEvent>, T> {
14
17
  const inference = yield* infer(schema)
15
18
  yield* message("assistant", [{ part: inference }])
16
- const input = JSON.parse(inference)
17
- return yield* continuation("validate_assistant_message", () => Schema.validateValue(schema, input))
19
+ return JSON.parse(inference)
18
20
  },
19
21
  {
20
22
  *[Symbol.iterator]() {
package/L/catch.ts CHANGED
@@ -7,6 +7,10 @@ import { reflect } from "./reflect.ts"
7
7
 
8
8
  export { catch_ as catch }
9
9
 
10
+ /**
11
+ * Error handling utility that catches exceptions from running a definition.
12
+ * Returns a result object indicating whether the operation succeeded or failed.
13
+ */
10
14
  function* catch_<Y extends Rune<any>, T>(
11
15
  definition: Definition<Y, T>,
12
16
  ): Generator<Rune<LEvent> | Rune<Y>, CatchResult<T>> {
package/L/continuation.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { LEvent } from "../LEvent.ts"
2
2
  import { Rune, RuneKey } from "../Rune.ts"
3
3
 
4
+ /** Yields a continuation rune that executes a function and passes its result to the next iteration. */
4
5
  export function* continuation<R>(debug: string, f: () => R): Generator<Rune<LEvent>, Awaited<R>> {
5
6
  return yield {
6
7
  [RuneKey]: true,
7
- value: {
8
- kind: "continuation",
8
+ instruction: {
9
+ kind: "continue",
9
10
  debug,
10
11
  f,
11
12
  },
package/L/emit.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import { Rune, RuneKey } from "../Rune.ts"
2
2
  import type { EnsureNarrow } from "../util/EnsureNarrow.ts"
3
3
 
4
+ /**
5
+ * Emits an event to be supplied to handlers.
6
+ * Used for broadcasting state changes and triggering side effects.
7
+ */
4
8
  export function* emit<E>(event: EnsureNarrow<E>): Generator<Rune<E>, void> {
5
9
  return yield {
6
10
  [RuneKey]: true,
7
- value: {
8
- kind: "event",
11
+ instruction: {
12
+ kind: "emit",
9
13
  event,
10
14
  },
11
15
  }
package/L/infer.ts CHANGED
@@ -6,22 +6,28 @@ import { continuation } from "./continuation.ts"
6
6
  import { emit } from "./emit.ts"
7
7
  import { reflect } from "./reflect.ts"
8
8
 
9
+ /**
10
+ * Requests an inference from the current model, optionally with a schema.
11
+ * Emits inference-related events and returns the model's response as a string.
12
+ */
9
13
  export function* infer(schema?: Schema): Generator<Rune<LEvent>, string> {
10
14
  const { context: { models, messages }, signal } = yield* reflect
11
15
  const model = models.peek()
12
16
  LiminalAssertionError.assert(model)
13
17
  const requestId = crypto.randomUUID()
14
18
  yield* emit(new InferenceRequested(requestId, schema))
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())
19
+ let inference = yield* continuation(
20
+ "infer",
21
+ model
22
+ .seal({
23
+ messages,
24
+ ...schema && {
25
+ schema: schema.type === "object" ? schema : Schema.wrap(schema),
26
+ },
27
+ signal,
28
+ })
29
+ .resolve,
30
+ )
25
31
  if (schema?.type && schema.type !== "object") {
26
32
  inference = JSON.stringify(JSON.parse(inference).value)
27
33
  }
package/L/message.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  import { LEvent, MessageAppended } from "../LEvent.ts"
2
- import type { ContentPart, Message, MessageRole } from "../Message.ts"
2
+ import type { Content, Message, MessageRole } from "../Message.ts"
3
3
  import type { Rune } from "../Rune.ts"
4
4
  import { emit } from "./emit.ts"
5
5
  import { reflect } from "./reflect.ts"
6
6
 
7
- export function* message(role: MessageRole, content: Array<ContentPart>): Generator<Rune<LEvent>, void> {
7
+ /**
8
+ * Adds a new message to the current context's message list.
9
+ * Emits a message append event to observers.
10
+ */
11
+ export function* message(role: MessageRole, content: Array<Content>): Generator<Rune<LEvent>, void> {
8
12
  const { context: { messages } } = yield* reflect
9
- const message: Message = { role, content }
13
+ const message: Message = { role, parts: content }
10
14
  yield* emit(new MessageAppended(message))
11
15
  messages.push(message)
12
16
  }
package/L/model.ts CHANGED
@@ -5,6 +5,10 @@ import type { Rune } from "../Rune.ts"
5
5
  import { emit } from "./emit.ts"
6
6
  import { reflect } from "./reflect.ts"
7
7
 
8
+ /**
9
+ * Registers a model in the current context and emits a model registration event.
10
+ * Returns the registered model instance.
11
+ */
8
12
  export function* model(model: Model): Generator<Rune<LEvent>, Model> {
9
13
  const { context: { models } } = yield* reflect
10
14
  models.register(model)
package/L/reflect.ts CHANGED
@@ -2,11 +2,12 @@ import type { LEvent } from "../LEvent.ts"
2
2
  import { Rune, RuneKey } from "../Rune.ts"
3
3
  import type { Strand } from "../Strand.ts"
4
4
 
5
+ /** Returns the current strand instance, providing access to context and parent information. */
5
6
  export const reflect: Iterable<Rune<LEvent>, Strand> = {
6
7
  *[Symbol.iterator]() {
7
8
  return yield {
8
9
  [RuneKey]: true,
9
- value: { kind: "reflect" },
10
+ instruction: { kind: "reflect" },
10
11
  }
11
12
  },
12
13
  }
package/L/run.ts CHANGED
@@ -7,6 +7,7 @@ import type { Rune } from "../Rune.ts"
7
7
  import { Strand } from "../Strand.ts"
8
8
  import type { Tool } from "../Tool.ts"
9
9
 
10
+ /** Configuration options for running a definition. */
10
11
  export interface RunConfig<Y extends Rune<any>> {
11
12
  handler?: Handler<Y> | undefined
12
13
  models?: ModelRegistry | undefined
@@ -15,7 +16,7 @@ export interface RunConfig<Y extends Rune<any>> {
15
16
  signal?: AbortSignal | undefined
16
17
  }
17
18
 
18
- export function run<Y extends Rune<any>, T>(definition: Definition<Y, T>, config?: RunConfig<Y>): Strand {
19
+ export function run<Y extends Rune<any>, T>(definition: Definition<Y, T>, config?: RunConfig<Y>): Strand<Y, T> {
19
20
  const context = Context({
20
21
  handler: config?.handler,
21
22
  models: config?.models ?? new ModelRegistry(),
@@ -0,0 +1,29 @@
1
+ import type { Schema } from "../../Schema.ts"
2
+ import { isTemplateStringsArray } from "../../util/isTemplateStringsArray.ts"
3
+
4
+ export function make<S extends Schema>(schema: Omit<S, "T">, description?: string): S & TypeBase {
5
+ const schema_ = {
6
+ ...schema,
7
+ ...description && { description },
8
+ }
9
+
10
+ const Type = Object.assign(function describe(e0?: TemplateStringsArray | string, ...rest: Array<string>) {
11
+ const junction = isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0
12
+ return make(
13
+ schema_,
14
+ description ? `${description}${junction ? `\n\n${junction}` : ""}` : junction,
15
+ )
16
+ }, schema_)
17
+ Object.defineProperty(Type, "toJSON", {
18
+ value() {
19
+ return schema_
20
+ },
21
+ enumerable: false,
22
+ })
23
+ return Type as never
24
+ }
25
+
26
+ export interface TypeBase {
27
+ (template: TemplateStringsArray, ...substitutions: Array<string>): this
28
+ (...values: Array<string>): this
29
+ }
@@ -0,0 +1,10 @@
1
+ import type { Schema, SchemaAnyOf } from "../../Schema.ts"
2
+ import { make } from "./_schema_common.ts"
3
+
4
+ export interface anyOf<XA extends Array<Schema> = Array<Schema>> extends SchemaAnyOf<XA[number]["T"]> {
5
+ anyOf: XA
6
+ }
7
+
8
+ export function anyOf<XA extends Array<Schema>>(anyOf: XA): anyOf<XA> {
9
+ return make({ anyOf })
10
+ }
@@ -0,0 +1,13 @@
1
+ import type { Schema, SchemaArray } from "../../Schema.ts"
2
+ import { make } from "./_schema_common.ts"
3
+
4
+ export interface LArray<X extends Schema = Schema> extends SchemaArray<Array<X["T"]>> {
5
+ items: X
6
+ }
7
+
8
+ export function array<X extends Schema>(items: X): LArray<X> {
9
+ return make({
10
+ type: "array",
11
+ items,
12
+ })
13
+ }
@@ -0,0 +1,8 @@
1
+ import type { SchemaBoolean } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ interface boolean_ extends SchemaBoolean<boolean>, TypeBase {}
5
+
6
+ const boolean_: boolean_ = make({ type: "boolean" })
7
+
8
+ export { boolean_ as boolean }
@@ -0,0 +1,18 @@
1
+ import type { SchemaString } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ interface const_<K extends string> extends SchemaString<K>, TypeBase {
5
+ enum?: never
6
+ const: K
7
+ }
8
+
9
+ function const_<K extends string>(value: K): const_<K> {
10
+ return make({
11
+ type: "string",
12
+ const: value,
13
+ })
14
+ }
15
+
16
+ Object.defineProperty(const_, "name", { value: "const" })
17
+
18
+ export { const_ as const }
@@ -0,0 +1,18 @@
1
+ import type { SchemaString } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ interface enum_<V extends Array<string> = Array<string>> extends SchemaString<V[number]>, TypeBase {
5
+ enum: V
6
+ const?: never
7
+ }
8
+
9
+ function enum_<const V extends Array<string>>(...values: V): enum_<V> {
10
+ return make({
11
+ type: "string",
12
+ enum: values,
13
+ })
14
+ }
15
+
16
+ Object.defineProperty(enum_, "name", { value: "enum" })
17
+
18
+ export { enum_ as enum }
@@ -0,0 +1,6 @@
1
+ import type { SchemaInteger } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ export interface integer extends SchemaInteger<number>, TypeBase {}
5
+
6
+ export const integer: integer = make({ type: "integer" })
@@ -0,0 +1,8 @@
1
+ import type { SchemaNull } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ export interface null_ extends SchemaNull<null>, TypeBase {}
5
+
6
+ const null_: null_ = make({ type: "null" })
7
+
8
+ export { null_ as null }
@@ -0,0 +1,8 @@
1
+ import type { SchemaNumber } from "../../Schema.ts"
2
+ import { make, type TypeBase } from "./_schema_common.ts"
3
+
4
+ interface number_ extends SchemaNumber<number>, TypeBase {}
5
+
6
+ const number_: number_ = make({ type: "number" })
7
+
8
+ export { number_ as number }
@@ -0,0 +1,21 @@
1
+ import type { Schema, SchemaObject } from "../../Schema.ts"
2
+ import { make } from "./_schema_common.ts"
3
+
4
+ interface object_<F extends Record<string, Schema> = Record<string, Schema>>
5
+ extends SchemaObject<{ [K in keyof F]: F[K]["T"] }>
6
+ {
7
+ properties: F
8
+ required: Array<Extract<keyof F, string>>
9
+ }
10
+
11
+ function object_<XR extends Record<string, Schema>>(properties: XR): object_<XR> {
12
+ return make({
13
+ type: "object",
14
+ properties,
15
+ additionalProperties: false,
16
+ required: Object.keys(properties) as never,
17
+ })
18
+ }
19
+
20
+ Object.defineProperty(object_, "name", { value: "object" })
21
+ export { object_ as object }
@@ -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
@@ -3,14 +3,18 @@ import type { Definition } from "../Definition.ts"
3
3
  import type { LEvent } from "../LEvent.ts"
4
4
  import { type Rune, RuneKey } from "../Rune.ts"
5
5
 
6
+ /**
7
+ * Creates a child strand that executes a definition.
8
+ * Optionally specify the context. Otherwise the current context is inherited.
9
+ */
6
10
  export function* strand<Y extends Rune<any>, T>(
7
11
  definition: Definition<Y, T>,
8
12
  context?: Context,
9
13
  ): Generator<Rune<LEvent>, T> {
10
14
  return yield {
11
15
  [RuneKey]: true,
12
- value: {
13
- kind: "child",
16
+ instruction: {
17
+ kind: "create_child",
14
18
  definition,
15
19
  context,
16
20
  },
package/L/stream.ts CHANGED
@@ -5,6 +5,7 @@ import { continuation } from "./continuation.ts"
5
5
  import { emit } from "./emit.ts"
6
6
  import { reflect } from "./reflect.ts"
7
7
 
8
+ /** Creates a readable stream of content from the current model. */
8
9
  export const stream: Iterable<Rune<LEvent>, ReadableStream<string>> = {
9
10
  *[Symbol.iterator]() {
10
11
  const { context: { models, messages }, signal } = yield* reflect
@@ -12,6 +13,6 @@ export const stream: Iterable<Rune<LEvent>, ReadableStream<string>> = {
12
13
  LiminalAssertionError.assert(model)
13
14
  const requestId = crypto.randomUUID()
14
15
  yield* emit(new InferenceRequested(requestId))
15
- return yield* continuation("stream", () => model.seal({ messages, signal }).stream())
16
+ return yield* continuation("stream", model.seal({ messages, signal }).stream)
16
17
  },
17
18
  }
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
@@ -5,12 +5,12 @@ import { attachCustomInspect } from "./util/attachCustomInspect.ts"
5
5
 
6
6
  export class Model {
7
7
  constructor(
8
- readonly vendor: string,
8
+ readonly client: string,
9
9
  readonly seal: (envelope: Envelope) => SealedEnvelope,
10
10
  ) {}
11
11
 
12
12
  static {
13
- attachCustomInspect(this, ({ vendor }) => ({ vendor }))
13
+ attachCustomInspect(this, ({ client }) => ({ client }))
14
14
  }
15
15
  }
16
16
 
@@ -22,6 +22,6 @@ export interface Envelope {
22
22
  }
23
23
 
24
24
  export interface SealedEnvelope {
25
- resolve(): Promise<string>
26
- stream(): ReadableStream<string>
25
+ resolve: () => Promise<string>
26
+ stream: () => ReadableStream<string>
27
27
  }
package/ModelRegistry.ts CHANGED
@@ -1,14 +1,22 @@
1
1
  import type { Model } from "./Model.ts"
2
2
 
3
- /** An intrusive list for storing `Model`s. */
3
+ /**
4
+ * An intrusive doubly-linked list for storing `Model`s.
5
+ * Provides efficient insertion, removal, and lookups.
6
+ */
4
7
  export class ModelRegistry {
5
8
  declare head?: ModelRegistryNode | undefined
6
9
  declare tail?: ModelRegistryNode | undefined
7
10
 
11
+ /** Returns the most recently registered model */
8
12
  peek() {
9
13
  return this.tail?.model
10
14
  }
11
15
 
16
+ /**
17
+ * Registers a new model and returns the created node
18
+ * @param value The model to register
19
+ */
12
20
  register(value: Model): ModelRegistryNode {
13
21
  const node: ModelRegistryNode = {
14
22
  prev: this.tail,
@@ -23,6 +31,7 @@ export class ModelRegistry {
23
31
  return node
24
32
  }
25
33
 
34
+ /** Remove a model from the registry. */
26
35
  remove(node: ModelRegistryNode) {
27
36
  if (node.prev) {
28
37
  node.prev.next = node.next
@@ -36,13 +45,17 @@ export class ModelRegistry {
36
45
  if (node === this.tail) {
37
46
  this.tail = node.prev
38
47
  }
39
- node.prev = node.next = undefined
48
+ node.prev = undefined
49
+ delete node.next
40
50
  }
41
51
 
52
+ /** Creates a deep copy of this registry. */
42
53
  clone() {
43
54
  const instance = new ModelRegistry()
44
55
  for (let node = this.head; node; node = node.next) {
45
- instance.register(node.model)
56
+ if (node.model) {
57
+ instance.register(node.model)
58
+ }
46
59
  }
47
60
  return instance
48
61
  }