@openagentpack/sdk 0.7.2 → 0.8.0
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/{chunk-7L73W3DL.js → chunk-KYGVVTV6.js} +1 -1
- package/dist/{chunk-LJQMLMAT.js → chunk-LKLR56IB.js} +199 -167
- package/dist/{chunk-HLZOSZ7B.js → chunk-ZOMPZ7R6.js} +338 -103
- package/dist/{directory-nY2Slsfi.d.ts → directory-CbplCCLL.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +45 -3
- package/dist/project-versions.d.ts +2 -2
- package/dist/project-versions.js +2 -2
- package/dist/project-workspace.d.ts +4 -4
- package/dist/project-workspace.js +3 -3
- package/dist/{resource-runtime-DZsBWDjg.d.ts → resource-runtime-DdMsAJ8U.d.ts} +25 -5
- package/dist/{session-event-DB_YlDiK.d.ts → session-event-8uezu9Rz.d.ts} +1 -1
- package/dist/session-events.d.ts +2 -2
- package/package.json +1 -1
- package/dist/{dto-BT1Q1Ii6.d.ts → dto-CVvsUr3b.d.ts} +58 -58
|
@@ -816,7 +816,21 @@ var toolsSchema = z.object({
|
|
|
816
816
|
});
|
|
817
817
|
var multiagentSchema = z.object({
|
|
818
818
|
type: z.literal("coordinator"),
|
|
819
|
-
agents: z.array(z.string())
|
|
819
|
+
agents: z.array(z.union([z.string().min(1), z.object({ agent_id: z.string().trim().min(1) })])).min(1)
|
|
820
|
+
}).superRefine((multiagent, ctx) => {
|
|
821
|
+
const seen = /* @__PURE__ */ new Set();
|
|
822
|
+
for (const [index, member] of multiagent.agents.entries()) {
|
|
823
|
+
const key = typeof member === "string" ? `logical:${member}` : `external:${member.agent_id}`;
|
|
824
|
+
if (seen.has(key)) {
|
|
825
|
+
const label = typeof member === "string" ? member : member.agent_id;
|
|
826
|
+
ctx.addIssue({
|
|
827
|
+
code: "custom",
|
|
828
|
+
path: ["agents", index],
|
|
829
|
+
message: `duplicates member '${label}'`
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
seen.add(key);
|
|
833
|
+
}
|
|
820
834
|
});
|
|
821
835
|
var agentSkillRefSchema = z.object({
|
|
822
836
|
type: z.enum(["official", "custom"]),
|
|
@@ -1344,6 +1358,86 @@ function extractCreatedEventId(res) {
|
|
|
1344
1358
|
return void 0;
|
|
1345
1359
|
}
|
|
1346
1360
|
|
|
1361
|
+
// src/internal/multiagent/reverse-index.ts
|
|
1362
|
+
function buildReverseIndex(agents, project) {
|
|
1363
|
+
const index = /* @__PURE__ */ new Map();
|
|
1364
|
+
for (const raw of agents) {
|
|
1365
|
+
const id = raw.id;
|
|
1366
|
+
if (typeof id !== "string") continue;
|
|
1367
|
+
const metadata = raw.metadata;
|
|
1368
|
+
const owned = metadata?.["agents.project"] === project;
|
|
1369
|
+
const resource = metadata?.["agents.resource"];
|
|
1370
|
+
const logicalName = owned && typeof resource === "string" && resource.trim() ? resource.trim() : void 0;
|
|
1371
|
+
index.set(id, {
|
|
1372
|
+
logical_name: logicalName,
|
|
1373
|
+
archived: raw.archived_at != null,
|
|
1374
|
+
owned
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
return index;
|
|
1378
|
+
}
|
|
1379
|
+
function memberDeclResolver(index) {
|
|
1380
|
+
const claims = /* @__PURE__ */ new Map();
|
|
1381
|
+
for (const entry of index.values()) {
|
|
1382
|
+
if (!entry.logical_name) continue;
|
|
1383
|
+
claims.set(entry.logical_name, (claims.get(entry.logical_name) ?? 0) + 1);
|
|
1384
|
+
}
|
|
1385
|
+
return (memberId) => {
|
|
1386
|
+
const entry = index.get(memberId);
|
|
1387
|
+
if (!entry) {
|
|
1388
|
+
throw new UserError(
|
|
1389
|
+
`sync.multiagent.member.unresolved: roster member '${memberId}' is missing from the /agents listing.`
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
if (!entry.owned) return { agent_id: memberId };
|
|
1393
|
+
if (entry.archived) {
|
|
1394
|
+
throw new UserError(
|
|
1395
|
+
`sync.multiagent.member.archived: roster member '${memberId}' is archived; restore it before syncing.`
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
const name = entry.logical_name;
|
|
1399
|
+
if (!name) {
|
|
1400
|
+
throw new UserError(
|
|
1401
|
+
`sync.multiagent.member.unresolved: roster member '${memberId}' carries no agents.resource metadata.`
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
if ((claims.get(name) ?? 0) > 1) {
|
|
1405
|
+
throw new UserError(
|
|
1406
|
+
`sync.multiagent.member.ambiguous: logical name '${name}' is claimed by multiple remote agents.`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
return name;
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
function reverseMultiagentDecl(raw, resolveMember) {
|
|
1413
|
+
if (raw === null || raw === void 0) return void 0;
|
|
1414
|
+
if (typeof raw !== "object") return void 0;
|
|
1415
|
+
const roster = raw;
|
|
1416
|
+
if (roster.type !== void 0 && roster.type !== "coordinator") {
|
|
1417
|
+
throw new UserError(
|
|
1418
|
+
`sync.multiagent.member.unresolved: remote multi-agent type '${String(roster.type)}' cannot be represented (coordinator only).`
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
if (!Array.isArray(roster.agents) || roster.agents.length === 0) return void 0;
|
|
1422
|
+
if (!resolveMember) {
|
|
1423
|
+
throw new UserError(
|
|
1424
|
+
"sync.multiagent.member.unresolved: reverse-mapping a multi-agent roster requires a member name resolver."
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
return {
|
|
1428
|
+
type: "coordinator",
|
|
1429
|
+
agents: roster.agents.map((member) => resolveMember(rosterMemberId(member)))
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
function rosterMemberId(member) {
|
|
1433
|
+
if (typeof member === "string") return member;
|
|
1434
|
+
if (typeof member === "object" && member !== null) {
|
|
1435
|
+
const m = member;
|
|
1436
|
+
if (m.type === "agent" && typeof m.id === "string") return m.id;
|
|
1437
|
+
}
|
|
1438
|
+
throw new UserError("sync.multiagent.member.unresolved: roster member is not a representable agent reference.");
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1347
1441
|
// src/internal/providers/session-vault.ts
|
|
1348
1442
|
function extractVaultIds(res) {
|
|
1349
1443
|
const top = res.vault_ids;
|
|
@@ -1419,7 +1513,7 @@ function buildSessionInfo(res, memoryStoreIds) {
|
|
|
1419
1513
|
attributes: res
|
|
1420
1514
|
};
|
|
1421
1515
|
}
|
|
1422
|
-
async function exportRemoteResources(client, type, mappers) {
|
|
1516
|
+
async function exportRemoteResources(client, type, mappers, projectName) {
|
|
1423
1517
|
if (type === "environment") {
|
|
1424
1518
|
const envs = await client.getAllPaged("/environments");
|
|
1425
1519
|
return envs.map((env) => {
|
|
@@ -1458,9 +1552,11 @@ async function exportRemoteResources(client, type, mappers) {
|
|
|
1458
1552
|
}
|
|
1459
1553
|
if (type === "agent") {
|
|
1460
1554
|
const agents = await client.getAllPaged("/agents");
|
|
1555
|
+
const resolveMember = memberDeclResolver(buildReverseIndex(agents, projectName ?? ""));
|
|
1461
1556
|
return agents.filter((agent) => !agent.archived_at).map((agent) => {
|
|
1462
1557
|
const agentId = agent.id;
|
|
1463
|
-
|
|
1558
|
+
const name = resourceNameFromMetadata(agent.metadata, agent.name ?? agentId, agentId);
|
|
1559
|
+
return { name, decl: mappers.agentToDecl(agent, resolveMember) };
|
|
1464
1560
|
});
|
|
1465
1561
|
}
|
|
1466
1562
|
return [];
|
|
@@ -1684,11 +1780,10 @@ function envToDecl(raw) {
|
|
|
1684
1780
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
1685
1781
|
});
|
|
1686
1782
|
}
|
|
1687
|
-
function agentToDecl(raw) {
|
|
1783
|
+
function agentToDecl(raw, resolveMember) {
|
|
1688
1784
|
const tools = raw.tools;
|
|
1689
1785
|
const mcpServers = raw.mcp_servers;
|
|
1690
1786
|
const skills = raw.skills;
|
|
1691
|
-
const multiagent = raw.multiagent;
|
|
1692
1787
|
let builtinTools;
|
|
1693
1788
|
let builtinPermissions;
|
|
1694
1789
|
let allToolsEnabled = false;
|
|
@@ -1720,10 +1815,6 @@ function agentToDecl(raw) {
|
|
|
1720
1815
|
skill_id: s.skill_id
|
|
1721
1816
|
}));
|
|
1722
1817
|
}
|
|
1723
|
-
let multiagentDecl;
|
|
1724
|
-
if (multiagent && multiagent.agents?.length) {
|
|
1725
|
-
multiagentDecl = { type: "coordinator", agents: multiagent.agents };
|
|
1726
|
-
}
|
|
1727
1818
|
let toolsDecl;
|
|
1728
1819
|
if (builtinTools?.length) {
|
|
1729
1820
|
toolsDecl = { builtin: builtinTools, permissions: builtinPermissions };
|
|
@@ -1740,7 +1831,7 @@ function agentToDecl(raw) {
|
|
|
1740
1831
|
tools: toolsDecl,
|
|
1741
1832
|
mcp_servers: mcpServerDecls,
|
|
1742
1833
|
skills: skillDecls,
|
|
1743
|
-
multiagent:
|
|
1834
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
1744
1835
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
1745
1836
|
});
|
|
1746
1837
|
}
|
|
@@ -1823,10 +1914,10 @@ function mapAgent(name, decl, refs, version, projectName) {
|
|
|
1823
1914
|
skill_id: s.skill_id
|
|
1824
1915
|
}));
|
|
1825
1916
|
}
|
|
1826
|
-
if (decl.multiagent && refs.
|
|
1917
|
+
if (decl.multiagent && refs.multiagent) {
|
|
1827
1918
|
body.multiagent = {
|
|
1828
1919
|
type: "coordinator",
|
|
1829
|
-
agents: refs.
|
|
1920
|
+
agents: refs.multiagent.members.map((member) => member.remote_id)
|
|
1830
1921
|
};
|
|
1831
1922
|
}
|
|
1832
1923
|
return body;
|
|
@@ -2164,13 +2255,18 @@ var ClaudeAdapter = class _ClaudeAdapter {
|
|
|
2164
2255
|
await this.client.delete(`/vaults/${id}`);
|
|
2165
2256
|
}
|
|
2166
2257
|
async exportResources(type) {
|
|
2167
|
-
return exportRemoteResources(
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2258
|
+
return exportRemoteResources(
|
|
2259
|
+
this.client,
|
|
2260
|
+
type,
|
|
2261
|
+
{
|
|
2262
|
+
envToDecl,
|
|
2263
|
+
vaultToDecl,
|
|
2264
|
+
fileToDecl,
|
|
2265
|
+
skillToDecl,
|
|
2266
|
+
agentToDecl
|
|
2267
|
+
},
|
|
2268
|
+
this.projectName
|
|
2269
|
+
);
|
|
2174
2270
|
}
|
|
2175
2271
|
async createSkill(name, _decl, files) {
|
|
2176
2272
|
const formData = buildClaudeSkillFormData(name, files);
|
|
@@ -2539,6 +2635,31 @@ import { readFileSync as readFileSync2 } from "fs";
|
|
|
2539
2635
|
import { basename as basename3, dirname as dirname5, resolve as resolve5 } from "path";
|
|
2540
2636
|
import JSZip2 from "jszip";
|
|
2541
2637
|
|
|
2638
|
+
// src/internal/multiagent/comparable.ts
|
|
2639
|
+
function canonicalizeRemoteRoster(raw, materialization) {
|
|
2640
|
+
if (raw === null || raw === void 0) return { supported: true };
|
|
2641
|
+
if (typeof raw !== "object") return { supported: false };
|
|
2642
|
+
const roster = raw;
|
|
2643
|
+
if (roster.type !== "coordinator") return { supported: false };
|
|
2644
|
+
if (!Array.isArray(roster.agents)) return { supported: false };
|
|
2645
|
+
if (roster.agents.length === 0) return { supported: true };
|
|
2646
|
+
const memberIds = [];
|
|
2647
|
+
for (const entry of roster.agents) {
|
|
2648
|
+
if (typeof entry !== "object" || entry === null) return { supported: false };
|
|
2649
|
+
const member = entry;
|
|
2650
|
+
if (member.type !== "agent") return { supported: false };
|
|
2651
|
+
const id = materialization === "forward" ? member.template_id : member.id;
|
|
2652
|
+
if (typeof id !== "string") return { supported: false };
|
|
2653
|
+
memberIds.push(id);
|
|
2654
|
+
}
|
|
2655
|
+
return { supported: true, roster: { type: "coordinator", member_ids: [...new Set(memberIds)].sort() } };
|
|
2656
|
+
}
|
|
2657
|
+
function comparableMultiagentField(raw, materialization) {
|
|
2658
|
+
const canonical = canonicalizeRemoteRoster(raw, materialization);
|
|
2659
|
+
if (!canonical.supported) return { type: "unsupported" };
|
|
2660
|
+
return canonical.roster;
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2542
2663
|
// src/internal/providers/qoder/client.ts
|
|
2543
2664
|
var QoderClient = class extends BaseApiClient {
|
|
2544
2665
|
baseUrl;
|
|
@@ -2688,7 +2809,7 @@ function skillToDecl2(raw, name) {
|
|
|
2688
2809
|
description: raw.description
|
|
2689
2810
|
});
|
|
2690
2811
|
}
|
|
2691
|
-
function agentToDecl2(raw) {
|
|
2812
|
+
function agentToDecl2(raw, resolveMember) {
|
|
2692
2813
|
const tools = raw.tools;
|
|
2693
2814
|
const mcpServers = raw.mcp_servers;
|
|
2694
2815
|
const skills = raw.skills;
|
|
@@ -2727,6 +2848,7 @@ function agentToDecl2(raw) {
|
|
|
2727
2848
|
tools: builtinTools?.length ? { builtin: builtinTools, permissions: builtinPermissions } : void 0,
|
|
2728
2849
|
mcp_servers: mcpServerDecls,
|
|
2729
2850
|
skills: skillDecls,
|
|
2851
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
2730
2852
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
2731
2853
|
});
|
|
2732
2854
|
}
|
|
@@ -2835,7 +2957,7 @@ function mapDeploymentResources2(decl, refs, uploadedFiles) {
|
|
|
2835
2957
|
}
|
|
2836
2958
|
return resources;
|
|
2837
2959
|
}
|
|
2838
|
-
function mapAgent2(name, decl, refs, version, projectName) {
|
|
2960
|
+
function mapAgent2(name, decl, refs, version, projectName, operation = "create") {
|
|
2839
2961
|
let model;
|
|
2840
2962
|
if (typeof decl.model === "string") {
|
|
2841
2963
|
model = decl.model;
|
|
@@ -2894,15 +3016,21 @@ function mapAgent2(name, decl, refs, version, projectName) {
|
|
|
2894
3016
|
}
|
|
2895
3017
|
}
|
|
2896
3018
|
}
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
3019
|
+
body.skills = refs.skill_ids.map((s) => ({
|
|
3020
|
+
type: s.type === "official" ? "qoder" : s.type,
|
|
3021
|
+
skill_id: s.skill_id
|
|
3022
|
+
}));
|
|
3023
|
+
if (refs.multiagent) {
|
|
3024
|
+
body.multiagent = {
|
|
3025
|
+
type: "coordinator",
|
|
3026
|
+
agents: refs.multiagent.members.map(({ remote_id }) => ({ type: "agent", id: remote_id }))
|
|
3027
|
+
};
|
|
3028
|
+
} else if (operation === "update") {
|
|
3029
|
+
body.multiagent = null;
|
|
2902
3030
|
}
|
|
2903
3031
|
return body;
|
|
2904
3032
|
}
|
|
2905
|
-
function mapForwardTemplate(name, decl, refs, projectName) {
|
|
3033
|
+
function mapForwardTemplate(name, decl, refs, projectName, operation = "create") {
|
|
2906
3034
|
let model;
|
|
2907
3035
|
if (typeof decl.model === "string") {
|
|
2908
3036
|
model = decl.model;
|
|
@@ -2964,6 +3092,14 @@ function mapForwardTemplate(name, decl, refs, projectName) {
|
|
|
2964
3092
|
...skill.version ? { version: skill.version } : {},
|
|
2965
3093
|
enabled: true
|
|
2966
3094
|
}));
|
|
3095
|
+
if (refs.multiagent) {
|
|
3096
|
+
body.multiagent = {
|
|
3097
|
+
type: "coordinator",
|
|
3098
|
+
agents: refs.multiagent.members.map(({ remote_id }) => ({ type: "agent", template_id: remote_id }))
|
|
3099
|
+
};
|
|
3100
|
+
} else if (operation === "update") {
|
|
3101
|
+
body.multiagent = null;
|
|
3102
|
+
}
|
|
2967
3103
|
return body;
|
|
2968
3104
|
}
|
|
2969
3105
|
function mapSendMessage2(text) {
|
|
@@ -3309,7 +3445,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3309
3445
|
if (!metadata || typeof metadata !== "object") return false;
|
|
3310
3446
|
return metadata["agents.project"] === this.projectName && metadata["agents.resource"] === displayName;
|
|
3311
3447
|
}
|
|
3312
|
-
normalizeDesiredResource(type, name, decl) {
|
|
3448
|
+
normalizeDesiredResource(type, name, decl, refs) {
|
|
3313
3449
|
if (type === "environment") {
|
|
3314
3450
|
return this.normalizeRemote(
|
|
3315
3451
|
type,
|
|
@@ -3319,10 +3455,16 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3319
3455
|
if (type === "agent") {
|
|
3320
3456
|
return this.normalizeRemote(
|
|
3321
3457
|
type,
|
|
3322
|
-
mapAgent2(name, decl, { skill_ids: [] }, void 0, this.projectName)
|
|
3458
|
+
mapAgent2(name, decl, refs ?? { skill_ids: [] }, void 0, this.projectName)
|
|
3459
|
+
);
|
|
3460
|
+
}
|
|
3461
|
+
if (type === "template") {
|
|
3462
|
+
if (!refs) return null;
|
|
3463
|
+
return this.normalizeRemote(
|
|
3464
|
+
type,
|
|
3465
|
+
mapForwardTemplate(name, decl, refs, this.projectName)
|
|
3323
3466
|
);
|
|
3324
3467
|
}
|
|
3325
|
-
if (type === "template") return null;
|
|
3326
3468
|
if (type === "identity") {
|
|
3327
3469
|
const identity = decl;
|
|
3328
3470
|
if (identity.identity_id) return null;
|
|
@@ -3350,10 +3492,10 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3350
3492
|
description: raw.description,
|
|
3351
3493
|
model: raw.model,
|
|
3352
3494
|
system: raw.system,
|
|
3353
|
-
tools: raw.tools,
|
|
3354
|
-
mcp_servers: raw.mcp_servers,
|
|
3495
|
+
tools: normalizeQoderTools(raw.tools),
|
|
3496
|
+
mcp_servers: normalizeQoderMcpServers(raw.mcp_servers),
|
|
3355
3497
|
skills: raw.skills,
|
|
3356
|
-
multiagent: raw.multiagent,
|
|
3498
|
+
multiagent: comparableMultiagentField(raw.multiagent, "forward"),
|
|
3357
3499
|
environment_id: raw.environment_id,
|
|
3358
3500
|
tunnel_id: raw.tunnel_id,
|
|
3359
3501
|
vault_ids: Array.isArray(raw.vault_ids) ? raw.vault_ids : Object.keys(raw.vaults ?? {}),
|
|
@@ -3395,6 +3537,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3395
3537
|
instructions: raw.system,
|
|
3396
3538
|
tools: normalizeQoderTools(raw.tools),
|
|
3397
3539
|
mcp_servers: normalizeQoderMcpServers(raw.mcp_servers),
|
|
3540
|
+
multiagent: comparableMultiagentField(raw.multiagent, "managed"),
|
|
3398
3541
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
3399
3542
|
});
|
|
3400
3543
|
}
|
|
@@ -3473,13 +3616,18 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3473
3616
|
await (mode === "forward" ? this.forwardClient : this.client).delete(`/vaults/${id}`);
|
|
3474
3617
|
}
|
|
3475
3618
|
async exportResources(type) {
|
|
3476
|
-
return exportRemoteResources(
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3619
|
+
return exportRemoteResources(
|
|
3620
|
+
this.client,
|
|
3621
|
+
type,
|
|
3622
|
+
{
|
|
3623
|
+
envToDecl: envToDecl2,
|
|
3624
|
+
vaultToDecl: vaultToDecl2,
|
|
3625
|
+
fileToDecl: fileToDecl2,
|
|
3626
|
+
skillToDecl: skillToDecl2,
|
|
3627
|
+
agentToDecl: agentToDecl2
|
|
3628
|
+
},
|
|
3629
|
+
this.projectName
|
|
3630
|
+
);
|
|
3483
3631
|
}
|
|
3484
3632
|
async createSkill(name, decl, files, mode = "managed") {
|
|
3485
3633
|
const formData = await buildSkillFormData(name, decl, files);
|
|
@@ -3501,13 +3649,13 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3501
3649
|
await (mode === "forward" ? this.forwardClient : this.client).delete(`/skills/${id}`);
|
|
3502
3650
|
}
|
|
3503
3651
|
async createAgent(name, decl, refs) {
|
|
3504
|
-
const body = mapAgent2(name, decl, refs, void 0, this.projectName);
|
|
3652
|
+
const body = mapAgent2(name, decl, refs, void 0, this.projectName, "create");
|
|
3505
3653
|
const res = await this.client.post("/agents", body);
|
|
3506
3654
|
return toRemoteResource(res);
|
|
3507
3655
|
}
|
|
3508
3656
|
async updateAgent(id, name, decl, refs) {
|
|
3509
3657
|
const current = await this.client.get(`/agents/${id}`);
|
|
3510
|
-
const body = mapAgent2(name, decl, refs, current.version, this.projectName);
|
|
3658
|
+
const body = mapAgent2(name, decl, refs, current.version, this.projectName, "update");
|
|
3511
3659
|
const res = await this.client.put(`/agents/${id}`, body);
|
|
3512
3660
|
return toRemoteResource(res);
|
|
3513
3661
|
}
|
|
@@ -3515,13 +3663,13 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3515
3663
|
await this.client.delete(`/agents/${id}`);
|
|
3516
3664
|
}
|
|
3517
3665
|
async createTemplate(name, decl, refs) {
|
|
3518
|
-
const body = mapForwardTemplate(name, decl, refs, this.projectName);
|
|
3666
|
+
const body = mapForwardTemplate(name, decl, refs, this.projectName, "create");
|
|
3519
3667
|
const res = await this.forwardClient.post("/templates", body);
|
|
3520
3668
|
await this.reconcileForwardMemoryMounts(res.id, refs);
|
|
3521
3669
|
return toRemoteResource(res);
|
|
3522
3670
|
}
|
|
3523
3671
|
async updateTemplate(id, name, decl, refs) {
|
|
3524
|
-
const body = mapForwardTemplate(name, decl, refs, this.projectName);
|
|
3672
|
+
const body = mapForwardTemplate(name, decl, refs, this.projectName, "update");
|
|
3525
3673
|
if (!refs.tunnel_id) body.tunnel_id = null;
|
|
3526
3674
|
const res = await this.forwardClient.post(`/templates/${id}`, body);
|
|
3527
3675
|
await this.reconcileForwardMemoryMounts(id, refs);
|
|
@@ -4120,11 +4268,7 @@ var QODER_CAPABILITIES = {
|
|
|
4120
4268
|
template: { tier: "native", reason: "Forward Templates API" },
|
|
4121
4269
|
memory_store: { tier: "native", reason: "memory_stores API" },
|
|
4122
4270
|
mcp_server: { tier: "native", reason: "mcp_servers field on agent" },
|
|
4123
|
-
multiagent: {
|
|
4124
|
-
tier: "unsupported",
|
|
4125
|
-
reason: "no multiagent primitive on Qoder",
|
|
4126
|
-
remediation: "deploy agents independently and orchestrate via MCP"
|
|
4127
|
-
},
|
|
4271
|
+
multiagent: { tier: "native", reason: "coordinator + roster topology" },
|
|
4128
4272
|
deployment: {
|
|
4129
4273
|
tier: "native",
|
|
4130
4274
|
reason: "deployments API with scheduled and manual runs"
|
|
@@ -4299,7 +4443,7 @@ function envToDecl3(raw) {
|
|
|
4299
4443
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4300
4444
|
});
|
|
4301
4445
|
}
|
|
4302
|
-
function agentToDecl3(raw) {
|
|
4446
|
+
function agentToDecl3(raw, resolveMember) {
|
|
4303
4447
|
const tools = raw.tools;
|
|
4304
4448
|
const mcpServers = raw.mcp_servers;
|
|
4305
4449
|
const skills = raw.skills;
|
|
@@ -4336,10 +4480,11 @@ function agentToDecl3(raw) {
|
|
|
4336
4480
|
tools: builtinTools?.length ? { builtin: builtinTools } : void 0,
|
|
4337
4481
|
mcp_servers: mcpServerDecls,
|
|
4338
4482
|
skills: skillDecls,
|
|
4483
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
4339
4484
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4340
4485
|
});
|
|
4341
4486
|
}
|
|
4342
|
-
function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
4487
|
+
function mapAgent3(name, decl, refs, version, projectName, skillVersions, operation = "create") {
|
|
4343
4488
|
let modelId;
|
|
4344
4489
|
if (typeof decl.model === "string") {
|
|
4345
4490
|
modelId = decl.model;
|
|
@@ -4360,7 +4505,17 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
4360
4505
|
} else if (decl.metadata) {
|
|
4361
4506
|
body.metadata = decl.metadata;
|
|
4362
4507
|
}
|
|
4363
|
-
const BAILIAN_BUILTINS = /* @__PURE__ */ new Set([
|
|
4508
|
+
const BAILIAN_BUILTINS = /* @__PURE__ */ new Set([
|
|
4509
|
+
"bash",
|
|
4510
|
+
"read",
|
|
4511
|
+
"write",
|
|
4512
|
+
"edit",
|
|
4513
|
+
"glob",
|
|
4514
|
+
"grep",
|
|
4515
|
+
"web_search",
|
|
4516
|
+
"web_fetch",
|
|
4517
|
+
"mark_artifacts"
|
|
4518
|
+
]);
|
|
4364
4519
|
if (decl.tools) {
|
|
4365
4520
|
const toolConfigs = resolveBuiltinTools(decl.tools, {
|
|
4366
4521
|
supportedWireNames: BAILIAN_BUILTINS
|
|
@@ -4404,17 +4559,24 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
4404
4559
|
});
|
|
4405
4560
|
}
|
|
4406
4561
|
}
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4562
|
+
body.skills = refs.skill_ids.map((s) => ({
|
|
4563
|
+
// Bailian's SkillType enum is "customer" | "official"; map the
|
|
4564
|
+
// resolver's generic "custom" sentinel to "customer".
|
|
4565
|
+
type: s.type === "custom" ? "customer" : s.type,
|
|
4566
|
+
skill_id: s.skill_id,
|
|
4567
|
+
// Bailian composes `{skill_id}@{version}` internally and rejects
|
|
4568
|
+
// entries without a version. Prefer explicit external references, then
|
|
4569
|
+
// the latest active remote version, then the common initial version.
|
|
4570
|
+
version: s.version ?? skillVersions?.[s.skill_id] ?? "1.0"
|
|
4571
|
+
}));
|
|
4572
|
+
if (refs.multiagent) {
|
|
4573
|
+
body.multiagent = {
|
|
4574
|
+
type: "coordinator",
|
|
4575
|
+
// No version: Bailian resolves the child Thread on first creation.
|
|
4576
|
+
agents: refs.multiagent.members.map(({ remote_id }) => ({ type: "agent", id: remote_id }))
|
|
4577
|
+
};
|
|
4578
|
+
} else if (operation === "update") {
|
|
4579
|
+
body.multiagent = { type: "coordinator", agents: [] };
|
|
4418
4580
|
}
|
|
4419
4581
|
return body;
|
|
4420
4582
|
}
|
|
@@ -4551,7 +4713,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4551
4713
|
snapshot: comparable
|
|
4552
4714
|
};
|
|
4553
4715
|
}
|
|
4554
|
-
normalizeDesiredResource(type, name, decl) {
|
|
4716
|
+
normalizeDesiredResource(type, name, decl, refs) {
|
|
4555
4717
|
if (type === "environment") {
|
|
4556
4718
|
return this.normalizeRemote(
|
|
4557
4719
|
type,
|
|
@@ -4561,7 +4723,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4561
4723
|
if (type === "agent") {
|
|
4562
4724
|
return this.normalizeRemote(
|
|
4563
4725
|
type,
|
|
4564
|
-
mapAgent3(name, decl, { skill_ids: [] }, void 0, this.projectName)
|
|
4726
|
+
mapAgent3(name, decl, refs ?? { skill_ids: [] }, void 0, this.projectName)
|
|
4565
4727
|
);
|
|
4566
4728
|
}
|
|
4567
4729
|
return null;
|
|
@@ -4586,17 +4748,23 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4586
4748
|
instructions: raw.system,
|
|
4587
4749
|
tools: normalizeBailianTools(raw.tools),
|
|
4588
4750
|
mcp_servers: normalizeBailianMcpServers(raw.mcp_servers),
|
|
4751
|
+
multiagent: comparableMultiagentField(raw.multiagent, "managed"),
|
|
4589
4752
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4590
4753
|
});
|
|
4591
4754
|
}
|
|
4592
4755
|
async exportResources(type) {
|
|
4593
|
-
return exportRemoteResources(
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4756
|
+
return exportRemoteResources(
|
|
4757
|
+
this.client,
|
|
4758
|
+
type,
|
|
4759
|
+
{
|
|
4760
|
+
envToDecl: envToDecl3,
|
|
4761
|
+
vaultToDecl: vaultToDecl3,
|
|
4762
|
+
fileToDecl: fileToDecl3,
|
|
4763
|
+
skillToDecl: skillToDecl3,
|
|
4764
|
+
agentToDecl: agentToDecl3
|
|
4765
|
+
},
|
|
4766
|
+
this.projectName
|
|
4767
|
+
);
|
|
4600
4768
|
}
|
|
4601
4769
|
// --- Environment ---
|
|
4602
4770
|
async createEnvironment(name, decl) {
|
|
@@ -4627,14 +4795,14 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4627
4795
|
// --- Agent ---
|
|
4628
4796
|
async createAgent(name, decl, refs) {
|
|
4629
4797
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
4630
|
-
const body = mapAgent3(name, decl, refs, void 0, this.projectName, skillVersions);
|
|
4798
|
+
const body = mapAgent3(name, decl, refs, void 0, this.projectName, skillVersions, "create");
|
|
4631
4799
|
const res = await this.client.post("/agents", body);
|
|
4632
4800
|
return toRemoteResource(res);
|
|
4633
4801
|
}
|
|
4634
4802
|
async updateAgent(id, name, decl, refs) {
|
|
4635
4803
|
const current = await this.client.get(`/agents/${id}`);
|
|
4636
4804
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
4637
|
-
const body = mapAgent3(name, decl, refs, current.version, this.projectName, skillVersions);
|
|
4805
|
+
const body = mapAgent3(name, decl, refs, current.version, this.projectName, skillVersions, "update");
|
|
4638
4806
|
const res = await this.client.post(`/agents/${id}`, body);
|
|
4639
4807
|
return toRemoteResource(res);
|
|
4640
4808
|
}
|
|
@@ -5356,11 +5524,7 @@ var BAILIAN_CAPABILITIES = {
|
|
|
5356
5524
|
reason: "no memory store primitive on Bailian"
|
|
5357
5525
|
},
|
|
5358
5526
|
mcp_server: { tier: "native", reason: "mcp_servers field on agent (official servers)" },
|
|
5359
|
-
multiagent: {
|
|
5360
|
-
tier: "unsupported",
|
|
5361
|
-
reason: "no multiagent primitive on Bailian",
|
|
5362
|
-
remediation: "deploy agents independently and orchestrate via MCP"
|
|
5363
|
-
},
|
|
5527
|
+
multiagent: { tier: "native", reason: "coordinator + roster topology" },
|
|
5364
5528
|
deployment: {
|
|
5365
5529
|
tier: "native",
|
|
5366
5530
|
reason: "deployments API with cron schedules, manual runs, pause/unpause and archive"
|
|
@@ -5513,11 +5677,10 @@ function envToDecl4(raw) {
|
|
|
5513
5677
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
5514
5678
|
});
|
|
5515
5679
|
}
|
|
5516
|
-
function agentToDecl4(raw) {
|
|
5680
|
+
function agentToDecl4(raw, resolveMember) {
|
|
5517
5681
|
const tools = raw.tools;
|
|
5518
5682
|
const mcpServers = raw.mcp_servers;
|
|
5519
5683
|
const skills = raw.skills;
|
|
5520
|
-
const multiagent = raw.multiagent;
|
|
5521
5684
|
let builtinTools;
|
|
5522
5685
|
let builtinPermissions;
|
|
5523
5686
|
let allToolsEnabled = false;
|
|
@@ -5549,14 +5712,6 @@ function agentToDecl4(raw) {
|
|
|
5549
5712
|
skill_id: s.skill_id
|
|
5550
5713
|
}));
|
|
5551
5714
|
}
|
|
5552
|
-
let multiagentDecl;
|
|
5553
|
-
if (multiagent) {
|
|
5554
|
-
const rawAgents = multiagent.agents;
|
|
5555
|
-
if (rawAgents?.length) {
|
|
5556
|
-
const ids = rawAgents.map((a) => typeof a === "string" ? a : a.id).filter(Boolean);
|
|
5557
|
-
if (ids.length) multiagentDecl = { type: "coordinator", agents: ids };
|
|
5558
|
-
}
|
|
5559
|
-
}
|
|
5560
5715
|
let toolsDecl;
|
|
5561
5716
|
if (builtinTools?.length) {
|
|
5562
5717
|
toolsDecl = { builtin: builtinTools, permissions: builtinPermissions };
|
|
@@ -5573,7 +5728,7 @@ function agentToDecl4(raw) {
|
|
|
5573
5728
|
tools: toolsDecl,
|
|
5574
5729
|
mcp_servers: mcpServerDecls,
|
|
5575
5730
|
skills: skillDecls,
|
|
5576
|
-
multiagent:
|
|
5731
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
5577
5732
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
5578
5733
|
});
|
|
5579
5734
|
}
|
|
@@ -5657,10 +5812,10 @@ function mapAgent4(name, decl, refs, version, projectName) {
|
|
|
5657
5812
|
skill_id: s.skill_id
|
|
5658
5813
|
}));
|
|
5659
5814
|
}
|
|
5660
|
-
if (decl.multiagent && refs.
|
|
5815
|
+
if (decl.multiagent && refs.multiagent) {
|
|
5661
5816
|
body.multiagent = {
|
|
5662
5817
|
type: "coordinator",
|
|
5663
|
-
agents: refs.
|
|
5818
|
+
agents: refs.multiagent.members.map(({ remote_id }) => ({ type: "agent", id: remote_id }))
|
|
5664
5819
|
};
|
|
5665
5820
|
}
|
|
5666
5821
|
return body;
|
|
@@ -5912,13 +6067,18 @@ var ArkAdapter = class _ArkAdapter {
|
|
|
5912
6067
|
}
|
|
5913
6068
|
async exportResources(type) {
|
|
5914
6069
|
if (type === "skill") return [];
|
|
5915
|
-
return exportRemoteResources(
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
6070
|
+
return exportRemoteResources(
|
|
6071
|
+
this.client,
|
|
6072
|
+
type,
|
|
6073
|
+
{
|
|
6074
|
+
envToDecl: envToDecl4,
|
|
6075
|
+
vaultToDecl: vaultToDecl4,
|
|
6076
|
+
fileToDecl: fileToDecl4,
|
|
6077
|
+
skillToDecl: skillToDecl4,
|
|
6078
|
+
agentToDecl: agentToDecl4
|
|
6079
|
+
},
|
|
6080
|
+
this.projectName
|
|
6081
|
+
);
|
|
5922
6082
|
}
|
|
5923
6083
|
// Ark skills support create + get + attach only. There is no list/update/delete endpoint
|
|
5924
6084
|
// (GET /skills, PUT /skills/{id}, DELETE /skills/{id} all return 404 on real probe), so:
|
|
@@ -6233,6 +6393,50 @@ function severityIcon(s) {
|
|
|
6233
6393
|
}
|
|
6234
6394
|
}
|
|
6235
6395
|
|
|
6396
|
+
// src/internal/multiagent/topology.ts
|
|
6397
|
+
var MULTIAGENT_MEMBER_LIMIT = 20;
|
|
6398
|
+
function collectMultiagentTopologyDiagnostics(config, diagnostics) {
|
|
6399
|
+
const agents = config.agents ?? {};
|
|
6400
|
+
const names = Object.keys(agents).sort();
|
|
6401
|
+
for (const name of names) {
|
|
6402
|
+
const decl = agents[name];
|
|
6403
|
+
if (!decl?.multiagent) continue;
|
|
6404
|
+
for (const member of decl.multiagent.agents) {
|
|
6405
|
+
if (typeof member !== "string") continue;
|
|
6406
|
+
if (agents[member]?.multiagent) {
|
|
6407
|
+
diagnostics.error(
|
|
6408
|
+
"config.agent.multiagent.nested",
|
|
6409
|
+
`agent.${name}: multiagent member '${member}' is itself a coordinator; nested coordinators are not supported`
|
|
6410
|
+
);
|
|
6411
|
+
}
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
const state = /* @__PURE__ */ new Map();
|
|
6415
|
+
const path = [];
|
|
6416
|
+
const visit2 = (name) => {
|
|
6417
|
+
if (state.get(name) === "done") return;
|
|
6418
|
+
state.set(name, "visiting");
|
|
6419
|
+
path.push(name);
|
|
6420
|
+
const members = agents[name]?.multiagent?.agents ?? [];
|
|
6421
|
+
for (const member of members) {
|
|
6422
|
+
if (typeof member !== "string") continue;
|
|
6423
|
+
if (!agents[member]) continue;
|
|
6424
|
+
if (state.get(member) === "visiting") {
|
|
6425
|
+
const cycle = [...path.slice(path.indexOf(member)), member];
|
|
6426
|
+
diagnostics.error(
|
|
6427
|
+
"config.agent.multiagent.cycle",
|
|
6428
|
+
`agent.${name}: multiagent cycle detected: ${cycle.join(" -> ")}`
|
|
6429
|
+
);
|
|
6430
|
+
continue;
|
|
6431
|
+
}
|
|
6432
|
+
visit2(member);
|
|
6433
|
+
}
|
|
6434
|
+
path.pop();
|
|
6435
|
+
state.set(name, "done");
|
|
6436
|
+
};
|
|
6437
|
+
for (const name of names) visit2(name);
|
|
6438
|
+
}
|
|
6439
|
+
|
|
6236
6440
|
// src/internal/validation/bailian.ts
|
|
6237
6441
|
function findMissingBailianMcpToolConfigs(config, providerName = "bailian") {
|
|
6238
6442
|
if (providerName !== "bailian") return [];
|
|
@@ -6334,6 +6538,7 @@ function collectReferenceDiagnostics(config, diagnostics) {
|
|
|
6334
6538
|
}
|
|
6335
6539
|
if (agent.multiagent) {
|
|
6336
6540
|
for (const subAgent of agent.multiagent.agents) {
|
|
6541
|
+
if (typeof subAgent !== "string") continue;
|
|
6337
6542
|
if (!agentNames.has(subAgent)) {
|
|
6338
6543
|
diagnostics.error(
|
|
6339
6544
|
"config.agent.multiagent.unknown",
|
|
@@ -6346,6 +6551,7 @@ function collectReferenceDiagnostics(config, diagnostics) {
|
|
|
6346
6551
|
}
|
|
6347
6552
|
}
|
|
6348
6553
|
}
|
|
6554
|
+
collectMultiagentTopologyDiagnostics(config, diagnostics);
|
|
6349
6555
|
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
6350
6556
|
if (deployment.tunnel && !tunnelNames.has(deployment.tunnel)) {
|
|
6351
6557
|
diagnostics.error(
|
|
@@ -6667,15 +6873,44 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
6667
6873
|
{ type: "template", name, provider: providerName }
|
|
6668
6874
|
);
|
|
6669
6875
|
}
|
|
6670
|
-
|
|
6876
|
+
}
|
|
6877
|
+
if (providerName === "qoder" && agent.multiagent) {
|
|
6878
|
+
const coordinatorMode = resolveAgentMaterialization(providerName, agent).mode;
|
|
6879
|
+
for (const memberName of agent.multiagent.agents) {
|
|
6880
|
+
if (typeof memberName !== "string") {
|
|
6881
|
+
if (coordinatorMode === "forward") {
|
|
6882
|
+
diagnostics.error(
|
|
6883
|
+
"qoder.template.multiagent.external_member",
|
|
6884
|
+
`agent.${name}: Qoder Forward coordinator cannot reference external Managed Agent '${memberName.agent_id}'.`,
|
|
6885
|
+
{ type: "template", name, provider: providerName }
|
|
6886
|
+
);
|
|
6887
|
+
}
|
|
6888
|
+
continue;
|
|
6889
|
+
}
|
|
6890
|
+
const memberDecl = config.agents?.[memberName];
|
|
6891
|
+
if (!memberDecl) continue;
|
|
6892
|
+
const memberMode = resolveAgentMaterialization(providerName, memberDecl).mode;
|
|
6893
|
+
if (memberMode === coordinatorMode) continue;
|
|
6671
6894
|
diagnostics.error(
|
|
6672
|
-
"qoder.template.multiagent.
|
|
6673
|
-
`agent.${name}: multiagent
|
|
6674
|
-
{ type: "template", name, provider: providerName }
|
|
6895
|
+
"qoder.template.multiagent.member_materialization",
|
|
6896
|
+
`agent.${name}: multiagent member '${memberName}' uses ${memberMode} delivery but the coordinator uses ${coordinatorMode}; Qoder multiagent members must match the coordinator's delivery type.`,
|
|
6897
|
+
{ type: coordinatorMode === "forward" ? "template" : "agent", name, provider: providerName }
|
|
6675
6898
|
);
|
|
6676
6899
|
}
|
|
6677
6900
|
}
|
|
6678
6901
|
}
|
|
6902
|
+
if (providerName === "qoder" || providerName === "bailian") {
|
|
6903
|
+
for (const [name, agent] of Object.entries(config.agents ?? {})) {
|
|
6904
|
+
if (agent.provider && agent.provider !== providerName) continue;
|
|
6905
|
+
const size = agent.multiagent?.agents.length ?? 0;
|
|
6906
|
+
if (size <= MULTIAGENT_MEMBER_LIMIT) continue;
|
|
6907
|
+
diagnostics.error(
|
|
6908
|
+
`${providerName}.agent.multiagent.member_limit`,
|
|
6909
|
+
`agent.${name}: provider '${providerName}' supports at most ${MULTIAGENT_MEMBER_LIMIT} multiagent members; got ${size}.`,
|
|
6910
|
+
{ type: resolveAgentMaterialization(providerName, agent).resourceType, name, provider: providerName }
|
|
6911
|
+
);
|
|
6912
|
+
}
|
|
6913
|
+
}
|
|
6679
6914
|
if (providerName === "qoder") {
|
|
6680
6915
|
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
6681
6916
|
if (deployment.provider && deployment.provider !== providerName) continue;
|