dsh-ant 0.5.12 → 0.6.1

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/index.js CHANGED
@@ -2,6 +2,7 @@ export const name = 'ant'
2
2
 
3
3
  import { createHash } from 'node:crypto'
4
4
  import { createRequire } from 'node:module'
5
+ import { readFile } from 'node:fs/promises'
5
6
  import { installSkill, listSkills, uninstallSkill } from './skill-install.js'
6
7
  import { readLocalDelegationSettings, recentDelegationStatus, startDelegationHost,
7
8
  writeLocalDelegationSettings } from './delegation.js'
@@ -13,6 +14,7 @@ const BRANDING_PATH = '/api/ant-teams/branding'
13
14
  const SERVICE_INFO_PATH = '/api/ant-teams/service-info'
14
15
  const DSH_COMPATIBILITY_PATH = '/api/ant-teams/dsh-compatibility'
15
16
  const BUNDLE_RELEASE_PATH = '/api/ant-teams/bundle-release'
17
+ const LOCALE_MESSAGES_PATH = '/api/ant-teams/locale-messages'
16
18
  const CONNECTION_ORIGIN_PATH = '/api/ant-teams/connection-origin'
17
19
  const DISCONNECT_PATH = '/api/ant-teams/disconnect'
18
20
  const REQUEST_CODE_PATH = '/api/ant-teams/request-code'
@@ -27,6 +29,7 @@ const DELEGATION_GRANTS_PATH = '/api/ant-teams/delegation/grants'
27
29
  const DELEGATION_ENROLLED_BOTS_PATH = '/api/ant-teams/delegation/enrolled-bots'
28
30
  const DELEGATION_GROUPS_PATH = '/api/ant-teams/delegation/groups'
29
31
  const DELEGATION_DM_CHAT_PATH = '/api/ant-teams/delegation/dm-chat'
32
+ const DELEGATION_OWNER_CHALLENGE_PATH = '/api/ant-teams/delegation/owner-challenge'
30
33
  const DELEGATION_STATUS_PATH = '/api/ant-teams/delegation/status'
31
34
  const DELEGATION_CARDS_PATH = '/api/ant-teams/delegation/cards'
32
35
  const DELEGATION_RULE_RECOGNITION_PATH = '/api/ant-teams/delegation/recognize'
@@ -52,6 +55,16 @@ function jsonResponse(status, value) {
52
55
  })
53
56
  }
54
57
 
58
+ async function fetchLocaleMessages(request) {
59
+ if (request.method !== 'GET') return jsonResponse(405, { message: '只支持 GET 请求。' })
60
+ try {
61
+ const source = await readFile(new URL('./locale/messages.json', import.meta.url), 'utf8')
62
+ return jsonResponse(200, JSON.parse(source))
63
+ } catch {
64
+ return jsonResponse(500, { message: 'ANT 界面语言资源无法读取。' })
65
+ }
66
+ }
67
+
55
68
  export async function readDshCompatibility(requiredRange = DSH_ENGINE_RANGE,
56
69
  loadAppBoot = () => import('@deepseek-ai/dsh-app-boot')) {
57
70
  try {
@@ -119,7 +132,7 @@ async function fetchDshCompatibility(request) {
119
132
 
120
133
  function modelProviderConfigHeader(request) {
121
134
  const version = request.headers.get('x-ant-model-provider-config')
122
- return version === '1' || version === '2' ? { 'x-ant-model-provider-config': version } : {}
135
+ return version === '1' || version === '2' || version === '3' ? { 'x-ant-model-provider-config': version } : {}
123
136
  }
124
137
 
125
138
  function normalizeServiceUrl(value) {
@@ -281,6 +294,7 @@ async function fetchMemberModels(request, credentials, settings) {
281
294
  models: result.models,
282
295
  default_model: result.default_model ?? null,
283
296
  ...(result.model_provider_config_version === 1 || result.model_provider_config_version === 2
297
+ || result.model_provider_config_version === 3
284
298
  ? { model_provider_config_version: result.model_provider_config_version } : {}),
285
299
  })
286
300
  } catch {
@@ -387,7 +401,7 @@ async function fetchDelegationGroupSettings(request, ctx, credentials, settings,
387
401
  body = JSON.parse(raw)
388
402
  } catch { return jsonResponse(400, { message: '请求格式无效。' }) }
389
403
  }
390
- if (kind === 'bots' && request.method === 'POST') {
404
+ if (['bots', 'challenge'].includes(kind) && request.method === 'POST') {
391
405
  const service = dshImService(ctx)
392
406
  if (!service?.describeBot) return jsonResponse(503, { message: '请先安装并启用 DSH-IM。' })
393
407
  try {
@@ -404,6 +418,7 @@ async function fetchDelegationGroupSettings(request, ctx, credentials, settings,
404
418
  }
405
419
  const path = kind === 'groups' ? '/api/me/im-delegations/groups'
406
420
  : kind === 'dm-chat' ? '/api/me/im-delegations/dm-chat'
421
+ : kind === 'challenge' ? '/api/me/im-delegations/owner-challenge'
407
422
  : request.method === 'DELETE'
408
423
  ? `/api/me/im-delegations/bots/${encodeURIComponent(body.bot_id)}`
409
424
  : '/api/me/im-delegations/bots'
@@ -417,6 +432,7 @@ async function fetchDelegationGroupSettings(request, ctx, credentials, settings,
417
432
  method: request.method,
418
433
  headers: { authorization: `Bearer ${connection.token}`, accept: 'application/json',
419
434
  ...(request.method !== 'GET' ? { origin: new URL(connection.serviceUrl).origin } : {}),
435
+ ...(kind === 'challenge' ? { 'x-ant-owner-approval-version': '1' } : {}),
420
436
  ...(['POST', 'PUT'].includes(request.method) ? { 'content-type': 'application/json' } : {}) },
421
437
  ...(['POST', 'PUT'].includes(request.method) ? { body: JSON.stringify(body) } : {}),
422
438
  redirect: 'manual', signal: AbortSignal.timeout(12_000),
@@ -589,12 +605,14 @@ async function fetchDelegationExecutors(request, ctx) {
589
605
  if (Array.isArray(listed)) providers = listed
590
606
  } catch {}
591
607
  const available = new Set(providers)
592
- const externalProviderReason = 'DSH 尚未提供可核验的逐任务文件、Git 和网络权限;ANT 暂不把外部子 Agent 用于协作任务。'
608
+ const providerReason = (name) => `DSH 尚未启用 ${name} 子 Agent 提供方。`
593
609
  return jsonResponse(200, [
594
610
  { id: 'dsh', title: 'DSH', available: Boolean(optionalHostService(ctx, 'sessionController')
595
611
  && optionalHostService(ctx, 'agents')) },
596
- { id: 'codex', title: 'Codex', available: false, reason: externalProviderReason },
597
- { id: 'claude-code', title: 'Claude Code', available: false, reason: externalProviderReason },
612
+ { id: 'codex', title: 'Codex', available: available.has('codex'),
613
+ ...(!available.has('codex') ? { reason: providerReason('Codex') } : {}) },
614
+ { id: 'claude-code', title: 'Claude Code', available: available.has('claude-code'),
615
+ ...(!available.has('claude-code') ? { reason: providerReason('Claude Code') } : {}) },
598
616
  { id: 'acp', title: 'DSH ACP', available: available.has('acp') },
599
617
  { id: 'dsh-sdk', title: 'DSH SDK 子代理', available: available.has('dsh-sdk') },
600
618
  ])
@@ -1034,6 +1052,9 @@ async function fetchAuthRequest(request, endpoint, credentials, settings) {
1034
1052
  accept: 'application/json',
1035
1053
  'content-type': 'application/json',
1036
1054
  origin: serviceUrl,
1055
+ ...(endpoint === 'request-code' && /^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u.test(request.headers.get('x-ant-locale') || '')
1056
+ ? { 'x-ant-locale': request.headers.get('x-ant-locale') }
1057
+ : {}),
1037
1058
  ...(endpoint === 'dsh-connect' ? modelProviderConfigHeader(request) : {}),
1038
1059
  },
1039
1060
  body: JSON.stringify(payload),
@@ -1072,6 +1093,12 @@ async function fetchAuthRequest(request, endpoint, credentials, settings) {
1072
1093
  export function apply(ctx) {
1073
1094
  ctx.inject(['connection', 'credentials', 'settings'], (connectionCtx) => {
1074
1095
  let delegationHost = null
1096
+ connectionCtx.effect(() => connectionCtx.connection.fetch.register({
1097
+ path: LOCALE_MESSAGES_PATH,
1098
+ methods: ['GET'],
1099
+ requestBody: 'buffered',
1100
+ fetch: fetchLocaleMessages,
1101
+ }), 'ant-teams: local UI locale catalogs')
1075
1102
  connectionCtx.effect(() => connectionCtx.connection.fetch.register({
1076
1103
  path: SERVICE_INFO_PATH,
1077
1104
  methods: ['POST'],
@@ -1139,6 +1166,7 @@ export function apply(ctx) {
1139
1166
  [DELEGATION_ENROLLED_BOTS_PATH, ['GET', 'POST', 'DELETE'], 'bots'],
1140
1167
  [DELEGATION_GROUPS_PATH, ['GET', 'PUT'], 'groups'],
1141
1168
  [DELEGATION_DM_CHAT_PATH, ['PUT'], 'dm-chat'],
1169
+ [DELEGATION_OWNER_CHALLENGE_PATH, ['POST'], 'challenge'],
1142
1170
  ]) {
1143
1171
  connectionCtx.effect(() => connectionCtx.connection.fetch.register({
1144
1172
  path, methods, requestBody: 'buffered',
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "ANT",
4
+ "description": "ANT (AI-native Teams) verbindet ein DeepSeek-Harness-Desktop-Profil mit der Teamidentität und den freigegebenen Modellen."
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "ANT",
4
+ "description": "ANT (AI-native Teams) conecta un perfil de DeepSeek Harness Desktop con la identidad del equipo y los modelos autorizados."
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "ANT",
4
+ "description": "ANT(AI-native Teams)は DeepSeek Harness Desktop のプロファイルをチームのメンバー管理と許可済みモデルに接続します。"
5
+ }
6
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "locales": ["en", "zh", "es-ES", "de-DE", "ja-JP", "pt-BR"],
3
+ "messages": {
4
+ "login_subject": {
5
+ "en": "ANT team sign-in code",
6
+ "zh": "ANT 团队登录验证码",
7
+ "es-ES": "Código de acceso al equipo ANT",
8
+ "de-DE": "ANT-Team-Anmeldecode",
9
+ "ja-JP": "ANT チームのログインコード",
10
+ "pt-BR": "Código de acesso à equipe ANT"
11
+ },
12
+ "login_body": {
13
+ "en": "Your ANT team sign-in code is: {code}\nThis code is valid for 10 minutes. Do not forward it.",
14
+ "zh": "你的 ANT 团队登录验证码是:{code}\n验证码 10 分钟内有效,请勿转发。",
15
+ "es-ES": "Tu código de acceso al equipo ANT es: {code}\nEste código es válido durante 10 minutos. No lo reenvíes.",
16
+ "de-DE": "Dein ANT-Team-Anmeldecode lautet: {code}\nDer Code ist 10 Minuten gültig. Bitte leite ihn nicht weiter.",
17
+ "ja-JP": "ANT チームのログインコードは {code} です。\nコードの有効期限は 10 分です。転送しないでください。",
18
+ "pt-BR": "Seu código de acesso à equipe ANT é: {code}\nEste código é válido por 10 minutos. Não o encaminhe."
19
+ },
20
+ "invitation_subject": {
21
+ "en": "Invitation to join the ANT team",
22
+ "zh": "ANT 团队成员邀请",
23
+ "es-ES": "Invitación para unirse al equipo ANT",
24
+ "de-DE": "Einladung zum ANT-Team",
25
+ "ja-JP": "ANT チームへの招待",
26
+ "pt-BR": "Convite para participar da equipe ANT"
27
+ },
28
+ "invitation_body": {
29
+ "en": "You have been invited to join the ANT team “{team_name}”.\n\nOpen the link below within 7 days of receiving this invitation email, then verify this email address to join the team:\n{invite_url}\n\nIf you were not expecting this email, you can ignore it.",
30
+ "zh": "你受邀加入「{team_name}」ANT 团队。\n\n请在邀请邮件发送后的 7 天内打开下方链接,并验证此邮箱以加入团队:\n{invite_url}\n\n如果这封邮件并非发给你,请忽略它。",
31
+ "es-ES": "Te han invitado a unirte al equipo ANT “{team_name}”.\n\nAbre el siguiente enlace en un plazo de 7 días desde la recepción de este correo y verifica esta dirección de correo para unirte al equipo:\n{invite_url}\n\nSi no esperabas este correo, puedes ignorarlo.",
32
+ "de-DE": "Du wurdest eingeladen, dem ANT-Team „{team_name}“ beizutreten.\n\nÖffne den folgenden Link innerhalb von 7 Tagen nach Erhalt dieser Einladungs-E-Mail und bestätige diese E-Mail-Adresse, um dem Team beizutreten:\n{invite_url}\n\nWenn du diese E-Mail nicht erwartet hast, kannst du sie ignorieren.",
33
+ "ja-JP": "ANT チーム「{team_name}」への招待が届きました。\n\nこの招待メールの受信から 7 日以内に次のリンクを開き、このメールアドレスを確認してチームに参加してください。\n{invite_url}\n\n心当たりがない場合は、このメールを無視してください。",
34
+ "pt-BR": "Você foi convidado para participar da equipe ANT “{team_name}”.\n\nAbra o link abaixo em até 7 dias após receber este e-mail e confirme este endereço de e-mail para entrar na equipe:\n{invite_url}\n\nSe você não estava esperando este e-mail, pode ignorá-lo."
35
+ }
36
+ }
37
+ }