humanish 0.86.0 → 0.87.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 (55) hide show
  1. package/dist/actor-contract.d.ts +4 -0
  2. package/dist/actor-contract.js.map +1 -1
  3. package/dist/actor-stop-cause.d.ts +7 -0
  4. package/dist/actor-stop-cause.js +36 -0
  5. package/dist/actor-stop-cause.js.map +1 -0
  6. package/dist/computer-use.d.ts +1 -1
  7. package/dist/computer-use.js +15 -8
  8. package/dist/computer-use.js.map +1 -1
  9. package/dist/concurrent-shared-world-lab.d.ts +1 -1
  10. package/dist/concurrent-shared-world-lab.js +4 -0
  11. package/dist/concurrent-shared-world-lab.js.map +1 -1
  12. package/dist/cua-actor-lab.d.ts +1 -1
  13. package/dist/cua-actor-lab.js +9 -0
  14. package/dist/cua-actor-lab.js.map +1 -1
  15. package/dist/e2b-terminal-lab.d.ts +1 -1
  16. package/dist/e2b-terminal-lab.js +4 -0
  17. package/dist/e2b-terminal-lab.js.map +1 -1
  18. package/dist/export.js +1 -1
  19. package/dist/export.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/lab-config.d.ts +4 -0
  23. package/dist/lab-config.js +18 -0
  24. package/dist/lab-config.js.map +1 -1
  25. package/dist/lab-engine.js +24 -1
  26. package/dist/lab-engine.js.map +1 -1
  27. package/dist/observer-app.html +9 -9
  28. package/dist/observer-data.d.ts +5 -0
  29. package/dist/observer-data.js +27 -4
  30. package/dist/observer-data.js.map +1 -1
  31. package/dist/observer.d.ts +3 -1
  32. package/dist/observer.js +9 -6
  33. package/dist/observer.js.map +1 -1
  34. package/dist/openai-responses-cu.js +1 -1
  35. package/dist/openai-responses-cu.js.map +1 -1
  36. package/dist/oss-lab.d.ts +1 -1
  37. package/dist/oss-meta-lab.d.ts +1 -1
  38. package/dist/oss-meta-lab.js.map +1 -1
  39. package/dist/run.d.ts +6 -3
  40. package/dist/run.js +22 -7
  41. package/dist/run.js.map +1 -1
  42. package/dist/scripted-browser-lab.d.ts +1 -1
  43. package/dist/scripted-browser-lab.js +9 -0
  44. package/dist/scripted-browser-lab.js.map +1 -1
  45. package/dist/shared-world-lab.d.ts +1 -1
  46. package/dist/shared-world-lab.js +4 -0
  47. package/dist/shared-world-lab.js.map +1 -1
  48. package/docs/architecture/task-protocol-support.md +35 -0
  49. package/docs/contracts/run-bundle.md +17 -0
  50. package/docs/contracts/schemas.md +1 -1
  51. package/docs/goals/current.md +151 -717
  52. package/docs/ramp/README.md +11 -3
  53. package/docs/release/0.86.1-task-preflight-saved-recordings.md +40 -0
  54. package/docs/release/0.87.0-participant-endings-and-phone-review.md +64 -0
  55. package/package.json +3 -2
package/dist/run.d.ts CHANGED
@@ -937,7 +937,7 @@ export interface ParticipantOutcomes {
937
937
  reachedGoal: number;
938
938
  /** Stopped trying. A finding about the product. */
939
939
  abandoned: number;
940
- /** Ran out of session or budget before reaching the goal. */
940
+ /** Interrupted before reaching the goal, including session, spend and provider limits. */
941
941
  ranOut: number;
942
942
  /** Needed an approval the run could not give. */
943
943
  blocked: number;
@@ -1012,7 +1012,10 @@ export declare function aggregateTaskFunnels(funnels: readonly TaskFunnel[]): St
1012
1012
  /** The funnel as one line, denominator on every number: `signup 2/2 · verify-email 1/2`. */
1013
1013
  export declare function formatStudyTaskFunnel(funnel: StudyTaskFunnel): string;
1014
1014
  /** One line a stakeholder can read, with the denominator attached to every number. */
1015
- export declare function formatParticipantOutcomes(outcomes: ParticipantOutcomes): string;
1015
+ export declare function formatParticipantOutcomes(outcomes: ParticipantOutcomes, terminalCauses?: readonly {
1016
+ status: ActorStatus;
1017
+ label?: string;
1018
+ }[]): string;
1016
1019
  export declare function buildRunSource(args: {
1017
1020
  cwd: string;
1018
1021
  capturedAt?: Date | string;
@@ -1032,7 +1035,7 @@ export interface RunResult {
1032
1035
  latestPath?: string;
1033
1036
  warnings: string[];
1034
1037
  error?: {
1035
- code: "HUMANISH_ACTOR_FANOUT_UNIMPLEMENTED" | "HUMANISH_APP_URL_OPTION_CONFLICT" | "HUMANISH_BROWSER_APP_CAPTURE_FAILED" | "HUMANISH_CODEX_APP_SERVER_FAILED" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED" | "HUMANISH_LOCAL_CODEX_EXEC_FAILED" | "HUMANISH_LOCAL_CODEX_TUI_FAILED" | "HUMANISH_INVALID_APP_URL" | "HUMANISH_INVALID_ACTOR_CONCURRENCY" | "HUMANISH_INVALID_CWD" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_INVALID_TIMEOUT" | "HUMANISH_INVALID_PORT" | "HUMANISH_UNSUPPORTED_ACTOR" | "HUMANISH_UNSUPPORTED_RERUN_FLAGS" | "HUMANISH_WATCH_OPTION_CONFLICT" | "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
1038
+ code: "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_ACTOR_FANOUT_UNIMPLEMENTED" | "HUMANISH_APP_URL_OPTION_CONFLICT" | "HUMANISH_BROWSER_APP_CAPTURE_FAILED" | "HUMANISH_CODEX_APP_SERVER_FAILED" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED" | "HUMANISH_LOCAL_CODEX_EXEC_FAILED" | "HUMANISH_LOCAL_CODEX_TUI_FAILED" | "HUMANISH_INVALID_APP_URL" | "HUMANISH_INVALID_ACTOR_CONCURRENCY" | "HUMANISH_INVALID_CWD" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_INVALID_TIMEOUT" | "HUMANISH_INVALID_PORT" | "HUMANISH_UNSUPPORTED_ACTOR" | "HUMANISH_UNSUPPORTED_RERUN_FLAGS" | "HUMANISH_WATCH_OPTION_CONFLICT" | "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
1036
1039
  message: string;
1037
1040
  };
1038
1041
  }
package/dist/run.js CHANGED
@@ -138,21 +138,36 @@ export function formatStudyTaskFunnel(funnel) {
138
138
  .join(" · ");
139
139
  }
140
140
  /** One line a stakeholder can read, with the denominator attached to every number. */
141
- export function formatParticipantOutcomes(outcomes) {
141
+ export function formatParticipantOutcomes(outcomes, terminalCauses = []) {
142
142
  if (outcomes.total === 0)
143
143
  return "no participants reached a terminal state";
144
144
  const parts = [`${outcomes.reachedGoal}/${outcomes.total} reached the goal`];
145
- if (outcomes.abandoned > 0)
146
- parts.push(`${outcomes.abandoned} gave up`);
147
- if (outcomes.ranOut > 0)
148
- parts.push(`${outcomes.ranOut} ran out of session`);
145
+ // Detail may explain a recorded outcome, but must never change its count or invent a match
146
+ // between a tally and an incomplete set of traces.
147
+ const append = (count, statuses, fallback) => {
148
+ if (count === 0)
149
+ return;
150
+ const matching = terminalCauses.filter((entry) => statuses.includes(entry.status));
151
+ if (matching.length !== count) {
152
+ parts.push(`${count} ${fallback}`);
153
+ return;
154
+ }
155
+ const counts = new Map();
156
+ for (const entry of matching) {
157
+ const description = entry.label === undefined ? fallback : `interrupted (${entry.label})`;
158
+ counts.set(description, (counts.get(description) ?? 0) + 1);
159
+ }
160
+ for (const [description, n] of counts)
161
+ parts.push(`${n} ${description}`);
162
+ };
163
+ append(outcomes.abandoned, ["abandoned"], "gave up");
164
+ append(outcomes.ranOut, ["incomplete", "timed_out"], "interrupted (stop details unavailable)");
149
165
  // "blocked" covers an approval the run could not give AND a blocker the participant reported in
150
166
  // its own words (#476); the old "on an approval" read wrongly on a keyboard-first participant who
151
167
  // wrote "Blocked before diagram creation" about a mouse-only modal.
152
168
  if (outcomes.blocked > 0)
153
169
  parts.push(`${outcomes.blocked} blocked`);
154
- if (outcomes.harnessFailed > 0)
155
- parts.push(`${outcomes.harnessFailed} lost to a harness failure`);
170
+ append(outcomes.harnessFailed, ["failed"], "lost to a harness failure");
156
171
  // Last, and separate, because it cuts across the outcomes rather than partitioning them: someone
157
172
  // can reach the goal and still have found the road there broken.
158
173
  if (outcomes.reportedFriction > 0)