@mnemom/mnemom 0.17.9-next.0 → 0.17.10
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/commands/agent-setup.d.ts +68 -49
- package/dist/commands/agent-setup.js +242 -160
- package/dist/commands/agent.d.ts +9 -12
- package/dist/commands/agent.js +26 -56
- package/dist/commands/card.js +2 -2
- package/dist/commands/onboard.js +4 -3
- package/dist/commands/protection.js +1 -1
- package/dist/commands/try-me.d.ts +13 -0
- package/dist/commands/try-me.js +44 -13
- package/dist/commands/wrap.js +3 -3
- package/dist/index.js +2 -2
- package/dist/lib/agent-identity-route.d.ts +28 -0
- package/dist/lib/agent-identity-route.js +57 -0
- package/dist/lib/login-detect.d.ts +2 -2
- package/dist/lib/login-detect.js +4 -4
- package/dist/lib/served-agent-cache.d.ts +8 -0
- package/dist/lib/served-agent-cache.js +26 -9
- package/dist/lib/try-me.d.ts +18 -0
- package/dist/lib/try-me.js +70 -3
- package/package.json +1 -1
package/dist/lib/try-me.js
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* consumes and tolerate everything else (`[key: string]: unknown`) so a manifest
|
|
22
22
|
* bump that adds fields never breaks the CLI.
|
|
23
23
|
*/
|
|
24
|
-
import { MnemomApiError, readApiError } from "./api.js";
|
|
25
|
-
import { getApiUrl } from "./config.js";
|
|
24
|
+
import { MnemomApiError, normalizeApiError, readApiError } from "./api.js";
|
|
25
|
+
import { getApiUrl, getWebsiteUrl } from "./config.js";
|
|
26
26
|
// ── resolve (zero-auth; the token IS the credential) ─────────────────────────
|
|
27
27
|
const TOKEN_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
28
28
|
/** True iff `token` is shaped like a try-me token (tryme_… / a bare slug). */
|
|
@@ -212,7 +212,28 @@ export async function birthAgent(manifest, name, opts = {}) {
|
|
|
212
212
|
const agentId = response.headers.get(manifest.gateway.agent_header.toLowerCase());
|
|
213
213
|
if (!response.ok && !agentId) {
|
|
214
214
|
const text = await response.text().catch(() => "");
|
|
215
|
-
|
|
215
|
+
let raw;
|
|
216
|
+
try {
|
|
217
|
+
raw = JSON.parse(text);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
raw = null;
|
|
221
|
+
}
|
|
222
|
+
const parsed = normalizeApiError(raw);
|
|
223
|
+
const outOfMu = describeOutOfMu({
|
|
224
|
+
status: response.status,
|
|
225
|
+
code: parsed.code,
|
|
226
|
+
message: parsed.message,
|
|
227
|
+
details: parsed.details,
|
|
228
|
+
});
|
|
229
|
+
if (outOfMu) {
|
|
230
|
+
throw new MnemomApiError(response.status, outOfMu, {
|
|
231
|
+
code: parsed.code,
|
|
232
|
+
details: parsed.details,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
throw new MnemomApiError(response.status, `Birth call failed (${response.status}) and no agent id was minted: ` +
|
|
236
|
+
(parsed.message ?? text.slice(0, 300)), { code: parsed.code, details: parsed.details });
|
|
216
237
|
}
|
|
217
238
|
if (!agentId || !/^mnm-/.test(agentId)) {
|
|
218
239
|
throw new Error(`Birth succeeded (${response.status}) but the gateway returned no mnm- agent id on the ` +
|
|
@@ -220,6 +241,52 @@ export async function birthAgent(manifest, name, opts = {}) {
|
|
|
220
241
|
}
|
|
221
242
|
return { agentId, status: response.status };
|
|
222
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Error codes that mean "Dojo play needs µ": the gateway's 402 `billing_error`
|
|
246
|
+
* (balance_depleted / dojo_billing_account_required) and mnemom-api's Dojo and
|
|
247
|
+
* card-publish balance refusals.
|
|
248
|
+
*/
|
|
249
|
+
const OUT_OF_MU_CODES = new Set([
|
|
250
|
+
"billing_error",
|
|
251
|
+
"balance_depleted",
|
|
252
|
+
"balance_required",
|
|
253
|
+
"dojo_balance_depleted",
|
|
254
|
+
"dojo_billing_unconfigured",
|
|
255
|
+
]);
|
|
256
|
+
/**
|
|
257
|
+
* Where to recharge: the server's `details.top_up_url` (absolute, or a path on
|
|
258
|
+
* the website), else the website's billing page.
|
|
259
|
+
*/
|
|
260
|
+
export function rechargeUrl(details, websiteBase = getWebsiteUrl()) {
|
|
261
|
+
const base = websiteBase.replace(/\/$/, "");
|
|
262
|
+
const fromServer = details && typeof details === "object"
|
|
263
|
+
? details.top_up_url
|
|
264
|
+
: undefined;
|
|
265
|
+
if (typeof fromServer === "string") {
|
|
266
|
+
if (/^https?:\/\//.test(fromServer))
|
|
267
|
+
return fromServer;
|
|
268
|
+
if (fromServer.startsWith("/"))
|
|
269
|
+
return `${base}${fromServer}`;
|
|
270
|
+
}
|
|
271
|
+
return `${base}/settings/billing`;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The human message for a refusal that means the org is out of µ (or has no
|
|
275
|
+
* billing account): what happened, where to recharge, and how to resume.
|
|
276
|
+
* Undefined for any other refusal.
|
|
277
|
+
*/
|
|
278
|
+
export function describeOutOfMu(refusal, websiteBase = getWebsiteUrl()) {
|
|
279
|
+
const isOutOfMu = refusal.status === 402 || (refusal.code !== undefined && OUT_OF_MU_CODES.has(refusal.code));
|
|
280
|
+
if (!isOutOfMu)
|
|
281
|
+
return undefined;
|
|
282
|
+
const url = rechargeUrl(refusal.details, websiteBase);
|
|
283
|
+
const said = refusal.message?.trim();
|
|
284
|
+
const lead = said || "Your organization's µ balance is used up.";
|
|
285
|
+
const withUrl = lead.includes(url) ? lead : `${lead} Recharge at ${url}.`;
|
|
286
|
+
const headline = /^out of µ/i.test(withUrl) ? withUrl : `Out of µ — ${withUrl}`;
|
|
287
|
+
return (`${headline} Dojo play is charged to your organization's µ balance; ` +
|
|
288
|
+
"once it is recharged, re-run this command to keep going.");
|
|
289
|
+
}
|
|
223
290
|
/**
|
|
224
291
|
* Read the PUBLIC (no-auth) agent projection used to detect the human's claim.
|
|
225
292
|
* Never throws — a transient 404/5xx (the agent not yet queryable, or a blip)
|