@ai-wendao/ant 0.4.1 → 0.4.5
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/README.md +3 -3
- package/client.js +537 -552
- package/conversation.js +522 -199
- package/cordis.patch.yml +3 -3
- package/delegation.js +670 -60
- package/index.js +51 -12
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const name = 'ant'
|
|
2
2
|
|
|
3
3
|
import { createHash } from 'node:crypto'
|
|
4
|
+
import { spawn } from 'node:child_process'
|
|
4
5
|
import { createRequire } from 'node:module'
|
|
5
6
|
import { installSkill, listSkills, uninstallSkill } from './skill-install.js'
|
|
6
7
|
import { readLocalDelegationSettings, recentDelegationStatus, startDelegationHost,
|
|
@@ -201,6 +202,10 @@ function dshImService(ctx) {
|
|
|
201
202
|
try { return ctx.get?.('dshIm') ?? ctx.dshIm ?? null } catch { return null }
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
function optionalHostService(ctx, name) {
|
|
206
|
+
try { return ctx.get?.(name) ?? ctx[name] ?? null } catch { return null }
|
|
207
|
+
}
|
|
208
|
+
|
|
204
209
|
async function fetchDelegationBots(request, ctx) {
|
|
205
210
|
if (request.method !== 'GET') return jsonResponse(405, { message: '只支持 GET 请求。' })
|
|
206
211
|
const service = dshImService(ctx)
|
|
@@ -259,6 +264,7 @@ async function fetchDelegationGrants(request, ctx, credentials, settings) {
|
|
|
259
264
|
const response = await fetch(new URL(path, connection.serviceUrl), {
|
|
260
265
|
method: request.method,
|
|
261
266
|
headers: { authorization: `Bearer ${connection.token}`, accept: 'application/json',
|
|
267
|
+
...(request.method !== 'GET' ? { origin: new URL(connection.serviceUrl).origin } : {}),
|
|
262
268
|
...(request.method === 'POST' ? { 'content-type': 'application/json' } : {}) },
|
|
263
269
|
...(request.method === 'POST' ? { body: JSON.stringify(body) } : {}),
|
|
264
270
|
redirect: 'manual', signal: AbortSignal.timeout(12_000),
|
|
@@ -274,8 +280,8 @@ async function fetchDelegationGrants(request, ctx, credentials, settings) {
|
|
|
274
280
|
} catch { return jsonResponse(502, { message: '暂时无法连接 ANT 团队服务。' }) }
|
|
275
281
|
}
|
|
276
282
|
|
|
277
|
-
async function fetchDelegationGroupSettings(request, ctx, credentials, settings, kind) {
|
|
278
|
-
const methods = kind === 'groups' ? ['GET'] : kind === 'challenge' ? ['POST'] : ['GET', 'POST', 'DELETE']
|
|
283
|
+
async function fetchDelegationGroupSettings(request, ctx, credentials, settings, kind, getHost) {
|
|
284
|
+
const methods = kind === 'groups' ? ['GET', 'PUT'] : kind === 'challenge' ? ['POST'] : ['GET', 'POST', 'DELETE']
|
|
279
285
|
if (!methods.includes(request.method)) return jsonResponse(405, { message: '请求方式不支持。' })
|
|
280
286
|
let connection
|
|
281
287
|
try { connection = await readMemberConnection(credentials, settings) } catch {
|
|
@@ -311,17 +317,29 @@ async function fetchDelegationGroupSettings(request, ctx, credentials, settings,
|
|
|
311
317
|
? `/api/me/im-delegations/bots/${encodeURIComponent(body.bot_id)}`
|
|
312
318
|
: '/api/me/im-delegations/bots'
|
|
313
319
|
try {
|
|
314
|
-
const
|
|
320
|
+
const destination = new URL(path, connection.serviceUrl)
|
|
321
|
+
if (kind === 'bots' && request.method === 'GET'
|
|
322
|
+
&& request.headers.get('x-ant-include-unbound') === 'true') {
|
|
323
|
+
destination.searchParams.set('include_unbound', 'true')
|
|
324
|
+
}
|
|
325
|
+
const response = await fetch(destination, {
|
|
315
326
|
method: request.method,
|
|
316
327
|
headers: { authorization: `Bearer ${connection.token}`, accept: 'application/json',
|
|
317
|
-
...(request.method
|
|
318
|
-
|
|
328
|
+
...(request.method !== 'GET' ? { origin: new URL(connection.serviceUrl).origin } : {}),
|
|
329
|
+
...(['POST', 'PUT'].includes(request.method) ? { 'content-type': 'application/json' } : {}) },
|
|
330
|
+
...(['POST', 'PUT'].includes(request.method) ? { body: JSON.stringify(body) } : {}),
|
|
319
331
|
redirect: 'manual', signal: AbortSignal.timeout(12_000),
|
|
320
332
|
})
|
|
321
333
|
if (response.status === 404 && request.method !== 'DELETE') {
|
|
322
334
|
return jsonResponse(426, { message: '团队服务端尚未支持群聊委托,请联系管理员升级 ANT 服务端。' })
|
|
323
335
|
}
|
|
324
|
-
if (response.status === 204)
|
|
336
|
+
if (response.status === 204) {
|
|
337
|
+
if (kind === 'groups' && request.method === 'PUT') {
|
|
338
|
+
const refresh = getHost?.()?.refresh
|
|
339
|
+
if (refresh) await refresh().catch(() => undefined)
|
|
340
|
+
}
|
|
341
|
+
return new Response(null, { status: 204 })
|
|
342
|
+
}
|
|
325
343
|
const text = await readLimitedBody(response)
|
|
326
344
|
if (text === null) return jsonResponse(502, { message: '团队服务响应过大。' })
|
|
327
345
|
return new Response(text, { status: response.status,
|
|
@@ -373,6 +391,7 @@ async function fetchDelegationCards(request, ctx, credentials, settings) {
|
|
|
373
391
|
const response = await fetch(new URL(path, connection.serviceUrl), {
|
|
374
392
|
method: request.method,
|
|
375
393
|
headers: { authorization: `Bearer ${connection.token}`, accept: 'application/json',
|
|
394
|
+
...(request.method !== 'GET' ? { origin: new URL(connection.serviceUrl).origin } : {}),
|
|
376
395
|
...(request.method === 'POST' ? { 'content-type': 'application/json' } : {}) },
|
|
377
396
|
...(request.method === 'POST' ? { body: JSON.stringify(body) } : {}),
|
|
378
397
|
redirect: 'manual', signal: AbortSignal.timeout(12_000),
|
|
@@ -400,15 +419,35 @@ async function fetchDelegationRuntimeSettings(request, credentials, settings) {
|
|
|
400
419
|
} catch { return jsonResponse(502, { message: '暂时无法读取团队协作设置。' }) }
|
|
401
420
|
}
|
|
402
421
|
|
|
403
|
-
function fetchDelegationExecutors(request, ctx) {
|
|
422
|
+
async function fetchDelegationExecutors(request, ctx) {
|
|
404
423
|
if (request.method !== 'GET') return jsonResponse(405, { message: '请求方式不支持。' })
|
|
405
424
|
let providers = []
|
|
406
|
-
try {
|
|
425
|
+
try {
|
|
426
|
+
const listed = optionalHostService(ctx, 'subagents')?.list?.()
|
|
427
|
+
if (Array.isArray(listed)) providers = listed
|
|
428
|
+
} catch {}
|
|
407
429
|
const available = new Set(providers)
|
|
430
|
+
const codexCliAvailable = await new Promise((resolve) => {
|
|
431
|
+
const child = spawn('codex', ['exec', '--help'], { stdio: ['ignore', 'pipe', 'ignore'] })
|
|
432
|
+
let help = ''
|
|
433
|
+
child.stdout.on('data', (chunk) => { help = (help + chunk.toString()).slice(0, 32_000) })
|
|
434
|
+
const timer = setTimeout(() => { child.kill(); resolve(false) }, 3_000)
|
|
435
|
+
child.once('error', () => { clearTimeout(timer); resolve(false) })
|
|
436
|
+
child.once('close', (code) => { clearTimeout(timer)
|
|
437
|
+
resolve(code === 0 && ['--ignore-user-config', '--strict-config', '--output-last-message']
|
|
438
|
+
.every((flag) => help.includes(flag))) })
|
|
439
|
+
})
|
|
440
|
+
const nativePrSnapshotSupported = process.platform !== 'win32'
|
|
441
|
+
const nativePrUnavailableReason = nativePrSnapshotSupported ? null
|
|
442
|
+
: '当前 Windows 环境无法限制 Git 仓库缓存容量'
|
|
408
443
|
return jsonResponse(200, [
|
|
409
|
-
{ id: 'dsh', title: 'DSH', available: Boolean(ctx
|
|
444
|
+
{ id: 'dsh', title: 'DSH', available: Boolean(optionalHostService(ctx, 'sessionController')
|
|
445
|
+
&& optionalHostService(ctx, 'agents')) },
|
|
410
446
|
{ id: 'codex', title: 'Codex', available: available.has('codex') },
|
|
411
|
-
{ id: '
|
|
447
|
+
{ id: 'codex-readonly', title: 'Codex 专用只读差异审查', available: codexCliAvailable && nativePrSnapshotSupported,
|
|
448
|
+
...(nativePrUnavailableReason ? { reason: nativePrUnavailableReason } : {}) },
|
|
449
|
+
{ id: 'claude-code', title: 'Claude Code', available: available.has('claude-code') && nativePrSnapshotSupported,
|
|
450
|
+
...(nativePrUnavailableReason ? { reason: nativePrUnavailableReason } : {}) },
|
|
412
451
|
{ id: 'acp', title: 'DSH ACP', available: available.has('acp') },
|
|
413
452
|
{ id: 'dsh-sdk', title: 'DSH SDK 子代理', available: available.has('dsh-sdk') },
|
|
414
453
|
])
|
|
@@ -903,13 +942,13 @@ export function apply(ctx) {
|
|
|
903
942
|
}), 'ant-teams: member delegation settings')
|
|
904
943
|
for (const [path, methods, kind] of [
|
|
905
944
|
[DELEGATION_ENROLLED_BOTS_PATH, ['GET', 'POST', 'DELETE'], 'bots'],
|
|
906
|
-
[DELEGATION_GROUPS_PATH, ['GET'], 'groups'],
|
|
945
|
+
[DELEGATION_GROUPS_PATH, ['GET', 'PUT'], 'groups'],
|
|
907
946
|
[DELEGATION_OWNER_CHALLENGE_PATH, ['POST'], 'challenge'],
|
|
908
947
|
]) {
|
|
909
948
|
connectionCtx.effect(() => connectionCtx.connection.fetch.register({
|
|
910
949
|
path, methods, requestBody: 'buffered',
|
|
911
950
|
fetch: (request) => fetchDelegationGroupSettings(request, connectionCtx,
|
|
912
|
-
connectionCtx.credentials, connectionCtx.settings, kind),
|
|
951
|
+
connectionCtx.credentials, connectionCtx.settings, kind, () => delegationHost),
|
|
913
952
|
}), `ant-teams: member delegation ${kind}`)
|
|
914
953
|
}
|
|
915
954
|
connectionCtx.effect(() => connectionCtx.connection.fetch.register({
|