@fangyb/ahchat-bridge 0.1.32 → 0.1.33

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.
@@ -5440,6 +5440,21 @@ EXCEPTION \u2014 inner-voice envelope overrides no-reply:
5440
5440
  - In group chat, default to short. Long-form only when explicitly asked.
5441
5441
  - In 1:1 chat with the human, you may write longer answers when warranted.
5442
5442
 
5443
+ # Media generation replies
5444
+ - Official Seedream / Seedance MCP tools render visible AHChat media task cards.
5445
+ Let the card carry status, preview, download, copy, and regenerate actions.
5446
+ - Current media generation is one output per user request: one Seedream image or
5447
+ one Seedance video. Do not submit candidate batches, parallel tasks, or
5448
+ alternate versions in the same turn.
5449
+ - Do not print raw media URLs, request_id, task_id, polling logs, or repeated
5450
+ "let me check again" narration in the final reply unless the user explicitly
5451
+ asks for diagnostics.
5452
+ - For media submission or completion, write a short natural sentence only,
5453
+ such as "\u5DF2\u5F00\u59CB\u751F\u6210\uFF0C\u6211\u4F1A\u5728\u8FD9\u91CC\u66F4\u65B0\u7ED3\u679C\u3002" or "\u751F\u6210\u597D\u4E86\uFF0C\u53EF\u4EE5\u5728\u5361\u7247\u91CC\u67E5\u770B\u3002"
5454
+ - Do not use Bash, sleep loops, Monitor, curl polling, or background tasks just
5455
+ to wait for Seedream / Seedance. Seedream returns final images directly.
5456
+ Seedance is tracked by AHChat after one create_task call.
5457
+
5443
5458
  # Group chat \u2014 shared task board
5444
5459
  AHChat group conversations have a shared kanban board that is fed by structured
5445
5460
  task tools (TodoWrite when available; otherwise TaskCreate / TaskUpdate). Treat
@@ -5613,13 +5628,14 @@ list_available_skills \u67E5\u8BE2\u5F53\u524D Agent \u53EF\u76F4\u63A5\u4F7F\u7
5613
5628
  - \u5DF2\u51FA\u73B0\u5728 list_available_skills \u7684 assigned/local skill \u4E0D\u9700\u8981\u8BA9\u7528\u6237\u518D\u786E\u8BA4\u662F\u5426\u53EF\u7528\uFF1B\u4F46\u8BFB\u65E5\u5FD7\u3001\u8DD1\u547D\u4EE4\u3001\u5199\u6587\u4EF6\u3001\u53D1\u5E16\u3001\u8BFB\u5927\u91CF\u79C1\u5BC6\u4E0A\u4E0B\u6587\u7B49\u5177\u4F53\u9AD8\u98CE\u9669\u52A8\u4F5C\u6267\u884C\u524D\u5FC5\u987B\u8BF4\u660E\u539F\u56E0\u5E76\u9075\u5B88\u7528\u6237/\u7CFB\u7EDF\u6743\u9650\u8FB9\u754C\u3002
5614
5629
 
5615
5630
  # Cross-scope session isolation
5616
- \u6BCF\u4E2A scope\uFF08single / group\uFF09\u6709\u72EC\u7ACB\u7684 SDK Session / \u5DE5\u4F5C\u8BB0\u5FC6\uFF0C\u4F46\u540C\u4E00\u4E2A Agent \u7684\u6240\u6709 scope \u4F7F\u7528\u540C\u4E00\u4E2A\u5F53\u524D workdir\u3002
5617
- \u4F60\u5728 # Your scopes \u4E2D\u53EF\u4EE5\u770B\u5230\u6BCF\u4E2A scope \u5F53\u524D\u4F7F\u7528\u7684 workdir \u8DEF\u5F84\uFF1B\u6B63\u5E38\u60C5\u51B5\u4E0B\uFF0C\u540C\u4E00 Agent \u7684 single \u4E0E group scope \u8DEF\u5F84\u76F8\u540C\u3002
5631
+ \u6BCF\u4E2A scope\uFF08single / group\uFF09\u6709\u72EC\u7ACB\u7684 SDK Session / \u5DE5\u4F5C\u8BB0\u5FC6\uFF0Cworkdir \u4E5F\u6309 scope \u53D6\u4E0D\u540C\u6743\u5A01\u6765\u6E90\u3002
5632
+ \u4F60\u5728 # Your scopes \u4E2D\u53EF\u4EE5\u770B\u5230\u6BCF\u4E2A scope \u5F53\u524D\u4F7F\u7528\u7684 workdir \u8DEF\u5F84\u3002
5618
5633
 
5619
- - \u4F60\u53EF\u4EE5\u5728\u5F53\u524D workdir \u5185 Read/Glob/Grep/Write/Edit\uFF1B\u4E0D\u8981\u5047\u8BBE\u7FA4\u804A\u548C\u5355\u804A\u6709\u4E24\u4EFD\u4E92\u4E0D\u76F8\u901A\u7684\u6587\u4EF6\u533A\u3002
5620
- - \u5F53\u4F60\u5728\u7FA4 scope \u5B8C\u6210\u4E86\u6587\u4EF6\u4EA7\u51FA\uFF0C\u7528 neural_send \u628A\u6587\u4EF6\u8DEF\u5F84\u548C\u6458\u8981\u901A\u77E5\u4F60\u5728 single scope \u7684\u5206\u8EAB\uFF0C\u65B9\u4FBF\u7528\u6237\u5728\u5355\u804A\u4E2D\u67E5\u770B\u3002
5621
- - \u53CD\u8FC7\u6765\u4E5F\u4E00\u6837\uFF1A\u5355\u804A\u4EA7\u51FA\u540E\uFF0C\u7528 neural_send \u901A\u77E5\u76F8\u5173\u7FA4 scope\u3002
5622
- - neural_send \u7528\u6765\u540C\u6B65\u4E0A\u4E0B\u6587\u548C\u7ED3\u8BBA\uFF1B\u540C\u4E00 Agent \u8DE8 scope \u5171\u4EAB\u6587\u4EF6\u65F6\u901A\u5E38\u53EA\u9700\u8981\u4F20\u8DEF\u5F84\u548C\u6458\u8981\uFF0C\u4E0D\u9700\u8981\u590D\u5236\u6587\u4EF6\u3002
5634
+ - single workdir \u662F\u4F60\u7684\u79C1\u6709 Agent \u5DE5\u4F5C\u76EE\u5F55\uFF0C\u7528\u4E8E\u4F60\u548C\u7528\u6237\u7684 1:1 \u5355\u804A\u3002
5635
+ - group workdir \u662F\u8BE5\u7FA4\u7684\u5171\u4EAB\u5DE5\u4F5C\u76EE\u5F55\uFF1B\u5F53\u4F60\u5728\u8FD9\u4E2A\u7FA4 scope \u4E2D\u8FD0\u884C\u65F6\uFF0C\u5F53\u524D runtime cwd \u5C31\u662F\u8FD9\u4E2A\u7FA4\u76EE\u5F55\u3002
5636
+ - \u7528\u6237\u95EE\u201C\u4F60\u81EA\u5DF1\u7684\u5DE5\u4F5C\u76EE\u5F55\u201D\u548C\u201C\u8FD9\u4E2A\u7FA4\u804A\u5DE5\u4F5C\u76EE\u5F55\u201D\u65F6\uFF0C\u8981\u5206\u522B\u62A5\u544A single workdir \u548C\u5F53\u524D group workdir\uFF1B\u9664\u975E # Your scopes \u91CC\u4E24\u4E2A\u8DEF\u5F84\u5B57\u9762\u5B8C\u5168\u76F8\u540C\uFF0C\u4E0D\u8981\u8BF4\u5B83\u4EEC\u76F8\u540C\u3002
5637
+ - \u4F60\u53EA\u80FD\u5728\u5F53\u524D runtime cwd \u5185 Read/Glob/Grep/Write/Edit\uFF1B\u5728\u7FA4\u91CC\u4EA7\u51FA\u7684\u6587\u4EF6\u9ED8\u8BA4\u5C5E\u4E8E\u7FA4\u5171\u4EAB\u76EE\u5F55\u3002
5638
+ - \u8DE8 scope \u540C\u6B65\u4E0A\u4E0B\u6587\u548C\u7ED3\u8BBA\u7528 neural_send\uFF1B\u5982\u679C\u53E6\u4E00\u4E2A scope \u9700\u8981\u67E5\u770B\u6587\u4EF6\uFF0C\u4F20\u8DEF\u5F84\u548C\u6458\u8981\uFF0C\u4E0D\u8981\u5047\u88C5\u90A3\u4E2A scope \u7684 cwd \u81EA\u52A8\u76F8\u540C\u3002
5623
5639
 
5624
5640
  # Cross-scope awareness (Neural Send)
5625
5641
 
@@ -5818,11 +5834,121 @@ function createRequestId() {
5818
5834
  function isWSMessage(data) {
5819
5835
  return typeof data === "object" && data !== null && "type" in data && "payload" in data;
5820
5836
  }
5837
+ function isPlainRecord(value) {
5838
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
5839
+ const proto2 = Object.getPrototypeOf(value);
5840
+ return proto2 === Object.prototype || proto2 === null;
5841
+ }
5842
+ function invalidWsMessage(type, field) {
5843
+ return new Error(`Invalid WS message ${type} payload.${field}`);
5844
+ }
5845
+ function assertPayloadRecord(type, payload) {
5846
+ if (!isPlainRecord(payload)) {
5847
+ throw new Error(`Invalid WS message ${type} payload`);
5848
+ }
5849
+ }
5850
+ function assertStringPayloadField(type, payload, field) {
5851
+ if (typeof payload[field] !== "string") {
5852
+ throw invalidWsMessage(type, field);
5853
+ }
5854
+ }
5855
+ function assertNumberPayloadField(type, payload, field) {
5856
+ if (typeof payload[field] !== "number" || Number.isNaN(payload[field])) {
5857
+ throw invalidWsMessage(type, field);
5858
+ }
5859
+ }
5860
+ function assertArrayPayloadField(type, payload, field) {
5861
+ if (!Array.isArray(payload[field])) {
5862
+ throw invalidWsMessage(type, field);
5863
+ }
5864
+ }
5865
+ function assertRecordPayloadField(type, payload, field) {
5866
+ if (!isPlainRecord(payload[field])) {
5867
+ throw invalidWsMessage(type, field);
5868
+ }
5869
+ }
5870
+ function validateRequiredStrings(type, payload, fields) {
5871
+ for (const field of fields) assertStringPayloadField(type, payload, field);
5872
+ }
5873
+ function validateWSMessageShape(msg) {
5874
+ const type = msg.type;
5875
+ const payload = msg.payload;
5876
+ switch (type) {
5877
+ case "heartbeat": {
5878
+ assertPayloadRecord(type, payload);
5879
+ assertNumberPayloadField(type, payload, "ts");
5880
+ return;
5881
+ }
5882
+ case "client:hello": {
5883
+ assertPayloadRecord(type, payload);
5884
+ validateRequiredStrings(type, payload, ["sessionId", "platform", "version", "env", "traceId"]);
5885
+ return;
5886
+ }
5887
+ case "user:send_message": {
5888
+ assertPayloadRecord(type, payload);
5889
+ validateRequiredStrings(type, payload, ["id", "agentId", "conversationId", "content", "traceId"]);
5890
+ return;
5891
+ }
5892
+ case "user:group_message": {
5893
+ assertPayloadRecord(type, payload);
5894
+ validateRequiredStrings(type, payload, ["id", "groupId", "conversationId", "content", "traceId"]);
5895
+ assertArrayPayloadField(type, payload, "mentions");
5896
+ return;
5897
+ }
5898
+ case "agent:done": {
5899
+ assertPayloadRecord(type, payload);
5900
+ validateRequiredStrings(type, payload, [
5901
+ "ackId",
5902
+ "messageId",
5903
+ "agentId",
5904
+ "conversationId",
5905
+ "fullContent",
5906
+ "traceId"
5907
+ ]);
5908
+ assertArrayPayloadField(type, payload, "contentBlocks");
5909
+ assertRecordPayloadField(type, payload, "metadata");
5910
+ return;
5911
+ }
5912
+ case "agent:segment": {
5913
+ assertPayloadRecord(type, payload);
5914
+ validateRequiredStrings(type, payload, [
5915
+ "messageId",
5916
+ "ackId",
5917
+ "agentId",
5918
+ "conversationId",
5919
+ "groupId",
5920
+ "content",
5921
+ "traceId"
5922
+ ]);
5923
+ assertArrayPayloadField(type, payload, "contentBlocks");
5924
+ return;
5925
+ }
5926
+ case "agent:turn_complete": {
5927
+ assertPayloadRecord(type, payload);
5928
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "groupId", "traceId"]);
5929
+ assertNumberPayloadField(type, payload, "segmentCount");
5930
+ return;
5931
+ }
5932
+ case "agent:no_reply": {
5933
+ assertPayloadRecord(type, payload);
5934
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "traceId"]);
5935
+ return;
5936
+ }
5937
+ case "agent:error": {
5938
+ assertPayloadRecord(type, payload);
5939
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "error", "traceId"]);
5940
+ return;
5941
+ }
5942
+ default:
5943
+ return;
5944
+ }
5945
+ }
5821
5946
  function parseWSMessage(raw) {
5822
5947
  const parsed = JSON.parse(raw);
5823
5948
  if (!isWSMessage(parsed)) {
5824
5949
  throw new Error("Invalid WS message: missing type/payload");
5825
5950
  }
5951
+ validateWSMessageShape(parsed);
5826
5952
  return parsed;
5827
5953
  }
5828
5954
 
@@ -6133,6 +6259,106 @@ var OFFICIAL_OFFICE_SKILL_MARKDOWN = Object.fromEntries(
6133
6259
  // ../shared/src/officialSkills.ts
6134
6260
  init_cjs_shims();
6135
6261
 
6262
+ // ../shared/src/officialMediaSkills.ts
6263
+ init_cjs_shims();
6264
+ var OFFICIAL_MEDIA_SKILL_IDS = [
6265
+ "media-video-generation"
6266
+ ];
6267
+ var OFFICIAL_MEDIA_SKILLS = [
6268
+ {
6269
+ id: "media-video-generation",
6270
+ name: "\u89C6\u9891\u751F\u6210",
6271
+ summary: "\u5B98\u65B9 Seedance \u89C6\u9891\u751F\u6210\u6D41\u7A0B\u6280\u80FD\uFF1A\u628A\u89C6\u9891\u9700\u6C42\u8F6C\u6210\u7A33\u5B9A\u4EFB\u52A1\uFF0C\u6BCF\u6B21\u53EA\u63D0\u4EA4\u4E00\u4E2A\u89C6\u9891\u4EFB\u52A1\uFF0C\u5E76\u4EA4\u7ED9 AHChat \u5A92\u4F53\u4EFB\u52A1\u5361\u8DDF\u8E2A\u7ED3\u679C\u3002",
6272
+ sourceType: "official",
6273
+ trustLevel: "official",
6274
+ status: "team_approved",
6275
+ taskTypes: [
6276
+ "\u89C6\u9891\u751F\u6210",
6277
+ "\u89C6\u9891",
6278
+ "\u751F\u89C6\u9891",
6279
+ "AI \u89C6\u9891",
6280
+ "Seedance",
6281
+ "\u6587\u751F\u89C6\u9891",
6282
+ "\u56FE\u751F\u89C6\u9891",
6283
+ "\u77ED\u89C6\u9891",
6284
+ "video_generation",
6285
+ "media_generation"
6286
+ ],
6287
+ applicableRoles: [
6288
+ "video",
6289
+ "media",
6290
+ "creative",
6291
+ "designer",
6292
+ "\u5BFC\u6F14",
6293
+ "\u89C6\u9891",
6294
+ "\u751F\u89C6\u9891",
6295
+ "\u521B\u610F",
6296
+ "\u8BBE\u8BA1",
6297
+ "\u591A\u5A92\u4F53",
6298
+ "\u5185\u5BB9"
6299
+ ],
6300
+ applicableScopes: ["single", "group", "smith"],
6301
+ problem: "\u89C6\u9891\u751F\u6210\u662F\u957F\u8017\u65F6\u5916\u90E8\u4EFB\u52A1\u3002\u6CA1\u6709\u4E13\u95E8\u6D41\u7A0B\u65F6\uFF0CAgent \u5BB9\u6613\u7528 Bash\u3001sleep \u6216\u53CD\u590D\u67E5\u8BE2\u5236\u9020\u566A\u97F3\uFF0C\u5E76\u628A task_id\u3001\u7B7E\u540D URL \u548C\u8F6E\u8BE2\u65E5\u5FD7\u66B4\u9732\u7ED9\u7528\u6237\u3002",
6302
+ inputs: [
6303
+ { name: "videoGoal", description: "\u89C6\u9891\u4E3B\u9898\u3001\u4E3B\u4F53\u3001\u52A8\u4F5C\u3001\u98CE\u683C\u548C\u7528\u6237\u671F\u671B\u7684\u6548\u679C\u3002", required: true },
6304
+ { name: "duration", description: "\u671F\u671B\u65F6\u957F\uFF1B\u7528\u6237\u672A\u6307\u5B9A\u65F6\u4F7F\u7528 Seedance \u9ED8\u8BA4\u77ED\u89C6\u9891\u65F6\u957F\u3002" },
6305
+ { name: "format", description: "\u6BD4\u4F8B\u3001\u5206\u8FA8\u7387\u3001\u662F\u5426\u5FEB\u901F\u7248\u3001\u662F\u5426\u9700\u8981\u58F0\u97F3\u6216\u53C2\u8003\u56FE\u3002" }
6306
+ ],
6307
+ outputs: [
6308
+ { name: "mediaTask", description: "\u4E00\u5F20 AHChat \u5A92\u4F53\u4EFB\u52A1\u5361\uFF0C\u5C55\u793A\u751F\u6210\u4E2D\u3001\u5B8C\u6210\u3001\u5931\u8D25\u3001\u9884\u89C8\u3001\u4E0B\u8F7D\u548C\u518D\u6B21\u751F\u6210\u3002", required: true },
6309
+ { name: "shortReply", description: "\u4E00\u53E5\u81EA\u7136\u77ED\u56DE\u590D\uFF0C\u907F\u514D\u91CD\u590D\u89E3\u91CA\u5DE5\u5177\u7EC6\u8282\u3002" }
6310
+ ],
6311
+ steps: [
6312
+ "\u5148\u5224\u65AD\u9700\u6C42\u662F\u5426\u8DB3\u591F\u63D0\u4EA4\uFF1A\u4E3B\u4F53\u3001\u52A8\u4F5C\u3001\u573A\u666F\u548C\u98CE\u683C\u6E05\u695A\u65F6\u76F4\u63A5\u5F00\u59CB\uFF1B\u7F3A\u5173\u952E\u8981\u7D20\u65F6\u6700\u591A\u95EE\u4E00\u4E2A\u805A\u7126\u95EE\u9898\u3002",
6313
+ "\u628A\u9700\u6C42\u6574\u7406\u6210 Seedance prompt\uFF1B\u7528\u6237\u8BF4\u201C\u5FEB\u901F\u7248\u3001\u8D28\u91CF\u4E00\u822C\u3001\u5148\u770B\u770B\u201D\u65F6\u4F18\u5148\u9009\u62E9\u5FEB\u901F / \u8F83\u4F4E\u5206\u8FA8\u7387\u53C2\u6570\uFF0C\u7528\u6237\u660E\u786E\u8981\u9AD8\u8D28\u91CF\u65F6\u518D\u63D0\u9AD8\u53C2\u6570\u3002",
6314
+ "\u6BCF\u6B21\u7528\u6237\u8BF7\u6C42\u53EA\u751F\u6210 1 \u4E2A\u89C6\u9891\u3002\u5982\u679C\u7528\u6237\u8981\u6C42\u591A\u4E2A\u89C6\u9891\u3001\u591A\u4E2A\u7248\u672C\u6216\u5019\u9009\uFF0C\u5148\u8BF4\u660E\u5F53\u524D ALL-CAN \u6D41\u7A0B\u4E00\u6B21\u53EA\u751F\u6210\u4E00\u4E2A\u89C6\u9891\uFF0C\u5E76\u8BA9\u7528\u6237\u5148\u9009\u4E00\u4E2A\u65B9\u5411\u3002",
6315
+ "\u8C03\u7528 mcp__seedance__seedance_create_task \u4E00\u6B21\u63D0\u4EA4 1 \u4E2A\u4EFB\u52A1\u3002\u63D0\u4EA4\u540E\u505C\u6B62\u672C\u8F6E\u624B\u52A8\u7B49\u5F85\uFF0C\u4E0D\u8981\u5E76\u53D1\u63D0\u4EA4\u591A\u4E2A\u4EFB\u52A1\uFF0C\u4E5F\u4E0D\u8981\u7528 Bash\u3001sleep\u3001curl\u3001Monitor\u3001\u540E\u53F0\u4EFB\u52A1\u6216\u5FAA\u73AF\u67E5\u8BE2\u6765\u7B49\u7ED3\u679C\u3002",
6316
+ "\u63D0\u4EA4\u6210\u529F\u540E\u53EA\u56DE\u590D\u4E00\u53E5\u81EA\u7136\u8BDD\u672F\uFF0C\u4F8B\u5982\u201C\u5DF2\u5F00\u59CB\u751F\u6210\uFF0C\u6211\u4F1A\u5728\u8FD9\u91CC\u66F4\u65B0\u7ED3\u679C\u3002\u201D\uFF1B\u8BA9 AHChat \u5A92\u4F53\u4EFB\u52A1\u5361\u5C55\u793A\u7B49\u5F85\u72B6\u6001\u3001\u8017\u65F6\u548C\u53C2\u6570\u3002",
6317
+ "\u7528\u6237\u4E3B\u52A8\u95EE\u201C\u597D\u4E86\u6CA1 / \u8FDB\u5EA6\u600E\u6837\u201D\u65F6\uFF0C\u6700\u591A\u8C03\u7528\u4E00\u6B21 mcp__seedance__seedance_check_task\uFF0C\u5E76\u6839\u636E\u7ED3\u679C\u7B80\u77ED\u56DE\u7B54\uFF1B\u4E0D\u8981\u5FAA\u73AF\u8F6E\u8BE2\u3002",
6318
+ "\u4EFB\u52A1\u5B8C\u6210\u540E\u53EA\u56DE\u590D\u4E00\u53E5\u81EA\u7136\u8BDD\u672F\uFF0C\u4F8B\u5982\u201C\u751F\u6210\u597D\u4E86\uFF0C\u53EF\u4EE5\u5728\u5361\u7247\u91CC\u67E5\u770B\u3002\u201D\uFF1B\u9884\u89C8\u3001\u4E0B\u8F7D\u3001\u590D\u5236\u94FE\u63A5\u548C\u518D\u6B21\u751F\u6210\u7531\u5A92\u4F53\u4EFB\u52A1\u5361\u627F\u8F7D\u3002"
6319
+ ],
6320
+ successCriteria: [
6321
+ "\u804A\u5929\u4E2D\u53EA\u51FA\u73B0\u4E00\u5F20\u6301\u7EED\u66F4\u65B0\u7684\u5A92\u4F53\u4EFB\u52A1\u5361\u548C\u4E00\u4E2A\u89C6\u9891\u7ED3\u679C\uFF0C\u4E0D\u51FA\u73B0\u591A\u4E2A\u5019\u9009\u4EFB\u52A1\u3001\u591A\u6BB5 Bash\u3001sleep\u3001curl \u6216\u91CD\u590D check_task \u65E5\u5FD7\u3002",
6322
+ "\u4E0D\u4F1A\u5411\u7528\u6237\u66B4\u9732 raw task_id\u3001request_id\u3001\u957F\u7B7E\u540D URL \u6216\u8F6E\u8BE2\u8FC7\u7A0B\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u8BCA\u65AD\u3002",
6323
+ "Agent \u7684\u6587\u672C\u56DE\u590D\u77ED\u800C\u81EA\u7136\uFF0C\u751F\u6210\u72B6\u6001\u3001\u53C2\u6570\u3001\u9884\u89C8\u548C\u64CD\u4F5C\u90FD\u7531\u5A92\u4F53\u5361\u5C55\u793A\u3002",
6324
+ "\u751F\u6210\u5931\u8D25\u3001\u989D\u5EA6\u4E0D\u8DB3\u6216\u914D\u7F6E\u7F3A\u5931\u65F6\u8BF4\u660E\u53EF\u7406\u89E3\u539F\u56E0\uFF0C\u5E76\u505C\u6B62\u91CD\u8BD5\u5FAA\u73AF\u3002"
6325
+ ],
6326
+ limitations: [
6327
+ "\u4F9D\u8D56\u5B98\u65B9 Seedance MCP \u5DF2\u542F\u7528\u3001\u516C\u53F8 Ark Key \u5DF2\u914D\u7F6E\u4E14\u6BCF\u65E5\u989D\u5EA6\u672A\u8017\u5C3D\u3002",
6328
+ "\u89C6\u9891\u751F\u6210\u4F1A\u6D88\u8017\u516C\u53F8\u5A92\u4F53\u989D\u5EA6\uFF1B\u5177\u4F53\u63D0\u4EA4\u8C03\u7528\u7531 MCP \u6743\u9650\u3001\u6BCF\u65E5\u9650\u989D\u548C\u5BA1\u8BA1\u7CFB\u7EDF\u63A7\u5236\u3002",
6329
+ "\u7B7E\u540D\u5A92\u4F53 URL \u53EF\u80FD\u8FC7\u671F\uFF0C\u5E94\u63D0\u793A\u7528\u6237\u53CA\u65F6\u5728\u5361\u7247\u91CC\u9884\u89C8\u6216\u4E0B\u8F7D\uFF0C\u4F46\u4E0D\u8981\u76F4\u63A5\u7C98\u8D34\u957F URL\u3002",
6330
+ "\u8BE5\u6280\u80FD\u53EA\u89C4\u8303\u89C6\u9891\u751F\u6210\u6D41\u7A0B\uFF0C\u4E0D\u8D1F\u8D23\u7F16\u8F91\u672C\u5730\u89C6\u9891\u6587\u4EF6\u6216\u957F\u671F\u540E\u53F0\u901A\u77E5\u3002"
6331
+ ],
6332
+ permissions: {
6333
+ readsProjectFiles: false,
6334
+ readsLogs: false,
6335
+ readsConversationContext: true,
6336
+ canRunBash: false,
6337
+ canWriteFiles: false,
6338
+ canPostToForum: false,
6339
+ permissionLevel: "medium"
6340
+ },
6341
+ sourceEvidence: {
6342
+ feedPostIds: [],
6343
+ feedCategories: [],
6344
+ groupIds: [],
6345
+ taskIds: [],
6346
+ contributingAgentIds: [],
6347
+ successExamples: [
6348
+ "ProductCore \u5A92\u4F53\u4EFB\u52A1\u72B6\u6001\u67B6\u6784\uFF1ASeedance \u957F\u4EFB\u52A1\u7531 AHChat \u5A92\u4F53\u4EFB\u52A1\u5361\u8DDF\u8E2A\uFF0C\u800C\u4E0D\u662F\u9760 Agent \u624B\u52A8\u8F6E\u8BE2\u3002",
6349
+ "\u5B98\u65B9 Seedance MCP\uFF1Amcp__seedance__seedance_create_task / mcp__seedance__seedance_check_task\u3002"
6350
+ ],
6351
+ failureExamples: [
6352
+ "Agent \u7528 Bash sleep \u6216\u5FAA\u73AF check_task \u7B49\u5F85\u89C6\u9891\uFF0C\u5BFC\u81F4\u804A\u5929\u91CC\u51FA\u73B0\u5927\u91CF\u65E0\u610F\u4E49\u5DE5\u5177\u8C03\u7528\u3002",
6353
+ "Agent \u628A task_id\u3001\u957F\u7B7E\u540D URL \u548C\u8F6E\u8BE2\u65E5\u5FD7\u4F5C\u4E3A\u6B63\u6587\u8F93\u51FA\uFF0C\u7834\u574F\u5FAE\u4FE1\u5F0F\u804A\u5929\u4F53\u9A8C\u3002"
6354
+ ]
6355
+ },
6356
+ installScope: "team",
6357
+ version: "1.0.0",
6358
+ createdBy: "system"
6359
+ }
6360
+ ];
6361
+
6136
6362
  // ../shared/src/officialWazaSkills.ts
6137
6363
  init_cjs_shims();
6138
6364
  var WAZA_VERSION = "3.28.0";
@@ -6453,11 +6679,13 @@ var OFFICIAL_WAZA_SKILLS = [
6453
6679
  // ../shared/src/officialSkills.ts
6454
6680
  var OFFICIAL_SKILL_IDS = [
6455
6681
  ...OFFICIAL_OFFICE_SKILL_IDS,
6456
- ...OFFICIAL_WAZA_SKILL_IDS
6682
+ ...OFFICIAL_WAZA_SKILL_IDS,
6683
+ ...OFFICIAL_MEDIA_SKILL_IDS
6457
6684
  ];
6458
6685
  var OFFICIAL_SKILLS = [
6459
6686
  ...OFFICIAL_OFFICE_SKILLS,
6460
- ...OFFICIAL_WAZA_SKILLS
6687
+ ...OFFICIAL_WAZA_SKILLS,
6688
+ ...OFFICIAL_MEDIA_SKILLS
6461
6689
  ];
6462
6690
  function renderOfficialSkillMarkdown(skill) {
6463
6691
  return renderSkillManifestMarkdown(skill, { cacheSource: "shared-official" });
@@ -6573,6 +6801,12 @@ init_cjs_shims();
6573
6801
  // ../shared/src/utils/serverUrl.ts
6574
6802
  init_cjs_shims();
6575
6803
 
6804
+ // ../shared/src/utils/mediaPreviewHtml.ts
6805
+ init_cjs_shims();
6806
+
6807
+ // ../shared/src/utils/bridgeLocality.ts
6808
+ init_cjs_shims();
6809
+
6576
6810
  // ../shared/src/utils/mcp.ts
6577
6811
  init_cjs_shims();
6578
6812
  var OFFICIAL_MCP_SERVER_NAMES = [
@@ -6619,6 +6853,60 @@ var readpageScrapeTool = {
6619
6853
  enabled: true,
6620
6854
  permissionPolicy: "always_allow"
6621
6855
  };
6856
+ var seedreamGenerateImageTool = {
6857
+ name: "generate_image",
6858
+ displayName: "Seedream \u751F\u56FE",
6859
+ description: "\u4F7F\u7528\u706B\u5C71\u65B9\u821F Seedream \u751F\u6210\u5355\u5F20\u56FE\u7247\uFF0C\u652F\u6301\u6587\u672C\u751F\u56FE\u4E0E\u53C2\u8003\u56FE\u751F\u56FE\uFF0C\u4F1A\u4EA7\u751F\u516C\u53F8 Ark \u8D26\u53F7\u7528\u91CF\u3002",
6860
+ category: "media",
6861
+ riskLevel: "medium",
6862
+ enabled: true,
6863
+ permissionPolicy: "always_ask"
6864
+ };
6865
+ var seedreamEditImageTool = {
6866
+ name: "edit_image",
6867
+ displayName: "Seedream \u6539\u56FE",
6868
+ description: "\u4F7F\u7528\u706B\u5C71\u65B9\u821F Seedream \u6839\u636E\u53C2\u8003\u56FE\u548C\u63D0\u793A\u8BCD\u7F16\u8F91\u6216\u91CD\u7ED8\u5355\u5F20\u56FE\u7247\uFF0C\u4F1A\u4EA7\u751F\u516C\u53F8 Ark \u8D26\u53F7\u7528\u91CF\u3002",
6869
+ category: "media",
6870
+ riskLevel: "medium",
6871
+ enabled: true,
6872
+ permissionPolicy: "always_ask"
6873
+ };
6874
+ var seedreamGenerateImageGroupTool = {
6875
+ name: "generate_image_group",
6876
+ displayName: "Seedream \u5355\u56FE",
6877
+ description: "\u517C\u5BB9\u65E7\u540D\u79F0\u7684 Seedream \u5355\u56FE\u751F\u6210\u5DE5\u5177\uFF0C\u4F1A\u4EA7\u751F\u516C\u53F8 Ark \u8D26\u53F7\u7528\u91CF\u3002\u5F53\u524D\u6BCF\u6B21\u8BF7\u6C42\u53EA\u751F\u6210 1 \u5F20\u56FE\u7247\u3002",
6878
+ category: "media",
6879
+ riskLevel: "medium",
6880
+ enabled: true,
6881
+ permissionPolicy: "always_ask"
6882
+ };
6883
+ var seedanceUsageGuideTool = {
6884
+ name: "seedance_usage_guide",
6885
+ displayName: "Seedance \u4F7F\u7528\u8BF4\u660E",
6886
+ description: "\u67E5\u770B Seedance \u89C6\u9891\u751F\u6210\u6D41\u7A0B\u4E0E\u53C2\u6570\u8BF4\u660E\uFF0C\u4E0D\u521B\u5EFA\u65B0\u7684\u751F\u6210\u4EFB\u52A1\u3002",
6887
+ category: "media",
6888
+ riskLevel: "low",
6889
+ enabled: true,
6890
+ permissionPolicy: "always_allow"
6891
+ };
6892
+ var seedanceCreateTaskTool = {
6893
+ name: "seedance_create_task",
6894
+ displayName: "Seedance \u751F\u89C6\u9891",
6895
+ description: "\u4F7F\u7528\u706B\u5C71\u65B9\u821F Seedance \u521B\u5EFA\u5355\u4E2A\u89C6\u9891\u751F\u6210\u4EFB\u52A1\uFF0C\u4F1A\u4EA7\u751F\u516C\u53F8 Ark \u8D26\u53F7\u7528\u91CF\u3002\u5F53\u524D\u6BCF\u6B21\u8BF7\u6C42\u53EA\u751F\u6210 1 \u4E2A\u89C6\u9891\u3002",
6896
+ category: "media",
6897
+ riskLevel: "high",
6898
+ enabled: true,
6899
+ permissionPolicy: "always_ask"
6900
+ };
6901
+ var seedanceCheckTaskTool = {
6902
+ name: "seedance_check_task",
6903
+ displayName: "Seedance \u67E5\u7ED3\u679C",
6904
+ description: "\u67E5\u8BE2 Seedance \u89C6\u9891\u751F\u6210\u4EFB\u52A1\u72B6\u6001\u4E0E\u89C6\u9891 URL\uFF0C\u4E0D\u521B\u5EFA\u65B0\u7684\u751F\u6210\u4EFB\u52A1\u3002",
6905
+ category: "media",
6906
+ riskLevel: "low",
6907
+ enabled: true,
6908
+ permissionPolicy: "always_allow"
6909
+ };
6622
6910
  var context7ResolveLibraryTool = {
6623
6911
  name: "resolve-library-id",
6624
6912
  displayName: "\u89E3\u6790\u6587\u6863\u5E93",
@@ -6925,8 +7213,56 @@ var ALIYUN_IQS_MCP_PROVIDERS = [
6925
7213
  tools: [readpageBasicTool, readpageScrapeTool]
6926
7214
  }
6927
7215
  ];
7216
+ var VOLCENGINE_SEEDREAM_MCP_PROVIDER = {
7217
+ providerId: "volcengine_seedream",
7218
+ name: "Volcengine Seedream",
7219
+ summary: "\u706B\u5C71\u65B9\u821F Seedream \u56FE\u7247\u751F\u6210/\u7F16\u8F91 MCP\uFF0C\u4F7F\u7528\u516C\u53F8\u7EDF\u4E00 Ark Key\uFF0C\u5E76\u8FDB\u5165 AHChat \u8C03\u7528\u5BA1\u8BA1\u3002",
7220
+ serverName: "seedream",
7221
+ transport: "stdio",
7222
+ url: null,
7223
+ command: "ahchat-builtin",
7224
+ args: ["seedream-mcp"],
7225
+ env: {
7226
+ ARK_API_KEY: "",
7227
+ ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
7228
+ },
7229
+ authType: "x_api_key",
7230
+ customHeaders: [],
7231
+ enabled: true,
7232
+ alwaysLoad: true,
7233
+ tools: [
7234
+ seedreamGenerateImageTool,
7235
+ seedreamEditImageTool,
7236
+ seedreamGenerateImageGroupTool
7237
+ ]
7238
+ };
7239
+ var VOLCENGINE_SEEDANCE_MCP_PROVIDER = {
7240
+ providerId: "volcengine_seedance",
7241
+ name: "Volcengine Seedance",
7242
+ summary: "\u706B\u5C71\u65B9\u821F Seedance \u89C6\u9891\u751F\u6210 MCP\uFF0C\u4F7F\u7528\u516C\u53F8\u7EDF\u4E00 Ark Key\uFF0C\u5E76\u8FDB\u5165 AHChat \u8C03\u7528\u5BA1\u8BA1\u3002",
7243
+ serverName: "seedance",
7244
+ transport: "stdio",
7245
+ url: null,
7246
+ command: "ahchat-builtin",
7247
+ args: ["seedance-mcp"],
7248
+ env: {
7249
+ ARK_API_KEY: "",
7250
+ ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
7251
+ },
7252
+ authType: "x_api_key",
7253
+ customHeaders: [],
7254
+ enabled: true,
7255
+ alwaysLoad: true,
7256
+ tools: [
7257
+ seedanceUsageGuideTool,
7258
+ seedanceCreateTaskTool,
7259
+ seedanceCheckTaskTool
7260
+ ]
7261
+ };
6928
7262
  var OFFICIAL_MCP_PROVIDERS = [
6929
- ...ALIYUN_IQS_MCP_PROVIDERS
7263
+ ...ALIYUN_IQS_MCP_PROVIDERS,
7264
+ VOLCENGINE_SEEDANCE_MCP_PROVIDER,
7265
+ VOLCENGINE_SEEDREAM_MCP_PROVIDER
6930
7266
  ];
6931
7267
  var MCP_STORE_PROVIDERS = [
6932
7268
  {
@@ -7129,6 +7465,18 @@ var wsMetrics = new WsMetrics();
7129
7465
  var logger2 = createModuleLogger("ws.connector");
7130
7466
  var WATCHDOG_INTERVAL_MS = 15e3;
7131
7467
  var STALE_THRESHOLD_MS = WS_HEARTBEAT_INTERVAL_MS * 2 + 15e3;
7468
+ function localNetworkAddresses() {
7469
+ const out = /* @__PURE__ */ new Set();
7470
+ for (const entries of Object.values(import_node_os4.default.networkInterfaces())) {
7471
+ for (const entry of entries ?? []) {
7472
+ if (entry.internal) continue;
7473
+ const address = entry.address.trim();
7474
+ if (!address) continue;
7475
+ out.add(address.toLowerCase());
7476
+ }
7477
+ }
7478
+ return [...out].sort();
7479
+ }
7132
7480
  var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
7133
7481
  "agent:segment",
7134
7482
  "agent:turn_complete",
@@ -7141,7 +7489,8 @@ var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
7141
7489
  "ask_question_updated",
7142
7490
  "artifact:created",
7143
7491
  "agent:todos_update",
7144
- "feedback:analysis_result"
7492
+ "feedback:analysis_result",
7493
+ "bridge:resume_reply_session_response"
7145
7494
  ]);
7146
7495
  var OUTBOX_MAX_ENTRIES = 300;
7147
7496
  function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
@@ -7151,6 +7500,24 @@ function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
7151
7500
  url.searchParams.set("token", token);
7152
7501
  return url.toString();
7153
7502
  }
7503
+ function bridgeResumeUnsupportedResponse(payload) {
7504
+ return {
7505
+ type: "bridge:resume_reply_session_response",
7506
+ payload: {
7507
+ requestId: payload.requestId,
7508
+ replySessionId: payload.replySessionId,
7509
+ replyMessageId: payload.replyMessageId,
7510
+ agentId: payload.agentId,
7511
+ conversationId: payload.conversationId,
7512
+ canResume: false,
7513
+ currentStatus: "paused",
7514
+ recoverability: "retryable",
7515
+ reason: "bridge_resume_not_supported",
7516
+ traceId: payload.traceId,
7517
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7518
+ }
7519
+ };
7520
+ }
7154
7521
  var ServerConnector = class {
7155
7522
  ws = null;
7156
7523
  reconnectAttempts = 0;
@@ -7168,6 +7535,7 @@ var ServerConnector = class {
7168
7535
  onTaskDispatch;
7169
7536
  onGroupTaskDispatch;
7170
7537
  onStopGeneration;
7538
+ onResumeReplySession;
7171
7539
  onConnected;
7172
7540
  onRegistered;
7173
7541
  onServerPush;
@@ -7182,6 +7550,7 @@ var ServerConnector = class {
7182
7550
  this.onTaskDispatch = params.onTaskDispatch;
7183
7551
  this.onGroupTaskDispatch = params.onGroupTaskDispatch;
7184
7552
  this.onStopGeneration = params.onStopGeneration;
7553
+ this.onResumeReplySession = params.onResumeReplySession;
7185
7554
  this.onConnected = params.onConnected;
7186
7555
  this.onRegistered = params.onRegistered;
7187
7556
  this.onServerPush = params.onServerPush;
@@ -7258,6 +7627,7 @@ var ServerConnector = class {
7258
7627
  bridgeId: this.config.bridgeId,
7259
7628
  agents: ids,
7260
7629
  hostname: import_node_os4.default.hostname(),
7630
+ localAddresses: localNetworkAddresses(),
7261
7631
  runtimes: Object.keys(runtimes).length > 0 ? runtimes : void 0,
7262
7632
  queryConfig: {
7263
7633
  maxActive: qc.maxActive,
@@ -7295,6 +7665,7 @@ var ServerConnector = class {
7295
7665
  agentId: payload.agentId,
7296
7666
  conversationId: payload.conversationId,
7297
7667
  requestId,
7668
+ dispatchKind: payload.dispatchKind ?? "normal",
7298
7669
  traceId: payload.traceId
7299
7670
  });
7300
7671
  void this.onTaskDispatch(payload).catch((err) => {
@@ -7335,6 +7706,31 @@ var ServerConnector = class {
7335
7706
  });
7336
7707
  return;
7337
7708
  }
7709
+ case "bridge:resume_reply_session_request": {
7710
+ logger2.info("bridge:resume_reply_session_request received", {
7711
+ requestId: msg.payload.requestId,
7712
+ replySessionId: msg.payload.replySessionId,
7713
+ agentId: msg.payload.agentId,
7714
+ conversationId: msg.payload.conversationId,
7715
+ lastTokenIndex: msg.payload.lastTokenIndex ?? null,
7716
+ traceId: msg.payload.traceId
7717
+ });
7718
+ if (!this.onResumeReplySession) {
7719
+ this.send(bridgeResumeUnsupportedResponse(msg.payload));
7720
+ return;
7721
+ }
7722
+ void Promise.resolve(this.onResumeReplySession(msg.payload)).then((response) => this.send(response)).catch((err) => {
7723
+ logger2.error("Failed to handle bridge resume request", {
7724
+ error: err,
7725
+ requestId: msg.payload.requestId,
7726
+ replySessionId: msg.payload.replySessionId,
7727
+ agentId: msg.payload.agentId,
7728
+ traceId: msg.payload.traceId
7729
+ });
7730
+ this.send(bridgeResumeUnsupportedResponse(msg.payload));
7731
+ });
7732
+ return;
7733
+ }
7338
7734
  case "session:terminated": {
7339
7735
  logger2.warn("Session terminated by server, exiting bridge process", {
7340
7736
  reason: msg.payload.reason
@@ -7593,6 +7989,10 @@ function localCodexRuntimeCapability(status) {
7593
7989
  message: status.message
7594
7990
  };
7595
7991
  }
7992
+ function normalizeAnalysisGuidance(guidance) {
7993
+ const trimmed = guidance?.trim();
7994
+ return trimmed ? trimmed : null;
7995
+ }
7596
7996
  function normalizeFeedbackText(text) {
7597
7997
  return text.trim().replace(/\s+/g, " ");
7598
7998
  }
@@ -7694,12 +8094,14 @@ function skippedResult(reason) {
7694
8094
  };
7695
8095
  }
7696
8096
  function buildFeedbackAnalysisPrompt(payload, options, attachments) {
8097
+ const guidance = normalizeAnalysisGuidance(payload.guidance);
7697
8098
  const feedbackJson = JSON.stringify({
7698
8099
  jobId: payload.jobId,
7699
8100
  feedbackId: payload.feedbackId,
7700
8101
  content: payload.content,
7701
8102
  type: payload.type,
7702
8103
  priority: payload.priority,
8104
+ guidance,
7703
8105
  attachments: payload.attachments,
7704
8106
  pageUrl: payload.pageUrl,
7705
8107
  userAgent: payload.userAgent,
@@ -7742,6 +8144,7 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
7742
8144
  - \u5982\u679C\u76EE\u6807\u673A\u5668\u4E0A\u7684\u5B9A\u65F6\u4EFB\u52A1\u6216\u670D\u52A1\u914D\u7F6E\u663E\u793A\u65E5\u5FD7\u76EE\u5F55\u4E0D\u540C\uFF0C\u4EE5\u5B9E\u9645\u914D\u7F6E\u4E3A\u51C6\u3002
7743
8145
  - \u53EA\u505A\u53EA\u8BFB\u67E5\u8BE2\uFF1B\u4E0D\u8981\u590D\u5236\u6570\u636E\u5E93\uFF1B\u53EF\u7528 ssh \u5230\u76EE\u6807\u673A\u5668\u540E\u901A\u8FC7 python3/sqlite3 \u67E5\u8BE2\u3002
7744
8146
  4. \u67E5\u5B8C\u65E5\u5FD7\u540E\uFF0C\u5728\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4E2D\u9605\u8BFB\u76F8\u5173\u4EE3\u7801\uFF0C\u7ED9\u51FA\u95EE\u9898\u539F\u56E0\u603B\u7ED3\u548C\u4FEE\u590D\u5EFA\u8BAE\u3002
8147
+ - \u5982\u679C\u201C\u7BA1\u7406\u5458\u8865\u5145\u8BF4\u660E\u201D\u4E0D\u4E3A\u7A7A\uFF0C\u5FC5\u987B\u4F18\u5148\u6309\u5B83\u6307\u5B9A\u7684\u65B9\u5411\u6392\u67E5\uFF1B\u5B83\u53EA\u80FD\u4F5C\u4E3A\u5206\u6790\u6307\u5BFC\uFF0C\u4E0D\u80FD\u8986\u76D6\u53CD\u9988\u539F\u6587\u3001\u65E5\u5FD7\u548C\u4EE3\u7801\u8BC1\u636E\u3002
7745
8148
  5. \u72B6\u6001\u89C4\u5219\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF1A
7746
8149
  - status=skipped\uFF1A\u4EC5\u7528\u4E8E\u65E0\u610F\u4E49\u53CD\u9988\u3002
7747
8150
  - status=completed\uFF1A\u5DF2\u7ECF\u5F62\u6210\u6709\u610F\u4E49\u7684\u95EE\u9898\u539F\u56E0\u3001\u8BC1\u636E\u6216\u4FEE\u590D\u5EFA\u8BAE\u3002\u5373\u4F7F\u65E5\u5FD7\u56E0\u6743\u9650\u3001\u7F51\u7EDC\u6216\u8DEF\u5F84\u95EE\u9898\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u53EA\u8981\u80FD\u7ED3\u5408\u4EE3\u7801\u7ED9\u51FA\u5224\u65AD\uFF0C\u4E5F\u5FC5\u987B\u7528 completed\uFF0C\u5E76\u5728 evidence \u91CC\u8BB0\u5F55\u65E5\u5FD7\u4E0D\u53EF\u8BFB\uFF0C\u964D\u4F4E confidence\u3002
@@ -7751,6 +8154,9 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
7751
8154
  \u53CD\u9988\uFF1A
7752
8155
  ${feedbackJson}
7753
8156
 
8157
+ \u7BA1\u7406\u5458\u8865\u5145\u8BF4\u660E\uFF1A
8158
+ ${guidance ?? "\uFF08\u65E0\uFF09"}
8159
+
7754
8160
  \u9644\u4EF6\u672C\u5730\u5316\u7ED3\u679C\uFF1A
7755
8161
  ${attachmentJson}
7756
8162
 
@@ -8027,9 +8433,13 @@ function withWorkerCodexDefaults(env2) {
8027
8433
  };
8028
8434
  }
8029
8435
  function sanitizeAttachmentFileName(fileName) {
8030
- const base = import_node_path6.default.basename(fileName).replace(/[<>:"/\\|?*\u0000-\u001f]/g, "_").replace(/[. ]+$/g, "").replace(/^\.+/, "_");
8436
+ const base = import_node_path6.default.basename(fileName).split("").map((char) => isUnsafeFileNameChar(char) ? "_" : char).join("").replace(/[. ]+$/g, "").replace(/^\.+/, "_");
8031
8437
  return base || `attachment-${Date.now().toString(36)}`;
8032
8438
  }
8439
+ function isUnsafeFileNameChar(char) {
8440
+ const code = char.charCodeAt(0);
8441
+ return code <= 31 || '<>:"/\\|?*'.includes(char);
8442
+ }
8033
8443
  function feedbackAttachmentDownloadUrl(target, attachment) {
8034
8444
  return `${target.serverApiUrl}/api/uploads/${encodeURIComponent(attachment.storageKey)}`;
8035
8445
  }