liminal 0.5.7 → 0.5.9

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 (70) hide show
  1. package/Agent.ts +8 -5
  2. package/CHANGELOG.md +17 -0
  3. package/Context.ts +1 -10
  4. package/Fiber.ts +92 -25
  5. package/L/L.ts +1 -0
  6. package/L/_infer.ts +6 -8
  7. package/L/assistant.ts +2 -2
  8. package/L/branch.ts +13 -9
  9. package/L/catch.ts +23 -0
  10. package/L/emit.ts +1 -1
  11. package/L/rune.ts +24 -13
  12. package/LEvent.ts +1 -1
  13. package/Model.ts +10 -9
  14. package/ModelRegistry.ts +0 -8
  15. package/Rune.ts +4 -2
  16. package/Tool.ts +31 -0
  17. package/ToolRegistry.ts +5 -0
  18. package/dist/Agent.d.ts +5 -3
  19. package/dist/Agent.js +5 -3
  20. package/dist/Agent.js.map +1 -1
  21. package/dist/Context.d.ts +1 -2
  22. package/dist/Context.js +0 -8
  23. package/dist/Context.js.map +1 -1
  24. package/dist/Fiber.d.ts +25 -5
  25. package/dist/Fiber.js +69 -27
  26. package/dist/Fiber.js.map +1 -1
  27. package/dist/L/L.d.ts +1 -0
  28. package/dist/L/L.js +1 -0
  29. package/dist/L/L.js.map +1 -1
  30. package/dist/L/_infer.js +6 -7
  31. package/dist/L/_infer.js.map +1 -1
  32. package/dist/L/assistant.d.ts +1 -1
  33. package/dist/L/assistant.js +1 -1
  34. package/dist/L/assistant.js.map +1 -1
  35. package/dist/L/branch.js +13 -9
  36. package/dist/L/branch.js.map +1 -1
  37. package/dist/L/catch.d.ts +11 -0
  38. package/dist/L/catch.js +14 -0
  39. package/dist/L/catch.js.map +1 -0
  40. package/dist/L/emit.js +1 -1
  41. package/dist/L/emit.js.map +1 -1
  42. package/dist/L/rune.d.ts +5 -3
  43. package/dist/L/rune.js +11 -4
  44. package/dist/L/rune.js.map +1 -1
  45. package/dist/LEvent.js +1 -1
  46. package/dist/LEvent.js.map +1 -1
  47. package/dist/Model.d.ts +4 -2
  48. package/dist/Model.js +12 -7
  49. package/dist/Model.js.map +1 -1
  50. package/dist/ModelRegistry.d.ts +0 -1
  51. package/dist/ModelRegistry.js +0 -7
  52. package/dist/ModelRegistry.js.map +1 -1
  53. package/dist/Rune.d.ts +4 -2
  54. package/dist/Rune.js.map +1 -1
  55. package/dist/Tool.d.ts +9 -0
  56. package/dist/Tool.js +31 -0
  57. package/dist/Tool.js.map +1 -0
  58. package/dist/ToolRegistry.d.ts +5 -0
  59. package/dist/ToolRegistry.js +5 -0
  60. package/dist/ToolRegistry.js.map +1 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +2 -0
  63. package/dist/index.js.map +1 -1
  64. package/dist/tsconfig.tsbuildinfo +1 -1
  65. package/index.ts +2 -0
  66. package/package.json +3 -3
  67. package/cli/main.ts +0 -1
  68. package/dist/cli/main.d.ts +0 -1
  69. package/dist/cli/main.js +0 -3
  70. package/dist/cli/main.js.map +0 -1
package/Agent.ts CHANGED
@@ -5,11 +5,13 @@ import { MessageRegistry, MessageRegistryContext } from "./MessageRegistry.ts"
5
5
  import { ModelRegistry, ModelRegistryContext } from "./ModelRegistry.ts"
6
6
  import type { Rune } from "./Rune.ts"
7
7
  import type { Runic } from "./Runic.ts"
8
+ import { ToolRegistry, ToolRegistryContext } from "./ToolRegistry.ts"
8
9
 
9
- export interface AgentConfig<E> {
10
- handler?: ((this: Fiber, event: E) => void) | undefined
10
+ export interface AgentConfig<T, E> {
11
+ handler?: ((this: Fiber<T>, event: E) => void) | undefined
11
12
  models?: ModelRegistry
12
13
  messages?: MessageRegistry
14
+ tools?: ToolRegistry
13
15
  signal?: AbortSignal | undefined
14
16
  }
15
17
 
@@ -20,16 +22,17 @@ export interface Agent<out T, out E> extends PromiseLike<T> {
20
22
 
21
23
  export function Agent<Y extends Rune, T>(
22
24
  runic: Runic<Y, T>,
23
- config?: AgentConfig<Rune.E<Y>>,
25
+ config?: AgentConfig<T, Rune.E<Y>>,
24
26
  ): Agent<T, Rune.E<Y>> {
25
27
  return {
26
28
  then(onfulfilled, onrejected) {
27
- const rootCtx = new Context([
29
+ return new Context([
28
30
  [HandlerContext, config?.handler],
29
31
  [ModelRegistryContext, config?.models ?? new ModelRegistry()],
30
32
  [MessageRegistryContext, config?.messages ?? new MessageRegistry()],
33
+ [ToolRegistryContext, config?.tools ?? new ToolRegistry()],
31
34
  ])
32
- return rootCtx.run(() => new Fiber(runic).resolve().then(onfulfilled, onrejected))
35
+ .run(() => new Fiber(runic).resolution().then(onfulfilled, onrejected))
33
36
  },
34
37
  } satisfies Omit<Agent<T, Rune.E<Y>>, "E" | "T"> as never
35
38
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # liminal
2
2
 
3
+ ## 0.5.9
4
+
5
+ ### Patch Changes
6
+
7
+ - dbd5e93: Reintroduced tools and various examples.
8
+
9
+ ## 0.5.8
10
+
11
+ ### Patch Changes
12
+
13
+ - 23a24ae: Reintroduce L.catch and clean up parts of the generator runtime.
14
+ - f2f360c: Continue to clean up the generator runtime internals.
15
+ - Updated dependencies [23a24ae]
16
+ - Updated dependencies [f2f360c]
17
+ - liminal-schema@0.0.3
18
+ - liminal-util@0.0.4
19
+
3
20
  ## 0.5.7
4
21
 
5
22
  ### Patch Changes
package/Context.ts CHANGED
@@ -14,15 +14,6 @@ export class Context extends Map<ContextHandle, unknown> {
14
14
  return super.get(context) as never
15
15
  }
16
16
 
17
- getOrInit<V>(context: ContextHandle<V>, init: () => V): V {
18
- if (this.has(context)) {
19
- return this.get(context) as V
20
- }
21
- const instance = init()
22
- this.set(context, instance)
23
- return instance
24
- }
25
-
26
17
  set<V>(context: ContextHandle<V>, value: V): this {
27
18
  super.set(context, value)
28
19
  return this
@@ -44,7 +35,7 @@ export class Context extends Map<ContextHandle, unknown> {
44
35
  }
45
36
 
46
37
  export type ContextHandle<V = any> = {
47
- clone?: ((value: V) => V) | undefined
38
+ clone: ((value: V) => V) | undefined
48
39
  }
49
40
 
50
41
  export function ContextHandle<V>(clone?: (value: V) => V): ContextHandle<V> {
package/Fiber.ts CHANGED
@@ -3,41 +3,108 @@ import { Context } from "./Context.ts"
3
3
  import type { Rune } from "./Rune.ts"
4
4
  import { Runic } from "./Runic.ts"
5
5
 
6
- let nextIndex = 0
6
+ export type FiberStatus<T> = {
7
+ type: "untouched"
8
+ } | {
9
+ type: "pending"
10
+ self: AbortSignal
11
+ promise: Promise<T>
12
+ } | {
13
+ type: "aborted"
14
+ reason: unknown
15
+ } | {
16
+ type: "resolved"
17
+ value: T
18
+ } | {
19
+ type: "rejected"
20
+ exception: unknown
21
+ }
7
22
 
8
23
  export class Fiber<T = any> {
9
- readonly index = nextIndex++
24
+ static nextIndex: number = 0
25
+
26
+ declare T: T
27
+ readonly index: number = Fiber.nextIndex++
28
+
29
+ #runic: Runic<Rune, T>
10
30
  declare readonly parent?: Fiber
11
- context = Context.ensure()
12
- pending: Promise<T> | undefined
13
- constructor(readonly runic: Runic<Rune, T>, parent?: Fiber) {
31
+ #context: Context = Context.ensure()
32
+
33
+ signal: AbortSignal
34
+ either: AbortSignal
35
+ abort: (reason?: any) => void
36
+
37
+ status: FiberStatus<T> = { type: "untouched" }
38
+
39
+ constructor(runic: Runic<Rune, T>, parent?: Fiber) {
40
+ this.#runic = runic
14
41
  if (parent) {
15
42
  this.parent = parent
16
43
  }
44
+ const controller = new AbortController()
45
+ this.signal = controller.signal
46
+ this.either = AbortSignal.any([
47
+ ...this.parent?.signal ? [this.parent.signal] : [],
48
+ this.signal,
49
+ ])
50
+ this.abort = controller.abort.bind(controller)
17
51
  }
18
52
 
19
- resolve(this: Fiber<T>): Promise<T> {
20
- if (!this.pending) {
21
- const { promise, resolve, reject } = Promise.withResolvers<T>()
22
- this.pending = promise
23
- const iterator = Runic.unwrap(this.runic)
24
- let nextArg: unknown
25
- this.context.run(async () => {
26
- try {
27
- let current = await iterator.next()
28
- while (!current.done) {
29
- const rune = current.value
30
- nextArg = await rune(this)
31
- current = await iterator.next(nextArg)
32
- }
33
- const { value } = current
34
- resolve(value)
35
- } catch (error) {
36
- reject(error)
53
+ fork<T>(runic: Runic<Rune, T>): Fiber<T> {
54
+ return new Fiber(runic, this)
55
+ }
56
+
57
+ resolution(this: Fiber<T>): Promise<T> {
58
+ const { status, abort } = this
59
+ switch (status.type) {
60
+ case "untouched": {
61
+ const { promise, resolve, reject } = Promise.withResolvers<T>()
62
+ this.status = {
63
+ type: "pending",
64
+ self: this.signal,
65
+ promise,
37
66
  }
38
- })
67
+ const iterator = Runic.unwrap(this.#runic)
68
+ let nextArg: unknown
69
+ this.#context.run(async () => {
70
+ try {
71
+ let current = await iterator.next()
72
+ while (!current.done) {
73
+ const rune = current.value
74
+ nextArg = await rune(this)
75
+ current = await iterator.next(nextArg)
76
+ }
77
+ const { value } = current
78
+ this.status = {
79
+ type: "resolved",
80
+ value,
81
+ }
82
+ abort()
83
+ resolve(value)
84
+ } catch (exception) {
85
+ this.status = {
86
+ type: "rejected",
87
+ exception,
88
+ }
89
+ abort(exception)
90
+ reject(exception)
91
+ }
92
+ })
93
+ return promise
94
+ }
95
+ case "pending": {
96
+ return status.promise
97
+ }
98
+ case "resolved": {
99
+ return Promise.resolve(status.value)
100
+ }
101
+ case "rejected": {
102
+ return Promise.reject(status.exception)
103
+ }
104
+ case "aborted": {
105
+ return Promise.reject(status.reason)
106
+ }
39
107
  }
40
- return this.pending
41
108
  }
42
109
 
43
110
  static {
package/L/L.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./_infer.ts"
3
3
  export * from "./_message.ts"
4
4
  export * from "./assistant.ts"
5
5
  export * from "./branch.ts"
6
+ export * from "./catch.ts"
6
7
  export * from "./emit.ts"
7
8
  export * from "./model.ts"
8
9
  export * from "./system.ts"
package/L/_infer.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { SchemaObject } from "liminal-schema"
2
2
  import { assert } from "liminal-util"
3
- import { Context, ContextHandle } from "../Context.ts"
3
+ import { Context } from "../Context.ts"
4
4
  import { InferenceRequested, Inferred, type LEvent } from "../LEvent.ts"
5
5
  import { MessageRegistryContext } from "../MessageRegistry.ts"
6
6
  import { ModelRegistryContext } from "../ModelRegistry.ts"
@@ -14,20 +14,18 @@ export function* _infer(schema?: SchemaObject): Generator<Rune<LEvent>, string>
14
14
  assert(modelRegistry)
15
15
  const model = modelRegistry.peek()
16
16
  assert(model)
17
- const requestId = context.getOrInit(InferenceRequestCounterContext, () => new InferenceRequestCounter()).next()
17
+ const requestId = InferenceCounter.next()
18
18
  yield* emit(new InferenceRequested(requestId, schema))
19
19
  const messageRegistry = context.get(MessageRegistryContext)
20
20
  assert(messageRegistry)
21
- const inference = yield* rune(() => model.resolve(messageRegistry.messages, schema))
21
+ const inference = yield* rune(() => model.resolve(messageRegistry.messages, schema), "infer")
22
22
  yield* emit(new Inferred(requestId, inference))
23
23
  return inference
24
24
  }
25
25
 
26
- class InferenceRequestCounter {
27
- count: number = 0
28
- next(): number {
26
+ class InferenceCounter {
27
+ static count: number = 0
28
+ static next(): number {
29
29
  return this.count++
30
30
  }
31
31
  }
32
-
33
- const InferenceRequestCounterContext: ContextHandle<InferenceRequestCounter> = ContextHandle()
package/L/assistant.ts CHANGED
@@ -6,7 +6,7 @@ import { _message } from "./_message.ts"
6
6
  import { rune } from "./rune.ts"
7
7
 
8
8
  export interface assistant extends Iterable<Rune<LEvent>, string> {
9
- <T>(schema: LType<T>): Generator<Rune<LEvent>, T>
9
+ <T>(type: LType<T>): Generator<Rune<LEvent>, T>
10
10
  }
11
11
 
12
12
  export const assistant: assistant = Object.assign(
@@ -15,7 +15,7 @@ export const assistant: assistant = Object.assign(
15
15
  const inference = yield* _infer(schema)
16
16
  yield* _message("assistant", [{ part: inference }])
17
17
  const input = JSON.parse(inference)
18
- return yield* rune(() => validate(type, input))
18
+ return yield* rune(() => validate(type, input), "validate_assistant_message")
19
19
  },
20
20
  {
21
21
  *[Symbol.iterator]() {
package/L/branch.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Context } from "../Context.ts"
2
- import { Fiber } from "../Fiber.ts"
3
2
  import { type Rune } from "../Rune.ts"
4
3
  import type { Runic } from "../Runic.ts"
5
4
  import { rune } from "./rune.ts"
@@ -15,15 +14,20 @@ export function branch<XR extends Record<keyof any, Runic>>(
15
14
  ): branch<Runic.Y<XR[keyof XR]> | Rune<never>, { [K in keyof XR]: Runic.T<XR[K]> }>
16
15
  export function* branch(value: Runic | Array<Runic> | Record<keyof any, Runic>): branch<Rune, any> {
17
16
  const context = Context.ensure()
18
- const parent = yield* rune((fiber) => fiber)
17
+ const parent = yield* rune
19
18
  if (Array.isArray(value)) {
20
- const fibers = value.map((runic) => context.clone().run(() => new Fiber(runic, parent)))
21
- return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.resolve())))
19
+ const fibers = value.map((runic) => context.clone().run(() => parent.fork(runic)))
20
+ return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.resolution())), "branch")
22
21
  } else if (typeof value === "object") {
23
- const entries = Object.entries(value)
24
- const fibers = entries.map(([_key, runic]) => context.clone().run(() => new Fiber(runic, parent)))
25
- return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.resolve())).then(Object.fromEntries))
22
+ const fibers = Object.values(value).map((runic) => context.clone().run(() => parent.fork(runic)))
23
+ return yield* rune(async () => {
24
+ const keys = Object.keys(value)
25
+ return await Promise
26
+ .all(fibers.map((fiber) => fiber.resolution()))
27
+ .then((resolved) => resolved.map((value, i) => [keys[i], value]))
28
+ .then(Object.fromEntries)
29
+ }, "branch")
26
30
  }
27
- const fiber = context.clone().run(() => new Fiber(typeof value === "function" ? value() : value, parent))
28
- return yield* rune(() => fiber.resolve())
31
+ const fiber = context.clone().run(() => parent.fork(typeof value === "function" ? value() : value))
32
+ return yield* rune(() => fiber.resolution(), "branch")
29
33
  }
package/L/catch.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { Rune } from "../Rune.ts"
2
+ import type { Runic } from "../Runic.ts"
3
+ import { rune } from "./rune.ts"
4
+
5
+ export { catch_ as catch }
6
+ function* catch_<Y extends Rune, T>(runic: Runic<Y, T>): Generator<Rune<Y>, CatchResult<T>> {
7
+ return yield* rune(async (fiber) => {
8
+ try {
9
+ return { resolved: await fiber.fork(runic).resolution() }
10
+ } catch (exception: unknown) {
11
+ return { rejected: exception }
12
+ }
13
+ }, "catch")
14
+ }
15
+ Object.defineProperty(catch_, "name", { value: "catch" })
16
+
17
+ export type CatchResult<T> = {
18
+ resolved: T
19
+ rejected?: never
20
+ } | {
21
+ resolved?: never
22
+ rejected: unknown
23
+ }
package/L/emit.ts CHANGED
@@ -9,6 +9,6 @@ export interface emit<E> extends Generator<Rune<E>, void> {}
9
9
  export function* emit<const E>(event: EnsureNarrow<E>): emit<E> {
10
10
  const context = Context.ensure()
11
11
  const handler = context.get(HandlerContext)
12
- const fiber = yield* rune((fiber) => fiber)
12
+ const fiber = yield* rune
13
13
  handler?.call(fiber, event)
14
14
  }
package/L/rune.ts CHANGED
@@ -1,19 +1,30 @@
1
1
  import { Fiber } from "../Fiber.ts"
2
2
  import { type Rune, RuneKey } from "../Rune.ts"
3
3
 
4
- export interface rune<T> extends Iterable<Rune<never>, T> {
5
- <E>(): Generator<Rune<E>, T>
4
+ export interface rune extends Iterable<Rune<never>, Fiber> {
5
+ <R>(source: (fiber: Fiber) => R, debug?: string): Iterable<Rune<never>, Awaited<R>> & {
6
+ <E>(): Generator<Rune<E>, Awaited<R>>
7
+ }
6
8
  }
7
-
8
- export function rune<R>(source: (fiber: Fiber) => R): rune<Awaited<R>> {
9
- return Object.assign(
10
- function*<E>(): Generator<Rune<E>, Awaited<R>> {
11
- return yield Object.assign(source, { [RuneKey]: {} as never })
12
- },
13
- {
14
- *[Symbol.iterator](): Generator<Rune<never>, Awaited<R>> {
15
- return yield Object.assign(source, { [RuneKey]: {} as never })
9
+ export const rune: rune = Object.assign(
10
+ function<R>(source: (fiber: Fiber) => R, debug?: string) {
11
+ return Object.assign(
12
+ function*<E>(): Generator<Rune<E>, Awaited<R>> {
13
+ return yield Object.assign(source, { [RuneKey]: true, debug } as never)
16
14
  },
15
+ {
16
+ *[Symbol.iterator](): Generator<Rune<never>, Awaited<R>> {
17
+ return yield Object.assign(source, { [RuneKey]: true, debug } as never)
18
+ },
19
+ },
20
+ )
21
+ },
22
+ {
23
+ *[Symbol.iterator](): Generator<Rune<never>, Fiber> {
24
+ return yield Object.assign((fiber: Fiber) => fiber, {
25
+ [RuneKey]: true,
26
+ debug: "get_current_fiber",
27
+ } as never)
17
28
  },
18
- )
19
- }
29
+ },
30
+ )
package/LEvent.ts CHANGED
@@ -58,5 +58,5 @@ export class FiberResolved extends EventBase(LEventTag, "fiber_resolved") {
58
58
  }
59
59
 
60
60
  export function isLEvent(value: unknown): value is LEvent {
61
- return typeof value === "object" && value !== null && LEventTag in value
61
+ return typeof value === "object" && value !== null && "brand" in value && value.brand === LEventTag
62
62
  }
package/Model.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import type { Schema } from "liminal-schema"
2
+ import { attachCustomInspect } from "liminal-util"
2
3
  import type { Message } from "./Message.ts"
3
4
 
4
- export interface Model {
5
- resolve(messages: Array<Message>, schema?: Schema): Promise<string>
6
- }
5
+ export class Model {
6
+ constructor(
7
+ readonly vendor: string,
8
+ readonly resolve: (messages: Array<Message>, schema?: Schema) => Promise<string>,
9
+ ) {}
7
10
 
8
- // export interface ModelCapabilities {
9
- // readonly url: boolean
10
- // readonly mimes: Set<string>
11
- // readonly reasoning: boolean
12
- // readonly structures: boolean
13
- // }
11
+ static {
12
+ attachCustomInspect(this, ({ vendor }) => ({ vendor }))
13
+ }
14
+ }
package/ModelRegistry.ts CHANGED
@@ -6,14 +6,6 @@ export class ModelRegistry {
6
6
  declare head?: ModelRegistryNode | undefined
7
7
  declare tail?: ModelRegistryNode | undefined
8
8
 
9
- constructor(models?: Array<Model>) {
10
- if (models) {
11
- for (const model of models) {
12
- this.register(model)
13
- }
14
- }
15
- }
16
-
17
9
  peek() {
18
10
  return this.tail?.model
19
11
  }
package/Rune.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import type { Fiber } from "./Fiber.ts"
2
2
 
3
3
  export interface Rune<out E = any> {
4
+ E: E
4
5
  (fiber: Fiber): any
5
- [RuneKey]: E
6
+ [RuneKey]: true
7
+ debug?: string
6
8
  }
7
9
 
8
10
  export declare namespace Rune {
9
- export type E<X extends Rune> = X[RuneKey]
11
+ export type E<X extends Rune> = X["E"]
10
12
  }
11
13
 
12
14
  export const RuneKey: unique symbol = Symbol.for("liminal/Rune")
package/Tool.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { type LType, type SchemaObject, toJSONSchema, validate, type Value, type ValueObject } from "liminal-schema"
2
+ import { subtle } from "node:crypto"
3
+
4
+ export class Tool {
5
+ static async make<T extends ValueObject>(
6
+ description: string,
7
+ type: LType<T>,
8
+ f: (arg: T) => Value | Promise<Value>,
9
+ ) {
10
+ const encoder = new TextEncoder()
11
+ const schema = toJSONSchema(type)
12
+ const buffer = await subtle.digest("SHA-256", encoder.encode(description + "\n\n" + JSON.stringify(schema)))
13
+ const bytes = new Uint8Array(buffer)
14
+ let binary = ""
15
+ for (const b of bytes) binary += String.fromCharCode(b)
16
+ const base64 = btoa(binary)
17
+ .replace(/\+/g, "-")
18
+ .replace(/\//g, "_")
19
+ .replace(/=+$/, "")
20
+ return new Tool(base64, description, schema, async (arg) => {
21
+ return await f(await validate(type, arg) as never)
22
+ })
23
+ }
24
+
25
+ constructor(
26
+ readonly name: string,
27
+ readonly description: string,
28
+ readonly parameterSchema: SchemaObject,
29
+ readonly f: (arg: any) => Value | Promise<Value>,
30
+ ) {}
31
+ }
@@ -0,0 +1,5 @@
1
+ import { ContextHandle } from "liminal"
2
+ import type { Tool } from "./Tool"
3
+
4
+ export class ToolRegistry extends Set<Tool> {}
5
+ export const ToolRegistryContext: ContextHandle<ToolRegistry> = ContextHandle()
package/dist/Agent.d.ts CHANGED
@@ -3,14 +3,16 @@ import { MessageRegistry } from "./MessageRegistry.ts";
3
3
  import { ModelRegistry } from "./ModelRegistry.ts";
4
4
  import type { Rune } from "./Rune.ts";
5
5
  import type { Runic } from "./Runic.ts";
6
- export interface AgentConfig<E> {
7
- handler?: ((this: Fiber, event: E) => void) | undefined;
6
+ import { ToolRegistry } from "./ToolRegistry.ts";
7
+ export interface AgentConfig<T, E> {
8
+ handler?: ((this: Fiber<T>, event: E) => void) | undefined;
8
9
  models?: ModelRegistry;
9
10
  messages?: MessageRegistry;
11
+ tools?: ToolRegistry;
10
12
  signal?: AbortSignal | undefined;
11
13
  }
12
14
  export interface Agent<out T, out E> extends PromiseLike<T> {
13
15
  T: T;
14
16
  E: E;
15
17
  }
16
- export declare function Agent<Y extends Rune, T>(runic: Runic<Y, T>, config?: AgentConfig<Rune.E<Y>>): Agent<T, Rune.E<Y>>;
18
+ export declare function Agent<Y extends Rune, T>(runic: Runic<Y, T>, config?: AgentConfig<T, Rune.E<Y>>): Agent<T, Rune.E<Y>>;
package/dist/Agent.js CHANGED
@@ -3,15 +3,17 @@ import { Fiber } from "./Fiber.js";
3
3
  import { HandlerContext } from "./Handler.js";
4
4
  import { MessageRegistry, MessageRegistryContext } from "./MessageRegistry.js";
5
5
  import { ModelRegistry, ModelRegistryContext } from "./ModelRegistry.js";
6
+ import { ToolRegistry, ToolRegistryContext } from "./ToolRegistry.js";
6
7
  export function Agent(runic, config) {
7
8
  return {
8
9
  then(onfulfilled, onrejected) {
9
- const rootCtx = new Context([
10
+ return new Context([
10
11
  [HandlerContext, config?.handler],
11
12
  [ModelRegistryContext, config?.models ?? new ModelRegistry()],
12
13
  [MessageRegistryContext, config?.messages ?? new MessageRegistry()],
13
- ]);
14
- return rootCtx.run(() => new Fiber(runic).resolve().then(onfulfilled, onrejected));
14
+ [ToolRegistryContext, config?.tools ?? new ToolRegistry()],
15
+ ])
16
+ .run(() => new Fiber(runic).resolution().then(onfulfilled, onrejected));
15
17
  },
16
18
  };
17
19
  }
package/dist/Agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Agent.js","sourceRoot":"","sources":["../Agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAgBxE,MAAM,UAAU,KAAK,CACnB,KAAkB,EAClB,MAA+B;IAE/B,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,UAAU;YAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC1B,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;gBACjC,CAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC7D,CAAC,sBAAsB,EAAE,MAAM,EAAE,QAAQ,IAAI,IAAI,eAAe,EAAE,CAAC;aACpE,CAAC,CAAA;YACF,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;QACpF,CAAC;KACsD,CAAA;AAC3D,CAAC"}
1
+ {"version":3,"file":"Agent.js","sourceRoot":"","sources":["../Agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAGxE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAerE,MAAM,UAAU,KAAK,CACnB,KAAkB,EAClB,MAAkC;IAElC,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,UAAU;YAC1B,OAAO,IAAI,OAAO,CAAC;gBACjB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;gBACjC,CAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC7D,CAAC,sBAAsB,EAAE,MAAM,EAAE,QAAQ,IAAI,IAAI,eAAe,EAAE,CAAC;gBACnE,CAAC,mBAAmB,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI,YAAY,EAAE,CAAC;aAC3D,CAAC;iBACC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;QAC3E,CAAC;KACsD,CAAA;AAC3D,CAAC"}
package/dist/Context.d.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  export declare class Context extends Map<ContextHandle, unknown> {
2
2
  static ensure(): Context;
3
3
  get<V>(context: ContextHandle<V>): V | undefined;
4
- getOrInit<V>(context: ContextHandle<V>, init: () => V): V;
5
4
  set<V>(context: ContextHandle<V>, value: V): this;
6
5
  run<R>(callback: () => R): R;
7
6
  clone(overrides?: Iterable<[ContextHandle, unknown]>): Context;
8
7
  }
9
8
  export type ContextHandle<V = any> = {
10
- clone?: ((value: V) => V) | undefined;
9
+ clone: ((value: V) => V) | undefined;
11
10
  };
12
11
  export declare function ContextHandle<V>(clone?: (value: V) => V): ContextHandle<V>;
package/dist/Context.js CHANGED
@@ -10,14 +10,6 @@ export class Context extends Map {
10
10
  get(context) {
11
11
  return super.get(context);
12
12
  }
13
- getOrInit(context, init) {
14
- if (this.has(context)) {
15
- return this.get(context);
16
- }
17
- const instance = init();
18
- this.set(context, instance);
19
- return instance;
20
- }
21
13
  set(context, value) {
22
14
  super.set(context, value);
23
15
  return this;
@@ -1 +1 @@
1
- {"version":3,"file":"Context.js","sourceRoot":"","sources":["../Context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAW,CAAA;AAEhD,MAAM,OAAO,OAAQ,SAAQ,GAA2B;IACtD,MAAM,CAAC,MAAM;QACX,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,MAAM,CAAC,OAAO,CAAC,CAAA;QACf,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,GAAG,CAAI,OAAyB;QAC9B,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAU,CAAA;IACpC,CAAC;IAED,SAAS,CAAI,OAAyB,EAAE,IAAa;QACnD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAM,CAAA;QAC/B,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,EAAE,CAAA;QACvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAC3B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,GAAG,CAAI,OAAyB,EAAE,KAAQ;QACxC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,GAAG,CAAI,QAAiB;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,SAA8C;QAClD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;QACtC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAMD,MAAM,UAAU,aAAa,CAAI,KAAuB;IACtD,OAAO,EAAE,KAAK,EAAE,CAAA;AAClB,CAAC"}
1
+ {"version":3,"file":"Context.js","sourceRoot":"","sources":["../Context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAW,CAAA;AAEhD,MAAM,OAAO,OAAQ,SAAQ,GAA2B;IACtD,MAAM,CAAC,MAAM;QACX,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,MAAM,CAAC,OAAO,CAAC,CAAA;QACf,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,GAAG,CAAI,OAAyB;QAC9B,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAU,CAAA;IACpC,CAAC;IAED,GAAG,CAAI,OAAyB,EAAE,KAAQ;QACxC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,GAAG,CAAI,QAAiB;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,SAA8C;QAClD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;QACtC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAMD,MAAM,UAAU,aAAa,CAAI,KAAuB;IACtD,OAAO,EAAE,KAAK,EAAE,CAAA;AAClB,CAAC"}
package/dist/Fiber.d.ts CHANGED
@@ -1,12 +1,32 @@
1
- import { Context } from "./Context.ts";
2
1
  import type { Rune } from "./Rune.ts";
3
2
  import { Runic } from "./Runic.ts";
3
+ export type FiberStatus<T> = {
4
+ type: "untouched";
5
+ } | {
6
+ type: "pending";
7
+ self: AbortSignal;
8
+ promise: Promise<T>;
9
+ } | {
10
+ type: "aborted";
11
+ reason: unknown;
12
+ } | {
13
+ type: "resolved";
14
+ value: T;
15
+ } | {
16
+ type: "rejected";
17
+ exception: unknown;
18
+ };
4
19
  export declare class Fiber<T = any> {
5
- readonly runic: Runic<Rune, T>;
20
+ #private;
21
+ static nextIndex: number;
22
+ T: T;
6
23
  readonly index: number;
7
24
  readonly parent?: Fiber;
8
- context: Context;
9
- pending: Promise<T> | undefined;
25
+ signal: AbortSignal;
26
+ either: AbortSignal;
27
+ abort: (reason?: any) => void;
28
+ status: FiberStatus<T>;
10
29
  constructor(runic: Runic<Rune, T>, parent?: Fiber);
11
- resolve(this: Fiber<T>): Promise<T>;
30
+ fork<T>(runic: Runic<Rune, T>): Fiber<T>;
31
+ resolution(this: Fiber<T>): Promise<T>;
12
32
  }