@relay-harness/coding-agent 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +2 -3
- package/dist/bundle/chunks/{chunk-NS67SA75.js → chunk-6AEKWHDP.js} +1 -1
- package/dist/bundle/chunks/{chunk-3QND5D7W.js → chunk-7ZBTLURV.js} +1 -1
- package/dist/bundle/chunks/{chunk-WMTXXI7H.js → chunk-FUPU6X73.js} +1 -1
- package/dist/bundle/chunks/{chunk-XDAWU2J5.js → chunk-IDUCLYG3.js} +1 -1
- package/dist/bundle/chunks/{chunk-5H4IRYOE.js → chunk-LVFZRSZQ.js} +7 -7
- package/dist/bundle/chunks/{chunk-ISNO4JTR.js → chunk-PJWDW5WR.js} +2 -2
- package/dist/bundle/chunks/{chunk-3XNI2SB6.js → chunk-TZ2ZVU7E.js} +1 -1
- package/dist/bundle/chunks/{chunk-MP5FU7MG.js → chunk-UVFWV6YH.js} +1 -1
- package/dist/bundle/chunks/{chunk-PTRF7IZB.js → chunk-WU7MEKPF.js} +1 -1
- package/dist/bundle/chunks/{cli-K4CNHWOI.js → cli-2LN4J4IN.js} +1 -1
- package/dist/bundle/chunks/{easter-egg-3d-TGRCIHA4.js → easter-egg-3d-URCOHV3B.js} +1 -1
- package/dist/bundle/chunks/{execute-6E5DA2QI.js → execute-JAHDBPR2.js} +1 -1
- package/dist/bundle/chunks/{runtime-O5HLCH3V.js → runtime-TTSK6Y5T.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-ZGB2J7DY.js → virtual-modules-2G2P7CK2.js} +1 -1
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/extensions/laya/server.d.ts.map +1 -1
- package/dist/extensions/laya/server.js +16 -9
- package/dist/extensions/laya/server.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +9 -9
- package/dist/modes/interactive/theme/light.json +9 -9
- package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/system-theme.js +11 -10
- package/dist/modes/interactive/theme/system-theme.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +10 -10
|
@@ -107,20 +107,27 @@ export class LayaServer {
|
|
|
107
107
|
const image = await this.options.image();
|
|
108
108
|
const present = await docker(["image", "inspect", "--format", "{{.Id}}", image], { signal });
|
|
109
109
|
if (present.code !== 0) {
|
|
110
|
-
report("downloading the Laya image");
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
report("downloading the Laya image (a few GB, only the first time)");
|
|
111
|
+
// Docker Desktop's containerd store reports "Download complete" per layer while it downloads
|
|
112
|
+
// and "Pull complete" only when it extracts, and also completes blobs that are not layers.
|
|
113
|
+
// A layer counts once, when it is downloaded or already present.
|
|
114
|
+
const layers = new Set();
|
|
115
|
+
const done = new Set();
|
|
113
116
|
const pull = await docker(["pull", image], {
|
|
114
117
|
signal,
|
|
115
118
|
timeout: PULL_TIMEOUT_MS,
|
|
116
119
|
onLine: (line) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
else if (/: (Pull complete|Already exists)$/.test(line))
|
|
120
|
-
done++;
|
|
121
|
-
else
|
|
120
|
+
const match = /^([0-9a-f]{12}): (Pulling fs layer|Already exists|Download complete|Pull complete)$/.exec(line.trim());
|
|
121
|
+
if (!match)
|
|
122
122
|
return;
|
|
123
|
-
|
|
123
|
+
const [, id, status] = match;
|
|
124
|
+
if (status === "Pulling fs layer" || status === "Already exists")
|
|
125
|
+
layers.add(id);
|
|
126
|
+
if (status !== "Pulling fs layer" && layers.has(id) && !done.has(id))
|
|
127
|
+
done.add(id);
|
|
128
|
+
else if (status !== "Pulling fs layer")
|
|
129
|
+
return;
|
|
130
|
+
report(`downloading the Laya image: ${done.size}/${layers.size} layers`);
|
|
124
131
|
},
|
|
125
132
|
});
|
|
126
133
|
if (pull.code !== 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/extensions/laya/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { DOCKER_MISSING, type DockerRun, dockerError } from \"./docker.ts\";\nimport { LAYA_QUESTIONS } from \"./questions.ts\";\nimport {\n\tLAYA_CONTAINER,\n\tLAYA_CONTAINER_PORT,\n\tLAYA_IMAGE_PATHS,\n\tLAYA_IMAGE_REPOSITORY,\n\tLAYA_MODELS_VOLUME,\n} from \"./runtime.ts\";\n\nconst HEALTH_TIMEOUT_MS = 1500;\n/** Loading the model on the CPU of a slow machine takes a while. */\nconst START_TIMEOUT_MS = 180_000;\nconst POLL_MS = 1000;\nconst PULL_TIMEOUT_MS = 60 * 60_000;\nconst COMMAND_TIMEOUT_MS = 60_000;\n\n/** Labels that describe what a server container runs; a container whose labels differ is replaced. */\nconst LABEL_IMAGE = \"relay.laya.image\";\nconst LABEL_MODEL = \"relay.laya.model\";\nconst LABEL_ADDRESS = \"relay.laya.address\";\n\nexport type LayaServerState =\n\t/** Not checked yet in this process. */\n\t| \"unknown\"\n\t/** The docker command is missing or its daemon does not answer. */\n\t| \"no-docker\"\n\t| \"installing\"\n\t| \"ready\"\n\t| \"failed\";\n\nexport interface LayaServerOptions {\n\tdocker: DockerRun;\n\t/** The configured System One URL, e.g. `http://127.0.0.1:8737/v1`. */\n\tbaseUrl: () => string;\n\t/** Image to run. */\n\timage: () => Promise<string>;\n\t/** Model to serve, as a path inside the container. */\n\tmodel: () => string;\n\tfetch?: typeof fetch;\n}\n\n/** Whether a URL points at this machine, the only place Relay runs a server. */\nexport function isLocalUrl(url: string): boolean {\n\ttry {\n\t\treturn [\"127.0.0.1\", \"localhost\", \"[::1]\"].includes(new URL(url).hostname);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Host address Docker publishes the server port on, from the configured URL. */\nfunction publishAddress(baseUrl: string): string {\n\tconst url = new URL(baseUrl);\n\tconst host = url.hostname === \"[::1]\" ? \"[::1]\" : \"127.0.0.1\";\n\treturn `${host}:${url.port || \"80\"}`;\n}\n\n/**\n * The Laya server container. `install()` pulls the image when it is missing and keeps one container\n * running with the active model, published on the configured local port only. The container\n * restarts with Docker, so later sessions find it answering. A server that answers without being\n * ours (no container named relay-laya) is used as is, unless it serves other questions than Relay's.\n */\nexport class LayaServer {\n\tprivate readonly options: LayaServerOptions;\n\tprivate installing: Promise<boolean> | undefined;\n\tstate: LayaServerState = \"unknown\";\n\t/** Why the server is not ready, for `/laya status`. */\n\tdetail: string | undefined;\n\t/** Image of the running container. */\n\timage: string | undefined;\n\n\tconstructor(options: LayaServerOptions) {\n\t\tthis.options = options;\n\t}\n\n\t/** The server's health answer, when it answers. */\n\tprivate async health(): Promise<{ ok?: boolean; decisions?: unknown } | undefined> {\n\t\tconst request = this.options.fetch ?? globalThis.fetch;\n\t\ttry {\n\t\t\tconst response = await request(new URL(\"/health\", this.options.baseUrl()), {\n\t\t\t\tsignal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),\n\t\t\t});\n\t\t\tif (!response.ok) return undefined;\n\t\t\tconst body = (await response.json()) as { ok?: boolean; decisions?: unknown };\n\t\t\treturn body.ok === true ? body : undefined;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync isUp(): Promise<boolean> {\n\t\treturn (await this.health()) !== undefined;\n\t}\n\n\t/** Makes the server answer: pulls, creates, replaces or starts the container. Concurrent calls share one run. */\n\tinstall(report: (message: string) => void = () => {}, signal?: AbortSignal): Promise<boolean> {\n\t\tthis.installing ??= this.run(report, signal).finally(() => {\n\t\t\tthis.installing = undefined;\n\t\t});\n\t\treturn this.installing;\n\t}\n\n\tprivate fail(state: \"no-docker\" | \"failed\", detail: string): false {\n\t\tthis.state = state;\n\t\tthis.detail = detail;\n\t\treturn false;\n\t}\n\n\tprivate async run(report: (message: string) => void, signal?: AbortSignal): Promise<boolean> {\n\t\tconst { docker } = this.options;\n\t\tconst baseUrl = this.options.baseUrl();\n\t\tif (!isLocalUrl(baseUrl)) {\n\t\t\t// A remote server is not Relay's to manage.\n\t\t\tconst up = await this.isUp();\n\t\t\treturn up ? this.ready() : this.fail(\"failed\", `${baseUrl} does not answer`);\n\t\t}\n\t\tthis.state = \"installing\";\n\t\tthis.detail = undefined;\n\n\t\tconst version = await docker([\"version\", \"--format\", \"{{.Server.Version}}\"], {\n\t\t\tsignal,\n\t\t\ttimeout: COMMAND_TIMEOUT_MS,\n\t\t});\n\t\tif (version.code !== 0) {\n\t\t\treturn this.fail(\n\t\t\t\t\"no-docker\",\n\t\t\t\tversion.code === DOCKER_MISSING\n\t\t\t\t\t? \"Docker is not installed\"\n\t\t\t\t\t: `Docker does not answer; start Docker Desktop or the Docker service (${dockerError(version)})`,\n\t\t\t);\n\t\t}\n\n\t\tconst container = await this.inspect(signal);\n\t\tconst foreign = container ? undefined : await this.health();\n\t\tif (foreign) {\n\t\t\t// Someone else's server on this port: use it, unless it says it answers other questions,\n\t\t\t// like a laya-trainer server of another project.\n\t\t\tconst decisions = Array.isArray(foreign.decisions) ? foreign.decisions : undefined;\n\t\t\tif (decisions && !Object.keys(LAYA_QUESTIONS).every((name) => decisions.includes(name))) {\n\t\t\t\treturn this.fail(\n\t\t\t\t\t\"failed\",\n\t\t\t\t\t`another Laya server, which answers other questions, uses ${publishAddress(baseUrl)}; stop it or set laya.baseUrl to a free port`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.ready();\n\t\t}\n\n\t\tconst image = await this.options.image();\n\t\tconst present = await docker([\"image\", \"inspect\", \"--format\", \"{{.Id}}\", image], { signal });\n\t\tif (present.code !== 0) {\n\t\t\treport(\"downloading the Laya image\");\n\t\t\tlet layers = 0;\n\t\t\tlet done = 0;\n\t\t\tconst pull = await docker([\"pull\", image], {\n\t\t\t\tsignal,\n\t\t\t\ttimeout: PULL_TIMEOUT_MS,\n\t\t\t\tonLine: (line) => {\n\t\t\t\t\tif (/: Pulling fs layer$/.test(line)) layers++;\n\t\t\t\t\telse if (/: (Pull complete|Already exists)$/.test(line)) done++;\n\t\t\t\t\telse return;\n\t\t\t\t\treport(`downloading the Laya image: ${done}/${layers} layers`);\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (pull.code !== 0) return this.fail(\"failed\", `Pulling ${image} failed: ${dockerError(pull)}`);\n\t\t}\n\n\t\tconst labels = {\n\t\t\t[LABEL_IMAGE]: image,\n\t\t\t[LABEL_MODEL]: this.options.model(),\n\t\t\t[LABEL_ADDRESS]: publishAddress(baseUrl),\n\t\t};\n\t\tconst matches = container && Object.entries(labels).every(([key, value]) => container.labels[key] === value);\n\t\tif (container && !matches) {\n\t\t\tconst removed = await docker([\"rm\", \"--force\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\tif (removed.code !== 0)\n\t\t\t\treturn this.fail(\"failed\", `Replacing the Laya container failed: ${dockerError(removed)}`);\n\t\t}\n\t\tif (!matches) {\n\t\t\treport(\"starting the Laya server\");\n\t\t\tconst created = await docker(this.runArgs(image, labels), { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\t// Another Relay created it at the same time: use theirs, it runs the same image and model.\n\t\t\tif (created.code !== 0 && !(await this.inspect(signal))) {\n\t\t\t\treturn this.fail(\"failed\", `Starting the Laya container failed: ${dockerError(created)}`);\n\t\t\t}\n\t\t} else if (container && !container.running) {\n\t\t\treport(\"starting the Laya server\");\n\t\t\tconst started = await docker([\"start\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\tif (started.code !== 0)\n\t\t\t\treturn this.fail(\"failed\", `Starting the Laya container failed: ${dockerError(started)}`);\n\t\t}\n\n\t\t// A running container that matches is only checked; nothing new to report.\n\t\tif (!matches || !container?.running) report(\"loading the Laya model\");\n\t\tconst deadline = Date.now() + START_TIMEOUT_MS;\n\t\twhile (Date.now() < deadline && !signal?.aborted) {\n\t\t\tif (await this.isUp()) {\n\t\t\t\tthis.image = image;\n\t\t\t\tawait this.removeOtherImages(image);\n\t\t\t\treturn this.ready();\n\t\t\t}\n\t\t\tconst current = await this.inspect(signal);\n\t\t\tif (!current?.running) {\n\t\t\t\tconst logs = await docker([\"logs\", \"--tail\", \"5\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\t\treturn this.fail(\"failed\", `The Laya container stopped: ${dockerError(logs)}`);\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, POLL_MS));\n\t\t}\n\t\treturn this.fail(\"failed\", \"The Laya server did not answer in time (see docker logs relay-laya)\");\n\t}\n\n\tprivate ready(): true {\n\t\tthis.state = \"ready\";\n\t\tthis.detail = undefined;\n\t\treturn true;\n\t}\n\n\tprivate runArgs(image: string, labels: Record<string, string>): string[] {\n\t\treturn [\n\t\t\t\"run\",\n\t\t\t\"--detach\",\n\t\t\t\"--name\",\n\t\t\tLAYA_CONTAINER,\n\t\t\t\"--restart\",\n\t\t\t\"unless-stopped\",\n\t\t\t\"--publish\",\n\t\t\t`${labels[LABEL_ADDRESS]}:${LAYA_CONTAINER_PORT}`,\n\t\t\t\"--volume\",\n\t\t\t`${LAYA_MODELS_VOLUME}:${LAYA_IMAGE_PATHS.trainedModels}`,\n\t\t\t...Object.entries(labels).flatMap(([key, value]) => [\"--label\", `${key}=${value}`]),\n\t\t\timage,\n\t\t\t\"python\",\n\t\t\tLAYA_IMAGE_PATHS.serveScript,\n\t\t\t\"--model\",\n\t\t\tlabels[LABEL_MODEL],\n\t\t\t\"--host\",\n\t\t\t\"0.0.0.0\",\n\t\t\t\"--port\",\n\t\t\tString(LAYA_CONTAINER_PORT),\n\t\t];\n\t}\n\n\tprivate async inspect(\n\t\tsignal?: AbortSignal,\n\t): Promise<{ running: boolean; labels: Record<string, string> } | undefined> {\n\t\tconst result = await this.options.docker(\n\t\t\t[\"container\", \"inspect\", \"--format\", \"{{json .State.Running}} {{json .Config.Labels}}\", LAYA_CONTAINER],\n\t\t\t{ signal, timeout: COMMAND_TIMEOUT_MS },\n\t\t);\n\t\tif (result.code !== 0) return undefined;\n\t\tconst [running, ...labels] = result.stdout.trim().split(\" \");\n\t\ttry {\n\t\t\treturn {\n\t\t\t\trunning: running === \"true\",\n\t\t\t\tlabels: (JSON.parse(labels.join(\" \")) as Record<string, string> | null) ?? {},\n\t\t\t};\n\t\t} catch {\n\t\t\treturn { running: running === \"true\", labels: {} };\n\t\t}\n\t}\n\n\t/** Frees the disk taken by images of earlier Relay versions. */\n\tprivate async removeOtherImages(image: string): Promise<void> {\n\t\tconst listed = await this.options.docker(\n\t\t\t[\"image\", \"ls\", LAYA_IMAGE_REPOSITORY, \"--format\", \"{{.Repository}}:{{.Tag}}\"],\n\t\t\t{ timeout: COMMAND_TIMEOUT_MS },\n\t\t);\n\t\tif (listed.code !== 0) return;\n\t\tconst others = listed.stdout\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter((ref) => ref && ref !== image && !ref.endsWith(\":<none>\"));\n\t\t// An image still used by a training container is kept; rmi fails on it.\n\t\tif (others.length > 0) await this.options.docker([\"rmi\", ...others], { timeout: COMMAND_TIMEOUT_MS });\n\t}\n\n\t/** Stops the server container; the next install starts it again. */\n\tasync stop(): Promise<void> {\n\t\tawait this.options.docker([\"stop\", LAYA_CONTAINER], { timeout: COMMAND_TIMEOUT_MS });\n\t\tif (this.state === \"ready\") this.state = \"unknown\";\n\t}\n\n\tdescribe(): string {\n\t\tswitch (this.state) {\n\t\t\tcase \"ready\":\n\t\t\t\treturn `running in Docker${this.image ? ` (${this.image}, model ${this.options.model()})` : \"\"}`;\n\t\t\tcase \"installing\":\n\t\t\t\treturn \"installing in Docker\";\n\t\t\tcase \"no-docker\":\n\t\t\t\treturn `not available: ${this.detail}`;\n\t\t\tcase \"failed\":\n\t\t\t\treturn `failed: ${this.detail}`;\n\t\t\tdefault:\n\t\t\t\treturn \"not checked yet\";\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/extensions/laya/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { DOCKER_MISSING, type DockerRun, dockerError } from \"./docker.ts\";\nimport { LAYA_QUESTIONS } from \"./questions.ts\";\nimport {\n\tLAYA_CONTAINER,\n\tLAYA_CONTAINER_PORT,\n\tLAYA_IMAGE_PATHS,\n\tLAYA_IMAGE_REPOSITORY,\n\tLAYA_MODELS_VOLUME,\n} from \"./runtime.ts\";\n\nconst HEALTH_TIMEOUT_MS = 1500;\n/** Loading the model on the CPU of a slow machine takes a while. */\nconst START_TIMEOUT_MS = 180_000;\nconst POLL_MS = 1000;\nconst PULL_TIMEOUT_MS = 60 * 60_000;\nconst COMMAND_TIMEOUT_MS = 60_000;\n\n/** Labels that describe what a server container runs; a container whose labels differ is replaced. */\nconst LABEL_IMAGE = \"relay.laya.image\";\nconst LABEL_MODEL = \"relay.laya.model\";\nconst LABEL_ADDRESS = \"relay.laya.address\";\n\nexport type LayaServerState =\n\t/** Not checked yet in this process. */\n\t| \"unknown\"\n\t/** The docker command is missing or its daemon does not answer. */\n\t| \"no-docker\"\n\t| \"installing\"\n\t| \"ready\"\n\t| \"failed\";\n\nexport interface LayaServerOptions {\n\tdocker: DockerRun;\n\t/** The configured System One URL, e.g. `http://127.0.0.1:8737/v1`. */\n\tbaseUrl: () => string;\n\t/** Image to run. */\n\timage: () => Promise<string>;\n\t/** Model to serve, as a path inside the container. */\n\tmodel: () => string;\n\tfetch?: typeof fetch;\n}\n\n/** Whether a URL points at this machine, the only place Relay runs a server. */\nexport function isLocalUrl(url: string): boolean {\n\ttry {\n\t\treturn [\"127.0.0.1\", \"localhost\", \"[::1]\"].includes(new URL(url).hostname);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Host address Docker publishes the server port on, from the configured URL. */\nfunction publishAddress(baseUrl: string): string {\n\tconst url = new URL(baseUrl);\n\tconst host = url.hostname === \"[::1]\" ? \"[::1]\" : \"127.0.0.1\";\n\treturn `${host}:${url.port || \"80\"}`;\n}\n\n/**\n * The Laya server container. `install()` pulls the image when it is missing and keeps one container\n * running with the active model, published on the configured local port only. The container\n * restarts with Docker, so later sessions find it answering. A server that answers without being\n * ours (no container named relay-laya) is used as is, unless it serves other questions than Relay's.\n */\nexport class LayaServer {\n\tprivate readonly options: LayaServerOptions;\n\tprivate installing: Promise<boolean> | undefined;\n\tstate: LayaServerState = \"unknown\";\n\t/** Why the server is not ready, for `/laya status`. */\n\tdetail: string | undefined;\n\t/** Image of the running container. */\n\timage: string | undefined;\n\n\tconstructor(options: LayaServerOptions) {\n\t\tthis.options = options;\n\t}\n\n\t/** The server's health answer, when it answers. */\n\tprivate async health(): Promise<{ ok?: boolean; decisions?: unknown } | undefined> {\n\t\tconst request = this.options.fetch ?? globalThis.fetch;\n\t\ttry {\n\t\t\tconst response = await request(new URL(\"/health\", this.options.baseUrl()), {\n\t\t\t\tsignal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),\n\t\t\t});\n\t\t\tif (!response.ok) return undefined;\n\t\t\tconst body = (await response.json()) as { ok?: boolean; decisions?: unknown };\n\t\t\treturn body.ok === true ? body : undefined;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync isUp(): Promise<boolean> {\n\t\treturn (await this.health()) !== undefined;\n\t}\n\n\t/** Makes the server answer: pulls, creates, replaces or starts the container. Concurrent calls share one run. */\n\tinstall(report: (message: string) => void = () => {}, signal?: AbortSignal): Promise<boolean> {\n\t\tthis.installing ??= this.run(report, signal).finally(() => {\n\t\t\tthis.installing = undefined;\n\t\t});\n\t\treturn this.installing;\n\t}\n\n\tprivate fail(state: \"no-docker\" | \"failed\", detail: string): false {\n\t\tthis.state = state;\n\t\tthis.detail = detail;\n\t\treturn false;\n\t}\n\n\tprivate async run(report: (message: string) => void, signal?: AbortSignal): Promise<boolean> {\n\t\tconst { docker } = this.options;\n\t\tconst baseUrl = this.options.baseUrl();\n\t\tif (!isLocalUrl(baseUrl)) {\n\t\t\t// A remote server is not Relay's to manage.\n\t\t\tconst up = await this.isUp();\n\t\t\treturn up ? this.ready() : this.fail(\"failed\", `${baseUrl} does not answer`);\n\t\t}\n\t\tthis.state = \"installing\";\n\t\tthis.detail = undefined;\n\n\t\tconst version = await docker([\"version\", \"--format\", \"{{.Server.Version}}\"], {\n\t\t\tsignal,\n\t\t\ttimeout: COMMAND_TIMEOUT_MS,\n\t\t});\n\t\tif (version.code !== 0) {\n\t\t\treturn this.fail(\n\t\t\t\t\"no-docker\",\n\t\t\t\tversion.code === DOCKER_MISSING\n\t\t\t\t\t? \"Docker is not installed\"\n\t\t\t\t\t: `Docker does not answer; start Docker Desktop or the Docker service (${dockerError(version)})`,\n\t\t\t);\n\t\t}\n\n\t\tconst container = await this.inspect(signal);\n\t\tconst foreign = container ? undefined : await this.health();\n\t\tif (foreign) {\n\t\t\t// Someone else's server on this port: use it, unless it says it answers other questions,\n\t\t\t// like a laya-trainer server of another project.\n\t\t\tconst decisions = Array.isArray(foreign.decisions) ? foreign.decisions : undefined;\n\t\t\tif (decisions && !Object.keys(LAYA_QUESTIONS).every((name) => decisions.includes(name))) {\n\t\t\t\treturn this.fail(\n\t\t\t\t\t\"failed\",\n\t\t\t\t\t`another Laya server, which answers other questions, uses ${publishAddress(baseUrl)}; stop it or set laya.baseUrl to a free port`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.ready();\n\t\t}\n\n\t\tconst image = await this.options.image();\n\t\tconst present = await docker([\"image\", \"inspect\", \"--format\", \"{{.Id}}\", image], { signal });\n\t\tif (present.code !== 0) {\n\t\t\treport(\"downloading the Laya image (a few GB, only the first time)\");\n\t\t\t// Docker Desktop's containerd store reports \"Download complete\" per layer while it downloads\n\t\t\t// and \"Pull complete\" only when it extracts, and also completes blobs that are not layers.\n\t\t\t// A layer counts once, when it is downloaded or already present.\n\t\t\tconst layers = new Set<string>();\n\t\t\tconst done = new Set<string>();\n\t\t\tconst pull = await docker([\"pull\", image], {\n\t\t\t\tsignal,\n\t\t\t\ttimeout: PULL_TIMEOUT_MS,\n\t\t\t\tonLine: (line) => {\n\t\t\t\t\tconst match = /^([0-9a-f]{12}): (Pulling fs layer|Already exists|Download complete|Pull complete)$/.exec(\n\t\t\t\t\t\tline.trim(),\n\t\t\t\t\t);\n\t\t\t\t\tif (!match) return;\n\t\t\t\t\tconst [, id, status] = match;\n\t\t\t\t\tif (status === \"Pulling fs layer\" || status === \"Already exists\") layers.add(id);\n\t\t\t\t\tif (status !== \"Pulling fs layer\" && layers.has(id) && !done.has(id)) done.add(id);\n\t\t\t\t\telse if (status !== \"Pulling fs layer\") return;\n\t\t\t\t\treport(`downloading the Laya image: ${done.size}/${layers.size} layers`);\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (pull.code !== 0) return this.fail(\"failed\", `Pulling ${image} failed: ${dockerError(pull)}`);\n\t\t}\n\n\t\tconst labels = {\n\t\t\t[LABEL_IMAGE]: image,\n\t\t\t[LABEL_MODEL]: this.options.model(),\n\t\t\t[LABEL_ADDRESS]: publishAddress(baseUrl),\n\t\t};\n\t\tconst matches = container && Object.entries(labels).every(([key, value]) => container.labels[key] === value);\n\t\tif (container && !matches) {\n\t\t\tconst removed = await docker([\"rm\", \"--force\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\tif (removed.code !== 0)\n\t\t\t\treturn this.fail(\"failed\", `Replacing the Laya container failed: ${dockerError(removed)}`);\n\t\t}\n\t\tif (!matches) {\n\t\t\treport(\"starting the Laya server\");\n\t\t\tconst created = await docker(this.runArgs(image, labels), { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\t// Another Relay created it at the same time: use theirs, it runs the same image and model.\n\t\t\tif (created.code !== 0 && !(await this.inspect(signal))) {\n\t\t\t\treturn this.fail(\"failed\", `Starting the Laya container failed: ${dockerError(created)}`);\n\t\t\t}\n\t\t} else if (container && !container.running) {\n\t\t\treport(\"starting the Laya server\");\n\t\t\tconst started = await docker([\"start\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\tif (started.code !== 0)\n\t\t\t\treturn this.fail(\"failed\", `Starting the Laya container failed: ${dockerError(started)}`);\n\t\t}\n\n\t\t// A running container that matches is only checked; nothing new to report.\n\t\tif (!matches || !container?.running) report(\"loading the Laya model\");\n\t\tconst deadline = Date.now() + START_TIMEOUT_MS;\n\t\twhile (Date.now() < deadline && !signal?.aborted) {\n\t\t\tif (await this.isUp()) {\n\t\t\t\tthis.image = image;\n\t\t\t\tawait this.removeOtherImages(image);\n\t\t\t\treturn this.ready();\n\t\t\t}\n\t\t\tconst current = await this.inspect(signal);\n\t\t\tif (!current?.running) {\n\t\t\t\tconst logs = await docker([\"logs\", \"--tail\", \"5\", LAYA_CONTAINER], { signal, timeout: COMMAND_TIMEOUT_MS });\n\t\t\t\treturn this.fail(\"failed\", `The Laya container stopped: ${dockerError(logs)}`);\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, POLL_MS));\n\t\t}\n\t\treturn this.fail(\"failed\", \"The Laya server did not answer in time (see docker logs relay-laya)\");\n\t}\n\n\tprivate ready(): true {\n\t\tthis.state = \"ready\";\n\t\tthis.detail = undefined;\n\t\treturn true;\n\t}\n\n\tprivate runArgs(image: string, labels: Record<string, string>): string[] {\n\t\treturn [\n\t\t\t\"run\",\n\t\t\t\"--detach\",\n\t\t\t\"--name\",\n\t\t\tLAYA_CONTAINER,\n\t\t\t\"--restart\",\n\t\t\t\"unless-stopped\",\n\t\t\t\"--publish\",\n\t\t\t`${labels[LABEL_ADDRESS]}:${LAYA_CONTAINER_PORT}`,\n\t\t\t\"--volume\",\n\t\t\t`${LAYA_MODELS_VOLUME}:${LAYA_IMAGE_PATHS.trainedModels}`,\n\t\t\t...Object.entries(labels).flatMap(([key, value]) => [\"--label\", `${key}=${value}`]),\n\t\t\timage,\n\t\t\t\"python\",\n\t\t\tLAYA_IMAGE_PATHS.serveScript,\n\t\t\t\"--model\",\n\t\t\tlabels[LABEL_MODEL],\n\t\t\t\"--host\",\n\t\t\t\"0.0.0.0\",\n\t\t\t\"--port\",\n\t\t\tString(LAYA_CONTAINER_PORT),\n\t\t];\n\t}\n\n\tprivate async inspect(\n\t\tsignal?: AbortSignal,\n\t): Promise<{ running: boolean; labels: Record<string, string> } | undefined> {\n\t\tconst result = await this.options.docker(\n\t\t\t[\"container\", \"inspect\", \"--format\", \"{{json .State.Running}} {{json .Config.Labels}}\", LAYA_CONTAINER],\n\t\t\t{ signal, timeout: COMMAND_TIMEOUT_MS },\n\t\t);\n\t\tif (result.code !== 0) return undefined;\n\t\tconst [running, ...labels] = result.stdout.trim().split(\" \");\n\t\ttry {\n\t\t\treturn {\n\t\t\t\trunning: running === \"true\",\n\t\t\t\tlabels: (JSON.parse(labels.join(\" \")) as Record<string, string> | null) ?? {},\n\t\t\t};\n\t\t} catch {\n\t\t\treturn { running: running === \"true\", labels: {} };\n\t\t}\n\t}\n\n\t/** Frees the disk taken by images of earlier Relay versions. */\n\tprivate async removeOtherImages(image: string): Promise<void> {\n\t\tconst listed = await this.options.docker(\n\t\t\t[\"image\", \"ls\", LAYA_IMAGE_REPOSITORY, \"--format\", \"{{.Repository}}:{{.Tag}}\"],\n\t\t\t{ timeout: COMMAND_TIMEOUT_MS },\n\t\t);\n\t\tif (listed.code !== 0) return;\n\t\tconst others = listed.stdout\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter((ref) => ref && ref !== image && !ref.endsWith(\":<none>\"));\n\t\t// An image still used by a training container is kept; rmi fails on it.\n\t\tif (others.length > 0) await this.options.docker([\"rmi\", ...others], { timeout: COMMAND_TIMEOUT_MS });\n\t}\n\n\t/** Stops the server container; the next install starts it again. */\n\tasync stop(): Promise<void> {\n\t\tawait this.options.docker([\"stop\", LAYA_CONTAINER], { timeout: COMMAND_TIMEOUT_MS });\n\t\tif (this.state === \"ready\") this.state = \"unknown\";\n\t}\n\n\tdescribe(): string {\n\t\tswitch (this.state) {\n\t\t\tcase \"ready\":\n\t\t\t\treturn `running in Docker${this.image ? ` (${this.image}, model ${this.options.model()})` : \"\"}`;\n\t\t\tcase \"installing\":\n\t\t\t\treturn \"installing in Docker\";\n\t\t\tcase \"no-docker\":\n\t\t\t\treturn `not available: ${this.detail}`;\n\t\t\tcase \"failed\":\n\t\t\t\treturn `failed: ${this.detail}`;\n\t\t\tdefault:\n\t\t\t\treturn \"not checked yet\";\n\t\t}\n\t}\n}\n"]}
|
|
@@ -19,7 +19,7 @@ export class CustomMessageComponent extends Container {
|
|
|
19
19
|
this.markdownTheme = markdownTheme;
|
|
20
20
|
this.outputPad = outputPad;
|
|
21
21
|
this.addChild(new Spacer(1));
|
|
22
|
-
// Create box with
|
|
22
|
+
// Create box with the accent-tinted background (used for default rendering)
|
|
23
23
|
this.box = new Box(1, 1, (t) => theme.bg("customMessageBg", t));
|
|
24
24
|
this.rebuild();
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAGhG,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,SAAS;IAC5C,OAAO,CAAyB;IAChC,cAAc,CAAmB;IACjC,GAAG,CAAM;IACT,eAAe,CAAa;IAC5B,aAAa,CAAgB;IAC7B,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,CAAS;IAE1B,YACC,OAA+B,EAC/B,cAAgC,EAChC,aAAa,GAAkB,gBAAgB,EAAE,EACjD,SAAS,GAAG,CAAC;QAEb,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,
|
|
1
|
+
{"version":3,"file":"custom-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TextContent } from \"@relay-harness/ai\";\nimport type { Component } from \"@relay-harness/tui\";\nimport { Box, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@relay-harness/tui\";\nimport type { MessageRenderer } from \"../../../core/extensions/types.ts\";\nimport type { CustomMessage } from \"../../../core/messages.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\n/**\n * Component that renders a custom message entry from extensions.\n * Uses distinct styling to differentiate from user messages.\n */\nexport class CustomMessageComponent extends Container {\n\tprivate message: CustomMessage<unknown>;\n\tprivate customRenderer?: MessageRenderer;\n\tprivate box: Box;\n\tprivate customComponent?: Component;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate _expanded = false;\n\tprivate outputPad: number;\n\n\tconstructor(\n\t\tmessage: CustomMessage<unknown>,\n\t\tcustomRenderer?: MessageRenderer,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.customRenderer = customRenderer;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create box with the accent-tinted background (used for default rendering)\n\t\tthis.box = new Box(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\n\t\tthis.rebuild();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this._expanded !== expanded) {\n\t\t\tthis._expanded = expanded;\n\t\t\tthis.rebuild();\n\t\t}\n\t}\n\n\tsetOutputPad(outputPad: number): void {\n\t\tif (this.outputPad !== outputPad) {\n\t\t\tthis.outputPad = outputPad;\n\t\t\tthis.rebuild();\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\t// Remove previous content component\n\t\tif (this.customComponent) {\n\t\t\tthis.removeChild(this.customComponent);\n\t\t\tthis.customComponent = undefined;\n\t\t}\n\t\tthis.removeChild(this.box);\n\n\t\t// Try custom renderer first - it handles its own styling\n\t\tif (this.customRenderer) {\n\t\t\ttry {\n\t\t\t\tconst component = this.customRenderer(\n\t\t\t\t\tthis.message,\n\t\t\t\t\t{ expanded: this._expanded, outputPad: this.outputPad },\n\t\t\t\t\ttheme,\n\t\t\t\t);\n\t\t\t\tif (component) {\n\t\t\t\t\t// Custom renderer provides its own styled component\n\t\t\t\t\tthis.customComponent = component;\n\t\t\t\t\tthis.addChild(component);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to default rendering\n\t\t\t}\n\t\t}\n\n\t\t// Default rendering uses our box\n\t\tthis.addChild(this.box);\n\t\tthis.box.clear();\n\n\t\t// Default rendering: label + content\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[${this.message.customType}]\\x1b[22m`);\n\t\tthis.box.addChild(new Text(label, 0, 0));\n\t\tthis.box.addChild(new Spacer(1));\n\n\t\t// Extract text content\n\t\tlet text: string;\n\t\tif (typeof this.message.content === \"string\") {\n\t\t\ttext = this.message.content;\n\t\t} else {\n\t\t\ttext = this.message.content\n\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\\n\");\n\t\t}\n\n\t\tthis.box.addChild(\n\t\t\tnew Markdown(text, 0, 0, this.markdownTheme, {\n\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t}),\n\t\t);\n\t}\n}\n"]}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"vars": {
|
|
6
6
|
"text": "okhsl(234 3% 89%)",
|
|
7
7
|
"muted": "okhsl(229 6% 67%)",
|
|
8
|
-
"
|
|
8
|
+
"cyan": "okhsl(188 75% 67%)",
|
|
9
9
|
"blue": "okhsl(232 54% 67%)",
|
|
10
10
|
"green": "okhsl(159 59% 67%)",
|
|
11
11
|
"red": "okhsl(20 72% 67%)",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"blueBg": "okhsl(233 41% 24%)"
|
|
14
14
|
},
|
|
15
15
|
"colors": {
|
|
16
|
-
"accent": "
|
|
16
|
+
"accent": "cyan",
|
|
17
17
|
"border": "okhsl(231 57% 65%)",
|
|
18
|
-
"borderAccent": "okhsl(
|
|
18
|
+
"borderAccent": "okhsl(188 70% 64%)",
|
|
19
19
|
"borderMuted": "okhsl(229 8% 53%)",
|
|
20
20
|
"success": "green",
|
|
21
21
|
"error": "red",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"searchMatchText": "muted",
|
|
32
32
|
"userMessageBg": "blueBg",
|
|
33
33
|
"userMessageText": "text",
|
|
34
|
-
"customMessageBg": "okhsl(
|
|
34
|
+
"customMessageBg": "okhsl(188 42% 24%)",
|
|
35
35
|
"customMessageText": "muted",
|
|
36
|
-
"customMessageLabel": "
|
|
36
|
+
"customMessageLabel": "cyan",
|
|
37
37
|
"toolPendingBg": "okhsl(229 5% 24%)",
|
|
38
38
|
"toolSuccessBg": "okhsl(158 46% 25%)",
|
|
39
39
|
"toolErrorBg": "okhsl(19 54% 25%)",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"mdHeading": "yellow",
|
|
43
43
|
"mdLink": "blue",
|
|
44
44
|
"mdLinkUrl": "muted",
|
|
45
|
-
"mdCode": "
|
|
45
|
+
"mdCode": "cyan",
|
|
46
46
|
"mdCodeBlock": "green",
|
|
47
47
|
"mdCodeBlockBorder": "muted",
|
|
48
48
|
"mdQuote": "muted",
|
|
49
49
|
"mdQuoteBorder": "muted",
|
|
50
50
|
"mdHr": "muted",
|
|
51
|
-
"mdListBullet": "
|
|
51
|
+
"mdListBullet": "cyan",
|
|
52
52
|
"toolDiffAdded": "green",
|
|
53
53
|
"toolDiffRemoved": "red",
|
|
54
54
|
"toolDiffContext": "muted",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"syntaxVariable": "okhsl(202 58% 67%)",
|
|
59
59
|
"syntaxString": "okhsl(52 67% 67%)",
|
|
60
60
|
"syntaxNumber": "green",
|
|
61
|
-
"syntaxType": "
|
|
61
|
+
"syntaxType": "cyan",
|
|
62
62
|
"syntaxOperator": "muted",
|
|
63
63
|
"syntaxPunctuation": "muted",
|
|
64
64
|
"thinkingOff": "okhsl(229 8% 49%)",
|
|
65
65
|
"thinkingMinimal": "okhsl(232 20% 52%)",
|
|
66
66
|
"thinkingLow": "okhsl(232 45% 54%)",
|
|
67
67
|
"thinkingMedium": "okhsl(263 59% 56%)",
|
|
68
|
-
"thinkingHigh": "okhsl(
|
|
68
|
+
"thinkingHigh": "okhsl(188 73% 59%)",
|
|
69
69
|
"thinkingXhigh": "okhsl(337 81% 61%)",
|
|
70
70
|
"thinkingMax": "okhsl(20 99% 63%)",
|
|
71
71
|
"bashMode": "okhsl(159 64% 65%)"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"vars": {
|
|
6
6
|
"text": "okhsl(225 5% 27%)",
|
|
7
7
|
"muted": "okhsl(229 8% 47%)",
|
|
8
|
-
"
|
|
8
|
+
"cyan": "okhsl(188 80% 46%)",
|
|
9
9
|
"blue": "okhsl(231 68% 47%)",
|
|
10
10
|
"green": "okhsl(159 75% 46%)",
|
|
11
11
|
"red": "okhsl(20 91% 47%)",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"blueBg": "okhsl(235 19% 91%)"
|
|
14
14
|
},
|
|
15
15
|
"colors": {
|
|
16
|
-
"accent": "
|
|
16
|
+
"accent": "cyan",
|
|
17
17
|
"border": "okhsl(231 67% 55%)",
|
|
18
|
-
"borderAccent": "okhsl(
|
|
18
|
+
"borderAccent": "okhsl(188 75% 55%)",
|
|
19
19
|
"borderMuted": "okhsl(235 7% 66%)",
|
|
20
20
|
"success": "green",
|
|
21
21
|
"error": "red",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"searchMatchText": "muted",
|
|
32
32
|
"userMessageBg": "blueBg",
|
|
33
33
|
"userMessageText": "text",
|
|
34
|
-
"customMessageBg": "okhsl(
|
|
34
|
+
"customMessageBg": "okhsl(188 25% 91%)",
|
|
35
35
|
"customMessageText": "muted",
|
|
36
|
-
"customMessageLabel": "
|
|
36
|
+
"customMessageLabel": "cyan",
|
|
37
37
|
"toolPendingBg": "okhsl(248 3% 91%)",
|
|
38
38
|
"toolSuccessBg": "okhsl(156 21% 91%)",
|
|
39
39
|
"toolErrorBg": "okhsl(24 23% 91%)",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"mdHeading": "yellow",
|
|
43
43
|
"mdLink": "blue",
|
|
44
44
|
"mdLinkUrl": "muted",
|
|
45
|
-
"mdCode": "
|
|
45
|
+
"mdCode": "cyan",
|
|
46
46
|
"mdCodeBlock": "green",
|
|
47
47
|
"mdCodeBlockBorder": "muted",
|
|
48
48
|
"mdQuote": "muted",
|
|
49
49
|
"mdQuoteBorder": "muted",
|
|
50
50
|
"mdHr": "muted",
|
|
51
|
-
"mdListBullet": "
|
|
51
|
+
"mdListBullet": "cyan",
|
|
52
52
|
"toolDiffAdded": "green",
|
|
53
53
|
"toolDiffRemoved": "red",
|
|
54
54
|
"toolDiffContext": "muted",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"syntaxVariable": "okhsl(203 73% 46%)",
|
|
59
59
|
"syntaxString": "okhsl(52 84% 46%)",
|
|
60
60
|
"syntaxNumber": "green",
|
|
61
|
-
"syntaxType": "
|
|
61
|
+
"syntaxType": "cyan",
|
|
62
62
|
"syntaxOperator": "muted",
|
|
63
63
|
"syntaxPunctuation": "muted",
|
|
64
64
|
"thinkingOff": "okhsl(223 5% 80%)",
|
|
65
65
|
"thinkingMinimal": "okhsl(229 14% 78%)",
|
|
66
66
|
"thinkingLow": "okhsl(232 33% 76%)",
|
|
67
67
|
"thinkingMedium": "okhsl(264 48% 74%)",
|
|
68
|
-
"thinkingHigh": "okhsl(
|
|
68
|
+
"thinkingHigh": "okhsl(188 62% 72%)",
|
|
69
69
|
"thinkingXhigh": "okhsl(337 74% 70%)",
|
|
70
70
|
"thinkingMax": "okhsl(20 98% 68%)",
|
|
71
71
|
"bashMode": "okhsl(159 74% 55%)"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-theme.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/system-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAQN,KAAK,QAAQ,EAEb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAW,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnF,eAAO,MAAM,iBAAiB,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"system-theme.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/system-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAQN,KAAK,QAAQ,EAEb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAW,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnF,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAiV1C,MAAM,WAAW,gBAAgB;IAChC,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,wBAAwB;IACxB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACrB,+GAA+G;IAC/G,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gHAAgH;IAChH,cAAc,CAAC,EAAE,eAAe,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IACjC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC5C,0FAA0F;IAC1F,GAAG,EAAE,UAAU,EAAE,CAAC;IAClB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;CACxC;AAOD,iCAAiC;AACjC,wBAAgB,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAM/D;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,MAAM,CAItE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,QAAQ,GAAG,eAAe,CAe/F;AA+BD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CA0HpF"}
|
|
@@ -27,12 +27,13 @@ const FAMILIES = {
|
|
|
27
27
|
red: { hue: 20, saturation: { min: 0.1, max: 0.92 }, slot: 1 },
|
|
28
28
|
yellow: { hue: 82.36, saturation: { min: 0.5, max: 1 }, slot: 3 },
|
|
29
29
|
orange: { hue: 52, saturation: { min: 0.12, max: 0.85 }, slot: 3 },
|
|
30
|
-
|
|
30
|
+
// The brand cyan of the relay logo (relay-logo.ts).
|
|
31
|
+
cyan: { hue: 188, saturation: { min: 0.2, max: 0.75 }, slot: 6 },
|
|
31
32
|
calamine: { hue: 202.43, saturation: { min: 0.1, max: 0.74 }, slot: 6 },
|
|
32
33
|
thinkingSlate: { hue: 231.49, saturation: { min: 0.08, max: 0.2 }, slot: 4 },
|
|
33
34
|
thinkingBlue: { hue: 231.49, saturation: { min: 0.2, max: 0.45 }, slot: 4 },
|
|
34
35
|
thinkingPeriwinkle: { hue: 263.25, saturation: { min: 0.3, max: 0.6 }, slot: 6 },
|
|
35
|
-
|
|
36
|
+
thinkingCyan: { hue: 188, saturation: { min: 0.4, max: 0.75 }, slot: 6 },
|
|
36
37
|
thinkingMagenta: { hue: 337.5, saturation: { min: 0.5, max: 0.85 }, slot: 13 },
|
|
37
38
|
thinkingRed: { hue: 20, saturation: { min: 0.95, max: 1 }, slot: 1 },
|
|
38
39
|
};
|
|
@@ -40,7 +41,7 @@ const TOKEN_FAMILIES = {
|
|
|
40
41
|
selectedBg: "blue",
|
|
41
42
|
searchMatchBg: "orange",
|
|
42
43
|
userMessageBg: "blue",
|
|
43
|
-
customMessageBg: "
|
|
44
|
+
customMessageBg: "cyan",
|
|
44
45
|
toolPendingBg: "neutral",
|
|
45
46
|
toolSuccessBg: "green",
|
|
46
47
|
toolErrorBg: "red",
|
|
@@ -65,12 +66,12 @@ const TOKEN_FAMILIES = {
|
|
|
65
66
|
scrollbarThumb: "neutral",
|
|
66
67
|
searchMatchText: "neutral",
|
|
67
68
|
borderMuted: "neutral",
|
|
68
|
-
accent: "
|
|
69
|
-
borderAccent: "
|
|
70
|
-
customMessageLabel: "
|
|
71
|
-
mdCode: "
|
|
72
|
-
mdListBullet: "
|
|
73
|
-
syntaxType: "
|
|
69
|
+
accent: "cyan",
|
|
70
|
+
borderAccent: "cyan",
|
|
71
|
+
customMessageLabel: "cyan",
|
|
72
|
+
mdCode: "cyan",
|
|
73
|
+
mdListBullet: "cyan",
|
|
74
|
+
syntaxType: "cyan",
|
|
74
75
|
border: "blue",
|
|
75
76
|
mdLink: "blue",
|
|
76
77
|
syntaxKeyword: "blue",
|
|
@@ -90,7 +91,7 @@ const TOKEN_FAMILIES = {
|
|
|
90
91
|
thinkingMinimal: "thinkingSlate",
|
|
91
92
|
thinkingLow: "thinkingBlue",
|
|
92
93
|
thinkingMedium: "thinkingPeriwinkle",
|
|
93
|
-
thinkingHigh: "
|
|
94
|
+
thinkingHigh: "thinkingCyan",
|
|
94
95
|
thinkingXhigh: "thinkingMagenta",
|
|
95
96
|
thinkingMax: "thinkingRed",
|
|
96
97
|
};
|