@openagentpack/sdk 0.4.0 → 0.5.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-GAAU67HX.js → chunk-6PDVAFLK.js} +13 -0
- package/dist/{file-URqwlxLf.d.ts → file-Cj5-Vx27.d.ts} +5 -0
- package/dist/file-lifecycle.d.ts +1 -1
- package/dist/index.d.ts +278 -24
- package/dist/index.js +1385 -503
- package/dist/{session-event--Mxe1bnT.d.ts → session-event-5kLRNMHC.d.ts} +50 -38
- package/dist/session-events.d.ts +1 -1
- package/dist/session-events.js +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
toSessionEvent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6PDVAFLK.js";
|
|
4
4
|
import {
|
|
5
5
|
defaultFileUploadPurpose,
|
|
6
6
|
enrichProviderFileInfo
|
|
@@ -628,6 +628,13 @@ async function listSessionEventsPaged(client, sessionId, options, toEvent, confi
|
|
|
628
628
|
const params = new URLSearchParams();
|
|
629
629
|
if (options?.limit) params.set("limit", String(options.limit));
|
|
630
630
|
if (options?.order) params.set("order", options.order);
|
|
631
|
+
if (config?.forwardTypes !== false) {
|
|
632
|
+
for (const type of options?.types ?? []) params.append("types", type);
|
|
633
|
+
}
|
|
634
|
+
if (options?.created_at_gt) params.set("created_at[gt]", options.created_at_gt);
|
|
635
|
+
if (options?.created_at_gte) params.set("created_at[gte]", options.created_at_gte);
|
|
636
|
+
if (options?.created_at_lt) params.set("created_at[lt]", options.created_at_lt);
|
|
637
|
+
if (options?.created_at_lte) params.set("created_at[lte]", options.created_at_lte);
|
|
631
638
|
const pageCursor = options?.page_token ?? options?.page;
|
|
632
639
|
if (pageCursor) params.set("page", pageCursor);
|
|
633
640
|
if (config?.forwardAfterId && options?.after_id) params.set("after_id", options.after_id);
|
|
@@ -794,7 +801,8 @@ function toCloudAgent(raw) {
|
|
|
794
801
|
workspace_id: raw.workspace_id,
|
|
795
802
|
created_at: raw.created_at,
|
|
796
803
|
updated_at: raw.updated_at,
|
|
797
|
-
archived_at: raw.archived_at ?? null
|
|
804
|
+
archived_at: raw.archived_at ?? null,
|
|
805
|
+
attributes: raw
|
|
798
806
|
};
|
|
799
807
|
}
|
|
800
808
|
function toCloudEnvironment(raw) {
|
|
@@ -810,7 +818,8 @@ function toCloudEnvironment(raw) {
|
|
|
810
818
|
workspace_id: raw.workspace_id,
|
|
811
819
|
created_at: raw.created_at,
|
|
812
820
|
updated_at: raw.updated_at,
|
|
813
|
-
archived_at: raw.archived_at ?? null
|
|
821
|
+
archived_at: raw.archived_at ?? null,
|
|
822
|
+
attributes: raw
|
|
814
823
|
};
|
|
815
824
|
}
|
|
816
825
|
function toCloudVault(raw) {
|
|
@@ -821,7 +830,8 @@ function toCloudVault(raw) {
|
|
|
821
830
|
type: raw.type,
|
|
822
831
|
created_at: raw.created_at ?? null,
|
|
823
832
|
updated_at: raw.updated_at ?? null,
|
|
824
|
-
archived_at: raw.archived_at ?? null
|
|
833
|
+
archived_at: raw.archived_at ?? null,
|
|
834
|
+
attributes: raw
|
|
825
835
|
};
|
|
826
836
|
}
|
|
827
837
|
function toRestFileInfo(res) {
|
|
@@ -833,7 +843,9 @@ function toRestFileInfo(res) {
|
|
|
833
843
|
created_at: res.created_at,
|
|
834
844
|
downloadable: res.downloadable,
|
|
835
845
|
status: res.status,
|
|
836
|
-
purpose: res.purpose
|
|
846
|
+
purpose: res.purpose,
|
|
847
|
+
scope: res.scope,
|
|
848
|
+
attributes: res
|
|
837
849
|
};
|
|
838
850
|
}
|
|
839
851
|
function toRestSkillInfo(res) {
|
|
@@ -846,7 +858,8 @@ function toRestSkillInfo(res) {
|
|
|
846
858
|
status: "active",
|
|
847
859
|
latest_version: res.latest_version,
|
|
848
860
|
created_at: res.created_at,
|
|
849
|
-
updated_at: res.updated_at
|
|
861
|
+
updated_at: res.updated_at,
|
|
862
|
+
attributes: res
|
|
850
863
|
};
|
|
851
864
|
}
|
|
852
865
|
|
|
@@ -1238,7 +1251,7 @@ function mapAgent(name, decl, refs, version, projectName) {
|
|
|
1238
1251
|
}
|
|
1239
1252
|
}
|
|
1240
1253
|
const body = {
|
|
1241
|
-
name,
|
|
1254
|
+
name: decl.name ?? name,
|
|
1242
1255
|
model: modelValue,
|
|
1243
1256
|
system: decl.instructions
|
|
1244
1257
|
};
|
|
@@ -1297,7 +1310,7 @@ function mapAgent(name, decl, refs, version, projectName) {
|
|
|
1297
1310
|
}
|
|
1298
1311
|
function mapDeployment(name, decl, refs, projectName, uploadedFiles) {
|
|
1299
1312
|
const body = {
|
|
1300
|
-
name,
|
|
1313
|
+
name: decl.name ?? name,
|
|
1301
1314
|
agent: refs.agent_version !== void 0 ? { id: refs.agent_id, type: "agent", version: refs.agent_version } : refs.agent_id,
|
|
1302
1315
|
environment_id: refs.environment_id,
|
|
1303
1316
|
initial_events: mapInitialEvents(decl.initial_events)
|
|
@@ -2183,6 +2196,7 @@ function agentToDecl2(raw) {
|
|
|
2183
2196
|
}));
|
|
2184
2197
|
}
|
|
2185
2198
|
return compactDeep({
|
|
2199
|
+
name: raw.name,
|
|
2186
2200
|
description: raw.description,
|
|
2187
2201
|
model: raw.model,
|
|
2188
2202
|
instructions: raw.system,
|
|
@@ -2201,7 +2215,7 @@ function mapMemoryStore2(name, decl) {
|
|
|
2201
2215
|
}
|
|
2202
2216
|
function mapDeployment2(name, decl, refs, projectName, uploadedFiles) {
|
|
2203
2217
|
const body = {
|
|
2204
|
-
name,
|
|
2218
|
+
name: decl.name ?? name,
|
|
2205
2219
|
agent: refs.agent_version !== void 0 ? { id: refs.agent_id, type: "agent", version: refs.agent_version } : refs.agent_id,
|
|
2206
2220
|
environment_id: refs.environment_id,
|
|
2207
2221
|
initial_events: mapDeploymentInitialEvents(decl.initial_events)
|
|
@@ -2307,7 +2321,7 @@ function mapAgent2(name, decl, refs, version, projectName) {
|
|
|
2307
2321
|
model = typeof qoderModel === "string" ? qoderModel : qoderModel.id;
|
|
2308
2322
|
}
|
|
2309
2323
|
const body = {
|
|
2310
|
-
name,
|
|
2324
|
+
name: decl.name ?? name,
|
|
2311
2325
|
model,
|
|
2312
2326
|
system: decl.instructions
|
|
2313
2327
|
};
|
|
@@ -2811,6 +2825,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
2811
2825
|
return compactDeep(normalized);
|
|
2812
2826
|
}
|
|
2813
2827
|
return compactDeep({
|
|
2828
|
+
name: raw.name,
|
|
2814
2829
|
description: raw.description,
|
|
2815
2830
|
model: normalizeModel(raw.model),
|
|
2816
2831
|
instructions: raw.system,
|
|
@@ -2831,7 +2846,7 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
2831
2846
|
const currentMetadata = current.metadata ?? {};
|
|
2832
2847
|
const metadata = { ...body.metadata ?? {} };
|
|
2833
2848
|
for (const key of Object.keys(currentMetadata)) {
|
|
2834
|
-
if (!key.startsWith("agents.") && !(key in metadata)) metadata[key] = null;
|
|
2849
|
+
if (key !== "created_by" && !key.startsWith("agents.") && !(key in metadata)) metadata[key] = null;
|
|
2835
2850
|
}
|
|
2836
2851
|
body.metadata = metadata;
|
|
2837
2852
|
const res = await client.post(`/environments/${id}`, body);
|
|
@@ -2839,8 +2854,20 @@ var QoderAdapter = class _QoderAdapter {
|
|
|
2839
2854
|
}
|
|
2840
2855
|
async deleteEnvironment(id, cascade = false, mode = "managed") {
|
|
2841
2856
|
if (mode === "forward") {
|
|
2842
|
-
|
|
2843
|
-
|
|
2857
|
+
try {
|
|
2858
|
+
await this.forwardClient.delete(`/environments/${id}`);
|
|
2859
|
+
return;
|
|
2860
|
+
} catch (err) {
|
|
2861
|
+
const isConflict = err instanceof ApiError && (err.statusCode === 409 || err.responseBody.includes("in use"));
|
|
2862
|
+
if (!isConflict) throw err;
|
|
2863
|
+
if (!cascade) {
|
|
2864
|
+
throw new UserError(
|
|
2865
|
+
`Environment ${id} is referenced by one or more Forward sessions. Use --cascade to archive the environment.`
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
await this.forwardClient.post(`/environments/${id}/archive`, {});
|
|
2869
|
+
return;
|
|
2870
|
+
}
|
|
2844
2871
|
}
|
|
2845
2872
|
try {
|
|
2846
2873
|
await this.client.delete(`/environments/${id}`);
|
|
@@ -3630,25 +3657,22 @@ function mapVault2(name, decl, projectName) {
|
|
|
3630
3657
|
return body;
|
|
3631
3658
|
}
|
|
3632
3659
|
function mapCredential2(cred) {
|
|
3633
|
-
if (cred.type
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
secret_name: cred.secret_name,
|
|
3638
|
-
secret_value: cred.secret_value,
|
|
3639
|
-
networking: cred.networking ?? { type: "unrestricted" }
|
|
3640
|
-
},
|
|
3641
|
-
display_name: cred.name
|
|
3642
|
-
};
|
|
3660
|
+
if (cred.type !== "environment_variable") {
|
|
3661
|
+
throw new UserError(
|
|
3662
|
+
`credential '${cred.name}': Bailian only supports credential type 'environment_variable', but '${cred.type}' was declared.`
|
|
3663
|
+
);
|
|
3643
3664
|
}
|
|
3644
|
-
|
|
3665
|
+
const body = {
|
|
3645
3666
|
auth: {
|
|
3646
|
-
type:
|
|
3647
|
-
|
|
3648
|
-
|
|
3667
|
+
type: "environment_variable",
|
|
3668
|
+
secret_name: cred.secret_name,
|
|
3669
|
+
secret_value: cred.secret_value,
|
|
3670
|
+
networking: cred.networking ?? { type: "unrestricted" }
|
|
3649
3671
|
},
|
|
3650
3672
|
display_name: cred.name
|
|
3651
3673
|
};
|
|
3674
|
+
if (cred.metadata) body.metadata = cred.metadata;
|
|
3675
|
+
return body;
|
|
3652
3676
|
}
|
|
3653
3677
|
function credToDecl3(raw, vaultName) {
|
|
3654
3678
|
const auth = raw.auth ?? {};
|
|
@@ -3658,6 +3682,7 @@ function credToDecl3(raw, vaultName) {
|
|
|
3658
3682
|
return {
|
|
3659
3683
|
name,
|
|
3660
3684
|
type: "static_bearer",
|
|
3685
|
+
metadata: stripAgentsMetadata(raw.metadata),
|
|
3661
3686
|
mcp_server_url: auth.mcp_server_url ?? "",
|
|
3662
3687
|
access_token: placeholder
|
|
3663
3688
|
};
|
|
@@ -3666,6 +3691,7 @@ function credToDecl3(raw, vaultName) {
|
|
|
3666
3691
|
return {
|
|
3667
3692
|
name,
|
|
3668
3693
|
type: "environment_variable",
|
|
3694
|
+
metadata: stripAgentsMetadata(raw.metadata),
|
|
3669
3695
|
secret_name: auth.secret_name ?? name,
|
|
3670
3696
|
secret_value: placeholder,
|
|
3671
3697
|
networking: networking ?? { type: "unrestricted" }
|
|
@@ -3733,6 +3759,7 @@ function agentToDecl3(raw) {
|
|
|
3733
3759
|
const model = raw.model;
|
|
3734
3760
|
const modelValue = typeof model === "object" && model ? model.id : model;
|
|
3735
3761
|
return compactDeep({
|
|
3762
|
+
name: raw.name,
|
|
3736
3763
|
description: raw.description,
|
|
3737
3764
|
model: modelValue,
|
|
3738
3765
|
instructions: raw.system,
|
|
@@ -3752,7 +3779,7 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
3752
3779
|
modelId = typeof bailianModel === "string" ? bailianModel : bailianModel.id;
|
|
3753
3780
|
}
|
|
3754
3781
|
const body = {
|
|
3755
|
-
name,
|
|
3782
|
+
name: decl.name ?? name,
|
|
3756
3783
|
model: { id: modelId },
|
|
3757
3784
|
system: decl.instructions
|
|
3758
3785
|
};
|
|
@@ -3845,7 +3872,7 @@ function mapDeployment3(name, decl, refs, projectName, uploadedFiles) {
|
|
|
3845
3872
|
const agent = { id: refs.agent_id };
|
|
3846
3873
|
if (refs.agent_version !== void 0) agent.version = refs.agent_version;
|
|
3847
3874
|
const body = {
|
|
3848
|
-
name,
|
|
3875
|
+
name: decl.name ?? name,
|
|
3849
3876
|
agent,
|
|
3850
3877
|
environment_id: refs.environment_id,
|
|
3851
3878
|
initial_events: mapMessageEvents(decl.initial_events)
|
|
@@ -3983,6 +4010,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
3983
4010
|
});
|
|
3984
4011
|
}
|
|
3985
4012
|
return compactDeep({
|
|
4013
|
+
name: raw.name,
|
|
3986
4014
|
description: raw.description,
|
|
3987
4015
|
model: normalizeBailianModel(raw.model),
|
|
3988
4016
|
instructions: raw.system,
|
|
@@ -4014,6 +4042,18 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4014
4042
|
async deleteEnvironment(id) {
|
|
4015
4043
|
await this.client.delete(`/environments/${id}`);
|
|
4016
4044
|
}
|
|
4045
|
+
async listEnvironmentResources(options) {
|
|
4046
|
+
const params = cursorParams(options);
|
|
4047
|
+
if (options?.include_archived !== void 0) {
|
|
4048
|
+
params.set("include_archived", String(options.include_archived));
|
|
4049
|
+
}
|
|
4050
|
+
const res = await this.client.get(withQuery("/environments", params));
|
|
4051
|
+
return cursorPage(res, toCloudEnvironment);
|
|
4052
|
+
}
|
|
4053
|
+
async getRemoteEnvironment(id) {
|
|
4054
|
+
const res = await this.client.get(`/environments/${id}`);
|
|
4055
|
+
return toCloudEnvironment(res);
|
|
4056
|
+
}
|
|
4017
4057
|
// --- Agent ---
|
|
4018
4058
|
async createAgent(name, decl, refs) {
|
|
4019
4059
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
@@ -4062,6 +4102,25 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4062
4102
|
async deleteAgent(id) {
|
|
4063
4103
|
await this.client.post(`/agents/${id}/archive`, {});
|
|
4064
4104
|
}
|
|
4105
|
+
async listAgentResources(options) {
|
|
4106
|
+
const params = cursorParams(options);
|
|
4107
|
+
if (options?.include_archived !== void 0) {
|
|
4108
|
+
params.set("include_archived", String(options.include_archived));
|
|
4109
|
+
}
|
|
4110
|
+
const res = await this.client.get(withQuery("/agents", params));
|
|
4111
|
+
return cursorPage(res, toCloudAgent);
|
|
4112
|
+
}
|
|
4113
|
+
async getRemoteAgent(id, version) {
|
|
4114
|
+
const params = new URLSearchParams();
|
|
4115
|
+
if (version !== void 0) params.set("version", String(version));
|
|
4116
|
+
const res = await this.client.get(withQuery(`/agents/${id}`, params));
|
|
4117
|
+
return toCloudAgent(res);
|
|
4118
|
+
}
|
|
4119
|
+
async listAgentVersions(id, options) {
|
|
4120
|
+
const params = cursorParams(options);
|
|
4121
|
+
const res = await this.client.get(withQuery(`/agents/${id}/versions`, params));
|
|
4122
|
+
return cursorPage(res, toCloudAgent);
|
|
4123
|
+
}
|
|
4065
4124
|
// --- Skill (2-step: Files API → Skills API) ---
|
|
4066
4125
|
async createSkill(name, decl, files) {
|
|
4067
4126
|
const fileId = await this.uploadSkillZip(name, decl, files);
|
|
@@ -4160,10 +4219,31 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4160
4219
|
const all = await this.client.getAllPaged(path);
|
|
4161
4220
|
return all.map(toBailianSkillInfo);
|
|
4162
4221
|
}
|
|
4222
|
+
async listSkillResources(options) {
|
|
4223
|
+
const params = cursorParams(options);
|
|
4224
|
+
if (options?.source === "official") params.set("source", "official");
|
|
4225
|
+
if (options?.source === "custom") params.set("source", "customer");
|
|
4226
|
+
const res = await this.client.get(withQuery("/skills", params));
|
|
4227
|
+
return cursorPage(res, toBailianSkillInfo);
|
|
4228
|
+
}
|
|
4163
4229
|
async getSkillInfo(id) {
|
|
4164
4230
|
const res = await this.client.get(`/skills/${id}`);
|
|
4165
4231
|
return toBailianSkillInfo(res);
|
|
4166
4232
|
}
|
|
4233
|
+
async listSkillVersions(id, options) {
|
|
4234
|
+
const params = cursorParams(options);
|
|
4235
|
+
const res = await this.client.get(withQuery(`/skills/${id}/versions`, params));
|
|
4236
|
+
return cursorPage(res, toSkillVersionInfo);
|
|
4237
|
+
}
|
|
4238
|
+
async getSkillVersion(id, version) {
|
|
4239
|
+
const res = await this.client.get(`/skills/${id}/versions/${encodeURIComponent(version)}`);
|
|
4240
|
+
return toSkillVersionInfo(res);
|
|
4241
|
+
}
|
|
4242
|
+
async getSkillDownloadInfo(id, version) {
|
|
4243
|
+
return await this.client.get(
|
|
4244
|
+
`/skills/${id}/versions/${encodeURIComponent(version)}/content`
|
|
4245
|
+
);
|
|
4246
|
+
}
|
|
4167
4247
|
// Non-blocking create: file already uploaded → POST /skills with retry for residual OSS
|
|
4168
4248
|
// replication lag (postSkillWithRetry covers SKILL_FILE_NOT_FOUND for a few seconds), and return
|
|
4169
4249
|
// the initial status WITHOUT waiting for the security scan. Callers MUST ensure the file has
|
|
@@ -4223,6 +4303,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4223
4303
|
// thin wrappers over the AgentStudio endpoints, exposed so callers/tests can
|
|
4224
4304
|
// exercise the full surface through real project code rather than raw fetch.
|
|
4225
4305
|
async createVault(name, decl) {
|
|
4306
|
+
for (const credential of decl.credentials ?? []) mapCredential2(credential);
|
|
4226
4307
|
const body = mapVault2(name, decl, this.projectName);
|
|
4227
4308
|
const res = await this.client.post("/vaults", body);
|
|
4228
4309
|
const vaultId = res.id;
|
|
@@ -4235,6 +4316,18 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4235
4316
|
const all = await this.client.getAllPaged("/vaults");
|
|
4236
4317
|
return all.map(toCloudVault);
|
|
4237
4318
|
}
|
|
4319
|
+
async listVaultResources(options) {
|
|
4320
|
+
const params = cursorParams(options);
|
|
4321
|
+
if (options?.include_archived !== void 0) {
|
|
4322
|
+
params.set("include_archived", String(options.include_archived));
|
|
4323
|
+
}
|
|
4324
|
+
const res = await this.client.get(withQuery("/vaults", params));
|
|
4325
|
+
return cursorPage(res, toCloudVault);
|
|
4326
|
+
}
|
|
4327
|
+
async getRemoteVault(id) {
|
|
4328
|
+
const res = await this.client.get(`/vaults/${id}`);
|
|
4329
|
+
return toCloudVault(res);
|
|
4330
|
+
}
|
|
4238
4331
|
async getVault(id) {
|
|
4239
4332
|
return await this.client.get(`/vaults/${id}`);
|
|
4240
4333
|
}
|
|
@@ -4256,7 +4349,22 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4256
4349
|
}
|
|
4257
4350
|
async listCredentials(vaultId) {
|
|
4258
4351
|
const all = await this.client.getAllPaged(`/vaults/${vaultId}/credentials`);
|
|
4259
|
-
return all.map(
|
|
4352
|
+
return all.map((raw) => {
|
|
4353
|
+
const auth = raw.auth ?? {};
|
|
4354
|
+
const networking = auth.networking;
|
|
4355
|
+
const metadata = raw.metadata;
|
|
4356
|
+
return {
|
|
4357
|
+
id: raw.id,
|
|
4358
|
+
display_name: raw.display_name ?? raw.id,
|
|
4359
|
+
auth_type: auth.type ?? "",
|
|
4360
|
+
secret_name: auth.secret_name,
|
|
4361
|
+
mcp_server_url: auth.mcp_server_url,
|
|
4362
|
+
networking_type: networking?.type,
|
|
4363
|
+
metadata: metadata ? Object.fromEntries(
|
|
4364
|
+
Object.entries(metadata).filter((entry) => typeof entry[1] === "string")
|
|
4365
|
+
) : void 0
|
|
4366
|
+
};
|
|
4367
|
+
});
|
|
4260
4368
|
}
|
|
4261
4369
|
async getCredential(vaultId, credentialId) {
|
|
4262
4370
|
return await this.client.get(`/vaults/${vaultId}/credentials/${credentialId}`);
|
|
@@ -4306,11 +4414,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4306
4414
|
throw new UserError(`Deployment '${ctx.name}' has no remote id; run \`agents apply\` first.`);
|
|
4307
4415
|
}
|
|
4308
4416
|
const res = await this.client.post(`/deployments/${ctx.id}/run`, {});
|
|
4309
|
-
return
|
|
4310
|
-
run_id: res.id,
|
|
4311
|
-
session_id: res.session_id ?? null,
|
|
4312
|
-
error: res.error ?? void 0
|
|
4313
|
-
};
|
|
4417
|
+
return toDeploymentRunResult(res);
|
|
4314
4418
|
}
|
|
4315
4419
|
async getDeployment(ctx) {
|
|
4316
4420
|
if (!ctx.id) {
|
|
@@ -4322,6 +4426,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4322
4426
|
async listDeployments(filter) {
|
|
4323
4427
|
const params = new URLSearchParams();
|
|
4324
4428
|
if (filter?.agent_id) params.set("agent_id", filter.agent_id);
|
|
4429
|
+
if (filter?.keyword) params.set("keyword", filter.keyword);
|
|
4325
4430
|
if (filter?.status) params.set("status", filter.status);
|
|
4326
4431
|
if (filter?.include_archived) params.set("include_archived", "true");
|
|
4327
4432
|
if (filter?.limit) params.set("limit", String(filter.limit));
|
|
@@ -4337,6 +4442,32 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4337
4442
|
next_page: nextPage
|
|
4338
4443
|
};
|
|
4339
4444
|
}
|
|
4445
|
+
async getDeploymentById(id) {
|
|
4446
|
+
const res = await this.client.get(`/deployments/${id}`);
|
|
4447
|
+
return toDeploymentInfo3(res);
|
|
4448
|
+
}
|
|
4449
|
+
async runDeploymentById(id) {
|
|
4450
|
+
const res = await this.client.post(`/deployments/${id}/run`, {});
|
|
4451
|
+
return toDeploymentRunResult(res);
|
|
4452
|
+
}
|
|
4453
|
+
async pauseDeploymentById(id) {
|
|
4454
|
+
const res = await this.client.post(`/deployments/${id}/pause`, {});
|
|
4455
|
+
return toDeploymentInfo3(res);
|
|
4456
|
+
}
|
|
4457
|
+
async unpauseDeploymentById(id) {
|
|
4458
|
+
const res = await this.client.post(`/deployments/${id}/unpause`, {});
|
|
4459
|
+
return toDeploymentInfo3(res);
|
|
4460
|
+
}
|
|
4461
|
+
async listDeploymentRuns(deploymentId, options) {
|
|
4462
|
+
const res = await this.client.get(
|
|
4463
|
+
withQuery(`/deployments/${deploymentId}/runs`, cursorParams(options))
|
|
4464
|
+
);
|
|
4465
|
+
return cursorPage(res, toDeploymentRunInfo);
|
|
4466
|
+
}
|
|
4467
|
+
async getDeploymentRun(runId) {
|
|
4468
|
+
const res = await this.client.get(`/deployment_runs/${runId}`);
|
|
4469
|
+
return toDeploymentRunInfo(res);
|
|
4470
|
+
}
|
|
4340
4471
|
async pauseDeployment(ctx) {
|
|
4341
4472
|
return this.setDeploymentPaused(ctx, true);
|
|
4342
4473
|
}
|
|
@@ -4391,6 +4522,9 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4391
4522
|
async listSessions(filter) {
|
|
4392
4523
|
const params = new URLSearchParams();
|
|
4393
4524
|
if (filter?.agent_id) params.set("agent_id", filter.agent_id);
|
|
4525
|
+
for (const status of filter?.statuses ?? []) params.append("statuses[]", status);
|
|
4526
|
+
if (filter?.created_at_gte) params.set("created_at[gte]", filter.created_at_gte);
|
|
4527
|
+
if (filter?.created_at_lte) params.set("created_at[lte]", filter.created_at_lte);
|
|
4394
4528
|
if (filter?.limit) params.set("limit", String(filter.limit));
|
|
4395
4529
|
if (filter?.page) params.set("page", filter.page);
|
|
4396
4530
|
const qs = params.toString();
|
|
@@ -4407,6 +4541,15 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4407
4541
|
const res = await this.client.get(`/sessions/${id}`);
|
|
4408
4542
|
return toSessionInfo3(res);
|
|
4409
4543
|
}
|
|
4544
|
+
async updateSession(id, input) {
|
|
4545
|
+
const res = await this.client.post(`/sessions/${id}`, input);
|
|
4546
|
+
if (!res.agent || !res.environment_id) return this.getSession(id);
|
|
4547
|
+
return toSessionInfo3(res);
|
|
4548
|
+
}
|
|
4549
|
+
async archiveSession(id) {
|
|
4550
|
+
const res = await this.client.post(`/sessions/${id}/archive`, {});
|
|
4551
|
+
return toSessionInfo3(res);
|
|
4552
|
+
}
|
|
4410
4553
|
async deleteSession(id) {
|
|
4411
4554
|
await this.client.delete(`/sessions/${id}`);
|
|
4412
4555
|
}
|
|
@@ -4415,13 +4558,20 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4415
4558
|
const res = await this.client.post(`/sessions/${sessionId}/events`, body);
|
|
4416
4559
|
return extractCreatedEventId(res);
|
|
4417
4560
|
}
|
|
4561
|
+
async sendSessionEvents(sessionId, events) {
|
|
4562
|
+
const res = await this.client.post(`/sessions/${sessionId}/events`, { input: events });
|
|
4563
|
+
return {
|
|
4564
|
+
event_ids: extractCreatedEventIds(res),
|
|
4565
|
+
attributes: res
|
|
4566
|
+
};
|
|
4567
|
+
}
|
|
4418
4568
|
async *streamSessionEvents(sessionId, _options) {
|
|
4419
4569
|
for await (const raw of this.client.sse(`/sessions/${sessionId}/events/stream`)) {
|
|
4420
4570
|
yield toSessionEvent(raw);
|
|
4421
4571
|
}
|
|
4422
4572
|
}
|
|
4423
4573
|
async listSessionEvents(sessionId, options) {
|
|
4424
|
-
return listSessionEventsPaged(this.client, sessionId, options, toSessionEvent);
|
|
4574
|
+
return listSessionEventsPaged(this.client, sessionId, options, toSessionEvent, { forwardTypes: false });
|
|
4425
4575
|
}
|
|
4426
4576
|
// --- Files ---
|
|
4427
4577
|
async uploadFile(filePath, options) {
|
|
@@ -4447,6 +4597,15 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4447
4597
|
const all = await this.client.getAllPaged("/files");
|
|
4448
4598
|
return all.map(toRestFileInfo);
|
|
4449
4599
|
}
|
|
4600
|
+
async listFileResources(options) {
|
|
4601
|
+
const params = cursorParams(options);
|
|
4602
|
+
if (options?.scope_id) params.set("scope_id", options.scope_id);
|
|
4603
|
+
const res = await this.client.get(withQuery("/files", params));
|
|
4604
|
+
return cursorPage(res, toRestFileInfo);
|
|
4605
|
+
}
|
|
4606
|
+
async downloadFileContent(id) {
|
|
4607
|
+
return new Uint8Array(await this.client.getBuffer(`/files/${id}/content`));
|
|
4608
|
+
}
|
|
4450
4609
|
async deleteFile(id) {
|
|
4451
4610
|
await this.client.delete(`/files/${id}`);
|
|
4452
4611
|
}
|
|
@@ -4481,9 +4640,77 @@ function toBailianSkillInfo(res) {
|
|
|
4481
4640
|
status: skillStatusFromString(res.status),
|
|
4482
4641
|
latest_version: res.latest_version,
|
|
4483
4642
|
created_at: res.created_at,
|
|
4484
|
-
updated_at: res.updated_at
|
|
4643
|
+
updated_at: res.updated_at,
|
|
4644
|
+
attributes: res
|
|
4645
|
+
};
|
|
4646
|
+
}
|
|
4647
|
+
function cursorParams(options) {
|
|
4648
|
+
const params = new URLSearchParams();
|
|
4649
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
4650
|
+
if (options?.page) params.set("page", options.page);
|
|
4651
|
+
return params;
|
|
4652
|
+
}
|
|
4653
|
+
function withQuery(path, params) {
|
|
4654
|
+
const query2 = params.toString();
|
|
4655
|
+
return query2 ? `${path}?${query2}` : path;
|
|
4656
|
+
}
|
|
4657
|
+
function cursorPage(res, mapper) {
|
|
4658
|
+
const nextPage = res.next_page ?? void 0;
|
|
4659
|
+
return {
|
|
4660
|
+
data: (res.data ?? []).map(mapper),
|
|
4661
|
+
has_more: res.has_more ?? nextPage !== void 0,
|
|
4662
|
+
next_page: nextPage
|
|
4663
|
+
};
|
|
4664
|
+
}
|
|
4665
|
+
function toSkillVersionInfo(res) {
|
|
4666
|
+
return {
|
|
4667
|
+
id: res.id,
|
|
4668
|
+
skill_id: res.skill_id ?? "",
|
|
4669
|
+
type: res.type ?? "skill_version",
|
|
4670
|
+
name: res.name,
|
|
4671
|
+
description: res.description,
|
|
4672
|
+
version: res.version ?? "",
|
|
4673
|
+
status: res.status,
|
|
4674
|
+
created_at: res.created_at,
|
|
4675
|
+
updated_at: res.updated_at,
|
|
4676
|
+
additional_properties: res.additional_properties,
|
|
4677
|
+
attributes: res
|
|
4678
|
+
};
|
|
4679
|
+
}
|
|
4680
|
+
function toDeploymentRunResult(res) {
|
|
4681
|
+
return {
|
|
4682
|
+
run_id: res.id,
|
|
4683
|
+
session_id: res.session_id ?? null,
|
|
4684
|
+
error: res.error ?? void 0
|
|
4685
|
+
};
|
|
4686
|
+
}
|
|
4687
|
+
function toDeploymentRunInfo(res) {
|
|
4688
|
+
return {
|
|
4689
|
+
id: res.id ?? "",
|
|
4690
|
+
deployment_id: res.deployment_id,
|
|
4691
|
+
session_id: res.session_id ?? void 0,
|
|
4692
|
+
status: res.status,
|
|
4693
|
+
error: res.error ?? void 0,
|
|
4694
|
+
created_at: res.created_at,
|
|
4695
|
+
updated_at: res.updated_at,
|
|
4696
|
+
attributes: res
|
|
4485
4697
|
};
|
|
4486
4698
|
}
|
|
4699
|
+
function extractCreatedEventIds(res) {
|
|
4700
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4701
|
+
const topLevel = extractCreatedEventId(res);
|
|
4702
|
+
if (topLevel) ids.add(topLevel);
|
|
4703
|
+
for (const key of ["data", "events"]) {
|
|
4704
|
+
const items = res[key];
|
|
4705
|
+
if (!Array.isArray(items)) continue;
|
|
4706
|
+
for (const item of items) {
|
|
4707
|
+
if (!item || typeof item !== "object") continue;
|
|
4708
|
+
const id = item.id;
|
|
4709
|
+
if (typeof id === "string") ids.add(id);
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
return Array.from(ids);
|
|
4713
|
+
}
|
|
4487
4714
|
function normalizeBailianModel(value) {
|
|
4488
4715
|
if (value && typeof value === "object" && "id" in value) {
|
|
4489
4716
|
return value.id;
|
|
@@ -4548,7 +4775,7 @@ function guessMimeType(fileName) {
|
|
|
4548
4775
|
// src/internal/providers/bailian/capabilities.ts
|
|
4549
4776
|
var BAILIAN_CAPABILITIES = {
|
|
4550
4777
|
environment: { tier: "native", reason: "environments API" },
|
|
4551
|
-
vault: { tier: "native", reason: "vaults + credentials API
|
|
4778
|
+
vault: { tier: "native", reason: "vaults + environment_variable credentials API" },
|
|
4552
4779
|
skill: { tier: "native", reason: "skills API with 2-step zip upload via Files API" },
|
|
4553
4780
|
agent: { tier: "native", reason: "agents API with versioned updates" },
|
|
4554
4781
|
template: { tier: "unsupported", reason: "no Forward Template equivalent on Bailian" },
|
|
@@ -4809,7 +5036,7 @@ function mapAgent4(name, decl, refs, version, projectName) {
|
|
|
4809
5036
|
if (!arkModel) throw new UserError(`No Ark model specified for agent '${name}'`);
|
|
4810
5037
|
const modelValue = typeof arkModel === "string" ? { id: arkModel } : { id: arkModel.id };
|
|
4811
5038
|
const body = {
|
|
4812
|
-
name,
|
|
5039
|
+
name: decl.name ?? name,
|
|
4813
5040
|
model: modelValue,
|
|
4814
5041
|
system: decl.instructions
|
|
4815
5042
|
};
|
|
@@ -5543,6 +5770,7 @@ var coerceString = z5.union([z5.string(), z5.number()]).transform(String);
|
|
|
5543
5770
|
var staticBearerCredentialSchema = z5.object({
|
|
5544
5771
|
name: z5.string(),
|
|
5545
5772
|
type: z5.literal("static_bearer"),
|
|
5773
|
+
metadata: z5.record(z5.string(), z5.string()).optional(),
|
|
5546
5774
|
mcp_server_url: z5.string(),
|
|
5547
5775
|
access_token: coerceString,
|
|
5548
5776
|
protocol: z5.enum(["sse", "streamable_http"]).optional()
|
|
@@ -5550,6 +5778,7 @@ var staticBearerCredentialSchema = z5.object({
|
|
|
5550
5778
|
var environmentVariableCredentialSchema = z5.object({
|
|
5551
5779
|
name: z5.string(),
|
|
5552
5780
|
type: z5.literal("environment_variable"),
|
|
5781
|
+
metadata: z5.record(z5.string(), z5.string()).optional(),
|
|
5553
5782
|
secret_name: z5.string(),
|
|
5554
5783
|
secret_value: coerceString,
|
|
5555
5784
|
networking: z5.object({ type: z5.enum(["unrestricted", "limited"]) }).optional()
|
|
@@ -5783,6 +6012,7 @@ var scheduleSchema = z5.object({
|
|
|
5783
6012
|
timezone: z5.string()
|
|
5784
6013
|
});
|
|
5785
6014
|
var deploymentSchema = z5.object({
|
|
6015
|
+
name: z5.string().optional(),
|
|
5786
6016
|
agent: z5.string(),
|
|
5787
6017
|
agent_version: z5.number().int().optional(),
|
|
5788
6018
|
environment: z5.string().optional(),
|
|
@@ -6350,8 +6580,61 @@ function resolveTunnelIdFromConfig(config, tunnelName, provider) {
|
|
|
6350
6580
|
}
|
|
6351
6581
|
|
|
6352
6582
|
// src/internal/executor/skill-resolver.ts
|
|
6583
|
+
import { dirname as dirname9 } from "path";
|
|
6584
|
+
|
|
6585
|
+
// src/internal/core/skill-source.ts
|
|
6353
6586
|
import { readFileSync as readFileSync7, statSync as statSync3 } from "fs";
|
|
6354
|
-
import {
|
|
6587
|
+
import { basename as basename6, resolve as resolve10 } from "path";
|
|
6588
|
+
import { parse } from "yaml";
|
|
6589
|
+
async function inspectSkillSource(source, options = {}) {
|
|
6590
|
+
if (/^https?:\/\//i.test(source)) {
|
|
6591
|
+
throw new UserError("Skill source inspection only accepts a local directory, zip, or SKILL.md file.");
|
|
6592
|
+
}
|
|
6593
|
+
const sourcePath = resolve10(options.basePath ?? process.cwd(), source);
|
|
6594
|
+
const sourceStat = statSync3(sourcePath, { throwIfNoEntry: false });
|
|
6595
|
+
if (!sourceStat) throw new UserError(`Skill source not found: ${source}`);
|
|
6596
|
+
let files;
|
|
6597
|
+
if (sourceStat.isDirectory()) {
|
|
6598
|
+
files = collectFiles(sourcePath, "");
|
|
6599
|
+
} else if (sourceStat.isFile() && sourcePath.toLowerCase().endsWith(".zip")) {
|
|
6600
|
+
files = await extractSkillZipFiles(readFileSync7(sourcePath));
|
|
6601
|
+
} else if (sourceStat.isFile() && basename6(sourcePath).toLowerCase() === "skill.md") {
|
|
6602
|
+
files = [{ relativePath: "SKILL.md", content: readFileSync7(sourcePath) }];
|
|
6603
|
+
} else {
|
|
6604
|
+
throw new UserError("Skill source must be a directory, .zip archive, or SKILL.md file.");
|
|
6605
|
+
}
|
|
6606
|
+
const normalizedFiles = normalizeSkillRoot(files);
|
|
6607
|
+
const manifest = normalizedFiles.find((file) => file.relativePath === "SKILL.md");
|
|
6608
|
+
const name = parseSkillManifestName(manifest.content);
|
|
6609
|
+
return { name, sourcePath, files: normalizedFiles };
|
|
6610
|
+
}
|
|
6611
|
+
function normalizeSkillRoot(files) {
|
|
6612
|
+
if (files.some((file) => file.relativePath === "SKILL.md")) return files;
|
|
6613
|
+
const manifests = files.filter((file) => file.relativePath.endsWith("/SKILL.md"));
|
|
6614
|
+
if (manifests.length === 0) throw new UserError("Skill source does not contain SKILL.md.");
|
|
6615
|
+
if (manifests.length > 1) {
|
|
6616
|
+
throw new UserError("Skill source contains multiple SKILL.md files and has no unambiguous root.");
|
|
6617
|
+
}
|
|
6618
|
+
const prefix = manifests[0].relativePath.slice(0, -"SKILL.md".length);
|
|
6619
|
+
return files.filter((file) => file.relativePath.startsWith(prefix)).map((file) => ({ ...file, relativePath: file.relativePath.slice(prefix.length) }));
|
|
6620
|
+
}
|
|
6621
|
+
function parseSkillManifestName(content) {
|
|
6622
|
+
const text = content.toString("utf8");
|
|
6623
|
+
const frontmatter = text.match(/^---\s*\r?\n([\s\S]*?)\r?\n---(?:\s*\r?\n|$)/);
|
|
6624
|
+
if (!frontmatter) throw new UserError("SKILL.md must start with YAML frontmatter containing a name.");
|
|
6625
|
+
let manifest;
|
|
6626
|
+
try {
|
|
6627
|
+
manifest = parse(frontmatter[1]);
|
|
6628
|
+
} catch (error) {
|
|
6629
|
+
throw new UserError(`Invalid SKILL.md frontmatter: ${error instanceof Error ? error.message : String(error)}`);
|
|
6630
|
+
}
|
|
6631
|
+
const rawName = manifest && typeof manifest === "object" ? manifest.name : void 0;
|
|
6632
|
+
const name = typeof rawName === "string" ? rawName.trim() : "";
|
|
6633
|
+
if (!name) throw new UserError("SKILL.md frontmatter must contain a non-empty name.");
|
|
6634
|
+
return name;
|
|
6635
|
+
}
|
|
6636
|
+
|
|
6637
|
+
// src/internal/executor/skill-resolver.ts
|
|
6355
6638
|
async function resolveSkillFiles(decl, ctx) {
|
|
6356
6639
|
if (/^https?:\/\//i.test(decl.source)) {
|
|
6357
6640
|
const res = await resolveFetch()(decl.source);
|
|
@@ -6359,19 +6642,7 @@ async function resolveSkillFiles(decl, ctx) {
|
|
|
6359
6642
|
return extractSkillZipFiles(Buffer.from(await res.arrayBuffer()));
|
|
6360
6643
|
}
|
|
6361
6644
|
if (!ctx.configPath) return [];
|
|
6362
|
-
|
|
6363
|
-
const stat = statSync3(sourcePath, { throwIfNoEntry: false });
|
|
6364
|
-
if (stat?.isDirectory()) {
|
|
6365
|
-
return collectFiles(sourcePath, "");
|
|
6366
|
-
}
|
|
6367
|
-
if (stat?.isFile()) {
|
|
6368
|
-
if (sourcePath.endsWith(".zip")) {
|
|
6369
|
-
return extractSkillZipFiles(readFileSync7(sourcePath));
|
|
6370
|
-
}
|
|
6371
|
-
const content = readFileSync7(sourcePath);
|
|
6372
|
-
return [{ relativePath: "SKILL.md", content }];
|
|
6373
|
-
}
|
|
6374
|
-
return [];
|
|
6645
|
+
return (await inspectSkillSource(decl.source, { basePath: dirname9(ctx.configPath) })).files;
|
|
6375
6646
|
}
|
|
6376
6647
|
|
|
6377
6648
|
// src/internal/executor/executor.ts
|
|
@@ -6449,7 +6720,9 @@ async function executePlan(plan, ctx, options = {}) {
|
|
|
6449
6720
|
await runWithConcurrency(level, concurrency, runAction);
|
|
6450
6721
|
await ctx.state.save();
|
|
6451
6722
|
}
|
|
6452
|
-
|
|
6723
|
+
if (!ctx.createOnly) {
|
|
6724
|
+
await reconcileDefaultMemoryStores(ctx, new Set(plan.actions.map((action) => action.address.provider)));
|
|
6725
|
+
}
|
|
6453
6726
|
for (const action of deletions) {
|
|
6454
6727
|
await runAction(action);
|
|
6455
6728
|
await ctx.state.save();
|
|
@@ -6661,6 +6934,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6661
6934
|
} catch (err) {
|
|
6662
6935
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6663
6936
|
mode: apiMode,
|
|
6937
|
+
createOnly: ctx.createOnly,
|
|
6664
6938
|
onExisting: (existing) => provider.updateEnvironment(existing.id, remoteName, decl, apiMode)
|
|
6665
6939
|
});
|
|
6666
6940
|
adopted = true;
|
|
@@ -6680,6 +6954,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6680
6954
|
} catch (err) {
|
|
6681
6955
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6682
6956
|
mode: apiMode,
|
|
6957
|
+
createOnly: ctx.createOnly,
|
|
6683
6958
|
onExisting: (existing) => provider.updateEnvironment(existing.id, remoteName, decl, apiMode)
|
|
6684
6959
|
});
|
|
6685
6960
|
adopted = true;
|
|
@@ -6706,6 +6981,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6706
6981
|
} catch (err) {
|
|
6707
6982
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6708
6983
|
mode: apiMode,
|
|
6984
|
+
createOnly: ctx.createOnly,
|
|
6709
6985
|
onExisting: async (existing) => {
|
|
6710
6986
|
await provider.deleteVault(existing.id, apiMode);
|
|
6711
6987
|
return provider.createVault(name, decl, apiMode);
|
|
@@ -6742,6 +7018,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6742
7018
|
const searchNames = manifestName && manifestName !== remoteName ? [remoteName, manifestName] : [remoteName];
|
|
6743
7019
|
const existing = await findExistingByNames(provider, "skill", searchNames, apiMode);
|
|
6744
7020
|
if (existing) {
|
|
7021
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address, existing.name);
|
|
6745
7022
|
result = existing.resource;
|
|
6746
7023
|
emitRuntimeFeedback(ctx.onFeedback, {
|
|
6747
7024
|
type: "resource_adopted",
|
|
@@ -6757,6 +7034,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6757
7034
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6758
7035
|
mode: apiMode,
|
|
6759
7036
|
searchNames,
|
|
7037
|
+
createOnly: ctx.createOnly,
|
|
6760
7038
|
onExisting: async (existing2) => existing2
|
|
6761
7039
|
});
|
|
6762
7040
|
adopted = true;
|
|
@@ -6823,6 +7101,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6823
7101
|
} catch (err) {
|
|
6824
7102
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6825
7103
|
mode: apiMode,
|
|
7104
|
+
createOnly: ctx.createOnly,
|
|
6826
7105
|
onExisting: async (existing) => reconcile(existing.id)
|
|
6827
7106
|
});
|
|
6828
7107
|
adopted = true;
|
|
@@ -6841,6 +7120,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6841
7120
|
result = await provider.createAgent(remoteName, decl, refs);
|
|
6842
7121
|
} catch (err) {
|
|
6843
7122
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7123
|
+
createOnly: ctx.createOnly,
|
|
6844
7124
|
onExisting: (existing) => provider.updateAgent(existing.id, remoteName, decl, refs)
|
|
6845
7125
|
});
|
|
6846
7126
|
adopted = true;
|
|
@@ -6864,6 +7144,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6864
7144
|
result = await createTemplate(remoteName, decl, refs);
|
|
6865
7145
|
} catch (err) {
|
|
6866
7146
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7147
|
+
createOnly: ctx.createOnly,
|
|
6867
7148
|
onExisting: (existing) => updateTemplate(existing.id, remoteName, decl, refs)
|
|
6868
7149
|
});
|
|
6869
7150
|
adopted = true;
|
|
@@ -6898,6 +7179,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6898
7179
|
result = await createIdentity(name, decl);
|
|
6899
7180
|
} catch (err) {
|
|
6900
7181
|
if (!(err instanceof ConflictError)) throw err;
|
|
7182
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address);
|
|
6901
7183
|
const existing = await provider.findResource("identity", decl.external_id);
|
|
6902
7184
|
if (!existing?.id) throw err;
|
|
6903
7185
|
result = await updateIdentity(existing.id, name, decl);
|
|
@@ -6921,6 +7203,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6921
7203
|
result = await createChannel(name, decl, refs);
|
|
6922
7204
|
} catch (err) {
|
|
6923
7205
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7206
|
+
createOnly: ctx.createOnly,
|
|
6924
7207
|
onExisting: (existing) => updateChannel(existing.id, name, decl, refs)
|
|
6925
7208
|
});
|
|
6926
7209
|
adopted = true;
|
|
@@ -6940,6 +7223,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6940
7223
|
} catch (err) {
|
|
6941
7224
|
const preparedFiles = err instanceof DeploymentCreateConflictError ? err.preparedFiles : void 0;
|
|
6942
7225
|
const existing = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7226
|
+
createOnly: ctx.createOnly,
|
|
6943
7227
|
onExisting: (existing2) => provider.updateDeployment(existing2.id, name, decl, refs, ctx.configPath ?? "", preparedFiles)
|
|
6944
7228
|
});
|
|
6945
7229
|
adopted = true;
|
|
@@ -6951,6 +7235,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6951
7235
|
} else {
|
|
6952
7236
|
const existing = hasLocalFileSources ? await findExistingByNames(provider, "deployment", [name]) : null;
|
|
6953
7237
|
if (existing) {
|
|
7238
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address, existing.name);
|
|
6954
7239
|
result = await provider.updateDeployment(existing.resource.id, name, decl, refs, ctx.configPath ?? "");
|
|
6955
7240
|
emitRuntimeFeedback(ctx.onFeedback, {
|
|
6956
7241
|
type: "resource_adopted",
|
|
@@ -7051,6 +7336,7 @@ async function findExistingByNames(provider, type, names, mode) {
|
|
|
7051
7336
|
async function adoptOnConflict(err, address, provider, onFeedback, opts) {
|
|
7052
7337
|
if (!(err instanceof ConflictError)) throw err;
|
|
7053
7338
|
const candidates = opts.searchNames?.length ? opts.searchNames : [address.name];
|
|
7339
|
+
if (opts.createOnly) throw createOnlyExistingResourceError(address, candidates.join('" / "'));
|
|
7054
7340
|
const existing = await findExistingByNames(provider, address.type, candidates, opts.mode);
|
|
7055
7341
|
if (!existing) throw nameReservedError(err, address, candidates.join('" / "'));
|
|
7056
7342
|
emitRuntimeFeedback(onFeedback, {
|
|
@@ -7061,6 +7347,11 @@ async function adoptOnConflict(err, address, provider, onFeedback, opts) {
|
|
|
7061
7347
|
});
|
|
7062
7348
|
return opts.onExisting(existing.resource);
|
|
7063
7349
|
}
|
|
7350
|
+
function createOnlyExistingResourceError(address, remoteName = address.name) {
|
|
7351
|
+
return new UserError(
|
|
7352
|
+
`Create-only cannot adopt or reconcile existing ${address.type} "${remoteName}" on provider '${address.provider}'. Choose a new name, or use a normal apply/import workflow to manage the existing resource.`
|
|
7353
|
+
);
|
|
7354
|
+
}
|
|
7064
7355
|
function nameReservedError(err, address, searchName) {
|
|
7065
7356
|
const detail = err instanceof ApiError ? err.message : String(err);
|
|
7066
7357
|
if (address.type === "channel" && err instanceof ApiError && err.responseBody.includes("CHANNEL_CREDENTIAL_CONFLICT")) {
|
|
@@ -7073,73 +7364,6 @@ function nameReservedError(err, address, searchName) {
|
|
|
7073
7364
|
);
|
|
7074
7365
|
}
|
|
7075
7366
|
|
|
7076
|
-
// src/internal/diagnostics/diagnostics.ts
|
|
7077
|
-
var DiagnosticCollector = class {
|
|
7078
|
-
items = [];
|
|
7079
|
-
error(code, message, resource) {
|
|
7080
|
-
this.items.push({ severity: "error", code, message, resource });
|
|
7081
|
-
}
|
|
7082
|
-
warning(code, message, resource) {
|
|
7083
|
-
this.items.push({ severity: "warning", code, message, resource });
|
|
7084
|
-
}
|
|
7085
|
-
info(code, message, resource) {
|
|
7086
|
-
this.items.push({ severity: "info", code, message, resource });
|
|
7087
|
-
}
|
|
7088
|
-
hasErrors() {
|
|
7089
|
-
return this.items.some((d) => d.severity === "error");
|
|
7090
|
-
}
|
|
7091
|
-
getAll() {
|
|
7092
|
-
return [...this.items];
|
|
7093
|
-
}
|
|
7094
|
-
format() {
|
|
7095
|
-
if (this.items.length === 0) return "";
|
|
7096
|
-
const lines = [];
|
|
7097
|
-
for (const d of this.items) {
|
|
7098
|
-
const icon = severityIcon(d.severity);
|
|
7099
|
-
const addr = d.resource ? ` ${d.resource.type}.${d.resource.name} (${d.resource.provider})` : "";
|
|
7100
|
-
lines.push(`${icon} ${d.code}`);
|
|
7101
|
-
if (addr) lines.push(` Resource:${addr}`);
|
|
7102
|
-
lines.push(` ${d.message}`);
|
|
7103
|
-
lines.push("");
|
|
7104
|
-
}
|
|
7105
|
-
return lines.join("\n");
|
|
7106
|
-
}
|
|
7107
|
-
};
|
|
7108
|
-
function severityIcon(s) {
|
|
7109
|
-
switch (s) {
|
|
7110
|
-
case "error":
|
|
7111
|
-
return "\u2717";
|
|
7112
|
-
case "warning":
|
|
7113
|
-
return "\u26A0";
|
|
7114
|
-
case "info":
|
|
7115
|
-
return "\u2139";
|
|
7116
|
-
}
|
|
7117
|
-
}
|
|
7118
|
-
|
|
7119
|
-
// src/internal/validation/bailian.ts
|
|
7120
|
-
function findMissingBailianMcpToolConfigs(config, providerName = "bailian") {
|
|
7121
|
-
if (providerName !== "bailian") return [];
|
|
7122
|
-
const missing = [];
|
|
7123
|
-
for (const [agentName, agent] of Object.entries(config.agents ?? {})) {
|
|
7124
|
-
if (!agentTargetsProvider(config, agent.provider, providerName)) continue;
|
|
7125
|
-
const configuredToolServers = new Set((agent.tools?.mcp ?? []).map((tool) => tool.mcp_server_name));
|
|
7126
|
-
for (const server of agent.mcp_servers ?? []) {
|
|
7127
|
-
if (!configuredToolServers.has(server.name)) {
|
|
7128
|
-
missing.push({ agentName, serverName: server.name });
|
|
7129
|
-
}
|
|
7130
|
-
}
|
|
7131
|
-
}
|
|
7132
|
-
return missing;
|
|
7133
|
-
}
|
|
7134
|
-
function agentTargetsProvider(config, agentProvider, providerName) {
|
|
7135
|
-
if (agentProvider) return agentProvider === providerName;
|
|
7136
|
-
const defaultProvider = config.defaults?.provider;
|
|
7137
|
-
if (defaultProvider && defaultProvider !== "all") {
|
|
7138
|
-
return defaultProvider === providerName;
|
|
7139
|
-
}
|
|
7140
|
-
return Object.hasOwn(config.providers, providerName);
|
|
7141
|
-
}
|
|
7142
|
-
|
|
7143
7367
|
// src/internal/core/agent-materialization.ts
|
|
7144
7368
|
function resolveAgentMaterialization(provider, agent) {
|
|
7145
7369
|
const mode = agent.delivery?.[provider]?.type ?? "managed";
|
|
@@ -7147,44 +7371,334 @@ function resolveAgentMaterialization(provider, agent) {
|
|
|
7147
7371
|
return { resourceType: "template", mode };
|
|
7148
7372
|
}
|
|
7149
7373
|
|
|
7150
|
-
// src/internal/
|
|
7151
|
-
function
|
|
7152
|
-
const
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
return collector.getAll();
|
|
7162
|
-
}
|
|
7163
|
-
function resolveTargetProviders(config) {
|
|
7164
|
-
const defaultProvider = config.defaults?.provider;
|
|
7165
|
-
if (!defaultProvider || defaultProvider === "all") {
|
|
7166
|
-
return Object.keys(config.providers);
|
|
7374
|
+
// src/internal/graph/dependency.ts
|
|
7375
|
+
function collectDependencyClosure(graph, roots) {
|
|
7376
|
+
const selected = /* @__PURE__ */ new Map();
|
|
7377
|
+
function visit(address) {
|
|
7378
|
+
const key = addressKey(address);
|
|
7379
|
+
if (selected.has(key)) return;
|
|
7380
|
+
selected.set(key, graph.nodes.get(key) ?? address);
|
|
7381
|
+
for (const dependencyKey of graph.edges.get(key) ?? []) {
|
|
7382
|
+
const dependency = graph.nodes.get(dependencyKey);
|
|
7383
|
+
if (dependency) visit(dependency);
|
|
7384
|
+
}
|
|
7167
7385
|
}
|
|
7168
|
-
|
|
7386
|
+
for (const root of roots) visit(root);
|
|
7387
|
+
return [...selected.values()];
|
|
7169
7388
|
}
|
|
7170
|
-
function
|
|
7171
|
-
const
|
|
7172
|
-
const
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
const agentNames = new Set(Object.keys(config.agents ?? {}));
|
|
7178
|
-
const identityNames = new Set(Object.keys(config.identities ?? {}));
|
|
7179
|
-
if (config.defaults?.identity && !identityNames.has(config.defaults.identity)) {
|
|
7180
|
-
diagnostics.error(
|
|
7181
|
-
"config.defaults.identity.unknown",
|
|
7182
|
-
`defaults.identity references unknown identity '${config.defaults.identity}'`
|
|
7183
|
-
);
|
|
7389
|
+
function buildDependencyGraph(config, targetProviders) {
|
|
7390
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
7391
|
+
const edges = /* @__PURE__ */ new Map();
|
|
7392
|
+
function addNode(addr) {
|
|
7393
|
+
const key = addressKey(addr);
|
|
7394
|
+
nodes.set(key, addr);
|
|
7395
|
+
if (!edges.has(key)) edges.set(key, /* @__PURE__ */ new Set());
|
|
7184
7396
|
}
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7397
|
+
function addEdge(from, to) {
|
|
7398
|
+
const fromKey = addressKey(from);
|
|
7399
|
+
const toKey = addressKey(to);
|
|
7400
|
+
edges.get(fromKey)?.add(toKey);
|
|
7401
|
+
}
|
|
7402
|
+
for (const provider of targetProviders) {
|
|
7403
|
+
const def = getProvider(provider);
|
|
7404
|
+
const caps = def?.capabilities;
|
|
7405
|
+
if (config.environments) {
|
|
7406
|
+
for (const name of Object.keys(config.environments)) {
|
|
7407
|
+
const decl = config.environments[name];
|
|
7408
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7409
|
+
addNode({ type: "environment", name, provider });
|
|
7410
|
+
}
|
|
7411
|
+
}
|
|
7412
|
+
if (config.memory_stores) {
|
|
7413
|
+
for (const name of Object.keys(config.memory_stores)) {
|
|
7414
|
+
const decl = config.memory_stores[name];
|
|
7415
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7416
|
+
if (!isSupported(caps, "memory_store")) continue;
|
|
7417
|
+
addNode({ type: "memory_store", name, provider });
|
|
7418
|
+
}
|
|
7419
|
+
}
|
|
7420
|
+
if (config.vaults) {
|
|
7421
|
+
for (const name of Object.keys(config.vaults)) {
|
|
7422
|
+
const decl = config.vaults[name];
|
|
7423
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7424
|
+
addNode({ type: "vault", name, provider });
|
|
7425
|
+
}
|
|
7426
|
+
}
|
|
7427
|
+
if (config.skills) {
|
|
7428
|
+
for (const name of Object.keys(config.skills)) {
|
|
7429
|
+
const decl = config.skills[name];
|
|
7430
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7431
|
+
addNode({ type: "skill", name, provider });
|
|
7432
|
+
}
|
|
7433
|
+
}
|
|
7434
|
+
if (config.files) {
|
|
7435
|
+
for (const name of Object.keys(config.files)) {
|
|
7436
|
+
const decl = config.files[name];
|
|
7437
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7438
|
+
addNode({ type: "file", name, provider });
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
if (config.identities && isSupported(caps, "identity")) {
|
|
7442
|
+
for (const name of Object.keys(config.identities)) {
|
|
7443
|
+
const decl = config.identities[name];
|
|
7444
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7445
|
+
addNode({ type: "identity", name, provider });
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
if (config.agents) {
|
|
7449
|
+
for (const name of Object.keys(config.agents)) {
|
|
7450
|
+
const decl = config.agents[name];
|
|
7451
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7452
|
+
const materialization = resolveAgentMaterialization(provider, decl);
|
|
7453
|
+
const agentAddr = { type: materialization.resourceType, name, provider };
|
|
7454
|
+
addNode(agentAddr);
|
|
7455
|
+
if ((decl.default_memory_store || decl.memory_stores?.length) && materialization.resourceType === "template") {
|
|
7456
|
+
const identityName = config.defaults?.identity;
|
|
7457
|
+
if (identityName) {
|
|
7458
|
+
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7459
|
+
if (nodes.has(addressKey(identityAddr))) addEdge(agentAddr, identityAddr);
|
|
7460
|
+
}
|
|
7461
|
+
}
|
|
7462
|
+
if (decl.environment && config.environments?.[decl.environment]) {
|
|
7463
|
+
const envAddr = {
|
|
7464
|
+
type: "environment",
|
|
7465
|
+
name: decl.environment,
|
|
7466
|
+
provider
|
|
7467
|
+
};
|
|
7468
|
+
if (nodes.has(addressKey(envAddr))) {
|
|
7469
|
+
addEdge(agentAddr, envAddr);
|
|
7470
|
+
}
|
|
7471
|
+
}
|
|
7472
|
+
if (decl.skills) {
|
|
7473
|
+
for (const skillRef of decl.skills) {
|
|
7474
|
+
if (typeof skillRef !== "string") continue;
|
|
7475
|
+
const skillName = skillRef;
|
|
7476
|
+
const skillAddr = { type: "skill", name: skillName, provider };
|
|
7477
|
+
if (nodes.has(addressKey(skillAddr))) {
|
|
7478
|
+
addEdge(agentAddr, skillAddr);
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7482
|
+
if (decl.vault) {
|
|
7483
|
+
const vaultAddr = { type: "vault", name: decl.vault, provider };
|
|
7484
|
+
if (nodes.has(addressKey(vaultAddr))) {
|
|
7485
|
+
addEdge(agentAddr, vaultAddr);
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
if (decl.files) {
|
|
7489
|
+
for (const fileName of decl.files) {
|
|
7490
|
+
const fileAddr = { type: "file", name: fileName, provider };
|
|
7491
|
+
if (nodes.has(addressKey(fileAddr))) addEdge(agentAddr, fileAddr);
|
|
7492
|
+
}
|
|
7493
|
+
}
|
|
7494
|
+
if (decl.memory_stores) {
|
|
7495
|
+
for (const msName of decl.memory_stores) {
|
|
7496
|
+
const msAddr = {
|
|
7497
|
+
type: "memory_store",
|
|
7498
|
+
name: msName,
|
|
7499
|
+
provider
|
|
7500
|
+
};
|
|
7501
|
+
if (nodes.has(addressKey(msAddr))) {
|
|
7502
|
+
addEdge(agentAddr, msAddr);
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
}
|
|
7506
|
+
if (decl.multiagent && isSupported(caps, "multiagent")) {
|
|
7507
|
+
for (const subName of decl.multiagent.agents) {
|
|
7508
|
+
const subDecl = config.agents[subName];
|
|
7509
|
+
const subType = subDecl ? resolveAgentMaterialization(provider, subDecl).resourceType : "agent";
|
|
7510
|
+
const subAddr = { type: subType, name: subName, provider };
|
|
7511
|
+
addEdge(agentAddr, subAddr);
|
|
7512
|
+
}
|
|
7513
|
+
}
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
if (config.deployments) {
|
|
7517
|
+
for (const name of Object.keys(config.deployments)) {
|
|
7518
|
+
const decl = config.deployments[name];
|
|
7519
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7520
|
+
const depAddr = { type: "deployment", name, provider };
|
|
7521
|
+
addNode(depAddr);
|
|
7522
|
+
const agentDecl = config.agents?.[decl.agent];
|
|
7523
|
+
const agentType = agentDecl ? resolveAgentMaterialization(provider, agentDecl).resourceType : "agent";
|
|
7524
|
+
const agentAddr = { type: agentType, name: decl.agent, provider };
|
|
7525
|
+
if (nodes.has(addressKey(agentAddr))) addEdge(depAddr, agentAddr);
|
|
7526
|
+
if (decl.environment) {
|
|
7527
|
+
const envAddr = { type: "environment", name: decl.environment, provider };
|
|
7528
|
+
if (nodes.has(addressKey(envAddr))) addEdge(depAddr, envAddr);
|
|
7529
|
+
}
|
|
7530
|
+
if (decl.vaults) {
|
|
7531
|
+
for (const vName of decl.vaults) {
|
|
7532
|
+
const vAddr = { type: "vault", name: vName, provider };
|
|
7533
|
+
if (nodes.has(addressKey(vAddr))) addEdge(depAddr, vAddr);
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
if (decl.memory_stores) {
|
|
7537
|
+
for (const msName of decl.memory_stores) {
|
|
7538
|
+
const msAddr = { type: "memory_store", name: msName, provider };
|
|
7539
|
+
if (nodes.has(addressKey(msAddr))) addEdge(depAddr, msAddr);
|
|
7540
|
+
}
|
|
7541
|
+
}
|
|
7542
|
+
if (decl.resources) {
|
|
7543
|
+
for (const r of decl.resources) {
|
|
7544
|
+
if (r.type === "memory_store") {
|
|
7545
|
+
const msAddr = { type: "memory_store", name: r.memory_store, provider };
|
|
7546
|
+
if (nodes.has(addressKey(msAddr))) addEdge(depAddr, msAddr);
|
|
7547
|
+
}
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
}
|
|
7551
|
+
}
|
|
7552
|
+
if (config.channels && isSupported(caps, "channel")) {
|
|
7553
|
+
for (const name of Object.keys(config.channels)) {
|
|
7554
|
+
const decl = config.channels[name];
|
|
7555
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7556
|
+
const channelAddr = { type: "channel", name, provider };
|
|
7557
|
+
addNode(channelAddr);
|
|
7558
|
+
if (decl.mode === "pairing" || !decl.agent) continue;
|
|
7559
|
+
const agentDecl = config.agents?.[decl.agent];
|
|
7560
|
+
const agentType = agentDecl ? resolveAgentMaterialization(provider, agentDecl).resourceType : "agent";
|
|
7561
|
+
const agentAddr = { type: agentType, name: decl.agent, provider };
|
|
7562
|
+
if (nodes.has(addressKey(agentAddr))) addEdge(channelAddr, agentAddr);
|
|
7563
|
+
const identityName = decl.identity ?? config.defaults?.identity;
|
|
7564
|
+
if (identityName) {
|
|
7565
|
+
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7566
|
+
if (nodes.has(addressKey(identityAddr))) addEdge(channelAddr, identityAddr);
|
|
7567
|
+
}
|
|
7568
|
+
}
|
|
7569
|
+
}
|
|
7570
|
+
}
|
|
7571
|
+
return { nodes, edges };
|
|
7572
|
+
}
|
|
7573
|
+
function topologicalSort(graph) {
|
|
7574
|
+
const visited = /* @__PURE__ */ new Set();
|
|
7575
|
+
const sorted = [];
|
|
7576
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
7577
|
+
function visit(key) {
|
|
7578
|
+
if (visited.has(key)) return;
|
|
7579
|
+
if (visiting.has(key)) {
|
|
7580
|
+
throw new UserError(`Circular dependency detected involving: ${key}`);
|
|
7581
|
+
}
|
|
7582
|
+
visiting.add(key);
|
|
7583
|
+
const deps = graph.edges.get(key) ?? /* @__PURE__ */ new Set();
|
|
7584
|
+
for (const dep of deps) {
|
|
7585
|
+
visit(dep);
|
|
7586
|
+
}
|
|
7587
|
+
visiting.delete(key);
|
|
7588
|
+
visited.add(key);
|
|
7589
|
+
sorted.push(graph.nodes.get(key));
|
|
7590
|
+
}
|
|
7591
|
+
for (const key of graph.nodes.keys()) {
|
|
7592
|
+
visit(key);
|
|
7593
|
+
}
|
|
7594
|
+
return sorted;
|
|
7595
|
+
}
|
|
7596
|
+
|
|
7597
|
+
// src/internal/diagnostics/diagnostics.ts
|
|
7598
|
+
var DiagnosticCollector = class {
|
|
7599
|
+
items = [];
|
|
7600
|
+
error(code, message, resource) {
|
|
7601
|
+
this.items.push({ severity: "error", code, message, resource });
|
|
7602
|
+
}
|
|
7603
|
+
warning(code, message, resource) {
|
|
7604
|
+
this.items.push({ severity: "warning", code, message, resource });
|
|
7605
|
+
}
|
|
7606
|
+
info(code, message, resource) {
|
|
7607
|
+
this.items.push({ severity: "info", code, message, resource });
|
|
7608
|
+
}
|
|
7609
|
+
hasErrors() {
|
|
7610
|
+
return this.items.some((d) => d.severity === "error");
|
|
7611
|
+
}
|
|
7612
|
+
getAll() {
|
|
7613
|
+
return [...this.items];
|
|
7614
|
+
}
|
|
7615
|
+
format() {
|
|
7616
|
+
if (this.items.length === 0) return "";
|
|
7617
|
+
const lines = [];
|
|
7618
|
+
for (const d of this.items) {
|
|
7619
|
+
const icon = severityIcon(d.severity);
|
|
7620
|
+
const addr = d.resource ? ` ${d.resource.type}.${d.resource.name} (${d.resource.provider})` : "";
|
|
7621
|
+
lines.push(`${icon} ${d.code}`);
|
|
7622
|
+
if (addr) lines.push(` Resource:${addr}`);
|
|
7623
|
+
lines.push(` ${d.message}`);
|
|
7624
|
+
lines.push("");
|
|
7625
|
+
}
|
|
7626
|
+
return lines.join("\n");
|
|
7627
|
+
}
|
|
7628
|
+
};
|
|
7629
|
+
function severityIcon(s) {
|
|
7630
|
+
switch (s) {
|
|
7631
|
+
case "error":
|
|
7632
|
+
return "\u2717";
|
|
7633
|
+
case "warning":
|
|
7634
|
+
return "\u26A0";
|
|
7635
|
+
case "info":
|
|
7636
|
+
return "\u2139";
|
|
7637
|
+
}
|
|
7638
|
+
}
|
|
7639
|
+
|
|
7640
|
+
// src/internal/validation/bailian.ts
|
|
7641
|
+
function findMissingBailianMcpToolConfigs(config, providerName = "bailian") {
|
|
7642
|
+
if (providerName !== "bailian") return [];
|
|
7643
|
+
const missing = [];
|
|
7644
|
+
for (const [agentName, agent] of Object.entries(config.agents ?? {})) {
|
|
7645
|
+
if (!agentTargetsProvider(config, agent.provider, providerName)) continue;
|
|
7646
|
+
const configuredToolServers = new Set((agent.tools?.mcp ?? []).map((tool) => tool.mcp_server_name));
|
|
7647
|
+
for (const server of agent.mcp_servers ?? []) {
|
|
7648
|
+
if (!configuredToolServers.has(server.name)) {
|
|
7649
|
+
missing.push({ agentName, serverName: server.name });
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
}
|
|
7653
|
+
return missing;
|
|
7654
|
+
}
|
|
7655
|
+
function agentTargetsProvider(config, agentProvider, providerName) {
|
|
7656
|
+
if (agentProvider) return agentProvider === providerName;
|
|
7657
|
+
const defaultProvider = config.defaults?.provider;
|
|
7658
|
+
if (defaultProvider && defaultProvider !== "all") {
|
|
7659
|
+
return defaultProvider === providerName;
|
|
7660
|
+
}
|
|
7661
|
+
return Object.hasOwn(config.providers, providerName);
|
|
7662
|
+
}
|
|
7663
|
+
|
|
7664
|
+
// src/internal/core/validate-config.ts
|
|
7665
|
+
function validateProjectConfig(config, options = {}) {
|
|
7666
|
+
const collector = new DiagnosticCollector();
|
|
7667
|
+
collectReferenceDiagnostics(config, collector);
|
|
7668
|
+
const providers = options.providers ?? resolveTargetProviders(config);
|
|
7669
|
+
collectProviderCapabilities(config, providers, collector);
|
|
7670
|
+
return collector.getAll();
|
|
7671
|
+
}
|
|
7672
|
+
function collectConfigReferences(config) {
|
|
7673
|
+
const collector = new DiagnosticCollector();
|
|
7674
|
+
collectReferenceDiagnostics(config, collector);
|
|
7675
|
+
return collector.getAll();
|
|
7676
|
+
}
|
|
7677
|
+
function resolveTargetProviders(config) {
|
|
7678
|
+
const defaultProvider = config.defaults?.provider;
|
|
7679
|
+
if (!defaultProvider || defaultProvider === "all") {
|
|
7680
|
+
return Object.keys(config.providers);
|
|
7681
|
+
}
|
|
7682
|
+
return [defaultProvider];
|
|
7683
|
+
}
|
|
7684
|
+
function collectReferenceDiagnostics(config, diagnostics) {
|
|
7685
|
+
const envNames = new Set(Object.keys(config.environments ?? {}));
|
|
7686
|
+
const tunnelNames = new Set(Object.keys(config.tunnels ?? {}));
|
|
7687
|
+
const skillNames = new Set(Object.keys(config.skills ?? {}));
|
|
7688
|
+
const vaultNames = new Set(Object.keys(config.vaults ?? {}));
|
|
7689
|
+
const memoryNames = new Set(Object.keys(config.memory_stores ?? {}));
|
|
7690
|
+
const fileNames = new Set(Object.keys(config.files ?? {}));
|
|
7691
|
+
const agentNames = new Set(Object.keys(config.agents ?? {}));
|
|
7692
|
+
const identityNames = new Set(Object.keys(config.identities ?? {}));
|
|
7693
|
+
if (config.defaults?.identity && !identityNames.has(config.defaults.identity)) {
|
|
7694
|
+
diagnostics.error(
|
|
7695
|
+
"config.defaults.identity.unknown",
|
|
7696
|
+
`defaults.identity references unknown identity '${config.defaults.identity}'`
|
|
7697
|
+
);
|
|
7698
|
+
}
|
|
7699
|
+
for (const [name, agent] of Object.entries(config.agents ?? {})) {
|
|
7700
|
+
if (agent.environment && !envNames.has(agent.environment)) {
|
|
7701
|
+
diagnostics.error(
|
|
7188
7702
|
"config.agent.environment.unknown",
|
|
7189
7703
|
`agent.${name}: references unknown environment '${agent.environment}'`
|
|
7190
7704
|
);
|
|
@@ -7666,295 +8180,89 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7666
8180
|
{ type: "agent", name: missing.agentName, provider: providerName }
|
|
7667
8181
|
);
|
|
7668
8182
|
}
|
|
7669
|
-
if (config.memory_stores && !isSupported(caps, "memory_store")) {
|
|
7670
|
-
for (const [name, decl] of Object.entries(config.memory_stores)) {
|
|
7671
|
-
if (!decl.provider || decl.provider === providerName) {
|
|
7672
|
-
diagnostics.error(
|
|
7673
|
-
`${providerName}.memory_store.unsupported`,
|
|
7674
|
-
`${caps.memory_store.reason}. ${caps.memory_store.remediation ?? ""}`.trim(),
|
|
7675
|
-
{ type: "memory_store", name, provider: providerName }
|
|
7676
|
-
);
|
|
7677
|
-
}
|
|
7678
|
-
}
|
|
7679
|
-
}
|
|
7680
|
-
if (config.agents && !isSupported(caps, "multiagent")) {
|
|
7681
|
-
for (const [name, agent] of Object.entries(config.agents)) {
|
|
7682
|
-
if (agent.multiagent) {
|
|
7683
|
-
if (!agent.provider || agent.provider === providerName) {
|
|
7684
|
-
diagnostics.error(
|
|
7685
|
-
`${providerName}.multiagent.unsupported`,
|
|
7686
|
-
`${caps.multiagent.reason}. ${caps.multiagent.remediation ?? ""}`.trim(),
|
|
7687
|
-
{ type: "agent", name, provider: providerName }
|
|
7688
|
-
);
|
|
7689
|
-
}
|
|
7690
|
-
}
|
|
7691
|
-
}
|
|
7692
|
-
}
|
|
7693
|
-
if (config.deployments && caps.deployment.tier === "emulated") {
|
|
7694
|
-
for (const [name, dep] of Object.entries(config.deployments)) {
|
|
7695
|
-
if (dep.provider && dep.provider !== providerName) continue;
|
|
7696
|
-
const addr = {
|
|
7697
|
-
type: "deployment",
|
|
7698
|
-
name,
|
|
7699
|
-
provider: providerName
|
|
7700
|
-
};
|
|
7701
|
-
if (dep.schedule) {
|
|
7702
|
-
diagnostics.warning(
|
|
7703
|
-
`${providerName}.deployment.schedule_unsupported`,
|
|
7704
|
-
"Schedules are not enforced server-side on this provider; trigger runs via external cron/CI.",
|
|
7705
|
-
addr
|
|
7706
|
-
);
|
|
7707
|
-
}
|
|
7708
|
-
if (dep.initial_events?.some((e) => e.type === "user.define_outcome")) {
|
|
7709
|
-
diagnostics.warning(
|
|
7710
|
-
`${providerName}.deployment.define_outcome_unsupported`,
|
|
7711
|
-
"Outcome rubrics (user.define_outcome) are not enforced server-side on this provider; the run executes without rubric grading.",
|
|
7712
|
-
addr
|
|
7713
|
-
);
|
|
7714
|
-
}
|
|
7715
|
-
if (dep.resources?.some((r) => r.type === "github_repository")) {
|
|
7716
|
-
diagnostics.warning(
|
|
7717
|
-
`${providerName}.deployment.github_repository_unsupported`,
|
|
7718
|
-
"github_repository resources are not provisioned on this provider; clone the repository inside the session instead.",
|
|
7719
|
-
addr
|
|
7720
|
-
);
|
|
7721
|
-
}
|
|
7722
|
-
if (dep.resources?.some((r) => r.type === "memory_store" && (r.access === "read_only" || r.instructions))) {
|
|
7723
|
-
diagnostics.warning(
|
|
7724
|
-
`${providerName}.deployment.memory_store_options_unsupported`,
|
|
7725
|
-
"Per-resource memory_store access/instructions are not honored on this provider; the store is attached with default access.",
|
|
7726
|
-
addr
|
|
7727
|
-
);
|
|
7728
|
-
}
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
7731
|
-
}
|
|
7732
|
-
}
|
|
7733
|
-
|
|
7734
|
-
// src/internal/graph/dependency.ts
|
|
7735
|
-
function buildDependencyGraph(config, targetProviders) {
|
|
7736
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
7737
|
-
const edges = /* @__PURE__ */ new Map();
|
|
7738
|
-
function addNode(addr) {
|
|
7739
|
-
const key = addressKey(addr);
|
|
7740
|
-
nodes.set(key, addr);
|
|
7741
|
-
if (!edges.has(key)) edges.set(key, /* @__PURE__ */ new Set());
|
|
7742
|
-
}
|
|
7743
|
-
function addEdge(from, to) {
|
|
7744
|
-
const fromKey = addressKey(from);
|
|
7745
|
-
const toKey = addressKey(to);
|
|
7746
|
-
edges.get(fromKey)?.add(toKey);
|
|
7747
|
-
}
|
|
7748
|
-
for (const provider of targetProviders) {
|
|
7749
|
-
const def = getProvider(provider);
|
|
7750
|
-
const caps = def?.capabilities;
|
|
7751
|
-
if (config.environments) {
|
|
7752
|
-
for (const name of Object.keys(config.environments)) {
|
|
7753
|
-
const decl = config.environments[name];
|
|
7754
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7755
|
-
addNode({ type: "environment", name, provider });
|
|
7756
|
-
}
|
|
7757
|
-
}
|
|
7758
|
-
if (config.memory_stores) {
|
|
7759
|
-
for (const name of Object.keys(config.memory_stores)) {
|
|
7760
|
-
const decl = config.memory_stores[name];
|
|
7761
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7762
|
-
if (!isSupported(caps, "memory_store")) continue;
|
|
7763
|
-
addNode({ type: "memory_store", name, provider });
|
|
7764
|
-
}
|
|
7765
|
-
}
|
|
7766
|
-
if (config.vaults) {
|
|
7767
|
-
for (const name of Object.keys(config.vaults)) {
|
|
7768
|
-
const decl = config.vaults[name];
|
|
7769
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7770
|
-
addNode({ type: "vault", name, provider });
|
|
7771
|
-
}
|
|
7772
|
-
}
|
|
7773
|
-
if (config.skills) {
|
|
7774
|
-
for (const name of Object.keys(config.skills)) {
|
|
7775
|
-
const decl = config.skills[name];
|
|
7776
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7777
|
-
addNode({ type: "skill", name, provider });
|
|
7778
|
-
}
|
|
7779
|
-
}
|
|
7780
|
-
if (config.files) {
|
|
7781
|
-
for (const name of Object.keys(config.files)) {
|
|
7782
|
-
const decl = config.files[name];
|
|
7783
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7784
|
-
addNode({ type: "file", name, provider });
|
|
7785
|
-
}
|
|
7786
|
-
}
|
|
7787
|
-
if (config.identities && isSupported(caps, "identity")) {
|
|
7788
|
-
for (const name of Object.keys(config.identities)) {
|
|
7789
|
-
const decl = config.identities[name];
|
|
7790
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7791
|
-
addNode({ type: "identity", name, provider });
|
|
7792
|
-
}
|
|
7793
|
-
}
|
|
7794
|
-
if (config.agents) {
|
|
7795
|
-
for (const name of Object.keys(config.agents)) {
|
|
7796
|
-
const decl = config.agents[name];
|
|
7797
|
-
if (decl.provider && decl.provider !== provider) continue;
|
|
7798
|
-
const materialization = resolveAgentMaterialization(provider, decl);
|
|
7799
|
-
const agentAddr = { type: materialization.resourceType, name, provider };
|
|
7800
|
-
addNode(agentAddr);
|
|
7801
|
-
if ((decl.default_memory_store || decl.memory_stores?.length) && materialization.resourceType === "template") {
|
|
7802
|
-
const identityName = config.defaults?.identity;
|
|
7803
|
-
if (identityName) {
|
|
7804
|
-
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7805
|
-
if (nodes.has(addressKey(identityAddr))) addEdge(agentAddr, identityAddr);
|
|
7806
|
-
}
|
|
7807
|
-
}
|
|
7808
|
-
if (decl.environment && config.environments?.[decl.environment]) {
|
|
7809
|
-
const envAddr = {
|
|
7810
|
-
type: "environment",
|
|
7811
|
-
name: decl.environment,
|
|
7812
|
-
provider
|
|
7813
|
-
};
|
|
7814
|
-
if (nodes.has(addressKey(envAddr))) {
|
|
7815
|
-
addEdge(agentAddr, envAddr);
|
|
7816
|
-
}
|
|
7817
|
-
}
|
|
7818
|
-
if (decl.skills) {
|
|
7819
|
-
for (const skillRef of decl.skills) {
|
|
7820
|
-
if (typeof skillRef !== "string") continue;
|
|
7821
|
-
const skillName = skillRef;
|
|
7822
|
-
const skillAddr = { type: "skill", name: skillName, provider };
|
|
7823
|
-
if (nodes.has(addressKey(skillAddr))) {
|
|
7824
|
-
addEdge(agentAddr, skillAddr);
|
|
7825
|
-
}
|
|
7826
|
-
}
|
|
7827
|
-
}
|
|
7828
|
-
if (decl.vault) {
|
|
7829
|
-
const vaultAddr = { type: "vault", name: decl.vault, provider };
|
|
7830
|
-
if (nodes.has(addressKey(vaultAddr))) {
|
|
7831
|
-
addEdge(agentAddr, vaultAddr);
|
|
7832
|
-
}
|
|
7833
|
-
}
|
|
7834
|
-
if (decl.files) {
|
|
7835
|
-
for (const fileName of decl.files) {
|
|
7836
|
-
const fileAddr = { type: "file", name: fileName, provider };
|
|
7837
|
-
if (nodes.has(addressKey(fileAddr))) addEdge(agentAddr, fileAddr);
|
|
7838
|
-
}
|
|
7839
|
-
}
|
|
7840
|
-
if (decl.memory_stores) {
|
|
7841
|
-
for (const msName of decl.memory_stores) {
|
|
7842
|
-
const msAddr = {
|
|
7843
|
-
type: "memory_store",
|
|
7844
|
-
name: msName,
|
|
7845
|
-
provider
|
|
7846
|
-
};
|
|
7847
|
-
if (nodes.has(addressKey(msAddr))) {
|
|
7848
|
-
addEdge(agentAddr, msAddr);
|
|
7849
|
-
}
|
|
7850
|
-
}
|
|
8183
|
+
if (config.memory_stores && !isSupported(caps, "memory_store")) {
|
|
8184
|
+
for (const [name, decl] of Object.entries(config.memory_stores)) {
|
|
8185
|
+
if (!decl.provider || decl.provider === providerName) {
|
|
8186
|
+
diagnostics.error(
|
|
8187
|
+
`${providerName}.memory_store.unsupported`,
|
|
8188
|
+
`${caps.memory_store.reason}. ${caps.memory_store.remediation ?? ""}`.trim(),
|
|
8189
|
+
{ type: "memory_store", name, provider: providerName }
|
|
8190
|
+
);
|
|
7851
8191
|
}
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8194
|
+
if (config.agents && !isSupported(caps, "multiagent")) {
|
|
8195
|
+
for (const [name, agent] of Object.entries(config.agents)) {
|
|
8196
|
+
if (agent.multiagent) {
|
|
8197
|
+
if (!agent.provider || agent.provider === providerName) {
|
|
8198
|
+
diagnostics.error(
|
|
8199
|
+
`${providerName}.multiagent.unsupported`,
|
|
8200
|
+
`${caps.multiagent.reason}. ${caps.multiagent.remediation ?? ""}`.trim(),
|
|
8201
|
+
{ type: "agent", name, provider: providerName }
|
|
8202
|
+
);
|
|
7858
8203
|
}
|
|
7859
8204
|
}
|
|
7860
8205
|
}
|
|
7861
8206
|
}
|
|
7862
|
-
if (config.deployments) {
|
|
7863
|
-
for (const name of Object.
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
if (decl.vaults) {
|
|
7877
|
-
for (const vName of decl.vaults) {
|
|
7878
|
-
const vAddr = { type: "vault", name: vName, provider };
|
|
7879
|
-
if (nodes.has(addressKey(vAddr))) addEdge(depAddr, vAddr);
|
|
7880
|
-
}
|
|
8207
|
+
if (config.deployments && caps.deployment.tier === "emulated") {
|
|
8208
|
+
for (const [name, dep] of Object.entries(config.deployments)) {
|
|
8209
|
+
if (dep.provider && dep.provider !== providerName) continue;
|
|
8210
|
+
const addr = {
|
|
8211
|
+
type: "deployment",
|
|
8212
|
+
name,
|
|
8213
|
+
provider: providerName
|
|
8214
|
+
};
|
|
8215
|
+
if (dep.schedule) {
|
|
8216
|
+
diagnostics.warning(
|
|
8217
|
+
`${providerName}.deployment.schedule_unsupported`,
|
|
8218
|
+
"Schedules are not enforced server-side on this provider; trigger runs via external cron/CI.",
|
|
8219
|
+
addr
|
|
8220
|
+
);
|
|
7881
8221
|
}
|
|
7882
|
-
if (
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
8222
|
+
if (dep.initial_events?.some((e) => e.type === "user.define_outcome")) {
|
|
8223
|
+
diagnostics.warning(
|
|
8224
|
+
`${providerName}.deployment.define_outcome_unsupported`,
|
|
8225
|
+
"Outcome rubrics (user.define_outcome) are not enforced server-side on this provider; the run executes without rubric grading.",
|
|
8226
|
+
addr
|
|
8227
|
+
);
|
|
7887
8228
|
}
|
|
7888
|
-
if (
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
}
|
|
8229
|
+
if (dep.resources?.some((r) => r.type === "github_repository")) {
|
|
8230
|
+
diagnostics.warning(
|
|
8231
|
+
`${providerName}.deployment.github_repository_unsupported`,
|
|
8232
|
+
"github_repository resources are not provisioned on this provider; clone the repository inside the session instead.",
|
|
8233
|
+
addr
|
|
8234
|
+
);
|
|
7895
8235
|
}
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
const channelAddr = { type: "channel", name, provider };
|
|
7903
|
-
addNode(channelAddr);
|
|
7904
|
-
if (decl.mode === "pairing" || !decl.agent) continue;
|
|
7905
|
-
const agentDecl = config.agents?.[decl.agent];
|
|
7906
|
-
const agentType = agentDecl ? resolveAgentMaterialization(provider, agentDecl).resourceType : "agent";
|
|
7907
|
-
const agentAddr = { type: agentType, name: decl.agent, provider };
|
|
7908
|
-
if (nodes.has(addressKey(agentAddr))) addEdge(channelAddr, agentAddr);
|
|
7909
|
-
const identityName = decl.identity ?? config.defaults?.identity;
|
|
7910
|
-
if (identityName) {
|
|
7911
|
-
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7912
|
-
if (nodes.has(addressKey(identityAddr))) addEdge(channelAddr, identityAddr);
|
|
8236
|
+
if (dep.resources?.some((r) => r.type === "memory_store" && (r.access === "read_only" || r.instructions))) {
|
|
8237
|
+
diagnostics.warning(
|
|
8238
|
+
`${providerName}.deployment.memory_store_options_unsupported`,
|
|
8239
|
+
"Per-resource memory_store access/instructions are not honored on this provider; the store is attached with default access.",
|
|
8240
|
+
addr
|
|
8241
|
+
);
|
|
7913
8242
|
}
|
|
7914
8243
|
}
|
|
7915
8244
|
}
|
|
7916
8245
|
}
|
|
7917
|
-
return { nodes, edges };
|
|
7918
|
-
}
|
|
7919
|
-
function topologicalSort(graph) {
|
|
7920
|
-
const visited = /* @__PURE__ */ new Set();
|
|
7921
|
-
const sorted = [];
|
|
7922
|
-
const visiting = /* @__PURE__ */ new Set();
|
|
7923
|
-
function visit(key) {
|
|
7924
|
-
if (visited.has(key)) return;
|
|
7925
|
-
if (visiting.has(key)) {
|
|
7926
|
-
throw new UserError(`Circular dependency detected involving: ${key}`);
|
|
7927
|
-
}
|
|
7928
|
-
visiting.add(key);
|
|
7929
|
-
const deps = graph.edges.get(key) ?? /* @__PURE__ */ new Set();
|
|
7930
|
-
for (const dep of deps) {
|
|
7931
|
-
visit(dep);
|
|
7932
|
-
}
|
|
7933
|
-
visiting.delete(key);
|
|
7934
|
-
visited.add(key);
|
|
7935
|
-
sorted.push(graph.nodes.get(key));
|
|
7936
|
-
}
|
|
7937
|
-
for (const key of graph.nodes.keys()) {
|
|
7938
|
-
visit(key);
|
|
7939
|
-
}
|
|
7940
|
-
return sorted;
|
|
7941
8246
|
}
|
|
7942
8247
|
|
|
7943
8248
|
// src/internal/planner/planner.ts
|
|
7944
8249
|
async function buildPlan(config, state, options = {}) {
|
|
8250
|
+
const scopedConfig = options.resourceAddresses ? selectProjectConfig(config, options.resourceAddresses) : config;
|
|
8251
|
+
const resourceKeys = options.resourceAddresses ? new Set(options.resourceAddresses.map(addressKey)) : void 0;
|
|
8252
|
+
const scopedState = resourceKeys ? { ...state, resources: state.resources.filter((resource) => resourceKeys.has(addressKey(resource.address))) } : state;
|
|
7945
8253
|
const diagnostics = new DiagnosticCollector();
|
|
7946
8254
|
const actions = [];
|
|
7947
|
-
const targetProviders = options.providers ?? resolveTargetProviders(
|
|
7948
|
-
collectReferenceDiagnostics(
|
|
7949
|
-
collectProviderCapabilities(
|
|
7950
|
-
const graph = buildDependencyGraph(
|
|
8255
|
+
const targetProviders = options.providers ?? resolveTargetProviders(scopedConfig);
|
|
8256
|
+
collectReferenceDiagnostics(scopedConfig, diagnostics);
|
|
8257
|
+
collectProviderCapabilities(scopedConfig, targetProviders, diagnostics);
|
|
8258
|
+
const graph = buildDependencyGraph(scopedConfig, targetProviders);
|
|
7951
8259
|
const sorted = topologicalSort(graph);
|
|
7952
8260
|
const stateIndex = /* @__PURE__ */ new Map();
|
|
7953
|
-
for (const res of
|
|
8261
|
+
for (const res of scopedState.resources) {
|
|
7954
8262
|
stateIndex.set(addressKey(res.address), res);
|
|
7955
8263
|
}
|
|
7956
8264
|
const remoteIdLookup = /* @__PURE__ */ new Map();
|
|
7957
|
-
for (const res of
|
|
8265
|
+
for (const res of scopedState.resources) {
|
|
7958
8266
|
remoteIdLookup.set(addressKey(res.address), res);
|
|
7959
8267
|
}
|
|
7960
8268
|
const hashStateLookup = { getResource: (addr) => remoteIdLookup.get(addressKey(addr)) };
|
|
@@ -8098,9 +8406,53 @@ async function buildPlan(config, state, options = {}) {
|
|
|
8098
8406
|
dependencies: replacement ? [replacement] : []
|
|
8099
8407
|
});
|
|
8100
8408
|
}
|
|
8101
|
-
coalesceChannelRenames(actions,
|
|
8409
|
+
coalesceChannelRenames(actions, scopedConfig, scopedState);
|
|
8102
8410
|
return { actions, diagnostics: diagnostics.getAll() };
|
|
8103
8411
|
}
|
|
8412
|
+
function selectProjectConfig(config, addresses) {
|
|
8413
|
+
const providers = new Set(addresses.map((address) => address.provider));
|
|
8414
|
+
const namesByType = /* @__PURE__ */ new Map();
|
|
8415
|
+
for (const address of addresses) {
|
|
8416
|
+
const names = namesByType.get(address.type) ?? /* @__PURE__ */ new Set();
|
|
8417
|
+
names.add(address.name);
|
|
8418
|
+
namesByType.set(address.type, names);
|
|
8419
|
+
}
|
|
8420
|
+
const pick = (record, names) => {
|
|
8421
|
+
if (!record || !names?.size) return void 0;
|
|
8422
|
+
const selected = Object.fromEntries(Object.entries(record).filter(([name]) => names.has(name)));
|
|
8423
|
+
return Object.keys(selected).length > 0 ? selected : void 0;
|
|
8424
|
+
};
|
|
8425
|
+
const agentNames = /* @__PURE__ */ new Set([...namesByType.get("agent") ?? [], ...namesByType.get("template") ?? []]);
|
|
8426
|
+
const selectedAgents = pick(config.agents, agentNames);
|
|
8427
|
+
const tunnelNames = /* @__PURE__ */ new Set();
|
|
8428
|
+
for (const agent of Object.values(selectedAgents ?? {})) {
|
|
8429
|
+
if (agent.tunnel) tunnelNames.add(agent.tunnel);
|
|
8430
|
+
}
|
|
8431
|
+
for (const deployment of Object.values(pick(config.deployments, namesByType.get("deployment")) ?? {})) {
|
|
8432
|
+
if (deployment.tunnel) tunnelNames.add(deployment.tunnel);
|
|
8433
|
+
}
|
|
8434
|
+
const identityNames = namesByType.get("identity");
|
|
8435
|
+
const selectedProviders = Object.fromEntries(
|
|
8436
|
+
Object.entries(config.providers).filter(([providerName]) => providers.has(providerName))
|
|
8437
|
+
);
|
|
8438
|
+
const defaultProvider = providers.size === 1 ? [...providers][0] : config.defaults?.provider;
|
|
8439
|
+
const defaultIdentity = config.defaults?.identity && identityNames?.has(config.defaults.identity) ? config.defaults.identity : void 0;
|
|
8440
|
+
return {
|
|
8441
|
+
...config,
|
|
8442
|
+
providers: selectedProviders,
|
|
8443
|
+
defaults: defaultProvider || defaultIdentity ? { provider: defaultProvider, identity: defaultIdentity } : void 0,
|
|
8444
|
+
environments: pick(config.environments, namesByType.get("environment")),
|
|
8445
|
+
tunnels: pick(config.tunnels, tunnelNames),
|
|
8446
|
+
vaults: pick(config.vaults, namesByType.get("vault")),
|
|
8447
|
+
memory_stores: pick(config.memory_stores, namesByType.get("memory_store")),
|
|
8448
|
+
skills: pick(config.skills, namesByType.get("skill")),
|
|
8449
|
+
files: pick(config.files, namesByType.get("file")),
|
|
8450
|
+
identities: pick(config.identities, identityNames),
|
|
8451
|
+
agents: selectedAgents,
|
|
8452
|
+
channels: pick(config.channels, namesByType.get("channel")),
|
|
8453
|
+
deployments: pick(config.deployments, namesByType.get("deployment"))
|
|
8454
|
+
};
|
|
8455
|
+
}
|
|
8104
8456
|
function coalesceChannelRenames(actions, config, state) {
|
|
8105
8457
|
const creates = actions.filter((action) => action.action === "create" && action.address.type === "channel");
|
|
8106
8458
|
const deletes = actions.filter((action) => action.action === "delete" && action.address.type === "channel");
|
|
@@ -8180,6 +8532,9 @@ async function refreshState(state, providers, options = {}) {
|
|
|
8180
8532
|
const errors = [];
|
|
8181
8533
|
let dirty = false;
|
|
8182
8534
|
for (const res of resources) {
|
|
8535
|
+
if (options.resourceKeys && !options.resourceKeys.has(addressKey(res.address))) {
|
|
8536
|
+
continue;
|
|
8537
|
+
}
|
|
8183
8538
|
if (options.targetProviders && !options.targetProviders.includes(res.address.provider)) {
|
|
8184
8539
|
continue;
|
|
8185
8540
|
}
|
|
@@ -8293,12 +8648,19 @@ async function refreshState(state, providers, options = {}) {
|
|
|
8293
8648
|
}
|
|
8294
8649
|
|
|
8295
8650
|
// src/internal/core/resource-runtime.ts
|
|
8651
|
+
async function planProjectWithStateBackend(input, options = {}) {
|
|
8652
|
+
return readProjectRuntime(input, (ctx) => planProjectContext(ctx, options));
|
|
8653
|
+
}
|
|
8296
8654
|
async function syncProjectResourcesWithStateBackend(input, options = {}) {
|
|
8297
8655
|
return writeProjectRuntime(input, async (ctx) => {
|
|
8298
8656
|
const planned = await planProjectContext(ctx, options);
|
|
8299
8657
|
if (options.refreshOnly) {
|
|
8300
8658
|
return { planned };
|
|
8301
8659
|
}
|
|
8660
|
+
if (options.mode === "create-only") {
|
|
8661
|
+
const errorDiagnostic = planned.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
8662
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
8663
|
+
}
|
|
8302
8664
|
return {
|
|
8303
8665
|
planned,
|
|
8304
8666
|
execution: await executePlannedProject(planned, {
|
|
@@ -8366,26 +8728,103 @@ async function importResource(ctx, address, remoteId, options = {}) {
|
|
|
8366
8728
|
return resource;
|
|
8367
8729
|
}
|
|
8368
8730
|
async function planProjectContext(ctx, options = {}) {
|
|
8369
|
-
|
|
8731
|
+
if (options.mode === "create-only" && !options.scope) {
|
|
8732
|
+
throw new UserError("Resource create-only mode requires an explicit resource scope.");
|
|
8733
|
+
}
|
|
8734
|
+
let targetProviders = resolveTargetProviders2(options.provider);
|
|
8735
|
+
if (!targetProviders && options.scope) {
|
|
8736
|
+
targetProviders = [...new Set(options.scope.roots.map((root) => root.provider))];
|
|
8737
|
+
}
|
|
8738
|
+
const selectedAddresses = options.scope ? resolvePlanScope(ctx, targetProviders ?? [], options.scope) : void 0;
|
|
8739
|
+
const resourceKeys = selectedAddresses ? new Set(selectedAddresses.map(addressKey)) : void 0;
|
|
8370
8740
|
const refreshResult = options.refresh !== false && ctx.state.listResources().length > 0 ? await refreshState(ctx.state, ctx.providers, {
|
|
8371
8741
|
targetProviders,
|
|
8742
|
+
resourceKeys,
|
|
8372
8743
|
config: ctx.config,
|
|
8373
8744
|
quiet: options.quiet ?? true,
|
|
8374
8745
|
onFeedback: options.onFeedback
|
|
8375
8746
|
}) : void 0;
|
|
8376
|
-
|
|
8747
|
+
let plan = await buildPlan(ctx.config, ctx.state.getStateFile(), {
|
|
8377
8748
|
providers: targetProviders,
|
|
8378
|
-
configPath: ctx.configPath
|
|
8749
|
+
configPath: ctx.configPath,
|
|
8750
|
+
resourceAddresses: selectedAddresses
|
|
8379
8751
|
});
|
|
8752
|
+
if (options.mode === "create-only" && options.scope) {
|
|
8753
|
+
plan = enforceCreateOnlyPlan(plan, options.scope, toResourceRefreshResult(refreshResult));
|
|
8754
|
+
}
|
|
8380
8755
|
return {
|
|
8381
8756
|
executionContext: ctx,
|
|
8382
8757
|
plan,
|
|
8383
8758
|
refreshResult: toResourceRefreshResult(refreshResult),
|
|
8384
8759
|
targetProviders,
|
|
8385
|
-
destructiveActions: selectDestructive(plan.actions)
|
|
8760
|
+
destructiveActions: selectDestructive(plan.actions),
|
|
8761
|
+
selectedAddresses,
|
|
8762
|
+
mode: options.mode
|
|
8763
|
+
};
|
|
8764
|
+
}
|
|
8765
|
+
function enforceCreateOnlyPlan(plan, scope, refreshResult) {
|
|
8766
|
+
const reasons = [];
|
|
8767
|
+
const rootKeys = new Set(scope.roots.map(addressKey));
|
|
8768
|
+
const refreshError = refreshResult?.errors[0];
|
|
8769
|
+
if (refreshError) {
|
|
8770
|
+
reasons.push(
|
|
8771
|
+
`Cannot verify scoped dependencies because refresh failed for ${addressKey(refreshError.resource.address)}: ${refreshError.error}`
|
|
8772
|
+
);
|
|
8773
|
+
}
|
|
8774
|
+
for (const root of scope.roots) {
|
|
8775
|
+
const rootKey = addressKey(root);
|
|
8776
|
+
const rootAction = plan.actions.find((action) => addressKey(action.address) === rootKey);
|
|
8777
|
+
if (!rootAction) {
|
|
8778
|
+
reasons.push(`Scoped plan did not contain target resource ${rootKey}.`);
|
|
8779
|
+
} else if (rootAction.action !== "create") {
|
|
8780
|
+
reasons.push(`Target resource ${rootKey} must be new, but the scoped plan requires '${rootAction.action}'.`);
|
|
8781
|
+
}
|
|
8782
|
+
}
|
|
8783
|
+
const dependencyChanges = plan.actions.filter(
|
|
8784
|
+
(action) => !rootKeys.has(addressKey(action.address)) && action.action !== "no-op"
|
|
8785
|
+
);
|
|
8786
|
+
if (dependencyChanges.length > 0) {
|
|
8787
|
+
const labels = dependencyChanges.map((action) => `${addressKey(action.address)} (${action.action})`).join(", ");
|
|
8788
|
+
reasons.push(`Create-only requires every scoped dependency to be up-to-date. Reconcile first: ${labels}.`);
|
|
8789
|
+
}
|
|
8790
|
+
if (reasons.length === 0) return plan;
|
|
8791
|
+
return {
|
|
8792
|
+
...plan,
|
|
8793
|
+
diagnostics: [
|
|
8794
|
+
...plan.diagnostics,
|
|
8795
|
+
{
|
|
8796
|
+
severity: "error",
|
|
8797
|
+
code: "resource.create_only.blocked",
|
|
8798
|
+
message: reasons.join(" "),
|
|
8799
|
+
resource: scope.roots[0]
|
|
8800
|
+
}
|
|
8801
|
+
]
|
|
8386
8802
|
};
|
|
8387
8803
|
}
|
|
8804
|
+
function resolvePlanScope(ctx, targetProviders, scope) {
|
|
8805
|
+
if (scope.roots.length === 0) {
|
|
8806
|
+
throw new UserError("Resource plan scope requires at least one root address.");
|
|
8807
|
+
}
|
|
8808
|
+
for (const root of scope.roots) {
|
|
8809
|
+
if (!targetProviders.includes(root.provider)) {
|
|
8810
|
+
throw new UserError(
|
|
8811
|
+
`Scoped resource ${addressKey(root)} is outside the selected provider set: ${targetProviders.join(", ")}.`
|
|
8812
|
+
);
|
|
8813
|
+
}
|
|
8814
|
+
}
|
|
8815
|
+
const graph = buildDependencyGraph(ctx.config, targetProviders);
|
|
8816
|
+
for (const root of scope.roots) {
|
|
8817
|
+
if (!graph.nodes.has(addressKey(root))) {
|
|
8818
|
+
throw new UserError(`Scoped resource ${addressKey(root)} is not declared in the project config.`);
|
|
8819
|
+
}
|
|
8820
|
+
}
|
|
8821
|
+
return scope.includeDependencies === false ? [...scope.roots] : collectDependencyClosure(graph, scope.roots);
|
|
8822
|
+
}
|
|
8388
8823
|
async function executePlannedProject(planned, options = {}) {
|
|
8824
|
+
if (planned.mode === "create-only") {
|
|
8825
|
+
const errorDiagnostic = planned.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
8826
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
8827
|
+
}
|
|
8389
8828
|
const decision = await decideDestructive(planned.destructiveActions, {
|
|
8390
8829
|
policy: options.policy,
|
|
8391
8830
|
confirm: options.confirm
|
|
@@ -8403,7 +8842,8 @@ async function executePlannedProject(planned, options = {}) {
|
|
|
8403
8842
|
configPath: ctx.configPath,
|
|
8404
8843
|
providers: ctx.providers,
|
|
8405
8844
|
state: ctx.state,
|
|
8406
|
-
onFeedback: options.onFeedback
|
|
8845
|
+
onFeedback: options.onFeedback,
|
|
8846
|
+
createOnly: planned.mode === "create-only"
|
|
8407
8847
|
},
|
|
8408
8848
|
{ concurrency: options.concurrency }
|
|
8409
8849
|
);
|
|
@@ -8428,13 +8868,6 @@ async function decideDestructive(destructiveActions, options = {}) {
|
|
|
8428
8868
|
return "blocked";
|
|
8429
8869
|
}
|
|
8430
8870
|
}
|
|
8431
|
-
function replaceResourcePlan(planned, plan) {
|
|
8432
|
-
return {
|
|
8433
|
-
...planned,
|
|
8434
|
-
plan,
|
|
8435
|
-
destructiveActions: selectDestructive(plan.actions)
|
|
8436
|
-
};
|
|
8437
|
-
}
|
|
8438
8871
|
function toResourceRefreshResult(result) {
|
|
8439
8872
|
if (!result) return void 0;
|
|
8440
8873
|
return {
|
|
@@ -8783,6 +9216,369 @@ function buildDeploymentContext(ctx, name, provider) {
|
|
|
8783
9216
|
};
|
|
8784
9217
|
}
|
|
8785
9218
|
|
|
9219
|
+
// src/internal/core/managed-api-runtime.ts
|
|
9220
|
+
function resolveAdapter(ctx, provider) {
|
|
9221
|
+
if (provider) return getRuntimeProvider(ctx, provider);
|
|
9222
|
+
const configured = Array.from(ctx.providers.keys());
|
|
9223
|
+
if (configured.length === 1) return getRuntimeProvider(ctx, configured[0]);
|
|
9224
|
+
throw new UserError("Multiple providers configured. Use --provider to specify one.");
|
|
9225
|
+
}
|
|
9226
|
+
function requiredMethod(value, provider, operation) {
|
|
9227
|
+
if (value) return value;
|
|
9228
|
+
throw new UserError(`Provider '${provider}' does not support ${operation}.`);
|
|
9229
|
+
}
|
|
9230
|
+
async function listRemoteAgents(ctx, options = {}) {
|
|
9231
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9232
|
+
const method2 = requiredMethod(adapter2.listAgentResources, adapter2.name, "agent listing");
|
|
9233
|
+
return method2.call(adapter2, options);
|
|
9234
|
+
}
|
|
9235
|
+
async function getRemoteAgent(ctx, id, options = {}) {
|
|
9236
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9237
|
+
const method2 = requiredMethod(adapter2.getRemoteAgent, adapter2.name, "agent lookup");
|
|
9238
|
+
return method2.call(adapter2, id, options.version);
|
|
9239
|
+
}
|
|
9240
|
+
async function listRemoteAgentVersions(ctx, id, options = {}) {
|
|
9241
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9242
|
+
const method2 = requiredMethod(adapter2.listAgentVersions, adapter2.name, "agent version listing");
|
|
9243
|
+
return method2.call(adapter2, id, options);
|
|
9244
|
+
}
|
|
9245
|
+
async function listRemoteEnvironments(ctx, options = {}) {
|
|
9246
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9247
|
+
const method2 = requiredMethod(adapter2.listEnvironmentResources, adapter2.name, "environment listing");
|
|
9248
|
+
return method2.call(adapter2, options);
|
|
9249
|
+
}
|
|
9250
|
+
async function getRemoteEnvironment(ctx, id, options = {}) {
|
|
9251
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9252
|
+
const method2 = requiredMethod(adapter2.getRemoteEnvironment, adapter2.name, "environment lookup");
|
|
9253
|
+
return method2.call(adapter2, id);
|
|
9254
|
+
}
|
|
9255
|
+
async function listRemoteVaults(ctx, options = {}) {
|
|
9256
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9257
|
+
const method2 = requiredMethod(adapter2.listVaultResources, adapter2.name, "vault listing");
|
|
9258
|
+
return method2.call(adapter2, options);
|
|
9259
|
+
}
|
|
9260
|
+
async function getRemoteVault(ctx, id, options = {}) {
|
|
9261
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9262
|
+
const method2 = requiredMethod(adapter2.getRemoteVault, adapter2.name, "vault lookup");
|
|
9263
|
+
return method2.call(adapter2, id);
|
|
9264
|
+
}
|
|
9265
|
+
async function listRemoteSkills(ctx, options = {}) {
|
|
9266
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9267
|
+
const method2 = requiredMethod(adapter2.listSkillResources, adapter2.name, "skill listing");
|
|
9268
|
+
return method2.call(adapter2, options);
|
|
9269
|
+
}
|
|
9270
|
+
async function getRemoteSkill(ctx, id, options = {}) {
|
|
9271
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9272
|
+
const method2 = requiredMethod(adapter2.getSkillInfo, adapter2.name, "skill lookup");
|
|
9273
|
+
return method2.call(adapter2, id);
|
|
9274
|
+
}
|
|
9275
|
+
async function listRemoteSkillVersions(ctx, id, options = {}) {
|
|
9276
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9277
|
+
const method2 = requiredMethod(adapter2.listSkillVersions, adapter2.name, "skill version listing");
|
|
9278
|
+
return method2.call(adapter2, id, options);
|
|
9279
|
+
}
|
|
9280
|
+
async function getRemoteSkillVersion(ctx, id, version, options = {}) {
|
|
9281
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9282
|
+
const method2 = requiredMethod(adapter2.getSkillVersion, adapter2.name, "skill version lookup");
|
|
9283
|
+
return method2.call(adapter2, id, version);
|
|
9284
|
+
}
|
|
9285
|
+
async function getRemoteSkillDownloadInfo(ctx, id, version, options = {}) {
|
|
9286
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9287
|
+
const method2 = requiredMethod(adapter2.getSkillDownloadInfo, adapter2.name, "skill version download");
|
|
9288
|
+
return method2.call(adapter2, id, version);
|
|
9289
|
+
}
|
|
9290
|
+
async function downloadRemoteSkill(ctx, id, version, options = {}) {
|
|
9291
|
+
const info = await getRemoteSkillDownloadInfo(ctx, id, version, options);
|
|
9292
|
+
const response = await resolveFetch()(info.file_url, { method: "GET" });
|
|
9293
|
+
if (!response.ok) {
|
|
9294
|
+
throw new ApiError(response.status, await response.text(), "Skill download failed");
|
|
9295
|
+
}
|
|
9296
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
9297
|
+
}
|
|
9298
|
+
async function listRemoteFiles(ctx, options = {}) {
|
|
9299
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9300
|
+
const method2 = requiredMethod(adapter2.listFileResources, adapter2.name, "file listing");
|
|
9301
|
+
return method2.call(adapter2, options);
|
|
9302
|
+
}
|
|
9303
|
+
async function downloadRemoteFile(ctx, id, options = {}) {
|
|
9304
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9305
|
+
const method2 = requiredMethod(adapter2.downloadFileContent, adapter2.name, "file content download");
|
|
9306
|
+
return method2.call(adapter2, id);
|
|
9307
|
+
}
|
|
9308
|
+
async function updateRemoteSession(ctx, id, input, options = {}) {
|
|
9309
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9310
|
+
const method2 = requiredMethod(adapter2.updateSession, adapter2.name, "session update");
|
|
9311
|
+
return method2.call(adapter2, id, input);
|
|
9312
|
+
}
|
|
9313
|
+
async function archiveRemoteSession(ctx, id, options = {}) {
|
|
9314
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9315
|
+
const method2 = requiredMethod(adapter2.archiveSession, adapter2.name, "session archive");
|
|
9316
|
+
return method2.call(adapter2, id);
|
|
9317
|
+
}
|
|
9318
|
+
async function sendRemoteSessionEvents(ctx, id, events, options = {}) {
|
|
9319
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9320
|
+
const method2 = requiredMethod(adapter2.sendSessionEvents, adapter2.name, "generic session event sending");
|
|
9321
|
+
return method2.call(adapter2, id, events);
|
|
9322
|
+
}
|
|
9323
|
+
async function listRemoteDeployments(ctx, options = {}) {
|
|
9324
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9325
|
+
const method2 = requiredMethod(adapter2.listDeployments, adapter2.name, "deployment listing");
|
|
9326
|
+
return method2.call(adapter2, options);
|
|
9327
|
+
}
|
|
9328
|
+
async function getRemoteDeployment(ctx, id, options = {}) {
|
|
9329
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9330
|
+
const method2 = requiredMethod(adapter2.getDeploymentById, adapter2.name, "deployment lookup");
|
|
9331
|
+
return method2.call(adapter2, id);
|
|
9332
|
+
}
|
|
9333
|
+
async function runRemoteDeployment(ctx, id, options = {}) {
|
|
9334
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9335
|
+
const method2 = requiredMethod(adapter2.runDeploymentById, adapter2.name, "deployment run");
|
|
9336
|
+
return method2.call(adapter2, id);
|
|
9337
|
+
}
|
|
9338
|
+
async function setRemoteDeploymentPaused(ctx, id, paused, options = {}) {
|
|
9339
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9340
|
+
const method2 = paused ? adapter2.pauseDeploymentById : adapter2.unpauseDeploymentById;
|
|
9341
|
+
return requiredMethod(method2, adapter2.name, `${paused ? "pausing" : "unpausing"} deployments`).call(adapter2, id);
|
|
9342
|
+
}
|
|
9343
|
+
async function listRemoteDeploymentRuns(ctx, deploymentId, options = {}) {
|
|
9344
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9345
|
+
const method2 = requiredMethod(adapter2.listDeploymentRuns, adapter2.name, "deployment run listing");
|
|
9346
|
+
return method2.call(adapter2, deploymentId, options);
|
|
9347
|
+
}
|
|
9348
|
+
async function getRemoteDeploymentRun(ctx, runId, options = {}) {
|
|
9349
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9350
|
+
const method2 = requiredMethod(adapter2.getDeploymentRun, adapter2.name, "deployment run lookup");
|
|
9351
|
+
return method2.call(adapter2, runId);
|
|
9352
|
+
}
|
|
9353
|
+
var API_KEY = { supported: true, auth: "api_key" };
|
|
9354
|
+
var CLIENT_SEARCH = {
|
|
9355
|
+
supported: true,
|
|
9356
|
+
auth: "api_key",
|
|
9357
|
+
reason: "Client-side filtering over the corresponding list API."
|
|
9358
|
+
};
|
|
9359
|
+
var UNSUPPORTED_MODEL = {
|
|
9360
|
+
supported: false,
|
|
9361
|
+
auth: null,
|
|
9362
|
+
reason: "The public Managed Agents API does not expose a model catalog endpoint."
|
|
9363
|
+
};
|
|
9364
|
+
var UNSUPPORTED_THREAD = {
|
|
9365
|
+
supported: false,
|
|
9366
|
+
auth: null,
|
|
9367
|
+
reason: "Managed Agents exposes child-thread ids and lifecycle events through Session Events, but no independent Thread resource API."
|
|
9368
|
+
};
|
|
9369
|
+
var UNSUPPORTED_OAUTH = {
|
|
9370
|
+
supported: false,
|
|
9371
|
+
auth: null,
|
|
9372
|
+
reason: "The public Managed Agents data plane does not expose MCP OAuth login."
|
|
9373
|
+
};
|
|
9374
|
+
var BAILIAN_OPERATIONS = {
|
|
9375
|
+
"agent.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9376
|
+
"agent.list": API_KEY,
|
|
9377
|
+
"agent.get": API_KEY,
|
|
9378
|
+
"agent.search": CLIENT_SEARCH,
|
|
9379
|
+
"agent.versions": API_KEY,
|
|
9380
|
+
"environment.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9381
|
+
"environment.list": API_KEY,
|
|
9382
|
+
"environment.get": API_KEY,
|
|
9383
|
+
"environment.search": CLIENT_SEARCH,
|
|
9384
|
+
"skill.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9385
|
+
"skill.list": API_KEY,
|
|
9386
|
+
"skill.get": API_KEY,
|
|
9387
|
+
"skill.search": CLIENT_SEARCH,
|
|
9388
|
+
"skill.versions": API_KEY,
|
|
9389
|
+
"skill.download": API_KEY,
|
|
9390
|
+
"vault.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9391
|
+
"vault.credential.create": {
|
|
9392
|
+
...API_KEY,
|
|
9393
|
+
reason: "YAML declaration plus scoped Vault transaction; Bailian supports environment_variable credentials only."
|
|
9394
|
+
},
|
|
9395
|
+
"vault.list": API_KEY,
|
|
9396
|
+
"vault.get": API_KEY,
|
|
9397
|
+
"vault.search": CLIENT_SEARCH,
|
|
9398
|
+
"deployment.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9399
|
+
"deployment.list": API_KEY,
|
|
9400
|
+
"deployment.get": API_KEY,
|
|
9401
|
+
"deployment.search": { ...API_KEY, reason: "Maps to the server-side keyword parameter." },
|
|
9402
|
+
"deployment.runs.list": API_KEY,
|
|
9403
|
+
"deployment.runs.get": API_KEY,
|
|
9404
|
+
"deployment.run": API_KEY,
|
|
9405
|
+
"deployment.pause": API_KEY,
|
|
9406
|
+
"deployment.unpause": API_KEY,
|
|
9407
|
+
"session.create": API_KEY,
|
|
9408
|
+
"session.list": API_KEY,
|
|
9409
|
+
"session.get": API_KEY,
|
|
9410
|
+
"session.search": CLIENT_SEARCH,
|
|
9411
|
+
"session.update": API_KEY,
|
|
9412
|
+
"session.archive": API_KEY,
|
|
9413
|
+
"session.delete": API_KEY,
|
|
9414
|
+
"session.run": { ...API_KEY, reason: "Client composition of session create and event send/stream." },
|
|
9415
|
+
"session.event.send": API_KEY,
|
|
9416
|
+
"session.event.list": API_KEY,
|
|
9417
|
+
"session.event.stream": API_KEY,
|
|
9418
|
+
"session.debug": { ...API_KEY, reason: "Client-side aggregation of supported read APIs." },
|
|
9419
|
+
"session.export": { ...API_KEY, reason: "Client-side export of supported read APIs." },
|
|
9420
|
+
"file.upload": API_KEY,
|
|
9421
|
+
"file.list": API_KEY,
|
|
9422
|
+
"file.get": API_KEY,
|
|
9423
|
+
"file.search": CLIENT_SEARCH,
|
|
9424
|
+
"file.download": API_KEY,
|
|
9425
|
+
"file.delete": API_KEY,
|
|
9426
|
+
"model.list": UNSUPPORTED_MODEL,
|
|
9427
|
+
"model.search": UNSUPPORTED_MODEL,
|
|
9428
|
+
"session_thread.list": UNSUPPORTED_THREAD,
|
|
9429
|
+
"session_thread.get": UNSUPPORTED_THREAD,
|
|
9430
|
+
"session_thread.archive": UNSUPPORTED_THREAD,
|
|
9431
|
+
"session_thread.events": UNSUPPORTED_THREAD,
|
|
9432
|
+
"mcp.oauth_login": UNSUPPORTED_OAUTH
|
|
9433
|
+
};
|
|
9434
|
+
function getManagedAgentProviderCapabilities(provider) {
|
|
9435
|
+
if (provider === "bailian") {
|
|
9436
|
+
return { provider, operations: { ...BAILIAN_OPERATIONS } };
|
|
9437
|
+
}
|
|
9438
|
+
return {
|
|
9439
|
+
provider,
|
|
9440
|
+
operations: {
|
|
9441
|
+
"managed_agent.api": {
|
|
9442
|
+
supported: false,
|
|
9443
|
+
auth: null,
|
|
9444
|
+
reason: "The operation-level API command surface is currently implemented for Bailian only."
|
|
9445
|
+
}
|
|
9446
|
+
}
|
|
9447
|
+
};
|
|
9448
|
+
}
|
|
9449
|
+
|
|
9450
|
+
// src/internal/core/vault-credential-runtime.ts
|
|
9451
|
+
async function planVaultCredentialCreate(ctx, vaultName, credentialName, options = {}) {
|
|
9452
|
+
const prepared = await prepareVaultCredentialCreate(ctx, vaultName, credentialName, options);
|
|
9453
|
+
return {
|
|
9454
|
+
provider: prepared.provider,
|
|
9455
|
+
vault: vaultName,
|
|
9456
|
+
vaultRemoteId: prepared.vaultState.remote_id,
|
|
9457
|
+
credential: credentialName,
|
|
9458
|
+
remoteChecked: prepared.remoteChecked,
|
|
9459
|
+
reuseRemote: Boolean(prepared.remoteCredential),
|
|
9460
|
+
remoteCredentialId: prepared.remoteCredential?.id
|
|
9461
|
+
};
|
|
9462
|
+
}
|
|
9463
|
+
async function planVaultCredentialCreateWithStateBackend(input, vaultName, credentialName, options = {}) {
|
|
9464
|
+
return readProjectRuntime(input, (ctx) => planVaultCredentialCreate(ctx, vaultName, credentialName, options));
|
|
9465
|
+
}
|
|
9466
|
+
async function createVaultCredential(ctx, vaultName, credentialName, options = {}) {
|
|
9467
|
+
if (options.checkRemote === false) {
|
|
9468
|
+
throw new UserError("Vault Credential create requires the remote duplicate check.");
|
|
9469
|
+
}
|
|
9470
|
+
const prepared = await prepareVaultCredentialCreate(ctx, vaultName, credentialName, options);
|
|
9471
|
+
const remote = prepared.remoteCredential ?? await prepared.adapter.createCredential(prepared.vaultState.remote_id, prepared.credential);
|
|
9472
|
+
if (!remote.id) throw new UserError("Credential create returned no remote id.");
|
|
9473
|
+
const address = { type: "vault", name: vaultName, provider: prepared.provider };
|
|
9474
|
+
const desiredHash = await computeResourceHash(address, ctx.config, ctx.configPath, ctx.state);
|
|
9475
|
+
ctx.state.setResource({
|
|
9476
|
+
...prepared.vaultState,
|
|
9477
|
+
content_hash: desiredHash,
|
|
9478
|
+
desired_hash: desiredHash,
|
|
9479
|
+
drift_paths: [],
|
|
9480
|
+
drift_status: "unchecked"
|
|
9481
|
+
});
|
|
9482
|
+
await ctx.state.save();
|
|
9483
|
+
return {
|
|
9484
|
+
provider: prepared.provider,
|
|
9485
|
+
vault: vaultName,
|
|
9486
|
+
vaultRemoteId: prepared.vaultState.remote_id,
|
|
9487
|
+
credential: credentialName,
|
|
9488
|
+
remoteChecked: prepared.remoteChecked,
|
|
9489
|
+
credentialId: remote.id,
|
|
9490
|
+
reuseRemote: Boolean(prepared.remoteCredential),
|
|
9491
|
+
remoteCredentialId: prepared.remoteCredential?.id,
|
|
9492
|
+
adopted: Boolean(prepared.remoteCredential)
|
|
9493
|
+
};
|
|
9494
|
+
}
|
|
9495
|
+
async function createVaultCredentialWithStateBackend(input, vaultName, credentialName, options = {}) {
|
|
9496
|
+
return writeProjectRuntime(input, (ctx) => createVaultCredential(ctx, vaultName, credentialName, options));
|
|
9497
|
+
}
|
|
9498
|
+
async function prepareVaultCredentialCreate(ctx, vaultName, credentialName, options) {
|
|
9499
|
+
const vault = ctx.config.vaults?.[vaultName];
|
|
9500
|
+
if (!vault) throw new UserError(`Vault '${vaultName}' is not declared in the project config.`);
|
|
9501
|
+
const provider = resolveVaultProvider(ctx, vault.provider, options.provider);
|
|
9502
|
+
const credential = vault.credentials.at(-1);
|
|
9503
|
+
if (!credential || credential.name !== credentialName) {
|
|
9504
|
+
throw new UserError(`Credential '${credentialName}' must be the final newly appended entry in vault.${vaultName}.`);
|
|
9505
|
+
}
|
|
9506
|
+
if (vault.credentials.slice(0, -1).some((entry) => entry.name === credentialName)) {
|
|
9507
|
+
throw new UserError(`Vault '${vaultName}' already declares a credential named '${credentialName}'.`);
|
|
9508
|
+
}
|
|
9509
|
+
if (provider === "bailian" && credential.type !== "environment_variable") {
|
|
9510
|
+
throw new UserError(
|
|
9511
|
+
`Credential '${credentialName}' uses '${credential.type}', but Bailian only supports 'environment_variable' credentials.`
|
|
9512
|
+
);
|
|
9513
|
+
}
|
|
9514
|
+
const address = { type: "vault", name: vaultName, provider };
|
|
9515
|
+
const priorConfig = structuredClone(ctx.config);
|
|
9516
|
+
priorConfig.vaults[vaultName] = {
|
|
9517
|
+
...priorConfig.vaults[vaultName],
|
|
9518
|
+
credentials: priorConfig.vaults[vaultName].credentials.slice(0, -1)
|
|
9519
|
+
};
|
|
9520
|
+
const priorPlan = await planProjectContext(
|
|
9521
|
+
{ ...ctx, config: priorConfig },
|
|
9522
|
+
{
|
|
9523
|
+
provider,
|
|
9524
|
+
scope: { roots: [address] },
|
|
9525
|
+
refresh: options.refresh,
|
|
9526
|
+
quiet: options.quiet ?? true
|
|
9527
|
+
}
|
|
9528
|
+
);
|
|
9529
|
+
const refreshError = priorPlan.refreshResult?.errors[0];
|
|
9530
|
+
if (refreshError) {
|
|
9531
|
+
throw new UserError(`Cannot verify vault.${vaultName} because refresh failed: ${refreshError.error}`);
|
|
9532
|
+
}
|
|
9533
|
+
const errorDiagnostic = priorPlan.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
9534
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
9535
|
+
const vaultAction = priorPlan.plan.actions.find(
|
|
9536
|
+
(action) => action.address.type === "vault" && action.address.name === vaultName
|
|
9537
|
+
);
|
|
9538
|
+
if (vaultAction?.action !== "no-op") {
|
|
9539
|
+
throw new UserError(
|
|
9540
|
+
`vault.${vaultName} must be tracked and up-to-date before adding a credential; current action is '${vaultAction?.action ?? "missing"}'.`
|
|
9541
|
+
);
|
|
9542
|
+
}
|
|
9543
|
+
const vaultState = ctx.state.getResource(address);
|
|
9544
|
+
if (!vaultState?.remote_id) throw new UserError(`vault.${vaultName} has no tracked remote id.`);
|
|
9545
|
+
const adapter2 = getRuntimeProvider(ctx, provider);
|
|
9546
|
+
if (!adapter2.createCredential || !adapter2.listCredentials) {
|
|
9547
|
+
throw new UserError(`Provider '${provider}' does not support scoped Vault Credential create.`);
|
|
9548
|
+
}
|
|
9549
|
+
const remoteChecked = options.checkRemote !== false;
|
|
9550
|
+
const sameName = remoteChecked ? (await adapter2.listCredentials(vaultState.remote_id)).filter(
|
|
9551
|
+
(remoteCredential) => remoteCredential.display_name === credentialName
|
|
9552
|
+
) : [];
|
|
9553
|
+
const exact = sameName.find((remoteCredential) => credentialMatches(remoteCredential, credential));
|
|
9554
|
+
if (sameName.length > 0 && !exact) {
|
|
9555
|
+
throw new UserError(`Vault '${vaultName}' already has a different remote credential named '${credentialName}'.`);
|
|
9556
|
+
}
|
|
9557
|
+
return { provider, credential, vaultState, adapter: adapter2, remoteChecked, remoteCredential: exact };
|
|
9558
|
+
}
|
|
9559
|
+
function resolveVaultProvider(ctx, declaredProvider, requestedProvider) {
|
|
9560
|
+
if (requestedProvider && declaredProvider && requestedProvider !== declaredProvider) {
|
|
9561
|
+
throw new UserError(
|
|
9562
|
+
`Vault provider '${declaredProvider}' does not match requested provider '${requestedProvider}'.`
|
|
9563
|
+
);
|
|
9564
|
+
}
|
|
9565
|
+
const provider = requestedProvider ?? declaredProvider ?? ctx.config.defaults?.provider;
|
|
9566
|
+
if (provider && provider !== "all") return provider;
|
|
9567
|
+
const configured = [...ctx.providers.keys()];
|
|
9568
|
+
if (configured.length === 1) return configured[0];
|
|
9569
|
+
throw new UserError("Cannot infer one provider for Vault Credential create.");
|
|
9570
|
+
}
|
|
9571
|
+
function credentialMatches(remote, desired) {
|
|
9572
|
+
if (remote.auth_type !== desired.type || !metadataMatches(remote.metadata, desired.metadata)) return false;
|
|
9573
|
+
if (desired.type === "static_bearer") return remote.mcp_server_url === desired.mcp_server_url;
|
|
9574
|
+
return remote.secret_name === desired.secret_name && (remote.networking_type ?? "unrestricted") === (desired.networking?.type ?? "unrestricted");
|
|
9575
|
+
}
|
|
9576
|
+
function metadataMatches(remote, desired) {
|
|
9577
|
+
const remoteEntries = Object.entries(remote ?? {});
|
|
9578
|
+
const desiredEntries = Object.entries(desired ?? {});
|
|
9579
|
+
return remoteEntries.length === desiredEntries.length && desiredEntries.every(([key, value]) => remote?.[key] === value);
|
|
9580
|
+
}
|
|
9581
|
+
|
|
8786
9582
|
// src/internal/core/destroy-runtime.ts
|
|
8787
9583
|
var destroyOrder = {
|
|
8788
9584
|
deployment: 0,
|
|
@@ -8805,11 +9601,14 @@ function planDestroyProjectContext(ctx) {
|
|
|
8805
9601
|
for (const [agentName, agent] of Object.entries(ctx.config.agents ?? {})) {
|
|
8806
9602
|
if (!agent.default_memory_store || agent.delivery?.qoder?.type !== "forward") continue;
|
|
8807
9603
|
if (agent.provider && agent.provider !== "qoder") continue;
|
|
9604
|
+
const identityId = identityName ? ctx.state.getResource({ type: "identity", name: identityName, provider: "qoder" })?.remote_id ?? null : null;
|
|
9605
|
+
const templateId = ctx.state.getResource({ type: "template", name: agentName, provider: "qoder" })?.remote_id ?? null;
|
|
9606
|
+
if (!identityId && !templateId) continue;
|
|
8808
9607
|
defaultMemoryStores.push({
|
|
8809
9608
|
agentName,
|
|
8810
9609
|
provider: "qoder",
|
|
8811
|
-
identityId
|
|
8812
|
-
templateId
|
|
9610
|
+
identityId,
|
|
9611
|
+
templateId,
|
|
8813
9612
|
deleteOnDestroy: agent.default_memory_store.delete_on_destroy ?? false
|
|
8814
9613
|
});
|
|
8815
9614
|
}
|
|
@@ -9322,6 +10121,7 @@ function buildAgentDecl(base, input) {
|
|
|
9322
10121
|
});
|
|
9323
10122
|
const agent = {
|
|
9324
10123
|
...base ?? {},
|
|
10124
|
+
name: input.name ?? base?.name,
|
|
9325
10125
|
description: input.description ?? base?.description,
|
|
9326
10126
|
model,
|
|
9327
10127
|
instructions: input.instructions ?? base?.instructions ?? "",
|
|
@@ -9558,28 +10358,36 @@ async function listAgentsWithReadiness(ctx, options = {}) {
|
|
|
9558
10358
|
}
|
|
9559
10359
|
async function planAgentResources(ctx, agentId, options = {}) {
|
|
9560
10360
|
const agent = getAgent(ctx, agentId);
|
|
10361
|
+
const rootAddress = collectAgentAddresses(ctx.config, agent.agentName, agent.provider)[0];
|
|
9561
10362
|
const planned = await planProjectContext(ctx, {
|
|
9562
10363
|
provider: agent.provider,
|
|
10364
|
+
scope: { roots: [rootAddress] },
|
|
10365
|
+
mode: options.mode,
|
|
9563
10366
|
refresh: options.refresh,
|
|
9564
10367
|
quiet: options.quiet ?? true
|
|
9565
10368
|
});
|
|
9566
|
-
const actions =
|
|
10369
|
+
const actions = planned.plan.actions;
|
|
10370
|
+
const diagnostics = planned.plan.diagnostics;
|
|
9567
10371
|
return {
|
|
9568
10372
|
agentId,
|
|
9569
10373
|
provider: agent.provider,
|
|
9570
10374
|
actions,
|
|
9571
|
-
diagnostics
|
|
10375
|
+
diagnostics,
|
|
9572
10376
|
destructiveActions: selectDestructive(actions),
|
|
9573
10377
|
planned
|
|
9574
10378
|
};
|
|
9575
10379
|
}
|
|
10380
|
+
async function planAgentResourcesWithStateBackend(input, agentId, options = {}) {
|
|
10381
|
+
return readProjectRuntime(input, (ctx) => planAgentResources(ctx, agentId, options));
|
|
10382
|
+
}
|
|
9576
10383
|
async function syncAgentResources(ctx, agentId, options = {}) {
|
|
9577
10384
|
return runAgentSync(ctx, agentId, options);
|
|
9578
10385
|
}
|
|
9579
10386
|
async function runAgentSync(ctx, agentId, options) {
|
|
9580
10387
|
const fullPlan = await planAgentResources(ctx, agentId, {
|
|
9581
10388
|
refresh: options.refresh,
|
|
9582
|
-
quiet: options.quiet
|
|
10389
|
+
quiet: options.quiet,
|
|
10390
|
+
mode: options.mode
|
|
9583
10391
|
});
|
|
9584
10392
|
const actions = fullPlan.actions;
|
|
9585
10393
|
const destructiveActions = fullPlan.destructiveActions;
|
|
@@ -9613,11 +10421,7 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9613
10421
|
};
|
|
9614
10422
|
}
|
|
9615
10423
|
try {
|
|
9616
|
-
const
|
|
9617
|
-
diagnostics: fullPlan.diagnostics,
|
|
9618
|
-
actions: scopePlanActions(fullPlan.planned.plan, actions)
|
|
9619
|
-
};
|
|
9620
|
-
const execution = await executePlannedProject(replaceResourcePlan(fullPlan.planned, scopedPlan), {
|
|
10424
|
+
const execution = await executePlannedProject(fullPlan.planned, {
|
|
9621
10425
|
policy: "force"
|
|
9622
10426
|
});
|
|
9623
10427
|
const results = toAgentSyncResults(execution);
|
|
@@ -9721,29 +10525,6 @@ function getAgentReadinessFromPlan(ctx, agentId, plan) {
|
|
|
9721
10525
|
plannedActions: relevantActions
|
|
9722
10526
|
};
|
|
9723
10527
|
}
|
|
9724
|
-
function filterAgentActions(ctx, agent, plan) {
|
|
9725
|
-
const relevantKeys = agentAddressKeys(ctx, agent);
|
|
9726
|
-
return plan.actions.filter(
|
|
9727
|
-
(action) => relevantKeys.has(addressKey(action.address)) || action.dependencies.some((dependency) => relevantKeys.has(addressKey(dependency)))
|
|
9728
|
-
);
|
|
9729
|
-
}
|
|
9730
|
-
function filterAgentDiagnostics(ctx, agent, plan) {
|
|
9731
|
-
const relevantKeys = agentAddressKeys(ctx, agent);
|
|
9732
|
-
return plan.diagnostics.filter(
|
|
9733
|
-
(diagnostic) => !diagnostic.resource || relevantKeys.has(addressKey(diagnostic.resource))
|
|
9734
|
-
);
|
|
9735
|
-
}
|
|
9736
|
-
function agentAddressKeys(ctx, agent) {
|
|
9737
|
-
return new Set(collectAgentAddresses(ctx.config, agent.agentName, agent.provider).map(addressKey));
|
|
9738
|
-
}
|
|
9739
|
-
function scopePlanActions(fullPlan, agentActions) {
|
|
9740
|
-
const allowedKeys = new Set(agentActions.filter((action) => action.action !== "no-op").map(actionKey));
|
|
9741
|
-
return fullPlan.actions.filter((action) => action.action === "no-op" || allowedKeys.has(actionKey(action)));
|
|
9742
|
-
}
|
|
9743
|
-
function actionKey(action) {
|
|
9744
|
-
const address = action.address;
|
|
9745
|
-
return `${action.action}:${address.provider}:${address.type}:${address.name}`;
|
|
9746
|
-
}
|
|
9747
10528
|
function isNonBlockingAgentDrift(action) {
|
|
9748
10529
|
if (action.action === "no-op") return true;
|
|
9749
10530
|
return action.readinessImpact === "non_blocking";
|
|
@@ -9755,33 +10536,13 @@ function collectAgentAddresses(config, agentName, provider) {
|
|
|
9755
10536
|
}
|
|
9756
10537
|
const resolvedProvider = provider ?? resolveSessionProvider(agentName, config, void 0);
|
|
9757
10538
|
const materialization = resolveAgentMaterialization(resolvedProvider, agent);
|
|
9758
|
-
const
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
provider: resolvedProvider
|
|
9766
|
-
});
|
|
9767
|
-
}
|
|
9768
|
-
if (agent.vault) {
|
|
9769
|
-
addresses.push({ type: "vault", name: agent.vault, provider: resolvedProvider });
|
|
9770
|
-
}
|
|
9771
|
-
for (const name of agent.memory_stores ?? []) {
|
|
9772
|
-
addresses.push({ type: "memory_store", name, provider: resolvedProvider });
|
|
9773
|
-
}
|
|
9774
|
-
for (const skill of agent.skills ?? []) {
|
|
9775
|
-
if (typeof skill === "string") {
|
|
9776
|
-
addresses.push({ type: "skill", name: skill, provider: resolvedProvider });
|
|
9777
|
-
}
|
|
9778
|
-
}
|
|
9779
|
-
for (const subAgent of agent.multiagent?.agents ?? []) {
|
|
9780
|
-
const subDecl = config.agents?.[subAgent];
|
|
9781
|
-
const subType = subDecl ? resolveAgentMaterialization(resolvedProvider, subDecl).resourceType : "agent";
|
|
9782
|
-
addresses.push({ type: subType, name: subAgent, provider: resolvedProvider });
|
|
9783
|
-
}
|
|
9784
|
-
return addresses;
|
|
10539
|
+
const rootAddress = {
|
|
10540
|
+
type: materialization.resourceType,
|
|
10541
|
+
name: agentName,
|
|
10542
|
+
provider: resolvedProvider
|
|
10543
|
+
};
|
|
10544
|
+
const graph = buildDependencyGraph(config, [resolvedProvider]);
|
|
10545
|
+
return collectDependencyClosure(graph, [rootAddress]);
|
|
9785
10546
|
}
|
|
9786
10547
|
function toAgentDefinition(config, agentName, agent) {
|
|
9787
10548
|
return {
|
|
@@ -10008,12 +10769,20 @@ async function listSessionEvents(ctx, sessionId, options = {}) {
|
|
|
10008
10769
|
const listOptions = {};
|
|
10009
10770
|
if (options.limit !== void 0) listOptions.limit = options.limit;
|
|
10010
10771
|
if (options.order !== void 0) listOptions.order = options.order;
|
|
10772
|
+
if (options.types !== void 0) listOptions.types = options.types;
|
|
10773
|
+
if (options.created_at_gt !== void 0) listOptions.created_at_gt = options.created_at_gt;
|
|
10774
|
+
if (options.created_at_gte !== void 0) listOptions.created_at_gte = options.created_at_gte;
|
|
10775
|
+
if (options.created_at_lt !== void 0) listOptions.created_at_lt = options.created_at_lt;
|
|
10776
|
+
if (options.created_at_lte !== void 0) listOptions.created_at_lte = options.created_at_lte;
|
|
10011
10777
|
const pageToken = options.page_token ?? options.page;
|
|
10012
10778
|
if (pageToken !== void 0) listOptions.page_token = pageToken;
|
|
10013
|
-
|
|
10779
|
+
const result = await resolveDirectAdapter(ctx, options.provider).listSessionEvents(
|
|
10014
10780
|
sessionId,
|
|
10015
10781
|
Object.keys(listOptions).length > 0 ? listOptions : void 0
|
|
10016
10782
|
);
|
|
10783
|
+
if (!options.types || options.types.length === 0) return result;
|
|
10784
|
+
const allowedTypes = new Set(options.types);
|
|
10785
|
+
return { ...result, events: result.events.filter((event) => allowedTypes.has(event.raw_type)) };
|
|
10017
10786
|
}
|
|
10018
10787
|
async function uploadFile(ctx, content, filename, options = {}) {
|
|
10019
10788
|
const adapter2 = resolveDirectAdapter(ctx, options.provider);
|
|
@@ -10063,12 +10832,89 @@ async function deleteSkill(ctx, id, options = {}) {
|
|
|
10063
10832
|
await resolveDirectAdapter(ctx, options.provider).deleteSkill(id);
|
|
10064
10833
|
}
|
|
10065
10834
|
function streamSessionEvents(ctx, sessionId, options = {}) {
|
|
10835
|
+
const adapter2 = resolveDirectAdapter(ctx, options.provider);
|
|
10836
|
+
if (options.after_id && !adapter2.eventResume) {
|
|
10837
|
+
return replaySessionEventsByPolling(adapter2, sessionId, options.after_id);
|
|
10838
|
+
}
|
|
10066
10839
|
const streamOptions = {};
|
|
10067
10840
|
if (options.after_id !== void 0) streamOptions.after_id = options.after_id;
|
|
10068
|
-
return
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
);
|
|
10841
|
+
return adapter2.streamSessionEvents(sessionId, Object.keys(streamOptions).length > 0 ? streamOptions : void 0);
|
|
10842
|
+
}
|
|
10843
|
+
async function* replaySessionEventsByPolling(adapter2, sessionId, afterId) {
|
|
10844
|
+
const history = await listAllSessionEventHistory(adapter2, sessionId);
|
|
10845
|
+
const markerIndex = history.findIndex((event) => event.id === afterId);
|
|
10846
|
+
if (markerIndex < 0) {
|
|
10847
|
+
throw new UserError(`Session event '${afterId}' was not found; list session events and choose a valid event id.`);
|
|
10848
|
+
}
|
|
10849
|
+
const knownEventKeys = new Set(history.slice(0, markerIndex + 1).map(sessionEventKey));
|
|
10850
|
+
for (const event of history.slice(markerIndex + 1)) {
|
|
10851
|
+
const eventKey = sessionEventKey(event);
|
|
10852
|
+
if (knownEventKeys.has(eventKey)) continue;
|
|
10853
|
+
knownEventKeys.add(eventKey);
|
|
10854
|
+
yield event;
|
|
10855
|
+
if (event.type === "status" && isTerminalSessionStatus(event.status)) return;
|
|
10856
|
+
}
|
|
10857
|
+
while (true) {
|
|
10858
|
+
const newEvents = await listNewSessionEvents(adapter2, sessionId, knownEventKeys);
|
|
10859
|
+
for (const event of newEvents) {
|
|
10860
|
+
const eventKey = sessionEventKey(event);
|
|
10861
|
+
if (knownEventKeys.has(eventKey)) continue;
|
|
10862
|
+
knownEventKeys.add(eventKey);
|
|
10863
|
+
yield event;
|
|
10864
|
+
if (event.type === "status" && isTerminalSessionStatus(event.status)) return;
|
|
10865
|
+
}
|
|
10866
|
+
const session = await adapter2.getSession(sessionId);
|
|
10867
|
+
if (isTerminalSessionStatus(session.status)) return;
|
|
10868
|
+
await delay2(DEFAULT_POLL_INTERVAL_MS);
|
|
10869
|
+
}
|
|
10870
|
+
}
|
|
10871
|
+
async function listAllSessionEventHistory(adapter2, sessionId) {
|
|
10872
|
+
const events = [];
|
|
10873
|
+
const seenPageTokens = /* @__PURE__ */ new Set();
|
|
10874
|
+
let pageToken;
|
|
10875
|
+
while (true) {
|
|
10876
|
+
const result = await adapter2.listSessionEvents(sessionId, {
|
|
10877
|
+
limit: 100,
|
|
10878
|
+
order: "asc",
|
|
10879
|
+
...pageToken ? { page_token: pageToken } : {}
|
|
10880
|
+
});
|
|
10881
|
+
events.push(...result.events);
|
|
10882
|
+
if (!result.next_page) return events;
|
|
10883
|
+
if (seenPageTokens.has(result.next_page)) {
|
|
10884
|
+
throw new UserError("Session event pagination returned a repeated cursor.");
|
|
10885
|
+
}
|
|
10886
|
+
seenPageTokens.add(result.next_page);
|
|
10887
|
+
pageToken = result.next_page;
|
|
10888
|
+
}
|
|
10889
|
+
}
|
|
10890
|
+
async function listNewSessionEvents(adapter2, sessionId, knownEventKeys) {
|
|
10891
|
+
const descendingEvents = [];
|
|
10892
|
+
const seenPageTokens = /* @__PURE__ */ new Set();
|
|
10893
|
+
let pageToken;
|
|
10894
|
+
while (true) {
|
|
10895
|
+
const result = await adapter2.listSessionEvents(sessionId, {
|
|
10896
|
+
limit: 100,
|
|
10897
|
+
order: "desc",
|
|
10898
|
+
...pageToken ? { page_token: pageToken } : {}
|
|
10899
|
+
});
|
|
10900
|
+
let reachedKnownEvent = false;
|
|
10901
|
+
for (const event of result.events) {
|
|
10902
|
+
if (knownEventKeys.has(sessionEventKey(event))) {
|
|
10903
|
+
reachedKnownEvent = true;
|
|
10904
|
+
break;
|
|
10905
|
+
}
|
|
10906
|
+
descendingEvents.push(event);
|
|
10907
|
+
}
|
|
10908
|
+
if (reachedKnownEvent || !result.next_page) return descendingEvents.reverse();
|
|
10909
|
+
if (seenPageTokens.has(result.next_page)) {
|
|
10910
|
+
throw new UserError("Session event pagination returned a repeated cursor.");
|
|
10911
|
+
}
|
|
10912
|
+
seenPageTokens.add(result.next_page);
|
|
10913
|
+
pageToken = result.next_page;
|
|
10914
|
+
}
|
|
10915
|
+
}
|
|
10916
|
+
function sessionEventKey(event) {
|
|
10917
|
+
return event.id ?? `raw:${event.raw_type}:${JSON.stringify(event.raw)}`;
|
|
10072
10918
|
}
|
|
10073
10919
|
function resolveDirectAdapter(ctx, overrideProvider) {
|
|
10074
10920
|
if (overrideProvider) return getRuntimeProvider(ctx, overrideProvider);
|
|
@@ -10600,7 +11446,8 @@ var CloudAgentSchema = z6.object({
|
|
|
10600
11446
|
workspace_id: z6.string().optional(),
|
|
10601
11447
|
created_at: z6.string().optional(),
|
|
10602
11448
|
updated_at: z6.string().optional(),
|
|
10603
|
-
archived_at: z6.string().nullish()
|
|
11449
|
+
archived_at: z6.string().nullish(),
|
|
11450
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10604
11451
|
});
|
|
10605
11452
|
var ListCloudAgentsResponseSchema = z6.object({
|
|
10606
11453
|
agents: z6.array(CloudAgentSchema)
|
|
@@ -10617,7 +11464,8 @@ var CloudEnvironmentSchema = z6.object({
|
|
|
10617
11464
|
workspace_id: z6.string().optional(),
|
|
10618
11465
|
created_at: z6.string().optional(),
|
|
10619
11466
|
updated_at: z6.string().optional(),
|
|
10620
|
-
archived_at: z6.string().nullish()
|
|
11467
|
+
archived_at: z6.string().nullish(),
|
|
11468
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10621
11469
|
});
|
|
10622
11470
|
var ListCloudEnvironmentsResponseSchema = z6.object({
|
|
10623
11471
|
environments: z6.array(CloudEnvironmentSchema)
|
|
@@ -10629,7 +11477,8 @@ var CloudVaultSchema = z6.object({
|
|
|
10629
11477
|
type: z6.string().optional(),
|
|
10630
11478
|
created_at: z6.string().nullish(),
|
|
10631
11479
|
updated_at: z6.string().nullish(),
|
|
10632
|
-
archived_at: z6.string().nullish()
|
|
11480
|
+
archived_at: z6.string().nullish(),
|
|
11481
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10633
11482
|
});
|
|
10634
11483
|
var ListCloudVaultsResponseSchema = z6.object({
|
|
10635
11484
|
vaults: z6.array(CloudVaultSchema)
|
|
@@ -10809,6 +11658,7 @@ export {
|
|
|
10809
11658
|
applyProviderConfigToEnv,
|
|
10810
11659
|
archiveCloudAgent,
|
|
10811
11660
|
archiveMemoryStore,
|
|
11661
|
+
archiveRemoteSession,
|
|
10812
11662
|
areRuntimeCredentialsReady,
|
|
10813
11663
|
batchCreateMemories,
|
|
10814
11664
|
bootstrapRuntimeCredentials,
|
|
@@ -10822,6 +11672,8 @@ export {
|
|
|
10822
11672
|
createProjectRuntime,
|
|
10823
11673
|
createSessionForAgent,
|
|
10824
11674
|
createSkillFromFileId,
|
|
11675
|
+
createVaultCredential,
|
|
11676
|
+
createVaultCredentialWithStateBackend,
|
|
10825
11677
|
decideDestructive,
|
|
10826
11678
|
deleteCloudEnvironment,
|
|
10827
11679
|
deleteCloudVault,
|
|
@@ -10831,6 +11683,8 @@ export {
|
|
|
10831
11683
|
deleteSession,
|
|
10832
11684
|
deleteSkill,
|
|
10833
11685
|
destroyPlannedProjectResources,
|
|
11686
|
+
downloadRemoteFile,
|
|
11687
|
+
downloadRemoteSkill,
|
|
10834
11688
|
executePlannedProject,
|
|
10835
11689
|
extractSkillZipFiles,
|
|
10836
11690
|
getAgent,
|
|
@@ -10838,13 +11692,23 @@ export {
|
|
|
10838
11692
|
getDeploymentRuntimeProviderForContext,
|
|
10839
11693
|
getFileDownloadUrl,
|
|
10840
11694
|
getFileInfo,
|
|
11695
|
+
getManagedAgentProviderCapabilities,
|
|
10841
11696
|
getMemory,
|
|
10842
11697
|
getMemoryProviderCapabilities,
|
|
10843
11698
|
getMemoryStore,
|
|
10844
11699
|
getMemoryVersion,
|
|
11700
|
+
getRemoteAgent,
|
|
11701
|
+
getRemoteDeployment,
|
|
11702
|
+
getRemoteDeploymentRun,
|
|
11703
|
+
getRemoteEnvironment,
|
|
11704
|
+
getRemoteSkill,
|
|
11705
|
+
getRemoteSkillDownloadInfo,
|
|
11706
|
+
getRemoteSkillVersion,
|
|
11707
|
+
getRemoteVault,
|
|
10845
11708
|
getSession,
|
|
10846
11709
|
getSkillInfo,
|
|
10847
11710
|
importResource,
|
|
11711
|
+
inspectSkillSource,
|
|
10848
11712
|
isTerminalSessionStatus,
|
|
10849
11713
|
listAgentsWithReadiness,
|
|
10850
11714
|
listCloudAgents,
|
|
@@ -10857,7 +11721,16 @@ export {
|
|
|
10857
11721
|
listMemoryVersions,
|
|
10858
11722
|
listProviderModelsForContext,
|
|
10859
11723
|
listProviderNames,
|
|
11724
|
+
listRemoteAgentVersions,
|
|
11725
|
+
listRemoteAgents,
|
|
11726
|
+
listRemoteDeploymentRuns,
|
|
11727
|
+
listRemoteDeployments,
|
|
10860
11728
|
listRemoteDeploymentsForContext,
|
|
11729
|
+
listRemoteEnvironments,
|
|
11730
|
+
listRemoteFiles,
|
|
11731
|
+
listRemoteSkillVersions,
|
|
11732
|
+
listRemoteSkills,
|
|
11733
|
+
listRemoteVaults,
|
|
10861
11734
|
listSessionEvents,
|
|
10862
11735
|
listSessionSummaries,
|
|
10863
11736
|
listSkills,
|
|
@@ -10867,8 +11740,13 @@ export {
|
|
|
10867
11740
|
migrateConfig,
|
|
10868
11741
|
parseStateAddress,
|
|
10869
11742
|
pauseDeploymentForContext,
|
|
11743
|
+
planAgentResources,
|
|
11744
|
+
planAgentResourcesWithStateBackend,
|
|
10870
11745
|
planDestroyProjectContext,
|
|
10871
11746
|
planProjectContext,
|
|
11747
|
+
planProjectWithStateBackend,
|
|
11748
|
+
planVaultCredentialCreate,
|
|
11749
|
+
planVaultCredentialCreateWithStateBackend,
|
|
10872
11750
|
prepareInitialSessionPrompt,
|
|
10873
11751
|
preparePromptForProvider,
|
|
10874
11752
|
prependFileHint,
|
|
@@ -10884,9 +11762,12 @@ export {
|
|
|
10884
11762
|
resolveSyncProvider,
|
|
10885
11763
|
rewriteFileMentions,
|
|
10886
11764
|
runDeploymentForContext,
|
|
11765
|
+
runRemoteDeployment,
|
|
11766
|
+
sendRemoteSessionEvents,
|
|
10887
11767
|
sendSessionMessagePolling,
|
|
10888
11768
|
sendSessionMessageStreaming,
|
|
10889
11769
|
setDefaultFetch,
|
|
11770
|
+
setRemoteDeploymentPaused,
|
|
10890
11771
|
startSessionRun,
|
|
10891
11772
|
startSessionRunPolling,
|
|
10892
11773
|
streamSessionEvents,
|
|
@@ -10896,6 +11777,7 @@ export {
|
|
|
10896
11777
|
syncProviderResourcesFromEnv,
|
|
10897
11778
|
updateMemory,
|
|
10898
11779
|
updateMemoryStore,
|
|
11780
|
+
updateRemoteSession,
|
|
10899
11781
|
uploadFile,
|
|
10900
11782
|
validateProjectConfig,
|
|
10901
11783
|
writeProjectRuntime
|