@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.
package/dist/cli.cjs CHANGED
@@ -94269,6 +94269,21 @@ EXCEPTION \u2014 inner-voice envelope overrides no-reply:
94269
94269
  - In group chat, default to short. Long-form only when explicitly asked.
94270
94270
  - In 1:1 chat with the human, you may write longer answers when warranted.
94271
94271
 
94272
+ # Media generation replies
94273
+ - Official Seedream / Seedance MCP tools render visible AHChat media task cards.
94274
+ Let the card carry status, preview, download, copy, and regenerate actions.
94275
+ - Current media generation is one output per user request: one Seedream image or
94276
+ one Seedance video. Do not submit candidate batches, parallel tasks, or
94277
+ alternate versions in the same turn.
94278
+ - Do not print raw media URLs, request_id, task_id, polling logs, or repeated
94279
+ "let me check again" narration in the final reply unless the user explicitly
94280
+ asks for diagnostics.
94281
+ - For media submission or completion, write a short natural sentence only,
94282
+ 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"
94283
+ - Do not use Bash, sleep loops, Monitor, curl polling, or background tasks just
94284
+ to wait for Seedream / Seedance. Seedream returns final images directly.
94285
+ Seedance is tracked by AHChat after one create_task call.
94286
+
94272
94287
  # Group chat \u2014 shared task board
94273
94288
  AHChat group conversations have a shared kanban board that is fed by structured
94274
94289
  task tools (TodoWrite when available; otherwise TaskCreate / TaskUpdate). Treat
@@ -94442,13 +94457,14 @@ list_available_skills \u67E5\u8BE2\u5F53\u524D Agent \u53EF\u76F4\u63A5\u4F7F\u7
94442
94457
  - \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
94443
94458
 
94444
94459
  # Cross-scope session isolation
94445
- \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
94446
- \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
94460
+ \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
94461
+ \u4F60\u5728 # Your scopes \u4E2D\u53EF\u4EE5\u770B\u5230\u6BCF\u4E2A scope \u5F53\u524D\u4F7F\u7528\u7684 workdir \u8DEF\u5F84\u3002
94447
94462
 
94448
- - \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
94449
- - \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
94450
- - \u53CD\u8FC7\u6765\u4E5F\u4E00\u6837\uFF1A\u5355\u804A\u4EA7\u51FA\u540E\uFF0C\u7528 neural_send \u901A\u77E5\u76F8\u5173\u7FA4 scope\u3002
94451
- - 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
94463
+ - 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
94464
+ - 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
94465
+ - \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
94466
+ - \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
94467
+ - \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
94452
94468
 
94453
94469
  # Cross-scope awareness (Neural Send)
94454
94470
 
@@ -94694,11 +94710,121 @@ function createMcpToolInvocationId() {
94694
94710
  function isWSMessage(data) {
94695
94711
  return typeof data === "object" && data !== null && "type" in data && "payload" in data;
94696
94712
  }
94713
+ function isPlainRecord(value) {
94714
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
94715
+ const proto2 = Object.getPrototypeOf(value);
94716
+ return proto2 === Object.prototype || proto2 === null;
94717
+ }
94718
+ function invalidWsMessage(type, field) {
94719
+ return new Error(`Invalid WS message ${type} payload.${field}`);
94720
+ }
94721
+ function assertPayloadRecord(type, payload) {
94722
+ if (!isPlainRecord(payload)) {
94723
+ throw new Error(`Invalid WS message ${type} payload`);
94724
+ }
94725
+ }
94726
+ function assertStringPayloadField(type, payload, field) {
94727
+ if (typeof payload[field] !== "string") {
94728
+ throw invalidWsMessage(type, field);
94729
+ }
94730
+ }
94731
+ function assertNumberPayloadField(type, payload, field) {
94732
+ if (typeof payload[field] !== "number" || Number.isNaN(payload[field])) {
94733
+ throw invalidWsMessage(type, field);
94734
+ }
94735
+ }
94736
+ function assertArrayPayloadField(type, payload, field) {
94737
+ if (!Array.isArray(payload[field])) {
94738
+ throw invalidWsMessage(type, field);
94739
+ }
94740
+ }
94741
+ function assertRecordPayloadField(type, payload, field) {
94742
+ if (!isPlainRecord(payload[field])) {
94743
+ throw invalidWsMessage(type, field);
94744
+ }
94745
+ }
94746
+ function validateRequiredStrings(type, payload, fields) {
94747
+ for (const field of fields) assertStringPayloadField(type, payload, field);
94748
+ }
94749
+ function validateWSMessageShape(msg) {
94750
+ const type = msg.type;
94751
+ const payload = msg.payload;
94752
+ switch (type) {
94753
+ case "heartbeat": {
94754
+ assertPayloadRecord(type, payload);
94755
+ assertNumberPayloadField(type, payload, "ts");
94756
+ return;
94757
+ }
94758
+ case "client:hello": {
94759
+ assertPayloadRecord(type, payload);
94760
+ validateRequiredStrings(type, payload, ["sessionId", "platform", "version", "env", "traceId"]);
94761
+ return;
94762
+ }
94763
+ case "user:send_message": {
94764
+ assertPayloadRecord(type, payload);
94765
+ validateRequiredStrings(type, payload, ["id", "agentId", "conversationId", "content", "traceId"]);
94766
+ return;
94767
+ }
94768
+ case "user:group_message": {
94769
+ assertPayloadRecord(type, payload);
94770
+ validateRequiredStrings(type, payload, ["id", "groupId", "conversationId", "content", "traceId"]);
94771
+ assertArrayPayloadField(type, payload, "mentions");
94772
+ return;
94773
+ }
94774
+ case "agent:done": {
94775
+ assertPayloadRecord(type, payload);
94776
+ validateRequiredStrings(type, payload, [
94777
+ "ackId",
94778
+ "messageId",
94779
+ "agentId",
94780
+ "conversationId",
94781
+ "fullContent",
94782
+ "traceId"
94783
+ ]);
94784
+ assertArrayPayloadField(type, payload, "contentBlocks");
94785
+ assertRecordPayloadField(type, payload, "metadata");
94786
+ return;
94787
+ }
94788
+ case "agent:segment": {
94789
+ assertPayloadRecord(type, payload);
94790
+ validateRequiredStrings(type, payload, [
94791
+ "messageId",
94792
+ "ackId",
94793
+ "agentId",
94794
+ "conversationId",
94795
+ "groupId",
94796
+ "content",
94797
+ "traceId"
94798
+ ]);
94799
+ assertArrayPayloadField(type, payload, "contentBlocks");
94800
+ return;
94801
+ }
94802
+ case "agent:turn_complete": {
94803
+ assertPayloadRecord(type, payload);
94804
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "groupId", "traceId"]);
94805
+ assertNumberPayloadField(type, payload, "segmentCount");
94806
+ return;
94807
+ }
94808
+ case "agent:no_reply": {
94809
+ assertPayloadRecord(type, payload);
94810
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "traceId"]);
94811
+ return;
94812
+ }
94813
+ case "agent:error": {
94814
+ assertPayloadRecord(type, payload);
94815
+ validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "error", "traceId"]);
94816
+ return;
94817
+ }
94818
+ default:
94819
+ return;
94820
+ }
94821
+ }
94697
94822
  function parseWSMessage(raw) {
94698
94823
  const parsed = JSON.parse(raw);
94699
94824
  if (!isWSMessage(parsed)) {
94700
94825
  throw new Error("Invalid WS message: missing type/payload");
94701
94826
  }
94827
+ validateWSMessageShape(parsed);
94702
94828
  return parsed;
94703
94829
  }
94704
94830
  function isAskUserQuestionToolName(toolName) {
@@ -94713,7 +94839,7 @@ var SLUG_MAX_LEN = 32;
94713
94839
  function slugifyForFs(name) {
94714
94840
  const trimmed = name.trim();
94715
94841
  if (!trimmed) return "unnamed";
94716
- const slug = trimmed.replace(/[^\w\u4e00-\u9fa5 \-]/gu, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
94842
+ const slug = trimmed.replace(/[^\w\u4e00-\u9fa5 -]/gu, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
94717
94843
  const base = slug.length > 0 ? slug : "unnamed";
94718
94844
  return base.length > SLUG_MAX_LEN ? base.slice(0, SLUG_MAX_LEN) : base;
94719
94845
  }
@@ -95237,6 +95363,106 @@ var OFFICIAL_OFFICE_SKILL_MARKDOWN = Object.fromEntries(
95237
95363
  // ../shared/src/officialSkills.ts
95238
95364
  init_cjs_shims();
95239
95365
 
95366
+ // ../shared/src/officialMediaSkills.ts
95367
+ init_cjs_shims();
95368
+ var OFFICIAL_MEDIA_SKILL_IDS = [
95369
+ "media-video-generation"
95370
+ ];
95371
+ var OFFICIAL_MEDIA_SKILLS = [
95372
+ {
95373
+ id: "media-video-generation",
95374
+ name: "\u89C6\u9891\u751F\u6210",
95375
+ 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",
95376
+ sourceType: "official",
95377
+ trustLevel: "official",
95378
+ status: "team_approved",
95379
+ taskTypes: [
95380
+ "\u89C6\u9891\u751F\u6210",
95381
+ "\u89C6\u9891",
95382
+ "\u751F\u89C6\u9891",
95383
+ "AI \u89C6\u9891",
95384
+ "Seedance",
95385
+ "\u6587\u751F\u89C6\u9891",
95386
+ "\u56FE\u751F\u89C6\u9891",
95387
+ "\u77ED\u89C6\u9891",
95388
+ "video_generation",
95389
+ "media_generation"
95390
+ ],
95391
+ applicableRoles: [
95392
+ "video",
95393
+ "media",
95394
+ "creative",
95395
+ "designer",
95396
+ "\u5BFC\u6F14",
95397
+ "\u89C6\u9891",
95398
+ "\u751F\u89C6\u9891",
95399
+ "\u521B\u610F",
95400
+ "\u8BBE\u8BA1",
95401
+ "\u591A\u5A92\u4F53",
95402
+ "\u5185\u5BB9"
95403
+ ],
95404
+ applicableScopes: ["single", "group", "smith"],
95405
+ 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",
95406
+ inputs: [
95407
+ { 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 },
95408
+ { 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" },
95409
+ { 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" }
95410
+ ],
95411
+ outputs: [
95412
+ { 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 },
95413
+ { name: "shortReply", description: "\u4E00\u53E5\u81EA\u7136\u77ED\u56DE\u590D\uFF0C\u907F\u514D\u91CD\u590D\u89E3\u91CA\u5DE5\u5177\u7EC6\u8282\u3002" }
95414
+ ],
95415
+ steps: [
95416
+ "\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",
95417
+ "\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",
95418
+ "\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",
95419
+ "\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",
95420
+ "\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",
95421
+ "\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",
95422
+ "\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"
95423
+ ],
95424
+ successCriteria: [
95425
+ "\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",
95426
+ "\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",
95427
+ "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",
95428
+ "\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"
95429
+ ],
95430
+ limitations: [
95431
+ "\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",
95432
+ "\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",
95433
+ "\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",
95434
+ "\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"
95435
+ ],
95436
+ permissions: {
95437
+ readsProjectFiles: false,
95438
+ readsLogs: false,
95439
+ readsConversationContext: true,
95440
+ canRunBash: false,
95441
+ canWriteFiles: false,
95442
+ canPostToForum: false,
95443
+ permissionLevel: "medium"
95444
+ },
95445
+ sourceEvidence: {
95446
+ feedPostIds: [],
95447
+ feedCategories: [],
95448
+ groupIds: [],
95449
+ taskIds: [],
95450
+ contributingAgentIds: [],
95451
+ successExamples: [
95452
+ "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",
95453
+ "\u5B98\u65B9 Seedance MCP\uFF1Amcp__seedance__seedance_create_task / mcp__seedance__seedance_check_task\u3002"
95454
+ ],
95455
+ failureExamples: [
95456
+ "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",
95457
+ "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"
95458
+ ]
95459
+ },
95460
+ installScope: "team",
95461
+ version: "1.0.0",
95462
+ createdBy: "system"
95463
+ }
95464
+ ];
95465
+
95240
95466
  // ../shared/src/officialWazaSkills.ts
95241
95467
  init_cjs_shims();
95242
95468
  var WAZA_VERSION = "3.28.0";
@@ -95557,11 +95783,13 @@ var OFFICIAL_WAZA_SKILLS = [
95557
95783
  // ../shared/src/officialSkills.ts
95558
95784
  var OFFICIAL_SKILL_IDS = [
95559
95785
  ...OFFICIAL_OFFICE_SKILL_IDS,
95560
- ...OFFICIAL_WAZA_SKILL_IDS
95786
+ ...OFFICIAL_WAZA_SKILL_IDS,
95787
+ ...OFFICIAL_MEDIA_SKILL_IDS
95561
95788
  ];
95562
95789
  var OFFICIAL_SKILLS = [
95563
95790
  ...OFFICIAL_OFFICE_SKILLS,
95564
- ...OFFICIAL_WAZA_SKILLS
95791
+ ...OFFICIAL_WAZA_SKILLS,
95792
+ ...OFFICIAL_MEDIA_SKILLS
95565
95793
  ];
95566
95794
  function renderOfficialSkillMarkdown(skill) {
95567
95795
  return renderSkillManifestMarkdown(skill, { cacheSource: "shared-official" });
@@ -95695,7 +95923,42 @@ function searchTokens(value) {
95695
95923
  value.split(/[\s,,、/|]+/g).map((token) => token.trim()).filter((token) => token.length >= 2)
95696
95924
  )];
95697
95925
  }
95698
- var BROAD_TASK_TERMS = /* @__PURE__ */ new Set(["\u65B9\u6848", "\u5185\u5BB9", "\u6587\u6863", "\u5206\u6790", "\u4F18\u5316", "plan", "content", "document", "analysis"]);
95926
+ var BROAD_TASK_TERMS = /* @__PURE__ */ new Set([
95927
+ "\u65B9\u6848",
95928
+ "\u5185\u5BB9",
95929
+ "\u6587\u6863",
95930
+ "\u5206\u6790",
95931
+ "\u4F18\u5316",
95932
+ "\u7528\u6237",
95933
+ "\u5F53\u524D",
95934
+ "\u8FD9\u4E2A",
95935
+ "\u4E00\u4E2A",
95936
+ "\u4E00\u4E9B",
95937
+ "\u9700\u8981",
95938
+ "\u8D1F\u8D23",
95939
+ "\u53EF\u4EE5",
95940
+ "\u5DE5\u5177",
95941
+ "\u80FD\u529B",
95942
+ "\u8BA1\u5212",
95943
+ "plan",
95944
+ "content",
95945
+ "document",
95946
+ "analysis",
95947
+ "agent",
95948
+ "skill",
95949
+ "tool",
95950
+ "task",
95951
+ "user",
95952
+ "need",
95953
+ "needs",
95954
+ "use",
95955
+ "using",
95956
+ "create",
95957
+ "make",
95958
+ "help",
95959
+ "with"
95960
+ ]);
95961
+ var TASK_TOKEN_SCORE_CAP = 6;
95699
95962
  function entryCorpus(entry) {
95700
95963
  return [
95701
95964
  entry.id,
@@ -95706,6 +95969,27 @@ function entryCorpus(entry) {
95706
95969
  ...entry.applicableRoles
95707
95970
  ].join(" ").toLowerCase();
95708
95971
  }
95972
+ function meaningfulTokens(value) {
95973
+ return searchTokens(value).filter((token) => !BROAD_TASK_TERMS.has(token));
95974
+ }
95975
+ function tokensFuzzyMatch(left, right) {
95976
+ if (left === right) return true;
95977
+ if (left.length >= 2 && right.length >= 2 && (left.includes(right) || right.includes(left))) return true;
95978
+ return false;
95979
+ }
95980
+ function matchedTaskKeywords(corpus, taskText) {
95981
+ if (!taskText) return [];
95982
+ const taskTokens = meaningfulTokens(taskText);
95983
+ if (taskTokens.length === 0) return [];
95984
+ const corpusTokens = meaningfulTokens(corpus);
95985
+ const matches = [];
95986
+ for (const taskToken of taskTokens) {
95987
+ if (corpus.includes(taskToken) || corpusTokens.some((corpusToken) => tokensFuzzyMatch(taskToken, corpusToken))) {
95988
+ matches.push(taskToken);
95989
+ }
95990
+ }
95991
+ return [...new Set(matches)];
95992
+ }
95709
95993
  function scoreEntry(entry, query4) {
95710
95994
  const corpus = entryCorpus(entry);
95711
95995
  const queryText = normalizeText(query4.query);
@@ -95728,6 +96012,7 @@ function scoreEntry(entry, query4) {
95728
96012
  const normalizedTaskType = taskType.toLowerCase().replace(/_/g, " ");
95729
96013
  if (taskText.includes(normalizedTaskType) || taskText.includes(taskType.toLowerCase())) score += 4;
95730
96014
  }
96015
+ score += Math.min(TASK_TOKEN_SCORE_CAP, matchedTaskKeywords(corpus, taskText).length * 2);
95731
96016
  if (taskText && corpus.includes(taskText)) score += 2;
95732
96017
  }
95733
96018
  if (!queryText && !roleText && !taskText) score = 1;
@@ -95765,6 +96050,8 @@ function recommendationReasons(entry, input) {
95765
96050
  if (matchedRoles.length > 0) reasons.push(`\u5339\u914D\u89D2\u8272\uFF1A${matchedRoles.slice(0, 3).join("\u3001")}`);
95766
96051
  const matchedTasks = matchedTaskTypes(entry, taskText);
95767
96052
  if (matchedTasks.length > 0) reasons.push(`\u5339\u914D\u4EFB\u52A1\u7C7B\u578B\uFF1A${matchedTasks.slice(0, 3).join("\u3001")}`);
96053
+ const matchedKeywords = matchedTaskKeywords(entryCorpus(entry), taskText);
96054
+ if (matchedTasks.length === 0 && matchedKeywords.length > 0) reasons.push(`\u5339\u914D\u5173\u952E\u8BCD\uFF1A${matchedKeywords.slice(0, 3).join("\u3001")}`);
95768
96055
  if (entry.permissionLevel === "high") reasons.push("\u9AD8\u6743\u9650 skill\uFF1A\u9ED8\u8BA4\u6216\u5DF2\u5206\u914D\u65F6\u53EF\u6309\u4EFB\u52A1\u4F7F\u7528\uFF1B\u5199\u6587\u4EF6\u3001\u8DD1\u547D\u4EE4\u3001\u53D1\u5E03\u7B49\u5177\u4F53\u52A8\u4F5C\u524D\u518D\u786E\u8BA4");
95769
96056
  if (entry.runtimeAvailability === "smith_only") reasons.push("\u5F53\u524D\u53EA\u80FD\u7531 Smith \u8BFB\u53D6\u5B8C\u6574\u65B9\u6CD5\u5B66");
95770
96057
  if (entry.runtimeAvailability === "planned") reasons.push("\u5F53\u524D\u662F\u89C4\u5212\u4E2D\u7684 P0 skill \u5019\u9009\uFF0C\u4E0D\u80FD\u58F0\u79F0\u5DF2\u5B89\u88C5");
@@ -95887,6 +96174,12 @@ init_cjs_shims();
95887
96174
  // ../shared/src/utils/serverUrl.ts
95888
96175
  init_cjs_shims();
95889
96176
 
96177
+ // ../shared/src/utils/mediaPreviewHtml.ts
96178
+ init_cjs_shims();
96179
+
96180
+ // ../shared/src/utils/bridgeLocality.ts
96181
+ init_cjs_shims();
96182
+
95890
96183
  // ../shared/src/utils/mcp.ts
95891
96184
  init_cjs_shims();
95892
96185
  var OFFICIAL_MCP_PROVIDER_IDS = [
@@ -96003,6 +96296,7 @@ function normalizeMcpConnectionSnapshot(value) {
96003
96296
  customHeaders: normalizeMcpCustomHeaderSnapshot(raw.customHeaders),
96004
96297
  enabled: raw.enabled === true,
96005
96298
  alwaysLoad: raw.alwaysLoad === true,
96299
+ dailyCallLimit: normalizeMcpDailyCallLimitSnapshot(raw.dailyCallLimit),
96006
96300
  isBuiltin: false,
96007
96301
  ownerUserId: null,
96008
96302
  createdBy: null,
@@ -96012,6 +96306,11 @@ function normalizeMcpConnectionSnapshot(value) {
96012
96306
  bindings: bindings.length > 0 ? bindings : [{ connectionId: raw.id, targetKind: "global", targetId: MCP_GLOBAL_TARGET_ID, enabled: true }]
96013
96307
  };
96014
96308
  }
96309
+ function normalizeMcpDailyCallLimitSnapshot(value) {
96310
+ if (value === null || value === void 0 || value === "") return null;
96311
+ if (typeof value !== "number" || !Number.isFinite(value)) return null;
96312
+ return Math.max(0, Math.floor(value));
96313
+ }
96015
96314
  function normalizeMcpToolSnapshot(value) {
96016
96315
  if (!value || typeof value !== "object") return null;
96017
96316
  const raw = value;
@@ -96120,6 +96419,60 @@ var readpageScrapeTool = {
96120
96419
  enabled: true,
96121
96420
  permissionPolicy: "always_allow"
96122
96421
  };
96422
+ var seedreamGenerateImageTool = {
96423
+ name: "generate_image",
96424
+ displayName: "Seedream \u751F\u56FE",
96425
+ 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",
96426
+ category: "media",
96427
+ riskLevel: "medium",
96428
+ enabled: true,
96429
+ permissionPolicy: "always_ask"
96430
+ };
96431
+ var seedreamEditImageTool = {
96432
+ name: "edit_image",
96433
+ displayName: "Seedream \u6539\u56FE",
96434
+ 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",
96435
+ category: "media",
96436
+ riskLevel: "medium",
96437
+ enabled: true,
96438
+ permissionPolicy: "always_ask"
96439
+ };
96440
+ var seedreamGenerateImageGroupTool = {
96441
+ name: "generate_image_group",
96442
+ displayName: "Seedream \u5355\u56FE",
96443
+ 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",
96444
+ category: "media",
96445
+ riskLevel: "medium",
96446
+ enabled: true,
96447
+ permissionPolicy: "always_ask"
96448
+ };
96449
+ var seedanceUsageGuideTool = {
96450
+ name: "seedance_usage_guide",
96451
+ displayName: "Seedance \u4F7F\u7528\u8BF4\u660E",
96452
+ 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",
96453
+ category: "media",
96454
+ riskLevel: "low",
96455
+ enabled: true,
96456
+ permissionPolicy: "always_allow"
96457
+ };
96458
+ var seedanceCreateTaskTool = {
96459
+ name: "seedance_create_task",
96460
+ displayName: "Seedance \u751F\u89C6\u9891",
96461
+ 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",
96462
+ category: "media",
96463
+ riskLevel: "high",
96464
+ enabled: true,
96465
+ permissionPolicy: "always_ask"
96466
+ };
96467
+ var seedanceCheckTaskTool = {
96468
+ name: "seedance_check_task",
96469
+ displayName: "Seedance \u67E5\u7ED3\u679C",
96470
+ 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",
96471
+ category: "media",
96472
+ riskLevel: "low",
96473
+ enabled: true,
96474
+ permissionPolicy: "always_allow"
96475
+ };
96123
96476
  var context7ResolveLibraryTool = {
96124
96477
  name: "resolve-library-id",
96125
96478
  displayName: "\u89E3\u6790\u6587\u6863\u5E93",
@@ -96426,8 +96779,56 @@ var ALIYUN_IQS_MCP_PROVIDERS = [
96426
96779
  tools: [readpageBasicTool, readpageScrapeTool]
96427
96780
  }
96428
96781
  ];
96782
+ var VOLCENGINE_SEEDREAM_MCP_PROVIDER = {
96783
+ providerId: "volcengine_seedream",
96784
+ name: "Volcengine Seedream",
96785
+ 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",
96786
+ serverName: "seedream",
96787
+ transport: "stdio",
96788
+ url: null,
96789
+ command: "ahchat-builtin",
96790
+ args: ["seedream-mcp"],
96791
+ env: {
96792
+ ARK_API_KEY: "",
96793
+ ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
96794
+ },
96795
+ authType: "x_api_key",
96796
+ customHeaders: [],
96797
+ enabled: true,
96798
+ alwaysLoad: true,
96799
+ tools: [
96800
+ seedreamGenerateImageTool,
96801
+ seedreamEditImageTool,
96802
+ seedreamGenerateImageGroupTool
96803
+ ]
96804
+ };
96805
+ var VOLCENGINE_SEEDANCE_MCP_PROVIDER = {
96806
+ providerId: "volcengine_seedance",
96807
+ name: "Volcengine Seedance",
96808
+ 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",
96809
+ serverName: "seedance",
96810
+ transport: "stdio",
96811
+ url: null,
96812
+ command: "ahchat-builtin",
96813
+ args: ["seedance-mcp"],
96814
+ env: {
96815
+ ARK_API_KEY: "",
96816
+ ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
96817
+ },
96818
+ authType: "x_api_key",
96819
+ customHeaders: [],
96820
+ enabled: true,
96821
+ alwaysLoad: true,
96822
+ tools: [
96823
+ seedanceUsageGuideTool,
96824
+ seedanceCreateTaskTool,
96825
+ seedanceCheckTaskTool
96826
+ ]
96827
+ };
96429
96828
  var OFFICIAL_MCP_PROVIDERS = [
96430
- ...ALIYUN_IQS_MCP_PROVIDERS
96829
+ ...ALIYUN_IQS_MCP_PROVIDERS,
96830
+ VOLCENGINE_SEEDANCE_MCP_PROVIDER,
96831
+ VOLCENGINE_SEEDREAM_MCP_PROVIDER
96431
96832
  ];
96432
96833
  var MCP_STORE_PROVIDERS = [
96433
96834
  {
@@ -96889,7 +97290,7 @@ var AgentMemoryStore = class {
96889
97290
 
96890
97291
  // src/agentManager.ts
96891
97292
  init_cjs_shims();
96892
- var import_node_child_process2 = require("child_process");
97293
+ var import_node_child_process3 = require("child_process");
96893
97294
  var import_node_crypto3 = require("crypto");
96894
97295
  var import_node_fs6 = __toESM(require("fs"), 1);
96895
97296
  var import_promises3 = __toESM(require("fs/promises"), 1);
@@ -97502,6 +97903,77 @@ function cronCreateDurableAllow(input) {
97502
97903
  priorDurable: input.durable
97503
97904
  };
97504
97905
  }
97906
+ var OFFICIAL_MEDIA_GENERATION_TOOL_NAMES = [
97907
+ "mcp__seedream__generate_image",
97908
+ "mcp__seedream__edit_image",
97909
+ "mcp__seedream__generate_image_group",
97910
+ "mcp__seedance__seedance_create_task"
97911
+ ];
97912
+ var OFFICIAL_MEDIA_GENERATION_TOOLS = new Set(OFFICIAL_MEDIA_GENERATION_TOOL_NAMES);
97913
+ var OFFICIAL_MEDIA_GENERATION_TOOL_PATTERNS = [
97914
+ /^mcp__seedream(?:_\d+)?__(?:generate_image|edit_image|generate_image_group)$/,
97915
+ /^mcp__seedance(?:_\d+)?__seedance_create_task$/
97916
+ ];
97917
+ function isOfficialMediaGenerationToolName(toolName) {
97918
+ return OFFICIAL_MEDIA_GENERATION_TOOLS.has(toolName) || OFFICIAL_MEDIA_GENERATION_TOOL_PATTERNS.some((pattern) => pattern.test(toolName));
97919
+ }
97920
+ function createOfficialMediaGenerationTurnGuard() {
97921
+ return {
97922
+ replyMessageId: null,
97923
+ toolName: null,
97924
+ duplicateDenied: false
97925
+ };
97926
+ }
97927
+ function resetOfficialMediaGenerationTurnGuard(guard, replyMessageId) {
97928
+ guard.replyMessageId = replyMessageId;
97929
+ guard.toolName = null;
97930
+ guard.duplicateDenied = false;
97931
+ }
97932
+ var OFFICIAL_MEDIA_DUPLICATE_DENY_REASON = "\u672C\u8F6E\u5DF2\u7ECF\u8C03\u7528\u8FC7\u5B98\u65B9\u5A92\u4F53\u751F\u6210\u5DE5\u5177";
97933
+ function isOfficialMediaGenerationDuplicateDenyMessage(message) {
97934
+ return message.includes(OFFICIAL_MEDIA_DUPLICATE_DENY_REASON);
97935
+ }
97936
+ function guardOfficialMediaGenerationTool(guard, toolName) {
97937
+ if (!isOfficialMediaGenerationToolName(toolName)) return null;
97938
+ if (!guard.toolName) {
97939
+ guard.toolName = toolName;
97940
+ return null;
97941
+ }
97942
+ guard.duplicateDenied = true;
97943
+ return {
97944
+ behavior: "deny",
97945
+ message: `\u672C\u8F6E\u5DF2\u7ECF\u8C03\u7528\u8FC7\u5B98\u65B9\u5A92\u4F53\u751F\u6210\u5DE5\u5177\uFF08${guard.toolName}\uFF09\u3002\u6BCF\u6761\u7528\u6237\u8BF7\u6C42\u53EA\u80FD\u751F\u6210\u4E00\u4E2A\u5A92\u4F53\u7ED3\u679C\uFF1B\u8BF7\u505C\u6B62\u91CD\u8BD5\uFF0C\u76F4\u63A5\u6839\u636E\u5DF2\u7ECF\u8FD4\u56DE\u7684\u5A92\u4F53\u5361\u7247\u56DE\u590D\u7528\u6237\u3002`
97946
+ };
97947
+ }
97948
+ function createOfficialMediaGenerationPreToolUseHooks(guard, toolNames, meta3) {
97949
+ const mediaToolNames = /* @__PURE__ */ new Set([
97950
+ ...OFFICIAL_MEDIA_GENERATION_TOOL_NAMES,
97951
+ ...Array.from(toolNames).filter(isOfficialMediaGenerationToolName)
97952
+ ]);
97953
+ return Array.from(mediaToolNames).map((toolName) => ({
97954
+ matcher: toolName,
97955
+ hooks: [
97956
+ async (_input) => {
97957
+ const decision = guardOfficialMediaGenerationTool(guard, toolName);
97958
+ if (!decision || decision.behavior !== "deny") return {};
97959
+ meta3.log("PreToolUse deny: duplicate official media generation tool in one turn", {
97960
+ agentId: meta3.agentId,
97961
+ scope: meta3.scope,
97962
+ toolName,
97963
+ firstToolName: guard.toolName,
97964
+ replyMessageId: guard.replyMessageId
97965
+ });
97966
+ return {
97967
+ hookSpecificOutput: {
97968
+ hookEventName: "PreToolUse",
97969
+ permissionDecision: "deny",
97970
+ permissionDecisionReason: decision.message
97971
+ }
97972
+ };
97973
+ }
97974
+ ]
97975
+ }));
97976
+ }
97505
97977
  function normalizedCommand(input) {
97506
97978
  const raw = input.command;
97507
97979
  return typeof raw === "string" ? raw.replace(/\s+/g, " ").trim() : "";
@@ -112254,8 +112726,117 @@ config(en_default());
112254
112726
  // src/documentReader.ts
112255
112727
  init_cjs_shims();
112256
112728
  var import_promises2 = __toESM(require("fs/promises"), 1);
112729
+ var import_node_child_process2 = require("child_process");
112730
+ var import_node_path10 = __toESM(require("path"), 1);
112731
+ var import_node_util = require("util");
112732
+
112733
+ // src/officeRuntime.ts
112734
+ init_cjs_shims();
112735
+ var import_node_fs5 = __toESM(require("fs"), 1);
112736
+ var import_node_os5 = __toESM(require("os"), 1);
112257
112737
  var import_node_path9 = __toESM(require("path"), 1);
112258
- var logger7 = createModuleLogger("document.reader");
112738
+ var OFFICECLI_EXECUTABLE_ENV = "AHCHAT_OFFICECLI_EXECUTABLE";
112739
+ var OFFICECLI_BIN_DIR_ENV = "AHCHAT_OFFICECLI_BIN_DIR";
112740
+ var logger7 = createModuleLogger("bridge.officeRuntime");
112741
+ function sanitizedOfficeCliProbeError(error51) {
112742
+ const rawCode = error51 && typeof error51 === "object" && "code" in error51 ? error51.code : void 0;
112743
+ const code = typeof rawCode === "string" ? rawCode : void 0;
112744
+ const sanitized = new Error(`OfficeCLI executable probe failed${code ? ` (${code})` : ""}`);
112745
+ if (error51 instanceof Error) sanitized.name = error51.name;
112746
+ return sanitized;
112747
+ }
112748
+ function defaultRuntimeRoot() {
112749
+ if (process.platform === "win32") {
112750
+ return import_node_path9.default.join(process.env.LOCALAPPDATA || import_node_path9.default.join(import_node_os5.default.homedir(), "AppData", "Local"), "AHChat", "runtime", "officecli");
112751
+ }
112752
+ if (process.platform === "darwin") {
112753
+ return import_node_path9.default.join(import_node_os5.default.homedir(), "Library", "Caches", "AHChat", "runtime", "officecli");
112754
+ }
112755
+ return import_node_path9.default.join(process.env.XDG_CACHE_HOME || import_node_path9.default.join(import_node_os5.default.homedir(), ".cache"), "ahchat", "runtime", "officecli");
112756
+ }
112757
+ function getManagedOfficeCliBinDir(env2 = process.env) {
112758
+ return env2[OFFICECLI_BIN_DIR_ENV] || import_node_path9.default.join(defaultRuntimeRoot(), "bin");
112759
+ }
112760
+ function getOfficeCliExecutableName() {
112761
+ return process.platform === "win32" ? "officecli.exe" : "officecli";
112762
+ }
112763
+ function getManagedOfficeCliExecutablePath(env2 = process.env) {
112764
+ return import_node_path9.default.join(getManagedOfficeCliBinDir(env2), getOfficeCliExecutableName());
112765
+ }
112766
+ function isExecutable(filePath, options = {}) {
112767
+ const logFailure = options.logFailure !== false;
112768
+ try {
112769
+ if (process.platform === "win32") return import_node_fs5.default.existsSync(filePath);
112770
+ import_node_fs5.default.accessSync(filePath, import_node_fs5.default.constants.X_OK);
112771
+ return true;
112772
+ } catch (error51) {
112773
+ if (logFailure) {
112774
+ logger7.error("OfficeCLI executable probe failed", {
112775
+ error: sanitizedOfficeCliProbeError(error51),
112776
+ fileName: import_node_path9.default.basename(filePath)
112777
+ });
112778
+ }
112779
+ return false;
112780
+ }
112781
+ }
112782
+ function withPrependedPath(env2, entries) {
112783
+ const pathEntries = entries.filter((entry) => entry && import_node_fs5.default.existsSync(entry));
112784
+ if (pathEntries.length === 0) return env2;
112785
+ const current = env2.PATH ?? "";
112786
+ return {
112787
+ ...env2,
112788
+ PATH: [...pathEntries, current].filter(Boolean).join(import_node_path9.default.delimiter)
112789
+ };
112790
+ }
112791
+ function statusForPath(filePath, source, env2, options = {}) {
112792
+ if (!isExecutable(filePath, { logFailure: options.logProbeFailure })) {
112793
+ return {
112794
+ ok: false,
112795
+ path: filePath,
112796
+ source,
112797
+ message: `officecli not executable at ${filePath}`
112798
+ };
112799
+ }
112800
+ const runtimeEnv = withPrependedPath(env2, [import_node_path9.default.dirname(filePath)]);
112801
+ const version4 = readCommandVersion(filePath, ["--version"], runtimeEnv);
112802
+ if (!version4) {
112803
+ return {
112804
+ ok: false,
112805
+ path: filePath,
112806
+ source,
112807
+ message: `officecli found at ${filePath} but --version failed`
112808
+ };
112809
+ }
112810
+ return { ok: true, path: filePath, source, version: version4 };
112811
+ }
112812
+ function detectOfficeCliRuntime(env2 = process.env) {
112813
+ const explicitPath = env2[OFFICECLI_EXECUTABLE_ENV]?.trim();
112814
+ if (explicitPath) return statusForPath(explicitPath, "env", env2);
112815
+ const managedPath = getManagedOfficeCliExecutablePath(env2);
112816
+ const managed = statusForPath(managedPath, "managed", env2, { logProbeFailure: false });
112817
+ if (managed.ok) return managed;
112818
+ const resolved = resolveCommand(["officecli"], withPrependedPath(env2, [import_node_path9.default.dirname(managedPath)]));
112819
+ if (!resolved) {
112820
+ return {
112821
+ ok: false,
112822
+ source: "managed",
112823
+ path: managedPath,
112824
+ message: `officecli not found. Run pnpm setup:office-runtime or set ${OFFICECLI_EXECUTABLE_ENV}.`
112825
+ };
112826
+ }
112827
+ return statusForPath(resolved.path, resolved.path === managedPath ? "managed" : "path", env2);
112828
+ }
112829
+ function withOfficeCliRuntimeEnv(status, env2 = process.env) {
112830
+ if (!status.ok || !status.path) return env2;
112831
+ return {
112832
+ ...withPrependedPath(env2, [import_node_path9.default.dirname(status.path)]),
112833
+ [OFFICECLI_EXECUTABLE_ENV]: status.path
112834
+ };
112835
+ }
112836
+
112837
+ // src/documentReader.ts
112838
+ var logger8 = createModuleLogger("document.reader");
112839
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
112259
112840
  var SUPPORTED_DOCUMENT_EXTENSIONS = /* @__PURE__ */ new Set([
112260
112841
  ".docx",
112261
112842
  ".xls",
@@ -112292,22 +112873,22 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
112292
112873
  var DEFAULT_MAX_CHARS = 5e5;
112293
112874
  var DEFAULT_TIMEOUT_MS = 45e3;
112294
112875
  function isReadableDocumentPath(filePath) {
112295
- return SUPPORTED_DOCUMENT_EXTENSIONS.has(import_node_path9.default.extname(filePath).toLowerCase());
112876
+ return SUPPORTED_DOCUMENT_EXTENSIONS.has(import_node_path10.default.extname(filePath).toLowerCase());
112296
112877
  }
112297
112878
  function resolveDocumentPath(inputPath, cwd) {
112298
112879
  const trimmed = inputPath.trim();
112299
112880
  if (!trimmed) throw new Error("path is required");
112300
- const resolvedCwd = import_node_path9.default.resolve(resolveUserPath(cwd));
112301
- const candidate = import_node_path9.default.isAbsolute(trimmed) ? import_node_path9.default.resolve(resolveUserPath(trimmed)) : import_node_path9.default.resolve(resolvedCwd, trimmed);
112302
- const relative = import_node_path9.default.relative(resolvedCwd, candidate);
112303
- if (relative.startsWith("..") || import_node_path9.default.isAbsolute(relative)) {
112881
+ const resolvedCwd = import_node_path10.default.resolve(resolveUserPath(cwd));
112882
+ const candidate = import_node_path10.default.isAbsolute(trimmed) ? import_node_path10.default.resolve(resolveUserPath(trimmed)) : import_node_path10.default.resolve(resolvedCwd, trimmed);
112883
+ const relative = import_node_path10.default.relative(resolvedCwd, candidate);
112884
+ if (relative.startsWith("..") || import_node_path10.default.isAbsolute(relative)) {
112304
112885
  throw new Error("document path must be inside the current working directory");
112305
112886
  }
112306
112887
  return candidate;
112307
112888
  }
112308
112889
  async function readDocumentAsMarkdown(inputPath, opts = {}) {
112309
- const resolvedPath = opts.cwd ? resolveDocumentPath(inputPath, opts.cwd) : import_node_path9.default.resolve(resolveUserPath(inputPath));
112310
- const ext = import_node_path9.default.extname(resolvedPath).toLowerCase();
112890
+ const resolvedPath = opts.cwd ? resolveDocumentPath(inputPath, opts.cwd) : import_node_path10.default.resolve(resolveUserPath(inputPath));
112891
+ const ext = import_node_path10.default.extname(resolvedPath).toLowerCase();
112311
112892
  if (!isReadableDocumentPath(resolvedPath)) {
112312
112893
  throw new Error(`unsupported document type: ${ext || "(no extension)"}`);
112313
112894
  }
@@ -112334,7 +112915,7 @@ async function readDocumentAsMarkdown(inputPath, opts = {}) {
112334
112915
  if (!markdown.trim()) {
112335
112916
  warnings.push("No readable text was extracted from this document.");
112336
112917
  }
112337
- logger7.info("Document read as markdown", {
112918
+ logger8.info("Document read as markdown", {
112338
112919
  path: resolvedPath,
112339
112920
  ext,
112340
112921
  length: markdown.length,
@@ -112349,17 +112930,17 @@ async function readDocumentAsMarkdown(inputPath, opts = {}) {
112349
112930
  };
112350
112931
  }
112351
112932
  function documentSidecarPath(filePath, outputDir) {
112352
- const dir = outputDir ?? import_node_path9.default.dirname(filePath);
112353
- const base = import_node_path9.default.basename(filePath);
112354
- return import_node_path9.default.join(dir, `${base}.content.md`);
112933
+ const dir = outputDir ?? import_node_path10.default.dirname(filePath);
112934
+ const base = import_node_path10.default.basename(filePath);
112935
+ return import_node_path10.default.join(dir, `${base}.content.md`);
112355
112936
  }
112356
112937
  async function writeDocumentSidecar(filePath, opts = {}) {
112357
112938
  const result = await readDocumentAsMarkdown(filePath, opts);
112358
- const sidecarDir = opts.sidecarDir ? import_node_path9.default.resolve(resolveUserPath(opts.sidecarDir)) : import_node_path9.default.dirname(result.path);
112939
+ const sidecarDir = opts.sidecarDir ? import_node_path10.default.resolve(resolveUserPath(opts.sidecarDir)) : import_node_path10.default.dirname(result.path);
112359
112940
  if (opts.cwd) {
112360
- const resolvedCwd = import_node_path9.default.resolve(resolveUserPath(opts.cwd));
112361
- const relative = import_node_path9.default.relative(resolvedCwd, sidecarDir);
112362
- if (relative.startsWith("..") || import_node_path9.default.isAbsolute(relative)) {
112941
+ const resolvedCwd = import_node_path10.default.resolve(resolveUserPath(opts.cwd));
112942
+ const relative = import_node_path10.default.relative(resolvedCwd, sidecarDir);
112943
+ if (relative.startsWith("..") || import_node_path10.default.isAbsolute(relative)) {
112363
112944
  throw new Error("document sidecar path must be inside the current working directory");
112364
112945
  }
112365
112946
  }
@@ -112379,7 +112960,7 @@ ${result.warnings.map((w) => `- ${w}`).join("\n")}
112379
112960
  warningText
112380
112961
  ].join("\n");
112381
112962
  await import_promises2.default.writeFile(sidecarPath, content, "utf-8");
112382
- logger7.info("Document sidecar written", {
112963
+ logger8.info("Document sidecar written", {
112383
112964
  path: result.path,
112384
112965
  sidecarPath,
112385
112966
  length: content.length
@@ -112402,7 +112983,7 @@ async function convertOfficeDocument(filePath, timeoutMs) {
112402
112983
  abortSignal: controller.signal
112403
112984
  },
112404
112985
  onWarning: (issue2) => {
112405
- logger7.warn("Document conversion warning", {
112986
+ logger8.warn("Document conversion warning", {
112406
112987
  path: filePath,
112407
112988
  code: issue2.code,
112408
112989
  message: issue2.message
@@ -112412,10 +112993,53 @@ async function convertOfficeDocument(filePath, timeoutMs) {
112412
112993
  if (typeof result.value === "string") return result.value;
112413
112994
  if (result.value instanceof Uint8Array) return Buffer.from(result.value).toString("utf-8");
112414
112995
  return JSON.stringify(result.value, null, 2);
112996
+ } catch (e) {
112997
+ if (import_node_path10.default.extname(filePath).toLowerCase() !== ".docx") throw e;
112998
+ logger8.warn("Office parser failed; trying OfficeCLI text fallback", {
112999
+ path: filePath,
113000
+ error: e
113001
+ });
113002
+ try {
113003
+ return await convertDocxWithOfficeCli(filePath, timeoutMs);
113004
+ } catch (fallbackError) {
113005
+ logger8.warn("OfficeCLI text fallback failed", {
113006
+ path: filePath,
113007
+ error: fallbackError
113008
+ });
113009
+ throw e;
113010
+ }
112415
113011
  } finally {
112416
113012
  clearTimeout(timer);
112417
113013
  }
112418
113014
  }
113015
+ function parseOfficeCliParagraphText(value) {
113016
+ if (!value || typeof value !== "object") return "";
113017
+ const root = value;
113018
+ if (root.success !== true || !root.data || typeof root.data !== "object") return "";
113019
+ const data = root.data;
113020
+ if (!Array.isArray(data.results)) return "";
113021
+ return data.results.map((item) => {
113022
+ if (!item || typeof item !== "object") return "";
113023
+ const text = item.text;
113024
+ return typeof text === "string" ? text.trim() : "";
113025
+ }).filter((text) => text.length > 0).join("\n\n");
113026
+ }
113027
+ async function convertDocxWithOfficeCli(filePath, timeoutMs) {
113028
+ const executable = process.env[OFFICECLI_EXECUTABLE_ENV]?.trim() || "officecli";
113029
+ const { stdout } = await execFileAsync(executable, ["query", filePath, "paragraph", "--json"], {
113030
+ timeout: timeoutMs,
113031
+ maxBuffer: 20 * 1024 * 1024,
113032
+ windowsHide: true
113033
+ });
113034
+ const parsed = JSON.parse(stdout);
113035
+ const text = parseOfficeCliParagraphText(parsed);
113036
+ if (!text.trim()) throw new Error("OfficeCLI returned no paragraph text");
113037
+ logger8.info("Document read via OfficeCLI text fallback", {
113038
+ path: filePath,
113039
+ length: text.length
113040
+ });
113041
+ return text;
113042
+ }
112419
113043
  async function convertLegacyExcelDocument(filePath) {
112420
113044
  const XLSX2 = await Promise.resolve().then(() => (init_xlsx(), xlsx_exports));
112421
113045
  const workbook = XLSX2.readFile(filePath, { cellDates: true });
@@ -112464,7 +113088,9 @@ function normalizeDocumentText(value) {
112464
113088
  }
112465
113089
 
112466
113090
  // src/neuralMcpServer.ts
112467
- var logger8 = createModuleLogger("neural.mcpServer");
113091
+ var logger9 = createModuleLogger("neural.mcpServer");
113092
+ var VIDEO_GENERATION_SKILL_ID = OFFICIAL_MEDIA_SKILL_IDS[0];
113093
+ var AUTO_LOCAL_ENHANCER_LIMIT = 2;
112468
113094
  function formatSkillEntry(entry, index) {
112469
113095
  return [
112470
113096
  `${index + 1}. ${entry.displayName} (${entry.name})`,
@@ -112497,7 +113123,7 @@ function runtimeSkillIndexEntries(skillStore, agentId, smithDefaultAllSkills = f
112497
113123
  return entry.runtimeAvailability === "available";
112498
113124
  });
112499
113125
  } catch (e) {
112500
- logger8.warn("Runtime skill index unavailable", { error: e });
113126
+ logger9.warn("Runtime skill index unavailable", { error: e });
112501
113127
  return [];
112502
113128
  }
112503
113129
  }
@@ -112507,7 +113133,7 @@ function runtimeVisibleSkillIds(skillStore, runtimeEntries) {
112507
113133
  try {
112508
113134
  for (const name of skillStore.allowedNames()) ids.add(name);
112509
113135
  } catch (e) {
112510
- logger8.warn("Runtime skill names unavailable", { error: e });
113136
+ logger9.warn("Runtime skill names unavailable", { error: e });
112511
113137
  }
112512
113138
  for (const entry of runtimeEntries) {
112513
113139
  ids.add(entry.id);
@@ -112526,6 +113152,69 @@ function filterAgentAvailableSkillEntries(entries, availableIds) {
112526
113152
  if (!availableIds) return entries;
112527
113153
  return entries.filter((entry) => availableIds.has(entry.id) || availableIds.has(entry.name));
112528
113154
  }
113155
+ function matchesVideoGenerationIntent(input) {
113156
+ const roleText = [input.name, input.role].join("\n").toLowerCase();
113157
+ if (/seedance|生视频|视频生成|生成视频|视频助手|ai\s*video|video\s*generation|creative\s*video/.test(roleText)) {
113158
+ return true;
113159
+ }
113160
+ if (roleText.includes("\u89C6\u9891") && /[生成创作制作导演剪辑]/.test(roleText)) {
113161
+ return true;
113162
+ }
113163
+ const promptText = [input.systemPrompt, input.initialInstruction].join("\n").toLowerCase();
113164
+ return /seedance|生视频|视频生成|生成视频|文生视频|图生视频|text-to-video|image-to-video|ai\s*video|video\s*generation/.test(promptText);
113165
+ }
113166
+ var AUTO_ASSIGN_SKILL_RULES = [
113167
+ {
113168
+ skillId: VIDEO_GENERATION_SKILL_ID,
113169
+ intent: "media_video_generation",
113170
+ matches: matchesVideoGenerationIntent
113171
+ }
113172
+ ];
113173
+ function autoAssignOfficialSkillIds(input) {
113174
+ return AUTO_ASSIGN_SKILL_RULES.filter((rule) => rule.matches(input)).map((rule) => rule.skillId);
113175
+ }
113176
+ function runtimeCachedSkillIds(skillStore) {
113177
+ if (!skillStore) return /* @__PURE__ */ new Set();
113178
+ try {
113179
+ return new Set(skillStore.allowedNames());
113180
+ } catch (e) {
113181
+ logger9.warn("Runtime skill names unavailable", { error: e });
113182
+ return /* @__PURE__ */ new Set();
113183
+ }
113184
+ }
113185
+ function isCurrentMachineLocalTarget(targetBridgeKey, currentBridgeKey) {
113186
+ const target = targetBridgeKey?.trim();
113187
+ if (!target) return true;
113188
+ const current = currentBridgeKey?.trim();
113189
+ return Boolean(current && target === current);
113190
+ }
113191
+ function selectLocalSkillEnhancersForCreateAgent(input, skillStore, alreadySelectedSkillIds) {
113192
+ if (!skillStore) return [];
113193
+ const cachedSkillIds = runtimeCachedSkillIds(skillStore);
113194
+ if (cachedSkillIds.size === 0) return [];
113195
+ const localCandidates2 = runtimeSkillIndexEntries(
113196
+ skillStore,
113197
+ null,
113198
+ true,
113199
+ true
113200
+ ).filter((entry) => {
113201
+ if (entry.runtimeAvailability !== "available") return false;
113202
+ if (entry.origin !== "local" && !isLocalSkillId(entry.id)) return false;
113203
+ if (alreadySelectedSkillIds.has(entry.id) || alreadySelectedSkillIds.has(entry.name)) return false;
113204
+ return cachedSkillIds.has(entry.id) || cachedSkillIds.has(entry.name);
113205
+ });
113206
+ if (localCandidates2.length === 0) return [];
113207
+ const localCandidateIds = new Set(localCandidates2.map((entry) => entry.id));
113208
+ const recommendations = recommendInitialSkillsForAgent({
113209
+ role: input.role,
113210
+ systemPrompt: input.systemPrompt,
113211
+ workingDirectory: input.workingDirectory,
113212
+ task: [input.name, input.role, input.initialInstruction].filter(Boolean).join("\n"),
113213
+ includePlanned: false,
113214
+ entries: localCandidates2
113215
+ });
113216
+ return recommendations.map((rec) => rec.skill.id).filter((skillId) => localCandidateIds.has(skillId)).filter((skillId, index, ids) => ids.indexOf(skillId) === index).slice(0, AUTO_LOCAL_ENHANCER_LIMIT);
113217
+ }
112529
113218
  function skillRuntimeContext(officeCliRuntime) {
112530
113219
  return officeCliRuntime ? {
112531
113220
  officeCliAvailable: officeCliRuntime.ok,
@@ -112571,6 +113260,16 @@ function formatMachineOptionLine(machine) {
112571
113260
  const bridgeId = machine.bridgeId ? `\uFF0CbridgeId=${machine.bridgeId}` : "";
112572
113261
  return `- machine_bridge_key=${machine.bridgeKey} [${machineStatusText(machine)}] ${formatBridgeMachineLabel(machine)}${bridgeId}`;
112573
113262
  }
113263
+ function rejectRemoteCreateMachineBridgeKey(machineBridgeKey, deps) {
113264
+ if (!machineBridgeKey || machineBridgeKey === "auto") return null;
113265
+ const currentBridgeKey = deps.currentBridgeKey?.trim();
113266
+ if (!currentBridgeKey || machineBridgeKey === currentBridgeKey) return null;
113267
+ return [
113268
+ `[create_agent] \u4E3A\u907F\u514D\u628A\u65B0 Agent \u521B\u5EFA\u5230\u522B\u7684\u7535\u8111\uFF0C\u521B\u5EFA\u65F6\u4E0D\u8981\u4F20\u5176\u4ED6\u673A\u5668\u7684 machine_bridge_key\u3002`,
113269
+ `\u8BF7\u7701\u7565 machine_bridge_key\uFF0C\u8BA9\u5B83\u4F7F\u7528\u5F53\u524D\u673A\u5668\uFF08${currentBridgeKey}\uFF09\u3002`,
113270
+ `\u5982\u679C\u7528\u6237\u660E\u786E\u8981\u6C42\u5207\u5230\u5176\u4ED6\u7535\u8111\uFF0C\u8BF7\u5148\u521B\u5EFA Agent\uFF0C\u518D\u7528 update_agent_profile \u5207\u6362\u8FD0\u884C\u673A\u5668\u3002`
113271
+ ].join(" ");
113272
+ }
112574
113273
  async function fetchVisibleBridgeMachines(deps) {
112575
113274
  if (!deps.serverApiUrl || !deps.bridgeToken) return [];
112576
113275
  try {
@@ -112579,14 +113278,14 @@ async function fetchVisibleBridgeMachines(deps) {
112579
113278
  headers: bridgeAuthHeaders(deps.bridgeToken)
112580
113279
  });
112581
113280
  if (!res.ok) {
112582
- logger8.warn("Bridge machine listing failed", { status: res.status });
113281
+ logger9.warn("Bridge machine listing failed", { status: res.status });
112583
113282
  return [];
112584
113283
  }
112585
113284
  const body = await res.json();
112586
113285
  if (!Array.isArray(body)) return [];
112587
113286
  return body.filter(isBridgeMachineSummary);
112588
113287
  } catch (e) {
112589
- logger8.warn("Bridge machine listing failed", { error: e });
113288
+ logger9.warn("Bridge machine listing failed", { error: e });
112590
113289
  return [];
112591
113290
  }
112592
113291
  }
@@ -112631,7 +113330,7 @@ async function resolveTierSubscriptionPreference(preferredSubscriptionId, deps)
112631
113330
  (subscription) => subscription.billingMode === "company_billable" && subscription.isPrimaryCompany === true
112632
113331
  )?.id ?? preferredSubscriptionId;
112633
113332
  } catch (e) {
112634
- logger8.warn("Primary company tier preference resolution failed", { error: e });
113333
+ logger9.warn("Primary company tier preference resolution failed", { error: e });
112635
113334
  return preferredSubscriptionId;
112636
113335
  }
112637
113336
  }
@@ -112806,7 +113505,7 @@ async function createNeuralMcpServer(deps) {
112806
113505
  message: external_exports.string().min(1).describe('\u8981\u4F20\u7ED9\u76EE\u6807\u5206\u8EAB\u7684\u4E00\u6BB5\u81EA\u7136\u8BED\u8A00\u3002\u5B83\u4F1A\u4F5C\u4E3A\u4F60\u7684"\u5185\u5FC3\u72EC\u767D"\u51FA\u73B0\u5728\u90A3\u4E2A scope\u3002')
112807
113506
  },
112808
113507
  async (args) => {
112809
- logger8.info("neural_send tool called", {
113508
+ logger9.info("neural_send tool called", {
112810
113509
  agentId: deps.agentId,
112811
113510
  fromScope: currentScopeKey,
112812
113511
  rawTargetScope: args.target_scope,
@@ -112828,7 +113527,7 @@ async function createNeuralMcpServer(deps) {
112828
113527
  if (singleConvId) {
112829
113528
  conversationId = singleConvId;
112830
113529
  } else {
112831
- logger8.warn("neural_send: failed to resolve single conv", { agentId: deps.agentId });
113530
+ logger9.warn("neural_send: failed to resolve single conv", { agentId: deps.agentId });
112832
113531
  return {
112833
113532
  content: [{ type: "text", text: "[neural_send] \u65E0\u6CD5\u89E3\u6790\u5355\u804A conversationId\uFF0C\u6D88\u606F\u672A\u9001\u8FBE\u3002\u8BF7\u5237\u65B0\u4F1A\u8BDD\u540E\u91CD\u8BD5\u3002" }],
112834
113533
  isError: true
@@ -112837,7 +113536,7 @@ async function createNeuralMcpServer(deps) {
112837
113536
  } else if (args.target_scope.startsWith("group:")) {
112838
113537
  const r = await deps.groupRegistry.resolveScope(args.target_scope);
112839
113538
  if (!r) {
112840
- logger8.info("neural_send: target scope not found", { rawTargetScope: args.target_scope });
113539
+ logger9.info("neural_send: target scope not found", { rawTargetScope: args.target_scope });
112841
113540
  return {
112842
113541
  content: [{ type: "text", text: `[neural_send] \u627E\u4E0D\u5230\u7FA4\u300C${args.target_scope.slice(6)}\u300D\u3002\u8BF7\u786E\u8BA4\u7FA4\u540D\u662F\u5426\u6B63\u786E\u3002` }],
112843
113542
  isError: true
@@ -112854,7 +113553,7 @@ async function createNeuralMcpServer(deps) {
112854
113553
  cached2 = deps.groupRegistry.getById(r.groupId);
112855
113554
  }
112856
113555
  if (!cached2 || !cached2.members.includes(deps.agentId)) {
112857
- logger8.info("neural_send: not a member of target group", {
113556
+ logger9.info("neural_send: not a member of target group", {
112858
113557
  agentId: deps.agentId,
112859
113558
  groupId: r.groupId,
112860
113559
  groupName: r.groupName,
@@ -112869,7 +113568,7 @@ async function createNeuralMcpServer(deps) {
112869
113568
  isError: true
112870
113569
  };
112871
113570
  }
112872
- logger8.info("neural_send: member check passed", {
113571
+ logger9.info("neural_send: member check passed", {
112873
113572
  agentId: deps.agentId,
112874
113573
  groupId: r.groupId,
112875
113574
  groupName: r.groupName
@@ -112881,7 +113580,7 @@ async function createNeuralMcpServer(deps) {
112881
113580
  };
112882
113581
  }
112883
113582
  if (resolvedKey === currentScopeKey) {
112884
- logger8.warn("neural_send: self-send refused", { agentId: deps.agentId, scope: currentScopeKey });
113583
+ logger9.warn("neural_send: self-send refused", { agentId: deps.agentId, scope: currentScopeKey });
112885
113584
  return {
112886
113585
  content: [{ type: "text", text: "[neural_send] \u4E0D\u80FD\u628A\u6D88\u606F\u9001\u7ED9\u81EA\u5DF1\u5F53\u524D\u6240\u5728\u7684 scope\u3002" }],
112887
113586
  isError: true
@@ -112899,7 +113598,7 @@ async function createNeuralMcpServer(deps) {
112899
113598
  if (sendHistory.length >= NEURAL_DEDUP_MAX_REPEATS) {
112900
113599
  sendHistory.push(nowTs);
112901
113600
  recentNeuralSends.set(dedupKey, sendHistory);
112902
- logger8.warn("neural_send: identical message throttled (repetition guard)", {
113601
+ logger9.warn("neural_send: identical message throttled (repetition guard)", {
112903
113602
  agentId: deps.agentId,
112904
113603
  fromScope: currentScopeKey,
112905
113604
  toScope: resolvedKey,
@@ -112928,7 +113627,7 @@ async function createNeuralMcpServer(deps) {
112928
113627
  });
112929
113628
  sendHistory.push(nowTs);
112930
113629
  recentNeuralSends.set(dedupKey, sendHistory);
112931
- logger8.info("neural_send delivered", {
113630
+ logger9.info("neural_send delivered", {
112932
113631
  agentId: deps.agentId,
112933
113632
  fromScope: currentScopeKey,
112934
113633
  toScope: resolvedKey,
@@ -112939,7 +113638,7 @@ async function createNeuralMcpServer(deps) {
112939
113638
  content: [{ type: "text", text: `[neural_send] \u5DF2\u9001\u8FBE\u5230\u300C${toLabel}\u300D(scope: ${resolvedKey})\u3002` }]
112940
113639
  };
112941
113640
  } catch (err) {
112942
- logger8.error("neural_send dispatch failed", { agentId: deps.agentId, error: err });
113641
+ logger9.error("neural_send dispatch failed", { agentId: deps.agentId, error: err });
112943
113642
  return {
112944
113643
  content: [{ type: "text", text: `[neural_send] \u9001\u8FBE\u5931\u8D25\uFF1A${err.message}` }],
112945
113644
  isError: true
@@ -112965,7 +113664,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
112965
113664
  async (args) => {
112966
113665
  const action = args.action;
112967
113666
  const content = args.content;
112968
- logger8.info("self_note tool called", {
113667
+ logger9.info("self_note tool called", {
112969
113668
  agentId: deps.agentId,
112970
113669
  scope: currentScopeKey,
112971
113670
  action,
@@ -112974,7 +113673,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
112974
113673
  if (action === "read") {
112975
113674
  const current = deps.memoryStore.read(deps.agentId);
112976
113675
  if (current.length === 0) {
112977
- logger8.info("self_note read empty", {
113676
+ logger9.info("self_note read empty", {
112978
113677
  agentId: deps.agentId,
112979
113678
  scope: currentScopeKey
112980
113679
  });
@@ -112982,7 +113681,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
112982
113681
  content: [{ type: "text", text: "[self_note] \u4F60\u7684\u7B14\u8BB0\u672C\u76EE\u524D\u662F\u7A7A\u7684\u3002" }]
112983
113682
  };
112984
113683
  }
112985
- logger8.info("self_note read ok", {
113684
+ logger9.info("self_note read ok", {
112986
113685
  agentId: deps.agentId,
112987
113686
  scope: currentScopeKey,
112988
113687
  notebookBytes: current.length
@@ -112993,7 +113692,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
112993
113692
  }
112994
113693
  if (action === "append" || action === "write") {
112995
113694
  if (typeof content !== "string" || content.length === 0) {
112996
- logger8.warn("self_note missing content", {
113695
+ logger9.warn("self_note missing content", {
112997
113696
  agentId: deps.agentId,
112998
113697
  scope: currentScopeKey,
112999
113698
  action
@@ -113010,7 +113709,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113010
113709
  deps.memoryStore.write(deps.agentId, content);
113011
113710
  }
113012
113711
  const after = deps.memoryStore.read(deps.agentId);
113013
- logger8.info("self_note persisted", {
113712
+ logger9.info("self_note persisted", {
113014
113713
  agentId: deps.agentId,
113015
113714
  scope: currentScopeKey,
113016
113715
  action,
@@ -113021,14 +113720,14 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113021
113720
  content: [{ type: "text", text: `[self_note] \u5DF2${action === "append" ? "\u8FFD\u52A0" : "\u8986\u76D6"}\uFF0C\u5F53\u524D\u7B14\u8BB0\u672C\u5171 ${after.length} \u5B57\u7B26\u3002` }]
113022
113721
  };
113023
113722
  } catch (err) {
113024
- logger8.error("self_note write failed", { agentId: deps.agentId, action, error: err });
113723
+ logger9.error("self_note write failed", { agentId: deps.agentId, action, error: err });
113025
113724
  return {
113026
113725
  content: [{ type: "text", text: `[self_note] \u5199\u5165\u5931\u8D25\uFF1A${err.message}` }],
113027
113726
  isError: true
113028
113727
  };
113029
113728
  }
113030
113729
  }
113031
- logger8.warn("self_note invalid action", {
113730
+ logger9.warn("self_note invalid action", {
113032
113731
  agentId: deps.agentId,
113033
113732
  scope: currentScopeKey,
113034
113733
  action: String(action)
@@ -113047,7 +113746,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113047
113746
  \u901A\u5E38\u4F60\u4E0D\u9700\u8981\u4E3B\u52A8\u8C03\u2014\u2014\u8FD9\u4EFD\u5217\u8868\u5DF2\u7ECF\u5728\u4F60\u7684 system prompt \u9876\u90E8\u9759\u6001\u6CE8\u5165\u8FC7\u3002\u4EC5\u5728\u4F60\u6000\u7591\u5217\u8868\u8FC7\u65F6\uFF08\u6BD4\u5982\u7528\u6237\u521A\u8BF4\u81EA\u5DF1\u521A\u62C9\u4F60\u8FDB\u4E86\u4E00\u4E2A\u7FA4\uFF0C\u4F46\u4F60\u7684\u5FEB\u7167\u91CC\u6CA1\u6709\uFF09\u65F6\u5237\u65B0\u4E00\u6B21\u3002`,
113048
113747
  {},
113049
113748
  async () => {
113050
- logger8.info("neural_list_scopes tool called", {
113749
+ logger9.info("neural_list_scopes tool called", {
113051
113750
  agentId: deps.agentId,
113052
113751
  scope: currentScopeKey
113053
113752
  });
@@ -113055,7 +113754,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113055
113754
  let myGroups;
113056
113755
  if (cachedScopes && now - cachedScopes.at < SCOPES_CACHE_MS) {
113057
113756
  myGroups = cachedScopes.groups;
113058
- logger8.info("neural_list_scopes: cache hit", {
113757
+ logger9.info("neural_list_scopes: cache hit", {
113059
113758
  agentId: deps.agentId,
113060
113759
  cachedAt: cachedScopes.at,
113061
113760
  ageMs: now - cachedScopes.at
@@ -113067,7 +113766,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113067
113766
  name: g.name
113068
113767
  }));
113069
113768
  cachedScopes = { groups: myGroups, at: now };
113070
- logger8.info("neural_list_scopes: registry refreshed", {
113769
+ logger9.info("neural_list_scopes: registry refreshed", {
113071
113770
  agentId: deps.agentId,
113072
113771
  scope: currentScopeKey,
113073
113772
  myGroupCount: myGroups.length
@@ -113089,7 +113788,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113089
113788
  '\u8C03 neural_send(target_scope="...") \u65F6\u8BF7\u7528\u4E0A\u9762\u5217\u51FA\u7684 scope \u5B57\u7B26\u4E32\u3002',
113090
113789
  myGroups.length === 0 ? "\uFF08\u4F60\u4E0D\u662F\u4EFB\u4F55\u7FA4\u7684\u6210\u5458\uFF1B\u53EF\u4E0E\u7528\u6237\u5728 single \u901A\u8BDD\uFF0C\u4F46\u6682\u65F6\u6CA1\u6709\u8DE8\u7FA4\u5206\u8EAB\u53EF\u89E6\u8FBE\u3002\uFF09" : "\u82E5\u7528\u6237\u63D0\u5230\u7684\u7FA4\u540D\u4E0D\u5728\u5217\u8868\u91CC\uFF0C\u8BF4\u660E\u4F60\u4E0D\u662F\u8BE5\u7FA4\u6210\u5458\u2014\u2014\u522B\u5C1D\u8BD5 neural_send \u5230\u90A3\u4E2A\u7FA4\uFF08\u4F1A\u88AB\u62D2\uFF09\u3002"
113091
113790
  ].join("\n");
113092
- logger8.info("neural_list_scopes returned", {
113791
+ logger9.info("neural_list_scopes returned", {
113093
113792
  agentId: deps.agentId,
113094
113793
  scope: currentScopeKey,
113095
113794
  groupCount: myGroups.length
@@ -113120,7 +113819,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113120
113819
  async (args) => {
113121
113820
  const requestedScope = args.scope?.trim() || "current";
113122
113821
  const limit = Math.min(50, Math.max(1, Math.floor(args.limit ?? 20)));
113123
- logger8.info("read_chat_history tool called", {
113822
+ logger9.info("read_chat_history tool called", {
113124
113823
  agentId: deps.agentId,
113125
113824
  scope: currentScopeKey,
113126
113825
  requestedScope,
@@ -113150,7 +113849,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113150
113849
  cached2 = deps.groupRegistry.getById(r.groupId);
113151
113850
  }
113152
113851
  if (!cached2 || !cached2.members.includes(deps.agentId)) {
113153
- logger8.info("read_chat_history: membership denied", {
113852
+ logger9.info("read_chat_history: membership denied", {
113154
113853
  agentId: deps.agentId,
113155
113854
  groupId: r.groupId,
113156
113855
  requestedScope
@@ -113184,7 +113883,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113184
113883
  scopeLabel = `\u7FA4\u300C${r?.groupName ?? targetScope.groupId}\u300D`;
113185
113884
  }
113186
113885
  if (!conversationId) {
113187
- logger8.info("read_chat_history: no conversation for scope", {
113886
+ logger9.info("read_chat_history: no conversation for scope", {
113188
113887
  agentId: deps.agentId,
113189
113888
  requestedScope,
113190
113889
  scopeLabel
@@ -113198,7 +113897,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113198
113897
  };
113199
113898
  }
113200
113899
  resolvedScopeLabel = scopeLabel;
113201
- logger8.info("read_chat_history: resolved target", {
113900
+ logger9.info("read_chat_history: resolved target", {
113202
113901
  agentId: deps.agentId,
113203
113902
  requestedScope,
113204
113903
  conversationId,
@@ -113215,7 +113914,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113215
113914
  const url2 = `${base}/api/conversations/${encodeURIComponent(conversationId)}/messages?${params.toString()}`;
113216
113915
  const resp = await fetch(url2);
113217
113916
  if (!resp.ok) {
113218
- logger8.warn("read_chat_history: HTTP error", {
113917
+ logger9.warn("read_chat_history: HTTP error", {
113219
113918
  agentId: deps.agentId,
113220
113919
  status: resp.status,
113221
113920
  conversationId
@@ -113232,7 +113931,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113232
113931
  const messages = body.messages ?? [];
113233
113932
  const hasMore = body.hasMore === true;
113234
113933
  if (messages.length === 0) {
113235
- logger8.info("read_chat_history: empty result", {
113934
+ logger9.info("read_chat_history: empty result", {
113236
113935
  agentId: deps.agentId,
113237
113936
  conversationId,
113238
113937
  requestedScope
@@ -113262,7 +113961,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113262
113961
  `\u7EE7\u7EED\u7FFB\uFF1Aread_chat_history(before="${firstTs}", scope="${requestedScope}")`
113263
113962
  );
113264
113963
  }
113265
- logger8.info("read_chat_history returned", {
113964
+ logger9.info("read_chat_history returned", {
113266
113965
  agentId: deps.agentId,
113267
113966
  conversationId,
113268
113967
  scopeLabel: resolvedScopeLabel,
@@ -113273,7 +113972,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
113273
113972
  });
113274
113973
  return { content: [{ type: "text", text: lines.join("\n") }] };
113275
113974
  } catch (e) {
113276
- logger8.error("read_chat_history failed", { error: e, agentId: deps.agentId });
113975
+ logger9.error("read_chat_history failed", { error: e, agentId: deps.agentId });
113277
113976
  return {
113278
113977
  content: [{
113279
113978
  type: "text",
@@ -113300,7 +113999,7 @@ Pass either a relative path from the current working directory or an absolute pa
113300
113999
  async (args) => {
113301
114000
  const requestedPath = args.path.trim();
113302
114001
  const maxChars = args.max_chars ?? 12e4;
113303
- logger8.info("read_document tool called", {
114002
+ logger9.info("read_document tool called", {
113304
114003
  agentId: deps.agentId,
113305
114004
  scope: currentScopeKey,
113306
114005
  path: requestedPath,
@@ -113322,7 +114021,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113322
114021
  warningText,
113323
114022
  result.markdown
113324
114023
  ].filter((line) => line.length > 0).join("\n");
113325
- logger8.info("read_document returned", {
114024
+ logger9.info("read_document returned", {
113326
114025
  agentId: deps.agentId,
113327
114026
  scope: currentScopeKey,
113328
114027
  path: result.path,
@@ -113333,7 +114032,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113333
114032
  return { content: [{ type: "text", text }] };
113334
114033
  } catch (e) {
113335
114034
  const message = e instanceof Error ? e.message : String(e);
113336
- logger8.error("read_document failed", {
114035
+ logger9.error("read_document failed", {
113337
114036
  agentId: deps.agentId,
113338
114037
  scope: currentScopeKey,
113339
114038
  path: requestedPath,
@@ -113371,7 +114070,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113371
114070
  if (!resolved.ok) {
113372
114071
  return { content: [{ type: "text", text: resolved.text }], isError: true };
113373
114072
  }
113374
- logger8.info("create_group_issue tool called", {
114073
+ logger9.info("create_group_issue tool called", {
113375
114074
  agentId: deps.agentId,
113376
114075
  scope: currentScopeKey,
113377
114076
  groupId: resolved.groupId,
@@ -113386,7 +114085,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113386
114085
  (issue2) => issue2.status === "open" && issue2.title.trim() === title
113387
114086
  );
113388
114087
  if (duplicate) {
113389
- logger8.info("create_group_issue: duplicate open issue reused", {
114088
+ logger9.info("create_group_issue: duplicate open issue reused", {
113390
114089
  agentId: deps.agentId,
113391
114090
  groupId: resolved.groupId,
113392
114091
  issueId: duplicate.id,
@@ -113415,7 +114114,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113415
114114
  });
113416
114115
  if (!res.ok) {
113417
114116
  const errText = await res.text().catch(() => "");
113418
- logger8.warn("create_group_issue: server rejected", {
114117
+ logger9.warn("create_group_issue: server rejected", {
113419
114118
  agentId: deps.agentId,
113420
114119
  groupId: resolved.groupId,
113421
114120
  status: res.status,
@@ -113427,7 +114126,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113427
114126
  };
113428
114127
  }
113429
114128
  const payload = await res.json();
113430
- logger8.info("create_group_issue: created", {
114129
+ logger9.info("create_group_issue: created", {
113431
114130
  agentId: deps.agentId,
113432
114131
  groupId: resolved.groupId,
113433
114132
  issueId: payload.issue?.id,
@@ -113440,7 +114139,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113440
114139
  }]
113441
114140
  };
113442
114141
  } catch (e) {
113443
- logger8.error("create_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
114142
+ logger9.error("create_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
113444
114143
  return {
113445
114144
  content: [{ type: "text", text: `[create_group_issue] \u521B\u5EFA\u5931\u8D25\uFF1A${e.message}` }],
113446
114145
  isError: true
@@ -113469,7 +114168,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113469
114168
  if (!resolved.ok) {
113470
114169
  return { content: [{ type: "text", text: resolved.text }], isError: true };
113471
114170
  }
113472
- logger8.info("resolve_group_issue tool called", {
114171
+ logger9.info("resolve_group_issue tool called", {
113473
114172
  agentId: deps.agentId,
113474
114173
  scope: currentScopeKey,
113475
114174
  groupId: resolved.groupId,
@@ -113514,7 +114213,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113514
114213
  );
113515
114214
  if (!res.ok) {
113516
114215
  const errText = await res.text().catch(() => "");
113517
- logger8.warn("resolve_group_issue: server rejected", {
114216
+ logger9.warn("resolve_group_issue: server rejected", {
113518
114217
  agentId: deps.agentId,
113519
114218
  groupId: resolved.groupId,
113520
114219
  issueId,
@@ -113527,7 +114226,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113527
114226
  };
113528
114227
  }
113529
114228
  const payload = await res.json();
113530
- logger8.info("resolve_group_issue: resolved", {
114229
+ logger9.info("resolve_group_issue: resolved", {
113531
114230
  agentId: deps.agentId,
113532
114231
  groupId: resolved.groupId,
113533
114232
  issueId: payload.issue?.id ?? issueId
@@ -113539,7 +114238,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113539
114238
  }]
113540
114239
  };
113541
114240
  } catch (e) {
113542
- logger8.error("resolve_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, issueId });
114241
+ logger9.error("resolve_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, issueId });
113543
114242
  return {
113544
114243
  content: [{ type: "text", text: `[resolve_group_issue] \u5173\u95ED\u5931\u8D25\uFF1A${e.message}` }],
113545
114244
  isError: true
@@ -113562,7 +114261,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
113562
114261
  if (!resolved.ok) {
113563
114262
  return { content: [{ type: "text", text: resolved.text }], isError: true };
113564
114263
  }
113565
- logger8.info("list_group_tasks tool called", {
114264
+ logger9.info("list_group_tasks tool called", {
113566
114265
  agentId: deps.agentId,
113567
114266
  scope: currentScopeKey,
113568
114267
  groupId: resolved.groupId,
@@ -113586,7 +114285,7 @@ ${body}`
113586
114285
  }]
113587
114286
  };
113588
114287
  } catch (e) {
113589
- logger8.error("list_group_tasks failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
114288
+ logger9.error("list_group_tasks failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
113590
114289
  return {
113591
114290
  content: [{ type: "text", text: `[list_group_tasks] \u67E5\u8BE2\u5931\u8D25\uFF1A${e.message}` }],
113592
114291
  isError: true
@@ -113615,7 +114314,7 @@ ${body}`
113615
114314
  if (!resolved.ok) {
113616
114315
  return { content: [{ type: "text", text: resolved.text }], isError: true };
113617
114316
  }
113618
- logger8.info("update_group_task tool called", {
114317
+ logger9.info("update_group_task tool called", {
113619
114318
  agentId: deps.agentId,
113620
114319
  scope: currentScopeKey,
113621
114320
  groupId: resolved.groupId,
@@ -113658,7 +114357,7 @@ ${body}`
113658
114357
  );
113659
114358
  if (!res.ok) {
113660
114359
  const errText = await res.text().catch(() => "");
113661
- logger8.warn("update_group_task: server rejected", {
114360
+ logger9.warn("update_group_task: server rejected", {
113662
114361
  agentId: deps.agentId,
113663
114362
  groupId: resolved.groupId,
113664
114363
  itemId,
@@ -113672,7 +114371,7 @@ ${body}`
113672
114371
  };
113673
114372
  }
113674
114373
  const payload = await res.json();
113675
- logger8.info("update_group_task: updated", {
114374
+ logger9.info("update_group_task: updated", {
113676
114375
  agentId: deps.agentId,
113677
114376
  groupId: resolved.groupId,
113678
114377
  itemId: payload.item?.id ?? itemId,
@@ -113685,7 +114384,7 @@ ${body}`
113685
114384
  }]
113686
114385
  };
113687
114386
  } catch (e) {
113688
- logger8.error("update_group_task failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, itemId, status });
114387
+ logger9.error("update_group_task failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, itemId, status });
113689
114388
  return {
113690
114389
  content: [{ type: "text", text: `[update_group_task] \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}` }],
113691
114390
  isError: true
@@ -113700,18 +114399,18 @@ ${body}`
113700
114399
  \u8FD4\u56DE\u7ED3\u6784\u662F\u4E00\u6BB5 Markdown\uFF1A\u6BCF\u4E00\u6761\u542B id / \u540D\u5B57 / \u89D2\u8272 / \u673A\u5668\u5F52\u5C5E\u3002\u4F1A\u6807\u6CE8\u54EA\u4E00\u6761\u662F"\u4F60\u81EA\u5DF1"\uFF0C\u4EE5\u53CA\u4F60\u548C\u54EA\u4E9B Agent \u5DF2\u7ECF\u5171\u5728\u67D0\u4E2A\u7FA4\u91CC\u3002\u4EBA\u7C7B\u7528\u6237\u4F1A\u5E26 (\u4EBA\u7C7B) \u6807\u8BB0\u3002
113701
114400
  \u901A\u5E38\u4F60\u5728\u7528\u6237\u63D0\u5230\u5177\u4F53\u540C\u4E8B\u59D3\u540D\u3001\u6216\u601D\u8003"\u8BE5\u62C9\u8C01\u8FDB\u7FA4\u534F\u4F5C"\u65F6\u8C03\u4E00\u6B21\uFF1B\u4E0D\u8981\u6BCF\u8F6E\u90FD\u67E5\u3002
113702
114401
  \u652F\u6301 filter\uFF08\u6309\u540D\u5B57\u6216\u89D2\u8272\u6A21\u7CCA\u641C\u7D22\uFF09\u548C limit\uFF08\u9650\u5236\u8FD4\u56DE\u6761\u6570\uFF09\u53C2\u6570\u3002
113703
- Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\u53C2\u8003"\u53EF\u7528\u673A\u5668"\u91CC\u7684 bridgeKey\uFF0C\u7ED9 create_agent / update_agent_profile \u4F20 machine_bridge_key\uFF1B\u7701\u7565\u5219\u4F7F\u7528\u5F53\u524D Bridge \u6216\u4FDD\u7559\u539F\u504F\u597D\u3002
114402
+ Smith \u521B\u5EFA Agent \u65F6\u9ED8\u8BA4\u4E0D\u8981\u4F20 machine_bridge_key\uFF1B\u7701\u7565\u5373\u4F7F\u7528\u5F53\u524D Bridge\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u6307\u5B9A\u67D0\u53F0\u673A\u5668\u65F6\uFF0C\u624D\u53C2\u8003"\u53EF\u7528\u673A\u5668"\u91CC\u7684 bridgeKey\uFF0C\u5E76\u4F18\u5148\u901A\u8FC7 update_agent_profile \u5207\u6362\u3002
113704
114403
  \u8981\u628A\u4EBA\u7C7B\u62C9\u8FDB\u7FA4\uFF1A\u5728 create_group / add_to_group \u7684 member_ids / agent_ids \u91CC\u5E26\u4E0A**\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id**\uFF08\u5373\u5217\u8868\u91CC\u5E26"(\u4EBA\u7C7B)"\u6807\u8BB0\u7684\u90A3\u4E00\u6761\uFF1B\u591A\u7528\u6237\u6A21\u5F0F\u4E0B\u6BCF\u4E2A\u7528\u6237\u90FD\u6709\u81EA\u5DF1\u72EC\u7ACB\u7684 id\uFF0C\u4F8B\u5982 agt_usr_XXX\uFF1B\u8001\u7684\u5355\u7528\u6237\u6A21\u5F0F\u4E0B\u662F agt_usr_self\uFF09\u3002\u4E0D\u8981\u786C\u7F16\u7801 agt_usr_self\u2014\u2014\u4EE5 list_contacts \u5B9E\u9645\u8FD4\u56DE\u7684 id \u4E3A\u51C6\u3002`,
113705
114404
  {
113706
114405
  filter: external_exports.string().optional().describe("\u53EF\u9009\u3002\u6309\u540D\u5B57\u6216\u89D2\u8272\u6A21\u7CCA\u8FC7\u6EE4\uFF08\u4E0D\u533A\u5206\u5927\u5C0F\u5199\uFF09\u3002"),
113707
114406
  limit: external_exports.number().int().min(1).max(200).optional().describe("\u6700\u591A\u8FD4\u56DE\u591A\u5C11\u6761\uFF0C\u9ED8\u8BA4\u4E0D\u9650\u3002")
113708
114407
  },
113709
114408
  async (args) => {
113710
- logger8.info("list_contacts tool called", { agentId: deps.agentId, scope: currentScopeKey });
114409
+ logger9.info("list_contacts tool called", { agentId: deps.agentId, scope: currentScopeKey });
113711
114410
  try {
113712
114411
  await deps.agentRegistry.refresh();
113713
114412
  } catch (e) {
113714
- logger8.warn("list_contacts: registry refresh failed, using cache", {
114413
+ logger9.warn("list_contacts: registry refresh failed, using cache", {
113715
114414
  agentId: deps.agentId,
113716
114415
  error: e
113717
114416
  });
@@ -113758,16 +114457,16 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113758
114457
  const onlineMachines = machines.filter((machine) => machine.status === "online");
113759
114458
  const offlineMachines = machines.filter((machine) => machine.status !== "online");
113760
114459
  const machineSection = machines.length > 0 ? [
113761
- "\u5728\u7EBF\u673A\u5668\uFF08\u63A8\u8350\uFF1Bcreate_agent / update_agent_profile \u53EA\u80FD\u4F20\u8FD9\u4E9B machine_bridge_key\uFF1B\u7701\u7565\u5219\u4F7F\u7528\u5F53\u524D Bridge \u6216\u4FDD\u7559\u539F\u504F\u597D\uFF09\uFF1A",
114460
+ "\u53EF\u7528\u673A\u5668\uFF08\u4EC5\u5728\u7528\u6237\u660E\u786E\u6307\u5B9A\u8FD0\u884C\u7535\u8111\u65F6\u4F7F\u7528\uFF1B\u666E\u901A create_agent \u4E0D\u8981\u4F20 machine_bridge_key\uFF0C\u7701\u7565\u5373\u5F53\u524D\u673A\u5668\uFF09\uFF1A",
113762
114461
  ...onlineMachines.length > 0 ? onlineMachines.map(formatMachineOptionLine) : ["- \u5F53\u524D\u6CA1\u6709\u5728\u7EBF\u673A\u5668\uFF1B\u53EF\u7701\u7565 machine_bridge_key\uFF0C\u8BA9\u5F53\u524D Bridge \u515C\u5E95\u3002"],
113763
114462
  ...offlineMachines.length > 0 ? [
113764
114463
  "",
113765
114464
  "\u79BB\u7EBF/\u4E0D\u53EF\u76F4\u63A5\u7528\u4E8E\u65B0\u5EFA\u7684\u673A\u5668\uFF08\u4E0D\u8981\u628A\u8FD9\u4E9B bridgeKey \u4F20\u7ED9 create_agent\uFF1B\u5426\u5219\u4EFB\u52A1\u4F1A Bridge offline\uFF09\uFF1A",
113766
114465
  ...offlineMachines.map(formatMachineOptionLine)
113767
114466
  ] : []
113768
- ].join("\n") : "\u53EF\u7528\u673A\u5668\uFF1A\u5F53\u524D Bridge\uFF08create_agent \u7701\u7565 machine_bridge_key \u5373\u4F7F\u7528\u5F53\u524D Bridge\uFF1Bupdate_agent_profile \u7701\u7565\u5373\u4FDD\u7559\u539F\u504F\u597D\uFF09\u3002";
114467
+ ].join("\n") : "\u53EF\u7528\u673A\u5668\uFF1A\u5F53\u524D Bridge\uFF08\u666E\u901A create_agent \u7701\u7565 machine_bridge_key \u5373\u4F7F\u7528\u5F53\u524D\u673A\u5668\uFF1Bupdate_agent_profile \u7701\u7565\u5373\u4FDD\u7559\u539F\u504F\u597D\uFF09\u3002";
113769
114468
  const text = shown === 0 ? q ? `\u672A\u627E\u5230\u4E0E "${args?.filter}" \u5339\u914D\u7684\u8054\u7CFB\u4EBA\u3002` : "\u5F53\u524D\u7CFB\u7EDF\u91CC\u8FD8\u6CA1\u6709\u4EFB\u4F55 Agent\u3002" : [header, "", machineSection, "", ...lines].join("\n");
113770
- logger8.info("list_contacts returned", {
114469
+ logger9.info("list_contacts returned", {
113771
114470
  agentId: deps.agentId,
113772
114471
  count: all.length,
113773
114472
  humanCount,
@@ -113830,7 +114529,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113830
114529
  }
113831
114530
  const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim().replaceAll(USR_SELF_ID, resolveMyHuman(deps.agentRegistry, deps.agentId)) : "";
113832
114531
  const hasInitial = initialMessage.length > 0;
113833
- logger8.info("create_group tool called", {
114532
+ logger9.info("create_group tool called", {
113834
114533
  agentId: deps.agentId,
113835
114534
  name: trimmedName,
113836
114535
  memberCount: dedup.length,
@@ -113861,7 +114560,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113861
114560
  });
113862
114561
  if (!res.ok) {
113863
114562
  const errText = await res.text().catch(() => "");
113864
- logger8.warn("create_group: server rejected", { status: res.status, errText });
114563
+ logger9.warn("create_group: server rejected", { status: res.status, errText });
113865
114564
  return {
113866
114565
  content: [{ type: "text", text: `[create_group] \u670D\u52A1\u7AEF\u62D2\u7EDD\uFF08${res.status}\uFF09\uFF1A${errText || "(no body)"}` }],
113867
114566
  isError: true
@@ -113869,7 +114568,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113869
114568
  }
113870
114569
  const group = await res.json();
113871
114570
  const groupScopeKey = `group:${group.id}`;
113872
- logger8.info("create_group: created", {
114571
+ logger9.info("create_group: created", {
113873
114572
  agentId: deps.agentId,
113874
114573
  groupId: group.id,
113875
114574
  name: group.name,
@@ -113897,7 +114596,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113897
114596
  }]
113898
114597
  };
113899
114598
  } catch (e) {
113900
- logger8.error("create_group failed", { error: e, name: trimmedName });
114599
+ logger9.error("create_group failed", { error: e, name: trimmedName });
113901
114600
  return {
113902
114601
  content: [{ type: "text", text: `[create_group] \u5EFA\u7FA4\u5931\u8D25\uFF1A${e.message}` }],
113903
114602
  isError: true
@@ -113954,7 +114653,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113954
114653
  const scopeInput = rawGroup.startsWith("group:") ? rawGroup : `group:${rawGroup}`;
113955
114654
  const resolved = await deps.groupRegistry.resolveScope(scopeInput);
113956
114655
  if (!resolved) {
113957
- logger8.info("add_to_group: group not found", { rawGroup, scopeInput });
114656
+ logger9.info("add_to_group: group not found", { rawGroup, scopeInput });
113958
114657
  return {
113959
114658
  content: [{ type: "text", text: `[add_to_group] \u627E\u4E0D\u5230\u7FA4\u300C${rawGroup}\u300D\u3002\u53EF\u8C03 neural_list_scopes() \u67E5\u770B\u4F60\u7684\u7FA4\u5217\u8868\u3002` }],
113960
114659
  isError: true
@@ -113966,7 +114665,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113966
114665
  cached2 = deps.groupRegistry.getById(resolved.groupId);
113967
114666
  }
113968
114667
  if (!cached2 || !cached2.members.includes(deps.agentId)) {
113969
- logger8.info("add_to_group: not a member of target group", {
114668
+ logger9.info("add_to_group: not a member of target group", {
113970
114669
  agentId: deps.agentId,
113971
114670
  groupId: resolved.groupId,
113972
114671
  groupName: resolved.groupName
@@ -113982,7 +114681,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113982
114681
  const alreadyIn = agentIds.filter((id) => cached2.members.includes(id));
113983
114682
  const toAdd = agentIds.filter((id) => !cached2.members.includes(id));
113984
114683
  if (toAdd.length === 0) {
113985
- logger8.info("add_to_group: all agents already in group", {
114684
+ logger9.info("add_to_group: all agents already in group", {
113986
114685
  agentId: deps.agentId,
113987
114686
  groupId: resolved.groupId,
113988
114687
  alreadyIn
@@ -113994,7 +114693,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
113994
114693
  }]
113995
114694
  };
113996
114695
  }
113997
- logger8.info("add_to_group tool called", {
114696
+ logger9.info("add_to_group tool called", {
113998
114697
  agentId: deps.agentId,
113999
114698
  groupId: resolved.groupId,
114000
114699
  groupName: resolved.groupName,
@@ -114010,7 +114709,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114010
114709
  });
114011
114710
  if (!res.ok) {
114012
114711
  const errText = await res.text().catch(() => "");
114013
- logger8.warn("add_to_group: server rejected", {
114712
+ logger9.warn("add_to_group: server rejected", {
114014
114713
  status: res.status,
114015
114714
  errText,
114016
114715
  groupId: resolved.groupId,
@@ -114025,7 +114724,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114025
114724
  const a = deps.agentRegistry.getById(id);
114026
114725
  return a ? a.name : id;
114027
114726
  });
114028
- logger8.info("add_to_group: members added", {
114727
+ logger9.info("add_to_group: members added", {
114029
114728
  agentId: deps.agentId,
114030
114729
  groupId: resolved.groupId,
114031
114730
  groupName: resolved.groupName,
@@ -114044,7 +114743,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114044
114743
  }]
114045
114744
  };
114046
114745
  } catch (e) {
114047
- logger8.error("add_to_group failed", {
114746
+ logger9.error("add_to_group failed", {
114048
114747
  error: e,
114049
114748
  groupId: resolved.groupId,
114050
114749
  toAdd
@@ -114091,13 +114790,13 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114091
114790
  cached2 = deps.groupRegistry.getById(resolved.groupId);
114092
114791
  }
114093
114792
  if (!cached2 || !cached2.members.includes(deps.agentId)) {
114094
- logger8.info("leave_group: not a member", { agentId: deps.agentId, groupId: resolved.groupId });
114793
+ logger9.info("leave_group: not a member", { agentId: deps.agentId, groupId: resolved.groupId });
114095
114794
  return {
114096
114795
  content: [{ type: "text", text: `[leave_group] \u4F60\u4E0D\u5728\u7FA4\u300C${resolved.groupName}\u300D\u91CC\uFF0C\u65E0\u9700\u9000\u51FA\u3002` }],
114097
114796
  isError: true
114098
114797
  };
114099
114798
  }
114100
- logger8.info("leave_group tool called", {
114799
+ logger9.info("leave_group tool called", {
114101
114800
  agentId: deps.agentId,
114102
114801
  groupId: resolved.groupId,
114103
114802
  groupName: resolved.groupName
@@ -114110,13 +114809,13 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114110
114809
  });
114111
114810
  if (!res.ok) {
114112
114811
  const errText = await res.text().catch(() => "");
114113
- logger8.warn("leave_group: server rejected", { status: res.status, errText, groupId: resolved.groupId });
114812
+ logger9.warn("leave_group: server rejected", { status: res.status, errText, groupId: resolved.groupId });
114114
114813
  return {
114115
114814
  content: [{ type: "text", text: `[leave_group] \u670D\u52A1\u7AEF\u62D2\u7EDD\uFF08${res.status}\uFF09\uFF1A${errText || "(no body)"}` }],
114116
114815
  isError: true
114117
114816
  };
114118
114817
  }
114119
- logger8.info("leave_group: succeeded", {
114818
+ logger9.info("leave_group: succeeded", {
114120
114819
  agentId: deps.agentId,
114121
114820
  groupId: resolved.groupId,
114122
114821
  groupName: resolved.groupName
@@ -114131,7 +114830,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114131
114830
  }]
114132
114831
  };
114133
114832
  } catch (e) {
114134
- logger8.error("leave_group failed", { error: e, groupId: resolved.groupId });
114833
+ logger9.error("leave_group failed", { error: e, groupId: resolved.groupId });
114135
114834
  return {
114136
114835
  content: [{ type: "text", text: `[leave_group] \u9000\u7FA4\u5931\u8D25\uFF1A${e.message}` }],
114137
114836
  isError: true
@@ -114187,7 +114886,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114187
114886
  };
114188
114887
  }
114189
114888
  if (cached2.createdBy == null) {
114190
- logger8.info("remove_from_group: ownerless group rejected", { agentId: deps.agentId, groupId: resolved.groupId });
114889
+ logger9.info("remove_from_group: ownerless group rejected", { agentId: deps.agentId, groupId: resolved.groupId });
114191
114890
  return {
114192
114891
  content: [{ type: "text", text: `[remove_from_group] \u7FA4\u300C${resolved.groupName}\u300D\u6CA1\u6709\u7FA4\u4E3B\uFF08\u539F\u7FA4\u4E3B\u5DF2\u9000\u7FA4\uFF09\uFF0C\u6CA1\u4EBA\u80FD\u8E22\u6210\u5458\u3002` }],
114193
114892
  isError: true
@@ -114196,7 +114895,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114196
114895
  if (cached2.createdBy !== deps.agentId) {
114197
114896
  const ownerInfo = deps.agentRegistry.getById(cached2.createdBy);
114198
114897
  const ownerLabel = ownerInfo ? `${ownerInfo.name} (${cached2.createdBy})` : cached2.createdBy;
114199
- logger8.info("remove_from_group: not owner", {
114898
+ logger9.info("remove_from_group: not owner", {
114200
114899
  agentId: deps.agentId,
114201
114900
  groupId: resolved.groupId,
114202
114901
  ownerId: cached2.createdBy
@@ -114234,7 +114933,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114234
114933
  }]
114235
114934
  };
114236
114935
  }
114237
- logger8.info("remove_from_group tool called", {
114936
+ logger9.info("remove_from_group tool called", {
114238
114937
  agentId: deps.agentId,
114239
114938
  groupId: resolved.groupId,
114240
114939
  groupName: resolved.groupName,
@@ -114264,7 +114963,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114264
114963
  const a = deps.agentRegistry.getById(id);
114265
114964
  return a ? a.name : id;
114266
114965
  });
114267
- logger8.info("remove_from_group: completed", {
114966
+ logger9.info("remove_from_group: completed", {
114268
114967
  agentId: deps.agentId,
114269
114968
  groupId: resolved.groupId,
114270
114969
  removedCount: removed.length,
@@ -114305,7 +115004,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114305
115004
  }
114306
115005
  const latestReadableSkillNames = currentReadableSkillNames();
114307
115006
  if (!latestReadableSkillNames.includes(name)) {
114308
- logger8.warn("read_skill: not readable for agent", {
115007
+ logger9.warn("read_skill: not readable for agent", {
114309
115008
  agentId: deps.agentId,
114310
115009
  isSmith: deps.isSmith,
114311
115010
  name,
@@ -114319,7 +115018,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114319
115018
  isError: true
114320
115019
  };
114321
115020
  }
114322
- logger8.info("read_skill tool called", { agentId: deps.agentId, scope: currentScopeKey, name });
115021
+ logger9.info("read_skill tool called", { agentId: deps.agentId, scope: currentScopeKey, name });
114323
115022
  const content = deps.skillStore.read(name);
114324
115023
  if (!content) {
114325
115024
  return {
@@ -114330,7 +115029,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114330
115029
  isError: true
114331
115030
  };
114332
115031
  }
114333
- logger8.info("read_skill returned", { agentId: deps.agentId, name, bytes: content.length });
115032
+ logger9.info("read_skill returned", { agentId: deps.agentId, name, bytes: content.length });
114334
115033
  return { content: [{ type: "text", text: content }] };
114335
115034
  },
114336
115035
  {}
@@ -114339,7 +115038,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114339
115038
  "list_available_skills",
114340
115039
  `\u5217\u51FA\u5F53\u524D Agent \u6B64\u523B\u53EF\u76F4\u63A5\u6309\u4EFB\u52A1\u4F7F\u7528\u7684 skill\u3002
114341
115040
  \u666E\u901A Agent \u9009\u62E9 skill \u65F6\u5FC5\u987B\u5148\u8C03\u7528\u5B83\uFF1B\u4F18\u5148\u7528\u5B83\u56DE\u7B54"\u6211\u73B0\u5728\u80FD\u7528\u4EC0\u4E48 skill"\u548C\u4EFB\u52A1\u5F00\u59CB\u524D\u7684 skill \u9009\u62E9\u95EE\u9898\u3002
114342
- \u53EA\u8FD4\u56DE\u8F7B\u91CF\u6458\u8981\u3001\u6743\u9650\u3001\u6765\u6E90\u548C\u8FD0\u884C\u72B6\u6001\uFF1B\u4E0D\u8FD4\u56DE\u5B8C\u6574\u65B9\u6CD5\u5B66\u3002\u53EA\u5305\u542B\u5DF2\u7ECF\u843D\u5230\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u5BF9\u5F53\u524D Agent \u53EF\u89C1\u7684 skill\u3002\u59CB\u7EC8\u53EA\u8FD4\u56DE runtimeAvailability=available\uFF1B\u4E0D\u4F1A\u8FD4\u56DE unavailable\u3001planned \u6216 smith_only\u3002include_unavailable \u662F\u65E7\u5BA2\u6237\u7AEF\u517C\u5BB9\u53C2\u6570\uFF0C\u5DF2\u5FFD\u7565\u3002
115041
+ \u53EA\u8FD4\u56DE\u8F7B\u91CF\u6458\u8981\u3001\u6743\u9650\u3001\u6765\u6E90\u548C\u8FD0\u884C\u72B6\u6001\uFF1B\u4E0D\u8FD4\u56DE\u5B8C\u6574\u65B9\u6CD5\u5B66\u3002Skill \u662F AHChat \u7684\u65B9\u6CD5\u5B66/\u6D41\u7A0B\u63D0\u793A\uFF0C\u4E0D\u662F\u53EF\u8C03\u7528 SDK \u5DE5\u5177\uFF1B\u4E0D\u8981\u8C03\u7528\u540D\u4E3A Skill \u7684\u901A\u7528\u5DE5\u5177\uFF0C\u4E5F\u4E0D\u8981\u628A\u8FD9\u91CC\u7684 skill \u540D\u79F0\u6216 ID \u586B\u8FDB tool \u53C2\u6570\u3002\u53EA\u5305\u542B\u5DF2\u7ECF\u843D\u5230\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u5BF9\u5F53\u524D Agent \u53EF\u89C1\u7684 skill\u3002\u59CB\u7EC8\u53EA\u8FD4\u56DE runtimeAvailability=available\uFF1B\u4E0D\u4F1A\u8FD4\u56DE unavailable\u3001planned \u6216 smith_only\u3002include_unavailable \u662F\u65E7\u5BA2\u6237\u7AEF\u517C\u5BB9\u53C2\u6570\uFF0C\u5DF2\u5FFD\u7565\u3002
114343
115042
  \u5982\u679C\u8FD9\u91CC\u6CA1\u6709\u5339\u914D\u9879\uFF0C\u624D\u7528 list_skill_index \u67E5\u5019\u9009\u3002\u82E5 list_skill_index \u627E\u5230\u4E86\u5408\u9002\u4F46\u672A\u5206\u914D\u7684\u5019\u9009\uFF0C\u5FC5\u987B\u8C03\u7528 AskUserQuestion \u5DE5\u5177\u8BE2\u95EE\u7528\u6237\u662F\u5426\u8981\u4E3A\u5F53\u524D Agent \u542F\u7528/\u5206\u914D\uFF1B\u95EE\u9898 metadata \u5C3D\u91CF\u5E26\u4E0A skillId/skillName\uFF1B\u4E0D\u8981\u7528\u666E\u901A\u6587\u672C\u63D0\u95EE\uFF0C\u4E5F\u4E0D\u8981\u76F4\u63A5\u5047\u88C5\u8C03\u7528\u3002`,
114344
115043
  {
114345
115044
  query: external_exports.string().optional().describe("\u53EF\u9009\u3002\u6309 skill \u540D\u79F0\u3001\u6458\u8981\u6216\u5173\u952E\u8BCD\u641C\u7D22\u5F53\u524D\u53EF\u7528 skill\u3002"),
@@ -114359,14 +115058,14 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114359
115058
  entries: runtimeEntries,
114360
115059
  runtime: skillRuntimeContext(deps.officeCliRuntime)
114361
115060
  }), visibleSkillIds), availableSkillIds);
114362
- logger8.info("list_available_skills tool called", {
115061
+ logger9.info("list_available_skills tool called", {
114363
115062
  agentId: deps.agentId,
114364
115063
  scope: currentScopeKey,
114365
115064
  resultCount: entries.length,
114366
115065
  agentScoped: Boolean(availableSkillIds)
114367
115066
  });
114368
115067
  const text = entries.length > 0 ? entries.map((entry, index) => formatSkillEntry(entry, index)).join("\n") : "\u5F53\u524D\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u53EF\u7528 skill\u3002";
114369
- const scopeRule = deps.isSmith ? "\u89C4\u5219\uFF1ASmith \u662F\u7CFB\u7EDF\u7EC4\u7EC7\u8005\uFF0C\u7ED3\u679C\u5305\u542B\u5F53\u524D\u7528\u6237\u53EF\u89C1\u4E14\u5DF2\u5B89\u88C5/\u5DF2\u542F\u7528\u3001\u5DF2\u843D\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u53EF\u8FD0\u884C\u7684\u8F7B\u91CF skill \u6458\u8981\uFF1B\u4E0D\u662F\u5B8C\u6574\u65B9\u6CD5\u5B66\u3002\u53EA\u6709 summary\u3001taskTypes\u3001outputs \u4E0E\u7528\u6237\u76EE\u6807\u5339\u914D\u65F6\u624D\u4F7F\u7528\u3002" : '\u89C4\u5219\uFF1A\u8FD9\u4E9B\u7ED3\u679C\u53EA\u5305\u542B\u5F53\u524D Agent \u5DF2\u5206\u914D/\u672C\u673A Local \u5DF2\u7ED1\u5B9A\u3001\u5DF2\u843D\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u53EF\u8FD0\u884C\u7684\u8F7B\u91CF skill \u6458\u8981\uFF0C\u4E0D\u662F\u5B8C\u6574\u65B9\u6CD5\u5B66\u3002\u53EA\u6709 summary\u3001taskTypes\u3001outputs \u4E0E\u7528\u6237\u76EE\u6807\u5339\u914D\u65F6\u624D\u4F7F\u7528\uFF1B\u5982\u679C\u6CA1\u6709\u5339\u914D\u9879\uFF0C\u5C31\u76F4\u63A5\u5B8C\u6210\u4EFB\u52A1\uFF0C\u6216\u7528 list_skill_index \u641C\u7D22\u5019\u9009\uFF0C\u5E76\u8C03\u7528 AskUserQuestion \u5DE5\u5177\u8BE2\u95EE\u7528\u6237\u662F\u5426\u8981\u4E3A\u5F53\u524D Agent \u542F\u7528/\u5206\u914D\u8BE5 skill\u3002AskUserQuestion \u9009\u9879\u5FC5\u987B\u5305\u542B"\u542F\u7528/\u5206\u914D\u8FD9\u4E2A skill"\u548C"\u5148\u4E0D\u7528\uFF0C\u76F4\u63A5\u5904\u7406"\uFF0Cmetadata \u5C3D\u91CF\u5E26\u4E0A skillId/skillName\u3002\u7528\u6237\u786E\u8BA4\u524D\u4E0D\u8981\u58F0\u79F0\u5DF2\u4F7F\u7528\u672A\u5206\u914D skill\uFF1B\u786E\u8BA4\u540E\u5FC5\u987B\u91CD\u65B0\u67E5\u8BE2\u672C\u5DE5\u5177\uFF0C\u53EA\u6709\u51FA\u73B0\u5728\u8FD9\u91CC\u624D\u7B97\u53EF\u7528\u3002';
115068
+ const scopeRule = deps.isSmith ? "\u89C4\u5219\uFF1ASmith \u662F\u7CFB\u7EDF\u7EC4\u7EC7\u8005\uFF0C\u7ED3\u679C\u5305\u542B\u5F53\u524D\u7528\u6237\u53EF\u89C1\u4E14\u5DF2\u5B89\u88C5/\u5DF2\u542F\u7528\u3001\u5DF2\u843D\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u53EF\u8FD0\u884C\u7684\u8F7B\u91CF skill \u6458\u8981\uFF1B\u4E0D\u662F\u5B8C\u6574\u65B9\u6CD5\u5B66\uFF0C\u4E5F\u4E0D\u662F\u53EF\u8C03\u7528 SDK \u5DE5\u5177\u3002\u53EA\u6709 summary\u3001taskTypes\u3001outputs \u4E0E\u7528\u6237\u76EE\u6807\u5339\u914D\u65F6\u624D\u4F7F\u7528\uFF1B\u4E0D\u8981\u8C03\u7528\u540D\u4E3A Skill \u7684\u901A\u7528\u5DE5\u5177\u3002" : '\u89C4\u5219\uFF1A\u8FD9\u4E9B\u7ED3\u679C\u53EA\u5305\u542B\u5F53\u524D Agent \u5DF2\u5206\u914D/\u672C\u673A Local \u5DF2\u7ED1\u5B9A\u3001\u5DF2\u843D\u5F53\u524D\u673A\u5668 runtime cache \u4E14\u53EF\u8FD0\u884C\u7684\u8F7B\u91CF skill \u6458\u8981\uFF0C\u4E0D\u662F\u5B8C\u6574\u65B9\u6CD5\u5B66\uFF0C\u4E5F\u4E0D\u662F\u53EF\u8C03\u7528 SDK \u5DE5\u5177\uFF1B\u4E0D\u8981\u8C03\u7528\u540D\u4E3A Skill \u7684\u901A\u7528\u5DE5\u5177\u3002\u53EA\u6709 summary\u3001taskTypes\u3001outputs \u4E0E\u7528\u6237\u76EE\u6807\u5339\u914D\u65F6\u624D\u4F7F\u7528\uFF1B\u5982\u679C\u6CA1\u6709\u5339\u914D\u9879\uFF0C\u5C31\u76F4\u63A5\u5B8C\u6210\u4EFB\u52A1\uFF0C\u6216\u7528 list_skill_index \u641C\u7D22\u5019\u9009\uFF0C\u5E76\u8C03\u7528 AskUserQuestion \u5DE5\u5177\u8BE2\u95EE\u7528\u6237\u662F\u5426\u8981\u4E3A\u5F53\u524D Agent \u542F\u7528/\u5206\u914D\u8BE5 skill\u3002AskUserQuestion \u9009\u9879\u5FC5\u987B\u5305\u542B"\u542F\u7528/\u5206\u914D\u8FD9\u4E2A skill"\u548C"\u5148\u4E0D\u7528\uFF0C\u76F4\u63A5\u5904\u7406"\uFF0Cmetadata \u5C3D\u91CF\u5E26\u4E0A skillId/skillName\u3002\u7528\u6237\u786E\u8BA4\u524D\u4E0D\u8981\u58F0\u79F0\u5DF2\u4F7F\u7528\u672A\u5206\u914D skill\uFF1B\u786E\u8BA4\u540E\u5FC5\u987B\u91CD\u65B0\u67E5\u8BE2\u672C\u5DE5\u5177\uFF0C\u53EA\u6709\u51FA\u73B0\u5728\u8FD9\u91CC\u624D\u7B97\u53EF\u7528\u3002';
114370
115069
  return {
114371
115070
  content: [{
114372
115071
  type: "text",
@@ -114395,7 +115094,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114395
115094
  },
114396
115095
  async (args) => {
114397
115096
  if (!deps.isSmith && deps.getAvailableSkillIds && !availableSkillsChecked) {
114398
- logger8.info("list_skill_index blocked before list_available_skills", {
115097
+ logger9.info("list_skill_index blocked before list_available_skills", {
114399
115098
  agentId: deps.agentId,
114400
115099
  scope: currentScopeKey
114401
115100
  });
@@ -114421,7 +115120,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
114421
115120
  entries: runtimeEntries,
114422
115121
  runtime: skillRuntimeContext(deps.officeCliRuntime)
114423
115122
  }), visibleSkillIds);
114424
- logger8.info("list_skill_index tool called", {
115123
+ logger9.info("list_skill_index tool called", {
114425
115124
  agentId: deps.agentId,
114426
115125
  scope: currentScopeKey,
114427
115126
  resultCount: entries.length
@@ -114474,7 +115173,7 @@ local_modelscope_* \u662F\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server
114474
115173
  officeCliMessage: deps.officeCliRuntime.message
114475
115174
  } : void 0
114476
115175
  }).filter((rec) => filterRuntimeVisibleSkillEntries([rec.skill], visibleSkillIds).length > 0);
114477
- logger8.info("recommend_agent_skills tool called", {
115176
+ logger9.info("recommend_agent_skills tool called", {
114478
115177
  agentId: deps.agentId,
114479
115178
  scope: currentScopeKey,
114480
115179
  resultCount: recommendations.length
@@ -114486,7 +115185,8 @@ local_modelscope_* \u662F\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server
114486
115185
  `[recommend_agent_skills] recommended initial skill set (${recommendations.length})`,
114487
115186
  formatSkillRecommendations(recommendations),
114488
115187
  "",
114489
- "\u8FB9\u754C\uFF1A\u63A8\u8350 != \u5B89\u88C5 != \u8C03\u7528\u3002\u9ED8\u8BA4/\u56E2\u961F\u5DF2\u542F\u7528 skill \u53EF\u6309\u4EFB\u52A1\u4F7F\u7528\uFF1B\u975E\u9ED8\u8BA4\u542F\u7528\u6216\u5199\u6587\u4EF6\u3001\u8DD1\u547D\u4EE4\u3001\u53D1\u5E03\u3001\u5927\u91CF\u8BFB\u53D6\u79C1\u5BC6\u4E0A\u4E0B\u6587\u7B49\u5177\u4F53\u9AD8\u98CE\u9669\u52A8\u4F5C\u524D\u624D\u9700\u8981\u786E\u8BA4\u3002"
115188
+ "\u8FB9\u754C\uFF1A\u63A8\u8350 != \u5B89\u88C5 != \u8C03\u7528\u3002\u9ED8\u8BA4/\u56E2\u961F\u5DF2\u542F\u7528 skill \u53EF\u6309\u4EFB\u52A1\u4F7F\u7528\uFF1B\u975E\u9ED8\u8BA4\u542F\u7528\u6216\u5199\u6587\u4EF6\u3001\u8DD1\u547D\u4EE4\u3001\u53D1\u5E03\u3001\u5927\u91CF\u8BFB\u53D6\u79C1\u5BC6\u4E0A\u4E0B\u6587\u7B49\u5177\u4F53\u9AD8\u98CE\u9669\u52A8\u4F5C\u524D\u624D\u9700\u8981\u786E\u8BA4\u3002",
115189
+ "local_modelscope_* \u662F\u672C\u673A Local Skill \u589E\u5F3A\u5019\u9009\uFF0C\u53EA\u80FD\u5728\u5F53\u524D\u673A\u5668\u7ED1\u5B9A\u5230 Agent\uFF0C\u4E0D\u5199\u5165 Server\uFF0C\u4E5F\u4E0D\u4F1A\u8DE8\u7528\u6237\u6216\u8DE8\u673A\u5668\u751F\u6548\u3002"
114490
115190
  ].join("\n")
114491
115191
  }]
114492
115192
  };
@@ -114512,7 +115212,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
114512
115212
  },
114513
115213
  async (args) => {
114514
115214
  if (!deps.isSmith) {
114515
- logger8.warn("fetch_logs: permission denied (non-Smith caller)", { agentId: deps.agentId });
115215
+ logger9.warn("fetch_logs: permission denied (non-Smith caller)", { agentId: deps.agentId });
114516
115216
  return {
114517
115217
  content: [{ type: "text", text: "[fetch_logs] \u6743\u9650\u62D2\u7EDD\uFF1A\u53EA\u6709 Smith \u80FD\u8C03\u7528\u3002" }],
114518
115218
  isError: true
@@ -114525,7 +115225,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
114525
115225
  isError: true
114526
115226
  };
114527
115227
  }
114528
- logger8.info("fetch_logs tool called", {
115228
+ logger9.info("fetch_logs tool called", {
114529
115229
  agentId: deps.agentId,
114530
115230
  source,
114531
115231
  startIso: args.start_iso,
@@ -114558,7 +115258,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
114558
115258
  });
114559
115259
  if (!res.ok) {
114560
115260
  const errText = await res.text().catch(() => "");
114561
- logger8.warn("fetch_logs: server rejected", { status: res.status, errText });
115261
+ logger9.warn("fetch_logs: server rejected", { status: res.status, errText });
114562
115262
  return {
114563
115263
  content: [{
114564
115264
  type: "text",
@@ -114568,7 +115268,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
114568
115268
  };
114569
115269
  }
114570
115270
  const json2 = await res.json();
114571
- logger8.info("fetch_logs returned", {
115271
+ logger9.info("fetch_logs returned", {
114572
115272
  source,
114573
115273
  count: json2.entries.length,
114574
115274
  truncated: json2.truncated,
@@ -114594,7 +115294,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114594
115294
  const text = [header, "", ...lines].join("\n");
114595
115295
  return { content: [{ type: "text", text }] };
114596
115296
  } catch (e) {
114597
- logger8.error("fetch_logs failed", { error: e });
115297
+ logger9.error("fetch_logs failed", { error: e });
114598
115298
  return {
114599
115299
  content: [{ type: "text", text: `[fetch_logs] \u8C03\u7528\u5931\u8D25\uFF1A${e.message}` }],
114600
115300
  isError: true
@@ -114608,7 +115308,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114608
115308
  `\u521B\u9020\u4E00\u4E2A\u65B0\u7684 Agent\u3002\u53EA\u6709\u4F60\uFF08Smith\uFF09\u80FD\u4F7F\u7528\u6B64\u5DE5\u5177\u3002
114609
115309
  \u65B0 Agent \u4F1A\u7ACB\u5373\u51FA\u73B0\u5728\u7CFB\u7EDF\u901A\u8BAF\u5F55\u4E2D\uFF0C\u62E5\u6709\u72EC\u7ACB\u7684 SDK runtime \u548C\u5DE5\u4F5C\u76EE\u5F55\u3002
114610
115310
  \u521B\u5EFA\u540E\u4F60\u53EF\u4EE5\u901A\u8FC7 create_group + add_to_group \u628A\u5B83\u62C9\u8FDB\u7FA4\u3002
114611
- \u521B\u5EFA\u65F6\u53EF\u4EE5\u9009\u62E9\u521D\u59CB\u8FD0\u884C\u673A\u5668\uFF1A\u5148\u7528 list_contacts \u67E5\u770B"\u53EF\u7528\u673A\u5668"\uFF0C\u518D\u4F20 machine_bridge_key\u3002\u540E\u7EED\u53EF\u7528 update_agent_profile \u5207\u6362\uFF1B\u4E0D\u4F20\u5219\u4F7F\u7528\u5F53\u524D Bridge\u3002
115311
+ \u521B\u5EFA\u65F6\u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D Bridge\uFF1A\u666E\u901A\u521B\u5EFA\u4E0D\u8981\u4F20 machine_bridge_key\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u6307\u5B9A\u67D0\u53F0\u8FD0\u884C\u673A\u5668\u65F6\uFF0C\u624D\u5148\u521B\u5EFA Agent\uFF0C\u518D\u7528 update_agent_profile \u5207\u6362\u3002
114612
115312
 
114613
115313
  **\u80FD\u529B\u6863\u4F4D\u9009\u62E9\u6307\u5357\uFF1A**
114614
115314
  - **smart\uFF08\u65D7\u8230\uFF09**\uFF1A\u7F16\u6392\u8005\u3001\u590D\u6742\u63A8\u7406\u3001\u6700\u7EC8\u7EFC\u5408\u3001\u9AD8\u96BE\u5EA6\u89D2\u8272\u3002\u4F7F\u7528\u6700\u5F3A\u6A21\u578B\u3002
@@ -114642,15 +115342,15 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114642
115342
  "\u53EF\u9009\u3002\u8BE5 Agent \u7684\u5DE5\u4F5C\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\u3002\u4E0D\u4F20\u5219\u7531\u7CFB\u7EDF\u81EA\u52A8\u5206\u914D\u3002"
114643
115343
  ),
114644
115344
  machine_bridge_key: external_exports.string().optional().describe(
114645
- '\u53EF\u9009\u3002\u8FD0\u884C\u673A\u5668 bridgeKey\uFF0C\u6765\u81EA list_contacts \u7684"\u53EF\u7528\u673A\u5668"\u3002\u4E0D\u4F20\u5219\u4F7F\u7528\u5F53\u524D Bridge\uFF1B\u540E\u7EED\u53EF\u7528 update_agent_profile \u5207\u6362\u3002'
115345
+ "\u53EF\u9009\u3002\u53EA\u5141\u8BB8\u4F20\u5F53\u524D Bridge \u7684 bridgeKey\uFF1B\u666E\u901A\u521B\u5EFA\u8BF7\u7701\u7565\uFF0C\u7CFB\u7EDF\u4F1A\u4F7F\u7528\u5F53\u524D\u673A\u5668\u3002\u8DE8\u673A\u5668\u8FD0\u884C\u8BF7\u521B\u5EFA\u540E\u7528 update_agent_profile \u5207\u6362\u3002"
114646
115346
  ),
114647
115347
  skill_ids: external_exports.array(external_exports.string()).optional().describe(
114648
- "\u53EF\u9009\u3002\u521B\u5EFA\u540E\u7ACB\u5373\u5206\u914D\u7ED9\u65B0 Agent \u7684\u521D\u59CB skill \u5305\uFF08skill id \u5217\u8868\uFF09\u3002\u9ED8\u8BA4/\u56E2\u961F\u5DF2\u542F\u7528\u63A8\u8350\u53EF\u6309\u89D2\u8272\u76F4\u63A5\u4F20\u5165\uFF1B\u975E\u9ED8\u8BA4/\u672A\u542F\u7528 skill \u9700\u8981\u7528\u6237\u660E\u786E\u8981\u6C42\u6216\u786E\u8BA4\u540E\u518D\u4F20\u3002local_modelscope_* \u5C5E\u4E8E\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server \u5206\u914D\uFF1B\u53EA\u6709\u65B0 Agent \u8FD0\u884C\u5728\u5F53\u524D\u673A\u5668\u65F6\u624D\u4F1A\u5199\u5165\u5F53\u524D\u673A\u5668 allowedAgentIds\u3002\u4E0D\u8981\u8BA9\u7528\u6237\u66FF\u7CFB\u7EDF\u5224\u65AD\u9ED8\u8BA4 skill \u662F\u5426\u53EF\u7528\u3002"
115348
+ "\u53EF\u9009\u3002\u521B\u5EFA\u540E\u7ACB\u5373\u5206\u914D\u7ED9\u65B0 Agent \u7684\u521D\u59CB skill \u5305\uFF08skill id \u5217\u8868\uFF09\u3002\u9ED8\u8BA4/\u56E2\u961F\u5DF2\u542F\u7528\u63A8\u8350\u53EF\u6309\u89D2\u8272\u76F4\u63A5\u4F20\u5165\uFF1B\u975E\u9ED8\u8BA4/\u672A\u542F\u7528 skill \u9700\u8981\u7528\u6237\u660E\u786E\u8981\u6C42\u6216\u786E\u8BA4\u540E\u518D\u4F20\u3002\u9700\u8981\u957F\u8017\u65F6\u5916\u90E8\u4EFB\u52A1\u7684\u5B98\u65B9\u6D41\u7A0B skill \u4F1A\u901A\u8FC7\u53EF\u6269\u5C55\u89C4\u5219\u505A\u4FDD\u5B88\u8865\u9F50\uFF1B\u672C\u673A Local Skill \u53EA\u4F5C\u4E3A\u5F53\u524D\u673A\u5668\u7684\u4EFB\u52A1\u589E\u5F3A\u5019\u9009\u3002local_modelscope_* \u5C5E\u4E8E\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server \u5206\u914D\uFF1B\u53EA\u6709\u65B0 Agent \u8FD0\u884C\u5728\u5F53\u524D\u673A\u5668\u65F6\u624D\u4F1A\u5199\u5165\u5F53\u524D\u673A\u5668 allowedAgentIds\uFF0C\u4E0D\u80FD\u8DE8\u7528\u6237\u6216\u8DE8\u673A\u5668\u751F\u6548\u3002\u4E0D\u8981\u8BA9\u7528\u6237\u66FF\u7CFB\u7EDF\u5224\u65AD\u9ED8\u8BA4 skill \u662F\u5426\u53EF\u7528\u3002"
114649
115349
  )
114650
115350
  },
114651
115351
  async (args) => {
114652
115352
  if (!deps.isSmith) {
114653
- logger8.warn("create_agent: permission denied (non-Smith caller)", {
115353
+ logger9.warn("create_agent: permission denied (non-Smith caller)", {
114654
115354
  agentId: deps.agentId,
114655
115355
  scope: currentScopeKey
114656
115356
  });
@@ -114675,10 +115375,24 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114675
115375
  const avatar = args.avatar && String(args.avatar).trim() || "";
114676
115376
  const initialInstruction = args.initial_instruction && String(args.initial_instruction).trim() || "";
114677
115377
  const workingDirectory = args.working_directory && String(args.working_directory).trim() || "";
114678
- const machineBridgeKey = args.machine_bridge_key && String(args.machine_bridge_key).trim() || "";
115378
+ const requestedMachineBridgeKey = args.machine_bridge_key && String(args.machine_bridge_key).trim() || "";
115379
+ const machineBridgeKey = requestedMachineBridgeKey === "auto" ? "" : requestedMachineBridgeKey;
115380
+ const remoteMachineError = rejectRemoteCreateMachineBridgeKey(machineBridgeKey, deps);
115381
+ if (remoteMachineError) {
115382
+ logger9.warn("create_agent: rejected remote machine_bridge_key on create", {
115383
+ agentId: deps.agentId,
115384
+ scope: currentScopeKey,
115385
+ requestedMachineBridgeKey: machineBridgeKey,
115386
+ currentBridgeKey: deps.currentBridgeKey ?? null
115387
+ });
115388
+ return {
115389
+ content: [{ type: "text", text: remoteMachineError }],
115390
+ isError: true
115391
+ };
115392
+ }
114679
115393
  const machineValidation = await validateOnlineMachineBridgeKey("create_agent", machineBridgeKey, deps);
114680
115394
  if (!machineValidation.ok) {
114681
- logger8.warn("create_agent: rejected offline or unknown machine_bridge_key", {
115395
+ logger9.warn("create_agent: rejected offline or unknown machine_bridge_key", {
114682
115396
  agentId: deps.agentId,
114683
115397
  scope: currentScopeKey,
114684
115398
  machineBridgeKey
@@ -114707,15 +115421,15 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114707
115421
  capabilityTier: tier,
114708
115422
  subscriptionId: tierConfig.subscriptionId
114709
115423
  });
114710
- logger8.info("Tier resolved", { tier, subscriptionId: tierConfig.subscriptionId, model: tierConfig.modelName });
115424
+ logger9.info("Tier resolved", { tier, subscriptionId: tierConfig.subscriptionId, model: tierConfig.modelName });
114711
115425
  } else {
114712
- logger8.warn("Tier not found, using default", { tier, availableTiers: tiers.map((t) => t.tier) });
115426
+ logger9.warn("Tier not found, using default", { tier, availableTiers: tiers.map((t) => t.tier) });
114713
115427
  }
114714
115428
  } else {
114715
- logger8.warn("Failed to fetch tiers", { status: tierRes.status });
115429
+ logger9.warn("Failed to fetch tiers", { status: tierRes.status });
114716
115430
  }
114717
115431
  } catch (e) {
114718
- logger8.error("Tier resolution failed", { error: e });
115432
+ logger9.error("Tier resolution failed", { error: e });
114719
115433
  }
114720
115434
  }
114721
115435
  const body = { name, role, systemPrompt, avatar };
@@ -114728,7 +115442,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114728
115442
  if (machineBridgeKey) {
114729
115443
  body.machineBridgeKey = machineBridgeKey;
114730
115444
  }
114731
- logger8.info("create_agent tool called", {
115445
+ logger9.info("create_agent tool called", {
114732
115446
  agentId: deps.agentId,
114733
115447
  requestedBy: deps.agentId,
114734
115448
  scope: currentScopeKey,
@@ -114749,7 +115463,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114749
115463
  });
114750
115464
  if (!res.ok) {
114751
115465
  const errText = await res.text().catch(() => "");
114752
- logger8.warn("create_agent: server rejected", { status: res.status, errText, name });
115466
+ logger9.warn("create_agent: server rejected", { status: res.status, errText, name });
114753
115467
  return {
114754
115468
  content: [{
114755
115469
  type: "text",
@@ -114760,7 +115474,44 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114760
115474
  }
114761
115475
  const agent = await res.json();
114762
115476
  const resolvedMachineBridgeKey = agent.machineBridgeKey ?? machineBridgeKey;
115477
+ const skillIntent = {
115478
+ name,
115479
+ role,
115480
+ systemPrompt,
115481
+ initialInstruction,
115482
+ workingDirectory
115483
+ };
114763
115484
  const requestedSkillIds = Array.isArray(args.skill_ids) ? args.skill_ids.map((id) => typeof id === "string" ? id.trim() : "").filter((id) => id.length > 0) : [];
115485
+ const autoAssignedOfficialSkillIds = autoAssignOfficialSkillIds(skillIntent);
115486
+ for (const skillId of autoAssignedOfficialSkillIds) {
115487
+ if (requestedSkillIds.includes(skillId)) continue;
115488
+ requestedSkillIds.push(skillId);
115489
+ logger9.info("create_agent: auto-added official workflow skill", {
115490
+ requestedBy: deps.agentId,
115491
+ newAgentId: agent.id,
115492
+ skillId
115493
+ });
115494
+ }
115495
+ const explicitlyRequestedLocalSkill = requestedSkillIds.some(isLocalSkillId);
115496
+ const localEnhancerTargetBridgeKey = resolvedMachineBridgeKey ?? machineBridgeKey;
115497
+ if (autoAssignedOfficialSkillIds.length > 0 && !explicitlyRequestedLocalSkill && deps.setLocalSkillAgentVisibility && isCurrentMachineLocalTarget(localEnhancerTargetBridgeKey, deps.currentBridgeKey)) {
115498
+ const localEnhancerSkillIds = selectLocalSkillEnhancersForCreateAgent(
115499
+ skillIntent,
115500
+ deps.skillStore,
115501
+ new Set(requestedSkillIds)
115502
+ );
115503
+ for (const skillId of localEnhancerSkillIds) {
115504
+ requestedSkillIds.push(skillId);
115505
+ }
115506
+ if (localEnhancerSkillIds.length > 0) {
115507
+ logger9.info("create_agent: auto-added local skill enhancers", {
115508
+ requestedBy: deps.agentId,
115509
+ newAgentId: agent.id,
115510
+ localEnhancerSkillIds,
115511
+ targetBridgeKey: localEnhancerTargetBridgeKey || "(current-bridge)"
115512
+ });
115513
+ }
115514
+ }
114764
115515
  const skillIds = Array.from(new Set(requestedSkillIds));
114765
115516
  const localSkillIds = skillIds.filter(isLocalSkillId);
114766
115517
  const serverSkillIds = skillIds.filter((id) => !isLocalSkillId(id));
@@ -114779,7 +115530,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114779
115530
  const assignBody = await assignRes.json();
114780
115531
  const assignedCount = assignBody.assigned?.length ?? 0;
114781
115532
  const skipped = assignBody.skipped ?? [];
114782
- logger8.info("create_agent: initial skills assigned", {
115533
+ logger9.info("create_agent: initial skills assigned", {
114783
115534
  requestedBy: deps.agentId,
114784
115535
  newAgentId: agent.id,
114785
115536
  assignedCount,
@@ -114788,7 +115539,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114788
115539
  skillAssignNote = skipped.length > 0 ? `\u5DF2\u5206\u914D ${assignedCount} \u4E2A\u521D\u59CB skill\uFF08${skipped.length} \u4E2A\u65E0\u6548\u5DF2\u8DF3\u8FC7\uFF09\u3002` : `\u5DF2\u5206\u914D ${assignedCount} \u4E2A\u521D\u59CB skill\u3002`;
114789
115540
  } else {
114790
115541
  const errText = await assignRes.text().catch(() => "");
114791
- logger8.warn("create_agent: initial skill assignment rejected", {
115542
+ logger9.warn("create_agent: initial skill assignment rejected", {
114792
115543
  newAgentId: agent.id,
114793
115544
  status: assignRes.status,
114794
115545
  errText
@@ -114796,18 +115547,18 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114796
115547
  skillAssignNote = `\u521D\u59CB skill \u5206\u914D\u5931\u8D25\uFF08${assignRes.status}\uFF09\uFF0C\u53EF\u7A0D\u540E\u7528 assign \u6D41\u7A0B\u8865\u914D\u3002`;
114797
115548
  }
114798
115549
  } catch (e) {
114799
- logger8.error("create_agent: initial skill assignment failed", { error: e, newAgentId: agent.id });
115550
+ logger9.error("create_agent: initial skill assignment failed", { error: e, newAgentId: agent.id });
114800
115551
  skillAssignNote = "\u521D\u59CB skill \u5206\u914D\u5931\u8D25\uFF0C\u53EF\u7A0D\u540E\u8865\u914D\u3002";
114801
115552
  }
114802
115553
  }
114803
115554
  if (localSkillIds.length > 0) {
114804
115555
  const targetBridgeKey = resolvedMachineBridgeKey ?? machineBridgeKey;
114805
- const localSkillTargetIsCurrentMachine = !targetBridgeKey || deps.currentBridgeKey != null && targetBridgeKey === deps.currentBridgeKey;
115556
+ const localSkillTargetIsCurrentMachine = isCurrentMachineLocalTarget(targetBridgeKey, deps.currentBridgeKey);
114806
115557
  let localAssignedCount = 0;
114807
115558
  const localSkipped = [];
114808
115559
  if (!localSkillTargetIsCurrentMachine) {
114809
115560
  localSkipped.push(...localSkillIds);
114810
- logger8.warn("create_agent: local skills skipped for remote machine target", {
115561
+ logger9.warn("create_agent: local skills skipped for remote machine target", {
114811
115562
  requestedBy: deps.agentId,
114812
115563
  newAgentId: agent.id,
114813
115564
  localSkillIds,
@@ -114816,7 +115567,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114816
115567
  });
114817
115568
  } else if (!deps.setLocalSkillAgentVisibility) {
114818
115569
  localSkipped.push(...localSkillIds);
114819
- logger8.warn("create_agent: local skill binder unavailable", {
115570
+ logger9.warn("create_agent: local skill binder unavailable", {
114820
115571
  requestedBy: deps.agentId,
114821
115572
  newAgentId: agent.id,
114822
115573
  localSkillIds
@@ -114832,7 +115583,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114832
115583
  }
114833
115584
  } catch (e) {
114834
115585
  localSkipped.push(skillId);
114835
- logger8.error("create_agent: local skill assignment failed", {
115586
+ logger9.error("create_agent: local skill assignment failed", {
114836
115587
  error: e,
114837
115588
  requestedBy: deps.agentId,
114838
115589
  newAgentId: agent.id,
@@ -114844,7 +115595,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114844
115595
  await deps.onLocalSkillVisibilityChanged?.([agent.id]);
114845
115596
  }
114846
115597
  }
114847
- logger8.info("create_agent: local skill assignment resolved", {
115598
+ logger9.info("create_agent: local skill assignment resolved", {
114848
115599
  requestedBy: deps.agentId,
114849
115600
  newAgentId: agent.id,
114850
115601
  localSkillIds,
@@ -114854,7 +115605,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114854
115605
  const localSkillNote = localAssignedCount > 0 ? `\u672C\u673A Local Skill \u5DF2\u7ED1\u5B9A ${localAssignedCount} \u4E2A\u5230\u5F53\u524D\u673A\u5668\uFF1B${localSkipped.length > 0 ? `${localSkipped.length} \u4E2A\u672A\u627E\u5230\u6216\u4E0D\u53EF\u7ED1\u5B9A\u3002` : "\u4E0D\u4F1A\u5199\u5165 Server\u3002"}` : `\u672C\u673A Local Skill ${localSkillIds.length} \u4E2A\u672A\u5199\u5165 Server${localSkipped.length > 0 ? "\uFF0C\u4E14\u672A\u7ED1\u5B9A\u5230\u5F53\u524D\u673A\u5668" : ""}\uFF1B\u5982\u679C\u65B0 Agent \u5728\u53E6\u4E00\u53F0\u673A\u5668\u8FD0\u884C\uFF0C\u9700\u8981\u5728\u90A3\u53F0\u673A\u5668\u5B89\u88C5\u5E76\u7ED1\u5B9A\u3002`;
114855
115606
  skillAssignNote = skillAssignNote ? `${skillAssignNote}${localSkillNote}` : localSkillNote;
114856
115607
  }
114857
- logger8.info("create_agent: created", {
115608
+ logger9.info("create_agent: created", {
114858
115609
  requestedBy: deps.agentId,
114859
115610
  scope: currentScopeKey,
114860
115611
  agentId: agent.id,
@@ -114873,7 +115624,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114873
115624
  });
114874
115625
  if (initialInstruction && deps.onAgentCreatedInitInstruction) {
114875
115626
  try {
114876
- logger8.info("create_agent: firing initial instruction dispatch", {
115627
+ logger9.info("create_agent: firing initial instruction dispatch", {
114877
115628
  requestedBy: deps.agentId,
114878
115629
  newAgentId: agent.id,
114879
115630
  newAgentName: agent.name,
@@ -114886,7 +115637,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114886
115637
  requestedBy: deps.agentId
114887
115638
  });
114888
115639
  } catch (e) {
114889
- logger8.error("create_agent: onAgentCreatedInitInstruction sync threw", {
115640
+ logger9.error("create_agent: onAgentCreatedInitInstruction sync threw", {
114890
115641
  error: e,
114891
115642
  newAgentId: agent.id
114892
115643
  });
@@ -114899,7 +115650,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114899
115650
  content: [{ type: "text", text: reply }]
114900
115651
  };
114901
115652
  } catch (e) {
114902
- logger8.error("create_agent failed", { error: e, name });
115653
+ logger9.error("create_agent failed", { error: e, name });
114903
115654
  return {
114904
115655
  content: [{ type: "text", text: `[create_agent] \u521B\u5EFA\u5931\u8D25\uFF1A${e.message}` }],
114905
115656
  isError: true
@@ -114971,7 +115722,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
114971
115722
  deps
114972
115723
  );
114973
115724
  if (!machineValidation.ok) {
114974
- logger8.warn("update_agent_profile: rejected offline or unknown machine_bridge_key", {
115725
+ logger9.warn("update_agent_profile: rejected offline or unknown machine_bridge_key", {
114975
115726
  agentId: deps.agentId,
114976
115727
  targetAgentId: agentId,
114977
115728
  machineBridgeKey: requestedMachineBridgeKey
@@ -115002,11 +115753,11 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115002
115753
  subscriptionId: tierConfig.subscriptionId,
115003
115754
  model: tierConfig.modelName
115004
115755
  });
115005
- logger8.info("update_agent: tier resolved", { agentId, tier, subscriptionId: tierConfig.subscriptionId });
115756
+ logger9.info("update_agent: tier resolved", { agentId, tier, subscriptionId: tierConfig.subscriptionId });
115006
115757
  }
115007
115758
  }
115008
115759
  } catch (e) {
115009
- logger8.error("update_agent: tier resolution failed", { error: e });
115760
+ logger9.error("update_agent: tier resolution failed", { error: e });
115010
115761
  }
115011
115762
  }
115012
115763
  const patchBody = {};
@@ -115025,7 +115776,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115025
115776
  isError: true
115026
115777
  };
115027
115778
  }
115028
- logger8.info("update_agent_profile tool called", {
115779
+ logger9.info("update_agent_profile tool called", {
115029
115780
  agentId: deps.agentId,
115030
115781
  targetAgentId: agentId,
115031
115782
  targetName: existing.name,
@@ -115045,7 +115796,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115045
115796
  };
115046
115797
  }
115047
115798
  const updated = await res.json();
115048
- logger8.info("update_agent_profile: succeeded", {
115799
+ logger9.info("update_agent_profile: succeeded", {
115049
115800
  agentId: deps.agentId,
115050
115801
  targetAgentId: agentId,
115051
115802
  newName: updated.name
@@ -115057,7 +115808,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115057
115808
  }]
115058
115809
  };
115059
115810
  } catch (e) {
115060
- logger8.error("update_agent_profile failed", { error: e, agentId });
115811
+ logger9.error("update_agent_profile failed", { error: e, agentId });
115061
115812
  return {
115062
115813
  content: [{ type: "text", text: `[update_agent_profile] \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}` }],
115063
115814
  isError: true
@@ -115094,7 +115845,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115094
115845
  };
115095
115846
  }
115096
115847
  const base = deps.serverApiUrl.replace(/\/$/, "");
115097
- logger8.info("archive_conversation tool called", {
115848
+ logger9.info("archive_conversation tool called", {
115098
115849
  agentId: deps.agentId,
115099
115850
  targetAgentId: agentId,
115100
115851
  conversationId
@@ -115115,7 +115866,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115115
115866
  isError: true
115116
115867
  };
115117
115868
  }
115118
- logger8.info("archive_conversation: succeeded", {
115869
+ logger9.info("archive_conversation: succeeded", {
115119
115870
  agentId: deps.agentId,
115120
115871
  conversationId
115121
115872
  });
@@ -115126,7 +115877,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115126
115877
  }]
115127
115878
  };
115128
115879
  } catch (e) {
115129
- logger8.error("archive_conversation failed", { error: e, conversationId });
115880
+ logger9.error("archive_conversation failed", { error: e, conversationId });
115130
115881
  return {
115131
115882
  content: [{ type: "text", text: `[archive_conversation] \u5F52\u6863\u5931\u8D25\uFF1A${e.message}` }],
115132
115883
  isError: true
@@ -115170,7 +115921,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115170
115921
  isError: true
115171
115922
  };
115172
115923
  }
115173
- logger8.info("transfer_group_owner tool called", {
115924
+ logger9.info("transfer_group_owner tool called", {
115174
115925
  agentId: deps.agentId,
115175
115926
  fromOwnerId: deps.agentId,
115176
115927
  scope: currentScopeKey,
@@ -115189,7 +115940,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115189
115940
  });
115190
115941
  if (!res.ok) {
115191
115942
  const errText = await res.text().catch(() => "");
115192
- logger8.warn("transfer_group_owner: server rejected", {
115943
+ logger9.warn("transfer_group_owner: server rejected", {
115193
115944
  status: res.status,
115194
115945
  errText,
115195
115946
  groupId: resolved.groupId
@@ -115202,7 +115953,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115202
115953
  isError: true
115203
115954
  };
115204
115955
  }
115205
- logger8.info("transfer_group_owner: succeeded", {
115956
+ logger9.info("transfer_group_owner: succeeded", {
115206
115957
  agentId: deps.agentId,
115207
115958
  fromOwnerId: deps.agentId,
115208
115959
  scope: currentScopeKey,
@@ -115216,7 +115967,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115216
115967
  }]
115217
115968
  };
115218
115969
  } catch (e) {
115219
- logger8.error("transfer_group_owner failed", { error: e, groupId: resolved.groupId });
115970
+ logger9.error("transfer_group_owner failed", { error: e, groupId: resolved.groupId });
115220
115971
  return {
115221
115972
  content: [{
115222
115973
  type: "text",
@@ -115285,7 +116036,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115285
116036
  }
115286
116037
  }
115287
116038
  }
115288
- logger8.info("list_friends called", {
116039
+ logger9.info("list_friends called", {
115289
116040
  agentId: deps.agentId,
115290
116041
  friendCount: friends.length
115291
116042
  });
@@ -115293,7 +116044,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115293
116044
  content: [{ type: "text", text: parts.join("\n") }]
115294
116045
  };
115295
116046
  } catch (e) {
115296
- logger8.error("list_friends failed", { error: e });
116047
+ logger9.error("list_friends failed", { error: e });
115297
116048
  return {
115298
116049
  content: [{ type: "text", text: `[list_friends] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
115299
116050
  isError: true
@@ -115337,7 +116088,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115337
116088
  isError: true
115338
116089
  };
115339
116090
  }
115340
- logger8.info("accept_friend called", {
116091
+ logger9.info("accept_friend called", {
115341
116092
  agentId: deps.agentId,
115342
116093
  requestId,
115343
116094
  action
@@ -115353,7 +116104,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115353
116104
  content: [{ type: "text", text: `[accept_friend] \u5DF2\u62D2\u7EDD\u8BE5\u597D\u53CB\u7533\u8BF7\u3002` }]
115354
116105
  };
115355
116106
  } catch (e) {
115356
- logger8.error("accept_friend failed", { error: e });
116107
+ logger9.error("accept_friend failed", { error: e });
115357
116108
  return {
115358
116109
  content: [{ type: "text", text: `[accept_friend] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
115359
116110
  isError: true
@@ -115431,7 +116182,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115431
116182
  isError: true
115432
116183
  };
115433
116184
  }
115434
- logger8.info("add_friend: request sent", {
116185
+ logger9.info("add_friend: request sent", {
115435
116186
  agentId: deps.agentId,
115436
116187
  targetUserId: lookup.user.id,
115437
116188
  targetName: lookup.user.name,
@@ -115444,7 +116195,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115444
116195
  }]
115445
116196
  };
115446
116197
  } catch (e) {
115447
- logger8.error("add_friend failed", { error: e });
116198
+ logger9.error("add_friend failed", { error: e });
115448
116199
  return {
115449
116200
  content: [{ type: "text", text: `[add_friend] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
115450
116201
  isError: true
@@ -115464,7 +116215,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115464
116215
  }
115465
116216
  const category = normalizeFeedCategory(args.category);
115466
116217
  const groupId = (args.group_id ?? "").trim() || (deps.scope.kind === "group" ? deps.scope.groupId : void 0);
115467
- logger8.info(`${toolName} tool called`, {
116218
+ logger9.info(`${toolName} tool called`, {
115468
116219
  agentId: deps.agentId,
115469
116220
  scope: currentScopeKey,
115470
116221
  title,
@@ -115487,7 +116238,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115487
116238
  });
115488
116239
  if (!res.ok) {
115489
116240
  const errText = await res.text().catch(() => "");
115490
- logger8.warn(`${toolName}: server rejected`, { status: res.status, errText, title });
116241
+ logger9.warn(`${toolName}: server rejected`, { status: res.status, errText, title });
115491
116242
  return {
115492
116243
  content: [{
115493
116244
  type: "text",
@@ -115497,7 +116248,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115497
116248
  };
115498
116249
  }
115499
116250
  const payload = await res.json();
115500
- logger8.info(`${toolName}: created`, {
116251
+ logger9.info(`${toolName}: created`, {
115501
116252
  agentId: deps.agentId,
115502
116253
  scope: currentScopeKey,
115503
116254
  postId: payload.post?.id,
@@ -115510,7 +116261,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115510
116261
  }]
115511
116262
  };
115512
116263
  } catch (e) {
115513
- logger8.error(`${toolName} failed`, { error: e, title });
116264
+ logger9.error(`${toolName} failed`, { error: e, title });
115514
116265
  return {
115515
116266
  content: [{ type: "text", text: `[${toolName}] \u53D1\u5E03\u5931\u8D25\uFF1A${e.message}` }],
115516
116267
  isError: true
@@ -115565,7 +116316,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115565
116316
  const category = args.category ? normalizeFeedCategory(args.category) : void 0;
115566
116317
  const rawGroupId = (args.group_id ?? "").trim();
115567
116318
  const groupId = rawGroupId === "all" ? void 0 : rawGroupId || (deps.scope.kind === "group" ? deps.scope.groupId : void 0);
115568
- logger8.info("read_moments tool called", {
116319
+ logger9.info("read_moments tool called", {
115569
116320
  agentId: deps.agentId,
115570
116321
  scope: currentScopeKey,
115571
116322
  limit,
@@ -115582,7 +116333,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115582
116333
  });
115583
116334
  if (!res.ok) {
115584
116335
  const errText = await res.text().catch(() => "");
115585
- logger8.warn("read_moments: server rejected", { status: res.status, errText });
116336
+ logger9.warn("read_moments: server rejected", { status: res.status, errText });
115586
116337
  return {
115587
116338
  content: [{
115588
116339
  type: "text",
@@ -115593,7 +116344,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115593
116344
  }
115594
116345
  const payload = await res.json();
115595
116346
  const posts = Array.isArray(payload.posts) ? payload.posts : [];
115596
- logger8.info("read_moments returned", {
116347
+ logger9.info("read_moments returned", {
115597
116348
  agentId: deps.agentId,
115598
116349
  scope: currentScopeKey,
115599
116350
  count: posts.length,
@@ -115617,7 +116368,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115617
116368
  }]
115618
116369
  };
115619
116370
  } catch (e) {
115620
- logger8.error("read_moments failed", { error: e });
116371
+ logger9.error("read_moments failed", { error: e });
115621
116372
  return {
115622
116373
  content: [{ type: "text", text: `[read_moments] \u8BFB\u53D6\u5931\u8D25\uFF1A${e.message}` }],
115623
116374
  isError: true
@@ -115685,7 +116436,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115685
116436
  if (postToMomentsTool) toolNames.push("post_to_moments");
115686
116437
  if (postToForumTool) toolNames.push("post_to_forum");
115687
116438
  if (readMomentsTool) toolNames.push("read_moments");
115688
- logger8.info("Neural MCP server created", {
116439
+ logger9.info("Neural MCP server created", {
115689
116440
  agentId: deps.agentId,
115690
116441
  isSmith: deps.isSmith,
115691
116442
  scope: currentScopeKey,
@@ -115696,7 +116447,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115696
116447
 
115697
116448
  // src/groupDispatchMemory.ts
115698
116449
  init_cjs_shims();
115699
- var logger9 = createModuleLogger("agent.dispatchMemory");
116450
+ var logger10 = createModuleLogger("agent.dispatchMemory");
115700
116451
  var GroupDispatchMemoryStore = class {
115701
116452
  memo = /* @__PURE__ */ new Map();
115702
116453
  getOrCreate(agentId, scope) {
@@ -115717,7 +116468,7 @@ var GroupDispatchMemoryStore = class {
115717
116468
  reset(agentId, scope, reason = "compact_completed") {
115718
116469
  const key = runtimeKey(agentId, scope);
115719
116470
  if (this.memo.delete(key)) {
115720
- logger9.info("Dispatch memory reset", {
116471
+ logger10.info("Dispatch memory reset", {
115721
116472
  agentId,
115722
116473
  scope: scope.kind === "single" ? "single" : scope.groupId,
115723
116474
  reason
@@ -115924,110 +116675,6 @@ function buildGroupInboxPrompt(entries, opts = {}) {
115924
116675
  return lines.join("\n");
115925
116676
  }
115926
116677
 
115927
- // src/officeRuntime.ts
115928
- init_cjs_shims();
115929
- var import_node_fs5 = __toESM(require("fs"), 1);
115930
- var import_node_os5 = __toESM(require("os"), 1);
115931
- var import_node_path10 = __toESM(require("path"), 1);
115932
- var OFFICECLI_EXECUTABLE_ENV = "AHCHAT_OFFICECLI_EXECUTABLE";
115933
- var OFFICECLI_BIN_DIR_ENV = "AHCHAT_OFFICECLI_BIN_DIR";
115934
- var logger10 = createModuleLogger("bridge.officeRuntime");
115935
- function sanitizedOfficeCliProbeError(error51) {
115936
- const rawCode = error51 && typeof error51 === "object" && "code" in error51 ? error51.code : void 0;
115937
- const code = typeof rawCode === "string" ? rawCode : void 0;
115938
- const sanitized = new Error(`OfficeCLI executable probe failed${code ? ` (${code})` : ""}`);
115939
- if (error51 instanceof Error) sanitized.name = error51.name;
115940
- return sanitized;
115941
- }
115942
- function defaultRuntimeRoot() {
115943
- if (process.platform === "win32") {
115944
- return import_node_path10.default.join(process.env.LOCALAPPDATA || import_node_path10.default.join(import_node_os5.default.homedir(), "AppData", "Local"), "AHChat", "runtime", "officecli");
115945
- }
115946
- if (process.platform === "darwin") {
115947
- return import_node_path10.default.join(import_node_os5.default.homedir(), "Library", "Caches", "AHChat", "runtime", "officecli");
115948
- }
115949
- return import_node_path10.default.join(process.env.XDG_CACHE_HOME || import_node_path10.default.join(import_node_os5.default.homedir(), ".cache"), "ahchat", "runtime", "officecli");
115950
- }
115951
- function getManagedOfficeCliBinDir(env2 = process.env) {
115952
- return env2[OFFICECLI_BIN_DIR_ENV] || import_node_path10.default.join(defaultRuntimeRoot(), "bin");
115953
- }
115954
- function getOfficeCliExecutableName() {
115955
- return process.platform === "win32" ? "officecli.exe" : "officecli";
115956
- }
115957
- function getManagedOfficeCliExecutablePath(env2 = process.env) {
115958
- return import_node_path10.default.join(getManagedOfficeCliBinDir(env2), getOfficeCliExecutableName());
115959
- }
115960
- function isExecutable(filePath, options = {}) {
115961
- const logFailure = options.logFailure !== false;
115962
- try {
115963
- if (process.platform === "win32") return import_node_fs5.default.existsSync(filePath);
115964
- import_node_fs5.default.accessSync(filePath, import_node_fs5.default.constants.X_OK);
115965
- return true;
115966
- } catch (error51) {
115967
- if (logFailure) {
115968
- logger10.error("OfficeCLI executable probe failed", {
115969
- error: sanitizedOfficeCliProbeError(error51),
115970
- fileName: import_node_path10.default.basename(filePath)
115971
- });
115972
- }
115973
- return false;
115974
- }
115975
- }
115976
- function withPrependedPath(env2, entries) {
115977
- const pathEntries = entries.filter((entry) => entry && import_node_fs5.default.existsSync(entry));
115978
- if (pathEntries.length === 0) return env2;
115979
- const current = env2.PATH ?? "";
115980
- return {
115981
- ...env2,
115982
- PATH: [...pathEntries, current].filter(Boolean).join(import_node_path10.default.delimiter)
115983
- };
115984
- }
115985
- function statusForPath(filePath, source, env2, options = {}) {
115986
- if (!isExecutable(filePath, { logFailure: options.logProbeFailure })) {
115987
- return {
115988
- ok: false,
115989
- path: filePath,
115990
- source,
115991
- message: `officecli not executable at ${filePath}`
115992
- };
115993
- }
115994
- const runtimeEnv = withPrependedPath(env2, [import_node_path10.default.dirname(filePath)]);
115995
- const version4 = readCommandVersion(filePath, ["--version"], runtimeEnv);
115996
- if (!version4) {
115997
- return {
115998
- ok: false,
115999
- path: filePath,
116000
- source,
116001
- message: `officecli found at ${filePath} but --version failed`
116002
- };
116003
- }
116004
- return { ok: true, path: filePath, source, version: version4 };
116005
- }
116006
- function detectOfficeCliRuntime(env2 = process.env) {
116007
- const explicitPath = env2[OFFICECLI_EXECUTABLE_ENV]?.trim();
116008
- if (explicitPath) return statusForPath(explicitPath, "env", env2);
116009
- const managedPath = getManagedOfficeCliExecutablePath(env2);
116010
- const managed = statusForPath(managedPath, "managed", env2, { logProbeFailure: false });
116011
- if (managed.ok) return managed;
116012
- const resolved = resolveCommand(["officecli"], withPrependedPath(env2, [import_node_path10.default.dirname(managedPath)]));
116013
- if (!resolved) {
116014
- return {
116015
- ok: false,
116016
- source: "managed",
116017
- path: managedPath,
116018
- message: `officecli not found. Run pnpm setup:office-runtime or set ${OFFICECLI_EXECUTABLE_ENV}.`
116019
- };
116020
- }
116021
- return statusForPath(resolved.path, resolved.path === managedPath ? "managed" : "path", env2);
116022
- }
116023
- function withOfficeCliRuntimeEnv(status, env2 = process.env) {
116024
- if (!status.ok || !status.path) return env2;
116025
- return {
116026
- ...withPrependedPath(env2, [import_node_path10.default.dirname(status.path)]),
116027
- [OFFICECLI_EXECUTABLE_ENV]: status.path
116028
- };
116029
- }
116030
-
116031
116678
  // src/sdkEventMapper.ts
116032
116679
  init_cjs_shims();
116033
116680
  var logger11 = createModuleLogger("sdk.mapper");
@@ -116035,6 +116682,22 @@ var HIGH_WATERMARK_INPUT_TOKENS = 12e4;
116035
116682
  var WARN_THRESHOLD_INPUT_TOKENS = 1e5;
116036
116683
  var LIVE_INPUT_PREVIEW_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit"]);
116037
116684
  var CONTEXT_OVERFLOW_LOCK_MS = 6e4;
116685
+ function parseJsonRecord(text) {
116686
+ try {
116687
+ const parsed = JSON.parse(text);
116688
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
116689
+ } catch {
116690
+ return null;
116691
+ }
116692
+ }
116693
+ function isSuccessfulOfficialMediaOutput(toolName, output) {
116694
+ if (!isOfficialMediaGenerationToolName(toolName)) return false;
116695
+ const parsed = parseJsonRecord(output);
116696
+ if (!parsed) return false;
116697
+ const state = typeof parsed.state === "string" ? parsed.state.toLowerCase() : typeof parsed.status === "string" ? parsed.status.toLowerCase() : "";
116698
+ if (!["succeeded", "success", "completed", "done"].includes(state)) return false;
116699
+ return Array.isArray(parsed.images) && parsed.images.length > 0 || typeof parsed.video_url === "string" || typeof parsed.videoUrl === "string";
116700
+ }
116038
116701
  function isContextOverflowText(text) {
116039
116702
  const trimmed = text.trim();
116040
116703
  return /^prompt is too long\b/i.test(trimmed) || /context length .* exceed/i.test(trimmed);
@@ -116045,6 +116708,10 @@ function isAuthFailureText(text, sdkError) {
116045
116708
  function isProviderApiErrorText(text) {
116046
116709
  return /^API Error:\s*\d+/i.test(text.trim());
116047
116710
  }
116711
+ function isNoReplyText(text) {
116712
+ const normalized = text.trim().replace(/^`+|`+$/g, "").trim().toLowerCase();
116713
+ return normalized === NO_REPLY_TOKEN || normalized === "<no-reply>" || normalized === "no-reply" || normalized === "no_reply" || normalized === "no reply";
116714
+ }
116048
116715
  function decodeJsonStringFragment(raw) {
116049
116716
  let out = "";
116050
116717
  for (let i = 0; i < raw.length; i++) {
@@ -116531,7 +117198,7 @@ function emitGroupSegment(proc, emit, base, content, contentBlocks, isSilent = f
116531
117198
  }
116532
117199
  function flushTextSegmentOnBlockStop(proc, emit, base) {
116533
117200
  const trimmed = proc.segmentBuffer.trim();
116534
- const isSilent = trimmed === NO_REPLY_TOKEN;
117201
+ const isSilent = isNoReplyText(trimmed);
116535
117202
  const isEmpty = trimmed.length === 0;
116536
117203
  if (!isEmpty) {
116537
117204
  const blocksForSegment = [...proc.contentBlocks, { type: "text", content: proc.segmentBuffer }];
@@ -116629,8 +117296,10 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116629
117296
  if (block.type === "thinking") {
116630
117297
  proc.currentBlockType = "thinking";
116631
117298
  proc.accumulatedThinking = "";
117299
+ proc.suppressCurrentThinking = proc.officialMediaGenerationSatisfied === true;
116632
117300
  } else if (block.type === "text") {
116633
117301
  proc.currentBlockType = "text";
117302
+ proc.suppressCurrentThinking = false;
116634
117303
  if (isGroupTask(proc)) {
116635
117304
  proc.segmentBuffer = "";
116636
117305
  }
@@ -116639,10 +117308,11 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116639
117308
  proc.currentToolName = block.name ?? "unknown";
116640
117309
  proc.accumulatedToolInput = "";
116641
117310
  const toolName = block.name ?? "unknown";
117311
+ proc.suppressCurrentToolUse = proc.officialMediaGenerationSatisfied === true && isOfficialMediaGenerationToolName(toolName);
116642
117312
  const isMcpTool = parseMcpRuntimeToolName(toolName) != null;
116643
117313
  proc.currentMcpInvocationId = isMcpTool ? createMcpToolInvocationId() : null;
116644
117314
  proc.currentMcpInvocationStartedAt = isMcpTool ? (/* @__PURE__ */ new Date()).toISOString() : null;
116645
- if (toolName !== "ExitPlanMode" && !isAskUserQuestionToolName(toolName)) {
117315
+ if (!isGroupTask(proc) && !proc.suppressCurrentToolUse && toolName !== "ExitPlanMode" && !isAskUserQuestionToolName(toolName)) {
116646
117316
  emit({
116647
117317
  type: "agent:tool_use",
116648
117318
  payload: {
@@ -116665,17 +117335,20 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116665
117335
  const delta = ev.delta;
116666
117336
  if (!delta) break;
116667
117337
  if (delta.type === "thinking_delta" && typeof delta.thinking === "string") {
117338
+ if (proc.suppressCurrentThinking) break;
116668
117339
  proc.accumulatedThinking += delta.thinking;
116669
- emit({
116670
- type: "agent:thinking_chunk",
116671
- payload: { ...wireBase(base), chunk: delta.thinking }
116672
- });
117340
+ if (!isGroupTask(proc)) {
117341
+ emit({
117342
+ type: "agent:thinking_chunk",
117343
+ payload: { ...wireBase(base), chunk: delta.thinking }
117344
+ });
117345
+ }
116673
117346
  } else if (delta.type === "input_json_delta") {
116674
117347
  const partial2 = delta.partial_json;
116675
117348
  if (typeof partial2 === "string") {
116676
117349
  proc.accumulatedToolInput += partial2;
116677
117350
  const liveInput = extractLiveToolInput(proc.currentToolName, proc.accumulatedToolInput);
116678
- if (liveInput && proc.currentToolName != null) {
117351
+ if (!isGroupTask(proc) && liveInput && proc.currentToolName != null) {
116679
117352
  emit({
116680
117353
  type: "agent:tool_input_update",
116681
117354
  payload: {
@@ -116709,16 +117382,19 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116709
117382
  }
116710
117383
  case "content_block_stop": {
116711
117384
  if (proc.currentBlockType === "thinking") {
116712
- emit({
116713
- type: "agent:thinking_done",
116714
- payload: wireBase(getTaskBase(proc))
116715
- });
116716
- proc.contentBlocks.push({
116717
- type: "thinking",
116718
- content: proc.accumulatedThinking,
116719
- isComplete: true
116720
- });
117385
+ if (!isGroupTask(proc) && !proc.suppressCurrentThinking) {
117386
+ emit({
117387
+ type: "agent:thinking_done",
117388
+ payload: wireBase(getTaskBase(proc))
117389
+ });
117390
+ proc.contentBlocks.push({
117391
+ type: "thinking",
117392
+ content: proc.accumulatedThinking,
117393
+ isComplete: true
117394
+ });
117395
+ }
116721
117396
  proc.accumulatedThinking = "";
117397
+ proc.suppressCurrentThinking = false;
116722
117398
  } else if (proc.currentBlockType === "text" && isGroupTask(proc)) {
116723
117399
  flushTextSegmentOnBlockStop(proc, emit, base);
116724
117400
  } else if (proc.currentBlockType === "tool_use") {
@@ -116735,19 +117411,21 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116735
117411
  });
116736
117412
  }
116737
117413
  }
116738
- const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
116739
- if (lastToolUse && lastToolUse.type === "tool_use") {
116740
- lastToolUse.input = parsedInput;
116741
- }
116742
- if (proc.currentToolName != null && LIVE_INPUT_PREVIEW_TOOLS.has(proc.currentToolName) && Object.keys(parsedInput).length > 0) {
116743
- emit({
116744
- type: "agent:tool_input_update",
116745
- payload: {
116746
- ...wireBase(base),
116747
- toolName: proc.currentToolName,
116748
- input: parsedInput
116749
- }
116750
- });
117414
+ if (!proc.suppressCurrentToolUse) {
117415
+ const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
117416
+ if (lastToolUse && lastToolUse.type === "tool_use") {
117417
+ lastToolUse.input = parsedInput;
117418
+ }
117419
+ if (!isGroupTask(proc) && proc.currentToolName != null && LIVE_INPUT_PREVIEW_TOOLS.has(proc.currentToolName) && Object.keys(parsedInput).length > 0) {
117420
+ emit({
117421
+ type: "agent:tool_input_update",
117422
+ payload: {
117423
+ ...wireBase(base),
117424
+ toolName: proc.currentToolName,
117425
+ input: parsedInput
117426
+ }
117427
+ });
117428
+ }
116751
117429
  }
116752
117430
  if (proc.currentToolName === "TodoWrite") {
116753
117431
  const todos = extractTodosFromInput(parsedInput);
@@ -116812,7 +117490,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116812
117490
  proc.contentBlocks.pop();
116813
117491
  }
116814
117492
  }
116815
- if (proc.currentToolName && proc.currentMcpInvocationId && proc.currentMcpInvocationStartedAt && parseMcpRuntimeToolName(proc.currentToolName)) {
117493
+ if (proc.currentToolName && !proc.suppressCurrentToolUse && proc.currentMcpInvocationId && proc.currentMcpInvocationStartedAt && parseMcpRuntimeToolName(proc.currentToolName)) {
116816
117494
  try {
116817
117495
  proc.mcpAuditRecorder?.recordStart({
116818
117496
  id: proc.currentMcpInvocationId,
@@ -116835,6 +117513,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116835
117513
  }
116836
117514
  proc.accumulatedToolInput = "";
116837
117515
  }
117516
+ proc.suppressCurrentToolUse = false;
116838
117517
  proc.currentBlockType = null;
116839
117518
  break;
116840
117519
  }
@@ -116881,6 +117560,23 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116881
117560
  const toolName = proc.currentToolName ?? "unknown";
116882
117561
  const isError = toolName === "ExitPlanMode" ? false : !!b.is_error;
116883
117562
  const output = typeof b.content === "string" ? b.content : JSON.stringify(b.content);
117563
+ const duplicateOfficialMediaDeny = isError && isOfficialMediaGenerationToolName(toolName) && isOfficialMediaGenerationDuplicateDenyMessage(output);
117564
+ if (duplicateOfficialMediaDeny) {
117565
+ logger11.info("Suppressing duplicate official media tool denial after success", {
117566
+ agentId: proc.agentId,
117567
+ replyMessageId: base.replyMessageId,
117568
+ traceId: base.traceId,
117569
+ toolName
117570
+ });
117571
+ proc.currentMcpInvocationId = null;
117572
+ proc.currentMcpInvocationStartedAt = null;
117573
+ proc.currentToolName = null;
117574
+ continue;
117575
+ }
117576
+ if (isSuccessfulOfficialMediaOutput(toolName, output)) {
117577
+ proc.officialMediaGenerationSatisfied = true;
117578
+ proc.officialMediaSessionRecycleRequested = true;
117579
+ }
116884
117580
  if (isAskUserQuestionToolName(toolName)) {
116885
117581
  proc.currentToolName = null;
116886
117582
  continue;
@@ -116909,26 +117605,28 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116909
117605
  proc.currentMcpInvocationId = null;
116910
117606
  proc.currentMcpInvocationStartedAt = null;
116911
117607
  }
116912
- emit({
116913
- type: "agent:tool_result",
116914
- payload: {
116915
- ...wireBase(base),
117608
+ if (!isGroupTask(proc)) {
117609
+ emit({
117610
+ type: "agent:tool_result",
117611
+ payload: {
117612
+ ...wireBase(base),
117613
+ toolName,
117614
+ output,
117615
+ isError
117616
+ }
117617
+ });
117618
+ proc.contentBlocks.push({
117619
+ type: "tool_result",
116916
117620
  toolName,
116917
117621
  output,
116918
117622
  isError
116919
- }
116920
- });
116921
- proc.contentBlocks.push({
116922
- type: "tool_result",
116923
- toolName,
116924
- output,
116925
- isError
116926
- });
116927
- const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
116928
- if (lastToolUse && lastToolUse.type === "tool_use") {
116929
- lastToolUse.status = isError ? "error" : "done";
116930
- if (lastToolUse.toolName === "ExitPlanMode") {
116931
- proc.planModeActive = false;
117623
+ });
117624
+ const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
117625
+ if (lastToolUse && lastToolUse.type === "tool_use") {
117626
+ lastToolUse.status = isError ? "error" : "done";
117627
+ if (lastToolUse.toolName === "ExitPlanMode") {
117628
+ proc.planModeActive = false;
117629
+ }
116932
117630
  }
116933
117631
  }
116934
117632
  }
@@ -116987,7 +117685,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
116987
117685
  const groupMode = groupId != null;
116988
117686
  const usage = extractUsage(successMsg);
116989
117687
  const watermarkUsage = proc.peakContextUsage ?? usage;
116990
- if (trimmed === NO_REPLY_TOKEN) {
117688
+ if (isNoReplyText(trimmed)) {
116991
117689
  checkInputTokenWatermark(proc, watermarkUsage, base.traceId);
116992
117690
  emitUsageReported(proc, emit, base, usage);
116993
117691
  if (groupMode && proc.contentBlocks.length > 0) {
@@ -117328,6 +118026,9 @@ function resetAccumulators(proc) {
117328
118026
  proc.apiErrorEmitted = false;
117329
118027
  proc.peakContextUsage = void 0;
117330
118028
  proc.lastAssistantContentDescription = void 0;
118029
+ proc.officialMediaGenerationSatisfied = false;
118030
+ proc.suppressCurrentThinking = false;
118031
+ proc.suppressCurrentToolUse = false;
117331
118032
  }
117332
118033
 
117333
118034
  // src/forkHistoryReplay.ts
@@ -117519,11 +118220,24 @@ function missingSubscriptionMessage(subscriptionId) {
117519
118220
  }
117520
118221
  var NODE_USER_UID = 1e3;
117521
118222
  var POST_MERGE_CONTINUATION_ROUTE_MS = 15e3;
118223
+ var SCOPE_PROMPT_FINGERPRINT_REVISION = "workdir-scope-prompt-v2";
117522
118224
  var BINARY_ATTACHMENT_EXT_RE = /\.(?:7z|bmp|csv|doc|docx|gif|jpeg|jpg|m4a|mov|mp3|mp4|pdf|png|ppt|pptx|rar|rtf|wav|webm|webp|xls|xlsx|zip)$/i;
117523
118225
  var DOCUMENT_READING_RULES = `DOCUMENT READING:
117524
118226
  - The built-in Read tool cannot read binary office documents such as .docx, .xls, .xlsx, .pptx, .pdf, .odt, .ods, .odp, or .rtf.
117525
118227
  - When the user asks about document contents, use mcp__neural__read_document with the document path, or Read the provided .content.md extracted text path.
117526
118228
  - Do not report that a binary document is unreadable until you have tried read_document or the extracted text path.`;
118229
+ var MEDIA_GENERATION_RULES = `MEDIA GENERATION:
118230
+ - Official media MCP tools are first-class AHChat tasks. Do not use Bash, Monitor, sleep loops, background polling, curl polling, or TaskStop just to wait for image or video generation.
118231
+ - Seedream image tools return final images directly; no polling is needed. Generate exactly one image per user request for now. If the user asks for multiple candidates or a batch, say the current AHChat flow generates one image at a time and ask them to pick the first direction.
118232
+ - After a successful Seedream result, do not call another Seedream tool in the same turn to improve, regenerate, or create alternatives. If the user wants another version, ask them to send a new request after the current result is ready.
118233
+ - If a Seedream image tool returns an error, do not retry by switching between generate_image, edit_image, and generate_image_group in the same turn. Explain the issue briefly and ask for a usable public image URL/base64 image, or continue with text-only generation if the user confirms.
118234
+ - Seedance video flow: generate exactly one video per user request. Call mcp__seedance__seedance_create_task once; do not submit parallel tasks or alternate versions in the same turn. AHChat will track and refresh the visible media task card.
118235
+ - Keep media replies short. Do not print raw media URLs, request_id, task_id, polling logs, or "let me check again" narration unless the user explicitly asks for diagnostics.
118236
+ - When a media task is submitted or completed, write only a natural one-line note 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"; let the media card show status, preview, download, copy, and regenerate actions.
118237
+ - If the user asks whether a Seedance task is ready, call mcp__seedance__seedance_check_task once and answer from that result. Do not loop, sleep, or invent external Seedance API endpoints.`;
118238
+ function isRecoveryDispatchTask(task) {
118239
+ return task.dispatchKind === "manual_continue" || task.dispatchKind === "regenerate";
118240
+ }
117527
118241
  function isSmithAgent2(agent) {
117528
118242
  return isSmithAgent(agent);
117529
118243
  }
@@ -117640,6 +118354,9 @@ var AGENT_SKILL_PROFILE_TTL_MS = 6e4;
117640
118354
  function isBoundarySkillIndexEntry(entry) {
117641
118355
  return entry.permissionLevel === "high";
117642
118356
  }
118357
+ var OFFICIAL_MEDIA_SKILL_STEPS_BY_ID = new Map(
118358
+ OFFICIAL_MEDIA_SKILLS.map((skill) => [skill.id, skill.steps])
118359
+ );
117643
118360
  function buildTaskSkillContext(task, officeCliRuntime = null, runtimeSkillIndexEntries2 = [], skillProfile = null) {
117644
118361
  const assignedSkillIds = skillProfile?.assignedIds ?? null;
117645
118362
  const availableSkillIds = skillProfile?.availableIds ?? null;
@@ -117717,12 +118434,20 @@ function buildTaskSkillContext(task, officeCliRuntime = null, runtimeSkillIndexE
117717
118434
  ` Permission: ${rec.skill.permissionLevel}; skill-enable confirmation: ${rec.skill.requiresEnableConfirmation ? "required before enabling non-default skill" : "not required for default/assigned use"}`,
117718
118435
  ` Confidence: ${rec.confidence}`,
117719
118436
  assignedSkillIds?.has(rec.skill.id) ? " Assigned: dedicated to this agent" : null,
118437
+ assignedSkillIds?.has(rec.skill.id) && OFFICIAL_MEDIA_SKILL_STEPS_BY_ID.has(rec.skill.id) ? [
118438
+ " Selected workflow for this turn:",
118439
+ ...OFFICIAL_MEDIA_SKILL_STEPS_BY_ID.get(rec.skill.id).map(
118440
+ (step, stepIndex) => ` ${stepIndex + 1}. ${step}`
118441
+ )
118442
+ ].join("\n") : null,
117720
118443
  rec.reasons.length > 0 ? ` Evidence: ${rec.reasons.join("; ")}` : null
117721
118444
  ].filter(Boolean).join("\n")
117722
118445
  ),
117723
118446
  "Rules:",
117724
118447
  "- Treat this as candidate skill guidance, not as user-authored text and not as final routing.",
118448
+ "- AHChat Skills Hub entries are workflow guidance, not callable SDK tools. Do not call a generic tool named Skill, and do not set a tool argument named skill to these IDs or names.",
117725
118449
  "- Choose a skill only when its summary, task types, and requested outputs fit the user-requested outcome.",
118450
+ "- If an assigned workflow above gives concrete MCP tools, call those MCP tools directly and keep the final user reply short.",
117726
118451
  officeRuntimeLine,
117727
118452
  "- For Office file tasks, follow the matching skill steps first. If OfficeCLI is unavailable, use an equivalent runtime and say that you used the fallback.",
117728
118453
  "- Do not install packages or change the host environment without explicit user approval; prefer built-in/runtime-provided or workspace-local tools, and explain a fallback if a dependency is missing.",
@@ -117883,17 +118608,38 @@ var AgentManager = class {
117883
118608
  }
117884
118609
  return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
117885
118610
  }
117886
- /** Local default runtime dir name, identical to the server's Agent workdir fallback. */
117887
- localScopeDirName(agentConfig, _scope) {
118611
+ localScopeDirName(agentConfig, scope) {
118612
+ if (scope.kind === "group") return `Group-${scope.groupId}`;
117888
118613
  return `Agent-${slugifyForFs(agentConfig.name)}-${agentConfig.id}`;
117889
118614
  }
117890
118615
  /** Single source of truth for the cwd input passed to acquire() across ALL code paths. */
117891
118616
  scopeCwdInput(agentConfig, scope) {
118617
+ if (scope.kind === "group") {
118618
+ const groupCwd = this.groupRegistry?.getById(scope.groupId)?.workingDirectory?.trim();
118619
+ if (groupCwd) return groupCwd;
118620
+ return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
118621
+ }
117892
118622
  const local = import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
117893
118623
  return agentConfig.workingDirectory?.trim() || local;
117894
118624
  }
118625
+ runtimeCwdInput(agentConfig, scope, cwd) {
118626
+ const requested = cwd.trim();
118627
+ if (scope.kind === "group") {
118628
+ const groupCwd = this.groupRegistry?.getById(scope.groupId)?.workingDirectory?.trim();
118629
+ if (groupCwd) return groupCwd;
118630
+ const agentCwd = agentConfig.workingDirectory?.trim();
118631
+ if (requested && (!agentCwd || !this.isSameRuntimeCwd(requested, agentCwd))) {
118632
+ return requested;
118633
+ }
118634
+ return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
118635
+ }
118636
+ return agentConfig.workingDirectory?.trim() || requested || this.scopeCwdInput(agentConfig, scope);
118637
+ }
118638
+ workdirOverrideTarget(agentConfig, scope) {
118639
+ return scope.kind === "group" ? { targetKind: "group", targetId: scope.groupId } : { targetKind: "agent", targetId: agentConfig.id };
118640
+ }
117895
118641
  remapServerWorkspaceCwd(agentConfig, scope, requestedCwd) {
117896
- const overrideTarget = { targetKind: "agent", targetId: agentConfig.id };
118642
+ const overrideTarget = this.workdirOverrideTarget(agentConfig, scope);
117897
118643
  const overridden = this.workdirOverrideStore?.resolvePath(requestedCwd, overrideTarget);
117898
118644
  if (overridden?.overridden) {
117899
118645
  logger14.info("Local workdir override applied to runtime cwd", {
@@ -118093,7 +118839,7 @@ var AgentManager = class {
118093
118839
  modelInputModeForConfig(agentId, scope, cfg) {
118094
118840
  const key = runtimeKey(agentId, scope);
118095
118841
  if (this.visionBlockedScopes.has(key)) return "path-only";
118096
- return cfg.supportsVision === false ? "path-only" : "vision";
118842
+ return cfg.supportsVision === true ? "vision" : "path-only";
118097
118843
  }
118098
118844
  isSameRuntimeCwd(a, b) {
118099
118845
  const left = import_node_path13.default.normalize(a);
@@ -118172,6 +118918,40 @@ var AgentManager = class {
118172
118918
  });
118173
118919
  return null;
118174
118920
  }
118921
+ scopePromptFingerprint(agentConfig, scope, agentCwd, scopesSection) {
118922
+ return (0, import_node_crypto3.createHash)("sha256").update(SCOPE_PROMPT_FINGERPRINT_REVISION).update("\0").update(agentConfig.id).update("\0").update(agentConfig.name).update("\0").update(scopeKey(scope)).update("\0").update(import_node_path13.default.normalize(agentCwd)).update("\0").update(scopesSection).digest("hex");
118923
+ }
118924
+ discardSessionIfScopePromptChanged(agentConfig, scope, sessionId, fingerprint) {
118925
+ const previous = this.sessionStore.getPromptFingerprint(agentConfig.id, scope);
118926
+ if (!sessionId) {
118927
+ this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
118928
+ return null;
118929
+ }
118930
+ if (previous === fingerprint) return sessionId;
118931
+ if (!previous && scope.kind === "single") {
118932
+ this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
118933
+ logger14.info("Retaining legacy single-scope session while recording prompt fingerprint", {
118934
+ agentId: agentConfig.id,
118935
+ scope: scopeKey(scope),
118936
+ sessionId,
118937
+ nextFingerprint: fingerprint,
118938
+ revision: SCOPE_PROMPT_FINGERPRINT_REVISION
118939
+ });
118940
+ return sessionId;
118941
+ }
118942
+ this.sessionStore.delete(agentConfig.id, scope);
118943
+ this.dispatchMemory.deleteScope(agentConfig.id, scope);
118944
+ this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
118945
+ logger14.info("Cleared scoped session because scope prompt fingerprint changed", {
118946
+ agentId: agentConfig.id,
118947
+ scope: scopeKey(scope),
118948
+ sessionId,
118949
+ previousFingerprint: previous,
118950
+ nextFingerprint: fingerprint,
118951
+ revision: SCOPE_PROMPT_FINGERPRINT_REVISION
118952
+ });
118953
+ return null;
118954
+ }
118175
118955
  async awaitQueryReturn(query4, timeoutMs, agentId) {
118176
118956
  const ret = query4.return(void 0);
118177
118957
  try {
@@ -118227,6 +119007,47 @@ var AgentManager = class {
118227
119007
  this.agents.delete(key);
118228
119008
  this.lastUsedAt.delete(key);
118229
119009
  }
119010
+ /**
119011
+ * Runtime config reloads need a fresh SDK process, but the next turn should
119012
+ * resume the same Claude session so short follow-ups like "重新生成" keep context.
119013
+ */
119014
+ async closeRuntimeForRuntimeReload(proc, reason) {
119015
+ if (proc.status === "dead") return;
119016
+ const runtime = this.asRuntime(proc);
119017
+ const key = runtimeKey(proc.agentId, proc.scope);
119018
+ this.clearQuietFlushTimer(runtime);
119019
+ runtime.currentTask = null;
119020
+ runtime.injectedTasks = [];
119021
+ runtime.mergedTasks = [];
119022
+ runtime.planModeBuffer = [];
119023
+ runtime.groupInbox = [];
119024
+ try {
119025
+ runtime.inputController.close();
119026
+ await this.awaitQueryReturn(runtime.query, 5e3, proc.agentId);
119027
+ } catch (e) {
119028
+ logger14.error("runtime reload close failed", {
119029
+ agentId: proc.agentId,
119030
+ scope: scopeKey(proc.scope),
119031
+ reason,
119032
+ error: e
119033
+ });
119034
+ }
119035
+ proc.pendingTerminate = false;
119036
+ proc.pendingTerminatePreserveSession = false;
119037
+ proc.pendingTerminateReason = void 0;
119038
+ proc.status = "dead";
119039
+ this.agents.delete(key);
119040
+ this.lastUsedAt.delete(key);
119041
+ this.dormantScopes.delete(key);
119042
+ this.dormantGroupInboxes.delete(key);
119043
+ this.dispatchMemory.deleteScope(proc.agentId, proc.scope);
119044
+ logger14.info("runtime reload: scoped query removed, session preserved", {
119045
+ agentId: proc.agentId,
119046
+ scope: scopeKey(proc.scope),
119047
+ reason,
119048
+ sessionId: runtime.ccSessionId
119049
+ });
119050
+ }
118230
119051
  /** Evict LRU among idle (ready/starting + no injected tasks) agents past the idle timeout. */
118231
119052
  evictIdle() {
118232
119053
  const now = Date.now();
@@ -118303,13 +119124,15 @@ var AgentManager = class {
118303
119124
  throw new Error(`Refusing to spawn SDK runtime for human agent ${agentConfig.id}`);
118304
119125
  }
118305
119126
  const key = runtimeKey(agentConfig.id, scope);
118306
- const cwdInput = agentConfig.workingDirectory?.trim() || cwd || this.scopeCwdInput(agentConfig, scope);
119127
+ const cwdInput = this.runtimeCwdInput(agentConfig, scope, cwd);
118307
119128
  const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwdInput);
118308
119129
  const existing = this.agents.get(key);
118309
119130
  if (existing && existing.status !== "dead") {
118310
119131
  if (!this.isSameRuntimeCwd(existing.cwd, agentCwd) || existing.pendingTerminate) {
118311
119132
  if (existing.status === "working" && existing.currentTask) {
118312
119133
  existing.pendingTerminate = true;
119134
+ existing.pendingTerminatePreserveSession = false;
119135
+ existing.pendingTerminateReason = "cwd_changed";
118313
119136
  logger14.info("Runtime cwd changed while working; reload deferred until turn completes", {
118314
119137
  agentId: agentConfig.id,
118315
119138
  scope: scopeKey(scope),
@@ -118327,7 +119150,14 @@ var AgentManager = class {
118327
119150
  nextCwd: agentCwd,
118328
119151
  pendingTerminate: existing.pendingTerminate ?? false
118329
119152
  });
118330
- await this.terminateScope(agentConfig.id, scope);
119153
+ if (existing.pendingTerminatePreserveSession === true && this.isSameRuntimeCwd(existing.cwd, agentCwd)) {
119154
+ await this.closeRuntimeForRuntimeReload(
119155
+ existing,
119156
+ existing.pendingTerminateReason ?? "pending_runtime_reload"
119157
+ );
119158
+ } else {
119159
+ await this.terminateScope(agentConfig.id, scope);
119160
+ }
118331
119161
  } else {
118332
119162
  this.lastUsedAt.set(key, Date.now());
118333
119163
  return existing;
@@ -118344,7 +119174,7 @@ var AgentManager = class {
118344
119174
  throw new BridgeBusyError();
118345
119175
  }
118346
119176
  }
118347
- const proc = await this.getOrCreate(agentConfig, scope, agentCwd);
119177
+ const proc = await this.getOrCreate(agentConfig, scope, cwdInput);
118348
119178
  this.lastUsedAt.set(key, Date.now());
118349
119179
  return proc;
118350
119180
  }
@@ -118355,13 +119185,16 @@ var AgentManager = class {
118355
119185
  return existing;
118356
119186
  }
118357
119187
  const inputController = new InputController();
118358
- const cwdInput = agentConfig.workingDirectory?.trim() || cwd || this.scopeCwdInput(agentConfig, scope);
119188
+ const cwdInput = this.runtimeCwdInput(agentConfig, scope, cwd);
118359
119189
  const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwdInput);
118360
119190
  const cfg = await this.resolveAgentConfig(agentConfig);
118361
- if (cfg.instructions?.trim()) {
119191
+ const scopedInstructions = cfg.instructions?.trim() && scope.kind === "group" ? `# Agent project instructions
119192
+ ${cfg.instructions.trim()}` : "";
119193
+ if (cfg.instructions?.trim() && scope.kind === "single") {
118362
119194
  await import_promises3.default.writeFile(import_node_path13.default.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
118363
119195
  logger14.info("CLAUDE.md written", {
118364
119196
  agentId: agentConfig.id,
119197
+ scope: scopeKey(scope),
118365
119198
  bytes: cfg.instructions.trim().length
118366
119199
  });
118367
119200
  }
@@ -118372,7 +119205,10 @@ var AgentManager = class {
118372
119205
  try {
118373
119206
  await import_promises3.default.access(effectiveConfigDir);
118374
119207
  } catch (e) {
118375
- logger14.debug("Agent API key config dir missing; creating isolated dir", { error: e, agentId: agentConfig.id });
119208
+ logger14.debug("Agent API key config dir missing; creating isolated dir", {
119209
+ error: e,
119210
+ agentId: agentConfig.id
119211
+ });
118376
119212
  isNew = true;
118377
119213
  }
118378
119214
  await import_promises3.default.mkdir(effectiveConfigDir, { recursive: true });
@@ -118414,17 +119250,17 @@ var AgentManager = class {
118414
119250
  });
118415
119251
  }
118416
119252
  let savedSessionId = this.sessionStore.get(agentConfig.id, scope);
118417
- const agentOverride = agentConfig.workingDirectory ? this.workdirOverrideStore?.resolvePath(agentConfig.workingDirectory, {
118418
- targetKind: "agent",
118419
- targetId: agentConfig.id
118420
- }) : null;
119253
+ const runtimeOverride = cwdInput ? this.workdirOverrideStore?.resolvePath(
119254
+ cwdInput,
119255
+ this.workdirOverrideTarget(agentConfig, scope)
119256
+ ) : null;
118421
119257
  savedSessionId = this.discardSessionIfItBelongsToAnotherCwd(
118422
119258
  agentConfig,
118423
119259
  scope,
118424
119260
  agentCwd,
118425
119261
  effectiveConfigDir,
118426
119262
  savedSessionId,
118427
- agentOverride?.overridden === true
119263
+ runtimeOverride?.overridden === true
118428
119264
  );
118429
119265
  const queryFn = await this.getQueryFn();
118430
119266
  let procRef = null;
@@ -118490,11 +119326,28 @@ var AgentManager = class {
118490
119326
  },
118491
119327
  onLeaveGroup: (groupId) => this.deferLeaveGroup(agentConfig.id, groupId)
118492
119328
  });
119329
+ if (this.mcpRegistry) {
119330
+ try {
119331
+ await this.mcpRegistry.refresh();
119332
+ } catch (e) {
119333
+ logger14.warn("MCP registry refresh before runtime failed; using cached MCP config", {
119334
+ error: e,
119335
+ agentId: agentConfig.id,
119336
+ scope: scopeKey(scope)
119337
+ });
119338
+ }
119339
+ }
118493
119340
  const externalMcp = this.mcpRegistry?.buildForAgent({
118494
119341
  agentId: agentConfig.id,
118495
119342
  capabilityTier: cfg.capabilityTier,
118496
119343
  isSmith: smithAgent
118497
119344
  }) ?? { mcpServers: {}, allowedTools: [] };
119345
+ logger14.info("External MCP resolved for runtime", {
119346
+ agentId: agentConfig.id,
119347
+ scope: scopeKey(scope),
119348
+ serverNames: Object.keys(externalMcp.mcpServers),
119349
+ allowedToolCount: externalMcp.allowedTools.length
119350
+ });
118498
119351
  if (this.memoryStore) {
118499
119352
  logger14.info("Notebook pull on runtime start", {
118500
119353
  agentId: agentConfig.id,
@@ -118504,7 +119357,13 @@ var AgentManager = class {
118504
119357
  await this.memoryStore.pullFromServer(agentConfig.id);
118505
119358
  }
118506
119359
  const notebookSection = this.buildNotebookSection(agentConfig.id);
118507
- const scopesSection = this.buildScopesSection(agentConfig.id, scope, agentCwd);
119360
+ const scopesSection = this.buildScopesSection(agentConfig, scope, agentCwd);
119361
+ savedSessionId = this.discardSessionIfScopePromptChanged(
119362
+ agentConfig,
119363
+ scope,
119364
+ savedSessionId,
119365
+ this.scopePromptFingerprint(agentConfig, scope, agentCwd, scopesSection)
119366
+ );
118508
119367
  let forkHistorySection = "";
118509
119368
  if (!savedSessionId && scope.kind === "single") {
118510
119369
  const forkMeta = await consumeForkMeta(this.dataDir, agentConfig.id);
@@ -118542,6 +119401,7 @@ var AgentManager = class {
118542
119401
  cronLockOwnedByMe: cronLockSnapshot.sessionId != null && cronLockSnapshot.sessionId === savedSessionId
118543
119402
  });
118544
119403
  const planModeRef = { active: false, denyCount: 0 };
119404
+ const mediaGenerationTurnGuard = createOfficialMediaGenerationTurnGuard();
118545
119405
  const builtinWebSearchAllowed = this.queryConfig.allowBuiltinWebSearch;
118546
119406
  const options = {
118547
119407
  cwd: agentCwd,
@@ -118551,7 +119411,9 @@ var AgentManager = class {
118551
119411
  append: [
118552
119412
  PLATFORM_AGENT_RULES,
118553
119413
  DOCUMENT_READING_RULES,
119414
+ MEDIA_GENERATION_RULES,
118554
119415
  agentConfig.systemPrompt,
119416
+ scopedInstructions,
118555
119417
  notebookSection,
118556
119418
  forkHistorySection,
118557
119419
  scopesSection
@@ -118559,8 +119421,9 @@ var AgentManager = class {
118559
119421
  },
118560
119422
  permissionMode: "bypassPermissions",
118561
119423
  allowDangerouslySkipPermissions: true,
118562
- // allowedTools = auto-allow without prompting (irrelevant in bypassPermissions mode,
118563
- // but set to all available tools for consistency).
119424
+ // allowedTools is the visibility whitelist passed to Claude Code. MCP tools
119425
+ // with always_ask must still be included here so the model can request them;
119426
+ // the MCP server policy/permission layer decides whether execution asks.
118564
119427
  allowedTools: [
118565
119428
  "Read",
118566
119429
  "Edit",
@@ -118831,6 +119694,15 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
118831
119694
  },
118832
119695
  hooks: {
118833
119696
  PreToolUse: [
119697
+ ...createOfficialMediaGenerationPreToolUseHooks(
119698
+ mediaGenerationTurnGuard,
119699
+ externalMcp.allowedTools,
119700
+ {
119701
+ agentId: agentConfig.id,
119702
+ scope: scopeKey(scope),
119703
+ log: (msg, meta3) => logger14.warn(msg, meta3)
119704
+ }
119705
+ ),
118834
119706
  {
118835
119707
  matcher: "ExitPlanMode",
118836
119708
  hooks: [
@@ -118892,7 +119764,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
118892
119764
  await chownForRootSpawn(settingsFilePath, "settingsFile");
118893
119765
  options.spawnClaudeCodeProcess = (spawnOptions) => {
118894
119766
  const env2 = { ...spawnOptions.env, HOME: "/home/node" };
118895
- return (0, import_node_child_process2.spawn)(spawnOptions.command, spawnOptions.args, {
119767
+ return (0, import_node_child_process3.spawn)(spawnOptions.command, spawnOptions.args, {
118896
119768
  cwd: spawnOptions.cwd,
118897
119769
  env: env2,
118898
119770
  stdio: ["pipe", "pipe", "pipe"],
@@ -118939,6 +119811,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
118939
119811
  segmentCount: 0,
118940
119812
  accumulatedToolInput: "",
118941
119813
  planModeRef,
119814
+ mediaGenerationTurnGuard,
118942
119815
  groupInbox: []
118943
119816
  };
118944
119817
  const runtime = Object.assign(proc, {
@@ -119056,7 +119929,15 @@ ${trimmed}`;
119056
119929
  });
119057
119930
  return section;
119058
119931
  }
119059
- buildScopesSection(agentId, scope, currentCwd) {
119932
+ promptWorkdir(agentConfig, scope, requestedCwd) {
119933
+ const remapped = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
119934
+ if (!isFullyQualifiedAbsolutePath(remapped)) {
119935
+ return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119936
+ }
119937
+ return remapped;
119938
+ }
119939
+ buildScopesSection(agentConfig, scope, currentCwd) {
119940
+ const agentId = agentConfig.id;
119060
119941
  if (!this.groupRegistry) {
119061
119942
  logger14.info("Scopes injection skipped", { agentId, reason: "no_group_registry" });
119062
119943
  return "";
@@ -119065,15 +119946,32 @@ ${trimmed}`;
119065
119946
  const curKey = scopeKey(scope);
119066
119947
  const lines = [];
119067
119948
  const isCurSingle = curKey === "single";
119949
+ const singleScope = { kind: "single" };
119950
+ const singleWorkdir = isCurSingle ? currentCwd : this.promptWorkdir(agentConfig, singleScope, this.scopeCwdInput(agentConfig, singleScope));
119951
+ lines.push("Workdir semantics:");
119952
+ lines.push("- single workdir = your private Agent workspace for 1:1 chat.");
119953
+ lines.push(
119954
+ "- group workdir = that group's shared workspace; it is your runtime cwd while you are in that group."
119955
+ );
119956
+ lines.push(
119957
+ '- If asked for "your own workdir" vs "this group workdir", report the separate paths shown below.'
119958
+ );
119959
+ lines.push("");
119068
119960
  lines.push(`- single \u2014 1:1 chat with the user${isCurSingle ? " (you are here)" : ""}`);
119069
- lines.push(` workdir: ${currentCwd}`);
119961
+ lines.push(` workdir: ${singleWorkdir}`);
119070
119962
  let rosterCount = 0;
119071
119963
  for (const g of myGroups) {
119072
119964
  const key = `group:${g.groupId}`;
119073
119965
  const here = key === curKey ? " (you are here)" : "";
119074
119966
  const userMark = g.userJoined ? " [user joined]" : " [no user]";
119075
119967
  lines.push(`- ${key} \u2014 ${g.name}${here}${userMark}`);
119076
- lines.push(` workdir: ${currentCwd}`);
119968
+ const groupScope = { kind: "group", groupId: g.groupId };
119969
+ const groupWorkdir = key === curKey ? currentCwd : this.promptWorkdir(
119970
+ agentConfig,
119971
+ groupScope,
119972
+ g.workingDirectory?.trim() || this.scopeCwdInput(agentConfig, groupScope)
119973
+ );
119974
+ lines.push(` workdir: ${groupWorkdir}`);
119077
119975
  const others = g.members.filter((id) => id !== agentId).map((id) => {
119078
119976
  const a = this.agentRegistry?.getById(id);
119079
119977
  return a ? `${a.name} (${id}, role: ${a.role})` : `Agent(${id})`;
@@ -119156,6 +120054,28 @@ ${lines.join("\n")}`;
119156
120054
  await this.dispatchToSDK(runtime, task);
119157
120055
  return;
119158
120056
  }
120057
+ if (isRecoveryDispatchTask(task)) {
120058
+ logger14.warn("Recovery dispatch rejected while Agent is already working", {
120059
+ agentId: task.agentId,
120060
+ scope: scopeKey(task.scope),
120061
+ replyMessageId: task.replyMessageId,
120062
+ conversationId: task.conversationId,
120063
+ currentTaskReplyMessageId: runtime.currentTask?.replyMessageId,
120064
+ dispatchKind: task.dispatchKind,
120065
+ traceId: task.traceId
120066
+ });
120067
+ this.emit({
120068
+ type: "agent:error",
120069
+ payload: {
120070
+ agentId: task.agentId,
120071
+ conversationId: task.conversationId,
120072
+ ackId: task.replyMessageId,
120073
+ traceId: task.traceId,
120074
+ error: "Bridge is already working on another reply; recovery dispatch was rejected."
120075
+ }
120076
+ });
120077
+ return;
120078
+ }
119159
120079
  if (proc.planModeActive) {
119160
120080
  runtime.planModeBuffer.push(task);
119161
120081
  logger14.info("Message buffered during plan mode", {
@@ -119505,6 +120425,7 @@ ${lines.join("\n")}`;
119505
120425
  runtime.status = "working";
119506
120426
  runtime.currentTask = task;
119507
120427
  runtime.currentTaskStartedAt = Date.now();
120428
+ resetOfficialMediaGenerationTurnGuard(runtime.mediaGenerationTurnGuard, task.replyMessageId);
119508
120429
  runtime.cachedConversationId = task.conversationId;
119509
120430
  logger14.info("Agent run started", {
119510
120431
  agentId: runtime.agentId,
@@ -119652,9 +120573,9 @@ ${lines.join("\n")}`;
119652
120573
  throw new Error(`HTTP ${res.status}`);
119653
120574
  }
119654
120575
  const body = await res.json();
119655
- const runtimeCachedSkillIds = this.getRuntimeCachedSkillIds();
120576
+ const runtimeCachedSkillIds2 = this.getRuntimeCachedSkillIds();
119656
120577
  const serverAssignedIds = (body.assigned ?? []).map((s) => s.id);
119657
- const cachedServerAssignedIds = serverAssignedIds.filter((id) => runtimeCachedSkillIds.has(id));
120578
+ const cachedServerAssignedIds = serverAssignedIds.filter((id) => runtimeCachedSkillIds2.has(id));
119658
120579
  const localRuntimeSkillIds = this.getLocalRuntimeSkillIdsForAgent(agentId);
119659
120580
  const assignedIds = /* @__PURE__ */ new Set([...serverAssignedIds, ...localRuntimeSkillIds]);
119660
120581
  const availableIds = /* @__PURE__ */ new Set([...cachedServerAssignedIds, ...localRuntimeSkillIds]);
@@ -119999,7 +120920,7 @@ ${lines.join("\n")}`;
119999
120920
  }
120000
120921
  });
120001
120922
  }
120002
- const continuationTask = mergedBatch.at(-1);
120923
+ const continuationTask = mergedBatch.filter((task) => !isRecoveryDispatchTask(task)).at(-1);
120003
120924
  if (continuationTask) {
120004
120925
  proc.postMergeContinuationTask = continuationTask;
120005
120926
  proc.postMergeContinuationUntil = Date.now() + POST_MERGE_CONTINUATION_ROUTE_MS;
@@ -120011,6 +120932,16 @@ ${lines.join("\n")}`;
120011
120932
  routeUntil: new Date(proc.postMergeContinuationUntil).toISOString(),
120012
120933
  traceId: completedTask.traceId
120013
120934
  });
120935
+ } else {
120936
+ delete proc.postMergeContinuationTask;
120937
+ delete proc.postMergeContinuationUntil;
120938
+ logger14.info("Skipped post-merge continuation routing for recovery-only merged tasks", {
120939
+ agentId: proc.agentId,
120940
+ carrierReplyMessageId: completedTask.replyMessageId,
120941
+ mergedCount: mergedBatch.length,
120942
+ mergedReplyMessageIds: mergedBatch.map((task) => task.replyMessageId),
120943
+ traceId: completedTask.traceId
120944
+ });
120014
120945
  }
120015
120946
  runtime.mergedTasks = [];
120016
120947
  } else if (runtime.mergedTasks.length > 0) {
@@ -120020,6 +120951,37 @@ ${lines.join("\n")}`;
120020
120951
  });
120021
120952
  runtime.mergedTasks = [];
120022
120953
  }
120954
+ if (proc.officialMediaSessionRecycleRequested) {
120955
+ const hasPendingWork = runtime.injectedTasks.length > 0 || runtime.planModeBuffer.length > 0 || runtime.groupInbox.length > 0 || proc.postMergeContinuationTask != null || proc.pendingTerminate === true || proc.compactRequested === true || proc.pendingLeaveGroupId != null;
120956
+ if (!hasPendingWork) {
120957
+ proc.officialMediaSessionRecycleRequested = false;
120958
+ this.sessionStore.delete(proc.agentId, proc.scope);
120959
+ this.dispatchMemory.deleteScope(proc.agentId, proc.scope);
120960
+ logger14.info("Recycling SDK session after successful official media generation", {
120961
+ agentId: proc.agentId,
120962
+ scope: scopeKey(proc.scope),
120963
+ sessionId: proc.ccSessionId,
120964
+ completedAckId: completedTask?.replyMessageId,
120965
+ traceId: completedTask?.traceId
120966
+ });
120967
+ void this.closeRuntime(proc, "official_media_session_recycle");
120968
+ return;
120969
+ }
120970
+ logger14.info("Official media session recycle deferred because pending work remains", {
120971
+ agentId: proc.agentId,
120972
+ scope: scopeKey(proc.scope),
120973
+ sessionId: proc.ccSessionId,
120974
+ injectedTasks: runtime.injectedTasks.length,
120975
+ planModeBuffer: runtime.planModeBuffer.length,
120976
+ groupInbox: runtime.groupInbox.length,
120977
+ hasPostMergeContinuation: proc.postMergeContinuationTask != null,
120978
+ pendingTerminate: proc.pendingTerminate === true,
120979
+ compactRequested: proc.compactRequested === true,
120980
+ pendingLeaveGroup: proc.pendingLeaveGroupId != null,
120981
+ completedAckId: completedTask?.replyMessageId,
120982
+ traceId: completedTask?.traceId
120983
+ });
120984
+ }
120023
120985
  if (proc.pendingTerminate) {
120024
120986
  this.checkPendingTerminate(proc);
120025
120987
  return;
@@ -120104,6 +121066,7 @@ ${lines.join("\n")}`;
120104
121066
  proc.currentTask = next;
120105
121067
  proc.status = "working";
120106
121068
  proc.currentTaskStartedAt = Date.now();
121069
+ resetOfficialMediaGenerationTurnGuard(runtime.mediaGenerationTurnGuard, next.replyMessageId);
120107
121070
  logger14.info("Promoted next injected task after result", {
120108
121071
  agentId: proc.agentId,
120109
121072
  replyMessageId: next.replyMessageId,
@@ -120283,7 +121246,7 @@ ${lines.join("\n")}`;
120283
121246
  userInScope: group?.userJoined === true
120284
121247
  };
120285
121248
  }
120286
- deliverNeuralSend(agentConfig, payload) {
121249
+ async deliverNeuralSend(agentConfig, payload) {
120287
121250
  if (agentConfig.kind === "human") {
120288
121251
  logger14.warn("Neural send rejected: target is human principal", {
120289
121252
  agentId: agentConfig.id,
@@ -120322,8 +121285,31 @@ ${lines.join("\n")}`;
120322
121285
  traceId: createTraceId(),
120323
121286
  groupId: payload.groupId
120324
121287
  };
121288
+ const cwd = payload.targetCwd?.trim() || this.scopeCwdInput(agentConfig, targetScope);
121289
+ const resolvedCwd = await this.resolveRuntimeCwd(agentConfig, targetScope, cwd);
120325
121290
  const key = runtimeKey(agentConfig.id, targetScope);
120326
- const existingProc = this.agents.get(key);
121291
+ let existingProc = this.agents.get(key);
121292
+ if (existingProc && existingProc.status !== "dead" && !this.isSameRuntimeCwd(existingProc.cwd, resolvedCwd)) {
121293
+ if (existingProc.status === "working" && existingProc.currentTask) {
121294
+ existingProc.pendingTerminate = true;
121295
+ logger14.info("Neural send target runtime cwd changed while working; reload deferred", {
121296
+ agentId: agentConfig.id,
121297
+ toScope: payload.toScopeKey,
121298
+ currentCwd: existingProc.cwd,
121299
+ nextCwd: resolvedCwd,
121300
+ replyMessageId: existingProc.currentTask.replyMessageId
121301
+ });
121302
+ } else {
121303
+ logger14.info("Neural send target runtime cwd changed while idle; rebuilding", {
121304
+ agentId: agentConfig.id,
121305
+ toScope: payload.toScopeKey,
121306
+ currentCwd: existingProc.cwd,
121307
+ nextCwd: resolvedCwd
121308
+ });
121309
+ await this.terminateScope(agentConfig.id, targetScope);
121310
+ existingProc = void 0;
121311
+ }
121312
+ }
120327
121313
  logger14.info("Neural send dispatching", {
120328
121314
  agentId: agentConfig.id,
120329
121315
  fromScope: payload.fromScopeKey,
@@ -120334,6 +121320,7 @@ ${lines.join("\n")}`;
120334
121320
  messageLen: payload.message.length,
120335
121321
  conversationId: payload.conversationId ?? "(none)",
120336
121322
  groupId: payload.groupId ?? "(none)",
121323
+ cwd: resolvedCwd,
120337
121324
  replyMessageId: task.replyMessageId,
120338
121325
  peerCount: ctx.peers.length,
120339
121326
  peerNames: ctx.peers.map((p) => p.name),
@@ -120366,13 +121353,12 @@ ${lines.join("\n")}`;
120366
121353
  }
120367
121354
  return;
120368
121355
  }
120369
- const cwd = this.scopeCwdInput(agentConfig, targetScope);
120370
- void this.acquire(agentConfig, targetScope, cwd).then(() => {
121356
+ void this.acquire(agentConfig, targetScope, resolvedCwd).then(() => {
120371
121357
  logger14.info("Neural send new runtime acquired", {
120372
121358
  agentId: agentConfig.id,
120373
121359
  toScope: payload.toScopeKey,
120374
121360
  traceId: task.traceId,
120375
- cwd,
121361
+ cwd: resolvedCwd,
120376
121362
  replyMessageId: task.replyMessageId
120377
121363
  });
120378
121364
  return this.sendMessage({ ...task, agentId: agentConfig.id, scope: targetScope });
@@ -120381,7 +121367,7 @@ ${lines.join("\n")}`;
120381
121367
  agentId: agentConfig.id,
120382
121368
  toScope: payload.toScopeKey,
120383
121369
  traceId: task.traceId,
120384
- cwd,
121370
+ cwd: resolvedCwd,
120385
121371
  error: err
120386
121372
  });
120387
121373
  });
@@ -120568,16 +121554,19 @@ ${lines.join("\n")}`;
120568
121554
  for (const proc of [...this.agents.values()]) {
120569
121555
  if (proc.status === "working" || proc.status === "starting") {
120570
121556
  proc.pendingTerminate = true;
121557
+ proc.pendingTerminatePreserveSession = true;
121558
+ proc.pendingTerminateReason = reason;
120571
121559
  deferred++;
120572
121560
  logger14.info("Runtime reload deferred until turn completes", {
120573
121561
  agentId: proc.agentId,
120574
121562
  scope: scopeKey(proc.scope),
120575
121563
  status: proc.status,
120576
- reason
121564
+ reason,
121565
+ preserveSession: true
120577
121566
  });
120578
121567
  continue;
120579
121568
  }
120580
- await this.terminateScope(proc.agentId, proc.scope);
121569
+ await this.closeRuntimeForRuntimeReload(proc, reason);
120581
121570
  terminated++;
120582
121571
  }
120583
121572
  return { terminated, deferred };
@@ -120596,7 +121585,9 @@ ${lines.join("\n")}`;
120596
121585
  )) {
120597
121586
  this.dormantGroupInboxes.delete(key);
120598
121587
  }
120599
- const result = await this.terminateAgentForRuntimeReload(agentId, reason);
121588
+ const result = await this.terminateAgentForRuntimeReload(agentId, reason, {
121589
+ preserveSession: false
121590
+ });
120600
121591
  logger14.info("Agent scoped runtime reload requested", {
120601
121592
  agentId,
120602
121593
  reason,
@@ -120605,9 +121596,10 @@ ${lines.join("\n")}`;
120605
121596
  });
120606
121597
  return result;
120607
121598
  }
120608
- async terminateAgentForRuntimeReload(agentId, reason) {
121599
+ async terminateAgentForRuntimeReload(agentId, reason, options = {}) {
120609
121600
  let terminated = 0;
120610
121601
  let deferred = 0;
121602
+ const preserveSession = options.preserveSession ?? true;
120611
121603
  const procs = [...this.agents.values()].filter((proc) => proc.agentId === agentId);
120612
121604
  if (procs.length === 0) {
120613
121605
  logger14.info("runtime reload: no live runtime for agent", { agentId, reason });
@@ -120616,16 +121608,23 @@ ${lines.join("\n")}`;
120616
121608
  for (const proc of procs) {
120617
121609
  if (proc.status === "working" || proc.status === "starting") {
120618
121610
  proc.pendingTerminate = true;
121611
+ proc.pendingTerminatePreserveSession = preserveSession;
121612
+ proc.pendingTerminateReason = reason;
120619
121613
  deferred++;
120620
121614
  logger14.info("Runtime reload deferred until turn completes", {
120621
121615
  agentId: proc.agentId,
120622
121616
  scope: scopeKey(proc.scope),
120623
121617
  status: proc.status,
120624
- reason
121618
+ reason,
121619
+ preserveSession
120625
121620
  });
120626
121621
  continue;
120627
121622
  }
120628
- await this.terminateScope(proc.agentId, proc.scope);
121623
+ if (preserveSession) {
121624
+ await this.closeRuntimeForRuntimeReload(proc, reason);
121625
+ } else {
121626
+ await this.terminateScope(proc.agentId, proc.scope);
121627
+ }
120629
121628
  terminated++;
120630
121629
  }
120631
121630
  return { terminated, deferred };
@@ -120677,7 +121676,11 @@ ${lines.join("\n")}`;
120677
121676
  */
120678
121677
  checkPendingTerminate(proc) {
120679
121678
  if (!proc.pendingTerminate) return;
121679
+ const preserveSession = proc.pendingTerminatePreserveSession === true;
121680
+ const reason = proc.pendingTerminateReason ?? "deferred_terminate";
120680
121681
  proc.pendingTerminate = false;
121682
+ proc.pendingTerminatePreserveSession = false;
121683
+ proc.pendingTerminateReason = void 0;
120681
121684
  const runtime = this.asRuntime(proc);
120682
121685
  const pendingTasks = [...runtime.injectedTasks.splice(0), ...runtime.planModeBuffer.splice(0)];
120683
121686
  for (const task of pendingTasks) {
@@ -120712,10 +121715,16 @@ ${lines.join("\n")}`;
120712
121715
  logger14.info("checkPendingTerminate: executing deferred runtime-reload teardown", {
120713
121716
  agentId: proc.agentId,
120714
121717
  scope: scopeKey(proc.scope),
121718
+ reason,
121719
+ preserveSession,
120715
121720
  releasedPendingTaskCount: pendingTasks.length,
120716
121721
  releasedInboxCount: pendingInbox.length
120717
121722
  });
120718
- void this.terminateScope(proc.agentId, proc.scope);
121723
+ if (preserveSession) {
121724
+ void this.closeRuntimeForRuntimeReload(proc, reason);
121725
+ } else {
121726
+ void this.terminateScope(proc.agentId, proc.scope);
121727
+ }
120719
121728
  }
120720
121729
  /** Stop one scoped SDK runtime (workdir change). */
120721
121730
  async terminateScope(agentId, scope) {
@@ -120731,6 +121740,8 @@ ${lines.join("\n")}`;
120731
121740
  }
120732
121741
  if (proc.status === "working" && proc.currentTask) {
120733
121742
  proc.pendingTerminate = true;
121743
+ proc.pendingTerminatePreserveSession = false;
121744
+ proc.pendingTerminateReason = "terminate_scope";
120734
121745
  logger14.info("terminateScope: runtime working; teardown deferred until turn completes", {
120735
121746
  agentId,
120736
121747
  scope: scopeKey(scope),
@@ -121061,6 +122072,109 @@ ${lines.join("\n")}`;
121061
122072
  }
121062
122073
  return [...ids];
121063
122074
  }
122075
+ latestOpenToolUse(proc) {
122076
+ for (let i = proc.contentBlocks.length - 1; i >= 0; i -= 1) {
122077
+ const block = proc.contentBlocks[i];
122078
+ if (block?.type !== "tool_use") continue;
122079
+ if (block.status === "pending" || block.status === "running" || block.status === "paused" || block.status === "resumed") {
122080
+ return block;
122081
+ }
122082
+ return null;
122083
+ }
122084
+ return null;
122085
+ }
122086
+ emitLiveToolInputSnapshotForResume(proc, payload) {
122087
+ const task = proc.currentTask;
122088
+ const openTool = this.latestOpenToolUse(proc);
122089
+ if (!task || !openTool) return false;
122090
+ const toolName = proc.currentToolName ?? openTool.toolName;
122091
+ if (toolName !== openTool.toolName) return false;
122092
+ const liveInput = proc.accumulatedToolInput.length > 0 ? extractLiveToolInput(toolName, proc.accumulatedToolInput) : null;
122093
+ const input = liveInput && Object.keys(liveInput).length > 0 ? liveInput : Object.keys(openTool.input).length > 0 ? openTool.input : null;
122094
+ if (!input) return false;
122095
+ openTool.input = input;
122096
+ this.emit({
122097
+ type: "agent:tool_input_update",
122098
+ payload: {
122099
+ ackId: task.replyMessageId,
122100
+ agentId: proc.agentId,
122101
+ conversationId: task.conversationId,
122102
+ toolName,
122103
+ input,
122104
+ traceId: payload.traceId
122105
+ }
122106
+ });
122107
+ logger14.info("Reply session resume emitted live tool input snapshot", {
122108
+ requestId: payload.requestId,
122109
+ replySessionId: payload.replySessionId,
122110
+ replyMessageId: payload.replyMessageId,
122111
+ agentId: payload.agentId,
122112
+ scope: scopeKey(proc.scope),
122113
+ toolName,
122114
+ inputKeys: Object.keys(input),
122115
+ accumulatedToolInputLen: proc.accumulatedToolInput.length,
122116
+ traceId: payload.traceId
122117
+ });
122118
+ return true;
122119
+ }
122120
+ resumeReplySession(payload) {
122121
+ for (const [, proc] of this.agents) {
122122
+ if (proc.agentId !== payload.agentId) continue;
122123
+ const runtime = this.asRuntime(proc);
122124
+ if (runtime.currentTask?.replyMessageId !== payload.replyMessageId) continue;
122125
+ const lastTokenIndex = Math.max(0, payload.lastTokenIndex ?? 0);
122126
+ const missingDelta = runtime.accumulatedText.length > lastTokenIndex ? runtime.accumulatedText.slice(lastTokenIndex) : void 0;
122127
+ const canResume = proc.status === "working";
122128
+ const liveToolInputSnapshotEmitted = canResume ? this.emitLiveToolInputSnapshotForResume(runtime, payload) : false;
122129
+ logger14.info("Reply session resume resolved from active runtime", {
122130
+ requestId: payload.requestId,
122131
+ replySessionId: payload.replySessionId,
122132
+ replyMessageId: payload.replyMessageId,
122133
+ agentId: payload.agentId,
122134
+ scope: scopeKey(proc.scope),
122135
+ canResume,
122136
+ accumulatedTextLen: runtime.accumulatedText.length,
122137
+ missingDeltaLen: missingDelta?.length ?? 0,
122138
+ liveToolInputSnapshotEmitted,
122139
+ traceId: payload.traceId
122140
+ });
122141
+ return {
122142
+ requestId: payload.requestId,
122143
+ replySessionId: payload.replySessionId,
122144
+ replyMessageId: payload.replyMessageId,
122145
+ agentId: payload.agentId,
122146
+ conversationId: payload.conversationId,
122147
+ canResume,
122148
+ currentStatus: canResume ? "replying" : "paused",
122149
+ recoverability: canResume ? "resumable" : "retryable",
122150
+ ...missingDelta ? { missingDelta } : {},
122151
+ reason: canResume ? "active_runtime_resumed" : "runtime_not_working",
122152
+ traceId: payload.traceId,
122153
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
122154
+ };
122155
+ }
122156
+ logger14.warn("Reply session resume could not find active runtime", {
122157
+ requestId: payload.requestId,
122158
+ replySessionId: payload.replySessionId,
122159
+ replyMessageId: payload.replyMessageId,
122160
+ agentId: payload.agentId,
122161
+ conversationId: payload.conversationId,
122162
+ traceId: payload.traceId
122163
+ });
122164
+ return {
122165
+ requestId: payload.requestId,
122166
+ replySessionId: payload.replySessionId,
122167
+ replyMessageId: payload.replyMessageId,
122168
+ agentId: payload.agentId,
122169
+ conversationId: payload.conversationId,
122170
+ canResume: false,
122171
+ currentStatus: "paused",
122172
+ recoverability: "retryable",
122173
+ reason: "reply_session_not_found",
122174
+ traceId: payload.traceId,
122175
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
122176
+ };
122177
+ }
121064
122178
  /**
121065
122179
  * Resolve the conversationId that a scope-notice task should land on for the
121066
122180
  * given runtime scope. Returns null on resolve failure (server unreachable,
@@ -121173,7 +122287,8 @@ ${lines.join("\n")}`;
121173
122287
  }
121174
122288
  const runtime = this.asRuntime(proc);
121175
122289
  const key = runtimeKey(agentId, proc.scope);
121176
- const hadPendingRuntimeReload = proc.pendingTerminate === true;
122290
+ const hadPendingTerminate = proc.pendingTerminate === true;
122291
+ const preserveSessionForRuntimeReload = proc.pendingTerminatePreserveSession === true;
121177
122292
  if (!runtime.currentTask || runtime.currentTask.replyMessageId !== replyMessageId) {
121178
122293
  logger14.warn("cancelReply: replyMessageId mismatch", {
121179
122294
  agentId,
@@ -121260,7 +122375,7 @@ ${lines.join("\n")}`;
121260
122375
  traceId: t.traceId
121261
122376
  });
121262
122377
  }
121263
- if (hadPendingRuntimeReload) {
122378
+ if (hadPendingTerminate) {
121264
122379
  const pendingInbox = [...runtime.groupInbox];
121265
122380
  runtime.groupInbox = [];
121266
122381
  for (const entry of pendingInbox) {
@@ -121276,9 +122391,10 @@ ${lines.join("\n")}`;
121276
122391
  }
121277
122392
  });
121278
122393
  }
121279
- logger14.info("cancelReply: pending runtime reload will clear scoped session after stop", {
122394
+ logger14.info("cancelReply: pending deferred teardown handled after stop", {
121280
122395
  agentId,
121281
122396
  scope: scopeKey(proc.scope),
122397
+ preserveSession: preserveSessionForRuntimeReload,
121282
122398
  releasedInboxCount: pendingInbox.length,
121283
122399
  traceId
121284
122400
  });
@@ -121288,11 +122404,15 @@ ${lines.join("\n")}`;
121288
122404
  proc.status = "dead";
121289
122405
  this.agents.delete(key);
121290
122406
  this.lastUsedAt.delete(key);
121291
- if (hadPendingRuntimeReload) {
122407
+ if (hadPendingTerminate) {
121292
122408
  proc.pendingTerminate = false;
122409
+ proc.pendingTerminatePreserveSession = false;
122410
+ proc.pendingTerminateReason = void 0;
121293
122411
  this.dormantScopes.delete(key);
121294
122412
  this.dormantGroupInboxes.delete(key);
121295
- this.sessionStore.delete(agentId, proc.scope);
122413
+ if (!preserveSessionForRuntimeReload) {
122414
+ this.sessionStore.delete(agentId, proc.scope);
122415
+ }
121296
122416
  this.dispatchMemory.deleteScope(agentId, proc.scope);
121297
122417
  }
121298
122418
  logger14.info("cancelReply: process torn down", {
@@ -121300,7 +122420,7 @@ ${lines.join("\n")}`;
121300
122420
  scope: scopeKey(proc.scope),
121301
122421
  conversationId,
121302
122422
  traceId,
121303
- clearedScopedSession: hadPendingRuntimeReload
122423
+ sessionPreservedForRuntimeReload: preserveSessionForRuntimeReload
121304
122424
  });
121305
122425
  try {
121306
122426
  runtime.inputController.close();
@@ -122122,6 +123242,7 @@ var import_node_url = require("url");
122122
123242
  var logger19 = createModuleLogger("mcp.registry");
122123
123243
  var AHCHAT_BUILTIN_MCP_COMMAND = "ahchat-builtin";
122124
123244
  var SEEDANCE_BUILTIN_MCP_ID = "seedance-mcp";
123245
+ var SEEDREAM_BUILTIN_MCP_ID = "seedream-mcp";
122125
123246
  var HttpMcpRegistry = class {
122126
123247
  constructor(serverApiUrl, bridgeToken = null, localStore = null) {
122127
123248
  this.serverApiUrl = serverApiUrl;
@@ -122195,7 +123316,7 @@ var HttpMcpRegistry = class {
122195
123316
  usedNames.add(serverName);
122196
123317
  mcpServers[serverName] = sdkConfig;
122197
123318
  for (const tool2 of connection.tools) {
122198
- if (!tool2.enabled || tool2.permissionPolicy !== "always_allow") continue;
123319
+ if (!tool2.enabled || tool2.permissionPolicy === "always_deny") continue;
122199
123320
  allowedTools.push(mcpRuntimeToolName(serverName, tool2.name));
122200
123321
  }
122201
123322
  }
@@ -122245,7 +123366,7 @@ var HttpMcpRegistry = class {
122245
123366
  return null;
122246
123367
  }
122247
123368
  if (connection.command === AHCHAT_BUILTIN_MCP_COMMAND) {
122248
- return resolveBuiltinMcpServerConfig(connection);
123369
+ return this.resolveBuiltinMcpServerConfig(connection);
122249
123370
  }
122250
123371
  return {
122251
123372
  type: "stdio",
@@ -122271,37 +123392,113 @@ var HttpMcpRegistry = class {
122271
123392
  };
122272
123393
  return connection.transport === "sse" ? { type: "sse", ...common } : { type: "http", ...common };
122273
123394
  }
122274
- };
122275
- function resolveBuiltinMcpServerConfig(connection) {
122276
- const [builtinId, ...extraArgs] = connection.args;
122277
- if (builtinId !== SEEDANCE_BUILTIN_MCP_ID) {
122278
- logger19.warn("Skipping unknown built-in MCP server", {
122279
- id: connection.id,
122280
- serverName: connection.serverName,
122281
- builtinId
122282
- });
122283
- return null;
123395
+ resolveBuiltinMcpServerConfig(connection) {
123396
+ const [builtinId, ...extraArgs] = connection.args;
123397
+ if (builtinId !== SEEDANCE_BUILTIN_MCP_ID && builtinId !== SEEDREAM_BUILTIN_MCP_ID) {
123398
+ logger19.warn("Skipping unknown built-in MCP server", {
123399
+ id: connection.id,
123400
+ serverName: connection.serverName,
123401
+ builtinId
123402
+ });
123403
+ return null;
123404
+ }
123405
+ const executable = builtinId === SEEDANCE_BUILTIN_MCP_ID ? resolveSeedanceMcpExecutable(extraArgs) : resolveSeedreamMcpExecutable(extraArgs);
123406
+ if (!executable) {
123407
+ logger19.warn("Skipping built-in MCP server because CLI bundle is missing", {
123408
+ id: connection.id,
123409
+ serverName: connection.serverName,
123410
+ builtinId
123411
+ });
123412
+ return null;
123413
+ }
123414
+ return {
123415
+ type: "stdio",
123416
+ command: executable.command,
123417
+ args: executable.args,
123418
+ env: {
123419
+ ...connection.env,
123420
+ ...executable.env,
123421
+ AHCHAT_SERVER_API_URL: this.serverApiUrl,
123422
+ ...this.bridgeToken ? { AHCHAT_BRIDGE_TOKEN: this.bridgeToken } : {},
123423
+ AHCHAT_MCP_SERVER_NAME: normalizeMcpServerName(connection.serverName)
123424
+ },
123425
+ alwaysLoad: connection.alwaysLoad
123426
+ };
122284
123427
  }
122285
- const executable = resolveSeedanceMcpExecutable(extraArgs);
122286
- return {
122287
- type: "stdio",
122288
- command: executable.command,
122289
- args: executable.args,
122290
- env: connection.env,
122291
- alwaysLoad: connection.alwaysLoad
122292
- };
122293
- }
122294
- function resolveSeedanceMcpExecutable(extraArgs) {
122295
- const currentDir = import_node_path14.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
122296
- const distCliPath = import_node_path14.default.join(currentDir, "seedanceMcpCli.cjs");
122297
- if (import_node_fs7.default.existsSync(distCliPath)) {
122298
- return { command: process.execPath, args: [distCliPath, ...extraArgs] };
123428
+ };
123429
+ function resolveSeedanceMcpExecutable(extraArgs, options = {}) {
123430
+ return resolveBundledMcpExecutable("seedanceMcpCli", extraArgs, options);
123431
+ }
123432
+ function resolveSeedreamMcpExecutable(extraArgs, options = {}) {
123433
+ return resolveBundledMcpExecutable("seedreamMcpCli", extraArgs, options);
123434
+ }
123435
+ function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
123436
+ const currentDir = options.currentDir ?? import_node_path14.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
123437
+ const cwd = options.cwd ?? process.cwd();
123438
+ const execPath = options.execPath ?? process.execPath;
123439
+ const existsSync3 = options.existsSync ?? import_node_fs7.default.existsSync;
123440
+ const distCliPath = firstExistingPath(
123441
+ [
123442
+ import_node_path14.default.join(currentDir, `${cliBaseName}.cjs`)
123443
+ ],
123444
+ existsSync3
123445
+ );
123446
+ if (distCliPath) {
123447
+ return {
123448
+ command: execPath,
123449
+ args: [distCliPath, ...extraArgs],
123450
+ env: shouldRunExecPathAsNode(execPath, options) ? { ELECTRON_RUN_AS_NODE: "1" } : void 0
123451
+ };
122299
123452
  }
122300
- const sourceCliPath = import_node_path14.default.join(currentDir, "seedanceMcpCli.ts");
122301
- if (import_node_fs7.default.existsSync(sourceCliPath)) {
123453
+ const sourceCliPath = firstExistingPath(
123454
+ [
123455
+ import_node_path14.default.join(currentDir, `${cliBaseName}.ts`)
123456
+ ],
123457
+ existsSync3
123458
+ );
123459
+ if (sourceCliPath) {
122302
123460
  return { command: "tsx", args: [sourceCliPath, ...extraArgs] };
122303
123461
  }
122304
- return { command: process.execPath, args: [distCliPath, ...extraArgs] };
123462
+ const workspaceDistCliPath = firstExistingPath(
123463
+ [
123464
+ import_node_path14.default.resolve(currentDir, `../../bridge/dist/${cliBaseName}.cjs`),
123465
+ import_node_path14.default.resolve(cwd, `packages/desktop/dist/${cliBaseName}.cjs`),
123466
+ import_node_path14.default.resolve(cwd, `packages/bridge/dist/${cliBaseName}.cjs`)
123467
+ ],
123468
+ existsSync3
123469
+ );
123470
+ if (workspaceDistCliPath) {
123471
+ return {
123472
+ command: execPath,
123473
+ args: [workspaceDistCliPath, ...extraArgs],
123474
+ env: shouldRunExecPathAsNode(execPath, options) ? { ELECTRON_RUN_AS_NODE: "1" } : void 0
123475
+ };
123476
+ }
123477
+ const workspaceSourceCliPath = firstExistingPath(
123478
+ [
123479
+ import_node_path14.default.resolve(currentDir, `../../bridge/src/${cliBaseName}.ts`),
123480
+ import_node_path14.default.resolve(cwd, `packages/bridge/src/${cliBaseName}.ts`)
123481
+ ],
123482
+ existsSync3
123483
+ );
123484
+ if (workspaceSourceCliPath) {
123485
+ return { command: "tsx", args: [workspaceSourceCliPath, ...extraArgs] };
123486
+ }
123487
+ return null;
123488
+ }
123489
+ function firstExistingPath(paths, existsSync3) {
123490
+ const seen = /* @__PURE__ */ new Set();
123491
+ for (const filePath of paths) {
123492
+ if (seen.has(filePath)) continue;
123493
+ seen.add(filePath);
123494
+ if (existsSync3(filePath)) return filePath;
123495
+ }
123496
+ return null;
123497
+ }
123498
+ function shouldRunExecPathAsNode(execPath, options) {
123499
+ if (typeof options.isElectron === "boolean") return options.isElectron;
123500
+ if (process.versions.electron) return true;
123501
+ return import_node_path14.default.basename(execPath).toLowerCase().includes("electron");
122305
123502
  }
122306
123503
  function uniqueServerName(serverName, usedNames) {
122307
123504
  if (!usedNames.has(serverName)) return serverName;
@@ -122676,6 +123873,18 @@ var wrapper_default = import_websocket.default;
122676
123873
  var logger23 = createModuleLogger("ws.connector");
122677
123874
  var WATCHDOG_INTERVAL_MS = 15e3;
122678
123875
  var STALE_THRESHOLD_MS = WS_HEARTBEAT_INTERVAL_MS * 2 + 15e3;
123876
+ function localNetworkAddresses() {
123877
+ const out = /* @__PURE__ */ new Set();
123878
+ for (const entries of Object.values(import_node_os8.default.networkInterfaces())) {
123879
+ for (const entry of entries ?? []) {
123880
+ if (entry.internal) continue;
123881
+ const address = entry.address.trim();
123882
+ if (!address) continue;
123883
+ out.add(address.toLowerCase());
123884
+ }
123885
+ }
123886
+ return [...out].sort();
123887
+ }
122679
123888
  var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
122680
123889
  "agent:segment",
122681
123890
  "agent:turn_complete",
@@ -122688,7 +123897,8 @@ var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
122688
123897
  "ask_question_updated",
122689
123898
  "artifact:created",
122690
123899
  "agent:todos_update",
122691
- "feedback:analysis_result"
123900
+ "feedback:analysis_result",
123901
+ "bridge:resume_reply_session_response"
122692
123902
  ]);
122693
123903
  var OUTBOX_MAX_ENTRIES = 300;
122694
123904
  function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
@@ -122698,6 +123908,24 @@ function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
122698
123908
  url2.searchParams.set("token", token);
122699
123909
  return url2.toString();
122700
123910
  }
123911
+ function bridgeResumeUnsupportedResponse(payload) {
123912
+ return {
123913
+ type: "bridge:resume_reply_session_response",
123914
+ payload: {
123915
+ requestId: payload.requestId,
123916
+ replySessionId: payload.replySessionId,
123917
+ replyMessageId: payload.replyMessageId,
123918
+ agentId: payload.agentId,
123919
+ conversationId: payload.conversationId,
123920
+ canResume: false,
123921
+ currentStatus: "paused",
123922
+ recoverability: "retryable",
123923
+ reason: "bridge_resume_not_supported",
123924
+ traceId: payload.traceId,
123925
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
123926
+ }
123927
+ };
123928
+ }
122701
123929
  var ServerConnector = class {
122702
123930
  ws = null;
122703
123931
  reconnectAttempts = 0;
@@ -122715,6 +123943,7 @@ var ServerConnector = class {
122715
123943
  onTaskDispatch;
122716
123944
  onGroupTaskDispatch;
122717
123945
  onStopGeneration;
123946
+ onResumeReplySession;
122718
123947
  onConnected;
122719
123948
  onRegistered;
122720
123949
  onServerPush;
@@ -122729,6 +123958,7 @@ var ServerConnector = class {
122729
123958
  this.onTaskDispatch = params.onTaskDispatch;
122730
123959
  this.onGroupTaskDispatch = params.onGroupTaskDispatch;
122731
123960
  this.onStopGeneration = params.onStopGeneration;
123961
+ this.onResumeReplySession = params.onResumeReplySession;
122732
123962
  this.onConnected = params.onConnected;
122733
123963
  this.onRegistered = params.onRegistered;
122734
123964
  this.onServerPush = params.onServerPush;
@@ -122805,6 +124035,7 @@ var ServerConnector = class {
122805
124035
  bridgeId: this.config.bridgeId,
122806
124036
  agents: ids,
122807
124037
  hostname: import_node_os8.default.hostname(),
124038
+ localAddresses: localNetworkAddresses(),
122808
124039
  runtimes: Object.keys(runtimes).length > 0 ? runtimes : void 0,
122809
124040
  queryConfig: {
122810
124041
  maxActive: qc.maxActive,
@@ -122842,6 +124073,7 @@ var ServerConnector = class {
122842
124073
  agentId: payload.agentId,
122843
124074
  conversationId: payload.conversationId,
122844
124075
  requestId,
124076
+ dispatchKind: payload.dispatchKind ?? "normal",
122845
124077
  traceId: payload.traceId
122846
124078
  });
122847
124079
  void this.onTaskDispatch(payload).catch((err) => {
@@ -122882,6 +124114,31 @@ var ServerConnector = class {
122882
124114
  });
122883
124115
  return;
122884
124116
  }
124117
+ case "bridge:resume_reply_session_request": {
124118
+ logger23.info("bridge:resume_reply_session_request received", {
124119
+ requestId: msg.payload.requestId,
124120
+ replySessionId: msg.payload.replySessionId,
124121
+ agentId: msg.payload.agentId,
124122
+ conversationId: msg.payload.conversationId,
124123
+ lastTokenIndex: msg.payload.lastTokenIndex ?? null,
124124
+ traceId: msg.payload.traceId
124125
+ });
124126
+ if (!this.onResumeReplySession) {
124127
+ this.send(bridgeResumeUnsupportedResponse(msg.payload));
124128
+ return;
124129
+ }
124130
+ void Promise.resolve(this.onResumeReplySession(msg.payload)).then((response) => this.send(response)).catch((err) => {
124131
+ logger23.error("Failed to handle bridge resume request", {
124132
+ error: err,
124133
+ requestId: msg.payload.requestId,
124134
+ replySessionId: msg.payload.replySessionId,
124135
+ agentId: msg.payload.agentId,
124136
+ traceId: msg.payload.traceId
124137
+ });
124138
+ this.send(bridgeResumeUnsupportedResponse(msg.payload));
124139
+ });
124140
+ return;
124141
+ }
122885
124142
  case "session:terminated": {
122886
124143
  logger23.warn("Session terminated by server, exiting bridge process", {
122887
124144
  reason: msg.payload.reason
@@ -123864,14 +125121,14 @@ async function dumpAgentContext(agentId, deps) {
123864
125121
 
123865
125122
  // src/clipboardFiles.ts
123866
125123
  init_cjs_shims();
123867
- var import_node_child_process3 = require("child_process");
125124
+ var import_node_child_process4 = require("child_process");
123868
125125
  var import_node_crypto4 = __toESM(require("crypto"), 1);
123869
125126
  var import_promises5 = __toESM(require("fs/promises"), 1);
123870
125127
  var import_node_os10 = __toESM(require("os"), 1);
123871
125128
  var import_node_path18 = __toESM(require("path"), 1);
123872
- var import_node_util = require("util");
125129
+ var import_node_util2 = require("util");
123873
125130
  var logger25 = createModuleLogger("bridge.clipboardFiles");
123874
- var execFileAsync = (0, import_node_util.promisify)(import_node_child_process3.execFile);
125131
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process4.execFile);
123875
125132
  var MAX_CLIPBOARD_FILE_SIZE = 100 * 1024 * 1024;
123876
125133
  var WINDOWS_CLIPBOARD_TIMEOUT_MS = 3e3;
123877
125134
  function isRecord5(value) {
@@ -123966,7 +125223,7 @@ async function readWindowsClipboardPathCandidates() {
123966
125223
  "[pscustomobject]@{ files = $files; text = $text } | ConvertTo-Json -Compress;"
123967
125224
  ].join(" ");
123968
125225
  try {
123969
- const { stdout } = await execFileAsync("powershell.exe", [
125226
+ const { stdout } = await execFileAsync2("powershell.exe", [
123970
125227
  "-NoProfile",
123971
125228
  "-NonInteractive",
123972
125229
  "-STA",
@@ -124170,7 +125427,7 @@ async function readWorkdirFile(filePath, baseDir) {
124170
125427
  };
124171
125428
  }
124172
125429
  async function allocateTrashPath(trashDir, name) {
124173
- const safeName = name.replace(/[<>:"/\\|?*\x00-\x1F]/g, "_").replace(/[. ]+$/g, "") || "item";
125430
+ const safeName = name.split("").map((char) => isUnsafeFileNameChar(char) ? "_" : char).join("").replace(/[. ]+$/g, "") || "item";
124174
125431
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
124175
125432
  for (let index = 0; index < 1e3; index += 1) {
124176
125433
  const suffix = index === 0 ? "" : `-${index}`;
@@ -124184,6 +125441,10 @@ async function allocateTrashPath(trashDir, name) {
124184
125441
  }
124185
125442
  throw new Error("unable to allocate trash path");
124186
125443
  }
125444
+ function isUnsafeFileNameChar(char) {
125445
+ const code = char.charCodeAt(0);
125446
+ return code <= 31 || '<>:"/\\|?*'.includes(char);
125447
+ }
124187
125448
  async function trashWorkdirPath(opts) {
124188
125449
  const resolvedBaseDir = resolveUserPath(opts.baseDir);
124189
125450
  const resolvedTargetPath = resolveUserPath(opts.targetPath);
@@ -124987,7 +126248,8 @@ function groupInboxEntryFromDispatch(payload) {
124987
126248
  boardItems: payload.boardItems,
124988
126249
  boardSprints: payload.boardSprints,
124989
126250
  boardIssues: payload.boardIssues,
124990
- boardMeta: payload.boardMeta
126251
+ boardMeta: payload.boardMeta,
126252
+ dispatchKind: payload.dispatchKind
124991
126253
  };
124992
126254
  }
124993
126255
 
@@ -125084,7 +126346,8 @@ function createTaskDispatchHandler(agentManager, agentRegistry, emit) {
125084
126346
  replyMessageId: payload.ackId,
125085
126347
  traceId: payload.traceId,
125086
126348
  requestId,
125087
- planMode: payload.planMode ?? void 0
126349
+ planMode: payload.planMode ?? void 0,
126350
+ dispatchKind: payload.dispatchKind ?? "normal"
125088
126351
  });
125089
126352
  logger32.info("Agent run dispatched", {
125090
126353
  agentId: payload.agentId,
@@ -125124,6 +126387,7 @@ function createGroupTaskDispatchHandler(agentManager, agentRegistry, emit) {
125124
126387
  isMentioned: payload.isMentioned,
125125
126388
  senderKind: payload.sender.kind,
125126
126389
  chainDepth: payload.chainDepth,
126390
+ dispatchKind: payload.dispatchKind ?? "normal",
125127
126391
  traceId: payload.traceId
125128
126392
  });
125129
126393
  emitTaskAck(emit, payload.ackId, payload.agentId, payload.traceId);
@@ -125158,7 +126422,7 @@ function createGroupTaskDispatchHandler(agentManager, agentRegistry, emit) {
125158
126422
  }
125159
126423
  const groupScope = { kind: "group", groupId: payload.groupId };
125160
126424
  try {
125161
- const cwd = agentConfig.workingDirectory?.trim() || payload.cwd;
126425
+ const cwd = payload.cwd;
125162
126426
  await agentManager.acquire(
125163
126427
  agentConfig,
125164
126428
  groupScope,
@@ -125366,10 +126630,14 @@ var import_node_path25 = __toESM(require("path"), 1);
125366
126630
  var logger34 = createModuleLogger("session.store");
125367
126631
  var SessionStore = class {
125368
126632
  filePath;
126633
+ fingerprintPath;
125369
126634
  cache;
126635
+ fingerprints;
125370
126636
  constructor(dataDir) {
125371
126637
  this.filePath = import_node_path25.default.join(dataDir, "sessions.json");
126638
+ this.fingerprintPath = import_node_path25.default.join(dataDir, "session-fingerprints.json");
125372
126639
  this.cache = this.loadFromDisk();
126640
+ this.fingerprints = this.loadMapFromDisk(this.fingerprintPath, "session fingerprints");
125373
126641
  }
125374
126642
  cacheKey(agentId, scope) {
125375
126643
  return runtimeKey(agentId, scope);
@@ -125382,8 +126650,13 @@ var SessionStore = class {
125382
126650
  this.saveToDisk();
125383
126651
  }
125384
126652
  delete(agentId, scope) {
125385
- delete this.cache[this.cacheKey(agentId, scope)];
125386
- this.saveToDisk();
126653
+ const key = this.cacheKey(agentId, scope);
126654
+ const hadSession = Object.prototype.hasOwnProperty.call(this.cache, key);
126655
+ const hadFingerprint = Object.prototype.hasOwnProperty.call(this.fingerprints, key);
126656
+ delete this.cache[key];
126657
+ delete this.fingerprints[key];
126658
+ if (hadSession) this.saveToDisk();
126659
+ if (hadFingerprint) this.saveFingerprintsToDisk();
125387
126660
  }
125388
126661
  deleteAllForAgent(agentId) {
125389
126662
  const prefix = `${agentId}::`;
@@ -125397,10 +126670,27 @@ var SessionStore = class {
125397
126670
  if (changed) {
125398
126671
  this.saveToDisk();
125399
126672
  }
126673
+ let fingerprintsChanged = false;
126674
+ for (const key of Object.keys(this.fingerprints)) {
126675
+ if (key === agentId || key.startsWith(prefix)) {
126676
+ delete this.fingerprints[key];
126677
+ fingerprintsChanged = true;
126678
+ }
126679
+ }
126680
+ if (fingerprintsChanged) {
126681
+ this.saveFingerprintsToDisk();
126682
+ }
125400
126683
  }
125401
126684
  getAll() {
125402
126685
  return new Map(Object.entries(this.cache));
125403
126686
  }
126687
+ getPromptFingerprint(agentId, scope) {
126688
+ return this.fingerprints[this.cacheKey(agentId, scope)] ?? null;
126689
+ }
126690
+ setPromptFingerprint(agentId, scope, fingerprint) {
126691
+ this.fingerprints[this.cacheKey(agentId, scope)] = fingerprint;
126692
+ this.saveFingerprintsToDisk();
126693
+ }
125404
126694
  loadFromDisk() {
125405
126695
  try {
125406
126696
  if (!import_node_fs15.default.existsSync(this.filePath)) return {};
@@ -125426,6 +126716,22 @@ var SessionStore = class {
125426
126716
  return {};
125427
126717
  }
125428
126718
  }
126719
+ loadMapFromDisk(filePath, label) {
126720
+ try {
126721
+ if (!import_node_fs15.default.existsSync(filePath)) return {};
126722
+ const raw = import_node_fs15.default.readFileSync(filePath, "utf-8");
126723
+ const parsed = JSON.parse(raw);
126724
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
126725
+ const out = {};
126726
+ for (const [key, value] of Object.entries(parsed)) {
126727
+ if (typeof value === "string") out[key] = value;
126728
+ }
126729
+ return out;
126730
+ } catch (e) {
126731
+ logger34.warn(`Failed to load ${label} file, starting fresh`, { error: e, path: filePath });
126732
+ return {};
126733
+ }
126734
+ }
125429
126735
  saveToDisk() {
125430
126736
  try {
125431
126737
  const dir = import_node_path25.default.dirname(this.filePath);
@@ -125435,6 +126741,22 @@ var SessionStore = class {
125435
126741
  logger34.error("Failed to save sessions file", { error: e, path: this.filePath });
125436
126742
  }
125437
126743
  }
126744
+ saveFingerprintsToDisk() {
126745
+ try {
126746
+ const dir = import_node_path25.default.dirname(this.fingerprintPath);
126747
+ import_node_fs15.default.mkdirSync(dir, { recursive: true });
126748
+ import_node_fs15.default.writeFileSync(
126749
+ this.fingerprintPath,
126750
+ JSON.stringify(this.fingerprints, null, 2),
126751
+ "utf-8"
126752
+ );
126753
+ } catch (e) {
126754
+ logger34.error("Failed to save session fingerprints file", {
126755
+ error: e,
126756
+ path: this.fingerprintPath
126757
+ });
126758
+ }
126759
+ }
125438
126760
  };
125439
126761
 
125440
126762
  // src/workdirEnsure.ts
@@ -125565,7 +126887,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
125565
126887
 
125566
126888
  // src/feedbackCodexAnalyzer.ts
125567
126889
  init_cjs_shims();
125568
- var import_node_child_process4 = require("child_process");
126890
+ var import_node_child_process5 = require("child_process");
125569
126891
  var import_node_path27 = __toESM(require("path"), 1);
125570
126892
  var logger36 = createModuleLogger("feedbackCodexAnalyzer");
125571
126893
  var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
@@ -125601,7 +126923,7 @@ function resolveFeedbackCodexOptions(defaultWorkdir, env2 = process.env) {
125601
126923
  };
125602
126924
  }
125603
126925
  function resolveLocalCodexRuntime(options) {
125604
- const probe = (0, import_node_child_process4.spawnSync)(options.executable, ["--version"], {
126926
+ const probe = (0, import_node_child_process5.spawnSync)(options.executable, ["--version"], {
125605
126927
  encoding: "utf8",
125606
126928
  timeout: 3e3
125607
126929
  });
@@ -125639,6 +126961,10 @@ function localCodexRuntimeCapability(status) {
125639
126961
  message: status.message
125640
126962
  };
125641
126963
  }
126964
+ function normalizeAnalysisGuidance(guidance) {
126965
+ const trimmed = guidance?.trim();
126966
+ return trimmed ? trimmed : null;
126967
+ }
125642
126968
  function normalizeFeedbackText(text) {
125643
126969
  return text.trim().replace(/\s+/g, " ");
125644
126970
  }
@@ -125740,12 +127066,14 @@ function skippedResult(reason) {
125740
127066
  };
125741
127067
  }
125742
127068
  function buildFeedbackAnalysisPrompt(payload, options, attachments) {
127069
+ const guidance = normalizeAnalysisGuidance(payload.guidance);
125743
127070
  const feedbackJson = JSON.stringify({
125744
127071
  jobId: payload.jobId,
125745
127072
  feedbackId: payload.feedbackId,
125746
127073
  content: payload.content,
125747
127074
  type: payload.type,
125748
127075
  priority: payload.priority,
127076
+ guidance,
125749
127077
  attachments: payload.attachments,
125750
127078
  pageUrl: payload.pageUrl,
125751
127079
  userAgent: payload.userAgent,
@@ -125788,6 +127116,7 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
125788
127116
  - \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
125789
127117
  - \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
125790
127118
  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
127119
+ - \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
125791
127120
  5. \u72B6\u6001\u89C4\u5219\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF1A
125792
127121
  - status=skipped\uFF1A\u4EC5\u7528\u4E8E\u65E0\u610F\u4E49\u53CD\u9988\u3002
125793
127122
  - 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
@@ -125797,6 +127126,9 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
125797
127126
  \u53CD\u9988\uFF1A
125798
127127
  ${feedbackJson}
125799
127128
 
127129
+ \u7BA1\u7406\u5458\u8865\u5145\u8BF4\u660E\uFF1A
127130
+ ${guidance ?? "\uFF08\u65E0\uFF09"}
127131
+
125800
127132
  \u9644\u4EF6\u672C\u5730\u5316\u7ED3\u679C\uFF1A
125801
127133
  ${attachmentJson}
125802
127134
 
@@ -125886,7 +127218,7 @@ function runCodex(prompt, options) {
125886
127218
  if (options.model) {
125887
127219
  args.splice(3, 0, "--model", options.model);
125888
127220
  }
125889
- const child = (0, import_node_child_process4.spawn)(options.executable, args, {
127221
+ const child = (0, import_node_child_process5.spawn)(options.executable, args, {
125890
127222
  cwd: options.workdir,
125891
127223
  env: process.env,
125892
127224
  stdio: ["pipe", "pipe", "pipe"]
@@ -126026,14 +127358,14 @@ async function listModels(queryFn, opts = {}) {
126026
127358
 
126027
127359
  // src/officeRuntimeSetup.ts
126028
127360
  init_cjs_shims();
126029
- var import_node_child_process5 = require("child_process");
127361
+ var import_node_child_process6 = require("child_process");
126030
127362
  var import_node_crypto5 = __toESM(require("crypto"), 1);
126031
127363
  var import_node_fs17 = __toESM(require("fs"), 1);
126032
127364
  var import_promises9 = __toESM(require("fs/promises"), 1);
126033
127365
  var import_node_os13 = __toESM(require("os"), 1);
126034
127366
  var import_node_path29 = __toESM(require("path"), 1);
126035
- var import_node_util2 = require("util");
126036
- var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process5.execFile);
127367
+ var import_node_util3 = require("util");
127368
+ var execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process6.execFile);
126037
127369
  var logger38 = createModuleLogger("bridge.officeRuntimeSetup");
126038
127370
  var REPO = "iOfficeAI/OfficeCLI";
126039
127371
  var DEFAULT_VERSION = "v1.0.110";
@@ -126117,7 +127449,7 @@ async function sha256(filePath) {
126117
127449
  }
126118
127450
  async function runBestEffort(command, args) {
126119
127451
  try {
126120
- await execFileAsync2(command, args);
127452
+ await execFileAsync3(command, args);
126121
127453
  return true;
126122
127454
  } catch (error51) {
126123
127455
  logger38.error("OfficeCLI best-effort command failed", {
@@ -126640,7 +127972,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
126640
127972
  }
126641
127973
  const skillStore = new SkillStore(config2.dataDir);
126642
127974
  const currentBridgeKey = bridgeKeyForBridgeToken(config2.bridgeToken);
126643
- const localSkillStore = new LocalSkillStore(config2.dataDir, { machineBridgeKey: currentBridgeKey });
127975
+ const localSkillStore = new LocalSkillStore(config2.dataDir);
126644
127976
  skillStore.seed("log-analysis", LOG_ANALYSIS_SKILL);
126645
127977
  const runtimeSkillSync = await syncRuntimeSkillsFromServer({
126646
127978
  skillStore,
@@ -126816,6 +128148,10 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
126816
128148
  traceId: payload.traceId
126817
128149
  });
126818
128150
  },
128151
+ onResumeReplySession: (payload) => ({
128152
+ type: "bridge:resume_reply_session_response",
128153
+ payload: agentManager.resumeReplySession(payload)
128154
+ }),
126819
128155
  onConnected: async () => {
126820
128156
  await agentRegistry.refresh();
126821
128157
  await groupRegistry.refresh();
@@ -127655,7 +128991,7 @@ function handleBridgeStartError(e, message) {
127655
128991
 
127656
128992
  // src/protocol.ts
127657
128993
  init_cjs_shims();
127658
- var import_node_child_process6 = require("child_process");
128994
+ var import_node_child_process7 = require("child_process");
127659
128995
  var import_node_fs18 = __toESM(require("fs"), 1);
127660
128996
  var import_node_os16 = __toESM(require("os"), 1);
127661
128997
  var import_node_path32 = __toESM(require("path"), 1);
@@ -127767,7 +129103,7 @@ function registerWindows() {
127767
129103
  ].join("\r\n")
127768
129104
  );
127769
129105
  try {
127770
- (0, import_node_child_process6.execSync)(`powershell -ExecutionPolicy Bypass -File "${psRegisterPath}"`, { stdio: "pipe" });
129106
+ (0, import_node_child_process7.execSync)(`powershell -ExecutionPolicy Bypass -File "${psRegisterPath}"`, { stdio: "pipe" });
127771
129107
  } catch (e) {
127772
129108
  logger43.error("Failed to register Windows protocol handler", { error: e });
127773
129109
  throw new Error("Failed to register Windows protocol handler");
@@ -127798,7 +129134,7 @@ function registerMacOS() {
127798
129134
  } catch {
127799
129135
  }
127800
129136
  try {
127801
- (0, import_node_child_process6.execSync)(`osacompile -o ${JSON.stringify(appDir)} ${JSON.stringify(tmpScript)}`, { stdio: "pipe" });
129137
+ (0, import_node_child_process7.execSync)(`osacompile -o ${JSON.stringify(appDir)} ${JSON.stringify(tmpScript)}`, { stdio: "pipe" });
127802
129138
  } finally {
127803
129139
  try {
127804
129140
  import_node_fs18.default.unlinkSync(tmpScript);
@@ -127807,13 +129143,13 @@ function registerMacOS() {
127807
129143
  }
127808
129144
  const plistPath = import_node_path32.default.join(appDir, "Contents", "Info.plist");
127809
129145
  const urlTypes = JSON.stringify([{ CFBundleURLName: "ALL-CAN Bridge", CFBundleURLSchemes: ["ahchat"] }]);
127810
- (0, import_node_child_process6.execSync)(
129146
+ (0, import_node_child_process7.execSync)(
127811
129147
  `/usr/bin/plutil -insert CFBundleURLTypes -json ${JSON.stringify(urlTypes)} ${JSON.stringify(plistPath)}`,
127812
129148
  { stdio: "pipe" }
127813
129149
  );
127814
129150
  const lsregister = "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister";
127815
129151
  try {
127816
- (0, import_node_child_process6.execSync)(`${lsregister} -f ${JSON.stringify(appDir)}`, { stdio: "pipe" });
129152
+ (0, import_node_child_process7.execSync)(`${lsregister} -f ${JSON.stringify(appDir)}`, { stdio: "pipe" });
127817
129153
  } catch (e) {
127818
129154
  logger43.warn("lsregister failed; URL scheme registration may be delayed", { error: e });
127819
129155
  }
@@ -127835,7 +129171,7 @@ function registerLinux() {
127835
129171
  import_node_fs18.default.mkdirSync(import_node_path32.default.dirname(desktopPath), { recursive: true });
127836
129172
  import_node_fs18.default.writeFileSync(desktopPath, desktopFile);
127837
129173
  try {
127838
- (0, import_node_child_process6.execSync)("update-desktop-database ~/.local/share/applications/", { stdio: "pipe" });
129174
+ (0, import_node_child_process7.execSync)("update-desktop-database ~/.local/share/applications/", { stdio: "pipe" });
127839
129175
  } catch (e) {
127840
129176
  logger43.warn("update-desktop-database not available; run it manually if needed", { error: e });
127841
129177
  }
@@ -127845,7 +129181,7 @@ function unregisterProtocolHandler() {
127845
129181
  const platform = import_node_os16.default.platform();
127846
129182
  if (platform === "win32") {
127847
129183
  try {
127848
- (0, import_node_child_process6.execSync)(
129184
+ (0, import_node_child_process7.execSync)(
127849
129185
  `powershell -ExecutionPolicy Bypass -Command "Remove-Item -Path 'HKCU:\\Software\\Classes\\ahchat' -Recurse -Force -ErrorAction SilentlyContinue"`,
127850
129186
  { stdio: "pipe" }
127851
129187
  );
@@ -127885,7 +129221,7 @@ function isProtocolRegistered() {
127885
129221
  const stableCliExists = import_node_fs18.default.existsSync(getStableCliPath());
127886
129222
  if (platform === "win32") {
127887
129223
  try {
127888
- (0, import_node_child_process6.execSync)('REG QUERY "HKCU\\Software\\Classes\\ahchat" /ve', { stdio: "pipe" });
129224
+ (0, import_node_child_process7.execSync)('REG QUERY "HKCU\\Software\\Classes\\ahchat" /ve', { stdio: "pipe" });
127889
129225
  return stableCliExists;
127890
129226
  } catch {
127891
129227
  return false;