@odla-ai/cli 0.46.4 → 0.46.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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-PCEGBCLZ.js";
4
+ } from "./chunk-PTOBFRCO.js";
5
5
  import {
6
6
  exitCodeFor
7
7
  } from "./chunk-5MEO3BVF.js";
@@ -9,4 +9,4 @@ export {
9
9
  exitCodeFor,
10
10
  runCli
11
11
  };
12
- //# sourceMappingURL=cli-UTMLBANX.js.map
12
+ //# sourceMappingURL=cli-NXZIUCZT.js.map
package/dist/index.cjs CHANGED
@@ -1327,7 +1327,7 @@ var COMMAND_SURFACE = {
1327
1327
  audit: {},
1328
1328
  credential: { set: {} }
1329
1329
  },
1330
- spend: { show: {}, reset: {} }
1330
+ spend: { show: {}, set: {}, reset: {} }
1331
1331
  },
1332
1332
  app: {
1333
1333
  archive: {},
@@ -1475,11 +1475,15 @@ function surfacePaths(node = COMMAND_SURFACE, prefix = []) {
1475
1475
  }
1476
1476
 
1477
1477
  // src/admin-spend.ts
1478
- async function call(ctx, method, scope) {
1478
+ async function call(ctx, method, scope, payload) {
1479
1479
  const url = `${ctx.platformUrl.replace(/\/$/, "")}/registry/platform/spend?scope=${encodeURIComponent(scope)}`;
1480
1480
  const response2 = await ctx.doFetch(url, {
1481
1481
  method,
1482
- headers: { authorization: `Bearer ${ctx.token}` }
1482
+ headers: {
1483
+ authorization: `Bearer ${ctx.token}`,
1484
+ ...payload === void 0 ? {} : { "content-type": "application/json" }
1485
+ },
1486
+ ...payload === void 0 ? {} : { body: JSON.stringify(payload) }
1483
1487
  });
1484
1488
  const body = await response2.json().catch(() => ({}));
1485
1489
  if (!response2.ok) {
@@ -1523,14 +1527,36 @@ async function spendReset(ctx, scope) {
1523
1527
  async function adminSpend(parsed, ctx) {
1524
1528
  const action2 = parsed.positionals[2];
1525
1529
  const scope = parsed.positionals[3] ?? stringOpt(parsed.options.scope);
1526
- if (action2 !== "show" && action2 !== "reset") rejectWord(["admin", "spend"], action2);
1530
+ if (action2 !== "show" && action2 !== "reset" && action2 !== "set") rejectWord(["admin", "spend"], action2);
1527
1531
  if (!scope) {
1528
1532
  throw new Error(
1529
1533
  `"admin spend ${action2}" needs a scope, e.g. odla-ai admin spend ${action2} app:my-app:<incarnation>`
1530
1534
  );
1531
1535
  }
1536
+ if (action2 === "set") return adminSpendSet(ctx, parsed, scope);
1532
1537
  return action2 === "show" ? spendShow(ctx, scope) : spendReset(ctx, scope);
1533
1538
  }
1539
+ async function adminSpendSet(ctx, parsed, scope) {
1540
+ const daily = stringOpt(parsed.options.daily);
1541
+ const none = parsed.options.none === true;
1542
+ if (none === (daily !== void 0)) {
1543
+ throw new Error("admin spend set needs exactly one of --daily <usd> or --none");
1544
+ }
1545
+ const dailyCapUsd = none ? null : Number(daily);
1546
+ if (dailyCapUsd !== null && (!Number.isFinite(dailyCapUsd) || dailyCapUsd < 0)) {
1547
+ throw new Error("--daily takes a non-negative dollar amount, for example --daily 25");
1548
+ }
1549
+ const result = await call(ctx, "PUT", scope, { dailyCapUsd });
1550
+ if (ctx.json) {
1551
+ ctx.out.log(JSON.stringify(result, null, 2));
1552
+ return;
1553
+ }
1554
+ ctx.out.log(`${result.scope}: ${result.message}`);
1555
+ ctx.out.log(` spent today ${money(result.spentUsd)}`);
1556
+ if (result.alreadyOverCap) {
1557
+ ctx.out.log(" today's spend already exceeds this cap \u2014 the next call will latch it.");
1558
+ }
1559
+ }
1534
1560
 
1535
1561
  // src/operator-context.ts
1536
1562
  var import_node_fs8 = require("fs");
@@ -2328,7 +2354,7 @@ async function adminCommand(parsed, deps = {}) {
2328
2354
  rejectWord(["admin", "ai", "credential"], parsed.positionals[3]);
2329
2355
  }
2330
2356
  if (area === "spend") {
2331
- assertArgs(parsed, JSON_OPTIONS, 4);
2357
+ assertArgs(parsed, [...JSON_OPTIONS, "daily", "none", "scope"], 4);
2332
2358
  const context2 = await resolveOperatorContext(parsed, { allowMissingConfig: true });
2333
2359
  const out = deps.stdout ?? console;
2334
2360
  const doFetch = deps.fetch ?? fetch;
@@ -11208,6 +11234,7 @@ Usage:
11208
11234
  odla-ai admin ai usage [--context <name>] [--app-id <id>] [--env <env>] [--run-id <id>] [--limit <1-500>] [--json]
11209
11235
  odla-ai admin ai audit [--context <name>] [--limit <1-200>] [--json]
11210
11236
  odla-ai admin spend show <app:<id>:<incarnation>> [--context <name>] [--json]
11237
+ odla-ai admin spend set <app:<id>:<incarnation>> (--daily <usd>|--none) [--context <name>] [--json]
11211
11238
  odla-ai admin spend reset <app:<id>:<incarnation>> [--context <name>] [--json]
11212
11239
  odla-ai security github connect [--repo owner/name] [--env dev] [continue in Studio; human session required]
11213
11240
  odla-ai security github disconnect --source <id> [--env dev] [continue in Studio; human session required]