@openagentpack/sdk 0.7.3 → 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-XQMLTTGI.js → chunk-KYGVVTV6.js} +1 -1
- package/dist/{chunk-DFRNXUT3.js → chunk-LKLR56IB.js} +199 -167
- package/dist/{chunk-IRA4LOCJ.js → chunk-ZOMPZ7R6.js} +326 -87
- 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;
|
|
@@ -2898,9 +3020,17 @@ function mapAgent2(name, decl, refs, version, projectName) {
|
|
|
2898
3020
|
type: s.type === "official" ? "qoder" : s.type,
|
|
2899
3021
|
skill_id: s.skill_id
|
|
2900
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;
|
|
3030
|
+
}
|
|
2901
3031
|
return body;
|
|
2902
3032
|
}
|
|
2903
|
-
function mapForwardTemplate(name, decl, refs, projectName) {
|
|
3033
|
+
function mapForwardTemplate(name, decl, refs, projectName, operation = "create") {
|
|
2904
3034
|
let model;
|
|
2905
3035
|
if (typeof decl.model === "string") {
|
|
2906
3036
|
model = decl.model;
|
|
@@ -2962,6 +3092,14 @@ function mapForwardTemplate(name, decl, refs, projectName) {
|
|
|
2962
3092
|
...skill.version ? { version: skill.version } : {},
|
|
2963
3093
|
enabled: true
|
|
2964
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
|
+
}
|
|
2965
3103
|
return body;
|
|
2966
3104
|
}
|
|
2967
3105
|
function mapSendMessage2(text) {
|
|
@@ -3307,7 +3445,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3307
3445
|
if (!metadata || typeof metadata !== "object") return false;
|
|
3308
3446
|
return metadata["agents.project"] === this.projectName && metadata["agents.resource"] === displayName;
|
|
3309
3447
|
}
|
|
3310
|
-
normalizeDesiredResource(type, name, decl) {
|
|
3448
|
+
normalizeDesiredResource(type, name, decl, refs) {
|
|
3311
3449
|
if (type === "environment") {
|
|
3312
3450
|
return this.normalizeRemote(
|
|
3313
3451
|
type,
|
|
@@ -3317,10 +3455,16 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3317
3455
|
if (type === "agent") {
|
|
3318
3456
|
return this.normalizeRemote(
|
|
3319
3457
|
type,
|
|
3320
|
-
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)
|
|
3321
3466
|
);
|
|
3322
3467
|
}
|
|
3323
|
-
if (type === "template") return null;
|
|
3324
3468
|
if (type === "identity") {
|
|
3325
3469
|
const identity = decl;
|
|
3326
3470
|
if (identity.identity_id) return null;
|
|
@@ -3348,10 +3492,10 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3348
3492
|
description: raw.description,
|
|
3349
3493
|
model: raw.model,
|
|
3350
3494
|
system: raw.system,
|
|
3351
|
-
tools: raw.tools,
|
|
3352
|
-
mcp_servers: raw.mcp_servers,
|
|
3495
|
+
tools: normalizeQoderTools(raw.tools),
|
|
3496
|
+
mcp_servers: normalizeQoderMcpServers(raw.mcp_servers),
|
|
3353
3497
|
skills: raw.skills,
|
|
3354
|
-
multiagent: raw.multiagent,
|
|
3498
|
+
multiagent: comparableMultiagentField(raw.multiagent, "forward"),
|
|
3355
3499
|
environment_id: raw.environment_id,
|
|
3356
3500
|
tunnel_id: raw.tunnel_id,
|
|
3357
3501
|
vault_ids: Array.isArray(raw.vault_ids) ? raw.vault_ids : Object.keys(raw.vaults ?? {}),
|
|
@@ -3393,6 +3537,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3393
3537
|
instructions: raw.system,
|
|
3394
3538
|
tools: normalizeQoderTools(raw.tools),
|
|
3395
3539
|
mcp_servers: normalizeQoderMcpServers(raw.mcp_servers),
|
|
3540
|
+
multiagent: comparableMultiagentField(raw.multiagent, "managed"),
|
|
3396
3541
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
3397
3542
|
});
|
|
3398
3543
|
}
|
|
@@ -3471,13 +3616,18 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3471
3616
|
await (mode === "forward" ? this.forwardClient : this.client).delete(`/vaults/${id}`);
|
|
3472
3617
|
}
|
|
3473
3618
|
async exportResources(type) {
|
|
3474
|
-
return exportRemoteResources(
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
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
|
+
);
|
|
3481
3631
|
}
|
|
3482
3632
|
async createSkill(name, decl, files, mode = "managed") {
|
|
3483
3633
|
const formData = await buildSkillFormData(name, decl, files);
|
|
@@ -3499,13 +3649,13 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3499
3649
|
await (mode === "forward" ? this.forwardClient : this.client).delete(`/skills/${id}`);
|
|
3500
3650
|
}
|
|
3501
3651
|
async createAgent(name, decl, refs) {
|
|
3502
|
-
const body = mapAgent2(name, decl, refs, void 0, this.projectName);
|
|
3652
|
+
const body = mapAgent2(name, decl, refs, void 0, this.projectName, "create");
|
|
3503
3653
|
const res = await this.client.post("/agents", body);
|
|
3504
3654
|
return toRemoteResource(res);
|
|
3505
3655
|
}
|
|
3506
3656
|
async updateAgent(id, name, decl, refs) {
|
|
3507
3657
|
const current = await this.client.get(`/agents/${id}`);
|
|
3508
|
-
const body = mapAgent2(name, decl, refs, current.version, this.projectName);
|
|
3658
|
+
const body = mapAgent2(name, decl, refs, current.version, this.projectName, "update");
|
|
3509
3659
|
const res = await this.client.put(`/agents/${id}`, body);
|
|
3510
3660
|
return toRemoteResource(res);
|
|
3511
3661
|
}
|
|
@@ -3513,13 +3663,13 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
3513
3663
|
await this.client.delete(`/agents/${id}`);
|
|
3514
3664
|
}
|
|
3515
3665
|
async createTemplate(name, decl, refs) {
|
|
3516
|
-
const body = mapForwardTemplate(name, decl, refs, this.projectName);
|
|
3666
|
+
const body = mapForwardTemplate(name, decl, refs, this.projectName, "create");
|
|
3517
3667
|
const res = await this.forwardClient.post("/templates", body);
|
|
3518
3668
|
await this.reconcileForwardMemoryMounts(res.id, refs);
|
|
3519
3669
|
return toRemoteResource(res);
|
|
3520
3670
|
}
|
|
3521
3671
|
async updateTemplate(id, name, decl, refs) {
|
|
3522
|
-
const body = mapForwardTemplate(name, decl, refs, this.projectName);
|
|
3672
|
+
const body = mapForwardTemplate(name, decl, refs, this.projectName, "update");
|
|
3523
3673
|
if (!refs.tunnel_id) body.tunnel_id = null;
|
|
3524
3674
|
const res = await this.forwardClient.post(`/templates/${id}`, body);
|
|
3525
3675
|
await this.reconcileForwardMemoryMounts(id, refs);
|
|
@@ -4118,11 +4268,7 @@ var QODER_CAPABILITIES = {
|
|
|
4118
4268
|
template: { tier: "native", reason: "Forward Templates API" },
|
|
4119
4269
|
memory_store: { tier: "native", reason: "memory_stores API" },
|
|
4120
4270
|
mcp_server: { tier: "native", reason: "mcp_servers field on agent" },
|
|
4121
|
-
multiagent: {
|
|
4122
|
-
tier: "unsupported",
|
|
4123
|
-
reason: "no multiagent primitive on Qoder",
|
|
4124
|
-
remediation: "deploy agents independently and orchestrate via MCP"
|
|
4125
|
-
},
|
|
4271
|
+
multiagent: { tier: "native", reason: "coordinator + roster topology" },
|
|
4126
4272
|
deployment: {
|
|
4127
4273
|
tier: "native",
|
|
4128
4274
|
reason: "deployments API with scheduled and manual runs"
|
|
@@ -4297,7 +4443,7 @@ function envToDecl3(raw) {
|
|
|
4297
4443
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4298
4444
|
});
|
|
4299
4445
|
}
|
|
4300
|
-
function agentToDecl3(raw) {
|
|
4446
|
+
function agentToDecl3(raw, resolveMember) {
|
|
4301
4447
|
const tools = raw.tools;
|
|
4302
4448
|
const mcpServers = raw.mcp_servers;
|
|
4303
4449
|
const skills = raw.skills;
|
|
@@ -4334,10 +4480,11 @@ function agentToDecl3(raw) {
|
|
|
4334
4480
|
tools: builtinTools?.length ? { builtin: builtinTools } : void 0,
|
|
4335
4481
|
mcp_servers: mcpServerDecls,
|
|
4336
4482
|
skills: skillDecls,
|
|
4483
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
4337
4484
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4338
4485
|
});
|
|
4339
4486
|
}
|
|
4340
|
-
function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
4487
|
+
function mapAgent3(name, decl, refs, version, projectName, skillVersions, operation = "create") {
|
|
4341
4488
|
let modelId;
|
|
4342
4489
|
if (typeof decl.model === "string") {
|
|
4343
4490
|
modelId = decl.model;
|
|
@@ -4358,7 +4505,17 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
4358
4505
|
} else if (decl.metadata) {
|
|
4359
4506
|
body.metadata = decl.metadata;
|
|
4360
4507
|
}
|
|
4361
|
-
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
|
+
]);
|
|
4362
4519
|
if (decl.tools) {
|
|
4363
4520
|
const toolConfigs = resolveBuiltinTools(decl.tools, {
|
|
4364
4521
|
supportedWireNames: BAILIAN_BUILTINS
|
|
@@ -4412,6 +4569,15 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
4412
4569
|
// the latest active remote version, then the common initial version.
|
|
4413
4570
|
version: s.version ?? skillVersions?.[s.skill_id] ?? "1.0"
|
|
4414
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: [] };
|
|
4580
|
+
}
|
|
4415
4581
|
return body;
|
|
4416
4582
|
}
|
|
4417
4583
|
function mapSession3(bindings) {
|
|
@@ -4547,7 +4713,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4547
4713
|
snapshot: comparable
|
|
4548
4714
|
};
|
|
4549
4715
|
}
|
|
4550
|
-
normalizeDesiredResource(type, name, decl) {
|
|
4716
|
+
normalizeDesiredResource(type, name, decl, refs) {
|
|
4551
4717
|
if (type === "environment") {
|
|
4552
4718
|
return this.normalizeRemote(
|
|
4553
4719
|
type,
|
|
@@ -4557,7 +4723,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4557
4723
|
if (type === "agent") {
|
|
4558
4724
|
return this.normalizeRemote(
|
|
4559
4725
|
type,
|
|
4560
|
-
mapAgent3(name, decl, { skill_ids: [] }, void 0, this.projectName)
|
|
4726
|
+
mapAgent3(name, decl, refs ?? { skill_ids: [] }, void 0, this.projectName)
|
|
4561
4727
|
);
|
|
4562
4728
|
}
|
|
4563
4729
|
return null;
|
|
@@ -4582,17 +4748,23 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4582
4748
|
instructions: raw.system,
|
|
4583
4749
|
tools: normalizeBailianTools(raw.tools),
|
|
4584
4750
|
mcp_servers: normalizeBailianMcpServers(raw.mcp_servers),
|
|
4751
|
+
multiagent: comparableMultiagentField(raw.multiagent, "managed"),
|
|
4585
4752
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
4586
4753
|
});
|
|
4587
4754
|
}
|
|
4588
4755
|
async exportResources(type) {
|
|
4589
|
-
return exportRemoteResources(
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
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
|
+
);
|
|
4596
4768
|
}
|
|
4597
4769
|
// --- Environment ---
|
|
4598
4770
|
async createEnvironment(name, decl) {
|
|
@@ -4623,14 +4795,14 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4623
4795
|
// --- Agent ---
|
|
4624
4796
|
async createAgent(name, decl, refs) {
|
|
4625
4797
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
4626
|
-
const body = mapAgent3(name, decl, refs, void 0, this.projectName, skillVersions);
|
|
4798
|
+
const body = mapAgent3(name, decl, refs, void 0, this.projectName, skillVersions, "create");
|
|
4627
4799
|
const res = await this.client.post("/agents", body);
|
|
4628
4800
|
return toRemoteResource(res);
|
|
4629
4801
|
}
|
|
4630
4802
|
async updateAgent(id, name, decl, refs) {
|
|
4631
4803
|
const current = await this.client.get(`/agents/${id}`);
|
|
4632
4804
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
4633
|
-
const body = mapAgent3(name, decl, refs, current.version, this.projectName, skillVersions);
|
|
4805
|
+
const body = mapAgent3(name, decl, refs, current.version, this.projectName, skillVersions, "update");
|
|
4634
4806
|
const res = await this.client.post(`/agents/${id}`, body);
|
|
4635
4807
|
return toRemoteResource(res);
|
|
4636
4808
|
}
|
|
@@ -5352,11 +5524,7 @@ var BAILIAN_CAPABILITIES = {
|
|
|
5352
5524
|
reason: "no memory store primitive on Bailian"
|
|
5353
5525
|
},
|
|
5354
5526
|
mcp_server: { tier: "native", reason: "mcp_servers field on agent (official servers)" },
|
|
5355
|
-
multiagent: {
|
|
5356
|
-
tier: "unsupported",
|
|
5357
|
-
reason: "no multiagent primitive on Bailian",
|
|
5358
|
-
remediation: "deploy agents independently and orchestrate via MCP"
|
|
5359
|
-
},
|
|
5527
|
+
multiagent: { tier: "native", reason: "coordinator + roster topology" },
|
|
5360
5528
|
deployment: {
|
|
5361
5529
|
tier: "native",
|
|
5362
5530
|
reason: "deployments API with cron schedules, manual runs, pause/unpause and archive"
|
|
@@ -5509,11 +5677,10 @@ function envToDecl4(raw) {
|
|
|
5509
5677
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
5510
5678
|
});
|
|
5511
5679
|
}
|
|
5512
|
-
function agentToDecl4(raw) {
|
|
5680
|
+
function agentToDecl4(raw, resolveMember) {
|
|
5513
5681
|
const tools = raw.tools;
|
|
5514
5682
|
const mcpServers = raw.mcp_servers;
|
|
5515
5683
|
const skills = raw.skills;
|
|
5516
|
-
const multiagent = raw.multiagent;
|
|
5517
5684
|
let builtinTools;
|
|
5518
5685
|
let builtinPermissions;
|
|
5519
5686
|
let allToolsEnabled = false;
|
|
@@ -5545,14 +5712,6 @@ function agentToDecl4(raw) {
|
|
|
5545
5712
|
skill_id: s.skill_id
|
|
5546
5713
|
}));
|
|
5547
5714
|
}
|
|
5548
|
-
let multiagentDecl;
|
|
5549
|
-
if (multiagent) {
|
|
5550
|
-
const rawAgents = multiagent.agents;
|
|
5551
|
-
if (rawAgents?.length) {
|
|
5552
|
-
const ids = rawAgents.map((a) => typeof a === "string" ? a : a.id).filter(Boolean);
|
|
5553
|
-
if (ids.length) multiagentDecl = { type: "coordinator", agents: ids };
|
|
5554
|
-
}
|
|
5555
|
-
}
|
|
5556
5715
|
let toolsDecl;
|
|
5557
5716
|
if (builtinTools?.length) {
|
|
5558
5717
|
toolsDecl = { builtin: builtinTools, permissions: builtinPermissions };
|
|
@@ -5569,7 +5728,7 @@ function agentToDecl4(raw) {
|
|
|
5569
5728
|
tools: toolsDecl,
|
|
5570
5729
|
mcp_servers: mcpServerDecls,
|
|
5571
5730
|
skills: skillDecls,
|
|
5572
|
-
multiagent:
|
|
5731
|
+
multiagent: reverseMultiagentDecl(raw.multiagent, resolveMember),
|
|
5573
5732
|
metadata: stripAgentsMetadata(raw.metadata)
|
|
5574
5733
|
});
|
|
5575
5734
|
}
|
|
@@ -5653,10 +5812,10 @@ function mapAgent4(name, decl, refs, version, projectName) {
|
|
|
5653
5812
|
skill_id: s.skill_id
|
|
5654
5813
|
}));
|
|
5655
5814
|
}
|
|
5656
|
-
if (decl.multiagent && refs.
|
|
5815
|
+
if (decl.multiagent && refs.multiagent) {
|
|
5657
5816
|
body.multiagent = {
|
|
5658
5817
|
type: "coordinator",
|
|
5659
|
-
agents: refs.
|
|
5818
|
+
agents: refs.multiagent.members.map(({ remote_id }) => ({ type: "agent", id: remote_id }))
|
|
5660
5819
|
};
|
|
5661
5820
|
}
|
|
5662
5821
|
return body;
|
|
@@ -5908,13 +6067,18 @@ var ArkAdapter = class _ArkAdapter {
|
|
|
5908
6067
|
}
|
|
5909
6068
|
async exportResources(type) {
|
|
5910
6069
|
if (type === "skill") return [];
|
|
5911
|
-
return exportRemoteResources(
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
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
|
+
);
|
|
5918
6082
|
}
|
|
5919
6083
|
// Ark skills support create + get + attach only. There is no list/update/delete endpoint
|
|
5920
6084
|
// (GET /skills, PUT /skills/{id}, DELETE /skills/{id} all return 404 on real probe), so:
|
|
@@ -6229,6 +6393,50 @@ function severityIcon(s) {
|
|
|
6229
6393
|
}
|
|
6230
6394
|
}
|
|
6231
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
|
+
|
|
6232
6440
|
// src/internal/validation/bailian.ts
|
|
6233
6441
|
function findMissingBailianMcpToolConfigs(config, providerName = "bailian") {
|
|
6234
6442
|
if (providerName !== "bailian") return [];
|
|
@@ -6330,6 +6538,7 @@ function collectReferenceDiagnostics(config, diagnostics) {
|
|
|
6330
6538
|
}
|
|
6331
6539
|
if (agent.multiagent) {
|
|
6332
6540
|
for (const subAgent of agent.multiagent.agents) {
|
|
6541
|
+
if (typeof subAgent !== "string") continue;
|
|
6333
6542
|
if (!agentNames.has(subAgent)) {
|
|
6334
6543
|
diagnostics.error(
|
|
6335
6544
|
"config.agent.multiagent.unknown",
|
|
@@ -6342,6 +6551,7 @@ function collectReferenceDiagnostics(config, diagnostics) {
|
|
|
6342
6551
|
}
|
|
6343
6552
|
}
|
|
6344
6553
|
}
|
|
6554
|
+
collectMultiagentTopologyDiagnostics(config, diagnostics);
|
|
6345
6555
|
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
6346
6556
|
if (deployment.tunnel && !tunnelNames.has(deployment.tunnel)) {
|
|
6347
6557
|
diagnostics.error(
|
|
@@ -6663,15 +6873,44 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
6663
6873
|
{ type: "template", name, provider: providerName }
|
|
6664
6874
|
);
|
|
6665
6875
|
}
|
|
6666
|
-
|
|
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;
|
|
6667
6894
|
diagnostics.error(
|
|
6668
|
-
"qoder.template.multiagent.
|
|
6669
|
-
`agent.${name}: multiagent
|
|
6670
|
-
{ 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 }
|
|
6671
6898
|
);
|
|
6672
6899
|
}
|
|
6673
6900
|
}
|
|
6674
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
|
+
}
|
|
6675
6914
|
if (providerName === "qoder") {
|
|
6676
6915
|
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
6677
6916
|
if (deployment.provider && deployment.provider !== providerName) continue;
|