@m8t-stack/cli 0.2.11 → 0.2.12
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/cli.js +111 -57
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1195,7 +1195,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1195
1195
|
import { Builtins, Cli } from "clipanion";
|
|
1196
1196
|
|
|
1197
1197
|
// src/lib/package-version.ts
|
|
1198
|
-
var CLI_VERSION = "0.2.
|
|
1198
|
+
var CLI_VERSION = "0.2.12";
|
|
1199
1199
|
|
|
1200
1200
|
// src/lib/render-error.ts
|
|
1201
1201
|
init_errors();
|
|
@@ -15196,6 +15196,109 @@ init_errors();
|
|
|
15196
15196
|
init_foundry_agent_get();
|
|
15197
15197
|
import { randomBytes as randomBytes2, createHash } from "crypto";
|
|
15198
15198
|
|
|
15199
|
+
// src/lib/data-plane-ready.ts
|
|
15200
|
+
init_errors();
|
|
15201
|
+
async function awaitDataPlaneReady(opts) {
|
|
15202
|
+
const consecutive = opts.consecutive ?? 3;
|
|
15203
|
+
const attempts = opts.attempts ?? 60;
|
|
15204
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
15205
|
+
const sleep2 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
15206
|
+
let streak = 0;
|
|
15207
|
+
for (let i = 1; i <= attempts; i++) {
|
|
15208
|
+
const r = await opts.probe();
|
|
15209
|
+
if (r.ok) {
|
|
15210
|
+
streak++;
|
|
15211
|
+
opts.onProgress?.(`data-plane ok (${streak.toString()}/${consecutive.toString()})`);
|
|
15212
|
+
if (streak >= consecutive) return { ready: true, attempts: i };
|
|
15213
|
+
} else {
|
|
15214
|
+
const cls = classifyFoundryError({ status: r.status, message: r.message ?? "" });
|
|
15215
|
+
const forcedRetryable = r.status !== void 0 && (opts.retryableStatuses?.includes(r.status) ?? false);
|
|
15216
|
+
if (!forcedRetryable && !cls.retryable) {
|
|
15217
|
+
throw new LocalCliError({
|
|
15218
|
+
code: "FOUNDRY_NOT_READY_FATAL",
|
|
15219
|
+
message: `Foundry data plane returned a non-retryable error: ${cls.message}`,
|
|
15220
|
+
hint: "This is not a transient data-plane delay \u2014 check `az login`/permissions and the endpoint.",
|
|
15221
|
+
retryable: false
|
|
15222
|
+
});
|
|
15223
|
+
}
|
|
15224
|
+
streak = 0;
|
|
15225
|
+
opts.onProgress?.(`data-plane not ready (${forcedRetryable ? `status ${(r.status ?? 0).toString()}` : cls.category}), waiting\u2026`);
|
|
15226
|
+
}
|
|
15227
|
+
if (i < attempts) await sleep2(intervalMs);
|
|
15228
|
+
}
|
|
15229
|
+
return { ready: false, attempts };
|
|
15230
|
+
}
|
|
15231
|
+
|
|
15232
|
+
// src/lib/foundry-ready-probe.ts
|
|
15233
|
+
init_http();
|
|
15234
|
+
var FOUNDRY_SCOPE3 = "https://ai.azure.com/.default";
|
|
15235
|
+
function makeAgentsProbe(credential2, endpoint) {
|
|
15236
|
+
return async () => {
|
|
15237
|
+
try {
|
|
15238
|
+
const r = await authedJsonResult({
|
|
15239
|
+
credential: credential2,
|
|
15240
|
+
scope: FOUNDRY_SCOPE3,
|
|
15241
|
+
method: "GET",
|
|
15242
|
+
url: `${endpoint}/agents?api-version=v1`,
|
|
15243
|
+
okStatuses: [404, 500, 502, 503]
|
|
15244
|
+
// don't throw — return the status so the loop classifies it
|
|
15245
|
+
});
|
|
15246
|
+
if (r.status === 200) return { ok: true, status: 200, message: "" };
|
|
15247
|
+
const body = r.data?.error?.message ?? "";
|
|
15248
|
+
return { ok: false, status: r.status, message: `${r.status.toString()} ${body}`.trim() };
|
|
15249
|
+
} catch (e) {
|
|
15250
|
+
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
15251
|
+
}
|
|
15252
|
+
};
|
|
15253
|
+
}
|
|
15254
|
+
function makeAgentProbe(credential2, endpoint, agentName) {
|
|
15255
|
+
return async () => {
|
|
15256
|
+
try {
|
|
15257
|
+
const r = await authedJsonResult({
|
|
15258
|
+
credential: credential2,
|
|
15259
|
+
scope: FOUNDRY_SCOPE3,
|
|
15260
|
+
method: "GET",
|
|
15261
|
+
url: `${endpoint}/agents/${agentName}?api-version=v1`,
|
|
15262
|
+
okStatuses: [404, 500, 502, 503]
|
|
15263
|
+
// don't throw — return the status so the loop classifies it
|
|
15264
|
+
});
|
|
15265
|
+
if (r.status === 200) return { ok: true, status: 200, message: "" };
|
|
15266
|
+
const body = r.data?.error?.message ?? "";
|
|
15267
|
+
return { ok: false, status: r.status, message: `${r.status.toString()} ${body}`.trim() };
|
|
15268
|
+
} catch (e) {
|
|
15269
|
+
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
15270
|
+
}
|
|
15271
|
+
};
|
|
15272
|
+
}
|
|
15273
|
+
|
|
15274
|
+
// src/lib/agent-ready.ts
|
|
15275
|
+
init_errors();
|
|
15276
|
+
async function awaitAgentQueryable(args) {
|
|
15277
|
+
const attemptsMax = args.attempts ?? 40;
|
|
15278
|
+
const intervalMs = args.intervalMs ?? 3e3;
|
|
15279
|
+
const probe = args.probe ?? makeAgentProbe(args.credential, args.projectEndpoint, args.agentName);
|
|
15280
|
+
const { ready, attempts } = await awaitDataPlaneReady({
|
|
15281
|
+
probe,
|
|
15282
|
+
consecutive: args.consecutive ?? 2,
|
|
15283
|
+
attempts: attemptsMax,
|
|
15284
|
+
intervalMs,
|
|
15285
|
+
sleep: args.sleep,
|
|
15286
|
+
onProgress: args.onProgress,
|
|
15287
|
+
retryableStatuses: [404]
|
|
15288
|
+
});
|
|
15289
|
+
if (!ready) {
|
|
15290
|
+
const approxSec = Math.round(attemptsMax * intervalMs / 1e3);
|
|
15291
|
+
throw new LocalCliError({
|
|
15292
|
+
code: "AGENT_NOT_QUERYABLE",
|
|
15293
|
+
message: `Agent '${args.agentName}' did not become queryable within ${attempts.toString()} probes (~${approxSec.toString()}s) after deploy.`,
|
|
15294
|
+
hint: "Foundry agent registration propagates asynchronously after deploy; a retry usually clears it. Re-run shortly (e.g. 'm8t bootstrap launch' or 'm8t a2a enable <name>').",
|
|
15295
|
+
category: "data_plane_not_ready",
|
|
15296
|
+
retryable: false
|
|
15297
|
+
});
|
|
15298
|
+
}
|
|
15299
|
+
return { attempts };
|
|
15300
|
+
}
|
|
15301
|
+
|
|
15199
15302
|
// src/lib/persona-a2a.ts
|
|
15200
15303
|
init_errors();
|
|
15201
15304
|
init_esm();
|
|
@@ -15251,6 +15354,13 @@ async function enableA2a(args) {
|
|
|
15251
15354
|
const connectionName = `a2a-${args.agentName}`;
|
|
15252
15355
|
progress("Reading persona a2a-card\u2026");
|
|
15253
15356
|
const { serialized: a2aCardJson } = readPersonaA2aCard(args.personaPath);
|
|
15357
|
+
progress("Waiting for the agent to become queryable\u2026");
|
|
15358
|
+
await awaitAgentQueryable({
|
|
15359
|
+
credential: args.credential,
|
|
15360
|
+
projectEndpoint: args.projectEndpoint,
|
|
15361
|
+
agentName: args.agentName,
|
|
15362
|
+
onProgress: args.onProgress
|
|
15363
|
+
});
|
|
15254
15364
|
progress("Reading current agent definition\u2026");
|
|
15255
15365
|
const current = await getAgentVersion({ credential: args.credential, projectEndpoint: args.projectEndpoint, agentName: args.agentName });
|
|
15256
15366
|
if (current.definition.kind === "hosted") {
|
|
@@ -22147,62 +22257,6 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
22147
22257
|
// src/commands/foundry/await-ready.ts
|
|
22148
22258
|
import { Command as Command44, Option as Option42 } from "clipanion";
|
|
22149
22259
|
import { AzureCliCredential as AzureCliCredential2 } from "@azure/identity";
|
|
22150
|
-
|
|
22151
|
-
// src/lib/data-plane-ready.ts
|
|
22152
|
-
init_errors();
|
|
22153
|
-
async function awaitDataPlaneReady(opts) {
|
|
22154
|
-
const consecutive = opts.consecutive ?? 3;
|
|
22155
|
-
const attempts = opts.attempts ?? 60;
|
|
22156
|
-
const intervalMs = opts.intervalMs ?? 5e3;
|
|
22157
|
-
const sleep2 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
22158
|
-
let streak = 0;
|
|
22159
|
-
for (let i = 1; i <= attempts; i++) {
|
|
22160
|
-
const r = await opts.probe();
|
|
22161
|
-
if (r.ok) {
|
|
22162
|
-
streak++;
|
|
22163
|
-
opts.onProgress?.(`data-plane ok (${streak.toString()}/${consecutive.toString()})`);
|
|
22164
|
-
if (streak >= consecutive) return { ready: true, attempts: i };
|
|
22165
|
-
} else {
|
|
22166
|
-
const cls = classifyFoundryError({ status: r.status, message: r.message ?? "" });
|
|
22167
|
-
if (!cls.retryable) {
|
|
22168
|
-
throw new LocalCliError({
|
|
22169
|
-
code: "FOUNDRY_NOT_READY_FATAL",
|
|
22170
|
-
message: `Foundry data plane returned a non-retryable error: ${cls.message}`,
|
|
22171
|
-
hint: "This is not a transient data-plane delay \u2014 check `az login`/permissions and the endpoint."
|
|
22172
|
-
});
|
|
22173
|
-
}
|
|
22174
|
-
streak = 0;
|
|
22175
|
-
opts.onProgress?.(`data-plane not ready (${cls.category}), waiting\u2026`);
|
|
22176
|
-
}
|
|
22177
|
-
if (i < attempts) await sleep2(intervalMs);
|
|
22178
|
-
}
|
|
22179
|
-
return { ready: false, attempts };
|
|
22180
|
-
}
|
|
22181
|
-
|
|
22182
|
-
// src/lib/foundry-ready-probe.ts
|
|
22183
|
-
init_http();
|
|
22184
|
-
var FOUNDRY_SCOPE3 = "https://ai.azure.com/.default";
|
|
22185
|
-
function makeAgentsProbe(credential2, endpoint) {
|
|
22186
|
-
return async () => {
|
|
22187
|
-
try {
|
|
22188
|
-
const r = await authedJsonResult({
|
|
22189
|
-
credential: credential2,
|
|
22190
|
-
scope: FOUNDRY_SCOPE3,
|
|
22191
|
-
method: "GET",
|
|
22192
|
-
url: `${endpoint}/agents?api-version=v1`,
|
|
22193
|
-
okStatuses: [404, 500, 502, 503]
|
|
22194
|
-
// don't throw — return the status so the loop classifies it
|
|
22195
|
-
});
|
|
22196
|
-
if (r.status === 200) return { ok: true, status: 200, message: "" };
|
|
22197
|
-
const body = r.data?.error?.message ?? "";
|
|
22198
|
-
return { ok: false, status: r.status, message: `${r.status.toString()} ${body}`.trim() };
|
|
22199
|
-
} catch (e) {
|
|
22200
|
-
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
22201
|
-
}
|
|
22202
|
-
};
|
|
22203
|
-
}
|
|
22204
|
-
|
|
22205
|
-
// src/commands/foundry/await-ready.ts
|
|
22206
22260
|
init_errors();
|
|
22207
22261
|
var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
22208
22262
|
static paths = [["foundry", "await-ready"]];
|