liminal 0.5.10 → 0.5.12
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 +17 -0
- package/Context.ts +36 -21
- package/Fiber.ts +56 -52
- package/Handler.ts +2 -2
- package/L/L.ts +4 -3
- package/L/assistant.ts +6 -6
- package/L/catch.ts +10 -2
- package/L/emit.ts +3 -7
- package/L/{_infer.ts → infer.ts} +9 -8
- package/L/{_message.ts → message.ts} +3 -7
- package/L/model.ts +1 -5
- package/L/rune.ts +8 -26
- package/L/strand.ts +75 -0
- package/L/stream.ts +3 -5
- package/L/system.ts +4 -4
- package/L/user.ts +4 -4
- package/MessageRegistry.ts +4 -3
- package/ModelRegistry.ts +13 -8
- package/StrandConfig.ts +12 -0
- package/ToolRegistry.ts +8 -3
- package/dist/Context.d.ts +11 -9
- package/dist/Context.js +30 -17
- package/dist/Context.js.map +1 -1
- package/dist/Fiber.d.ts +18 -15
- package/dist/Fiber.js +32 -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 +9 -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 -9
- package/dist/L/infer.js.map +1 -0
- package/dist/L/message.d.ts +6 -0
- package/dist/L/message.js +10 -0
- package/dist/L/message.js.map +1 -0
- package/dist/L/model.js +1 -5
- 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 +16 -0
- package/dist/L/strand.js +57 -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.d.ts +1 -1
- package/dist/L/system.js +2 -2
- package/dist/L/system.js.map +1 -1
- package/dist/L/user.d.ts +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/StrandConfig.d.ts +11 -0
- package/dist/StrandConfig.js +2 -0
- package/dist/StrandConfig.js.map +1 -0
- 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 +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +1 -1
- package/package.json +4 -7
- 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 +0 -14
- 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,22 @@
|
|
|
1
1
|
# liminal
|
|
2
2
|
|
|
3
|
+
## 0.5.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4808a57: Fix handling of standalone iterables supplied to L.strand. Also introduce strandard, a standard library of strands.
|
|
8
|
+
- Updated dependencies [4808a57]
|
|
9
|
+
- liminal-util@0.0.7
|
|
10
|
+
|
|
11
|
+
## 0.5.11
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- cf42ed2: Agent -> Strand. Making the API more uniform. Ie. Agent -> L.strand. L.branch -> L.strand.
|
|
16
|
+
- Updated dependencies [cf42ed2]
|
|
17
|
+
- liminal-schema@0.0.5
|
|
18
|
+
- liminal-util@0.0.6
|
|
19
|
+
|
|
3
20
|
## 0.5.10
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/Context.ts
CHANGED
|
@@ -3,41 +3,56 @@ import { AsyncLocalStorage } from "node:async_hooks"
|
|
|
3
3
|
|
|
4
4
|
const storage = new AsyncLocalStorage<Context>()
|
|
5
5
|
|
|
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
|
|
6
|
+
export class Context extends Map<ContextPart, unknown> {
|
|
7
|
+
static get(): Context | undefined {
|
|
8
|
+
return storage.getStore()
|
|
15
9
|
}
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
static ensure(): Context {
|
|
12
|
+
const current = Context.get()
|
|
13
|
+
assert(current)
|
|
14
|
+
return current
|
|
20
15
|
}
|
|
21
16
|
|
|
22
|
-
run<R>(
|
|
23
|
-
return storage.run(this,
|
|
17
|
+
run<R>(f: () => R): R {
|
|
18
|
+
return storage.run(this, f)
|
|
24
19
|
}
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
const context = new Context(
|
|
21
|
+
fork(): Context {
|
|
22
|
+
const context = new Context()
|
|
28
23
|
for (const [handle, value] of this.entries()) {
|
|
29
24
|
if (!context.has(handle)) {
|
|
30
|
-
context.set(handle, handle.
|
|
25
|
+
context.set(handle, handle.fork(value))
|
|
31
26
|
}
|
|
32
27
|
}
|
|
33
28
|
return context
|
|
34
29
|
}
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
export
|
|
38
|
-
|
|
32
|
+
export interface ContextPart<V = any> {
|
|
33
|
+
fork(parent?: V): V
|
|
34
|
+
get(): V | undefined
|
|
35
|
+
getOrInit(): V
|
|
36
|
+
debug?: string
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
export function
|
|
42
|
-
|
|
39
|
+
export function ContextPart<V>(fork: (parent?: V) => V, debug?: string): ContextPart<V> {
|
|
40
|
+
const self: ContextPart<V> = {
|
|
41
|
+
fork,
|
|
42
|
+
get() {
|
|
43
|
+
return Context.get()?.get(self) as never
|
|
44
|
+
},
|
|
45
|
+
getOrInit() {
|
|
46
|
+
const context = Context.get()
|
|
47
|
+
assert(context)
|
|
48
|
+
let value = context.get(this)
|
|
49
|
+
if (!value) {
|
|
50
|
+
value = this.fork()
|
|
51
|
+
context.set(this, value)
|
|
52
|
+
}
|
|
53
|
+
return value as never
|
|
54
|
+
},
|
|
55
|
+
...debug && { debug },
|
|
56
|
+
}
|
|
57
|
+
return self
|
|
43
58
|
}
|
package/Fiber.ts
CHANGED
|
@@ -2,72 +2,59 @@ import { attachCustomInspect } from "liminal-util"
|
|
|
2
2
|
import { Context } from "./Context.ts"
|
|
3
3
|
import { type Handler, HandlerContext } from "./Handler.ts"
|
|
4
4
|
import { FiberCreated, FiberRejected, FiberResolved, FiberStarted } from "./LEvent.ts"
|
|
5
|
-
import type
|
|
5
|
+
import { type Rune, RuneKey } from "./Rune.ts"
|
|
6
6
|
import { Runic } from "./Runic.ts"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
self: AbortSignal
|
|
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
|
|
7
|
+
|
|
8
|
+
export interface FiberConfig {
|
|
9
|
+
parent?: Fiber
|
|
10
|
+
signal?: AbortSignal
|
|
22
11
|
}
|
|
23
12
|
|
|
24
13
|
export class Fiber<T = any> {
|
|
25
|
-
static
|
|
14
|
+
static *[Symbol.iterator](): Generator<Rune<never>, Fiber> {
|
|
15
|
+
return yield Object.assign((fiber: Fiber) => fiber, {
|
|
16
|
+
[RuneKey]: true,
|
|
17
|
+
debug: "current_fiber",
|
|
18
|
+
} as never)
|
|
19
|
+
}
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
static nextIndex: number = 0
|
|
28
22
|
readonly index: number = Fiber.nextIndex++
|
|
23
|
+
readonly depth: number
|
|
29
24
|
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
#
|
|
25
|
+
readonly #context: Context = Context.get() ?? new Context()
|
|
26
|
+
readonly #runic: Runic<Rune, T>
|
|
27
|
+
readonly #handler: Handler | undefined = HandlerContext.get()
|
|
28
|
+
readonly #configSignal?: AbortSignal
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
either: AbortSignal
|
|
37
|
-
abort: (reason?: any) => void
|
|
30
|
+
declare readonly parent?: Fiber
|
|
38
31
|
|
|
39
32
|
status: FiberStatus<T> = { type: "untouched" }
|
|
33
|
+
controller: AbortController = new AbortController()
|
|
40
34
|
|
|
41
|
-
constructor(runic: Runic<Rune, T>,
|
|
35
|
+
constructor(runic: Runic<Rune, T>, config?: FiberConfig) {
|
|
36
|
+
this.depth = (config?.parent?.depth ?? -2) + 1
|
|
42
37
|
this.#runic = runic
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.signal = controller.signal
|
|
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())
|
|
38
|
+
const { parent, signal } = config ?? {}
|
|
39
|
+
if (parent) this.parent = parent
|
|
40
|
+
if (signal) this.#configSignal = signal
|
|
41
|
+
this.handle(new FiberCreated())
|
|
54
42
|
}
|
|
55
43
|
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
handle(event: any) {
|
|
45
|
+
this.#handler?.call(this, event)
|
|
58
46
|
}
|
|
59
47
|
|
|
60
|
-
resolution(
|
|
61
|
-
|
|
62
|
-
switch (status.type) {
|
|
48
|
+
resolution(): Promise<T> {
|
|
49
|
+
switch (this.status.type) {
|
|
63
50
|
case "untouched": {
|
|
64
51
|
const { promise, resolve, reject } = Promise.withResolvers<T>()
|
|
65
52
|
this.status = {
|
|
66
53
|
type: "pending",
|
|
67
|
-
self: this.signal,
|
|
54
|
+
self: this.controller.signal,
|
|
68
55
|
promise,
|
|
69
56
|
}
|
|
70
|
-
this
|
|
57
|
+
this.handle(new FiberStarted())
|
|
71
58
|
const iterator = Runic.unwrap(this.#runic)
|
|
72
59
|
let nextArg: unknown
|
|
73
60
|
this.#context.run(async () => {
|
|
@@ -83,32 +70,32 @@ export class Fiber<T = any> {
|
|
|
83
70
|
type: "resolved",
|
|
84
71
|
value,
|
|
85
72
|
}
|
|
86
|
-
this
|
|
87
|
-
abort()
|
|
73
|
+
this.handle(new FiberResolved(value))
|
|
74
|
+
this.controller.abort()
|
|
88
75
|
resolve(value)
|
|
89
76
|
} catch (exception) {
|
|
90
77
|
this.status = {
|
|
91
78
|
type: "rejected",
|
|
92
79
|
exception,
|
|
93
80
|
}
|
|
94
|
-
this
|
|
95
|
-
abort(
|
|
81
|
+
this.handle(new FiberRejected(exception))
|
|
82
|
+
this.controller.abort()
|
|
96
83
|
reject(exception)
|
|
97
84
|
}
|
|
98
85
|
})
|
|
99
86
|
return promise
|
|
100
87
|
}
|
|
101
88
|
case "pending": {
|
|
102
|
-
return status.promise
|
|
89
|
+
return this.status.promise
|
|
103
90
|
}
|
|
104
91
|
case "resolved": {
|
|
105
|
-
return Promise.resolve(status.value)
|
|
92
|
+
return Promise.resolve(this.status.value)
|
|
106
93
|
}
|
|
107
94
|
case "rejected": {
|
|
108
|
-
return Promise.reject(status.exception)
|
|
95
|
+
return Promise.reject(this.status.exception)
|
|
109
96
|
}
|
|
110
97
|
case "aborted": {
|
|
111
|
-
return Promise.reject(status.reason)
|
|
98
|
+
return Promise.reject(this.status.reason)
|
|
112
99
|
}
|
|
113
100
|
}
|
|
114
101
|
}
|
|
@@ -117,3 +104,20 @@ export class Fiber<T = any> {
|
|
|
117
104
|
attachCustomInspect(this, ({ index, parent }) => ({ index, ...parent && { parent } }))
|
|
118
105
|
}
|
|
119
106
|
}
|
|
107
|
+
|
|
108
|
+
export type FiberStatus<T> = {
|
|
109
|
+
type: "untouched"
|
|
110
|
+
} | {
|
|
111
|
+
type: "pending"
|
|
112
|
+
self: AbortSignal
|
|
113
|
+
promise: Promise<T>
|
|
114
|
+
} | {
|
|
115
|
+
type: "aborted"
|
|
116
|
+
reason: unknown
|
|
117
|
+
} | {
|
|
118
|
+
type: "resolved"
|
|
119
|
+
value: T
|
|
120
|
+
} | {
|
|
121
|
+
type: "rejected"
|
|
122
|
+
exception: unknown
|
|
123
|
+
}
|
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,20 @@
|
|
|
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(() => new Fiber(runic, { parent }).resolution()),
|
|
17
|
+
}
|
|
10
18
|
} catch (exception: unknown) {
|
|
11
19
|
return { rejected: exception }
|
|
12
20
|
}
|
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,26 @@ 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
|
-
|
|
15
|
-
|
|
11
|
+
export { infer_ as infer }
|
|
12
|
+
|
|
13
|
+
interface infer_ extends Generator<Rune<LEvent>, string> {}
|
|
14
|
+
|
|
15
|
+
function* infer_(schema?: SchemaObject): infer_ {
|
|
16
|
+
const modelRegistry = ModelRegistryContext.getOrInit()
|
|
16
17
|
const model = modelRegistry.peek()
|
|
17
18
|
assert(model)
|
|
18
19
|
const requestId = RequestCounter.next()
|
|
19
20
|
yield* emit(new InferenceRequested(requestId, schema))
|
|
20
|
-
const messageRegistry =
|
|
21
|
-
assert(messageRegistry)
|
|
21
|
+
const messageRegistry = MessageRegistryContext.getOrInit()
|
|
22
22
|
const inference = yield* rune((fiber) =>
|
|
23
23
|
model
|
|
24
24
|
.seal({
|
|
25
25
|
messages: messageRegistry.messages,
|
|
26
26
|
schema,
|
|
27
|
-
signal: fiber.signal,
|
|
27
|
+
signal: fiber.controller.signal,
|
|
28
28
|
})
|
|
29
29
|
.resolve(), "infer")
|
|
30
30
|
yield* emit(new Inferred(requestId, inference))
|
|
31
31
|
return inference
|
|
32
32
|
}
|
|
33
|
+
Object.defineProperty(infer_, "name", { value: "infer" })
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { assert } from "liminal-util"
|
|
2
|
-
import { Context } from "../Context.ts"
|
|
3
1
|
import { type LEvent, MessageAppended } from "../LEvent.ts"
|
|
4
2
|
import type { ContentPart, Message, MessageRole } from "../Message.ts"
|
|
5
3
|
import { MessageRegistryContext } from "../MessageRegistry.ts"
|
|
6
4
|
import type { Rune } from "../Rune.ts"
|
|
7
5
|
import { emit } from "./emit.ts"
|
|
8
6
|
|
|
9
|
-
export interface
|
|
7
|
+
export interface message extends Generator<Rune<LEvent>, void> {}
|
|
10
8
|
|
|
11
|
-
export function*
|
|
12
|
-
const
|
|
13
|
-
const messageRegistry = context.get(MessageRegistryContext)
|
|
14
|
-
assert(messageRegistry)
|
|
9
|
+
export function* message(role: MessageRole, content: Array<ContentPart>): message {
|
|
10
|
+
const messageRegistry = MessageRegistryContext.getOrInit()
|
|
15
11
|
const message: Message = { role, content }
|
|
16
12
|
yield* emit(new MessageAppended(message))
|
|
17
13
|
messageRegistry.append(message)
|
package/L/model.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { assert } from "liminal-util"
|
|
2
|
-
import { Context } from "../Context.ts"
|
|
3
1
|
import { ModelRegistered } from "../LEvent.ts"
|
|
4
2
|
import type { Model } from "../Model.ts"
|
|
5
3
|
import { ModelRegistryContext } from "../ModelRegistry.ts"
|
|
@@ -9,9 +7,7 @@ import { emit } from "./emit.ts"
|
|
|
9
7
|
export interface model extends Generator<Rune<ModelRegistered>, void> {}
|
|
10
8
|
|
|
11
9
|
export function* model(model: Model): model {
|
|
12
|
-
const
|
|
13
|
-
const registry = context.get(ModelRegistryContext)
|
|
14
|
-
assert(registry)
|
|
10
|
+
const registry = ModelRegistryContext.getOrInit()
|
|
15
11
|
registry.register(model)
|
|
16
12
|
yield* emit(new ModelRegistered(model))
|
|
17
13
|
}
|
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,75 @@
|
|
|
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"
|
|
12
|
+
|
|
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)
|
|
52
|
+
},
|
|
53
|
+
}
|
|
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
|
+
}
|
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,13 +1,13 @@
|
|
|
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
|
|
|
8
|
-
export function system(template: TemplateStringsArray, ...substitutions: Array<string>): system
|
|
8
|
+
export function system(template: TemplateStringsArray, ...substitutions: Array<number | string>): system
|
|
9
9
|
export function system(value: string): system
|
|
10
|
-
export function system(e0: TemplateStringsArray | string, ...rest: Array<string>): system {
|
|
10
|
+
export function system(e0: TemplateStringsArray | string, ...rest: Array<number | 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,13 +1,13 @@
|
|
|
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
|
|
|
8
|
-
export function user(template: TemplateStringsArray, ...substitutions: Array<string>): user
|
|
8
|
+
export function user(template: TemplateStringsArray, ...substitutions: Array<number | string>): user
|
|
9
9
|
export function user(value: string): user
|
|
10
|
-
export function user(e0: TemplateStringsArray | string, ...rest: Array<string>): user {
|
|
10
|
+
export function user(e0: TemplateStringsArray | string, ...rest: Array<number | 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
|
)
|