@fangyb/ahchat-bridge 0.1.32 → 0.1.34
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 +1765 -429
- package/dist/feedbackWorkerCli.cjs +421 -11
- package/dist/index.js +1754 -427
- package/dist/seedanceMcpCli.cjs +234 -40
- package/dist/seedreamMcpCli.cjs +31904 -0
- package/package.json +15 -13
package/dist/index.js
CHANGED
|
@@ -5515,6 +5515,21 @@ EXCEPTION \u2014 inner-voice envelope overrides no-reply:
|
|
|
5515
5515
|
- In group chat, default to short. Long-form only when explicitly asked.
|
|
5516
5516
|
- In 1:1 chat with the human, you may write longer answers when warranted.
|
|
5517
5517
|
|
|
5518
|
+
# Media generation replies
|
|
5519
|
+
- Official Seedream / Seedance MCP tools render visible AHChat media task cards.
|
|
5520
|
+
Let the card carry status, preview, download, copy, and regenerate actions.
|
|
5521
|
+
- Current media generation is one output per user request: one Seedream image or
|
|
5522
|
+
one Seedance video. Do not submit candidate batches, parallel tasks, or
|
|
5523
|
+
alternate versions in the same turn.
|
|
5524
|
+
- Do not print raw media URLs, request_id, task_id, polling logs, or repeated
|
|
5525
|
+
"let me check again" narration in the final reply unless the user explicitly
|
|
5526
|
+
asks for diagnostics.
|
|
5527
|
+
- For media submission or completion, write a short natural sentence only,
|
|
5528
|
+
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"
|
|
5529
|
+
- Do not use Bash, sleep loops, Monitor, curl polling, or background tasks just
|
|
5530
|
+
to wait for Seedream / Seedance. Seedream returns final images directly.
|
|
5531
|
+
Seedance is tracked by AHChat after one create_task call.
|
|
5532
|
+
|
|
5518
5533
|
# Group chat \u2014 shared task board
|
|
5519
5534
|
AHChat group conversations have a shared kanban board that is fed by structured
|
|
5520
5535
|
task tools (TodoWrite when available; otherwise TaskCreate / TaskUpdate). Treat
|
|
@@ -5688,13 +5703,14 @@ list_available_skills \u67E5\u8BE2\u5F53\u524D Agent \u53EF\u76F4\u63A5\u4F7F\u7
|
|
|
5688
5703
|
- \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
|
|
5689
5704
|
|
|
5690
5705
|
# Cross-scope session isolation
|
|
5691
|
-
\u6BCF\u4E2A scope\uFF08single / group\uFF09\u6709\u72EC\u7ACB\u7684 SDK Session / \u5DE5\u4F5C\u8BB0\u5FC6\
|
|
5692
|
-
\u4F60\u5728 # Your scopes \u4E2D\u53EF\u4EE5\u770B\u5230\u6BCF\u4E2A scope \u5F53\u524D\u4F7F\u7528\u7684 workdir \u8DEF\u5F84\
|
|
5706
|
+
\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
|
|
5707
|
+
\u4F60\u5728 # Your scopes \u4E2D\u53EF\u4EE5\u770B\u5230\u6BCF\u4E2A scope \u5F53\u524D\u4F7F\u7528\u7684 workdir \u8DEF\u5F84\u3002
|
|
5693
5708
|
|
|
5694
|
-
- \u4F60\
|
|
5695
|
-
-
|
|
5696
|
-
- \
|
|
5697
|
-
-
|
|
5709
|
+
- 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
|
|
5710
|
+
- 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
|
|
5711
|
+
- \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
|
|
5712
|
+
- \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
|
|
5713
|
+
- \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
|
|
5698
5714
|
|
|
5699
5715
|
# Cross-scope awareness (Neural Send)
|
|
5700
5716
|
|
|
@@ -5921,11 +5937,121 @@ function createMcpToolInvocationId() {
|
|
|
5921
5937
|
function isWSMessage(data) {
|
|
5922
5938
|
return typeof data === "object" && data !== null && "type" in data && "payload" in data;
|
|
5923
5939
|
}
|
|
5940
|
+
function isPlainRecord(value) {
|
|
5941
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
5942
|
+
const proto2 = Object.getPrototypeOf(value);
|
|
5943
|
+
return proto2 === Object.prototype || proto2 === null;
|
|
5944
|
+
}
|
|
5945
|
+
function invalidWsMessage(type, field) {
|
|
5946
|
+
return new Error(`Invalid WS message ${type} payload.${field}`);
|
|
5947
|
+
}
|
|
5948
|
+
function assertPayloadRecord(type, payload) {
|
|
5949
|
+
if (!isPlainRecord(payload)) {
|
|
5950
|
+
throw new Error(`Invalid WS message ${type} payload`);
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
function assertStringPayloadField(type, payload, field) {
|
|
5954
|
+
if (typeof payload[field] !== "string") {
|
|
5955
|
+
throw invalidWsMessage(type, field);
|
|
5956
|
+
}
|
|
5957
|
+
}
|
|
5958
|
+
function assertNumberPayloadField(type, payload, field) {
|
|
5959
|
+
if (typeof payload[field] !== "number" || Number.isNaN(payload[field])) {
|
|
5960
|
+
throw invalidWsMessage(type, field);
|
|
5961
|
+
}
|
|
5962
|
+
}
|
|
5963
|
+
function assertArrayPayloadField(type, payload, field) {
|
|
5964
|
+
if (!Array.isArray(payload[field])) {
|
|
5965
|
+
throw invalidWsMessage(type, field);
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
function assertRecordPayloadField(type, payload, field) {
|
|
5969
|
+
if (!isPlainRecord(payload[field])) {
|
|
5970
|
+
throw invalidWsMessage(type, field);
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
function validateRequiredStrings(type, payload, fields) {
|
|
5974
|
+
for (const field of fields) assertStringPayloadField(type, payload, field);
|
|
5975
|
+
}
|
|
5976
|
+
function validateWSMessageShape(msg) {
|
|
5977
|
+
const type = msg.type;
|
|
5978
|
+
const payload = msg.payload;
|
|
5979
|
+
switch (type) {
|
|
5980
|
+
case "heartbeat": {
|
|
5981
|
+
assertPayloadRecord(type, payload);
|
|
5982
|
+
assertNumberPayloadField(type, payload, "ts");
|
|
5983
|
+
return;
|
|
5984
|
+
}
|
|
5985
|
+
case "client:hello": {
|
|
5986
|
+
assertPayloadRecord(type, payload);
|
|
5987
|
+
validateRequiredStrings(type, payload, ["sessionId", "platform", "version", "env", "traceId"]);
|
|
5988
|
+
return;
|
|
5989
|
+
}
|
|
5990
|
+
case "user:send_message": {
|
|
5991
|
+
assertPayloadRecord(type, payload);
|
|
5992
|
+
validateRequiredStrings(type, payload, ["id", "agentId", "conversationId", "content", "traceId"]);
|
|
5993
|
+
return;
|
|
5994
|
+
}
|
|
5995
|
+
case "user:group_message": {
|
|
5996
|
+
assertPayloadRecord(type, payload);
|
|
5997
|
+
validateRequiredStrings(type, payload, ["id", "groupId", "conversationId", "content", "traceId"]);
|
|
5998
|
+
assertArrayPayloadField(type, payload, "mentions");
|
|
5999
|
+
return;
|
|
6000
|
+
}
|
|
6001
|
+
case "agent:done": {
|
|
6002
|
+
assertPayloadRecord(type, payload);
|
|
6003
|
+
validateRequiredStrings(type, payload, [
|
|
6004
|
+
"ackId",
|
|
6005
|
+
"messageId",
|
|
6006
|
+
"agentId",
|
|
6007
|
+
"conversationId",
|
|
6008
|
+
"fullContent",
|
|
6009
|
+
"traceId"
|
|
6010
|
+
]);
|
|
6011
|
+
assertArrayPayloadField(type, payload, "contentBlocks");
|
|
6012
|
+
assertRecordPayloadField(type, payload, "metadata");
|
|
6013
|
+
return;
|
|
6014
|
+
}
|
|
6015
|
+
case "agent:segment": {
|
|
6016
|
+
assertPayloadRecord(type, payload);
|
|
6017
|
+
validateRequiredStrings(type, payload, [
|
|
6018
|
+
"messageId",
|
|
6019
|
+
"ackId",
|
|
6020
|
+
"agentId",
|
|
6021
|
+
"conversationId",
|
|
6022
|
+
"groupId",
|
|
6023
|
+
"content",
|
|
6024
|
+
"traceId"
|
|
6025
|
+
]);
|
|
6026
|
+
assertArrayPayloadField(type, payload, "contentBlocks");
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
case "agent:turn_complete": {
|
|
6030
|
+
assertPayloadRecord(type, payload);
|
|
6031
|
+
validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "groupId", "traceId"]);
|
|
6032
|
+
assertNumberPayloadField(type, payload, "segmentCount");
|
|
6033
|
+
return;
|
|
6034
|
+
}
|
|
6035
|
+
case "agent:no_reply": {
|
|
6036
|
+
assertPayloadRecord(type, payload);
|
|
6037
|
+
validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "traceId"]);
|
|
6038
|
+
return;
|
|
6039
|
+
}
|
|
6040
|
+
case "agent:error": {
|
|
6041
|
+
assertPayloadRecord(type, payload);
|
|
6042
|
+
validateRequiredStrings(type, payload, ["ackId", "agentId", "conversationId", "error", "traceId"]);
|
|
6043
|
+
return;
|
|
6044
|
+
}
|
|
6045
|
+
default:
|
|
6046
|
+
return;
|
|
6047
|
+
}
|
|
6048
|
+
}
|
|
5924
6049
|
function parseWSMessage(raw) {
|
|
5925
6050
|
const parsed = JSON.parse(raw);
|
|
5926
6051
|
if (!isWSMessage(parsed)) {
|
|
5927
6052
|
throw new Error("Invalid WS message: missing type/payload");
|
|
5928
6053
|
}
|
|
6054
|
+
validateWSMessageShape(parsed);
|
|
5929
6055
|
return parsed;
|
|
5930
6056
|
}
|
|
5931
6057
|
function isAskUserQuestionToolName(toolName) {
|
|
@@ -5939,7 +6065,7 @@ var SLUG_MAX_LEN = 32;
|
|
|
5939
6065
|
function slugifyForFs(name) {
|
|
5940
6066
|
const trimmed = name.trim();
|
|
5941
6067
|
if (!trimmed) return "unnamed";
|
|
5942
|
-
const slug = trimmed.replace(/[^\w\u4e00-\u9fa5
|
|
6068
|
+
const slug = trimmed.replace(/[^\w\u4e00-\u9fa5 -]/gu, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
5943
6069
|
const base = slug.length > 0 ? slug : "unnamed";
|
|
5944
6070
|
return base.length > SLUG_MAX_LEN ? base.slice(0, SLUG_MAX_LEN) : base;
|
|
5945
6071
|
}
|
|
@@ -6443,6 +6569,105 @@ var OFFICIAL_OFFICE_SKILL_MARKDOWN = Object.fromEntries(
|
|
|
6443
6569
|
OFFICIAL_OFFICE_SKILLS.map((skill) => [skill.id, renderOfficialOfficeSkillMarkdown(skill)])
|
|
6444
6570
|
);
|
|
6445
6571
|
|
|
6572
|
+
// ../shared/src/officialMediaSkills.ts
|
|
6573
|
+
var OFFICIAL_MEDIA_SKILL_IDS = [
|
|
6574
|
+
"media-video-generation"
|
|
6575
|
+
];
|
|
6576
|
+
var OFFICIAL_MEDIA_SKILLS = [
|
|
6577
|
+
{
|
|
6578
|
+
id: "media-video-generation",
|
|
6579
|
+
name: "\u89C6\u9891\u751F\u6210",
|
|
6580
|
+
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",
|
|
6581
|
+
sourceType: "official",
|
|
6582
|
+
trustLevel: "official",
|
|
6583
|
+
status: "team_approved",
|
|
6584
|
+
taskTypes: [
|
|
6585
|
+
"\u89C6\u9891\u751F\u6210",
|
|
6586
|
+
"\u89C6\u9891",
|
|
6587
|
+
"\u751F\u89C6\u9891",
|
|
6588
|
+
"AI \u89C6\u9891",
|
|
6589
|
+
"Seedance",
|
|
6590
|
+
"\u6587\u751F\u89C6\u9891",
|
|
6591
|
+
"\u56FE\u751F\u89C6\u9891",
|
|
6592
|
+
"\u77ED\u89C6\u9891",
|
|
6593
|
+
"video_generation",
|
|
6594
|
+
"media_generation"
|
|
6595
|
+
],
|
|
6596
|
+
applicableRoles: [
|
|
6597
|
+
"video",
|
|
6598
|
+
"media",
|
|
6599
|
+
"creative",
|
|
6600
|
+
"designer",
|
|
6601
|
+
"\u5BFC\u6F14",
|
|
6602
|
+
"\u89C6\u9891",
|
|
6603
|
+
"\u751F\u89C6\u9891",
|
|
6604
|
+
"\u521B\u610F",
|
|
6605
|
+
"\u8BBE\u8BA1",
|
|
6606
|
+
"\u591A\u5A92\u4F53",
|
|
6607
|
+
"\u5185\u5BB9"
|
|
6608
|
+
],
|
|
6609
|
+
applicableScopes: ["single", "group", "smith"],
|
|
6610
|
+
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",
|
|
6611
|
+
inputs: [
|
|
6612
|
+
{ 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 },
|
|
6613
|
+
{ 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" },
|
|
6614
|
+
{ 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" }
|
|
6615
|
+
],
|
|
6616
|
+
outputs: [
|
|
6617
|
+
{ 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 },
|
|
6618
|
+
{ name: "shortReply", description: "\u4E00\u53E5\u81EA\u7136\u77ED\u56DE\u590D\uFF0C\u907F\u514D\u91CD\u590D\u89E3\u91CA\u5DE5\u5177\u7EC6\u8282\u3002" }
|
|
6619
|
+
],
|
|
6620
|
+
steps: [
|
|
6621
|
+
"\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",
|
|
6622
|
+
"\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",
|
|
6623
|
+
"\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",
|
|
6624
|
+
"\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",
|
|
6625
|
+
"\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",
|
|
6626
|
+
"\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",
|
|
6627
|
+
"\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"
|
|
6628
|
+
],
|
|
6629
|
+
successCriteria: [
|
|
6630
|
+
"\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",
|
|
6631
|
+
"\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",
|
|
6632
|
+
"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",
|
|
6633
|
+
"\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"
|
|
6634
|
+
],
|
|
6635
|
+
limitations: [
|
|
6636
|
+
"\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",
|
|
6637
|
+
"\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",
|
|
6638
|
+
"\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",
|
|
6639
|
+
"\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"
|
|
6640
|
+
],
|
|
6641
|
+
permissions: {
|
|
6642
|
+
readsProjectFiles: false,
|
|
6643
|
+
readsLogs: false,
|
|
6644
|
+
readsConversationContext: true,
|
|
6645
|
+
canRunBash: false,
|
|
6646
|
+
canWriteFiles: false,
|
|
6647
|
+
canPostToForum: false,
|
|
6648
|
+
permissionLevel: "medium"
|
|
6649
|
+
},
|
|
6650
|
+
sourceEvidence: {
|
|
6651
|
+
feedPostIds: [],
|
|
6652
|
+
feedCategories: [],
|
|
6653
|
+
groupIds: [],
|
|
6654
|
+
taskIds: [],
|
|
6655
|
+
contributingAgentIds: [],
|
|
6656
|
+
successExamples: [
|
|
6657
|
+
"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",
|
|
6658
|
+
"\u5B98\u65B9 Seedance MCP\uFF1Amcp__seedance__seedance_create_task / mcp__seedance__seedance_check_task\u3002"
|
|
6659
|
+
],
|
|
6660
|
+
failureExamples: [
|
|
6661
|
+
"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",
|
|
6662
|
+
"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"
|
|
6663
|
+
]
|
|
6664
|
+
},
|
|
6665
|
+
installScope: "team",
|
|
6666
|
+
version: "1.0.0",
|
|
6667
|
+
createdBy: "system"
|
|
6668
|
+
}
|
|
6669
|
+
];
|
|
6670
|
+
|
|
6446
6671
|
// ../shared/src/officialWazaSkills.ts
|
|
6447
6672
|
var WAZA_VERSION = "3.28.0";
|
|
6448
6673
|
var WAZA_UPSTREAM = "Upstream: tw93/Waza (MIT) https://github.com/tw93/Waza";
|
|
@@ -6762,11 +6987,13 @@ var OFFICIAL_WAZA_SKILLS = [
|
|
|
6762
6987
|
// ../shared/src/officialSkills.ts
|
|
6763
6988
|
var OFFICIAL_SKILL_IDS = [
|
|
6764
6989
|
...OFFICIAL_OFFICE_SKILL_IDS,
|
|
6765
|
-
...OFFICIAL_WAZA_SKILL_IDS
|
|
6990
|
+
...OFFICIAL_WAZA_SKILL_IDS,
|
|
6991
|
+
...OFFICIAL_MEDIA_SKILL_IDS
|
|
6766
6992
|
];
|
|
6767
6993
|
var OFFICIAL_SKILLS = [
|
|
6768
6994
|
...OFFICIAL_OFFICE_SKILLS,
|
|
6769
|
-
...OFFICIAL_WAZA_SKILLS
|
|
6995
|
+
...OFFICIAL_WAZA_SKILLS,
|
|
6996
|
+
...OFFICIAL_MEDIA_SKILLS
|
|
6770
6997
|
];
|
|
6771
6998
|
function renderOfficialSkillMarkdown(skill) {
|
|
6772
6999
|
return renderSkillManifestMarkdown(skill, { cacheSource: "shared-official" });
|
|
@@ -6900,7 +7127,42 @@ function searchTokens(value) {
|
|
|
6900
7127
|
value.split(/[\s,,、/|]+/g).map((token) => token.trim()).filter((token) => token.length >= 2)
|
|
6901
7128
|
)];
|
|
6902
7129
|
}
|
|
6903
|
-
var BROAD_TASK_TERMS = /* @__PURE__ */ new Set([
|
|
7130
|
+
var BROAD_TASK_TERMS = /* @__PURE__ */ new Set([
|
|
7131
|
+
"\u65B9\u6848",
|
|
7132
|
+
"\u5185\u5BB9",
|
|
7133
|
+
"\u6587\u6863",
|
|
7134
|
+
"\u5206\u6790",
|
|
7135
|
+
"\u4F18\u5316",
|
|
7136
|
+
"\u7528\u6237",
|
|
7137
|
+
"\u5F53\u524D",
|
|
7138
|
+
"\u8FD9\u4E2A",
|
|
7139
|
+
"\u4E00\u4E2A",
|
|
7140
|
+
"\u4E00\u4E9B",
|
|
7141
|
+
"\u9700\u8981",
|
|
7142
|
+
"\u8D1F\u8D23",
|
|
7143
|
+
"\u53EF\u4EE5",
|
|
7144
|
+
"\u5DE5\u5177",
|
|
7145
|
+
"\u80FD\u529B",
|
|
7146
|
+
"\u8BA1\u5212",
|
|
7147
|
+
"plan",
|
|
7148
|
+
"content",
|
|
7149
|
+
"document",
|
|
7150
|
+
"analysis",
|
|
7151
|
+
"agent",
|
|
7152
|
+
"skill",
|
|
7153
|
+
"tool",
|
|
7154
|
+
"task",
|
|
7155
|
+
"user",
|
|
7156
|
+
"need",
|
|
7157
|
+
"needs",
|
|
7158
|
+
"use",
|
|
7159
|
+
"using",
|
|
7160
|
+
"create",
|
|
7161
|
+
"make",
|
|
7162
|
+
"help",
|
|
7163
|
+
"with"
|
|
7164
|
+
]);
|
|
7165
|
+
var TASK_TOKEN_SCORE_CAP = 6;
|
|
6904
7166
|
function entryCorpus(entry) {
|
|
6905
7167
|
return [
|
|
6906
7168
|
entry.id,
|
|
@@ -6911,6 +7173,27 @@ function entryCorpus(entry) {
|
|
|
6911
7173
|
...entry.applicableRoles
|
|
6912
7174
|
].join(" ").toLowerCase();
|
|
6913
7175
|
}
|
|
7176
|
+
function meaningfulTokens(value) {
|
|
7177
|
+
return searchTokens(value).filter((token) => !BROAD_TASK_TERMS.has(token));
|
|
7178
|
+
}
|
|
7179
|
+
function tokensFuzzyMatch(left, right) {
|
|
7180
|
+
if (left === right) return true;
|
|
7181
|
+
if (left.length >= 2 && right.length >= 2 && (left.includes(right) || right.includes(left))) return true;
|
|
7182
|
+
return false;
|
|
7183
|
+
}
|
|
7184
|
+
function matchedTaskKeywords(corpus, taskText) {
|
|
7185
|
+
if (!taskText) return [];
|
|
7186
|
+
const taskTokens = meaningfulTokens(taskText);
|
|
7187
|
+
if (taskTokens.length === 0) return [];
|
|
7188
|
+
const corpusTokens = meaningfulTokens(corpus);
|
|
7189
|
+
const matches = [];
|
|
7190
|
+
for (const taskToken of taskTokens) {
|
|
7191
|
+
if (corpus.includes(taskToken) || corpusTokens.some((corpusToken) => tokensFuzzyMatch(taskToken, corpusToken))) {
|
|
7192
|
+
matches.push(taskToken);
|
|
7193
|
+
}
|
|
7194
|
+
}
|
|
7195
|
+
return [...new Set(matches)];
|
|
7196
|
+
}
|
|
6914
7197
|
function scoreEntry(entry, query4) {
|
|
6915
7198
|
const corpus = entryCorpus(entry);
|
|
6916
7199
|
const queryText = normalizeText(query4.query);
|
|
@@ -6933,6 +7216,7 @@ function scoreEntry(entry, query4) {
|
|
|
6933
7216
|
const normalizedTaskType = taskType.toLowerCase().replace(/_/g, " ");
|
|
6934
7217
|
if (taskText.includes(normalizedTaskType) || taskText.includes(taskType.toLowerCase())) score += 4;
|
|
6935
7218
|
}
|
|
7219
|
+
score += Math.min(TASK_TOKEN_SCORE_CAP, matchedTaskKeywords(corpus, taskText).length * 2);
|
|
6936
7220
|
if (taskText && corpus.includes(taskText)) score += 2;
|
|
6937
7221
|
}
|
|
6938
7222
|
if (!queryText && !roleText && !taskText) score = 1;
|
|
@@ -6970,6 +7254,8 @@ function recommendationReasons(entry, input) {
|
|
|
6970
7254
|
if (matchedRoles.length > 0) reasons.push(`\u5339\u914D\u89D2\u8272\uFF1A${matchedRoles.slice(0, 3).join("\u3001")}`);
|
|
6971
7255
|
const matchedTasks = matchedTaskTypes(entry, taskText);
|
|
6972
7256
|
if (matchedTasks.length > 0) reasons.push(`\u5339\u914D\u4EFB\u52A1\u7C7B\u578B\uFF1A${matchedTasks.slice(0, 3).join("\u3001")}`);
|
|
7257
|
+
const matchedKeywords = matchedTaskKeywords(entryCorpus(entry), taskText);
|
|
7258
|
+
if (matchedTasks.length === 0 && matchedKeywords.length > 0) reasons.push(`\u5339\u914D\u5173\u952E\u8BCD\uFF1A${matchedKeywords.slice(0, 3).join("\u3001")}`);
|
|
6973
7259
|
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");
|
|
6974
7260
|
if (entry.runtimeAvailability === "smith_only") reasons.push("\u5F53\u524D\u53EA\u80FD\u7531 Smith \u8BFB\u53D6\u5B8C\u6574\u65B9\u6CD5\u5B66");
|
|
6975
7261
|
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");
|
|
@@ -7200,6 +7486,7 @@ function normalizeMcpConnectionSnapshot(value) {
|
|
|
7200
7486
|
customHeaders: normalizeMcpCustomHeaderSnapshot(raw.customHeaders),
|
|
7201
7487
|
enabled: raw.enabled === true,
|
|
7202
7488
|
alwaysLoad: raw.alwaysLoad === true,
|
|
7489
|
+
dailyCallLimit: normalizeMcpDailyCallLimitSnapshot(raw.dailyCallLimit),
|
|
7203
7490
|
isBuiltin: false,
|
|
7204
7491
|
ownerUserId: null,
|
|
7205
7492
|
createdBy: null,
|
|
@@ -7209,6 +7496,11 @@ function normalizeMcpConnectionSnapshot(value) {
|
|
|
7209
7496
|
bindings: bindings.length > 0 ? bindings : [{ connectionId: raw.id, targetKind: "global", targetId: MCP_GLOBAL_TARGET_ID, enabled: true }]
|
|
7210
7497
|
};
|
|
7211
7498
|
}
|
|
7499
|
+
function normalizeMcpDailyCallLimitSnapshot(value) {
|
|
7500
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
7501
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
7502
|
+
return Math.max(0, Math.floor(value));
|
|
7503
|
+
}
|
|
7212
7504
|
function normalizeMcpToolSnapshot(value) {
|
|
7213
7505
|
if (!value || typeof value !== "object") return null;
|
|
7214
7506
|
const raw = value;
|
|
@@ -7317,6 +7609,60 @@ var readpageScrapeTool = {
|
|
|
7317
7609
|
enabled: true,
|
|
7318
7610
|
permissionPolicy: "always_allow"
|
|
7319
7611
|
};
|
|
7612
|
+
var seedreamGenerateImageTool = {
|
|
7613
|
+
name: "generate_image",
|
|
7614
|
+
displayName: "Seedream \u751F\u56FE",
|
|
7615
|
+
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",
|
|
7616
|
+
category: "media",
|
|
7617
|
+
riskLevel: "medium",
|
|
7618
|
+
enabled: true,
|
|
7619
|
+
permissionPolicy: "always_ask"
|
|
7620
|
+
};
|
|
7621
|
+
var seedreamEditImageTool = {
|
|
7622
|
+
name: "edit_image",
|
|
7623
|
+
displayName: "Seedream \u6539\u56FE",
|
|
7624
|
+
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",
|
|
7625
|
+
category: "media",
|
|
7626
|
+
riskLevel: "medium",
|
|
7627
|
+
enabled: true,
|
|
7628
|
+
permissionPolicy: "always_ask"
|
|
7629
|
+
};
|
|
7630
|
+
var seedreamGenerateImageGroupTool = {
|
|
7631
|
+
name: "generate_image_group",
|
|
7632
|
+
displayName: "Seedream \u5355\u56FE",
|
|
7633
|
+
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",
|
|
7634
|
+
category: "media",
|
|
7635
|
+
riskLevel: "medium",
|
|
7636
|
+
enabled: true,
|
|
7637
|
+
permissionPolicy: "always_ask"
|
|
7638
|
+
};
|
|
7639
|
+
var seedanceUsageGuideTool = {
|
|
7640
|
+
name: "seedance_usage_guide",
|
|
7641
|
+
displayName: "Seedance \u4F7F\u7528\u8BF4\u660E",
|
|
7642
|
+
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",
|
|
7643
|
+
category: "media",
|
|
7644
|
+
riskLevel: "low",
|
|
7645
|
+
enabled: true,
|
|
7646
|
+
permissionPolicy: "always_allow"
|
|
7647
|
+
};
|
|
7648
|
+
var seedanceCreateTaskTool = {
|
|
7649
|
+
name: "seedance_create_task",
|
|
7650
|
+
displayName: "Seedance \u751F\u89C6\u9891",
|
|
7651
|
+
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",
|
|
7652
|
+
category: "media",
|
|
7653
|
+
riskLevel: "high",
|
|
7654
|
+
enabled: true,
|
|
7655
|
+
permissionPolicy: "always_ask"
|
|
7656
|
+
};
|
|
7657
|
+
var seedanceCheckTaskTool = {
|
|
7658
|
+
name: "seedance_check_task",
|
|
7659
|
+
displayName: "Seedance \u67E5\u7ED3\u679C",
|
|
7660
|
+
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",
|
|
7661
|
+
category: "media",
|
|
7662
|
+
riskLevel: "low",
|
|
7663
|
+
enabled: true,
|
|
7664
|
+
permissionPolicy: "always_allow"
|
|
7665
|
+
};
|
|
7320
7666
|
var context7ResolveLibraryTool = {
|
|
7321
7667
|
name: "resolve-library-id",
|
|
7322
7668
|
displayName: "\u89E3\u6790\u6587\u6863\u5E93",
|
|
@@ -7623,8 +7969,56 @@ var ALIYUN_IQS_MCP_PROVIDERS = [
|
|
|
7623
7969
|
tools: [readpageBasicTool, readpageScrapeTool]
|
|
7624
7970
|
}
|
|
7625
7971
|
];
|
|
7972
|
+
var VOLCENGINE_SEEDREAM_MCP_PROVIDER = {
|
|
7973
|
+
providerId: "volcengine_seedream",
|
|
7974
|
+
name: "Volcengine Seedream",
|
|
7975
|
+
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",
|
|
7976
|
+
serverName: "seedream",
|
|
7977
|
+
transport: "stdio",
|
|
7978
|
+
url: null,
|
|
7979
|
+
command: "ahchat-builtin",
|
|
7980
|
+
args: ["seedream-mcp"],
|
|
7981
|
+
env: {
|
|
7982
|
+
ARK_API_KEY: "",
|
|
7983
|
+
ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
|
|
7984
|
+
},
|
|
7985
|
+
authType: "x_api_key",
|
|
7986
|
+
customHeaders: [],
|
|
7987
|
+
enabled: true,
|
|
7988
|
+
alwaysLoad: true,
|
|
7989
|
+
tools: [
|
|
7990
|
+
seedreamGenerateImageTool,
|
|
7991
|
+
seedreamEditImageTool,
|
|
7992
|
+
seedreamGenerateImageGroupTool
|
|
7993
|
+
]
|
|
7994
|
+
};
|
|
7995
|
+
var VOLCENGINE_SEEDANCE_MCP_PROVIDER = {
|
|
7996
|
+
providerId: "volcengine_seedance",
|
|
7997
|
+
name: "Volcengine Seedance",
|
|
7998
|
+
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",
|
|
7999
|
+
serverName: "seedance",
|
|
8000
|
+
transport: "stdio",
|
|
8001
|
+
url: null,
|
|
8002
|
+
command: "ahchat-builtin",
|
|
8003
|
+
args: ["seedance-mcp"],
|
|
8004
|
+
env: {
|
|
8005
|
+
ARK_API_KEY: "",
|
|
8006
|
+
ARK_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
|
|
8007
|
+
},
|
|
8008
|
+
authType: "x_api_key",
|
|
8009
|
+
customHeaders: [],
|
|
8010
|
+
enabled: true,
|
|
8011
|
+
alwaysLoad: true,
|
|
8012
|
+
tools: [
|
|
8013
|
+
seedanceUsageGuideTool,
|
|
8014
|
+
seedanceCreateTaskTool,
|
|
8015
|
+
seedanceCheckTaskTool
|
|
8016
|
+
]
|
|
8017
|
+
};
|
|
7626
8018
|
var OFFICIAL_MCP_PROVIDERS = [
|
|
7627
|
-
...ALIYUN_IQS_MCP_PROVIDERS
|
|
8019
|
+
...ALIYUN_IQS_MCP_PROVIDERS,
|
|
8020
|
+
VOLCENGINE_SEEDANCE_MCP_PROVIDER,
|
|
8021
|
+
VOLCENGINE_SEEDREAM_MCP_PROVIDER
|
|
7628
8022
|
];
|
|
7629
8023
|
var MCP_STORE_PROVIDERS = [
|
|
7630
8024
|
{
|
|
@@ -8724,6 +9118,77 @@ function cronCreateDurableAllow(input) {
|
|
|
8724
9118
|
priorDurable: input.durable
|
|
8725
9119
|
};
|
|
8726
9120
|
}
|
|
9121
|
+
var OFFICIAL_MEDIA_GENERATION_TOOL_NAMES = [
|
|
9122
|
+
"mcp__seedream__generate_image",
|
|
9123
|
+
"mcp__seedream__edit_image",
|
|
9124
|
+
"mcp__seedream__generate_image_group",
|
|
9125
|
+
"mcp__seedance__seedance_create_task"
|
|
9126
|
+
];
|
|
9127
|
+
var OFFICIAL_MEDIA_GENERATION_TOOLS = new Set(OFFICIAL_MEDIA_GENERATION_TOOL_NAMES);
|
|
9128
|
+
var OFFICIAL_MEDIA_GENERATION_TOOL_PATTERNS = [
|
|
9129
|
+
/^mcp__seedream(?:_\d+)?__(?:generate_image|edit_image|generate_image_group)$/,
|
|
9130
|
+
/^mcp__seedance(?:_\d+)?__seedance_create_task$/
|
|
9131
|
+
];
|
|
9132
|
+
function isOfficialMediaGenerationToolName(toolName) {
|
|
9133
|
+
return OFFICIAL_MEDIA_GENERATION_TOOLS.has(toolName) || OFFICIAL_MEDIA_GENERATION_TOOL_PATTERNS.some((pattern) => pattern.test(toolName));
|
|
9134
|
+
}
|
|
9135
|
+
function createOfficialMediaGenerationTurnGuard() {
|
|
9136
|
+
return {
|
|
9137
|
+
replyMessageId: null,
|
|
9138
|
+
toolName: null,
|
|
9139
|
+
duplicateDenied: false
|
|
9140
|
+
};
|
|
9141
|
+
}
|
|
9142
|
+
function resetOfficialMediaGenerationTurnGuard(guard, replyMessageId) {
|
|
9143
|
+
guard.replyMessageId = replyMessageId;
|
|
9144
|
+
guard.toolName = null;
|
|
9145
|
+
guard.duplicateDenied = false;
|
|
9146
|
+
}
|
|
9147
|
+
var OFFICIAL_MEDIA_DUPLICATE_DENY_REASON = "\u672C\u8F6E\u5DF2\u7ECF\u8C03\u7528\u8FC7\u5B98\u65B9\u5A92\u4F53\u751F\u6210\u5DE5\u5177";
|
|
9148
|
+
function isOfficialMediaGenerationDuplicateDenyMessage(message) {
|
|
9149
|
+
return message.includes(OFFICIAL_MEDIA_DUPLICATE_DENY_REASON);
|
|
9150
|
+
}
|
|
9151
|
+
function guardOfficialMediaGenerationTool(guard, toolName) {
|
|
9152
|
+
if (!isOfficialMediaGenerationToolName(toolName)) return null;
|
|
9153
|
+
if (!guard.toolName) {
|
|
9154
|
+
guard.toolName = toolName;
|
|
9155
|
+
return null;
|
|
9156
|
+
}
|
|
9157
|
+
guard.duplicateDenied = true;
|
|
9158
|
+
return {
|
|
9159
|
+
behavior: "deny",
|
|
9160
|
+
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`
|
|
9161
|
+
};
|
|
9162
|
+
}
|
|
9163
|
+
function createOfficialMediaGenerationPreToolUseHooks(guard, toolNames, meta3) {
|
|
9164
|
+
const mediaToolNames = /* @__PURE__ */ new Set([
|
|
9165
|
+
...OFFICIAL_MEDIA_GENERATION_TOOL_NAMES,
|
|
9166
|
+
...Array.from(toolNames).filter(isOfficialMediaGenerationToolName)
|
|
9167
|
+
]);
|
|
9168
|
+
return Array.from(mediaToolNames).map((toolName) => ({
|
|
9169
|
+
matcher: toolName,
|
|
9170
|
+
hooks: [
|
|
9171
|
+
async (_input) => {
|
|
9172
|
+
const decision = guardOfficialMediaGenerationTool(guard, toolName);
|
|
9173
|
+
if (!decision || decision.behavior !== "deny") return {};
|
|
9174
|
+
meta3.log("PreToolUse deny: duplicate official media generation tool in one turn", {
|
|
9175
|
+
agentId: meta3.agentId,
|
|
9176
|
+
scope: meta3.scope,
|
|
9177
|
+
toolName,
|
|
9178
|
+
firstToolName: guard.toolName,
|
|
9179
|
+
replyMessageId: guard.replyMessageId
|
|
9180
|
+
});
|
|
9181
|
+
return {
|
|
9182
|
+
hookSpecificOutput: {
|
|
9183
|
+
hookEventName: "PreToolUse",
|
|
9184
|
+
permissionDecision: "deny",
|
|
9185
|
+
permissionDecisionReason: decision.message
|
|
9186
|
+
}
|
|
9187
|
+
};
|
|
9188
|
+
}
|
|
9189
|
+
]
|
|
9190
|
+
}));
|
|
9191
|
+
}
|
|
8727
9192
|
function normalizedCommand(input) {
|
|
8728
9193
|
const raw = input.command;
|
|
8729
9194
|
return typeof raw === "string" ? raw.replace(/\s+/g, " ").trim() : "";
|
|
@@ -23377,8 +23842,10 @@ function date4(params) {
|
|
|
23377
23842
|
config(en_default());
|
|
23378
23843
|
|
|
23379
23844
|
// src/documentReader.ts
|
|
23380
|
-
import
|
|
23381
|
-
import
|
|
23845
|
+
import fs4 from "fs/promises";
|
|
23846
|
+
import { execFile } from "child_process";
|
|
23847
|
+
import path9 from "path";
|
|
23848
|
+
import { promisify } from "util";
|
|
23382
23849
|
|
|
23383
23850
|
// src/runtimeEnv.ts
|
|
23384
23851
|
import { execFileSync } from "child_process";
|
|
@@ -23518,8 +23985,112 @@ function resolveUserPath(input) {
|
|
|
23518
23985
|
return path7.isAbsolute(value) ? path7.normalize(value) : path7.resolve(value);
|
|
23519
23986
|
}
|
|
23520
23987
|
|
|
23988
|
+
// src/officeRuntime.ts
|
|
23989
|
+
import fs3 from "fs";
|
|
23990
|
+
import os5 from "os";
|
|
23991
|
+
import path8 from "path";
|
|
23992
|
+
var OFFICECLI_EXECUTABLE_ENV = "AHCHAT_OFFICECLI_EXECUTABLE";
|
|
23993
|
+
var OFFICECLI_BIN_DIR_ENV = "AHCHAT_OFFICECLI_BIN_DIR";
|
|
23994
|
+
var logger6 = createModuleLogger("bridge.officeRuntime");
|
|
23995
|
+
function sanitizedOfficeCliProbeError(error51) {
|
|
23996
|
+
const rawCode = error51 && typeof error51 === "object" && "code" in error51 ? error51.code : void 0;
|
|
23997
|
+
const code = typeof rawCode === "string" ? rawCode : void 0;
|
|
23998
|
+
const sanitized = new Error(`OfficeCLI executable probe failed${code ? ` (${code})` : ""}`);
|
|
23999
|
+
if (error51 instanceof Error) sanitized.name = error51.name;
|
|
24000
|
+
return sanitized;
|
|
24001
|
+
}
|
|
24002
|
+
function defaultRuntimeRoot() {
|
|
24003
|
+
if (process.platform === "win32") {
|
|
24004
|
+
return path8.join(process.env.LOCALAPPDATA || path8.join(os5.homedir(), "AppData", "Local"), "AHChat", "runtime", "officecli");
|
|
24005
|
+
}
|
|
24006
|
+
if (process.platform === "darwin") {
|
|
24007
|
+
return path8.join(os5.homedir(), "Library", "Caches", "AHChat", "runtime", "officecli");
|
|
24008
|
+
}
|
|
24009
|
+
return path8.join(process.env.XDG_CACHE_HOME || path8.join(os5.homedir(), ".cache"), "ahchat", "runtime", "officecli");
|
|
24010
|
+
}
|
|
24011
|
+
function getManagedOfficeCliBinDir(env2 = process.env) {
|
|
24012
|
+
return env2[OFFICECLI_BIN_DIR_ENV] || path8.join(defaultRuntimeRoot(), "bin");
|
|
24013
|
+
}
|
|
24014
|
+
function getOfficeCliExecutableName() {
|
|
24015
|
+
return process.platform === "win32" ? "officecli.exe" : "officecli";
|
|
24016
|
+
}
|
|
24017
|
+
function getManagedOfficeCliExecutablePath(env2 = process.env) {
|
|
24018
|
+
return path8.join(getManagedOfficeCliBinDir(env2), getOfficeCliExecutableName());
|
|
24019
|
+
}
|
|
24020
|
+
function isExecutable(filePath, options = {}) {
|
|
24021
|
+
const logFailure = options.logFailure !== false;
|
|
24022
|
+
try {
|
|
24023
|
+
if (process.platform === "win32") return fs3.existsSync(filePath);
|
|
24024
|
+
fs3.accessSync(filePath, fs3.constants.X_OK);
|
|
24025
|
+
return true;
|
|
24026
|
+
} catch (error51) {
|
|
24027
|
+
if (logFailure) {
|
|
24028
|
+
logger6.error("OfficeCLI executable probe failed", {
|
|
24029
|
+
error: sanitizedOfficeCliProbeError(error51),
|
|
24030
|
+
fileName: path8.basename(filePath)
|
|
24031
|
+
});
|
|
24032
|
+
}
|
|
24033
|
+
return false;
|
|
24034
|
+
}
|
|
24035
|
+
}
|
|
24036
|
+
function withPrependedPath(env2, entries) {
|
|
24037
|
+
const pathEntries = entries.filter((entry) => entry && fs3.existsSync(entry));
|
|
24038
|
+
if (pathEntries.length === 0) return env2;
|
|
24039
|
+
const current = env2.PATH ?? "";
|
|
24040
|
+
return {
|
|
24041
|
+
...env2,
|
|
24042
|
+
PATH: [...pathEntries, current].filter(Boolean).join(path8.delimiter)
|
|
24043
|
+
};
|
|
24044
|
+
}
|
|
24045
|
+
function statusForPath(filePath, source, env2, options = {}) {
|
|
24046
|
+
if (!isExecutable(filePath, { logFailure: options.logProbeFailure })) {
|
|
24047
|
+
return {
|
|
24048
|
+
ok: false,
|
|
24049
|
+
path: filePath,
|
|
24050
|
+
source,
|
|
24051
|
+
message: `officecli not executable at ${filePath}`
|
|
24052
|
+
};
|
|
24053
|
+
}
|
|
24054
|
+
const runtimeEnv = withPrependedPath(env2, [path8.dirname(filePath)]);
|
|
24055
|
+
const version2 = readCommandVersion(filePath, ["--version"], runtimeEnv);
|
|
24056
|
+
if (!version2) {
|
|
24057
|
+
return {
|
|
24058
|
+
ok: false,
|
|
24059
|
+
path: filePath,
|
|
24060
|
+
source,
|
|
24061
|
+
message: `officecli found at ${filePath} but --version failed`
|
|
24062
|
+
};
|
|
24063
|
+
}
|
|
24064
|
+
return { ok: true, path: filePath, source, version: version2 };
|
|
24065
|
+
}
|
|
24066
|
+
function detectOfficeCliRuntime(env2 = process.env) {
|
|
24067
|
+
const explicitPath = env2[OFFICECLI_EXECUTABLE_ENV]?.trim();
|
|
24068
|
+
if (explicitPath) return statusForPath(explicitPath, "env", env2);
|
|
24069
|
+
const managedPath = getManagedOfficeCliExecutablePath(env2);
|
|
24070
|
+
const managed = statusForPath(managedPath, "managed", env2, { logProbeFailure: false });
|
|
24071
|
+
if (managed.ok) return managed;
|
|
24072
|
+
const resolved = resolveCommand(["officecli"], withPrependedPath(env2, [path8.dirname(managedPath)]));
|
|
24073
|
+
if (!resolved) {
|
|
24074
|
+
return {
|
|
24075
|
+
ok: false,
|
|
24076
|
+
source: "managed",
|
|
24077
|
+
path: managedPath,
|
|
24078
|
+
message: `officecli not found. Run pnpm setup:office-runtime or set ${OFFICECLI_EXECUTABLE_ENV}.`
|
|
24079
|
+
};
|
|
24080
|
+
}
|
|
24081
|
+
return statusForPath(resolved.path, resolved.path === managedPath ? "managed" : "path", env2);
|
|
24082
|
+
}
|
|
24083
|
+
function withOfficeCliRuntimeEnv(status, env2 = process.env) {
|
|
24084
|
+
if (!status.ok || !status.path) return env2;
|
|
24085
|
+
return {
|
|
24086
|
+
...withPrependedPath(env2, [path8.dirname(status.path)]),
|
|
24087
|
+
[OFFICECLI_EXECUTABLE_ENV]: status.path
|
|
24088
|
+
};
|
|
24089
|
+
}
|
|
24090
|
+
|
|
23521
24091
|
// src/documentReader.ts
|
|
23522
|
-
var
|
|
24092
|
+
var logger7 = createModuleLogger("document.reader");
|
|
24093
|
+
var execFileAsync = promisify(execFile);
|
|
23523
24094
|
var SUPPORTED_DOCUMENT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
23524
24095
|
".docx",
|
|
23525
24096
|
".xls",
|
|
@@ -23556,31 +24127,31 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
23556
24127
|
var DEFAULT_MAX_CHARS = 5e5;
|
|
23557
24128
|
var DEFAULT_TIMEOUT_MS = 45e3;
|
|
23558
24129
|
function isReadableDocumentPath(filePath) {
|
|
23559
|
-
return SUPPORTED_DOCUMENT_EXTENSIONS.has(
|
|
24130
|
+
return SUPPORTED_DOCUMENT_EXTENSIONS.has(path9.extname(filePath).toLowerCase());
|
|
23560
24131
|
}
|
|
23561
24132
|
function resolveDocumentPath(inputPath, cwd) {
|
|
23562
24133
|
const trimmed = inputPath.trim();
|
|
23563
24134
|
if (!trimmed) throw new Error("path is required");
|
|
23564
|
-
const resolvedCwd =
|
|
23565
|
-
const candidate =
|
|
23566
|
-
const relative =
|
|
23567
|
-
if (relative.startsWith("..") ||
|
|
24135
|
+
const resolvedCwd = path9.resolve(resolveUserPath(cwd));
|
|
24136
|
+
const candidate = path9.isAbsolute(trimmed) ? path9.resolve(resolveUserPath(trimmed)) : path9.resolve(resolvedCwd, trimmed);
|
|
24137
|
+
const relative = path9.relative(resolvedCwd, candidate);
|
|
24138
|
+
if (relative.startsWith("..") || path9.isAbsolute(relative)) {
|
|
23568
24139
|
throw new Error("document path must be inside the current working directory");
|
|
23569
24140
|
}
|
|
23570
24141
|
return candidate;
|
|
23571
24142
|
}
|
|
23572
24143
|
async function readDocumentAsMarkdown(inputPath, opts = {}) {
|
|
23573
|
-
const resolvedPath = opts.cwd ? resolveDocumentPath(inputPath, opts.cwd) :
|
|
23574
|
-
const ext =
|
|
24144
|
+
const resolvedPath = opts.cwd ? resolveDocumentPath(inputPath, opts.cwd) : path9.resolve(resolveUserPath(inputPath));
|
|
24145
|
+
const ext = path9.extname(resolvedPath).toLowerCase();
|
|
23575
24146
|
if (!isReadableDocumentPath(resolvedPath)) {
|
|
23576
24147
|
throw new Error(`unsupported document type: ${ext || "(no extension)"}`);
|
|
23577
24148
|
}
|
|
23578
|
-
const stat3 = await
|
|
24149
|
+
const stat3 = await fs4.stat(resolvedPath);
|
|
23579
24150
|
if (!stat3.isFile()) throw new Error("path is not a file");
|
|
23580
24151
|
const warnings = [];
|
|
23581
24152
|
let markdown;
|
|
23582
24153
|
if (TEXT_EXTENSIONS.has(ext)) {
|
|
23583
|
-
markdown = await
|
|
24154
|
+
markdown = await fs4.readFile(resolvedPath, "utf-8");
|
|
23584
24155
|
} else if (ext === ".xls") {
|
|
23585
24156
|
markdown = await convertLegacyExcelDocument(resolvedPath);
|
|
23586
24157
|
} else {
|
|
@@ -23598,7 +24169,7 @@ async function readDocumentAsMarkdown(inputPath, opts = {}) {
|
|
|
23598
24169
|
if (!markdown.trim()) {
|
|
23599
24170
|
warnings.push("No readable text was extracted from this document.");
|
|
23600
24171
|
}
|
|
23601
|
-
|
|
24172
|
+
logger7.info("Document read as markdown", {
|
|
23602
24173
|
path: resolvedPath,
|
|
23603
24174
|
ext,
|
|
23604
24175
|
length: markdown.length,
|
|
@@ -23613,21 +24184,21 @@ async function readDocumentAsMarkdown(inputPath, opts = {}) {
|
|
|
23613
24184
|
};
|
|
23614
24185
|
}
|
|
23615
24186
|
function documentSidecarPath(filePath, outputDir) {
|
|
23616
|
-
const dir = outputDir ??
|
|
23617
|
-
const base =
|
|
23618
|
-
return
|
|
24187
|
+
const dir = outputDir ?? path9.dirname(filePath);
|
|
24188
|
+
const base = path9.basename(filePath);
|
|
24189
|
+
return path9.join(dir, `${base}.content.md`);
|
|
23619
24190
|
}
|
|
23620
24191
|
async function writeDocumentSidecar(filePath, opts = {}) {
|
|
23621
24192
|
const result = await readDocumentAsMarkdown(filePath, opts);
|
|
23622
|
-
const sidecarDir = opts.sidecarDir ?
|
|
24193
|
+
const sidecarDir = opts.sidecarDir ? path9.resolve(resolveUserPath(opts.sidecarDir)) : path9.dirname(result.path);
|
|
23623
24194
|
if (opts.cwd) {
|
|
23624
|
-
const resolvedCwd =
|
|
23625
|
-
const relative =
|
|
23626
|
-
if (relative.startsWith("..") ||
|
|
24195
|
+
const resolvedCwd = path9.resolve(resolveUserPath(opts.cwd));
|
|
24196
|
+
const relative = path9.relative(resolvedCwd, sidecarDir);
|
|
24197
|
+
if (relative.startsWith("..") || path9.isAbsolute(relative)) {
|
|
23627
24198
|
throw new Error("document sidecar path must be inside the current working directory");
|
|
23628
24199
|
}
|
|
23629
24200
|
}
|
|
23630
|
-
await
|
|
24201
|
+
await fs4.mkdir(sidecarDir, { recursive: true });
|
|
23631
24202
|
const sidecarPath = documentSidecarPath(result.path, sidecarDir);
|
|
23632
24203
|
const warningText = result.warnings.length > 0 ? `
|
|
23633
24204
|
|
|
@@ -23642,8 +24213,8 @@ ${result.warnings.map((w) => `- ${w}`).join("\n")}
|
|
|
23642
24213
|
result.markdown,
|
|
23643
24214
|
warningText
|
|
23644
24215
|
].join("\n");
|
|
23645
|
-
await
|
|
23646
|
-
|
|
24216
|
+
await fs4.writeFile(sidecarPath, content, "utf-8");
|
|
24217
|
+
logger7.info("Document sidecar written", {
|
|
23647
24218
|
path: result.path,
|
|
23648
24219
|
sidecarPath,
|
|
23649
24220
|
length: content.length
|
|
@@ -23666,7 +24237,7 @@ async function convertOfficeDocument(filePath, timeoutMs) {
|
|
|
23666
24237
|
abortSignal: controller.signal
|
|
23667
24238
|
},
|
|
23668
24239
|
onWarning: (issue2) => {
|
|
23669
|
-
|
|
24240
|
+
logger7.warn("Document conversion warning", {
|
|
23670
24241
|
path: filePath,
|
|
23671
24242
|
code: issue2.code,
|
|
23672
24243
|
message: issue2.message
|
|
@@ -23676,10 +24247,53 @@ async function convertOfficeDocument(filePath, timeoutMs) {
|
|
|
23676
24247
|
if (typeof result.value === "string") return result.value;
|
|
23677
24248
|
if (result.value instanceof Uint8Array) return Buffer.from(result.value).toString("utf-8");
|
|
23678
24249
|
return JSON.stringify(result.value, null, 2);
|
|
24250
|
+
} catch (e) {
|
|
24251
|
+
if (path9.extname(filePath).toLowerCase() !== ".docx") throw e;
|
|
24252
|
+
logger7.warn("Office parser failed; trying OfficeCLI text fallback", {
|
|
24253
|
+
path: filePath,
|
|
24254
|
+
error: e
|
|
24255
|
+
});
|
|
24256
|
+
try {
|
|
24257
|
+
return await convertDocxWithOfficeCli(filePath, timeoutMs);
|
|
24258
|
+
} catch (fallbackError) {
|
|
24259
|
+
logger7.warn("OfficeCLI text fallback failed", {
|
|
24260
|
+
path: filePath,
|
|
24261
|
+
error: fallbackError
|
|
24262
|
+
});
|
|
24263
|
+
throw e;
|
|
24264
|
+
}
|
|
23679
24265
|
} finally {
|
|
23680
24266
|
clearTimeout(timer);
|
|
23681
24267
|
}
|
|
23682
24268
|
}
|
|
24269
|
+
function parseOfficeCliParagraphText(value) {
|
|
24270
|
+
if (!value || typeof value !== "object") return "";
|
|
24271
|
+
const root = value;
|
|
24272
|
+
if (root.success !== true || !root.data || typeof root.data !== "object") return "";
|
|
24273
|
+
const data = root.data;
|
|
24274
|
+
if (!Array.isArray(data.results)) return "";
|
|
24275
|
+
return data.results.map((item) => {
|
|
24276
|
+
if (!item || typeof item !== "object") return "";
|
|
24277
|
+
const text = item.text;
|
|
24278
|
+
return typeof text === "string" ? text.trim() : "";
|
|
24279
|
+
}).filter((text) => text.length > 0).join("\n\n");
|
|
24280
|
+
}
|
|
24281
|
+
async function convertDocxWithOfficeCli(filePath, timeoutMs) {
|
|
24282
|
+
const executable = process.env[OFFICECLI_EXECUTABLE_ENV]?.trim() || "officecli";
|
|
24283
|
+
const { stdout } = await execFileAsync(executable, ["query", filePath, "paragraph", "--json"], {
|
|
24284
|
+
timeout: timeoutMs,
|
|
24285
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
24286
|
+
windowsHide: true
|
|
24287
|
+
});
|
|
24288
|
+
const parsed = JSON.parse(stdout);
|
|
24289
|
+
const text = parseOfficeCliParagraphText(parsed);
|
|
24290
|
+
if (!text.trim()) throw new Error("OfficeCLI returned no paragraph text");
|
|
24291
|
+
logger7.info("Document read via OfficeCLI text fallback", {
|
|
24292
|
+
path: filePath,
|
|
24293
|
+
length: text.length
|
|
24294
|
+
});
|
|
24295
|
+
return text;
|
|
24296
|
+
}
|
|
23683
24297
|
async function convertLegacyExcelDocument(filePath) {
|
|
23684
24298
|
const XLSX = await import("./xlsx-E4ZR5JHK.js");
|
|
23685
24299
|
const workbook = XLSX.readFile(filePath, { cellDates: true });
|
|
@@ -23728,7 +24342,9 @@ function normalizeDocumentText(value) {
|
|
|
23728
24342
|
}
|
|
23729
24343
|
|
|
23730
24344
|
// src/neuralMcpServer.ts
|
|
23731
|
-
var
|
|
24345
|
+
var logger8 = createModuleLogger("neural.mcpServer");
|
|
24346
|
+
var VIDEO_GENERATION_SKILL_ID = OFFICIAL_MEDIA_SKILL_IDS[0];
|
|
24347
|
+
var AUTO_LOCAL_ENHANCER_LIMIT = 2;
|
|
23732
24348
|
function formatSkillEntry(entry, index) {
|
|
23733
24349
|
return [
|
|
23734
24350
|
`${index + 1}. ${entry.displayName} (${entry.name})`,
|
|
@@ -23761,7 +24377,7 @@ function runtimeSkillIndexEntries(skillStore, agentId, smithDefaultAllSkills = f
|
|
|
23761
24377
|
return entry.runtimeAvailability === "available";
|
|
23762
24378
|
});
|
|
23763
24379
|
} catch (e) {
|
|
23764
|
-
|
|
24380
|
+
logger8.warn("Runtime skill index unavailable", { error: e });
|
|
23765
24381
|
return [];
|
|
23766
24382
|
}
|
|
23767
24383
|
}
|
|
@@ -23771,7 +24387,7 @@ function runtimeVisibleSkillIds(skillStore, runtimeEntries) {
|
|
|
23771
24387
|
try {
|
|
23772
24388
|
for (const name of skillStore.allowedNames()) ids.add(name);
|
|
23773
24389
|
} catch (e) {
|
|
23774
|
-
|
|
24390
|
+
logger8.warn("Runtime skill names unavailable", { error: e });
|
|
23775
24391
|
}
|
|
23776
24392
|
for (const entry of runtimeEntries) {
|
|
23777
24393
|
ids.add(entry.id);
|
|
@@ -23790,12 +24406,75 @@ function filterAgentAvailableSkillEntries(entries, availableIds) {
|
|
|
23790
24406
|
if (!availableIds) return entries;
|
|
23791
24407
|
return entries.filter((entry) => availableIds.has(entry.id) || availableIds.has(entry.name));
|
|
23792
24408
|
}
|
|
23793
|
-
function
|
|
23794
|
-
|
|
23795
|
-
|
|
23796
|
-
|
|
23797
|
-
|
|
23798
|
-
|
|
24409
|
+
function matchesVideoGenerationIntent(input) {
|
|
24410
|
+
const roleText = [input.name, input.role].join("\n").toLowerCase();
|
|
24411
|
+
if (/seedance|生视频|视频生成|生成视频|视频助手|ai\s*video|video\s*generation|creative\s*video/.test(roleText)) {
|
|
24412
|
+
return true;
|
|
24413
|
+
}
|
|
24414
|
+
if (roleText.includes("\u89C6\u9891") && /[生成创作制作导演剪辑]/.test(roleText)) {
|
|
24415
|
+
return true;
|
|
24416
|
+
}
|
|
24417
|
+
const promptText = [input.systemPrompt, input.initialInstruction].join("\n").toLowerCase();
|
|
24418
|
+
return /seedance|生视频|视频生成|生成视频|文生视频|图生视频|text-to-video|image-to-video|ai\s*video|video\s*generation/.test(promptText);
|
|
24419
|
+
}
|
|
24420
|
+
var AUTO_ASSIGN_SKILL_RULES = [
|
|
24421
|
+
{
|
|
24422
|
+
skillId: VIDEO_GENERATION_SKILL_ID,
|
|
24423
|
+
intent: "media_video_generation",
|
|
24424
|
+
matches: matchesVideoGenerationIntent
|
|
24425
|
+
}
|
|
24426
|
+
];
|
|
24427
|
+
function autoAssignOfficialSkillIds(input) {
|
|
24428
|
+
return AUTO_ASSIGN_SKILL_RULES.filter((rule) => rule.matches(input)).map((rule) => rule.skillId);
|
|
24429
|
+
}
|
|
24430
|
+
function runtimeCachedSkillIds(skillStore) {
|
|
24431
|
+
if (!skillStore) return /* @__PURE__ */ new Set();
|
|
24432
|
+
try {
|
|
24433
|
+
return new Set(skillStore.allowedNames());
|
|
24434
|
+
} catch (e) {
|
|
24435
|
+
logger8.warn("Runtime skill names unavailable", { error: e });
|
|
24436
|
+
return /* @__PURE__ */ new Set();
|
|
24437
|
+
}
|
|
24438
|
+
}
|
|
24439
|
+
function isCurrentMachineLocalTarget(targetBridgeKey, currentBridgeKey) {
|
|
24440
|
+
const target = targetBridgeKey?.trim();
|
|
24441
|
+
if (!target) return true;
|
|
24442
|
+
const current = currentBridgeKey?.trim();
|
|
24443
|
+
return Boolean(current && target === current);
|
|
24444
|
+
}
|
|
24445
|
+
function selectLocalSkillEnhancersForCreateAgent(input, skillStore, alreadySelectedSkillIds) {
|
|
24446
|
+
if (!skillStore) return [];
|
|
24447
|
+
const cachedSkillIds = runtimeCachedSkillIds(skillStore);
|
|
24448
|
+
if (cachedSkillIds.size === 0) return [];
|
|
24449
|
+
const localCandidates2 = runtimeSkillIndexEntries(
|
|
24450
|
+
skillStore,
|
|
24451
|
+
null,
|
|
24452
|
+
true,
|
|
24453
|
+
true
|
|
24454
|
+
).filter((entry) => {
|
|
24455
|
+
if (entry.runtimeAvailability !== "available") return false;
|
|
24456
|
+
if (entry.origin !== "local" && !isLocalSkillId(entry.id)) return false;
|
|
24457
|
+
if (alreadySelectedSkillIds.has(entry.id) || alreadySelectedSkillIds.has(entry.name)) return false;
|
|
24458
|
+
return cachedSkillIds.has(entry.id) || cachedSkillIds.has(entry.name);
|
|
24459
|
+
});
|
|
24460
|
+
if (localCandidates2.length === 0) return [];
|
|
24461
|
+
const localCandidateIds = new Set(localCandidates2.map((entry) => entry.id));
|
|
24462
|
+
const recommendations = recommendInitialSkillsForAgent({
|
|
24463
|
+
role: input.role,
|
|
24464
|
+
systemPrompt: input.systemPrompt,
|
|
24465
|
+
workingDirectory: input.workingDirectory,
|
|
24466
|
+
task: [input.name, input.role, input.initialInstruction].filter(Boolean).join("\n"),
|
|
24467
|
+
includePlanned: false,
|
|
24468
|
+
entries: localCandidates2
|
|
24469
|
+
});
|
|
24470
|
+
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);
|
|
24471
|
+
}
|
|
24472
|
+
function skillRuntimeContext(officeCliRuntime) {
|
|
24473
|
+
return officeCliRuntime ? {
|
|
24474
|
+
officeCliAvailable: officeCliRuntime.ok,
|
|
24475
|
+
officeCliPath: officeCliRuntime.path,
|
|
24476
|
+
officeCliVersion: officeCliRuntime.version,
|
|
24477
|
+
officeCliMessage: officeCliRuntime.message
|
|
23799
24478
|
} : void 0;
|
|
23800
24479
|
}
|
|
23801
24480
|
var NEURAL_DEDUP_WINDOW_MS = 3e4;
|
|
@@ -23835,6 +24514,16 @@ function formatMachineOptionLine(machine) {
|
|
|
23835
24514
|
const bridgeId = machine.bridgeId ? `\uFF0CbridgeId=${machine.bridgeId}` : "";
|
|
23836
24515
|
return `- machine_bridge_key=${machine.bridgeKey} [${machineStatusText(machine)}] ${formatBridgeMachineLabel(machine)}${bridgeId}`;
|
|
23837
24516
|
}
|
|
24517
|
+
function rejectRemoteCreateMachineBridgeKey(machineBridgeKey, deps) {
|
|
24518
|
+
if (!machineBridgeKey || machineBridgeKey === "auto") return null;
|
|
24519
|
+
const currentBridgeKey = deps.currentBridgeKey?.trim();
|
|
24520
|
+
if (!currentBridgeKey || machineBridgeKey === currentBridgeKey) return null;
|
|
24521
|
+
return [
|
|
24522
|
+
`[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`,
|
|
24523
|
+
`\u8BF7\u7701\u7565 machine_bridge_key\uFF0C\u8BA9\u5B83\u4F7F\u7528\u5F53\u524D\u673A\u5668\uFF08${currentBridgeKey}\uFF09\u3002`,
|
|
24524
|
+
`\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`
|
|
24525
|
+
].join(" ");
|
|
24526
|
+
}
|
|
23838
24527
|
async function fetchVisibleBridgeMachines(deps) {
|
|
23839
24528
|
if (!deps.serverApiUrl || !deps.bridgeToken) return [];
|
|
23840
24529
|
try {
|
|
@@ -23843,14 +24532,14 @@ async function fetchVisibleBridgeMachines(deps) {
|
|
|
23843
24532
|
headers: bridgeAuthHeaders(deps.bridgeToken)
|
|
23844
24533
|
});
|
|
23845
24534
|
if (!res.ok) {
|
|
23846
|
-
|
|
24535
|
+
logger8.warn("Bridge machine listing failed", { status: res.status });
|
|
23847
24536
|
return [];
|
|
23848
24537
|
}
|
|
23849
24538
|
const body = await res.json();
|
|
23850
24539
|
if (!Array.isArray(body)) return [];
|
|
23851
24540
|
return body.filter(isBridgeMachineSummary);
|
|
23852
24541
|
} catch (e) {
|
|
23853
|
-
|
|
24542
|
+
logger8.warn("Bridge machine listing failed", { error: e });
|
|
23854
24543
|
return [];
|
|
23855
24544
|
}
|
|
23856
24545
|
}
|
|
@@ -23895,7 +24584,7 @@ async function resolveTierSubscriptionPreference(preferredSubscriptionId, deps)
|
|
|
23895
24584
|
(subscription) => subscription.billingMode === "company_billable" && subscription.isPrimaryCompany === true
|
|
23896
24585
|
)?.id ?? preferredSubscriptionId;
|
|
23897
24586
|
} catch (e) {
|
|
23898
|
-
|
|
24587
|
+
logger8.warn("Primary company tier preference resolution failed", { error: e });
|
|
23899
24588
|
return preferredSubscriptionId;
|
|
23900
24589
|
}
|
|
23901
24590
|
}
|
|
@@ -24070,7 +24759,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24070
24759
|
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')
|
|
24071
24760
|
},
|
|
24072
24761
|
async (args) => {
|
|
24073
|
-
|
|
24762
|
+
logger8.info("neural_send tool called", {
|
|
24074
24763
|
agentId: deps.agentId,
|
|
24075
24764
|
fromScope: currentScopeKey,
|
|
24076
24765
|
rawTargetScope: args.target_scope,
|
|
@@ -24092,7 +24781,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24092
24781
|
if (singleConvId) {
|
|
24093
24782
|
conversationId = singleConvId;
|
|
24094
24783
|
} else {
|
|
24095
|
-
|
|
24784
|
+
logger8.warn("neural_send: failed to resolve single conv", { agentId: deps.agentId });
|
|
24096
24785
|
return {
|
|
24097
24786
|
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" }],
|
|
24098
24787
|
isError: true
|
|
@@ -24101,7 +24790,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24101
24790
|
} else if (args.target_scope.startsWith("group:")) {
|
|
24102
24791
|
const r = await deps.groupRegistry.resolveScope(args.target_scope);
|
|
24103
24792
|
if (!r) {
|
|
24104
|
-
|
|
24793
|
+
logger8.info("neural_send: target scope not found", { rawTargetScope: args.target_scope });
|
|
24105
24794
|
return {
|
|
24106
24795
|
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` }],
|
|
24107
24796
|
isError: true
|
|
@@ -24118,7 +24807,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24118
24807
|
cached2 = deps.groupRegistry.getById(r.groupId);
|
|
24119
24808
|
}
|
|
24120
24809
|
if (!cached2 || !cached2.members.includes(deps.agentId)) {
|
|
24121
|
-
|
|
24810
|
+
logger8.info("neural_send: not a member of target group", {
|
|
24122
24811
|
agentId: deps.agentId,
|
|
24123
24812
|
groupId: r.groupId,
|
|
24124
24813
|
groupName: r.groupName,
|
|
@@ -24133,7 +24822,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24133
24822
|
isError: true
|
|
24134
24823
|
};
|
|
24135
24824
|
}
|
|
24136
|
-
|
|
24825
|
+
logger8.info("neural_send: member check passed", {
|
|
24137
24826
|
agentId: deps.agentId,
|
|
24138
24827
|
groupId: r.groupId,
|
|
24139
24828
|
groupName: r.groupName
|
|
@@ -24145,7 +24834,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24145
24834
|
};
|
|
24146
24835
|
}
|
|
24147
24836
|
if (resolvedKey === currentScopeKey) {
|
|
24148
|
-
|
|
24837
|
+
logger8.warn("neural_send: self-send refused", { agentId: deps.agentId, scope: currentScopeKey });
|
|
24149
24838
|
return {
|
|
24150
24839
|
content: [{ type: "text", text: "[neural_send] \u4E0D\u80FD\u628A\u6D88\u606F\u9001\u7ED9\u81EA\u5DF1\u5F53\u524D\u6240\u5728\u7684 scope\u3002" }],
|
|
24151
24840
|
isError: true
|
|
@@ -24163,7 +24852,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24163
24852
|
if (sendHistory.length >= NEURAL_DEDUP_MAX_REPEATS) {
|
|
24164
24853
|
sendHistory.push(nowTs);
|
|
24165
24854
|
recentNeuralSends.set(dedupKey, sendHistory);
|
|
24166
|
-
|
|
24855
|
+
logger8.warn("neural_send: identical message throttled (repetition guard)", {
|
|
24167
24856
|
agentId: deps.agentId,
|
|
24168
24857
|
fromScope: currentScopeKey,
|
|
24169
24858
|
toScope: resolvedKey,
|
|
@@ -24192,7 +24881,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24192
24881
|
});
|
|
24193
24882
|
sendHistory.push(nowTs);
|
|
24194
24883
|
recentNeuralSends.set(dedupKey, sendHistory);
|
|
24195
|
-
|
|
24884
|
+
logger8.info("neural_send delivered", {
|
|
24196
24885
|
agentId: deps.agentId,
|
|
24197
24886
|
fromScope: currentScopeKey,
|
|
24198
24887
|
toScope: resolvedKey,
|
|
@@ -24203,7 +24892,7 @@ async function createNeuralMcpServer(deps) {
|
|
|
24203
24892
|
content: [{ type: "text", text: `[neural_send] \u5DF2\u9001\u8FBE\u5230\u300C${toLabel}\u300D(scope: ${resolvedKey})\u3002` }]
|
|
24204
24893
|
};
|
|
24205
24894
|
} catch (err) {
|
|
24206
|
-
|
|
24895
|
+
logger8.error("neural_send dispatch failed", { agentId: deps.agentId, error: err });
|
|
24207
24896
|
return {
|
|
24208
24897
|
content: [{ type: "text", text: `[neural_send] \u9001\u8FBE\u5931\u8D25\uFF1A${err.message}` }],
|
|
24209
24898
|
isError: true
|
|
@@ -24229,7 +24918,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24229
24918
|
async (args) => {
|
|
24230
24919
|
const action = args.action;
|
|
24231
24920
|
const content = args.content;
|
|
24232
|
-
|
|
24921
|
+
logger8.info("self_note tool called", {
|
|
24233
24922
|
agentId: deps.agentId,
|
|
24234
24923
|
scope: currentScopeKey,
|
|
24235
24924
|
action,
|
|
@@ -24238,7 +24927,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24238
24927
|
if (action === "read") {
|
|
24239
24928
|
const current = deps.memoryStore.read(deps.agentId);
|
|
24240
24929
|
if (current.length === 0) {
|
|
24241
|
-
|
|
24930
|
+
logger8.info("self_note read empty", {
|
|
24242
24931
|
agentId: deps.agentId,
|
|
24243
24932
|
scope: currentScopeKey
|
|
24244
24933
|
});
|
|
@@ -24246,7 +24935,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24246
24935
|
content: [{ type: "text", text: "[self_note] \u4F60\u7684\u7B14\u8BB0\u672C\u76EE\u524D\u662F\u7A7A\u7684\u3002" }]
|
|
24247
24936
|
};
|
|
24248
24937
|
}
|
|
24249
|
-
|
|
24938
|
+
logger8.info("self_note read ok", {
|
|
24250
24939
|
agentId: deps.agentId,
|
|
24251
24940
|
scope: currentScopeKey,
|
|
24252
24941
|
notebookBytes: current.length
|
|
@@ -24257,7 +24946,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24257
24946
|
}
|
|
24258
24947
|
if (action === "append" || action === "write") {
|
|
24259
24948
|
if (typeof content !== "string" || content.length === 0) {
|
|
24260
|
-
|
|
24949
|
+
logger8.warn("self_note missing content", {
|
|
24261
24950
|
agentId: deps.agentId,
|
|
24262
24951
|
scope: currentScopeKey,
|
|
24263
24952
|
action
|
|
@@ -24274,7 +24963,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24274
24963
|
deps.memoryStore.write(deps.agentId, content);
|
|
24275
24964
|
}
|
|
24276
24965
|
const after = deps.memoryStore.read(deps.agentId);
|
|
24277
|
-
|
|
24966
|
+
logger8.info("self_note persisted", {
|
|
24278
24967
|
agentId: deps.agentId,
|
|
24279
24968
|
scope: currentScopeKey,
|
|
24280
24969
|
action,
|
|
@@ -24285,14 +24974,14 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24285
24974
|
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` }]
|
|
24286
24975
|
};
|
|
24287
24976
|
} catch (err) {
|
|
24288
|
-
|
|
24977
|
+
logger8.error("self_note write failed", { agentId: deps.agentId, action, error: err });
|
|
24289
24978
|
return {
|
|
24290
24979
|
content: [{ type: "text", text: `[self_note] \u5199\u5165\u5931\u8D25\uFF1A${err.message}` }],
|
|
24291
24980
|
isError: true
|
|
24292
24981
|
};
|
|
24293
24982
|
}
|
|
24294
24983
|
}
|
|
24295
|
-
|
|
24984
|
+
logger8.warn("self_note invalid action", {
|
|
24296
24985
|
agentId: deps.agentId,
|
|
24297
24986
|
scope: currentScopeKey,
|
|
24298
24987
|
action: String(action)
|
|
@@ -24311,7 +25000,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24311
25000
|
\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`,
|
|
24312
25001
|
{},
|
|
24313
25002
|
async () => {
|
|
24314
|
-
|
|
25003
|
+
logger8.info("neural_list_scopes tool called", {
|
|
24315
25004
|
agentId: deps.agentId,
|
|
24316
25005
|
scope: currentScopeKey
|
|
24317
25006
|
});
|
|
@@ -24319,7 +25008,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24319
25008
|
let myGroups;
|
|
24320
25009
|
if (cachedScopes && now - cachedScopes.at < SCOPES_CACHE_MS) {
|
|
24321
25010
|
myGroups = cachedScopes.groups;
|
|
24322
|
-
|
|
25011
|
+
logger8.info("neural_list_scopes: cache hit", {
|
|
24323
25012
|
agentId: deps.agentId,
|
|
24324
25013
|
cachedAt: cachedScopes.at,
|
|
24325
25014
|
ageMs: now - cachedScopes.at
|
|
@@ -24331,7 +25020,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24331
25020
|
name: g.name
|
|
24332
25021
|
}));
|
|
24333
25022
|
cachedScopes = { groups: myGroups, at: now };
|
|
24334
|
-
|
|
25023
|
+
logger8.info("neural_list_scopes: registry refreshed", {
|
|
24335
25024
|
agentId: deps.agentId,
|
|
24336
25025
|
scope: currentScopeKey,
|
|
24337
25026
|
myGroupCount: myGroups.length
|
|
@@ -24353,7 +25042,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24353
25042
|
'\u8C03 neural_send(target_scope="...") \u65F6\u8BF7\u7528\u4E0A\u9762\u5217\u51FA\u7684 scope \u5B57\u7B26\u4E32\u3002',
|
|
24354
25043
|
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"
|
|
24355
25044
|
].join("\n");
|
|
24356
|
-
|
|
25045
|
+
logger8.info("neural_list_scopes returned", {
|
|
24357
25046
|
agentId: deps.agentId,
|
|
24358
25047
|
scope: currentScopeKey,
|
|
24359
25048
|
groupCount: myGroups.length
|
|
@@ -24384,7 +25073,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24384
25073
|
async (args) => {
|
|
24385
25074
|
const requestedScope = args.scope?.trim() || "current";
|
|
24386
25075
|
const limit = Math.min(50, Math.max(1, Math.floor(args.limit ?? 20)));
|
|
24387
|
-
|
|
25076
|
+
logger8.info("read_chat_history tool called", {
|
|
24388
25077
|
agentId: deps.agentId,
|
|
24389
25078
|
scope: currentScopeKey,
|
|
24390
25079
|
requestedScope,
|
|
@@ -24414,7 +25103,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24414
25103
|
cached2 = deps.groupRegistry.getById(r.groupId);
|
|
24415
25104
|
}
|
|
24416
25105
|
if (!cached2 || !cached2.members.includes(deps.agentId)) {
|
|
24417
|
-
|
|
25106
|
+
logger8.info("read_chat_history: membership denied", {
|
|
24418
25107
|
agentId: deps.agentId,
|
|
24419
25108
|
groupId: r.groupId,
|
|
24420
25109
|
requestedScope
|
|
@@ -24448,7 +25137,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24448
25137
|
scopeLabel = `\u7FA4\u300C${r?.groupName ?? targetScope.groupId}\u300D`;
|
|
24449
25138
|
}
|
|
24450
25139
|
if (!conversationId) {
|
|
24451
|
-
|
|
25140
|
+
logger8.info("read_chat_history: no conversation for scope", {
|
|
24452
25141
|
agentId: deps.agentId,
|
|
24453
25142
|
requestedScope,
|
|
24454
25143
|
scopeLabel
|
|
@@ -24462,7 +25151,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24462
25151
|
};
|
|
24463
25152
|
}
|
|
24464
25153
|
resolvedScopeLabel = scopeLabel;
|
|
24465
|
-
|
|
25154
|
+
logger8.info("read_chat_history: resolved target", {
|
|
24466
25155
|
agentId: deps.agentId,
|
|
24467
25156
|
requestedScope,
|
|
24468
25157
|
conversationId,
|
|
@@ -24479,7 +25168,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24479
25168
|
const url2 = `${base}/api/conversations/${encodeURIComponent(conversationId)}/messages?${params.toString()}`;
|
|
24480
25169
|
const resp = await fetch(url2);
|
|
24481
25170
|
if (!resp.ok) {
|
|
24482
|
-
|
|
25171
|
+
logger8.warn("read_chat_history: HTTP error", {
|
|
24483
25172
|
agentId: deps.agentId,
|
|
24484
25173
|
status: resp.status,
|
|
24485
25174
|
conversationId
|
|
@@ -24496,7 +25185,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24496
25185
|
const messages = body.messages ?? [];
|
|
24497
25186
|
const hasMore = body.hasMore === true;
|
|
24498
25187
|
if (messages.length === 0) {
|
|
24499
|
-
|
|
25188
|
+
logger8.info("read_chat_history: empty result", {
|
|
24500
25189
|
agentId: deps.agentId,
|
|
24501
25190
|
conversationId,
|
|
24502
25191
|
requestedScope
|
|
@@ -24526,7 +25215,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24526
25215
|
`\u7EE7\u7EED\u7FFB\uFF1Aread_chat_history(before="${firstTs}", scope="${requestedScope}")`
|
|
24527
25216
|
);
|
|
24528
25217
|
}
|
|
24529
|
-
|
|
25218
|
+
logger8.info("read_chat_history returned", {
|
|
24530
25219
|
agentId: deps.agentId,
|
|
24531
25220
|
conversationId,
|
|
24532
25221
|
scopeLabel: resolvedScopeLabel,
|
|
@@ -24537,7 +25226,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
24537
25226
|
});
|
|
24538
25227
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
24539
25228
|
} catch (e) {
|
|
24540
|
-
|
|
25229
|
+
logger8.error("read_chat_history failed", { error: e, agentId: deps.agentId });
|
|
24541
25230
|
return {
|
|
24542
25231
|
content: [{
|
|
24543
25232
|
type: "text",
|
|
@@ -24564,7 +25253,7 @@ Pass either a relative path from the current working directory or an absolute pa
|
|
|
24564
25253
|
async (args) => {
|
|
24565
25254
|
const requestedPath = args.path.trim();
|
|
24566
25255
|
const maxChars = args.max_chars ?? 12e4;
|
|
24567
|
-
|
|
25256
|
+
logger8.info("read_document tool called", {
|
|
24568
25257
|
agentId: deps.agentId,
|
|
24569
25258
|
scope: currentScopeKey,
|
|
24570
25259
|
path: requestedPath,
|
|
@@ -24586,7 +25275,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24586
25275
|
warningText,
|
|
24587
25276
|
result.markdown
|
|
24588
25277
|
].filter((line) => line.length > 0).join("\n");
|
|
24589
|
-
|
|
25278
|
+
logger8.info("read_document returned", {
|
|
24590
25279
|
agentId: deps.agentId,
|
|
24591
25280
|
scope: currentScopeKey,
|
|
24592
25281
|
path: result.path,
|
|
@@ -24597,7 +25286,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24597
25286
|
return { content: [{ type: "text", text }] };
|
|
24598
25287
|
} catch (e) {
|
|
24599
25288
|
const message = e instanceof Error ? e.message : String(e);
|
|
24600
|
-
|
|
25289
|
+
logger8.error("read_document failed", {
|
|
24601
25290
|
agentId: deps.agentId,
|
|
24602
25291
|
scope: currentScopeKey,
|
|
24603
25292
|
path: requestedPath,
|
|
@@ -24635,7 +25324,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24635
25324
|
if (!resolved.ok) {
|
|
24636
25325
|
return { content: [{ type: "text", text: resolved.text }], isError: true };
|
|
24637
25326
|
}
|
|
24638
|
-
|
|
25327
|
+
logger8.info("create_group_issue tool called", {
|
|
24639
25328
|
agentId: deps.agentId,
|
|
24640
25329
|
scope: currentScopeKey,
|
|
24641
25330
|
groupId: resolved.groupId,
|
|
@@ -24650,7 +25339,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24650
25339
|
(issue2) => issue2.status === "open" && issue2.title.trim() === title
|
|
24651
25340
|
);
|
|
24652
25341
|
if (duplicate) {
|
|
24653
|
-
|
|
25342
|
+
logger8.info("create_group_issue: duplicate open issue reused", {
|
|
24654
25343
|
agentId: deps.agentId,
|
|
24655
25344
|
groupId: resolved.groupId,
|
|
24656
25345
|
issueId: duplicate.id,
|
|
@@ -24679,7 +25368,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24679
25368
|
});
|
|
24680
25369
|
if (!res.ok) {
|
|
24681
25370
|
const errText = await res.text().catch(() => "");
|
|
24682
|
-
|
|
25371
|
+
logger8.warn("create_group_issue: server rejected", {
|
|
24683
25372
|
agentId: deps.agentId,
|
|
24684
25373
|
groupId: resolved.groupId,
|
|
24685
25374
|
status: res.status,
|
|
@@ -24691,7 +25380,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24691
25380
|
};
|
|
24692
25381
|
}
|
|
24693
25382
|
const payload = await res.json();
|
|
24694
|
-
|
|
25383
|
+
logger8.info("create_group_issue: created", {
|
|
24695
25384
|
agentId: deps.agentId,
|
|
24696
25385
|
groupId: resolved.groupId,
|
|
24697
25386
|
issueId: payload.issue?.id,
|
|
@@ -24704,7 +25393,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24704
25393
|
}]
|
|
24705
25394
|
};
|
|
24706
25395
|
} catch (e) {
|
|
24707
|
-
|
|
25396
|
+
logger8.error("create_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
|
|
24708
25397
|
return {
|
|
24709
25398
|
content: [{ type: "text", text: `[create_group_issue] \u521B\u5EFA\u5931\u8D25\uFF1A${e.message}` }],
|
|
24710
25399
|
isError: true
|
|
@@ -24733,7 +25422,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24733
25422
|
if (!resolved.ok) {
|
|
24734
25423
|
return { content: [{ type: "text", text: resolved.text }], isError: true };
|
|
24735
25424
|
}
|
|
24736
|
-
|
|
25425
|
+
logger8.info("resolve_group_issue tool called", {
|
|
24737
25426
|
agentId: deps.agentId,
|
|
24738
25427
|
scope: currentScopeKey,
|
|
24739
25428
|
groupId: resolved.groupId,
|
|
@@ -24778,7 +25467,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24778
25467
|
);
|
|
24779
25468
|
if (!res.ok) {
|
|
24780
25469
|
const errText = await res.text().catch(() => "");
|
|
24781
|
-
|
|
25470
|
+
logger8.warn("resolve_group_issue: server rejected", {
|
|
24782
25471
|
agentId: deps.agentId,
|
|
24783
25472
|
groupId: resolved.groupId,
|
|
24784
25473
|
issueId,
|
|
@@ -24791,7 +25480,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24791
25480
|
};
|
|
24792
25481
|
}
|
|
24793
25482
|
const payload = await res.json();
|
|
24794
|
-
|
|
25483
|
+
logger8.info("resolve_group_issue: resolved", {
|
|
24795
25484
|
agentId: deps.agentId,
|
|
24796
25485
|
groupId: resolved.groupId,
|
|
24797
25486
|
issueId: payload.issue?.id ?? issueId
|
|
@@ -24803,7 +25492,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24803
25492
|
}]
|
|
24804
25493
|
};
|
|
24805
25494
|
} catch (e) {
|
|
24806
|
-
|
|
25495
|
+
logger8.error("resolve_group_issue failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, issueId });
|
|
24807
25496
|
return {
|
|
24808
25497
|
content: [{ type: "text", text: `[resolve_group_issue] \u5173\u95ED\u5931\u8D25\uFF1A${e.message}` }],
|
|
24809
25498
|
isError: true
|
|
@@ -24826,7 +25515,7 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
|
|
|
24826
25515
|
if (!resolved.ok) {
|
|
24827
25516
|
return { content: [{ type: "text", text: resolved.text }], isError: true };
|
|
24828
25517
|
}
|
|
24829
|
-
|
|
25518
|
+
logger8.info("list_group_tasks tool called", {
|
|
24830
25519
|
agentId: deps.agentId,
|
|
24831
25520
|
scope: currentScopeKey,
|
|
24832
25521
|
groupId: resolved.groupId,
|
|
@@ -24850,7 +25539,7 @@ ${body}`
|
|
|
24850
25539
|
}]
|
|
24851
25540
|
};
|
|
24852
25541
|
} catch (e) {
|
|
24853
|
-
|
|
25542
|
+
logger8.error("list_group_tasks failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId });
|
|
24854
25543
|
return {
|
|
24855
25544
|
content: [{ type: "text", text: `[list_group_tasks] \u67E5\u8BE2\u5931\u8D25\uFF1A${e.message}` }],
|
|
24856
25545
|
isError: true
|
|
@@ -24879,7 +25568,7 @@ ${body}`
|
|
|
24879
25568
|
if (!resolved.ok) {
|
|
24880
25569
|
return { content: [{ type: "text", text: resolved.text }], isError: true };
|
|
24881
25570
|
}
|
|
24882
|
-
|
|
25571
|
+
logger8.info("update_group_task tool called", {
|
|
24883
25572
|
agentId: deps.agentId,
|
|
24884
25573
|
scope: currentScopeKey,
|
|
24885
25574
|
groupId: resolved.groupId,
|
|
@@ -24922,7 +25611,7 @@ ${body}`
|
|
|
24922
25611
|
);
|
|
24923
25612
|
if (!res.ok) {
|
|
24924
25613
|
const errText = await res.text().catch(() => "");
|
|
24925
|
-
|
|
25614
|
+
logger8.warn("update_group_task: server rejected", {
|
|
24926
25615
|
agentId: deps.agentId,
|
|
24927
25616
|
groupId: resolved.groupId,
|
|
24928
25617
|
itemId,
|
|
@@ -24936,7 +25625,7 @@ ${body}`
|
|
|
24936
25625
|
};
|
|
24937
25626
|
}
|
|
24938
25627
|
const payload = await res.json();
|
|
24939
|
-
|
|
25628
|
+
logger8.info("update_group_task: updated", {
|
|
24940
25629
|
agentId: deps.agentId,
|
|
24941
25630
|
groupId: resolved.groupId,
|
|
24942
25631
|
itemId: payload.item?.id ?? itemId,
|
|
@@ -24949,7 +25638,7 @@ ${body}`
|
|
|
24949
25638
|
}]
|
|
24950
25639
|
};
|
|
24951
25640
|
} catch (e) {
|
|
24952
|
-
|
|
25641
|
+
logger8.error("update_group_task failed", { error: e, agentId: deps.agentId, groupId: resolved.groupId, itemId, status });
|
|
24953
25642
|
return {
|
|
24954
25643
|
content: [{ type: "text", text: `[update_group_task] \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}` }],
|
|
24955
25644
|
isError: true
|
|
@@ -24964,18 +25653,18 @@ ${body}`
|
|
|
24964
25653
|
\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
|
|
24965
25654
|
\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
|
|
24966
25655
|
\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
|
|
24967
|
-
Smith \u521B\u5EFA\
|
|
25656
|
+
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
|
|
24968
25657
|
\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`,
|
|
24969
25658
|
{
|
|
24970
25659
|
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"),
|
|
24971
25660
|
limit: external_exports.number().int().min(1).max(200).optional().describe("\u6700\u591A\u8FD4\u56DE\u591A\u5C11\u6761\uFF0C\u9ED8\u8BA4\u4E0D\u9650\u3002")
|
|
24972
25661
|
},
|
|
24973
25662
|
async (args) => {
|
|
24974
|
-
|
|
25663
|
+
logger8.info("list_contacts tool called", { agentId: deps.agentId, scope: currentScopeKey });
|
|
24975
25664
|
try {
|
|
24976
25665
|
await deps.agentRegistry.refresh();
|
|
24977
25666
|
} catch (e) {
|
|
24978
|
-
|
|
25667
|
+
logger8.warn("list_contacts: registry refresh failed, using cache", {
|
|
24979
25668
|
agentId: deps.agentId,
|
|
24980
25669
|
error: e
|
|
24981
25670
|
});
|
|
@@ -25022,16 +25711,16 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25022
25711
|
const onlineMachines = machines.filter((machine) => machine.status === "online");
|
|
25023
25712
|
const offlineMachines = machines.filter((machine) => machine.status !== "online");
|
|
25024
25713
|
const machineSection = machines.length > 0 ? [
|
|
25025
|
-
"\
|
|
25714
|
+
"\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",
|
|
25026
25715
|
...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"],
|
|
25027
25716
|
...offlineMachines.length > 0 ? [
|
|
25028
25717
|
"",
|
|
25029
25718
|
"\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",
|
|
25030
25719
|
...offlineMachines.map(formatMachineOptionLine)
|
|
25031
25720
|
] : []
|
|
25032
|
-
].join("\n") : "\u53EF\u7528\u673A\u5668\uFF1A\u5F53\u524D Bridge\
|
|
25721
|
+
].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";
|
|
25033
25722
|
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");
|
|
25034
|
-
|
|
25723
|
+
logger8.info("list_contacts returned", {
|
|
25035
25724
|
agentId: deps.agentId,
|
|
25036
25725
|
count: all.length,
|
|
25037
25726
|
humanCount,
|
|
@@ -25094,7 +25783,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25094
25783
|
}
|
|
25095
25784
|
const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim().replaceAll(USR_SELF_ID, resolveMyHuman(deps.agentRegistry, deps.agentId)) : "";
|
|
25096
25785
|
const hasInitial = initialMessage.length > 0;
|
|
25097
|
-
|
|
25786
|
+
logger8.info("create_group tool called", {
|
|
25098
25787
|
agentId: deps.agentId,
|
|
25099
25788
|
name: trimmedName,
|
|
25100
25789
|
memberCount: dedup.length,
|
|
@@ -25125,7 +25814,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25125
25814
|
});
|
|
25126
25815
|
if (!res.ok) {
|
|
25127
25816
|
const errText = await res.text().catch(() => "");
|
|
25128
|
-
|
|
25817
|
+
logger8.warn("create_group: server rejected", { status: res.status, errText });
|
|
25129
25818
|
return {
|
|
25130
25819
|
content: [{ type: "text", text: `[create_group] \u670D\u52A1\u7AEF\u62D2\u7EDD\uFF08${res.status}\uFF09\uFF1A${errText || "(no body)"}` }],
|
|
25131
25820
|
isError: true
|
|
@@ -25133,7 +25822,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25133
25822
|
}
|
|
25134
25823
|
const group = await res.json();
|
|
25135
25824
|
const groupScopeKey = `group:${group.id}`;
|
|
25136
|
-
|
|
25825
|
+
logger8.info("create_group: created", {
|
|
25137
25826
|
agentId: deps.agentId,
|
|
25138
25827
|
groupId: group.id,
|
|
25139
25828
|
name: group.name,
|
|
@@ -25161,7 +25850,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25161
25850
|
}]
|
|
25162
25851
|
};
|
|
25163
25852
|
} catch (e) {
|
|
25164
|
-
|
|
25853
|
+
logger8.error("create_group failed", { error: e, name: trimmedName });
|
|
25165
25854
|
return {
|
|
25166
25855
|
content: [{ type: "text", text: `[create_group] \u5EFA\u7FA4\u5931\u8D25\uFF1A${e.message}` }],
|
|
25167
25856
|
isError: true
|
|
@@ -25218,7 +25907,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25218
25907
|
const scopeInput = rawGroup.startsWith("group:") ? rawGroup : `group:${rawGroup}`;
|
|
25219
25908
|
const resolved = await deps.groupRegistry.resolveScope(scopeInput);
|
|
25220
25909
|
if (!resolved) {
|
|
25221
|
-
|
|
25910
|
+
logger8.info("add_to_group: group not found", { rawGroup, scopeInput });
|
|
25222
25911
|
return {
|
|
25223
25912
|
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` }],
|
|
25224
25913
|
isError: true
|
|
@@ -25230,7 +25919,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25230
25919
|
cached2 = deps.groupRegistry.getById(resolved.groupId);
|
|
25231
25920
|
}
|
|
25232
25921
|
if (!cached2 || !cached2.members.includes(deps.agentId)) {
|
|
25233
|
-
|
|
25922
|
+
logger8.info("add_to_group: not a member of target group", {
|
|
25234
25923
|
agentId: deps.agentId,
|
|
25235
25924
|
groupId: resolved.groupId,
|
|
25236
25925
|
groupName: resolved.groupName
|
|
@@ -25246,7 +25935,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25246
25935
|
const alreadyIn = agentIds.filter((id) => cached2.members.includes(id));
|
|
25247
25936
|
const toAdd = agentIds.filter((id) => !cached2.members.includes(id));
|
|
25248
25937
|
if (toAdd.length === 0) {
|
|
25249
|
-
|
|
25938
|
+
logger8.info("add_to_group: all agents already in group", {
|
|
25250
25939
|
agentId: deps.agentId,
|
|
25251
25940
|
groupId: resolved.groupId,
|
|
25252
25941
|
alreadyIn
|
|
@@ -25258,7 +25947,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25258
25947
|
}]
|
|
25259
25948
|
};
|
|
25260
25949
|
}
|
|
25261
|
-
|
|
25950
|
+
logger8.info("add_to_group tool called", {
|
|
25262
25951
|
agentId: deps.agentId,
|
|
25263
25952
|
groupId: resolved.groupId,
|
|
25264
25953
|
groupName: resolved.groupName,
|
|
@@ -25274,7 +25963,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25274
25963
|
});
|
|
25275
25964
|
if (!res.ok) {
|
|
25276
25965
|
const errText = await res.text().catch(() => "");
|
|
25277
|
-
|
|
25966
|
+
logger8.warn("add_to_group: server rejected", {
|
|
25278
25967
|
status: res.status,
|
|
25279
25968
|
errText,
|
|
25280
25969
|
groupId: resolved.groupId,
|
|
@@ -25289,7 +25978,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25289
25978
|
const a = deps.agentRegistry.getById(id);
|
|
25290
25979
|
return a ? a.name : id;
|
|
25291
25980
|
});
|
|
25292
|
-
|
|
25981
|
+
logger8.info("add_to_group: members added", {
|
|
25293
25982
|
agentId: deps.agentId,
|
|
25294
25983
|
groupId: resolved.groupId,
|
|
25295
25984
|
groupName: resolved.groupName,
|
|
@@ -25308,7 +25997,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25308
25997
|
}]
|
|
25309
25998
|
};
|
|
25310
25999
|
} catch (e) {
|
|
25311
|
-
|
|
26000
|
+
logger8.error("add_to_group failed", {
|
|
25312
26001
|
error: e,
|
|
25313
26002
|
groupId: resolved.groupId,
|
|
25314
26003
|
toAdd
|
|
@@ -25355,13 +26044,13 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25355
26044
|
cached2 = deps.groupRegistry.getById(resolved.groupId);
|
|
25356
26045
|
}
|
|
25357
26046
|
if (!cached2 || !cached2.members.includes(deps.agentId)) {
|
|
25358
|
-
|
|
26047
|
+
logger8.info("leave_group: not a member", { agentId: deps.agentId, groupId: resolved.groupId });
|
|
25359
26048
|
return {
|
|
25360
26049
|
content: [{ type: "text", text: `[leave_group] \u4F60\u4E0D\u5728\u7FA4\u300C${resolved.groupName}\u300D\u91CC\uFF0C\u65E0\u9700\u9000\u51FA\u3002` }],
|
|
25361
26050
|
isError: true
|
|
25362
26051
|
};
|
|
25363
26052
|
}
|
|
25364
|
-
|
|
26053
|
+
logger8.info("leave_group tool called", {
|
|
25365
26054
|
agentId: deps.agentId,
|
|
25366
26055
|
groupId: resolved.groupId,
|
|
25367
26056
|
groupName: resolved.groupName
|
|
@@ -25374,13 +26063,13 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25374
26063
|
});
|
|
25375
26064
|
if (!res.ok) {
|
|
25376
26065
|
const errText = await res.text().catch(() => "");
|
|
25377
|
-
|
|
26066
|
+
logger8.warn("leave_group: server rejected", { status: res.status, errText, groupId: resolved.groupId });
|
|
25378
26067
|
return {
|
|
25379
26068
|
content: [{ type: "text", text: `[leave_group] \u670D\u52A1\u7AEF\u62D2\u7EDD\uFF08${res.status}\uFF09\uFF1A${errText || "(no body)"}` }],
|
|
25380
26069
|
isError: true
|
|
25381
26070
|
};
|
|
25382
26071
|
}
|
|
25383
|
-
|
|
26072
|
+
logger8.info("leave_group: succeeded", {
|
|
25384
26073
|
agentId: deps.agentId,
|
|
25385
26074
|
groupId: resolved.groupId,
|
|
25386
26075
|
groupName: resolved.groupName
|
|
@@ -25395,7 +26084,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25395
26084
|
}]
|
|
25396
26085
|
};
|
|
25397
26086
|
} catch (e) {
|
|
25398
|
-
|
|
26087
|
+
logger8.error("leave_group failed", { error: e, groupId: resolved.groupId });
|
|
25399
26088
|
return {
|
|
25400
26089
|
content: [{ type: "text", text: `[leave_group] \u9000\u7FA4\u5931\u8D25\uFF1A${e.message}` }],
|
|
25401
26090
|
isError: true
|
|
@@ -25451,7 +26140,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25451
26140
|
};
|
|
25452
26141
|
}
|
|
25453
26142
|
if (cached2.createdBy == null) {
|
|
25454
|
-
|
|
26143
|
+
logger8.info("remove_from_group: ownerless group rejected", { agentId: deps.agentId, groupId: resolved.groupId });
|
|
25455
26144
|
return {
|
|
25456
26145
|
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` }],
|
|
25457
26146
|
isError: true
|
|
@@ -25460,7 +26149,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25460
26149
|
if (cached2.createdBy !== deps.agentId) {
|
|
25461
26150
|
const ownerInfo = deps.agentRegistry.getById(cached2.createdBy);
|
|
25462
26151
|
const ownerLabel = ownerInfo ? `${ownerInfo.name} (${cached2.createdBy})` : cached2.createdBy;
|
|
25463
|
-
|
|
26152
|
+
logger8.info("remove_from_group: not owner", {
|
|
25464
26153
|
agentId: deps.agentId,
|
|
25465
26154
|
groupId: resolved.groupId,
|
|
25466
26155
|
ownerId: cached2.createdBy
|
|
@@ -25498,7 +26187,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25498
26187
|
}]
|
|
25499
26188
|
};
|
|
25500
26189
|
}
|
|
25501
|
-
|
|
26190
|
+
logger8.info("remove_from_group tool called", {
|
|
25502
26191
|
agentId: deps.agentId,
|
|
25503
26192
|
groupId: resolved.groupId,
|
|
25504
26193
|
groupName: resolved.groupName,
|
|
@@ -25528,7 +26217,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25528
26217
|
const a = deps.agentRegistry.getById(id);
|
|
25529
26218
|
return a ? a.name : id;
|
|
25530
26219
|
});
|
|
25531
|
-
|
|
26220
|
+
logger8.info("remove_from_group: completed", {
|
|
25532
26221
|
agentId: deps.agentId,
|
|
25533
26222
|
groupId: resolved.groupId,
|
|
25534
26223
|
removedCount: removed.length,
|
|
@@ -25569,7 +26258,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25569
26258
|
}
|
|
25570
26259
|
const latestReadableSkillNames = currentReadableSkillNames();
|
|
25571
26260
|
if (!latestReadableSkillNames.includes(name)) {
|
|
25572
|
-
|
|
26261
|
+
logger8.warn("read_skill: not readable for agent", {
|
|
25573
26262
|
agentId: deps.agentId,
|
|
25574
26263
|
isSmith: deps.isSmith,
|
|
25575
26264
|
name,
|
|
@@ -25583,7 +26272,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25583
26272
|
isError: true
|
|
25584
26273
|
};
|
|
25585
26274
|
}
|
|
25586
|
-
|
|
26275
|
+
logger8.info("read_skill tool called", { agentId: deps.agentId, scope: currentScopeKey, name });
|
|
25587
26276
|
const content = deps.skillStore.read(name);
|
|
25588
26277
|
if (!content) {
|
|
25589
26278
|
return {
|
|
@@ -25594,7 +26283,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25594
26283
|
isError: true
|
|
25595
26284
|
};
|
|
25596
26285
|
}
|
|
25597
|
-
|
|
26286
|
+
logger8.info("read_skill returned", { agentId: deps.agentId, name, bytes: content.length });
|
|
25598
26287
|
return { content: [{ type: "text", text: content }] };
|
|
25599
26288
|
},
|
|
25600
26289
|
{}
|
|
@@ -25603,7 +26292,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25603
26292
|
"list_available_skills",
|
|
25604
26293
|
`\u5217\u51FA\u5F53\u524D Agent \u6B64\u523B\u53EF\u76F4\u63A5\u6309\u4EFB\u52A1\u4F7F\u7528\u7684 skill\u3002
|
|
25605
26294
|
\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
|
|
25606
|
-
\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
|
|
26295
|
+
\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
|
|
25607
26296
|
\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`,
|
|
25608
26297
|
{
|
|
25609
26298
|
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"),
|
|
@@ -25623,14 +26312,14 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25623
26312
|
entries: runtimeEntries,
|
|
25624
26313
|
runtime: skillRuntimeContext(deps.officeCliRuntime)
|
|
25625
26314
|
}), visibleSkillIds), availableSkillIds);
|
|
25626
|
-
|
|
26315
|
+
logger8.info("list_available_skills tool called", {
|
|
25627
26316
|
agentId: deps.agentId,
|
|
25628
26317
|
scope: currentScopeKey,
|
|
25629
26318
|
resultCount: entries.length,
|
|
25630
26319
|
agentScoped: Boolean(availableSkillIds)
|
|
25631
26320
|
});
|
|
25632
26321
|
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";
|
|
25633
|
-
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';
|
|
26322
|
+
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';
|
|
25634
26323
|
return {
|
|
25635
26324
|
content: [{
|
|
25636
26325
|
type: "text",
|
|
@@ -25659,7 +26348,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25659
26348
|
},
|
|
25660
26349
|
async (args) => {
|
|
25661
26350
|
if (!deps.isSmith && deps.getAvailableSkillIds && !availableSkillsChecked) {
|
|
25662
|
-
|
|
26351
|
+
logger8.info("list_skill_index blocked before list_available_skills", {
|
|
25663
26352
|
agentId: deps.agentId,
|
|
25664
26353
|
scope: currentScopeKey
|
|
25665
26354
|
});
|
|
@@ -25685,7 +26374,7 @@ Smith \u521B\u5EFA\u6216\u5207\u6362 Agent \u8FD0\u884C\u673A\u5668\u65F6\u53EF\
|
|
|
25685
26374
|
entries: runtimeEntries,
|
|
25686
26375
|
runtime: skillRuntimeContext(deps.officeCliRuntime)
|
|
25687
26376
|
}), visibleSkillIds);
|
|
25688
|
-
|
|
26377
|
+
logger8.info("list_skill_index tool called", {
|
|
25689
26378
|
agentId: deps.agentId,
|
|
25690
26379
|
scope: currentScopeKey,
|
|
25691
26380
|
resultCount: entries.length
|
|
@@ -25738,7 +26427,7 @@ local_modelscope_* \u662F\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server
|
|
|
25738
26427
|
officeCliMessage: deps.officeCliRuntime.message
|
|
25739
26428
|
} : void 0
|
|
25740
26429
|
}).filter((rec) => filterRuntimeVisibleSkillEntries([rec.skill], visibleSkillIds).length > 0);
|
|
25741
|
-
|
|
26430
|
+
logger8.info("recommend_agent_skills tool called", {
|
|
25742
26431
|
agentId: deps.agentId,
|
|
25743
26432
|
scope: currentScopeKey,
|
|
25744
26433
|
resultCount: recommendations.length
|
|
@@ -25750,7 +26439,8 @@ local_modelscope_* \u662F\u672C\u673A Local Skill\uFF0C\u4E0D\u5199\u5165 Server
|
|
|
25750
26439
|
`[recommend_agent_skills] recommended initial skill set (${recommendations.length})`,
|
|
25751
26440
|
formatSkillRecommendations(recommendations),
|
|
25752
26441
|
"",
|
|
25753
|
-
"\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"
|
|
26442
|
+
"\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",
|
|
26443
|
+
"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"
|
|
25754
26444
|
].join("\n")
|
|
25755
26445
|
}]
|
|
25756
26446
|
};
|
|
@@ -25776,7 +26466,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
|
|
|
25776
26466
|
},
|
|
25777
26467
|
async (args) => {
|
|
25778
26468
|
if (!deps.isSmith) {
|
|
25779
|
-
|
|
26469
|
+
logger8.warn("fetch_logs: permission denied (non-Smith caller)", { agentId: deps.agentId });
|
|
25780
26470
|
return {
|
|
25781
26471
|
content: [{ type: "text", text: "[fetch_logs] \u6743\u9650\u62D2\u7EDD\uFF1A\u53EA\u6709 Smith \u80FD\u8C03\u7528\u3002" }],
|
|
25782
26472
|
isError: true
|
|
@@ -25789,7 +26479,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
|
|
|
25789
26479
|
isError: true
|
|
25790
26480
|
};
|
|
25791
26481
|
}
|
|
25792
|
-
|
|
26482
|
+
logger8.info("fetch_logs tool called", {
|
|
25793
26483
|
agentId: deps.agentId,
|
|
25794
26484
|
source,
|
|
25795
26485
|
startIso: args.start_iso,
|
|
@@ -25822,7 +26512,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
|
|
|
25822
26512
|
});
|
|
25823
26513
|
if (!res.ok) {
|
|
25824
26514
|
const errText = await res.text().catch(() => "");
|
|
25825
|
-
|
|
26515
|
+
logger8.warn("fetch_logs: server rejected", { status: res.status, errText });
|
|
25826
26516
|
return {
|
|
25827
26517
|
content: [{
|
|
25828
26518
|
type: "text",
|
|
@@ -25832,7 +26522,7 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\uFF1B\u652F\u6301 offset \u5
|
|
|
25832
26522
|
};
|
|
25833
26523
|
}
|
|
25834
26524
|
const json2 = await res.json();
|
|
25835
|
-
|
|
26525
|
+
logger8.info("fetch_logs returned", {
|
|
25836
26526
|
source,
|
|
25837
26527
|
count: json2.entries.length,
|
|
25838
26528
|
truncated: json2.truncated,
|
|
@@ -25858,7 +26548,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25858
26548
|
const text = [header, "", ...lines].join("\n");
|
|
25859
26549
|
return { content: [{ type: "text", text }] };
|
|
25860
26550
|
} catch (e) {
|
|
25861
|
-
|
|
26551
|
+
logger8.error("fetch_logs failed", { error: e });
|
|
25862
26552
|
return {
|
|
25863
26553
|
content: [{ type: "text", text: `[fetch_logs] \u8C03\u7528\u5931\u8D25\uFF1A${e.message}` }],
|
|
25864
26554
|
isError: true
|
|
@@ -25872,7 +26562,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25872
26562
|
`\u521B\u9020\u4E00\u4E2A\u65B0\u7684 Agent\u3002\u53EA\u6709\u4F60\uFF08Smith\uFF09\u80FD\u4F7F\u7528\u6B64\u5DE5\u5177\u3002
|
|
25873
26563
|
\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
|
|
25874
26564
|
\u521B\u5EFA\u540E\u4F60\u53EF\u4EE5\u901A\u8FC7 create_group + add_to_group \u628A\u5B83\u62C9\u8FDB\u7FA4\u3002
|
|
25875
|
-
\u521B\u5EFA\u65F6\
|
|
26565
|
+
\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
|
|
25876
26566
|
|
|
25877
26567
|
**\u80FD\u529B\u6863\u4F4D\u9009\u62E9\u6307\u5357\uFF1A**
|
|
25878
26568
|
- **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
|
|
@@ -25906,15 +26596,15 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25906
26596
|
"\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"
|
|
25907
26597
|
),
|
|
25908
26598
|
machine_bridge_key: external_exports.string().optional().describe(
|
|
25909
|
-
|
|
26599
|
+
"\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"
|
|
25910
26600
|
),
|
|
25911
26601
|
skill_ids: external_exports.array(external_exports.string()).optional().describe(
|
|
25912
|
-
"\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"
|
|
26602
|
+
"\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"
|
|
25913
26603
|
)
|
|
25914
26604
|
},
|
|
25915
26605
|
async (args) => {
|
|
25916
26606
|
if (!deps.isSmith) {
|
|
25917
|
-
|
|
26607
|
+
logger8.warn("create_agent: permission denied (non-Smith caller)", {
|
|
25918
26608
|
agentId: deps.agentId,
|
|
25919
26609
|
scope: currentScopeKey
|
|
25920
26610
|
});
|
|
@@ -25939,10 +26629,24 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25939
26629
|
const avatar = args.avatar && String(args.avatar).trim() || "";
|
|
25940
26630
|
const initialInstruction = args.initial_instruction && String(args.initial_instruction).trim() || "";
|
|
25941
26631
|
const workingDirectory = args.working_directory && String(args.working_directory).trim() || "";
|
|
25942
|
-
const
|
|
26632
|
+
const requestedMachineBridgeKey = args.machine_bridge_key && String(args.machine_bridge_key).trim() || "";
|
|
26633
|
+
const machineBridgeKey = requestedMachineBridgeKey === "auto" ? "" : requestedMachineBridgeKey;
|
|
26634
|
+
const remoteMachineError = rejectRemoteCreateMachineBridgeKey(machineBridgeKey, deps);
|
|
26635
|
+
if (remoteMachineError) {
|
|
26636
|
+
logger8.warn("create_agent: rejected remote machine_bridge_key on create", {
|
|
26637
|
+
agentId: deps.agentId,
|
|
26638
|
+
scope: currentScopeKey,
|
|
26639
|
+
requestedMachineBridgeKey: machineBridgeKey,
|
|
26640
|
+
currentBridgeKey: deps.currentBridgeKey ?? null
|
|
26641
|
+
});
|
|
26642
|
+
return {
|
|
26643
|
+
content: [{ type: "text", text: remoteMachineError }],
|
|
26644
|
+
isError: true
|
|
26645
|
+
};
|
|
26646
|
+
}
|
|
25943
26647
|
const machineValidation = await validateOnlineMachineBridgeKey("create_agent", machineBridgeKey, deps);
|
|
25944
26648
|
if (!machineValidation.ok) {
|
|
25945
|
-
|
|
26649
|
+
logger8.warn("create_agent: rejected offline or unknown machine_bridge_key", {
|
|
25946
26650
|
agentId: deps.agentId,
|
|
25947
26651
|
scope: currentScopeKey,
|
|
25948
26652
|
machineBridgeKey
|
|
@@ -25971,15 +26675,15 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25971
26675
|
capabilityTier: tier,
|
|
25972
26676
|
subscriptionId: tierConfig.subscriptionId
|
|
25973
26677
|
});
|
|
25974
|
-
|
|
26678
|
+
logger8.info("Tier resolved", { tier, subscriptionId: tierConfig.subscriptionId, model: tierConfig.modelName });
|
|
25975
26679
|
} else {
|
|
25976
|
-
|
|
26680
|
+
logger8.warn("Tier not found, using default", { tier, availableTiers: tiers.map((t) => t.tier) });
|
|
25977
26681
|
}
|
|
25978
26682
|
} else {
|
|
25979
|
-
|
|
26683
|
+
logger8.warn("Failed to fetch tiers", { status: tierRes.status });
|
|
25980
26684
|
}
|
|
25981
26685
|
} catch (e) {
|
|
25982
|
-
|
|
26686
|
+
logger8.error("Tier resolution failed", { error: e });
|
|
25983
26687
|
}
|
|
25984
26688
|
}
|
|
25985
26689
|
const body = { name, role, systemPrompt, avatar };
|
|
@@ -25992,7 +26696,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
25992
26696
|
if (machineBridgeKey) {
|
|
25993
26697
|
body.machineBridgeKey = machineBridgeKey;
|
|
25994
26698
|
}
|
|
25995
|
-
|
|
26699
|
+
logger8.info("create_agent tool called", {
|
|
25996
26700
|
agentId: deps.agentId,
|
|
25997
26701
|
requestedBy: deps.agentId,
|
|
25998
26702
|
scope: currentScopeKey,
|
|
@@ -26013,7 +26717,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26013
26717
|
});
|
|
26014
26718
|
if (!res.ok) {
|
|
26015
26719
|
const errText = await res.text().catch(() => "");
|
|
26016
|
-
|
|
26720
|
+
logger8.warn("create_agent: server rejected", { status: res.status, errText, name });
|
|
26017
26721
|
return {
|
|
26018
26722
|
content: [{
|
|
26019
26723
|
type: "text",
|
|
@@ -26024,7 +26728,44 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26024
26728
|
}
|
|
26025
26729
|
const agent = await res.json();
|
|
26026
26730
|
const resolvedMachineBridgeKey = agent.machineBridgeKey ?? machineBridgeKey;
|
|
26731
|
+
const skillIntent = {
|
|
26732
|
+
name,
|
|
26733
|
+
role,
|
|
26734
|
+
systemPrompt,
|
|
26735
|
+
initialInstruction,
|
|
26736
|
+
workingDirectory
|
|
26737
|
+
};
|
|
26027
26738
|
const requestedSkillIds = Array.isArray(args.skill_ids) ? args.skill_ids.map((id) => typeof id === "string" ? id.trim() : "").filter((id) => id.length > 0) : [];
|
|
26739
|
+
const autoAssignedOfficialSkillIds = autoAssignOfficialSkillIds(skillIntent);
|
|
26740
|
+
for (const skillId of autoAssignedOfficialSkillIds) {
|
|
26741
|
+
if (requestedSkillIds.includes(skillId)) continue;
|
|
26742
|
+
requestedSkillIds.push(skillId);
|
|
26743
|
+
logger8.info("create_agent: auto-added official workflow skill", {
|
|
26744
|
+
requestedBy: deps.agentId,
|
|
26745
|
+
newAgentId: agent.id,
|
|
26746
|
+
skillId
|
|
26747
|
+
});
|
|
26748
|
+
}
|
|
26749
|
+
const explicitlyRequestedLocalSkill = requestedSkillIds.some(isLocalSkillId);
|
|
26750
|
+
const localEnhancerTargetBridgeKey = resolvedMachineBridgeKey ?? machineBridgeKey;
|
|
26751
|
+
if (autoAssignedOfficialSkillIds.length > 0 && !explicitlyRequestedLocalSkill && deps.setLocalSkillAgentVisibility && isCurrentMachineLocalTarget(localEnhancerTargetBridgeKey, deps.currentBridgeKey)) {
|
|
26752
|
+
const localEnhancerSkillIds = selectLocalSkillEnhancersForCreateAgent(
|
|
26753
|
+
skillIntent,
|
|
26754
|
+
deps.skillStore,
|
|
26755
|
+
new Set(requestedSkillIds)
|
|
26756
|
+
);
|
|
26757
|
+
for (const skillId of localEnhancerSkillIds) {
|
|
26758
|
+
requestedSkillIds.push(skillId);
|
|
26759
|
+
}
|
|
26760
|
+
if (localEnhancerSkillIds.length > 0) {
|
|
26761
|
+
logger8.info("create_agent: auto-added local skill enhancers", {
|
|
26762
|
+
requestedBy: deps.agentId,
|
|
26763
|
+
newAgentId: agent.id,
|
|
26764
|
+
localEnhancerSkillIds,
|
|
26765
|
+
targetBridgeKey: localEnhancerTargetBridgeKey || "(current-bridge)"
|
|
26766
|
+
});
|
|
26767
|
+
}
|
|
26768
|
+
}
|
|
26028
26769
|
const skillIds = Array.from(new Set(requestedSkillIds));
|
|
26029
26770
|
const localSkillIds = skillIds.filter(isLocalSkillId);
|
|
26030
26771
|
const serverSkillIds = skillIds.filter((id) => !isLocalSkillId(id));
|
|
@@ -26043,7 +26784,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26043
26784
|
const assignBody = await assignRes.json();
|
|
26044
26785
|
const assignedCount = assignBody.assigned?.length ?? 0;
|
|
26045
26786
|
const skipped = assignBody.skipped ?? [];
|
|
26046
|
-
|
|
26787
|
+
logger8.info("create_agent: initial skills assigned", {
|
|
26047
26788
|
requestedBy: deps.agentId,
|
|
26048
26789
|
newAgentId: agent.id,
|
|
26049
26790
|
assignedCount,
|
|
@@ -26052,7 +26793,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26052
26793
|
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`;
|
|
26053
26794
|
} else {
|
|
26054
26795
|
const errText = await assignRes.text().catch(() => "");
|
|
26055
|
-
|
|
26796
|
+
logger8.warn("create_agent: initial skill assignment rejected", {
|
|
26056
26797
|
newAgentId: agent.id,
|
|
26057
26798
|
status: assignRes.status,
|
|
26058
26799
|
errText
|
|
@@ -26060,18 +26801,18 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26060
26801
|
skillAssignNote = `\u521D\u59CB skill \u5206\u914D\u5931\u8D25\uFF08${assignRes.status}\uFF09\uFF0C\u53EF\u7A0D\u540E\u7528 assign \u6D41\u7A0B\u8865\u914D\u3002`;
|
|
26061
26802
|
}
|
|
26062
26803
|
} catch (e) {
|
|
26063
|
-
|
|
26804
|
+
logger8.error("create_agent: initial skill assignment failed", { error: e, newAgentId: agent.id });
|
|
26064
26805
|
skillAssignNote = "\u521D\u59CB skill \u5206\u914D\u5931\u8D25\uFF0C\u53EF\u7A0D\u540E\u8865\u914D\u3002";
|
|
26065
26806
|
}
|
|
26066
26807
|
}
|
|
26067
26808
|
if (localSkillIds.length > 0) {
|
|
26068
26809
|
const targetBridgeKey = resolvedMachineBridgeKey ?? machineBridgeKey;
|
|
26069
|
-
const localSkillTargetIsCurrentMachine =
|
|
26810
|
+
const localSkillTargetIsCurrentMachine = isCurrentMachineLocalTarget(targetBridgeKey, deps.currentBridgeKey);
|
|
26070
26811
|
let localAssignedCount = 0;
|
|
26071
26812
|
const localSkipped = [];
|
|
26072
26813
|
if (!localSkillTargetIsCurrentMachine) {
|
|
26073
26814
|
localSkipped.push(...localSkillIds);
|
|
26074
|
-
|
|
26815
|
+
logger8.warn("create_agent: local skills skipped for remote machine target", {
|
|
26075
26816
|
requestedBy: deps.agentId,
|
|
26076
26817
|
newAgentId: agent.id,
|
|
26077
26818
|
localSkillIds,
|
|
@@ -26080,7 +26821,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26080
26821
|
});
|
|
26081
26822
|
} else if (!deps.setLocalSkillAgentVisibility) {
|
|
26082
26823
|
localSkipped.push(...localSkillIds);
|
|
26083
|
-
|
|
26824
|
+
logger8.warn("create_agent: local skill binder unavailable", {
|
|
26084
26825
|
requestedBy: deps.agentId,
|
|
26085
26826
|
newAgentId: agent.id,
|
|
26086
26827
|
localSkillIds
|
|
@@ -26096,7 +26837,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26096
26837
|
}
|
|
26097
26838
|
} catch (e) {
|
|
26098
26839
|
localSkipped.push(skillId);
|
|
26099
|
-
|
|
26840
|
+
logger8.error("create_agent: local skill assignment failed", {
|
|
26100
26841
|
error: e,
|
|
26101
26842
|
requestedBy: deps.agentId,
|
|
26102
26843
|
newAgentId: agent.id,
|
|
@@ -26108,7 +26849,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26108
26849
|
await deps.onLocalSkillVisibilityChanged?.([agent.id]);
|
|
26109
26850
|
}
|
|
26110
26851
|
}
|
|
26111
|
-
|
|
26852
|
+
logger8.info("create_agent: local skill assignment resolved", {
|
|
26112
26853
|
requestedBy: deps.agentId,
|
|
26113
26854
|
newAgentId: agent.id,
|
|
26114
26855
|
localSkillIds,
|
|
@@ -26118,7 +26859,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26118
26859
|
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`;
|
|
26119
26860
|
skillAssignNote = skillAssignNote ? `${skillAssignNote}${localSkillNote}` : localSkillNote;
|
|
26120
26861
|
}
|
|
26121
|
-
|
|
26862
|
+
logger8.info("create_agent: created", {
|
|
26122
26863
|
requestedBy: deps.agentId,
|
|
26123
26864
|
scope: currentScopeKey,
|
|
26124
26865
|
agentId: agent.id,
|
|
@@ -26137,7 +26878,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26137
26878
|
});
|
|
26138
26879
|
if (initialInstruction && deps.onAgentCreatedInitInstruction) {
|
|
26139
26880
|
try {
|
|
26140
|
-
|
|
26881
|
+
logger8.info("create_agent: firing initial instruction dispatch", {
|
|
26141
26882
|
requestedBy: deps.agentId,
|
|
26142
26883
|
newAgentId: agent.id,
|
|
26143
26884
|
newAgentName: agent.name,
|
|
@@ -26150,7 +26891,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26150
26891
|
requestedBy: deps.agentId
|
|
26151
26892
|
});
|
|
26152
26893
|
} catch (e) {
|
|
26153
|
-
|
|
26894
|
+
logger8.error("create_agent: onAgentCreatedInitInstruction sync threw", {
|
|
26154
26895
|
error: e,
|
|
26155
26896
|
newAgentId: agent.id
|
|
26156
26897
|
});
|
|
@@ -26163,7 +26904,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26163
26904
|
content: [{ type: "text", text: reply }]
|
|
26164
26905
|
};
|
|
26165
26906
|
} catch (e) {
|
|
26166
|
-
|
|
26907
|
+
logger8.error("create_agent failed", { error: e, name });
|
|
26167
26908
|
return {
|
|
26168
26909
|
content: [{ type: "text", text: `[create_agent] \u521B\u5EFA\u5931\u8D25\uFF1A${e.message}` }],
|
|
26169
26910
|
isError: true
|
|
@@ -26235,7 +26976,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26235
26976
|
deps
|
|
26236
26977
|
);
|
|
26237
26978
|
if (!machineValidation.ok) {
|
|
26238
|
-
|
|
26979
|
+
logger8.warn("update_agent_profile: rejected offline or unknown machine_bridge_key", {
|
|
26239
26980
|
agentId: deps.agentId,
|
|
26240
26981
|
targetAgentId: agentId,
|
|
26241
26982
|
machineBridgeKey: requestedMachineBridgeKey
|
|
@@ -26266,11 +27007,11 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26266
27007
|
subscriptionId: tierConfig.subscriptionId,
|
|
26267
27008
|
model: tierConfig.modelName
|
|
26268
27009
|
});
|
|
26269
|
-
|
|
27010
|
+
logger8.info("update_agent: tier resolved", { agentId, tier, subscriptionId: tierConfig.subscriptionId });
|
|
26270
27011
|
}
|
|
26271
27012
|
}
|
|
26272
27013
|
} catch (e) {
|
|
26273
|
-
|
|
27014
|
+
logger8.error("update_agent: tier resolution failed", { error: e });
|
|
26274
27015
|
}
|
|
26275
27016
|
}
|
|
26276
27017
|
const patchBody = {};
|
|
@@ -26289,7 +27030,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26289
27030
|
isError: true
|
|
26290
27031
|
};
|
|
26291
27032
|
}
|
|
26292
|
-
|
|
27033
|
+
logger8.info("update_agent_profile tool called", {
|
|
26293
27034
|
agentId: deps.agentId,
|
|
26294
27035
|
targetAgentId: agentId,
|
|
26295
27036
|
targetName: existing.name,
|
|
@@ -26309,7 +27050,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26309
27050
|
};
|
|
26310
27051
|
}
|
|
26311
27052
|
const updated = await res.json();
|
|
26312
|
-
|
|
27053
|
+
logger8.info("update_agent_profile: succeeded", {
|
|
26313
27054
|
agentId: deps.agentId,
|
|
26314
27055
|
targetAgentId: agentId,
|
|
26315
27056
|
newName: updated.name
|
|
@@ -26321,7 +27062,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26321
27062
|
}]
|
|
26322
27063
|
};
|
|
26323
27064
|
} catch (e) {
|
|
26324
|
-
|
|
27065
|
+
logger8.error("update_agent_profile failed", { error: e, agentId });
|
|
26325
27066
|
return {
|
|
26326
27067
|
content: [{ type: "text", text: `[update_agent_profile] \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}` }],
|
|
26327
27068
|
isError: true
|
|
@@ -26358,7 +27099,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26358
27099
|
};
|
|
26359
27100
|
}
|
|
26360
27101
|
const base = deps.serverApiUrl.replace(/\/$/, "");
|
|
26361
|
-
|
|
27102
|
+
logger8.info("archive_conversation tool called", {
|
|
26362
27103
|
agentId: deps.agentId,
|
|
26363
27104
|
targetAgentId: agentId,
|
|
26364
27105
|
conversationId
|
|
@@ -26379,7 +27120,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26379
27120
|
isError: true
|
|
26380
27121
|
};
|
|
26381
27122
|
}
|
|
26382
|
-
|
|
27123
|
+
logger8.info("archive_conversation: succeeded", {
|
|
26383
27124
|
agentId: deps.agentId,
|
|
26384
27125
|
conversationId
|
|
26385
27126
|
});
|
|
@@ -26390,7 +27131,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26390
27131
|
}]
|
|
26391
27132
|
};
|
|
26392
27133
|
} catch (e) {
|
|
26393
|
-
|
|
27134
|
+
logger8.error("archive_conversation failed", { error: e, conversationId });
|
|
26394
27135
|
return {
|
|
26395
27136
|
content: [{ type: "text", text: `[archive_conversation] \u5F52\u6863\u5931\u8D25\uFF1A${e.message}` }],
|
|
26396
27137
|
isError: true
|
|
@@ -26434,7 +27175,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26434
27175
|
isError: true
|
|
26435
27176
|
};
|
|
26436
27177
|
}
|
|
26437
|
-
|
|
27178
|
+
logger8.info("transfer_group_owner tool called", {
|
|
26438
27179
|
agentId: deps.agentId,
|
|
26439
27180
|
fromOwnerId: deps.agentId,
|
|
26440
27181
|
scope: currentScopeKey,
|
|
@@ -26453,7 +27194,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26453
27194
|
});
|
|
26454
27195
|
if (!res.ok) {
|
|
26455
27196
|
const errText = await res.text().catch(() => "");
|
|
26456
|
-
|
|
27197
|
+
logger8.warn("transfer_group_owner: server rejected", {
|
|
26457
27198
|
status: res.status,
|
|
26458
27199
|
errText,
|
|
26459
27200
|
groupId: resolved.groupId
|
|
@@ -26466,7 +27207,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26466
27207
|
isError: true
|
|
26467
27208
|
};
|
|
26468
27209
|
}
|
|
26469
|
-
|
|
27210
|
+
logger8.info("transfer_group_owner: succeeded", {
|
|
26470
27211
|
agentId: deps.agentId,
|
|
26471
27212
|
fromOwnerId: deps.agentId,
|
|
26472
27213
|
scope: currentScopeKey,
|
|
@@ -26480,7 +27221,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26480
27221
|
}]
|
|
26481
27222
|
};
|
|
26482
27223
|
} catch (e) {
|
|
26483
|
-
|
|
27224
|
+
logger8.error("transfer_group_owner failed", { error: e, groupId: resolved.groupId });
|
|
26484
27225
|
return {
|
|
26485
27226
|
content: [{
|
|
26486
27227
|
type: "text",
|
|
@@ -26549,7 +27290,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26549
27290
|
}
|
|
26550
27291
|
}
|
|
26551
27292
|
}
|
|
26552
|
-
|
|
27293
|
+
logger8.info("list_friends called", {
|
|
26553
27294
|
agentId: deps.agentId,
|
|
26554
27295
|
friendCount: friends.length
|
|
26555
27296
|
});
|
|
@@ -26557,7 +27298,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26557
27298
|
content: [{ type: "text", text: parts.join("\n") }]
|
|
26558
27299
|
};
|
|
26559
27300
|
} catch (e) {
|
|
26560
|
-
|
|
27301
|
+
logger8.error("list_friends failed", { error: e });
|
|
26561
27302
|
return {
|
|
26562
27303
|
content: [{ type: "text", text: `[list_friends] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
|
|
26563
27304
|
isError: true
|
|
@@ -26601,7 +27342,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26601
27342
|
isError: true
|
|
26602
27343
|
};
|
|
26603
27344
|
}
|
|
26604
|
-
|
|
27345
|
+
logger8.info("accept_friend called", {
|
|
26605
27346
|
agentId: deps.agentId,
|
|
26606
27347
|
requestId,
|
|
26607
27348
|
action
|
|
@@ -26617,7 +27358,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26617
27358
|
content: [{ type: "text", text: `[accept_friend] \u5DF2\u62D2\u7EDD\u8BE5\u597D\u53CB\u7533\u8BF7\u3002` }]
|
|
26618
27359
|
};
|
|
26619
27360
|
} catch (e) {
|
|
26620
|
-
|
|
27361
|
+
logger8.error("accept_friend failed", { error: e });
|
|
26621
27362
|
return {
|
|
26622
27363
|
content: [{ type: "text", text: `[accept_friend] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
|
|
26623
27364
|
isError: true
|
|
@@ -26695,7 +27436,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26695
27436
|
isError: true
|
|
26696
27437
|
};
|
|
26697
27438
|
}
|
|
26698
|
-
|
|
27439
|
+
logger8.info("add_friend: request sent", {
|
|
26699
27440
|
agentId: deps.agentId,
|
|
26700
27441
|
targetUserId: lookup.user.id,
|
|
26701
27442
|
targetName: lookup.user.name,
|
|
@@ -26708,7 +27449,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26708
27449
|
}]
|
|
26709
27450
|
};
|
|
26710
27451
|
} catch (e) {
|
|
26711
|
-
|
|
27452
|
+
logger8.error("add_friend failed", { error: e });
|
|
26712
27453
|
return {
|
|
26713
27454
|
content: [{ type: "text", text: `[add_friend] \u64CD\u4F5C\u5931\u8D25\uFF1A${e.message}` }],
|
|
26714
27455
|
isError: true
|
|
@@ -26728,7 +27469,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26728
27469
|
}
|
|
26729
27470
|
const category = normalizeFeedCategory(args.category);
|
|
26730
27471
|
const groupId = (args.group_id ?? "").trim() || (deps.scope.kind === "group" ? deps.scope.groupId : void 0);
|
|
26731
|
-
|
|
27472
|
+
logger8.info(`${toolName} tool called`, {
|
|
26732
27473
|
agentId: deps.agentId,
|
|
26733
27474
|
scope: currentScopeKey,
|
|
26734
27475
|
title,
|
|
@@ -26751,7 +27492,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26751
27492
|
});
|
|
26752
27493
|
if (!res.ok) {
|
|
26753
27494
|
const errText = await res.text().catch(() => "");
|
|
26754
|
-
|
|
27495
|
+
logger8.warn(`${toolName}: server rejected`, { status: res.status, errText, title });
|
|
26755
27496
|
return {
|
|
26756
27497
|
content: [{
|
|
26757
27498
|
type: "text",
|
|
@@ -26761,7 +27502,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26761
27502
|
};
|
|
26762
27503
|
}
|
|
26763
27504
|
const payload = await res.json();
|
|
26764
|
-
|
|
27505
|
+
logger8.info(`${toolName}: created`, {
|
|
26765
27506
|
agentId: deps.agentId,
|
|
26766
27507
|
scope: currentScopeKey,
|
|
26767
27508
|
postId: payload.post?.id,
|
|
@@ -26774,7 +27515,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26774
27515
|
}]
|
|
26775
27516
|
};
|
|
26776
27517
|
} catch (e) {
|
|
26777
|
-
|
|
27518
|
+
logger8.error(`${toolName} failed`, { error: e, title });
|
|
26778
27519
|
return {
|
|
26779
27520
|
content: [{ type: "text", text: `[${toolName}] \u53D1\u5E03\u5931\u8D25\uFF1A${e.message}` }],
|
|
26780
27521
|
isError: true
|
|
@@ -26829,7 +27570,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26829
27570
|
const category = args.category ? normalizeFeedCategory(args.category) : void 0;
|
|
26830
27571
|
const rawGroupId = (args.group_id ?? "").trim();
|
|
26831
27572
|
const groupId = rawGroupId === "all" ? void 0 : rawGroupId || (deps.scope.kind === "group" ? deps.scope.groupId : void 0);
|
|
26832
|
-
|
|
27573
|
+
logger8.info("read_moments tool called", {
|
|
26833
27574
|
agentId: deps.agentId,
|
|
26834
27575
|
scope: currentScopeKey,
|
|
26835
27576
|
limit,
|
|
@@ -26846,7 +27587,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26846
27587
|
});
|
|
26847
27588
|
if (!res.ok) {
|
|
26848
27589
|
const errText = await res.text().catch(() => "");
|
|
26849
|
-
|
|
27590
|
+
logger8.warn("read_moments: server rejected", { status: res.status, errText });
|
|
26850
27591
|
return {
|
|
26851
27592
|
content: [{
|
|
26852
27593
|
type: "text",
|
|
@@ -26857,7 +27598,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26857
27598
|
}
|
|
26858
27599
|
const payload = await res.json();
|
|
26859
27600
|
const posts = Array.isArray(payload.posts) ? payload.posts : [];
|
|
26860
|
-
|
|
27601
|
+
logger8.info("read_moments returned", {
|
|
26861
27602
|
agentId: deps.agentId,
|
|
26862
27603
|
scope: currentScopeKey,
|
|
26863
27604
|
count: posts.length,
|
|
@@ -26881,7 +27622,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26881
27622
|
}]
|
|
26882
27623
|
};
|
|
26883
27624
|
} catch (e) {
|
|
26884
|
-
|
|
27625
|
+
logger8.error("read_moments failed", { error: e });
|
|
26885
27626
|
return {
|
|
26886
27627
|
content: [{ type: "text", text: `[read_moments] \u8BFB\u53D6\u5931\u8D25\uFF1A${e.message}` }],
|
|
26887
27628
|
isError: true
|
|
@@ -26949,7 +27690,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26949
27690
|
if (postToMomentsTool) toolNames.push("post_to_moments");
|
|
26950
27691
|
if (postToForumTool) toolNames.push("post_to_forum");
|
|
26951
27692
|
if (readMomentsTool) toolNames.push("read_moments");
|
|
26952
|
-
|
|
27693
|
+
logger8.info("Neural MCP server created", {
|
|
26953
27694
|
agentId: deps.agentId,
|
|
26954
27695
|
isSmith: deps.isSmith,
|
|
26955
27696
|
scope: currentScopeKey,
|
|
@@ -26959,7 +27700,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
|
|
|
26959
27700
|
}
|
|
26960
27701
|
|
|
26961
27702
|
// src/groupDispatchMemory.ts
|
|
26962
|
-
var
|
|
27703
|
+
var logger9 = createModuleLogger("agent.dispatchMemory");
|
|
26963
27704
|
var GroupDispatchMemoryStore = class {
|
|
26964
27705
|
memo = /* @__PURE__ */ new Map();
|
|
26965
27706
|
getOrCreate(agentId, scope) {
|
|
@@ -26980,7 +27721,7 @@ var GroupDispatchMemoryStore = class {
|
|
|
26980
27721
|
reset(agentId, scope, reason = "compact_completed") {
|
|
26981
27722
|
const key = runtimeKey(agentId, scope);
|
|
26982
27723
|
if (this.memo.delete(key)) {
|
|
26983
|
-
|
|
27724
|
+
logger9.info("Dispatch memory reset", {
|
|
26984
27725
|
agentId,
|
|
26985
27726
|
scope: scope.kind === "single" ? "single" : scope.groupId,
|
|
26986
27727
|
reason
|
|
@@ -27183,115 +27924,28 @@ function buildGroupInboxPrompt(entries, opts = {}) {
|
|
|
27183
27924
|
return lines.join("\n");
|
|
27184
27925
|
}
|
|
27185
27926
|
|
|
27186
|
-
// src/officeRuntime.ts
|
|
27187
|
-
import fs4 from "fs";
|
|
27188
|
-
import os5 from "os";
|
|
27189
|
-
import path9 from "path";
|
|
27190
|
-
var OFFICECLI_EXECUTABLE_ENV = "AHCHAT_OFFICECLI_EXECUTABLE";
|
|
27191
|
-
var OFFICECLI_BIN_DIR_ENV = "AHCHAT_OFFICECLI_BIN_DIR";
|
|
27192
|
-
var logger9 = createModuleLogger("bridge.officeRuntime");
|
|
27193
|
-
function sanitizedOfficeCliProbeError(error51) {
|
|
27194
|
-
const rawCode = error51 && typeof error51 === "object" && "code" in error51 ? error51.code : void 0;
|
|
27195
|
-
const code = typeof rawCode === "string" ? rawCode : void 0;
|
|
27196
|
-
const sanitized = new Error(`OfficeCLI executable probe failed${code ? ` (${code})` : ""}`);
|
|
27197
|
-
if (error51 instanceof Error) sanitized.name = error51.name;
|
|
27198
|
-
return sanitized;
|
|
27199
|
-
}
|
|
27200
|
-
function defaultRuntimeRoot() {
|
|
27201
|
-
if (process.platform === "win32") {
|
|
27202
|
-
return path9.join(process.env.LOCALAPPDATA || path9.join(os5.homedir(), "AppData", "Local"), "AHChat", "runtime", "officecli");
|
|
27203
|
-
}
|
|
27204
|
-
if (process.platform === "darwin") {
|
|
27205
|
-
return path9.join(os5.homedir(), "Library", "Caches", "AHChat", "runtime", "officecli");
|
|
27206
|
-
}
|
|
27207
|
-
return path9.join(process.env.XDG_CACHE_HOME || path9.join(os5.homedir(), ".cache"), "ahchat", "runtime", "officecli");
|
|
27208
|
-
}
|
|
27209
|
-
function getManagedOfficeCliBinDir(env2 = process.env) {
|
|
27210
|
-
return env2[OFFICECLI_BIN_DIR_ENV] || path9.join(defaultRuntimeRoot(), "bin");
|
|
27211
|
-
}
|
|
27212
|
-
function getOfficeCliExecutableName() {
|
|
27213
|
-
return process.platform === "win32" ? "officecli.exe" : "officecli";
|
|
27214
|
-
}
|
|
27215
|
-
function getManagedOfficeCliExecutablePath(env2 = process.env) {
|
|
27216
|
-
return path9.join(getManagedOfficeCliBinDir(env2), getOfficeCliExecutableName());
|
|
27217
|
-
}
|
|
27218
|
-
function isExecutable(filePath, options = {}) {
|
|
27219
|
-
const logFailure = options.logFailure !== false;
|
|
27220
|
-
try {
|
|
27221
|
-
if (process.platform === "win32") return fs4.existsSync(filePath);
|
|
27222
|
-
fs4.accessSync(filePath, fs4.constants.X_OK);
|
|
27223
|
-
return true;
|
|
27224
|
-
} catch (error51) {
|
|
27225
|
-
if (logFailure) {
|
|
27226
|
-
logger9.error("OfficeCLI executable probe failed", {
|
|
27227
|
-
error: sanitizedOfficeCliProbeError(error51),
|
|
27228
|
-
fileName: path9.basename(filePath)
|
|
27229
|
-
});
|
|
27230
|
-
}
|
|
27231
|
-
return false;
|
|
27232
|
-
}
|
|
27233
|
-
}
|
|
27234
|
-
function withPrependedPath(env2, entries) {
|
|
27235
|
-
const pathEntries = entries.filter((entry) => entry && fs4.existsSync(entry));
|
|
27236
|
-
if (pathEntries.length === 0) return env2;
|
|
27237
|
-
const current = env2.PATH ?? "";
|
|
27238
|
-
return {
|
|
27239
|
-
...env2,
|
|
27240
|
-
PATH: [...pathEntries, current].filter(Boolean).join(path9.delimiter)
|
|
27241
|
-
};
|
|
27242
|
-
}
|
|
27243
|
-
function statusForPath(filePath, source, env2, options = {}) {
|
|
27244
|
-
if (!isExecutable(filePath, { logFailure: options.logProbeFailure })) {
|
|
27245
|
-
return {
|
|
27246
|
-
ok: false,
|
|
27247
|
-
path: filePath,
|
|
27248
|
-
source,
|
|
27249
|
-
message: `officecli not executable at ${filePath}`
|
|
27250
|
-
};
|
|
27251
|
-
}
|
|
27252
|
-
const runtimeEnv = withPrependedPath(env2, [path9.dirname(filePath)]);
|
|
27253
|
-
const version2 = readCommandVersion(filePath, ["--version"], runtimeEnv);
|
|
27254
|
-
if (!version2) {
|
|
27255
|
-
return {
|
|
27256
|
-
ok: false,
|
|
27257
|
-
path: filePath,
|
|
27258
|
-
source,
|
|
27259
|
-
message: `officecli found at ${filePath} but --version failed`
|
|
27260
|
-
};
|
|
27261
|
-
}
|
|
27262
|
-
return { ok: true, path: filePath, source, version: version2 };
|
|
27263
|
-
}
|
|
27264
|
-
function detectOfficeCliRuntime(env2 = process.env) {
|
|
27265
|
-
const explicitPath = env2[OFFICECLI_EXECUTABLE_ENV]?.trim();
|
|
27266
|
-
if (explicitPath) return statusForPath(explicitPath, "env", env2);
|
|
27267
|
-
const managedPath = getManagedOfficeCliExecutablePath(env2);
|
|
27268
|
-
const managed = statusForPath(managedPath, "managed", env2, { logProbeFailure: false });
|
|
27269
|
-
if (managed.ok) return managed;
|
|
27270
|
-
const resolved = resolveCommand(["officecli"], withPrependedPath(env2, [path9.dirname(managedPath)]));
|
|
27271
|
-
if (!resolved) {
|
|
27272
|
-
return {
|
|
27273
|
-
ok: false,
|
|
27274
|
-
source: "managed",
|
|
27275
|
-
path: managedPath,
|
|
27276
|
-
message: `officecli not found. Run pnpm setup:office-runtime or set ${OFFICECLI_EXECUTABLE_ENV}.`
|
|
27277
|
-
};
|
|
27278
|
-
}
|
|
27279
|
-
return statusForPath(resolved.path, resolved.path === managedPath ? "managed" : "path", env2);
|
|
27280
|
-
}
|
|
27281
|
-
function withOfficeCliRuntimeEnv(status, env2 = process.env) {
|
|
27282
|
-
if (!status.ok || !status.path) return env2;
|
|
27283
|
-
return {
|
|
27284
|
-
...withPrependedPath(env2, [path9.dirname(status.path)]),
|
|
27285
|
-
[OFFICECLI_EXECUTABLE_ENV]: status.path
|
|
27286
|
-
};
|
|
27287
|
-
}
|
|
27288
|
-
|
|
27289
27927
|
// src/sdkEventMapper.ts
|
|
27290
27928
|
var logger10 = createModuleLogger("sdk.mapper");
|
|
27291
27929
|
var HIGH_WATERMARK_INPUT_TOKENS = 12e4;
|
|
27292
27930
|
var WARN_THRESHOLD_INPUT_TOKENS = 1e5;
|
|
27293
27931
|
var LIVE_INPUT_PREVIEW_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit"]);
|
|
27294
27932
|
var CONTEXT_OVERFLOW_LOCK_MS = 6e4;
|
|
27933
|
+
function parseJsonRecord(text) {
|
|
27934
|
+
try {
|
|
27935
|
+
const parsed = JSON.parse(text);
|
|
27936
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
27937
|
+
} catch {
|
|
27938
|
+
return null;
|
|
27939
|
+
}
|
|
27940
|
+
}
|
|
27941
|
+
function isSuccessfulOfficialMediaOutput(toolName, output) {
|
|
27942
|
+
if (!isOfficialMediaGenerationToolName(toolName)) return false;
|
|
27943
|
+
const parsed = parseJsonRecord(output);
|
|
27944
|
+
if (!parsed) return false;
|
|
27945
|
+
const state = typeof parsed.state === "string" ? parsed.state.toLowerCase() : typeof parsed.status === "string" ? parsed.status.toLowerCase() : "";
|
|
27946
|
+
if (!["succeeded", "success", "completed", "done"].includes(state)) return false;
|
|
27947
|
+
return Array.isArray(parsed.images) && parsed.images.length > 0 || typeof parsed.video_url === "string" || typeof parsed.videoUrl === "string";
|
|
27948
|
+
}
|
|
27295
27949
|
function isContextOverflowText(text) {
|
|
27296
27950
|
const trimmed = text.trim();
|
|
27297
27951
|
return /^prompt is too long\b/i.test(trimmed) || /context length .* exceed/i.test(trimmed);
|
|
@@ -27302,6 +27956,10 @@ function isAuthFailureText(text, sdkError) {
|
|
|
27302
27956
|
function isProviderApiErrorText(text) {
|
|
27303
27957
|
return /^API Error:\s*\d+/i.test(text.trim());
|
|
27304
27958
|
}
|
|
27959
|
+
function isNoReplyText(text) {
|
|
27960
|
+
const normalized = text.trim().replace(/^`+|`+$/g, "").trim().toLowerCase();
|
|
27961
|
+
return normalized === NO_REPLY_TOKEN || normalized === "<no-reply>" || normalized === "no-reply" || normalized === "no_reply" || normalized === "no reply";
|
|
27962
|
+
}
|
|
27305
27963
|
function decodeJsonStringFragment(raw) {
|
|
27306
27964
|
let out = "";
|
|
27307
27965
|
for (let i = 0; i < raw.length; i++) {
|
|
@@ -27788,7 +28446,7 @@ function emitGroupSegment(proc, emit, base, content, contentBlocks, isSilent = f
|
|
|
27788
28446
|
}
|
|
27789
28447
|
function flushTextSegmentOnBlockStop(proc, emit, base) {
|
|
27790
28448
|
const trimmed = proc.segmentBuffer.trim();
|
|
27791
|
-
const isSilent = trimmed
|
|
28449
|
+
const isSilent = isNoReplyText(trimmed);
|
|
27792
28450
|
const isEmpty = trimmed.length === 0;
|
|
27793
28451
|
if (!isEmpty) {
|
|
27794
28452
|
const blocksForSegment = [...proc.contentBlocks, { type: "text", content: proc.segmentBuffer }];
|
|
@@ -27886,8 +28544,10 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
27886
28544
|
if (block.type === "thinking") {
|
|
27887
28545
|
proc.currentBlockType = "thinking";
|
|
27888
28546
|
proc.accumulatedThinking = "";
|
|
28547
|
+
proc.suppressCurrentThinking = proc.officialMediaGenerationSatisfied === true;
|
|
27889
28548
|
} else if (block.type === "text") {
|
|
27890
28549
|
proc.currentBlockType = "text";
|
|
28550
|
+
proc.suppressCurrentThinking = false;
|
|
27891
28551
|
if (isGroupTask(proc)) {
|
|
27892
28552
|
proc.segmentBuffer = "";
|
|
27893
28553
|
}
|
|
@@ -27896,10 +28556,11 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
27896
28556
|
proc.currentToolName = block.name ?? "unknown";
|
|
27897
28557
|
proc.accumulatedToolInput = "";
|
|
27898
28558
|
const toolName = block.name ?? "unknown";
|
|
28559
|
+
proc.suppressCurrentToolUse = proc.officialMediaGenerationSatisfied === true && isOfficialMediaGenerationToolName(toolName);
|
|
27899
28560
|
const isMcpTool = parseMcpRuntimeToolName(toolName) != null;
|
|
27900
28561
|
proc.currentMcpInvocationId = isMcpTool ? createMcpToolInvocationId() : null;
|
|
27901
28562
|
proc.currentMcpInvocationStartedAt = isMcpTool ? (/* @__PURE__ */ new Date()).toISOString() : null;
|
|
27902
|
-
if (toolName !== "ExitPlanMode" && !isAskUserQuestionToolName(toolName)) {
|
|
28563
|
+
if (!isGroupTask(proc) && !proc.suppressCurrentToolUse && toolName !== "ExitPlanMode" && !isAskUserQuestionToolName(toolName)) {
|
|
27903
28564
|
emit({
|
|
27904
28565
|
type: "agent:tool_use",
|
|
27905
28566
|
payload: {
|
|
@@ -27922,17 +28583,20 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
27922
28583
|
const delta = ev.delta;
|
|
27923
28584
|
if (!delta) break;
|
|
27924
28585
|
if (delta.type === "thinking_delta" && typeof delta.thinking === "string") {
|
|
28586
|
+
if (proc.suppressCurrentThinking) break;
|
|
27925
28587
|
proc.accumulatedThinking += delta.thinking;
|
|
27926
|
-
|
|
27927
|
-
|
|
27928
|
-
|
|
27929
|
-
|
|
28588
|
+
if (!isGroupTask(proc)) {
|
|
28589
|
+
emit({
|
|
28590
|
+
type: "agent:thinking_chunk",
|
|
28591
|
+
payload: { ...wireBase(base), chunk: delta.thinking }
|
|
28592
|
+
});
|
|
28593
|
+
}
|
|
27930
28594
|
} else if (delta.type === "input_json_delta") {
|
|
27931
28595
|
const partial2 = delta.partial_json;
|
|
27932
28596
|
if (typeof partial2 === "string") {
|
|
27933
28597
|
proc.accumulatedToolInput += partial2;
|
|
27934
28598
|
const liveInput = extractLiveToolInput(proc.currentToolName, proc.accumulatedToolInput);
|
|
27935
|
-
if (liveInput && proc.currentToolName != null) {
|
|
28599
|
+
if (!isGroupTask(proc) && liveInput && proc.currentToolName != null) {
|
|
27936
28600
|
emit({
|
|
27937
28601
|
type: "agent:tool_input_update",
|
|
27938
28602
|
payload: {
|
|
@@ -27966,16 +28630,19 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
27966
28630
|
}
|
|
27967
28631
|
case "content_block_stop": {
|
|
27968
28632
|
if (proc.currentBlockType === "thinking") {
|
|
27969
|
-
|
|
27970
|
-
|
|
27971
|
-
|
|
27972
|
-
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27977
|
-
|
|
28633
|
+
if (!isGroupTask(proc) && !proc.suppressCurrentThinking) {
|
|
28634
|
+
emit({
|
|
28635
|
+
type: "agent:thinking_done",
|
|
28636
|
+
payload: wireBase(getTaskBase(proc))
|
|
28637
|
+
});
|
|
28638
|
+
proc.contentBlocks.push({
|
|
28639
|
+
type: "thinking",
|
|
28640
|
+
content: proc.accumulatedThinking,
|
|
28641
|
+
isComplete: true
|
|
28642
|
+
});
|
|
28643
|
+
}
|
|
27978
28644
|
proc.accumulatedThinking = "";
|
|
28645
|
+
proc.suppressCurrentThinking = false;
|
|
27979
28646
|
} else if (proc.currentBlockType === "text" && isGroupTask(proc)) {
|
|
27980
28647
|
flushTextSegmentOnBlockStop(proc, emit, base);
|
|
27981
28648
|
} else if (proc.currentBlockType === "tool_use") {
|
|
@@ -27992,19 +28659,21 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
27992
28659
|
});
|
|
27993
28660
|
}
|
|
27994
28661
|
}
|
|
27995
|
-
|
|
27996
|
-
|
|
27997
|
-
lastToolUse.
|
|
27998
|
-
|
|
27999
|
-
|
|
28000
|
-
|
|
28001
|
-
|
|
28002
|
-
|
|
28003
|
-
|
|
28004
|
-
|
|
28005
|
-
|
|
28006
|
-
|
|
28007
|
-
|
|
28662
|
+
if (!proc.suppressCurrentToolUse) {
|
|
28663
|
+
const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
|
|
28664
|
+
if (lastToolUse && lastToolUse.type === "tool_use") {
|
|
28665
|
+
lastToolUse.input = parsedInput;
|
|
28666
|
+
}
|
|
28667
|
+
if (!isGroupTask(proc) && proc.currentToolName != null && LIVE_INPUT_PREVIEW_TOOLS.has(proc.currentToolName) && Object.keys(parsedInput).length > 0) {
|
|
28668
|
+
emit({
|
|
28669
|
+
type: "agent:tool_input_update",
|
|
28670
|
+
payload: {
|
|
28671
|
+
...wireBase(base),
|
|
28672
|
+
toolName: proc.currentToolName,
|
|
28673
|
+
input: parsedInput
|
|
28674
|
+
}
|
|
28675
|
+
});
|
|
28676
|
+
}
|
|
28008
28677
|
}
|
|
28009
28678
|
if (proc.currentToolName === "TodoWrite") {
|
|
28010
28679
|
const todos = extractTodosFromInput(parsedInput);
|
|
@@ -28069,7 +28738,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
28069
28738
|
proc.contentBlocks.pop();
|
|
28070
28739
|
}
|
|
28071
28740
|
}
|
|
28072
|
-
if (proc.currentToolName && proc.currentMcpInvocationId && proc.currentMcpInvocationStartedAt && parseMcpRuntimeToolName(proc.currentToolName)) {
|
|
28741
|
+
if (proc.currentToolName && !proc.suppressCurrentToolUse && proc.currentMcpInvocationId && proc.currentMcpInvocationStartedAt && parseMcpRuntimeToolName(proc.currentToolName)) {
|
|
28073
28742
|
try {
|
|
28074
28743
|
proc.mcpAuditRecorder?.recordStart({
|
|
28075
28744
|
id: proc.currentMcpInvocationId,
|
|
@@ -28092,6 +28761,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
28092
28761
|
}
|
|
28093
28762
|
proc.accumulatedToolInput = "";
|
|
28094
28763
|
}
|
|
28764
|
+
proc.suppressCurrentToolUse = false;
|
|
28095
28765
|
proc.currentBlockType = null;
|
|
28096
28766
|
break;
|
|
28097
28767
|
}
|
|
@@ -28138,6 +28808,23 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
28138
28808
|
const toolName = proc.currentToolName ?? "unknown";
|
|
28139
28809
|
const isError = toolName === "ExitPlanMode" ? false : !!b.is_error;
|
|
28140
28810
|
const output = typeof b.content === "string" ? b.content : JSON.stringify(b.content);
|
|
28811
|
+
const duplicateOfficialMediaDeny = isError && isOfficialMediaGenerationToolName(toolName) && isOfficialMediaGenerationDuplicateDenyMessage(output);
|
|
28812
|
+
if (duplicateOfficialMediaDeny) {
|
|
28813
|
+
logger10.info("Suppressing duplicate official media tool denial after success", {
|
|
28814
|
+
agentId: proc.agentId,
|
|
28815
|
+
replyMessageId: base.replyMessageId,
|
|
28816
|
+
traceId: base.traceId,
|
|
28817
|
+
toolName
|
|
28818
|
+
});
|
|
28819
|
+
proc.currentMcpInvocationId = null;
|
|
28820
|
+
proc.currentMcpInvocationStartedAt = null;
|
|
28821
|
+
proc.currentToolName = null;
|
|
28822
|
+
continue;
|
|
28823
|
+
}
|
|
28824
|
+
if (isSuccessfulOfficialMediaOutput(toolName, output)) {
|
|
28825
|
+
proc.officialMediaGenerationSatisfied = true;
|
|
28826
|
+
proc.officialMediaSessionRecycleRequested = true;
|
|
28827
|
+
}
|
|
28141
28828
|
if (isAskUserQuestionToolName(toolName)) {
|
|
28142
28829
|
proc.currentToolName = null;
|
|
28143
28830
|
continue;
|
|
@@ -28166,26 +28853,28 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
28166
28853
|
proc.currentMcpInvocationId = null;
|
|
28167
28854
|
proc.currentMcpInvocationStartedAt = null;
|
|
28168
28855
|
}
|
|
28169
|
-
|
|
28170
|
-
|
|
28171
|
-
|
|
28172
|
-
|
|
28856
|
+
if (!isGroupTask(proc)) {
|
|
28857
|
+
emit({
|
|
28858
|
+
type: "agent:tool_result",
|
|
28859
|
+
payload: {
|
|
28860
|
+
...wireBase(base),
|
|
28861
|
+
toolName,
|
|
28862
|
+
output,
|
|
28863
|
+
isError
|
|
28864
|
+
}
|
|
28865
|
+
});
|
|
28866
|
+
proc.contentBlocks.push({
|
|
28867
|
+
type: "tool_result",
|
|
28173
28868
|
toolName,
|
|
28174
28869
|
output,
|
|
28175
28870
|
isError
|
|
28176
|
-
}
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28183
|
-
});
|
|
28184
|
-
const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
|
|
28185
|
-
if (lastToolUse && lastToolUse.type === "tool_use") {
|
|
28186
|
-
lastToolUse.status = isError ? "error" : "done";
|
|
28187
|
-
if (lastToolUse.toolName === "ExitPlanMode") {
|
|
28188
|
-
proc.planModeActive = false;
|
|
28871
|
+
});
|
|
28872
|
+
const lastToolUse = [...proc.contentBlocks].reverse().find((bl) => bl.type === "tool_use");
|
|
28873
|
+
if (lastToolUse && lastToolUse.type === "tool_use") {
|
|
28874
|
+
lastToolUse.status = isError ? "error" : "done";
|
|
28875
|
+
if (lastToolUse.toolName === "ExitPlanMode") {
|
|
28876
|
+
proc.planModeActive = false;
|
|
28877
|
+
}
|
|
28189
28878
|
}
|
|
28190
28879
|
}
|
|
28191
28880
|
}
|
|
@@ -28244,7 +28933,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onProv
|
|
|
28244
28933
|
const groupMode = groupId != null;
|
|
28245
28934
|
const usage = extractUsage(successMsg);
|
|
28246
28935
|
const watermarkUsage = proc.peakContextUsage ?? usage;
|
|
28247
|
-
if (trimmed
|
|
28936
|
+
if (isNoReplyText(trimmed)) {
|
|
28248
28937
|
checkInputTokenWatermark(proc, watermarkUsage, base.traceId);
|
|
28249
28938
|
emitUsageReported(proc, emit, base, usage);
|
|
28250
28939
|
if (groupMode && proc.contentBlocks.length > 0) {
|
|
@@ -28585,6 +29274,9 @@ function resetAccumulators(proc) {
|
|
|
28585
29274
|
proc.apiErrorEmitted = false;
|
|
28586
29275
|
proc.peakContextUsage = void 0;
|
|
28587
29276
|
proc.lastAssistantContentDescription = void 0;
|
|
29277
|
+
proc.officialMediaGenerationSatisfied = false;
|
|
29278
|
+
proc.suppressCurrentThinking = false;
|
|
29279
|
+
proc.suppressCurrentToolUse = false;
|
|
28588
29280
|
}
|
|
28589
29281
|
|
|
28590
29282
|
// src/forkHistoryReplay.ts
|
|
@@ -28772,11 +29464,24 @@ function missingSubscriptionMessage(subscriptionId) {
|
|
|
28772
29464
|
}
|
|
28773
29465
|
var NODE_USER_UID = 1e3;
|
|
28774
29466
|
var POST_MERGE_CONTINUATION_ROUTE_MS = 15e3;
|
|
29467
|
+
var SCOPE_PROMPT_FINGERPRINT_REVISION = "workdir-scope-prompt-v2";
|
|
28775
29468
|
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;
|
|
28776
29469
|
var DOCUMENT_READING_RULES = `DOCUMENT READING:
|
|
28777
29470
|
- The built-in Read tool cannot read binary office documents such as .docx, .xls, .xlsx, .pptx, .pdf, .odt, .ods, .odp, or .rtf.
|
|
28778
29471
|
- 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.
|
|
28779
29472
|
- Do not report that a binary document is unreadable until you have tried read_document or the extracted text path.`;
|
|
29473
|
+
var MEDIA_GENERATION_RULES = `MEDIA GENERATION:
|
|
29474
|
+
- 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.
|
|
29475
|
+
- 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.
|
|
29476
|
+
- 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.
|
|
29477
|
+
- 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.
|
|
29478
|
+
- 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.
|
|
29479
|
+
- 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.
|
|
29480
|
+
- 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.
|
|
29481
|
+
- 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.`;
|
|
29482
|
+
function isRecoveryDispatchTask(task) {
|
|
29483
|
+
return task.dispatchKind === "manual_continue" || task.dispatchKind === "regenerate";
|
|
29484
|
+
}
|
|
28780
29485
|
function isSmithAgent2(agent) {
|
|
28781
29486
|
return isSmithAgent(agent);
|
|
28782
29487
|
}
|
|
@@ -28893,6 +29598,9 @@ var AGENT_SKILL_PROFILE_TTL_MS = 6e4;
|
|
|
28893
29598
|
function isBoundarySkillIndexEntry(entry) {
|
|
28894
29599
|
return entry.permissionLevel === "high";
|
|
28895
29600
|
}
|
|
29601
|
+
var OFFICIAL_MEDIA_SKILL_STEPS_BY_ID = new Map(
|
|
29602
|
+
OFFICIAL_MEDIA_SKILLS.map((skill) => [skill.id, skill.steps])
|
|
29603
|
+
);
|
|
28896
29604
|
function buildTaskSkillContext(task, officeCliRuntime = null, runtimeSkillIndexEntries2 = [], skillProfile = null) {
|
|
28897
29605
|
const assignedSkillIds = skillProfile?.assignedIds ?? null;
|
|
28898
29606
|
const availableSkillIds = skillProfile?.availableIds ?? null;
|
|
@@ -28970,12 +29678,20 @@ function buildTaskSkillContext(task, officeCliRuntime = null, runtimeSkillIndexE
|
|
|
28970
29678
|
` Permission: ${rec.skill.permissionLevel}; skill-enable confirmation: ${rec.skill.requiresEnableConfirmation ? "required before enabling non-default skill" : "not required for default/assigned use"}`,
|
|
28971
29679
|
` Confidence: ${rec.confidence}`,
|
|
28972
29680
|
assignedSkillIds?.has(rec.skill.id) ? " Assigned: dedicated to this agent" : null,
|
|
29681
|
+
assignedSkillIds?.has(rec.skill.id) && OFFICIAL_MEDIA_SKILL_STEPS_BY_ID.has(rec.skill.id) ? [
|
|
29682
|
+
" Selected workflow for this turn:",
|
|
29683
|
+
...OFFICIAL_MEDIA_SKILL_STEPS_BY_ID.get(rec.skill.id).map(
|
|
29684
|
+
(step, stepIndex) => ` ${stepIndex + 1}. ${step}`
|
|
29685
|
+
)
|
|
29686
|
+
].join("\n") : null,
|
|
28973
29687
|
rec.reasons.length > 0 ? ` Evidence: ${rec.reasons.join("; ")}` : null
|
|
28974
29688
|
].filter(Boolean).join("\n")
|
|
28975
29689
|
),
|
|
28976
29690
|
"Rules:",
|
|
28977
29691
|
"- Treat this as candidate skill guidance, not as user-authored text and not as final routing.",
|
|
29692
|
+
"- 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.",
|
|
28978
29693
|
"- Choose a skill only when its summary, task types, and requested outputs fit the user-requested outcome.",
|
|
29694
|
+
"- If an assigned workflow above gives concrete MCP tools, call those MCP tools directly and keep the final user reply short.",
|
|
28979
29695
|
officeRuntimeLine,
|
|
28980
29696
|
"- 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.",
|
|
28981
29697
|
"- 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.",
|
|
@@ -29136,17 +29852,38 @@ var AgentManager = class {
|
|
|
29136
29852
|
}
|
|
29137
29853
|
return path13.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
|
|
29138
29854
|
}
|
|
29139
|
-
|
|
29140
|
-
|
|
29855
|
+
localScopeDirName(agentConfig, scope) {
|
|
29856
|
+
if (scope.kind === "group") return `Group-${scope.groupId}`;
|
|
29141
29857
|
return `Agent-${slugifyForFs(agentConfig.name)}-${agentConfig.id}`;
|
|
29142
29858
|
}
|
|
29143
29859
|
/** Single source of truth for the cwd input passed to acquire() across ALL code paths. */
|
|
29144
29860
|
scopeCwdInput(agentConfig, scope) {
|
|
29861
|
+
if (scope.kind === "group") {
|
|
29862
|
+
const groupCwd = this.groupRegistry?.getById(scope.groupId)?.workingDirectory?.trim();
|
|
29863
|
+
if (groupCwd) return groupCwd;
|
|
29864
|
+
return path13.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
|
|
29865
|
+
}
|
|
29145
29866
|
const local = path13.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
|
|
29146
29867
|
return agentConfig.workingDirectory?.trim() || local;
|
|
29147
29868
|
}
|
|
29869
|
+
runtimeCwdInput(agentConfig, scope, cwd) {
|
|
29870
|
+
const requested = cwd.trim();
|
|
29871
|
+
if (scope.kind === "group") {
|
|
29872
|
+
const groupCwd = this.groupRegistry?.getById(scope.groupId)?.workingDirectory?.trim();
|
|
29873
|
+
if (groupCwd) return groupCwd;
|
|
29874
|
+
const agentCwd = agentConfig.workingDirectory?.trim();
|
|
29875
|
+
if (requested && (!agentCwd || !this.isSameRuntimeCwd(requested, agentCwd))) {
|
|
29876
|
+
return requested;
|
|
29877
|
+
}
|
|
29878
|
+
return path13.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
|
|
29879
|
+
}
|
|
29880
|
+
return agentConfig.workingDirectory?.trim() || requested || this.scopeCwdInput(agentConfig, scope);
|
|
29881
|
+
}
|
|
29882
|
+
workdirOverrideTarget(agentConfig, scope) {
|
|
29883
|
+
return scope.kind === "group" ? { targetKind: "group", targetId: scope.groupId } : { targetKind: "agent", targetId: agentConfig.id };
|
|
29884
|
+
}
|
|
29148
29885
|
remapServerWorkspaceCwd(agentConfig, scope, requestedCwd) {
|
|
29149
|
-
const overrideTarget =
|
|
29886
|
+
const overrideTarget = this.workdirOverrideTarget(agentConfig, scope);
|
|
29150
29887
|
const overridden = this.workdirOverrideStore?.resolvePath(requestedCwd, overrideTarget);
|
|
29151
29888
|
if (overridden?.overridden) {
|
|
29152
29889
|
logger13.info("Local workdir override applied to runtime cwd", {
|
|
@@ -29346,7 +30083,7 @@ var AgentManager = class {
|
|
|
29346
30083
|
modelInputModeForConfig(agentId, scope, cfg) {
|
|
29347
30084
|
const key = runtimeKey(agentId, scope);
|
|
29348
30085
|
if (this.visionBlockedScopes.has(key)) return "path-only";
|
|
29349
|
-
return cfg.supportsVision ===
|
|
30086
|
+
return cfg.supportsVision === true ? "vision" : "path-only";
|
|
29350
30087
|
}
|
|
29351
30088
|
isSameRuntimeCwd(a, b) {
|
|
29352
30089
|
const left = path13.normalize(a);
|
|
@@ -29425,6 +30162,40 @@ var AgentManager = class {
|
|
|
29425
30162
|
});
|
|
29426
30163
|
return null;
|
|
29427
30164
|
}
|
|
30165
|
+
scopePromptFingerprint(agentConfig, scope, agentCwd, scopesSection) {
|
|
30166
|
+
return 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(path13.normalize(agentCwd)).update("\0").update(scopesSection).digest("hex");
|
|
30167
|
+
}
|
|
30168
|
+
discardSessionIfScopePromptChanged(agentConfig, scope, sessionId, fingerprint) {
|
|
30169
|
+
const previous = this.sessionStore.getPromptFingerprint(agentConfig.id, scope);
|
|
30170
|
+
if (!sessionId) {
|
|
30171
|
+
this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
|
|
30172
|
+
return null;
|
|
30173
|
+
}
|
|
30174
|
+
if (previous === fingerprint) return sessionId;
|
|
30175
|
+
if (!previous && scope.kind === "single") {
|
|
30176
|
+
this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
|
|
30177
|
+
logger13.info("Retaining legacy single-scope session while recording prompt fingerprint", {
|
|
30178
|
+
agentId: agentConfig.id,
|
|
30179
|
+
scope: scopeKey(scope),
|
|
30180
|
+
sessionId,
|
|
30181
|
+
nextFingerprint: fingerprint,
|
|
30182
|
+
revision: SCOPE_PROMPT_FINGERPRINT_REVISION
|
|
30183
|
+
});
|
|
30184
|
+
return sessionId;
|
|
30185
|
+
}
|
|
30186
|
+
this.sessionStore.delete(agentConfig.id, scope);
|
|
30187
|
+
this.dispatchMemory.deleteScope(agentConfig.id, scope);
|
|
30188
|
+
this.sessionStore.setPromptFingerprint(agentConfig.id, scope, fingerprint);
|
|
30189
|
+
logger13.info("Cleared scoped session because scope prompt fingerprint changed", {
|
|
30190
|
+
agentId: agentConfig.id,
|
|
30191
|
+
scope: scopeKey(scope),
|
|
30192
|
+
sessionId,
|
|
30193
|
+
previousFingerprint: previous,
|
|
30194
|
+
nextFingerprint: fingerprint,
|
|
30195
|
+
revision: SCOPE_PROMPT_FINGERPRINT_REVISION
|
|
30196
|
+
});
|
|
30197
|
+
return null;
|
|
30198
|
+
}
|
|
29428
30199
|
async awaitQueryReturn(query4, timeoutMs, agentId) {
|
|
29429
30200
|
const ret = query4.return(void 0);
|
|
29430
30201
|
try {
|
|
@@ -29480,6 +30251,47 @@ var AgentManager = class {
|
|
|
29480
30251
|
this.agents.delete(key);
|
|
29481
30252
|
this.lastUsedAt.delete(key);
|
|
29482
30253
|
}
|
|
30254
|
+
/**
|
|
30255
|
+
* Runtime config reloads need a fresh SDK process, but the next turn should
|
|
30256
|
+
* resume the same Claude session so short follow-ups like "重新生成" keep context.
|
|
30257
|
+
*/
|
|
30258
|
+
async closeRuntimeForRuntimeReload(proc, reason) {
|
|
30259
|
+
if (proc.status === "dead") return;
|
|
30260
|
+
const runtime = this.asRuntime(proc);
|
|
30261
|
+
const key = runtimeKey(proc.agentId, proc.scope);
|
|
30262
|
+
this.clearQuietFlushTimer(runtime);
|
|
30263
|
+
runtime.currentTask = null;
|
|
30264
|
+
runtime.injectedTasks = [];
|
|
30265
|
+
runtime.mergedTasks = [];
|
|
30266
|
+
runtime.planModeBuffer = [];
|
|
30267
|
+
runtime.groupInbox = [];
|
|
30268
|
+
try {
|
|
30269
|
+
runtime.inputController.close();
|
|
30270
|
+
await this.awaitQueryReturn(runtime.query, 5e3, proc.agentId);
|
|
30271
|
+
} catch (e) {
|
|
30272
|
+
logger13.error("runtime reload close failed", {
|
|
30273
|
+
agentId: proc.agentId,
|
|
30274
|
+
scope: scopeKey(proc.scope),
|
|
30275
|
+
reason,
|
|
30276
|
+
error: e
|
|
30277
|
+
});
|
|
30278
|
+
}
|
|
30279
|
+
proc.pendingTerminate = false;
|
|
30280
|
+
proc.pendingTerminatePreserveSession = false;
|
|
30281
|
+
proc.pendingTerminateReason = void 0;
|
|
30282
|
+
proc.status = "dead";
|
|
30283
|
+
this.agents.delete(key);
|
|
30284
|
+
this.lastUsedAt.delete(key);
|
|
30285
|
+
this.dormantScopes.delete(key);
|
|
30286
|
+
this.dormantGroupInboxes.delete(key);
|
|
30287
|
+
this.dispatchMemory.deleteScope(proc.agentId, proc.scope);
|
|
30288
|
+
logger13.info("runtime reload: scoped query removed, session preserved", {
|
|
30289
|
+
agentId: proc.agentId,
|
|
30290
|
+
scope: scopeKey(proc.scope),
|
|
30291
|
+
reason,
|
|
30292
|
+
sessionId: runtime.ccSessionId
|
|
30293
|
+
});
|
|
30294
|
+
}
|
|
29483
30295
|
/** Evict LRU among idle (ready/starting + no injected tasks) agents past the idle timeout. */
|
|
29484
30296
|
evictIdle() {
|
|
29485
30297
|
const now = Date.now();
|
|
@@ -29556,13 +30368,15 @@ var AgentManager = class {
|
|
|
29556
30368
|
throw new Error(`Refusing to spawn SDK runtime for human agent ${agentConfig.id}`);
|
|
29557
30369
|
}
|
|
29558
30370
|
const key = runtimeKey(agentConfig.id, scope);
|
|
29559
|
-
const cwdInput =
|
|
30371
|
+
const cwdInput = this.runtimeCwdInput(agentConfig, scope, cwd);
|
|
29560
30372
|
const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwdInput);
|
|
29561
30373
|
const existing = this.agents.get(key);
|
|
29562
30374
|
if (existing && existing.status !== "dead") {
|
|
29563
30375
|
if (!this.isSameRuntimeCwd(existing.cwd, agentCwd) || existing.pendingTerminate) {
|
|
29564
30376
|
if (existing.status === "working" && existing.currentTask) {
|
|
29565
30377
|
existing.pendingTerminate = true;
|
|
30378
|
+
existing.pendingTerminatePreserveSession = false;
|
|
30379
|
+
existing.pendingTerminateReason = "cwd_changed";
|
|
29566
30380
|
logger13.info("Runtime cwd changed while working; reload deferred until turn completes", {
|
|
29567
30381
|
agentId: agentConfig.id,
|
|
29568
30382
|
scope: scopeKey(scope),
|
|
@@ -29580,7 +30394,14 @@ var AgentManager = class {
|
|
|
29580
30394
|
nextCwd: agentCwd,
|
|
29581
30395
|
pendingTerminate: existing.pendingTerminate ?? false
|
|
29582
30396
|
});
|
|
29583
|
-
|
|
30397
|
+
if (existing.pendingTerminatePreserveSession === true && this.isSameRuntimeCwd(existing.cwd, agentCwd)) {
|
|
30398
|
+
await this.closeRuntimeForRuntimeReload(
|
|
30399
|
+
existing,
|
|
30400
|
+
existing.pendingTerminateReason ?? "pending_runtime_reload"
|
|
30401
|
+
);
|
|
30402
|
+
} else {
|
|
30403
|
+
await this.terminateScope(agentConfig.id, scope);
|
|
30404
|
+
}
|
|
29584
30405
|
} else {
|
|
29585
30406
|
this.lastUsedAt.set(key, Date.now());
|
|
29586
30407
|
return existing;
|
|
@@ -29597,7 +30418,7 @@ var AgentManager = class {
|
|
|
29597
30418
|
throw new BridgeBusyError();
|
|
29598
30419
|
}
|
|
29599
30420
|
}
|
|
29600
|
-
const proc = await this.getOrCreate(agentConfig, scope,
|
|
30421
|
+
const proc = await this.getOrCreate(agentConfig, scope, cwdInput);
|
|
29601
30422
|
this.lastUsedAt.set(key, Date.now());
|
|
29602
30423
|
return proc;
|
|
29603
30424
|
}
|
|
@@ -29608,13 +30429,16 @@ var AgentManager = class {
|
|
|
29608
30429
|
return existing;
|
|
29609
30430
|
}
|
|
29610
30431
|
const inputController = new InputController();
|
|
29611
|
-
const cwdInput =
|
|
30432
|
+
const cwdInput = this.runtimeCwdInput(agentConfig, scope, cwd);
|
|
29612
30433
|
const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwdInput);
|
|
29613
30434
|
const cfg = await this.resolveAgentConfig(agentConfig);
|
|
29614
|
-
|
|
30435
|
+
const scopedInstructions = cfg.instructions?.trim() && scope.kind === "group" ? `# Agent project instructions
|
|
30436
|
+
${cfg.instructions.trim()}` : "";
|
|
30437
|
+
if (cfg.instructions?.trim() && scope.kind === "single") {
|
|
29615
30438
|
await fs6.writeFile(path13.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
|
|
29616
30439
|
logger13.info("CLAUDE.md written", {
|
|
29617
30440
|
agentId: agentConfig.id,
|
|
30441
|
+
scope: scopeKey(scope),
|
|
29618
30442
|
bytes: cfg.instructions.trim().length
|
|
29619
30443
|
});
|
|
29620
30444
|
}
|
|
@@ -29625,7 +30449,10 @@ var AgentManager = class {
|
|
|
29625
30449
|
try {
|
|
29626
30450
|
await fs6.access(effectiveConfigDir);
|
|
29627
30451
|
} catch (e) {
|
|
29628
|
-
logger13.debug("Agent API key config dir missing; creating isolated dir", {
|
|
30452
|
+
logger13.debug("Agent API key config dir missing; creating isolated dir", {
|
|
30453
|
+
error: e,
|
|
30454
|
+
agentId: agentConfig.id
|
|
30455
|
+
});
|
|
29629
30456
|
isNew = true;
|
|
29630
30457
|
}
|
|
29631
30458
|
await fs6.mkdir(effectiveConfigDir, { recursive: true });
|
|
@@ -29667,17 +30494,17 @@ var AgentManager = class {
|
|
|
29667
30494
|
});
|
|
29668
30495
|
}
|
|
29669
30496
|
let savedSessionId = this.sessionStore.get(agentConfig.id, scope);
|
|
29670
|
-
const
|
|
29671
|
-
|
|
29672
|
-
|
|
29673
|
-
|
|
30497
|
+
const runtimeOverride = cwdInput ? this.workdirOverrideStore?.resolvePath(
|
|
30498
|
+
cwdInput,
|
|
30499
|
+
this.workdirOverrideTarget(agentConfig, scope)
|
|
30500
|
+
) : null;
|
|
29674
30501
|
savedSessionId = this.discardSessionIfItBelongsToAnotherCwd(
|
|
29675
30502
|
agentConfig,
|
|
29676
30503
|
scope,
|
|
29677
30504
|
agentCwd,
|
|
29678
30505
|
effectiveConfigDir,
|
|
29679
30506
|
savedSessionId,
|
|
29680
|
-
|
|
30507
|
+
runtimeOverride?.overridden === true
|
|
29681
30508
|
);
|
|
29682
30509
|
const queryFn = await this.getQueryFn();
|
|
29683
30510
|
let procRef = null;
|
|
@@ -29743,11 +30570,28 @@ var AgentManager = class {
|
|
|
29743
30570
|
},
|
|
29744
30571
|
onLeaveGroup: (groupId) => this.deferLeaveGroup(agentConfig.id, groupId)
|
|
29745
30572
|
});
|
|
30573
|
+
if (this.mcpRegistry) {
|
|
30574
|
+
try {
|
|
30575
|
+
await this.mcpRegistry.refresh();
|
|
30576
|
+
} catch (e) {
|
|
30577
|
+
logger13.warn("MCP registry refresh before runtime failed; using cached MCP config", {
|
|
30578
|
+
error: e,
|
|
30579
|
+
agentId: agentConfig.id,
|
|
30580
|
+
scope: scopeKey(scope)
|
|
30581
|
+
});
|
|
30582
|
+
}
|
|
30583
|
+
}
|
|
29746
30584
|
const externalMcp = this.mcpRegistry?.buildForAgent({
|
|
29747
30585
|
agentId: agentConfig.id,
|
|
29748
30586
|
capabilityTier: cfg.capabilityTier,
|
|
29749
30587
|
isSmith: smithAgent
|
|
29750
30588
|
}) ?? { mcpServers: {}, allowedTools: [] };
|
|
30589
|
+
logger13.info("External MCP resolved for runtime", {
|
|
30590
|
+
agentId: agentConfig.id,
|
|
30591
|
+
scope: scopeKey(scope),
|
|
30592
|
+
serverNames: Object.keys(externalMcp.mcpServers),
|
|
30593
|
+
allowedToolCount: externalMcp.allowedTools.length
|
|
30594
|
+
});
|
|
29751
30595
|
if (this.memoryStore) {
|
|
29752
30596
|
logger13.info("Notebook pull on runtime start", {
|
|
29753
30597
|
agentId: agentConfig.id,
|
|
@@ -29757,7 +30601,13 @@ var AgentManager = class {
|
|
|
29757
30601
|
await this.memoryStore.pullFromServer(agentConfig.id);
|
|
29758
30602
|
}
|
|
29759
30603
|
const notebookSection = this.buildNotebookSection(agentConfig.id);
|
|
29760
|
-
const scopesSection = this.buildScopesSection(agentConfig
|
|
30604
|
+
const scopesSection = this.buildScopesSection(agentConfig, scope, agentCwd);
|
|
30605
|
+
savedSessionId = this.discardSessionIfScopePromptChanged(
|
|
30606
|
+
agentConfig,
|
|
30607
|
+
scope,
|
|
30608
|
+
savedSessionId,
|
|
30609
|
+
this.scopePromptFingerprint(agentConfig, scope, agentCwd, scopesSection)
|
|
30610
|
+
);
|
|
29761
30611
|
let forkHistorySection = "";
|
|
29762
30612
|
if (!savedSessionId && scope.kind === "single") {
|
|
29763
30613
|
const forkMeta = await consumeForkMeta(this.dataDir, agentConfig.id);
|
|
@@ -29795,6 +30645,7 @@ var AgentManager = class {
|
|
|
29795
30645
|
cronLockOwnedByMe: cronLockSnapshot.sessionId != null && cronLockSnapshot.sessionId === savedSessionId
|
|
29796
30646
|
});
|
|
29797
30647
|
const planModeRef = { active: false, denyCount: 0 };
|
|
30648
|
+
const mediaGenerationTurnGuard = createOfficialMediaGenerationTurnGuard();
|
|
29798
30649
|
const builtinWebSearchAllowed = this.queryConfig.allowBuiltinWebSearch;
|
|
29799
30650
|
const options = {
|
|
29800
30651
|
cwd: agentCwd,
|
|
@@ -29804,7 +30655,9 @@ var AgentManager = class {
|
|
|
29804
30655
|
append: [
|
|
29805
30656
|
PLATFORM_AGENT_RULES,
|
|
29806
30657
|
DOCUMENT_READING_RULES,
|
|
30658
|
+
MEDIA_GENERATION_RULES,
|
|
29807
30659
|
agentConfig.systemPrompt,
|
|
30660
|
+
scopedInstructions,
|
|
29808
30661
|
notebookSection,
|
|
29809
30662
|
forkHistorySection,
|
|
29810
30663
|
scopesSection
|
|
@@ -29812,8 +30665,9 @@ var AgentManager = class {
|
|
|
29812
30665
|
},
|
|
29813
30666
|
permissionMode: "bypassPermissions",
|
|
29814
30667
|
allowDangerouslySkipPermissions: true,
|
|
29815
|
-
// allowedTools
|
|
29816
|
-
//
|
|
30668
|
+
// allowedTools is the visibility whitelist passed to Claude Code. MCP tools
|
|
30669
|
+
// with always_ask must still be included here so the model can request them;
|
|
30670
|
+
// the MCP server policy/permission layer decides whether execution asks.
|
|
29817
30671
|
allowedTools: [
|
|
29818
30672
|
"Read",
|
|
29819
30673
|
"Edit",
|
|
@@ -30084,6 +30938,15 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
|
|
|
30084
30938
|
},
|
|
30085
30939
|
hooks: {
|
|
30086
30940
|
PreToolUse: [
|
|
30941
|
+
...createOfficialMediaGenerationPreToolUseHooks(
|
|
30942
|
+
mediaGenerationTurnGuard,
|
|
30943
|
+
externalMcp.allowedTools,
|
|
30944
|
+
{
|
|
30945
|
+
agentId: agentConfig.id,
|
|
30946
|
+
scope: scopeKey(scope),
|
|
30947
|
+
log: (msg, meta3) => logger13.warn(msg, meta3)
|
|
30948
|
+
}
|
|
30949
|
+
),
|
|
30087
30950
|
{
|
|
30088
30951
|
matcher: "ExitPlanMode",
|
|
30089
30952
|
hooks: [
|
|
@@ -30192,6 +31055,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
|
|
|
30192
31055
|
segmentCount: 0,
|
|
30193
31056
|
accumulatedToolInput: "",
|
|
30194
31057
|
planModeRef,
|
|
31058
|
+
mediaGenerationTurnGuard,
|
|
30195
31059
|
groupInbox: []
|
|
30196
31060
|
};
|
|
30197
31061
|
const runtime = Object.assign(proc, {
|
|
@@ -30309,7 +31173,15 @@ ${trimmed}`;
|
|
|
30309
31173
|
});
|
|
30310
31174
|
return section;
|
|
30311
31175
|
}
|
|
30312
|
-
|
|
31176
|
+
promptWorkdir(agentConfig, scope, requestedCwd) {
|
|
31177
|
+
const remapped = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
|
|
31178
|
+
if (!isFullyQualifiedAbsolutePath(remapped)) {
|
|
31179
|
+
return path13.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
|
|
31180
|
+
}
|
|
31181
|
+
return remapped;
|
|
31182
|
+
}
|
|
31183
|
+
buildScopesSection(agentConfig, scope, currentCwd) {
|
|
31184
|
+
const agentId = agentConfig.id;
|
|
30313
31185
|
if (!this.groupRegistry) {
|
|
30314
31186
|
logger13.info("Scopes injection skipped", { agentId, reason: "no_group_registry" });
|
|
30315
31187
|
return "";
|
|
@@ -30318,15 +31190,32 @@ ${trimmed}`;
|
|
|
30318
31190
|
const curKey = scopeKey(scope);
|
|
30319
31191
|
const lines = [];
|
|
30320
31192
|
const isCurSingle = curKey === "single";
|
|
31193
|
+
const singleScope = { kind: "single" };
|
|
31194
|
+
const singleWorkdir = isCurSingle ? currentCwd : this.promptWorkdir(agentConfig, singleScope, this.scopeCwdInput(agentConfig, singleScope));
|
|
31195
|
+
lines.push("Workdir semantics:");
|
|
31196
|
+
lines.push("- single workdir = your private Agent workspace for 1:1 chat.");
|
|
31197
|
+
lines.push(
|
|
31198
|
+
"- group workdir = that group's shared workspace; it is your runtime cwd while you are in that group."
|
|
31199
|
+
);
|
|
31200
|
+
lines.push(
|
|
31201
|
+
'- If asked for "your own workdir" vs "this group workdir", report the separate paths shown below.'
|
|
31202
|
+
);
|
|
31203
|
+
lines.push("");
|
|
30321
31204
|
lines.push(`- single \u2014 1:1 chat with the user${isCurSingle ? " (you are here)" : ""}`);
|
|
30322
|
-
lines.push(` workdir: ${
|
|
31205
|
+
lines.push(` workdir: ${singleWorkdir}`);
|
|
30323
31206
|
let rosterCount = 0;
|
|
30324
31207
|
for (const g of myGroups) {
|
|
30325
31208
|
const key = `group:${g.groupId}`;
|
|
30326
31209
|
const here = key === curKey ? " (you are here)" : "";
|
|
30327
31210
|
const userMark = g.userJoined ? " [user joined]" : " [no user]";
|
|
30328
31211
|
lines.push(`- ${key} \u2014 ${g.name}${here}${userMark}`);
|
|
30329
|
-
|
|
31212
|
+
const groupScope = { kind: "group", groupId: g.groupId };
|
|
31213
|
+
const groupWorkdir = key === curKey ? currentCwd : this.promptWorkdir(
|
|
31214
|
+
agentConfig,
|
|
31215
|
+
groupScope,
|
|
31216
|
+
g.workingDirectory?.trim() || this.scopeCwdInput(agentConfig, groupScope)
|
|
31217
|
+
);
|
|
31218
|
+
lines.push(` workdir: ${groupWorkdir}`);
|
|
30330
31219
|
const others = g.members.filter((id) => id !== agentId).map((id) => {
|
|
30331
31220
|
const a = this.agentRegistry?.getById(id);
|
|
30332
31221
|
return a ? `${a.name} (${id}, role: ${a.role})` : `Agent(${id})`;
|
|
@@ -30409,6 +31298,28 @@ ${lines.join("\n")}`;
|
|
|
30409
31298
|
await this.dispatchToSDK(runtime, task);
|
|
30410
31299
|
return;
|
|
30411
31300
|
}
|
|
31301
|
+
if (isRecoveryDispatchTask(task)) {
|
|
31302
|
+
logger13.warn("Recovery dispatch rejected while Agent is already working", {
|
|
31303
|
+
agentId: task.agentId,
|
|
31304
|
+
scope: scopeKey(task.scope),
|
|
31305
|
+
replyMessageId: task.replyMessageId,
|
|
31306
|
+
conversationId: task.conversationId,
|
|
31307
|
+
currentTaskReplyMessageId: runtime.currentTask?.replyMessageId,
|
|
31308
|
+
dispatchKind: task.dispatchKind,
|
|
31309
|
+
traceId: task.traceId
|
|
31310
|
+
});
|
|
31311
|
+
this.emit({
|
|
31312
|
+
type: "agent:error",
|
|
31313
|
+
payload: {
|
|
31314
|
+
agentId: task.agentId,
|
|
31315
|
+
conversationId: task.conversationId,
|
|
31316
|
+
ackId: task.replyMessageId,
|
|
31317
|
+
traceId: task.traceId,
|
|
31318
|
+
error: "Bridge is already working on another reply; recovery dispatch was rejected."
|
|
31319
|
+
}
|
|
31320
|
+
});
|
|
31321
|
+
return;
|
|
31322
|
+
}
|
|
30412
31323
|
if (proc.planModeActive) {
|
|
30413
31324
|
runtime.planModeBuffer.push(task);
|
|
30414
31325
|
logger13.info("Message buffered during plan mode", {
|
|
@@ -30758,6 +31669,7 @@ ${lines.join("\n")}`;
|
|
|
30758
31669
|
runtime.status = "working";
|
|
30759
31670
|
runtime.currentTask = task;
|
|
30760
31671
|
runtime.currentTaskStartedAt = Date.now();
|
|
31672
|
+
resetOfficialMediaGenerationTurnGuard(runtime.mediaGenerationTurnGuard, task.replyMessageId);
|
|
30761
31673
|
runtime.cachedConversationId = task.conversationId;
|
|
30762
31674
|
logger13.info("Agent run started", {
|
|
30763
31675
|
agentId: runtime.agentId,
|
|
@@ -30905,9 +31817,9 @@ ${lines.join("\n")}`;
|
|
|
30905
31817
|
throw new Error(`HTTP ${res.status}`);
|
|
30906
31818
|
}
|
|
30907
31819
|
const body = await res.json();
|
|
30908
|
-
const
|
|
31820
|
+
const runtimeCachedSkillIds2 = this.getRuntimeCachedSkillIds();
|
|
30909
31821
|
const serverAssignedIds = (body.assigned ?? []).map((s) => s.id);
|
|
30910
|
-
const cachedServerAssignedIds = serverAssignedIds.filter((id) =>
|
|
31822
|
+
const cachedServerAssignedIds = serverAssignedIds.filter((id) => runtimeCachedSkillIds2.has(id));
|
|
30911
31823
|
const localRuntimeSkillIds = this.getLocalRuntimeSkillIdsForAgent(agentId);
|
|
30912
31824
|
const assignedIds = /* @__PURE__ */ new Set([...serverAssignedIds, ...localRuntimeSkillIds]);
|
|
30913
31825
|
const availableIds = /* @__PURE__ */ new Set([...cachedServerAssignedIds, ...localRuntimeSkillIds]);
|
|
@@ -31252,7 +32164,7 @@ ${lines.join("\n")}`;
|
|
|
31252
32164
|
}
|
|
31253
32165
|
});
|
|
31254
32166
|
}
|
|
31255
|
-
const continuationTask = mergedBatch.at(-1);
|
|
32167
|
+
const continuationTask = mergedBatch.filter((task) => !isRecoveryDispatchTask(task)).at(-1);
|
|
31256
32168
|
if (continuationTask) {
|
|
31257
32169
|
proc.postMergeContinuationTask = continuationTask;
|
|
31258
32170
|
proc.postMergeContinuationUntil = Date.now() + POST_MERGE_CONTINUATION_ROUTE_MS;
|
|
@@ -31264,6 +32176,16 @@ ${lines.join("\n")}`;
|
|
|
31264
32176
|
routeUntil: new Date(proc.postMergeContinuationUntil).toISOString(),
|
|
31265
32177
|
traceId: completedTask.traceId
|
|
31266
32178
|
});
|
|
32179
|
+
} else {
|
|
32180
|
+
delete proc.postMergeContinuationTask;
|
|
32181
|
+
delete proc.postMergeContinuationUntil;
|
|
32182
|
+
logger13.info("Skipped post-merge continuation routing for recovery-only merged tasks", {
|
|
32183
|
+
agentId: proc.agentId,
|
|
32184
|
+
carrierReplyMessageId: completedTask.replyMessageId,
|
|
32185
|
+
mergedCount: mergedBatch.length,
|
|
32186
|
+
mergedReplyMessageIds: mergedBatch.map((task) => task.replyMessageId),
|
|
32187
|
+
traceId: completedTask.traceId
|
|
32188
|
+
});
|
|
31267
32189
|
}
|
|
31268
32190
|
runtime.mergedTasks = [];
|
|
31269
32191
|
} else if (runtime.mergedTasks.length > 0) {
|
|
@@ -31273,6 +32195,37 @@ ${lines.join("\n")}`;
|
|
|
31273
32195
|
});
|
|
31274
32196
|
runtime.mergedTasks = [];
|
|
31275
32197
|
}
|
|
32198
|
+
if (proc.officialMediaSessionRecycleRequested) {
|
|
32199
|
+
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;
|
|
32200
|
+
if (!hasPendingWork) {
|
|
32201
|
+
proc.officialMediaSessionRecycleRequested = false;
|
|
32202
|
+
this.sessionStore.delete(proc.agentId, proc.scope);
|
|
32203
|
+
this.dispatchMemory.deleteScope(proc.agentId, proc.scope);
|
|
32204
|
+
logger13.info("Recycling SDK session after successful official media generation", {
|
|
32205
|
+
agentId: proc.agentId,
|
|
32206
|
+
scope: scopeKey(proc.scope),
|
|
32207
|
+
sessionId: proc.ccSessionId,
|
|
32208
|
+
completedAckId: completedTask?.replyMessageId,
|
|
32209
|
+
traceId: completedTask?.traceId
|
|
32210
|
+
});
|
|
32211
|
+
void this.closeRuntime(proc, "official_media_session_recycle");
|
|
32212
|
+
return;
|
|
32213
|
+
}
|
|
32214
|
+
logger13.info("Official media session recycle deferred because pending work remains", {
|
|
32215
|
+
agentId: proc.agentId,
|
|
32216
|
+
scope: scopeKey(proc.scope),
|
|
32217
|
+
sessionId: proc.ccSessionId,
|
|
32218
|
+
injectedTasks: runtime.injectedTasks.length,
|
|
32219
|
+
planModeBuffer: runtime.planModeBuffer.length,
|
|
32220
|
+
groupInbox: runtime.groupInbox.length,
|
|
32221
|
+
hasPostMergeContinuation: proc.postMergeContinuationTask != null,
|
|
32222
|
+
pendingTerminate: proc.pendingTerminate === true,
|
|
32223
|
+
compactRequested: proc.compactRequested === true,
|
|
32224
|
+
pendingLeaveGroup: proc.pendingLeaveGroupId != null,
|
|
32225
|
+
completedAckId: completedTask?.replyMessageId,
|
|
32226
|
+
traceId: completedTask?.traceId
|
|
32227
|
+
});
|
|
32228
|
+
}
|
|
31276
32229
|
if (proc.pendingTerminate) {
|
|
31277
32230
|
this.checkPendingTerminate(proc);
|
|
31278
32231
|
return;
|
|
@@ -31357,6 +32310,7 @@ ${lines.join("\n")}`;
|
|
|
31357
32310
|
proc.currentTask = next;
|
|
31358
32311
|
proc.status = "working";
|
|
31359
32312
|
proc.currentTaskStartedAt = Date.now();
|
|
32313
|
+
resetOfficialMediaGenerationTurnGuard(runtime.mediaGenerationTurnGuard, next.replyMessageId);
|
|
31360
32314
|
logger13.info("Promoted next injected task after result", {
|
|
31361
32315
|
agentId: proc.agentId,
|
|
31362
32316
|
replyMessageId: next.replyMessageId,
|
|
@@ -31536,7 +32490,7 @@ ${lines.join("\n")}`;
|
|
|
31536
32490
|
userInScope: group?.userJoined === true
|
|
31537
32491
|
};
|
|
31538
32492
|
}
|
|
31539
|
-
deliverNeuralSend(agentConfig, payload) {
|
|
32493
|
+
async deliverNeuralSend(agentConfig, payload) {
|
|
31540
32494
|
if (agentConfig.kind === "human") {
|
|
31541
32495
|
logger13.warn("Neural send rejected: target is human principal", {
|
|
31542
32496
|
agentId: agentConfig.id,
|
|
@@ -31575,8 +32529,31 @@ ${lines.join("\n")}`;
|
|
|
31575
32529
|
traceId: createTraceId(),
|
|
31576
32530
|
groupId: payload.groupId
|
|
31577
32531
|
};
|
|
32532
|
+
const cwd = payload.targetCwd?.trim() || this.scopeCwdInput(agentConfig, targetScope);
|
|
32533
|
+
const resolvedCwd = await this.resolveRuntimeCwd(agentConfig, targetScope, cwd);
|
|
31578
32534
|
const key = runtimeKey(agentConfig.id, targetScope);
|
|
31579
|
-
|
|
32535
|
+
let existingProc = this.agents.get(key);
|
|
32536
|
+
if (existingProc && existingProc.status !== "dead" && !this.isSameRuntimeCwd(existingProc.cwd, resolvedCwd)) {
|
|
32537
|
+
if (existingProc.status === "working" && existingProc.currentTask) {
|
|
32538
|
+
existingProc.pendingTerminate = true;
|
|
32539
|
+
logger13.info("Neural send target runtime cwd changed while working; reload deferred", {
|
|
32540
|
+
agentId: agentConfig.id,
|
|
32541
|
+
toScope: payload.toScopeKey,
|
|
32542
|
+
currentCwd: existingProc.cwd,
|
|
32543
|
+
nextCwd: resolvedCwd,
|
|
32544
|
+
replyMessageId: existingProc.currentTask.replyMessageId
|
|
32545
|
+
});
|
|
32546
|
+
} else {
|
|
32547
|
+
logger13.info("Neural send target runtime cwd changed while idle; rebuilding", {
|
|
32548
|
+
agentId: agentConfig.id,
|
|
32549
|
+
toScope: payload.toScopeKey,
|
|
32550
|
+
currentCwd: existingProc.cwd,
|
|
32551
|
+
nextCwd: resolvedCwd
|
|
32552
|
+
});
|
|
32553
|
+
await this.terminateScope(agentConfig.id, targetScope);
|
|
32554
|
+
existingProc = void 0;
|
|
32555
|
+
}
|
|
32556
|
+
}
|
|
31580
32557
|
logger13.info("Neural send dispatching", {
|
|
31581
32558
|
agentId: agentConfig.id,
|
|
31582
32559
|
fromScope: payload.fromScopeKey,
|
|
@@ -31587,6 +32564,7 @@ ${lines.join("\n")}`;
|
|
|
31587
32564
|
messageLen: payload.message.length,
|
|
31588
32565
|
conversationId: payload.conversationId ?? "(none)",
|
|
31589
32566
|
groupId: payload.groupId ?? "(none)",
|
|
32567
|
+
cwd: resolvedCwd,
|
|
31590
32568
|
replyMessageId: task.replyMessageId,
|
|
31591
32569
|
peerCount: ctx.peers.length,
|
|
31592
32570
|
peerNames: ctx.peers.map((p) => p.name),
|
|
@@ -31619,13 +32597,12 @@ ${lines.join("\n")}`;
|
|
|
31619
32597
|
}
|
|
31620
32598
|
return;
|
|
31621
32599
|
}
|
|
31622
|
-
|
|
31623
|
-
void this.acquire(agentConfig, targetScope, cwd).then(() => {
|
|
32600
|
+
void this.acquire(agentConfig, targetScope, resolvedCwd).then(() => {
|
|
31624
32601
|
logger13.info("Neural send new runtime acquired", {
|
|
31625
32602
|
agentId: agentConfig.id,
|
|
31626
32603
|
toScope: payload.toScopeKey,
|
|
31627
32604
|
traceId: task.traceId,
|
|
31628
|
-
cwd,
|
|
32605
|
+
cwd: resolvedCwd,
|
|
31629
32606
|
replyMessageId: task.replyMessageId
|
|
31630
32607
|
});
|
|
31631
32608
|
return this.sendMessage({ ...task, agentId: agentConfig.id, scope: targetScope });
|
|
@@ -31634,7 +32611,7 @@ ${lines.join("\n")}`;
|
|
|
31634
32611
|
agentId: agentConfig.id,
|
|
31635
32612
|
toScope: payload.toScopeKey,
|
|
31636
32613
|
traceId: task.traceId,
|
|
31637
|
-
cwd,
|
|
32614
|
+
cwd: resolvedCwd,
|
|
31638
32615
|
error: err
|
|
31639
32616
|
});
|
|
31640
32617
|
});
|
|
@@ -31821,16 +32798,19 @@ ${lines.join("\n")}`;
|
|
|
31821
32798
|
for (const proc of [...this.agents.values()]) {
|
|
31822
32799
|
if (proc.status === "working" || proc.status === "starting") {
|
|
31823
32800
|
proc.pendingTerminate = true;
|
|
32801
|
+
proc.pendingTerminatePreserveSession = true;
|
|
32802
|
+
proc.pendingTerminateReason = reason;
|
|
31824
32803
|
deferred++;
|
|
31825
32804
|
logger13.info("Runtime reload deferred until turn completes", {
|
|
31826
32805
|
agentId: proc.agentId,
|
|
31827
32806
|
scope: scopeKey(proc.scope),
|
|
31828
32807
|
status: proc.status,
|
|
31829
|
-
reason
|
|
32808
|
+
reason,
|
|
32809
|
+
preserveSession: true
|
|
31830
32810
|
});
|
|
31831
32811
|
continue;
|
|
31832
32812
|
}
|
|
31833
|
-
await this.
|
|
32813
|
+
await this.closeRuntimeForRuntimeReload(proc, reason);
|
|
31834
32814
|
terminated++;
|
|
31835
32815
|
}
|
|
31836
32816
|
return { terminated, deferred };
|
|
@@ -31849,7 +32829,9 @@ ${lines.join("\n")}`;
|
|
|
31849
32829
|
)) {
|
|
31850
32830
|
this.dormantGroupInboxes.delete(key);
|
|
31851
32831
|
}
|
|
31852
|
-
const result = await this.terminateAgentForRuntimeReload(agentId, reason
|
|
32832
|
+
const result = await this.terminateAgentForRuntimeReload(agentId, reason, {
|
|
32833
|
+
preserveSession: false
|
|
32834
|
+
});
|
|
31853
32835
|
logger13.info("Agent scoped runtime reload requested", {
|
|
31854
32836
|
agentId,
|
|
31855
32837
|
reason,
|
|
@@ -31858,9 +32840,10 @@ ${lines.join("\n")}`;
|
|
|
31858
32840
|
});
|
|
31859
32841
|
return result;
|
|
31860
32842
|
}
|
|
31861
|
-
async terminateAgentForRuntimeReload(agentId, reason) {
|
|
32843
|
+
async terminateAgentForRuntimeReload(agentId, reason, options = {}) {
|
|
31862
32844
|
let terminated = 0;
|
|
31863
32845
|
let deferred = 0;
|
|
32846
|
+
const preserveSession = options.preserveSession ?? true;
|
|
31864
32847
|
const procs = [...this.agents.values()].filter((proc) => proc.agentId === agentId);
|
|
31865
32848
|
if (procs.length === 0) {
|
|
31866
32849
|
logger13.info("runtime reload: no live runtime for agent", { agentId, reason });
|
|
@@ -31869,16 +32852,23 @@ ${lines.join("\n")}`;
|
|
|
31869
32852
|
for (const proc of procs) {
|
|
31870
32853
|
if (proc.status === "working" || proc.status === "starting") {
|
|
31871
32854
|
proc.pendingTerminate = true;
|
|
32855
|
+
proc.pendingTerminatePreserveSession = preserveSession;
|
|
32856
|
+
proc.pendingTerminateReason = reason;
|
|
31872
32857
|
deferred++;
|
|
31873
32858
|
logger13.info("Runtime reload deferred until turn completes", {
|
|
31874
32859
|
agentId: proc.agentId,
|
|
31875
32860
|
scope: scopeKey(proc.scope),
|
|
31876
32861
|
status: proc.status,
|
|
31877
|
-
reason
|
|
32862
|
+
reason,
|
|
32863
|
+
preserveSession
|
|
31878
32864
|
});
|
|
31879
32865
|
continue;
|
|
31880
32866
|
}
|
|
31881
|
-
|
|
32867
|
+
if (preserveSession) {
|
|
32868
|
+
await this.closeRuntimeForRuntimeReload(proc, reason);
|
|
32869
|
+
} else {
|
|
32870
|
+
await this.terminateScope(proc.agentId, proc.scope);
|
|
32871
|
+
}
|
|
31882
32872
|
terminated++;
|
|
31883
32873
|
}
|
|
31884
32874
|
return { terminated, deferred };
|
|
@@ -31930,7 +32920,11 @@ ${lines.join("\n")}`;
|
|
|
31930
32920
|
*/
|
|
31931
32921
|
checkPendingTerminate(proc) {
|
|
31932
32922
|
if (!proc.pendingTerminate) return;
|
|
32923
|
+
const preserveSession = proc.pendingTerminatePreserveSession === true;
|
|
32924
|
+
const reason = proc.pendingTerminateReason ?? "deferred_terminate";
|
|
31933
32925
|
proc.pendingTerminate = false;
|
|
32926
|
+
proc.pendingTerminatePreserveSession = false;
|
|
32927
|
+
proc.pendingTerminateReason = void 0;
|
|
31934
32928
|
const runtime = this.asRuntime(proc);
|
|
31935
32929
|
const pendingTasks = [...runtime.injectedTasks.splice(0), ...runtime.planModeBuffer.splice(0)];
|
|
31936
32930
|
for (const task of pendingTasks) {
|
|
@@ -31965,10 +32959,16 @@ ${lines.join("\n")}`;
|
|
|
31965
32959
|
logger13.info("checkPendingTerminate: executing deferred runtime-reload teardown", {
|
|
31966
32960
|
agentId: proc.agentId,
|
|
31967
32961
|
scope: scopeKey(proc.scope),
|
|
32962
|
+
reason,
|
|
32963
|
+
preserveSession,
|
|
31968
32964
|
releasedPendingTaskCount: pendingTasks.length,
|
|
31969
32965
|
releasedInboxCount: pendingInbox.length
|
|
31970
32966
|
});
|
|
31971
|
-
|
|
32967
|
+
if (preserveSession) {
|
|
32968
|
+
void this.closeRuntimeForRuntimeReload(proc, reason);
|
|
32969
|
+
} else {
|
|
32970
|
+
void this.terminateScope(proc.agentId, proc.scope);
|
|
32971
|
+
}
|
|
31972
32972
|
}
|
|
31973
32973
|
/** Stop one scoped SDK runtime (workdir change). */
|
|
31974
32974
|
async terminateScope(agentId, scope) {
|
|
@@ -31984,6 +32984,8 @@ ${lines.join("\n")}`;
|
|
|
31984
32984
|
}
|
|
31985
32985
|
if (proc.status === "working" && proc.currentTask) {
|
|
31986
32986
|
proc.pendingTerminate = true;
|
|
32987
|
+
proc.pendingTerminatePreserveSession = false;
|
|
32988
|
+
proc.pendingTerminateReason = "terminate_scope";
|
|
31987
32989
|
logger13.info("terminateScope: runtime working; teardown deferred until turn completes", {
|
|
31988
32990
|
agentId,
|
|
31989
32991
|
scope: scopeKey(scope),
|
|
@@ -32314,6 +33316,109 @@ ${lines.join("\n")}`;
|
|
|
32314
33316
|
}
|
|
32315
33317
|
return [...ids];
|
|
32316
33318
|
}
|
|
33319
|
+
latestOpenToolUse(proc) {
|
|
33320
|
+
for (let i = proc.contentBlocks.length - 1; i >= 0; i -= 1) {
|
|
33321
|
+
const block = proc.contentBlocks[i];
|
|
33322
|
+
if (block?.type !== "tool_use") continue;
|
|
33323
|
+
if (block.status === "pending" || block.status === "running" || block.status === "paused" || block.status === "resumed") {
|
|
33324
|
+
return block;
|
|
33325
|
+
}
|
|
33326
|
+
return null;
|
|
33327
|
+
}
|
|
33328
|
+
return null;
|
|
33329
|
+
}
|
|
33330
|
+
emitLiveToolInputSnapshotForResume(proc, payload) {
|
|
33331
|
+
const task = proc.currentTask;
|
|
33332
|
+
const openTool = this.latestOpenToolUse(proc);
|
|
33333
|
+
if (!task || !openTool) return false;
|
|
33334
|
+
const toolName = proc.currentToolName ?? openTool.toolName;
|
|
33335
|
+
if (toolName !== openTool.toolName) return false;
|
|
33336
|
+
const liveInput = proc.accumulatedToolInput.length > 0 ? extractLiveToolInput(toolName, proc.accumulatedToolInput) : null;
|
|
33337
|
+
const input = liveInput && Object.keys(liveInput).length > 0 ? liveInput : Object.keys(openTool.input).length > 0 ? openTool.input : null;
|
|
33338
|
+
if (!input) return false;
|
|
33339
|
+
openTool.input = input;
|
|
33340
|
+
this.emit({
|
|
33341
|
+
type: "agent:tool_input_update",
|
|
33342
|
+
payload: {
|
|
33343
|
+
ackId: task.replyMessageId,
|
|
33344
|
+
agentId: proc.agentId,
|
|
33345
|
+
conversationId: task.conversationId,
|
|
33346
|
+
toolName,
|
|
33347
|
+
input,
|
|
33348
|
+
traceId: payload.traceId
|
|
33349
|
+
}
|
|
33350
|
+
});
|
|
33351
|
+
logger13.info("Reply session resume emitted live tool input snapshot", {
|
|
33352
|
+
requestId: payload.requestId,
|
|
33353
|
+
replySessionId: payload.replySessionId,
|
|
33354
|
+
replyMessageId: payload.replyMessageId,
|
|
33355
|
+
agentId: payload.agentId,
|
|
33356
|
+
scope: scopeKey(proc.scope),
|
|
33357
|
+
toolName,
|
|
33358
|
+
inputKeys: Object.keys(input),
|
|
33359
|
+
accumulatedToolInputLen: proc.accumulatedToolInput.length,
|
|
33360
|
+
traceId: payload.traceId
|
|
33361
|
+
});
|
|
33362
|
+
return true;
|
|
33363
|
+
}
|
|
33364
|
+
resumeReplySession(payload) {
|
|
33365
|
+
for (const [, proc] of this.agents) {
|
|
33366
|
+
if (proc.agentId !== payload.agentId) continue;
|
|
33367
|
+
const runtime = this.asRuntime(proc);
|
|
33368
|
+
if (runtime.currentTask?.replyMessageId !== payload.replyMessageId) continue;
|
|
33369
|
+
const lastTokenIndex = Math.max(0, payload.lastTokenIndex ?? 0);
|
|
33370
|
+
const missingDelta = runtime.accumulatedText.length > lastTokenIndex ? runtime.accumulatedText.slice(lastTokenIndex) : void 0;
|
|
33371
|
+
const canResume = proc.status === "working";
|
|
33372
|
+
const liveToolInputSnapshotEmitted = canResume ? this.emitLiveToolInputSnapshotForResume(runtime, payload) : false;
|
|
33373
|
+
logger13.info("Reply session resume resolved from active runtime", {
|
|
33374
|
+
requestId: payload.requestId,
|
|
33375
|
+
replySessionId: payload.replySessionId,
|
|
33376
|
+
replyMessageId: payload.replyMessageId,
|
|
33377
|
+
agentId: payload.agentId,
|
|
33378
|
+
scope: scopeKey(proc.scope),
|
|
33379
|
+
canResume,
|
|
33380
|
+
accumulatedTextLen: runtime.accumulatedText.length,
|
|
33381
|
+
missingDeltaLen: missingDelta?.length ?? 0,
|
|
33382
|
+
liveToolInputSnapshotEmitted,
|
|
33383
|
+
traceId: payload.traceId
|
|
33384
|
+
});
|
|
33385
|
+
return {
|
|
33386
|
+
requestId: payload.requestId,
|
|
33387
|
+
replySessionId: payload.replySessionId,
|
|
33388
|
+
replyMessageId: payload.replyMessageId,
|
|
33389
|
+
agentId: payload.agentId,
|
|
33390
|
+
conversationId: payload.conversationId,
|
|
33391
|
+
canResume,
|
|
33392
|
+
currentStatus: canResume ? "replying" : "paused",
|
|
33393
|
+
recoverability: canResume ? "resumable" : "retryable",
|
|
33394
|
+
...missingDelta ? { missingDelta } : {},
|
|
33395
|
+
reason: canResume ? "active_runtime_resumed" : "runtime_not_working",
|
|
33396
|
+
traceId: payload.traceId,
|
|
33397
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33398
|
+
};
|
|
33399
|
+
}
|
|
33400
|
+
logger13.warn("Reply session resume could not find active runtime", {
|
|
33401
|
+
requestId: payload.requestId,
|
|
33402
|
+
replySessionId: payload.replySessionId,
|
|
33403
|
+
replyMessageId: payload.replyMessageId,
|
|
33404
|
+
agentId: payload.agentId,
|
|
33405
|
+
conversationId: payload.conversationId,
|
|
33406
|
+
traceId: payload.traceId
|
|
33407
|
+
});
|
|
33408
|
+
return {
|
|
33409
|
+
requestId: payload.requestId,
|
|
33410
|
+
replySessionId: payload.replySessionId,
|
|
33411
|
+
replyMessageId: payload.replyMessageId,
|
|
33412
|
+
agentId: payload.agentId,
|
|
33413
|
+
conversationId: payload.conversationId,
|
|
33414
|
+
canResume: false,
|
|
33415
|
+
currentStatus: "paused",
|
|
33416
|
+
recoverability: "retryable",
|
|
33417
|
+
reason: "reply_session_not_found",
|
|
33418
|
+
traceId: payload.traceId,
|
|
33419
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33420
|
+
};
|
|
33421
|
+
}
|
|
32317
33422
|
/**
|
|
32318
33423
|
* Resolve the conversationId that a scope-notice task should land on for the
|
|
32319
33424
|
* given runtime scope. Returns null on resolve failure (server unreachable,
|
|
@@ -32426,7 +33531,8 @@ ${lines.join("\n")}`;
|
|
|
32426
33531
|
}
|
|
32427
33532
|
const runtime = this.asRuntime(proc);
|
|
32428
33533
|
const key = runtimeKey(agentId, proc.scope);
|
|
32429
|
-
const
|
|
33534
|
+
const hadPendingTerminate = proc.pendingTerminate === true;
|
|
33535
|
+
const preserveSessionForRuntimeReload = proc.pendingTerminatePreserveSession === true;
|
|
32430
33536
|
if (!runtime.currentTask || runtime.currentTask.replyMessageId !== replyMessageId) {
|
|
32431
33537
|
logger13.warn("cancelReply: replyMessageId mismatch", {
|
|
32432
33538
|
agentId,
|
|
@@ -32513,7 +33619,7 @@ ${lines.join("\n")}`;
|
|
|
32513
33619
|
traceId: t.traceId
|
|
32514
33620
|
});
|
|
32515
33621
|
}
|
|
32516
|
-
if (
|
|
33622
|
+
if (hadPendingTerminate) {
|
|
32517
33623
|
const pendingInbox = [...runtime.groupInbox];
|
|
32518
33624
|
runtime.groupInbox = [];
|
|
32519
33625
|
for (const entry of pendingInbox) {
|
|
@@ -32529,9 +33635,10 @@ ${lines.join("\n")}`;
|
|
|
32529
33635
|
}
|
|
32530
33636
|
});
|
|
32531
33637
|
}
|
|
32532
|
-
logger13.info("cancelReply: pending
|
|
33638
|
+
logger13.info("cancelReply: pending deferred teardown handled after stop", {
|
|
32533
33639
|
agentId,
|
|
32534
33640
|
scope: scopeKey(proc.scope),
|
|
33641
|
+
preserveSession: preserveSessionForRuntimeReload,
|
|
32535
33642
|
releasedInboxCount: pendingInbox.length,
|
|
32536
33643
|
traceId
|
|
32537
33644
|
});
|
|
@@ -32541,11 +33648,15 @@ ${lines.join("\n")}`;
|
|
|
32541
33648
|
proc.status = "dead";
|
|
32542
33649
|
this.agents.delete(key);
|
|
32543
33650
|
this.lastUsedAt.delete(key);
|
|
32544
|
-
if (
|
|
33651
|
+
if (hadPendingTerminate) {
|
|
32545
33652
|
proc.pendingTerminate = false;
|
|
33653
|
+
proc.pendingTerminatePreserveSession = false;
|
|
33654
|
+
proc.pendingTerminateReason = void 0;
|
|
32546
33655
|
this.dormantScopes.delete(key);
|
|
32547
33656
|
this.dormantGroupInboxes.delete(key);
|
|
32548
|
-
|
|
33657
|
+
if (!preserveSessionForRuntimeReload) {
|
|
33658
|
+
this.sessionStore.delete(agentId, proc.scope);
|
|
33659
|
+
}
|
|
32549
33660
|
this.dispatchMemory.deleteScope(agentId, proc.scope);
|
|
32550
33661
|
}
|
|
32551
33662
|
logger13.info("cancelReply: process torn down", {
|
|
@@ -32553,7 +33664,7 @@ ${lines.join("\n")}`;
|
|
|
32553
33664
|
scope: scopeKey(proc.scope),
|
|
32554
33665
|
conversationId,
|
|
32555
33666
|
traceId,
|
|
32556
|
-
|
|
33667
|
+
sessionPreservedForRuntimeReload: preserveSessionForRuntimeReload
|
|
32557
33668
|
});
|
|
32558
33669
|
try {
|
|
32559
33670
|
runtime.inputController.close();
|
|
@@ -33370,6 +34481,7 @@ import { fileURLToPath } from "url";
|
|
|
33370
34481
|
var logger18 = createModuleLogger("mcp.registry");
|
|
33371
34482
|
var AHCHAT_BUILTIN_MCP_COMMAND = "ahchat-builtin";
|
|
33372
34483
|
var SEEDANCE_BUILTIN_MCP_ID = "seedance-mcp";
|
|
34484
|
+
var SEEDREAM_BUILTIN_MCP_ID = "seedream-mcp";
|
|
33373
34485
|
var HttpMcpRegistry = class {
|
|
33374
34486
|
constructor(serverApiUrl, bridgeToken = null, localStore = null) {
|
|
33375
34487
|
this.serverApiUrl = serverApiUrl;
|
|
@@ -33443,7 +34555,7 @@ var HttpMcpRegistry = class {
|
|
|
33443
34555
|
usedNames.add(serverName);
|
|
33444
34556
|
mcpServers[serverName] = sdkConfig;
|
|
33445
34557
|
for (const tool2 of connection.tools) {
|
|
33446
|
-
if (!tool2.enabled || tool2.permissionPolicy
|
|
34558
|
+
if (!tool2.enabled || tool2.permissionPolicy === "always_deny") continue;
|
|
33447
34559
|
allowedTools.push(mcpRuntimeToolName(serverName, tool2.name));
|
|
33448
34560
|
}
|
|
33449
34561
|
}
|
|
@@ -33493,7 +34605,7 @@ var HttpMcpRegistry = class {
|
|
|
33493
34605
|
return null;
|
|
33494
34606
|
}
|
|
33495
34607
|
if (connection.command === AHCHAT_BUILTIN_MCP_COMMAND) {
|
|
33496
|
-
return resolveBuiltinMcpServerConfig(connection);
|
|
34608
|
+
return this.resolveBuiltinMcpServerConfig(connection);
|
|
33497
34609
|
}
|
|
33498
34610
|
return {
|
|
33499
34611
|
type: "stdio",
|
|
@@ -33519,37 +34631,113 @@ var HttpMcpRegistry = class {
|
|
|
33519
34631
|
};
|
|
33520
34632
|
return connection.transport === "sse" ? { type: "sse", ...common } : { type: "http", ...common };
|
|
33521
34633
|
}
|
|
33522
|
-
|
|
33523
|
-
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
34634
|
+
resolveBuiltinMcpServerConfig(connection) {
|
|
34635
|
+
const [builtinId, ...extraArgs] = connection.args;
|
|
34636
|
+
if (builtinId !== SEEDANCE_BUILTIN_MCP_ID && builtinId !== SEEDREAM_BUILTIN_MCP_ID) {
|
|
34637
|
+
logger18.warn("Skipping unknown built-in MCP server", {
|
|
34638
|
+
id: connection.id,
|
|
34639
|
+
serverName: connection.serverName,
|
|
34640
|
+
builtinId
|
|
34641
|
+
});
|
|
34642
|
+
return null;
|
|
34643
|
+
}
|
|
34644
|
+
const executable = builtinId === SEEDANCE_BUILTIN_MCP_ID ? resolveSeedanceMcpExecutable(extraArgs) : resolveSeedreamMcpExecutable(extraArgs);
|
|
34645
|
+
if (!executable) {
|
|
34646
|
+
logger18.warn("Skipping built-in MCP server because CLI bundle is missing", {
|
|
34647
|
+
id: connection.id,
|
|
34648
|
+
serverName: connection.serverName,
|
|
34649
|
+
builtinId
|
|
34650
|
+
});
|
|
34651
|
+
return null;
|
|
34652
|
+
}
|
|
34653
|
+
return {
|
|
34654
|
+
type: "stdio",
|
|
34655
|
+
command: executable.command,
|
|
34656
|
+
args: executable.args,
|
|
34657
|
+
env: {
|
|
34658
|
+
...connection.env,
|
|
34659
|
+
...executable.env,
|
|
34660
|
+
AHCHAT_SERVER_API_URL: this.serverApiUrl,
|
|
34661
|
+
...this.bridgeToken ? { AHCHAT_BRIDGE_TOKEN: this.bridgeToken } : {},
|
|
34662
|
+
AHCHAT_MCP_SERVER_NAME: normalizeMcpServerName(connection.serverName)
|
|
34663
|
+
},
|
|
34664
|
+
alwaysLoad: connection.alwaysLoad
|
|
34665
|
+
};
|
|
33532
34666
|
}
|
|
33533
|
-
|
|
33534
|
-
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
33540
|
-
|
|
33541
|
-
|
|
33542
|
-
|
|
33543
|
-
const
|
|
33544
|
-
const
|
|
33545
|
-
|
|
33546
|
-
|
|
34667
|
+
};
|
|
34668
|
+
function resolveSeedanceMcpExecutable(extraArgs, options = {}) {
|
|
34669
|
+
return resolveBundledMcpExecutable("seedanceMcpCli", extraArgs, options);
|
|
34670
|
+
}
|
|
34671
|
+
function resolveSeedreamMcpExecutable(extraArgs, options = {}) {
|
|
34672
|
+
return resolveBundledMcpExecutable("seedreamMcpCli", extraArgs, options);
|
|
34673
|
+
}
|
|
34674
|
+
function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
|
|
34675
|
+
const currentDir = options.currentDir ?? path14.dirname(fileURLToPath(import.meta.url));
|
|
34676
|
+
const cwd = options.cwd ?? process.cwd();
|
|
34677
|
+
const execPath = options.execPath ?? process.execPath;
|
|
34678
|
+
const existsSync3 = options.existsSync ?? fs7.existsSync;
|
|
34679
|
+
const distCliPath = firstExistingPath(
|
|
34680
|
+
[
|
|
34681
|
+
path14.join(currentDir, `${cliBaseName}.cjs`)
|
|
34682
|
+
],
|
|
34683
|
+
existsSync3
|
|
34684
|
+
);
|
|
34685
|
+
if (distCliPath) {
|
|
34686
|
+
return {
|
|
34687
|
+
command: execPath,
|
|
34688
|
+
args: [distCliPath, ...extraArgs],
|
|
34689
|
+
env: shouldRunExecPathAsNode(execPath, options) ? { ELECTRON_RUN_AS_NODE: "1" } : void 0
|
|
34690
|
+
};
|
|
33547
34691
|
}
|
|
33548
|
-
const sourceCliPath =
|
|
33549
|
-
|
|
34692
|
+
const sourceCliPath = firstExistingPath(
|
|
34693
|
+
[
|
|
34694
|
+
path14.join(currentDir, `${cliBaseName}.ts`)
|
|
34695
|
+
],
|
|
34696
|
+
existsSync3
|
|
34697
|
+
);
|
|
34698
|
+
if (sourceCliPath) {
|
|
33550
34699
|
return { command: "tsx", args: [sourceCliPath, ...extraArgs] };
|
|
33551
34700
|
}
|
|
33552
|
-
|
|
34701
|
+
const workspaceDistCliPath = firstExistingPath(
|
|
34702
|
+
[
|
|
34703
|
+
path14.resolve(currentDir, `../../bridge/dist/${cliBaseName}.cjs`),
|
|
34704
|
+
path14.resolve(cwd, `packages/desktop/dist/${cliBaseName}.cjs`),
|
|
34705
|
+
path14.resolve(cwd, `packages/bridge/dist/${cliBaseName}.cjs`)
|
|
34706
|
+
],
|
|
34707
|
+
existsSync3
|
|
34708
|
+
);
|
|
34709
|
+
if (workspaceDistCliPath) {
|
|
34710
|
+
return {
|
|
34711
|
+
command: execPath,
|
|
34712
|
+
args: [workspaceDistCliPath, ...extraArgs],
|
|
34713
|
+
env: shouldRunExecPathAsNode(execPath, options) ? { ELECTRON_RUN_AS_NODE: "1" } : void 0
|
|
34714
|
+
};
|
|
34715
|
+
}
|
|
34716
|
+
const workspaceSourceCliPath = firstExistingPath(
|
|
34717
|
+
[
|
|
34718
|
+
path14.resolve(currentDir, `../../bridge/src/${cliBaseName}.ts`),
|
|
34719
|
+
path14.resolve(cwd, `packages/bridge/src/${cliBaseName}.ts`)
|
|
34720
|
+
],
|
|
34721
|
+
existsSync3
|
|
34722
|
+
);
|
|
34723
|
+
if (workspaceSourceCliPath) {
|
|
34724
|
+
return { command: "tsx", args: [workspaceSourceCliPath, ...extraArgs] };
|
|
34725
|
+
}
|
|
34726
|
+
return null;
|
|
34727
|
+
}
|
|
34728
|
+
function firstExistingPath(paths, existsSync3) {
|
|
34729
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34730
|
+
for (const filePath of paths) {
|
|
34731
|
+
if (seen.has(filePath)) continue;
|
|
34732
|
+
seen.add(filePath);
|
|
34733
|
+
if (existsSync3(filePath)) return filePath;
|
|
34734
|
+
}
|
|
34735
|
+
return null;
|
|
34736
|
+
}
|
|
34737
|
+
function shouldRunExecPathAsNode(execPath, options) {
|
|
34738
|
+
if (typeof options.isElectron === "boolean") return options.isElectron;
|
|
34739
|
+
if (process.versions.electron) return true;
|
|
34740
|
+
return path14.basename(execPath).toLowerCase().includes("electron");
|
|
33553
34741
|
}
|
|
33554
34742
|
function uniqueServerName(serverName, usedNames) {
|
|
33555
34743
|
if (!usedNames.has(serverName)) return serverName;
|
|
@@ -33919,6 +35107,18 @@ var wrapper_default = import_websocket.default;
|
|
|
33919
35107
|
var logger22 = createModuleLogger("ws.connector");
|
|
33920
35108
|
var WATCHDOG_INTERVAL_MS = 15e3;
|
|
33921
35109
|
var STALE_THRESHOLD_MS = WS_HEARTBEAT_INTERVAL_MS * 2 + 15e3;
|
|
35110
|
+
function localNetworkAddresses() {
|
|
35111
|
+
const out = /* @__PURE__ */ new Set();
|
|
35112
|
+
for (const entries of Object.values(os8.networkInterfaces())) {
|
|
35113
|
+
for (const entry of entries ?? []) {
|
|
35114
|
+
if (entry.internal) continue;
|
|
35115
|
+
const address = entry.address.trim();
|
|
35116
|
+
if (!address) continue;
|
|
35117
|
+
out.add(address.toLowerCase());
|
|
35118
|
+
}
|
|
35119
|
+
}
|
|
35120
|
+
return [...out].sort();
|
|
35121
|
+
}
|
|
33922
35122
|
var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
|
|
33923
35123
|
"agent:segment",
|
|
33924
35124
|
"agent:turn_complete",
|
|
@@ -33931,7 +35131,8 @@ var OUTBOX_CRITICAL_TYPES = /* @__PURE__ */ new Set([
|
|
|
33931
35131
|
"ask_question_updated",
|
|
33932
35132
|
"artifact:created",
|
|
33933
35133
|
"agent:todos_update",
|
|
33934
|
-
"feedback:analysis_result"
|
|
35134
|
+
"feedback:analysis_result",
|
|
35135
|
+
"bridge:resume_reply_session_response"
|
|
33935
35136
|
]);
|
|
33936
35137
|
var OUTBOX_MAX_ENTRIES = 300;
|
|
33937
35138
|
function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
|
|
@@ -33941,6 +35142,24 @@ function buildBridgeWebSocketUrl(serverUrl, bridgeToken) {
|
|
|
33941
35142
|
url2.searchParams.set("token", token);
|
|
33942
35143
|
return url2.toString();
|
|
33943
35144
|
}
|
|
35145
|
+
function bridgeResumeUnsupportedResponse(payload) {
|
|
35146
|
+
return {
|
|
35147
|
+
type: "bridge:resume_reply_session_response",
|
|
35148
|
+
payload: {
|
|
35149
|
+
requestId: payload.requestId,
|
|
35150
|
+
replySessionId: payload.replySessionId,
|
|
35151
|
+
replyMessageId: payload.replyMessageId,
|
|
35152
|
+
agentId: payload.agentId,
|
|
35153
|
+
conversationId: payload.conversationId,
|
|
35154
|
+
canResume: false,
|
|
35155
|
+
currentStatus: "paused",
|
|
35156
|
+
recoverability: "retryable",
|
|
35157
|
+
reason: "bridge_resume_not_supported",
|
|
35158
|
+
traceId: payload.traceId,
|
|
35159
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
35160
|
+
}
|
|
35161
|
+
};
|
|
35162
|
+
}
|
|
33944
35163
|
var ServerConnector = class {
|
|
33945
35164
|
ws = null;
|
|
33946
35165
|
reconnectAttempts = 0;
|
|
@@ -33958,6 +35177,7 @@ var ServerConnector = class {
|
|
|
33958
35177
|
onTaskDispatch;
|
|
33959
35178
|
onGroupTaskDispatch;
|
|
33960
35179
|
onStopGeneration;
|
|
35180
|
+
onResumeReplySession;
|
|
33961
35181
|
onConnected;
|
|
33962
35182
|
onRegistered;
|
|
33963
35183
|
onServerPush;
|
|
@@ -33972,6 +35192,7 @@ var ServerConnector = class {
|
|
|
33972
35192
|
this.onTaskDispatch = params.onTaskDispatch;
|
|
33973
35193
|
this.onGroupTaskDispatch = params.onGroupTaskDispatch;
|
|
33974
35194
|
this.onStopGeneration = params.onStopGeneration;
|
|
35195
|
+
this.onResumeReplySession = params.onResumeReplySession;
|
|
33975
35196
|
this.onConnected = params.onConnected;
|
|
33976
35197
|
this.onRegistered = params.onRegistered;
|
|
33977
35198
|
this.onServerPush = params.onServerPush;
|
|
@@ -34048,6 +35269,7 @@ var ServerConnector = class {
|
|
|
34048
35269
|
bridgeId: this.config.bridgeId,
|
|
34049
35270
|
agents: ids,
|
|
34050
35271
|
hostname: os8.hostname(),
|
|
35272
|
+
localAddresses: localNetworkAddresses(),
|
|
34051
35273
|
runtimes: Object.keys(runtimes).length > 0 ? runtimes : void 0,
|
|
34052
35274
|
queryConfig: {
|
|
34053
35275
|
maxActive: qc.maxActive,
|
|
@@ -34085,6 +35307,7 @@ var ServerConnector = class {
|
|
|
34085
35307
|
agentId: payload.agentId,
|
|
34086
35308
|
conversationId: payload.conversationId,
|
|
34087
35309
|
requestId,
|
|
35310
|
+
dispatchKind: payload.dispatchKind ?? "normal",
|
|
34088
35311
|
traceId: payload.traceId
|
|
34089
35312
|
});
|
|
34090
35313
|
void this.onTaskDispatch(payload).catch((err) => {
|
|
@@ -34125,6 +35348,31 @@ var ServerConnector = class {
|
|
|
34125
35348
|
});
|
|
34126
35349
|
return;
|
|
34127
35350
|
}
|
|
35351
|
+
case "bridge:resume_reply_session_request": {
|
|
35352
|
+
logger22.info("bridge:resume_reply_session_request received", {
|
|
35353
|
+
requestId: msg.payload.requestId,
|
|
35354
|
+
replySessionId: msg.payload.replySessionId,
|
|
35355
|
+
agentId: msg.payload.agentId,
|
|
35356
|
+
conversationId: msg.payload.conversationId,
|
|
35357
|
+
lastTokenIndex: msg.payload.lastTokenIndex ?? null,
|
|
35358
|
+
traceId: msg.payload.traceId
|
|
35359
|
+
});
|
|
35360
|
+
if (!this.onResumeReplySession) {
|
|
35361
|
+
this.send(bridgeResumeUnsupportedResponse(msg.payload));
|
|
35362
|
+
return;
|
|
35363
|
+
}
|
|
35364
|
+
void Promise.resolve(this.onResumeReplySession(msg.payload)).then((response) => this.send(response)).catch((err) => {
|
|
35365
|
+
logger22.error("Failed to handle bridge resume request", {
|
|
35366
|
+
error: err,
|
|
35367
|
+
requestId: msg.payload.requestId,
|
|
35368
|
+
replySessionId: msg.payload.replySessionId,
|
|
35369
|
+
agentId: msg.payload.agentId,
|
|
35370
|
+
traceId: msg.payload.traceId
|
|
35371
|
+
});
|
|
35372
|
+
this.send(bridgeResumeUnsupportedResponse(msg.payload));
|
|
35373
|
+
});
|
|
35374
|
+
return;
|
|
35375
|
+
}
|
|
34128
35376
|
case "session:terminated": {
|
|
34129
35377
|
logger22.warn("Session terminated by server, exiting bridge process", {
|
|
34130
35378
|
reason: msg.payload.reason
|
|
@@ -35105,14 +36353,14 @@ async function dumpAgentContext(agentId, deps) {
|
|
|
35105
36353
|
}
|
|
35106
36354
|
|
|
35107
36355
|
// src/clipboardFiles.ts
|
|
35108
|
-
import { execFile } from "child_process";
|
|
36356
|
+
import { execFile as execFile2 } from "child_process";
|
|
35109
36357
|
import crypto3 from "crypto";
|
|
35110
36358
|
import fs11 from "fs/promises";
|
|
35111
36359
|
import os10 from "os";
|
|
35112
36360
|
import path18 from "path";
|
|
35113
|
-
import { promisify } from "util";
|
|
36361
|
+
import { promisify as promisify2 } from "util";
|
|
35114
36362
|
var logger24 = createModuleLogger("bridge.clipboardFiles");
|
|
35115
|
-
var
|
|
36363
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
35116
36364
|
var MAX_CLIPBOARD_FILE_SIZE = 100 * 1024 * 1024;
|
|
35117
36365
|
var WINDOWS_CLIPBOARD_TIMEOUT_MS = 3e3;
|
|
35118
36366
|
function isRecord5(value) {
|
|
@@ -35207,7 +36455,7 @@ async function readWindowsClipboardPathCandidates() {
|
|
|
35207
36455
|
"[pscustomobject]@{ files = $files; text = $text } | ConvertTo-Json -Compress;"
|
|
35208
36456
|
].join(" ");
|
|
35209
36457
|
try {
|
|
35210
|
-
const { stdout } = await
|
|
36458
|
+
const { stdout } = await execFileAsync2("powershell.exe", [
|
|
35211
36459
|
"-NoProfile",
|
|
35212
36460
|
"-NonInteractive",
|
|
35213
36461
|
"-STA",
|
|
@@ -35410,7 +36658,7 @@ async function readWorkdirFile(filePath, baseDir) {
|
|
|
35410
36658
|
};
|
|
35411
36659
|
}
|
|
35412
36660
|
async function allocateTrashPath(trashDir, name) {
|
|
35413
|
-
const safeName = name.
|
|
36661
|
+
const safeName = name.split("").map((char) => isUnsafeFileNameChar(char) ? "_" : char).join("").replace(/[. ]+$/g, "") || "item";
|
|
35414
36662
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
35415
36663
|
for (let index = 0; index < 1e3; index += 1) {
|
|
35416
36664
|
const suffix = index === 0 ? "" : `-${index}`;
|
|
@@ -35424,6 +36672,10 @@ async function allocateTrashPath(trashDir, name) {
|
|
|
35424
36672
|
}
|
|
35425
36673
|
throw new Error("unable to allocate trash path");
|
|
35426
36674
|
}
|
|
36675
|
+
function isUnsafeFileNameChar(char) {
|
|
36676
|
+
const code = char.charCodeAt(0);
|
|
36677
|
+
return code <= 31 || '<>:"/\\|?*'.includes(char);
|
|
36678
|
+
}
|
|
35427
36679
|
async function trashWorkdirPath(opts) {
|
|
35428
36680
|
const resolvedBaseDir = resolveUserPath(opts.baseDir);
|
|
35429
36681
|
const resolvedTargetPath = resolveUserPath(opts.targetPath);
|
|
@@ -36218,7 +37470,8 @@ function groupInboxEntryFromDispatch(payload) {
|
|
|
36218
37470
|
boardItems: payload.boardItems,
|
|
36219
37471
|
boardSprints: payload.boardSprints,
|
|
36220
37472
|
boardIssues: payload.boardIssues,
|
|
36221
|
-
boardMeta: payload.boardMeta
|
|
37473
|
+
boardMeta: payload.boardMeta,
|
|
37474
|
+
dispatchKind: payload.dispatchKind
|
|
36222
37475
|
};
|
|
36223
37476
|
}
|
|
36224
37477
|
|
|
@@ -36315,7 +37568,8 @@ function createTaskDispatchHandler(agentManager, agentRegistry, emit) {
|
|
|
36315
37568
|
replyMessageId: payload.ackId,
|
|
36316
37569
|
traceId: payload.traceId,
|
|
36317
37570
|
requestId,
|
|
36318
|
-
planMode: payload.planMode ?? void 0
|
|
37571
|
+
planMode: payload.planMode ?? void 0,
|
|
37572
|
+
dispatchKind: payload.dispatchKind ?? "normal"
|
|
36319
37573
|
});
|
|
36320
37574
|
logger31.info("Agent run dispatched", {
|
|
36321
37575
|
agentId: payload.agentId,
|
|
@@ -36355,6 +37609,7 @@ function createGroupTaskDispatchHandler(agentManager, agentRegistry, emit) {
|
|
|
36355
37609
|
isMentioned: payload.isMentioned,
|
|
36356
37610
|
senderKind: payload.sender.kind,
|
|
36357
37611
|
chainDepth: payload.chainDepth,
|
|
37612
|
+
dispatchKind: payload.dispatchKind ?? "normal",
|
|
36358
37613
|
traceId: payload.traceId
|
|
36359
37614
|
});
|
|
36360
37615
|
emitTaskAck(emit, payload.ackId, payload.agentId, payload.traceId);
|
|
@@ -36389,7 +37644,7 @@ function createGroupTaskDispatchHandler(agentManager, agentRegistry, emit) {
|
|
|
36389
37644
|
}
|
|
36390
37645
|
const groupScope = { kind: "group", groupId: payload.groupId };
|
|
36391
37646
|
try {
|
|
36392
|
-
const cwd =
|
|
37647
|
+
const cwd = payload.cwd;
|
|
36393
37648
|
await agentManager.acquire(
|
|
36394
37649
|
agentConfig,
|
|
36395
37650
|
groupScope,
|
|
@@ -36595,10 +37850,14 @@ import path25 from "path";
|
|
|
36595
37850
|
var logger33 = createModuleLogger("session.store");
|
|
36596
37851
|
var SessionStore = class {
|
|
36597
37852
|
filePath;
|
|
37853
|
+
fingerprintPath;
|
|
36598
37854
|
cache;
|
|
37855
|
+
fingerprints;
|
|
36599
37856
|
constructor(dataDir) {
|
|
36600
37857
|
this.filePath = path25.join(dataDir, "sessions.json");
|
|
37858
|
+
this.fingerprintPath = path25.join(dataDir, "session-fingerprints.json");
|
|
36601
37859
|
this.cache = this.loadFromDisk();
|
|
37860
|
+
this.fingerprints = this.loadMapFromDisk(this.fingerprintPath, "session fingerprints");
|
|
36602
37861
|
}
|
|
36603
37862
|
cacheKey(agentId, scope) {
|
|
36604
37863
|
return runtimeKey(agentId, scope);
|
|
@@ -36611,8 +37870,13 @@ var SessionStore = class {
|
|
|
36611
37870
|
this.saveToDisk();
|
|
36612
37871
|
}
|
|
36613
37872
|
delete(agentId, scope) {
|
|
36614
|
-
|
|
36615
|
-
this.
|
|
37873
|
+
const key = this.cacheKey(agentId, scope);
|
|
37874
|
+
const hadSession = Object.prototype.hasOwnProperty.call(this.cache, key);
|
|
37875
|
+
const hadFingerprint = Object.prototype.hasOwnProperty.call(this.fingerprints, key);
|
|
37876
|
+
delete this.cache[key];
|
|
37877
|
+
delete this.fingerprints[key];
|
|
37878
|
+
if (hadSession) this.saveToDisk();
|
|
37879
|
+
if (hadFingerprint) this.saveFingerprintsToDisk();
|
|
36616
37880
|
}
|
|
36617
37881
|
deleteAllForAgent(agentId) {
|
|
36618
37882
|
const prefix = `${agentId}::`;
|
|
@@ -36626,10 +37890,27 @@ var SessionStore = class {
|
|
|
36626
37890
|
if (changed) {
|
|
36627
37891
|
this.saveToDisk();
|
|
36628
37892
|
}
|
|
37893
|
+
let fingerprintsChanged = false;
|
|
37894
|
+
for (const key of Object.keys(this.fingerprints)) {
|
|
37895
|
+
if (key === agentId || key.startsWith(prefix)) {
|
|
37896
|
+
delete this.fingerprints[key];
|
|
37897
|
+
fingerprintsChanged = true;
|
|
37898
|
+
}
|
|
37899
|
+
}
|
|
37900
|
+
if (fingerprintsChanged) {
|
|
37901
|
+
this.saveFingerprintsToDisk();
|
|
37902
|
+
}
|
|
36629
37903
|
}
|
|
36630
37904
|
getAll() {
|
|
36631
37905
|
return new Map(Object.entries(this.cache));
|
|
36632
37906
|
}
|
|
37907
|
+
getPromptFingerprint(agentId, scope) {
|
|
37908
|
+
return this.fingerprints[this.cacheKey(agentId, scope)] ?? null;
|
|
37909
|
+
}
|
|
37910
|
+
setPromptFingerprint(agentId, scope, fingerprint) {
|
|
37911
|
+
this.fingerprints[this.cacheKey(agentId, scope)] = fingerprint;
|
|
37912
|
+
this.saveFingerprintsToDisk();
|
|
37913
|
+
}
|
|
36633
37914
|
loadFromDisk() {
|
|
36634
37915
|
try {
|
|
36635
37916
|
if (!fs18.existsSync(this.filePath)) return {};
|
|
@@ -36655,6 +37936,22 @@ var SessionStore = class {
|
|
|
36655
37936
|
return {};
|
|
36656
37937
|
}
|
|
36657
37938
|
}
|
|
37939
|
+
loadMapFromDisk(filePath, label) {
|
|
37940
|
+
try {
|
|
37941
|
+
if (!fs18.existsSync(filePath)) return {};
|
|
37942
|
+
const raw = fs18.readFileSync(filePath, "utf-8");
|
|
37943
|
+
const parsed = JSON.parse(raw);
|
|
37944
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
|
|
37945
|
+
const out = {};
|
|
37946
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
37947
|
+
if (typeof value === "string") out[key] = value;
|
|
37948
|
+
}
|
|
37949
|
+
return out;
|
|
37950
|
+
} catch (e) {
|
|
37951
|
+
logger33.warn(`Failed to load ${label} file, starting fresh`, { error: e, path: filePath });
|
|
37952
|
+
return {};
|
|
37953
|
+
}
|
|
37954
|
+
}
|
|
36658
37955
|
saveToDisk() {
|
|
36659
37956
|
try {
|
|
36660
37957
|
const dir = path25.dirname(this.filePath);
|
|
@@ -36664,6 +37961,22 @@ var SessionStore = class {
|
|
|
36664
37961
|
logger33.error("Failed to save sessions file", { error: e, path: this.filePath });
|
|
36665
37962
|
}
|
|
36666
37963
|
}
|
|
37964
|
+
saveFingerprintsToDisk() {
|
|
37965
|
+
try {
|
|
37966
|
+
const dir = path25.dirname(this.fingerprintPath);
|
|
37967
|
+
fs18.mkdirSync(dir, { recursive: true });
|
|
37968
|
+
fs18.writeFileSync(
|
|
37969
|
+
this.fingerprintPath,
|
|
37970
|
+
JSON.stringify(this.fingerprints, null, 2),
|
|
37971
|
+
"utf-8"
|
|
37972
|
+
);
|
|
37973
|
+
} catch (e) {
|
|
37974
|
+
logger33.error("Failed to save session fingerprints file", {
|
|
37975
|
+
error: e,
|
|
37976
|
+
path: this.fingerprintPath
|
|
37977
|
+
});
|
|
37978
|
+
}
|
|
37979
|
+
}
|
|
36667
37980
|
};
|
|
36668
37981
|
|
|
36669
37982
|
// src/workdirEnsure.ts
|
|
@@ -37138,6 +38451,10 @@ function localCodexRuntimeCapability(status) {
|
|
|
37138
38451
|
message: status.message
|
|
37139
38452
|
};
|
|
37140
38453
|
}
|
|
38454
|
+
function normalizeAnalysisGuidance(guidance) {
|
|
38455
|
+
const trimmed = guidance?.trim();
|
|
38456
|
+
return trimmed ? trimmed : null;
|
|
38457
|
+
}
|
|
37141
38458
|
function normalizeFeedbackText(text) {
|
|
37142
38459
|
return text.trim().replace(/\s+/g, " ");
|
|
37143
38460
|
}
|
|
@@ -37239,12 +38556,14 @@ function skippedResult(reason) {
|
|
|
37239
38556
|
};
|
|
37240
38557
|
}
|
|
37241
38558
|
function buildFeedbackAnalysisPrompt(payload, options, attachments) {
|
|
38559
|
+
const guidance = normalizeAnalysisGuidance(payload.guidance);
|
|
37242
38560
|
const feedbackJson = JSON.stringify({
|
|
37243
38561
|
jobId: payload.jobId,
|
|
37244
38562
|
feedbackId: payload.feedbackId,
|
|
37245
38563
|
content: payload.content,
|
|
37246
38564
|
type: payload.type,
|
|
37247
38565
|
priority: payload.priority,
|
|
38566
|
+
guidance,
|
|
37248
38567
|
attachments: payload.attachments,
|
|
37249
38568
|
pageUrl: payload.pageUrl,
|
|
37250
38569
|
userAgent: payload.userAgent,
|
|
@@ -37287,6 +38606,7 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
|
|
|
37287
38606
|
- \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
|
|
37288
38607
|
- \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
|
|
37289
38608
|
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
|
|
38609
|
+
- \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
|
|
37290
38610
|
5. \u72B6\u6001\u89C4\u5219\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF1A
|
|
37291
38611
|
- status=skipped\uFF1A\u4EC5\u7528\u4E8E\u65E0\u610F\u4E49\u53CD\u9988\u3002
|
|
37292
38612
|
- 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
|
|
@@ -37296,6 +38616,9 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
|
|
|
37296
38616
|
\u53CD\u9988\uFF1A
|
|
37297
38617
|
${feedbackJson}
|
|
37298
38618
|
|
|
38619
|
+
\u7BA1\u7406\u5458\u8865\u5145\u8BF4\u660E\uFF1A
|
|
38620
|
+
${guidance ?? "\uFF08\u65E0\uFF09"}
|
|
38621
|
+
|
|
37299
38622
|
\u9644\u4EF6\u672C\u5730\u5316\u7ED3\u679C\uFF1A
|
|
37300
38623
|
${attachmentJson}
|
|
37301
38624
|
|
|
@@ -37523,14 +38846,14 @@ async function listModels(queryFn, opts = {}) {
|
|
|
37523
38846
|
}
|
|
37524
38847
|
|
|
37525
38848
|
// src/officeRuntimeSetup.ts
|
|
37526
|
-
import { execFile as
|
|
38849
|
+
import { execFile as execFile3 } from "child_process";
|
|
37527
38850
|
import crypto4 from "crypto";
|
|
37528
38851
|
import fsSync2 from "fs";
|
|
37529
38852
|
import fs22 from "fs/promises";
|
|
37530
38853
|
import os13 from "os";
|
|
37531
38854
|
import path31 from "path";
|
|
37532
|
-
import { promisify as
|
|
37533
|
-
var
|
|
38855
|
+
import { promisify as promisify3 } from "util";
|
|
38856
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
37534
38857
|
var logger38 = createModuleLogger("bridge.officeRuntimeSetup");
|
|
37535
38858
|
var REPO = "iOfficeAI/OfficeCLI";
|
|
37536
38859
|
var DEFAULT_VERSION = "v1.0.110";
|
|
@@ -37614,7 +38937,7 @@ async function sha256(filePath) {
|
|
|
37614
38937
|
}
|
|
37615
38938
|
async function runBestEffort(command, args) {
|
|
37616
38939
|
try {
|
|
37617
|
-
await
|
|
38940
|
+
await execFileAsync3(command, args);
|
|
37618
38941
|
return true;
|
|
37619
38942
|
} catch (error51) {
|
|
37620
38943
|
logger38.error("OfficeCLI best-effort command failed", {
|
|
@@ -38135,7 +39458,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
38135
39458
|
}
|
|
38136
39459
|
const skillStore = new SkillStore(config2.dataDir);
|
|
38137
39460
|
const currentBridgeKey = bridgeKeyForBridgeToken(config2.bridgeToken);
|
|
38138
|
-
const localSkillStore = new LocalSkillStore(config2.dataDir
|
|
39461
|
+
const localSkillStore = new LocalSkillStore(config2.dataDir);
|
|
38139
39462
|
skillStore.seed("log-analysis", LOG_ANALYSIS_SKILL);
|
|
38140
39463
|
const runtimeSkillSync = await syncRuntimeSkillsFromServer({
|
|
38141
39464
|
skillStore,
|
|
@@ -38311,6 +39634,10 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
38311
39634
|
traceId: payload.traceId
|
|
38312
39635
|
});
|
|
38313
39636
|
},
|
|
39637
|
+
onResumeReplySession: (payload) => ({
|
|
39638
|
+
type: "bridge:resume_reply_session_response",
|
|
39639
|
+
payload: agentManager.resumeReplySession(payload)
|
|
39640
|
+
}),
|
|
38314
39641
|
onConnected: async () => {
|
|
38315
39642
|
await agentRegistry.refresh();
|
|
38316
39643
|
await groupRegistry.refresh();
|