humanish 0.141.0 → 0.142.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 (97) hide show
  1. package/ARCHITECTURE.md +1 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +2 -0
  4. package/dist/analysis/admission.d.ts +8 -0
  5. package/dist/analysis/admission.js +15 -4
  6. package/dist/analysis/automatic-config.d.ts +5 -2
  7. package/dist/analysis/automatic-config.js +23 -8
  8. package/dist/analysis/automatic.js +13 -7
  9. package/dist/analysis/execute.d.ts +17 -6
  10. package/dist/analysis/execute.js +36 -18
  11. package/dist/analysis/gemini-wire.d.ts +8 -0
  12. package/dist/analysis/gemini-wire.js +165 -0
  13. package/dist/analysis/image-tokens.d.ts +4 -2
  14. package/dist/analysis/image-tokens.js +24 -3
  15. package/dist/analysis/job.d.ts +1 -0
  16. package/dist/analysis/job.js +1 -0
  17. package/dist/analysis/openai-wire.d.ts +5 -0
  18. package/dist/analysis/openai-wire.js +101 -0
  19. package/dist/analysis/provider.d.ts +15 -7
  20. package/dist/analysis/provider.js +21 -101
  21. package/dist/analysis/responses.d.ts +3 -0
  22. package/dist/analysis/responses.js +19 -0
  23. package/dist/analysis/service.js +11 -3
  24. package/dist/analysis/types.d.ts +8 -2
  25. package/dist/analysis/validation.d.ts +1 -0
  26. package/dist/analysis/validation.js +13 -12
  27. package/dist/cli/commands/analyze.js +9 -7
  28. package/dist/cli/commands/observe.js +26 -1
  29. package/dist/cli/commands/run-command.d.ts +1 -1
  30. package/dist/cli/commands/run-command.js +12 -0
  31. package/dist/cli/commands/study-remote.d.ts +13 -0
  32. package/dist/cli/commands/study-remote.js +125 -0
  33. package/dist/cli/commands/study-route-computer-use.js +26 -2
  34. package/dist/cli/commands/study-route-scripted.js +1 -0
  35. package/dist/cli/commands/study-route-shared-world.js +1 -0
  36. package/dist/cli/commands/study-route-terminal.js +1 -0
  37. package/dist/cli/commands/study-run.js +34 -0
  38. package/dist/cli/commands/watch.js +5 -0
  39. package/dist/cli/doctor.js +7 -2
  40. package/dist/cli/findings.d.ts +8 -1
  41. package/dist/cli/findings.js +38 -15
  42. package/dist/cli/io.d.ts +8 -0
  43. package/dist/cli/io.js +2 -1
  44. package/dist/keys/key-resolution.d.ts +10 -0
  45. package/dist/keys/key-resolution.js +33 -5
  46. package/dist/observer/listen.d.ts +7 -2
  47. package/dist/observer/listen.js +10 -4
  48. package/dist/observer/render.d.ts +2 -0
  49. package/dist/observer/render.js +1 -1
  50. package/dist/observer-app.html +1 -1
  51. package/dist/remote/launch.d.ts +53 -0
  52. package/dist/remote/launch.js +320 -0
  53. package/dist/remote/observer-proxy.d.ts +11 -0
  54. package/dist/remote/observer-proxy.js +66 -0
  55. package/dist/remote/plan.d.ts +35 -0
  56. package/dist/remote/plan.js +114 -0
  57. package/dist/remote/reattach.d.ts +17 -0
  58. package/dist/remote/reattach.js +81 -0
  59. package/dist/remote/runner.d.ts +68 -0
  60. package/dist/remote/runner.js +216 -0
  61. package/dist/routes/computer-use/e2b-desktop/start.js +1 -1
  62. package/dist/routes/computer-use/types.d.ts +2 -0
  63. package/dist/routes/scripted/types.d.ts +2 -0
  64. package/dist/routes/shared-world/types.d.ts +2 -0
  65. package/dist/routes/terminal/types.d.ts +2 -0
  66. package/dist/run/costs.d.ts +2 -1
  67. package/dist/run/pricing.d.ts +13 -1
  68. package/dist/run/pricing.js +50 -4
  69. package/dist/run/results.d.ts +1 -1
  70. package/dist/run/run-cost.d.ts +2 -1
  71. package/dist/run/run-cost.js +6 -1
  72. package/dist/run/run.d.ts +13 -0
  73. package/dist/run/run.js +18 -7
  74. package/dist/run/sandbox-creates.d.ts +10 -3
  75. package/dist/run/sandbox-creates.js +48 -6
  76. package/dist/run-study.d.ts +5 -0
  77. package/dist/study/doctor.js +14 -1
  78. package/dist/study/requirements.d.ts +1 -1
  79. package/dist/study/requirements.js +8 -6
  80. package/dist/study/route-inputs.js +4 -0
  81. package/dist/study/run-study-events.d.ts +1 -1
  82. package/dist/study/run-study-events.js +9 -2
  83. package/dist/substrates/e2b/base-module.d.ts +3 -0
  84. package/dist/substrates/e2b/base-module.js +40 -0
  85. package/dist/substrates/e2b/desktop-browser.d.ts +1 -1
  86. package/dist/substrates/e2b/desktop-browser.js +24 -6
  87. package/dist/substrates/e2b/sdk.d.ts +24 -0
  88. package/dist/substrates/e2b/sdk.js +5 -1
  89. package/dist/substrates/e2b/shell-only.d.ts +5 -0
  90. package/dist/substrates/e2b/shell-only.js +27 -0
  91. package/dist/substrates/modal/sandbox.js +27 -28
  92. package/dist/substrates/modal/sdk.d.ts +7 -0
  93. package/dist/tui-app.js +46 -46
  94. package/docs/contracts/study-analysis.md +51 -3
  95. package/docs/product/automatic-analysis.md +26 -2
  96. package/package.json +2 -2
  97. package/skills/humanish/SKILL.md +10 -0
@@ -5,7 +5,8 @@ It is separate from the participant's account, recorded outcome, and the run's
5
5
  deterministic review verdict. Opening an Observer never starts a provider request.
6
6
  Supported live runs request analysis on completion by default. A study that declares no analyst
7
7
  gets the Codex account analyst when its participant is a Codex `local-agent`, and the OpenAI
8
- analyst with a separate $10 cap on its expected cost otherwise. Set `review.analysis: false` to
8
+ analyst with a separate $10 cap on its expected cost otherwise. A study can also select the
9
+ [Gemini API analyst](#gemini-api-analysis). Set `review.analysis: false` to
9
10
  disable that request; see [automatic analysis](../product/automatic-analysis.md).
10
11
 
11
12
  ## Invocation
@@ -117,6 +118,49 @@ the current merge instructions, billed $1.92, most of its input served from the
117
118
  provider's prompt cache, and each of its 466 citations resolved. Two runs do not
118
119
  calibrate the merge request's estimate.
119
120
 
121
+ ## Gemini API analysis
122
+
123
+ `review.analysis.provider: gemini`, or `analyze --provider gemini`, sends the same request to
124
+ Google's Gemini API:
125
+
126
+ ```bash
127
+ humanish keys set gemini
128
+ humanish analyze --run latest --provider gemini --max-cost 2 --dry-run --json
129
+ humanish analyze --run latest --provider gemini --model gemini-3.8-flash --max-cost 2 --json
130
+ ```
131
+
132
+ The request goes to `generativelanguage.googleapis.com/v1beta/models/<model>:generateContent`
133
+ with the key in the `x-goog-api-key` header. It carries the same instructions, packet and
134
+ captures, with each capture at `MEDIA_RESOLUTION_HIGH`, thinking level `HIGH`, one candidate,
135
+ the standard service tier, no tools and `store: false`. The key is `GEMINI_API_KEY` when set,
136
+ else `GOOGLE_API_KEY`. Google's client libraries prefer `GOOGLE_API_KEY`; humanish does not, so a
137
+ `GOOGLE_API_KEY` exported for another Google API never replaces the stored Gemini key. Key
138
+ discovery fills neither name while the other is already in the environment. Without either, the attempt ends with
139
+ `ANALYSIS_API_KEY_MISSING` and nothing is sent; the OpenAI key is never used.
140
+
141
+ The supported model is `gemini-3.8-flash`, the one with a completed live analysis. The other
142
+ Gemini models whose pages list image input and structured output join once a live analysis on
143
+ each completes. `--max-cost` is required, and admission, the cost cap, `--max-output-tokens`
144
+ (at most 32,768) and the partial result for a bill above the worst case work as on OpenAI.
145
+ Admission prices each capture at 1,120 tokens, the media-resolution guide's figure for a
146
+ high-resolution image, and expects twice the output it expects from OpenAI: one
147
+ `gemini-3.8-flash` analysis of one participant wrote 24,246 output tokens. Usage maps
148
+ `promptTokenCount` to input, `candidatesTokenCount` plus `thoughtsTokenCount` to output, and
149
+ `cachedContentTokenCount` to cached input; a usage record whose `totalTokenCount` disagrees
150
+ with those parts is kept as unknown. Rates are Google's paid standard tier. `gemini-3.8-flash`
151
+ has a published price change on 2027-01-01, and each request is priced at the rates of the day
152
+ it is sent. A free-tier key bills nothing, and Google's terms
153
+ let it use free-tier content to improve its products.
154
+
155
+ Gemini refuses the analysis schemas while they carry `maxItems`, so the request leaves those
156
+ array limits out of the schema and states them, by field path, at the end of the system
157
+ instruction. The response is still checked against the full schema. A `STOP` candidate
158
+ whose only non-thought part is the JSON answer completes. `MAX_TOKENS` and `CONTINUATION` end
159
+ as `output_incomplete`. A blocked prompt and the `SAFETY`, `RECITATION`, `LANGUAGE`,
160
+ `BLOCKLIST`, `PROHIBITED_CONTENT`, `SPII`, `ESCALATION` and image-safety finish reasons end as
161
+ `refusal`. Any other finish reason or answer shape ends as `invalid_response`. An HTTP error
162
+ keeps only its status code, which the attempt's warnings name.
163
+
120
164
  ## Codex account analysis
121
165
 
122
166
  A study whose participant is a Codex `local-agent` uses this analyst unless it declares another,
@@ -492,11 +536,15 @@ The states without findings:
492
536
  `analyze --max-cost 10`, which runs an analysis anyway. For a skip without `OPENAI_API_KEY`
493
537
  on a machine where Codex is signed in with a ChatGPT account (read when the view is built),
494
538
  `next` is `analyze --provider codex` and the message names `review.analysis.provider: codex`
495
- in the run's study file; otherwise the message says to set the key. For an analysis refused for its
539
+ in the run's study file; otherwise the message says to set the key. A study analyzed on Gemini
540
+ is skipped with `AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING`; its message names `keys set gemini`,
541
+ and `next` is `analyze --provider gemini --model <model> --max-cost 10`.
542
+ For an analysis refused for its
496
543
  cost, the message gives the expected cost, the worst case and the cap, and `next` sets
497
544
  `--max-cost` to the worst case rounded up.
498
545
  - `failed`: the latest attempt failed or was cancelled and no usable version exists. `next`
499
- reruns it with the same analyst, `--provider codex` for the Codex account analyst.
546
+ reruns it with the same analyst: `--provider codex` for the Codex account analyst, and
547
+ `--provider gemini --model <model>` for a Gemini one.
500
548
  - `none`: no analysis ran for this live run and nothing records why, for example a run that
501
549
  started from a library call, or one whose study file has moved or changed id.
502
550
  - `dry_run`: a dry run has no participant evidence to analyze. `next` is `run` with the run's own
@@ -50,7 +50,8 @@ allowance before deliberately choosing a larger budget. Explicit
50
50
  `maxOutputTokens` and `--max-output-tokens` limits are honored exactly. The output allowance
51
51
  includes reasoning as well as the report; exhausting it does not produce a usable
52
52
  report and never starts an automatic retry. Analysis
53
- sends selected retained text and captures to OpenAI using `OPENAI_API_KEY`.
53
+ sends selected retained text and captures to OpenAI using `OPENAI_API_KEY`, or to Google with
54
+ `provider: gemini`.
54
55
  Analysis runs in the humanish runner using its credentials. This setting adds no
55
56
  credential channel to the target application; each participant's route keeps
56
57
  its existing authentication boundary. Review the separate analysis budget before running a manifest live; an actor's
@@ -78,6 +79,27 @@ remain untested until a request. An omitted provider means this analyst for a Co
78
79
  `local-agent` participant on any target, and OpenAI for every other participant. This setting
79
80
  does not enable managed local desktops.
80
81
 
82
+ To use Google's Gemini API for the separate analyst:
83
+
84
+ ```yaml
85
+ review:
86
+ analysis:
87
+ provider: gemini
88
+ model: gemini-3.8-flash
89
+ maxCostUsd: 2
90
+ ```
91
+
92
+ Gemini analysis sends the same evidence packet and captures to Google, at high thinking level,
93
+ with each capture at high media resolution. It reads `GEMINI_API_KEY`, which `humanish keys set
94
+ gemini` stores, and `GOOGLE_API_KEY` only when `GEMINI_API_KEY` is unset. Key discovery treats
95
+ the two names as one key: a project's `.humanish/local/provider.env` or the user store never adds
96
+ one while the other is already in the environment. A missing Gemini key skips the analysis
97
+ (`AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING`); the OpenAI key is never used in its place. Admission,
98
+ `maxCostUsd`, `maxOutputTokens` and priced usage work as they do on OpenAI, at the paid-tier
99
+ rates in `src/run/pricing.ts`; requests made with a free-tier key bill nothing, and Google's
100
+ terms let it use free-tier content to improve its products. The supported model is
101
+ `gemini-3.8-flash`, the one with a completed live analysis.
102
+
81
103
  The same configuration works through `humanish run <study>`,
82
104
  `watch <study>`, and TUI live starts. Direct library calls to the five recording
83
105
  producers honor it too. Supported routes are computer-use, scripted-browser,
@@ -147,7 +169,8 @@ run's own result is ok, the first line of the human output reads
147
169
  command: with Codex signed in with a ChatGPT account it is `humanish analyze --run <id>
148
170
  --provider codex`, and the message names `review.analysis.provider: codex` as the setting that
149
171
  makes that analyst the study's; otherwise it says to set the key and names `humanish analyze
150
- --run <id> --max-cost 10`. So does a
172
+ --run <id> --max-cost 10`. A study analyzed on Gemini names `humanish keys set gemini` and
173
+ `humanish analyze --run <id> --provider gemini --model <model> --max-cost 10`. So does a
151
174
  default analysis whose expected cost, plus the margin, is over the default $10 cap:
152
175
  it is skipped with `AUTOMATIC_ANALYSIS_ADMISSION_REFUSED` and the run exits 0. For
153
176
  any analysis refused for its cost, the job records the expected cost, the worst
@@ -197,6 +220,7 @@ JSON also has `findings`:
197
220
  | `AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE` | `skipped` | This invocation published no run to analyze, or the run id is invalid |
198
221
  | `AUTOMATIC_ANALYSIS_SOURCE_CHANGED` | `failed` | The run directory changed after the run published its bundle |
199
222
  | `AUTOMATIC_ANALYSIS_KEY_MISSING` | `skipped` | No OpenAI API key |
223
+ | `AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING` | `skipped` | No Gemini API key for a study analyzed on Gemini |
200
224
  | `AUTOMATIC_ANALYSIS_NO_PARTICIPANT_EVIDENCE` | `skipped` | A default analysis found no participant evidence |
201
225
  | `AUTOMATIC_ANALYSIS_ACTOR_CANCELLED` | `skipped` | The harness cancelled the participants, or a signal stopped the run |
202
226
  | `AUTOMATIC_ANALYSIS_CLEANUP_UNCONFIRMED` | `skipped` | A local VM study could not confirm its cleanup; the command exits 2 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.141.0",
3
+ "version": "0.142.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",
@@ -96,7 +96,7 @@
96
96
  "comms:agentmail:contract": "node --import tsx scripts/agentmail-contract-check.mjs",
97
97
  "format": "oxfmt",
98
98
  "format:check": "oxfmt --check",
99
- "lint": "node scripts/check-lint-cap.mjs --max-warnings=411",
99
+ "lint": "node scripts/check-lint-cap.mjs --max-warnings=410",
100
100
  "knip": "knip",
101
101
  "prose:check": "node scripts/check-code-prose.mjs",
102
102
  "vocabulary:check": "tsx scripts/check-retired-words.ts",
@@ -108,6 +108,16 @@ not local inference or the participant's existing conversation. See
108
108
  [the analysis contract](../../docs/contracts/study-analysis.md) for the current
109
109
  CLI/model qualification and setup limits.
110
110
 
111
+ To analyze on Gemini, the user stores a key with `npx humanish keys set gemini`
112
+ (`GEMINI_API_KEY`; `GOOGLE_API_KEY` is read only when `GEMINI_API_KEY` is
113
+ unset), then sets `review.analysis: {provider: gemini, maxCostUsd: <n>}` or
114
+ passes `analyze --provider gemini --max-cost <n>`. The supported model is
115
+ `gemini-3.8-flash`. This sends the evidence packet and
116
+ captures to Google. Admission, the cost cap and priced usage work as on OpenAI,
117
+ and a missing Gemini key never falls back to OpenAI. On a free-tier key, Google
118
+ may use the content to improve its products; tell the user before a study with
119
+ private evidence runs on one.
120
+
111
121
  When post-run analysis is refused for its cost, the run output and `humanish
112
122
  review` give its expected cost, its worst case and the command that runs it,
113
123
  `humanish analyze --run <id> --max-cost <n>`. Show the user those costs and run