liminal 0.5.10 → 0.5.11
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.
- package/CHANGELOG.md +9 -0
- package/Context.ts +21 -24
- package/Fiber.ts +59 -52
- package/Handler.ts +2 -2
- package/L/L.ts +4 -3
- package/L/assistant.ts +6 -6
- package/L/catch.ts +15 -2
- package/L/emit.ts +3 -7
- package/L/{_infer.ts → infer.ts} +9 -6
- package/L/{_message.ts → message.ts} +3 -5
- package/L/model.ts +1 -3
- package/L/rune.ts +8 -26
- package/L/strand.ts +99 -0
- package/L/stream.ts +3 -5
- package/L/system.ts +2 -2
- package/L/user.ts +2 -2
- package/MessageRegistry.ts +4 -3
- package/ModelRegistry.ts +13 -8
- package/ToolRegistry.ts +8 -3
- package/dist/Context.d.ts +10 -10
- package/dist/Context.js +16 -19
- package/dist/Context.js.map +1 -1
- package/dist/Fiber.d.ts +19 -15
- package/dist/Fiber.js +34 -30
- package/dist/Fiber.js.map +1 -1
- package/dist/Handler.d.ts +2 -2
- package/dist/Handler.js +2 -2
- package/dist/Handler.js.map +1 -1
- package/dist/L/L.d.ts +4 -3
- package/dist/L/L.js +4 -3
- package/dist/L/L.js.map +1 -1
- package/dist/L/assistant.js +6 -6
- package/dist/L/assistant.js.map +1 -1
- package/dist/L/catch.js +12 -2
- package/dist/L/catch.js.map +1 -1
- package/dist/L/emit.js +3 -7
- package/dist/L/emit.js.map +1 -1
- package/dist/L/infer.d.ts +7 -0
- package/dist/L/{_infer.js → infer.js} +7 -7
- package/dist/L/infer.js.map +1 -0
- package/dist/L/message.d.ts +6 -0
- package/dist/L/{_message.js → message.js} +3 -5
- package/dist/L/message.js.map +1 -0
- package/dist/L/model.js +1 -3
- package/dist/L/model.js.map +1 -1
- package/dist/L/rune.d.ts +1 -6
- package/dist/L/rune.js +5 -15
- package/dist/L/rune.js.map +1 -1
- package/dist/L/strand.d.ts +26 -0
- package/dist/L/strand.js +69 -0
- package/dist/L/strand.js.map +1 -0
- package/dist/L/stream.js +3 -5
- package/dist/L/stream.js.map +1 -1
- package/dist/L/system.js +2 -2
- package/dist/L/system.js.map +1 -1
- package/dist/L/user.js +2 -2
- package/dist/L/user.js.map +1 -1
- package/dist/MessageRegistry.d.ts +2 -2
- package/dist/MessageRegistry.js +2 -2
- package/dist/MessageRegistry.js.map +1 -1
- package/dist/ModelRegistry.d.ts +3 -2
- package/dist/ModelRegistry.js +9 -8
- package/dist/ModelRegistry.js.map +1 -1
- package/dist/ToolRegistry.d.ts +3 -2
- package/dist/ToolRegistry.js +5 -2
- package/dist/ToolRegistry.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +0 -1
- package/package.json +4 -4
- package/Agent.ts +0 -38
- package/L/branch.ts +0 -33
- package/dist/Agent.d.ts +0 -18
- package/dist/Agent.js +0 -20
- package/dist/Agent.js.map +0 -1
- package/dist/L/_infer.d.ts +0 -4
- package/dist/L/_infer.js.map +0 -1
- package/dist/L/_message.d.ts +0 -6
- package/dist/L/_message.js.map +0 -1
- package/dist/L/branch.d.ts +0 -11
- package/dist/L/branch.js +0 -24
- package/dist/L/branch.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# liminal
|
|
2
2
|
|
|
3
|
+
## 0.5.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cf42ed2: Agent -> Strand. Making the API more uniform. Ie. Agent -> L.strand. L.branch -> L.strand.
|
|
8
|
+
- Updated dependencies [cf42ed2]
|
|
9
|
+
- liminal-schema@0.0.5
|
|
10
|
+
- liminal-util@0.0.6
|
|
11
|
+
|
|
3
12
|
## 0.5.10
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/Context.ts
CHANGED
|
@@ -1,43 +1,40 @@
|
|
|
1
|
-
import { assert } from "liminal-util"
|
|
2
1
|
import { AsyncLocalStorage } from "node:async_hooks"
|
|
3
2
|
|
|
4
3
|
const storage = new AsyncLocalStorage<Context>()
|
|
5
4
|
|
|
6
|
-
export class Context extends Map<
|
|
7
|
-
static
|
|
8
|
-
|
|
9
|
-
assert(context)
|
|
10
|
-
return context
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
get<V>(context: ContextHandle<V>): V | undefined {
|
|
14
|
-
return super.get(context) as never
|
|
5
|
+
export class Context extends Map<ContextPart, unknown> {
|
|
6
|
+
static get(): Context | undefined {
|
|
7
|
+
return storage.getStore()
|
|
15
8
|
}
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return this
|
|
10
|
+
run<R>(f: () => R): R {
|
|
11
|
+
return storage.run(this, f)
|
|
20
12
|
}
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
clone(overrides?: Iterable<[ContextHandle, unknown]>): Context {
|
|
27
|
-
const context = new Context(overrides)
|
|
14
|
+
fork(): Context {
|
|
15
|
+
const context = new Context()
|
|
28
16
|
for (const [handle, value] of this.entries()) {
|
|
29
17
|
if (!context.has(handle)) {
|
|
30
|
-
context.set(handle, handle.
|
|
18
|
+
context.set(handle, handle.fork(value))
|
|
31
19
|
}
|
|
32
20
|
}
|
|
33
21
|
return context
|
|
34
22
|
}
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
export
|
|
38
|
-
|
|
25
|
+
export interface ContextPart<V = any> {
|
|
26
|
+
fork(parent?: V): V
|
|
27
|
+
get(): V | undefined
|
|
28
|
+
debug?: string
|
|
39
29
|
}
|
|
40
30
|
|
|
41
|
-
export function
|
|
42
|
-
|
|
31
|
+
export function ContextPart<V>(fork: (parent?: V) => V, debug?: string): ContextPart<V> {
|
|
32
|
+
const self: ContextPart<V> = {
|
|
33
|
+
fork,
|
|
34
|
+
get() {
|
|
35
|
+
return Context.get()?.get(self) as never
|
|
36
|
+
},
|
|
37
|
+
...debug && { debug },
|
|
38
|
+
}
|
|
39
|
+
return self
|
|
43
40
|
}
|
package/Fiber.ts
CHANGED
|
@@ -1,73 +1,63 @@
|
|
|
1
1
|
import { attachCustomInspect } from "liminal-util"
|
|
2
2
|
import { Context } from "./Context.ts"
|
|
3
3
|
import { type Handler, HandlerContext } from "./Handler.ts"
|
|
4
|
+
import { ToolRegistry, ToolRegistryContext } from "./index.ts"
|
|
4
5
|
import { FiberCreated, FiberRejected, FiberResolved, FiberStarted } from "./LEvent.ts"
|
|
5
|
-
import
|
|
6
|
+
import { MessageRegistry, MessageRegistryContext } from "./MessageRegistry.ts"
|
|
7
|
+
import { ModelRegistry, ModelRegistryContext } from "./ModelRegistry.ts"
|
|
8
|
+
import { type Rune, RuneKey } from "./Rune.ts"
|
|
6
9
|
import { Runic } from "./Runic.ts"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
promise: Promise<T>
|
|
13
|
-
} | {
|
|
14
|
-
type: "aborted"
|
|
15
|
-
reason: unknown
|
|
16
|
-
} | {
|
|
17
|
-
type: "resolved"
|
|
18
|
-
value: T
|
|
19
|
-
} | {
|
|
20
|
-
type: "rejected"
|
|
21
|
-
exception: unknown
|
|
10
|
+
|
|
11
|
+
export interface FiberConfig {
|
|
12
|
+
parent?: Fiber
|
|
13
|
+
signal?: AbortSignal
|
|
14
|
+
context: Context
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
export class Fiber<T = any> {
|
|
25
|
-
static
|
|
18
|
+
static *[Symbol.iterator](): Generator<Rune<never>, Fiber> {
|
|
19
|
+
return yield Object.assign((fiber: Fiber) => fiber, {
|
|
20
|
+
[RuneKey]: true,
|
|
21
|
+
debug: "current_fiber",
|
|
22
|
+
} as never)
|
|
23
|
+
}
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
static nextIndex: number = 0
|
|
28
26
|
readonly index: number = Fiber.nextIndex++
|
|
29
27
|
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
#
|
|
28
|
+
readonly #context: Context
|
|
29
|
+
readonly #runic: Runic<Rune, T>
|
|
30
|
+
readonly #handler: Handler | undefined = HandlerContext.get()
|
|
31
|
+
readonly #configSignal?: AbortSignal
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
either: AbortSignal
|
|
37
|
-
abort: (reason?: any) => void
|
|
33
|
+
declare readonly parent?: Fiber
|
|
38
34
|
|
|
39
35
|
status: FiberStatus<T> = { type: "untouched" }
|
|
36
|
+
controller: AbortController = new AbortController()
|
|
40
37
|
|
|
41
|
-
constructor(runic: Runic<Rune, T>,
|
|
38
|
+
constructor(runic: Runic<Rune, T>, config: FiberConfig) {
|
|
42
39
|
this.#runic = runic
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
this.either = AbortSignal.any([
|
|
49
|
-
...this.parent?.signal ? [this.parent.signal] : [],
|
|
50
|
-
this.signal,
|
|
51
|
-
])
|
|
52
|
-
this.abort = controller.abort.bind(controller)
|
|
53
|
-
this.#handler?.call(this, new FiberCreated())
|
|
40
|
+
const { context, parent, signal } = config
|
|
41
|
+
this.#context = context
|
|
42
|
+
if (parent) this.parent = parent
|
|
43
|
+
if (signal) this.#configSignal = signal
|
|
44
|
+
this.handle(new FiberCreated())
|
|
54
45
|
}
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
handle(event: any) {
|
|
48
|
+
this.#handler?.call(this, event)
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
resolution(
|
|
61
|
-
|
|
62
|
-
switch (status.type) {
|
|
51
|
+
resolution(): Promise<T> {
|
|
52
|
+
switch (this.status.type) {
|
|
63
53
|
case "untouched": {
|
|
64
54
|
const { promise, resolve, reject } = Promise.withResolvers<T>()
|
|
65
55
|
this.status = {
|
|
66
56
|
type: "pending",
|
|
67
|
-
self: this.signal,
|
|
57
|
+
self: this.controller.signal,
|
|
68
58
|
promise,
|
|
69
59
|
}
|
|
70
|
-
this
|
|
60
|
+
this.handle(new FiberStarted())
|
|
71
61
|
const iterator = Runic.unwrap(this.#runic)
|
|
72
62
|
let nextArg: unknown
|
|
73
63
|
this.#context.run(async () => {
|
|
@@ -83,32 +73,32 @@ export class Fiber<T = any> {
|
|
|
83
73
|
type: "resolved",
|
|
84
74
|
value,
|
|
85
75
|
}
|
|
86
|
-
this
|
|
87
|
-
abort()
|
|
76
|
+
this.handle(new FiberResolved(value))
|
|
77
|
+
this.controller.abort()
|
|
88
78
|
resolve(value)
|
|
89
79
|
} catch (exception) {
|
|
90
80
|
this.status = {
|
|
91
81
|
type: "rejected",
|
|
92
82
|
exception,
|
|
93
83
|
}
|
|
94
|
-
this
|
|
95
|
-
abort(
|
|
84
|
+
this.handle(new FiberRejected(exception))
|
|
85
|
+
this.controller.abort()
|
|
96
86
|
reject(exception)
|
|
97
87
|
}
|
|
98
88
|
})
|
|
99
89
|
return promise
|
|
100
90
|
}
|
|
101
91
|
case "pending": {
|
|
102
|
-
return status.promise
|
|
92
|
+
return this.status.promise
|
|
103
93
|
}
|
|
104
94
|
case "resolved": {
|
|
105
|
-
return Promise.resolve(status.value)
|
|
95
|
+
return Promise.resolve(this.status.value)
|
|
106
96
|
}
|
|
107
97
|
case "rejected": {
|
|
108
|
-
return Promise.reject(status.exception)
|
|
98
|
+
return Promise.reject(this.status.exception)
|
|
109
99
|
}
|
|
110
100
|
case "aborted": {
|
|
111
|
-
return Promise.reject(status.reason)
|
|
101
|
+
return Promise.reject(this.status.reason)
|
|
112
102
|
}
|
|
113
103
|
}
|
|
114
104
|
}
|
|
@@ -117,3 +107,20 @@ export class Fiber<T = any> {
|
|
|
117
107
|
attachCustomInspect(this, ({ index, parent }) => ({ index, ...parent && { parent } }))
|
|
118
108
|
}
|
|
119
109
|
}
|
|
110
|
+
|
|
111
|
+
export type FiberStatus<T> = {
|
|
112
|
+
type: "untouched"
|
|
113
|
+
} | {
|
|
114
|
+
type: "pending"
|
|
115
|
+
self: AbortSignal
|
|
116
|
+
promise: Promise<T>
|
|
117
|
+
} | {
|
|
118
|
+
type: "aborted"
|
|
119
|
+
reason: unknown
|
|
120
|
+
} | {
|
|
121
|
+
type: "resolved"
|
|
122
|
+
value: T
|
|
123
|
+
} | {
|
|
124
|
+
type: "rejected"
|
|
125
|
+
exception: unknown
|
|
126
|
+
}
|
package/Handler.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContextPart as ContextPart } from "./Context.ts"
|
|
2
2
|
import type { Fiber } from "./Fiber.ts"
|
|
3
3
|
|
|
4
4
|
export type Handler<E = any> = [(this: Fiber, event: E) => void][0]
|
|
5
5
|
|
|
6
|
-
export const HandlerContext:
|
|
6
|
+
export const HandlerContext: ContextPart<Handler | undefined> = ContextPart((parent) => parent, "handler")
|
package/L/L.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export * from "liminal-schema/factories"
|
|
2
|
-
export * from "./_infer.ts"
|
|
3
|
-
export * from "./_message.ts"
|
|
4
2
|
export * from "./assistant.ts"
|
|
5
|
-
export * from "./branch.ts"
|
|
6
3
|
export * from "./catch.ts"
|
|
7
4
|
export * from "./emit.ts"
|
|
5
|
+
export * from "./infer.ts"
|
|
6
|
+
export * from "./message.ts"
|
|
8
7
|
export * from "./model.ts"
|
|
8
|
+
export * from "./rune.ts"
|
|
9
|
+
export * from "./strand.ts"
|
|
9
10
|
export * from "./stream.ts"
|
|
10
11
|
export * from "./system.ts"
|
|
11
12
|
export * from "./user.ts"
|
package/L/assistant.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type LType, toJSONSchema, validate } from "liminal-schema"
|
|
2
2
|
import type { LEvent } from "../LEvent.ts"
|
|
3
3
|
import type { Rune } from "../Rune.ts"
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { infer } from "./infer.ts"
|
|
5
|
+
import { message } from "./message.ts"
|
|
6
6
|
import { rune } from "./rune.ts"
|
|
7
7
|
|
|
8
8
|
export interface assistant extends Iterable<Rune<LEvent>, string> {
|
|
@@ -12,15 +12,15 @@ export interface assistant extends Iterable<Rune<LEvent>, string> {
|
|
|
12
12
|
export const assistant: assistant = Object.assign(
|
|
13
13
|
function*<T>(type: LType<T>): Generator<Rune<LEvent>, T> {
|
|
14
14
|
const schema = toJSONSchema(type)
|
|
15
|
-
const inference = yield*
|
|
16
|
-
yield*
|
|
15
|
+
const inference = yield* infer(schema)
|
|
16
|
+
yield* message("assistant", [{ part: inference }])
|
|
17
17
|
const input = JSON.parse(inference)
|
|
18
18
|
return yield* rune(() => validate(type, input), "validate_assistant_message")
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
*[Symbol.iterator]() {
|
|
22
|
-
const inference = yield*
|
|
23
|
-
yield*
|
|
22
|
+
const inference = yield* infer()
|
|
23
|
+
yield* message("assistant", [{ part: inference }])
|
|
24
24
|
return inference
|
|
25
25
|
},
|
|
26
26
|
},
|
package/L/catch.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
+
import { assert } from "liminal-util"
|
|
2
|
+
import { Context } from "../Context.ts"
|
|
3
|
+
import { Fiber } from "../Fiber.ts"
|
|
1
4
|
import type { Rune } from "../Rune.ts"
|
|
2
5
|
import type { Runic } from "../Runic.ts"
|
|
3
6
|
import { rune } from "./rune.ts"
|
|
4
7
|
|
|
5
8
|
export { catch_ as catch }
|
|
9
|
+
|
|
6
10
|
function* catch_<Y extends Rune, T>(runic: Runic<Y, T>): Generator<Rune<Y>, CatchResult<T>> {
|
|
7
|
-
return yield* rune(async (
|
|
11
|
+
return yield* rune(async (parent) => {
|
|
8
12
|
try {
|
|
9
|
-
|
|
13
|
+
const context = Context.get()
|
|
14
|
+
assert(context)
|
|
15
|
+
return {
|
|
16
|
+
resolved: await context.fork().run(() =>
|
|
17
|
+
new Fiber(runic, {
|
|
18
|
+
context: context.fork(),
|
|
19
|
+
parent,
|
|
20
|
+
}).resolution()
|
|
21
|
+
),
|
|
22
|
+
}
|
|
10
23
|
} catch (exception: unknown) {
|
|
11
24
|
return { rejected: exception }
|
|
12
25
|
}
|
package/L/emit.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import type { EnsureNarrow } from "liminal-util"
|
|
2
|
-
import {
|
|
3
|
-
import { HandlerContext } from "../Handler.ts"
|
|
2
|
+
import { Fiber } from "../Fiber.ts"
|
|
4
3
|
import type { Rune } from "../Rune.ts"
|
|
5
|
-
import { rune } from "./rune.ts"
|
|
6
4
|
|
|
7
5
|
export interface emit<E> extends Generator<Rune<E>, void> {}
|
|
8
6
|
|
|
9
7
|
export function* emit<const E>(event: EnsureNarrow<E>): emit<E> {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const fiber = yield* rune
|
|
13
|
-
handler?.call(fiber, event)
|
|
8
|
+
const self = yield* Fiber
|
|
9
|
+
self.handle(event)
|
|
14
10
|
}
|
package/L/{_infer.ts → infer.ts}
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { SchemaObject } from "liminal-schema"
|
|
2
2
|
import { assert } from "liminal-util"
|
|
3
|
-
import { Context } from "../Context.ts"
|
|
4
3
|
import { InferenceRequested, Inferred, type LEvent } from "../LEvent.ts"
|
|
5
4
|
import { MessageRegistryContext } from "../MessageRegistry.ts"
|
|
6
5
|
import { ModelRegistryContext } from "../ModelRegistry.ts"
|
|
@@ -9,24 +8,28 @@ import { RequestCounter } from "./_common.ts"
|
|
|
9
8
|
import { emit } from "./emit.ts"
|
|
10
9
|
import { rune } from "./rune.ts"
|
|
11
10
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
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.get()
|
|
15
17
|
assert(modelRegistry)
|
|
16
18
|
const model = modelRegistry.peek()
|
|
17
19
|
assert(model)
|
|
18
20
|
const requestId = RequestCounter.next()
|
|
19
21
|
yield* emit(new InferenceRequested(requestId, schema))
|
|
20
|
-
const messageRegistry =
|
|
22
|
+
const messageRegistry = MessageRegistryContext.get()
|
|
21
23
|
assert(messageRegistry)
|
|
22
24
|
const inference = yield* rune((fiber) =>
|
|
23
25
|
model
|
|
24
26
|
.seal({
|
|
25
27
|
messages: messageRegistry.messages,
|
|
26
28
|
schema,
|
|
27
|
-
signal: fiber.signal,
|
|
29
|
+
signal: fiber.controller.signal,
|
|
28
30
|
})
|
|
29
31
|
.resolve(), "infer")
|
|
30
32
|
yield* emit(new Inferred(requestId, inference))
|
|
31
33
|
return inference
|
|
32
34
|
}
|
|
35
|
+
Object.defineProperty(infer_, "name", { value: "infer" })
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { assert } from "liminal-util"
|
|
2
|
-
import { Context } from "../Context.ts"
|
|
3
2
|
import { type LEvent, MessageAppended } from "../LEvent.ts"
|
|
4
3
|
import type { ContentPart, Message, MessageRole } from "../Message.ts"
|
|
5
4
|
import { MessageRegistryContext } from "../MessageRegistry.ts"
|
|
6
5
|
import type { Rune } from "../Rune.ts"
|
|
7
6
|
import { emit } from "./emit.ts"
|
|
8
7
|
|
|
9
|
-
export interface
|
|
8
|
+
export interface message extends Generator<Rune<LEvent>, void> {}
|
|
10
9
|
|
|
11
|
-
export function*
|
|
12
|
-
const
|
|
13
|
-
const messageRegistry = context.get(MessageRegistryContext)
|
|
10
|
+
export function* message(role: MessageRole, content: Array<ContentPart>): message {
|
|
11
|
+
const messageRegistry = MessageRegistryContext.get()
|
|
14
12
|
assert(messageRegistry)
|
|
15
13
|
const message: Message = { role, content }
|
|
16
14
|
yield* emit(new MessageAppended(message))
|
package/L/model.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { assert } from "liminal-util"
|
|
2
|
-
import { Context } from "../Context.ts"
|
|
3
2
|
import { ModelRegistered } from "../LEvent.ts"
|
|
4
3
|
import type { Model } from "../Model.ts"
|
|
5
4
|
import { ModelRegistryContext } from "../ModelRegistry.ts"
|
|
@@ -9,8 +8,7 @@ import { emit } from "./emit.ts"
|
|
|
9
8
|
export interface model extends Generator<Rune<ModelRegistered>, void> {}
|
|
10
9
|
|
|
11
10
|
export function* model(model: Model): model {
|
|
12
|
-
const
|
|
13
|
-
const registry = context.get(ModelRegistryContext)
|
|
11
|
+
const registry = ModelRegistryContext.get()
|
|
14
12
|
assert(registry)
|
|
15
13
|
registry.register(model)
|
|
16
14
|
yield* emit(new ModelRegistered(model))
|
package/L/rune.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { Fiber } from "../Fiber.ts"
|
|
2
2
|
import { type Rune, RuneKey } from "../Rune.ts"
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
export function* rune<R>(
|
|
5
|
+
source: (fiber: Fiber) => R,
|
|
6
|
+
debug?: string,
|
|
7
|
+
): Generator<Rune<never>, Awaited<R>> {
|
|
8
|
+
return yield Object.assign(source, {
|
|
9
|
+
[RuneKey]: true,
|
|
10
|
+
debug,
|
|
11
|
+
}) as never
|
|
8
12
|
}
|
|
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)
|
|
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)
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
)
|
package/L/strand.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Context } from "../Context.ts"
|
|
2
|
+
import { Fiber } from "../Fiber.ts"
|
|
3
|
+
import { HandlerContext } from "../Handler.ts"
|
|
4
|
+
import { MessageRegistry, MessageRegistryContext } from "../MessageRegistry.ts"
|
|
5
|
+
import { ModelRegistry, ModelRegistryContext } from "../ModelRegistry.ts"
|
|
6
|
+
import { type Rune } from "../Rune.ts"
|
|
7
|
+
import type { Runic } from "../Runic.ts"
|
|
8
|
+
import { ToolRegistry, ToolRegistryContext } from "../ToolRegistry.ts"
|
|
9
|
+
import { rune } from "./rune.ts"
|
|
10
|
+
|
|
11
|
+
export interface StrandConfig<T = any, E = any> {
|
|
12
|
+
handler?: ((this: Fiber<T>, event: E) => void) | undefined
|
|
13
|
+
models?: ModelRegistry | undefined
|
|
14
|
+
messages?: MessageRegistry | undefined
|
|
15
|
+
tools?: ToolRegistry | undefined
|
|
16
|
+
signal?: AbortSignal | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface strand<Y extends Rune, T> extends Iterable<Y, T>, PromiseLike<T> {}
|
|
20
|
+
|
|
21
|
+
export function strand<X extends Runic>(
|
|
22
|
+
runic: X,
|
|
23
|
+
config?: StrandConfig<Runic.T<X>, Rune.E<Runic.Y<X>>>,
|
|
24
|
+
): strand<Runic.Y<X>, Runic.T<X>>
|
|
25
|
+
export function strand<XA extends Array<Runic>>(
|
|
26
|
+
runics: XA,
|
|
27
|
+
config?: StrandConfig<{ [I in keyof XA]: Runic.T<XA[I]> }, Rune.E<Runic.Y<XA[number]>>>,
|
|
28
|
+
): strand<Runic.Y<XA[number]> | Rune<never>, { [I in keyof XA]: Runic.T<XA[I]> }>
|
|
29
|
+
export function strand<XR extends Record<keyof any, Runic>>(
|
|
30
|
+
runics: XR,
|
|
31
|
+
config?: StrandConfig<{ [K in keyof XR]: Runic.T<XR[K]> }, Rune.E<Runic.Y<XR[keyof XR]>>>,
|
|
32
|
+
): strand<Runic.Y<XR[keyof XR]> | Rune<never>, { [K in keyof XR]: Runic.T<XR[K]> }>
|
|
33
|
+
export function strand(
|
|
34
|
+
value: Runic | Array<Runic> | Record<keyof any, Runic>,
|
|
35
|
+
config?: StrandConfig,
|
|
36
|
+
): strand<Rune, any> {
|
|
37
|
+
return {
|
|
38
|
+
*[Symbol.iterator](): Generator<Rune, any> {
|
|
39
|
+
const parent = yield* Fiber
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
const fibers = value.map((runic) =>
|
|
42
|
+
new Fiber(runic, {
|
|
43
|
+
parent,
|
|
44
|
+
context: makeContext(),
|
|
45
|
+
})
|
|
46
|
+
)
|
|
47
|
+
return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.resolution())), "strand")
|
|
48
|
+
} else if (typeof value === "object") {
|
|
49
|
+
const fibers = Object.values(value).map((runic) =>
|
|
50
|
+
new Fiber(runic, {
|
|
51
|
+
parent,
|
|
52
|
+
context: makeContext(),
|
|
53
|
+
})
|
|
54
|
+
)
|
|
55
|
+
return yield* rune(async () => {
|
|
56
|
+
const keys = Object.keys(value)
|
|
57
|
+
return await Promise
|
|
58
|
+
.all(fibers.map((fiber) => fiber.resolution()))
|
|
59
|
+
.then((resolved) => resolved.map((value, i) => [keys[i], value]))
|
|
60
|
+
.then(Object.fromEntries)
|
|
61
|
+
}, "strand")
|
|
62
|
+
}
|
|
63
|
+
const self = new Fiber(typeof value === "function" ? value() : value, {
|
|
64
|
+
parent,
|
|
65
|
+
context: makeContext(),
|
|
66
|
+
})
|
|
67
|
+
return yield* rune(() => self.resolution(), "strand")
|
|
68
|
+
},
|
|
69
|
+
then(onfulfilled, onrejected) {
|
|
70
|
+
return new Fiber(this, { context: makeContext() }).resolution().then(onfulfilled, onrejected)
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function makeContext() {
|
|
75
|
+
let context = Context.get()?.fork()
|
|
76
|
+
if (!context) {
|
|
77
|
+
context = new Context([
|
|
78
|
+
[ModelRegistryContext, new ModelRegistry()],
|
|
79
|
+
[MessageRegistryContext, new MessageRegistry()],
|
|
80
|
+
[ToolRegistryContext, new ToolRegistry()],
|
|
81
|
+
])
|
|
82
|
+
}
|
|
83
|
+
if (config) {
|
|
84
|
+
if ("handler" in config) {
|
|
85
|
+
context.set(HandlerContext, config.handler)
|
|
86
|
+
}
|
|
87
|
+
if ("models" in config) {
|
|
88
|
+
context.set(ModelRegistryContext, config.models?.clone() ?? new ModelRegistry())
|
|
89
|
+
}
|
|
90
|
+
if ("messages" in config) {
|
|
91
|
+
context.set(MessageRegistryContext, config.messages?.clone() ?? new MessageRegistry())
|
|
92
|
+
}
|
|
93
|
+
if ("tools" in config) {
|
|
94
|
+
context.set(ToolRegistryContext, config.tools?.clone() ?? new ToolRegistry())
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return context
|
|
98
|
+
}
|
|
99
|
+
}
|
package/L/stream.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { assert } from "liminal-util"
|
|
2
|
-
import { Context } from "../Context.ts"
|
|
3
2
|
import { InferenceRequested, type LEvent } from "../LEvent.ts"
|
|
4
3
|
import { MessageRegistryContext } from "../MessageRegistry.ts"
|
|
5
4
|
import { ModelRegistryContext } from "../ModelRegistry.ts"
|
|
@@ -12,20 +11,19 @@ export interface stream extends Iterable<Rune<LEvent>, ReadableStream<string>> {
|
|
|
12
11
|
|
|
13
12
|
export const stream: stream = {
|
|
14
13
|
*[Symbol.iterator](): Generator<Rune<LEvent>, ReadableStream<string>> {
|
|
15
|
-
const
|
|
16
|
-
const modelRegistry = context.get(ModelRegistryContext)
|
|
14
|
+
const modelRegistry = ModelRegistryContext.get()
|
|
17
15
|
assert(modelRegistry)
|
|
18
16
|
const model = modelRegistry.peek()
|
|
19
17
|
assert(model)
|
|
20
18
|
const requestId = RequestCounter.next()
|
|
21
19
|
yield* emit(new InferenceRequested(requestId))
|
|
22
|
-
const messageRegistry =
|
|
20
|
+
const messageRegistry = MessageRegistryContext.get()
|
|
23
21
|
assert(messageRegistry)
|
|
24
22
|
return yield* rune((fiber) =>
|
|
25
23
|
model
|
|
26
24
|
.seal({
|
|
27
25
|
messages: messageRegistry.messages,
|
|
28
|
-
signal: fiber.signal,
|
|
26
|
+
signal: fiber.controller.signal,
|
|
29
27
|
})
|
|
30
28
|
.stream(), "stream")
|
|
31
29
|
},
|
package/L/system.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isTemplateStringsArray } from "liminal-util"
|
|
2
2
|
import type { LEvent } from "../LEvent.ts"
|
|
3
3
|
import type { Rune } from "../Rune.ts"
|
|
4
|
-
import {
|
|
4
|
+
import { message } from "./message.ts"
|
|
5
5
|
|
|
6
6
|
export interface system extends Generator<Rune<LEvent>, void> {}
|
|
7
7
|
|
|
@@ -9,5 +9,5 @@ export function system(template: TemplateStringsArray, ...substitutions: Array<s
|
|
|
9
9
|
export function system(value: string): system
|
|
10
10
|
export function system(e0: TemplateStringsArray | string, ...rest: Array<string>): system {
|
|
11
11
|
const part = isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0
|
|
12
|
-
return
|
|
12
|
+
return message("system", [{ part }])
|
|
13
13
|
}
|
package/L/user.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isTemplateStringsArray } from "liminal-util"
|
|
2
2
|
import type { LEvent } from "../LEvent.ts"
|
|
3
3
|
import type { Rune } from "../Rune.ts"
|
|
4
|
-
import {
|
|
4
|
+
import { message } from "./message.ts"
|
|
5
5
|
|
|
6
6
|
export interface user extends Generator<Rune<LEvent>, void> {}
|
|
7
7
|
|
|
@@ -9,5 +9,5 @@ export function user(template: TemplateStringsArray, ...substitutions: Array<str
|
|
|
9
9
|
export function user(value: string): user
|
|
10
10
|
export function user(e0: TemplateStringsArray | string, ...rest: Array<string>): user {
|
|
11
11
|
const part = isTemplateStringsArray(e0) ? String.raw(e0, ...rest) : e0
|
|
12
|
-
return
|
|
12
|
+
return message("user", [{ part }])
|
|
13
13
|
}
|
package/MessageRegistry.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContextPart } from "./Context.ts"
|
|
2
2
|
import type { Message } from "./Message.ts"
|
|
3
3
|
|
|
4
4
|
export class MessageRegistry {
|
|
@@ -16,6 +16,7 @@ export class MessageRegistry {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export const MessageRegistryContext:
|
|
20
|
-
new MessageRegistry(
|
|
19
|
+
export const MessageRegistryContext: ContextPart<MessageRegistry> = ContextPart(
|
|
20
|
+
(parent) => parent?.clone() ?? new MessageRegistry(),
|
|
21
|
+
"message_registry",
|
|
21
22
|
)
|