humanish 0.120.0 → 0.120.1

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/CHANGELOG.md CHANGED
@@ -8,6 +8,18 @@ The Unreleased section holds the full notes for the next version until it is tag
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 0.120.1: Analysis requests under Bun run past 5 minutes (2026-10-09)
12
+
13
+ humanish 0.120.1 lets an analysis request from a Bun process run longer than 5 minutes. Under Bun,
14
+ `undici` is Bun's built-in module, whose `fetch` ignores the analysis provider's dispatcher and
15
+ ended each request after 300 seconds, so an analysis whose model took longer, as a 34-participant
16
+ run's cohort requests did at 325 to 405 seconds, failed with `analysis_provider_network_error`.
17
+ The provider now passes `timeout: false`, which Bun reads and Node's undici ignores, and the
18
+ request's own `timeoutMs` ends it under either runtime. A `TimeoutError` from `fetch` is recorded
19
+ as `provider_client_timeout`.
20
+
21
+ [Release notes](https://github.com/danielgwilson/humanish/releases/tag/v0.120.1)
22
+
11
23
  ## 0.120.0: Analysis completes under Bun, runs past 16 participants print a bounded list, Observer counts participants by status (2026-10-09)
12
24
 
13
25
  humanish 0.120.0 completes an analysis run from a Bun process, prints a run of more than 16
@@ -28,7 +28,7 @@ export interface AnalysisProviderResult {
28
28
  dispatched: boolean;
29
29
  /** Omitted preserves complete API-response accounting; account snapshots must state this. */
30
30
  usageComplete?: boolean;
31
- errorCode: "invalid_request" | "provider_http_error" | "provider_network_error" | "invalid_response" | "provider_headers_timeout" | "provider_body_timeout" | "provider_connect_timeout" | "provider_connection_reset" | "provider_dns_error" | "codex_busy" | "codex_unavailable" | "codex_unsupported_version" | "codex_incompatible_release" | "codex_unsupported_platform" | "codex_login_required" | "codex_unsupported_auth" | "codex_unsafe_configuration" | "codex_model_unavailable" | "codex_protocol_error" | "codex_tool_call" | "codex_process_failed" | "codex_cleanup_failed" | "response_too_large" | "output_incomplete" | "refusal" | "cancelled" | "timeout" | null;
31
+ errorCode: "invalid_request" | "provider_http_error" | "provider_network_error" | "invalid_response" | "provider_headers_timeout" | "provider_client_timeout" | "provider_body_timeout" | "provider_connect_timeout" | "provider_connection_reset" | "provider_dns_error" | "codex_busy" | "codex_unavailable" | "codex_unsupported_version" | "codex_incompatible_release" | "codex_unsupported_platform" | "codex_login_required" | "codex_unsupported_auth" | "codex_unsafe_configuration" | "codex_model_unavailable" | "codex_protocol_error" | "codex_tool_call" | "codex_process_failed" | "codex_cleanup_failed" | "response_too_large" | "output_incomplete" | "refusal" | "cancelled" | "timeout" | null;
32
32
  httpStatus?: number;
33
33
  /** Codex only: notification methods humanish does not know that carried no item, by count. */
34
34
  unknownNotifications?: Readonly<Record<string, number>>;
@@ -52,6 +52,11 @@ export type AnalysisFetch = (url: string, init: {
52
52
  headers: Record<string, string>;
53
53
  body: string;
54
54
  dispatcher: Dispatcher;
55
+ /**
56
+ * Bun's fetch ignores `dispatcher` and ends a request after 300 s unless this is false;
57
+ * Node's undici fetch ignores the field. The caller's timeoutMs governs either way.
58
+ */
59
+ timeout: false;
55
60
  }) => Promise<{
56
61
  ok: boolean;
57
62
  status: number;
@@ -34,6 +34,9 @@ function networkErrorCode(error) {
34
34
  const value = record(current);
35
35
  if (typeof value.code === "string" && Object.hasOwn(codes, value.code))
36
36
  return codes[value.code];
37
+ // Bun's fetch ends a request with a TimeoutError of its own, with no code.
38
+ if (value.name === "TimeoutError")
39
+ return "provider_client_timeout";
37
40
  current = value.cause;
38
41
  }
39
42
  return "provider_network_error";
@@ -177,6 +180,7 @@ export function createAnalysisProvider(options) {
177
180
  headers: { Authorization: `Bearer ${options.apiKey}`, "Content-Type": "application/json" },
178
181
  body,
179
182
  dispatcher,
183
+ timeout: false,
180
184
  });
181
185
  if (!response.ok) {
182
186
  // Never read provider error prose: it may echo evidence or credentials.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.120.0",
3
+ "version": "0.120.1",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",