@llm4ts/runner 3.3.0 → 4.0.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/README.md +1 -1
- package/dist/AgentTree.d.ts +2 -3
- package/dist/AgentTree.d.ts.map +1 -1
- package/dist/AgentTree.js +8 -20
- package/dist/AgentTree.js.map +1 -1
- package/dist/AgentTreeSurface.d.ts +1 -1
- package/dist/AgentTreeSurface.d.ts.map +1 -1
- package/dist/AgentTreeSurface.js +2 -5
- package/dist/AgentTreeSurface.js.map +1 -1
- package/dist/Cli.d.ts.map +1 -1
- package/dist/Cli.js +2 -1
- package/dist/Cli.js.map +1 -1
- package/dist/Connectors.d.ts +27 -2
- package/dist/Connectors.d.ts.map +1 -1
- package/dist/Connectors.js +76 -89
- package/dist/Connectors.js.map +1 -1
- package/dist/Doctor.d.ts.map +1 -1
- package/dist/Doctor.js +8 -11
- package/dist/Doctor.js.map +1 -1
- package/dist/EventPresentation.d.ts +35 -0
- package/dist/EventPresentation.d.ts.map +1 -0
- package/dist/EventPresentation.js +132 -0
- package/dist/EventPresentation.js.map +1 -0
- package/dist/ExecutorRoster.d.ts.map +1 -1
- package/dist/ExecutorRoster.js +4 -6
- package/dist/ExecutorRoster.js.map +1 -1
- package/dist/FlowArgs.d.ts +1 -1
- package/dist/FlowArgs.d.ts.map +1 -1
- package/dist/FlowArgs.js +4 -2
- package/dist/FlowArgs.js.map +1 -1
- package/dist/FlowRunner.d.ts +13 -4
- package/dist/FlowRunner.d.ts.map +1 -1
- package/dist/FlowRunner.js +50 -39
- package/dist/FlowRunner.js.map +1 -1
- package/dist/NodeGeminiCliExecutor.d.ts.map +1 -1
- package/dist/NodeGeminiCliExecutor.js +7 -4
- package/dist/NodeGeminiCliExecutor.js.map +1 -1
- package/dist/NodeGeminiModelBridge.d.ts.map +1 -1
- package/dist/NodeGeminiModelBridge.js +4 -1
- package/dist/NodeGeminiModelBridge.js.map +1 -1
- package/dist/NodeHttpClient.d.ts.map +1 -1
- package/dist/NodeHttpClient.js +1 -0
- package/dist/NodeHttpClient.js.map +1 -1
- package/dist/Otel.d.ts.map +1 -1
- package/dist/Otel.js +5 -5
- package/dist/Otel.js.map +1 -1
- package/dist/Package.d.ts.map +1 -1
- package/dist/Package.js +1 -0
- package/dist/Package.js.map +1 -1
- package/dist/Packs.d.ts.map +1 -1
- package/dist/Packs.js +2 -1
- package/dist/Packs.js.map +1 -1
- package/dist/PiModels.d.ts.map +1 -1
- package/dist/PiModels.js +6 -9
- package/dist/PiModels.js.map +1 -1
- package/dist/Terminal.d.ts +13 -11
- package/dist/Terminal.d.ts.map +1 -1
- package/dist/Terminal.js +24 -80
- package/dist/Terminal.js.map +1 -1
- package/dist/Tools.d.ts.map +1 -1
- package/dist/Tools.js +2 -1
- package/dist/Tools.js.map +1 -1
- package/dist/Transcripts.d.ts +1 -1
- package/dist/Transcripts.d.ts.map +1 -1
- package/dist/Transcripts.js +3 -2
- package/dist/Transcripts.js.map +1 -1
- package/dist/WindowsCommand.d.ts.map +1 -1
- package/dist/WindowsCommand.js +1 -0
- package/dist/WindowsCommand.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/package.json +9 -21
- package/src/AgentTree.ts +16 -25
- package/src/AgentTreeSurface.ts +6 -11
- package/src/Cli.ts +2 -1
- package/src/Connectors.ts +131 -107
- package/src/Doctor.ts +10 -12
- package/src/EventPresentation.ts +167 -0
- package/src/ExecutorRoster.ts +4 -6
- package/src/FlowArgs.ts +7 -2
- package/src/FlowRunner.ts +66 -60
- package/src/NodeGeminiCliExecutor.ts +8 -4
- package/src/NodeGeminiModelBridge.ts +5 -1
- package/src/NodeHttpClient.ts +1 -0
- package/src/Otel.ts +5 -6
- package/src/Package.ts +1 -0
- package/src/Packs.ts +2 -1
- package/src/PiModels.ts +6 -10
- package/src/Terminal.ts +104 -165
- package/src/Tools.ts +2 -1
- package/src/Transcripts.ts +3 -2
- package/src/WindowsCommand.ts +1 -0
- package/src/index.ts +3 -2
- package/dist/Costs.d.ts +0 -52
- package/dist/Costs.d.ts.map +0 -1
- package/dist/Costs.js +0 -95
- package/dist/Costs.js.map +0 -1
- package/dist/McpStdio.d.ts +0 -7
- package/dist/McpStdio.d.ts.map +0 -1
- package/dist/McpStdio.js +0 -19
- package/dist/McpStdio.js.map +0 -1
- package/dist/Profile.d.ts +0 -309
- package/dist/Profile.d.ts.map +0 -1
- package/dist/Profile.js +0 -967
- package/dist/Profile.js.map +0 -1
- package/dist/ReviewFingerprint.d.ts +0 -2
- package/dist/ReviewFingerprint.d.ts.map +0 -1
- package/dist/ReviewFingerprint.js +0 -13
- package/dist/ReviewFingerprint.js.map +0 -1
- package/dist/RunReaders.d.ts +0 -69
- package/dist/RunReaders.d.ts.map +0 -1
- package/dist/RunReaders.js +0 -283
- package/dist/RunReaders.js.map +0 -1
- package/dist/StoryReaders.d.ts +0 -16
- package/dist/StoryReaders.d.ts.map +0 -1
- package/dist/StoryReaders.js +0 -107
- package/dist/StoryReaders.js.map +0 -1
- package/dist/Watch.d.ts +0 -68
- package/dist/Watch.d.ts.map +0 -1
- package/dist/Watch.js +0 -261
- package/dist/Watch.js.map +0 -1
- package/src/Costs.ts +0 -148
- package/src/McpStdio.ts +0 -41
- package/src/Profile.ts +0 -1213
- package/src/ReviewFingerprint.ts +0 -13
- package/src/RunReaders.ts +0 -419
- package/src/StoryReaders.ts +0 -157
- package/src/Watch.ts +0 -446
package/src/Terminal.ts
CHANGED
|
@@ -5,18 +5,16 @@ import * as Effect from "effect/Effect"
|
|
|
5
5
|
import * as Ref from "effect/Ref"
|
|
6
6
|
import * as Semaphore from "effect/Semaphore"
|
|
7
7
|
import type * as Scope from "effect/Scope"
|
|
8
|
-
import * as Schema from "effect/Schema"
|
|
9
|
-
import * as Stream from "effect/Stream"
|
|
10
8
|
import {
|
|
11
|
-
|
|
9
|
+
eventLanes,
|
|
12
10
|
type FlowEvent,
|
|
13
11
|
type FlowEventHub,
|
|
12
|
+
laneOf,
|
|
13
|
+
type LaneRef,
|
|
14
14
|
rosterEventMessage,
|
|
15
15
|
type ReviewFindings
|
|
16
16
|
} from "@llm4ts/flow/FlowEvents"
|
|
17
|
-
|
|
18
|
-
export const Verbosity = Schema.Literals(["Quiet", "Normal", "Verbose", "Debug"])
|
|
19
|
-
export type Verbosity = typeof Verbosity.Type
|
|
17
|
+
import { atLeast, presentationOf, type Verbosity } from "./EventPresentation.ts"
|
|
20
18
|
|
|
21
19
|
export const parseVerbosity = (value: string | undefined): Verbosity => {
|
|
22
20
|
switch (value?.trim().toLowerCase()) {
|
|
@@ -32,45 +30,10 @@ export const parseVerbosity = (value: string | undefined): Verbosity => {
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
export const rendersEvent = (verbosity: Verbosity, event: FlowEvent): boolean => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// cleared it. None is a line of its own.
|
|
40
|
-
case "JudgmentObserved":
|
|
41
|
-
case "BlackboardRun":
|
|
42
|
-
case "UsageProgress":
|
|
43
|
-
case "ExecutorReleased":
|
|
44
|
-
case "StoryJudged":
|
|
45
|
-
case "RoundtableTurn":
|
|
46
|
-
case "BriefReported":
|
|
47
|
-
case "Timed":
|
|
48
|
-
case "TasksPlanned":
|
|
49
|
-
case "TaskStarted":
|
|
50
|
-
case "TaskCompleted":
|
|
51
|
-
case "StoryStatusChanged":
|
|
52
|
-
return false
|
|
53
|
-
// A gate or a setup may run for many minutes: its start is a line, so a
|
|
54
|
-
// long one reads as running, not stuck. Other work starts too often.
|
|
55
|
-
case "Began":
|
|
56
|
-
return event.kind === "gate" && verbosity !== "Quiet"
|
|
57
|
-
case "StageStarted":
|
|
58
|
-
case "StageCompleted":
|
|
59
|
-
case "StageFailed":
|
|
60
|
-
case "Aborted":
|
|
61
|
-
case "CapabilityDenied":
|
|
62
|
-
case "CapabilityUnenforceable":
|
|
63
|
-
case "EvidenceChecked":
|
|
64
|
-
case "ReviewFindingDemoted":
|
|
65
|
-
return true
|
|
66
|
-
// Every git read and gate command is a capability event: useful in a
|
|
67
|
-
// trace, noise on screen once several stories run.
|
|
68
|
-
case "TokensUsed":
|
|
69
|
-
case "CapabilityUsed":
|
|
70
|
-
return verbosity === "Verbose" || verbosity === "Debug"
|
|
71
|
-
default:
|
|
72
|
-
return verbosity !== "Quiet"
|
|
73
|
-
}
|
|
33
|
+
const { line } = presentationOf(event)
|
|
34
|
+
return typeof line === "function"
|
|
35
|
+
? line(event, verbosity)
|
|
36
|
+
: line !== "never" && atLeast(verbosity, line)
|
|
74
37
|
}
|
|
75
38
|
|
|
76
39
|
export const terminalSafe = (value: string): string => {
|
|
@@ -313,8 +276,6 @@ export const terminalLine = (
|
|
|
313
276
|
: palette.dim(
|
|
314
277
|
`evidence: ${safe(event.task)} — ${event.claimed} claimed command(s) ran${event.confidence === undefined ? "" : `, confidence ${event.confidence}`}`
|
|
315
278
|
)
|
|
316
|
-
case "Declassified":
|
|
317
|
-
return palette.info(`declassified: ${safe(event.label)}`)
|
|
318
279
|
case "ExecutorLeased":
|
|
319
280
|
case "ExecutorReleased":
|
|
320
281
|
case "ExecutorExcluded":
|
|
@@ -548,7 +509,6 @@ export interface TerminalRunStats {
|
|
|
548
509
|
}
|
|
549
510
|
|
|
550
511
|
export interface TerminalConsumer {
|
|
551
|
-
readonly consumed: Ref.Ref<number>
|
|
552
512
|
readonly stats: Effect.Effect<TerminalRunStats>
|
|
553
513
|
readonly awaitDrained: (timeout?: Duration.Input) => Effect.Effect<void>
|
|
554
514
|
}
|
|
@@ -562,33 +522,20 @@ interface OpenStage {
|
|
|
562
522
|
readonly startedAt: number
|
|
563
523
|
}
|
|
564
524
|
|
|
565
|
-
/**
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
case "TasksPlanned":
|
|
580
|
-
case "TaskStarted":
|
|
581
|
-
case "TaskCompleted":
|
|
582
|
-
return event.lane === undefined
|
|
583
|
-
? undefined
|
|
584
|
-
: {
|
|
585
|
-
lane: event.lane,
|
|
586
|
-
...(event.executor === undefined ? {} : { executor: event.executor })
|
|
587
|
-
}
|
|
588
|
-
default:
|
|
589
|
-
return undefined
|
|
590
|
-
}
|
|
591
|
-
}
|
|
525
|
+
/**
|
|
526
|
+
* The lane an event belongs to on screen (a concurrent story), if it carries
|
|
527
|
+
* one. This is `laneOf` with two exclusions, both kept as they were:
|
|
528
|
+
* - an event whose producer names its lane (a verdict, a roundtable turn, an
|
|
529
|
+
* evidence check, a parked item) prints, when it prints, as a line of the
|
|
530
|
+
* run: only the events `withLane` stamps drive a lane's row;
|
|
531
|
+
* - `Timed` and `Began`: one arriving after its lane's last stage closed
|
|
532
|
+
* would reopen a row that never closes (`UsageProgress` has the same
|
|
533
|
+
* hazard and is guarded where the consumer reads it).
|
|
534
|
+
*/
|
|
535
|
+
export const laneOfEvent = (event: FlowEvent): LaneRef | undefined =>
|
|
536
|
+
eventLanes[event._tag].lane !== "stamped" || event._tag === "Timed" || event._tag === "Began"
|
|
537
|
+
? undefined
|
|
538
|
+
: laneOf(event)
|
|
592
539
|
|
|
593
540
|
/** `bonifici-list · lemonade-deepseek` — how a lane is named on screen. */
|
|
594
541
|
export const laneLabel = (lane: string, executor: string | undefined): string =>
|
|
@@ -744,9 +691,7 @@ export const consumeTerminalEvents = Effect.fn("@llm4ts/runner/Terminal.consume"
|
|
|
744
691
|
// Tokens of events outside any lane: the whole run, for a flow with one coder.
|
|
745
692
|
const runTokens = emptyTally()
|
|
746
693
|
const runInFlight = new Map<string, TokenTally>()
|
|
747
|
-
const consumed = yield* Ref.make(0)
|
|
748
694
|
const statsRef = yield* Ref.make<TerminalRunStats>({ stagesCompleted: 0, stagesFailed: 0 })
|
|
749
|
-
const subscription = yield* events.subscribe
|
|
750
695
|
const palette = surface.palette
|
|
751
696
|
const timestampPrefix =
|
|
752
697
|
options.timestamps === true
|
|
@@ -800,99 +745,93 @@ export const consumeTerminalEvents = Effect.fn("@llm4ts/runner/Terminal.consume"
|
|
|
800
745
|
return `${line} ${palette.dim(`(${formatDurationMs(now - closed.startedAt)})`)}`
|
|
801
746
|
})
|
|
802
747
|
|
|
803
|
-
yield*
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
lanes.
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
if (tagged.executor !== undefined) {
|
|
829
|
-
state.executor = tagged.executor
|
|
830
|
-
}
|
|
831
|
-
let closed: OpenStage | undefined
|
|
832
|
-
if (closesChild(event)) {
|
|
833
|
-
state.depth = Math.max(0, state.depth - 1)
|
|
834
|
-
}
|
|
835
|
-
const lineDepth = state.depth
|
|
836
|
-
if (event._tag === "StageStarted") {
|
|
837
|
-
state.depth += 1
|
|
838
|
-
state.stages = [...state.stages, { name: terminalSafe(event.stage), startedAt: now }]
|
|
839
|
-
} else if (closesChild(event)) {
|
|
840
|
-
closed = state.stages.at(-1)
|
|
841
|
-
state.stages = state.stages.slice(0, -1)
|
|
842
|
-
yield* countStage(event)
|
|
843
|
-
} else if (event._tag === "ToolUse") {
|
|
844
|
-
state.tools += 1
|
|
845
|
-
state.lastTool = { tool: terminalSafe(event.tool), at: now }
|
|
846
|
-
}
|
|
847
|
-
addTokens(state.tokens, event)
|
|
848
|
-
trackProgress(state.inFlight, event)
|
|
849
|
-
if (state.stages.length === 0 && closesChild(event)) {
|
|
850
|
-
lanes.delete(tagged.lane)
|
|
851
|
-
}
|
|
852
|
-
if (rendersLanedEvent(verbosity, event)) {
|
|
853
|
-
const tag = palette.lane(state.index, `[${laneLabel(tagged.lane, state.executor)}]`)
|
|
854
|
-
const line = yield* withDuration(event, terminalLine(event, palette, verbosity), closed)
|
|
855
|
-
const prefix = yield* timestampPrefix
|
|
856
|
-
yield* surface.log(`${prefix}${tag} ${indentBlock(lineDepth, line)}`)
|
|
857
|
-
}
|
|
858
|
-
yield* refreshStatus
|
|
859
|
-
yield* Ref.update(consumed, (count) => count + 1)
|
|
860
|
-
return
|
|
748
|
+
const consumer = yield* events.consume("terminal", (event) =>
|
|
749
|
+
Effect.gen(function* () {
|
|
750
|
+
const tagged = laneOfEvent(event)
|
|
751
|
+
if (tagged !== undefined && event._tag === "UsageProgress" && !lanes.has(tagged.lane)) {
|
|
752
|
+
// A call that ends after its story's row closed: nothing to show.
|
|
753
|
+
return
|
|
754
|
+
}
|
|
755
|
+
if (tagged !== undefined) {
|
|
756
|
+
const now = yield* Clock.currentTimeMillis
|
|
757
|
+
const state =
|
|
758
|
+
lanes.get(tagged.lane) ??
|
|
759
|
+
({
|
|
760
|
+
index: lanes.size,
|
|
761
|
+
depth: 0,
|
|
762
|
+
stages: [],
|
|
763
|
+
tools: 0,
|
|
764
|
+
executor: undefined,
|
|
765
|
+
startedAt: now,
|
|
766
|
+
tokens: emptyTally(),
|
|
767
|
+
inFlight: new Map(),
|
|
768
|
+
lastTool: undefined
|
|
769
|
+
} satisfies LaneState)
|
|
770
|
+
lanes.set(tagged.lane, state)
|
|
771
|
+
if (tagged.executor !== undefined) {
|
|
772
|
+
state.executor = tagged.executor
|
|
861
773
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
yield* refreshStatus
|
|
774
|
+
let closed: OpenStage | undefined
|
|
775
|
+
if (closesChild(event)) {
|
|
776
|
+
state.depth = Math.max(0, state.depth - 1)
|
|
866
777
|
}
|
|
867
|
-
const
|
|
868
|
-
? yield* Ref.updateAndGet(depth, (value) => Math.max(0, value - 1))
|
|
869
|
-
: yield* Ref.get(depth)
|
|
870
|
-
let closedStage: OpenStage | undefined
|
|
778
|
+
const lineDepth = state.depth
|
|
871
779
|
if (event._tag === "StageStarted") {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const startedAt = yield* Clock.currentTimeMillis
|
|
875
|
-
yield* Ref.update(stages, (current) => [...current, { name: active, startedAt }])
|
|
876
|
-
yield* refreshStatus
|
|
780
|
+
state.depth += 1
|
|
781
|
+
state.stages = [...state.stages, { name: terminalSafe(event.stage), startedAt: now }]
|
|
877
782
|
} else if (closesChild(event)) {
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
yield* refreshStatus
|
|
783
|
+
closed = state.stages.at(-1)
|
|
784
|
+
state.stages = state.stages.slice(0, -1)
|
|
881
785
|
yield* countStage(event)
|
|
786
|
+
} else if (event._tag === "ToolUse") {
|
|
787
|
+
state.tools += 1
|
|
788
|
+
state.lastTool = { tool: terminalSafe(event.tool), at: now }
|
|
882
789
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
790
|
+
addTokens(state.tokens, event)
|
|
791
|
+
trackProgress(state.inFlight, event)
|
|
792
|
+
if (state.stages.length === 0 && closesChild(event)) {
|
|
793
|
+
lanes.delete(tagged.lane)
|
|
794
|
+
}
|
|
795
|
+
if (rendersLanedEvent(verbosity, event)) {
|
|
796
|
+
const tag = palette.lane(state.index, `[${laneLabel(tagged.lane, state.executor)}]`)
|
|
797
|
+
const line = yield* withDuration(event, terminalLine(event, palette, verbosity), closed)
|
|
889
798
|
const prefix = yield* timestampPrefix
|
|
890
|
-
yield* surface.log(`${prefix}${indentBlock(
|
|
799
|
+
yield* surface.log(`${prefix}${tag} ${indentBlock(lineDepth, line)}`)
|
|
891
800
|
}
|
|
892
|
-
yield*
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
801
|
+
yield* refreshStatus
|
|
802
|
+
return
|
|
803
|
+
}
|
|
804
|
+
if (event._tag === "TokensUsed" || event._tag === "UsageProgress") {
|
|
805
|
+
addTokens(runTokens, event)
|
|
806
|
+
trackProgress(runInFlight, event)
|
|
807
|
+
yield* refreshStatus
|
|
808
|
+
}
|
|
809
|
+
const currentDepth = closesChild(event)
|
|
810
|
+
? yield* Ref.updateAndGet(depth, (value) => Math.max(0, value - 1))
|
|
811
|
+
: yield* Ref.get(depth)
|
|
812
|
+
let closedStage: OpenStage | undefined
|
|
813
|
+
if (event._tag === "StageStarted") {
|
|
814
|
+
yield* Ref.update(depth, (value) => value + 1)
|
|
815
|
+
const active = terminalSafe(event.stage)
|
|
816
|
+
const startedAt = yield* Clock.currentTimeMillis
|
|
817
|
+
yield* Ref.update(stages, (current) => [...current, { name: active, startedAt }])
|
|
818
|
+
yield* refreshStatus
|
|
819
|
+
} else if (closesChild(event)) {
|
|
820
|
+
closedStage = (yield* Ref.get(stages)).at(-1)
|
|
821
|
+
yield* Ref.update(stages, (current) => current.slice(0, -1))
|
|
822
|
+
yield* refreshStatus
|
|
823
|
+
yield* countStage(event)
|
|
824
|
+
}
|
|
825
|
+
if (rendersEvent(verbosity, event)) {
|
|
826
|
+
const line = yield* withDuration(
|
|
827
|
+
event,
|
|
828
|
+
terminalLine(event, palette, verbosity),
|
|
829
|
+
closedStage
|
|
830
|
+
)
|
|
831
|
+
const prefix = yield* timestampPrefix
|
|
832
|
+
yield* surface.log(`${prefix}${indentBlock(currentDepth, line)}`)
|
|
833
|
+
}
|
|
834
|
+
})
|
|
896
835
|
)
|
|
897
836
|
// Elapsed time and "Running <tool>…" age between events too.
|
|
898
837
|
yield* Effect.sleep("1 second").pipe(
|
|
@@ -901,8 +840,8 @@ export const consumeTerminalEvents = Effect.fn("@llm4ts/runner/Terminal.consume"
|
|
|
901
840
|
Effect.forkScoped
|
|
902
841
|
)
|
|
903
842
|
// Display only, so a drain that gives up just means a trailing line was
|
|
904
|
-
// never printed; the
|
|
843
|
+
// never printed; the hub already bounds the wait.
|
|
905
844
|
const awaitDrained = (timeout?: Duration.Input): Effect.Effect<void> =>
|
|
906
|
-
Effect.asVoid(
|
|
907
|
-
return {
|
|
845
|
+
Effect.asVoid(consumer.caughtUp(timeout))
|
|
846
|
+
return { stats: Ref.get(statsRef), awaitDrained }
|
|
908
847
|
})
|
package/src/Tools.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { builtinTools } from "@llm4ts/flow/tools/Builtin"
|
|
|
7
7
|
import type { ToolReport, ToolSpec } from "@llm4ts/flow/tools/Tool"
|
|
8
8
|
import { isToolName, renderUsage, specOf, type ToolShape } from "@llm4ts/flow/tools/Tool"
|
|
9
9
|
import type { ToolPreset } from "@llm4ts/flow/Pack"
|
|
10
|
+
import { settingValue } from "@llm4ts/flow/Settings"
|
|
10
11
|
import type { DiscoveredKit } from "./Kits.ts"
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -177,7 +178,7 @@ export const toolBrief = (
|
|
|
177
178
|
specs: ReadonlyMap<string, ToolSpec>,
|
|
178
179
|
environment: Readonly<Record<string, string | undefined>> = process.env
|
|
179
180
|
): string | undefined => {
|
|
180
|
-
if (
|
|
181
|
+
if (!settingValue("LLM4TS_TOOL_BRIEF", environment)) {
|
|
181
182
|
return undefined
|
|
182
183
|
}
|
|
183
184
|
const lines = [
|
package/src/Transcripts.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as Effect from "effect/Effect"
|
|
|
4
4
|
import * as Schema from "effect/Schema"
|
|
5
5
|
import { summariseToolArgs } from "@llm4ts/flow/Activity"
|
|
6
6
|
import { TranscriptEntry, type TranscriptSink } from "@llm4ts/flow/Transcript"
|
|
7
|
+
import { settingValue } from "@llm4ts/flow/Settings"
|
|
7
8
|
import { duration } from "./AgentTree.ts"
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -14,10 +15,10 @@ import { duration } from "./AgentTree.ts"
|
|
|
14
15
|
* never fails the run.
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
|
-
/** `LLM4TS_TRANSCRIPT=on` (what `--transcript` sets)
|
|
18
|
+
/** `LLM4TS_TRANSCRIPT=on` (what `--transcript` sets). */
|
|
18
19
|
export const transcriptsWanted = (
|
|
19
20
|
environment: Readonly<Record<string, string | undefined>>
|
|
20
|
-
): boolean =>
|
|
21
|
+
): boolean => settingValue("LLM4TS_TRANSCRIPT", environment) === true
|
|
21
22
|
|
|
22
23
|
export const transcriptFileOf = (lane: string | undefined): string =>
|
|
23
24
|
`${(lane ?? "run").replace(/[^A-Za-z0-9._-]/gu, "_")}.jsonl`
|
package/src/WindowsCommand.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -14,8 +14,10 @@ export {
|
|
|
14
14
|
asReadOnly,
|
|
15
15
|
asToolless,
|
|
16
16
|
coderFor,
|
|
17
|
-
coderFromEnv,
|
|
18
17
|
mock,
|
|
18
|
+
coderFromEnvironment,
|
|
19
|
+
reasonerFromEnvironment,
|
|
20
|
+
seatsFromEnvironment,
|
|
19
21
|
withModel,
|
|
20
22
|
withTurnLimit
|
|
21
23
|
} from "./Connectors.ts"
|
|
@@ -24,7 +26,6 @@ export type { OpenedPack } from "./Packs.ts"
|
|
|
24
26
|
export { nodePlainFileStore } from "./NodePlainFileStore.ts"
|
|
25
27
|
export { makeNodeWorkspace } from "./NodeWorkspace.ts"
|
|
26
28
|
export { nodeProcessExecutor } from "./NodeProcessExecutor.ts"
|
|
27
|
-
export { reviewFingerprint } from "./ReviewFingerprint.ts"
|
|
28
29
|
|
|
29
30
|
export { completeAndPublish, implementPlanFlow } from "@llm4ts/flow/Flow"
|
|
30
31
|
export type { ImplementPlanOptions } from "@llm4ts/flow/Flow"
|
package/dist/Costs.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type * as DateTime from "effect/DateTime";
|
|
2
|
-
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Schema from "effect/Schema";
|
|
4
|
-
import { CostReport } from "@llm4ts/flow/CostReport";
|
|
5
|
-
import type { PlainFileStoreShape } from "@llm4ts/flow/Persistence";
|
|
6
|
-
/**
|
|
7
|
-
* `llm4ts costs`: the budgeting view over every trace the runner wrote.
|
|
8
|
-
*
|
|
9
|
-
* Traces are the source for timing: a run can span hours and only the trace
|
|
10
|
-
* carries a timestamp per token report, which the hourly buckets need. The
|
|
11
|
-
* cost ledger is the source for each run's total: its line is the run's own
|
|
12
|
-
* summary, and a trace can be short (`CostReport.reconcileWithLedger`). One
|
|
13
|
-
* unreadable trace is reported and skipped rather than failing the whole
|
|
14
|
-
* report — the other runs still answer the question.
|
|
15
|
-
*/
|
|
16
|
-
export declare const TraceDirectoryName = ".llm4ts";
|
|
17
|
-
/** `trace-<timestamp>.jsonl` as the runner writes it, or a prefixed variant like `loop-trace-…`. */
|
|
18
|
-
export declare const isTraceFileName: (name: string) => boolean;
|
|
19
|
-
export declare const nodeListTraces: (directory: string) => ReadonlyArray<string>;
|
|
20
|
-
export interface CostsOptions {
|
|
21
|
-
/** Repositories whose `.llm4ts/` traces are read. */
|
|
22
|
-
readonly repos: ReadonlyArray<string>;
|
|
23
|
-
/** Drop token reports before this epoch millisecond. */
|
|
24
|
-
readonly since?: number;
|
|
25
|
-
readonly timeZone?: DateTime.TimeZone;
|
|
26
|
-
readonly runsPerDay?: number;
|
|
27
|
-
}
|
|
28
|
-
export interface CostsDependencies {
|
|
29
|
-
readonly files: PlainFileStoreShape;
|
|
30
|
-
/** Absolute trace paths under one `.llm4ts/` directory. */
|
|
31
|
-
readonly listTraces: (directory: string) => ReadonlyArray<string>;
|
|
32
|
-
}
|
|
33
|
-
export declare const nodeCostsDependencies: () => CostsDependencies;
|
|
34
|
-
declare const SkippedTrace_base: Schema.Class<SkippedTrace, Schema.Struct<{
|
|
35
|
-
readonly path: Schema.String;
|
|
36
|
-
readonly reason: Schema.String;
|
|
37
|
-
}>, {}>;
|
|
38
|
-
export declare class SkippedTrace extends SkippedTrace_base {
|
|
39
|
-
}
|
|
40
|
-
declare const CostsResult_base: Schema.Class<CostsResult, Schema.Struct<{
|
|
41
|
-
readonly report: typeof CostReport;
|
|
42
|
-
readonly traces: Schema.Int;
|
|
43
|
-
readonly skipped: Schema.$Array<typeof SkippedTrace>;
|
|
44
|
-
/** Runs whose trace was short or missing, completed from their cost ledger line. */
|
|
45
|
-
readonly ledgerRuns: Schema.withDecodingDefaultKey<Schema.withConstructorDefault<Schema.$Array<Schema.String>>, never>;
|
|
46
|
-
}>, {}>;
|
|
47
|
-
export declare class CostsResult extends CostsResult_base {
|
|
48
|
-
}
|
|
49
|
-
export declare const makeCostsProgram: (options: CostsOptions, dependencies?: CostsDependencies | undefined) => Effect.Effect<CostsResult, never, never>;
|
|
50
|
-
export declare const renderCostsResult: (result: CostsResult) => string;
|
|
51
|
-
export {};
|
|
52
|
-
//# sourceMappingURL=Costs.d.ts.map
|
package/dist/Costs.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Costs.d.ts","sourceRoot":"","sources":["../src/Costs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EACL,UAAU,EAMX,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAInE;;;;;;;;;GASG;AAEH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C,oGAAoG;AACpG,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OAAiD,CAAA;AAEhG,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,KAAG,aAAa,CAAC,MAAM,CAM/D,CAAA;AAER,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC,CAAA;CAClE;AAED,eAAO,MAAM,qBAAqB,QAAO,iBAGvC,CAAA;;;;;AAEF,qBAAa,YAAa,SAAQ,iBAGhC;CAAG;;;;;IAMH,oFAAoF;;;AAJtF,qBAAa,WAAY,SAAQ,gBAS/B;CAAG;AAEL,eAAO,MAAM,gBAAgB,mHAgD3B,CAAA;AAEF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,WAAW,KAAG,MAkBvD,CAAA"}
|
package/dist/Costs.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Schema from "effect/Schema";
|
|
5
|
-
import { CostLedgerFileName, loadCostLedger } from "@llm4ts/flow/CostLedger";
|
|
6
|
-
import { CostReport, buildCostReport, reconcileWithLedger, renderCostReport, usageSamplesFromTrace } from "@llm4ts/flow/CostReport";
|
|
7
|
-
import { describeFlowError } from "@llm4ts/flow/FlowError";
|
|
8
|
-
import { readTrace } from "@llm4ts/flow/Replay";
|
|
9
|
-
import { nodePlainFileStore } from "./NodePlainFileStore.js";
|
|
10
|
-
/**
|
|
11
|
-
* `llm4ts costs`: the budgeting view over every trace the runner wrote.
|
|
12
|
-
*
|
|
13
|
-
* Traces are the source for timing: a run can span hours and only the trace
|
|
14
|
-
* carries a timestamp per token report, which the hourly buckets need. The
|
|
15
|
-
* cost ledger is the source for each run's total: its line is the run's own
|
|
16
|
-
* summary, and a trace can be short (`CostReport.reconcileWithLedger`). One
|
|
17
|
-
* unreadable trace is reported and skipped rather than failing the whole
|
|
18
|
-
* report — the other runs still answer the question.
|
|
19
|
-
*/
|
|
20
|
-
export const TraceDirectoryName = ".llm4ts";
|
|
21
|
-
/** `trace-<timestamp>.jsonl` as the runner writes it, or a prefixed variant like `loop-trace-…`. */
|
|
22
|
-
export const isTraceFileName = (name) => /(?:^|-)trace-\d+\.jsonl$/u.test(name);
|
|
23
|
-
export const nodeListTraces = (directory) => existsSync(directory)
|
|
24
|
-
? readdirSync(directory)
|
|
25
|
-
.filter(isTraceFileName)
|
|
26
|
-
.sort()
|
|
27
|
-
.map((name) => join(directory, name))
|
|
28
|
-
: [];
|
|
29
|
-
export const nodeCostsDependencies = () => ({
|
|
30
|
-
files: nodePlainFileStore,
|
|
31
|
-
listTraces: nodeListTraces
|
|
32
|
-
});
|
|
33
|
-
export class SkippedTrace extends Schema.Class("SkippedTrace")({
|
|
34
|
-
path: Schema.String,
|
|
35
|
-
reason: Schema.String
|
|
36
|
-
}) {
|
|
37
|
-
}
|
|
38
|
-
export class CostsResult extends Schema.Class("CostsResult")({
|
|
39
|
-
report: CostReport,
|
|
40
|
-
traces: Schema.Int,
|
|
41
|
-
skipped: Schema.Array(SkippedTrace),
|
|
42
|
-
/** Runs whose trace was short or missing, completed from their cost ledger line. */
|
|
43
|
-
ledgerRuns: Schema.Array(Schema.String).pipe(Schema.withConstructorDefault(Effect.succeed([])), Schema.withDecodingDefaultKey(Effect.succeed([])))
|
|
44
|
-
}) {
|
|
45
|
-
}
|
|
46
|
-
export const makeCostsProgram = Effect.fn("@llm4ts/runner/Costs.make")(function* (options, dependencies = nodeCostsDependencies()) {
|
|
47
|
-
const paths = options.repos.flatMap((repo) => dependencies.listTraces(join(repo, TraceDirectoryName)));
|
|
48
|
-
const skipped = [];
|
|
49
|
-
const traced = [];
|
|
50
|
-
for (const path of paths) {
|
|
51
|
-
const lines = yield* readTrace(dependencies.files, path).pipe(Effect.catch((error) => Effect.sync(() => {
|
|
52
|
-
skipped.push(SkippedTrace.make({ path, reason: describeFlowError(error) }));
|
|
53
|
-
return [];
|
|
54
|
-
})));
|
|
55
|
-
traced.push(...usageSamplesFromTrace(lines));
|
|
56
|
-
}
|
|
57
|
-
// An unreadable ledger is no ledger: the traces still answer, uncorrected.
|
|
58
|
-
const records = [];
|
|
59
|
-
for (const repo of options.repos) {
|
|
60
|
-
const path = join(repo, TraceDirectoryName, CostLedgerFileName);
|
|
61
|
-
records.push(...(yield* loadCostLedger(dependencies.files, path).pipe(Effect.catch((error) => Effect.sync(() => {
|
|
62
|
-
skipped.push(SkippedTrace.make({ path, reason: describeFlowError(error) }));
|
|
63
|
-
return [];
|
|
64
|
-
})))));
|
|
65
|
-
}
|
|
66
|
-
const reconciled = reconcileWithLedger(traced, records);
|
|
67
|
-
const samples = reconciled.samples.filter((sample) => options.since === undefined || sample.at >= options.since);
|
|
68
|
-
return CostsResult.make({
|
|
69
|
-
report: buildCostReport(samples, {
|
|
70
|
-
...(options.timeZone === undefined ? {} : { timeZone: options.timeZone }),
|
|
71
|
-
...(options.runsPerDay === undefined ? {} : { runsPerDay: options.runsPerDay })
|
|
72
|
-
}),
|
|
73
|
-
traces: paths.length,
|
|
74
|
-
skipped,
|
|
75
|
-
ledgerRuns: reconciled.filledRuns
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
export const renderCostsResult = (result) => {
|
|
79
|
-
const skipped = result.skipped.length === 0
|
|
80
|
-
? []
|
|
81
|
-
: ["", ...result.skipped.map((entry) => `skipped ${entry.path}: ${entry.reason}`)];
|
|
82
|
-
const ledger = result.ledgerRuns.length === 0
|
|
83
|
-
? []
|
|
84
|
-
: [
|
|
85
|
-
`${result.ledgerRuns.length} run${result.ledgerRuns.length === 1 ? "" : "s"} completed from the cost ledger (trace short or missing, remainder at the run's start): ${result.ledgerRuns.join(", ")}`
|
|
86
|
-
];
|
|
87
|
-
return [
|
|
88
|
-
renderCostReport(result.report),
|
|
89
|
-
"",
|
|
90
|
-
`traces read: ${result.traces - result.skipped.length} of ${result.traces}`,
|
|
91
|
-
...ledger,
|
|
92
|
-
...skipped
|
|
93
|
-
].join("\n");
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=Costs.js.map
|
package/dist/Costs.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Costs.js","sourceRoot":"","sources":["../src/Costs.ts"],"names":[],"mappings":"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"}
|
package/dist/McpStdio.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Stream from "effect/Stream";
|
|
3
|
-
import { type FlowError } from "@llm4ts/flow/FlowError";
|
|
4
|
-
import { type McpTool } from "@llm4ts/flow/McpServer";
|
|
5
|
-
export declare const mcpStdioResponses: <R>(lines: Stream.Stream<string, FlowError, R>, tools: ReadonlyArray<McpTool>) => Stream.Stream<string, FlowError, R>;
|
|
6
|
-
export declare const runMcpStdio: (tools: ReadonlyArray<McpTool>, write?: (line: string) => void) => Effect.Effect<void, FlowError>;
|
|
7
|
-
//# sourceMappingURL=McpStdio.d.ts.map
|
package/dist/McpStdio.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"McpStdio.d.ts","sourceRoot":"","sources":["../src/McpStdio.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAEpE,eAAO,MAAM,iBAAiB,GAAI,CAAC,EACjC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAC1C,OAAO,aAAa,CAAC,OAAO,CAAC,KAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAIlC,CAAA;AAEH,eAAO,MAAM,WAAW,GACtB,OAAO,aAAa,CAAC,OAAO,CAAC,EAC7B,QAAO,CAAC,IAAI,EAAE,MAAM,KAAK,IAA0C,KAClE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAqB7B,CAAA"}
|
package/dist/McpStdio.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createInterface } from "node:readline";
|
|
2
|
-
import { stdin, stdout } from "node:process";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Stream from "effect/Stream";
|
|
5
|
-
import { ProcessError } from "@llm4ts/flow/FlowError";
|
|
6
|
-
import { handleMcpLine } from "@llm4ts/flow/McpServer";
|
|
7
|
-
export const mcpStdioResponses = (lines, tools) => lines.pipe(Stream.mapEffect((line) => handleMcpLine(line, tools)), Stream.filter((response) => response !== undefined));
|
|
8
|
-
export const runMcpStdio = (tools, write = (line) => stdout.write(`${line}\n`)) => Effect.acquireUseRelease(Effect.sync(() => createInterface({
|
|
9
|
-
input: stdin,
|
|
10
|
-
crlfDelay: Infinity,
|
|
11
|
-
terminal: false
|
|
12
|
-
})), (input) => {
|
|
13
|
-
const lines = Stream.fromAsyncIterable(input, (error) => ProcessError.make({
|
|
14
|
-
message: "MCP stdio input",
|
|
15
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
16
|
-
}));
|
|
17
|
-
return mcpStdioResponses(lines, tools).pipe(Stream.runForEach((line) => Effect.sync(() => write(line))));
|
|
18
|
-
}, (input) => Effect.sync(() => input.close()));
|
|
19
|
-
//# sourceMappingURL=McpStdio.js.map
|
package/dist/McpStdio.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"McpStdio.js","sourceRoot":"","sources":["../src/McpStdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,YAAY,EAAkB,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,aAAa,EAAgB,MAAM,wBAAwB,CAAA;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAA0C,EAC1C,KAA6B,EACQ,EAAE,CACvC,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EACtD,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAsB,EAAE,CAAC,QAAQ,KAAK,SAAS,CAAC,CACxE,CAAA;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,KAA6B,EAC7B,QAAgC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,EACnC,EAAE,CAClC,MAAM,CAAC,iBAAiB,CACtB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CACf,eAAe,CAAC;IACd,KAAK,EAAE,KAAK;IACZ,SAAS,EAAE,QAAQ;IACnB,QAAQ,EAAE,KAAK;CAChB,CAAC,CACH,EACD,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,KAAK,GAAG,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACtD,YAAY,CAAC,IAAI,CAAC;QAChB,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC/D,CAAC,CACH,CAAA;IACD,OAAO,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAC5D,CAAA;AACH,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAC5C,CAAA"}
|