@agent-hubs/runtime-client
Advanced tools
+64
-8
@@ -9,2 +9,3 @@ #!/usr/bin/env node | ||
| import { detectCodexBinary, runLocalCodexTask, verifyCodexBinary } from "./lib/runtime.js"; | ||
| const RUNTIME_CLIENT_VERSION = "0.1.1"; | ||
| function parseArgs(argv) { | ||
@@ -112,2 +113,11 @@ if (argv[0] === "--help" || argv[0] === "-h") { | ||
| } | ||
| function isRecoverableRuntimeClientError(error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| return (message.includes("Runtime client not found") || | ||
| message.includes("fetch failed") || | ||
| message.includes("ECONNREFUSED") || | ||
| message.includes("ECONNRESET") || | ||
| message.includes("ETIMEDOUT") || | ||
| message.includes("EAI_AGAIN")); | ||
| } | ||
| async function run() { | ||
@@ -183,3 +193,3 @@ const parsed = parseArgs(process.argv.slice(2)); | ||
| const codexBin = verifyCodexBinary(detectCodexBinary()); | ||
| const registration = await registerRuntimeClient(gatewayUrl, provider, { | ||
| const registrationPayload = { | ||
| gatewayUrl, | ||
@@ -190,4 +200,27 @@ runtimeUserLabel, | ||
| codexBin, | ||
| clientVersion: "0.1.0" | ||
| }); | ||
| clientVersion: RUNTIME_CLIENT_VERSION | ||
| }; | ||
| let registration = await registerRuntimeClient(gatewayUrl, provider, registrationPayload); | ||
| let isRegistering = false; | ||
| let isWorking = false; | ||
| const reconnect = async (reason) => { | ||
| if (isRegistering) { | ||
| return; | ||
| } | ||
| isRegistering = true; | ||
| try { | ||
| registration = await registerRuntimeClient(gatewayUrl, provider, registrationPayload); | ||
| if (!json) { | ||
| process.stdout.write(`[reconnect] runtime client re-registered: ${registration.clientId} (${reason})\n`); | ||
| } | ||
| } | ||
| catch (error) { | ||
| if (!json) { | ||
| process.stderr.write(`[reconnect] ${error instanceof Error ? error.message : String(error)}\n`); | ||
| } | ||
| } | ||
| finally { | ||
| isRegistering = false; | ||
| } | ||
| }; | ||
| if (json) { | ||
@@ -222,10 +255,24 @@ printJson(registration); | ||
| process.stderr.write(`[heartbeat] ${error instanceof Error ? error.message : String(error)}\n`); | ||
| if (isRecoverableRuntimeClientError(error)) { | ||
| await reconnect("heartbeat failed"); | ||
| } | ||
| } | ||
| }; | ||
| const work = async () => { | ||
| const claimed = await claimRuntimeTask(gatewayUrl, provider, registration.clientId); | ||
| if (!claimed.task) { | ||
| if (isWorking || isRegistering) { | ||
| return; | ||
| } | ||
| isWorking = true; | ||
| let claimed = null; | ||
| try { | ||
| claimed = await claimRuntimeTask(gatewayUrl, provider, registration.clientId).catch(async (error) => { | ||
| if (isRecoverableRuntimeClientError(error)) { | ||
| await reconnect("task claim failed"); | ||
| return null; | ||
| } | ||
| throw error; | ||
| }); | ||
| if (!claimed?.task) { | ||
| return; | ||
| } | ||
| const result = await runLocalCodexTask({ | ||
@@ -249,5 +296,11 @@ codexBin, | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| await completeRuntimeTask(gatewayUrl, provider, registration.clientId, claimed.task.id, { | ||
| errorMessage: message | ||
| }).catch(() => null); | ||
| if (claimed?.task) { | ||
| await completeRuntimeTask(gatewayUrl, provider, registration.clientId, claimed.task.id, { | ||
| errorMessage: message | ||
| }).catch(async (completeError) => { | ||
| if (isRecoverableRuntimeClientError(completeError)) { | ||
| await reconnect("task result failed"); | ||
| } | ||
| }); | ||
| } | ||
| if (!json) { | ||
@@ -257,2 +310,5 @@ process.stderr.write(`[task] ${message}\n`); | ||
| } | ||
| finally { | ||
| isWorking = false; | ||
| } | ||
| }; | ||
@@ -259,0 +315,0 @@ await tick(); |
+1
-1
| { | ||
| "name": "@agent-hubs/runtime-client", | ||
| "private": false, | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "Agent Hub local runtime client for connecting local Codex CLI to a shared Gateway.", | ||
@@ -6,0 +6,0 @@ "type": "module", |
+36
-2
@@ -30,3 +30,3 @@ # @agent-hubs/runtime-client | ||
| 如果已发布到 npm registry: | ||
| 正式安装方式: | ||
@@ -37,5 +37,11 @@ ```bash | ||
| 如果使用本地 tarball: | ||
| 安装后验证: | ||
| ```bash | ||
| agent-runtime --help | ||
| ``` | ||
| 如果使用本地 tarball 调试: | ||
| ```bash | ||
| npm install -g agent-hubs-runtime-client-0.1.0.tgz | ||
@@ -100,2 +106,30 @@ ``` | ||
| ## 发布与升级 | ||
| 维护者发布新版本前先升级版本号: | ||
| ```bash | ||
| npm version patch --workspace @agent-hubs/runtime-client | ||
| ``` | ||
| 发布到 npm registry: | ||
| ```bash | ||
| npm publish --workspace @agent-hubs/runtime-client --access public --otp <6位验证码> | ||
| ``` | ||
| 发布成功后验证: | ||
| ```bash | ||
| npm view @agent-hubs/runtime-client version | ||
| npm install -g @agent-hubs/runtime-client | ||
| agent-runtime --help | ||
| ``` | ||
| 说明: | ||
| - `@agent-hubs/runtime-client` 是 npm 包名。 | ||
| - `agent-runtime` 是安装后提供的命令名。 | ||
| - 如果 npm 账号开启了发布 2FA,发布时需要传 `--otp`。 | ||
| ## 查看状态 | ||
@@ -102,0 +136,0 @@ |
32450
9.73%722
8.41%155
28.1%