@llm4ts/flow 2.7.0 → 2.7.2
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/CostTracker.d.ts +4 -2
- package/dist/CostTracker.d.ts.map +1 -1
- package/dist/CostTracker.js +2 -5
- package/dist/CostTracker.js.map +1 -1
- package/dist/FlowEvents.d.ts +16 -0
- package/dist/FlowEvents.d.ts.map +1 -1
- package/dist/FlowEvents.js +25 -1
- package/dist/FlowEvents.js.map +1 -1
- package/dist/FlowRecorder.d.ts +4 -2
- package/dist/FlowRecorder.d.ts.map +1 -1
- package/dist/FlowRecorder.js +2 -5
- package/dist/FlowRecorder.js.map +1 -1
- package/dist/JudgmentLog.d.ts +3 -1
- package/dist/JudgmentLog.d.ts.map +1 -1
- package/dist/JudgmentLog.js +2 -6
- package/dist/JudgmentLog.js.map +1 -1
- package/package.json +2 -2
- package/src/CostTracker.ts +5 -14
- package/src/FlowEvents.ts +42 -2
- package/src/FlowRecorder.ts +5 -14
- package/src/JudgmentLog.ts +6 -14
package/dist/CostTracker.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import type * as Duration from "effect/Duration";
|
|
1
2
|
import * as Effect from "effect/Effect";
|
|
2
3
|
import type * as Scope from "effect/Scope";
|
|
3
4
|
import { CostCell } from "./CostLedger.ts";
|
|
4
|
-
import type
|
|
5
|
+
import { type FlowEvent, type FlowEventHub } from "./FlowEvents.ts";
|
|
5
6
|
export interface CostTracker {
|
|
6
7
|
readonly record: (event: FlowEvent) => Effect.Effect<void>;
|
|
7
8
|
readonly cells: Effect.Effect<ReadonlyArray<CostCell>>;
|
|
8
9
|
readonly summary: Effect.Effect<string>;
|
|
9
10
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>;
|
|
10
|
-
|
|
11
|
+
/** Waits for this tracker to catch up; `false` means it gave up first. */
|
|
12
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>;
|
|
11
13
|
}
|
|
12
14
|
export declare const makeCostTracker: () => Effect.Effect<CostTracker, never, never>;
|
|
13
15
|
//# sourceMappingURL=CostTracker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CostTracker.d.ts","sourceRoot":"","sources":["../src/CostTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"CostTracker.d.ts","sourceRoot":"","sources":["../src/CostTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAWlF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAA;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAChF,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CAC/F;AAwGD,eAAO,MAAM,eAAe,gDAqD3B,CAAA"}
|
package/dist/CostTracker.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as Ref from "effect/Ref";
|
|
|
3
3
|
import * as Stream from "effect/Stream";
|
|
4
4
|
import { TokenUsage } from "@llm4ts/core/Models";
|
|
5
5
|
import { CostCell } from "./CostLedger.js";
|
|
6
|
+
import { awaitConsumed } from "./FlowEvents.js";
|
|
6
7
|
import { estimateCostUsd, PricesAsOf } from "./PriceList.js";
|
|
7
8
|
const emptyState = {
|
|
8
9
|
byAgent: new Map(),
|
|
@@ -124,11 +125,7 @@ export const makeCostTracker = Effect.fn("@llm4ts/flow/CostTracker.make")(functi
|
|
|
124
125
|
const subscription = yield* hub.subscribe;
|
|
125
126
|
yield* Stream.fromSubscription(subscription).pipe(Stream.runForEach((event) => record(event).pipe(Effect.andThen(Ref.update(consumed, (count) => count + 1)))), Effect.forkScoped, Effect.asVoid);
|
|
126
127
|
}),
|
|
127
|
-
awaitDrained: (hub) =>
|
|
128
|
-
const target = yield* hub.publishedCount;
|
|
129
|
-
const drain = Effect.suspend(() => Ref.get(consumed).pipe(Effect.flatMap((count) => count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain)))));
|
|
130
|
-
yield* drain;
|
|
131
|
-
})
|
|
128
|
+
awaitDrained: (hub, timeout) => awaitConsumed(hub, consumed, timeout)
|
|
132
129
|
};
|
|
133
130
|
});
|
|
134
131
|
//# sourceMappingURL=CostTracker.js.map
|
package/dist/CostTracker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CostTracker.js","sourceRoot":"","sources":["../src/CostTracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CostTracker.js","sourceRoot":"","sources":["../src/CostTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/FlowEvents.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as Context from "effect/Context";
|
|
2
|
+
import type * as Duration from "effect/Duration";
|
|
2
3
|
import * as Effect from "effect/Effect";
|
|
3
4
|
import * as Layer from "effect/Layer";
|
|
4
5
|
import * as PubSub from "effect/PubSub";
|
|
6
|
+
import * as Ref from "effect/Ref";
|
|
5
7
|
import * as Schema from "effect/Schema";
|
|
6
8
|
import type * as Scope from "effect/Scope";
|
|
7
9
|
import * as Stream from "effect/Stream";
|
|
@@ -140,5 +142,19 @@ export interface FlowEventHub extends FlowEventsShape {
|
|
|
140
142
|
readonly publishedCount: Effect.Effect<number>;
|
|
141
143
|
}
|
|
142
144
|
export declare const makeFlowEventHub: (capacity?: any) => Effect.Effect<FlowEventHub, never, never>;
|
|
145
|
+
/** How long a consumer waits to catch up before the run moves on regardless. */
|
|
146
|
+
export declare const defaultDrainTimeout = "3 seconds";
|
|
147
|
+
/**
|
|
148
|
+
* The shared drain: wait until `consumed` has caught up with everything the
|
|
149
|
+
* hub published, and report whether it did.
|
|
150
|
+
*
|
|
151
|
+
* Bounded on purpose, and the single copy of this loop. A consumer can fall
|
|
152
|
+
* permanently short of the count — a subscription torn down early, an
|
|
153
|
+
* event the PubSub refused — and an unbounded wait then pegs a core forever.
|
|
154
|
+
* In the runner that swallowed the end of a run: every stage printed and
|
|
155
|
+
* ticked green, and no cost summary ever following, because the summary is
|
|
156
|
+
* written only once every consumer reports drained.
|
|
157
|
+
*/
|
|
158
|
+
export declare const awaitConsumed: (hub: FlowEventHub, consumed: Ref.Ref<number>, timeout?: Duration.Input) => Effect.Effect<boolean>;
|
|
143
159
|
export {};
|
|
144
160
|
//# sourceMappingURL=FlowEvents.d.ts.map
|
package/dist/FlowEvents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowEvents.d.ts","sourceRoot":"","sources":["../src/FlowEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"FlowEvents.d.ts","sourceRoot":"","sources":["../src/FlowEvents.ts"],"names":[],"mappings":"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"}
|
package/dist/FlowEvents.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Context from "effect/Context";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Option from "effect/Option";
|
|
3
4
|
import * as Layer from "effect/Layer";
|
|
4
5
|
import * as PubSub from "effect/PubSub";
|
|
5
6
|
import * as Ref from "effect/Ref";
|
|
@@ -129,10 +130,33 @@ export const makeFlowEventHub = Effect.fn("@llm4ts/flow/FlowEvents.makeHub")(fun
|
|
|
129
130
|
const events = yield* PubSub.bounded(capacity);
|
|
130
131
|
const published = yield* Ref.make(0);
|
|
131
132
|
return {
|
|
132
|
-
|
|
133
|
+
// Counted AFTER delivery, and only when the PubSub accepted the event.
|
|
134
|
+
// Tallying first meant a publish interrupted while backpressured (a
|
|
135
|
+
// bounded PubSub suspends when a subscriber is behind) left `published`
|
|
136
|
+
// permanently above anything a consumer could ever reach, and every
|
|
137
|
+
// drain waiting on it never finished.
|
|
138
|
+
publish: (event) => PubSub.publish(events, event).pipe(Effect.flatMap((accepted) => accepted ? Ref.update(published, (count) => count + 1) : Effect.void), Effect.asVoid),
|
|
133
139
|
subscribe: PubSub.subscribe(events),
|
|
134
140
|
stream: Stream.fromPubSub(events),
|
|
135
141
|
publishedCount: Ref.get(published)
|
|
136
142
|
};
|
|
137
143
|
});
|
|
144
|
+
/** How long a consumer waits to catch up before the run moves on regardless. */
|
|
145
|
+
export const defaultDrainTimeout = "3 seconds";
|
|
146
|
+
/**
|
|
147
|
+
* The shared drain: wait until `consumed` has caught up with everything the
|
|
148
|
+
* hub published, and report whether it did.
|
|
149
|
+
*
|
|
150
|
+
* Bounded on purpose, and the single copy of this loop. A consumer can fall
|
|
151
|
+
* permanently short of the count — a subscription torn down early, an
|
|
152
|
+
* event the PubSub refused — and an unbounded wait then pegs a core forever.
|
|
153
|
+
* In the runner that swallowed the end of a run: every stage printed and
|
|
154
|
+
* ticked green, and no cost summary ever following, because the summary is
|
|
155
|
+
* written only once every consumer reports drained.
|
|
156
|
+
*/
|
|
157
|
+
export const awaitConsumed = (hub, consumed, timeout = defaultDrainTimeout) => Effect.gen(function* () {
|
|
158
|
+
const target = yield* hub.publishedCount;
|
|
159
|
+
const drain = Effect.suspend(() => Ref.get(consumed).pipe(Effect.flatMap((count) => count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain)))));
|
|
160
|
+
return Option.isSome(yield* Effect.timeoutOption(drain, timeout));
|
|
161
|
+
});
|
|
138
162
|
//# sourceMappingURL=FlowEvents.js.map
|
package/dist/FlowEvents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowEvents.js","sourceRoot":"","sources":["../src/FlowEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"FlowEvents.js","sourceRoot":"","sources":["../src/FlowEvents.ts"],"names":[],"mappings":"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"}
|
package/dist/FlowRecorder.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type * as Duration from "effect/Duration";
|
|
1
2
|
import * as Effect from "effect/Effect";
|
|
2
3
|
import * as Schema from "effect/Schema";
|
|
3
4
|
import type * as Scope from "effect/Scope";
|
|
4
5
|
import type { StreamRecorder } from "@llm4ts/core/observability/StreamRecorder";
|
|
5
|
-
import type
|
|
6
|
+
import { type FlowEvent, type FlowEventHub } from "./FlowEvents.ts";
|
|
6
7
|
import type { PlainFileStoreShape } from "./Persistence.ts";
|
|
7
8
|
declare const TraceLine_base: Schema.Class<TraceLine, Schema.Struct<{
|
|
8
9
|
readonly schemaVersion: Schema.optionalKey<Schema.Int>;
|
|
@@ -19,7 +20,8 @@ export interface FlowRecorderShape extends StreamRecorder {
|
|
|
19
20
|
readonly tracePath: string;
|
|
20
21
|
readonly record: (event: FlowEvent) => Effect.Effect<void>;
|
|
21
22
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>;
|
|
22
|
-
|
|
23
|
+
/** Waits for this recorder to catch up; `false` means it gave up first. */
|
|
24
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>;
|
|
23
25
|
}
|
|
24
26
|
export declare const makeFlowRecorder: (files: PlainFileStoreShape, tracePath: string, runId: string) => Effect.Effect<FlowRecorderShape, never, never>;
|
|
25
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowRecorder.d.ts","sourceRoot":"","sources":["../src/FlowRecorder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAA;AAE/E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"FlowRecorder.d.ts","sourceRoot":"","sources":["../src/FlowRecorder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAA;AAE/E,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;;;;;;;;;AAE3D,qBAAa,SAAU,SAAQ,cAO7B;CAAG;AAEL,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1D,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAChF,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CAC/F;AAYD,eAAO,MAAM,gBAAgB,kHAiE3B,CAAA"}
|
package/dist/FlowRecorder.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as Ref from "effect/Ref";
|
|
|
4
4
|
import * as Schema from "effect/Schema";
|
|
5
5
|
import * as Semaphore from "effect/Semaphore";
|
|
6
6
|
import * as Stream from "effect/Stream";
|
|
7
|
+
import { awaitConsumed } from "./FlowEvents.js";
|
|
7
8
|
export class TraceLine extends Schema.Class("TraceLine")({
|
|
8
9
|
schemaVersion: Schema.optionalKey(Schema.Int),
|
|
9
10
|
seq: Schema.Int,
|
|
@@ -63,11 +64,7 @@ export const makeFlowRecorder = Effect.fn("@llm4ts/flow/FlowRecorder.make")(func
|
|
|
63
64
|
const subscription = yield* hub.subscribe;
|
|
64
65
|
yield* Stream.fromSubscription(subscription).pipe(Stream.runForEach((event) => record(event).pipe(Effect.andThen(Ref.update(consumed, (count) => count + 1)))), Effect.forkScoped, Effect.asVoid);
|
|
65
66
|
}),
|
|
66
|
-
awaitDrained: (hub) =>
|
|
67
|
-
const target = yield* hub.publishedCount;
|
|
68
|
-
const drain = Effect.suspend(() => Ref.get(consumed).pipe(Effect.flatMap((count) => count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain)))));
|
|
69
|
-
yield* drain;
|
|
70
|
-
})
|
|
67
|
+
awaitDrained: (hub, timeout) => awaitConsumed(hub, consumed, timeout)
|
|
71
68
|
};
|
|
72
69
|
return recorder;
|
|
73
70
|
});
|
package/dist/FlowRecorder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowRecorder.js","sourceRoot":"","sources":["../src/FlowRecorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"FlowRecorder.js","sourceRoot":"","sources":["../src/FlowRecorder.ts"],"names":[],"mappings":"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"}
|
package/dist/JudgmentLog.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as Duration from "effect/Duration";
|
|
1
2
|
import * as Effect from "effect/Effect";
|
|
2
3
|
import * as Schema from "effect/Schema";
|
|
3
4
|
import type * as Scope from "effect/Scope";
|
|
@@ -34,7 +35,8 @@ export declare const judgmentLogPath: (root: string, consumer: JudgmentObservati
|
|
|
34
35
|
export interface JudgmentLogShape {
|
|
35
36
|
readonly record: (event: FlowEvent) => Effect.Effect<void>;
|
|
36
37
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>;
|
|
37
|
-
|
|
38
|
+
/** Waits for this log to catch up; `false` means it gave up first. */
|
|
39
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>;
|
|
38
40
|
}
|
|
39
41
|
/** A best-effort subscriber, with the same permanent degradation policy as FlowRecorder. */
|
|
40
42
|
export declare const makeJudgmentLog: (options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JudgmentLog.d.ts","sourceRoot":"","sources":["../src/JudgmentLog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,
|
|
1
|
+
{"version":3,"file":"JudgmentLog.d.ts","sourceRoot":"","sources":["../src/JudgmentLog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAmC,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;;;IAIzD,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;AAF/D,qBAAa,mBAAoB,SAAQ,wBAavC;CAAG;AAEL,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAU,mBAAmB,CAAC,UAAU,CAAC,KAAG,MACpB,CAAA;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1D,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAChF,sEAAsE;IACtE,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CAC/F;AAID,4FAA4F;AAC5F,eAAO,MAAM,eAAe;oBACV,mBAAmB;mBACpB,MAAM;oBACL,MAAM;mDA6CtB,CAAA"}
|
package/dist/JudgmentLog.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as Ref from "effect/Ref";
|
|
|
4
4
|
import * as Schema from "effect/Schema";
|
|
5
5
|
import * as Semaphore from "effect/Semaphore";
|
|
6
6
|
import * as Stream from "effect/Stream";
|
|
7
|
-
import { JudgmentObserved } from "./FlowEvents.js";
|
|
7
|
+
import { awaitConsumed, JudgmentObserved } from "./FlowEvents.js";
|
|
8
8
|
export class JudgmentObservation extends Schema.Class("JudgmentObservation")({
|
|
9
9
|
runId: Schema.String,
|
|
10
10
|
/** Epoch milliseconds, matching FlowRecorder's timestamp. */
|
|
@@ -42,11 +42,7 @@ export const makeJudgmentLog = Effect.fn("@llm4ts/flow/JudgmentLog.make")(functi
|
|
|
42
42
|
const line = yield* Schema.encodeEffect(codec)(observation);
|
|
43
43
|
yield* options.files.append(judgmentLogPath(options.root, event.consumer), `${line}\n`);
|
|
44
44
|
}).pipe(Effect.catch(() => Ref.set(degraded, true))));
|
|
45
|
-
const awaitDrained = (hub) =>
|
|
46
|
-
const target = yield* hub.publishedCount;
|
|
47
|
-
const drain = Effect.suspend(() => Ref.get(consumed).pipe(Effect.flatMap((count) => count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain)))));
|
|
48
|
-
yield* drain;
|
|
49
|
-
});
|
|
45
|
+
const awaitDrained = (hub, timeout) => awaitConsumed(hub, consumed, timeout);
|
|
50
46
|
return {
|
|
51
47
|
record,
|
|
52
48
|
awaitDrained,
|
package/dist/JudgmentLog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JudgmentLog.js","sourceRoot":"","sources":["../src/JudgmentLog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"JudgmentLog.js","sourceRoot":"","sources":["../src/JudgmentLog.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.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Effect-native LLM workflow, persistence, review, and repository automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"typescript"
|
|
99
99
|
],
|
|
100
100
|
"dependencies": {
|
|
101
|
-
"@llm4ts/core": "2.7.
|
|
101
|
+
"@llm4ts/core": "2.7.2"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
104
|
"effect": "4.0.0-rc.115"
|
package/src/CostTracker.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type * as Duration from "effect/Duration"
|
|
1
2
|
import * as Effect from "effect/Effect"
|
|
2
3
|
import * as Ref from "effect/Ref"
|
|
3
4
|
import type * as Scope from "effect/Scope"
|
|
4
5
|
import * as Stream from "effect/Stream"
|
|
5
6
|
import { TokenUsage } from "@llm4ts/core/Models"
|
|
6
7
|
import { CostCell } from "./CostLedger.ts"
|
|
7
|
-
import type
|
|
8
|
+
import { awaitConsumed, type FlowEvent, type FlowEventHub } from "./FlowEvents.ts"
|
|
8
9
|
import { estimateCostUsd, PricesAsOf } from "./PriceList.ts"
|
|
9
10
|
|
|
10
11
|
interface CostState {
|
|
@@ -20,7 +21,8 @@ export interface CostTracker {
|
|
|
20
21
|
readonly cells: Effect.Effect<ReadonlyArray<CostCell>>
|
|
21
22
|
readonly summary: Effect.Effect<string>
|
|
22
23
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>
|
|
23
|
-
|
|
24
|
+
/** Waits for this tracker to catch up; `false` means it gave up first. */
|
|
25
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const emptyState: CostState = {
|
|
@@ -175,18 +177,7 @@ export const makeCostTracker = Effect.fn("@llm4ts/flow/CostTracker.make")(
|
|
|
175
177
|
Effect.asVoid
|
|
176
178
|
)
|
|
177
179
|
}),
|
|
178
|
-
awaitDrained: (hub) =>
|
|
179
|
-
Effect.gen(function* () {
|
|
180
|
-
const target = yield* hub.publishedCount
|
|
181
|
-
const drain: Effect.Effect<void> = Effect.suspend(() =>
|
|
182
|
-
Ref.get(consumed).pipe(
|
|
183
|
-
Effect.flatMap((count) =>
|
|
184
|
-
count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain))
|
|
185
|
-
)
|
|
186
|
-
)
|
|
187
|
-
)
|
|
188
|
-
yield* drain
|
|
189
|
-
})
|
|
180
|
+
awaitDrained: (hub, timeout) => awaitConsumed(hub, consumed, timeout)
|
|
190
181
|
}
|
|
191
182
|
}
|
|
192
183
|
)
|
package/src/FlowEvents.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as Context from "effect/Context"
|
|
2
|
+
import type * as Duration from "effect/Duration"
|
|
2
3
|
import * as Effect from "effect/Effect"
|
|
4
|
+
import * as Option from "effect/Option"
|
|
3
5
|
import * as Layer from "effect/Layer"
|
|
4
6
|
import * as PubSub from "effect/PubSub"
|
|
5
7
|
import * as Ref from "effect/Ref"
|
|
@@ -177,9 +179,16 @@ export const makeFlowEventHub = Effect.fn("@llm4ts/flow/FlowEvents.makeHub")(fun
|
|
|
177
179
|
const events = yield* PubSub.bounded<FlowEvent>(capacity)
|
|
178
180
|
const published = yield* Ref.make(0)
|
|
179
181
|
return {
|
|
182
|
+
// Counted AFTER delivery, and only when the PubSub accepted the event.
|
|
183
|
+
// Tallying first meant a publish interrupted while backpressured (a
|
|
184
|
+
// bounded PubSub suspends when a subscriber is behind) left `published`
|
|
185
|
+
// permanently above anything a consumer could ever reach, and every
|
|
186
|
+
// drain waiting on it never finished.
|
|
180
187
|
publish: (event) =>
|
|
181
|
-
|
|
182
|
-
Effect.
|
|
188
|
+
PubSub.publish(events, event).pipe(
|
|
189
|
+
Effect.flatMap((accepted) =>
|
|
190
|
+
accepted ? Ref.update(published, (count) => count + 1) : Effect.void
|
|
191
|
+
),
|
|
183
192
|
Effect.asVoid
|
|
184
193
|
),
|
|
185
194
|
subscribe: PubSub.subscribe(events),
|
|
@@ -187,3 +196,34 @@ export const makeFlowEventHub = Effect.fn("@llm4ts/flow/FlowEvents.makeHub")(fun
|
|
|
187
196
|
publishedCount: Ref.get(published)
|
|
188
197
|
}
|
|
189
198
|
})
|
|
199
|
+
|
|
200
|
+
/** How long a consumer waits to catch up before the run moves on regardless. */
|
|
201
|
+
export const defaultDrainTimeout = "3 seconds"
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* The shared drain: wait until `consumed` has caught up with everything the
|
|
205
|
+
* hub published, and report whether it did.
|
|
206
|
+
*
|
|
207
|
+
* Bounded on purpose, and the single copy of this loop. A consumer can fall
|
|
208
|
+
* permanently short of the count — a subscription torn down early, an
|
|
209
|
+
* event the PubSub refused — and an unbounded wait then pegs a core forever.
|
|
210
|
+
* In the runner that swallowed the end of a run: every stage printed and
|
|
211
|
+
* ticked green, and no cost summary ever following, because the summary is
|
|
212
|
+
* written only once every consumer reports drained.
|
|
213
|
+
*/
|
|
214
|
+
export const awaitConsumed = (
|
|
215
|
+
hub: FlowEventHub,
|
|
216
|
+
consumed: Ref.Ref<number>,
|
|
217
|
+
timeout: Duration.Input = defaultDrainTimeout
|
|
218
|
+
): Effect.Effect<boolean> =>
|
|
219
|
+
Effect.gen(function* () {
|
|
220
|
+
const target = yield* hub.publishedCount
|
|
221
|
+
const drain: Effect.Effect<void> = Effect.suspend(() =>
|
|
222
|
+
Ref.get(consumed).pipe(
|
|
223
|
+
Effect.flatMap((count) =>
|
|
224
|
+
count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain))
|
|
225
|
+
)
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
return Option.isSome(yield* Effect.timeoutOption(drain, timeout))
|
|
229
|
+
})
|
package/src/FlowRecorder.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Clock from "effect/Clock"
|
|
2
|
+
import type * as Duration from "effect/Duration"
|
|
2
3
|
import * as Effect from "effect/Effect"
|
|
3
4
|
import * as Ref from "effect/Ref"
|
|
4
5
|
import * as Schema from "effect/Schema"
|
|
@@ -7,7 +8,7 @@ import type * as Scope from "effect/Scope"
|
|
|
7
8
|
import * as Stream from "effect/Stream"
|
|
8
9
|
import type { StreamRecorder } from "@llm4ts/core/observability/StreamRecorder"
|
|
9
10
|
import type { JsonValue } from "@llm4ts/core/providers/CliSupport"
|
|
10
|
-
import type
|
|
11
|
+
import { awaitConsumed, type FlowEvent, type FlowEventHub } from "./FlowEvents.ts"
|
|
11
12
|
import type { PlainFileStoreShape } from "./Persistence.ts"
|
|
12
13
|
|
|
13
14
|
export class TraceLine extends Schema.Class<TraceLine>("TraceLine")({
|
|
@@ -24,7 +25,8 @@ export interface FlowRecorderShape extends StreamRecorder {
|
|
|
24
25
|
readonly tracePath: string
|
|
25
26
|
readonly record: (event: FlowEvent) => Effect.Effect<void>
|
|
26
27
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>
|
|
27
|
-
|
|
28
|
+
/** Waits for this recorder to catch up; `false` means it gave up first. */
|
|
29
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
const encode = (line: TraceLine): string =>
|
|
@@ -99,18 +101,7 @@ export const makeFlowRecorder = Effect.fn("@llm4ts/flow/FlowRecorder.make")(func
|
|
|
99
101
|
Effect.asVoid
|
|
100
102
|
)
|
|
101
103
|
}),
|
|
102
|
-
awaitDrained: (hub) =>
|
|
103
|
-
Effect.gen(function* () {
|
|
104
|
-
const target = yield* hub.publishedCount
|
|
105
|
-
const drain: Effect.Effect<void> = Effect.suspend(() =>
|
|
106
|
-
Ref.get(consumed).pipe(
|
|
107
|
-
Effect.flatMap((count) =>
|
|
108
|
-
count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain))
|
|
109
|
-
)
|
|
110
|
-
)
|
|
111
|
-
)
|
|
112
|
-
yield* drain
|
|
113
|
-
})
|
|
104
|
+
awaitDrained: (hub, timeout) => awaitConsumed(hub, consumed, timeout)
|
|
114
105
|
}
|
|
115
106
|
return recorder
|
|
116
107
|
})
|
package/src/JudgmentLog.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as Clock from "effect/Clock"
|
|
2
|
+
import type * as Duration from "effect/Duration"
|
|
2
3
|
import * as Effect from "effect/Effect"
|
|
3
4
|
import * as Ref from "effect/Ref"
|
|
4
5
|
import * as Schema from "effect/Schema"
|
|
5
6
|
import * as Semaphore from "effect/Semaphore"
|
|
6
7
|
import type * as Scope from "effect/Scope"
|
|
7
8
|
import * as Stream from "effect/Stream"
|
|
8
|
-
import { JudgmentObserved, type FlowEvent, type FlowEventHub } from "./FlowEvents.ts"
|
|
9
|
+
import { awaitConsumed, JudgmentObserved, type FlowEvent, type FlowEventHub } from "./FlowEvents.ts"
|
|
9
10
|
import type { PlainFileStoreShape } from "./Persistence.ts"
|
|
10
11
|
|
|
11
12
|
export class JudgmentObservation extends Schema.Class<JudgmentObservation>("JudgmentObservation")({
|
|
@@ -29,7 +30,8 @@ export const judgmentLogPath = (root: string, consumer: JudgmentObservation["con
|
|
|
29
30
|
export interface JudgmentLogShape {
|
|
30
31
|
readonly record: (event: FlowEvent) => Effect.Effect<void>
|
|
31
32
|
readonly consume: (hub: FlowEventHub) => Effect.Effect<void, never, Scope.Scope>
|
|
32
|
-
|
|
33
|
+
/** Waits for this log to catch up; `false` means it gave up first. */
|
|
34
|
+
readonly awaitDrained: (hub: FlowEventHub, timeout?: Duration.Input) => Effect.Effect<boolean>
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
const codec = Schema.fromJsonString(JudgmentObservation)
|
|
@@ -63,18 +65,8 @@ export const makeJudgmentLog = Effect.fn("@llm4ts/flow/JudgmentLog.make")(functi
|
|
|
63
65
|
}).pipe(Effect.catch(() => Ref.set(degraded, true)))
|
|
64
66
|
)
|
|
65
67
|
|
|
66
|
-
const awaitDrained = (hub: FlowEventHub): Effect.Effect<
|
|
67
|
-
|
|
68
|
-
const target = yield* hub.publishedCount
|
|
69
|
-
const drain: Effect.Effect<void> = Effect.suspend(() =>
|
|
70
|
-
Ref.get(consumed).pipe(
|
|
71
|
-
Effect.flatMap((count) =>
|
|
72
|
-
count >= target ? Effect.void : Effect.yieldNow.pipe(Effect.andThen(drain))
|
|
73
|
-
)
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
yield* drain
|
|
77
|
-
})
|
|
68
|
+
const awaitDrained = (hub: FlowEventHub, timeout?: Duration.Input): Effect.Effect<boolean> =>
|
|
69
|
+
awaitConsumed(hub, consumed, timeout)
|
|
78
70
|
|
|
79
71
|
return {
|
|
80
72
|
record,
|