@openagentpack/sdk 0.4.0 → 0.6.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 +324 -29
- package/dist/index.js +1889 -649
- package/dist/{session-event--Mxe1bnT.d.ts → session-event-B63Rbjim.d.ts} +63 -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,26 @@ 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
|
+
if (cred.networking?.type === "limited" && cred.networking.allowed_hosts === void 0) {
|
|
3666
|
+
throw new UserError(`credential '${cred.name}': Bailian limited networking requires networking.allowed_hosts.`);
|
|
3667
|
+
}
|
|
3668
|
+
const body = {
|
|
3645
3669
|
auth: {
|
|
3646
|
-
type:
|
|
3647
|
-
|
|
3648
|
-
|
|
3670
|
+
type: "environment_variable",
|
|
3671
|
+
secret_name: cred.secret_name,
|
|
3672
|
+
secret_value: cred.secret_value,
|
|
3673
|
+
networking: { allowed_hosts: cred.networking?.allowed_hosts ?? ["*"] },
|
|
3674
|
+
injection_location: cred.injection_location ?? { header: true, body: false }
|
|
3649
3675
|
},
|
|
3650
3676
|
display_name: cred.name
|
|
3651
3677
|
};
|
|
3678
|
+
if (cred.metadata) body.metadata = cred.metadata;
|
|
3679
|
+
return body;
|
|
3652
3680
|
}
|
|
3653
3681
|
function credToDecl3(raw, vaultName) {
|
|
3654
3682
|
const auth = raw.auth ?? {};
|
|
@@ -3658,17 +3686,21 @@ function credToDecl3(raw, vaultName) {
|
|
|
3658
3686
|
return {
|
|
3659
3687
|
name,
|
|
3660
3688
|
type: "static_bearer",
|
|
3689
|
+
metadata: stripAgentsMetadata(raw.metadata),
|
|
3661
3690
|
mcp_server_url: auth.mcp_server_url ?? "",
|
|
3662
3691
|
access_token: placeholder
|
|
3663
3692
|
};
|
|
3664
3693
|
}
|
|
3665
3694
|
const networking = auth.networking;
|
|
3695
|
+
const injectionLocation = auth.injection_location;
|
|
3666
3696
|
return {
|
|
3667
3697
|
name,
|
|
3668
3698
|
type: "environment_variable",
|
|
3699
|
+
metadata: stripAgentsMetadata(raw.metadata),
|
|
3669
3700
|
secret_name: auth.secret_name ?? name,
|
|
3670
3701
|
secret_value: placeholder,
|
|
3671
|
-
networking: networking ?? { type: "unrestricted" }
|
|
3702
|
+
networking: networking ?? { type: "unrestricted" },
|
|
3703
|
+
...injectionLocation ? { injection_location: injectionLocation } : {}
|
|
3672
3704
|
};
|
|
3673
3705
|
}
|
|
3674
3706
|
function vaultToDecl3(raw, rawCredentials, resourceName) {
|
|
@@ -3733,6 +3765,7 @@ function agentToDecl3(raw) {
|
|
|
3733
3765
|
const model = raw.model;
|
|
3734
3766
|
const modelValue = typeof model === "object" && model ? model.id : model;
|
|
3735
3767
|
return compactDeep({
|
|
3768
|
+
name: raw.name,
|
|
3736
3769
|
description: raw.description,
|
|
3737
3770
|
model: modelValue,
|
|
3738
3771
|
instructions: raw.system,
|
|
@@ -3752,7 +3785,7 @@ function mapAgent3(name, decl, refs, version, projectName, skillVersions) {
|
|
|
3752
3785
|
modelId = typeof bailianModel === "string" ? bailianModel : bailianModel.id;
|
|
3753
3786
|
}
|
|
3754
3787
|
const body = {
|
|
3755
|
-
name,
|
|
3788
|
+
name: decl.name ?? name,
|
|
3756
3789
|
model: { id: modelId },
|
|
3757
3790
|
system: decl.instructions
|
|
3758
3791
|
};
|
|
@@ -3845,7 +3878,7 @@ function mapDeployment3(name, decl, refs, projectName, uploadedFiles) {
|
|
|
3845
3878
|
const agent = { id: refs.agent_id };
|
|
3846
3879
|
if (refs.agent_version !== void 0) agent.version = refs.agent_version;
|
|
3847
3880
|
const body = {
|
|
3848
|
-
name,
|
|
3881
|
+
name: decl.name ?? name,
|
|
3849
3882
|
agent,
|
|
3850
3883
|
environment_id: refs.environment_id,
|
|
3851
3884
|
initial_events: mapMessageEvents(decl.initial_events)
|
|
@@ -3983,6 +4016,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
3983
4016
|
});
|
|
3984
4017
|
}
|
|
3985
4018
|
return compactDeep({
|
|
4019
|
+
name: raw.name,
|
|
3986
4020
|
description: raw.description,
|
|
3987
4021
|
model: normalizeBailianModel(raw.model),
|
|
3988
4022
|
instructions: raw.system,
|
|
@@ -4014,6 +4048,18 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4014
4048
|
async deleteEnvironment(id) {
|
|
4015
4049
|
await this.client.delete(`/environments/${id}`);
|
|
4016
4050
|
}
|
|
4051
|
+
async listEnvironmentResources(options) {
|
|
4052
|
+
const params = cursorParams(options);
|
|
4053
|
+
if (options?.include_archived !== void 0) {
|
|
4054
|
+
params.set("include_archived", String(options.include_archived));
|
|
4055
|
+
}
|
|
4056
|
+
const res = await this.client.get(withQuery("/environments", params));
|
|
4057
|
+
return cursorPage(res, toCloudEnvironment);
|
|
4058
|
+
}
|
|
4059
|
+
async getRemoteEnvironment(id) {
|
|
4060
|
+
const res = await this.client.get(`/environments/${id}`);
|
|
4061
|
+
return toCloudEnvironment(res);
|
|
4062
|
+
}
|
|
4017
4063
|
// --- Agent ---
|
|
4018
4064
|
async createAgent(name, decl, refs) {
|
|
4019
4065
|
const skillVersions = await this.fetchSkillVersions(refs);
|
|
@@ -4062,6 +4108,25 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4062
4108
|
async deleteAgent(id) {
|
|
4063
4109
|
await this.client.post(`/agents/${id}/archive`, {});
|
|
4064
4110
|
}
|
|
4111
|
+
async listAgentResources(options) {
|
|
4112
|
+
const params = cursorParams(options);
|
|
4113
|
+
if (options?.include_archived !== void 0) {
|
|
4114
|
+
params.set("include_archived", String(options.include_archived));
|
|
4115
|
+
}
|
|
4116
|
+
const res = await this.client.get(withQuery("/agents", params));
|
|
4117
|
+
return cursorPage(res, toCloudAgent);
|
|
4118
|
+
}
|
|
4119
|
+
async getRemoteAgent(id, version) {
|
|
4120
|
+
const params = new URLSearchParams();
|
|
4121
|
+
if (version !== void 0) params.set("version", String(version));
|
|
4122
|
+
const res = await this.client.get(withQuery(`/agents/${id}`, params));
|
|
4123
|
+
return toCloudAgent(res);
|
|
4124
|
+
}
|
|
4125
|
+
async listAgentVersions(id, options) {
|
|
4126
|
+
const params = cursorParams(options);
|
|
4127
|
+
const res = await this.client.get(withQuery(`/agents/${id}/versions`, params));
|
|
4128
|
+
return cursorPage(res, toCloudAgent);
|
|
4129
|
+
}
|
|
4065
4130
|
// --- Skill (2-step: Files API → Skills API) ---
|
|
4066
4131
|
async createSkill(name, decl, files) {
|
|
4067
4132
|
const fileId = await this.uploadSkillZip(name, decl, files);
|
|
@@ -4160,10 +4225,31 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4160
4225
|
const all = await this.client.getAllPaged(path);
|
|
4161
4226
|
return all.map(toBailianSkillInfo);
|
|
4162
4227
|
}
|
|
4228
|
+
async listSkillResources(options) {
|
|
4229
|
+
const params = cursorParams(options);
|
|
4230
|
+
if (options?.source === "official") params.set("source", "official");
|
|
4231
|
+
if (options?.source === "custom") params.set("source", "customer");
|
|
4232
|
+
const res = await this.client.get(withQuery("/skills", params));
|
|
4233
|
+
return cursorPage(res, toBailianSkillInfo);
|
|
4234
|
+
}
|
|
4163
4235
|
async getSkillInfo(id) {
|
|
4164
4236
|
const res = await this.client.get(`/skills/${id}`);
|
|
4165
4237
|
return toBailianSkillInfo(res);
|
|
4166
4238
|
}
|
|
4239
|
+
async listSkillVersions(id, options) {
|
|
4240
|
+
const params = cursorParams(options);
|
|
4241
|
+
const res = await this.client.get(withQuery(`/skills/${id}/versions`, params));
|
|
4242
|
+
return cursorPage(res, toSkillVersionInfo);
|
|
4243
|
+
}
|
|
4244
|
+
async getSkillVersion(id, version) {
|
|
4245
|
+
const res = await this.client.get(`/skills/${id}/versions/${encodeURIComponent(version)}`);
|
|
4246
|
+
return toSkillVersionInfo(res);
|
|
4247
|
+
}
|
|
4248
|
+
async getSkillDownloadInfo(id, version) {
|
|
4249
|
+
return await this.client.get(
|
|
4250
|
+
`/skills/${id}/versions/${encodeURIComponent(version)}/content`
|
|
4251
|
+
);
|
|
4252
|
+
}
|
|
4167
4253
|
// Non-blocking create: file already uploaded → POST /skills with retry for residual OSS
|
|
4168
4254
|
// replication lag (postSkillWithRetry covers SKILL_FILE_NOT_FOUND for a few seconds), and return
|
|
4169
4255
|
// the initial status WITHOUT waiting for the security scan. Callers MUST ensure the file has
|
|
@@ -4223,6 +4309,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4223
4309
|
// thin wrappers over the AgentStudio endpoints, exposed so callers/tests can
|
|
4224
4310
|
// exercise the full surface through real project code rather than raw fetch.
|
|
4225
4311
|
async createVault(name, decl) {
|
|
4312
|
+
for (const credential of decl.credentials ?? []) mapCredential2(credential);
|
|
4226
4313
|
const body = mapVault2(name, decl, this.projectName);
|
|
4227
4314
|
const res = await this.client.post("/vaults", body);
|
|
4228
4315
|
const vaultId = res.id;
|
|
@@ -4235,6 +4322,18 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4235
4322
|
const all = await this.client.getAllPaged("/vaults");
|
|
4236
4323
|
return all.map(toCloudVault);
|
|
4237
4324
|
}
|
|
4325
|
+
async listVaultResources(options) {
|
|
4326
|
+
const params = cursorParams(options);
|
|
4327
|
+
if (options?.include_archived !== void 0) {
|
|
4328
|
+
params.set("include_archived", String(options.include_archived));
|
|
4329
|
+
}
|
|
4330
|
+
const res = await this.client.get(withQuery("/vaults", params));
|
|
4331
|
+
return cursorPage(res, toCloudVault);
|
|
4332
|
+
}
|
|
4333
|
+
async getRemoteVault(id) {
|
|
4334
|
+
const res = await this.client.get(`/vaults/${id}`);
|
|
4335
|
+
return toCloudVault(res);
|
|
4336
|
+
}
|
|
4238
4337
|
async getVault(id) {
|
|
4239
4338
|
return await this.client.get(`/vaults/${id}`);
|
|
4240
4339
|
}
|
|
@@ -4256,7 +4355,24 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4256
4355
|
}
|
|
4257
4356
|
async listCredentials(vaultId) {
|
|
4258
4357
|
const all = await this.client.getAllPaged(`/vaults/${vaultId}/credentials`);
|
|
4259
|
-
return all.map(
|
|
4358
|
+
return all.map((raw) => {
|
|
4359
|
+
const auth = raw.auth ?? {};
|
|
4360
|
+
const networking = auth.networking;
|
|
4361
|
+
const metadata = raw.metadata;
|
|
4362
|
+
return {
|
|
4363
|
+
id: raw.id,
|
|
4364
|
+
display_name: raw.display_name ?? raw.id,
|
|
4365
|
+
auth_type: auth.type ?? "",
|
|
4366
|
+
secret_name: auth.secret_name,
|
|
4367
|
+
mcp_server_url: auth.mcp_server_url,
|
|
4368
|
+
networking_type: networking?.type,
|
|
4369
|
+
networking,
|
|
4370
|
+
injection_location: auth.injection_location,
|
|
4371
|
+
metadata: metadata ? Object.fromEntries(
|
|
4372
|
+
Object.entries(metadata).filter((entry) => typeof entry[1] === "string")
|
|
4373
|
+
) : void 0
|
|
4374
|
+
};
|
|
4375
|
+
});
|
|
4260
4376
|
}
|
|
4261
4377
|
async getCredential(vaultId, credentialId) {
|
|
4262
4378
|
return await this.client.get(`/vaults/${vaultId}/credentials/${credentialId}`);
|
|
@@ -4306,11 +4422,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4306
4422
|
throw new UserError(`Deployment '${ctx.name}' has no remote id; run \`agents apply\` first.`);
|
|
4307
4423
|
}
|
|
4308
4424
|
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
|
-
};
|
|
4425
|
+
return toDeploymentRunResult(res);
|
|
4314
4426
|
}
|
|
4315
4427
|
async getDeployment(ctx) {
|
|
4316
4428
|
if (!ctx.id) {
|
|
@@ -4322,6 +4434,7 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4322
4434
|
async listDeployments(filter) {
|
|
4323
4435
|
const params = new URLSearchParams();
|
|
4324
4436
|
if (filter?.agent_id) params.set("agent_id", filter.agent_id);
|
|
4437
|
+
if (filter?.keyword) params.set("keyword", filter.keyword);
|
|
4325
4438
|
if (filter?.status) params.set("status", filter.status);
|
|
4326
4439
|
if (filter?.include_archived) params.set("include_archived", "true");
|
|
4327
4440
|
if (filter?.limit) params.set("limit", String(filter.limit));
|
|
@@ -4337,6 +4450,32 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4337
4450
|
next_page: nextPage
|
|
4338
4451
|
};
|
|
4339
4452
|
}
|
|
4453
|
+
async getDeploymentById(id) {
|
|
4454
|
+
const res = await this.client.get(`/deployments/${id}`);
|
|
4455
|
+
return toDeploymentInfo3(res);
|
|
4456
|
+
}
|
|
4457
|
+
async runDeploymentById(id) {
|
|
4458
|
+
const res = await this.client.post(`/deployments/${id}/run`, {});
|
|
4459
|
+
return toDeploymentRunResult(res);
|
|
4460
|
+
}
|
|
4461
|
+
async pauseDeploymentById(id) {
|
|
4462
|
+
const res = await this.client.post(`/deployments/${id}/pause`, {});
|
|
4463
|
+
return toDeploymentInfo3(res);
|
|
4464
|
+
}
|
|
4465
|
+
async unpauseDeploymentById(id) {
|
|
4466
|
+
const res = await this.client.post(`/deployments/${id}/unpause`, {});
|
|
4467
|
+
return toDeploymentInfo3(res);
|
|
4468
|
+
}
|
|
4469
|
+
async listDeploymentRuns(deploymentId, options) {
|
|
4470
|
+
const res = await this.client.get(
|
|
4471
|
+
withQuery(`/deployments/${deploymentId}/runs`, cursorParams(options))
|
|
4472
|
+
);
|
|
4473
|
+
return cursorPage(res, toDeploymentRunInfo);
|
|
4474
|
+
}
|
|
4475
|
+
async getDeploymentRun(runId) {
|
|
4476
|
+
const res = await this.client.get(`/deployment_runs/${runId}`);
|
|
4477
|
+
return toDeploymentRunInfo(res);
|
|
4478
|
+
}
|
|
4340
4479
|
async pauseDeployment(ctx) {
|
|
4341
4480
|
return this.setDeploymentPaused(ctx, true);
|
|
4342
4481
|
}
|
|
@@ -4391,6 +4530,9 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4391
4530
|
async listSessions(filter) {
|
|
4392
4531
|
const params = new URLSearchParams();
|
|
4393
4532
|
if (filter?.agent_id) params.set("agent_id", filter.agent_id);
|
|
4533
|
+
for (const status of filter?.statuses ?? []) params.append("statuses[]", status);
|
|
4534
|
+
if (filter?.created_at_gte) params.set("created_at[gte]", filter.created_at_gte);
|
|
4535
|
+
if (filter?.created_at_lte) params.set("created_at[lte]", filter.created_at_lte);
|
|
4394
4536
|
if (filter?.limit) params.set("limit", String(filter.limit));
|
|
4395
4537
|
if (filter?.page) params.set("page", filter.page);
|
|
4396
4538
|
const qs = params.toString();
|
|
@@ -4407,6 +4549,15 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4407
4549
|
const res = await this.client.get(`/sessions/${id}`);
|
|
4408
4550
|
return toSessionInfo3(res);
|
|
4409
4551
|
}
|
|
4552
|
+
async updateSession(id, input) {
|
|
4553
|
+
const res = await this.client.post(`/sessions/${id}`, input);
|
|
4554
|
+
if (!res.agent || !res.environment_id) return this.getSession(id);
|
|
4555
|
+
return toSessionInfo3(res);
|
|
4556
|
+
}
|
|
4557
|
+
async archiveSession(id) {
|
|
4558
|
+
const res = await this.client.post(`/sessions/${id}/archive`, {});
|
|
4559
|
+
return toSessionInfo3(res);
|
|
4560
|
+
}
|
|
4410
4561
|
async deleteSession(id) {
|
|
4411
4562
|
await this.client.delete(`/sessions/${id}`);
|
|
4412
4563
|
}
|
|
@@ -4415,13 +4566,20 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4415
4566
|
const res = await this.client.post(`/sessions/${sessionId}/events`, body);
|
|
4416
4567
|
return extractCreatedEventId(res);
|
|
4417
4568
|
}
|
|
4569
|
+
async sendSessionEvents(sessionId, events) {
|
|
4570
|
+
const res = await this.client.post(`/sessions/${sessionId}/events`, { input: events });
|
|
4571
|
+
return {
|
|
4572
|
+
event_ids: extractCreatedEventIds(res),
|
|
4573
|
+
attributes: res
|
|
4574
|
+
};
|
|
4575
|
+
}
|
|
4418
4576
|
async *streamSessionEvents(sessionId, _options) {
|
|
4419
4577
|
for await (const raw of this.client.sse(`/sessions/${sessionId}/events/stream`)) {
|
|
4420
4578
|
yield toSessionEvent(raw);
|
|
4421
4579
|
}
|
|
4422
4580
|
}
|
|
4423
4581
|
async listSessionEvents(sessionId, options) {
|
|
4424
|
-
return listSessionEventsPaged(this.client, sessionId, options, toSessionEvent);
|
|
4582
|
+
return listSessionEventsPaged(this.client, sessionId, options, toSessionEvent, { forwardTypes: false });
|
|
4425
4583
|
}
|
|
4426
4584
|
// --- Files ---
|
|
4427
4585
|
async uploadFile(filePath, options) {
|
|
@@ -4447,6 +4605,15 @@ var BailianAdapter = class _BailianAdapter {
|
|
|
4447
4605
|
const all = await this.client.getAllPaged("/files");
|
|
4448
4606
|
return all.map(toRestFileInfo);
|
|
4449
4607
|
}
|
|
4608
|
+
async listFileResources(options) {
|
|
4609
|
+
const params = cursorParams(options);
|
|
4610
|
+
if (options?.scope_id) params.set("scope_id", options.scope_id);
|
|
4611
|
+
const res = await this.client.get(withQuery("/files", params));
|
|
4612
|
+
return cursorPage(res, toRestFileInfo);
|
|
4613
|
+
}
|
|
4614
|
+
async downloadFileContent(id) {
|
|
4615
|
+
return new Uint8Array(await this.client.getBuffer(`/files/${id}/content`));
|
|
4616
|
+
}
|
|
4450
4617
|
async deleteFile(id) {
|
|
4451
4618
|
await this.client.delete(`/files/${id}`);
|
|
4452
4619
|
}
|
|
@@ -4481,9 +4648,77 @@ function toBailianSkillInfo(res) {
|
|
|
4481
4648
|
status: skillStatusFromString(res.status),
|
|
4482
4649
|
latest_version: res.latest_version,
|
|
4483
4650
|
created_at: res.created_at,
|
|
4484
|
-
updated_at: res.updated_at
|
|
4651
|
+
updated_at: res.updated_at,
|
|
4652
|
+
attributes: res
|
|
4653
|
+
};
|
|
4654
|
+
}
|
|
4655
|
+
function cursorParams(options) {
|
|
4656
|
+
const params = new URLSearchParams();
|
|
4657
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
4658
|
+
if (options?.page) params.set("page", options.page);
|
|
4659
|
+
return params;
|
|
4660
|
+
}
|
|
4661
|
+
function withQuery(path, params) {
|
|
4662
|
+
const query2 = params.toString();
|
|
4663
|
+
return query2 ? `${path}?${query2}` : path;
|
|
4664
|
+
}
|
|
4665
|
+
function cursorPage(res, mapper) {
|
|
4666
|
+
const nextPage = res.next_page ?? void 0;
|
|
4667
|
+
return {
|
|
4668
|
+
data: (res.data ?? []).map(mapper),
|
|
4669
|
+
has_more: res.has_more ?? nextPage !== void 0,
|
|
4670
|
+
next_page: nextPage
|
|
4671
|
+
};
|
|
4672
|
+
}
|
|
4673
|
+
function toSkillVersionInfo(res) {
|
|
4674
|
+
return {
|
|
4675
|
+
id: res.id,
|
|
4676
|
+
skill_id: res.skill_id ?? "",
|
|
4677
|
+
type: res.type ?? "skill_version",
|
|
4678
|
+
name: res.name,
|
|
4679
|
+
description: res.description,
|
|
4680
|
+
version: res.version ?? "",
|
|
4681
|
+
status: res.status,
|
|
4682
|
+
created_at: res.created_at,
|
|
4683
|
+
updated_at: res.updated_at,
|
|
4684
|
+
additional_properties: res.additional_properties,
|
|
4685
|
+
attributes: res
|
|
4686
|
+
};
|
|
4687
|
+
}
|
|
4688
|
+
function toDeploymentRunResult(res) {
|
|
4689
|
+
return {
|
|
4690
|
+
run_id: res.id,
|
|
4691
|
+
session_id: res.session_id ?? null,
|
|
4692
|
+
error: res.error ?? void 0
|
|
4693
|
+
};
|
|
4694
|
+
}
|
|
4695
|
+
function toDeploymentRunInfo(res) {
|
|
4696
|
+
return {
|
|
4697
|
+
id: res.id ?? "",
|
|
4698
|
+
deployment_id: res.deployment_id,
|
|
4699
|
+
session_id: res.session_id ?? void 0,
|
|
4700
|
+
status: res.status,
|
|
4701
|
+
error: res.error ?? void 0,
|
|
4702
|
+
created_at: res.created_at,
|
|
4703
|
+
updated_at: res.updated_at,
|
|
4704
|
+
attributes: res
|
|
4485
4705
|
};
|
|
4486
4706
|
}
|
|
4707
|
+
function extractCreatedEventIds(res) {
|
|
4708
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4709
|
+
const topLevel = extractCreatedEventId(res);
|
|
4710
|
+
if (topLevel) ids.add(topLevel);
|
|
4711
|
+
for (const key of ["data", "events"]) {
|
|
4712
|
+
const items = res[key];
|
|
4713
|
+
if (!Array.isArray(items)) continue;
|
|
4714
|
+
for (const item of items) {
|
|
4715
|
+
if (!item || typeof item !== "object") continue;
|
|
4716
|
+
const id = item.id;
|
|
4717
|
+
if (typeof id === "string") ids.add(id);
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
return Array.from(ids);
|
|
4721
|
+
}
|
|
4487
4722
|
function normalizeBailianModel(value) {
|
|
4488
4723
|
if (value && typeof value === "object" && "id" in value) {
|
|
4489
4724
|
return value.id;
|
|
@@ -4548,7 +4783,7 @@ function guessMimeType(fileName) {
|
|
|
4548
4783
|
// src/internal/providers/bailian/capabilities.ts
|
|
4549
4784
|
var BAILIAN_CAPABILITIES = {
|
|
4550
4785
|
environment: { tier: "native", reason: "environments API" },
|
|
4551
|
-
vault: { tier: "native", reason: "vaults + credentials API
|
|
4786
|
+
vault: { tier: "native", reason: "vaults + environment_variable credentials API" },
|
|
4552
4787
|
skill: { tier: "native", reason: "skills API with 2-step zip upload via Files API" },
|
|
4553
4788
|
agent: { tier: "native", reason: "agents API with versioned updates" },
|
|
4554
4789
|
template: { tier: "unsupported", reason: "no Forward Template equivalent on Bailian" },
|
|
@@ -4809,7 +5044,7 @@ function mapAgent4(name, decl, refs, version, projectName) {
|
|
|
4809
5044
|
if (!arkModel) throw new UserError(`No Ark model specified for agent '${name}'`);
|
|
4810
5045
|
const modelValue = typeof arkModel === "string" ? { id: arkModel } : { id: arkModel.id };
|
|
4811
5046
|
const body = {
|
|
4812
|
-
name,
|
|
5047
|
+
name: decl.name ?? name,
|
|
4813
5048
|
model: modelValue,
|
|
4814
5049
|
system: decl.instructions
|
|
4815
5050
|
};
|
|
@@ -5499,6 +5734,30 @@ async function resolveFileReferences(config, configPath) {
|
|
|
5499
5734
|
// src/internal/parser/resolve-project-config.ts
|
|
5500
5735
|
import { basename as basename5, dirname as dirname7, resolve as resolve7 } from "path";
|
|
5501
5736
|
|
|
5737
|
+
// src/internal/utils/env.ts
|
|
5738
|
+
var ENV_VAR_PATTERN = /\$\{([^}]+)\}/g;
|
|
5739
|
+
function interpolateEnvVars(value, resolve13 = false, environment = process.env) {
|
|
5740
|
+
return value.replace(ENV_VAR_PATTERN, (match, varName) => {
|
|
5741
|
+
if (!resolve13) return match;
|
|
5742
|
+
const resolvedValue = environment[varName];
|
|
5743
|
+
if (resolvedValue === void 0) {
|
|
5744
|
+
throw new UserError(`Environment variable '${varName}' is not set`);
|
|
5745
|
+
}
|
|
5746
|
+
return resolvedValue;
|
|
5747
|
+
});
|
|
5748
|
+
}
|
|
5749
|
+
function interpolateObjectEnv(value, environment = process.env) {
|
|
5750
|
+
if (typeof value === "string") return interpolateEnvVars(value, true, environment);
|
|
5751
|
+
if (Array.isArray(value)) return value.map((entry) => interpolateObjectEnv(entry, environment));
|
|
5752
|
+
if (!value || typeof value !== "object") return value;
|
|
5753
|
+
return Object.fromEntries(
|
|
5754
|
+
Object.entries(value).map(([key, entry]) => [
|
|
5755
|
+
key,
|
|
5756
|
+
interpolateObjectEnv(entry, environment)
|
|
5757
|
+
])
|
|
5758
|
+
);
|
|
5759
|
+
}
|
|
5760
|
+
|
|
5502
5761
|
// src/internal/parser/schema.ts
|
|
5503
5762
|
import { z as z5 } from "zod";
|
|
5504
5763
|
var networkingSchema = z5.object({
|
|
@@ -5543,6 +5802,7 @@ var coerceString = z5.union([z5.string(), z5.number()]).transform(String);
|
|
|
5543
5802
|
var staticBearerCredentialSchema = z5.object({
|
|
5544
5803
|
name: z5.string(),
|
|
5545
5804
|
type: z5.literal("static_bearer"),
|
|
5805
|
+
metadata: z5.record(z5.string(), z5.string()).optional(),
|
|
5546
5806
|
mcp_server_url: z5.string(),
|
|
5547
5807
|
access_token: coerceString,
|
|
5548
5808
|
protocol: z5.enum(["sse", "streamable_http"]).optional()
|
|
@@ -5550,9 +5810,17 @@ var staticBearerCredentialSchema = z5.object({
|
|
|
5550
5810
|
var environmentVariableCredentialSchema = z5.object({
|
|
5551
5811
|
name: z5.string(),
|
|
5552
5812
|
type: z5.literal("environment_variable"),
|
|
5813
|
+
metadata: z5.record(z5.string(), z5.string()).optional(),
|
|
5553
5814
|
secret_name: z5.string(),
|
|
5554
5815
|
secret_value: coerceString,
|
|
5555
|
-
networking: z5.object({
|
|
5816
|
+
networking: z5.object({
|
|
5817
|
+
type: z5.enum(["unrestricted", "limited"]).optional(),
|
|
5818
|
+
allowed_hosts: z5.array(z5.string()).optional()
|
|
5819
|
+
}).optional(),
|
|
5820
|
+
injection_location: z5.object({
|
|
5821
|
+
header: z5.boolean().optional(),
|
|
5822
|
+
body: z5.boolean().optional()
|
|
5823
|
+
}).optional()
|
|
5556
5824
|
});
|
|
5557
5825
|
var credentialSchema = z5.discriminatedUnion("type", [
|
|
5558
5826
|
staticBearerCredentialSchema,
|
|
@@ -5692,6 +5960,10 @@ var agentSkillRefSchema = z5.object({
|
|
|
5692
5960
|
var agentDeliverySchema = z5.object({
|
|
5693
5961
|
type: z5.enum(["managed", "forward"])
|
|
5694
5962
|
});
|
|
5963
|
+
var agentFileMountSchema = z5.object({
|
|
5964
|
+
file: z5.string().min(1),
|
|
5965
|
+
mount_path: z5.string().min(1)
|
|
5966
|
+
});
|
|
5695
5967
|
var managedToolConfigSchema = z5.object({
|
|
5696
5968
|
enabled_tools: z5.array(z5.string().min(1))
|
|
5697
5969
|
});
|
|
@@ -5716,8 +5988,8 @@ var agentSchema = z5.object({
|
|
|
5716
5988
|
mcp_servers: z5.array(mcpServerSchema).optional(),
|
|
5717
5989
|
skills: z5.array(z5.union([z5.string(), agentSkillRefSchema])).optional(),
|
|
5718
5990
|
vault: z5.string().optional(),
|
|
5719
|
-
files: z5.array(z5.string()).optional(),
|
|
5720
5991
|
memory_stores: z5.array(z5.string()).optional(),
|
|
5992
|
+
files: z5.array(z5.union([z5.string().min(1), agentFileMountSchema])).optional(),
|
|
5721
5993
|
default_memory_store: z5.object({
|
|
5722
5994
|
name: z5.string().trim().min(1).max(255),
|
|
5723
5995
|
description: z5.string().max(1024).optional(),
|
|
@@ -5783,6 +6055,7 @@ var scheduleSchema = z5.object({
|
|
|
5783
6055
|
timezone: z5.string()
|
|
5784
6056
|
});
|
|
5785
6057
|
var deploymentSchema = z5.object({
|
|
6058
|
+
name: z5.string().optional(),
|
|
5786
6059
|
agent: z5.string(),
|
|
5787
6060
|
agent_version: z5.number().int().optional(),
|
|
5788
6061
|
environment: z5.string().optional(),
|
|
@@ -5819,22 +6092,7 @@ var projectConfigSchema = z5.object({
|
|
|
5819
6092
|
// src/internal/parser/yaml-loader.ts
|
|
5820
6093
|
import { readFile as readFile3 } from "fs/promises";
|
|
5821
6094
|
import { parse as parseYaml } from "yaml";
|
|
5822
|
-
|
|
5823
|
-
// src/internal/utils/env.ts
|
|
5824
|
-
var ENV_VAR_PATTERN = /\$\{([^}]+)\}/g;
|
|
5825
|
-
function interpolateEnvVars(value, resolve13 = false) {
|
|
5826
|
-
return value.replace(ENV_VAR_PATTERN, (match, varName) => {
|
|
5827
|
-
if (!resolve13) return match;
|
|
5828
|
-
const val = process.env[varName];
|
|
5829
|
-
if (val === void 0) {
|
|
5830
|
-
throw new UserError(`Environment variable '${varName}' is not set`);
|
|
5831
|
-
}
|
|
5832
|
-
return val;
|
|
5833
|
-
});
|
|
5834
|
-
}
|
|
5835
|
-
|
|
5836
|
-
// src/internal/parser/yaml-loader.ts
|
|
5837
|
-
async function loadConfig(filePath, resolveEnv = false) {
|
|
6095
|
+
async function loadConfig(filePath, resolveEnv = false, environment) {
|
|
5838
6096
|
let raw;
|
|
5839
6097
|
try {
|
|
5840
6098
|
raw = await readFile3(filePath, "utf8");
|
|
@@ -5845,7 +6103,7 @@ async function loadConfig(filePath, resolveEnv = false) {
|
|
|
5845
6103
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5846
6104
|
return { config: null, errors: [`Failed to read file: ${msg}`] };
|
|
5847
6105
|
}
|
|
5848
|
-
if (resolveEnv) {
|
|
6106
|
+
if (resolveEnv && !environment) {
|
|
5849
6107
|
raw = interpolateEnvVars(raw, true);
|
|
5850
6108
|
}
|
|
5851
6109
|
let parsed;
|
|
@@ -5855,6 +6113,7 @@ async function loadConfig(filePath, resolveEnv = false) {
|
|
|
5855
6113
|
const msg = e instanceof Error ? e.message : String(e);
|
|
5856
6114
|
return { config: null, errors: [`YAML parse error: ${msg}`] };
|
|
5857
6115
|
}
|
|
6116
|
+
if (resolveEnv && environment) parsed = interpolateObjectEnv(parsed, environment);
|
|
5858
6117
|
const result = projectConfigSchema.safeParse(parsed);
|
|
5859
6118
|
if (!result.success) {
|
|
5860
6119
|
const errors = result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`);
|
|
@@ -5867,27 +6126,73 @@ async function loadConfig(filePath, resolveEnv = false) {
|
|
|
5867
6126
|
async function resolveProjectConfig(filePath, options = {}) {
|
|
5868
6127
|
const configPath = resolve7(filePath);
|
|
5869
6128
|
const projectName = options.projectName ?? basename5(dirname7(configPath));
|
|
5870
|
-
const { config: parsed, errors } = await loadConfig(
|
|
6129
|
+
const { config: parsed, errors } = await loadConfig(
|
|
6130
|
+
configPath,
|
|
6131
|
+
options.resolveEnv ?? true,
|
|
6132
|
+
options.environment ? { ...options.environment, ...process.env } : void 0
|
|
6133
|
+
);
|
|
5871
6134
|
if (errors.length > 0) {
|
|
5872
6135
|
throw new UserError(errors.join("\n"));
|
|
5873
6136
|
}
|
|
5874
|
-
const
|
|
5875
|
-
|
|
6137
|
+
const sourcePaths = collectProjectSourcePaths(parsed, configPath, true);
|
|
6138
|
+
let config;
|
|
6139
|
+
try {
|
|
6140
|
+
config = await resolveFileReferences(parsed, configPath);
|
|
6141
|
+
} catch (error) {
|
|
6142
|
+
if (error && typeof error === "object") {
|
|
6143
|
+
Object.assign(error, { sourcePaths });
|
|
6144
|
+
}
|
|
6145
|
+
throw error;
|
|
6146
|
+
}
|
|
6147
|
+
return { configPath, projectName, config, sourcePaths };
|
|
5876
6148
|
}
|
|
5877
6149
|
async function resolveProjectConfigFromObject(rawConfig, options) {
|
|
5878
6150
|
const basePath = resolve7(options.basePath ?? process.cwd());
|
|
5879
|
-
const
|
|
6151
|
+
const input = options.resolveEnv ? interpolateObjectEnv(rawConfig, { ...options.environment, ...process.env }) : rawConfig;
|
|
6152
|
+
const result = projectConfigSchema.safeParse(input);
|
|
5880
6153
|
if (!result.success) {
|
|
5881
6154
|
const errors = result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`);
|
|
5882
6155
|
throw new UserError(errors.join("\n"));
|
|
5883
6156
|
}
|
|
5884
6157
|
const anchor = resolve7(basePath, "__in_memory_config__");
|
|
5885
|
-
const
|
|
5886
|
-
|
|
6158
|
+
const parsed = result.data;
|
|
6159
|
+
const sourcePaths = collectProjectSourcePaths(parsed, anchor, false);
|
|
6160
|
+
const config = await resolveFileReferences(parsed, anchor);
|
|
6161
|
+
return { configPath: basePath, projectName: options.projectName, config, sourcePaths };
|
|
6162
|
+
}
|
|
6163
|
+
function collectProjectSourcePaths(config, configPath, includeConfigPath) {
|
|
6164
|
+
const baseDirectory = dirname7(configPath);
|
|
6165
|
+
const paths = /* @__PURE__ */ new Set();
|
|
6166
|
+
if (includeConfigPath) paths.add(configPath);
|
|
6167
|
+
const addLocalPath = (value, requirePathSyntax = false) => {
|
|
6168
|
+
if (!value || /^https?:\/\//i.test(value)) return;
|
|
6169
|
+
if (requirePathSyntax && !isLocalPathReference(value)) return;
|
|
6170
|
+
paths.add(resolve7(baseDirectory, value));
|
|
6171
|
+
};
|
|
6172
|
+
for (const agent of Object.values(config.agents ?? {})) {
|
|
6173
|
+
addLocalPath(agent.instructions, true);
|
|
6174
|
+
}
|
|
6175
|
+
for (const store of Object.values(config.memory_stores ?? {})) {
|
|
6176
|
+
for (const entry of store.entries ?? []) addLocalPath(entry.content, true);
|
|
6177
|
+
}
|
|
6178
|
+
for (const skill of Object.values(config.skills ?? {})) addLocalPath(skill.source);
|
|
6179
|
+
for (const file of Object.values(config.files ?? {})) addLocalPath(file.source);
|
|
6180
|
+
for (const deployment of Object.values(config.deployments ?? {})) {
|
|
6181
|
+
for (const resource of deployment.resources ?? []) {
|
|
6182
|
+
if (resource.type === "file") addLocalPath(resource.source);
|
|
6183
|
+
}
|
|
6184
|
+
for (const event of deployment.initial_events ?? []) {
|
|
6185
|
+
if (event.type === "user.define_outcome") addLocalPath(event.rubric_file, true);
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
return [...paths].sort();
|
|
6189
|
+
}
|
|
6190
|
+
function isLocalPathReference(value) {
|
|
6191
|
+
return value.startsWith("./") || value.startsWith("../") || value.startsWith("/");
|
|
5887
6192
|
}
|
|
5888
6193
|
|
|
5889
6194
|
// src/internal/executor/executor.ts
|
|
5890
|
-
import { dirname as dirname10, resolve as resolve11 } from "path";
|
|
6195
|
+
import { basename as basename7, dirname as dirname10, resolve as resolve11 } from "path";
|
|
5891
6196
|
|
|
5892
6197
|
// src/internal/utils/hash.ts
|
|
5893
6198
|
import { createHash } from "crypto";
|
|
@@ -6001,8 +6306,9 @@ async function computeResourceHash(address, config, basePath, state) {
|
|
|
6001
6306
|
}
|
|
6002
6307
|
if (address.type === "template") {
|
|
6003
6308
|
const refs = resolveTemplateReferenceIds(decl, config, address.provider, state);
|
|
6004
|
-
return contentHash({ decl, refs });
|
|
6309
|
+
return contentHash({ decl: withoutLocalSessionFileMounts(decl), refs });
|
|
6005
6310
|
}
|
|
6311
|
+
if (address.type === "agent") return contentHash(withoutLocalSessionFileMounts(decl));
|
|
6006
6312
|
if (address.type === "channel") {
|
|
6007
6313
|
const refs = resolveChannelReferenceIds(
|
|
6008
6314
|
decl,
|
|
@@ -6014,6 +6320,12 @@ async function computeResourceHash(address, config, basePath, state) {
|
|
|
6014
6320
|
}
|
|
6015
6321
|
return contentHash(decl);
|
|
6016
6322
|
}
|
|
6323
|
+
function withoutLocalSessionFileMounts(decl) {
|
|
6324
|
+
if (!decl || typeof decl !== "object" || Array.isArray(decl)) return decl;
|
|
6325
|
+
const { files, ...remoteDeclaration } = decl;
|
|
6326
|
+
const templateFiles = Array.isArray(files) ? files.filter((file) => typeof file === "string") : [];
|
|
6327
|
+
return templateFiles.length ? { ...remoteDeclaration, files: templateFiles } : remoteDeclaration;
|
|
6328
|
+
}
|
|
6017
6329
|
function resolveQoderApiMode(type, name, provider, config) {
|
|
6018
6330
|
if (provider !== "qoder") return void 0;
|
|
6019
6331
|
if (type === "environment" && config.environments?.[name]?.environment_id) return "auto";
|
|
@@ -6021,7 +6333,7 @@ function resolveQoderApiMode(type, name, provider, config) {
|
|
|
6021
6333
|
if (agent.provider && agent.provider !== provider) continue;
|
|
6022
6334
|
const referenced = type === "environment" ? agent.environment === name : type === "skill" ? agent.skills?.some(
|
|
6023
6335
|
(skill) => typeof skill === "string" ? skill === name : skill.type === "custom" && skill.skill_id === name
|
|
6024
|
-
) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.
|
|
6336
|
+
) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.some((file) => (typeof file === "string" ? file : file.file) === name);
|
|
6025
6337
|
if (referenced && agent.delivery?.qoder?.type === "forward") return "forward";
|
|
6026
6338
|
}
|
|
6027
6339
|
return "managed";
|
|
@@ -6062,9 +6374,7 @@ function resolveTemplateReferenceIds(decl, config, provider, state) {
|
|
|
6062
6374
|
memory_store_ids: (decl.memory_stores ?? []).map(
|
|
6063
6375
|
(memoryStore) => state?.getResource({ type: "memory_store", name: memoryStore, provider })?.remote_id ?? memoryStore
|
|
6064
6376
|
),
|
|
6065
|
-
file_ids: (decl.files ?? []).map(
|
|
6066
|
-
(file) => state?.getResource({ type: "file", name: file, provider })?.remote_id ?? file
|
|
6067
|
-
),
|
|
6377
|
+
file_ids: (decl.files ?? []).filter((file) => typeof file === "string").map((file) => state?.getResource({ type: "file", name: file, provider })?.remote_id ?? file),
|
|
6068
6378
|
identity_id: decl.memory_stores?.length && config.defaults?.identity ? state?.getResource({ type: "identity", name: config.defaults.identity, provider })?.remote_id : void 0
|
|
6069
6379
|
};
|
|
6070
6380
|
}
|
|
@@ -6254,7 +6564,7 @@ function resolveTemplateRefs(agentName, config, provider, state) {
|
|
|
6254
6564
|
environment_id: environment.environment_id ?? requireRef(state, { type: "environment", name: agent.environment, provider }),
|
|
6255
6565
|
...agent.tunnel ? { tunnel_id: resolveTunnelIdFromConfig(config, agent.tunnel, provider) } : {},
|
|
6256
6566
|
vault_ids: agent.vault ? [requireRef(state, { type: "vault", name: agent.vault, provider })] : [],
|
|
6257
|
-
file_ids: (agent.files ?? []).map((file) => requireRef(state, { type: "file", name: file, provider })),
|
|
6567
|
+
file_ids: (agent.files ?? []).filter((file) => typeof file === "string").map((file) => requireRef(state, { type: "file", name: file, provider })),
|
|
6258
6568
|
memory_store_ids: memoryStoreIds,
|
|
6259
6569
|
owned_memory_store_ids: state.listResources().filter(
|
|
6260
6570
|
(resource) => resource.address.provider === provider && resource.address.type === "memory_store" && resource.api_mode === "forward" && typeof resource.remote_id === "string"
|
|
@@ -6350,8 +6660,61 @@ function resolveTunnelIdFromConfig(config, tunnelName, provider) {
|
|
|
6350
6660
|
}
|
|
6351
6661
|
|
|
6352
6662
|
// src/internal/executor/skill-resolver.ts
|
|
6663
|
+
import { dirname as dirname9 } from "path";
|
|
6664
|
+
|
|
6665
|
+
// src/internal/core/skill-source.ts
|
|
6353
6666
|
import { readFileSync as readFileSync7, statSync as statSync3 } from "fs";
|
|
6354
|
-
import {
|
|
6667
|
+
import { basename as basename6, resolve as resolve10 } from "path";
|
|
6668
|
+
import { parse } from "yaml";
|
|
6669
|
+
async function inspectSkillSource(source, options = {}) {
|
|
6670
|
+
if (/^https?:\/\//i.test(source)) {
|
|
6671
|
+
throw new UserError("Skill source inspection only accepts a local directory, zip, or SKILL.md file.");
|
|
6672
|
+
}
|
|
6673
|
+
const sourcePath = resolve10(options.basePath ?? process.cwd(), source);
|
|
6674
|
+
const sourceStat = statSync3(sourcePath, { throwIfNoEntry: false });
|
|
6675
|
+
if (!sourceStat) throw new UserError(`Skill source not found: ${source}`);
|
|
6676
|
+
let files;
|
|
6677
|
+
if (sourceStat.isDirectory()) {
|
|
6678
|
+
files = collectFiles(sourcePath, "");
|
|
6679
|
+
} else if (sourceStat.isFile() && sourcePath.toLowerCase().endsWith(".zip")) {
|
|
6680
|
+
files = await extractSkillZipFiles(readFileSync7(sourcePath));
|
|
6681
|
+
} else if (sourceStat.isFile() && basename6(sourcePath).toLowerCase() === "skill.md") {
|
|
6682
|
+
files = [{ relativePath: "SKILL.md", content: readFileSync7(sourcePath) }];
|
|
6683
|
+
} else {
|
|
6684
|
+
throw new UserError("Skill source must be a directory, .zip archive, or SKILL.md file.");
|
|
6685
|
+
}
|
|
6686
|
+
const normalizedFiles = normalizeSkillRoot(files);
|
|
6687
|
+
const manifest = normalizedFiles.find((file) => file.relativePath === "SKILL.md");
|
|
6688
|
+
const name = parseSkillManifestName(manifest.content);
|
|
6689
|
+
return { name, sourcePath, files: normalizedFiles };
|
|
6690
|
+
}
|
|
6691
|
+
function normalizeSkillRoot(files) {
|
|
6692
|
+
if (files.some((file) => file.relativePath === "SKILL.md")) return files;
|
|
6693
|
+
const manifests = files.filter((file) => file.relativePath.endsWith("/SKILL.md"));
|
|
6694
|
+
if (manifests.length === 0) throw new UserError("Skill source does not contain SKILL.md.");
|
|
6695
|
+
if (manifests.length > 1) {
|
|
6696
|
+
throw new UserError("Skill source contains multiple SKILL.md files and has no unambiguous root.");
|
|
6697
|
+
}
|
|
6698
|
+
const prefix = manifests[0].relativePath.slice(0, -"SKILL.md".length);
|
|
6699
|
+
return files.filter((file) => file.relativePath.startsWith(prefix)).map((file) => ({ ...file, relativePath: file.relativePath.slice(prefix.length) }));
|
|
6700
|
+
}
|
|
6701
|
+
function parseSkillManifestName(content) {
|
|
6702
|
+
const text = content.toString("utf8");
|
|
6703
|
+
const frontmatter = text.match(/^---\s*\r?\n([\s\S]*?)\r?\n---(?:\s*\r?\n|$)/);
|
|
6704
|
+
if (!frontmatter) throw new UserError("SKILL.md must start with YAML frontmatter containing a name.");
|
|
6705
|
+
let manifest;
|
|
6706
|
+
try {
|
|
6707
|
+
manifest = parse(frontmatter[1]);
|
|
6708
|
+
} catch (error) {
|
|
6709
|
+
throw new UserError(`Invalid SKILL.md frontmatter: ${error instanceof Error ? error.message : String(error)}`);
|
|
6710
|
+
}
|
|
6711
|
+
const rawName = manifest && typeof manifest === "object" ? manifest.name : void 0;
|
|
6712
|
+
const name = typeof rawName === "string" ? rawName.trim() : "";
|
|
6713
|
+
if (!name) throw new UserError("SKILL.md frontmatter must contain a non-empty name.");
|
|
6714
|
+
return name;
|
|
6715
|
+
}
|
|
6716
|
+
|
|
6717
|
+
// src/internal/executor/skill-resolver.ts
|
|
6355
6718
|
async function resolveSkillFiles(decl, ctx) {
|
|
6356
6719
|
if (/^https?:\/\//i.test(decl.source)) {
|
|
6357
6720
|
const res = await resolveFetch()(decl.source);
|
|
@@ -6359,19 +6722,7 @@ async function resolveSkillFiles(decl, ctx) {
|
|
|
6359
6722
|
return extractSkillZipFiles(Buffer.from(await res.arrayBuffer()));
|
|
6360
6723
|
}
|
|
6361
6724
|
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 [];
|
|
6725
|
+
return (await inspectSkillSource(decl.source, { basePath: dirname9(ctx.configPath) })).files;
|
|
6375
6726
|
}
|
|
6376
6727
|
|
|
6377
6728
|
// src/internal/executor/executor.ts
|
|
@@ -6449,7 +6800,9 @@ async function executePlan(plan, ctx, options = {}) {
|
|
|
6449
6800
|
await runWithConcurrency(level, concurrency, runAction);
|
|
6450
6801
|
await ctx.state.save();
|
|
6451
6802
|
}
|
|
6452
|
-
|
|
6803
|
+
if (!ctx.createOnly) {
|
|
6804
|
+
await reconcileDefaultMemoryStores(ctx, new Set(plan.actions.map((action) => action.address.provider)));
|
|
6805
|
+
}
|
|
6453
6806
|
for (const action of deletions) {
|
|
6454
6807
|
await runAction(action);
|
|
6455
6808
|
await ctx.state.save();
|
|
@@ -6661,6 +7014,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6661
7014
|
} catch (err) {
|
|
6662
7015
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6663
7016
|
mode: apiMode,
|
|
7017
|
+
createOnly: ctx.createOnly,
|
|
6664
7018
|
onExisting: (existing) => provider.updateEnvironment(existing.id, remoteName, decl, apiMode)
|
|
6665
7019
|
});
|
|
6666
7020
|
adopted = true;
|
|
@@ -6680,6 +7034,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6680
7034
|
} catch (err) {
|
|
6681
7035
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6682
7036
|
mode: apiMode,
|
|
7037
|
+
createOnly: ctx.createOnly,
|
|
6683
7038
|
onExisting: (existing) => provider.updateEnvironment(existing.id, remoteName, decl, apiMode)
|
|
6684
7039
|
});
|
|
6685
7040
|
adopted = true;
|
|
@@ -6706,6 +7061,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6706
7061
|
} catch (err) {
|
|
6707
7062
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6708
7063
|
mode: apiMode,
|
|
7064
|
+
createOnly: ctx.createOnly,
|
|
6709
7065
|
onExisting: async (existing) => {
|
|
6710
7066
|
await provider.deleteVault(existing.id, apiMode);
|
|
6711
7067
|
return provider.createVault(name, decl, apiMode);
|
|
@@ -6742,6 +7098,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6742
7098
|
const searchNames = manifestName && manifestName !== remoteName ? [remoteName, manifestName] : [remoteName];
|
|
6743
7099
|
const existing = await findExistingByNames(provider, "skill", searchNames, apiMode);
|
|
6744
7100
|
if (existing) {
|
|
7101
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address, existing.name);
|
|
6745
7102
|
result = existing.resource;
|
|
6746
7103
|
emitRuntimeFeedback(ctx.onFeedback, {
|
|
6747
7104
|
type: "resource_adopted",
|
|
@@ -6757,6 +7114,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6757
7114
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6758
7115
|
mode: apiMode,
|
|
6759
7116
|
searchNames,
|
|
7117
|
+
createOnly: ctx.createOnly,
|
|
6760
7118
|
onExisting: async (existing2) => existing2
|
|
6761
7119
|
});
|
|
6762
7120
|
adopted = true;
|
|
@@ -6823,6 +7181,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6823
7181
|
} catch (err) {
|
|
6824
7182
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
6825
7183
|
mode: apiMode,
|
|
7184
|
+
createOnly: ctx.createOnly,
|
|
6826
7185
|
onExisting: async (existing) => reconcile(existing.id)
|
|
6827
7186
|
});
|
|
6828
7187
|
adopted = true;
|
|
@@ -6841,6 +7200,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6841
7200
|
result = await provider.createAgent(remoteName, decl, refs);
|
|
6842
7201
|
} catch (err) {
|
|
6843
7202
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7203
|
+
createOnly: ctx.createOnly,
|
|
6844
7204
|
onExisting: (existing) => provider.updateAgent(existing.id, remoteName, decl, refs)
|
|
6845
7205
|
});
|
|
6846
7206
|
adopted = true;
|
|
@@ -6864,6 +7224,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6864
7224
|
result = await createTemplate(remoteName, decl, refs);
|
|
6865
7225
|
} catch (err) {
|
|
6866
7226
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7227
|
+
createOnly: ctx.createOnly,
|
|
6867
7228
|
onExisting: (existing) => updateTemplate(existing.id, remoteName, decl, refs)
|
|
6868
7229
|
});
|
|
6869
7230
|
adopted = true;
|
|
@@ -6898,6 +7259,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6898
7259
|
result = await createIdentity(name, decl);
|
|
6899
7260
|
} catch (err) {
|
|
6900
7261
|
if (!(err instanceof ConflictError)) throw err;
|
|
7262
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address);
|
|
6901
7263
|
const existing = await provider.findResource("identity", decl.external_id);
|
|
6902
7264
|
if (!existing?.id) throw err;
|
|
6903
7265
|
result = await updateIdentity(existing.id, name, decl);
|
|
@@ -6921,6 +7283,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6921
7283
|
result = await createChannel(name, decl, refs);
|
|
6922
7284
|
} catch (err) {
|
|
6923
7285
|
result = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7286
|
+
createOnly: ctx.createOnly,
|
|
6924
7287
|
onExisting: (existing) => updateChannel(existing.id, name, decl, refs)
|
|
6925
7288
|
});
|
|
6926
7289
|
adopted = true;
|
|
@@ -6940,6 +7303,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6940
7303
|
} catch (err) {
|
|
6941
7304
|
const preparedFiles = err instanceof DeploymentCreateConflictError ? err.preparedFiles : void 0;
|
|
6942
7305
|
const existing = await adoptOnConflict(err, address, provider, ctx.onFeedback, {
|
|
7306
|
+
createOnly: ctx.createOnly,
|
|
6943
7307
|
onExisting: (existing2) => provider.updateDeployment(existing2.id, name, decl, refs, ctx.configPath ?? "", preparedFiles)
|
|
6944
7308
|
});
|
|
6945
7309
|
adopted = true;
|
|
@@ -6951,6 +7315,7 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6951
7315
|
} else {
|
|
6952
7316
|
const existing = hasLocalFileSources ? await findExistingByNames(provider, "deployment", [name]) : null;
|
|
6953
7317
|
if (existing) {
|
|
7318
|
+
if (ctx.createOnly) throw createOnlyExistingResourceError(address, existing.name);
|
|
6954
7319
|
result = await provider.updateDeployment(existing.resource.id, name, decl, refs, ctx.configPath ?? "");
|
|
6955
7320
|
emitRuntimeFeedback(ctx.onFeedback, {
|
|
6956
7321
|
type: "resource_adopted",
|
|
@@ -6977,7 +7342,16 @@ async function executeActionInner(action, provider, ctx) {
|
|
|
6977
7342
|
}
|
|
6978
7343
|
}
|
|
6979
7344
|
}
|
|
6980
|
-
const info = await provider.uploadFile(
|
|
7345
|
+
const info = await provider.uploadFile(
|
|
7346
|
+
filePath,
|
|
7347
|
+
{
|
|
7348
|
+
// Keep the source filename and extension; a declaration label must not
|
|
7349
|
+
// change the multipart filename or the provider's inferred MIME type.
|
|
7350
|
+
name: basename7(filePath),
|
|
7351
|
+
purpose: decl.purpose
|
|
7352
|
+
},
|
|
7353
|
+
apiMode
|
|
7354
|
+
);
|
|
6981
7355
|
result = { id: info.id, type: "file" };
|
|
6982
7356
|
break;
|
|
6983
7357
|
}
|
|
@@ -7029,7 +7403,7 @@ function resolveResourceApiMode(type, name, provider, config) {
|
|
|
7029
7403
|
if (agent.provider && agent.provider !== provider) continue;
|
|
7030
7404
|
const referenced = type === "environment" ? agent.environment === name : type === "skill" ? agent.skills?.some(
|
|
7031
7405
|
(skill) => typeof skill === "string" ? skill === name : skill.type === "custom" && skill.skill_id === name
|
|
7032
|
-
) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.
|
|
7406
|
+
) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.some((file) => (typeof file === "string" ? file : file.file) === name);
|
|
7033
7407
|
if (!referenced) continue;
|
|
7034
7408
|
if (agent.delivery?.qoder?.type === "forward") forward = true;
|
|
7035
7409
|
else managed = true;
|
|
@@ -7051,6 +7425,7 @@ async function findExistingByNames(provider, type, names, mode) {
|
|
|
7051
7425
|
async function adoptOnConflict(err, address, provider, onFeedback, opts) {
|
|
7052
7426
|
if (!(err instanceof ConflictError)) throw err;
|
|
7053
7427
|
const candidates = opts.searchNames?.length ? opts.searchNames : [address.name];
|
|
7428
|
+
if (opts.createOnly) throw createOnlyExistingResourceError(address, candidates.join('" / "'));
|
|
7054
7429
|
const existing = await findExistingByNames(provider, address.type, candidates, opts.mode);
|
|
7055
7430
|
if (!existing) throw nameReservedError(err, address, candidates.join('" / "'));
|
|
7056
7431
|
emitRuntimeFeedback(onFeedback, {
|
|
@@ -7061,6 +7436,11 @@ async function adoptOnConflict(err, address, provider, onFeedback, opts) {
|
|
|
7061
7436
|
});
|
|
7062
7437
|
return opts.onExisting(existing.resource);
|
|
7063
7438
|
}
|
|
7439
|
+
function createOnlyExistingResourceError(address, remoteName = address.name) {
|
|
7440
|
+
return new UserError(
|
|
7441
|
+
`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.`
|
|
7442
|
+
);
|
|
7443
|
+
}
|
|
7064
7444
|
function nameReservedError(err, address, searchName) {
|
|
7065
7445
|
const detail = err instanceof ApiError ? err.message : String(err);
|
|
7066
7446
|
if (address.type === "channel" && err instanceof ApiError && err.responseBody.includes("CHANNEL_CREDENTIAL_CONFLICT")) {
|
|
@@ -7073,73 +7453,6 @@ function nameReservedError(err, address, searchName) {
|
|
|
7073
7453
|
);
|
|
7074
7454
|
}
|
|
7075
7455
|
|
|
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
7456
|
// src/internal/core/agent-materialization.ts
|
|
7144
7457
|
function resolveAgentMaterialization(provider, agent) {
|
|
7145
7458
|
const mode = agent.delivery?.[provider]?.type ?? "managed";
|
|
@@ -7147,7 +7460,298 @@ function resolveAgentMaterialization(provider, agent) {
|
|
|
7147
7460
|
return { resourceType: "template", mode };
|
|
7148
7461
|
}
|
|
7149
7462
|
|
|
7150
|
-
// src/internal/
|
|
7463
|
+
// src/internal/graph/dependency.ts
|
|
7464
|
+
function collectDependencyClosure(graph, roots) {
|
|
7465
|
+
const selected = /* @__PURE__ */ new Map();
|
|
7466
|
+
function visit2(address) {
|
|
7467
|
+
const key = addressKey(address);
|
|
7468
|
+
if (selected.has(key)) return;
|
|
7469
|
+
selected.set(key, graph.nodes.get(key) ?? address);
|
|
7470
|
+
for (const dependencyKey of graph.edges.get(key) ?? []) {
|
|
7471
|
+
const dependency = graph.nodes.get(dependencyKey);
|
|
7472
|
+
if (dependency) visit2(dependency);
|
|
7473
|
+
}
|
|
7474
|
+
}
|
|
7475
|
+
for (const root of roots) visit2(root);
|
|
7476
|
+
return [...selected.values()];
|
|
7477
|
+
}
|
|
7478
|
+
function buildDependencyGraph(config, targetProviders) {
|
|
7479
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
7480
|
+
const edges = /* @__PURE__ */ new Map();
|
|
7481
|
+
function addNode(addr) {
|
|
7482
|
+
const key = addressKey(addr);
|
|
7483
|
+
nodes.set(key, addr);
|
|
7484
|
+
if (!edges.has(key)) edges.set(key, /* @__PURE__ */ new Set());
|
|
7485
|
+
}
|
|
7486
|
+
function addEdge(from, to) {
|
|
7487
|
+
const fromKey = addressKey(from);
|
|
7488
|
+
const toKey = addressKey(to);
|
|
7489
|
+
edges.get(fromKey)?.add(toKey);
|
|
7490
|
+
}
|
|
7491
|
+
for (const provider of targetProviders) {
|
|
7492
|
+
const def = getProvider(provider);
|
|
7493
|
+
const caps = def?.capabilities;
|
|
7494
|
+
if (config.environments) {
|
|
7495
|
+
for (const name of Object.keys(config.environments)) {
|
|
7496
|
+
const decl = config.environments[name];
|
|
7497
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7498
|
+
addNode({ type: "environment", name, provider });
|
|
7499
|
+
}
|
|
7500
|
+
}
|
|
7501
|
+
if (config.memory_stores) {
|
|
7502
|
+
for (const name of Object.keys(config.memory_stores)) {
|
|
7503
|
+
const decl = config.memory_stores[name];
|
|
7504
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7505
|
+
if (!isSupported(caps, "memory_store")) continue;
|
|
7506
|
+
addNode({ type: "memory_store", name, provider });
|
|
7507
|
+
}
|
|
7508
|
+
}
|
|
7509
|
+
if (config.vaults) {
|
|
7510
|
+
for (const name of Object.keys(config.vaults)) {
|
|
7511
|
+
const decl = config.vaults[name];
|
|
7512
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7513
|
+
addNode({ type: "vault", name, provider });
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
if (config.skills) {
|
|
7517
|
+
for (const name of Object.keys(config.skills)) {
|
|
7518
|
+
const decl = config.skills[name];
|
|
7519
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7520
|
+
addNode({ type: "skill", name, provider });
|
|
7521
|
+
}
|
|
7522
|
+
}
|
|
7523
|
+
if (config.files) {
|
|
7524
|
+
for (const name of Object.keys(config.files)) {
|
|
7525
|
+
const decl = config.files[name];
|
|
7526
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7527
|
+
addNode({ type: "file", name, provider });
|
|
7528
|
+
}
|
|
7529
|
+
}
|
|
7530
|
+
if (config.identities && isSupported(caps, "identity")) {
|
|
7531
|
+
for (const name of Object.keys(config.identities)) {
|
|
7532
|
+
const decl = config.identities[name];
|
|
7533
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7534
|
+
addNode({ type: "identity", name, provider });
|
|
7535
|
+
}
|
|
7536
|
+
}
|
|
7537
|
+
if (config.agents) {
|
|
7538
|
+
for (const name of Object.keys(config.agents)) {
|
|
7539
|
+
const decl = config.agents[name];
|
|
7540
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7541
|
+
const materialization = resolveAgentMaterialization(provider, decl);
|
|
7542
|
+
const agentAddr = { type: materialization.resourceType, name, provider };
|
|
7543
|
+
addNode(agentAddr);
|
|
7544
|
+
if ((decl.default_memory_store || decl.memory_stores?.length) && materialization.resourceType === "template") {
|
|
7545
|
+
const identityName = config.defaults?.identity;
|
|
7546
|
+
if (identityName) {
|
|
7547
|
+
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7548
|
+
if (nodes.has(addressKey(identityAddr))) addEdge(agentAddr, identityAddr);
|
|
7549
|
+
}
|
|
7550
|
+
}
|
|
7551
|
+
if (decl.environment && config.environments?.[decl.environment]) {
|
|
7552
|
+
const envAddr = {
|
|
7553
|
+
type: "environment",
|
|
7554
|
+
name: decl.environment,
|
|
7555
|
+
provider
|
|
7556
|
+
};
|
|
7557
|
+
if (nodes.has(addressKey(envAddr))) {
|
|
7558
|
+
addEdge(agentAddr, envAddr);
|
|
7559
|
+
}
|
|
7560
|
+
}
|
|
7561
|
+
if (decl.skills) {
|
|
7562
|
+
for (const skillRef of decl.skills) {
|
|
7563
|
+
if (typeof skillRef !== "string") continue;
|
|
7564
|
+
const skillName = skillRef;
|
|
7565
|
+
const skillAddr = { type: "skill", name: skillName, provider };
|
|
7566
|
+
if (nodes.has(addressKey(skillAddr))) {
|
|
7567
|
+
addEdge(agentAddr, skillAddr);
|
|
7568
|
+
}
|
|
7569
|
+
}
|
|
7570
|
+
}
|
|
7571
|
+
if (decl.vault) {
|
|
7572
|
+
const vaultAddr = { type: "vault", name: decl.vault, provider };
|
|
7573
|
+
if (nodes.has(addressKey(vaultAddr))) {
|
|
7574
|
+
addEdge(agentAddr, vaultAddr);
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7577
|
+
if (decl.files) {
|
|
7578
|
+
for (const file of decl.files) {
|
|
7579
|
+
const fileName = typeof file === "string" ? file : file.file;
|
|
7580
|
+
const fileAddr = { type: "file", name: fileName, provider };
|
|
7581
|
+
if (nodes.has(addressKey(fileAddr))) addEdge(agentAddr, fileAddr);
|
|
7582
|
+
}
|
|
7583
|
+
}
|
|
7584
|
+
if (decl.memory_stores) {
|
|
7585
|
+
for (const msName of decl.memory_stores) {
|
|
7586
|
+
const msAddr = {
|
|
7587
|
+
type: "memory_store",
|
|
7588
|
+
name: msName,
|
|
7589
|
+
provider
|
|
7590
|
+
};
|
|
7591
|
+
if (nodes.has(addressKey(msAddr))) {
|
|
7592
|
+
addEdge(agentAddr, msAddr);
|
|
7593
|
+
}
|
|
7594
|
+
}
|
|
7595
|
+
}
|
|
7596
|
+
if (decl.multiagent && isSupported(caps, "multiagent")) {
|
|
7597
|
+
for (const subName of decl.multiagent.agents) {
|
|
7598
|
+
const subDecl = config.agents[subName];
|
|
7599
|
+
const subType = subDecl ? resolveAgentMaterialization(provider, subDecl).resourceType : "agent";
|
|
7600
|
+
const subAddr = { type: subType, name: subName, provider };
|
|
7601
|
+
addEdge(agentAddr, subAddr);
|
|
7602
|
+
}
|
|
7603
|
+
}
|
|
7604
|
+
}
|
|
7605
|
+
}
|
|
7606
|
+
if (config.deployments) {
|
|
7607
|
+
for (const name of Object.keys(config.deployments)) {
|
|
7608
|
+
const decl = config.deployments[name];
|
|
7609
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7610
|
+
const depAddr = { type: "deployment", name, provider };
|
|
7611
|
+
addNode(depAddr);
|
|
7612
|
+
const agentDecl = config.agents?.[decl.agent];
|
|
7613
|
+
const agentType = agentDecl ? resolveAgentMaterialization(provider, agentDecl).resourceType : "agent";
|
|
7614
|
+
const agentAddr = { type: agentType, name: decl.agent, provider };
|
|
7615
|
+
if (nodes.has(addressKey(agentAddr))) addEdge(depAddr, agentAddr);
|
|
7616
|
+
if (decl.environment) {
|
|
7617
|
+
const envAddr = { type: "environment", name: decl.environment, provider };
|
|
7618
|
+
if (nodes.has(addressKey(envAddr))) addEdge(depAddr, envAddr);
|
|
7619
|
+
}
|
|
7620
|
+
if (decl.vaults) {
|
|
7621
|
+
for (const vName of decl.vaults) {
|
|
7622
|
+
const vAddr = { type: "vault", name: vName, provider };
|
|
7623
|
+
if (nodes.has(addressKey(vAddr))) addEdge(depAddr, vAddr);
|
|
7624
|
+
}
|
|
7625
|
+
}
|
|
7626
|
+
if (decl.memory_stores) {
|
|
7627
|
+
for (const msName of decl.memory_stores) {
|
|
7628
|
+
const msAddr = { type: "memory_store", name: msName, provider };
|
|
7629
|
+
if (nodes.has(addressKey(msAddr))) addEdge(depAddr, msAddr);
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
if (decl.resources) {
|
|
7633
|
+
for (const r of decl.resources) {
|
|
7634
|
+
if (r.type === "memory_store") {
|
|
7635
|
+
const msAddr = { type: "memory_store", name: r.memory_store, provider };
|
|
7636
|
+
if (nodes.has(addressKey(msAddr))) addEdge(depAddr, msAddr);
|
|
7637
|
+
}
|
|
7638
|
+
}
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
}
|
|
7642
|
+
if (config.channels && isSupported(caps, "channel")) {
|
|
7643
|
+
for (const name of Object.keys(config.channels)) {
|
|
7644
|
+
const decl = config.channels[name];
|
|
7645
|
+
if (decl.provider && decl.provider !== provider) continue;
|
|
7646
|
+
const channelAddr = { type: "channel", name, provider };
|
|
7647
|
+
addNode(channelAddr);
|
|
7648
|
+
if (decl.mode === "pairing" || !decl.agent) continue;
|
|
7649
|
+
const agentDecl = config.agents?.[decl.agent];
|
|
7650
|
+
const agentType = agentDecl ? resolveAgentMaterialization(provider, agentDecl).resourceType : "agent";
|
|
7651
|
+
const agentAddr = { type: agentType, name: decl.agent, provider };
|
|
7652
|
+
if (nodes.has(addressKey(agentAddr))) addEdge(channelAddr, agentAddr);
|
|
7653
|
+
const identityName = decl.identity ?? config.defaults?.identity;
|
|
7654
|
+
if (identityName) {
|
|
7655
|
+
const identityAddr = { type: "identity", name: identityName, provider };
|
|
7656
|
+
if (nodes.has(addressKey(identityAddr))) addEdge(channelAddr, identityAddr);
|
|
7657
|
+
}
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
}
|
|
7661
|
+
return { nodes, edges };
|
|
7662
|
+
}
|
|
7663
|
+
function topologicalSort(graph) {
|
|
7664
|
+
const visited = /* @__PURE__ */ new Set();
|
|
7665
|
+
const sorted = [];
|
|
7666
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
7667
|
+
function visit2(key) {
|
|
7668
|
+
if (visited.has(key)) return;
|
|
7669
|
+
if (visiting.has(key)) {
|
|
7670
|
+
throw new UserError(`Circular dependency detected involving: ${key}`);
|
|
7671
|
+
}
|
|
7672
|
+
visiting.add(key);
|
|
7673
|
+
const deps = graph.edges.get(key) ?? /* @__PURE__ */ new Set();
|
|
7674
|
+
for (const dep of deps) {
|
|
7675
|
+
visit2(dep);
|
|
7676
|
+
}
|
|
7677
|
+
visiting.delete(key);
|
|
7678
|
+
visited.add(key);
|
|
7679
|
+
sorted.push(graph.nodes.get(key));
|
|
7680
|
+
}
|
|
7681
|
+
for (const key of graph.nodes.keys()) {
|
|
7682
|
+
visit2(key);
|
|
7683
|
+
}
|
|
7684
|
+
return sorted;
|
|
7685
|
+
}
|
|
7686
|
+
|
|
7687
|
+
// src/internal/diagnostics/diagnostics.ts
|
|
7688
|
+
var DiagnosticCollector = class {
|
|
7689
|
+
items = [];
|
|
7690
|
+
error(code, message, resource) {
|
|
7691
|
+
this.items.push({ severity: "error", code, message, resource });
|
|
7692
|
+
}
|
|
7693
|
+
warning(code, message, resource) {
|
|
7694
|
+
this.items.push({ severity: "warning", code, message, resource });
|
|
7695
|
+
}
|
|
7696
|
+
info(code, message, resource) {
|
|
7697
|
+
this.items.push({ severity: "info", code, message, resource });
|
|
7698
|
+
}
|
|
7699
|
+
hasErrors() {
|
|
7700
|
+
return this.items.some((d) => d.severity === "error");
|
|
7701
|
+
}
|
|
7702
|
+
getAll() {
|
|
7703
|
+
return [...this.items];
|
|
7704
|
+
}
|
|
7705
|
+
format() {
|
|
7706
|
+
if (this.items.length === 0) return "";
|
|
7707
|
+
const lines = [];
|
|
7708
|
+
for (const d of this.items) {
|
|
7709
|
+
const icon = severityIcon(d.severity);
|
|
7710
|
+
const addr = d.resource ? ` ${d.resource.type}.${d.resource.name} (${d.resource.provider})` : "";
|
|
7711
|
+
lines.push(`${icon} ${d.code}`);
|
|
7712
|
+
if (addr) lines.push(` Resource:${addr}`);
|
|
7713
|
+
lines.push(` ${d.message}`);
|
|
7714
|
+
lines.push("");
|
|
7715
|
+
}
|
|
7716
|
+
return lines.join("\n");
|
|
7717
|
+
}
|
|
7718
|
+
};
|
|
7719
|
+
function severityIcon(s) {
|
|
7720
|
+
switch (s) {
|
|
7721
|
+
case "error":
|
|
7722
|
+
return "\u2717";
|
|
7723
|
+
case "warning":
|
|
7724
|
+
return "\u26A0";
|
|
7725
|
+
case "info":
|
|
7726
|
+
return "\u2139";
|
|
7727
|
+
}
|
|
7728
|
+
}
|
|
7729
|
+
|
|
7730
|
+
// src/internal/validation/bailian.ts
|
|
7731
|
+
function findMissingBailianMcpToolConfigs(config, providerName = "bailian") {
|
|
7732
|
+
if (providerName !== "bailian") return [];
|
|
7733
|
+
const missing = [];
|
|
7734
|
+
for (const [agentName, agent] of Object.entries(config.agents ?? {})) {
|
|
7735
|
+
if (!agentTargetsProvider(config, agent.provider, providerName)) continue;
|
|
7736
|
+
const configuredToolServers = new Set((agent.tools?.mcp ?? []).map((tool) => tool.mcp_server_name));
|
|
7737
|
+
for (const server of agent.mcp_servers ?? []) {
|
|
7738
|
+
if (!configuredToolServers.has(server.name)) {
|
|
7739
|
+
missing.push({ agentName, serverName: server.name });
|
|
7740
|
+
}
|
|
7741
|
+
}
|
|
7742
|
+
}
|
|
7743
|
+
return missing;
|
|
7744
|
+
}
|
|
7745
|
+
function agentTargetsProvider(config, agentProvider, providerName) {
|
|
7746
|
+
if (agentProvider) return agentProvider === providerName;
|
|
7747
|
+
const defaultProvider = config.defaults?.provider;
|
|
7748
|
+
if (defaultProvider && defaultProvider !== "all") {
|
|
7749
|
+
return defaultProvider === providerName;
|
|
7750
|
+
}
|
|
7751
|
+
return Object.hasOwn(config.providers, providerName);
|
|
7752
|
+
}
|
|
7753
|
+
|
|
7754
|
+
// src/internal/core/validate-config.ts
|
|
7151
7755
|
function validateProjectConfig(config, options = {}) {
|
|
7152
7756
|
const collector = new DiagnosticCollector();
|
|
7153
7757
|
collectReferenceDiagnostics(config, collector);
|
|
@@ -7202,8 +7806,9 @@ function collectReferenceDiagnostics(config, diagnostics) {
|
|
|
7202
7806
|
diagnostics.error("config.agent.vault.unknown", `agent.${name}: references unknown vault '${agent.vault}'`);
|
|
7203
7807
|
}
|
|
7204
7808
|
for (const file of agent.files ?? []) {
|
|
7205
|
-
|
|
7206
|
-
|
|
7809
|
+
const fileName = typeof file === "string" ? file : file.file;
|
|
7810
|
+
if (!fileNames.has(fileName)) {
|
|
7811
|
+
diagnostics.error("config.agent.file.unknown", `agent.${name}: references unknown file '${fileName}'`);
|
|
7207
7812
|
}
|
|
7208
7813
|
}
|
|
7209
7814
|
for (const memory of agent.memory_stores ?? []) {
|
|
@@ -7268,6 +7873,16 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7268
7873
|
continue;
|
|
7269
7874
|
}
|
|
7270
7875
|
const caps = def.capabilities;
|
|
7876
|
+
for (const [name, vault] of Object.entries(config.vaults ?? {})) {
|
|
7877
|
+
if (vault.provider && vault.provider !== providerName) continue;
|
|
7878
|
+
if (providerName !== "bailian" && vault.credentials.some((credential) => credential.injection_location !== void 0)) {
|
|
7879
|
+
diagnostics.error(
|
|
7880
|
+
`${providerName}.vault.injection_location.unsupported`,
|
|
7881
|
+
`vault.${name}: provider '${providerName}' does not support credential injection_location; pin this vault to bailian.`,
|
|
7882
|
+
{ type: "vault", name, provider: providerName }
|
|
7883
|
+
);
|
|
7884
|
+
}
|
|
7885
|
+
}
|
|
7271
7886
|
for (const [name, environment] of Object.entries(config.environments ?? {})) {
|
|
7272
7887
|
if (environment.provider && environment.provider !== providerName) continue;
|
|
7273
7888
|
if (environment.environment_id) continue;
|
|
@@ -7387,7 +8002,7 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7387
8002
|
),
|
|
7388
8003
|
...agent.vault ? [`vault:${agent.vault}`] : [],
|
|
7389
8004
|
...(agent.memory_stores ?? []).map((store) => `memory_store:${store}`),
|
|
7390
|
-
...(agent.files ?? []).map((file) => `file:${file}`)
|
|
8005
|
+
...(agent.files ?? []).map((file) => `file:${typeof file === "string" ? file : file.file}`)
|
|
7391
8006
|
];
|
|
7392
8007
|
for (const ref of refs) {
|
|
7393
8008
|
const modes = domains.get(ref) ?? /* @__PURE__ */ new Set();
|
|
@@ -7407,7 +8022,7 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7407
8022
|
}
|
|
7408
8023
|
for (const [name, agent] of Object.entries(config.agents ?? {})) {
|
|
7409
8024
|
if (agent.provider && agent.provider !== providerName) continue;
|
|
7410
|
-
if (agent.files?.
|
|
8025
|
+
if (agent.files?.some((file) => typeof file === "string") && (providerName !== "qoder" || agent.delivery?.qoder?.type !== "forward")) {
|
|
7411
8026
|
diagnostics.error(
|
|
7412
8027
|
"config.agent.files.unsupported",
|
|
7413
8028
|
`agent.${name}: files are supported only by Qoder Forward Templates.`,
|
|
@@ -7431,6 +8046,30 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7431
8046
|
address
|
|
7432
8047
|
);
|
|
7433
8048
|
}
|
|
8049
|
+
const normalizedFileMountPaths = /* @__PURE__ */ new Set();
|
|
8050
|
+
for (const file of agent.files ?? []) {
|
|
8051
|
+
if (typeof file === "string") continue;
|
|
8052
|
+
let normalizedMountPath;
|
|
8053
|
+
try {
|
|
8054
|
+
normalizedMountPath = resolveSandboxMountPath(providerName, file.mount_path);
|
|
8055
|
+
} catch (error) {
|
|
8056
|
+
diagnostics.error(
|
|
8057
|
+
`${providerName}.agent.file.mount_path.invalid`,
|
|
8058
|
+
`agent.${name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
8059
|
+
address
|
|
8060
|
+
);
|
|
8061
|
+
continue;
|
|
8062
|
+
}
|
|
8063
|
+
if (normalizedFileMountPaths.has(normalizedMountPath)) {
|
|
8064
|
+
diagnostics.error(
|
|
8065
|
+
`${providerName}.agent.file.mount_path.duplicate`,
|
|
8066
|
+
`agent.${name}: file mount_path '${normalizedMountPath}' is duplicated after normalization.`,
|
|
8067
|
+
address
|
|
8068
|
+
);
|
|
8069
|
+
} else {
|
|
8070
|
+
normalizedFileMountPaths.add(normalizedMountPath);
|
|
8071
|
+
}
|
|
8072
|
+
}
|
|
7434
8073
|
for (const resource of agent.resources ?? []) {
|
|
7435
8074
|
if (!def.features.session_resources.includes(resource.type)) {
|
|
7436
8075
|
diagnostics.error(
|
|
@@ -7591,370 +8230,164 @@ function collectProviderCapabilities(config, providers, diagnostics) {
|
|
|
7591
8230
|
`${providerName}.deployment.file.mount_path.invalid`,
|
|
7592
8231
|
`deployment.${name}: Bailian file mount_path must start with '${mountPrefix}/'.`,
|
|
7593
8232
|
addr
|
|
7594
|
-
);
|
|
7595
|
-
continue;
|
|
7596
|
-
}
|
|
7597
|
-
const normalizedMountPath = resolveSandboxMountPath(providerName, resource.mount_path);
|
|
7598
|
-
if (normalizedMountPaths.has(normalizedMountPath)) {
|
|
7599
|
-
diagnostics.error(
|
|
7600
|
-
`${providerName}.deployment.file.mount_path.duplicate`,
|
|
7601
|
-
`deployment.${name}: Bailian file mount_path '${normalizedMountPath}' is duplicated after normalization.`,
|
|
7602
|
-
addr
|
|
7603
|
-
);
|
|
7604
|
-
} else {
|
|
7605
|
-
normalizedMountPaths.add(normalizedMountPath);
|
|
7606
|
-
}
|
|
7607
|
-
}
|
|
7608
|
-
}
|
|
7609
|
-
}
|
|
7610
|
-
if (providerName !== "qoder") {
|
|
7611
|
-
for (const [name, env] of Object.entries(config.environments ?? {})) {
|
|
7612
|
-
if (env.environment_id) continue;
|
|
7613
|
-
if (env.config.type === "self_hosted" && (!env.provider || env.provider === providerName)) {
|
|
7614
|
-
diagnostics.error(
|
|
7615
|
-
`${providerName}.environment.self_hosted.unsupported`,
|
|
7616
|
-
`environment.${name}: self_hosted environments are supported only by Qoder BYOC; use type 'cloud' or pin this environment to the qoder provider.`,
|
|
7617
|
-
{ type: "environment", name, provider: providerName }
|
|
7618
|
-
);
|
|
7619
|
-
}
|
|
7620
|
-
}
|
|
7621
|
-
for (const [name, agent] of Object.entries(config.agents ?? {})) {
|
|
7622
|
-
if (agent.environment_variables && (!agent.provider || agent.provider === providerName)) {
|
|
7623
|
-
diagnostics.error(
|
|
7624
|
-
`${providerName}.agent.environment_variables.unsupported`,
|
|
7625
|
-
`agent.${name}: environment_variables is supported only by Qoder; remove it or pin this agent to qoder.`,
|
|
7626
|
-
{ type: "agent", name, provider: providerName }
|
|
7627
|
-
);
|
|
7628
|
-
}
|
|
7629
|
-
if (agent.managed_tool_config && (!agent.provider || agent.provider === providerName)) {
|
|
7630
|
-
diagnostics.error(
|
|
7631
|
-
`${providerName}.agent.managed_tool_config.unsupported`,
|
|
7632
|
-
`agent.${name}: managed_tool_config is supported only by Qoder; remove it or pin this agent to qoder.`,
|
|
7633
|
-
{ type: "agent", name, provider: providerName }
|
|
7634
|
-
);
|
|
7635
|
-
}
|
|
7636
|
-
if (agent.tunnel && (!agent.provider || agent.provider === providerName)) {
|
|
7637
|
-
diagnostics.error(
|
|
7638
|
-
`${providerName}.agent.tunnel.unsupported`,
|
|
7639
|
-
"Tunnels are supported only by Qoder BYOC sessions.",
|
|
7640
|
-
{ type: "agent", name, provider: providerName }
|
|
7641
|
-
);
|
|
7642
|
-
}
|
|
7643
|
-
}
|
|
7644
|
-
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
7645
|
-
if (deployment.provider && deployment.provider !== providerName) continue;
|
|
7646
|
-
if (deployment.environment_variables !== void 0) {
|
|
7647
|
-
diagnostics.error(
|
|
7648
|
-
`${providerName}.deployment.environment_variables.unsupported`,
|
|
7649
|
-
`deployment.${name}: environment_variables is supported only by Qoder deployments; remove it or pin this deployment to the qoder provider.`,
|
|
7650
|
-
{ type: "deployment", name, provider: providerName }
|
|
7651
|
-
);
|
|
7652
|
-
}
|
|
7653
|
-
if (deployment.tunnel && (!deployment.provider || deployment.provider === providerName)) {
|
|
7654
|
-
diagnostics.error(
|
|
7655
|
-
`${providerName}.deployment.tunnel.unsupported`,
|
|
7656
|
-
"Tunnels are supported only by Qoder BYOC sessions.",
|
|
7657
|
-
{ type: "deployment", name, provider: providerName }
|
|
7658
|
-
);
|
|
7659
|
-
}
|
|
7660
|
-
}
|
|
7661
|
-
}
|
|
7662
|
-
for (const missing of findMissingBailianMcpToolConfigs(config, providerName)) {
|
|
7663
|
-
diagnostics.error(
|
|
7664
|
-
`${providerName}.agent.mcp_toolkit_missing`,
|
|
7665
|
-
`Bailian MCP server '${missing.serverName}' requires a matching tools.mcp entry.`,
|
|
7666
|
-
{ type: "agent", name: missing.agentName, provider: providerName }
|
|
7667
|
-
);
|
|
7668
|
-
}
|
|
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
|
-
}
|
|
8233
|
+
);
|
|
8234
|
+
continue;
|
|
7850
8235
|
}
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
8236
|
+
const normalizedMountPath = resolveSandboxMountPath(providerName, resource.mount_path);
|
|
8237
|
+
if (normalizedMountPaths.has(normalizedMountPath)) {
|
|
8238
|
+
diagnostics.error(
|
|
8239
|
+
`${providerName}.deployment.file.mount_path.duplicate`,
|
|
8240
|
+
`deployment.${name}: Bailian file mount_path '${normalizedMountPath}' is duplicated after normalization.`,
|
|
8241
|
+
addr
|
|
8242
|
+
);
|
|
8243
|
+
} else {
|
|
8244
|
+
normalizedMountPaths.add(normalizedMountPath);
|
|
7858
8245
|
}
|
|
7859
8246
|
}
|
|
7860
8247
|
}
|
|
7861
8248
|
}
|
|
7862
|
-
if (
|
|
7863
|
-
for (const name of Object.
|
|
7864
|
-
|
|
7865
|
-
if (
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
if (nodes.has(addressKey(agentAddr))) addEdge(depAddr, agentAddr);
|
|
7872
|
-
if (decl.environment) {
|
|
7873
|
-
const envAddr = { type: "environment", name: decl.environment, provider };
|
|
7874
|
-
if (nodes.has(addressKey(envAddr))) addEdge(depAddr, envAddr);
|
|
8249
|
+
if (providerName !== "qoder") {
|
|
8250
|
+
for (const [name, env] of Object.entries(config.environments ?? {})) {
|
|
8251
|
+
if (env.environment_id) continue;
|
|
8252
|
+
if (env.config.type === "self_hosted" && (!env.provider || env.provider === providerName)) {
|
|
8253
|
+
diagnostics.error(
|
|
8254
|
+
`${providerName}.environment.self_hosted.unsupported`,
|
|
8255
|
+
`environment.${name}: self_hosted environments are supported only by Qoder BYOC; use type 'cloud' or pin this environment to the qoder provider.`,
|
|
8256
|
+
{ type: "environment", name, provider: providerName }
|
|
8257
|
+
);
|
|
7875
8258
|
}
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
8259
|
+
}
|
|
8260
|
+
for (const [name, agent] of Object.entries(config.agents ?? {})) {
|
|
8261
|
+
if (agent.environment_variables && (!agent.provider || agent.provider === providerName)) {
|
|
8262
|
+
diagnostics.error(
|
|
8263
|
+
`${providerName}.agent.environment_variables.unsupported`,
|
|
8264
|
+
`agent.${name}: environment_variables is supported only by Qoder; remove it or pin this agent to qoder.`,
|
|
8265
|
+
{ type: "agent", name, provider: providerName }
|
|
8266
|
+
);
|
|
7881
8267
|
}
|
|
7882
|
-
if (
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
8268
|
+
if (agent.managed_tool_config && (!agent.provider || agent.provider === providerName)) {
|
|
8269
|
+
diagnostics.error(
|
|
8270
|
+
`${providerName}.agent.managed_tool_config.unsupported`,
|
|
8271
|
+
`agent.${name}: managed_tool_config is supported only by Qoder; remove it or pin this agent to qoder.`,
|
|
8272
|
+
{ type: "agent", name, provider: providerName }
|
|
8273
|
+
);
|
|
7887
8274
|
}
|
|
7888
|
-
if (
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
8275
|
+
if (agent.tunnel && (!agent.provider || agent.provider === providerName)) {
|
|
8276
|
+
diagnostics.error(
|
|
8277
|
+
`${providerName}.agent.tunnel.unsupported`,
|
|
8278
|
+
"Tunnels are supported only by Qoder BYOC sessions.",
|
|
8279
|
+
{ type: "agent", name, provider: providerName }
|
|
8280
|
+
);
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
for (const [name, deployment] of Object.entries(config.deployments ?? {})) {
|
|
8284
|
+
if (deployment.provider && deployment.provider !== providerName) continue;
|
|
8285
|
+
if (deployment.environment_variables !== void 0) {
|
|
8286
|
+
diagnostics.error(
|
|
8287
|
+
`${providerName}.deployment.environment_variables.unsupported`,
|
|
8288
|
+
`deployment.${name}: environment_variables is supported only by Qoder deployments; remove it or pin this deployment to the qoder provider.`,
|
|
8289
|
+
{ type: "deployment", name, provider: providerName }
|
|
8290
|
+
);
|
|
8291
|
+
}
|
|
8292
|
+
if (deployment.tunnel && (!deployment.provider || deployment.provider === providerName)) {
|
|
8293
|
+
diagnostics.error(
|
|
8294
|
+
`${providerName}.deployment.tunnel.unsupported`,
|
|
8295
|
+
"Tunnels are supported only by Qoder BYOC sessions.",
|
|
8296
|
+
{ type: "deployment", name, provider: providerName }
|
|
8297
|
+
);
|
|
7895
8298
|
}
|
|
7896
8299
|
}
|
|
7897
8300
|
}
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
8301
|
+
for (const missing of findMissingBailianMcpToolConfigs(config, providerName)) {
|
|
8302
|
+
diagnostics.error(
|
|
8303
|
+
`${providerName}.agent.mcp_toolkit_missing`,
|
|
8304
|
+
`Bailian MCP server '${missing.serverName}' requires a matching tools.mcp entry.`,
|
|
8305
|
+
{ type: "agent", name: missing.agentName, provider: providerName }
|
|
8306
|
+
);
|
|
8307
|
+
}
|
|
8308
|
+
if (config.memory_stores && !isSupported(caps, "memory_store")) {
|
|
8309
|
+
for (const [name, decl] of Object.entries(config.memory_stores)) {
|
|
8310
|
+
if (!decl.provider || decl.provider === providerName) {
|
|
8311
|
+
diagnostics.error(
|
|
8312
|
+
`${providerName}.memory_store.unsupported`,
|
|
8313
|
+
`${caps.memory_store.reason}. ${caps.memory_store.remediation ?? ""}`.trim(),
|
|
8314
|
+
{ type: "memory_store", name, provider: providerName }
|
|
8315
|
+
);
|
|
7913
8316
|
}
|
|
7914
8317
|
}
|
|
7915
8318
|
}
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
8319
|
+
if (config.agents && !isSupported(caps, "multiagent")) {
|
|
8320
|
+
for (const [name, agent] of Object.entries(config.agents)) {
|
|
8321
|
+
if (agent.multiagent) {
|
|
8322
|
+
if (!agent.provider || agent.provider === providerName) {
|
|
8323
|
+
diagnostics.error(
|
|
8324
|
+
`${providerName}.multiagent.unsupported`,
|
|
8325
|
+
`${caps.multiagent.reason}. ${caps.multiagent.remediation ?? ""}`.trim(),
|
|
8326
|
+
{ type: "agent", name, provider: providerName }
|
|
8327
|
+
);
|
|
8328
|
+
}
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
7927
8331
|
}
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
8332
|
+
if (config.deployments && caps.deployment.tier === "emulated") {
|
|
8333
|
+
for (const [name, dep] of Object.entries(config.deployments)) {
|
|
8334
|
+
if (dep.provider && dep.provider !== providerName) continue;
|
|
8335
|
+
const addr = {
|
|
8336
|
+
type: "deployment",
|
|
8337
|
+
name,
|
|
8338
|
+
provider: providerName
|
|
8339
|
+
};
|
|
8340
|
+
if (dep.schedule) {
|
|
8341
|
+
diagnostics.warning(
|
|
8342
|
+
`${providerName}.deployment.schedule_unsupported`,
|
|
8343
|
+
"Schedules are not enforced server-side on this provider; trigger runs via external cron/CI.",
|
|
8344
|
+
addr
|
|
8345
|
+
);
|
|
8346
|
+
}
|
|
8347
|
+
if (dep.initial_events?.some((e) => e.type === "user.define_outcome")) {
|
|
8348
|
+
diagnostics.warning(
|
|
8349
|
+
`${providerName}.deployment.define_outcome_unsupported`,
|
|
8350
|
+
"Outcome rubrics (user.define_outcome) are not enforced server-side on this provider; the run executes without rubric grading.",
|
|
8351
|
+
addr
|
|
8352
|
+
);
|
|
8353
|
+
}
|
|
8354
|
+
if (dep.resources?.some((r) => r.type === "github_repository")) {
|
|
8355
|
+
diagnostics.warning(
|
|
8356
|
+
`${providerName}.deployment.github_repository_unsupported`,
|
|
8357
|
+
"github_repository resources are not provisioned on this provider; clone the repository inside the session instead.",
|
|
8358
|
+
addr
|
|
8359
|
+
);
|
|
8360
|
+
}
|
|
8361
|
+
if (dep.resources?.some((r) => r.type === "memory_store" && (r.access === "read_only" || r.instructions))) {
|
|
8362
|
+
diagnostics.warning(
|
|
8363
|
+
`${providerName}.deployment.memory_store_options_unsupported`,
|
|
8364
|
+
"Per-resource memory_store access/instructions are not honored on this provider; the store is attached with default access.",
|
|
8365
|
+
addr
|
|
8366
|
+
);
|
|
8367
|
+
}
|
|
8368
|
+
}
|
|
7932
8369
|
}
|
|
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
8370
|
}
|
|
7940
|
-
return sorted;
|
|
7941
8371
|
}
|
|
7942
8372
|
|
|
7943
8373
|
// src/internal/planner/planner.ts
|
|
7944
8374
|
async function buildPlan(config, state, options = {}) {
|
|
8375
|
+
const scopedConfig = options.resourceAddresses ? selectProjectConfig(config, options.resourceAddresses) : config;
|
|
8376
|
+
const resourceKeys = options.resourceAddresses ? new Set(options.resourceAddresses.map(addressKey)) : void 0;
|
|
8377
|
+
const scopedState = resourceKeys ? { ...state, resources: state.resources.filter((resource) => resourceKeys.has(addressKey(resource.address))) } : state;
|
|
7945
8378
|
const diagnostics = new DiagnosticCollector();
|
|
7946
8379
|
const actions = [];
|
|
7947
|
-
const targetProviders = options.providers ?? resolveTargetProviders(
|
|
7948
|
-
collectReferenceDiagnostics(
|
|
7949
|
-
collectProviderCapabilities(
|
|
7950
|
-
const graph = buildDependencyGraph(
|
|
8380
|
+
const targetProviders = options.providers ?? resolveTargetProviders(scopedConfig);
|
|
8381
|
+
collectReferenceDiagnostics(scopedConfig, diagnostics);
|
|
8382
|
+
collectProviderCapabilities(scopedConfig, targetProviders, diagnostics);
|
|
8383
|
+
const graph = buildDependencyGraph(scopedConfig, targetProviders);
|
|
7951
8384
|
const sorted = topologicalSort(graph);
|
|
7952
8385
|
const stateIndex = /* @__PURE__ */ new Map();
|
|
7953
|
-
for (const res of
|
|
8386
|
+
for (const res of scopedState.resources) {
|
|
7954
8387
|
stateIndex.set(addressKey(res.address), res);
|
|
7955
8388
|
}
|
|
7956
8389
|
const remoteIdLookup = /* @__PURE__ */ new Map();
|
|
7957
|
-
for (const res of
|
|
8390
|
+
for (const res of scopedState.resources) {
|
|
7958
8391
|
remoteIdLookup.set(addressKey(res.address), res);
|
|
7959
8392
|
}
|
|
7960
8393
|
const hashStateLookup = { getResource: (addr) => remoteIdLookup.get(addressKey(addr)) };
|
|
@@ -8098,9 +8531,53 @@ async function buildPlan(config, state, options = {}) {
|
|
|
8098
8531
|
dependencies: replacement ? [replacement] : []
|
|
8099
8532
|
});
|
|
8100
8533
|
}
|
|
8101
|
-
coalesceChannelRenames(actions,
|
|
8534
|
+
coalesceChannelRenames(actions, scopedConfig, scopedState);
|
|
8102
8535
|
return { actions, diagnostics: diagnostics.getAll() };
|
|
8103
8536
|
}
|
|
8537
|
+
function selectProjectConfig(config, addresses) {
|
|
8538
|
+
const providers = new Set(addresses.map((address) => address.provider));
|
|
8539
|
+
const namesByType = /* @__PURE__ */ new Map();
|
|
8540
|
+
for (const address of addresses) {
|
|
8541
|
+
const names = namesByType.get(address.type) ?? /* @__PURE__ */ new Set();
|
|
8542
|
+
names.add(address.name);
|
|
8543
|
+
namesByType.set(address.type, names);
|
|
8544
|
+
}
|
|
8545
|
+
const pick = (record, names) => {
|
|
8546
|
+
if (!record || !names?.size) return void 0;
|
|
8547
|
+
const selected = Object.fromEntries(Object.entries(record).filter(([name]) => names.has(name)));
|
|
8548
|
+
return Object.keys(selected).length > 0 ? selected : void 0;
|
|
8549
|
+
};
|
|
8550
|
+
const agentNames = /* @__PURE__ */ new Set([...namesByType.get("agent") ?? [], ...namesByType.get("template") ?? []]);
|
|
8551
|
+
const selectedAgents = pick(config.agents, agentNames);
|
|
8552
|
+
const tunnelNames = /* @__PURE__ */ new Set();
|
|
8553
|
+
for (const agent of Object.values(selectedAgents ?? {})) {
|
|
8554
|
+
if (agent.tunnel) tunnelNames.add(agent.tunnel);
|
|
8555
|
+
}
|
|
8556
|
+
for (const deployment of Object.values(pick(config.deployments, namesByType.get("deployment")) ?? {})) {
|
|
8557
|
+
if (deployment.tunnel) tunnelNames.add(deployment.tunnel);
|
|
8558
|
+
}
|
|
8559
|
+
const identityNames = namesByType.get("identity");
|
|
8560
|
+
const selectedProviders = Object.fromEntries(
|
|
8561
|
+
Object.entries(config.providers).filter(([providerName]) => providers.has(providerName))
|
|
8562
|
+
);
|
|
8563
|
+
const defaultProvider = providers.size === 1 ? [...providers][0] : config.defaults?.provider;
|
|
8564
|
+
const defaultIdentity = config.defaults?.identity && identityNames?.has(config.defaults.identity) ? config.defaults.identity : void 0;
|
|
8565
|
+
return {
|
|
8566
|
+
...config,
|
|
8567
|
+
providers: selectedProviders,
|
|
8568
|
+
defaults: defaultProvider || defaultIdentity ? { provider: defaultProvider, identity: defaultIdentity } : void 0,
|
|
8569
|
+
environments: pick(config.environments, namesByType.get("environment")),
|
|
8570
|
+
tunnels: pick(config.tunnels, tunnelNames),
|
|
8571
|
+
vaults: pick(config.vaults, namesByType.get("vault")),
|
|
8572
|
+
memory_stores: pick(config.memory_stores, namesByType.get("memory_store")),
|
|
8573
|
+
skills: pick(config.skills, namesByType.get("skill")),
|
|
8574
|
+
files: pick(config.files, namesByType.get("file")),
|
|
8575
|
+
identities: pick(config.identities, identityNames),
|
|
8576
|
+
agents: selectedAgents,
|
|
8577
|
+
channels: pick(config.channels, namesByType.get("channel")),
|
|
8578
|
+
deployments: pick(config.deployments, namesByType.get("deployment"))
|
|
8579
|
+
};
|
|
8580
|
+
}
|
|
8104
8581
|
function coalesceChannelRenames(actions, config, state) {
|
|
8105
8582
|
const creates = actions.filter((action) => action.action === "create" && action.address.type === "channel");
|
|
8106
8583
|
const deletes = actions.filter((action) => action.action === "delete" && action.address.type === "channel");
|
|
@@ -8180,6 +8657,9 @@ async function refreshState(state, providers, options = {}) {
|
|
|
8180
8657
|
const errors = [];
|
|
8181
8658
|
let dirty = false;
|
|
8182
8659
|
for (const res of resources) {
|
|
8660
|
+
if (options.resourceKeys && !options.resourceKeys.has(addressKey(res.address))) {
|
|
8661
|
+
continue;
|
|
8662
|
+
}
|
|
8183
8663
|
if (options.targetProviders && !options.targetProviders.includes(res.address.provider)) {
|
|
8184
8664
|
continue;
|
|
8185
8665
|
}
|
|
@@ -8293,18 +8773,26 @@ async function refreshState(state, providers, options = {}) {
|
|
|
8293
8773
|
}
|
|
8294
8774
|
|
|
8295
8775
|
// src/internal/core/resource-runtime.ts
|
|
8776
|
+
async function planProjectWithStateBackend(input, options = {}) {
|
|
8777
|
+
return readProjectRuntime(input, (ctx) => planProjectContext(ctx, options));
|
|
8778
|
+
}
|
|
8296
8779
|
async function syncProjectResourcesWithStateBackend(input, options = {}) {
|
|
8297
8780
|
return writeProjectRuntime(input, async (ctx) => {
|
|
8298
8781
|
const planned = await planProjectContext(ctx, options);
|
|
8299
8782
|
if (options.refreshOnly) {
|
|
8300
8783
|
return { planned };
|
|
8301
8784
|
}
|
|
8785
|
+
if (options.mode === "create-only") {
|
|
8786
|
+
const errorDiagnostic = planned.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
8787
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
8788
|
+
}
|
|
8302
8789
|
return {
|
|
8303
8790
|
planned,
|
|
8304
8791
|
execution: await executePlannedProject(planned, {
|
|
8305
8792
|
onFeedback: options.onFeedback,
|
|
8306
8793
|
policy: options.policy,
|
|
8307
|
-
confirm: options.confirm
|
|
8794
|
+
confirm: options.confirm,
|
|
8795
|
+
concurrency: options.concurrency
|
|
8308
8796
|
})
|
|
8309
8797
|
};
|
|
8310
8798
|
});
|
|
@@ -8366,26 +8854,103 @@ async function importResource(ctx, address, remoteId, options = {}) {
|
|
|
8366
8854
|
return resource;
|
|
8367
8855
|
}
|
|
8368
8856
|
async function planProjectContext(ctx, options = {}) {
|
|
8369
|
-
|
|
8857
|
+
if (options.mode === "create-only" && !options.scope) {
|
|
8858
|
+
throw new UserError("Resource create-only mode requires an explicit resource scope.");
|
|
8859
|
+
}
|
|
8860
|
+
let targetProviders = resolveTargetProviders2(options.provider);
|
|
8861
|
+
if (!targetProviders && options.scope) {
|
|
8862
|
+
targetProviders = [...new Set(options.scope.roots.map((root) => root.provider))];
|
|
8863
|
+
}
|
|
8864
|
+
const selectedAddresses = options.scope ? resolvePlanScope(ctx, targetProviders ?? [], options.scope) : void 0;
|
|
8865
|
+
const resourceKeys = selectedAddresses ? new Set(selectedAddresses.map(addressKey)) : void 0;
|
|
8370
8866
|
const refreshResult = options.refresh !== false && ctx.state.listResources().length > 0 ? await refreshState(ctx.state, ctx.providers, {
|
|
8371
8867
|
targetProviders,
|
|
8868
|
+
resourceKeys,
|
|
8372
8869
|
config: ctx.config,
|
|
8373
8870
|
quiet: options.quiet ?? true,
|
|
8374
8871
|
onFeedback: options.onFeedback
|
|
8375
8872
|
}) : void 0;
|
|
8376
|
-
|
|
8873
|
+
let plan = await buildPlan(ctx.config, ctx.state.getStateFile(), {
|
|
8377
8874
|
providers: targetProviders,
|
|
8378
|
-
configPath: ctx.configPath
|
|
8875
|
+
configPath: ctx.configPath,
|
|
8876
|
+
resourceAddresses: selectedAddresses
|
|
8379
8877
|
});
|
|
8878
|
+
if (options.mode === "create-only" && options.scope) {
|
|
8879
|
+
plan = enforceCreateOnlyPlan(plan, options.scope, toResourceRefreshResult(refreshResult));
|
|
8880
|
+
}
|
|
8380
8881
|
return {
|
|
8381
8882
|
executionContext: ctx,
|
|
8382
8883
|
plan,
|
|
8383
8884
|
refreshResult: toResourceRefreshResult(refreshResult),
|
|
8384
8885
|
targetProviders,
|
|
8385
|
-
destructiveActions: selectDestructive(plan.actions)
|
|
8886
|
+
destructiveActions: selectDestructive(plan.actions),
|
|
8887
|
+
selectedAddresses,
|
|
8888
|
+
mode: options.mode
|
|
8889
|
+
};
|
|
8890
|
+
}
|
|
8891
|
+
function enforceCreateOnlyPlan(plan, scope, refreshResult) {
|
|
8892
|
+
const reasons = [];
|
|
8893
|
+
const rootKeys = new Set(scope.roots.map(addressKey));
|
|
8894
|
+
const refreshError = refreshResult?.errors[0];
|
|
8895
|
+
if (refreshError) {
|
|
8896
|
+
reasons.push(
|
|
8897
|
+
`Cannot verify scoped dependencies because refresh failed for ${addressKey(refreshError.resource.address)}: ${refreshError.error}`
|
|
8898
|
+
);
|
|
8899
|
+
}
|
|
8900
|
+
for (const root of scope.roots) {
|
|
8901
|
+
const rootKey = addressKey(root);
|
|
8902
|
+
const rootAction = plan.actions.find((action) => addressKey(action.address) === rootKey);
|
|
8903
|
+
if (!rootAction) {
|
|
8904
|
+
reasons.push(`Scoped plan did not contain target resource ${rootKey}.`);
|
|
8905
|
+
} else if (rootAction.action !== "create") {
|
|
8906
|
+
reasons.push(`Target resource ${rootKey} must be new, but the scoped plan requires '${rootAction.action}'.`);
|
|
8907
|
+
}
|
|
8908
|
+
}
|
|
8909
|
+
const dependencyChanges = plan.actions.filter(
|
|
8910
|
+
(action) => !rootKeys.has(addressKey(action.address)) && action.action !== "no-op"
|
|
8911
|
+
);
|
|
8912
|
+
if (dependencyChanges.length > 0) {
|
|
8913
|
+
const labels = dependencyChanges.map((action) => `${addressKey(action.address)} (${action.action})`).join(", ");
|
|
8914
|
+
reasons.push(`Create-only requires every scoped dependency to be up-to-date. Reconcile first: ${labels}.`);
|
|
8915
|
+
}
|
|
8916
|
+
if (reasons.length === 0) return plan;
|
|
8917
|
+
return {
|
|
8918
|
+
...plan,
|
|
8919
|
+
diagnostics: [
|
|
8920
|
+
...plan.diagnostics,
|
|
8921
|
+
{
|
|
8922
|
+
severity: "error",
|
|
8923
|
+
code: "resource.create_only.blocked",
|
|
8924
|
+
message: reasons.join(" "),
|
|
8925
|
+
resource: scope.roots[0]
|
|
8926
|
+
}
|
|
8927
|
+
]
|
|
8386
8928
|
};
|
|
8387
8929
|
}
|
|
8930
|
+
function resolvePlanScope(ctx, targetProviders, scope) {
|
|
8931
|
+
if (scope.roots.length === 0) {
|
|
8932
|
+
throw new UserError("Resource plan scope requires at least one root address.");
|
|
8933
|
+
}
|
|
8934
|
+
for (const root of scope.roots) {
|
|
8935
|
+
if (!targetProviders.includes(root.provider)) {
|
|
8936
|
+
throw new UserError(
|
|
8937
|
+
`Scoped resource ${addressKey(root)} is outside the selected provider set: ${targetProviders.join(", ")}.`
|
|
8938
|
+
);
|
|
8939
|
+
}
|
|
8940
|
+
}
|
|
8941
|
+
const graph = buildDependencyGraph(ctx.config, targetProviders);
|
|
8942
|
+
for (const root of scope.roots) {
|
|
8943
|
+
if (!graph.nodes.has(addressKey(root))) {
|
|
8944
|
+
throw new UserError(`Scoped resource ${addressKey(root)} is not declared in the project config.`);
|
|
8945
|
+
}
|
|
8946
|
+
}
|
|
8947
|
+
return scope.includeDependencies === false ? [...scope.roots] : collectDependencyClosure(graph, scope.roots);
|
|
8948
|
+
}
|
|
8388
8949
|
async function executePlannedProject(planned, options = {}) {
|
|
8950
|
+
if (planned.mode === "create-only") {
|
|
8951
|
+
const errorDiagnostic = planned.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
8952
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
8953
|
+
}
|
|
8389
8954
|
const decision = await decideDestructive(planned.destructiveActions, {
|
|
8390
8955
|
policy: options.policy,
|
|
8391
8956
|
confirm: options.confirm
|
|
@@ -8403,7 +8968,8 @@ async function executePlannedProject(planned, options = {}) {
|
|
|
8403
8968
|
configPath: ctx.configPath,
|
|
8404
8969
|
providers: ctx.providers,
|
|
8405
8970
|
state: ctx.state,
|
|
8406
|
-
onFeedback: options.onFeedback
|
|
8971
|
+
onFeedback: options.onFeedback,
|
|
8972
|
+
createOnly: planned.mode === "create-only"
|
|
8407
8973
|
},
|
|
8408
8974
|
{ concurrency: options.concurrency }
|
|
8409
8975
|
);
|
|
@@ -8428,13 +8994,6 @@ async function decideDestructive(destructiveActions, options = {}) {
|
|
|
8428
8994
|
return "blocked";
|
|
8429
8995
|
}
|
|
8430
8996
|
}
|
|
8431
|
-
function replaceResourcePlan(planned, plan) {
|
|
8432
|
-
return {
|
|
8433
|
-
...planned,
|
|
8434
|
-
plan,
|
|
8435
|
-
destructiveActions: selectDestructive(plan.actions)
|
|
8436
|
-
};
|
|
8437
|
-
}
|
|
8438
8997
|
function toResourceRefreshResult(result) {
|
|
8439
8998
|
if (!result) return void 0;
|
|
8440
8999
|
return {
|
|
@@ -8456,6 +9015,124 @@ function toResourceExecutionResult(result) {
|
|
|
8456
9015
|
};
|
|
8457
9016
|
}
|
|
8458
9017
|
|
|
9018
|
+
// src/internal/core/project-source-security.ts
|
|
9019
|
+
import { basename as basename8, dirname as dirname11 } from "path";
|
|
9020
|
+
import { isScalar, parseDocument, visit } from "yaml";
|
|
9021
|
+
var REDACTED = "[redacted]";
|
|
9022
|
+
var ENVIRONMENT_REFERENCE = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
|
|
9023
|
+
var SENSITIVE_KEY = /(access[_-]?key(?:[_-]?id)?|api[_-]?key|authorization|credential|headers?|password|secret(?![_-]?name)|signature|token)/i;
|
|
9024
|
+
async function inspectProjectSource(source, configPath) {
|
|
9025
|
+
const document = parseDocument(source, { keepSourceTokens: true, prettyErrors: true });
|
|
9026
|
+
if (document.errors.length > 0) {
|
|
9027
|
+
return {
|
|
9028
|
+
diagnostics: document.errors.map(() => ({
|
|
9029
|
+
severity: "error",
|
|
9030
|
+
code: "project.config.invalid",
|
|
9031
|
+
message: "agents.yaml contains invalid YAML. Fix the syntax before creating or restoring a version."
|
|
9032
|
+
})),
|
|
9033
|
+
redacted_source: "# Invalid agents.yaml source omitted from the safe preview.\n",
|
|
9034
|
+
sensitive_literals: []
|
|
9035
|
+
};
|
|
9036
|
+
}
|
|
9037
|
+
const rawConfig = document.toJS({ mapAsMap: false });
|
|
9038
|
+
const displaySecrets = collectSensitiveScalars(rawConfig);
|
|
9039
|
+
const sensitiveLiterals = [...displaySecrets].filter((value) => !ENVIRONMENT_REFERENCE.test(value));
|
|
9040
|
+
let diagnostics;
|
|
9041
|
+
try {
|
|
9042
|
+
const loaded = await resolveProjectConfigFromObject(rawConfig, {
|
|
9043
|
+
projectName: basename8(dirname11(configPath)),
|
|
9044
|
+
basePath: dirname11(configPath)
|
|
9045
|
+
});
|
|
9046
|
+
diagnostics = validateProjectConfig(loaded.config);
|
|
9047
|
+
} catch (error) {
|
|
9048
|
+
diagnostics = [
|
|
9049
|
+
{
|
|
9050
|
+
severity: "error",
|
|
9051
|
+
code: "project.config.invalid",
|
|
9052
|
+
message: error instanceof Error ? error.message : String(error)
|
|
9053
|
+
}
|
|
9054
|
+
];
|
|
9055
|
+
}
|
|
9056
|
+
if (sensitiveLiterals.length > 0) {
|
|
9057
|
+
diagnostics.push({
|
|
9058
|
+
severity: "error",
|
|
9059
|
+
code: "project.version.sensitive_literal",
|
|
9060
|
+
message: "agents.yaml contains a credential value in a sensitive field. Replace it with an environment variable reference before creating or restoring a version."
|
|
9061
|
+
});
|
|
9062
|
+
}
|
|
9063
|
+
return {
|
|
9064
|
+
diagnostics: redactDiagnostics(diagnostics, displaySecrets),
|
|
9065
|
+
redacted_source: redactDocumentSource(source, document, displaySecrets),
|
|
9066
|
+
sensitive_literals: sensitiveLiterals.map(() => REDACTED)
|
|
9067
|
+
};
|
|
9068
|
+
}
|
|
9069
|
+
function collectSensitiveScalars(value, result = /* @__PURE__ */ new Set(), key = "", ancestorSensitive = false) {
|
|
9070
|
+
if (Array.isArray(value)) {
|
|
9071
|
+
const nestedSensitive = ancestorSensitive || isSensitiveValueKey(key);
|
|
9072
|
+
for (const entry of value) collectSensitiveScalars(entry, result, key, nestedSensitive);
|
|
9073
|
+
return result;
|
|
9074
|
+
}
|
|
9075
|
+
if (isRecord2(value)) {
|
|
9076
|
+
const nestedSensitive = ancestorSensitive || isSensitiveContainerKey(key);
|
|
9077
|
+
for (const [entryKey, entry] of Object.entries(value)) {
|
|
9078
|
+
collectSensitiveScalars(entry, result, entryKey, nestedSensitive);
|
|
9079
|
+
}
|
|
9080
|
+
return result;
|
|
9081
|
+
}
|
|
9082
|
+
if ((ancestorSensitive || isSensitiveValueKey(key)) && (typeof value === "string" || typeof value === "number") && String(value).length > 0) {
|
|
9083
|
+
result.add(String(value));
|
|
9084
|
+
}
|
|
9085
|
+
return result;
|
|
9086
|
+
}
|
|
9087
|
+
function isSensitiveContainerKey(key) {
|
|
9088
|
+
return ["header", "headers", "authorization"].includes(key.toLowerCase().replaceAll("-", "_"));
|
|
9089
|
+
}
|
|
9090
|
+
function isSensitiveValueKey(key) {
|
|
9091
|
+
const normalized = key.toLowerCase().replaceAll("-", "_");
|
|
9092
|
+
if (normalized === "secret_name" || normalized === "credentials") return false;
|
|
9093
|
+
return SENSITIVE_KEY.test(normalized);
|
|
9094
|
+
}
|
|
9095
|
+
function redactDocumentSource(source, document, secrets) {
|
|
9096
|
+
if (secrets.size === 0) return source;
|
|
9097
|
+
const redactedDocument = document.clone();
|
|
9098
|
+
visit(redactedDocument, (_key, node) => {
|
|
9099
|
+
if (isScalar(node) && (typeof node.value === "string" || typeof node.value === "number")) {
|
|
9100
|
+
const value = String(node.value);
|
|
9101
|
+
const redacted = redactText(value, secrets);
|
|
9102
|
+
if (redacted !== value) {
|
|
9103
|
+
node.value = redacted;
|
|
9104
|
+
node.source = redacted;
|
|
9105
|
+
node.type = "PLAIN";
|
|
9106
|
+
}
|
|
9107
|
+
}
|
|
9108
|
+
redactComments(node, secrets);
|
|
9109
|
+
});
|
|
9110
|
+
redactComments(redactedDocument, secrets);
|
|
9111
|
+
return redactedDocument.toString();
|
|
9112
|
+
}
|
|
9113
|
+
function redactText(source, secrets) {
|
|
9114
|
+
let redacted = source;
|
|
9115
|
+
for (const secret of [...secrets].sort((left, right) => right.length - left.length)) {
|
|
9116
|
+
redacted = redacted.replaceAll(secret, REDACTED);
|
|
9117
|
+
}
|
|
9118
|
+
return redacted;
|
|
9119
|
+
}
|
|
9120
|
+
function redactComments(value, secrets) {
|
|
9121
|
+
if (!value || typeof value !== "object") return;
|
|
9122
|
+
const commented = value;
|
|
9123
|
+
if (commented.comment) commented.comment = redactText(commented.comment, secrets);
|
|
9124
|
+
if (commented.commentBefore) commented.commentBefore = redactText(commented.commentBefore, secrets);
|
|
9125
|
+
}
|
|
9126
|
+
function redactDiagnostics(diagnostics, secrets) {
|
|
9127
|
+
return diagnostics.map((diagnostic) => ({
|
|
9128
|
+
...diagnostic,
|
|
9129
|
+
message: redactText(diagnostic.message, secrets)
|
|
9130
|
+
}));
|
|
9131
|
+
}
|
|
9132
|
+
function isRecord2(value) {
|
|
9133
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9134
|
+
}
|
|
9135
|
+
|
|
8459
9136
|
// src/internal/core/sync-runtime.ts
|
|
8460
9137
|
import { stringify as stringifyYaml } from "yaml";
|
|
8461
9138
|
var SYNCABLE_GROUP = {
|
|
@@ -8783,6 +9460,378 @@ function buildDeploymentContext(ctx, name, provider) {
|
|
|
8783
9460
|
};
|
|
8784
9461
|
}
|
|
8785
9462
|
|
|
9463
|
+
// src/internal/core/managed-api-runtime.ts
|
|
9464
|
+
function resolveAdapter(ctx, provider) {
|
|
9465
|
+
if (provider) return getRuntimeProvider(ctx, provider);
|
|
9466
|
+
const configured = Array.from(ctx.providers.keys());
|
|
9467
|
+
if (configured.length === 1) return getRuntimeProvider(ctx, configured[0]);
|
|
9468
|
+
throw new UserError("Multiple providers configured. Use --provider to specify one.");
|
|
9469
|
+
}
|
|
9470
|
+
function requiredMethod(value, provider, operation) {
|
|
9471
|
+
if (value) return value;
|
|
9472
|
+
throw new UserError(`Provider '${provider}' does not support ${operation}.`);
|
|
9473
|
+
}
|
|
9474
|
+
async function listRemoteAgents(ctx, options = {}) {
|
|
9475
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9476
|
+
const method2 = requiredMethod(adapter2.listAgentResources, adapter2.name, "agent listing");
|
|
9477
|
+
return method2.call(adapter2, options);
|
|
9478
|
+
}
|
|
9479
|
+
async function getRemoteAgent(ctx, id, options = {}) {
|
|
9480
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9481
|
+
const method2 = requiredMethod(adapter2.getRemoteAgent, adapter2.name, "agent lookup");
|
|
9482
|
+
return method2.call(adapter2, id, options.version);
|
|
9483
|
+
}
|
|
9484
|
+
async function listRemoteAgentVersions(ctx, id, options = {}) {
|
|
9485
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9486
|
+
const method2 = requiredMethod(adapter2.listAgentVersions, adapter2.name, "agent version listing");
|
|
9487
|
+
return method2.call(adapter2, id, options);
|
|
9488
|
+
}
|
|
9489
|
+
async function listRemoteEnvironments(ctx, options = {}) {
|
|
9490
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9491
|
+
const method2 = requiredMethod(adapter2.listEnvironmentResources, adapter2.name, "environment listing");
|
|
9492
|
+
return method2.call(adapter2, options);
|
|
9493
|
+
}
|
|
9494
|
+
async function getRemoteEnvironment(ctx, id, options = {}) {
|
|
9495
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9496
|
+
const method2 = requiredMethod(adapter2.getRemoteEnvironment, adapter2.name, "environment lookup");
|
|
9497
|
+
return method2.call(adapter2, id);
|
|
9498
|
+
}
|
|
9499
|
+
async function listRemoteVaults(ctx, options = {}) {
|
|
9500
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9501
|
+
const method2 = requiredMethod(adapter2.listVaultResources, adapter2.name, "vault listing");
|
|
9502
|
+
return method2.call(adapter2, options);
|
|
9503
|
+
}
|
|
9504
|
+
async function getRemoteVault(ctx, id, options = {}) {
|
|
9505
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9506
|
+
const method2 = requiredMethod(adapter2.getRemoteVault, adapter2.name, "vault lookup");
|
|
9507
|
+
return method2.call(adapter2, id);
|
|
9508
|
+
}
|
|
9509
|
+
async function listRemoteSkills(ctx, options = {}) {
|
|
9510
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9511
|
+
const method2 = requiredMethod(adapter2.listSkillResources, adapter2.name, "skill listing");
|
|
9512
|
+
return method2.call(adapter2, options);
|
|
9513
|
+
}
|
|
9514
|
+
async function getRemoteSkill(ctx, id, options = {}) {
|
|
9515
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9516
|
+
const method2 = requiredMethod(adapter2.getSkillInfo, adapter2.name, "skill lookup");
|
|
9517
|
+
return method2.call(adapter2, id);
|
|
9518
|
+
}
|
|
9519
|
+
async function listRemoteSkillVersions(ctx, id, options = {}) {
|
|
9520
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9521
|
+
const method2 = requiredMethod(adapter2.listSkillVersions, adapter2.name, "skill version listing");
|
|
9522
|
+
return method2.call(adapter2, id, options);
|
|
9523
|
+
}
|
|
9524
|
+
async function getRemoteSkillVersion(ctx, id, version, options = {}) {
|
|
9525
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9526
|
+
const method2 = requiredMethod(adapter2.getSkillVersion, adapter2.name, "skill version lookup");
|
|
9527
|
+
return method2.call(adapter2, id, version);
|
|
9528
|
+
}
|
|
9529
|
+
async function getRemoteSkillDownloadInfo(ctx, id, version, options = {}) {
|
|
9530
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9531
|
+
const method2 = requiredMethod(adapter2.getSkillDownloadInfo, adapter2.name, "skill version download");
|
|
9532
|
+
return method2.call(adapter2, id, version);
|
|
9533
|
+
}
|
|
9534
|
+
async function downloadRemoteSkill(ctx, id, version, options = {}) {
|
|
9535
|
+
const info = await getRemoteSkillDownloadInfo(ctx, id, version, options);
|
|
9536
|
+
const response = await resolveFetch()(info.file_url, { method: "GET" });
|
|
9537
|
+
if (!response.ok) {
|
|
9538
|
+
throw new ApiError(response.status, await response.text(), "Skill download failed");
|
|
9539
|
+
}
|
|
9540
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
9541
|
+
}
|
|
9542
|
+
async function listRemoteFiles(ctx, options = {}) {
|
|
9543
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9544
|
+
const method2 = requiredMethod(adapter2.listFileResources, adapter2.name, "file listing");
|
|
9545
|
+
return method2.call(adapter2, options);
|
|
9546
|
+
}
|
|
9547
|
+
async function downloadRemoteFile(ctx, id, options = {}) {
|
|
9548
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9549
|
+
const method2 = requiredMethod(adapter2.downloadFileContent, adapter2.name, "file content download");
|
|
9550
|
+
return method2.call(adapter2, id);
|
|
9551
|
+
}
|
|
9552
|
+
async function updateRemoteSession(ctx, id, input, options = {}) {
|
|
9553
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9554
|
+
const method2 = requiredMethod(adapter2.updateSession, adapter2.name, "session update");
|
|
9555
|
+
return method2.call(adapter2, id, input);
|
|
9556
|
+
}
|
|
9557
|
+
async function archiveRemoteSession(ctx, id, options = {}) {
|
|
9558
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9559
|
+
const method2 = requiredMethod(adapter2.archiveSession, adapter2.name, "session archive");
|
|
9560
|
+
return method2.call(adapter2, id);
|
|
9561
|
+
}
|
|
9562
|
+
async function sendRemoteSessionEvents(ctx, id, events, options = {}) {
|
|
9563
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9564
|
+
const method2 = requiredMethod(adapter2.sendSessionEvents, adapter2.name, "generic session event sending");
|
|
9565
|
+
return method2.call(adapter2, id, events);
|
|
9566
|
+
}
|
|
9567
|
+
async function listRemoteDeployments(ctx, options = {}) {
|
|
9568
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9569
|
+
const method2 = requiredMethod(adapter2.listDeployments, adapter2.name, "deployment listing");
|
|
9570
|
+
return method2.call(adapter2, options);
|
|
9571
|
+
}
|
|
9572
|
+
async function getRemoteDeployment(ctx, id, options = {}) {
|
|
9573
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9574
|
+
const method2 = requiredMethod(adapter2.getDeploymentById, adapter2.name, "deployment lookup");
|
|
9575
|
+
return method2.call(adapter2, id);
|
|
9576
|
+
}
|
|
9577
|
+
async function runRemoteDeployment(ctx, id, options = {}) {
|
|
9578
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9579
|
+
const method2 = requiredMethod(adapter2.runDeploymentById, adapter2.name, "deployment run");
|
|
9580
|
+
return method2.call(adapter2, id);
|
|
9581
|
+
}
|
|
9582
|
+
async function setRemoteDeploymentPaused(ctx, id, paused, options = {}) {
|
|
9583
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9584
|
+
const method2 = paused ? adapter2.pauseDeploymentById : adapter2.unpauseDeploymentById;
|
|
9585
|
+
return requiredMethod(method2, adapter2.name, `${paused ? "pausing" : "unpausing"} deployments`).call(adapter2, id);
|
|
9586
|
+
}
|
|
9587
|
+
async function listRemoteDeploymentRuns(ctx, deploymentId, options = {}) {
|
|
9588
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9589
|
+
const method2 = requiredMethod(adapter2.listDeploymentRuns, adapter2.name, "deployment run listing");
|
|
9590
|
+
return method2.call(adapter2, deploymentId, options);
|
|
9591
|
+
}
|
|
9592
|
+
async function getRemoteDeploymentRun(ctx, runId, options = {}) {
|
|
9593
|
+
const adapter2 = resolveAdapter(ctx, options.provider);
|
|
9594
|
+
const method2 = requiredMethod(adapter2.getDeploymentRun, adapter2.name, "deployment run lookup");
|
|
9595
|
+
return method2.call(adapter2, runId);
|
|
9596
|
+
}
|
|
9597
|
+
var API_KEY = { supported: true, auth: "api_key" };
|
|
9598
|
+
var CLIENT_SEARCH = {
|
|
9599
|
+
supported: true,
|
|
9600
|
+
auth: "api_key",
|
|
9601
|
+
reason: "Client-side filtering over the corresponding list API."
|
|
9602
|
+
};
|
|
9603
|
+
var UNSUPPORTED_MODEL = {
|
|
9604
|
+
supported: false,
|
|
9605
|
+
auth: null,
|
|
9606
|
+
reason: "The public Managed Agents API does not expose a model catalog endpoint."
|
|
9607
|
+
};
|
|
9608
|
+
var UNSUPPORTED_THREAD = {
|
|
9609
|
+
supported: false,
|
|
9610
|
+
auth: null,
|
|
9611
|
+
reason: "Managed Agents exposes child-thread ids and lifecycle events through Session Events, but no independent Thread resource API."
|
|
9612
|
+
};
|
|
9613
|
+
var UNSUPPORTED_OAUTH = {
|
|
9614
|
+
supported: false,
|
|
9615
|
+
auth: null,
|
|
9616
|
+
reason: "The public Managed Agents data plane does not expose MCP OAuth login."
|
|
9617
|
+
};
|
|
9618
|
+
var BAILIAN_OPERATIONS = {
|
|
9619
|
+
"agent.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9620
|
+
"agent.list": API_KEY,
|
|
9621
|
+
"agent.get": API_KEY,
|
|
9622
|
+
"agent.search": CLIENT_SEARCH,
|
|
9623
|
+
"agent.versions": API_KEY,
|
|
9624
|
+
"environment.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9625
|
+
"environment.list": API_KEY,
|
|
9626
|
+
"environment.get": API_KEY,
|
|
9627
|
+
"environment.search": CLIENT_SEARCH,
|
|
9628
|
+
"skill.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9629
|
+
"skill.list": API_KEY,
|
|
9630
|
+
"skill.get": API_KEY,
|
|
9631
|
+
"skill.search": CLIENT_SEARCH,
|
|
9632
|
+
"skill.versions": API_KEY,
|
|
9633
|
+
"skill.download": API_KEY,
|
|
9634
|
+
"vault.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9635
|
+
"vault.credential.create": {
|
|
9636
|
+
...API_KEY,
|
|
9637
|
+
reason: "YAML declaration plus scoped Vault transaction; Bailian supports environment_variable credentials only."
|
|
9638
|
+
},
|
|
9639
|
+
"vault.list": API_KEY,
|
|
9640
|
+
"vault.get": API_KEY,
|
|
9641
|
+
"vault.search": CLIENT_SEARCH,
|
|
9642
|
+
"deployment.create": { ...API_KEY, reason: "YAML declaration plus scoped create-only apply." },
|
|
9643
|
+
"deployment.list": API_KEY,
|
|
9644
|
+
"deployment.get": API_KEY,
|
|
9645
|
+
"deployment.search": { ...API_KEY, reason: "Maps to the server-side keyword parameter." },
|
|
9646
|
+
"deployment.runs.list": API_KEY,
|
|
9647
|
+
"deployment.runs.get": API_KEY,
|
|
9648
|
+
"deployment.run": API_KEY,
|
|
9649
|
+
"deployment.pause": API_KEY,
|
|
9650
|
+
"deployment.unpause": API_KEY,
|
|
9651
|
+
"session.create": API_KEY,
|
|
9652
|
+
"session.list": API_KEY,
|
|
9653
|
+
"session.get": API_KEY,
|
|
9654
|
+
"session.search": CLIENT_SEARCH,
|
|
9655
|
+
"session.update": API_KEY,
|
|
9656
|
+
"session.archive": API_KEY,
|
|
9657
|
+
"session.delete": API_KEY,
|
|
9658
|
+
"session.run": { ...API_KEY, reason: "Client composition of session create and event send/stream." },
|
|
9659
|
+
"session.event.send": API_KEY,
|
|
9660
|
+
"session.event.list": API_KEY,
|
|
9661
|
+
"session.event.stream": API_KEY,
|
|
9662
|
+
"session.debug": { ...API_KEY, reason: "Client-side aggregation of supported read APIs." },
|
|
9663
|
+
"session.export": { ...API_KEY, reason: "Client-side export of supported read APIs." },
|
|
9664
|
+
"file.upload": API_KEY,
|
|
9665
|
+
"file.list": API_KEY,
|
|
9666
|
+
"file.get": API_KEY,
|
|
9667
|
+
"file.search": CLIENT_SEARCH,
|
|
9668
|
+
"file.download": API_KEY,
|
|
9669
|
+
"file.delete": API_KEY,
|
|
9670
|
+
"model.list": UNSUPPORTED_MODEL,
|
|
9671
|
+
"model.search": UNSUPPORTED_MODEL,
|
|
9672
|
+
"session_thread.list": UNSUPPORTED_THREAD,
|
|
9673
|
+
"session_thread.get": UNSUPPORTED_THREAD,
|
|
9674
|
+
"session_thread.archive": UNSUPPORTED_THREAD,
|
|
9675
|
+
"session_thread.events": UNSUPPORTED_THREAD,
|
|
9676
|
+
"mcp.oauth_login": UNSUPPORTED_OAUTH
|
|
9677
|
+
};
|
|
9678
|
+
function getManagedAgentProviderCapabilities(provider) {
|
|
9679
|
+
if (provider === "bailian") {
|
|
9680
|
+
return { provider, operations: { ...BAILIAN_OPERATIONS } };
|
|
9681
|
+
}
|
|
9682
|
+
return {
|
|
9683
|
+
provider,
|
|
9684
|
+
operations: {
|
|
9685
|
+
"managed_agent.api": {
|
|
9686
|
+
supported: false,
|
|
9687
|
+
auth: null,
|
|
9688
|
+
reason: "The operation-level API command surface is currently implemented for Bailian only."
|
|
9689
|
+
}
|
|
9690
|
+
}
|
|
9691
|
+
};
|
|
9692
|
+
}
|
|
9693
|
+
|
|
9694
|
+
// src/internal/core/vault-credential-runtime.ts
|
|
9695
|
+
async function planVaultCredentialCreate(ctx, vaultName, credentialName, options = {}) {
|
|
9696
|
+
const prepared = await prepareVaultCredentialCreate(ctx, vaultName, credentialName, options);
|
|
9697
|
+
return {
|
|
9698
|
+
provider: prepared.provider,
|
|
9699
|
+
vault: vaultName,
|
|
9700
|
+
vaultRemoteId: prepared.vaultState.remote_id,
|
|
9701
|
+
credential: credentialName,
|
|
9702
|
+
remoteChecked: prepared.remoteChecked,
|
|
9703
|
+
reuseRemote: Boolean(prepared.remoteCredential),
|
|
9704
|
+
remoteCredentialId: prepared.remoteCredential?.id
|
|
9705
|
+
};
|
|
9706
|
+
}
|
|
9707
|
+
async function planVaultCredentialCreateWithStateBackend(input, vaultName, credentialName, options = {}) {
|
|
9708
|
+
return readProjectRuntime(input, (ctx) => planVaultCredentialCreate(ctx, vaultName, credentialName, options));
|
|
9709
|
+
}
|
|
9710
|
+
async function createVaultCredential(ctx, vaultName, credentialName, options = {}) {
|
|
9711
|
+
if (options.checkRemote === false) {
|
|
9712
|
+
throw new UserError("Vault Credential create requires the remote duplicate check.");
|
|
9713
|
+
}
|
|
9714
|
+
const prepared = await prepareVaultCredentialCreate(ctx, vaultName, credentialName, options);
|
|
9715
|
+
const remote = prepared.remoteCredential ?? await prepared.adapter.createCredential(prepared.vaultState.remote_id, prepared.credential);
|
|
9716
|
+
if (!remote.id) throw new UserError("Credential create returned no remote id.");
|
|
9717
|
+
const address = { type: "vault", name: vaultName, provider: prepared.provider };
|
|
9718
|
+
const desiredHash = await computeResourceHash(address, ctx.config, ctx.configPath, ctx.state);
|
|
9719
|
+
ctx.state.setResource({
|
|
9720
|
+
...prepared.vaultState,
|
|
9721
|
+
content_hash: desiredHash,
|
|
9722
|
+
desired_hash: desiredHash,
|
|
9723
|
+
drift_paths: [],
|
|
9724
|
+
drift_status: "unchecked"
|
|
9725
|
+
});
|
|
9726
|
+
await ctx.state.save();
|
|
9727
|
+
return {
|
|
9728
|
+
provider: prepared.provider,
|
|
9729
|
+
vault: vaultName,
|
|
9730
|
+
vaultRemoteId: prepared.vaultState.remote_id,
|
|
9731
|
+
credential: credentialName,
|
|
9732
|
+
remoteChecked: prepared.remoteChecked,
|
|
9733
|
+
credentialId: remote.id,
|
|
9734
|
+
reuseRemote: Boolean(prepared.remoteCredential),
|
|
9735
|
+
remoteCredentialId: prepared.remoteCredential?.id,
|
|
9736
|
+
adopted: Boolean(prepared.remoteCredential)
|
|
9737
|
+
};
|
|
9738
|
+
}
|
|
9739
|
+
async function createVaultCredentialWithStateBackend(input, vaultName, credentialName, options = {}) {
|
|
9740
|
+
return writeProjectRuntime(input, (ctx) => createVaultCredential(ctx, vaultName, credentialName, options));
|
|
9741
|
+
}
|
|
9742
|
+
async function prepareVaultCredentialCreate(ctx, vaultName, credentialName, options) {
|
|
9743
|
+
const vault = ctx.config.vaults?.[vaultName];
|
|
9744
|
+
if (!vault) throw new UserError(`Vault '${vaultName}' is not declared in the project config.`);
|
|
9745
|
+
const provider = resolveVaultProvider(ctx, vault.provider, options.provider);
|
|
9746
|
+
const credential = vault.credentials.at(-1);
|
|
9747
|
+
if (!credential || credential.name !== credentialName) {
|
|
9748
|
+
throw new UserError(`Credential '${credentialName}' must be the final newly appended entry in vault.${vaultName}.`);
|
|
9749
|
+
}
|
|
9750
|
+
if (vault.credentials.slice(0, -1).some((entry) => entry.name === credentialName)) {
|
|
9751
|
+
throw new UserError(`Vault '${vaultName}' already declares a credential named '${credentialName}'.`);
|
|
9752
|
+
}
|
|
9753
|
+
if (provider === "bailian" && credential.type !== "environment_variable") {
|
|
9754
|
+
throw new UserError(
|
|
9755
|
+
`Credential '${credentialName}' uses '${credential.type}', but Bailian only supports 'environment_variable' credentials.`
|
|
9756
|
+
);
|
|
9757
|
+
}
|
|
9758
|
+
const address = { type: "vault", name: vaultName, provider };
|
|
9759
|
+
const priorConfig = structuredClone(ctx.config);
|
|
9760
|
+
priorConfig.vaults[vaultName] = {
|
|
9761
|
+
...priorConfig.vaults[vaultName],
|
|
9762
|
+
credentials: priorConfig.vaults[vaultName].credentials.slice(0, -1)
|
|
9763
|
+
};
|
|
9764
|
+
const priorPlan = await planProjectContext(
|
|
9765
|
+
{ ...ctx, config: priorConfig },
|
|
9766
|
+
{
|
|
9767
|
+
provider,
|
|
9768
|
+
scope: { roots: [address] },
|
|
9769
|
+
refresh: options.refresh,
|
|
9770
|
+
quiet: options.quiet ?? true
|
|
9771
|
+
}
|
|
9772
|
+
);
|
|
9773
|
+
const refreshError = priorPlan.refreshResult?.errors[0];
|
|
9774
|
+
if (refreshError) {
|
|
9775
|
+
throw new UserError(`Cannot verify vault.${vaultName} because refresh failed: ${refreshError.error}`);
|
|
9776
|
+
}
|
|
9777
|
+
const errorDiagnostic = priorPlan.plan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
9778
|
+
if (errorDiagnostic) throw new UserError(errorDiagnostic.message);
|
|
9779
|
+
const vaultAction = priorPlan.plan.actions.find(
|
|
9780
|
+
(action) => action.address.type === "vault" && action.address.name === vaultName
|
|
9781
|
+
);
|
|
9782
|
+
if (vaultAction?.action !== "no-op") {
|
|
9783
|
+
throw new UserError(
|
|
9784
|
+
`vault.${vaultName} must be tracked and up-to-date before adding a credential; current action is '${vaultAction?.action ?? "missing"}'.`
|
|
9785
|
+
);
|
|
9786
|
+
}
|
|
9787
|
+
const vaultState = ctx.state.getResource(address);
|
|
9788
|
+
if (!vaultState?.remote_id) throw new UserError(`vault.${vaultName} has no tracked remote id.`);
|
|
9789
|
+
const adapter2 = getRuntimeProvider(ctx, provider);
|
|
9790
|
+
if (!adapter2.createCredential || !adapter2.listCredentials) {
|
|
9791
|
+
throw new UserError(`Provider '${provider}' does not support scoped Vault Credential create.`);
|
|
9792
|
+
}
|
|
9793
|
+
const remoteChecked = options.checkRemote !== false;
|
|
9794
|
+
const sameName = remoteChecked ? (await adapter2.listCredentials(vaultState.remote_id)).filter(
|
|
9795
|
+
(remoteCredential) => remoteCredential.display_name === credentialName
|
|
9796
|
+
) : [];
|
|
9797
|
+
const exact = sameName.find((remoteCredential) => credentialMatches(remoteCredential, credential));
|
|
9798
|
+
if (sameName.length > 0 && !exact) {
|
|
9799
|
+
throw new UserError(`Vault '${vaultName}' already has a different remote credential named '${credentialName}'.`);
|
|
9800
|
+
}
|
|
9801
|
+
return { provider, credential, vaultState, adapter: adapter2, remoteChecked, remoteCredential: exact };
|
|
9802
|
+
}
|
|
9803
|
+
function resolveVaultProvider(ctx, declaredProvider, requestedProvider) {
|
|
9804
|
+
if (requestedProvider && declaredProvider && requestedProvider !== declaredProvider) {
|
|
9805
|
+
throw new UserError(
|
|
9806
|
+
`Vault provider '${declaredProvider}' does not match requested provider '${requestedProvider}'.`
|
|
9807
|
+
);
|
|
9808
|
+
}
|
|
9809
|
+
const provider = requestedProvider ?? declaredProvider ?? ctx.config.defaults?.provider;
|
|
9810
|
+
if (provider && provider !== "all") return provider;
|
|
9811
|
+
const configured = [...ctx.providers.keys()];
|
|
9812
|
+
if (configured.length === 1) return configured[0];
|
|
9813
|
+
throw new UserError("Cannot infer one provider for Vault Credential create.");
|
|
9814
|
+
}
|
|
9815
|
+
function credentialMatches(remote, desired) {
|
|
9816
|
+
if (remote.auth_type !== desired.type || !metadataMatches(remote.metadata, desired.metadata)) return false;
|
|
9817
|
+
if (desired.type === "static_bearer") return remote.mcp_server_url === desired.mcp_server_url;
|
|
9818
|
+
const desiredHosts = credentialHosts(desired.networking);
|
|
9819
|
+
const remoteHosts = credentialHosts(remote.networking ?? { type: remote.networking_type });
|
|
9820
|
+
const desiredLocation = desired.injection_location;
|
|
9821
|
+
const remoteLocation = remote.injection_location;
|
|
9822
|
+
if (desiredLocation && !remoteLocation) return false;
|
|
9823
|
+
return remote.secret_name === desired.secret_name && desiredHosts !== void 0 && remoteHosts !== void 0 && desiredHosts.length === remoteHosts.length && desiredHosts.every((host) => remoteHosts.includes(host)) && (desiredLocation?.header ?? true) === (remoteLocation?.header ?? true) && (desiredLocation?.body ?? false) === (remoteLocation?.body ?? false);
|
|
9824
|
+
}
|
|
9825
|
+
function credentialHosts(networking) {
|
|
9826
|
+
if (networking?.allowed_hosts !== void 0) return [...new Set(networking.allowed_hosts)];
|
|
9827
|
+
return networking?.type === "limited" ? void 0 : ["*"];
|
|
9828
|
+
}
|
|
9829
|
+
function metadataMatches(remote, desired) {
|
|
9830
|
+
const remoteEntries = Object.entries(remote ?? {});
|
|
9831
|
+
const desiredEntries = Object.entries(desired ?? {});
|
|
9832
|
+
return remoteEntries.length === desiredEntries.length && desiredEntries.every(([key, value]) => remote?.[key] === value);
|
|
9833
|
+
}
|
|
9834
|
+
|
|
8786
9835
|
// src/internal/core/destroy-runtime.ts
|
|
8787
9836
|
var destroyOrder = {
|
|
8788
9837
|
deployment: 0,
|
|
@@ -8805,11 +9854,14 @@ function planDestroyProjectContext(ctx) {
|
|
|
8805
9854
|
for (const [agentName, agent] of Object.entries(ctx.config.agents ?? {})) {
|
|
8806
9855
|
if (!agent.default_memory_store || agent.delivery?.qoder?.type !== "forward") continue;
|
|
8807
9856
|
if (agent.provider && agent.provider !== "qoder") continue;
|
|
9857
|
+
const identityId = identityName ? ctx.state.getResource({ type: "identity", name: identityName, provider: "qoder" })?.remote_id ?? null : null;
|
|
9858
|
+
const templateId = ctx.state.getResource({ type: "template", name: agentName, provider: "qoder" })?.remote_id ?? null;
|
|
9859
|
+
if (!identityId && !templateId) continue;
|
|
8808
9860
|
defaultMemoryStores.push({
|
|
8809
9861
|
agentName,
|
|
8810
9862
|
provider: "qoder",
|
|
8811
|
-
identityId
|
|
8812
|
-
templateId
|
|
9863
|
+
identityId,
|
|
9864
|
+
templateId,
|
|
8813
9865
|
deleteOnDestroy: agent.default_memory_store.delete_on_destroy ?? false
|
|
8814
9866
|
});
|
|
8815
9867
|
}
|
|
@@ -9322,6 +10374,7 @@ function buildAgentDecl(base, input) {
|
|
|
9322
10374
|
});
|
|
9323
10375
|
const agent = {
|
|
9324
10376
|
...base ?? {},
|
|
10377
|
+
name: input.name ?? base?.name,
|
|
9325
10378
|
description: input.description ?? base?.description,
|
|
9326
10379
|
model,
|
|
9327
10380
|
instructions: input.instructions ?? base?.instructions ?? "",
|
|
@@ -9365,6 +10418,7 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
|
|
|
9365
10418
|
throw new UserError(`Agent '${agentName}' not found in config. Available agents: ${available || "(none)"}`);
|
|
9366
10419
|
}
|
|
9367
10420
|
const sessionResources = options.resources ?? agent.resources;
|
|
10421
|
+
const sessionFiles = resolveSessionFiles(agentName, agent, provider, state, options.files ?? []);
|
|
9368
10422
|
const environmentVariables = options.environmentVariables ?? agent.environment_variables;
|
|
9369
10423
|
if (environmentVariables && provider !== "qoder") {
|
|
9370
10424
|
throw new UserError("Session environment variables are supported only by Qoder.");
|
|
@@ -9395,7 +10449,7 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
|
|
|
9395
10449
|
delivery: "forward",
|
|
9396
10450
|
template_id: templateId,
|
|
9397
10451
|
identity_id: identityId,
|
|
9398
|
-
files:
|
|
10452
|
+
files: sessionFiles,
|
|
9399
10453
|
title: options.title,
|
|
9400
10454
|
metadata: options.metadata,
|
|
9401
10455
|
environment_variables: environmentVariables
|
|
@@ -9440,13 +10494,41 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
|
|
|
9440
10494
|
tunnel_id: tunnelId,
|
|
9441
10495
|
vault_ids: vaultIds,
|
|
9442
10496
|
memory_store_ids: memoryStoreIds,
|
|
9443
|
-
files:
|
|
10497
|
+
files: sessionFiles,
|
|
9444
10498
|
resources: sessionResources,
|
|
9445
10499
|
title: options.title,
|
|
9446
10500
|
metadata: options.metadata,
|
|
9447
10501
|
environment_variables: environmentVariables
|
|
9448
10502
|
};
|
|
9449
10503
|
}
|
|
10504
|
+
function resolveSessionFiles(agentName, agent, provider, state, explicitFiles) {
|
|
10505
|
+
const resolved = [];
|
|
10506
|
+
const mountOwners = /* @__PURE__ */ new Map();
|
|
10507
|
+
for (const file of agent.files ?? []) {
|
|
10508
|
+
if (typeof file === "string") continue;
|
|
10509
|
+
const mountPath = resolveSandboxMountPath(provider, file.mount_path);
|
|
10510
|
+
assertUniqueMountPath(mountOwners, mountPath, `declared file '${file.file}'`, agentName);
|
|
10511
|
+
resolved.push({
|
|
10512
|
+
file_id: requireRef(state, { type: "file", name: file.file, provider }),
|
|
10513
|
+
mount_path: mountPath
|
|
10514
|
+
});
|
|
10515
|
+
}
|
|
10516
|
+
for (const file of explicitFiles) {
|
|
10517
|
+
const mountPath = resolveSandboxMountPath(provider, file.mountPath);
|
|
10518
|
+
assertUniqueMountPath(mountOwners, mountPath, `Session file '${file.fileId}'`, agentName);
|
|
10519
|
+
resolved.push({ file_id: file.fileId, mount_path: mountPath });
|
|
10520
|
+
}
|
|
10521
|
+
return resolved;
|
|
10522
|
+
}
|
|
10523
|
+
function assertUniqueMountPath(mountOwners, mountPath, owner, agentName) {
|
|
10524
|
+
const existing = mountOwners.get(mountPath);
|
|
10525
|
+
if (existing) {
|
|
10526
|
+
throw new UserError(
|
|
10527
|
+
`Agent '${agentName}' cannot mount ${owner} at '${mountPath}'; the path is already used by ${existing}.`
|
|
10528
|
+
);
|
|
10529
|
+
}
|
|
10530
|
+
mountOwners.set(mountPath, owner);
|
|
10531
|
+
}
|
|
9450
10532
|
function resolveTunnelId(agent, config, options, provider) {
|
|
9451
10533
|
const tunnelName = options.tunnel ?? agent.tunnel;
|
|
9452
10534
|
if (!options.tunnelId && !tunnelName) return void 0;
|
|
@@ -9466,6 +10548,74 @@ function validateResourceInConfig(name, type, resources) {
|
|
|
9466
10548
|
}
|
|
9467
10549
|
}
|
|
9468
10550
|
|
|
10551
|
+
// src/internal/state/backend.ts
|
|
10552
|
+
function cloneStateFile(state) {
|
|
10553
|
+
return structuredClone(state);
|
|
10554
|
+
}
|
|
10555
|
+
|
|
10556
|
+
// src/internal/state/in-memory-state-manager.ts
|
|
10557
|
+
var InMemoryStateManager = class _InMemoryStateManager {
|
|
10558
|
+
state;
|
|
10559
|
+
index;
|
|
10560
|
+
constructor(state) {
|
|
10561
|
+
this.state = state;
|
|
10562
|
+
this.index = this.buildIndex();
|
|
10563
|
+
}
|
|
10564
|
+
buildIndex() {
|
|
10565
|
+
const idx = /* @__PURE__ */ new Map();
|
|
10566
|
+
for (let i = 0; i < this.state.resources.length; i++) {
|
|
10567
|
+
idx.set(addressKey(this.state.resources[i].address), i);
|
|
10568
|
+
}
|
|
10569
|
+
return idx;
|
|
10570
|
+
}
|
|
10571
|
+
static fromJSON(data) {
|
|
10572
|
+
return new _InMemoryStateManager(structuredClone(data));
|
|
10573
|
+
}
|
|
10574
|
+
static empty() {
|
|
10575
|
+
return new _InMemoryStateManager({ resources: [] });
|
|
10576
|
+
}
|
|
10577
|
+
getResource(address) {
|
|
10578
|
+
const i = this.index.get(addressKey(address));
|
|
10579
|
+
return i !== void 0 ? this.state.resources[i] : void 0;
|
|
10580
|
+
}
|
|
10581
|
+
setResource(resource) {
|
|
10582
|
+
const key = addressKey(resource.address);
|
|
10583
|
+
const i = this.index.get(key);
|
|
10584
|
+
if (i !== void 0) {
|
|
10585
|
+
this.state.resources[i] = resource;
|
|
10586
|
+
} else {
|
|
10587
|
+
this.index.set(key, this.state.resources.length);
|
|
10588
|
+
this.state.resources.push(resource);
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
removeResource(address) {
|
|
10592
|
+
const key = addressKey(address);
|
|
10593
|
+
const i = this.index.get(key);
|
|
10594
|
+
if (i === void 0) return;
|
|
10595
|
+
this.state.resources.splice(i, 1);
|
|
10596
|
+
this.index.delete(key);
|
|
10597
|
+
for (let j = i; j < this.state.resources.length; j++) {
|
|
10598
|
+
this.index.set(addressKey(this.state.resources[j].address), j);
|
|
10599
|
+
}
|
|
10600
|
+
}
|
|
10601
|
+
listResources() {
|
|
10602
|
+
return [...this.state.resources];
|
|
10603
|
+
}
|
|
10604
|
+
findResource(query2) {
|
|
10605
|
+
return this.state.resources.find((resource) => {
|
|
10606
|
+
const matchType = resource.address.type === query2.type;
|
|
10607
|
+
const matchName = resource.address.name === query2.name;
|
|
10608
|
+
const matchProvider = !query2.provider || resource.address.provider === query2.provider;
|
|
10609
|
+
return matchType && matchName && matchProvider;
|
|
10610
|
+
});
|
|
10611
|
+
}
|
|
10612
|
+
getStateFile() {
|
|
10613
|
+
return this.state;
|
|
10614
|
+
}
|
|
10615
|
+
async save() {
|
|
10616
|
+
}
|
|
10617
|
+
};
|
|
10618
|
+
|
|
9469
10619
|
// src/internal/core/agent-runtime.ts
|
|
9470
10620
|
function listAgents(ctx) {
|
|
9471
10621
|
const agents = ctx.config.agents ?? {};
|
|
@@ -9556,34 +10706,64 @@ async function listAgentsWithReadiness(ctx, options = {}) {
|
|
|
9556
10706
|
readiness: getAgentReadinessFromPlan(ctx, agent.id, planResult.plan)
|
|
9557
10707
|
}));
|
|
9558
10708
|
}
|
|
10709
|
+
function isAgentRunnable(readiness) {
|
|
10710
|
+
return readiness.status === "ready" || readiness.status === "drifted" && readiness.driftSeverity === "non_blocking";
|
|
10711
|
+
}
|
|
9559
10712
|
async function planAgentResources(ctx, agentId, options = {}) {
|
|
9560
10713
|
const agent = getAgent(ctx, agentId);
|
|
10714
|
+
const addresses = collectAgentAddresses(ctx.config, agent.agentName, agent.provider);
|
|
9561
10715
|
const planned = await planProjectContext(ctx, {
|
|
9562
10716
|
provider: agent.provider,
|
|
10717
|
+
scope: { roots: options.scope === "runtime" ? addresses : [addresses[0]] },
|
|
10718
|
+
mode: options.mode,
|
|
9563
10719
|
refresh: options.refresh,
|
|
9564
|
-
quiet: options.quiet ?? true
|
|
10720
|
+
quiet: options.quiet ?? true,
|
|
10721
|
+
onFeedback: options.onFeedback
|
|
9565
10722
|
});
|
|
9566
|
-
const actions =
|
|
10723
|
+
const actions = planned.plan.actions;
|
|
10724
|
+
const diagnostics = planned.plan.diagnostics;
|
|
9567
10725
|
return {
|
|
9568
10726
|
agentId,
|
|
9569
10727
|
provider: agent.provider,
|
|
10728
|
+
fingerprint: computeAgentPlanFingerprint(agentId, agent.provider, actions, diagnostics),
|
|
9570
10729
|
actions,
|
|
9571
|
-
diagnostics
|
|
10730
|
+
diagnostics,
|
|
9572
10731
|
destructiveActions: selectDestructive(actions),
|
|
9573
10732
|
planned
|
|
9574
10733
|
};
|
|
9575
10734
|
}
|
|
10735
|
+
async function planAgentResourcesWithStateBackend(input, agentId, options = {}) {
|
|
10736
|
+
return readProjectRuntime(input, (ctx) => planAgentResources(ctx, agentId, options));
|
|
10737
|
+
}
|
|
9576
10738
|
async function syncAgentResources(ctx, agentId, options = {}) {
|
|
9577
10739
|
return runAgentSync(ctx, agentId, options);
|
|
9578
10740
|
}
|
|
9579
10741
|
async function runAgentSync(ctx, agentId, options) {
|
|
9580
|
-
const
|
|
10742
|
+
const transactionalState = options.expectedPlanFingerprint ? InMemoryStateManager.fromJSON(cloneStateFile(ctx.state.getStateFile())) : void 0;
|
|
10743
|
+
const planningContext = transactionalState ? { ...ctx, state: transactionalState } : ctx;
|
|
10744
|
+
const fullPlan = await planAgentResources(planningContext, agentId, {
|
|
9581
10745
|
refresh: options.refresh,
|
|
9582
|
-
quiet: options.quiet
|
|
10746
|
+
quiet: options.quiet,
|
|
10747
|
+
onFeedback: options.onFeedback,
|
|
10748
|
+
scope: options.scope,
|
|
10749
|
+
mode: options.mode
|
|
9583
10750
|
});
|
|
9584
10751
|
const actions = fullPlan.actions;
|
|
9585
10752
|
const destructiveActions = fullPlan.destructiveActions;
|
|
9586
10753
|
const errorDiagnostic = fullPlan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
10754
|
+
if (options.expectedPlanFingerprint && options.expectedPlanFingerprint !== fullPlan.fingerprint) {
|
|
10755
|
+
return {
|
|
10756
|
+
agentId,
|
|
10757
|
+
provider: fullPlan.provider,
|
|
10758
|
+
status: "blocked",
|
|
10759
|
+
reason: "plan_stale",
|
|
10760
|
+
actions,
|
|
10761
|
+
diagnostics: fullPlan.diagnostics,
|
|
10762
|
+
destructiveActions,
|
|
10763
|
+
results: [],
|
|
10764
|
+
error: "The project or remote resources changed after planning. Create a new plan before applying."
|
|
10765
|
+
};
|
|
10766
|
+
}
|
|
9587
10767
|
const decision = await decideDestructive(destructiveActions, {
|
|
9588
10768
|
policy: options.policy,
|
|
9589
10769
|
confirm: options.confirm
|
|
@@ -9593,6 +10773,7 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9593
10773
|
agentId,
|
|
9594
10774
|
provider: fullPlan.provider,
|
|
9595
10775
|
status: "blocked",
|
|
10776
|
+
reason: decision === "cancelled" ? "cancelled" : "destructive_blocked",
|
|
9596
10777
|
actions,
|
|
9597
10778
|
diagnostics: fullPlan.diagnostics,
|
|
9598
10779
|
destructiveActions,
|
|
@@ -9605,6 +10786,7 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9605
10786
|
agentId,
|
|
9606
10787
|
provider: fullPlan.provider,
|
|
9607
10788
|
status: "blocked",
|
|
10789
|
+
reason: "diagnostic_error",
|
|
9608
10790
|
actions,
|
|
9609
10791
|
diagnostics: fullPlan.diagnostics,
|
|
9610
10792
|
destructiveActions,
|
|
@@ -9613,13 +10795,11 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9613
10795
|
};
|
|
9614
10796
|
}
|
|
9615
10797
|
try {
|
|
9616
|
-
const
|
|
9617
|
-
|
|
9618
|
-
actions: scopePlanActions(fullPlan.planned.plan, actions)
|
|
9619
|
-
};
|
|
9620
|
-
const execution = await executePlannedProject(replaceResourcePlan(fullPlan.planned, scopedPlan), {
|
|
10798
|
+
const execution = await executePlannedProject(fullPlan.planned, {
|
|
10799
|
+
onFeedback: options.onFeedback,
|
|
9621
10800
|
policy: "force"
|
|
9622
10801
|
});
|
|
10802
|
+
if (transactionalState) await replaceState(ctx.state, transactionalState);
|
|
9623
10803
|
const results = toAgentSyncResults(execution);
|
|
9624
10804
|
const failed = results.find((result) => result.status === "failed");
|
|
9625
10805
|
return {
|
|
@@ -9633,6 +10813,7 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9633
10813
|
error: failed?.error
|
|
9634
10814
|
};
|
|
9635
10815
|
} catch (error) {
|
|
10816
|
+
if (transactionalState) await replaceState(ctx.state, transactionalState);
|
|
9636
10817
|
return {
|
|
9637
10818
|
agentId,
|
|
9638
10819
|
provider: fullPlan.provider,
|
|
@@ -9645,6 +10826,11 @@ async function runAgentSync(ctx, agentId, options) {
|
|
|
9645
10826
|
};
|
|
9646
10827
|
}
|
|
9647
10828
|
}
|
|
10829
|
+
async function replaceState(target, source) {
|
|
10830
|
+
for (const resource of target.listResources()) target.removeResource(resource.address);
|
|
10831
|
+
for (const resource of source.listResources()) target.setResource(resource);
|
|
10832
|
+
await target.save();
|
|
10833
|
+
}
|
|
9648
10834
|
async function syncAgentResourcesWithStateBackend(input, agentId, options = {}) {
|
|
9649
10835
|
return writeProjectRuntime(input, (ctx) => syncAgentResources(ctx, agentId, options));
|
|
9650
10836
|
}
|
|
@@ -9721,25 +10907,6 @@ function getAgentReadinessFromPlan(ctx, agentId, plan) {
|
|
|
9721
10907
|
plannedActions: relevantActions
|
|
9722
10908
|
};
|
|
9723
10909
|
}
|
|
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
10910
|
function actionKey(action) {
|
|
9744
10911
|
const address = action.address;
|
|
9745
10912
|
return `${action.action}:${address.provider}:${address.type}:${address.name}`;
|
|
@@ -9755,33 +10922,48 @@ function collectAgentAddresses(config, agentName, provider) {
|
|
|
9755
10922
|
}
|
|
9756
10923
|
const resolvedProvider = provider ?? resolveSessionProvider(agentName, config, void 0);
|
|
9757
10924
|
const materialization = resolveAgentMaterialization(resolvedProvider, agent);
|
|
9758
|
-
const
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
10925
|
+
const rootAddress = {
|
|
10926
|
+
type: materialization.resourceType,
|
|
10927
|
+
name: agentName,
|
|
10928
|
+
provider: resolvedProvider
|
|
10929
|
+
};
|
|
10930
|
+
const graph = buildDependencyGraph(config, [resolvedProvider]);
|
|
10931
|
+
const roots = [rootAddress];
|
|
10932
|
+
const visited = /* @__PURE__ */ new Set();
|
|
10933
|
+
function collectRuntimeRoots(name) {
|
|
10934
|
+
if (visited.has(name)) return;
|
|
10935
|
+
visited.add(name);
|
|
10936
|
+
const declaration = config.agents?.[name];
|
|
10937
|
+
if (!declaration) return;
|
|
10938
|
+
const type = resolveAgentMaterialization(resolvedProvider, declaration).resourceType;
|
|
10939
|
+
if (type === "template" && config.defaults?.identity) {
|
|
10940
|
+
roots.push({ type: "identity", name: config.defaults.identity, provider: resolvedProvider });
|
|
10941
|
+
}
|
|
10942
|
+
for (const subAgentName of declaration.multiagent?.agents ?? []) {
|
|
10943
|
+
const subAgent = config.agents?.[subAgentName];
|
|
10944
|
+
if (!subAgent) continue;
|
|
10945
|
+
roots.push({
|
|
10946
|
+
type: resolveAgentMaterialization(resolvedProvider, subAgent).resourceType,
|
|
10947
|
+
name: subAgentName,
|
|
10948
|
+
provider: resolvedProvider
|
|
10949
|
+
});
|
|
10950
|
+
collectRuntimeRoots(subAgentName);
|
|
9777
10951
|
}
|
|
9778
10952
|
}
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
10953
|
+
collectRuntimeRoots(agentName);
|
|
10954
|
+
return collectDependencyClosure(graph, roots);
|
|
10955
|
+
}
|
|
10956
|
+
function computeAgentPlanFingerprint(agentId, provider, actions, diagnostics) {
|
|
10957
|
+
const normalizedActions = actions.map((action) => ({
|
|
10958
|
+
...action,
|
|
10959
|
+
dependencies: [...action.dependencies].sort((left, right) => addressKey(left).localeCompare(addressKey(right)))
|
|
10960
|
+
})).sort((left, right) => actionKey(left).localeCompare(actionKey(right)));
|
|
10961
|
+
const normalizedDiagnostics = [...diagnostics].sort((left, right) => {
|
|
10962
|
+
const leftKey = `${left.resource ? addressKey(left.resource) : ""}:${left.severity}:${left.code}:${left.message}`;
|
|
10963
|
+
const rightKey = `${right.resource ? addressKey(right.resource) : ""}:${right.severity}:${right.code}:${right.message}`;
|
|
10964
|
+
return leftKey.localeCompare(rightKey);
|
|
10965
|
+
});
|
|
10966
|
+
return contentHash({ agentId, provider, actions: normalizedActions, diagnostics: normalizedDiagnostics });
|
|
9785
10967
|
}
|
|
9786
10968
|
function toAgentDefinition(config, agentName, agent) {
|
|
9787
10969
|
return {
|
|
@@ -10008,12 +11190,20 @@ async function listSessionEvents(ctx, sessionId, options = {}) {
|
|
|
10008
11190
|
const listOptions = {};
|
|
10009
11191
|
if (options.limit !== void 0) listOptions.limit = options.limit;
|
|
10010
11192
|
if (options.order !== void 0) listOptions.order = options.order;
|
|
11193
|
+
if (options.types !== void 0) listOptions.types = options.types;
|
|
11194
|
+
if (options.created_at_gt !== void 0) listOptions.created_at_gt = options.created_at_gt;
|
|
11195
|
+
if (options.created_at_gte !== void 0) listOptions.created_at_gte = options.created_at_gte;
|
|
11196
|
+
if (options.created_at_lt !== void 0) listOptions.created_at_lt = options.created_at_lt;
|
|
11197
|
+
if (options.created_at_lte !== void 0) listOptions.created_at_lte = options.created_at_lte;
|
|
10011
11198
|
const pageToken = options.page_token ?? options.page;
|
|
10012
11199
|
if (pageToken !== void 0) listOptions.page_token = pageToken;
|
|
10013
|
-
|
|
11200
|
+
const result = await resolveDirectAdapter(ctx, options.provider).listSessionEvents(
|
|
10014
11201
|
sessionId,
|
|
10015
11202
|
Object.keys(listOptions).length > 0 ? listOptions : void 0
|
|
10016
11203
|
);
|
|
11204
|
+
if (!options.types || options.types.length === 0) return result;
|
|
11205
|
+
const allowedTypes = new Set(options.types);
|
|
11206
|
+
return { ...result, events: result.events.filter((event) => allowedTypes.has(event.raw_type)) };
|
|
10017
11207
|
}
|
|
10018
11208
|
async function uploadFile(ctx, content, filename, options = {}) {
|
|
10019
11209
|
const adapter2 = resolveDirectAdapter(ctx, options.provider);
|
|
@@ -10063,12 +11253,89 @@ async function deleteSkill(ctx, id, options = {}) {
|
|
|
10063
11253
|
await resolveDirectAdapter(ctx, options.provider).deleteSkill(id);
|
|
10064
11254
|
}
|
|
10065
11255
|
function streamSessionEvents(ctx, sessionId, options = {}) {
|
|
11256
|
+
const adapter2 = resolveDirectAdapter(ctx, options.provider);
|
|
11257
|
+
if (options.after_id && !adapter2.eventResume) {
|
|
11258
|
+
return replaySessionEventsByPolling(adapter2, sessionId, options.after_id);
|
|
11259
|
+
}
|
|
10066
11260
|
const streamOptions = {};
|
|
10067
11261
|
if (options.after_id !== void 0) streamOptions.after_id = options.after_id;
|
|
10068
|
-
return
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
);
|
|
11262
|
+
return adapter2.streamSessionEvents(sessionId, Object.keys(streamOptions).length > 0 ? streamOptions : void 0);
|
|
11263
|
+
}
|
|
11264
|
+
async function* replaySessionEventsByPolling(adapter2, sessionId, afterId) {
|
|
11265
|
+
const history = await listAllSessionEventHistory(adapter2, sessionId);
|
|
11266
|
+
const markerIndex = history.findIndex((event) => event.id === afterId);
|
|
11267
|
+
if (markerIndex < 0) {
|
|
11268
|
+
throw new UserError(`Session event '${afterId}' was not found; list session events and choose a valid event id.`);
|
|
11269
|
+
}
|
|
11270
|
+
const knownEventKeys = new Set(history.slice(0, markerIndex + 1).map(sessionEventKey));
|
|
11271
|
+
for (const event of history.slice(markerIndex + 1)) {
|
|
11272
|
+
const eventKey = sessionEventKey(event);
|
|
11273
|
+
if (knownEventKeys.has(eventKey)) continue;
|
|
11274
|
+
knownEventKeys.add(eventKey);
|
|
11275
|
+
yield event;
|
|
11276
|
+
if (event.type === "status" && isTerminalSessionStatus(event.status)) return;
|
|
11277
|
+
}
|
|
11278
|
+
while (true) {
|
|
11279
|
+
const newEvents = await listNewSessionEvents(adapter2, sessionId, knownEventKeys);
|
|
11280
|
+
for (const event of newEvents) {
|
|
11281
|
+
const eventKey = sessionEventKey(event);
|
|
11282
|
+
if (knownEventKeys.has(eventKey)) continue;
|
|
11283
|
+
knownEventKeys.add(eventKey);
|
|
11284
|
+
yield event;
|
|
11285
|
+
if (event.type === "status" && isTerminalSessionStatus(event.status)) return;
|
|
11286
|
+
}
|
|
11287
|
+
const session = await adapter2.getSession(sessionId);
|
|
11288
|
+
if (isTerminalSessionStatus(session.status)) return;
|
|
11289
|
+
await delay2(DEFAULT_POLL_INTERVAL_MS);
|
|
11290
|
+
}
|
|
11291
|
+
}
|
|
11292
|
+
async function listAllSessionEventHistory(adapter2, sessionId) {
|
|
11293
|
+
const events = [];
|
|
11294
|
+
const seenPageTokens = /* @__PURE__ */ new Set();
|
|
11295
|
+
let pageToken;
|
|
11296
|
+
while (true) {
|
|
11297
|
+
const result = await adapter2.listSessionEvents(sessionId, {
|
|
11298
|
+
limit: 100,
|
|
11299
|
+
order: "asc",
|
|
11300
|
+
...pageToken ? { page_token: pageToken } : {}
|
|
11301
|
+
});
|
|
11302
|
+
events.push(...result.events);
|
|
11303
|
+
if (!result.next_page) return events;
|
|
11304
|
+
if (seenPageTokens.has(result.next_page)) {
|
|
11305
|
+
throw new UserError("Session event pagination returned a repeated cursor.");
|
|
11306
|
+
}
|
|
11307
|
+
seenPageTokens.add(result.next_page);
|
|
11308
|
+
pageToken = result.next_page;
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
async function listNewSessionEvents(adapter2, sessionId, knownEventKeys) {
|
|
11312
|
+
const descendingEvents = [];
|
|
11313
|
+
const seenPageTokens = /* @__PURE__ */ new Set();
|
|
11314
|
+
let pageToken;
|
|
11315
|
+
while (true) {
|
|
11316
|
+
const result = await adapter2.listSessionEvents(sessionId, {
|
|
11317
|
+
limit: 100,
|
|
11318
|
+
order: "desc",
|
|
11319
|
+
...pageToken ? { page_token: pageToken } : {}
|
|
11320
|
+
});
|
|
11321
|
+
let reachedKnownEvent = false;
|
|
11322
|
+
for (const event of result.events) {
|
|
11323
|
+
if (knownEventKeys.has(sessionEventKey(event))) {
|
|
11324
|
+
reachedKnownEvent = true;
|
|
11325
|
+
break;
|
|
11326
|
+
}
|
|
11327
|
+
descendingEvents.push(event);
|
|
11328
|
+
}
|
|
11329
|
+
if (reachedKnownEvent || !result.next_page) return descendingEvents.reverse();
|
|
11330
|
+
if (seenPageTokens.has(result.next_page)) {
|
|
11331
|
+
throw new UserError("Session event pagination returned a repeated cursor.");
|
|
11332
|
+
}
|
|
11333
|
+
seenPageTokens.add(result.next_page);
|
|
11334
|
+
pageToken = result.next_page;
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
function sessionEventKey(event) {
|
|
11338
|
+
return event.id ?? `raw:${event.raw_type}:${JSON.stringify(event.raw)}`;
|
|
10072
11339
|
}
|
|
10073
11340
|
function resolveDirectAdapter(ctx, overrideProvider) {
|
|
10074
11341
|
if (overrideProvider) return getRuntimeProvider(ctx, overrideProvider);
|
|
@@ -10141,7 +11408,7 @@ function delay2(ms) {
|
|
|
10141
11408
|
import { readFileSync as readFileSync8 } from "fs";
|
|
10142
11409
|
import { readFile as readFile5 } from "fs/promises";
|
|
10143
11410
|
import { homedir } from "os";
|
|
10144
|
-
import { dirname as
|
|
11411
|
+
import { dirname as dirname12, join } from "path";
|
|
10145
11412
|
var AGENTS_CONFIG_PROVIDERS = ["bailian", "qoder", "ark", "claude"];
|
|
10146
11413
|
var AGENTS_PROVIDER_FIELDS = {
|
|
10147
11414
|
bailian: [
|
|
@@ -10210,7 +11477,7 @@ function loadDotEnv(startDir = process.cwd()) {
|
|
|
10210
11477
|
return envPath;
|
|
10211
11478
|
} catch {
|
|
10212
11479
|
}
|
|
10213
|
-
const parent =
|
|
11480
|
+
const parent = dirname12(dir);
|
|
10214
11481
|
if (parent === dir) break;
|
|
10215
11482
|
dir = parent;
|
|
10216
11483
|
}
|
|
@@ -10294,7 +11561,7 @@ function parseStateAddress(address, options = {}) {
|
|
|
10294
11561
|
|
|
10295
11562
|
// src/internal/state/state-manager.ts
|
|
10296
11563
|
import { mkdir, readFile as readFile6, rename, unlink, writeFile } from "fs/promises";
|
|
10297
|
-
import { dirname as
|
|
11564
|
+
import { dirname as dirname13 } from "path";
|
|
10298
11565
|
var StateManager = class _StateManager {
|
|
10299
11566
|
state;
|
|
10300
11567
|
path;
|
|
@@ -10385,7 +11652,7 @@ var StateManager = class _StateManager {
|
|
|
10385
11652
|
return this.state;
|
|
10386
11653
|
}
|
|
10387
11654
|
async save() {
|
|
10388
|
-
await mkdir(
|
|
11655
|
+
await mkdir(dirname13(this.path), { recursive: true });
|
|
10389
11656
|
const tmpPath = `${this.path}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
10390
11657
|
try {
|
|
10391
11658
|
await writeFile(tmpPath, `${JSON.stringify(this.state, null, 2)}
|
|
@@ -10407,74 +11674,6 @@ function deriveStatePath(configPath) {
|
|
|
10407
11674
|
return /\.ya?ml$/i.test(configPath) ? configPath.replace(/\.ya?ml$/i, ".state.json") : `${configPath}.state.json`;
|
|
10408
11675
|
}
|
|
10409
11676
|
|
|
10410
|
-
// src/internal/state/backend.ts
|
|
10411
|
-
function cloneStateFile(state) {
|
|
10412
|
-
return structuredClone(state);
|
|
10413
|
-
}
|
|
10414
|
-
|
|
10415
|
-
// src/internal/state/in-memory-state-manager.ts
|
|
10416
|
-
var InMemoryStateManager = class _InMemoryStateManager {
|
|
10417
|
-
state;
|
|
10418
|
-
index;
|
|
10419
|
-
constructor(state) {
|
|
10420
|
-
this.state = state;
|
|
10421
|
-
this.index = this.buildIndex();
|
|
10422
|
-
}
|
|
10423
|
-
buildIndex() {
|
|
10424
|
-
const idx = /* @__PURE__ */ new Map();
|
|
10425
|
-
for (let i = 0; i < this.state.resources.length; i++) {
|
|
10426
|
-
idx.set(addressKey(this.state.resources[i].address), i);
|
|
10427
|
-
}
|
|
10428
|
-
return idx;
|
|
10429
|
-
}
|
|
10430
|
-
static fromJSON(data) {
|
|
10431
|
-
return new _InMemoryStateManager(structuredClone(data));
|
|
10432
|
-
}
|
|
10433
|
-
static empty() {
|
|
10434
|
-
return new _InMemoryStateManager({ resources: [] });
|
|
10435
|
-
}
|
|
10436
|
-
getResource(address) {
|
|
10437
|
-
const i = this.index.get(addressKey(address));
|
|
10438
|
-
return i !== void 0 ? this.state.resources[i] : void 0;
|
|
10439
|
-
}
|
|
10440
|
-
setResource(resource) {
|
|
10441
|
-
const key = addressKey(resource.address);
|
|
10442
|
-
const i = this.index.get(key);
|
|
10443
|
-
if (i !== void 0) {
|
|
10444
|
-
this.state.resources[i] = resource;
|
|
10445
|
-
} else {
|
|
10446
|
-
this.index.set(key, this.state.resources.length);
|
|
10447
|
-
this.state.resources.push(resource);
|
|
10448
|
-
}
|
|
10449
|
-
}
|
|
10450
|
-
removeResource(address) {
|
|
10451
|
-
const key = addressKey(address);
|
|
10452
|
-
const i = this.index.get(key);
|
|
10453
|
-
if (i === void 0) return;
|
|
10454
|
-
this.state.resources.splice(i, 1);
|
|
10455
|
-
this.index.delete(key);
|
|
10456
|
-
for (let j = i; j < this.state.resources.length; j++) {
|
|
10457
|
-
this.index.set(addressKey(this.state.resources[j].address), j);
|
|
10458
|
-
}
|
|
10459
|
-
}
|
|
10460
|
-
listResources() {
|
|
10461
|
-
return [...this.state.resources];
|
|
10462
|
-
}
|
|
10463
|
-
findResource(query2) {
|
|
10464
|
-
return this.state.resources.find((resource) => {
|
|
10465
|
-
const matchType = resource.address.type === query2.type;
|
|
10466
|
-
const matchName = resource.address.name === query2.name;
|
|
10467
|
-
const matchProvider = !query2.provider || resource.address.provider === query2.provider;
|
|
10468
|
-
return matchType && matchName && matchProvider;
|
|
10469
|
-
});
|
|
10470
|
-
}
|
|
10471
|
-
getStateFile() {
|
|
10472
|
-
return this.state;
|
|
10473
|
-
}
|
|
10474
|
-
async save() {
|
|
10475
|
-
}
|
|
10476
|
-
};
|
|
10477
|
-
|
|
10478
11677
|
// src/internal/state/local-file-state-backend.ts
|
|
10479
11678
|
var LocalFileStateBackend = class {
|
|
10480
11679
|
configPath;
|
|
@@ -10600,7 +11799,8 @@ var CloudAgentSchema = z6.object({
|
|
|
10600
11799
|
workspace_id: z6.string().optional(),
|
|
10601
11800
|
created_at: z6.string().optional(),
|
|
10602
11801
|
updated_at: z6.string().optional(),
|
|
10603
|
-
archived_at: z6.string().nullish()
|
|
11802
|
+
archived_at: z6.string().nullish(),
|
|
11803
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10604
11804
|
});
|
|
10605
11805
|
var ListCloudAgentsResponseSchema = z6.object({
|
|
10606
11806
|
agents: z6.array(CloudAgentSchema)
|
|
@@ -10617,7 +11817,8 @@ var CloudEnvironmentSchema = z6.object({
|
|
|
10617
11817
|
workspace_id: z6.string().optional(),
|
|
10618
11818
|
created_at: z6.string().optional(),
|
|
10619
11819
|
updated_at: z6.string().optional(),
|
|
10620
|
-
archived_at: z6.string().nullish()
|
|
11820
|
+
archived_at: z6.string().nullish(),
|
|
11821
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10621
11822
|
});
|
|
10622
11823
|
var ListCloudEnvironmentsResponseSchema = z6.object({
|
|
10623
11824
|
environments: z6.array(CloudEnvironmentSchema)
|
|
@@ -10629,7 +11830,8 @@ var CloudVaultSchema = z6.object({
|
|
|
10629
11830
|
type: z6.string().optional(),
|
|
10630
11831
|
created_at: z6.string().nullish(),
|
|
10631
11832
|
updated_at: z6.string().nullish(),
|
|
10632
|
-
archived_at: z6.string().nullish()
|
|
11833
|
+
archived_at: z6.string().nullish(),
|
|
11834
|
+
attributes: z6.record(z6.string(), z6.unknown()).optional()
|
|
10633
11835
|
});
|
|
10634
11836
|
var ListCloudVaultsResponseSchema = z6.object({
|
|
10635
11837
|
vaults: z6.array(CloudVaultSchema)
|
|
@@ -10644,6 +11846,7 @@ var SessionEventTypeSchema = z6.enum([
|
|
|
10644
11846
|
"unknown"
|
|
10645
11847
|
]);
|
|
10646
11848
|
var AgentSyncStatusSchema = z6.enum(["completed", "blocked", "failed"]);
|
|
11849
|
+
var AgentSyncReasonSchema = z6.enum(["destructive_blocked", "cancelled", "diagnostic_error", "plan_stale"]);
|
|
10647
11850
|
var AgentSyncResultSchema = z6.object({
|
|
10648
11851
|
action: PlannedActionSchema,
|
|
10649
11852
|
status: z6.enum(["success", "failed", "skipped"]),
|
|
@@ -10653,6 +11856,7 @@ var AgentSyncRunSchema = z6.object({
|
|
|
10653
11856
|
agentId: z6.string(),
|
|
10654
11857
|
provider: z6.string().optional(),
|
|
10655
11858
|
status: AgentSyncStatusSchema,
|
|
11859
|
+
reason: AgentSyncReasonSchema.optional(),
|
|
10656
11860
|
actions: z6.array(PlannedActionSchema),
|
|
10657
11861
|
diagnostics: z6.array(DiagnosticSchema),
|
|
10658
11862
|
destructiveActions: z6.array(PlannedActionSchema),
|
|
@@ -10770,6 +11974,7 @@ export {
|
|
|
10770
11974
|
AgentReadinessStatusSchema,
|
|
10771
11975
|
AgentRecoveryActionSchema,
|
|
10772
11976
|
AgentSkillRefSchema,
|
|
11977
|
+
AgentSyncReasonSchema,
|
|
10773
11978
|
AgentSyncResultSchema,
|
|
10774
11979
|
AgentSyncRunSchema,
|
|
10775
11980
|
AgentSyncStatusSchema,
|
|
@@ -10809,6 +12014,7 @@ export {
|
|
|
10809
12014
|
applyProviderConfigToEnv,
|
|
10810
12015
|
archiveCloudAgent,
|
|
10811
12016
|
archiveMemoryStore,
|
|
12017
|
+
archiveRemoteSession,
|
|
10812
12018
|
areRuntimeCredentialsReady,
|
|
10813
12019
|
batchCreateMemories,
|
|
10814
12020
|
bootstrapRuntimeCredentials,
|
|
@@ -10822,6 +12028,8 @@ export {
|
|
|
10822
12028
|
createProjectRuntime,
|
|
10823
12029
|
createSessionForAgent,
|
|
10824
12030
|
createSkillFromFileId,
|
|
12031
|
+
createVaultCredential,
|
|
12032
|
+
createVaultCredentialWithStateBackend,
|
|
10825
12033
|
decideDestructive,
|
|
10826
12034
|
deleteCloudEnvironment,
|
|
10827
12035
|
deleteCloudVault,
|
|
@@ -10831,6 +12039,8 @@ export {
|
|
|
10831
12039
|
deleteSession,
|
|
10832
12040
|
deleteSkill,
|
|
10833
12041
|
destroyPlannedProjectResources,
|
|
12042
|
+
downloadRemoteFile,
|
|
12043
|
+
downloadRemoteSkill,
|
|
10834
12044
|
executePlannedProject,
|
|
10835
12045
|
extractSkillZipFiles,
|
|
10836
12046
|
getAgent,
|
|
@@ -10838,13 +12048,25 @@ export {
|
|
|
10838
12048
|
getDeploymentRuntimeProviderForContext,
|
|
10839
12049
|
getFileDownloadUrl,
|
|
10840
12050
|
getFileInfo,
|
|
12051
|
+
getManagedAgentProviderCapabilities,
|
|
10841
12052
|
getMemory,
|
|
10842
12053
|
getMemoryProviderCapabilities,
|
|
10843
12054
|
getMemoryStore,
|
|
10844
12055
|
getMemoryVersion,
|
|
12056
|
+
getRemoteAgent,
|
|
12057
|
+
getRemoteDeployment,
|
|
12058
|
+
getRemoteDeploymentRun,
|
|
12059
|
+
getRemoteEnvironment,
|
|
12060
|
+
getRemoteSkill,
|
|
12061
|
+
getRemoteSkillDownloadInfo,
|
|
12062
|
+
getRemoteSkillVersion,
|
|
12063
|
+
getRemoteVault,
|
|
10845
12064
|
getSession,
|
|
10846
12065
|
getSkillInfo,
|
|
10847
12066
|
importResource,
|
|
12067
|
+
inspectProjectSource,
|
|
12068
|
+
inspectSkillSource,
|
|
12069
|
+
isAgentRunnable,
|
|
10848
12070
|
isTerminalSessionStatus,
|
|
10849
12071
|
listAgentsWithReadiness,
|
|
10850
12072
|
listCloudAgents,
|
|
@@ -10857,7 +12079,16 @@ export {
|
|
|
10857
12079
|
listMemoryVersions,
|
|
10858
12080
|
listProviderModelsForContext,
|
|
10859
12081
|
listProviderNames,
|
|
12082
|
+
listRemoteAgentVersions,
|
|
12083
|
+
listRemoteAgents,
|
|
12084
|
+
listRemoteDeploymentRuns,
|
|
12085
|
+
listRemoteDeployments,
|
|
10860
12086
|
listRemoteDeploymentsForContext,
|
|
12087
|
+
listRemoteEnvironments,
|
|
12088
|
+
listRemoteFiles,
|
|
12089
|
+
listRemoteSkillVersions,
|
|
12090
|
+
listRemoteSkills,
|
|
12091
|
+
listRemoteVaults,
|
|
10861
12092
|
listSessionEvents,
|
|
10862
12093
|
listSessionSummaries,
|
|
10863
12094
|
listSkills,
|
|
@@ -10867,8 +12098,13 @@ export {
|
|
|
10867
12098
|
migrateConfig,
|
|
10868
12099
|
parseStateAddress,
|
|
10869
12100
|
pauseDeploymentForContext,
|
|
12101
|
+
planAgentResources,
|
|
12102
|
+
planAgentResourcesWithStateBackend,
|
|
10870
12103
|
planDestroyProjectContext,
|
|
10871
12104
|
planProjectContext,
|
|
12105
|
+
planProjectWithStateBackend,
|
|
12106
|
+
planVaultCredentialCreate,
|
|
12107
|
+
planVaultCredentialCreateWithStateBackend,
|
|
10872
12108
|
prepareInitialSessionPrompt,
|
|
10873
12109
|
preparePromptForProvider,
|
|
10874
12110
|
prependFileHint,
|
|
@@ -10884,9 +12120,12 @@ export {
|
|
|
10884
12120
|
resolveSyncProvider,
|
|
10885
12121
|
rewriteFileMentions,
|
|
10886
12122
|
runDeploymentForContext,
|
|
12123
|
+
runRemoteDeployment,
|
|
12124
|
+
sendRemoteSessionEvents,
|
|
10887
12125
|
sendSessionMessagePolling,
|
|
10888
12126
|
sendSessionMessageStreaming,
|
|
10889
12127
|
setDefaultFetch,
|
|
12128
|
+
setRemoteDeploymentPaused,
|
|
10890
12129
|
startSessionRun,
|
|
10891
12130
|
startSessionRunPolling,
|
|
10892
12131
|
streamSessionEvents,
|
|
@@ -10896,6 +12135,7 @@ export {
|
|
|
10896
12135
|
syncProviderResourcesFromEnv,
|
|
10897
12136
|
updateMemory,
|
|
10898
12137
|
updateMemoryStore,
|
|
12138
|
+
updateRemoteSession,
|
|
10899
12139
|
uploadFile,
|
|
10900
12140
|
validateProjectConfig,
|
|
10901
12141
|
writeProjectRuntime
|