liminal 0.12.2 → 0.13.0

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # liminal
2
2
 
3
+ ## 0.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0e4954e: Rename `L.assistantStruct` to `L.assistantSchema`, is it now supports all schemas, not just struct schemas. Template tag calls are properly dedented and normalized. Additionally, `L.userJson` now uses the optional schema to JSONC-encode with description annotations as comments on corresponding fields.
8
+
3
9
  ## 0.12.1
4
10
 
5
11
  ### Patch Changes
package/L.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from "./append.ts"
2
2
  export * from "./assistant.ts"
3
+ export * from "./assistantSchema.ts"
3
4
  export * from "./assistantStream.ts"
4
- export * from "./assistantStruct.ts"
5
5
  export * from "./branch.ts"
6
6
  export * from "./clear.ts"
7
7
  export * from "./enable.ts"
@@ -0,0 +1,60 @@
1
+ import type { AiError } from "@effect/ai/AiError"
2
+ import { AssistantMessage, TextPart } from "@effect/ai/AiInput"
3
+ import { AiLanguageModel } from "@effect/ai/AiLanguageModel"
4
+ import * as Effect from "effect/Effect"
5
+ import * as Option from "effect/Option"
6
+ import * as Schema from "effect/Schema"
7
+ import * as SchemaAST from "effect/SchemaAST"
8
+ import { append } from "./append.ts"
9
+ import { Strand } from "./Strand.ts"
10
+ import { encodeJsonc, type JsonValue } from "./util/JsonValue.ts"
11
+
12
+ /** Infer a structured assistant message and append its JSON representation to the conversation. */
13
+ export const assistantSchema: {
14
+ <F extends Record<string, Schema.Schema.AnyNoContext>>(
15
+ fields: F,
16
+ ): Effect.Effect<{ [K in keyof F]: Schema.Schema.Type<F[K]> }, AiError, AiLanguageModel | Strand>
17
+ <O, I extends JsonValue>(
18
+ schema: Schema.Schema<O, I, never>,
19
+ ): Effect.Effect<O, AiError, AiLanguageModel | Strand>
20
+ } = Effect.fnUntraced(function*(schema) {
21
+ const model = yield* AiLanguageModel
22
+ const { system, messages } = yield* Strand
23
+
24
+ const isSchema = Schema.isSchema(schema)
25
+ const schema_ = isSchema ? schema : Schema.Struct(schema) as Schema.Schema.AnyNoContext
26
+ const isObject = !isSchema || isObjectSchema(SchemaAST.encodedAST(schema.ast))
27
+ const wrapped = isObject ? schema_ : Schema.Struct({ inner: schema_ })
28
+
29
+ const value = yield* model.generateObject({
30
+ system: Option.getOrUndefined(system),
31
+ schema: wrapped,
32
+ prompt: messages,
33
+ }).pipe(
34
+ Effect.map(({ value }) => isObject ? value : value["inner"]),
35
+ )
36
+
37
+ yield* append(
38
+ new AssistantMessage({
39
+ parts: [
40
+ new TextPart({
41
+ text: yield* encodeJsonc(schema_)(value),
42
+ }),
43
+ ],
44
+ }),
45
+ )
46
+ return value
47
+ })
48
+
49
+ const isObjectSchema = (ast: SchemaAST.AST): boolean => {
50
+ switch (ast._tag) {
51
+ case "TypeLiteral": {
52
+ return true
53
+ }
54
+ case "Refinement":
55
+ case "Transformation": {
56
+ return isObjectSchema(ast.from)
57
+ }
58
+ }
59
+ return false
60
+ }
package/dist/L.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from "./append.ts";
2
2
  export * from "./assistant.ts";
3
+ export * from "./assistantSchema.ts";
3
4
  export * from "./assistantStream.ts";
4
- export * from "./assistantStruct.ts";
5
5
  export * from "./branch.ts";
6
6
  export * from "./clear.ts";
7
7
  export * from "./enable.ts";
package/dist/L.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from "./append.js";
2
2
  export * from "./assistant.js";
3
+ export * from "./assistantSchema.js";
3
4
  export * from "./assistantStream.js";
4
- export * from "./assistantStruct.js";
5
5
  export * from "./branch.js";
6
6
  export * from "./clear.js";
7
7
  export * from "./enable.js";
@@ -3,10 +3,11 @@ import { AiLanguageModel } from "@effect/ai/AiLanguageModel";
3
3
  import * as Effect from "effect/Effect";
4
4
  import * as Schema from "effect/Schema";
5
5
  import { Strand } from "./Strand.ts";
6
+ import { type JsonValue } from "./util/JsonValue.ts";
6
7
  /** Infer a structured assistant message and append its JSON representation to the conversation. */
7
- export declare const assistantStruct: {
8
+ export declare const assistantSchema: {
8
9
  <F extends Record<string, Schema.Schema.AnyNoContext>>(fields: F): Effect.Effect<{
9
10
  [K in keyof F]: Schema.Schema.Type<F[K]>;
10
11
  }, AiError, AiLanguageModel | Strand>;
11
- <O, I extends Record<string, unknown>>(schema: Schema.Schema<O, I, never>): Effect.Effect<O, AiError, AiLanguageModel | Strand>;
12
+ <O, I extends JsonValue>(schema: Schema.Schema<O, I, never>): Effect.Effect<O, AiError, AiLanguageModel | Strand>;
12
13
  };
@@ -0,0 +1,44 @@
1
+ import { AssistantMessage, TextPart } from "@effect/ai/AiInput";
2
+ import { AiLanguageModel } from "@effect/ai/AiLanguageModel";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Option from "effect/Option";
5
+ import * as Schema from "effect/Schema";
6
+ import * as SchemaAST from "effect/SchemaAST";
7
+ import { append } from "./append.js";
8
+ import { Strand } from "./Strand.js";
9
+ import { encodeJsonc } from "./util/JsonValue.js";
10
+ /** Infer a structured assistant message and append its JSON representation to the conversation. */
11
+ export const assistantSchema = Effect.fnUntraced(function* (schema) {
12
+ const model = yield* AiLanguageModel;
13
+ const { system, messages } = yield* Strand;
14
+ const isSchema = Schema.isSchema(schema);
15
+ const schema_ = isSchema ? schema : Schema.Struct(schema);
16
+ const isObject = !isSchema || isObjectSchema(SchemaAST.encodedAST(schema.ast));
17
+ const wrapped = isObject ? schema_ : Schema.Struct({ inner: schema_ });
18
+ const value = yield* model.generateObject({
19
+ system: Option.getOrUndefined(system),
20
+ schema: wrapped,
21
+ prompt: messages,
22
+ }).pipe(Effect.map(({ value }) => isObject ? value : value["inner"]));
23
+ yield* append(new AssistantMessage({
24
+ parts: [
25
+ new TextPart({
26
+ text: yield* encodeJsonc(schema_)(value),
27
+ }),
28
+ ],
29
+ }));
30
+ return value;
31
+ });
32
+ const isObjectSchema = (ast) => {
33
+ switch (ast._tag) {
34
+ case "TypeLiteral": {
35
+ return true;
36
+ }
37
+ case "Refinement":
38
+ case "Transformation": {
39
+ return isObjectSchema(ast.from);
40
+ }
41
+ }
42
+ return false;
43
+ };
44
+ //# sourceMappingURL=assistantSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistantSchema.js","sourceRoot":"","sources":["../assistantSchema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,WAAW,EAAkB,MAAM,qBAAqB,CAAA;AAEjE,mGAAmG;AACnG,MAAM,CAAC,MAAM,eAAe,GAOxB,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAC,MAAM;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,eAAe,CAAA;IACpC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAA;IAE1C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAA+B,CAAA;IACvF,MAAM,QAAQ,GAAG,CAAC,QAAQ,IAAI,cAAc,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9E,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IAEtE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;QACxC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;QACrC,MAAM,EAAE,OAAO;QACf,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAC7D,CAAA;IAED,KAAK,CAAC,CAAC,MAAM,CACX,IAAI,gBAAgB,CAAC;QACnB,KAAK,EAAE;YACL,IAAI,QAAQ,CAAC;gBACX,IAAI,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC;aACzC,CAAC;SACH;KACF,CAAC,CACH,CAAA;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAC,CAAA;AAEF,MAAM,cAAc,GAAG,CAAC,GAAkB,EAAW,EAAE;IACrD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,OAAO,IAAI,CAAA;QACb,CAAC;QACD,KAAK,YAAY,CAAC;QAClB,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
package/dist/handle.d.ts CHANGED
@@ -4,4 +4,4 @@ import * as Scope from "effect/Scope";
4
4
  import type { LEvent } from "./LEvent.ts";
5
5
  import { Strand } from "./Strand.ts";
6
6
  /** Attach an event handler to process the events of the current strand. */
7
- export declare const handle: <A, E, R>(f: (event: LEvent) => Effect.Effect<A, E, R>) => Effect.Effect<RuntimeFiber<void, E>, never, Strand | R | Scope.Scope>;
7
+ export declare const listen: <A, E, R>(f: (event: LEvent) => Effect.Effect<A, E, R>) => Effect.Effect<RuntimeFiber<void, E>, never, Strand | R | Scope.Scope>;
package/dist/handle.js CHANGED
@@ -3,7 +3,7 @@ import * as Scope from "effect/Scope";
3
3
  import * as Stream from "effect/Stream";
4
4
  import { Strand } from "./Strand.js";
5
5
  /** Attach an event handler to process the events of the current strand. */
6
- export const handle = Effect.fnUntraced(function* (f) {
6
+ export const listen = Effect.fnUntraced(function* (f) {
7
7
  const latch = yield* Effect.makeLatch(false);
8
8
  const { events } = yield* Strand;
9
9
  const dequeue = yield* events.subscribe;