@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.
package/dist/bin.cjs CHANGED
@@ -1725,7 +1725,7 @@ var init_surface = __esm({
1725
1725
  audit: {},
1726
1726
  credential: { set: {} }
1727
1727
  },
1728
- spend: { show: {}, reset: {} }
1728
+ spend: { show: {}, set: {}, reset: {} }
1729
1729
  },
1730
1730
  app: {
1731
1731
  archive: {},
@@ -1820,11 +1820,15 @@ var init_surface = __esm({
1820
1820
  });
1821
1821
 
1822
1822
  // src/admin-spend.ts
1823
- async function call(ctx, method, scope) {
1823
+ async function call(ctx, method, scope, payload) {
1824
1824
  const url = `${ctx.platformUrl.replace(/\/$/, "")}/registry/platform/spend?scope=${encodeURIComponent(scope)}`;
1825
1825
  const response2 = await ctx.doFetch(url, {
1826
1826
  method,
1827
- headers: { authorization: `Bearer ${ctx.token}` }
1827
+ headers: {
1828
+ authorization: `Bearer ${ctx.token}`,
1829
+ ...payload === void 0 ? {} : { "content-type": "application/json" }
1830
+ },
1831
+ ...payload === void 0 ? {} : { body: JSON.stringify(payload) }
1828
1832
  });
1829
1833
  const body = await response2.json().catch(() => ({}));
1830
1834
  if (!response2.ok) {
@@ -1867,14 +1871,36 @@ async function spendReset(ctx, scope) {
1867
1871
  async function adminSpend(parsed, ctx) {
1868
1872
  const action2 = parsed.positionals[2];
1869
1873
  const scope = parsed.positionals[3] ?? stringOpt(parsed.options.scope);
1870
- if (action2 !== "show" && action2 !== "reset") rejectWord(["admin", "spend"], action2);
1874
+ if (action2 !== "show" && action2 !== "reset" && action2 !== "set") rejectWord(["admin", "spend"], action2);
1871
1875
  if (!scope) {
1872
1876
  throw new Error(
1873
1877
  `"admin spend ${action2}" needs a scope, e.g. odla-ai admin spend ${action2} app:my-app:<incarnation>`
1874
1878
  );
1875
1879
  }
1880
+ if (action2 === "set") return adminSpendSet(ctx, parsed, scope);
1876
1881
  return action2 === "show" ? spendShow(ctx, scope) : spendReset(ctx, scope);
1877
1882
  }
1883
+ async function adminSpendSet(ctx, parsed, scope) {
1884
+ const daily = stringOpt(parsed.options.daily);
1885
+ const none = parsed.options.none === true;
1886
+ if (none === (daily !== void 0)) {
1887
+ throw new Error("admin spend set needs exactly one of --daily <usd> or --none");
1888
+ }
1889
+ const dailyCapUsd = none ? null : Number(daily);
1890
+ if (dailyCapUsd !== null && (!Number.isFinite(dailyCapUsd) || dailyCapUsd < 0)) {
1891
+ throw new Error("--daily takes a non-negative dollar amount, for example --daily 25");
1892
+ }
1893
+ const result = await call(ctx, "PUT", scope, { dailyCapUsd });
1894
+ if (ctx.json) {
1895
+ ctx.out.log(JSON.stringify(result, null, 2));
1896
+ return;
1897
+ }
1898
+ ctx.out.log(`${result.scope}: ${result.message}`);
1899
+ ctx.out.log(` spent today ${money(result.spentUsd)}`);
1900
+ if (result.alreadyOverCap) {
1901
+ ctx.out.log(" today's spend already exceeds this cap \u2014 the next call will latch it.");
1902
+ }
1903
+ }
1878
1904
  var money;
1879
1905
  var init_admin_spend = __esm({
1880
1906
  "src/admin-spend.ts"() {
@@ -2723,7 +2749,7 @@ async function adminCommand(parsed, deps = {}) {
2723
2749
  rejectWord(["admin", "ai", "credential"], parsed.positionals[3]);
2724
2750
  }
2725
2751
  if (area === "spend") {
2726
- assertArgs(parsed, JSON_OPTIONS, 4);
2752
+ assertArgs(parsed, [...JSON_OPTIONS, "daily", "none", "scope"], 4);
2727
2753
  const context2 = await resolveOperatorContext(parsed, { allowMissingConfig: true });
2728
2754
  const out = deps.stdout ?? console;
2729
2755
  const doFetch = deps.fetch ?? fetch;
@@ -12139,6 +12165,7 @@ Usage:
12139
12165
  odla-ai admin ai usage [--context <name>] [--app-id <id>] [--env <env>] [--run-id <id>] [--limit <1-500>] [--json]
12140
12166
  odla-ai admin ai audit [--context <name>] [--limit <1-200>] [--json]
12141
12167
  odla-ai admin spend show <app:<id>:<incarnation>> [--context <name>] [--json]
12168
+ odla-ai admin spend set <app:<id>:<incarnation>> (--daily <usd>|--none) [--context <name>] [--json]
12142
12169
  odla-ai admin spend reset <app:<id>:<incarnation>> [--context <name>] [--json]
12143
12170
  odla-ai security github connect [--repo owner/name] [--env dev] [continue in Studio; human session required]
12144
12171
  odla-ai security github disconnect --source <id> [--env dev] [continue in Studio; human session required]