humanish 0.115.0 → 0.117.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/CHANGELOG.md +41 -0
- package/README.md +7 -6
- package/TELEMETRY.md +6 -0
- package/dist/actors/codex/app-server-ui.js +11 -4
- package/dist/actors/codex/restricted-participant-policy.d.ts +0 -2
- package/dist/actors/codex/restricted-participant-policy.js +4 -32
- package/dist/actors/codex/restricted-participant.d.ts +5 -0
- package/dist/actors/codex/restricted-participant.js +3 -2
- package/dist/actors/computer-use/actor.d.ts +4 -0
- package/dist/actors/computer-use/actor.js +2 -0
- package/dist/actors/computer-use/loop/actions.d.ts +4 -4
- package/dist/actors/computer-use/loop/actions.js +25 -18
- package/dist/actors/computer-use/loop/debrief.js +61 -27
- package/dist/actors/computer-use/loop/session.d.ts +3 -0
- package/dist/actors/computer-use/loop/session.js +9 -1
- package/dist/actors/computer-use/loop/trace.js +1 -0
- package/dist/actors/computer-use/loop/types.d.ts +16 -14
- package/dist/actors/computer-use/loop.d.ts +1 -1
- package/dist/actors/computer-use/loop.js +1 -1
- package/dist/actors/computer-use/wait.d.ts +74 -0
- package/dist/actors/computer-use/wait.js +100 -0
- package/dist/actors/contract.d.ts +14 -0
- package/dist/actors/scripted-browser/steps.js +6 -5
- package/dist/analysis/analysis-limits.d.ts +35 -0
- package/dist/analysis/analysis-limits.js +41 -0
- package/dist/analysis/validation.js +14 -21
- package/dist/browser-control/protocol.d.ts +86 -6
- package/dist/browser-control/protocol.js +13 -6
- package/dist/cli/commands/analyze.js +2 -1
- package/dist/cli/commands/notes.js +2 -1
- package/dist/cli/commands/run-signals.js +5 -1
- package/dist/cli/commands/runs.js +2 -1
- package/dist/cli/commands/setup.js +3 -3
- package/dist/cli/commands/study-format.d.ts +5 -2
- package/dist/cli/commands/study-format.js +29 -9
- package/dist/cli/commands/study-route-computer-use.js +2 -2
- package/dist/cli/commands/study-route-scripted.js +1 -1
- package/dist/cli/commands/tui.js +59 -17
- package/dist/cli/doctor.js +9 -2
- package/dist/cli/findings-text.d.ts +5 -0
- package/dist/cli/findings-text.js +169 -0
- package/dist/cli/findings.d.ts +0 -4
- package/dist/cli/findings.js +5 -167
- package/dist/cli/io.js +6 -1
- package/dist/cli/update-check.js +4 -1
- package/dist/comms/connections.js +4 -3
- package/dist/comms/setup.js +18 -12
- package/dist/evidence/redaction.js +9 -1
- package/dist/evidence/secret-scrub.d.ts +15 -5
- package/dist/evidence/secret-scrub.js +67 -9
- package/dist/feedback/draft.js +1 -1
- package/dist/feedback/export-bundle.js +18 -14
- package/dist/feedback/feedback.js +25 -7
- package/dist/guest/desktop-executor.js +3 -1
- package/dist/guest/desktop-keys.js +59 -5
- package/dist/keys/key-resolution.d.ts +9 -0
- package/dist/keys/key-resolution.js +60 -48
- package/dist/keys/key-status.d.ts +2 -0
- package/dist/keys/key-status.js +9 -16
- package/dist/observer/pinned-files.js +1 -1
- package/dist/observer/render.js +3 -2
- package/dist/observer-app.html +5 -5
- package/dist/routes/computer-use/bundle-parts.d.ts +4 -4
- package/dist/routes/computer-use/bundle-parts.js +2 -2
- package/dist/routes/computer-use/bundle.d.ts +4 -5
- package/dist/routes/computer-use/bundle.js +1 -3
- package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -31
- package/dist/routes/computer-use/fanout-records.js +10 -11
- package/dist/routes/computer-use/live-phase.d.ts +1 -1
- package/dist/routes/computer-use/live-phase.js +0 -1
- package/dist/routes/computer-use/local-vm.js +5 -2
- package/dist/routes/computer-use/participant-execution.d.ts +3 -2
- package/dist/routes/computer-use/participant-model.js +9 -0
- package/dist/routes/computer-use/participant-runs.d.ts +6 -2
- package/dist/routes/computer-use/participant-runs.js +9 -5
- package/dist/routes/computer-use/plan.d.ts +3 -0
- package/dist/routes/computer-use/plan.js +18 -13
- package/dist/routes/computer-use/rerun-selection.js +2 -2
- package/dist/routes/computer-use/result.js +3 -6
- package/dist/routes/computer-use/setup.d.ts +4 -6
- package/dist/routes/computer-use/setup.js +2 -6
- package/dist/routes/computer-use/single-bundle.d.ts +4 -5
- package/dist/routes/computer-use/single-bundle.js +22 -25
- package/dist/routes/computer-use/subject-projection.d.ts +4 -8
- package/dist/routes/computer-use/subject-projection.js +9 -31
- package/dist/routes/computer-use/types.d.ts +5 -42
- package/dist/routes/scripted/scenario.js +28 -12
- package/dist/routes/scripted/session-result.js +6 -3
- package/dist/routes/shared-world/bundle-records.js +2 -8
- package/dist/routes/shared-world/participant-specs.d.ts +0 -2
- package/dist/routes/shared-world/participant-specs.js +1 -20
- package/dist/routes/shared-world/plan.d.ts +3 -0
- package/dist/routes/shared-world/plan.js +25 -4
- package/dist/routes/shared-world/setup.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +9 -9
- package/dist/routes/terminal/ledger.js +63 -40
- package/dist/routes/terminal/live-finish.js +7 -10
- package/dist/routes/terminal/live-sandbox.d.ts +1 -1
- package/dist/routes/terminal/live-sandbox.js +14 -11
- package/dist/routes/terminal/plan.d.ts +3 -0
- package/dist/routes/terminal/plan.js +8 -5
- package/dist/routes/terminal/sandbox.d.ts +4 -3
- package/dist/routes/terminal/sandbox.js +5 -5
- package/dist/routes/terminal/token-usage.d.ts +1 -2
- package/dist/routes/terminal/token-usage.js +4 -6
- package/dist/routes/terminal/types.d.ts +9 -1
- package/dist/run/bundle-shape.js +6 -1
- package/dist/run/bundle.d.ts +5 -3
- package/dist/run/contained-output.d.ts +53 -5
- package/dist/run/contained-output.js +141 -42
- package/dist/run/detail.d.ts +2 -1
- package/dist/run/detail.js +12 -7
- package/dist/run/escape-sequences.d.ts +11 -0
- package/dist/run/escape-sequences.js +93 -0
- package/dist/run/evidence-files.d.ts +8 -8
- package/dist/run/evidence-files.js +19 -23
- package/dist/run/locate.d.ts +32 -3
- package/dist/run/locate.js +45 -40
- package/dist/run/notes.d.ts +0 -8
- package/dist/run/notes.js +5 -51
- package/dist/run/outcomes.d.ts +24 -0
- package/dist/run/outcomes.js +19 -0
- package/dist/run/paths.d.ts +2 -0
- package/dist/run/paths.js +5 -1
- package/dist/run/preflight-receipts.js +13 -8
- package/dist/run/project.js +7 -4
- package/dist/run/reclaim-outcomes.d.ts +8 -6
- package/dist/run/reclaim-outcomes.js +10 -6
- package/dist/run/reclaim.d.ts +5 -0
- package/dist/run/reclaim.js +43 -16
- package/dist/run/run-clock.d.ts +50 -0
- package/dist/run/run-clock.js +66 -0
- package/dist/run/run.js +5 -2
- package/dist/run/sandbox-ids.d.ts +7 -2
- package/dist/run/sandbox-ids.js +27 -11
- package/dist/run/secrets.d.ts +2 -1
- package/dist/run/secrets.js +18 -22
- package/dist/run/stored-runs.js +14 -7
- package/dist/run/transient-comms-secrets.js +6 -17
- package/dist/run-study.js +22 -13
- package/dist/study/adapter-scorer-loader.js +6 -4
- package/dist/study/config.js +4 -1
- package/dist/study/discover.js +9 -6
- package/dist/study/init-paths.js +7 -5
- package/dist/study/keys.d.ts +2 -0
- package/dist/study/keys.js +2 -0
- package/dist/study/migrate/v2.js +2 -1
- package/dist/study/parse/actors.js +8 -0
- package/dist/study/persona-resolve.d.ts +2 -2
- package/dist/study/persona-resolve.js +9 -5
- package/dist/study/plan-participants.d.ts +4 -0
- package/dist/study/plan-participants.js +4 -0
- package/dist/study/plan-types.d.ts +2 -2
- package/dist/study/plan.d.ts +5 -3
- package/dist/study/plan.js +18 -9
- package/dist/study/preflight-probes.js +11 -3
- package/dist/study/preflight.js +9 -5
- package/dist/study/summary.d.ts +8 -2
- package/dist/study/summary.js +20 -22
- package/dist/study/types.d.ts +14 -0
- package/dist/study/validation.d.ts +5 -0
- package/dist/study/validation.js +8 -0
- package/dist/study/warnings.d.ts +19 -12
- package/dist/study/warnings.js +50 -17
- package/dist/subject/serve.d.ts +3 -0
- package/dist/subject/serve.js +4 -1
- package/dist/substrates/detached.js +14 -7
- package/dist/substrates/e2b/connection.d.ts +12 -0
- package/dist/substrates/e2b/connection.js +35 -0
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -5
- package/dist/substrates/e2b/desktop-executor.js +45 -12
- package/dist/substrates/e2b/lifetime.d.ts +24 -4
- package/dist/substrates/e2b/lifetime.js +41 -4
- package/dist/substrates/e2b/sandbox.d.ts +4 -3
- package/dist/substrates/e2b/sandbox.js +13 -18
- package/dist/substrates/e2b/sdk.d.ts +20 -9
- package/dist/substrates/local/capacity.d.ts +18 -2
- package/dist/substrates/local/capacity.js +21 -2
- package/dist/substrates/local/runtime-host.js +21 -14
- package/dist/substrates/local/runtime.js +3 -11
- package/dist/tui/contract.d.ts +30 -5
- package/dist/tui/contract.js +4 -1
- package/dist/tui-app.js +150 -147
- package/dist/verify/artifacts.d.ts +9 -2
- package/dist/verify/artifacts.js +37 -13
- package/dist/verify/liveness.js +19 -5
- package/dist/verify/verify.js +54 -27
- package/docs/architecture/browser-control.md +10 -4
- package/docs/architecture/guest-desktop.md +7 -2
- package/docs/architecture/state-driven-executor.md +4 -2
- package/docs/contracts/run-bundle.md +18 -10
- package/docs/contracts/schemas.md +46 -29
- package/docs/contracts/study-analysis.md +10 -1
- package/docs/product/automatic-analysis.md +7 -1
- package/package.json +2 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type RunProviderResource, type RunSubjectProvenance } from "../../run/bundle.js";
|
|
2
2
|
import { type ParticipantIds } from "../../run/participant-records.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type ParticipantRunOutcome } from "./types.js";
|
|
4
4
|
/** The human-readable state story appended to the provenance event (and review.md via it). */
|
|
5
5
|
export declare function describeSubjectState(state: RunSubjectProvenance["state"], dryRun: boolean): string;
|
|
6
|
-
/** Human-readable provenance line for the single-participant subject.provenance event
|
|
7
|
-
* claims "cloned/packed and served" only when it actually happened. */
|
|
8
|
-
export declare function subjectProvenanceMessage(provenance:
|
|
6
|
+
/** Human-readable provenance line for the single-participant subject.provenance event of a clone
|
|
7
|
+
* or local-tree subject: claims "cloned/packed and served" only when it actually happened. */
|
|
8
|
+
export declare function subjectProvenanceMessage(provenance: RunSubjectProvenance, publicAppUrl: string, dryRun: boolean, hasSession: boolean): string;
|
|
9
9
|
export declare function providerResourcesForOutcome(args: {
|
|
10
10
|
outcome: ParticipantRunOutcome | undefined;
|
|
11
11
|
createdAt: string;
|
|
@@ -24,8 +24,8 @@ export function describeSubjectState(state, dryRun) {
|
|
|
24
24
|
return "external-public (operator-declared, operator-owned public deployment; neither provisioned nor seeded)";
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
/** Human-readable provenance line for the single-participant subject.provenance event
|
|
28
|
-
* claims "cloned/packed and served" only when it actually happened. */
|
|
27
|
+
/** Human-readable provenance line for the single-participant subject.provenance event of a clone
|
|
28
|
+
* or local-tree subject: claims "cloned/packed and served" only when it actually happened. */
|
|
29
29
|
export function subjectProvenanceMessage(provenance, publicAppUrl, dryRun, hasSession) {
|
|
30
30
|
if (provenance.source === "clone") {
|
|
31
31
|
if (dryRun) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
2
|
import type { ComputerUsePlan } from "../../study/plan-types.js";
|
|
3
|
-
import type { BundleRun, RunBundle, RunRerunLineage } from "../../run/bundle.js";
|
|
3
|
+
import type { BundleRun, RunBundle, RunRerunLineage, RunSubjectProvenance } from "../../run/bundle.js";
|
|
4
4
|
import { type Judgment } from "../../run/judge.js";
|
|
5
|
-
import type { CuaParticipantPlan, DesktopParticipantRun,
|
|
5
|
+
import type { CuaParticipantPlan, DesktopParticipantRun, ParticipantRunOutcome } from "./types.js";
|
|
6
6
|
/** What every bundle of one run shares, in progress or final. */
|
|
7
7
|
export interface CuaRunBundleBase {
|
|
8
8
|
/** The run every bundle of it belongs to. */
|
|
@@ -32,9 +32,8 @@ interface CuaRunBundleState {
|
|
|
32
32
|
judgment: Judgment;
|
|
33
33
|
dryRun: boolean;
|
|
34
34
|
outcomes: ParticipantRunOutcome[] | undefined;
|
|
35
|
-
subjects:
|
|
36
|
-
aggregateSubject:
|
|
37
|
-
subjectProvenance: CuaSubjectProvenanceArg | undefined;
|
|
35
|
+
subjects: RunSubjectProvenance[];
|
|
36
|
+
aggregateSubject: RunSubjectProvenance;
|
|
38
37
|
failFastReason?: string;
|
|
39
38
|
inProgress?: true;
|
|
40
39
|
}
|
|
@@ -117,9 +117,7 @@ function singleParticipantArgs(base, state) {
|
|
|
117
117
|
}),
|
|
118
118
|
source: base.source,
|
|
119
119
|
...(state.inProgress === undefined ? {} : { inProgress: state.inProgress }),
|
|
120
|
-
|
|
121
|
-
? {}
|
|
122
|
-
: { subjectProvenance: state.subjectProvenance }),
|
|
120
|
+
subject: state.aggregateSubject,
|
|
123
121
|
...(desktopTemplate === undefined ? {} : { desktopTemplate }),
|
|
124
122
|
...(outcome?.desktopBrowser === undefined ? {} : { desktopBrowser: outcome.desktopBrowser }),
|
|
125
123
|
providerResources: providerResourcesForOutcome({
|
|
@@ -5,6 +5,7 @@ import { validatePreparedRunArtifactPaths } from "../../../run/paths.js";
|
|
|
5
5
|
import { provisionCloneSubject } from "../../../subject/clone.js";
|
|
6
6
|
import { provisionDesktopCli } from "../../../subject/desktop-cli.js";
|
|
7
7
|
import { provisionLocalTreeSubject } from "../../../subject/local-tree.js";
|
|
8
|
+
import { SubjectBuildError } from "../../../subject/serve.js";
|
|
8
9
|
import { inspectDesktopScreenGeometry } from "../../../substrates/e2b/desktop-geometry.js";
|
|
9
10
|
import { observeDesktopResources } from "../../../substrates/e2b/desktop-resources.js";
|
|
10
11
|
import { acquireE2BDesktopSandbox, e2bDesktopTemplate } from "../../../substrates/e2b/sandbox.js";
|
|
@@ -166,37 +167,45 @@ export async function provisionParticipantSubject(ctx, state, desktop) {
|
|
|
166
167
|
onPhase: ctx.onSubjectPhase,
|
|
167
168
|
});
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
170
|
+
try {
|
|
171
|
+
if (subject.kind === "clone") {
|
|
172
|
+
state.subjectCommit = await provisionCloneSubject(shell, {
|
|
173
|
+
repo: subject.repo,
|
|
174
|
+
depth: residual.subject.clone?.depth ?? 1,
|
|
175
|
+
serve: subject.serve,
|
|
176
|
+
...(subject.state === undefined ? {} : { state: subject.state }),
|
|
177
|
+
hasGithubToken: subject.env.includes("GITHUB_TOKEN"),
|
|
178
|
+
requestTimeoutMs: deps.requestTimeoutMs,
|
|
179
|
+
scrub: deps.scrubKnownValues,
|
|
180
|
+
onCommit: (commit) => {
|
|
181
|
+
state.subjectCommit = commit;
|
|
182
|
+
},
|
|
183
|
+
onStateStep: (record) => {
|
|
184
|
+
state.stateStepRecords.push(record);
|
|
185
|
+
},
|
|
186
|
+
onPhase: ctx.onSubjectPhase,
|
|
187
|
+
...deps.detachedTimers,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else if (subject.kind === "local-tree" && deps.localTreeArchiveBuffer) {
|
|
191
|
+
await provisionLocalTreeSubject(shell, {
|
|
192
|
+
archiveBuffer: deps.localTreeArchiveBuffer,
|
|
193
|
+
serve: subject.serve,
|
|
194
|
+
...(subject.state === undefined ? {} : { state: subject.state }),
|
|
195
|
+
requestTimeoutMs: deps.requestTimeoutMs,
|
|
196
|
+
scrub: deps.scrubKnownValues,
|
|
197
|
+
onStateStep: (record) => {
|
|
198
|
+
state.stateStepRecords.push(record);
|
|
199
|
+
},
|
|
200
|
+
onPhase: ctx.onSubjectPhase,
|
|
201
|
+
...deps.detachedTimers,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
187
204
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
requestTimeoutMs: deps.requestTimeoutMs,
|
|
194
|
-
scrub: deps.scrubKnownValues,
|
|
195
|
-
onStateStep: (record) => {
|
|
196
|
-
state.stateStepRecords.push(record);
|
|
197
|
-
},
|
|
198
|
-
onPhase: ctx.onSubjectPhase,
|
|
199
|
-
...deps.detachedTimers,
|
|
200
|
-
});
|
|
205
|
+
catch (error) {
|
|
206
|
+
// A failed serve.build gets its own code, so the run names the step the author has to fix.
|
|
207
|
+
if (error instanceof SubjectBuildError)
|
|
208
|
+
state.failureCode = "HUMANISH_COMPUTER_USE_SUBJECT_BUILD_FAILED";
|
|
209
|
+
throw error;
|
|
201
210
|
}
|
|
202
211
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { participantAssignment } from "../../study/participant-assignment.js";
|
|
4
4
|
import { participantEvent, participantRecord, participantStream, } from "../../run/participant-records.js";
|
|
5
5
|
import { participantCaption } from "../../run/participant-caption.js";
|
|
6
|
-
import {
|
|
6
|
+
import { participantSummary } from "../../run/outcomes.js";
|
|
7
7
|
import { declaredScreenForRender } from "../../substrates/e2b/desktop-geometry.js";
|
|
8
8
|
import { describeSubjectState, phaseEventIdSuffix, publicSafeAppUrlLabel } from "./bundle-parts.js";
|
|
9
9
|
import { participantSubjectEnv } from "./types.js";
|
|
@@ -60,15 +60,12 @@ function fanoutParticipantRecord(args, spec, index, view) {
|
|
|
60
60
|
mode: "browser-sim",
|
|
61
61
|
progress: args.inProgress === true && outcome === undefined ? 20 : 100,
|
|
62
62
|
currentStep: reason,
|
|
63
|
-
summary:
|
|
64
|
-
|
|
65
|
-
:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
: outcome?.sessionError !== undefined
|
|
70
|
-
? `${name} did not finish a session: ${outcome.sessionError}`
|
|
71
|
-
: `${name} would use ${publicTargetUrl}; no session ran.`,
|
|
63
|
+
summary: participantSummary(name, { name: "the app", target: publicTargetUrl }, {
|
|
64
|
+
trace: session?.trace,
|
|
65
|
+
skippedReason: outcome?.skippedReason,
|
|
66
|
+
sessionError: outcome?.sessionError,
|
|
67
|
+
inProgress: args.inProgress === true && outcome === undefined,
|
|
68
|
+
}),
|
|
72
69
|
startedAt: args.run.createdAt,
|
|
73
70
|
updatedAt: args.run.createdAt,
|
|
74
71
|
});
|
|
@@ -208,7 +205,9 @@ function fanoutSubjectEvents(ctx, spec, view) {
|
|
|
208
205
|
at: args.run.createdAt,
|
|
209
206
|
level: "info",
|
|
210
207
|
type: "cua-lab.subject.declared",
|
|
211
|
-
message:
|
|
208
|
+
message: subject.source === "desktop-cli"
|
|
209
|
+
? `Participant ${spec.planned.id}: subject product declared: ${subject.product}, used from a terminal window inside the participant's own desktop sandbox.`
|
|
210
|
+
: `Participant ${spec.planned.id}: subject app declared at ${publicTargetUrl} (loopback inside the participant's own desktop sandbox).`,
|
|
212
211
|
});
|
|
213
212
|
}
|
|
214
213
|
return events;
|
|
@@ -31,7 +31,7 @@ export declare function runStudyParticipants(setup: CuaRunSetup, participants: C
|
|
|
31
31
|
killed: boolean;
|
|
32
32
|
streamUrlPresent: boolean;
|
|
33
33
|
};
|
|
34
|
-
subject?: import("
|
|
34
|
+
subject?: import("../../run/bundle.js").RunSubjectProvenance;
|
|
35
35
|
plan?: import("./types.js").CuaParticipantPlan;
|
|
36
36
|
lanes?: import("./types.js").CuaParticipantResult[];
|
|
37
37
|
laneSummary?: import("./types.js").CuaParticipantSummary;
|
|
@@ -37,7 +37,6 @@ export async function runStudyParticipants(setup, participants) {
|
|
|
37
37
|
outcomes: undefined,
|
|
38
38
|
subjects: inProgress.subjects,
|
|
39
39
|
aggregateSubject: inProgress.aggregateSubject,
|
|
40
|
-
subjectProvenance: inProgress.provenance,
|
|
41
40
|
inProgress: true,
|
|
42
41
|
});
|
|
43
42
|
await run.writeSnapshot(inProgressBundle);
|
|
@@ -139,10 +139,11 @@ function createLocalParticipantDesktop(context, run, warnings, artifactRoot) {
|
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
/** The Codex account participant, whose unconfirmed cleanup blocks the study's analysis. */
|
|
142
|
-
function accountProvider(state) {
|
|
142
|
+
function accountProvider(state, maxWaitMs) {
|
|
143
143
|
return async ({ executor }) => {
|
|
144
144
|
const participant = createRestrictedCodexParticipant({
|
|
145
145
|
speechEnabled: executor.speechEnabled === true,
|
|
146
|
+
...(maxWaitMs === undefined ? {} : { maxWaitMs }),
|
|
146
147
|
});
|
|
147
148
|
state.participants.push(participant);
|
|
148
149
|
const provider = Object.assign(participant.provider, {
|
|
@@ -183,7 +184,9 @@ export function prepareLocalVmRun(options) {
|
|
|
183
184
|
};
|
|
184
185
|
const { config: _config, assets: _assets, signal: _signal, ...runOptions } = options;
|
|
185
186
|
return {
|
|
186
|
-
options: account
|
|
187
|
+
options: account
|
|
188
|
+
? { ...runOptions, createProvider: accountProvider(state, config.actor?.maxWaitMs) }
|
|
189
|
+
: runOptions,
|
|
187
190
|
localVm: {
|
|
188
191
|
desktop: (run, warnings, artifactRoot) => createLocalParticipantDesktop(context, run, warnings, artifactRoot),
|
|
189
192
|
capacity: () => localRuntimeCapacity(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type PreparedOutputRoot } from "../../run/contained-output.js";
|
|
2
|
-
import type { CuaParticipantDeps, CuaParticipantPlan, CuaParticipantResult, DesktopParticipantRun,
|
|
2
|
+
import type { CuaParticipantDeps, CuaParticipantPlan, CuaParticipantResult, DesktopParticipantRun, ParticipantRunOutcome } from "./types.js";
|
|
3
|
+
import type { RunSubjectProvenance } from "../../run/bundle.js";
|
|
3
4
|
/** Build a participant's writeScreenshot closure: writes under screenshots/<screenshotDir>/ and records
|
|
4
5
|
* the relative path the trace references (screenshots/<name> at N=1; screenshots/<laneId>/<name>
|
|
5
6
|
* at N>1). */
|
|
@@ -24,7 +25,7 @@ export declare function runCuaParticipants(runs: DesktopParticipantRun[], deps:
|
|
|
24
25
|
failFastReason?: string;
|
|
25
26
|
}>;
|
|
26
27
|
/** Project one participant outcome (or a dry-run contract spec) into the public CuaParticipantResult. */
|
|
27
|
-
export declare function toParticipantResult(spec: DesktopParticipantRun, outcome: ParticipantRunOutcome | undefined, subject:
|
|
28
|
+
export declare function toParticipantResult(spec: DesktopParticipantRun, outcome: ParticipantRunOutcome | undefined, subject: RunSubjectProvenance, dryRun: boolean): CuaParticipantResult;
|
|
28
29
|
/**
|
|
29
30
|
* Run every participant of a live run. The in-process route drives its single participant in this
|
|
30
31
|
* process; one hosted participant runs alone; a fan-out runs at the plan's concurrency and may stop early.
|
|
@@ -44,6 +44,9 @@ export async function startParticipantModel(spec, deps, executor) {
|
|
|
44
44
|
: { reasoningEffort: spec.planned.limits.reasoningEffort }),
|
|
45
45
|
...(brain.declaredModel === undefined ? {} : { model: brain.declaredModel }),
|
|
46
46
|
...(executor.speechEnabled === true ? { speechEnabled: true } : {}),
|
|
47
|
+
...(spec.planned.limits.maxWaitMs === undefined
|
|
48
|
+
? {}
|
|
49
|
+
: { maxWaitMs: spec.planned.limits.maxWaitMs }),
|
|
47
50
|
session: { env },
|
|
48
51
|
});
|
|
49
52
|
return { provider: codexParticipant.provider, codexParticipant };
|
|
@@ -130,6 +133,12 @@ export function participantSessionOptions(spec, deps, ready, provider, writeScre
|
|
|
130
133
|
? {}
|
|
131
134
|
: { stopWhen: spec.planned.limits.stopWhen }),
|
|
132
135
|
...(spec.planned.limits.dwell === undefined ? {} : { dwell: spec.planned.limits.dwell }),
|
|
136
|
+
...(spec.planned.limits.maxWaitMs === undefined
|
|
137
|
+
? {}
|
|
138
|
+
: { maxWaitMs: spec.planned.limits.maxWaitMs }),
|
|
139
|
+
...(spec.planned.limits.idleWaitMs === undefined
|
|
140
|
+
? {}
|
|
141
|
+
: { idleWaitMs: spec.planned.limits.idleWaitMs }),
|
|
133
142
|
...(spec.planned.tasks === undefined ? {} : { tasks: spec.planned.tasks }),
|
|
134
143
|
// The study budget: this participant notes its own running estimate on the shared
|
|
135
144
|
// ledger and stops when the run total crosses the cap, independent of the per-participant
|
|
@@ -4,14 +4,18 @@ import { type ResolvedPersona } from "../../study/persona.js";
|
|
|
4
4
|
import { type RunRerunLineage } from "../../run/bundle.js";
|
|
5
5
|
import type { PreparedSelectedOutputDirectory } from "../../run/contained-output.js";
|
|
6
6
|
import { type CuaActorStudyErrorCode, type CuaParticipantPlan, type CuaParticipantPlanEntry, type DesktopParticipantRun, type ParticipantRunsAndPlan } from "./types.js";
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The session budget of a study that declares no execution.timeoutMs. On a provisioned route it is
|
|
9
|
+
* what the `ceilingMs` sandbox ceiling leaves after provisioning, seeding and the teardown buffer.
|
|
10
|
+
*/
|
|
11
|
+
export declare function defaultSessionTimeoutMs(config: StudyConfig, ceilingMs: number): number;
|
|
8
12
|
/** Per-participant sandbox deadline (each one owns its own desktop). Mirrors the
|
|
9
13
|
* single-participant formula verbatim so N=1 stays byte-stable: explicit sandboxTimeoutMs, else session budget + (clone
|
|
10
14
|
* or local-tree: provision budget + Σ state-step budgets) + the server-side
|
|
11
15
|
* reclamation buffer. Local-tree shares the clone route's provisioning budget: it swaps a
|
|
12
16
|
* git clone for an upload+extract, but the shared install/build/state/start/probe pipeline
|
|
13
17
|
* costs the same wall-clock room either way. */
|
|
14
|
-
export declare function resolveParticipantSandboxMs(config: StudyConfig): number;
|
|
18
|
+
export declare function resolveParticipantSandboxMs(config: StudyConfig, ceilingMs: number): number;
|
|
15
19
|
/**
|
|
16
20
|
* The in-flight participant bound a study declares. Defaults to the participant count: every
|
|
17
21
|
* declared participant runs at once, because a throttle nobody asked for silently turns "N actors
|
|
@@ -12,18 +12,22 @@ import {} from "../../run/bundle.js";
|
|
|
12
12
|
import { participantAssignment } from "../../study/participant-assignment.js";
|
|
13
13
|
import { resolveCommittedPersonas } from "../../study/persona-resolve.js";
|
|
14
14
|
import { CUA_FANOUT_STRATEGY, CUA_MAX_CONCURRENCY_ENV, DEFAULT_APP_URL_SESSION_TIMEOUT_MS, MIN_DERIVED_SESSION_TIMEOUT_MS, } from "./types.js";
|
|
15
|
-
import {
|
|
15
|
+
import { SANDBOX_TIMEOUT_BUFFER_MS, SUBJECT_PROVISION_BUDGET_MS, } from "../../substrates/e2b/lifetime.js";
|
|
16
16
|
import { readPositiveInt } from "../../study/parse/values.js";
|
|
17
17
|
import { digestUrl } from "./bundle-parts.js";
|
|
18
18
|
import { composeParticipantInstructions, DEFAULT_MISSION } from "./participant-prompt.js";
|
|
19
19
|
import { resolveCuaRerunSelection } from "./rerun-selection.js";
|
|
20
20
|
import { plural } from "../../run/text.js";
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The session budget of a study that declares no execution.timeoutMs. On a provisioned route it is
|
|
23
|
+
* what the `ceilingMs` sandbox ceiling leaves after provisioning, seeding and the teardown buffer.
|
|
24
|
+
*/
|
|
25
|
+
export function defaultSessionTimeoutMs(config, ceilingMs) {
|
|
22
26
|
const provisionedRoute = config.subject.source === "clone" || config.subject.source === "local-tree";
|
|
23
27
|
if (!provisionedRoute)
|
|
24
28
|
return DEFAULT_APP_URL_SESSION_TIMEOUT_MS;
|
|
25
29
|
const stateBudgetMs = (config.subject.state?.seed ?? []).reduce((sum, step) => sum + (step.timeoutMs ?? DEFAULT_STATE_STEP_TIMEOUT_MS), 0);
|
|
26
|
-
const room =
|
|
30
|
+
const room = ceilingMs - SUBJECT_PROVISION_BUDGET_MS - stateBudgetMs - SANDBOX_TIMEOUT_BUFFER_MS;
|
|
27
31
|
return Math.max(MIN_DERIVED_SESSION_TIMEOUT_MS, Math.min(DEFAULT_APP_URL_SESSION_TIMEOUT_MS, room));
|
|
28
32
|
}
|
|
29
33
|
/** Per-participant sandbox deadline (each one owns its own desktop). Mirrors the
|
|
@@ -32,10 +36,10 @@ export function defaultSessionTimeoutMs(config) {
|
|
|
32
36
|
* reclamation buffer. Local-tree shares the clone route's provisioning budget: it swaps a
|
|
33
37
|
* git clone for an upload+extract, but the shared install/build/state/start/probe pipeline
|
|
34
38
|
* costs the same wall-clock room either way. */
|
|
35
|
-
export function resolveParticipantSandboxMs(config) {
|
|
39
|
+
export function resolveParticipantSandboxMs(config, ceilingMs) {
|
|
36
40
|
if (isLocalBrowserStudy(config))
|
|
37
41
|
return LOCAL_BROWSER_LIFETIME_MS;
|
|
38
|
-
const timeoutMs = config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config);
|
|
42
|
+
const timeoutMs = config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config, ceilingMs);
|
|
39
43
|
const provisionedRoute = config.subject.source === "clone" || config.subject.source === "local-tree";
|
|
40
44
|
const stateBudgetMs = provisionedRoute
|
|
41
45
|
? (config.subject.state?.seed ?? []).reduce((sum, step) => sum + (step.timeoutMs ?? DEFAULT_STATE_STEP_TIMEOUT_MS), 0)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
2
|
import type { ComputerUsePlan, ComputerUseRunner, RoutePlanResult, RouteRefusal } from "../../study/plan-types.js";
|
|
3
3
|
import type { StudyConfig, StudySubjectState } from "../../study/types.js";
|
|
4
|
+
import { type SandboxCeiling } from "../../substrates/e2b/lifetime.js";
|
|
4
5
|
import { type ComputerUseRunInput, type CuaActorStudyErrorCode } from "./types.js";
|
|
5
6
|
/** The error a computer-use study returns before a run starts. */
|
|
6
7
|
export interface ComputerUseRefusal extends RouteRefusal<"computer-use", CuaActorStudyErrorCode> {
|
|
@@ -45,4 +46,6 @@ export declare function planComputerUseStudy(config: StudyConfig, input: {
|
|
|
45
46
|
readonly driving?: CallerDriving;
|
|
46
47
|
readonly countOverride?: number;
|
|
47
48
|
readonly rerun?: ComputerUseRunInput["rerun"];
|
|
49
|
+
/** The longest sandbox lifetime the operator's E2B plan allows (sandboxCeiling). */
|
|
50
|
+
readonly sandboxCeiling: SandboxCeiling;
|
|
48
51
|
}): ComputerUsePlanResult;
|
|
@@ -10,11 +10,11 @@ import { subjectStateInvalidReason } from "../../study/parse/subject-state.js";
|
|
|
10
10
|
import { brainOf, callerBrainOf, planCaps, desktopRequirements, planBase, provisionedSubject, } from "../../study/plan-base.js";
|
|
11
11
|
import { computerUseParticipants, declaredTargets } from "../../study/plan-participants.js";
|
|
12
12
|
import { MAX_COMPUTER_USE_PARTICIPANTS } from "../../study/routing.js";
|
|
13
|
-
import { cloneTargetValidationReason, computerUseValidationReason, desktopMediaValidationReason, outputTokenLimitValidationReason, receivingEmailValidationReason, taskProtocolValidationReason, } from "../../study/validation.js";
|
|
13
|
+
import { cloneTargetValidationReason, computerUseValidationReason, desktopMediaValidationReason, outputTokenLimitValidationReason, receivingEmailValidationReason, taskProtocolValidationReason, waitLimitValidationReason, } from "../../study/validation.js";
|
|
14
14
|
import { desktopCliProductReason } from "../../study/composition-rules.js";
|
|
15
15
|
import { isLocalBrowserStudy } from "../../substrates/local/runtime-config.js";
|
|
16
16
|
import { boundedConcurrency, defaultSessionTimeoutMs, resolveParticipantSandboxMs, } from "./participant-runs.js";
|
|
17
|
-
import {
|
|
17
|
+
import { ceilingAdvice } from "../../substrates/e2b/lifetime.js";
|
|
18
18
|
import {} from "./types.js";
|
|
19
19
|
/** The registered descriptor for a planned actor id; planComputerUseStudy checked the registry. */
|
|
20
20
|
export function cuaDescriptorOf(actor) {
|
|
@@ -74,16 +74,18 @@ const invalid = (message) => ({
|
|
|
74
74
|
* is touched. The parser enforces most of these too; the engine repeats them for library callers
|
|
75
75
|
* that hand it a config directly. The groups run in this order, and each returns its first reason.
|
|
76
76
|
*/
|
|
77
|
-
function cuaStudyRejection(config, hasRunSession, driving, subjectRoute) {
|
|
77
|
+
function cuaStudyRejection(config, hasRunSession, driving, subjectRoute, ceilingMs) {
|
|
78
78
|
return (unsupportedDeclarationReason(config, hasRunSession, driving, subjectRoute) ??
|
|
79
79
|
subjectStructureReason(config, subjectRoute) ??
|
|
80
80
|
entryTargetReason(config, subjectRoute) ??
|
|
81
81
|
driverReason(driving, subjectRoute) ??
|
|
82
|
-
rosterShapeReason(config));
|
|
82
|
+
rosterShapeReason(config, ceilingMs));
|
|
83
83
|
}
|
|
84
84
|
/** A declaration this route cannot honor, for any subject or with the caller's own driver. */
|
|
85
85
|
function unsupportedDeclarationReason(config, hasRunSession, driving, { inProcessRoute }) {
|
|
86
|
-
const reason = desktopMediaValidationReason(config) ||
|
|
86
|
+
const reason = desktopMediaValidationReason(config) ||
|
|
87
|
+
outputTokenLimitValidationReason(config) ||
|
|
88
|
+
waitLimitValidationReason(config);
|
|
87
89
|
if (reason)
|
|
88
90
|
return invalid(reason);
|
|
89
91
|
if (config.actor?.maxOutputTokens !== undefined &&
|
|
@@ -173,7 +175,7 @@ function driverReason(driving, { localAppSubject, inProcessRoute }) {
|
|
|
173
175
|
return undefined;
|
|
174
176
|
}
|
|
175
177
|
/** The participant roster, then the sandbox deadline its session budget derives. */
|
|
176
|
-
function rosterShapeReason(config) {
|
|
178
|
+
function rosterShapeReason(config, ceilingMs) {
|
|
177
179
|
// Device XOR raw resolution, cap, unique ids,
|
|
178
180
|
// allowPublicTargets with more than one participant, clone.fanout.
|
|
179
181
|
const fanoutReason = computerUseValidationReason(config);
|
|
@@ -182,13 +184,13 @@ function rosterShapeReason(config) {
|
|
|
182
184
|
// The sandbox deadline is derived from the session budget, so a study can ask for a session that
|
|
183
185
|
// cannot legally be provisioned. Show the arithmetic: the provider's own error names a limit
|
|
184
186
|
// but not which knob produced it.
|
|
185
|
-
const derivedSandboxMs = resolveParticipantSandboxMs(config);
|
|
186
|
-
if (derivedSandboxMs <=
|
|
187
|
+
const derivedSandboxMs = resolveParticipantSandboxMs(config, ceilingMs);
|
|
188
|
+
if (derivedSandboxMs <= ceilingMs)
|
|
187
189
|
return undefined;
|
|
188
190
|
const provisionedRoute = config.subject.source === "clone" || config.subject.source === "local-tree";
|
|
189
|
-
const sessionMs = config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config);
|
|
191
|
+
const sessionMs = config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config, ceilingMs);
|
|
190
192
|
const headroomMs = derivedSandboxMs - sessionMs;
|
|
191
|
-
return invalid(`execution.timeoutMs ${Math.round(sessionMs / 60_000)}m derives a ${Math.round(derivedSandboxMs / 60_000)}m sandbox deadline, and a sandbox may not live longer than ${
|
|
193
|
+
return invalid(`execution.timeoutMs ${Math.round(sessionMs / 60_000)}m derives a ${Math.round(derivedSandboxMs / 60_000)}m sandbox deadline, and a sandbox may not live longer than ${ceilingMs / 60_000}m. The deadline is the session budget plus ${Math.round(headroomMs / 60_000)}m of provisioning and teardown headroom${provisionedRoute ? " (this route clones, installs, builds and serves the subject before the actor starts)" : ""}. Lower execution.timeoutMs to at most ${Math.round((ceilingMs - headroomMs) / 60_000)}m, or set execution.desktop.sandboxTimeoutMs explicitly.${ceilingAdvice(derivedSandboxMs)}`);
|
|
192
194
|
}
|
|
193
195
|
/** The plan's rerun: the source run and, when given, the participants to rerun. */
|
|
194
196
|
function rerunPlan({ sourceRunId, participantIds, }) {
|
|
@@ -223,7 +225,10 @@ export function planComputerUseStudy(config, input) {
|
|
|
223
225
|
if (!descriptor || !isCuaActorDescriptor(descriptor))
|
|
224
226
|
return refuse("in-scope", "HUMANISH_COMPUTER_USE_ACTOR_UNSUPPORTED", `actor.type "${actorType}" is not a registered computer-use actor.`);
|
|
225
227
|
const actor = descriptor.id;
|
|
226
|
-
const
|
|
228
|
+
const ceiling = input.sandboxCeiling;
|
|
229
|
+
if (!ceiling.ok)
|
|
230
|
+
return refuse("in-scope", "HUMANISH_COMPUTER_USE_SUBJECT_INVALID", ceiling.message, actor);
|
|
231
|
+
const rejection = cuaStudyRejection(config, hasRunSession, driving, declaredSubjectRoute(config, driving), ceiling.ms);
|
|
227
232
|
if (rejection)
|
|
228
233
|
return refuse("in-scope", rejection.code, rejection.message, actor);
|
|
229
234
|
// A shared world runs every participant against one app; this route would run them as separate
|
|
@@ -288,8 +293,8 @@ export function planComputerUseStudy(config, input) {
|
|
|
288
293
|
actor,
|
|
289
294
|
runner,
|
|
290
295
|
concurrency: boundedConcurrency(declared, n),
|
|
291
|
-
sessionBudgetMs: config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config),
|
|
292
|
-
sandboxMs: resolveParticipantSandboxMs(config),
|
|
296
|
+
sessionBudgetMs: config.execution?.timeoutMs ?? defaultSessionTimeoutMs(config, ceiling.ms),
|
|
297
|
+
sandboxMs: resolveParticipantSandboxMs(config, ceiling.ms),
|
|
293
298
|
caps: planCaps(config),
|
|
294
299
|
...(input.rerun === undefined ? {} : { rerun: rerunPlan(input.rerun) }),
|
|
295
300
|
requirements: base.dryRun || runner.desktop === "in-process"
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// participants that failed, blocked, timed out or finished hollow are picked unless ids are given.
|
|
3
3
|
import {} from "../../run/bundle.js";
|
|
4
4
|
import { loadRunBundle } from "../../run/locate.js";
|
|
5
|
+
import { resolveLatestRunPointer } from "../../run/paths.js";
|
|
5
6
|
import {} from "../../run/streams.js";
|
|
6
7
|
import { plural } from "../../run/text.js";
|
|
7
8
|
import { access } from "node:fs/promises";
|
|
8
|
-
import path from "node:path";
|
|
9
9
|
import { cli } from "../../cli/invocation.js";
|
|
10
10
|
export async function resolveCuaRerunSelection(args) {
|
|
11
11
|
const { studyId, sourceRunId } = args;
|
|
@@ -16,7 +16,7 @@ export async function resolveCuaRerunSelection(args) {
|
|
|
16
16
|
const source = await loadRunBundle(args.cwd, sourceRunId);
|
|
17
17
|
if (!source) {
|
|
18
18
|
const noRuns = sourceRunId === "latest" &&
|
|
19
|
-
!(await access(
|
|
19
|
+
!(await access(resolveLatestRunPointer(args.cwd)).then(() => true, () => false));
|
|
20
20
|
return refuse(noRuns
|
|
21
21
|
? "--rerun-failed-from latest found no run: this project has no runs yet, and a rerun repeats the failed participants of an earlier live run."
|
|
22
22
|
: `--rerun-failed-from ${sourceRunId} names no run humanish can read in this project. ${cli("runs")} lists its runs.`);
|
|
@@ -7,8 +7,8 @@ import { participantCapWarning } from "./participant-model.js";
|
|
|
7
7
|
import { summarizeCuaDiagnostics } from "./diagnostics.js";
|
|
8
8
|
import { toParticipantResult } from "./participant-execution.js";
|
|
9
9
|
import { buildCuaRunBundle, judgeComputerUseRun } from "./bundle.js";
|
|
10
|
-
import { aggregateCuaSubject, projectParticipantSubjects
|
|
11
|
-
import { CUA_FANOUT_STRATEGY,
|
|
10
|
+
import { aggregateCuaSubject, projectParticipantSubjects } from "./subject-projection.js";
|
|
11
|
+
import { CUA_FANOUT_STRATEGY, } from "./types.js";
|
|
12
12
|
import { plannedAppUrl } from "./plan.js";
|
|
13
13
|
import { studyResultIdentity } from "../../run/study-result.js";
|
|
14
14
|
import { plural } from "../../run/text.js";
|
|
@@ -157,10 +157,9 @@ function cuaStudyResult(args) {
|
|
|
157
157
|
export async function finishCuaRun(setup, finish, ran) {
|
|
158
158
|
const { plan, input, cwd, streams, descriptor, run } = setup;
|
|
159
159
|
const { participantRuns, participantPlan, bundleBase } = setup;
|
|
160
|
-
const { rerunLineage,
|
|
160
|
+
const { rerunLineage, subjectArgs } = finish;
|
|
161
161
|
const { dryRun } = plan;
|
|
162
162
|
const appUrl = plannedAppUrl(plan.runner.subject);
|
|
163
|
-
const subjectEnvNames = [...participantSubjectEnv(plan.runner.subject)];
|
|
164
163
|
const { runId } = run;
|
|
165
164
|
const participantCount = participantRuns.length;
|
|
166
165
|
const { outcomes, failFastReason, receiving, receivingWarnings, externalCommsWarnings } = ran;
|
|
@@ -174,7 +173,6 @@ export async function finishCuaRun(setup, finish, ran) {
|
|
|
174
173
|
...(capWarning === undefined ? [] : [capWarning]),
|
|
175
174
|
...aggregate.warnings,
|
|
176
175
|
];
|
|
177
|
-
const finalProvenance = subjectProvenanceArg(aggregateSubject, publicRepo, subjectEnvNames);
|
|
178
176
|
// One judgment for the whole run: the bundle's verdict and the result's ok both read it.
|
|
179
177
|
const judgment = judgeComputerUseRun(bundleBase, { dryRun, outcomes });
|
|
180
178
|
const bundle = buildCuaRunBundle(bundleBase, {
|
|
@@ -183,7 +181,6 @@ export async function finishCuaRun(setup, finish, ran) {
|
|
|
183
181
|
outcomes,
|
|
184
182
|
subjects,
|
|
185
183
|
aggregateSubject,
|
|
186
|
-
subjectProvenance: finalProvenance,
|
|
187
184
|
...(failFastReason === undefined ? {} : { failFastReason }),
|
|
188
185
|
});
|
|
189
186
|
const adapterWarnings = [];
|
|
@@ -3,14 +3,14 @@ import type { RefusedStudy } from "../../run/route-shell.js";
|
|
|
3
3
|
import { RunSecrets } from "../../run/secrets.js";
|
|
4
4
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
5
5
|
import type { StudyCommsEmail, StudyCommsExternal, StudyConfig } from "../../study/types.js";
|
|
6
|
-
import { type RunRerunLineage } from "../../run/bundle.js";
|
|
6
|
+
import { type RunRerunLineage, type RunSubjectProvenance } from "../../run/bundle.js";
|
|
7
7
|
import { type LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
8
8
|
import { type ComputerUseRefusal } from "./plan.js";
|
|
9
9
|
import type { ComputerUsePlan } from "../../study/plan-types.js";
|
|
10
10
|
import { trackRuntimeStreams, type LiveTraceFlush } from "./live-flush.js";
|
|
11
11
|
import { type CuaRunBundleBase } from "./bundle.js";
|
|
12
12
|
import { projectParticipantSubjects } from "./subject-projection.js";
|
|
13
|
-
import { type CuaActorStudyErrorCode, type CuaActorStudyResult, type CuaParticipantDeps, type CuaParticipantPlan, type DesktopParticipantRun, type
|
|
13
|
+
import { type CuaActorStudyErrorCode, type CuaActorStudyResult, type CuaParticipantDeps, type CuaParticipantPlan, type DesktopParticipantRun, type ComputerUseRunInput } from "./types.js";
|
|
14
14
|
/**
|
|
15
15
|
* The envelope of a refusal the plan left for after the cwd checks. The participant cap and
|
|
16
16
|
* in-process fan-out refusals come after the committed personas are read, so a persona-file error still wins.
|
|
@@ -51,9 +51,8 @@ export interface CuaParticipantsSetup {
|
|
|
51
51
|
} | undefined;
|
|
52
52
|
/** The subjects of the in-progress bundle, written before any participant starts. */
|
|
53
53
|
inProgress: {
|
|
54
|
-
subjects:
|
|
55
|
-
aggregateSubject:
|
|
56
|
-
provenance: CuaSubjectProvenanceArg | undefined;
|
|
54
|
+
subjects: RunSubjectProvenance[];
|
|
55
|
+
aggregateSubject: RunSubjectProvenance;
|
|
57
56
|
};
|
|
58
57
|
/** The refusal envelope, for a run that stops before its bundle. */
|
|
59
58
|
fail: (code: CuaActorStudyErrorCode, message: string, actorLabel?: string) => CuaActorStudyResult;
|
|
@@ -61,7 +60,6 @@ export interface CuaParticipantsSetup {
|
|
|
61
60
|
/** What only finishCuaRun reads besides the participants' outcomes. */
|
|
62
61
|
export interface CuaFinishFacts {
|
|
63
62
|
rerunLineage: RunRerunLineage | undefined;
|
|
64
|
-
publicRepo: string | undefined;
|
|
65
63
|
subjectArgs: Omit<Parameters<typeof projectParticipantSubjects>[0], "outcomes" | "dryRun">;
|
|
66
64
|
}
|
|
67
65
|
type PreparedCuaRun = {
|
|
@@ -20,7 +20,7 @@ import { phaseEvent, planEvent } from "../../study/run-study-events.js";
|
|
|
20
20
|
import { defaultSubjectPhaseSink } from "../../subject/steps.js";
|
|
21
21
|
import {} from "./bundle.js";
|
|
22
22
|
import { packRunLocalTree } from "./local-tree-pack.js";
|
|
23
|
-
import { projectParticipantSubjects
|
|
23
|
+
import { projectParticipantSubjects } from "./subject-projection.js";
|
|
24
24
|
import { participantSubjectEnv, } from "./types.js";
|
|
25
25
|
import { capacityShortfall } from "../../substrates/local/capacity.js";
|
|
26
26
|
import { studyPersonaIds } from "../../study/persona-resolve.js";
|
|
@@ -248,9 +248,6 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
248
248
|
dryRun: false,
|
|
249
249
|
});
|
|
250
250
|
const inProgressAggregateSubject = inProgressSubjects[0];
|
|
251
|
-
const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo, [
|
|
252
|
-
...participantSubjectEnv(plan.runner.subject),
|
|
253
|
-
]);
|
|
254
251
|
const bundleBase = {
|
|
255
252
|
run,
|
|
256
253
|
participantRuns,
|
|
@@ -287,11 +284,10 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
287
284
|
inProgress: {
|
|
288
285
|
subjects: inProgressSubjects,
|
|
289
286
|
aggregateSubject: inProgressAggregateSubject,
|
|
290
|
-
provenance: inProgressProvenance,
|
|
291
287
|
},
|
|
292
288
|
fail: admitted.fail,
|
|
293
289
|
},
|
|
294
|
-
finish: { rerunLineage: admitted.rerunLineage,
|
|
290
|
+
finish: { rerunLineage: admitted.rerunLineage, subjectArgs },
|
|
295
291
|
};
|
|
296
292
|
}
|
|
297
293
|
/** The participant deps every participant reads, with computer use's own overrides. */
|
|
@@ -3,11 +3,10 @@ import type { SubjectPhaseEvent } from "../../subject/steps.js";
|
|
|
3
3
|
import type { DesktopBrowserEvidence } from "../../substrates/e2b/desktop-browser.js";
|
|
4
4
|
import type { ActorPersonaRef } from "../../actors/contract.js";
|
|
5
5
|
import type { CuaLoopResult } from "../../actors/computer-use/loop.js";
|
|
6
|
-
import { type BundleRun, type RunBundle, type RunFeedbackCandidate, type RunProviderResource } from "../../run/bundle.js";
|
|
6
|
+
import { type BundleRun, type RunBundle, type RunFeedbackCandidate, type RunProviderResource, type RunSubjectProvenance } from "../../run/bundle.js";
|
|
7
7
|
import { type RunDesktopGeometry, type RunStream } from "../../run/streams.js";
|
|
8
8
|
import { type Verdict } from "../../run/judge.js";
|
|
9
9
|
import { type DesktopUsage } from "../../run/cost-summary.js";
|
|
10
|
-
import type { CuaSubjectProvenanceArg } from "./types.js";
|
|
11
10
|
/**
|
|
12
11
|
* The bundle of a single-participant run: one participant and no rerun. buildCuaRunBundle
|
|
13
12
|
* (bundle.ts) maps the run's base and state into these arguments.
|
|
@@ -70,9 +69,9 @@ export declare function buildSingleParticipantBundle(args: {
|
|
|
70
69
|
reportedFriction: boolean;
|
|
71
70
|
};
|
|
72
71
|
source: RunBundle["source"];
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
75
|
-
|
|
72
|
+
/** The subject as subject-projection.ts projects it (names and digests only, never values or
|
|
73
|
+
* command text): run.json records it as `subject`, and the subject event describes it. */
|
|
74
|
+
subject: RunSubjectProvenance;
|
|
76
75
|
/**
|
|
77
76
|
* Entry kind for the non-clone subject.declared event, which declares what the subject
|
|
78
77
|
* was. "local-app": an already-running local dev server driven in-process, un-pinnable, and
|