humanish 0.38.0 → 0.40.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 (57) hide show
  1. package/README.md +5 -2
  2. package/dist/actor-contract.d.ts +24 -1
  3. package/dist/actor-contract.js +4 -0
  4. package/dist/actor-contract.js.map +1 -1
  5. package/dist/claude-agent-sdk.js +4 -0
  6. package/dist/claude-agent-sdk.js.map +1 -1
  7. package/dist/comms-catch-host.d.ts +31 -0
  8. package/dist/comms-catch-host.js +82 -4
  9. package/dist/comms-catch-host.js.map +1 -1
  10. package/dist/comms-sandbox-catch.d.ts +32 -1
  11. package/dist/comms-sandbox-catch.js +226 -19
  12. package/dist/comms-sandbox-catch.js.map +1 -1
  13. package/dist/computer-use-actor.d.ts +1 -1
  14. package/dist/computer-use.d.ts +13 -1
  15. package/dist/computer-use.js +100 -14
  16. package/dist/computer-use.js.map +1 -1
  17. package/dist/concurrent-shared-world-lab.js +7 -2
  18. package/dist/concurrent-shared-world-lab.js.map +1 -1
  19. package/dist/cua-actor-lab.d.ts +8 -0
  20. package/dist/cua-actor-lab.js +110 -9
  21. package/dist/cua-actor-lab.js.map +1 -1
  22. package/dist/e2b-desktop-executor.d.ts +21 -6
  23. package/dist/e2b-desktop-executor.js +65 -21
  24. package/dist/e2b-desktop-executor.js.map +1 -1
  25. package/dist/lab-config.d.ts +36 -0
  26. package/dist/lab-config.js +87 -2
  27. package/dist/lab-config.js.map +1 -1
  28. package/dist/observer-data.js +5 -0
  29. package/dist/observer-data.js.map +1 -1
  30. package/dist/openai-responses-cu.js +10 -1
  31. package/dist/openai-responses-cu.js.map +1 -1
  32. package/dist/orientation.d.ts +29 -0
  33. package/dist/orientation.js +95 -0
  34. package/dist/orientation.js.map +1 -0
  35. package/dist/persona-resolve.d.ts +44 -0
  36. package/dist/persona-resolve.js +109 -0
  37. package/dist/persona-resolve.js.map +1 -0
  38. package/dist/pi-agent-core.js +4 -0
  39. package/dist/pi-agent-core.js.map +1 -1
  40. package/dist/pricing.d.ts +8 -0
  41. package/dist/pricing.js +22 -6
  42. package/dist/pricing.js.map +1 -1
  43. package/dist/program.js +36 -1
  44. package/dist/program.js.map +1 -1
  45. package/dist/run.d.ts +1 -1
  46. package/dist/run.js +27 -1
  47. package/dist/run.js.map +1 -1
  48. package/dist/shared-world-lab.js +7 -2
  49. package/dist/shared-world-lab.js.map +1 -1
  50. package/dist/subject-runtime.d.ts +23 -0
  51. package/dist/subject-runtime.js +70 -0
  52. package/dist/subject-runtime.js.map +1 -0
  53. package/docs/contracts/schemas.md +1 -1
  54. package/docs/goals/current.md +2 -2
  55. package/docs/principles/three-roles.md +68 -0
  56. package/docs/ramp/README.md +1 -1
  57. package/package.json +1 -1
@@ -52,6 +52,9 @@ INBOX_PORT = int(sys.argv[4]) if len(sys.argv) > 4 else 0
52
52
  # in-sandbox default: the capture listener binds loopback there, so nothing external can reach it.
53
53
  # An ADOPTER-HOSTED catch is reachable over the network, so it should pass one.
54
54
  DELIVERIES_TOKEN = sys.argv[5] if len(sys.argv) > 5 else ""
55
+ # Optional loopback SMTP listener. Most self-hostable apps send mail over SMTP rather than an HTTP
56
+ # provider API, so without this the catch only works for the minority that speak HTTP.
57
+ SMTP_PORT = int(sys.argv[6]) if len(sys.argv) > 6 else 0
55
58
  try:
56
59
  os.makedirs(os.path.dirname(OUT_FILE), exist_ok=True)
57
60
  except Exception:
@@ -79,9 +82,19 @@ class BaseHandler(BaseHTTPRequestHandler):
79
82
 
80
83
  def do_GET(self):
81
84
  path = self.path.split("?")[0]
82
- if path == "/" or path == "/health":
85
+ if path == "/health":
83
86
  self._json(200, {"ok": True, "service": "humanish-comms-catch"})
84
87
  return
88
+ if path == "/":
89
+ # A persona that trims the /inbox path lands here. It used to get the health JSON and read
90
+ # it as "wrong place / broken", so send it where it meant to go. /health keeps the machine
91
+ # marker: both readiness probes assert on /health specifically, never on /.
92
+ self.send_response(200)
93
+ self.send_header("content-type", "text/html; charset=utf-8")
94
+ self.send_header("content-security-policy", CSP)
95
+ self.end_headers()
96
+ self.wfile.write(b"<!doctype html><title>Mailbox</title><p><a href='/inbox'>Open the inbox</a></p>")
97
+ return
85
98
  if path == "/deliveries":
86
99
  # The drain read. In-sandbox humanish reads the NDJSON file directly; an adopter-hosted
87
100
  # catch is on another machine, so the same bytes are served over HTTP. Capture bodies
@@ -117,10 +130,15 @@ class BaseHandler(BaseHTTPRequestHandler):
117
130
  except Exception:
118
131
  data = None
119
132
  if data is None:
133
+ # A JSON route answers in JSON; only the HTML route answers in HTML.
134
+ if rel.startswith("/api/"):
135
+ self._json(404, {"error": "message not found"})
136
+ return
120
137
  self.send_response(404)
121
138
  self.send_header("content-type", "text/html; charset=utf-8")
139
+ self.send_header("content-security-policy", CSP)
122
140
  self.end_headers()
123
- self.wfile.write(b"<p>message not found</p>")
141
+ self.wfile.write(b"<!doctype html><title>Mailbox</title><p>message not found</p><p><a href='/inbox'>Back to the inbox</a></p>")
124
142
  return
125
143
  is_api = rel.startswith("/api/")
126
144
  self.send_response(200)
@@ -174,6 +192,114 @@ class ReadOnlyHandler(BaseHandler):
174
192
  if INBOX_PORT and INBOX_PORT != PORT:
175
193
  threading.Thread(target=lambda: ThreadingHTTPServer(("0.0.0.0", INBOX_PORT), ReadOnlyHandler).serve_forever(), daemon=True).start()
176
194
 
195
+
196
+ # Minimal SMTP capture listener. Most self-hostable apps send mail through SMTP, not an HTTP provider
197
+ # API, so an HTTP-only catch could not study them at all. Plain sockets and the stdlib email parser:
198
+ # python 3.12 removed smtpd, and a co-located catcher must not need a dependency.
199
+ #
200
+ # It normalizes each message into the SAME NDJSON line an HTTP send produces, on the /emails path, so
201
+ # every host-side profile, the inbox surface, and the drain work unchanged — SMTP is a transport
202
+ # here, not a second pipeline.
203
+ # Built from chr() rather than a backslash escape: this script lives inside a TS template
204
+ # literal, where JS would consume the escape before python ever saw it.
205
+ CRLF = chr(13) + chr(10)
206
+
207
+
208
+ def smtp_reply(conn, text):
209
+ conn.sendall((text + CRLF).encode("utf-8"))
210
+
211
+
212
+ def smtp_session(conn):
213
+ import email
214
+ from email import policy
215
+
216
+ reader = conn.makefile("rb")
217
+ smtp_reply(conn, "220 humanish-comms-catch")
218
+ sender = ""
219
+ rcpts = []
220
+ while True:
221
+ line = reader.readline()
222
+ if not line:
223
+ break
224
+ command = line.decode("utf-8", "replace").strip()
225
+ upper = command.upper()
226
+ if upper.startswith("EHLO") or upper.startswith("HELO"):
227
+ # AUTH is advertised and then accepted unconditionally: the app under test holds
228
+ # whatever credentials its config carries, and this listener is loopback-only.
229
+ smtp_reply(conn, "250-humanish-comms-catch")
230
+ smtp_reply(conn, "250 AUTH PLAIN LOGIN")
231
+ elif upper.startswith("AUTH"):
232
+ smtp_reply(conn, "235 2.7.0 accepted")
233
+ elif upper.startswith("MAIL FROM"):
234
+ sender = command[command.find(":") + 1 :].strip().strip("<>")
235
+ smtp_reply(conn, "250 2.1.0 ok")
236
+ elif upper.startswith("RCPT TO"):
237
+ rcpts.append(command[command.find(":") + 1 :].strip().strip("<>"))
238
+ smtp_reply(conn, "250 2.1.5 ok")
239
+ elif upper == "DATA":
240
+ smtp_reply(conn, "354 end with <CRLF>.<CRLF>")
241
+ raw = b""
242
+ while True:
243
+ chunk = reader.readline()
244
+ if not chunk or chunk.strip() == b".":
245
+ break
246
+ # Undo dot-stuffing (RFC 5321): a leading '.' on a body line is doubled on the wire.
247
+ if chunk.startswith(b".."):
248
+ chunk = chunk[1:]
249
+ raw += chunk
250
+ if len(raw) > MAX_BODY:
251
+ break
252
+ try:
253
+ parsed = email.message_from_bytes(raw, policy=policy.default)
254
+ subject = str(parsed.get("subject") or "")
255
+ html_part = parsed.get_body(preferencelist=("html", "plain"))
256
+ body = html_part.get_content() if html_part is not None else ""
257
+ except Exception:
258
+ subject = ""
259
+ body = raw.decode("utf-8", "replace")
260
+ record = {
261
+ "t": int(time.time() * 1000),
262
+ "path": "/emails",
263
+ "body": json.dumps({"from": sender, "to": rcpts, "subject": subject, "html": body})
264
+ }
265
+ # Same append convention as the HTTP capture path: one line, opened in append mode.
266
+ with open(OUT_FILE, "a", encoding="utf-8") as handle:
267
+ print(json.dumps(record), file=handle)
268
+ sender = ""
269
+ rcpts = []
270
+ smtp_reply(conn, "250 2.0.0 queued")
271
+ elif upper == "RSET":
272
+ sender = ""
273
+ rcpts = []
274
+ smtp_reply(conn, "250 2.0.0 ok")
275
+ elif upper == "QUIT":
276
+ smtp_reply(conn, "221 2.0.0 bye")
277
+ break
278
+ elif upper == "NOOP":
279
+ smtp_reply(conn, "250 2.0.0 ok")
280
+ else:
281
+ smtp_reply(conn, "250 2.0.0 ok")
282
+ try:
283
+ conn.close()
284
+ except Exception:
285
+ pass
286
+
287
+
288
+ def smtp_serve(port):
289
+ import socket
290
+
291
+ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
292
+ server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
293
+ server.bind(("127.0.0.1", port))
294
+ server.listen(16)
295
+ while True:
296
+ conn, _ = server.accept()
297
+ threading.Thread(target=smtp_session, args=(conn,), daemon=True).start()
298
+
299
+
300
+ if SMTP_PORT:
301
+ threading.Thread(target=lambda: smtp_serve(SMTP_PORT), daemon=True).start()
302
+
177
303
  ThreadingHTTPServer(("127.0.0.1", PORT), CaptureHandler).serve_forever()
178
304
  `;
179
305
  /** Readiness probe that asserts OUR service marker in the /health body (not merely any 2xx) — so a
@@ -208,6 +334,11 @@ export async function deployCommsCatch(desktop, options = {}) {
208
334
  if (inboxPort !== undefined && (!Number.isInteger(inboxPort) || inboxPort <= 0 || inboxPort > 65_535 || inboxPort === port)) {
209
335
  throw new Error(`deployCommsCatch: invalid inboxPort ${JSON.stringify(options.inboxPort)}`);
210
336
  }
337
+ const smtpPort = options.smtpPort === undefined ? undefined : Math.trunc(Number(options.smtpPort));
338
+ if (smtpPort !== undefined &&
339
+ (!Number.isInteger(smtpPort) || smtpPort <= 0 || smtpPort > 65_535 || smtpPort === port || smtpPort === inboxPort)) {
340
+ throw new Error(`deployCommsCatch: invalid smtpPort ${JSON.stringify(options.smtpPort)}`);
341
+ }
211
342
  const dir = options.dir ?? DEFAULT_CATCH_DIR;
212
343
  const name = options.name ?? "comms-catch";
213
344
  const requestTimeoutMs = options.requestTimeoutMs ?? 30_000;
@@ -218,7 +349,17 @@ export async function deployCommsCatch(desktop, options = {}) {
218
349
  await desktop.files.write(scriptPath, SANDBOX_CATCH_SCRIPT);
219
350
  await startDetachedProcess(desktop, {
220
351
  name,
221
- command: `python3 ${shq(scriptPath)} ${port} ${shq(deliveriesPath)} ${shq(surfaceDir)}${inboxPort === undefined ? "" : ` ${inboxPort}`}`,
352
+ command: [
353
+ "python3",
354
+ shq(scriptPath),
355
+ String(port),
356
+ shq(deliveriesPath),
357
+ shq(surfaceDir),
358
+ ...(inboxPort === undefined && smtpPort === undefined ? [] : [String(inboxPort ?? 0)]),
359
+ // The token slot is positional: an SMTP port cannot be reached without filling it. In-sandbox
360
+ // the capture listener is loopback-only, so an empty token is the same posture as before.
361
+ ...(smtpPort === undefined ? [] : ['""', String(smtpPort)])
362
+ ].join(" "),
222
363
  requestTimeoutMs
223
364
  });
224
365
  const probe = { timeoutMs: options.readyTimeoutMs ?? 15_000, requestTimeoutMs, ...(options.timers ?? {}) };
@@ -232,6 +373,7 @@ export async function deployCommsCatch(desktop, options = {}) {
232
373
  deliveriesPath,
233
374
  surfaceDir,
234
375
  ...(inboxPort === undefined ? {} : { inboxPort }),
376
+ ...(smtpPort === undefined ? {} : { smtpPort }),
235
377
  ready: ready && inboxReady
236
378
  };
237
379
  }
@@ -263,6 +405,86 @@ export async function drainCommsCatch(desktop, deployed, cursor = 0, requestTime
263
405
  }
264
406
  return { sends, cursor: lines.length };
265
407
  }
408
+ /**
409
+ * Parse an append-only deliveries NDJSON blob into raw sends. Split out of drainCommsCatch (#380) so
410
+ * the SAME parsing serves a sandbox we own (read over the E2B command channel) and a catch running on
411
+ * a plane we do not own (read from the local filesystem by `humanish comms catch`).
412
+ *
413
+ * A file that does not end in a newline may have a PARTIAL last line — a reader racing an append of a
414
+ * large body. Dropping it is never lossy: the script only ever emits valid JSON lines, so an incomplete
415
+ * line re-reads complete on the next pass.
416
+ */
417
+ export function parseDeliveriesNdjson(text) {
418
+ let lines = text.split("\n").filter((line) => line.trim().length > 0);
419
+ if (!text.endsWith("\n") && lines.length > 0)
420
+ lines = lines.slice(0, -1);
421
+ const sends = [];
422
+ for (const line of lines) {
423
+ try {
424
+ const parsed = JSON.parse(line);
425
+ if (typeof parsed.path === "string" && typeof parsed.body === "string") {
426
+ sends.push({ path: parsed.path, body: parsed.body, t: typeof parsed.t === "number" ? parsed.t : 0 });
427
+ }
428
+ }
429
+ catch {
430
+ // skip a malformed line
431
+ }
432
+ }
433
+ return sends;
434
+ }
435
+ /**
436
+ * The distinct `to` addresses the captured mail was actually sent to, parsed with the SAME profiles
437
+ * that route it. A lab run knows its recipients from the declared roster; a standalone catch does not,
438
+ * so it discovers them from the mail itself — otherwise an operator who forgot to name an address gets
439
+ * a technically-healthy catch rendering an empty inbox forever, which is the false-green class #380 is
440
+ * about.
441
+ */
442
+ export function capturedRecipientAddresses(sends, profiles = DEFAULT_EMAIL_PROFILES) {
443
+ const addresses = new Set();
444
+ for (const send of sends) {
445
+ let parsed;
446
+ try {
447
+ parsed = JSON.parse(send.body.length > 0 ? send.body : "{}");
448
+ }
449
+ catch {
450
+ continue;
451
+ }
452
+ const profile = profiles.find((candidate) => candidate.sendPaths.includes(send.path)) ?? profiles[0];
453
+ if (profile === undefined)
454
+ continue;
455
+ for (const normalized of profile.parse(send.path, parsed)) {
456
+ for (const address of normalized.to) {
457
+ if (address.trim().length > 0)
458
+ addresses.add(address);
459
+ }
460
+ }
461
+ }
462
+ return [...addresses];
463
+ }
464
+ /**
465
+ * Route raw sends into a FRESH FakeInbox and return the deduped, delivery-ordered messages. Split out
466
+ * of refreshInboxSurface (#380) so the rendering pipeline is shared by every transport; the freshness
467
+ * is what makes a full rebuild idempotent (a send is never routed twice, so no duplicate emails).
468
+ */
469
+ export async function inboxMessagesFrom(sends, recipients) {
470
+ const channel = new FakeInbox();
471
+ const inboxes = [];
472
+ for (const recipient of recipients)
473
+ inboxes.push(await channel.provisionAddress(recipient.lane, recipient.address));
474
+ await routeCapturedSends([...sends], channel);
475
+ const seen = new Set();
476
+ const messages = [];
477
+ for (const inbox of inboxes) {
478
+ for (const message of await channel.poll(inbox, 0)) {
479
+ if (seen.has(message.id))
480
+ continue;
481
+ seen.add(message.id);
482
+ messages.push(message);
483
+ }
484
+ }
485
+ messages.sort((a, b) => a.deliveredAt - b.deliveredAt || a.id.localeCompare(b.id));
486
+ return messages;
487
+ }
266
488
  /**
267
489
  * Parse drained raw sends with the host profiles and route them into the CommsChannel (the host-side
268
490
  * FakeInbox). Returns the number of inbox deliveries made. Same profiles as the host catch, so the
@@ -452,24 +674,9 @@ export async function refreshInboxSurface(args) {
452
674
  return { count: 0, rendered: false };
453
675
  if (args.sinceCount !== undefined && sends.length <= args.sinceCount)
454
676
  return { count: sends.length, rendered: false };
455
- const channel = new FakeInbox();
456
- const inboxes = [];
457
- for (const recipient of args.recipients)
458
- inboxes.push(await channel.provisionAddress(recipient.lane, recipient.address));
459
- await routeCapturedSends(sends, channel);
460
- const seen = new Set();
461
- const messages = [];
462
- for (const inbox of inboxes) {
463
- for (const message of await channel.poll(inbox, 0)) {
464
- if (seen.has(message.id))
465
- continue;
466
- seen.add(message.id);
467
- messages.push(message);
468
- }
469
- }
677
+ const messages = await inboxMessagesFrom(sends, args.recipients);
470
678
  if (messages.length === 0)
471
679
  return { count: sends.length, rendered: false };
472
- messages.sort((a, b) => a.deliveredAt - b.deliveredAt || a.id.localeCompare(b.id));
473
680
  await writeInboxSurface(args.desktop, args.deployed.surfaceDir, messages, {
474
681
  ...(args.originMap === undefined ? {} : { originMap: args.originMap }),
475
682
  ...(args.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: args.requestTimeoutMs })
@@ -1 +1 @@
1
- {"version":3,"file":"comms-sandbox-catch.js","sourceRoot":"","sources":["../src/comms-sandbox-catch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"comms-sandbox-catch.js","sourceRoot":"","sources":["../src/comms-sandbox-catch.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,wGAAwG;AACxG,uGAAuG;AACvG,qGAAqG;AACrG,qGAAqG;AACrG,qGAAqG;AACrG,oGAAoG;AACpG,4FAA4F;AAG5F,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAA4B,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAA2B,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAyB,MAAM,wBAAwB,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAuB,MAAM,mBAAmB,CAAC;AAG9E;;8EAE8E;AAC9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAC/C,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEhD,iDAAiD;AACjD,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0QnC,CAAC;AA2CF;0GAC0G;AAC1G,KAAK,UAAU,YAAY,CACzB,OAA0B,EAC1B,IAAY,EACZ,OAAyE;IAEzE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACzG,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAC3C,SAAS,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ;aAClC,GAAG,CAAC,yCAAyC,IAAI,6BAA6B,EAAE,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;aAC/H,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAAE,OAAO,IAAI,CAAC;QACxE,IAAI,GAAG,EAAE,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC;QACpC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA0B,EAC1B,UAAmC,EAAE;IAErC,kGAAkG;IAClG,sGAAsG;IACtG,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,0BAA0B,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACtG,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,MAAM,IAAI,SAAS,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5H,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnG,IACE,QAAQ,KAAK,SAAS;QACtB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,GAAG,MAAM,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC,EAClH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,iBAAiB,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,aAAa,CAAC;IAC3C,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,MAAM,CAAC;IAC5D,MAAM,UAAU,GAAG,GAAG,GAAG,WAAW,CAAC;IACrC,MAAM,cAAc,GAAG,GAAG,GAAG,oBAAoB,CAAC;IAClD,MAAM,UAAU,GAAG,GAAG,GAAG,UAAU,CAAC;IAEpC,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5F,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC5D,MAAM,oBAAoB,CAAC,OAAO,EAAE;QAClC,IAAI;QACJ,OAAO,EAAE;YACP,SAAS;YACT,GAAG,CAAC,UAAU,CAAC;YACf,MAAM,CAAC,IAAI,CAAC;YACZ,GAAG,CAAC,cAAc,CAAC;YACnB,GAAG,CAAC,UAAU,CAAC;YACf,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;YACtF,8FAA8F;YAC9F,0FAA0F;YAC1F,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;SAC5D,CAAC,IAAI,CAAC,GAAG,CAAC;QACX,gBAAgB;KACjB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,IAAI,MAAM,EAAE,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3G,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACvD,wGAAwG;IACxG,kFAAkF;IAClF,MAAM,UAAU,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAClG,OAAO;QACL,IAAI;QACJ,OAAO,EAAE,oBAAoB,IAAI,EAAE;QACnC,cAAc;QACd,UAAU;QACV,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;QACjD,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/C,KAAK,EAAE,KAAK,IAAI,UAAU;KAC3B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA0B,EAC1B,QAAoD,EACpD,MAAM,GAAG,CAAC,EACV,gBAAgB,GAAG,MAAM;IAEzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,sBAAsB,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC3H,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACxE,oGAAoG;IACpG,oGAAoG;IACpG,sGAAsG;IACtG,wEAAwE;IACxE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;YAC3D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,MAAM,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;YAC3D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,MAAM,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAiC,EACjC,WAA+B,sBAAsB;IAErD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrG,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC1D,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;oBAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAiC,EACjC,UAA4C;IAE5C,MAAM,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC;IAChC,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,SAAS,IAAI,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACpH,MAAM,kBAAkB,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAwB,EACxB,OAAqB,EACrB,WAA+B,sBAAsB;IAErD,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrG,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC1D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;gBACxC,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,EAAE,EAAE,UAAU,CAAC,EAAE;gBACjB,GAAG,CAAC,UAAU,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC5E,IAAI,EAAE,UAAU,CAAC,IAAI;aACtB,CAAC,CAAC;YACH,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAcD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAQxC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC3D,MAAM,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,KAAK,MAAM,OAAO,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,yFAAyF;YACzF,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACzE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,EAAE,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC5G,CAAC;AAYD,oFAAoF;AACpF,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAA4B,EAC5B,UAA0D,EAAE;IAE5D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE;YACxE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC;SACzD,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAA4B,EAC5B,MAAM,GAAG,CAAC,EACV,UAA0D,EAAE;IAE5D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE;QAC5E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC;QACxD,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9F,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wCAAwC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;YAC3D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,MAAM,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAOhD;IACC,MAAM,YAAY,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACpJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;IAChF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC3D,MAAM,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,KAAK,MAAM,OAAO,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACzE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,EAAE,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC5G,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA0B,EAC1B,UAAkB,EAClB,QAAwB,EACxB,UAA8D,EAAE;IAEhE,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,uFAAuF;IACvF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,KAAK,GAAG,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM,EAAE,CAAC,CAAC;IACjI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAQD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAOzC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7D,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACtH,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC3E,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE;QACxE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACtE,GAAG,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;KAC5F,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC"}
@@ -51,7 +51,7 @@ export interface CuaActorSessionOptions {
51
51
  /** FAIL-CLOSED spend cap (USD) threaded to the loop; absent = uncapped. See CuaLoopOptions.maxUsd. */
52
52
  maxUsd?: number;
53
53
  /** Injected pure per-turn cost estimator paired with `maxUsd`. See CuaLoopOptions.estimateTurnCostUsd. */
54
- estimateTurnCostUsd?: (input: number, output: number) => number | null;
54
+ estimateTurnCostUsd?: (input: number, output: number, cachedInput?: number) => number | null;
55
55
  /** RUNTIME-ONLY observed-URL callback threaded to the loop; see CuaLoopOptions.onObservedUrl. Used by
56
56
  * the concurrent shared-world handoff barrier to latch a host seat's live /lobby/CODE URL. */
57
57
  onObservedUrl?: (url: string | undefined) => void;
@@ -123,6 +123,7 @@ export interface CuaTurn {
123
123
  usage?: {
124
124
  input?: number;
125
125
  output?: number;
126
+ cachedInput?: number;
126
127
  };
127
128
  /** True when the model reported a natural endpoint (no further action). */
128
129
  done: boolean;
@@ -217,7 +218,7 @@ export interface CuaLoopOptions {
217
218
  * mid-run cannot trip the cap — preflight already guaranteed a rate exists, so a null here is a
218
219
  * vanished-rate harness condition, not a silent uncapped pass.
219
220
  */
220
- estimateTurnCostUsd?: (input: number, output: number) => number | null;
221
+ estimateTurnCostUsd?: (input: number, output: number, cachedInput?: number) => number | null;
221
222
  /**
222
223
  * RUNTIME-ONLY observed-URL callback (#164 handoff crux): invoked with `observation.url` right
223
224
  * after EVERY executor.observe() (the initial observe and each post-action observe), so the
@@ -253,6 +254,15 @@ export interface CuaLoopResult {
253
254
  reason: string;
254
255
  trace: ActorTrace;
255
256
  }
257
+ /**
258
+ * A public-safe fingerprint of ONE turn's actions, used only in memory to tell "trying the same
259
+ * thing again" from "trying something new" (#383).
260
+ *
261
+ * Never includes typed text or key contents — a `type` contributes its LENGTH, exactly as
262
+ * describeCuaAction does, so this can never become a keylogger. Coordinates are bucketed so that
263
+ * re-clicking the same control counts as a repeat while moving to a different control does not.
264
+ */
265
+ export declare function actionFingerprint(actions: readonly CuaAction[]): string;
256
266
  /**
257
267
  * A deterministic, bounded, sorted-key projection of an appState object, used as the friction
258
268
  * loop's progress key. Two structurally-equal states (regardless of key insertion order) map
@@ -268,6 +278,8 @@ export interface CuaLoopResult {
268
278
  export declare function stableProgressKey(appState: Record<string, unknown>): string;
269
279
  /** A public-safe one-line action label. Never includes raw typed text. */
270
280
  export declare function describeCuaAction(action: CuaAction): string;
281
+ /** Exported so the participant-vs-harness distinction is pinned directly, not inferred from a run. */
282
+ export declare function statusForCompletionReason(reason: ActorCompletionReason): ActorStatus;
271
283
  /**
272
284
  * Drive the computer-use loop to a single explicit completion and return an
273
285
  * ActorTrace. Every screenshot is redacted through the injected RedactionHooks
@@ -2,9 +2,54 @@ import { ACTOR_TRACE_SCHEMA } from "./actor-contract.js";
2
2
  import { classifyCuaAction, summarizeAffordanceUse } from "./affordance.js";
3
3
  import { commandFailureInfo, isCommandExitError } from "./command-failure.js";
4
4
  import { evaluateStopWhen } from "./stop-conditions.js";
5
- const DEFAULT_IDLE_STEPS = 6;
6
- const DEFAULT_NO_PROGRESS_STEPS = 8;
5
+ // Waiting is a legitimate strategy, not idleness. A persona told to sign up and verify by email
6
+ // polls its inbox — screenshot, wait, screenshot, wait — and at 6 steps that ended the session as
7
+ // `gave_up`/`failed` in well under a minute, before the mail could plausibly arrive. The concurrent
8
+ // shared-world route already overrode these to 80/40 for exactly this reason; the knowledge existed
9
+ // in the codebase and never reached the default every other route uses.
10
+ const DEFAULT_IDLE_STEPS = 24;
11
+ // The no-progress signal is much stronger since #383 (a stale frame alone no longer counts — the
12
+ // actor must also be repeating itself), so this needs less headroom than the raw idle count.
13
+ const DEFAULT_NO_PROGRESS_STEPS = 20;
7
14
  const IDLE_PROGRESS_FORGIVENESS_STEPS = 2;
15
+ /** How many recent turns the repetition check looks back over (#383). */
16
+ const ACTION_REPEAT_WINDOW = 3;
17
+ /** Click/scroll coordinates are bucketed to this many pixels before fingerprinting, so a one-pixel
18
+ * jitter between two otherwise identical clicks still reads as the same attempt. */
19
+ const ACTION_FINGERPRINT_BUCKET = 24;
20
+ /**
21
+ * A public-safe fingerprint of ONE turn's actions, used only in memory to tell "trying the same
22
+ * thing again" from "trying something new" (#383).
23
+ *
24
+ * Never includes typed text or key contents — a `type` contributes its LENGTH, exactly as
25
+ * describeCuaAction does, so this can never become a keylogger. Coordinates are bucketed so that
26
+ * re-clicking the same control counts as a repeat while moving to a different control does not.
27
+ */
28
+ export function actionFingerprint(actions) {
29
+ const bucket = (value) => Math.round(value / ACTION_FINGERPRINT_BUCKET);
30
+ return actions
31
+ .map((action) => {
32
+ switch (action.kind) {
33
+ case "click":
34
+ case "double_click":
35
+ case "move":
36
+ return `${action.kind}@${bucket(action.x)},${bucket(action.y)}`;
37
+ case "scroll":
38
+ return `scroll@${bucket(action.x)},${bucket(action.y)}:${Math.sign(action.dx)},${Math.sign(action.dy)}`;
39
+ case "type":
40
+ return `type:${action.text.length}`;
41
+ case "keypress":
42
+ return `keypress:${action.keys.join("+")}`;
43
+ case "drag":
44
+ return `drag:${action.path.length}`;
45
+ case "wait":
46
+ return "wait";
47
+ case "screenshot":
48
+ return "screenshot";
49
+ }
50
+ })
51
+ .join("|");
52
+ }
8
53
  function isIdleAction(action) {
9
54
  return action.kind === "screenshot" || action.kind === "wait";
10
55
  }
@@ -127,23 +172,28 @@ export function describeCuaAction(action) {
127
172
  return "screenshot";
128
173
  }
129
174
  }
130
- function statusForCompletion(reason) {
175
+ /** Exported so the participant-vs-harness distinction is pinned directly, not inferred from a run. */
176
+ export function statusForCompletionReason(reason) {
131
177
  switch (reason) {
132
178
  case "goal_satisfied":
133
179
  case "turn_completed": // turn_completed is a Codex-lane reason; this loop emits goal_satisfied
134
180
  return "passed";
135
- // Productive wall-clock stop: an open-ended watch session that reached the safety cap AFTER
136
- // material progress is a non-failure completion (ActorStatus has no "budget_reached" member; the
137
- // honest distinction lives in completionReason). This switch is exhaustive with no default, so a
138
- // new completion reason forces a compile error here until it is handled — the safety net that
139
- // guarantees budget_reached is mapped.
181
+ // A session that ran out of time or budget did not reach its goal, whatever it achieved along
182
+ // the way. Calling that `passed` is how a truncated study came to be reported as a green one —
183
+ // and why "raise the timeout" kept landing on the operator instead of on the tool. This switch
184
+ // is exhaustive with no default, so a new completion reason forces a compile error here.
140
185
  case "budget_reached":
141
- return "passed";
186
+ return "incomplete";
142
187
  case "timed_out":
143
188
  return "timed_out";
144
189
  case "blocked_approval":
145
190
  return "blocked";
191
+ // A participant who stopped trying is the single most valuable thing a usability study
192
+ // produces. Recording it as `failed` said the instrument broke, which is a different claim and
193
+ // a false one — see docs/principles/three-roles.md.
146
194
  case "gave_up":
195
+ return "abandoned";
196
+ // Only the harness failing is a harness failure.
147
197
  case "actor_error":
148
198
  case "step_failed": // step_failed is the scripted-browser lane's reason; this loop never emits it
149
199
  case "harness_error":
@@ -224,6 +274,8 @@ export async function runComputerUseLoop(options) {
224
274
  idleTurns: 0,
225
275
  noProgressTurns: 0
226
276
  };
277
+ // The last few turns' action fingerprints, in memory only, for the #383 corroboration rule.
278
+ const recentFingerprints = [];
227
279
  // Productivity signal for the wall-clock deadline: a session that took at least one material
228
280
  // (non-idle) action before the cap reached its BUDGET rather than stalling. A deadline hit with
229
281
  // zero material actions is still an honest failure (timed_out). Kept beside counts.materialActions
@@ -231,6 +283,7 @@ export async function runComputerUseLoop(options) {
231
283
  let materialActions = 0;
232
284
  let seq = 0;
233
285
  let usageInput = 0;
286
+ let usageCachedInput = 0;
234
287
  let usageOutput = 0;
235
288
  let sawUsage = false;
236
289
  let lastResponseId;
@@ -367,6 +420,7 @@ export async function runComputerUseLoop(options) {
367
420
  if (turn.usage) {
368
421
  sawUsage = true;
369
422
  usageInput += turn.usage.input ?? 0;
423
+ usageCachedInput += turn.usage.cachedInput ?? 0;
370
424
  usageOutput += turn.usage.output ?? 0;
371
425
  }
372
426
  // RUNTIME-ONLY: hand the model's narration back so the concurrent host-first barrier can read
@@ -391,7 +445,7 @@ export async function runComputerUseLoop(options) {
391
445
  // trips here before any action executes) — so it surfaces as "gave_up" (→ failed). Either way
392
446
  // the running estimate + the cap are cited so the operator sees WHY the loop stopped.
393
447
  if (maxUsd !== undefined && estimateTurnCostUsd) {
394
- const running = estimateTurnCostUsd(usageInput, usageOutput);
448
+ const running = estimateTurnCostUsd(usageInput, usageOutput, usageCachedInput);
395
449
  if (running !== null && running > maxUsd) {
396
450
  if (materialActions > 0) {
397
451
  completionReason = "budget_reached";
@@ -557,14 +611,35 @@ export async function runComputerUseLoop(options) {
557
611
  // Progress prefers the stable appState projection; a state executor with a constant
558
612
  // stateSignature still registers progress when its appState changed (and vice versa).
559
613
  const progressKey = progressKeyOf(observation);
560
- const progressed = progressKey !== lastSignature;
614
+ const frameChanged = progressKey !== lastSignature;
561
615
  lastSignature = progressKey;
616
+ // CORROBORATION (#383). A stale frame alone is NOT evidence of a stuck agent. The frame hash is
617
+ // a coarse whole-screen measure, and on a light-themed web app it can miss a renamed row, a new
618
+ // list item, or an opened panel — a measured run had 9 visibly different consecutive frames hash
619
+ // identically while the agent was a foreign key away from finishing. Ending a lane on that
620
+ // signal alone recorded working sessions as `gave_up`, capping every browser run at roughly
621
+ // noProgressSteps turns and writing harness artifacts into evidence as actor behavior.
622
+ //
623
+ // So a no-progress turn now requires BOTH a stale frame AND the agent repeating something it
624
+ // just tried. An agent doing varied work is never counted stuck, however blind the hash is;
625
+ // an agent re-clicking the same dead control trips it as fast as it did before — arguably
626
+ // faster, since that is the actual signature of being stuck.
627
+ const fingerprint = actionFingerprint(turn.actions);
628
+ const repeatingRecentAction = fingerprint.length > 0 && recentFingerprints.includes(fingerprint);
629
+ recentFingerprints.push(fingerprint);
630
+ if (recentFingerprints.length > ACTION_REPEAT_WINDOW)
631
+ recentFingerprints.shift();
632
+ // Corroboration governs the FRAME-STALENESS backstop only. The idle backstop below is a direct
633
+ // behavioral signal already (the agent took nothing but screenshots and waits), so it keeps
634
+ // reading the frame on its own — a repeated screenshot is exactly what an idle streak IS, and
635
+ // feeding repetition into it would grant an extra forgiveness step for being idle.
636
+ const progressed = frameChanged || !repeatingRecentAction;
562
637
  // A screenshot/wait turn while the UI visibly changes may be patience through loading or a
563
638
  // transition, so grant a bounded recovery window. Do not grant infinite immunity: animated
564
639
  // pixels or state-executor turn counters can otherwise keep a screenshot/wait loop alive
565
640
  // until the wall-clock timeout.
566
641
  if (idleThisTurn) {
567
- if (progressed && idleProgressForgivenessUsed < IDLE_PROGRESS_FORGIVENESS_STEPS) {
642
+ if (frameChanged && idleProgressForgivenessUsed < IDLE_PROGRESS_FORGIVENESS_STEPS) {
568
643
  idleProgressForgivenessUsed += 1;
569
644
  consecutiveIdle = 0;
570
645
  }
@@ -661,7 +736,7 @@ export async function runComputerUseLoop(options) {
661
736
  }
662
737
  }
663
738
  const completedAtMs = now();
664
- const status = statusForCompletion(completionReason);
739
+ const status = statusForCompletionReason(completionReason);
665
740
  const ids = {};
666
741
  if (provider.version !== undefined)
667
742
  ids.model = provider.version;
@@ -706,7 +781,18 @@ export async function runComputerUseLoop(options) {
706
781
  counts,
707
782
  items,
708
783
  ...(affordanceObservations.length > 0 ? { affordanceUse: summarizeAffordanceUse(affordanceObservations) } : {}),
709
- ...(sawUsage ? { tokenUsage: { input: usageInput, output: usageOutput, total: usageInput + usageOutput } } : {}),
784
+ ...(sawUsage
785
+ ? {
786
+ tokenUsage: {
787
+ input: usageInput,
788
+ output: usageOutput,
789
+ // Recorded only when the provider actually reported it, so a reader can tell "no cache
790
+ // hits" from "this provider does not say" (#391).
791
+ ...(usageCachedInput > 0 ? { cachedInput: usageCachedInput } : {}),
792
+ total: usageInput + usageOutput
793
+ }
794
+ }
795
+ : {}),
710
796
  capabilities: provider.capabilities
711
797
  };
712
798
  return { status, completionReason, reason, trace };