@bnbagent/studio-cli 0.0.11-alpha.4 → 0.0.11-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bag.js +91 -16
- package/dist/{chunk-GKFTJDDJ.js → chunk-XY6EZGQF.js} +48 -11
- package/dist/{deployCli-YYV7FFFG.js → deployCli-OQICQCKT.js} +1 -1
- package/package.json +2 -2
- package/skills/bnbagent-studio.md +4 -4
- package/skills/references/bnbagent-studio-adding-to-project.md +1 -1
- package/skills/references/bnbagent-studio-scaffolding-agent.md +4 -4
- package/skills/references/bnbagent-studio-selling-via-8183.md +1 -1
- package/skills/references/bnbagent-studio-use-aws-agentcore.md +1 -1
- package/skills/references/bnbagent-studio-use-azure-foundry.md +8 -7
- package/skills/references/bnbagent-studio-use-bnb-trial.md +1 -1
package/dist/bag.js
CHANGED
|
@@ -47,10 +47,12 @@ import {
|
|
|
47
47
|
whichBin,
|
|
48
48
|
withDeployFiles,
|
|
49
49
|
x402DeploySummary,
|
|
50
|
+
x402DeploySummaryFromSnapshot,
|
|
51
|
+
x402DeploymentSnapshot,
|
|
50
52
|
x402SellerIsFree,
|
|
51
53
|
x402SellerPricingState,
|
|
52
54
|
x402SellerUsesB402
|
|
53
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-XY6EZGQF.js";
|
|
54
56
|
import {
|
|
55
57
|
TWAK_CLI_MIN_VERSION,
|
|
56
58
|
TWAK_CLI_VERSION,
|
|
@@ -228,7 +230,7 @@ import {
|
|
|
228
230
|
var CAMPAIGN_DOC_URL = "https://www.bnbchain.org/en/blog/bnb-agent-studio-is-live-on-bnb-chain-ai-agents-from-one-prompt";
|
|
229
231
|
var CAMPAIGN_CHECK_TIMEOUT_MS = 6e3;
|
|
230
232
|
async function fetchCampaignActive() {
|
|
231
|
-
const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-
|
|
233
|
+
const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-OQICQCKT.js");
|
|
232
234
|
const controller = new AbortController();
|
|
233
235
|
const timer = setTimeout(() => controller.abort(), CAMPAIGN_CHECK_TIMEOUT_MS);
|
|
234
236
|
try {
|
|
@@ -3363,6 +3365,21 @@ function protocolFaces(value) {
|
|
|
3363
3365
|
return null;
|
|
3364
3366
|
}
|
|
3365
3367
|
}
|
|
3368
|
+
function recordedX402Snapshot(azure) {
|
|
3369
|
+
const status = text(azure.deployed_x402_status);
|
|
3370
|
+
const priceMode = text(azure.deployed_x402_price_mode);
|
|
3371
|
+
const credentialsComplete = azure.deployed_x402_credentials_complete;
|
|
3372
|
+
if (!["active", "free", "dormant"].includes(status ?? "") || !["paid", "free", "invalid"].includes(priceMode ?? "") || typeof credentialsComplete !== "boolean") {
|
|
3373
|
+
return null;
|
|
3374
|
+
}
|
|
3375
|
+
const expectedStatus = priceMode === "free" ? "free" : priceMode === "paid" && credentialsComplete ? "active" : "dormant";
|
|
3376
|
+
if (status !== expectedStatus) return null;
|
|
3377
|
+
return {
|
|
3378
|
+
status,
|
|
3379
|
+
priceMode,
|
|
3380
|
+
credentialsComplete
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3366
3383
|
function descriptorName(workspaceRoot) {
|
|
3367
3384
|
try {
|
|
3368
3385
|
const data = JSON.parse(
|
|
@@ -3420,6 +3437,7 @@ function discoverRecordedDeployments(root) {
|
|
|
3420
3437
|
const azureEndpoint = text(azure.agent_endpoint);
|
|
3421
3438
|
const azureDeploymentId = text(azure.deployment_id);
|
|
3422
3439
|
const azureFaces = protocolFaces(azure.deployed_faces);
|
|
3440
|
+
const azureX402 = recordedX402Snapshot(azure);
|
|
3423
3441
|
if (azureEndpoint || azureDeploymentId || text(azure.last_deploy_at)) {
|
|
3424
3442
|
found.push({
|
|
3425
3443
|
provider: "azure",
|
|
@@ -3428,6 +3446,7 @@ function discoverRecordedDeployments(root) {
|
|
|
3428
3446
|
deploymentId: azureDeploymentId,
|
|
3429
3447
|
endpoint: azureEndpoint,
|
|
3430
3448
|
...azureFaces ? { faces: azureFaces } : {},
|
|
3449
|
+
...azureX402 ? { x402: azureX402 } : {},
|
|
3431
3450
|
status: "active"
|
|
3432
3451
|
});
|
|
3433
3452
|
}
|
|
@@ -4175,9 +4194,13 @@ function recordAzureDeployment(root, data, endpoint) {
|
|
|
4175
4194
|
if (agentRoot2 === null) return;
|
|
4176
4195
|
const tomlPath = path16.join(agentRoot2, "studio.toml");
|
|
4177
4196
|
let deployedFaces = null;
|
|
4197
|
+
let deployedX402 = null;
|
|
4178
4198
|
try {
|
|
4179
4199
|
const cfg = loadStudioCfg(deployWorkspaceRoot(root));
|
|
4180
4200
|
deployedFaces = stackFaces(tableOf4(cfg, "stack"), tableOf4(cfg, "payments"));
|
|
4201
|
+
if (hasX402Face(deployedFaces)) {
|
|
4202
|
+
deployedX402 = x402DeploymentSnapshot(agentRoot2, "self");
|
|
4203
|
+
}
|
|
4181
4204
|
} catch {
|
|
4182
4205
|
}
|
|
4183
4206
|
try {
|
|
@@ -4192,6 +4215,24 @@ function recordAzureDeployment(root, data, endpoint) {
|
|
|
4192
4215
|
}
|
|
4193
4216
|
if (deployedFaces) {
|
|
4194
4217
|
patchTomlKv(tomlPath, "azure", "deployed_faces", deployedFaces);
|
|
4218
|
+
patchTomlKv(
|
|
4219
|
+
tomlPath,
|
|
4220
|
+
"azure",
|
|
4221
|
+
"deployed_x402_status",
|
|
4222
|
+
deployedX402?.status ?? ""
|
|
4223
|
+
);
|
|
4224
|
+
patchTomlKv(
|
|
4225
|
+
tomlPath,
|
|
4226
|
+
"azure",
|
|
4227
|
+
"deployed_x402_price_mode",
|
|
4228
|
+
deployedX402?.priceMode ?? ""
|
|
4229
|
+
);
|
|
4230
|
+
patchTomlKv(
|
|
4231
|
+
tomlPath,
|
|
4232
|
+
"azure",
|
|
4233
|
+
"deployed_x402_credentials_complete",
|
|
4234
|
+
deployedX402?.credentialsComplete ?? false
|
|
4235
|
+
);
|
|
4195
4236
|
}
|
|
4196
4237
|
patchTomlKv(tomlPath, "azure", "last_deploy_at", (/* @__PURE__ */ new Date()).toISOString());
|
|
4197
4238
|
} catch {
|
|
@@ -4211,6 +4252,9 @@ function clearAzureEndpoint(root) {
|
|
|
4211
4252
|
patchTomlKv(tomlPath, "azure", key, "");
|
|
4212
4253
|
}
|
|
4213
4254
|
patchTomlKv(tomlPath, "azure", "deployed_faces", []);
|
|
4255
|
+
patchTomlKv(tomlPath, "azure", "deployed_x402_status", "");
|
|
4256
|
+
patchTomlKv(tomlPath, "azure", "deployed_x402_price_mode", "");
|
|
4257
|
+
patchTomlKv(tomlPath, "azure", "deployed_x402_credentials_complete", false);
|
|
4214
4258
|
} catch {
|
|
4215
4259
|
}
|
|
4216
4260
|
}
|
|
@@ -7901,7 +7945,7 @@ function registerInit(program) {
|
|
|
7901
7945
|
).addOption(
|
|
7902
7946
|
new Option2(
|
|
7903
7947
|
"--protocols <faces>",
|
|
7904
|
-
"Comma-separated public faces to expose; recorded in studio.toml [stack].protocols. Any non-empty combination of A2A, MCP, X402 (case-insensitive; default: A2A)."
|
|
7948
|
+
"Comma-separated public faces to expose; recorded in studio.toml [stack].protocols. Any non-empty combination of A2A, MCP, X402 (case-insensitive; default: A2A,X402)."
|
|
7905
7949
|
)
|
|
7906
7950
|
).addOption(
|
|
7907
7951
|
new Option2(
|
|
@@ -7911,7 +7955,7 @@ function registerInit(program) {
|
|
|
7911
7955
|
).addOption(
|
|
7912
7956
|
new Option2(
|
|
7913
7957
|
"--rails <rails>",
|
|
7914
|
-
"Commerce rail(s) to scaffold: 8183
|
|
7958
|
+
"Commerce rail(s) to scaffold: 8183, b402, or both (default; Altana defaults to 8183)."
|
|
7915
7959
|
).choices(["8183", "b402", "both"])
|
|
7916
7960
|
).option(
|
|
7917
7961
|
"--erc8183-price <base-units>",
|
|
@@ -8063,9 +8107,12 @@ async function cmdInitFlow(nameArg, opts) {
|
|
|
8063
8107
|
printErr("error: pass either --protocols or --protocol, not both.");
|
|
8064
8108
|
return 2;
|
|
8065
8109
|
}
|
|
8110
|
+
const facesExplicit = opts.protocols !== void 0 || opts.protocol !== void 0;
|
|
8066
8111
|
let faces;
|
|
8067
8112
|
try {
|
|
8068
|
-
faces = normalizeProtocolFaces(
|
|
8113
|
+
faces = normalizeProtocolFaces(
|
|
8114
|
+
opts.protocols ?? opts.protocol ?? "A2A,X402"
|
|
8115
|
+
);
|
|
8069
8116
|
if (opts.protocol !== void 0 && faces.length !== 1) {
|
|
8070
8117
|
throw new Error("--protocol is a single-face alias; use --protocols");
|
|
8071
8118
|
}
|
|
@@ -8101,7 +8148,13 @@ async function cmdInitFlow(nameArg, opts) {
|
|
|
8101
8148
|
if (llmProvider === null) {
|
|
8102
8149
|
return 2;
|
|
8103
8150
|
}
|
|
8104
|
-
|
|
8151
|
+
const inferredRails = opts.rails ?? (facesExplicit ? hasX402Face(faces) ? "both" : "8183" : walletKind2 === "altana" ? "8183" : void 0);
|
|
8152
|
+
let rails = await resolveRails(inferredRails, isTty);
|
|
8153
|
+
if (!facesExplicit) {
|
|
8154
|
+
faces = normalizeProtocolFaces(
|
|
8155
|
+
rails === "8183" ? ["A2A"] : ["A2A", "X402"]
|
|
8156
|
+
);
|
|
8157
|
+
}
|
|
8105
8158
|
if (hasX402Face(faces) && rails === "8183") {
|
|
8106
8159
|
rails = "both";
|
|
8107
8160
|
} else if (hasX402Face(faces) && rails !== "both") {
|
|
@@ -8855,6 +8908,9 @@ function renderAzureSection(name, account, project) {
|
|
|
8855
8908
|
[azure]
|
|
8856
8909
|
# Hosted-Agents-supported region (eastus does NOT support Hosted Agents).
|
|
8857
8910
|
location = "${DEFAULT_LOCATION}"
|
|
8911
|
+
# Optional Azure subscription id. Set it when the signed-in identity can access
|
|
8912
|
+
# more than one subscription so non-interactive deploy never guesses.
|
|
8913
|
+
subscription_id = ""
|
|
8858
8914
|
# account_name MUST equal subdomain \u2014 the runtime derives the storage host
|
|
8859
8915
|
# (https://{account_name}.services.ai.azure.com) from it; a mismatch is NXDOMAIN.
|
|
8860
8916
|
account_name = "${azureName}"
|
|
@@ -9261,13 +9317,15 @@ async function resolveRails(flagValue, isTty) {
|
|
|
9261
9317
|
if (flagValue === "8183" || flagValue === "b402" || flagValue === "both") {
|
|
9262
9318
|
return flagValue;
|
|
9263
9319
|
}
|
|
9264
|
-
if (!isTty) return "
|
|
9265
|
-
const answer = (await promptUser("Commerce rails [8183/b402/both, Enter =
|
|
9266
|
-
if (answer === "b402" || answer === "both")
|
|
9267
|
-
|
|
9268
|
-
|
|
9320
|
+
if (!isTty) return "both";
|
|
9321
|
+
const answer = (await promptUser("Commerce rails [8183/b402/both, Enter = both]: ")).trim().toLowerCase();
|
|
9322
|
+
if (answer === "8183" || answer === "b402" || answer === "both") {
|
|
9323
|
+
return answer;
|
|
9324
|
+
}
|
|
9325
|
+
if (answer !== "") {
|
|
9326
|
+
printErr(`hint: unknown commerce rail '${answer}' \u2014 using both.`);
|
|
9269
9327
|
}
|
|
9270
|
-
return "
|
|
9328
|
+
return "both";
|
|
9271
9329
|
}
|
|
9272
9330
|
var DEFAULT_ERC8183_PRICE = "100000000000000000";
|
|
9273
9331
|
async function resolveErc8183Price(flagValue, isTty) {
|
|
@@ -16760,6 +16818,12 @@ function azureX402CarrierBody() {
|
|
|
16760
16818
|
function sameFaces(a, b) {
|
|
16761
16819
|
return a.length === b.length && a.every((face, index) => face === b[index]);
|
|
16762
16820
|
}
|
|
16821
|
+
function sameX402Snapshot(a, b) {
|
|
16822
|
+
if (a === null || a === void 0 || b === null || b === void 0) {
|
|
16823
|
+
return a === b;
|
|
16824
|
+
}
|
|
16825
|
+
return a.status === b.status && a.priceMode === b.priceMode && a.credentialsComplete === b.credentialsComplete;
|
|
16826
|
+
}
|
|
16763
16827
|
function printAzureInfo(root, deployment, opts) {
|
|
16764
16828
|
const endpoint = deployment.endpoint;
|
|
16765
16829
|
if (!endpoint) {
|
|
@@ -16788,11 +16852,21 @@ function printAzureInfo(root, deployment, opts) {
|
|
|
16788
16852
|
const currentFaces = agentFacesOf(agentRoot2);
|
|
16789
16853
|
const faces = deployment.faces ?? currentFaces;
|
|
16790
16854
|
const facesSource = deployment.faces ? "deployment-record" : "current-scaffold";
|
|
16791
|
-
const
|
|
16855
|
+
const facesDrift = deployment.faces !== void 0 && !sameFaces(deployment.faces, currentFaces);
|
|
16792
16856
|
const hasX402 = hasX402Face(faces);
|
|
16793
16857
|
const hasA2a = hasA2aFace(faces);
|
|
16794
|
-
const
|
|
16795
|
-
const
|
|
16858
|
+
const currentX402 = hasX402Face(currentFaces) ? x402DeploymentSnapshot(agentRoot2, "self") : null;
|
|
16859
|
+
const x402State = deployment.x402 ?? currentX402;
|
|
16860
|
+
const x402StateSource = deployment.x402 ? "deployment-record" : "current-scaffold";
|
|
16861
|
+
const x402Drift = deployment.x402 !== void 0 && !sameX402Snapshot(deployment.x402, currentX402);
|
|
16862
|
+
const configurationDrift = facesDrift || x402Drift;
|
|
16863
|
+
const x402Summary = hasX402 ? deployment.x402 ? x402DeploySummaryFromSnapshot(
|
|
16864
|
+
deployment.x402,
|
|
16865
|
+
"azure-foundry",
|
|
16866
|
+
"self",
|
|
16867
|
+
null
|
|
16868
|
+
) : x402DeploySummary(agentRoot2, "self", null) : "";
|
|
16869
|
+
const x402Status = x402State?.status ?? (x402Summary.includes("ACTIVE in FREE mode") ? "free" : x402Summary.startsWith("x402 rail is ACTIVE") ? "active" : "dormant");
|
|
16796
16870
|
const x402Body = hasX402 ? azureX402CarrierBody() : void 0;
|
|
16797
16871
|
const body = hasA2a || x402Body === void 0 ? azureNegotiateQuickVerifyBody() : x402Body;
|
|
16798
16872
|
const x402Info = hasX402 ? {
|
|
@@ -16802,6 +16876,7 @@ function printAzureInfo(root, deployment, opts) {
|
|
|
16802
16876
|
carrier: "http-envelope-v1",
|
|
16803
16877
|
gateway_guide: foundryX402GatewayGuideUrl(),
|
|
16804
16878
|
summary: x402Summary || "x402 seller state is not available locally.",
|
|
16879
|
+
state_source: x402StateSource,
|
|
16805
16880
|
...x402Status === "dormant" ? {} : {
|
|
16806
16881
|
request: {
|
|
16807
16882
|
method: "POST",
|
|
@@ -16846,7 +16921,7 @@ function printAzureInfo(root, deployment, opts) {
|
|
|
16846
16921
|
printOut(` deployed faces: ${faces.join(", ")} (${facesSource})`);
|
|
16847
16922
|
if (configurationDrift) {
|
|
16848
16923
|
printErr(
|
|
16849
|
-
|
|
16924
|
+
"warning: current scaffold/payment configuration differs from the recorded deployment; redeploy before treating local config as live."
|
|
16850
16925
|
);
|
|
16851
16926
|
}
|
|
16852
16927
|
printOut(
|
|
@@ -686,8 +686,8 @@ function packageRoot() {
|
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
688
|
function studioCliVersion() {
|
|
689
|
-
if ("0.0.11-alpha.
|
|
690
|
-
return "0.0.11-alpha.
|
|
689
|
+
if ("0.0.11-alpha.5") {
|
|
690
|
+
return "0.0.11-alpha.5";
|
|
691
691
|
}
|
|
692
692
|
const file = path3.join(packageRoot(), "package.json");
|
|
693
693
|
const pkg = JSON.parse(fs3.readFileSync(file, "utf-8"));
|
|
@@ -831,14 +831,47 @@ function loadDeployConfig(root) {
|
|
|
831
831
|
return { agentRoot, cfg: {} };
|
|
832
832
|
}
|
|
833
833
|
}
|
|
834
|
-
function
|
|
834
|
+
function deploymentStatus(priceMode, credentialsComplete, runtime, destination) {
|
|
835
|
+
if (destination !== "platform" && !X402_CAPABLE_RUNTIMES.has(runtime)) {
|
|
836
|
+
return "dormant";
|
|
837
|
+
}
|
|
838
|
+
if (priceMode === "free") return "free";
|
|
839
|
+
if (priceMode === "paid" && credentialsComplete) return "active";
|
|
840
|
+
return "dormant";
|
|
841
|
+
}
|
|
842
|
+
function x402DeploymentSnapshot(root, destination) {
|
|
835
843
|
const { agentRoot, cfg } = loadDeployConfig(root);
|
|
836
|
-
if (!commerceRails(cfg).x402) return
|
|
844
|
+
if (!commerceRails(cfg).x402) return null;
|
|
837
845
|
const seller = table3(table3(cfg.payments).x402_seller);
|
|
838
846
|
const pricing = x402SellerPricingState(seller);
|
|
839
847
|
const credentials = b402Credentials(agentRoot);
|
|
840
|
-
const
|
|
848
|
+
const priceMode = pricing.kind;
|
|
841
849
|
const runtime = String(table3(cfg.stack).runtime ?? "agentcore");
|
|
850
|
+
return {
|
|
851
|
+
status: deploymentStatus(
|
|
852
|
+
priceMode,
|
|
853
|
+
credentials.complete,
|
|
854
|
+
runtime,
|
|
855
|
+
destination
|
|
856
|
+
),
|
|
857
|
+
priceMode,
|
|
858
|
+
credentialsComplete: credentials.complete
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
function x402DeploySummary(root, destination, publicUrl) {
|
|
862
|
+
const { cfg } = loadDeployConfig(root);
|
|
863
|
+
const snapshot = x402DeploymentSnapshot(root, destination);
|
|
864
|
+
if (snapshot === null) return "";
|
|
865
|
+
const runtime = String(table3(cfg.stack).runtime ?? "agentcore");
|
|
866
|
+
return x402DeploySummaryFromSnapshot(
|
|
867
|
+
snapshot,
|
|
868
|
+
runtime,
|
|
869
|
+
destination,
|
|
870
|
+
publicUrl
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
function x402DeploySummaryFromSnapshot(snapshot, runtime, destination, publicUrl) {
|
|
874
|
+
const activation = `${B402_PAID_ONBOARDING_GUIDANCE} Then run the bnbagent-studio-selling-via-b402 skill, fill the four B402_* variables in .studio/.env.local, and redeploy.`;
|
|
842
875
|
if (destination !== "platform" && !X402_CAPABLE_RUNTIMES.has(runtime)) {
|
|
843
876
|
return `x402 rail is FORCED DORMANT: the ${runtime} runtime has no x402 path. Deploy to AgentCore or Azure Foundry (managed platform or self-hosted) to activate the rail.`;
|
|
844
877
|
}
|
|
@@ -846,10 +879,10 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
846
879
|
const runtimeLabel = azure ? "Azure Foundry" : "AgentCore";
|
|
847
880
|
const tunnelLine = azure ? 'The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"/x402","headers":{...},"body":"<base64>"}, inside an Entra-authenticated Foundry invocation (POST \u2026/agents/<name>/endpoint/protocols/invocations with an https://ai.azure.com bearer). Limits: 1 MiB request, 5 MiB response, no streaming.' : 'The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"/x402","headers":{...},"body":"<base64>"}, inside an authenticated AgentCore invocation. The default Bag self-deploy uses Cognito OAuth over HTTPS; IAM runtimes may use SDK/SigV4. Limits: 1 MiB request, 5 MiB response, no streaming.';
|
|
848
881
|
const gatewayDocLine = azure ? `Gateway example: https://unpkg.com/@bnbagent/studio-cli@${studioCliVersion()}/skills/references/bnbagent-studio-use-azure-foundry.md#x402-external-gateway` : "Gateway example: https://github.com/bnb-chain/bnbagent-studio/blob/main/docs/guides/self-hosted-x402-gateway.md";
|
|
849
|
-
if (
|
|
882
|
+
if (snapshot.priceMode === "invalid") {
|
|
850
883
|
return "x402 rail is DORMANT: price_usd is invalid; run `bag doctor`.";
|
|
851
884
|
}
|
|
852
|
-
if (
|
|
885
|
+
if (snapshot.priceMode === "free") {
|
|
853
886
|
if (destination !== "platform") {
|
|
854
887
|
return [
|
|
855
888
|
`x402 rail is ACTIVE in FREE mode (self-hosted ${runtimeLabel}).`,
|
|
@@ -867,7 +900,7 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
867
900
|
"B402 verify/settle is bypassed; no credentials, token payment, or settlement audit is used."
|
|
868
901
|
].join("\n");
|
|
869
902
|
}
|
|
870
|
-
if (!
|
|
903
|
+
if (!snapshot.credentialsComplete) {
|
|
871
904
|
return `x402 rail is DORMANT. To activate: ${activation}`;
|
|
872
905
|
}
|
|
873
906
|
const settlement = [
|
|
@@ -904,7 +937,7 @@ function isTable(value) {
|
|
|
904
937
|
}
|
|
905
938
|
|
|
906
939
|
// src/cli/_deploy/deployCli.ts
|
|
907
|
-
var DEPLOY_CLI_VERSION = "0.5.
|
|
940
|
+
var DEPLOY_CLI_VERSION = "0.5.12";
|
|
908
941
|
var DEPLOY_CLI_PACKAGE = `@bnbagent/deploy-cli@${DEPLOY_CLI_VERSION}`;
|
|
909
942
|
var BNB_PLATFORM_API_URL = "https://bnbagent-api.bnbchain.world";
|
|
910
943
|
var BNB_PLATFORM_API_URL_ENV = "BNBAGENT_API_URL";
|
|
@@ -936,7 +969,8 @@ var FOUNDRY_PASSTHROUGH_KEYS = /* @__PURE__ */ new Set([
|
|
|
936
969
|
"project",
|
|
937
970
|
"projectEndpoint",
|
|
938
971
|
"protocol",
|
|
939
|
-
"registry"
|
|
972
|
+
"registry",
|
|
973
|
+
"subscriptionId"
|
|
940
974
|
]);
|
|
941
975
|
function tableOf(data, key) {
|
|
942
976
|
const v = data[key];
|
|
@@ -1054,7 +1088,8 @@ function buildDeploySpec(root, opts) {
|
|
|
1054
1088
|
["account_name", "account"],
|
|
1055
1089
|
["project_name", "project"],
|
|
1056
1090
|
["project_endpoint", "projectEndpoint"],
|
|
1057
|
-
["location", "location"]
|
|
1091
|
+
["location", "location"],
|
|
1092
|
+
["subscription_id", "subscriptionId"]
|
|
1058
1093
|
]) {
|
|
1059
1094
|
const value = String(azure[source] ?? "").trim();
|
|
1060
1095
|
if (value) {
|
|
@@ -1336,7 +1371,9 @@ export {
|
|
|
1336
1371
|
X402_CAPABLE_RUNTIMES,
|
|
1337
1372
|
commerceRails,
|
|
1338
1373
|
b402Credentials,
|
|
1374
|
+
x402DeploymentSnapshot,
|
|
1339
1375
|
x402DeploySummary,
|
|
1376
|
+
x402DeploySummaryFromSnapshot,
|
|
1340
1377
|
DEPLOY_CLI_VERSION,
|
|
1341
1378
|
DEPLOY_CLI_PACKAGE,
|
|
1342
1379
|
BNB_PLATFORM_API_URL,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bnbagent/studio-cli",
|
|
3
|
-
"version": "0.0.11-alpha.
|
|
3
|
+
"version": "0.0.11-alpha.5",
|
|
4
4
|
"description": "Skills-first toolkit and bag CLI for BNB Chain seller agents: ERC-8004 identity, ERC-8183 escrowed commerce, and x402 payments.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bnb-chain",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"tar": "^7.4.0",
|
|
55
55
|
"viem": "^2.54.0",
|
|
56
56
|
"yaml": "^2.9.0",
|
|
57
|
-
"@bnbagent/studio-runtime": "0.0.11-alpha.
|
|
57
|
+
"@bnbagent/studio-runtime": "0.0.11-alpha.5"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@a2a-js/sdk": "^0.3.14",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio
|
|
3
|
-
description: The single entry point for bnbagent-studio - a TypeScript CLI (`bag`) for building a blockchain SELLER agent that earns $U on BNB Chain via ERC-8004 + ERC-8183 + x402 (Pieverse LLM inside). Load this skill whenever the user works in a bnbagent-studio / `bag` project, or wants to create/scaffold, deploy, run, debug, operate, or monetize such a seller agent (composable A2A, MCP, and X402 faces; BNB Chain trial or
|
|
3
|
+
description: The single entry point for bnbagent-studio - a TypeScript CLI (`bag`) for building a blockchain SELLER agent that earns $U on BNB Chain via ERC-8004 + ERC-8183 + x402 (Pieverse LLM inside). Load this skill whenever the user works in a bnbagent-studio / `bag` project, or wants to create/scaffold, deploy, run, debug, operate, or monetize such a seller agent (composable A2A, MCP, and X402 faces; BNB Chain trial, AWS AgentCore, or Azure Foundry). All detailed playbooks ship as references/ files inside this skill - route via the decision tree in the body. When invoked with arguments, treat them as the user's intent and route the same way.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# bnbagent-studio (the single entry point)
|
|
7
7
|
|
|
8
|
-
`bnbagent-studio` (CLI: `bag`) wires the `@bnbagent/sdk` protocol layer (wallet / ERC-8004 / ERC-8183 / Pieverse LLM) into a TypeScript agent project, then deploys it as a **single blockchain seller runtime**. A2A, MCP, and X402 are composable public faces selected with `--protocols`; A2A is
|
|
8
|
+
`bnbagent-studio` (CLI: `bag`) wires the `@bnbagent/sdk` protocol layer (wallet / ERC-8004 / ERC-8183 / Pieverse LLM) into a TypeScript agent project, then deploys it as a **single blockchain seller runtime**. A2A, MCP, and X402 are composable public faces selected with `--protocols`; the default evm-local/twak scaffold serves A2A + X402 with both ERC-8183 and B402 rails, while Altana defaults to A2A + ERC-8183 because paid B402 is unsupported. `bag deploy` uses **scheme C**: every new deploy or redeploy explicitly selects BNB, AWS, or Azure; a recorded deployment is used only to offer an explicit update action, never as a silent default. BNB is a 48h testnet trial and is disabled after expiry. AWS and Azure self-deploy into the user's own account. All cloud lifecycle mutations go through the pinned `@bnbagent/deploy-cli`; the optional AWS CLI is used only by the fail-open, read-only AgentCore quota check in `bag deploy prepare`. AgentCore and Azure Foundry share the unified A2A/X402 entrypoint; Azure rejects MCP. Treat an incompatible provider row as unavailable-do not force through it or mutate the scaffold during deploy.
|
|
9
9
|
|
|
10
10
|
Invoked as `/bnbagent-studio <ask>`? Treat `<ask>` as the user's intent and route it through the decision tree below, exactly like a natural-language ask.
|
|
11
11
|
|
|
@@ -24,7 +24,7 @@ One deployed runtime, one signer: a single valuable Agent serves the selected fa
|
|
|
24
24
|
| Run / debug / dev / doctor / RPC / balance / incident triage | `references/bnbagent-studio-operating.md` |
|
|
25
25
|
| Implement what the Agent sells, tune pricing, publish over A2A and/or MCP, defend disputes (seller flow) | `references/bnbagent-studio-selling-via-8183.md` |
|
|
26
26
|
| Sell one paid or FREE HTTP request through the B402-backed x402 rail (pricing choice; paid merchant application, RSA key, credentials, IP allowlist, activation) | `references/bnbagent-studio-selling-via-b402.md` |
|
|
27
|
-
| Deploy / redeploy / status / logs / destroy | Run `bag deploy` and explicitly choose a provider. Non-interactive deploy requires `--provider bnb\|aws --yes` (and `--allow-multiple` when keeping another provider active). Read `references/bnbagent-studio-use-bnb-trial.md` or `references/bnbagent-studio-use-
|
|
27
|
+
| Deploy / redeploy / status / logs / destroy | Run `bag deploy` and explicitly choose a provider. Non-interactive deploy requires `--provider bnb\|aws\|azure --yes` (and `--allow-multiple` when keeping another provider active). Read `references/bnbagent-studio-use-bnb-trial.md`, `references/bnbagent-studio-use-aws-agentcore.md`, or `references/bnbagent-studio-use-azure-foundry.md` for the selected provider. `bag deploy status` lists every recorded provider; multi-deployment logs/verify/destroy require `--provider`. |
|
|
28
28
|
| Wire chain-read tools into the Agent's LLM (AI SDK `tool()` wrappers, or any TS agent framework) | `references/bnbagent-studio-wiring-llm-tools.md` |
|
|
29
29
|
| Buy a service from another ERC-8183 seller via CLI - incl. testing your own seller from the buyer side (v2/internal - NOT the v1 seller product flow) | `references/bnbagent-studio-buying-via-8183.md` |
|
|
30
30
|
| Give the agent a PAID x402 capability - CMC market data / Binance Bazaar (B402) merchants / any pay-per-call API (`bag x402 trust`, x402-buyer recipe, 402 buyer errors) | `references/bnbagent-studio-buying-from-bazaar.md` |
|
|
@@ -53,7 +53,7 @@ Treat ERC-8183 amounts as decimal strings at CLI/config boundaries and `bigint`
|
|
|
53
53
|
|
|
54
54
|
## CLI groups at a glance
|
|
55
55
|
|
|
56
|
-
`init`, `scan`, `recipe`, `skills`, `wallet`, `erc8004`, `erc8183`, `x402`, `agents`, `config`, `env`, `dev`, `doctor`, `audit`, `deploy`, `platform`, `llm`, `bundle`, `budget` - see `bag --help` for details. `bag deploy [--provider bnb\|aws] [--backend aws\|azure]` is the primary deploy command; `--backend` is valid only for provider `bnb` and confirms the recipe-derived managed backend. `prepare`, `verify`, `status`, `info`, `destroy`, `logs`, and `fix-gitignore` remain lifecycle subcommands (`deploy agent` is a deprecated compatibility alias). Provider deploy/status/logs/destroy and deploy-time credential validation are delegated to pinned `@bnbagent/deploy-cli@0.5.
|
|
56
|
+
`init`, `scan`, `recipe`, `skills`, `wallet`, `erc8004`, `erc8183`, `x402`, `agents`, `config`, `env`, `dev`, `doctor`, `audit`, `deploy`, `platform`, `llm`, `bundle`, `budget` - see `bag --help` for details. `bag deploy [--provider bnb\|aws\|azure] [--backend aws\|azure]` is the primary deploy command; `--backend` is valid only for provider `bnb` and confirms the recipe-derived managed backend. `prepare`, `verify`, `status`, `info`, `destroy`, `logs`, and `fix-gitignore` remain lifecycle subcommands (`deploy agent` is a deprecated compatibility alias). Provider deploy/status/logs/destroy and deploy-time credential validation are delegated to pinned `@bnbagent/deploy-cli@0.5.12`.
|
|
57
57
|
|
|
58
58
|
## Tool surface
|
|
59
59
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio-adding-to-project
|
|
3
|
-
description: When the user wants to add bnbagent-studio's single
|
|
3
|
+
description: When the user wants to add bnbagent-studio's single seller runtime (one valuable Agent on AWS Bedrock AgentCore that serves A2A + X402 with ERC-8183 + B402 by default, or another selected face/rail combination, holds the key, and signs in-process) to an existing TypeScript agent project.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Reference file** of the `bnbagent-studio` router skill - installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio-scaffolding-agent
|
|
3
|
-
description: When the user wants to create a brand-new blockchain SELLER from zero - a single valuable Agent on AWS Bedrock AgentCore that serves A2A by default or
|
|
3
|
+
description: When the user wants to create a brand-new blockchain SELLER from zero - a single valuable Agent on AWS Bedrock AgentCore that serves A2A + X402 with ERC-8183 + B402 by default (or another selected face/rail combination), holds the key, and signs in-process. Drives the full intake → todo-list → execute flow.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Reference file** of the `bnbagent-studio` router skill - installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
@@ -71,7 +71,7 @@ The fields (give the user all of them at once):
|
|
|
71
71
|
| 3 | **LLM provider** | `pieverse-llm` / `openrouter` / `openai` / `anthropic` / `bedrock` | `pieverse-llm` |
|
|
72
72
|
| 4 | **Wallet kind** (`--wallet-kind`) | `evm-local` (encrypted local keystore at the workspace root; `bag wallet new` creates it, `--private-key` imports an existing key; CodeZip deploy) / `twak` (**fully supported, opt in with `--wallet-kind twak`** - Trust Wallet Agent Kit CLI ≥0.20.0, self-custody encrypted mnemonic in a **project-dedicated** home `.studio/twak`, isolated from your main `~/.twak`; created manually with `HOME=<ws>/.studio/twak twak wallet create`, then `bag wallet new` adopts; container deploy. Reuse an existing wallet across agents with `--twak-home <path>`) / `altana` (bounded-session custody - admin keystore stays local, deploys ship ONLY the `ALTANA_SESSION` secret; zip deploy; not compatible with `pieverse-llm` or a paid b402 rail; flow: `references/bnbagent-studio-using-altana-wallet.md`) | `evm-local` |
|
|
73
73
|
| 5 | **Storage** | `local` (file:// on disk, offline dev only, does **NOT** survive deploy) / `ipfs` (durable, public, deploy-ready; needs your pinning service's upload endpoint + write key as `STORAGE_API_URL` / `STORAGE_API_KEY` in `.studio/.env.local` **before the first real delivery** - see Step 6b) | `local` |
|
|
74
|
-
| 6 | **Protocol faces** (`--protocols`) | any non-empty subset of `A2A`, `MCP`, `X402` | `A2A` |
|
|
74
|
+
| 6 | **Protocol faces** (`--protocols`) | any non-empty subset of `A2A`, `MCP`, `X402` | `A2A,X402` (`A2A` for Altana) |
|
|
75
75
|
| 7 | **LLM model** | provider catalogue; for `pieverse-llm` the default `auto/free` runs at $0/token | `auto/free` |
|
|
76
76
|
| 8 | **Auto-topup** | `enable` / `disable` - lets the Agent auto-pay $U from the wallet when LLM credits run low | deferred (non-interactive `bag init` records no `[budget]`; enable later with `bag budget enable`) |
|
|
77
77
|
| 9 | **Scaffold destination** (`--destination`) | `self` (prepare the AgentCore scaffold for **your own** AWS account; runtime material stays under your cloud-account control) / `platform` (prepare for a 48h **testnet-only** trial on the BNB Chain managed platform - runs the _same_ agent in the **operator's** AWS, so a wallet key **leaves your control**; it hard-forces `[network].default = bsc-testnet`, pins runtime=`agentcore`, packages an artifact, and auth is GitHub device flow. Use a **throwaway** `bag wallet new`, never your main wallet). This is scaffold intent only; deploy still explicitly selects `--provider`. | `platform` while the trial campaign runs (bare init falls back to `self` once it ends, or when `--network bsc-mainnet` / a non-agentcore `--runtime` is passed) |
|
|
@@ -86,7 +86,7 @@ v1 is **seller-only** - there is no role to choose. `bag init` scaffolds the sin
|
|
|
86
86
|
| --- | --- | --- |
|
|
87
87
|
| **Agent stack** | AI SDK (`ai`) | The library the agent's brain is built with - the emitted `src/model.ts` factory returns an AI SDK `LanguageModel`, and `src/tools.ts` wraps the chain reads as AI SDK `tool()`s. (There is no `--framework` flag: the old framework axis folded into the runtime templates.) |
|
|
88
88
|
| **Runtime** | `agentcore` | AWS Bedrock AgentCore - where the agent is hosted and served (`--runtime agentcore`). |
|
|
89
|
-
| **Protocol faces** | selected above (`A2A` default; MCP
|
|
89
|
+
| **Protocol faces** | selected above (`A2A,X402` default for evm-local/twak; `A2A` for Altana; MCP composable) | A2A hosts agent card + JSON-RPC on `:9000`; MCP-only hosts `/mcp` on `:8000`; A2A+MCP uses A2A-native `dualMain.ts` on `:9000` and tunnels buffered MCP through the platform; X402 adds `/x402`, and X402-only suppresses protocol discovery. |
|
|
90
90
|
|
|
91
91
|
**Not surfaced** (handled automatically, no need to show or ask):
|
|
92
92
|
|
|
@@ -138,7 +138,7 @@ Build a TodoWrite list. The shape depends on the `wallet kind`. The canonical 8-
|
|
|
138
138
|
|
|
139
139
|
> **Onboarding note.** On a human TTY, `bag init` runs steps 3, 4 and 6 automatically (it prompts once for the wallet password, runs `bag wallet new`, zero-deposit-activates Pieverse, and prints faucet URLs). **You (Claude Code) drive `bag init` non-interactively**, so that auto-flow does NOT fire - keep steps 3/4/6 below. Pass `--no-onboard` to `bag init` to make this explicit and deterministic regardless of how the shell wires stdin.
|
|
140
140
|
|
|
141
|
-
1. `bag init <name> --llm-provider <p> --network <n> --storage-provider <s> --wallet-kind <k> --rails <8183|b402|both> [--erc8183-price <base-units>] [--b402-price <usd>] --no-onboard` - scaffold the current workspace. **`<name>` must start with a letter, use ASCII letters and digits only, and be at most 23 characters.** `bag init` rejects `-`, `_`, `.`, and overlong names instead of renaming them. Pass `--wallet-kind evm-local` (default) or `--wallet-kind twak` (twak is fully supported - pass the flag to opt in), and `--storage-provider local` (default) or `ipfs`, per the Stage-1 choices; for twak, add `--twak-home <path>` ONLY if the user wants to reuse an existing wallet (otherwise omit - a project-dedicated `.studio/twak` is the safe default).
|
|
141
|
+
1. `bag init <name> --llm-provider <p> --network <n> --storage-provider <s> --wallet-kind <k> [--protocols <comma-list>] [--rails <8183|b402|both>] [--erc8183-price <base-units>] [--b402-price <usd>] --no-onboard` - scaffold the current workspace. **`<name>` must start with a letter, use ASCII letters and digits only, and be at most 23 characters.** `bag init` rejects `-`, `_`, `.`, and overlong names instead of renaming them. Pass `--wallet-kind evm-local` (default) or `--wallet-kind twak` (twak is fully supported - pass the flag to opt in), and `--storage-provider local` (default) or `ipfs`, per the Stage-1 choices; for twak, add `--twak-home <path>` ONLY if the user wants to reuse an existing wallet (otherwise omit - a project-dedicated `.studio/twak` is the safe default). Omit `--protocols` and `--rails` for the default A2A + X402 faces with both ERC-8183 and B402 rails; Altana instead defaults to A2A + ERC-8183 because paid B402 is unsupported. Pass either flag when the user chose another face/rail combination (`--protocol <one>` is only a legacy alias), add `--model <m>` only if the user overrode the provider default, and `--enable-auto-topup` / `--no-auto-topup` only if they made an explicit choice (otherwise omit - consent stays deferred). Pass `--erc8183-price 0` only when the user explicitly chose FREE; omitting the flag preserves the paid 0.1 U default. The canonical stack supports FREE; if a custom deployment is selected, set all three `ERC8183_COMMERCE_ADDRESS`, `ERC8183_ROUTER_ADDRESS`, and `ERC8183_POLICY_ADDRESS` values from that same stack. For B402, pass `--b402-price 0` only after the user explicitly accepts an unrestricted anonymous FREE `/x402` endpoint. FREE bypasses B402 verify/settle and needs no merchant credentials; a positive price keeps the `$0.01` default and requires the paid onboarding playbook. **Destination:** while the trial campaign runs, bare `bag init` (no `--destination`) defaults to `platform` - so pass `--destination self` **explicitly** whenever the user chose their own AWS, otherwise studio.toml silently records `platform` and the confirmation block you echoed no longer matches what was written. Omit `--destination` only when the user actually wants the `platform` 48h testnet trial (the campaign default) - do NOT treat that default as a mistake or re-confirm it; it is the intended behavior while the campaign is open. (Bare init also resolves to `self` once the campaign ends, or when `--network bsc-mainnet` / a non-agentcore `--runtime` is passed.) On the `platform` path `bag init` hard-forces `bsc-testnet`, pins `--runtime agentcore` + packages an artifact (a zip for the default evm-local and altana wallets, a container for twak). For evm-local a wallet key will later leave your machine, so pair it with a throwaway `bag wallet new`; for altana only the bounded session ships - do NOT create a new wallet (full flow: `docs/guides/platform-deploy.md`). Defaults `--runtime agentcore` (the only advertised runtime; the Preview `azure-foundry` runtime remains explicitly selectable but is outside this playbook; there is no `--framework` flag because the AI SDK model/tools story is part of the runtime templates). Creates `<name>/` workspace root + `<name>/app/agent/` (the single sub-project: A2A emits `src/unifiedMain.ts` (the express + A2A entrypoint, one code set for both deploy clouds) + `src/sellerCore.ts` (the protocol-neutral core; executor inherits it) + `src/executor.ts` + `src/agentCard.ts`; MCP emits `src/mcpMain.ts`; both include `src/signing.ts` + `src/tools.ts` + `src/model.ts` + their own `studio.toml` + `package.json` + `tsconfig.json`) + `<name>/agentcore/` (`agentcore.json` + `aws-targets.json`, self-rendered - no agentcore CLI needed at init). The workspace root holds the `agentcore/` deploy descriptor, the `.studio/wallets/` keystore, a thin `package.json` + `pnpm-workspace.yaml`, README, and `.gitignore`. (v1 is seller-only - no `--role`.)
|
|
142
142
|
> **Altana + custom contracts:** Altana sessions remain bound to the canonical ERC-8183 targets. Use `evm-local` for a custom Commerce/Router/Policy stack; doctor and deploy readiness reject this unsupported combination when the ERC-8183 rail is active.
|
|
143
143
|
|
|
144
144
|
2. `cd <name>`, then make sure the dependencies are installed. `bag init` already runs the install by default (skip only if it was scaffolded with `--no-install`); the manual equivalent from the workspace root is:
|
|
@@ -7,7 +7,7 @@ description: When the user is acting as an ERC-8183 seller on the single selecte
|
|
|
7
7
|
|
|
8
8
|
# bnbagent-studio-selling-via-8183
|
|
9
9
|
|
|
10
|
-
Procedure for the **single seller flow**: implement the value your Agent produces, deploy it to AgentCore (where
|
|
10
|
+
Procedure for the **single seller flow**: implement the value your Agent produces, deploy it to AgentCore (where the default scaffold serves A2A + X402, while ERC-8183 remains available through A2A or an explicitly selected MCP face), and handle the job lifecycle (Agent quotes → buyer funds → buyer calls `notify_funded` → Agent delivers → buyer reads the result from the chain → buyer settles or disputes).
|
|
11
11
|
|
|
12
12
|
Audience: Claude Code in a working repo with a funded wallet (tBNB + U) and an Agent that produces some valuable output (text, classification, image - whatever).
|
|
13
13
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio-use-aws-agentcore
|
|
3
|
-
description: When the user wants to deploy or operate a bnbagent-studio project on AWS Bedrock AgentCore - deploy with `bag deploy --provider aws` (all cloud lifecycle mutations are delegated to pinned `@bnbagent/deploy-cli@0.5.
|
|
3
|
+
description: When the user wants to deploy or operate a bnbagent-studio project on AWS Bedrock AgentCore - deploy with `bag deploy --provider aws` (all cloud lifecycle mutations are delegated to pinned `@bnbagent/deploy-cli@0.5.12`), inspect with `bag deploy status` / `logs --provider aws` / `verify --provider aws`, and tear down with `bag deploy destroy --provider aws --execute [--purge]`. Also covers AWS credential prerequisites, the optional read-only quota probe, and the runtime-secret channel.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Reference file** of the `bnbagent-studio` router skill - installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio-use-azure-foundry
|
|
3
|
-
description: When the user wants to deploy or operate a bnbagent-studio project on Azure AI Foundry Hosted Agents - scaffold with `bag init --runtime azure-foundry`, deploy either to the managed platform with `bag deploy --provider bnb --backend azure` or directly with `bag deploy --provider azure`; all cloud lifecycle execution is delegated to pinned `@bnbagent/deploy-cli@0.5.
|
|
3
|
+
description: When the user wants to deploy or operate a bnbagent-studio project on Azure AI Foundry Hosted Agents - scaffold with `bag init --runtime azure-foundry`, deploy either to the managed platform with `bag deploy --provider bnb --backend azure` or directly with `bag deploy --provider azure`; all cloud lifecycle execution is delegated to pinned `@bnbagent/deploy-cli@0.5.12`. Native MCP is not supported on Azure; use AgentCore for MCP.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Reference file** of the `bnbagent-studio` router skill - installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
@@ -16,7 +16,7 @@ Procedure for deploying and operating the seller Agent on **Azure AI Foundry Hos
|
|
|
16
16
|
```
|
|
17
17
|
<workspace>/
|
|
18
18
|
├── app/agent/ # the deployed code (src/unifiedMain.ts host + Dockerfile here)
|
|
19
|
-
│ ├── studio.toml # [azure] block: location / account_name / subdomain / project_name / agent_endpoint
|
|
19
|
+
│ ├── studio.toml # [azure] block: location / subscription_id / account_name / subdomain / project_name / agent_endpoint
|
|
20
20
|
│ └── Dockerfile # the container image bnbagent-deploy builds + pushes
|
|
21
21
|
└── .studio/ # secrets + wallets (workspace root - never in the image)
|
|
22
22
|
```
|
|
@@ -31,7 +31,7 @@ Procedure for deploying and operating the seller Agent on **Azure AI Foundry Hos
|
|
|
31
31
|
|
|
32
32
|
1. **Bun 1.3+ (`bunx`) on PATH** - the pinned `@bnbagent/deploy-cli` runs through it.
|
|
33
33
|
2. **Docker running** - the image is built locally (linux/amd64) before push.
|
|
34
|
-
3. **An Azure subscription** the operator may provision in (Foundry account/project, container registry, hosted agent). Before a local self-deploy, run `bunx --bun @bnbagent/deploy-cli@0.5.
|
|
34
|
+
3. **An Azure subscription** the operator may provision in (Foundry account/project, container registry, hosted agent). Before a local self-deploy, run `bunx --bun @bnbagent/deploy-cli@0.5.12 login --provider azure`; use OIDC/service-principal credentials in CI.
|
|
35
35
|
|
|
36
36
|
## ⚠️ Foundry gotchas (read before deploying)
|
|
37
37
|
|
|
@@ -49,7 +49,7 @@ Procedure for deploying and operating the seller Agent on **Azure AI Foundry Hos
|
|
|
49
49
|
|
|
50
50
|
> The encrypted keystore (`.studio/wallets/`) stays at the workspace root and rides only that secret channel - never baked into the image.
|
|
51
51
|
|
|
52
|
-
Provider-native overrides go in the optional `studio.toml [deploy.foundry]` table (verbatim deploy-spec keys; deploy-cli 0.5.
|
|
52
|
+
Provider-native overrides go in the optional `studio.toml [deploy.foundry]` table (verbatim deploy-spec keys; deploy-cli 0.5.12 consumes `account`, `cpu`, `location`, `memory`, `project`, `projectEndpoint`, `protocol`, `registry`, `subscriptionId` and warns about anything else). The `[azure]` block's `subscription_id` / `account_name` / `project_name` / `project_endpoint` / `location` win over conflicting `[deploy.foundry]` keys.
|
|
53
53
|
|
|
54
54
|
## Typical workflow
|
|
55
55
|
|
|
@@ -76,8 +76,9 @@ bag deploy --provider azure # delegated: onboard → build+push
|
|
|
76
76
|
|
|
77
77
|
For a first deploy in non-interactive automation, pass `--yes`. Studio treats
|
|
78
78
|
that as confirmation of the full deployment plan and delegates explicit
|
|
79
|
-
Foundry project onboarding. Configure `[azure]`
|
|
80
|
-
when several candidates are accessible so no prompt or guess is
|
|
79
|
+
Foundry project onboarding. Configure `[azure].subscription_id` and
|
|
80
|
+
`account_name` when several candidates are accessible so no prompt or guess is
|
|
81
|
+
required.
|
|
81
82
|
|
|
82
83
|
### C. Validate / operate
|
|
83
84
|
|
|
@@ -138,6 +139,6 @@ Azure Foundry is an alternate runtime for the whole seller agent. There is no se
|
|
|
138
139
|
## Reference
|
|
139
140
|
|
|
140
141
|
- `bag deploy --help` / `bag deploy <command> --help` (authoritative for commands + flags)
|
|
141
|
-
- `app/agent/studio.toml [azure]` - location / account_name / subdomain / project_name / agent_endpoint
|
|
142
|
+
- `app/agent/studio.toml [azure]` - location / subscription_id / account_name / subdomain / project_name / agent_endpoint
|
|
142
143
|
- `app/agent/studio.toml [deploy.foundry]` - provider-native deploy-spec passthrough
|
|
143
144
|
- `BNBAGENT_DEPLOY_COMMAND` - override the pinned `bunx --bun @bnbagent/deploy-cli@<pin>` invocation (E2E/dev)
|
|
@@ -9,7 +9,7 @@ description: Use when deploying or operating a bnbagent-studio seller on the BNB
|
|
|
9
9
|
|
|
10
10
|
Treat this provider as a temporary testnet sandbox. Require a throwaway wallet, keep `bsc-testnet`, and explain that the runtime signing material is transmitted to the operator's managed secret store for the trial. Never use a mainnet key. Exception: `wallet.kind='altana'` ships only the bounded, budget-limited, revocable session - the throwaway-wallet advice does not apply; tighten the session instead (`bag wallet session grant --force --budget-u <small> --expiry-days <short>`) and never run `bag wallet new` on an altana project (it breaks the session's `[wallet].address` anchor).
|
|
11
11
|
|
|
12
|
-
All auth and cloud lifecycle work must cross the pinned `@bnbagent/deploy-cli@0.5.
|
|
12
|
+
All auth and cloud lifecycle work must cross the pinned `@bnbagent/deploy-cli@0.5.12` boundary. Do not call a cloud CLI or platform REST routes directly. The managed backend is recipe-derived: `agentcore` uses AWS; `azure-foundry` uses Azure. For headless managed Azure, confirm with `bag deploy --provider bnb --backend azure --yes`; never treat `--backend` as a cross-cloud recipe converter.
|
|
13
13
|
|
|
14
14
|
## Select and authenticate
|
|
15
15
|
|