humanish 0.129.0 → 0.131.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 (53) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/actors/codex/restricted-participant.d.ts +2 -2
  3. package/dist/actors/codex/restricted-participant.js +3 -3
  4. package/dist/actors/computer-use/loop/actions.d.ts +17 -2
  5. package/dist/actors/computer-use/loop/actions.js +24 -5
  6. package/dist/actors/computer-use/loop/backstop.d.ts +9 -1
  7. package/dist/actors/computer-use/loop/backstop.js +4 -3
  8. package/dist/actors/computer-use/loop/clock.d.ts +4 -4
  9. package/dist/actors/computer-use/loop/clock.js +5 -5
  10. package/dist/actors/computer-use/loop/observation.d.ts +21 -2
  11. package/dist/actors/computer-use/loop/observation.js +50 -8
  12. package/dist/actors/computer-use/loop/trace.js +5 -1
  13. package/dist/actors/computer-use/loop/types.d.ts +30 -19
  14. package/dist/actors/computer-use/loop/watch.d.ts +42 -0
  15. package/dist/actors/computer-use/loop/watch.js +260 -0
  16. package/dist/actors/computer-use/loop.js +18 -4
  17. package/dist/actors/computer-use/wait.d.ts +36 -18
  18. package/dist/actors/computer-use/wait.js +51 -22
  19. package/dist/actors/contract.d.ts +34 -0
  20. package/dist/actors/local-agent/cli.js +5 -0
  21. package/dist/actors/stop-cause.d.ts +1 -1
  22. package/dist/analysis/automatic.js +0 -1
  23. package/dist/analysis/evidence-sources.d.ts +44 -7
  24. package/dist/analysis/evidence-sources.js +40 -6
  25. package/dist/analysis/evidence.js +96 -122
  26. package/dist/analysis/service.js +12 -6
  27. package/dist/analysis/source.d.ts +28 -0
  28. package/dist/analysis/source.js +118 -0
  29. package/dist/evidence/frame-change.d.ts +39 -0
  30. package/dist/evidence/frame-change.js +293 -0
  31. package/dist/feedback/export.js +0 -1
  32. package/dist/observer/data.d.ts +2 -2
  33. package/dist/observer-app.html +1 -1
  34. package/dist/run/bundle-shape.d.ts +2 -2
  35. package/dist/run/bundle.d.ts +8 -1
  36. package/dist/run/detail.js +4 -1
  37. package/dist/run/participant-records.d.ts +1 -1
  38. package/dist/run/stream-shape.d.ts +2 -2
  39. package/dist/run/stream-trace.d.ts +21 -7
  40. package/dist/run/stream-trace.js +42 -8
  41. package/dist/run/streams.d.ts +18 -0
  42. package/dist/study/bundle-estimate.d.ts +4 -1
  43. package/dist/study/bundle-estimate.js +40 -15
  44. package/dist/study/plan-participants.d.ts +1 -1
  45. package/dist/study/types.d.ts +11 -7
  46. package/dist/study/warnings.js +1 -1
  47. package/dist/verify/verify.js +28 -21
  48. package/docs/architecture/actor-contract.md +8 -0
  49. package/docs/architecture/browser-control.md +11 -9
  50. package/docs/contracts/run-bundle.md +2 -2
  51. package/docs/contracts/schemas.md +48 -8
  52. package/docs/contracts/study-analysis.md +13 -1
  53. package/package.json +1 -1
@@ -104,15 +104,17 @@ title, text, fractional scroll position and heard speech; those remain
104
104
  runtime-only under the existing loop contract. Arbitrary `appState` is refused
105
105
  because v1 has no closed schema for it. The protocol does not truncate strings,
106
106
  round coordinates, or silently drop unsupported state. A participant may ask for a
107
- longer wait than one request carries. The computer-use loop shortens it to the study's
108
- `actor.maxWaitMs` (by default two minutes, or 30 seconds on a desktop with speech, whose heard
109
- speech reaches the participant only with a screenshot), records a `wait shortened` notice with both
110
- durations when it does, and sends the rest as consecutive waits of at most 30 seconds. The Codex
111
- participant's `humanish_ui` schema leaves a wait's length open for that reason; the wire still
112
- refuses a single wait over 30 seconds. A wait that names no duration, as every OpenAI computer-use
113
- wait does, reaches the desktop with a length too: the study's `actor.idleWaitMs` (5 seconds by
114
- default) when the participant's turn only waits or takes screenshots, and 500 ms after an action in
115
- the same turn.
107
+ longer wait than one request carries. In a turn with another action, the computer-use loop
108
+ shortens it to the study's `actor.maxWaitMs` (by default two minutes, or 30 seconds on a desktop
109
+ with speech, whose heard speech reaches the participant only with a screenshot), records a `wait
110
+ shortened` notice with both durations when it does, and sends the rest as consecutive waits of at
111
+ most 30 seconds. The Codex participant's `humanish_ui` schema leaves a wait's length open for that
112
+ reason; the wire still refuses a single wait over 30 seconds. A wait that names no duration, as
113
+ every OpenAI computer-use wait does, reaches the desktop with a length too: 500 ms after an action
114
+ in the same turn. A turn that only waits or takes screenshots sends no wait to the desktop: the
115
+ loop observes the screen every `actor.idleWaitMs` until it changes or the wait's time passes
116
+ (`src/actors/computer-use/loop/watch.ts`), so a waiting participant costs one observe request per
117
+ look.
116
118
 
117
119
  Click, double-click, move, scroll and drag may carry `heldKeys`, which the
118
120
  OpenAI provider maps from its computer tool's `keys`. The Codex participant's
@@ -52,8 +52,8 @@ a run id or `latest`: it returns run.json with every trace file and live file jo
52
52
  as below, for v1, v2, v3 and v4 bundles, with each participant's per-request lists, and throws an Error named `StreamTraceRefusedError` for a
53
53
  file that does not match its index. Inside humanish, readers load a stream through
54
54
  `loadStreamTrace(runPaths, stream)`. A v1 stream returns as it is.
55
- An indexed stream's file is read under the 32 MiB per-file limit (analysis uses its 16 MiB
56
- source limit for each trace) and refused unless its size, sha256, item count and screenshot count
55
+ An indexed stream's file is read under the 32 MiB per-file limit, by analysis as by every other
56
+ reader, and refused unless its size, sha256, item count and screenshot count
57
57
  match the index. A trace or live file whose index records more than the limit is refused before it
58
58
  is read, and the refusal says the file is larger than humanish reads of one file and that
59
59
  restoring a copy does not help. A trace file whose index is under the limit and whose bytes are
@@ -263,8 +263,10 @@ The rest of this section names keys by their v3 spelling:
263
263
  the end, a turn that requests no action does not end the session: the trace records a
264
264
  `participant ended before its scheduled end` notice, the next request says the time left, and
265
265
  the turn counts toward the idle backstop. Before the end, a turn that only waits or takes
266
- screenshots counts toward neither backstop streak (`advanceBackstop`'s `waitingIsTheTask`). The
267
- plan entry carries `endAfterMs`, and `study check` prints a `windows` row;
266
+ screenshots counts toward neither backstop streak (`advanceBackstop`'s `waitingIsTheTask`). A
267
+ watch that reaches the end stops there with no further look, and a backstop streak that trips on
268
+ a turn reaching the end gives way to the end. The plan entry carries `endAfterMs`, and `study
269
+ check` prints a `windows` row;
268
270
  - `participants[].maxSessionMs` (computer-use only, also on `count:` groups): the longest the
269
271
  participant's session lasts, in whole milliseconds from 1 to 86,400,000, counted from the start
270
272
  of its own session. `windDownMs` applies to it as to `endAfterMs`. Refused: a value outside that
@@ -282,7 +284,9 @@ The rest of this section names keys by their v3 spelling:
282
284
  `cap=<duration>`;
283
285
  - `participants[].idleWaitMs` (computer-use and shared-world, also on `count:` groups): this
284
286
  participant's `actor.idleWaitMs`, in the same range and refused above an explicit
285
- `actor.maxWaitMs` (`waitLimitValidationReason`). Its trace records it in `waitSettings`;
287
+ `actor.maxWaitMs` (`waitLimitValidationReason`): how long its wait with no duration lasts in a
288
+ turn that only waits, and how often the loop looks at its screen while it watches such a turn.
289
+ Its trace records it in `waitSettings`;
286
290
  - `actor.clock.timeZone` (computer-use and shared-world): a tz database time zone name, such as `Europe/London`. Each turn's context hint carries
287
291
  the local time in it, and a scheduled end or session cap is given in it (UTC without it). On a hosted desktop the
288
292
  participant's browser launches with `TZ` set to it (`openParticipantSurface` in
@@ -1067,6 +1071,35 @@ Core-owned fields:
1067
1071
  click-like `ui_action` items, structured `coord` (`x`/`y`). Both are additive:
1068
1072
  absent on older bundles and non-stamping producers, and absence means
1069
1073
  "timing/position unrecorded", never zero
1074
+ - optional `items[].watch` (`ActorWatch` in `src/actors/contract.ts`), on the
1075
+ computer-use `ui_action` of the wait during which a watch ended. A turn whose
1076
+ actions are only waits and screenshots, and that asks for wait time, sends no
1077
+ wait to the desktop: the loop looks at the screen every `waitSettings.idleWaitMs`
1078
+ and requests the next turn when a change holds still, speech arrives, a
1079
+ `stopWhen` rule, `dwell.when` or task `success` rule matches a look, the
1080
+ participant's wind-down or end arrives, or the watch's time passes
1081
+ (`src/actors/computer-use/loop/watch.ts`). A change of more than 24 tiles of
1082
+ 16 pixels counts once it holds still at a look; one of 24 tiles or fewer once
1083
+ it has held still for more than 65 s with no tile within 4 tiles of it ticking
1084
+ or moving with a region of more than 24 tiles
1085
+ (`src/evidence/frame-change.ts`). The first watch lasts the turn's planned
1086
+ length: the named waits' lengths, together up to `actor.maxWaitMs` (else
1087
+ 600000), and `idleWaitMs` for each wait that names none. Each further one in a row that ended
1088
+ at its limit, or that a change of 24 tiles or fewer woke, lasts twice as long,
1089
+ up to the larger of its planned length and that cap. `limitMs` is how long it
1090
+ could last; `askedMs` is what the turn's waits asked for, the same sum with no
1091
+ cap, so it is above `limitMs` when the named waits passed the cap and below it
1092
+ when the watch grew; `wake` is `changed`, `speech`,
1093
+ `condition`, `limit`, `clock` (wind-down or end), `stalled` (a look got no
1094
+ frame; the next observation is a fresh one), or `stopped` (the study budget or
1095
+ the session's time ran out); `looks` counts its looks; `area` (`x`, `y`,
1096
+ `width`, `height` in pixels) bounds the change that woke it and is absent for
1097
+ other wakes and for a change still moving at the last look. A `notice` titled
1098
+ `watching the screen`, `lifecycle: started`, opens each watch. The turn's
1099
+ waits share the watch in order, in proportion to their planned lengths, and
1100
+ waits after the one carrying `watch` are titled `wait 0ms`. The look that
1101
+ ended a watch is the turn's `turn-NN` screenshot; other looks are not kept.
1102
+ Additive: absent on plain waits, other producers and older bundles
1070
1103
  - optional `items[].page` and `finalPage` (`{ origin, path }`, `TracePage` in
1071
1104
  `src/actors/contract.ts`): where a computer-use participant's browser was. The loop puts `page`
1072
1105
  on the `screenshot` item of each observation that read a URL: `turn-00-start` is the page before
@@ -1121,13 +1154,20 @@ Core-owned fields:
1121
1154
  `stopCause: provider_output_limit`.
1122
1155
  - optional `waitSettings`: the wait lengths a computer-use participant's session
1123
1156
  applied, in milliseconds, defaults included. `maxWaitMs` is the longest one
1124
- wait action lasts (`actor.maxWaitMs`); a longer wait is shortened to it.
1157
+ wait action lasts (`actor.maxWaitMs`, else 120000, or 30000 on a desktop with
1158
+ speech); in a turn with another action a longer wait is shortened to it.
1125
1159
  `idleWaitMs` is how long a wait that names no duration lasts in a turn that
1126
1160
  only waits or takes screenshots (`participants[].idleWaitMs`, else
1127
- `actor.idleWaitMs`), and `settleWaitMs` how
1128
- long such a wait lasts after an action in the same turn. Each `ui_action` for
1129
- a wait is titled with the length it lasted. Absent on other routes and on
1130
- earlier bundles
1161
+ `actor.idleWaitMs`), and the time between looks at the screen while the loop
1162
+ watches such a turn, at most 30000 on a desktop with speech. `settleWaitMs` is
1163
+ how long a wait that names no duration lasts after an action in the same turn,
1164
+ and the time to a watch's quick look after a large change. A watch's length
1165
+ grows to `actor.maxWaitMs`, else 600000, which `waitSettings` does not record;
1166
+ each watch's `watch.limitMs` does. The named waits of a turn that only waits
1167
+ are watched for their lengths, together up to that cap, past `maxWaitMs`. A wait sent to the desktop has a
1168
+ `ui_action` titled with its planned length, which a stalled wait keeps. A
1169
+ watched wait's `ui_action` is titled with the part of the watch it covered.
1170
+ Absent on other routes and on earlier bundles
1131
1171
  - optional `conversation`: how the first-party OpenAI computer-use provider
1132
1172
  carried the conversation between requests. `mode` is `threaded` (the server
1133
1173
  kept it through `previous_response_id`) or `explicit_context` (the server kept
@@ -183,7 +183,19 @@ stopped, an operator can remove the empty lock directory and retry.
183
183
 
184
184
  Each request's packet admits up to 16 participants, 800 evidence items, 40 PNG
185
185
  captures, 160 KiB of text and 20 MiB of images. Individual source files, image
186
- dimensions and result sizes have separate limits. Count and text budgets are
186
+ dimensions and result sizes have separate limits. Analysis reads run.json up to
187
+ 16 MiB and each participant's trace up to 32 MiB, as verify and the Observer do.
188
+ It reads the traces one at a time and keeps of each only what selection can
189
+ reach: the participant's share of its request's 800 evidence items, worked out
190
+ from run.json before any trace is read, and the first 80 captures selection may
191
+ read. Beside the one trace it is reading, analysis holds at most 800 entries for
192
+ each request and 80 for each participant; their size grows with each trace
193
+ item's text. A run.json past 16 MiB is refused as `ANALYSIS_SOURCE_TOO_LARGE`, and
194
+ a run.json or trace without the fields analysis reads as `ANALYSIS_SOURCE_INVALID`;
195
+ each message names the file, says why, and says no request was sent. Analysis
196
+ verifies the run before it reads a trace, so a trace that does not match its
197
+ index in run.json, or whose index records more than 32 MiB, fails verify and
198
+ `humanish analyze` reports `ANALYSIS_VERIFY_FAILED`. Count and text budgets are
187
199
  distributed across included participants, with unused capacity from short
188
200
  sessions available to longer ones. Reclaimed capture slots go first to eligible
189
201
  participants with fewer admitted images, including those deferred by their
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.129.0",
3
+ "version": "0.131.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",