@butlerbot/sdk 0.0.6-alpha.5 → 0.0.7-alpha.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/dist/config.d.ts CHANGED
@@ -22,5 +22,12 @@ export declare const CONFIG: {
22
22
  };
23
23
  };
24
24
  };
25
+ usage: {
26
+ policy: {
27
+ v3: {
28
+ base: string;
29
+ };
30
+ };
31
+ };
25
32
  };
26
33
  };
package/dist/config.js CHANGED
@@ -16,6 +16,11 @@ exports.CONFIG = {
16
16
  chats: {
17
17
  v1: { base: "/api/convo/get/history" }
18
18
  }
19
+ },
20
+ usage: {
21
+ policy: {
22
+ v3: { base: "/user/usage/v3/policy" },
23
+ }
19
24
  }
20
25
  }
21
26
  };
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export declare class ButlerBotClient {
20
20
  healthCheck(healthCheckPath?: string): Promise<boolean>;
21
21
  /** Spawns a new Conversation, inherits api key and server URL */
22
22
  createConversation(config?: OptionalApiKey<ConversationOptions>): Conversation;
23
+ /** Get current usage policy data */
24
+ getUsagePolicyData(usagePolicyPath?: string): Promise<import("./types/usage/policy").UsagePolicyData>;
23
25
  }
24
- export { Conversation, ConversationOptions };
25
26
  export * from "./types/type_registry";
27
+ export { Conversation, ConversationOptions };
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ exports.Conversation = exports.ButlerBotClient = void 0;
27
27
  const config_1 = require("./config");
28
28
  const conversation_1 = require("./modules/conversation");
29
29
  Object.defineProperty(exports, "Conversation", { enumerable: true, get: function () { return conversation_1.Conversation; } });
30
+ const usage_1 = require("./modules/usage");
30
31
  class ButlerBotClient {
31
32
  constructor(config) {
32
33
  this.apiKey = config.apiKey;
@@ -52,6 +53,11 @@ class ButlerBotClient {
52
53
  createConversation(config = {}) {
53
54
  return new conversation_1.Conversation(Object.assign({ debug: this.debug, apiKey: this.apiKey, serverUrl: this.serverUrl }, config));
54
55
  }
56
+ /** Get current usage policy data */
57
+ getUsagePolicyData(usagePolicyPath) {
58
+ return (0, usage_1.getUsagePolicyData)({ serverURL: this.serverUrl, path: usagePolicyPath }, this.apiKey, this.debug);
59
+ }
55
60
  }
56
61
  exports.ButlerBotClient = ButlerBotClient;
62
+ // Expose types from subsequent modules
57
63
  __exportStar(require("./types/type_registry"), exports);
@@ -84,7 +84,6 @@ export declare class Conversation {
84
84
  getPlatform(): string | undefined;
85
85
  /** Gets the current personality configuration */
86
86
  getPersonality(): string | undefined;
87
- formatURL(url: string, params?: Object): string;
88
87
  /** Fetches the conversation state from the server, including message history and metadata */
89
88
  fetchState(): Promise<ConversationStateResponse>;
90
89
  /** Sends a message into the conversation */
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Conversation = void 0;
13
13
  const eventsource_1 = require("eventsource");
14
14
  const config_1 = require("../config");
15
+ const url_formatter_1 = require("../util/url_formatter");
15
16
  const DEFAULT_CONVO_API_V = "v3";
16
17
  class Conversation {
17
18
  constructor(config) {
@@ -108,29 +109,13 @@ class Conversation {
108
109
  var _a;
109
110
  return (_a = this.options) === null || _a === void 0 ? void 0 : _a.personality;
110
111
  }
111
- // HELPERS
112
- formatURL(url, params = {}) {
113
- const fParams = Object.assign({ api_key: this.apiKey }, params);
114
- const paramQuery = new URLSearchParams(fParams).toString();
115
- const fUrl = `${url}?${paramQuery}`;
116
- if (this.debug) {
117
- const debugUrl = new URL(fUrl);
118
- const apiKey = debugUrl.searchParams.get('api_key');
119
- if (apiKey) {
120
- const obscuredKey = apiKey.length > 6 ? `${apiKey.slice(0, 3)}...${apiKey.slice(-3)}` : '***';
121
- debugUrl.searchParams.set('api_key', obscuredKey);
122
- }
123
- console.log(`[Formatting URL ${debugUrl.toString()}]`);
124
- }
125
- return fUrl;
126
- }
127
112
  // GETTERS
128
113
  /** Fetches the conversation state from the server, including message history and metadata */
129
114
  fetchState() {
130
115
  return __awaiter(this, void 0, void 0, function* () {
131
116
  if (!this.convoId)
132
117
  throw new Error("Conversation ID is not set");
133
- const url = this.formatURL(`${this.endpoints.history}/${this.convoId}`);
118
+ const url = (0, url_formatter_1.formatURL)(`${this.endpoints.history}/${this.convoId}`, undefined, { apiKey: this.apiKey, debug: this.debug });
134
119
  const response = yield fetch(url);
135
120
  if (!response.ok) {
136
121
  const errorText = yield response.text();
@@ -148,7 +133,7 @@ class Conversation {
148
133
  );
149
134
  if (this.convoId)
150
135
  payload.chatId = this.convoId;
151
- const url = this.formatURL(this.endpoints.conversation, payload);
136
+ const url = (0, url_formatter_1.formatURL)(this.endpoints.conversation, payload, { apiKey: this.apiKey, debug: this.debug });
152
137
  const sse = new eventsource_1.EventSource(url);
153
138
  sse.addEventListener("message", (event) => {
154
139
  const data = JSON.parse(event.data);
@@ -0,0 +1,6 @@
1
+ import { UsagePolicyData } from "../types/usage/policy";
2
+ /** Fetches the current usage policy data from the server */
3
+ export declare function getUsagePolicyData(endpoint: {
4
+ serverURL: string;
5
+ path?: string;
6
+ }, apiKey: string, debug?: boolean): Promise<UsagePolicyData>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getUsagePolicyData = getUsagePolicyData;
13
+ const config_1 = require("../config");
14
+ const url_formatter_1 = require("../util/url_formatter");
15
+ /** Fetches the current usage policy data from the server */
16
+ function getUsagePolicyData(endpoint, apiKey, debug) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const useEndpoint = endpoint.serverURL + (endpoint.path || config_1.CONFIG.paths.usage.policy.v3.base);
19
+ const url = (0, url_formatter_1.formatURL)(useEndpoint, {}, { apiKey, debug });
20
+ const response = yield fetch(url);
21
+ const data = yield response.json();
22
+ if (!response.ok) {
23
+ const errorText = yield response.text();
24
+ throw new Error(`Failed to fetch usage policy data: ${response.status} ${response.statusText} - ${errorText}`);
25
+ }
26
+ if (!data.success) {
27
+ throw new Error(`API error while fetching usage policy data: ${data.error || 'Unknown error'}`);
28
+ }
29
+ return data;
30
+ });
31
+ }
@@ -131,40 +131,15 @@ export type ResponseMetadata = {
131
131
  };
132
132
  /** Token usage breakdown */
133
133
  tokens: TokenUsage;
134
- /** The cost breakdown */
134
+ /** The cost of the current turn */
135
135
  cost: {
136
- /** The cost of the current turn */
137
136
  turnCost?: ModelMessageCost;
138
- /** The current user's usage cost */
139
- dailyUsageCost: number;
140
- /** The user's cost limit for the conversation (e.g., daily limit) */
141
- dailyUsageCostLimit: number;
142
- };
143
- /** Usage budget info */
144
- limit: {
145
- /** Current usage cost as a percentage of daily limit (0–1) */
146
- percentage: number;
147
- /** Human-readable percentage (e.g. "42.3%") */
148
- percentageDisplay: string;
149
- /** Name of the active usage stage */
150
- stageName: string;
151
- };
152
- /** Model switching info (tiered auto-downgrade) */
153
- modelSwitching: {
154
- /** Whether the model was switched from the user's request */
155
- switched: boolean;
156
- /** Originally requested model */
157
- requestedModel: string;
158
- /** Model that was actually used */
159
- activeModel: string;
160
- /** Usage stage that triggered the switch */
161
- stage?: string;
162
137
  };
163
138
  /** Response timing */
164
139
  timing: {
165
- /** Milliseconds from request start to first streamed event */
140
+ /** Milliseconds from turn start to first streamed event */
166
141
  firstEventMs: number;
167
- /** Total response time in milliseconds */
142
+ /** Total turn time in milliseconds */
168
143
  totalMs: number;
169
144
  };
170
145
  };
@@ -0,0 +1,45 @@
1
+ import { AI_MODEL } from "../model";
2
+ export type PolicyRule = {
3
+ /** When the current usage exceeds this threshold */
4
+ whenUsageAbove: {
5
+ type: "percentage";
6
+ value: number;
7
+ };
8
+ /** When the current chosen model is equal to this model */
9
+ whenModelEquals?: {
10
+ value: AI_MODEL;
11
+ };
12
+ /** The model to overwrite the convos as, 'null' means no overwrite - use user's choice */
13
+ model: AI_MODEL | null;
14
+ /** When this rule is activated, this message will be sent to the user */
15
+ switchMessage?: string;
16
+ /** The message appended on the end of every message sent giving additional info */
17
+ appendMessage?: string;
18
+ };
19
+ export type UsagePolicy = {
20
+ rules: PolicyRule[];
21
+ maxConvoLength?: number;
22
+ };
23
+ export type UsagePolicyData = {
24
+ limit: {
25
+ /** Current usage cost as a percentage of daily limit (0–1) */
26
+ percentage: number;
27
+ };
28
+ /** Model switching info (tiered auto-downgrade) */
29
+ modelSwitching: {
30
+ /** Whether the model was switched from the user's request */
31
+ switched: boolean;
32
+ /** Originally requested model */
33
+ requestedModel?: string;
34
+ /** Model that was actually used */
35
+ activeModel?: string;
36
+ };
37
+ /** Usage policy information */
38
+ usagePolicy: UsagePolicy;
39
+ daily: {
40
+ /** The current user's usage cost */
41
+ dailyUsageCost: number;
42
+ /** The user's cost limit for the conversation (e.g., daily limit) */
43
+ dailyUsageCostLimit: number;
44
+ };
45
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export declare function formatURL(url: string, params: Object | undefined, config: {
2
+ apiKey: string;
3
+ debug?: boolean;
4
+ }): string;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatURL = formatURL;
4
+ function formatURL(url, params = {}, config) {
5
+ const fParams = Object.assign({ api_key: config.apiKey }, params);
6
+ const paramQuery = new URLSearchParams(fParams).toString();
7
+ const fUrl = `${url}?${paramQuery}`;
8
+ if (config.debug) {
9
+ const debugUrl = new URL(fUrl);
10
+ const apiKey = debugUrl.searchParams.get('api_key');
11
+ if (apiKey) {
12
+ const obscuredKey = apiKey.length > 6 ? `${apiKey.slice(0, 3)}...${apiKey.slice(-3)}` : '***';
13
+ debugUrl.searchParams.set('api_key', obscuredKey);
14
+ }
15
+ console.log(`[Formatting URL ${debugUrl.toString()}]`);
16
+ }
17
+ return fUrl;
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@butlerbot/sdk",
3
- "version": "0.0.6-alpha.5",
3
+ "version": "0.0.7-alpha.0",
4
4
  "description": "The official ButlerBot SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",