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.
- package/Agent.ts +8 -5
- package/CHANGELOG.md +17 -0
- package/Context.ts +1 -10
- package/Fiber.ts +92 -25
- package/L/L.ts +1 -0
- package/L/_infer.ts +6 -8
- package/L/assistant.ts +2 -2
- package/L/branch.ts +13 -9
- package/L/catch.ts +23 -0
- package/L/emit.ts +1 -1
- package/L/rune.ts +24 -13
- package/LEvent.ts +1 -1
- package/Model.ts +10 -9
- package/ModelRegistry.ts +0 -8
- package/Rune.ts +4 -2
- package/Tool.ts +31 -0
- package/ToolRegistry.ts +5 -0
- package/dist/Agent.d.ts +5 -3
- package/dist/Agent.js +5 -3
- package/dist/Agent.js.map +1 -1
- package/dist/Context.d.ts +1 -2
- package/dist/Context.js +0 -8
- package/dist/Context.js.map +1 -1
- package/dist/Fiber.d.ts +25 -5
- package/dist/Fiber.js +69 -27
- package/dist/Fiber.js.map +1 -1
- package/dist/L/L.d.ts +1 -0
- package/dist/L/L.js +1 -0
- package/dist/L/L.js.map +1 -1
- package/dist/L/_infer.js +6 -7
- package/dist/L/_infer.js.map +1 -1
- package/dist/L/assistant.d.ts +1 -1
- package/dist/L/assistant.js +1 -1
- package/dist/L/assistant.js.map +1 -1
- package/dist/L/branch.js +13 -9
- package/dist/L/branch.js.map +1 -1
- package/dist/L/catch.d.ts +11 -0
- package/dist/L/catch.js +14 -0
- package/dist/L/catch.js.map +1 -0
- package/dist/L/emit.js +1 -1
- package/dist/L/emit.js.map +1 -1
- package/dist/L/rune.d.ts +5 -3
- package/dist/L/rune.js +11 -4
- package/dist/L/rune.js.map +1 -1
- package/dist/LEvent.js +1 -1
- package/dist/LEvent.js.map +1 -1
- package/dist/Model.d.ts +4 -2
- package/dist/Model.js +12 -7
- package/dist/Model.js.map +1 -1
- package/dist/ModelRegistry.d.ts +0 -1
- package/dist/ModelRegistry.js +0 -7
- package/dist/ModelRegistry.js.map +1 -1
- package/dist/Rune.d.ts +4 -2
- package/dist/Rune.js.map +1 -1
- package/dist/Tool.d.ts +9 -0
- package/dist/Tool.js +31 -0
- package/dist/Tool.js.map +1 -0
- package/dist/ToolRegistry.d.ts +5 -0
- package/dist/ToolRegistry.js +5 -0
- package/dist/ToolRegistry.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +2 -0
- package/package.json +3 -3
- package/cli/main.ts +0 -1
- package/dist/cli/main.d.ts +0 -1
- package/dist/cli/main.js +0 -3
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
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
|
|
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 =
|
|
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
|
|
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>(
|
|
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
|
|
17
|
+
const parent = yield* rune
|
|
19
18
|
if (Array.isArray(value)) {
|
|
20
|
-
const fibers = value.map((runic) => context.clone().run(() =>
|
|
21
|
-
return yield* rune(() => Promise.all(fibers.map((fiber) => fiber.
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
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(() =>
|
|
28
|
-
return yield* rune(() => fiber.
|
|
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
|
|
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
|
|
5
|
-
<
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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 &&
|
|
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
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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]:
|
|
6
|
+
[RuneKey]: true
|
|
7
|
+
debug?: string
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export declare namespace Rune {
|
|
9
|
-
export type E<X extends Rune> = X[
|
|
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
|
+
}
|
package/ToolRegistry.ts
ADDED
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
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
|
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;
|
package/dist/Context.js.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
20
|
+
#private;
|
|
21
|
+
static nextIndex: number;
|
|
22
|
+
T: T;
|
|
6
23
|
readonly index: number;
|
|
7
24
|
readonly parent?: Fiber;
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
30
|
+
fork<T>(runic: Runic<Rune, T>): Fiber<T>;
|
|
31
|
+
resolution(this: Fiber<T>): Promise<T>;
|
|
12
32
|
}
|