humanish 0.87.0 → 0.88.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/README.md +12 -2
- package/dist/actor-contract.d.ts +4 -1
- package/dist/actor-contract.js.map +1 -1
- package/dist/actor-goal-source.d.ts +5 -0
- package/dist/actor-goal-source.js +32 -0
- package/dist/actor-goal-source.js.map +1 -0
- package/dist/actor-stop-cause.d.ts +2 -0
- package/dist/actor-stop-cause.js +7 -2
- package/dist/actor-stop-cause.js.map +1 -1
- package/dist/computer-use.d.ts +3 -0
- package/dist/computer-use.js +30 -4
- package/dist/computer-use.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +10 -3
- package/dist/cua-actor-lab.js +35 -10
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/cua-admission-limit.d.ts +12 -0
- package/dist/cua-admission-limit.js +20 -0
- package/dist/cua-admission-limit.js.map +1 -0
- package/dist/cua-diagnostics.d.ts +38 -0
- package/dist/cua-diagnostics.js +68 -0
- package/dist/cua-diagnostics.js.map +1 -0
- package/dist/e2b-desktop-executor.js +4 -2
- package/dist/e2b-desktop-executor.js.map +1 -1
- package/dist/feedback.js +5 -3
- package/dist/feedback.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/observer-data.js +11 -4
- package/dist/observer-data.js.map +1 -1
- package/dist/openai-responses-cu.js +13 -2
- package/dist/openai-responses-cu.js.map +1 -1
- package/dist/program.d.ts +2 -0
- package/dist/program.js +9 -4
- package/dist/program.js.map +1 -1
- package/dist/run.d.ts +18 -5
- package/dist/run.js +70 -2
- package/dist/run.js.map +1 -1
- package/dist/stats.js +1 -1
- package/dist/stats.js.map +1 -1
- package/dist/telemetry.d.ts +3 -0
- package/dist/telemetry.js +15 -1
- package/dist/telemetry.js.map +1 -1
- package/docs/architecture/examples/state-driven-local-app/README.md +75 -0
- package/docs/architecture/examples/state-driven-local-app/app.mjs +48 -0
- package/docs/architecture/examples/state-driven-local-app/runner.mjs +104 -0
- package/docs/architecture/state-driven-executor.md +19 -26
- package/docs/contracts/adapter-admission.md +54 -0
- package/docs/contracts/run-bundle.md +8 -1
- package/docs/contracts/schemas.md +16 -2
- package/docs/goals/current.md +9 -4
- package/docs/ramp/README.md +11 -1
- package/docs/release/0.88.0-study-diagnostics.md +43 -0
- package/docs/release/0.88.1-completion-evidence-and-local-app.md +79 -0
- package/package.json +1 -1
package/dist/run.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CodexAppServerTrace } from "./codex-app-server.js";
|
|
2
2
|
import { type ActorStatus, type ActorTrace, type ActorTraceItem } from "./actor-contract.js";
|
|
3
|
+
import { type CuaGoalSource } from "./actor-goal-source.js";
|
|
3
4
|
import type { TaskFunnel } from "./tasks.js";
|
|
4
5
|
import { type CapturedGitState } from "./core/git-state.js";
|
|
5
6
|
import type { E2BDesktopModule } from "./e2b-desktop-launch.js";
|
|
@@ -844,7 +845,7 @@ export interface RunCostLine {
|
|
|
844
845
|
modelId?: string;
|
|
845
846
|
/** null = NOT MEASURED / no rate; never coerced to 0. */
|
|
846
847
|
estimatedCostUsd: number | null;
|
|
847
|
-
reason?: "no_rate_for_model" | "no_rate_for_desktop" | "no_token_usage" | "no_duration" | "closing_usage_unreported" | "no_desktop_resources" | "desktop_lifetime_incomplete";
|
|
848
|
+
reason?: "no_rate_for_model" | "no_rate_for_desktop" | "no_token_usage" | "no_duration" | "closing_usage_unreported" | "interaction_usage_unreported" | "no_desktop_resources" | "desktop_lifetime_incomplete";
|
|
848
849
|
/** Pricing provenance date; non-null iff estimatedCostUsd is non-null. */
|
|
849
850
|
ratesAsOf: string | null;
|
|
850
851
|
source?: string;
|
|
@@ -933,7 +934,7 @@ export interface RunRerunLineage {
|
|
|
933
934
|
export interface ParticipantOutcomes {
|
|
934
935
|
/** Participants whose sessions reached a terminal state — the denominator for every count below. */
|
|
935
936
|
total: number;
|
|
936
|
-
/**
|
|
937
|
+
/** Recorded successful sessions; completion provenance depends on the actor and its evidence. */
|
|
937
938
|
reachedGoal: number;
|
|
938
939
|
/** Stopped trying. A finding about the product. */
|
|
939
940
|
abandoned: number;
|
|
@@ -1011,11 +1012,23 @@ export interface StudyTaskFunnel {
|
|
|
1011
1012
|
export declare function aggregateTaskFunnels(funnels: readonly TaskFunnel[]): StudyTaskFunnel | undefined;
|
|
1012
1013
|
/** The funnel as one line, denominator on every number: `signup 2/2 · verify-email 1/2`. */
|
|
1013
1014
|
export declare function formatStudyTaskFunnel(funnel: StudyTaskFunnel): string;
|
|
1014
|
-
|
|
1015
|
-
export declare function formatParticipantOutcomes(outcomes: ParticipantOutcomes, terminalCauses?: readonly {
|
|
1015
|
+
type ParticipantOutcomeDetail = {
|
|
1016
1016
|
status: ActorStatus;
|
|
1017
1017
|
label?: string;
|
|
1018
|
-
|
|
1018
|
+
goalSource?: CuaGoalSource;
|
|
1019
|
+
};
|
|
1020
|
+
/** One line a stakeholder can read, with the denominator attached to every number. */
|
|
1021
|
+
export declare function formatParticipantOutcomes(outcomes: ParticipantOutcomes, terminalCauses?: readonly ParticipantOutcomeDetail[]): string;
|
|
1022
|
+
/** Presentation details tolerate optional legacy actor payloads without changing their tallies. */
|
|
1023
|
+
export declare function participantOutcomeDetails(streams: readonly {
|
|
1024
|
+
actor?: unknown;
|
|
1025
|
+
status?: unknown;
|
|
1026
|
+
}[]): ParticipantOutcomeDetail[];
|
|
1027
|
+
/** Refresh a CUA completion claim from recorded traces, leaving original evidence and enums intact. */
|
|
1028
|
+
export declare function withCuaReviewProvenance(review: ReviewSummary, streams: readonly {
|
|
1029
|
+
actor?: unknown;
|
|
1030
|
+
status?: unknown;
|
|
1031
|
+
}[]): ReviewSummary;
|
|
1019
1032
|
export declare function buildRunSource(args: {
|
|
1020
1033
|
cwd: string;
|
|
1021
1034
|
capturedAt?: Date | string;
|
package/dist/run.js
CHANGED
|
@@ -13,6 +13,8 @@ import { CODEX_APP_SERVER_TRACE_SCHEMA, runCodexAppServerSessionInPreparedRoot }
|
|
|
13
13
|
import { getActor } from "./actor-registry.js";
|
|
14
14
|
import { artifactReferenceIfWritten, hasWrittenScreenshot } from "./artifact-reference.js";
|
|
15
15
|
import { ACTOR_TRACE_SCHEMA } from "./actor-contract.js";
|
|
16
|
+
import { cuaGoalSource, isCuaTrace, CUA_COMPLETION_NOTE } from "./actor-goal-source.js";
|
|
17
|
+
import { actorEnding } from "./actor-stop-cause.js";
|
|
16
18
|
import { captureGitState, GIT_STATE_SCHEMA } from "./core/git-state.js";
|
|
17
19
|
import { inspectVerifiedGitWorkspace } from "./core/git-workspace.js";
|
|
18
20
|
import { mapWithConcurrency } from "./concurrency.js";
|
|
@@ -137,11 +139,34 @@ export function formatStudyTaskFunnel(funnel) {
|
|
|
137
139
|
})
|
|
138
140
|
.join(" · ");
|
|
139
141
|
}
|
|
142
|
+
function participantCompletionLine(outcomes, terminalCauses) {
|
|
143
|
+
const completions = terminalCauses.filter((entry) => entry.status === "passed");
|
|
144
|
+
const reported = completions.filter((entry) => entry.goalSource === "participant_report").length;
|
|
145
|
+
const matched = completions.filter((entry) => entry.goalSource === "condition_matched").length;
|
|
146
|
+
let goalLine = outcomes.reachedGoal === 0
|
|
147
|
+
? `0/${outcomes.total} recorded completions`
|
|
148
|
+
: `${outcomes.reachedGoal}/${outcomes.total} reached the goal`;
|
|
149
|
+
if (outcomes.reachedGoal > 0 && terminalCauses.some((entry) => entry.goalSource !== undefined)) {
|
|
150
|
+
const count = `${outcomes.reachedGoal}/${outcomes.total}`;
|
|
151
|
+
goalLine = completions.length !== outcomes.reachedGoal
|
|
152
|
+
? `${count} recorded completions (completion source unavailable)`
|
|
153
|
+
: reported === outcomes.reachedGoal
|
|
154
|
+
? `${count} reported reaching the goal`
|
|
155
|
+
: matched === outcomes.reachedGoal
|
|
156
|
+
? `${count} met a recorded completion condition`
|
|
157
|
+
: `${count} recorded completions (${[
|
|
158
|
+
reported > 0 ? `${reported} participant-reported` : undefined,
|
|
159
|
+
matched > 0 ? `${matched} condition-matched` : undefined,
|
|
160
|
+
outcomes.reachedGoal - reported - matched > 0 ? `${outcomes.reachedGoal - reported - matched} other or unavailable source` : undefined
|
|
161
|
+
].filter(Boolean).join(", ")})`;
|
|
162
|
+
}
|
|
163
|
+
return goalLine;
|
|
164
|
+
}
|
|
140
165
|
/** One line a stakeholder can read, with the denominator attached to every number. */
|
|
141
166
|
export function formatParticipantOutcomes(outcomes, terminalCauses = []) {
|
|
142
167
|
if (outcomes.total === 0)
|
|
143
168
|
return "no participants reached a terminal state";
|
|
144
|
-
const parts = [
|
|
169
|
+
const parts = [participantCompletionLine(outcomes, terminalCauses)];
|
|
145
170
|
// Detail may explain a recorded outcome, but must never change its count or invent a match
|
|
146
171
|
// between a tally and an incomplete set of traces.
|
|
147
172
|
const append = (count, statuses, fallback) => {
|
|
@@ -174,6 +199,46 @@ export function formatParticipantOutcomes(outcomes, terminalCauses = []) {
|
|
|
174
199
|
parts.push(`${outcomes.reportedFriction} reported friction`);
|
|
175
200
|
return parts.join(", ");
|
|
176
201
|
}
|
|
202
|
+
/** Presentation details tolerate optional legacy actor payloads without changing their tallies. */
|
|
203
|
+
export function participantOutcomeDetails(streams) {
|
|
204
|
+
return streams.flatMap((stream) => {
|
|
205
|
+
if (!isRecord(stream.actor))
|
|
206
|
+
return [];
|
|
207
|
+
const actor = stream.actor;
|
|
208
|
+
const goalSource = cuaGoalSource(actor, stream.status);
|
|
209
|
+
if (!["passed", "abandoned", "incomplete", "blocked", "timed_out", "failed"].includes(String(actor.status))) {
|
|
210
|
+
return goalSource === "unavailable" ? [{ status: "passed", goalSource }] : [];
|
|
211
|
+
}
|
|
212
|
+
const ending = Array.isArray(actor.items) && actor.items.every(isRecord) ? actorEnding(actor) : undefined;
|
|
213
|
+
return [{ status: actor.status,
|
|
214
|
+
...(ending === undefined ? {} : { label: ending.label }),
|
|
215
|
+
...(goalSource === undefined ? {} : { goalSource }) }];
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/** Refresh a CUA completion claim from recorded traces, leaving original evidence and enums intact. */
|
|
219
|
+
export function withCuaReviewProvenance(review, streams) {
|
|
220
|
+
const details = participantOutcomeDetails(streams);
|
|
221
|
+
if (!isRecord(review.participants)
|
|
222
|
+
|| !["total", "reachedGoal", "abandoned", "ranOut", "blocked", "harnessFailed", "reportedFriction"].every((key) => isNonNegativeSafeInteger(review.participants[key]))
|
|
223
|
+
|| (review.participants.reachedGoal === 0
|
|
224
|
+
? !streams.some((stream) => isCuaTrace(stream.actor))
|
|
225
|
+
: !details.some((entry) => entry.goalSource !== undefined)))
|
|
226
|
+
return review;
|
|
227
|
+
const outcomes = formatParticipantOutcomes(review.participants, details);
|
|
228
|
+
// Preserve rerun context, participant narration and adapter-specific findings. Refreshing a
|
|
229
|
+
// historical summary qualifies its old tally instead of silently discarding that context.
|
|
230
|
+
const header = `Run gate: ${review.verdict}. Participants: ${outcomes}.${review.tasks ? ` Tasks: ${formatStudyTaskFunnel(review.tasks)}.` : ""}`;
|
|
231
|
+
const prefix = `${header} Recorded summary: `;
|
|
232
|
+
const recorded = review.summary.startsWith(prefix) ? review.summary.slice(prefix.length) : review.summary;
|
|
233
|
+
const oldGoal = `${review.participants.reachedGoal}/${review.participants.total} reached the goal`;
|
|
234
|
+
const qualified = recorded.split(oldGoal).join(participantCompletionLine(review.participants, details));
|
|
235
|
+
return {
|
|
236
|
+
...review,
|
|
237
|
+
summary: `${prefix}${qualified}`,
|
|
238
|
+
gaps: review.participants.reachedGoal === 0 ? review.gaps
|
|
239
|
+
: [...review.gaps.filter((gap) => gap !== CUA_COMPLETION_NOTE), CUA_COMPLETION_NOTE]
|
|
240
|
+
};
|
|
241
|
+
}
|
|
177
242
|
export async function buildRunSource(args) {
|
|
178
243
|
const gitOptions = args.capturedAt === undefined ? {} : { capturedAt: args.capturedAt };
|
|
179
244
|
return {
|
|
@@ -2988,8 +3053,11 @@ export async function readReview(cwdInput, runInput) {
|
|
|
2988
3053
|
}
|
|
2989
3054
|
};
|
|
2990
3055
|
}
|
|
3056
|
+
const bundle = runPaths ? await readRunJsonIfExists(runPaths, "run.json") : null;
|
|
3057
|
+
const projected = isRecord(bundle) && Array.isArray(bundle.streams)
|
|
3058
|
+
? withCuaReviewProvenance(review, bundle.streams.filter(isRecord)) : review;
|
|
2991
3059
|
return {
|
|
2992
|
-
...
|
|
3060
|
+
...projected,
|
|
2993
3061
|
path: path.relative(cwd, path.join(runPaths.absoluteRunRoot, "review.json")),
|
|
2994
3062
|
runId: path.basename(runPaths.absoluteRunRoot)
|
|
2995
3063
|
};
|