@12ui/design 0.2.74 → 0.2.75
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/SKILL.md +1 -1
- package/dist/cli-codex-readiness.d.ts +19 -6
- package/dist/cli-codex-readiness.d.ts.map +1 -1
- package/dist/cli-codex-readiness.js +36 -16
- package/dist/cli-codex-readiness.js.map +1 -1
- package/dist/cli-help/design.d.ts +9 -2
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +17 -2
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +9 -2
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +6 -0
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +1 -0
- package/dist/cli-usage.js.map +1 -1
- package/dist/cli-workspace-command.js +1 -1
- package/dist/cli-workspace-command.js.map +1 -1
- package/dist/cli-workspace-draw.d.ts +23 -0
- package/dist/cli-workspace-draw.d.ts.map +1 -0
- package/dist/cli-workspace-draw.js +97 -0
- package/dist/cli-workspace-draw.js.map +1 -0
- package/dist/codex-binary.d.ts +20 -0
- package/dist/codex-binary.d.ts.map +1 -0
- package/dist/codex-binary.js +46 -0
- package/dist/codex-binary.js.map +1 -0
- package/dist/slate-image-executor.js +1 -1
- package/dist/slate-image-executor.js.map +1 -1
- package/dist/slate-local-image.d.ts +3 -6
- package/dist/slate-local-image.d.ts.map +1 -1
- package/dist/slate-local-image.js +2 -18
- package/dist/slate-local-image.js.map +1 -1
- package/dist/workspace-draw-client.d.ts +69 -0
- package/dist/workspace-draw-client.d.ts.map +1 -0
- package/dist/workspace-draw-client.js +193 -0
- package/dist/workspace-draw-client.js.map +1 -0
- package/dist/workspace-draw-codex.d.ts +49 -0
- package/dist/workspace-draw-codex.d.ts.map +1 -0
- package/dist/workspace-draw-codex.js +89 -0
- package/dist/workspace-draw-codex.js.map +1 -0
- package/dist/workspace-draw-engine.d.ts +39 -0
- package/dist/workspace-draw-engine.d.ts.map +1 -0
- package/dist/workspace-draw-engine.js +72 -0
- package/dist/workspace-draw-engine.js.map +1 -0
- package/dist/workspace-draw-messages.d.ts +45 -0
- package/dist/workspace-draw-messages.d.ts.map +1 -0
- package/dist/workspace-draw-messages.js +48 -0
- package/dist/workspace-draw-messages.js.map +1 -0
- package/dist/workspace-draw-run.d.ts +43 -0
- package/dist/workspace-draw-run.d.ts.map +1 -0
- package/dist/workspace-draw-run.js +328 -0
- package/dist/workspace-draw-run.js.map +1 -0
- package/dist/workspace-draw-store.d.ts +23 -0
- package/dist/workspace-draw-store.d.ts.map +1 -0
- package/dist/workspace-draw-store.js +65 -0
- package/dist/workspace-draw-store.js.map +1 -0
- package/dist/workspace-draw-types.d.ts +121 -0
- package/dist/workspace-draw-types.d.ts.map +1 -0
- package/dist/workspace-draw-types.js +21 -0
- package/dist/workspace-draw-types.js.map +1 -0
- package/open-design.json +2 -2
- package/package.json +1 -1
- package/runtime/codex-conversion/src/codex/home.mjs +43 -14
- package/runtime/codex-conversion/src/images/native-files.mjs +20 -0
- package/runtime/codex-conversion/src/images/native-invoke.mjs +5 -2
- package/runtime/codex-conversion/src/images/native-records.mjs +75 -3
- package/runtime/codex-conversion/src/images/native.mjs +7 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-binary.d.ts","sourceRoot":"","sources":["../src/codex-binary.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,6FAA6F,CAAC;AAEnI,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,MAAM,GAAG,aAAa,CAAC;AAClG,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAWxE,eAAO,MAAM,iBAAiB,GAC5B,MAAK,MAAM,CAAC,UAAwB,EACpC,aAAY,CAAC,IAAI,EAAE,MAAM,KAAK,OAAsB,KACnD,WAAW,GAAG,IAWhB,CAAC;AAEF,eAAO,MAAM,sBAAsB,4IAA4I,CAAC;AAEhL,uGAAuG;AACvG,eAAO,MAAM,kBAAkB,GAC7B,MAAK,MAAM,CAAC,UAAwB,EACpC,aAAY,CAAC,IAAI,EAAE,MAAM,KAAK,OAAsB,KACnD,MAIF,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { accessSync, constants } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Which `codex` executable 12ui runs, in one place: the design workspace's local runner, the readiness probe and
|
|
5
|
+
* the engine selector of `12ui workspace draw` all resolve it here.
|
|
6
|
+
*
|
|
7
|
+
* Order: `TWELVE_UI_CODEX_BIN` (taken as given, so an explicit choice is never second-guessed), then
|
|
8
|
+
* `CODEX_CLI_PATH` (the desktop app sets it in its shells), then `codex` on `PATH`, then the CLI the ChatGPT
|
|
9
|
+
* desktop app ships inside its bundle. Nothing else: a machine with none of these has no Codex.
|
|
10
|
+
*/
|
|
11
|
+
/** The Codex CLI inside the ChatGPT desktop app's bundle; the last place looked. */
|
|
12
|
+
export const CHATGPT_APP_CODEX_BINARY = '/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex';
|
|
13
|
+
const isExecutable = (file) => {
|
|
14
|
+
try {
|
|
15
|
+
accessSync(file, constants.X_OK);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const locateCodexBinary = (env = process.env, executable = isExecutable) => {
|
|
23
|
+
const explicit = env.TWELVE_UI_CODEX_BIN?.trim();
|
|
24
|
+
if (explicit)
|
|
25
|
+
return { binary: explicit, source: 'TWELVE_UI_CODEX_BIN' };
|
|
26
|
+
const desktop = env.CODEX_CLI_PATH?.trim();
|
|
27
|
+
if (desktop && executable(desktop))
|
|
28
|
+
return { binary: desktop, source: 'CODEX_CLI_PATH' };
|
|
29
|
+
for (const directory of (env.PATH ?? '').split(path.delimiter)) {
|
|
30
|
+
if (directory === '')
|
|
31
|
+
continue;
|
|
32
|
+
const candidate = path.join(directory, 'codex');
|
|
33
|
+
if (executable(candidate))
|
|
34
|
+
return { binary: candidate, source: 'PATH' };
|
|
35
|
+
}
|
|
36
|
+
return executable(CHATGPT_APP_CODEX_BINARY) ? { binary: CHATGPT_APP_CODEX_BINARY, source: 'ChatGPT.app' } : null;
|
|
37
|
+
};
|
|
38
|
+
export const NO_CODEX_BINARY_REASON = 'No Codex CLI was found: TWELVE_UI_CODEX_BIN and CODEX_CLI_PATH are not set, codex is not on PATH, and the ChatGPT app is not installed.';
|
|
39
|
+
/** The executable to run; throws when this machine has none, so nothing ever spawns a guessed name. */
|
|
40
|
+
export const resolveCodexBinary = (env = process.env, executable = isExecutable) => {
|
|
41
|
+
const located = locateCodexBinary(env, executable);
|
|
42
|
+
if (!located)
|
|
43
|
+
throw Object.assign(new Error(NO_CODEX_BINARY_REASON), { code: 'CODEX_BINARY_MISSING' });
|
|
44
|
+
return located.binary;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=codex-binary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-binary.js","sourceRoot":"","sources":["../src/codex-binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;GAOG;AAEH,oFAAoF;AACpF,MAAM,CAAC,MAAM,wBAAwB,GAAG,0FAA0F,CAAC;AAKnI,MAAM,YAAY,GAAG,CAAC,IAAY,EAAW,EAAE;IAC7C,IAAI,CAAC;QACH,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAAyB,OAAO,CAAC,GAAG,EACpC,aAAwC,YAAY,EAChC,EAAE;IACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACzE,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IACzF,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/D,IAAI,SAAS,KAAK,EAAE;YAAE,SAAS;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,yIAAyI,CAAC;AAEhL,uGAAuG;AACvG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAyB,OAAO,CAAC,GAAG,EACpC,aAAwC,YAAY,EAC5C,EAAE;IACV,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC;IACvG,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
-
import { resolveCodexBinary } from './
|
|
4
|
+
import { resolveCodexBinary } from './codex-binary.js';
|
|
5
5
|
/** One image call may run this long before it is stopped. */
|
|
6
6
|
export const IMAGE_CALL_TIMEOUT_MS = 15 * 60_000;
|
|
7
7
|
const importRuntime = async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slate-image-executor.js","sourceRoot":"","sources":["../src/slate-image-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"slate-image-executor.js","sourceRoot":"","sources":["../src/slate-image-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,17 +2,14 @@ import type { LocalImageState } from './slate-view.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Whether Design and Edit can run on this Mac: the local Codex CLI, signed in
|
|
4
4
|
* with ChatGPT, with the image model available. It reads only the readiness
|
|
5
|
-
* probe (`codex --version`, `codex login status`, `codex exec --help
|
|
6
|
-
* model cache), which runs no inference, and is asked at most once a minute
|
|
5
|
+
* probe (`codex --version`, `codex login status`, `codex exec --help`, the
|
|
6
|
+
* model cache and `codex features list`), which runs no inference, and is asked at most once a minute
|
|
7
7
|
* per server. The workspace never buys an alternative: when this says not
|
|
8
8
|
* ready, the dialogs show the reason and stay disabled.
|
|
9
9
|
*/
|
|
10
10
|
export type SlateImageProbe = () => Promise<LocalImageState>;
|
|
11
11
|
export declare const LOCAL_IMAGE_PROBE_TTL_MS = 60000;
|
|
12
|
-
/** The
|
|
13
|
-
export declare const CODEX_APP_BINARY = "/Applications/Codex.app/Contents/Resources/codex";
|
|
14
|
-
/** `TWELVE_UI_CODEX_BIN`, then `codex` on `PATH`, then the Codex app bundle if it is installed. */
|
|
15
|
-
export declare const resolveCodexBinary: (env?: NodeJS.ProcessEnv, exists?: (file: string) => boolean) => string;
|
|
12
|
+
/** The shared probe, with the binary resolved from `env` (`codex-binary.ts`) and `env.CODEX_HOME` as the home. */
|
|
16
13
|
export declare const codexReadinessProbe: (env?: NodeJS.ProcessEnv) => SlateImageProbe;
|
|
17
14
|
/** The probe's answer, kept for a minute. A not-ready reason is passed through verbatim. */
|
|
18
15
|
export declare const cachedImageProbe: (probe: SlateImageProbe, now: () => Date) => SlateImageProbe;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slate-local-image.d.ts","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slate-local-image.d.ts","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;GAOG;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;AAE7D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,kHAAkH;AAClH,eAAO,MAAM,mBAAmB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,eAG1E,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,EAAE,KAAK,MAAM,IAAI,KAAG,eAS1E,CAAC"}
|
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
1
|
import { probeCodexReadiness } from './cli-codex-readiness.js';
|
|
4
2
|
export const LOCAL_IMAGE_PROBE_TTL_MS = 60_000;
|
|
5
|
-
/** The
|
|
6
|
-
export const CODEX_APP_BINARY = '/Applications/Codex.app/Contents/Resources/codex';
|
|
7
|
-
/** `TWELVE_UI_CODEX_BIN`, then `codex` on `PATH`, then the Codex app bundle if it is installed. */
|
|
8
|
-
export const resolveCodexBinary = (env = process.env, exists = existsSync) => {
|
|
9
|
-
const explicit = env.TWELVE_UI_CODEX_BIN?.trim();
|
|
10
|
-
if (explicit)
|
|
11
|
-
return explicit;
|
|
12
|
-
const onPath = (env.PATH ?? '').split(path.delimiter).some((directory) => directory !== '' && exists(path.join(directory, 'codex')));
|
|
13
|
-
if (onPath)
|
|
14
|
-
return 'codex';
|
|
15
|
-
return exists(CODEX_APP_BINARY) ? CODEX_APP_BINARY : 'codex';
|
|
16
|
-
};
|
|
3
|
+
/** The shared probe, with the binary resolved from `env` (`codex-binary.ts`) and `env.CODEX_HOME` as the home. */
|
|
17
4
|
export const codexReadinessProbe = (env = process.env) => async () => {
|
|
18
|
-
const result = await probeCodexReadiness({
|
|
19
|
-
codexBin: resolveCodexBinary(env),
|
|
20
|
-
...(env.CODEX_HOME?.trim() ? { codexHome: env.CODEX_HOME.trim() } : {}),
|
|
21
|
-
});
|
|
5
|
+
const result = await probeCodexReadiness({ env });
|
|
22
6
|
return { ready: result.ready, reason: result.ready ? null : result.reason };
|
|
23
7
|
};
|
|
24
8
|
/** The probe's answer, kept for a minute. A not-ready reason is passed through verbatim. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slate-local-image.js","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"slate-local-image.js","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAc/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAE/C,kHAAkH;AAClH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAyB,OAAO,CAAC,GAAG,EAAmB,EAAE,CAAC,KAAK,IAAI,EAAE;IACvG,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAClD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;AAC9E,CAAC,CAAC;AAEF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAE,GAAe,EAAmB,EAAE;IAC3F,IAAI,MAA0D,CAAC;IAC/D,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,MAAM,IAAI,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,wBAAwB,IAAI,EAAE,IAAI,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAChG,MAAM,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;QAC5B,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type PlanImageName, type SlateDrawPlan } from './workspace-draw-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The CLI's side of interface I1: the three `/api/v1/slate/` routes `12ui workspace draw` calls on
|
|
4
|
+
* design.12ui.com, authenticated by the push token alone. Every route is idempotent, so a `429` (and a retryable
|
|
5
|
+
* `503`) is retried after the seconds the server gives, up to three times per request.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PUSH_HEADER = "X-12ui-Push";
|
|
8
|
+
export declare const CLI_HEADER = "X-12ui-Cli";
|
|
9
|
+
export declare const MAX_RETRIES = 3;
|
|
10
|
+
/** How long a plan may stay `plan_pending` (its direction call in flight) before the run gives up on it. */
|
|
11
|
+
export declare const PLAN_PENDING_LIMIT_MS = 180000;
|
|
12
|
+
/** The server answered with an error (`{ok:false,error:{code,...}}`, or the flat `{error:"code"}` form). */
|
|
13
|
+
export declare class DrawHttpError extends Error {
|
|
14
|
+
readonly status: number;
|
|
15
|
+
readonly code: string;
|
|
16
|
+
readonly retryAfterSeconds: number | null;
|
|
17
|
+
readonly body: unknown;
|
|
18
|
+
constructor(status: number, code: string, retryAfterSeconds: number | null, body: unknown);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The server could not be reached (`unreachable`), bytes arrived other than declared (`corrupt`), or its answer was
|
|
22
|
+
* not what I1 says (`malformed`: a server this CLI is too old to read).
|
|
23
|
+
*/
|
|
24
|
+
export declare class DrawTransportError extends Error {
|
|
25
|
+
readonly kind: 'unreachable' | 'corrupt' | 'malformed';
|
|
26
|
+
constructor(kind: 'unreachable' | 'corrupt' | 'malformed', message: string, options?: {
|
|
27
|
+
cause?: unknown;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export type DrawFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
31
|
+
export type PlanImage = {
|
|
32
|
+
bytes: Buffer;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
sha256: string;
|
|
35
|
+
referenceId: string | null;
|
|
36
|
+
};
|
|
37
|
+
export type PushOutcome = {
|
|
38
|
+
state: 'filled' | 'failed';
|
|
39
|
+
label: string | null;
|
|
40
|
+
versionId: string | null;
|
|
41
|
+
replayed: boolean;
|
|
42
|
+
opState: string | null;
|
|
43
|
+
};
|
|
44
|
+
/** The error code in either error shape the server uses. */
|
|
45
|
+
export declare const errorCodeOf: (body: unknown) => string | null;
|
|
46
|
+
/** Check the plan against I1 before anything is drawn from it; a plan this CLI cannot read is never guessed at. */
|
|
47
|
+
export declare const validatePlan: (value: unknown, opId: string) => SlateDrawPlan;
|
|
48
|
+
export declare const createDrawClient: (args: {
|
|
49
|
+
origin: string;
|
|
50
|
+
token: string;
|
|
51
|
+
opId: string;
|
|
52
|
+
cliVersion: string;
|
|
53
|
+
fetch?: DrawFetch;
|
|
54
|
+
sleep?: (milliseconds: number) => Promise<void>;
|
|
55
|
+
now?: () => number;
|
|
56
|
+
}) => {
|
|
57
|
+
/** The frozen plan (2.1), waiting out `plan_pending` while the round's direction call finishes. */
|
|
58
|
+
plan: () => Promise<SlateDrawPlan>;
|
|
59
|
+
/** The exact bytes every engine attaches (2.2), checked against the server's sha256. */
|
|
60
|
+
image: (name: PlanImageName) => Promise<PlanImage>;
|
|
61
|
+
/** One option's image or failure reason (2.3). */
|
|
62
|
+
push: (key: string, part: {
|
|
63
|
+
png: Buffer;
|
|
64
|
+
} | {
|
|
65
|
+
reason: string;
|
|
66
|
+
}) => Promise<PushOutcome>;
|
|
67
|
+
};
|
|
68
|
+
export type DrawClient = ReturnType<typeof createDrawClient>;
|
|
69
|
+
//# sourceMappingURL=workspace-draw-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-client.d.ts","sourceRoot":"","sources":["../src/workspace-draw-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAEhG;;;;GAIG;AAEH,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,4GAA4G;AAC5G,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAE7C,4GAA4G;AAC5G,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBACX,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO;CAO1F;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC;gBAC3C,IAAI,EAAE,aAAa,GAAG,SAAS,GAAG,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI1G;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE9E,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAExG,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAOF,4DAA4D;AAC5D,eAAO,MAAM,WAAW,GAAI,MAAM,OAAO,KAAG,MAAM,GAAG,IAKpD,CAAC;AAkBF,mHAAmH;AACnH,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,EAAE,MAAM,MAAM,KAAG,aA0B3D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;IAmCG,mGAAmG;gBACnF,OAAO,CAAC,aAAa,CAAC;IAYtC,wFAAwF;kBACpE,aAAa,KAAG,OAAO,CAAC,SAAS,CAAC;IActD,kDAAkD;gBAChC,MAAM,QAAQ;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,WAAW,CAAC;CAgB9F,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { PLAN_SCHEMA } from './workspace-draw-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The CLI's side of interface I1: the three `/api/v1/slate/` routes `12ui workspace draw` calls on
|
|
5
|
+
* design.12ui.com, authenticated by the push token alone. Every route is idempotent, so a `429` (and a retryable
|
|
6
|
+
* `503`) is retried after the seconds the server gives, up to three times per request.
|
|
7
|
+
*/
|
|
8
|
+
export const PUSH_HEADER = 'X-12ui-Push';
|
|
9
|
+
export const CLI_HEADER = 'X-12ui-Cli';
|
|
10
|
+
export const MAX_RETRIES = 3;
|
|
11
|
+
/** How long a plan may stay `plan_pending` (its direction call in flight) before the run gives up on it. */
|
|
12
|
+
export const PLAN_PENDING_LIMIT_MS = 180_000;
|
|
13
|
+
/** The server answered with an error (`{ok:false,error:{code,...}}`, or the flat `{error:"code"}` form). */
|
|
14
|
+
export class DrawHttpError extends Error {
|
|
15
|
+
status;
|
|
16
|
+
code;
|
|
17
|
+
retryAfterSeconds;
|
|
18
|
+
body;
|
|
19
|
+
constructor(status, code, retryAfterSeconds, body) {
|
|
20
|
+
super(`design.12ui.com answered ${status} ${code}`);
|
|
21
|
+
this.status = status;
|
|
22
|
+
this.code = code;
|
|
23
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
24
|
+
this.body = body;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The server could not be reached (`unreachable`), bytes arrived other than declared (`corrupt`), or its answer was
|
|
29
|
+
* not what I1 says (`malformed`: a server this CLI is too old to read).
|
|
30
|
+
*/
|
|
31
|
+
export class DrawTransportError extends Error {
|
|
32
|
+
kind;
|
|
33
|
+
constructor(kind, message, options) {
|
|
34
|
+
super(message, options);
|
|
35
|
+
this.kind = kind;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const sha256 = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
39
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
40
|
+
const stringOrNull = (value) => (typeof value === 'string' ? value : null);
|
|
41
|
+
/** The error code in either error shape the server uses. */
|
|
42
|
+
export const errorCodeOf = (body) => {
|
|
43
|
+
if (!isRecord(body))
|
|
44
|
+
return null;
|
|
45
|
+
if (typeof body.error === 'string')
|
|
46
|
+
return body.error;
|
|
47
|
+
if (isRecord(body.error) && typeof body.error.code === 'string')
|
|
48
|
+
return body.error.code;
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
const retryAfterOf = (response, body) => {
|
|
52
|
+
const fromBody = isRecord(body) ? (body.retryAfterSeconds ?? (isRecord(body.error) ? body.error.retryAfterSeconds : undefined)) : undefined;
|
|
53
|
+
if (typeof fromBody === 'number' && Number.isFinite(fromBody) && fromBody >= 0)
|
|
54
|
+
return fromBody;
|
|
55
|
+
const header = Number(response.headers.get('retry-after'));
|
|
56
|
+
return Number.isFinite(header) && header >= 0 && response.headers.get('retry-after') !== null ? header : null;
|
|
57
|
+
};
|
|
58
|
+
const readBody = async (response) => {
|
|
59
|
+
const text = await response.text();
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(text);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return text;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
/** Check the plan against I1 before anything is drawn from it; a plan this CLI cannot read is never guessed at. */
|
|
68
|
+
export const validatePlan = (value, opId) => {
|
|
69
|
+
const fail = (what) => { throw new DrawTransportError('malformed', `The plan for ${opId} is not one this command can read: ${what}.`); };
|
|
70
|
+
if (!isRecord(value))
|
|
71
|
+
return fail('not an object');
|
|
72
|
+
if (value.schema !== PLAN_SCHEMA)
|
|
73
|
+
return fail(`schema ${JSON.stringify(value.schema)}`);
|
|
74
|
+
if (value.opId !== opId)
|
|
75
|
+
return fail('it names another request');
|
|
76
|
+
if (!Array.isArray(value.options))
|
|
77
|
+
return fail('no options');
|
|
78
|
+
for (const field of ['workspace', 'kind', 'mode', 'promptRevision', 'planDigest', 'state']) {
|
|
79
|
+
if (typeof value[field] !== 'string')
|
|
80
|
+
fail(`no ${field}`);
|
|
81
|
+
}
|
|
82
|
+
const keys = new Set();
|
|
83
|
+
for (const option of value.options) {
|
|
84
|
+
if (!isRecord(option))
|
|
85
|
+
return fail('an option is not an object');
|
|
86
|
+
const key = option.key;
|
|
87
|
+
if (typeof key !== 'string' || key === '' || keys.has(key))
|
|
88
|
+
return fail('an option key is missing or repeated');
|
|
89
|
+
keys.add(key);
|
|
90
|
+
if (typeof option.callId !== 'string' || typeof option.prompt !== 'string' || typeof option.promptSha256 !== 'string')
|
|
91
|
+
fail(`option ${key} has no call id or prompt`);
|
|
92
|
+
if (sha256(option.prompt) !== option.promptSha256)
|
|
93
|
+
fail(`option ${key}'s prompt does not match its sha256`);
|
|
94
|
+
if (!['pending', 'filled', 'failed'].includes(option.state))
|
|
95
|
+
fail(`option ${key} has state ${JSON.stringify(option.state)}`);
|
|
96
|
+
const frame = option.frame;
|
|
97
|
+
if (!isRecord(frame) || !Number.isSafeInteger(frame.width) || !Number.isSafeInteger(frame.height) || frame.width < 1 || frame.height < 1)
|
|
98
|
+
fail(`option ${key} has no frame`);
|
|
99
|
+
if (!Array.isArray(option.images))
|
|
100
|
+
return fail(`option ${key} has no image list`);
|
|
101
|
+
for (const image of option.images) {
|
|
102
|
+
if (!isRecord(image) || typeof image.name !== 'string' || !/^(parent|annotated|ref-[1-9]\d*)$/u.test(image.name))
|
|
103
|
+
fail(`option ${key} names an unknown image`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return value;
|
|
107
|
+
};
|
|
108
|
+
export const createDrawClient = (args) => {
|
|
109
|
+
const fetcher = args.fetch ?? ((url, init) => fetch(url, init));
|
|
110
|
+
const sleep = args.sleep ?? ((milliseconds) => new Promise((resolve) => { setTimeout(resolve, milliseconds); }));
|
|
111
|
+
const now = args.now ?? Date.now;
|
|
112
|
+
const opPath = `${args.origin}/api/v1/slate/ops/${encodeURIComponent(args.opId)}`;
|
|
113
|
+
/** One request, with the 429/503 retry policy; resolves only on a 2xx. */
|
|
114
|
+
const request = async (url, init = {}) => {
|
|
115
|
+
for (let attempt = 0;; attempt += 1) {
|
|
116
|
+
let response;
|
|
117
|
+
try {
|
|
118
|
+
response = await fetcher(url, { ...init, headers: { [PUSH_HEADER]: args.token, [CLI_HEADER]: args.cliVersion, ...init.headers } });
|
|
119
|
+
}
|
|
120
|
+
catch (cause) {
|
|
121
|
+
throw new DrawTransportError('unreachable', `${new URL(url).host} could not be reached`, { cause });
|
|
122
|
+
}
|
|
123
|
+
if (response.ok)
|
|
124
|
+
return response;
|
|
125
|
+
const body = await readBody(response);
|
|
126
|
+
const code = errorCodeOf(body) ?? `http_${response.status}`;
|
|
127
|
+
const retryAfter = retryAfterOf(response, body);
|
|
128
|
+
const retryable = response.status === 429 || (response.status === 503 && code === 'service_unavailable');
|
|
129
|
+
if (retryable && attempt < MAX_RETRIES) {
|
|
130
|
+
await sleep((retryAfter ?? 5) * 1000);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
throw new DrawHttpError(response.status, code, retryAfter, body);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const json = async (response) => {
|
|
137
|
+
const body = await readBody(response);
|
|
138
|
+
if (!isRecord(body))
|
|
139
|
+
throw new DrawTransportError('malformed', `${new URL(response.url || args.origin).pathname} did not answer JSON`);
|
|
140
|
+
return body;
|
|
141
|
+
};
|
|
142
|
+
return {
|
|
143
|
+
/** The frozen plan (2.1), waiting out `plan_pending` while the round's direction call finishes. */
|
|
144
|
+
plan: async () => {
|
|
145
|
+
const started = now();
|
|
146
|
+
for (;;) {
|
|
147
|
+
try {
|
|
148
|
+
return validatePlan(await json(await request(`${opPath}/plan`)), args.opId);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
if (!(error instanceof DrawHttpError) || error.code !== 'plan_pending' || now() - started >= PLAN_PENDING_LIMIT_MS)
|
|
152
|
+
throw error;
|
|
153
|
+
await sleep(Math.max(1, error.retryAfterSeconds ?? 2) * 1000);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
/** The exact bytes every engine attaches (2.2), checked against the server's sha256. */
|
|
158
|
+
image: async (name) => {
|
|
159
|
+
const response = await request(`${opPath}/images/${encodeURIComponent(name)}`);
|
|
160
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
161
|
+
const declared = response.headers.get('x-12ui-sha256');
|
|
162
|
+
const actual = sha256(bytes);
|
|
163
|
+
if (declared !== actual)
|
|
164
|
+
throw new DrawTransportError('corrupt', `Image ${name} arrived with sha256 ${actual}, not the ${declared ?? 'missing'} the server declared`);
|
|
165
|
+
return {
|
|
166
|
+
bytes,
|
|
167
|
+
mimeType: (response.headers.get('content-type') ?? 'application/octet-stream').split(';')[0].trim(),
|
|
168
|
+
sha256: actual,
|
|
169
|
+
referenceId: response.headers.get('x-12ui-reference-id'),
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
/** One option's image or failure reason (2.3). */
|
|
173
|
+
push: async (key, part) => {
|
|
174
|
+
const form = new FormData();
|
|
175
|
+
if ('png' in part)
|
|
176
|
+
form.append('file', new Blob([new Uint8Array(part.png)], { type: 'image/png' }), `${key}.png`);
|
|
177
|
+
else
|
|
178
|
+
form.append('reason', part.reason);
|
|
179
|
+
const url = `${args.origin}/api/v1/slate/push?op=${encodeURIComponent(args.opId)}&option=${encodeURIComponent(key)}`;
|
|
180
|
+
const body = await json(await request(url, { method: 'POST', body: form }));
|
|
181
|
+
if (body.state !== 'filled' && body.state !== 'failed')
|
|
182
|
+
throw new DrawTransportError('malformed', `The push of ${key} answered state ${JSON.stringify(body.state)}`);
|
|
183
|
+
return {
|
|
184
|
+
state: body.state,
|
|
185
|
+
label: stringOrNull(body.label),
|
|
186
|
+
versionId: stringOrNull(body.versionId),
|
|
187
|
+
replayed: body.replayed === true,
|
|
188
|
+
opState: stringOrNull(body.opState),
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=workspace-draw-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-client.js","sourceRoot":"","sources":["../src/workspace-draw-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type SlateImageExecutor } from './slate-image-executor.js';
|
|
2
|
+
import type { DrawOptionCodex, SlatePlanOption } from './workspace-draw-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The codex engine for one option (design section 6): one native `codex exec` image call through the repo's own
|
|
5
|
+
* executor, in its own temp `CODEX_HOME` linked to the agent's `auth.json`, under the call id the plan names. The
|
|
6
|
+
* executor's call store makes that id durable: a rerun returns a drawn image without a second call, and an id
|
|
7
|
+
* whose call ended without an image answers the same way again, never re-dispatched.
|
|
8
|
+
*
|
|
9
|
+
* After the call this reads the call directory back for the run record: the temp home (and whether it is gone),
|
|
10
|
+
* the rollouts kept in `native-custody/`, how many image calls the nested driver made, and whether the prompt it
|
|
11
|
+
* sent was the plan's prompt byte for byte.
|
|
12
|
+
*/
|
|
13
|
+
export type CodexOptionResult = {
|
|
14
|
+
kind: 'drawn';
|
|
15
|
+
png: Buffer;
|
|
16
|
+
reused: boolean;
|
|
17
|
+
details: DrawOptionCodex;
|
|
18
|
+
}
|
|
19
|
+
/** A model-class failure: pushed to the screen with this fixed sentence. */
|
|
20
|
+
| {
|
|
21
|
+
kind: 'failed';
|
|
22
|
+
failure: string;
|
|
23
|
+
details: DrawOptionCodex;
|
|
24
|
+
}
|
|
25
|
+
/** An environment-class failure (signed out, binary gone, store locked): not pushed, so a rerun can fix it. */
|
|
26
|
+
| {
|
|
27
|
+
kind: 'environment';
|
|
28
|
+
error: string;
|
|
29
|
+
details: DrawOptionCodex;
|
|
30
|
+
};
|
|
31
|
+
export type ExecutorFactory = (args: {
|
|
32
|
+
root: string;
|
|
33
|
+
env: NodeJS.ProcessEnv;
|
|
34
|
+
}) => SlateImageExecutor;
|
|
35
|
+
/** The executor's call store keeps one folder per call id at `<root>/calls/<sha256(id)>`. */
|
|
36
|
+
export declare const callDirectoryOf: (root: string, callId: string) => string;
|
|
37
|
+
/** What the call directory says about the call, for the record. */
|
|
38
|
+
export declare const readCallDetails: (callDir: string, prompt: string) => Promise<DrawOptionCodex & {
|
|
39
|
+
receiptState: string | null;
|
|
40
|
+
timedOut: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
export declare const drawOptionWithCodex: (args: {
|
|
43
|
+
root: string;
|
|
44
|
+
env: NodeJS.ProcessEnv;
|
|
45
|
+
option: SlatePlanOption;
|
|
46
|
+
images: Buffer[];
|
|
47
|
+
executorFactory?: ExecutorFactory;
|
|
48
|
+
}) => Promise<CodexOptionResult>;
|
|
49
|
+
//# sourceMappingURL=workspace-draw-codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-codex.d.ts","sourceRoot":"","sources":["../src/workspace-draw-codex.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAElF;;;;;;;;;GASG;AAEH,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE;AAC3E,4EAA4E;GAC1E;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE;AAC/D,+GAA+G;GAC7G;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAAK,kBAAkB,CAAC;AAIrG,6FAA6F;AAC7F,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,MAAkD,CAAC;AAWlH,mEAAmE;AACnE,eAAO,MAAM,eAAe,GAAU,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,eAAe,GAAG;IAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAgCnJ,CAAC;AAQF,eAAO,MAAM,mBAAmB,GAAU,MAAM;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,KAAG,OAAO,CAAC,iBAAiB,CAsB5B,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { createNativeImageExecutor } from './slate-image-executor.js';
|
|
6
|
+
import { OPTION_FAILURES } from './workspace-draw-messages.js';
|
|
7
|
+
const sha256 = (value) => createHash('sha256').update(value).digest('hex');
|
|
8
|
+
/** The executor's call store keeps one folder per call id at `<root>/calls/<sha256(id)>`. */
|
|
9
|
+
export const callDirectoryOf = (root, callId) => path.join(root, 'calls', sha256(callId));
|
|
10
|
+
const readJson = async (file) => {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(await readFile(file, 'utf8'));
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error.code === 'ENOENT')
|
|
16
|
+
return null;
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/** What the call directory says about the call, for the record. */
|
|
21
|
+
export const readCallDetails = async (callDir, prompt) => {
|
|
22
|
+
const [state, receipt, completion] = await Promise.all([
|
|
23
|
+
readJson(path.join(callDir, 'state.json')),
|
|
24
|
+
readJson(path.join(callDir, 'native-custody', 'receipt.json')),
|
|
25
|
+
readJson(path.join(callDir, 'completion.json')),
|
|
26
|
+
]);
|
|
27
|
+
const tempHome = typeof state?.metadata?.home === 'string' ? state.metadata.home : '';
|
|
28
|
+
let rollouts = [];
|
|
29
|
+
try {
|
|
30
|
+
rollouts = (await readdir(path.join(callDir, 'native-custody')))
|
|
31
|
+
.filter((name) => /^rollout-.*\.jsonl$/u.test(name))
|
|
32
|
+
.sort()
|
|
33
|
+
.map((name) => path.join(callDir, 'native-custody', name));
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error.code !== 'ENOENT')
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
const calls = Array.isArray(receipt?.calls) ? receipt.calls : [];
|
|
40
|
+
const literals = calls.flatMap((call) => call.prompts ?? [null]);
|
|
41
|
+
const generations = Array.isArray(receipt?.generations) ? receipt.generations : [];
|
|
42
|
+
const revised = generations[0]?.revisedPrompt;
|
|
43
|
+
return {
|
|
44
|
+
callDir,
|
|
45
|
+
tempHome,
|
|
46
|
+
tempHomeRemoved: tempHome !== '' && !existsSync(tempHome),
|
|
47
|
+
rollouts,
|
|
48
|
+
imageGenCalls: typeof receipt?.invocationCount === 'number' ? receipt.invocationCount : 0,
|
|
49
|
+
// Measured, never assumed: true only when exactly one call's literal is the plan prompt byte for byte.
|
|
50
|
+
promptVerbatim: literals.length === 1 && literals[0] !== null && literals[0] !== undefined ? literals[0] === prompt : null,
|
|
51
|
+
revisedPrompt: typeof revised === 'string' ? revised : null,
|
|
52
|
+
receiptState: typeof receipt?.state === 'string' ? receipt.state : null,
|
|
53
|
+
timedOut: completion?.timedOut === true,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
const failureSentence = (details) => {
|
|
57
|
+
if (details.timedOut)
|
|
58
|
+
return OPTION_FAILURES.timeout;
|
|
59
|
+
if (details.receiptState === 'protocol-violation-multiple-calls')
|
|
60
|
+
return OPTION_FAILURES.protocol;
|
|
61
|
+
return OPTION_FAILURES.noImage;
|
|
62
|
+
};
|
|
63
|
+
export const drawOptionWithCodex = async (args) => {
|
|
64
|
+
const executor = (args.executorFactory ?? createNativeImageExecutor)({ root: args.root, env: args.env });
|
|
65
|
+
const callDir = callDirectoryOf(args.root, args.option.callId);
|
|
66
|
+
const details = async () => {
|
|
67
|
+
const { receiptState, timedOut, ...record } = await readCallDetails(callDir, args.option.prompt);
|
|
68
|
+
return { record, receiptState, timedOut };
|
|
69
|
+
};
|
|
70
|
+
try {
|
|
71
|
+
const result = await executor.generate({
|
|
72
|
+
callId: args.option.callId,
|
|
73
|
+
prompt: args.option.prompt,
|
|
74
|
+
images: args.images,
|
|
75
|
+
expected: args.option.frame,
|
|
76
|
+
});
|
|
77
|
+
return { kind: 'drawn', png: result.png, reused: result.reused, details: (await details()).record };
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const code = error.code;
|
|
81
|
+
const read = await details();
|
|
82
|
+
if (code === 'NEEDS_RECONCILIATION')
|
|
83
|
+
return { kind: 'failed', failure: failureSentence(read), details: read.record };
|
|
84
|
+
if (code === 'REQUEST_CHANGED')
|
|
85
|
+
return { kind: 'failed', failure: OPTION_FAILURES.changed, details: read.record };
|
|
86
|
+
return { kind: 'environment', error: error instanceof Error ? error.message : String(error), details: read.record };
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=workspace-draw-codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-codex.js","sourceRoot":"","sources":["../src/workspace-draw-codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type CodexReadiness, type CodexReadinessCheck } from './cli-codex-readiness.js';
|
|
2
|
+
import type { DrawEngine, DrawRecordCodex } from './workspace-draw-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Whether Codex can draw a request, decided once per op and recorded with its reason (design section 3, step 4):
|
|
5
|
+
* Codex when the readiness probe passes in the agent's own Codex home. There is no other engine in this release
|
|
6
|
+
* (decision D2-B: drawing on 12ui needs a 12ui sign-in), so a probe that fails is a reason, never a fallback.
|
|
7
|
+
*/
|
|
8
|
+
export type RequestedEngine = 'auto' | DrawEngine;
|
|
9
|
+
export type EngineChoice = {
|
|
10
|
+
ok: true;
|
|
11
|
+
engine: DrawEngine;
|
|
12
|
+
reason: string;
|
|
13
|
+
codex: DrawRecordCodex;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: string;
|
|
17
|
+
check: Exclude<CodexReadinessCheck, 'ready'>;
|
|
18
|
+
};
|
|
19
|
+
export type ReadinessProbe = (options: {
|
|
20
|
+
env: NodeJS.ProcessEnv;
|
|
21
|
+
}) => Promise<CodexReadiness>;
|
|
22
|
+
/** "The same home": the calling agent's `CODEX_HOME`, else `~/.codex`. */
|
|
23
|
+
export declare const codexHomeOf: (env: NodeJS.ProcessEnv) => string;
|
|
24
|
+
/**
|
|
25
|
+
* `<home>/sessions/**\/rollout-*-<threadId>.jsonl`: the calling agent's own rollout, cheap proof that the drawing
|
|
26
|
+
* account is the caller's. Null when the thread id is unset or no such file exists.
|
|
27
|
+
*/
|
|
28
|
+
export declare const findSameHomeRollout: (home: string, threadId: string | null) => Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* `--engine` is strict: anything but auto or codex is a usage error. `TWELVE_UI_ENGINE` is shared with conversion,
|
|
31
|
+
* where `api` is a valid choice, so for this verb it counts only when it names auto or codex; any other value
|
|
32
|
+
* leaves the default, and a conversion setting never stops a workspace request from drawing.
|
|
33
|
+
*/
|
|
34
|
+
export declare const parseRequestedEngine: (flag: string | undefined, env: NodeJS.ProcessEnv) => RequestedEngine | null;
|
|
35
|
+
export declare const chooseEngine: (args: {
|
|
36
|
+
env: NodeJS.ProcessEnv;
|
|
37
|
+
probe?: ReadinessProbe;
|
|
38
|
+
}) => Promise<EngineChoice>;
|
|
39
|
+
//# sourceMappingURL=workspace-draw-engine.d.ts.map
|