@usine/orchestrator 0.2.1 → 0.4.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.
Files changed (222) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +174 -52
  3. package/dist/board/items.d.ts +22 -3
  4. package/dist/board/items.d.ts.map +1 -1
  5. package/dist/board/items.js +44 -4
  6. package/dist/board/items.js.map +1 -1
  7. package/dist/board/projection.d.ts +8 -1
  8. package/dist/board/projection.d.ts.map +1 -1
  9. package/dist/board/projection.js +63 -14
  10. package/dist/board/projection.js.map +1 -1
  11. package/dist/board/tasks.d.ts +15 -3
  12. package/dist/board/tasks.d.ts.map +1 -1
  13. package/dist/board/tasks.js +28 -9
  14. package/dist/board/tasks.js.map +1 -1
  15. package/dist/cloudflare.d.ts +32 -0
  16. package/dist/cloudflare.d.ts.map +1 -0
  17. package/dist/cloudflare.js +68 -0
  18. package/dist/cloudflare.js.map +1 -0
  19. package/dist/credentials.d.ts +5 -6
  20. package/dist/credentials.d.ts.map +1 -1
  21. package/dist/credentials.js +22 -15
  22. package/dist/credentials.js.map +1 -1
  23. package/dist/current-instance/changes.d.ts +87 -0
  24. package/dist/current-instance/changes.d.ts.map +1 -0
  25. package/dist/current-instance/changes.js +141 -0
  26. package/dist/current-instance/changes.js.map +1 -0
  27. package/dist/current-instance/current-instance.d.ts +89 -0
  28. package/dist/current-instance/current-instance.d.ts.map +1 -0
  29. package/dist/current-instance/current-instance.js +163 -0
  30. package/dist/current-instance/current-instance.js.map +1 -0
  31. package/dist/exe-dev.d.ts +6 -2
  32. package/dist/exe-dev.d.ts.map +1 -1
  33. package/dist/exe-dev.js +10 -9
  34. package/dist/exe-dev.js.map +1 -1
  35. package/dist/http-client.d.ts +8 -0
  36. package/dist/http-client.d.ts.map +1 -0
  37. package/dist/http-client.js +8 -0
  38. package/dist/http-client.js.map +1 -0
  39. package/dist/idle-triggers.d.ts +1 -1
  40. package/dist/idle-triggers.d.ts.map +1 -1
  41. package/dist/idle-triggers.js +1 -1
  42. package/dist/idle-triggers.js.map +1 -1
  43. package/dist/label-reconciler.d.ts +5 -2
  44. package/dist/label-reconciler.d.ts.map +1 -1
  45. package/dist/label-reconciler.js.map +1 -1
  46. package/dist/lease-order.d.ts +60 -0
  47. package/dist/lease-order.d.ts.map +1 -0
  48. package/dist/lease-order.js +76 -0
  49. package/dist/lease-order.js.map +1 -0
  50. package/dist/local.d.ts +4 -18
  51. package/dist/local.d.ts.map +1 -1
  52. package/dist/local.js +9 -45
  53. package/dist/local.js.map +1 -1
  54. package/dist/loop-matches.d.ts +28 -0
  55. package/dist/loop-matches.d.ts.map +1 -0
  56. package/dist/loop-matches.js +74 -0
  57. package/dist/loop-matches.js.map +1 -0
  58. package/dist/operator/attempt.d.ts +76 -10
  59. package/dist/operator/attempt.d.ts.map +1 -1
  60. package/dist/operator/attempt.js +69 -11
  61. package/dist/operator/attempt.js.map +1 -1
  62. package/dist/operator/board.d.ts +48 -16
  63. package/dist/operator/board.d.ts.map +1 -1
  64. package/dist/operator/board.js +48 -17
  65. package/dist/operator/board.js.map +1 -1
  66. package/dist/operator/configuration.d.ts +314 -0
  67. package/dist/operator/configuration.d.ts.map +1 -0
  68. package/dist/operator/configuration.js +490 -0
  69. package/dist/operator/configuration.js.map +1 -0
  70. package/dist/operator/desk.d.ts +206 -0
  71. package/dist/operator/desk.d.ts.map +1 -0
  72. package/dist/operator/desk.js +525 -0
  73. package/dist/operator/desk.js.map +1 -0
  74. package/dist/operator/github-changes.d.ts +88 -0
  75. package/dist/operator/github-changes.d.ts.map +1 -0
  76. package/dist/operator/github-changes.js +266 -0
  77. package/dist/operator/github-changes.js.map +1 -0
  78. package/dist/operator/http.d.ts +135 -105
  79. package/dist/operator/http.d.ts.map +1 -1
  80. package/dist/operator/http.js +155 -30
  81. package/dist/operator/http.js.map +1 -1
  82. package/dist/operator/machines.d.ts +71 -0
  83. package/dist/operator/machines.d.ts.map +1 -0
  84. package/dist/operator/machines.js +103 -0
  85. package/dist/operator/machines.js.map +1 -0
  86. package/dist/operator/need.d.ts +58 -11
  87. package/dist/operator/need.d.ts.map +1 -1
  88. package/dist/operator/need.js +61 -9
  89. package/dist/operator/need.js.map +1 -1
  90. package/dist/operator/operator.d.ts +135 -29
  91. package/dist/operator/operator.d.ts.map +1 -1
  92. package/dist/operator/operator.js +370 -63
  93. package/dist/operator/operator.js.map +1 -1
  94. package/dist/operator/overview.d.ts +7 -7
  95. package/dist/operator/overview.d.ts.map +1 -1
  96. package/dist/operator/overview.js +5 -5
  97. package/dist/operator/overview.js.map +1 -1
  98. package/dist/operator/projection.d.ts +56 -5
  99. package/dist/operator/projection.d.ts.map +1 -1
  100. package/dist/operator/projection.js +108 -9
  101. package/dist/operator/projection.js.map +1 -1
  102. package/dist/operator/run.d.ts +101 -6
  103. package/dist/operator/run.d.ts.map +1 -1
  104. package/dist/operator/run.js +100 -7
  105. package/dist/operator/run.js.map +1 -1
  106. package/dist/operator/statistics/cache.d.ts +7 -0
  107. package/dist/operator/statistics/cache.d.ts.map +1 -0
  108. package/dist/operator/statistics/cache.js +40 -0
  109. package/dist/operator/statistics/cache.js.map +1 -0
  110. package/dist/operator/statistics/runs.d.ts +36 -0
  111. package/dist/operator/statistics/runs.d.ts.map +1 -0
  112. package/dist/operator/statistics/runs.js +284 -0
  113. package/dist/operator/statistics/runs.js.map +1 -0
  114. package/dist/operator/statistics/statistics.d.ts +20 -0
  115. package/dist/operator/statistics/statistics.d.ts.map +1 -0
  116. package/dist/operator/statistics/statistics.js +138 -0
  117. package/dist/operator/statistics/statistics.js.map +1 -0
  118. package/dist/operator/statistics/tasks.d.ts +30 -0
  119. package/dist/operator/statistics/tasks.d.ts.map +1 -0
  120. package/dist/operator/statistics/tasks.js +244 -0
  121. package/dist/operator/statistics/tasks.js.map +1 -0
  122. package/dist/operator/statistics/view.d.ts +302 -0
  123. package/dist/operator/statistics/view.d.ts.map +1 -0
  124. package/dist/operator/statistics/view.js +243 -0
  125. package/dist/operator/statistics/view.js.map +1 -0
  126. package/dist/operator/statistics/window.d.ts +24 -0
  127. package/dist/operator/statistics/window.d.ts.map +1 -0
  128. package/dist/operator/statistics/window.js +47 -0
  129. package/dist/operator/statistics/window.js.map +1 -0
  130. package/dist/operator/task.d.ts +94 -0
  131. package/dist/operator/task.d.ts.map +1 -0
  132. package/dist/operator/task.js +204 -0
  133. package/dist/operator/task.js.map +1 -0
  134. package/dist/operator/transcript.d.ts +12 -12
  135. package/dist/operator/transcript.d.ts.map +1 -1
  136. package/dist/operator/transcript.js +11 -9
  137. package/dist/operator/transcript.js.map +1 -1
  138. package/dist/operator/usage.d.ts +103 -0
  139. package/dist/operator/usage.d.ts.map +1 -0
  140. package/dist/operator/usage.js +234 -0
  141. package/dist/operator/usage.js.map +1 -0
  142. package/dist/orchestrator.d.ts +8 -5
  143. package/dist/orchestrator.d.ts.map +1 -1
  144. package/dist/orchestrator.js +4 -2
  145. package/dist/orchestrator.js.map +1 -1
  146. package/dist/polling/closed-item-asks.d.ts +8 -0
  147. package/dist/polling/closed-item-asks.d.ts.map +1 -0
  148. package/dist/polling/closed-item-asks.js +28 -0
  149. package/dist/polling/closed-item-asks.js.map +1 -0
  150. package/dist/polling/cycle.d.ts +28 -10
  151. package/dist/polling/cycle.d.ts.map +1 -1
  152. package/dist/polling/cycle.js +20 -6
  153. package/dist/polling/cycle.js.map +1 -1
  154. package/dist/polling/evaluation-failures.d.ts +42 -0
  155. package/dist/polling/evaluation-failures.d.ts.map +1 -0
  156. package/dist/polling/evaluation-failures.js +103 -0
  157. package/dist/polling/evaluation-failures.js.map +1 -0
  158. package/dist/polling/hints.d.ts +2 -2
  159. package/dist/polling/hints.d.ts.map +1 -1
  160. package/dist/polling/hints.js +2 -2
  161. package/dist/polling/hints.js.map +1 -1
  162. package/dist/polling/loop-evaluation.d.ts +21 -11
  163. package/dist/polling/loop-evaluation.d.ts.map +1 -1
  164. package/dist/polling/loop-evaluation.js +70 -27
  165. package/dist/polling/loop-evaluation.js.map +1 -1
  166. package/dist/polling/open-issues.d.ts +23 -0
  167. package/dist/polling/open-issues.d.ts.map +1 -0
  168. package/dist/polling/open-issues.js +77 -0
  169. package/dist/polling/open-issues.js.map +1 -0
  170. package/dist/polling/open-pull-requests.d.ts +28 -0
  171. package/dist/polling/open-pull-requests.d.ts.map +1 -0
  172. package/dist/polling/open-pull-requests.js +131 -0
  173. package/dist/polling/open-pull-requests.js.map +1 -0
  174. package/dist/polling/polling.d.ts +20 -11
  175. package/dist/polling/polling.d.ts.map +1 -1
  176. package/dist/polling/polling.js +215 -52
  177. package/dist/polling/polling.js.map +1 -1
  178. package/dist/polling/repository-sync.d.ts +21 -14
  179. package/dist/polling/repository-sync.d.ts.map +1 -1
  180. package/dist/polling/repository-sync.js +35 -28
  181. package/dist/polling/repository-sync.js.map +1 -1
  182. package/dist/polling-triggers.d.ts +1 -1
  183. package/dist/polling-triggers.d.ts.map +1 -1
  184. package/dist/polling-triggers.js +1 -1
  185. package/dist/polling-triggers.js.map +1 -1
  186. package/dist/reloads.d.ts +14 -0
  187. package/dist/reloads.d.ts.map +1 -0
  188. package/dist/reloads.js +7 -0
  189. package/dist/reloads.js.map +1 -0
  190. package/dist/runtime.d.ts +24 -0
  191. package/dist/runtime.d.ts.map +1 -0
  192. package/dist/runtime.js +58 -0
  193. package/dist/runtime.js.map +1 -0
  194. package/dist/schedule-triggers.d.ts +14 -10
  195. package/dist/schedule-triggers.d.ts.map +1 -1
  196. package/dist/schedule-triggers.js +36 -31
  197. package/dist/schedule-triggers.js.map +1 -1
  198. package/dist/scheduler.d.ts +45 -5
  199. package/dist/scheduler.d.ts.map +1 -1
  200. package/dist/scheduler.js +587 -44
  201. package/dist/scheduler.js.map +1 -1
  202. package/dist/ssh.d.ts +103 -0
  203. package/dist/ssh.d.ts.map +1 -0
  204. package/dist/ssh.js +144 -0
  205. package/dist/ssh.js.map +1 -0
  206. package/dist/trigger-condition.d.ts +12 -0
  207. package/dist/trigger-condition.d.ts.map +1 -0
  208. package/dist/trigger-condition.js +88 -0
  209. package/dist/trigger-condition.js.map +1 -0
  210. package/dist/trigger-submission.d.ts +16 -13
  211. package/dist/trigger-submission.d.ts.map +1 -1
  212. package/dist/trigger-submission.js +19 -14
  213. package/dist/trigger-submission.js.map +1 -1
  214. package/dist/worker-engine.d.ts +13 -0
  215. package/dist/worker-engine.d.ts.map +1 -0
  216. package/dist/worker-engine.js +56 -0
  217. package/dist/worker-engine.js.map +1 -0
  218. package/dist/worker-status.d.ts +140 -0
  219. package/dist/worker-status.d.ts.map +1 -0
  220. package/dist/worker-status.js +76 -0
  221. package/dist/worker-status.js.map +1 -0
  222. package/package.json +47 -22
@@ -0,0 +1,284 @@
1
+ import { TokenCount, UsdAmount } from "@usine/core/agent/session";
2
+ import * as RunState from "@usine/core/run/state";
3
+ import { Array as EffectArray, DateTime, Option } from "effect";
4
+ import { AgentStatisticsView, AttemptCountView, BrainStatisticsView, CostSummaryView, DurationSummaryView, LoopStatisticsView, NeedsAttentionPeriodView, NeedsAttentionView, OutcomeCountsView, PoolTokensView, RunStatisticsView, ThroughputPeriodView, UsageSummaryView, WorkerQueueWaitView, WorkerUtilizationView, } from "./view.js";
5
+ import { epoch, median, periodStart, periodStarts, replacedBeforeStart, spanBucket, startOfUtcDay, sum, utcDay, windowStart, } from "./window.js";
6
+ const POOLS = ["apiKeys", "claudePlan", "chatgptPlan"];
7
+ /** Returns when a closed Run closed; the fallback only covers the nullable stored field. */
8
+ const closedAt = (summary) => Option.match(summary.closedAt, {
9
+ onSome: epoch,
10
+ onNone: () => {
11
+ const last = summary.attempts.at(-1);
12
+ return last === undefined
13
+ ? epoch(summary.run.openedAt)
14
+ : Option.match(last.endedAt, {
15
+ onSome: epoch,
16
+ onNone: () => epoch(last.startedAt),
17
+ });
18
+ },
19
+ });
20
+ /** Returns the median of `durations`, or null if there are none. */
21
+ export const durationSummary = (durations) => Option.match(median(durations), {
22
+ onNone: () => null,
23
+ onSome: (middle) => new DurationSummaryView({ count: durations.length, medianMillis: Math.round(middle) }),
24
+ });
25
+ const runOutcome = (summary) => {
26
+ switch (summary.run.state._tag) {
27
+ case "Succeeded":
28
+ return "succeeded";
29
+ case "Failed":
30
+ return "failed";
31
+ case "Canceled":
32
+ return "canceled";
33
+ default:
34
+ return null;
35
+ }
36
+ };
37
+ const attemptOutcome = (attempt) => Option.match(attempt.outcome, {
38
+ onNone: () => null,
39
+ onSome: ({ _tag }) => _tag === "Succeeded" ? "succeeded" : _tag === "Failed" ? "failed" : "canceled",
40
+ });
41
+ const outcomeCounts = (outcomes) => new OutcomeCountsView({
42
+ succeeded: outcomes.filter((outcome) => outcome === "succeeded").length,
43
+ failed: outcomes.filter((outcome) => outcome === "failed").length,
44
+ canceled: outcomes.filter((outcome) => outcome === "canceled").length,
45
+ });
46
+ /** Returns the Attempt's wall time, or `None` while it runs or if its end wasn't recorded. */
47
+ export const attemptMillis = (attempt) => Option.isNone(attempt.outcome)
48
+ ? Option.none()
49
+ : Option.map(attempt.endedAt, (endedAt) => Math.max(0, epoch(endedAt) - epoch(attempt.startedAt)));
50
+ const runMillis = (summary) => Math.max(0, closedAt(summary) - epoch(summary.run.openedAt));
51
+ /**
52
+ * Sums the tokens and prices of `units`, each the sessions of one Run or Attempt. A unit is priced
53
+ * if it has a session and each of its sessions has a price.
54
+ */
55
+ const usageSummary = (units) => {
56
+ const sessions = units.flat();
57
+ const tokens = sum(sessions.map((session) => session.tokens));
58
+ const priced = units.filter((unit) => unit.length > 0 && unit.every(({ cost }) => cost !== null));
59
+ const usd = sum(priced.flatMap((unit) => unit.flatMap(({ cost }) => (cost === null ? [] : [cost.usd]))));
60
+ return new UsageSummaryView({
61
+ measured: units.length,
62
+ tokens: TokenCount.make(tokens),
63
+ meanTokens: units.length === 0 ? null : TokenCount.make(Math.round(tokens / units.length)),
64
+ pools: POOLS.flatMap((pool) => {
65
+ const members = sessions.filter((session) => session.pool === pool);
66
+ return members.length === 0
67
+ ? []
68
+ : [
69
+ new PoolTokensView({
70
+ pool,
71
+ tokens: TokenCount.make(sum(members.map((session) => session.tokens))),
72
+ }),
73
+ ];
74
+ }),
75
+ cost: priced.length === 0
76
+ ? null
77
+ : new CostSummaryView({
78
+ usd: UsdAmount.make(usd),
79
+ meanUsd: UsdAmount.make(usd / priced.length),
80
+ estimate: priced.some((unit) => unit.some(({ cost }) => cost?.estimate === true)),
81
+ priced: priced.length,
82
+ }),
83
+ });
84
+ };
85
+ const runSessions = (summary, usage) => usage.get(summary.run.id)?.sessions ?? [];
86
+ /** Returns the closed Runs grouped by `key`, the largest group first, then by key. */
87
+ const groupRuns = (runs, key) => Object.values(EffectArray.groupBy(runs, (summary) => key(summary)))
88
+ .map((members) => [key(members[0]), members])
89
+ .sort(([leftName, left], [rightName, right]) => right.length - left.length || leftName.localeCompare(rightName));
90
+ const runGroup = (runs, usage) => ({
91
+ outcomes: outcomeCounts(runs.map(runOutcome)),
92
+ time: durationSummary(runs.map(runMillis)),
93
+ usage: usageSummary(runs
94
+ .filter(({ attempts }) => attempts.length > 0)
95
+ .map((summary) => runSessions(summary, usage))),
96
+ });
97
+ const brainGroups = (runs, usage) => {
98
+ const ended = runs.flatMap((summary) => summary.attempts
99
+ .filter((attempt) => Option.isSome(attempt.outcome))
100
+ .map((attempt) => ({
101
+ attempt,
102
+ sessions: runSessions(summary, usage).filter(({ attemptId }) => attemptId === attempt.id),
103
+ })));
104
+ const groups = EffectArray.groupBy(ended, ({ attempt: { brain } }) => JSON.stringify([brain.harness, brain.model, brain.effort]));
105
+ return Object.values(groups)
106
+ .map((members) => new BrainStatisticsView({
107
+ brain: members[0].attempt.brain,
108
+ outcomes: outcomeCounts(members.map(({ attempt }) => attemptOutcome(attempt))),
109
+ time: durationSummary(members.flatMap(({ attempt }) => Option.toArray(attemptMillis(attempt)))),
110
+ usage: usageSummary(members.map(({ sessions }) => sessions)),
111
+ }))
112
+ .sort((left, right) => right.outcomes.succeeded +
113
+ right.outcomes.failed +
114
+ right.outcomes.canceled -
115
+ (left.outcomes.succeeded + left.outcomes.failed + left.outcomes.canceled) ||
116
+ left.brain.harness.localeCompare(right.brain.harness) ||
117
+ left.brain.model.localeCompare(right.brain.model) ||
118
+ left.brain.effort.localeCompare(right.brain.effort));
119
+ };
120
+ /** Counts `instants` per period of `starts`; instants outside every period are left out. */
121
+ const perPeriod = (bucket, starts, instants) => {
122
+ const counts = new Map(starts.map((start) => [start, 0]));
123
+ for (const instant of instants) {
124
+ const start = periodStart(bucket, instant);
125
+ const count = counts.get(start);
126
+ if (count !== undefined)
127
+ counts.set(start, count + 1);
128
+ }
129
+ return counts;
130
+ };
131
+ const firstAttempt = (summary) => summary.attempts.reduce((first, attempt) => (first === undefined || attempt.number < first.number ? attempt : first), undefined);
132
+ const automaticRestart = (attempt) => attempt !== undefined &&
133
+ Option.exists(attempt.start, ({ _tag }) => _tag === "InfraRetry" || _tag === "AfterRestart");
134
+ /** Whether the operator started the Attempt by retrying the failed Run, with or without an edit. */
135
+ export const operatorRetry = (attempt) => attempt !== undefined &&
136
+ Option.exists(attempt.start, ({ _tag }) => _tag === "OperatorRetry" || _tag === "EditAndRetry");
137
+ /**
138
+ * Returns the approvals asked for and the failures raised in the window, from the Runs' openings,
139
+ * approvals, and Attempts.
140
+ */
141
+ const needsAttention = (runs, from, bucket, starts) => {
142
+ const approvals = [];
143
+ const approvalWaits = [];
144
+ const failures = [];
145
+ const retryWaits = [];
146
+ const resolutionWaits = [];
147
+ for (const summary of runs) {
148
+ const opened = epoch(summary.run.openedAt);
149
+ if (opened >= from) {
150
+ Option.match(summary.approval, {
151
+ onNone: () => {
152
+ if (summary.run.state._tag === "Waiting")
153
+ approvals.push(opened);
154
+ },
155
+ onSome: ({ approvedAt }) => {
156
+ approvals.push(opened);
157
+ approvalWaits.push(Math.max(0, epoch(approvedAt) - opened));
158
+ },
159
+ });
160
+ }
161
+ const ordered = [...summary.attempts].sort((left, right) => left.number - right.number);
162
+ ordered.forEach((attempt, index) => {
163
+ const failed = Option.exists(attempt.outcome, ({ _tag }) => _tag === "Failed");
164
+ if (!failed || Option.isNone(attempt.endedAt))
165
+ return;
166
+ const ended = epoch(attempt.endedAt.value);
167
+ const next = ordered[index + 1];
168
+ if (ended < from || automaticRestart(next))
169
+ return;
170
+ failures.push(ended);
171
+ if (Option.isSome(attempt.failureResolution)) {
172
+ resolutionWaits.push(Math.max(0, epoch(attempt.failureResolution.value.resolvedAt) - ended));
173
+ }
174
+ else if (operatorRetry(next)) {
175
+ retryWaits.push(Math.max(0, epoch(next.startedAt) - ended));
176
+ }
177
+ });
178
+ }
179
+ const approvalCounts = perPeriod(bucket, starts, approvals);
180
+ const failureCounts = perPeriod(bucket, starts, failures);
181
+ return new NeedsAttentionView({
182
+ approvals: approvals.length,
183
+ failures: failures.length,
184
+ periods: starts.map((start) => new NeedsAttentionPeriodView({
185
+ start: utcDay(start),
186
+ approvals: approvalCounts.get(start) ?? 0,
187
+ failures: failureCounts.get(start) ?? 0,
188
+ })),
189
+ approvalWait: durationSummary(approvalWaits),
190
+ retryWait: durationSummary(retryWaits),
191
+ resolutionWait: durationSummary(resolutionWaits),
192
+ failureWait: durationSummary([...retryWaits, ...resolutionWaits]),
193
+ });
194
+ };
195
+ /**
196
+ * Reduces the stored facts to the Run statistics of `window`. Run measures cover the Runs that
197
+ * closed in the window; queue wait, Worker utilization, and Needs attention also cover the open
198
+ * Runs.
199
+ */
200
+ export const runStatisticsView = ({ window, now, runs: stored, usage, workers, }) => {
201
+ const to = epoch(now);
202
+ const runs = stored.filter((summary) => !replacedBeforeStart(summary));
203
+ const from = Option.match(windowStart(window, now), {
204
+ onSome: epoch,
205
+ onNone: () => startOfUtcDay(runs.reduce((earliest, { run, attempts }) => attempts.reduce((first, { startedAt }) => Math.min(first, epoch(startedAt)), Math.min(earliest, epoch(run.openedAt))), to)),
206
+ });
207
+ const closed = runs.filter(({ run }) => !RunState.isOpen(run.state));
208
+ const bucket = spanBucket(from, to);
209
+ const starts = periodStarts(bucket, from, to);
210
+ const throughputCounts = new Map(starts.map((start) => [start, { succeeded: 0, failed: 0, canceled: 0 }]));
211
+ for (const summary of closed) {
212
+ const outcome = runOutcome(summary);
213
+ const period = throughputCounts.get(periodStart(bucket, closedAt(summary)));
214
+ if (outcome !== null && period !== undefined)
215
+ period[outcome] += 1;
216
+ }
217
+ const ended = closed.flatMap(({ attempts }) => attempts.filter(({ outcome }) => Option.isSome(outcome)));
218
+ const waits = new Map();
219
+ for (const summary of runs) {
220
+ const first = firstAttempt(summary);
221
+ if (first === undefined || epoch(first.startedAt) < from)
222
+ continue;
223
+ const ready = Math.max(epoch(summary.run.openedAt), Option.match(summary.approval, {
224
+ onNone: () => 0,
225
+ onSome: ({ approvedAt }) => epoch(approvedAt),
226
+ }));
227
+ const worker = waits.get(first.worker) ?? [];
228
+ worker.push(Math.max(0, epoch(first.startedAt) - ready));
229
+ waits.set(first.worker, worker);
230
+ }
231
+ const attemptCounts = closed.flatMap(({ attempts }) => attempts.length === 0 ? [] : [attempts.length]);
232
+ const mostAttempts = attemptCounts.reduce((most, count) => Math.max(most, count), 0);
233
+ const windowMillis = Math.max(0, to - from);
234
+ const occupied = (worker) => sum(runs.flatMap(({ attempts }) => attempts
235
+ .filter((attempt) => attempt.worker === worker)
236
+ .flatMap((attempt) => {
237
+ const end = Option.isNone(attempt.outcome)
238
+ ? Option.some(to)
239
+ : Option.map(attempt.endedAt, epoch);
240
+ return Option.toArray(Option.map(end, (until) => Math.max(0, Math.min(until, to) - Math.max(epoch(attempt.startedAt), from))));
241
+ })));
242
+ return new RunStatisticsView({
243
+ window,
244
+ from: new Date(from).toISOString(),
245
+ to: DateTime.formatIso(now),
246
+ bucket,
247
+ runs: outcomeCounts(closed.map(runOutcome)),
248
+ runTime: durationSummary(closed.map(runMillis)),
249
+ attemptTime: durationSummary(ended.flatMap((attempt) => Option.toArray(attemptMillis(attempt)))),
250
+ unmeasuredAttempts: ended.filter(({ endedAt }) => Option.isNone(endedAt)).length,
251
+ throughput: starts.map((start) => new ThroughputPeriodView({
252
+ start: utcDay(start),
253
+ ...(throughputCounts.get(start) ?? { succeeded: 0, failed: 0, canceled: 0 }),
254
+ })),
255
+ loops: groupRuns(closed, ({ run }) => run.loop).map(([loop, members]) => new LoopStatisticsView({ loop, ...runGroup(members, usage) })),
256
+ agents: groupRuns(closed, ({ agent }) => agent.name).map(([agent, members]) => new AgentStatisticsView({ agent, ...runGroup(members, usage) })),
257
+ brains: brainGroups(closed, usage),
258
+ queueWait: [...waits.entries()]
259
+ .sort(([left], [right]) => left.localeCompare(right))
260
+ .flatMap(([worker, durations]) => {
261
+ const wait = durationSummary(durations);
262
+ return wait === null ? [] : [new WorkerQueueWaitView({ worker, wait })];
263
+ }),
264
+ attemptsPerRun: Array.from({ length: mostAttempts }, (_, index) => new AttemptCountView({
265
+ attempts: index + 1,
266
+ runs: attemptCounts.filter((count) => count === index + 1).length,
267
+ })),
268
+ utilization: workers.flatMap(({ name, slots }) => {
269
+ if (slots < 1)
270
+ return [];
271
+ const held = occupied(name);
272
+ return [
273
+ new WorkerUtilizationView({
274
+ worker: name,
275
+ slots,
276
+ occupiedMillis: Math.round(held),
277
+ share: windowMillis === 0 ? 0 : Math.min(1, held / (slots * windowMillis)),
278
+ }),
279
+ ];
280
+ }),
281
+ needsAttention: needsAttention(runs, from, bucket, starts),
282
+ });
283
+ };
284
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../../src/operator/statistics/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { LoadedInstance } from "@usine/config/instance";
2
+ import { CycleBudgets } from "@usine/engine/cycle-budget";
3
+ import type { RunStoreError } from "@usine/engine/engine";
4
+ import { ItemProjectionReader } from "@usine/engine/item-projection";
5
+ import { RunReader } from "@usine/engine/run-reader";
6
+ import { Context, Effect, Layer } from "effect";
7
+ import { RunUsageReader } from "../usage.ts";
8
+ import type { RunStatisticsView, StatisticsView, StatisticsWindow } from "./view.ts";
9
+ declare const OperatorStatistics_base: Context.ServiceClass<OperatorStatistics, "@usine/orchestrator/OperatorStatistics", {
10
+ /** Returns the tasks done in `window`, as described in `StatisticsView`. */
11
+ readonly statistics: (instance: LoadedInstance, window: StatisticsWindow) => Effect.Effect<StatisticsView, RunStoreError>;
12
+ /** Returns the Runs of `window`, as described in `RunStatisticsView`. */
13
+ readonly runStatistics: (instance: LoadedInstance, window: StatisticsWindow) => Effect.Effect<RunStatisticsView, RunStoreError>;
14
+ }>;
15
+ /** Computes the operator's statistics from the stored Items, Runs, usage, and cycle budgets. */
16
+ export declare class OperatorStatistics extends OperatorStatistics_base {
17
+ static readonly layer: Layer.Layer<OperatorStatistics, never, CycleBudgets | ItemProjectionReader | RunReader | RunUsageReader>;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=statistics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../../../src/operator/statistics/statistics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAmB,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAY,MAAM,EAAE,KAAK,EAA0B,MAAM,QAAQ,CAAC;AAIlF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;;IAkLjF,4EAA4E;yBACvD,CACnB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACjD,yEAAyE;4BACjD,CACtB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;;AAbxD,gGAAgG;AAChG,qBAAa,kBAAmB,SAAQ,uBAcK;IAC3C,MAAM,CAAC,QAAQ,CAAC,KAAK,2GAAoD;CAC1E"}
@@ -0,0 +1,138 @@
1
+ import * as RunState from "@usine/core/run/state";
2
+ import { CycleBudgets } from "@usine/engine/cycle-budget";
3
+ import { ItemProjectionReader } from "@usine/engine/item-projection";
4
+ import { RunReader } from "@usine/engine/run-reader";
5
+ import { Context, DateTime, Effect, Layer, Option, Result, Schema } from "effect";
6
+ import { projectedItem } from "../../board/items.js";
7
+ import { taskCards } from "../../board/tasks.js";
8
+ import { runView } from "../projection.js";
9
+ import { RunUsageReader } from "../usage.js";
10
+ import { cacheStatistics } from "./cache.js";
11
+ import { runStatisticsView } from "./runs.js";
12
+ import { taskStatisticsView } from "./tasks.js";
13
+ import { sum, windowStart } from "./window.js";
14
+ /** The number of newest Items per repository searched for merged pull requests, as on a Board. */
15
+ const STATISTICS_ITEMS = 500;
16
+ const decodeMergedAt = Schema.decodeUnknownOption(Schema.Struct({ mergedAt: Schema.NullOr(Schema.DateTimeUtcFromString) }));
17
+ const makeStatistics = Effect.gen(function* () {
18
+ const reader = yield* RunReader;
19
+ const itemReader = yield* ItemProjectionReader;
20
+ const usageReader = yield* RunUsageReader;
21
+ const budgets = yield* CycleBudgets;
22
+ const usageOf = (runs) => Effect.forEach(runs, (summary) => usageReader.read(summary).pipe(Effect.map((read) => [summary.run.id, read])), { concurrency: 4 }).pipe(Effect.map((entries) => new Map(entries)));
23
+ /**
24
+ * Returns each task of `repository` among its newest Items whose pull request merged at or after
25
+ * `since`, with every Run on its Items and the resets of their cycle budgets.
26
+ */
27
+ const mergedTasks = Effect.fn("Operator.statistics.mergedTasks")(function* (repository, since) {
28
+ yield* Effect.annotateCurrentSpan({ repository });
29
+ const stored = yield* itemReader.list(repository, { limit: STATISTICS_ITEMS });
30
+ const items = [];
31
+ const mergedAt = new Map();
32
+ for (const item of stored) {
33
+ const projected = yield* Effect.result(projectedItem(item));
34
+ // The Board reports an Item it can't project in Needs attention.
35
+ if (Result.isFailure(projected))
36
+ continue;
37
+ items.push(projected.success);
38
+ if (projected.success.state !== "pr-merged")
39
+ continue;
40
+ const merged = Option.flatMap(decodeMergedAt(item.payload), ({ mergedAt }) => Option.fromNullOr(mergedAt));
41
+ if (Option.isSome(merged) &&
42
+ Option.match(since, {
43
+ onNone: () => true,
44
+ onSome: (from) => DateTime.isGreaterThanOrEqualTo(merged.value, from),
45
+ }))
46
+ mergedAt.set(item.itemKey, merged.value);
47
+ }
48
+ if (mergedAt.size === 0) {
49
+ yield* Effect.logDebug("No pull request merged in the statistics window", {
50
+ repository,
51
+ items: items.length,
52
+ });
53
+ return [];
54
+ }
55
+ const history = yield* reader.forItems(items.map(({ itemKey }) => itemKey));
56
+ const summaries = new Map(history.map((summary) => [summary.run.id, summary]));
57
+ const cards = taskCards(repository, items, history.map((summary) => runView(summary, new Set(), new Map())), [], new Map(), new Map());
58
+ const found = cards.flatMap(({ view }) => {
59
+ const merges = view.items.flatMap(({ itemKey }) => {
60
+ const at = mergedAt.get(itemKey);
61
+ return at === undefined ? [] : [at];
62
+ });
63
+ const runs = view.runs.flatMap(({ id }) => summaries.get(id) ?? []);
64
+ const [first] = merges;
65
+ return first === undefined || runs.length === 0
66
+ ? []
67
+ : [
68
+ {
69
+ view,
70
+ runs,
71
+ mergedAt: merges.reduce((latest, at) => (DateTime.isGreaterThan(at, latest) ? at : latest), first),
72
+ },
73
+ ];
74
+ });
75
+ const tasks = yield* Effect.forEach(found, ({ view, runs, mergedAt }) => Effect.forEach(view.items, ({ itemKey }) => budgets.generation(itemKey)).pipe(Effect.map((generations) => ({
76
+ repository,
77
+ number: view.items[0]?.number ?? view.number,
78
+ mergedAt,
79
+ runs,
80
+ budgetResets: sum(generations),
81
+ }))), { concurrency: 4 });
82
+ yield* Effect.logDebug("Read the merged tasks for the statistics", {
83
+ repository,
84
+ mergedPullRequests: mergedAt.size,
85
+ tasks: tasks.length,
86
+ runs: history.length,
87
+ });
88
+ return tasks;
89
+ });
90
+ const statistics = Effect.fn("Operator.statistics")(function* (instance, window) {
91
+ yield* Effect.annotateCurrentSpan({ window });
92
+ const now = yield* DateTime.now;
93
+ const tasks = (yield* Effect.forEach(instance.config.repos, ({ name }) => mergedTasks(name, windowStart(window, now)), { concurrency: 4 })).flat();
94
+ // The reader keeps ended Attempts' reports, so a closed Run's usage is read once per process.
95
+ const usage = yield* usageOf(tasks.flatMap(({ runs }) => runs));
96
+ const view = taskStatisticsView({ window, now, tasks, usage });
97
+ yield* Effect.logDebug("Computed the task statistics", {
98
+ window,
99
+ from: view.from,
100
+ tasks: view.tasks.length,
101
+ timedTasks: view.time?.tasks ?? 0,
102
+ meteredTasks: view.tokens?.tasks ?? 0,
103
+ });
104
+ return view;
105
+ });
106
+ const runStatistics = Effect.fn("Operator.runStatistics")(function* (instance, window) {
107
+ yield* Effect.annotateCurrentSpan({ window });
108
+ const now = yield* DateTime.now;
109
+ const [closed, listed] = yield* Effect.all([reader.closedSince(windowStart(window, now)), reader.list({ closedLimit: 0 })], { concurrency: "unbounded" });
110
+ const open = listed.filter(({ run }) => RunState.isOpen(run.state));
111
+ const view = runStatisticsView({
112
+ window,
113
+ now,
114
+ runs: [...closed, ...open],
115
+ usage: yield* usageOf(closed),
116
+ workers: instance.config.workers.map(({ name, maxConcurrentAttempts }) => ({
117
+ name,
118
+ slots: maxConcurrentAttempts,
119
+ })),
120
+ });
121
+ yield* Effect.logDebug("Computed the run statistics", {
122
+ window,
123
+ from: view.from,
124
+ closedRuns: closed.length,
125
+ openRuns: open.length,
126
+ });
127
+ return view;
128
+ });
129
+ return {
130
+ statistics: cacheStatistics(reader.revision, statistics),
131
+ runStatistics: cacheStatistics(reader.revision, runStatistics),
132
+ };
133
+ });
134
+ /** Computes the operator's statistics from the stored Items, Runs, usage, and cycle budgets. */
135
+ export class OperatorStatistics extends Context.Service()("@usine/orchestrator/OperatorStatistics") {
136
+ static layer = Layer.effect(OperatorStatistics, makeStatistics);
137
+ }
138
+ //# sourceMappingURL=statistics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistics.js","sourceRoot":"","sources":["../../../src/operator/statistics/statistics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAmB,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClF,OAAO,EAAsB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAmB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,kGAAkG;AAClG,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAC/C,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC,CACzE,CAAC;AAEF,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,oBAAoB,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC;IAEpC,MAAM,OAAO,GAAG,CAAC,IAA+B,EAAE,EAAE,CAClD,MAAM,CAAC,OAAO,CACZ,IAAI,EACJ,CAAC,OAAO,EAAE,EAAE,CACV,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAU,CAAC,CAAC,EACvF,EAAE,WAAW,EAAE,CAAC,EAAE,CACnB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAEpD;;;OAGG;IACH,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,iCAAiC,CAAC,CAAC,QAAQ,CAAC,EACxE,UAA0B,EAC1B,KAAkC;QAElC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAyB,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,iEAAiE;YACjE,IAAI,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC;gBAAE,SAAS;YAC1C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,KAAK,WAAW;gBAAE,SAAS;YACtD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC3E,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC5B,CAAC;YACF,IACE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;gBACrB,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;oBAClB,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI;oBAClB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC;iBACtE,CAAC;gBAEF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,iDAAiD,EAAE;gBACxE,UAAU;gBACV,KAAK,EAAE,KAAK,CAAC,MAAM;aACpB,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,SAAS,CACrB,UAAU,EACV,KAAK,EACL,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,EAChE,EAAE,EACF,IAAI,GAAG,EAAE,EACT,IAAI,GAAG,EAAE,CACV,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;gBAChD,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACjC,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;YACvB,OAAO,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAC7C,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE;wBACE,IAAI;wBACJ,IAAI;wBACJ,QAAQ,EAAE,MAAM,CAAC,MAAM,CACrB,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAClE,KAAK,CACN;qBACF;iBACF,CAAC;QACR,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACjC,KAAK,EACL,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC3B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAC3E,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAc,EAAE,CAAC,CAAC;YACvC,UAAU;YACV,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM;YAC5C,QAAQ;YACR,IAAI;YACJ,YAAY,EAAE,GAAG,CAAC,WAAW,CAAC;SAC/B,CAAC,CAAC,CACJ,EACH,EAAE,WAAW,EAAE,CAAC,EAAE,CACnB,CAAC;QACF,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,0CAA0C,EAAE;YACjE,UAAU;YACV,kBAAkB,EAAE,QAAQ,CAAC,IAAI;YACjC,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,IAAI,EAAE,OAAO,CAAC,MAAM;SACrB,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAC3D,QAAwB,EACxB,MAAwB;QAExB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAClC,QAAQ,CAAC,MAAM,CAAC,KAAK,EACrB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EACzD,EAAE,WAAW,EAAE,CAAC,EAAE,CACnB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,8FAA8F;QAC9F,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,8BAA8B,EAAE;YACrD,MAAM;YACN,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACxB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC;YACjC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC;SACtC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EACjE,QAAwB,EACxB,MAAwB;QAExB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CACxC,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAU,EACxF,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,iBAAiB,CAAC;YAC7B,MAAM;YACN,GAAG;YACH,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;YAC1B,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzE,IAAI;gBACJ,KAAK,EAAE,qBAAqB;aAC7B,CAAC,CAAC;SACJ,CAAC,CAAC;QACH,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAA6B,EAAE;YACpD,MAAM;YACN,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,MAAM,CAAC,MAAM;YACzB,QAAQ,EAAE,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;QACxD,aAAa,EAAE,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;KAC/D,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,gGAAgG;AAChG,MAAM,OAAO,kBAAmB,SAAQ,OAAO,CAAC,OAAO,EAcpD,CAAC,wCAAwC,CAAC;IAC3C,MAAM,CAAU,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;CAC1E"}
@@ -0,0 +1,30 @@
1
+ import type { ItemNumber } from "@usine/core/item";
2
+ import type { RepositoryName } from "@usine/core/repository";
3
+ import type { RunId } from "@usine/core/run";
4
+ import type { RunSummary } from "@usine/engine/run-reader";
5
+ import { DateTime } from "effect";
6
+ import type { RunUsageView } from "../usage.ts";
7
+ import { StatisticsView, type StatisticsWindow } from "./view.ts";
8
+ /** A task whose pull request merged, with every Run on its Items. */
9
+ export interface MergedTask {
10
+ readonly repository: RepositoryName;
11
+ /** The task's first issue, or its first pull request if it has no issue. */
12
+ readonly number: ItemNumber;
13
+ /** The newest merge among the task's pull requests. */
14
+ readonly mergedAt: DateTime.Utc;
15
+ readonly runs: ReadonlyArray<RunSummary>;
16
+ /** The operator resets of the cycle budgets of the task's Items. */
17
+ readonly budgetResets: number;
18
+ }
19
+ /** The stored facts that `taskStatisticsView` reduces. */
20
+ export interface TaskStatisticsFacts {
21
+ readonly window: StatisticsWindow;
22
+ readonly now: DateTime.Utc;
23
+ /** The tasks merged in the window; the reduction leaves out those merged outside it. */
24
+ readonly tasks: ReadonlyArray<MergedTask>;
25
+ /** The usage of each Run of `tasks`. */
26
+ readonly usage: ReadonlyMap<RunId, RunUsageView>;
27
+ }
28
+ /** Reduces the merged tasks to the statistics of `window`. */
29
+ export declare const taskStatisticsView: ({ window, now, tasks: merged, usage, }: TaskStatisticsFacts) => StatisticsView;
30
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/operator/statistics/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAwB,QAAQ,EAAU,MAAM,QAAQ,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAGL,cAAc,EACd,KAAK,gBAAgB,EAOtB,MAAM,WAAW,CAAC;AAenB,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1C,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;CAClD;AAySD,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,2CAK5B,mBAAmB,KAAG,cAoDxB,CAAC"}