@kubitnodes/stellaris 0.4.1 → 0.4.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/cli/index.js +603 -18
- package/dist/server/index.js +744 -60
- package/package.json +1 -1
- package/web/dist/assets/BackLink-DNHWkHmh.js +1 -0
- package/web/dist/assets/{Button-DxGzriWQ.js → Button-B6EN7Lh7.js} +1 -1
- package/web/dist/assets/ChannelForms-BrcWrkej.js +1 -0
- package/web/dist/assets/{ChannelView-DvtoxLi5.js → ChannelView-D7bT7d9q.js} +2 -2
- package/web/dist/assets/CitizenView-D6d1KnS6.js +2 -0
- package/web/dist/assets/{CitizensView-BOZHABbN.js → CitizensView-C55zOiYE.js} +1 -1
- package/web/dist/assets/{CliIcon-D3GddnP4.js → CliIcon-BRq1tnhu.js} +1 -1
- package/web/dist/assets/CronsView-BTGiqn10.js +1 -0
- package/web/dist/assets/{FileTree-DSFN4sd8.js → FileTree-BDhtTIzT.js} +1 -1
- package/web/dist/assets/{FileView-DyUYLXRC.js → FileView-BkZPGEbO.js} +2 -2
- package/web/dist/assets/{KnowledgeView-CMdXaTvS.js → KnowledgeView-BiTS-lyE.js} +1 -1
- package/web/dist/assets/{Markdown-BSeWHBBA.js → Markdown-DYk-gVwe.js} +5 -5
- package/web/dist/assets/{MessageItem-qIxS96uJ.js → MessageItem-WBBIzv48.js} +1 -1
- package/web/dist/assets/MetricsView-CYmnG6aQ.js +1 -0
- package/web/dist/assets/NeedsYouView-B-5olhZL.js +1 -0
- package/web/dist/assets/Overview-BO_lR1cu.js +1 -0
- package/web/dist/assets/{Pane-pZUzNQIW.js → Pane-DFJdAhv9.js} +1 -1
- package/web/dist/assets/{Picker-CDf6os_x.js → Picker-CAEREZF9.js} +1 -1
- package/web/dist/assets/ProjectView-LU59V2vh.js +1 -0
- package/web/dist/assets/ProposalView-DHemTlkc.js +1 -0
- package/web/dist/assets/{ProposalsView-DBGpcAPO.js → ProposalsView-DBIOJAul.js} +1 -1
- package/web/dist/assets/{Quota-Brd4ddB4.js → Quota-D6_yyawu.js} +1 -1
- package/web/dist/assets/{RunnersView-45OXtalD.js → RunnersView-BNKgYuNw.js} +1 -1
- package/web/dist/assets/{SkillFileList-BUImALv9.js → SkillFileList-Ntyv8noL.js} +1 -1
- package/web/dist/assets/SkillView-Dez1fvqU.js +1 -0
- package/web/dist/assets/SocietyView-CbmbQXHi.js +1 -0
- package/web/dist/assets/{StickyList-D_ED_-LW.js → StickyList-Q0KEWBUl.js} +1 -1
- package/web/dist/assets/{SubjectThread-B5zvoRSd.js → SubjectThread-1PnxxtZc.js} +1 -1
- package/web/dist/assets/{TaskView-B5_QTI3p.js → TaskView-CcIlNHBh.js} +2 -2
- package/web/dist/assets/TasksView-BkTU43PD.js +1 -0
- package/web/dist/assets/{ThreadForms-CbFClyd0.js → ThreadForms-BlOEvY5E.js} +1 -1
- package/web/dist/assets/ThreadItem-D5N_Fw1K.js +1 -0
- package/web/dist/assets/{ThreadView-CHFs0zaS.js → ThreadView-BaYV77mQ.js} +1 -1
- package/web/dist/assets/{citizen-B8p56JRh.js → citizen-BRg9UIgD.js} +1 -1
- package/web/dist/assets/{compose-CV4o6TMb.js → compose-BnOoMY1c.js} +1 -1
- package/web/dist/assets/format-hyYD8qd8.js +55 -0
- package/web/dist/assets/governance-D4hlG-xw.js +1 -0
- package/web/dist/assets/index-5CbC_NpF.js +24 -0
- package/web/dist/assets/{index-CA_njyMe.css → index-vxBI4BYp.css} +1 -1
- package/web/dist/assets/{mentions-BH0RZXfc.js → mentions-Ckktc7nR.js} +1 -1
- package/web/dist/assets/{tasks-D2Es55TQ.js → tasks-CFVtN9TK.js} +1 -1
- package/web/dist/assets/{useMatch-DeOpK57G.js → useMatch-BCaBBHc2.js} +1 -1
- package/web/dist/favicon.svg +89 -4
- package/web/dist/index.html +9 -9
- package/web/dist/assets/BackLink-fxPmFUg8.js +0 -1
- package/web/dist/assets/ChannelForms-C3m4IPnZ.js +0 -1
- package/web/dist/assets/CitizenView-Dq64VsZi.js +0 -2
- package/web/dist/assets/CronsView-CI947lZS.js +0 -1
- package/web/dist/assets/MetricsView-BhjdwkX1.js +0 -1
- package/web/dist/assets/NeedsYouView-7uZW9dY8.js +0 -1
- package/web/dist/assets/Overview-D6kiK8sE.js +0 -1
- package/web/dist/assets/ProjectView-B6OmxiT9.js +0 -1
- package/web/dist/assets/ProposalView-B1X8Jlo0.js +0 -1
- package/web/dist/assets/SkillView-B1knYZV8.js +0 -1
- package/web/dist/assets/SocietyView-F7bzrNv5.js +0 -1
- package/web/dist/assets/TasksView-DZLNqU2V.js +0 -1
- package/web/dist/assets/ThreadItem-kFn5M3Cx.js +0 -1
- package/web/dist/assets/format-BYF63sQU.js +0 -55
- package/web/dist/assets/governance-BjIg0eok.js +0 -1
- package/web/dist/assets/index-CyROMh25.js +0 -24
package/dist/cli/index.js
CHANGED
|
@@ -1040,6 +1040,12 @@ import { z as z7 } from "zod";
|
|
|
1040
1040
|
import { z as z6 } from "zod";
|
|
1041
1041
|
var IMAGE_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
1042
1042
|
var ImageTypeSchema = z6.enum(["png", "jpeg", "gif", "webp"]);
|
|
1043
|
+
var IMAGE_KIND_NAMES = {
|
|
1044
|
+
png: "PNG",
|
|
1045
|
+
jpeg: "JPEG",
|
|
1046
|
+
gif: "GIF",
|
|
1047
|
+
webp: "WebP"
|
|
1048
|
+
};
|
|
1043
1049
|
function startsWith(bytes, prefix, at = 0) {
|
|
1044
1050
|
for (let index = 0; index < prefix.length; index += 1) {
|
|
1045
1051
|
if (bytes[at + index] !== prefix[index]) {
|
|
@@ -1461,7 +1467,11 @@ var RunnerHelloSchema = z9.object({
|
|
|
1461
1467
|
gitIdentityMissing: z9.array(GitIdentityPartSchema).optional(),
|
|
1462
1468
|
/** Turns the runner runs at once, or null for no limit. */
|
|
1463
1469
|
slots: z9.number().int().positive().nullable(),
|
|
1464
|
-
/**
|
|
1470
|
+
/**
|
|
1471
|
+
* Turns the runner is still running, when it registers again: the server fails the rest of its
|
|
1472
|
+
* turns, and has any of these it has ended stopped once the stream opens, when the runner lists
|
|
1473
|
+
* a CLI it can stop.
|
|
1474
|
+
*/
|
|
1465
1475
|
turns: z9.array(UlidSchema).default([])
|
|
1466
1476
|
});
|
|
1467
1477
|
var RunnerWelcomeSchema = z9.object({ name: NameSchema, version: z9.string() });
|
|
@@ -1616,9 +1626,9 @@ var TurnOutcomeSchema = z9.object({
|
|
|
1616
1626
|
*/
|
|
1617
1627
|
resumeFailed: ResumeFailureSchema.optional(),
|
|
1618
1628
|
/**
|
|
1619
|
-
* Set when the model service turned
|
|
1620
|
-
*
|
|
1621
|
-
* runner from before never sends it.
|
|
1629
|
+
* Set when the turn failed for now: the model service turned it away or cut it off, or the runner
|
|
1630
|
+
* could not reach the board before the CLI started. The scheduler answers it by sending the same
|
|
1631
|
+
* wake again within minutes. A runner from before never sends it.
|
|
1622
1632
|
*/
|
|
1623
1633
|
transient: z9.boolean().optional(),
|
|
1624
1634
|
/** The model the CLI reported, when it reported one. */
|
|
@@ -2009,13 +2019,18 @@ var TurnRecordSchema = z10.object({
|
|
|
2009
2019
|
stoppedBy: NameSchema.optional(),
|
|
2010
2020
|
/** Why the CLI could not resume the turn's session, for a turn that failed so. */
|
|
2011
2021
|
resumeFailed: ResumeFailureSchema.optional(),
|
|
2012
|
-
/**
|
|
2022
|
+
/**
|
|
2023
|
+
* Whether the turn failed for now, which the same wake may get past in a minute: the model service
|
|
2024
|
+
* turned it away or cut it off, the runner could not reach the board before the CLI started, or
|
|
2025
|
+
* the job never reached the runner.
|
|
2026
|
+
*/
|
|
2013
2027
|
transient: z10.boolean().optional(),
|
|
2014
2028
|
/** How many turns in a row, this one included, could not resume the session for a `retry`. */
|
|
2015
2029
|
resumeRetries: z10.number().int().positive().optional(),
|
|
2016
2030
|
/**
|
|
2017
2031
|
* Whether the server dropped the conversation's session after this turn, which the next starts
|
|
2018
|
-
* anew: one its CLI could not resume, or a society role's home after a
|
|
2032
|
+
* anew: one its CLI could not resume, or a society role's or a project member's home after a
|
|
2033
|
+
* reflection completed.
|
|
2019
2034
|
*/
|
|
2020
2035
|
sessionDropped: z10.boolean().optional(),
|
|
2021
2036
|
/** The crons whose fire started the turn, which record how it ended. */
|
|
@@ -2260,6 +2275,11 @@ var ServerConfigSchema = z13.object({
|
|
|
2260
2275
|
dataDir: z13.string().min(1),
|
|
2261
2276
|
host: z13.string().min(1),
|
|
2262
2277
|
port: z13.number().int().positive().max(65535),
|
|
2278
|
+
/**
|
|
2279
|
+
* A second port, on the same host, that serves Prometheus's counters at `/metrics` and nothing
|
|
2280
|
+
* else, or null for none: the main port's `/metrics` is the interface's page.
|
|
2281
|
+
*/
|
|
2282
|
+
metricsPort: z13.number().int().positive().max(65535).nullable(),
|
|
2263
2283
|
/**
|
|
2264
2284
|
* An address every runner's agents reach this server at, for example https://board.example, or
|
|
2265
2285
|
* null for each runner to use the address it reaches the server at itself.
|
|
@@ -2300,7 +2320,7 @@ var RunnerConfigSchema = z13.object({
|
|
|
2300
2320
|
});
|
|
2301
2321
|
|
|
2302
2322
|
// packages/shared/dist/version.js
|
|
2303
|
-
var STELLARIS_VERSION = "0.4.
|
|
2323
|
+
var STELLARIS_VERSION = "0.4.2";
|
|
2304
2324
|
|
|
2305
2325
|
// packages/shared/dist/mentions.js
|
|
2306
2326
|
import { parse, postprocess, preprocess } from "micromark";
|
|
@@ -2992,6 +3012,451 @@ function filesOf(lines, status) {
|
|
|
2992
3012
|
return [...files.values()];
|
|
2993
3013
|
}
|
|
2994
3014
|
|
|
3015
|
+
// packages/shared/dist/image-metadata.js
|
|
3016
|
+
function withoutMetadata(bytes) {
|
|
3017
|
+
switch (imageTypeOf(bytes)) {
|
|
3018
|
+
case "jpeg":
|
|
3019
|
+
return jpegWithoutMetadata(bytes);
|
|
3020
|
+
case "png":
|
|
3021
|
+
return pngWithoutMetadata(bytes);
|
|
3022
|
+
case "gif":
|
|
3023
|
+
return gifWithoutMetadata(bytes);
|
|
3024
|
+
case "webp":
|
|
3025
|
+
return webpWithoutMetadata(bytes);
|
|
3026
|
+
default:
|
|
3027
|
+
return null;
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
function exifOrientation(block) {
|
|
3031
|
+
const tiff = startsWith2(block, EXIF_HEADER) ? block.subarray(EXIF_HEADER.length) : block;
|
|
3032
|
+
let little;
|
|
3033
|
+
if (tiff[0] === 73 && tiff[1] === 73) {
|
|
3034
|
+
little = true;
|
|
3035
|
+
} else if (tiff[0] === 77 && tiff[1] === 77) {
|
|
3036
|
+
little = false;
|
|
3037
|
+
} else {
|
|
3038
|
+
return 1;
|
|
3039
|
+
}
|
|
3040
|
+
const number = (offset, size) => offset >= 0 && size <= tiff.length && offset <= tiff.length - size ? numberAt(tiff, offset, size, little) : null;
|
|
3041
|
+
const directory = number(4, 4);
|
|
3042
|
+
const count = directory === null ? null : number(directory, 2);
|
|
3043
|
+
if (number(2, 2) !== 42 || directory === null || count === null) {
|
|
3044
|
+
return 1;
|
|
3045
|
+
}
|
|
3046
|
+
for (let entry = directory + 2; entry < directory + 2 + count * 12; entry += 12) {
|
|
3047
|
+
const tag = number(entry, 2);
|
|
3048
|
+
if (tag === null) {
|
|
3049
|
+
return 1;
|
|
3050
|
+
}
|
|
3051
|
+
if (tag === 274) {
|
|
3052
|
+
const value = number(entry + 8, 2);
|
|
3053
|
+
if (number(entry + 2, 2) !== 3 || number(entry + 4, 4) !== 1 || value === null || value < 1 || value > 8) {
|
|
3054
|
+
return 1;
|
|
3055
|
+
}
|
|
3056
|
+
return value;
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
return 1;
|
|
3060
|
+
}
|
|
3061
|
+
function orientationOnly(orientation) {
|
|
3062
|
+
const block = new Uint8Array([
|
|
3063
|
+
77,
|
|
3064
|
+
77,
|
|
3065
|
+
0,
|
|
3066
|
+
42,
|
|
3067
|
+
0,
|
|
3068
|
+
0,
|
|
3069
|
+
0,
|
|
3070
|
+
8,
|
|
3071
|
+
0,
|
|
3072
|
+
1,
|
|
3073
|
+
1,
|
|
3074
|
+
18,
|
|
3075
|
+
0,
|
|
3076
|
+
3,
|
|
3077
|
+
0,
|
|
3078
|
+
0,
|
|
3079
|
+
0,
|
|
3080
|
+
1,
|
|
3081
|
+
0,
|
|
3082
|
+
0,
|
|
3083
|
+
0,
|
|
3084
|
+
0,
|
|
3085
|
+
0,
|
|
3086
|
+
0,
|
|
3087
|
+
0,
|
|
3088
|
+
0
|
|
3089
|
+
]);
|
|
3090
|
+
block[19] = orientation;
|
|
3091
|
+
return block;
|
|
3092
|
+
}
|
|
3093
|
+
function crc32(bytes) {
|
|
3094
|
+
let crc = 4294967295;
|
|
3095
|
+
for (const byte of bytes) {
|
|
3096
|
+
crc = (crcTable()[(crc ^ byte) & 255] ?? 0) ^ crc >>> 8;
|
|
3097
|
+
}
|
|
3098
|
+
return (crc ^ 4294967295) >>> 0;
|
|
3099
|
+
}
|
|
3100
|
+
var crcEntries;
|
|
3101
|
+
function crcTable() {
|
|
3102
|
+
if (crcEntries === void 0) {
|
|
3103
|
+
crcEntries = new Uint32Array(256);
|
|
3104
|
+
for (let index = 0; index < 256; index += 1) {
|
|
3105
|
+
let crc = index;
|
|
3106
|
+
for (let bit = 0; bit < 8; bit += 1) {
|
|
3107
|
+
crc = crc & 1 ? 3988292384 ^ crc >>> 1 : crc >>> 1;
|
|
3108
|
+
}
|
|
3109
|
+
crcEntries[index] = crc >>> 0;
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
return crcEntries;
|
|
3113
|
+
}
|
|
3114
|
+
var ascii2 = (text) => new TextEncoder().encode(text);
|
|
3115
|
+
var EXIF_HEADER = Uint8Array.of(69, 120, 105, 102, 0, 0);
|
|
3116
|
+
function startsWith2(bytes, prefix, at = 0) {
|
|
3117
|
+
if (bytes.length - at < prefix.length) {
|
|
3118
|
+
return false;
|
|
3119
|
+
}
|
|
3120
|
+
for (let index = 0; index < prefix.length; index += 1) {
|
|
3121
|
+
if (bytes[at + index] !== prefix[index]) {
|
|
3122
|
+
return false;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
return true;
|
|
3126
|
+
}
|
|
3127
|
+
function typeAt(bytes, at) {
|
|
3128
|
+
return String.fromCharCode(bytes[at] ?? 0, bytes[at + 1] ?? 0, bytes[at + 2] ?? 0, bytes[at + 3] ?? 0);
|
|
3129
|
+
}
|
|
3130
|
+
function numberAt(bytes, at, size, little = false) {
|
|
3131
|
+
let value = 0;
|
|
3132
|
+
for (let index = 0; index < size; index += 1) {
|
|
3133
|
+
value = value * 256 + (bytes[at + (little ? size - 1 - index : index)] ?? 0);
|
|
3134
|
+
}
|
|
3135
|
+
return value;
|
|
3136
|
+
}
|
|
3137
|
+
function bigEndian(value, size) {
|
|
3138
|
+
return Array.from({ length: size }, (_, index) => value >>> (size - 1 - index) * 8 & 255);
|
|
3139
|
+
}
|
|
3140
|
+
function littleEndian(value, size) {
|
|
3141
|
+
return Array.from({ length: size }, (_, index) => value >>> index * 8 & 255);
|
|
3142
|
+
}
|
|
3143
|
+
var Kept = class {
|
|
3144
|
+
buffer;
|
|
3145
|
+
length = 0;
|
|
3146
|
+
constructor(capacity) {
|
|
3147
|
+
this.buffer = new Uint8Array(Math.max(capacity, 64));
|
|
3148
|
+
}
|
|
3149
|
+
add(piece) {
|
|
3150
|
+
if (this.length + piece.length > this.buffer.length) {
|
|
3151
|
+
const grown = new Uint8Array(Math.max(this.buffer.length * 2, this.length + piece.length));
|
|
3152
|
+
grown.set(this.buffer.subarray(0, this.length));
|
|
3153
|
+
this.buffer = grown;
|
|
3154
|
+
}
|
|
3155
|
+
this.buffer.set(piece, this.length);
|
|
3156
|
+
this.length += piece.length;
|
|
3157
|
+
}
|
|
3158
|
+
/** Writes `piece` over what was kept from `at` on, as a size once what it measures is kept. */
|
|
3159
|
+
set(at, piece) {
|
|
3160
|
+
this.buffer.set(piece, at);
|
|
3161
|
+
}
|
|
3162
|
+
get bytes() {
|
|
3163
|
+
return this.buffer.subarray(0, this.length);
|
|
3164
|
+
}
|
|
3165
|
+
};
|
|
3166
|
+
function jpegWithoutMetadata(bytes) {
|
|
3167
|
+
if (bytes[0] !== 255 || bytes[1] !== 216) {
|
|
3168
|
+
return null;
|
|
3169
|
+
}
|
|
3170
|
+
const kept = new Kept(bytes.length);
|
|
3171
|
+
kept.add([255, 216]);
|
|
3172
|
+
let at = 2;
|
|
3173
|
+
let orientationKept = false;
|
|
3174
|
+
for (; ; ) {
|
|
3175
|
+
if (at + 1 >= bytes.length || bytes[at] !== 255) {
|
|
3176
|
+
return null;
|
|
3177
|
+
}
|
|
3178
|
+
const marker = bytes[at + 1] ?? 0;
|
|
3179
|
+
if (marker === 255) {
|
|
3180
|
+
at += 1;
|
|
3181
|
+
continue;
|
|
3182
|
+
}
|
|
3183
|
+
if (marker === 0 || marker >= 2 && marker <= 191 || marker === 216 || marker === 217) {
|
|
3184
|
+
return null;
|
|
3185
|
+
}
|
|
3186
|
+
if (marker === 1 || marker >= 208 && marker <= 215) {
|
|
3187
|
+
kept.add([255, marker]);
|
|
3188
|
+
at += 2;
|
|
3189
|
+
continue;
|
|
3190
|
+
}
|
|
3191
|
+
if (at + 4 > bytes.length) {
|
|
3192
|
+
return null;
|
|
3193
|
+
}
|
|
3194
|
+
const length = numberAt(bytes, at + 2, 2);
|
|
3195
|
+
const end = at + 2 + length;
|
|
3196
|
+
if (length < 2 || end > bytes.length) {
|
|
3197
|
+
return null;
|
|
3198
|
+
}
|
|
3199
|
+
const payload = bytes.subarray(at + 4, end);
|
|
3200
|
+
if (marker === 224) {
|
|
3201
|
+
if (startsWith2(payload, JFIF) && payload.length >= 14) {
|
|
3202
|
+
kept.add([255, 224, 0, 16]);
|
|
3203
|
+
kept.add(payload.subarray(0, 12));
|
|
3204
|
+
kept.add([0, 0]);
|
|
3205
|
+
}
|
|
3206
|
+
} else if (marker === 225) {
|
|
3207
|
+
if (startsWith2(payload, EXIF_HEADER) && !orientationKept) {
|
|
3208
|
+
orientationKept = true;
|
|
3209
|
+
const orientation = exifOrientation(payload.subarray(EXIF_HEADER.length));
|
|
3210
|
+
if (orientation !== 1) {
|
|
3211
|
+
const exif = orientationOnly(orientation);
|
|
3212
|
+
kept.add([255, 225, ...bigEndian(EXIF_HEADER.length + exif.length + 2, 2)]);
|
|
3213
|
+
kept.add(EXIF_HEADER);
|
|
3214
|
+
kept.add(exif);
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
} else if (marker === 226 && startsWith2(payload, ICC_PROFILE) || marker === 238 && startsWith2(payload, ADOBE) || // A frame, its tables, a scan, and their kin, JPEG-LS's frame and parameters among them.
|
|
3218
|
+
marker >= 192 && marker <= 207 && marker !== 200 || marker >= 218 && marker <= 223 || marker === 247 || marker === 248) {
|
|
3219
|
+
kept.add(bytes.subarray(at, end));
|
|
3220
|
+
}
|
|
3221
|
+
at = end;
|
|
3222
|
+
if (marker !== 218) {
|
|
3223
|
+
continue;
|
|
3224
|
+
}
|
|
3225
|
+
const scan = at;
|
|
3226
|
+
for (; ; ) {
|
|
3227
|
+
const next = bytes.indexOf(255, at);
|
|
3228
|
+
if (next === -1 || next + 1 >= bytes.length) {
|
|
3229
|
+
return null;
|
|
3230
|
+
}
|
|
3231
|
+
at = next;
|
|
3232
|
+
const after = bytes[at + 1] ?? 0;
|
|
3233
|
+
if (after !== 0 && after !== 255 && !(after >= 208 && after <= 215)) {
|
|
3234
|
+
break;
|
|
3235
|
+
}
|
|
3236
|
+
at += 1;
|
|
3237
|
+
}
|
|
3238
|
+
kept.add(bytes.subarray(scan, at));
|
|
3239
|
+
if (bytes[at + 1] === 217) {
|
|
3240
|
+
kept.add([255, 217]);
|
|
3241
|
+
return kept.bytes;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
var JFIF = Uint8Array.of(74, 70, 73, 70, 0);
|
|
3246
|
+
var ICC_PROFILE = ascii2("ICC_PROFILE\0");
|
|
3247
|
+
var ADOBE = ascii2("Adobe");
|
|
3248
|
+
var PNG_DRAWING_CHUNKS = /* @__PURE__ */ new Set([
|
|
3249
|
+
"IHDR",
|
|
3250
|
+
"PLTE",
|
|
3251
|
+
"IDAT",
|
|
3252
|
+
"IEND",
|
|
3253
|
+
"tRNS",
|
|
3254
|
+
"cHRM",
|
|
3255
|
+
"gAMA",
|
|
3256
|
+
"iCCP",
|
|
3257
|
+
"sBIT",
|
|
3258
|
+
"sRGB",
|
|
3259
|
+
"cICP",
|
|
3260
|
+
"mDCV",
|
|
3261
|
+
"cLLI",
|
|
3262
|
+
"bKGD",
|
|
3263
|
+
"hIST",
|
|
3264
|
+
"pHYs",
|
|
3265
|
+
"sPLT",
|
|
3266
|
+
"acTL",
|
|
3267
|
+
"fcTL",
|
|
3268
|
+
"fdAT"
|
|
3269
|
+
]);
|
|
3270
|
+
function pngWithoutMetadata(bytes) {
|
|
3271
|
+
const kept = new Kept(bytes.length);
|
|
3272
|
+
kept.add(bytes.subarray(0, 8));
|
|
3273
|
+
let at = 8;
|
|
3274
|
+
let orientationKept = false;
|
|
3275
|
+
while (at + 12 <= bytes.length) {
|
|
3276
|
+
const length = numberAt(bytes, at, 4);
|
|
3277
|
+
const type = typeAt(bytes, at + 4);
|
|
3278
|
+
if (length > bytes.length - at - 12) {
|
|
3279
|
+
return null;
|
|
3280
|
+
}
|
|
3281
|
+
const end = at + 12 + length;
|
|
3282
|
+
if (PNG_DRAWING_CHUNKS.has(type)) {
|
|
3283
|
+
kept.add(bytes.subarray(at, end));
|
|
3284
|
+
} else if (type === "eXIf" && !orientationKept) {
|
|
3285
|
+
orientationKept = true;
|
|
3286
|
+
const orientation = exifOrientation(bytes.subarray(at + 8, at + 8 + length));
|
|
3287
|
+
if (orientation !== 1) {
|
|
3288
|
+
const data = new Uint8Array([...ascii2("eXIf"), ...orientationOnly(orientation)]);
|
|
3289
|
+
kept.add(bigEndian(data.length - 4, 4));
|
|
3290
|
+
kept.add(data);
|
|
3291
|
+
kept.add(bigEndian(crc32(data), 4));
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
if (type === "IEND") {
|
|
3295
|
+
return kept.bytes;
|
|
3296
|
+
}
|
|
3297
|
+
at = end;
|
|
3298
|
+
}
|
|
3299
|
+
return null;
|
|
3300
|
+
}
|
|
3301
|
+
var GIF_PLAYING_APPLICATIONS = [
|
|
3302
|
+
"NETSCAPE2.0",
|
|
3303
|
+
"ANIMEXTS1.0",
|
|
3304
|
+
"ICCRGBG1012"
|
|
3305
|
+
].map(ascii2);
|
|
3306
|
+
function gifColourTable(packed) {
|
|
3307
|
+
return packed & 128 ? 3 << (packed & 7) + 1 : 0;
|
|
3308
|
+
}
|
|
3309
|
+
function gifWithoutMetadata(bytes) {
|
|
3310
|
+
const subBlocksEnd = (start) => {
|
|
3311
|
+
let at2 = start;
|
|
3312
|
+
while (at2 < bytes.length) {
|
|
3313
|
+
const size = bytes[at2] ?? 0;
|
|
3314
|
+
if (size === 0) {
|
|
3315
|
+
return at2 + 1;
|
|
3316
|
+
}
|
|
3317
|
+
at2 += 1 + size;
|
|
3318
|
+
}
|
|
3319
|
+
return null;
|
|
3320
|
+
};
|
|
3321
|
+
if (bytes.length < 13) {
|
|
3322
|
+
return null;
|
|
3323
|
+
}
|
|
3324
|
+
let at = 13 + gifColourTable(bytes[10] ?? 0);
|
|
3325
|
+
if (at > bytes.length) {
|
|
3326
|
+
return null;
|
|
3327
|
+
}
|
|
3328
|
+
const kept = new Kept(bytes.length);
|
|
3329
|
+
kept.add(bytes.subarray(0, at));
|
|
3330
|
+
while (at < bytes.length) {
|
|
3331
|
+
switch (bytes[at]) {
|
|
3332
|
+
case 44: {
|
|
3333
|
+
if (at + 10 > bytes.length) {
|
|
3334
|
+
return null;
|
|
3335
|
+
}
|
|
3336
|
+
const data = at + 10 + gifColourTable(bytes[at + 9] ?? 0);
|
|
3337
|
+
const end = data < bytes.length ? subBlocksEnd(data + 1) : null;
|
|
3338
|
+
if (end === null) {
|
|
3339
|
+
return null;
|
|
3340
|
+
}
|
|
3341
|
+
kept.add(bytes.subarray(at, end));
|
|
3342
|
+
at = end;
|
|
3343
|
+
break;
|
|
3344
|
+
}
|
|
3345
|
+
case 33: {
|
|
3346
|
+
const end = at + 2 < bytes.length ? subBlocksEnd(at + 2) : null;
|
|
3347
|
+
if (end === null) {
|
|
3348
|
+
return null;
|
|
3349
|
+
}
|
|
3350
|
+
const label = bytes[at + 1];
|
|
3351
|
+
const plays = label === 255 && bytes[at + 2] === 11 && end >= at + 14 && GIF_PLAYING_APPLICATIONS.some((name) => startsWith2(bytes, name, at + 3));
|
|
3352
|
+
if (label === 249 || label === 1 || plays) {
|
|
3353
|
+
kept.add(bytes.subarray(at, end));
|
|
3354
|
+
}
|
|
3355
|
+
at = end;
|
|
3356
|
+
break;
|
|
3357
|
+
}
|
|
3358
|
+
case 59:
|
|
3359
|
+
kept.add([59]);
|
|
3360
|
+
return kept.bytes;
|
|
3361
|
+
default:
|
|
3362
|
+
return null;
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
return null;
|
|
3366
|
+
}
|
|
3367
|
+
var WEBP_DRAWING_CHUNKS = /* @__PURE__ */ new Set([
|
|
3368
|
+
"VP8X",
|
|
3369
|
+
"ICCP",
|
|
3370
|
+
"ANIM",
|
|
3371
|
+
"ANMF",
|
|
3372
|
+
"ALPH",
|
|
3373
|
+
"VP8 ",
|
|
3374
|
+
"VP8L"
|
|
3375
|
+
]);
|
|
3376
|
+
function webpWithoutMetadata(bytes) {
|
|
3377
|
+
if (bytes.length < 12) {
|
|
3378
|
+
return null;
|
|
3379
|
+
}
|
|
3380
|
+
const end = 8 + numberAt(bytes, 4, 4, true);
|
|
3381
|
+
const chunks = end >= 12 && end <= bytes.length ? webpChunks(bytes.subarray(12, end)) : null;
|
|
3382
|
+
if (chunks === null || chunks.length === 0) {
|
|
3383
|
+
return null;
|
|
3384
|
+
}
|
|
3385
|
+
const kept = new Kept(chunks.length + 12);
|
|
3386
|
+
kept.add(ascii2("RIFF"));
|
|
3387
|
+
kept.add(littleEndian(chunks.length + 4, 4));
|
|
3388
|
+
kept.add(ascii2("WEBP"));
|
|
3389
|
+
kept.add(chunks);
|
|
3390
|
+
const image = kept.bytes;
|
|
3391
|
+
if (image.length > 20 && typeAt(image, 12) === "VP8X" && numberAt(image, 16, 4, true) > 0) {
|
|
3392
|
+
const exif = webpChunkTypes(image.subarray(12)).includes("EXIF");
|
|
3393
|
+
image[20] = (image[20] ?? 0) & ~12 | (exif ? 8 : 0);
|
|
3394
|
+
}
|
|
3395
|
+
return image;
|
|
3396
|
+
}
|
|
3397
|
+
function webpChunks(chunks) {
|
|
3398
|
+
const kept = new Kept(chunks.length);
|
|
3399
|
+
const frames = [];
|
|
3400
|
+
let end = chunks.length;
|
|
3401
|
+
let at = 0;
|
|
3402
|
+
let orientationKept = false;
|
|
3403
|
+
for (; ; ) {
|
|
3404
|
+
if (at >= end) {
|
|
3405
|
+
const frame = frames.pop();
|
|
3406
|
+
if (frame === void 0) {
|
|
3407
|
+
return kept.bytes;
|
|
3408
|
+
}
|
|
3409
|
+
kept.set(frame.size, littleEndian(kept.length - frame.size - 4, 4));
|
|
3410
|
+
at = frame.resume;
|
|
3411
|
+
end = frames.at(-1)?.end ?? chunks.length;
|
|
3412
|
+
continue;
|
|
3413
|
+
}
|
|
3414
|
+
if (end - at < 8) {
|
|
3415
|
+
return null;
|
|
3416
|
+
}
|
|
3417
|
+
const type = typeAt(chunks, at);
|
|
3418
|
+
const size = numberAt(chunks, at + 4, 4, true);
|
|
3419
|
+
if (size > end - at - 8) {
|
|
3420
|
+
return null;
|
|
3421
|
+
}
|
|
3422
|
+
const data = at + 8;
|
|
3423
|
+
at = Math.min(data + size + size % 2, end);
|
|
3424
|
+
if (type === "ANMF") {
|
|
3425
|
+
if (size < 16) {
|
|
3426
|
+
return null;
|
|
3427
|
+
}
|
|
3428
|
+
frames.push({ end: data + size, resume: at, size: kept.length + 4 });
|
|
3429
|
+
kept.add(chunks.subarray(data - 8, data + 16));
|
|
3430
|
+
at = data + 16;
|
|
3431
|
+
end = data + size;
|
|
3432
|
+
} else if (WEBP_DRAWING_CHUNKS.has(type)) {
|
|
3433
|
+
kept.add(chunks.subarray(data - 8, data + size));
|
|
3434
|
+
if (size % 2 === 1) {
|
|
3435
|
+
kept.add([0]);
|
|
3436
|
+
}
|
|
3437
|
+
} else if (type === "EXIF" && frames.length === 0 && !orientationKept) {
|
|
3438
|
+
orientationKept = true;
|
|
3439
|
+
const turned = exifOrientation(chunks.subarray(data, data + size));
|
|
3440
|
+
if (turned !== 1) {
|
|
3441
|
+
const exif = orientationOnly(turned);
|
|
3442
|
+
kept.add(ascii2(type));
|
|
3443
|
+
kept.add(littleEndian(exif.length, 4));
|
|
3444
|
+
kept.add(exif);
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
function webpChunkTypes(chunks) {
|
|
3450
|
+
const types = [];
|
|
3451
|
+
let at = 0;
|
|
3452
|
+
while (chunks.length - at >= 8) {
|
|
3453
|
+
types.push(typeAt(chunks, at));
|
|
3454
|
+
const size = numberAt(chunks, at + 4, 4, true);
|
|
3455
|
+
at += 8 + size + size % 2;
|
|
3456
|
+
}
|
|
3457
|
+
return types;
|
|
3458
|
+
}
|
|
3459
|
+
|
|
2995
3460
|
// packages/board-core/dist/moves.js
|
|
2996
3461
|
import { mkdir as mkdir4, rm as rm2 } from "node:fs/promises";
|
|
2997
3462
|
import path5 from "node:path";
|
|
@@ -3434,6 +3899,72 @@ function tokenUse(events, window, now) {
|
|
|
3434
3899
|
};
|
|
3435
3900
|
}
|
|
3436
3901
|
|
|
3902
|
+
// packages/board-core/dist/turn-counters.js
|
|
3903
|
+
var TOKEN_KINDS = ["input", "output", "cache_read", "cache_write"];
|
|
3904
|
+
var USAGE_FIELD = {
|
|
3905
|
+
input: "inputTokens",
|
|
3906
|
+
output: "outputTokens",
|
|
3907
|
+
cache_read: "cacheReadTokens",
|
|
3908
|
+
cache_write: "cacheWriteTokens"
|
|
3909
|
+
};
|
|
3910
|
+
var UNKNOWN_LABEL = "unknown";
|
|
3911
|
+
function byKey(entries) {
|
|
3912
|
+
return [...entries].toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, series]) => series);
|
|
3913
|
+
}
|
|
3914
|
+
var TurnCounters = class {
|
|
3915
|
+
cliOf;
|
|
3916
|
+
tokens = /* @__PURE__ */ new Map();
|
|
3917
|
+
turns = /* @__PURE__ */ new Map();
|
|
3918
|
+
/**
|
|
3919
|
+
* `cliOf` names a citizen's CLI for an end logged before ends named theirs: a turn runs on the
|
|
3920
|
+
* CLI its citizen's record names, which nothing changes after the citizen is added.
|
|
3921
|
+
*/
|
|
3922
|
+
constructor(cliOf) {
|
|
3923
|
+
this.cliOf = cliOf;
|
|
3924
|
+
}
|
|
3925
|
+
/** Counts a turn's end, `turn.completed` or `turn.failed`, and passes over any other event. */
|
|
3926
|
+
add(event) {
|
|
3927
|
+
if (event.type !== "turn.completed" && event.type !== "turn.failed") {
|
|
3928
|
+
return;
|
|
3929
|
+
}
|
|
3930
|
+
const turn2 = TurnHistoryPayloadSchema.safeParse(event.payload);
|
|
3931
|
+
if (!turn2.success) {
|
|
3932
|
+
return;
|
|
3933
|
+
}
|
|
3934
|
+
const agent2 = event.actor;
|
|
3935
|
+
const outcome = event.type === "turn.failed" ? "failed" : "completed";
|
|
3936
|
+
const trigger = turn2.data.trigger;
|
|
3937
|
+
const counted = JSON.stringify([agent2, outcome, trigger]);
|
|
3938
|
+
this.turns.set(counted, {
|
|
3939
|
+
agent: agent2,
|
|
3940
|
+
outcome,
|
|
3941
|
+
trigger,
|
|
3942
|
+
turns: (this.turns.get(counted)?.turns ?? 0) + 1
|
|
3943
|
+
});
|
|
3944
|
+
const usage = turn2.data.usage;
|
|
3945
|
+
if (usage === void 0) {
|
|
3946
|
+
return;
|
|
3947
|
+
}
|
|
3948
|
+
const named = CliKindSchema.safeParse(event.payload["cli"]);
|
|
3949
|
+
const cli = (named.success ? named.data : this.cliOf(agent2)) ?? UNKNOWN_LABEL;
|
|
3950
|
+
const model = turn2.data.model ?? UNKNOWN_LABEL;
|
|
3951
|
+
for (const kind of TOKEN_KINDS) {
|
|
3952
|
+
const key = JSON.stringify([agent2, cli, model, kind]);
|
|
3953
|
+
this.tokens.set(key, {
|
|
3954
|
+
agent: agent2,
|
|
3955
|
+
cli,
|
|
3956
|
+
model,
|
|
3957
|
+
kind,
|
|
3958
|
+
tokens: (this.tokens.get(key)?.tokens ?? 0) + usage[USAGE_FIELD[kind]]
|
|
3959
|
+
});
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
/** The counts so far, in an order that holds from one read to the next. */
|
|
3963
|
+
read() {
|
|
3964
|
+
return { tokens: byKey(this.tokens), turns: byKey(this.turns) };
|
|
3965
|
+
}
|
|
3966
|
+
};
|
|
3967
|
+
|
|
3437
3968
|
// packages/board-core/dist/mutex.js
|
|
3438
3969
|
var Mutex = class {
|
|
3439
3970
|
tail = Promise.resolve();
|
|
@@ -3793,6 +4324,7 @@ function hashToken(token) {
|
|
|
3793
4324
|
// packages/board-core/dist/board.js
|
|
3794
4325
|
var SYSTEM_ACTOR = { name: "board", role: USER_ROLE };
|
|
3795
4326
|
var CLOSING_ATTEMPTS = 3;
|
|
4327
|
+
var CHANNEL_POST_WAIT_MS = 24 * 36e5;
|
|
3796
4328
|
function ownTurn(actor, turn2) {
|
|
3797
4329
|
return turn2.agent === actor.name && turn2.scope === actor.scope && turn2.thread === actor.thread && turn2.channel === actor.channel && turn2.place === actor.place;
|
|
3798
4330
|
}
|
|
@@ -5107,10 +5639,13 @@ ${DASHBOARD_LINE}
|
|
|
5107
5639
|
* when it mentions the user, so the creator can put a wait on the user in; a post that asks the
|
|
5108
5640
|
* reader counts wherever it is. A closed thread counts for nothing: its conversation has ended,
|
|
5109
5641
|
* and a turn there could only read its posts and be refused a reply, while a wake queued before
|
|
5110
|
-
* it closed, as for a mention, still runs there.
|
|
5642
|
+
* it closed, as for a mention, still runs there. A top-level post in a project's channel, general
|
|
5643
|
+
* or a workstream's, counts only for a reader it asks until it is `channelPostWaitMs` old, and
|
|
5644
|
+
* then for every reader who has not read it, so a turn there for anything else reads it sooner.
|
|
5111
5645
|
*/
|
|
5112
|
-
async unreadByConversation(actor) {
|
|
5646
|
+
async unreadByConversation(actor, options = {}) {
|
|
5113
5647
|
const { cursors, upto } = await this.digestSnapshot(actor.name);
|
|
5648
|
+
const waited = this.now().getTime() - (options.channelPostWaitMs ?? CHANNEL_POST_WAIT_MS);
|
|
5114
5649
|
const counts = /* @__PURE__ */ new Map();
|
|
5115
5650
|
const threadCounts = /* @__PURE__ */ new Map();
|
|
5116
5651
|
const unscoped = { name: actor.name, role: actor.role };
|
|
@@ -5118,11 +5653,15 @@ ${DASHBOARD_LINE}
|
|
|
5118
5653
|
if (news === true || message.step !== void 0 || message.author === SYSTEM_ACTOR.name || message.notice?.kind === "knowledge") {
|
|
5119
5654
|
continue;
|
|
5120
5655
|
}
|
|
5121
|
-
const
|
|
5656
|
+
const project2 = parseChannelRef(message.channel).project;
|
|
5657
|
+
const posted = project2 ?? SOCIETY_SCOPE;
|
|
5122
5658
|
if (posted !== scope && scope !== SOCIETY_SCOPE) {
|
|
5123
5659
|
continue;
|
|
5124
5660
|
}
|
|
5125
5661
|
const thread2 = threadOfPart(part);
|
|
5662
|
+
if (thread2 === void 0 && project2 !== null && asked !== true && Date.parse(message.ts) > waited) {
|
|
5663
|
+
continue;
|
|
5664
|
+
}
|
|
5126
5665
|
if (thread2 !== void 0) {
|
|
5127
5666
|
let counted = threadCounts.get(thread2);
|
|
5128
5667
|
if (counted === void 0) {
|
|
@@ -5546,9 +6085,9 @@ ${current.body}`);
|
|
|
5546
6085
|
/**
|
|
5547
6086
|
* Keeps an image a citizen's turn names by its path, read on the runner the turn runs on, which
|
|
5548
6087
|
* refuses a file outside the turn's worktree, the citizen's home, and the system temp folder.
|
|
5549
|
-
* Only
|
|
5550
|
-
*
|
|
5551
|
-
* mirrors
|
|
6088
|
+
* Only a PNG, JPEG, GIF, or WebP of at most `IMAGE_LIMIT_BYTES` is kept, checked here again
|
|
6089
|
+
* whatever the runner said, without its metadata, under a new id outside the projection, so no
|
|
6090
|
+
* runner mirrors it and no prompt carries it: a post shows the image by its `image:` address.
|
|
5552
6091
|
*/
|
|
5553
6092
|
async uploadImage(actor, input) {
|
|
5554
6093
|
const args = VerbInputs.upload_image.parse(input);
|
|
@@ -5574,8 +6113,13 @@ ${current.body}`);
|
|
|
5574
6113
|
}
|
|
5575
6114
|
/**
|
|
5576
6115
|
* Keeps `bytes` under a new id when they are a PNG, JPEG, GIF, or WebP of at most
|
|
5577
|
-
* `IMAGE_LIMIT_BYTES
|
|
5578
|
-
* names the image in a refusal.
|
|
6116
|
+
* `IMAGE_LIMIT_BYTES` that reads to its end, without its metadata (`withoutMetadata`), and
|
|
6117
|
+
* answers the markdown that shows it, described by `name`. `what` names the image in a refusal.
|
|
6118
|
+
* The limit is for the bytes as they came, as the route's body cap measures them, and bounds
|
|
6119
|
+
* what is read; what is kept is checked against it too, since an orientation written smaller
|
|
6120
|
+
* than the board writes it grows by a few bytes. The runner, the web's composer, and the app
|
|
6121
|
+
* strip an image before they send it, and stripping it again changes nothing, but an older
|
|
6122
|
+
* runner, page, or app sends one as it was.
|
|
5579
6123
|
*/
|
|
5580
6124
|
async keepImage(actor, bytes, what, name) {
|
|
5581
6125
|
const type = imageTypeOf(bytes);
|
|
@@ -5585,19 +6129,26 @@ ${current.body}`);
|
|
|
5585
6129
|
if (bytes.byteLength > IMAGE_LIMIT_BYTES) {
|
|
5586
6130
|
throw new BoardError("VALIDATION", `${what} is ${bytes.byteLength} bytes, over the ${IMAGE_LIMIT_BYTES} an image may be`);
|
|
5587
6131
|
}
|
|
6132
|
+
const kept = withoutMetadata(bytes);
|
|
6133
|
+
if (kept === null) {
|
|
6134
|
+
throw new BoardError("VALIDATION", `${what} does not read to its end as a ${IMAGE_KIND_NAMES[type]}, so its metadata cannot be told from its picture; save it again and send that copy`);
|
|
6135
|
+
}
|
|
6136
|
+
if (kept.byteLength > IMAGE_LIMIT_BYTES) {
|
|
6137
|
+
throw new BoardError("VALIDATION", `${what} is ${kept.byteLength} bytes without its metadata, over the ${IMAGE_LIMIT_BYTES} an image may be`);
|
|
6138
|
+
}
|
|
5588
6139
|
return this.mutex.run(async () => {
|
|
5589
6140
|
const id = this.newId();
|
|
5590
|
-
await writeFileAtomic(this.paths.image(id),
|
|
6141
|
+
await writeFileAtomic(this.paths.image(id), kept);
|
|
5591
6142
|
await this.events.append("image.uploaded", actor.name, {
|
|
5592
6143
|
id,
|
|
5593
6144
|
type,
|
|
5594
|
-
size:
|
|
6145
|
+
size: kept.byteLength
|
|
5595
6146
|
});
|
|
5596
6147
|
const description = imageDescription(name);
|
|
5597
6148
|
return {
|
|
5598
6149
|
id,
|
|
5599
6150
|
type,
|
|
5600
|
-
size:
|
|
6151
|
+
size: kept.byteLength,
|
|
5601
6152
|
markdown: ``
|
|
5602
6153
|
};
|
|
5603
6154
|
});
|
|
@@ -6898,6 +7449,39 @@ ${rationale}`}`);
|
|
|
6898
7449
|
const events = await this.events.readSince(null, Number.MAX_SAFE_INTEGER);
|
|
6899
7450
|
return tokenUse(events, window, this.now());
|
|
6900
7451
|
}
|
|
7452
|
+
/**
|
|
7453
|
+
* Every finished turn counted for Prometheus: seeded once from the whole event log, then moved
|
|
7454
|
+
* by each turn's end this process appends, so reading the counts never reads the log. The server
|
|
7455
|
+
* logs every turn's end itself; one another process appended would count from the next seed.
|
|
7456
|
+
*/
|
|
7457
|
+
async countTurns() {
|
|
7458
|
+
const clis = /* @__PURE__ */ new Map();
|
|
7459
|
+
const counters = new TurnCounters((agent2) => clis.get(agent2) ?? null);
|
|
7460
|
+
let waiting = [];
|
|
7461
|
+
this.events.onAppend((event) => {
|
|
7462
|
+
if (waiting === null) {
|
|
7463
|
+
counters.add(event);
|
|
7464
|
+
} else {
|
|
7465
|
+
waiting.push(event);
|
|
7466
|
+
}
|
|
7467
|
+
});
|
|
7468
|
+
const events = await this.events.readSince(null, Number.MAX_SAFE_INTEGER);
|
|
7469
|
+
for (const agent2 of await this.listAgents()) {
|
|
7470
|
+
clis.set(agent2.name, agent2.cli);
|
|
7471
|
+
}
|
|
7472
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7473
|
+
for (const event of events) {
|
|
7474
|
+
seen.add(event.id);
|
|
7475
|
+
counters.add(event);
|
|
7476
|
+
}
|
|
7477
|
+
for (const event of waiting) {
|
|
7478
|
+
if (!seen.has(event.id)) {
|
|
7479
|
+
counters.add(event);
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7482
|
+
waiting = null;
|
|
7483
|
+
return counters;
|
|
7484
|
+
}
|
|
6901
7485
|
/** The board actions a finished turn took, from its transcript; null when it kept none. */
|
|
6902
7486
|
async turnActions(agent2, turnId) {
|
|
6903
7487
|
const known = this.actionCounts.get(turnId);
|
|
@@ -7095,6 +7679,7 @@ ${rationale}`}`);
|
|
|
7095
7679
|
trigger: parsed.trigger.kind,
|
|
7096
7680
|
...parsed.trigger.heartbeat === void 0 ? {} : { heartbeat: parsed.trigger.heartbeat },
|
|
7097
7681
|
session: parsed.session,
|
|
7682
|
+
cli: parsed.cli,
|
|
7098
7683
|
exitReason: parsed.exitReason,
|
|
7099
7684
|
costUsd: parsed.costUsd,
|
|
7100
7685
|
...parsed.usage === null ? {} : { usage: parsed.usage },
|