humanish 0.97.0 → 0.99.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.
Files changed (151) hide show
  1. package/AGENTS.md +86 -79
  2. package/CONTRIBUTING.md +7 -2
  3. package/README.md +8 -1
  4. package/dist/actor-contract.d.ts +35 -1
  5. package/dist/actor-contract.js +38 -0
  6. package/dist/actor-contract.js.map +1 -1
  7. package/dist/adapter-extension.js +1 -0
  8. package/dist/adapter-extension.js.map +1 -1
  9. package/dist/browser-control-client.d.ts +14 -0
  10. package/dist/browser-control-client.js +134 -0
  11. package/dist/browser-control-client.js.map +1 -0
  12. package/dist/browser-control-dispatcher.d.ts +14 -0
  13. package/dist/browser-control-dispatcher.js +109 -0
  14. package/dist/browser-control-dispatcher.js.map +1 -0
  15. package/dist/browser-control-protocol.d.ts +371 -0
  16. package/dist/browser-control-protocol.js +155 -0
  17. package/dist/browser-control-protocol.js.map +1 -0
  18. package/dist/browser-control-transport.d.ts +24 -0
  19. package/dist/browser-control-transport.js +156 -0
  20. package/dist/browser-control-transport.js.map +1 -0
  21. package/dist/comms-lease-store.d.ts +1 -0
  22. package/dist/comms-lease-store.js +9 -3
  23. package/dist/comms-lease-store.js.map +1 -1
  24. package/dist/computer-use-actor.d.ts +2 -2
  25. package/dist/computer-use-actor.js +6 -1
  26. package/dist/computer-use-actor.js.map +1 -1
  27. package/dist/computer-use.d.ts +23 -1
  28. package/dist/computer-use.js +253 -70
  29. package/dist/computer-use.js.map +1 -1
  30. package/dist/cua-actor-lab.d.ts +6 -1
  31. package/dist/cua-actor-lab.js +55 -15
  32. package/dist/cua-actor-lab.js.map +1 -1
  33. package/dist/cua-executor-error.d.ts +31 -0
  34. package/dist/cua-executor-error.js +48 -0
  35. package/dist/cua-executor-error.js.map +1 -0
  36. package/dist/cua-provider-error.d.ts +12 -0
  37. package/dist/cua-provider-error.js +28 -0
  38. package/dist/cua-provider-error.js.map +1 -0
  39. package/dist/desktop-session.js +3 -1
  40. package/dist/desktop-session.js.map +1 -1
  41. package/dist/doctor-lab.d.ts +2 -0
  42. package/dist/doctor-lab.js +26 -8
  43. package/dist/doctor-lab.js.map +1 -1
  44. package/dist/e2b-desktop-executor.d.ts +1 -24
  45. package/dist/e2b-desktop-executor.js +2 -127
  46. package/dist/e2b-desktop-executor.js.map +1 -1
  47. package/dist/e2b-terminal-lab.js +1 -0
  48. package/dist/e2b-terminal-lab.js.map +1 -1
  49. package/dist/frame-signature.d.ts +24 -0
  50. package/dist/frame-signature.js +128 -0
  51. package/dist/frame-signature.js.map +1 -0
  52. package/dist/guest-bootstrap.d.ts +43 -0
  53. package/dist/guest-bootstrap.js +240 -0
  54. package/dist/guest-bootstrap.js.map +1 -0
  55. package/dist/guest-browser-tools.d.ts +8 -0
  56. package/dist/guest-browser-tools.js +66 -0
  57. package/dist/guest-browser-tools.js.map +1 -0
  58. package/dist/guest-chromium-text.d.ts +27 -0
  59. package/dist/guest-chromium-text.js +281 -0
  60. package/dist/guest-chromium-text.js.map +1 -0
  61. package/dist/guest-desktop-executor.d.ts +22 -0
  62. package/dist/guest-desktop-executor.js +177 -0
  63. package/dist/guest-desktop-executor.js.map +1 -0
  64. package/dist/guest-desktop-native.d.ts +14 -0
  65. package/dist/guest-desktop-native.js +131 -0
  66. package/dist/guest-desktop-native.js.map +1 -0
  67. package/dist/guest-runtime-desktop.d.ts +35 -0
  68. package/dist/guest-runtime-desktop.js +231 -0
  69. package/dist/guest-runtime-desktop.js.map +1 -0
  70. package/dist/guest-runtime-main.d.ts +1 -0
  71. package/dist/guest-runtime-main.js +31 -0
  72. package/dist/guest-runtime-main.js.map +1 -0
  73. package/dist/guest-runtime-revision.d.ts +1 -0
  74. package/dist/guest-runtime-revision.js +3 -0
  75. package/dist/guest-runtime-revision.js.map +1 -0
  76. package/dist/guest-runtime.d.ts +25 -0
  77. package/dist/guest-runtime.js +96 -0
  78. package/dist/guest-runtime.js.map +1 -0
  79. package/dist/lab-config.js +10 -3
  80. package/dist/lab-config.js.map +1 -1
  81. package/dist/lab-engine.js +6 -0
  82. package/dist/lab-engine.js.map +1 -1
  83. package/dist/lab-summary.d.ts +2 -0
  84. package/dist/lab-summary.js +5 -0
  85. package/dist/lab-summary.js.map +1 -1
  86. package/dist/local-agent-cli.js +1 -1
  87. package/dist/local-agent-cli.js.map +1 -1
  88. package/dist/local-firecracker-desktop.d.ts +13 -0
  89. package/dist/local-firecracker-desktop.js +166 -0
  90. package/dist/local-firecracker-desktop.js.map +1 -0
  91. package/dist/local-firecracker-study.d.ts +9 -0
  92. package/dist/local-firecracker-study.js +93 -0
  93. package/dist/local-firecracker-study.js.map +1 -0
  94. package/dist/local-runtime-config.d.ts +6 -0
  95. package/dist/local-runtime-config.js +56 -0
  96. package/dist/local-runtime-config.js.map +1 -0
  97. package/dist/local-runtime-host.d.ts +31 -0
  98. package/dist/local-runtime-host.js +128 -0
  99. package/dist/local-runtime-host.js.map +1 -0
  100. package/dist/local-runtime-release.d.ts +5 -0
  101. package/dist/local-runtime-release.js +18 -0
  102. package/dist/local-runtime-release.js.map +1 -0
  103. package/dist/local-runtime-ssh.d.ts +21 -0
  104. package/dist/local-runtime-ssh.js +89 -0
  105. package/dist/local-runtime-ssh.js.map +1 -0
  106. package/dist/local-runtime.d.ts +24 -0
  107. package/dist/local-runtime.js +131 -0
  108. package/dist/local-runtime.js.map +1 -0
  109. package/dist/observer-app.html +4 -4
  110. package/dist/pricing.d.ts +22 -1
  111. package/dist/pricing.js +22 -0
  112. package/dist/pricing.js.map +1 -1
  113. package/dist/program.js +26 -0
  114. package/dist/program.js.map +1 -1
  115. package/dist/restricted-codex-participant-policy.d.ts +39 -0
  116. package/dist/restricted-codex-participant-policy.js +69 -0
  117. package/dist/restricted-codex-participant-policy.js.map +1 -0
  118. package/dist/restricted-codex-participant-run.d.ts +20 -0
  119. package/dist/restricted-codex-participant-run.js +78 -0
  120. package/dist/restricted-codex-participant-run.js.map +1 -0
  121. package/dist/restricted-codex-participant.d.ts +14 -0
  122. package/dist/restricted-codex-participant.js +178 -0
  123. package/dist/restricted-codex-participant.js.map +1 -0
  124. package/dist/restricted-codex-session.d.ts +2 -2
  125. package/dist/restricted-codex-session.js +34 -26
  126. package/dist/restricted-codex-session.js.map +1 -1
  127. package/dist/run-detail.js +4 -2
  128. package/dist/run-detail.js.map +1 -1
  129. package/dist/run.d.ts +12 -5
  130. package/dist/run.js +17 -1
  131. package/dist/run.js.map +1 -1
  132. package/dist/shared-world-lab.js +2 -2
  133. package/dist/shared-world-lab.js.map +1 -1
  134. package/dist/study-analysis-job.d.ts +2 -2
  135. package/dist/study-analysis-validation.d.ts +14 -14
  136. package/dist/study-costs.js +6 -0
  137. package/dist/study-costs.js.map +1 -1
  138. package/dist/tui-app.js +37 -37
  139. package/docs/architecture/browser-control.md +117 -0
  140. package/docs/architecture/guest-desktop.md +87 -0
  141. package/docs/architecture/local-browser-runtime.md +147 -0
  142. package/docs/architecture/restricted-codex-analysis.md +8 -4
  143. package/docs/architecture/runtime-broker-core.md +30 -0
  144. package/docs/contracts/schemas.md +1 -1
  145. package/docs/goals/current.md +26 -9
  146. package/docs/product/open-source-install-experience.md +7 -0
  147. package/docs/ramp/README.md +28 -13
  148. package/docs/release/0.98.0-local-browser-studies.md +31 -0
  149. package/docs/release/0.99.0-local-browser-mac.md +34 -0
  150. package/package.json +4 -2
  151. package/skills/humanish/SKILL.md +23 -3
@@ -0,0 +1,39 @@
1
+ import { type CuaTurn } from "./computer-use.js";
2
+ import type { ActorExecutionProfile, ParticipantClosingReport } from "./actor-contract.js";
3
+ export declare const PARTICIPANT_PROFILE: Readonly<ActorExecutionProfile>;
4
+ export declare const PARTICIPANT_LIMITS: Readonly<{
5
+ instructions: number;
6
+ hint: number;
7
+ history: number;
8
+ historyTurns: 8;
9
+ narration: 2000;
10
+ output: number;
11
+ actions: 4;
12
+ requestMs: 180000;
13
+ cleanupMs: 5000;
14
+ }>;
15
+ export declare const PARTICIPANT_TURN_SCHEMA: Record<string, unknown>;
16
+ export declare const PARTICIPANT_CLOSING_SCHEMA: {
17
+ type: string;
18
+ additionalProperties: boolean;
19
+ required: string[];
20
+ properties: {
21
+ summary: {
22
+ type: string;
23
+ minLength: number;
24
+ maxLength: number;
25
+ };
26
+ frictionReports: {
27
+ type: string;
28
+ maxItems: number;
29
+ items: {
30
+ type: string;
31
+ minLength: number;
32
+ maxLength: number;
33
+ };
34
+ };
35
+ };
36
+ };
37
+ /** Humanish output schema, not a provider-wire parser. Reject the whole proposal. */
38
+ export declare function parseParticipantTurn(value: unknown): CuaTurn;
39
+ export declare function parseParticipantClosing(value: unknown): ParticipantClosingReport;
@@ -0,0 +1,69 @@
1
+ import { z } from "zod";
2
+ import { browserControlActionSchema, validateBrowserControlAction } from "./browser-control-protocol.js";
3
+ import { validClosingReport } from "./computer-use.js";
4
+ export const PARTICIPANT_PROFILE = Object.freeze({
5
+ schema: "humanish.actor-execution-profile.v1", transport: "codex-app-server", authentication: "chatgpt-account",
6
+ billing: "account-unknown", requestedModel: "gpt-6-astra", reasoningEffort: "low", cliVersion: "0.154.0",
7
+ toolPolicy: "restricted-codex-v1", participantSchema: "humanish.restricted-participant-turn.v1", memoryPolicy: "recent-eight-16k-v1"
8
+ });
9
+ export const PARTICIPANT_LIMITS = Object.freeze({ instructions: 64 * 1024, hint: 8 * 1024, history: 16 * 1024,
10
+ historyTurns: 8, narration: 2000, output: 256 * 1024, actions: 4, requestMs: 180_000, cleanupMs: 5000 });
11
+ const envelope = z.strictObject({ schema: z.literal(PARTICIPANT_PROFILE.participantSchema),
12
+ narration: z.string().max(PARTICIPANT_LIMITS.narration), done: z.boolean(),
13
+ outcome: z.enum(["reached", "not_reached", "blocked"]).nullable(),
14
+ actions: z.array(browserControlActionSchema).max(PARTICIPANT_LIMITS.actions) });
15
+ /** Strict structured output requires all object keys. Null selects the existing
16
+ * executor default for click.button/wait.ms; it is never a new browser action. */
17
+ function outputSchema(value) {
18
+ if (Array.isArray(value))
19
+ return value.map(outputSchema);
20
+ if (value === null || typeof value !== "object")
21
+ return value;
22
+ const result = Object.fromEntries(Object.entries(value).filter(([key]) => key !== "$schema")
23
+ .map(([key, v]) => [key === "oneOf" ? "anyOf" : key, outputSchema(v)]));
24
+ if (result.type === "object" && result.properties) {
25
+ const properties = result.properties;
26
+ const required = result.required;
27
+ for (const key of Object.keys(properties))
28
+ if (!required.includes(key))
29
+ properties[key] = { anyOf: [properties[key], { type: "null" }] };
30
+ result.required = Object.keys(properties);
31
+ }
32
+ return result;
33
+ }
34
+ export const PARTICIPANT_TURN_SCHEMA = outputSchema(z.toJSONSchema(envelope, { io: "input" }));
35
+ export const PARTICIPANT_CLOSING_SCHEMA = {
36
+ type: "object", additionalProperties: false, required: ["summary", "frictionReports"], properties: {
37
+ summary: { type: "string", minLength: 1, maxLength: 4000 },
38
+ frictionReports: { type: "array", maxItems: 8, items: { type: "string", minLength: 1, maxLength: 2000 } }
39
+ }
40
+ };
41
+ /** Humanish output schema, not a provider-wire parser. Reject the whole proposal. */
42
+ export function parseParticipantTurn(value) {
43
+ if (Buffer.byteLength(JSON.stringify(value) ?? "") > PARTICIPANT_LIMITS.output)
44
+ throw new Error("invalid_response");
45
+ const source = value;
46
+ const normalized = source && Array.isArray(source.actions) ? { ...source, actions: source.actions.map((action) => {
47
+ if (!action || typeof action !== "object" || Array.isArray(action))
48
+ return action;
49
+ const result = { ...action };
50
+ if (result.kind === "click" && result.button === null)
51
+ delete result.button;
52
+ if (result.kind === "wait" && result.ms === null)
53
+ delete result.ms;
54
+ return result;
55
+ }) } : value;
56
+ const v = envelope.parse(normalized);
57
+ if (Buffer.byteLength(v.narration) > PARTICIPANT_LIMITS.narration ||
58
+ (v.done ? v.actions.length !== 0 || v.outcome === null || !v.narration.trim() : v.actions.length === 0 || v.outcome !== null)) {
59
+ throw new Error("invalid_response");
60
+ }
61
+ return { actions: v.actions.map(validateBrowserControlAction), pendingSafetyChecks: [], done: v.done,
62
+ ...(v.narration ? { message: v.narration } : {}), ...(v.outcome === null ? {} : { outcome: v.outcome }) };
63
+ }
64
+ export function parseParticipantClosing(value) {
65
+ if (!validClosingReport(value))
66
+ throw new Error("invalid_response");
67
+ return { summary: value.summary, frictionReports: [...value.frictionReports] };
68
+ }
69
+ //# sourceMappingURL=restricted-codex-participant-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restricted-codex-participant-policy.js","sourceRoot":"","sources":["../src/restricted-codex-participant-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { LabConfig } from "./lab-config.js";
2
+ import { type LabOutcome } from "./lab-engine.js";
3
+ import type { DesktopSession, DesktopReleaseResult } from "./desktop-session.js";
4
+ import type { AutomaticAnalysisHooks } from "./automatic-analysis-completion.js";
5
+ import { type ParticipantProviderCloseResult, type RestrictedParticipantOptions } from "./restricted-codex-participant.js";
6
+ /** Internal, explicit single-participant consumer. Uses the existing producer and
7
+ * its automatic-completion boundary; never allocates or discovers a desktop. */
8
+ export declare function runRestrictedParticipantStudy(options: {
9
+ cwd: string;
10
+ config: LabConfig;
11
+ desktop: DesktopSession;
12
+ participant?: RestrictedParticipantOptions;
13
+ signal?: AbortSignal;
14
+ runId?: string;
15
+ automaticAnalysis?: AutomaticAnalysisHooks;
16
+ }): Promise<{
17
+ outcome: LabOutcome;
18
+ providerCleanup: ParticipantProviderCloseResult;
19
+ desktopCleanup: DesktopReleaseResult;
20
+ }>;
@@ -0,0 +1,78 @@
1
+ import { runLab } from "./lab-engine.js";
2
+ import { runCuaActorSession } from "./computer-use-actor.js";
3
+ import { createRestrictedCodexParticipant } from "./restricted-codex-participant.js";
4
+ import { CuaProviderError } from "./cua-provider-error.js";
5
+ /** Internal, explicit single-participant consumer. Uses the existing producer and
6
+ * its automatic-completion boundary; never allocates or discovers a desktop. */
7
+ export async function runRestrictedParticipantStudy(options) {
8
+ let participant;
9
+ let providerCleanup = { status: "unconfirmed" };
10
+ let desktopCleanup = { status: "unconfirmed", reason: "release_unavailable" };
11
+ let cleanupUncertain = false;
12
+ let finalized = false;
13
+ let finalizing;
14
+ const finish = () => finalizing ??= (async () => {
15
+ try {
16
+ if (participant)
17
+ providerCleanup = await participant.close();
18
+ }
19
+ catch {
20
+ providerCleanup = { status: "unconfirmed" };
21
+ }
22
+ let timer;
23
+ try {
24
+ desktopCleanup = await Promise.race([Promise.resolve().then(() => options.desktop.close()), new Promise(resolve => {
25
+ timer = setTimeout(() => resolve({ status: "unconfirmed", reason: "release_unavailable" }), 10_000);
26
+ })]);
27
+ }
28
+ catch {
29
+ desktopCleanup = { status: "unconfirmed", reason: "release_failed" };
30
+ }
31
+ finally {
32
+ clearTimeout(timer);
33
+ }
34
+ cleanupUncertain ||= providerCleanup.status !== "confirmed" || desktopCleanup.status !== "released";
35
+ finalized = true;
36
+ })();
37
+ try {
38
+ const config = options.config;
39
+ if (config.subject.source !== "local-app" || config.actors.length !== 1 || config.actors[0]?.type !== "openai-computer-use" ||
40
+ (config.actors[0].model !== undefined && config.actors[0].model !== "gpt-6-astra") ||
41
+ (config.actors[0].reasoningEffort !== undefined && config.actors[0].reasoningEffort !== "low") ||
42
+ (config.actors[0]?.count ?? 1) !== 1 || (config.execution?.concurrency ?? 1) !== 1 ||
43
+ config.actors[0]?.lanes?.length ||
44
+ config.actors[0]?.maxOutputTokens !== undefined || config.execution?.caps?.maxUsd !== undefined ||
45
+ config.execution?.caps?.maxTotalUsd !== undefined || config.scenario?.caps?.maxUsd !== undefined || config.scenario?.caps?.maxTotalUsd !== undefined ||
46
+ !Number.isFinite(config.execution?.timeoutMs) || config.execution.timeoutMs < 1 || config.execution.timeoutMs > 600_000 ||
47
+ (config.review?.analysis !== false && (!config.review?.analysis || config.review.analysis.provider !== "codex"))) {
48
+ throw new CuaProviderError("request_rejected", { dispatched: false, usageComplete: false, cleanup: "confirmed" });
49
+ }
50
+ participant = createRestrictedCodexParticipant(options.participant);
51
+ const outcome = await runLab(config, { cwd: options.cwd, dryRun: false, open: false,
52
+ ...(options.runId === undefined ? {} : { runId: options.runId }),
53
+ automaticAnalysis: { ...options.automaticAnalysis, onStart: () => {
54
+ if (!finalized || cleanupUncertain || providerCleanup.status !== "confirmed" || desktopCleanup.status !== "released")
55
+ throw new Error("participant_cleanup_unconfirmed");
56
+ return options.automaticAnalysis?.onStart?.();
57
+ } },
58
+ cuaHooks: { env: {}, buildExecutor: async () => options.desktop.executor,
59
+ buildProvider: async () => participant.provider,
60
+ runSession: async (input) => {
61
+ try {
62
+ const result = await runCuaActorSession({ ...input, ...(options.signal === undefined ? {} : { signal: options.signal }) });
63
+ cleanupUncertain ||= result.trace.providerRequests?.some(r => r.cleanup !== "confirmed") === true;
64
+ return result;
65
+ }
66
+ finally {
67
+ await finish();
68
+ }
69
+ } }
70
+ });
71
+ await finish();
72
+ return { outcome, providerCleanup, desktopCleanup };
73
+ }
74
+ finally {
75
+ await finish();
76
+ }
77
+ }
78
+ //# sourceMappingURL=restricted-codex-participant-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restricted-codex-participant-run.js","sourceRoot":"","sources":["../src/restricted-codex-participant-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type CuaProvider } from "./computer-use.js";
2
+ import { type RestrictedCodexSessionOptions } from "./restricted-codex-session.js";
3
+ export type ParticipantProviderCloseResult = {
4
+ status: "confirmed" | "unconfirmed";
5
+ };
6
+ export interface RestrictedParticipantOptions {
7
+ session?: RestrictedCodexSessionOptions;
8
+ requestTimeoutMs?: number;
9
+ }
10
+ /** Fresh single turns over an already-owned executor. No desktop or login acquisition here. */
11
+ export declare function createRestrictedCodexParticipant(options?: RestrictedParticipantOptions): {
12
+ provider: CuaProvider;
13
+ close(): Promise<ParticipantProviderCloseResult>;
14
+ };
@@ -0,0 +1,178 @@
1
+ import { describeCuaAction } from "./computer-use.js";
2
+ import { CuaProviderError, isCuaProviderError } from "./cua-provider-error.js";
3
+ import { validateBrowserControlPng } from "./browser-control-protocol.js";
4
+ import { runRestrictedCodexSession } from "./restricted-codex-session.js";
5
+ import { PARTICIPANT_PROFILE, PARTICIPANT_LIMITS as L, PARTICIPANT_TURN_SCHEMA, PARTICIPANT_CLOSING_SCHEMA, parseParticipantTurn, parseParticipantClosing } from "./restricted-codex-participant-policy.js";
6
+ const codeOf = (code) => {
7
+ if (code === "cancelled" || code === "timeout" || code === "refusal")
8
+ return code === "refusal" ? "refused" : code;
9
+ if (code === "codex_cleanup_failed")
10
+ return "cleanup_unconfirmed";
11
+ if (code === "codex_busy")
12
+ return "busy";
13
+ if (code === "codex_protocol_error" || code === "codex_tool_call")
14
+ return "protocol_error";
15
+ if (code === "invalid_response" || code === "response_too_large" || code === "output_incomplete")
16
+ return "invalid_response";
17
+ if (code === "invalid_request")
18
+ return "request_rejected";
19
+ if (code === "codex_process_failed")
20
+ return "process_failed";
21
+ return "unavailable";
22
+ };
23
+ const noDispatch = () => ({ dispatched: false, usageComplete: false, cleanup: "confirmed" });
24
+ /** Fresh single turns over an already-owned executor. No desktop or login acquisition here. */
25
+ export function createRestrictedCodexParticipant(options = {}) {
26
+ const timeoutMs = options.requestTimeoutMs ?? L.requestMs;
27
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > L.requestMs)
28
+ throw new CuaProviderError("request_rejected", noDispatch());
29
+ let closed = false, failedCleanup = false, incompleteUsage = false, omitted = 0;
30
+ let instructions;
31
+ let history = [];
32
+ let controller;
33
+ let pending;
34
+ let closing;
35
+ let abortAt;
36
+ let cleanupTimer;
37
+ const revoke = () => {
38
+ closed = true;
39
+ abortAt ??= performance.now();
40
+ controller?.abort();
41
+ cleanupTimer ??= setTimeout(() => { if (pending)
42
+ failedCleanup = true; }, Math.max(0, L.cleanupMs - (performance.now() - abortAt)));
43
+ };
44
+ const trim = () => {
45
+ while (history.length > L.historyTurns || Buffer.byteLength(JSON.stringify(history)) > L.history) {
46
+ history.shift();
47
+ omitted++;
48
+ }
49
+ };
50
+ async function execute(req, signal, debrief, own) {
51
+ let receipt = noDispatch();
52
+ let usage;
53
+ const onAbort = () => { revoke(); own.abort(); };
54
+ signal.addEventListener("abort", onAbort, { once: true });
55
+ if (signal.aborted)
56
+ onAbort();
57
+ try {
58
+ if (own.signal.aborted || closed)
59
+ throw new CuaProviderError("cancelled", receipt);
60
+ if (typeof req.instructions !== "string" || Buffer.byteLength(req.instructions) > L.instructions ||
61
+ (req.contextHint !== undefined && (typeof req.contextHint !== "string" || Buffer.byteLength(req.contextHint) > L.hint)) ||
62
+ req.previousResponseId !== undefined || (req.acknowledgedSafetyChecks?.length ?? 0) > 0 ||
63
+ (instructions !== undefined && instructions !== req.instructions))
64
+ throw new CuaProviderError("request_rejected", receipt);
65
+ const frame = req.observation.screenshot;
66
+ try {
67
+ if (!Buffer.isBuffer(frame))
68
+ throw new Error();
69
+ validateBrowserControlPng(frame);
70
+ }
71
+ catch {
72
+ throw new CuaProviderError("request_rejected", receipt);
73
+ }
74
+ instructions ??= req.instructions;
75
+ const last = history.at(-1);
76
+ if (last && req.previousExecution !== undefined) {
77
+ if (req.previousExecution.actions.length !== last.actions.length || req.previousExecution.actions.some((a, i) => a.index !== i || !["completed", "skipped", "not_dispatched", "outcome_uncertain"].includes(a.status))) {
78
+ throw new CuaProviderError("request_rejected", receipt);
79
+ }
80
+ last.execution = { actions: req.previousExecution.actions.map(a => ({ ...a })) };
81
+ }
82
+ trim();
83
+ const result = await runRestrictedCodexSession({ model: PARTICIPANT_PROFILE.requestedModel,
84
+ instructions: `${instructions}\n\nYou are the study participant. Use only the current screenshot and explicit recent history. Describe your experience as public participant speech, never private reasoning. History contains proposals and input acknowledgments, not independent proof of success. A completed input does not prove its application outcome. Never use tools or request integrations. ${debrief ? "The interaction has ended. Give only a closing summary and frictionReports about what you observed; do not propose actions." : "Return the supplied JSON schema. Continue with one to four browser actions, or explicitly finish with no actions and your outcome. Preserve uncertainty and do not invent observations."}`,
85
+ evidence: JSON.stringify({ phase: debrief ? "closing" : "interaction", width: frame.readUInt32BE(16), height: frame.readUInt32BE(20),
86
+ contextHint: req.contextHint ?? null, memoryPolicy: PARTICIPANT_PROFILE.memoryPolicy, omittedTurns: omitted, history }),
87
+ images: [{ evidenceId: "current-frame", dataUrl: `data:image/png;base64,${frame.toString("base64")}` }],
88
+ schema: debrief ? PARTICIPANT_CLOSING_SCHEMA : PARTICIPANT_TURN_SCHEMA, maxOutputTokens: null, timeoutMs, signal: own.signal }, options.session);
89
+ receipt = { dispatched: result.dispatched, usageComplete: result.usageComplete,
90
+ cleanup: result.errorCode === "codex_cleanup_failed" ? "unconfirmed" : "confirmed" };
91
+ usage = result.usage ?? undefined;
92
+ if (receipt.cleanup === "unconfirmed") {
93
+ failedCleanup = true;
94
+ closed = true;
95
+ }
96
+ if (result.dispatched && !result.usageComplete && !debrief)
97
+ incompleteUsage = true;
98
+ if (closed || own.signal.aborted)
99
+ throw new CuaProviderError(receipt.cleanup === "unconfirmed" ? "cleanup_unconfirmed" : "cancelled", receipt, usage);
100
+ if (result.status !== "completed" || result.errorCode !== null)
101
+ throw new CuaProviderError(codeOf(result.errorCode), receipt, usage);
102
+ let turn;
103
+ try {
104
+ turn = debrief ? { actions: [], pendingSafetyChecks: [], done: true, closingReport: parseParticipantClosing(result.output) }
105
+ : parseParticipantTurn(result.output);
106
+ }
107
+ catch {
108
+ throw new CuaProviderError("invalid_response", receipt, usage);
109
+ }
110
+ if (!debrief) {
111
+ history.push({ narration: turn.message ?? "", actions: turn.actions.map(describeCuaAction) });
112
+ trim();
113
+ }
114
+ return { ...turn, ...(usage === undefined ? {} : { usage }), providerRequest: receipt };
115
+ }
116
+ catch (error) {
117
+ if (isCuaProviderError(error))
118
+ throw error;
119
+ failedCleanup = true;
120
+ closed = true;
121
+ incompleteUsage = true;
122
+ throw new CuaProviderError("process_failed", { dispatched: "unknown", usageComplete: false, cleanup: "unconfirmed" }, usage);
123
+ }
124
+ finally {
125
+ signal.removeEventListener("abort", onAbort);
126
+ }
127
+ }
128
+ const start = (req, signal, debrief) => {
129
+ if (closed)
130
+ return Promise.reject(new CuaProviderError("request_rejected", noDispatch()));
131
+ if (pending)
132
+ return Promise.reject(new CuaProviderError("busy", noDispatch()));
133
+ const own = new AbortController();
134
+ controller = own;
135
+ const task = execute(req, signal, debrief, own);
136
+ pending = task;
137
+ void task.finally(() => { if (pending === task) {
138
+ pending = undefined;
139
+ controller = undefined;
140
+ clearTimeout(cleanupTimer);
141
+ } }).catch(() => undefined);
142
+ return task;
143
+ };
144
+ const provider = {
145
+ id: "restricted-codex-participant", version: PARTICIPANT_PROFILE.requestedModel, requiresFrame: true, requestPolicy: "fail_closed",
146
+ executionProfile: PARTICIPANT_PROFILE, modelSettings: { reasoningEffort: "low" },
147
+ capabilities: { headless: true, structuredTrace: true, lanes: ["computer-use"], producesScreenshots: true, byoModel: false,
148
+ preGrantableApprovals: false, inProcessTools: false, license: "proprietary" },
149
+ get interactionUsageIncomplete() { return incompleteUsage; }, get historyTurnsOmitted() { return omitted; },
150
+ nextTurn: (req, signal) => start(req, signal, false), debrief: (req, signal) => start(req, signal, true)
151
+ };
152
+ return { provider, close: () => {
153
+ if (closing)
154
+ return closing;
155
+ revoke();
156
+ history = [];
157
+ instructions = undefined;
158
+ closing = (async () => {
159
+ let timer;
160
+ try {
161
+ const settled = !pending || await Promise.race([pending.then(() => true, () => true), new Promise(resolve => {
162
+ timer = setTimeout(() => resolve(false), Math.max(0, L.cleanupMs - (performance.now() - abortAt)));
163
+ })]);
164
+ if (!settled)
165
+ failedCleanup = true;
166
+ return { status: failedCleanup ? "unconfirmed" : "confirmed" };
167
+ }
168
+ finally {
169
+ clearTimeout(timer);
170
+ clearTimeout(cleanupTimer);
171
+ history = [];
172
+ instructions = undefined;
173
+ }
174
+ })();
175
+ return closing;
176
+ } };
177
+ }
178
+ //# sourceMappingURL=restricted-codex-participant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restricted-codex-participant.js","sourceRoot":"","sources":["../src/restricted-codex-participant.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,8 @@ export interface RestrictedCodexSessionOptions {
10
10
  arch?: string;
11
11
  spawnFn?: RestrictedCodexSpawn;
12
12
  }
13
- /** The gate covers all factories and readiness checks in this process. It does not
14
- * promise to serialize unrelated Codex applications using the same host login. */
13
+ /** Each call owns a separate process, home and thread. An unresolved child blocks
14
+ * new work, but ordinary participant turns may run concurrently. */
15
15
  export declare function runRestrictedCodexSession(request: RestrictedCodexRequest, options?: RestrictedCodexSessionOptions, readinessOnly?: boolean): Promise<RestrictedCodexResult>;
16
16
  export declare function checkRestrictedCodexSessionReadiness(input?: {
17
17
  signal?: AbortSignal;
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
2
2
  import { constants } from "node:fs";
3
3
  import { access, chmod, lstat, mkdir, mkdtemp, open, readdir, realpath, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
4
4
  import { homedir, tmpdir } from "node:os";
5
+ import { createRequire } from "node:module";
5
6
  import path from "node:path";
6
7
  import { CODEX_IMAGE, CODEX_MAX_OUTPUT_BYTES, RESTRICTED_CODEX_ANALYSIS_IDENTITY, RESTRICTED_CODEX_ANALYSIS_MODELS, admitsRestrictedCodexConfig, admitsRestrictedCodexThread, codexRecord, restrictedCodexConfig, restrictedCodexFailure, restrictedCodexRequestError, restrictedCodexUsage } from "./restricted-codex-policy.js";
7
8
  import { RestrictedCodexDeadline, RestrictedCodexStop, RestrictedCodexTransport, closeOwnedCodexProcess, ownCodexProcess } from "./restricted-codex-transport.js";
@@ -12,14 +13,16 @@ function childEnvironment(source, home, scratch) {
12
13
  result[key] = source[key];
13
14
  return result;
14
15
  }
15
- async function isNativeExecutable(file) {
16
+ async function isNativeExecutable(file, platform) {
16
17
  try {
17
18
  await access(file, constants.X_OK);
18
19
  const handle = await open(file, "r");
19
20
  try {
20
21
  const buffer = Buffer.alloc(4);
21
22
  const read = await handle.read(buffer, 0, 4, 0);
22
- return read.bytesRead === 4 && buffer.equals(Buffer.from([0x7f, 0x45, 0x4c, 0x46]));
23
+ return read.bytesRead === 4 && (platform === "darwin"
24
+ ? ["cffaedfe", "feedfacf", "cafebabe", "bebafeca", "cafebabf"].includes(buffer.toString("hex"))
25
+ : buffer.equals(Buffer.from([0x7f, 0x45, 0x4c, 0x46])));
23
26
  }
24
27
  finally {
25
28
  await handle.close();
@@ -32,6 +35,7 @@ async function isNativeExecutable(file) {
32
35
  /** Resolve PATH without running a shell. The npm launcher is resolved to its
33
36
  * native optional package so cleanup owns the real app-server child. */
34
37
  async function resolveExecutable(options, env) {
38
+ const platform = options.platform ?? process.platform;
35
39
  let selected = options.executable;
36
40
  if (selected === undefined) {
37
41
  for (const directory of (env.PATH ?? "").split(path.delimiter).filter(entry => path.isAbsolute(entry))) {
@@ -53,14 +57,23 @@ async function resolveExecutable(options, env) {
53
57
  catch {
54
58
  throw new RestrictedCodexStop("codex_unavailable");
55
59
  }
56
- if (await isNativeExecutable(resolved))
60
+ if (await isNativeExecutable(resolved, platform))
57
61
  return resolved;
58
62
  if (path.basename(resolved) === "codex.js" && path.basename(path.dirname(resolved)) === "bin") {
59
63
  const packageRoot = path.dirname(path.dirname(resolved));
60
- const triple = "x86_64-unknown-linux-musl";
61
- for (const candidate of [path.join(packageRoot, "node_modules", "@openai", "codex-linux-x64", "vendor", triple, "bin", "codex"),
62
- path.join(packageRoot, "vendor", triple, "bin", "codex")]) {
63
- if (await isNativeExecutable(candidate))
64
+ const triple = platform === "darwin" ? "aarch64-apple-darwin" : "x86_64-unknown-linux-musl";
65
+ const nativePackage = platform === "darwin" ? "codex-darwin-arm64" : "codex-linux-x64";
66
+ const candidates = [];
67
+ try {
68
+ // Match the npm launcher's resolution: optional packages may be hoisted or
69
+ // linked by the package manager rather than nested inside @openai/codex.
70
+ const manifest = createRequire(resolved).resolve(`@openai/${nativePackage}/package.json`);
71
+ candidates.push(path.join(path.dirname(manifest), "vendor", triple, "bin", "codex"));
72
+ }
73
+ catch { /* Older packages may bundle the native executable directly. */ }
74
+ candidates.push(path.join(packageRoot, "vendor", triple, "bin", "codex"));
75
+ for (const candidate of candidates) {
76
+ if (await isNativeExecutable(candidate, platform))
64
77
  return realpath(candidate);
65
78
  }
66
79
  }
@@ -98,27 +111,20 @@ async function checkVersion(file, env, cwd, spawnFn, deadline) {
98
111
  }
99
112
  }
100
113
  }
101
- let activeSession = false;
102
- let unclosedChild = false;
114
+ const unclosedChildren = new Set();
103
115
  function retainUnclosedChild(closed) {
104
- unclosedChild = true;
105
- void closed.then(() => { unclosedChild = false; });
116
+ unclosedChildren.add(closed);
117
+ void closed.then(() => { unclosedChildren.delete(closed); });
106
118
  }
107
- /** The gate covers all factories and readiness checks in this process. It does not
108
- * promise to serialize unrelated Codex applications using the same host login. */
119
+ /** Each call owns a separate process, home and thread. An unresolved child blocks
120
+ * new work, but ordinary participant turns may run concurrently. */
109
121
  export async function runRestrictedCodexSession(request, options = {}, readinessOnly = false) {
110
122
  const error = restrictedCodexRequestError(request);
111
123
  if (error)
112
124
  return restrictedCodexFailure(error);
113
- if (activeSession || unclosedChild)
125
+ if (unclosedChildren.size)
114
126
  return restrictedCodexFailure("codex_busy");
115
- activeSession = true;
116
- try {
117
- return await executeRestrictedCodexSession(request, options, readinessOnly);
118
- }
119
- finally {
120
- activeSession = false;
121
- }
127
+ return executeRestrictedCodexSession(request, options, readinessOnly);
122
128
  }
123
129
  async function writeRecoveryMarker(work, sourceEnv, reason) {
124
130
  const cache = sourceEnv.XDG_CACHE_HOME ?? path.join(sourceEnv.HOME ?? homedir(), ".cache");
@@ -162,7 +168,8 @@ async function executeRestrictedCodexSession(request, options = {}, readinessOnl
162
168
  const admissionError = restrictedCodexRequestError(request);
163
169
  if (admissionError)
164
170
  return restrictedCodexFailure(admissionError);
165
- if ((options.platform ?? process.platform) !== "linux" || (options.arch ?? process.arch) !== "x64")
171
+ const platform = options.platform ?? process.platform, arch = options.arch ?? process.arch;
172
+ if (!(platform === "linux" && arch === "x64") && !(platform === "darwin" && arch === "arm64"))
166
173
  return restrictedCodexFailure("codex_unsupported_platform");
167
174
  const deadline = new RestrictedCodexDeadline(request.timeoutMs, request.signal);
168
175
  const sourceEnv = options.env ?? process.env;
@@ -318,7 +325,7 @@ async function executeRestrictedCodexSession(request, options = {}, readinessOnl
318
325
  clientInfo: { name: "humanish_analysis", version: "1.0.0" }, capabilities: { experimentalApi: true }
319
326
  });
320
327
  if (typeof initialize.userAgent !== "string" || !initialize.userAgent.includes(`/0.154.0 `)
321
- || initialize.codexHome !== home || initialize.platformOs !== "linux" || initialize.platformFamily !== "unix")
328
+ || initialize.codexHome !== home || initialize.platformOs !== (platform === "darwin" ? "macos" : "linux") || initialize.platformFamily !== "unix")
322
329
  throw new RestrictedCodexStop("codex_unsupported_version");
323
330
  transport.notify("initialized", {});
324
331
  const effective = await transport.rpc("config/read", { includeLayers: true, cwd });
@@ -368,12 +375,13 @@ async function executeRestrictedCodexSession(request, options = {}, readinessOnl
368
375
  }
369
376
  }
370
377
  catch (error) {
371
- result = restrictedCodexFailure(deadline.code ?? (error instanceof RestrictedCodexStop ? error.code : "codex_process_failed"), dispatched, usage);
378
+ const code = error instanceof RestrictedCodexStop ? error.code : "codex_process_failed";
379
+ result = restrictedCodexFailure(code === "codex_cleanup_failed" ? code : deadline.code ?? code, dispatched, usage);
372
380
  }
373
381
  finally {
374
382
  // Deadline remains authoritative until acceptance; teardown has its own small grace.
375
383
  deadline.close();
376
- let cleaned = !unclosedChild;
384
+ let cleaned = result.errorCode !== "codex_cleanup_failed";
377
385
  if (transport) {
378
386
  const cleanupTurn = turnId ?? earlyTurnId;
379
387
  cleaned = await transport.close(dispatched && !completed && threadId && cleanupTurn
@@ -404,7 +412,7 @@ async function executeRestrictedCodexSession(request, options = {}, readinessOnl
404
412
  }
405
413
  if (work && cleaned && !authReplaced)
406
414
  await rm(work, { recursive: true, force: true }).catch(() => { cleaned = false; });
407
- if (work && unclosedChild)
415
+ if (work && !cleaned && !authReplaced)
408
416
  await writeRecoveryMarker(work, sourceEnv, "process_cleanup_unconfirmed").catch(() => undefined);
409
417
  if (!cleaned)
410
418
  result = restrictedCodexFailure("codex_cleanup_failed", dispatched, usage);