humanish 0.89.1 → 0.91.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.
- package/README.md +20 -1
- package/dist/automatic-analysis-completion.d.ts +25 -0
- package/dist/automatic-analysis-completion.js +56 -0
- package/dist/automatic-analysis-completion.js.map +1 -0
- package/dist/automatic-analysis-config.d.ts +25 -0
- package/dist/automatic-analysis-config.js +44 -0
- package/dist/automatic-analysis-config.js.map +1 -0
- package/dist/automatic-study-analysis.d.ts +15 -0
- package/dist/automatic-study-analysis.js +187 -0
- package/dist/automatic-study-analysis.js.map +1 -0
- package/dist/concurrent-shared-world-lab.d.ts +4 -2
- package/dist/concurrent-shared-world-lab.js +10 -3
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +4 -2
- package/dist/cua-actor-lab.js +10 -5
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.d.ts +4 -2
- package/dist/e2b-terminal-lab.js +15 -3
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/export-bundle.js +2 -0
- package/dist/export-bundle.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +5 -0
- package/dist/lab-config.js +21 -2
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.d.ts +2 -0
- package/dist/lab-engine.js +12 -3
- package/dist/lab-engine.js.map +1 -1
- package/dist/lab-preflight.d.ts +3 -0
- package/dist/lab-preflight.js +3 -0
- package/dist/lab-preflight.js.map +1 -1
- package/dist/lab-summary.d.ts +4 -0
- package/dist/lab-summary.js +6 -1
- package/dist/lab-summary.js.map +1 -1
- package/dist/observer-app.html +8 -8
- package/dist/observer.d.ts +3 -0
- package/dist/observer.js +23 -6
- package/dist/observer.js.map +1 -1
- package/dist/oss-lab.d.ts +1 -1
- package/dist/oss-lab.js.map +1 -1
- package/dist/oss-meta-lab.d.ts +1 -1
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.d.ts +5 -0
- package/dist/program.js +49 -8
- package/dist/program.js.map +1 -1
- package/dist/run-detail.d.ts +2 -0
- package/dist/run-detail.js +3 -0
- package/dist/run-detail.js.map +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-lab.d.ts +4 -2
- package/dist/scripted-browser-lab.js +14 -9
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/shared-world-lab.d.ts +4 -2
- package/dist/shared-world-lab.js +10 -3
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/study-analysis-engine.d.ts +7 -2
- package/dist/study-analysis-engine.js +26 -6
- package/dist/study-analysis-engine.js.map +1 -1
- package/dist/study-analysis-evidence.js +273 -59
- package/dist/study-analysis-evidence.js.map +1 -1
- package/dist/study-analysis-job.d.ts +88 -0
- package/dist/study-analysis-job.js +197 -0
- package/dist/study-analysis-job.js.map +1 -0
- package/dist/study-analysis-service.d.ts +10 -1
- package/dist/study-analysis-service.js +31 -8
- package/dist/study-analysis-service.js.map +1 -1
- package/dist/study-analysis-sharing.js +13 -5
- package/dist/study-analysis-sharing.js.map +1 -1
- package/dist/study-analysis-store.d.ts +4 -0
- package/dist/study-analysis-store.js +40 -1
- package/dist/study-analysis-store.js.map +1 -1
- package/dist/study-analysis-validation.d.ts +135 -1
- package/dist/study-analysis-validation.js +62 -26
- package/dist/study-analysis-validation.js.map +1 -1
- package/dist/study-analysis.d.ts +14 -0
- package/dist/study-analysis.js.map +1 -1
- package/dist/terminal-participant-activity.d.ts +6 -0
- package/dist/terminal-participant-activity.js +34 -0
- package/dist/terminal-participant-activity.js.map +1 -0
- package/dist/tui-actions.d.ts +1 -1
- package/dist/tui-actions.js +15 -1
- package/dist/tui-actions.js.map +1 -1
- package/dist/tui-app.js +116 -116
- package/dist/tui-contract.d.ts +3 -2
- package/dist/tui-contract.js.map +1 -1
- package/docs/architecture/examples/state-driven-local-app/README.md +5 -0
- package/docs/architecture/examples/state-driven-local-app/runner.mjs +1 -0
- package/docs/contracts/schemas.md +1 -1
- package/docs/contracts/study-analysis.md +47 -3
- package/docs/goals/current.md +4 -4
- package/docs/principles/invariants-and-defaults.md +7 -3
- package/docs/product/automatic-analysis.md +81 -0
- package/docs/ramp/README.md +11 -2
- package/docs/release/0.90.0-automatic-analysis.md +21 -0
- package/docs/release/0.91.0-analysis-quality-and-defaults.md +33 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,9 @@ npx humanish observe --run latest --open
|
|
|
50
50
|
|
|
51
51
|
Existing `E2B_API_KEY` and `OPENAI_API_KEY` environment variables also work.
|
|
52
52
|
`try-live` clones and studies drawDB, not your project. Its **$2 cap covers
|
|
53
|
-
estimated model spend
|
|
53
|
+
estimated participant model spend**. Post-run analysis defaults to a separate
|
|
54
|
+
**$3 admission estimate limit**; set `review.analysis: false` to disable it.
|
|
55
|
+
Hosted desktop time is additional. Participant caps are checked
|
|
54
56
|
between turns and are not provider billing ceilings. Allow a few minutes for
|
|
55
57
|
the app to build and the participant to work. See [budgets and privacy](https://humanish.dev/docs/budgets-and-privacy).
|
|
56
58
|
|
|
@@ -104,6 +106,23 @@ beside Participants in Observer, with evidence links and separate participant
|
|
|
104
106
|
feedback. See the [analysis contract](docs/contracts/study-analysis.md) for
|
|
105
107
|
coverage limits, estimated cost controls, corrections and sharing behavior.
|
|
106
108
|
|
|
109
|
+
Supported live studies generate findings automatically after participants finish,
|
|
110
|
+
using a separate $3 admission estimate limit with `gpt-6-astra` and high reasoning.
|
|
111
|
+
This is additional to participant execution costs, and is not a hard provider
|
|
112
|
+
billing cap. To disable the extra request:
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
review:
|
|
116
|
+
analysis: false
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`humanish run <lab>`, `humanish lab run <lab>`, `humanish watch <lab>`, and live
|
|
120
|
+
starts in the TUI share this default. Dry runs and unsupported routes dispatch
|
|
121
|
+
nothing. Without `OPENAI_API_KEY`, default analysis is skipped and a successful
|
|
122
|
+
recording stays successful. Opening the TUI or Observer never starts a request.
|
|
123
|
+
See [automatic analysis](docs/product/automatic-analysis.md) for configuration,
|
|
124
|
+
cancellation, and failure behavior.
|
|
125
|
+
|
|
107
126
|
## Public-Safety Boundary
|
|
108
127
|
|
|
109
128
|
Humanish is designed for public repositories and public issue queues. The
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type PreparedRunArtifactPaths } from "./run-paths.js";
|
|
2
|
+
import type { StudyAnalysisConfig } from "./study-analysis.js";
|
|
3
|
+
import { runAutomaticStudyAnalysis, type AutomaticStudyAnalysisDeps } from "./automatic-study-analysis.js";
|
|
4
|
+
import type { AutomaticStudyAnalysisOutcome } from "./study-analysis-job.js";
|
|
5
|
+
export interface AutomaticAnalysisHooks {
|
|
6
|
+
/** Provider/test dependencies apply only to analysis, never to the participant. */
|
|
7
|
+
deps?: AutomaticStudyAnalysisDeps;
|
|
8
|
+
/** Called after the source is finalized; the returned cleanup always runs. */
|
|
9
|
+
onStart?: () => void | (() => void);
|
|
10
|
+
run?: typeof runAutomaticStudyAnalysis;
|
|
11
|
+
}
|
|
12
|
+
export interface AutomaticAnalysisResult {
|
|
13
|
+
automaticAnalysis?: AutomaticStudyAnalysisOutcome;
|
|
14
|
+
/** Distinguishes the default missing-key skip from failure of an explicit request. */
|
|
15
|
+
automaticAnalysisTrigger?: "default" | "explicit";
|
|
16
|
+
}
|
|
17
|
+
/** Internal producer receipt: call only after final source publication, never for an early refusal. */
|
|
18
|
+
export declare function markFinalizedStudyResult<T extends object>(result: T, prepared: PreparedRunArtifactPaths): T;
|
|
19
|
+
/** One post-completion boundary shared by all live recording producers. */
|
|
20
|
+
export declare function completeAutomaticAnalysis<T extends {
|
|
21
|
+
cwd: string;
|
|
22
|
+
runId: string;
|
|
23
|
+
dryRun: boolean;
|
|
24
|
+
}>(result: T, config: StudyAnalysisConfig | undefined, hooks?: AutomaticAnalysisHooks, trigger?: "default" | "explicit"): Promise<T & AutomaticAnalysisResult>;
|
|
25
|
+
export declare function automaticAnalysisSucceeded(result: AutomaticAnalysisResult): boolean;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { validatePreparedRunRootIdentity } from "./run-paths.js";
|
|
3
|
+
import { runAutomaticStudyAnalysis } from "./automatic-study-analysis.js";
|
|
4
|
+
const finalizedResults = new WeakMap();
|
|
5
|
+
/** Internal producer receipt: call only after final source publication, never for an early refusal. */
|
|
6
|
+
export function markFinalizedStudyResult(result, prepared) {
|
|
7
|
+
finalizedResults.set(result, prepared);
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
/** One post-completion boundary shared by all live recording producers. */
|
|
11
|
+
export async function completeAutomaticAnalysis(result, config, hooks, trigger = "explicit") {
|
|
12
|
+
if (config === undefined)
|
|
13
|
+
return result;
|
|
14
|
+
const origin = trigger === "default" ? { automaticAnalysisTrigger: trigger } : {};
|
|
15
|
+
if (result.dryRun)
|
|
16
|
+
return { ...result, ...origin, automaticAnalysis: { state: "skipped", reason: "analysis_dry_run" } };
|
|
17
|
+
// An early refusal can echo a caller-supplied ID belonging to an older run.
|
|
18
|
+
// Require this invocation's internal final-publication receipt before reading that ID.
|
|
19
|
+
const prepared = finalizedResults.get(result);
|
|
20
|
+
if (!result.runId || result.runId === "not-created" || prepared === undefined) {
|
|
21
|
+
return { ...result, ...origin, automaticAnalysis: { state: "skipped", reason: "analysis_source_unavailable" } };
|
|
22
|
+
}
|
|
23
|
+
let cleanup = undefined;
|
|
24
|
+
try {
|
|
25
|
+
cleanup = hooks?.onStart?.();
|
|
26
|
+
try {
|
|
27
|
+
await validatePreparedRunRootIdentity(prepared);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return { ...result, ...origin, automaticAnalysis: { state: "failed", reason: "analysis_source_changed" } };
|
|
31
|
+
}
|
|
32
|
+
const sourceCwd = path.dirname(path.dirname(prepared.physicalRunsRoot));
|
|
33
|
+
const automaticAnalysis = await (hooks?.run ?? runAutomaticStudyAnalysis)(sourceCwd, result.runId, config, { ...hooks?.deps, ...(trigger === "default" ? { defaultRequest: true } : {}), expectedRun: prepared });
|
|
34
|
+
return { ...result, ...origin, automaticAnalysis };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Preserve the producer result. Never put a hook exception or provider response in the envelope.
|
|
38
|
+
return { ...result, ...origin, automaticAnalysis: { state: "failed", reason: "analysis_automatic_failed" } };
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
try {
|
|
42
|
+
cleanup?.();
|
|
43
|
+
}
|
|
44
|
+
catch { /* Cleanup cannot erase accounting or the completed recording. */ }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function automaticAnalysisSucceeded(result) {
|
|
48
|
+
const value = result.automaticAnalysis;
|
|
49
|
+
if (value === undefined)
|
|
50
|
+
return true;
|
|
51
|
+
if (value.state === "skipped")
|
|
52
|
+
return value.reason === "analysis_dry_run"
|
|
53
|
+
|| (result.automaticAnalysisTrigger === "default" && ["AUTOMATIC_ANALYSIS_KEY_MISSING", "AUTOMATIC_ANALYSIS_NO_PARTICIPANT_EVIDENCE"].includes(value.reason ?? ""));
|
|
54
|
+
return (value.state === "complete" || value.state === "partial") && value.result?.ok === true;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=automatic-analysis-completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-analysis-completion.js","sourceRoot":"","sources":["../src/automatic-analysis-completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StudyAnalysisConfig } from "./study-analysis.js";
|
|
2
|
+
/** A separately budgeted review after a live participant study. */
|
|
3
|
+
export interface LabAnalysis {
|
|
4
|
+
maxCostUsd: number;
|
|
5
|
+
model?: string;
|
|
6
|
+
question?: string;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
maxOutputTokens?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Called for parsed manifests AND direct library configs, before participant execution. */
|
|
11
|
+
export declare function resolveAutomaticAnalysis(raw: unknown): {
|
|
12
|
+
ok: true;
|
|
13
|
+
config: StudyAnalysisConfig | undefined;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
message: string;
|
|
17
|
+
};
|
|
18
|
+
export interface AutomaticAnalysisBudget {
|
|
19
|
+
model: string;
|
|
20
|
+
maxCostUsd: number;
|
|
21
|
+
trigger: "default" | "explicit";
|
|
22
|
+
}
|
|
23
|
+
/** Metadata only: resolving the future live-run budget never reads keys or dispatches. */
|
|
24
|
+
export declare function automaticAnalysisBudget(raw: unknown, backend: string): AutomaticAnalysisBudget | undefined;
|
|
25
|
+
export declare function formatAutomaticAnalysisBudget(budget: AutomaticAnalysisBudget): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SUPPORTED_STUDY_ANALYSIS_MODELS } from "./study-analysis-engine.js";
|
|
2
|
+
import { containsSensitive } from "./redaction.js";
|
|
3
|
+
const MODELS = new Set(SUPPORTED_STUDY_ANALYSIS_MODELS);
|
|
4
|
+
const FIELDS = new Set(["maxCostUsd", "model", "question", "timeoutMs", "maxOutputTokens"]);
|
|
5
|
+
/** Called for parsed manifests AND direct library configs, before participant execution. */
|
|
6
|
+
export function resolveAutomaticAnalysis(raw) {
|
|
7
|
+
if (raw === false)
|
|
8
|
+
return { ok: true, config: undefined };
|
|
9
|
+
if (raw === undefined)
|
|
10
|
+
raw = { maxCostUsd: 3 };
|
|
11
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)
|
|
12
|
+
|| Object.keys(raw).some(key => !FIELDS.has(key))) {
|
|
13
|
+
return { ok: false, message: "review.analysis must be false or a mapping containing only maxCostUsd, model, question, timeoutMs and maxOutputTokens." };
|
|
14
|
+
}
|
|
15
|
+
const value = raw;
|
|
16
|
+
const { maxCostUsd } = value;
|
|
17
|
+
const model = value.model === undefined ? "gpt-6-astra" : value.model;
|
|
18
|
+
const question = value.question === undefined ? null : value.question;
|
|
19
|
+
const timeoutMs = value.timeoutMs === undefined ? 300_000 : value.timeoutMs;
|
|
20
|
+
const maxOutputTokens = value.maxOutputTokens === undefined ? 16_384 : value.maxOutputTokens;
|
|
21
|
+
if (typeof maxCostUsd !== "number" || !Number.isFinite(maxCostUsd) || maxCostUsd <= 0 || maxCostUsd > 1000
|
|
22
|
+
|| typeof model !== "string" || !MODELS.has(model)
|
|
23
|
+
|| typeof timeoutMs !== "number" || !Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 600_000
|
|
24
|
+
|| typeof maxOutputTokens !== "number" || !Number.isSafeInteger(maxOutputTokens) || maxOutputTokens < 256 || maxOutputTokens > 32_768
|
|
25
|
+
|| (value.question !== undefined && (typeof question !== "string" || question.length > 4000))) {
|
|
26
|
+
return { ok: false, message: "review.analysis requires a positive maxCostUsd up to 1000, a supported analysis model, timeoutMs 1–600000, maxOutputTokens 256–32768, and an optional question of at most 4000 characters." };
|
|
27
|
+
}
|
|
28
|
+
if (question !== null && containsSensitive(question)) {
|
|
29
|
+
return { ok: false, message: "review.analysis.question contains sensitive text and cannot be sent for analysis." };
|
|
30
|
+
}
|
|
31
|
+
return { ok: true, config: { model, maxCostUsd, timeoutMs, maxOutputTokens, question: question } };
|
|
32
|
+
}
|
|
33
|
+
/** Metadata only: resolving the future live-run budget never reads keys or dispatches. */
|
|
34
|
+
export function automaticAnalysisBudget(raw, backend) {
|
|
35
|
+
if (!["cua", "scripted", "terminal", "shared-world", "concurrent-shared-world"].includes(backend))
|
|
36
|
+
return undefined;
|
|
37
|
+
const resolved = resolveAutomaticAnalysis(raw);
|
|
38
|
+
return resolved.ok && resolved.config ? { model: resolved.config.model, maxCostUsd: resolved.config.maxCostUsd,
|
|
39
|
+
trigger: raw === undefined ? "default" : "explicit" } : undefined;
|
|
40
|
+
}
|
|
41
|
+
export function formatAutomaticAnalysisBudget(budget) {
|
|
42
|
+
return `After live runs: ${budget.trigger} analysis · ${budget.model} · separate $${budget.maxCostUsd} admission estimate limit (not a provider billing cap). Set review.analysis: false to disable.`;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=automatic-analysis-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-analysis-config.js","sourceRoot":"","sources":["../src/automatic-analysis-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type AnalyzeDeps } from "./study-analysis-service.js";
|
|
2
|
+
import { type AutomaticStudyAnalysisView, type AutomaticStudyAnalysisOutcome, type AutomaticStudyAnalysisCancellation } from "./study-analysis-job.js";
|
|
3
|
+
import type { StudyAnalysisConfig } from "./study-analysis.js";
|
|
4
|
+
export type { AutomaticStudyAnalysisView, AutomaticStudyAnalysisOutcome, AutomaticStudyAnalysisCancellation } from "./study-analysis-job.js";
|
|
5
|
+
export type AutomaticStudyAnalysisDeps = Omit<AnalyzeDeps, "analysisId" | "beforeDispatch"> & {
|
|
6
|
+
/** A missing default key records a skip before admission, preserving a successful recording. */
|
|
7
|
+
defaultRequest?: boolean;
|
|
8
|
+
};
|
|
9
|
+
/** Small read-only TUI/CLI projection. Neither this nor Observer can resume a job. */
|
|
10
|
+
export declare function readAutomaticStudyAnalysis(cwd: string, runId: string): Promise<AutomaticStudyAnalysisView | undefined>;
|
|
11
|
+
export declare function requestAutomaticStudyAnalysisCancellation(cwd: string, runId: string): Promise<AutomaticStudyAnalysisCancellation>;
|
|
12
|
+
/** One permanent claim per completed run, consumed even when preparation/cancellation fails.
|
|
13
|
+
* Only the original producer calls this after all recording writes return.
|
|
14
|
+
* No file reader, restart recovery, Observer poll or export calls this function. */
|
|
15
|
+
export declare function runAutomaticStudyAnalysis(cwdInput: string, runId: string, configInput: StudyAnalysisConfig, deps?: AutomaticStudyAnalysisDeps): Promise<AutomaticStudyAnalysisOutcome>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { renderObserver } from "./observer.js";
|
|
3
|
+
import { resolveRunPath } from "./run.js";
|
|
4
|
+
import { analyzeStudy, readCompletedStudyAnalysisSource, resolveStudyAnalysisRun } from "./study-analysis-service.js";
|
|
5
|
+
import { STUDY_ANALYSIS_PROMPT_VERSION } from "./study-analysis-engine.js";
|
|
6
|
+
import { hashStudyAnalysisValue } from "./study-analysis-validation.js";
|
|
7
|
+
import { claimAutomaticStudyAnalysis, readAutomaticStudyAnalysisPrepared, requestAutomaticStudyAnalysisCancellationPrepared } from "./study-analysis-job.js";
|
|
8
|
+
import { readStudyAnalysisExecution, readStudyAnalysisVersion } from "./study-analysis-store.js";
|
|
9
|
+
const exactId = (runId) => runId !== "latest" && /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(runId);
|
|
10
|
+
const skipped = (reason) => ({ state: "skipped", reason });
|
|
11
|
+
function hasParticipantEvidence(bundle) {
|
|
12
|
+
return bundle.streams.some(stream => {
|
|
13
|
+
// Terminal commands and transcript messages also include launcher output.
|
|
14
|
+
// Fresh producers count recognized participant runtime items separately.
|
|
15
|
+
if (stream.actor?.lane === "terminal")
|
|
16
|
+
return (stream.actor.counts.runtimeParticipantItems ?? 0) > 0;
|
|
17
|
+
return stream.actor?.items.some(item => ["screenshot", "ui_action", "command", "tool_call", "file_change", "approval"].includes(item.kind)
|
|
18
|
+
|| (["message", "reasoning"].includes(item.kind) && !!item.text?.trim()));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** Small read-only TUI/CLI projection. Neither this nor Observer can resume a job. */
|
|
22
|
+
export async function readAutomaticStudyAnalysis(cwd, runId) {
|
|
23
|
+
if (!exactId(runId))
|
|
24
|
+
return undefined;
|
|
25
|
+
const prepared = await resolveRunPath(path.resolve(cwd), runId).catch(() => null);
|
|
26
|
+
return prepared ? readAutomaticStudyAnalysisPrepared(prepared) : undefined;
|
|
27
|
+
}
|
|
28
|
+
export async function requestAutomaticStudyAnalysisCancellation(cwd, runId) {
|
|
29
|
+
if (!exactId(runId))
|
|
30
|
+
return { requested: false, reason: "AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE" };
|
|
31
|
+
const prepared = await resolveRunPath(path.resolve(cwd), runId).catch(() => null);
|
|
32
|
+
return prepared ? requestAutomaticStudyAnalysisCancellationPrepared(prepared)
|
|
33
|
+
: { requested: false, reason: "AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE" };
|
|
34
|
+
}
|
|
35
|
+
function outcomeOf(result) {
|
|
36
|
+
if (result.error?.code === "ANALYSIS_PUBLICATION_FAILED")
|
|
37
|
+
return { state: "failed", reason: "AUTOMATIC_ANALYSIS_PUBLICATION_FAILED", result };
|
|
38
|
+
if (result.status)
|
|
39
|
+
return { state: result.status, result, reason: result.reused ? "AUTOMATIC_ANALYSIS_REUSED"
|
|
40
|
+
: result.status === "partial" ? (result.error?.code === "analysis_admission_estimate_exceeded"
|
|
41
|
+
? "AUTOMATIC_ANALYSIS_ADMISSION_EXCEEDED" : result.ok ? "AUTOMATIC_ANALYSIS_LIMITATIONS" : "AUTOMATIC_ANALYSIS_FAILED")
|
|
42
|
+
: result.status === "failed" ? "AUTOMATIC_ANALYSIS_FAILED"
|
|
43
|
+
: result.status === "cancelled" ? "AUTOMATIC_ANALYSIS_CANCELLED" : null };
|
|
44
|
+
const code = result.error?.code;
|
|
45
|
+
if (code === "ANALYSIS_CANCELLED")
|
|
46
|
+
return { state: "cancelled", reason: "AUTOMATIC_ANALYSIS_CANCELLED", result };
|
|
47
|
+
if (code === "ANALYSIS_API_KEY_MISSING")
|
|
48
|
+
return { ...skipped("AUTOMATIC_ANALYSIS_KEY_MISSING"), result };
|
|
49
|
+
if (code === "ANALYSIS_BUSY")
|
|
50
|
+
return { ...skipped("AUTOMATIC_ANALYSIS_BUSY"), result };
|
|
51
|
+
if (code === "ANALYSIS_HISTORY_UNAVAILABLE")
|
|
52
|
+
return { ...skipped("AUTOMATIC_ANALYSIS_STORAGE_UNAVAILABLE"), result };
|
|
53
|
+
if (code === "ANALYSIS_CONFIG_INVALID" || code === "ANALYSIS_QUESTION_UNSAFE" || code?.startsWith("analysis_")) {
|
|
54
|
+
return { ...skipped("AUTOMATIC_ANALYSIS_ADMISSION_REFUSED"), result };
|
|
55
|
+
}
|
|
56
|
+
return { state: "unknown", reason: "AUTOMATIC_ANALYSIS_OUTCOME_UNKNOWN", result };
|
|
57
|
+
}
|
|
58
|
+
/** One permanent claim per completed run, consumed even when preparation/cancellation fails.
|
|
59
|
+
* Only the original producer calls this after all recording writes return.
|
|
60
|
+
* No file reader, restart recovery, Observer poll or export calls this function. */
|
|
61
|
+
export async function runAutomaticStudyAnalysis(cwdInput, runId, configInput, deps = {}) {
|
|
62
|
+
if (!exactId(runId))
|
|
63
|
+
return skipped("AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE");
|
|
64
|
+
let cwd = path.resolve(cwdInput);
|
|
65
|
+
const prepared = await resolveStudyAnalysisRun(cwd, runId, deps.expectedRun).catch(() => null);
|
|
66
|
+
if (!prepared)
|
|
67
|
+
return skipped("AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE");
|
|
68
|
+
cwd = path.dirname(path.dirname(prepared.physicalRunsRoot));
|
|
69
|
+
let participantEvidence = false;
|
|
70
|
+
// Do not consume a future run's one claim while a producer is still writing it.
|
|
71
|
+
try {
|
|
72
|
+
const bytes = await readCompletedStudyAnalysisSource(cwd, prepared);
|
|
73
|
+
const bundle = JSON.parse(bytes.toString("utf8"));
|
|
74
|
+
if (bundle.streams.some(stream => stream.actor?.stopCause === "harness_aborted"))
|
|
75
|
+
return skipped("AUTOMATIC_ANALYSIS_ACTOR_CANCELLED");
|
|
76
|
+
participantEvidence = hasParticipantEvidence(bundle);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return skipped("AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE");
|
|
80
|
+
}
|
|
81
|
+
const config = structuredClone(configInput);
|
|
82
|
+
let job;
|
|
83
|
+
try {
|
|
84
|
+
const claimed = await claimAutomaticStudyAnalysis(prepared, { configDigest: hashStudyAnalysisValue(config), promptVersion: STUDY_ANALYSIS_PROMPT_VERSION });
|
|
85
|
+
if (!claimed)
|
|
86
|
+
return skipped("AUTOMATIC_ANALYSIS_ALREADY_REQUESTED");
|
|
87
|
+
job = claimed;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { state: "unknown", reason: "AUTOMATIC_ANALYSIS_STORAGE_UNAVAILABLE" };
|
|
91
|
+
}
|
|
92
|
+
const controller = new AbortController();
|
|
93
|
+
const signal = deps.signal ? AbortSignal.any([deps.signal, controller.signal]) : controller.signal;
|
|
94
|
+
let polling = false;
|
|
95
|
+
let storageFailed = false;
|
|
96
|
+
let cancellationFailed = false;
|
|
97
|
+
const poll = async () => {
|
|
98
|
+
if (polling)
|
|
99
|
+
return;
|
|
100
|
+
polling = true;
|
|
101
|
+
try {
|
|
102
|
+
if (await job.cancellationRequested())
|
|
103
|
+
controller.abort();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
cancellationFailed = true;
|
|
107
|
+
controller.abort();
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
polling = false;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const cancellationTimer = setInterval(() => { void poll(); }, 250);
|
|
114
|
+
cancellationTimer.unref();
|
|
115
|
+
const heartbeat = setInterval(() => {
|
|
116
|
+
void job.touch().catch(() => { storageFailed = true; controller.abort(); });
|
|
117
|
+
}, 5000);
|
|
118
|
+
heartbeat.unref();
|
|
119
|
+
let outcome;
|
|
120
|
+
try {
|
|
121
|
+
await poll();
|
|
122
|
+
const missingKey = !(deps.apiKey ?? process.env.OPENAI_API_KEY)?.trim();
|
|
123
|
+
if (deps.defaultRequest === true && (missingKey || !participantEvidence)) {
|
|
124
|
+
outcome = signal.aborted ? { state: "cancelled", reason: "AUTOMATIC_ANALYSIS_CANCELLED" }
|
|
125
|
+
: skipped(missingKey ? "AUTOMATIC_ANALYSIS_KEY_MISSING" : "AUTOMATIC_ANALYSIS_NO_PARTICIPANT_EVIDENCE");
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const result = await analyzeStudy(cwd, runId, { config }, {
|
|
129
|
+
...deps, signal, expectedRun: prepared, analysisId: job.attemptId,
|
|
130
|
+
beforeDispatch: async (context) => {
|
|
131
|
+
if (await job.cancellationRequested())
|
|
132
|
+
controller.abort();
|
|
133
|
+
if (signal.aborted)
|
|
134
|
+
return;
|
|
135
|
+
await job.update({ state: "running", analysisId: context.id, startedAt: new Date().toISOString(),
|
|
136
|
+
sourceRunSha256: context.sourceRunSha256, inputDigest: context.inputDigest });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
outcome = outcomeOf(result);
|
|
140
|
+
}
|
|
141
|
+
if (cancellationFailed)
|
|
142
|
+
outcome = { ...outcome, state: "unknown", reason: "AUTOMATIC_ANALYSIS_CANCELLATION_UNAVAILABLE" };
|
|
143
|
+
if (storageFailed)
|
|
144
|
+
outcome = { ...outcome, state: "unknown", reason: "AUTOMATIC_ANALYSIS_STORAGE_UNAVAILABLE" };
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
outcome = { state: "unknown", reason: "AUTOMATIC_ANALYSIS_OUTCOME_UNKNOWN" };
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
clearInterval(cancellationTimer);
|
|
151
|
+
clearInterval(heartbeat);
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
// Bind terminal metadata to the exact safely published execution. Reads never
|
|
155
|
+
// promote a completed-looking sidecar without rechecking these bindings.
|
|
156
|
+
const analysisId = outcome.result?.analysisId;
|
|
157
|
+
const [entry, receipt] = analysisId ? await Promise.all([
|
|
158
|
+
readStudyAnalysisVersion(prepared, analysisId), readStudyAnalysisExecution(prepared, analysisId)
|
|
159
|
+
]) : [null, null];
|
|
160
|
+
await job.update({ state: outcome.state, reason: outcome.reason,
|
|
161
|
+
analysisId: analysisId ?? null,
|
|
162
|
+
...(receipt === null ? {} : { sourceRunSha256: receipt.sourceRunSha256, inputDigest: receipt.inputDigest,
|
|
163
|
+
receiptSha256: hashStudyAnalysisValue(receipt) }),
|
|
164
|
+
...(entry?.analysis ? { analysisSha256: hashStudyAnalysisValue(entry.analysis) } : {}) });
|
|
165
|
+
const persisted = await readAutomaticStudyAnalysisPrepared(prepared);
|
|
166
|
+
if (persisted?.state === "unknown")
|
|
167
|
+
outcome = { ...outcome, state: "unknown", reason: persisted.reason };
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return { ...outcome, state: "unknown", reason: "AUTOMATIC_ANALYSIS_STORAGE_UNAVAILABLE" };
|
|
171
|
+
}
|
|
172
|
+
// The service may render while this owner is still running. Freeze the final
|
|
173
|
+
// job projection for direct file opening too, including no-request outcomes.
|
|
174
|
+
// A failed refresh must never erase the durable outcome or measured usage.
|
|
175
|
+
try {
|
|
176
|
+
const rendered = await renderObserver(cwd, runId, { open: false, expectedRun: prepared });
|
|
177
|
+
if (!rendered.ok)
|
|
178
|
+
throw new Error("AUTOMATIC_ANALYSIS_OBSERVER_UNAVAILABLE");
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
if (outcome.result)
|
|
182
|
+
outcome = { ...outcome, result: { ...outcome.result,
|
|
183
|
+
warnings: [...outcome.result.warnings, "Automatic analysis status was saved, but Observer could not be refreshed. Run humanish observe again."] } };
|
|
184
|
+
}
|
|
185
|
+
return outcome;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=automatic-study-analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-study-analysis.js","sourceRoot":"","sources":["../src/automatic-study-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AutomaticAnalysisHooks, type AutomaticAnalysisResult } from "./automatic-analysis-completion.js";
|
|
1
2
|
import { type RunLabProvenance } from "./run-status.js";
|
|
2
3
|
import { type CuaActorDescriptor } from "./actor-registry.js";
|
|
3
4
|
import { type CuaLaneSpec, type LaneRunOutcome } from "./cua-actor-lab.js";
|
|
@@ -12,6 +13,7 @@ export declare const CONCURRENT_SHARED_WORLD_PROVIDER_METADATA: {
|
|
|
12
13
|
};
|
|
13
14
|
export declare const CONCURRENT_ATTRIBUTION_LIMITS: readonly ["concurrent", "best-effort-causal-attribution", "non-deterministic-shared-state", "window-and-snapshot-granularity", "contention-observed-not-proven-safe", "state-change-not-isolated-to-actors"];
|
|
14
15
|
export interface RunConcurrentSharedWorldLabOptions {
|
|
16
|
+
automaticAnalysis?: AutomaticAnalysisHooks;
|
|
15
17
|
/** Which manifest produced this run (#455); threaded into the status record + bundle. */
|
|
16
18
|
lab?: RunLabProvenance;
|
|
17
19
|
cwd: string;
|
|
@@ -28,7 +30,7 @@ export interface RunConcurrentSharedWorldLabOptions {
|
|
|
28
30
|
* (#316); core-stamped onto the bundle as evidence. Absent for library callers. */
|
|
29
31
|
scorerProvenance?: RunScorerProvenance;
|
|
30
32
|
}
|
|
31
|
-
export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_GETHOST_UNAVAILABLE" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT"
|
|
33
|
+
export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_GETHOST_UNAVAILABLE" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT"
|
|
32
34
|
/** A declared adopter-hosted comms catch (#328) did not answer as a humanish catch — fail closed
|
|
33
35
|
* BEFORE any actor spend, since the funnel would silently collect nothing. */
|
|
34
36
|
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE";
|
|
@@ -94,7 +96,7 @@ export interface ConcurrentSharedWorldRoleResult {
|
|
|
94
96
|
message: string;
|
|
95
97
|
};
|
|
96
98
|
}
|
|
97
|
-
export interface ConcurrentSharedWorldLabResult {
|
|
99
|
+
export interface ConcurrentSharedWorldLabResult extends AutomaticAnalysisResult {
|
|
98
100
|
schema: typeof CONCURRENT_SHARED_WORLD_LAB_SCHEMA;
|
|
99
101
|
ok: boolean;
|
|
100
102
|
cwd: string;
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
// synthetic-seeded-subjects ONLY. Verify fail-closes on subject.state.provenance != "seeded" and
|
|
33
33
|
// requires the author attestation subject.exposure: synthetic. This is author-trust + a provenance
|
|
34
34
|
// gate, NOT a no-real-data guarantee (Humanish cannot tell synthetic from real data).
|
|
35
|
+
import { resolveAutomaticAnalysis } from "./automatic-analysis-config.js";
|
|
36
|
+
import { completeAutomaticAnalysis, markFinalizedStudyResult } from "./automatic-analysis-completion.js";
|
|
35
37
|
import { taskProtocolValidationReason } from "./lab-config.js";
|
|
36
38
|
import { randomBytes } from "node:crypto";
|
|
37
39
|
import { describeMissingKeys } from "./key-resolution.js";
|
|
@@ -500,7 +502,9 @@ function observerResultForConcurrentArtifacts(cwd, runId, artifactRoot, warnings
|
|
|
500
502
|
* ticking into a directory something else is deleting, which surfaces as an unrelated ENOTEMPTY.
|
|
501
503
|
*/
|
|
502
504
|
export async function runConcurrentSharedWorld(options) {
|
|
503
|
-
|
|
505
|
+
const analysis = resolveAutomaticAnalysis(options.config.review?.analysis);
|
|
506
|
+
const result = await withRunStatusScope(() => runConcurrentSharedWorldInScope(options));
|
|
507
|
+
return completeAutomaticAnalysis(result, analysis.ok ? analysis.config : undefined, options.automaticAnalysis, options.config.review?.analysis === undefined ? "default" : "explicit");
|
|
504
508
|
}
|
|
505
509
|
async function runConcurrentSharedWorldInScope(options) {
|
|
506
510
|
const { config, dryRun } = options;
|
|
@@ -530,6 +534,9 @@ async function runConcurrentSharedWorldInScope(options) {
|
|
|
530
534
|
warnings: [],
|
|
531
535
|
error: { code, message }
|
|
532
536
|
});
|
|
537
|
+
const analysis = resolveAutomaticAnalysis(config.review?.analysis);
|
|
538
|
+
if (!analysis.ok)
|
|
539
|
+
return fail("HUMANISH_LAB_ANALYSIS_INVALID", analysis.message);
|
|
533
540
|
const tasksReason = taskProtocolValidationReason(config, false);
|
|
534
541
|
if (tasksReason)
|
|
535
542
|
return fail("HUMANISH_LAB_TASKS_UNSUPPORTED", tasksReason);
|
|
@@ -1595,7 +1602,7 @@ async function runConcurrentSharedWorldInScope(options) {
|
|
|
1595
1602
|
const passed = roleResults.filter((role) => role.ok).length;
|
|
1596
1603
|
return { code: "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED", message: `Concurrent shared-world run did not run coherently: ${passed}/${roles.length} actor(s) reached a terminal, engaged passed session.` };
|
|
1597
1604
|
})();
|
|
1598
|
-
return {
|
|
1605
|
+
return markFinalizedStudyResult({
|
|
1599
1606
|
schema: CONCURRENT_SHARED_WORLD_LAB_SCHEMA,
|
|
1600
1607
|
ok,
|
|
1601
1608
|
cwd,
|
|
@@ -1616,7 +1623,7 @@ async function runConcurrentSharedWorldInScope(options) {
|
|
|
1616
1623
|
observer,
|
|
1617
1624
|
warnings: [...warnings, ...adapterWarnings, ...observer.warnings],
|
|
1618
1625
|
...(errorResult === undefined ? {} : { error: errorResult })
|
|
1619
|
-
};
|
|
1626
|
+
}, runPaths);
|
|
1620
1627
|
}
|
|
1621
1628
|
/** Max windows live at the same instant (sweep over start/end points). The honest simultaneity
|
|
1622
1629
|
* count: lane COUNT says how many seats existed; this says how many ever ran at once. */
|