humanish 0.88.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-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/cua-actor-lab.js +6 -6
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-desktop-executor.js +4 -2
- package/dist/e2b-desktop-executor.js.map +1 -1
- package/dist/feedback.js +4 -12
- package/dist/feedback.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -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/run.d.ts +17 -4
- 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/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/schemas.md +16 -2
- package/docs/goals/current.md +9 -4
- package/docs/ramp/README.md +7 -1
- package/docs/release/0.88.1-completion-evidence-and-local-app.md +79 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,9 +201,19 @@ Mobile viewport and touch flags do not certify gesture equivalence. The
|
|
|
201
201
|
qualifies the historical phone-lane results: they describe Humanish's measured input path,
|
|
202
202
|
not established physical-device app behavior.
|
|
203
203
|
|
|
204
|
-
####
|
|
204
|
+
#### Drive an already-running local app
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
Use a custom executor and non-vision provider to drive your app's state contract
|
|
207
|
+
without E2B. The [runnable npm example](docs/architecture/examples/state-driven-local-app/README.md)
|
|
208
|
+
includes a synthetic loopback app, deterministic provider, verification and cleanup:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
node node_modules/humanish/docs/architecture/examples/state-driven-local-app/runner.mjs
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Run it after installing `humanish`. It makes no model calls; it proves the
|
|
215
|
+
integration, not persona behavior. See [state-driven local adapters](https://humanish.dev/docs/computer-use#state-driven-local-adapters)
|
|
216
|
+
for the supported library seam.
|
|
207
217
|
|
|
208
218
|
## Browser Scenario Manifests
|
|
209
219
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Presentation provenance for computer-use completion; never reclassifies the stored outcome. */
|
|
2
|
+
export type CuaGoalSource = "participant_report" | "condition_matched" | "unavailable";
|
|
3
|
+
export declare function isCuaTrace(value: unknown): boolean;
|
|
4
|
+
export declare function cuaGoalSource(value: unknown, recordedStatus?: unknown): CuaGoalSource | undefined;
|
|
5
|
+
export declare const CUA_COMPLETION_NOTE = "Participant reports alone do not establish task success. A matched stop condition establishes only its declared condition. Run gate and share-safety results are separate.";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function isCuaTrace(value) {
|
|
2
|
+
if (typeof value !== "object" || value === null)
|
|
3
|
+
return false;
|
|
4
|
+
const trace = value;
|
|
5
|
+
return trace.lane === "computer-use" || trace.protocol === "cua-loop";
|
|
6
|
+
}
|
|
7
|
+
export function cuaGoalSource(value, recordedStatus) {
|
|
8
|
+
if (!isCuaTrace(value))
|
|
9
|
+
return undefined;
|
|
10
|
+
const trace = value;
|
|
11
|
+
if (trace.status !== "passed")
|
|
12
|
+
return recordedStatus === "passed" || recordedStatus === "complete" ? "unavailable" : undefined;
|
|
13
|
+
if (trace.lane !== "computer-use" || trace.protocol !== "cua-loop"
|
|
14
|
+
|| trace.completionReason !== "goal_satisfied")
|
|
15
|
+
return "unavailable";
|
|
16
|
+
if (!Array.isArray(trace.items) || !trace.items.every((item) => typeof item === "object" && item !== null
|
|
17
|
+
&& !Array.isArray(item) && typeof item.id === "string" && typeof item.kind === "string"
|
|
18
|
+
&& typeof item.title === "string" && (item.lifecycle === "started" || item.lifecycle === "completed"))) {
|
|
19
|
+
return "unavailable";
|
|
20
|
+
}
|
|
21
|
+
// These notices are written by the loop after a matched predicate/window, not by the model.
|
|
22
|
+
if (trace.items.some((item) => item.kind === "notice"
|
|
23
|
+
&& item.lifecycle === "completed" && item.status === "matched"
|
|
24
|
+
&& typeof item.title === "string"
|
|
25
|
+
&& (item.title.startsWith("stopWhen matched:") || item.title === "dwell window complete"))) {
|
|
26
|
+
return "condition_matched";
|
|
27
|
+
}
|
|
28
|
+
// A legacy trace without enough detail cannot establish which endpoint ended the loop.
|
|
29
|
+
return trace.items.length > 0 ? "participant_report" : "unavailable";
|
|
30
|
+
}
|
|
31
|
+
export const CUA_COMPLETION_NOTE = "Participant reports alone do not establish task success. A matched stop condition establishes only its declared condition. Run gate and share-safety results are separate.";
|
|
32
|
+
//# sourceMappingURL=actor-goal-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor-goal-source.js","sourceRoot":"","sources":["../src/actor-goal-source.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,OAAO,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,cAAwB;IACpE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/H,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU;WAC7D,KAAK,CAAC,gBAAgB,KAAK,gBAAgB;QAAE,OAAO,aAAa,CAAC;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;WACpG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;WACpF,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,EAAE,CAAC;QACzG,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,4FAA4F;IAC5F,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;WACzE,IAAI,CAAC,SAAS,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;WAC3D,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;WAC9B,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IACD,uFAAuF;IACvF,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,4KAA4K,CAAC"}
|
package/dist/cua-actor-lab.js
CHANGED
|
@@ -61,7 +61,7 @@ import { actorEnding } from "./actor-stop-cause.js";
|
|
|
61
61
|
import { assertPreparedSelectedOutputDirectory, assertSafeOutputPathSegment, prepareContainedOutputDirectory, prepareSelectedOutputDirectory, writeContainedOutputFile, writePreparedRunLatestPointer } from "./selected-output-paths.js";
|
|
62
62
|
import { prepareRunArtifactPaths, validatePreparedRunArtifactPaths } from "./run-paths.js";
|
|
63
63
|
import { createLocalTreeArchive } from "./source-archive.js";
|
|
64
|
-
import { buildRunSource, loadRunBundle, PUBLIC_TARGET_CWD, REVIEW_SCHEMA, RUN_BUNDLE_SCHEMA, aggregateTaskFunnels, formatParticipantOutcomes, formatStudyTaskFunnel, tallyParticipantOutcomes } from "./run.js";
|
|
64
|
+
import { buildRunSource, loadRunBundle, PUBLIC_TARGET_CWD, REVIEW_SCHEMA, RUN_BUNDLE_SCHEMA, aggregateTaskFunnels, formatParticipantOutcomes, formatStudyTaskFunnel, tallyParticipantOutcomes, withCuaReviewProvenance } from "./run.js";
|
|
65
65
|
import { estimateActorCost, estimateDesktopCost, estimateAllocatedDesktopCost, MODEL_RATES, round6 } from "./pricing.js";
|
|
66
66
|
import { observeDesktopResources } from "./e2b-desktop-resources.js";
|
|
67
67
|
export const CUA_ACTOR_LAB_SCHEMA = "humanish.cua-lab-result.v2";
|
|
@@ -4465,7 +4465,7 @@ export function buildCuaBundle(args) {
|
|
|
4465
4465
|
: args.credibility?.noEngagement === true
|
|
4466
4466
|
? "Not counted as a pass: the participant took no actions and said nothing."
|
|
4467
4467
|
: "Not counted as a pass: the participant's final message described a blocker.";
|
|
4468
|
-
const review = {
|
|
4468
|
+
const review = withCuaReviewProvenance({
|
|
4469
4469
|
schema: REVIEW_SCHEMA,
|
|
4470
4470
|
verdict: args.inProgress === true
|
|
4471
4471
|
? "contract_proof_only"
|
|
@@ -4486,7 +4486,7 @@ export function buildCuaBundle(args) {
|
|
|
4486
4486
|
: args.inProgress === true
|
|
4487
4487
|
? ["Live desktop session is still running."]
|
|
4488
4488
|
: ["Live desktop session not yet run (dry-run contract only)."]
|
|
4489
|
-
};
|
|
4489
|
+
}, [stream]);
|
|
4490
4490
|
return {
|
|
4491
4491
|
schema: RUN_BUNDLE_SCHEMA,
|
|
4492
4492
|
runId: args.runId,
|
|
@@ -4922,7 +4922,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
4922
4922
|
const ending = actorEnding(outcome.session.trace);
|
|
4923
4923
|
return { status: outcome.session.status, ...(ending === undefined ? {} : { label: ending.label }) };
|
|
4924
4924
|
});
|
|
4925
|
-
const review = {
|
|
4925
|
+
const review = withCuaReviewProvenance({
|
|
4926
4926
|
schema: REVIEW_SCHEMA,
|
|
4927
4927
|
verdict,
|
|
4928
4928
|
...(participants === undefined ? {} : { participants }),
|
|
@@ -4946,7 +4946,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
4946
4946
|
|| outcome.session === undefined
|
|
4947
4947
|
|| outcome.session.status !== "passed")
|
|
4948
4948
|
.map(({ spec, outcome }) => `${spec.laneId}: ${outcome?.skippedReason ?? outcome?.sessionError ?? outcome?.session?.reason ?? "did not pass"}`)
|
|
4949
|
-
};
|
|
4949
|
+
}, streams);
|
|
4950
4950
|
const anyRaw = (outcomes ?? []).some((outcome) => outcome.session?.trace.redaction.screenshots === "raw");
|
|
4951
4951
|
const ranLive = (outcomes ?? []).some((outcome) => outcome.session !== undefined || outcome.sessionError !== undefined);
|
|
4952
4952
|
const configuredBrowser = config.execution?.desktop?.browser;
|
|
@@ -5130,7 +5130,7 @@ function renderCuaReviewMarkdown(bundle) {
|
|
|
5130
5130
|
"",
|
|
5131
5131
|
`- run: ${bundle.runId}`,
|
|
5132
5132
|
`- mode: ${bundle.mode}`,
|
|
5133
|
-
`-
|
|
5133
|
+
`- run gate: ${bundle.review.verdict}`,
|
|
5134
5134
|
`- summary: ${bundle.review.summary}`,
|
|
5135
5135
|
...(provenance ? [`- subject: ${provenance.message}`] : []),
|
|
5136
5136
|
...(trace
|