@clocknext/sdk 0.15.0 → 0.17.0

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/src/types.ts CHANGED
@@ -21,12 +21,15 @@ export type SignalStatus = "SUCCESS" | "FAILURE" | "PENDING";
21
21
  /**
22
22
  * Token counts for a signal. `input` and `output` are required — every metered
23
23
  * call has them, and the server requires them. `cache` (provider-specific
24
- * prompt-cache reads) is optional and defaults to 0 server-side when omitted.
24
+ * prompt-cache reads) and `cacheWrite` (tokens written into the prompt cache,
25
+ * priced at the model's separate cache-write rate) are optional and default to
26
+ * 0 server-side when omitted.
25
27
  */
26
28
  export interface Tokens {
27
29
  input: number;
28
30
  output: number;
29
31
  cache?: number;
32
+ cacheWrite?: number;
30
33
  }
31
34
 
32
35
  /**
@@ -273,7 +276,10 @@ export interface SerializedUsageLog {
273
276
  member: string | null;
274
277
  inputTokens: number;
275
278
  outputTokens: number;
279
+ /** Cache-read tokens. */
276
280
  cacheTokens: number;
281
+ /** Cache-write tokens, priced separately from cache reads. */
282
+ cacheWriteTokens: number;
277
283
  /** Total credits deducted: the call's real per-model provider cost as a
278
284
  * fraction of the credit's base price (i.e. cost + your margin), plus any
279
285
  * credit-rule add-ons; 0 for wallet-money calls. */
@@ -431,7 +437,14 @@ export interface UsageLogEntry {
431
437
  typeName: string | null;
432
438
  member: string | null;
433
439
  model: { name: string | null; provider: string | null } | null;
434
- usage: { inputTokens: number; outputTokens: number; cacheTokens: number };
440
+ usage: {
441
+ inputTokens: number;
442
+ outputTokens: number;
443
+ /** Cache-read tokens. */
444
+ cacheTokens: number;
445
+ /** Cache-write tokens, priced separately from cache reads. */
446
+ cacheWriteTokens: number;
447
+ };
435
448
  /** Formatted USD strings (e.g. `"$0.0064"`). */
436
449
  cost: { providedCost: string; customerCost: string };
437
450
  /** Populated only when `kind === "credit"`. `amount` is a formatted credit
@@ -564,20 +577,45 @@ export interface UnitBalance {
564
577
  remaining: number;
565
578
  }
566
579
 
567
- /** Wallet / credit / outcome / unit balances for a customer's active plan
568
- * (`customers.balances()`). */
580
+ /** One prepaid (ADVANCE) composite pool on a customer's plan. */
581
+ export interface CompositeBalance {
582
+ compositeId: string;
583
+ /** The tag signals send in their `composite` block. */
584
+ refId: string;
585
+ name: string;
586
+ /** The pool size the plan grants this cycle. */
587
+ granted: number;
588
+ /** Slots claimed this cycle — one per distinct tag value. */
589
+ used: number;
590
+ /** `granted - used` plus this cycle's manual adjustments. May be negative:
591
+ * running past the pool is allowed and carries into the next cycle. */
592
+ remaining: number;
593
+ /** What `granted` was before the pool was ever resized for this customer;
594
+ * `null` if it never was. */
595
+ originalGranted: number | null;
596
+ }
597
+
598
+ /** Wallet / credit / outcome / unit balances and composite pools for a
599
+ * customer's active plan (`customers.balances()`). */
569
600
  export interface CustomerBalances {
570
601
  customerId: string;
571
602
  currency: { code: string; rateUsd: number };
572
603
  hasPlan: boolean;
573
- /** `null` when the plan has no Wallet component. */
574
- wallet: { balanceUsd: number } | null;
575
- /** The Reserved Wallet; `null` when the org hasn't enabled it. Independent
576
- * of `wallet` — present whether or not the plan has a Wallet. */
577
- reservedWallet: { balanceUsd: number } | null;
604
+ /** Both wallet balances, in USD. Always present. */
605
+ wallet: {
606
+ /** The ordinary wallet — always reported, also when the plan has no
607
+ * Wallet component or there's no plan. May be negative. */
608
+ balance: number;
609
+ /** The Reserved Wallet; absent when the org hasn't enabled it, otherwise
610
+ * present whether or not the plan has a Wallet. Never negative. */
611
+ reservedBalance?: number;
612
+ };
578
613
  credits: CreditBalance[];
579
614
  outcomes: OutcomeBalance[];
580
615
  units: UnitBalance[];
616
+ /** ADVANCE composite pools. A composite billed in ARREAR has no pool and
617
+ * isn't listed. */
618
+ composites: CompositeBalance[];
581
619
  }
582
620
 
583
621
  /** The customer's active plan (the `plan` field of `customers.plan()`);
@@ -626,13 +664,12 @@ export interface PortalToken {
626
664
  // Plans
627
665
  // ---------------------------------------------------------------------------
628
666
 
629
- /** How often a plan bills. `FREE` is a one-time grant; `EVERY_5_MIN` is a test cadence. */
667
+ /** How often a plan bills. `FREE` is a one-time grant. */
630
668
  export type BillingCycle =
631
669
  | "MONTHLY"
632
670
  | "QUARTERLY"
633
671
  | "SEMI_ANNUAL"
634
672
  | "YEARLY"
635
- | "EVERY_5_MIN"
636
673
  | "FREE";
637
674
  export type PlanType = "WALLET" | "BUNDLE";
638
675
  export type PlanKind = "FLAT_PRICE" | "PAY_AS_YOU_GO" | "PAY_PER_SEAT";
@@ -654,7 +691,8 @@ export type ComponentType =
654
691
  /** ADVANCE bills up-front for the cycle; ARREAR bills for what was consumed. */
655
692
  export type BillingMode = "ADVANCE" | "ARREAR";
656
693
 
657
- export interface PlanComponent {
694
+ /** One line of a plan (`plan.entitlements[]`). */
695
+ export interface PlanEntitlement {
658
696
  id: string;
659
697
  type: ComponentType;
660
698
  billingMode: BillingMode;
@@ -667,14 +705,19 @@ export interface PlanComponent {
667
705
  targetName: string | null;
668
706
  quantity: number | null;
669
707
  amount: number | null;
708
+ /** ADVANCE credit / outcome / composite / wallet components: what's left at
709
+ * the end of a cycle carries into the next one instead of resetting.
710
+ * Always false for unit, flat and ARREAR components and on FREE plans. */
711
+ rollover: boolean;
670
712
  }
671
713
 
714
+ /** @deprecated Renamed to {@link PlanEntitlement} — a plan's lines are `entitlements` now. */
715
+ export type PlanComponent = PlanEntitlement;
716
+
672
717
  export interface Plan {
673
718
  id: string;
674
719
  name: string;
675
720
  description: string | null;
676
- type: PlanType;
677
- kind: PlanKind;
678
721
  billingCycle: BillingCycle;
679
722
  cost: number;
680
723
  /** Signed adjustment applied to the plan's headline price (default 0). */
@@ -682,11 +725,290 @@ export interface Plan {
682
725
  /** When true, ARREAR consumption is funded from the customer's wallet as it
683
726
  * happens instead of being invoiced at cycle end. All-or-nothing per plan. */
684
727
  walletFundedArrear: boolean;
728
+ /** The workspace's primary currency when the plan was created. */
685
729
  currencyCode: string;
686
730
  isActive: boolean;
687
- components: PlanComponent[];
731
+ createdAt: string;
732
+ updatedAt: string;
733
+ /** The plan's lines — what a customer on it is granted or metered for. */
734
+ entitlements: PlanEntitlement[];
735
+ }
736
+
737
+ /** One line of a plan, as you send it to `plans.create()` / `plans.update()`.
738
+ * Set the id that matches `type`: `creditId` (CREDIT), `outcomeId`
739
+ * (OUTCOME), `unitId` (UNIT) or `compositeId` (PRICING_METRIC — a
740
+ * composite). The lines `plans.get()` returns can be sent back as they are. */
741
+ export interface PlanEntitlementInput {
742
+ type: ComponentType;
743
+ billingMode: BillingMode;
744
+ creditId?: string | null;
745
+ outcomeId?: string | null;
746
+ unitId?: string | null;
747
+ compositeId?: string | null;
748
+ /** ADVANCE credit / outcome / unit / composite: granted each cycle (0 allowed). */
749
+ quantity?: number | null;
750
+ /** WALLET (ADVANCE prepaid balance, $0 allowed) or FLAT (fee, above $0), in USD. */
751
+ amount?: number | null;
752
+ /** ADVANCE credit / outcome / composite / wallet: carry leftovers into the next cycle. */
753
+ rollover?: boolean;
754
+ }
755
+
756
+ /** `plans.create()` body. The plan's currency is the workspace's primary
757
+ * currency — it can't be chosen. A new plan is active; retire it with
758
+ * `plans.archive()`. */
759
+ export interface CreatePlanInput {
760
+ name: string;
761
+ billingCycle: BillingCycle;
762
+ description?: string | null;
763
+ /** Pay ARREAR usage from the prepaid wallet as it happens. Needs an ADVANCE
764
+ * WALLET line and at least one ARREAR credit / outcome / unit / composite. */
765
+ walletFundedArrear?: boolean;
766
+ /** Signed rounding nudge (USD) on the due-at-purchase total. */
767
+ priceAdjustment?: number;
768
+ /** At least one line. At most one WALLET and one FLAT. */
769
+ entitlements: PlanEntitlementInput[];
770
+ }
771
+
772
+ /** `plans.update()` body — a PARTIAL update: only the fields you send change.
773
+ * `entitlements`, when sent, is the complete new list. */
774
+ export type UpdatePlanInput = Partial<CreatePlanInput>;
775
+
776
+ // ---------------------------------------------------------------------------
777
+ // Catalogue: credits, outcomes, units, composites
778
+ //
779
+ // Every catalogue resource has the same six calls — list, get, create,
780
+ // update (a PARTIAL update: only the fields you send change), archive and
781
+ // unarchive — and NO delete: the API never deletes catalogue items, so usage
782
+ // history never loses what it points at. Archiving is the only way to retire
783
+ // one, and `isActive` is read-only.
784
+ // ---------------------------------------------------------------------------
785
+
786
+ /** One model line of a credit's / outcome step's pricing bundle, as returned. */
787
+ export interface ModelBundleLine {
788
+ /** The model's id — the same one a usage signal sends as `usage.model`.
789
+ * `null` only when the model was removed from the workspace after this
790
+ * bundle was saved (the line keeps its name and stored price). */
791
+ modelId: string | null;
792
+ /** The model's display name, filled in by the server. */
793
+ modelName: string;
794
+ /** Average tokens one LLM call uses on this model. */
795
+ averageTokensPerLLMCall: number;
796
+ /** Whole-percent split of those tokens; the four add up to 100. */
797
+ input: number;
798
+ output: number;
799
+ cache: number;
800
+ /** 0 on a model with no cache-write price. */
801
+ cacheWrite: number;
802
+ }
803
+
804
+ /** One model line as you send it. Several lines (one per model) are allowed;
805
+ * the price is the sum of their costs, worked out on the server from the
806
+ * models' live prices. */
807
+ export interface ModelBundleLineInput {
808
+ /** The model's id, e.g. `"gpt-4o"` — the same one a usage signal sends as
809
+ * `usage.model`. Matched ignoring case; it must be enabled in your
810
+ * workspace. */
811
+ modelId: string;
812
+ /** Above 0. */
813
+ averageTokensPerLLMCall: number;
814
+ input: number;
815
+ output: number;
816
+ cache: number;
817
+ /** Default 0. Only on a model that has a cache-write price. */
818
+ cacheWrite?: number;
819
+ }
820
+
821
+ /** A credit — a token-metered entitlement your product draws down by its
822
+ * `agentKey`. */
823
+ export interface Credit {
824
+ id: string;
825
+ name: string;
826
+ /** What a credit signal names; unique in the workspace. */
827
+ agentKey: string;
828
+ description: string | null;
829
+ /** Sum of the bundle lines' tokens (display figure). */
830
+ tokensPerCredit: number;
831
+ /** Cost of one credit, worked out from `modelBundle`. */
832
+ basePrice: number;
833
+ modelBundle: ModelBundleLine[];
834
+ marginPercent: number;
835
+ /** `basePrice` plus the margin — what a customer pays per credit. */
836
+ pricePerCredit: number;
837
+ isActive: boolean;
838
+ createdAt: string;
839
+ updatedAt: string;
840
+ }
841
+
842
+ /** `credits.create()` body. The price is always worked out on the server from
843
+ * `modelBundle` — it is never typed in. */
844
+ export interface CreateCreditInput {
845
+ name: string;
846
+ agentKey: string;
847
+ /** -100 or more. */
848
+ marginPercent: number;
849
+ /** At least one line. */
850
+ modelBundle: ModelBundleLineInput[];
851
+ description?: string | null;
852
+ }
853
+
854
+ /** `credits.update()` body — PARTIAL. Send `modelBundle` to re-price; leave it
855
+ * out to keep the stored base price (a new margin is applied on top). */
856
+ export type UpdateCreditInput = Partial<CreateCreditInput>;
857
+
858
+ /** An outcome — a multi-step deliverable billed per completed outcome. */
859
+ export interface Outcome {
860
+ id: string;
861
+ name: string;
862
+ /** The outcome's own key (unique in the workspace) — not what a step signal
863
+ * names; each step has its own `agentKey`. */
864
+ agentKey: string;
865
+ description: string | null;
866
+ isActive: boolean;
867
+ /** Sum of the steps' base prices. */
868
+ basePrice: number;
869
+ marginPercent: number;
870
+ pricePerOutcome: number;
871
+ createdAt: string;
872
+ updatedAt: string;
873
+ }
874
+
875
+ /** One step of an outcome. */
876
+ export interface OutcomeStep {
877
+ /** Send it back on `outcomes.update()` to keep this step. */
878
+ id: string;
879
+ name: string;
880
+ /** What an outcome step signal names; unique in the workspace. */
881
+ agentKey: string;
882
+ order: number;
883
+ basePrice: number;
884
+ modelBundle: ModelBundleLine[];
885
+ }
886
+
887
+ /** `outcomes.get()` — the outcome with its steps in full. */
888
+ export interface OutcomeWithSteps extends Outcome {
889
+ steps: OutcomeStep[];
890
+ }
891
+
892
+ /** One step as you send it. */
893
+ export interface OutcomeStepInput {
894
+ /** An existing step's id, to keep that step (update only). A step sent
895
+ * without an id but with an existing step's `agentKey` is that step too. */
896
+ id?: string;
897
+ name: string;
898
+ agentKey: string;
899
+ /** Required for a new step. Leave it out on an existing step to keep its
900
+ * price. */
901
+ modelBundle?: ModelBundleLineInput[];
902
+ }
903
+
904
+ /** `outcomes.create()` body. */
905
+ export interface CreateOutcomeInput {
906
+ name: string;
907
+ agentKey: string;
908
+ /** -100 or more. */
909
+ marginPercent: number;
910
+ /** 1–50 steps; names and agent keys unique. */
911
+ steps: OutcomeStepInput[];
912
+ description?: string | null;
913
+ }
914
+
915
+ /** `outcomes.update()` body — PARTIAL. Leave `steps` out to leave the steps
916
+ * alone; send it and it is the complete step list (stored steps left out are
917
+ * removed). */
918
+ export type UpdateOutcomeInput = Partial<CreateOutcomeInput>;
919
+
920
+ /** How a unit is priced. */
921
+ export type UnitPricingType = "FLAT" | "SLAB" | "VOLUME";
922
+
923
+ /** One price band of a SLAB / VOLUME unit. */
924
+ export interface UnitTier {
925
+ id: string;
926
+ /** Inclusive upper bound; `null` on the last tier ("and above"). */
927
+ upTo: number | null;
928
+ /** Per-unit price for this band. */
929
+ price: number;
930
+ order: number;
931
+ }
932
+
933
+ /** A unit — a fixed-price, non-LLM event (an upload, a seat, an API call). */
934
+ export interface Unit {
935
+ id: string;
936
+ name: string;
937
+ /** What a unit signal names; unique in the workspace. */
938
+ agentKey: string;
939
+ description: string | null;
940
+ pricingType: UnitPricingType;
941
+ /** FLAT only. */
942
+ flatPrice: number;
943
+ /** SLAB / VOLUME only. */
944
+ tiers: UnitTier[];
945
+ isActive: boolean;
946
+ createdAt: string;
947
+ updatedAt: string;
948
+ createdByName: string | null;
949
+ }
950
+
951
+ /** `units.create()` body. */
952
+ export interface CreateUnitInput {
953
+ name: string;
954
+ agentKey: string;
955
+ pricingType: UnitPricingType;
956
+ /** FLAT only. */
957
+ flatPrice?: number;
958
+ /** SLAB / VOLUME: 1–50 tiers, `upTo` rising; the last one `upTo: null`. */
959
+ tiers?: { upTo: number | null; price: number }[];
960
+ description?: string | null;
961
+ }
962
+
963
+ /** `units.update()` body — PARTIAL. `tiers`, when sent, is the complete list. */
964
+ export type UpdateUnitInput = Partial<CreateUnitInput>;
965
+
966
+ /** A catalogue item a composite wraps. */
967
+ export interface CompositeItem {
968
+ id: string;
969
+ name: string;
970
+ agentKey: string;
971
+ }
972
+
973
+ /** A composite — several credits / outcomes / units grouped under one tag and
974
+ * billed as ONE thing, per completed occurrence, once a plan sells it. */
975
+ export interface Composite {
976
+ id: string;
977
+ name: string;
978
+ /** The tag your signals send in their `composite` block. */
979
+ refId: string;
980
+ description: string | null;
981
+ /** USD per completed occurrence, once a plan sells it. */
982
+ price: number;
983
+ isActive: boolean;
984
+ createdAt: string;
985
+ updatedAt: string;
986
+ entitlements: {
987
+ credits: CompositeItem[];
988
+ outcomes: CompositeItem[];
989
+ units: CompositeItem[];
990
+ };
688
991
  }
689
992
 
993
+ /** `composites.create()` body. */
994
+ export interface CreateCompositeInput {
995
+ name: string;
996
+ refId: string;
997
+ price: number;
998
+ description?: string | null;
999
+ /** At least one id across the three lists. Every item must be active, and a
1000
+ * unit must be FLAT-priced. */
1001
+ entitlements: {
1002
+ creditIds?: string[];
1003
+ outcomeIds?: string[];
1004
+ unitIds?: string[];
1005
+ };
1006
+ }
1007
+
1008
+ /** `composites.update()` body — PARTIAL. `entitlements`, when sent, is the
1009
+ * complete new set. */
1010
+ export type UpdateCompositeInput = Partial<CreateCompositeInput>;
1011
+
690
1012
  // ---------------------------------------------------------------------------
691
1013
  // Purchases (subscriptions)
692
1014
  // ---------------------------------------------------------------------------
@@ -948,11 +1270,12 @@ export interface UpdateMemberInput {
948
1270
  // ---------------------------------------------------------------------------
949
1271
 
950
1272
  /**
951
- * Which of a customer's two wallet balances an entry moves: `MAIN` (the
952
- * ordinary wallet) or `RESERVED` (the Reserved Wallet — an org-gated second
953
- * balance behind it; see {@link WalletAdjustInput.pool}).
1273
+ * Which of a customer's two wallet balances an entry moves: `"main"` (the
1274
+ * ordinary wallet) or `"reserved"` (the Reserved Wallet — an org-gated second
1275
+ * balance behind it; see {@link WalletAdjustInput.pool}). Lowercase only —
1276
+ * the API refuses `"MAIN"` / `"RESERVED"`.
954
1277
  */
955
- export type WalletPool = "MAIN" | "RESERVED";
1278
+ export type WalletPool = "main" | "reserved";
956
1279
 
957
1280
  /** Top up (positive) or draw down (negative) a customer's wallet. `delta` is
958
1281
  * a non-zero amount in USD (cents allowed); absolute value ≤ 10,000,000. No
@@ -964,16 +1287,17 @@ export interface WalletAdjustInput {
964
1287
  delta: number;
965
1288
  notes?: string;
966
1289
  /**
967
- * Which balance to move. Default `"MAIN"`, the ordinary wallet.
1290
+ * Which balance to move. Default `"main"`, the ordinary wallet (leave it
1291
+ * out; `null` is refused).
968
1292
  *
969
- * `"RESERVED"` moves the Reserved Wallet instead — a second balance behind
1293
+ * `"reserved"` moves the Reserved Wallet instead — a second balance behind
970
1294
  * the wallet that a wallet-funded Arrear charge draws on once the wallet
971
1295
  * runs out (Wallet → Reserved down to 0 → Wallet goes negative). It must be
972
1296
  * switched on for the org (Settings → Organisation → "Enable Reserved
973
1297
  * balance in wallet"), else this is a `PlanError`. It never goes negative:
974
1298
  * a reduce below zero is refused (an `AllowanceError`), not capped — drawing
975
1299
  * down to exactly 0 is fine. `remaining` is then the Reserved balance. A
976
- * `"MAIN"` adjustment never touches it.
1300
+ * `"main"` adjustment never touches it.
977
1301
  */
978
1302
  pool?: WalletPool;
979
1303
  /**