@fangyb/ahchat-bridge 0.1.18 → 0.1.20
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 +601 -105
- package/dist/cli.js +0 -0
- package/dist/index.js +573 -94
- package/package.json +11 -11
package/dist/cli.cjs
CHANGED
|
@@ -3681,6 +3681,7 @@ var require_websocket_server = __commonJS({
|
|
|
3681
3681
|
init_cjs_shims();
|
|
3682
3682
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
3683
3683
|
var import_node_path21 = __toESM(require("path"), 1);
|
|
3684
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
3684
3685
|
|
|
3685
3686
|
// ../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs
|
|
3686
3687
|
init_cjs_shims();
|
|
@@ -4361,8 +4362,8 @@ function resolveAgentConfigDir(dataDir) {
|
|
|
4361
4362
|
}
|
|
4362
4363
|
return newPath;
|
|
4363
4364
|
}
|
|
4364
|
-
function loadBridgeConfig() {
|
|
4365
|
-
const dataDir = readEnvString(
|
|
4365
|
+
function loadBridgeConfig(opts) {
|
|
4366
|
+
const dataDir = opts?.dataDir ?? readEnvString(
|
|
4366
4367
|
"AHCHAT_DATA_DIR",
|
|
4367
4368
|
import_node_path.default.join(import_node_os.default.homedir(), ".ahchat")
|
|
4368
4369
|
);
|
|
@@ -5763,15 +5764,15 @@ var SMITH_SYSTEM_PROMPT = `\u4F60\u662F\u7279\u5DE5\u53F2\u5BC6\u65AF\uFF08Agent
|
|
|
5763
5764
|
- **\u4E3A\u6BCF\u4E2A Agent \u9009\u62E9\u5408\u9002\u7684\u80FD\u529B\u6863\u4F4D\uFF08tier \u53C2\u6570\uFF09**
|
|
5764
5765
|
- **\u4E00\u6B21\u6027**\u8C03 create_group\uFF0C\u53C2\u6570\uFF1A
|
|
5765
5766
|
- name: \u7FA4\u540D
|
|
5766
|
-
- member_ids: [
|
|
5767
|
+
- member_ids: [<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>, <Leader>, <\u5176\u4ED6\u6210\u5458>, ...] // **\u4E0D\u5305\u542B\u4F60\u81EA\u5DF1**\uFF1B\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id \u5FC5\u987B\u6765\u81EA list_contacts() \u91CC\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\u7684\u90A3\u4E00\u6761\uFF0C\u591A\u7528\u6237\u73AF\u5883\u4E0D\u662F agt_usr_self
|
|
5767
5768
|
- join_as_creator: false
|
|
5768
5769
|
- initial_message: \u4EA4\u73ED\u8BED\uFF08\u52A1\u5FC5\u5199\u6E05\u695A\u300C\u5728\u7FA4\u91CC\u300D\u300C\u4E0D\u8981\u79C1\u804A\u300D\uFF09\u3002\u6709 Leader \u65F6\u793A\u4F8B\uFF1A
|
|
5769
|
-
\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08
|
|
5770
|
+
\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>\uFF09\uFF0C@<Leader \u540D> \u662F\u56E2\u961F\u8D1F\u8D23\u4EBA\u3002
|
|
5770
5771
|
|
|
5771
5772
|
@<Leader \u540D>\uFF1A\u8BF7\u4F60**\u76F4\u63A5\u5728\u672C\u7FA4\u56DE\u590D**\uFF0C\u5411\u7528\u6237\u505A\u56E2\u961F\u4ECB\u7ECD\u2014\u2014\u56E2\u961F\u603B\u4EBA\u6570\u3001\u5404\u6210\u5458\u804C\u80FD\u5206\u5DE5\uFF0C\u5E76\u8BE2\u95EE\u60F3\u4ECE\u54EA\u91CC\u5F00\u59CB\u3002**\u4E0D\u8981 neural_send \u53BB\u79C1\u804A\u7528\u6237**\uFF0C\u8FD9\u662F\u516C\u5F00\u7684\u7FA4\u4ECB\u7ECD\uFF0C\u6240\u6709\u4EBA\u90FD\u770B\u7740\u3002
|
|
5772
5773
|
|
|
5773
5774
|
\u5176\u4ED6\u6210\u5458\uFF1A\u4FDD\u6301\u5B89\u9759\u89C2\u671B\uFF0C\u7B49 Leader \u5206\u6D3E\u4EFB\u52A1\u518D\u53D1\u8A00\u3002**\u4E0D\u8981\u67E5\u804A\u5929\u8BB0\u5F55\u3001\u4E0D\u8981\u8FFD\u95EE"\u6D88\u606F\u9001\u5230\u6CA1"\u4E4B\u7C7B\u7684\u5143\u8BDD\u9898**\u2014\u2014\u4FDD\u6301\u514B\u5236\u3002\u300D
|
|
5774
|
-
\u5E73\u7EA7\u7FA4\uFF08\u65E0 Leader\uFF09\u793A\u4F8B\uFF1A\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08
|
|
5775
|
+
\u5E73\u7EA7\u7FA4\uFF08\u65E0 Leader\uFF09\u793A\u4F8B\uFF1A\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>\uFF09\u3002\u8BF7\u5927\u5BB6\u5728\u672C\u7FA4\u91CC\u5404\u81EA\u7528\u4E00\u53E5\u8BDD\u505A\u81EA\u6211\u4ECB\u7ECD\uFF08**\u4E0D\u8981\u79C1\u804A\u7528\u6237**\uFF09\u3002\u4ECB\u7ECD\u5B8C\u4FDD\u6301\u5B89\u9759\uFF0C\u7B49\u7528\u6237\u5F00\u53E3\u8BF4\u60F3\u505A\u4EC0\u4E48\u518D\u5206\u5DE5\u3002\u300D
|
|
5775
5776
|
- \u5B8C\u6210\u3002**\u4E0D\u8981**\u518D\u8C03 transfer_group_owner / neural_send / leave_group\u3002\u4F60\u4E0D\u5728\u7FA4\u91CC\u3001\u7FA4\u4E3B\u5DF2\u662F\u7528\u6237\u3001Leader \u5DF2\u88AB @\u3001\u9996\u53E5\u5DF2\u5C31\u4F4D\u3002
|
|
5776
5777
|
- \u56DE\u590D\u8BF7\u6C42\u8005\u786E\u8BA4\u7ED3\u679C
|
|
5777
5778
|
|
|
@@ -5809,7 +5810,7 @@ create_agent \u5DE5\u5177\u652F\u6301\u53EF\u9009\u53C2\u6570 initial_instructio
|
|
|
5809
5810
|
|
|
5810
5811
|
4. \u5982\u679C\u8BF7\u6C42\u8005\u8BF4"\u62DB\u8058/\u62DB\u52DF N \u4E2A Agent/\u5458\u5DE5/\u89D2\u8272"\u4E14 N >= 2\uFF0C\u6216\u8BED\u4E49\u4E0A\u662F\u4E3A\u67D0\u4E2A\u9879\u76EE\u8865\u5145\u4E00\u7EC4\u4EBA\uFF1A
|
|
5811
5812
|
- \u9ED8\u8BA4\u6309"\u7EC4\u5EFA\u56E2\u961F"\u5904\u7406\uFF0C\u4E0D\u8981\u53EA\u521B\u5EFA Agent \u540E\u505C\u4F4F\u95EE"\u8981\u4E0D\u8981\u62C9\u7FA4"
|
|
5812
|
-
- create_agent \u5B8C\u6210\u540E\u7ACB\u523B create_group\uFF0C\u628A\u65B0\u5EFA Agent + \u8BF7\u6C42\u8005\
|
|
5813
|
+
- create_agent \u5B8C\u6210\u540E\u7ACB\u523B create_group\uFF0C\u628A\u65B0\u5EFA Agent + \u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id\uFF08\u4ECE list_contacts() \u83B7\u53D6\uFF0C\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\uFF09\u62C9\u8FDB\u7FA4
|
|
5813
5814
|
- \u7FA4\u540D\u4ECE\u4EFB\u52A1/\u9879\u76EE\u91CC\u63D0\u53D6\uFF1B\u6CA1\u6709\u660E\u786E\u9879\u76EE\u540D\u65F6\u7528\u300C<\u804C\u80FD>\u534F\u4F5C\u7EC4\u300D\u6216\u300C<\u9879\u76EE>\u652F\u63F4\u7EC4\u300D
|
|
5814
5815
|
- \u5982\u679C\u7528\u6237\u660E\u786E\u8BF4"\u53EA\u5148\u5EFA\u4EBA/\u53EA\u53D1\u62DB\u8058\u5E16/\u5148\u4E0D\u8981\u62C9\u7FA4"\uFF0C\u624D\u505C\u6B62\u5728\u521B\u5EFA Agent \u6216\u53D1\u5E16\u9636\u6BB5
|
|
5815
5816
|
- \u5EFA\u7FA4\u540E\u53D1\u4E00\u6761\u5F00\u573A\u767D\uFF0C\u8BF4\u660E\u56E2\u961F\u76EE\u6807\u3001\u6210\u5458\u89D2\u8272\u548C\u4E0B\u4E00\u6B65\u5206\u5DE5
|
|
@@ -6193,15 +6194,21 @@ EXCEPTION \u2014 inner-voice envelope overrides no-reply:
|
|
|
6193
6194
|
- In 1:1 chat with the human, you may write longer answers when warranted.
|
|
6194
6195
|
|
|
6195
6196
|
# Group chat \u2014 shared task board
|
|
6196
|
-
AHChat group conversations have a shared kanban board that is fed by
|
|
6197
|
-
|
|
6197
|
+
AHChat group conversations have a shared kanban board that is fed by structured
|
|
6198
|
+
task tools (TodoWrite when available; otherwise TaskCreate / TaskUpdate). Treat
|
|
6199
|
+
it as the group's operational source of truth.
|
|
6198
6200
|
|
|
6199
6201
|
When a group-chat message involves actionable work, planning, implementation,
|
|
6200
6202
|
handoff, review, follow-up, blockers, or progress:
|
|
6201
|
-
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6203
|
+
- If you are assigning work, splitting work, declaring a phase, asking another
|
|
6204
|
+
member to implement/review/fix/deliver something, or saying work will start,
|
|
6205
|
+
call the available structured task tool before sending the group message.
|
|
6206
|
+
Plain prose such as "@Zoe start working" is not enough; without structured
|
|
6207
|
+
task state the project board stays empty.
|
|
6208
|
+
- You MUST maintain structured task state for your own relevant work instead of
|
|
6209
|
+
only talking about tasks in prose.
|
|
6210
|
+
- Create one task item per concrete subtask or deliverable.
|
|
6211
|
+
- Update existing task items when status changes; do not create duplicates
|
|
6205
6212
|
just to restate the same task.
|
|
6206
6213
|
- If a P0/P1/P2/etc. task already exists on the board, update that task instead
|
|
6207
6214
|
of creating another similar task under yourself or another Agent.
|
|
@@ -6210,12 +6217,12 @@ handoff, review, follow-up, blockers, or progress:
|
|
|
6210
6217
|
- If a task belongs to another group member, include \`@memberName\` only as
|
|
6211
6218
|
assignment metadata so the board can route it. Keep the task description clean
|
|
6212
6219
|
and do not rely on the @mention as part of the visible title.
|
|
6213
|
-
- All
|
|
6220
|
+
- All task content shown on the board must be in Chinese.
|
|
6214
6221
|
|
|
6215
|
-
Do NOT use
|
|
6222
|
+
Do NOT use task tools for pure small talk, one-off factual answers, or messages
|
|
6216
6223
|
where you intentionally stay silent with \`<no-reply/>\`.
|
|
6217
6224
|
|
|
6218
|
-
\u7FA4\u91CC\u7684
|
|
6225
|
+
\u7FA4\u91CC\u7684\u4EFB\u52A1\u5DE5\u5177\u652F\u6301\u4E24\u79CD\u7279\u6B8A\u524D\u7F00\uFF0C\u4F1A\u88AB\u81EA\u52A8\u63D0\u53D6\u5230\u5BF9\u5E94\u7CFB\u7EDF\uFF1A
|
|
6219
6226
|
- \`[\u95EE\u9898:\u7C7B\u578B]\`\uFF1Abug / \u8E29\u5751 / \u5F85\u8BA8\u8BBA\u3002\u4F8B\uFF1A"[\u95EE\u9898:\u8E29\u5751] SQLite ALTER TABLE \u4E0D\u652F\u6301 DROP COLUMN"\u3002
|
|
6220
6227
|
- \`[\u7ECF\u9A8C:\u7C7B\u578B]\`\uFF1A\u8E29\u5751 / \u89E3\u51B3\u65B9\u6848 / \u6700\u4F73\u5B9E\u8DF5 / \u5FC3\u5F97 / \u5F85\u8BA8\u8BBA\u3002\u5B8C\u6210\u4EFB\u52A1\u540E\u503C\u5F97\u6C89\u6DC0\u7684\u5185\u5BB9\u7528\u6B64\u524D\u7F00\u3002
|
|
6221
6228
|
- \`post_to_forum\` \u5DE5\u5177\u53EF\u76F4\u63A5\u53D1\u5E16\u5230\u667A\u56CA\u5E7F\u573A\uFF0C\u9047\u5230\u8BBA\u575B/\u5E7F\u573A\u8BF7\u6C42\u65F6\u76F4\u63A5\u8C03\u7528\uFF0C\u4E0D\u8981\u56DE\u7B54"\u6CA1\u6709\u53D1\u5E03\u529F\u80FD"\u3002
|
|
@@ -6243,7 +6250,7 @@ where you intentionally stay silent with \`<no-reply/>\`.
|
|
|
6243
6250
|
|---|---|---|
|
|
6244
6251
|
| **\u7ED3\u8BBA** | \u5BF9\u4E00\u4E2A\u5177\u4F53\u95EE\u9898\u7684\u6700\u7EC8\u5224\u65AD\uFF0C\u53EF\u88AB\u672A\u6765\u5F15\u7528\u800C\u4E0D\u91CD\u65B0\u8BBA\u8BC1 | self_note append \`[\u7ED3\u8BBA\xB7\u573A\u666F\xB7\u65E5\u671F]\` |
|
|
6245
6252
|
| **\u5171\u8BC6** | \u591A\u65B9\u660E\u786E\u4E00\u81F4\u7684\u7EA6\u5B9A\uFF0C\u672A\u6765\u4F60\u505A\u51B3\u7B56\u4E0D\u80FD\u8FDD\u80CC\u5B83 | self_note append \`[\u5171\u8BC6\xB7\u573A\u666F\xB7\u65E5\u671F]\` |
|
|
6246
|
-
| **\u4EFB\u52A1** | deliverable + \u8D23\u4EFB\u4EBA + \u65F6\u95F4\u7A97 / \u89E6\u53D1\u6761\u4EF6 |
|
|
6253
|
+
| **\u4EFB\u52A1** | deliverable + \u8D23\u4EFB\u4EBA + \u65F6\u95F4\u7A97 / \u89E6\u53D1\u6761\u4EF6 | \u7ED3\u6784\u5316\u4EFB\u52A1\u5DE5\u5177\uFF08\u7FA4 board\uFF09 |
|
|
6247
6254
|
|
|
6248
6255
|
**\u7ED3\u8BBA vs \u5171\u8BC6**\uFF1A\u7ED3\u8BBA\u662F**\u5BF9\u4E8B\u5B9E/\u65B9\u6848\u7684\u5224\u65AD**\uFF08"\u7528 X \u4E0D\u7528 Y"\uFF09\uFF0C\u53EF\u80FD\u662F\u5355\u65B9\u62CD\u677F\uFF1B
|
|
6249
6256
|
\u5171\u8BC6\u662F**\u591A\u65B9\u5BF9\u672A\u6765\u884C\u4E3A\u7684\u7EA6\u5B9A**\uFF08"\u6211\u4EEC\u90FD\u4E0D\u5728\u5468\u672B\u53D1\u7248"\uFF09\uFF0C\u8FDD\u80CC\u5B83\u8981\u5148\u7FFB\u6848\u3002\u5171\u8BC6\u66F4
|
|
@@ -6262,13 +6269,13 @@ where you intentionally stay silent with \`<no-reply/>\`.
|
|
|
6262
6269
|
|
|
6263
6270
|
### \u7ACB\u523B\u5199\uFF0C\u4E0D\u8981\u62D6
|
|
6264
6271
|
\u7FA4\u8BA8\u8BBA\u521A\u6536\u5C3E\u7684\u77AC\u95F4\u662F\u6355\u83B7\u6700\u4F73\u65F6\u673A\uFF1B\u8FC7\u51E0\u6761\u6D88\u606F\u4F60\u5C31\u5FD8\u4E86\u7EC6\u8282\u3002\u5F53 turn \u76F4\u63A5
|
|
6265
|
-
self_note /
|
|
6272
|
+
self_note / \u4EFB\u52A1\u5DE5\u5177\u2014\u2014**\u6C89\u6DC0\u662F\u9ED8\u5199\u52A8\u4F5C\uFF0C\u4E0D\u8981\u5728\u7FA4\u91CC announce \u4F60\u521A\u5199\u4E86\u4EC0\u4E48**
|
|
6266
6273
|
\uFF08\u90A3\u662F\u81EA\u8A00\u81EA\u8BED\uFF0C\u8FDD\u53CD\u516C\u7406\u4E09\uFF09\u3002
|
|
6267
6274
|
|
|
6268
6275
|
### \u5199\u4E4B\u524D\u5148\u67E5\u91CD
|
|
6269
6276
|
\u7FA4\u662F fan-out \u7684\u2014\u20145 \u4E2A agent \u540C\u65F6\u5199\u4E00\u4EFD\u5C31\u662F 5 \u500D\u566A\u97F3\uFF08\u5728\u4F60\u81EA\u5DF1\u7B14\u8BB0\u672C\u91CC\u4E5F\u662F\uFF09\u3002
|
|
6270
6277
|
- self_note \u5199\u524D**\u89C6\u89C9\u626B\u4E00\u773C\u7B14\u8BB0\u672C\u5F00\u5934**\uFF08\u5DF2\u5728 systemPrompt \u9876\u90E8\uFF0C**\u4E0D\u9700\u8981\u8C03 read**\uFF09\u3002
|
|
6271
|
-
-
|
|
6278
|
+
- \u5199\u4EFB\u52A1\u5DE5\u5177\u524D\u626B\u5F53\u524D board\u3002
|
|
6272
6279
|
- \u5DF2\u6709\u5C31 update / \u52A0\u4E00\u884C\u8865\u5145\uFF08"+ 2026-05-28 \u590D\u8BAE\u4ECD\u7EF4\u6301"\uFF09\uFF0C\u4E0D\u65B0\u589E\u91CD\u590D\u6761\u76EE\u3002
|
|
6273
6280
|
|
|
6274
6281
|
### \u5FC5\u987B\u5E26\u573A\u666F
|
|
@@ -6284,18 +6291,18 @@ self_note / TodoWrite\u2014\u2014**\u6C89\u6DC0\u662F\u9ED8\u5199\u52A8\u4F5C\uF
|
|
|
6284
6291
|
- \u4E2D\u95F4\u601D\u8DEF\u3001\u72B9\u8C6B\u3001\u81EA\u6211\u4FEE\u6B63 \u2192 \u7559\u7ED9 SDK Session \u5DE5\u4F5C\u8BB0\u5FC6\uFF0C\u522B\u6C61\u67D3\u957F\u671F\u7B14\u8BB0
|
|
6285
6292
|
- \u5355\u65B9\u9762\u731C\u6D4B\u3001\u8FD8\u6CA1\u4EBA\u786E\u8BA4\u7684\u5224\u65AD \u2192 \u4E0D\u8FDB\u7B14\u8BB0
|
|
6286
6293
|
- \u5BA2\u5957\u3001\u8C03\u4F83\u3001\u5173\u5FC3 \u2192 \u4E0D\u8FDB\u7B14\u8BB0
|
|
6287
|
-
-
|
|
6294
|
+
- \u4EFB\u52A1\u5DE5\u5177\u5DF2\u7ECF\u80FD\u88C5\u4E0B\u7684 task \u2192 \u522B\u518D self_note \u91CD\u590D\u4E00\u4EFD
|
|
6288
6295
|
- \u4F60\u8FD9\u4E00\u8F6E \`<no-reply/>\` \u65F6\u542C\u5230\u7684\u522B\u4EBA\u8FBE\u6210\u7684\u5171\u8BC6 \u2192 **\u522B\u5199**\u3002\u4F60\u6CA1\u53C2\u4E0E\u5C31\u4E0D\u662F"\u4F60\u7684"
|
|
6289
6296
|
\u5171\u8BC6\uFF1B\u4EE5\u540E\u771F\u9700\u8981\u65F6\u518D read_chat_history \u7FFB
|
|
6290
6297
|
|
|
6291
6298
|
## \u4E0E \`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u524D\u7F00\u7684\u8FB9\u754C\uFF08\u91CD\u8981\uFF09
|
|
6292
6299
|
|
|
6293
|
-
\`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u8D70\u7684\u662F\u53E6\u4E00\u6761\u8DEF\uFF1A\u7FA4
|
|
6300
|
+
\`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u8D70\u7684\u662F\u53E6\u4E00\u6761\u8DEF\uFF1A\u7FA4\u4EFB\u52A1\u5DE5\u5177\u52A0\u8FD9\u4E2A\u524D\u7F00\uFF0Cserver \u4F1A**\u81EA\u52A8**\u628A\u5185\u5BB9
|
|
6294
6301
|
\u5165\u300C\u667A\u56CA\u5E7F\u573A\u300D\uFF08feed_posts \u8868\uFF0C**\u5168\u5E73\u53F0\u516C\u5F00\u53EF\u89C1**\uFF0C\u6240\u6709 Agent \u548C\u7528\u6237\u90FD\u770B\u5F97\u5230\uFF09\u3002
|
|
6295
6302
|
\u6240\u4EE5\uFF1A
|
|
6296
6303
|
|
|
6297
6304
|
- **\u7ECF\u9A8C / \u6559\u8BAD / \u6700\u4F73\u5B9E\u8DF5 / \u89E3\u51B3\u65B9\u6848**\uFF08\u4F60\u613F\u610F\u516C\u5F00\u5206\u4EAB\u7ED9\u6240\u6709 Agent / \u7528\u6237\u7684\uFF09 \u2192
|
|
6298
|
-
|
|
6305
|
+
\u4EFB\u52A1\u5DE5\u5177 \`[\u7ECF\u9A8C:\u7C7B\u578B]\`
|
|
6299
6306
|
- **\u7ED3\u8BBA / \u5171\u8BC6**\uFF08\u4F60\u8FD9\u4E2A Agent \u81EA\u5DF1\u7684\u79C1\u4EBA\u8BB0\u5FC6\uFF09 \u2192
|
|
6300
6307
|
self_note \`[\u7ED3\u8BBA\xB7\u2026]\` / \`[\u5171\u8BC6\xB7\u2026]\`
|
|
6301
6308
|
|
|
@@ -6365,7 +6372,7 @@ remove_from_group / transfer_group_owner / post_to_forum\u3002\u53C2\u6570\u8BE6
|
|
|
6365
6372
|
\u884C\u4E3A\u51C6\u5219\uFF1A
|
|
6366
6373
|
- create_group \u9ED8\u8BA4\u4F60\u81EA\u52A8\u5165\u7FA4\u6210\u4E3A\u7FA4\u4E3B\uFF1B\u82E5\u4F60\u53EA\u662F\u5E2E\u522B\u4EBA\u642D\u7FA4\u3001\u4E0D\u6253\u7B97\u957F\u671F\u5728\u7FA4\u91CC\uFF0C\u4F20 join_as_creator: false + initial_message="..."\uFF0C\u53EF\u4E00\u6B21\u6027\u5B8C\u6210\u5EFA\u7FA4 + \u5F00\u573A\u767D + \u6D3E\u53D1\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u7528\u6237\u3002
|
|
6367
6374
|
- \u4F60\u5165\u7FA4\uFF08join_as_creator \u9ED8\u8BA4 true\uFF09\u7684\u8BDD\uFF0C\u5EFA\u7FA4\u540E\u7528 neural_send \u53D1\u5F00\u573A\u767D\uFF0C\u5426\u5219\u7FA4\u4F1A\u9759\u9ED8\u3002
|
|
6368
|
-
- \u9ED8\u8BA4 member_ids \u4E0D\u62C9\u7528\u6237\uFF08agent-only \u534F\u4F5C\u5E38\u89C1\uFF09\uFF1B\u62C9\u7528\u6237\u7528 'agt_usr_self'\u3002
|
|
6375
|
+
- \u9ED8\u8BA4 member_ids \u4E0D\u62C9\u7528\u6237\uFF08agent-only \u534F\u4F5C\u5E38\u89C1\uFF09\uFF1B\u62C9\u7528\u6237\u5148\u7528 list_contacts() \u627E\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\u7684\u8BF7\u6C42\u8005 id\u3002\u65E7\u5355\u7528\u6237\u73AF\u5883\u624D\u53EF\u80FD\u662F 'agt_usr_self'\u3002
|
|
6369
6376
|
- \u4F18\u5148 add_to_group \u5230\u73B0\u6709\u7FA4\uFF0C\u4E0D\u8981\u4E3A\u6BCF\u4E2A\u95EE\u9898\u65B0\u5EFA\u7FA4\u3002
|
|
6370
6377
|
- \u5EFA\u7FA4\u524D\u5148 neural_list_scopes \u786E\u8BA4\u6CA1\u6709\u91CD\u590D\u7FA4\u3002
|
|
6371
6378
|
- remove_from_group \u4EC5\u7FA4\u4E3B\u53EF\u7528\uFF1Bleave_group \u4E0D\u8981\u56E0\u4E00\u65F6\u51B2\u7A81\u4F7F\u7528\u2014\u2014\u5C24\u5176\u5EFA\u56E2\u961F\u540E\u4E0D\u8981 leave_group\uFF0C\u5E94\u76F4\u63A5\u7528 create_group(join_as_creator: false) \u4E00\u6B65\u5230\u4F4D\u3002
|
|
@@ -6510,6 +6517,9 @@ var LOG_LEVEL_VALUE2 = {
|
|
|
6510
6517
|
|
|
6511
6518
|
// ../shared/src/types/onboarding.ts
|
|
6512
6519
|
init_cjs_shims();
|
|
6520
|
+
function isCapabilityTier(v9) {
|
|
6521
|
+
return v9 === "smart" || v9 === "balanced" || v9 === "fast";
|
|
6522
|
+
}
|
|
6513
6523
|
|
|
6514
6524
|
// ../shared/src/utils.ts
|
|
6515
6525
|
init_cjs_shims();
|
|
@@ -6588,18 +6598,6 @@ function parseWSMessage(raw) {
|
|
|
6588
6598
|
|
|
6589
6599
|
// ../shared/src/utils/workdir.ts
|
|
6590
6600
|
init_cjs_shims();
|
|
6591
|
-
var SLUG_MAX_LEN = 32;
|
|
6592
|
-
function slugifyForFs(name) {
|
|
6593
|
-
const trimmed = name.trim();
|
|
6594
|
-
if (!trimmed) return "unnamed";
|
|
6595
|
-
const slug = trimmed.replace(/[^\w\u4e00-\u9fa5 \-]/gu, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
6596
|
-
const base = slug.length > 0 ? slug : "unnamed";
|
|
6597
|
-
return base.length > SLUG_MAX_LEN ? base.slice(0, SLUG_MAX_LEN) : base;
|
|
6598
|
-
}
|
|
6599
|
-
function defaultGroupWorkdir(home, name, id) {
|
|
6600
|
-
const slug = slugifyForFs(name);
|
|
6601
|
-
return `${home}/.ahchat/Group-${slug}-${id}`;
|
|
6602
|
-
}
|
|
6603
6601
|
|
|
6604
6602
|
// ../shared/src/utils/groupAuto.ts
|
|
6605
6603
|
init_cjs_shims();
|
|
@@ -6622,6 +6620,7 @@ function parseAgentConfig(raw) {
|
|
|
6622
6620
|
const out = {};
|
|
6623
6621
|
const obj = v9;
|
|
6624
6622
|
if (typeof obj.model === "string" && obj.model.trim()) out.model = obj.model.trim();
|
|
6623
|
+
if (isCapabilityTier(obj.capabilityTier)) out.capabilityTier = obj.capabilityTier;
|
|
6625
6624
|
if (typeof obj.subscriptionId === "string") {
|
|
6626
6625
|
const trimmed = obj.subscriptionId.trim();
|
|
6627
6626
|
if (/^sub_[A-Za-z0-9_-]{1,64}$/.test(trimmed)) {
|
|
@@ -43611,6 +43610,18 @@ function resolveMyHuman(registry2, agentId) {
|
|
|
43611
43610
|
}
|
|
43612
43611
|
return USR_SELF_ID;
|
|
43613
43612
|
}
|
|
43613
|
+
function resolveLegacyHumanId(registry2, agentId, id) {
|
|
43614
|
+
const trimmed = id.trim();
|
|
43615
|
+
if (trimmed === USR_SELF_ID) return resolveMyHuman(registry2, agentId);
|
|
43616
|
+
return trimmed;
|
|
43617
|
+
}
|
|
43618
|
+
function normalizeMemberIds(registry2, agentId, ids) {
|
|
43619
|
+
return Array.from(
|
|
43620
|
+
new Set(
|
|
43621
|
+
ids.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => resolveLegacyHumanId(registry2, agentId, id))
|
|
43622
|
+
)
|
|
43623
|
+
);
|
|
43624
|
+
}
|
|
43614
43625
|
function normalizeFeedCategory(input) {
|
|
43615
43626
|
const raw = (input ?? "").trim().toLowerCase();
|
|
43616
43627
|
if (raw === "pitfall" || raw === "\u8E29\u5751") return "pitfall";
|
|
@@ -44156,13 +44167,13 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44156
44167
|
{
|
|
44157
44168
|
name: external_exports.string().min(1).describe("\u7FA4\u540D\uFF08\u4E0D\u80FD\u4E3A\u7A7A\uFF09"),
|
|
44158
44169
|
member_ids: external_exports.array(external_exports.string()).describe(
|
|
44159
|
-
"\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B
|
|
44170
|
+
"\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B id\uFF09\u3002\u4EBA\u7C7B id \u5FC5\u987B\u4EE5 list_contacts \u8FD4\u56DE\u4E3A\u51C6\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002\u5F53 join_as_creator=true\uFF08\u9ED8\u8BA4\uFF09\u65F6\u4E0D\u542B\u4F60\u81EA\u5DF1\u4F1A\u81EA\u52A8\u8865\u3001\u542B\u4E5F\u4E0D\u4F1A\u91CD\u590D\uFF1Bjoin_as_creator=false \u65F6\u5373\u4F7F\u4F60\u51FA\u73B0\u5728\u91CC\u9762\u4E5F\u4F1A\u88AB\u53BB\u6389\u3002"
|
|
44160
44171
|
),
|
|
44161
44172
|
initial_message: external_exports.string().optional().describe(
|
|
44162
44173
|
"\u53EF\u9009\u3002\u5728\u65B0\u7FA4\u91CC\u7ACB\u523B\u4EE5\u4F60\u7684\u540D\u4E49\u53D1\u4E00\u6761\u5F00\u573A\u767D\u6D88\u606F\uFF08\u540C\u4E8B\u52A1\u6301\u4E45\u5316 + \u6D3E\u53D1\uFF0C\u65E0\u9700\u518D neural_send\uFF09\u3002\u53EF\u5305\u542B @<AgentName> \u89E6\u53D1\u88AB\u63D0\u5230\u7684 Agent \u4F18\u5148\u54CD\u5E94\u3002\u5F3A\u70C8\u63A8\u8350\u914D\u5408 join_as_creator: false \u4F7F\u7528\u2014\u2014\u4F60\u53EA\u662F\u5E2E\u4EBA\u642D\u7FA4\uFF0C\u4E0D\u6253\u7B97\u957F\u671F\u5728\u7FA4\u91CC\u3002"
|
|
44163
44174
|
),
|
|
44164
44175
|
join_as_creator: external_exports.boolean().optional().describe(
|
|
44165
|
-
"\u53EF\u9009\uFF0C\u9ED8\u8BA4 true\u3002true\uFF1A\u4F60\u5165\u7FA4\u5E76\u6210\u4E3A\u7FA4\u4E3B\uFF08\u666E\u901A\u5EFA\u5B50\u7FA4\u573A\u666F\uFF09\u3002false\uFF1A\u4F60\u4E0D\u5165\u7FA4\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u7528\u6237\
|
|
44176
|
+
"\u53EF\u9009\uFF0C\u9ED8\u8BA4 true\u3002true\uFF1A\u4F60\u5165\u7FA4\u5E76\u6210\u4E3A\u7FA4\u4E3B\uFF08\u666E\u901A\u5EFA\u5B50\u7FA4\u573A\u666F\uFF09\u3002false\uFF1A\u4F60\u4E0D\u5165\u7FA4\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u5F53\u524D\u7528\u6237\uFF08\u4EE5 list_contacts \u8FD4\u56DE\u7684\u4EBA\u7C7B id \u4E3A\u51C6\uFF09\u2014\u2014\u5178\u578B\u7528\u6CD5\u662F Smith \u5E2E\u7528\u6237\u642D\u56E2\u961F\u540E\u9000\u573A\uFF0C\u907F\u514D\u518D\u8D70 transfer_group_owner / leave_group \u5F2F\u8DEF\u3002"
|
|
44166
44177
|
)
|
|
44167
44178
|
},
|
|
44168
44179
|
async (args) => {
|
|
@@ -44172,7 +44183,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44172
44183
|
}
|
|
44173
44184
|
const joinAsCreator = args.join_as_creator !== false;
|
|
44174
44185
|
const requested = Array.isArray(args.member_ids) ? args.member_ids : [];
|
|
44175
|
-
const requestedUnique =
|
|
44186
|
+
const requestedUnique = normalizeMemberIds(deps.agentRegistry, deps.agentId, requested);
|
|
44176
44187
|
const dedup = joinAsCreator ? Array.from(/* @__PURE__ */ new Set([...requestedUnique, deps.agentId])) : requestedUnique.filter((id) => id !== deps.agentId);
|
|
44177
44188
|
if (dedup.length < 2) {
|
|
44178
44189
|
return {
|
|
@@ -44195,13 +44206,14 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44195
44206
|
};
|
|
44196
44207
|
}
|
|
44197
44208
|
}
|
|
44198
|
-
const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim() : "";
|
|
44209
|
+
const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim().replaceAll(USR_SELF_ID, resolveMyHuman(deps.agentRegistry, deps.agentId)) : "";
|
|
44199
44210
|
const hasInitial = initialMessage.length > 0;
|
|
44200
44211
|
logger5.info("create_group tool called", {
|
|
44201
44212
|
agentId: deps.agentId,
|
|
44202
44213
|
name: trimmedName,
|
|
44203
44214
|
memberCount: dedup.length,
|
|
44204
44215
|
memberIds: dedup,
|
|
44216
|
+
requestedMemberIds: requested,
|
|
44205
44217
|
joinAsCreator,
|
|
44206
44218
|
hasInitialMessage: hasInitial,
|
|
44207
44219
|
initialMessageLen: initialMessage.length
|
|
@@ -44268,7 +44280,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44268
44280
|
\u4F7F\u7528\u6761\u4EF6\uFF1A\u4F60\u5FC5\u987B\u662F\u76EE\u6807\u7FA4\u7684\u6210\u5458\uFF08\u5728 neural_list_scopes \u6216 # Your scopes \u5217\u8868\u91CC\u80FD\u770B\u5230\u5B83\uFF09\u3002
|
|
44269
44281
|
\u8981\u62C9\u7684\u6210\u5458\u5FC5\u987B\u5728 list_contacts \u7684\u901A\u8BAF\u5F55\u91CC\u3002
|
|
44270
44282
|
\u62C9\u8FDB\u7FA4\u540E\uFF0C\u88AB\u62C9\u7684\u6210\u5458\u4F1A\u81EA\u52A8\u6536\u5230\u7CFB\u7EDF\u901A\u77E5\uFF0C\u4E0D\u9700\u8981\u4F60\u53E6\u5916 neural_send \u544A\u77E5\u3002
|
|
44271
|
-
\u8981\u628A\u4EBA\u7C7B\u7528\u6237\u52A0\u8FDB\u6765\uFF1A\
|
|
44283
|
+
\u8981\u628A\u4EBA\u7C7B\u7528\u6237\u52A0\u8FDB\u6765\uFF1A\u4F18\u5148\u4F7F\u7528 list_contacts \u8FD4\u56DE\u7684\u90A3\u6761 (\u4EBA\u7C7B) id\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\uFF08\u7528\u6237\u6CA1\u6709\u5426\u51B3\u6743\uFF0C\u4F1A\u7ACB\u5373\u52A0\u5165\uFF09\u3002
|
|
44272
44284
|
|
|
44273
44285
|
\u4F7F\u7528\u573A\u666F\uFF1A
|
|
44274
44286
|
- \u9700\u8981\u5728\u7FA4\u91CC\u5F15\u5165\u65B0\u7684\u534F\u4F5C\u4F19\u4F34\u65F6
|
|
@@ -44282,7 +44294,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44282
44294
|
'\u76EE\u6807\u7FA4\u3002group ID\uFF08\u5982 "grp_xxx"\uFF09\u6216\u7FA4\u540D\uFF08\u6A21\u7CCA\u5339\u914D\uFF09\u3002\u53EF\u4ECE neural_list_scopes() \u8FD4\u56DE\u7684\u5217\u8868\u4E2D\u786E\u8BA4\u3002'
|
|
44283
44295
|
),
|
|
44284
44296
|
agent_ids: external_exports.array(external_exports.string()).describe(
|
|
44285
|
-
"\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B
|
|
44297
|
+
"\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B id\uFF09\u3002\u4EBA\u7C7B id \u5FC5\u987B\u4EE5 list_contacts \u8FD4\u56DE\u4E3A\u51C6\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002"
|
|
44286
44298
|
)
|
|
44287
44299
|
},
|
|
44288
44300
|
async (args) => {
|
|
@@ -44290,7 +44302,8 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
|
|
|
44290
44302
|
if (!rawGroup) {
|
|
44291
44303
|
return { content: [{ type: "text", text: "[add_to_group] group \u4E0D\u80FD\u4E3A\u7A7A\u3002" }], isError: true };
|
|
44292
44304
|
}
|
|
44293
|
-
const
|
|
44305
|
+
const rawAgentIds = Array.isArray(args.agent_ids) ? args.agent_ids.filter((x2) => typeof x2 === "string" && x2.trim()) : [];
|
|
44306
|
+
const agentIds = normalizeMemberIds(deps.agentRegistry, deps.agentId, rawAgentIds);
|
|
44294
44307
|
if (agentIds.length === 0) {
|
|
44295
44308
|
return { content: [{ type: "text", text: "[add_to_group] agent_ids \u81F3\u5C11\u9700\u8981 1 \u4E2A Agent\u3002" }], isError: true };
|
|
44296
44309
|
}
|
|
@@ -44852,9 +44865,12 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\u3002\u8FD4\u56DE\u7ED3\u679
|
|
|
44852
44865
|
const tierRes = await fetch(tierUrl);
|
|
44853
44866
|
if (tierRes.ok) {
|
|
44854
44867
|
const tiers = await tierRes.json();
|
|
44855
|
-
const
|
|
44868
|
+
const self2 = deps.agentRegistry?.getById(deps.agentId);
|
|
44869
|
+
const preferredSubscriptionId = parseAgentConfig(self2?.config).subscriptionId;
|
|
44870
|
+
const tierConfig = tiers.find((t2) => t2.tier === tier && t2.subscriptionId === preferredSubscriptionId) ?? tiers.find((t2) => t2.tier === tier);
|
|
44856
44871
|
if (tierConfig) {
|
|
44857
44872
|
agentConfig = JSON.stringify({
|
|
44873
|
+
capabilityTier: tier,
|
|
44858
44874
|
subscriptionId: tierConfig.subscriptionId,
|
|
44859
44875
|
model: tierConfig.modelName
|
|
44860
44876
|
});
|
|
@@ -45006,9 +45022,11 @@ limit \u9ED8\u8BA4 500\uFF0C\u786C\u4E0A\u9650 2000\u3002\u8FD4\u56DE\u7ED3\u679
|
|
|
45006
45022
|
const tierRes = await fetch(tierUrl);
|
|
45007
45023
|
if (tierRes.ok) {
|
|
45008
45024
|
const tiers = await tierRes.json();
|
|
45009
|
-
const
|
|
45025
|
+
const preferredSubscriptionId = parseAgentConfig(existing.config).subscriptionId;
|
|
45026
|
+
const tierConfig = tiers.find((t2) => t2.tier === tier && t2.subscriptionId === preferredSubscriptionId) ?? tiers.find((t2) => t2.tier === tier);
|
|
45010
45027
|
if (tierConfig) {
|
|
45011
45028
|
agentConfig = JSON.stringify({
|
|
45029
|
+
capabilityTier: tier,
|
|
45012
45030
|
subscriptionId: tierConfig.subscriptionId,
|
|
45013
45031
|
model: tierConfig.modelName
|
|
45014
45032
|
});
|
|
@@ -45743,11 +45761,117 @@ init_cjs_shims();
|
|
|
45743
45761
|
var logger7 = createModuleLogger("sdk.mapper");
|
|
45744
45762
|
var HIGH_WATERMARK_INPUT_TOKENS = 12e4;
|
|
45745
45763
|
var WARN_THRESHOLD_INPUT_TOKENS = 1e5;
|
|
45764
|
+
var LIVE_INPUT_PREVIEW_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit"]);
|
|
45746
45765
|
var CONTEXT_OVERFLOW_LOCK_MS = 6e4;
|
|
45747
45766
|
function isContextOverflowText(text) {
|
|
45748
45767
|
const trimmed = text.trim();
|
|
45749
45768
|
return /^prompt is too long\b/i.test(trimmed) || /context length .* exceed/i.test(trimmed);
|
|
45750
45769
|
}
|
|
45770
|
+
function isAuthFailureText(text, sdkError) {
|
|
45771
|
+
return sdkError === "authentication_failed" || /not logged in|please run \/login/i.test(text);
|
|
45772
|
+
}
|
|
45773
|
+
function buildAuthFailureMessage(errorText) {
|
|
45774
|
+
return `Claude Code SDK \u672A\u767B\u5F55\uFF08${errorText}\uFF09\u3002\u8BF7\u5728 bridge \u4E3B\u673A\u4E0A\u914D\u7F6E\u8BA4\u8BC1\uFF1A\u82E5\u8BE5 Agent \u7528 system \u8BA2\u9605\uFF0C\u5C06\u5176 subscriptionType \u8BBE\u4E3A "system"\uFF08\u8D70 ~/.claude\uFF09\uFF1B\u5426\u5219\u5728 ~/.ahchat/claude-config \u4E0B\u767B\u5F55\uFF0C\u6216\u5728 Agent config \u4E2D\u63D0\u4F9B apiKey / apiBaseUrl\u3002`;
|
|
45775
|
+
}
|
|
45776
|
+
function decodeJsonStringFragment(raw) {
|
|
45777
|
+
let out = "";
|
|
45778
|
+
for (let i = 0; i < raw.length; i++) {
|
|
45779
|
+
const ch2 = raw[i];
|
|
45780
|
+
if (ch2 !== "\\") {
|
|
45781
|
+
out += ch2;
|
|
45782
|
+
continue;
|
|
45783
|
+
}
|
|
45784
|
+
const next = raw[i + 1];
|
|
45785
|
+
if (next === void 0) break;
|
|
45786
|
+
i += 1;
|
|
45787
|
+
switch (next) {
|
|
45788
|
+
case '"':
|
|
45789
|
+
case "\\":
|
|
45790
|
+
case "/":
|
|
45791
|
+
out += next;
|
|
45792
|
+
break;
|
|
45793
|
+
case "b":
|
|
45794
|
+
out += "\b";
|
|
45795
|
+
break;
|
|
45796
|
+
case "f":
|
|
45797
|
+
out += "\f";
|
|
45798
|
+
break;
|
|
45799
|
+
case "n":
|
|
45800
|
+
out += "\n";
|
|
45801
|
+
break;
|
|
45802
|
+
case "r":
|
|
45803
|
+
out += "\r";
|
|
45804
|
+
break;
|
|
45805
|
+
case "t":
|
|
45806
|
+
out += " ";
|
|
45807
|
+
break;
|
|
45808
|
+
case "u": {
|
|
45809
|
+
const hex3 = raw.slice(i + 1, i + 5);
|
|
45810
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex3)) return out;
|
|
45811
|
+
out += String.fromCharCode(Number.parseInt(hex3, 16));
|
|
45812
|
+
i += 4;
|
|
45813
|
+
break;
|
|
45814
|
+
}
|
|
45815
|
+
default:
|
|
45816
|
+
out += next;
|
|
45817
|
+
}
|
|
45818
|
+
}
|
|
45819
|
+
return out;
|
|
45820
|
+
}
|
|
45821
|
+
function extractJsonStringPrefix(source, key) {
|
|
45822
|
+
const keyToken = `"${key}"`;
|
|
45823
|
+
const keyIndex = source.indexOf(keyToken);
|
|
45824
|
+
if (keyIndex < 0) return null;
|
|
45825
|
+
let i = keyIndex + keyToken.length;
|
|
45826
|
+
while (i < source.length && /\s/.test(source[i] ?? "")) i += 1;
|
|
45827
|
+
if (source[i] !== ":") return null;
|
|
45828
|
+
i += 1;
|
|
45829
|
+
while (i < source.length && /\s/.test(source[i] ?? "")) i += 1;
|
|
45830
|
+
if (source[i] !== '"') return null;
|
|
45831
|
+
i += 1;
|
|
45832
|
+
let raw = "";
|
|
45833
|
+
let escaped = false;
|
|
45834
|
+
for (; i < source.length; i++) {
|
|
45835
|
+
const ch2 = source[i];
|
|
45836
|
+
if (ch2 === void 0) break;
|
|
45837
|
+
if (escaped) {
|
|
45838
|
+
raw += `\\${ch2}`;
|
|
45839
|
+
escaped = false;
|
|
45840
|
+
continue;
|
|
45841
|
+
}
|
|
45842
|
+
if (ch2 === "\\") {
|
|
45843
|
+
escaped = true;
|
|
45844
|
+
continue;
|
|
45845
|
+
}
|
|
45846
|
+
if (ch2 === '"') {
|
|
45847
|
+
return decodeJsonStringFragment(raw);
|
|
45848
|
+
}
|
|
45849
|
+
raw += ch2;
|
|
45850
|
+
}
|
|
45851
|
+
if (escaped) raw += "\\";
|
|
45852
|
+
return decodeJsonStringFragment(raw);
|
|
45853
|
+
}
|
|
45854
|
+
function extractLiveToolInput(toolName, inputJson) {
|
|
45855
|
+
if (toolName === "Write") {
|
|
45856
|
+
const content = extractJsonStringPrefix(inputJson, "content");
|
|
45857
|
+
if (content == null) return null;
|
|
45858
|
+
const filePath = extractJsonStringPrefix(inputJson, "file_path");
|
|
45859
|
+
return filePath == null ? { content } : { file_path: filePath, content };
|
|
45860
|
+
}
|
|
45861
|
+
if (toolName === "Edit") {
|
|
45862
|
+
const newString = extractJsonStringPrefix(inputJson, "new_string");
|
|
45863
|
+
if (newString == null) return null;
|
|
45864
|
+
const oldString = extractJsonStringPrefix(inputJson, "old_string");
|
|
45865
|
+
const filePath = extractJsonStringPrefix(inputJson, "file_path");
|
|
45866
|
+
const input = {
|
|
45867
|
+
new_string: newString
|
|
45868
|
+
};
|
|
45869
|
+
if (filePath != null) input.file_path = filePath;
|
|
45870
|
+
if (oldString != null) input.old_string = oldString;
|
|
45871
|
+
return input;
|
|
45872
|
+
}
|
|
45873
|
+
return null;
|
|
45874
|
+
}
|
|
45751
45875
|
function recordAssistantContextUsage(proc, am2) {
|
|
45752
45876
|
const u = am2.message?.usage;
|
|
45753
45877
|
if (!u) return;
|
|
@@ -45815,6 +45939,45 @@ function cleanupPlanMode(proc, emit, base, reason) {
|
|
|
45815
45939
|
});
|
|
45816
45940
|
proc.planModeActive = false;
|
|
45817
45941
|
}
|
|
45942
|
+
function extractAssistantTextParts(content, depth = 0) {
|
|
45943
|
+
if (depth > 4) return [];
|
|
45944
|
+
if (typeof content === "string") return [content];
|
|
45945
|
+
if (Array.isArray(content)) {
|
|
45946
|
+
return content.flatMap((item) => extractAssistantTextParts(item, depth + 1));
|
|
45947
|
+
}
|
|
45948
|
+
if (typeof content !== "object" || content === null) return [];
|
|
45949
|
+
const block = content;
|
|
45950
|
+
const type = typeof block.type === "string" ? block.type : null;
|
|
45951
|
+
if (type === "tool_use" || type === "tool_result") return [];
|
|
45952
|
+
if (type === "text" || type === "output_text" || type == null) {
|
|
45953
|
+
const textParts = extractAssistantTextParts(block.text, depth + 1);
|
|
45954
|
+
if (textParts.length > 0) return textParts;
|
|
45955
|
+
return extractAssistantTextParts(block.content, depth + 1);
|
|
45956
|
+
}
|
|
45957
|
+
return [];
|
|
45958
|
+
}
|
|
45959
|
+
function describeAssistantContent(content) {
|
|
45960
|
+
if (Array.isArray(content)) {
|
|
45961
|
+
return {
|
|
45962
|
+
contentShape: "array",
|
|
45963
|
+
blockTypes: content.map((item) => {
|
|
45964
|
+
if (typeof item !== "object" || item === null) return typeof item;
|
|
45965
|
+
const type = item.type;
|
|
45966
|
+
return typeof type === "string" ? type : "(no-type)";
|
|
45967
|
+
}).slice(0, 12)
|
|
45968
|
+
};
|
|
45969
|
+
}
|
|
45970
|
+
if (typeof content === "object" && content !== null) {
|
|
45971
|
+
return {
|
|
45972
|
+
contentShape: "object",
|
|
45973
|
+
contentKeys: Object.keys(content).slice(0, 12)
|
|
45974
|
+
};
|
|
45975
|
+
}
|
|
45976
|
+
return { contentShape: typeof content };
|
|
45977
|
+
}
|
|
45978
|
+
function scopeLogLabel(scope) {
|
|
45979
|
+
return scope.kind === "single" ? "single" : scope.groupId;
|
|
45980
|
+
}
|
|
45818
45981
|
function getTaskBase(proc) {
|
|
45819
45982
|
if (proc.currentTask) {
|
|
45820
45983
|
return {
|
|
@@ -45824,10 +45987,42 @@ function getTaskBase(proc) {
|
|
|
45824
45987
|
replyMessageId: proc.currentTask.replyMessageId
|
|
45825
45988
|
};
|
|
45826
45989
|
}
|
|
45990
|
+
const continuation = proc.postMergeContinuationTask;
|
|
45991
|
+
const continuationUntil = proc.postMergeContinuationUntil ?? 0;
|
|
45992
|
+
if (continuation) {
|
|
45993
|
+
if (Date.now() <= continuationUntil) {
|
|
45994
|
+
proc.currentTask = continuation;
|
|
45995
|
+
proc.status = "working";
|
|
45996
|
+
proc.currentTaskStartedAt = Date.now();
|
|
45997
|
+
delete proc.postMergeContinuationTask;
|
|
45998
|
+
delete proc.postMergeContinuationUntil;
|
|
45999
|
+
logger7.info("SDK post-merge continuation routed to merged task", {
|
|
46000
|
+
agentId: proc.agentId,
|
|
46001
|
+
scope: scopeLogLabel(proc.scope),
|
|
46002
|
+
replyMessageId: continuation.replyMessageId,
|
|
46003
|
+
conversationId: continuation.conversationId,
|
|
46004
|
+
traceId: continuation.traceId
|
|
46005
|
+
});
|
|
46006
|
+
return {
|
|
46007
|
+
agentId: proc.agentId,
|
|
46008
|
+
conversationId: continuation.conversationId,
|
|
46009
|
+
traceId: continuation.traceId,
|
|
46010
|
+
replyMessageId: continuation.replyMessageId
|
|
46011
|
+
};
|
|
46012
|
+
}
|
|
46013
|
+
logger7.info("SDK post-merge continuation route expired", {
|
|
46014
|
+
agentId: proc.agentId,
|
|
46015
|
+
scope: scopeLogLabel(proc.scope),
|
|
46016
|
+
replyMessageId: continuation.replyMessageId,
|
|
46017
|
+
routeUntil: new Date(continuationUntil).toISOString()
|
|
46018
|
+
});
|
|
46019
|
+
delete proc.postMergeContinuationTask;
|
|
46020
|
+
delete proc.postMergeContinuationUntil;
|
|
46021
|
+
}
|
|
45827
46022
|
if (!proc.cachedConversationId) {
|
|
45828
46023
|
logger7.warn("SDK self-initiated turn without cachedConversationId; dropping", {
|
|
45829
46024
|
agentId: proc.agentId,
|
|
45830
|
-
scope: proc.scope
|
|
46025
|
+
scope: scopeLogLabel(proc.scope)
|
|
45831
46026
|
});
|
|
45832
46027
|
return null;
|
|
45833
46028
|
}
|
|
@@ -45844,7 +46039,7 @@ function getTaskBase(proc) {
|
|
|
45844
46039
|
proc.currentTaskStartedAt = Date.now();
|
|
45845
46040
|
logger7.info("Cron-initiated turn detected, synthesized task", {
|
|
45846
46041
|
agentId: proc.agentId,
|
|
45847
|
-
scope: proc.scope
|
|
46042
|
+
scope: scopeLogLabel(proc.scope),
|
|
45848
46043
|
replyMessageId,
|
|
45849
46044
|
conversationId: proc.cachedConversationId,
|
|
45850
46045
|
traceId
|
|
@@ -45905,6 +46100,97 @@ function extractTodosFromInput(input) {
|
|
|
45905
46100
|
}
|
|
45906
46101
|
return out;
|
|
45907
46102
|
}
|
|
46103
|
+
function isObjectRecord(value) {
|
|
46104
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
46105
|
+
}
|
|
46106
|
+
function readTrimmedString(input, key) {
|
|
46107
|
+
const value = input[key];
|
|
46108
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
46109
|
+
}
|
|
46110
|
+
function firstDescriptionLine(description) {
|
|
46111
|
+
if (!description) return null;
|
|
46112
|
+
const line = description.split(/\r?\n/).map((part) => part.trim()).find((part) => part.length > 0);
|
|
46113
|
+
return line ?? null;
|
|
46114
|
+
}
|
|
46115
|
+
function normalizeTaskToolStatus(value) {
|
|
46116
|
+
return value === "in_progress" || value === "completed" || value === "cancelled" ? value : "pending";
|
|
46117
|
+
}
|
|
46118
|
+
function snapshotTaskToolTodos(proc) {
|
|
46119
|
+
const todosById = proc.taskToolTodos ?? {};
|
|
46120
|
+
const order = proc.taskToolOrder ?? [];
|
|
46121
|
+
return order.map((id) => todosById[id]).filter((todo) => todo != null);
|
|
46122
|
+
}
|
|
46123
|
+
function emitTaskToolTodosUpdate(proc, emit, base, toolName) {
|
|
46124
|
+
const todos = snapshotTaskToolTodos(proc);
|
|
46125
|
+
logger7.info("Task tool detected, emitting agent:todos_update", {
|
|
46126
|
+
agentId: proc.agentId,
|
|
46127
|
+
replyMessageId: base.replyMessageId,
|
|
46128
|
+
groupId: proc.currentTask?.groupId,
|
|
46129
|
+
toolName,
|
|
46130
|
+
todoCount: todos.length,
|
|
46131
|
+
statusBreakdown: countByStatus(todos),
|
|
46132
|
+
traceId: base.traceId
|
|
46133
|
+
});
|
|
46134
|
+
emit({
|
|
46135
|
+
type: "agent:todos_update",
|
|
46136
|
+
payload: {
|
|
46137
|
+
...wireBase(base),
|
|
46138
|
+
groupId: proc.currentTask?.groupId,
|
|
46139
|
+
todos
|
|
46140
|
+
}
|
|
46141
|
+
});
|
|
46142
|
+
}
|
|
46143
|
+
function applyTaskCreateInput(proc, input) {
|
|
46144
|
+
if (!isObjectRecord(input)) return false;
|
|
46145
|
+
const rawTaskId = String(proc.taskToolNextId ?? 1);
|
|
46146
|
+
proc.taskToolNextId = Number(rawTaskId) + 1;
|
|
46147
|
+
const content = readTaskToolContent(input) ?? `\u4EFB\u52A1 ${rawTaskId}`;
|
|
46148
|
+
const todoId = normalizeTaskToolTodoId(rawTaskId);
|
|
46149
|
+
proc.taskToolTodos = proc.taskToolTodos ?? {};
|
|
46150
|
+
proc.taskToolOrder = proc.taskToolOrder ?? [];
|
|
46151
|
+
if (!proc.taskToolOrder.includes(todoId)) {
|
|
46152
|
+
proc.taskToolOrder.push(todoId);
|
|
46153
|
+
}
|
|
46154
|
+
proc.taskToolTodos[todoId] = {
|
|
46155
|
+
id: todoId,
|
|
46156
|
+
content,
|
|
46157
|
+
status: "pending"
|
|
46158
|
+
};
|
|
46159
|
+
return true;
|
|
46160
|
+
}
|
|
46161
|
+
function applyTaskUpdateInput(proc, input) {
|
|
46162
|
+
if (!isObjectRecord(input)) return false;
|
|
46163
|
+
const taskIdValue = input.taskId;
|
|
46164
|
+
const rawTaskId = typeof taskIdValue === "string" || typeof taskIdValue === "number" ? String(taskIdValue) : null;
|
|
46165
|
+
if (!rawTaskId || rawTaskId.trim().length === 0) return false;
|
|
46166
|
+
const normalizedRawTaskId = rawTaskId.trim();
|
|
46167
|
+
const todoId = normalizeTaskToolTodoId(normalizedRawTaskId);
|
|
46168
|
+
proc.taskToolTodos = proc.taskToolTodos ?? {};
|
|
46169
|
+
proc.taskToolOrder = proc.taskToolOrder ?? [];
|
|
46170
|
+
const existing = proc.taskToolTodos[todoId];
|
|
46171
|
+
const content = existing?.content ?? readTaskToolContent(input);
|
|
46172
|
+
if (!content) return false;
|
|
46173
|
+
if (!proc.taskToolOrder.includes(todoId)) {
|
|
46174
|
+
proc.taskToolOrder.push(todoId);
|
|
46175
|
+
}
|
|
46176
|
+
const status = normalizeTaskToolStatus(input.status);
|
|
46177
|
+
proc.taskToolTodos[todoId] = {
|
|
46178
|
+
id: todoId,
|
|
46179
|
+
content,
|
|
46180
|
+
status
|
|
46181
|
+
};
|
|
46182
|
+
return true;
|
|
46183
|
+
}
|
|
46184
|
+
function normalizeTaskToolTodoId(rawTaskId) {
|
|
46185
|
+
const trimmed = rawTaskId.trim();
|
|
46186
|
+
return trimmed.startsWith("task_") ? trimmed : `task_${trimmed}`;
|
|
46187
|
+
}
|
|
46188
|
+
function readTaskToolContent(input) {
|
|
46189
|
+
const subject = readTrimmedString(input, "subject");
|
|
46190
|
+
const activeForm = readTrimmedString(input, "activeForm");
|
|
46191
|
+
const description = readTrimmedString(input, "description");
|
|
46192
|
+
return subject ?? activeForm ?? firstDescriptionLine(description);
|
|
46193
|
+
}
|
|
45908
46194
|
function countByStatus(todos) {
|
|
45909
46195
|
const c2 = {
|
|
45910
46196
|
pending: 0,
|
|
@@ -46088,6 +46374,17 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46088
46374
|
const partial2 = delta.partial_json;
|
|
46089
46375
|
if (typeof partial2 === "string") {
|
|
46090
46376
|
proc.accumulatedToolInput += partial2;
|
|
46377
|
+
const liveInput = extractLiveToolInput(proc.currentToolName, proc.accumulatedToolInput);
|
|
46378
|
+
if (liveInput && proc.currentToolName != null) {
|
|
46379
|
+
emit({
|
|
46380
|
+
type: "agent:tool_input_update",
|
|
46381
|
+
payload: {
|
|
46382
|
+
...wireBase(base),
|
|
46383
|
+
toolName: proc.currentToolName,
|
|
46384
|
+
input: liveInput
|
|
46385
|
+
}
|
|
46386
|
+
});
|
|
46387
|
+
}
|
|
46091
46388
|
}
|
|
46092
46389
|
} else if (delta.type === "text_delta" && typeof delta.text === "string") {
|
|
46093
46390
|
if (proc.accumulatedText.length === 0) {
|
|
@@ -46142,6 +46439,16 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46142
46439
|
if (lastToolUse && lastToolUse.type === "tool_use") {
|
|
46143
46440
|
lastToolUse.input = parsedInput;
|
|
46144
46441
|
}
|
|
46442
|
+
if (proc.currentToolName != null && LIVE_INPUT_PREVIEW_TOOLS.has(proc.currentToolName) && Object.keys(parsedInput).length > 0) {
|
|
46443
|
+
emit({
|
|
46444
|
+
type: "agent:tool_input_update",
|
|
46445
|
+
payload: {
|
|
46446
|
+
...wireBase(base),
|
|
46447
|
+
toolName: proc.currentToolName,
|
|
46448
|
+
input: parsedInput
|
|
46449
|
+
}
|
|
46450
|
+
});
|
|
46451
|
+
}
|
|
46145
46452
|
if (proc.currentToolName === "TodoWrite") {
|
|
46146
46453
|
const todos = extractTodosFromInput(parsedInput);
|
|
46147
46454
|
if (todos) {
|
|
@@ -46177,6 +46484,28 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46177
46484
|
});
|
|
46178
46485
|
}
|
|
46179
46486
|
}
|
|
46487
|
+
if (proc.currentToolName === "TaskCreate") {
|
|
46488
|
+
if (applyTaskCreateInput(proc, parsedInput)) {
|
|
46489
|
+
emitTaskToolTodosUpdate(proc, emit, base, "TaskCreate");
|
|
46490
|
+
} else {
|
|
46491
|
+
logger7.warn("TaskCreate detected but input was not usable", {
|
|
46492
|
+
agentId: proc.agentId,
|
|
46493
|
+
replyMessageId: base.replyMessageId,
|
|
46494
|
+
traceId: base.traceId
|
|
46495
|
+
});
|
|
46496
|
+
}
|
|
46497
|
+
}
|
|
46498
|
+
if (proc.currentToolName === "TaskUpdate") {
|
|
46499
|
+
if (applyTaskUpdateInput(proc, parsedInput)) {
|
|
46500
|
+
emitTaskToolTodosUpdate(proc, emit, base, "TaskUpdate");
|
|
46501
|
+
} else {
|
|
46502
|
+
logger7.warn("TaskUpdate detected but input was not usable", {
|
|
46503
|
+
agentId: proc.agentId,
|
|
46504
|
+
replyMessageId: base.replyMessageId,
|
|
46505
|
+
traceId: base.traceId
|
|
46506
|
+
});
|
|
46507
|
+
}
|
|
46508
|
+
}
|
|
46180
46509
|
if (proc.currentToolName === "AskUserQuestion") {
|
|
46181
46510
|
const last = proc.contentBlocks[proc.contentBlocks.length - 1];
|
|
46182
46511
|
if (last?.type === "tool_use" && last.toolName === "AskUserQuestion") {
|
|
@@ -46386,6 +46715,29 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46386
46715
|
onCompleted();
|
|
46387
46716
|
break;
|
|
46388
46717
|
}
|
|
46718
|
+
if (proc.accumulatedText.length === 0 && proc.contentBlocks.length === 0) {
|
|
46719
|
+
cleanupPlanMode(proc, emit, base, "error");
|
|
46720
|
+
logger7.warn("SDK success produced empty assistant output; emitting agent:error", {
|
|
46721
|
+
agentId: proc.agentId,
|
|
46722
|
+
ackId: base.replyMessageId,
|
|
46723
|
+
tokenCount: usage.tokenCount,
|
|
46724
|
+
inputTokens: usage.inputTokens,
|
|
46725
|
+
cacheReadTokens: usage.cacheReadTokens,
|
|
46726
|
+
cacheCreationTokens: usage.cacheCreationTokens,
|
|
46727
|
+
assistantContent: proc.lastAssistantContentDescription,
|
|
46728
|
+
traceId: base.traceId
|
|
46729
|
+
});
|
|
46730
|
+
emit({
|
|
46731
|
+
type: "agent:error",
|
|
46732
|
+
payload: {
|
|
46733
|
+
...wireBase(base),
|
|
46734
|
+
error: "Agent \u8FD4\u56DE\u4E86\u7A7A\u7ED3\u679C\uFF0C\u5DF2\u963B\u6B62\u7A7A\u6D88\u606F\u8986\u76D6\u601D\u8003\u6C14\u6CE1\u3002\u8BF7\u91CD\u8BD5\uFF1B\u5982\u679C\u53CD\u590D\u51FA\u73B0\uFF0C\u8BF7\u68C0\u67E5 Claude Code \u767B\u5F55\u72B6\u6001\u6216\u6A21\u578B\u914D\u7F6E\u3002"
|
|
46735
|
+
}
|
|
46736
|
+
});
|
|
46737
|
+
resetAccumulators(proc);
|
|
46738
|
+
onCompleted();
|
|
46739
|
+
break;
|
|
46740
|
+
}
|
|
46389
46741
|
if (proc.accumulatedText) {
|
|
46390
46742
|
proc.contentBlocks.push({ type: "text", content: proc.accumulatedText });
|
|
46391
46743
|
}
|
|
@@ -46455,14 +46807,9 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46455
46807
|
if (am2.isApiErrorMessage === true) {
|
|
46456
46808
|
const base = getTaskBase(proc);
|
|
46457
46809
|
if (!base) break;
|
|
46458
|
-
const errorTexts =
|
|
46459
|
-
for (const block of am2.message?.content ?? []) {
|
|
46460
|
-
if (block?.type === "text" && typeof block.text === "string") {
|
|
46461
|
-
errorTexts.push(block.text);
|
|
46462
|
-
}
|
|
46463
|
-
}
|
|
46810
|
+
const errorTexts = extractAssistantTextParts(am2.message?.content);
|
|
46464
46811
|
const errorText = errorTexts.join("\n").trim() || `SDK ${am2.error ?? "api_error"}`;
|
|
46465
|
-
const isAuthFail = am2.error
|
|
46812
|
+
const isAuthFail = isAuthFailureText(errorText, am2.error);
|
|
46466
46813
|
if (isAuthFail) {
|
|
46467
46814
|
sessionStore.delete(proc.agentId, proc.scope);
|
|
46468
46815
|
}
|
|
@@ -46474,7 +46821,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46474
46821
|
isAuthFail,
|
|
46475
46822
|
traceId: base.traceId
|
|
46476
46823
|
});
|
|
46477
|
-
const friendlyError = isAuthFail ?
|
|
46824
|
+
const friendlyError = isAuthFail ? buildAuthFailureMessage(errorText) : errorText;
|
|
46478
46825
|
emit({
|
|
46479
46826
|
type: "agent:error",
|
|
46480
46827
|
payload: { ...wireBase(base), error: friendlyError }
|
|
@@ -46487,14 +46834,36 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46487
46834
|
break;
|
|
46488
46835
|
}
|
|
46489
46836
|
if (proc.accumulatedText.length === 0 && proc.contentBlocks.length === 0) {
|
|
46490
|
-
const captured =
|
|
46491
|
-
for (const block of am2.message?.content ?? []) {
|
|
46492
|
-
if (block?.type === "text" && typeof block.text === "string") {
|
|
46493
|
-
captured.push(block.text);
|
|
46494
|
-
}
|
|
46495
|
-
}
|
|
46837
|
+
const captured = extractAssistantTextParts(am2.message?.content);
|
|
46496
46838
|
if (captured.length > 0) {
|
|
46497
46839
|
const text = captured.join("");
|
|
46840
|
+
if (isAuthFailureText(text, am2.error)) {
|
|
46841
|
+
const base = getTaskBase(proc);
|
|
46842
|
+
logger7.warn("SDK auth failure assistant detected without api-error flag, emitting agent:error", {
|
|
46843
|
+
agentId: proc.agentId,
|
|
46844
|
+
scope: proc.scope.kind === "single" ? "single" : proc.scope.groupId,
|
|
46845
|
+
sdkError: am2.error,
|
|
46846
|
+
errorText: text.slice(0, 200),
|
|
46847
|
+
traceId: base?.traceId,
|
|
46848
|
+
hasCurrentTask: base != null
|
|
46849
|
+
});
|
|
46850
|
+
if (base) {
|
|
46851
|
+
sessionStore.delete(proc.agentId, proc.scope);
|
|
46852
|
+
emit({
|
|
46853
|
+
type: "agent:error",
|
|
46854
|
+
payload: {
|
|
46855
|
+
...wireBase(base),
|
|
46856
|
+
error: buildAuthFailureMessage(text)
|
|
46857
|
+
}
|
|
46858
|
+
});
|
|
46859
|
+
proc.apiErrorEmitted = true;
|
|
46860
|
+
}
|
|
46861
|
+
proc.contentBlocks = [];
|
|
46862
|
+
proc.accumulatedText = "";
|
|
46863
|
+
proc.accumulatedThinking = "";
|
|
46864
|
+
proc.segmentBuffer = "";
|
|
46865
|
+
break;
|
|
46866
|
+
}
|
|
46498
46867
|
if (isContextOverflowText(text)) {
|
|
46499
46868
|
const base = getTaskBase(proc);
|
|
46500
46869
|
logger7.warn("SDK reported context overflow; auto-compact already failed inside SDK", {
|
|
@@ -46538,6 +46907,8 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
|
|
|
46538
46907
|
textLen: text.length,
|
|
46539
46908
|
textSample: text.slice(0, 100)
|
|
46540
46909
|
});
|
|
46910
|
+
} else {
|
|
46911
|
+
proc.lastAssistantContentDescription = describeAssistantContent(am2.message?.content);
|
|
46541
46912
|
}
|
|
46542
46913
|
}
|
|
46543
46914
|
break;
|
|
@@ -46561,6 +46932,7 @@ function resetAccumulators(proc) {
|
|
|
46561
46932
|
proc.accumulatedToolInput = "";
|
|
46562
46933
|
proc.apiErrorEmitted = false;
|
|
46563
46934
|
proc.peakContextUsage = void 0;
|
|
46935
|
+
proc.lastAssistantContentDescription = void 0;
|
|
46564
46936
|
}
|
|
46565
46937
|
|
|
46566
46938
|
// src/forkHistoryReplay.ts
|
|
@@ -46675,8 +47047,15 @@ var wsMetrics = new WsMetrics();
|
|
|
46675
47047
|
// src/agentManager.ts
|
|
46676
47048
|
var logger10 = createModuleLogger("agent.manager");
|
|
46677
47049
|
var NODE_USER_UID = 1e3;
|
|
47050
|
+
var POST_MERGE_CONTINUATION_ROUTE_MS = 15e3;
|
|
46678
47051
|
function isSmithAgent(agent) {
|
|
46679
|
-
|
|
47052
|
+
if (agent.id === SMITH_AGENT_ID) return true;
|
|
47053
|
+
if (agent.systemPrompt === SMITH_SYSTEM_PROMPT) return true;
|
|
47054
|
+
const prompt = agent.systemPrompt ?? "";
|
|
47055
|
+
if (prompt.includes("\u4F60\u662F\u7279\u5DE5\u53F2\u5BC6\u65AF") && prompt.includes("create_agent")) return true;
|
|
47056
|
+
const name = agent.name?.toLowerCase() ?? "";
|
|
47057
|
+
const role = agent.role?.toLowerCase() ?? "";
|
|
47058
|
+
return role === "system" && (name.includes("\u53F2\u5BC6\u65AF") || name.includes("smith"));
|
|
46680
47059
|
}
|
|
46681
47060
|
function isRunningAsRoot() {
|
|
46682
47061
|
try {
|
|
@@ -46685,6 +47064,13 @@ function isRunningAsRoot() {
|
|
|
46685
47064
|
return false;
|
|
46686
47065
|
}
|
|
46687
47066
|
}
|
|
47067
|
+
async function chownForRootSpawn(targetPath, target) {
|
|
47068
|
+
try {
|
|
47069
|
+
await import_promises8.default.chown(targetPath, NODE_USER_UID, NODE_USER_UID);
|
|
47070
|
+
} catch (error51) {
|
|
47071
|
+
logger10.error("Best-effort root chown failed", { error: error51, target, path: targetPath });
|
|
47072
|
+
}
|
|
47073
|
+
}
|
|
46688
47074
|
function readCronLockSnapshot() {
|
|
46689
47075
|
try {
|
|
46690
47076
|
const lockPath2 = import_node_path8.default.join(import_node_os5.default.homedir(), ".claude", "scheduled_tasks.lock");
|
|
@@ -46793,14 +47179,57 @@ var AgentManager = class {
|
|
|
46793
47179
|
this.queryFn = QA$;
|
|
46794
47180
|
return this.queryFn;
|
|
46795
47181
|
}
|
|
47182
|
+
extractAhchatWorkspaceSuffix(requestedCwd) {
|
|
47183
|
+
const normalized = requestedCwd.trim().replace(/\\/g, "/");
|
|
47184
|
+
const marker = "/.ahchat/users/";
|
|
47185
|
+
const markerIndex = normalized.indexOf(marker);
|
|
47186
|
+
if (markerIndex >= 0) {
|
|
47187
|
+
const afterUsers = normalized.slice(markerIndex + marker.length);
|
|
47188
|
+
const workspaceMarker = "/workspaces/";
|
|
47189
|
+
const workspaceIndex = afterUsers.indexOf(workspaceMarker);
|
|
47190
|
+
if (workspaceIndex >= 0) {
|
|
47191
|
+
const suffix = afterUsers.slice(workspaceIndex + workspaceMarker.length);
|
|
47192
|
+
const parts = suffix.split("/").filter((part) => part && part !== "." && part !== "..");
|
|
47193
|
+
return parts.length > 0 ? parts.join(import_node_path8.default.sep) : null;
|
|
47194
|
+
}
|
|
47195
|
+
}
|
|
47196
|
+
const legacyMarker = "/.ahchat/";
|
|
47197
|
+
const legacyIndex = normalized.indexOf(legacyMarker);
|
|
47198
|
+
if (legacyIndex >= 0) {
|
|
47199
|
+
const firstSegment = normalized.slice(legacyIndex + legacyMarker.length).split("/").find(Boolean);
|
|
47200
|
+
if (firstSegment && /^(Agent|Group)-/.test(firstSegment)) {
|
|
47201
|
+
return firstSegment;
|
|
47202
|
+
}
|
|
47203
|
+
}
|
|
47204
|
+
return null;
|
|
47205
|
+
}
|
|
46796
47206
|
fallbackCwd(agentConfig, scope, requestedCwd) {
|
|
46797
47207
|
const normalized = requestedCwd.trim();
|
|
47208
|
+
const ahchatSuffix = this.extractAhchatWorkspaceSuffix(normalized);
|
|
47209
|
+
if (ahchatSuffix) {
|
|
47210
|
+
return import_node_path8.default.join(this.workspacesDir, ahchatSuffix);
|
|
47211
|
+
}
|
|
46798
47212
|
const basename = normalized ? import_node_path8.default.basename(import_node_path8.default.normalize(normalized)) : "";
|
|
46799
47213
|
const suffix = basename && basename !== "." && basename !== import_node_path8.default.sep ? basename : scope.kind === "group" ? `Group-${scope.groupId}` : agentConfig.id;
|
|
46800
47214
|
return import_node_path8.default.join(this.workspacesDir, suffix);
|
|
46801
47215
|
}
|
|
47216
|
+
remapServerWorkspaceCwd(agentConfig, scope, requestedCwd) {
|
|
47217
|
+
const remapped = this.fallbackCwd(agentConfig, scope, requestedCwd);
|
|
47218
|
+
const normalizedRequested = import_node_path8.default.normalize(requestedCwd);
|
|
47219
|
+
const normalizedRemapped = import_node_path8.default.normalize(remapped);
|
|
47220
|
+
if (this.extractAhchatWorkspaceSuffix(requestedCwd) && normalizedRequested !== normalizedRemapped) {
|
|
47221
|
+
logger10.info("Server working directory remapped to local Bridge workspace", {
|
|
47222
|
+
agentId: agentConfig.id,
|
|
47223
|
+
scope: scopeKey(scope),
|
|
47224
|
+
requested: requestedCwd,
|
|
47225
|
+
remapped
|
|
47226
|
+
});
|
|
47227
|
+
return remapped;
|
|
47228
|
+
}
|
|
47229
|
+
return requestedCwd;
|
|
47230
|
+
}
|
|
46802
47231
|
async resolveRuntimeCwd(agentConfig, scope, requestedCwd) {
|
|
46803
|
-
let cwd = requestedCwd;
|
|
47232
|
+
let cwd = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
|
|
46804
47233
|
if (isRunningAsRoot() && cwd.startsWith("/root/")) {
|
|
46805
47234
|
cwd = this.fallbackCwd(agentConfig, scope, cwd);
|
|
46806
47235
|
}
|
|
@@ -47433,19 +47862,10 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
|
|
|
47433
47862
|
options.resume = savedSessionId;
|
|
47434
47863
|
}
|
|
47435
47864
|
if (isRunningAsRoot()) {
|
|
47436
|
-
|
|
47437
|
-
|
|
47438
|
-
} catch {
|
|
47439
|
-
}
|
|
47440
|
-
try {
|
|
47441
|
-
await import_promises8.default.chown(agentCwd, NODE_USER_UID, NODE_USER_UID);
|
|
47442
|
-
} catch {
|
|
47443
|
-
}
|
|
47865
|
+
await chownForRootSpawn(effectiveConfigDir, "configDir");
|
|
47866
|
+
await chownForRootSpawn(agentCwd, "agentCwd");
|
|
47444
47867
|
const settingsFilePath = import_node_path8.default.join(effectiveConfigDir, "settings.json");
|
|
47445
|
-
|
|
47446
|
-
await import_promises8.default.chown(settingsFilePath, NODE_USER_UID, NODE_USER_UID);
|
|
47447
|
-
} catch {
|
|
47448
|
-
}
|
|
47868
|
+
await chownForRootSpawn(settingsFilePath, "settingsFile");
|
|
47449
47869
|
options.spawnClaudeCodeProcess = (spawnOptions) => {
|
|
47450
47870
|
const env2 = { ...spawnOptions.env, HOME: "/home/node" };
|
|
47451
47871
|
return (0, import_node_child_process.spawn)(spawnOptions.command, spawnOptions.args, {
|
|
@@ -47611,7 +48031,7 @@ ${trimmed}`;
|
|
|
47611
48031
|
lines.push(` workdir: ${currentCwd}`);
|
|
47612
48032
|
} else {
|
|
47613
48033
|
const a = this.agentRegistry?.getById(agentId);
|
|
47614
|
-
const singleCwd = a?.workingDirectory || import_node_path8.default.join(
|
|
48034
|
+
const singleCwd = a?.workingDirectory || import_node_path8.default.join(this.workspacesDir, agentId);
|
|
47615
48035
|
lines.push(` workdir: ${singleCwd}`);
|
|
47616
48036
|
}
|
|
47617
48037
|
let rosterCount = 0;
|
|
@@ -47623,7 +48043,7 @@ ${trimmed}`;
|
|
|
47623
48043
|
if (key === curKey) {
|
|
47624
48044
|
lines.push(` workdir: ${currentCwd}`);
|
|
47625
48045
|
} else {
|
|
47626
|
-
const groupCwd =
|
|
48046
|
+
const groupCwd = g2.workingDirectory || import_node_path8.default.join(this.workspacesDir, g2.groupId);
|
|
47627
48047
|
lines.push(` workdir: ${groupCwd}`);
|
|
47628
48048
|
}
|
|
47629
48049
|
const others = g2.members.filter((id) => id !== agentId).map((id) => {
|
|
@@ -47970,6 +48390,16 @@ ${lines.join("\n")}`;
|
|
|
47970
48390
|
}
|
|
47971
48391
|
}
|
|
47972
48392
|
async dispatchToSDK(runtime, task) {
|
|
48393
|
+
if (runtime.postMergeContinuationTask) {
|
|
48394
|
+
logger10.info("Clearing stale post-merge continuation route before explicit dispatch", {
|
|
48395
|
+
agentId: runtime.agentId,
|
|
48396
|
+
staleReplyMessageId: runtime.postMergeContinuationTask.replyMessageId,
|
|
48397
|
+
nextReplyMessageId: task.replyMessageId,
|
|
48398
|
+
traceId: task.traceId
|
|
48399
|
+
});
|
|
48400
|
+
delete runtime.postMergeContinuationTask;
|
|
48401
|
+
delete runtime.postMergeContinuationUntil;
|
|
48402
|
+
}
|
|
47973
48403
|
await this.applyEffortMode(runtime, "high", {
|
|
47974
48404
|
source: "dispatchToSDK",
|
|
47975
48405
|
replyMessageId: task.replyMessageId
|
|
@@ -48178,6 +48608,19 @@ ${lines.join("\n")}`;
|
|
|
48178
48608
|
}
|
|
48179
48609
|
});
|
|
48180
48610
|
}
|
|
48611
|
+
const continuationTask = mergedBatch.at(-1);
|
|
48612
|
+
if (continuationTask) {
|
|
48613
|
+
proc.postMergeContinuationTask = continuationTask;
|
|
48614
|
+
proc.postMergeContinuationUntil = Date.now() + POST_MERGE_CONTINUATION_ROUTE_MS;
|
|
48615
|
+
logger10.info("Armed SDK post-merge continuation routing", {
|
|
48616
|
+
agentId: proc.agentId,
|
|
48617
|
+
carrierReplyMessageId: completedTask.replyMessageId,
|
|
48618
|
+
continuationReplyMessageId: continuationTask.replyMessageId,
|
|
48619
|
+
mergedCount: mergedBatch.length,
|
|
48620
|
+
routeUntil: new Date(proc.postMergeContinuationUntil).toISOString(),
|
|
48621
|
+
traceId: completedTask.traceId
|
|
48622
|
+
});
|
|
48623
|
+
}
|
|
48181
48624
|
runtime.mergedTasks = [];
|
|
48182
48625
|
} else if (runtime.mergedTasks.length > 0) {
|
|
48183
48626
|
logger10.warn("mergedTasks non-empty but no currentTask; dropping", {
|
|
@@ -50937,6 +51380,13 @@ var import_node_child_process2 = require("child_process");
|
|
|
50937
51380
|
var import_node_fs8 = require("fs");
|
|
50938
51381
|
var import_node_path15 = require("path");
|
|
50939
51382
|
var logger24 = createModuleLogger("bridge.ensureCli");
|
|
51383
|
+
var DEFAULT_INSTALL_TIMEOUT_MS = 6e5;
|
|
51384
|
+
function getInstallTimeoutMs() {
|
|
51385
|
+
const raw = process.env.AHCHAT_CLAUDE_CLI_INSTALL_TIMEOUT_MS;
|
|
51386
|
+
if (!raw) return DEFAULT_INSTALL_TIMEOUT_MS;
|
|
51387
|
+
const parsed = Number.parseInt(raw, 10);
|
|
51388
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_INSTALL_TIMEOUT_MS;
|
|
51389
|
+
}
|
|
50940
51390
|
function detectClaudeCli() {
|
|
50941
51391
|
try {
|
|
50942
51392
|
return (0, import_node_child_process2.execFileSync)("claude", ["--version"], { timeout: 1e4 }).toString().trim();
|
|
@@ -50965,9 +51415,18 @@ function resolveClaudeBinary() {
|
|
|
50965
51415
|
if (first) return first;
|
|
50966
51416
|
} catch {
|
|
50967
51417
|
}
|
|
51418
|
+
return resolveViaNpmBin();
|
|
51419
|
+
}
|
|
51420
|
+
function getNpmClaudeCandidates(bin) {
|
|
51421
|
+
if (process.platform === "win32") {
|
|
51422
|
+
return ["claude.cmd", "claude.exe", "claude", "anthropic-cli.cmd", "anthropic-cli.exe", "anthropic-cli"].map((name) => (0, import_node_path15.join)(bin, name));
|
|
51423
|
+
}
|
|
51424
|
+
return [(0, import_node_path15.join)(bin, "claude"), (0, import_node_path15.join)(bin, "anthropic-cli")];
|
|
51425
|
+
}
|
|
51426
|
+
function resolveViaNpmBin() {
|
|
50968
51427
|
const bin = getNpmGlobalBin();
|
|
50969
|
-
if (bin)
|
|
50970
|
-
|
|
51428
|
+
if (!bin) return void 0;
|
|
51429
|
+
for (const candidate of getNpmClaudeCandidates(bin)) {
|
|
50971
51430
|
try {
|
|
50972
51431
|
(0, import_node_fs8.accessSync)(candidate, import_node_fs8.constants.X_OK);
|
|
50973
51432
|
return candidate;
|
|
@@ -50977,9 +51436,30 @@ function resolveClaudeBinary() {
|
|
|
50977
51436
|
return void 0;
|
|
50978
51437
|
}
|
|
50979
51438
|
function detectViaNpmBin() {
|
|
50980
|
-
const
|
|
50981
|
-
if (!
|
|
50982
|
-
|
|
51439
|
+
const binPath = resolveViaNpmBin();
|
|
51440
|
+
if (!binPath) return void 0;
|
|
51441
|
+
try {
|
|
51442
|
+
return (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51443
|
+
} catch {
|
|
51444
|
+
}
|
|
51445
|
+
return void 0;
|
|
51446
|
+
}
|
|
51447
|
+
function detectResolvedClaudeCli() {
|
|
51448
|
+
const viaPath = detectClaudeCli();
|
|
51449
|
+
if (viaPath) {
|
|
51450
|
+
return { version: viaPath, path: resolveClaudeBinary() };
|
|
51451
|
+
}
|
|
51452
|
+
const npmBinPath = resolveViaNpmBin();
|
|
51453
|
+
if (!npmBinPath) return void 0;
|
|
51454
|
+
try {
|
|
51455
|
+
const version2 = (0, import_node_child_process2.execFileSync)(npmBinPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51456
|
+
return { version: version2, path: npmBinPath };
|
|
51457
|
+
} catch {
|
|
51458
|
+
}
|
|
51459
|
+
return void 0;
|
|
51460
|
+
}
|
|
51461
|
+
function detectVersionFromResolvedCandidates() {
|
|
51462
|
+
const candidates = [resolveClaudeBinary(), resolveViaNpmBin()].filter((p) => Boolean(p));
|
|
50983
51463
|
for (const p of candidates) {
|
|
50984
51464
|
try {
|
|
50985
51465
|
(0, import_node_fs8.accessSync)(p, import_node_fs8.constants.X_OK);
|
|
@@ -50993,7 +51473,7 @@ function installClaudeCli() {
|
|
|
50993
51473
|
logger24.info("Installing Claude Code CLI via npm...");
|
|
50994
51474
|
const result = (0, import_node_child_process2.spawnSync)("npm", ["install", "-g", "@anthropic-ai/claude-code"], {
|
|
50995
51475
|
stdio: "inherit",
|
|
50996
|
-
timeout:
|
|
51476
|
+
timeout: getInstallTimeoutMs()
|
|
50997
51477
|
});
|
|
50998
51478
|
if (result.error) {
|
|
50999
51479
|
logger24.error("npm install -g failed (spawn error)", {
|
|
@@ -51008,9 +51488,9 @@ function installClaudeCli() {
|
|
|
51008
51488
|
return void 0;
|
|
51009
51489
|
}
|
|
51010
51490
|
logger24.info("npm install -g completed, checking for claude binary...");
|
|
51011
|
-
const viaPath =
|
|
51491
|
+
const viaPath = detectVersionFromResolvedCandidates();
|
|
51012
51492
|
if (viaPath) {
|
|
51013
|
-
logger24.info("claude detected
|
|
51493
|
+
logger24.info("claude detected after install", { version: viaPath });
|
|
51014
51494
|
return viaPath;
|
|
51015
51495
|
}
|
|
51016
51496
|
const viaBin = detectViaNpmBin();
|
|
@@ -51028,14 +51508,13 @@ function installClaudeCli() {
|
|
|
51028
51508
|
return void 0;
|
|
51029
51509
|
}
|
|
51030
51510
|
async function ensureClaudeCli() {
|
|
51031
|
-
let
|
|
51032
|
-
if (
|
|
51033
|
-
|
|
51034
|
-
|
|
51035
|
-
return binPath2;
|
|
51511
|
+
let detected = detectResolvedClaudeCli();
|
|
51512
|
+
if (detected) {
|
|
51513
|
+
logger24.info("Claude Code CLI ready", { version: detected.version, path: detected.path ?? null });
|
|
51514
|
+
return detected.path;
|
|
51036
51515
|
}
|
|
51037
51516
|
process.stderr.write("\n\u26A0 Claude Code CLI (`claude`) not found. Attempting auto-install...\n\n");
|
|
51038
|
-
version2 = installClaudeCli();
|
|
51517
|
+
const version2 = installClaudeCli();
|
|
51039
51518
|
if (!version2) {
|
|
51040
51519
|
const npmBin = getNpmGlobalBin();
|
|
51041
51520
|
process.stderr.write(
|
|
@@ -51046,9 +51525,9 @@ async function ensureClaudeCli() {
|
|
|
51046
51525
|
);
|
|
51047
51526
|
process.exit(1);
|
|
51048
51527
|
}
|
|
51049
|
-
|
|
51050
|
-
logger24.info("Claude Code CLI ready", { version: version2, path:
|
|
51051
|
-
return
|
|
51528
|
+
detected = detectResolvedClaudeCli();
|
|
51529
|
+
logger24.info("Claude Code CLI ready", { version: version2, path: detected?.path ?? null });
|
|
51530
|
+
return detected?.path;
|
|
51052
51531
|
}
|
|
51053
51532
|
|
|
51054
51533
|
// src/forkAgentFiles.ts
|
|
@@ -51378,9 +51857,9 @@ function isRunningAsRoot2() {
|
|
|
51378
51857
|
}
|
|
51379
51858
|
async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
51380
51859
|
const rootClaudeDir = import_node_path19.default.join(process.env.HOME ?? "/root", ".claude");
|
|
51381
|
-
const
|
|
51860
|
+
const fs16 = await import("fs/promises");
|
|
51382
51861
|
try {
|
|
51383
|
-
await
|
|
51862
|
+
await fs16.access(rootClaudeDir);
|
|
51384
51863
|
} catch {
|
|
51385
51864
|
logger28.info("No /root/.claude to sync", { rootClaudeDir });
|
|
51386
51865
|
return;
|
|
@@ -51390,7 +51869,7 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
|
51390
51869
|
const src = import_node_path19.default.join(rootClaudeDir, file2);
|
|
51391
51870
|
const dest = import_node_path19.default.join(agentConfigDir, file2);
|
|
51392
51871
|
try {
|
|
51393
|
-
await
|
|
51872
|
+
await fs16.copyFile(src, dest);
|
|
51394
51873
|
logger28.info("Synced credential file", { file: file2, from: src, to: dest });
|
|
51395
51874
|
} catch {
|
|
51396
51875
|
logger28.debug("Credential file not present, skipping", { file: file2, src });
|
|
@@ -51398,15 +51877,15 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
|
51398
51877
|
}
|
|
51399
51878
|
}
|
|
51400
51879
|
async function chownRecursive(dirPath, uid, gid) {
|
|
51401
|
-
const
|
|
51880
|
+
const fs16 = await import("fs/promises");
|
|
51402
51881
|
try {
|
|
51403
|
-
await
|
|
51882
|
+
await fs16.chown(dirPath, uid, gid);
|
|
51404
51883
|
} catch {
|
|
51405
51884
|
logger28.debug("chown skipped", { dirPath, uid, gid });
|
|
51406
51885
|
}
|
|
51407
51886
|
let entries;
|
|
51408
51887
|
try {
|
|
51409
|
-
entries = await
|
|
51888
|
+
entries = await fs16.readdir(dirPath, { withFileTypes: true });
|
|
51410
51889
|
} catch {
|
|
51411
51890
|
return;
|
|
51412
51891
|
}
|
|
@@ -51416,7 +51895,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51416
51895
|
await chownRecursive(fullPath, uid, gid);
|
|
51417
51896
|
} else {
|
|
51418
51897
|
try {
|
|
51419
|
-
await
|
|
51898
|
+
await fs16.chown(fullPath, uid, gid);
|
|
51420
51899
|
} catch {
|
|
51421
51900
|
logger28.debug("chown skipped", { fullPath, uid, gid });
|
|
51422
51901
|
}
|
|
@@ -51489,6 +51968,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
51489
51968
|
agentRegistry,
|
|
51490
51969
|
subscriptionRegistry,
|
|
51491
51970
|
serverApiUrl: config2.serverApiUrl,
|
|
51971
|
+
bridgeToken: config2.bridgeToken,
|
|
51492
51972
|
dataDir: config2.dataDir
|
|
51493
51973
|
});
|
|
51494
51974
|
const taskDispatchHandler = createTaskDispatchHandler(agentManager, agentRegistry, emit);
|
|
@@ -52059,6 +52539,25 @@ function isProtocolRegistered() {
|
|
|
52059
52539
|
|
|
52060
52540
|
// src/cli.ts
|
|
52061
52541
|
var logger30 = createModuleLogger("bridge");
|
|
52542
|
+
function readCliVersion() {
|
|
52543
|
+
const candidates = [
|
|
52544
|
+
import_node_path21.default.resolve(__dirname, "../package.json"),
|
|
52545
|
+
import_node_path21.default.resolve(__dirname, "../../package.json"),
|
|
52546
|
+
import_node_path21.default.resolve(process.cwd(), "packages/bridge/package.json")
|
|
52547
|
+
];
|
|
52548
|
+
for (const candidate of candidates) {
|
|
52549
|
+
if (!import_node_fs10.default.existsSync(candidate)) continue;
|
|
52550
|
+
try {
|
|
52551
|
+
const parsed = JSON.parse(import_node_fs10.default.readFileSync(candidate, "utf8"));
|
|
52552
|
+
if (parsed && typeof parsed === "object" && "version" in parsed && typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
52553
|
+
return parsed.version;
|
|
52554
|
+
}
|
|
52555
|
+
} catch (e7) {
|
|
52556
|
+
logger30.warn("Unable to read CLI package version candidate", { error: e7, candidate });
|
|
52557
|
+
}
|
|
52558
|
+
}
|
|
52559
|
+
return "0.1.20";
|
|
52560
|
+
}
|
|
52062
52561
|
function resolveDataDir(dataDir) {
|
|
52063
52562
|
const userHome = process.env.USERPROFILE || import_node_os13.default.homedir();
|
|
52064
52563
|
if (/^~[/\\]/.test(dataDir)) {
|
|
@@ -52096,17 +52595,14 @@ function parseAhchatUrl(url2) {
|
|
|
52096
52595
|
}
|
|
52097
52596
|
}
|
|
52098
52597
|
async function run(args) {
|
|
52099
|
-
|
|
52598
|
+
const dataDir = args.dataDir ? resolveDataDir(args.dataDir) : void 0;
|
|
52599
|
+
let config2 = loadBridgeConfig(dataDir ? { dataDir } : void 0);
|
|
52100
52600
|
if (args.serverUrl) {
|
|
52101
52601
|
const wsUrl = new URL(args.serverUrl);
|
|
52102
52602
|
const httpBase = `${wsUrl.protocol === "wss:" ? "https" : "http"}://${wsUrl.host}`;
|
|
52103
52603
|
config2 = { ...config2, serverUrl: args.serverUrl, serverApiUrl: httpBase };
|
|
52104
52604
|
}
|
|
52105
52605
|
if (args.token) config2 = { ...config2, bridgeToken: args.token };
|
|
52106
|
-
if (args.dataDir) {
|
|
52107
|
-
const resolved = resolveDataDir(args.dataDir);
|
|
52108
|
-
config2 = { ...config2, dataDir: resolved };
|
|
52109
|
-
}
|
|
52110
52606
|
if (args.logLevel) config2 = { ...config2, logLevel: args.logLevel };
|
|
52111
52607
|
await startBridge(config2);
|
|
52112
52608
|
}
|
|
@@ -52143,5 +52639,5 @@ cli.command("status", "Check if protocol handler is registered").action(() => {
|
|
|
52143
52639
|
if (!registered) process.stdout.write('Run "npx @fangyb/ahchat-bridge install" to register it.\n');
|
|
52144
52640
|
});
|
|
52145
52641
|
cli.help();
|
|
52146
|
-
cli.version(
|
|
52642
|
+
cli.version(readCliVersion());
|
|
52147
52643
|
cli.parse();
|