@shgroup/dsh-serenity-hooks 1.20.0 → 1.20.1

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.20.0",
3
+ "version": "1.20.1",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/loop + 拦截缝机械约束(safe-mode/路径守卫)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。私有(dsh-external 组织)。",
6
6
  "engines": {
package/lib/client.js CHANGED
@@ -259,6 +259,7 @@ window.__ModuleLoader__.load({
259
259
  const { uploadImage, getDraftFiles, resendText } = props;
260
260
  const [state, setState] = (0, react.useState)("idle");
261
261
  const [paths, setPaths] = (0, react.useState)([]);
262
+ const [errorText, setErrorText] = (0, react.useState)(null);
262
263
  const handlingRef = (0, react.useRef)(false);
263
264
  const promptError = session?.promptError?.error;
264
265
  const imageIds = input?.imageIds ?? [];
@@ -273,7 +274,7 @@ window.__ModuleLoader__.load({
273
274
  const files = await getDraftFiles(String(sessionId), imageIds);
274
275
  if (files.length === 0) throw new Error("no draft image files");
275
276
  const saved = [];
276
- for (const file of files) saved.push(await uploadImage(file));
277
+ for (const file of files) saved.push(await uploadImage(file, String(sessionId)));
277
278
  const note = saved.map((p) => `用户提供了图片在 ${p}`).join("\n");
278
279
  const draft = input?.draft ?? "";
279
280
  const text = draft === "" ? note : `${draft}\n${note}`;
@@ -281,7 +282,9 @@ window.__ModuleLoader__.load({
281
282
  setPaths(saved);
282
283
  setState("done");
283
284
  } catch (err) {
284
- console.warn(`[serenity] image fallback failed: ${String(err?.message ?? err)}`);
285
+ const message = String(err?.message ?? err);
286
+ console.warn(`[serenity] image fallback failed: ${message}`);
287
+ setErrorText(message);
285
288
  setState("error");
286
289
  } finally {
287
290
  handlingRef.current = false;
@@ -310,10 +313,10 @@ window.__ModuleLoader__.load({
310
313
  "data-state": "done",
311
314
  children: paths.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: p }, p))
312
315
  });
313
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
316
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
314
317
  className: "serenity-image-fallback",
315
318
  "data-state": "error",
316
- children: "图片保存失败,请重试"
319
+ children: ["图片保存失败:", errorText ?? "未知错误"]
317
320
  });
318
321
  }
319
322
  //#endregion
@@ -330,8 +333,11 @@ window.__ModuleLoader__.load({
330
333
  return btoa(binary);
331
334
  });
332
335
  }
333
- /** 上传一张图片到 CCC _tmp/images_from_user/,返回相对路径(如 _tmp/images_from_user/xxx.png) */
334
- async function uploadImage(file) {
336
+ /**
337
+ * 上传一张图片到 CCC _tmp/images_from_user/,返回相对路径(如 _tmp/images_from_user/xxx.png)。
338
+ * sessionId 必传:node half 经会话 header.cwd 解析 CCC 根(进程 cwd 不可靠)。
339
+ */
340
+ async function uploadImage(file, sessionId) {
335
341
  const data = await fileToBase64(file);
336
342
  const res = await fetch(UPLOAD_PATH, {
337
343
  method: "POST",
@@ -340,6 +346,7 @@ window.__ModuleLoader__.load({
340
346
  "x-serenity-ui": "1"
341
347
  },
342
348
  body: JSON.stringify({
349
+ sessionId,
343
350
  mediaType: file.type,
344
351
  name: file.name,
345
352
  data
@@ -349,9 +356,13 @@ window.__ModuleLoader__.load({
349
356
  if (!res.ok || typeof body.path !== "string") throw new Error(`serenity image upload failed: ${body.error ?? res.status}`);
350
357
  return body.path;
351
358
  }
352
- /** 取 rail 图片的浏览器 File(conversation.draftImages,session-scoped;类型宽松访问——IConversation 类型面未含 draftImages) */
353
- async function getDraftFiles(ctx, sessionId, ids) {
354
- const draftImages = (ctx.sessions.scope(sessionId)?.conversation)?.draftImages;
359
+ /**
360
+ * rail 图片的浏览器 File。
361
+ * conversation.draftImages root singleton 的公开方法(读 controller 的 draftAttachments Map,
362
+ * 与调用 ctx 的作用域无关)——直接 ctx.get('conversation'),避开 scope 寻址不确定性。
363
+ */
364
+ async function getDraftFiles(ctx, _sessionId, ids) {
365
+ const draftImages = (ctx.get?.("conversation"))?.draftImages;
355
366
  if (draftImages === void 0) return [];
356
367
  return (draftImages(ids) ?? []).map((a) => a.file);
357
368
  }
@@ -388,7 +399,7 @@ window.__ModuleLoader__.load({
388
399
  id: "serenity-image-fallback",
389
400
  order: 100,
390
401
  inject: () => ({
391
- uploadImage: (file) => uploadImage(file),
402
+ uploadImage: (file, sessionId) => uploadImage(file, sessionId),
392
403
  getDraftFiles: (sessionId, ids) => getDraftFiles(scope, sessionId, ids),
393
404
  resendText: (sessionId, text) => resendText(scope, sessionId, text)
394
405
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.20.0",
3
+ "version": "1.20.1",
4
4
  "description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
5
5
  "license": "MIT",
6
6
  "repository": {