@clawos-dev/clawd 0.2.600 → 0.2.602

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 (2) hide show
  1. package/dist/cli.cjs +34 -10
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -53791,7 +53791,7 @@ function driveCodexThread(opts) {
53791
53791
  if (opts.skillsExtraRoots?.length) {
53792
53792
  void client.request("skills/extraRoots/set", { extraRoots: opts.skillsExtraRoots }).catch((e) => logger?.warn("codex skills/extraRoots/set failed", { message: e.message }));
53793
53793
  }
53794
- const threadParams = typeof opts.threadParams === "function" ? await opts.threadParams() : opts.threadParams;
53794
+ const threadParams = typeof opts.threadParams === "function" ? await opts.threadParams(client) : opts.threadParams;
53795
53795
  if (threadId) {
53796
53796
  await client.request("thread/resume", { threadId, ...threadParams });
53797
53797
  } else {
@@ -64380,6 +64380,7 @@ var CloudGatewayClient = class {
64380
64380
  * `toolSessionId`:调用方预分配的引擎会话 id(pi 的 --session-id;codex 的 thread id 是协议内的、不传),进 open 的 body `engineSessionId`
64381
64381
  * (契约 2026-09-18 §3.2)。`instructions`:会话级指令(pi-cloud 的连接 intro,工作目录写 CLOUD_WORKSPACE_SLOT),进 body `instructions`,
64382
64382
  * gateway 落成 Pod 里的 /run/agent/instructions.md(契约 §3.1);codex-cloud 不发(走协议内 developerInstructions)。
64383
+ * `expectedEngine` 是 session 创建时的引擎;gateway 在起 Pod 前与当前发布核对。
64383
64384
  */
64384
64385
  async openSession(personaId2, opts = {}) {
64385
64386
  const { apiKey, gatewayUrl } = await this.credentials();
@@ -64391,6 +64392,7 @@ var CloudGatewayClient = class {
64391
64392
  ...opts.toolSessionId ? { engineSessionId: opts.toolSessionId } : {},
64392
64393
  ...opts.instructions ? { instructions: opts.instructions } : {},
64393
64394
  ...opts.purpose ? { purpose: opts.purpose } : {},
64395
+ ...opts.expectedEngine ? { expectedEngine: opts.expectedEngine } : {},
64394
64396
  logger: this.deps.logger
64395
64397
  });
64396
64398
  }
@@ -64448,7 +64450,9 @@ function parseControlLine(line) {
64448
64450
  kind: "ready",
64449
64451
  session: typeof r2.session === "string" ? r2.session : "",
64450
64452
  personaDir: typeof r2.personaDir === "string" ? r2.personaDir : "",
64451
- workDir: typeof r2.workDir === "string" ? r2.workDir : ""
64453
+ workDir: typeof r2.workDir === "string" ? r2.workDir : "",
64454
+ ...typeof r2.model === "string" ? { model: r2.model } : {},
64455
+ ...typeof r2.engine === "string" ? { engine: r2.engine } : {}
64452
64456
  };
64453
64457
  case "error":
64454
64458
  return { kind: "error", message: typeof r2.message === "string" ? r2.message : "gateway error" };
@@ -64457,7 +64461,7 @@ function parseControlLine(line) {
64457
64461
  }
64458
64462
  }
64459
64463
  function openHttpLineStream(opts) {
64460
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, instructions, purpose, logger } = opts;
64464
+ const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, instructions, purpose, expectedEngine, logger } = opts;
64461
64465
  const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
64462
64466
  const ac = new AbortController();
64463
64467
  const lineCbs = [];
@@ -64525,7 +64529,7 @@ function openHttpLineStream(opts) {
64525
64529
  res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.session(personaId2), {
64526
64530
  method: "POST",
64527
64531
  headers,
64528
- body: JSON.stringify({ ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {} }),
64532
+ body: JSON.stringify({ ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {}, ...expectedEngine ? { expectedEngine } : {} }),
64529
64533
  signal: ac.signal
64530
64534
  });
64531
64535
  } catch (e) {
@@ -64539,6 +64543,7 @@ function openHttpLineStream(opts) {
64539
64543
  const body = await res.json();
64540
64544
  if (typeof body.message === "string") message = body.message;
64541
64545
  else if (typeof body.error === "string") message = body.error;
64546
+ if (body.error === "SESSION_VERSION_EXPIRED" && !message.includes("SESSION_VERSION_EXPIRED")) message = `SESSION_VERSION_EXPIRED: ${message}`;
64542
64547
  } catch {
64543
64548
  }
64544
64549
  emitControl({ kind: "error", message });
@@ -64579,6 +64584,14 @@ function openHttpLineStream(opts) {
64579
64584
  });
64580
64585
  break;
64581
64586
  }
64587
+ if (expectedEngine && control.engine !== expectedEngine) {
64588
+ emitControl({ kind: "error", message: control.engine ? `SESSION_VERSION_EXPIRED: \u5F53\u524D Pod \u662F ${control.engine}\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u9700\u8981 ${expectedEngine}` : "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 engine\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway" });
64589
+ stop = true;
64590
+ ac.abort();
64591
+ void reader.cancel().catch(() => {
64592
+ });
64593
+ break;
64594
+ }
64582
64595
  sessionId = control.session;
64583
64596
  flush();
64584
64597
  }
@@ -64643,7 +64656,7 @@ var import_node_fs38 = __toESM(require("fs"), 1);
64643
64656
  function cloudThreadParams(ctx, paths) {
64644
64657
  const { model: _model, ...base } = threadStartParams(ctx);
64645
64658
  const developerInstructions = ctx.titleOnly ? "\u53EA\u6839\u636E\u7528\u6237\u6D88\u606F\u8FD4\u56DE\u7B80\u77ED\u6807\u9898\u3002\u4E0D\u8981\u8C03\u7528\u5DE5\u5177\u3001\u8BFB\u53D6\u6587\u4EF6\u3001\u8BBF\u95EE\u7F51\u7EDC\u6216\u4FEE\u6539\u4EFB\u4F55\u5185\u5BB9\u3002" : [ctx.extraSystemPrompt, workDirPrompt(paths.workDir, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
64646
- return { ...base, cwd: paths.personaDir, approvalPolicy: "never", sandbox: ctx.titleOnly ? "read-only" : "danger-full-access", developerInstructions };
64659
+ return { ...base, ...paths.model ? { model: paths.model } : {}, cwd: paths.personaDir, approvalPolicy: "never", sandbox: ctx.titleOnly ? "read-only" : "danger-full-access", developerInstructions };
64647
64660
  }
64648
64661
  function deferredLineStream() {
64649
64662
  let target = null;
@@ -64722,7 +64735,18 @@ function createCloudCodexSession(ctx, sink, deps) {
64722
64735
  sink,
64723
64736
  stream,
64724
64737
  logger: deps.logger,
64725
- threadParams: () => paths.then((p3) => cloudThreadParams(ctx, p3)),
64738
+ threadParams: async (client) => {
64739
+ const p3 = await paths;
64740
+ const params = cloudThreadParams(ctx, p3);
64741
+ if (!ctx.toolSessionId || p3.model) return params;
64742
+ const config = await client.request("config/read", {});
64743
+ if (config?.config?.model) return { ...params, model: config.config.model };
64744
+ const list = await client.request("model/list", {});
64745
+ const selected = list?.data?.find((m3) => m3.isDefault);
64746
+ const current = selected?.id || selected?.model;
64747
+ if (!current) throw new Error("\u65E0\u6CD5\u786E\u5B9A\u5F53\u524D Codex \u9ED8\u8BA4\u6A21\u578B\uFF0C\u62D2\u7EDD\u6CBF\u7528\u65E7\u4F1A\u8BDD\u6A21\u578B");
64748
+ return { ...params, model: current };
64749
+ },
64726
64750
  imageInput: cloudImageInput(deps),
64727
64751
  // skills 在 Pod 里由 persona 目录自带,本机路径对它没意义
64728
64752
  // 「让对端走人」= 断开下行流,gateway 收到就删 Job;信号对 Pod 没有意义
@@ -64742,12 +64766,12 @@ function createCloudCodexSession(ctx, sink, deps) {
64742
64766
  });
64743
64767
  return driver.session;
64744
64768
  }
64745
- void (ctx.titleOnly ? deps.client.openSession(personaId2, { purpose: "title" }) : deps.client.openSession(personaId2)).then(
64769
+ void deps.client.openSession(personaId2, { expectedEngine: "codex", ...ctx.titleOnly ? { purpose: "title" } : {} }).then(
64746
64770
  (opened) => {
64747
64771
  channel = opened;
64748
64772
  channel.onControl((c2) => {
64749
64773
  if (c2.kind === "ready") {
64750
- resolvePaths({ personaDir: c2.personaDir, workDir: c2.workDir });
64774
+ resolvePaths({ personaDir: c2.personaDir, workDir: c2.workDir, model: c2.model });
64751
64775
  } else if (c2.kind === "queued") {
64752
64776
  sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
64753
64777
  } else if (c2.kind === "error") {
@@ -65474,7 +65498,7 @@ function createCloudPiSession(ctx, sink, deps) {
65474
65498
  });
65475
65499
  return driver.session;
65476
65500
  }
65477
- void deps.client.openSession(personaId2, { toolSessionId: sessionId, instructions: ctx.titleOnly ? "" : cloudPiInstructions(ctx), ...ctx.titleOnly ? { purpose: "title" } : {} }).then(
65501
+ void deps.client.openSession(personaId2, { toolSessionId: sessionId, instructions: ctx.titleOnly ? "" : cloudPiInstructions(ctx), expectedEngine: "pi", ...ctx.titleOnly ? { purpose: "title" } : {} }).then(
65478
65502
  (opened) => {
65479
65503
  channel = opened;
65480
65504
  channel.onControl((c2) => {
@@ -73068,7 +73092,7 @@ function computeMethodAccess(args) {
73068
73092
  }
73069
73093
 
73070
73094
  // src/version.ts
73071
- var version = "0.2.600".length > 0 ? "0.2.600" : "dev";
73095
+ var version = "0.2.602".length > 0 ? "0.2.602" : "dev";
73072
73096
 
73073
73097
  // src/cli-probe/probe.ts
73074
73098
  var fs83 = __toESM(require("fs"), 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.600",
3
+ "version": "0.2.602",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",