@michengai/dsh-agency-agents 0.1.13 → 0.1.14

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.
@@ -1,6 +1,6 @@
1
1
  # 技术架构基线
2
2
 
3
- 更新时间:2026-08-16 00:10(Asia/Shanghai)
3
+ 更新时间:2026-08-17 03:00(Asia/Shanghai)
4
4
 
5
5
  - 运行时:Node.js ESM、TypeScript 严格模式、DSH/Cordis 插件机制。
6
6
  - 智能体资产:`assets\agency-agents` 是默认根目录;显式 `root` 优先,其次读取 `AGENCY_AGENTS_ROOT`。
@@ -9,7 +9,8 @@
9
9
  - 深度:`maxDepth` 为可选正整数绝对上限;未配置时不改变宿主的既有深度策略。
10
10
  - 启停与持久化:通过 `@deepseek-ai/dsh-settings` 的 settings namespace(`agency-agents`,schema `{ enabled: string[] }`)在宿主侧持久化;**白名单语义,默认全停用**,用户在设置「专家」标签页启用。宿主工具按「已启用」过滤。
11
11
  - 客户端取数:启用状态不经过 `api.settings`(那是 Host 自有配置面,`WEB_SETTINGS_NAMESPACES` 白名单对第三方插件硬编码封死),改走插件自有的 **Typert Remote** 通道 —— 宿主 `AgencyAgentsRemote extends TypertRemoteService`(`@Remote getEnabled/setEnabled`)由 gateway SRC 自动发现,客户端 `$mount(TYPERT_REMOTE)` 后经 `ctx.remote.agencyAgents` 读写(`src/client/remote.ts` 手写 strict 贡献)。第三方安装无需修改或重编 DSH 源码。
12
- - 客户端:client bundle(`lib/client.js`,`window.__ModuleLoader__.load` 格式)提供 composer「专家」按钮 + 弹窗、设置「专家」标签页、@ 菜单;静态花名册与中文名打包进 client(`src/client/roster.ts`、`src/names.ts`)。
12
+ - 客户端:client bundle(`lib/client.js`,`window.__ModuleLoader__.load` 格式)提供 composer「专家」按钮 + 弹窗、设置「专家」标签页、@ 菜单;静态花名册与中英文名打包进 client(`src/client/roster.ts`、`src/names.ts`)。界面词条走 `agency` 命名空间;专家名/简介/排序跟随 `locale` 的 `zh`/`en`。
13
+ - 宿主文案:`list_experts` 的名单、分区标题和用户可见错误读取 settings `locale.preference`(仅显式 `en` 走英文,其余回退 `zh`)。分区筛选同时认 key、中文名和英文名。
13
14
  - 发布:包必须包含 `lib`(含 `client.js`)、智能体资产、`cordis.patch.yml`、Apache `LICENSE` 和 `NOTICE`。
14
15
 
15
16
  ## 与早期临时动态插件(agency-1)的差异
@@ -7,6 +7,9 @@
7
7
  ## 组件职责
8
8
 
9
9
  - `src\index.ts`:解析 frontmatter、加载目录、注册工具和系统提示。
10
+ - `src\i18n.ts`:宿主侧中英文词条,以及分区/专家名的语言切换。
11
+ - `src\names.ts`:中英文分区名与中文专家名。
12
+ - `src\client\locales.ts`:设置页、按钮、`@` 菜单的客户端词条。
10
13
  - `cordis.patch.yml`:通过 DSH bundle 把插件挂载进 profile。
11
14
  - `scripts\verify.mjs`:校验构建入口、发布文件、bundle patch 和许可证资产。
12
15
  - `assets\agency-agents`:上游 persona 快照;仅其中的合法 frontmatter Markdown 会进入目录。
package/lib/client.js CHANGED
@@ -49,6 +49,26 @@ window.__ModuleLoader__.load({
49
49
  support: "支持",
50
50
  testing: "测试"
51
51
  };
52
+ /** 分区目录名 → 英文分区名。 */
53
+ const EN_DIVISION = {
54
+ academic: "Academic",
55
+ design: "Design",
56
+ engineering: "Engineering",
57
+ finance: "Finance",
58
+ "game-development": "Game Development",
59
+ gis: "GIS",
60
+ healthcare: "Healthcare",
61
+ marketing: "Marketing",
62
+ "paid-media": "Paid Media",
63
+ product: "Product",
64
+ "project-management": "Project Management",
65
+ sales: "Sales",
66
+ security: "Security",
67
+ "spatial-computing": "Spatial Computing",
68
+ specialized: "Specialized",
69
+ support: "Support",
70
+ testing: "Testing"
71
+ };
52
72
  /** 智能体 slug(文件名去 .md)→ 中文名(现实岗位)。缺省时回退英文 frontmatter name。 */
53
73
  const ZH_NAME = {
54
74
  "academic-anthropologist": "人类学家",
@@ -2522,7 +2542,6 @@ window.__ModuleLoader__.load({
2522
2542
  "summary.group": "{count} 个",
2523
2543
  "button.title": "召唤专家",
2524
2544
  "menu.empty": "暂无可召唤的专家",
2525
- "group.count": "{division}({count})",
2526
2545
  "summon.instruction": "召唤专家「{name}」({slug})处理以下任务:",
2527
2546
  "summon.instruction.withTask": "召唤专家「{name}」({slug})处理以下任务:\n{task}",
2528
2547
  "division.academic": ZH_DIVISION.academic,
@@ -2563,26 +2582,25 @@ window.__ModuleLoader__.load({
2563
2582
  "summary.group": "{count} items",
2564
2583
  "button.title": "Summon expert",
2565
2584
  "menu.empty": "No experts available yet",
2566
- "group.count": "{division} ({count})",
2567
2585
  "summon.instruction": "Summon expert \"{name}\" ({slug}) to handle the following task:",
2568
2586
  "summon.instruction.withTask": "Summon expert \"{name}\" ({slug}) to handle the following task:\n{task}",
2569
- "division.academic": "Academic",
2570
- "division.design": "Design",
2571
- "division.engineering": "Engineering",
2572
- "division.finance": "Finance",
2573
- "division.game-development": "Game Development",
2574
- "division.gis": "GIS",
2575
- "division.healthcare": "Healthcare",
2576
- "division.marketing": "Marketing",
2577
- "division.paid-media": "Paid Media",
2578
- "division.product": "Product",
2579
- "division.project-management": "Project Management",
2580
- "division.sales": "Sales",
2581
- "division.security": "Security",
2582
- "division.spatial-computing": "Spatial Computing",
2583
- "division.specialized": "Specialized",
2584
- "division.support": "Support",
2585
- "division.testing": "Testing"
2587
+ "division.academic": EN_DIVISION.academic,
2588
+ "division.design": EN_DIVISION.design,
2589
+ "division.engineering": EN_DIVISION.engineering,
2590
+ "division.finance": EN_DIVISION.finance,
2591
+ "division.game-development": EN_DIVISION["game-development"],
2592
+ "division.gis": EN_DIVISION.gis,
2593
+ "division.healthcare": EN_DIVISION.healthcare,
2594
+ "division.marketing": EN_DIVISION.marketing,
2595
+ "division.paid-media": EN_DIVISION["paid-media"],
2596
+ "division.product": EN_DIVISION.product,
2597
+ "division.project-management": EN_DIVISION["project-management"],
2598
+ "division.sales": EN_DIVISION.sales,
2599
+ "division.security": EN_DIVISION.security,
2600
+ "division.spatial-computing": EN_DIVISION["spatial-computing"],
2601
+ "division.specialized": EN_DIVISION.specialized,
2602
+ "division.support": EN_DIVISION.support,
2603
+ "division.testing": EN_DIVISION.testing
2586
2604
  };
2587
2605
  //#endregion
2588
2606
  //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
@@ -6630,7 +6648,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6630
6648
  description: e.description,
6631
6649
  descriptionEn: e.descriptionEn
6632
6650
  })).sort((a, b) => a.division.localeCompare(b.division) || a.slug.localeCompare(b.slug));
6633
- function groupByDivision(list) {
6651
+ /** 按当前语言比较专家显示名,供设置页和菜单分组排序。 */
6652
+ function compareExpertName(a, b, active) {
6653
+ const left = active === "en" ? a.nameEn : a.name;
6654
+ const right = active === "en" ? b.nameEn : b.name;
6655
+ return left.localeCompare(right, active === "en" ? "en" : "zh");
6656
+ }
6657
+ function groupByDivision(list, active) {
6634
6658
  const groups = /* @__PURE__ */ new Map();
6635
6659
  for (const e of list) {
6636
6660
  const arr = groups.get(e.division) ?? [];
@@ -6640,7 +6664,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6640
6664
  return DIVISION_ORDER.filter((d) => groups.has(d)).map((d) => ({
6641
6665
  division: d,
6642
6666
  divisionZh: ZH_DIVISION[d] ?? d,
6643
- experts: (groups.get(d) ?? []).slice().sort((a, b) => a.name.localeCompare(b.name, "zh"))
6667
+ experts: (groups.get(d) ?? []).slice().sort((a, b) => compareExpertName(a, b, active))
6644
6668
  }));
6645
6669
  }
6646
6670
  /** 按当前 locale 取专家显示名:en 用花名册英文名,其余用中文名。 */
@@ -6773,7 +6797,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6773
6797
  });
6774
6798
  setOpen(false);
6775
6799
  };
6776
- const groups = groupByDivision(EXPERTS.filter((e) => enabled.has(e.slug)));
6800
+ const groups = groupByDivision(EXPERTS.filter((e) => enabled.has(e.slug)), props.getActive());
6777
6801
  const menu = open ? react.default.createElement("div", { className: "aag-menu" }, groups.length === 0 ? react.default.createElement("div", { className: "aag-menu-empty" }, props.t("menu.empty")) : groups.map((g) => menuGroup(g, pick, props.t, props.getActive))) : null;
6778
6802
  return react.default.createElement("div", { className: "aag-btn-wrap" }, react.default.createElement("button", {
6779
6803
  type: "button",
@@ -6852,7 +6876,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6852
6876
  className: "aag-note"
6853
6877
  }, props.t("settings.loading")));
6854
6878
  else {
6855
- const groups = groupByDivision(EXPERTS);
6879
+ const groups = groupByDivision(EXPERTS, props.getActive());
6856
6880
  const enabledCount = [...state.enabled].filter((slug) => EXPERTS.some((e) => e.slug === slug)).length;
6857
6881
  const total = EXPERTS.length;
6858
6882
  nodes.push(react.default.createElement("div", {
@@ -6965,6 +6989,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6965
6989
  exports.apply = apply;
6966
6990
  exports.applyExpertSummon = applyExpertSummon;
6967
6991
  exports.buildSummonInstruction = buildSummonInstruction;
6992
+ exports.compareExpertName = compareExpertName;
6968
6993
  exports.inject = inject;
6969
6994
  exports.writeErrorKey = writeErrorKey;
6970
6995
  exports.writeErrorMessage = writeErrorMessage;
@@ -0,0 +1,442 @@
1
+ import { settingsNamespace } from "@deepseek-ai/dsh-settings";
2
+ //#region src/names.ts
3
+ /** 分区目录名 → 中文分区名。 */
4
+ const ZH_DIVISION = {
5
+ academic: "学术",
6
+ design: "设计",
7
+ engineering: "工程",
8
+ finance: "金融",
9
+ "game-development": "游戏开发",
10
+ gis: "地理信息",
11
+ healthcare: "医疗健康",
12
+ marketing: "市场营销",
13
+ "paid-media": "付费媒体",
14
+ product: "产品",
15
+ "project-management": "项目管理",
16
+ sales: "销售",
17
+ security: "安全",
18
+ "spatial-computing": "空间计算",
19
+ specialized: "专业",
20
+ support: "支持",
21
+ testing: "测试"
22
+ };
23
+ /** 分区目录名 → 英文分区名。 */
24
+ const EN_DIVISION = {
25
+ academic: "Academic",
26
+ design: "Design",
27
+ engineering: "Engineering",
28
+ finance: "Finance",
29
+ "game-development": "Game Development",
30
+ gis: "GIS",
31
+ healthcare: "Healthcare",
32
+ marketing: "Marketing",
33
+ "paid-media": "Paid Media",
34
+ product: "Product",
35
+ "project-management": "Project Management",
36
+ sales: "Sales",
37
+ security: "Security",
38
+ "spatial-computing": "Spatial Computing",
39
+ specialized: "Specialized",
40
+ support: "Support",
41
+ testing: "Testing"
42
+ };
43
+ /** 智能体 slug(文件名去 .md)→ 中文名(现实岗位)。缺省时回退英文 frontmatter name。 */
44
+ const ZH_NAME = {
45
+ "academic-anthropologist": "人类学家",
46
+ "academic-geographer": "地理学家",
47
+ "academic-historian": "历史学家",
48
+ "academic-narratologist": "叙事学家",
49
+ "academic-psychologist": "心理学家",
50
+ "academic-statistician": "统计学家",
51
+ "design-brand-guardian": "品牌视觉设计师",
52
+ "design-image-prompt-engineer": "AI 图像设计师",
53
+ "design-inclusive-visuals-specialist": "无障碍设计师",
54
+ "design-persona-walkthrough": "用户体验设计师",
55
+ "design-ui-designer": "UI 设计师",
56
+ "design-ui-finish-gate-reviewer": "UI 视觉验收设计师",
57
+ "design-ux-architect": "UX 架构师",
58
+ "design-ux-researcher": "UX 研究员",
59
+ "design-visual-storyteller": "视觉传达设计师",
60
+ "design-whimsy-injector": "创意设计师",
61
+ "engineering-ai-data-remediation-engineer": "AI 数据治理工程师",
62
+ "engineering-ai-engineer": "AI 工程师",
63
+ "engineering-api-platform-engineer": "API 平台工程师",
64
+ "engineering-autonomous-optimization-architect": "自动化优化架构师",
65
+ "engineering-backend-architect": "后端架构师",
66
+ "engineering-cms-developer": "CMS 开发者",
67
+ "engineering-code-reviewer": "代码审查工程师",
68
+ "engineering-codebase-onboarding-engineer": "工程效率工程师",
69
+ "engineering-data-engineer": "数据工程师",
70
+ "engineering-data-visualization-engineer": "数据可视化工程师",
71
+ "engineering-database-optimizer": "数据库性能工程师",
72
+ "engineering-database-reliability-engineer": "数据库可靠性工程师",
73
+ "engineering-desktop-app-engineer": "桌面应用工程师",
74
+ "engineering-developer-tooling-engineer": "开发者工具工程师",
75
+ "engineering-devops-automator": "DevOps 自动化工程师",
76
+ "engineering-drupal-performance": "Drupal 性能工程师",
77
+ "engineering-drupal-shopping-cart": "Drupal 购物车工程师",
78
+ "engineering-email-intelligence-engineer": "邮件系统工程师",
79
+ "engineering-embedded-firmware-engineer": "嵌入式固件工程师",
80
+ "engineering-feishu-integration-developer": "飞书集成开发工程师",
81
+ "engineering-filament-optimization-specialist": "Filament 后台优化专家",
82
+ "engineering-finops-engineer": "FinOps 工程师",
83
+ "engineering-frontend-developer": "前端开发者",
84
+ "engineering-gaussdb-expert": "GaussDB 专家工程师",
85
+ "engineering-git-workflow-master": "Git 工作流工程师",
86
+ "engineering-i18n-engineer": "国际化工程师",
87
+ "engineering-identity-access-engineer": "身份与访问管理工程师",
88
+ "engineering-incident-response-commander": "故障应急工程师",
89
+ "engineering-iot-fleet-engineer": "物联网设备工程师",
90
+ "engineering-it-service-manager": "IT 服务经理",
91
+ "engineering-llm-post-training-engineer": "LLM 后训练工程师",
92
+ "engineering-minimal-change-engineer": "低风险变更工程师",
93
+ "engineering-mobile-app-builder": "移动应用开发工程师",
94
+ "engineering-mobile-release-engineer": "移动发布工程师",
95
+ "engineering-multi-agent-systems-architect": "多智能体系统架构师",
96
+ "engineering-network-engineer": "网络工程师",
97
+ "engineering-orgscript-engineer": "OrgScript 工程师",
98
+ "engineering-payments-billing-engineer": "支付计费工程师",
99
+ "engineering-privacy-engineer": "隐私工程师",
100
+ "engineering-prompt-engineer": "提示词工程师",
101
+ "engineering-rag-pipeline-engineer": "RAG 管线工程师",
102
+ "engineering-rapid-prototyper": "快速原型工程师",
103
+ "engineering-realtime-collaboration-engineer": "实时协作工程师",
104
+ "engineering-rust-refactoring-specialist": "Rust 重构工程师",
105
+ "engineering-search-relevance-engineer": "搜索相关性工程师",
106
+ "engineering-section-508-specialist": "无障碍合规工程师",
107
+ "engineering-senior-developer": "高级开发者",
108
+ "engineering-software-architect": "软件架构师",
109
+ "engineering-solidity-smart-contract-engineer": "Solidity 智能合约工程师",
110
+ "engineering-sre": "SRE(站点可靠性工程师)",
111
+ "engineering-technical-writer": "技术文档工程师",
112
+ "engineering-uswds-developer": "USWDS 开发者",
113
+ "engineering-video-streaming-engineer": "视频流工程师",
114
+ "engineering-voice-ai-integration-engineer": "语音 AI 集成工程师",
115
+ "engineering-webassembly-engineer": "WebAssembly 工程师",
116
+ "engineering-wechat-mini-program-developer": "微信小程序开发者",
117
+ "engineering-wordpress-performance": "WordPress 性能工程师",
118
+ "engineering-wordpress-shopping-cart": "WordPress 购物车工程师",
119
+ "finance-bookkeeper-controller": "财务会计主管",
120
+ "finance-financial-analyst": "财务分析师",
121
+ "finance-fpa-analyst": "财务计划分析师",
122
+ "finance-investment-researcher": "投资研究员",
123
+ "finance-tax-strategist": "税务筹划师",
124
+ "economy-designer": "经济系统设计师",
125
+ "game-audio-engineer": "游戏音频工程师",
126
+ "game-designer": "游戏设计师",
127
+ "level-designer": "关卡设计师",
128
+ "narrative-designer": "叙事设计师",
129
+ "technical-artist": "技术美术",
130
+ "gis-3d-scene-developer": "3D 场景开发者",
131
+ "gis-analyst": "GIS 分析师",
132
+ "gis-bim-specialist": "BIM/GIS 专家",
133
+ "gis-cartography-designer": "制图设计师",
134
+ "gis-drone-reality-mapping": "无人机/实景测绘专家",
135
+ "gis-geoai-ml-engineer": "地理 AI/ML 工程师",
136
+ "gis-geoprocessing-specialist": "地理处理专家",
137
+ "gis-qa-engineer": "GIS QA 工程师",
138
+ "gis-solution-engineer": "解决方案工程师",
139
+ "gis-spatial-data-engineer": "空间数据工程师",
140
+ "gis-spatial-data-scientist": "空间数据科学家",
141
+ "gis-technical-consultant": "技术顾问",
142
+ "gis-web-gis-developer": "Web GIS 开发者",
143
+ "healthcare-clinical-evidence-agent": "循证医学研究员",
144
+ "healthcare-innovation-strategist": "医疗创新战略顾问",
145
+ "healthcare-sovereign-health-systems-agent": "医疗系统治理顾问",
146
+ "marketing-aeo-foundations": "AEO 搜索优化师",
147
+ "marketing-agentic-search-optimizer": "AI 搜索优化师",
148
+ "marketing-ai-citation-strategist": "AI 引用优化师",
149
+ "marketing-app-store-optimizer": "应用商店优化师",
150
+ "marketing-baidu-seo-specialist": "百度 SEO 专家",
151
+ "marketing-bilibili-content-strategist": "B站内容运营专家",
152
+ "marketing-book-co-author": "图书策划编辑",
153
+ "marketing-carousel-growth-engine": "内容增长运营专家",
154
+ "marketing-china-ecommerce-operator": "中国电商运营",
155
+ "marketing-china-market-localization-strategist": "中国市场本地化专家",
156
+ "marketing-content-creator": "内容创作者",
157
+ "marketing-cross-border-ecommerce": "跨境电商专家",
158
+ "marketing-douyin-strategist": "抖音运营专家",
159
+ "marketing-email-strategist": "邮件营销专家",
160
+ "marketing-global-podcast-strategist": "播客运营专家",
161
+ "marketing-growth-hacker": "增长营销专家",
162
+ "marketing-instagram-curator": "Instagram 运营",
163
+ "marketing-kuaishou-strategist": "快手运营专家",
164
+ "marketing-linkedin-content-creator": "LinkedIn 内容创作者",
165
+ "marketing-livestream-commerce-coach": "直播电商运营专家",
166
+ "marketing-multi-platform-publisher": "多平台内容运营专家",
167
+ "marketing-podcast-strategist": "播客运营专家",
168
+ "marketing-pr-communications-manager": "公关传播经理",
169
+ "marketing-private-domain-operator": "私域运营",
170
+ "marketing-reddit-community-builder": "Reddit 社区运营",
171
+ "marketing-seo-specialist": "SEO 专家",
172
+ "marketing-short-video-editing-coach": "短视频剪辑师",
173
+ "marketing-social-media-strategist": "社媒运营专家",
174
+ "marketing-tiktok-strategist": "TikTok 运营专家",
175
+ "marketing-twitter-engager": "Twitter 互动运营",
176
+ "marketing-video-optimization-specialist": "视频优化专家",
177
+ "marketing-wechat-official-account": "公众号运营",
178
+ "marketing-weibo-strategist": "微博运营专家",
179
+ "marketing-x-twitter-intelligence-analyst": "X/Twitter 舆情分析师",
180
+ "marketing-xiaohongshu-specialist": "小红书运营专家",
181
+ "marketing-zhihu-strategist": "知乎运营专家",
182
+ "paid-media-auditor": "广告投放审计师",
183
+ "paid-media-creative-strategist": "广告创意策划师",
184
+ "paid-media-paid-social-strategist": "付费社媒投放专家",
185
+ "paid-media-ppc-strategist": "PPC 投放优化师",
186
+ "paid-media-programmatic-buyer": "程序化广告投放师",
187
+ "paid-media-search-query-analyst": "搜索词分析师",
188
+ "paid-media-tracking-specialist": "广告归因分析师",
189
+ "product-behavioral-nudge-engine": "增长产品经理",
190
+ "product-feedback-synthesizer": "用户反馈研究员",
191
+ "product-manager": "产品经理",
192
+ "product-sprint-prioritizer": "需求优先级分析师",
193
+ "product-trend-researcher": "趋势研究员",
194
+ "project-management-experiment-tracker": "实验项目运营",
195
+ "project-management-jira-workflow-steward": "Jira 流程管理员",
196
+ "project-management-meeting-notes-specialist": "项目记录专员",
197
+ "project-management-project-shepherd": "项目推进专员",
198
+ "project-management-studio-operations": "工作室运营",
199
+ "project-management-studio-producer": "工作室制片人",
200
+ "project-manager-senior": "高级项目经理",
201
+ "sales-account-strategist": "大客户经理",
202
+ "sales-coach": "销售培训师",
203
+ "sales-deal-strategist": "商务谈判顾问",
204
+ "sales-discovery-coach": "售前需求顾问",
205
+ "sales-engineer": "销售工程师",
206
+ "sales-offer-lead-gen-strategist": "销售获客专员",
207
+ "sales-outbound-strategist": "外呼销售专员",
208
+ "sales-pipeline-analyst": "销售管线分析师",
209
+ "sales-proposal-strategist": "方案提案顾问",
210
+ "security-ai-generated-code-auditor": "AI 生成代码安全审计师",
211
+ "security-appsec-engineer": "应用安全工程师",
212
+ "security-architect": "安全架构师",
213
+ "security-blockchain-security-auditor": "区块链安全审计师",
214
+ "security-cloud-security-architect": "云安全架构师",
215
+ "security-compliance-auditor": "合规审计师",
216
+ "security-incident-responder": "应急响应工程师",
217
+ "security-penetration-tester": "渗透测试工程师",
218
+ "security-secrets-credential-engineer": "密钥与凭据治理工程师",
219
+ "security-senior-secops": "高级安全运营工程师",
220
+ "security-threat-detection-engineer": "威胁检测工程师",
221
+ "security-threat-intelligence-analyst": "威胁情报分析师",
222
+ "macos-spatial-metal-engineer": "macOS 空间/Metal 工程师",
223
+ "terminal-integration-specialist": "终端集成专家",
224
+ "visionos-spatial-engineer": "visionOS 空间工程师",
225
+ "xr-cockpit-interaction-specialist": "XR 座舱交互专家",
226
+ "xr-immersive-developer": "XR 沉浸式开发者",
227
+ "xr-interface-architect": "XR 界面架构师",
228
+ "accounts-payable-agent": "应付账款会计",
229
+ "agentic-identity-trust": "身份与信任架构师",
230
+ "agents-orchestrator": "AI 流程编排师",
231
+ "automation-governance-architect": "自动化治理架构师",
232
+ "business-strategist": "商业策略顾问",
233
+ "change-management-consultant": "变革管理顾问",
234
+ "chief-financial-officer": "首席财务官",
235
+ "corporate-training-designer": "企业培训师",
236
+ "customer-service": "客户服务",
237
+ "customer-success-manager": "客户成功经理",
238
+ "data-consolidation-agent": "数据整合专员",
239
+ "data-privacy-officer": "数据隐私官",
240
+ "esg-sustainability-officer": "ESG 与可持续发展官",
241
+ "government-digital-presales-consultant": "政务数字化售前顾问",
242
+ "grant-writer": "基金申报专员",
243
+ "healthcare-aging-parent-care-companion": "老年照护顾问",
244
+ "healthcare-customer-service": "医疗客服",
245
+ "healthcare-marketing-compliance": "医疗营销合规专家",
246
+ "hospitality-guest-services": "酒店宾客服务",
247
+ "hr-onboarding": "HR 入职专员",
248
+ "identity-graph-operator": "身份图谱运营",
249
+ "language-translator": "翻译专员",
250
+ "legal-billing-time-tracking": "法务计费专员",
251
+ "legal-client-intake": "法务客户接待专员",
252
+ "legal-document-review": "法务文档审核员",
253
+ "loan-officer-assistant": "信贷专员助理",
254
+ "lsp-index-engineer": "LSP/索引工程师",
255
+ "ma-integration-manager": "并购整合经理",
256
+ "medical-billing-coding-specialist": "医疗计费编码专家",
257
+ "operations-manager": "运营经理",
258
+ "organizational-psychologist": "组织心理学家",
259
+ "personal-growth-mentor": "职业发展导师",
260
+ "real-estate-buyer-seller": "房产买卖顾问",
261
+ "recruitment-specialist": "招聘专员",
262
+ "report-distribution-agent": "报告分发专员",
263
+ "resume-tailor": "简历优化顾问",
264
+ "retail-customer-returns": "零售售后客服",
265
+ "sales-data-extraction-agent": "销售数据专员",
266
+ "sales-outreach": "销售拓展专员",
267
+ "specialized-chief-of-staff": "幕僚长",
268
+ "specialized-civil-engineer": "土木工程师",
269
+ "specialized-codebase-archaeologist": "遗留系统工程师",
270
+ "specialized-cultural-intelligence-strategist": "跨文化咨询顾问",
271
+ "specialized-developer-advocate": "开发者布道师",
272
+ "specialized-document-generator": "文档工程师",
273
+ "specialized-fedramp-rmf-compliance": "FedRAMP 与 RMF 合规工程师",
274
+ "specialized-french-consulting-market": "法国市场咨询顾问",
275
+ "specialized-korean-business-navigator": "韩国市场咨询顾问",
276
+ "specialized-mcp-builder": "MCP 集成工程师",
277
+ "specialized-model-qa": "模型质量评估工程师",
278
+ "specialized-pricing-analyst": "定价分析师",
279
+ "specialized-salesforce-architect": "Salesforce 架构师",
280
+ "specialized-strategy-duel-agent": "竞争战略分析师",
281
+ "specialized-workflow-architect": "工作流架构师",
282
+ "study-abroad-advisor": "留学顾问",
283
+ "supply-chain-strategist": "供应链规划师",
284
+ "zk-steward": "零知识证明工程师",
285
+ "support-analytics-reporter": "分析报表专员",
286
+ "support-executive-summary-generator": "管理报告专员",
287
+ "support-finance-tracker": "财务跟踪专员",
288
+ "support-infrastructure-maintainer": "基础设施运维工程师",
289
+ "support-legal-compliance-checker": "合规检查专员",
290
+ "support-support-responder": "客服响应专员",
291
+ "testing-accessibility-auditor": "无障碍测试工程师",
292
+ "testing-api-tester": "API 测试工程师",
293
+ "testing-evidence-collector": "质量记录专员",
294
+ "testing-performance-benchmarker": "性能基准测试工程师",
295
+ "testing-reality-checker": "验收测试工程师",
296
+ "testing-test-automation-engineer": "测试自动化工程师",
297
+ "testing-test-results-analyzer": "测试结果分析师",
298
+ "testing-tool-evaluator": "测试工具评估工程师",
299
+ "testing-workflow-optimizer": "测试流程优化工程师",
300
+ "blender-addon-engineer": "Blender 插件工程师",
301
+ "godot-gameplay-scripter": "Godot 玩法脚本工程师",
302
+ "godot-multiplayer-engineer": "Godot 多人联机工程师",
303
+ "godot-shader-developer": "Godot 着色器开发者",
304
+ "roblox-avatar-creator": "Roblox 虚拟形象创作者",
305
+ "roblox-experience-designer": "Roblox 体验设计师",
306
+ "roblox-systems-scripter": "Roblox 系统脚本工程师",
307
+ "unity-architect": "Unity 架构师",
308
+ "unity-editor-tool-developer": "Unity 编辑器工具开发者",
309
+ "unity-multiplayer-engineer": "Unity 多人联机工程师",
310
+ "unity-shader-graph-artist": "Unity 着色器美术",
311
+ "unreal-multiplayer-architect": "Unreal 多人联机架构师",
312
+ "unreal-systems-engineer": "Unreal 系统工程师",
313
+ "unreal-technical-artist": "Unreal 技术美术",
314
+ "unreal-world-builder": "Unreal 世界构建师",
315
+ "backend-architect-with-memory": "资深后端架构师"
316
+ };
317
+ //#endregion
318
+ //#region src/i18n.ts
319
+ /**
320
+ * 宿主侧用户可见文案。zh 为 key 集真相源;en 用 satisfies 校验完整性。
321
+ * 模板占位符使用 {word},与客户端 locale 服务约定一致。
322
+ */
323
+ /** 简体中文宿主文案(key 集真相源)。 */
324
+ const zhHost = {
325
+ "error.rootMissing": "智能体目录 root 不存在或无法访问:\"{root}\"。请设置环境变量 {env} 或提供正确路径。",
326
+ "error.rootNotDir": "智能体目录 root \"{root}\" 不是目录",
327
+ "error.catalogEmpty": "在 root \"{root}\" 下未发现任何智能体(*.md 文件)。请确认路径正确。",
328
+ "error.catalogLoad": "agency-agents 花名册加载失败:{detail}",
329
+ "error.expertRequired": "必须提供专家 slug 或名称",
330
+ "error.expertAmbiguous": "专家 \"{query}\" 有歧义;候选:{candidates}。请用 list_experts 选择精确 slug。",
331
+ "error.expertMissing": "没有匹配 \"{query}\" 的专家。请调用 list_experts 查看花名册。",
332
+ "error.expertDisabled": "专家 \"{name}\" 已停用",
333
+ "error.summonRequiresAgent": "summon_expert 需要由智能体调用",
334
+ "error.summonManyRequiresAgent": "summon_experts 需要由智能体调用",
335
+ "error.expertsEmpty": "experts 必须是非空数组",
336
+ "error.providerMissing": "子代理 provider \"{provider}\" 未注册",
337
+ "error.providerNoPersona": "子代理 provider \"{provider}\" 不支持专家人格",
338
+ "error.providerNoToolFilter": "子代理 provider \"{provider}\" 无法阻止递归专家委派",
339
+ "error.providerNoMaxDepth": "子代理 provider \"{provider}\" 不支持 maxDepth",
340
+ "error.expertRun": "专家运行以 \"{reason}\" 结束{detail}",
341
+ "error.partialOutput": "\n部分输出:\n{text}",
342
+ "error.maxDepth": "agency-agents 配置 maxDepth 必须是正安全整数",
343
+ "error.settingsMissing": "agency-agents 设置区尚未注册",
344
+ "list.empty": "暂无可用专家。",
345
+ "list.emptyDivision": "没有匹配分区 \"{division}\" 的专家。",
346
+ "list.heading": "{total} 位专家,覆盖 {count} 个分区:",
347
+ "list.group": "## {division}({count})"
348
+ };
349
+ /** 英文宿主文案,key 完整性由 satisfies 在编译期保证。 */
350
+ const enHost = {
351
+ "error.rootMissing": "Agent catalog root is missing or inaccessible: \"{root}\". Set {env} or provide a valid path.",
352
+ "error.rootNotDir": "Agent catalog root \"{root}\" is not a directory",
353
+ "error.catalogEmpty": "No agents (*.md files) found under root \"{root}\". Check the path.",
354
+ "error.catalogLoad": "agency-agents catalog failed to load: {detail}",
355
+ "error.expertRequired": "expert is required",
356
+ "error.expertAmbiguous": "Ambiguous expert \"{query}\"; candidates: {candidates}. Use list_experts to pick an exact slug.",
357
+ "error.expertMissing": "No expert matched \"{query}\". Call list_experts to see the roster.",
358
+ "error.expertDisabled": "expert \"{name}\" is disabled",
359
+ "error.summonRequiresAgent": "summon_expert requires a calling agent",
360
+ "error.summonManyRequiresAgent": "summon_experts requires a calling agent",
361
+ "error.expertsEmpty": "experts must be a non-empty array",
362
+ "error.providerMissing": "subagent provider \"{provider}\" is not registered",
363
+ "error.providerNoPersona": "subagent provider \"{provider}\" does not support expert personas",
364
+ "error.providerNoToolFilter": "subagent provider \"{provider}\" cannot prevent recursive expert delegation",
365
+ "error.providerNoMaxDepth": "subagent provider \"{provider}\" does not support maxDepth",
366
+ "error.expertRun": "expert run ended with \"{reason}\"{detail}",
367
+ "error.partialOutput": "\nPartial output:\n{text}",
368
+ "error.maxDepth": "agency-agents config maxDepth must be a positive safe integer",
369
+ "error.settingsMissing": "agency-agents settings section is not registered",
370
+ "list.empty": "No experts available.",
371
+ "list.emptyDivision": "No experts matched division \"{division}\".",
372
+ "list.heading": "{total} experts across {count} divisions:",
373
+ "list.group": "## {division} ({count})"
374
+ };
375
+ /** 将未知值收成 zh / en;只有显式 en 才走英文。 */
376
+ function resolveHostLocale(value) {
377
+ return value === "en" ? "en" : "zh";
378
+ }
379
+ /** 按当前语言格式化宿主文案。 */
380
+ function formatHost(locale, key, params) {
381
+ let text = (locale === "en" ? enHost : zhHost)[key];
382
+ if (params !== void 0) for (const [name, value] of Object.entries(params)) text = text.replaceAll("{" + name + "}", String(value));
383
+ return text;
384
+ }
385
+ /** 从宿主 settings 的 locale.preference 读取语言,缺失或异常时回退 zh。 */
386
+ function readHostLocale(ctx) {
387
+ if (ctx.settings?.get === void 0) return "zh";
388
+ try {
389
+ return resolveHostLocale(ctx.settings.get(settingsNamespace("locale"))?.preference);
390
+ } catch {
391
+ return "zh";
392
+ }
393
+ }
394
+ /** 分区查询同时认 key、中文名和英文名。 */
395
+ function matchDivision(query, division) {
396
+ const q = query.trim().toLowerCase();
397
+ if (q.length === 0) return false;
398
+ if (division.toLowerCase() === q) return true;
399
+ const zh = ZH_DIVISION[division];
400
+ if (zh !== void 0 && zh.toLowerCase() === q) return true;
401
+ const en = EN_DIVISION[division];
402
+ if (en !== void 0 && en.toLowerCase() === q) return true;
403
+ return false;
404
+ }
405
+ /** 按当前语言取分区显示名。 */
406
+ function localizedDivision(division, locale) {
407
+ if (locale === "en") return EN_DIVISION[division] ?? division;
408
+ return ZH_DIVISION[division] ?? division;
409
+ }
410
+ /** 按当前语言取专家显示名。 */
411
+ function localizedExpertName(expert, locale) {
412
+ return locale === "en" ? expert.nameEn : expert.name;
413
+ }
414
+ /** 按当前语言取专家简介;英文缺失时回退中文。 */
415
+ function localizedExpertDescription(expert, locale) {
416
+ return locale === "en" && expert.descriptionEn !== void 0 && expert.descriptionEn !== "" ? expert.descriptionEn : expert.description;
417
+ }
418
+ /** 渲染 list_experts 的用户可见文本。 */
419
+ function renderExpertList(locale, args, value) {
420
+ if (value.divisions.length === 0) {
421
+ const division = args.division === void 0 ? "" : String(args.division).trim();
422
+ return division === "" ? formatHost(locale, "list.empty") : formatHost(locale, "list.emptyDivision", { division });
423
+ }
424
+ const lines = [];
425
+ for (const group of value.divisions) {
426
+ lines.push(formatHost(locale, "list.group", {
427
+ division: localizedDivision(group.division, locale),
428
+ count: group.count
429
+ }));
430
+ for (const expert of group.experts ?? []) {
431
+ const mark = expert.emoji !== "" ? expert.emoji + " " : "";
432
+ lines.push("- " + mark + expert.name + " — `" + expert.slug + "` — " + expert.description);
433
+ }
434
+ }
435
+ lines.unshift(formatHost(locale, "list.heading", {
436
+ total: value.total,
437
+ count: value.divisions.length
438
+ }));
439
+ return lines.join("\n");
440
+ }
441
+ //#endregion
442
+ export { readHostLocale as a, ZH_NAME as c, matchDivision as i, localizedExpertDescription as n, renderExpertList as o, localizedExpertName as r, ZH_DIVISION as s, formatHost as t };
package/lib/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
+ import "@deepseek-ai/dsh-settings";
2
3
  import { Context } from "@deepseek-ai/cordis";
4
+ //#region src/i18n.d.ts
5
+ /** 与 DSH locale 插件一致的语言标识。 */
6
+ type LocaleId = 'zh' | 'en';
7
+ //#endregion
3
8
  //#region src/index.d.ts
4
9
  declare const name = "agency-agents";
5
10
  declare const inject: string[];
@@ -9,6 +14,7 @@ interface Expert {
9
14
  readonly name: string;
10
15
  readonly nameEn: string;
11
16
  readonly description: string;
17
+ readonly descriptionEn: string;
12
18
  readonly emoji: string;
13
19
  readonly division: string;
14
20
  readonly divisionZh: string;
@@ -31,6 +37,7 @@ declare function resolveCatalogRoot(root: string): string;
31
37
  interface Frontmatter {
32
38
  name?: string;
33
39
  description?: string;
40
+ descriptionEn?: string;
34
41
  emoji?: string;
35
42
  body: string;
36
43
  }
@@ -51,7 +58,7 @@ declare function resolveExpert<T extends {
51
58
  readonly slug: string;
52
59
  readonly name: string;
53
60
  readonly nameEn?: string;
54
- }>(experts: readonly T[], query: unknown): T;
61
+ }>(experts: readonly T[], query: unknown, locale?: LocaleId): T;
55
62
  declare function apply(ctx: Context, config: Config): void;
56
63
  //#endregion
57
64
  export { Config, apply, inject, loadCatalog, name, parseFrontmatter, resolveCatalogRoot, resolveExpert, sanitize, stripBom, truncate, unquote };
package/lib/index.js CHANGED
@@ -1,305 +1,10 @@
1
+ import { a as readHostLocale, c as ZH_NAME, i as matchDivision, n as localizedExpertDescription, o as renderExpertList, r as localizedExpertName, s as ZH_DIVISION, t as formatHost } from "./i18n-BmBLXFtD.js";
1
2
  import z from "@deepseek-ai/schemastery";
2
3
  import { defineTool } from "@deepseek-ai/dsh-tools";
3
4
  import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
4
5
  import { readFile, readdir, stat } from "node:fs/promises";
5
6
  import { join } from "node:path";
6
7
  import { fileURLToPath } from "node:url";
7
- //#region src/names.ts
8
- /** 分区目录名 → 中文分区名。 */
9
- const ZH_DIVISION = {
10
- academic: "学术",
11
- design: "设计",
12
- engineering: "工程",
13
- finance: "金融",
14
- "game-development": "游戏开发",
15
- gis: "地理信息",
16
- healthcare: "医疗健康",
17
- marketing: "市场营销",
18
- "paid-media": "付费媒体",
19
- product: "产品",
20
- "project-management": "项目管理",
21
- sales: "销售",
22
- security: "安全",
23
- "spatial-computing": "空间计算",
24
- specialized: "专业",
25
- support: "支持",
26
- testing: "测试"
27
- };
28
- /** 智能体 slug(文件名去 .md)→ 中文名(现实岗位)。缺省时回退英文 frontmatter name。 */
29
- const ZH_NAME = {
30
- "academic-anthropologist": "人类学家",
31
- "academic-geographer": "地理学家",
32
- "academic-historian": "历史学家",
33
- "academic-narratologist": "叙事学家",
34
- "academic-psychologist": "心理学家",
35
- "academic-statistician": "统计学家",
36
- "design-brand-guardian": "品牌视觉设计师",
37
- "design-image-prompt-engineer": "AI 图像设计师",
38
- "design-inclusive-visuals-specialist": "无障碍设计师",
39
- "design-persona-walkthrough": "用户体验设计师",
40
- "design-ui-designer": "UI 设计师",
41
- "design-ui-finish-gate-reviewer": "UI 视觉验收设计师",
42
- "design-ux-architect": "UX 架构师",
43
- "design-ux-researcher": "UX 研究员",
44
- "design-visual-storyteller": "视觉传达设计师",
45
- "design-whimsy-injector": "创意设计师",
46
- "engineering-ai-data-remediation-engineer": "AI 数据治理工程师",
47
- "engineering-ai-engineer": "AI 工程师",
48
- "engineering-api-platform-engineer": "API 平台工程师",
49
- "engineering-autonomous-optimization-architect": "自动化优化架构师",
50
- "engineering-backend-architect": "后端架构师",
51
- "engineering-cms-developer": "CMS 开发者",
52
- "engineering-code-reviewer": "代码审查工程师",
53
- "engineering-codebase-onboarding-engineer": "工程效率工程师",
54
- "engineering-data-engineer": "数据工程师",
55
- "engineering-data-visualization-engineer": "数据可视化工程师",
56
- "engineering-database-optimizer": "数据库性能工程师",
57
- "engineering-database-reliability-engineer": "数据库可靠性工程师",
58
- "engineering-desktop-app-engineer": "桌面应用工程师",
59
- "engineering-developer-tooling-engineer": "开发者工具工程师",
60
- "engineering-devops-automator": "DevOps 自动化工程师",
61
- "engineering-drupal-performance": "Drupal 性能工程师",
62
- "engineering-drupal-shopping-cart": "Drupal 购物车工程师",
63
- "engineering-email-intelligence-engineer": "邮件系统工程师",
64
- "engineering-embedded-firmware-engineer": "嵌入式固件工程师",
65
- "engineering-feishu-integration-developer": "飞书集成开发工程师",
66
- "engineering-filament-optimization-specialist": "Filament 后台优化专家",
67
- "engineering-finops-engineer": "FinOps 工程师",
68
- "engineering-frontend-developer": "前端开发者",
69
- "engineering-gaussdb-expert": "GaussDB 专家工程师",
70
- "engineering-git-workflow-master": "Git 工作流工程师",
71
- "engineering-i18n-engineer": "国际化工程师",
72
- "engineering-identity-access-engineer": "身份与访问管理工程师",
73
- "engineering-incident-response-commander": "故障应急工程师",
74
- "engineering-iot-fleet-engineer": "物联网设备工程师",
75
- "engineering-it-service-manager": "IT 服务经理",
76
- "engineering-llm-post-training-engineer": "LLM 后训练工程师",
77
- "engineering-minimal-change-engineer": "低风险变更工程师",
78
- "engineering-mobile-app-builder": "移动应用开发工程师",
79
- "engineering-mobile-release-engineer": "移动发布工程师",
80
- "engineering-multi-agent-systems-architect": "多智能体系统架构师",
81
- "engineering-network-engineer": "网络工程师",
82
- "engineering-orgscript-engineer": "OrgScript 工程师",
83
- "engineering-payments-billing-engineer": "支付计费工程师",
84
- "engineering-privacy-engineer": "隐私工程师",
85
- "engineering-prompt-engineer": "提示词工程师",
86
- "engineering-rag-pipeline-engineer": "RAG 管线工程师",
87
- "engineering-rapid-prototyper": "快速原型工程师",
88
- "engineering-realtime-collaboration-engineer": "实时协作工程师",
89
- "engineering-rust-refactoring-specialist": "Rust 重构工程师",
90
- "engineering-search-relevance-engineer": "搜索相关性工程师",
91
- "engineering-section-508-specialist": "无障碍合规工程师",
92
- "engineering-senior-developer": "高级开发者",
93
- "engineering-software-architect": "软件架构师",
94
- "engineering-solidity-smart-contract-engineer": "Solidity 智能合约工程师",
95
- "engineering-sre": "SRE(站点可靠性工程师)",
96
- "engineering-technical-writer": "技术文档工程师",
97
- "engineering-uswds-developer": "USWDS 开发者",
98
- "engineering-video-streaming-engineer": "视频流工程师",
99
- "engineering-voice-ai-integration-engineer": "语音 AI 集成工程师",
100
- "engineering-webassembly-engineer": "WebAssembly 工程师",
101
- "engineering-wechat-mini-program-developer": "微信小程序开发者",
102
- "engineering-wordpress-performance": "WordPress 性能工程师",
103
- "engineering-wordpress-shopping-cart": "WordPress 购物车工程师",
104
- "finance-bookkeeper-controller": "财务会计主管",
105
- "finance-financial-analyst": "财务分析师",
106
- "finance-fpa-analyst": "财务计划分析师",
107
- "finance-investment-researcher": "投资研究员",
108
- "finance-tax-strategist": "税务筹划师",
109
- "economy-designer": "经济系统设计师",
110
- "game-audio-engineer": "游戏音频工程师",
111
- "game-designer": "游戏设计师",
112
- "level-designer": "关卡设计师",
113
- "narrative-designer": "叙事设计师",
114
- "technical-artist": "技术美术",
115
- "gis-3d-scene-developer": "3D 场景开发者",
116
- "gis-analyst": "GIS 分析师",
117
- "gis-bim-specialist": "BIM/GIS 专家",
118
- "gis-cartography-designer": "制图设计师",
119
- "gis-drone-reality-mapping": "无人机/实景测绘专家",
120
- "gis-geoai-ml-engineer": "地理 AI/ML 工程师",
121
- "gis-geoprocessing-specialist": "地理处理专家",
122
- "gis-qa-engineer": "GIS QA 工程师",
123
- "gis-solution-engineer": "解决方案工程师",
124
- "gis-spatial-data-engineer": "空间数据工程师",
125
- "gis-spatial-data-scientist": "空间数据科学家",
126
- "gis-technical-consultant": "技术顾问",
127
- "gis-web-gis-developer": "Web GIS 开发者",
128
- "healthcare-clinical-evidence-agent": "循证医学研究员",
129
- "healthcare-innovation-strategist": "医疗创新战略顾问",
130
- "healthcare-sovereign-health-systems-agent": "医疗系统治理顾问",
131
- "marketing-aeo-foundations": "AEO 搜索优化师",
132
- "marketing-agentic-search-optimizer": "AI 搜索优化师",
133
- "marketing-ai-citation-strategist": "AI 引用优化师",
134
- "marketing-app-store-optimizer": "应用商店优化师",
135
- "marketing-baidu-seo-specialist": "百度 SEO 专家",
136
- "marketing-bilibili-content-strategist": "B站内容运营专家",
137
- "marketing-book-co-author": "图书策划编辑",
138
- "marketing-carousel-growth-engine": "内容增长运营专家",
139
- "marketing-china-ecommerce-operator": "中国电商运营",
140
- "marketing-china-market-localization-strategist": "中国市场本地化专家",
141
- "marketing-content-creator": "内容创作者",
142
- "marketing-cross-border-ecommerce": "跨境电商专家",
143
- "marketing-douyin-strategist": "抖音运营专家",
144
- "marketing-email-strategist": "邮件营销专家",
145
- "marketing-global-podcast-strategist": "播客运营专家",
146
- "marketing-growth-hacker": "增长营销专家",
147
- "marketing-instagram-curator": "Instagram 运营",
148
- "marketing-kuaishou-strategist": "快手运营专家",
149
- "marketing-linkedin-content-creator": "LinkedIn 内容创作者",
150
- "marketing-livestream-commerce-coach": "直播电商运营专家",
151
- "marketing-multi-platform-publisher": "多平台内容运营专家",
152
- "marketing-podcast-strategist": "播客运营专家",
153
- "marketing-pr-communications-manager": "公关传播经理",
154
- "marketing-private-domain-operator": "私域运营",
155
- "marketing-reddit-community-builder": "Reddit 社区运营",
156
- "marketing-seo-specialist": "SEO 专家",
157
- "marketing-short-video-editing-coach": "短视频剪辑师",
158
- "marketing-social-media-strategist": "社媒运营专家",
159
- "marketing-tiktok-strategist": "TikTok 运营专家",
160
- "marketing-twitter-engager": "Twitter 互动运营",
161
- "marketing-video-optimization-specialist": "视频优化专家",
162
- "marketing-wechat-official-account": "公众号运营",
163
- "marketing-weibo-strategist": "微博运营专家",
164
- "marketing-x-twitter-intelligence-analyst": "X/Twitter 舆情分析师",
165
- "marketing-xiaohongshu-specialist": "小红书运营专家",
166
- "marketing-zhihu-strategist": "知乎运营专家",
167
- "paid-media-auditor": "广告投放审计师",
168
- "paid-media-creative-strategist": "广告创意策划师",
169
- "paid-media-paid-social-strategist": "付费社媒投放专家",
170
- "paid-media-ppc-strategist": "PPC 投放优化师",
171
- "paid-media-programmatic-buyer": "程序化广告投放师",
172
- "paid-media-search-query-analyst": "搜索词分析师",
173
- "paid-media-tracking-specialist": "广告归因分析师",
174
- "product-behavioral-nudge-engine": "增长产品经理",
175
- "product-feedback-synthesizer": "用户反馈研究员",
176
- "product-manager": "产品经理",
177
- "product-sprint-prioritizer": "需求优先级分析师",
178
- "product-trend-researcher": "趋势研究员",
179
- "project-management-experiment-tracker": "实验项目运营",
180
- "project-management-jira-workflow-steward": "Jira 流程管理员",
181
- "project-management-meeting-notes-specialist": "项目记录专员",
182
- "project-management-project-shepherd": "项目推进专员",
183
- "project-management-studio-operations": "工作室运营",
184
- "project-management-studio-producer": "工作室制片人",
185
- "project-manager-senior": "高级项目经理",
186
- "sales-account-strategist": "大客户经理",
187
- "sales-coach": "销售培训师",
188
- "sales-deal-strategist": "商务谈判顾问",
189
- "sales-discovery-coach": "售前需求顾问",
190
- "sales-engineer": "销售工程师",
191
- "sales-offer-lead-gen-strategist": "销售获客专员",
192
- "sales-outbound-strategist": "外呼销售专员",
193
- "sales-pipeline-analyst": "销售管线分析师",
194
- "sales-proposal-strategist": "方案提案顾问",
195
- "security-ai-generated-code-auditor": "AI 生成代码安全审计师",
196
- "security-appsec-engineer": "应用安全工程师",
197
- "security-architect": "安全架构师",
198
- "security-blockchain-security-auditor": "区块链安全审计师",
199
- "security-cloud-security-architect": "云安全架构师",
200
- "security-compliance-auditor": "合规审计师",
201
- "security-incident-responder": "应急响应工程师",
202
- "security-penetration-tester": "渗透测试工程师",
203
- "security-secrets-credential-engineer": "密钥与凭据治理工程师",
204
- "security-senior-secops": "高级安全运营工程师",
205
- "security-threat-detection-engineer": "威胁检测工程师",
206
- "security-threat-intelligence-analyst": "威胁情报分析师",
207
- "macos-spatial-metal-engineer": "macOS 空间/Metal 工程师",
208
- "terminal-integration-specialist": "终端集成专家",
209
- "visionos-spatial-engineer": "visionOS 空间工程师",
210
- "xr-cockpit-interaction-specialist": "XR 座舱交互专家",
211
- "xr-immersive-developer": "XR 沉浸式开发者",
212
- "xr-interface-architect": "XR 界面架构师",
213
- "accounts-payable-agent": "应付账款会计",
214
- "agentic-identity-trust": "身份与信任架构师",
215
- "agents-orchestrator": "AI 流程编排师",
216
- "automation-governance-architect": "自动化治理架构师",
217
- "business-strategist": "商业策略顾问",
218
- "change-management-consultant": "变革管理顾问",
219
- "chief-financial-officer": "首席财务官",
220
- "corporate-training-designer": "企业培训师",
221
- "customer-service": "客户服务",
222
- "customer-success-manager": "客户成功经理",
223
- "data-consolidation-agent": "数据整合专员",
224
- "data-privacy-officer": "数据隐私官",
225
- "esg-sustainability-officer": "ESG 与可持续发展官",
226
- "government-digital-presales-consultant": "政务数字化售前顾问",
227
- "grant-writer": "基金申报专员",
228
- "healthcare-aging-parent-care-companion": "老年照护顾问",
229
- "healthcare-customer-service": "医疗客服",
230
- "healthcare-marketing-compliance": "医疗营销合规专家",
231
- "hospitality-guest-services": "酒店宾客服务",
232
- "hr-onboarding": "HR 入职专员",
233
- "identity-graph-operator": "身份图谱运营",
234
- "language-translator": "翻译专员",
235
- "legal-billing-time-tracking": "法务计费专员",
236
- "legal-client-intake": "法务客户接待专员",
237
- "legal-document-review": "法务文档审核员",
238
- "loan-officer-assistant": "信贷专员助理",
239
- "lsp-index-engineer": "LSP/索引工程师",
240
- "ma-integration-manager": "并购整合经理",
241
- "medical-billing-coding-specialist": "医疗计费编码专家",
242
- "operations-manager": "运营经理",
243
- "organizational-psychologist": "组织心理学家",
244
- "personal-growth-mentor": "职业发展导师",
245
- "real-estate-buyer-seller": "房产买卖顾问",
246
- "recruitment-specialist": "招聘专员",
247
- "report-distribution-agent": "报告分发专员",
248
- "resume-tailor": "简历优化顾问",
249
- "retail-customer-returns": "零售售后客服",
250
- "sales-data-extraction-agent": "销售数据专员",
251
- "sales-outreach": "销售拓展专员",
252
- "specialized-chief-of-staff": "幕僚长",
253
- "specialized-civil-engineer": "土木工程师",
254
- "specialized-codebase-archaeologist": "遗留系统工程师",
255
- "specialized-cultural-intelligence-strategist": "跨文化咨询顾问",
256
- "specialized-developer-advocate": "开发者布道师",
257
- "specialized-document-generator": "文档工程师",
258
- "specialized-fedramp-rmf-compliance": "FedRAMP 与 RMF 合规工程师",
259
- "specialized-french-consulting-market": "法国市场咨询顾问",
260
- "specialized-korean-business-navigator": "韩国市场咨询顾问",
261
- "specialized-mcp-builder": "MCP 集成工程师",
262
- "specialized-model-qa": "模型质量评估工程师",
263
- "specialized-pricing-analyst": "定价分析师",
264
- "specialized-salesforce-architect": "Salesforce 架构师",
265
- "specialized-strategy-duel-agent": "竞争战略分析师",
266
- "specialized-workflow-architect": "工作流架构师",
267
- "study-abroad-advisor": "留学顾问",
268
- "supply-chain-strategist": "供应链规划师",
269
- "zk-steward": "零知识证明工程师",
270
- "support-analytics-reporter": "分析报表专员",
271
- "support-executive-summary-generator": "管理报告专员",
272
- "support-finance-tracker": "财务跟踪专员",
273
- "support-infrastructure-maintainer": "基础设施运维工程师",
274
- "support-legal-compliance-checker": "合规检查专员",
275
- "support-support-responder": "客服响应专员",
276
- "testing-accessibility-auditor": "无障碍测试工程师",
277
- "testing-api-tester": "API 测试工程师",
278
- "testing-evidence-collector": "质量记录专员",
279
- "testing-performance-benchmarker": "性能基准测试工程师",
280
- "testing-reality-checker": "验收测试工程师",
281
- "testing-test-automation-engineer": "测试自动化工程师",
282
- "testing-test-results-analyzer": "测试结果分析师",
283
- "testing-tool-evaluator": "测试工具评估工程师",
284
- "testing-workflow-optimizer": "测试流程优化工程师",
285
- "blender-addon-engineer": "Blender 插件工程师",
286
- "godot-gameplay-scripter": "Godot 玩法脚本工程师",
287
- "godot-multiplayer-engineer": "Godot 多人联机工程师",
288
- "godot-shader-developer": "Godot 着色器开发者",
289
- "roblox-avatar-creator": "Roblox 虚拟形象创作者",
290
- "roblox-experience-designer": "Roblox 体验设计师",
291
- "roblox-systems-scripter": "Roblox 系统脚本工程师",
292
- "unity-architect": "Unity 架构师",
293
- "unity-editor-tool-developer": "Unity 编辑器工具开发者",
294
- "unity-multiplayer-engineer": "Unity 多人联机工程师",
295
- "unity-shader-graph-artist": "Unity 着色器美术",
296
- "unreal-multiplayer-architect": "Unreal 多人联机架构师",
297
- "unreal-systems-engineer": "Unreal 系统工程师",
298
- "unreal-technical-artist": "Unreal 技术美术",
299
- "unreal-world-builder": "Unreal 世界构建师",
300
- "backend-architect-with-memory": "资深后端架构师"
301
- };
302
- //#endregion
303
8
  //#region src/index.ts
304
9
  const name = "agency-agents";
305
10
  const inject = [
@@ -351,7 +56,7 @@ function resolveCatalogRoot(root) {
351
56
  /** 规范化可选深度上限:配置表单的空值等同于未设置,其他值必须允许至少一层子代理。 */
352
57
  function normalizeMaxDepth(value) {
353
58
  if (value === void 0 || value === null) return void 0;
354
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1) throw new Error("agency-agents config maxDepth must be a positive safe integer");
59
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1) throw new Error(formatHost("zh", "error.maxDepth"));
355
60
  return value;
356
61
  }
357
62
  /** Neutralize strict `{{...}}` template interpolation inside expert prose. */
@@ -386,6 +91,7 @@ function parseFrontmatter(raw) {
386
91
  return {
387
92
  name: get("name"),
388
93
  description: get("description"),
94
+ descriptionEn: get("descriptionEn"),
389
95
  emoji: get("emoji"),
390
96
  body
391
97
  };
@@ -397,8 +103,11 @@ function textBlocks(blocks) {
397
103
  /** 校验 root 目录存在且为目录,否则抛出明确错误(避免静默得到空列表)。 */
398
104
  async function assertDirectory(root) {
399
105
  const info = await stat(root).catch(() => void 0);
400
- if (info === void 0) throw new Error(`智能体目录 root 不存在或无法访问:"${root}"。请设置环境变量 ${ROOT_ENV} 或提供正确路径。`);
401
- if (!info.isDirectory()) throw new Error(`智能体目录 root "${root}" 不是目录`);
106
+ if (info === void 0) throw new Error(formatHost("zh", "error.rootMissing", {
107
+ root,
108
+ env: ROOT_ENV
109
+ }));
110
+ if (!info.isDirectory()) throw new Error(formatHost("zh", "error.rootNotDir", { root }));
402
111
  }
403
112
  /** 递归遍历目录下的所有 .md 文件,逐个回调其绝对路径与文件名。 */
404
113
  async function walkMarkdown(dir, onFile) {
@@ -437,19 +146,20 @@ async function loadCatalog(root, divisions) {
437
146
  name: ZH_NAME[slug] ?? parsed.name,
438
147
  nameEn: parsed.name,
439
148
  description: parsed.description,
149
+ descriptionEn: parsed.descriptionEn ?? "",
440
150
  emoji: parsed.emoji ?? "",
441
151
  division: source.division,
442
152
  divisionZh: ZH_DIVISION[source.division] ?? source.division,
443
153
  persona: sanitize(parsed.body)
444
154
  });
445
155
  });
446
- if (map.size === 0) throw new Error(`在 root "${root}" 下未发现任何智能体(*.md 文件)。请确认路径正确。`);
156
+ if (map.size === 0) throw new Error(formatHost("zh", "error.catalogEmpty", { root }));
447
157
  return map;
448
158
  }
449
159
  /** 根据 slug 或名称解析智能体;任意多命中都必须要求调用者提供更精确的 slug。 */
450
- function resolveExpert(experts, query) {
160
+ function resolveExpert(experts, query, locale = "zh") {
451
161
  const q = String(query).trim().toLowerCase();
452
- if (q.length === 0) throw new Error("expert is required");
162
+ if (q.length === 0) throw new Error(formatHost(locale, "error.expertRequired"));
453
163
  const bySlug = experts.find((expert) => expert.slug.toLowerCase() === q);
454
164
  if (bySlug !== void 0) return bySlug;
455
165
  const exactNames = experts.filter((expert) => expert.name.toLowerCase() === q || expert.nameEn?.toLowerCase() === q);
@@ -458,9 +168,12 @@ function resolveExpert(experts, query) {
458
168
  if (matches.length === 1) return matches[0];
459
169
  if (matches.length > 1) {
460
170
  const preview = matches.slice(0, 12).map((expert) => expert.slug).join(", ");
461
- throw new Error(`Ambiguous expert "${String(query)}"; candidates: ${preview}. Use list_experts to pick an exact slug.`);
171
+ throw new Error(formatHost(locale, "error.expertAmbiguous", {
172
+ query: String(query),
173
+ candidates: preview
174
+ }));
462
175
  }
463
- throw new Error(`No expert matched "${String(query)}". Call list_experts to see the roster.`);
176
+ throw new Error(formatHost(locale, "error.expertMissing", { query: String(query) }));
464
177
  }
465
178
  function apply(ctx, config) {
466
179
  const maxDepth = normalizeMaxDepth(config.maxDepth);
@@ -472,6 +185,7 @@ function apply(ctx, config) {
472
185
  onChange: () => {}
473
186
  });
474
187
  const enabledSet = () => new Set(enabledSource());
188
+ const activeLocale = () => readHostLocale(ctx);
475
189
  let experts = /* @__PURE__ */ new Map();
476
190
  let loadError = null;
477
191
  const ready = loadCatalog(resolveCatalogRoot(config.root), config.divisions).then((map) => {
@@ -481,9 +195,9 @@ function apply(ctx, config) {
481
195
  });
482
196
  async function ensureReady() {
483
197
  await ready;
484
- if (loadError !== null) throw new Error(`agency-agents catalog failed to load: ${loadError}`);
198
+ if (loadError !== null) throw new Error(formatHost(activeLocale(), "error.catalogLoad", { detail: loadError }));
485
199
  }
486
- function groupByDivision(withExperts) {
200
+ function groupByDivision(withExperts, locale) {
487
201
  const groups = /* @__PURE__ */ new Map();
488
202
  const enabled = enabledSet();
489
203
  for (const expert of experts.values()) {
@@ -497,9 +211,9 @@ function apply(ctx, config) {
497
211
  count: list.length,
498
212
  ...withExperts ? { experts: list.slice().sort((a, b) => a.slug.localeCompare(b.slug)).map((e) => ({
499
213
  slug: e.slug,
500
- name: e.name,
214
+ name: localizedExpertName(e, locale),
501
215
  emoji: e.emoji,
502
- description: truncate(e.description, DESCRIPTION_LIMIT)
216
+ description: truncate(localizedExpertDescription(e, locale), DESCRIPTION_LIMIT)
503
217
  })) } : {}
504
218
  }));
505
219
  }
@@ -528,34 +242,22 @@ function apply(ctx, config) {
528
242
  },
529
243
  render: (args, value) => {
530
244
  const divisions = value.divisions;
531
- if (divisions.length === 0) {
532
- const division = args.division === void 0 ? "" : String(args.division).trim();
533
- return [{
534
- type: "text",
535
- text: division === "" ? "No experts available." : `No experts matched division "${division}".`
536
- }];
537
- }
538
- const lines = [];
539
- for (const group of divisions) {
540
- lines.push(`## ${group.division} (${group.count})`);
541
- for (const expert of group.experts ?? []) lines.push(`- ${expert.emoji ? `${expert.emoji} ` : ""}${expert.name} — \`${expert.slug}\` — ${expert.description}`);
542
- }
543
- lines.unshift(`${value.total} experts across ${divisions.length} divisions:`);
544
245
  return [{
545
246
  type: "text",
546
- text: lines.join("\n")
247
+ text: renderExpertList(activeLocale(), args, {
248
+ divisions,
249
+ total: value.total
250
+ })
547
251
  }];
548
252
  }
549
253
  },
550
254
  async execute(args) {
551
255
  await ensureReady();
552
- const query = args.division === void 0 ? "" : String(args.division).trim().toLowerCase();
256
+ const query = args.division === void 0 ? "" : String(args.division).trim();
553
257
  const hasFilter = query !== "";
554
- const groups = groupByDivision(hasFilter);
258
+ const groups = groupByDivision(hasFilter, activeLocale());
555
259
  if (hasFilter) {
556
- const filtered = groups.filter((g) => {
557
- return g.division.toLowerCase() === query;
558
- });
260
+ const filtered = groups.filter((g) => matchDivision(query, g.division));
559
261
  return {
560
262
  divisions: filtered,
561
263
  total: filtered.reduce((n, g) => n + g.count, 0)
@@ -568,14 +270,15 @@ function apply(ctx, config) {
568
270
  }
569
271
  }));
570
272
  async function runExpert(query, task, exec) {
571
- if (exec.agent === void 0) throw new Error("summon_expert requires a calling agent");
273
+ const locale = activeLocale();
274
+ if (exec.agent === void 0) throw new Error(formatHost(locale, "error.summonRequiresAgent"));
572
275
  const provider = ctx.subagents.getProvider(config.provider);
573
- if (provider === void 0) throw new Error(`subagent provider "${config.provider}" is not registered`);
574
- if (!provider.capabilities.persona) throw new Error(`subagent provider "${config.provider}" does not support expert personas`);
575
- if (!provider.capabilities.toolFilter) throw new Error(`subagent provider "${config.provider}" cannot prevent recursive expert delegation`);
576
- if (maxDepth !== void 0 && !provider.capabilities.depthLimit) throw new Error(`subagent provider "${config.provider}" does not support maxDepth`);
577
- const expert = resolveExpert([...experts.values()], query);
578
- if (!enabledSet().has(expert.slug)) throw new Error(`expert "${expert.name}" is disabled`);
276
+ if (provider === void 0) throw new Error(formatHost(locale, "error.providerMissing", { provider: config.provider }));
277
+ if (!provider.capabilities.persona) throw new Error(formatHost(locale, "error.providerNoPersona", { provider: config.provider }));
278
+ if (!provider.capabilities.toolFilter) throw new Error(formatHost(locale, "error.providerNoToolFilter", { provider: config.provider }));
279
+ if (maxDepth !== void 0 && !provider.capabilities.depthLimit) throw new Error(formatHost(locale, "error.providerNoMaxDepth", { provider: config.provider }));
280
+ const expert = resolveExpert([...experts.values()], query, locale);
281
+ if (!enabledSet().has(expert.slug)) throw new Error(formatHost(locale, "error.expertDisabled", { name: localizedExpertName(expert, locale) }));
579
282
  const run = await ctx.subagents.start(config.provider, {
580
283
  label: `expert:${expert.slug}`,
581
284
  prompt: [{
@@ -596,8 +299,11 @@ function apply(ctx, config) {
596
299
  const result = await run.result;
597
300
  const text = textBlocks(result.output);
598
301
  if (result.stopReason !== "completed") {
599
- const detail = text.length > 0 ? `\nPartial output:\n${text}` : "";
600
- throw new Error(`expert run ended with "${result.stopReason}"${detail}`);
302
+ const detail = text.length > 0 ? formatHost(locale, "error.partialOutput", { text }) : "";
303
+ throw new Error(formatHost(locale, "error.expertRun", {
304
+ reason: result.stopReason,
305
+ detail
306
+ }));
601
307
  }
602
308
  return {
603
309
  expert: expert.slug,
@@ -690,9 +396,9 @@ function apply(ctx, config) {
690
396
  },
691
397
  async execute(args, exec) {
692
398
  await ensureReady();
693
- if (exec.agent === void 0) throw new Error("summon_experts requires a calling agent");
399
+ if (exec.agent === void 0) throw new Error(formatHost(activeLocale(), "error.summonManyRequiresAgent"));
694
400
  const specs = args.experts;
695
- if (!Array.isArray(specs) || specs.length === 0) throw new Error("experts must be a non-empty array");
401
+ if (!Array.isArray(specs) || specs.length === 0) throw new Error(formatHost(activeLocale(), "error.expertsEmpty"));
696
402
  return { results: await Promise.all(specs.map((spec) => runExpert(spec.expert, spec.task, exec))) };
697
403
  }
698
404
  }));
package/lib/remote.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as formatHost } from "./i18n-BmBLXFtD.js";
1
2
  import { settingsNamespace } from "@deepseek-ai/dsh-settings";
2
3
  import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
3
4
  import { z } from "zod";
@@ -157,7 +158,7 @@ let AgencyAgentsRemote = (() => {
157
158
  getEnabled() {
158
159
  const enabled = this.ctx.settings.get(settingsNamespace("agency-agents"))?.enabled;
159
160
  const descriptor = this.ctx.settings.describe().find((candidate) => candidate.ns === settingsNamespace("agency-agents"));
160
- if (descriptor === void 0) throw new Error("agency-agents 设置区尚未注册");
161
+ if (descriptor === void 0) throw new Error(formatHost("zh", "error.settingsMissing"));
161
162
  return {
162
163
  enabled: Array.isArray(enabled) ? enabled.filter((slug) => typeof slug === "string") : [],
163
164
  revision: descriptor.revision
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@michengai/dsh-agency-agents",
3
3
  "description": "Agency Experts — a summonable domain-expert roster for DSH (expert mode)",
4
- "version": "0.1.13",
4
+ "version": "0.1.14",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",