@llm4ts/flow 2.23.0 → 2.24.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/dist/Timing.d.ts +2 -0
- package/dist/Timing.d.ts.map +1 -1
- package/dist/Timing.js +2 -0
- package/dist/Timing.js.map +1 -1
- package/dist/Transcript.d.ts +57 -0
- package/dist/Transcript.d.ts.map +1 -0
- package/dist/Transcript.js +158 -0
- package/dist/Transcript.js.map +1 -0
- package/package.json +3 -2
- package/src/Timing.ts +4 -0
- package/src/Transcript.ts +240 -0
package/dist/Timing.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import * as Effect from "effect/Effect";
|
|
|
2
2
|
import type { JudgmentShape } from "@llm4ts/core/judgment/Judgment";
|
|
3
3
|
import type { LlmServiceShape } from "@llm4ts/core/LlmService";
|
|
4
4
|
import { Timed, type FlowEventsShape } from "./FlowEvents.ts";
|
|
5
|
+
/** The role the current call is made for: the caller's, or else `label`. */
|
|
6
|
+
export declare const roleOr: (label: string) => Effect.Effect<string>;
|
|
5
7
|
/** Times the seat calls `effect` makes under `role` instead of the seat's own label. */
|
|
6
8
|
export declare const withTimedRole: <A, E, R>(role: string, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, never>>;
|
|
7
9
|
/** Times `effect`, publishing what `timed` makes of its duration whether it succeeds or fails. */
|
package/dist/Timing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timing.d.ts","sourceRoot":"","sources":["../src/Timing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAkB7D,wFAAwF;AACxF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CACnC,CAAA;AAQhD,kGAAkG;AAClG,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAChC,QAAQ,eAAe,EACvB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,KAAK,KACtE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAOrB,CAAA;AAmDH,eAAO,MAAM,SAAS,GACpB,SAAS,eAAe,EACxB,QAAQ,eAAe,EACvB,OAAO,MAAM,KACZ,eAuBF,CAAA;AAED,qGAAqG;AACrG,eAAO,MAAM,aAAa,GAAI,UAAU,aAAa,EAAE,QAAQ,eAAe,KAAG,aAW/E,CAAA"}
|
|
1
|
+
{"version":3,"file":"Timing.d.ts","sourceRoot":"","sources":["../src/Timing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAkB7D,4EAA4E;AAC5E,eAAO,MAAM,MAAM,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACX,CAAA;AAEhD,wFAAwF;AACxF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CACnC,CAAA;AAQhD,kGAAkG;AAClG,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAChC,QAAQ,eAAe,EACvB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,KAAK,KACtE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAOrB,CAAA;AAmDH,eAAO,MAAM,SAAS,GACpB,SAAS,eAAe,EACxB,QAAQ,eAAe,EACvB,OAAO,MAAM,KACZ,eAuBF,CAAA;AAED,qGAAqG;AACrG,eAAO,MAAM,aAAa,GAAI,UAAU,aAAa,EAAE,QAAQ,eAAe,KAAG,aAW/E,CAAA"}
|
package/dist/Timing.js
CHANGED
|
@@ -19,6 +19,8 @@ import { Timed } from "./FlowEvents.js";
|
|
|
19
19
|
const TimedRole = Context.Reference("@llm4ts/flow/Timing/TimedRole", {
|
|
20
20
|
defaultValue: () => undefined
|
|
21
21
|
});
|
|
22
|
+
/** The role the current call is made for: the caller's, or else `label`. */
|
|
23
|
+
export const roleOr = (label) => Effect.map(TimedRole, (role) => role ?? label);
|
|
22
24
|
/** Times the seat calls `effect` makes under `role` instead of the seat's own label. */
|
|
23
25
|
export const withTimedRole = (role, effect) => Effect.provideService(effect, TimedRole, role);
|
|
24
26
|
const reportedMs = (chunk, key) => {
|
package/dist/Timing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timing.js","sourceRoot":"","sources":["../src/Timing.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Timing.js","sourceRoot":"","sources":["../src/Timing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import type { LlmServiceShape } from "@llm4ts/core/LlmService";
|
|
4
|
+
export declare const TranscriptEntry: Schema.Union<readonly [Schema.TaggedStruct<"Call", {
|
|
5
|
+
readonly at: Schema.Number;
|
|
6
|
+
readonly call: Schema.String;
|
|
7
|
+
readonly role: Schema.String;
|
|
8
|
+
readonly executor: Schema.optionalKey<Schema.String>;
|
|
9
|
+
/** The system prompt, on a chat's first call only. */
|
|
10
|
+
readonly system: Schema.optionalKey<Schema.String>;
|
|
11
|
+
/** The input: a chat's newest message, or a one-shot prompt. */
|
|
12
|
+
readonly input: Schema.String;
|
|
13
|
+
/** How many messages came before the input (a chat resends them all). */
|
|
14
|
+
readonly earlier: Schema.optionalKey<Schema.Int>;
|
|
15
|
+
}>, Schema.TaggedStruct<"Reply", {
|
|
16
|
+
readonly at: Schema.Number;
|
|
17
|
+
readonly call: Schema.String;
|
|
18
|
+
readonly text: Schema.String;
|
|
19
|
+
}>, Schema.TaggedStruct<"Tool", {
|
|
20
|
+
readonly at: Schema.Number;
|
|
21
|
+
readonly call: Schema.String;
|
|
22
|
+
readonly tool: Schema.String;
|
|
23
|
+
readonly args: Schema.String;
|
|
24
|
+
}>, Schema.TaggedStruct<"ToolResult", {
|
|
25
|
+
readonly at: Schema.Number;
|
|
26
|
+
readonly call: Schema.String;
|
|
27
|
+
readonly output: Schema.String;
|
|
28
|
+
readonly failed: Schema.optionalKey<Schema.Boolean>;
|
|
29
|
+
}>, Schema.TaggedStruct<"End", {
|
|
30
|
+
readonly at: Schema.Number;
|
|
31
|
+
readonly call: Schema.String;
|
|
32
|
+
readonly ms: Schema.Number;
|
|
33
|
+
readonly failed: Schema.optionalKey<Schema.Boolean>;
|
|
34
|
+
}>]>;
|
|
35
|
+
export type TranscriptEntry = typeof TranscriptEntry.Type;
|
|
36
|
+
/** Where entries go: one stream per story lane, and one for the run. */
|
|
37
|
+
export interface TranscriptSink {
|
|
38
|
+
readonly write: (lane: string | undefined, entry: TranscriptEntry) => Effect.Effect<void>;
|
|
39
|
+
}
|
|
40
|
+
export interface MemoryTranscriptSink {
|
|
41
|
+
readonly sink: TranscriptSink;
|
|
42
|
+
readonly entries: Effect.Effect<ReadonlyArray<{
|
|
43
|
+
readonly lane: string | undefined;
|
|
44
|
+
readonly entry: TranscriptEntry;
|
|
45
|
+
}>>;
|
|
46
|
+
}
|
|
47
|
+
export declare const makeMemoryTranscriptSink: Effect.Effect<MemoryTranscriptSink>;
|
|
48
|
+
export interface TranscriptSeatOptions {
|
|
49
|
+
readonly lane?: string;
|
|
50
|
+
/** The seat's role; a caller's `withTimedRole` names the call instead. */
|
|
51
|
+
readonly role: string;
|
|
52
|
+
/** Who serves the seat, read at each call (a roster hands the coder over). */
|
|
53
|
+
readonly executor?: Effect.Effect<string | undefined>;
|
|
54
|
+
}
|
|
55
|
+
/** A seat whose every call is written to `sink`, as it happens. */
|
|
56
|
+
export declare const transcriptSeat: (service: LlmServiceShape, sink: TranscriptSink, options: TranscriptSeatOptions) => LlmServiceShape;
|
|
57
|
+
//# sourceMappingURL=Transcript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Transcript.d.ts","sourceRoot":"","sources":["../src/Transcript.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAiD9D,eAAO,MAAM,eAAe;;;;;IAhC1B,sDAAsD;;IAEtD,gEAAgE;;IAEhE,yEAAyE;;;;;;;;;;;;;;;;;;;;;IA4BM,CAAA;AACjF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAEzD,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAC1F;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAC7B,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CACtF,CAAA;CACF;AAED,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAQxE,CAAA;AAaD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,mEAAmE;AACnE,eAAO,MAAM,cAAc,GACzB,SAAS,eAAe,EACxB,MAAM,cAAc,EACpB,SAAS,qBAAqB,KAC7B,eAuIF,CAAA"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import * as Clock from "effect/Clock";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Exit from "effect/Exit";
|
|
4
|
+
import * as Ref from "effect/Ref";
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
6
|
+
import * as Stream from "effect/Stream";
|
|
7
|
+
import { redactText } from "@llm4ts/core/observability/Redaction";
|
|
8
|
+
import { roleOr } from "./Timing.js";
|
|
9
|
+
/**
|
|
10
|
+
* What the model was told and what it answered, per seat call — an opt-in
|
|
11
|
+
* record (`llm4ts run --transcript`) that `llm4ts watch` tails. It lives in
|
|
12
|
+
* its own files, never in the trace, so the trace and `llm4ts profile` stay
|
|
13
|
+
* content-free. Secrets are redacted and every field is capped.
|
|
14
|
+
*/
|
|
15
|
+
const Call = Schema.TaggedStruct("Call", {
|
|
16
|
+
at: Schema.Number,
|
|
17
|
+
call: Schema.String,
|
|
18
|
+
role: Schema.String,
|
|
19
|
+
executor: Schema.optionalKey(Schema.String),
|
|
20
|
+
/** The system prompt, on a chat's first call only. */
|
|
21
|
+
system: Schema.optionalKey(Schema.String),
|
|
22
|
+
/** The input: a chat's newest message, or a one-shot prompt. */
|
|
23
|
+
input: Schema.String,
|
|
24
|
+
/** How many messages came before the input (a chat resends them all). */
|
|
25
|
+
earlier: Schema.optionalKey(Schema.Int)
|
|
26
|
+
});
|
|
27
|
+
const Reply = Schema.TaggedStruct("Reply", {
|
|
28
|
+
at: Schema.Number,
|
|
29
|
+
call: Schema.String,
|
|
30
|
+
text: Schema.String
|
|
31
|
+
});
|
|
32
|
+
const Tool = Schema.TaggedStruct("Tool", {
|
|
33
|
+
at: Schema.Number,
|
|
34
|
+
call: Schema.String,
|
|
35
|
+
tool: Schema.String,
|
|
36
|
+
args: Schema.String
|
|
37
|
+
});
|
|
38
|
+
const ToolResult = Schema.TaggedStruct("ToolResult", {
|
|
39
|
+
at: Schema.Number,
|
|
40
|
+
call: Schema.String,
|
|
41
|
+
output: Schema.String,
|
|
42
|
+
failed: Schema.optionalKey(Schema.Boolean)
|
|
43
|
+
});
|
|
44
|
+
const End = Schema.TaggedStruct("End", {
|
|
45
|
+
at: Schema.Number,
|
|
46
|
+
call: Schema.String,
|
|
47
|
+
ms: Schema.Number,
|
|
48
|
+
failed: Schema.optionalKey(Schema.Boolean)
|
|
49
|
+
});
|
|
50
|
+
export const TranscriptEntry = Schema.Union([Call, Reply, Tool, ToolResult, End]);
|
|
51
|
+
export const makeMemoryTranscriptSink = Effect.map(Ref.make([]), (entries) => ({
|
|
52
|
+
sink: { write: (lane, entry) => Ref.update(entries, (all) => [...all, { lane, entry }]) },
|
|
53
|
+
entries: Ref.get(entries)
|
|
54
|
+
}));
|
|
55
|
+
const inputChars = 64_000;
|
|
56
|
+
const partChars = 4_000;
|
|
57
|
+
const clean = (text, limit) => redactText(text, { maxLength: limit });
|
|
58
|
+
let calls = 0;
|
|
59
|
+
const nextCall = Effect.sync(() => {
|
|
60
|
+
calls += 1;
|
|
61
|
+
return `call-${calls}`;
|
|
62
|
+
});
|
|
63
|
+
/** A seat whose every call is written to `sink`, as it happens. */
|
|
64
|
+
export const transcriptSeat = (service, sink, options) => {
|
|
65
|
+
const write = (entry) => sink.write(options.lane, entry);
|
|
66
|
+
const opened = (input, extra) => Effect.gen(function* () {
|
|
67
|
+
const call = yield* nextCall;
|
|
68
|
+
const start = yield* Clock.currentTimeMillis;
|
|
69
|
+
const role = yield* roleOr(options.role);
|
|
70
|
+
const executor = options.executor === undefined ? undefined : yield* options.executor;
|
|
71
|
+
yield* write({
|
|
72
|
+
_tag: "Call",
|
|
73
|
+
at: start,
|
|
74
|
+
call,
|
|
75
|
+
role,
|
|
76
|
+
...(executor === undefined ? {} : { executor }),
|
|
77
|
+
...(extra.system === undefined ? {} : { system: clean(extra.system, inputChars) }),
|
|
78
|
+
input: clean(input, inputChars),
|
|
79
|
+
...(extra.earlier === undefined ? {} : { earlier: extra.earlier })
|
|
80
|
+
});
|
|
81
|
+
return { call, start };
|
|
82
|
+
});
|
|
83
|
+
const closed = (call, start, failed) => Effect.flatMap(Clock.currentTimeMillis, (at) => write({ _tag: "End", at, call, ms: at - start, ...(failed ? { failed } : {}) }));
|
|
84
|
+
const chunkEntry = (call, chunk) => Effect.flatMap(Clock.currentTimeMillis, (at) => {
|
|
85
|
+
switch (chunk.metadata.event) {
|
|
86
|
+
case "tool_use":
|
|
87
|
+
return write({
|
|
88
|
+
_tag: "Tool",
|
|
89
|
+
at,
|
|
90
|
+
call,
|
|
91
|
+
tool: chunk.metadata.tool_name ?? chunk.metadata.toolName ?? "",
|
|
92
|
+
args: clean(chunk.metadata.tool_input ?? chunk.metadata.toolInput ?? "", partChars)
|
|
93
|
+
});
|
|
94
|
+
case "tool_result": {
|
|
95
|
+
const failed = chunk.metadata.tool_failed === "true" || chunk.metadata.tool_status === "error";
|
|
96
|
+
return write({
|
|
97
|
+
_tag: "ToolResult",
|
|
98
|
+
at,
|
|
99
|
+
call,
|
|
100
|
+
output: clean(chunk.metadata.tool_content ?? "", partChars),
|
|
101
|
+
...(failed ? { failed } : {})
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
return chunk.delta.length === 0
|
|
106
|
+
? Effect.void
|
|
107
|
+
: write({
|
|
108
|
+
_tag: "Reply",
|
|
109
|
+
at,
|
|
110
|
+
call,
|
|
111
|
+
text: redactText(chunk.delta, { maxLength: inputChars })
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const recorded = (open, stream) => Stream.unwrap(Effect.map(Effect.all([open, Ref.make(false)]), ([{ call, start }, failed]) => stream.pipe(Stream.tap((chunk) => chunkEntry(call, chunk)), Stream.tapError(() => Ref.set(failed, true)), Stream.ensuring(Effect.flatMap(Ref.get(failed), (did) => closed(call, start, did))))));
|
|
116
|
+
const once = (input, effect) => Effect.flatMap(opened(input, {}), ({ call, start }) => Effect.onExit(effect, (exit) => Effect.andThen(Exit.isSuccess(exit)
|
|
117
|
+
? Effect.flatMap(Clock.currentTimeMillis, (at) => write({
|
|
118
|
+
_tag: "Reply",
|
|
119
|
+
at,
|
|
120
|
+
call,
|
|
121
|
+
text: clean(JSON.stringify(exit.value) ?? "", inputChars)
|
|
122
|
+
}))
|
|
123
|
+
: Effect.void, closed(call, start, Exit.isFailure(exit)))));
|
|
124
|
+
/** A chat's first call is told everything; a later one only what is new. */
|
|
125
|
+
const chatInput = (messages) => {
|
|
126
|
+
const system = messages.filter((message) => message.role === "System");
|
|
127
|
+
const rest = messages.filter((message) => message.role !== "System");
|
|
128
|
+
const first = !rest.some((message) => message.role === "Assistant");
|
|
129
|
+
const newest = rest.at(-1)?.content ?? "";
|
|
130
|
+
return first
|
|
131
|
+
? {
|
|
132
|
+
input: rest.map((message) => message.content).join("\n\n"),
|
|
133
|
+
extra: system.length === 0
|
|
134
|
+
? {}
|
|
135
|
+
: { system: system.map((message) => message.content).join("\n\n") }
|
|
136
|
+
}
|
|
137
|
+
: { input: newest, extra: { earlier: rest.length - 1 } };
|
|
138
|
+
};
|
|
139
|
+
const batched = service.scoreLabelSequence;
|
|
140
|
+
return {
|
|
141
|
+
executeStream: (prompt) => recorded(opened(prompt, {}), service.executeStream(prompt)),
|
|
142
|
+
executeStreamWithHistory: (messages) => {
|
|
143
|
+
const { input, extra } = chatInput(messages);
|
|
144
|
+
return recorded(opened(input, extra), service.executeStreamWithHistory(messages));
|
|
145
|
+
},
|
|
146
|
+
executeWithTools: (prompt, tools) => once(prompt, service.executeWithTools(prompt, tools)),
|
|
147
|
+
executeStructured: (prompt, schema, jsonSchema) => once(prompt, service.executeStructured(prompt, schema, jsonSchema)),
|
|
148
|
+
executeStructuredWithUsage: (prompt, schema, jsonSchema) => once(prompt, service.executeStructuredWithUsage(prompt, schema, jsonSchema)),
|
|
149
|
+
scoreLabels: (prompt, labels) => once(prompt, service.scoreLabels(prompt, labels)),
|
|
150
|
+
...(batched === undefined
|
|
151
|
+
? {}
|
|
152
|
+
: {
|
|
153
|
+
scoreLabelSequence: (prompt, labelSets) => once(prompt, batched(prompt, labelSets))
|
|
154
|
+
}),
|
|
155
|
+
isAvailable: service.isAvailable
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=Transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Transcript.js","sourceRoot":"","sources":["../src/Transcript.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llm4ts/flow",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.24.0",
|
|
4
4
|
"description": "Effect-native LLM workflow, persistence, review, and repository automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"./StoryPlan": "./dist/StoryPlan.js",
|
|
77
77
|
"./Survey": "./dist/Survey.js",
|
|
78
78
|
"./Timing": "./dist/Timing.js",
|
|
79
|
+
"./Transcript": "./dist/Transcript.js",
|
|
79
80
|
"./TransientRetry": "./dist/TransientRetry.js",
|
|
80
81
|
"./Usage": "./dist/Usage.js",
|
|
81
82
|
"./Wall": "./dist/Wall.js",
|
|
@@ -107,7 +108,7 @@
|
|
|
107
108
|
"typescript"
|
|
108
109
|
],
|
|
109
110
|
"dependencies": {
|
|
110
|
-
"@llm4ts/core": "2.
|
|
111
|
+
"@llm4ts/core": "2.24.0"
|
|
111
112
|
},
|
|
112
113
|
"peerDependencies": {
|
|
113
114
|
"effect": "4.0.0"
|
package/src/Timing.ts
CHANGED
|
@@ -25,6 +25,10 @@ const TimedRole = Context.Reference<string | undefined>("@llm4ts/flow/Timing/Tim
|
|
|
25
25
|
defaultValue: () => undefined
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
/** The role the current call is made for: the caller's, or else `label`. */
|
|
29
|
+
export const roleOr = (label: string): Effect.Effect<string> =>
|
|
30
|
+
Effect.map(TimedRole, (role) => role ?? label)
|
|
31
|
+
|
|
28
32
|
/** Times the seat calls `effect` makes under `role` instead of the seat's own label. */
|
|
29
33
|
export const withTimedRole = <A, E, R>(role: string, effect: Effect.Effect<A, E, R>) =>
|
|
30
34
|
Effect.provideService(effect, TimedRole, role)
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import * as Clock from "effect/Clock"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import * as Exit from "effect/Exit"
|
|
4
|
+
import * as Ref from "effect/Ref"
|
|
5
|
+
import * as Schema from "effect/Schema"
|
|
6
|
+
import * as Stream from "effect/Stream"
|
|
7
|
+
import type { LlmServiceShape } from "@llm4ts/core/LlmService"
|
|
8
|
+
import type { LlmChunk, Message } from "@llm4ts/core/Models"
|
|
9
|
+
import { redactText } from "@llm4ts/core/observability/Redaction"
|
|
10
|
+
import { roleOr } from "./Timing.ts"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* What the model was told and what it answered, per seat call — an opt-in
|
|
14
|
+
* record (`llm4ts run --transcript`) that `llm4ts watch` tails. It lives in
|
|
15
|
+
* its own files, never in the trace, so the trace and `llm4ts profile` stay
|
|
16
|
+
* content-free. Secrets are redacted and every field is capped.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const Call = Schema.TaggedStruct("Call", {
|
|
20
|
+
at: Schema.Number,
|
|
21
|
+
call: Schema.String,
|
|
22
|
+
role: Schema.String,
|
|
23
|
+
executor: Schema.optionalKey(Schema.String),
|
|
24
|
+
/** The system prompt, on a chat's first call only. */
|
|
25
|
+
system: Schema.optionalKey(Schema.String),
|
|
26
|
+
/** The input: a chat's newest message, or a one-shot prompt. */
|
|
27
|
+
input: Schema.String,
|
|
28
|
+
/** How many messages came before the input (a chat resends them all). */
|
|
29
|
+
earlier: Schema.optionalKey(Schema.Int)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const Reply = Schema.TaggedStruct("Reply", {
|
|
33
|
+
at: Schema.Number,
|
|
34
|
+
call: Schema.String,
|
|
35
|
+
text: Schema.String
|
|
36
|
+
})
|
|
37
|
+
const Tool = Schema.TaggedStruct("Tool", {
|
|
38
|
+
at: Schema.Number,
|
|
39
|
+
call: Schema.String,
|
|
40
|
+
tool: Schema.String,
|
|
41
|
+
args: Schema.String
|
|
42
|
+
})
|
|
43
|
+
const ToolResult = Schema.TaggedStruct("ToolResult", {
|
|
44
|
+
at: Schema.Number,
|
|
45
|
+
call: Schema.String,
|
|
46
|
+
output: Schema.String,
|
|
47
|
+
failed: Schema.optionalKey(Schema.Boolean)
|
|
48
|
+
})
|
|
49
|
+
const End = Schema.TaggedStruct("End", {
|
|
50
|
+
at: Schema.Number,
|
|
51
|
+
call: Schema.String,
|
|
52
|
+
ms: Schema.Number,
|
|
53
|
+
failed: Schema.optionalKey(Schema.Boolean)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export const TranscriptEntry = Schema.Union([Call, Reply, Tool, ToolResult, End])
|
|
57
|
+
export type TranscriptEntry = typeof TranscriptEntry.Type
|
|
58
|
+
|
|
59
|
+
/** Where entries go: one stream per story lane, and one for the run. */
|
|
60
|
+
export interface TranscriptSink {
|
|
61
|
+
readonly write: (lane: string | undefined, entry: TranscriptEntry) => Effect.Effect<void>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface MemoryTranscriptSink {
|
|
65
|
+
readonly sink: TranscriptSink
|
|
66
|
+
readonly entries: Effect.Effect<
|
|
67
|
+
ReadonlyArray<{ readonly lane: string | undefined; readonly entry: TranscriptEntry }>
|
|
68
|
+
>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const makeMemoryTranscriptSink: Effect.Effect<MemoryTranscriptSink> = Effect.map(
|
|
72
|
+
Ref.make<ReadonlyArray<{ readonly lane: string | undefined; readonly entry: TranscriptEntry }>>(
|
|
73
|
+
[]
|
|
74
|
+
),
|
|
75
|
+
(entries) => ({
|
|
76
|
+
sink: { write: (lane, entry) => Ref.update(entries, (all) => [...all, { lane, entry }]) },
|
|
77
|
+
entries: Ref.get(entries)
|
|
78
|
+
})
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
const inputChars = 64_000
|
|
82
|
+
const partChars = 4_000
|
|
83
|
+
|
|
84
|
+
const clean = (text: string, limit: number): string => redactText(text, { maxLength: limit })
|
|
85
|
+
|
|
86
|
+
let calls = 0
|
|
87
|
+
const nextCall: Effect.Effect<string> = Effect.sync(() => {
|
|
88
|
+
calls += 1
|
|
89
|
+
return `call-${calls}`
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
export interface TranscriptSeatOptions {
|
|
93
|
+
readonly lane?: string
|
|
94
|
+
/** The seat's role; a caller's `withTimedRole` names the call instead. */
|
|
95
|
+
readonly role: string
|
|
96
|
+
/** Who serves the seat, read at each call (a roster hands the coder over). */
|
|
97
|
+
readonly executor?: Effect.Effect<string | undefined>
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** A seat whose every call is written to `sink`, as it happens. */
|
|
101
|
+
export const transcriptSeat = (
|
|
102
|
+
service: LlmServiceShape,
|
|
103
|
+
sink: TranscriptSink,
|
|
104
|
+
options: TranscriptSeatOptions
|
|
105
|
+
): LlmServiceShape => {
|
|
106
|
+
const write = (entry: TranscriptEntry) => sink.write(options.lane, entry)
|
|
107
|
+
|
|
108
|
+
const opened = (
|
|
109
|
+
input: string,
|
|
110
|
+
extra: { readonly system?: string; readonly earlier?: number }
|
|
111
|
+
): Effect.Effect<{ readonly call: string; readonly start: number }> =>
|
|
112
|
+
Effect.gen(function* () {
|
|
113
|
+
const call = yield* nextCall
|
|
114
|
+
const start = yield* Clock.currentTimeMillis
|
|
115
|
+
const role = yield* roleOr(options.role)
|
|
116
|
+
const executor = options.executor === undefined ? undefined : yield* options.executor
|
|
117
|
+
yield* write({
|
|
118
|
+
_tag: "Call",
|
|
119
|
+
at: start,
|
|
120
|
+
call,
|
|
121
|
+
role,
|
|
122
|
+
...(executor === undefined ? {} : { executor }),
|
|
123
|
+
...(extra.system === undefined ? {} : { system: clean(extra.system, inputChars) }),
|
|
124
|
+
input: clean(input, inputChars),
|
|
125
|
+
...(extra.earlier === undefined ? {} : { earlier: extra.earlier })
|
|
126
|
+
})
|
|
127
|
+
return { call, start }
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const closed = (call: string, start: number, failed: boolean): Effect.Effect<void> =>
|
|
131
|
+
Effect.flatMap(Clock.currentTimeMillis, (at) =>
|
|
132
|
+
write({ _tag: "End", at, call, ms: at - start, ...(failed ? { failed } : {}) })
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
const chunkEntry = (call: string, chunk: LlmChunk): Effect.Effect<void> =>
|
|
136
|
+
Effect.flatMap(Clock.currentTimeMillis, (at) => {
|
|
137
|
+
switch (chunk.metadata.event) {
|
|
138
|
+
case "tool_use":
|
|
139
|
+
return write({
|
|
140
|
+
_tag: "Tool",
|
|
141
|
+
at,
|
|
142
|
+
call,
|
|
143
|
+
tool: chunk.metadata.tool_name ?? chunk.metadata.toolName ?? "",
|
|
144
|
+
args: clean(chunk.metadata.tool_input ?? chunk.metadata.toolInput ?? "", partChars)
|
|
145
|
+
})
|
|
146
|
+
case "tool_result": {
|
|
147
|
+
const failed =
|
|
148
|
+
chunk.metadata.tool_failed === "true" || chunk.metadata.tool_status === "error"
|
|
149
|
+
return write({
|
|
150
|
+
_tag: "ToolResult",
|
|
151
|
+
at,
|
|
152
|
+
call,
|
|
153
|
+
output: clean(chunk.metadata.tool_content ?? "", partChars),
|
|
154
|
+
...(failed ? { failed } : {})
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
default:
|
|
158
|
+
return chunk.delta.length === 0
|
|
159
|
+
? Effect.void
|
|
160
|
+
: write({
|
|
161
|
+
_tag: "Reply",
|
|
162
|
+
at,
|
|
163
|
+
call,
|
|
164
|
+
text: redactText(chunk.delta, { maxLength: inputChars })
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
const recorded = <E>(
|
|
170
|
+
open: Effect.Effect<{ readonly call: string; readonly start: number }>,
|
|
171
|
+
stream: Stream.Stream<LlmChunk, E>
|
|
172
|
+
): Stream.Stream<LlmChunk, E> =>
|
|
173
|
+
Stream.unwrap(
|
|
174
|
+
Effect.map(Effect.all([open, Ref.make(false)]), ([{ call, start }, failed]) =>
|
|
175
|
+
stream.pipe(
|
|
176
|
+
Stream.tap((chunk) => chunkEntry(call, chunk)),
|
|
177
|
+
Stream.tapError(() => Ref.set(failed, true)),
|
|
178
|
+
Stream.ensuring(Effect.flatMap(Ref.get(failed), (did) => closed(call, start, did)))
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
const once = <A, E, R>(input: string, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
184
|
+
Effect.flatMap(opened(input, {}), ({ call, start }) =>
|
|
185
|
+
Effect.onExit(effect, (exit) =>
|
|
186
|
+
Effect.andThen(
|
|
187
|
+
Exit.isSuccess(exit)
|
|
188
|
+
? Effect.flatMap(Clock.currentTimeMillis, (at) =>
|
|
189
|
+
write({
|
|
190
|
+
_tag: "Reply",
|
|
191
|
+
at,
|
|
192
|
+
call,
|
|
193
|
+
text: clean(JSON.stringify(exit.value) ?? "", inputChars)
|
|
194
|
+
})
|
|
195
|
+
)
|
|
196
|
+
: Effect.void,
|
|
197
|
+
closed(call, start, Exit.isFailure(exit))
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
/** A chat's first call is told everything; a later one only what is new. */
|
|
203
|
+
const chatInput = (messages: ReadonlyArray<Message>) => {
|
|
204
|
+
const system = messages.filter((message) => message.role === "System")
|
|
205
|
+
const rest = messages.filter((message) => message.role !== "System")
|
|
206
|
+
const first = !rest.some((message) => message.role === "Assistant")
|
|
207
|
+
const newest = rest.at(-1)?.content ?? ""
|
|
208
|
+
return first
|
|
209
|
+
? {
|
|
210
|
+
input: rest.map((message) => message.content).join("\n\n"),
|
|
211
|
+
extra:
|
|
212
|
+
system.length === 0
|
|
213
|
+
? {}
|
|
214
|
+
: { system: system.map((message) => message.content).join("\n\n") }
|
|
215
|
+
}
|
|
216
|
+
: { input: newest, extra: { earlier: rest.length - 1 } }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const batched = service.scoreLabelSequence
|
|
220
|
+
return {
|
|
221
|
+
executeStream: (prompt) => recorded(opened(prompt, {}), service.executeStream(prompt)),
|
|
222
|
+
executeStreamWithHistory: (messages) => {
|
|
223
|
+
const { input, extra } = chatInput(messages)
|
|
224
|
+
return recorded(opened(input, extra), service.executeStreamWithHistory(messages))
|
|
225
|
+
},
|
|
226
|
+
executeWithTools: (prompt, tools) => once(prompt, service.executeWithTools(prompt, tools)),
|
|
227
|
+
executeStructured: (prompt, schema, jsonSchema) =>
|
|
228
|
+
once(prompt, service.executeStructured(prompt, schema, jsonSchema)),
|
|
229
|
+
executeStructuredWithUsage: (prompt, schema, jsonSchema) =>
|
|
230
|
+
once(prompt, service.executeStructuredWithUsage(prompt, schema, jsonSchema)),
|
|
231
|
+
scoreLabels: (prompt, labels) => once(prompt, service.scoreLabels(prompt, labels)),
|
|
232
|
+
...(batched === undefined
|
|
233
|
+
? {}
|
|
234
|
+
: {
|
|
235
|
+
scoreLabelSequence: (prompt: string, labelSets: ReadonlyArray<ReadonlyArray<string>>) =>
|
|
236
|
+
once(prompt, batched(prompt, labelSets))
|
|
237
|
+
}),
|
|
238
|
+
isAvailable: service.isAvailable
|
|
239
|
+
}
|
|
240
|
+
}
|